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.internal.os; 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.usage.NetworkStatsManager; 30 import android.bluetooth.BluetoothActivityEnergyInfo; 31 import android.bluetooth.UidTraffic; 32 import android.compat.annotation.UnsupportedAppUsage; 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.Binder; 48 import android.os.BluetoothBatteryStats; 49 import android.os.Build; 50 import android.os.Handler; 51 import android.os.IBatteryPropertiesRegistrar; 52 import android.os.Looper; 53 import android.os.Message; 54 import android.os.OsProtoEnums; 55 import android.os.Parcel; 56 import android.os.ParcelFormatException; 57 import android.os.Parcelable; 58 import android.os.PowerManager; 59 import android.os.Process; 60 import android.os.RemoteException; 61 import android.os.ServiceManager; 62 import android.os.SystemClock; 63 import android.os.UserHandle; 64 import android.os.WakeLockStats; 65 import android.os.WorkSource; 66 import android.os.WorkSource.WorkChain; 67 import android.os.connectivity.CellularBatteryStats; 68 import android.os.connectivity.GpsBatteryStats; 69 import android.os.connectivity.WifiActivityEnergyInfo; 70 import android.os.connectivity.WifiBatteryStats; 71 import android.provider.Settings; 72 import android.telephony.AccessNetworkConstants; 73 import android.telephony.Annotation.NetworkType; 74 import android.telephony.CellSignalStrength; 75 import android.telephony.CellSignalStrengthLte; 76 import android.telephony.CellSignalStrengthNr; 77 import android.telephony.DataConnectionRealTimeInfo; 78 import android.telephony.ModemActivityInfo; 79 import android.telephony.ServiceState; 80 import android.telephony.ServiceState.RegState; 81 import android.telephony.SignalStrength; 82 import android.telephony.TelephonyManager; 83 import android.text.TextUtils; 84 import android.util.ArrayMap; 85 import android.util.ArraySet; 86 import android.util.AtomicFile; 87 import android.util.IndentingPrintWriter; 88 import android.util.KeyValueListParser; 89 import android.util.Log; 90 import android.util.LongSparseArray; 91 import android.util.LongSparseLongArray; 92 import android.util.MutableInt; 93 import android.util.PrintWriterPrinter; 94 import android.util.Printer; 95 import android.util.Slog; 96 import android.util.SparseArray; 97 import android.util.SparseDoubleArray; 98 import android.util.SparseIntArray; 99 import android.util.SparseLongArray; 100 import android.util.TimeUtils; 101 import android.util.TypedXmlPullParser; 102 import android.util.TypedXmlSerializer; 103 import android.util.Xml; 104 import android.view.Display; 105 106 import com.android.internal.annotations.GuardedBy; 107 import com.android.internal.annotations.VisibleForTesting; 108 import com.android.internal.os.KernelCpuUidTimeReader.KernelCpuUidActiveTimeReader; 109 import com.android.internal.os.KernelCpuUidTimeReader.KernelCpuUidClusterTimeReader; 110 import com.android.internal.os.KernelCpuUidTimeReader.KernelCpuUidFreqTimeReader; 111 import com.android.internal.os.KernelCpuUidTimeReader.KernelCpuUidUserSysTimeReader; 112 import com.android.internal.os.SystemServerCpuThreadReader.SystemServiceCpuThreadTimes; 113 import com.android.internal.power.MeasuredEnergyStats; 114 import com.android.internal.power.MeasuredEnergyStats.StandardPowerBucket; 115 import com.android.internal.util.ArrayUtils; 116 import com.android.internal.util.FrameworkStatsLog; 117 import com.android.internal.util.XmlUtils; 118 import com.android.net.module.util.NetworkCapabilitiesUtils; 119 120 import libcore.util.EmptyArray; 121 122 import org.xmlpull.v1.XmlPullParser; 123 import org.xmlpull.v1.XmlPullParserException; 124 125 import java.io.ByteArrayOutputStream; 126 import java.io.File; 127 import java.io.FileInputStream; 128 import java.io.FileNotFoundException; 129 import java.io.FileOutputStream; 130 import java.io.IOException; 131 import java.io.PrintWriter; 132 import java.lang.annotation.Retention; 133 import java.lang.annotation.RetentionPolicy; 134 import java.util.ArrayList; 135 import java.util.Arrays; 136 import java.util.Calendar; 137 import java.util.Collection; 138 import java.util.Comparator; 139 import java.util.HashMap; 140 import java.util.HashSet; 141 import java.util.Iterator; 142 import java.util.LinkedList; 143 import java.util.List; 144 import java.util.Map; 145 import java.util.Queue; 146 import java.util.concurrent.Future; 147 import java.util.concurrent.atomic.AtomicInteger; 148 import java.util.concurrent.locks.ReentrantLock; 149 150 /** 151 * All information we are collecting about things that can happen that impact 152 * battery life. All times are represented in microseconds except where indicated 153 * otherwise. 154 */ 155 public class BatteryStatsImpl extends BatteryStats { 156 private static final String TAG = "BatteryStatsImpl"; 157 private static final boolean DEBUG = false; 158 public static final boolean DEBUG_ENERGY = false; 159 private static final boolean DEBUG_ENERGY_CPU = DEBUG_ENERGY; 160 private static final boolean DEBUG_BINDER_STATS = false; 161 private static final boolean DEBUG_MEMORY = false; 162 private static final boolean DEBUG_HISTORY = false; 163 164 // TODO: remove "tcp" from network methods, since we measure total stats. 165 166 // In-memory Parcel magic number, used to detect attempts to unmarshall bad data 167 private static final int MAGIC = 0xBA757475; // 'BATSTATS' 168 169 // Current on-disk Parcel version. Must be updated when the format of the parcelable changes 170 public static final int VERSION = 211; 171 172 // The maximum number of names wakelocks we will keep track of 173 // per uid; once the limit is reached, we batch the remaining wakelocks 174 // in to one common name. 175 private static final int MAX_WAKELOCKS_PER_UID; 176 177 static { 178 if (ActivityManager.isLowRamDeviceStatic()) { 179 MAX_WAKELOCKS_PER_UID = 40; 180 } else { 181 MAX_WAKELOCKS_PER_UID = 200; 182 } 183 } 184 185 // Number of transmit power states the Wifi controller can be in. 186 private static final int NUM_WIFI_TX_LEVELS = 1; 187 188 // Number of transmit power states the Bluetooth controller can be in. 189 private static final int NUM_BT_TX_LEVELS = 1; 190 191 /** 192 * Holding a wakelock costs more than just using the cpu. 193 * Currently, we assign only half the cpu time to an app that is running but 194 * not holding a wakelock. The apps holding wakelocks get the rest of the blame. 195 * If no app is holding a wakelock, then the distribution is normal. 196 */ 197 @VisibleForTesting 198 public static final int WAKE_LOCK_WEIGHT = 50; 199 200 public static final int RESET_REASON_CORRUPT_FILE = 1; 201 public static final int RESET_REASON_ADB_COMMAND = 2; 202 public static final int RESET_REASON_FULL_CHARGE = 3; 203 public static final int RESET_REASON_MEASURED_ENERGY_BUCKETS_CHANGE = 4; 204 205 protected Clock mClock; 206 207 private final AtomicFile mStatsFile; 208 public final AtomicFile mCheckinFile; 209 public final AtomicFile mDailyFile; 210 211 static final int MSG_REPORT_CPU_UPDATE_NEEDED = 1; 212 static final int MSG_REPORT_POWER_CHANGE = 2; 213 static final int MSG_REPORT_CHARGING = 3; 214 static final int MSG_REPORT_RESET_STATS = 4; 215 static final long DELAY_UPDATE_WAKELOCKS = 60 * 1000; 216 217 private static final double MILLISECONDS_IN_HOUR = 3600 * 1000; 218 private static final long MILLISECONDS_IN_YEAR = 365 * 24 * 3600 * 1000L; 219 220 private static final LongCounter ZERO_LONG_COUNTER = new LongCounter() { 221 @Override 222 public long getCountLocked(int which) { 223 return 0; 224 } 225 226 @Override 227 public long getCountForProcessState(int procState) { 228 return 0; 229 } 230 231 @Override 232 public void logState(Printer pw, String prefix) { 233 pw.println(prefix + "mCount=0"); 234 } 235 }; 236 237 private static final LongCounter[] ZERO_LONG_COUNTER_ARRAY = 238 new LongCounter[]{ZERO_LONG_COUNTER}; 239 240 private final KernelWakelockReader mKernelWakelockReader = new KernelWakelockReader(); 241 private final KernelWakelockStats mTmpWakelockStats = new KernelWakelockStats(); 242 243 @VisibleForTesting 244 protected KernelCpuUidUserSysTimeReader mCpuUidUserSysTimeReader; 245 @VisibleForTesting 246 protected KernelCpuSpeedReader[] mKernelCpuSpeedReaders; 247 @VisibleForTesting 248 protected KernelCpuUidFreqTimeReader mCpuUidFreqTimeReader; 249 @VisibleForTesting 250 protected KernelCpuUidActiveTimeReader mCpuUidActiveTimeReader; 251 @VisibleForTesting 252 protected KernelCpuUidClusterTimeReader mCpuUidClusterTimeReader; 253 @VisibleForTesting 254 protected KernelSingleUidTimeReader mKernelSingleUidTimeReader; 255 @VisibleForTesting 256 protected SystemServerCpuThreadReader mSystemServerCpuThreadReader = 257 SystemServerCpuThreadReader.create(); 258 259 private final KernelMemoryBandwidthStats mKernelMemoryBandwidthStats 260 = new KernelMemoryBandwidthStats(); 261 private final LongSparseArray<SamplingTimer> mKernelMemoryStats = new LongSparseArray<>(); 262 getKernelMemoryStats()263 public LongSparseArray<SamplingTimer> getKernelMemoryStats() { 264 return mKernelMemoryStats; 265 } 266 267 private static final int[] SUPPORTED_PER_PROCESS_STATE_STANDARD_ENERGY_BUCKETS = { 268 MeasuredEnergyStats.POWER_BUCKET_CPU, 269 MeasuredEnergyStats.POWER_BUCKET_MOBILE_RADIO, 270 MeasuredEnergyStats.POWER_BUCKET_WIFI, 271 MeasuredEnergyStats.POWER_BUCKET_BLUETOOTH, 272 }; 273 274 // TimeInState counters need NUM_PROCESS_STATE states in order to accommodate 275 // Uid.PROCESS_STATE_NONEXISTENT, which is outside the range of legitimate proc states. 276 private static final int PROC_STATE_TIME_COUNTER_STATE_COUNT = NUM_PROCESS_STATE + 1; 277 278 @GuardedBy("this") 279 public boolean mPerProcStateCpuTimesAvailable = true; 280 281 @GuardedBy("this") 282 private long mNumSingleUidCpuTimeReads; 283 @GuardedBy("this") 284 private long mCpuTimeReadsTrackingStartTimeMs = SystemClock.uptimeMillis(); 285 @GuardedBy("this") 286 private int mNumUidsRemoved; 287 @GuardedBy("this") 288 private int mNumAllUidCpuTimeReads; 289 290 /** Container for Resource Power Manager stats. Updated by updateRpmStatsLocked. */ 291 private RpmStats mTmpRpmStats = null; 292 /** The soonest the RPM stats can be updated after it was last updated. */ 293 private static final long RPM_STATS_UPDATE_FREQ_MS = 1000; 294 /** Last time that RPM stats were updated by updateRpmStatsLocked. */ 295 private long mLastRpmStatsUpdateTimeMs = -RPM_STATS_UPDATE_FREQ_MS; 296 297 /** Container for Rail Energy Data stats. */ 298 private final RailStats mTmpRailStats = new RailStats(); 299 300 /** 301 * Use a queue to delay removing UIDs from {@link KernelCpuUidUserSysTimeReader}, 302 * {@link KernelCpuUidActiveTimeReader}, {@link KernelCpuUidClusterTimeReader}, 303 * {@link KernelCpuUidFreqTimeReader} and from the Kernel. 304 * 305 * Isolated and invalid UID info must be removed to conserve memory. However, STATSD and 306 * Batterystats both need to access UID cpu time. To resolve this race condition, only 307 * Batterystats shall remove UIDs, and a delay {@link Constants#UID_REMOVE_DELAY_MS} is 308 * implemented so that STATSD can capture those UID times before they are deleted. 309 */ 310 @GuardedBy("this") 311 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) 312 protected Queue<UidToRemove> mPendingRemovedUids = new LinkedList<>(); 313 314 @VisibleForTesting 315 public final class UidToRemove { 316 private final int mStartUid; 317 private final int mEndUid; 318 private final long mUidRemovalTimestamp; 319 320 /** Remove just one UID */ UidToRemove(int uid, long timestamp)321 public UidToRemove(int uid, long timestamp) { 322 this(uid, uid, timestamp); 323 } 324 325 /** Remove a range of UIDs, startUid must be smaller than endUid. */ UidToRemove(int startUid, int endUid, long timestamp)326 public UidToRemove(int startUid, int endUid, long timestamp) { 327 mStartUid = startUid; 328 mEndUid = endUid; 329 mUidRemovalTimestamp = timestamp; 330 } 331 getUidRemovalTimestamp()332 public long getUidRemovalTimestamp() { 333 return mUidRemovalTimestamp; 334 } 335 336 @GuardedBy("BatteryStatsImpl.this") removeLocked()337 void removeLocked() { 338 removeCpuStatsForUidRangeLocked(mStartUid, mEndUid); 339 } 340 } 341 342 /** 343 * Listener for the battery stats reset. 344 */ 345 public interface BatteryResetListener { 346 347 /** 348 * Callback invoked immediately prior to resetting battery stats. 349 * @param resetReason One of the RESET_REASON_* constants. 350 */ prepareForBatteryStatsReset(int resetReason)351 void prepareForBatteryStatsReset(int resetReason); 352 } 353 354 private BatteryResetListener mBatteryResetListener; 355 356 public interface BatteryCallback { batteryNeedsCpuUpdate()357 public void batteryNeedsCpuUpdate(); batteryPowerChanged(boolean onBattery)358 public void batteryPowerChanged(boolean onBattery); batterySendBroadcast(Intent intent)359 public void batterySendBroadcast(Intent intent); batteryStatsReset()360 public void batteryStatsReset(); 361 } 362 363 public interface PlatformIdleStateCallback { fillLowPowerStats(RpmStats rpmStats)364 public void fillLowPowerStats(RpmStats rpmStats); getSubsystemLowPowerStats()365 public String getSubsystemLowPowerStats(); 366 } 367 368 /** interface to update rail information for power monitor */ 369 public interface MeasuredEnergyRetriever { 370 /** Function to fill the map for the rail data stats 371 * Used for power monitoring feature 372 * @param railStats 373 */ fillRailDataStats(RailStats railStats)374 void fillRailDataStats(RailStats railStats); 375 } 376 377 public static abstract class UserInfoProvider { 378 private int[] userIds; getUserIds()379 protected abstract @Nullable int[] getUserIds(); 380 @VisibleForTesting refreshUserIds()381 public final void refreshUserIds() { 382 userIds = getUserIds(); 383 } 384 @VisibleForTesting exists(int userId)385 public boolean exists(int userId) { 386 return userIds != null ? ArrayUtils.contains(userIds, userId) : true; 387 } 388 } 389 390 private final PlatformIdleStateCallback mPlatformIdleStateCallback; 391 392 private final Runnable mDeferSetCharging = new Runnable() { 393 @Override 394 public void run() { 395 synchronized (BatteryStatsImpl.this) { 396 if (mOnBattery) { 397 // if the device gets unplugged in the time between this runnable being 398 // executed and the lock being taken, we don't want to set charging state 399 return; 400 } 401 boolean changed = setChargingLocked(true); 402 if (changed) { 403 final long uptimeMs = mClock.uptimeMillis(); 404 final long elapsedRealtimeMs = mClock.elapsedRealtime(); 405 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 406 } 407 } 408 } 409 }; 410 411 public final MeasuredEnergyRetriever mMeasuredEnergyRetriever; 412 413 /** 414 * This handler is running on {@link BackgroundThread}. 415 */ 416 final class MyHandler extends Handler { MyHandler(Looper looper)417 public MyHandler(Looper looper) { 418 super(looper, null, true); 419 } 420 421 @Override handleMessage(Message msg)422 public void handleMessage(Message msg) { 423 BatteryCallback cb = mCallback; 424 switch (msg.what) { 425 case MSG_REPORT_CPU_UPDATE_NEEDED: 426 if (cb != null) { 427 cb.batteryNeedsCpuUpdate(); 428 } 429 break; 430 case MSG_REPORT_POWER_CHANGE: 431 if (cb != null) { 432 cb.batteryPowerChanged(msg.arg1 != 0); 433 } 434 break; 435 case MSG_REPORT_CHARGING: 436 if (cb != null) { 437 final String action; 438 synchronized (BatteryStatsImpl.this) { 439 action = mCharging ? BatteryManager.ACTION_CHARGING 440 : BatteryManager.ACTION_DISCHARGING; 441 } 442 Intent intent = new Intent(action); 443 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); 444 cb.batterySendBroadcast(intent); 445 } 446 break; 447 case MSG_REPORT_RESET_STATS: 448 if (cb != null) { 449 cb.batteryStatsReset(); 450 } 451 } 452 } 453 } 454 postBatteryNeedsCpuUpdateMsg()455 public void postBatteryNeedsCpuUpdateMsg() { 456 mHandler.sendEmptyMessage(MSG_REPORT_CPU_UPDATE_NEEDED); 457 } 458 459 /** 460 * Update per-freq cpu times for the supplied UID. 461 */ 462 @GuardedBy("this") 463 @SuppressWarnings("GuardedBy") // errorprone false positive on getProcStateTimeCounter 464 @VisibleForTesting updateProcStateCpuTimesLocked(int uid, long timestampMs)465 public void updateProcStateCpuTimesLocked(int uid, long timestampMs) { 466 if (!initKernelSingleUidTimeReaderLocked()) { 467 return; 468 } 469 470 final Uid u = getUidStatsLocked(uid); 471 472 mNumSingleUidCpuTimeReads++; 473 474 LongArrayMultiStateCounter onBatteryCounter = 475 u.getProcStateTimeCounter(timestampMs).getCounter(); 476 LongArrayMultiStateCounter onBatteryScreenOffCounter = 477 u.getProcStateScreenOffTimeCounter(timestampMs).getCounter(); 478 479 mKernelSingleUidTimeReader.addDelta(uid, onBatteryCounter, timestampMs); 480 mKernelSingleUidTimeReader.addDelta(uid, onBatteryScreenOffCounter, timestampMs); 481 482 if (u.mChildUids != null) { 483 LongArrayMultiStateCounter.LongArrayContainer deltaContainer = 484 getCpuTimeInFreqContainer(); 485 int childUidCount = u.mChildUids.size(); 486 for (int j = childUidCount - 1; j >= 0; --j) { 487 LongArrayMultiStateCounter cpuTimeInFreqCounter = 488 u.mChildUids.valueAt(j).cpuTimeInFreqCounter; 489 if (cpuTimeInFreqCounter != null) { 490 mKernelSingleUidTimeReader.addDelta(u.mChildUids.keyAt(j), 491 cpuTimeInFreqCounter, timestampMs, deltaContainer); 492 onBatteryCounter.addCounts(deltaContainer); 493 onBatteryScreenOffCounter.addCounts(deltaContainer); 494 } 495 } 496 } 497 } 498 499 /** 500 * Removes kernel CPU stats for removed UIDs, in the order they were added to the 501 * mPendingRemovedUids queue. 502 */ 503 @GuardedBy("this") 504 @SuppressWarnings("GuardedBy") // errorprone false positive on removeLocked clearPendingRemovedUidsLocked()505 public void clearPendingRemovedUidsLocked() { 506 long cutOffTimeMs = mClock.elapsedRealtime() - mConstants.UID_REMOVE_DELAY_MS; 507 while (!mPendingRemovedUids.isEmpty() 508 && mPendingRemovedUids.peek().getUidRemovalTimestamp() < cutOffTimeMs) { 509 mPendingRemovedUids.poll().removeLocked(); 510 } 511 } 512 513 /** 514 * When the battery/screen state changes, we don't attribute the cpu times to any process 515 * but we still need to take snapshots of all uids to get correct deltas later on. 516 */ 517 @SuppressWarnings("GuardedBy") // errorprone false positive on getProcStateTimeCounter updateCpuTimesForAllUids()518 public void updateCpuTimesForAllUids() { 519 synchronized (BatteryStatsImpl.this) { 520 if (!trackPerProcStateCpuTimes()) { 521 return; 522 } 523 524 if(!initKernelSingleUidTimeReaderLocked()) { 525 return; 526 } 527 528 // TODO(b/197162116): just get a list of UIDs 529 final SparseArray<long[]> allUidCpuFreqTimesMs = 530 mCpuUidFreqTimeReader.getAllUidCpuFreqTimeMs(); 531 for (int i = allUidCpuFreqTimesMs.size() - 1; i >= 0; --i) { 532 final int uid = allUidCpuFreqTimesMs.keyAt(i); 533 final int parentUid = mapUid(uid); 534 final Uid u = getAvailableUidStatsLocked(parentUid); 535 if (u == null) { 536 continue; 537 } 538 539 final int procState = u.mProcessState; 540 if (procState == Uid.PROCESS_STATE_NONEXISTENT) { 541 continue; 542 } 543 544 final long timestampMs = mClock.elapsedRealtime(); 545 final LongArrayMultiStateCounter onBatteryCounter = 546 u.getProcStateTimeCounter(timestampMs).getCounter(); 547 final LongArrayMultiStateCounter onBatteryScreenOffCounter = 548 u.getProcStateScreenOffTimeCounter(timestampMs).getCounter(); 549 550 if (uid == parentUid || Process.isSdkSandboxUid(uid)) { 551 mKernelSingleUidTimeReader.addDelta(parentUid, onBatteryCounter, timestampMs); 552 mKernelSingleUidTimeReader.addDelta(parentUid, onBatteryScreenOffCounter, 553 timestampMs); 554 } else { 555 Uid.ChildUid childUid = u.getChildUid(uid); 556 if (childUid != null) { 557 final LongArrayMultiStateCounter counter = childUid.cpuTimeInFreqCounter; 558 if (counter != null) { 559 final LongArrayMultiStateCounter.LongArrayContainer deltaContainer = 560 getCpuTimeInFreqContainer(); 561 mKernelSingleUidTimeReader.addDelta(uid, counter, timestampMs, 562 deltaContainer); 563 onBatteryCounter.addCounts(deltaContainer); 564 onBatteryScreenOffCounter.addCounts(deltaContainer); 565 } 566 } 567 } 568 } 569 } 570 } 571 572 @VisibleForTesting addCpuTimes(long[] timesA, long[] timesB)573 public static long[] addCpuTimes(long[] timesA, long[] timesB) { 574 if (timesA != null && timesB != null) { 575 for (int i = timesA.length - 1; i >= 0; --i) { 576 timesA[i] += timesB[i]; 577 } 578 return timesA; 579 } 580 return timesA == null ? (timesB == null ? null : timesB) : timesA; 581 } 582 583 @GuardedBy("this") initKernelSingleUidTimeReaderLocked()584 private boolean initKernelSingleUidTimeReaderLocked() { 585 if (mKernelSingleUidTimeReader == null) { 586 if (mPowerProfile == null) { 587 return false; 588 } 589 if (mCpuFreqs == null) { 590 mCpuFreqs = mCpuUidFreqTimeReader.readFreqs(mPowerProfile); 591 } 592 if (mCpuFreqs != null) { 593 mKernelSingleUidTimeReader = new KernelSingleUidTimeReader(mCpuFreqs.length); 594 } else { 595 mPerProcStateCpuTimesAvailable = mCpuUidFreqTimeReader.allUidTimesAvailable(); 596 return false; 597 } 598 } 599 mPerProcStateCpuTimesAvailable = mCpuUidFreqTimeReader.allUidTimesAvailable() 600 && mKernelSingleUidTimeReader.singleUidCpuTimesAvailable(); 601 return true; 602 } 603 604 public interface ExternalStatsSync { 605 int UPDATE_CPU = 0x01; 606 int UPDATE_WIFI = 0x02; 607 int UPDATE_RADIO = 0x04; 608 int UPDATE_BT = 0x08; 609 int UPDATE_RPM = 0x10; 610 int UPDATE_DISPLAY = 0x20; 611 int RESET = 0x40; 612 613 int UPDATE_ALL = 614 UPDATE_CPU | UPDATE_WIFI | UPDATE_RADIO | UPDATE_BT | UPDATE_RPM | UPDATE_DISPLAY; 615 616 int UPDATE_ON_PROC_STATE_CHANGE = UPDATE_WIFI | UPDATE_RADIO | UPDATE_BT; 617 618 int UPDATE_ON_RESET = UPDATE_ALL | RESET; 619 620 @IntDef(flag = true, prefix = "UPDATE_", value = { 621 UPDATE_CPU, 622 UPDATE_WIFI, 623 UPDATE_RADIO, 624 UPDATE_BT, 625 UPDATE_RPM, 626 UPDATE_DISPLAY, 627 UPDATE_ALL, 628 }) 629 @Retention(RetentionPolicy.SOURCE) 630 public @interface ExternalUpdateFlag { 631 } 632 scheduleSync(String reason, int flags)633 Future<?> scheduleSync(String reason, int flags); scheduleCpuSyncDueToRemovedUid(int uid)634 Future<?> scheduleCpuSyncDueToRemovedUid(int uid); scheduleCpuSyncDueToSettingChange()635 Future<?> scheduleCpuSyncDueToSettingChange(); 636 /** 637 * Schedule a sync because of a screen state change. 638 */ scheduleSyncDueToScreenStateChange(int flags, boolean onBattery, boolean onBatteryScreenOff, int screenState, int[] perDisplayScreenStates)639 Future<?> scheduleSyncDueToScreenStateChange(int flags, boolean onBattery, 640 boolean onBatteryScreenOff, int screenState, int[] perDisplayScreenStates); scheduleCpuSyncDueToWakelockChange(long delayMillis)641 Future<?> scheduleCpuSyncDueToWakelockChange(long delayMillis); cancelCpuSyncDueToWakelockChange()642 void cancelCpuSyncDueToWakelockChange(); scheduleSyncDueToBatteryLevelChange(long delayMillis)643 Future<?> scheduleSyncDueToBatteryLevelChange(long delayMillis); 644 /** Schedule removal of UIDs corresponding to a removed user */ scheduleCleanupDueToRemovedUser(int userId)645 Future<?> scheduleCleanupDueToRemovedUser(int userId); 646 /** Schedule a sync because of a process state change */ scheduleSyncDueToProcessStateChange(int flags, long delayMillis)647 void scheduleSyncDueToProcessStateChange(int flags, long delayMillis); 648 } 649 650 public Handler mHandler; 651 private ExternalStatsSync mExternalSync = null; 652 @VisibleForTesting 653 protected UserInfoProvider mUserInfoProvider = null; 654 655 private BatteryCallback mCallback; 656 657 /** 658 * Mapping isolated uids to the actual owning app uid. 659 */ 660 final SparseIntArray mIsolatedUids = new SparseIntArray(); 661 /** 662 * Internal reference count of isolated uids. 663 */ 664 final SparseIntArray mIsolatedUidRefCounts = new SparseIntArray(); 665 666 /** 667 * The statistics we have collected organized by uids. 668 */ 669 final SparseArray<BatteryStatsImpl.Uid> mUidStats = new SparseArray<>(); 670 671 // A set of pools of currently active timers. When a timer is queried, we will divide the 672 // elapsed time by the number of active timers to arrive at that timer's share of the time. 673 // In order to do this, we must refresh each timer whenever the number of active timers 674 // changes. 675 @VisibleForTesting 676 @UnsupportedAppUsage 677 protected ArrayList<StopwatchTimer> mPartialTimers = new ArrayList<>(); 678 @UnsupportedAppUsage 679 final ArrayList<StopwatchTimer> mFullTimers = new ArrayList<>(); 680 @UnsupportedAppUsage 681 final ArrayList<StopwatchTimer> mWindowTimers = new ArrayList<>(); 682 final ArrayList<StopwatchTimer> mDrawTimers = new ArrayList<>(); 683 final SparseArray<ArrayList<StopwatchTimer>> mSensorTimers = new SparseArray<>(); 684 final ArrayList<StopwatchTimer> mWifiRunningTimers = new ArrayList<>(); 685 final ArrayList<StopwatchTimer> mFullWifiLockTimers = new ArrayList<>(); 686 final ArrayList<StopwatchTimer> mWifiMulticastTimers = new ArrayList<>(); 687 final ArrayList<StopwatchTimer> mWifiScanTimers = new ArrayList<>(); 688 final SparseArray<ArrayList<StopwatchTimer>> mWifiBatchedScanTimers = new SparseArray<>(); 689 final ArrayList<StopwatchTimer> mAudioTurnedOnTimers = new ArrayList<>(); 690 final ArrayList<StopwatchTimer> mVideoTurnedOnTimers = new ArrayList<>(); 691 final ArrayList<StopwatchTimer> mFlashlightTurnedOnTimers = new ArrayList<>(); 692 final ArrayList<StopwatchTimer> mCameraTurnedOnTimers = new ArrayList<>(); 693 final ArrayList<StopwatchTimer> mBluetoothScanOnTimers = new ArrayList<>(); 694 695 // Last partial timers we use for distributing CPU usage. 696 @VisibleForTesting 697 protected ArrayList<StopwatchTimer> mLastPartialTimers = new ArrayList<>(); 698 699 // These are the objects that will want to do something when the device 700 // is unplugged from power. 701 protected final TimeBase mOnBatteryTimeBase = new TimeBase(true); 702 703 // These are the objects that will want to do something when the device 704 // is unplugged from power *and* the screen is off or doze. 705 protected final TimeBase mOnBatteryScreenOffTimeBase = new TimeBase(true); 706 707 // Set to true when we want to distribute CPU across wakelocks for the next 708 // CPU update, even if we aren't currently running wake locks. 709 boolean mDistributeWakelockCpu; 710 711 private boolean mSystemReady; 712 boolean mShuttingDown; 713 714 final HistoryEventTracker mActiveEvents = new HistoryEventTracker(); 715 716 long mHistoryBaseTimeMs; 717 protected boolean mHaveBatteryLevel = false; 718 protected boolean mRecordingHistory = false; 719 int mNumHistoryItems; 720 721 private static final int HISTORY_TAG_INDEX_LIMIT = 0x7ffe; 722 private static final int MAX_HISTORY_TAG_STRING_LENGTH = 1024; 723 724 final HashMap<HistoryTag, Integer> mHistoryTagPool = new HashMap<>(); 725 private SparseArray<HistoryTag> mHistoryTags; 726 final Parcel mHistoryBuffer = Parcel.obtain(); 727 final HistoryItem mHistoryLastWritten = new HistoryItem(); 728 final HistoryItem mHistoryLastLastWritten = new HistoryItem(); 729 final HistoryItem mHistoryAddTmp = new HistoryItem(); 730 int mNextHistoryTagIdx = 0; 731 int mNumHistoryTagChars = 0; 732 int mHistoryBufferLastPos = -1; 733 int mActiveHistoryStates = 0xffffffff; 734 int mActiveHistoryStates2 = 0xffffffff; 735 long mLastHistoryElapsedRealtimeMs = 0; 736 long mTrackRunningHistoryElapsedRealtimeMs = 0; 737 long mTrackRunningHistoryUptimeMs = 0; 738 739 @NonNull 740 final BatteryStatsHistory mBatteryStatsHistory; 741 742 final HistoryItem mHistoryCur = new HistoryItem(); 743 744 HistoryItem mHistory; 745 HistoryItem mHistoryEnd; 746 HistoryItem mHistoryLastEnd; 747 HistoryItem mHistoryCache; 748 749 // Used by computeHistoryStepDetails 750 HistoryStepDetails mLastHistoryStepDetails = null; 751 byte mLastHistoryStepLevel = 0; 752 final HistoryStepDetails mCurHistoryStepDetails = new HistoryStepDetails(); 753 final HistoryStepDetails mReadHistoryStepDetails = new HistoryStepDetails(); 754 final HistoryStepDetails mTmpHistoryStepDetails = new HistoryStepDetails(); 755 756 /** 757 * Total time (in milliseconds) spent executing in user code. 758 */ 759 long mLastStepCpuUserTimeMs; 760 long mCurStepCpuUserTimeMs; 761 /** 762 * Total time (in milliseconds) spent executing in kernel code. 763 */ 764 long mLastStepCpuSystemTimeMs; 765 long mCurStepCpuSystemTimeMs; 766 /** 767 * Times from /proc/stat (but measured in milliseconds). 768 */ 769 long mLastStepStatUserTimeMs; 770 long mLastStepStatSystemTimeMs; 771 long mLastStepStatIOWaitTimeMs; 772 long mLastStepStatIrqTimeMs; 773 long mLastStepStatSoftIrqTimeMs; 774 long mLastStepStatIdleTimeMs; 775 long mCurStepStatUserTimeMs; 776 long mCurStepStatSystemTimeMs; 777 long mCurStepStatIOWaitTimeMs; 778 long mCurStepStatIrqTimeMs; 779 long mCurStepStatSoftIrqTimeMs; 780 long mCurStepStatIdleTimeMs; 781 782 private BatteryStatsHistoryIterator mBatteryStatsHistoryIterator; 783 private HistoryItem mHistoryIterator; 784 785 int mStartCount; 786 787 /** 788 * Set to true when a reset occurs, informing us that the next time BatteryExternalStatsWorker 789 * gives us data, we mustn't process it since this data includes pre-reset-period data. 790 */ 791 @GuardedBy("this") 792 boolean mIgnoreNextExternalStats = false; 793 794 long mStartClockTimeMs; 795 String mStartPlatformVersion; 796 String mEndPlatformVersion; 797 798 long mUptimeUs; 799 long mUptimeStartUs; 800 long mRealtimeUs; 801 long mRealtimeStartUs; 802 803 int mWakeLockNesting; 804 boolean mWakeLockImportant; 805 public boolean mRecordAllHistory; 806 boolean mNoAutoReset; 807 808 /** 809 * Overall screen state. For multidisplay devices, this represents the current highest screen 810 * state of the displays. 811 */ 812 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) 813 protected int mScreenState = Display.STATE_UNKNOWN; 814 /** 815 * Overall screen on timer. For multidisplay devices, this represents the time spent with at 816 * least one display in the screen on state. 817 */ 818 StopwatchTimer mScreenOnTimer; 819 /** 820 * Overall screen doze timer. For multidisplay devices, this represents the time spent with 821 * screen doze being the highest screen state. 822 */ 823 StopwatchTimer mScreenDozeTimer; 824 /** 825 * Overall screen brightness bin. For multidisplay devices, this represents the current 826 * brightest screen. 827 */ 828 int mScreenBrightnessBin = -1; 829 /** 830 * Overall screen brightness timers. For multidisplay devices, the {@link mScreenBrightnessBin} 831 * timer will be active at any given time 832 */ 833 final StopwatchTimer[] mScreenBrightnessTimer = 834 new StopwatchTimer[NUM_SCREEN_BRIGHTNESS_BINS]; 835 836 boolean mPretendScreenOff; 837 838 private static class DisplayBatteryStats { 839 /** 840 * Per display screen state. 841 */ 842 public int screenState = Display.STATE_UNKNOWN; 843 /** 844 * Per display screen on timers. 845 */ 846 public StopwatchTimer screenOnTimer; 847 /** 848 * Per display screen doze timers. 849 */ 850 public StopwatchTimer screenDozeTimer; 851 /** 852 * Per display screen brightness bins. 853 */ 854 public int screenBrightnessBin = -1; 855 /** 856 * Per display screen brightness timers. 857 */ 858 public StopwatchTimer[] screenBrightnessTimers = 859 new StopwatchTimer[NUM_SCREEN_BRIGHTNESS_BINS]; 860 /** 861 * Per display screen state the last time {@link #updateDisplayMeasuredEnergyStatsLocked} 862 * was called. 863 */ 864 public int screenStateAtLastEnergyMeasurement = Display.STATE_UNKNOWN; 865 DisplayBatteryStats(Clock clock, TimeBase timeBase)866 DisplayBatteryStats(Clock clock, TimeBase timeBase) { 867 screenOnTimer = new StopwatchTimer(clock, null, -1, null, 868 timeBase); 869 screenDozeTimer = new StopwatchTimer(clock, null, -1, null, 870 timeBase); 871 for (int i = 0; i < NUM_SCREEN_BRIGHTNESS_BINS; i++) { 872 screenBrightnessTimers[i] = new StopwatchTimer(clock, null, -100 - i, null, 873 timeBase); 874 } 875 } 876 877 /** 878 * Reset display timers. 879 */ reset(long elapsedRealtimeUs)880 public void reset(long elapsedRealtimeUs) { 881 screenOnTimer.reset(false, elapsedRealtimeUs); 882 screenDozeTimer.reset(false, elapsedRealtimeUs); 883 for (int i = 0; i < NUM_SCREEN_BRIGHTNESS_BINS; i++) { 884 screenBrightnessTimers[i].reset(false, elapsedRealtimeUs); 885 } 886 } 887 } 888 889 DisplayBatteryStats[] mPerDisplayBatteryStats; 890 891 private int mDisplayMismatchWtfCount = 0; 892 893 boolean mInteractive; 894 StopwatchTimer mInteractiveTimer; 895 896 boolean mPowerSaveModeEnabled; 897 StopwatchTimer mPowerSaveModeEnabledTimer; 898 899 boolean mDeviceIdling; 900 StopwatchTimer mDeviceIdlingTimer; 901 902 boolean mDeviceLightIdling; 903 StopwatchTimer mDeviceLightIdlingTimer; 904 905 int mDeviceIdleMode; 906 long mLastIdleTimeStartMs; 907 long mLongestLightIdleTimeMs; 908 long mLongestFullIdleTimeMs; 909 StopwatchTimer mDeviceIdleModeLightTimer; 910 StopwatchTimer mDeviceIdleModeFullTimer; 911 912 boolean mPhoneOn; 913 StopwatchTimer mPhoneOnTimer; 914 915 int mAudioOnNesting; 916 StopwatchTimer mAudioOnTimer; 917 918 int mVideoOnNesting; 919 StopwatchTimer mVideoOnTimer; 920 921 int mFlashlightOnNesting; 922 StopwatchTimer mFlashlightOnTimer; 923 924 int mCameraOnNesting; 925 StopwatchTimer mCameraOnTimer; 926 927 private static final int USB_DATA_UNKNOWN = 0; 928 private static final int USB_DATA_DISCONNECTED = 1; 929 private static final int USB_DATA_CONNECTED = 2; 930 int mUsbDataState = USB_DATA_UNKNOWN; 931 932 int mGpsSignalQualityBin = -1; 933 final StopwatchTimer[] mGpsSignalQualityTimer = 934 new StopwatchTimer[GnssSignalQuality.NUM_GNSS_SIGNAL_QUALITY_LEVELS]; 935 936 int mPhoneSignalStrengthBin = -1; 937 int mPhoneSignalStrengthBinRaw = -1; 938 final StopwatchTimer[] mPhoneSignalStrengthsTimer = 939 new StopwatchTimer[CellSignalStrength.getNumSignalStrengthLevels()]; 940 941 StopwatchTimer mPhoneSignalScanningTimer; 942 943 int mPhoneDataConnectionType = -1; 944 final StopwatchTimer[] mPhoneDataConnectionsTimer = 945 new StopwatchTimer[NUM_DATA_CONNECTION_TYPES]; 946 947 @RadioAccessTechnology 948 int mActiveRat = RADIO_ACCESS_TECHNOLOGY_OTHER; 949 950 private static class RadioAccessTechnologyBatteryStats { 951 /** 952 * This RAT is currently being used. 953 */ 954 private boolean mActive = false; 955 /** 956 * Current active frequency range for this RAT. 957 */ 958 @ServiceState.FrequencyRange 959 private int mFrequencyRange = ServiceState.FREQUENCY_RANGE_UNKNOWN; 960 /** 961 * Current signal strength for this RAT. 962 */ 963 private int mSignalStrength = CellSignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN; 964 /** 965 * Timers for each combination of frequency range and signal strength. 966 */ 967 public final StopwatchTimer[][] perStateTimers; 968 /** 969 * Counters tracking the time (in milliseconds) spent transmitting data in a given state. 970 */ 971 @Nullable 972 private LongSamplingCounter[][] mPerStateTxDurationMs = null; 973 /** 974 * Counters tracking the time (in milliseconds) spent receiving data in at given frequency. 975 */ 976 @Nullable 977 private LongSamplingCounter[] mPerFrequencyRxDurationMs = null; 978 RadioAccessTechnologyBatteryStats(int freqCount, Clock clock, TimeBase timeBase)979 RadioAccessTechnologyBatteryStats(int freqCount, Clock clock, TimeBase timeBase) { 980 perStateTimers = 981 new StopwatchTimer[freqCount][CellSignalStrength.NUM_SIGNAL_STRENGTH_BINS]; 982 for (int i = 0; i < freqCount; i++) { 983 for (int j = 0; j < CellSignalStrength.NUM_SIGNAL_STRENGTH_BINS; j++) { 984 perStateTimers[i][j] = new StopwatchTimer(clock, null, -1, null, timeBase); 985 } 986 } 987 } 988 989 /** 990 * Note this RAT is currently being used. 991 */ noteActive(boolean active, long elapsedRealtimeMs)992 public void noteActive(boolean active, long elapsedRealtimeMs) { 993 if (mActive == active) return; 994 mActive = active; 995 if (mActive) { 996 perStateTimers[mFrequencyRange][mSignalStrength].startRunningLocked( 997 elapsedRealtimeMs); 998 } else { 999 perStateTimers[mFrequencyRange][mSignalStrength].stopRunningLocked( 1000 elapsedRealtimeMs); 1001 } 1002 } 1003 1004 /** 1005 * Note current frequency range has changed. 1006 */ noteFrequencyRange(@erviceState.FrequencyRange int frequencyRange, long elapsedRealtimeMs)1007 public void noteFrequencyRange(@ServiceState.FrequencyRange int frequencyRange, 1008 long elapsedRealtimeMs) { 1009 if (mFrequencyRange == frequencyRange) return; 1010 1011 if (!mActive) { 1012 // RAT not in use, note the frequency change and move on. 1013 mFrequencyRange = frequencyRange; 1014 return; 1015 } 1016 perStateTimers[mFrequencyRange][mSignalStrength].stopRunningLocked(elapsedRealtimeMs); 1017 perStateTimers[frequencyRange][mSignalStrength].startRunningLocked(elapsedRealtimeMs); 1018 mFrequencyRange = frequencyRange; 1019 } 1020 1021 /** 1022 * Note current signal strength has changed. 1023 */ noteSignalStrength(int signalStrength, long elapsedRealtimeMs)1024 public void noteSignalStrength(int signalStrength, long elapsedRealtimeMs) { 1025 if (mSignalStrength == signalStrength) return; 1026 1027 if (!mActive) { 1028 // RAT not in use, note the signal strength change and move on. 1029 mSignalStrength = signalStrength; 1030 return; 1031 } 1032 perStateTimers[mFrequencyRange][mSignalStrength].stopRunningLocked(elapsedRealtimeMs); 1033 perStateTimers[mFrequencyRange][signalStrength].startRunningLocked(elapsedRealtimeMs); 1034 mSignalStrength = signalStrength; 1035 } 1036 1037 /** 1038 * Returns the duration in milliseconds spent in a given state since the last mark. 1039 */ getTimeSinceMark(@erviceState.FrequencyRange int frequencyRange, int signalStrength, long elapsedRealtimeMs)1040 public long getTimeSinceMark(@ServiceState.FrequencyRange int frequencyRange, 1041 int signalStrength, long elapsedRealtimeMs) { 1042 return perStateTimers[frequencyRange][signalStrength].getTimeSinceMarkLocked( 1043 elapsedRealtimeMs * 1000) / 1000; 1044 } 1045 1046 /** 1047 * Set mark for all timers. 1048 */ setMark(long elapsedRealtimeMs)1049 public void setMark(long elapsedRealtimeMs) { 1050 final int size = perStateTimers.length; 1051 for (int i = 0; i < size; i++) { 1052 for (int j = 0; j < CellSignalStrength.NUM_SIGNAL_STRENGTH_BINS; j++) { 1053 perStateTimers[i][j].setMark(elapsedRealtimeMs); 1054 } 1055 } 1056 } 1057 1058 /** 1059 * Returns numbers of frequencies tracked for this RAT. 1060 */ getFrequencyRangeCount()1061 public int getFrequencyRangeCount() { 1062 return perStateTimers.length; 1063 } 1064 1065 /** 1066 * Add TX time for a given state. 1067 */ incrementTxDuration(@erviceState.FrequencyRange int frequencyRange, int signalStrength, long durationMs)1068 public void incrementTxDuration(@ServiceState.FrequencyRange int frequencyRange, 1069 int signalStrength, long durationMs) { 1070 getTxDurationCounter(frequencyRange, signalStrength, true).addCountLocked(durationMs); 1071 } 1072 1073 /** 1074 * Add TX time for a given frequency. 1075 */ incrementRxDuration(@erviceState.FrequencyRange int frequencyRange, long durationMs)1076 public void incrementRxDuration(@ServiceState.FrequencyRange int frequencyRange, 1077 long durationMs) { 1078 getRxDurationCounter(frequencyRange, true).addCountLocked(durationMs); 1079 } 1080 1081 /** 1082 * Reset radio access technology timers and counts. 1083 */ reset(long elapsedRealtimeUs)1084 public void reset(long elapsedRealtimeUs) { 1085 final int size = perStateTimers.length; 1086 for (int i = 0; i < size; i++) { 1087 for (int j = 0; j < CellSignalStrength.NUM_SIGNAL_STRENGTH_BINS; j++) { 1088 perStateTimers[i][j].reset(false, elapsedRealtimeUs); 1089 if (mPerStateTxDurationMs == null) continue; 1090 mPerStateTxDurationMs[i][j].reset(false, elapsedRealtimeUs); 1091 } 1092 if (mPerFrequencyRxDurationMs == null) continue; 1093 mPerFrequencyRxDurationMs[i].reset(false, elapsedRealtimeUs); 1094 } 1095 } 1096 1097 /** 1098 * Write data to summary parcel 1099 */ writeSummaryToParcel(Parcel out, long elapsedRealtimeUs)1100 public void writeSummaryToParcel(Parcel out, long elapsedRealtimeUs) { 1101 final int freqCount = perStateTimers.length; 1102 out.writeInt(freqCount); 1103 out.writeInt(CellSignalStrength.NUM_SIGNAL_STRENGTH_BINS); 1104 for (int i = 0; i < freqCount; i++) { 1105 for (int j = 0; j < CellSignalStrength.NUM_SIGNAL_STRENGTH_BINS; j++) { 1106 perStateTimers[i][j].writeSummaryFromParcelLocked(out, elapsedRealtimeUs); 1107 } 1108 } 1109 1110 if (mPerStateTxDurationMs == null) { 1111 out.writeInt(0); 1112 } else { 1113 out.writeInt(1); 1114 for (int i = 0; i < freqCount; i++) { 1115 for (int j = 0; j < CellSignalStrength.NUM_SIGNAL_STRENGTH_BINS; j++) { 1116 mPerStateTxDurationMs[i][j].writeSummaryFromParcelLocked(out); 1117 } 1118 } 1119 } 1120 1121 if (mPerFrequencyRxDurationMs == null) { 1122 out.writeInt(0); 1123 } else { 1124 out.writeInt(1); 1125 for (int i = 0; i < freqCount; i++) { 1126 mPerFrequencyRxDurationMs[i].writeSummaryFromParcelLocked(out); 1127 } 1128 } 1129 } 1130 1131 /** 1132 * Read data from summary parcel 1133 */ readSummaryFromParcel(Parcel in)1134 public void readSummaryFromParcel(Parcel in) { 1135 final int oldFreqCount = in.readInt(); 1136 final int oldSignalStrengthCount = in.readInt(); 1137 final int currFreqCount = perStateTimers.length; 1138 final int currSignalStrengthCount = CellSignalStrength.NUM_SIGNAL_STRENGTH_BINS; 1139 1140 for (int freq = 0; freq < oldFreqCount; freq++) { 1141 for (int strength = 0; strength < oldSignalStrengthCount; strength++) { 1142 if (freq >= currFreqCount || strength >= currSignalStrengthCount) { 1143 // Mismatch with the summary parcel. Consume the data but don't use it. 1144 final StopwatchTimer temp = new StopwatchTimer(null, null, -1, null, 1145 new TimeBase()); 1146 // Consume perStateTimers data. 1147 temp.readSummaryFromParcelLocked(in); 1148 } else { 1149 perStateTimers[freq][strength].readSummaryFromParcelLocked(in); 1150 } 1151 } 1152 } 1153 1154 if (in.readInt() == 1) { 1155 for (int freq = 0; freq < oldFreqCount; freq++) { 1156 for (int strength = 0; strength < oldSignalStrengthCount; strength++) { 1157 if (freq >= currFreqCount || strength >= currSignalStrengthCount) { 1158 // Mismatch with the summary parcel. Consume the data but don't use it. 1159 final StopwatchTimer temp = new StopwatchTimer(null, null, -1, null, 1160 new TimeBase()); 1161 // Consume mPerStateTxDurationMs data. 1162 temp.readSummaryFromParcelLocked(in); 1163 } 1164 getTxDurationCounter(freq, strength, true).readSummaryFromParcelLocked(in); 1165 } 1166 } 1167 } 1168 1169 if (in.readInt() == 1) { 1170 for (int freq = 0; freq < oldFreqCount; freq++) { 1171 if (freq >= currFreqCount) { 1172 // Mismatch with the summary parcel. Consume the data but don't use it. 1173 final StopwatchTimer 1174 temp = new StopwatchTimer(null, null, -1, null, new TimeBase()); 1175 // Consume mPerFrequencyRxDurationMs data. 1176 temp.readSummaryFromParcelLocked(in); 1177 continue; 1178 } 1179 getRxDurationCounter(freq, true).readSummaryFromParcelLocked(in); 1180 } 1181 } 1182 } 1183 getTxDurationCounter( @erviceState.FrequencyRange int frequencyRange, int signalStrength, boolean make)1184 private LongSamplingCounter getTxDurationCounter( 1185 @ServiceState.FrequencyRange int frequencyRange, int signalStrength, boolean make) { 1186 if (mPerStateTxDurationMs == null) { 1187 if (!make) return null; 1188 1189 final int freqCount = getFrequencyRangeCount(); 1190 final int signalStrengthCount = perStateTimers[0].length; 1191 final TimeBase timeBase = perStateTimers[0][0].mTimeBase; 1192 mPerStateTxDurationMs = new LongSamplingCounter[freqCount][signalStrengthCount]; 1193 for (int freq = 0; freq < freqCount; freq++) { 1194 for (int strength = 0; strength < signalStrengthCount; strength++) { 1195 mPerStateTxDurationMs[freq][strength] = new LongSamplingCounter(timeBase); 1196 } 1197 } 1198 } 1199 if (frequencyRange < 0 || frequencyRange >= getFrequencyRangeCount()) { 1200 Slog.w(TAG, "Unexpected frequency range (" + frequencyRange 1201 + ") requested in getTxDurationCounter"); 1202 return null; 1203 } 1204 if (signalStrength < 0 || signalStrength >= perStateTimers[0].length) { 1205 Slog.w(TAG, "Unexpected signal strength (" + signalStrength 1206 + ") requested in getTxDurationCounter"); 1207 return null; 1208 } 1209 return mPerStateTxDurationMs[frequencyRange][signalStrength]; 1210 } 1211 getRxDurationCounter( @erviceState.FrequencyRange int frequencyRange, boolean make)1212 private LongSamplingCounter getRxDurationCounter( 1213 @ServiceState.FrequencyRange int frequencyRange, boolean make) { 1214 if (mPerFrequencyRxDurationMs == null) { 1215 if (!make) return null; 1216 1217 final int freqCount = getFrequencyRangeCount(); 1218 final TimeBase timeBase = perStateTimers[0][0].mTimeBase; 1219 mPerFrequencyRxDurationMs = new LongSamplingCounter[freqCount]; 1220 for (int freq = 0; freq < freqCount; freq++) { 1221 mPerFrequencyRxDurationMs[freq] = new LongSamplingCounter(timeBase); 1222 } 1223 } 1224 if (frequencyRange < 0 || frequencyRange >= getFrequencyRangeCount()) { 1225 Slog.w(TAG, "Unexpected frequency range (" + frequencyRange 1226 + ") requested in getRxDurationCounter"); 1227 return null; 1228 } 1229 return mPerFrequencyRxDurationMs[frequencyRange]; 1230 } 1231 } 1232 1233 /** 1234 * Number of frequency ranges, keep in sync with {@link ServiceState.FrequencyRange} 1235 */ 1236 private static final int NR_FREQUENCY_COUNT = 5; 1237 1238 RadioAccessTechnologyBatteryStats[] mPerRatBatteryStats = 1239 new RadioAccessTechnologyBatteryStats[RADIO_ACCESS_TECHNOLOGY_COUNT]; 1240 1241 @GuardedBy("this") getRatBatteryStatsLocked( @adioAccessTechnology int rat)1242 private RadioAccessTechnologyBatteryStats getRatBatteryStatsLocked( 1243 @RadioAccessTechnology int rat) { 1244 RadioAccessTechnologyBatteryStats stats = mPerRatBatteryStats[rat]; 1245 if (stats == null) { 1246 final int freqCount = rat == RADIO_ACCESS_TECHNOLOGY_NR ? NR_FREQUENCY_COUNT : 1; 1247 stats = new RadioAccessTechnologyBatteryStats(freqCount, mClock, mOnBatteryTimeBase); 1248 mPerRatBatteryStats[rat] = stats; 1249 } 1250 return stats; 1251 } 1252 1253 final LongSamplingCounter[] mNetworkByteActivityCounters = 1254 new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES]; 1255 1256 final LongSamplingCounter[] mNetworkPacketActivityCounters = 1257 new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES]; 1258 1259 /** 1260 * The WiFi Overall wakelock timer 1261 * This timer tracks the actual aggregate time for which MC wakelocks are enabled 1262 * since addition of per UID timers would not result in an accurate value due to overlapp of 1263 * per uid wakelock timers 1264 */ 1265 StopwatchTimer mWifiMulticastWakelockTimer; 1266 1267 /** 1268 * The WiFi controller activity (time in tx, rx, idle, and power consumed) for the device. 1269 */ 1270 ControllerActivityCounterImpl mWifiActivity; 1271 1272 /** 1273 * The Bluetooth controller activity (time in tx, rx, idle, and power consumed) for the device. 1274 */ 1275 ControllerActivityCounterImpl mBluetoothActivity; 1276 1277 /** 1278 * The Modem controller activity (time in tx, rx, idle, and power consumed) for the device. 1279 */ 1280 ControllerActivityCounterImpl mModemActivity; 1281 1282 /** 1283 * Whether the device supports WiFi controller energy reporting. This is set to true on 1284 * the first WiFi energy report. See {@link #mWifiActivity}. 1285 */ 1286 boolean mHasWifiReporting = false; 1287 1288 /** 1289 * Whether the device supports Bluetooth controller energy reporting. This is set to true on 1290 * the first Bluetooth energy report. See {@link #mBluetoothActivity}. 1291 */ 1292 boolean mHasBluetoothReporting = false; 1293 1294 /** 1295 * Whether the device supports Modem controller energy reporting. This is set to true on 1296 * the first Modem energy report. See {@link #mModemActivity}. 1297 */ 1298 boolean mHasModemReporting = false; 1299 1300 boolean mWifiOn; 1301 StopwatchTimer mWifiOnTimer; 1302 1303 boolean mGlobalWifiRunning; 1304 StopwatchTimer mGlobalWifiRunningTimer; 1305 1306 int mWifiState = -1; 1307 final StopwatchTimer[] mWifiStateTimer = new StopwatchTimer[NUM_WIFI_STATES]; 1308 1309 int mWifiSupplState = -1; 1310 final StopwatchTimer[] mWifiSupplStateTimer = new StopwatchTimer[NUM_WIFI_SUPPL_STATES]; 1311 1312 int mWifiSignalStrengthBin = -1; 1313 final StopwatchTimer[] mWifiSignalStrengthsTimer = 1314 new StopwatchTimer[NUM_WIFI_SIGNAL_STRENGTH_BINS]; 1315 1316 StopwatchTimer mWifiActiveTimer; 1317 1318 int mBluetoothScanNesting; 1319 StopwatchTimer mBluetoothScanTimer; 1320 1321 int mMobileRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW; 1322 long mMobileRadioActiveStartTimeMs; 1323 StopwatchTimer mMobileRadioActiveTimer; 1324 StopwatchTimer mMobileRadioActivePerAppTimer; 1325 LongSamplingCounter mMobileRadioActiveAdjustedTime; 1326 LongSamplingCounter mMobileRadioActiveUnknownTime; 1327 LongSamplingCounter mMobileRadioActiveUnknownCount; 1328 1329 /** 1330 * The soonest the Mobile Radio stats can be updated due to a mobile radio power state change 1331 * after it was last updated. 1332 */ 1333 @VisibleForTesting 1334 protected static final long MOBILE_RADIO_POWER_STATE_UPDATE_FREQ_MS = 1000 * 60 * 10; 1335 1336 int mWifiRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW; 1337 1338 @GuardedBy("this") 1339 @VisibleForTesting 1340 protected @Nullable MeasuredEnergyStats.Config mMeasuredEnergyStatsConfig; 1341 1342 /** 1343 * Accumulated global (generally, device-wide total) charge consumption of various consumers 1344 * while on battery. 1345 * Its '<b>custom</b> power buckets' correspond to the 1346 * {@link android.hardware.power.stats.EnergyConsumer.ordinal}s of (custom) energy consumer 1347 * type {@link android.hardware.power.stats.EnergyConsumerType#OTHER}). 1348 * 1349 * If energy consumer data is completely unavailable this will be null. 1350 */ 1351 @GuardedBy("this") 1352 @VisibleForTesting 1353 protected @Nullable MeasuredEnergyStats mGlobalMeasuredEnergyStats; 1354 /** Bluetooth Power calculator for attributing measured bluetooth charge consumption to uids */ 1355 @Nullable BluetoothPowerCalculator mBluetoothPowerCalculator = null; 1356 /** Cpu Power calculator for attributing measured cpu charge consumption to uids */ 1357 @Nullable CpuPowerCalculator mCpuPowerCalculator = null; 1358 /** Mobile Radio Power calculator for attributing measured radio charge consumption to uids */ 1359 @Nullable 1360 MobileRadioPowerCalculator mMobileRadioPowerCalculator = null; 1361 /** Wifi Power calculator for attributing measured wifi charge consumption to uids */ 1362 @Nullable WifiPowerCalculator mWifiPowerCalculator = null; 1363 1364 /** 1365 * These provide time bases that discount the time the device is plugged 1366 * in to power. 1367 */ 1368 boolean mOnBattery; 1369 @VisibleForTesting 1370 protected boolean mOnBatteryInternal; 1371 1372 /** 1373 * External reporting of whether the device is actually charging. 1374 */ 1375 boolean mCharging = true; 1376 int mLastChargingStateLevel; 1377 1378 /* 1379 * These keep track of battery levels (1-100) at the last plug event and the last unplug event. 1380 */ 1381 int mDischargeStartLevel; 1382 int mDischargeUnplugLevel; 1383 int mDischargePlugLevel; 1384 int mDischargeCurrentLevel; 1385 int mCurrentBatteryLevel; 1386 int mLowDischargeAmountSinceCharge; 1387 int mHighDischargeAmountSinceCharge; 1388 int mDischargeScreenOnUnplugLevel; 1389 int mDischargeScreenOffUnplugLevel; 1390 int mDischargeScreenDozeUnplugLevel; 1391 int mDischargeAmountScreenOn; 1392 int mDischargeAmountScreenOnSinceCharge; 1393 int mDischargeAmountScreenOff; 1394 int mDischargeAmountScreenOffSinceCharge; 1395 int mDischargeAmountScreenDoze; 1396 int mDischargeAmountScreenDozeSinceCharge; 1397 1398 private LongSamplingCounter mDischargeScreenOffCounter; 1399 private LongSamplingCounter mDischargeScreenDozeCounter; 1400 private LongSamplingCounter mDischargeCounter; 1401 private LongSamplingCounter mDischargeLightDozeCounter; 1402 private LongSamplingCounter mDischargeDeepDozeCounter; 1403 1404 static final int MAX_LEVEL_STEPS = 200; 1405 1406 int mInitStepMode = 0; 1407 int mCurStepMode = 0; 1408 int mModStepMode = 0; 1409 1410 int mLastDischargeStepLevel; 1411 int mMinDischargeStepLevel; 1412 final LevelStepTracker mDischargeStepTracker = new LevelStepTracker(MAX_LEVEL_STEPS); 1413 final LevelStepTracker mDailyDischargeStepTracker = new LevelStepTracker(MAX_LEVEL_STEPS*2); 1414 ArrayList<PackageChange> mDailyPackageChanges; 1415 1416 int mLastChargeStepLevel; 1417 int mMaxChargeStepLevel; 1418 final LevelStepTracker mChargeStepTracker = new LevelStepTracker(MAX_LEVEL_STEPS); 1419 final LevelStepTracker mDailyChargeStepTracker = new LevelStepTracker(MAX_LEVEL_STEPS*2); 1420 1421 static final int MAX_DAILY_ITEMS = 10; 1422 1423 long mDailyStartTimeMs = 0; 1424 long mNextMinDailyDeadlineMs = 0; 1425 long mNextMaxDailyDeadlineMs = 0; 1426 1427 final ArrayList<DailyItem> mDailyItems = new ArrayList<>(); 1428 1429 long mLastWriteTimeMs = 0; // Milliseconds 1430 1431 private int mPhoneServiceState = -1; 1432 private int mPhoneServiceStateRaw = -1; 1433 private int mPhoneSimStateRaw = -1; 1434 1435 private int mNumConnectivityChange; 1436 1437 private int mBatteryVoltageMv = -1; 1438 private int mEstimatedBatteryCapacityMah = -1; 1439 1440 private int mLastLearnedBatteryCapacityUah = -1; 1441 private int mMinLearnedBatteryCapacityUah = -1; 1442 private int mMaxLearnedBatteryCapacityUah = -1; 1443 1444 private long mBatteryTimeToFullSeconds = -1; 1445 1446 private boolean mCpuFreqsInitialized; 1447 private long[] mCpuFreqs; 1448 private LongArrayMultiStateCounter.LongArrayContainer mTmpCpuTimeInFreq; 1449 1450 /** 1451 * Times spent by the system server threads handling incoming binder requests. 1452 */ 1453 private LongSamplingCounterArray mBinderThreadCpuTimesUs; 1454 1455 @VisibleForTesting 1456 protected PowerProfile mPowerProfile; 1457 1458 @VisibleForTesting 1459 @GuardedBy("this") 1460 protected final Constants mConstants; 1461 1462 /* 1463 * Holds a SamplingTimer associated with each Resource Power Manager state and voter, 1464 * recording their times when on-battery (regardless of screen state). 1465 */ 1466 private final HashMap<String, SamplingTimer> mRpmStats = new HashMap<>(); 1467 /** Times for each Resource Power Manager state and voter when screen-off and on-battery. */ 1468 private final HashMap<String, SamplingTimer> mScreenOffRpmStats = new HashMap<>(); 1469 1470 @Override getRpmStats()1471 public Map<String, ? extends Timer> getRpmStats() { 1472 return mRpmStats; 1473 } 1474 1475 // TODO: Note: screenOffRpmStats has been disabled via SCREEN_OFF_RPM_STATS_ENABLED. 1476 @Override getScreenOffRpmStats()1477 public Map<String, ? extends Timer> getScreenOffRpmStats() { 1478 return mScreenOffRpmStats; 1479 } 1480 1481 /* 1482 * Holds a SamplingTimer associated with each kernel wakelock name being tracked. 1483 */ 1484 private final HashMap<String, SamplingTimer> mKernelWakelockStats = new HashMap<>(); 1485 1486 @UnsupportedAppUsage getKernelWakelockStats()1487 public Map<String, ? extends Timer> getKernelWakelockStats() { 1488 return mKernelWakelockStats; 1489 } 1490 1491 @Override getWakeLockStats()1492 public WakeLockStats getWakeLockStats() { 1493 final long realtimeMs = mClock.elapsedRealtime(); 1494 final long realtimeUs = realtimeMs * 1000; 1495 List<WakeLockStats.WakeLock> uidWakeLockStats = new ArrayList<>(); 1496 for (int i = mUidStats.size() - 1; i >= 0; i--) { 1497 final Uid uid = mUidStats.valueAt(i); 1498 final ArrayMap<String, ? extends BatteryStats.Uid.Wakelock> wakelockStats = 1499 uid.mWakelockStats.getMap(); 1500 for (int j = wakelockStats.size() - 1; j >= 0; j--) { 1501 final String name = wakelockStats.keyAt(j); 1502 final Uid.Wakelock wakelock = (Uid.Wakelock) wakelockStats.valueAt(j); 1503 final DualTimer timer = wakelock.mTimerPartial; 1504 if (timer != null) { 1505 final long totalTimeLockHeldMs = 1506 timer.getTotalTimeLocked(realtimeUs, STATS_SINCE_CHARGED) / 1000; 1507 if (totalTimeLockHeldMs != 0) { 1508 uidWakeLockStats.add( 1509 new WakeLockStats.WakeLock(uid.getUid(), name, 1510 timer.getCountLocked(STATS_SINCE_CHARGED), 1511 totalTimeLockHeldMs, 1512 timer.isRunningLocked() 1513 ? timer.getCurrentDurationMsLocked(realtimeMs) 1514 : 0)); 1515 } 1516 } 1517 } 1518 } 1519 return new WakeLockStats(uidWakeLockStats); 1520 } 1521 1522 @Override 1523 @GuardedBy("this") getBluetoothBatteryStats()1524 public BluetoothBatteryStats getBluetoothBatteryStats() { 1525 final long elapsedRealtimeUs = mClock.elapsedRealtime() * 1000; 1526 ArrayList<BluetoothBatteryStats.UidStats> uidStats = new ArrayList<>(); 1527 for (int i = mUidStats.size() - 1; i >= 0; i--) { 1528 final Uid uid = mUidStats.valueAt(i); 1529 final Timer scanTimer = uid.getBluetoothScanTimer(); 1530 final long scanTimeMs = 1531 scanTimer != null ? scanTimer.getTotalTimeLocked( 1532 elapsedRealtimeUs, STATS_SINCE_CHARGED) / 1000 : 0; 1533 1534 final Timer unoptimizedScanTimer = uid.getBluetoothUnoptimizedScanTimer(); 1535 final long unoptimizedScanTimeMs = 1536 unoptimizedScanTimer != null ? unoptimizedScanTimer.getTotalTimeLocked( 1537 elapsedRealtimeUs, STATS_SINCE_CHARGED) / 1000 : 0; 1538 1539 final Counter scanResultCounter = uid.getBluetoothScanResultCounter(); 1540 final int scanResultCount = 1541 scanResultCounter != null ? scanResultCounter.getCountLocked( 1542 STATS_SINCE_CHARGED) : 0; 1543 1544 final ControllerActivityCounter counter = uid.getBluetoothControllerActivity(); 1545 final long rxTimeMs = counter != null ? counter.getRxTimeCounter().getCountLocked( 1546 STATS_SINCE_CHARGED) : 0; 1547 final long txTimeMs = counter != null ? counter.getTxTimeCounters()[0].getCountLocked( 1548 STATS_SINCE_CHARGED) : 0; 1549 1550 if (scanTimeMs != 0 || unoptimizedScanTimeMs != 0 || scanResultCount != 0 1551 || rxTimeMs != 0 || txTimeMs != 0) { 1552 uidStats.add(new BluetoothBatteryStats.UidStats(uid.getUid(), 1553 scanTimeMs, 1554 unoptimizedScanTimeMs, 1555 scanResultCount, 1556 rxTimeMs, 1557 txTimeMs)); 1558 } 1559 } 1560 1561 return new BluetoothBatteryStats(uidStats); 1562 } 1563 1564 String mLastWakeupReason = null; 1565 long mLastWakeupUptimeMs = 0; 1566 private final HashMap<String, SamplingTimer> mWakeupReasonStats = new HashMap<>(); 1567 getWakeupReasonStats()1568 public Map<String, ? extends Timer> getWakeupReasonStats() { 1569 return mWakeupReasonStats; 1570 } 1571 1572 @Override getUahDischarge(int which)1573 public long getUahDischarge(int which) { 1574 return mDischargeCounter.getCountLocked(which); 1575 } 1576 1577 @Override getUahDischargeScreenOff(int which)1578 public long getUahDischargeScreenOff(int which) { 1579 return mDischargeScreenOffCounter.getCountLocked(which); 1580 } 1581 1582 @Override getUahDischargeScreenDoze(int which)1583 public long getUahDischargeScreenDoze(int which) { 1584 return mDischargeScreenDozeCounter.getCountLocked(which); 1585 } 1586 1587 @Override getUahDischargeLightDoze(int which)1588 public long getUahDischargeLightDoze(int which) { 1589 return mDischargeLightDozeCounter.getCountLocked(which); 1590 } 1591 1592 @Override getUahDischargeDeepDoze(int which)1593 public long getUahDischargeDeepDoze(int which) { 1594 return mDischargeDeepDozeCounter.getCountLocked(which); 1595 } 1596 1597 @Override getEstimatedBatteryCapacity()1598 public int getEstimatedBatteryCapacity() { 1599 return mEstimatedBatteryCapacityMah; 1600 } 1601 1602 @Override getLearnedBatteryCapacity()1603 public int getLearnedBatteryCapacity() { 1604 return mLastLearnedBatteryCapacityUah; 1605 } 1606 1607 @Override getMinLearnedBatteryCapacity()1608 public int getMinLearnedBatteryCapacity() { 1609 return mMinLearnedBatteryCapacityUah; 1610 } 1611 1612 @Override getMaxLearnedBatteryCapacity()1613 public int getMaxLearnedBatteryCapacity() { 1614 return mMaxLearnedBatteryCapacityUah; 1615 } 1616 BatteryStatsImpl()1617 public BatteryStatsImpl() { 1618 this(Clock.SYSTEM_CLOCK); 1619 } 1620 BatteryStatsImpl(Clock clock)1621 public BatteryStatsImpl(Clock clock) { 1622 this(clock, (File) null); 1623 } 1624 BatteryStatsImpl(Clock clock, File historyDirectory)1625 public BatteryStatsImpl(Clock clock, File historyDirectory) { 1626 init(clock); 1627 mStartClockTimeMs = clock.currentTimeMillis(); 1628 mCheckinFile = null; 1629 mDailyFile = null; 1630 if (historyDirectory == null) { 1631 mStatsFile = null; 1632 mBatteryStatsHistory = new BatteryStatsHistory(mHistoryBuffer); 1633 } else { 1634 mStatsFile = new AtomicFile(new File(historyDirectory, "batterystats.bin")); 1635 mBatteryStatsHistory = new BatteryStatsHistory(this, historyDirectory, mHistoryBuffer); 1636 } 1637 mHandler = null; 1638 mPlatformIdleStateCallback = null; 1639 mMeasuredEnergyRetriever = null; 1640 mUserInfoProvider = null; 1641 mConstants = new Constants(mHandler); 1642 clearHistoryLocked(); 1643 } 1644 init(Clock clock)1645 private void init(Clock clock) { 1646 mClock = clock; 1647 mCpuUidUserSysTimeReader = new KernelCpuUidUserSysTimeReader(true, clock); 1648 mCpuUidFreqTimeReader = new KernelCpuUidFreqTimeReader(true, clock); 1649 mCpuUidActiveTimeReader = new KernelCpuUidActiveTimeReader(true, clock); 1650 mCpuUidClusterTimeReader = new KernelCpuUidClusterTimeReader(true, clock); 1651 } 1652 1653 /** 1654 * TimeBase observer. 1655 */ 1656 public interface TimeBaseObs { onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)1657 void onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs); onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)1658 void onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs); 1659 1660 /** 1661 * Reset the observer's state, returns true if the timer/counter is inactive 1662 * so it can be destroyed. 1663 * @param detachIfReset detach if true, no-op if false. 1664 * @return Returns true if the timer/counter is inactive and can be destroyed. 1665 */ reset(boolean detachIfReset)1666 default boolean reset(boolean detachIfReset) { 1667 return reset(detachIfReset, SystemClock.elapsedRealtime() * 1000); 1668 } 1669 1670 /** 1671 * @see #reset(boolean) 1672 * @param detachIfReset detach if true, no-op if false. 1673 * @param elapsedRealtimeUs the timestamp when this reset is actually reequested 1674 * @return Returns true if the timer/counter is inactive and can be destroyed. 1675 */ reset(boolean detachIfReset, long elapsedRealtimeUs)1676 boolean reset(boolean detachIfReset, long elapsedRealtimeUs); 1677 1678 /** 1679 * Detach the observer from TimeBase. 1680 */ detach()1681 void detach(); 1682 } 1683 1684 // methods are protected not private to be VisibleForTesting 1685 public static class TimeBase { 1686 protected final Collection<TimeBaseObs> mObservers; 1687 1688 // All below time metrics are in microseconds. 1689 protected long mUptimeUs; 1690 protected long mRealtimeUs; 1691 1692 protected boolean mRunning; 1693 1694 protected long mPastUptimeUs; 1695 protected long mUptimeStartUs; 1696 protected long mPastRealtimeUs; 1697 protected long mRealtimeStartUs; 1698 protected long mUnpluggedUptimeUs; 1699 protected long mUnpluggedRealtimeUs; 1700 dump(PrintWriter pw, String prefix)1701 public void dump(PrintWriter pw, String prefix) { 1702 StringBuilder sb = new StringBuilder(128); 1703 pw.print(prefix); pw.print("mRunning="); pw.println(mRunning); 1704 sb.setLength(0); 1705 sb.append(prefix); 1706 sb.append("mUptime="); 1707 formatTimeMs(sb, mUptimeUs / 1000); 1708 pw.println(sb.toString()); 1709 sb.setLength(0); 1710 sb.append(prefix); 1711 sb.append("mRealtime="); 1712 formatTimeMs(sb, mRealtimeUs / 1000); 1713 pw.println(sb.toString()); 1714 sb.setLength(0); 1715 sb.append(prefix); 1716 sb.append("mPastUptime="); 1717 formatTimeMs(sb, mPastUptimeUs / 1000); sb.append("mUptimeStart="); 1718 formatTimeMs(sb, mUptimeStartUs / 1000); 1719 sb.append("mUnpluggedUptime="); formatTimeMs(sb, mUnpluggedUptimeUs / 1000); 1720 pw.println(sb.toString()); 1721 sb.setLength(0); 1722 sb.append(prefix); 1723 sb.append("mPastRealtime="); 1724 formatTimeMs(sb, mPastRealtimeUs / 1000); sb.append("mRealtimeStart="); 1725 formatTimeMs(sb, mRealtimeStartUs / 1000); 1726 sb.append("mUnpluggedRealtime="); formatTimeMs(sb, mUnpluggedRealtimeUs / 1000); 1727 pw.println(sb.toString()); 1728 } 1729 /** 1730 * The mObservers of TimeBase in BatteryStatsImpl object can contain up to 20k entries. 1731 * The mObservers of TimeBase in BatteryStatsImpl.Uid object only contains a few or tens of 1732 * entries. 1733 * mObservers must have good performance on add(), remove(), also be memory efficient. 1734 * This is why we provide isLongList parameter for long and short list user cases. 1735 * @param isLongList If true, use HashSet for mObservers list. 1736 * If false, use ArrayList for mObservers list. 1737 */ TimeBase(boolean isLongList)1738 public TimeBase(boolean isLongList) { 1739 mObservers = isLongList ? new HashSet<>() : new ArrayList<>(); 1740 } 1741 TimeBase()1742 public TimeBase() { 1743 this(false); 1744 } 1745 add(TimeBaseObs observer)1746 public void add(TimeBaseObs observer) { 1747 mObservers.add(observer); 1748 } 1749 remove(TimeBaseObs observer)1750 public void remove(TimeBaseObs observer) { 1751 mObservers.remove(observer); 1752 } 1753 hasObserver(TimeBaseObs observer)1754 public boolean hasObserver(TimeBaseObs observer) { 1755 return mObservers.contains(observer); 1756 } 1757 init(long uptimeUs, long elapsedRealtimeUs)1758 public void init(long uptimeUs, long elapsedRealtimeUs) { 1759 mRealtimeUs = 0; 1760 mUptimeUs = 0; 1761 mPastUptimeUs = 0; 1762 mPastRealtimeUs = 0; 1763 mUptimeStartUs = uptimeUs; 1764 mRealtimeStartUs = elapsedRealtimeUs; 1765 mUnpluggedUptimeUs = getUptime(mUptimeStartUs); 1766 mUnpluggedRealtimeUs = getRealtime(mRealtimeStartUs); 1767 } 1768 reset(long uptimeUs, long elapsedRealtimeUs)1769 public void reset(long uptimeUs, long elapsedRealtimeUs) { 1770 if (!mRunning) { 1771 mPastUptimeUs = 0; 1772 mPastRealtimeUs = 0; 1773 } else { 1774 mUptimeStartUs = uptimeUs; 1775 mRealtimeStartUs = elapsedRealtimeUs; 1776 // TODO: Since mUptimeStartUs was just reset and we are running, getUptime will 1777 // just return mPastUptimeUs. Also, are we sure we don't want to reset that? 1778 mUnpluggedUptimeUs = getUptime(uptimeUs); 1779 // TODO: likewise. 1780 mUnpluggedRealtimeUs = getRealtime(elapsedRealtimeUs); 1781 } 1782 } 1783 computeUptime(long curTimeUs, int which)1784 public long computeUptime(long curTimeUs, int which) { 1785 return mUptimeUs + getUptime(curTimeUs); 1786 } 1787 computeRealtime(long curTimeUs, int which)1788 public long computeRealtime(long curTimeUs, int which) { 1789 return mRealtimeUs + getRealtime(curTimeUs); 1790 } 1791 getUptime(long curTimeUs)1792 public long getUptime(long curTimeUs) { 1793 long time = mPastUptimeUs; 1794 if (mRunning) { 1795 time += curTimeUs - mUptimeStartUs; 1796 } 1797 return time; 1798 } 1799 getRealtime(long curTimeUs)1800 public long getRealtime(long curTimeUs) { 1801 long time = mPastRealtimeUs; 1802 if (mRunning) { 1803 time += curTimeUs - mRealtimeStartUs; 1804 } 1805 return time; 1806 } 1807 getUptimeStart()1808 public long getUptimeStart() { 1809 return mUptimeStartUs; 1810 } 1811 getRealtimeStart()1812 public long getRealtimeStart() { 1813 return mRealtimeStartUs; 1814 } 1815 isRunning()1816 public boolean isRunning() { 1817 return mRunning; 1818 } 1819 setRunning(boolean running, long uptimeUs, long elapsedRealtimeUs)1820 public boolean setRunning(boolean running, long uptimeUs, long elapsedRealtimeUs) { 1821 if (mRunning != running) { 1822 mRunning = running; 1823 if (running) { 1824 mUptimeStartUs = uptimeUs; 1825 mRealtimeStartUs = elapsedRealtimeUs; 1826 long batteryUptimeUs = mUnpluggedUptimeUs = getUptime(uptimeUs); 1827 long batteryRealtimeUs = mUnpluggedRealtimeUs = getRealtime(elapsedRealtimeUs); 1828 // Normally we do not use Iterator in framework code to avoid alloc/dealloc 1829 // Iterator object, here is an exception because mObservers' type is Collection 1830 // instead of list. 1831 final Iterator<TimeBaseObs> iter = mObservers.iterator(); 1832 while (iter.hasNext()) { 1833 iter.next().onTimeStarted( 1834 elapsedRealtimeUs, batteryUptimeUs, batteryRealtimeUs); 1835 } 1836 } else { 1837 mPastUptimeUs += uptimeUs - mUptimeStartUs; 1838 mPastRealtimeUs += elapsedRealtimeUs - mRealtimeStartUs; 1839 long batteryUptimeUs = getUptime(uptimeUs); 1840 long batteryRealtimeUs = getRealtime(elapsedRealtimeUs); 1841 // Normally we do not use Iterator in framework code to avoid alloc/dealloc 1842 // Iterator object, here is an exception because mObservers' type is Collection 1843 // instead of list. 1844 final Iterator<TimeBaseObs> iter = mObservers.iterator(); 1845 while (iter.hasNext()) { 1846 iter.next().onTimeStopped( 1847 elapsedRealtimeUs, batteryUptimeUs, batteryRealtimeUs); 1848 } 1849 } 1850 return true; 1851 } 1852 return false; 1853 } 1854 readSummaryFromParcel(Parcel in)1855 public void readSummaryFromParcel(Parcel in) { 1856 mUptimeUs = in.readLong(); 1857 mRealtimeUs = in.readLong(); 1858 } 1859 writeSummaryToParcel(Parcel out, long uptimeUs, long elapsedRealtimeUs)1860 public void writeSummaryToParcel(Parcel out, long uptimeUs, long elapsedRealtimeUs) { 1861 out.writeLong(computeUptime(uptimeUs, STATS_SINCE_CHARGED)); 1862 out.writeLong(computeRealtime(elapsedRealtimeUs, STATS_SINCE_CHARGED)); 1863 } 1864 readFromParcel(Parcel in)1865 public void readFromParcel(Parcel in) { 1866 mRunning = false; 1867 mUptimeUs = in.readLong(); 1868 mPastUptimeUs = in.readLong(); 1869 mUptimeStartUs = in.readLong(); 1870 mRealtimeUs = in.readLong(); 1871 mPastRealtimeUs = in.readLong(); 1872 mRealtimeStartUs = in.readLong(); 1873 mUnpluggedUptimeUs = in.readLong(); 1874 mUnpluggedRealtimeUs = in.readLong(); 1875 } 1876 writeToParcel(Parcel out, long uptimeUs, long elapsedRealtimeUs)1877 public void writeToParcel(Parcel out, long uptimeUs, long elapsedRealtimeUs) { 1878 final long runningUptime = getUptime(uptimeUs); 1879 final long runningRealtime = getRealtime(elapsedRealtimeUs); 1880 out.writeLong(mUptimeUs); 1881 out.writeLong(runningUptime); 1882 out.writeLong(mUptimeStartUs); 1883 out.writeLong(mRealtimeUs); 1884 out.writeLong(runningRealtime); 1885 out.writeLong(mRealtimeStartUs); 1886 out.writeLong(mUnpluggedUptimeUs); 1887 out.writeLong(mUnpluggedRealtimeUs); 1888 } 1889 } 1890 1891 /** 1892 * State for keeping track of counting information. 1893 */ 1894 public static class Counter extends BatteryStats.Counter implements TimeBaseObs { 1895 @UnsupportedAppUsage 1896 final AtomicInteger mCount = new AtomicInteger(); 1897 final TimeBase mTimeBase; 1898 Counter(TimeBase timeBase, Parcel in)1899 public Counter(TimeBase timeBase, Parcel in) { 1900 mTimeBase = timeBase; 1901 mCount.set(in.readInt()); 1902 timeBase.add(this); 1903 } 1904 Counter(TimeBase timeBase)1905 public Counter(TimeBase timeBase) { 1906 mTimeBase = timeBase; 1907 timeBase.add(this); 1908 } 1909 writeToParcel(Parcel out)1910 public void writeToParcel(Parcel out) { 1911 out.writeInt(mCount.get()); 1912 } 1913 1914 @Override onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)1915 public void onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { 1916 } 1917 1918 @Override onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)1919 public void onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { 1920 } 1921 1922 /** 1923 * Writes a possibly null Counter to a Parcel. 1924 * 1925 * @param out the Parcel to be written to. 1926 * @param counter a Counter, or null. 1927 */ writeCounterToParcel(Parcel out, @Nullable Counter counter)1928 public static void writeCounterToParcel(Parcel out, @Nullable Counter counter) { 1929 if (counter == null) { 1930 out.writeInt(0); // indicates null 1931 return; 1932 } 1933 out.writeInt(1); // indicates non-null 1934 1935 counter.writeToParcel(out); 1936 } 1937 1938 /** 1939 * Reads a Counter that was written using {@link #writeCounterToParcel(Parcel, Counter)}. 1940 * @param timeBase the timebase to assign to the Counter 1941 * @param in the parcel to read from 1942 * @return the Counter or null. 1943 */ 1944 @Nullable readCounterFromParcel(TimeBase timeBase, Parcel in)1945 public static Counter readCounterFromParcel(TimeBase timeBase, Parcel in) { 1946 if (in.readInt() == 0) { 1947 return null; 1948 } 1949 return new Counter(timeBase, in); 1950 } 1951 1952 @Override getCountLocked(int which)1953 public int getCountLocked(int which) { 1954 return mCount.get(); 1955 } 1956 logState(Printer pw, String prefix)1957 public void logState(Printer pw, String prefix) { 1958 pw.println(prefix + "mCount=" + mCount.get()); 1959 } 1960 1961 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) stepAtomic()1962 public void stepAtomic() { 1963 if (mTimeBase.isRunning()) { 1964 mCount.incrementAndGet(); 1965 } 1966 } 1967 addAtomic(int delta)1968 void addAtomic(int delta) { 1969 if (mTimeBase.isRunning()) { 1970 mCount.addAndGet(delta); 1971 } 1972 } 1973 1974 /** 1975 * Clear state of this counter. 1976 */ 1977 @Override reset(boolean detachIfReset, long elapsedRealtimeUs )1978 public boolean reset(boolean detachIfReset, long elapsedRealtimeUs /* unused */) { 1979 mCount.set(0); 1980 if (detachIfReset) { 1981 detach(); 1982 } 1983 return true; 1984 } 1985 1986 @Override detach()1987 public void detach() { 1988 mTimeBase.remove(this); 1989 } 1990 1991 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) writeSummaryFromParcelLocked(Parcel out)1992 public void writeSummaryFromParcelLocked(Parcel out) { 1993 out.writeInt(mCount.get()); 1994 } 1995 1996 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) readSummaryFromParcelLocked(Parcel in)1997 public void readSummaryFromParcelLocked(Parcel in) { 1998 mCount.set(in.readInt()); 1999 } 2000 } 2001 2002 @VisibleForTesting 2003 public static class LongSamplingCounterArray extends LongCounterArray implements TimeBaseObs { 2004 final TimeBase mTimeBase; 2005 public long[] mCounts; 2006 LongSamplingCounterArray(TimeBase timeBase, Parcel in)2007 private LongSamplingCounterArray(TimeBase timeBase, Parcel in) { 2008 mTimeBase = timeBase; 2009 mCounts = in.createLongArray(); 2010 timeBase.add(this); 2011 } 2012 LongSamplingCounterArray(TimeBase timeBase)2013 public LongSamplingCounterArray(TimeBase timeBase) { 2014 mTimeBase = timeBase; 2015 timeBase.add(this); 2016 } 2017 writeToParcel(Parcel out)2018 private void writeToParcel(Parcel out) { 2019 out.writeLongArray(mCounts); 2020 } 2021 2022 @Override onTimeStarted(long elapsedRealTimeUs, long baseUptimeUs, long baseRealtimeUs)2023 public void onTimeStarted(long elapsedRealTimeUs, long baseUptimeUs, long baseRealtimeUs) { 2024 } 2025 2026 @Override onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)2027 public void onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { 2028 } 2029 2030 @Override getCountsLocked(int which)2031 public long[] getCountsLocked(int which) { 2032 return mCounts == null ? null : Arrays.copyOf(mCounts, mCounts.length); 2033 } 2034 2035 @Override logState(Printer pw, String prefix)2036 public void logState(Printer pw, String prefix) { 2037 pw.println(prefix + "mCounts=" + Arrays.toString(mCounts)); 2038 } 2039 addCountLocked(long[] counts)2040 public void addCountLocked(long[] counts) { 2041 addCountLocked(counts, mTimeBase.isRunning()); 2042 } 2043 addCountLocked(long[] counts, boolean isRunning)2044 public void addCountLocked(long[] counts, boolean isRunning) { 2045 if (counts == null) { 2046 return; 2047 } 2048 if (isRunning) { 2049 if (mCounts == null) { 2050 mCounts = new long[counts.length]; 2051 } 2052 for (int i = 0; i < counts.length; ++i) { 2053 mCounts[i] += counts[i]; 2054 } 2055 } 2056 } 2057 getSize()2058 public int getSize() { 2059 return mCounts == null ? 0 : mCounts.length; 2060 } 2061 2062 /** 2063 * Clear state of this counter. 2064 */ 2065 @Override reset(boolean detachIfReset, long elapsedRealtimeUs )2066 public boolean reset(boolean detachIfReset, long elapsedRealtimeUs /* unused */) { 2067 if (mCounts != null) { 2068 Arrays.fill(mCounts, 0); 2069 } 2070 if (detachIfReset) { 2071 detach(); 2072 } 2073 return true; 2074 } 2075 2076 @Override detach()2077 public void detach() { 2078 mTimeBase.remove(this); 2079 } 2080 writeSummaryToParcelLocked(Parcel out)2081 private void writeSummaryToParcelLocked(Parcel out) { 2082 out.writeLongArray(mCounts); 2083 } 2084 readSummaryFromParcelLocked(Parcel in)2085 private void readSummaryFromParcelLocked(Parcel in) { 2086 mCounts = in.createLongArray(); 2087 } 2088 writeToParcel(Parcel out, LongSamplingCounterArray counterArray)2089 public static void writeToParcel(Parcel out, LongSamplingCounterArray counterArray) { 2090 if (counterArray != null) { 2091 out.writeInt(1); 2092 counterArray.writeToParcel(out); 2093 } else { 2094 out.writeInt(0); 2095 } 2096 } 2097 readFromParcel(Parcel in, TimeBase timeBase)2098 public static LongSamplingCounterArray readFromParcel(Parcel in, TimeBase timeBase) { 2099 if (in.readInt() != 0) { 2100 return new LongSamplingCounterArray(timeBase, in); 2101 } else { 2102 return null; 2103 } 2104 } 2105 writeSummaryToParcelLocked(Parcel out, LongSamplingCounterArray counterArray)2106 public static void writeSummaryToParcelLocked(Parcel out, 2107 LongSamplingCounterArray counterArray) { 2108 if (counterArray != null) { 2109 out.writeInt(1); 2110 counterArray.writeSummaryToParcelLocked(out); 2111 } else { 2112 out.writeInt(0); 2113 } 2114 } 2115 readSummaryFromParcelLocked(Parcel in, TimeBase timeBase)2116 public static LongSamplingCounterArray readSummaryFromParcelLocked(Parcel in, 2117 TimeBase timeBase) { 2118 if (in.readInt() != 0) { 2119 final LongSamplingCounterArray counterArray 2120 = new LongSamplingCounterArray(timeBase); 2121 counterArray.readSummaryFromParcelLocked(in); 2122 return counterArray; 2123 } else { 2124 return null; 2125 } 2126 } 2127 } 2128 2129 private static class TimeMultiStateCounter extends LongCounter implements TimeBaseObs { 2130 private final TimeBase mTimeBase; 2131 private final LongMultiStateCounter mCounter; 2132 TimeMultiStateCounter(TimeBase timeBase, int stateCount, long timestampMs)2133 private TimeMultiStateCounter(TimeBase timeBase, int stateCount, long timestampMs) { 2134 this(timeBase, new LongMultiStateCounter(stateCount), timestampMs); 2135 } 2136 TimeMultiStateCounter(TimeBase timeBase, LongMultiStateCounter counter, long timestampMs)2137 private TimeMultiStateCounter(TimeBase timeBase, LongMultiStateCounter counter, 2138 long timestampMs) { 2139 mTimeBase = timeBase; 2140 mCounter = counter; 2141 mCounter.setEnabled(mTimeBase.isRunning(), timestampMs); 2142 timeBase.add(this); 2143 } 2144 2145 @Nullable readFromParcel(Parcel in, TimeBase timeBase, int stateCount, long timestampMs)2146 private static TimeMultiStateCounter readFromParcel(Parcel in, TimeBase timeBase, 2147 int stateCount, long timestampMs) { 2148 LongMultiStateCounter counter = LongMultiStateCounter.CREATOR.createFromParcel(in); 2149 if (counter.getStateCount() != stateCount) { 2150 return null; 2151 } 2152 return new TimeMultiStateCounter(timeBase, counter, timestampMs); 2153 } 2154 writeToParcel(Parcel out)2155 private void writeToParcel(Parcel out) { 2156 mCounter.writeToParcel(out, 0); 2157 } 2158 2159 @Override onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)2160 public void onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { 2161 mCounter.setEnabled(true, elapsedRealtimeUs / 1000); 2162 } 2163 2164 @Override onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)2165 public void onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { 2166 mCounter.setEnabled(false, elapsedRealtimeUs / 1000); 2167 } 2168 getStateCount()2169 public int getStateCount() { 2170 return mCounter.getStateCount(); 2171 } 2172 setState(@atteryConsumer.ProcessState int processState, long elapsedRealtimeMs)2173 private void setState(@BatteryConsumer.ProcessState int processState, 2174 long elapsedRealtimeMs) { 2175 mCounter.setState(processState, elapsedRealtimeMs); 2176 } 2177 update(long value, long timestampMs)2178 private long update(long value, long timestampMs) { 2179 return mCounter.updateValue(value, timestampMs); 2180 } 2181 increment(long increment, long timestampMs)2182 private void increment(long increment, long timestampMs) { 2183 mCounter.incrementValue(increment, timestampMs); 2184 } 2185 2186 /** 2187 * Returns accumulated count for the specified state. 2188 */ getCountForProcessState(@atteryConsumer.ProcessState int procState)2189 public long getCountForProcessState(@BatteryConsumer.ProcessState int procState) { 2190 return mCounter.getCount(procState); 2191 } 2192 getTotalCountLocked()2193 public long getTotalCountLocked() { 2194 return mCounter.getTotalCount(); 2195 } 2196 2197 @Override getCountLocked(int statsType)2198 public long getCountLocked(int statsType) { 2199 return getTotalCountLocked(); 2200 } 2201 2202 @Override logState(Printer pw, String prefix)2203 public void logState(Printer pw, String prefix) { 2204 pw.println(prefix + "mCounter=" + mCounter); 2205 } 2206 2207 /** 2208 * Clears state of this counter. 2209 */ 2210 @Override reset(boolean detachIfReset, long elapsedRealtimeUs )2211 public boolean reset(boolean detachIfReset, long elapsedRealtimeUs /* unused */) { 2212 mCounter.reset(); 2213 if (detachIfReset) { 2214 detach(); 2215 } 2216 return true; 2217 } 2218 2219 @Override detach()2220 public void detach() { 2221 mTimeBase.remove(this); 2222 } 2223 } 2224 2225 private static class TimeInFreqMultiStateCounter implements TimeBaseObs { 2226 private final TimeBase mTimeBase; 2227 private final LongArrayMultiStateCounter mCounter; 2228 TimeInFreqMultiStateCounter(TimeBase timeBase, int stateCount, int cpuFreqCount, long timestampMs)2229 private TimeInFreqMultiStateCounter(TimeBase timeBase, int stateCount, int cpuFreqCount, 2230 long timestampMs) { 2231 this(timeBase, new LongArrayMultiStateCounter(stateCount, cpuFreqCount), timestampMs); 2232 } 2233 TimeInFreqMultiStateCounter(TimeBase timeBase, LongArrayMultiStateCounter counter, long timestampMs)2234 private TimeInFreqMultiStateCounter(TimeBase timeBase, LongArrayMultiStateCounter counter, 2235 long timestampMs) { 2236 mTimeBase = timeBase; 2237 mCounter = counter; 2238 mCounter.setEnabled(mTimeBase.isRunning(), timestampMs); 2239 timeBase.add(this); 2240 } 2241 writeToParcel(Parcel out)2242 private void writeToParcel(Parcel out) { 2243 mCounter.writeToParcel(out, 0); 2244 } 2245 2246 @Nullable readFromParcel(Parcel in, TimeBase timeBase, int stateCount, int cpuFreqCount, long timestampMs)2247 private static TimeInFreqMultiStateCounter readFromParcel(Parcel in, TimeBase timeBase, 2248 int stateCount, int cpuFreqCount, long timestampMs) { 2249 // Read the object from the Parcel, whether it's usable or not 2250 LongArrayMultiStateCounter counter = 2251 LongArrayMultiStateCounter.CREATOR.createFromParcel(in); 2252 if (counter.getStateCount() != stateCount 2253 || counter.getArrayLength() != cpuFreqCount) { 2254 return null; 2255 } 2256 return new TimeInFreqMultiStateCounter(timeBase, counter, timestampMs); 2257 } 2258 2259 @Override onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)2260 public void onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { 2261 mCounter.setEnabled(true, elapsedRealtimeUs / 1000); 2262 } 2263 2264 @Override onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)2265 public void onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { 2266 mCounter.setEnabled(false, elapsedRealtimeUs / 1000); 2267 } 2268 getCounter()2269 public LongArrayMultiStateCounter getCounter() { 2270 return mCounter; 2271 } 2272 getStateCount()2273 public int getStateCount() { 2274 return mCounter.getStateCount(); 2275 } 2276 setTrackingEnabled(boolean enabled, long timestampMs)2277 public void setTrackingEnabled(boolean enabled, long timestampMs) { 2278 mCounter.setEnabled(enabled && mTimeBase.isRunning(), timestampMs); 2279 } 2280 setState(int uidRunningState, long elapsedRealtimeMs)2281 private void setState(int uidRunningState, long elapsedRealtimeMs) { 2282 mCounter.setState(uidRunningState, elapsedRealtimeMs); 2283 } 2284 2285 /** 2286 * Returns accumulated counts for the specified state, or false if all counts are zero. 2287 */ getCountsLocked(long[] counts, int procState)2288 public boolean getCountsLocked(long[] counts, int procState) { 2289 if (counts.length != mCounter.getArrayLength()) { 2290 return false; 2291 } 2292 2293 mCounter.getCounts(counts, procState); 2294 2295 // Return counts only if at least one of the elements is non-zero. 2296 for (int i = counts.length - 1; i >= 0; --i) { 2297 if (counts[i] != 0) { 2298 return true; 2299 } 2300 } 2301 return false; 2302 } 2303 logState(Printer pw, String prefix)2304 public void logState(Printer pw, String prefix) { 2305 pw.println(prefix + "mCounter=" + mCounter); 2306 } 2307 2308 /** 2309 * Clears state of this counter. 2310 */ 2311 @Override reset(boolean detachIfReset, long elapsedRealtimeUs )2312 public boolean reset(boolean detachIfReset, long elapsedRealtimeUs /* unused */) { 2313 mCounter.reset(); 2314 if (detachIfReset) { 2315 detach(); 2316 } 2317 return true; 2318 } 2319 2320 @Override detach()2321 public void detach() { 2322 mTimeBase.remove(this); 2323 } 2324 } 2325 2326 @VisibleForTesting 2327 public static class LongSamplingCounter extends LongCounter implements TimeBaseObs { 2328 final TimeBase mTimeBase; 2329 private long mCount; 2330 LongSamplingCounter(TimeBase timeBase, Parcel in)2331 public LongSamplingCounter(TimeBase timeBase, Parcel in) { 2332 mTimeBase = timeBase; 2333 mCount = in.readLong(); 2334 timeBase.add(this); 2335 } 2336 LongSamplingCounter(TimeBase timeBase)2337 public LongSamplingCounter(TimeBase timeBase) { 2338 mTimeBase = timeBase; 2339 timeBase.add(this); 2340 } 2341 writeToParcel(Parcel out)2342 public void writeToParcel(Parcel out) { 2343 out.writeLong(mCount); 2344 } 2345 2346 @Override onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)2347 public void onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { 2348 } 2349 2350 @Override onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)2351 public void onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { 2352 } 2353 getCountLocked(int which)2354 public long getCountLocked(int which) { 2355 return mCount; 2356 } 2357 2358 @Override getCountForProcessState(int procState)2359 public long getCountForProcessState(int procState) { 2360 if (procState == BatteryConsumer.PROCESS_STATE_ANY) { 2361 return getCountLocked(STATS_SINCE_CHARGED); 2362 } 2363 return 0; 2364 } 2365 2366 @Override logState(Printer pw, String prefix)2367 public void logState(Printer pw, String prefix) { 2368 pw.println(prefix + "mCount=" + mCount); 2369 } 2370 addCountLocked(long count)2371 public void addCountLocked(long count) { 2372 addCountLocked(count, mTimeBase.isRunning()); 2373 } 2374 addCountLocked(long count, boolean isRunning)2375 public void addCountLocked(long count, boolean isRunning) { 2376 if (isRunning) { 2377 mCount += count; 2378 } 2379 } 2380 2381 /** 2382 * Clear state of this counter. 2383 */ 2384 @Override reset(boolean detachIfReset, long elapsedRealtimeUs )2385 public boolean reset(boolean detachIfReset, long elapsedRealtimeUs /* unused */) { 2386 mCount = 0; 2387 if (detachIfReset) { 2388 detach(); 2389 } 2390 return true; 2391 } 2392 2393 @Override detach()2394 public void detach() { 2395 mTimeBase.remove(this); 2396 } 2397 writeSummaryFromParcelLocked(Parcel out)2398 public void writeSummaryFromParcelLocked(Parcel out) { 2399 out.writeLong(mCount); 2400 } 2401 readSummaryFromParcelLocked(Parcel in)2402 public void readSummaryFromParcelLocked(Parcel in) { 2403 mCount = in.readLong(); 2404 } 2405 } 2406 2407 /** 2408 * State for keeping track of timing information. 2409 */ 2410 public static abstract class Timer extends BatteryStats.Timer implements TimeBaseObs { 2411 protected final Clock mClock; 2412 protected final int mType; 2413 protected final TimeBase mTimeBase; 2414 2415 protected int mCount; 2416 2417 // Times are in microseconds for better accuracy when dividing by the 2418 // lock count, and are in "battery realtime" units. 2419 2420 /** 2421 * The total time we have accumulated since the start of the original 2422 * boot, to the last time something interesting happened in the 2423 * current run. 2424 */ 2425 protected long mTotalTimeUs; 2426 2427 /** 2428 * The total time this timer has been running until the latest mark has been set. 2429 * Subtract this from mTotalTimeUs to get the time spent running since the mark was set. 2430 */ 2431 protected long mTimeBeforeMarkUs; 2432 2433 /** 2434 * Constructs from a parcel. 2435 * @param type 2436 * @param timeBase 2437 * @param in 2438 */ Timer(Clock clock, int type, TimeBase timeBase, Parcel in)2439 public Timer(Clock clock, int type, TimeBase timeBase, Parcel in) { 2440 mClock = clock; 2441 mType = type; 2442 mTimeBase = timeBase; 2443 2444 mCount = in.readInt(); 2445 mTotalTimeUs = in.readLong(); 2446 mTimeBeforeMarkUs = in.readLong(); 2447 timeBase.add(this); 2448 if (DEBUG) Log.i(TAG, "**** READ TIMER #" + mType + ": mTotalTime=" + mTotalTimeUs); 2449 } 2450 Timer(Clock clock, int type, TimeBase timeBase)2451 public Timer(Clock clock, int type, TimeBase timeBase) { 2452 mClock = clock; 2453 mType = type; 2454 mTimeBase = timeBase; 2455 timeBase.add(this); 2456 } 2457 writeToParcel(Parcel out, long elapsedRealtimeUs)2458 public void writeToParcel(Parcel out, long elapsedRealtimeUs) { 2459 if (DEBUG) { 2460 Log.i(TAG, "**** WRITING TIMER #" + mType + ": mTotalTime=" 2461 + computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs), 2462 elapsedRealtimeUs)); 2463 } 2464 out.writeInt(computeCurrentCountLocked()); 2465 out.writeLong(computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs), 2466 elapsedRealtimeUs)); 2467 out.writeLong(mTimeBeforeMarkUs); 2468 } 2469 computeRunTimeLocked(long curBatteryRealtime, long elapsedRealtimeUs)2470 protected abstract long computeRunTimeLocked(long curBatteryRealtime, 2471 long elapsedRealtimeUs); 2472 computeCurrentCountLocked()2473 protected abstract int computeCurrentCountLocked(); 2474 2475 /** 2476 * Clear state of this timer. Returns true if the timer is inactive 2477 * so can be completely dropped. 2478 */ 2479 @Override reset(boolean detachIfReset)2480 public boolean reset(boolean detachIfReset) { 2481 return reset(detachIfReset, mClock.elapsedRealtime() * 1000); 2482 } 2483 2484 @Override reset(boolean detachIfReset, long elapsedRealtimeUs )2485 public boolean reset(boolean detachIfReset, long elapsedRealtimeUs /* unused */) { 2486 mTotalTimeUs = mTimeBeforeMarkUs = 0; 2487 mCount = 0; 2488 if (detachIfReset) { 2489 detach(); 2490 } 2491 return true; 2492 } 2493 2494 @Override detach()2495 public void detach() { 2496 mTimeBase.remove(this); 2497 } 2498 2499 @Override onTimeStarted(long elapsedRealtimeUs, long timeBaseUptimeUs, long baseRealtimeUs)2500 public void onTimeStarted(long elapsedRealtimeUs, long timeBaseUptimeUs, 2501 long baseRealtimeUs) { 2502 } 2503 2504 @Override onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)2505 public void onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { 2506 if (DEBUG && mType < 0) { 2507 Log.v(TAG, "plug #" + mType + ": realtime=" + baseRealtimeUs 2508 + " old mTotalTime=" + mTotalTimeUs); 2509 } 2510 mTotalTimeUs = computeRunTimeLocked(baseRealtimeUs, elapsedRealtimeUs); 2511 mCount = computeCurrentCountLocked(); 2512 if (DEBUG && mType < 0) { 2513 Log.v(TAG, "plug #" + mType + ": new mTotalTime=" + mTotalTimeUs); 2514 } 2515 } 2516 2517 /** 2518 * Writes a possibly null Timer to a Parcel. 2519 * 2520 * @param out the Parcel to be written to. 2521 * @param timer a Timer, or null. 2522 */ 2523 @UnsupportedAppUsage writeTimerToParcel(Parcel out, Timer timer, long elapsedRealtimeUs)2524 public static void writeTimerToParcel(Parcel out, Timer timer, long elapsedRealtimeUs) { 2525 if (timer == null) { 2526 out.writeInt(0); // indicates null 2527 return; 2528 } 2529 out.writeInt(1); // indicates non-null 2530 timer.writeToParcel(out, elapsedRealtimeUs); 2531 } 2532 2533 @Override 2534 @UnsupportedAppUsage getTotalTimeLocked(long elapsedRealtimeUs, int which)2535 public long getTotalTimeLocked(long elapsedRealtimeUs, int which) { 2536 return computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs), 2537 elapsedRealtimeUs); 2538 } 2539 2540 @Override 2541 @UnsupportedAppUsage getCountLocked(int which)2542 public int getCountLocked(int which) { 2543 return computeCurrentCountLocked(); 2544 } 2545 2546 @Override getTimeSinceMarkLocked(long elapsedRealtimeUs)2547 public long getTimeSinceMarkLocked(long elapsedRealtimeUs) { 2548 long val = computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs), 2549 elapsedRealtimeUs); 2550 return val - mTimeBeforeMarkUs; 2551 } 2552 2553 @Override logState(Printer pw, String prefix)2554 public void logState(Printer pw, String prefix) { 2555 pw.println(prefix + "mCount=" + mCount); 2556 pw.println(prefix + "mTotalTime=" + mTotalTimeUs); 2557 } 2558 2559 writeSummaryFromParcelLocked(Parcel out, long elapsedRealtimeUs)2560 public void writeSummaryFromParcelLocked(Parcel out, long elapsedRealtimeUs) { 2561 long runTimeUs = computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs), 2562 elapsedRealtimeUs); 2563 out.writeLong(runTimeUs); 2564 out.writeInt(computeCurrentCountLocked()); 2565 } 2566 readSummaryFromParcelLocked(Parcel in)2567 public void readSummaryFromParcelLocked(Parcel in) { 2568 // Multiply by 1000 for backwards compatibility 2569 mTotalTimeUs = in.readLong(); 2570 mCount = in.readInt(); 2571 // When reading the summary, we set the mark to be the latest information. 2572 mTimeBeforeMarkUs = mTotalTimeUs; 2573 } 2574 } 2575 2576 /** 2577 * A counter meant to accept monotonically increasing values to its {@link #update(long, int)} 2578 * method. The state of the timer according to its {@link TimeBase} will determine how much 2579 * of the value is recorded. 2580 * 2581 * If the value being recorded resets, {@link #endSample()} can be called in order to 2582 * account for the change. If the value passed in to {@link #update(long, int)} decreased 2583 * between calls, the {@link #endSample()} is automatically called and the new value is 2584 * expected to increase monotonically from that point on. 2585 */ 2586 public static class SamplingTimer extends Timer { 2587 2588 /** 2589 * The most recent reported count from /proc/wakelocks. 2590 */ 2591 int mCurrentReportedCount; 2592 2593 /** 2594 * The reported count from /proc/wakelocks when unplug() was last 2595 * called. 2596 */ 2597 int mUnpluggedReportedCount; 2598 2599 /** 2600 * The most recent reported total_time from /proc/wakelocks. 2601 */ 2602 long mCurrentReportedTotalTimeUs; 2603 2604 2605 /** 2606 * The reported total_time from /proc/wakelocks when unplug() was last 2607 * called. 2608 */ 2609 long mUnpluggedReportedTotalTimeUs; 2610 2611 /** 2612 * Whether we are currently in a discharge cycle. 2613 */ 2614 boolean mTimeBaseRunning; 2615 2616 /** 2617 * Whether we are currently recording reported values. 2618 */ 2619 boolean mTrackingReportedValues; 2620 2621 /* 2622 * A sequence counter, incremented once for each update of the stats. 2623 */ 2624 int mUpdateVersion; 2625 2626 @VisibleForTesting SamplingTimer(Clock clock, TimeBase timeBase, Parcel in)2627 public SamplingTimer(Clock clock, TimeBase timeBase, Parcel in) { 2628 super(clock, 0, timeBase, in); 2629 mCurrentReportedCount = in.readInt(); 2630 mUnpluggedReportedCount = in.readInt(); 2631 mCurrentReportedTotalTimeUs = in.readLong(); 2632 mUnpluggedReportedTotalTimeUs = in.readLong(); 2633 mTrackingReportedValues = in.readInt() == 1; 2634 mTimeBaseRunning = timeBase.isRunning(); 2635 } 2636 2637 @VisibleForTesting SamplingTimer(Clock clock, TimeBase timeBase)2638 public SamplingTimer(Clock clock, TimeBase timeBase) { 2639 super(clock, 0, timeBase); 2640 mTrackingReportedValues = false; 2641 mTimeBaseRunning = timeBase.isRunning(); 2642 } 2643 2644 /** 2645 * Ends the current sample, allowing subsequent values to {@link #update(long, int)} to 2646 * be less than the values used for a previous invocation. 2647 */ endSample()2648 public void endSample() { 2649 endSample(mClock.elapsedRealtime() * 1000); 2650 } 2651 2652 /** 2653 * @see #endSample() 2654 */ endSample(long elapsedRealtimeUs)2655 public void endSample(long elapsedRealtimeUs) { 2656 mTotalTimeUs = computeRunTimeLocked(0 /* unused by us */, elapsedRealtimeUs); 2657 mCount = computeCurrentCountLocked(); 2658 mUnpluggedReportedTotalTimeUs = mCurrentReportedTotalTimeUs = 0; 2659 mUnpluggedReportedCount = mCurrentReportedCount = 0; 2660 mTrackingReportedValues = false; 2661 } 2662 setUpdateVersion(int version)2663 public void setUpdateVersion(int version) { 2664 mUpdateVersion = version; 2665 } 2666 getUpdateVersion()2667 public int getUpdateVersion() { 2668 return mUpdateVersion; 2669 } 2670 2671 /** 2672 * Updates the current recorded values. These are meant to be monotonically increasing 2673 * and cumulative. If you are dealing with deltas, use {@link #add(long, int)}. 2674 * 2675 * If the values being recorded have been reset, the monotonically increasing requirement 2676 * will be broken. In this case, {@link #endSample()} is automatically called and 2677 * the total value of totalTimeUs and count are recorded, starting a new monotonically 2678 * increasing sample. 2679 * 2680 * @param totalTimeUs total time of sample in microseconds. 2681 * @param count total number of times the event being sampled occurred. 2682 */ updated(long totalTimeUs, int count)2683 public void updated(long totalTimeUs, int count) { 2684 update(totalTimeUs, count, mClock.elapsedRealtime() * 1000); 2685 } 2686 2687 /** 2688 * @see #update(long, int) 2689 */ update(long totalTimeUs, int count, long elapsedRealtimeUs)2690 public void update(long totalTimeUs, int count, long elapsedRealtimeUs) { 2691 if (mTimeBaseRunning && !mTrackingReportedValues) { 2692 // Updating the reported value for the first time. 2693 mUnpluggedReportedTotalTimeUs = totalTimeUs; 2694 mUnpluggedReportedCount = count; 2695 } 2696 2697 mTrackingReportedValues = true; 2698 2699 if (totalTimeUs < mCurrentReportedTotalTimeUs || count < mCurrentReportedCount) { 2700 endSample(elapsedRealtimeUs); 2701 } 2702 2703 mCurrentReportedTotalTimeUs = totalTimeUs; 2704 mCurrentReportedCount = count; 2705 } 2706 2707 /** 2708 * Adds deltaTime and deltaCount to the current sample. 2709 * 2710 * @param deltaTime additional time recorded since the last sampled event, in microseconds. 2711 * @param deltaCount additional number of times the event being sampled occurred. 2712 */ add(long deltaTimeUs, int deltaCount)2713 public void add(long deltaTimeUs, int deltaCount) { 2714 add(deltaTimeUs, deltaCount, mClock.elapsedRealtime() * 1000); 2715 } 2716 2717 /** 2718 * @see #add(long, int) 2719 */ add(long deltaTimeUs, int deltaCount, long elapsedRealtimeUs)2720 public void add(long deltaTimeUs, int deltaCount, long elapsedRealtimeUs) { 2721 update(mCurrentReportedTotalTimeUs + deltaTimeUs, mCurrentReportedCount + deltaCount, 2722 elapsedRealtimeUs); 2723 } 2724 2725 @Override onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)2726 public void onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { 2727 super.onTimeStarted(elapsedRealtimeUs, baseUptimeUs, baseRealtimeUs); 2728 if (mTrackingReportedValues) { 2729 mUnpluggedReportedTotalTimeUs = mCurrentReportedTotalTimeUs; 2730 mUnpluggedReportedCount = mCurrentReportedCount; 2731 } 2732 mTimeBaseRunning = true; 2733 } 2734 2735 @Override onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)2736 public void onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { 2737 super.onTimeStopped(elapsedRealtimeUs, baseUptimeUs, baseRealtimeUs); 2738 mTimeBaseRunning = false; 2739 } 2740 2741 @Override logState(Printer pw, String prefix)2742 public void logState(Printer pw, String prefix) { 2743 super.logState(pw, prefix); 2744 pw.println(prefix + "mCurrentReportedCount=" + mCurrentReportedCount 2745 + " mUnpluggedReportedCount=" + mUnpluggedReportedCount 2746 + " mCurrentReportedTotalTime=" + mCurrentReportedTotalTimeUs 2747 + " mUnpluggedReportedTotalTime=" + mUnpluggedReportedTotalTimeUs); 2748 } 2749 2750 @Override computeRunTimeLocked(long curBatteryRealtime, long elapsedRealtimeUs)2751 protected long computeRunTimeLocked(long curBatteryRealtime, long elapsedRealtimeUs) { 2752 return mTotalTimeUs + (mTimeBaseRunning && mTrackingReportedValues 2753 ? mCurrentReportedTotalTimeUs - mUnpluggedReportedTotalTimeUs : 0); 2754 } 2755 2756 @Override computeCurrentCountLocked()2757 protected int computeCurrentCountLocked() { 2758 return mCount + (mTimeBaseRunning && mTrackingReportedValues 2759 ? mCurrentReportedCount - mUnpluggedReportedCount : 0); 2760 } 2761 2762 @Override writeToParcel(Parcel out, long elapsedRealtimeUs)2763 public void writeToParcel(Parcel out, long elapsedRealtimeUs) { 2764 super.writeToParcel(out, elapsedRealtimeUs); 2765 out.writeInt(mCurrentReportedCount); 2766 out.writeInt(mUnpluggedReportedCount); 2767 out.writeLong(mCurrentReportedTotalTimeUs); 2768 out.writeLong(mUnpluggedReportedTotalTimeUs); 2769 out.writeInt(mTrackingReportedValues ? 1 : 0); 2770 } 2771 2772 @Override reset(boolean detachIfReset, long elapsedRealtimeUs)2773 public boolean reset(boolean detachIfReset, long elapsedRealtimeUs) { 2774 super.reset(detachIfReset, elapsedRealtimeUs); 2775 mTrackingReportedValues = false; 2776 mUnpluggedReportedTotalTimeUs = 0; 2777 mUnpluggedReportedCount = 0; 2778 return true; 2779 } 2780 } 2781 2782 /** 2783 * A timer that increments in batches. It does not run for durations, but just jumps 2784 * for a pre-determined amount. 2785 */ 2786 public static class BatchTimer extends Timer { 2787 final Uid mUid; 2788 2789 /** 2790 * The last time at which we updated the timer. This is in elapsed realtime microseconds. 2791 */ 2792 long mLastAddedTimeUs; 2793 2794 /** 2795 * The last duration that we added to the timer. This is in microseconds. 2796 */ 2797 long mLastAddedDurationUs; 2798 2799 /** 2800 * Whether we are currently in a discharge cycle. 2801 */ 2802 boolean mInDischarge; 2803 BatchTimer(Clock clock, Uid uid, int type, TimeBase timeBase, Parcel in)2804 BatchTimer(Clock clock, Uid uid, int type, TimeBase timeBase, Parcel in) { 2805 super(clock, type, timeBase, in); 2806 mUid = uid; 2807 mLastAddedTimeUs = in.readLong(); 2808 mLastAddedDurationUs = in.readLong(); 2809 mInDischarge = timeBase.isRunning(); 2810 } 2811 BatchTimer(Clock clock, Uid uid, int type, TimeBase timeBase)2812 BatchTimer(Clock clock, Uid uid, int type, TimeBase timeBase) { 2813 super(clock, type, timeBase); 2814 mUid = uid; 2815 mInDischarge = timeBase.isRunning(); 2816 } 2817 2818 @Override writeToParcel(Parcel out, long elapsedRealtimeUs)2819 public void writeToParcel(Parcel out, long elapsedRealtimeUs) { 2820 super.writeToParcel(out, elapsedRealtimeUs); 2821 out.writeLong(mLastAddedTimeUs); 2822 out.writeLong(mLastAddedDurationUs); 2823 } 2824 2825 @Override onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)2826 public void onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { 2827 recomputeLastDuration(elapsedRealtimeUs, false); 2828 mInDischarge = false; 2829 super.onTimeStopped(elapsedRealtimeUs, baseUptimeUs, baseRealtimeUs); 2830 } 2831 2832 @Override onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)2833 public void onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { 2834 recomputeLastDuration(elapsedRealtimeUs, false); 2835 mInDischarge = true; 2836 // If we are still within the last added duration, then re-added whatever remains. 2837 if (mLastAddedTimeUs == elapsedRealtimeUs) { 2838 mTotalTimeUs += mLastAddedDurationUs; 2839 } 2840 super.onTimeStarted(elapsedRealtimeUs, baseUptimeUs, baseRealtimeUs); 2841 } 2842 2843 @Override logState(Printer pw, String prefix)2844 public void logState(Printer pw, String prefix) { 2845 super.logState(pw, prefix); 2846 pw.println(prefix + "mLastAddedTime=" + mLastAddedTimeUs 2847 + " mLastAddedDuration=" + mLastAddedDurationUs); 2848 } 2849 computeOverage(long curTimeUs)2850 private long computeOverage(long curTimeUs) { 2851 if (mLastAddedTimeUs > 0) { 2852 return mLastAddedDurationUs - curTimeUs; 2853 } 2854 return 0; 2855 } 2856 recomputeLastDuration(long curTimeUs, boolean abort)2857 private void recomputeLastDuration(long curTimeUs, boolean abort) { 2858 final long overage = computeOverage(curTimeUs); 2859 if (overage > 0) { 2860 // Aborting before the duration ran out -- roll back the remaining 2861 // duration. Only do this if currently discharging; otherwise we didn't 2862 // actually add the time. 2863 if (mInDischarge) { 2864 mTotalTimeUs -= overage; 2865 } 2866 if (abort) { 2867 mLastAddedTimeUs = 0; 2868 } else { 2869 mLastAddedTimeUs = curTimeUs; 2870 mLastAddedDurationUs -= overage; 2871 } 2872 } 2873 } 2874 addDuration(BatteryStatsImpl stats, long durationMs)2875 public void addDuration(BatteryStatsImpl stats, long durationMs) { 2876 addDuration(stats, durationMs, mClock.elapsedRealtime()); 2877 } 2878 addDuration(BatteryStatsImpl stats, long durationMs, long elapsedRealtimeMs)2879 public void addDuration(BatteryStatsImpl stats, long durationMs, long elapsedRealtimeMs) { 2880 final long nowUs = elapsedRealtimeMs * 1000; 2881 recomputeLastDuration(nowUs, true); 2882 mLastAddedTimeUs = nowUs; 2883 mLastAddedDurationUs = durationMs * 1000; 2884 if (mInDischarge) { 2885 mTotalTimeUs += mLastAddedDurationUs; 2886 mCount++; 2887 } 2888 } 2889 abortLastDuration(BatteryStatsImpl stats)2890 public void abortLastDuration(BatteryStatsImpl stats) { 2891 abortLastDuration(stats, mClock.elapsedRealtime()); 2892 } 2893 abortLastDuration(BatteryStatsImpl stats, long elapsedRealtimeMs)2894 public void abortLastDuration(BatteryStatsImpl stats, long elapsedRealtimeMs) { 2895 final long nowUs = elapsedRealtimeMs * 1000; 2896 recomputeLastDuration(nowUs, true); 2897 } 2898 2899 @Override computeCurrentCountLocked()2900 protected int computeCurrentCountLocked() { 2901 return mCount; 2902 } 2903 2904 @Override computeRunTimeLocked(long curBatteryRealtimeUs, long elapsedRealtimeUs)2905 protected long computeRunTimeLocked(long curBatteryRealtimeUs, long elapsedRealtimeUs) { 2906 final long overage = computeOverage(elapsedRealtimeUs); 2907 if (overage > 0) { 2908 return mTotalTimeUs = overage; 2909 } 2910 return mTotalTimeUs; 2911 } 2912 2913 @Override reset(boolean detachIfReset, long elapsedRealtimeUs)2914 public boolean reset(boolean detachIfReset, long elapsedRealtimeUs) { 2915 recomputeLastDuration(elapsedRealtimeUs, true); 2916 boolean stillActive = mLastAddedTimeUs == elapsedRealtimeUs; 2917 super.reset(!stillActive && detachIfReset, elapsedRealtimeUs); 2918 return !stillActive; 2919 } 2920 } 2921 2922 2923 /** 2924 * A StopwatchTimer that also tracks the total and max individual 2925 * time spent active according to the given timebase. Whereas 2926 * StopwatchTimer apportions the time amongst all in the pool, 2927 * the total and max durations are not apportioned. 2928 */ 2929 public static class DurationTimer extends StopwatchTimer { 2930 /** 2931 * The time (in ms) that the timer was last acquired or the time base 2932 * last (re-)started. Increasing the nesting depth does not reset this time. 2933 * 2934 * -1 if the timer is currently not running or the time base is not running. 2935 * 2936 * If written to a parcel, the start time is reset, as is mNesting in the base class 2937 * StopwatchTimer. 2938 */ 2939 long mStartTimeMs = -1; 2940 2941 /** 2942 * The longest time period (in ms) that the timer has been active. Not pooled. 2943 */ 2944 long mMaxDurationMs; 2945 2946 /** 2947 * The time (in ms) that that the timer has been active since most recent 2948 * stopRunningLocked() or reset(). Not pooled. 2949 */ 2950 long mCurrentDurationMs; 2951 2952 /** 2953 * The total time (in ms) that that the timer has been active since most recent reset() 2954 * prior to the current startRunningLocked. This is the sum of all past currentDurations 2955 * (but not including the present currentDuration) since reset. Not pooled. 2956 */ 2957 long mTotalDurationMs; 2958 DurationTimer(Clock clock, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, TimeBase timeBase, Parcel in)2959 public DurationTimer(Clock clock, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, 2960 TimeBase timeBase, Parcel in) { 2961 super(clock, uid, type, timerPool, timeBase, in); 2962 mMaxDurationMs = in.readLong(); 2963 mTotalDurationMs = in.readLong(); 2964 mCurrentDurationMs = in.readLong(); 2965 } 2966 DurationTimer(Clock clock, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, TimeBase timeBase)2967 public DurationTimer(Clock clock, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, 2968 TimeBase timeBase) { 2969 super(clock, uid, type, timerPool, timeBase); 2970 } 2971 2972 @Override writeToParcel(Parcel out, long elapsedRealtimeUs)2973 public void writeToParcel(Parcel out, long elapsedRealtimeUs) { 2974 super.writeToParcel(out, elapsedRealtimeUs); 2975 out.writeLong(getMaxDurationMsLocked(elapsedRealtimeUs / 1000)); 2976 out.writeLong(mTotalDurationMs); 2977 out.writeLong(getCurrentDurationMsLocked(elapsedRealtimeUs / 1000)); 2978 } 2979 2980 /** 2981 * Write the summary to the parcel. 2982 * 2983 * Since the time base is probably meaningless after we come back, reading 2984 * from this will have the effect of stopping the timer. So here all we write 2985 * is the max and total durations. 2986 */ 2987 @Override writeSummaryFromParcelLocked(Parcel out, long elapsedRealtimeUs)2988 public void writeSummaryFromParcelLocked(Parcel out, long elapsedRealtimeUs) { 2989 super.writeSummaryFromParcelLocked(out, elapsedRealtimeUs); 2990 out.writeLong(getMaxDurationMsLocked(elapsedRealtimeUs / 1000)); 2991 out.writeLong(getTotalDurationMsLocked(elapsedRealtimeUs / 1000)); 2992 } 2993 2994 /** 2995 * Read the summary parcel. 2996 * 2997 * Has the side effect of stopping the timer. 2998 */ 2999 @Override readSummaryFromParcelLocked(Parcel in)3000 public void readSummaryFromParcelLocked(Parcel in) { 3001 super.readSummaryFromParcelLocked(in); 3002 mMaxDurationMs = in.readLong(); 3003 mTotalDurationMs = in.readLong(); 3004 mStartTimeMs = -1; 3005 mCurrentDurationMs = 0; 3006 } 3007 3008 /** 3009 * The TimeBase time started (again). 3010 * 3011 * If the timer is also running, store the start time. 3012 */ onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)3013 public void onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { 3014 super.onTimeStarted(elapsedRealtimeUs, baseUptimeUs, baseRealtimeUs); 3015 if (mNesting > 0) { 3016 mStartTimeMs = baseRealtimeUs / 1000; 3017 } 3018 } 3019 3020 /** 3021 * The TimeBase stopped running. 3022 * 3023 * If the timer is running, add the duration into mCurrentDurationMs. 3024 */ 3025 @Override onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)3026 public void onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { 3027 super.onTimeStopped(elapsedRealtimeUs, baseUptimeUs, baseRealtimeUs); 3028 if (mNesting > 0) { 3029 // baseRealtimeUs has already been converted to the timebase's realtime. 3030 mCurrentDurationMs += (baseRealtimeUs / 1000) - mStartTimeMs; 3031 } 3032 mStartTimeMs = -1; 3033 } 3034 3035 @Override logState(Printer pw, String prefix)3036 public void logState(Printer pw, String prefix) { 3037 super.logState(pw, prefix); 3038 } 3039 3040 @Override startRunningLocked(long elapsedRealtimeMs)3041 public void startRunningLocked(long elapsedRealtimeMs) { 3042 super.startRunningLocked(elapsedRealtimeMs); 3043 if (mNesting == 1 && mTimeBase.isRunning()) { 3044 // Just started 3045 mStartTimeMs = mTimeBase.getRealtime(elapsedRealtimeMs * 1000) / 1000; 3046 } 3047 } 3048 3049 /** 3050 * Decrements the mNesting ref-count on this timer. 3051 * 3052 * If it actually stopped (mNesting went to 0), then possibly update 3053 * mMaxDuration if the current duration was the longest ever. 3054 */ 3055 @Override stopRunningLocked(long elapsedRealtimeMs)3056 public void stopRunningLocked(long elapsedRealtimeMs) { 3057 if (mNesting == 1) { 3058 final long durationMs = getCurrentDurationMsLocked(elapsedRealtimeMs); 3059 mTotalDurationMs += durationMs; 3060 if (durationMs > mMaxDurationMs) { 3061 mMaxDurationMs = durationMs; 3062 } 3063 mStartTimeMs = -1; 3064 mCurrentDurationMs = 0; 3065 } 3066 // super method decrements mNesting, which getCurrentDurationMsLocked relies on, 3067 // so call super.stopRunningLocked after calling getCurrentDurationMsLocked. 3068 super.stopRunningLocked(elapsedRealtimeMs); 3069 } 3070 3071 @Override reset(boolean detachIfReset, long elapsedRealtimeUs)3072 public boolean reset(boolean detachIfReset, long elapsedRealtimeUs) { 3073 boolean result = super.reset(detachIfReset, elapsedRealtimeUs); 3074 mMaxDurationMs = 0; 3075 mTotalDurationMs = 0; 3076 mCurrentDurationMs = 0; 3077 if (mNesting > 0) { 3078 mStartTimeMs = mTimeBase.getRealtime(elapsedRealtimeUs) / 1000; 3079 } else { 3080 mStartTimeMs = -1; 3081 } 3082 return result; 3083 } 3084 3085 /** 3086 * Returns the max duration that this timer has ever seen. 3087 * 3088 * Note that this time is NOT split between the timers in the timer group that 3089 * this timer is attached to. It is the TOTAL time. 3090 */ 3091 @Override getMaxDurationMsLocked(long elapsedRealtimeMs)3092 public long getMaxDurationMsLocked(long elapsedRealtimeMs) { 3093 if (mNesting > 0) { 3094 final long durationMs = getCurrentDurationMsLocked(elapsedRealtimeMs); 3095 if (durationMs > mMaxDurationMs) { 3096 return durationMs; 3097 } 3098 } 3099 return mMaxDurationMs; 3100 } 3101 3102 /** 3103 * Returns the time since the timer was started. 3104 * Returns 0 if the timer is not currently running. 3105 * 3106 * Note that this time is NOT split between the timers in the timer group that 3107 * this timer is attached to. It is the TOTAL time. 3108 * 3109 * Note that if running timer is parceled and unparceled, this method will return 3110 * current duration value at the time of parceling even though timer may not be 3111 * currently running. 3112 */ 3113 @Override getCurrentDurationMsLocked(long elapsedRealtimeMs)3114 public long getCurrentDurationMsLocked(long elapsedRealtimeMs) { 3115 long durationMs = mCurrentDurationMs; 3116 if (mNesting > 0 && mTimeBase.isRunning()) { 3117 durationMs += (mTimeBase.getRealtime(elapsedRealtimeMs * 1000) / 1000) 3118 - mStartTimeMs; 3119 } 3120 return durationMs; 3121 } 3122 3123 /** 3124 * Returns the total cumulative duration that this timer has been on since reset(). 3125 * If mTimerPool == null, this should be the same 3126 * as getTotalTimeLocked(elapsedRealtimeMs*1000, STATS_SINCE_CHARGED)/1000. 3127 * 3128 * Note that this time is NOT split between the timers in the timer group that 3129 * this timer is attached to. It is the TOTAL time. For this reason, if mTimerPool != null, 3130 * the result will not be equivalent to getTotalTimeLocked. 3131 */ 3132 @Override getTotalDurationMsLocked(long elapsedRealtimeMs)3133 public long getTotalDurationMsLocked(long elapsedRealtimeMs) { 3134 return mTotalDurationMs + getCurrentDurationMsLocked(elapsedRealtimeMs); 3135 } 3136 } 3137 3138 /** 3139 * State for keeping track of timing information. 3140 */ 3141 public static class StopwatchTimer extends Timer { 3142 final Uid mUid; 3143 final ArrayList<StopwatchTimer> mTimerPool; 3144 3145 int mNesting; 3146 3147 /** 3148 * The last time at which we updated the timer. If mNesting is > 0, 3149 * subtract this from the current battery time to find the amount of 3150 * time we have been running since we last computed an update. 3151 */ 3152 long mUpdateTimeUs; 3153 3154 /** 3155 * The total time at which the timer was acquired, to determine if it 3156 * was actually held for an interesting duration. If time base was not running when timer 3157 * was acquired, will be -1. 3158 */ 3159 long mAcquireTimeUs = -1; 3160 3161 long mTimeoutUs; 3162 3163 /** 3164 * For partial wake locks, keep track of whether we are in the list 3165 * to consume CPU cycles. 3166 */ 3167 @VisibleForTesting 3168 public boolean mInList; 3169 StopwatchTimer(Clock clock, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, TimeBase timeBase, Parcel in)3170 public StopwatchTimer(Clock clock, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, 3171 TimeBase timeBase, Parcel in) { 3172 super(clock, type, timeBase, in); 3173 mUid = uid; 3174 mTimerPool = timerPool; 3175 mUpdateTimeUs = in.readLong(); 3176 } 3177 StopwatchTimer(Clock clock, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, TimeBase timeBase)3178 public StopwatchTimer(Clock clock, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, 3179 TimeBase timeBase) { 3180 super(clock, type, timeBase); 3181 mUid = uid; 3182 mTimerPool = timerPool; 3183 } 3184 setTimeout(long timeoutUs)3185 public void setTimeout(long timeoutUs) { 3186 mTimeoutUs = timeoutUs; 3187 } 3188 writeToParcel(Parcel out, long elapsedRealtimeUs)3189 public void writeToParcel(Parcel out, long elapsedRealtimeUs) { 3190 super.writeToParcel(out, elapsedRealtimeUs); 3191 out.writeLong(mUpdateTimeUs); 3192 } 3193 onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)3194 public void onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { 3195 if (mNesting > 0) { 3196 if (DEBUG && mType < 0) { 3197 Log.v(TAG, "old mUpdateTime=" + mUpdateTimeUs); 3198 } 3199 super.onTimeStopped(elapsedRealtimeUs, baseUptimeUs, baseRealtimeUs); 3200 mUpdateTimeUs = baseRealtimeUs; 3201 if (DEBUG && mType < 0) { 3202 Log.v(TAG, "new mUpdateTime=" + mUpdateTimeUs); 3203 } 3204 } 3205 } 3206 logState(Printer pw, String prefix)3207 public void logState(Printer pw, String prefix) { 3208 super.logState(pw, prefix); 3209 pw.println(prefix + "mNesting=" + mNesting + " mUpdateTime=" + mUpdateTimeUs 3210 + " mAcquireTime=" + mAcquireTimeUs); 3211 } 3212 startRunningLocked(long elapsedRealtimeMs)3213 public void startRunningLocked(long elapsedRealtimeMs) { 3214 if (mNesting++ == 0) { 3215 final long batteryRealtimeUs = mTimeBase.getRealtime(elapsedRealtimeMs * 1000); 3216 mUpdateTimeUs = batteryRealtimeUs; 3217 if (mTimerPool != null) { 3218 // Accumulate time to all currently active timers before adding 3219 // this new one to the pool. 3220 refreshTimersLocked(batteryRealtimeUs, mTimerPool, null); 3221 // Add this timer to the active pool 3222 mTimerPool.add(this); 3223 } 3224 if (mTimeBase.isRunning()) { 3225 // Increment the count 3226 mCount++; 3227 mAcquireTimeUs = mTotalTimeUs; 3228 } else { 3229 mAcquireTimeUs = -1; 3230 } 3231 if (DEBUG && mType < 0) { 3232 Log.v(TAG, "start #" + mType + ": mUpdateTime=" + mUpdateTimeUs 3233 + " mTotalTime=" + mTotalTimeUs + " mCount=" + mCount 3234 + " mAcquireTime=" + mAcquireTimeUs); 3235 } 3236 } 3237 } 3238 isRunningLocked()3239 public boolean isRunningLocked() { 3240 return mNesting > 0; 3241 } 3242 stopRunningLocked(long elapsedRealtimeMs)3243 public void stopRunningLocked(long elapsedRealtimeMs) { 3244 // Ignore attempt to stop a timer that isn't running 3245 if (mNesting == 0) { 3246 return; 3247 } 3248 if (--mNesting == 0) { 3249 final long batteryRealtimeUs = mTimeBase.getRealtime(elapsedRealtimeMs * 1000); 3250 if (mTimerPool != null) { 3251 // Accumulate time to all active counters, scaled by the total 3252 // active in the pool, before taking this one out of the pool. 3253 refreshTimersLocked(batteryRealtimeUs, mTimerPool, null); 3254 // Remove this timer from the active pool 3255 mTimerPool.remove(this); 3256 } else { 3257 mNesting = 1; 3258 mTotalTimeUs = computeRunTimeLocked(batteryRealtimeUs, 3259 elapsedRealtimeMs * 1000); 3260 mNesting = 0; 3261 } 3262 3263 if (DEBUG && mType < 0) { 3264 Log.v(TAG, "stop #" + mType + ": mUpdateTime=" + mUpdateTimeUs 3265 + " mTotalTime=" + mTotalTimeUs + " mCount=" + mCount 3266 + " mAcquireTime=" + mAcquireTimeUs); 3267 } 3268 3269 if (mAcquireTimeUs >= 0 && mTotalTimeUs == mAcquireTimeUs) { 3270 // If there was no change in the time, then discard this 3271 // count. A somewhat cheezy strategy, but hey. 3272 mCount--; 3273 } 3274 } 3275 } 3276 stopAllRunningLocked(long elapsedRealtimeMs)3277 public void stopAllRunningLocked(long elapsedRealtimeMs) { 3278 if (mNesting > 0) { 3279 mNesting = 1; 3280 stopRunningLocked(elapsedRealtimeMs); 3281 } 3282 } 3283 3284 // Update the total time for all other running Timers with the same type as this Timer 3285 // due to a change in timer count refreshTimersLocked(long batteryRealtimeUs, final ArrayList<StopwatchTimer> pool, StopwatchTimer self)3286 private static long refreshTimersLocked(long batteryRealtimeUs, 3287 final ArrayList<StopwatchTimer> pool, StopwatchTimer self) { 3288 long selfTimeUs = 0; 3289 final int N = pool.size(); 3290 for (int i=N-1; i>= 0; i--) { 3291 final StopwatchTimer t = pool.get(i); 3292 long heldTimeUs = batteryRealtimeUs - t.mUpdateTimeUs; 3293 if (heldTimeUs > 0) { 3294 final long myTimeUs = heldTimeUs / N; 3295 if (t == self) { 3296 selfTimeUs = myTimeUs; 3297 } 3298 t.mTotalTimeUs += myTimeUs; 3299 } 3300 t.mUpdateTimeUs = batteryRealtimeUs; 3301 } 3302 return selfTimeUs; 3303 } 3304 3305 @Override computeRunTimeLocked(long curBatteryRealtimeUs, long elapsedRealtimeUs)3306 protected long computeRunTimeLocked(long curBatteryRealtimeUs, long elapsedRealtimeUs) { 3307 if (mTimeoutUs > 0 && curBatteryRealtimeUs > mUpdateTimeUs + mTimeoutUs) { 3308 curBatteryRealtimeUs = mUpdateTimeUs + mTimeoutUs; 3309 } 3310 return mTotalTimeUs + (mNesting > 0 3311 ? (curBatteryRealtimeUs - mUpdateTimeUs) 3312 / (mTimerPool != null ? mTimerPool.size() : 1) 3313 : 0); 3314 } 3315 3316 @Override computeCurrentCountLocked()3317 protected int computeCurrentCountLocked() { 3318 return mCount; 3319 } 3320 3321 @Override reset(boolean detachIfReset, long elapsedRealtimeUs)3322 public boolean reset(boolean detachIfReset, long elapsedRealtimeUs) { 3323 boolean canDetach = mNesting <= 0; 3324 super.reset(canDetach && detachIfReset, elapsedRealtimeUs); 3325 if (mNesting > 0) { 3326 mUpdateTimeUs = mTimeBase.getRealtime(elapsedRealtimeUs); 3327 } 3328 // To ensure mCount isn't decreased to -1 if timer is stopped later. 3329 mAcquireTimeUs = -1; 3330 return canDetach; 3331 } 3332 3333 @Override 3334 @UnsupportedAppUsage detach()3335 public void detach() { 3336 super.detach(); 3337 if (mTimerPool != null) { 3338 mTimerPool.remove(this); 3339 } 3340 } 3341 3342 @Override readSummaryFromParcelLocked(Parcel in)3343 public void readSummaryFromParcelLocked(Parcel in) { 3344 super.readSummaryFromParcelLocked(in); 3345 mNesting = 0; 3346 } 3347 3348 /** 3349 * Set the mark so that we can query later for the total time the timer has 3350 * accumulated since this point. The timer can be running or not. 3351 * 3352 * @param elapsedRealtimeMs the current elapsed realtime in milliseconds. 3353 */ setMark(long elapsedRealtimeMs)3354 public void setMark(long elapsedRealtimeMs) { 3355 final long batteryRealtimeUs = mTimeBase.getRealtime(elapsedRealtimeMs * 1000); 3356 if (mNesting > 0) { 3357 // We are running. 3358 if (mTimerPool != null) { 3359 refreshTimersLocked(batteryRealtimeUs, mTimerPool, this); 3360 } else { 3361 mTotalTimeUs += batteryRealtimeUs - mUpdateTimeUs; 3362 mUpdateTimeUs = batteryRealtimeUs; 3363 } 3364 } 3365 mTimeBeforeMarkUs = mTotalTimeUs; 3366 } 3367 } 3368 3369 /** 3370 * State for keeping track of two DurationTimers with different TimeBases, presumably where one 3371 * TimeBase is effectively a subset of the other. 3372 */ 3373 public static class DualTimer extends DurationTimer { 3374 // This class both is a DurationTimer and also holds a second DurationTimer. 3375 // The main timer (this) typically tracks the total time. It may be pooled (but since it's a 3376 // durationTimer, it also has the unpooled getTotalDurationMsLocked() for 3377 // STATS_SINCE_CHARGED). 3378 // mSubTimer typically tracks only part of the total time, such as background time, as 3379 // determined by a subTimeBase. It is NOT pooled. 3380 private final DurationTimer mSubTimer; 3381 3382 /** 3383 * Creates a DualTimer to hold a main timer (this) and a mSubTimer. 3384 * The main timer (this) is based on the given timeBase and timerPool. 3385 * The mSubTimer is based on the given subTimeBase. The mSubTimer is not pooled, even if 3386 * the main timer is. 3387 */ DualTimer(Clock clock, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, TimeBase timeBase, TimeBase subTimeBase, Parcel in)3388 public DualTimer(Clock clock, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, 3389 TimeBase timeBase, TimeBase subTimeBase, Parcel in) { 3390 super(clock, uid, type, timerPool, timeBase, in); 3391 mSubTimer = new DurationTimer(clock, uid, type, null, subTimeBase, in); 3392 } 3393 3394 /** 3395 * Creates a DualTimer to hold a main timer (this) and a mSubTimer. 3396 * The main timer (this) is based on the given timeBase and timerPool. 3397 * The mSubTimer is based on the given subTimeBase. The mSubTimer is not pooled, even if 3398 * the main timer is. 3399 */ DualTimer(Clock clock, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, TimeBase timeBase, TimeBase subTimeBase)3400 public DualTimer(Clock clock, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, 3401 TimeBase timeBase, TimeBase subTimeBase) { 3402 super(clock, uid, type, timerPool, timeBase); 3403 mSubTimer = new DurationTimer(clock, uid, type, null, subTimeBase); 3404 } 3405 3406 /** Get the secondary timer. */ 3407 @Override getSubTimer()3408 public DurationTimer getSubTimer() { 3409 return mSubTimer; 3410 } 3411 3412 @Override startRunningLocked(long elapsedRealtimeMs)3413 public void startRunningLocked(long elapsedRealtimeMs) { 3414 super.startRunningLocked(elapsedRealtimeMs); 3415 mSubTimer.startRunningLocked(elapsedRealtimeMs); 3416 } 3417 3418 @Override stopRunningLocked(long elapsedRealtimeMs)3419 public void stopRunningLocked(long elapsedRealtimeMs) { 3420 super.stopRunningLocked(elapsedRealtimeMs); 3421 mSubTimer.stopRunningLocked(elapsedRealtimeMs); 3422 } 3423 3424 @Override stopAllRunningLocked(long elapsedRealtimeMs)3425 public void stopAllRunningLocked(long elapsedRealtimeMs) { 3426 super.stopAllRunningLocked(elapsedRealtimeMs); 3427 mSubTimer.stopAllRunningLocked(elapsedRealtimeMs); 3428 } 3429 3430 @Override reset(boolean detachIfReset, long elapsedRealtimeUs)3431 public boolean reset(boolean detachIfReset, long elapsedRealtimeUs) { 3432 boolean active = false; 3433 // Do not detach the subTimer explicitly since that'll be done by DualTimer.detach(). 3434 active |= !mSubTimer.reset(false, elapsedRealtimeUs); 3435 active |= !super.reset(detachIfReset, elapsedRealtimeUs); 3436 return !active; 3437 } 3438 3439 @Override detach()3440 public void detach() { 3441 mSubTimer.detach(); 3442 super.detach(); 3443 } 3444 3445 @Override writeToParcel(Parcel out, long elapsedRealtimeUs)3446 public void writeToParcel(Parcel out, long elapsedRealtimeUs) { 3447 super.writeToParcel(out, elapsedRealtimeUs); 3448 mSubTimer.writeToParcel(out, elapsedRealtimeUs); 3449 } 3450 3451 @Override writeSummaryFromParcelLocked(Parcel out, long elapsedRealtimeUs)3452 public void writeSummaryFromParcelLocked(Parcel out, long elapsedRealtimeUs) { 3453 super.writeSummaryFromParcelLocked(out, elapsedRealtimeUs); 3454 mSubTimer.writeSummaryFromParcelLocked(out, elapsedRealtimeUs); 3455 } 3456 3457 @Override readSummaryFromParcelLocked(Parcel in)3458 public void readSummaryFromParcelLocked(Parcel in) { 3459 super.readSummaryFromParcelLocked(in); 3460 mSubTimer.readSummaryFromParcelLocked(in); 3461 } 3462 } 3463 3464 3465 public abstract class OverflowArrayMap<T> { 3466 private static final String OVERFLOW_NAME = "*overflow*"; 3467 3468 final int mUid; 3469 final ArrayMap<String, T> mMap = new ArrayMap<>(); 3470 T mCurOverflow; 3471 ArrayMap<String, MutableInt> mActiveOverflow; 3472 long mLastOverflowTimeMs; 3473 long mLastOverflowFinishTimeMs; 3474 long mLastClearTimeMs; 3475 long mLastCleanupTimeMs; 3476 OverflowArrayMap(int uid)3477 public OverflowArrayMap(int uid) { 3478 mUid = uid; 3479 } 3480 getMap()3481 public ArrayMap<String, T> getMap() { 3482 return mMap; 3483 } 3484 clear()3485 public void clear() { 3486 mLastClearTimeMs = SystemClock.elapsedRealtime(); 3487 mMap.clear(); 3488 mCurOverflow = null; 3489 mActiveOverflow = null; 3490 } 3491 add(String name, T obj)3492 public void add(String name, T obj) { 3493 if (name == null) { 3494 name = ""; 3495 } 3496 mMap.put(name, obj); 3497 if (OVERFLOW_NAME.equals(name)) { 3498 mCurOverflow = obj; 3499 } 3500 } 3501 cleanup(long elapsedRealtimeMs)3502 public void cleanup(long elapsedRealtimeMs) { 3503 mLastCleanupTimeMs = elapsedRealtimeMs; 3504 if (mActiveOverflow != null) { 3505 if (mActiveOverflow.size() == 0) { 3506 mActiveOverflow = null; 3507 } 3508 } 3509 if (mActiveOverflow == null) { 3510 // There is no currently active overflow, so we should no longer have 3511 // an overflow entry. 3512 if (mMap.containsKey(OVERFLOW_NAME)) { 3513 Slog.wtf(TAG, "Cleaning up with no active overflow, but have overflow entry " 3514 + mMap.get(OVERFLOW_NAME)); 3515 mMap.remove(OVERFLOW_NAME); 3516 } 3517 mCurOverflow = null; 3518 } else { 3519 // There is currently active overflow, so we should still have an overflow entry. 3520 if (mCurOverflow == null || !mMap.containsKey(OVERFLOW_NAME)) { 3521 Slog.wtf(TAG, "Cleaning up with active overflow, but no overflow entry: cur=" 3522 + mCurOverflow + " map=" + mMap.get(OVERFLOW_NAME)); 3523 } 3524 } 3525 } 3526 startObject(String name, long elapsedRealtimeMs)3527 public T startObject(String name, long elapsedRealtimeMs) { 3528 if (name == null) { 3529 name = ""; 3530 } 3531 T obj = mMap.get(name); 3532 if (obj != null) { 3533 return obj; 3534 } 3535 3536 // No object exists for the given name, but do we currently have it 3537 // running as part of the overflow? 3538 if (mActiveOverflow != null) { 3539 MutableInt over = mActiveOverflow.get(name); 3540 if (over != null) { 3541 // We are already actively counting this name in the overflow object. 3542 obj = mCurOverflow; 3543 if (obj == null) { 3544 // Shouldn't be here, but we'll try to recover. 3545 Slog.wtf(TAG, "Have active overflow " + name + " but null overflow"); 3546 obj = mCurOverflow = instantiateObject(); 3547 mMap.put(OVERFLOW_NAME, obj); 3548 } 3549 over.value++; 3550 return obj; 3551 } 3552 } 3553 3554 // No object exists for given name nor in the overflow; we need to make 3555 // a new one. 3556 final int N = mMap.size(); 3557 if (N >= MAX_WAKELOCKS_PER_UID) { 3558 // Went over the limit on number of objects to track; this one goes 3559 // in to the overflow. 3560 obj = mCurOverflow; 3561 if (obj == null) { 3562 // Need to start overflow now... 3563 obj = mCurOverflow = instantiateObject(); 3564 mMap.put(OVERFLOW_NAME, obj); 3565 } 3566 if (mActiveOverflow == null) { 3567 mActiveOverflow = new ArrayMap<>(); 3568 } 3569 mActiveOverflow.put(name, new MutableInt(1)); 3570 mLastOverflowTimeMs = elapsedRealtimeMs; 3571 return obj; 3572 } 3573 3574 // Normal case where we just need to make a new object. 3575 obj = instantiateObject(); 3576 mMap.put(name, obj); 3577 return obj; 3578 } 3579 stopObject(String name, long elapsedRealtimeMs)3580 public T stopObject(String name, long elapsedRealtimeMs) { 3581 if (name == null) { 3582 name = ""; 3583 } 3584 T obj = mMap.get(name); 3585 if (obj != null) { 3586 return obj; 3587 } 3588 3589 // No object exists for the given name, but do we currently have it 3590 // running as part of the overflow? 3591 if (mActiveOverflow != null) { 3592 MutableInt over = mActiveOverflow.get(name); 3593 if (over != null) { 3594 // We are already actively counting this name in the overflow object. 3595 obj = mCurOverflow; 3596 if (obj != null) { 3597 over.value--; 3598 if (over.value <= 0) { 3599 mActiveOverflow.remove(name); 3600 mLastOverflowFinishTimeMs = elapsedRealtimeMs; 3601 } 3602 return obj; 3603 } 3604 } 3605 } 3606 3607 // Huh, they are stopping an active operation but we can't find one! 3608 // That's not good. 3609 StringBuilder sb = new StringBuilder(); 3610 sb.append("Unable to find object for "); 3611 sb.append(name); 3612 sb.append(" in uid "); 3613 sb.append(mUid); 3614 sb.append(" mapsize="); 3615 sb.append(mMap.size()); 3616 sb.append(" activeoverflow="); 3617 sb.append(mActiveOverflow); 3618 sb.append(" curoverflow="); 3619 sb.append(mCurOverflow); 3620 long now = elapsedRealtimeMs; 3621 if (mLastOverflowTimeMs != 0) { 3622 sb.append(" lastOverflowTime="); 3623 TimeUtils.formatDuration(mLastOverflowTimeMs - now, sb); 3624 } 3625 if (mLastOverflowFinishTimeMs != 0) { 3626 sb.append(" lastOverflowFinishTime="); 3627 TimeUtils.formatDuration(mLastOverflowFinishTimeMs - now, sb); 3628 } 3629 if (mLastClearTimeMs != 0) { 3630 sb.append(" lastClearTime="); 3631 TimeUtils.formatDuration(mLastClearTimeMs - now, sb); 3632 } 3633 if (mLastCleanupTimeMs != 0) { 3634 sb.append(" lastCleanupTime="); 3635 TimeUtils.formatDuration(mLastCleanupTimeMs - now, sb); 3636 } 3637 Slog.wtf(TAG, sb.toString()); 3638 return null; 3639 } 3640 instantiateObject()3641 public abstract T instantiateObject(); 3642 } 3643 3644 public static class ControllerActivityCounterImpl extends ControllerActivityCounter 3645 implements Parcelable { 3646 private final Clock mClock; 3647 private final TimeBase mTimeBase; 3648 private int mNumTxStates; 3649 private int mProcessState; 3650 private TimeMultiStateCounter mIdleTimeMillis; 3651 private final LongSamplingCounter mScanTimeMillis; 3652 private final LongSamplingCounter mSleepTimeMillis; 3653 private TimeMultiStateCounter mRxTimeMillis; 3654 private TimeMultiStateCounter[] mTxTimeMillis; 3655 private final LongSamplingCounter mPowerDrainMaMs; 3656 private final LongSamplingCounter mMonitoredRailChargeConsumedMaMs; 3657 ControllerActivityCounterImpl(Clock clock, TimeBase timeBase, int numTxStates)3658 public ControllerActivityCounterImpl(Clock clock, TimeBase timeBase, int numTxStates) { 3659 mClock = clock; 3660 mTimeBase = timeBase; 3661 mNumTxStates = numTxStates; 3662 mScanTimeMillis = new LongSamplingCounter(timeBase); 3663 mSleepTimeMillis = new LongSamplingCounter(timeBase); 3664 mPowerDrainMaMs = new LongSamplingCounter(timeBase); 3665 mMonitoredRailChargeConsumedMaMs = new LongSamplingCounter(timeBase); 3666 } 3667 ControllerActivityCounterImpl(Clock clock, TimeBase timeBase, int numTxStates, Parcel in)3668 public ControllerActivityCounterImpl(Clock clock, TimeBase timeBase, int numTxStates, 3669 Parcel in) { 3670 mClock = clock; 3671 mTimeBase = timeBase; 3672 mNumTxStates = numTxStates; 3673 mIdleTimeMillis = readTimeMultiStateCounter(in, timeBase); 3674 mScanTimeMillis = new LongSamplingCounter(timeBase, in); 3675 mSleepTimeMillis = new LongSamplingCounter(timeBase, in); 3676 mRxTimeMillis = readTimeMultiStateCounter(in, timeBase); 3677 mTxTimeMillis = readTimeMultiStateCounters(in, timeBase, numTxStates); 3678 3679 mPowerDrainMaMs = new LongSamplingCounter(timeBase, in); 3680 mMonitoredRailChargeConsumedMaMs = new LongSamplingCounter(timeBase, in); 3681 } 3682 readSummaryFromParcel(Parcel in)3683 public void readSummaryFromParcel(Parcel in) { 3684 mIdleTimeMillis = readTimeMultiStateCounter(in, mTimeBase); 3685 mScanTimeMillis.readSummaryFromParcelLocked(in); 3686 mSleepTimeMillis.readSummaryFromParcelLocked(in); 3687 mRxTimeMillis = readTimeMultiStateCounter(in, mTimeBase); 3688 mTxTimeMillis = readTimeMultiStateCounters(in, mTimeBase, mNumTxStates); 3689 3690 mPowerDrainMaMs.readSummaryFromParcelLocked(in); 3691 mMonitoredRailChargeConsumedMaMs.readSummaryFromParcelLocked(in); 3692 } 3693 3694 @Override describeContents()3695 public int describeContents() { 3696 return 0; 3697 } 3698 writeSummaryToParcel(Parcel dest)3699 public void writeSummaryToParcel(Parcel dest) { 3700 writeTimeMultiStateCounter(dest, mIdleTimeMillis); 3701 mScanTimeMillis.writeSummaryFromParcelLocked(dest); 3702 mSleepTimeMillis.writeSummaryFromParcelLocked(dest); 3703 writeTimeMultiStateCounter(dest, mRxTimeMillis); 3704 writeTimeMultiStateCounters(dest, mTxTimeMillis); 3705 mPowerDrainMaMs.writeSummaryFromParcelLocked(dest); 3706 mMonitoredRailChargeConsumedMaMs.writeSummaryFromParcelLocked(dest); 3707 } 3708 3709 @Override writeToParcel(Parcel dest, int flags)3710 public void writeToParcel(Parcel dest, int flags) { 3711 writeTimeMultiStateCounter(dest, mIdleTimeMillis); 3712 mScanTimeMillis.writeToParcel(dest); 3713 mSleepTimeMillis.writeToParcel(dest); 3714 writeTimeMultiStateCounter(dest, mRxTimeMillis); 3715 writeTimeMultiStateCounters(dest, mTxTimeMillis); 3716 mPowerDrainMaMs.writeToParcel(dest); 3717 mMonitoredRailChargeConsumedMaMs.writeToParcel(dest); 3718 } 3719 readTimeMultiStateCounter(Parcel in, TimeBase timeBase)3720 private TimeMultiStateCounter readTimeMultiStateCounter(Parcel in, TimeBase timeBase) { 3721 if (in.readBoolean()) { 3722 return TimeMultiStateCounter.readFromParcel(in, timeBase, 3723 BatteryConsumer.PROCESS_STATE_COUNT, mClock.elapsedRealtime()); 3724 } 3725 return null; 3726 } 3727 writeTimeMultiStateCounter(Parcel dest, TimeMultiStateCounter counter)3728 private void writeTimeMultiStateCounter(Parcel dest, TimeMultiStateCounter counter) { 3729 if (counter != null) { 3730 dest.writeBoolean(true); 3731 counter.writeToParcel(dest); 3732 } else { 3733 dest.writeBoolean(false); 3734 } 3735 } 3736 readTimeMultiStateCounters(Parcel in, TimeBase timeBase, int expectedNumCounters)3737 private TimeMultiStateCounter[] readTimeMultiStateCounters(Parcel in, TimeBase timeBase, 3738 int expectedNumCounters) { 3739 if (in.readBoolean()) { 3740 final int numCounters = in.readInt(); 3741 boolean valid = (numCounters == expectedNumCounters); 3742 // Need to read counters out of the Parcel, even if all or some of them are 3743 // invalid. 3744 TimeMultiStateCounter[] counters = new TimeMultiStateCounter[numCounters]; 3745 for (int i = 0; i < numCounters; i++) { 3746 final TimeMultiStateCounter counter = TimeMultiStateCounter.readFromParcel(in, 3747 timeBase, BatteryConsumer.PROCESS_STATE_COUNT, 3748 mClock.elapsedRealtime()); 3749 if (counter != null) { 3750 counters[i] = counter; 3751 } else { 3752 valid = false; 3753 } 3754 } 3755 if (valid) { 3756 return counters; 3757 } 3758 } 3759 return null; 3760 } 3761 writeTimeMultiStateCounters(Parcel dest, TimeMultiStateCounter[] counters)3762 private void writeTimeMultiStateCounters(Parcel dest, TimeMultiStateCounter[] counters) { 3763 if (counters != null) { 3764 dest.writeBoolean(true); 3765 dest.writeInt(counters.length); 3766 for (TimeMultiStateCounter counter : counters) { 3767 counter.writeToParcel(dest); 3768 } 3769 } else { 3770 dest.writeBoolean(false); 3771 } 3772 } 3773 reset(boolean detachIfReset, long elapsedRealtimeUs)3774 public void reset(boolean detachIfReset, long elapsedRealtimeUs) { 3775 resetIfNotNull(mIdleTimeMillis, detachIfReset, elapsedRealtimeUs); 3776 mScanTimeMillis.reset(detachIfReset, elapsedRealtimeUs); 3777 mSleepTimeMillis.reset(detachIfReset, elapsedRealtimeUs); 3778 resetIfNotNull(mRxTimeMillis, detachIfReset, elapsedRealtimeUs); 3779 resetIfNotNull(mTxTimeMillis, detachIfReset, elapsedRealtimeUs); 3780 mPowerDrainMaMs.reset(detachIfReset, elapsedRealtimeUs); 3781 mMonitoredRailChargeConsumedMaMs.reset(detachIfReset, elapsedRealtimeUs); 3782 } 3783 detach()3784 public void detach() { 3785 detachIfNotNull(mIdleTimeMillis); 3786 mScanTimeMillis.detach(); 3787 mSleepTimeMillis.detach(); 3788 detachIfNotNull(mRxTimeMillis); 3789 detachIfNotNull(mTxTimeMillis); 3790 mPowerDrainMaMs.detach(); 3791 mMonitoredRailChargeConsumedMaMs.detach(); 3792 } 3793 3794 /** 3795 * @return a LongSamplingCounter, measuring time spent in the idle state in 3796 * milliseconds. 3797 */ 3798 @Override getIdleTimeCounter()3799 public LongCounter getIdleTimeCounter() { 3800 if (mIdleTimeMillis == null) { 3801 return ZERO_LONG_COUNTER; 3802 } 3803 return mIdleTimeMillis; 3804 } 3805 getOrCreateIdleTimeCounter()3806 private TimeMultiStateCounter getOrCreateIdleTimeCounter() { 3807 if (mIdleTimeMillis == null) { 3808 mIdleTimeMillis = createTimeMultiStateCounter(); 3809 } 3810 return mIdleTimeMillis; 3811 } 3812 3813 /** 3814 * @return a LongSamplingCounter, measuring time spent in the scan state in 3815 * milliseconds. 3816 */ 3817 @Override getScanTimeCounter()3818 public LongSamplingCounter getScanTimeCounter() { 3819 return mScanTimeMillis; 3820 } 3821 3822 /** 3823 * @return a LongSamplingCounter, measuring time spent in the sleep state in 3824 * milliseconds. 3825 */ 3826 @Override getSleepTimeCounter()3827 public LongSamplingCounter getSleepTimeCounter() { 3828 return mSleepTimeMillis; 3829 } 3830 3831 /** 3832 * @return a LongSamplingCounter, measuring time spent in the receive state in 3833 * milliseconds. 3834 */ 3835 @Override getRxTimeCounter()3836 public LongCounter getRxTimeCounter() { 3837 if (mRxTimeMillis == null) { 3838 return ZERO_LONG_COUNTER; 3839 } 3840 return mRxTimeMillis; 3841 } 3842 getOrCreateRxTimeCounter()3843 private TimeMultiStateCounter getOrCreateRxTimeCounter() { 3844 if (mRxTimeMillis == null) { 3845 mRxTimeMillis = createTimeMultiStateCounter(); 3846 } 3847 return mRxTimeMillis; 3848 } 3849 3850 /** 3851 * @return a LongSamplingCounter[], measuring time spent in various transmit states in 3852 * milliseconds. 3853 */ 3854 @Override getTxTimeCounters()3855 public LongCounter[] getTxTimeCounters() { 3856 if (mTxTimeMillis == null) { 3857 return ZERO_LONG_COUNTER_ARRAY; 3858 } 3859 return mTxTimeMillis; 3860 } 3861 getOrCreateTxTimeCounters()3862 private TimeMultiStateCounter[] getOrCreateTxTimeCounters() { 3863 if (mTxTimeMillis == null) { 3864 mTxTimeMillis = new TimeMultiStateCounter[mNumTxStates]; 3865 for (int i = 0; i < mNumTxStates; i++) { 3866 mTxTimeMillis[i] = createTimeMultiStateCounter(); 3867 } 3868 } 3869 return mTxTimeMillis; 3870 } 3871 createTimeMultiStateCounter()3872 private TimeMultiStateCounter createTimeMultiStateCounter() { 3873 final long timestampMs = mClock.elapsedRealtime(); 3874 TimeMultiStateCounter counter = new TimeMultiStateCounter(mTimeBase, 3875 BatteryConsumer.PROCESS_STATE_COUNT, timestampMs); 3876 counter.setState(mapUidProcessStateToBatteryConsumerProcessState(mProcessState), 3877 timestampMs); 3878 counter.update(0, timestampMs); 3879 return counter; 3880 } 3881 3882 /** 3883 * @return a LongSamplingCounter, measuring power use in milli-ampere milliseconds (mAmS). 3884 */ 3885 @Override getPowerCounter()3886 public LongSamplingCounter getPowerCounter() { 3887 return mPowerDrainMaMs; 3888 } 3889 3890 /** 3891 * @return a LongSamplingCounter, measuring actual monitored rail energy consumed 3892 * milli-ampere milli-seconds (mAmS). 3893 */ 3894 @Override getMonitoredRailChargeConsumedMaMs()3895 public LongSamplingCounter getMonitoredRailChargeConsumedMaMs() { 3896 return mMonitoredRailChargeConsumedMaMs; 3897 } 3898 setState(int processState, long elapsedTimeMs)3899 private void setState(int processState, long elapsedTimeMs) { 3900 mProcessState = processState; 3901 if (mIdleTimeMillis != null) { 3902 mIdleTimeMillis.setState(processState, elapsedTimeMs); 3903 } 3904 if (mRxTimeMillis != null) { 3905 mRxTimeMillis.setState(processState, elapsedTimeMs); 3906 } 3907 if (mTxTimeMillis != null) { 3908 for (int i = 0; i < mTxTimeMillis.length; i++) { 3909 mTxTimeMillis[i].setState(processState, elapsedTimeMs); 3910 } 3911 } 3912 } 3913 } 3914 3915 /** Get Resource Power Manager stats. Create a new one if it doesn't already exist. */ getRpmTimerLocked(String name)3916 public SamplingTimer getRpmTimerLocked(String name) { 3917 SamplingTimer rpmt = mRpmStats.get(name); 3918 if (rpmt == null) { 3919 rpmt = new SamplingTimer(mClock, mOnBatteryTimeBase); 3920 mRpmStats.put(name, rpmt); 3921 } 3922 return rpmt; 3923 } 3924 3925 /** Get Screen-off Resource Power Manager stats. Create new one if it doesn't already exist. */ getScreenOffRpmTimerLocked(String name)3926 public SamplingTimer getScreenOffRpmTimerLocked(String name) { 3927 SamplingTimer rpmt = mScreenOffRpmStats.get(name); 3928 if (rpmt == null) { 3929 rpmt = new SamplingTimer(mClock, mOnBatteryScreenOffTimeBase); 3930 mScreenOffRpmStats.put(name, rpmt); 3931 } 3932 return rpmt; 3933 } 3934 3935 /* 3936 * Get the wakeup reason counter, and create a new one if one 3937 * doesn't already exist. 3938 */ getWakeupReasonTimerLocked(String name)3939 public SamplingTimer getWakeupReasonTimerLocked(String name) { 3940 SamplingTimer timer = mWakeupReasonStats.get(name); 3941 if (timer == null) { 3942 timer = new SamplingTimer(mClock, mOnBatteryTimeBase); 3943 mWakeupReasonStats.put(name, timer); 3944 } 3945 return timer; 3946 } 3947 3948 /* 3949 * Get the KernelWakelockTimer associated with name, and create a new one if one 3950 * doesn't already exist. 3951 */ getKernelWakelockTimerLocked(String name)3952 public SamplingTimer getKernelWakelockTimerLocked(String name) { 3953 SamplingTimer kwlt = mKernelWakelockStats.get(name); 3954 if (kwlt == null) { 3955 kwlt = new SamplingTimer(mClock, mOnBatteryScreenOffTimeBase); 3956 mKernelWakelockStats.put(name, kwlt); 3957 } 3958 return kwlt; 3959 } 3960 getKernelMemoryTimerLocked(long bucket)3961 public SamplingTimer getKernelMemoryTimerLocked(long bucket) { 3962 SamplingTimer kmt = mKernelMemoryStats.get(bucket); 3963 if (kmt == null) { 3964 kmt = new SamplingTimer(mClock, mOnBatteryTimeBase); 3965 mKernelMemoryStats.put(bucket, kmt); 3966 } 3967 return kmt; 3968 } 3969 3970 /** 3971 * Returns the index for the specified tag. If this is the first time the tag is encountered 3972 * while writing the current history buffer, the method returns 3973 * <code>(index | TAG_FIRST_OCCURRENCE_FLAG)</code> 3974 */ writeHistoryTag(HistoryTag tag)3975 private int writeHistoryTag(HistoryTag tag) { 3976 if (tag.string == null) { 3977 Slog.wtfStack(TAG, "writeHistoryTag called with null name"); 3978 } 3979 3980 final int stringLength = tag.string.length(); 3981 if (stringLength > MAX_HISTORY_TAG_STRING_LENGTH) { 3982 Slog.e(TAG, "Long battery history tag: " + tag.string); 3983 tag.string = tag.string.substring(0, MAX_HISTORY_TAG_STRING_LENGTH); 3984 } 3985 3986 Integer idxObj = mHistoryTagPool.get(tag); 3987 int idx; 3988 if (idxObj != null) { 3989 idx = idxObj; 3990 if ((idx & TAG_FIRST_OCCURRENCE_FLAG) != 0) { 3991 mHistoryTagPool.put(tag, idx & ~TAG_FIRST_OCCURRENCE_FLAG); 3992 } 3993 return idx; 3994 } else if (mNextHistoryTagIdx < HISTORY_TAG_INDEX_LIMIT) { 3995 idx = mNextHistoryTagIdx; 3996 HistoryTag key = new HistoryTag(); 3997 key.setTo(tag); 3998 tag.poolIdx = idx; 3999 mHistoryTagPool.put(key, idx); 4000 mNextHistoryTagIdx++; 4001 4002 mNumHistoryTagChars += stringLength + 1; 4003 if (mHistoryTags != null) { 4004 mHistoryTags.put(idx, key); 4005 } 4006 return idx | TAG_FIRST_OCCURRENCE_FLAG; 4007 } else { 4008 // Tag pool overflow: include the tag itself in the parcel 4009 return HISTORY_TAG_INDEX_LIMIT | TAG_FIRST_OCCURRENCE_FLAG; 4010 } 4011 } 4012 4013 /* 4014 The history delta format uses flags to denote further data in subsequent ints in the parcel. 4015 4016 There is always the first token, which may contain the delta time, or an indicator of 4017 the length of the time (int or long) following this token. 4018 4019 First token: always present, 4020 31 23 15 7 0 4021 █M|L|K|J|I|H|G|F█E|D|C|B|A|T|T|T█T|T|T|T|T|T|T|T█T|T|T|T|T|T|T|T█ 4022 4023 T: the delta time if it is <= 0x7fffd. Otherwise 0x7fffe indicates an int immediately 4024 follows containing the time, and 0x7ffff indicates a long immediately follows with the 4025 delta time. 4026 A: battery level changed and an int follows with battery data. 4027 B: state changed and an int follows with state change data. 4028 C: state2 has changed and an int follows with state2 change data. 4029 D: wakelock/wakereason has changed and an wakelock/wakereason struct follows. 4030 E: event data has changed and an event struct follows. 4031 F: battery charge in coulombs has changed and an int with the charge follows. 4032 G: state flag denoting that the mobile radio was active. 4033 H: state flag denoting that the wifi radio was active. 4034 I: state flag denoting that a wifi scan occurred. 4035 J: state flag denoting that a wifi full lock was held. 4036 K: state flag denoting that the gps was on. 4037 L: state flag denoting that a wakelock was held. 4038 M: state flag denoting that the cpu was running. 4039 4040 Time int/long: if T in the first token is 0x7ffff or 0x7fffe, then an int or long follows 4041 with the time delta. 4042 4043 Battery level int: if A in the first token is set, 4044 31 23 15 7 0 4045 █L|L|L|L|L|L|L|T█T|T|T|T|T|T|T|T█T|V|V|V|V|V|V|V█V|V|V|V|V|V|V|D█ 4046 4047 D: indicates that extra history details follow. 4048 V: the battery voltage. 4049 T: the battery temperature. 4050 L: the battery level (out of 100). 4051 4052 State change int: if B in the first token is set, 4053 31 23 15 7 0 4054 █S|S|S|H|H|H|P|P█F|E|D|C|B| | |A█ | | | | | | | █ | | | | | | | █ 4055 4056 A: wifi multicast was on. 4057 B: battery was plugged in. 4058 C: screen was on. 4059 D: phone was scanning for signal. 4060 E: audio was on. 4061 F: a sensor was active. 4062 4063 State2 change int: if C in the first token is set, 4064 31 23 15 7 0 4065 █M|L|K|J|I|H|H|G█F|E|D|C| | | | █ | | | | | | | █ |B|B|B|A|A|A|A█ 4066 4067 A: 4 bits indicating the wifi supplicant state: {@link BatteryStats#WIFI_SUPPL_STATE_NAMES}. 4068 B: 3 bits indicating the wifi signal strength: 0, 1, 2, 3, 4. 4069 C: a bluetooth scan was active. 4070 D: the camera was active. 4071 E: bluetooth was on. 4072 F: a phone call was active. 4073 G: the device was charging. 4074 H: 2 bits indicating the device-idle (doze) state: off, light, full 4075 I: the flashlight was on. 4076 J: wifi was on. 4077 K: wifi was running. 4078 L: video was playing. 4079 M: power save mode was on. 4080 4081 Wakelock/wakereason struct: if D in the first token is set, 4082 TODO(adamlesinski): describe wakelock/wakereason struct. 4083 4084 Event struct: if E in the first token is set, 4085 TODO(adamlesinski): describe the event struct. 4086 4087 History step details struct: if D in the battery level int is set, 4088 TODO(adamlesinski): describe the history step details struct. 4089 4090 Battery charge int: if F in the first token is set, an int representing the battery charge 4091 in coulombs follows. 4092 */ 4093 4094 // Part of initial delta int that specifies the time delta. 4095 static final int DELTA_TIME_MASK = 0x7ffff; 4096 static final int DELTA_TIME_LONG = 0x7ffff; // The delta is a following long 4097 static final int DELTA_TIME_INT = 0x7fffe; // The delta is a following int 4098 static final int DELTA_TIME_ABS = 0x7fffd; // Following is an entire abs update. 4099 // Flag in delta int: a new battery level int follows. 4100 static final int DELTA_BATTERY_LEVEL_FLAG = 0x00080000; 4101 // Flag in delta int: a new full state and battery status int follows. 4102 static final int DELTA_STATE_FLAG = 0x00100000; 4103 // Flag in delta int: a new full state2 int follows. 4104 static final int DELTA_STATE2_FLAG = 0x00200000; 4105 // Flag in delta int: contains a wakelock or wakeReason tag. 4106 static final int DELTA_WAKELOCK_FLAG = 0x00400000; 4107 // Flag in delta int: contains an event description. 4108 static final int DELTA_EVENT_FLAG = 0x00800000; 4109 // Flag in delta int: contains the battery charge count in uAh. 4110 static final int DELTA_BATTERY_CHARGE_FLAG = 0x01000000; 4111 // These upper bits are the frequently changing state bits. 4112 static final int DELTA_STATE_MASK = 0xfe000000; 4113 4114 // Flag in history tag index: indicates that this is the first occurrence of this tag, 4115 // therefore the tag value is written in the parcel 4116 static final int TAG_FIRST_OCCURRENCE_FLAG = 0x8000; 4117 4118 // These are the pieces of battery state that are packed in to the upper bits of 4119 // the state int that have been packed in to the first delta int. They must fit 4120 // in STATE_BATTERY_MASK. 4121 static final int STATE_BATTERY_MASK = 0xff000000; 4122 static final int STATE_BATTERY_STATUS_MASK = 0x00000007; 4123 static final int STATE_BATTERY_STATUS_SHIFT = 29; 4124 static final int STATE_BATTERY_HEALTH_MASK = 0x00000007; 4125 static final int STATE_BATTERY_HEALTH_SHIFT = 26; 4126 static final int STATE_BATTERY_PLUG_MASK = 0x00000003; 4127 static final int STATE_BATTERY_PLUG_SHIFT = 24; 4128 4129 // We use the low bit of the battery state int to indicate that we have full details 4130 // from a battery level change. 4131 static final int BATTERY_DELTA_LEVEL_FLAG = 0x00000001; 4132 4133 @GuardedBy("this") writeHistoryDelta(Parcel dest, HistoryItem cur, HistoryItem last)4134 public void writeHistoryDelta(Parcel dest, HistoryItem cur, HistoryItem last) { 4135 if (last == null || cur.cmd != HistoryItem.CMD_UPDATE) { 4136 dest.writeInt(DELTA_TIME_ABS); 4137 cur.writeToParcel(dest, 0); 4138 return; 4139 } 4140 4141 final long deltaTime = cur.time - last.time; 4142 final int lastBatteryLevelInt = buildBatteryLevelInt(last); 4143 final int lastStateInt = buildStateInt(last); 4144 4145 int deltaTimeToken; 4146 if (deltaTime < 0 || deltaTime > Integer.MAX_VALUE) { 4147 deltaTimeToken = DELTA_TIME_LONG; 4148 } else if (deltaTime >= DELTA_TIME_ABS) { 4149 deltaTimeToken = DELTA_TIME_INT; 4150 } else { 4151 deltaTimeToken = (int)deltaTime; 4152 } 4153 int firstToken = deltaTimeToken | (cur.states&DELTA_STATE_MASK); 4154 final int includeStepDetails = mLastHistoryStepLevel > cur.batteryLevel 4155 ? BATTERY_DELTA_LEVEL_FLAG : 0; 4156 final boolean computeStepDetails = includeStepDetails != 0 4157 || mLastHistoryStepDetails == null; 4158 final int batteryLevelInt = buildBatteryLevelInt(cur) | includeStepDetails; 4159 final boolean batteryLevelIntChanged = batteryLevelInt != lastBatteryLevelInt; 4160 if (batteryLevelIntChanged) { 4161 firstToken |= DELTA_BATTERY_LEVEL_FLAG; 4162 } 4163 final int stateInt = buildStateInt(cur); 4164 final boolean stateIntChanged = stateInt != lastStateInt; 4165 if (stateIntChanged) { 4166 firstToken |= DELTA_STATE_FLAG; 4167 } 4168 final boolean state2IntChanged = cur.states2 != last.states2; 4169 if (state2IntChanged) { 4170 firstToken |= DELTA_STATE2_FLAG; 4171 } 4172 if (cur.wakelockTag != null || cur.wakeReasonTag != null) { 4173 firstToken |= DELTA_WAKELOCK_FLAG; 4174 } 4175 if (cur.eventCode != HistoryItem.EVENT_NONE) { 4176 firstToken |= DELTA_EVENT_FLAG; 4177 } 4178 4179 final boolean batteryChargeChanged = cur.batteryChargeUah != last.batteryChargeUah; 4180 if (batteryChargeChanged) { 4181 firstToken |= DELTA_BATTERY_CHARGE_FLAG; 4182 } 4183 dest.writeInt(firstToken); 4184 if (DEBUG) Slog.i(TAG, "WRITE DELTA: firstToken=0x" + Integer.toHexString(firstToken) 4185 + " deltaTime=" + deltaTime); 4186 4187 if (deltaTimeToken >= DELTA_TIME_INT) { 4188 if (deltaTimeToken == DELTA_TIME_INT) { 4189 if (DEBUG) Slog.i(TAG, "WRITE DELTA: int deltaTime=" + (int)deltaTime); 4190 dest.writeInt((int)deltaTime); 4191 } else { 4192 if (DEBUG) Slog.i(TAG, "WRITE DELTA: long deltaTime=" + deltaTime); 4193 dest.writeLong(deltaTime); 4194 } 4195 } 4196 if (batteryLevelIntChanged) { 4197 dest.writeInt(batteryLevelInt); 4198 if (DEBUG) Slog.i(TAG, "WRITE DELTA: batteryToken=0x" 4199 + Integer.toHexString(batteryLevelInt) 4200 + " batteryLevel=" + cur.batteryLevel 4201 + " batteryTemp=" + cur.batteryTemperature 4202 + " batteryVolt=" + (int)cur.batteryVoltage); 4203 } 4204 if (stateIntChanged) { 4205 dest.writeInt(stateInt); 4206 if (DEBUG) Slog.i(TAG, "WRITE DELTA: stateToken=0x" 4207 + Integer.toHexString(stateInt) 4208 + " batteryStatus=" + cur.batteryStatus 4209 + " batteryHealth=" + cur.batteryHealth 4210 + " batteryPlugType=" + cur.batteryPlugType 4211 + " states=0x" + Integer.toHexString(cur.states)); 4212 } 4213 if (state2IntChanged) { 4214 dest.writeInt(cur.states2); 4215 if (DEBUG) Slog.i(TAG, "WRITE DELTA: states2=0x" 4216 + Integer.toHexString(cur.states2)); 4217 } 4218 if (cur.wakelockTag != null || cur.wakeReasonTag != null) { 4219 int wakeLockIndex; 4220 int wakeReasonIndex; 4221 if (cur.wakelockTag != null) { 4222 wakeLockIndex = writeHistoryTag(cur.wakelockTag); 4223 if (DEBUG) Slog.i(TAG, "WRITE DELTA: wakelockTag=#" + cur.wakelockTag.poolIdx 4224 + " " + cur.wakelockTag.uid + ":" + cur.wakelockTag.string); 4225 } else { 4226 wakeLockIndex = 0xffff; 4227 } 4228 if (cur.wakeReasonTag != null) { 4229 wakeReasonIndex = writeHistoryTag(cur.wakeReasonTag); 4230 if (DEBUG) Slog.i(TAG, "WRITE DELTA: wakeReasonTag=#" + cur.wakeReasonTag.poolIdx 4231 + " " + cur.wakeReasonTag.uid + ":" + cur.wakeReasonTag.string); 4232 } else { 4233 wakeReasonIndex = 0xffff; 4234 } 4235 dest.writeInt((wakeReasonIndex<<16) | wakeLockIndex); 4236 if (cur.wakelockTag != null && (wakeLockIndex & TAG_FIRST_OCCURRENCE_FLAG) != 0) { 4237 cur.wakelockTag.writeToParcel(dest, 0); 4238 cur.tagsFirstOccurrence = true; 4239 } 4240 if (cur.wakeReasonTag != null && (wakeReasonIndex & TAG_FIRST_OCCURRENCE_FLAG) != 0) { 4241 cur.wakeReasonTag.writeToParcel(dest, 0); 4242 cur.tagsFirstOccurrence = true; 4243 } 4244 } 4245 if (cur.eventCode != HistoryItem.EVENT_NONE) { 4246 final int index = writeHistoryTag(cur.eventTag); 4247 final int codeAndIndex = (cur.eventCode & 0xffff) | (index << 16); 4248 dest.writeInt(codeAndIndex); 4249 if ((index & TAG_FIRST_OCCURRENCE_FLAG) != 0) { 4250 cur.eventTag.writeToParcel(dest, 0); 4251 cur.tagsFirstOccurrence = true; 4252 } 4253 if (DEBUG) Slog.i(TAG, "WRITE DELTA: event=" + cur.eventCode + " tag=#" 4254 + cur.eventTag.poolIdx + " " + cur.eventTag.uid + ":" 4255 + cur.eventTag.string); 4256 } 4257 if (computeStepDetails) { 4258 if (mPlatformIdleStateCallback != null) { 4259 mCurHistoryStepDetails.statSubsystemPowerState = 4260 mPlatformIdleStateCallback.getSubsystemLowPowerStats(); 4261 if (DEBUG) Slog.i(TAG, "WRITE SubsystemPowerState:" + 4262 mCurHistoryStepDetails.statSubsystemPowerState); 4263 4264 } 4265 computeHistoryStepDetails(mCurHistoryStepDetails, mLastHistoryStepDetails); 4266 if (includeStepDetails != 0) { 4267 mCurHistoryStepDetails.writeToParcel(dest); 4268 } 4269 cur.stepDetails = mCurHistoryStepDetails; 4270 mLastHistoryStepDetails = mCurHistoryStepDetails; 4271 } else { 4272 cur.stepDetails = null; 4273 } 4274 if (mLastHistoryStepLevel < cur.batteryLevel) { 4275 mLastHistoryStepDetails = null; 4276 } 4277 mLastHistoryStepLevel = cur.batteryLevel; 4278 4279 if (batteryChargeChanged) { 4280 if (DEBUG) Slog.i(TAG, "WRITE DELTA: batteryChargeUah=" + cur.batteryChargeUah); 4281 dest.writeInt(cur.batteryChargeUah); 4282 } 4283 dest.writeDouble(cur.modemRailChargeMah); 4284 dest.writeDouble(cur.wifiRailChargeMah); 4285 } 4286 buildBatteryLevelInt(HistoryItem h)4287 private int buildBatteryLevelInt(HistoryItem h) { 4288 return ((((int)h.batteryLevel)<<25)&0xfe000000) 4289 | ((((int)h.batteryTemperature)<<15)&0x01ff8000) 4290 | ((((int)h.batteryVoltage)<<1)&0x00007ffe); 4291 } 4292 readBatteryLevelInt(int batteryLevelInt, HistoryItem out)4293 private void readBatteryLevelInt(int batteryLevelInt, HistoryItem out) { 4294 out.batteryLevel = (byte)((batteryLevelInt & 0xfe000000) >>> 25); 4295 out.batteryTemperature = (short)((batteryLevelInt & 0x01ff8000) >>> 15); 4296 out.batteryVoltage = (char)((batteryLevelInt & 0x00007ffe) >>> 1); 4297 } 4298 buildStateInt(HistoryItem h)4299 private int buildStateInt(HistoryItem h) { 4300 int plugType = 0; 4301 if ((h.batteryPlugType&BatteryManager.BATTERY_PLUGGED_AC) != 0) { 4302 plugType = 1; 4303 } else if ((h.batteryPlugType&BatteryManager.BATTERY_PLUGGED_USB) != 0) { 4304 plugType = 2; 4305 } else if ((h.batteryPlugType&BatteryManager.BATTERY_PLUGGED_WIRELESS) != 0) { 4306 plugType = 3; 4307 } 4308 return ((h.batteryStatus&STATE_BATTERY_STATUS_MASK)<<STATE_BATTERY_STATUS_SHIFT) 4309 | ((h.batteryHealth&STATE_BATTERY_HEALTH_MASK)<<STATE_BATTERY_HEALTH_SHIFT) 4310 | ((plugType&STATE_BATTERY_PLUG_MASK)<<STATE_BATTERY_PLUG_SHIFT) 4311 | (h.states&(~STATE_BATTERY_MASK)); 4312 } 4313 computeHistoryStepDetails(final HistoryStepDetails out, final HistoryStepDetails last)4314 private void computeHistoryStepDetails(final HistoryStepDetails out, 4315 final HistoryStepDetails last) { 4316 final HistoryStepDetails tmp = last != null ? mTmpHistoryStepDetails : out; 4317 4318 // Perform a CPU update right after we do this collection, so we have started 4319 // collecting good data for the next step. 4320 requestImmediateCpuUpdate(); 4321 4322 if (last == null) { 4323 // We are not generating a delta, so all we need to do is reset the stats 4324 // we will later be doing a delta from. 4325 final int NU = mUidStats.size(); 4326 for (int i=0; i<NU; i++) { 4327 final BatteryStatsImpl.Uid uid = mUidStats.valueAt(i); 4328 uid.mLastStepUserTimeMs = uid.mCurStepUserTimeMs; 4329 uid.mLastStepSystemTimeMs = uid.mCurStepSystemTimeMs; 4330 } 4331 mLastStepCpuUserTimeMs = mCurStepCpuUserTimeMs; 4332 mLastStepCpuSystemTimeMs = mCurStepCpuSystemTimeMs; 4333 mLastStepStatUserTimeMs = mCurStepStatUserTimeMs; 4334 mLastStepStatSystemTimeMs = mCurStepStatSystemTimeMs; 4335 mLastStepStatIOWaitTimeMs = mCurStepStatIOWaitTimeMs; 4336 mLastStepStatIrqTimeMs = mCurStepStatIrqTimeMs; 4337 mLastStepStatSoftIrqTimeMs = mCurStepStatSoftIrqTimeMs; 4338 mLastStepStatIdleTimeMs = mCurStepStatIdleTimeMs; 4339 tmp.clear(); 4340 return; 4341 } 4342 if (DEBUG) { 4343 Slog.d(TAG, "Step stats last: user=" + mLastStepCpuUserTimeMs + " sys=" 4344 + mLastStepStatSystemTimeMs + " io=" + mLastStepStatIOWaitTimeMs 4345 + " irq=" + mLastStepStatIrqTimeMs + " sirq=" 4346 + mLastStepStatSoftIrqTimeMs + " idle=" + mLastStepStatIdleTimeMs); 4347 Slog.d(TAG, "Step stats cur: user=" + mCurStepCpuUserTimeMs + " sys=" 4348 + mCurStepStatSystemTimeMs + " io=" + mCurStepStatIOWaitTimeMs 4349 + " irq=" + mCurStepStatIrqTimeMs + " sirq=" 4350 + mCurStepStatSoftIrqTimeMs + " idle=" + mCurStepStatIdleTimeMs); 4351 } 4352 out.userTime = (int) (mCurStepCpuUserTimeMs - mLastStepCpuUserTimeMs); 4353 out.systemTime = (int) (mCurStepCpuSystemTimeMs - mLastStepCpuSystemTimeMs); 4354 out.statUserTime = (int) (mCurStepStatUserTimeMs - mLastStepStatUserTimeMs); 4355 out.statSystemTime = (int) (mCurStepStatSystemTimeMs - mLastStepStatSystemTimeMs); 4356 out.statIOWaitTime = (int) (mCurStepStatIOWaitTimeMs - mLastStepStatIOWaitTimeMs); 4357 out.statIrqTime = (int) (mCurStepStatIrqTimeMs - mLastStepStatIrqTimeMs); 4358 out.statSoftIrqTime = (int) (mCurStepStatSoftIrqTimeMs - mLastStepStatSoftIrqTimeMs); 4359 out.statIdlTime = (int) (mCurStepStatIdleTimeMs - mLastStepStatIdleTimeMs); 4360 out.appCpuUid1 = out.appCpuUid2 = out.appCpuUid3 = -1; 4361 out.appCpuUTime1 = out.appCpuUTime2 = out.appCpuUTime3 = 0; 4362 out.appCpuSTime1 = out.appCpuSTime2 = out.appCpuSTime3 = 0; 4363 final int NU = mUidStats.size(); 4364 for (int i=0; i<NU; i++) { 4365 final BatteryStatsImpl.Uid uid = mUidStats.valueAt(i); 4366 final int totalUTimeMs = (int) (uid.mCurStepUserTimeMs - uid.mLastStepUserTimeMs); 4367 final int totalSTimeMs = (int) (uid.mCurStepSystemTimeMs - uid.mLastStepSystemTimeMs); 4368 final int totalTimeMs = totalUTimeMs + totalSTimeMs; 4369 uid.mLastStepUserTimeMs = uid.mCurStepUserTimeMs; 4370 uid.mLastStepSystemTimeMs = uid.mCurStepSystemTimeMs; 4371 if (totalTimeMs <= (out.appCpuUTime3 + out.appCpuSTime3)) { 4372 continue; 4373 } 4374 if (totalTimeMs <= (out.appCpuUTime2 + out.appCpuSTime2)) { 4375 out.appCpuUid3 = uid.mUid; 4376 out.appCpuUTime3 = totalUTimeMs; 4377 out.appCpuSTime3 = totalSTimeMs; 4378 } else { 4379 out.appCpuUid3 = out.appCpuUid2; 4380 out.appCpuUTime3 = out.appCpuUTime2; 4381 out.appCpuSTime3 = out.appCpuSTime2; 4382 if (totalTimeMs <= (out.appCpuUTime1 + out.appCpuSTime1)) { 4383 out.appCpuUid2 = uid.mUid; 4384 out.appCpuUTime2 = totalUTimeMs; 4385 out.appCpuSTime2 = totalSTimeMs; 4386 } else { 4387 out.appCpuUid2 = out.appCpuUid1; 4388 out.appCpuUTime2 = out.appCpuUTime1; 4389 out.appCpuSTime2 = out.appCpuSTime1; 4390 out.appCpuUid1 = uid.mUid; 4391 out.appCpuUTime1 = totalUTimeMs; 4392 out.appCpuSTime1 = totalSTimeMs; 4393 } 4394 } 4395 } 4396 mLastStepCpuUserTimeMs = mCurStepCpuUserTimeMs; 4397 mLastStepCpuSystemTimeMs = mCurStepCpuSystemTimeMs; 4398 mLastStepStatUserTimeMs = mCurStepStatUserTimeMs; 4399 mLastStepStatSystemTimeMs = mCurStepStatSystemTimeMs; 4400 mLastStepStatIOWaitTimeMs = mCurStepStatIOWaitTimeMs; 4401 mLastStepStatIrqTimeMs = mCurStepStatIrqTimeMs; 4402 mLastStepStatSoftIrqTimeMs = mCurStepStatSoftIrqTimeMs; 4403 mLastStepStatIdleTimeMs = mCurStepStatIdleTimeMs; 4404 } 4405 4406 @GuardedBy("this") 4407 @Override commitCurrentHistoryBatchLocked()4408 public void commitCurrentHistoryBatchLocked() { 4409 mHistoryLastWritten.cmd = HistoryItem.CMD_NULL; 4410 } 4411 4412 @GuardedBy("this") createFakeHistoryEvents(long numEvents)4413 public void createFakeHistoryEvents(long numEvents) { 4414 final long elapsedRealtimeMs = mClock.elapsedRealtime(); 4415 final long uptimeMs = mClock.uptimeMillis(); 4416 for(long i = 0; i < numEvents; i++) { 4417 noteLongPartialWakelockStart("name1", "historyName1", 1000, 4418 elapsedRealtimeMs, uptimeMs); 4419 noteLongPartialWakelockFinish("name1", "historyName1", 1000, 4420 elapsedRealtimeMs, uptimeMs); 4421 } 4422 } 4423 4424 @GuardedBy("this") addHistoryBufferLocked(long elapsedRealtimeMs, long uptimeMs, HistoryItem cur)4425 void addHistoryBufferLocked(long elapsedRealtimeMs, long uptimeMs, HistoryItem cur) { 4426 if (!mHaveBatteryLevel || !mRecordingHistory) { 4427 return; 4428 } 4429 4430 final long timeDiffMs = (mHistoryBaseTimeMs + elapsedRealtimeMs) - mHistoryLastWritten.time; 4431 final int diffStates = mHistoryLastWritten.states^(cur.states&mActiveHistoryStates); 4432 final int diffStates2 = mHistoryLastWritten.states2^(cur.states2&mActiveHistoryStates2); 4433 final int lastDiffStates = mHistoryLastWritten.states^mHistoryLastLastWritten.states; 4434 final int lastDiffStates2 = mHistoryLastWritten.states2^mHistoryLastLastWritten.states2; 4435 if (DEBUG) { 4436 Slog.i(TAG, "ADD: tdelta=" + timeDiffMs + " diff=" 4437 + Integer.toHexString(diffStates) + " lastDiff=" 4438 + Integer.toHexString(lastDiffStates) + " diff2=" 4439 + Integer.toHexString(diffStates2) + " lastDiff2=" 4440 + Integer.toHexString(lastDiffStates2)); 4441 } 4442 4443 mBatteryStatsHistory.recordTraceEvents(cur.eventCode, cur.eventTag); 4444 mBatteryStatsHistory.recordTraceCounters(mHistoryLastWritten.states, 4445 cur.states & mActiveHistoryStates, BatteryStats.HISTORY_STATE_DESCRIPTIONS); 4446 mBatteryStatsHistory.recordTraceCounters(mHistoryLastWritten.states2, 4447 cur.states2 & mActiveHistoryStates2, BatteryStats.HISTORY_STATE2_DESCRIPTIONS); 4448 if (mHistoryBufferLastPos >= 0 && mHistoryLastWritten.cmd == HistoryItem.CMD_UPDATE 4449 && timeDiffMs < 1000 && (diffStates & lastDiffStates) == 0 4450 && (diffStates2&lastDiffStates2) == 0 4451 && (!mHistoryLastWritten.tagsFirstOccurrence && !cur.tagsFirstOccurrence) 4452 && (mHistoryLastWritten.wakelockTag == null || cur.wakelockTag == null) 4453 && (mHistoryLastWritten.wakeReasonTag == null || cur.wakeReasonTag == null) 4454 && mHistoryLastWritten.stepDetails == null 4455 && (mHistoryLastWritten.eventCode == HistoryItem.EVENT_NONE 4456 || cur.eventCode == HistoryItem.EVENT_NONE) 4457 && mHistoryLastWritten.batteryLevel == cur.batteryLevel 4458 && mHistoryLastWritten.batteryStatus == cur.batteryStatus 4459 && mHistoryLastWritten.batteryHealth == cur.batteryHealth 4460 && mHistoryLastWritten.batteryPlugType == cur.batteryPlugType 4461 && mHistoryLastWritten.batteryTemperature == cur.batteryTemperature 4462 && mHistoryLastWritten.batteryVoltage == cur.batteryVoltage) { 4463 // We can merge this new change in with the last one. Merging is 4464 // allowed as long as only the states have changed, and within those states 4465 // as long as no bit has changed both between now and the last entry, as 4466 // well as the last entry and the one before it (so we capture any toggles). 4467 if (DEBUG) Slog.i(TAG, "ADD: rewinding back to " + mHistoryBufferLastPos); 4468 mHistoryBuffer.setDataSize(mHistoryBufferLastPos); 4469 mHistoryBuffer.setDataPosition(mHistoryBufferLastPos); 4470 mHistoryBufferLastPos = -1; 4471 elapsedRealtimeMs = mHistoryLastWritten.time - mHistoryBaseTimeMs; 4472 // If the last written history had a wakelock tag, we need to retain it. 4473 // Note that the condition above made sure that we aren't in a case where 4474 // both it and the current history item have a wakelock tag. 4475 if (mHistoryLastWritten.wakelockTag != null) { 4476 cur.wakelockTag = cur.localWakelockTag; 4477 cur.wakelockTag.setTo(mHistoryLastWritten.wakelockTag); 4478 } 4479 // If the last written history had a wake reason tag, we need to retain it. 4480 // Note that the condition above made sure that we aren't in a case where 4481 // both it and the current history item have a wakelock tag. 4482 if (mHistoryLastWritten.wakeReasonTag != null) { 4483 cur.wakeReasonTag = cur.localWakeReasonTag; 4484 cur.wakeReasonTag.setTo(mHistoryLastWritten.wakeReasonTag); 4485 } 4486 // If the last written history had an event, we need to retain it. 4487 // Note that the condition above made sure that we aren't in a case where 4488 // both it and the current history item have an event. 4489 if (mHistoryLastWritten.eventCode != HistoryItem.EVENT_NONE) { 4490 cur.eventCode = mHistoryLastWritten.eventCode; 4491 cur.eventTag = cur.localEventTag; 4492 cur.eventTag.setTo(mHistoryLastWritten.eventTag); 4493 } 4494 mHistoryLastWritten.setTo(mHistoryLastLastWritten); 4495 } 4496 final int dataSize = mHistoryBuffer.dataSize(); 4497 4498 if (dataSize >= mConstants.MAX_HISTORY_BUFFER) { 4499 //open a new history file. 4500 final long start = SystemClock.uptimeMillis(); 4501 writeHistoryLocked(true); 4502 if (DEBUG) { 4503 Slog.d(TAG, "addHistoryBufferLocked writeHistoryLocked takes ms:" 4504 + (SystemClock.uptimeMillis() - start)); 4505 } 4506 mBatteryStatsHistory.startNextFile(); 4507 mHistoryBuffer.setDataSize(0); 4508 mHistoryBuffer.setDataPosition(0); 4509 mHistoryBuffer.setDataCapacity(mConstants.MAX_HISTORY_BUFFER / 2); 4510 mHistoryBufferLastPos = -1; 4511 mHistoryLastWritten.clear(); 4512 mHistoryLastLastWritten.clear(); 4513 4514 // Mark every entry in the pool with a flag indicating that the tag 4515 // has not yet been encountered while writing the current history buffer. 4516 for (Map.Entry<HistoryTag, Integer> entry: mHistoryTagPool.entrySet()) { 4517 entry.setValue(entry.getValue() | TAG_FIRST_OCCURRENCE_FLAG); 4518 } 4519 // Make a copy of mHistoryCur. 4520 HistoryItem copy = new HistoryItem(); 4521 copy.setTo(cur); 4522 // startRecordingHistory will reset mHistoryCur. 4523 startRecordingHistory(elapsedRealtimeMs, uptimeMs, false); 4524 // Add the copy into history buffer. 4525 addHistoryBufferLocked(elapsedRealtimeMs, HistoryItem.CMD_UPDATE, copy); 4526 return; 4527 } 4528 4529 if (dataSize == 0) { 4530 // The history is currently empty; we need it to start with a time stamp. 4531 cur.currentTime = mClock.currentTimeMillis(); 4532 addHistoryBufferLocked(elapsedRealtimeMs, HistoryItem.CMD_RESET, cur); 4533 } 4534 addHistoryBufferLocked(elapsedRealtimeMs, HistoryItem.CMD_UPDATE, cur); 4535 } 4536 4537 @GuardedBy("this") addHistoryBufferLocked(long elapsedRealtimeMs, byte cmd, HistoryItem cur)4538 private void addHistoryBufferLocked(long elapsedRealtimeMs, byte cmd, HistoryItem cur) { 4539 if (mBatteryStatsHistoryIterator != null) { 4540 throw new IllegalStateException("Can't do this while iterating history!"); 4541 } 4542 mHistoryBufferLastPos = mHistoryBuffer.dataPosition(); 4543 mHistoryLastLastWritten.setTo(mHistoryLastWritten); 4544 final boolean hasTags = mHistoryLastWritten.tagsFirstOccurrence || cur.tagsFirstOccurrence; 4545 mHistoryLastWritten.setTo(mHistoryBaseTimeMs + elapsedRealtimeMs, cmd, cur); 4546 mHistoryLastWritten.tagsFirstOccurrence = hasTags; 4547 mHistoryLastWritten.states &= mActiveHistoryStates; 4548 mHistoryLastWritten.states2 &= mActiveHistoryStates2; 4549 writeHistoryDelta(mHistoryBuffer, mHistoryLastWritten, mHistoryLastLastWritten); 4550 mLastHistoryElapsedRealtimeMs = elapsedRealtimeMs; 4551 cur.wakelockTag = null; 4552 cur.wakeReasonTag = null; 4553 cur.eventCode = HistoryItem.EVENT_NONE; 4554 cur.eventTag = null; 4555 cur.tagsFirstOccurrence = false; 4556 if (DEBUG_HISTORY) Slog.i(TAG, "Writing history buffer: was " + mHistoryBufferLastPos 4557 + " now " + mHistoryBuffer.dataPosition() 4558 + " size is now " + mHistoryBuffer.dataSize()); 4559 } 4560 4561 int mChangedStates = 0; 4562 int mChangedStates2 = 0; 4563 4564 @GuardedBy("this") addHistoryRecordLocked(long elapsedRealtimeMs, long uptimeMs)4565 void addHistoryRecordLocked(long elapsedRealtimeMs, long uptimeMs) { 4566 if (mTrackRunningHistoryElapsedRealtimeMs != 0) { 4567 final long diffElapsedMs = elapsedRealtimeMs - mTrackRunningHistoryElapsedRealtimeMs; 4568 final long diffUptimeMs = uptimeMs - mTrackRunningHistoryUptimeMs; 4569 if (diffUptimeMs < (diffElapsedMs - 20)) { 4570 final long wakeElapsedTimeMs = elapsedRealtimeMs - (diffElapsedMs - diffUptimeMs); 4571 mHistoryAddTmp.setTo(mHistoryLastWritten); 4572 mHistoryAddTmp.wakelockTag = null; 4573 mHistoryAddTmp.wakeReasonTag = null; 4574 mHistoryAddTmp.eventCode = HistoryItem.EVENT_NONE; 4575 mHistoryAddTmp.states &= ~HistoryItem.STATE_CPU_RUNNING_FLAG; 4576 addHistoryRecordInnerLocked(wakeElapsedTimeMs, uptimeMs, mHistoryAddTmp); 4577 } 4578 } 4579 mHistoryCur.states |= HistoryItem.STATE_CPU_RUNNING_FLAG; 4580 mTrackRunningHistoryElapsedRealtimeMs = elapsedRealtimeMs; 4581 mTrackRunningHistoryUptimeMs = uptimeMs; 4582 addHistoryRecordInnerLocked(elapsedRealtimeMs, uptimeMs, mHistoryCur); 4583 } 4584 4585 @GuardedBy("this") addHistoryRecordInnerLocked(long elapsedRealtimeMs, long uptimeMs, HistoryItem cur)4586 void addHistoryRecordInnerLocked(long elapsedRealtimeMs, long uptimeMs, HistoryItem cur) { 4587 addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, cur); 4588 } 4589 4590 @GuardedBy("this") addHistoryEventLocked(long elapsedRealtimeMs, long uptimeMs, int code, String name, int uid)4591 public void addHistoryEventLocked(long elapsedRealtimeMs, long uptimeMs, int code, 4592 String name, int uid) { 4593 mHistoryCur.eventCode = code; 4594 mHistoryCur.eventTag = mHistoryCur.localEventTag; 4595 mHistoryCur.eventTag.string = name; 4596 mHistoryCur.eventTag.uid = uid; 4597 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 4598 } 4599 4600 @GuardedBy("this") addHistoryRecordLocked(long elapsedRealtimeMs, long uptimeMs, byte cmd, HistoryItem cur)4601 void addHistoryRecordLocked(long elapsedRealtimeMs, long uptimeMs, byte cmd, HistoryItem cur) { 4602 HistoryItem rec = mHistoryCache; 4603 if (rec != null) { 4604 mHistoryCache = rec.next; 4605 } else { 4606 rec = new HistoryItem(); 4607 } 4608 rec.setTo(mHistoryBaseTimeMs + elapsedRealtimeMs, cmd, cur); 4609 4610 addHistoryRecordLocked(rec); 4611 } 4612 4613 @GuardedBy("this") addHistoryRecordLocked(HistoryItem rec)4614 void addHistoryRecordLocked(HistoryItem rec) { 4615 mNumHistoryItems++; 4616 rec.next = null; 4617 mHistoryLastEnd = mHistoryEnd; 4618 if (mHistoryEnd != null) { 4619 mHistoryEnd.next = rec; 4620 mHistoryEnd = rec; 4621 } else { 4622 mHistory = mHistoryEnd = rec; 4623 } 4624 } 4625 4626 @GuardedBy("this") clearHistoryLocked()4627 void clearHistoryLocked() { 4628 if (DEBUG_HISTORY) Slog.i(TAG, "********** CLEARING HISTORY!"); 4629 mHistoryBaseTimeMs = 0; 4630 mLastHistoryElapsedRealtimeMs = 0; 4631 mTrackRunningHistoryElapsedRealtimeMs = 0; 4632 mTrackRunningHistoryUptimeMs = 0; 4633 4634 mHistoryBuffer.setDataSize(0); 4635 mHistoryBuffer.setDataPosition(0); 4636 mHistoryBuffer.setDataCapacity(mConstants.MAX_HISTORY_BUFFER / 2); 4637 mHistoryLastLastWritten.clear(); 4638 mHistoryLastWritten.clear(); 4639 mHistoryTagPool.clear(); 4640 mNextHistoryTagIdx = 0; 4641 mNumHistoryTagChars = 0; 4642 mHistoryBufferLastPos = -1; 4643 mActiveHistoryStates = 0xffffffff; 4644 mActiveHistoryStates2 = 0xffffffff; 4645 } 4646 4647 @GuardedBy("this") updateTimeBasesLocked(boolean unplugged, int screenState, long uptimeUs, long realtimeUs)4648 public void updateTimeBasesLocked(boolean unplugged, int screenState, long uptimeUs, 4649 long realtimeUs) { 4650 final boolean screenOff = !Display.isOnState(screenState); 4651 final boolean updateOnBatteryTimeBase = unplugged != mOnBatteryTimeBase.isRunning(); 4652 final boolean updateOnBatteryScreenOffTimeBase = 4653 (unplugged && screenOff) != mOnBatteryScreenOffTimeBase.isRunning(); 4654 4655 if (updateOnBatteryScreenOffTimeBase || updateOnBatteryTimeBase) { 4656 if (updateOnBatteryScreenOffTimeBase) { 4657 updateKernelWakelocksLocked(realtimeUs); 4658 updateBatteryPropertiesLocked(); 4659 } 4660 // This if{} is only necessary due to SCREEN_OFF_RPM_STATS_ENABLED, which exists because 4661 // updateRpmStatsLocked is too slow to run each screen change. When the speed is 4662 // improved, remove the surrounding if{}. 4663 if (SCREEN_OFF_RPM_STATS_ENABLED || updateOnBatteryTimeBase) { 4664 // if either OnBattery or OnBatteryScreenOfftimebase changes. 4665 updateRpmStatsLocked(realtimeUs); 4666 } 4667 if (DEBUG_ENERGY_CPU) { 4668 Slog.d(TAG, "Updating cpu time because screen is now " 4669 + Display.stateToString(screenState) 4670 + " and battery is " + (unplugged ? "on" : "off")); 4671 } 4672 4673 mOnBatteryTimeBase.setRunning(unplugged, uptimeUs, realtimeUs); 4674 if (updateOnBatteryTimeBase) { 4675 for (int i = mUidStats.size() - 1; i >= 0; --i) { 4676 mUidStats.valueAt(i).updateOnBatteryBgTimeBase(uptimeUs, realtimeUs); 4677 } 4678 } 4679 if (updateOnBatteryScreenOffTimeBase) { 4680 mOnBatteryScreenOffTimeBase.setRunning(unplugged && screenOff, 4681 uptimeUs, realtimeUs); 4682 for (int i = mUidStats.size() - 1; i >= 0; --i) { 4683 mUidStats.valueAt(i).updateOnBatteryScreenOffBgTimeBase(uptimeUs, realtimeUs); 4684 } 4685 } 4686 } 4687 } 4688 4689 @GuardedBy("this") updateBatteryPropertiesLocked()4690 private void updateBatteryPropertiesLocked() { 4691 try { 4692 IBatteryPropertiesRegistrar registrar = IBatteryPropertiesRegistrar.Stub.asInterface( 4693 ServiceManager.getService("batteryproperties")); 4694 if (registrar != null) { 4695 registrar.scheduleUpdate(); 4696 } 4697 } catch (RemoteException e) { 4698 // Ignore. 4699 } 4700 } 4701 4702 @GuardedBy("this") addIsolatedUidLocked(int isolatedUid, int appUid)4703 public void addIsolatedUidLocked(int isolatedUid, int appUid) { 4704 addIsolatedUidLocked(isolatedUid, appUid, 4705 mClock.elapsedRealtime(), mClock.uptimeMillis()); 4706 } 4707 4708 @GuardedBy("this") 4709 @SuppressWarnings("GuardedBy") // errorprone false positive on u.addIsolatedUid addIsolatedUidLocked(int isolatedUid, int appUid, long elapsedRealtimeMs, long uptimeMs)4710 public void addIsolatedUidLocked(int isolatedUid, int appUid, 4711 long elapsedRealtimeMs, long uptimeMs) { 4712 mIsolatedUids.put(isolatedUid, appUid); 4713 mIsolatedUidRefCounts.put(isolatedUid, 1); 4714 final Uid u = getUidStatsLocked(appUid, elapsedRealtimeMs, uptimeMs); 4715 u.addIsolatedUid(isolatedUid); 4716 } 4717 4718 /** 4719 * Schedules a read of the latest cpu times before removing the isolated UID. 4720 * @see #removeIsolatedUidLocked(int, int, int) 4721 */ scheduleRemoveIsolatedUidLocked(int isolatedUid, int appUid)4722 public void scheduleRemoveIsolatedUidLocked(int isolatedUid, int appUid) { 4723 int curUid = mIsolatedUids.get(isolatedUid, -1); 4724 if (curUid == appUid) { 4725 if (mExternalSync != null) { 4726 mExternalSync.scheduleCpuSyncDueToRemovedUid(isolatedUid); 4727 } 4728 } 4729 } 4730 4731 /** 4732 * Isolated uid should only be removed after all wakelocks associated with the uid are stopped 4733 * and the cpu time-in-state has been read one last time for the uid. 4734 * 4735 * @see #scheduleRemoveIsolatedUidLocked(int, int) 4736 * 4737 * @return true if the isolated uid is actually removed. 4738 */ 4739 @GuardedBy("this") maybeRemoveIsolatedUidLocked(int isolatedUid, long elapsedRealtimeMs, long uptimeMs)4740 public boolean maybeRemoveIsolatedUidLocked(int isolatedUid, long elapsedRealtimeMs, 4741 long uptimeMs) { 4742 final int refCount = mIsolatedUidRefCounts.get(isolatedUid, 0) - 1; 4743 if (refCount > 0) { 4744 // Isolated uid is still being tracked 4745 mIsolatedUidRefCounts.put(isolatedUid, refCount); 4746 return false; 4747 } 4748 4749 final int idx = mIsolatedUids.indexOfKey(isolatedUid); 4750 if (idx >= 0) { 4751 final int ownerUid = mIsolatedUids.valueAt(idx); 4752 final Uid u = getUidStatsLocked(ownerUid, elapsedRealtimeMs, uptimeMs); 4753 u.removeIsolatedUid(isolatedUid); 4754 mIsolatedUids.removeAt(idx); 4755 mIsolatedUidRefCounts.delete(isolatedUid); 4756 } else { 4757 Slog.w(TAG, "Attempted to remove untracked isolated uid (" + isolatedUid + ")"); 4758 } 4759 mPendingRemovedUids.add(new UidToRemove(isolatedUid, elapsedRealtimeMs)); 4760 4761 return true; 4762 } 4763 4764 /** 4765 * Increment the ref count for an isolated uid. 4766 * call #maybeRemoveIsolatedUidLocked to decrement. 4767 */ incrementIsolatedUidRefCount(int uid)4768 public void incrementIsolatedUidRefCount(int uid) { 4769 final int refCount = mIsolatedUidRefCounts.get(uid, 0); 4770 if (refCount <= 0) { 4771 // Uid is not mapped or referenced 4772 Slog.w(TAG, 4773 "Attempted to increment ref counted of untracked isolated uid (" + uid + ")"); 4774 return; 4775 } 4776 mIsolatedUidRefCounts.put(uid, refCount + 1); 4777 } 4778 mapUid(int uid)4779 private int mapUid(int uid) { 4780 if (Process.isSdkSandboxUid(uid)) { 4781 return Process.getAppUidForSdkSandboxUid(uid); 4782 } 4783 return mapIsolatedUid(uid); 4784 } 4785 mapIsolatedUid(int uid)4786 private int mapIsolatedUid(int uid) { 4787 return mIsolatedUids.get(/*key=*/uid, /*valueIfKeyNotFound=*/uid); 4788 } 4789 4790 @GuardedBy("this") noteEventLocked(int code, String name, int uid)4791 public void noteEventLocked(int code, String name, int uid) { 4792 noteEventLocked(code, name, uid, mClock.elapsedRealtime(), mClock.uptimeMillis()); 4793 } 4794 4795 @GuardedBy("this") noteEventLocked(int code, String name, int uid, long elapsedRealtimeMs, long uptimeMs)4796 public void noteEventLocked(int code, String name, int uid, 4797 long elapsedRealtimeMs, long uptimeMs) { 4798 uid = mapUid(uid); 4799 if (!mActiveEvents.updateState(code, name, uid, 0)) { 4800 return; 4801 } 4802 addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, code, name, uid); 4803 } 4804 4805 @GuardedBy("this") noteCurrentTimeChangedLocked()4806 public void noteCurrentTimeChangedLocked() { 4807 final long currentTime = mClock.currentTimeMillis(); 4808 final long elapsedRealtime = mClock.elapsedRealtime(); 4809 final long uptime = mClock.uptimeMillis(); 4810 noteCurrentTimeChangedLocked(currentTime, elapsedRealtime, uptime); 4811 } 4812 4813 @GuardedBy("this") noteCurrentTimeChangedLocked(long currentTimeMs, long elapsedRealtimeMs, long uptimeMs)4814 public void noteCurrentTimeChangedLocked(long currentTimeMs, 4815 long elapsedRealtimeMs, long uptimeMs) { 4816 recordCurrentTimeChangeLocked(currentTimeMs, elapsedRealtimeMs, uptimeMs); 4817 } 4818 4819 @GuardedBy("this") noteProcessStartLocked(String name, int uid)4820 public void noteProcessStartLocked(String name, int uid) { 4821 noteProcessStartLocked(name, uid, mClock.elapsedRealtime(), mClock.uptimeMillis()); 4822 } 4823 4824 @GuardedBy("this") noteProcessStartLocked(String name, int uid, long elapsedRealtimeMs, long uptimeMs)4825 public void noteProcessStartLocked(String name, int uid, 4826 long elapsedRealtimeMs, long uptimeMs) { 4827 uid = mapUid(uid); 4828 if (isOnBattery()) { 4829 Uid u = getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs); 4830 u.getProcessStatsLocked(name).incStartsLocked(); 4831 } 4832 if (!mActiveEvents.updateState(HistoryItem.EVENT_PROC_START, name, uid, 0)) { 4833 return; 4834 } 4835 if (!mRecordAllHistory) { 4836 return; 4837 } 4838 addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_PROC_START, name, uid); 4839 } 4840 4841 @GuardedBy("this") noteProcessCrashLocked(String name, int uid)4842 public void noteProcessCrashLocked(String name, int uid) { 4843 noteProcessCrashLocked(name, uid, mClock.elapsedRealtime(), mClock.uptimeMillis()); 4844 } 4845 4846 @GuardedBy("this") noteProcessCrashLocked(String name, int uid, long elapsedRealtimeMs, long uptimeMs)4847 public void noteProcessCrashLocked(String name, int uid, 4848 long elapsedRealtimeMs, long uptimeMs) { 4849 uid = mapUid(uid); 4850 if (isOnBattery()) { 4851 Uid u = getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs); 4852 u.getProcessStatsLocked(name).incNumCrashesLocked(); 4853 } 4854 } 4855 4856 @GuardedBy("this") noteProcessAnrLocked(String name, int uid)4857 public void noteProcessAnrLocked(String name, int uid) { 4858 noteProcessAnrLocked(name, uid, mClock.elapsedRealtime(), mClock.uptimeMillis()); 4859 } 4860 4861 @GuardedBy("this") noteProcessAnrLocked(String name, int uid, long elapsedRealtimeMs, long uptimeMs)4862 public void noteProcessAnrLocked(String name, int uid, long elapsedRealtimeMs, long uptimeMs) { 4863 uid = mapUid(uid); 4864 if (isOnBattery()) { 4865 Uid u = getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs); 4866 u.getProcessStatsLocked(name).incNumAnrsLocked(); 4867 } 4868 } 4869 4870 @GuardedBy("this") noteUidProcessStateLocked(int uid, int state)4871 public void noteUidProcessStateLocked(int uid, int state) { 4872 noteUidProcessStateLocked(uid, state, mClock.elapsedRealtime(), mClock.uptimeMillis()); 4873 } 4874 4875 @GuardedBy("this") 4876 @SuppressWarnings("GuardedBy") // errorprone false positive on u.updateUidProcessStateLocked noteUidProcessStateLocked(int uid, int state, long elapsedRealtimeMs, long uptimeMs)4877 public void noteUidProcessStateLocked(int uid, int state, 4878 long elapsedRealtimeMs, long uptimeMs) { 4879 int parentUid = mapUid(uid); 4880 if (uid != parentUid) { 4881 if (Process.isIsolated(uid)) { 4882 // Isolated UIDs process state is already rolled up into parent, so no need to track 4883 // Otherwise the parent's process state will get downgraded incorrectly 4884 return; 4885 } 4886 } 4887 // TODO(b/155216561): It is possible for isolated uids to be in a higher 4888 // state than its parent uid. We should track the highest state within the union of host 4889 // and isolated uids rather than only the parent uid. 4890 FrameworkStatsLog.write(FrameworkStatsLog.UID_PROCESS_STATE_CHANGED, uid, 4891 ActivityManager.processStateAmToProto(state)); 4892 getUidStatsLocked(parentUid, elapsedRealtimeMs, uptimeMs) 4893 .updateUidProcessStateLocked(state, elapsedRealtimeMs, uptimeMs); 4894 } 4895 4896 @GuardedBy("this") noteProcessFinishLocked(String name, int uid)4897 public void noteProcessFinishLocked(String name, int uid) { 4898 noteProcessFinishLocked(name, uid, mClock.elapsedRealtime(), mClock.uptimeMillis()); 4899 } 4900 4901 @GuardedBy("this") noteProcessFinishLocked(String name, int uid, long elapsedRealtimeMs, long uptimeMs)4902 public void noteProcessFinishLocked(String name, int uid, 4903 long elapsedRealtimeMs, long uptimeMs) { 4904 uid = mapUid(uid); 4905 if (!mActiveEvents.updateState(HistoryItem.EVENT_PROC_FINISH, name, uid, 0)) { 4906 return; 4907 } 4908 if (!mRecordAllHistory) { 4909 return; 4910 } 4911 addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_PROC_FINISH, 4912 name, uid); 4913 } 4914 4915 @GuardedBy("this") noteSyncStartLocked(String name, int uid)4916 public void noteSyncStartLocked(String name, int uid) { 4917 noteSyncStartLocked(name, uid, mClock.elapsedRealtime(), mClock.uptimeMillis()); 4918 } 4919 4920 @GuardedBy("this") noteSyncStartLocked(String name, int uid, long elapsedRealtimeMs, long uptimeMs)4921 public void noteSyncStartLocked(String name, int uid, long elapsedRealtimeMs, long uptimeMs) { 4922 uid = mapUid(uid); 4923 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 4924 .noteStartSyncLocked(name, elapsedRealtimeMs); 4925 if (!mActiveEvents.updateState(HistoryItem.EVENT_SYNC_START, name, uid, 0)) { 4926 return; 4927 } 4928 addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_SYNC_START, name, uid); 4929 } 4930 4931 @GuardedBy("this") noteSyncFinishLocked(String name, int uid)4932 public void noteSyncFinishLocked(String name, int uid) { 4933 noteSyncFinishLocked(name, uid, mClock.elapsedRealtime(), mClock.uptimeMillis()); 4934 } 4935 4936 @GuardedBy("this") noteSyncFinishLocked(String name, int uid, long elapsedRealtimeMs, long uptimeMs)4937 public void noteSyncFinishLocked(String name, int uid, long elapsedRealtimeMs, long uptimeMs) { 4938 uid = mapUid(uid); 4939 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 4940 .noteStopSyncLocked(name, elapsedRealtimeMs); 4941 if (!mActiveEvents.updateState(HistoryItem.EVENT_SYNC_FINISH, name, uid, 0)) { 4942 return; 4943 } 4944 addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_SYNC_FINISH, 4945 name, uid); 4946 } 4947 4948 @GuardedBy("this") noteJobStartLocked(String name, int uid)4949 public void noteJobStartLocked(String name, int uid) { 4950 noteJobStartLocked(name, uid, mClock.elapsedRealtime(), mClock.uptimeMillis()); 4951 } 4952 4953 @GuardedBy("this") noteJobStartLocked(String name, int uid, long elapsedRealtimeMs, long uptimeMs)4954 public void noteJobStartLocked(String name, int uid, long elapsedRealtimeMs, long uptimeMs) { 4955 uid = mapUid(uid); 4956 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 4957 .noteStartJobLocked(name, elapsedRealtimeMs); 4958 if (!mActiveEvents.updateState(HistoryItem.EVENT_JOB_START, name, uid, 0)) { 4959 return; 4960 } 4961 addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_JOB_START, name, uid); 4962 } 4963 4964 @GuardedBy("this") noteJobFinishLocked(String name, int uid, int stopReason)4965 public void noteJobFinishLocked(String name, int uid, int stopReason) { 4966 noteJobFinishLocked(name, uid, stopReason, 4967 mClock.elapsedRealtime(), mClock.uptimeMillis()); 4968 } 4969 4970 @GuardedBy("this") noteJobFinishLocked(String name, int uid, int stopReason, long elapsedRealtimeMs, long uptimeMs)4971 public void noteJobFinishLocked(String name, int uid, int stopReason, 4972 long elapsedRealtimeMs, long uptimeMs) { 4973 uid = mapUid(uid); 4974 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 4975 .noteStopJobLocked(name, elapsedRealtimeMs, stopReason); 4976 if (!mActiveEvents.updateState(HistoryItem.EVENT_JOB_FINISH, name, uid, 0)) { 4977 return; 4978 } 4979 addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_JOB_FINISH, name, uid); 4980 } 4981 4982 @GuardedBy("this") noteJobsDeferredLocked(int uid, int numDeferred, long sinceLast)4983 public void noteJobsDeferredLocked(int uid, int numDeferred, long sinceLast) { 4984 noteJobsDeferredLocked(uid, numDeferred, sinceLast, 4985 mClock.elapsedRealtime(), mClock.uptimeMillis()); 4986 } 4987 4988 @GuardedBy("this") noteJobsDeferredLocked(int uid, int numDeferred, long sinceLast, long elapsedRealtimeMs, long uptimeMs)4989 public void noteJobsDeferredLocked(int uid, int numDeferred, long sinceLast, 4990 long elapsedRealtimeMs, long uptimeMs) { 4991 uid = mapUid(uid); 4992 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 4993 .noteJobsDeferredLocked(numDeferred, sinceLast); 4994 } 4995 4996 @GuardedBy("this") noteAlarmStartLocked(String name, WorkSource workSource, int uid)4997 public void noteAlarmStartLocked(String name, WorkSource workSource, int uid) { 4998 noteAlarmStartLocked(name, workSource, uid, 4999 mClock.elapsedRealtime(), mClock.uptimeMillis()); 5000 } 5001 5002 @GuardedBy("this") noteAlarmStartLocked(String name, WorkSource workSource, int uid, long elapsedRealtimeMs, long uptimeMs)5003 public void noteAlarmStartLocked(String name, WorkSource workSource, int uid, 5004 long elapsedRealtimeMs, long uptimeMs) { 5005 noteAlarmStartOrFinishLocked(HistoryItem.EVENT_ALARM_START, name, workSource, uid, 5006 elapsedRealtimeMs, uptimeMs); 5007 } 5008 5009 @GuardedBy("this") noteAlarmFinishLocked(String name, WorkSource workSource, int uid)5010 public void noteAlarmFinishLocked(String name, WorkSource workSource, int uid) { 5011 noteAlarmFinishLocked(name, workSource, uid, 5012 mClock.elapsedRealtime(), mClock.uptimeMillis()); 5013 } 5014 5015 @GuardedBy("this") noteAlarmFinishLocked(String name, WorkSource workSource, int uid, long elapsedRealtimeMs, long uptimeMs)5016 public void noteAlarmFinishLocked(String name, WorkSource workSource, int uid, 5017 long elapsedRealtimeMs, long uptimeMs) { 5018 noteAlarmStartOrFinishLocked(HistoryItem.EVENT_ALARM_FINISH, name, workSource, uid, 5019 elapsedRealtimeMs, uptimeMs); 5020 } 5021 5022 @GuardedBy("this") noteAlarmStartOrFinishLocked(int historyItem, String name, WorkSource workSource, int uid, long elapsedRealtimeMs, long uptimeMs)5023 private void noteAlarmStartOrFinishLocked(int historyItem, String name, WorkSource workSource, 5024 int uid, long elapsedRealtimeMs, long uptimeMs) { 5025 if (!mRecordAllHistory) { 5026 return; 5027 } 5028 5029 if (workSource != null) { 5030 for (int i = 0; i < workSource.size(); ++i) { 5031 uid = mapUid(workSource.getUid(i)); 5032 if (mActiveEvents.updateState(historyItem, name, uid, 0)) { 5033 addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, historyItem, name, uid); 5034 } 5035 } 5036 5037 List<WorkChain> workChains = workSource.getWorkChains(); 5038 if (workChains != null) { 5039 for (int i = 0; i < workChains.size(); ++i) { 5040 uid = mapUid(workChains.get(i).getAttributionUid()); 5041 if (mActiveEvents.updateState(historyItem, name, uid, 0)) { 5042 addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, historyItem, name, uid); 5043 } 5044 } 5045 } 5046 } else { 5047 uid = mapUid(uid); 5048 5049 if (mActiveEvents.updateState(historyItem, name, uid, 0)) { 5050 addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, historyItem, name, uid); 5051 } 5052 } 5053 } 5054 5055 @GuardedBy("this") noteWakupAlarmLocked(String packageName, int uid, WorkSource workSource, String tag)5056 public void noteWakupAlarmLocked(String packageName, int uid, WorkSource workSource, 5057 String tag) { 5058 noteWakupAlarmLocked(packageName, uid, workSource, tag, 5059 mClock.elapsedRealtime(), mClock.uptimeMillis()); 5060 } 5061 5062 @GuardedBy("this") noteWakupAlarmLocked(String packageName, int uid, WorkSource workSource, String tag, long elapsedRealtimeMs, long uptimeMs)5063 public void noteWakupAlarmLocked(String packageName, int uid, WorkSource workSource, 5064 String tag, long elapsedRealtimeMs, long uptimeMs) { 5065 if (workSource != null) { 5066 for (int i = 0; i < workSource.size(); ++i) { 5067 uid = workSource.getUid(i); 5068 final String workSourceName = workSource.getPackageName(i); 5069 5070 if (isOnBattery()) { 5071 BatteryStatsImpl.Uid.Pkg pkg = getPackageStatsLocked(uid, 5072 workSourceName != null ? workSourceName : packageName, 5073 elapsedRealtimeMs, uptimeMs); 5074 pkg.noteWakeupAlarmLocked(tag); 5075 } 5076 } 5077 5078 List<WorkChain> workChains = workSource.getWorkChains(); 5079 if (workChains != null) { 5080 for (int i = 0; i < workChains.size(); ++i) { 5081 final WorkChain wc = workChains.get(i); 5082 uid = wc.getAttributionUid(); 5083 5084 if (isOnBattery()) { 5085 BatteryStatsImpl.Uid.Pkg pkg = getPackageStatsLocked(uid, packageName, 5086 elapsedRealtimeMs, uptimeMs); 5087 pkg.noteWakeupAlarmLocked(tag); 5088 } 5089 } 5090 } 5091 } else { 5092 if (isOnBattery()) { 5093 BatteryStatsImpl.Uid.Pkg pkg = getPackageStatsLocked(uid, packageName, 5094 elapsedRealtimeMs, uptimeMs); 5095 pkg.noteWakeupAlarmLocked(tag); 5096 } 5097 } 5098 } 5099 requestWakelockCpuUpdate()5100 private void requestWakelockCpuUpdate() { 5101 mExternalSync.scheduleCpuSyncDueToWakelockChange(DELAY_UPDATE_WAKELOCKS); 5102 } 5103 requestImmediateCpuUpdate()5104 private void requestImmediateCpuUpdate() { 5105 mExternalSync.scheduleCpuSyncDueToWakelockChange(0 /* delayMillis */); 5106 } 5107 5108 @GuardedBy("this") setRecordAllHistoryLocked(boolean enabled)5109 public void setRecordAllHistoryLocked(boolean enabled) { 5110 mRecordAllHistory = enabled; 5111 if (!enabled) { 5112 // Clear out any existing state. 5113 mActiveEvents.removeEvents(HistoryItem.EVENT_WAKE_LOCK); 5114 mActiveEvents.removeEvents(HistoryItem.EVENT_ALARM); 5115 // Record the currently running processes as stopping, now that we are no 5116 // longer tracking them. 5117 HashMap<String, SparseIntArray> active = mActiveEvents.getStateForEvent( 5118 HistoryItem.EVENT_PROC); 5119 if (active != null) { 5120 long mSecRealtime = mClock.elapsedRealtime(); 5121 final long mSecUptime = mClock.uptimeMillis(); 5122 for (HashMap.Entry<String, SparseIntArray> ent : active.entrySet()) { 5123 SparseIntArray uids = ent.getValue(); 5124 for (int j=0; j<uids.size(); j++) { 5125 addHistoryEventLocked(mSecRealtime, mSecUptime, 5126 HistoryItem.EVENT_PROC_FINISH, ent.getKey(), uids.keyAt(j)); 5127 } 5128 } 5129 } 5130 } else { 5131 // Record the currently running processes as starting, now that we are tracking them. 5132 HashMap<String, SparseIntArray> active = mActiveEvents.getStateForEvent( 5133 HistoryItem.EVENT_PROC); 5134 if (active != null) { 5135 long mSecRealtime = mClock.elapsedRealtime(); 5136 final long mSecUptime = mClock.uptimeMillis(); 5137 for (HashMap.Entry<String, SparseIntArray> ent : active.entrySet()) { 5138 SparseIntArray uids = ent.getValue(); 5139 for (int j=0; j<uids.size(); j++) { 5140 addHistoryEventLocked(mSecRealtime, mSecUptime, 5141 HistoryItem.EVENT_PROC_START, ent.getKey(), uids.keyAt(j)); 5142 } 5143 } 5144 } 5145 } 5146 } 5147 setNoAutoReset(boolean enabled)5148 public void setNoAutoReset(boolean enabled) { 5149 mNoAutoReset = enabled; 5150 } 5151 5152 @GuardedBy("this") setPretendScreenOff(boolean pretendScreenOff)5153 public void setPretendScreenOff(boolean pretendScreenOff) { 5154 if (mPretendScreenOff != pretendScreenOff) { 5155 mPretendScreenOff = pretendScreenOff; 5156 final int primaryScreenState = mPerDisplayBatteryStats[0].screenState; 5157 noteScreenStateLocked(0, primaryScreenState, 5158 mClock.elapsedRealtime(), mClock.uptimeMillis(), 5159 mClock.currentTimeMillis()); 5160 } 5161 } 5162 5163 private String mInitialAcquireWakeName; 5164 private int mInitialAcquireWakeUid = -1; 5165 5166 @GuardedBy("this") noteStartWakeLocked(int uid, int pid, WorkChain wc, String name, String historyName, int type, boolean unimportantForLogging)5167 public void noteStartWakeLocked(int uid, int pid, WorkChain wc, String name, String historyName, 5168 int type, boolean unimportantForLogging) { 5169 noteStartWakeLocked(uid, pid, wc, name, historyName, type, unimportantForLogging, 5170 mClock.elapsedRealtime(), mClock.uptimeMillis()); 5171 } 5172 5173 @GuardedBy("this") noteStartWakeLocked(int uid, int pid, WorkChain wc, String name, String historyName, int type, boolean unimportantForLogging, long elapsedRealtimeMs, long uptimeMs)5174 public void noteStartWakeLocked(int uid, int pid, WorkChain wc, String name, String historyName, 5175 int type, boolean unimportantForLogging, long elapsedRealtimeMs, long uptimeMs) { 5176 final int mappedUid = mapUid(uid); 5177 if (type == WAKE_TYPE_PARTIAL) { 5178 // Only care about partial wake locks, since full wake locks 5179 // will be canceled when the user puts the screen to sleep. 5180 aggregateLastWakeupUptimeLocked(elapsedRealtimeMs, uptimeMs); 5181 if (historyName == null) { 5182 historyName = name; 5183 } 5184 if (mRecordAllHistory) { 5185 if (mActiveEvents.updateState(HistoryItem.EVENT_WAKE_LOCK_START, historyName, 5186 mappedUid, 0)) { 5187 addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, 5188 HistoryItem.EVENT_WAKE_LOCK_START, historyName, mappedUid); 5189 } 5190 } 5191 if (mWakeLockNesting == 0) { 5192 mHistoryCur.states |= HistoryItem.STATE_WAKE_LOCK_FLAG; 5193 if (DEBUG_HISTORY) Slog.v(TAG, "Start wake lock to: " 5194 + Integer.toHexString(mHistoryCur.states)); 5195 mHistoryCur.wakelockTag = mHistoryCur.localWakelockTag; 5196 mHistoryCur.wakelockTag.string = mInitialAcquireWakeName = historyName; 5197 mHistoryCur.wakelockTag.uid = mInitialAcquireWakeUid = mappedUid; 5198 mWakeLockImportant = !unimportantForLogging; 5199 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 5200 } else if (!mWakeLockImportant && !unimportantForLogging 5201 && mHistoryLastWritten.cmd == HistoryItem.CMD_UPDATE) { 5202 if (mHistoryLastWritten.wakelockTag != null) { 5203 // We'll try to update the last tag. 5204 mHistoryLastWritten.wakelockTag = null; 5205 mHistoryCur.wakelockTag = mHistoryCur.localWakelockTag; 5206 mHistoryCur.wakelockTag.string = mInitialAcquireWakeName = historyName; 5207 mHistoryCur.wakelockTag.uid = mInitialAcquireWakeUid = mappedUid; 5208 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 5209 } 5210 mWakeLockImportant = true; 5211 } 5212 mWakeLockNesting++; 5213 } 5214 if (mappedUid >= 0) { 5215 if (mappedUid != uid) { 5216 // Prevent the isolated uid mapping from being removed while the wakelock is 5217 // being held. 5218 incrementIsolatedUidRefCount(uid); 5219 } 5220 if (mOnBatteryScreenOffTimeBase.isRunning()) { 5221 // We only update the cpu time when a wake lock is acquired if the screen is off. 5222 // If the screen is on, we don't distribute the power amongst partial wakelocks. 5223 if (DEBUG_ENERGY_CPU) { 5224 Slog.d(TAG, "Updating cpu time because of +wake_lock"); 5225 } 5226 requestWakelockCpuUpdate(); 5227 } 5228 5229 getUidStatsLocked(mappedUid, elapsedRealtimeMs, uptimeMs) 5230 .noteStartWakeLocked(pid, name, type, elapsedRealtimeMs); 5231 5232 if (wc != null) { 5233 FrameworkStatsLog.write(FrameworkStatsLog.WAKELOCK_STATE_CHANGED, wc.getUids(), 5234 wc.getTags(), getPowerManagerWakeLockLevel(type), name, 5235 FrameworkStatsLog.WAKELOCK_STATE_CHANGED__STATE__ACQUIRE); 5236 } else { 5237 FrameworkStatsLog.write_non_chained(FrameworkStatsLog.WAKELOCK_STATE_CHANGED, 5238 mapIsolatedUid(uid), null, getPowerManagerWakeLockLevel(type), name, 5239 FrameworkStatsLog.WAKELOCK_STATE_CHANGED__STATE__ACQUIRE); 5240 } 5241 } 5242 } 5243 5244 @GuardedBy("this") noteStopWakeLocked(int uid, int pid, WorkChain wc, String name, String historyName, int type)5245 public void noteStopWakeLocked(int uid, int pid, WorkChain wc, String name, String historyName, 5246 int type) { 5247 noteStopWakeLocked(uid, pid, wc, name, historyName, type, 5248 mClock.elapsedRealtime(), mClock.uptimeMillis()); 5249 } 5250 5251 @GuardedBy("this") noteStopWakeLocked(int uid, int pid, WorkChain wc, String name, String historyName, int type, long elapsedRealtimeMs, long uptimeMs)5252 public void noteStopWakeLocked(int uid, int pid, WorkChain wc, String name, String historyName, 5253 int type, long elapsedRealtimeMs, long uptimeMs) { 5254 final int mappedUid = mapUid(uid); 5255 if (type == WAKE_TYPE_PARTIAL) { 5256 mWakeLockNesting--; 5257 if (mRecordAllHistory) { 5258 if (historyName == null) { 5259 historyName = name; 5260 } 5261 if (mActiveEvents.updateState(HistoryItem.EVENT_WAKE_LOCK_FINISH, historyName, 5262 mappedUid, 0)) { 5263 addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, 5264 HistoryItem.EVENT_WAKE_LOCK_FINISH, historyName, mappedUid); 5265 } 5266 } 5267 if (mWakeLockNesting == 0) { 5268 mHistoryCur.states &= ~HistoryItem.STATE_WAKE_LOCK_FLAG; 5269 if (DEBUG_HISTORY) Slog.v(TAG, "Stop wake lock to: " 5270 + Integer.toHexString(mHistoryCur.states)); 5271 mInitialAcquireWakeName = null; 5272 mInitialAcquireWakeUid = -1; 5273 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 5274 } 5275 } 5276 if (mappedUid >= 0) { 5277 if (mOnBatteryScreenOffTimeBase.isRunning()) { 5278 if (DEBUG_ENERGY_CPU) { 5279 Slog.d(TAG, "Updating cpu time because of -wake_lock"); 5280 } 5281 requestWakelockCpuUpdate(); 5282 } 5283 5284 getUidStatsLocked(mappedUid, elapsedRealtimeMs, uptimeMs) 5285 .noteStopWakeLocked(pid, name, type, elapsedRealtimeMs); 5286 if (wc != null) { 5287 FrameworkStatsLog.write(FrameworkStatsLog.WAKELOCK_STATE_CHANGED, wc.getUids(), 5288 wc.getTags(), getPowerManagerWakeLockLevel(type), name, 5289 FrameworkStatsLog.WAKELOCK_STATE_CHANGED__STATE__RELEASE); 5290 } else { 5291 FrameworkStatsLog.write_non_chained(FrameworkStatsLog.WAKELOCK_STATE_CHANGED, 5292 mapIsolatedUid(uid), null, getPowerManagerWakeLockLevel(type), name, 5293 FrameworkStatsLog.WAKELOCK_STATE_CHANGED__STATE__RELEASE); 5294 } 5295 5296 if (mappedUid != uid) { 5297 // Decrement the ref count for the isolated uid and delete the mapping if uneeded. 5298 maybeRemoveIsolatedUidLocked(uid, elapsedRealtimeMs, uptimeMs); 5299 } 5300 } 5301 } 5302 5303 /** 5304 * Converts BatteryStats wakelock types back into PowerManager wakelock levels. 5305 * This is the inverse map of Notifier.getBatteryStatsWakeLockMonitorType(). 5306 * These are estimations, since batterystats loses some of the original data. 5307 * TODO: Delete this. Instead, FrameworkStatsLog.write should be called from 5308 * PowerManager's Notifier. 5309 */ getPowerManagerWakeLockLevel(int battertStatsWakelockType)5310 private int getPowerManagerWakeLockLevel(int battertStatsWakelockType) { 5311 switch (battertStatsWakelockType) { 5312 // PowerManager.PARTIAL_WAKE_LOCK or PROXIMITY_SCREEN_OFF_WAKE_LOCK 5313 case BatteryStats.WAKE_TYPE_PARTIAL: 5314 return PowerManager.PARTIAL_WAKE_LOCK; 5315 5316 // PowerManager.SCREEN_DIM_WAKE_LOCK or SCREEN_BRIGHT_WAKE_LOCK 5317 case BatteryStats.WAKE_TYPE_FULL: 5318 return PowerManager.FULL_WAKE_LOCK; 5319 5320 case BatteryStats.WAKE_TYPE_DRAW: 5321 return PowerManager.DRAW_WAKE_LOCK; 5322 5323 // It appears that nothing can ever make a Window and PowerManager lacks an equivalent. 5324 case BatteryStats.WAKE_TYPE_WINDOW: 5325 Slog.e(TAG, "Illegal window wakelock type observed in batterystats."); 5326 return -1; 5327 5328 default: 5329 Slog.e(TAG, "Illegal wakelock type in batterystats: " + battertStatsWakelockType); 5330 return -1; 5331 } 5332 } 5333 5334 @GuardedBy("this") noteStartWakeFromSourceLocked(WorkSource ws, int pid, String name, String historyName, int type, boolean unimportantForLogging)5335 public void noteStartWakeFromSourceLocked(WorkSource ws, int pid, String name, 5336 String historyName, int type, boolean unimportantForLogging) { 5337 noteStartWakeFromSourceLocked(ws, pid, name, historyName, type, unimportantForLogging, 5338 mClock.elapsedRealtime(), mClock.uptimeMillis()); 5339 } 5340 5341 @GuardedBy("this") noteStartWakeFromSourceLocked(WorkSource ws, int pid, String name, String historyName, int type, boolean unimportantForLogging, long elapsedRealtimeMs, long uptimeMs)5342 public void noteStartWakeFromSourceLocked(WorkSource ws, int pid, String name, 5343 String historyName, int type, boolean unimportantForLogging, 5344 long elapsedRealtimeMs, long uptimeMs) { 5345 final int N = ws.size(); 5346 for (int i=0; i<N; i++) { 5347 noteStartWakeLocked(ws.getUid(i), pid, null, name, historyName, type, 5348 unimportantForLogging, elapsedRealtimeMs, uptimeMs); 5349 } 5350 5351 List<WorkChain> wcs = ws.getWorkChains(); 5352 if (wcs != null) { 5353 for (int i = 0; i < wcs.size(); ++i) { 5354 final WorkChain wc = wcs.get(i); 5355 noteStartWakeLocked(wc.getAttributionUid(), pid, wc, name, historyName, type, 5356 unimportantForLogging, elapsedRealtimeMs, uptimeMs); 5357 } 5358 } 5359 } 5360 5361 @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)5362 public void noteChangeWakelockFromSourceLocked(WorkSource ws, int pid, String name, 5363 String historyName, int type, WorkSource newWs, int newPid, String newName, 5364 String newHistoryName, int newType, boolean newUnimportantForLogging) { 5365 noteChangeWakelockFromSourceLocked(ws, pid, name, historyName, type, newWs, newPid, 5366 newName, newHistoryName, newType, newUnimportantForLogging, 5367 mClock.elapsedRealtime(), mClock.uptimeMillis()); 5368 } 5369 5370 @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)5371 public void noteChangeWakelockFromSourceLocked(WorkSource ws, int pid, String name, 5372 String historyName, int type, WorkSource newWs, int newPid, String newName, 5373 String newHistoryName, int newType, boolean newUnimportantForLogging, 5374 long elapsedRealtimeMs, long uptimeMs) { 5375 List<WorkChain>[] wcs = WorkSource.diffChains(ws, newWs); 5376 5377 // For correct semantics, we start the need worksources first, so that we won't 5378 // make inappropriate history items as if all wake locks went away and new ones 5379 // appeared. This is okay because tracking of wake locks allows nesting. 5380 // 5381 // First the starts : 5382 final int NN = newWs.size(); 5383 for (int i=0; i<NN; i++) { 5384 noteStartWakeLocked(newWs.getUid(i), newPid, null, newName, newHistoryName, newType, 5385 newUnimportantForLogging, elapsedRealtimeMs, uptimeMs); 5386 } 5387 if (wcs != null) { 5388 List<WorkChain> newChains = wcs[0]; 5389 if (newChains != null) { 5390 for (int i = 0; i < newChains.size(); ++i) { 5391 final WorkChain newChain = newChains.get(i); 5392 noteStartWakeLocked(newChain.getAttributionUid(), newPid, newChain, newName, 5393 newHistoryName, newType, newUnimportantForLogging, elapsedRealtimeMs, 5394 uptimeMs); 5395 } 5396 } 5397 } 5398 5399 // Then the stops : 5400 final int NO = ws.size(); 5401 for (int i=0; i<NO; i++) { 5402 noteStopWakeLocked(ws.getUid(i), pid, null, name, historyName, type, elapsedRealtimeMs, 5403 uptimeMs); 5404 } 5405 if (wcs != null) { 5406 List<WorkChain> goneChains = wcs[1]; 5407 if (goneChains != null) { 5408 for (int i = 0; i < goneChains.size(); ++i) { 5409 final WorkChain goneChain = goneChains.get(i); 5410 noteStopWakeLocked(goneChain.getAttributionUid(), pid, goneChain, name, 5411 historyName, type, elapsedRealtimeMs, uptimeMs); 5412 } 5413 } 5414 } 5415 } 5416 5417 @GuardedBy("this") noteStopWakeFromSourceLocked(WorkSource ws, int pid, String name, String historyName, int type)5418 public void noteStopWakeFromSourceLocked(WorkSource ws, int pid, String name, 5419 String historyName, int type) { 5420 noteStopWakeFromSourceLocked(ws, pid, name, historyName, type, 5421 mClock.elapsedRealtime(), mClock.uptimeMillis()); 5422 } 5423 5424 @GuardedBy("this") noteStopWakeFromSourceLocked(WorkSource ws, int pid, String name, String historyName, int type, long elapsedRealtimeMs, long uptimeMs)5425 public void noteStopWakeFromSourceLocked(WorkSource ws, int pid, String name, 5426 String historyName, int type, long elapsedRealtimeMs, long uptimeMs) { 5427 final int N = ws.size(); 5428 for (int i=0; i<N; i++) { 5429 noteStopWakeLocked(ws.getUid(i), pid, null, name, historyName, type, elapsedRealtimeMs, 5430 uptimeMs); 5431 } 5432 5433 List<WorkChain> wcs = ws.getWorkChains(); 5434 if (wcs != null) { 5435 for (int i = 0; i < wcs.size(); ++i) { 5436 final WorkChain wc = wcs.get(i); 5437 noteStopWakeLocked(wc.getAttributionUid(), pid, wc, name, historyName, type, 5438 elapsedRealtimeMs, uptimeMs); 5439 } 5440 } 5441 } 5442 5443 @GuardedBy("this") noteLongPartialWakelockStart(String name, String historyName, int uid)5444 public void noteLongPartialWakelockStart(String name, String historyName, int uid) { 5445 noteLongPartialWakelockStart(name, historyName, uid, 5446 mClock.elapsedRealtime(), mClock.uptimeMillis()); 5447 } 5448 5449 @GuardedBy("this") noteLongPartialWakelockStart(String name, String historyName, int uid, long elapsedRealtimeMs, long uptimeMs)5450 public void noteLongPartialWakelockStart(String name, String historyName, int uid, 5451 long elapsedRealtimeMs, long uptimeMs) { 5452 noteLongPartialWakeLockStartInternal(name, historyName, uid, elapsedRealtimeMs, uptimeMs); 5453 } 5454 5455 @GuardedBy("this") noteLongPartialWakelockStartFromSource(String name, String historyName, WorkSource workSource)5456 public void noteLongPartialWakelockStartFromSource(String name, String historyName, 5457 WorkSource workSource) { 5458 noteLongPartialWakelockStartFromSource(name, historyName, workSource, 5459 mClock.elapsedRealtime(), mClock.uptimeMillis()); 5460 } 5461 5462 @GuardedBy("this") noteLongPartialWakelockStartFromSource(String name, String historyName, WorkSource workSource, long elapsedRealtimeMs, long uptimeMs)5463 public void noteLongPartialWakelockStartFromSource(String name, String historyName, 5464 WorkSource workSource, long elapsedRealtimeMs, long uptimeMs) { 5465 final int N = workSource.size(); 5466 for (int i = 0; i < N; ++i) { 5467 final int uid = mapUid(workSource.getUid(i)); 5468 noteLongPartialWakeLockStartInternal(name, historyName, uid, 5469 elapsedRealtimeMs, uptimeMs); 5470 } 5471 5472 final List<WorkChain> workChains = workSource.getWorkChains(); 5473 if (workChains != null) { 5474 for (int i = 0; i < workChains.size(); ++i) { 5475 final WorkChain workChain = workChains.get(i); 5476 final int uid = workChain.getAttributionUid(); 5477 noteLongPartialWakeLockStartInternal(name, historyName, uid, 5478 elapsedRealtimeMs, uptimeMs); 5479 } 5480 } 5481 } 5482 5483 @GuardedBy("this") noteLongPartialWakeLockStartInternal(String name, String historyName, int uid, long elapsedRealtimeMs, long uptimeMs)5484 private void noteLongPartialWakeLockStartInternal(String name, String historyName, int uid, 5485 long elapsedRealtimeMs, long uptimeMs) { 5486 final int mappedUid = mapUid(uid); 5487 if (historyName == null) { 5488 historyName = name; 5489 } 5490 if (!mActiveEvents.updateState(HistoryItem.EVENT_LONG_WAKE_LOCK_START, historyName, 5491 mappedUid, 0)) { 5492 return; 5493 } 5494 addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_LONG_WAKE_LOCK_START, 5495 historyName, mappedUid); 5496 if (mappedUid != uid) { 5497 // Prevent the isolated uid mapping from being removed while the wakelock is 5498 // being held. 5499 incrementIsolatedUidRefCount(uid); 5500 } 5501 } 5502 5503 @GuardedBy("this") noteLongPartialWakelockFinish(String name, String historyName, int uid)5504 public void noteLongPartialWakelockFinish(String name, String historyName, int uid) { 5505 noteLongPartialWakelockFinish(name, historyName, uid, 5506 mClock.elapsedRealtime(), mClock.uptimeMillis()); 5507 } 5508 5509 @GuardedBy("this") noteLongPartialWakelockFinish(String name, String historyName, int uid, long elapsedRealtimeMs, long uptimeMs)5510 public void noteLongPartialWakelockFinish(String name, String historyName, int uid, 5511 long elapsedRealtimeMs, long uptimeMs) { 5512 noteLongPartialWakeLockFinishInternal(name, historyName, uid, elapsedRealtimeMs, uptimeMs); 5513 } 5514 5515 @GuardedBy("this") noteLongPartialWakelockFinishFromSource(String name, String historyName, WorkSource workSource)5516 public void noteLongPartialWakelockFinishFromSource(String name, String historyName, 5517 WorkSource workSource) { 5518 noteLongPartialWakelockFinishFromSource(name, historyName, workSource, 5519 mClock.elapsedRealtime(), mClock.uptimeMillis()); 5520 } 5521 5522 @GuardedBy("this") noteLongPartialWakelockFinishFromSource(String name, String historyName, WorkSource workSource, long elapsedRealtimeMs, long uptimeMs)5523 public void noteLongPartialWakelockFinishFromSource(String name, String historyName, 5524 WorkSource workSource, long elapsedRealtimeMs, long uptimeMs) { 5525 final int N = workSource.size(); 5526 for (int i = 0; i < N; ++i) { 5527 final int uid = mapUid(workSource.getUid(i)); 5528 noteLongPartialWakeLockFinishInternal(name, historyName, uid, 5529 elapsedRealtimeMs, uptimeMs); 5530 } 5531 5532 final List<WorkChain> workChains = workSource.getWorkChains(); 5533 if (workChains != null) { 5534 for (int i = 0; i < workChains.size(); ++i) { 5535 final WorkChain workChain = workChains.get(i); 5536 final int uid = workChain.getAttributionUid(); 5537 noteLongPartialWakeLockFinishInternal(name, historyName, uid, 5538 elapsedRealtimeMs, uptimeMs); 5539 } 5540 } 5541 } 5542 5543 @GuardedBy("this") noteLongPartialWakeLockFinishInternal(String name, String historyName, int uid, long elapsedRealtimeMs, long uptimeMs)5544 private void noteLongPartialWakeLockFinishInternal(String name, String historyName, int uid, 5545 long elapsedRealtimeMs, long uptimeMs) { 5546 final int mappedUid = mapUid(uid); 5547 if (historyName == null) { 5548 historyName = name; 5549 } 5550 if (!mActiveEvents.updateState(HistoryItem.EVENT_LONG_WAKE_LOCK_FINISH, historyName, 5551 mappedUid, 0)) { 5552 return; 5553 } 5554 addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_LONG_WAKE_LOCK_FINISH, 5555 historyName, mappedUid); 5556 if (mappedUid != uid) { 5557 // Decrement the ref count for the isolated uid and delete the mapping if uneeded. 5558 maybeRemoveIsolatedUidLocked(uid, elapsedRealtimeMs, uptimeMs); 5559 } 5560 } 5561 5562 @GuardedBy("this") aggregateLastWakeupUptimeLocked(long elapsedRealtimeMs, long uptimeMs)5563 void aggregateLastWakeupUptimeLocked(long elapsedRealtimeMs, long uptimeMs) { 5564 if (mLastWakeupReason != null) { 5565 long deltaUptimeMs = uptimeMs - mLastWakeupUptimeMs; 5566 SamplingTimer timer = getWakeupReasonTimerLocked(mLastWakeupReason); 5567 timer.add(deltaUptimeMs * 1000, 1, elapsedRealtimeMs); // time in in microseconds 5568 FrameworkStatsLog.write(FrameworkStatsLog.KERNEL_WAKEUP_REPORTED, mLastWakeupReason, 5569 /* duration_usec */ deltaUptimeMs * 1000); 5570 mLastWakeupReason = null; 5571 } 5572 } 5573 5574 @GuardedBy("this") noteWakeupReasonLocked(String reason)5575 public void noteWakeupReasonLocked(String reason) { 5576 noteWakeupReasonLocked(reason, mClock.elapsedRealtime(), mClock.uptimeMillis()); 5577 } 5578 5579 @GuardedBy("this") noteWakeupReasonLocked(String reason, long elapsedRealtimeMs, long uptimeMs)5580 public void noteWakeupReasonLocked(String reason, long elapsedRealtimeMs, long uptimeMs) { 5581 if (DEBUG_HISTORY) Slog.v(TAG, "Wakeup reason \"" + reason +"\": " 5582 + Integer.toHexString(mHistoryCur.states)); 5583 aggregateLastWakeupUptimeLocked(elapsedRealtimeMs, uptimeMs); 5584 mHistoryCur.wakeReasonTag = mHistoryCur.localWakeReasonTag; 5585 mHistoryCur.wakeReasonTag.string = reason; 5586 mHistoryCur.wakeReasonTag.uid = 0; 5587 mLastWakeupReason = reason; 5588 mLastWakeupUptimeMs = uptimeMs; 5589 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 5590 } 5591 5592 @GuardedBy("this") startAddingCpuLocked()5593 public boolean startAddingCpuLocked() { 5594 mExternalSync.cancelCpuSyncDueToWakelockChange(); 5595 return mOnBatteryInternal; 5596 } 5597 5598 @GuardedBy("this") finishAddingCpuLocked(int totalUTimeMs, int totalSTimeMs, int statUserTimeMs, int statSystemTimeMs, int statIOWaitTimeMs, int statIrqTimeMs, int statSoftIrqTimeMs, int statIdleTimeMs)5599 public void finishAddingCpuLocked(int totalUTimeMs, int totalSTimeMs, int statUserTimeMs, 5600 int statSystemTimeMs, int statIOWaitTimeMs, int statIrqTimeMs, 5601 int statSoftIrqTimeMs, int statIdleTimeMs) { 5602 if (DEBUG) { 5603 Slog.d(TAG, "Adding cpu: tuser=" + totalUTimeMs + " tsys=" + totalSTimeMs 5604 + " user=" + statUserTimeMs + " sys=" + statSystemTimeMs 5605 + " io=" + statIOWaitTimeMs + " irq=" + statIrqTimeMs 5606 + " sirq=" + statSoftIrqTimeMs + " idle=" + statIdleTimeMs); 5607 } 5608 mCurStepCpuUserTimeMs += totalUTimeMs; 5609 mCurStepCpuSystemTimeMs += totalSTimeMs; 5610 mCurStepStatUserTimeMs += statUserTimeMs; 5611 mCurStepStatSystemTimeMs += statSystemTimeMs; 5612 mCurStepStatIOWaitTimeMs += statIOWaitTimeMs; 5613 mCurStepStatIrqTimeMs += statIrqTimeMs; 5614 mCurStepStatSoftIrqTimeMs += statSoftIrqTimeMs; 5615 mCurStepStatIdleTimeMs += statIdleTimeMs; 5616 } 5617 noteProcessDiedLocked(int uid, int pid)5618 public void noteProcessDiedLocked(int uid, int pid) { 5619 uid = mapUid(uid); 5620 Uid u = mUidStats.get(uid); 5621 if (u != null) { 5622 u.mPids.remove(pid); 5623 } 5624 } 5625 getProcessWakeTime(int uid, int pid, long realtimeMs)5626 public long getProcessWakeTime(int uid, int pid, long realtimeMs) { 5627 uid = mapUid(uid); 5628 Uid u = mUidStats.get(uid); 5629 if (u != null) { 5630 Uid.Pid p = u.mPids.get(pid); 5631 if (p != null) { 5632 return p.mWakeSumMs + (p.mWakeNesting > 0 ? (realtimeMs - p.mWakeStartMs) : 0); 5633 } 5634 } 5635 return 0; 5636 } 5637 reportExcessiveCpuLocked(int uid, String proc, long overTimeMs, long usedTimeMs)5638 public void reportExcessiveCpuLocked(int uid, String proc, long overTimeMs, long usedTimeMs) { 5639 uid = mapUid(uid); 5640 Uid u = mUidStats.get(uid); 5641 if (u != null) { 5642 u.reportExcessiveCpuLocked(proc, overTimeMs, usedTimeMs); 5643 } 5644 } 5645 5646 int mSensorNesting; 5647 5648 @GuardedBy("this") noteStartSensorLocked(int uid, int sensor)5649 public void noteStartSensorLocked(int uid, int sensor) { 5650 noteStartSensorLocked(uid, sensor, mClock.elapsedRealtime(), mClock.uptimeMillis()); 5651 } 5652 5653 @GuardedBy("this") noteStartSensorLocked(int uid, int sensor, long elapsedRealtimeMs, long uptimeMs)5654 public void noteStartSensorLocked(int uid, int sensor, long elapsedRealtimeMs, long uptimeMs) { 5655 uid = mapUid(uid); 5656 if (mSensorNesting == 0) { 5657 mHistoryCur.states |= HistoryItem.STATE_SENSOR_ON_FLAG; 5658 if (DEBUG_HISTORY) Slog.v(TAG, "Start sensor to: " 5659 + Integer.toHexString(mHistoryCur.states)); 5660 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 5661 } 5662 mSensorNesting++; 5663 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 5664 .noteStartSensor(sensor, elapsedRealtimeMs); 5665 } 5666 5667 @GuardedBy("this") noteStopSensorLocked(int uid, int sensor)5668 public void noteStopSensorLocked(int uid, int sensor) { 5669 noteStopSensorLocked(uid, sensor, mClock.elapsedRealtime(), mClock.uptimeMillis()); 5670 } 5671 5672 @GuardedBy("this") noteStopSensorLocked(int uid, int sensor, long elapsedRealtimeMs, long uptimeMs)5673 public void noteStopSensorLocked(int uid, int sensor, long elapsedRealtimeMs, long uptimeMs) { 5674 uid = mapUid(uid); 5675 mSensorNesting--; 5676 if (mSensorNesting == 0) { 5677 mHistoryCur.states &= ~HistoryItem.STATE_SENSOR_ON_FLAG; 5678 if (DEBUG_HISTORY) Slog.v(TAG, "Stop sensor to: " 5679 + Integer.toHexString(mHistoryCur.states)); 5680 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 5681 } 5682 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 5683 .noteStopSensor(sensor, elapsedRealtimeMs); 5684 } 5685 5686 int mGpsNesting; 5687 5688 @GuardedBy("this") noteGpsChangedLocked(WorkSource oldWs, WorkSource newWs)5689 public void noteGpsChangedLocked(WorkSource oldWs, WorkSource newWs) { 5690 noteGpsChangedLocked(oldWs, newWs, mClock.elapsedRealtime(), mClock.uptimeMillis()); 5691 } 5692 5693 @GuardedBy("this") noteGpsChangedLocked(WorkSource oldWs, WorkSource newWs, long elapsedRealtimeMs, long uptimeMs)5694 public void noteGpsChangedLocked(WorkSource oldWs, WorkSource newWs, 5695 long elapsedRealtimeMs, long uptimeMs) { 5696 for (int i = 0; i < newWs.size(); ++i) { 5697 noteStartGpsLocked(newWs.getUid(i), null, elapsedRealtimeMs, uptimeMs); 5698 } 5699 5700 for (int i = 0; i < oldWs.size(); ++i) { 5701 noteStopGpsLocked((oldWs.getUid(i)), null, elapsedRealtimeMs, uptimeMs); 5702 } 5703 5704 List<WorkChain>[] wcs = WorkSource.diffChains(oldWs, newWs); 5705 if (wcs != null) { 5706 if (wcs[0] != null) { 5707 final List<WorkChain> newChains = wcs[0]; 5708 for (int i = 0; i < newChains.size(); ++i) { 5709 noteStartGpsLocked(-1, newChains.get(i), elapsedRealtimeMs, uptimeMs); 5710 } 5711 } 5712 5713 if (wcs[1] != null) { 5714 final List<WorkChain> goneChains = wcs[1]; 5715 for (int i = 0; i < goneChains.size(); ++i) { 5716 noteStopGpsLocked(-1, goneChains.get(i), elapsedRealtimeMs, uptimeMs); 5717 } 5718 } 5719 } 5720 } 5721 5722 @GuardedBy("this") noteStartGpsLocked(int uid, WorkChain workChain, long elapsedRealtimeMs, long uptimeMs)5723 private void noteStartGpsLocked(int uid, WorkChain workChain, 5724 long elapsedRealtimeMs, long uptimeMs) { 5725 if (workChain != null) { 5726 uid = workChain.getAttributionUid(); 5727 } 5728 final int mappedUid = mapUid(uid); 5729 if (mGpsNesting == 0) { 5730 mHistoryCur.states |= HistoryItem.STATE_GPS_ON_FLAG; 5731 if (DEBUG_HISTORY) Slog.v(TAG, "Start GPS to: " 5732 + Integer.toHexString(mHistoryCur.states)); 5733 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 5734 } 5735 mGpsNesting++; 5736 5737 if (workChain == null) { 5738 FrameworkStatsLog.write_non_chained(FrameworkStatsLog.GPS_SCAN_STATE_CHANGED, 5739 mapIsolatedUid(uid), null, FrameworkStatsLog.GPS_SCAN_STATE_CHANGED__STATE__ON); 5740 } else { 5741 FrameworkStatsLog.write(FrameworkStatsLog.GPS_SCAN_STATE_CHANGED, 5742 workChain.getUids(), workChain.getTags(), 5743 FrameworkStatsLog.GPS_SCAN_STATE_CHANGED__STATE__ON); 5744 } 5745 5746 getUidStatsLocked(mappedUid, elapsedRealtimeMs, uptimeMs).noteStartGps(elapsedRealtimeMs); 5747 } 5748 5749 @GuardedBy("this") noteStopGpsLocked(int uid, WorkChain workChain, long elapsedRealtimeMs, long uptimeMs)5750 private void noteStopGpsLocked(int uid, WorkChain workChain, 5751 long elapsedRealtimeMs, long uptimeMs) { 5752 if (workChain != null) { 5753 uid = workChain.getAttributionUid(); 5754 } 5755 final int mappedUid = mapUid(uid); 5756 mGpsNesting--; 5757 if (mGpsNesting == 0) { 5758 mHistoryCur.states &= ~HistoryItem.STATE_GPS_ON_FLAG; 5759 if (DEBUG_HISTORY) Slog.v(TAG, "Stop GPS to: " 5760 + Integer.toHexString(mHistoryCur.states)); 5761 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 5762 stopAllGpsSignalQualityTimersLocked(-1, elapsedRealtimeMs); 5763 mGpsSignalQualityBin = -1; 5764 } 5765 5766 if (workChain == null) { 5767 FrameworkStatsLog.write_non_chained(FrameworkStatsLog.GPS_SCAN_STATE_CHANGED, 5768 mapIsolatedUid(uid), null, 5769 FrameworkStatsLog.GPS_SCAN_STATE_CHANGED__STATE__OFF); 5770 } else { 5771 FrameworkStatsLog.write(FrameworkStatsLog.GPS_SCAN_STATE_CHANGED, workChain.getUids(), 5772 workChain.getTags(), FrameworkStatsLog.GPS_SCAN_STATE_CHANGED__STATE__OFF); 5773 } 5774 5775 getUidStatsLocked(mappedUid, elapsedRealtimeMs, uptimeMs).noteStopGps(elapsedRealtimeMs); 5776 } 5777 5778 @GuardedBy("this") noteGpsSignalQualityLocked(int signalLevel)5779 public void noteGpsSignalQualityLocked(int signalLevel) { 5780 noteGpsSignalQualityLocked(signalLevel, mClock.elapsedRealtime(), mClock.uptimeMillis()); 5781 } 5782 5783 @GuardedBy("this") noteGpsSignalQualityLocked(int signalLevel, long elapsedRealtimeMs, long uptimeMs)5784 public void noteGpsSignalQualityLocked(int signalLevel, long elapsedRealtimeMs, long uptimeMs) { 5785 if (mGpsNesting == 0) { 5786 return; 5787 } 5788 if (signalLevel < 0 || signalLevel >= mGpsSignalQualityTimer.length) { 5789 stopAllGpsSignalQualityTimersLocked(-1, elapsedRealtimeMs); 5790 return; 5791 } 5792 if (mGpsSignalQualityBin != signalLevel) { 5793 if (mGpsSignalQualityBin >= 0) { 5794 mGpsSignalQualityTimer[mGpsSignalQualityBin].stopRunningLocked(elapsedRealtimeMs); 5795 } 5796 if(!mGpsSignalQualityTimer[signalLevel].isRunningLocked()) { 5797 mGpsSignalQualityTimer[signalLevel].startRunningLocked(elapsedRealtimeMs); 5798 } 5799 mHistoryCur.states2 = (mHistoryCur.states2&~HistoryItem.STATE2_GPS_SIGNAL_QUALITY_MASK) 5800 | (signalLevel << HistoryItem.STATE2_GPS_SIGNAL_QUALITY_SHIFT); 5801 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 5802 mGpsSignalQualityBin = signalLevel; 5803 } 5804 return; 5805 } 5806 5807 @GuardedBy("this") noteScreenStateLocked(int display, int state)5808 public void noteScreenStateLocked(int display, int state) { 5809 noteScreenStateLocked(display, state, mClock.elapsedRealtime(), mClock.uptimeMillis(), 5810 mClock.currentTimeMillis()); 5811 } 5812 5813 @GuardedBy("this") noteScreenStateLocked(int display, int displayState, long elapsedRealtimeMs, long uptimeMs, long currentTimeMs)5814 public void noteScreenStateLocked(int display, int displayState, 5815 long elapsedRealtimeMs, long uptimeMs, long currentTimeMs) { 5816 // Battery stats relies on there being 4 states. To accommodate this, new states beyond the 5817 // original 4 are mapped to one of the originals. 5818 if (displayState > MAX_TRACKED_SCREEN_STATE) { 5819 if (Display.isOnState(displayState)) { 5820 displayState = Display.STATE_ON; 5821 } else if (Display.isDozeState(displayState)) { 5822 if (Display.isSuspendedState(displayState)) { 5823 displayState = Display.STATE_DOZE_SUSPEND; 5824 } else { 5825 displayState = Display.STATE_DOZE; 5826 } 5827 } else if (Display.isOffState(displayState)) { 5828 displayState = Display.STATE_OFF; 5829 } else { 5830 Slog.wtf(TAG, "Unknown screen state (not mapped): " + displayState); 5831 displayState = Display.STATE_UNKNOWN; 5832 } 5833 } 5834 // As of this point, displayState should be mapped to one of: 5835 // - Display.STATE_ON, 5836 // - Display.STATE_DOZE 5837 // - Display.STATE_DOZE_SUSPEND 5838 // - Display.STATE_OFF 5839 // - Display.STATE_UNKNOWN 5840 5841 int state; 5842 int overallBin = mScreenBrightnessBin; 5843 int externalUpdateFlag = 0; 5844 boolean shouldScheduleSync = false; 5845 final int numDisplay = mPerDisplayBatteryStats.length; 5846 if (display < 0 || display >= numDisplay) { 5847 Slog.wtf(TAG, "Unexpected note screen state for display " + display + " (only " 5848 + mPerDisplayBatteryStats.length + " displays exist...)"); 5849 return; 5850 } 5851 final DisplayBatteryStats displayStats = mPerDisplayBatteryStats[display]; 5852 final int oldDisplayState = displayStats.screenState; 5853 5854 if (oldDisplayState == displayState) { 5855 // Nothing changed 5856 state = mScreenState; 5857 } else { 5858 displayStats.screenState = displayState; 5859 5860 // Stop timer for previous display state. 5861 switch (oldDisplayState) { 5862 case Display.STATE_ON: 5863 displayStats.screenOnTimer.stopRunningLocked(elapsedRealtimeMs); 5864 final int bin = displayStats.screenBrightnessBin; 5865 if (bin >= 0) { 5866 displayStats.screenBrightnessTimers[bin].stopRunningLocked( 5867 elapsedRealtimeMs); 5868 } 5869 overallBin = evaluateOverallScreenBrightnessBinLocked(); 5870 shouldScheduleSync = true; 5871 break; 5872 case Display.STATE_DOZE: 5873 // Transition from doze to doze suspend can be ignored. 5874 if (displayState == Display.STATE_DOZE_SUSPEND) break; 5875 displayStats.screenDozeTimer.stopRunningLocked(elapsedRealtimeMs); 5876 shouldScheduleSync = true; 5877 break; 5878 case Display.STATE_DOZE_SUSPEND: 5879 // Transition from doze suspend to doze can be ignored. 5880 if (displayState == Display.STATE_DOZE) break; 5881 displayStats.screenDozeTimer.stopRunningLocked(elapsedRealtimeMs); 5882 shouldScheduleSync = true; 5883 break; 5884 case Display.STATE_OFF: // fallthrough 5885 case Display.STATE_UNKNOWN: 5886 // Not tracked by timers. 5887 break; 5888 default: 5889 Slog.wtf(TAG, 5890 "Attempted to stop timer for unexpected display state " + display); 5891 } 5892 5893 // Start timer for new display state. 5894 switch (displayState) { 5895 case Display.STATE_ON: 5896 displayStats.screenOnTimer.startRunningLocked(elapsedRealtimeMs); 5897 final int bin = displayStats.screenBrightnessBin; 5898 if (bin >= 0) { 5899 displayStats.screenBrightnessTimers[bin].startRunningLocked( 5900 elapsedRealtimeMs); 5901 } 5902 overallBin = evaluateOverallScreenBrightnessBinLocked(); 5903 shouldScheduleSync = true; 5904 break; 5905 case Display.STATE_DOZE: 5906 // Transition from doze suspend to doze can be ignored. 5907 if (oldDisplayState == Display.STATE_DOZE_SUSPEND) break; 5908 displayStats.screenDozeTimer.startRunningLocked(elapsedRealtimeMs); 5909 shouldScheduleSync = true; 5910 break; 5911 case Display.STATE_DOZE_SUSPEND: 5912 // Transition from doze to doze suspend can be ignored. 5913 if (oldDisplayState == Display.STATE_DOZE) break; 5914 displayStats.screenDozeTimer.startRunningLocked(elapsedRealtimeMs); 5915 shouldScheduleSync = true; 5916 break; 5917 case Display.STATE_OFF: // fallthrough 5918 case Display.STATE_UNKNOWN: 5919 // Not tracked by timers. 5920 break; 5921 default: 5922 Slog.wtf(TAG, 5923 "Attempted to start timer for unexpected display state " + displayState 5924 + " for display " + display); 5925 } 5926 5927 if (shouldScheduleSync 5928 && mGlobalMeasuredEnergyStats != null 5929 && mGlobalMeasuredEnergyStats.isStandardBucketSupported( 5930 MeasuredEnergyStats.POWER_BUCKET_SCREEN_ON)) { 5931 // Display measured energy stats is available. Prepare to schedule an 5932 // external sync. 5933 externalUpdateFlag |= ExternalStatsSync.UPDATE_DISPLAY; 5934 } 5935 5936 // Reevaluate most important display screen state. 5937 state = Display.STATE_UNKNOWN; 5938 for (int i = 0; i < numDisplay; i++) { 5939 final int tempState = mPerDisplayBatteryStats[i].screenState; 5940 if (tempState == Display.STATE_ON 5941 || state == Display.STATE_ON) { 5942 state = Display.STATE_ON; 5943 } else if (tempState == Display.STATE_DOZE 5944 || state == Display.STATE_DOZE) { 5945 state = Display.STATE_DOZE; 5946 } else if (tempState == Display.STATE_DOZE_SUSPEND 5947 || state == Display.STATE_DOZE_SUSPEND) { 5948 state = Display.STATE_DOZE_SUSPEND; 5949 } else if (tempState == Display.STATE_OFF 5950 || state == Display.STATE_OFF) { 5951 state = Display.STATE_OFF; 5952 } 5953 } 5954 } 5955 5956 final boolean batteryRunning = mOnBatteryTimeBase.isRunning(); 5957 final boolean batteryScreenOffRunning = mOnBatteryScreenOffTimeBase.isRunning(); 5958 5959 state = mPretendScreenOff ? Display.STATE_OFF : state; 5960 if (mScreenState != state) { 5961 recordDailyStatsIfNeededLocked(true, currentTimeMs); 5962 final int oldState = mScreenState; 5963 mScreenState = state; 5964 if (DEBUG) Slog.v(TAG, "Screen state: oldState=" + Display.stateToString(oldState) 5965 + ", newState=" + Display.stateToString(state)); 5966 5967 if (state != Display.STATE_UNKNOWN) { 5968 int stepState = state-1; 5969 if ((stepState & STEP_LEVEL_MODE_SCREEN_STATE) == stepState) { 5970 mModStepMode |= (mCurStepMode & STEP_LEVEL_MODE_SCREEN_STATE) ^ stepState; 5971 mCurStepMode = (mCurStepMode & ~STEP_LEVEL_MODE_SCREEN_STATE) | stepState; 5972 } else { 5973 Slog.wtf(TAG, "Unexpected screen state: " + state); 5974 } 5975 } 5976 5977 boolean updateHistory = false; 5978 if (Display.isDozeState(state) && !Display.isDozeState(oldState)) { 5979 mHistoryCur.states |= HistoryItem.STATE_SCREEN_DOZE_FLAG; 5980 mScreenDozeTimer.startRunningLocked(elapsedRealtimeMs); 5981 updateHistory = true; 5982 } else if (Display.isDozeState(oldState) && !Display.isDozeState(state)) { 5983 mHistoryCur.states &= ~HistoryItem.STATE_SCREEN_DOZE_FLAG; 5984 mScreenDozeTimer.stopRunningLocked(elapsedRealtimeMs); 5985 updateHistory = true; 5986 } 5987 if (Display.isOnState(state)) { 5988 mHistoryCur.states |= HistoryItem.STATE_SCREEN_ON_FLAG; 5989 if (DEBUG_HISTORY) Slog.v(TAG, "Screen on to: " 5990 + Integer.toHexString(mHistoryCur.states)); 5991 mScreenOnTimer.startRunningLocked(elapsedRealtimeMs); 5992 if (mScreenBrightnessBin >= 0) { 5993 mScreenBrightnessTimer[mScreenBrightnessBin] 5994 .startRunningLocked(elapsedRealtimeMs); 5995 } 5996 updateHistory = true; 5997 } else if (Display.isOnState(oldState)) { 5998 mHistoryCur.states &= ~HistoryItem.STATE_SCREEN_ON_FLAG; 5999 if (DEBUG_HISTORY) Slog.v(TAG, "Screen off to: " 6000 + Integer.toHexString(mHistoryCur.states)); 6001 mScreenOnTimer.stopRunningLocked(elapsedRealtimeMs); 6002 if (mScreenBrightnessBin >= 0) { 6003 mScreenBrightnessTimer[mScreenBrightnessBin] 6004 .stopRunningLocked(elapsedRealtimeMs); 6005 } 6006 updateHistory = true; 6007 } 6008 if (updateHistory) { 6009 if (DEBUG_HISTORY) Slog.v(TAG, "Screen state to: " 6010 + Display.stateToString(state)); 6011 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 6012 } 6013 6014 // Per screen state Cpu stats needed. Prepare to schedule an external sync. 6015 externalUpdateFlag |= ExternalStatsSync.UPDATE_CPU; 6016 shouldScheduleSync = true; 6017 6018 if (Display.isOnState(state)) { 6019 updateTimeBasesLocked(mOnBatteryTimeBase.isRunning(), state, 6020 uptimeMs * 1000, elapsedRealtimeMs * 1000); 6021 // Fake a wake lock, so we consider the device waked as long as the screen is on. 6022 noteStartWakeLocked(-1, -1, null, "screen", null, WAKE_TYPE_PARTIAL, false, 6023 elapsedRealtimeMs, uptimeMs); 6024 } else if (Display.isOnState(oldState)) { 6025 noteStopWakeLocked(-1, -1, null, "screen", "screen", WAKE_TYPE_PARTIAL, 6026 elapsedRealtimeMs, uptimeMs); 6027 updateTimeBasesLocked(mOnBatteryTimeBase.isRunning(), state, 6028 uptimeMs * 1000, elapsedRealtimeMs * 1000); 6029 } 6030 // Update discharge amounts. 6031 if (mOnBatteryInternal) { 6032 updateDischargeScreenLevelsLocked(oldState, state); 6033 } 6034 } 6035 6036 // Changing display states might have changed the screen used to determine the overall 6037 // brightness. 6038 maybeUpdateOverallScreenBrightness(overallBin, elapsedRealtimeMs, uptimeMs); 6039 6040 if (shouldScheduleSync) { 6041 final int numDisplays = mPerDisplayBatteryStats.length; 6042 final int[] displayStates = new int[numDisplays]; 6043 for (int i = 0; i < numDisplays; i++) { 6044 displayStates[i] = mPerDisplayBatteryStats[i].screenState; 6045 } 6046 mExternalSync.scheduleSyncDueToScreenStateChange(externalUpdateFlag, 6047 batteryRunning, batteryScreenOffRunning, state, displayStates); 6048 } 6049 } 6050 6051 @UnsupportedAppUsage 6052 @GuardedBy("this") noteScreenBrightnessLocked(int brightness)6053 public void noteScreenBrightnessLocked(int brightness) { 6054 noteScreenBrightnessLocked(0, brightness); 6055 } 6056 6057 /** 6058 * Note screen brightness change for a display. 6059 */ 6060 @GuardedBy("this") noteScreenBrightnessLocked(int display, int brightness)6061 public void noteScreenBrightnessLocked(int display, int brightness) { 6062 noteScreenBrightnessLocked(display, brightness, mClock.elapsedRealtime(), 6063 mClock.uptimeMillis()); 6064 } 6065 6066 6067 /** 6068 * Note screen brightness change for a display. 6069 */ 6070 @GuardedBy("this") noteScreenBrightnessLocked(int display, int brightness, long elapsedRealtimeMs, long uptimeMs)6071 public void noteScreenBrightnessLocked(int display, int brightness, long elapsedRealtimeMs, 6072 long uptimeMs) { 6073 // Bin the brightness. 6074 int bin = brightness / (256/NUM_SCREEN_BRIGHTNESS_BINS); 6075 if (bin < 0) bin = 0; 6076 else if (bin >= NUM_SCREEN_BRIGHTNESS_BINS) bin = NUM_SCREEN_BRIGHTNESS_BINS-1; 6077 6078 final int overallBin; 6079 6080 final int numDisplays = mPerDisplayBatteryStats.length; 6081 if (display < 0 || display >= numDisplays) { 6082 Slog.wtf(TAG, "Unexpected note screen brightness for display " + display + " (only " 6083 + mPerDisplayBatteryStats.length + " displays exist...)"); 6084 return; 6085 } 6086 6087 final DisplayBatteryStats displayStats = mPerDisplayBatteryStats[display]; 6088 final int oldBin = displayStats.screenBrightnessBin; 6089 if (oldBin == bin) { 6090 // Nothing changed 6091 overallBin = mScreenBrightnessBin; 6092 } else { 6093 displayStats.screenBrightnessBin = bin; 6094 if (displayStats.screenState == Display.STATE_ON) { 6095 if (oldBin >= 0) { 6096 displayStats.screenBrightnessTimers[oldBin].stopRunningLocked( 6097 elapsedRealtimeMs); 6098 } 6099 displayStats.screenBrightnessTimers[bin].startRunningLocked( 6100 elapsedRealtimeMs); 6101 } 6102 overallBin = evaluateOverallScreenBrightnessBinLocked(); 6103 } 6104 6105 maybeUpdateOverallScreenBrightness(overallBin, elapsedRealtimeMs, uptimeMs); 6106 } 6107 6108 @GuardedBy("this") evaluateOverallScreenBrightnessBinLocked()6109 private int evaluateOverallScreenBrightnessBinLocked() { 6110 int overallBin = -1; 6111 final int numDisplays = getDisplayCount(); 6112 for (int display = 0; display < numDisplays; display++) { 6113 final int displayBrightnessBin; 6114 if (mPerDisplayBatteryStats[display].screenState == Display.STATE_ON) { 6115 displayBrightnessBin = mPerDisplayBatteryStats[display].screenBrightnessBin; 6116 } else { 6117 displayBrightnessBin = -1; 6118 } 6119 if (displayBrightnessBin > overallBin) { 6120 overallBin = displayBrightnessBin; 6121 } 6122 } 6123 return overallBin; 6124 } 6125 6126 @GuardedBy("this") maybeUpdateOverallScreenBrightness(int overallBin, long elapsedRealtimeMs, long uptimeMs)6127 private void maybeUpdateOverallScreenBrightness(int overallBin, long elapsedRealtimeMs, 6128 long uptimeMs) { 6129 if (mScreenBrightnessBin != overallBin) { 6130 if (overallBin >= 0) { 6131 mHistoryCur.states = (mHistoryCur.states & ~HistoryItem.STATE_BRIGHTNESS_MASK) 6132 | (overallBin << HistoryItem.STATE_BRIGHTNESS_SHIFT); 6133 if (DEBUG_HISTORY) { 6134 Slog.v(TAG, "Screen brightness " + overallBin + " to: " 6135 + Integer.toHexString(mHistoryCur.states)); 6136 } 6137 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 6138 } 6139 if (mScreenState == Display.STATE_ON) { 6140 if (mScreenBrightnessBin >= 0) { 6141 mScreenBrightnessTimer[mScreenBrightnessBin] 6142 .stopRunningLocked(elapsedRealtimeMs); 6143 } 6144 if (overallBin >= 0) { 6145 mScreenBrightnessTimer[overallBin] 6146 .startRunningLocked(elapsedRealtimeMs); 6147 } 6148 } 6149 mScreenBrightnessBin = overallBin; 6150 } 6151 } 6152 6153 @UnsupportedAppUsage 6154 @GuardedBy("this") noteUserActivityLocked(int uid, @PowerManager.UserActivityEvent int event)6155 public void noteUserActivityLocked(int uid, @PowerManager.UserActivityEvent int event) { 6156 noteUserActivityLocked(uid, event, mClock.elapsedRealtime(), mClock.uptimeMillis()); 6157 } 6158 6159 @GuardedBy("this") noteUserActivityLocked(int uid, @PowerManager.UserActivityEvent int event, long elapsedRealtimeMs, long uptimeMs)6160 public void noteUserActivityLocked(int uid, @PowerManager.UserActivityEvent int event, 6161 long elapsedRealtimeMs, long uptimeMs) { 6162 if (mOnBatteryInternal) { 6163 uid = mapUid(uid); 6164 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs).noteUserActivityLocked(event); 6165 } 6166 } 6167 6168 @GuardedBy("this") noteWakeUpLocked(String reason, int reasonUid)6169 public void noteWakeUpLocked(String reason, int reasonUid) { 6170 noteWakeUpLocked(reason, reasonUid, mClock.elapsedRealtime(), mClock.uptimeMillis()); 6171 } 6172 6173 @GuardedBy("this") noteWakeUpLocked(String reason, int reasonUid, long elapsedRealtimeMs, long uptimeMs)6174 public void noteWakeUpLocked(String reason, int reasonUid, 6175 long elapsedRealtimeMs, long uptimeMs) { 6176 addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_SCREEN_WAKE_UP, 6177 reason, reasonUid); 6178 } 6179 6180 @GuardedBy("this") noteInteractiveLocked(boolean interactive)6181 public void noteInteractiveLocked(boolean interactive) { 6182 noteInteractiveLocked(interactive, mClock.elapsedRealtime()); 6183 } 6184 6185 @GuardedBy("this") noteInteractiveLocked(boolean interactive, long elapsedRealtimeMs)6186 public void noteInteractiveLocked(boolean interactive, long elapsedRealtimeMs) { 6187 if (mInteractive != interactive) { 6188 mInteractive = interactive; 6189 if (DEBUG) Slog.v(TAG, "Interactive: " + interactive); 6190 if (interactive) { 6191 mInteractiveTimer.startRunningLocked(elapsedRealtimeMs); 6192 } else { 6193 mInteractiveTimer.stopRunningLocked(elapsedRealtimeMs); 6194 } 6195 } 6196 } 6197 6198 @GuardedBy("this") noteConnectivityChangedLocked(int type, String extra)6199 public void noteConnectivityChangedLocked(int type, String extra) { 6200 noteConnectivityChangedLocked(type, extra, 6201 mClock.elapsedRealtime(), mClock.uptimeMillis()); 6202 } 6203 6204 @GuardedBy("this") noteConnectivityChangedLocked(int type, String extra, long elapsedRealtimeMs, long uptimeMs)6205 public void noteConnectivityChangedLocked(int type, String extra, 6206 long elapsedRealtimeMs, long uptimeMs) { 6207 addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_CONNECTIVITY_CHANGED, 6208 extra, type); 6209 mNumConnectivityChange++; 6210 } 6211 6212 @GuardedBy("this") noteMobileRadioApWakeupLocked(final long elapsedRealtimeMillis, final long uptimeMillis, int uid)6213 private void noteMobileRadioApWakeupLocked(final long elapsedRealtimeMillis, 6214 final long uptimeMillis, int uid) { 6215 uid = mapUid(uid); 6216 addHistoryEventLocked(elapsedRealtimeMillis, uptimeMillis, HistoryItem.EVENT_WAKEUP_AP, "", 6217 uid); 6218 getUidStatsLocked(uid, elapsedRealtimeMillis, uptimeMillis).noteMobileRadioApWakeupLocked(); 6219 } 6220 6221 /** 6222 * Updates the radio power state and returns true if an external stats collection should occur. 6223 */ 6224 @GuardedBy("this") noteMobileRadioPowerStateLocked(int powerState, long timestampNs, int uid)6225 public boolean noteMobileRadioPowerStateLocked(int powerState, long timestampNs, int uid) { 6226 return noteMobileRadioPowerStateLocked(powerState, timestampNs, uid, 6227 mClock.elapsedRealtime(), mClock.uptimeMillis()); 6228 } 6229 6230 @GuardedBy("this") noteMobileRadioPowerStateLocked(int powerState, long timestampNs, int uid, long elapsedRealtimeMs, long uptimeMs)6231 public boolean noteMobileRadioPowerStateLocked(int powerState, long timestampNs, int uid, 6232 long elapsedRealtimeMs, long uptimeMs) { 6233 if (mMobileRadioPowerState != powerState) { 6234 long realElapsedRealtimeMs; 6235 final boolean active = isActiveRadioPowerState(powerState); 6236 if (active) { 6237 if (uid > 0) { 6238 noteMobileRadioApWakeupLocked(elapsedRealtimeMs, uptimeMs, uid); 6239 } 6240 6241 mMobileRadioActiveStartTimeMs = realElapsedRealtimeMs = timestampNs / (1000 * 1000); 6242 mHistoryCur.states |= HistoryItem.STATE_MOBILE_RADIO_ACTIVE_FLAG; 6243 } else { 6244 realElapsedRealtimeMs = timestampNs / (1000*1000); 6245 long lastUpdateTimeMs = mMobileRadioActiveStartTimeMs; 6246 if (realElapsedRealtimeMs < lastUpdateTimeMs) { 6247 Slog.wtf(TAG, "Data connection inactive timestamp " + realElapsedRealtimeMs 6248 + " is before start time " + lastUpdateTimeMs); 6249 realElapsedRealtimeMs = elapsedRealtimeMs; 6250 } else if (realElapsedRealtimeMs < elapsedRealtimeMs) { 6251 mMobileRadioActiveAdjustedTime.addCountLocked(elapsedRealtimeMs 6252 - realElapsedRealtimeMs); 6253 } 6254 mHistoryCur.states &= ~HistoryItem.STATE_MOBILE_RADIO_ACTIVE_FLAG; 6255 } 6256 if (DEBUG_HISTORY) Slog.v(TAG, "Mobile network active " + active + " to: " 6257 + Integer.toHexString(mHistoryCur.states)); 6258 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 6259 mMobileRadioPowerState = powerState; 6260 6261 // Inform current RatBatteryStats that the modem active state might have changed. 6262 getRatBatteryStatsLocked(mActiveRat).noteActive(active, elapsedRealtimeMs); 6263 6264 if (active) { 6265 mMobileRadioActiveTimer.startRunningLocked(elapsedRealtimeMs); 6266 mMobileRadioActivePerAppTimer.startRunningLocked(elapsedRealtimeMs); 6267 } else { 6268 mMobileRadioActiveTimer.stopRunningLocked(realElapsedRealtimeMs); 6269 mMobileRadioActivePerAppTimer.stopRunningLocked(realElapsedRealtimeMs); 6270 6271 if (mLastModemActivityInfo != null) { 6272 if (elapsedRealtimeMs < mLastModemActivityInfo.getTimestampMillis() 6273 + MOBILE_RADIO_POWER_STATE_UPDATE_FREQ_MS) { 6274 // Modem Activity info has been collected recently, don't bother 6275 // triggering another update. 6276 return false; 6277 } 6278 } 6279 // Tell the caller to collect radio network/power stats. 6280 return true; 6281 } 6282 } 6283 return false; 6284 } 6285 isActiveRadioPowerState(int powerState)6286 private static boolean isActiveRadioPowerState(int powerState) { 6287 return powerState == DataConnectionRealTimeInfo.DC_POWER_STATE_MEDIUM 6288 || powerState == DataConnectionRealTimeInfo.DC_POWER_STATE_HIGH; 6289 } 6290 6291 @GuardedBy("this") notePowerSaveModeLocked(boolean enabled)6292 public void notePowerSaveModeLocked(boolean enabled) { 6293 notePowerSaveModeLocked(enabled, mClock.elapsedRealtime(), mClock.uptimeMillis()); 6294 } 6295 6296 /** 6297 * Toggles the power save mode state. 6298 */ 6299 @GuardedBy("this") notePowerSaveModeLockedInit(boolean enabled, long elapsedRealtimeMs, long uptimeMs)6300 public void notePowerSaveModeLockedInit(boolean enabled, long elapsedRealtimeMs, 6301 long uptimeMs) { 6302 if (mPowerSaveModeEnabled != enabled) { 6303 notePowerSaveModeLocked(enabled, elapsedRealtimeMs, uptimeMs); 6304 } else { 6305 // Log an initial value for BATTERY_SAVER_MODE_STATE_CHANGED in order to 6306 // allow the atom to read all future state changes. 6307 FrameworkStatsLog.write(FrameworkStatsLog.BATTERY_SAVER_MODE_STATE_CHANGED, 6308 enabled 6309 ? FrameworkStatsLog.BATTERY_SAVER_MODE_STATE_CHANGED__STATE__ON 6310 : FrameworkStatsLog.BATTERY_SAVER_MODE_STATE_CHANGED__STATE__OFF); 6311 } 6312 } 6313 6314 @GuardedBy("this") notePowerSaveModeLocked(boolean enabled, long elapsedRealtimeMs, long uptimeMs)6315 public void notePowerSaveModeLocked(boolean enabled, long elapsedRealtimeMs, long uptimeMs) { 6316 if (mPowerSaveModeEnabled != enabled) { 6317 int stepState = enabled ? STEP_LEVEL_MODE_POWER_SAVE : 0; 6318 mModStepMode |= (mCurStepMode&STEP_LEVEL_MODE_POWER_SAVE) ^ stepState; 6319 mCurStepMode = (mCurStepMode&~STEP_LEVEL_MODE_POWER_SAVE) | stepState; 6320 mPowerSaveModeEnabled = enabled; 6321 if (enabled) { 6322 mHistoryCur.states2 |= HistoryItem.STATE2_POWER_SAVE_FLAG; 6323 if (DEBUG_HISTORY) Slog.v(TAG, "Power save mode enabled to: " 6324 + Integer.toHexString(mHistoryCur.states2)); 6325 mPowerSaveModeEnabledTimer.startRunningLocked(elapsedRealtimeMs); 6326 } else { 6327 mHistoryCur.states2 &= ~HistoryItem.STATE2_POWER_SAVE_FLAG; 6328 if (DEBUG_HISTORY) Slog.v(TAG, "Power save mode disabled to: " 6329 + Integer.toHexString(mHistoryCur.states2)); 6330 mPowerSaveModeEnabledTimer.stopRunningLocked(elapsedRealtimeMs); 6331 } 6332 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 6333 FrameworkStatsLog.write(FrameworkStatsLog.BATTERY_SAVER_MODE_STATE_CHANGED, 6334 enabled 6335 ? FrameworkStatsLog.BATTERY_SAVER_MODE_STATE_CHANGED__STATE__ON 6336 : FrameworkStatsLog.BATTERY_SAVER_MODE_STATE_CHANGED__STATE__OFF); 6337 } 6338 } 6339 6340 @GuardedBy("this") noteDeviceIdleModeLocked(final int mode, String activeReason, int activeUid)6341 public void noteDeviceIdleModeLocked(final int mode, String activeReason, int activeUid) { 6342 noteDeviceIdleModeLocked(mode, activeReason, activeUid, 6343 mClock.elapsedRealtime(), mClock.uptimeMillis()); 6344 } 6345 6346 @GuardedBy("this") noteDeviceIdleModeLocked(final int mode, String activeReason, int activeUid, long elapsedRealtimeMs, long uptimeMs)6347 public void noteDeviceIdleModeLocked(final int mode, String activeReason, int activeUid, 6348 long elapsedRealtimeMs, long uptimeMs) { 6349 boolean nowIdling = mode == DEVICE_IDLE_MODE_DEEP; 6350 if (mDeviceIdling && !nowIdling && activeReason == null) { 6351 // We don't go out of general idling mode until explicitly taken out of 6352 // device idle through going active or significant motion. 6353 nowIdling = true; 6354 } 6355 boolean nowLightIdling = mode == DEVICE_IDLE_MODE_LIGHT; 6356 if (mDeviceLightIdling && !nowLightIdling && !nowIdling && activeReason == null) { 6357 // We don't go out of general light idling mode until explicitly taken out of 6358 // device idle through going active or significant motion. 6359 nowLightIdling = true; 6360 } 6361 if (activeReason != null && (mDeviceIdling || mDeviceLightIdling)) { 6362 addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_ACTIVE, 6363 activeReason, activeUid); 6364 } 6365 if (mDeviceIdling != nowIdling || mDeviceLightIdling != nowLightIdling) { 6366 int statsmode; 6367 if (nowIdling) statsmode = DEVICE_IDLE_MODE_DEEP; 6368 else if (nowLightIdling) statsmode = DEVICE_IDLE_MODE_LIGHT; 6369 else statsmode = DEVICE_IDLE_MODE_OFF; 6370 FrameworkStatsLog.write(FrameworkStatsLog.DEVICE_IDLING_MODE_STATE_CHANGED, statsmode); 6371 } 6372 if (mDeviceIdling != nowIdling) { 6373 mDeviceIdling = nowIdling; 6374 int stepState = nowIdling ? STEP_LEVEL_MODE_DEVICE_IDLE : 0; 6375 mModStepMode |= (mCurStepMode&STEP_LEVEL_MODE_DEVICE_IDLE) ^ stepState; 6376 mCurStepMode = (mCurStepMode&~STEP_LEVEL_MODE_DEVICE_IDLE) | stepState; 6377 if (nowIdling) { 6378 mDeviceIdlingTimer.startRunningLocked(elapsedRealtimeMs); 6379 } else { 6380 mDeviceIdlingTimer.stopRunningLocked(elapsedRealtimeMs); 6381 } 6382 } 6383 if (mDeviceLightIdling != nowLightIdling) { 6384 mDeviceLightIdling = nowLightIdling; 6385 if (nowLightIdling) { 6386 mDeviceLightIdlingTimer.startRunningLocked(elapsedRealtimeMs); 6387 } else { 6388 mDeviceLightIdlingTimer.stopRunningLocked(elapsedRealtimeMs); 6389 } 6390 } 6391 if (mDeviceIdleMode != mode) { 6392 mHistoryCur.states2 = (mHistoryCur.states2 & ~HistoryItem.STATE2_DEVICE_IDLE_MASK) 6393 | (mode << HistoryItem.STATE2_DEVICE_IDLE_SHIFT); 6394 if (DEBUG_HISTORY) Slog.v(TAG, "Device idle mode changed to: " 6395 + Integer.toHexString(mHistoryCur.states2)); 6396 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 6397 long lastDuration = elapsedRealtimeMs - mLastIdleTimeStartMs; 6398 mLastIdleTimeStartMs = elapsedRealtimeMs; 6399 if (mDeviceIdleMode == DEVICE_IDLE_MODE_LIGHT) { 6400 if (lastDuration > mLongestLightIdleTimeMs) { 6401 mLongestLightIdleTimeMs = lastDuration; 6402 } 6403 mDeviceIdleModeLightTimer.stopRunningLocked(elapsedRealtimeMs); 6404 } else if (mDeviceIdleMode == DEVICE_IDLE_MODE_DEEP) { 6405 if (lastDuration > mLongestFullIdleTimeMs) { 6406 mLongestFullIdleTimeMs = lastDuration; 6407 } 6408 mDeviceIdleModeFullTimer.stopRunningLocked(elapsedRealtimeMs); 6409 } 6410 if (mode == DEVICE_IDLE_MODE_LIGHT) { 6411 mDeviceIdleModeLightTimer.startRunningLocked(elapsedRealtimeMs); 6412 } else if (mode == DEVICE_IDLE_MODE_DEEP) { 6413 mDeviceIdleModeFullTimer.startRunningLocked(elapsedRealtimeMs); 6414 } 6415 mDeviceIdleMode = mode; 6416 FrameworkStatsLog.write(FrameworkStatsLog.DEVICE_IDLE_MODE_STATE_CHANGED, mode); 6417 } 6418 } 6419 6420 @GuardedBy("this") notePackageInstalledLocked(String pkgName, long versionCode)6421 public void notePackageInstalledLocked(String pkgName, long versionCode) { 6422 notePackageInstalledLocked(pkgName, versionCode, 6423 mClock.elapsedRealtime(), mClock.uptimeMillis()); 6424 } 6425 6426 @GuardedBy("this") notePackageInstalledLocked(String pkgName, long versionCode, long elapsedRealtimeMs, long uptimeMs)6427 public void notePackageInstalledLocked(String pkgName, long versionCode, 6428 long elapsedRealtimeMs, long uptimeMs) { 6429 // XXX need to figure out what to do with long version codes. 6430 addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_PACKAGE_INSTALLED, 6431 pkgName, (int)versionCode); 6432 PackageChange pc = new PackageChange(); 6433 pc.mPackageName = pkgName; 6434 pc.mUpdate = true; 6435 pc.mVersionCode = versionCode; 6436 addPackageChange(pc); 6437 } 6438 6439 @GuardedBy("this") notePackageUninstalledLocked(String pkgName)6440 public void notePackageUninstalledLocked(String pkgName) { 6441 notePackageUninstalledLocked(pkgName, mClock.elapsedRealtime(), mClock.uptimeMillis()); 6442 } 6443 6444 @GuardedBy("this") notePackageUninstalledLocked(String pkgName, long elapsedRealtimeMs, long uptimeMs)6445 public void notePackageUninstalledLocked(String pkgName, 6446 long elapsedRealtimeMs, long uptimeMs) { 6447 addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, 6448 HistoryItem.EVENT_PACKAGE_UNINSTALLED, pkgName, 0); 6449 PackageChange pc = new PackageChange(); 6450 pc.mPackageName = pkgName; 6451 pc.mUpdate = true; 6452 addPackageChange(pc); 6453 } 6454 addPackageChange(PackageChange pc)6455 private void addPackageChange(PackageChange pc) { 6456 if (mDailyPackageChanges == null) { 6457 mDailyPackageChanges = new ArrayList<>(); 6458 } 6459 mDailyPackageChanges.add(pc); 6460 } 6461 6462 @GuardedBy("this") stopAllGpsSignalQualityTimersLocked(int except)6463 void stopAllGpsSignalQualityTimersLocked(int except) { 6464 stopAllGpsSignalQualityTimersLocked(except, mClock.elapsedRealtime()); 6465 } 6466 6467 @GuardedBy("this") stopAllGpsSignalQualityTimersLocked(int except, long elapsedRealtimeMs)6468 void stopAllGpsSignalQualityTimersLocked(int except, long elapsedRealtimeMs) { 6469 for (int i = 0; i < mGpsSignalQualityTimer.length; i++) { 6470 if (i == except) { 6471 continue; 6472 } 6473 while (mGpsSignalQualityTimer[i].isRunningLocked()) { 6474 mGpsSignalQualityTimer[i].stopRunningLocked(elapsedRealtimeMs); 6475 } 6476 } 6477 } 6478 6479 @UnsupportedAppUsage 6480 @GuardedBy("this") notePhoneOnLocked()6481 public void notePhoneOnLocked() { 6482 notePhoneOnLocked(mClock.elapsedRealtime(), mClock.uptimeMillis()); 6483 } 6484 6485 @GuardedBy("this") notePhoneOnLocked(long elapsedRealtimeMs, long uptimeMs)6486 public void notePhoneOnLocked(long elapsedRealtimeMs, long uptimeMs) { 6487 if (!mPhoneOn) { 6488 mHistoryCur.states2 |= HistoryItem.STATE2_PHONE_IN_CALL_FLAG; 6489 if (DEBUG_HISTORY) Slog.v(TAG, "Phone on to: " 6490 + Integer.toHexString(mHistoryCur.states)); 6491 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 6492 mPhoneOn = true; 6493 mPhoneOnTimer.startRunningLocked(elapsedRealtimeMs); 6494 if (mConstants.PHONE_ON_EXTERNAL_STATS_COLLECTION) { 6495 scheduleSyncExternalStatsLocked("phone-on", ExternalStatsSync.UPDATE_RADIO); 6496 } 6497 } 6498 } 6499 6500 @UnsupportedAppUsage 6501 @GuardedBy("this") notePhoneOffLocked()6502 public void notePhoneOffLocked() { 6503 notePhoneOffLocked(mClock.elapsedRealtime(), mClock.uptimeMillis()); 6504 } 6505 6506 @GuardedBy("this") notePhoneOffLocked(long elapsedRealtimeMs, long uptimeMs)6507 public void notePhoneOffLocked(long elapsedRealtimeMs, long uptimeMs) { 6508 if (mPhoneOn) { 6509 mHistoryCur.states2 &= ~HistoryItem.STATE2_PHONE_IN_CALL_FLAG; 6510 if (DEBUG_HISTORY) Slog.v(TAG, "Phone off to: " 6511 + Integer.toHexString(mHistoryCur.states)); 6512 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 6513 mPhoneOn = false; 6514 mPhoneOnTimer.stopRunningLocked(elapsedRealtimeMs); 6515 scheduleSyncExternalStatsLocked("phone-off", ExternalStatsSync.UPDATE_RADIO); 6516 } 6517 } 6518 6519 @GuardedBy("this") registerUsbStateReceiver(Context context)6520 private void registerUsbStateReceiver(Context context) { 6521 final IntentFilter usbStateFilter = new IntentFilter(); 6522 usbStateFilter.addAction(UsbManager.ACTION_USB_STATE); 6523 context.registerReceiver(new BroadcastReceiver() { 6524 @Override 6525 public void onReceive(Context context, Intent intent) { 6526 final boolean state = intent.getBooleanExtra(UsbManager.USB_CONNECTED, false); 6527 synchronized (BatteryStatsImpl.this) { 6528 noteUsbConnectionStateLocked(state, mClock.elapsedRealtime(), 6529 mClock.uptimeMillis()); 6530 } 6531 } 6532 }, usbStateFilter); 6533 synchronized (this) { 6534 if (mUsbDataState == USB_DATA_UNKNOWN) { 6535 final Intent usbState = context.registerReceiver(null, usbStateFilter); 6536 final boolean initState = usbState != null && usbState.getBooleanExtra( 6537 UsbManager.USB_CONNECTED, false); 6538 noteUsbConnectionStateLocked(initState, mClock.elapsedRealtime(), 6539 mClock.uptimeMillis()); 6540 } 6541 } 6542 } 6543 6544 @GuardedBy("this") noteUsbConnectionStateLocked(boolean connected, long elapsedRealtimeMs, long uptimeMs)6545 private void noteUsbConnectionStateLocked(boolean connected, long elapsedRealtimeMs, 6546 long uptimeMs) { 6547 int newState = connected ? USB_DATA_CONNECTED : USB_DATA_DISCONNECTED; 6548 if (mUsbDataState != newState) { 6549 mUsbDataState = newState; 6550 if (connected) { 6551 mHistoryCur.states2 |= HistoryItem.STATE2_USB_DATA_LINK_FLAG; 6552 } else { 6553 mHistoryCur.states2 &= ~HistoryItem.STATE2_USB_DATA_LINK_FLAG; 6554 } 6555 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 6556 } 6557 } 6558 6559 @GuardedBy("this") stopAllPhoneSignalStrengthTimersLocked(int except, long elapsedRealtimeMs)6560 void stopAllPhoneSignalStrengthTimersLocked(int except, long elapsedRealtimeMs) { 6561 for (int i = 0; i < CellSignalStrength.getNumSignalStrengthLevels(); i++) { 6562 if (i == except) { 6563 continue; 6564 } 6565 while (mPhoneSignalStrengthsTimer[i].isRunningLocked()) { 6566 mPhoneSignalStrengthsTimer[i].stopRunningLocked(elapsedRealtimeMs); 6567 } 6568 } 6569 } 6570 fixPhoneServiceState(int state, int signalBin)6571 private int fixPhoneServiceState(int state, int signalBin) { 6572 if (mPhoneSimStateRaw == TelephonyManager.SIM_STATE_ABSENT) { 6573 // In this case we will always be STATE_OUT_OF_SERVICE, so need 6574 // to infer that we are scanning from other data. 6575 if (state == ServiceState.STATE_OUT_OF_SERVICE 6576 && signalBin > CellSignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN) { 6577 state = ServiceState.STATE_IN_SERVICE; 6578 } 6579 } 6580 6581 return state; 6582 } 6583 6584 @GuardedBy("this") updateAllPhoneStateLocked(int state, int simState, int strengthBin, long elapsedRealtimeMs, long uptimeMs)6585 private void updateAllPhoneStateLocked(int state, int simState, int strengthBin, 6586 long elapsedRealtimeMs, long uptimeMs) { 6587 boolean scanning = false; 6588 boolean newHistory = false; 6589 6590 mPhoneServiceStateRaw = state; 6591 mPhoneSimStateRaw = simState; 6592 mPhoneSignalStrengthBinRaw = strengthBin; 6593 6594 if (simState == TelephonyManager.SIM_STATE_ABSENT) { 6595 // In this case we will always be STATE_OUT_OF_SERVICE, so need 6596 // to infer that we are scanning from other data. 6597 if (state == ServiceState.STATE_OUT_OF_SERVICE 6598 && strengthBin > CellSignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN) { 6599 state = ServiceState.STATE_IN_SERVICE; 6600 } 6601 } 6602 6603 // If the phone is powered off, stop all timers. 6604 if (state == ServiceState.STATE_POWER_OFF) { 6605 strengthBin = -1; 6606 6607 // If we are in service, make sure the correct signal string timer is running. 6608 } else if (state == ServiceState.STATE_IN_SERVICE) { 6609 // Bin will be changed below. 6610 6611 // If we're out of service, we are in the lowest signal strength 6612 // bin and have the scanning bit set. 6613 } else if (state == ServiceState.STATE_OUT_OF_SERVICE) { 6614 scanning = true; 6615 strengthBin = CellSignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN; 6616 if (!mPhoneSignalScanningTimer.isRunningLocked()) { 6617 mHistoryCur.states |= HistoryItem.STATE_PHONE_SCANNING_FLAG; 6618 newHistory = true; 6619 if (DEBUG_HISTORY) Slog.v(TAG, "Phone started scanning to: " 6620 + Integer.toHexString(mHistoryCur.states)); 6621 mPhoneSignalScanningTimer.startRunningLocked(elapsedRealtimeMs); 6622 FrameworkStatsLog.write(FrameworkStatsLog.PHONE_SERVICE_STATE_CHANGED, state, 6623 simState, strengthBin); 6624 } 6625 } 6626 6627 if (!scanning) { 6628 // If we are no longer scanning, then stop the scanning timer. 6629 if (mPhoneSignalScanningTimer.isRunningLocked()) { 6630 mHistoryCur.states &= ~HistoryItem.STATE_PHONE_SCANNING_FLAG; 6631 if (DEBUG_HISTORY) Slog.v(TAG, "Phone stopped scanning to: " 6632 + Integer.toHexString(mHistoryCur.states)); 6633 newHistory = true; 6634 mPhoneSignalScanningTimer.stopRunningLocked(elapsedRealtimeMs); 6635 FrameworkStatsLog.write(FrameworkStatsLog.PHONE_SERVICE_STATE_CHANGED, state, 6636 simState, strengthBin); 6637 } 6638 } 6639 6640 if (mPhoneServiceState != state) { 6641 mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_PHONE_STATE_MASK) 6642 | (state << HistoryItem.STATE_PHONE_STATE_SHIFT); 6643 if (DEBUG_HISTORY) Slog.v(TAG, "Phone state " + state + " to: " 6644 + Integer.toHexString(mHistoryCur.states)); 6645 newHistory = true; 6646 mPhoneServiceState = state; 6647 } 6648 6649 if (mPhoneSignalStrengthBin != strengthBin) { 6650 if (mPhoneSignalStrengthBin >= 0) { 6651 mPhoneSignalStrengthsTimer[mPhoneSignalStrengthBin].stopRunningLocked( 6652 elapsedRealtimeMs); 6653 } 6654 if (strengthBin >= 0) { 6655 if (!mPhoneSignalStrengthsTimer[strengthBin].isRunningLocked()) { 6656 mPhoneSignalStrengthsTimer[strengthBin].startRunningLocked(elapsedRealtimeMs); 6657 } 6658 mHistoryCur.states = 6659 (mHistoryCur.states & ~HistoryItem.STATE_PHONE_SIGNAL_STRENGTH_MASK) 6660 | (strengthBin << HistoryItem.STATE_PHONE_SIGNAL_STRENGTH_SHIFT); 6661 if (DEBUG_HISTORY) Slog.v(TAG, "Signal strength " + strengthBin + " to: " 6662 + Integer.toHexString(mHistoryCur.states)); 6663 newHistory = true; 6664 FrameworkStatsLog.write( 6665 FrameworkStatsLog.PHONE_SIGNAL_STRENGTH_CHANGED, strengthBin); 6666 } else { 6667 stopAllPhoneSignalStrengthTimersLocked(-1, elapsedRealtimeMs); 6668 } 6669 mPhoneSignalStrengthBin = strengthBin; 6670 } 6671 6672 if (newHistory) { 6673 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 6674 } 6675 } 6676 6677 /** 6678 * Telephony stack updates the phone state. 6679 * @param state phone state from ServiceState.getState() 6680 */ 6681 @GuardedBy("this") notePhoneStateLocked(int state, int simState)6682 public void notePhoneStateLocked(int state, int simState) { 6683 notePhoneStateLocked(state, simState, mClock.elapsedRealtime(), mClock.uptimeMillis()); 6684 } 6685 6686 @GuardedBy("this") notePhoneStateLocked(int state, int simState, long elapsedRealtimeMs, long uptimeMs)6687 public void notePhoneStateLocked(int state, int simState, 6688 long elapsedRealtimeMs, long uptimeMs) { 6689 updateAllPhoneStateLocked(state, simState, mPhoneSignalStrengthBinRaw, 6690 elapsedRealtimeMs, uptimeMs); 6691 } 6692 6693 @UnsupportedAppUsage 6694 @GuardedBy("this") notePhoneSignalStrengthLocked(SignalStrength signalStrength)6695 public void notePhoneSignalStrengthLocked(SignalStrength signalStrength) { 6696 notePhoneSignalStrengthLocked(signalStrength, 6697 mClock.elapsedRealtime(), mClock.uptimeMillis()); 6698 } 6699 6700 @GuardedBy("this") notePhoneSignalStrengthLocked(SignalStrength signalStrength, long elapsedRealtimeMs, long uptimeMs)6701 public void notePhoneSignalStrengthLocked(SignalStrength signalStrength, 6702 long elapsedRealtimeMs, long uptimeMs) { 6703 final int overallSignalStrength = signalStrength.getLevel(); 6704 final SparseIntArray perRatSignalStrength = new SparseIntArray( 6705 BatteryStats.RADIO_ACCESS_TECHNOLOGY_COUNT); 6706 6707 // Extract signal strength level for each RAT. 6708 final List<CellSignalStrength> cellSignalStrengths = 6709 signalStrength.getCellSignalStrengths(); 6710 final int size = cellSignalStrengths.size(); 6711 for (int i = 0; i < size; i++) { 6712 CellSignalStrength cellSignalStrength = cellSignalStrengths.get(i); 6713 // Map each CellSignalStrength to a BatteryStats.RadioAccessTechnology 6714 final int ratType; 6715 final int level; 6716 if (cellSignalStrength instanceof CellSignalStrengthNr) { 6717 ratType = RADIO_ACCESS_TECHNOLOGY_NR; 6718 level = cellSignalStrength.getLevel(); 6719 } else if (cellSignalStrength instanceof CellSignalStrengthLte) { 6720 ratType = RADIO_ACCESS_TECHNOLOGY_LTE; 6721 level = cellSignalStrength.getLevel(); 6722 } else { 6723 ratType = RADIO_ACCESS_TECHNOLOGY_OTHER; 6724 level = cellSignalStrength.getLevel(); 6725 } 6726 6727 // According to SignalStrength#getCellSignalStrengths(), multiple of the same 6728 // cellSignalStrength can be present. Just take the highest level one for each RAT. 6729 if (perRatSignalStrength.get(ratType, -1) < level) { 6730 perRatSignalStrength.put(ratType, level); 6731 } 6732 } 6733 6734 notePhoneSignalStrengthLocked(overallSignalStrength, perRatSignalStrength, 6735 elapsedRealtimeMs, uptimeMs); 6736 } 6737 6738 /** 6739 * Note phone signal strength change, including per RAT signal strength. 6740 * 6741 * @param signalStrength overall signal strength {@see SignalStrength#getLevel()} 6742 * @param perRatSignalStrength signal strength of available RATs 6743 */ 6744 @GuardedBy("this") notePhoneSignalStrengthLocked(int signalStrength, SparseIntArray perRatSignalStrength)6745 public void notePhoneSignalStrengthLocked(int signalStrength, 6746 SparseIntArray perRatSignalStrength) { 6747 notePhoneSignalStrengthLocked(signalStrength, perRatSignalStrength, 6748 mClock.elapsedRealtime(), mClock.uptimeMillis()); 6749 } 6750 6751 /** 6752 * Note phone signal strength change, including per RAT signal strength. 6753 * 6754 * @param signalStrength overall signal strength {@see SignalStrength#getLevel()} 6755 * @param perRatSignalStrength signal strength of available RATs 6756 */ 6757 @GuardedBy("this") notePhoneSignalStrengthLocked(int signalStrength, SparseIntArray perRatSignalStrength, long elapsedRealtimeMs, long uptimeMs)6758 public void notePhoneSignalStrengthLocked(int signalStrength, 6759 SparseIntArray perRatSignalStrength, 6760 long elapsedRealtimeMs, long uptimeMs) { 6761 // Note each RAT's signal strength. 6762 final int size = perRatSignalStrength.size(); 6763 for (int i = 0; i < size; i++) { 6764 final int rat = perRatSignalStrength.keyAt(i); 6765 final int ratSignalStrength = perRatSignalStrength.valueAt(i); 6766 getRatBatteryStatsLocked(rat).noteSignalStrength(ratSignalStrength, elapsedRealtimeMs); 6767 } 6768 updateAllPhoneStateLocked(mPhoneServiceStateRaw, mPhoneSimStateRaw, signalStrength, 6769 elapsedRealtimeMs, uptimeMs); 6770 } 6771 6772 @UnsupportedAppUsage 6773 @GuardedBy("this") notePhoneDataConnectionStateLocked(@etworkType int dataType, boolean hasData, @RegState int serviceType, @ServiceState.FrequencyRange int nrFrequency)6774 public void notePhoneDataConnectionStateLocked(@NetworkType int dataType, boolean hasData, 6775 @RegState int serviceType, @ServiceState.FrequencyRange int nrFrequency) { 6776 notePhoneDataConnectionStateLocked(dataType, hasData, serviceType, nrFrequency, 6777 mClock.elapsedRealtime(), mClock.uptimeMillis()); 6778 } 6779 6780 @GuardedBy("this") notePhoneDataConnectionStateLocked(@etworkType int dataType, boolean hasData, @RegState int serviceType, @ServiceState.FrequencyRange int nrFrequency, long elapsedRealtimeMs, long uptimeMs)6781 public void notePhoneDataConnectionStateLocked(@NetworkType int dataType, boolean hasData, 6782 @RegState int serviceType, @ServiceState.FrequencyRange int nrFrequency, 6783 long elapsedRealtimeMs, long uptimeMs) { 6784 // BatteryStats uses 0 to represent no network type. 6785 // Telephony does not have a concept of no network type, and uses 0 to represent unknown. 6786 // Unknown is included in DATA_CONNECTION_OTHER. 6787 int bin = DATA_CONNECTION_OUT_OF_SERVICE; 6788 if (hasData) { 6789 if (dataType > 0 && dataType <= TelephonyManager.getAllNetworkTypes().length) { 6790 bin = dataType; 6791 } else { 6792 switch (serviceType) { 6793 case ServiceState.STATE_OUT_OF_SERVICE: 6794 bin = DATA_CONNECTION_OUT_OF_SERVICE; 6795 break; 6796 case ServiceState.STATE_EMERGENCY_ONLY: 6797 bin = DATA_CONNECTION_EMERGENCY_SERVICE; 6798 break; 6799 default: 6800 bin = DATA_CONNECTION_OTHER; 6801 break; 6802 } 6803 } 6804 } 6805 6806 final int newRat = mapNetworkTypeToRadioAccessTechnology(bin); 6807 if (newRat == RADIO_ACCESS_TECHNOLOGY_NR) { 6808 // Note possible frequency change for the NR RAT. 6809 getRatBatteryStatsLocked(newRat).noteFrequencyRange(nrFrequency, elapsedRealtimeMs); 6810 } 6811 6812 if (DEBUG) Log.i(TAG, "Phone Data Connection -> " + dataType + " = " + hasData); 6813 if (mPhoneDataConnectionType != bin) { 6814 mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_DATA_CONNECTION_MASK) 6815 | (bin << HistoryItem.STATE_DATA_CONNECTION_SHIFT); 6816 if (DEBUG_HISTORY) Slog.v(TAG, "Data connection " + bin + " to: " 6817 + Integer.toHexString(mHistoryCur.states)); 6818 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 6819 if (mPhoneDataConnectionType >= 0) { 6820 mPhoneDataConnectionsTimer[mPhoneDataConnectionType].stopRunningLocked( 6821 elapsedRealtimeMs); 6822 } 6823 mPhoneDataConnectionType = bin; 6824 mPhoneDataConnectionsTimer[bin].startRunningLocked(elapsedRealtimeMs); 6825 6826 if (mActiveRat != newRat) { 6827 getRatBatteryStatsLocked(mActiveRat).noteActive(false, elapsedRealtimeMs); 6828 mActiveRat = newRat; 6829 } 6830 final boolean modemActive = mMobileRadioActiveTimer.isRunningLocked(); 6831 getRatBatteryStatsLocked(newRat).noteActive(modemActive, elapsedRealtimeMs); 6832 } 6833 } 6834 6835 @RadioAccessTechnology mapNetworkTypeToRadioAccessTechnology(@etworkType int dataType)6836 private static int mapNetworkTypeToRadioAccessTechnology(@NetworkType int dataType) { 6837 switch (dataType) { 6838 case TelephonyManager.NETWORK_TYPE_NR: 6839 return RADIO_ACCESS_TECHNOLOGY_NR; 6840 case TelephonyManager.NETWORK_TYPE_LTE: 6841 return RADIO_ACCESS_TECHNOLOGY_LTE; 6842 case TelephonyManager.NETWORK_TYPE_UNKNOWN: //fallthrough 6843 case TelephonyManager.NETWORK_TYPE_GPRS: //fallthrough 6844 case TelephonyManager.NETWORK_TYPE_EDGE: //fallthrough 6845 case TelephonyManager.NETWORK_TYPE_UMTS: //fallthrough 6846 case TelephonyManager.NETWORK_TYPE_CDMA: //fallthrough 6847 case TelephonyManager.NETWORK_TYPE_EVDO_0: //fallthrough 6848 case TelephonyManager.NETWORK_TYPE_EVDO_A: //fallthrough 6849 case TelephonyManager.NETWORK_TYPE_1xRTT: //fallthrough 6850 case TelephonyManager.NETWORK_TYPE_HSDPA: //fallthrough 6851 case TelephonyManager.NETWORK_TYPE_HSUPA: //fallthrough 6852 case TelephonyManager.NETWORK_TYPE_HSPA: //fallthrough 6853 case TelephonyManager.NETWORK_TYPE_IDEN: //fallthrough 6854 case TelephonyManager.NETWORK_TYPE_EVDO_B: //fallthrough 6855 case TelephonyManager.NETWORK_TYPE_EHRPD: //fallthrough 6856 case TelephonyManager.NETWORK_TYPE_HSPAP: //fallthrough 6857 case TelephonyManager.NETWORK_TYPE_GSM: //fallthrough 6858 case TelephonyManager.NETWORK_TYPE_TD_SCDMA: //fallthrough 6859 case TelephonyManager.NETWORK_TYPE_IWLAN: //fallthrough 6860 return RADIO_ACCESS_TECHNOLOGY_OTHER; 6861 default: 6862 Slog.w(TAG, "Unhandled NetworkType (" + dataType + "), mapping to OTHER"); 6863 return RADIO_ACCESS_TECHNOLOGY_OTHER; 6864 } 6865 } 6866 6867 @RadioAccessTechnology mapRadioAccessNetworkTypeToRadioAccessTechnology( @ccessNetworkConstants.RadioAccessNetworkType int dataType)6868 private static int mapRadioAccessNetworkTypeToRadioAccessTechnology( 6869 @AccessNetworkConstants.RadioAccessNetworkType int dataType) { 6870 switch (dataType) { 6871 case AccessNetworkConstants.AccessNetworkType.NGRAN: 6872 return RADIO_ACCESS_TECHNOLOGY_NR; 6873 case AccessNetworkConstants.AccessNetworkType.EUTRAN: 6874 return RADIO_ACCESS_TECHNOLOGY_LTE; 6875 case AccessNetworkConstants.AccessNetworkType.UNKNOWN: //fallthrough 6876 case AccessNetworkConstants.AccessNetworkType.GERAN: //fallthrough 6877 case AccessNetworkConstants.AccessNetworkType.UTRAN: //fallthrough 6878 case AccessNetworkConstants.AccessNetworkType.CDMA2000: //fallthrough 6879 case AccessNetworkConstants.AccessNetworkType.IWLAN: 6880 return RADIO_ACCESS_TECHNOLOGY_OTHER; 6881 default: 6882 Slog.w(TAG, 6883 "Unhandled RadioAccessNetworkType (" + dataType + "), mapping to OTHER"); 6884 return RADIO_ACCESS_TECHNOLOGY_OTHER; 6885 } 6886 } 6887 6888 @GuardedBy("this") noteWifiOnLocked()6889 public void noteWifiOnLocked() { 6890 noteWifiOnLocked(mClock.elapsedRealtime(), mClock.uptimeMillis()); 6891 } 6892 6893 @GuardedBy("this") noteWifiOnLocked(long elapsedRealtimeMs, long uptimeMs)6894 public void noteWifiOnLocked(long elapsedRealtimeMs, long uptimeMs) { 6895 if (!mWifiOn) { 6896 mHistoryCur.states2 |= HistoryItem.STATE2_WIFI_ON_FLAG; 6897 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI on to: " 6898 + Integer.toHexString(mHistoryCur.states)); 6899 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 6900 mWifiOn = true; 6901 mWifiOnTimer.startRunningLocked(elapsedRealtimeMs); 6902 scheduleSyncExternalStatsLocked("wifi-off", ExternalStatsSync.UPDATE_WIFI); 6903 } 6904 } 6905 6906 @GuardedBy("this") noteWifiOffLocked()6907 public void noteWifiOffLocked() { 6908 noteWifiOffLocked(mClock.elapsedRealtime(), mClock.uptimeMillis()); 6909 } 6910 6911 @GuardedBy("this") noteWifiOffLocked(long elapsedRealtimeMs, long uptimeMs)6912 public void noteWifiOffLocked(long elapsedRealtimeMs, long uptimeMs) { 6913 if (mWifiOn) { 6914 mHistoryCur.states2 &= ~HistoryItem.STATE2_WIFI_ON_FLAG; 6915 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI off to: " 6916 + Integer.toHexString(mHistoryCur.states)); 6917 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 6918 mWifiOn = false; 6919 mWifiOnTimer.stopRunningLocked(elapsedRealtimeMs); 6920 scheduleSyncExternalStatsLocked("wifi-on", ExternalStatsSync.UPDATE_WIFI); 6921 } 6922 } 6923 6924 @UnsupportedAppUsage 6925 @GuardedBy("this") noteAudioOnLocked(int uid)6926 public void noteAudioOnLocked(int uid) { 6927 noteAudioOnLocked(uid, mClock.elapsedRealtime(), mClock.uptimeMillis()); 6928 } 6929 6930 @GuardedBy("this") noteAudioOnLocked(int uid, long elapsedRealtimeMs, long uptimeMs)6931 public void noteAudioOnLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 6932 uid = mapUid(uid); 6933 if (mAudioOnNesting == 0) { 6934 mHistoryCur.states |= HistoryItem.STATE_AUDIO_ON_FLAG; 6935 if (DEBUG_HISTORY) Slog.v(TAG, "Audio on to: " 6936 + Integer.toHexString(mHistoryCur.states)); 6937 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 6938 mAudioOnTimer.startRunningLocked(elapsedRealtimeMs); 6939 } 6940 mAudioOnNesting++; 6941 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6942 .noteAudioTurnedOnLocked(elapsedRealtimeMs); 6943 } 6944 6945 @UnsupportedAppUsage 6946 @GuardedBy("this") noteAudioOffLocked(int uid)6947 public void noteAudioOffLocked(int uid) { 6948 noteAudioOffLocked(uid, mClock.elapsedRealtime(), mClock.uptimeMillis()); 6949 } 6950 6951 @GuardedBy("this") noteAudioOffLocked(int uid, long elapsedRealtimeMs, long uptimeMs)6952 public void noteAudioOffLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 6953 if (mAudioOnNesting == 0) { 6954 return; 6955 } 6956 uid = mapUid(uid); 6957 if (--mAudioOnNesting == 0) { 6958 mHistoryCur.states &= ~HistoryItem.STATE_AUDIO_ON_FLAG; 6959 if (DEBUG_HISTORY) Slog.v(TAG, "Audio off to: " 6960 + Integer.toHexString(mHistoryCur.states)); 6961 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 6962 mAudioOnTimer.stopRunningLocked(elapsedRealtimeMs); 6963 } 6964 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6965 .noteAudioTurnedOffLocked(elapsedRealtimeMs); 6966 } 6967 6968 @UnsupportedAppUsage 6969 @GuardedBy("this") noteVideoOnLocked(int uid)6970 public void noteVideoOnLocked(int uid) { 6971 noteVideoOnLocked(uid, mClock.elapsedRealtime(), mClock.uptimeMillis()); 6972 } 6973 6974 @GuardedBy("this") noteVideoOnLocked(int uid, long elapsedRealtimeMs, long uptimeMs)6975 public void noteVideoOnLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 6976 uid = mapUid(uid); 6977 if (mVideoOnNesting == 0) { 6978 mHistoryCur.states2 |= HistoryItem.STATE2_VIDEO_ON_FLAG; 6979 if (DEBUG_HISTORY) Slog.v(TAG, "Video on to: " 6980 + Integer.toHexString(mHistoryCur.states)); 6981 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 6982 mVideoOnTimer.startRunningLocked(elapsedRealtimeMs); 6983 } 6984 mVideoOnNesting++; 6985 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6986 .noteVideoTurnedOnLocked(elapsedRealtimeMs); 6987 } 6988 6989 @UnsupportedAppUsage 6990 @GuardedBy("this") noteVideoOffLocked(int uid)6991 public void noteVideoOffLocked(int uid) { 6992 noteVideoOffLocked(uid, mClock.elapsedRealtime(), mClock.uptimeMillis()); 6993 } 6994 6995 @GuardedBy("this") noteVideoOffLocked(int uid, long elapsedRealtimeMs, long uptimeMs)6996 public void noteVideoOffLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 6997 if (mVideoOnNesting == 0) { 6998 return; 6999 } 7000 uid = mapUid(uid); 7001 if (--mVideoOnNesting == 0) { 7002 mHistoryCur.states2 &= ~HistoryItem.STATE2_VIDEO_ON_FLAG; 7003 if (DEBUG_HISTORY) Slog.v(TAG, "Video off to: " 7004 + Integer.toHexString(mHistoryCur.states)); 7005 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 7006 mVideoOnTimer.stopRunningLocked(elapsedRealtimeMs); 7007 } 7008 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 7009 .noteVideoTurnedOffLocked(elapsedRealtimeMs); 7010 } 7011 7012 @GuardedBy("this") noteResetAudioLocked()7013 public void noteResetAudioLocked() { 7014 noteResetAudioLocked(mClock.elapsedRealtime(), mClock.uptimeMillis()); 7015 } 7016 7017 @GuardedBy("this") noteResetAudioLocked(long elapsedRealtimeMs, long uptimeMs)7018 public void noteResetAudioLocked(long elapsedRealtimeMs, long uptimeMs) { 7019 if (mAudioOnNesting > 0) { 7020 mAudioOnNesting = 0; 7021 mHistoryCur.states &= ~HistoryItem.STATE_AUDIO_ON_FLAG; 7022 if (DEBUG_HISTORY) Slog.v(TAG, "Audio off to: " 7023 + Integer.toHexString(mHistoryCur.states)); 7024 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 7025 mAudioOnTimer.stopAllRunningLocked(elapsedRealtimeMs); 7026 for (int i=0; i<mUidStats.size(); i++) { 7027 BatteryStatsImpl.Uid uid = mUidStats.valueAt(i); 7028 uid.noteResetAudioLocked(elapsedRealtimeMs); 7029 } 7030 } 7031 } 7032 7033 @GuardedBy("this") noteResetVideoLocked()7034 public void noteResetVideoLocked() { 7035 noteResetVideoLocked(mClock.elapsedRealtime(), mClock.uptimeMillis()); 7036 } 7037 7038 @GuardedBy("this") noteResetVideoLocked(long elapsedRealtimeMs, long uptimeMs)7039 public void noteResetVideoLocked(long elapsedRealtimeMs, long uptimeMs) { 7040 if (mVideoOnNesting > 0) { 7041 mVideoOnNesting = 0; 7042 mHistoryCur.states2 &= ~HistoryItem.STATE2_VIDEO_ON_FLAG; 7043 if (DEBUG_HISTORY) Slog.v(TAG, "Video off to: " 7044 + Integer.toHexString(mHistoryCur.states)); 7045 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 7046 mVideoOnTimer.stopAllRunningLocked(elapsedRealtimeMs); 7047 for (int i=0; i<mUidStats.size(); i++) { 7048 BatteryStatsImpl.Uid uid = mUidStats.valueAt(i); 7049 uid.noteResetVideoLocked(elapsedRealtimeMs); 7050 } 7051 } 7052 } 7053 7054 @GuardedBy("this") noteActivityResumedLocked(int uid)7055 public void noteActivityResumedLocked(int uid) { 7056 noteActivityResumedLocked(uid, mClock.elapsedRealtime(), mClock.uptimeMillis()); 7057 } 7058 7059 @GuardedBy("this") noteActivityResumedLocked(int uid, long elapsedRealtimeMs, long uptimeMs)7060 public void noteActivityResumedLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 7061 uid = mapUid(uid); 7062 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 7063 .noteActivityResumedLocked(elapsedRealtimeMs); 7064 } 7065 7066 @GuardedBy("this") noteActivityPausedLocked(int uid)7067 public void noteActivityPausedLocked(int uid) { 7068 noteActivityPausedLocked(uid, mClock.elapsedRealtime(), mClock.uptimeMillis()); 7069 } 7070 7071 @GuardedBy("this") noteActivityPausedLocked(int uid, long elapsedRealtimeMs, long uptimeMs)7072 public void noteActivityPausedLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 7073 uid = mapUid(uid); 7074 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 7075 .noteActivityPausedLocked(elapsedRealtimeMs); 7076 } 7077 7078 @GuardedBy("this") noteVibratorOnLocked(int uid, long durationMillis)7079 public void noteVibratorOnLocked(int uid, long durationMillis) { 7080 noteVibratorOnLocked(uid, durationMillis, 7081 mClock.elapsedRealtime(), mClock.uptimeMillis()); 7082 } 7083 7084 @GuardedBy("this") noteVibratorOnLocked(int uid, long durationMillis, long elapsedRealtimeMs, long uptimeMs)7085 public void noteVibratorOnLocked(int uid, long durationMillis, 7086 long elapsedRealtimeMs, long uptimeMs) { 7087 uid = mapUid(uid); 7088 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 7089 .noteVibratorOnLocked(durationMillis, elapsedRealtimeMs); 7090 } 7091 7092 @GuardedBy("this") noteVibratorOffLocked(int uid)7093 public void noteVibratorOffLocked(int uid) { 7094 noteVibratorOffLocked(uid, mClock.elapsedRealtime(), mClock.uptimeMillis()); 7095 } 7096 7097 @GuardedBy("this") noteVibratorOffLocked(int uid, long elapsedRealtimeMs, long uptimeMs)7098 public void noteVibratorOffLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 7099 uid = mapUid(uid); 7100 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 7101 .noteVibratorOffLocked(elapsedRealtimeMs); 7102 } 7103 7104 @GuardedBy("this") noteFlashlightOnLocked(int uid)7105 public void noteFlashlightOnLocked(int uid) { 7106 noteFlashlightOnLocked(uid, mClock.elapsedRealtime(), mClock.uptimeMillis()); 7107 } 7108 7109 @GuardedBy("this") noteFlashlightOnLocked(int uid, long elapsedRealtimeMs, long uptimeMs)7110 public void noteFlashlightOnLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 7111 uid = mapUid(uid); 7112 if (mFlashlightOnNesting++ == 0) { 7113 mHistoryCur.states2 |= HistoryItem.STATE2_FLASHLIGHT_FLAG; 7114 if (DEBUG_HISTORY) Slog.v(TAG, "Flashlight on to: " 7115 + Integer.toHexString(mHistoryCur.states2)); 7116 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 7117 mFlashlightOnTimer.startRunningLocked(elapsedRealtimeMs); 7118 } 7119 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 7120 .noteFlashlightTurnedOnLocked(elapsedRealtimeMs); 7121 } 7122 7123 @GuardedBy("this") noteFlashlightOffLocked(int uid)7124 public void noteFlashlightOffLocked(int uid) { 7125 noteFlashlightOffLocked(uid, mClock.elapsedRealtime(), mClock.uptimeMillis()); 7126 } 7127 7128 @GuardedBy("this") noteFlashlightOffLocked(int uid, long elapsedRealtimeMs, long uptimeMs)7129 public void noteFlashlightOffLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 7130 if (mFlashlightOnNesting == 0) { 7131 return; 7132 } 7133 uid = mapUid(uid); 7134 if (--mFlashlightOnNesting == 0) { 7135 mHistoryCur.states2 &= ~HistoryItem.STATE2_FLASHLIGHT_FLAG; 7136 if (DEBUG_HISTORY) Slog.v(TAG, "Flashlight off to: " 7137 + Integer.toHexString(mHistoryCur.states2)); 7138 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 7139 mFlashlightOnTimer.stopRunningLocked(elapsedRealtimeMs); 7140 } 7141 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 7142 .noteFlashlightTurnedOffLocked(elapsedRealtimeMs); 7143 } 7144 7145 @GuardedBy("this") noteCameraOnLocked(int uid)7146 public void noteCameraOnLocked(int uid) { 7147 noteCameraOnLocked(uid, mClock.elapsedRealtime(), mClock.uptimeMillis()); 7148 } 7149 7150 @GuardedBy("this") noteCameraOnLocked(int uid, long elapsedRealtimeMs, long uptimeMs)7151 public void noteCameraOnLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 7152 uid = mapUid(uid); 7153 if (mCameraOnNesting++ == 0) { 7154 mHistoryCur.states2 |= HistoryItem.STATE2_CAMERA_FLAG; 7155 if (DEBUG_HISTORY) Slog.v(TAG, "Camera on to: " 7156 + Integer.toHexString(mHistoryCur.states2)); 7157 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 7158 mCameraOnTimer.startRunningLocked(elapsedRealtimeMs); 7159 } 7160 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 7161 .noteCameraTurnedOnLocked(elapsedRealtimeMs); 7162 } 7163 7164 @GuardedBy("this") noteCameraOffLocked(int uid)7165 public void noteCameraOffLocked(int uid) { 7166 noteCameraOffLocked(uid, mClock.elapsedRealtime(), mClock.uptimeMillis()); 7167 } 7168 7169 @GuardedBy("this") noteCameraOffLocked(int uid, long elapsedRealtimeMs, long uptimeMs)7170 public void noteCameraOffLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 7171 if (mCameraOnNesting == 0) { 7172 return; 7173 } 7174 uid = mapUid(uid); 7175 if (--mCameraOnNesting == 0) { 7176 mHistoryCur.states2 &= ~HistoryItem.STATE2_CAMERA_FLAG; 7177 if (DEBUG_HISTORY) Slog.v(TAG, "Camera off to: " 7178 + Integer.toHexString(mHistoryCur.states2)); 7179 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 7180 mCameraOnTimer.stopRunningLocked(elapsedRealtimeMs); 7181 } 7182 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 7183 .noteCameraTurnedOffLocked(elapsedRealtimeMs); 7184 } 7185 7186 @GuardedBy("this") noteResetCameraLocked()7187 public void noteResetCameraLocked() { 7188 noteResetCameraLocked(mClock.elapsedRealtime(), mClock.uptimeMillis()); 7189 } 7190 7191 @GuardedBy("this") noteResetCameraLocked(long elapsedRealtimeMs, long uptimeMs)7192 public void noteResetCameraLocked(long elapsedRealtimeMs, long uptimeMs) { 7193 if (mCameraOnNesting > 0) { 7194 mCameraOnNesting = 0; 7195 mHistoryCur.states2 &= ~HistoryItem.STATE2_CAMERA_FLAG; 7196 if (DEBUG_HISTORY) Slog.v(TAG, "Camera off to: " 7197 + Integer.toHexString(mHistoryCur.states2)); 7198 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 7199 mCameraOnTimer.stopAllRunningLocked(elapsedRealtimeMs); 7200 for (int i=0; i<mUidStats.size(); i++) { 7201 BatteryStatsImpl.Uid uid = mUidStats.valueAt(i); 7202 uid.noteResetCameraLocked(elapsedRealtimeMs); 7203 } 7204 } 7205 } 7206 7207 @GuardedBy("this") noteResetFlashlightLocked()7208 public void noteResetFlashlightLocked() { 7209 noteResetFlashlightLocked(mClock.elapsedRealtime(), mClock.uptimeMillis()); 7210 } 7211 7212 @GuardedBy("this") noteResetFlashlightLocked(long elapsedRealtimeMs, long uptimeMs)7213 public void noteResetFlashlightLocked(long elapsedRealtimeMs, long uptimeMs) { 7214 if (mFlashlightOnNesting > 0) { 7215 mFlashlightOnNesting = 0; 7216 mHistoryCur.states2 &= ~HistoryItem.STATE2_FLASHLIGHT_FLAG; 7217 if (DEBUG_HISTORY) Slog.v(TAG, "Flashlight off to: " 7218 + Integer.toHexString(mHistoryCur.states2)); 7219 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 7220 mFlashlightOnTimer.stopAllRunningLocked(elapsedRealtimeMs); 7221 for (int i=0; i<mUidStats.size(); i++) { 7222 BatteryStatsImpl.Uid uid = mUidStats.valueAt(i); 7223 uid.noteResetFlashlightLocked(elapsedRealtimeMs); 7224 } 7225 } 7226 } 7227 7228 @GuardedBy("this") noteBluetoothScanStartedLocked(WorkChain workChain, int uid, boolean isUnoptimized, long elapsedRealtimeMs, long uptimeMs)7229 private void noteBluetoothScanStartedLocked(WorkChain workChain, int uid, 7230 boolean isUnoptimized, long elapsedRealtimeMs, long uptimeMs) { 7231 if (workChain != null) { 7232 uid = workChain.getAttributionUid(); 7233 } 7234 uid = mapUid(uid); 7235 if (mBluetoothScanNesting == 0) { 7236 mHistoryCur.states2 |= HistoryItem.STATE2_BLUETOOTH_SCAN_FLAG; 7237 if (DEBUG_HISTORY) Slog.v(TAG, "BLE scan started for: " 7238 + Integer.toHexString(mHistoryCur.states2)); 7239 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 7240 mBluetoothScanTimer.startRunningLocked(elapsedRealtimeMs); 7241 } 7242 mBluetoothScanNesting++; 7243 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 7244 .noteBluetoothScanStartedLocked(elapsedRealtimeMs, isUnoptimized); 7245 } 7246 7247 @GuardedBy("this") noteBluetoothScanStartedFromSourceLocked(WorkSource ws, boolean isUnoptimized)7248 public void noteBluetoothScanStartedFromSourceLocked(WorkSource ws, boolean isUnoptimized) { 7249 noteBluetoothScanStartedFromSourceLocked(ws, isUnoptimized, 7250 mClock.elapsedRealtime(), mClock.uptimeMillis()); 7251 } 7252 7253 @GuardedBy("this") noteBluetoothScanStartedFromSourceLocked(WorkSource ws, boolean isUnoptimized, long elapsedRealtimeMs, long uptimeMs)7254 public void noteBluetoothScanStartedFromSourceLocked(WorkSource ws, boolean isUnoptimized, 7255 long elapsedRealtimeMs, long uptimeMs) { 7256 final int N = ws.size(); 7257 for (int i = 0; i < N; i++) { 7258 noteBluetoothScanStartedLocked(null, ws.getUid(i), isUnoptimized, 7259 elapsedRealtimeMs, uptimeMs); 7260 } 7261 7262 final List<WorkChain> workChains = ws.getWorkChains(); 7263 if (workChains != null) { 7264 for (int i = 0; i < workChains.size(); ++i) { 7265 noteBluetoothScanStartedLocked(workChains.get(i), -1, isUnoptimized, 7266 elapsedRealtimeMs, uptimeMs); 7267 } 7268 } 7269 } 7270 7271 @GuardedBy("this") noteBluetoothScanStoppedLocked(WorkChain workChain, int uid, boolean isUnoptimized, long elapsedRealtimeMs, long uptimeMs)7272 private void noteBluetoothScanStoppedLocked(WorkChain workChain, int uid, 7273 boolean isUnoptimized, long elapsedRealtimeMs, long uptimeMs) { 7274 if (workChain != null) { 7275 uid = workChain.getAttributionUid(); 7276 } 7277 uid = mapUid(uid); 7278 mBluetoothScanNesting--; 7279 if (mBluetoothScanNesting == 0) { 7280 mHistoryCur.states2 &= ~HistoryItem.STATE2_BLUETOOTH_SCAN_FLAG; 7281 if (DEBUG_HISTORY) Slog.v(TAG, "BLE scan stopped for: " 7282 + Integer.toHexString(mHistoryCur.states2)); 7283 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 7284 mBluetoothScanTimer.stopRunningLocked(elapsedRealtimeMs); 7285 } 7286 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 7287 .noteBluetoothScanStoppedLocked(elapsedRealtimeMs, isUnoptimized); 7288 } 7289 7290 @GuardedBy("this") noteBluetoothScanStoppedFromSourceLocked(WorkSource ws, boolean isUnoptimized)7291 public void noteBluetoothScanStoppedFromSourceLocked(WorkSource ws, boolean isUnoptimized) { 7292 noteBluetoothScanStoppedFromSourceLocked(ws, isUnoptimized, 7293 mClock.elapsedRealtime(), mClock.uptimeMillis()); 7294 } 7295 7296 @GuardedBy("this") noteBluetoothScanStoppedFromSourceLocked(WorkSource ws, boolean isUnoptimized, long elapsedRealtimeMs, long uptimeMs)7297 public void noteBluetoothScanStoppedFromSourceLocked(WorkSource ws, boolean isUnoptimized, 7298 long elapsedRealtimeMs, long uptimeMs) { 7299 final int N = ws.size(); 7300 for (int i = 0; i < N; i++) { 7301 noteBluetoothScanStoppedLocked(null, ws.getUid(i), isUnoptimized, 7302 elapsedRealtimeMs, uptimeMs); 7303 } 7304 7305 final List<WorkChain> workChains = ws.getWorkChains(); 7306 if (workChains != null) { 7307 for (int i = 0; i < workChains.size(); ++i) { 7308 noteBluetoothScanStoppedLocked(workChains.get(i), -1, isUnoptimized, 7309 elapsedRealtimeMs, uptimeMs); 7310 } 7311 } 7312 } 7313 7314 @GuardedBy("this") noteResetBluetoothScanLocked()7315 public void noteResetBluetoothScanLocked() { 7316 noteResetBluetoothScanLocked(mClock.elapsedRealtime(), mClock.uptimeMillis()); 7317 } 7318 7319 @GuardedBy("this") noteResetBluetoothScanLocked(long elapsedRealtimeMs, long uptimeMs)7320 public void noteResetBluetoothScanLocked(long elapsedRealtimeMs, long uptimeMs) { 7321 if (mBluetoothScanNesting > 0) { 7322 mBluetoothScanNesting = 0; 7323 mHistoryCur.states2 &= ~HistoryItem.STATE2_BLUETOOTH_SCAN_FLAG; 7324 if (DEBUG_HISTORY) Slog.v(TAG, "BLE can stopped for: " 7325 + Integer.toHexString(mHistoryCur.states2)); 7326 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 7327 mBluetoothScanTimer.stopAllRunningLocked(elapsedRealtimeMs); 7328 for (int i=0; i<mUidStats.size(); i++) { 7329 BatteryStatsImpl.Uid uid = mUidStats.valueAt(i); 7330 uid.noteResetBluetoothScanLocked(elapsedRealtimeMs); 7331 } 7332 } 7333 } 7334 7335 @GuardedBy("this") noteBluetoothScanResultsFromSourceLocked(WorkSource ws, int numNewResults)7336 public void noteBluetoothScanResultsFromSourceLocked(WorkSource ws, int numNewResults) { 7337 noteBluetoothScanResultsFromSourceLocked(ws, numNewResults, 7338 mClock.elapsedRealtime(), mClock.uptimeMillis()); 7339 } 7340 7341 @GuardedBy("this") noteBluetoothScanResultsFromSourceLocked(WorkSource ws, int numNewResults, long elapsedRealtimeMs, long uptimeMs)7342 public void noteBluetoothScanResultsFromSourceLocked(WorkSource ws, int numNewResults, 7343 long elapsedRealtimeMs, long uptimeMs) { 7344 final int N = ws.size(); 7345 for (int i = 0; i < N; i++) { 7346 int uid = mapUid(ws.getUid(i)); 7347 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 7348 .noteBluetoothScanResultsLocked(numNewResults); 7349 } 7350 7351 final List<WorkChain> workChains = ws.getWorkChains(); 7352 if (workChains != null) { 7353 for (int i = 0; i < workChains.size(); ++i) { 7354 final WorkChain wc = workChains.get(i); 7355 int uid = mapUid(wc.getAttributionUid()); 7356 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 7357 .noteBluetoothScanResultsLocked(numNewResults); 7358 } 7359 } 7360 } 7361 7362 @GuardedBy("this") noteWifiRadioApWakeupLocked(final long elapsedRealtimeMillis, final long uptimeMillis, int uid)7363 private void noteWifiRadioApWakeupLocked(final long elapsedRealtimeMillis, 7364 final long uptimeMillis, int uid) { 7365 uid = mapUid(uid); 7366 addHistoryEventLocked(elapsedRealtimeMillis, uptimeMillis, HistoryItem.EVENT_WAKEUP_AP, "", 7367 uid); 7368 getUidStatsLocked(uid, elapsedRealtimeMillis, uptimeMillis).noteWifiRadioApWakeupLocked(); 7369 } 7370 7371 @GuardedBy("this") noteWifiRadioPowerState(int powerState, long timestampNs, int uid)7372 public void noteWifiRadioPowerState(int powerState, long timestampNs, int uid) { 7373 noteWifiRadioPowerState(powerState, timestampNs, uid, 7374 mClock.elapsedRealtime(), mClock.uptimeMillis()); 7375 } 7376 7377 @GuardedBy("this") noteWifiRadioPowerState(int powerState, long timestampNs, int uid, long elapsedRealtimeMs, long uptimeMs)7378 public void noteWifiRadioPowerState(int powerState, long timestampNs, int uid, 7379 long elapsedRealtimeMs, long uptimeMs) { 7380 if (mWifiRadioPowerState != powerState) { 7381 final boolean active = 7382 powerState == DataConnectionRealTimeInfo.DC_POWER_STATE_MEDIUM 7383 || powerState == DataConnectionRealTimeInfo.DC_POWER_STATE_HIGH; 7384 if (active) { 7385 if (uid > 0) { 7386 noteWifiRadioApWakeupLocked(elapsedRealtimeMs, uptimeMs, uid); 7387 } 7388 mHistoryCur.states |= HistoryItem.STATE_WIFI_RADIO_ACTIVE_FLAG; 7389 mWifiActiveTimer.startRunningLocked(elapsedRealtimeMs); 7390 } else { 7391 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_RADIO_ACTIVE_FLAG; 7392 mWifiActiveTimer.stopRunningLocked(timestampNs / (1000 * 1000)); 7393 } 7394 if (DEBUG_HISTORY) Slog.v(TAG, "Wifi network active " + active + " to: " 7395 + Integer.toHexString(mHistoryCur.states)); 7396 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 7397 mWifiRadioPowerState = powerState; 7398 } 7399 } 7400 7401 @GuardedBy("this") noteWifiRunningLocked(WorkSource ws)7402 public void noteWifiRunningLocked(WorkSource ws) { 7403 noteWifiRunningLocked(ws, mClock.elapsedRealtime(), mClock.uptimeMillis()); 7404 } 7405 7406 @GuardedBy("this") noteWifiRunningLocked(WorkSource ws, long elapsedRealtimeMs, long uptimeMs)7407 public void noteWifiRunningLocked(WorkSource ws, long elapsedRealtimeMs, long uptimeMs) { 7408 if (!mGlobalWifiRunning) { 7409 mHistoryCur.states2 |= HistoryItem.STATE2_WIFI_RUNNING_FLAG; 7410 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI running to: " 7411 + Integer.toHexString(mHistoryCur.states)); 7412 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 7413 mGlobalWifiRunning = true; 7414 mGlobalWifiRunningTimer.startRunningLocked(elapsedRealtimeMs); 7415 int N = ws.size(); 7416 for (int i=0; i<N; i++) { 7417 int uid = mapUid(ws.getUid(i)); 7418 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 7419 .noteWifiRunningLocked(elapsedRealtimeMs); 7420 } 7421 7422 List<WorkChain> workChains = ws.getWorkChains(); 7423 if (workChains != null) { 7424 for (int i = 0; i < workChains.size(); ++i) { 7425 int uid = mapUid(workChains.get(i).getAttributionUid()); 7426 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 7427 .noteWifiRunningLocked(elapsedRealtimeMs); 7428 } 7429 } 7430 7431 scheduleSyncExternalStatsLocked("wifi-running", ExternalStatsSync.UPDATE_WIFI); 7432 } else { 7433 Log.w(TAG, "noteWifiRunningLocked -- called while WIFI running"); 7434 } 7435 } 7436 7437 @GuardedBy("this") noteWifiRunningChangedLocked(WorkSource oldWs, WorkSource newWs)7438 public void noteWifiRunningChangedLocked(WorkSource oldWs, WorkSource newWs) { 7439 noteWifiRunningChangedLocked(oldWs, newWs, 7440 mClock.elapsedRealtime(), mClock.uptimeMillis()); 7441 } 7442 7443 @GuardedBy("this") noteWifiRunningChangedLocked(WorkSource oldWs, WorkSource newWs, long elapsedRealtimeMs, long uptimeMs)7444 public void noteWifiRunningChangedLocked(WorkSource oldWs, WorkSource newWs, 7445 long elapsedRealtimeMs, long uptimeMs) { 7446 if (mGlobalWifiRunning) { 7447 int N = oldWs.size(); 7448 for (int i=0; i<N; i++) { 7449 int uid = mapUid(oldWs.getUid(i)); 7450 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 7451 .noteWifiStoppedLocked(elapsedRealtimeMs); 7452 } 7453 7454 List<WorkChain> workChains = oldWs.getWorkChains(); 7455 if (workChains != null) { 7456 for (int i = 0; i < workChains.size(); ++i) { 7457 int uid = mapUid(workChains.get(i).getAttributionUid()); 7458 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 7459 .noteWifiStoppedLocked(elapsedRealtimeMs); 7460 } 7461 } 7462 7463 N = newWs.size(); 7464 for (int i=0; i<N; i++) { 7465 int uid = mapUid(newWs.getUid(i)); 7466 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 7467 .noteWifiRunningLocked(elapsedRealtimeMs); 7468 } 7469 7470 workChains = newWs.getWorkChains(); 7471 if (workChains != null) { 7472 for (int i = 0; i < workChains.size(); ++i) { 7473 int uid = mapUid(workChains.get(i).getAttributionUid()); 7474 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 7475 .noteWifiRunningLocked(elapsedRealtimeMs); 7476 } 7477 } 7478 } else { 7479 Log.w(TAG, "noteWifiRunningChangedLocked -- called while WIFI not running"); 7480 } 7481 } 7482 7483 @GuardedBy("this") noteWifiStoppedLocked(WorkSource ws)7484 public void noteWifiStoppedLocked(WorkSource ws) { 7485 noteWifiStoppedLocked(ws, mClock.elapsedRealtime(), mClock.uptimeMillis()); 7486 } 7487 7488 @GuardedBy("this") noteWifiStoppedLocked(WorkSource ws, long elapsedRealtimeMs, long uptimeMs)7489 public void noteWifiStoppedLocked(WorkSource ws, long elapsedRealtimeMs, long uptimeMs) { 7490 if (mGlobalWifiRunning) { 7491 mHistoryCur.states2 &= ~HistoryItem.STATE2_WIFI_RUNNING_FLAG; 7492 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI stopped to: " 7493 + Integer.toHexString(mHistoryCur.states)); 7494 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 7495 mGlobalWifiRunning = false; 7496 mGlobalWifiRunningTimer.stopRunningLocked(elapsedRealtimeMs); 7497 int N = ws.size(); 7498 for (int i=0; i<N; i++) { 7499 int uid = mapUid(ws.getUid(i)); 7500 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 7501 .noteWifiStoppedLocked(elapsedRealtimeMs); 7502 } 7503 7504 List<WorkChain> workChains = ws.getWorkChains(); 7505 if (workChains != null) { 7506 for (int i = 0; i < workChains.size(); ++i) { 7507 int uid = mapUid(workChains.get(i).getAttributionUid()); 7508 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 7509 .noteWifiStoppedLocked(elapsedRealtimeMs); 7510 } 7511 } 7512 7513 scheduleSyncExternalStatsLocked("wifi-stopped", ExternalStatsSync.UPDATE_WIFI); 7514 } else { 7515 Log.w(TAG, "noteWifiStoppedLocked -- called while WIFI not running"); 7516 } 7517 } 7518 7519 @GuardedBy("this") noteWifiStateLocked(int wifiState, String accessPoint)7520 public void noteWifiStateLocked(int wifiState, String accessPoint) { 7521 noteWifiStateLocked(wifiState, accessPoint, mClock.elapsedRealtime()); 7522 } 7523 7524 @GuardedBy("this") noteWifiStateLocked(int wifiState, String accessPoint, long elapsedRealtimeMs)7525 public void noteWifiStateLocked(int wifiState, String accessPoint, long elapsedRealtimeMs) { 7526 if (DEBUG) Log.i(TAG, "WiFi state -> " + wifiState); 7527 if (mWifiState != wifiState) { 7528 if (mWifiState >= 0) { 7529 mWifiStateTimer[mWifiState].stopRunningLocked(elapsedRealtimeMs); 7530 } 7531 mWifiState = wifiState; 7532 mWifiStateTimer[wifiState].startRunningLocked(elapsedRealtimeMs); 7533 scheduleSyncExternalStatsLocked("wifi-state", ExternalStatsSync.UPDATE_WIFI); 7534 } 7535 } 7536 7537 @GuardedBy("this") noteWifiSupplicantStateChangedLocked(int supplState, boolean failedAuth)7538 public void noteWifiSupplicantStateChangedLocked(int supplState, boolean failedAuth) { 7539 noteWifiSupplicantStateChangedLocked(supplState, failedAuth, 7540 mClock.elapsedRealtime(), mClock.uptimeMillis()); 7541 } 7542 7543 @GuardedBy("this") noteWifiSupplicantStateChangedLocked(int supplState, boolean failedAuth, long elapsedRealtimeMs, long uptimeMs)7544 public void noteWifiSupplicantStateChangedLocked(int supplState, boolean failedAuth, 7545 long elapsedRealtimeMs, long uptimeMs) { 7546 if (DEBUG) Log.i(TAG, "WiFi suppl state -> " + supplState); 7547 if (mWifiSupplState != supplState) { 7548 if (mWifiSupplState >= 0) { 7549 mWifiSupplStateTimer[mWifiSupplState].stopRunningLocked(elapsedRealtimeMs); 7550 } 7551 mWifiSupplState = supplState; 7552 mWifiSupplStateTimer[supplState].startRunningLocked(elapsedRealtimeMs); 7553 mHistoryCur.states2 = 7554 (mHistoryCur.states2&~HistoryItem.STATE2_WIFI_SUPPL_STATE_MASK) 7555 | (supplState << HistoryItem.STATE2_WIFI_SUPPL_STATE_SHIFT); 7556 if (DEBUG_HISTORY) Slog.v(TAG, "Wifi suppl state " + supplState + " to: " 7557 + Integer.toHexString(mHistoryCur.states2)); 7558 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 7559 } 7560 } 7561 7562 @GuardedBy("this") stopAllWifiSignalStrengthTimersLocked(int except, long elapsedRealtimeMs)7563 void stopAllWifiSignalStrengthTimersLocked(int except, long elapsedRealtimeMs) { 7564 for (int i = 0; i < NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { 7565 if (i == except) { 7566 continue; 7567 } 7568 while (mWifiSignalStrengthsTimer[i].isRunningLocked()) { 7569 mWifiSignalStrengthsTimer[i].stopRunningLocked(elapsedRealtimeMs); 7570 } 7571 } 7572 } 7573 7574 @GuardedBy("this") noteWifiRssiChangedLocked(int newRssi)7575 public void noteWifiRssiChangedLocked(int newRssi) { 7576 noteWifiRssiChangedLocked(newRssi, mClock.elapsedRealtime(), mClock.uptimeMillis()); 7577 } 7578 7579 @GuardedBy("this") noteWifiRssiChangedLocked(int newRssi, long elapsedRealtimeMs, long uptimeMs)7580 public void noteWifiRssiChangedLocked(int newRssi, long elapsedRealtimeMs, long uptimeMs) { 7581 int strengthBin = WifiManager.calculateSignalLevel(newRssi, NUM_WIFI_SIGNAL_STRENGTH_BINS); 7582 if (DEBUG) Log.i(TAG, "WiFi rssi -> " + newRssi + " bin=" + strengthBin); 7583 if (mWifiSignalStrengthBin != strengthBin) { 7584 if (mWifiSignalStrengthBin >= 0) { 7585 mWifiSignalStrengthsTimer[mWifiSignalStrengthBin].stopRunningLocked( 7586 elapsedRealtimeMs); 7587 } 7588 if (strengthBin >= 0) { 7589 if (!mWifiSignalStrengthsTimer[strengthBin].isRunningLocked()) { 7590 mWifiSignalStrengthsTimer[strengthBin].startRunningLocked(elapsedRealtimeMs); 7591 } 7592 mHistoryCur.states2 = 7593 (mHistoryCur.states2&~HistoryItem.STATE2_WIFI_SIGNAL_STRENGTH_MASK) 7594 | (strengthBin << HistoryItem.STATE2_WIFI_SIGNAL_STRENGTH_SHIFT); 7595 if (DEBUG_HISTORY) Slog.v(TAG, "Wifi signal strength " + strengthBin + " to: " 7596 + Integer.toHexString(mHistoryCur.states2)); 7597 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 7598 } else { 7599 stopAllWifiSignalStrengthTimersLocked(-1, elapsedRealtimeMs); 7600 } 7601 mWifiSignalStrengthBin = strengthBin; 7602 } 7603 } 7604 7605 int mWifiFullLockNesting = 0; 7606 7607 @UnsupportedAppUsage 7608 @GuardedBy("this") noteFullWifiLockAcquiredLocked(int uid)7609 public void noteFullWifiLockAcquiredLocked(int uid) { 7610 noteFullWifiLockAcquiredLocked(uid, mClock.elapsedRealtime(), mClock.uptimeMillis()); 7611 } 7612 7613 @GuardedBy("this") noteFullWifiLockAcquiredLocked(int uid, long elapsedRealtimeMs, long uptimeMs)7614 public void noteFullWifiLockAcquiredLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 7615 if (mWifiFullLockNesting == 0) { 7616 mHistoryCur.states |= HistoryItem.STATE_WIFI_FULL_LOCK_FLAG; 7617 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI full lock on to: " 7618 + Integer.toHexString(mHistoryCur.states)); 7619 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 7620 } 7621 mWifiFullLockNesting++; 7622 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 7623 .noteFullWifiLockAcquiredLocked(elapsedRealtimeMs); 7624 } 7625 7626 @UnsupportedAppUsage 7627 @GuardedBy("this") noteFullWifiLockReleasedLocked(int uid)7628 public void noteFullWifiLockReleasedLocked(int uid) { 7629 noteFullWifiLockReleasedLocked(uid, mClock.elapsedRealtime(), mClock.uptimeMillis()); 7630 } 7631 7632 @GuardedBy("this") noteFullWifiLockReleasedLocked(int uid, long elapsedRealtimeMs, long uptimeMs)7633 public void noteFullWifiLockReleasedLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 7634 mWifiFullLockNesting--; 7635 if (mWifiFullLockNesting == 0) { 7636 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_FULL_LOCK_FLAG; 7637 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI full lock off to: " 7638 + Integer.toHexString(mHistoryCur.states)); 7639 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 7640 } 7641 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 7642 .noteFullWifiLockReleasedLocked(elapsedRealtimeMs); 7643 } 7644 7645 int mWifiScanNesting = 0; 7646 7647 @GuardedBy("this") noteWifiScanStartedLocked(int uid)7648 public void noteWifiScanStartedLocked(int uid) { 7649 noteWifiScanStartedLocked(uid, mClock.elapsedRealtime(), mClock.uptimeMillis()); 7650 } 7651 7652 @GuardedBy("this") noteWifiScanStartedLocked(int uid, long elapsedRealtimeMs, long uptimeMs)7653 public void noteWifiScanStartedLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 7654 if (mWifiScanNesting == 0) { 7655 mHistoryCur.states |= HistoryItem.STATE_WIFI_SCAN_FLAG; 7656 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI scan started for: " 7657 + Integer.toHexString(mHistoryCur.states)); 7658 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 7659 } 7660 mWifiScanNesting++; 7661 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 7662 .noteWifiScanStartedLocked(elapsedRealtimeMs); 7663 } 7664 7665 @GuardedBy("this") noteWifiScanStoppedLocked(int uid)7666 public void noteWifiScanStoppedLocked(int uid) { 7667 noteWifiScanStoppedLocked(uid, mClock.elapsedRealtime(), mClock.uptimeMillis()); 7668 } 7669 7670 @GuardedBy("this") noteWifiScanStoppedLocked(int uid, long elapsedRealtimeMs, long uptimeMs)7671 public void noteWifiScanStoppedLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 7672 mWifiScanNesting--; 7673 if (mWifiScanNesting == 0) { 7674 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_SCAN_FLAG; 7675 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI scan stopped for: " 7676 + Integer.toHexString(mHistoryCur.states)); 7677 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 7678 } 7679 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 7680 .noteWifiScanStoppedLocked(elapsedRealtimeMs); 7681 } 7682 noteWifiBatchedScanStartedLocked(int uid, int csph)7683 public void noteWifiBatchedScanStartedLocked(int uid, int csph) { 7684 noteWifiBatchedScanStartedLocked(uid, csph, 7685 mClock.elapsedRealtime(), mClock.uptimeMillis()); 7686 } 7687 noteWifiBatchedScanStartedLocked(int uid, int csph, long elapsedRealtimeMs, long uptimeMs)7688 public void noteWifiBatchedScanStartedLocked(int uid, int csph, 7689 long elapsedRealtimeMs, long uptimeMs) { 7690 uid = mapUid(uid); 7691 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 7692 .noteWifiBatchedScanStartedLocked(csph, elapsedRealtimeMs); 7693 } 7694 noteWifiBatchedScanStoppedLocked(int uid)7695 public void noteWifiBatchedScanStoppedLocked(int uid) { 7696 noteWifiBatchedScanStoppedLocked(uid, mClock.elapsedRealtime(), mClock.uptimeMillis()); 7697 } 7698 noteWifiBatchedScanStoppedLocked(int uid, long elapsedRealtimeMs, long uptimeMs)7699 public void noteWifiBatchedScanStoppedLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 7700 uid = mapUid(uid); 7701 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 7702 .noteWifiBatchedScanStoppedLocked(elapsedRealtimeMs); 7703 } 7704 7705 int mWifiMulticastNesting = 0; 7706 7707 @GuardedBy("this") 7708 @UnsupportedAppUsage noteWifiMulticastEnabledLocked(int uid)7709 public void noteWifiMulticastEnabledLocked(int uid) { 7710 noteWifiMulticastEnabledLocked(uid, mClock.elapsedRealtime(), mClock.uptimeMillis()); 7711 } 7712 7713 @GuardedBy("this") noteWifiMulticastEnabledLocked(int uid, long elapsedRealtimeMs, long uptimeMs)7714 public void noteWifiMulticastEnabledLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 7715 uid = mapUid(uid); 7716 if (mWifiMulticastNesting == 0) { 7717 mHistoryCur.states |= HistoryItem.STATE_WIFI_MULTICAST_ON_FLAG; 7718 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI multicast on to: " 7719 + Integer.toHexString(mHistoryCur.states)); 7720 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 7721 7722 // Start Wifi Multicast overall timer 7723 if (!mWifiMulticastWakelockTimer.isRunningLocked()) { 7724 if (DEBUG_HISTORY) Slog.v(TAG, "WiFi Multicast Overall Timer Started"); 7725 mWifiMulticastWakelockTimer.startRunningLocked(elapsedRealtimeMs); 7726 } 7727 } 7728 mWifiMulticastNesting++; 7729 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 7730 .noteWifiMulticastEnabledLocked(elapsedRealtimeMs); 7731 } 7732 7733 @UnsupportedAppUsage 7734 @GuardedBy("this") noteWifiMulticastDisabledLocked(int uid)7735 public void noteWifiMulticastDisabledLocked(int uid) { 7736 noteWifiMulticastDisabledLocked(uid, mClock.elapsedRealtime(), mClock.uptimeMillis()); 7737 } 7738 7739 @GuardedBy("this") noteWifiMulticastDisabledLocked(int uid, long elapsedRealtimeMs, long uptimeMs)7740 public void noteWifiMulticastDisabledLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 7741 uid = mapUid(uid); 7742 mWifiMulticastNesting--; 7743 if (mWifiMulticastNesting == 0) { 7744 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_MULTICAST_ON_FLAG; 7745 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI multicast off to: " 7746 + Integer.toHexString(mHistoryCur.states)); 7747 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 7748 7749 // Stop Wifi Multicast overall timer 7750 if (mWifiMulticastWakelockTimer.isRunningLocked()) { 7751 if (DEBUG_HISTORY) Slog.v(TAG, "Multicast Overall Timer Stopped"); 7752 mWifiMulticastWakelockTimer.stopRunningLocked(elapsedRealtimeMs); 7753 } 7754 } 7755 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 7756 .noteWifiMulticastDisabledLocked(elapsedRealtimeMs); 7757 } 7758 7759 @GuardedBy("this") noteFullWifiLockAcquiredFromSourceLocked(WorkSource ws)7760 public void noteFullWifiLockAcquiredFromSourceLocked(WorkSource ws) { 7761 noteFullWifiLockAcquiredFromSourceLocked(ws, 7762 mClock.elapsedRealtime(), mClock.uptimeMillis()); 7763 } 7764 7765 @GuardedBy("this") noteFullWifiLockAcquiredFromSourceLocked(WorkSource ws, long elapsedRealtimeMs, long uptimeMs)7766 public void noteFullWifiLockAcquiredFromSourceLocked(WorkSource ws, 7767 long elapsedRealtimeMs, long uptimeMs) { 7768 int N = ws.size(); 7769 for (int i=0; i<N; i++) { 7770 final int uid = mapUid(ws.getUid(i)); 7771 noteFullWifiLockAcquiredLocked(uid, elapsedRealtimeMs, uptimeMs); 7772 } 7773 7774 final List<WorkChain> workChains = ws.getWorkChains(); 7775 if (workChains != null) { 7776 for (int i = 0; i < workChains.size(); ++i) { 7777 final WorkChain workChain = workChains.get(i); 7778 final int uid = mapUid(workChain.getAttributionUid()); 7779 noteFullWifiLockAcquiredLocked(uid, elapsedRealtimeMs, uptimeMs); 7780 } 7781 } 7782 } 7783 7784 @GuardedBy("this") noteFullWifiLockReleasedFromSourceLocked(WorkSource ws)7785 public void noteFullWifiLockReleasedFromSourceLocked(WorkSource ws) { 7786 noteFullWifiLockReleasedFromSourceLocked(ws, 7787 mClock.elapsedRealtime(), mClock.uptimeMillis()); 7788 } 7789 7790 @GuardedBy("this") noteFullWifiLockReleasedFromSourceLocked(WorkSource ws, long elapsedRealtimeMs, long uptimeMs)7791 public void noteFullWifiLockReleasedFromSourceLocked(WorkSource ws, 7792 long elapsedRealtimeMs, long uptimeMs) { 7793 int N = ws.size(); 7794 for (int i=0; i<N; i++) { 7795 final int uid = mapUid(ws.getUid(i)); 7796 noteFullWifiLockReleasedLocked(uid, elapsedRealtimeMs, uptimeMs); 7797 } 7798 7799 final List<WorkChain> workChains = ws.getWorkChains(); 7800 if (workChains != null) { 7801 for (int i = 0; i < workChains.size(); ++i) { 7802 final WorkChain workChain = workChains.get(i); 7803 final int uid = mapUid(workChain.getAttributionUid()); 7804 noteFullWifiLockReleasedLocked(uid, elapsedRealtimeMs, uptimeMs); 7805 } 7806 } 7807 } 7808 7809 @GuardedBy("this") noteWifiScanStartedFromSourceLocked(WorkSource ws)7810 public void noteWifiScanStartedFromSourceLocked(WorkSource ws) { 7811 noteWifiScanStartedFromSourceLocked(ws, mClock.elapsedRealtime(), mClock.uptimeMillis()); 7812 } 7813 7814 @GuardedBy("this") noteWifiScanStartedFromSourceLocked(WorkSource ws, long elapsedRealtimeMs, long uptimeMs)7815 public void noteWifiScanStartedFromSourceLocked(WorkSource ws, 7816 long elapsedRealtimeMs, long uptimeMs) { 7817 int N = ws.size(); 7818 for (int i=0; i<N; i++) { 7819 final int uid = mapUid(ws.getUid(i)); 7820 noteWifiScanStartedLocked(uid, elapsedRealtimeMs, uptimeMs); 7821 } 7822 7823 final List<WorkChain> workChains = ws.getWorkChains(); 7824 if (workChains != null) { 7825 for (int i = 0; i < workChains.size(); ++i) { 7826 final WorkChain workChain = workChains.get(i); 7827 final int uid = mapUid(workChain.getAttributionUid()); 7828 noteWifiScanStartedLocked(uid, elapsedRealtimeMs, uptimeMs); 7829 } 7830 } 7831 } 7832 7833 @GuardedBy("this") noteWifiScanStoppedFromSourceLocked(WorkSource ws)7834 public void noteWifiScanStoppedFromSourceLocked(WorkSource ws) { 7835 noteWifiScanStoppedFromSourceLocked(ws, mClock.elapsedRealtime(), mClock.uptimeMillis()); 7836 } 7837 7838 @GuardedBy("this") noteWifiScanStoppedFromSourceLocked(WorkSource ws, long elapsedRealtimeMs, long uptimeMs)7839 public void noteWifiScanStoppedFromSourceLocked(WorkSource ws, 7840 long elapsedRealtimeMs, long uptimeMs) { 7841 int N = ws.size(); 7842 for (int i=0; i<N; i++) { 7843 final int uid = mapUid(ws.getUid(i)); 7844 noteWifiScanStoppedLocked(uid, elapsedRealtimeMs, uptimeMs); 7845 } 7846 7847 final List<WorkChain> workChains = ws.getWorkChains(); 7848 if (workChains != null) { 7849 for (int i = 0; i < workChains.size(); ++i) { 7850 final WorkChain workChain = workChains.get(i); 7851 final int uid = mapUid(workChain.getAttributionUid()); 7852 noteWifiScanStoppedLocked(uid, elapsedRealtimeMs, uptimeMs); 7853 } 7854 } 7855 } 7856 7857 @GuardedBy("this") noteWifiBatchedScanStartedFromSourceLocked(WorkSource ws, int csph)7858 public void noteWifiBatchedScanStartedFromSourceLocked(WorkSource ws, int csph) { 7859 noteWifiBatchedScanStartedFromSourceLocked(ws, csph, 7860 mClock.elapsedRealtime(), mClock.uptimeMillis()); 7861 } 7862 7863 @GuardedBy("this") noteWifiBatchedScanStartedFromSourceLocked(WorkSource ws, int csph, long elapsedRealtimeMs, long uptimeMs)7864 public void noteWifiBatchedScanStartedFromSourceLocked(WorkSource ws, int csph, 7865 long elapsedRealtimeMs, long uptimeMs) { 7866 int N = ws.size(); 7867 for (int i=0; i<N; i++) { 7868 noteWifiBatchedScanStartedLocked(ws.getUid(i), csph, elapsedRealtimeMs, uptimeMs); 7869 } 7870 7871 final List<WorkChain> workChains = ws.getWorkChains(); 7872 if (workChains != null) { 7873 for (int i = 0; i < workChains.size(); ++i) { 7874 noteWifiBatchedScanStartedLocked(workChains.get(i).getAttributionUid(), csph, 7875 elapsedRealtimeMs, uptimeMs); 7876 } 7877 } 7878 } 7879 7880 @GuardedBy("this") noteWifiBatchedScanStoppedFromSourceLocked(WorkSource ws)7881 public void noteWifiBatchedScanStoppedFromSourceLocked(WorkSource ws) { 7882 noteWifiBatchedScanStoppedFromSourceLocked(ws, 7883 mClock.elapsedRealtime(), mClock.uptimeMillis()); 7884 } 7885 7886 @GuardedBy("this") noteWifiBatchedScanStoppedFromSourceLocked(WorkSource ws, long elapsedRealtimeMs, long uptimeMs)7887 public void noteWifiBatchedScanStoppedFromSourceLocked(WorkSource ws, 7888 long elapsedRealtimeMs, long uptimeMs) { 7889 int N = ws.size(); 7890 for (int i=0; i<N; i++) { 7891 noteWifiBatchedScanStoppedLocked(ws.getUid(i), elapsedRealtimeMs, uptimeMs); 7892 } 7893 7894 final List<WorkChain> workChains = ws.getWorkChains(); 7895 if (workChains != null) { 7896 for (int i = 0; i < workChains.size(); ++i) { 7897 noteWifiBatchedScanStoppedLocked(workChains.get(i).getAttributionUid(), 7898 elapsedRealtimeMs, uptimeMs); 7899 } 7900 } 7901 } 7902 includeInStringArray(String[] array, String str)7903 private static String[] includeInStringArray(String[] array, String str) { 7904 if (ArrayUtils.indexOf(array, str) >= 0) { 7905 return array; 7906 } 7907 String[] newArray = new String[array.length+1]; 7908 System.arraycopy(array, 0, newArray, 0, array.length); 7909 newArray[array.length] = str; 7910 return newArray; 7911 } 7912 excludeFromStringArray(String[] array, String str)7913 private static String[] excludeFromStringArray(String[] array, String str) { 7914 int index = ArrayUtils.indexOf(array, str); 7915 if (index >= 0) { 7916 String[] newArray = new String[array.length-1]; 7917 if (index > 0) { 7918 System.arraycopy(array, 0, newArray, 0, index); 7919 } 7920 if (index < array.length-1) { 7921 System.arraycopy(array, index+1, newArray, index, array.length-index-1); 7922 } 7923 return newArray; 7924 } 7925 return array; 7926 } 7927 7928 /** @hide */ noteNetworkInterfaceForTransports(String iface, int[] transportTypes)7929 public void noteNetworkInterfaceForTransports(String iface, int[] transportTypes) { 7930 if (TextUtils.isEmpty(iface)) return; 7931 final int displayTransport = NetworkCapabilitiesUtils.getDisplayTransport(transportTypes); 7932 7933 synchronized (mModemNetworkLock) { 7934 if (displayTransport == TRANSPORT_CELLULAR) { 7935 mModemIfaces = includeInStringArray(mModemIfaces, iface); 7936 if (DEBUG) Slog.d(TAG, "Note mobile iface " + iface + ": " + mModemIfaces); 7937 } else { 7938 mModemIfaces = excludeFromStringArray(mModemIfaces, iface); 7939 if (DEBUG) Slog.d(TAG, "Note non-mobile iface " + iface + ": " + mModemIfaces); 7940 } 7941 } 7942 7943 synchronized (mWifiNetworkLock) { 7944 if (displayTransport == TRANSPORT_WIFI) { 7945 mWifiIfaces = includeInStringArray(mWifiIfaces, iface); 7946 if (DEBUG) Slog.d(TAG, "Note wifi iface " + iface + ": " + mWifiIfaces); 7947 } else { 7948 mWifiIfaces = excludeFromStringArray(mWifiIfaces, iface); 7949 if (DEBUG) Slog.d(TAG, "Note non-wifi iface " + iface + ": " + mWifiIfaces); 7950 } 7951 } 7952 } 7953 7954 /** 7955 * Records timing data related to an incoming Binder call in order to attribute 7956 * the power consumption to the calling app. 7957 */ noteBinderCallStats(int workSourceUid, long incrementalCallCount, Collection<BinderCallsStats.CallStat> callStats)7958 public void noteBinderCallStats(int workSourceUid, long incrementalCallCount, 7959 Collection<BinderCallsStats.CallStat> callStats) { 7960 noteBinderCallStats(workSourceUid, incrementalCallCount, callStats, 7961 mClock.elapsedRealtime(), mClock.uptimeMillis()); 7962 } 7963 noteBinderCallStats(int workSourceUid, long incrementalCallCount, Collection<BinderCallsStats.CallStat> callStats, long elapsedRealtimeMs, long uptimeMs)7964 public void noteBinderCallStats(int workSourceUid, long incrementalCallCount, 7965 Collection<BinderCallsStats.CallStat> callStats, 7966 long elapsedRealtimeMs, long uptimeMs) { 7967 synchronized (this) { 7968 getUidStatsLocked(workSourceUid, elapsedRealtimeMs, uptimeMs) 7969 .noteBinderCallStatsLocked(incrementalCallCount, callStats); 7970 } 7971 } 7972 7973 /** 7974 * Takes note of native IDs of threads taking incoming binder calls. The CPU time 7975 * of these threads is attributed to the apps making those binder calls. 7976 */ noteBinderThreadNativeIds(int[] binderThreadNativeTids)7977 public void noteBinderThreadNativeIds(int[] binderThreadNativeTids) { 7978 mSystemServerCpuThreadReader.setBinderThreadNativeTids(binderThreadNativeTids); 7979 } 7980 7981 /** 7982 * Estimates the proportion of system server CPU activity handling incoming binder calls 7983 * that can be attributed to each app 7984 */ 7985 @VisibleForTesting updateSystemServiceCallStats()7986 public void updateSystemServiceCallStats() { 7987 // Start off by computing the average duration of recorded binder calls, 7988 // regardless of which binder or transaction. We will use this as a fallback 7989 // for calls that were not sampled at all. 7990 int totalRecordedCallCount = 0; 7991 long totalRecordedCallTimeMicros = 0; 7992 for (int i = 0; i < mUidStats.size(); i++) { 7993 Uid uid = mUidStats.valueAt(i); 7994 ArraySet<BinderCallStats> binderCallStats = uid.mBinderCallStats; 7995 for (int j = binderCallStats.size() - 1; j >= 0; j--) { 7996 BinderCallStats stats = binderCallStats.valueAt(j); 7997 totalRecordedCallCount += stats.recordedCallCount; 7998 totalRecordedCallTimeMicros += stats.recordedCpuTimeMicros; 7999 } 8000 } 8001 8002 long totalSystemServiceTimeMicros = 0; 8003 8004 // For every UID, use recorded durations of sampled binder calls to estimate 8005 // the total time the system server spent handling requests from this UID. 8006 for (int i = 0; i < mUidStats.size(); i++) { 8007 Uid uid = mUidStats.valueAt(i); 8008 8009 long totalTimeForUidUs = 0; 8010 int totalCallCountForUid = 0; 8011 ArraySet<BinderCallStats> binderCallStats = uid.mBinderCallStats; 8012 for (int j = binderCallStats.size() - 1; j >= 0; j--) { 8013 BinderCallStats stats = binderCallStats.valueAt(j); 8014 totalCallCountForUid += stats.callCount; 8015 if (stats.recordedCallCount > 0) { 8016 totalTimeForUidUs += 8017 stats.callCount * stats.recordedCpuTimeMicros / stats.recordedCallCount; 8018 } else if (totalRecordedCallCount > 0) { 8019 totalTimeForUidUs += 8020 stats.callCount * totalRecordedCallTimeMicros / totalRecordedCallCount; 8021 } 8022 } 8023 8024 if (totalCallCountForUid < uid.mBinderCallCount && totalRecordedCallCount > 0) { 8025 // Estimate remaining calls, which were not tracked because of binder call 8026 // stats sampling 8027 totalTimeForUidUs += 8028 (uid.mBinderCallCount - totalCallCountForUid) * totalRecordedCallTimeMicros 8029 / totalRecordedCallCount; 8030 } 8031 8032 uid.mSystemServiceTimeUs = totalTimeForUidUs; 8033 totalSystemServiceTimeMicros += totalTimeForUidUs; 8034 } 8035 8036 for (int i = 0; i < mUidStats.size(); i++) { 8037 Uid uid = mUidStats.valueAt(i); 8038 if (totalSystemServiceTimeMicros > 0) { 8039 uid.mProportionalSystemServiceUsage = 8040 (double) uid.mSystemServiceTimeUs / totalSystemServiceTimeMicros; 8041 } else { 8042 uid.mProportionalSystemServiceUsage = 0; 8043 } 8044 } 8045 } 8046 getWifiIfaces()8047 public String[] getWifiIfaces() { 8048 synchronized (mWifiNetworkLock) { 8049 return mWifiIfaces; 8050 } 8051 } 8052 getMobileIfaces()8053 public String[] getMobileIfaces() { 8054 synchronized (mModemNetworkLock) { 8055 return mModemIfaces; 8056 } 8057 } 8058 8059 @UnsupportedAppUsage getScreenOnTime(long elapsedRealtimeUs, int which)8060 @Override public long getScreenOnTime(long elapsedRealtimeUs, int which) { 8061 return mScreenOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 8062 } 8063 getScreenOnCount(int which)8064 @Override public int getScreenOnCount(int which) { 8065 return mScreenOnTimer.getCountLocked(which); 8066 } 8067 getScreenDozeTime(long elapsedRealtimeUs, int which)8068 @Override public long getScreenDozeTime(long elapsedRealtimeUs, int which) { 8069 return mScreenDozeTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 8070 } 8071 getScreenDozeCount(int which)8072 @Override public int getScreenDozeCount(int which) { 8073 return mScreenDozeTimer.getCountLocked(which); 8074 } 8075 8076 @UnsupportedAppUsage getScreenBrightnessTime(int brightnessBin, long elapsedRealtimeUs, int which)8077 @Override public long getScreenBrightnessTime(int brightnessBin, 8078 long elapsedRealtimeUs, int which) { 8079 return mScreenBrightnessTimer[brightnessBin].getTotalTimeLocked( 8080 elapsedRealtimeUs, which); 8081 } 8082 getScreenBrightnessTimer(int brightnessBin)8083 @Override public Timer getScreenBrightnessTimer(int brightnessBin) { 8084 return mScreenBrightnessTimer[brightnessBin]; 8085 } 8086 8087 @Override getDisplayCount()8088 public int getDisplayCount() { 8089 return mPerDisplayBatteryStats.length; 8090 } 8091 8092 @Override getDisplayScreenOnTime(int display, long elapsedRealtimeUs)8093 public long getDisplayScreenOnTime(int display, long elapsedRealtimeUs) { 8094 return mPerDisplayBatteryStats[display].screenOnTimer.getTotalTimeLocked(elapsedRealtimeUs, 8095 STATS_SINCE_CHARGED); 8096 } 8097 8098 @Override getDisplayScreenDozeTime(int display, long elapsedRealtimeUs)8099 public long getDisplayScreenDozeTime(int display, long elapsedRealtimeUs) { 8100 return mPerDisplayBatteryStats[display].screenDozeTimer.getTotalTimeLocked( 8101 elapsedRealtimeUs, STATS_SINCE_CHARGED); 8102 } 8103 8104 @Override getDisplayScreenBrightnessTime(int display, int brightnessBin, long elapsedRealtimeUs)8105 public long getDisplayScreenBrightnessTime(int display, int brightnessBin, 8106 long elapsedRealtimeUs) { 8107 final DisplayBatteryStats displayStats = mPerDisplayBatteryStats[display]; 8108 return displayStats.screenBrightnessTimers[brightnessBin].getTotalTimeLocked( 8109 elapsedRealtimeUs, STATS_SINCE_CHARGED); 8110 } 8111 getInteractiveTime(long elapsedRealtimeUs, int which)8112 @Override public long getInteractiveTime(long elapsedRealtimeUs, int which) { 8113 return mInteractiveTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 8114 } 8115 getPowerSaveModeEnabledTime(long elapsedRealtimeUs, int which)8116 @Override public long getPowerSaveModeEnabledTime(long elapsedRealtimeUs, int which) { 8117 return mPowerSaveModeEnabledTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 8118 } 8119 getPowerSaveModeEnabledCount(int which)8120 @Override public int getPowerSaveModeEnabledCount(int which) { 8121 return mPowerSaveModeEnabledTimer.getCountLocked(which); 8122 } 8123 getDeviceIdleModeTime(int mode, long elapsedRealtimeUs, int which)8124 @Override public long getDeviceIdleModeTime(int mode, long elapsedRealtimeUs, 8125 int which) { 8126 switch (mode) { 8127 case DEVICE_IDLE_MODE_LIGHT: 8128 return mDeviceIdleModeLightTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 8129 case DEVICE_IDLE_MODE_DEEP: 8130 return mDeviceIdleModeFullTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 8131 } 8132 return 0; 8133 } 8134 getDeviceIdleModeCount(int mode, int which)8135 @Override public int getDeviceIdleModeCount(int mode, int which) { 8136 switch (mode) { 8137 case DEVICE_IDLE_MODE_LIGHT: 8138 return mDeviceIdleModeLightTimer.getCountLocked(which); 8139 case DEVICE_IDLE_MODE_DEEP: 8140 return mDeviceIdleModeFullTimer.getCountLocked(which); 8141 } 8142 return 0; 8143 } 8144 getLongestDeviceIdleModeTime(int mode)8145 @Override public long getLongestDeviceIdleModeTime(int mode) { 8146 switch (mode) { 8147 case DEVICE_IDLE_MODE_LIGHT: 8148 return mLongestLightIdleTimeMs; 8149 case DEVICE_IDLE_MODE_DEEP: 8150 return mLongestFullIdleTimeMs; 8151 } 8152 return 0; 8153 } 8154 getDeviceIdlingTime(int mode, long elapsedRealtimeUs, int which)8155 @Override public long getDeviceIdlingTime(int mode, long elapsedRealtimeUs, int which) { 8156 switch (mode) { 8157 case DEVICE_IDLE_MODE_LIGHT: 8158 return mDeviceLightIdlingTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 8159 case DEVICE_IDLE_MODE_DEEP: 8160 return mDeviceIdlingTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 8161 } 8162 return 0; 8163 } 8164 getDeviceIdlingCount(int mode, int which)8165 @Override public int getDeviceIdlingCount(int mode, int which) { 8166 switch (mode) { 8167 case DEVICE_IDLE_MODE_LIGHT: 8168 return mDeviceLightIdlingTimer.getCountLocked(which); 8169 case DEVICE_IDLE_MODE_DEEP: 8170 return mDeviceIdlingTimer.getCountLocked(which); 8171 } 8172 return 0; 8173 } 8174 getNumConnectivityChange(int which)8175 @Override public int getNumConnectivityChange(int which) { 8176 return mNumConnectivityChange; 8177 } 8178 getGpsSignalQualityTime(int strengthBin, long elapsedRealtimeUs, int which)8179 @Override public long getGpsSignalQualityTime(int strengthBin, 8180 long elapsedRealtimeUs, int which) { 8181 if (strengthBin < 0 || strengthBin >= mGpsSignalQualityTimer.length) { 8182 return 0; 8183 } 8184 return mGpsSignalQualityTimer[strengthBin].getTotalTimeLocked( 8185 elapsedRealtimeUs, which); 8186 } 8187 getGpsBatteryDrainMaMs()8188 @Override public long getGpsBatteryDrainMaMs() { 8189 final double opVolt = mPowerProfile.getAveragePower( 8190 PowerProfile.POWER_GPS_OPERATING_VOLTAGE) / 1000.0; 8191 if (opVolt == 0) { 8192 return 0; 8193 } 8194 double energyUsedMaMs = 0.0; 8195 final int which = STATS_SINCE_CHARGED; 8196 final long rawRealtimeUs = SystemClock.elapsedRealtime() * 1000; 8197 for(int i=0; i < mGpsSignalQualityTimer.length; i++) { 8198 energyUsedMaMs 8199 += mPowerProfile.getAveragePower(PowerProfile.POWER_GPS_SIGNAL_QUALITY_BASED, i) 8200 * (getGpsSignalQualityTime(i, rawRealtimeUs, which) / 1000); 8201 } 8202 return (long) energyUsedMaMs; 8203 } 8204 8205 @UnsupportedAppUsage getPhoneOnTime(long elapsedRealtimeUs, int which)8206 @Override public long getPhoneOnTime(long elapsedRealtimeUs, int which) { 8207 return mPhoneOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 8208 } 8209 getPhoneOnCount(int which)8210 @Override public int getPhoneOnCount(int which) { 8211 return mPhoneOnTimer.getCountLocked(which); 8212 } 8213 8214 @UnsupportedAppUsage getPhoneSignalStrengthTime(int strengthBin, long elapsedRealtimeUs, int which)8215 @Override public long getPhoneSignalStrengthTime(int strengthBin, 8216 long elapsedRealtimeUs, int which) { 8217 return mPhoneSignalStrengthsTimer[strengthBin].getTotalTimeLocked( 8218 elapsedRealtimeUs, which); 8219 } 8220 8221 @UnsupportedAppUsage getPhoneSignalScanningTime( long elapsedRealtimeUs, int which)8222 @Override public long getPhoneSignalScanningTime( 8223 long elapsedRealtimeUs, int which) { 8224 return mPhoneSignalScanningTimer.getTotalTimeLocked( 8225 elapsedRealtimeUs, which); 8226 } 8227 getPhoneSignalScanningTimer()8228 @Override public Timer getPhoneSignalScanningTimer() { 8229 return mPhoneSignalScanningTimer; 8230 } 8231 8232 @UnsupportedAppUsage getPhoneSignalStrengthCount(int strengthBin, int which)8233 @Override public int getPhoneSignalStrengthCount(int strengthBin, int which) { 8234 return mPhoneSignalStrengthsTimer[strengthBin].getCountLocked(which); 8235 } 8236 getPhoneSignalStrengthTimer(int strengthBin)8237 @Override public Timer getPhoneSignalStrengthTimer(int strengthBin) { 8238 return mPhoneSignalStrengthsTimer[strengthBin]; 8239 } 8240 8241 @UnsupportedAppUsage getPhoneDataConnectionTime(int dataType, long elapsedRealtimeUs, int which)8242 @Override public long getPhoneDataConnectionTime(int dataType, 8243 long elapsedRealtimeUs, int which) { 8244 return mPhoneDataConnectionsTimer[dataType].getTotalTimeLocked( 8245 elapsedRealtimeUs, which); 8246 } 8247 8248 @UnsupportedAppUsage getPhoneDataConnectionCount(int dataType, int which)8249 @Override public int getPhoneDataConnectionCount(int dataType, int which) { 8250 return mPhoneDataConnectionsTimer[dataType].getCountLocked(which); 8251 } 8252 getPhoneDataConnectionTimer(int dataType)8253 @Override public Timer getPhoneDataConnectionTimer(int dataType) { 8254 return mPhoneDataConnectionsTimer[dataType]; 8255 } 8256 getActiveRadioDurationMs(@adioAccessTechnology int rat, @ServiceState.FrequencyRange int frequencyRange, int signalStrength, long elapsedRealtimeMs)8257 @Override public long getActiveRadioDurationMs(@RadioAccessTechnology int rat, 8258 @ServiceState.FrequencyRange int frequencyRange, int signalStrength, 8259 long elapsedRealtimeMs) { 8260 final RadioAccessTechnologyBatteryStats stats = mPerRatBatteryStats[rat]; 8261 if (stats == null) return 0L; 8262 8263 final int freqCount = stats.perStateTimers.length; 8264 if (frequencyRange < 0 || frequencyRange >= freqCount) return 0L; 8265 8266 final StopwatchTimer[] strengthTimers = stats.perStateTimers[frequencyRange]; 8267 final int strengthCount = strengthTimers.length; 8268 if (signalStrength < 0 || signalStrength >= strengthCount) return 0L; 8269 8270 return stats.perStateTimers[frequencyRange][signalStrength].getTotalTimeLocked( 8271 elapsedRealtimeMs * 1000, STATS_SINCE_CHARGED) / 1000; 8272 } 8273 8274 @Override getActiveTxRadioDurationMs(@adioAccessTechnology int rat, @ServiceState.FrequencyRange int frequencyRange, int signalStrength, long elapsedRealtimeMs)8275 public long getActiveTxRadioDurationMs(@RadioAccessTechnology int rat, 8276 @ServiceState.FrequencyRange int frequencyRange, int signalStrength, 8277 long elapsedRealtimeMs) { 8278 final RadioAccessTechnologyBatteryStats stats = mPerRatBatteryStats[rat]; 8279 if (stats == null) return DURATION_UNAVAILABLE; 8280 8281 final LongSamplingCounter counter = stats.getTxDurationCounter(frequencyRange, 8282 signalStrength, false); 8283 if (counter == null) return DURATION_UNAVAILABLE; 8284 8285 return counter.getCountLocked(STATS_SINCE_CHARGED); 8286 } 8287 8288 @Override getActiveRxRadioDurationMs(@adioAccessTechnology int rat, @ServiceState.FrequencyRange int frequencyRange, long elapsedRealtimeMs)8289 public long getActiveRxRadioDurationMs(@RadioAccessTechnology int rat, 8290 @ServiceState.FrequencyRange int frequencyRange, long elapsedRealtimeMs) { 8291 final RadioAccessTechnologyBatteryStats stats = mPerRatBatteryStats[rat]; 8292 if (stats == null) return DURATION_UNAVAILABLE; 8293 8294 final LongSamplingCounter counter = stats.getRxDurationCounter(frequencyRange, false); 8295 if (counter == null) return DURATION_UNAVAILABLE; 8296 8297 return counter.getCountLocked(STATS_SINCE_CHARGED); 8298 } 8299 8300 @UnsupportedAppUsage getMobileRadioActiveTime(long elapsedRealtimeUs, int which)8301 @Override public long getMobileRadioActiveTime(long elapsedRealtimeUs, int which) { 8302 return mMobileRadioActiveTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 8303 } 8304 getMobileRadioActiveCount(int which)8305 @Override public int getMobileRadioActiveCount(int which) { 8306 return mMobileRadioActiveTimer.getCountLocked(which); 8307 } 8308 getMobileRadioActiveAdjustedTime(int which)8309 @Override public long getMobileRadioActiveAdjustedTime(int which) { 8310 return mMobileRadioActiveAdjustedTime.getCountLocked(which); 8311 } 8312 getMobileRadioActiveUnknownTime(int which)8313 @Override public long getMobileRadioActiveUnknownTime(int which) { 8314 return mMobileRadioActiveUnknownTime.getCountLocked(which); 8315 } 8316 getMobileRadioActiveUnknownCount(int which)8317 @Override public int getMobileRadioActiveUnknownCount(int which) { 8318 return (int)mMobileRadioActiveUnknownCount.getCountLocked(which); 8319 } 8320 getWifiMulticastWakelockTime( long elapsedRealtimeUs, int which)8321 @Override public long getWifiMulticastWakelockTime( 8322 long elapsedRealtimeUs, int which) { 8323 return mWifiMulticastWakelockTimer.getTotalTimeLocked( 8324 elapsedRealtimeUs, which); 8325 } 8326 getWifiMulticastWakelockCount(int which)8327 @Override public int getWifiMulticastWakelockCount(int which) { 8328 return mWifiMulticastWakelockTimer.getCountLocked(which); 8329 } 8330 8331 @UnsupportedAppUsage getWifiOnTime(long elapsedRealtimeUs, int which)8332 @Override public long getWifiOnTime(long elapsedRealtimeUs, int which) { 8333 return mWifiOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 8334 } 8335 getWifiActiveTime(long elapsedRealtimeUs, int which)8336 @Override public long getWifiActiveTime(long elapsedRealtimeUs, int which) { 8337 return mWifiActiveTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 8338 } 8339 8340 @UnsupportedAppUsage getGlobalWifiRunningTime(long elapsedRealtimeUs, int which)8341 @Override public long getGlobalWifiRunningTime(long elapsedRealtimeUs, int which) { 8342 return mGlobalWifiRunningTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 8343 } 8344 getWifiStateTime(int wifiState, long elapsedRealtimeUs, int which)8345 @Override public long getWifiStateTime(int wifiState, 8346 long elapsedRealtimeUs, int which) { 8347 return mWifiStateTimer[wifiState].getTotalTimeLocked( 8348 elapsedRealtimeUs, which); 8349 } 8350 getWifiStateCount(int wifiState, int which)8351 @Override public int getWifiStateCount(int wifiState, int which) { 8352 return mWifiStateTimer[wifiState].getCountLocked(which); 8353 } 8354 getWifiStateTimer(int wifiState)8355 @Override public Timer getWifiStateTimer(int wifiState) { 8356 return mWifiStateTimer[wifiState]; 8357 } 8358 getWifiSupplStateTime(int state, long elapsedRealtimeUs, int which)8359 @Override public long getWifiSupplStateTime(int state, 8360 long elapsedRealtimeUs, int which) { 8361 return mWifiSupplStateTimer[state].getTotalTimeLocked( 8362 elapsedRealtimeUs, which); 8363 } 8364 getWifiSupplStateCount(int state, int which)8365 @Override public int getWifiSupplStateCount(int state, int which) { 8366 return mWifiSupplStateTimer[state].getCountLocked(which); 8367 } 8368 getWifiSupplStateTimer(int state)8369 @Override public Timer getWifiSupplStateTimer(int state) { 8370 return mWifiSupplStateTimer[state]; 8371 } 8372 getWifiSignalStrengthTime(int strengthBin, long elapsedRealtimeUs, int which)8373 @Override public long getWifiSignalStrengthTime(int strengthBin, 8374 long elapsedRealtimeUs, int which) { 8375 return mWifiSignalStrengthsTimer[strengthBin].getTotalTimeLocked( 8376 elapsedRealtimeUs, which); 8377 } 8378 getWifiSignalStrengthCount(int strengthBin, int which)8379 @Override public int getWifiSignalStrengthCount(int strengthBin, int which) { 8380 return mWifiSignalStrengthsTimer[strengthBin].getCountLocked(which); 8381 } 8382 getWifiSignalStrengthTimer(int strengthBin)8383 @Override public Timer getWifiSignalStrengthTimer(int strengthBin) { 8384 return mWifiSignalStrengthsTimer[strengthBin]; 8385 } 8386 8387 @Override getBluetoothControllerActivity()8388 public ControllerActivityCounter getBluetoothControllerActivity() { 8389 return mBluetoothActivity; 8390 } 8391 8392 @Override getWifiControllerActivity()8393 public ControllerActivityCounter getWifiControllerActivity() { 8394 return mWifiActivity; 8395 } 8396 8397 @Override getModemControllerActivity()8398 public ControllerActivityCounter getModemControllerActivity() { 8399 return mModemActivity; 8400 } 8401 8402 @Override hasBluetoothActivityReporting()8403 public boolean hasBluetoothActivityReporting() { 8404 return mHasBluetoothReporting; 8405 } 8406 8407 @Override hasWifiActivityReporting()8408 public boolean hasWifiActivityReporting() { 8409 return mHasWifiReporting; 8410 } 8411 8412 @Override hasModemActivityReporting()8413 public boolean hasModemActivityReporting() { 8414 return mHasModemReporting; 8415 } 8416 8417 @Override getFlashlightOnTime(long elapsedRealtimeUs, int which)8418 public long getFlashlightOnTime(long elapsedRealtimeUs, int which) { 8419 return mFlashlightOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 8420 } 8421 8422 @Override getFlashlightOnCount(int which)8423 public long getFlashlightOnCount(int which) { 8424 return mFlashlightOnTimer.getCountLocked(which); 8425 } 8426 8427 @Override getCameraOnTime(long elapsedRealtimeUs, int which)8428 public long getCameraOnTime(long elapsedRealtimeUs, int which) { 8429 return mCameraOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 8430 } 8431 8432 @Override getBluetoothScanTime(long elapsedRealtimeUs, int which)8433 public long getBluetoothScanTime(long elapsedRealtimeUs, int which) { 8434 return mBluetoothScanTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 8435 } 8436 8437 @Override 8438 @UnsupportedAppUsage getNetworkActivityBytes(int type, int which)8439 public long getNetworkActivityBytes(int type, int which) { 8440 if (type >= 0 && type < mNetworkByteActivityCounters.length) { 8441 return mNetworkByteActivityCounters[type].getCountLocked(which); 8442 } else { 8443 return 0; 8444 } 8445 } 8446 8447 @Override getNetworkActivityPackets(int type, int which)8448 public long getNetworkActivityPackets(int type, int which) { 8449 if (type >= 0 && type < mNetworkPacketActivityCounters.length) { 8450 return mNetworkPacketActivityCounters[type].getCountLocked(which); 8451 } else { 8452 return 0; 8453 } 8454 } 8455 8456 @GuardedBy("this") 8457 @Override getBluetoothMeasuredBatteryConsumptionUC()8458 public long getBluetoothMeasuredBatteryConsumptionUC() { 8459 return getPowerBucketConsumptionUC(MeasuredEnergyStats.POWER_BUCKET_BLUETOOTH); 8460 } 8461 8462 @GuardedBy("this") 8463 @Override getCpuMeasuredBatteryConsumptionUC()8464 public long getCpuMeasuredBatteryConsumptionUC() { 8465 return getPowerBucketConsumptionUC(MeasuredEnergyStats.POWER_BUCKET_CPU); 8466 } 8467 8468 @GuardedBy("this") 8469 @Override getGnssMeasuredBatteryConsumptionUC()8470 public long getGnssMeasuredBatteryConsumptionUC() { 8471 return getPowerBucketConsumptionUC(MeasuredEnergyStats.POWER_BUCKET_GNSS); 8472 } 8473 8474 @GuardedBy("this") 8475 @Override getMobileRadioMeasuredBatteryConsumptionUC()8476 public long getMobileRadioMeasuredBatteryConsumptionUC() { 8477 return getPowerBucketConsumptionUC(MeasuredEnergyStats.POWER_BUCKET_MOBILE_RADIO); 8478 } 8479 8480 @GuardedBy("this") 8481 @Override getPhoneEnergyConsumptionUC()8482 public long getPhoneEnergyConsumptionUC() { 8483 return getPowerBucketConsumptionUC(MeasuredEnergyStats.POWER_BUCKET_PHONE); 8484 } 8485 8486 @GuardedBy("this") 8487 @Override getScreenOnMeasuredBatteryConsumptionUC()8488 public long getScreenOnMeasuredBatteryConsumptionUC() { 8489 return getPowerBucketConsumptionUC(MeasuredEnergyStats.POWER_BUCKET_SCREEN_ON); 8490 } 8491 8492 @GuardedBy("this") 8493 @Override getScreenDozeMeasuredBatteryConsumptionUC()8494 public long getScreenDozeMeasuredBatteryConsumptionUC() { 8495 return getPowerBucketConsumptionUC(MeasuredEnergyStats.POWER_BUCKET_SCREEN_DOZE); 8496 } 8497 8498 @GuardedBy("this") 8499 @Override getWifiMeasuredBatteryConsumptionUC()8500 public long getWifiMeasuredBatteryConsumptionUC() { 8501 return getPowerBucketConsumptionUC(MeasuredEnergyStats.POWER_BUCKET_WIFI); 8502 } 8503 8504 /** 8505 * Returns the consumption (in microcoulombs) that the given standard power bucket consumed. 8506 * Will return {@link #POWER_DATA_UNAVAILABLE} if data is unavailable 8507 * 8508 * @param bucket standard power bucket of interest 8509 * @return charge (in microcoulombs) used for this power bucket 8510 */ 8511 @GuardedBy("this") getPowerBucketConsumptionUC(@tandardPowerBucket int bucket)8512 private long getPowerBucketConsumptionUC(@StandardPowerBucket int bucket) { 8513 if (mGlobalMeasuredEnergyStats == null) { 8514 return POWER_DATA_UNAVAILABLE; 8515 } 8516 return mGlobalMeasuredEnergyStats.getAccumulatedStandardBucketCharge(bucket); 8517 } 8518 8519 @GuardedBy("this") 8520 @Override getCustomConsumerMeasuredBatteryConsumptionUC()8521 public @Nullable long[] getCustomConsumerMeasuredBatteryConsumptionUC() { 8522 if (mGlobalMeasuredEnergyStats == null) { 8523 return null; 8524 } 8525 return mGlobalMeasuredEnergyStats.getAccumulatedCustomBucketCharges(); 8526 } 8527 8528 /** 8529 * Returns the names of custom power components. 8530 */ 8531 @GuardedBy("this") 8532 @Override getCustomEnergyConsumerNames()8533 public @NonNull String[] getCustomEnergyConsumerNames() { 8534 if (mMeasuredEnergyStatsConfig == null) { 8535 return new String[0]; 8536 } 8537 final String[] names = mMeasuredEnergyStatsConfig.getCustomBucketNames(); 8538 for (int i = 0; i < names.length; i++) { 8539 if (TextUtils.isEmpty(names[i])) { 8540 names[i] = "CUSTOM_" + BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID + i; 8541 } 8542 } 8543 return names; 8544 } 8545 8546 @GuardedBy("this") getStartClockTime()8547 @Override public long getStartClockTime() { 8548 final long currentTimeMs = mClock.currentTimeMillis(); 8549 if ((currentTimeMs > MILLISECONDS_IN_YEAR 8550 && mStartClockTimeMs < (currentTimeMs - MILLISECONDS_IN_YEAR)) 8551 || (mStartClockTimeMs > currentTimeMs)) { 8552 // If the start clock time has changed by more than a year, then presumably 8553 // the previous time was completely bogus. So we are going to figure out a 8554 // new time based on how much time has elapsed since we started counting. 8555 recordCurrentTimeChangeLocked(currentTimeMs, mClock.elapsedRealtime(), 8556 mClock.uptimeMillis()); 8557 return currentTimeMs - (mClock.elapsedRealtime() - (mRealtimeStartUs / 1000)); 8558 } 8559 return mStartClockTimeMs; 8560 } 8561 getStartPlatformVersion()8562 @Override public String getStartPlatformVersion() { 8563 return mStartPlatformVersion; 8564 } 8565 getEndPlatformVersion()8566 @Override public String getEndPlatformVersion() { 8567 return mEndPlatformVersion; 8568 } 8569 getParcelVersion()8570 @Override public int getParcelVersion() { 8571 return VERSION; 8572 } 8573 getIsOnBattery()8574 @Override public boolean getIsOnBattery() { 8575 return mOnBattery; 8576 } 8577 getStatsStartRealtime()8578 @Override public long getStatsStartRealtime() { 8579 return mRealtimeStartUs; 8580 } 8581 8582 @UnsupportedAppUsage getUidStats()8583 @Override public SparseArray<? extends BatteryStats.Uid> getUidStats() { 8584 return mUidStats; 8585 } 8586 resetIfNotNull(T t, boolean detachIfReset, long elapsedRealtimeUs)8587 private static <T extends TimeBaseObs> boolean resetIfNotNull(T t, boolean detachIfReset, 8588 long elapsedRealtimeUs) { 8589 if (t != null) { 8590 return t.reset(detachIfReset, elapsedRealtimeUs); 8591 } 8592 return true; 8593 } 8594 resetIfNotNull(T[] t, boolean detachIfReset, long elapsedRealtimeUs)8595 private static <T extends TimeBaseObs> boolean resetIfNotNull(T[] t, boolean detachIfReset, 8596 long elapsedRealtimeUs) { 8597 if (t != null) { 8598 boolean ret = true; 8599 for (int i = 0; i < t.length; i++) { 8600 ret &= resetIfNotNull(t[i], detachIfReset, elapsedRealtimeUs); 8601 } 8602 return ret; 8603 } 8604 return true; 8605 } 8606 resetIfNotNull(T[][] t, boolean detachIfReset, long elapsedRealtimeUs)8607 private static <T extends TimeBaseObs> boolean resetIfNotNull(T[][] t, boolean detachIfReset, 8608 long elapsedRealtimeUs) { 8609 if (t != null) { 8610 boolean ret = true; 8611 for (int i = 0; i < t.length; i++) { 8612 ret &= resetIfNotNull(t[i], detachIfReset, elapsedRealtimeUs); 8613 } 8614 return ret; 8615 } 8616 return true; 8617 } 8618 resetIfNotNull(ControllerActivityCounterImpl counter, boolean detachIfReset, long elapsedRealtimeUs)8619 private static boolean resetIfNotNull(ControllerActivityCounterImpl counter, 8620 boolean detachIfReset, long elapsedRealtimeUs) { 8621 if (counter != null) { 8622 counter.reset(detachIfReset, elapsedRealtimeUs); 8623 } 8624 return true; 8625 } 8626 detachIfNotNull(T t)8627 private static <T extends TimeBaseObs> void detachIfNotNull(T t) { 8628 if (t != null) { 8629 t.detach(); 8630 } 8631 } 8632 detachIfNotNull(T[] t)8633 private static <T extends TimeBaseObs> void detachIfNotNull(T[] t) { 8634 if (t != null) { 8635 for (int i = 0; i < t.length; i++) { 8636 detachIfNotNull(t[i]); 8637 } 8638 } 8639 } 8640 detachIfNotNull(T[][] t)8641 private static <T extends TimeBaseObs> void detachIfNotNull(T[][] t) { 8642 if (t != null) { 8643 for (int i = 0; i < t.length; i++) { 8644 detachIfNotNull(t[i]); 8645 } 8646 } 8647 } 8648 detachIfNotNull(ControllerActivityCounterImpl counter)8649 private static void detachIfNotNull(ControllerActivityCounterImpl counter) { 8650 if (counter != null) { 8651 counter.detach(); 8652 } 8653 } 8654 8655 /** 8656 * Accumulates stats for a specific binder transaction. 8657 */ 8658 @VisibleForTesting 8659 protected static class BinderCallStats { 8660 static final Comparator<BinderCallStats> COMPARATOR = 8661 Comparator.comparing(BinderCallStats::getClassName) 8662 .thenComparing(BinderCallStats::getMethodName); 8663 8664 public Class<? extends Binder> binderClass; 8665 public int transactionCode; 8666 public String methodName; 8667 8668 public long callCount; 8669 public long recordedCallCount; 8670 public long recordedCpuTimeMicros; 8671 8672 8673 @Override hashCode()8674 public int hashCode() { 8675 return binderClass.hashCode() * 31 + transactionCode; 8676 } 8677 8678 @Override equals(Object obj)8679 public boolean equals(Object obj) { 8680 if (!(obj instanceof BinderCallStats)) { 8681 return false; 8682 } 8683 BinderCallStats bcsk = (BinderCallStats) obj; 8684 return binderClass.equals(bcsk.binderClass) && transactionCode == bcsk.transactionCode; 8685 } 8686 getClassName()8687 public String getClassName() { 8688 return binderClass.getName(); 8689 } 8690 getMethodName()8691 public String getMethodName() { 8692 return methodName; 8693 } 8694 8695 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) ensureMethodName(BinderTransactionNameResolver resolver)8696 public void ensureMethodName(BinderTransactionNameResolver resolver) { 8697 if (methodName == null) { 8698 methodName = resolver.getMethodName(binderClass, transactionCode); 8699 } 8700 } 8701 8702 @Override toString()8703 public String toString() { 8704 return "BinderCallStats{" 8705 + binderClass 8706 + " transaction=" + transactionCode 8707 + " callCount=" + callCount 8708 + " recordedCallCount=" + recordedCallCount 8709 + " recorderCpuTimeMicros=" + recordedCpuTimeMicros 8710 + "}"; 8711 } 8712 } 8713 8714 /** 8715 * The statistics associated with a particular uid. 8716 */ 8717 public static class Uid extends BatteryStats.Uid { 8718 /** 8719 * BatteryStatsImpl that we are associated with. 8720 */ 8721 protected BatteryStatsImpl mBsi; 8722 8723 final int mUid; 8724 8725 /** TimeBase for when uid is in background and device is on battery. */ 8726 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) 8727 public final TimeBase mOnBatteryBackgroundTimeBase; 8728 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) 8729 public final TimeBase mOnBatteryScreenOffBackgroundTimeBase; 8730 8731 boolean mWifiRunning; 8732 StopwatchTimer mWifiRunningTimer; 8733 8734 boolean mFullWifiLockOut; 8735 StopwatchTimer mFullWifiLockTimer; 8736 8737 boolean mWifiScanStarted; 8738 DualTimer mWifiScanTimer; 8739 8740 static final int NO_BATCHED_SCAN_STARTED = -1; 8741 int mWifiBatchedScanBinStarted = NO_BATCHED_SCAN_STARTED; 8742 StopwatchTimer[] mWifiBatchedScanTimer; 8743 8744 int mWifiMulticastWakelockCount; 8745 StopwatchTimer mWifiMulticastTimer; 8746 8747 StopwatchTimer mAudioTurnedOnTimer; 8748 StopwatchTimer mVideoTurnedOnTimer; 8749 StopwatchTimer mFlashlightTurnedOnTimer; 8750 StopwatchTimer mCameraTurnedOnTimer; 8751 StopwatchTimer mForegroundActivityTimer; 8752 StopwatchTimer mForegroundServiceTimer; 8753 /** Total time spent by the uid holding any partial wakelocks. */ 8754 DualTimer mAggregatedPartialWakelockTimer; 8755 DualTimer mBluetoothScanTimer; 8756 DualTimer mBluetoothUnoptimizedScanTimer; 8757 Counter mBluetoothScanResultCounter; 8758 Counter mBluetoothScanResultBgCounter; 8759 8760 int mProcessState = Uid.PROCESS_STATE_NONEXISTENT; 8761 StopwatchTimer[] mProcessStateTimer; 8762 8763 boolean mInForegroundService = false; 8764 8765 BatchTimer mVibratorOnTimer; 8766 8767 Counter[] mUserActivityCounters; 8768 8769 LongSamplingCounter[] mNetworkByteActivityCounters; 8770 LongSamplingCounter[] mNetworkPacketActivityCounters; 8771 TimeMultiStateCounter mMobileRadioActiveTime; 8772 LongSamplingCounter mMobileRadioActiveCount; 8773 8774 /** 8775 * How many times this UID woke up the Application Processor due to a Mobile radio packet. 8776 */ 8777 private LongSamplingCounter mMobileRadioApWakeupCount; 8778 8779 /** 8780 * How many times this UID woke up the Application Processor due to a Wifi packet. 8781 */ 8782 private LongSamplingCounter mWifiRadioApWakeupCount; 8783 8784 /** 8785 * The amount of time this uid has kept the WiFi controller in idle, tx, and rx mode. 8786 * Can be null if the UID has had no such activity. 8787 */ 8788 private ControllerActivityCounterImpl mWifiControllerActivity; 8789 8790 /** 8791 * The amount of time this uid has kept the Bluetooth controller in idle, tx, and rx mode. 8792 * Can be null if the UID has had no such activity. 8793 */ 8794 private ControllerActivityCounterImpl mBluetoothControllerActivity; 8795 8796 /** 8797 * The amount of time this uid has kept the Modem controller in idle, tx, and rx mode. 8798 * Can be null if the UID has had no such activity. 8799 */ 8800 private ControllerActivityCounterImpl mModemControllerActivity; 8801 8802 /** 8803 * The CPU times we had at the last history details update. 8804 */ 8805 long mLastStepUserTimeMs; 8806 long mLastStepSystemTimeMs; 8807 long mCurStepUserTimeMs; 8808 long mCurStepSystemTimeMs; 8809 8810 LongSamplingCounter mUserCpuTime; 8811 LongSamplingCounter mSystemCpuTime; 8812 LongSamplingCounter[][] mCpuClusterSpeedTimesUs; 8813 TimeMultiStateCounter mCpuActiveTimeMs; 8814 8815 LongSamplingCounterArray mCpuFreqTimeMs; 8816 LongSamplingCounterArray mScreenOffCpuFreqTimeMs; 8817 LongSamplingCounterArray mCpuClusterTimesMs; 8818 8819 TimeInFreqMultiStateCounter mProcStateTimeMs; 8820 TimeInFreqMultiStateCounter mProcStateScreenOffTimeMs; 8821 8822 SparseArray<ChildUid> mChildUids; 8823 8824 /** 8825 * The statistics we have collected for this uid's wake locks. 8826 */ 8827 final OverflowArrayMap<Wakelock> mWakelockStats; 8828 8829 /** 8830 * The statistics we have collected for this uid's syncs. 8831 */ 8832 final OverflowArrayMap<DualTimer> mSyncStats; 8833 8834 /** 8835 * The statistics we have collected for this uid's jobs. 8836 */ 8837 final OverflowArrayMap<DualTimer> mJobStats; 8838 8839 /** 8840 * Count of the jobs that have completed and the reasons why they completed. 8841 */ 8842 final ArrayMap<String, SparseIntArray> mJobCompletions = new ArrayMap<>(); 8843 8844 /** 8845 * Count of app launch events that had associated deferred job counts or info about 8846 * last time a job was run. 8847 */ 8848 Counter mJobsDeferredEventCount; 8849 8850 /** 8851 * Count of deferred jobs that were pending when the app was launched or brought to 8852 * the foreground through a user interaction. 8853 */ 8854 Counter mJobsDeferredCount; 8855 8856 /** 8857 * Sum of time since the last time a job was run for this app before it was launched. 8858 */ 8859 LongSamplingCounter mJobsFreshnessTimeMs; 8860 8861 /** 8862 * Array of counts of instances where the time since the last job was run for the app 8863 * fell within one of the thresholds in {@link #JOB_FRESHNESS_BUCKETS}. 8864 */ 8865 final Counter[] mJobsFreshnessBuckets; 8866 8867 /** 8868 * The statistics we have collected for this uid's sensor activations. 8869 */ 8870 final SparseArray<Sensor> mSensorStats = new SparseArray<>(); 8871 8872 /** 8873 * The statistics we have collected for this uid's processes. 8874 */ 8875 final ArrayMap<String, Proc> mProcessStats = new ArrayMap<>(); 8876 8877 /** 8878 * The statistics we have collected for this uid's processes. 8879 */ 8880 final ArrayMap<String, Pkg> mPackageStats = new ArrayMap<>(); 8881 8882 /** 8883 * The transient wake stats we have collected for this uid's pids. 8884 */ 8885 final SparseArray<Pid> mPids = new SparseArray<>(); 8886 8887 /** 8888 * Grand total of system server binder calls made by this uid. 8889 */ 8890 private long mBinderCallCount; 8891 8892 /** 8893 * Detailed information about system server binder calls made by this uid. 8894 */ 8895 private final ArraySet<BinderCallStats> mBinderCallStats = new ArraySet<>(); 8896 8897 /** 8898 * Measured charge consumption by this uid while on battery. 8899 * Its '<b>custom</b> power buckets' correspond to the 8900 * {@link android.hardware.power.stats.EnergyConsumer.ordinal}s of (custom) energy consumer 8901 * type {@link android.hardware.power.stats.EnergyConsumerType#OTHER}). 8902 * 8903 * Will be null if energy consumer data is completely unavailable (in which case 8904 * {@link #mGlobalMeasuredEnergyStats} will also be null) or if the power usage by this uid 8905 * is 0 for every bucket. 8906 */ 8907 private MeasuredEnergyStats mUidMeasuredEnergyStats; 8908 8909 /** 8910 * Estimated total time spent by the system server handling requests from this uid. 8911 */ 8912 private long mSystemServiceTimeUs; 8913 8914 /** 8915 * Estimated proportion of system server binder call CPU cost for this uid. 8916 */ 8917 private double mProportionalSystemServiceUsage; 8918 Uid(BatteryStatsImpl bsi, int uid)8919 public Uid(BatteryStatsImpl bsi, int uid) { 8920 this(bsi, uid, bsi.mClock.elapsedRealtime(), bsi.mClock.uptimeMillis()); 8921 } 8922 Uid(BatteryStatsImpl bsi, int uid, long elapsedRealtimeMs, long uptimeMs)8923 public Uid(BatteryStatsImpl bsi, int uid, long elapsedRealtimeMs, long uptimeMs) { 8924 mBsi = bsi; 8925 mUid = uid; 8926 8927 /* Observer list of TimeBase object in Uid is short */ 8928 mOnBatteryBackgroundTimeBase = new TimeBase(false); 8929 mOnBatteryBackgroundTimeBase.init(uptimeMs * 1000, elapsedRealtimeMs * 1000); 8930 /* Observer list of TimeBase object in Uid is short */ 8931 mOnBatteryScreenOffBackgroundTimeBase = new TimeBase(false); 8932 mOnBatteryScreenOffBackgroundTimeBase.init(uptimeMs * 1000, elapsedRealtimeMs * 1000); 8933 8934 mUserCpuTime = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); 8935 mSystemCpuTime = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); 8936 mCpuClusterTimesMs = new LongSamplingCounterArray(mBsi.mOnBatteryTimeBase); 8937 8938 mWakelockStats = mBsi.new OverflowArrayMap<Wakelock>(uid) { 8939 @Override public Wakelock instantiateObject() { 8940 return new Wakelock(mBsi, Uid.this); 8941 } 8942 }; 8943 mSyncStats = mBsi.new OverflowArrayMap<DualTimer>(uid) { 8944 @Override public DualTimer instantiateObject() { 8945 return new DualTimer(mBsi.mClock, Uid.this, SYNC, null, 8946 mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase); 8947 } 8948 }; 8949 mJobStats = mBsi.new OverflowArrayMap<DualTimer>(uid) { 8950 @Override public DualTimer instantiateObject() { 8951 return new DualTimer(mBsi.mClock, Uid.this, JOB, null, 8952 mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase); 8953 } 8954 }; 8955 8956 mWifiRunningTimer = new StopwatchTimer(mBsi.mClock, this, WIFI_RUNNING, 8957 mBsi.mWifiRunningTimers, mBsi.mOnBatteryTimeBase); 8958 mFullWifiLockTimer = new StopwatchTimer(mBsi.mClock, this, FULL_WIFI_LOCK, 8959 mBsi.mFullWifiLockTimers, mBsi.mOnBatteryTimeBase); 8960 mWifiScanTimer = new DualTimer(mBsi.mClock, this, WIFI_SCAN, 8961 mBsi.mWifiScanTimers, mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase); 8962 mWifiBatchedScanTimer = new StopwatchTimer[NUM_WIFI_BATCHED_SCAN_BINS]; 8963 mWifiMulticastTimer = new StopwatchTimer(mBsi.mClock, this, WIFI_MULTICAST_ENABLED, 8964 mBsi.mWifiMulticastTimers, mBsi.mOnBatteryTimeBase); 8965 mProcessStateTimer = new StopwatchTimer[NUM_PROCESS_STATE]; 8966 mJobsDeferredEventCount = new Counter(mBsi.mOnBatteryTimeBase); 8967 mJobsDeferredCount = new Counter(mBsi.mOnBatteryTimeBase); 8968 mJobsFreshnessTimeMs = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); 8969 mJobsFreshnessBuckets = new Counter[JOB_FRESHNESS_BUCKETS.length]; 8970 } 8971 8972 @GuardedBy("mBsi") 8973 @VisibleForTesting setProcessStateForTest(int procState, long elapsedTimeMs)8974 public void setProcessStateForTest(int procState, long elapsedTimeMs) { 8975 mProcessState = procState; 8976 getProcStateTimeCounter(elapsedTimeMs).setState(procState, elapsedTimeMs); 8977 getProcStateScreenOffTimeCounter(elapsedTimeMs).setState(procState, elapsedTimeMs); 8978 final int batteryConsumerProcessState = 8979 mapUidProcessStateToBatteryConsumerProcessState(procState); 8980 getCpuActiveTimeCounter().setState(batteryConsumerProcessState, elapsedTimeMs); 8981 getMobileRadioActiveTimeCounter().setState(batteryConsumerProcessState, elapsedTimeMs); 8982 final ControllerActivityCounterImpl wifiControllerActivity = 8983 getWifiControllerActivity(); 8984 if (wifiControllerActivity != null) { 8985 wifiControllerActivity.setState(batteryConsumerProcessState, elapsedTimeMs); 8986 } 8987 final ControllerActivityCounterImpl bluetoothControllerActivity = 8988 getBluetoothControllerActivity(); 8989 if (bluetoothControllerActivity != null) { 8990 bluetoothControllerActivity.setState(batteryConsumerProcessState, elapsedTimeMs); 8991 } 8992 final MeasuredEnergyStats energyStats = 8993 getOrCreateMeasuredEnergyStatsIfSupportedLocked(); 8994 if (energyStats != null) { 8995 energyStats.setState(batteryConsumerProcessState, elapsedTimeMs); 8996 } 8997 } 8998 8999 @Override getCpuFreqTimes(int which)9000 public long[] getCpuFreqTimes(int which) { 9001 return nullIfAllZeros(mCpuFreqTimeMs, which); 9002 } 9003 9004 @Override getScreenOffCpuFreqTimes(int which)9005 public long[] getScreenOffCpuFreqTimes(int which) { 9006 return nullIfAllZeros(mScreenOffCpuFreqTimeMs, which); 9007 } 9008 getCpuActiveTimeCounter()9009 private TimeMultiStateCounter getCpuActiveTimeCounter() { 9010 if (mCpuActiveTimeMs == null) { 9011 final long timestampMs = mBsi.mClock.elapsedRealtime(); 9012 mCpuActiveTimeMs = new TimeMultiStateCounter(mBsi.mOnBatteryTimeBase, 9013 BatteryConsumer.PROCESS_STATE_COUNT, timestampMs); 9014 mCpuActiveTimeMs.setState( 9015 mapUidProcessStateToBatteryConsumerProcessState(mProcessState), 9016 timestampMs); 9017 } 9018 return mCpuActiveTimeMs; 9019 } 9020 9021 @Override getCpuActiveTime()9022 public long getCpuActiveTime() { 9023 if (mCpuActiveTimeMs == null) { 9024 return 0; 9025 } 9026 9027 long activeTime = 0; 9028 for (int procState = 0; procState < BatteryConsumer.PROCESS_STATE_COUNT; procState++) { 9029 activeTime += mCpuActiveTimeMs.getCountForProcessState(procState); 9030 } 9031 return activeTime; 9032 } 9033 9034 @Override getCpuActiveTime(int procState)9035 public long getCpuActiveTime(int procState) { 9036 if (mCpuActiveTimeMs == null 9037 || procState < 0 || procState >= BatteryConsumer.PROCESS_STATE_COUNT) { 9038 return 0; 9039 } 9040 9041 return mCpuActiveTimeMs.getCountForProcessState(procState); 9042 } 9043 9044 @Override getCpuClusterTimes()9045 public long[] getCpuClusterTimes() { 9046 return nullIfAllZeros(mCpuClusterTimesMs, STATS_SINCE_CHARGED); 9047 } 9048 9049 @GuardedBy("mBsi") 9050 @Override getCpuFreqTimes(long[] timesInFreqMs, int procState)9051 public boolean getCpuFreqTimes(long[] timesInFreqMs, int procState) { 9052 if (procState < 0 || procState >= NUM_PROCESS_STATE) { 9053 return false; 9054 } 9055 if (mProcStateTimeMs == null) { 9056 return false; 9057 } 9058 if (!mBsi.mPerProcStateCpuTimesAvailable) { 9059 mProcStateTimeMs = null; 9060 return false; 9061 } 9062 return mProcStateTimeMs.getCountsLocked(timesInFreqMs, procState); 9063 } 9064 9065 @GuardedBy("mBsi") 9066 @Override getScreenOffCpuFreqTimes(long[] timesInFreqMs, int procState)9067 public boolean getScreenOffCpuFreqTimes(long[] timesInFreqMs, int procState) { 9068 if (procState < 0 || procState >= NUM_PROCESS_STATE) { 9069 return false; 9070 } 9071 if (mProcStateScreenOffTimeMs == null) { 9072 return false; 9073 } 9074 if (!mBsi.mPerProcStateCpuTimesAvailable) { 9075 mProcStateScreenOffTimeMs = null; 9076 return false; 9077 } 9078 return mProcStateScreenOffTimeMs.getCountsLocked(timesInFreqMs, procState); 9079 } 9080 getBinderCallCount()9081 public long getBinderCallCount() { 9082 return mBinderCallCount; 9083 } 9084 9085 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE) getBinderCallStats()9086 public ArraySet<BinderCallStats> getBinderCallStats() { 9087 return mBinderCallStats; 9088 } 9089 9090 @Override getProportionalSystemServiceUsage()9091 public double getProportionalSystemServiceUsage() { 9092 return mProportionalSystemServiceUsage; 9093 } 9094 9095 @GuardedBy("mBsi") addIsolatedUid(int isolatedUid)9096 public void addIsolatedUid(int isolatedUid) { 9097 if (mChildUids == null) { 9098 mChildUids = new SparseArray<>(); 9099 } else if (mChildUids.indexOfKey(isolatedUid) >= 0) { 9100 return; 9101 } 9102 mChildUids.put(isolatedUid, new ChildUid()); 9103 } 9104 removeIsolatedUid(int isolatedUid)9105 public void removeIsolatedUid(int isolatedUid) { 9106 final int idx = mChildUids == null ? -1 : mChildUids.indexOfKey(isolatedUid); 9107 if (idx < 0) { 9108 return; 9109 } 9110 mChildUids.remove(idx); 9111 } 9112 9113 @GuardedBy("mBsi") getChildUid(int childUid)9114 ChildUid getChildUid(int childUid) { 9115 return mChildUids == null ? null : mChildUids.get(childUid); 9116 } 9117 nullIfAllZeros(LongSamplingCounterArray cpuTimesMs, int which)9118 private long[] nullIfAllZeros(LongSamplingCounterArray cpuTimesMs, int which) { 9119 if (cpuTimesMs == null) { 9120 return null; 9121 } 9122 final long[] counts = cpuTimesMs.getCountsLocked(which); 9123 if (counts == null) { 9124 return null; 9125 } 9126 // Return counts only if at least one of the elements is non-zero. 9127 for (int i = counts.length - 1; i >= 0; --i) { 9128 if (counts[i] != 0) { 9129 return counts; 9130 } 9131 } 9132 return null; 9133 } 9134 9135 @GuardedBy("mBsi") ensureMultiStateCounters(long timestampMs)9136 private void ensureMultiStateCounters(long timestampMs) { 9137 if (mProcStateTimeMs != null) { 9138 return; 9139 } 9140 9141 mProcStateTimeMs = 9142 new TimeInFreqMultiStateCounter(mBsi.mOnBatteryTimeBase, 9143 PROC_STATE_TIME_COUNTER_STATE_COUNT, mBsi.getCpuFreqCount(), 9144 timestampMs); 9145 mProcStateScreenOffTimeMs = 9146 new TimeInFreqMultiStateCounter(mBsi.mOnBatteryScreenOffTimeBase, 9147 PROC_STATE_TIME_COUNTER_STATE_COUNT, mBsi.getCpuFreqCount(), 9148 timestampMs); 9149 } 9150 9151 @GuardedBy("mBsi") getProcStateTimeCounter(long timestampMs)9152 private TimeInFreqMultiStateCounter getProcStateTimeCounter(long timestampMs) { 9153 ensureMultiStateCounters(timestampMs); 9154 return mProcStateTimeMs; 9155 } 9156 9157 @GuardedBy("mBsi") getProcStateScreenOffTimeCounter(long timestampMs)9158 private TimeInFreqMultiStateCounter getProcStateScreenOffTimeCounter(long timestampMs) { 9159 ensureMultiStateCounters(timestampMs); 9160 return mProcStateScreenOffTimeMs; 9161 } 9162 9163 @Override getAggregatedPartialWakelockTimer()9164 public Timer getAggregatedPartialWakelockTimer() { 9165 return mAggregatedPartialWakelockTimer; 9166 } 9167 9168 @Override 9169 @UnsupportedAppUsage getWakelockStats()9170 public ArrayMap<String, ? extends BatteryStats.Uid.Wakelock> getWakelockStats() { 9171 return mWakelockStats.getMap(); 9172 } 9173 9174 @Override getMulticastWakelockStats()9175 public Timer getMulticastWakelockStats() { 9176 return mWifiMulticastTimer; 9177 } 9178 9179 @Override getSyncStats()9180 public ArrayMap<String, ? extends BatteryStats.Timer> getSyncStats() { 9181 return mSyncStats.getMap(); 9182 } 9183 9184 @Override getJobStats()9185 public ArrayMap<String, ? extends BatteryStats.Timer> getJobStats() { 9186 return mJobStats.getMap(); 9187 } 9188 9189 @Override getJobCompletionStats()9190 public ArrayMap<String, SparseIntArray> getJobCompletionStats() { 9191 return mJobCompletions; 9192 } 9193 9194 @Override 9195 @UnsupportedAppUsage getSensorStats()9196 public SparseArray<? extends BatteryStats.Uid.Sensor> getSensorStats() { 9197 return mSensorStats; 9198 } 9199 9200 @Override 9201 @UnsupportedAppUsage getProcessStats()9202 public ArrayMap<String, ? extends BatteryStats.Uid.Proc> getProcessStats() { 9203 return mProcessStats; 9204 } 9205 9206 @Override getPackageStats()9207 public ArrayMap<String, ? extends BatteryStats.Uid.Pkg> getPackageStats() { 9208 return mPackageStats; 9209 } 9210 9211 @Override 9212 @UnsupportedAppUsage getUid()9213 public int getUid() { 9214 return mUid; 9215 } 9216 9217 @Override noteWifiRunningLocked(long elapsedRealtimeMs)9218 public void noteWifiRunningLocked(long elapsedRealtimeMs) { 9219 if (!mWifiRunning) { 9220 mWifiRunning = true; 9221 if (mWifiRunningTimer == null) { 9222 mWifiRunningTimer = new StopwatchTimer(mBsi.mClock, Uid.this, WIFI_RUNNING, 9223 mBsi.mWifiRunningTimers, mBsi.mOnBatteryTimeBase); 9224 } 9225 mWifiRunningTimer.startRunningLocked(elapsedRealtimeMs); 9226 } 9227 } 9228 9229 @Override noteWifiStoppedLocked(long elapsedRealtimeMs)9230 public void noteWifiStoppedLocked(long elapsedRealtimeMs) { 9231 if (mWifiRunning) { 9232 mWifiRunning = false; 9233 mWifiRunningTimer.stopRunningLocked(elapsedRealtimeMs); 9234 } 9235 } 9236 9237 @Override noteFullWifiLockAcquiredLocked(long elapsedRealtimeMs)9238 public void noteFullWifiLockAcquiredLocked(long elapsedRealtimeMs) { 9239 if (!mFullWifiLockOut) { 9240 mFullWifiLockOut = true; 9241 if (mFullWifiLockTimer == null) { 9242 mFullWifiLockTimer = new StopwatchTimer(mBsi.mClock, Uid.this, FULL_WIFI_LOCK, 9243 mBsi.mFullWifiLockTimers, mBsi.mOnBatteryTimeBase); 9244 } 9245 mFullWifiLockTimer.startRunningLocked(elapsedRealtimeMs); 9246 } 9247 } 9248 9249 @Override noteFullWifiLockReleasedLocked(long elapsedRealtimeMs)9250 public void noteFullWifiLockReleasedLocked(long elapsedRealtimeMs) { 9251 if (mFullWifiLockOut) { 9252 mFullWifiLockOut = false; 9253 mFullWifiLockTimer.stopRunningLocked(elapsedRealtimeMs); 9254 } 9255 } 9256 9257 @Override noteWifiScanStartedLocked(long elapsedRealtimeMs)9258 public void noteWifiScanStartedLocked(long elapsedRealtimeMs) { 9259 if (!mWifiScanStarted) { 9260 mWifiScanStarted = true; 9261 if (mWifiScanTimer == null) { 9262 mWifiScanTimer = new DualTimer(mBsi.mClock, Uid.this, WIFI_SCAN, 9263 mBsi.mWifiScanTimers, mBsi.mOnBatteryTimeBase, 9264 mOnBatteryBackgroundTimeBase); 9265 } 9266 mWifiScanTimer.startRunningLocked(elapsedRealtimeMs); 9267 } 9268 } 9269 9270 @Override noteWifiScanStoppedLocked(long elapsedRealtimeMs)9271 public void noteWifiScanStoppedLocked(long elapsedRealtimeMs) { 9272 if (mWifiScanStarted) { 9273 mWifiScanStarted = false; 9274 mWifiScanTimer.stopRunningLocked(elapsedRealtimeMs); 9275 } 9276 } 9277 9278 @Override noteWifiBatchedScanStartedLocked(int csph, long elapsedRealtimeMs)9279 public void noteWifiBatchedScanStartedLocked(int csph, long elapsedRealtimeMs) { 9280 int bin = 0; 9281 while (csph > 8 && bin < NUM_WIFI_BATCHED_SCAN_BINS-1) { 9282 csph = csph >> 3; 9283 bin++; 9284 } 9285 9286 if (mWifiBatchedScanBinStarted == bin) return; 9287 9288 if (mWifiBatchedScanBinStarted != NO_BATCHED_SCAN_STARTED) { 9289 mWifiBatchedScanTimer[mWifiBatchedScanBinStarted]. 9290 stopRunningLocked(elapsedRealtimeMs); 9291 } 9292 mWifiBatchedScanBinStarted = bin; 9293 if (mWifiBatchedScanTimer[bin] == null) { 9294 makeWifiBatchedScanBin(bin, null); 9295 } 9296 mWifiBatchedScanTimer[bin].startRunningLocked(elapsedRealtimeMs); 9297 } 9298 9299 @Override noteWifiBatchedScanStoppedLocked(long elapsedRealtimeMs)9300 public void noteWifiBatchedScanStoppedLocked(long elapsedRealtimeMs) { 9301 if (mWifiBatchedScanBinStarted != NO_BATCHED_SCAN_STARTED) { 9302 mWifiBatchedScanTimer[mWifiBatchedScanBinStarted]. 9303 stopRunningLocked(elapsedRealtimeMs); 9304 mWifiBatchedScanBinStarted = NO_BATCHED_SCAN_STARTED; 9305 } 9306 } 9307 9308 @Override noteWifiMulticastEnabledLocked(long elapsedRealtimeMs)9309 public void noteWifiMulticastEnabledLocked(long elapsedRealtimeMs) { 9310 if (mWifiMulticastWakelockCount == 0) { 9311 if (mWifiMulticastTimer == null) { 9312 mWifiMulticastTimer = new StopwatchTimer(mBsi.mClock, Uid.this, 9313 WIFI_MULTICAST_ENABLED, mBsi.mWifiMulticastTimers, mBsi.mOnBatteryTimeBase); 9314 } 9315 mWifiMulticastTimer.startRunningLocked(elapsedRealtimeMs); 9316 } 9317 mWifiMulticastWakelockCount++; 9318 } 9319 9320 @Override noteWifiMulticastDisabledLocked(long elapsedRealtimeMs)9321 public void noteWifiMulticastDisabledLocked(long elapsedRealtimeMs) { 9322 if (mWifiMulticastWakelockCount == 0) { 9323 return; 9324 } 9325 9326 mWifiMulticastWakelockCount--; 9327 if (mWifiMulticastWakelockCount == 0) { 9328 mWifiMulticastTimer.stopRunningLocked(elapsedRealtimeMs); 9329 } 9330 } 9331 9332 @Override getWifiControllerActivity()9333 public ControllerActivityCounterImpl getWifiControllerActivity() { 9334 return mWifiControllerActivity; 9335 } 9336 9337 @Override getBluetoothControllerActivity()9338 public ControllerActivityCounterImpl getBluetoothControllerActivity() { 9339 return mBluetoothControllerActivity; 9340 } 9341 9342 @Override getModemControllerActivity()9343 public ControllerActivityCounter getModemControllerActivity() { 9344 return mModemControllerActivity; 9345 } 9346 getOrCreateWifiControllerActivityLocked()9347 public ControllerActivityCounterImpl getOrCreateWifiControllerActivityLocked() { 9348 if (mWifiControllerActivity == null) { 9349 mWifiControllerActivity = new ControllerActivityCounterImpl(mBsi.mClock, 9350 mBsi.mOnBatteryTimeBase, NUM_WIFI_TX_LEVELS); 9351 } 9352 return mWifiControllerActivity; 9353 } 9354 getOrCreateBluetoothControllerActivityLocked()9355 public ControllerActivityCounterImpl getOrCreateBluetoothControllerActivityLocked() { 9356 if (mBluetoothControllerActivity == null) { 9357 mBluetoothControllerActivity = new ControllerActivityCounterImpl(mBsi.mClock, 9358 mBsi.mOnBatteryTimeBase, NUM_BT_TX_LEVELS); 9359 } 9360 return mBluetoothControllerActivity; 9361 } 9362 getOrCreateModemControllerActivityLocked()9363 public ControllerActivityCounterImpl getOrCreateModemControllerActivityLocked() { 9364 if (mModemControllerActivity == null) { 9365 mModemControllerActivity = new ControllerActivityCounterImpl(mBsi.mClock, 9366 mBsi.mOnBatteryTimeBase, ModemActivityInfo.getNumTxPowerLevels()); 9367 } 9368 return mModemControllerActivity; 9369 } 9370 9371 @GuardedBy("mBsi") getOrCreateMeasuredEnergyStatsLocked()9372 private MeasuredEnergyStats getOrCreateMeasuredEnergyStatsLocked() { 9373 if (mUidMeasuredEnergyStats == null) { 9374 mUidMeasuredEnergyStats = new MeasuredEnergyStats(mBsi.mMeasuredEnergyStatsConfig); 9375 } 9376 return mUidMeasuredEnergyStats; 9377 } 9378 9379 @GuardedBy("mBsi") getOrCreateMeasuredEnergyStatsIfSupportedLocked()9380 private MeasuredEnergyStats getOrCreateMeasuredEnergyStatsIfSupportedLocked() { 9381 if (mUidMeasuredEnergyStats == null && mBsi.mMeasuredEnergyStatsConfig != null) { 9382 mUidMeasuredEnergyStats = new MeasuredEnergyStats(mBsi.mMeasuredEnergyStatsConfig); 9383 } 9384 return mUidMeasuredEnergyStats; 9385 } 9386 9387 /** Adds the given charge to the given standard power bucket for this uid. */ 9388 @GuardedBy("mBsi") addChargeToStandardBucketLocked(long chargeDeltaUC, @StandardPowerBucket int powerBucket, long timestampMs)9389 private void addChargeToStandardBucketLocked(long chargeDeltaUC, 9390 @StandardPowerBucket int powerBucket, long timestampMs) { 9391 final MeasuredEnergyStats measuredEnergyStats = 9392 getOrCreateMeasuredEnergyStatsLocked(); 9393 measuredEnergyStats.updateStandardBucket(powerBucket, chargeDeltaUC, timestampMs); 9394 } 9395 9396 /** Adds the given charge to the given custom power bucket for this uid. */ 9397 @GuardedBy("mBsi") addChargeToCustomBucketLocked(long chargeDeltaUC, int powerBucket)9398 private void addChargeToCustomBucketLocked(long chargeDeltaUC, int powerBucket) { 9399 getOrCreateMeasuredEnergyStatsLocked().updateCustomBucket(powerBucket, chargeDeltaUC, 9400 mBsi.mClock.elapsedRealtime()); 9401 } 9402 9403 /** 9404 * Returns the battery consumption (in microcoulomb) of this uid for a standard power bucket 9405 * of interest. 9406 * @param bucket standard power bucket of interest 9407 * @return consumption (in microcolombs) used by this uid for this power bucket 9408 */ 9409 @GuardedBy("mBsi") getMeasuredBatteryConsumptionUC(@tandardPowerBucket int bucket)9410 public long getMeasuredBatteryConsumptionUC(@StandardPowerBucket int bucket) { 9411 if (mBsi.mGlobalMeasuredEnergyStats == null 9412 || !mBsi.mGlobalMeasuredEnergyStats.isStandardBucketSupported(bucket)) { 9413 return POWER_DATA_UNAVAILABLE; 9414 } 9415 if (mUidMeasuredEnergyStats == null) { 9416 return 0L; // It is supported, but was never filled, so it must be 0 9417 } 9418 return mUidMeasuredEnergyStats.getAccumulatedStandardBucketCharge(bucket); 9419 } 9420 9421 /** 9422 * Returns the battery consumption (in microcoulombs) of this uid for a standard power 9423 * bucket and a process state, such as Uid.PROCESS_STATE_TOP. 9424 */ 9425 @GuardedBy("mBsi") getMeasuredBatteryConsumptionUC(@tandardPowerBucket int bucket, int processState)9426 public long getMeasuredBatteryConsumptionUC(@StandardPowerBucket int bucket, 9427 int processState) { 9428 if (mBsi.mGlobalMeasuredEnergyStats == null 9429 || !mBsi.mGlobalMeasuredEnergyStats.isStandardBucketSupported(bucket)) { 9430 return POWER_DATA_UNAVAILABLE; 9431 } 9432 if (mUidMeasuredEnergyStats == null) { 9433 return 0L; // It is supported, but was never filled, so it must be 0 9434 } 9435 return mUidMeasuredEnergyStats.getAccumulatedStandardBucketCharge(bucket, processState); 9436 } 9437 9438 @GuardedBy("mBsi") 9439 @Override getCustomConsumerMeasuredBatteryConsumptionUC()9440 public long[] getCustomConsumerMeasuredBatteryConsumptionUC() { 9441 if (mBsi.mGlobalMeasuredEnergyStats == null) { 9442 return null; 9443 } 9444 if (mUidMeasuredEnergyStats == null) { 9445 // Custom buckets may exist. But all values for this uid are 0 so we report all 0s. 9446 return new long[mBsi.mGlobalMeasuredEnergyStats.getNumberCustomPowerBuckets()]; 9447 } 9448 return mUidMeasuredEnergyStats.getAccumulatedCustomBucketCharges(); 9449 } 9450 9451 @GuardedBy("mBsi") 9452 @Override getBluetoothMeasuredBatteryConsumptionUC()9453 public long getBluetoothMeasuredBatteryConsumptionUC() { 9454 return getMeasuredBatteryConsumptionUC(MeasuredEnergyStats.POWER_BUCKET_BLUETOOTH); 9455 } 9456 9457 @GuardedBy("mBsi") 9458 @Override getBluetoothMeasuredBatteryConsumptionUC( @atteryConsumer.ProcessState int processState)9459 public long getBluetoothMeasuredBatteryConsumptionUC( 9460 @BatteryConsumer.ProcessState int processState) { 9461 return getMeasuredBatteryConsumptionUC(MeasuredEnergyStats.POWER_BUCKET_BLUETOOTH, 9462 processState); 9463 } 9464 9465 @GuardedBy("mBsi") 9466 @Override getCpuMeasuredBatteryConsumptionUC()9467 public long getCpuMeasuredBatteryConsumptionUC() { 9468 return getMeasuredBatteryConsumptionUC(MeasuredEnergyStats.POWER_BUCKET_CPU); 9469 } 9470 9471 @GuardedBy("mBsi") 9472 @Override getCpuMeasuredBatteryConsumptionUC( @atteryConsumer.ProcessState int processState)9473 public long getCpuMeasuredBatteryConsumptionUC( 9474 @BatteryConsumer.ProcessState int processState) { 9475 return getMeasuredBatteryConsumptionUC(MeasuredEnergyStats.POWER_BUCKET_CPU, 9476 processState); 9477 } 9478 9479 @GuardedBy("mBsi") 9480 @Override getGnssMeasuredBatteryConsumptionUC()9481 public long getGnssMeasuredBatteryConsumptionUC() { 9482 return getMeasuredBatteryConsumptionUC(MeasuredEnergyStats.POWER_BUCKET_GNSS); 9483 } 9484 9485 @GuardedBy("mBsi") 9486 @Override getMobileRadioMeasuredBatteryConsumptionUC()9487 public long getMobileRadioMeasuredBatteryConsumptionUC() { 9488 return getMeasuredBatteryConsumptionUC(MeasuredEnergyStats.POWER_BUCKET_MOBILE_RADIO); 9489 } 9490 9491 @GuardedBy("mBsi") 9492 @Override getMobileRadioMeasuredBatteryConsumptionUC(int processState)9493 public long getMobileRadioMeasuredBatteryConsumptionUC(int processState) { 9494 return getMeasuredBatteryConsumptionUC(MeasuredEnergyStats.POWER_BUCKET_MOBILE_RADIO, 9495 processState); 9496 } 9497 9498 @GuardedBy("mBsi") 9499 @Override getScreenOnMeasuredBatteryConsumptionUC()9500 public long getScreenOnMeasuredBatteryConsumptionUC() { 9501 return getMeasuredBatteryConsumptionUC(MeasuredEnergyStats.POWER_BUCKET_SCREEN_ON); 9502 } 9503 9504 @GuardedBy("mBsi") 9505 @Override getWifiMeasuredBatteryConsumptionUC()9506 public long getWifiMeasuredBatteryConsumptionUC() { 9507 return getMeasuredBatteryConsumptionUC(MeasuredEnergyStats.POWER_BUCKET_WIFI); 9508 } 9509 9510 @GuardedBy("mBsi") 9511 @Override getWifiMeasuredBatteryConsumptionUC(int processState)9512 public long getWifiMeasuredBatteryConsumptionUC(int processState) { 9513 return getMeasuredBatteryConsumptionUC(MeasuredEnergyStats.POWER_BUCKET_WIFI, 9514 processState); 9515 } 9516 9517 /** 9518 * Gets the minimum of the uid's foreground activity time and its PROCESS_STATE_TOP time 9519 * since last marked. Also sets the mark time for both these timers. 9520 * 9521 * @see CpuPowerCalculator 9522 * 9523 * @param doCalc if true, then calculate the minimum; else don't bother and return 0. Either 9524 * way, the mark is set. 9525 */ markProcessForegroundTimeUs(long elapsedRealtimeMs, boolean doCalc)9526 private long markProcessForegroundTimeUs(long elapsedRealtimeMs, 9527 boolean doCalc) { 9528 long fgTimeUs = 0; 9529 final StopwatchTimer fgTimer = mForegroundActivityTimer; 9530 if (fgTimer != null) { 9531 if (doCalc) fgTimeUs = fgTimer.getTimeSinceMarkLocked(elapsedRealtimeMs * 1000); 9532 fgTimer.setMark(elapsedRealtimeMs); 9533 } 9534 9535 long topTimeUs = 0; 9536 final StopwatchTimer topTimer = mProcessStateTimer[PROCESS_STATE_TOP]; 9537 if (topTimer != null) { 9538 if (doCalc) topTimeUs = topTimer.getTimeSinceMarkLocked(elapsedRealtimeMs * 1000); 9539 topTimer.setMark(elapsedRealtimeMs); 9540 } 9541 9542 // Return the min of the two 9543 return (topTimeUs < fgTimeUs) ? topTimeUs : fgTimeUs; 9544 } 9545 9546 9547 /** 9548 * Gets the uid's time spent using the GNSS since last marked. Also sets the mark time for 9549 * the GNSS timer. 9550 */ markGnssTimeUs(long elapsedRealtimeMs)9551 private long markGnssTimeUs(long elapsedRealtimeMs) { 9552 final Sensor sensor = mSensorStats.get(Sensor.GPS); 9553 if (sensor == null) { 9554 return 0; 9555 } 9556 9557 final StopwatchTimer timer = sensor.mTimer; 9558 if (timer == null) { 9559 return 0; 9560 } 9561 9562 final long gnssTimeUs = timer.getTimeSinceMarkLocked(elapsedRealtimeMs * 1000); 9563 timer.setMark(elapsedRealtimeMs); 9564 return gnssTimeUs; 9565 } 9566 createAudioTurnedOnTimerLocked()9567 public StopwatchTimer createAudioTurnedOnTimerLocked() { 9568 if (mAudioTurnedOnTimer == null) { 9569 mAudioTurnedOnTimer = new StopwatchTimer(mBsi.mClock, Uid.this, AUDIO_TURNED_ON, 9570 mBsi.mAudioTurnedOnTimers, mBsi.mOnBatteryTimeBase); 9571 } 9572 return mAudioTurnedOnTimer; 9573 } 9574 noteAudioTurnedOnLocked(long elapsedRealtimeMs)9575 public void noteAudioTurnedOnLocked(long elapsedRealtimeMs) { 9576 createAudioTurnedOnTimerLocked().startRunningLocked(elapsedRealtimeMs); 9577 } 9578 noteAudioTurnedOffLocked(long elapsedRealtimeMs)9579 public void noteAudioTurnedOffLocked(long elapsedRealtimeMs) { 9580 if (mAudioTurnedOnTimer != null) { 9581 mAudioTurnedOnTimer.stopRunningLocked(elapsedRealtimeMs); 9582 } 9583 } 9584 noteResetAudioLocked(long elapsedRealtimeMs)9585 public void noteResetAudioLocked(long elapsedRealtimeMs) { 9586 if (mAudioTurnedOnTimer != null) { 9587 mAudioTurnedOnTimer.stopAllRunningLocked(elapsedRealtimeMs); 9588 } 9589 } 9590 createVideoTurnedOnTimerLocked()9591 public StopwatchTimer createVideoTurnedOnTimerLocked() { 9592 if (mVideoTurnedOnTimer == null) { 9593 mVideoTurnedOnTimer = new StopwatchTimer(mBsi.mClock, Uid.this, VIDEO_TURNED_ON, 9594 mBsi.mVideoTurnedOnTimers, mBsi.mOnBatteryTimeBase); 9595 } 9596 return mVideoTurnedOnTimer; 9597 } 9598 noteVideoTurnedOnLocked(long elapsedRealtimeMs)9599 public void noteVideoTurnedOnLocked(long elapsedRealtimeMs) { 9600 createVideoTurnedOnTimerLocked().startRunningLocked(elapsedRealtimeMs); 9601 } 9602 noteVideoTurnedOffLocked(long elapsedRealtimeMs)9603 public void noteVideoTurnedOffLocked(long elapsedRealtimeMs) { 9604 if (mVideoTurnedOnTimer != null) { 9605 mVideoTurnedOnTimer.stopRunningLocked(elapsedRealtimeMs); 9606 } 9607 } 9608 noteResetVideoLocked(long elapsedRealtimeMs)9609 public void noteResetVideoLocked(long elapsedRealtimeMs) { 9610 if (mVideoTurnedOnTimer != null) { 9611 mVideoTurnedOnTimer.stopAllRunningLocked(elapsedRealtimeMs); 9612 } 9613 } 9614 createFlashlightTurnedOnTimerLocked()9615 public StopwatchTimer createFlashlightTurnedOnTimerLocked() { 9616 if (mFlashlightTurnedOnTimer == null) { 9617 mFlashlightTurnedOnTimer = new StopwatchTimer(mBsi.mClock, Uid.this, 9618 FLASHLIGHT_TURNED_ON, mBsi.mFlashlightTurnedOnTimers, mBsi.mOnBatteryTimeBase); 9619 } 9620 return mFlashlightTurnedOnTimer; 9621 } 9622 noteFlashlightTurnedOnLocked(long elapsedRealtimeMs)9623 public void noteFlashlightTurnedOnLocked(long elapsedRealtimeMs) { 9624 createFlashlightTurnedOnTimerLocked().startRunningLocked(elapsedRealtimeMs); 9625 } 9626 noteFlashlightTurnedOffLocked(long elapsedRealtimeMs)9627 public void noteFlashlightTurnedOffLocked(long elapsedRealtimeMs) { 9628 if (mFlashlightTurnedOnTimer != null) { 9629 mFlashlightTurnedOnTimer.stopRunningLocked(elapsedRealtimeMs); 9630 } 9631 } 9632 noteResetFlashlightLocked(long elapsedRealtimeMs)9633 public void noteResetFlashlightLocked(long elapsedRealtimeMs) { 9634 if (mFlashlightTurnedOnTimer != null) { 9635 mFlashlightTurnedOnTimer.stopAllRunningLocked(elapsedRealtimeMs); 9636 } 9637 } 9638 createCameraTurnedOnTimerLocked()9639 public StopwatchTimer createCameraTurnedOnTimerLocked() { 9640 if (mCameraTurnedOnTimer == null) { 9641 mCameraTurnedOnTimer = new StopwatchTimer(mBsi.mClock, Uid.this, CAMERA_TURNED_ON, 9642 mBsi.mCameraTurnedOnTimers, mBsi.mOnBatteryTimeBase); 9643 } 9644 return mCameraTurnedOnTimer; 9645 } 9646 noteCameraTurnedOnLocked(long elapsedRealtimeMs)9647 public void noteCameraTurnedOnLocked(long elapsedRealtimeMs) { 9648 createCameraTurnedOnTimerLocked().startRunningLocked(elapsedRealtimeMs); 9649 } 9650 noteCameraTurnedOffLocked(long elapsedRealtimeMs)9651 public void noteCameraTurnedOffLocked(long elapsedRealtimeMs) { 9652 if (mCameraTurnedOnTimer != null) { 9653 mCameraTurnedOnTimer.stopRunningLocked(elapsedRealtimeMs); 9654 } 9655 } 9656 noteResetCameraLocked(long elapsedRealtimeMs)9657 public void noteResetCameraLocked(long elapsedRealtimeMs) { 9658 if (mCameraTurnedOnTimer != null) { 9659 mCameraTurnedOnTimer.stopAllRunningLocked(elapsedRealtimeMs); 9660 } 9661 } 9662 createForegroundActivityTimerLocked()9663 public StopwatchTimer createForegroundActivityTimerLocked() { 9664 if (mForegroundActivityTimer == null) { 9665 mForegroundActivityTimer = new StopwatchTimer(mBsi.mClock, Uid.this, 9666 FOREGROUND_ACTIVITY, null, mBsi.mOnBatteryTimeBase); 9667 } 9668 return mForegroundActivityTimer; 9669 } 9670 createForegroundServiceTimerLocked()9671 public StopwatchTimer createForegroundServiceTimerLocked() { 9672 if (mForegroundServiceTimer == null) { 9673 mForegroundServiceTimer = new StopwatchTimer(mBsi.mClock, Uid.this, 9674 FOREGROUND_SERVICE, null, mBsi.mOnBatteryTimeBase); 9675 } 9676 return mForegroundServiceTimer; 9677 } 9678 createAggregatedPartialWakelockTimerLocked()9679 public DualTimer createAggregatedPartialWakelockTimerLocked() { 9680 if (mAggregatedPartialWakelockTimer == null) { 9681 mAggregatedPartialWakelockTimer = new DualTimer(mBsi.mClock, this, 9682 AGGREGATED_WAKE_TYPE_PARTIAL, null, 9683 mBsi.mOnBatteryScreenOffTimeBase, mOnBatteryScreenOffBackgroundTimeBase); 9684 } 9685 return mAggregatedPartialWakelockTimer; 9686 } 9687 createBluetoothScanTimerLocked()9688 public DualTimer createBluetoothScanTimerLocked() { 9689 if (mBluetoothScanTimer == null) { 9690 mBluetoothScanTimer = new DualTimer(mBsi.mClock, Uid.this, BLUETOOTH_SCAN_ON, 9691 mBsi.mBluetoothScanOnTimers, mBsi.mOnBatteryTimeBase, 9692 mOnBatteryBackgroundTimeBase); 9693 } 9694 return mBluetoothScanTimer; 9695 } 9696 createBluetoothUnoptimizedScanTimerLocked()9697 public DualTimer createBluetoothUnoptimizedScanTimerLocked() { 9698 if (mBluetoothUnoptimizedScanTimer == null) { 9699 mBluetoothUnoptimizedScanTimer = new DualTimer(mBsi.mClock, Uid.this, 9700 BLUETOOTH_UNOPTIMIZED_SCAN_ON, null, 9701 mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase); 9702 } 9703 return mBluetoothUnoptimizedScanTimer; 9704 } 9705 noteBluetoothScanStartedLocked(long elapsedRealtimeMs, boolean isUnoptimized)9706 public void noteBluetoothScanStartedLocked(long elapsedRealtimeMs, 9707 boolean isUnoptimized) { 9708 createBluetoothScanTimerLocked().startRunningLocked(elapsedRealtimeMs); 9709 if (isUnoptimized) { 9710 createBluetoothUnoptimizedScanTimerLocked().startRunningLocked(elapsedRealtimeMs); 9711 } 9712 } 9713 noteBluetoothScanStoppedLocked(long elapsedRealtimeMs, boolean isUnoptimized)9714 public void noteBluetoothScanStoppedLocked(long elapsedRealtimeMs, boolean isUnoptimized) { 9715 if (mBluetoothScanTimer != null) { 9716 mBluetoothScanTimer.stopRunningLocked(elapsedRealtimeMs); 9717 } 9718 if (isUnoptimized && mBluetoothUnoptimizedScanTimer != null) { 9719 mBluetoothUnoptimizedScanTimer.stopRunningLocked(elapsedRealtimeMs); 9720 } 9721 } 9722 noteResetBluetoothScanLocked(long elapsedRealtimeMs)9723 public void noteResetBluetoothScanLocked(long elapsedRealtimeMs) { 9724 if (mBluetoothScanTimer != null) { 9725 mBluetoothScanTimer.stopAllRunningLocked(elapsedRealtimeMs); 9726 } 9727 if (mBluetoothUnoptimizedScanTimer != null) { 9728 mBluetoothUnoptimizedScanTimer.stopAllRunningLocked(elapsedRealtimeMs); 9729 } 9730 } 9731 createBluetoothScanResultCounterLocked()9732 public Counter createBluetoothScanResultCounterLocked() { 9733 if (mBluetoothScanResultCounter == null) { 9734 mBluetoothScanResultCounter = new Counter(mBsi.mOnBatteryTimeBase); 9735 } 9736 return mBluetoothScanResultCounter; 9737 } 9738 createBluetoothScanResultBgCounterLocked()9739 public Counter createBluetoothScanResultBgCounterLocked() { 9740 if (mBluetoothScanResultBgCounter == null) { 9741 mBluetoothScanResultBgCounter = new Counter(mOnBatteryBackgroundTimeBase); 9742 } 9743 return mBluetoothScanResultBgCounter; 9744 } 9745 noteBluetoothScanResultsLocked(int numNewResults)9746 public void noteBluetoothScanResultsLocked(int numNewResults) { 9747 createBluetoothScanResultCounterLocked().addAtomic(numNewResults); 9748 // Uses background timebase, so the count will only be incremented if uid in background. 9749 createBluetoothScanResultBgCounterLocked().addAtomic(numNewResults); 9750 } 9751 9752 @Override noteActivityResumedLocked(long elapsedRealtimeMs)9753 public void noteActivityResumedLocked(long elapsedRealtimeMs) { 9754 // We always start, since we want multiple foreground PIDs to nest 9755 createForegroundActivityTimerLocked().startRunningLocked(elapsedRealtimeMs); 9756 } 9757 9758 @Override noteActivityPausedLocked(long elapsedRealtimeMs)9759 public void noteActivityPausedLocked(long elapsedRealtimeMs) { 9760 if (mForegroundActivityTimer != null) { 9761 mForegroundActivityTimer.stopRunningLocked(elapsedRealtimeMs); 9762 } 9763 } 9764 noteForegroundServiceResumedLocked(long elapsedRealtimeMs)9765 public void noteForegroundServiceResumedLocked(long elapsedRealtimeMs) { 9766 createForegroundServiceTimerLocked().startRunningLocked(elapsedRealtimeMs); 9767 } 9768 noteForegroundServicePausedLocked(long elapsedRealtimeMs)9769 public void noteForegroundServicePausedLocked(long elapsedRealtimeMs) { 9770 if (mForegroundServiceTimer != null) { 9771 mForegroundServiceTimer.stopRunningLocked(elapsedRealtimeMs); 9772 } 9773 } 9774 createVibratorOnTimerLocked()9775 public BatchTimer createVibratorOnTimerLocked() { 9776 if (mVibratorOnTimer == null) { 9777 mVibratorOnTimer = new BatchTimer(mBsi.mClock, Uid.this, VIBRATOR_ON, 9778 mBsi.mOnBatteryTimeBase); 9779 } 9780 return mVibratorOnTimer; 9781 } 9782 noteVibratorOnLocked(long durationMillis, long elapsedRealtimeMs)9783 public void noteVibratorOnLocked(long durationMillis, long elapsedRealtimeMs) { 9784 createVibratorOnTimerLocked().addDuration(mBsi, durationMillis, elapsedRealtimeMs); 9785 } 9786 noteVibratorOffLocked(long elapsedRealtimeMs)9787 public void noteVibratorOffLocked(long elapsedRealtimeMs) { 9788 if (mVibratorOnTimer != null) { 9789 mVibratorOnTimer.abortLastDuration(mBsi, elapsedRealtimeMs); 9790 } 9791 } 9792 9793 @Override 9794 @UnsupportedAppUsage getWifiRunningTime(long elapsedRealtimeUs, int which)9795 public long getWifiRunningTime(long elapsedRealtimeUs, int which) { 9796 if (mWifiRunningTimer == null) { 9797 return 0; 9798 } 9799 return mWifiRunningTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 9800 } 9801 9802 @Override getFullWifiLockTime(long elapsedRealtimeUs, int which)9803 public long getFullWifiLockTime(long elapsedRealtimeUs, int which) { 9804 if (mFullWifiLockTimer == null) { 9805 return 0; 9806 } 9807 return mFullWifiLockTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 9808 } 9809 9810 @Override 9811 @UnsupportedAppUsage getWifiScanTime(long elapsedRealtimeUs, int which)9812 public long getWifiScanTime(long elapsedRealtimeUs, int which) { 9813 if (mWifiScanTimer == null) { 9814 return 0; 9815 } 9816 return mWifiScanTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 9817 } 9818 9819 @Override getWifiScanCount(int which)9820 public int getWifiScanCount(int which) { 9821 if (mWifiScanTimer == null) { 9822 return 0; 9823 } 9824 return mWifiScanTimer.getCountLocked(which); 9825 } 9826 9827 @Override getWifiScanTimer()9828 public Timer getWifiScanTimer() { 9829 return mWifiScanTimer; 9830 } 9831 9832 @Override getWifiScanBackgroundCount(int which)9833 public int getWifiScanBackgroundCount(int which) { 9834 if (mWifiScanTimer == null || mWifiScanTimer.getSubTimer() == null) { 9835 return 0; 9836 } 9837 return mWifiScanTimer.getSubTimer().getCountLocked(which); 9838 } 9839 9840 @Override getWifiScanActualTime(final long elapsedRealtimeUs)9841 public long getWifiScanActualTime(final long elapsedRealtimeUs) { 9842 if (mWifiScanTimer == null) { 9843 return 0; 9844 } 9845 final long elapsedRealtimeMs = (elapsedRealtimeUs + 500) / 1000; 9846 return mWifiScanTimer.getTotalDurationMsLocked(elapsedRealtimeMs) * 1000; 9847 } 9848 9849 @Override getWifiScanBackgroundTime(final long elapsedRealtimeUs)9850 public long getWifiScanBackgroundTime(final long elapsedRealtimeUs) { 9851 if (mWifiScanTimer == null || mWifiScanTimer.getSubTimer() == null) { 9852 return 0; 9853 } 9854 final long elapsedRealtimeMs = (elapsedRealtimeUs + 500) / 1000; 9855 return mWifiScanTimer.getSubTimer().getTotalDurationMsLocked(elapsedRealtimeMs) * 1000; 9856 } 9857 9858 @Override getWifiScanBackgroundTimer()9859 public Timer getWifiScanBackgroundTimer() { 9860 if (mWifiScanTimer == null) { 9861 return null; 9862 } 9863 return mWifiScanTimer.getSubTimer(); 9864 } 9865 9866 @Override getWifiBatchedScanTime(int csphBin, long elapsedRealtimeUs, int which)9867 public long getWifiBatchedScanTime(int csphBin, long elapsedRealtimeUs, int which) { 9868 if (csphBin < 0 || csphBin >= NUM_WIFI_BATCHED_SCAN_BINS) return 0; 9869 if (mWifiBatchedScanTimer[csphBin] == null) { 9870 return 0; 9871 } 9872 return mWifiBatchedScanTimer[csphBin].getTotalTimeLocked(elapsedRealtimeUs, which); 9873 } 9874 9875 @Override getWifiBatchedScanCount(int csphBin, int which)9876 public int getWifiBatchedScanCount(int csphBin, int which) { 9877 if (csphBin < 0 || csphBin >= NUM_WIFI_BATCHED_SCAN_BINS) return 0; 9878 if (mWifiBatchedScanTimer[csphBin] == null) { 9879 return 0; 9880 } 9881 return mWifiBatchedScanTimer[csphBin].getCountLocked(which); 9882 } 9883 9884 @Override getWifiMulticastTime(long elapsedRealtimeUs, int which)9885 public long getWifiMulticastTime(long elapsedRealtimeUs, int which) { 9886 if (mWifiMulticastTimer == null) { 9887 return 0; 9888 } 9889 return mWifiMulticastTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 9890 } 9891 9892 @Override getAudioTurnedOnTimer()9893 public Timer getAudioTurnedOnTimer() { 9894 return mAudioTurnedOnTimer; 9895 } 9896 9897 @Override getVideoTurnedOnTimer()9898 public Timer getVideoTurnedOnTimer() { 9899 return mVideoTurnedOnTimer; 9900 } 9901 9902 @Override getFlashlightTurnedOnTimer()9903 public Timer getFlashlightTurnedOnTimer() { 9904 return mFlashlightTurnedOnTimer; 9905 } 9906 9907 @Override getCameraTurnedOnTimer()9908 public Timer getCameraTurnedOnTimer() { 9909 return mCameraTurnedOnTimer; 9910 } 9911 9912 @Override getForegroundActivityTimer()9913 public Timer getForegroundActivityTimer() { 9914 return mForegroundActivityTimer; 9915 } 9916 9917 @Override getForegroundServiceTimer()9918 public Timer getForegroundServiceTimer() { 9919 return mForegroundServiceTimer; 9920 } 9921 9922 @Override getBluetoothScanTimer()9923 public Timer getBluetoothScanTimer() { 9924 return mBluetoothScanTimer; 9925 } 9926 9927 @Override getBluetoothScanBackgroundTimer()9928 public Timer getBluetoothScanBackgroundTimer() { 9929 if (mBluetoothScanTimer == null) { 9930 return null; 9931 } 9932 return mBluetoothScanTimer.getSubTimer(); 9933 } 9934 9935 @Override getBluetoothUnoptimizedScanTimer()9936 public Timer getBluetoothUnoptimizedScanTimer() { 9937 return mBluetoothUnoptimizedScanTimer; 9938 } 9939 9940 @Override getBluetoothUnoptimizedScanBackgroundTimer()9941 public Timer getBluetoothUnoptimizedScanBackgroundTimer() { 9942 if (mBluetoothUnoptimizedScanTimer == null) { 9943 return null; 9944 } 9945 return mBluetoothUnoptimizedScanTimer.getSubTimer(); 9946 } 9947 9948 @Override getBluetoothScanResultCounter()9949 public Counter getBluetoothScanResultCounter() { 9950 return mBluetoothScanResultCounter; 9951 } 9952 9953 @Override getBluetoothScanResultBgCounter()9954 public Counter getBluetoothScanResultBgCounter() { 9955 return mBluetoothScanResultBgCounter; 9956 } 9957 makeProcessState(int i, Parcel in)9958 void makeProcessState(int i, Parcel in) { 9959 if (i < 0 || i >= NUM_PROCESS_STATE) return; 9960 9961 detachIfNotNull(mProcessStateTimer[i]); 9962 if (in == null) { 9963 mProcessStateTimer[i] = new StopwatchTimer(mBsi.mClock, this, PROCESS_STATE, null, 9964 mBsi.mOnBatteryTimeBase); 9965 } else { 9966 mProcessStateTimer[i] = new StopwatchTimer(mBsi.mClock, this, PROCESS_STATE, null, 9967 mBsi.mOnBatteryTimeBase, in); 9968 } 9969 } 9970 9971 @Override getProcessStateTime(int state, long elapsedRealtimeUs, int which)9972 public long getProcessStateTime(int state, long elapsedRealtimeUs, int which) { 9973 if (state < 0 || state >= NUM_PROCESS_STATE) return 0; 9974 if (mProcessStateTimer[state] == null) { 9975 return 0; 9976 } 9977 return mProcessStateTimer[state].getTotalTimeLocked(elapsedRealtimeUs, which); 9978 } 9979 9980 @Override getProcessStateTimer(int state)9981 public Timer getProcessStateTimer(int state) { 9982 if (state < 0 || state >= NUM_PROCESS_STATE) return null; 9983 return mProcessStateTimer[state]; 9984 } 9985 9986 @Override getVibratorOnTimer()9987 public Timer getVibratorOnTimer() { 9988 return mVibratorOnTimer; 9989 } 9990 9991 @Override noteUserActivityLocked(@owerManager.UserActivityEvent int event)9992 public void noteUserActivityLocked(@PowerManager.UserActivityEvent int event) { 9993 if (mUserActivityCounters == null) { 9994 initUserActivityLocked(); 9995 } 9996 if (event >= 0 && event < NUM_USER_ACTIVITY_TYPES) { 9997 mUserActivityCounters[event].stepAtomic(); 9998 } else { 9999 Slog.w(TAG, "Unknown user activity type " + event + " was specified.", 10000 new Throwable()); 10001 } 10002 } 10003 10004 @Override hasUserActivity()10005 public boolean hasUserActivity() { 10006 return mUserActivityCounters != null; 10007 } 10008 10009 @Override getUserActivityCount(int type, int which)10010 public int getUserActivityCount(int type, int which) { 10011 if (mUserActivityCounters == null) { 10012 return 0; 10013 } 10014 return mUserActivityCounters[type].getCountLocked(which); 10015 } 10016 makeWifiBatchedScanBin(int i, Parcel in)10017 void makeWifiBatchedScanBin(int i, Parcel in) { 10018 if (i < 0 || i >= NUM_WIFI_BATCHED_SCAN_BINS) return; 10019 10020 ArrayList<StopwatchTimer> collected = mBsi.mWifiBatchedScanTimers.get(i); 10021 if (collected == null) { 10022 collected = new ArrayList<StopwatchTimer>(); 10023 mBsi.mWifiBatchedScanTimers.put(i, collected); 10024 } 10025 detachIfNotNull(mWifiBatchedScanTimer[i]); 10026 if (in == null) { 10027 mWifiBatchedScanTimer[i] = new StopwatchTimer(mBsi.mClock, this, WIFI_BATCHED_SCAN, 10028 collected, mBsi.mOnBatteryTimeBase); 10029 } else { 10030 mWifiBatchedScanTimer[i] = new StopwatchTimer(mBsi.mClock, this, WIFI_BATCHED_SCAN, 10031 collected, mBsi.mOnBatteryTimeBase, in); 10032 } 10033 } 10034 10035 initUserActivityLocked()10036 void initUserActivityLocked() { 10037 detachIfNotNull(mUserActivityCounters); 10038 mUserActivityCounters = new Counter[NUM_USER_ACTIVITY_TYPES]; 10039 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) { 10040 mUserActivityCounters[i] = new Counter(mBsi.mOnBatteryTimeBase); 10041 } 10042 } 10043 noteNetworkActivityLocked(int type, long deltaBytes, long deltaPackets)10044 void noteNetworkActivityLocked(int type, long deltaBytes, long deltaPackets) { 10045 ensureNetworkActivityLocked(); 10046 if (type >= 0 && type < NUM_NETWORK_ACTIVITY_TYPES) { 10047 mNetworkByteActivityCounters[type].addCountLocked(deltaBytes); 10048 mNetworkPacketActivityCounters[type].addCountLocked(deltaPackets); 10049 } else { 10050 Slog.w(TAG, "Unknown network activity type " + type + " was specified.", 10051 new Throwable()); 10052 } 10053 } 10054 noteMobileRadioActiveTimeLocked(long batteryUptimeDeltaUs, long elapsedTimeMs)10055 void noteMobileRadioActiveTimeLocked(long batteryUptimeDeltaUs, long elapsedTimeMs) { 10056 ensureNetworkActivityLocked(); 10057 getMobileRadioActiveTimeCounter().increment(batteryUptimeDeltaUs, elapsedTimeMs); 10058 mMobileRadioActiveCount.addCountLocked(1); 10059 } 10060 getMobileRadioActiveTimeCounter()10061 private TimeMultiStateCounter getMobileRadioActiveTimeCounter() { 10062 if (mMobileRadioActiveTime == null) { 10063 final long timestampMs = mBsi.mClock.elapsedRealtime(); 10064 mMobileRadioActiveTime = new TimeMultiStateCounter( 10065 mBsi.mOnBatteryTimeBase, BatteryConsumer.PROCESS_STATE_COUNT, timestampMs); 10066 mMobileRadioActiveTime.setState( 10067 mapUidProcessStateToBatteryConsumerProcessState(mProcessState), 10068 timestampMs); 10069 mMobileRadioActiveTime.update(0, timestampMs); 10070 } 10071 return mMobileRadioActiveTime; 10072 } 10073 10074 @Override hasNetworkActivity()10075 public boolean hasNetworkActivity() { 10076 return mNetworkByteActivityCounters != null; 10077 } 10078 10079 @Override getNetworkActivityBytes(int type, int which)10080 public long getNetworkActivityBytes(int type, int which) { 10081 if (mNetworkByteActivityCounters != null && type >= 0 10082 && type < mNetworkByteActivityCounters.length) { 10083 return mNetworkByteActivityCounters[type].getCountLocked(which); 10084 } else { 10085 return 0; 10086 } 10087 } 10088 10089 @Override getNetworkActivityPackets(int type, int which)10090 public long getNetworkActivityPackets(int type, int which) { 10091 if (mNetworkPacketActivityCounters != null && type >= 0 10092 && type < mNetworkPacketActivityCounters.length) { 10093 return mNetworkPacketActivityCounters[type].getCountLocked(which); 10094 } else { 10095 return 0; 10096 } 10097 } 10098 10099 @Override getMobileRadioActiveTime(int which)10100 public long getMobileRadioActiveTime(int which) { 10101 return getMobileRadioActiveTimeInProcessState(BatteryConsumer.PROCESS_STATE_ANY); 10102 } 10103 10104 @Override getMobileRadioActiveTimeInProcessState( @atteryConsumer.ProcessState int processState)10105 public long getMobileRadioActiveTimeInProcessState( 10106 @BatteryConsumer.ProcessState int processState) { 10107 if (mMobileRadioActiveTime == null) { 10108 return 0; 10109 } 10110 if (processState == BatteryConsumer.PROCESS_STATE_ANY) { 10111 return mMobileRadioActiveTime.getTotalCountLocked(); 10112 } else { 10113 return mMobileRadioActiveTime.getCountForProcessState(processState); 10114 } 10115 } 10116 10117 @Override getMobileRadioActiveCount(int which)10118 public int getMobileRadioActiveCount(int which) { 10119 return mMobileRadioActiveCount != null 10120 ? (int)mMobileRadioActiveCount.getCountLocked(which) : 0; 10121 } 10122 10123 @Override getUserCpuTimeUs(int which)10124 public long getUserCpuTimeUs(int which) { 10125 return mUserCpuTime.getCountLocked(which); 10126 } 10127 10128 @Override getSystemCpuTimeUs(int which)10129 public long getSystemCpuTimeUs(int which) { 10130 return mSystemCpuTime.getCountLocked(which); 10131 } 10132 10133 @Override getTimeAtCpuSpeed(int cluster, int step, int which)10134 public long getTimeAtCpuSpeed(int cluster, int step, int which) { 10135 if (mCpuClusterSpeedTimesUs != null) { 10136 if (cluster >= 0 && cluster < mCpuClusterSpeedTimesUs.length) { 10137 final LongSamplingCounter[] cpuSpeedTimesUs = mCpuClusterSpeedTimesUs[cluster]; 10138 if (cpuSpeedTimesUs != null) { 10139 if (step >= 0 && step < cpuSpeedTimesUs.length) { 10140 final LongSamplingCounter c = cpuSpeedTimesUs[step]; 10141 if (c != null) { 10142 return c.getCountLocked(which); 10143 } 10144 } 10145 } 10146 } 10147 } 10148 return 0; 10149 } 10150 noteMobileRadioApWakeupLocked()10151 public void noteMobileRadioApWakeupLocked() { 10152 if (mMobileRadioApWakeupCount == null) { 10153 mMobileRadioApWakeupCount = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); 10154 } 10155 mMobileRadioApWakeupCount.addCountLocked(1); 10156 } 10157 10158 @Override getMobileRadioApWakeupCount(int which)10159 public long getMobileRadioApWakeupCount(int which) { 10160 if (mMobileRadioApWakeupCount != null) { 10161 return mMobileRadioApWakeupCount.getCountLocked(which); 10162 } 10163 return 0; 10164 } 10165 noteWifiRadioApWakeupLocked()10166 public void noteWifiRadioApWakeupLocked() { 10167 if (mWifiRadioApWakeupCount == null) { 10168 mWifiRadioApWakeupCount = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); 10169 } 10170 mWifiRadioApWakeupCount.addCountLocked(1); 10171 } 10172 10173 @Override getWifiRadioApWakeupCount(int which)10174 public long getWifiRadioApWakeupCount(int which) { 10175 if (mWifiRadioApWakeupCount != null) { 10176 return mWifiRadioApWakeupCount.getCountLocked(which); 10177 } 10178 return 0; 10179 } 10180 10181 @Override getDeferredJobsCheckinLineLocked(StringBuilder sb, int which)10182 public void getDeferredJobsCheckinLineLocked(StringBuilder sb, int which) { 10183 sb.setLength(0); 10184 final int deferredEventCount = mJobsDeferredEventCount.getCountLocked(which); 10185 if (deferredEventCount == 0) { 10186 return; 10187 } 10188 final int deferredCount = mJobsDeferredCount.getCountLocked(which); 10189 final long totalLatency = mJobsFreshnessTimeMs.getCountLocked(which); 10190 sb.append(deferredEventCount); sb.append(','); 10191 sb.append(deferredCount); sb.append(','); 10192 sb.append(totalLatency); 10193 for (int i = 0; i < JOB_FRESHNESS_BUCKETS.length; i++) { 10194 if (mJobsFreshnessBuckets[i] == null) { 10195 sb.append(",0"); 10196 } else { 10197 sb.append(","); 10198 sb.append(mJobsFreshnessBuckets[i].getCountLocked(which)); 10199 } 10200 } 10201 } 10202 10203 @Override getDeferredJobsLineLocked(StringBuilder sb, int which)10204 public void getDeferredJobsLineLocked(StringBuilder sb, int which) { 10205 sb.setLength(0); 10206 final int deferredEventCount = mJobsDeferredEventCount.getCountLocked(which); 10207 if (deferredEventCount == 0) { 10208 return; 10209 } 10210 final int deferredCount = mJobsDeferredCount.getCountLocked(which); 10211 final long totalLatency = mJobsFreshnessTimeMs.getCountLocked(which); 10212 sb.append("times="); sb.append(deferredEventCount); sb.append(", "); 10213 sb.append("count="); sb.append(deferredCount); sb.append(", "); 10214 sb.append("totalLatencyMs="); sb.append(totalLatency); sb.append(", "); 10215 for (int i = 0; i < JOB_FRESHNESS_BUCKETS.length; i++) { 10216 sb.append("<"); sb.append(JOB_FRESHNESS_BUCKETS[i]); sb.append("ms="); 10217 if (mJobsFreshnessBuckets[i] == null) { 10218 sb.append("0"); 10219 } else { 10220 sb.append(mJobsFreshnessBuckets[i].getCountLocked(which)); 10221 } 10222 sb.append(" "); 10223 } 10224 } 10225 ensureNetworkActivityLocked()10226 void ensureNetworkActivityLocked() { 10227 if (mNetworkByteActivityCounters != null) { 10228 return; 10229 } 10230 10231 mNetworkByteActivityCounters = new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES]; 10232 mNetworkPacketActivityCounters = new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES]; 10233 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 10234 mNetworkByteActivityCounters[i] = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); 10235 mNetworkPacketActivityCounters[i] = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); 10236 } 10237 mMobileRadioActiveCount = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); 10238 } 10239 10240 /** 10241 * Clear all stats for this uid. Returns true if the uid is completely 10242 * inactive so can be dropped. 10243 */ 10244 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) reset(long uptimeUs, long realtimeUs, int resetReason)10245 public boolean reset(long uptimeUs, long realtimeUs, int resetReason) { 10246 boolean active = false; 10247 10248 mOnBatteryBackgroundTimeBase.init(uptimeUs, realtimeUs); 10249 mOnBatteryScreenOffBackgroundTimeBase.init(uptimeUs, realtimeUs); 10250 10251 if (mWifiRunningTimer != null) { 10252 active |= !mWifiRunningTimer.reset(false, realtimeUs); 10253 active |= mWifiRunning; 10254 } 10255 if (mFullWifiLockTimer != null) { 10256 active |= !mFullWifiLockTimer.reset(false, realtimeUs); 10257 active |= mFullWifiLockOut; 10258 } 10259 if (mWifiScanTimer != null) { 10260 active |= !mWifiScanTimer.reset(false, realtimeUs); 10261 active |= mWifiScanStarted; 10262 } 10263 if (mWifiBatchedScanTimer != null) { 10264 for (int i = 0; i < NUM_WIFI_BATCHED_SCAN_BINS; i++) { 10265 if (mWifiBatchedScanTimer[i] != null) { 10266 active |= !mWifiBatchedScanTimer[i].reset(false, realtimeUs); 10267 } 10268 } 10269 active |= (mWifiBatchedScanBinStarted != NO_BATCHED_SCAN_STARTED); 10270 } 10271 if (mWifiMulticastTimer != null) { 10272 active |= !mWifiMulticastTimer.reset(false, realtimeUs); 10273 active |= (mWifiMulticastWakelockCount > 0); 10274 } 10275 10276 active |= !resetIfNotNull(mAudioTurnedOnTimer, false, realtimeUs); 10277 active |= !resetIfNotNull(mVideoTurnedOnTimer, false, realtimeUs); 10278 active |= !resetIfNotNull(mFlashlightTurnedOnTimer, false, realtimeUs); 10279 active |= !resetIfNotNull(mCameraTurnedOnTimer, false, realtimeUs); 10280 active |= !resetIfNotNull(mForegroundActivityTimer, false, realtimeUs); 10281 active |= !resetIfNotNull(mForegroundServiceTimer, false, realtimeUs); 10282 active |= !resetIfNotNull(mAggregatedPartialWakelockTimer, false, realtimeUs); 10283 active |= !resetIfNotNull(mBluetoothScanTimer, false, realtimeUs); 10284 active |= !resetIfNotNull(mBluetoothUnoptimizedScanTimer, false, realtimeUs); 10285 10286 resetIfNotNull(mBluetoothScanResultCounter, false, realtimeUs); 10287 resetIfNotNull(mBluetoothScanResultBgCounter, false, realtimeUs); 10288 10289 if (mProcessStateTimer != null) { 10290 for (int i = 0; i < NUM_PROCESS_STATE; i++) { 10291 active |= !resetIfNotNull(mProcessStateTimer[i], false, realtimeUs); 10292 } 10293 active |= (mProcessState != Uid.PROCESS_STATE_NONEXISTENT); 10294 } 10295 if (mVibratorOnTimer != null) { 10296 if (mVibratorOnTimer.reset(false, realtimeUs)) { 10297 mVibratorOnTimer.detach(); 10298 mVibratorOnTimer = null; 10299 } else { 10300 active = true; 10301 } 10302 } 10303 10304 resetIfNotNull(mUserActivityCounters, false, realtimeUs); 10305 10306 resetIfNotNull(mNetworkByteActivityCounters, false, realtimeUs); 10307 resetIfNotNull(mNetworkPacketActivityCounters, false, realtimeUs); 10308 resetIfNotNull(mMobileRadioActiveTime, false, realtimeUs); 10309 resetIfNotNull(mMobileRadioActiveCount, false, realtimeUs); 10310 10311 resetIfNotNull(mWifiControllerActivity, false, realtimeUs); 10312 resetIfNotNull(mBluetoothControllerActivity, false, realtimeUs); 10313 resetIfNotNull(mModemControllerActivity, false, realtimeUs); 10314 10315 if (resetReason == RESET_REASON_MEASURED_ENERGY_BUCKETS_CHANGE) { 10316 mUidMeasuredEnergyStats = null; 10317 } else { 10318 MeasuredEnergyStats.resetIfNotNull(mUidMeasuredEnergyStats); 10319 } 10320 10321 resetIfNotNull(mUserCpuTime, false, realtimeUs); 10322 resetIfNotNull(mSystemCpuTime, false, realtimeUs); 10323 10324 resetIfNotNull(mCpuClusterSpeedTimesUs, false, realtimeUs); 10325 10326 resetIfNotNull(mCpuFreqTimeMs, false, realtimeUs /* unused */); 10327 resetIfNotNull(mScreenOffCpuFreqTimeMs, false, realtimeUs /* unused */); 10328 10329 10330 resetIfNotNull(mCpuActiveTimeMs, false, realtimeUs /* unused */); 10331 resetIfNotNull(mCpuClusterTimesMs, false, realtimeUs /* unused */); 10332 10333 resetIfNotNull(mProcStateTimeMs, false, realtimeUs /* unused */); 10334 10335 resetIfNotNull(mProcStateScreenOffTimeMs, false, realtimeUs /* unused */); 10336 10337 resetIfNotNull(mMobileRadioApWakeupCount, false, realtimeUs); 10338 10339 resetIfNotNull(mWifiRadioApWakeupCount, false, realtimeUs); 10340 10341 10342 final ArrayMap<String, Wakelock> wakeStats = mWakelockStats.getMap(); 10343 for (int iw=wakeStats.size()-1; iw>=0; iw--) { 10344 Wakelock wl = wakeStats.valueAt(iw); 10345 if (wl.reset(realtimeUs)) { 10346 wakeStats.removeAt(iw); 10347 } else { 10348 active = true; 10349 } 10350 } 10351 final long realtimeMs = realtimeUs / 1000; 10352 mWakelockStats.cleanup(realtimeMs); 10353 final ArrayMap<String, DualTimer> syncStats = mSyncStats.getMap(); 10354 for (int is=syncStats.size()-1; is>=0; is--) { 10355 DualTimer timer = syncStats.valueAt(is); 10356 if (timer.reset(false, realtimeUs)) { 10357 syncStats.removeAt(is); 10358 timer.detach(); 10359 } else { 10360 active = true; 10361 } 10362 } 10363 mSyncStats.cleanup(realtimeMs); 10364 final ArrayMap<String, DualTimer> jobStats = mJobStats.getMap(); 10365 for (int ij=jobStats.size()-1; ij>=0; ij--) { 10366 DualTimer timer = jobStats.valueAt(ij); 10367 if (timer.reset(false, realtimeUs)) { 10368 jobStats.removeAt(ij); 10369 timer.detach(); 10370 } else { 10371 active = true; 10372 } 10373 } 10374 mJobStats.cleanup(realtimeMs); 10375 mJobCompletions.clear(); 10376 10377 resetIfNotNull(mJobsDeferredEventCount, false, realtimeUs); 10378 resetIfNotNull(mJobsDeferredCount, false, realtimeUs); 10379 resetIfNotNull(mJobsFreshnessTimeMs, false, realtimeUs /* unused */); 10380 resetIfNotNull(mJobsFreshnessBuckets, false, realtimeUs); 10381 10382 for (int ise = mSensorStats.size() - 1; ise >= 0; ise--) { 10383 Sensor s = mSensorStats.valueAt(ise); 10384 if (s.reset(realtimeUs)) { 10385 mSensorStats.removeAt(ise); 10386 } else { 10387 active = true; 10388 } 10389 } 10390 10391 for (int ip = mProcessStats.size() - 1; ip >= 0; ip--) { 10392 Proc proc = mProcessStats.valueAt(ip); 10393 proc.detach(); 10394 } 10395 mProcessStats.clear(); 10396 10397 for (int i = mPids.size() - 1; i >= 0; i--) { 10398 Pid pid = mPids.valueAt(i); 10399 if (pid.mWakeNesting > 0) { 10400 active = true; 10401 } else { 10402 mPids.removeAt(i); 10403 } 10404 } 10405 10406 10407 for(int i = mPackageStats.size() - 1; i >= 0; i--) { 10408 Pkg p = mPackageStats.valueAt(i); 10409 p.detach(); 10410 } 10411 mPackageStats.clear(); 10412 10413 mBinderCallCount = 0; 10414 mBinderCallStats.clear(); 10415 10416 mProportionalSystemServiceUsage = 0; 10417 10418 mLastStepUserTimeMs = mLastStepSystemTimeMs = 0; 10419 mCurStepUserTimeMs = mCurStepSystemTimeMs = 0; 10420 10421 10422 return !active; 10423 } 10424 10425 /** 10426 * This method MUST be called whenever the Uid object is destructed, otherwise it is a 10427 * memory leak in {@link TimeBase#mObservers} list. 10428 * Typically the Uid object is destructed when it is removed from 10429 * {@link BatteryStatsImpl#mUidStats} 10430 */ detachFromTimeBase()10431 void detachFromTimeBase() { 10432 detachIfNotNull(mWifiRunningTimer); 10433 detachIfNotNull(mFullWifiLockTimer); 10434 detachIfNotNull(mWifiScanTimer); 10435 detachIfNotNull(mWifiBatchedScanTimer); 10436 detachIfNotNull(mWifiMulticastTimer); 10437 detachIfNotNull(mAudioTurnedOnTimer); 10438 detachIfNotNull(mVideoTurnedOnTimer); 10439 detachIfNotNull(mFlashlightTurnedOnTimer); 10440 10441 detachIfNotNull(mCameraTurnedOnTimer); 10442 detachIfNotNull(mForegroundActivityTimer); 10443 detachIfNotNull(mForegroundServiceTimer); 10444 10445 detachIfNotNull(mAggregatedPartialWakelockTimer); 10446 10447 detachIfNotNull(mBluetoothScanTimer); 10448 detachIfNotNull(mBluetoothUnoptimizedScanTimer); 10449 detachIfNotNull(mBluetoothScanResultCounter); 10450 detachIfNotNull(mBluetoothScanResultBgCounter); 10451 10452 detachIfNotNull(mProcessStateTimer); 10453 10454 detachIfNotNull(mVibratorOnTimer); 10455 10456 detachIfNotNull(mUserActivityCounters); 10457 10458 detachIfNotNull(mNetworkByteActivityCounters); 10459 detachIfNotNull(mNetworkPacketActivityCounters); 10460 10461 detachIfNotNull(mMobileRadioActiveTime); 10462 detachIfNotNull(mMobileRadioActiveCount); 10463 detachIfNotNull(mMobileRadioApWakeupCount); 10464 detachIfNotNull(mWifiRadioApWakeupCount); 10465 10466 detachIfNotNull(mWifiControllerActivity); 10467 detachIfNotNull(mBluetoothControllerActivity); 10468 detachIfNotNull(mModemControllerActivity); 10469 10470 mPids.clear(); 10471 10472 detachIfNotNull(mUserCpuTime); 10473 detachIfNotNull(mSystemCpuTime); 10474 10475 detachIfNotNull(mCpuClusterSpeedTimesUs); 10476 10477 detachIfNotNull(mCpuActiveTimeMs); 10478 detachIfNotNull(mCpuFreqTimeMs); 10479 10480 detachIfNotNull(mScreenOffCpuFreqTimeMs); 10481 10482 detachIfNotNull(mCpuClusterTimesMs); 10483 10484 detachIfNotNull(mProcStateTimeMs); 10485 10486 detachIfNotNull(mProcStateScreenOffTimeMs); 10487 10488 final ArrayMap<String, Wakelock> wakeStats = mWakelockStats.getMap(); 10489 for (int iw = wakeStats.size() - 1; iw >= 0; iw--) { 10490 Wakelock wl = wakeStats.valueAt(iw); 10491 wl.detachFromTimeBase(); 10492 } 10493 final ArrayMap<String, DualTimer> syncStats = mSyncStats.getMap(); 10494 for (int is = syncStats.size() - 1; is >= 0; is--) { 10495 DualTimer timer = syncStats.valueAt(is); 10496 detachIfNotNull(timer); 10497 } 10498 final ArrayMap<String, DualTimer> jobStats = mJobStats.getMap(); 10499 for (int ij = jobStats.size() - 1; ij >= 0; ij--) { 10500 DualTimer timer = jobStats.valueAt(ij); 10501 detachIfNotNull(timer); 10502 } 10503 10504 detachIfNotNull(mJobsDeferredEventCount); 10505 detachIfNotNull(mJobsDeferredCount); 10506 detachIfNotNull(mJobsFreshnessTimeMs); 10507 detachIfNotNull(mJobsFreshnessBuckets); 10508 10509 10510 for (int ise = mSensorStats.size() - 1; ise >= 0; ise--) { 10511 Sensor s = mSensorStats.valueAt(ise); 10512 s.detachFromTimeBase(); 10513 } 10514 10515 for (int ip= mProcessStats.size() - 1; ip >= 0; ip--) { 10516 Proc proc = mProcessStats.valueAt(ip); 10517 proc.detach(); 10518 } 10519 mProcessStats.clear(); 10520 10521 for(int i = mPackageStats.size() - 1; i >= 0; i--) { 10522 Pkg p = mPackageStats.valueAt(i); 10523 p.detach(); 10524 } 10525 mPackageStats.clear(); 10526 } 10527 writeJobCompletionsToParcelLocked(Parcel out)10528 void writeJobCompletionsToParcelLocked(Parcel out) { 10529 int NJC = mJobCompletions.size(); 10530 out.writeInt(NJC); 10531 for (int ijc=0; ijc<NJC; ijc++) { 10532 out.writeString(mJobCompletions.keyAt(ijc)); 10533 SparseIntArray types = mJobCompletions.valueAt(ijc); 10534 int NT = types.size(); 10535 out.writeInt(NT); 10536 for (int it=0; it<NT; it++) { 10537 out.writeInt(types.keyAt(it)); 10538 out.writeInt(types.valueAt(it)); 10539 } 10540 } 10541 } 10542 writeToParcelLocked(Parcel out, long uptimeUs, long elapsedRealtimeUs)10543 void writeToParcelLocked(Parcel out, long uptimeUs, long elapsedRealtimeUs) { 10544 mOnBatteryBackgroundTimeBase.writeToParcel(out, uptimeUs, elapsedRealtimeUs); 10545 mOnBatteryScreenOffBackgroundTimeBase.writeToParcel(out, uptimeUs, elapsedRealtimeUs); 10546 10547 final ArrayMap<String, Wakelock> wakeStats = mWakelockStats.getMap(); 10548 int NW = wakeStats.size(); 10549 out.writeInt(NW); 10550 for (int iw=0; iw<NW; iw++) { 10551 out.writeString(wakeStats.keyAt(iw)); 10552 Uid.Wakelock wakelock = wakeStats.valueAt(iw); 10553 wakelock.writeToParcelLocked(out, elapsedRealtimeUs); 10554 } 10555 10556 final ArrayMap<String, DualTimer> syncStats = mSyncStats.getMap(); 10557 int NS = syncStats.size(); 10558 out.writeInt(NS); 10559 for (int is=0; is<NS; is++) { 10560 out.writeString(syncStats.keyAt(is)); 10561 DualTimer timer = syncStats.valueAt(is); 10562 Timer.writeTimerToParcel(out, timer, elapsedRealtimeUs); 10563 } 10564 10565 final ArrayMap<String, DualTimer> jobStats = mJobStats.getMap(); 10566 int NJ = jobStats.size(); 10567 out.writeInt(NJ); 10568 for (int ij=0; ij<NJ; ij++) { 10569 out.writeString(jobStats.keyAt(ij)); 10570 DualTimer timer = jobStats.valueAt(ij); 10571 Timer.writeTimerToParcel(out, timer, elapsedRealtimeUs); 10572 } 10573 10574 writeJobCompletionsToParcelLocked(out); 10575 10576 mJobsDeferredEventCount.writeToParcel(out); 10577 mJobsDeferredCount.writeToParcel(out); 10578 mJobsFreshnessTimeMs.writeToParcel(out); 10579 for (int i = 0; i < JOB_FRESHNESS_BUCKETS.length; i++) { 10580 Counter.writeCounterToParcel(out, mJobsFreshnessBuckets[i]); 10581 } 10582 10583 int NSE = mSensorStats.size(); 10584 out.writeInt(NSE); 10585 for (int ise=0; ise<NSE; ise++) { 10586 out.writeInt(mSensorStats.keyAt(ise)); 10587 Uid.Sensor sensor = mSensorStats.valueAt(ise); 10588 sensor.writeToParcelLocked(out, elapsedRealtimeUs); 10589 } 10590 10591 int NP = mProcessStats.size(); 10592 out.writeInt(NP); 10593 for (int ip=0; ip<NP; ip++) { 10594 out.writeString(mProcessStats.keyAt(ip)); 10595 Uid.Proc proc = mProcessStats.valueAt(ip); 10596 proc.writeToParcelLocked(out); 10597 } 10598 10599 out.writeInt(mPackageStats.size()); 10600 for (Map.Entry<String, Uid.Pkg> pkgEntry : mPackageStats.entrySet()) { 10601 out.writeString(pkgEntry.getKey()); 10602 Uid.Pkg pkg = pkgEntry.getValue(); 10603 pkg.writeToParcelLocked(out); 10604 } 10605 10606 if (mWifiRunningTimer != null) { 10607 out.writeInt(1); 10608 mWifiRunningTimer.writeToParcel(out, elapsedRealtimeUs); 10609 } else { 10610 out.writeInt(0); 10611 } 10612 if (mFullWifiLockTimer != null) { 10613 out.writeInt(1); 10614 mFullWifiLockTimer.writeToParcel(out, elapsedRealtimeUs); 10615 } else { 10616 out.writeInt(0); 10617 } 10618 if (mWifiScanTimer != null) { 10619 out.writeInt(1); 10620 mWifiScanTimer.writeToParcel(out, elapsedRealtimeUs); 10621 } else { 10622 out.writeInt(0); 10623 } 10624 for (int i = 0; i < NUM_WIFI_BATCHED_SCAN_BINS; i++) { 10625 if (mWifiBatchedScanTimer[i] != null) { 10626 out.writeInt(1); 10627 mWifiBatchedScanTimer[i].writeToParcel(out, elapsedRealtimeUs); 10628 } else { 10629 out.writeInt(0); 10630 } 10631 } 10632 if (mWifiMulticastTimer != null) { 10633 out.writeInt(1); 10634 mWifiMulticastTimer.writeToParcel(out, elapsedRealtimeUs); 10635 } else { 10636 out.writeInt(0); 10637 } 10638 10639 if (mAudioTurnedOnTimer != null) { 10640 out.writeInt(1); 10641 mAudioTurnedOnTimer.writeToParcel(out, elapsedRealtimeUs); 10642 } else { 10643 out.writeInt(0); 10644 } 10645 if (mVideoTurnedOnTimer != null) { 10646 out.writeInt(1); 10647 mVideoTurnedOnTimer.writeToParcel(out, elapsedRealtimeUs); 10648 } else { 10649 out.writeInt(0); 10650 } 10651 if (mFlashlightTurnedOnTimer != null) { 10652 out.writeInt(1); 10653 mFlashlightTurnedOnTimer.writeToParcel(out, elapsedRealtimeUs); 10654 } else { 10655 out.writeInt(0); 10656 } 10657 if (mCameraTurnedOnTimer != null) { 10658 out.writeInt(1); 10659 mCameraTurnedOnTimer.writeToParcel(out, elapsedRealtimeUs); 10660 } else { 10661 out.writeInt(0); 10662 } 10663 if (mForegroundActivityTimer != null) { 10664 out.writeInt(1); 10665 mForegroundActivityTimer.writeToParcel(out, elapsedRealtimeUs); 10666 } else { 10667 out.writeInt(0); 10668 } 10669 if (mForegroundServiceTimer != null) { 10670 out.writeInt(1); 10671 mForegroundServiceTimer.writeToParcel(out, elapsedRealtimeUs); 10672 } else { 10673 out.writeInt(0); 10674 } 10675 if (mAggregatedPartialWakelockTimer != null) { 10676 out.writeInt(1); 10677 mAggregatedPartialWakelockTimer.writeToParcel(out, elapsedRealtimeUs); 10678 } else { 10679 out.writeInt(0); 10680 } 10681 if (mBluetoothScanTimer != null) { 10682 out.writeInt(1); 10683 mBluetoothScanTimer.writeToParcel(out, elapsedRealtimeUs); 10684 } else { 10685 out.writeInt(0); 10686 } 10687 if (mBluetoothUnoptimizedScanTimer != null) { 10688 out.writeInt(1); 10689 mBluetoothUnoptimizedScanTimer.writeToParcel(out, elapsedRealtimeUs); 10690 } else { 10691 out.writeInt(0); 10692 } 10693 if (mBluetoothScanResultCounter != null) { 10694 out.writeInt(1); 10695 mBluetoothScanResultCounter.writeToParcel(out); 10696 } else { 10697 out.writeInt(0); 10698 } 10699 if (mBluetoothScanResultBgCounter != null) { 10700 out.writeInt(1); 10701 mBluetoothScanResultBgCounter.writeToParcel(out); 10702 } else { 10703 out.writeInt(0); 10704 } 10705 for (int i = 0; i < NUM_PROCESS_STATE; i++) { 10706 if (mProcessStateTimer[i] != null) { 10707 out.writeInt(1); 10708 mProcessStateTimer[i].writeToParcel(out, elapsedRealtimeUs); 10709 } else { 10710 out.writeInt(0); 10711 } 10712 } 10713 if (mVibratorOnTimer != null) { 10714 out.writeInt(1); 10715 mVibratorOnTimer.writeToParcel(out, elapsedRealtimeUs); 10716 } else { 10717 out.writeInt(0); 10718 } 10719 if (mUserActivityCounters != null) { 10720 out.writeInt(1); 10721 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) { 10722 mUserActivityCounters[i].writeToParcel(out); 10723 } 10724 } else { 10725 out.writeInt(0); 10726 } 10727 if (mNetworkByteActivityCounters != null) { 10728 out.writeInt(1); 10729 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 10730 mNetworkByteActivityCounters[i].writeToParcel(out); 10731 mNetworkPacketActivityCounters[i].writeToParcel(out); 10732 } 10733 if (mMobileRadioActiveTime != null) { 10734 out.writeBoolean(true); 10735 mMobileRadioActiveTime.writeToParcel(out); 10736 } else { 10737 out.writeBoolean(false); 10738 } 10739 mMobileRadioActiveCount.writeToParcel(out); 10740 } else { 10741 out.writeInt(0); 10742 } 10743 10744 if (mWifiControllerActivity != null) { 10745 out.writeInt(1); 10746 mWifiControllerActivity.writeToParcel(out, 0); 10747 } else { 10748 out.writeInt(0); 10749 } 10750 10751 if (mBluetoothControllerActivity != null) { 10752 out.writeInt(1); 10753 mBluetoothControllerActivity.writeToParcel(out, 0); 10754 } else { 10755 out.writeInt(0); 10756 } 10757 10758 if (mModemControllerActivity != null) { 10759 out.writeInt(1); 10760 mModemControllerActivity.writeToParcel(out, 0); 10761 } else { 10762 out.writeInt(0); 10763 } 10764 10765 if (mUidMeasuredEnergyStats != null) { 10766 out.writeInt(1); 10767 mUidMeasuredEnergyStats.writeToParcel(out); 10768 } else { 10769 out.writeInt(0); 10770 } 10771 10772 mUserCpuTime.writeToParcel(out); 10773 mSystemCpuTime.writeToParcel(out); 10774 10775 mBsi.writeCpuSpeedCountersToParcel(out, mCpuClusterSpeedTimesUs); 10776 10777 LongSamplingCounterArray.writeToParcel(out, mCpuFreqTimeMs); 10778 LongSamplingCounterArray.writeToParcel(out, mScreenOffCpuFreqTimeMs); 10779 10780 if (mCpuActiveTimeMs != null) { 10781 out.writeInt(mCpuActiveTimeMs.getStateCount()); 10782 mCpuActiveTimeMs.writeToParcel(out); 10783 } else { 10784 out.writeInt(0); 10785 } 10786 10787 mCpuClusterTimesMs.writeToParcel(out); 10788 10789 if (mProcStateTimeMs != null) { 10790 out.writeInt(mProcStateTimeMs.getStateCount()); 10791 mProcStateTimeMs.writeToParcel(out); 10792 } else { 10793 out.writeInt(0); 10794 } 10795 if (mProcStateScreenOffTimeMs != null) { 10796 out.writeInt(mProcStateScreenOffTimeMs.getStateCount()); 10797 mProcStateScreenOffTimeMs.writeToParcel(out); 10798 } else { 10799 out.writeInt(0); 10800 } 10801 10802 if (mMobileRadioApWakeupCount != null) { 10803 out.writeInt(1); 10804 mMobileRadioApWakeupCount.writeToParcel(out); 10805 } else { 10806 out.writeInt(0); 10807 } 10808 10809 if (mWifiRadioApWakeupCount != null) { 10810 out.writeInt(1); 10811 mWifiRadioApWakeupCount.writeToParcel(out); 10812 } else { 10813 out.writeInt(0); 10814 } 10815 out.writeDouble(mProportionalSystemServiceUsage); 10816 } 10817 readJobCompletionsFromParcelLocked(Parcel in)10818 void readJobCompletionsFromParcelLocked(Parcel in) { 10819 int numJobCompletions = in.readInt(); 10820 mJobCompletions.clear(); 10821 for (int j = 0; j < numJobCompletions; j++) { 10822 String jobName = in.readString(); 10823 int numTypes = in.readInt(); 10824 if (numTypes > 0) { 10825 SparseIntArray types = new SparseIntArray(); 10826 for (int k = 0; k < numTypes; k++) { 10827 int type = in.readInt(); 10828 int count = in.readInt(); 10829 types.put(type, count); 10830 } 10831 mJobCompletions.put(jobName, types); 10832 } 10833 } 10834 } 10835 10836 @GuardedBy("mBsi") readFromParcelLocked(TimeBase timeBase, TimeBase screenOffTimeBase, Parcel in)10837 void readFromParcelLocked(TimeBase timeBase, TimeBase screenOffTimeBase, Parcel in) { 10838 final long timestampMs = mBsi.mClock.elapsedRealtime(); 10839 mOnBatteryBackgroundTimeBase.readFromParcel(in); 10840 mOnBatteryScreenOffBackgroundTimeBase.readFromParcel(in); 10841 10842 int numWakelocks = in.readInt(); 10843 mWakelockStats.clear(); 10844 for (int j = 0; j < numWakelocks; j++) { 10845 String wakelockName = in.readString(); 10846 Uid.Wakelock wakelock = new Wakelock(mBsi, this); 10847 wakelock.readFromParcelLocked( 10848 timeBase, screenOffTimeBase, mOnBatteryScreenOffBackgroundTimeBase, in); 10849 mWakelockStats.add(wakelockName, wakelock); 10850 } 10851 10852 int numSyncs = in.readInt(); 10853 mSyncStats.clear(); 10854 for (int j = 0; j < numSyncs; j++) { 10855 String syncName = in.readString(); 10856 if (in.readInt() != 0) { 10857 mSyncStats.add(syncName, new DualTimer(mBsi.mClock, Uid.this, SYNC, null, 10858 mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase, in)); 10859 } 10860 } 10861 10862 int numJobs = in.readInt(); 10863 mJobStats.clear(); 10864 for (int j = 0; j < numJobs; j++) { 10865 String jobName = in.readString(); 10866 if (in.readInt() != 0) { 10867 mJobStats.add(jobName, new DualTimer(mBsi.mClock, Uid.this, JOB, null, 10868 mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase, in)); 10869 } 10870 } 10871 10872 readJobCompletionsFromParcelLocked(in); 10873 10874 mJobsDeferredEventCount = new Counter(mBsi.mOnBatteryTimeBase, in); 10875 mJobsDeferredCount = new Counter(mBsi.mOnBatteryTimeBase, in); 10876 mJobsFreshnessTimeMs = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in); 10877 for (int i = 0; i < JOB_FRESHNESS_BUCKETS.length; i++) { 10878 mJobsFreshnessBuckets[i] = Counter.readCounterFromParcel(mBsi.mOnBatteryTimeBase, 10879 in); 10880 } 10881 10882 int numSensors = in.readInt(); 10883 mSensorStats.clear(); 10884 for (int k = 0; k < numSensors; k++) { 10885 int sensorNumber = in.readInt(); 10886 Uid.Sensor sensor = new Sensor(mBsi, this, sensorNumber); 10887 sensor.readFromParcelLocked(mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase, 10888 in); 10889 mSensorStats.put(sensorNumber, sensor); 10890 } 10891 10892 int numProcs = in.readInt(); 10893 mProcessStats.clear(); 10894 for (int k = 0; k < numProcs; k++) { 10895 String processName = in.readString(); 10896 Uid.Proc proc = new Proc(mBsi, processName); 10897 proc.readFromParcelLocked(in); 10898 mProcessStats.put(processName, proc); 10899 } 10900 10901 int numPkgs = in.readInt(); 10902 mPackageStats.clear(); 10903 for (int l = 0; l < numPkgs; l++) { 10904 String packageName = in.readString(); 10905 Uid.Pkg pkg = new Pkg(mBsi); 10906 pkg.readFromParcelLocked(in); 10907 mPackageStats.put(packageName, pkg); 10908 } 10909 10910 mWifiRunning = false; 10911 if (in.readInt() != 0) { 10912 mWifiRunningTimer = new StopwatchTimer(mBsi.mClock, Uid.this, WIFI_RUNNING, 10913 mBsi.mWifiRunningTimers, mBsi.mOnBatteryTimeBase, in); 10914 } else { 10915 mWifiRunningTimer = null; 10916 } 10917 mFullWifiLockOut = false; 10918 if (in.readInt() != 0) { 10919 mFullWifiLockTimer = new StopwatchTimer(mBsi.mClock, Uid.this, FULL_WIFI_LOCK, 10920 mBsi.mFullWifiLockTimers, mBsi.mOnBatteryTimeBase, in); 10921 } else { 10922 mFullWifiLockTimer = null; 10923 } 10924 mWifiScanStarted = false; 10925 if (in.readInt() != 0) { 10926 mWifiScanTimer = new DualTimer(mBsi.mClock, Uid.this, WIFI_SCAN, 10927 mBsi.mWifiScanTimers, mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase, 10928 in); 10929 } else { 10930 mWifiScanTimer = null; 10931 } 10932 mWifiBatchedScanBinStarted = NO_BATCHED_SCAN_STARTED; 10933 for (int i = 0; i < NUM_WIFI_BATCHED_SCAN_BINS; i++) { 10934 if (in.readInt() != 0) { 10935 makeWifiBatchedScanBin(i, in); 10936 } else { 10937 mWifiBatchedScanTimer[i] = null; 10938 } 10939 } 10940 mWifiMulticastWakelockCount = 0; 10941 if (in.readInt() != 0) { 10942 mWifiMulticastTimer = new StopwatchTimer(mBsi.mClock, Uid.this, 10943 WIFI_MULTICAST_ENABLED, 10944 mBsi.mWifiMulticastTimers, mBsi.mOnBatteryTimeBase, in); 10945 } else { 10946 mWifiMulticastTimer = null; 10947 } 10948 if (in.readInt() != 0) { 10949 mAudioTurnedOnTimer = new StopwatchTimer(mBsi.mClock, Uid.this, AUDIO_TURNED_ON, 10950 mBsi.mAudioTurnedOnTimers, mBsi.mOnBatteryTimeBase, in); 10951 } else { 10952 mAudioTurnedOnTimer = null; 10953 } 10954 if (in.readInt() != 0) { 10955 mVideoTurnedOnTimer = new StopwatchTimer(mBsi.mClock, Uid.this, VIDEO_TURNED_ON, 10956 mBsi.mVideoTurnedOnTimers, mBsi.mOnBatteryTimeBase, in); 10957 } else { 10958 mVideoTurnedOnTimer = null; 10959 } 10960 if (in.readInt() != 0) { 10961 mFlashlightTurnedOnTimer = new StopwatchTimer(mBsi.mClock, Uid.this, 10962 FLASHLIGHT_TURNED_ON, mBsi.mFlashlightTurnedOnTimers, mBsi.mOnBatteryTimeBase, in); 10963 } else { 10964 mFlashlightTurnedOnTimer = null; 10965 } 10966 if (in.readInt() != 0) { 10967 mCameraTurnedOnTimer = new StopwatchTimer(mBsi.mClock, Uid.this, CAMERA_TURNED_ON, 10968 mBsi.mCameraTurnedOnTimers, mBsi.mOnBatteryTimeBase, in); 10969 } else { 10970 mCameraTurnedOnTimer = null; 10971 } 10972 if (in.readInt() != 0) { 10973 mForegroundActivityTimer = new StopwatchTimer(mBsi.mClock, Uid.this, 10974 FOREGROUND_ACTIVITY, null, mBsi.mOnBatteryTimeBase, in); 10975 } else { 10976 mForegroundActivityTimer = null; 10977 } 10978 if (in.readInt() != 0) { 10979 mForegroundServiceTimer = new StopwatchTimer(mBsi.mClock, Uid.this, 10980 FOREGROUND_SERVICE, null, mBsi.mOnBatteryTimeBase, in); 10981 } else { 10982 mForegroundServiceTimer = null; 10983 } 10984 if (in.readInt() != 0) { 10985 mAggregatedPartialWakelockTimer = new DualTimer(mBsi.mClock, this, 10986 AGGREGATED_WAKE_TYPE_PARTIAL, null, 10987 mBsi.mOnBatteryScreenOffTimeBase, mOnBatteryScreenOffBackgroundTimeBase, 10988 in); 10989 } else { 10990 mAggregatedPartialWakelockTimer = null; 10991 } 10992 if (in.readInt() != 0) { 10993 mBluetoothScanTimer = new DualTimer(mBsi.mClock, Uid.this, BLUETOOTH_SCAN_ON, 10994 mBsi.mBluetoothScanOnTimers, mBsi.mOnBatteryTimeBase, 10995 mOnBatteryBackgroundTimeBase, in); 10996 } else { 10997 mBluetoothScanTimer = null; 10998 } 10999 if (in.readInt() != 0) { 11000 mBluetoothUnoptimizedScanTimer = new DualTimer(mBsi.mClock, Uid.this, 11001 BLUETOOTH_UNOPTIMIZED_SCAN_ON, null, 11002 mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase, in); 11003 } else { 11004 mBluetoothUnoptimizedScanTimer = null; 11005 } 11006 if (in.readInt() != 0) { 11007 mBluetoothScanResultCounter = new Counter(mBsi.mOnBatteryTimeBase, in); 11008 } else { 11009 mBluetoothScanResultCounter = null; 11010 } 11011 if (in.readInt() != 0) { 11012 mBluetoothScanResultBgCounter = new Counter(mOnBatteryBackgroundTimeBase, in); 11013 } else { 11014 mBluetoothScanResultBgCounter = null; 11015 } 11016 mProcessState = Uid.PROCESS_STATE_NONEXISTENT; 11017 for (int i = 0; i < NUM_PROCESS_STATE; i++) { 11018 if (in.readInt() != 0) { 11019 makeProcessState(i, in); 11020 } else { 11021 mProcessStateTimer[i] = null; 11022 } 11023 } 11024 if (in.readInt() != 0) { 11025 mVibratorOnTimer = new BatchTimer(mBsi.mClock, Uid.this, VIBRATOR_ON, 11026 mBsi.mOnBatteryTimeBase, in); 11027 } else { 11028 mVibratorOnTimer = null; 11029 } 11030 if (in.readInt() != 0) { 11031 mUserActivityCounters = new Counter[NUM_USER_ACTIVITY_TYPES]; 11032 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) { 11033 mUserActivityCounters[i] = new Counter(mBsi.mOnBatteryTimeBase, in); 11034 } 11035 } else { 11036 mUserActivityCounters = null; 11037 } 11038 if (in.readInt() != 0) { 11039 mNetworkByteActivityCounters = new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES]; 11040 mNetworkPacketActivityCounters 11041 = new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES]; 11042 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 11043 mNetworkByteActivityCounters[i] 11044 = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in); 11045 mNetworkPacketActivityCounters[i] 11046 = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in); 11047 } 11048 if (in.readBoolean()) { 11049 mMobileRadioActiveTime = TimeMultiStateCounter.readFromParcel(in, 11050 mBsi.mOnBatteryTimeBase, BatteryConsumer.PROCESS_STATE_COUNT, 11051 timestampMs); 11052 } 11053 11054 mMobileRadioActiveCount = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in); 11055 } else { 11056 mNetworkByteActivityCounters = null; 11057 mNetworkPacketActivityCounters = null; 11058 } 11059 11060 if (in.readInt() != 0) { 11061 mWifiControllerActivity = new ControllerActivityCounterImpl(mBsi.mClock, 11062 mBsi.mOnBatteryTimeBase, NUM_WIFI_TX_LEVELS, in); 11063 } else { 11064 mWifiControllerActivity = null; 11065 } 11066 11067 if (in.readInt() != 0) { 11068 mBluetoothControllerActivity = new ControllerActivityCounterImpl(mBsi.mClock, 11069 mBsi.mOnBatteryTimeBase, NUM_BT_TX_LEVELS, in); 11070 } else { 11071 mBluetoothControllerActivity = null; 11072 } 11073 11074 if (in.readInt() != 0) { 11075 mModemControllerActivity = new ControllerActivityCounterImpl(mBsi.mClock, 11076 mBsi.mOnBatteryTimeBase, ModemActivityInfo.getNumTxPowerLevels(), in); 11077 } else { 11078 mModemControllerActivity = null; 11079 } 11080 11081 if (in.readInt() != 0) { 11082 mUidMeasuredEnergyStats = new MeasuredEnergyStats(mBsi.mMeasuredEnergyStatsConfig, 11083 in); 11084 } 11085 11086 mUserCpuTime = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in); 11087 mSystemCpuTime = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in); 11088 11089 mCpuClusterSpeedTimesUs = mBsi.readCpuSpeedCountersFromParcel(in); 11090 11091 mCpuFreqTimeMs = LongSamplingCounterArray.readFromParcel(in, mBsi.mOnBatteryTimeBase); 11092 mScreenOffCpuFreqTimeMs = LongSamplingCounterArray.readFromParcel( 11093 in, mBsi.mOnBatteryScreenOffTimeBase); 11094 11095 int stateCount = in.readInt(); 11096 if (stateCount != 0) { 11097 mCpuActiveTimeMs = TimeMultiStateCounter.readFromParcel(in, 11098 mBsi.mOnBatteryTimeBase, BatteryConsumer.PROCESS_STATE_COUNT, 11099 timestampMs); 11100 } 11101 mCpuClusterTimesMs = new LongSamplingCounterArray(mBsi.mOnBatteryTimeBase, in); 11102 11103 stateCount = in.readInt(); 11104 if (stateCount != 0) { 11105 mProcStateTimeMs = TimeInFreqMultiStateCounter.readFromParcel(in, 11106 mBsi.mOnBatteryTimeBase, PROC_STATE_TIME_COUNTER_STATE_COUNT, 11107 mBsi.getCpuFreqCount(), mBsi.mClock.elapsedRealtime()); 11108 } else { 11109 mProcStateTimeMs = null; 11110 } 11111 11112 stateCount = in.readInt(); 11113 if (stateCount != 0) { 11114 mProcStateScreenOffTimeMs = TimeInFreqMultiStateCounter.readFromParcel(in, 11115 mBsi.mOnBatteryScreenOffTimeBase, PROC_STATE_TIME_COUNTER_STATE_COUNT, 11116 mBsi.getCpuFreqCount(), mBsi.mClock.elapsedRealtime()); 11117 } else { 11118 mProcStateScreenOffTimeMs = null; 11119 } 11120 11121 if (in.readInt() != 0) { 11122 mMobileRadioApWakeupCount = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in); 11123 } else { 11124 mMobileRadioApWakeupCount = null; 11125 } 11126 11127 if (in.readInt() != 0) { 11128 mWifiRadioApWakeupCount = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in); 11129 } else { 11130 mWifiRadioApWakeupCount = null; 11131 } 11132 11133 mProportionalSystemServiceUsage = in.readDouble(); 11134 } 11135 noteJobsDeferredLocked(int numDeferred, long sinceLast)11136 public void noteJobsDeferredLocked(int numDeferred, long sinceLast) { 11137 mJobsDeferredEventCount.addAtomic(1); 11138 mJobsDeferredCount.addAtomic(numDeferred); 11139 if (sinceLast != 0) { 11140 // Add the total time, which can be divided by the event count to get an average 11141 mJobsFreshnessTimeMs.addCountLocked(sinceLast); 11142 // Also keep track of how many times there were in these different buckets. 11143 for (int i = 0; i < JOB_FRESHNESS_BUCKETS.length; i++) { 11144 if (sinceLast < JOB_FRESHNESS_BUCKETS[i]) { 11145 if (mJobsFreshnessBuckets[i] == null) { 11146 mJobsFreshnessBuckets[i] = new Counter( 11147 mBsi.mOnBatteryTimeBase); 11148 } 11149 mJobsFreshnessBuckets[i].addAtomic(1); 11150 break; 11151 } 11152 } 11153 } 11154 } 11155 11156 // Reusable object used as a key to lookup values in mBinderCallStats 11157 private static BinderCallStats sTempBinderCallStats = new BinderCallStats(); 11158 11159 /** 11160 * Notes incoming binder call stats associated with this work source UID. 11161 */ noteBinderCallStatsLocked(long incrementalCallCount, Collection<BinderCallsStats.CallStat> callStats)11162 public void noteBinderCallStatsLocked(long incrementalCallCount, 11163 Collection<BinderCallsStats.CallStat> callStats) { 11164 if (DEBUG) { 11165 Slog.d(TAG, "noteBinderCalls() workSourceUid = [" + mUid + "], " 11166 + " incrementalCallCount: " + incrementalCallCount + " callStats = [" 11167 + new ArrayList<>(callStats) + "]"); 11168 } 11169 mBinderCallCount += incrementalCallCount; 11170 for (BinderCallsStats.CallStat stat : callStats) { 11171 BinderCallStats bcs; 11172 sTempBinderCallStats.binderClass = stat.binderClass; 11173 sTempBinderCallStats.transactionCode = stat.transactionCode; 11174 int index = mBinderCallStats.indexOf(sTempBinderCallStats); 11175 if (index >= 0) { 11176 bcs = mBinderCallStats.valueAt(index); 11177 } else { 11178 bcs = new BinderCallStats(); 11179 bcs.binderClass = stat.binderClass; 11180 bcs.transactionCode = stat.transactionCode; 11181 mBinderCallStats.add(bcs); 11182 } 11183 11184 bcs.callCount += stat.incrementalCallCount; 11185 bcs.recordedCallCount = stat.recordedCallCount; 11186 bcs.recordedCpuTimeMicros = stat.cpuTimeMicros; 11187 } 11188 } 11189 11190 /** 11191 * The statistics associated with a particular wake lock. 11192 */ 11193 public static class Wakelock extends BatteryStats.Uid.Wakelock { 11194 /** 11195 * BatteryStatsImpl that we are associated with. 11196 */ 11197 protected BatteryStatsImpl mBsi; 11198 11199 /** 11200 * BatteryStatsImpl that we are associated with. 11201 */ 11202 protected Uid mUid; 11203 11204 /** 11205 * How long (in ms) this uid has been keeping the device partially awake. 11206 * Tracks both the total time and the time while the app was in the background. 11207 */ 11208 DualTimer mTimerPartial; 11209 11210 /** 11211 * How long (in ms) this uid has been keeping the device fully awake. 11212 */ 11213 StopwatchTimer mTimerFull; 11214 11215 /** 11216 * How long (in ms) this uid has had a window keeping the device awake. 11217 */ 11218 StopwatchTimer mTimerWindow; 11219 11220 /** 11221 * How long (in ms) this uid has had a draw wake lock. 11222 */ 11223 StopwatchTimer mTimerDraw; 11224 Wakelock(BatteryStatsImpl bsi, Uid uid)11225 public Wakelock(BatteryStatsImpl bsi, Uid uid) { 11226 mBsi = bsi; 11227 mUid = uid; 11228 } 11229 11230 /** 11231 * Reads a possibly null Timer from a Parcel. The timer is associated with the 11232 * proper timer pool from the given BatteryStatsImpl object. 11233 * 11234 * @param in the Parcel to be read from. 11235 * return a new Timer, or null. 11236 */ readStopwatchTimerFromParcel(int type, ArrayList<StopwatchTimer> pool, TimeBase timeBase, Parcel in)11237 private StopwatchTimer readStopwatchTimerFromParcel(int type, 11238 ArrayList<StopwatchTimer> pool, TimeBase timeBase, Parcel in) { 11239 if (in.readInt() == 0) { 11240 return null; 11241 } 11242 11243 return new StopwatchTimer(mBsi.mClock, mUid, type, pool, timeBase, in); 11244 } 11245 11246 /** 11247 * Reads a possibly null Timer from a Parcel. The timer is associated with the 11248 * proper timer pool from the given BatteryStatsImpl object. 11249 * 11250 * @param in the Parcel to be read from. 11251 * return a new Timer, or null. 11252 */ readDualTimerFromParcel(int type, ArrayList<StopwatchTimer> pool, TimeBase timeBase, TimeBase bgTimeBase, Parcel in)11253 private DualTimer readDualTimerFromParcel(int type, ArrayList<StopwatchTimer> pool, 11254 TimeBase timeBase, TimeBase bgTimeBase, Parcel in) { 11255 if (in.readInt() == 0) { 11256 return null; 11257 } 11258 11259 return new DualTimer(mBsi.mClock, mUid, type, pool, timeBase, bgTimeBase, in); 11260 } 11261 reset(long elapsedRealtimeUs)11262 boolean reset(long elapsedRealtimeUs) { 11263 boolean wlactive = false; 11264 11265 wlactive |= !resetIfNotNull(mTimerFull, false, elapsedRealtimeUs); 11266 wlactive |= !resetIfNotNull(mTimerPartial, false, elapsedRealtimeUs); 11267 wlactive |= !resetIfNotNull(mTimerWindow, false, elapsedRealtimeUs); 11268 wlactive |= !resetIfNotNull(mTimerDraw, false, elapsedRealtimeUs); 11269 11270 if (!wlactive) { 11271 detachIfNotNull(mTimerFull); 11272 mTimerFull = null; 11273 11274 detachIfNotNull(mTimerPartial); 11275 mTimerPartial = null; 11276 11277 detachIfNotNull(mTimerWindow); 11278 mTimerWindow = null; 11279 11280 detachIfNotNull(mTimerDraw); 11281 mTimerDraw = null; 11282 } 11283 return !wlactive; 11284 } 11285 readFromParcelLocked(TimeBase timeBase, TimeBase screenOffTimeBase, TimeBase screenOffBgTimeBase, Parcel in)11286 void readFromParcelLocked(TimeBase timeBase, TimeBase screenOffTimeBase, 11287 TimeBase screenOffBgTimeBase, Parcel in) { 11288 mTimerPartial = readDualTimerFromParcel(WAKE_TYPE_PARTIAL, 11289 mBsi.mPartialTimers, screenOffTimeBase, screenOffBgTimeBase, in); 11290 mTimerFull = readStopwatchTimerFromParcel(WAKE_TYPE_FULL, 11291 mBsi.mFullTimers, timeBase, in); 11292 mTimerWindow = readStopwatchTimerFromParcel(WAKE_TYPE_WINDOW, 11293 mBsi.mWindowTimers, timeBase, in); 11294 mTimerDraw = readStopwatchTimerFromParcel(WAKE_TYPE_DRAW, 11295 mBsi.mDrawTimers, timeBase, in); 11296 } 11297 writeToParcelLocked(Parcel out, long elapsedRealtimeUs)11298 void writeToParcelLocked(Parcel out, long elapsedRealtimeUs) { 11299 Timer.writeTimerToParcel(out, mTimerPartial, elapsedRealtimeUs); 11300 Timer.writeTimerToParcel(out, mTimerFull, elapsedRealtimeUs); 11301 Timer.writeTimerToParcel(out, mTimerWindow, elapsedRealtimeUs); 11302 Timer.writeTimerToParcel(out, mTimerDraw, elapsedRealtimeUs); 11303 } 11304 11305 @Override 11306 @UnsupportedAppUsage getWakeTime(int type)11307 public Timer getWakeTime(int type) { 11308 switch (type) { 11309 case WAKE_TYPE_FULL: return mTimerFull; 11310 case WAKE_TYPE_PARTIAL: return mTimerPartial; 11311 case WAKE_TYPE_WINDOW: return mTimerWindow; 11312 case WAKE_TYPE_DRAW: return mTimerDraw; 11313 default: throw new IllegalArgumentException("type = " + type); 11314 } 11315 } 11316 detachFromTimeBase()11317 public void detachFromTimeBase() { 11318 detachIfNotNull(mTimerPartial); 11319 detachIfNotNull(mTimerFull); 11320 detachIfNotNull(mTimerWindow); 11321 detachIfNotNull(mTimerDraw); 11322 } 11323 } 11324 11325 public static class Sensor extends BatteryStats.Uid.Sensor { 11326 /** 11327 * BatteryStatsImpl that we are associated with. 11328 */ 11329 protected BatteryStatsImpl mBsi; 11330 11331 /** 11332 * Uid that we are associated with. 11333 */ 11334 protected Uid mUid; 11335 11336 final int mHandle; 11337 DualTimer mTimer; 11338 Sensor(BatteryStatsImpl bsi, Uid uid, int handle)11339 public Sensor(BatteryStatsImpl bsi, Uid uid, int handle) { 11340 mBsi = bsi; 11341 mUid = uid; 11342 mHandle = handle; 11343 } 11344 readTimersFromParcel( TimeBase timeBase, TimeBase bgTimeBase, Parcel in)11345 private DualTimer readTimersFromParcel( 11346 TimeBase timeBase, TimeBase bgTimeBase, Parcel in) { 11347 if (in.readInt() == 0) { 11348 return null; 11349 } 11350 11351 ArrayList<StopwatchTimer> pool = mBsi.mSensorTimers.get(mHandle); 11352 if (pool == null) { 11353 pool = new ArrayList<StopwatchTimer>(); 11354 mBsi.mSensorTimers.put(mHandle, pool); 11355 } 11356 return new DualTimer(mBsi.mClock, mUid, 0, pool, timeBase, bgTimeBase, in); 11357 } 11358 reset(long elapsedRealtimeUs)11359 boolean reset(long elapsedRealtimeUs) { 11360 if (mTimer.reset(true, elapsedRealtimeUs)) { 11361 mTimer = null; 11362 return true; 11363 } 11364 return false; 11365 } 11366 readFromParcelLocked(TimeBase timeBase, TimeBase bgTimeBase, Parcel in)11367 void readFromParcelLocked(TimeBase timeBase, TimeBase bgTimeBase, Parcel in) { 11368 mTimer = readTimersFromParcel(timeBase, bgTimeBase, in); 11369 } 11370 writeToParcelLocked(Parcel out, long elapsedRealtimeUs)11371 void writeToParcelLocked(Parcel out, long elapsedRealtimeUs) { 11372 Timer.writeTimerToParcel(out, mTimer, elapsedRealtimeUs); 11373 } 11374 11375 @Override 11376 @UnsupportedAppUsage getSensorTime()11377 public Timer getSensorTime() { 11378 return mTimer; 11379 } 11380 11381 @Override getSensorBackgroundTime()11382 public Timer getSensorBackgroundTime() { 11383 if (mTimer == null) { 11384 return null; 11385 } 11386 return mTimer.getSubTimer(); 11387 } 11388 11389 @Override 11390 @UnsupportedAppUsage getHandle()11391 public int getHandle() { 11392 return mHandle; 11393 } 11394 detachFromTimeBase()11395 public void detachFromTimeBase() { 11396 detachIfNotNull(mTimer); 11397 } 11398 } 11399 11400 /** 11401 * The statistics associated with a particular process. 11402 */ 11403 public static class Proc extends BatteryStats.Uid.Proc implements TimeBaseObs { 11404 /** 11405 * BatteryStatsImpl that we are associated with. 11406 */ 11407 protected BatteryStatsImpl mBsi; 11408 11409 /** 11410 * The name of this process. 11411 */ 11412 final String mName; 11413 11414 /** 11415 * Remains true until removed from the stats. 11416 */ 11417 boolean mActive = true; 11418 11419 /** 11420 * Total time (in ms) spent executing in user code. 11421 */ 11422 long mUserTimeMs; 11423 11424 /** 11425 * Total time (in ms) spent executing in kernel code. 11426 */ 11427 long mSystemTimeMs; 11428 11429 /** 11430 * Amount of time (in ms) the process was running in the foreground. 11431 */ 11432 long mForegroundTimeMs; 11433 11434 /** 11435 * Number of times the process has been started. 11436 */ 11437 int mStarts; 11438 11439 /** 11440 * Number of times the process has crashed. 11441 */ 11442 int mNumCrashes; 11443 11444 /** 11445 * Number of times the process has had an ANR. 11446 */ 11447 int mNumAnrs; 11448 11449 ArrayList<ExcessivePower> mExcessivePower; 11450 Proc(BatteryStatsImpl bsi, String name)11451 public Proc(BatteryStatsImpl bsi, String name) { 11452 mBsi = bsi; 11453 mName = name; 11454 mBsi.mOnBatteryTimeBase.add(this); 11455 } 11456 onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)11457 public void onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, 11458 long baseRealtimeUs) { 11459 } 11460 onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)11461 public void onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, 11462 long baseRealtimeUs) { 11463 } 11464 11465 @Override reset(boolean detachIfReset, long elapsedRealtimeUs)11466 public boolean reset(boolean detachIfReset, long elapsedRealtimeUs) { 11467 if (detachIfReset) { 11468 this.detach(); 11469 } 11470 return true; 11471 } 11472 11473 @Override detach()11474 public void detach() { 11475 mActive = false; 11476 mBsi.mOnBatteryTimeBase.remove(this); 11477 } 11478 countExcessivePowers()11479 public int countExcessivePowers() { 11480 return mExcessivePower != null ? mExcessivePower.size() : 0; 11481 } 11482 getExcessivePower(int i)11483 public ExcessivePower getExcessivePower(int i) { 11484 if (mExcessivePower != null) { 11485 return mExcessivePower.get(i); 11486 } 11487 return null; 11488 } 11489 addExcessiveCpu(long overTimeMs, long usedTimeMs)11490 public void addExcessiveCpu(long overTimeMs, long usedTimeMs) { 11491 if (mExcessivePower == null) { 11492 mExcessivePower = new ArrayList<ExcessivePower>(); 11493 } 11494 ExcessivePower ew = new ExcessivePower(); 11495 ew.type = ExcessivePower.TYPE_CPU; 11496 ew.overTime = overTimeMs; 11497 ew.usedTime = usedTimeMs; 11498 mExcessivePower.add(ew); 11499 } 11500 writeExcessivePowerToParcelLocked(Parcel out)11501 void writeExcessivePowerToParcelLocked(Parcel out) { 11502 if (mExcessivePower == null) { 11503 out.writeInt(0); 11504 return; 11505 } 11506 11507 final int N = mExcessivePower.size(); 11508 out.writeInt(N); 11509 for (int i=0; i<N; i++) { 11510 ExcessivePower ew = mExcessivePower.get(i); 11511 out.writeInt(ew.type); 11512 out.writeLong(ew.overTime); 11513 out.writeLong(ew.usedTime); 11514 } 11515 } 11516 readExcessivePowerFromParcelLocked(Parcel in)11517 void readExcessivePowerFromParcelLocked(Parcel in) { 11518 final int N = in.readInt(); 11519 if (N == 0) { 11520 mExcessivePower = null; 11521 return; 11522 } 11523 11524 if (N > 10000) { 11525 throw new ParcelFormatException( 11526 "File corrupt: too many excessive power entries " + N); 11527 } 11528 11529 mExcessivePower = new ArrayList<>(); 11530 for (int i=0; i<N; i++) { 11531 ExcessivePower ew = new ExcessivePower(); 11532 ew.type = in.readInt(); 11533 ew.overTime = in.readLong(); 11534 ew.usedTime = in.readLong(); 11535 mExcessivePower.add(ew); 11536 } 11537 } 11538 writeToParcelLocked(Parcel out)11539 void writeToParcelLocked(Parcel out) { 11540 out.writeLong(mUserTimeMs); 11541 out.writeLong(mSystemTimeMs); 11542 out.writeLong(mForegroundTimeMs); 11543 out.writeInt(mStarts); 11544 out.writeInt(mNumCrashes); 11545 out.writeInt(mNumAnrs); 11546 writeExcessivePowerToParcelLocked(out); 11547 } 11548 readFromParcelLocked(Parcel in)11549 void readFromParcelLocked(Parcel in) { 11550 mUserTimeMs = in.readLong(); 11551 mSystemTimeMs = in.readLong(); 11552 mForegroundTimeMs = in.readLong(); 11553 mStarts = in.readInt(); 11554 mNumCrashes = in.readInt(); 11555 mNumAnrs = in.readInt(); 11556 readExcessivePowerFromParcelLocked(in); 11557 } 11558 11559 @UnsupportedAppUsage addCpuTimeLocked(int utimeMs, int stimeMs)11560 public void addCpuTimeLocked(int utimeMs, int stimeMs) { 11561 addCpuTimeLocked(utimeMs, stimeMs, mBsi.mOnBatteryTimeBase.isRunning()); 11562 } 11563 addCpuTimeLocked(int utimeMs, int stimeMs, boolean isRunning)11564 public void addCpuTimeLocked(int utimeMs, int stimeMs, boolean isRunning) { 11565 if (isRunning) { 11566 mUserTimeMs += utimeMs; 11567 mSystemTimeMs += stimeMs; 11568 } 11569 } 11570 11571 @UnsupportedAppUsage addForegroundTimeLocked(long ttimeMs)11572 public void addForegroundTimeLocked(long ttimeMs) { 11573 mForegroundTimeMs += ttimeMs; 11574 } 11575 11576 @UnsupportedAppUsage incStartsLocked()11577 public void incStartsLocked() { 11578 mStarts++; 11579 } 11580 incNumCrashesLocked()11581 public void incNumCrashesLocked() { 11582 mNumCrashes++; 11583 } 11584 incNumAnrsLocked()11585 public void incNumAnrsLocked() { 11586 mNumAnrs++; 11587 } 11588 11589 @Override isActive()11590 public boolean isActive() { 11591 return mActive; 11592 } 11593 11594 @Override 11595 @UnsupportedAppUsage getUserTime(int which)11596 public long getUserTime(int which) { 11597 return mUserTimeMs; 11598 } 11599 11600 @Override 11601 @UnsupportedAppUsage getSystemTime(int which)11602 public long getSystemTime(int which) { 11603 return mSystemTimeMs; 11604 } 11605 11606 @Override 11607 @UnsupportedAppUsage getForegroundTime(int which)11608 public long getForegroundTime(int which) { 11609 return mForegroundTimeMs; 11610 } 11611 11612 @Override 11613 @UnsupportedAppUsage getStarts(int which)11614 public int getStarts(int which) { 11615 return mStarts; 11616 } 11617 11618 @Override getNumCrashes(int which)11619 public int getNumCrashes(int which) { 11620 return mNumCrashes; 11621 } 11622 11623 @Override getNumAnrs(int which)11624 public int getNumAnrs(int which) { 11625 return mNumAnrs; 11626 } 11627 } 11628 11629 /** 11630 * The statistics associated with a particular package. 11631 */ 11632 public static class Pkg extends BatteryStats.Uid.Pkg implements TimeBaseObs { 11633 /** 11634 * BatteryStatsImpl that we are associated with. 11635 */ 11636 protected BatteryStatsImpl mBsi; 11637 11638 /** 11639 * Number of times wakeup alarms have occurred for this app. 11640 * On screen-off timebase starting in report v25. 11641 */ 11642 ArrayMap<String, Counter> mWakeupAlarms = new ArrayMap<>(); 11643 11644 /** 11645 * The statics we have collected for this package's services. 11646 */ 11647 final ArrayMap<String, Serv> mServiceStats = new ArrayMap<>(); 11648 Pkg(BatteryStatsImpl bsi)11649 public Pkg(BatteryStatsImpl bsi) { 11650 mBsi = bsi; 11651 mBsi.mOnBatteryScreenOffTimeBase.add(this); 11652 } 11653 onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)11654 public void onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, 11655 long baseRealtimeUs) { 11656 } 11657 onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)11658 public void onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, 11659 long baseRealtimeUs) { 11660 } 11661 11662 @Override reset(boolean detachIfReset, long elapsedRealtimeUs)11663 public boolean reset(boolean detachIfReset, long elapsedRealtimeUs) { 11664 if (detachIfReset) { 11665 this.detach(); 11666 } 11667 return true; 11668 } 11669 11670 @Override detach()11671 public void detach() { 11672 mBsi.mOnBatteryScreenOffTimeBase.remove(this); 11673 for (int j = mWakeupAlarms.size() - 1; j >= 0; j--) { 11674 detachIfNotNull(mWakeupAlarms.valueAt(j)); 11675 } 11676 for (int j = mServiceStats.size() - 1; j >= 0; j--) { 11677 detachIfNotNull(mServiceStats.valueAt(j)); 11678 } 11679 } 11680 readFromParcelLocked(Parcel in)11681 void readFromParcelLocked(Parcel in) { 11682 int numWA = in.readInt(); 11683 mWakeupAlarms.clear(); 11684 for (int i=0; i<numWA; i++) { 11685 String tag = in.readString(); 11686 mWakeupAlarms.put(tag, new Counter(mBsi.mOnBatteryScreenOffTimeBase, in)); 11687 } 11688 11689 int numServs = in.readInt(); 11690 mServiceStats.clear(); 11691 for (int m = 0; m < numServs; m++) { 11692 String serviceName = in.readString(); 11693 Uid.Pkg.Serv serv = new Serv(mBsi); 11694 mServiceStats.put(serviceName, serv); 11695 11696 serv.readFromParcelLocked(in); 11697 } 11698 } 11699 writeToParcelLocked(Parcel out)11700 void writeToParcelLocked(Parcel out) { 11701 int numWA = mWakeupAlarms.size(); 11702 out.writeInt(numWA); 11703 for (int i=0; i<numWA; i++) { 11704 out.writeString(mWakeupAlarms.keyAt(i)); 11705 mWakeupAlarms.valueAt(i).writeToParcel(out); 11706 } 11707 11708 final int NS = mServiceStats.size(); 11709 out.writeInt(NS); 11710 for (int i=0; i<NS; i++) { 11711 out.writeString(mServiceStats.keyAt(i)); 11712 Uid.Pkg.Serv serv = mServiceStats.valueAt(i); 11713 serv.writeToParcelLocked(out); 11714 } 11715 } 11716 11717 @Override getWakeupAlarmStats()11718 public ArrayMap<String, ? extends BatteryStats.Counter> getWakeupAlarmStats() { 11719 return mWakeupAlarms; 11720 } 11721 noteWakeupAlarmLocked(String tag)11722 public void noteWakeupAlarmLocked(String tag) { 11723 Counter c = mWakeupAlarms.get(tag); 11724 if (c == null) { 11725 c = new Counter(mBsi.mOnBatteryScreenOffTimeBase); 11726 mWakeupAlarms.put(tag, c); 11727 } 11728 c.stepAtomic(); 11729 } 11730 11731 @Override getServiceStats()11732 public ArrayMap<String, ? extends BatteryStats.Uid.Pkg.Serv> getServiceStats() { 11733 return mServiceStats; 11734 } 11735 11736 /** 11737 * The statistics associated with a particular service. 11738 */ 11739 public static class Serv extends BatteryStats.Uid.Pkg.Serv implements TimeBaseObs { 11740 /** 11741 * BatteryStatsImpl that we are associated with. 11742 */ 11743 protected BatteryStatsImpl mBsi; 11744 11745 /** 11746 * The android package in which this service resides. 11747 */ 11748 protected Pkg mPkg; 11749 11750 /** 11751 * Total time (ms in battery uptime) the service has been left started. 11752 */ 11753 protected long mStartTimeMs; 11754 11755 /** 11756 * If service has been started and not yet stopped, this is 11757 * when it was started. 11758 */ 11759 protected long mRunningSinceMs; 11760 11761 /** 11762 * True if we are currently running. 11763 */ 11764 protected boolean mRunning; 11765 11766 /** 11767 * Total number of times startService() has been called. 11768 */ 11769 protected int mStarts; 11770 11771 /** 11772 * Total time (ms in battery uptime) the service has been left launched. 11773 */ 11774 protected long mLaunchedTimeMs; 11775 11776 /** 11777 * If service has been launched and not yet exited, this is 11778 * when it was launched (ms in battery uptime). 11779 */ 11780 protected long mLaunchedSinceMs; 11781 11782 /** 11783 * True if we are currently launched. 11784 */ 11785 protected boolean mLaunched; 11786 11787 /** 11788 * Total number times the service has been launched. 11789 */ 11790 protected int mLaunches; 11791 11792 /** 11793 * Construct a Serv. Also adds it to the on-battery time base as a listener. 11794 */ Serv(BatteryStatsImpl bsi)11795 public Serv(BatteryStatsImpl bsi) { 11796 mBsi = bsi; 11797 mBsi.mOnBatteryTimeBase.add(this); 11798 } 11799 onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)11800 public void onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, 11801 long baseRealtimeUs) { 11802 } 11803 onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)11804 public void onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, 11805 long baseRealtimeUs) { 11806 } 11807 11808 @Override reset(boolean detachIfReset, long elapsedRealtimeUs)11809 public boolean reset(boolean detachIfReset, long elapsedRealtimeUs) { 11810 if (detachIfReset) { 11811 this.detach(); 11812 } 11813 return true; 11814 } 11815 11816 /** 11817 * Remove this Serv as a listener from the time base. 11818 Ms*/ 11819 @Override detach()11820 public void detach() { 11821 mBsi.mOnBatteryTimeBase.remove(this); 11822 } 11823 readFromParcelLocked(Parcel in)11824 public void readFromParcelLocked(Parcel in) { 11825 mStartTimeMs = in.readLong(); 11826 mRunningSinceMs = in.readLong(); 11827 mRunning = in.readInt() != 0; 11828 mStarts = in.readInt(); 11829 mLaunchedTimeMs = in.readLong(); 11830 mLaunchedSinceMs = in.readLong(); 11831 mLaunched = in.readInt() != 0; 11832 mLaunches = in.readInt(); 11833 } 11834 writeToParcelLocked(Parcel out)11835 public void writeToParcelLocked(Parcel out) { 11836 out.writeLong(mStartTimeMs); 11837 out.writeLong(mRunningSinceMs); 11838 out.writeInt(mRunning ? 1 : 0); 11839 out.writeInt(mStarts); 11840 out.writeLong(mLaunchedTimeMs); 11841 out.writeLong(mLaunchedSinceMs); 11842 out.writeInt(mLaunched ? 1 : 0); 11843 out.writeInt(mLaunches); 11844 } 11845 getLaunchTimeToNowLocked(long batteryUptimeMs)11846 public long getLaunchTimeToNowLocked(long batteryUptimeMs) { 11847 if (!mLaunched) return mLaunchedTimeMs; 11848 return mLaunchedTimeMs + batteryUptimeMs - mLaunchedSinceMs; 11849 } 11850 getStartTimeToNowLocked(long batteryUptimeMs)11851 public long getStartTimeToNowLocked(long batteryUptimeMs) { 11852 if (!mRunning) return mStartTimeMs; 11853 return mStartTimeMs + batteryUptimeMs - mRunningSinceMs; 11854 } 11855 11856 @UnsupportedAppUsage startLaunchedLocked()11857 public void startLaunchedLocked() { 11858 startLaunchedLocked(mBsi.mClock.uptimeMillis()); 11859 } 11860 startLaunchedLocked(long uptimeMs)11861 public void startLaunchedLocked(long uptimeMs) { 11862 if (!mLaunched) { 11863 mLaunches++; 11864 mLaunchedSinceMs = mBsi.getBatteryUptimeLocked(uptimeMs) / 1000; 11865 mLaunched = true; 11866 } 11867 } 11868 11869 @UnsupportedAppUsage stopLaunchedLocked()11870 public void stopLaunchedLocked() { 11871 stopLaunchedLocked(mBsi.mClock.uptimeMillis()); 11872 } 11873 stopLaunchedLocked(long uptimeMs)11874 public void stopLaunchedLocked(long uptimeMs) { 11875 if (mLaunched) { 11876 long timeMs = mBsi.getBatteryUptimeLocked(uptimeMs) / 1000 11877 - mLaunchedSinceMs; 11878 if (timeMs > 0) { 11879 mLaunchedTimeMs += timeMs; 11880 } else { 11881 mLaunches--; 11882 } 11883 mLaunched = false; 11884 } 11885 } 11886 11887 @UnsupportedAppUsage startRunningLocked()11888 public void startRunningLocked() { 11889 startRunningLocked(mBsi.mClock.uptimeMillis()); 11890 } 11891 startRunningLocked(long uptimeMs)11892 public void startRunningLocked(long uptimeMs) { 11893 if (!mRunning) { 11894 mStarts++; 11895 mRunningSinceMs = mBsi.getBatteryUptimeLocked(uptimeMs) / 1000; 11896 mRunning = true; 11897 } 11898 } 11899 11900 @UnsupportedAppUsage stopRunningLocked()11901 public void stopRunningLocked() { 11902 stopRunningLocked(mBsi.mClock.uptimeMillis()); 11903 } 11904 stopRunningLocked(long uptimeMs)11905 public void stopRunningLocked(long uptimeMs) { 11906 if (mRunning) { 11907 long timeMs = mBsi.getBatteryUptimeLocked(uptimeMs) / 1000 11908 - mRunningSinceMs; 11909 if (timeMs > 0) { 11910 mStartTimeMs += timeMs; 11911 } else { 11912 mStarts--; 11913 } 11914 mRunning = false; 11915 } 11916 } 11917 11918 @UnsupportedAppUsage getBatteryStats()11919 public BatteryStatsImpl getBatteryStats() { 11920 return mBsi; 11921 } 11922 11923 @Override getLaunches(int which)11924 public int getLaunches(int which) { 11925 return mLaunches; 11926 } 11927 11928 @Override getStartTime(long now, int which)11929 public long getStartTime(long now, int which) { 11930 return getStartTimeToNowLocked(now); 11931 } 11932 11933 @Override getStarts(int which)11934 public int getStarts(int which) { 11935 return mStarts; 11936 } 11937 } 11938 newServiceStatsLocked()11939 final Serv newServiceStatsLocked() { 11940 return new Serv(mBsi); 11941 } 11942 } 11943 11944 private class ChildUid { 11945 public final TimeMultiStateCounter cpuActiveCounter; 11946 public final LongArrayMultiStateCounter cpuTimeInFreqCounter; 11947 ChildUid()11948 ChildUid() { 11949 final long timestampMs = mBsi.mClock.elapsedRealtime(); 11950 cpuActiveCounter = 11951 new TimeMultiStateCounter(mBsi.mOnBatteryTimeBase, 1, timestampMs); 11952 cpuActiveCounter.setState(0, timestampMs); 11953 11954 if (mBsi.trackPerProcStateCpuTimes()) { 11955 final int cpuFreqCount = mBsi.getCpuFreqCount(); 11956 11957 cpuTimeInFreqCounter = new LongArrayMultiStateCounter(1, cpuFreqCount); 11958 11959 // Set initial values to all 0. This is a child UID and we want to include 11960 // the entirety of its CPU time-in-freq stats into the parent's stats. 11961 cpuTimeInFreqCounter.updateValues( 11962 new LongArrayMultiStateCounter.LongArrayContainer(cpuFreqCount), 11963 timestampMs); 11964 } else { 11965 cpuTimeInFreqCounter = null; 11966 } 11967 } 11968 } 11969 11970 /** 11971 * Retrieve the statistics object for a particular process, creating 11972 * if needed. 11973 */ getProcessStatsLocked(String name)11974 public Proc getProcessStatsLocked(String name) { 11975 Proc ps = mProcessStats.get(name); 11976 if (ps == null) { 11977 ps = new Proc(mBsi, name); 11978 mProcessStats.put(name, ps); 11979 } 11980 11981 return ps; 11982 } 11983 11984 @GuardedBy("mBsi") updateUidProcessStateLocked(int procState, long elapsedRealtimeMs, long uptimeMs)11985 public void updateUidProcessStateLocked(int procState, 11986 long elapsedRealtimeMs, long uptimeMs) { 11987 int uidRunningState; 11988 // Make special note of Foreground Services 11989 final boolean userAwareService = 11990 (ActivityManager.isForegroundService(procState)); 11991 uidRunningState = BatteryStats.mapToInternalProcessState(procState); 11992 11993 if (mProcessState == uidRunningState && userAwareService == mInForegroundService) { 11994 return; 11995 } 11996 11997 if (mProcessState != uidRunningState) { 11998 if (mProcessState != Uid.PROCESS_STATE_NONEXISTENT) { 11999 mProcessStateTimer[mProcessState].stopRunningLocked(elapsedRealtimeMs); 12000 } 12001 if (uidRunningState != Uid.PROCESS_STATE_NONEXISTENT) { 12002 if (mProcessStateTimer[uidRunningState] == null) { 12003 makeProcessState(uidRunningState, null); 12004 } 12005 mProcessStateTimer[uidRunningState].startRunningLocked(elapsedRealtimeMs); 12006 } 12007 12008 if (mBsi.trackPerProcStateCpuTimes()) { 12009 mBsi.updateProcStateCpuTimesLocked(mUid, elapsedRealtimeMs); 12010 12011 LongArrayMultiStateCounter onBatteryCounter = 12012 getProcStateTimeCounter(elapsedRealtimeMs).getCounter(); 12013 LongArrayMultiStateCounter onBatteryScreenOffCounter = 12014 getProcStateScreenOffTimeCounter(elapsedRealtimeMs).getCounter(); 12015 12016 onBatteryCounter.setState(uidRunningState, elapsedRealtimeMs); 12017 onBatteryScreenOffCounter.setState(uidRunningState, elapsedRealtimeMs); 12018 } 12019 12020 final int prevBatteryConsumerProcessState = 12021 mapUidProcessStateToBatteryConsumerProcessState(mProcessState); 12022 12023 mProcessState = uidRunningState; 12024 12025 updateOnBatteryBgTimeBase(uptimeMs * 1000, elapsedRealtimeMs * 1000); 12026 updateOnBatteryScreenOffBgTimeBase(uptimeMs * 1000, elapsedRealtimeMs * 1000); 12027 12028 final int batteryConsumerProcessState = 12029 mapUidProcessStateToBatteryConsumerProcessState(uidRunningState); 12030 getCpuActiveTimeCounter().setState(batteryConsumerProcessState, elapsedRealtimeMs); 12031 12032 getMobileRadioActiveTimeCounter() 12033 .setState(batteryConsumerProcessState, elapsedRealtimeMs); 12034 12035 final ControllerActivityCounterImpl wifiControllerActivity = 12036 getWifiControllerActivity(); 12037 if (wifiControllerActivity != null) { 12038 wifiControllerActivity.setState(batteryConsumerProcessState, elapsedRealtimeMs); 12039 } 12040 12041 final ControllerActivityCounterImpl bluetoothControllerActivity = 12042 getBluetoothControllerActivity(); 12043 if (bluetoothControllerActivity != null) { 12044 bluetoothControllerActivity.setState(batteryConsumerProcessState, 12045 elapsedRealtimeMs); 12046 } 12047 12048 final MeasuredEnergyStats energyStats = 12049 getOrCreateMeasuredEnergyStatsIfSupportedLocked(); 12050 if (energyStats != null) { 12051 energyStats.setState(batteryConsumerProcessState, elapsedRealtimeMs); 12052 } 12053 maybeScheduleExternalStatsSync(prevBatteryConsumerProcessState, 12054 batteryConsumerProcessState); 12055 } 12056 12057 if (userAwareService != mInForegroundService) { 12058 if (userAwareService) { 12059 noteForegroundServiceResumedLocked(elapsedRealtimeMs); 12060 } else { 12061 noteForegroundServicePausedLocked(elapsedRealtimeMs); 12062 } 12063 mInForegroundService = userAwareService; 12064 } 12065 } 12066 12067 @GuardedBy("mBsi") maybeScheduleExternalStatsSync( @atteryConsumer.ProcessState int oldProcessState, @BatteryConsumer.ProcessState int newProcessState)12068 private void maybeScheduleExternalStatsSync( 12069 @BatteryConsumer.ProcessState int oldProcessState, 12070 @BatteryConsumer.ProcessState int newProcessState) { 12071 if (oldProcessState == newProcessState) { 12072 return; 12073 } 12074 // Transitions between BACKGROUND and such non-foreground states like cached 12075 // or nonexistent do not warrant doing a sync. If some of the stats for those 12076 // proc states bleed into the PROCESS_STATE_BACKGROUND, that's ok. 12077 if ((oldProcessState == BatteryConsumer.PROCESS_STATE_UNSPECIFIED 12078 && newProcessState == BatteryConsumer.PROCESS_STATE_BACKGROUND) 12079 || (oldProcessState == BatteryConsumer.PROCESS_STATE_BACKGROUND 12080 && newProcessState == BatteryConsumer.PROCESS_STATE_UNSPECIFIED)) { 12081 return; 12082 } 12083 12084 int flags = ExternalStatsSync.UPDATE_ON_PROC_STATE_CHANGE; 12085 // Skip querying for inactive radio, where power usage is probably negligible. 12086 if (!BatteryStatsImpl.isActiveRadioPowerState(mBsi.mMobileRadioPowerState)) { 12087 flags &= ~ExternalStatsSync.UPDATE_RADIO; 12088 } 12089 12090 mBsi.mExternalSync.scheduleSyncDueToProcessStateChange(flags, 12091 mBsi.mConstants.PROC_STATE_CHANGE_COLLECTION_DELAY_MS); 12092 } 12093 12094 /** Whether to consider Uid to be in the background for background timebase purposes. */ isInBackground()12095 public boolean isInBackground() { 12096 // Note that PROCESS_STATE_CACHED and Uid.PROCESS_STATE_NONEXISTENT is 12097 // also considered to be 'background' for our purposes, because it's not foreground. 12098 return mProcessState >= PROCESS_STATE_BACKGROUND; 12099 } 12100 updateOnBatteryBgTimeBase(long uptimeUs, long realtimeUs)12101 public boolean updateOnBatteryBgTimeBase(long uptimeUs, long realtimeUs) { 12102 boolean on = mBsi.mOnBatteryTimeBase.isRunning() && isInBackground(); 12103 return mOnBatteryBackgroundTimeBase.setRunning(on, uptimeUs, realtimeUs); 12104 } 12105 updateOnBatteryScreenOffBgTimeBase(long uptimeUs, long realtimeUs)12106 public boolean updateOnBatteryScreenOffBgTimeBase(long uptimeUs, long realtimeUs) { 12107 boolean on = mBsi.mOnBatteryScreenOffTimeBase.isRunning() && isInBackground(); 12108 return mOnBatteryScreenOffBackgroundTimeBase.setRunning(on, uptimeUs, realtimeUs); 12109 } 12110 getPidStats()12111 public SparseArray<? extends Pid> getPidStats() { 12112 return mPids; 12113 } 12114 getPidStatsLocked(int pid)12115 public Pid getPidStatsLocked(int pid) { 12116 Pid p = mPids.get(pid); 12117 if (p == null) { 12118 p = new Pid(); 12119 mPids.put(pid, p); 12120 } 12121 return p; 12122 } 12123 12124 /** 12125 * Retrieve the statistics object for a particular service, creating 12126 * if needed. 12127 */ getPackageStatsLocked(String name)12128 public Pkg getPackageStatsLocked(String name) { 12129 Pkg ps = mPackageStats.get(name); 12130 if (ps == null) { 12131 ps = new Pkg(mBsi); 12132 mPackageStats.put(name, ps); 12133 } 12134 12135 return ps; 12136 } 12137 12138 /** 12139 * Retrieve the statistics object for a particular service, creating 12140 * if needed. 12141 */ getServiceStatsLocked(String pkg, String serv)12142 public Pkg.Serv getServiceStatsLocked(String pkg, String serv) { 12143 Pkg ps = getPackageStatsLocked(pkg); 12144 Pkg.Serv ss = ps.mServiceStats.get(serv); 12145 if (ss == null) { 12146 ss = ps.newServiceStatsLocked(); 12147 ps.mServiceStats.put(serv, ss); 12148 } 12149 12150 return ss; 12151 } 12152 readSyncSummaryFromParcelLocked(String name, Parcel in)12153 public void readSyncSummaryFromParcelLocked(String name, Parcel in) { 12154 DualTimer timer = mSyncStats.instantiateObject(); 12155 timer.readSummaryFromParcelLocked(in); 12156 mSyncStats.add(name, timer); 12157 } 12158 readJobSummaryFromParcelLocked(String name, Parcel in)12159 public void readJobSummaryFromParcelLocked(String name, Parcel in) { 12160 DualTimer timer = mJobStats.instantiateObject(); 12161 timer.readSummaryFromParcelLocked(in); 12162 mJobStats.add(name, timer); 12163 } 12164 readWakeSummaryFromParcelLocked(String wlName, Parcel in)12165 public void readWakeSummaryFromParcelLocked(String wlName, Parcel in) { 12166 Wakelock wl = new Wakelock(mBsi, this); 12167 mWakelockStats.add(wlName, wl); 12168 if (in.readInt() != 0) { 12169 getWakelockTimerLocked(wl, WAKE_TYPE_FULL).readSummaryFromParcelLocked(in); 12170 } 12171 if (in.readInt() != 0) { 12172 getWakelockTimerLocked(wl, WAKE_TYPE_PARTIAL).readSummaryFromParcelLocked(in); 12173 } 12174 if (in.readInt() != 0) { 12175 getWakelockTimerLocked(wl, WAKE_TYPE_WINDOW).readSummaryFromParcelLocked(in); 12176 } 12177 if (in.readInt() != 0) { 12178 getWakelockTimerLocked(wl, WAKE_TYPE_DRAW).readSummaryFromParcelLocked(in); 12179 } 12180 } 12181 getSensorTimerLocked(int sensor, boolean create)12182 public DualTimer getSensorTimerLocked(int sensor, boolean create) { 12183 Sensor se = mSensorStats.get(sensor); 12184 if (se == null) { 12185 if (!create) { 12186 return null; 12187 } 12188 se = new Sensor(mBsi, this, sensor); 12189 mSensorStats.put(sensor, se); 12190 } 12191 DualTimer t = se.mTimer; 12192 if (t != null) { 12193 return t; 12194 } 12195 ArrayList<StopwatchTimer> timers = mBsi.mSensorTimers.get(sensor); 12196 if (timers == null) { 12197 timers = new ArrayList<StopwatchTimer>(); 12198 mBsi.mSensorTimers.put(sensor, timers); 12199 } 12200 t = new DualTimer(mBsi.mClock, this, BatteryStats.SENSOR, timers, 12201 mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase); 12202 se.mTimer = t; 12203 return t; 12204 } 12205 noteStartSyncLocked(String name, long elapsedRealtimeMs)12206 public void noteStartSyncLocked(String name, long elapsedRealtimeMs) { 12207 DualTimer t = mSyncStats.startObject(name, elapsedRealtimeMs); 12208 if (t != null) { 12209 t.startRunningLocked(elapsedRealtimeMs); 12210 } 12211 } 12212 noteStopSyncLocked(String name, long elapsedRealtimeMs)12213 public void noteStopSyncLocked(String name, long elapsedRealtimeMs) { 12214 DualTimer t = mSyncStats.stopObject(name, elapsedRealtimeMs); 12215 if (t != null) { 12216 t.stopRunningLocked(elapsedRealtimeMs); 12217 } 12218 } 12219 noteStartJobLocked(String name, long elapsedRealtimeMs)12220 public void noteStartJobLocked(String name, long elapsedRealtimeMs) { 12221 DualTimer t = mJobStats.startObject(name, elapsedRealtimeMs); 12222 if (t != null) { 12223 t.startRunningLocked(elapsedRealtimeMs); 12224 } 12225 } 12226 noteStopJobLocked(String name, long elapsedRealtimeMs, int stopReason)12227 public void noteStopJobLocked(String name, long elapsedRealtimeMs, int stopReason) { 12228 DualTimer t = mJobStats.stopObject(name, elapsedRealtimeMs); 12229 if (t != null) { 12230 t.stopRunningLocked(elapsedRealtimeMs); 12231 } 12232 if (mBsi.mOnBatteryTimeBase.isRunning()) { 12233 SparseIntArray types = mJobCompletions.get(name); 12234 if (types == null) { 12235 types = new SparseIntArray(); 12236 mJobCompletions.put(name, types); 12237 } 12238 int last = types.get(stopReason, 0); 12239 types.put(stopReason, last + 1); 12240 } 12241 } 12242 getWakelockTimerLocked(Wakelock wl, int type)12243 public StopwatchTimer getWakelockTimerLocked(Wakelock wl, int type) { 12244 if (wl == null) { 12245 return null; 12246 } 12247 switch (type) { 12248 case WAKE_TYPE_PARTIAL: { 12249 DualTimer t = wl.mTimerPartial; 12250 if (t == null) { 12251 t = new DualTimer(mBsi.mClock, this, WAKE_TYPE_PARTIAL, 12252 mBsi.mPartialTimers, mBsi.mOnBatteryScreenOffTimeBase, 12253 mOnBatteryScreenOffBackgroundTimeBase); 12254 wl.mTimerPartial = t; 12255 } 12256 return t; 12257 } 12258 case WAKE_TYPE_FULL: { 12259 StopwatchTimer t = wl.mTimerFull; 12260 if (t == null) { 12261 t = new StopwatchTimer(mBsi.mClock, this, WAKE_TYPE_FULL, 12262 mBsi.mFullTimers, mBsi.mOnBatteryTimeBase); 12263 wl.mTimerFull = t; 12264 } 12265 return t; 12266 } 12267 case WAKE_TYPE_WINDOW: { 12268 StopwatchTimer t = wl.mTimerWindow; 12269 if (t == null) { 12270 t = new StopwatchTimer(mBsi.mClock, this, WAKE_TYPE_WINDOW, 12271 mBsi.mWindowTimers, mBsi.mOnBatteryTimeBase); 12272 wl.mTimerWindow = t; 12273 } 12274 return t; 12275 } 12276 case WAKE_TYPE_DRAW: { 12277 StopwatchTimer t = wl.mTimerDraw; 12278 if (t == null) { 12279 t = new StopwatchTimer(mBsi.mClock, this, WAKE_TYPE_DRAW, 12280 mBsi.mDrawTimers, mBsi.mOnBatteryTimeBase); 12281 wl.mTimerDraw = t; 12282 } 12283 return t; 12284 } 12285 default: 12286 throw new IllegalArgumentException("type=" + type); 12287 } 12288 } 12289 noteStartWakeLocked(int pid, String name, int type, long elapsedRealtimeMs)12290 public void noteStartWakeLocked(int pid, String name, int type, long elapsedRealtimeMs) { 12291 Wakelock wl = mWakelockStats.startObject(name, elapsedRealtimeMs); 12292 if (wl != null) { 12293 getWakelockTimerLocked(wl, type).startRunningLocked(elapsedRealtimeMs); 12294 } 12295 if (type == WAKE_TYPE_PARTIAL) { 12296 createAggregatedPartialWakelockTimerLocked().startRunningLocked(elapsedRealtimeMs); 12297 if (pid >= 0) { 12298 Pid p = getPidStatsLocked(pid); 12299 if (p.mWakeNesting++ == 0) { 12300 p.mWakeStartMs = elapsedRealtimeMs; 12301 } 12302 } 12303 } 12304 } 12305 noteStopWakeLocked(int pid, String name, int type, long elapsedRealtimeMs)12306 public void noteStopWakeLocked(int pid, String name, int type, long elapsedRealtimeMs) { 12307 Wakelock wl = mWakelockStats.stopObject(name, elapsedRealtimeMs); 12308 if (wl != null) { 12309 StopwatchTimer wlt = getWakelockTimerLocked(wl, type); 12310 wlt.stopRunningLocked(elapsedRealtimeMs); 12311 } 12312 if (type == WAKE_TYPE_PARTIAL) { 12313 if (mAggregatedPartialWakelockTimer != null) { 12314 mAggregatedPartialWakelockTimer.stopRunningLocked(elapsedRealtimeMs); 12315 } 12316 if (pid >= 0) { 12317 Pid p = mPids.get(pid); 12318 if (p != null && p.mWakeNesting > 0) { 12319 if (p.mWakeNesting-- == 1) { 12320 p.mWakeSumMs += elapsedRealtimeMs - p.mWakeStartMs; 12321 p.mWakeStartMs = 0; 12322 } 12323 } 12324 } 12325 } 12326 } 12327 reportExcessiveCpuLocked(String proc, long overTimeMs, long usedTimeMs)12328 public void reportExcessiveCpuLocked(String proc, long overTimeMs, long usedTimeMs) { 12329 Proc p = getProcessStatsLocked(proc); 12330 if (p != null) { 12331 p.addExcessiveCpu(overTimeMs, usedTimeMs); 12332 } 12333 } 12334 noteStartSensor(int sensor, long elapsedRealtimeMs)12335 public void noteStartSensor(int sensor, long elapsedRealtimeMs) { 12336 DualTimer t = getSensorTimerLocked(sensor, /* create= */ true); 12337 t.startRunningLocked(elapsedRealtimeMs); 12338 } 12339 noteStopSensor(int sensor, long elapsedRealtimeMs)12340 public void noteStopSensor(int sensor, long elapsedRealtimeMs) { 12341 // Don't create a timer if one doesn't already exist 12342 DualTimer t = getSensorTimerLocked(sensor, false); 12343 if (t != null) { 12344 t.stopRunningLocked(elapsedRealtimeMs); 12345 } 12346 } 12347 noteStartGps(long elapsedRealtimeMs)12348 public void noteStartGps(long elapsedRealtimeMs) { 12349 noteStartSensor(Sensor.GPS, elapsedRealtimeMs); 12350 } 12351 noteStopGps(long elapsedRealtimeMs)12352 public void noteStopGps(long elapsedRealtimeMs) { 12353 noteStopSensor(Sensor.GPS, elapsedRealtimeMs); 12354 } 12355 getBatteryStats()12356 public BatteryStatsImpl getBatteryStats() { 12357 return mBsi; 12358 } 12359 } 12360 12361 @GuardedBy("this") 12362 @Override getCpuFreqs()12363 public long[] getCpuFreqs() { 12364 if (!mCpuFreqsInitialized) { 12365 mCpuFreqs = mCpuUidFreqTimeReader.readFreqs(mPowerProfile); 12366 mCpuFreqsInitialized = true; 12367 } 12368 return mCpuFreqs; 12369 } 12370 12371 @GuardedBy("this") 12372 @Override getCpuFreqCount()12373 public int getCpuFreqCount() { 12374 final long[] cpuFreqs = getCpuFreqs(); 12375 return cpuFreqs != null ? cpuFreqs.length : 0; 12376 } 12377 12378 @GuardedBy("this") getCpuTimeInFreqContainer()12379 private LongArrayMultiStateCounter.LongArrayContainer getCpuTimeInFreqContainer() { 12380 if (mTmpCpuTimeInFreq == null) { 12381 mTmpCpuTimeInFreq = 12382 new LongArrayMultiStateCounter.LongArrayContainer(getCpuFreqCount()); 12383 } 12384 return mTmpCpuTimeInFreq; 12385 } 12386 BatteryStatsImpl(File systemDir, Handler handler, PlatformIdleStateCallback cb, MeasuredEnergyRetriever energyStatsCb, UserInfoProvider userInfoProvider)12387 public BatteryStatsImpl(File systemDir, Handler handler, PlatformIdleStateCallback cb, 12388 MeasuredEnergyRetriever energyStatsCb, UserInfoProvider userInfoProvider) { 12389 this(Clock.SYSTEM_CLOCK, systemDir, handler, cb, energyStatsCb, userInfoProvider); 12390 } 12391 BatteryStatsImpl(Clock clock, File systemDir, Handler handler, PlatformIdleStateCallback cb, MeasuredEnergyRetriever energyStatsCb, UserInfoProvider userInfoProvider)12392 private BatteryStatsImpl(Clock clock, File systemDir, Handler handler, 12393 PlatformIdleStateCallback cb, MeasuredEnergyRetriever energyStatsCb, 12394 UserInfoProvider userInfoProvider) { 12395 init(clock); 12396 12397 if (systemDir == null) { 12398 mStatsFile = null; 12399 mBatteryStatsHistory = new BatteryStatsHistory(mHistoryBuffer); 12400 } else { 12401 mStatsFile = new AtomicFile(new File(systemDir, "batterystats.bin")); 12402 mBatteryStatsHistory = new BatteryStatsHistory(this, systemDir, mHistoryBuffer); 12403 } 12404 mCheckinFile = new AtomicFile(new File(systemDir, "batterystats-checkin.bin")); 12405 mDailyFile = new AtomicFile(new File(systemDir, "batterystats-daily.xml")); 12406 mHandler = new MyHandler(handler.getLooper()); 12407 mConstants = new Constants(mHandler); 12408 mStartCount++; 12409 initTimersAndCounters(); 12410 mOnBattery = mOnBatteryInternal = false; 12411 long uptimeUs = mClock.uptimeMillis() * 1000; 12412 long realtimeUs = mClock.elapsedRealtime() * 1000; 12413 initTimes(uptimeUs, realtimeUs); 12414 mStartPlatformVersion = mEndPlatformVersion = Build.ID; 12415 initDischarge(realtimeUs); 12416 clearHistoryLocked(); 12417 updateDailyDeadlineLocked(); 12418 mPlatformIdleStateCallback = cb; 12419 mMeasuredEnergyRetriever = energyStatsCb; 12420 mUserInfoProvider = userInfoProvider; 12421 12422 // Notify statsd that the system is initially not in doze. 12423 mDeviceIdleMode = DEVICE_IDLE_MODE_OFF; 12424 FrameworkStatsLog.write(FrameworkStatsLog.DEVICE_IDLE_MODE_STATE_CHANGED, mDeviceIdleMode); 12425 } 12426 12427 @VisibleForTesting initTimersAndCounters()12428 protected void initTimersAndCounters() { 12429 mScreenOnTimer = new StopwatchTimer(mClock, null, -1, null, mOnBatteryTimeBase); 12430 mScreenDozeTimer = new StopwatchTimer(mClock, null, -1, null, mOnBatteryTimeBase); 12431 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 12432 mScreenBrightnessTimer[i] = new StopwatchTimer(mClock, null, -100 - i, null, 12433 mOnBatteryTimeBase); 12434 } 12435 12436 mPerDisplayBatteryStats = new DisplayBatteryStats[1]; 12437 mPerDisplayBatteryStats[0] = new DisplayBatteryStats(mClock, mOnBatteryTimeBase); 12438 12439 mInteractiveTimer = new StopwatchTimer(mClock, null, -10, null, mOnBatteryTimeBase); 12440 mPowerSaveModeEnabledTimer = new StopwatchTimer(mClock, null, -2, null, 12441 mOnBatteryTimeBase); 12442 mDeviceIdleModeLightTimer = new StopwatchTimer(mClock, null, -11, null, 12443 mOnBatteryTimeBase); 12444 mDeviceIdleModeFullTimer = new StopwatchTimer(mClock, null, -14, null, mOnBatteryTimeBase); 12445 mDeviceLightIdlingTimer = new StopwatchTimer(mClock, null, -15, null, mOnBatteryTimeBase); 12446 mDeviceIdlingTimer = new StopwatchTimer(mClock, null, -12, null, mOnBatteryTimeBase); 12447 mPhoneOnTimer = new StopwatchTimer(mClock, null, -3, null, mOnBatteryTimeBase); 12448 for (int i = 0; i < CellSignalStrength.getNumSignalStrengthLevels(); i++) { 12449 mPhoneSignalStrengthsTimer[i] = new StopwatchTimer(mClock, null, -200 - i, null, 12450 mOnBatteryTimeBase); 12451 } 12452 mPhoneSignalScanningTimer = new StopwatchTimer(mClock, null, -200 + 1, null, 12453 mOnBatteryTimeBase); 12454 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 12455 mPhoneDataConnectionsTimer[i] = new StopwatchTimer(mClock, null, -300 - i, null, 12456 mOnBatteryTimeBase); 12457 } 12458 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 12459 mNetworkByteActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase); 12460 mNetworkPacketActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase); 12461 } 12462 mWifiActivity = new ControllerActivityCounterImpl(mClock, mOnBatteryTimeBase, 12463 NUM_WIFI_TX_LEVELS); 12464 mBluetoothActivity = new ControllerActivityCounterImpl(mClock, mOnBatteryTimeBase, 12465 NUM_BT_TX_LEVELS); 12466 mModemActivity = new ControllerActivityCounterImpl(mClock, mOnBatteryTimeBase, 12467 ModemActivityInfo.getNumTxPowerLevels()); 12468 mMobileRadioActiveTimer = new StopwatchTimer(mClock, null, -400, null, mOnBatteryTimeBase); 12469 mMobileRadioActivePerAppTimer = new StopwatchTimer(mClock, null, -401, null, 12470 mOnBatteryTimeBase); 12471 mMobileRadioActiveAdjustedTime = new LongSamplingCounter(mOnBatteryTimeBase); 12472 mMobileRadioActiveUnknownTime = new LongSamplingCounter(mOnBatteryTimeBase); 12473 mMobileRadioActiveUnknownCount = new LongSamplingCounter(mOnBatteryTimeBase); 12474 mWifiMulticastWakelockTimer = new StopwatchTimer(mClock, null, 12475 WIFI_AGGREGATE_MULTICAST_ENABLED, null, mOnBatteryTimeBase); 12476 mWifiOnTimer = new StopwatchTimer(mClock, null, -4, null, mOnBatteryTimeBase); 12477 mGlobalWifiRunningTimer = new StopwatchTimer(mClock, null, -5, null, mOnBatteryTimeBase); 12478 for (int i=0; i<NUM_WIFI_STATES; i++) { 12479 mWifiStateTimer[i] = new StopwatchTimer(mClock, null, -600 - i, null, 12480 mOnBatteryTimeBase); 12481 } 12482 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) { 12483 mWifiSupplStateTimer[i] = new StopwatchTimer(mClock, null, -700 - i, null, 12484 mOnBatteryTimeBase); 12485 } 12486 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { 12487 mWifiSignalStrengthsTimer[i] = new StopwatchTimer(mClock, null, -800 - i, null, 12488 mOnBatteryTimeBase); 12489 } 12490 mWifiActiveTimer = new StopwatchTimer(mClock, null, -900, null, mOnBatteryTimeBase); 12491 for (int i=0; i< mGpsSignalQualityTimer.length; i++) { 12492 mGpsSignalQualityTimer[i] = new StopwatchTimer(mClock, null, -1000 - i, null, 12493 mOnBatteryTimeBase); 12494 } 12495 mAudioOnTimer = new StopwatchTimer(mClock, null, -7, null, mOnBatteryTimeBase); 12496 mVideoOnTimer = new StopwatchTimer(mClock, null, -8, null, mOnBatteryTimeBase); 12497 mFlashlightOnTimer = new StopwatchTimer(mClock, null, -9, null, mOnBatteryTimeBase); 12498 mCameraOnTimer = new StopwatchTimer(mClock, null, -13, null, mOnBatteryTimeBase); 12499 mBluetoothScanTimer = new StopwatchTimer(mClock, null, -14, null, mOnBatteryTimeBase); 12500 mDischargeScreenOffCounter = new LongSamplingCounter(mOnBatteryScreenOffTimeBase); 12501 mDischargeScreenDozeCounter = new LongSamplingCounter(mOnBatteryTimeBase); 12502 mDischargeLightDozeCounter = new LongSamplingCounter(mOnBatteryTimeBase); 12503 mDischargeDeepDozeCounter = new LongSamplingCounter(mOnBatteryTimeBase); 12504 mDischargeCounter = new LongSamplingCounter(mOnBatteryTimeBase); 12505 mDischargeStartLevel = 0; 12506 mDischargeUnplugLevel = 0; 12507 mDischargePlugLevel = -1; 12508 mDischargeCurrentLevel = 0; 12509 mCurrentBatteryLevel = 0; 12510 } 12511 12512 @UnsupportedAppUsage BatteryStatsImpl(Parcel p)12513 public BatteryStatsImpl(Parcel p) { 12514 this(Clock.SYSTEM_CLOCK, p); 12515 } 12516 BatteryStatsImpl(Clock clock, Parcel p)12517 public BatteryStatsImpl(Clock clock, Parcel p) { 12518 init(clock); 12519 mStatsFile = null; 12520 mCheckinFile = null; 12521 mDailyFile = null; 12522 mHandler = null; 12523 mExternalSync = null; 12524 mConstants = new Constants(mHandler); 12525 clearHistoryLocked(); 12526 mBatteryStatsHistory = new BatteryStatsHistory(mHistoryBuffer); 12527 readFromParcel(p); 12528 mPlatformIdleStateCallback = null; 12529 mMeasuredEnergyRetriever = null; 12530 } 12531 setPowerProfileLocked(PowerProfile profile)12532 public void setPowerProfileLocked(PowerProfile profile) { 12533 mPowerProfile = profile; 12534 12535 // We need to initialize the KernelCpuSpeedReaders to read from 12536 // the first cpu of each core. Once we have the PowerProfile, we have access to this 12537 // information. 12538 final int numClusters = mPowerProfile.getNumCpuClusters(); 12539 mKernelCpuSpeedReaders = new KernelCpuSpeedReader[numClusters]; 12540 int firstCpuOfCluster = 0; 12541 for (int i = 0; i < numClusters; i++) { 12542 final int numSpeedSteps = mPowerProfile.getNumSpeedStepsInCpuCluster(i); 12543 mKernelCpuSpeedReaders[i] = new KernelCpuSpeedReader(firstCpuOfCluster, 12544 numSpeedSteps); 12545 firstCpuOfCluster += mPowerProfile.getNumCoresInCpuCluster(i); 12546 } 12547 12548 if (mEstimatedBatteryCapacityMah == -1) { 12549 // Initialize the estimated battery capacity to a known preset one. 12550 mEstimatedBatteryCapacityMah = (int) mPowerProfile.getBatteryCapacity(); 12551 } 12552 12553 setDisplayCountLocked(mPowerProfile.getNumDisplays()); 12554 } 12555 getPowerProfile()12556 PowerProfile getPowerProfile() { 12557 return mPowerProfile; 12558 } 12559 12560 /** 12561 * Starts tracking CPU time-in-state for threads of the system server process, 12562 * keeping a separate account of threads receiving incoming binder calls. 12563 */ startTrackingSystemServerCpuTime()12564 public void startTrackingSystemServerCpuTime() { 12565 mSystemServerCpuThreadReader.startTrackingThreadCpuTime(); 12566 } 12567 getSystemServiceCpuThreadTimes()12568 public SystemServiceCpuThreadTimes getSystemServiceCpuThreadTimes() { 12569 return mSystemServerCpuThreadReader.readAbsolute(); 12570 } 12571 setCallback(BatteryCallback cb)12572 public void setCallback(BatteryCallback cb) { 12573 mCallback = cb; 12574 } 12575 setRadioScanningTimeoutLocked(long timeoutUs)12576 public void setRadioScanningTimeoutLocked(long timeoutUs) { 12577 if (mPhoneSignalScanningTimer != null) { 12578 mPhoneSignalScanningTimer.setTimeout(timeoutUs); 12579 } 12580 } 12581 setExternalStatsSyncLocked(ExternalStatsSync sync)12582 public void setExternalStatsSyncLocked(ExternalStatsSync sync) { 12583 mExternalSync = sync; 12584 } 12585 12586 /** 12587 * Initialize and set multi display timers and states. 12588 */ setDisplayCountLocked(int numDisplays)12589 public void setDisplayCountLocked(int numDisplays) { 12590 mPerDisplayBatteryStats = new DisplayBatteryStats[numDisplays]; 12591 for (int i = 0; i < numDisplays; i++) { 12592 mPerDisplayBatteryStats[i] = new DisplayBatteryStats(mClock, mOnBatteryTimeBase); 12593 } 12594 } 12595 updateDailyDeadlineLocked()12596 public void updateDailyDeadlineLocked() { 12597 // Get the current time. 12598 long currentTimeMs = mDailyStartTimeMs = mClock.currentTimeMillis(); 12599 Calendar calDeadline = Calendar.getInstance(); 12600 calDeadline.setTimeInMillis(currentTimeMs); 12601 12602 // Move time up to the next day, ranging from 1am to 3pm. 12603 calDeadline.set(Calendar.DAY_OF_YEAR, calDeadline.get(Calendar.DAY_OF_YEAR) + 1); 12604 calDeadline.set(Calendar.MILLISECOND, 0); 12605 calDeadline.set(Calendar.SECOND, 0); 12606 calDeadline.set(Calendar.MINUTE, 0); 12607 calDeadline.set(Calendar.HOUR_OF_DAY, 1); 12608 mNextMinDailyDeadlineMs = calDeadline.getTimeInMillis(); 12609 calDeadline.set(Calendar.HOUR_OF_DAY, 3); 12610 mNextMaxDailyDeadlineMs = calDeadline.getTimeInMillis(); 12611 } 12612 recordDailyStatsIfNeededLocked(boolean settled, long currentTimeMs)12613 public void recordDailyStatsIfNeededLocked(boolean settled, long currentTimeMs) { 12614 if (currentTimeMs >= mNextMaxDailyDeadlineMs) { 12615 recordDailyStatsLocked(); 12616 } else if (settled && currentTimeMs >= mNextMinDailyDeadlineMs) { 12617 recordDailyStatsLocked(); 12618 } else if (currentTimeMs < (mDailyStartTimeMs - (1000 * 60 * 60 * 24))) { 12619 recordDailyStatsLocked(); 12620 } 12621 } 12622 recordDailyStatsLocked()12623 public void recordDailyStatsLocked() { 12624 DailyItem item = new DailyItem(); 12625 item.mStartTime = mDailyStartTimeMs; 12626 item.mEndTime = mClock.currentTimeMillis(); 12627 boolean hasData = false; 12628 if (mDailyDischargeStepTracker.mNumStepDurations > 0) { 12629 hasData = true; 12630 item.mDischargeSteps = new LevelStepTracker( 12631 mDailyDischargeStepTracker.mNumStepDurations, 12632 mDailyDischargeStepTracker.mStepDurations); 12633 } 12634 if (mDailyChargeStepTracker.mNumStepDurations > 0) { 12635 hasData = true; 12636 item.mChargeSteps = new LevelStepTracker( 12637 mDailyChargeStepTracker.mNumStepDurations, 12638 mDailyChargeStepTracker.mStepDurations); 12639 } 12640 if (mDailyPackageChanges != null) { 12641 hasData = true; 12642 item.mPackageChanges = mDailyPackageChanges; 12643 mDailyPackageChanges = null; 12644 } 12645 mDailyDischargeStepTracker.init(); 12646 mDailyChargeStepTracker.init(); 12647 updateDailyDeadlineLocked(); 12648 12649 if (hasData) { 12650 final long startTimeMs = SystemClock.uptimeMillis(); 12651 mDailyItems.add(item); 12652 while (mDailyItems.size() > MAX_DAILY_ITEMS) { 12653 mDailyItems.remove(0); 12654 } 12655 final ByteArrayOutputStream memStream = new ByteArrayOutputStream(); 12656 try { 12657 TypedXmlSerializer out = Xml.resolveSerializer(memStream); 12658 writeDailyItemsLocked(out); 12659 final long initialTimeMs = SystemClock.uptimeMillis() - startTimeMs; 12660 BackgroundThread.getHandler().post(new Runnable() { 12661 @Override 12662 public void run() { 12663 synchronized (mCheckinFile) { 12664 final long startTimeMs2 = SystemClock.uptimeMillis(); 12665 FileOutputStream stream = null; 12666 try { 12667 stream = mDailyFile.startWrite(); 12668 memStream.writeTo(stream); 12669 stream.flush(); 12670 mDailyFile.finishWrite(stream); 12671 com.android.internal.logging.EventLogTags.writeCommitSysConfigFile( 12672 "batterystats-daily", 12673 initialTimeMs + SystemClock.uptimeMillis() - startTimeMs2); 12674 } catch (IOException e) { 12675 Slog.w("BatteryStats", 12676 "Error writing battery daily items", e); 12677 mDailyFile.failWrite(stream); 12678 } 12679 } 12680 } 12681 }); 12682 } catch (IOException e) { 12683 } 12684 } 12685 } 12686 writeDailyItemsLocked(TypedXmlSerializer out)12687 private void writeDailyItemsLocked(TypedXmlSerializer out) throws IOException { 12688 StringBuilder sb = new StringBuilder(64); 12689 out.startDocument(null, true); 12690 out.startTag(null, "daily-items"); 12691 for (int i=0; i<mDailyItems.size(); i++) { 12692 final DailyItem dit = mDailyItems.get(i); 12693 out.startTag(null, "item"); 12694 out.attributeLong(null, "start", dit.mStartTime); 12695 out.attributeLong(null, "end", dit.mEndTime); 12696 writeDailyLevelSteps(out, "dis", dit.mDischargeSteps, sb); 12697 writeDailyLevelSteps(out, "chg", dit.mChargeSteps, sb); 12698 if (dit.mPackageChanges != null) { 12699 for (int j=0; j<dit.mPackageChanges.size(); j++) { 12700 PackageChange pc = dit.mPackageChanges.get(j); 12701 if (pc.mUpdate) { 12702 out.startTag(null, "upd"); 12703 out.attribute(null, "pkg", pc.mPackageName); 12704 out.attributeLong(null, "ver", pc.mVersionCode); 12705 out.endTag(null, "upd"); 12706 } else { 12707 out.startTag(null, "rem"); 12708 out.attribute(null, "pkg", pc.mPackageName); 12709 out.endTag(null, "rem"); 12710 } 12711 } 12712 } 12713 out.endTag(null, "item"); 12714 } 12715 out.endTag(null, "daily-items"); 12716 out.endDocument(); 12717 } 12718 writeDailyLevelSteps(TypedXmlSerializer out, String tag, LevelStepTracker steps, StringBuilder tmpBuilder)12719 private void writeDailyLevelSteps(TypedXmlSerializer out, String tag, LevelStepTracker steps, 12720 StringBuilder tmpBuilder) throws IOException { 12721 if (steps != null) { 12722 out.startTag(null, tag); 12723 out.attributeInt(null, "n", steps.mNumStepDurations); 12724 for (int i=0; i<steps.mNumStepDurations; i++) { 12725 out.startTag(null, "s"); 12726 tmpBuilder.setLength(0); 12727 steps.encodeEntryAt(i, tmpBuilder); 12728 out.attribute(null, "v", tmpBuilder.toString()); 12729 out.endTag(null, "s"); 12730 } 12731 out.endTag(null, tag); 12732 } 12733 } 12734 12735 @GuardedBy("this") readDailyStatsLocked()12736 public void readDailyStatsLocked() { 12737 Slog.d(TAG, "Reading daily items from " + mDailyFile.getBaseFile()); 12738 mDailyItems.clear(); 12739 FileInputStream stream; 12740 try { 12741 stream = mDailyFile.openRead(); 12742 } catch (FileNotFoundException e) { 12743 return; 12744 } 12745 try { 12746 TypedXmlPullParser parser = Xml.resolvePullParser(stream); 12747 readDailyItemsLocked(parser); 12748 } catch (IOException e) { 12749 } finally { 12750 try { 12751 stream.close(); 12752 } catch (IOException e) { 12753 } 12754 } 12755 } 12756 readDailyItemsLocked(TypedXmlPullParser parser)12757 private void readDailyItemsLocked(TypedXmlPullParser parser) { 12758 try { 12759 int type; 12760 while ((type = parser.next()) != XmlPullParser.START_TAG 12761 && type != XmlPullParser.END_DOCUMENT) { 12762 ; 12763 } 12764 12765 if (type != XmlPullParser.START_TAG) { 12766 throw new IllegalStateException("no start tag found"); 12767 } 12768 12769 int outerDepth = parser.getDepth(); 12770 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 12771 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 12772 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 12773 continue; 12774 } 12775 12776 String tagName = parser.getName(); 12777 if (tagName.equals("item")) { 12778 readDailyItemTagLocked(parser); 12779 } else { 12780 Slog.w(TAG, "Unknown element under <daily-items>: " 12781 + parser.getName()); 12782 XmlUtils.skipCurrentTag(parser); 12783 } 12784 } 12785 12786 } catch (IllegalStateException e) { 12787 Slog.w(TAG, "Failed parsing daily " + e); 12788 } catch (NullPointerException e) { 12789 Slog.w(TAG, "Failed parsing daily " + e); 12790 } catch (NumberFormatException e) { 12791 Slog.w(TAG, "Failed parsing daily " + e); 12792 } catch (XmlPullParserException e) { 12793 Slog.w(TAG, "Failed parsing daily " + e); 12794 } catch (IOException e) { 12795 Slog.w(TAG, "Failed parsing daily " + e); 12796 } catch (IndexOutOfBoundsException e) { 12797 Slog.w(TAG, "Failed parsing daily " + e); 12798 } 12799 } 12800 readDailyItemTagLocked(TypedXmlPullParser parser)12801 void readDailyItemTagLocked(TypedXmlPullParser parser) throws NumberFormatException, 12802 XmlPullParserException, IOException { 12803 DailyItem dit = new DailyItem(); 12804 dit.mStartTime = parser.getAttributeLong(null, "start", 0); 12805 dit.mEndTime = parser.getAttributeLong(null, "end", 0); 12806 int outerDepth = parser.getDepth(); 12807 int type; 12808 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 12809 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 12810 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 12811 continue; 12812 } 12813 12814 String tagName = parser.getName(); 12815 if (tagName.equals("dis")) { 12816 readDailyItemTagDetailsLocked(parser, dit, false, "dis"); 12817 } else if (tagName.equals("chg")) { 12818 readDailyItemTagDetailsLocked(parser, dit, true, "chg"); 12819 } else if (tagName.equals("upd")) { 12820 if (dit.mPackageChanges == null) { 12821 dit.mPackageChanges = new ArrayList<>(); 12822 } 12823 PackageChange pc = new PackageChange(); 12824 pc.mUpdate = true; 12825 pc.mPackageName = parser.getAttributeValue(null, "pkg"); 12826 pc.mVersionCode = parser.getAttributeLong(null, "ver", 0); 12827 dit.mPackageChanges.add(pc); 12828 XmlUtils.skipCurrentTag(parser); 12829 } else if (tagName.equals("rem")) { 12830 if (dit.mPackageChanges == null) { 12831 dit.mPackageChanges = new ArrayList<>(); 12832 } 12833 PackageChange pc = new PackageChange(); 12834 pc.mUpdate = false; 12835 pc.mPackageName = parser.getAttributeValue(null, "pkg"); 12836 dit.mPackageChanges.add(pc); 12837 XmlUtils.skipCurrentTag(parser); 12838 } else { 12839 Slog.w(TAG, "Unknown element under <item>: " 12840 + parser.getName()); 12841 XmlUtils.skipCurrentTag(parser); 12842 } 12843 } 12844 mDailyItems.add(dit); 12845 } 12846 readDailyItemTagDetailsLocked(TypedXmlPullParser parser, DailyItem dit, boolean isCharge, String tag)12847 void readDailyItemTagDetailsLocked(TypedXmlPullParser parser, DailyItem dit, boolean isCharge, 12848 String tag) 12849 throws NumberFormatException, XmlPullParserException, IOException { 12850 final int num = parser.getAttributeInt(null, "n", -1); 12851 if (num == -1) { 12852 Slog.w(TAG, "Missing 'n' attribute at " + parser.getPositionDescription()); 12853 XmlUtils.skipCurrentTag(parser); 12854 return; 12855 } 12856 LevelStepTracker steps = new LevelStepTracker(num); 12857 if (isCharge) { 12858 dit.mChargeSteps = steps; 12859 } else { 12860 dit.mDischargeSteps = steps; 12861 } 12862 int i = 0; 12863 int outerDepth = parser.getDepth(); 12864 int type; 12865 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 12866 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 12867 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 12868 continue; 12869 } 12870 12871 String tagName = parser.getName(); 12872 if ("s".equals(tagName)) { 12873 if (i < num) { 12874 String valueAttr = parser.getAttributeValue(null, "v"); 12875 if (valueAttr != null) { 12876 steps.decodeEntryAt(i, valueAttr); 12877 i++; 12878 } 12879 } 12880 } else { 12881 Slog.w(TAG, "Unknown element under <" + tag + ">: " 12882 + parser.getName()); 12883 XmlUtils.skipCurrentTag(parser); 12884 } 12885 } 12886 steps.mNumStepDurations = i; 12887 } 12888 12889 @Override getDailyItemLocked(int daysAgo)12890 public DailyItem getDailyItemLocked(int daysAgo) { 12891 int index = mDailyItems.size()-1-daysAgo; 12892 return index >= 0 ? mDailyItems.get(index) : null; 12893 } 12894 12895 @Override getCurrentDailyStartTime()12896 public long getCurrentDailyStartTime() { 12897 return mDailyStartTimeMs; 12898 } 12899 12900 @Override getNextMinDailyDeadline()12901 public long getNextMinDailyDeadline() { 12902 return mNextMinDailyDeadlineMs; 12903 } 12904 12905 @Override getNextMaxDailyDeadline()12906 public long getNextMaxDailyDeadline() { 12907 return mNextMaxDailyDeadlineMs; 12908 } 12909 12910 @GuardedBy("this") getHistoryTotalSize()12911 public int getHistoryTotalSize() { 12912 return mConstants.MAX_HISTORY_BUFFER * mConstants.MAX_HISTORY_FILES; 12913 } 12914 getHistoryUsedSize()12915 public int getHistoryUsedSize() { 12916 return mBatteryStatsHistory.getHistoryUsedSize(); 12917 } 12918 12919 @Override 12920 @UnsupportedAppUsage startIteratingHistoryLocked()12921 public boolean startIteratingHistoryLocked() { 12922 mBatteryStatsHistoryIterator = createBatteryStatsHistoryIterator(); 12923 return true; 12924 } 12925 12926 /** 12927 * Creates an iterator for battery stats history. 12928 */ 12929 @VisibleForTesting createBatteryStatsHistoryIterator()12930 public BatteryStatsHistoryIterator createBatteryStatsHistoryIterator() { 12931 return new BatteryStatsHistoryIterator(mBatteryStatsHistory); 12932 } 12933 12934 @Override getHistoryStringPoolSize()12935 public int getHistoryStringPoolSize() { 12936 return mHistoryTagPool.size(); 12937 } 12938 12939 @Override getHistoryStringPoolBytes()12940 public int getHistoryStringPoolBytes() { 12941 return mNumHistoryTagChars; 12942 } 12943 12944 @Override getHistoryTagPoolString(int index)12945 public String getHistoryTagPoolString(int index) { 12946 ensureHistoryTagArray(); 12947 HistoryTag historyTag = mHistoryTags.get(index); 12948 return historyTag != null ? historyTag.string : null; 12949 } 12950 12951 @Override getHistoryTagPoolUid(int index)12952 public int getHistoryTagPoolUid(int index) { 12953 ensureHistoryTagArray(); 12954 HistoryTag historyTag = mHistoryTags.get(index); 12955 return historyTag != null ? historyTag.uid : Process.INVALID_UID; 12956 } 12957 ensureHistoryTagArray()12958 private void ensureHistoryTagArray() { 12959 if (mHistoryTags != null) { 12960 return; 12961 } 12962 12963 mHistoryTags = new SparseArray<>(mHistoryTagPool.size()); 12964 for (Map.Entry<HistoryTag, Integer> entry: mHistoryTagPool.entrySet()) { 12965 mHistoryTags.put(entry.getValue() & ~TAG_FIRST_OCCURRENCE_FLAG, entry.getKey()); 12966 } 12967 } 12968 12969 @Override 12970 @UnsupportedAppUsage getNextHistoryLocked(HistoryItem out)12971 public boolean getNextHistoryLocked(HistoryItem out) { 12972 return mBatteryStatsHistoryIterator.next(out); 12973 } 12974 12975 @Override finishIteratingHistoryLocked()12976 public void finishIteratingHistoryLocked() { 12977 mBatteryStatsHistoryIterator = null; 12978 } 12979 12980 @Override getHistoryBaseTime()12981 public long getHistoryBaseTime() { 12982 return mHistoryBaseTimeMs; 12983 } 12984 12985 @Override getStartCount()12986 public int getStartCount() { 12987 return mStartCount; 12988 } 12989 12990 @UnsupportedAppUsage isOnBattery()12991 public boolean isOnBattery() { 12992 return mOnBattery; 12993 } 12994 isCharging()12995 public boolean isCharging() { 12996 return mCharging; 12997 } 12998 initTimes(long uptimeUs, long realtimeUs)12999 void initTimes(long uptimeUs, long realtimeUs) { 13000 mStartClockTimeMs = mClock.currentTimeMillis(); 13001 mOnBatteryTimeBase.init(uptimeUs, realtimeUs); 13002 mOnBatteryScreenOffTimeBase.init(uptimeUs, realtimeUs); 13003 mRealtimeUs = 0; 13004 mUptimeUs = 0; 13005 mRealtimeStartUs = realtimeUs; 13006 mUptimeStartUs = uptimeUs; 13007 } 13008 initDischarge(long elapsedRealtimeUs)13009 void initDischarge(long elapsedRealtimeUs) { 13010 mLowDischargeAmountSinceCharge = 0; 13011 mHighDischargeAmountSinceCharge = 0; 13012 mDischargeAmountScreenOn = 0; 13013 mDischargeAmountScreenOnSinceCharge = 0; 13014 mDischargeAmountScreenOff = 0; 13015 mDischargeAmountScreenOffSinceCharge = 0; 13016 mDischargeAmountScreenDoze = 0; 13017 mDischargeAmountScreenDozeSinceCharge = 0; 13018 mDischargeStepTracker.init(); 13019 mChargeStepTracker.init(); 13020 mDischargeScreenOffCounter.reset(false, elapsedRealtimeUs); 13021 mDischargeScreenDozeCounter.reset(false, elapsedRealtimeUs); 13022 mDischargeLightDozeCounter.reset(false, elapsedRealtimeUs); 13023 mDischargeDeepDozeCounter.reset(false, elapsedRealtimeUs); 13024 mDischargeCounter.reset(false, elapsedRealtimeUs); 13025 } 13026 setBatteryResetListener(BatteryResetListener batteryResetListener)13027 public void setBatteryResetListener(BatteryResetListener batteryResetListener) { 13028 mBatteryResetListener = batteryResetListener; 13029 } 13030 13031 @GuardedBy("this") resetAllStatsCmdLocked()13032 public void resetAllStatsCmdLocked() { 13033 final long mSecUptime = mClock.uptimeMillis(); 13034 long uptimeUs = mSecUptime * 1000; 13035 long mSecRealtime = mClock.elapsedRealtime(); 13036 long realtimeUs = mSecRealtime * 1000; 13037 resetAllStatsLocked(mSecUptime, mSecRealtime, RESET_REASON_ADB_COMMAND); 13038 mDischargeStartLevel = mHistoryCur.batteryLevel; 13039 pullPendingStateUpdatesLocked(); 13040 addHistoryRecordLocked(mSecRealtime, mSecUptime); 13041 mDischargeCurrentLevel = mDischargeUnplugLevel = mDischargePlugLevel 13042 = mCurrentBatteryLevel = mHistoryCur.batteryLevel; 13043 mOnBatteryTimeBase.reset(uptimeUs, realtimeUs); 13044 mOnBatteryScreenOffTimeBase.reset(uptimeUs, realtimeUs); 13045 if ((mHistoryCur.states&HistoryItem.STATE_BATTERY_PLUGGED_FLAG) == 0) { 13046 if (Display.isOnState(mScreenState)) { 13047 mDischargeScreenOnUnplugLevel = mHistoryCur.batteryLevel; 13048 mDischargeScreenDozeUnplugLevel = 0; 13049 mDischargeScreenOffUnplugLevel = 0; 13050 } else if (Display.isDozeState(mScreenState)) { 13051 mDischargeScreenOnUnplugLevel = 0; 13052 mDischargeScreenDozeUnplugLevel = mHistoryCur.batteryLevel; 13053 mDischargeScreenOffUnplugLevel = 0; 13054 } else { 13055 mDischargeScreenOnUnplugLevel = 0; 13056 mDischargeScreenDozeUnplugLevel = 0; 13057 mDischargeScreenOffUnplugLevel = mHistoryCur.batteryLevel; 13058 } 13059 mDischargeAmountScreenOn = 0; 13060 mDischargeAmountScreenOff = 0; 13061 mDischargeAmountScreenDoze = 0; 13062 } 13063 initActiveHistoryEventsLocked(mSecRealtime, mSecUptime); 13064 } 13065 13066 @GuardedBy("this") resetAllStatsLocked(long uptimeMillis, long elapsedRealtimeMillis, int resetReason)13067 private void resetAllStatsLocked(long uptimeMillis, long elapsedRealtimeMillis, 13068 int resetReason) { 13069 if (mBatteryResetListener != null) { 13070 mBatteryResetListener.prepareForBatteryStatsReset(resetReason); 13071 } 13072 13073 final long uptimeUs = uptimeMillis * 1000; 13074 final long elapsedRealtimeUs = elapsedRealtimeMillis * 1000; 13075 mStartCount = 0; 13076 initTimes(uptimeUs, elapsedRealtimeUs); 13077 mScreenOnTimer.reset(false, elapsedRealtimeUs); 13078 mScreenDozeTimer.reset(false, elapsedRealtimeUs); 13079 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 13080 mScreenBrightnessTimer[i].reset(false, elapsedRealtimeUs); 13081 } 13082 13083 final int numDisplays = mPerDisplayBatteryStats.length; 13084 for (int i = 0; i < numDisplays; i++) { 13085 mPerDisplayBatteryStats[i].reset(elapsedRealtimeUs); 13086 } 13087 13088 if (mPowerProfile != null) { 13089 mEstimatedBatteryCapacityMah = (int) mPowerProfile.getBatteryCapacity(); 13090 } else { 13091 mEstimatedBatteryCapacityMah = -1; 13092 } 13093 mLastLearnedBatteryCapacityUah = -1; 13094 mMinLearnedBatteryCapacityUah = -1; 13095 mMaxLearnedBatteryCapacityUah = -1; 13096 mInteractiveTimer.reset(false, elapsedRealtimeUs); 13097 mPowerSaveModeEnabledTimer.reset(false, elapsedRealtimeUs); 13098 mLastIdleTimeStartMs = elapsedRealtimeMillis; 13099 mLongestLightIdleTimeMs = 0; 13100 mLongestFullIdleTimeMs = 0; 13101 mDeviceIdleModeLightTimer.reset(false, elapsedRealtimeUs); 13102 mDeviceIdleModeFullTimer.reset(false, elapsedRealtimeUs); 13103 mDeviceLightIdlingTimer.reset(false, elapsedRealtimeUs); 13104 mDeviceIdlingTimer.reset(false, elapsedRealtimeUs); 13105 mPhoneOnTimer.reset(false, elapsedRealtimeUs); 13106 mAudioOnTimer.reset(false, elapsedRealtimeUs); 13107 mVideoOnTimer.reset(false, elapsedRealtimeUs); 13108 mFlashlightOnTimer.reset(false, elapsedRealtimeUs); 13109 mCameraOnTimer.reset(false, elapsedRealtimeUs); 13110 mBluetoothScanTimer.reset(false, elapsedRealtimeUs); 13111 for (int i = 0; i < CellSignalStrength.getNumSignalStrengthLevels(); i++) { 13112 mPhoneSignalStrengthsTimer[i].reset(false, elapsedRealtimeUs); 13113 } 13114 mPhoneSignalScanningTimer.reset(false, elapsedRealtimeUs); 13115 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 13116 mPhoneDataConnectionsTimer[i].reset(false, elapsedRealtimeUs); 13117 } 13118 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 13119 mNetworkByteActivityCounters[i].reset(false, elapsedRealtimeUs); 13120 mNetworkPacketActivityCounters[i].reset(false, elapsedRealtimeUs); 13121 } 13122 for (int i = 0; i < RADIO_ACCESS_TECHNOLOGY_COUNT; i++) { 13123 final RadioAccessTechnologyBatteryStats stats = mPerRatBatteryStats[i]; 13124 if (stats == null) continue; 13125 stats.reset(elapsedRealtimeUs); 13126 } 13127 mMobileRadioActiveTimer.reset(false, elapsedRealtimeUs); 13128 mMobileRadioActivePerAppTimer.reset(false, elapsedRealtimeUs); 13129 mMobileRadioActiveAdjustedTime.reset(false, elapsedRealtimeUs); 13130 mMobileRadioActiveUnknownTime.reset(false, elapsedRealtimeUs); 13131 mMobileRadioActiveUnknownCount.reset(false, elapsedRealtimeUs); 13132 mWifiOnTimer.reset(false, elapsedRealtimeUs); 13133 mGlobalWifiRunningTimer.reset(false, elapsedRealtimeUs); 13134 for (int i=0; i<NUM_WIFI_STATES; i++) { 13135 mWifiStateTimer[i].reset(false, elapsedRealtimeUs); 13136 } 13137 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) { 13138 mWifiSupplStateTimer[i].reset(false, elapsedRealtimeUs); 13139 } 13140 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { 13141 mWifiSignalStrengthsTimer[i].reset(false, elapsedRealtimeUs); 13142 } 13143 mWifiMulticastWakelockTimer.reset(false, elapsedRealtimeUs); 13144 mWifiActiveTimer.reset(false, elapsedRealtimeUs); 13145 mWifiActivity.reset(false, elapsedRealtimeUs); 13146 for (int i=0; i< mGpsSignalQualityTimer.length; i++) { 13147 mGpsSignalQualityTimer[i].reset(false, elapsedRealtimeUs); 13148 } 13149 mBluetoothActivity.reset(false, elapsedRealtimeUs); 13150 mModemActivity.reset(false, elapsedRealtimeUs); 13151 mNumConnectivityChange = 0; 13152 13153 for (int i=0; i<mUidStats.size(); i++) { 13154 if (mUidStats.valueAt(i).reset(uptimeUs, elapsedRealtimeUs, resetReason)) { 13155 mUidStats.valueAt(i).detachFromTimeBase(); 13156 mUidStats.remove(mUidStats.keyAt(i)); 13157 i--; 13158 } 13159 } 13160 13161 if (mRpmStats.size() > 0) { 13162 for (SamplingTimer timer : mRpmStats.values()) { 13163 mOnBatteryTimeBase.remove(timer); 13164 } 13165 mRpmStats.clear(); 13166 } 13167 if (mScreenOffRpmStats.size() > 0) { 13168 for (SamplingTimer timer : mScreenOffRpmStats.values()) { 13169 mOnBatteryScreenOffTimeBase.remove(timer); 13170 } 13171 mScreenOffRpmStats.clear(); 13172 } 13173 13174 if (mKernelWakelockStats.size() > 0) { 13175 for (SamplingTimer timer : mKernelWakelockStats.values()) { 13176 mOnBatteryScreenOffTimeBase.remove(timer); 13177 } 13178 mKernelWakelockStats.clear(); 13179 } 13180 13181 if (mKernelMemoryStats.size() > 0) { 13182 for (int i = 0; i < mKernelMemoryStats.size(); i++) { 13183 mOnBatteryTimeBase.remove(mKernelMemoryStats.valueAt(i)); 13184 } 13185 mKernelMemoryStats.clear(); 13186 } 13187 13188 if (mWakeupReasonStats.size() > 0) { 13189 for (SamplingTimer timer : mWakeupReasonStats.values()) { 13190 mOnBatteryTimeBase.remove(timer); 13191 } 13192 mWakeupReasonStats.clear(); 13193 } 13194 13195 mTmpRailStats.reset(); 13196 13197 MeasuredEnergyStats.resetIfNotNull(mGlobalMeasuredEnergyStats); 13198 13199 resetIfNotNull(mBinderThreadCpuTimesUs, false, elapsedRealtimeUs); 13200 13201 mLastHistoryStepDetails = null; 13202 mLastStepCpuUserTimeMs = mLastStepCpuSystemTimeMs = 0; 13203 mCurStepCpuUserTimeMs = mCurStepCpuSystemTimeMs = 0; 13204 mLastStepCpuUserTimeMs = mCurStepCpuUserTimeMs = 0; 13205 mLastStepCpuSystemTimeMs = mCurStepCpuSystemTimeMs = 0; 13206 mLastStepStatUserTimeMs = mCurStepStatUserTimeMs = 0; 13207 mLastStepStatSystemTimeMs = mCurStepStatSystemTimeMs = 0; 13208 mLastStepStatIOWaitTimeMs = mCurStepStatIOWaitTimeMs = 0; 13209 mLastStepStatIrqTimeMs = mCurStepStatIrqTimeMs = 0; 13210 mLastStepStatSoftIrqTimeMs = mCurStepStatSoftIrqTimeMs = 0; 13211 mLastStepStatIdleTimeMs = mCurStepStatIdleTimeMs = 0; 13212 13213 mNumAllUidCpuTimeReads = 0; 13214 mNumUidsRemoved = 0; 13215 13216 initDischarge(elapsedRealtimeUs); 13217 13218 clearHistoryLocked(); 13219 if (mBatteryStatsHistory != null) { 13220 mBatteryStatsHistory.resetAllFiles(); 13221 } 13222 13223 // Flush external data, gathering snapshots, but don't process it since it is pre-reset data 13224 mIgnoreNextExternalStats = true; 13225 mExternalSync.scheduleSync("reset", ExternalStatsSync.UPDATE_ON_RESET); 13226 13227 mHandler.sendEmptyMessage(MSG_REPORT_RESET_STATS); 13228 } 13229 13230 @GuardedBy("this") initActiveHistoryEventsLocked(long elapsedRealtimeMs, long uptimeMs)13231 private void initActiveHistoryEventsLocked(long elapsedRealtimeMs, long uptimeMs) { 13232 for (int i=0; i<HistoryItem.EVENT_COUNT; i++) { 13233 if (!mRecordAllHistory && i == HistoryItem.EVENT_PROC) { 13234 // Not recording process starts/stops. 13235 continue; 13236 } 13237 HashMap<String, SparseIntArray> active = mActiveEvents.getStateForEvent(i); 13238 if (active == null) { 13239 continue; 13240 } 13241 for (HashMap.Entry<String, SparseIntArray> ent : active.entrySet()) { 13242 SparseIntArray uids = ent.getValue(); 13243 for (int j=0; j<uids.size(); j++) { 13244 addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, i, ent.getKey(), 13245 uids.keyAt(j)); 13246 } 13247 } 13248 } 13249 } 13250 13251 @GuardedBy("this") updateDischargeScreenLevelsLocked(int oldState, int newState)13252 void updateDischargeScreenLevelsLocked(int oldState, int newState) { 13253 updateOldDischargeScreenLevelLocked(oldState); 13254 updateNewDischargeScreenLevelLocked(newState); 13255 } 13256 13257 @GuardedBy("this") updateOldDischargeScreenLevelLocked(int state)13258 private void updateOldDischargeScreenLevelLocked(int state) { 13259 if (Display.isOnState(state)) { 13260 int diff = mDischargeScreenOnUnplugLevel - mDischargeCurrentLevel; 13261 if (diff > 0) { 13262 mDischargeAmountScreenOn += diff; 13263 mDischargeAmountScreenOnSinceCharge += diff; 13264 } 13265 } else if (Display.isDozeState(state)) { 13266 int diff = mDischargeScreenDozeUnplugLevel - mDischargeCurrentLevel; 13267 if (diff > 0) { 13268 mDischargeAmountScreenDoze += diff; 13269 mDischargeAmountScreenDozeSinceCharge += diff; 13270 } 13271 } else if (Display.isOffState(state)) { 13272 int diff = mDischargeScreenOffUnplugLevel - mDischargeCurrentLevel; 13273 if (diff > 0) { 13274 mDischargeAmountScreenOff += diff; 13275 mDischargeAmountScreenOffSinceCharge += diff; 13276 } 13277 } 13278 } 13279 13280 @GuardedBy("this") updateNewDischargeScreenLevelLocked(int state)13281 private void updateNewDischargeScreenLevelLocked(int state) { 13282 if (Display.isOnState(state)) { 13283 mDischargeScreenOnUnplugLevel = mDischargeCurrentLevel; 13284 mDischargeScreenOffUnplugLevel = 0; 13285 mDischargeScreenDozeUnplugLevel = 0; 13286 } else if (Display.isDozeState(state)) { 13287 mDischargeScreenOnUnplugLevel = 0; 13288 mDischargeScreenDozeUnplugLevel = mDischargeCurrentLevel; 13289 mDischargeScreenOffUnplugLevel = 0; 13290 } else if (Display.isOffState(state)) { 13291 mDischargeScreenOnUnplugLevel = 0; 13292 mDischargeScreenDozeUnplugLevel = 0; 13293 mDischargeScreenOffUnplugLevel = mDischargeCurrentLevel; 13294 } 13295 } 13296 13297 @GuardedBy("this") pullPendingStateUpdatesLocked()13298 public void pullPendingStateUpdatesLocked() { 13299 if (mOnBatteryInternal) { 13300 updateDischargeScreenLevelsLocked(mScreenState, mScreenState); 13301 } 13302 } 13303 13304 private final Object mWifiNetworkLock = new Object(); 13305 13306 @GuardedBy("mWifiNetworkLock") 13307 private String[] mWifiIfaces = EmptyArray.STRING; 13308 13309 @GuardedBy("mWifiNetworkLock") 13310 private NetworkStats mLastWifiNetworkStats = new NetworkStats(0, -1); 13311 13312 private final Object mModemNetworkLock = new Object(); 13313 13314 @GuardedBy("mModemNetworkLock") 13315 private String[] mModemIfaces = EmptyArray.STRING; 13316 13317 @GuardedBy("mModemNetworkLock") 13318 private NetworkStats mLastModemNetworkStats = new NetworkStats(0, -1); 13319 13320 @VisibleForTesting readMobileNetworkStatsLocked( @onNull NetworkStatsManager networkStatsManager)13321 protected NetworkStats readMobileNetworkStatsLocked( 13322 @NonNull NetworkStatsManager networkStatsManager) { 13323 return networkStatsManager.getMobileUidStats(); 13324 } 13325 13326 @VisibleForTesting readWifiNetworkStatsLocked( @onNull NetworkStatsManager networkStatsManager)13327 protected NetworkStats readWifiNetworkStatsLocked( 13328 @NonNull NetworkStatsManager networkStatsManager) { 13329 return networkStatsManager.getWifiUidStats(); 13330 } 13331 13332 /** 13333 * Distribute WiFi energy info and network traffic to apps. 13334 * @param info The energy information from the WiFi controller. 13335 */ 13336 @GuardedBy("this") updateWifiState(@ullable final WifiActivityEnergyInfo info, final long consumedChargeUC, long elapsedRealtimeMs, long uptimeMs, @NonNull NetworkStatsManager networkStatsManager)13337 public void updateWifiState(@Nullable final WifiActivityEnergyInfo info, 13338 final long consumedChargeUC, long elapsedRealtimeMs, long uptimeMs, 13339 @NonNull NetworkStatsManager networkStatsManager) { 13340 if (DEBUG_ENERGY) { 13341 synchronized (mWifiNetworkLock) { 13342 Slog.d(TAG, "Updating wifi stats: " + Arrays.toString(mWifiIfaces)); 13343 } 13344 } 13345 13346 // Grab a separate lock to acquire the network stats, which may do I/O. 13347 NetworkStats delta = null; 13348 synchronized (mWifiNetworkLock) { 13349 final NetworkStats latestStats = readWifiNetworkStatsLocked(networkStatsManager); 13350 if (latestStats != null) { 13351 delta = latestStats.subtract(mLastWifiNetworkStats); 13352 mLastWifiNetworkStats = latestStats; 13353 } 13354 } 13355 13356 synchronized (this) { 13357 if (!mOnBatteryInternal || mIgnoreNextExternalStats) { 13358 if (mIgnoreNextExternalStats) { 13359 // TODO: Strictly speaking, we should re-mark all 5 timers for each uid (and the 13360 // global one) here like we do for display. But I'm not sure it's worth the 13361 // complicated code for a codepath that shouldn't ever actually happen in real 13362 // life. 13363 } 13364 return; 13365 } 13366 13367 final SparseDoubleArray uidEstimatedConsumptionMah = 13368 (mGlobalMeasuredEnergyStats != null 13369 && mWifiPowerCalculator != null && consumedChargeUC > 0) ? 13370 new SparseDoubleArray() : null; 13371 double totalEstimatedConsumptionMah = 0; 13372 13373 SparseLongArray rxPackets = new SparseLongArray(); 13374 SparseLongArray txPackets = new SparseLongArray(); 13375 SparseLongArray rxTimesMs = new SparseLongArray(); 13376 SparseLongArray txTimesMs = new SparseLongArray(); 13377 long totalTxPackets = 0; 13378 long totalRxPackets = 0; 13379 if (delta != null) { 13380 for (NetworkStats.Entry entry : delta) { 13381 if (DEBUG_ENERGY) { 13382 Slog.d(TAG, "Wifi uid " + entry.getUid() 13383 + ": delta rx=" + entry.getRxBytes() 13384 + " tx=" + entry.getTxBytes() 13385 + " rxPackets=" + entry.getRxPackets() 13386 + " txPackets=" + entry.getTxPackets()); 13387 } 13388 13389 if (entry.getRxBytes() == 0 && entry.getTxBytes() == 0) { 13390 // Skip the lookup below since there is no work to do. 13391 continue; 13392 } 13393 13394 final int uid = mapUid(entry.getUid()); 13395 final Uid u = getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs); 13396 if (entry.getRxBytes() != 0) { 13397 u.noteNetworkActivityLocked(NETWORK_WIFI_RX_DATA, entry.getRxBytes(), 13398 entry.getRxPackets()); 13399 if (entry.getSet() == NetworkStats.SET_DEFAULT) { // Background transfers 13400 u.noteNetworkActivityLocked(NETWORK_WIFI_BG_RX_DATA, entry.getRxBytes(), 13401 entry.getRxPackets()); 13402 } 13403 mNetworkByteActivityCounters[NETWORK_WIFI_RX_DATA].addCountLocked( 13404 entry.getRxBytes()); 13405 mNetworkPacketActivityCounters[NETWORK_WIFI_RX_DATA].addCountLocked( 13406 entry.getRxPackets()); 13407 13408 rxPackets.incrementValue(uid, entry.getRxPackets()); 13409 13410 // Sum the total number of packets so that the Rx Power can 13411 // be evenly distributed amongst the apps. 13412 totalRxPackets += entry.getRxPackets(); 13413 } 13414 13415 if (entry.getTxBytes() != 0) { 13416 u.noteNetworkActivityLocked(NETWORK_WIFI_TX_DATA, entry.getTxBytes(), 13417 entry.getTxPackets()); 13418 if (entry.getSet() == NetworkStats.SET_DEFAULT) { // Background transfers 13419 u.noteNetworkActivityLocked(NETWORK_WIFI_BG_TX_DATA, entry.getTxBytes(), 13420 entry.getTxPackets()); 13421 } 13422 mNetworkByteActivityCounters[NETWORK_WIFI_TX_DATA].addCountLocked( 13423 entry.getTxBytes()); 13424 mNetworkPacketActivityCounters[NETWORK_WIFI_TX_DATA].addCountLocked( 13425 entry.getTxPackets()); 13426 13427 txPackets.incrementValue(uid, entry.getTxPackets()); 13428 13429 // Sum the total number of packets so that the Tx Power can 13430 // be evenly distributed amongst the apps. 13431 totalTxPackets += entry.getTxPackets(); 13432 } 13433 13434 // Calculate consumed energy for this uid. Only do so if WifiReporting isn't 13435 // enabled (if it is, we'll do it later instead using info). 13436 if (uidEstimatedConsumptionMah != null && info == null && !mHasWifiReporting) { 13437 final long uidRunningMs = u.mWifiRunningTimer 13438 .getTimeSinceMarkLocked(elapsedRealtimeMs * 1000) / 1000; 13439 if (uidRunningMs > 0) u.mWifiRunningTimer.setMark(elapsedRealtimeMs); 13440 13441 final long uidScanMs = u.mWifiScanTimer 13442 .getTimeSinceMarkLocked(elapsedRealtimeMs * 1000) / 1000; 13443 if (uidScanMs > 0) u.mWifiScanTimer.setMark(elapsedRealtimeMs); 13444 13445 long uidBatchScanMs = 0; 13446 for (int bn = 0; bn < BatteryStats.Uid.NUM_WIFI_BATCHED_SCAN_BINS; bn++) { 13447 if (u.mWifiBatchedScanTimer[bn] != null) { 13448 long bnMs = u.mWifiBatchedScanTimer[bn] 13449 .getTimeSinceMarkLocked(elapsedRealtimeMs * 1000) / 1000; 13450 if (bnMs > 0) { 13451 u.mWifiBatchedScanTimer[bn].setMark(elapsedRealtimeMs); 13452 } 13453 uidBatchScanMs += bnMs; 13454 } 13455 } 13456 13457 uidEstimatedConsumptionMah.incrementValue(u.getUid(), 13458 mWifiPowerCalculator.calcPowerWithoutControllerDataMah( 13459 entry.getRxPackets(), entry.getTxPackets(), 13460 uidRunningMs, uidScanMs, uidBatchScanMs)); 13461 } 13462 } 13463 delta = null; 13464 } 13465 13466 if (info != null) { 13467 mHasWifiReporting = true; 13468 13469 // Measured in mAms 13470 final long txTimeMs = info.getControllerTxDurationMillis(); 13471 final long rxTimeMs = info.getControllerRxDurationMillis(); 13472 final long scanTimeMs = info.getControllerScanDurationMillis(); 13473 final long idleTimeMs = info.getControllerIdleDurationMillis(); 13474 final long totalTimeMs = txTimeMs + rxTimeMs + idleTimeMs; 13475 13476 long leftOverRxTimeMs = rxTimeMs; 13477 long leftOverTxTimeMs = txTimeMs; 13478 13479 if (DEBUG_ENERGY) { 13480 Slog.d(TAG, "------ BEGIN WiFi power blaming ------"); 13481 Slog.d(TAG, " Tx Time: " + txTimeMs + " ms"); 13482 Slog.d(TAG, " Rx Time: " + rxTimeMs + " ms"); 13483 Slog.d(TAG, " Idle Time: " + idleTimeMs + " ms"); 13484 Slog.d(TAG, " Total Time: " + totalTimeMs + " ms"); 13485 Slog.d(TAG, " Scan Time: " + scanTimeMs + " ms"); 13486 } 13487 13488 long totalWifiLockTimeMs = 0; 13489 long totalScanTimeMs = 0; 13490 13491 // On the first pass, collect some totals so that we can normalize power 13492 // calculations if we need to. 13493 final int uidStatsSize = mUidStats.size(); 13494 for (int i = 0; i < uidStatsSize; i++) { 13495 final Uid uid = mUidStats.valueAt(i); 13496 13497 // Sum the total scan power for all apps. 13498 totalScanTimeMs += uid.mWifiScanTimer.getTimeSinceMarkLocked( 13499 elapsedRealtimeMs * 1000) / 1000; 13500 13501 // Sum the total time holding wifi lock for all apps. 13502 totalWifiLockTimeMs += uid.mFullWifiLockTimer.getTimeSinceMarkLocked( 13503 elapsedRealtimeMs * 1000) / 1000; 13504 } 13505 13506 if (DEBUG_ENERGY && totalScanTimeMs > rxTimeMs) { 13507 Slog.d(TAG, 13508 " !Estimated scan time > Actual rx time (" + totalScanTimeMs + " ms > " 13509 + rxTimeMs + " ms). Normalizing scan time."); 13510 } 13511 if (DEBUG_ENERGY && totalScanTimeMs > txTimeMs) { 13512 Slog.d(TAG, 13513 " !Estimated scan time > Actual tx time (" + totalScanTimeMs + " ms > " 13514 + txTimeMs + " ms). Normalizing scan time."); 13515 } 13516 13517 // Actually assign and distribute power usage to apps. 13518 for (int i = 0; i < uidStatsSize; i++) { 13519 final Uid uid = mUidStats.valueAt(i); 13520 13521 final long scanTimeSinceMarkMs = uid.mWifiScanTimer.getTimeSinceMarkLocked( 13522 elapsedRealtimeMs * 1000) / 1000; 13523 long scanRxTimeSinceMarkMs = scanTimeSinceMarkMs; // not final 13524 long scanTxTimeSinceMarkMs = scanTimeSinceMarkMs; // not final 13525 if (scanTimeSinceMarkMs > 0) { 13526 // Set the new mark so that next time we get new data since this point. 13527 uid.mWifiScanTimer.setMark(elapsedRealtimeMs); 13528 13529 // Our total scan time is more than the reported Tx/Rx time. 13530 // This is possible because the cost of a scan is approximate. 13531 // Let's normalize the result so that we evenly blame each app 13532 // scanning. 13533 // 13534 // This means that we may have apps that transmitted/received packets not be 13535 // blamed for this, but this is fine as scans are relatively more expensive. 13536 if (totalScanTimeMs > rxTimeMs) { 13537 scanRxTimeSinceMarkMs = (rxTimeMs * scanRxTimeSinceMarkMs) / 13538 totalScanTimeMs; 13539 } 13540 if (totalScanTimeMs > txTimeMs) { 13541 scanTxTimeSinceMarkMs = (txTimeMs * scanTxTimeSinceMarkMs) / 13542 totalScanTimeMs; 13543 } 13544 13545 if (DEBUG_ENERGY) { 13546 Slog.d(TAG, " ScanTime for UID " + uid.getUid() + ": Rx:" 13547 + scanRxTimeSinceMarkMs + " ms Tx:" 13548 + scanTxTimeSinceMarkMs + " ms)"); 13549 } 13550 13551 rxTimesMs.incrementValue(uid.getUid(), scanRxTimeSinceMarkMs); 13552 txTimesMs.incrementValue(uid.getUid(), scanTxTimeSinceMarkMs); 13553 13554 leftOverRxTimeMs -= scanRxTimeSinceMarkMs; 13555 leftOverTxTimeMs -= scanTxTimeSinceMarkMs; 13556 } 13557 13558 // Distribute evenly the power consumed while Idle to each app holding a WiFi 13559 // lock. 13560 long myIdleTimeMs = 0; 13561 final long wifiLockTimeSinceMarkMs = 13562 uid.mFullWifiLockTimer.getTimeSinceMarkLocked( 13563 elapsedRealtimeMs * 1000) / 1000; 13564 if (wifiLockTimeSinceMarkMs > 0) { 13565 // Set the new mark so that next time we get new data since this point. 13566 uid.mFullWifiLockTimer.setMark(elapsedRealtimeMs); 13567 13568 myIdleTimeMs = (wifiLockTimeSinceMarkMs * idleTimeMs) / totalWifiLockTimeMs; 13569 if (DEBUG_ENERGY) { 13570 Slog.d(TAG, " IdleTime for UID " + uid.getUid() + ": " 13571 + myIdleTimeMs + " ms"); 13572 } 13573 uid.getOrCreateWifiControllerActivityLocked().getOrCreateIdleTimeCounter() 13574 .increment(myIdleTimeMs, elapsedRealtimeMs); 13575 } 13576 13577 if (uidEstimatedConsumptionMah != null) { 13578 double uidEstMah = mWifiPowerCalculator.calcPowerFromControllerDataMah( 13579 scanRxTimeSinceMarkMs, scanTxTimeSinceMarkMs, myIdleTimeMs); 13580 uidEstimatedConsumptionMah.incrementValue(uid.getUid(), uidEstMah); 13581 } 13582 } 13583 13584 if (DEBUG_ENERGY) { 13585 Slog.d(TAG, " New RxPower: " + leftOverRxTimeMs + " ms"); 13586 Slog.d(TAG, " New TxPower: " + leftOverTxTimeMs + " ms"); 13587 } 13588 13589 // Distribute the remaining Tx power appropriately between all apps that transmitted 13590 // packets. 13591 for (int i = 0; i < txPackets.size(); i++) { 13592 final int uid = txPackets.keyAt(i); 13593 final long myTxTimeMs = (txPackets.valueAt(i) * leftOverTxTimeMs) 13594 / totalTxPackets; 13595 txTimesMs.incrementValue(uid, myTxTimeMs); 13596 } 13597 13598 // Distribute the remaining Rx power appropriately between all apps that received 13599 // packets. 13600 for (int i = 0; i < rxPackets.size(); i++) { 13601 final int uid = rxPackets.keyAt(i); 13602 final long myRxTimeMs = (rxPackets.valueAt(i) * leftOverRxTimeMs) 13603 / totalRxPackets; 13604 rxTimesMs.incrementValue(uid, myRxTimeMs); 13605 } 13606 13607 for (int i = 0; i < txTimesMs.size(); i++) { 13608 final int uid = txTimesMs.keyAt(i); 13609 final long myTxTimeMs = txTimesMs.valueAt(i); 13610 if (DEBUG_ENERGY) { 13611 Slog.d(TAG, " TxTime for UID " + uid + ": " + myTxTimeMs + " ms"); 13612 } 13613 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 13614 .getOrCreateWifiControllerActivityLocked() 13615 .getOrCreateTxTimeCounters()[0] 13616 .increment(myTxTimeMs, elapsedRealtimeMs); 13617 if (uidEstimatedConsumptionMah != null) { 13618 uidEstimatedConsumptionMah.incrementValue(uid, 13619 mWifiPowerCalculator.calcPowerFromControllerDataMah( 13620 0, myTxTimeMs, 0)); 13621 } 13622 } 13623 13624 for (int i = 0; i < rxTimesMs.size(); i++) { 13625 final int uid = rxTimesMs.keyAt(i); 13626 final long myRxTimeMs = rxTimesMs.valueAt(i); 13627 if (DEBUG_ENERGY) { 13628 Slog.d(TAG, " RxTime for UID " + uid + ": " + myRxTimeMs + " ms"); 13629 } 13630 13631 getUidStatsLocked(rxTimesMs.keyAt(i), elapsedRealtimeMs, uptimeMs) 13632 .getOrCreateWifiControllerActivityLocked() 13633 .getOrCreateRxTimeCounter() 13634 .increment(myRxTimeMs, elapsedRealtimeMs); 13635 if (uidEstimatedConsumptionMah != null) { 13636 uidEstimatedConsumptionMah.incrementValue(uid, 13637 mWifiPowerCalculator.calcPowerFromControllerDataMah( 13638 myRxTimeMs, 0, 0)); 13639 } 13640 } 13641 13642 // Any left over power use will be picked up by the WiFi category in BatteryStatsHelper. 13643 13644 // Update WiFi controller stats. 13645 mWifiActivity.getOrCreateRxTimeCounter().increment( 13646 info.getControllerRxDurationMillis(), elapsedRealtimeMs); 13647 mWifiActivity.getOrCreateTxTimeCounters()[0].increment( 13648 info.getControllerTxDurationMillis(), elapsedRealtimeMs); 13649 mWifiActivity.getScanTimeCounter().addCountLocked( 13650 info.getControllerScanDurationMillis()); 13651 mWifiActivity.getOrCreateIdleTimeCounter().increment( 13652 info.getControllerIdleDurationMillis(), elapsedRealtimeMs); 13653 13654 // POWER_WIFI_CONTROLLER_OPERATING_VOLTAGE is measured in mV, so convert to V. 13655 final double opVolt = mPowerProfile.getAveragePower( 13656 PowerProfile.POWER_WIFI_CONTROLLER_OPERATING_VOLTAGE) / 1000.0; 13657 double controllerMaMs = 0; 13658 if (opVolt != 0) { 13659 // We store the power drain as mAms. 13660 controllerMaMs = info.getControllerEnergyUsedMicroJoules() / opVolt; 13661 mWifiActivity.getPowerCounter().addCountLocked((long) controllerMaMs); 13662 } 13663 // Converting uWs to mAms. 13664 // Conversion: (uWs * (1000ms / 1s) * (1mW / 1000uW)) / mV = mAms 13665 long monitoredRailChargeConsumedMaMs = 13666 (long) (mTmpRailStats.getWifiTotalEnergyUseduWs() / opVolt); 13667 mWifiActivity.getMonitoredRailChargeConsumedMaMs().addCountLocked( 13668 monitoredRailChargeConsumedMaMs); 13669 mHistoryCur.wifiRailChargeMah += 13670 (monitoredRailChargeConsumedMaMs / MILLISECONDS_IN_HOUR); 13671 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 13672 mTmpRailStats.resetWifiTotalEnergyUsed(); 13673 13674 if (uidEstimatedConsumptionMah != null) { 13675 totalEstimatedConsumptionMah = Math.max(controllerMaMs / MILLISECONDS_IN_HOUR, 13676 mWifiPowerCalculator.calcPowerFromControllerDataMah( 13677 rxTimeMs, txTimeMs, idleTimeMs)); 13678 } 13679 } 13680 13681 // Update the MeasuredEnergyStats information. 13682 if (uidEstimatedConsumptionMah != null) { 13683 mGlobalMeasuredEnergyStats.updateStandardBucket( 13684 MeasuredEnergyStats.POWER_BUCKET_WIFI, consumedChargeUC); 13685 13686 // Now calculate the consumption for each uid, according to its proportional usage. 13687 if (!mHasWifiReporting) { 13688 final long globalTimeMs = mGlobalWifiRunningTimer 13689 .getTimeSinceMarkLocked(elapsedRealtimeMs * 1000) / 1000; 13690 mGlobalWifiRunningTimer.setMark(elapsedRealtimeMs); 13691 totalEstimatedConsumptionMah = mWifiPowerCalculator 13692 .calcGlobalPowerWithoutControllerDataMah(globalTimeMs); 13693 } 13694 distributeEnergyToUidsLocked(MeasuredEnergyStats.POWER_BUCKET_WIFI, 13695 consumedChargeUC, uidEstimatedConsumptionMah, totalEstimatedConsumptionMah, 13696 elapsedRealtimeMs); 13697 } 13698 } 13699 } 13700 13701 private ModemActivityInfo mLastModemActivityInfo = null; 13702 13703 /** 13704 * Distribute Cell radio energy info and network traffic to apps. 13705 */ noteModemControllerActivity(@ullable final ModemActivityInfo activityInfo, final long consumedChargeUC, long elapsedRealtimeMs, long uptimeMs, @NonNull NetworkStatsManager networkStatsManager)13706 public void noteModemControllerActivity(@Nullable final ModemActivityInfo activityInfo, 13707 final long consumedChargeUC, long elapsedRealtimeMs, long uptimeMs, 13708 @NonNull NetworkStatsManager networkStatsManager) { 13709 if (DEBUG_ENERGY) { 13710 Slog.d(TAG, "Updating mobile radio stats with " + activityInfo); 13711 } 13712 ModemActivityInfo deltaInfo = mLastModemActivityInfo == null ? activityInfo 13713 : mLastModemActivityInfo.getDelta(activityInfo); 13714 mLastModemActivityInfo = activityInfo; 13715 13716 // Add modem tx power to history. 13717 addModemTxPowerToHistory(deltaInfo, elapsedRealtimeMs, uptimeMs); 13718 13719 // Grab a separate lock to acquire the network stats, which may do I/O. 13720 NetworkStats delta = null; 13721 synchronized (mModemNetworkLock) { 13722 final NetworkStats latestStats = readMobileNetworkStatsLocked(networkStatsManager); 13723 if (latestStats != null) { 13724 delta = latestStats.subtract(mLastModemNetworkStats); 13725 mLastModemNetworkStats = latestStats; 13726 } 13727 } 13728 13729 synchronized (this) { 13730 final long totalRadioDurationMs = 13731 mMobileRadioActiveTimer.getTimeSinceMarkLocked( 13732 elapsedRealtimeMs * 1000) / 1000; 13733 mMobileRadioActiveTimer.setMark(elapsedRealtimeMs); 13734 final long phoneOnDurationMs = Math.min(totalRadioDurationMs, 13735 mPhoneOnTimer.getTimeSinceMarkLocked(elapsedRealtimeMs * 1000) / 1000); 13736 mPhoneOnTimer.setMark(elapsedRealtimeMs); 13737 13738 if (!mOnBatteryInternal || mIgnoreNextExternalStats) { 13739 return; 13740 } 13741 13742 final SparseDoubleArray uidEstimatedConsumptionMah; 13743 final long dataConsumedChargeUC; 13744 if (consumedChargeUC > 0 && mMobileRadioPowerCalculator != null 13745 && mGlobalMeasuredEnergyStats != null) { 13746 // Crudely attribute power consumption. Added (totalRadioDurationMs / 2) to the 13747 // numerator for long rounding. 13748 final long phoneConsumedChargeUC = 13749 (consumedChargeUC * phoneOnDurationMs + totalRadioDurationMs / 2) 13750 / totalRadioDurationMs; 13751 dataConsumedChargeUC = consumedChargeUC - phoneConsumedChargeUC; 13752 mGlobalMeasuredEnergyStats.updateStandardBucket( 13753 MeasuredEnergyStats.POWER_BUCKET_PHONE, phoneConsumedChargeUC); 13754 mGlobalMeasuredEnergyStats.updateStandardBucket( 13755 MeasuredEnergyStats.POWER_BUCKET_MOBILE_RADIO, dataConsumedChargeUC); 13756 uidEstimatedConsumptionMah = new SparseDoubleArray(); 13757 } else { 13758 uidEstimatedConsumptionMah = null; 13759 dataConsumedChargeUC = POWER_DATA_UNAVAILABLE; 13760 } 13761 13762 if (deltaInfo != null) { 13763 mHasModemReporting = true; 13764 mModemActivity.getOrCreateIdleTimeCounter() 13765 .increment(deltaInfo.getIdleTimeMillis(), elapsedRealtimeMs); 13766 mModemActivity.getSleepTimeCounter().addCountLocked( 13767 deltaInfo.getSleepTimeMillis()); 13768 mModemActivity.getOrCreateRxTimeCounter() 13769 .increment(deltaInfo.getReceiveTimeMillis(), elapsedRealtimeMs); 13770 for (int lvl = 0; lvl < ModemActivityInfo.getNumTxPowerLevels(); lvl++) { 13771 mModemActivity.getOrCreateTxTimeCounters()[lvl] 13772 .increment(deltaInfo.getTransmitDurationMillisAtPowerLevel(lvl), 13773 elapsedRealtimeMs); 13774 } 13775 13776 // POWER_MODEM_CONTROLLER_OPERATING_VOLTAGE is measured in mV, so convert to V. 13777 final double opVolt = mPowerProfile.getAveragePower( 13778 PowerProfile.POWER_MODEM_CONTROLLER_OPERATING_VOLTAGE) / 1000.0; 13779 if (opVolt != 0) { 13780 double energyUsed = 13781 deltaInfo.getSleepTimeMillis() * 13782 mPowerProfile.getAveragePower(PowerProfile.POWER_MODEM_CONTROLLER_SLEEP) 13783 + deltaInfo.getIdleTimeMillis() * 13784 mPowerProfile.getAveragePower(PowerProfile.POWER_MODEM_CONTROLLER_IDLE) 13785 + deltaInfo.getReceiveTimeMillis() * 13786 mPowerProfile.getAveragePower(PowerProfile.POWER_MODEM_CONTROLLER_RX); 13787 for (int i = 0; i < Math.min(ModemActivityInfo.getNumTxPowerLevels(), 13788 CellSignalStrength.getNumSignalStrengthLevels()); i++) { 13789 energyUsed += deltaInfo.getTransmitDurationMillisAtPowerLevel(i) 13790 * mPowerProfile.getAveragePower( 13791 PowerProfile.POWER_MODEM_CONTROLLER_TX, i); 13792 } 13793 13794 // We store the power drain as mAms. 13795 mModemActivity.getPowerCounter().addCountLocked((long) energyUsed); 13796 // Converting uWs to mAms. 13797 // Conversion: (uWs * (1000ms / 1s) * (1mW / 1000uW)) / mV = mAms 13798 long monitoredRailChargeConsumedMaMs = 13799 (long) (mTmpRailStats.getCellularTotalEnergyUseduWs() / opVolt); 13800 mModemActivity.getMonitoredRailChargeConsumedMaMs().addCountLocked( 13801 monitoredRailChargeConsumedMaMs); 13802 mHistoryCur.modemRailChargeMah += 13803 (monitoredRailChargeConsumedMaMs / MILLISECONDS_IN_HOUR); 13804 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 13805 mTmpRailStats.resetCellularTotalEnergyUsed(); 13806 } 13807 13808 incrementPerRatDataLocked(deltaInfo, elapsedRealtimeMs); 13809 } 13810 long totalAppRadioTimeUs = mMobileRadioActivePerAppTimer.getTimeSinceMarkLocked( 13811 elapsedRealtimeMs * 1000); 13812 mMobileRadioActivePerAppTimer.setMark(elapsedRealtimeMs); 13813 13814 long totalRxPackets = 0; 13815 long totalTxPackets = 0; 13816 if (delta != null) { 13817 for (NetworkStats.Entry entry : delta) { 13818 if (entry.getRxPackets() == 0 && entry.getTxPackets() == 0) { 13819 continue; 13820 } 13821 13822 if (DEBUG_ENERGY) { 13823 Slog.d(TAG, "Mobile uid " + entry.getUid() + ": delta rx=" 13824 + entry.getRxBytes() + " tx=" + entry.getTxBytes() 13825 + " rxPackets=" + entry.getRxPackets() 13826 + " txPackets=" + entry.getTxPackets()); 13827 } 13828 13829 totalRxPackets += entry.getRxPackets(); 13830 totalTxPackets += entry.getTxPackets(); 13831 13832 final Uid u = getUidStatsLocked( 13833 mapUid(entry.getUid()), elapsedRealtimeMs, uptimeMs); 13834 u.noteNetworkActivityLocked(NETWORK_MOBILE_RX_DATA, entry.getRxBytes(), 13835 entry.getRxPackets()); 13836 u.noteNetworkActivityLocked(NETWORK_MOBILE_TX_DATA, entry.getTxBytes(), 13837 entry.getTxPackets()); 13838 if (entry.getSet() == NetworkStats.SET_DEFAULT) { // Background transfers 13839 u.noteNetworkActivityLocked(NETWORK_MOBILE_BG_RX_DATA, 13840 entry.getRxBytes(), entry.getRxPackets()); 13841 u.noteNetworkActivityLocked(NETWORK_MOBILE_BG_TX_DATA, 13842 entry.getTxBytes(), entry.getTxPackets()); 13843 } 13844 13845 mNetworkByteActivityCounters[NETWORK_MOBILE_RX_DATA].addCountLocked( 13846 entry.getRxBytes()); 13847 mNetworkByteActivityCounters[NETWORK_MOBILE_TX_DATA].addCountLocked( 13848 entry.getTxBytes()); 13849 mNetworkPacketActivityCounters[NETWORK_MOBILE_RX_DATA].addCountLocked( 13850 entry.getRxPackets()); 13851 mNetworkPacketActivityCounters[NETWORK_MOBILE_TX_DATA].addCountLocked( 13852 entry.getTxPackets()); 13853 } 13854 13855 // Now distribute proportional blame to the apps that did networking. 13856 long totalPackets = totalRxPackets + totalTxPackets; 13857 if (totalPackets > 0) { 13858 for (NetworkStats.Entry entry : delta) { 13859 if (entry.getRxPackets() == 0 && entry.getTxPackets() == 0) { 13860 continue; 13861 } 13862 13863 final Uid u = getUidStatsLocked(mapUid(entry.getUid()), 13864 elapsedRealtimeMs, uptimeMs); 13865 13866 // Distribute total radio active time in to this app. 13867 final long appPackets = entry.getRxPackets() + entry.getTxPackets(); 13868 final long appRadioTimeUs = 13869 (totalAppRadioTimeUs * appPackets) / totalPackets; 13870 u.noteMobileRadioActiveTimeLocked(appRadioTimeUs, elapsedRealtimeMs); 13871 13872 // Distribute measured mobile radio charge consumption based on app radio 13873 // active time 13874 if (uidEstimatedConsumptionMah != null) { 13875 uidEstimatedConsumptionMah.incrementValue(u.getUid(), 13876 mMobileRadioPowerCalculator.calcPowerFromRadioActiveDurationMah( 13877 appRadioTimeUs / 1000)); 13878 } 13879 13880 // Remove this app from the totals, so that we don't lose any time 13881 // due to rounding. 13882 totalAppRadioTimeUs -= appRadioTimeUs; 13883 totalPackets -= appPackets; 13884 13885 if (deltaInfo != null) { 13886 ControllerActivityCounterImpl activityCounter = 13887 u.getOrCreateModemControllerActivityLocked(); 13888 if (totalRxPackets > 0 && entry.getRxPackets() > 0) { 13889 final long rxMs = (entry.getRxPackets() 13890 * deltaInfo.getReceiveTimeMillis()) / totalRxPackets; 13891 activityCounter.getOrCreateRxTimeCounter() 13892 .increment(rxMs, elapsedRealtimeMs); 13893 } 13894 13895 if (totalTxPackets > 0 && entry.getTxPackets() > 0) { 13896 for (int lvl = 0; lvl < ModemActivityInfo.getNumTxPowerLevels(); 13897 lvl++) { 13898 long txMs = entry.getTxPackets() 13899 * deltaInfo.getTransmitDurationMillisAtPowerLevel(lvl); 13900 txMs /= totalTxPackets; 13901 activityCounter.getOrCreateTxTimeCounters()[lvl] 13902 .increment(txMs, elapsedRealtimeMs); 13903 } 13904 } 13905 } 13906 } 13907 } 13908 13909 if (totalAppRadioTimeUs > 0) { 13910 // Whoops, there is some radio time we can't blame on an app! 13911 mMobileRadioActiveUnknownTime.addCountLocked(totalAppRadioTimeUs); 13912 mMobileRadioActiveUnknownCount.addCountLocked(1); 13913 } 13914 13915 13916 // Update the MeasuredEnergyStats information. 13917 if (uidEstimatedConsumptionMah != null) { 13918 double totalEstimatedConsumptionMah = 0.0; 13919 totalEstimatedConsumptionMah += 13920 mMobileRadioPowerCalculator.calcPowerFromRadioActiveDurationMah( 13921 totalRadioDurationMs); 13922 13923 // Estimate idle power consumption at each signal strength level 13924 final int numSignalStrengthLevels = mPhoneSignalStrengthsTimer.length; 13925 for (int strengthLevel = 0; strengthLevel < numSignalStrengthLevels; 13926 strengthLevel++) { 13927 final long strengthLevelDurationMs = 13928 mPhoneSignalStrengthsTimer[strengthLevel].getTimeSinceMarkLocked( 13929 elapsedRealtimeMs * 1000) / 1000; 13930 mPhoneSignalStrengthsTimer[strengthLevel].setMark(elapsedRealtimeMs); 13931 13932 totalEstimatedConsumptionMah += 13933 mMobileRadioPowerCalculator.calcIdlePowerAtSignalStrengthMah( 13934 strengthLevelDurationMs, strengthLevel); 13935 } 13936 13937 // Estimate total active radio power consumption since last mark. 13938 final long scanTimeMs = mPhoneSignalScanningTimer.getTimeSinceMarkLocked( 13939 elapsedRealtimeMs * 1000) / 1000; 13940 mPhoneSignalScanningTimer.setMark(elapsedRealtimeMs); 13941 totalEstimatedConsumptionMah += 13942 mMobileRadioPowerCalculator.calcScanTimePowerMah(scanTimeMs); 13943 13944 distributeEnergyToUidsLocked(MeasuredEnergyStats.POWER_BUCKET_MOBILE_RADIO, 13945 dataConsumedChargeUC, uidEstimatedConsumptionMah, 13946 totalEstimatedConsumptionMah, elapsedRealtimeMs); 13947 } 13948 13949 delta = null; 13950 } 13951 } 13952 } 13953 13954 @GuardedBy("this") incrementPerRatDataLocked(ModemActivityInfo deltaInfo, long elapsedRealtimeMs)13955 private void incrementPerRatDataLocked(ModemActivityInfo deltaInfo, long elapsedRealtimeMs) { 13956 final int infoSize = deltaInfo.getSpecificInfoLength(); 13957 if (infoSize == 1 && deltaInfo.getSpecificInfoRat(0) 13958 == AccessNetworkConstants.AccessNetworkType.UNKNOWN 13959 && deltaInfo.getSpecificInfoFrequencyRange(0) 13960 == ServiceState.FREQUENCY_RANGE_UNKNOWN) { 13961 // Specific info data unavailable. Proportionally smear Rx and Tx times across each RAT. 13962 final int levelCount = CellSignalStrength.getNumSignalStrengthLevels(); 13963 long[] perSignalStrengthActiveTimeMs = new long[levelCount]; 13964 long totalActiveTimeMs = 0; 13965 13966 for (int rat = 0; rat < RADIO_ACCESS_TECHNOLOGY_COUNT; rat++) { 13967 final RadioAccessTechnologyBatteryStats ratStats = mPerRatBatteryStats[rat]; 13968 if (ratStats == null) continue; 13969 13970 final int freqCount = ratStats.getFrequencyRangeCount(); 13971 for (int freq = 0; freq < freqCount; freq++) { 13972 for (int level = 0; level < levelCount; level++) { 13973 final long durationMs = ratStats.getTimeSinceMark(freq, level, 13974 elapsedRealtimeMs); 13975 perSignalStrengthActiveTimeMs[level] += durationMs; 13976 totalActiveTimeMs += durationMs; 13977 } 13978 } 13979 } 13980 if (totalActiveTimeMs != 0) { 13981 // Smear the provided Tx/Rx durations across each RAT, frequency, and signal 13982 // strength. 13983 for (int rat = 0; rat < RADIO_ACCESS_TECHNOLOGY_COUNT; rat++) { 13984 final RadioAccessTechnologyBatteryStats ratStats = mPerRatBatteryStats[rat]; 13985 if (ratStats == null) continue; 13986 13987 final int freqCount = ratStats.getFrequencyRangeCount(); 13988 for (int freq = 0; freq < freqCount; freq++) { 13989 long frequencyDurationMs = 0; 13990 for (int level = 0; level < levelCount; level++) { 13991 final long durationMs = ratStats.getTimeSinceMark(freq, level, 13992 elapsedRealtimeMs); 13993 final long totalLvlDurationMs = 13994 perSignalStrengthActiveTimeMs[level]; 13995 if (totalLvlDurationMs == 0) continue; 13996 final long totalTxLvlDurations = 13997 deltaInfo.getTransmitDurationMillisAtPowerLevel(level); 13998 // Smear HAL provided Tx power level duration based on active modem 13999 // duration in a given state. (Add totalLvlDurationMs / 2 before 14000 // the integer division with totalLvlDurationMs for rounding.) 14001 final long proportionalTxDurationMs = 14002 (durationMs * totalTxLvlDurations 14003 + (totalLvlDurationMs / 2)) / totalLvlDurationMs; 14004 ratStats.incrementTxDuration(freq, level, proportionalTxDurationMs); 14005 frequencyDurationMs += durationMs; 14006 } 14007 final long totalRxDuration = deltaInfo.getReceiveTimeMillis(); 14008 // Smear HAL provided Rx power duration based on active modem 14009 // duration in a given state. (Add totalActiveTimeMs / 2 before the 14010 // integer division with totalActiveTimeMs for rounding.) 14011 final long proportionalRxDurationMs = 14012 (frequencyDurationMs * totalRxDuration + (totalActiveTimeMs 14013 / 2)) / totalActiveTimeMs; 14014 ratStats.incrementRxDuration(freq, proportionalRxDurationMs); 14015 } 14016 14017 } 14018 } 14019 } else { 14020 // Specific data available. 14021 for (int index = 0; index < infoSize; index++) { 14022 final int rat = deltaInfo.getSpecificInfoRat(index); 14023 final int freq = deltaInfo.getSpecificInfoFrequencyRange(index); 14024 14025 // Map RadioAccessNetworkType to course grain RadioAccessTechnology. 14026 final int ratBucket = mapRadioAccessNetworkTypeToRadioAccessTechnology(rat); 14027 final RadioAccessTechnologyBatteryStats ratStats = getRatBatteryStatsLocked( 14028 ratBucket); 14029 14030 final long rxTimeMs = deltaInfo.getReceiveTimeMillis(rat, freq); 14031 final int[] txTimesMs = deltaInfo.getTransmitTimeMillis(rat, freq); 14032 14033 ratStats.incrementRxDuration(freq, rxTimeMs); 14034 final int numTxLvl = txTimesMs.length; 14035 for (int lvl = 0; lvl < numTxLvl; lvl++) { 14036 ratStats.incrementTxDuration(freq, lvl, txTimesMs[lvl]); 14037 } 14038 } 14039 } 14040 14041 for (int rat = 0; rat < RADIO_ACCESS_TECHNOLOGY_COUNT; rat++) { 14042 final RadioAccessTechnologyBatteryStats ratStats = mPerRatBatteryStats[rat]; 14043 if (ratStats == null) continue; 14044 ratStats.setMark(elapsedRealtimeMs); 14045 } 14046 } 14047 14048 /** 14049 * Add modem tx power to history 14050 * Device is said to be in high cellular transmit power when it has spent most of the transmit 14051 * time at the highest power level. 14052 * @param activityInfo 14053 */ addModemTxPowerToHistory(final ModemActivityInfo activityInfo, long elapsedRealtimeMs, long uptimeMs)14054 private synchronized void addModemTxPowerToHistory(final ModemActivityInfo activityInfo, 14055 long elapsedRealtimeMs, long uptimeMs) { 14056 if (activityInfo == null) { 14057 return; 14058 } 14059 int levelMaxTimeSpent = 0; 14060 for (int i = 1; i < ModemActivityInfo.getNumTxPowerLevels(); i++) { 14061 if (activityInfo.getTransmitDurationMillisAtPowerLevel(i) 14062 > activityInfo.getTransmitDurationMillisAtPowerLevel(levelMaxTimeSpent)) { 14063 levelMaxTimeSpent = i; 14064 } 14065 } 14066 if (levelMaxTimeSpent == ModemActivityInfo.getNumTxPowerLevels() - 1) { 14067 mHistoryCur.states2 |= HistoryItem.STATE2_CELLULAR_HIGH_TX_POWER_FLAG; 14068 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 14069 } 14070 } 14071 14072 private final class BluetoothActivityInfoCache { 14073 long idleTimeMs; 14074 long rxTimeMs; 14075 long txTimeMs; 14076 long energy; 14077 14078 SparseLongArray uidRxBytes = new SparseLongArray(); 14079 SparseLongArray uidTxBytes = new SparseLongArray(); 14080 set(BluetoothActivityEnergyInfo info)14081 void set(BluetoothActivityEnergyInfo info) { 14082 idleTimeMs = info.getControllerIdleTimeMillis(); 14083 rxTimeMs = info.getControllerRxTimeMillis(); 14084 txTimeMs = info.getControllerTxTimeMillis(); 14085 energy = info.getControllerEnergyUsed(); 14086 if (!info.getUidTraffic().isEmpty()) { 14087 for (UidTraffic traffic : info.getUidTraffic()) { 14088 uidRxBytes.incrementValue(traffic.getUid(), traffic.getRxBytes()); 14089 uidTxBytes.incrementValue(traffic.getUid(), traffic.getTxBytes()); 14090 } 14091 } 14092 } 14093 reset()14094 void reset() { 14095 idleTimeMs = 0; 14096 rxTimeMs = 0; 14097 txTimeMs = 0; 14098 energy = 0; 14099 uidRxBytes.clear(); 14100 uidTxBytes.clear(); 14101 } 14102 } 14103 14104 private final BluetoothActivityInfoCache mLastBluetoothActivityInfo 14105 = new BluetoothActivityInfoCache(); 14106 14107 /** 14108 * Distribute Bluetooth energy info and network traffic to apps. 14109 * 14110 * @param info The accumulated energy information from the bluetooth controller. 14111 */ 14112 @GuardedBy("this") updateBluetoothStateLocked(@ullable final BluetoothActivityEnergyInfo info, final long consumedChargeUC, long elapsedRealtimeMs, long uptimeMs)14113 public void updateBluetoothStateLocked(@Nullable final BluetoothActivityEnergyInfo info, 14114 final long consumedChargeUC, long elapsedRealtimeMs, long uptimeMs) { 14115 if (DEBUG_ENERGY) { 14116 Slog.d(TAG, "Updating bluetooth stats: " + info); 14117 } 14118 14119 if (info == null) { 14120 return; 14121 } 14122 if (!mOnBatteryInternal || mIgnoreNextExternalStats) { 14123 mLastBluetoothActivityInfo.set(info); 14124 return; 14125 } 14126 14127 mHasBluetoothReporting = true; 14128 14129 if (info.getControllerRxTimeMillis() < mLastBluetoothActivityInfo.rxTimeMs 14130 || info.getControllerTxTimeMillis() < mLastBluetoothActivityInfo.txTimeMs 14131 || info.getControllerIdleTimeMillis() < mLastBluetoothActivityInfo.idleTimeMs 14132 || info.getControllerEnergyUsed() < mLastBluetoothActivityInfo.energy) { 14133 // A drop in accumulated Bluetooth stats is a sign of a Bluetooth crash. 14134 // Reset the preserved previous snapshot in order to restart accumulating deltas. 14135 mLastBluetoothActivityInfo.reset(); 14136 } 14137 14138 final long rxTimeMs = 14139 info.getControllerRxTimeMillis() - mLastBluetoothActivityInfo.rxTimeMs; 14140 final long txTimeMs = 14141 info.getControllerTxTimeMillis() - mLastBluetoothActivityInfo.txTimeMs; 14142 final long idleTimeMs = 14143 info.getControllerIdleTimeMillis() - mLastBluetoothActivityInfo.idleTimeMs; 14144 14145 if (DEBUG_ENERGY) { 14146 Slog.d(TAG, "------ BEGIN BLE power blaming ------"); 14147 Slog.d(TAG, " Tx Time: " + txTimeMs + " ms"); 14148 Slog.d(TAG, " Rx Time: " + rxTimeMs + " ms"); 14149 Slog.d(TAG, " Idle Time: " + idleTimeMs + " ms"); 14150 } 14151 14152 final SparseDoubleArray uidEstimatedConsumptionMah = 14153 (mGlobalMeasuredEnergyStats != null 14154 && mBluetoothPowerCalculator != null && consumedChargeUC > 0) ? 14155 new SparseDoubleArray() : null; 14156 14157 long totalScanTimeMs = 0; 14158 14159 final int uidCount = mUidStats.size(); 14160 for (int i = 0; i < uidCount; i++) { 14161 final Uid u = mUidStats.valueAt(i); 14162 if (u.mBluetoothScanTimer == null) { 14163 continue; 14164 } 14165 14166 totalScanTimeMs += u.mBluetoothScanTimer.getTimeSinceMarkLocked( 14167 elapsedRealtimeMs * 1000) / 1000; 14168 } 14169 14170 final boolean normalizeScanRxTime = (totalScanTimeMs > rxTimeMs); 14171 final boolean normalizeScanTxTime = (totalScanTimeMs > txTimeMs); 14172 14173 if (DEBUG_ENERGY) { 14174 Slog.d(TAG, "Normalizing scan power for RX=" + normalizeScanRxTime 14175 + " TX=" + normalizeScanTxTime); 14176 } 14177 14178 long leftOverRxTimeMs = rxTimeMs; 14179 long leftOverTxTimeMs = txTimeMs; 14180 14181 final SparseLongArray rxTimesMs = new SparseLongArray(uidCount); 14182 final SparseLongArray txTimesMs = new SparseLongArray(uidCount); 14183 14184 for (int i = 0; i < uidCount; i++) { 14185 final Uid u = mUidStats.valueAt(i); 14186 if (u.mBluetoothScanTimer == null) { 14187 continue; 14188 } 14189 14190 long scanTimeSinceMarkMs = u.mBluetoothScanTimer.getTimeSinceMarkLocked( 14191 elapsedRealtimeMs * 1000) / 1000; 14192 if (scanTimeSinceMarkMs > 0) { 14193 // Set the new mark so that next time we get new data since this point. 14194 u.mBluetoothScanTimer.setMark(elapsedRealtimeMs); 14195 14196 long scanTimeRxSinceMarkMs = scanTimeSinceMarkMs; 14197 long scanTimeTxSinceMarkMs = scanTimeSinceMarkMs; 14198 14199 if (normalizeScanRxTime) { 14200 // Scan time is longer than the total rx time in the controller, 14201 // so distribute the scan time proportionately. This means regular traffic 14202 // will not blamed, but scans are more expensive anyways. 14203 scanTimeRxSinceMarkMs = (rxTimeMs * scanTimeRxSinceMarkMs) / totalScanTimeMs; 14204 } 14205 14206 if (normalizeScanTxTime) { 14207 // Scan time is longer than the total tx time in the controller, 14208 // so distribute the scan time proportionately. This means regular traffic 14209 // will not blamed, but scans are more expensive anyways. 14210 scanTimeTxSinceMarkMs = (txTimeMs * scanTimeTxSinceMarkMs) / totalScanTimeMs; 14211 } 14212 14213 rxTimesMs.incrementValue(u.getUid(), scanTimeRxSinceMarkMs); 14214 txTimesMs.incrementValue(u.getUid(), scanTimeTxSinceMarkMs); 14215 14216 if (uidEstimatedConsumptionMah != null) { 14217 uidEstimatedConsumptionMah.incrementValue(u.getUid(), 14218 mBluetoothPowerCalculator.calculatePowerMah( 14219 scanTimeRxSinceMarkMs, scanTimeTxSinceMarkMs, 0)); 14220 } 14221 14222 leftOverRxTimeMs -= scanTimeRxSinceMarkMs; 14223 leftOverTxTimeMs -= scanTimeTxSinceMarkMs; 14224 } 14225 } 14226 14227 if (DEBUG_ENERGY) { 14228 Slog.d(TAG, "Left over time for traffic RX=" + leftOverRxTimeMs + " TX=" 14229 + leftOverTxTimeMs); 14230 } 14231 14232 // 14233 // Now distribute blame to apps that did bluetooth traffic. 14234 // 14235 14236 long totalTxBytes = 0; 14237 long totalRxBytes = 0; 14238 14239 final List<UidTraffic> uidTraffic = info.getUidTraffic(); 14240 final int numUids = uidTraffic.size(); 14241 for (int i = 0; i < numUids; i++) { 14242 final UidTraffic traffic = uidTraffic.get(i); 14243 final long rxBytes = traffic.getRxBytes() - mLastBluetoothActivityInfo.uidRxBytes.get( 14244 traffic.getUid()); 14245 final long txBytes = traffic.getTxBytes() - mLastBluetoothActivityInfo.uidTxBytes.get( 14246 traffic.getUid()); 14247 14248 // Add to the global counters. 14249 mNetworkByteActivityCounters[NETWORK_BT_RX_DATA].addCountLocked(rxBytes); 14250 mNetworkByteActivityCounters[NETWORK_BT_TX_DATA].addCountLocked(txBytes); 14251 14252 // Add to the UID counters. 14253 final Uid u = getUidStatsLocked(mapUid(traffic.getUid()), elapsedRealtimeMs, uptimeMs); 14254 u.noteNetworkActivityLocked(NETWORK_BT_RX_DATA, rxBytes, 0); 14255 u.noteNetworkActivityLocked(NETWORK_BT_TX_DATA, txBytes, 0); 14256 14257 // Calculate the total traffic. 14258 totalRxBytes += rxBytes; 14259 totalTxBytes += txBytes; 14260 } 14261 14262 if ((totalTxBytes != 0 || totalRxBytes != 0) && (leftOverRxTimeMs != 0 14263 || leftOverTxTimeMs != 0)) { 14264 for (int i = 0; i < numUids; i++) { 14265 final UidTraffic traffic = uidTraffic.get(i); 14266 final int uid = traffic.getUid(); 14267 final long rxBytes = 14268 traffic.getRxBytes() - mLastBluetoothActivityInfo.uidRxBytes.get(uid); 14269 final long txBytes = 14270 traffic.getTxBytes() - mLastBluetoothActivityInfo.uidTxBytes.get(uid); 14271 14272 final Uid u = getUidStatsLocked(mapUid(uid), elapsedRealtimeMs, uptimeMs); 14273 final ControllerActivityCounterImpl counter = 14274 u.getOrCreateBluetoothControllerActivityLocked(); 14275 14276 if (totalRxBytes > 0 && rxBytes > 0) { 14277 final long timeRxMs = (leftOverRxTimeMs * rxBytes) / totalRxBytes; 14278 rxTimesMs.incrementValue(uid, timeRxMs); 14279 } 14280 14281 if (totalTxBytes > 0 && txBytes > 0) { 14282 final long timeTxMs = (leftOverTxTimeMs * txBytes) / totalTxBytes; 14283 txTimesMs.incrementValue(uid, timeTxMs); 14284 } 14285 } 14286 14287 for (int i = 0; i < txTimesMs.size(); i++) { 14288 final int uid = txTimesMs.keyAt(i); 14289 final long myTxTimeMs = txTimesMs.valueAt(i); 14290 if (DEBUG_ENERGY) { 14291 Slog.d(TAG, " TxTime for UID " + uid + ": " + myTxTimeMs + " ms"); 14292 } 14293 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 14294 .getOrCreateBluetoothControllerActivityLocked() 14295 .getOrCreateTxTimeCounters()[0] 14296 .increment(myTxTimeMs, elapsedRealtimeMs); 14297 if (uidEstimatedConsumptionMah != null) { 14298 uidEstimatedConsumptionMah.incrementValue(uid, 14299 mBluetoothPowerCalculator.calculatePowerMah(0, myTxTimeMs, 0)); 14300 } 14301 } 14302 14303 for (int i = 0; i < rxTimesMs.size(); i++) { 14304 final int uid = rxTimesMs.keyAt(i); 14305 final long myRxTimeMs = rxTimesMs.valueAt(i); 14306 if (DEBUG_ENERGY) { 14307 Slog.d(TAG, " RxTime for UID " + uid + ": " + myRxTimeMs + " ms"); 14308 } 14309 14310 getUidStatsLocked(rxTimesMs.keyAt(i), elapsedRealtimeMs, uptimeMs) 14311 .getOrCreateBluetoothControllerActivityLocked() 14312 .getOrCreateRxTimeCounter() 14313 .increment(myRxTimeMs, elapsedRealtimeMs); 14314 if (uidEstimatedConsumptionMah != null) { 14315 uidEstimatedConsumptionMah.incrementValue(uid, 14316 mBluetoothPowerCalculator.calculatePowerMah(myRxTimeMs, 0, 0)); 14317 } 14318 } 14319 } 14320 14321 mBluetoothActivity.getOrCreateRxTimeCounter().increment(rxTimeMs, elapsedRealtimeMs); 14322 mBluetoothActivity.getOrCreateTxTimeCounters()[0].increment(txTimeMs, elapsedRealtimeMs); 14323 mBluetoothActivity.getOrCreateIdleTimeCounter().increment(idleTimeMs, elapsedRealtimeMs); 14324 14325 // POWER_BLUETOOTH_CONTROLLER_OPERATING_VOLTAGE is measured in mV, so convert to V. 14326 final double opVolt = mPowerProfile.getAveragePower( 14327 PowerProfile.POWER_BLUETOOTH_CONTROLLER_OPERATING_VOLTAGE) / 1000.0; 14328 double controllerMaMs = 0; 14329 if (opVolt != 0) { 14330 controllerMaMs = (info.getControllerEnergyUsed() - mLastBluetoothActivityInfo.energy) 14331 / opVolt; 14332 // We store the power drain as mAms. 14333 mBluetoothActivity.getPowerCounter().addCountLocked((long) controllerMaMs); 14334 } 14335 14336 // Update the MeasuredEnergyStats information. 14337 if (uidEstimatedConsumptionMah != null) { 14338 mGlobalMeasuredEnergyStats.updateStandardBucket( 14339 MeasuredEnergyStats.POWER_BUCKET_BLUETOOTH, consumedChargeUC); 14340 14341 double totalEstimatedMah 14342 = mBluetoothPowerCalculator.calculatePowerMah(rxTimeMs, txTimeMs, idleTimeMs); 14343 totalEstimatedMah = Math.max(totalEstimatedMah, controllerMaMs / MILLISECONDS_IN_HOUR); 14344 distributeEnergyToUidsLocked(MeasuredEnergyStats.POWER_BUCKET_BLUETOOTH, 14345 consumedChargeUC, uidEstimatedConsumptionMah, totalEstimatedMah, 14346 elapsedRealtimeMs); 14347 } 14348 14349 mLastBluetoothActivityInfo.set(info); 14350 } 14351 /** 14352 * Read Resource Power Manager (RPM) state and voter times. 14353 * If RPM stats were fetched more recently than RPM_STATS_UPDATE_FREQ_MS ago, uses the old data 14354 * instead of fetching it anew. 14355 * 14356 * Note: This should be called without synchronizing this BatteryStatsImpl object 14357 */ fillLowPowerStats()14358 public void fillLowPowerStats() { 14359 if (mPlatformIdleStateCallback == null) return; 14360 14361 RpmStats rpmStats = new RpmStats(); 14362 long now = SystemClock.elapsedRealtime(); 14363 if (now - mLastRpmStatsUpdateTimeMs >= RPM_STATS_UPDATE_FREQ_MS) { 14364 mPlatformIdleStateCallback.fillLowPowerStats(rpmStats); 14365 synchronized (this) { 14366 mTmpRpmStats = rpmStats; 14367 mLastRpmStatsUpdateTimeMs = now; 14368 } 14369 } 14370 } 14371 14372 /** 14373 * Record Resource Power Manager (RPM) state and voter times. 14374 * TODO(b/185252376): Remove this logging. PowerStatsService logs the same data more 14375 * efficiently. 14376 */ updateRpmStatsLocked(long elapsedRealtimeUs)14377 public void updateRpmStatsLocked(long elapsedRealtimeUs) { 14378 if (mTmpRpmStats == null) return; 14379 14380 for (Map.Entry<String, RpmStats.PowerStatePlatformSleepState> pstate 14381 : mTmpRpmStats.mPlatformLowPowerStats.entrySet()) { 14382 14383 // Update values for this platform state. 14384 final String pName = pstate.getKey(); 14385 final long pTimeUs = pstate.getValue().mTimeMs * 1000; 14386 final int pCount = pstate.getValue().mCount; 14387 getRpmTimerLocked(pName).update(pTimeUs, pCount, elapsedRealtimeUs); 14388 if (SCREEN_OFF_RPM_STATS_ENABLED) { 14389 getScreenOffRpmTimerLocked(pName).update(pTimeUs, pCount, elapsedRealtimeUs); 14390 } 14391 14392 // Update values for each voter of this platform state. 14393 for (Map.Entry<String, RpmStats.PowerStateElement> voter 14394 : pstate.getValue().mVoters.entrySet()) { 14395 final String vName = pName + "." + voter.getKey(); 14396 final long vTimeUs = voter.getValue().mTimeMs * 1000; 14397 final int vCount = voter.getValue().mCount; 14398 getRpmTimerLocked(vName).update(vTimeUs, vCount, elapsedRealtimeUs); 14399 if (SCREEN_OFF_RPM_STATS_ENABLED) { 14400 getScreenOffRpmTimerLocked(vName).update(vTimeUs, vCount, elapsedRealtimeUs); 14401 } 14402 } 14403 } 14404 14405 for (Map.Entry<String, RpmStats.PowerStateSubsystem> subsys 14406 : mTmpRpmStats.mSubsystemLowPowerStats.entrySet()) { 14407 14408 final String subsysName = subsys.getKey(); 14409 for (Map.Entry<String, RpmStats.PowerStateElement> sstate 14410 : subsys.getValue().mStates.entrySet()) { 14411 final String name = subsysName + "." + sstate.getKey(); 14412 final long timeUs = sstate.getValue().mTimeMs * 1000; 14413 final int count = sstate.getValue().mCount; 14414 getRpmTimerLocked(name).update(timeUs, count, elapsedRealtimeUs); 14415 if (SCREEN_OFF_RPM_STATS_ENABLED) { 14416 getScreenOffRpmTimerLocked(name).update(timeUs, count, elapsedRealtimeUs); 14417 } 14418 } 14419 } 14420 } 14421 14422 /** 14423 * Accumulate Cpu charge consumption and distribute it to the correct state and the apps. 14424 * Only call if device is on battery. 14425 * 14426 * @param clusterChargeUC amount of charge (microcoulombs) consumed by each Cpu Cluster 14427 * @param accumulator collection of calculated uid cpu power consumption to smear 14428 * clusterChargeUC against. 14429 */ 14430 @GuardedBy("this") 14431 @SuppressWarnings("GuardedBy") // errorprone false positive on u.addChargeToStandardBucketLocked updateCpuMeasuredEnergyStatsLocked(@onNull long[] clusterChargeUC, @NonNull CpuDeltaPowerAccumulator accumulator)14432 private void updateCpuMeasuredEnergyStatsLocked(@NonNull long[] clusterChargeUC, 14433 @NonNull CpuDeltaPowerAccumulator accumulator) { 14434 if (DEBUG_ENERGY) { 14435 Slog.d(TAG, 14436 "Updating cpu cluster stats: " + clusterChargeUC.toString()); 14437 } 14438 if (mGlobalMeasuredEnergyStats == null) { 14439 return; 14440 } 14441 14442 final int numClusters = clusterChargeUC.length; 14443 long totalCpuChargeUC = 0; 14444 for (int i = 0; i < numClusters; i++) { 14445 totalCpuChargeUC += clusterChargeUC[i]; 14446 } 14447 if (totalCpuChargeUC <= 0) return; 14448 14449 final long timestampMs = mClock.elapsedRealtime(); 14450 14451 mGlobalMeasuredEnergyStats.updateStandardBucket(MeasuredEnergyStats.POWER_BUCKET_CPU, 14452 totalCpuChargeUC, timestampMs); 14453 14454 // Calculate the measured microcoulombs/calculated milliamp-hour charge ratio for each 14455 // cluster to normalize each uid's estimated power usage against actual power usage for 14456 // a given cluster. 14457 final double[] clusterChargeRatio = new double[numClusters]; 14458 for (int cluster = 0; cluster < numClusters; cluster++) { 14459 14460 final double totalClusterChargeMah = accumulator.totalClusterChargesMah[cluster]; 14461 if (totalClusterChargeMah <= 0.0) { 14462 // This cluster did not have any work on it, since last update. 14463 // Avoid dividing by zero. 14464 clusterChargeRatio[cluster] = 0.0; 14465 } else { 14466 clusterChargeRatio[cluster] = 14467 clusterChargeUC[cluster] / accumulator.totalClusterChargesMah[cluster]; 14468 } 14469 } 14470 14471 // Assign and distribute power usage to apps based on their calculated cpu cluster charge. 14472 final long uidChargeArraySize = accumulator.perUidCpuClusterChargesMah.size(); 14473 for (int i = 0; i < uidChargeArraySize; i++) { 14474 final Uid uid = accumulator.perUidCpuClusterChargesMah.keyAt(i); 14475 final double[] uidClusterChargesMah = accumulator.perUidCpuClusterChargesMah.valueAt(i); 14476 14477 // Iterate each cpu cluster and sum the proportional measured cpu cluster charge to 14478 // get the total cpu charge consumed by a uid. 14479 long uidCpuChargeUC = 0; 14480 for (int cluster = 0; cluster < numClusters; cluster++) { 14481 final double uidClusterChargeMah = uidClusterChargesMah[cluster]; 14482 14483 // Proportionally allocate the measured cpu cluster charge to a uid using the 14484 // measured charge/calculated charge ratio. Add 0.5 to round the proportional 14485 // charge double to the nearest long value. 14486 final long uidClusterChargeUC = 14487 (long) (uidClusterChargeMah * clusterChargeRatio[cluster] 14488 + 0.5); 14489 14490 uidCpuChargeUC += uidClusterChargeUC; 14491 } 14492 14493 if (uidCpuChargeUC < 0) { 14494 Slog.wtf(TAG, 14495 "Unexpected proportional measured charge (" + uidCpuChargeUC + ") for uid " 14496 + uid.mUid); 14497 continue; 14498 } 14499 14500 uid.addChargeToStandardBucketLocked(uidCpuChargeUC, 14501 MeasuredEnergyStats.POWER_BUCKET_CPU, timestampMs); 14502 } 14503 } 14504 14505 /** 14506 * Accumulate Display charge consumption and distribute it to the correct state and the apps. 14507 * 14508 * NOTE: The algorithm used makes the strong assumption that app foreground activity time 14509 * is always 0 when the screen is not "ON" and whenever the rail energy is 0 (if supported). 14510 * To the extent that those assumptions are violated, the algorithm will err. 14511 * 14512 * @param chargesUC amount of charge (microcoulombs) used by each Display since this was last 14513 * called. 14514 * @param screenStates each screen state at the time this data collection was scheduled 14515 */ 14516 @GuardedBy("this") updateDisplayMeasuredEnergyStatsLocked(long[] chargesUC, int[] screenStates, long elapsedRealtimeMs)14517 public void updateDisplayMeasuredEnergyStatsLocked(long[] chargesUC, int[] screenStates, 14518 long elapsedRealtimeMs) { 14519 if (DEBUG_ENERGY) Slog.d(TAG, "Updating display stats: " + Arrays.toString(chargesUC)); 14520 if (mGlobalMeasuredEnergyStats == null) { 14521 return; 14522 } 14523 14524 final int numDisplays; 14525 if (mPerDisplayBatteryStats.length == screenStates.length) { 14526 numDisplays = screenStates.length; 14527 } else { 14528 // if this point is reached, it will be reached every display state change. 14529 // Rate limit the wtf logging to once every 100 display updates. 14530 if (mDisplayMismatchWtfCount++ % 100 == 0) { 14531 Slog.wtf(TAG, "Mismatch between PowerProfile reported display count (" 14532 + mPerDisplayBatteryStats.length 14533 + ") and PowerStatsHal reported display count (" + screenStates.length 14534 + ")"); 14535 } 14536 // Keep the show going, use the shorter of the two. 14537 numDisplays = mPerDisplayBatteryStats.length < screenStates.length 14538 ? mPerDisplayBatteryStats.length : screenStates.length; 14539 } 14540 14541 final int[] oldScreenStates = new int[numDisplays]; 14542 for (int i = 0; i < numDisplays; i++) { 14543 final int screenState = screenStates[i]; 14544 oldScreenStates[i] = mPerDisplayBatteryStats[i].screenStateAtLastEnergyMeasurement; 14545 mPerDisplayBatteryStats[i].screenStateAtLastEnergyMeasurement = screenState; 14546 } 14547 14548 if (!mOnBatteryInternal) { 14549 // There's nothing further to update. 14550 return; 14551 } 14552 if (mIgnoreNextExternalStats) { 14553 // Although under ordinary resets we won't get here, and typically a new sync will 14554 // happen right after the reset, strictly speaking we need to set all mark times to now. 14555 final int uidStatsSize = mUidStats.size(); 14556 for (int i = 0; i < uidStatsSize; i++) { 14557 final Uid uid = mUidStats.valueAt(i); 14558 uid.markProcessForegroundTimeUs(elapsedRealtimeMs, false); 14559 } 14560 return; 14561 } 14562 14563 long totalScreenOnChargeUC = 0; 14564 for (int i = 0; i < numDisplays; i++) { 14565 final long chargeUC = chargesUC[i]; 14566 if (chargeUC <= 0) { 14567 // There's nothing further to update. 14568 continue; 14569 } 14570 14571 final @StandardPowerBucket int powerBucket = 14572 MeasuredEnergyStats.getDisplayPowerBucket(oldScreenStates[i]); 14573 mGlobalMeasuredEnergyStats.updateStandardBucket(powerBucket, chargeUC); 14574 if (powerBucket == MeasuredEnergyStats.POWER_BUCKET_SCREEN_ON) { 14575 totalScreenOnChargeUC += chargeUC; 14576 } 14577 } 14578 14579 // Now we blame individual apps, but only if the display was ON. 14580 if (totalScreenOnChargeUC <= 0) { 14581 return; 14582 } 14583 // TODO(b/175726779): Consider unifying the code with the non-rail display power blaming. 14584 14585 // NOTE: fg time is NOT pooled. If two uids are both somehow in fg, then that time is 14586 // 'double counted' and will simply exceed the realtime that elapsed. 14587 // TODO(b/175726779): collect per display uid visibility for display power attribution. 14588 14589 // Collect total time since mark so that we can normalize power. 14590 final SparseDoubleArray fgTimeUsArray = new SparseDoubleArray(); 14591 final long elapsedRealtimeUs = elapsedRealtimeMs * 1000; 14592 // TODO(b/175726779): Update and optimize the algorithm (e.g. avoid iterating over ALL uids) 14593 final int uidStatsSize = mUidStats.size(); 14594 for (int i = 0; i < uidStatsSize; i++) { 14595 final Uid uid = mUidStats.valueAt(i); 14596 final long fgTimeUs = uid.markProcessForegroundTimeUs(elapsedRealtimeMs, true); 14597 if (fgTimeUs == 0) continue; 14598 fgTimeUsArray.put(uid.getUid(), (double) fgTimeUs); 14599 } 14600 distributeEnergyToUidsLocked(MeasuredEnergyStats.POWER_BUCKET_SCREEN_ON, 14601 totalScreenOnChargeUC, fgTimeUsArray, 0, elapsedRealtimeMs); 14602 } 14603 14604 /** 14605 * Accumulate GNSS charge consumption and distribute it to the correct state and the apps. 14606 * 14607 * @param chargeUC amount of charge (microcoulombs) used by GNSS since this was last called. 14608 */ 14609 @GuardedBy("this") 14610 public void updateGnssMeasuredEnergyStatsLocked(long chargeUC, long elapsedRealtimeMs) { 14611 if (DEBUG_ENERGY) Slog.d(TAG, "Updating gnss stats: " + chargeUC); 14612 if (mGlobalMeasuredEnergyStats == null) { 14613 return; 14614 } 14615 14616 if (!mOnBatteryInternal || chargeUC <= 0) { 14617 // There's nothing further to update. 14618 return; 14619 } 14620 if (mIgnoreNextExternalStats) { 14621 // Although under ordinary resets we won't get here, and typically a new sync will 14622 // happen right after the reset, strictly speaking we need to set all mark times to now. 14623 final int uidStatsSize = mUidStats.size(); 14624 for (int i = 0; i < uidStatsSize; i++) { 14625 final Uid uid = mUidStats.valueAt(i); 14626 uid.markGnssTimeUs(elapsedRealtimeMs); 14627 } 14628 return; 14629 } 14630 14631 mGlobalMeasuredEnergyStats.updateStandardBucket(MeasuredEnergyStats.POWER_BUCKET_GNSS, 14632 chargeUC); 14633 14634 // Collect the per uid time since mark so that we can normalize power. 14635 final SparseDoubleArray gnssTimeUsArray = new SparseDoubleArray(); 14636 // TODO(b/175726779): Update and optimize the algorithm (e.g. avoid iterating over ALL uids) 14637 final int uidStatsSize = mUidStats.size(); 14638 for (int i = 0; i < uidStatsSize; i++) { 14639 final Uid uid = mUidStats.valueAt(i); 14640 final long gnssTimeUs = uid.markGnssTimeUs(elapsedRealtimeMs); 14641 if (gnssTimeUs == 0) continue; 14642 gnssTimeUsArray.put(uid.getUid(), (double) gnssTimeUs); 14643 } 14644 distributeEnergyToUidsLocked(MeasuredEnergyStats.POWER_BUCKET_GNSS, chargeUC, 14645 gnssTimeUsArray, 0, elapsedRealtimeMs); 14646 } 14647 14648 /** 14649 * Accumulate Custom power bucket charge, globally and for each app. 14650 * 14651 * @param totalChargeUC charge (microcoulombs) used for this bucket since this was last called. 14652 * @param uidCharges map of uid->charge (microcoulombs) for this bucket since last called. 14653 * Data inside uidCharges will not be modified (treated immutable). 14654 * Uids not already known to BatteryStats will be ignored. 14655 */ 14656 @GuardedBy("this") 14657 @SuppressWarnings("GuardedBy") // errorprone false positive on u.addChargeToCustomBucketLocked 14658 public void updateCustomMeasuredEnergyStatsLocked(int customPowerBucket, 14659 long totalChargeUC, @Nullable SparseLongArray uidCharges) { 14660 if (DEBUG_ENERGY) { 14661 Slog.d(TAG, "Updating attributed measured charge stats for custom bucket " 14662 + customPowerBucket 14663 + " with total charge " + totalChargeUC 14664 + " and uid charges " + String.valueOf(uidCharges)); 14665 } 14666 if (mGlobalMeasuredEnergyStats == null) return; 14667 if (!mOnBatteryInternal || mIgnoreNextExternalStats || totalChargeUC <= 0) return; 14668 14669 mGlobalMeasuredEnergyStats.updateCustomBucket(customPowerBucket, totalChargeUC, 14670 mClock.elapsedRealtime()); 14671 14672 if (uidCharges == null) return; 14673 final int numUids = uidCharges.size(); 14674 for (int i = 0; i < numUids; i++) { 14675 final int uidInt = mapUid(uidCharges.keyAt(i)); 14676 final long uidChargeUC = uidCharges.valueAt(i); 14677 if (uidChargeUC == 0) continue; 14678 14679 final Uid uidObj = getAvailableUidStatsLocked(uidInt); 14680 if (uidObj != null) { 14681 uidObj.addChargeToCustomBucketLocked(uidChargeUC, customPowerBucket); 14682 } else { 14683 // Ignore any uid not already known to BatteryStats, rather than creating a new Uid. 14684 // Otherwise we could end up reviving dead Uids. Note that the CPU data is updated 14685 // first, so any uid that has used any CPU should already be known to BatteryStats. 14686 // Recently removed uids (especially common for isolated uids) can reach this path 14687 // and are ignored. 14688 if (!Process.isIsolated(uidInt)) { 14689 Slog.w(TAG, "Received measured charge " + totalChargeUC + " for custom bucket " 14690 + customPowerBucket + " for non-existent uid " + uidInt); 14691 } 14692 } 14693 } 14694 } 14695 14696 /** 14697 * Attributes energy (for the given bucket) to each uid according to the following formula: 14698 * blamedEnergy[uid] = totalEnergy * ratioNumerators[uid] / ratioDenominator; 14699 * <p>Does nothing if ratioDenominator is 0. 14700 * 14701 * <p>Here, ratioDenominator = max(sumOfAllRatioNumerators, minRatioDenominator), 14702 * so if given minRatioDenominator <= 0, then sumOfAllRatioNumerators will be used implicitly. 14703 * 14704 * <p>Note that ratioNumerators and minRatioDenominator must use the same units, but need not 14705 * use the same units as totalConsumedChargeUC (which must be in microcoulombs). 14706 * 14707 * <p>A consequence of minRatioDenominator is that the sum over all uids might be less than 14708 * totalConsumedChargeUC. This is intentional; the remainder is purposefully unnaccounted rather 14709 * than incorrectly blamed on uids, and implies unknown (non-uid) sources of drain. 14710 * 14711 * <p>All uids in ratioNumerators must exist in mUidStats already. 14712 */ 14713 @GuardedBy("this") 14714 @SuppressWarnings("GuardedBy") // errorprone false positive on u.addChargeToStandardBucketLocked 14715 private void distributeEnergyToUidsLocked(@StandardPowerBucket int bucket, 14716 long totalConsumedChargeUC, SparseDoubleArray ratioNumerators, 14717 double minRatioDenominator, long timestampMs) { 14718 14719 // If the sum of all app usage was greater than the total, use that instead: 14720 double sumRatioNumerators = 0; 14721 for (int i = ratioNumerators.size() - 1; i >= 0; i--) { 14722 sumRatioNumerators += ratioNumerators.valueAt(i); 14723 } 14724 final double ratioDenominator = Math.max(sumRatioNumerators, minRatioDenominator); 14725 if (ratioDenominator <= 0) return; 14726 14727 for (int i = ratioNumerators.size() - 1; i >= 0; i--) { 14728 final Uid uid = getAvailableUidStatsLocked(ratioNumerators.keyAt(i)); 14729 final double ratioNumerator = ratioNumerators.valueAt(i); 14730 final long uidActualUC 14731 = (long) (totalConsumedChargeUC * ratioNumerator / ratioDenominator + 0.5); 14732 uid.addChargeToStandardBucketLocked(uidActualUC, bucket, timestampMs); 14733 } 14734 } 14735 14736 /** 14737 * Read and record Rail Energy data. 14738 */ 14739 public void updateRailStatsLocked() { 14740 if (mMeasuredEnergyRetriever == null || !mTmpRailStats.isRailStatsAvailable()) { 14741 return; 14742 } 14743 mMeasuredEnergyRetriever.fillRailDataStats(mTmpRailStats); 14744 } 14745 14746 /** Informs that external stats data has been completely flushed. */ 14747 public void informThatAllExternalStatsAreFlushed() { 14748 synchronized (this) { 14749 // Any data from the pre-reset era is flushed, so we can henceforth process future data. 14750 mIgnoreNextExternalStats = false; 14751 } 14752 } 14753 14754 /** 14755 * Read and distribute kernel wake lock use across apps. 14756 */ 14757 public void updateKernelWakelocksLocked() { 14758 updateKernelWakelocksLocked(mClock.elapsedRealtime() * 1000); 14759 } 14760 14761 /** 14762 * @see #updateKernelWakelocksLocked() 14763 */ 14764 public void updateKernelWakelocksLocked(long elapsedRealtimeUs) { 14765 final KernelWakelockStats wakelockStats = mKernelWakelockReader.readKernelWakelockStats( 14766 mTmpWakelockStats); 14767 if (wakelockStats == null) { 14768 // Not crashing might make board bringup easier. 14769 Slog.w(TAG, "Couldn't get kernel wake lock stats"); 14770 return; 14771 } 14772 14773 for (Map.Entry<String, KernelWakelockStats.Entry> ent : wakelockStats.entrySet()) { 14774 String name = ent.getKey(); 14775 KernelWakelockStats.Entry kws = ent.getValue(); 14776 14777 SamplingTimer kwlt = mKernelWakelockStats.get(name); 14778 if (kwlt == null) { 14779 kwlt = new SamplingTimer(mClock, mOnBatteryScreenOffTimeBase); 14780 mKernelWakelockStats.put(name, kwlt); 14781 } 14782 14783 kwlt.update(kws.mTotalTime, kws.mCount, elapsedRealtimeUs); 14784 kwlt.setUpdateVersion(kws.mVersion); 14785 } 14786 14787 int numWakelocksSetStale = 0; 14788 // Set timers to stale if they didn't appear in /d/wakeup_sources (or /proc/wakelocks) 14789 // this time. 14790 for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) { 14791 SamplingTimer st = ent.getValue(); 14792 if (st.getUpdateVersion() != wakelockStats.kernelWakelockVersion) { 14793 st.endSample(elapsedRealtimeUs); 14794 numWakelocksSetStale++; 14795 } 14796 } 14797 14798 // Record whether we've seen a non-zero time (for debugging b/22716723). 14799 if (wakelockStats.isEmpty()) { 14800 Slog.wtf(TAG, "All kernel wakelocks had time of zero"); 14801 } 14802 14803 if (numWakelocksSetStale == mKernelWakelockStats.size()) { 14804 Slog.wtf(TAG, "All kernel wakelocks were set stale. new version=" + 14805 wakelockStats.kernelWakelockVersion); 14806 } 14807 } 14808 14809 // We use an anonymous class to access these variables, 14810 // so they can't live on the stack or they'd have to be 14811 // final MutableLong objects (more allocations). 14812 // Used in updateCpuTimeLocked(). 14813 long mTempTotalCpuUserTimeUs; 14814 long mTempTotalCpuSystemTimeUs; 14815 long[][] mWakeLockAllocationsUs; 14816 14817 /** 14818 * Reads the newest memory stats from the kernel. 14819 */ 14820 public void updateKernelMemoryBandwidthLocked() { 14821 updateKernelMemoryBandwidthLocked(mClock.elapsedRealtime() * 1000); 14822 } 14823 14824 public void updateKernelMemoryBandwidthLocked(long elapsedRealtimeUs) { 14825 mKernelMemoryBandwidthStats.updateStats(); 14826 LongSparseLongArray bandwidthEntries = mKernelMemoryBandwidthStats.getBandwidthEntries(); 14827 final int bandwidthEntryCount = bandwidthEntries.size(); 14828 int index; 14829 for (int i = 0; i < bandwidthEntryCount; i++) { 14830 SamplingTimer timer; 14831 if ((index = mKernelMemoryStats.indexOfKey(bandwidthEntries.keyAt(i))) >= 0) { 14832 timer = mKernelMemoryStats.valueAt(index); 14833 } else { 14834 timer = new SamplingTimer(mClock, mOnBatteryTimeBase); 14835 mKernelMemoryStats.put(bandwidthEntries.keyAt(i), timer); 14836 } 14837 timer.update(bandwidthEntries.valueAt(i), 1, elapsedRealtimeUs); 14838 if (DEBUG_MEMORY) { 14839 Slog.d(TAG, String.format("Added entry %d and updated timer to: " 14840 + "mUnpluggedReportedTotalTimeUs %d size %d", bandwidthEntries.keyAt(i), 14841 mKernelMemoryStats.get( 14842 bandwidthEntries.keyAt(i)).mUnpluggedReportedTotalTimeUs, 14843 mKernelMemoryStats.size())); 14844 } 14845 } 14846 } 14847 14848 public boolean isOnBatteryLocked() { 14849 return mOnBatteryTimeBase.isRunning(); 14850 } 14851 14852 public boolean isOnBatteryScreenOffLocked() { 14853 return mOnBatteryScreenOffTimeBase.isRunning(); 14854 } 14855 14856 /** 14857 * Object for calculating and accumulating the estimated cpu power used while reading the 14858 * various cpu kernel files. 14859 */ 14860 @VisibleForTesting 14861 public static class CpuDeltaPowerAccumulator { 14862 // Keeps track of total charge used per cluster. 14863 public final double[] totalClusterChargesMah; 14864 // Keeps track of charge used per cluster per uid. 14865 public final ArrayMap<Uid, double[]> perUidCpuClusterChargesMah; 14866 14867 private final CpuPowerCalculator mCalculator; 14868 private Uid mCachedUid = null; 14869 private double[] mUidClusterCache = null; 14870 14871 CpuDeltaPowerAccumulator(CpuPowerCalculator calculator, int nClusters) { 14872 mCalculator = calculator; 14873 totalClusterChargesMah = new double[nClusters]; 14874 perUidCpuClusterChargesMah = new ArrayMap<>(); 14875 } 14876 14877 /** Add per cpu cluster durations to the currently cached uid. */ 14878 public void addCpuClusterDurationsMs(Uid uid, long[] durationsMs) { 14879 final double[] uidChargesMah = getOrCreateUidCpuClusterCharges(uid); 14880 for (int cluster = 0; cluster < durationsMs.length; cluster++) { 14881 final double estimatedDeltaMah = mCalculator.calculatePerCpuClusterPowerMah(cluster, 14882 durationsMs[cluster]); 14883 uidChargesMah[cluster] += estimatedDeltaMah; 14884 totalClusterChargesMah[cluster] += estimatedDeltaMah; 14885 } 14886 } 14887 14888 /** Add per speed per cpu cluster durations to the currently cached uid. */ 14889 public void addCpuClusterSpeedDurationsMs(Uid uid, int cluster, int speed, 14890 long durationsMs) { 14891 final double[] uidChargesMah = getOrCreateUidCpuClusterCharges(uid); 14892 final double estimatedDeltaMah = mCalculator.calculatePerCpuFreqPowerMah(cluster, speed, 14893 durationsMs); 14894 uidChargesMah[cluster] += estimatedDeltaMah; 14895 totalClusterChargesMah[cluster] += estimatedDeltaMah; 14896 } 14897 14898 private double[] getOrCreateUidCpuClusterCharges(Uid uid) { 14899 // Repeated additions on the same uid is very likely. 14900 // Skip a lookup if getting the same uid as the last get. 14901 if (uid == mCachedUid) return mUidClusterCache; 14902 14903 double[] uidChargesMah = perUidCpuClusterChargesMah.get(uid); 14904 if (uidChargesMah == null) { 14905 uidChargesMah = new double[totalClusterChargesMah.length]; 14906 perUidCpuClusterChargesMah.put(uid, uidChargesMah); 14907 } 14908 mCachedUid = uid; 14909 mUidClusterCache = uidChargesMah; 14910 return uidChargesMah; 14911 } 14912 } 14913 14914 /** 14915 * Read and distribute CPU usage across apps. If their are partial wakelocks being held 14916 * and we are on battery with screen off, we give more of the cpu time to those apps holding 14917 * wakelocks. If the screen is on, we just assign the actual cpu time an app used. 14918 * It's possible this will be invoked after the internal battery/screen states are updated, so 14919 * passing the appropriate battery/screen states to try attribute the cpu times to correct 14920 * buckets. 14921 */ 14922 @GuardedBy("this") 14923 public void updateCpuTimeLocked(boolean onBattery, boolean onBatteryScreenOff, 14924 long[] measuredCpuClusterChargeUC) { 14925 if (mPowerProfile == null) { 14926 return; 14927 } 14928 14929 if (DEBUG_ENERGY_CPU) { 14930 Slog.d(TAG, "!Cpu updating!"); 14931 } 14932 14933 if (mCpuFreqs == null) { 14934 mCpuFreqs = mCpuUidFreqTimeReader.readFreqs(mPowerProfile); 14935 } 14936 14937 // Calculate the wakelocks we have to distribute amongst. The system is excluded as it is 14938 // usually holding the wakelock on behalf of an app. 14939 // And Only distribute cpu power to wakelocks if the screen is off and we're on battery. 14940 ArrayList<StopwatchTimer> partialTimersToConsider = null; 14941 if (onBatteryScreenOff) { 14942 partialTimersToConsider = new ArrayList<>(); 14943 for (int i = mPartialTimers.size() - 1; i >= 0; --i) { 14944 final StopwatchTimer timer = mPartialTimers.get(i); 14945 // Since the collection and blaming of wakelocks can be scheduled to run after 14946 // some delay, the mPartialTimers list may have new entries. We can't blame 14947 // the newly added timer for past cpu time, so we only consider timers that 14948 // were present for one round of collection. Once a timer has gone through 14949 // a round of collection, its mInList field is set to true. 14950 if (timer.mInList && timer.mUid != null && timer.mUid.mUid != Process.SYSTEM_UID) { 14951 partialTimersToConsider.add(timer); 14952 } 14953 } 14954 } 14955 markPartialTimersAsEligible(); 14956 14957 // When the battery is not on, we don't attribute the cpu times to any timers but we still 14958 // need to take the snapshots. 14959 if (!onBattery) { 14960 mCpuUidUserSysTimeReader.readDelta(false, null); 14961 mCpuUidFreqTimeReader.readDelta(false, null); 14962 mNumAllUidCpuTimeReads += 2; 14963 if (mConstants.TRACK_CPU_ACTIVE_CLUSTER_TIME) { 14964 mCpuUidActiveTimeReader.readDelta(false, null); 14965 mCpuUidClusterTimeReader.readDelta(false, null); 14966 mNumAllUidCpuTimeReads += 2; 14967 } 14968 for (int cluster = mKernelCpuSpeedReaders.length - 1; cluster >= 0; --cluster) { 14969 mKernelCpuSpeedReaders[cluster].readDelta(); 14970 } 14971 mSystemServerCpuThreadReader.readDelta(); 14972 return; 14973 } 14974 14975 mUserInfoProvider.refreshUserIds(); 14976 final SparseLongArray updatedUids = mCpuUidFreqTimeReader.perClusterTimesAvailable() 14977 ? null : new SparseLongArray(); 14978 14979 final CpuDeltaPowerAccumulator powerAccumulator; 14980 if (mGlobalMeasuredEnergyStats != null 14981 && mGlobalMeasuredEnergyStats.isStandardBucketSupported( 14982 MeasuredEnergyStats.POWER_BUCKET_CPU) && mCpuPowerCalculator != null) { 14983 if (measuredCpuClusterChargeUC == null) { 14984 Slog.wtf(TAG, 14985 "POWER_BUCKET_CPU supported but no measured Cpu Cluster charge reported " 14986 + "on updateCpuTimeLocked!"); 14987 powerAccumulator = null; 14988 } else { 14989 // Cpu Measured Energy is supported, create an object to accumulate the estimated 14990 // charge consumption since the last cpu update 14991 final int numClusters = mPowerProfile.getNumCpuClusters(); 14992 powerAccumulator = new CpuDeltaPowerAccumulator(mCpuPowerCalculator, numClusters); 14993 } 14994 } else { 14995 powerAccumulator = null; 14996 } 14997 14998 readKernelUidCpuTimesLocked(partialTimersToConsider, updatedUids, onBattery); 14999 // updatedUids=null means /proc/uid_time_in_state provides snapshots of per-cluster cpu 15000 // freqs, so no need to approximate these values. 15001 if (updatedUids != null) { 15002 updateClusterSpeedTimes(updatedUids, onBattery, powerAccumulator); 15003 } 15004 readKernelUidCpuFreqTimesLocked(partialTimersToConsider, onBattery, onBatteryScreenOff, 15005 powerAccumulator); 15006 mNumAllUidCpuTimeReads += 2; 15007 if (mConstants.TRACK_CPU_ACTIVE_CLUSTER_TIME) { 15008 // Cpu Active times do not get any info ony how to attribute measured Cpu Cluster 15009 // charge, so not need to provide the powerAccumulator 15010 readKernelUidCpuActiveTimesLocked(onBattery); 15011 readKernelUidCpuClusterTimesLocked(onBattery, powerAccumulator); 15012 mNumAllUidCpuTimeReads += 2; 15013 } 15014 15015 updateSystemServerThreadStats(); 15016 15017 if (powerAccumulator != null) { 15018 updateCpuMeasuredEnergyStatsLocked(measuredCpuClusterChargeUC, powerAccumulator); 15019 } 15020 } 15021 15022 /** 15023 * Estimates the proportion of the System Server CPU activity (per cluster per speed) 15024 * spent on handling incoming binder calls. 15025 */ 15026 @VisibleForTesting 15027 public void updateSystemServerThreadStats() { 15028 // There are some simplifying assumptions made in this algorithm 15029 // 1) We assume that if a thread handles incoming binder calls, all of its activity 15030 // is spent doing that. Most incoming calls are handled by threads allocated 15031 // by the native layer in the binder thread pool, so this assumption is reasonable. 15032 // 2) We use the aggregate CPU time spent in different threads as a proxy for the CPU 15033 // cost. In reality, in multi-core CPUs, the CPU cost may not be linearly 15034 // affected by additional threads. 15035 15036 SystemServerCpuThreadReader.SystemServiceCpuThreadTimes systemServiceCpuThreadTimes = 15037 mSystemServerCpuThreadReader.readDelta(); 15038 if (systemServiceCpuThreadTimes == null) { 15039 return; 15040 } 15041 15042 if (mBinderThreadCpuTimesUs == null) { 15043 mBinderThreadCpuTimesUs = new LongSamplingCounterArray(mOnBatteryTimeBase); 15044 } 15045 mBinderThreadCpuTimesUs.addCountLocked(systemServiceCpuThreadTimes.binderThreadCpuTimesUs); 15046 15047 if (DEBUG_BINDER_STATS) { 15048 Slog.d(TAG, "System server threads per CPU cluster (incoming binder threads)"); 15049 long binderThreadTimeMs = 0; 15050 int cpuIndex = 0; 15051 final long[] binderThreadCpuTimesUs = mBinderThreadCpuTimesUs.getCountsLocked( 15052 BatteryStats.STATS_SINCE_CHARGED); 15053 int index = 0; 15054 int numCpuClusters = mPowerProfile.getNumCpuClusters(); 15055 for (int cluster = 0; cluster < numCpuClusters; cluster++) { 15056 StringBuilder sb = new StringBuilder(); 15057 sb.append("cpu").append(cpuIndex).append(": ["); 15058 int numSpeeds = mPowerProfile.getNumSpeedStepsInCpuCluster(cluster); 15059 for (int speed = 0; speed < numSpeeds; speed++) { 15060 if (speed != 0) { 15061 sb.append(", "); 15062 } 15063 long binderCountMs = binderThreadCpuTimesUs[index] / 1000; 15064 sb.append(TextUtils.formatSimple("%10d", binderCountMs)); 15065 15066 binderThreadTimeMs += binderCountMs; 15067 index++; 15068 } 15069 cpuIndex += mPowerProfile.getNumCoresInCpuCluster(cluster); 15070 Slog.d(TAG, sb.toString()); 15071 } 15072 } 15073 } 15074 15075 /** 15076 * Mark the current partial timers as gone through a collection so that they will be 15077 * considered in the next cpu times distribution to wakelock holders. 15078 */ 15079 @VisibleForTesting 15080 public void markPartialTimersAsEligible() { 15081 if (ArrayUtils.referenceEquals(mPartialTimers, mLastPartialTimers)) { 15082 // No difference, so each timer is now considered for the next collection. 15083 for (int i = mPartialTimers.size() - 1; i >= 0; --i) { 15084 mPartialTimers.get(i).mInList = true; 15085 } 15086 } else { 15087 // The lists are different, meaning we added (or removed a timer) since the last 15088 // collection. 15089 for (int i = mLastPartialTimers.size() - 1; i >= 0; --i) { 15090 mLastPartialTimers.get(i).mInList = false; 15091 } 15092 mLastPartialTimers.clear(); 15093 15094 // Mark the current timers as gone through a collection. 15095 final int numPartialTimers = mPartialTimers.size(); 15096 for (int i = 0; i < numPartialTimers; ++i) { 15097 final StopwatchTimer timer = mPartialTimers.get(i); 15098 timer.mInList = true; 15099 mLastPartialTimers.add(timer); 15100 } 15101 } 15102 } 15103 15104 /** 15105 * Take snapshot of cpu times (aggregated over all uids) at different frequencies and 15106 * calculate cpu times spent by each uid at different frequencies. Will also add estimated 15107 * power consumptions, if powerAccumulator data structure is provided. 15108 * 15109 * @param updatedUids The uids for which times spent at different frequencies are calculated. 15110 * @param onBattery whether or not this is onBattery 15111 * @param powerAccumulator object to accumulate the estimated cluster charge consumption. 15112 */ 15113 @VisibleForTesting 15114 public void updateClusterSpeedTimes(@NonNull SparseLongArray updatedUids, boolean onBattery, 15115 @Nullable CpuDeltaPowerAccumulator powerAccumulator) { 15116 long totalCpuClustersTimeMs = 0; 15117 // Read the time spent for each cluster at various cpu frequencies. 15118 final long[][] clusterSpeedTimesMs = new long[mKernelCpuSpeedReaders.length][]; 15119 for (int cluster = 0; cluster < mKernelCpuSpeedReaders.length; cluster++) { 15120 clusterSpeedTimesMs[cluster] = mKernelCpuSpeedReaders[cluster].readDelta(); 15121 if (clusterSpeedTimesMs[cluster] != null) { 15122 for (int speed = clusterSpeedTimesMs[cluster].length - 1; speed >= 0; --speed) { 15123 totalCpuClustersTimeMs += clusterSpeedTimesMs[cluster][speed]; 15124 } 15125 } 15126 } 15127 if (totalCpuClustersTimeMs != 0) { 15128 // We have cpu times per freq aggregated over all uids but we need the times per uid. 15129 // So, we distribute total time spent by an uid to different cpu freqs based on the 15130 // amount of time cpu was running at that freq. 15131 final int updatedUidsCount = updatedUids.size(); 15132 final long elapsedRealtimeMs = mClock.elapsedRealtime(); 15133 final long uptimeMs = mClock.uptimeMillis(); 15134 for (int i = 0; i < updatedUidsCount; ++i) { 15135 final Uid u = getUidStatsLocked(updatedUids.keyAt(i), elapsedRealtimeMs, uptimeMs); 15136 final long appCpuTimeUs = updatedUids.valueAt(i); 15137 // Add the cpu speeds to this UID. 15138 final int numClusters = mPowerProfile.getNumCpuClusters(); 15139 if (u.mCpuClusterSpeedTimesUs == null || 15140 u.mCpuClusterSpeedTimesUs.length != numClusters) { 15141 u.mCpuClusterSpeedTimesUs = new LongSamplingCounter[numClusters][]; 15142 } 15143 15144 for (int cluster = 0; cluster < clusterSpeedTimesMs.length; cluster++) { 15145 final int speedsInCluster = clusterSpeedTimesMs[cluster].length; 15146 if (u.mCpuClusterSpeedTimesUs[cluster] == null || speedsInCluster != 15147 u.mCpuClusterSpeedTimesUs[cluster].length) { 15148 u.mCpuClusterSpeedTimesUs[cluster] 15149 = new LongSamplingCounter[speedsInCluster]; 15150 } 15151 15152 final LongSamplingCounter[] cpuSpeeds = u.mCpuClusterSpeedTimesUs[cluster]; 15153 for (int speed = 0; speed < speedsInCluster; speed++) { 15154 if (cpuSpeeds[speed] == null) { 15155 cpuSpeeds[speed] = new LongSamplingCounter(mOnBatteryTimeBase); 15156 } 15157 final long deltaSpeedCount = appCpuTimeUs 15158 * clusterSpeedTimesMs[cluster][speed] 15159 / totalCpuClustersTimeMs; 15160 cpuSpeeds[speed].addCountLocked(deltaSpeedCount, onBattery); 15161 15162 if (powerAccumulator != null) { 15163 powerAccumulator.addCpuClusterSpeedDurationsMs(u, cluster, 15164 speed, deltaSpeedCount); 15165 } 15166 } 15167 } 15168 } 15169 } 15170 } 15171 15172 /** 15173 * Take a snapshot of the cpu times spent by each uid and update the corresponding counters. 15174 * If {@param partialTimers} is not null and empty, then we assign a portion of cpu times to 15175 * wakelock holders. 15176 * 15177 * @param partialTimers The wakelock holders among which the cpu times will be distributed. 15178 * @param updatedUids If not null, then the uids found in the snapshot will be added to this. 15179 */ 15180 @VisibleForTesting 15181 public void readKernelUidCpuTimesLocked(@Nullable ArrayList<StopwatchTimer> partialTimers, 15182 @Nullable SparseLongArray updatedUids, boolean onBattery) { 15183 mTempTotalCpuUserTimeUs = mTempTotalCpuSystemTimeUs = 0; 15184 final int numWakelocks = partialTimers == null ? 0 : partialTimers.size(); 15185 final long startTimeMs = mClock.uptimeMillis(); 15186 final long elapsedRealtimeMs = mClock.elapsedRealtime(); 15187 15188 mCpuUidUserSysTimeReader.readDelta(false, (uid, timesUs) -> { 15189 long userTimeUs = timesUs[0], systemTimeUs = timesUs[1]; 15190 15191 uid = mapUid(uid); 15192 if (Process.isIsolated(uid)) { 15193 // This could happen if the isolated uid mapping was removed before that process 15194 // was actually killed. 15195 if (DEBUG) Slog.d(TAG, "Got readings for an isolated uid: " + uid); 15196 return; 15197 } 15198 if (!mUserInfoProvider.exists(UserHandle.getUserId(uid))) { 15199 if (DEBUG) Slog.d(TAG, "Got readings for an invalid user's uid " + uid); 15200 return; 15201 } 15202 final Uid u = getUidStatsLocked(uid, elapsedRealtimeMs, startTimeMs); 15203 15204 // Accumulate the total system and user time. 15205 mTempTotalCpuUserTimeUs += userTimeUs; 15206 mTempTotalCpuSystemTimeUs += systemTimeUs; 15207 15208 StringBuilder sb = null; 15209 if (DEBUG_ENERGY_CPU) { 15210 sb = new StringBuilder(); 15211 sb.append(" got time for uid=").append(u.mUid).append(": u="); 15212 TimeUtils.formatDuration(userTimeUs / 1000, sb); 15213 sb.append(" s="); 15214 TimeUtils.formatDuration(systemTimeUs / 1000, sb); 15215 sb.append("\n"); 15216 } 15217 15218 if (numWakelocks > 0) { 15219 // We have wakelocks being held, so only give a portion of the 15220 // time to the process. The rest will be distributed among wakelock 15221 // holders. 15222 userTimeUs = (userTimeUs * WAKE_LOCK_WEIGHT) / 100; 15223 systemTimeUs = (systemTimeUs * WAKE_LOCK_WEIGHT) / 100; 15224 } 15225 15226 if (sb != null) { 15227 sb.append(" adding to uid=").append(u.mUid).append(": u="); 15228 TimeUtils.formatDuration(userTimeUs / 1000, sb); 15229 sb.append(" s="); 15230 TimeUtils.formatDuration(systemTimeUs / 1000, sb); 15231 Slog.d(TAG, sb.toString()); 15232 } 15233 15234 u.mUserCpuTime.addCountLocked(userTimeUs, onBattery); 15235 u.mSystemCpuTime.addCountLocked(systemTimeUs, onBattery); 15236 if (updatedUids != null) { 15237 updatedUids.put(u.getUid(), userTimeUs + systemTimeUs); 15238 } 15239 }); 15240 15241 final long elapsedTimeMs = mClock.uptimeMillis() - startTimeMs; 15242 if (DEBUG_ENERGY_CPU || elapsedTimeMs >= 100) { 15243 Slog.d(TAG, "Reading cpu stats took " + elapsedTimeMs + "ms"); 15244 } 15245 15246 if (numWakelocks > 0) { 15247 // Distribute a portion of the total cpu time to wakelock holders. 15248 mTempTotalCpuUserTimeUs = (mTempTotalCpuUserTimeUs * (100 - WAKE_LOCK_WEIGHT)) / 100; 15249 mTempTotalCpuSystemTimeUs = 15250 (mTempTotalCpuSystemTimeUs * (100 - WAKE_LOCK_WEIGHT)) / 100; 15251 15252 for (int i = 0; i < numWakelocks; ++i) { 15253 final StopwatchTimer timer = partialTimers.get(i); 15254 final int userTimeUs = (int) (mTempTotalCpuUserTimeUs / (numWakelocks - i)); 15255 final int systemTimeUs = (int) (mTempTotalCpuSystemTimeUs / (numWakelocks - i)); 15256 15257 if (DEBUG_ENERGY_CPU) { 15258 final StringBuilder sb = new StringBuilder(); 15259 sb.append(" Distributing wakelock uid=").append(timer.mUid.mUid) 15260 .append(": u="); 15261 TimeUtils.formatDuration(userTimeUs / 1000, sb); 15262 sb.append(" s="); 15263 TimeUtils.formatDuration(systemTimeUs / 1000, sb); 15264 Slog.d(TAG, sb.toString()); 15265 } 15266 15267 timer.mUid.mUserCpuTime.addCountLocked(userTimeUs, onBattery); 15268 timer.mUid.mSystemCpuTime.addCountLocked(systemTimeUs, onBattery); 15269 if (updatedUids != null) { 15270 final int uid = timer.mUid.getUid(); 15271 updatedUids.put(uid, updatedUids.get(uid, 0) + userTimeUs + systemTimeUs); 15272 } 15273 15274 final Uid.Proc proc = timer.mUid.getProcessStatsLocked("*wakelock*"); 15275 proc.addCpuTimeLocked(userTimeUs / 1000, systemTimeUs / 1000, onBattery); 15276 15277 mTempTotalCpuUserTimeUs -= userTimeUs; 15278 mTempTotalCpuSystemTimeUs -= systemTimeUs; 15279 } 15280 } 15281 } 15282 15283 /** 15284 * Take a snapshot of the cpu times spent by each uid in each freq and update the 15285 * corresponding counters. Will also add estimated power consumptions, if powerAccumulator 15286 * data structure is provided. 15287 * 15288 * @param partialTimers The wakelock holders among which the cpu freq times will be distributed. 15289 * @param onBattery whether or not this is onBattery 15290 * @param onBatteryScreenOff whether or not this is onBattery with the screen off. 15291 * @param powerAccumulator object to accumulate the estimated cluster charge consumption. 15292 */ 15293 @VisibleForTesting 15294 public void readKernelUidCpuFreqTimesLocked(@Nullable ArrayList<StopwatchTimer> partialTimers, 15295 boolean onBattery, boolean onBatteryScreenOff, 15296 @Nullable CpuDeltaPowerAccumulator powerAccumulator) { 15297 final boolean perClusterTimesAvailable = 15298 mCpuUidFreqTimeReader.perClusterTimesAvailable(); 15299 final int numWakelocks = partialTimers == null ? 0 : partialTimers.size(); 15300 final int numClusters = mPowerProfile.getNumCpuClusters(); 15301 mWakeLockAllocationsUs = null; 15302 final long startTimeMs = mClock.uptimeMillis(); 15303 final long elapsedRealtimeMs = mClock.elapsedRealtime(); 15304 // If power is being accumulated for attribution, data needs to be read immediately. 15305 final boolean forceRead = powerAccumulator != null; 15306 mCpuUidFreqTimeReader.readDelta(forceRead, (uid, cpuFreqTimeMs) -> { 15307 uid = mapUid(uid); 15308 if (Process.isIsolated(uid)) { 15309 if (DEBUG) Slog.d(TAG, "Got freq readings for an isolated uid: " + uid); 15310 return; 15311 } 15312 if (!mUserInfoProvider.exists(UserHandle.getUserId(uid))) { 15313 if (DEBUG) Slog.d(TAG, "Got freq readings for an invalid user's uid " + uid); 15314 return; 15315 } 15316 final Uid u = getUidStatsLocked(uid, elapsedRealtimeMs, startTimeMs); 15317 if (u.mCpuFreqTimeMs == null || u.mCpuFreqTimeMs.getSize() != cpuFreqTimeMs.length) { 15318 detachIfNotNull(u.mCpuFreqTimeMs); 15319 u.mCpuFreqTimeMs = new LongSamplingCounterArray(mOnBatteryTimeBase); 15320 } 15321 u.mCpuFreqTimeMs.addCountLocked(cpuFreqTimeMs, onBattery); 15322 if (u.mScreenOffCpuFreqTimeMs == null || 15323 u.mScreenOffCpuFreqTimeMs.getSize() != cpuFreqTimeMs.length) { 15324 detachIfNotNull(u.mScreenOffCpuFreqTimeMs); 15325 u.mScreenOffCpuFreqTimeMs = new LongSamplingCounterArray( 15326 mOnBatteryScreenOffTimeBase); 15327 } 15328 u.mScreenOffCpuFreqTimeMs.addCountLocked(cpuFreqTimeMs, onBatteryScreenOff); 15329 15330 if (perClusterTimesAvailable) { 15331 if (u.mCpuClusterSpeedTimesUs == null || 15332 u.mCpuClusterSpeedTimesUs.length != numClusters) { 15333 detachIfNotNull(u.mCpuClusterSpeedTimesUs); 15334 u.mCpuClusterSpeedTimesUs = new LongSamplingCounter[numClusters][]; 15335 } 15336 if (numWakelocks > 0 && mWakeLockAllocationsUs == null) { 15337 mWakeLockAllocationsUs = new long[numClusters][]; 15338 } 15339 15340 int freqIndex = 0; 15341 for (int cluster = 0; cluster < numClusters; ++cluster) { 15342 final int speedsInCluster = mPowerProfile.getNumSpeedStepsInCpuCluster(cluster); 15343 if (u.mCpuClusterSpeedTimesUs[cluster] == null || 15344 u.mCpuClusterSpeedTimesUs[cluster].length != speedsInCluster) { 15345 detachIfNotNull(u.mCpuClusterSpeedTimesUs[cluster]); 15346 u.mCpuClusterSpeedTimesUs[cluster] 15347 = new LongSamplingCounter[speedsInCluster]; 15348 } 15349 if (numWakelocks > 0 && mWakeLockAllocationsUs[cluster] == null) { 15350 mWakeLockAllocationsUs[cluster] = new long[speedsInCluster]; 15351 } 15352 final LongSamplingCounter[] cpuTimesUs = u.mCpuClusterSpeedTimesUs[cluster]; 15353 for (int speed = 0; speed < speedsInCluster; ++speed) { 15354 if (cpuTimesUs[speed] == null) { 15355 cpuTimesUs[speed] = new LongSamplingCounter(mOnBatteryTimeBase); 15356 } 15357 final long appAllocationUs; 15358 if (mWakeLockAllocationsUs != null) { 15359 appAllocationUs = 15360 (cpuFreqTimeMs[freqIndex] * 1000 * WAKE_LOCK_WEIGHT) / 100; 15361 mWakeLockAllocationsUs[cluster][speed] += 15362 (cpuFreqTimeMs[freqIndex] * 1000 - appAllocationUs); 15363 } else { 15364 appAllocationUs = cpuFreqTimeMs[freqIndex] * 1000; 15365 } 15366 cpuTimesUs[speed].addCountLocked(appAllocationUs, onBattery); 15367 15368 if (powerAccumulator != null) { 15369 powerAccumulator.addCpuClusterSpeedDurationsMs(u, cluster, 15370 speed, appAllocationUs / 1000); 15371 } 15372 freqIndex++; 15373 } 15374 } 15375 } 15376 }); 15377 15378 final long elapsedTimeMs = mClock.uptimeMillis() - startTimeMs; 15379 if (DEBUG_ENERGY_CPU || elapsedTimeMs >= 100) { 15380 Slog.d(TAG, "Reading cpu freq times took " + elapsedTimeMs + "ms"); 15381 } 15382 15383 if (mWakeLockAllocationsUs != null) { 15384 for (int i = 0; i < numWakelocks; ++i) { 15385 final Uid u = partialTimers.get(i).mUid; 15386 if (u.mCpuClusterSpeedTimesUs == null || 15387 u.mCpuClusterSpeedTimesUs.length != numClusters) { 15388 detachIfNotNull(u.mCpuClusterSpeedTimesUs); 15389 u.mCpuClusterSpeedTimesUs = new LongSamplingCounter[numClusters][]; 15390 } 15391 15392 for (int cluster = 0; cluster < numClusters; ++cluster) { 15393 final int speedsInCluster = mPowerProfile.getNumSpeedStepsInCpuCluster(cluster); 15394 if (u.mCpuClusterSpeedTimesUs[cluster] == null || 15395 u.mCpuClusterSpeedTimesUs[cluster].length != speedsInCluster) { 15396 detachIfNotNull(u.mCpuClusterSpeedTimesUs[cluster]); 15397 u.mCpuClusterSpeedTimesUs[cluster] 15398 = new LongSamplingCounter[speedsInCluster]; 15399 } 15400 final LongSamplingCounter[] cpuTimeUs = u.mCpuClusterSpeedTimesUs[cluster]; 15401 for (int speed = 0; speed < speedsInCluster; ++speed) { 15402 if (cpuTimeUs[speed] == null) { 15403 cpuTimeUs[speed] = new LongSamplingCounter(mOnBatteryTimeBase); 15404 } 15405 final long allocationUs = 15406 mWakeLockAllocationsUs[cluster][speed] / (numWakelocks - i); 15407 cpuTimeUs[speed].addCountLocked(allocationUs, onBattery); 15408 mWakeLockAllocationsUs[cluster][speed] -= allocationUs; 15409 15410 if (powerAccumulator != null) { 15411 powerAccumulator.addCpuClusterSpeedDurationsMs(u, cluster, 15412 speed, allocationUs / 1000); 15413 } 15414 } 15415 } 15416 } 15417 } 15418 } 15419 15420 /** 15421 * Take a snapshot of the cpu active times spent by each uid and update the corresponding 15422 * counters. 15423 */ 15424 @VisibleForTesting 15425 public void readKernelUidCpuActiveTimesLocked(boolean onBattery) { 15426 final long startTimeMs = mClock.uptimeMillis(); 15427 final long elapsedRealtimeMs = mClock.elapsedRealtime(); 15428 mCpuUidActiveTimeReader.readAbsolute((uid, cpuActiveTimesMs) -> { 15429 final int parentUid = mapUid(uid); 15430 if (Process.isIsolated(parentUid)) { 15431 if (DEBUG) Slog.w(TAG, "Got active times for an isolated uid: " + uid); 15432 return; 15433 } 15434 if (!mUserInfoProvider.exists(UserHandle.getUserId(uid))) { 15435 if (DEBUG) Slog.w(TAG, "Got active times for an invalid user's uid " + uid); 15436 return; 15437 } 15438 final Uid u = getUidStatsLocked(parentUid, elapsedRealtimeMs, startTimeMs); 15439 if (parentUid == uid) { 15440 u.getCpuActiveTimeCounter().update(cpuActiveTimesMs, elapsedRealtimeMs); 15441 } else { 15442 final SparseArray<Uid.ChildUid> childUids = u.mChildUids; 15443 if (childUids == null) { 15444 return; 15445 } 15446 15447 Uid.ChildUid childUid = childUids.get(uid); 15448 if (childUid != null) { 15449 final long delta = 15450 childUid.cpuActiveCounter.update(cpuActiveTimesMs, elapsedRealtimeMs); 15451 u.getCpuActiveTimeCounter().increment(delta, elapsedRealtimeMs); 15452 } 15453 } 15454 }); 15455 15456 final long elapsedTimeMs = mClock.uptimeMillis() - startTimeMs; 15457 if (DEBUG_ENERGY_CPU || elapsedTimeMs >= 100) { 15458 Slog.d(TAG, "Reading cpu active times took " + elapsedTimeMs + "ms"); 15459 } 15460 } 15461 15462 /** 15463 * Take a snapshot of the cpu cluster times spent by each uid and update the corresponding 15464 * counters. Will also add estimated power consumptions, if powerAccumulator data structure 15465 * is provided. 15466 * 15467 * @param onBattery whether or not this is onBattery 15468 * @param powerAccumulator object to accumulate the estimated cluster charge consumption. 15469 */ 15470 @VisibleForTesting 15471 public void readKernelUidCpuClusterTimesLocked(boolean onBattery, 15472 @Nullable CpuDeltaPowerAccumulator powerAccumulator) { 15473 final long startTimeMs = mClock.uptimeMillis(); 15474 final long elapsedRealtimeMs = mClock.elapsedRealtime(); 15475 // If power is being accumulated for attribution, data needs to be read immediately. 15476 final boolean forceRead = powerAccumulator != null; 15477 mCpuUidClusterTimeReader.readDelta(forceRead, (uid, cpuClusterTimesMs) -> { 15478 uid = mapUid(uid); 15479 if (Process.isIsolated(uid)) { 15480 if (DEBUG) Slog.w(TAG, "Got cluster times for an isolated uid: " + uid); 15481 return; 15482 } 15483 if (!mUserInfoProvider.exists(UserHandle.getUserId(uid))) { 15484 if (DEBUG) Slog.w(TAG, "Got cluster times for an invalid user's uid " + uid); 15485 return; 15486 } 15487 final Uid u = getUidStatsLocked(uid, elapsedRealtimeMs, startTimeMs); 15488 u.mCpuClusterTimesMs.addCountLocked(cpuClusterTimesMs, onBattery); 15489 15490 if (powerAccumulator != null) { 15491 powerAccumulator.addCpuClusterDurationsMs(u, cpuClusterTimesMs); 15492 } 15493 }); 15494 15495 final long elapsedTimeMs = mClock.uptimeMillis() - startTimeMs; 15496 if (DEBUG_ENERGY_CPU || elapsedTimeMs >= 100) { 15497 Slog.d(TAG, "Reading cpu cluster times took " + elapsedTimeMs + "ms"); 15498 } 15499 } 15500 15501 boolean setChargingLocked(boolean charging) { 15502 // if the device is no longer charging, remove the callback 15503 // if the device is now charging, it means that this is either called 15504 // 1. directly when level >= 90 15505 // 2. or from within the runnable that we deferred 15506 // For 1. if we have an existing callback, remove it, since we will immediately send a 15507 // ACTION_CHARGING 15508 // For 2. we remove existing callback so we don't send multiple ACTION_CHARGING 15509 mHandler.removeCallbacks(mDeferSetCharging); 15510 if (mCharging != charging) { 15511 mCharging = charging; 15512 if (charging) { 15513 mHistoryCur.states2 |= HistoryItem.STATE2_CHARGING_FLAG; 15514 } else { 15515 mHistoryCur.states2 &= ~HistoryItem.STATE2_CHARGING_FLAG; 15516 } 15517 mHandler.sendEmptyMessage(MSG_REPORT_CHARGING); 15518 return true; 15519 } 15520 return false; 15521 } 15522 15523 /** 15524 * Notifies BatteryStatsImpl that the system server is ready. 15525 */ 15526 public void onSystemReady() { 15527 mSystemReady = true; 15528 } 15529 15530 @GuardedBy("this") 15531 protected void setOnBatteryLocked(final long mSecRealtime, final long mSecUptime, 15532 final boolean onBattery, final int oldStatus, final int level, final int chargeUah) { 15533 boolean doWrite = false; 15534 Message m = mHandler.obtainMessage(MSG_REPORT_POWER_CHANGE); 15535 m.arg1 = onBattery ? 1 : 0; 15536 mHandler.sendMessage(m); 15537 15538 final long uptimeUs = mSecUptime * 1000; 15539 final long realtimeUs = mSecRealtime * 1000; 15540 final int screenState = mScreenState; 15541 if (onBattery) { 15542 // We will reset our status if we are unplugging after the 15543 // battery was last full, or the level is at 100, or 15544 // we have gone through a significant charge (from a very low 15545 // level to a now very high level). 15546 // Also, we will reset the stats if battery got partially charged 15547 // and discharged repeatedly without ever reaching the full charge. 15548 // This reset is done in order to prevent stats sessions from going on forever. 15549 // Exceedingly long battery sessions would lead to an overflow of 15550 // data structures such as mWakeupReasonStats. 15551 boolean reset = false; 15552 if (!mNoAutoReset && mSystemReady 15553 && (oldStatus == BatteryManager.BATTERY_STATUS_FULL 15554 || level >= 90 15555 || (mDischargeCurrentLevel < 20 && level >= 80) 15556 || getHighDischargeAmountSinceCharge() >= 200)) { 15557 Slog.i(TAG, "Resetting battery stats: level=" + level + " status=" + oldStatus 15558 + " dischargeLevel=" + mDischargeCurrentLevel 15559 + " lowAmount=" + getLowDischargeAmountSinceCharge() 15560 + " highAmount=" + getHighDischargeAmountSinceCharge()); 15561 // Before we write, collect a snapshot of the final aggregated 15562 // stats to be reported in the next checkin. Only do this if we have 15563 // a sufficient amount of data to make it interesting. 15564 if (getLowDischargeAmountSinceCharge() >= 20) { 15565 final long startTimeMs = SystemClock.uptimeMillis(); 15566 final Parcel parcel = Parcel.obtain(); 15567 writeSummaryToParcel(parcel, true); 15568 final long initialTimeMs = SystemClock.uptimeMillis() - startTimeMs; 15569 BackgroundThread.getHandler().post(new Runnable() { 15570 @Override public void run() { 15571 synchronized (mCheckinFile) { 15572 final long startTimeMs2 = SystemClock.uptimeMillis(); 15573 FileOutputStream stream = null; 15574 try { 15575 stream = mCheckinFile.startWrite(); 15576 stream.write(parcel.marshall()); 15577 stream.flush(); 15578 mCheckinFile.finishWrite(stream); 15579 com.android.internal.logging.EventLogTags.writeCommitSysConfigFile( 15580 "batterystats-checkin", initialTimeMs 15581 + SystemClock.uptimeMillis() - startTimeMs2); 15582 } catch (IOException e) { 15583 Slog.w("BatteryStats", 15584 "Error writing checkin battery statistics", e); 15585 mCheckinFile.failWrite(stream); 15586 } finally { 15587 parcel.recycle(); 15588 } 15589 } 15590 } 15591 }); 15592 } 15593 doWrite = true; 15594 resetAllStatsLocked(mSecUptime, mSecRealtime, RESET_REASON_FULL_CHARGE); 15595 if (chargeUah > 0 && level > 0) { 15596 // Only use the reported coulomb charge value if it is supported and reported. 15597 mEstimatedBatteryCapacityMah = (int) ((chargeUah / 1000) / (level / 100.0)); 15598 } 15599 mDischargeStartLevel = level; 15600 reset = true; 15601 mDischargeStepTracker.init(); 15602 } 15603 if (mCharging) { 15604 setChargingLocked(false); 15605 } 15606 mLastChargingStateLevel = level; 15607 mOnBattery = mOnBatteryInternal = true; 15608 mLastDischargeStepLevel = level; 15609 mMinDischargeStepLevel = level; 15610 mDischargeStepTracker.clearTime(); 15611 mDailyDischargeStepTracker.clearTime(); 15612 mInitStepMode = mCurStepMode; 15613 mModStepMode = 0; 15614 pullPendingStateUpdatesLocked(); 15615 mHistoryCur.batteryLevel = (byte)level; 15616 mHistoryCur.states &= ~HistoryItem.STATE_BATTERY_PLUGGED_FLAG; 15617 if (DEBUG_HISTORY) Slog.v(TAG, "Battery unplugged to: " 15618 + Integer.toHexString(mHistoryCur.states)); 15619 if (reset) { 15620 mRecordingHistory = true; 15621 startRecordingHistory(mSecRealtime, mSecUptime, reset); 15622 } 15623 addHistoryRecordLocked(mSecRealtime, mSecUptime); 15624 mDischargeCurrentLevel = mDischargeUnplugLevel = level; 15625 if (Display.isOnState(screenState)) { 15626 mDischargeScreenOnUnplugLevel = level; 15627 mDischargeScreenDozeUnplugLevel = 0; 15628 mDischargeScreenOffUnplugLevel = 0; 15629 } else if (Display.isDozeState(screenState)) { 15630 mDischargeScreenOnUnplugLevel = 0; 15631 mDischargeScreenDozeUnplugLevel = level; 15632 mDischargeScreenOffUnplugLevel = 0; 15633 } else { 15634 mDischargeScreenOnUnplugLevel = 0; 15635 mDischargeScreenDozeUnplugLevel = 0; 15636 mDischargeScreenOffUnplugLevel = level; 15637 } 15638 mDischargeAmountScreenOn = 0; 15639 mDischargeAmountScreenDoze = 0; 15640 mDischargeAmountScreenOff = 0; 15641 updateTimeBasesLocked(true, screenState, uptimeUs, realtimeUs); 15642 } else { 15643 mLastChargingStateLevel = level; 15644 mOnBattery = mOnBatteryInternal = false; 15645 pullPendingStateUpdatesLocked(); 15646 mHistoryCur.batteryLevel = (byte)level; 15647 mHistoryCur.states |= HistoryItem.STATE_BATTERY_PLUGGED_FLAG; 15648 if (DEBUG_HISTORY) Slog.v(TAG, "Battery plugged to: " 15649 + Integer.toHexString(mHistoryCur.states)); 15650 addHistoryRecordLocked(mSecRealtime, mSecUptime); 15651 mDischargeCurrentLevel = mDischargePlugLevel = level; 15652 if (level < mDischargeUnplugLevel) { 15653 mLowDischargeAmountSinceCharge += mDischargeUnplugLevel-level-1; 15654 mHighDischargeAmountSinceCharge += mDischargeUnplugLevel-level; 15655 } 15656 updateDischargeScreenLevelsLocked(screenState, screenState); 15657 updateTimeBasesLocked(false, screenState, uptimeUs, realtimeUs); 15658 mChargeStepTracker.init(); 15659 mLastChargeStepLevel = level; 15660 mMaxChargeStepLevel = level; 15661 mInitStepMode = mCurStepMode; 15662 mModStepMode = 0; 15663 } 15664 if (doWrite || (mLastWriteTimeMs + (60 * 1000)) < mSecRealtime) { 15665 if (mStatsFile != null && mBatteryStatsHistory.getActiveFile() != null) { 15666 writeAsyncLocked(); 15667 } 15668 } 15669 } 15670 15671 @GuardedBy("this") 15672 private void startRecordingHistory(final long elapsedRealtimeMs, final long uptimeMs, 15673 boolean reset) { 15674 mRecordingHistory = true; 15675 mHistoryCur.currentTime = mClock.currentTimeMillis(); 15676 addHistoryBufferLocked(elapsedRealtimeMs, 15677 reset ? HistoryItem.CMD_RESET : HistoryItem.CMD_CURRENT_TIME, 15678 mHistoryCur); 15679 mHistoryCur.currentTime = 0; 15680 if (reset) { 15681 initActiveHistoryEventsLocked(elapsedRealtimeMs, uptimeMs); 15682 } 15683 } 15684 15685 @GuardedBy("this") 15686 private void recordCurrentTimeChangeLocked(final long currentTimeMs, 15687 final long elapsedRealtimeMs, final long uptimeMs) { 15688 if (mRecordingHistory) { 15689 mHistoryCur.currentTime = currentTimeMs; 15690 addHistoryBufferLocked(elapsedRealtimeMs, HistoryItem.CMD_CURRENT_TIME, mHistoryCur); 15691 mHistoryCur.currentTime = 0; 15692 } 15693 } 15694 15695 @GuardedBy("this") 15696 private void recordShutdownLocked(final long currentTimeMs, final long elapsedRealtimeMs) { 15697 if (mRecordingHistory) { 15698 mHistoryCur.currentTime = currentTimeMs; 15699 addHistoryBufferLocked(elapsedRealtimeMs, HistoryItem.CMD_SHUTDOWN, mHistoryCur); 15700 mHistoryCur.currentTime = 0; 15701 } 15702 } 15703 15704 private void scheduleSyncExternalStatsLocked(String reason, int updateFlags) { 15705 if (mExternalSync != null) { 15706 mExternalSync.scheduleSync(reason, updateFlags); 15707 } 15708 } 15709 15710 // This should probably be exposed in the API, though it's not critical 15711 public static final int BATTERY_PLUGGED_NONE = OsProtoEnums.BATTERY_PLUGGED_NONE; // = 0 15712 15713 @GuardedBy("this") 15714 public void setBatteryStateLocked(final int status, final int health, final int plugType, 15715 final int level, /* not final */ int temp, final int voltageMv, final int chargeUah, 15716 final int chargeFullUah, final long chargeTimeToFullSeconds) { 15717 setBatteryStateLocked(status, health, plugType, level, temp, voltageMv, chargeUah, 15718 chargeFullUah, chargeTimeToFullSeconds, 15719 mClock.elapsedRealtime(), mClock.uptimeMillis(), mClock.currentTimeMillis()); 15720 } 15721 15722 @GuardedBy("this") 15723 public void setBatteryStateLocked(final int status, final int health, final int plugType, 15724 final int level, /* not final */ int temp, final int voltageMv, final int chargeUah, 15725 final int chargeFullUah, final long chargeTimeToFullSeconds, 15726 final long elapsedRealtimeMs, final long uptimeMs, final long currentTimeMs) { 15727 // Temperature is encoded without the signed bit, so clamp any negative temperatures to 0. 15728 temp = Math.max(0, temp); 15729 15730 reportChangesToStatsLog(mHaveBatteryLevel ? mHistoryCur : null, 15731 status, plugType, level); 15732 15733 final boolean onBattery = isOnBattery(plugType, status); 15734 if (!mHaveBatteryLevel) { 15735 mHaveBatteryLevel = true; 15736 // We start out assuming that the device is plugged in (not 15737 // on battery). If our first report is now that we are indeed 15738 // plugged in, then twiddle our state to correctly reflect that 15739 // since we won't be going through the full setOnBattery(). 15740 if (onBattery == mOnBattery) { 15741 if (onBattery) { 15742 mHistoryCur.states &= ~HistoryItem.STATE_BATTERY_PLUGGED_FLAG; 15743 } else { 15744 mHistoryCur.states |= HistoryItem.STATE_BATTERY_PLUGGED_FLAG; 15745 } 15746 } 15747 // Always start out assuming charging, that will be updated later. 15748 mHistoryCur.states2 |= HistoryItem.STATE2_CHARGING_FLAG; 15749 mHistoryCur.batteryStatus = (byte)status; 15750 mHistoryCur.batteryLevel = (byte)level; 15751 mHistoryCur.batteryChargeUah = chargeUah; 15752 mMaxChargeStepLevel = mMinDischargeStepLevel = 15753 mLastChargeStepLevel = mLastDischargeStepLevel = level; 15754 mLastChargingStateLevel = level; 15755 } else if (mCurrentBatteryLevel != level || mOnBattery != onBattery) { 15756 recordDailyStatsIfNeededLocked(level >= 100 && onBattery, currentTimeMs); 15757 } 15758 int oldStatus = mHistoryCur.batteryStatus; 15759 if (onBattery) { 15760 mDischargeCurrentLevel = level; 15761 if (!mRecordingHistory) { 15762 mRecordingHistory = true; 15763 startRecordingHistory(elapsedRealtimeMs, uptimeMs, true); 15764 } 15765 } else if (level < 96 && 15766 status != BatteryManager.BATTERY_STATUS_UNKNOWN) { 15767 if (!mRecordingHistory) { 15768 mRecordingHistory = true; 15769 startRecordingHistory(elapsedRealtimeMs, uptimeMs, true); 15770 } 15771 } 15772 mBatteryVoltageMv = voltageMv; 15773 mCurrentBatteryLevel = level; 15774 if (mDischargePlugLevel < 0) { 15775 mDischargePlugLevel = level; 15776 } 15777 15778 if (onBattery != mOnBattery) { 15779 mHistoryCur.batteryLevel = (byte)level; 15780 mHistoryCur.batteryStatus = (byte)status; 15781 mHistoryCur.batteryHealth = (byte)health; 15782 mHistoryCur.batteryPlugType = (byte)plugType; 15783 mHistoryCur.batteryTemperature = (short)temp; 15784 mHistoryCur.batteryVoltage = (char) voltageMv; 15785 if (chargeUah < mHistoryCur.batteryChargeUah) { 15786 // Only record discharges 15787 final long chargeDiff = mHistoryCur.batteryChargeUah - chargeUah; 15788 mDischargeCounter.addCountLocked(chargeDiff); 15789 mDischargeScreenOffCounter.addCountLocked(chargeDiff); 15790 if (Display.isDozeState(mScreenState)) { 15791 mDischargeScreenDozeCounter.addCountLocked(chargeDiff); 15792 } 15793 if (mDeviceIdleMode == DEVICE_IDLE_MODE_LIGHT) { 15794 mDischargeLightDozeCounter.addCountLocked(chargeDiff); 15795 } else if (mDeviceIdleMode == DEVICE_IDLE_MODE_DEEP) { 15796 mDischargeDeepDozeCounter.addCountLocked(chargeDiff); 15797 } 15798 } 15799 mHistoryCur.batteryChargeUah = chargeUah; 15800 setOnBatteryLocked(elapsedRealtimeMs, uptimeMs, onBattery, oldStatus, level, chargeUah); 15801 } else { 15802 boolean changed = false; 15803 if (mHistoryCur.batteryLevel != level) { 15804 mHistoryCur.batteryLevel = (byte)level; 15805 changed = true; 15806 15807 // TODO(adamlesinski): Schedule the creation of a HistoryStepDetails record 15808 // which will pull external stats. 15809 mExternalSync.scheduleSyncDueToBatteryLevelChange( 15810 mConstants.BATTERY_LEVEL_COLLECTION_DELAY_MS); 15811 } 15812 if (mHistoryCur.batteryStatus != status) { 15813 mHistoryCur.batteryStatus = (byte)status; 15814 changed = true; 15815 } 15816 if (mHistoryCur.batteryHealth != health) { 15817 mHistoryCur.batteryHealth = (byte)health; 15818 changed = true; 15819 } 15820 if (mHistoryCur.batteryPlugType != plugType) { 15821 mHistoryCur.batteryPlugType = (byte)plugType; 15822 changed = true; 15823 } 15824 if (temp >= (mHistoryCur.batteryTemperature+10) 15825 || temp <= (mHistoryCur.batteryTemperature-10)) { 15826 mHistoryCur.batteryTemperature = (short)temp; 15827 changed = true; 15828 } 15829 if (voltageMv > (mHistoryCur.batteryVoltage + 20) 15830 || voltageMv < (mHistoryCur.batteryVoltage - 20)) { 15831 mHistoryCur.batteryVoltage = (char) voltageMv; 15832 changed = true; 15833 } 15834 if (chargeUah >= (mHistoryCur.batteryChargeUah + 10) 15835 || chargeUah <= (mHistoryCur.batteryChargeUah - 10)) { 15836 if (chargeUah < mHistoryCur.batteryChargeUah) { 15837 // Only record discharges 15838 final long chargeDiff = mHistoryCur.batteryChargeUah - chargeUah; 15839 mDischargeCounter.addCountLocked(chargeDiff); 15840 mDischargeScreenOffCounter.addCountLocked(chargeDiff); 15841 if (Display.isDozeState(mScreenState)) { 15842 mDischargeScreenDozeCounter.addCountLocked(chargeDiff); 15843 } 15844 if (mDeviceIdleMode == DEVICE_IDLE_MODE_LIGHT) { 15845 mDischargeLightDozeCounter.addCountLocked(chargeDiff); 15846 } else if (mDeviceIdleMode == DEVICE_IDLE_MODE_DEEP) { 15847 mDischargeDeepDozeCounter.addCountLocked(chargeDiff); 15848 } 15849 } 15850 mHistoryCur.batteryChargeUah = chargeUah; 15851 changed = true; 15852 } 15853 long modeBits = (((long)mInitStepMode) << STEP_LEVEL_INITIAL_MODE_SHIFT) 15854 | (((long)mModStepMode) << STEP_LEVEL_MODIFIED_MODE_SHIFT) 15855 | (((long)(level&0xff)) << STEP_LEVEL_LEVEL_SHIFT); 15856 if (onBattery) { 15857 changed |= setChargingLocked(false); 15858 if (mLastDischargeStepLevel != level && mMinDischargeStepLevel > level) { 15859 mDischargeStepTracker.addLevelSteps(mLastDischargeStepLevel - level, 15860 modeBits, elapsedRealtimeMs); 15861 mDailyDischargeStepTracker.addLevelSteps(mLastDischargeStepLevel - level, 15862 modeBits, elapsedRealtimeMs); 15863 mLastDischargeStepLevel = level; 15864 mMinDischargeStepLevel = level; 15865 mInitStepMode = mCurStepMode; 15866 mModStepMode = 0; 15867 } 15868 } else { 15869 if (level >= 90) { 15870 // If the battery level is at least 90%, always consider the device to be 15871 // charging even if it happens to go down a level. 15872 changed |= setChargingLocked(true); 15873 } else if (!mCharging) { 15874 if (mLastChargeStepLevel < level) { 15875 // We have not reported that we are charging, but the level has gone up, 15876 // but we would like to not have tons of activity from charging-constraint 15877 // jobs, so instead of reporting ACTION_CHARGING immediately, we defer it. 15878 if (!mHandler.hasCallbacks(mDeferSetCharging)) { 15879 mHandler.postDelayed( 15880 mDeferSetCharging, 15881 mConstants.BATTERY_CHARGED_DELAY_MS); 15882 } 15883 } else if (mLastChargeStepLevel > level) { 15884 // if we had deferred a runnable due to charge level increasing, but then 15885 // later the charge level drops (could be due to thermal issues), we don't 15886 // want to trigger the deferred runnable, so remove it here 15887 mHandler.removeCallbacks(mDeferSetCharging); 15888 } 15889 } else { 15890 if (mLastChargeStepLevel > level) { 15891 // We had reported that the device was charging, but here we are with 15892 // power connected and the level going down. Looks like the current 15893 // power supplied isn't enough, so consider the device to now be 15894 // discharging. 15895 changed |= setChargingLocked(false); 15896 } 15897 } 15898 if (mLastChargeStepLevel != level && mMaxChargeStepLevel < level) { 15899 mChargeStepTracker.addLevelSteps(level - mLastChargeStepLevel, 15900 modeBits, elapsedRealtimeMs); 15901 mDailyChargeStepTracker.addLevelSteps(level - mLastChargeStepLevel, 15902 modeBits, elapsedRealtimeMs); 15903 mMaxChargeStepLevel = level; 15904 mInitStepMode = mCurStepMode; 15905 mModStepMode = 0; 15906 } 15907 mLastChargeStepLevel = level; 15908 } 15909 if (changed) { 15910 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 15911 } 15912 } 15913 if (!onBattery && 15914 (status == BatteryManager.BATTERY_STATUS_FULL || 15915 status == BatteryManager.BATTERY_STATUS_UNKNOWN)) { 15916 // We don't record history while we are plugged in and fully charged 15917 // (or when battery is not present). The next time we are 15918 // unplugged, history will be cleared. 15919 mRecordingHistory = DEBUG; 15920 } 15921 15922 mLastLearnedBatteryCapacityUah = chargeFullUah; 15923 if (mMinLearnedBatteryCapacityUah == -1) { 15924 mMinLearnedBatteryCapacityUah = chargeFullUah; 15925 } else { 15926 mMinLearnedBatteryCapacityUah = Math.min(mMinLearnedBatteryCapacityUah, chargeFullUah); 15927 } 15928 mMaxLearnedBatteryCapacityUah = Math.max(mMaxLearnedBatteryCapacityUah, chargeFullUah); 15929 15930 mBatteryTimeToFullSeconds = chargeTimeToFullSeconds; 15931 } 15932 15933 public static boolean isOnBattery(int plugType, int status) { 15934 return plugType == BATTERY_PLUGGED_NONE && status != BatteryManager.BATTERY_STATUS_UNKNOWN; 15935 } 15936 15937 // Inform StatsLog of setBatteryState changes. 15938 // If this is the first reporting, pass in recentPast == null. 15939 private void reportChangesToStatsLog(HistoryItem recentPast, 15940 final int status, final int plugType, final int level) { 15941 15942 if (recentPast == null || recentPast.batteryStatus != status) { 15943 FrameworkStatsLog.write(FrameworkStatsLog.CHARGING_STATE_CHANGED, status); 15944 } 15945 if (recentPast == null || recentPast.batteryPlugType != plugType) { 15946 FrameworkStatsLog.write(FrameworkStatsLog.PLUGGED_STATE_CHANGED, plugType); 15947 } 15948 if (recentPast == null || recentPast.batteryLevel != level) { 15949 FrameworkStatsLog.write(FrameworkStatsLog.BATTERY_LEVEL_CHANGED, level); 15950 } 15951 } 15952 15953 @UnsupportedAppUsage 15954 public long getAwakeTimeBattery() { 15955 // This previously evaluated to mOnBatteryTimeBase.getUptime(getBatteryUptimeLocked()); 15956 // for over a decade, but surely that was a mistake. 15957 return getBatteryUptimeLocked(mClock.uptimeMillis()); 15958 } 15959 15960 @UnsupportedAppUsage 15961 public long getAwakeTimePlugged() { 15962 return (mClock.uptimeMillis() * 1000) - getAwakeTimeBattery(); 15963 } 15964 15965 @Override 15966 public long computeUptime(long curTimeUs, int which) { 15967 return mUptimeUs + (curTimeUs - mUptimeStartUs); 15968 } 15969 15970 @Override 15971 public long computeRealtime(long curTimeUs, int which) { 15972 return mRealtimeUs + (curTimeUs - mRealtimeStartUs); 15973 } 15974 15975 @Override 15976 @UnsupportedAppUsage 15977 public long computeBatteryUptime(long curTimeUs, int which) { 15978 return mOnBatteryTimeBase.computeUptime(curTimeUs, which); 15979 } 15980 15981 @Override 15982 @UnsupportedAppUsage 15983 public long computeBatteryRealtime(long curTimeUs, int which) { 15984 return mOnBatteryTimeBase.computeRealtime(curTimeUs, which); 15985 } 15986 15987 @Override 15988 public long computeBatteryScreenOffUptime(long curTimeUs, int which) { 15989 return mOnBatteryScreenOffTimeBase.computeUptime(curTimeUs, which); 15990 } 15991 15992 @Override 15993 public long computeBatteryScreenOffRealtime(long curTimeUs, int which) { 15994 return mOnBatteryScreenOffTimeBase.computeRealtime(curTimeUs, which); 15995 } 15996 15997 private long computeTimePerLevel(long[] steps, int numSteps) { 15998 // For now we'll do a simple average across all steps. 15999 if (numSteps <= 0) { 16000 return -1; 16001 } 16002 long total = 0; 16003 for (int i=0; i<numSteps; i++) { 16004 total += steps[i] & STEP_LEVEL_TIME_MASK; 16005 } 16006 return total / numSteps; 16007 /* 16008 long[] buckets = new long[numSteps]; 16009 int numBuckets = 0; 16010 int numToAverage = 4; 16011 int i = 0; 16012 while (i < numSteps) { 16013 long totalTime = 0; 16014 int num = 0; 16015 for (int j=0; j<numToAverage && (i+j)<numSteps; j++) { 16016 totalTime += steps[i+j] & STEP_LEVEL_TIME_MASK; 16017 num++; 16018 } 16019 buckets[numBuckets] = totalTime / num; 16020 numBuckets++; 16021 numToAverage *= 2; 16022 i += num; 16023 } 16024 if (numBuckets < 1) { 16025 return -1; 16026 } 16027 long averageTime = buckets[numBuckets-1]; 16028 for (i=numBuckets-2; i>=0; i--) { 16029 averageTime = (averageTime + buckets[i]) / 2; 16030 } 16031 return averageTime; 16032 */ 16033 } 16034 16035 @Override 16036 @UnsupportedAppUsage 16037 public long computeBatteryTimeRemaining(long curTime) { 16038 if (!mOnBattery) { 16039 return -1; 16040 } 16041 /* Simple implementation just looks at the average discharge per level across the 16042 entire sample period. 16043 int discharge = (getLowDischargeAmountSinceCharge()+getHighDischargeAmountSinceCharge())/2; 16044 if (discharge < 2) { 16045 return -1; 16046 } 16047 long duration = computeBatteryRealtime(curTime, STATS_SINCE_CHARGED); 16048 if (duration < 1000*1000) { 16049 return -1; 16050 } 16051 long usPerLevel = duration/discharge; 16052 return usPerLevel * mCurrentBatteryLevel; 16053 */ 16054 if (mDischargeStepTracker.mNumStepDurations < 1) { 16055 return -1; 16056 } 16057 long msPerLevel = mDischargeStepTracker.computeTimePerLevel(); 16058 if (msPerLevel <= 0) { 16059 return -1; 16060 } 16061 return (msPerLevel * mCurrentBatteryLevel) * 1000; 16062 } 16063 16064 @Override 16065 public LevelStepTracker getDischargeLevelStepTracker() { 16066 return mDischargeStepTracker; 16067 } 16068 16069 @Override 16070 public LevelStepTracker getDailyDischargeLevelStepTracker() { 16071 return mDailyDischargeStepTracker; 16072 } 16073 16074 @Override 16075 public long computeChargeTimeRemaining(long curTime) { 16076 if (mOnBattery) { 16077 // Not yet working. 16078 return -1; 16079 } 16080 if (mBatteryTimeToFullSeconds >= 0) { 16081 return mBatteryTimeToFullSeconds * (1000 * 1000); // s to us 16082 } 16083 // Else use algorithmic approach 16084 if (mChargeStepTracker.mNumStepDurations < 1) { 16085 return -1; 16086 } 16087 long msPerLevel = mChargeStepTracker.computeTimePerLevel(); 16088 if (msPerLevel <= 0) { 16089 return -1; 16090 } 16091 return (msPerLevel * (100 - mCurrentBatteryLevel)) * 1000; 16092 } 16093 16094 /*@hide */ 16095 public CellularBatteryStats getCellularBatteryStats() { 16096 final int which = STATS_SINCE_CHARGED; 16097 final long rawRealTimeUs = SystemClock.elapsedRealtime() * 1000; 16098 final ControllerActivityCounter counter = getModemControllerActivity(); 16099 final long sleepTimeMs = counter.getSleepTimeCounter().getCountLocked(which); 16100 final long idleTimeMs = counter.getIdleTimeCounter().getCountLocked(which); 16101 final long rxTimeMs = counter.getRxTimeCounter().getCountLocked(which); 16102 final long energyConsumedMaMs = counter.getPowerCounter().getCountLocked(which); 16103 final long monitoredRailChargeConsumedMaMs = 16104 counter.getMonitoredRailChargeConsumedMaMs().getCountLocked(which); 16105 long[] timeInRatMs = new long[BatteryStats.NUM_DATA_CONNECTION_TYPES]; 16106 for (int i = 0; i < timeInRatMs.length; i++) { 16107 timeInRatMs[i] = getPhoneDataConnectionTime(i, rawRealTimeUs, which) / 1000; 16108 } 16109 long[] timeInRxSignalStrengthLevelMs = 16110 new long[CellSignalStrength.getNumSignalStrengthLevels()]; 16111 for (int i = 0; i < timeInRxSignalStrengthLevelMs.length; i++) { 16112 timeInRxSignalStrengthLevelMs[i] = 16113 getPhoneSignalStrengthTime(i, rawRealTimeUs, which) / 1000; 16114 } 16115 long[] txTimeMs = new long[Math.min(ModemActivityInfo.getNumTxPowerLevels(), 16116 counter.getTxTimeCounters().length)]; 16117 long totalTxTimeMs = 0; 16118 for (int i = 0; i < txTimeMs.length; i++) { 16119 txTimeMs[i] = counter.getTxTimeCounters()[i].getCountLocked(which); 16120 totalTxTimeMs += txTimeMs[i]; 16121 } 16122 16123 return new CellularBatteryStats(computeBatteryRealtime(rawRealTimeUs, which) / 1000, 16124 getMobileRadioActiveTime(rawRealTimeUs, which) / 1000, 16125 getNetworkActivityPackets(NETWORK_MOBILE_TX_DATA, which), 16126 getNetworkActivityBytes(NETWORK_MOBILE_TX_DATA, which), 16127 getNetworkActivityPackets(NETWORK_MOBILE_RX_DATA, which), 16128 getNetworkActivityBytes(NETWORK_MOBILE_RX_DATA, which), 16129 sleepTimeMs, idleTimeMs, rxTimeMs, energyConsumedMaMs, timeInRatMs, 16130 timeInRxSignalStrengthLevelMs, txTimeMs, 16131 monitoredRailChargeConsumedMaMs); 16132 } 16133 16134 /*@hide */ 16135 public WifiBatteryStats getWifiBatteryStats() { 16136 final int which = STATS_SINCE_CHARGED; 16137 final long rawRealTimeUs = SystemClock.elapsedRealtime() * 1000; 16138 final ControllerActivityCounter counter = getWifiControllerActivity(); 16139 final long idleTimeMs = counter.getIdleTimeCounter().getCountLocked(which); 16140 final long scanTimeMs = counter.getScanTimeCounter().getCountLocked(which); 16141 final long rxTimeMs = counter.getRxTimeCounter().getCountLocked(which); 16142 final long txTimeMs = counter.getTxTimeCounters()[0].getCountLocked(which); 16143 final long totalControllerActivityTimeMs 16144 = computeBatteryRealtime(SystemClock.elapsedRealtime() * 1000, which) / 1000; 16145 final long sleepTimeMs 16146 = totalControllerActivityTimeMs - (idleTimeMs + rxTimeMs + txTimeMs); 16147 final long energyConsumedMaMs = counter.getPowerCounter().getCountLocked(which); 16148 final long monitoredRailChargeConsumedMaMs = 16149 counter.getMonitoredRailChargeConsumedMaMs().getCountLocked(which); 16150 long numAppScanRequest = 0; 16151 for (int i = 0; i < mUidStats.size(); i++) { 16152 numAppScanRequest += mUidStats.valueAt(i).mWifiScanTimer.getCountLocked(which); 16153 } 16154 long[] timeInStateMs = new long[NUM_WIFI_STATES]; 16155 for (int i=0; i<NUM_WIFI_STATES; i++) { 16156 timeInStateMs[i] = getWifiStateTime(i, rawRealTimeUs, which) / 1000; 16157 } 16158 long[] timeInSupplStateMs = new long[NUM_WIFI_SUPPL_STATES]; 16159 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) { 16160 timeInSupplStateMs[i] = getWifiSupplStateTime(i, rawRealTimeUs, which) / 1000; 16161 } 16162 long[] timeSignalStrengthTimeMs = new long[NUM_WIFI_SIGNAL_STRENGTH_BINS]; 16163 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { 16164 timeSignalStrengthTimeMs[i] = getWifiSignalStrengthTime(i, rawRealTimeUs, which) / 1000; 16165 } 16166 return new WifiBatteryStats( 16167 computeBatteryRealtime(rawRealTimeUs, which) / 1000, 16168 getWifiActiveTime(rawRealTimeUs, which) / 1000, 16169 getNetworkActivityPackets(NETWORK_WIFI_TX_DATA, which), 16170 getNetworkActivityBytes(NETWORK_WIFI_TX_DATA, which), 16171 getNetworkActivityPackets(NETWORK_WIFI_RX_DATA, which), 16172 getNetworkActivityBytes(NETWORK_WIFI_RX_DATA, which), 16173 sleepTimeMs, scanTimeMs, idleTimeMs, rxTimeMs, txTimeMs, energyConsumedMaMs, 16174 numAppScanRequest, timeInStateMs, timeSignalStrengthTimeMs, timeInSupplStateMs, 16175 monitoredRailChargeConsumedMaMs); 16176 } 16177 16178 /*@hide */ 16179 public GpsBatteryStats getGpsBatteryStats() { 16180 GpsBatteryStats s = new GpsBatteryStats(); 16181 final int which = STATS_SINCE_CHARGED; 16182 final long rawRealTimeUs = SystemClock.elapsedRealtime() * 1000; 16183 s.setLoggingDurationMs(computeBatteryRealtime(rawRealTimeUs, which) / 1000); 16184 s.setEnergyConsumedMaMs(getGpsBatteryDrainMaMs()); 16185 long[] time = new long[mGpsSignalQualityTimer.length]; 16186 for (int i=0; i<time.length; i++) { 16187 time[i] = getGpsSignalQualityTime(i, rawRealTimeUs, which) / 1000; 16188 } 16189 s.setTimeInGpsSignalQualityLevel(time); 16190 return s; 16191 } 16192 16193 @Override 16194 public LevelStepTracker getChargeLevelStepTracker() { 16195 return mChargeStepTracker; 16196 } 16197 16198 @Override 16199 public LevelStepTracker getDailyChargeLevelStepTracker() { 16200 return mDailyChargeStepTracker; 16201 } 16202 16203 @Override 16204 public ArrayList<PackageChange> getDailyPackageChanges() { 16205 return mDailyPackageChanges; 16206 } 16207 16208 /** 16209 * @return battery uptime in microseconds 16210 */ 16211 protected long getBatteryUptimeLocked() { 16212 return getBatteryUptimeLocked(mClock.uptimeMillis()); 16213 } 16214 16215 /** 16216 * @return battery uptime in microseconds 16217 */ 16218 protected long getBatteryUptimeLocked(long uptimeMs) { 16219 return mOnBatteryTimeBase.getUptime(uptimeMs * 1000); 16220 } 16221 16222 @Override 16223 public long getBatteryUptime(long curTimeUs) { 16224 return mOnBatteryTimeBase.getUptime(curTimeUs); 16225 } 16226 16227 @Override 16228 @UnsupportedAppUsage 16229 public long getBatteryRealtime(long curTimeUs) { 16230 return mOnBatteryTimeBase.getRealtime(curTimeUs); 16231 } 16232 16233 @Override 16234 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) 16235 public int getDischargeStartLevel() { 16236 synchronized(this) { 16237 return getDischargeStartLevelLocked(); 16238 } 16239 } 16240 16241 public int getDischargeStartLevelLocked() { 16242 return mDischargeUnplugLevel; 16243 } 16244 16245 @Override 16246 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) 16247 public int getDischargeCurrentLevel() { 16248 synchronized(this) { 16249 return getDischargeCurrentLevelLocked(); 16250 } 16251 } 16252 16253 public int getDischargeCurrentLevelLocked() { 16254 return mDischargeCurrentLevel; 16255 } 16256 16257 @Override 16258 public int getLowDischargeAmountSinceCharge() { 16259 synchronized(this) { 16260 int val = mLowDischargeAmountSinceCharge; 16261 if (mOnBattery && mDischargeCurrentLevel < mDischargeUnplugLevel) { 16262 val += mDischargeUnplugLevel-mDischargeCurrentLevel-1; 16263 } 16264 return val; 16265 } 16266 } 16267 16268 @Override 16269 public int getHighDischargeAmountSinceCharge() { 16270 synchronized(this) { 16271 int val = mHighDischargeAmountSinceCharge; 16272 if (mOnBattery && mDischargeCurrentLevel < mDischargeUnplugLevel) { 16273 val += mDischargeUnplugLevel-mDischargeCurrentLevel; 16274 } 16275 return val; 16276 } 16277 } 16278 16279 @Override 16280 @UnsupportedAppUsage 16281 public int getDischargeAmount(int which) { 16282 int dischargeAmount = which == STATS_SINCE_CHARGED 16283 ? getHighDischargeAmountSinceCharge() 16284 : (getDischargeStartLevel() - getDischargeCurrentLevel()); 16285 if (dischargeAmount < 0) { 16286 dischargeAmount = 0; 16287 } 16288 return dischargeAmount; 16289 } 16290 16291 @Override 16292 @UnsupportedAppUsage 16293 public int getDischargeAmountScreenOn() { 16294 synchronized(this) { 16295 int val = mDischargeAmountScreenOn; 16296 if (mOnBattery && Display.isOnState(mScreenState) 16297 && mDischargeCurrentLevel < mDischargeScreenOnUnplugLevel) { 16298 val += mDischargeScreenOnUnplugLevel-mDischargeCurrentLevel; 16299 } 16300 return val; 16301 } 16302 } 16303 16304 @Override 16305 public int getDischargeAmountScreenOnSinceCharge() { 16306 synchronized(this) { 16307 int val = mDischargeAmountScreenOnSinceCharge; 16308 if (mOnBattery && Display.isOnState(mScreenState) 16309 && mDischargeCurrentLevel < mDischargeScreenOnUnplugLevel) { 16310 val += mDischargeScreenOnUnplugLevel-mDischargeCurrentLevel; 16311 } 16312 return val; 16313 } 16314 } 16315 16316 @Override 16317 @UnsupportedAppUsage 16318 public int getDischargeAmountScreenOff() { 16319 synchronized(this) { 16320 int val = mDischargeAmountScreenOff; 16321 if (mOnBattery && Display.isOffState(mScreenState) 16322 && mDischargeCurrentLevel < mDischargeScreenOffUnplugLevel) { 16323 val += mDischargeScreenOffUnplugLevel-mDischargeCurrentLevel; 16324 } 16325 // For backward compatibility, doze discharge is counted into screen off. 16326 return val + getDischargeAmountScreenDoze(); 16327 } 16328 } 16329 16330 @Override 16331 public int getDischargeAmountScreenOffSinceCharge() { 16332 synchronized(this) { 16333 int val = mDischargeAmountScreenOffSinceCharge; 16334 if (mOnBattery && Display.isOffState(mScreenState) 16335 && mDischargeCurrentLevel < mDischargeScreenOffUnplugLevel) { 16336 val += mDischargeScreenOffUnplugLevel-mDischargeCurrentLevel; 16337 } 16338 // For backward compatibility, doze discharge is counted into screen off. 16339 return val + getDischargeAmountScreenDozeSinceCharge(); 16340 } 16341 } 16342 16343 @Override 16344 public int getDischargeAmountScreenDoze() { 16345 synchronized(this) { 16346 int val = mDischargeAmountScreenDoze; 16347 if (mOnBattery && Display.isDozeState(mScreenState) 16348 && mDischargeCurrentLevel < mDischargeScreenDozeUnplugLevel) { 16349 val += mDischargeScreenDozeUnplugLevel-mDischargeCurrentLevel; 16350 } 16351 return val; 16352 } 16353 } 16354 16355 @Override 16356 public int getDischargeAmountScreenDozeSinceCharge() { 16357 synchronized(this) { 16358 int val = mDischargeAmountScreenDozeSinceCharge; 16359 if (mOnBattery && Display.isDozeState(mScreenState) 16360 && mDischargeCurrentLevel < mDischargeScreenDozeUnplugLevel) { 16361 val += mDischargeScreenDozeUnplugLevel-mDischargeCurrentLevel; 16362 } 16363 return val; 16364 } 16365 } 16366 16367 16368 /** 16369 * Estimates the time spent by the system server handling incoming binder requests. 16370 */ 16371 @Override 16372 public long[] getSystemServiceTimeAtCpuSpeeds() { 16373 if (mBinderThreadCpuTimesUs == null) { 16374 return null; 16375 } 16376 16377 return mBinderThreadCpuTimesUs.getCountsLocked(BatteryStats.STATS_SINCE_CHARGED); 16378 } 16379 16380 /** 16381 * Retrieve the statistics object for a particular uid, creating if needed. 16382 */ 16383 @UnsupportedAppUsage 16384 public Uid getUidStatsLocked(int uid) { 16385 return getUidStatsLocked(uid, mClock.elapsedRealtime(), mClock.uptimeMillis()); 16386 } 16387 16388 public Uid getUidStatsLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 16389 Uid u = mUidStats.get(uid); 16390 if (u == null) { 16391 if (Process.isSdkSandboxUid(uid)) { 16392 Log.wtf(TAG, "Tracking an SDK Sandbox UID"); 16393 } 16394 u = new Uid(this, uid, elapsedRealtimeMs, uptimeMs); 16395 mUidStats.put(uid, u); 16396 } 16397 return u; 16398 } 16399 16400 /** 16401 * Retrieve the statistics object for a particular uid. Returns null if the object is not 16402 * available. 16403 */ 16404 public Uid getAvailableUidStatsLocked(int uid) { 16405 Uid u = mUidStats.get(uid); 16406 return u; 16407 } 16408 16409 @GuardedBy("this") 16410 public void onCleanupUserLocked(int userId, long elapsedRealtimeMs) { 16411 final int firstUidForUser = UserHandle.getUid(userId, 0); 16412 final int lastUidForUser = UserHandle.getUid(userId, UserHandle.PER_USER_RANGE - 1); 16413 mPendingRemovedUids.add( 16414 new UidToRemove(firstUidForUser, lastUidForUser, elapsedRealtimeMs)); 16415 } 16416 16417 @GuardedBy("this") 16418 public void onUserRemovedLocked(int userId) { 16419 if (mExternalSync != null) { 16420 // Clear out the removed user's UIDs after a short delay. The delay is needed 16421 // because at the point that this method is called, some activities are still 16422 // being wrapped up by those UIDs 16423 mExternalSync.scheduleCleanupDueToRemovedUser(userId); 16424 } 16425 } 16426 16427 /** 16428 * Removes battery stats for UIDs corresponding to a removed user. 16429 */ 16430 @GuardedBy("this") 16431 public void clearRemovedUserUidsLocked(int userId) { 16432 final int firstUidForUser = UserHandle.getUid(userId, 0); 16433 final int lastUidForUser = UserHandle.getUid(userId, UserHandle.PER_USER_RANGE - 1); 16434 mUidStats.put(firstUidForUser, null); 16435 mUidStats.put(lastUidForUser, null); 16436 final int firstIndex = mUidStats.indexOfKey(firstUidForUser); 16437 final int lastIndex = mUidStats.indexOfKey(lastUidForUser); 16438 for (int i = firstIndex; i <= lastIndex; i++) { 16439 final Uid uid = mUidStats.valueAt(i); 16440 if (uid != null) { 16441 uid.detachFromTimeBase(); 16442 } 16443 } 16444 mUidStats.removeAtRange(firstIndex, lastIndex - firstIndex + 1); 16445 removeCpuStatsForUidRangeLocked(firstUidForUser, lastUidForUser); 16446 } 16447 16448 /** 16449 * Remove the statistics object for a particular uid. 16450 */ 16451 @UnsupportedAppUsage 16452 @GuardedBy("this") 16453 public void removeUidStatsLocked(int uid) { 16454 removeUidStatsLocked(uid, mClock.elapsedRealtime()); 16455 } 16456 16457 /** 16458 * @see #removeUidStatsLocked(int) 16459 */ 16460 @GuardedBy("this") 16461 public void removeUidStatsLocked(int uid, long elapsedRealtimeMs) { 16462 final Uid u = mUidStats.get(uid); 16463 if (u != null) { 16464 u.detachFromTimeBase(); 16465 } 16466 mUidStats.remove(uid); 16467 mPendingRemovedUids.add(new UidToRemove(uid, elapsedRealtimeMs)); 16468 } 16469 16470 /** 16471 * Removes the data for the deleted UIDs from the underlying kernel eBPF tables. 16472 */ 16473 @GuardedBy("this") 16474 private void removeCpuStatsForUidRangeLocked(int startUid, int endUid) { 16475 if (startUid == endUid) { 16476 mCpuUidUserSysTimeReader.removeUid(startUid); 16477 mCpuUidFreqTimeReader.removeUid(startUid); 16478 if (mConstants.TRACK_CPU_ACTIVE_CLUSTER_TIME) { 16479 mCpuUidActiveTimeReader.removeUid(startUid); 16480 mCpuUidClusterTimeReader.removeUid(startUid); 16481 } 16482 if (mKernelSingleUidTimeReader != null) { 16483 mKernelSingleUidTimeReader.removeUid(startUid); 16484 } 16485 mNumUidsRemoved++; 16486 } else if (startUid < endUid) { 16487 mCpuUidFreqTimeReader.removeUidsInRange(startUid, endUid); 16488 mCpuUidUserSysTimeReader.removeUidsInRange(startUid, endUid); 16489 if (mConstants.TRACK_CPU_ACTIVE_CLUSTER_TIME) { 16490 mCpuUidActiveTimeReader.removeUidsInRange(startUid, endUid); 16491 mCpuUidClusterTimeReader.removeUidsInRange(startUid, endUid); 16492 } 16493 if (mKernelSingleUidTimeReader != null) { 16494 mKernelSingleUidTimeReader.removeUidsInRange(startUid, endUid); 16495 } 16496 // Treat as one. We don't know how many uids there are in between. 16497 mNumUidsRemoved++; 16498 } else { 16499 Slog.w(TAG, "End UID " + endUid + " is smaller than start UID " + startUid); 16500 } 16501 } 16502 16503 /** 16504 * Retrieve the statistics object for a particular process, creating 16505 * if needed. 16506 */ 16507 @UnsupportedAppUsage 16508 public Uid.Proc getProcessStatsLocked(int uid, String name) { 16509 return getProcessStatsLocked(uid, name, mClock.elapsedRealtime(), mClock.uptimeMillis()); 16510 } 16511 16512 /** 16513 * @see #getProcessStatsLocked(int, String) 16514 */ 16515 public Uid.Proc getProcessStatsLocked(int uid, String name, 16516 long elapsedRealtimeMs, long uptimeMs) { 16517 uid = mapUid(uid); 16518 Uid u = getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs); 16519 return u.getProcessStatsLocked(name); 16520 } 16521 16522 /** 16523 * Retrieve the statistics object for a particular process, creating 16524 * if needed. 16525 */ 16526 @UnsupportedAppUsage 16527 public Uid.Pkg getPackageStatsLocked(int uid, String pkg) { 16528 return getPackageStatsLocked(uid, pkg, mClock.elapsedRealtime(), mClock.uptimeMillis()); 16529 } 16530 16531 /** 16532 * @see getPackageStatsLocked(int, String) 16533 */ 16534 public Uid.Pkg getPackageStatsLocked(int uid, String pkg, 16535 long elapsedRealtimeMs, long uptimeMs) { 16536 uid = mapUid(uid); 16537 Uid u = getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs); 16538 return u.getPackageStatsLocked(pkg); 16539 } 16540 16541 /** 16542 * Retrieve the statistics object for a particular service, creating 16543 * if needed. 16544 */ 16545 @UnsupportedAppUsage 16546 public Uid.Pkg.Serv getServiceStatsLocked(int uid, String pkg, String name) { 16547 return getServiceStatsLocked(uid, pkg, name, 16548 mClock.elapsedRealtime(), mClock.uptimeMillis()); 16549 } 16550 16551 public Uid.Pkg.Serv getServiceStatsLocked(int uid, String pkg, String name, 16552 long elapsedRealtimeMs, long uptimeMs) { 16553 uid = mapUid(uid); 16554 Uid u = getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs); 16555 return u.getServiceStatsLocked(pkg, name); 16556 } 16557 16558 @GuardedBy("this") 16559 public void shutdownLocked() { 16560 recordShutdownLocked(mClock.currentTimeMillis(), mClock.elapsedRealtime()); 16561 writeSyncLocked(); 16562 mShuttingDown = true; 16563 } 16564 16565 @GuardedBy("this") 16566 @Override 16567 public boolean isProcessStateDataAvailable() { 16568 return trackPerProcStateCpuTimes(); 16569 } 16570 16571 @GuardedBy("this") 16572 public boolean trackPerProcStateCpuTimes() { 16573 return mCpuUidFreqTimeReader.isFastCpuTimesReader(); 16574 } 16575 16576 @GuardedBy("this") 16577 public void systemServicesReady(Context context) { 16578 mConstants.startObserving(context.getContentResolver()); 16579 registerUsbStateReceiver(context); 16580 } 16581 16582 /** 16583 * Initialize the measured charge stats data structures. 16584 * 16585 * @param supportedStandardBuckets boolean array indicating which {@link StandardPowerBucket}s 16586 * are currently supported. If null, none are supported 16587 * (regardless of customBucketNames). 16588 * @param customBucketNames names of custom (OTHER) EnergyConsumers on this device 16589 */ 16590 @GuardedBy("this") 16591 public void initMeasuredEnergyStatsLocked(@Nullable boolean[] supportedStandardBuckets, 16592 String[] customBucketNames) { 16593 final int numDisplays = mPerDisplayBatteryStats.length; 16594 for (int i = 0; i < numDisplays; i++) { 16595 final int screenState = mPerDisplayBatteryStats[i].screenState; 16596 mPerDisplayBatteryStats[i].screenStateAtLastEnergyMeasurement = screenState; 16597 } 16598 16599 final boolean compatibleConfig; 16600 if (supportedStandardBuckets != null) { 16601 final MeasuredEnergyStats.Config config = new MeasuredEnergyStats.Config( 16602 supportedStandardBuckets, customBucketNames, 16603 SUPPORTED_PER_PROCESS_STATE_STANDARD_ENERGY_BUCKETS, 16604 getBatteryConsumerProcessStateNames()); 16605 16606 if (mMeasuredEnergyStatsConfig == null) { 16607 compatibleConfig = true; 16608 } else { 16609 compatibleConfig = mMeasuredEnergyStatsConfig.isCompatible(config); 16610 } 16611 16612 mMeasuredEnergyStatsConfig = config; 16613 mGlobalMeasuredEnergyStats = new MeasuredEnergyStats(config); 16614 16615 if (supportedStandardBuckets[MeasuredEnergyStats.POWER_BUCKET_BLUETOOTH]) { 16616 mBluetoothPowerCalculator = new BluetoothPowerCalculator(mPowerProfile); 16617 } 16618 if (supportedStandardBuckets[MeasuredEnergyStats.POWER_BUCKET_CPU]) { 16619 mCpuPowerCalculator = new CpuPowerCalculator(mPowerProfile); 16620 } 16621 if (supportedStandardBuckets[MeasuredEnergyStats.POWER_BUCKET_MOBILE_RADIO]) { 16622 mMobileRadioPowerCalculator = new MobileRadioPowerCalculator(mPowerProfile); 16623 } 16624 if (supportedStandardBuckets[MeasuredEnergyStats.POWER_BUCKET_WIFI]) { 16625 mWifiPowerCalculator = new WifiPowerCalculator(mPowerProfile); 16626 } 16627 } else { 16628 compatibleConfig = (mMeasuredEnergyStatsConfig == null); 16629 // Measured energy no longer supported, wipe out the existing data. 16630 mMeasuredEnergyStatsConfig = null; 16631 mGlobalMeasuredEnergyStats = null; 16632 } 16633 16634 if (!compatibleConfig) { 16635 // Supported power buckets changed since last boot. 16636 // Existing data is no longer reliable. 16637 resetAllStatsLocked(SystemClock.uptimeMillis(), SystemClock.elapsedRealtime(), 16638 RESET_REASON_MEASURED_ENERGY_BUCKETS_CHANGE); 16639 } 16640 } 16641 16642 @NonNull 16643 private static String[] getBatteryConsumerProcessStateNames() { 16644 String[] procStateNames = new String[BatteryConsumer.PROCESS_STATE_COUNT]; 16645 for (int procState = 0; procState < BatteryConsumer.PROCESS_STATE_COUNT; procState++) { 16646 procStateNames[procState] = BatteryConsumer.processStateToString(procState); 16647 } 16648 return procStateNames; 16649 } 16650 16651 /** Get the last known Battery voltage (in millivolts), returns -1 if unknown */ 16652 @GuardedBy("this") 16653 public int getBatteryVoltageMvLocked() { 16654 return mBatteryVoltageMv; 16655 } 16656 16657 @VisibleForTesting 16658 public final class Constants extends ContentObserver { 16659 public static final String KEY_TRACK_CPU_ACTIVE_CLUSTER_TIME 16660 = "track_cpu_active_cluster_time"; 16661 public static final String KEY_PROC_STATE_CPU_TIMES_READ_DELAY_MS 16662 = "proc_state_cpu_times_read_delay_ms"; 16663 public static final String KEY_KERNEL_UID_READERS_THROTTLE_TIME 16664 = "kernel_uid_readers_throttle_time"; 16665 public static final String KEY_UID_REMOVE_DELAY_MS 16666 = "uid_remove_delay_ms"; 16667 public static final String KEY_EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS 16668 = "external_stats_collection_rate_limit_ms"; 16669 public static final String KEY_BATTERY_LEVEL_COLLECTION_DELAY_MS 16670 = "battery_level_collection_delay_ms"; 16671 public static final String KEY_PROC_STATE_CHANGE_COLLECTION_DELAY_MS = 16672 "procstate_change_collection_delay_ms"; 16673 public static final String KEY_MAX_HISTORY_FILES = "max_history_files"; 16674 public static final String KEY_MAX_HISTORY_BUFFER_KB = "max_history_buffer_kb"; 16675 public static final String KEY_BATTERY_CHARGED_DELAY_MS = 16676 "battery_charged_delay_ms"; 16677 public static final String KEY_PHONE_ON_EXTERNAL_STATS_COLLECTION = 16678 "phone_on_external_stats_collection"; 16679 16680 private static final boolean DEFAULT_TRACK_CPU_ACTIVE_CLUSTER_TIME = true; 16681 private static final long DEFAULT_KERNEL_UID_READERS_THROTTLE_TIME = 1_000; 16682 private static final long DEFAULT_UID_REMOVE_DELAY_MS = 5L * 60L * 1000L; 16683 private static final long DEFAULT_EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS = 600_000; 16684 private static final long DEFAULT_BATTERY_LEVEL_COLLECTION_DELAY_MS = 300_000; 16685 private static final long DEFAULT_PROC_STATE_CHANGE_COLLECTION_DELAY_MS = 60_000; 16686 private static final int DEFAULT_MAX_HISTORY_FILES = 32; 16687 private static final int DEFAULT_MAX_HISTORY_BUFFER_KB = 128; /*Kilo Bytes*/ 16688 private static final int DEFAULT_MAX_HISTORY_FILES_LOW_RAM_DEVICE = 64; 16689 private static final int DEFAULT_MAX_HISTORY_BUFFER_LOW_RAM_DEVICE_KB = 64; /*Kilo Bytes*/ 16690 private static final int DEFAULT_BATTERY_CHARGED_DELAY_MS = 900000; /* 15 min */ 16691 private static final boolean DEFAULT_PHONE_ON_EXTERNAL_STATS_COLLECTION = true; 16692 16693 public boolean TRACK_CPU_ACTIVE_CLUSTER_TIME = DEFAULT_TRACK_CPU_ACTIVE_CLUSTER_TIME; 16694 /* Do not set default value for KERNEL_UID_READERS_THROTTLE_TIME. Need to trigger an 16695 * update when startObserving. */ 16696 public long KERNEL_UID_READERS_THROTTLE_TIME; 16697 public long UID_REMOVE_DELAY_MS = DEFAULT_UID_REMOVE_DELAY_MS; 16698 public long EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS 16699 = DEFAULT_EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS; 16700 public long BATTERY_LEVEL_COLLECTION_DELAY_MS 16701 = DEFAULT_BATTERY_LEVEL_COLLECTION_DELAY_MS; 16702 public long PROC_STATE_CHANGE_COLLECTION_DELAY_MS = 16703 DEFAULT_PROC_STATE_CHANGE_COLLECTION_DELAY_MS; 16704 public int MAX_HISTORY_FILES; 16705 public int MAX_HISTORY_BUFFER; /*Bytes*/ 16706 public int BATTERY_CHARGED_DELAY_MS = DEFAULT_BATTERY_CHARGED_DELAY_MS; 16707 public boolean PHONE_ON_EXTERNAL_STATS_COLLECTION = 16708 DEFAULT_PHONE_ON_EXTERNAL_STATS_COLLECTION; 16709 16710 private ContentResolver mResolver; 16711 private final KeyValueListParser mParser = new KeyValueListParser(','); 16712 16713 public Constants(Handler handler) { 16714 super(handler); 16715 if (ActivityManager.isLowRamDeviceStatic()) { 16716 MAX_HISTORY_FILES = DEFAULT_MAX_HISTORY_FILES_LOW_RAM_DEVICE; 16717 MAX_HISTORY_BUFFER = DEFAULT_MAX_HISTORY_BUFFER_LOW_RAM_DEVICE_KB * 1024; 16718 } else { 16719 MAX_HISTORY_FILES = DEFAULT_MAX_HISTORY_FILES; 16720 MAX_HISTORY_BUFFER = DEFAULT_MAX_HISTORY_BUFFER_KB * 1024; 16721 } 16722 } 16723 16724 public void startObserving(ContentResolver resolver) { 16725 mResolver = resolver; 16726 mResolver.registerContentObserver( 16727 Settings.Global.getUriFor(Settings.Global.BATTERY_STATS_CONSTANTS), 16728 false /* notifyForDescendants */, this); 16729 mResolver.registerContentObserver( 16730 Settings.Global.getUriFor(Settings.Global.BATTERY_CHARGING_STATE_UPDATE_DELAY), 16731 false /* notifyForDescendants */, this); 16732 updateConstants(); 16733 } 16734 16735 @Override 16736 public void onChange(boolean selfChange, Uri uri) { 16737 if (uri.equals( 16738 Settings.Global.getUriFor( 16739 Settings.Global.BATTERY_CHARGING_STATE_UPDATE_DELAY))) { 16740 synchronized (BatteryStatsImpl.this) { 16741 updateBatteryChargedDelayMsLocked(); 16742 } 16743 return; 16744 } 16745 updateConstants(); 16746 } 16747 16748 private void updateConstants() { 16749 synchronized (BatteryStatsImpl.this) { 16750 try { 16751 mParser.setString(Settings.Global.getString(mResolver, 16752 Settings.Global.BATTERY_STATS_CONSTANTS)); 16753 } catch (IllegalArgumentException e) { 16754 // Failed to parse the settings string, log this and move on 16755 // with defaults. 16756 Slog.e(TAG, "Bad batterystats settings", e); 16757 } 16758 16759 TRACK_CPU_ACTIVE_CLUSTER_TIME = mParser.getBoolean( 16760 KEY_TRACK_CPU_ACTIVE_CLUSTER_TIME, DEFAULT_TRACK_CPU_ACTIVE_CLUSTER_TIME); 16761 updateKernelUidReadersThrottleTime(KERNEL_UID_READERS_THROTTLE_TIME, 16762 mParser.getLong(KEY_KERNEL_UID_READERS_THROTTLE_TIME, 16763 DEFAULT_KERNEL_UID_READERS_THROTTLE_TIME)); 16764 updateUidRemoveDelay( 16765 mParser.getLong(KEY_UID_REMOVE_DELAY_MS, DEFAULT_UID_REMOVE_DELAY_MS)); 16766 EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS = mParser.getLong( 16767 KEY_EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS, 16768 DEFAULT_EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS); 16769 BATTERY_LEVEL_COLLECTION_DELAY_MS = mParser.getLong( 16770 KEY_BATTERY_LEVEL_COLLECTION_DELAY_MS, 16771 DEFAULT_BATTERY_LEVEL_COLLECTION_DELAY_MS); 16772 PROC_STATE_CHANGE_COLLECTION_DELAY_MS = mParser.getLong( 16773 KEY_PROC_STATE_CHANGE_COLLECTION_DELAY_MS, 16774 DEFAULT_PROC_STATE_CHANGE_COLLECTION_DELAY_MS); 16775 16776 MAX_HISTORY_FILES = mParser.getInt(KEY_MAX_HISTORY_FILES, 16777 ActivityManager.isLowRamDeviceStatic() ? 16778 DEFAULT_MAX_HISTORY_FILES_LOW_RAM_DEVICE 16779 : DEFAULT_MAX_HISTORY_FILES); 16780 MAX_HISTORY_BUFFER = mParser.getInt(KEY_MAX_HISTORY_BUFFER_KB, 16781 ActivityManager.isLowRamDeviceStatic() ? 16782 DEFAULT_MAX_HISTORY_BUFFER_LOW_RAM_DEVICE_KB 16783 : DEFAULT_MAX_HISTORY_BUFFER_KB) 16784 * 1024; 16785 16786 PHONE_ON_EXTERNAL_STATS_COLLECTION = mParser.getBoolean( 16787 KEY_PHONE_ON_EXTERNAL_STATS_COLLECTION, 16788 DEFAULT_PHONE_ON_EXTERNAL_STATS_COLLECTION); 16789 16790 updateBatteryChargedDelayMsLocked(); 16791 } 16792 } 16793 16794 private void updateBatteryChargedDelayMsLocked() { 16795 // a negative value indicates that we should ignore this override 16796 final int delay = Settings.Global.getInt(mResolver, 16797 Settings.Global.BATTERY_CHARGING_STATE_UPDATE_DELAY, 16798 -1); 16799 16800 BATTERY_CHARGED_DELAY_MS = delay >= 0 ? delay : mParser.getInt( 16801 KEY_BATTERY_CHARGED_DELAY_MS, 16802 DEFAULT_BATTERY_CHARGED_DELAY_MS); 16803 16804 if (mHandler.hasCallbacks(mDeferSetCharging)) { 16805 mHandler.removeCallbacks(mDeferSetCharging); 16806 mHandler.postDelayed(mDeferSetCharging, BATTERY_CHARGED_DELAY_MS); 16807 } 16808 } 16809 16810 private void updateKernelUidReadersThrottleTime(long oldTimeMs, long newTimeMs) { 16811 KERNEL_UID_READERS_THROTTLE_TIME = newTimeMs; 16812 if (oldTimeMs != newTimeMs) { 16813 mCpuUidUserSysTimeReader.setThrottle(KERNEL_UID_READERS_THROTTLE_TIME); 16814 mCpuUidFreqTimeReader.setThrottle(KERNEL_UID_READERS_THROTTLE_TIME); 16815 mCpuUidActiveTimeReader.setThrottle(KERNEL_UID_READERS_THROTTLE_TIME); 16816 mCpuUidClusterTimeReader 16817 .setThrottle(KERNEL_UID_READERS_THROTTLE_TIME); 16818 } 16819 } 16820 16821 @GuardedBy("BatteryStatsImpl.this") 16822 private void updateUidRemoveDelay(long newTimeMs) { 16823 UID_REMOVE_DELAY_MS = newTimeMs; 16824 clearPendingRemovedUidsLocked(); 16825 } 16826 16827 public void dumpLocked(PrintWriter pw) { 16828 pw.print(KEY_TRACK_CPU_ACTIVE_CLUSTER_TIME); pw.print("="); 16829 pw.println(TRACK_CPU_ACTIVE_CLUSTER_TIME); 16830 pw.print(KEY_KERNEL_UID_READERS_THROTTLE_TIME); pw.print("="); 16831 pw.println(KERNEL_UID_READERS_THROTTLE_TIME); 16832 pw.print(KEY_EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS); pw.print("="); 16833 pw.println(EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS); 16834 pw.print(KEY_BATTERY_LEVEL_COLLECTION_DELAY_MS); pw.print("="); 16835 pw.println(BATTERY_LEVEL_COLLECTION_DELAY_MS); 16836 pw.print(KEY_PROC_STATE_CHANGE_COLLECTION_DELAY_MS); pw.print("="); 16837 pw.println(PROC_STATE_CHANGE_COLLECTION_DELAY_MS); 16838 pw.print(KEY_MAX_HISTORY_FILES); pw.print("="); 16839 pw.println(MAX_HISTORY_FILES); 16840 pw.print(KEY_MAX_HISTORY_BUFFER_KB); pw.print("="); 16841 pw.println(MAX_HISTORY_BUFFER/1024); 16842 pw.print(KEY_BATTERY_CHARGED_DELAY_MS); pw.print("="); 16843 pw.println(BATTERY_CHARGED_DELAY_MS); 16844 pw.print(KEY_PHONE_ON_EXTERNAL_STATS_COLLECTION); pw.print("="); 16845 pw.println(PHONE_ON_EXTERNAL_STATS_COLLECTION); 16846 } 16847 } 16848 16849 public long getExternalStatsCollectionRateLimitMs() { 16850 synchronized (this) { 16851 return mConstants.EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS; 16852 } 16853 } 16854 16855 @GuardedBy("this") 16856 public void dumpConstantsLocked(PrintWriter pw) { 16857 final IndentingPrintWriter iPw = new IndentingPrintWriter(pw, " "); 16858 iPw.println("BatteryStats constants:"); 16859 iPw.increaseIndent(); 16860 mConstants.dumpLocked(iPw); 16861 iPw.decreaseIndent(); 16862 } 16863 16864 @GuardedBy("this") 16865 public void dumpCpuStatsLocked(PrintWriter pw) { 16866 int size = mUidStats.size(); 16867 pw.println("Per UID CPU user & system time in ms:"); 16868 for (int i = 0; i < size; i++) { 16869 int u = mUidStats.keyAt(i); 16870 Uid uid = mUidStats.get(u); 16871 pw.print(" "); pw.print(u); pw.print(": "); 16872 pw.print(uid.getUserCpuTimeUs(STATS_SINCE_CHARGED) / 1000); pw.print(" "); 16873 pw.println(uid.getSystemCpuTimeUs(STATS_SINCE_CHARGED) / 1000); 16874 } 16875 16876 pw.println("Per UID CPU active time in ms:"); 16877 for (int i = 0; i < size; i++) { 16878 int u = mUidStats.keyAt(i); 16879 Uid uid = mUidStats.get(u); 16880 if (uid.getCpuActiveTime() > 0) { 16881 pw.print(" "); pw.print(u); pw.print(": "); pw.println(uid.getCpuActiveTime()); 16882 } 16883 } 16884 pw.println("Per UID CPU cluster time in ms:"); 16885 for (int i = 0; i < size; i++) { 16886 int u = mUidStats.keyAt(i); 16887 long[] times = mUidStats.get(u).getCpuClusterTimes(); 16888 if (times != null) { 16889 pw.print(" "); pw.print(u); pw.print(": "); pw.println(Arrays.toString(times)); 16890 } 16891 } 16892 pw.println("Per UID CPU frequency time in ms:"); 16893 for (int i = 0; i < size; i++) { 16894 int u = mUidStats.keyAt(i); 16895 long[] times = mUidStats.get(u).getCpuFreqTimes(STATS_SINCE_CHARGED); 16896 if (times != null) { 16897 pw.print(" "); pw.print(u); pw.print(": "); pw.println(Arrays.toString(times)); 16898 } 16899 } 16900 16901 updateSystemServiceCallStats(); 16902 if (mBinderThreadCpuTimesUs != null) { 16903 pw.println("Per UID System server binder time in ms:"); 16904 long[] systemServiceTimeAtCpuSpeeds = getSystemServiceTimeAtCpuSpeeds(); 16905 for (int i = 0; i < size; i++) { 16906 int u = mUidStats.keyAt(i); 16907 Uid uid = mUidStats.get(u); 16908 double proportionalSystemServiceUsage = uid.getProportionalSystemServiceUsage(); 16909 long timeUs = 0; 16910 for (int j = systemServiceTimeAtCpuSpeeds.length - 1; j >= 0; j--) { 16911 timeUs += systemServiceTimeAtCpuSpeeds[j] * proportionalSystemServiceUsage; 16912 } 16913 16914 pw.print(" "); 16915 pw.print(u); 16916 pw.print(": "); 16917 pw.println(timeUs / 1000); 16918 } 16919 } 16920 } 16921 16922 /** 16923 * Dump measured charge stats 16924 */ 16925 @GuardedBy("this") 16926 public void dumpMeasuredEnergyStatsLocked(PrintWriter pw) { 16927 pw.printf("On battery measured charge stats (microcoulombs) \n"); 16928 if (mGlobalMeasuredEnergyStats == null) { 16929 pw.printf(" Not supported on this device.\n"); 16930 return; 16931 } 16932 16933 dumpMeasuredEnergyStatsLocked(pw, "global usage", mGlobalMeasuredEnergyStats); 16934 16935 int size = mUidStats.size(); 16936 for (int i = 0; i < size; i++) { 16937 final int u = mUidStats.keyAt(i); 16938 final Uid uid = mUidStats.get(u); 16939 final String name = "uid " + uid.mUid; 16940 dumpMeasuredEnergyStatsLocked(pw, name, uid.mUidMeasuredEnergyStats); 16941 } 16942 } 16943 16944 /** Dump measured charge stats for the given uid */ 16945 @GuardedBy("this") 16946 private void dumpMeasuredEnergyStatsLocked(PrintWriter pw, String name, 16947 MeasuredEnergyStats stats) { 16948 if (stats == null) return; 16949 final IndentingPrintWriter iPw = new IndentingPrintWriter(pw, " "); 16950 iPw.increaseIndent(); 16951 iPw.printf("%s:\n", name); 16952 iPw.increaseIndent(); 16953 stats.dump(iPw); 16954 iPw.decreaseIndent(); 16955 } 16956 16957 /** 16958 * Dump Power Profile 16959 */ 16960 @GuardedBy("this") 16961 public void dumpPowerProfileLocked(PrintWriter pw) { 16962 final IndentingPrintWriter iPw = new IndentingPrintWriter(pw, " "); 16963 iPw.printf("Power Profile: \n"); 16964 iPw.increaseIndent(); 16965 mPowerProfile.dump(iPw); 16966 iPw.decreaseIndent(); 16967 } 16968 16969 final ReentrantLock mWriteLock = new ReentrantLock(); 16970 16971 @GuardedBy("this") 16972 public void writeAsyncLocked() { 16973 writeStatsLocked(false); 16974 writeHistoryLocked(false); 16975 } 16976 16977 @GuardedBy("this") 16978 public void writeSyncLocked() { 16979 writeStatsLocked(true); 16980 writeHistoryLocked(true); 16981 } 16982 16983 @GuardedBy("this") 16984 void writeStatsLocked(boolean sync) { 16985 if (mStatsFile == null) { 16986 Slog.w(TAG, 16987 "writeStatsLocked: no file associated with this instance"); 16988 return; 16989 } 16990 16991 if (mShuttingDown) { 16992 return; 16993 } 16994 16995 final Parcel p = Parcel.obtain(); 16996 final long start = SystemClock.uptimeMillis(); 16997 writeSummaryToParcel(p, false/*history is in separate file*/); 16998 if (DEBUG) { 16999 Slog.d(TAG, "writeSummaryToParcel duration ms:" 17000 + (SystemClock.uptimeMillis() - start) + " bytes:" + p.dataSize()); 17001 } 17002 mLastWriteTimeMs = mClock.elapsedRealtime(); 17003 writeParcelToFileLocked(p, mStatsFile, sync); 17004 } 17005 17006 void writeHistoryLocked(boolean sync) { 17007 if (mBatteryStatsHistory.getActiveFile() == null) { 17008 Slog.w(TAG, 17009 "writeHistoryLocked: no history file associated with this instance"); 17010 return; 17011 } 17012 17013 if (mShuttingDown) { 17014 return; 17015 } 17016 17017 Parcel p = Parcel.obtain(); 17018 final long start = SystemClock.uptimeMillis(); 17019 writeHistoryBuffer(p, true); 17020 if (DEBUG) { 17021 Slog.d(TAG, "writeHistoryBuffer duration ms:" 17022 + (SystemClock.uptimeMillis() - start) + " bytes:" + p.dataSize()); 17023 } 17024 writeParcelToFileLocked(p, mBatteryStatsHistory.getActiveFile(), sync); 17025 } 17026 17027 void writeParcelToFileLocked(Parcel p, AtomicFile file, boolean sync) { 17028 if (sync) { 17029 commitPendingDataToDisk(p, file); 17030 } else { 17031 BackgroundThread.getHandler().post(new Runnable() { 17032 @Override public void run() { 17033 commitPendingDataToDisk(p, file); 17034 } 17035 }); 17036 } 17037 } 17038 17039 private void commitPendingDataToDisk(Parcel p, AtomicFile file) { 17040 mWriteLock.lock(); 17041 FileOutputStream fos = null; 17042 try { 17043 final long startTimeMs = SystemClock.uptimeMillis(); 17044 fos = file.startWrite(); 17045 fos.write(p.marshall()); 17046 fos.flush(); 17047 file.finishWrite(fos); 17048 if (DEBUG) { 17049 Slog.d(TAG, "commitPendingDataToDisk file:" + file.getBaseFile().getPath() 17050 + " duration ms:" + (SystemClock.uptimeMillis() - startTimeMs) 17051 + " bytes:" + p.dataSize()); 17052 } 17053 com.android.internal.logging.EventLogTags.writeCommitSysConfigFile( 17054 "batterystats", SystemClock.uptimeMillis() - startTimeMs); 17055 } catch (IOException e) { 17056 Slog.w(TAG, "Error writing battery statistics", e); 17057 file.failWrite(fos); 17058 } finally { 17059 p.recycle(); 17060 mWriteLock.unlock(); 17061 } 17062 } 17063 17064 @UnsupportedAppUsage 17065 @GuardedBy("this") 17066 public void readLocked() { 17067 if (mDailyFile != null) { 17068 readDailyStatsLocked(); 17069 } 17070 17071 if (mStatsFile == null) { 17072 Slog.w(TAG, "readLocked: no file associated with this instance"); 17073 return; 17074 } 17075 17076 final AtomicFile activeHistoryFile = mBatteryStatsHistory.getActiveFile(); 17077 if (activeHistoryFile == null) { 17078 Slog.w(TAG, 17079 "readLocked: no history file associated with this instance"); 17080 return; 17081 } 17082 17083 mUidStats.clear(); 17084 17085 Parcel stats = Parcel.obtain(); 17086 try { 17087 final long start = SystemClock.uptimeMillis(); 17088 if (mStatsFile.exists()) { 17089 byte[] raw = mStatsFile.readFully(); 17090 stats.unmarshall(raw, 0, raw.length); 17091 stats.setDataPosition(0); 17092 readSummaryFromParcel(stats); 17093 if (DEBUG) { 17094 Slog.d(TAG, "readLocked stats file:" + mStatsFile.getBaseFile().getPath() 17095 + " bytes:" + raw.length + " takes ms:" + (SystemClock.uptimeMillis() 17096 - start)); 17097 } 17098 } 17099 } catch (Exception e) { 17100 Slog.e(TAG, "Error reading battery statistics", e); 17101 resetAllStatsLocked(SystemClock.uptimeMillis(), SystemClock.elapsedRealtime(), 17102 RESET_REASON_CORRUPT_FILE); 17103 } finally { 17104 stats.recycle(); 17105 } 17106 17107 Parcel history = Parcel.obtain(); 17108 try { 17109 final long start = SystemClock.uptimeMillis(); 17110 if (activeHistoryFile.exists()) { 17111 byte[] raw = activeHistoryFile.readFully(); 17112 if (raw.length > 0) { 17113 history.unmarshall(raw, 0, raw.length); 17114 history.setDataPosition(0); 17115 readHistoryBuffer(history); 17116 } 17117 if (DEBUG) { 17118 Slog.d(TAG, "readLocked history file::" 17119 + activeHistoryFile.getBaseFile().getPath() 17120 + " bytes:" + raw.length + " takes ms:" + (SystemClock.uptimeMillis() 17121 - start)); 17122 } 17123 } 17124 } catch (Exception e) { 17125 Slog.e(TAG, "Error reading battery history", e); 17126 clearHistoryLocked(); 17127 mBatteryStatsHistory.resetAllFiles(); 17128 } finally { 17129 history.recycle(); 17130 } 17131 17132 mEndPlatformVersion = Build.ID; 17133 17134 if (mHistoryBuffer.dataPosition() > 0 17135 || mBatteryStatsHistory.getFilesNumbers().size() > 1) { 17136 mRecordingHistory = true; 17137 final long elapsedRealtimeMs = mClock.elapsedRealtime(); 17138 final long uptimeMs = mClock.uptimeMillis(); 17139 addHistoryBufferLocked(elapsedRealtimeMs, HistoryItem.CMD_START, mHistoryCur); 17140 startRecordingHistory(elapsedRealtimeMs, uptimeMs, false); 17141 } 17142 17143 recordDailyStatsIfNeededLocked(false, mClock.currentTimeMillis()); 17144 } 17145 17146 public int describeContents() { 17147 return 0; 17148 } 17149 17150 @GuardedBy("this") 17151 void readHistoryBuffer(Parcel in) throws ParcelFormatException { 17152 final int version = in.readInt(); 17153 if (version != VERSION) { 17154 Slog.w("BatteryStats", "readHistoryBuffer: version got " + version 17155 + ", expected " + VERSION + "; erasing old stats"); 17156 return; 17157 } 17158 17159 final long historyBaseTime = in.readLong(); 17160 17161 mHistoryBuffer.setDataSize(0); 17162 mHistoryBuffer.setDataPosition(0); 17163 17164 int bufSize = in.readInt(); 17165 int curPos = in.dataPosition(); 17166 if (bufSize >= (mConstants.MAX_HISTORY_BUFFER*100)) { 17167 throw new ParcelFormatException("File corrupt: history data buffer too large " + 17168 bufSize); 17169 } else if ((bufSize&~3) != bufSize) { 17170 throw new ParcelFormatException("File corrupt: history data buffer not aligned " + 17171 bufSize); 17172 } else { 17173 if (DEBUG_HISTORY) Slog.i(TAG, "***************** READING NEW HISTORY: " + bufSize 17174 + " bytes at " + curPos); 17175 mHistoryBuffer.appendFrom(in, curPos, bufSize); 17176 in.setDataPosition(curPos + bufSize); 17177 } 17178 17179 if (DEBUG_HISTORY) { 17180 StringBuilder sb = new StringBuilder(128); 17181 sb.append("****************** OLD mHistoryBaseTimeMs: "); 17182 TimeUtils.formatDuration(mHistoryBaseTimeMs, sb); 17183 Slog.i(TAG, sb.toString()); 17184 } 17185 mHistoryBaseTimeMs = historyBaseTime; 17186 if (DEBUG_HISTORY) { 17187 StringBuilder sb = new StringBuilder(128); 17188 sb.append("****************** NEW mHistoryBaseTimeMs: "); 17189 TimeUtils.formatDuration(mHistoryBaseTimeMs, sb); 17190 Slog.i(TAG, sb.toString()); 17191 } 17192 17193 // We are just arbitrarily going to insert 1 minute from the sample of 17194 // the last run until samples in this run. 17195 if (mHistoryBaseTimeMs > 0) { 17196 long oldnow = mClock.elapsedRealtime(); 17197 mHistoryBaseTimeMs = mHistoryBaseTimeMs - oldnow + 1; 17198 if (DEBUG_HISTORY) { 17199 StringBuilder sb = new StringBuilder(128); 17200 sb.append("****************** ADJUSTED mHistoryBaseTimeMs: "); 17201 TimeUtils.formatDuration(mHistoryBaseTimeMs, sb); 17202 Slog.i(TAG, sb.toString()); 17203 } 17204 } 17205 } 17206 17207 void writeHistoryBuffer(Parcel out, boolean inclData) { 17208 if (DEBUG_HISTORY) { 17209 StringBuilder sb = new StringBuilder(128); 17210 sb.append("****************** WRITING mHistoryBaseTimeMs: "); 17211 TimeUtils.formatDuration(mHistoryBaseTimeMs, sb); 17212 sb.append(" mLastHistoryElapsedRealtimeMs: "); 17213 TimeUtils.formatDuration(mLastHistoryElapsedRealtimeMs, sb); 17214 Slog.i(TAG, sb.toString()); 17215 } 17216 out.writeInt(VERSION); 17217 out.writeLong(mHistoryBaseTimeMs + mLastHistoryElapsedRealtimeMs); 17218 if (!inclData) { 17219 out.writeInt(0); 17220 out.writeInt(0); 17221 return; 17222 } 17223 17224 out.writeInt(mHistoryBuffer.dataSize()); 17225 if (DEBUG_HISTORY) Slog.i(TAG, "***************** WRITING HISTORY: " 17226 + mHistoryBuffer.dataSize() + " bytes at " + out.dataPosition()); 17227 out.appendFrom(mHistoryBuffer, 0, mHistoryBuffer.dataSize()); 17228 } 17229 17230 @GuardedBy("this") 17231 public void readSummaryFromParcel(Parcel in) throws ParcelFormatException { 17232 final int version = in.readInt(); 17233 17234 if (version != VERSION) { 17235 Slog.w("BatteryStats", "readFromParcel: version got " + version 17236 + ", expected " + VERSION + "; erasing old stats"); 17237 return; 17238 } 17239 17240 boolean inclHistory = in.readBoolean(); 17241 if (inclHistory) { 17242 readHistoryBuffer(in); 17243 mBatteryStatsHistory.readFromParcel(in); 17244 } 17245 17246 mHistoryTagPool.clear(); 17247 mNextHistoryTagIdx = 0; 17248 mNumHistoryTagChars = 0; 17249 17250 int numTags = in.readInt(); 17251 for (int i=0; i<numTags; i++) { 17252 int idx = in.readInt(); 17253 String str = in.readString(); 17254 int uid = in.readInt(); 17255 HistoryTag tag = new HistoryTag(); 17256 tag.string = str; 17257 tag.uid = uid; 17258 tag.poolIdx = idx; 17259 mHistoryTagPool.put(tag, idx); 17260 if (idx >= mNextHistoryTagIdx) { 17261 mNextHistoryTagIdx = idx+1; 17262 } 17263 mNumHistoryTagChars += tag.string.length() + 1; 17264 } 17265 17266 mStartCount = in.readInt(); 17267 mUptimeUs = in.readLong(); 17268 mRealtimeUs = in.readLong(); 17269 mStartClockTimeMs = in.readLong(); 17270 mStartPlatformVersion = in.readString(); 17271 mEndPlatformVersion = in.readString(); 17272 mOnBatteryTimeBase.readSummaryFromParcel(in); 17273 mOnBatteryScreenOffTimeBase.readSummaryFromParcel(in); 17274 mDischargeUnplugLevel = in.readInt(); 17275 mDischargePlugLevel = in.readInt(); 17276 mDischargeCurrentLevel = in.readInt(); 17277 mCurrentBatteryLevel = in.readInt(); 17278 mEstimatedBatteryCapacityMah = in.readInt(); 17279 mLastLearnedBatteryCapacityUah = in.readInt(); 17280 mMinLearnedBatteryCapacityUah = in.readInt(); 17281 mMaxLearnedBatteryCapacityUah = in.readInt(); 17282 mLowDischargeAmountSinceCharge = in.readInt(); 17283 mHighDischargeAmountSinceCharge = in.readInt(); 17284 mDischargeAmountScreenOnSinceCharge = in.readInt(); 17285 mDischargeAmountScreenOffSinceCharge = in.readInt(); 17286 mDischargeAmountScreenDozeSinceCharge = in.readInt(); 17287 mDischargeStepTracker.readFromParcel(in); 17288 mChargeStepTracker.readFromParcel(in); 17289 mDailyDischargeStepTracker.readFromParcel(in); 17290 mDailyChargeStepTracker.readFromParcel(in); 17291 mDischargeCounter.readSummaryFromParcelLocked(in); 17292 mDischargeScreenOffCounter.readSummaryFromParcelLocked(in); 17293 mDischargeScreenDozeCounter.readSummaryFromParcelLocked(in); 17294 mDischargeLightDozeCounter.readSummaryFromParcelLocked(in); 17295 mDischargeDeepDozeCounter.readSummaryFromParcelLocked(in); 17296 int NPKG = in.readInt(); 17297 if (NPKG > 0) { 17298 mDailyPackageChanges = new ArrayList<>(NPKG); 17299 while (NPKG > 0) { 17300 NPKG--; 17301 PackageChange pc = new PackageChange(); 17302 pc.mPackageName = in.readString(); 17303 pc.mUpdate = in.readInt() != 0; 17304 pc.mVersionCode = in.readLong(); 17305 mDailyPackageChanges.add(pc); 17306 } 17307 } else { 17308 mDailyPackageChanges = null; 17309 } 17310 mDailyStartTimeMs = in.readLong(); 17311 mNextMinDailyDeadlineMs = in.readLong(); 17312 mNextMaxDailyDeadlineMs = in.readLong(); 17313 mBatteryTimeToFullSeconds = in.readLong(); 17314 17315 final MeasuredEnergyStats.Config config = MeasuredEnergyStats.Config.createFromParcel(in); 17316 final MeasuredEnergyStats measuredEnergyStats = 17317 MeasuredEnergyStats.createAndReadSummaryFromParcel(mMeasuredEnergyStatsConfig, in); 17318 if (config != null && Arrays.equals(config.getStateNames(), 17319 getBatteryConsumerProcessStateNames())) { 17320 /** 17321 * WARNING: Supported buckets may have changed across boots. Bucket mismatch is handled 17322 * later when {@link #initMeasuredEnergyStatsLocked} is called. 17323 */ 17324 mMeasuredEnergyStatsConfig = config; 17325 mGlobalMeasuredEnergyStats = measuredEnergyStats; 17326 } 17327 17328 mStartCount++; 17329 17330 mScreenState = Display.STATE_UNKNOWN; 17331 mScreenOnTimer.readSummaryFromParcelLocked(in); 17332 mScreenDozeTimer.readSummaryFromParcelLocked(in); 17333 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 17334 mScreenBrightnessTimer[i].readSummaryFromParcelLocked(in); 17335 } 17336 mInteractive = false; 17337 mInteractiveTimer.readSummaryFromParcelLocked(in); 17338 mPhoneOn = false; 17339 mPowerSaveModeEnabledTimer.readSummaryFromParcelLocked(in); 17340 mLongestLightIdleTimeMs = in.readLong(); 17341 mLongestFullIdleTimeMs = in.readLong(); 17342 mDeviceIdleModeLightTimer.readSummaryFromParcelLocked(in); 17343 mDeviceIdleModeFullTimer.readSummaryFromParcelLocked(in); 17344 mDeviceLightIdlingTimer.readSummaryFromParcelLocked(in); 17345 mDeviceIdlingTimer.readSummaryFromParcelLocked(in); 17346 mPhoneOnTimer.readSummaryFromParcelLocked(in); 17347 for (int i = 0; i < CellSignalStrength.getNumSignalStrengthLevels(); i++) { 17348 mPhoneSignalStrengthsTimer[i].readSummaryFromParcelLocked(in); 17349 } 17350 mPhoneSignalScanningTimer.readSummaryFromParcelLocked(in); 17351 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 17352 mPhoneDataConnectionsTimer[i].readSummaryFromParcelLocked(in); 17353 } 17354 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 17355 mNetworkByteActivityCounters[i].readSummaryFromParcelLocked(in); 17356 mNetworkPacketActivityCounters[i].readSummaryFromParcelLocked(in); 17357 } 17358 17359 final int numRat = in.readInt(); 17360 for (int i = 0; i < numRat; i++) { 17361 if (in.readInt() == 0) continue; 17362 getRatBatteryStatsLocked(i).readSummaryFromParcel(in); 17363 } 17364 17365 mMobileRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW; 17366 mMobileRadioActiveTimer.readSummaryFromParcelLocked(in); 17367 mMobileRadioActivePerAppTimer.readSummaryFromParcelLocked(in); 17368 mMobileRadioActiveAdjustedTime.readSummaryFromParcelLocked(in); 17369 mMobileRadioActiveUnknownTime.readSummaryFromParcelLocked(in); 17370 mMobileRadioActiveUnknownCount.readSummaryFromParcelLocked(in); 17371 mWifiMulticastWakelockTimer.readSummaryFromParcelLocked(in); 17372 mWifiRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW; 17373 mWifiOn = false; 17374 mWifiOnTimer.readSummaryFromParcelLocked(in); 17375 mGlobalWifiRunning = false; 17376 mGlobalWifiRunningTimer.readSummaryFromParcelLocked(in); 17377 for (int i=0; i<NUM_WIFI_STATES; i++) { 17378 mWifiStateTimer[i].readSummaryFromParcelLocked(in); 17379 } 17380 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) { 17381 mWifiSupplStateTimer[i].readSummaryFromParcelLocked(in); 17382 } 17383 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { 17384 mWifiSignalStrengthsTimer[i].readSummaryFromParcelLocked(in); 17385 } 17386 mWifiActiveTimer.readSummaryFromParcelLocked(in); 17387 mWifiActivity.readSummaryFromParcel(in); 17388 for (int i=0; i<mGpsSignalQualityTimer.length; i++) { 17389 mGpsSignalQualityTimer[i].readSummaryFromParcelLocked(in); 17390 } 17391 mBluetoothActivity.readSummaryFromParcel(in); 17392 mModemActivity.readSummaryFromParcel(in); 17393 mHasWifiReporting = in.readInt() != 0; 17394 mHasBluetoothReporting = in.readInt() != 0; 17395 mHasModemReporting = in.readInt() != 0; 17396 17397 mNumConnectivityChange = in.readInt(); 17398 mFlashlightOnNesting = 0; 17399 mFlashlightOnTimer.readSummaryFromParcelLocked(in); 17400 mCameraOnNesting = 0; 17401 mCameraOnTimer.readSummaryFromParcelLocked(in); 17402 mBluetoothScanNesting = 0; 17403 mBluetoothScanTimer.readSummaryFromParcelLocked(in); 17404 17405 int NRPMS = in.readInt(); 17406 if (NRPMS > 10000) { 17407 throw new ParcelFormatException("File corrupt: too many rpm stats " + NRPMS); 17408 } 17409 for (int irpm = 0; irpm < NRPMS; irpm++) { 17410 if (in.readInt() != 0) { 17411 String rpmName = in.readString(); 17412 getRpmTimerLocked(rpmName).readSummaryFromParcelLocked(in); 17413 } 17414 } 17415 int NSORPMS = in.readInt(); 17416 if (NSORPMS > 10000) { 17417 throw new ParcelFormatException("File corrupt: too many screen-off rpm stats " + NSORPMS); 17418 } 17419 for (int irpm = 0; irpm < NSORPMS; irpm++) { 17420 if (in.readInt() != 0) { 17421 String rpmName = in.readString(); 17422 getScreenOffRpmTimerLocked(rpmName).readSummaryFromParcelLocked(in); 17423 } 17424 } 17425 int NKW = in.readInt(); 17426 if (NKW > 10000) { 17427 throw new ParcelFormatException("File corrupt: too many kernel wake locks " + NKW); 17428 } 17429 for (int ikw = 0; ikw < NKW; ikw++) { 17430 if (in.readInt() != 0) { 17431 String kwltName = in.readString(); 17432 getKernelWakelockTimerLocked(kwltName).readSummaryFromParcelLocked(in); 17433 } 17434 } 17435 17436 int NWR = in.readInt(); 17437 if (NWR > 10000) { 17438 throw new ParcelFormatException("File corrupt: too many wakeup reasons " + NWR); 17439 } 17440 for (int iwr = 0; iwr < NWR; iwr++) { 17441 if (in.readInt() != 0) { 17442 String reasonName = in.readString(); 17443 getWakeupReasonTimerLocked(reasonName).readSummaryFromParcelLocked(in); 17444 } 17445 } 17446 17447 int NMS = in.readInt(); 17448 for (int ims = 0; ims < NMS; ims++) { 17449 if (in.readInt() != 0) { 17450 long kmstName = in.readLong(); 17451 getKernelMemoryTimerLocked(kmstName).readSummaryFromParcelLocked(in); 17452 } 17453 } 17454 17455 final int NU = in.readInt(); 17456 if (NU > 10000) { 17457 throw new ParcelFormatException("File corrupt: too many uids " + NU); 17458 } 17459 final long elapsedRealtimeMs = mClock.elapsedRealtime(); 17460 final long uptimeMs = mClock.uptimeMillis(); 17461 for (int iu = 0; iu < NU; iu++) { 17462 int uid = in.readInt(); 17463 Uid u = new Uid(this, uid, elapsedRealtimeMs, uptimeMs); 17464 mUidStats.put(uid, u); 17465 17466 u.mOnBatteryBackgroundTimeBase.readSummaryFromParcel(in); 17467 u.mOnBatteryScreenOffBackgroundTimeBase.readSummaryFromParcel(in); 17468 17469 u.mWifiRunning = false; 17470 if (in.readInt() != 0) { 17471 u.mWifiRunningTimer.readSummaryFromParcelLocked(in); 17472 } 17473 u.mFullWifiLockOut = false; 17474 if (in.readInt() != 0) { 17475 u.mFullWifiLockTimer.readSummaryFromParcelLocked(in); 17476 } 17477 u.mWifiScanStarted = false; 17478 if (in.readInt() != 0) { 17479 u.mWifiScanTimer.readSummaryFromParcelLocked(in); 17480 } 17481 u.mWifiBatchedScanBinStarted = Uid.NO_BATCHED_SCAN_STARTED; 17482 for (int i = 0; i < Uid.NUM_WIFI_BATCHED_SCAN_BINS; i++) { 17483 if (in.readInt() != 0) { 17484 u.makeWifiBatchedScanBin(i, null); 17485 u.mWifiBatchedScanTimer[i].readSummaryFromParcelLocked(in); 17486 } 17487 } 17488 u.mWifiMulticastWakelockCount = 0; 17489 if (in.readInt() != 0) { 17490 u.mWifiMulticastTimer.readSummaryFromParcelLocked(in); 17491 } 17492 if (in.readInt() != 0) { 17493 u.createAudioTurnedOnTimerLocked().readSummaryFromParcelLocked(in); 17494 } 17495 if (in.readInt() != 0) { 17496 u.createVideoTurnedOnTimerLocked().readSummaryFromParcelLocked(in); 17497 } 17498 if (in.readInt() != 0) { 17499 u.createFlashlightTurnedOnTimerLocked().readSummaryFromParcelLocked(in); 17500 } 17501 if (in.readInt() != 0) { 17502 u.createCameraTurnedOnTimerLocked().readSummaryFromParcelLocked(in); 17503 } 17504 if (in.readInt() != 0) { 17505 u.createForegroundActivityTimerLocked().readSummaryFromParcelLocked(in); 17506 } 17507 if (in.readInt() != 0) { 17508 u.createForegroundServiceTimerLocked().readSummaryFromParcelLocked(in); 17509 } 17510 if (in.readInt() != 0) { 17511 u.createAggregatedPartialWakelockTimerLocked().readSummaryFromParcelLocked(in); 17512 } 17513 if (in.readInt() != 0) { 17514 u.createBluetoothScanTimerLocked().readSummaryFromParcelLocked(in); 17515 } 17516 if (in.readInt() != 0) { 17517 u.createBluetoothUnoptimizedScanTimerLocked().readSummaryFromParcelLocked(in); 17518 } 17519 if (in.readInt() != 0) { 17520 u.createBluetoothScanResultCounterLocked().readSummaryFromParcelLocked(in); 17521 } 17522 if (in.readInt() != 0) { 17523 u.createBluetoothScanResultBgCounterLocked().readSummaryFromParcelLocked(in); 17524 } 17525 u.mProcessState = Uid.PROCESS_STATE_NONEXISTENT; 17526 for (int i = 0; i < NUM_PROCESS_STATE; i++) { 17527 if (in.readInt() != 0) { 17528 u.makeProcessState(i, null); 17529 u.mProcessStateTimer[i].readSummaryFromParcelLocked(in); 17530 } 17531 } 17532 if (in.readInt() != 0) { 17533 u.createVibratorOnTimerLocked().readSummaryFromParcelLocked(in); 17534 } 17535 17536 if (in.readInt() != 0) { 17537 if (u.mUserActivityCounters == null) { 17538 u.initUserActivityLocked(); 17539 } 17540 for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) { 17541 u.mUserActivityCounters[i].readSummaryFromParcelLocked(in); 17542 } 17543 } 17544 17545 if (in.readInt() != 0) { 17546 u.ensureNetworkActivityLocked(); 17547 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 17548 u.mNetworkByteActivityCounters[i].readSummaryFromParcelLocked(in); 17549 u.mNetworkPacketActivityCounters[i].readSummaryFromParcelLocked(in); 17550 } 17551 if (in.readBoolean()) { 17552 u.mMobileRadioActiveTime = TimeMultiStateCounter.readFromParcel(in, 17553 mOnBatteryTimeBase, BatteryConsumer.PROCESS_STATE_COUNT, 17554 elapsedRealtimeMs); 17555 } 17556 u.mMobileRadioActiveCount.readSummaryFromParcelLocked(in); 17557 } 17558 17559 u.mUserCpuTime.readSummaryFromParcelLocked(in); 17560 u.mSystemCpuTime.readSummaryFromParcelLocked(in); 17561 17562 if (in.readInt() != 0) { 17563 final int numClusters = in.readInt(); 17564 if (mPowerProfile != null && mPowerProfile.getNumCpuClusters() != numClusters) { 17565 throw new ParcelFormatException("Incompatible cpu cluster arrangement"); 17566 } 17567 detachIfNotNull(u.mCpuClusterSpeedTimesUs); 17568 u.mCpuClusterSpeedTimesUs = new LongSamplingCounter[numClusters][]; 17569 for (int cluster = 0; cluster < numClusters; cluster++) { 17570 if (in.readInt() != 0) { 17571 final int NSB = in.readInt(); 17572 if (mPowerProfile != null && 17573 mPowerProfile.getNumSpeedStepsInCpuCluster(cluster) != NSB) { 17574 throw new ParcelFormatException("File corrupt: too many speed bins " + 17575 NSB); 17576 } 17577 17578 u.mCpuClusterSpeedTimesUs[cluster] = new LongSamplingCounter[NSB]; 17579 for (int speed = 0; speed < NSB; speed++) { 17580 if (in.readInt() != 0) { 17581 u.mCpuClusterSpeedTimesUs[cluster][speed] = new LongSamplingCounter( 17582 mOnBatteryTimeBase); 17583 u.mCpuClusterSpeedTimesUs[cluster][speed].readSummaryFromParcelLocked(in); 17584 } 17585 } 17586 } else { 17587 u.mCpuClusterSpeedTimesUs[cluster] = null; 17588 } 17589 } 17590 } else { 17591 detachIfNotNull(u.mCpuClusterSpeedTimesUs); 17592 u.mCpuClusterSpeedTimesUs = null; 17593 } 17594 17595 detachIfNotNull(u.mCpuFreqTimeMs); 17596 u.mCpuFreqTimeMs = LongSamplingCounterArray.readSummaryFromParcelLocked( 17597 in, mOnBatteryTimeBase); 17598 detachIfNotNull(u.mScreenOffCpuFreqTimeMs); 17599 u.mScreenOffCpuFreqTimeMs = LongSamplingCounterArray.readSummaryFromParcelLocked( 17600 in, mOnBatteryScreenOffTimeBase); 17601 17602 int stateCount = in.readInt(); 17603 if (stateCount != 0) { 17604 u.mCpuActiveTimeMs = TimeMultiStateCounter.readFromParcel(in, 17605 mOnBatteryTimeBase, BatteryConsumer.PROCESS_STATE_COUNT, 17606 mClock.elapsedRealtime()); 17607 } 17608 u.mCpuClusterTimesMs.readSummaryFromParcelLocked(in); 17609 17610 detachIfNotNull(u.mProcStateTimeMs); 17611 u.mProcStateTimeMs = null; 17612 17613 stateCount = in.readInt(); 17614 if (stateCount != 0) { 17615 detachIfNotNull(u.mProcStateTimeMs); 17616 u.mProcStateTimeMs = TimeInFreqMultiStateCounter.readFromParcel(in, 17617 mOnBatteryTimeBase, PROC_STATE_TIME_COUNTER_STATE_COUNT, 17618 getCpuFreqCount(), mClock.elapsedRealtime()); 17619 } 17620 17621 detachIfNotNull(u.mProcStateScreenOffTimeMs); 17622 u.mProcStateScreenOffTimeMs = null; 17623 17624 stateCount = in.readInt(); 17625 if (stateCount != 0) { 17626 detachIfNotNull(u.mProcStateScreenOffTimeMs); 17627 u.mProcStateScreenOffTimeMs = TimeInFreqMultiStateCounter.readFromParcel(in, 17628 mOnBatteryScreenOffTimeBase, PROC_STATE_TIME_COUNTER_STATE_COUNT, 17629 getCpuFreqCount(), mClock.elapsedRealtime()); 17630 } 17631 17632 if (in.readInt() != 0) { 17633 detachIfNotNull(u.mMobileRadioApWakeupCount); 17634 u.mMobileRadioApWakeupCount = new LongSamplingCounter(mOnBatteryTimeBase); 17635 u.mMobileRadioApWakeupCount.readSummaryFromParcelLocked(in); 17636 } else { 17637 detachIfNotNull(u.mMobileRadioApWakeupCount); 17638 u.mMobileRadioApWakeupCount = null; 17639 } 17640 17641 if (in.readInt() != 0) { 17642 detachIfNotNull(u.mWifiRadioApWakeupCount); 17643 u.mWifiRadioApWakeupCount = new LongSamplingCounter(mOnBatteryTimeBase); 17644 u.mWifiRadioApWakeupCount.readSummaryFromParcelLocked(in); 17645 } else { 17646 detachIfNotNull(u.mWifiRadioApWakeupCount); 17647 u.mWifiRadioApWakeupCount = null; 17648 } 17649 17650 u.mUidMeasuredEnergyStats = MeasuredEnergyStats.createAndReadSummaryFromParcel( 17651 mMeasuredEnergyStatsConfig, in); 17652 17653 int NW = in.readInt(); 17654 if (NW > (MAX_WAKELOCKS_PER_UID+1)) { 17655 throw new ParcelFormatException("File corrupt: too many wake locks " + NW); 17656 } 17657 for (int iw = 0; iw < NW; iw++) { 17658 String wlName = in.readString(); 17659 u.readWakeSummaryFromParcelLocked(wlName, in); 17660 } 17661 17662 int NS = in.readInt(); 17663 if (NS > (MAX_WAKELOCKS_PER_UID+1)) { 17664 throw new ParcelFormatException("File corrupt: too many syncs " + NS); 17665 } 17666 for (int is = 0; is < NS; is++) { 17667 String name = in.readString(); 17668 u.readSyncSummaryFromParcelLocked(name, in); 17669 } 17670 17671 int NJ = in.readInt(); 17672 if (NJ > (MAX_WAKELOCKS_PER_UID+1)) { 17673 throw new ParcelFormatException("File corrupt: too many job timers " + NJ); 17674 } 17675 for (int ij = 0; ij < NJ; ij++) { 17676 String name = in.readString(); 17677 u.readJobSummaryFromParcelLocked(name, in); 17678 } 17679 17680 u.readJobCompletionsFromParcelLocked(in); 17681 17682 u.mJobsDeferredEventCount.readSummaryFromParcelLocked(in); 17683 u.mJobsDeferredCount.readSummaryFromParcelLocked(in); 17684 u.mJobsFreshnessTimeMs.readSummaryFromParcelLocked(in); 17685 detachIfNotNull(u.mJobsFreshnessBuckets); 17686 for (int i = 0; i < JOB_FRESHNESS_BUCKETS.length; i++) { 17687 if (in.readInt() != 0) { 17688 u.mJobsFreshnessBuckets[i] = new Counter(u.mBsi.mOnBatteryTimeBase); 17689 u.mJobsFreshnessBuckets[i].readSummaryFromParcelLocked(in); 17690 } 17691 } 17692 17693 int NP = in.readInt(); 17694 if (NP > 1000) { 17695 throw new ParcelFormatException("File corrupt: too many sensors " + NP); 17696 } 17697 for (int is = 0; is < NP; is++) { 17698 int seNumber = in.readInt(); 17699 if (in.readInt() != 0) { 17700 u.getSensorTimerLocked(seNumber, true).readSummaryFromParcelLocked(in); 17701 } 17702 } 17703 17704 NP = in.readInt(); 17705 if (NP > 1000) { 17706 throw new ParcelFormatException("File corrupt: too many processes " + NP); 17707 } 17708 for (int ip = 0; ip < NP; ip++) { 17709 String procName = in.readString(); 17710 Uid.Proc p = u.getProcessStatsLocked(procName); 17711 p.mUserTimeMs = in.readLong(); 17712 p.mSystemTimeMs = in.readLong(); 17713 p.mForegroundTimeMs = in.readLong(); 17714 p.mStarts = in.readInt(); 17715 p.mNumCrashes = in.readInt(); 17716 p.mNumAnrs = in.readInt(); 17717 p.readExcessivePowerFromParcelLocked(in); 17718 } 17719 17720 NP = in.readInt(); 17721 if (NP > 10000) { 17722 throw new ParcelFormatException("File corrupt: too many packages " + NP); 17723 } 17724 for (int ip = 0; ip < NP; ip++) { 17725 String pkgName = in.readString(); 17726 detachIfNotNull(u.mPackageStats.get(pkgName)); 17727 Uid.Pkg p = u.getPackageStatsLocked(pkgName); 17728 final int NWA = in.readInt(); 17729 if (NWA > 10000) { 17730 throw new ParcelFormatException("File corrupt: too many wakeup alarms " + NWA); 17731 } 17732 p.mWakeupAlarms.clear(); 17733 for (int iwa = 0; iwa < NWA; iwa++) { 17734 String tag = in.readString(); 17735 Counter c = new Counter(mOnBatteryScreenOffTimeBase); 17736 c.readSummaryFromParcelLocked(in); 17737 p.mWakeupAlarms.put(tag, c); 17738 } 17739 NS = in.readInt(); 17740 if (NS > 10000) { 17741 throw new ParcelFormatException("File corrupt: too many services " + NS); 17742 } 17743 for (int is = 0; is < NS; is++) { 17744 String servName = in.readString(); 17745 Uid.Pkg.Serv s = u.getServiceStatsLocked(pkgName, servName); 17746 s.mStartTimeMs = in.readLong(); 17747 s.mStarts = in.readInt(); 17748 s.mLaunches = in.readInt(); 17749 } 17750 } 17751 } 17752 17753 mBinderThreadCpuTimesUs = 17754 LongSamplingCounterArray.readSummaryFromParcelLocked(in, mOnBatteryTimeBase); 17755 } 17756 17757 /** 17758 * Writes a summary of the statistics to a Parcel, in a format suitable to be written to 17759 * disk. This format does not allow a lossless round-trip. 17760 * 17761 * @param out the Parcel to be written to. 17762 */ 17763 @GuardedBy("this") 17764 public void writeSummaryToParcel(Parcel out, boolean inclHistory) { 17765 pullPendingStateUpdatesLocked(); 17766 17767 // Pull the clock time. This may update the time and make a new history entry 17768 // if we had originally pulled a time before the RTC was set. 17769 getStartClockTime(); 17770 17771 final long nowUptime = mClock.uptimeMillis() * 1000; 17772 final long nowRealtime = mClock.elapsedRealtime() * 1000; 17773 17774 out.writeInt(VERSION); 17775 17776 out.writeBoolean(inclHistory); 17777 if (inclHistory) { 17778 writeHistoryBuffer(out, true); 17779 mBatteryStatsHistory.writeToParcel(out); 17780 } 17781 17782 out.writeInt(mHistoryTagPool.size()); 17783 for (HashMap.Entry<HistoryTag, Integer> ent : mHistoryTagPool.entrySet()) { 17784 HistoryTag tag = ent.getKey(); 17785 out.writeInt(ent.getValue()); 17786 out.writeString(tag.string); 17787 out.writeInt(tag.uid); 17788 } 17789 17790 out.writeInt(mStartCount); 17791 out.writeLong(computeUptime(nowUptime, STATS_SINCE_CHARGED)); 17792 out.writeLong(computeRealtime(nowRealtime, STATS_SINCE_CHARGED)); 17793 out.writeLong(mStartClockTimeMs); 17794 out.writeString(mStartPlatformVersion); 17795 out.writeString(mEndPlatformVersion); 17796 mOnBatteryTimeBase.writeSummaryToParcel(out, nowUptime, nowRealtime); 17797 mOnBatteryScreenOffTimeBase.writeSummaryToParcel(out, nowUptime, nowRealtime); 17798 out.writeInt(mDischargeUnplugLevel); 17799 out.writeInt(mDischargePlugLevel); 17800 out.writeInt(mDischargeCurrentLevel); 17801 out.writeInt(mCurrentBatteryLevel); 17802 out.writeInt(mEstimatedBatteryCapacityMah); 17803 out.writeInt(mLastLearnedBatteryCapacityUah); 17804 out.writeInt(mMinLearnedBatteryCapacityUah); 17805 out.writeInt(mMaxLearnedBatteryCapacityUah); 17806 out.writeInt(getLowDischargeAmountSinceCharge()); 17807 out.writeInt(getHighDischargeAmountSinceCharge()); 17808 out.writeInt(getDischargeAmountScreenOnSinceCharge()); 17809 out.writeInt(getDischargeAmountScreenOffSinceCharge()); 17810 out.writeInt(getDischargeAmountScreenDozeSinceCharge()); 17811 mDischargeStepTracker.writeToParcel(out); 17812 mChargeStepTracker.writeToParcel(out); 17813 mDailyDischargeStepTracker.writeToParcel(out); 17814 mDailyChargeStepTracker.writeToParcel(out); 17815 mDischargeCounter.writeSummaryFromParcelLocked(out); 17816 mDischargeScreenOffCounter.writeSummaryFromParcelLocked(out); 17817 mDischargeScreenDozeCounter.writeSummaryFromParcelLocked(out); 17818 mDischargeLightDozeCounter.writeSummaryFromParcelLocked(out); 17819 mDischargeDeepDozeCounter.writeSummaryFromParcelLocked(out); 17820 if (mDailyPackageChanges != null) { 17821 final int NPKG = mDailyPackageChanges.size(); 17822 out.writeInt(NPKG); 17823 for (int i=0; i<NPKG; i++) { 17824 PackageChange pc = mDailyPackageChanges.get(i); 17825 out.writeString(pc.mPackageName); 17826 out.writeInt(pc.mUpdate ? 1 : 0); 17827 out.writeLong(pc.mVersionCode); 17828 } 17829 } else { 17830 out.writeInt(0); 17831 } 17832 out.writeLong(mDailyStartTimeMs); 17833 out.writeLong(mNextMinDailyDeadlineMs); 17834 out.writeLong(mNextMaxDailyDeadlineMs); 17835 out.writeLong(mBatteryTimeToFullSeconds); 17836 17837 MeasuredEnergyStats.Config.writeToParcel(mMeasuredEnergyStatsConfig, out); 17838 MeasuredEnergyStats.writeSummaryToParcel(mGlobalMeasuredEnergyStats, out); 17839 17840 mScreenOnTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17841 mScreenDozeTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17842 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 17843 mScreenBrightnessTimer[i].writeSummaryFromParcelLocked(out, nowRealtime); 17844 } 17845 mInteractiveTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17846 mPowerSaveModeEnabledTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17847 out.writeLong(mLongestLightIdleTimeMs); 17848 out.writeLong(mLongestFullIdleTimeMs); 17849 mDeviceIdleModeLightTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17850 mDeviceIdleModeFullTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17851 mDeviceLightIdlingTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17852 mDeviceIdlingTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17853 mPhoneOnTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17854 for (int i = 0; i < CellSignalStrength.getNumSignalStrengthLevels(); i++) { 17855 mPhoneSignalStrengthsTimer[i].writeSummaryFromParcelLocked(out, nowRealtime); 17856 } 17857 mPhoneSignalScanningTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17858 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 17859 mPhoneDataConnectionsTimer[i].writeSummaryFromParcelLocked(out, nowRealtime); 17860 } 17861 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 17862 mNetworkByteActivityCounters[i].writeSummaryFromParcelLocked(out); 17863 mNetworkPacketActivityCounters[i].writeSummaryFromParcelLocked(out); 17864 } 17865 final int numRat = mPerRatBatteryStats.length; 17866 out.writeInt(numRat); 17867 for (int i = 0; i < numRat; i++) { 17868 final RadioAccessTechnologyBatteryStats ratStat = mPerRatBatteryStats[i]; 17869 if (ratStat == null) { 17870 out.writeInt(0); 17871 continue; 17872 } 17873 out.writeInt(1); 17874 ratStat.writeSummaryToParcel(out, nowRealtime); 17875 } 17876 mMobileRadioActiveTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17877 mMobileRadioActivePerAppTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17878 mMobileRadioActiveAdjustedTime.writeSummaryFromParcelLocked(out); 17879 mMobileRadioActiveUnknownTime.writeSummaryFromParcelLocked(out); 17880 mMobileRadioActiveUnknownCount.writeSummaryFromParcelLocked(out); 17881 mWifiMulticastWakelockTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17882 mWifiOnTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17883 mGlobalWifiRunningTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17884 for (int i=0; i<NUM_WIFI_STATES; i++) { 17885 mWifiStateTimer[i].writeSummaryFromParcelLocked(out, nowRealtime); 17886 } 17887 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) { 17888 mWifiSupplStateTimer[i].writeSummaryFromParcelLocked(out, nowRealtime); 17889 } 17890 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { 17891 mWifiSignalStrengthsTimer[i].writeSummaryFromParcelLocked(out, nowRealtime); 17892 } 17893 mWifiActiveTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17894 mWifiActivity.writeSummaryToParcel(out); 17895 for (int i=0; i< mGpsSignalQualityTimer.length; i++) { 17896 mGpsSignalQualityTimer[i].writeSummaryFromParcelLocked(out, nowRealtime); 17897 } 17898 mBluetoothActivity.writeSummaryToParcel(out); 17899 mModemActivity.writeSummaryToParcel(out); 17900 out.writeInt(mHasWifiReporting ? 1 : 0); 17901 out.writeInt(mHasBluetoothReporting ? 1 : 0); 17902 out.writeInt(mHasModemReporting ? 1 : 0); 17903 17904 out.writeInt(mNumConnectivityChange); 17905 mFlashlightOnTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17906 mCameraOnTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17907 mBluetoothScanTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17908 17909 out.writeInt(mRpmStats.size()); 17910 for (Map.Entry<String, SamplingTimer> ent : mRpmStats.entrySet()) { 17911 Timer rpmt = ent.getValue(); 17912 if (rpmt != null) { 17913 out.writeInt(1); 17914 out.writeString(ent.getKey()); 17915 rpmt.writeSummaryFromParcelLocked(out, nowRealtime); 17916 } else { 17917 out.writeInt(0); 17918 } 17919 } 17920 out.writeInt(mScreenOffRpmStats.size()); 17921 for (Map.Entry<String, SamplingTimer> ent : mScreenOffRpmStats.entrySet()) { 17922 Timer rpmt = ent.getValue(); 17923 if (rpmt != null) { 17924 out.writeInt(1); 17925 out.writeString(ent.getKey()); 17926 rpmt.writeSummaryFromParcelLocked(out, nowRealtime); 17927 } else { 17928 out.writeInt(0); 17929 } 17930 } 17931 17932 out.writeInt(mKernelWakelockStats.size()); 17933 for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) { 17934 Timer kwlt = ent.getValue(); 17935 if (kwlt != null) { 17936 out.writeInt(1); 17937 out.writeString(ent.getKey()); 17938 kwlt.writeSummaryFromParcelLocked(out, nowRealtime); 17939 } else { 17940 out.writeInt(0); 17941 } 17942 } 17943 17944 out.writeInt(mWakeupReasonStats.size()); 17945 for (Map.Entry<String, SamplingTimer> ent : mWakeupReasonStats.entrySet()) { 17946 SamplingTimer timer = ent.getValue(); 17947 if (timer != null) { 17948 out.writeInt(1); 17949 out.writeString(ent.getKey()); 17950 timer.writeSummaryFromParcelLocked(out, nowRealtime); 17951 } else { 17952 out.writeInt(0); 17953 } 17954 } 17955 17956 out.writeInt(mKernelMemoryStats.size()); 17957 for (int i = 0; i < mKernelMemoryStats.size(); i++) { 17958 Timer kmt = mKernelMemoryStats.valueAt(i); 17959 if (kmt != null) { 17960 out.writeInt(1); 17961 out.writeLong(mKernelMemoryStats.keyAt(i)); 17962 kmt.writeSummaryFromParcelLocked(out, nowRealtime); 17963 } else { 17964 out.writeInt(0); 17965 } 17966 } 17967 17968 final int NU = mUidStats.size(); 17969 out.writeInt(NU); 17970 for (int iu = 0; iu < NU; iu++) { 17971 out.writeInt(mUidStats.keyAt(iu)); 17972 Uid u = mUidStats.valueAt(iu); 17973 17974 u.mOnBatteryBackgroundTimeBase.writeSummaryToParcel(out, nowUptime, nowRealtime); 17975 u.mOnBatteryScreenOffBackgroundTimeBase.writeSummaryToParcel(out, nowUptime, 17976 nowRealtime); 17977 17978 if (u.mWifiRunningTimer != null) { 17979 out.writeInt(1); 17980 u.mWifiRunningTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17981 } else { 17982 out.writeInt(0); 17983 } 17984 if (u.mFullWifiLockTimer != null) { 17985 out.writeInt(1); 17986 u.mFullWifiLockTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17987 } else { 17988 out.writeInt(0); 17989 } 17990 if (u.mWifiScanTimer != null) { 17991 out.writeInt(1); 17992 u.mWifiScanTimer.writeSummaryFromParcelLocked(out, nowRealtime); 17993 } else { 17994 out.writeInt(0); 17995 } 17996 for (int i = 0; i < Uid.NUM_WIFI_BATCHED_SCAN_BINS; i++) { 17997 if (u.mWifiBatchedScanTimer[i] != null) { 17998 out.writeInt(1); 17999 u.mWifiBatchedScanTimer[i].writeSummaryFromParcelLocked(out, nowRealtime); 18000 } else { 18001 out.writeInt(0); 18002 } 18003 } 18004 if (u.mWifiMulticastTimer != null) { 18005 out.writeInt(1); 18006 u.mWifiMulticastTimer.writeSummaryFromParcelLocked(out, nowRealtime); 18007 } else { 18008 out.writeInt(0); 18009 } 18010 if (u.mAudioTurnedOnTimer != null) { 18011 out.writeInt(1); 18012 u.mAudioTurnedOnTimer.writeSummaryFromParcelLocked(out, nowRealtime); 18013 } else { 18014 out.writeInt(0); 18015 } 18016 if (u.mVideoTurnedOnTimer != null) { 18017 out.writeInt(1); 18018 u.mVideoTurnedOnTimer.writeSummaryFromParcelLocked(out, nowRealtime); 18019 } else { 18020 out.writeInt(0); 18021 } 18022 if (u.mFlashlightTurnedOnTimer != null) { 18023 out.writeInt(1); 18024 u.mFlashlightTurnedOnTimer.writeSummaryFromParcelLocked(out, nowRealtime); 18025 } else { 18026 out.writeInt(0); 18027 } 18028 if (u.mCameraTurnedOnTimer != null) { 18029 out.writeInt(1); 18030 u.mCameraTurnedOnTimer.writeSummaryFromParcelLocked(out, nowRealtime); 18031 } else { 18032 out.writeInt(0); 18033 } 18034 if (u.mForegroundActivityTimer != null) { 18035 out.writeInt(1); 18036 u.mForegroundActivityTimer.writeSummaryFromParcelLocked(out, nowRealtime); 18037 } else { 18038 out.writeInt(0); 18039 } 18040 if (u.mForegroundServiceTimer != null) { 18041 out.writeInt(1); 18042 u.mForegroundServiceTimer.writeSummaryFromParcelLocked(out, nowRealtime); 18043 } else { 18044 out.writeInt(0); 18045 } 18046 if (u.mAggregatedPartialWakelockTimer != null) { 18047 out.writeInt(1); 18048 u.mAggregatedPartialWakelockTimer.writeSummaryFromParcelLocked(out, nowRealtime); 18049 } else { 18050 out.writeInt(0); 18051 } 18052 if (u.mBluetoothScanTimer != null) { 18053 out.writeInt(1); 18054 u.mBluetoothScanTimer.writeSummaryFromParcelLocked(out, nowRealtime); 18055 } else { 18056 out.writeInt(0); 18057 } 18058 if (u.mBluetoothUnoptimizedScanTimer != null) { 18059 out.writeInt(1); 18060 u.mBluetoothUnoptimizedScanTimer.writeSummaryFromParcelLocked(out, nowRealtime); 18061 } else { 18062 out.writeInt(0); 18063 } 18064 if (u.mBluetoothScanResultCounter != null) { 18065 out.writeInt(1); 18066 u.mBluetoothScanResultCounter.writeSummaryFromParcelLocked(out); 18067 } else { 18068 out.writeInt(0); 18069 } 18070 if (u.mBluetoothScanResultBgCounter != null) { 18071 out.writeInt(1); 18072 u.mBluetoothScanResultBgCounter.writeSummaryFromParcelLocked(out); 18073 } else { 18074 out.writeInt(0); 18075 } 18076 for (int i = 0; i < NUM_PROCESS_STATE; i++) { 18077 if (u.mProcessStateTimer[i] != null) { 18078 out.writeInt(1); 18079 u.mProcessStateTimer[i].writeSummaryFromParcelLocked(out, nowRealtime); 18080 } else { 18081 out.writeInt(0); 18082 } 18083 } 18084 if (u.mVibratorOnTimer != null) { 18085 out.writeInt(1); 18086 u.mVibratorOnTimer.writeSummaryFromParcelLocked(out, nowRealtime); 18087 } else { 18088 out.writeInt(0); 18089 } 18090 18091 if (u.mUserActivityCounters == null) { 18092 out.writeInt(0); 18093 } else { 18094 out.writeInt(1); 18095 for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) { 18096 u.mUserActivityCounters[i].writeSummaryFromParcelLocked(out); 18097 } 18098 } 18099 18100 if (u.mNetworkByteActivityCounters == null) { 18101 out.writeInt(0); 18102 } else { 18103 out.writeInt(1); 18104 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 18105 u.mNetworkByteActivityCounters[i].writeSummaryFromParcelLocked(out); 18106 u.mNetworkPacketActivityCounters[i].writeSummaryFromParcelLocked(out); 18107 } 18108 if (u.mMobileRadioActiveTime != null) { 18109 out.writeBoolean(true); 18110 u.mMobileRadioActiveTime.writeToParcel(out); 18111 } else { 18112 out.writeBoolean(false); 18113 } 18114 u.mMobileRadioActiveCount.writeSummaryFromParcelLocked(out); 18115 } 18116 18117 u.mUserCpuTime.writeSummaryFromParcelLocked(out); 18118 u.mSystemCpuTime.writeSummaryFromParcelLocked(out); 18119 18120 if (u.mCpuClusterSpeedTimesUs != null) { 18121 out.writeInt(1); 18122 out.writeInt(u.mCpuClusterSpeedTimesUs.length); 18123 for (LongSamplingCounter[] cpuSpeeds : u.mCpuClusterSpeedTimesUs) { 18124 if (cpuSpeeds != null) { 18125 out.writeInt(1); 18126 out.writeInt(cpuSpeeds.length); 18127 for (LongSamplingCounter c : cpuSpeeds) { 18128 if (c != null) { 18129 out.writeInt(1); 18130 c.writeSummaryFromParcelLocked(out); 18131 } else { 18132 out.writeInt(0); 18133 } 18134 } 18135 } else { 18136 out.writeInt(0); 18137 } 18138 } 18139 } else { 18140 out.writeInt(0); 18141 } 18142 18143 LongSamplingCounterArray.writeSummaryToParcelLocked(out, u.mCpuFreqTimeMs); 18144 LongSamplingCounterArray.writeSummaryToParcelLocked(out, u.mScreenOffCpuFreqTimeMs); 18145 18146 if (u.mCpuActiveTimeMs != null) { 18147 out.writeInt(u.mCpuActiveTimeMs.getStateCount()); 18148 u.mCpuActiveTimeMs.writeToParcel(out); 18149 } else { 18150 out.writeInt(0); 18151 } 18152 18153 u.mCpuClusterTimesMs.writeSummaryToParcelLocked(out); 18154 18155 if (u.mProcStateTimeMs != null) { 18156 out.writeInt(u.mProcStateTimeMs.getStateCount()); 18157 u.mProcStateTimeMs.writeToParcel(out); 18158 } else { 18159 out.writeInt(0); 18160 } 18161 18162 if (u.mProcStateScreenOffTimeMs != null) { 18163 out.writeInt(u.mProcStateScreenOffTimeMs.getStateCount()); 18164 u.mProcStateScreenOffTimeMs.writeToParcel(out); 18165 } else { 18166 out.writeInt(0); 18167 } 18168 18169 if (u.mMobileRadioApWakeupCount != null) { 18170 out.writeInt(1); 18171 u.mMobileRadioApWakeupCount.writeSummaryFromParcelLocked(out); 18172 } else { 18173 out.writeInt(0); 18174 } 18175 18176 if (u.mWifiRadioApWakeupCount != null) { 18177 out.writeInt(1); 18178 u.mWifiRadioApWakeupCount.writeSummaryFromParcelLocked(out); 18179 } else { 18180 out.writeInt(0); 18181 } 18182 18183 MeasuredEnergyStats.writeSummaryToParcel(u.mUidMeasuredEnergyStats, out); 18184 18185 final ArrayMap<String, Uid.Wakelock> wakeStats = u.mWakelockStats.getMap(); 18186 int NW = wakeStats.size(); 18187 out.writeInt(NW); 18188 for (int iw=0; iw<NW; iw++) { 18189 out.writeString(wakeStats.keyAt(iw)); 18190 Uid.Wakelock wl = wakeStats.valueAt(iw); 18191 if (wl.mTimerFull != null) { 18192 out.writeInt(1); 18193 wl.mTimerFull.writeSummaryFromParcelLocked(out, nowRealtime); 18194 } else { 18195 out.writeInt(0); 18196 } 18197 if (wl.mTimerPartial != null) { 18198 out.writeInt(1); 18199 wl.mTimerPartial.writeSummaryFromParcelLocked(out, nowRealtime); 18200 } else { 18201 out.writeInt(0); 18202 } 18203 if (wl.mTimerWindow != null) { 18204 out.writeInt(1); 18205 wl.mTimerWindow.writeSummaryFromParcelLocked(out, nowRealtime); 18206 } else { 18207 out.writeInt(0); 18208 } 18209 if (wl.mTimerDraw != null) { 18210 out.writeInt(1); 18211 wl.mTimerDraw.writeSummaryFromParcelLocked(out, nowRealtime); 18212 } else { 18213 out.writeInt(0); 18214 } 18215 } 18216 18217 final ArrayMap<String, DualTimer> syncStats = u.mSyncStats.getMap(); 18218 int NS = syncStats.size(); 18219 out.writeInt(NS); 18220 for (int is=0; is<NS; is++) { 18221 out.writeString(syncStats.keyAt(is)); 18222 syncStats.valueAt(is).writeSummaryFromParcelLocked(out, nowRealtime); 18223 } 18224 18225 final ArrayMap<String, DualTimer> jobStats = u.mJobStats.getMap(); 18226 int NJ = jobStats.size(); 18227 out.writeInt(NJ); 18228 for (int ij=0; ij<NJ; ij++) { 18229 out.writeString(jobStats.keyAt(ij)); 18230 jobStats.valueAt(ij).writeSummaryFromParcelLocked(out, nowRealtime); 18231 } 18232 18233 u.writeJobCompletionsToParcelLocked(out); 18234 18235 u.mJobsDeferredEventCount.writeSummaryFromParcelLocked(out); 18236 u.mJobsDeferredCount.writeSummaryFromParcelLocked(out); 18237 u.mJobsFreshnessTimeMs.writeSummaryFromParcelLocked(out); 18238 for (int i = 0; i < JOB_FRESHNESS_BUCKETS.length; i++) { 18239 if (u.mJobsFreshnessBuckets[i] != null) { 18240 out.writeInt(1); 18241 u.mJobsFreshnessBuckets[i].writeSummaryFromParcelLocked(out); 18242 } else { 18243 out.writeInt(0); 18244 } 18245 } 18246 18247 int NSE = u.mSensorStats.size(); 18248 out.writeInt(NSE); 18249 for (int ise=0; ise<NSE; ise++) { 18250 out.writeInt(u.mSensorStats.keyAt(ise)); 18251 Uid.Sensor se = u.mSensorStats.valueAt(ise); 18252 if (se.mTimer != null) { 18253 out.writeInt(1); 18254 se.mTimer.writeSummaryFromParcelLocked(out, nowRealtime); 18255 } else { 18256 out.writeInt(0); 18257 } 18258 } 18259 18260 int NP = u.mProcessStats.size(); 18261 out.writeInt(NP); 18262 for (int ip=0; ip<NP; ip++) { 18263 out.writeString(u.mProcessStats.keyAt(ip)); 18264 Uid.Proc ps = u.mProcessStats.valueAt(ip); 18265 out.writeLong(ps.mUserTimeMs); 18266 out.writeLong(ps.mSystemTimeMs); 18267 out.writeLong(ps.mForegroundTimeMs); 18268 out.writeInt(ps.mStarts); 18269 out.writeInt(ps.mNumCrashes); 18270 out.writeInt(ps.mNumAnrs); 18271 ps.writeExcessivePowerToParcelLocked(out); 18272 } 18273 18274 NP = u.mPackageStats.size(); 18275 out.writeInt(NP); 18276 if (NP > 0) { 18277 for (Map.Entry<String, BatteryStatsImpl.Uid.Pkg> ent 18278 : u.mPackageStats.entrySet()) { 18279 out.writeString(ent.getKey()); 18280 Uid.Pkg ps = ent.getValue(); 18281 final int NWA = ps.mWakeupAlarms.size(); 18282 out.writeInt(NWA); 18283 for (int iwa=0; iwa<NWA; iwa++) { 18284 out.writeString(ps.mWakeupAlarms.keyAt(iwa)); 18285 ps.mWakeupAlarms.valueAt(iwa).writeSummaryFromParcelLocked(out); 18286 } 18287 NS = ps.mServiceStats.size(); 18288 out.writeInt(NS); 18289 for (int is=0; is<NS; is++) { 18290 out.writeString(ps.mServiceStats.keyAt(is)); 18291 BatteryStatsImpl.Uid.Pkg.Serv ss = ps.mServiceStats.valueAt(is); 18292 long time = ss.getStartTimeToNowLocked( 18293 mOnBatteryTimeBase.getUptime(nowUptime) / 1000); 18294 out.writeLong(time); 18295 out.writeInt(ss.mStarts); 18296 out.writeInt(ss.mLaunches); 18297 } 18298 } 18299 } 18300 } 18301 18302 LongSamplingCounterArray.writeSummaryToParcelLocked(out, mBinderThreadCpuTimesUs); 18303 } 18304 18305 @GuardedBy("this") 18306 public void readFromParcel(Parcel in) { 18307 readFromParcelLocked(in); 18308 } 18309 18310 @GuardedBy("this") 18311 @SuppressWarnings("GuardedBy") // errorprone false positive on u.readFromParcelLocked 18312 void readFromParcelLocked(Parcel in) { 18313 int magic = in.readInt(); 18314 if (magic != MAGIC) { 18315 throw new ParcelFormatException("Bad magic number: #" + Integer.toHexString(magic)); 18316 } 18317 18318 readHistoryBuffer(in); 18319 mBatteryStatsHistory.readFromParcel(in); 18320 18321 mStartCount = in.readInt(); 18322 mStartClockTimeMs = in.readLong(); 18323 mStartPlatformVersion = in.readString(); 18324 mEndPlatformVersion = in.readString(); 18325 mUptimeUs = in.readLong(); 18326 mUptimeStartUs = in.readLong(); 18327 mRealtimeUs = in.readLong(); 18328 mRealtimeStartUs = in.readLong(); 18329 mOnBattery = in.readInt() != 0; 18330 mEstimatedBatteryCapacityMah = in.readInt(); 18331 mLastLearnedBatteryCapacityUah = in.readInt(); 18332 mMinLearnedBatteryCapacityUah = in.readInt(); 18333 mMaxLearnedBatteryCapacityUah = in.readInt(); 18334 mOnBatteryInternal = false; // we are no longer really running. 18335 mOnBatteryTimeBase.readFromParcel(in); 18336 mOnBatteryScreenOffTimeBase.readFromParcel(in); 18337 18338 mScreenState = Display.STATE_UNKNOWN; 18339 mScreenOnTimer = new StopwatchTimer(mClock, null, -1, null, mOnBatteryTimeBase, in); 18340 mScreenDozeTimer = new StopwatchTimer(mClock, null, -1, null, mOnBatteryTimeBase, in); 18341 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 18342 mScreenBrightnessTimer[i] = new StopwatchTimer(mClock, null, -100 - i, null, 18343 mOnBatteryTimeBase, in); 18344 } 18345 mInteractive = false; 18346 mInteractiveTimer = new StopwatchTimer(mClock, null, -10, null, mOnBatteryTimeBase, in); 18347 mPhoneOn = false; 18348 mPowerSaveModeEnabledTimer = new StopwatchTimer(mClock, null, -2, null, 18349 mOnBatteryTimeBase, in); 18350 mLongestLightIdleTimeMs = in.readLong(); 18351 mLongestFullIdleTimeMs = in.readLong(); 18352 mDeviceIdleModeLightTimer = new StopwatchTimer(mClock, null, -14, null, 18353 mOnBatteryTimeBase, in); 18354 mDeviceIdleModeFullTimer = new StopwatchTimer(mClock, null, -11, null, 18355 mOnBatteryTimeBase, in); 18356 mDeviceLightIdlingTimer = new StopwatchTimer(mClock, null, -15, null, 18357 mOnBatteryTimeBase, in); 18358 mDeviceIdlingTimer = new StopwatchTimer(mClock, null, -12, null, mOnBatteryTimeBase, in); 18359 mPhoneOnTimer = new StopwatchTimer(mClock, null, -3, null, mOnBatteryTimeBase, in); 18360 for (int i = 0; i < CellSignalStrength.getNumSignalStrengthLevels(); i++) { 18361 mPhoneSignalStrengthsTimer[i] = new StopwatchTimer(mClock, null, -200 - i, 18362 null, mOnBatteryTimeBase, in); 18363 } 18364 mPhoneSignalScanningTimer = new StopwatchTimer(mClock, null, -200 + 1, null, 18365 mOnBatteryTimeBase, in); 18366 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 18367 mPhoneDataConnectionsTimer[i] = new StopwatchTimer(mClock, null, -300 - i, 18368 null, mOnBatteryTimeBase, in); 18369 } 18370 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 18371 mNetworkByteActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase, in); 18372 mNetworkPacketActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase, in); 18373 } 18374 mMobileRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW; 18375 mMobileRadioActiveTimer = new StopwatchTimer(mClock, null, -400, null, 18376 mOnBatteryTimeBase, in); 18377 mMobileRadioActivePerAppTimer = new StopwatchTimer(mClock, null, -401, null, 18378 mOnBatteryTimeBase, in); 18379 mMobileRadioActiveAdjustedTime = new LongSamplingCounter(mOnBatteryTimeBase, in); 18380 mMobileRadioActiveUnknownTime = new LongSamplingCounter(mOnBatteryTimeBase, in); 18381 mMobileRadioActiveUnknownCount = new LongSamplingCounter(mOnBatteryTimeBase, in); 18382 mWifiMulticastWakelockTimer = new StopwatchTimer(mClock, null, -4, null, 18383 mOnBatteryTimeBase, in); 18384 mWifiRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW; 18385 mWifiOn = false; 18386 mWifiOnTimer = new StopwatchTimer(mClock, null, -4, null, mOnBatteryTimeBase, in); 18387 mGlobalWifiRunning = false; 18388 mGlobalWifiRunningTimer = new StopwatchTimer(mClock, null, -5, null, 18389 mOnBatteryTimeBase, in); 18390 for (int i=0; i<NUM_WIFI_STATES; i++) { 18391 mWifiStateTimer[i] = new StopwatchTimer(mClock, null, -600 - i, 18392 null, mOnBatteryTimeBase, in); 18393 } 18394 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) { 18395 mWifiSupplStateTimer[i] = new StopwatchTimer(mClock, null, -700 - i, 18396 null, mOnBatteryTimeBase, in); 18397 } 18398 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { 18399 mWifiSignalStrengthsTimer[i] = new StopwatchTimer(mClock, null, -800 - i, 18400 null, mOnBatteryTimeBase, in); 18401 } 18402 mWifiActiveTimer = new StopwatchTimer(mClock, null, -900, null, 18403 mOnBatteryTimeBase, in); 18404 mWifiActivity = new ControllerActivityCounterImpl(mClock, mOnBatteryTimeBase, 18405 NUM_WIFI_TX_LEVELS, in); 18406 for (int i=0; i<mGpsSignalQualityTimer.length; i++) { 18407 mGpsSignalQualityTimer[i] = new StopwatchTimer(mClock, null, -1000 - i, 18408 null, mOnBatteryTimeBase, in); 18409 } 18410 mBluetoothActivity = new ControllerActivityCounterImpl(mClock, mOnBatteryTimeBase, 18411 NUM_BT_TX_LEVELS, in); 18412 mModemActivity = new ControllerActivityCounterImpl(mClock, mOnBatteryTimeBase, 18413 ModemActivityInfo.getNumTxPowerLevels(), in); 18414 mHasWifiReporting = in.readInt() != 0; 18415 mHasBluetoothReporting = in.readInt() != 0; 18416 mHasModemReporting = in.readInt() != 0; 18417 18418 mNumConnectivityChange = in.readInt(); 18419 mAudioOnNesting = 0; 18420 // TODO: It's likely a mistake that mAudioOnTimer/mVideoOnTimer don't write/read to parcel! 18421 mAudioOnTimer = new StopwatchTimer(mClock, null, -7, null, mOnBatteryTimeBase); 18422 mVideoOnNesting = 0; 18423 mVideoOnTimer = new StopwatchTimer(mClock, null, -8, null, mOnBatteryTimeBase); 18424 mFlashlightOnNesting = 0; 18425 mFlashlightOnTimer = new StopwatchTimer(mClock, null, -9, null, mOnBatteryTimeBase, in); 18426 mCameraOnNesting = 0; 18427 mCameraOnTimer = new StopwatchTimer(mClock, null, -13, null, mOnBatteryTimeBase, in); 18428 mBluetoothScanNesting = 0; 18429 mBluetoothScanTimer = new StopwatchTimer(mClock, null, -14, null, mOnBatteryTimeBase, in); 18430 mDischargeUnplugLevel = in.readInt(); 18431 mDischargePlugLevel = in.readInt(); 18432 mDischargeCurrentLevel = in.readInt(); 18433 mCurrentBatteryLevel = in.readInt(); 18434 mLowDischargeAmountSinceCharge = in.readInt(); 18435 mHighDischargeAmountSinceCharge = in.readInt(); 18436 mDischargeAmountScreenOn = in.readInt(); 18437 mDischargeAmountScreenOnSinceCharge = in.readInt(); 18438 mDischargeAmountScreenOff = in.readInt(); 18439 mDischargeAmountScreenOffSinceCharge = in.readInt(); 18440 mDischargeAmountScreenDoze = in.readInt(); 18441 mDischargeAmountScreenDozeSinceCharge = in.readInt(); 18442 mDischargeStepTracker.readFromParcel(in); 18443 mChargeStepTracker.readFromParcel(in); 18444 mDischargeCounter = new LongSamplingCounter(mOnBatteryTimeBase, in); 18445 mDischargeScreenOffCounter = new LongSamplingCounter(mOnBatteryScreenOffTimeBase, in); 18446 mDischargeScreenDozeCounter = new LongSamplingCounter(mOnBatteryTimeBase, in); 18447 mDischargeLightDozeCounter = new LongSamplingCounter(mOnBatteryTimeBase, in); 18448 mDischargeDeepDozeCounter = new LongSamplingCounter(mOnBatteryTimeBase, in); 18449 mLastWriteTimeMs = in.readLong(); 18450 mBatteryTimeToFullSeconds = in.readLong(); 18451 18452 18453 final MeasuredEnergyStats.Config config = MeasuredEnergyStats.Config.createFromParcel(in); 18454 final MeasuredEnergyStats measuredEnergyStats = 18455 MeasuredEnergyStats.createFromParcel(mMeasuredEnergyStatsConfig, in); 18456 if (config != null && Arrays.equals(config.getStateNames(), 18457 getBatteryConsumerProcessStateNames())) { 18458 mMeasuredEnergyStatsConfig = config; 18459 mGlobalMeasuredEnergyStats = measuredEnergyStats; 18460 } 18461 18462 mRpmStats.clear(); 18463 int NRPMS = in.readInt(); 18464 for (int irpm = 0; irpm < NRPMS; irpm++) { 18465 if (in.readInt() != 0) { 18466 String rpmName = in.readString(); 18467 SamplingTimer rpmt = new SamplingTimer(mClock, mOnBatteryTimeBase, in); 18468 mRpmStats.put(rpmName, rpmt); 18469 } 18470 } 18471 mScreenOffRpmStats.clear(); 18472 int NSORPMS = in.readInt(); 18473 for (int irpm = 0; irpm < NSORPMS; irpm++) { 18474 if (in.readInt() != 0) { 18475 String rpmName = in.readString(); 18476 SamplingTimer rpmt = new SamplingTimer(mClock, mOnBatteryScreenOffTimeBase, in); 18477 mScreenOffRpmStats.put(rpmName, rpmt); 18478 } 18479 } 18480 18481 mKernelWakelockStats.clear(); 18482 int NKW = in.readInt(); 18483 for (int ikw = 0; ikw < NKW; ikw++) { 18484 if (in.readInt() != 0) { 18485 String wakelockName = in.readString(); 18486 SamplingTimer kwlt = new SamplingTimer(mClock, mOnBatteryScreenOffTimeBase, in); 18487 mKernelWakelockStats.put(wakelockName, kwlt); 18488 } 18489 } 18490 18491 mWakeupReasonStats.clear(); 18492 int NWR = in.readInt(); 18493 for (int iwr = 0; iwr < NWR; iwr++) { 18494 if (in.readInt() != 0) { 18495 String reasonName = in.readString(); 18496 SamplingTimer timer = new SamplingTimer(mClock, mOnBatteryTimeBase, in); 18497 mWakeupReasonStats.put(reasonName, timer); 18498 } 18499 } 18500 18501 mKernelMemoryStats.clear(); 18502 int nmt = in.readInt(); 18503 for (int imt = 0; imt < nmt; imt++) { 18504 if (in.readInt() != 0) { 18505 Long bucket = in.readLong(); 18506 SamplingTimer kmt = new SamplingTimer(mClock, mOnBatteryTimeBase, in); 18507 mKernelMemoryStats.put(bucket, kmt); 18508 } 18509 } 18510 18511 mPartialTimers.clear(); 18512 mFullTimers.clear(); 18513 mWindowTimers.clear(); 18514 mWifiRunningTimers.clear(); 18515 mFullWifiLockTimers.clear(); 18516 mWifiScanTimers.clear(); 18517 mWifiBatchedScanTimers.clear(); 18518 mWifiMulticastTimers.clear(); 18519 mAudioTurnedOnTimers.clear(); 18520 mVideoTurnedOnTimers.clear(); 18521 mFlashlightTurnedOnTimers.clear(); 18522 mCameraTurnedOnTimers.clear(); 18523 18524 int numUids = in.readInt(); 18525 mUidStats.clear(); 18526 final long elapsedRealtimeMs = mClock.elapsedRealtime(); 18527 final long uptimeMs = mClock.uptimeMillis(); 18528 for (int i = 0; i < numUids; i++) { 18529 int uid = in.readInt(); 18530 Uid u = new Uid(this, uid, elapsedRealtimeMs, uptimeMs); 18531 u.readFromParcelLocked(mOnBatteryTimeBase, mOnBatteryScreenOffTimeBase, 18532 in); 18533 mUidStats.append(uid, u); 18534 } 18535 18536 mBinderThreadCpuTimesUs = LongSamplingCounterArray.readFromParcel(in, mOnBatteryTimeBase); 18537 } 18538 18539 @GuardedBy("this") 18540 public void writeToParcel(Parcel out, int flags) { 18541 writeToParcelLocked(out, true, flags); 18542 } 18543 18544 @GuardedBy("this") 18545 public void writeToParcelWithoutUids(Parcel out, int flags) { 18546 writeToParcelLocked(out, false, flags); 18547 } 18548 18549 @SuppressWarnings("unused") 18550 @GuardedBy("this") 18551 void writeToParcelLocked(Parcel out, boolean inclUids, int flags) { 18552 // Need to update with current kernel wake lock counts. 18553 pullPendingStateUpdatesLocked(); 18554 18555 updateSystemServiceCallStats(); 18556 18557 // Pull the clock time. This may update the time and make a new history entry 18558 // if we had originally pulled a time before the RTC was set. 18559 getStartClockTime(); 18560 18561 final long uSecUptime = mClock.uptimeMillis() * 1000; 18562 final long uSecRealtime = mClock.elapsedRealtime() * 1000; 18563 final long batteryRealtime = mOnBatteryTimeBase.getRealtime(uSecRealtime); 18564 final long batteryScreenOffRealtime = mOnBatteryScreenOffTimeBase.getRealtime(uSecRealtime); 18565 18566 out.writeInt(MAGIC); 18567 18568 writeHistoryBuffer(out, true); 18569 mBatteryStatsHistory.writeToParcel(out); 18570 18571 out.writeInt(mStartCount); 18572 out.writeLong(mStartClockTimeMs); 18573 out.writeString(mStartPlatformVersion); 18574 out.writeString(mEndPlatformVersion); 18575 out.writeLong(mUptimeUs); 18576 out.writeLong(mUptimeStartUs); 18577 out.writeLong(mRealtimeUs); 18578 out.writeLong(mRealtimeStartUs); 18579 out.writeInt(mOnBattery ? 1 : 0); 18580 out.writeInt(mEstimatedBatteryCapacityMah); 18581 out.writeInt(mLastLearnedBatteryCapacityUah); 18582 out.writeInt(mMinLearnedBatteryCapacityUah); 18583 out.writeInt(mMaxLearnedBatteryCapacityUah); 18584 mOnBatteryTimeBase.writeToParcel(out, uSecUptime, uSecRealtime); 18585 mOnBatteryScreenOffTimeBase.writeToParcel(out, uSecUptime, uSecRealtime); 18586 18587 mScreenOnTimer.writeToParcel(out, uSecRealtime); 18588 mScreenDozeTimer.writeToParcel(out, uSecRealtime); 18589 for (int i = 0; i < NUM_SCREEN_BRIGHTNESS_BINS; i++) { 18590 mScreenBrightnessTimer[i].writeToParcel(out, uSecRealtime); 18591 } 18592 mInteractiveTimer.writeToParcel(out, uSecRealtime); 18593 mPowerSaveModeEnabledTimer.writeToParcel(out, uSecRealtime); 18594 out.writeLong(mLongestLightIdleTimeMs); 18595 out.writeLong(mLongestFullIdleTimeMs); 18596 mDeviceIdleModeLightTimer.writeToParcel(out, uSecRealtime); 18597 mDeviceIdleModeFullTimer.writeToParcel(out, uSecRealtime); 18598 mDeviceLightIdlingTimer.writeToParcel(out, uSecRealtime); 18599 mDeviceIdlingTimer.writeToParcel(out, uSecRealtime); 18600 mPhoneOnTimer.writeToParcel(out, uSecRealtime); 18601 for (int i = 0; i < CellSignalStrength.getNumSignalStrengthLevels(); i++) { 18602 mPhoneSignalStrengthsTimer[i].writeToParcel(out, uSecRealtime); 18603 } 18604 mPhoneSignalScanningTimer.writeToParcel(out, uSecRealtime); 18605 for (int i = 0; i < NUM_DATA_CONNECTION_TYPES; i++) { 18606 mPhoneDataConnectionsTimer[i].writeToParcel(out, uSecRealtime); 18607 } 18608 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 18609 mNetworkByteActivityCounters[i].writeToParcel(out); 18610 mNetworkPacketActivityCounters[i].writeToParcel(out); 18611 } 18612 mMobileRadioActiveTimer.writeToParcel(out, uSecRealtime); 18613 mMobileRadioActivePerAppTimer.writeToParcel(out, uSecRealtime); 18614 mMobileRadioActiveAdjustedTime.writeToParcel(out); 18615 mMobileRadioActiveUnknownTime.writeToParcel(out); 18616 mMobileRadioActiveUnknownCount.writeToParcel(out); 18617 mWifiMulticastWakelockTimer.writeToParcel(out, uSecRealtime); 18618 mWifiOnTimer.writeToParcel(out, uSecRealtime); 18619 mGlobalWifiRunningTimer.writeToParcel(out, uSecRealtime); 18620 for (int i = 0; i < NUM_WIFI_STATES; i++) { 18621 mWifiStateTimer[i].writeToParcel(out, uSecRealtime); 18622 } 18623 for (int i = 0; i < NUM_WIFI_SUPPL_STATES; i++) { 18624 mWifiSupplStateTimer[i].writeToParcel(out, uSecRealtime); 18625 } 18626 for (int i = 0; i < NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { 18627 mWifiSignalStrengthsTimer[i].writeToParcel(out, uSecRealtime); 18628 } 18629 mWifiActiveTimer.writeToParcel(out, uSecRealtime); 18630 mWifiActivity.writeToParcel(out, 0); 18631 for (int i = 0; i < mGpsSignalQualityTimer.length; i++) { 18632 mGpsSignalQualityTimer[i].writeToParcel(out, uSecRealtime); 18633 } 18634 mBluetoothActivity.writeToParcel(out, 0); 18635 mModemActivity.writeToParcel(out, 0); 18636 out.writeInt(mHasWifiReporting ? 1 : 0); 18637 out.writeInt(mHasBluetoothReporting ? 1 : 0); 18638 out.writeInt(mHasModemReporting ? 1 : 0); 18639 18640 out.writeInt(mNumConnectivityChange); 18641 mFlashlightOnTimer.writeToParcel(out, uSecRealtime); 18642 mCameraOnTimer.writeToParcel(out, uSecRealtime); 18643 mBluetoothScanTimer.writeToParcel(out, uSecRealtime); 18644 out.writeInt(mDischargeUnplugLevel); 18645 out.writeInt(mDischargePlugLevel); 18646 out.writeInt(mDischargeCurrentLevel); 18647 out.writeInt(mCurrentBatteryLevel); 18648 out.writeInt(mLowDischargeAmountSinceCharge); 18649 out.writeInt(mHighDischargeAmountSinceCharge); 18650 out.writeInt(mDischargeAmountScreenOn); 18651 out.writeInt(mDischargeAmountScreenOnSinceCharge); 18652 out.writeInt(mDischargeAmountScreenOff); 18653 out.writeInt(mDischargeAmountScreenOffSinceCharge); 18654 out.writeInt(mDischargeAmountScreenDoze); 18655 out.writeInt(mDischargeAmountScreenDozeSinceCharge); 18656 mDischargeStepTracker.writeToParcel(out); 18657 mChargeStepTracker.writeToParcel(out); 18658 mDischargeCounter.writeToParcel(out); 18659 mDischargeScreenOffCounter.writeToParcel(out); 18660 mDischargeScreenDozeCounter.writeToParcel(out); 18661 mDischargeLightDozeCounter.writeToParcel(out); 18662 mDischargeDeepDozeCounter.writeToParcel(out); 18663 out.writeLong(mLastWriteTimeMs); 18664 out.writeLong(mBatteryTimeToFullSeconds); 18665 18666 MeasuredEnergyStats.Config.writeToParcel(mMeasuredEnergyStatsConfig, out); 18667 18668 if (mGlobalMeasuredEnergyStats != null) { 18669 out.writeInt(1); 18670 mGlobalMeasuredEnergyStats.writeToParcel(out); 18671 } else { 18672 out.writeInt(0); 18673 } 18674 18675 out.writeInt(mRpmStats.size()); 18676 for (Map.Entry<String, SamplingTimer> ent : mRpmStats.entrySet()) { 18677 SamplingTimer rpmt = ent.getValue(); 18678 if (rpmt != null) { 18679 out.writeInt(1); 18680 out.writeString(ent.getKey()); 18681 rpmt.writeToParcel(out, uSecRealtime); 18682 } else { 18683 out.writeInt(0); 18684 } 18685 } 18686 out.writeInt(mScreenOffRpmStats.size()); 18687 for (Map.Entry<String, SamplingTimer> ent : mScreenOffRpmStats.entrySet()) { 18688 SamplingTimer rpmt = ent.getValue(); 18689 if (rpmt != null) { 18690 out.writeInt(1); 18691 out.writeString(ent.getKey()); 18692 rpmt.writeToParcel(out, uSecRealtime); 18693 } else { 18694 out.writeInt(0); 18695 } 18696 } 18697 18698 if (inclUids) { 18699 out.writeInt(mKernelWakelockStats.size()); 18700 for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) { 18701 SamplingTimer kwlt = ent.getValue(); 18702 if (kwlt != null) { 18703 out.writeInt(1); 18704 out.writeString(ent.getKey()); 18705 kwlt.writeToParcel(out, uSecRealtime); 18706 } else { 18707 out.writeInt(0); 18708 } 18709 } 18710 out.writeInt(mWakeupReasonStats.size()); 18711 for (Map.Entry<String, SamplingTimer> ent : mWakeupReasonStats.entrySet()) { 18712 SamplingTimer timer = ent.getValue(); 18713 if (timer != null) { 18714 out.writeInt(1); 18715 out.writeString(ent.getKey()); 18716 timer.writeToParcel(out, uSecRealtime); 18717 } else { 18718 out.writeInt(0); 18719 } 18720 } 18721 } else { 18722 out.writeInt(0); 18723 out.writeInt(0); 18724 } 18725 18726 out.writeInt(mKernelMemoryStats.size()); 18727 for (int i = 0; i < mKernelMemoryStats.size(); i++) { 18728 SamplingTimer kmt = mKernelMemoryStats.valueAt(i); 18729 if (kmt != null) { 18730 out.writeInt(1); 18731 out.writeLong(mKernelMemoryStats.keyAt(i)); 18732 kmt.writeToParcel(out, uSecRealtime); 18733 } else { 18734 out.writeInt(0); 18735 } 18736 } 18737 18738 if (inclUids) { 18739 int size = mUidStats.size(); 18740 out.writeInt(size); 18741 for (int i = 0; i < size; i++) { 18742 out.writeInt(mUidStats.keyAt(i)); 18743 Uid uid = mUidStats.valueAt(i); 18744 18745 uid.writeToParcelLocked(out, uSecUptime, uSecRealtime); 18746 } 18747 } else { 18748 out.writeInt(0); 18749 } 18750 LongSamplingCounterArray.writeToParcel(out, mBinderThreadCpuTimesUs); 18751 } 18752 18753 private void writeCpuSpeedCountersToParcel(Parcel out, LongSamplingCounter[][] counters) { 18754 if (counters == null) { 18755 out.writeInt(0); 18756 return; 18757 } 18758 18759 out.writeInt(1); 18760 out.writeInt(counters.length); 18761 for (int i = 0; i < counters.length; i++) { 18762 LongSamplingCounter[] counterArray = counters[i]; 18763 if (counterArray == null) { 18764 out.writeInt(0); 18765 continue; 18766 } 18767 18768 out.writeInt(1); 18769 out.writeInt(counterArray.length); 18770 for (int j = 0; j < counterArray.length; j++) { 18771 LongSamplingCounter c = counterArray[j]; 18772 if (c != null) { 18773 out.writeInt(1); 18774 c.writeToParcel(out); 18775 } else { 18776 out.writeInt(0); 18777 } 18778 } 18779 } 18780 } 18781 18782 private LongSamplingCounter[][] readCpuSpeedCountersFromParcel(Parcel in) { 18783 LongSamplingCounter[][] counters; 18784 if (in.readInt() != 0) { 18785 int numCpuClusters = in.readInt(); 18786 if (mPowerProfile != null 18787 && mPowerProfile.getNumCpuClusters() != numCpuClusters) { 18788 throw new ParcelFormatException("Incompatible number of cpu clusters"); 18789 } 18790 18791 counters = new LongSamplingCounter[numCpuClusters][]; 18792 for (int cluster = 0; cluster < numCpuClusters; cluster++) { 18793 if (in.readInt() != 0) { 18794 int numSpeeds = in.readInt(); 18795 if (mPowerProfile != null 18796 && mPowerProfile.getNumSpeedStepsInCpuCluster(cluster) != numSpeeds) { 18797 throw new ParcelFormatException("Incompatible number of cpu speeds"); 18798 } 18799 18800 final LongSamplingCounter[] cpuSpeeds = new LongSamplingCounter[numSpeeds]; 18801 counters[cluster] = cpuSpeeds; 18802 for (int speed = 0; speed < numSpeeds; speed++) { 18803 if (in.readInt() != 0) { 18804 cpuSpeeds[speed] = new LongSamplingCounter(mOnBatteryTimeBase, in); 18805 } 18806 } 18807 } else { 18808 counters[cluster] = null; 18809 } 18810 } 18811 } else { 18812 counters = null; 18813 } 18814 18815 return counters; 18816 } 18817 18818 @UnsupportedAppUsage 18819 public static final Parcelable.Creator<BatteryStatsImpl> CREATOR = 18820 new Parcelable.Creator<BatteryStatsImpl>() { 18821 public BatteryStatsImpl createFromParcel(Parcel in) { 18822 return new BatteryStatsImpl(in); 18823 } 18824 18825 public BatteryStatsImpl[] newArray(int size) { 18826 return new BatteryStatsImpl[size]; 18827 } 18828 }; 18829 18830 @GuardedBy("this") 18831 public void prepareForDumpLocked() { 18832 // Need to retrieve current kernel wake lock stats before printing. 18833 pullPendingStateUpdatesLocked(); 18834 18835 // Pull the clock time. This may update the time and make a new history entry 18836 // if we had originally pulled a time before the RTC was set. 18837 getStartClockTime(); 18838 18839 updateSystemServiceCallStats(); 18840 } 18841 18842 @GuardedBy("this") 18843 public void dumpLocked(Context context, PrintWriter pw, int flags, int reqUid, long histStart) { 18844 if (DEBUG) { 18845 pw.println("mOnBatteryTimeBase:"); 18846 mOnBatteryTimeBase.dump(pw, " "); 18847 pw.println("mOnBatteryScreenOffTimeBase:"); 18848 mOnBatteryScreenOffTimeBase.dump(pw, " "); 18849 Printer pr = new PrintWriterPrinter(pw); 18850 pr.println("*** Screen on timer:"); 18851 mScreenOnTimer.logState(pr, " "); 18852 pr.println("*** Screen doze timer:"); 18853 mScreenDozeTimer.logState(pr, " "); 18854 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 18855 pr.println("*** Screen brightness #" + i + ":"); 18856 mScreenBrightnessTimer[i].logState(pr, " "); 18857 } 18858 pr.println("*** Interactive timer:"); 18859 mInteractiveTimer.logState(pr, " "); 18860 pr.println("*** Power save mode timer:"); 18861 mPowerSaveModeEnabledTimer.logState(pr, " "); 18862 pr.println("*** Device idle mode light timer:"); 18863 mDeviceIdleModeLightTimer.logState(pr, " "); 18864 pr.println("*** Device idle mode full timer:"); 18865 mDeviceIdleModeFullTimer.logState(pr, " "); 18866 pr.println("*** Device light idling timer:"); 18867 mDeviceLightIdlingTimer.logState(pr, " "); 18868 pr.println("*** Device idling timer:"); 18869 mDeviceIdlingTimer.logState(pr, " "); 18870 pr.println("*** Phone timer:"); 18871 mPhoneOnTimer.logState(pr, " "); 18872 for (int i = 0; i < CellSignalStrength.getNumSignalStrengthLevels(); i++) { 18873 pr.println("*** Phone signal strength #" + i + ":"); 18874 mPhoneSignalStrengthsTimer[i].logState(pr, " "); 18875 } 18876 pr.println("*** Signal scanning :"); 18877 mPhoneSignalScanningTimer.logState(pr, " "); 18878 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 18879 pr.println("*** Data connection type #" + i + ":"); 18880 mPhoneDataConnectionsTimer[i].logState(pr, " "); 18881 } 18882 pr.println("*** mMobileRadioPowerState=" + mMobileRadioPowerState); 18883 pr.println("*** Mobile network active timer:"); 18884 mMobileRadioActiveTimer.logState(pr, " "); 18885 pr.println("*** Mobile network active adjusted timer:"); 18886 mMobileRadioActiveAdjustedTime.logState(pr, " "); 18887 pr.println("*** Wifi Multicast WakeLock Timer:"); 18888 mWifiMulticastWakelockTimer.logState(pr, " "); 18889 pr.println("*** mWifiRadioPowerState=" + mWifiRadioPowerState); 18890 pr.println("*** Wifi timer:"); 18891 mWifiOnTimer.logState(pr, " "); 18892 pr.println("*** WifiRunning timer:"); 18893 mGlobalWifiRunningTimer.logState(pr, " "); 18894 for (int i=0; i<NUM_WIFI_STATES; i++) { 18895 pr.println("*** Wifi state #" + i + ":"); 18896 mWifiStateTimer[i].logState(pr, " "); 18897 } 18898 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) { 18899 pr.println("*** Wifi suppl state #" + i + ":"); 18900 mWifiSupplStateTimer[i].logState(pr, " "); 18901 } 18902 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { 18903 pr.println("*** Wifi signal strength #" + i + ":"); 18904 mWifiSignalStrengthsTimer[i].logState(pr, " "); 18905 } 18906 for (int i=0; i<mGpsSignalQualityTimer.length; i++) { 18907 pr.println("*** GPS signal quality #" + i + ":"); 18908 mGpsSignalQualityTimer[i].logState(pr, " "); 18909 } 18910 pr.println("*** Flashlight timer:"); 18911 mFlashlightOnTimer.logState(pr, " "); 18912 pr.println("*** Camera timer:"); 18913 mCameraOnTimer.logState(pr, " "); 18914 } 18915 super.dumpLocked(context, pw, flags, reqUid, histStart); 18916 18917 pw.print("Per process state tracking available: "); 18918 pw.println(trackPerProcStateCpuTimes()); 18919 pw.print("Total cpu time reads: "); 18920 pw.println(mNumSingleUidCpuTimeReads); 18921 pw.print("Batching Duration (min): "); 18922 pw.println((mClock.uptimeMillis() - mCpuTimeReadsTrackingStartTimeMs) / (60 * 1000)); 18923 pw.print("All UID cpu time reads since the later of device start or stats reset: "); 18924 pw.println(mNumAllUidCpuTimeReads); 18925 pw.print("UIDs removed since the later of device start or stats reset: "); 18926 pw.println(mNumUidsRemoved); 18927 18928 pw.println("Currently mapped isolated uids:"); 18929 final int numIsolatedUids = mIsolatedUids.size(); 18930 for (int i = 0; i < numIsolatedUids; i++) { 18931 final int isolatedUid = mIsolatedUids.keyAt(i); 18932 final int ownerUid = mIsolatedUids.valueAt(i); 18933 final int refCount = mIsolatedUidRefCounts.get(isolatedUid); 18934 pw.println(" " + isolatedUid + "->" + ownerUid + " (ref count = " + refCount + ")"); 18935 } 18936 18937 pw.println(); 18938 dumpConstantsLocked(pw); 18939 18940 pw.println(); 18941 dumpMeasuredEnergyStatsLocked(pw); 18942 } 18943 } 18944