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.BatteryStatsManager.NUM_WIFI_STATES; 22 import static android.os.BatteryStatsManager.NUM_WIFI_SUPPL_STATES; 23 24 import android.annotation.IntDef; 25 import android.annotation.NonNull; 26 import android.annotation.Nullable; 27 import android.app.ActivityManager; 28 import android.bluetooth.BluetoothActivityEnergyInfo; 29 import android.bluetooth.UidTraffic; 30 import android.compat.annotation.UnsupportedAppUsage; 31 import android.content.BroadcastReceiver; 32 import android.content.ContentResolver; 33 import android.content.Context; 34 import android.content.Intent; 35 import android.content.IntentFilter; 36 import android.database.ContentObserver; 37 import android.hardware.usb.UsbManager; 38 import android.location.GnssSignalQuality; 39 import android.net.INetworkStatsService; 40 import android.net.NetworkStats; 41 import android.net.Uri; 42 import android.net.wifi.WifiManager; 43 import android.os.BatteryConsumer; 44 import android.os.BatteryManager; 45 import android.os.BatteryStats; 46 import android.os.Binder; 47 import android.os.Build; 48 import android.os.Handler; 49 import android.os.IBatteryPropertiesRegistrar; 50 import android.os.Looper; 51 import android.os.Message; 52 import android.os.OsProtoEnums; 53 import android.os.Parcel; 54 import android.os.ParcelFormatException; 55 import android.os.Parcelable; 56 import android.os.PowerManager; 57 import android.os.Process; 58 import android.os.RemoteException; 59 import android.os.ServiceManager; 60 import android.os.SystemClock; 61 import android.os.UserHandle; 62 import android.os.WorkSource; 63 import android.os.WorkSource.WorkChain; 64 import android.os.connectivity.CellularBatteryStats; 65 import android.os.connectivity.GpsBatteryStats; 66 import android.os.connectivity.WifiActivityEnergyInfo; 67 import android.os.connectivity.WifiBatteryStats; 68 import android.provider.Settings; 69 import android.telephony.CellSignalStrength; 70 import android.telephony.DataConnectionRealTimeInfo; 71 import android.telephony.ModemActivityInfo; 72 import android.telephony.ServiceState; 73 import android.telephony.SignalStrength; 74 import android.telephony.TelephonyManager; 75 import android.text.TextUtils; 76 import android.util.ArrayMap; 77 import android.util.ArraySet; 78 import android.util.AtomicFile; 79 import android.util.IndentingPrintWriter; 80 import android.util.IntArray; 81 import android.util.KeyValueListParser; 82 import android.util.Log; 83 import android.util.LongSparseArray; 84 import android.util.LongSparseLongArray; 85 import android.util.MutableInt; 86 import android.util.Pools; 87 import android.util.PrintWriterPrinter; 88 import android.util.Printer; 89 import android.util.Slog; 90 import android.util.SparseArray; 91 import android.util.SparseDoubleArray; 92 import android.util.SparseIntArray; 93 import android.util.SparseLongArray; 94 import android.util.TimeUtils; 95 import android.util.TypedXmlPullParser; 96 import android.util.TypedXmlSerializer; 97 import android.util.Xml; 98 import android.view.Display; 99 100 import com.android.internal.annotations.GuardedBy; 101 import com.android.internal.annotations.VisibleForTesting; 102 import com.android.internal.os.KernelCpuUidTimeReader.KernelCpuUidActiveTimeReader; 103 import com.android.internal.os.KernelCpuUidTimeReader.KernelCpuUidClusterTimeReader; 104 import com.android.internal.os.KernelCpuUidTimeReader.KernelCpuUidFreqTimeReader; 105 import com.android.internal.os.KernelCpuUidTimeReader.KernelCpuUidUserSysTimeReader; 106 import com.android.internal.os.SystemServerCpuThreadReader.SystemServiceCpuThreadTimes; 107 import com.android.internal.power.MeasuredEnergyStats; 108 import com.android.internal.power.MeasuredEnergyStats.StandardPowerBucket; 109 import com.android.internal.util.ArrayUtils; 110 import com.android.internal.util.FrameworkStatsLog; 111 import com.android.internal.util.XmlUtils; 112 import com.android.net.module.util.NetworkCapabilitiesUtils; 113 114 import libcore.util.EmptyArray; 115 116 import org.xmlpull.v1.XmlPullParser; 117 import org.xmlpull.v1.XmlPullParserException; 118 119 import java.io.ByteArrayOutputStream; 120 import java.io.File; 121 import java.io.FileInputStream; 122 import java.io.FileNotFoundException; 123 import java.io.FileOutputStream; 124 import java.io.IOException; 125 import java.io.PrintWriter; 126 import java.lang.annotation.Retention; 127 import java.lang.annotation.RetentionPolicy; 128 import java.util.ArrayList; 129 import java.util.Arrays; 130 import java.util.Calendar; 131 import java.util.Collection; 132 import java.util.Comparator; 133 import java.util.HashMap; 134 import java.util.HashSet; 135 import java.util.Iterator; 136 import java.util.LinkedList; 137 import java.util.List; 138 import java.util.Map; 139 import java.util.Queue; 140 import java.util.concurrent.Future; 141 import java.util.concurrent.atomic.AtomicInteger; 142 import java.util.concurrent.locks.ReentrantLock; 143 144 /** 145 * All information we are collecting about things that can happen that impact 146 * battery life. All times are represented in microseconds except where indicated 147 * otherwise. 148 */ 149 public class BatteryStatsImpl extends BatteryStats { 150 private static final String TAG = "BatteryStatsImpl"; 151 private static final boolean DEBUG = false; 152 public static final boolean DEBUG_ENERGY = false; 153 private static final boolean DEBUG_ENERGY_CPU = DEBUG_ENERGY; 154 private static final boolean DEBUG_BINDER_STATS = false; 155 private static final boolean DEBUG_MEMORY = false; 156 private static final boolean DEBUG_HISTORY = false; 157 158 // TODO: remove "tcp" from network methods, since we measure total stats. 159 160 // In-memory Parcel magic number, used to detect attempts to unmarshall bad data 161 private static final int MAGIC = 0xBA757475; // 'BATSTATS' 162 163 // Current on-disk Parcel version 164 static final int VERSION = 200; 165 166 // The maximum number of names wakelocks we will keep track of 167 // per uid; once the limit is reached, we batch the remaining wakelocks 168 // in to one common name. 169 private static final int MAX_WAKELOCKS_PER_UID; 170 171 static { 172 if (ActivityManager.isLowRamDeviceStatic()) { 173 MAX_WAKELOCKS_PER_UID = 40; 174 } else { 175 MAX_WAKELOCKS_PER_UID = 200; 176 } 177 } 178 179 // Number of transmit power states the Wifi controller can be in. 180 private static final int NUM_WIFI_TX_LEVELS = 1; 181 182 // Number of transmit power states the Bluetooth controller can be in. 183 private static final int NUM_BT_TX_LEVELS = 1; 184 185 /** 186 * Holding a wakelock costs more than just using the cpu. 187 * Currently, we assign only half the cpu time to an app that is running but 188 * not holding a wakelock. The apps holding wakelocks get the rest of the blame. 189 * If no app is holding a wakelock, then the distribution is normal. 190 */ 191 @VisibleForTesting 192 public static final int WAKE_LOCK_WEIGHT = 50; 193 194 public static final int RESET_REASON_CORRUPT_FILE = 1; 195 public static final int RESET_REASON_ADB_COMMAND = 2; 196 public static final int RESET_REASON_FULL_CHARGE = 3; 197 public static final int RESET_REASON_MEASURED_ENERGY_BUCKETS_CHANGE = 4; 198 199 protected Clocks mClocks; 200 201 private final AtomicFile mStatsFile; 202 public final AtomicFile mCheckinFile; 203 public final AtomicFile mDailyFile; 204 205 static final int MSG_REPORT_CPU_UPDATE_NEEDED = 1; 206 static final int MSG_REPORT_POWER_CHANGE = 2; 207 static final int MSG_REPORT_CHARGING = 3; 208 static final int MSG_REPORT_RESET_STATS = 4; 209 static final long DELAY_UPDATE_WAKELOCKS = 60 * 1000; 210 211 private static final double MILLISECONDS_IN_HOUR = 3600 * 1000; 212 private static final long MILLISECONDS_IN_YEAR = 365 * 24 * 3600 * 1000L; 213 214 private final KernelWakelockReader mKernelWakelockReader = new KernelWakelockReader(); 215 private final KernelWakelockStats mTmpWakelockStats = new KernelWakelockStats(); 216 217 @VisibleForTesting 218 protected KernelCpuUidUserSysTimeReader mCpuUidUserSysTimeReader = 219 new KernelCpuUidUserSysTimeReader(true); 220 @VisibleForTesting 221 protected KernelCpuSpeedReader[] mKernelCpuSpeedReaders; 222 @VisibleForTesting 223 protected KernelCpuUidFreqTimeReader mCpuUidFreqTimeReader = 224 new KernelCpuUidFreqTimeReader(true); 225 @VisibleForTesting 226 protected KernelCpuUidActiveTimeReader mCpuUidActiveTimeReader = 227 new KernelCpuUidActiveTimeReader(true); 228 @VisibleForTesting 229 protected KernelCpuUidClusterTimeReader mCpuUidClusterTimeReader = 230 new KernelCpuUidClusterTimeReader(true); 231 @VisibleForTesting 232 protected KernelSingleUidTimeReader mKernelSingleUidTimeReader; 233 @VisibleForTesting 234 protected SystemServerCpuThreadReader mSystemServerCpuThreadReader = 235 SystemServerCpuThreadReader.create(); 236 237 private final KernelMemoryBandwidthStats mKernelMemoryBandwidthStats 238 = new KernelMemoryBandwidthStats(); 239 private final LongSparseArray<SamplingTimer> mKernelMemoryStats = new LongSparseArray<>(); 240 getKernelMemoryStats()241 public LongSparseArray<SamplingTimer> getKernelMemoryStats() { 242 return mKernelMemoryStats; 243 } 244 245 @GuardedBy("this") 246 public boolean mPerProcStateCpuTimesAvailable = true; 247 248 /** 249 * When per process state cpu times tracking is off, cpu times in KernelSingleUidTimeReader are 250 * not updated. So, when the setting is turned on later, we would end up with huge cpu time 251 * deltas. This flag tracks the case where tracking is turned on from off so that we won't 252 * end up attributing the huge deltas to wrong buckets. 253 */ 254 @GuardedBy("this") 255 private boolean mIsPerProcessStateCpuDataStale; 256 257 /** 258 * Uids for which per-procstate cpu times need to be updated. 259 * 260 * Contains uid -> procState mappings. 261 */ 262 @GuardedBy("this") 263 @VisibleForTesting 264 protected final SparseIntArray mPendingUids = new SparseIntArray(); 265 266 @GuardedBy("this") 267 private long mNumSingleUidCpuTimeReads; 268 @GuardedBy("this") 269 private long mNumBatchedSingleUidCpuTimeReads; 270 @GuardedBy("this") 271 private long mCpuTimeReadsTrackingStartTimeMs = SystemClock.uptimeMillis(); 272 @GuardedBy("this") 273 private int mNumUidsRemoved; 274 @GuardedBy("this") 275 private int mNumAllUidCpuTimeReads; 276 277 /** Container for Resource Power Manager stats. Updated by updateRpmStatsLocked. */ 278 private RpmStats mTmpRpmStats = null; 279 /** The soonest the RPM stats can be updated after it was last updated. */ 280 private static final long RPM_STATS_UPDATE_FREQ_MS = 1000; 281 /** Last time that RPM stats were updated by updateRpmStatsLocked. */ 282 private long mLastRpmStatsUpdateTimeMs = -RPM_STATS_UPDATE_FREQ_MS; 283 284 /** Container for Rail Energy Data stats. */ 285 private final RailStats mTmpRailStats = new RailStats(); 286 287 /** 288 * Use a queue to delay removing UIDs from {@link KernelCpuUidUserSysTimeReader}, 289 * {@link KernelCpuUidActiveTimeReader}, {@link KernelCpuUidClusterTimeReader}, 290 * {@link KernelCpuUidFreqTimeReader} and from the Kernel. 291 * 292 * Isolated and invalid UID info must be removed to conserve memory. However, STATSD and 293 * Batterystats both need to access UID cpu time. To resolve this race condition, only 294 * Batterystats shall remove UIDs, and a delay {@link Constants#UID_REMOVE_DELAY_MS} is 295 * implemented so that STATSD can capture those UID times before they are deleted. 296 */ 297 @GuardedBy("this") 298 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) 299 protected Queue<UidToRemove> mPendingRemovedUids = new LinkedList<>(); 300 301 @VisibleForTesting 302 public final class UidToRemove { 303 int startUid; 304 int endUid; 305 long mTimeAddedInQueueMs; 306 307 /** Remove just one UID */ UidToRemove(int uid, long timestamp)308 public UidToRemove(int uid, long timestamp) { 309 this(uid, uid, timestamp); 310 } 311 312 /** Remove a range of UIDs, startUid must be smaller than endUid. */ UidToRemove(int startUid, int endUid, long timestamp)313 public UidToRemove(int startUid, int endUid, long timestamp) { 314 this.startUid = startUid; 315 this.endUid = endUid; 316 mTimeAddedInQueueMs = timestamp; 317 } 318 remove()319 void remove() { 320 if (startUid == endUid) { 321 mCpuUidUserSysTimeReader.removeUid(startUid); 322 mCpuUidFreqTimeReader.removeUid(startUid); 323 if (mConstants.TRACK_CPU_ACTIVE_CLUSTER_TIME) { 324 mCpuUidActiveTimeReader.removeUid(startUid); 325 mCpuUidClusterTimeReader.removeUid(startUid); 326 } 327 if (mKernelSingleUidTimeReader != null) { 328 mKernelSingleUidTimeReader.removeUid(startUid); 329 } 330 mNumUidsRemoved++; 331 } else if (startUid < endUid) { 332 mCpuUidFreqTimeReader.removeUidsInRange(startUid, endUid); 333 mCpuUidUserSysTimeReader.removeUidsInRange(startUid, endUid); 334 if (mConstants.TRACK_CPU_ACTIVE_CLUSTER_TIME) { 335 mCpuUidActiveTimeReader.removeUidsInRange(startUid, endUid); 336 mCpuUidClusterTimeReader.removeUidsInRange(startUid, endUid); 337 } 338 if (mKernelSingleUidTimeReader != null) { 339 mKernelSingleUidTimeReader.removeUidsInRange(startUid, endUid); 340 } 341 // Treat as one. We don't know how many uids there are in between. 342 mNumUidsRemoved++; 343 } else { 344 Slog.w(TAG, "End UID " + endUid + " is smaller than start UID " + startUid); 345 } 346 } 347 } 348 349 /** 350 * Listener for the battery stats reset. 351 */ 352 public interface BatteryResetListener { 353 354 /** 355 * Callback invoked immediately prior to resetting battery stats. 356 * @param resetReason One of the RESET_REASON_* constants. 357 */ prepareForBatteryStatsReset(int resetReason)358 void prepareForBatteryStatsReset(int resetReason); 359 } 360 361 private BatteryResetListener mBatteryResetListener; 362 363 public interface BatteryCallback { batteryNeedsCpuUpdate()364 public void batteryNeedsCpuUpdate(); batteryPowerChanged(boolean onBattery)365 public void batteryPowerChanged(boolean onBattery); batterySendBroadcast(Intent intent)366 public void batterySendBroadcast(Intent intent); batteryStatsReset()367 public void batteryStatsReset(); 368 } 369 370 public interface PlatformIdleStateCallback { fillLowPowerStats(RpmStats rpmStats)371 public void fillLowPowerStats(RpmStats rpmStats); getSubsystemLowPowerStats()372 public String getSubsystemLowPowerStats(); 373 } 374 375 /** interface to update rail information for power monitor */ 376 public interface MeasuredEnergyRetriever { 377 /** Function to fill the map for the rail data stats 378 * Used for power monitoring feature 379 * @param railStats 380 */ fillRailDataStats(RailStats railStats)381 void fillRailDataStats(RailStats railStats); 382 } 383 384 public static abstract class UserInfoProvider { 385 private int[] userIds; getUserIds()386 protected abstract @Nullable int[] getUserIds(); 387 @VisibleForTesting refreshUserIds()388 public final void refreshUserIds() { 389 userIds = getUserIds(); 390 } 391 @VisibleForTesting exists(int userId)392 public boolean exists(int userId) { 393 return userIds != null ? ArrayUtils.contains(userIds, userId) : true; 394 } 395 } 396 397 private final PlatformIdleStateCallback mPlatformIdleStateCallback; 398 399 private final Runnable mDeferSetCharging = new Runnable() { 400 @Override 401 public void run() { 402 synchronized (BatteryStatsImpl.this) { 403 if (mOnBattery) { 404 // if the device gets unplugged in the time between this runnable being 405 // executed and the lock being taken, we don't want to set charging state 406 return; 407 } 408 boolean changed = setChargingLocked(true); 409 if (changed) { 410 final long uptimeMs = mClocks.uptimeMillis(); 411 final long elapsedRealtimeMs = mClocks.elapsedRealtime(); 412 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 413 } 414 } 415 } 416 }; 417 418 public final MeasuredEnergyRetriever mMeasuredEnergyRetriever; 419 420 /** 421 * This handler is running on {@link BackgroundThread}. 422 */ 423 final class MyHandler extends Handler { MyHandler(Looper looper)424 public MyHandler(Looper looper) { 425 super(looper, null, true); 426 } 427 428 @Override handleMessage(Message msg)429 public void handleMessage(Message msg) { 430 BatteryCallback cb = mCallback; 431 switch (msg.what) { 432 case MSG_REPORT_CPU_UPDATE_NEEDED: 433 if (cb != null) { 434 cb.batteryNeedsCpuUpdate(); 435 } 436 break; 437 case MSG_REPORT_POWER_CHANGE: 438 if (cb != null) { 439 cb.batteryPowerChanged(msg.arg1 != 0); 440 } 441 break; 442 case MSG_REPORT_CHARGING: 443 if (cb != null) { 444 final String action; 445 synchronized (BatteryStatsImpl.this) { 446 action = mCharging ? BatteryManager.ACTION_CHARGING 447 : BatteryManager.ACTION_DISCHARGING; 448 } 449 Intent intent = new Intent(action); 450 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); 451 cb.batterySendBroadcast(intent); 452 } 453 break; 454 case MSG_REPORT_RESET_STATS: 455 if (cb != null) { 456 cb.batteryStatsReset(); 457 } 458 } 459 } 460 } 461 postBatteryNeedsCpuUpdateMsg()462 public void postBatteryNeedsCpuUpdateMsg() { 463 mHandler.sendEmptyMessage(MSG_REPORT_CPU_UPDATE_NEEDED); 464 } 465 466 /** 467 * Update per-freq cpu times for all the uids in {@link #mPendingUids}. 468 */ updateProcStateCpuTimes(boolean onBattery, boolean onBatteryScreenOff)469 public void updateProcStateCpuTimes(boolean onBattery, boolean onBatteryScreenOff) { 470 final SparseIntArray uidStates; 471 synchronized (BatteryStatsImpl.this) { 472 if (!mConstants.TRACK_CPU_TIMES_BY_PROC_STATE) { 473 return; 474 } 475 if(!initKernelSingleUidTimeReaderLocked()) { 476 return; 477 } 478 // If the KernelSingleUidTimeReader has stale cpu times, then we shouldn't try to 479 // compute deltas since it might result in mis-attributing cpu times to wrong states. 480 if (mIsPerProcessStateCpuDataStale) { 481 mPendingUids.clear(); 482 return; 483 } 484 485 if (mPendingUids.size() == 0) { 486 return; 487 } 488 uidStates = mPendingUids.clone(); 489 mPendingUids.clear(); 490 } 491 for (int i = uidStates.size() - 1; i >= 0; --i) { 492 final int uid = uidStates.keyAt(i); 493 final int procState = uidStates.valueAt(i); 494 final int[] isolatedUids; 495 final Uid u; 496 synchronized (BatteryStatsImpl.this) { 497 // It's possible that uid no longer exists and any internal references have 498 // already been deleted, so using {@link #getAvailableUidStatsLocked} to avoid 499 // creating an UidStats object if it doesn't already exist. 500 u = getAvailableUidStatsLocked(uid); 501 if (u == null) { 502 continue; 503 } 504 if (u.mChildUids == null) { 505 isolatedUids = null; 506 } else { 507 isolatedUids = u.mChildUids.toArray(); 508 for (int j = isolatedUids.length - 1; j >= 0; --j) { 509 isolatedUids[j] = u.mChildUids.get(j); 510 } 511 } 512 } 513 long[] cpuTimesMs = mKernelSingleUidTimeReader.readDeltaMs(uid); 514 if (isolatedUids != null) { 515 for (int j = isolatedUids.length - 1; j >= 0; --j) { 516 cpuTimesMs = addCpuTimes(cpuTimesMs, 517 mKernelSingleUidTimeReader.readDeltaMs(isolatedUids[j])); 518 } 519 } 520 if (onBattery && cpuTimesMs != null) { 521 synchronized (BatteryStatsImpl.this) { 522 u.addProcStateTimesMs(procState, cpuTimesMs, onBattery); 523 u.addProcStateScreenOffTimesMs(procState, cpuTimesMs, onBatteryScreenOff); 524 } 525 } 526 } 527 } 528 clearPendingRemovedUids()529 public void clearPendingRemovedUids() { 530 long cutOffTimeMs = mClocks.elapsedRealtime() - mConstants.UID_REMOVE_DELAY_MS; 531 while (!mPendingRemovedUids.isEmpty() 532 && mPendingRemovedUids.peek().mTimeAddedInQueueMs < cutOffTimeMs) { 533 mPendingRemovedUids.poll().remove(); 534 } 535 } 536 copyFromAllUidsCpuTimes()537 public void copyFromAllUidsCpuTimes() { 538 synchronized (BatteryStatsImpl.this) { 539 copyFromAllUidsCpuTimes( 540 mOnBatteryTimeBase.isRunning(), mOnBatteryScreenOffTimeBase.isRunning()); 541 } 542 } 543 544 /** 545 * When the battery/screen state changes, we don't attribute the cpu times to any process 546 * but we still need to snapshots of all uids to get correct deltas later on. Since we 547 * already read this data for updating per-freq cpu times, we can use the same data for 548 * per-procstate cpu times. 549 */ copyFromAllUidsCpuTimes(boolean onBattery, boolean onBatteryScreenOff)550 public void copyFromAllUidsCpuTimes(boolean onBattery, boolean onBatteryScreenOff) { 551 synchronized (BatteryStatsImpl.this) { 552 if (!mConstants.TRACK_CPU_TIMES_BY_PROC_STATE) { 553 return; 554 } 555 if(!initKernelSingleUidTimeReaderLocked()) { 556 return; 557 } 558 559 final SparseArray<long[]> allUidCpuFreqTimesMs = 560 mCpuUidFreqTimeReader.getAllUidCpuFreqTimeMs(); 561 // If the KernelSingleUidTimeReader has stale cpu times, then we shouldn't try to 562 // compute deltas since it might result in mis-attributing cpu times to wrong states. 563 if (mIsPerProcessStateCpuDataStale) { 564 mKernelSingleUidTimeReader.setAllUidsCpuTimesMs(allUidCpuFreqTimesMs); 565 mIsPerProcessStateCpuDataStale = false; 566 mPendingUids.clear(); 567 return; 568 } 569 for (int i = allUidCpuFreqTimesMs.size() - 1; i >= 0; --i) { 570 final int uid = allUidCpuFreqTimesMs.keyAt(i); 571 final Uid u = getAvailableUidStatsLocked(mapUid(uid)); 572 if (u == null) { 573 continue; 574 } 575 final long[] cpuTimesMs = allUidCpuFreqTimesMs.valueAt(i); 576 if (cpuTimesMs == null) { 577 continue; 578 } 579 final long[] deltaTimesMs = mKernelSingleUidTimeReader.computeDelta( 580 uid, cpuTimesMs.clone()); 581 if (onBattery && deltaTimesMs != null) { 582 final int procState; 583 final int idx = mPendingUids.indexOfKey(uid); 584 if (idx >= 0) { 585 procState = mPendingUids.valueAt(idx); 586 mPendingUids.removeAt(idx); 587 } else { 588 procState = u.mProcessState; 589 } 590 if (procState >= 0 && procState < Uid.NUM_PROCESS_STATE) { 591 u.addProcStateTimesMs(procState, deltaTimesMs, onBattery); 592 u.addProcStateScreenOffTimesMs(procState, deltaTimesMs, onBatteryScreenOff); 593 } 594 } 595 } 596 } 597 } 598 599 @VisibleForTesting addCpuTimes(long[] timesA, long[] timesB)600 public static long[] addCpuTimes(long[] timesA, long[] timesB) { 601 if (timesA != null && timesB != null) { 602 for (int i = timesA.length - 1; i >= 0; --i) { 603 timesA[i] += timesB[i]; 604 } 605 return timesA; 606 } 607 return timesA == null ? (timesB == null ? null : timesB) : timesA; 608 } 609 610 @GuardedBy("this") initKernelSingleUidTimeReaderLocked()611 private boolean initKernelSingleUidTimeReaderLocked() { 612 if (mKernelSingleUidTimeReader == null) { 613 if (mPowerProfile == null) { 614 return false; 615 } 616 if (mCpuFreqs == null) { 617 mCpuFreqs = mCpuUidFreqTimeReader.readFreqs(mPowerProfile); 618 } 619 if (mCpuFreqs != null) { 620 mKernelSingleUidTimeReader = new KernelSingleUidTimeReader(mCpuFreqs.length); 621 } else { 622 mPerProcStateCpuTimesAvailable = mCpuUidFreqTimeReader.allUidTimesAvailable(); 623 return false; 624 } 625 } 626 mPerProcStateCpuTimesAvailable = mCpuUidFreqTimeReader.allUidTimesAvailable() 627 && mKernelSingleUidTimeReader.singleUidCpuTimesAvailable(); 628 return true; 629 } 630 631 public interface Clocks { 632 /** Elapsed Realtime, see SystemClock.elapsedRealtime() */ elapsedRealtime()633 long elapsedRealtime(); 634 635 /** Uptime, see SystemClock.uptimeMillis() */ uptimeMillis()636 long uptimeMillis(); 637 638 /** Wall-clock time as per System.currentTimeMillis() */ currentTimeMillis()639 long currentTimeMillis(); 640 } 641 642 public static class SystemClocks implements Clocks { 643 644 @Override elapsedRealtime()645 public long elapsedRealtime() { 646 return SystemClock.elapsedRealtime(); 647 } 648 649 @Override uptimeMillis()650 public long uptimeMillis() { 651 return SystemClock.uptimeMillis(); 652 } 653 654 @Override currentTimeMillis()655 public long currentTimeMillis() { 656 return System.currentTimeMillis(); 657 } 658 } 659 660 public interface ExternalStatsSync { 661 int UPDATE_CPU = 0x01; 662 int UPDATE_WIFI = 0x02; 663 int UPDATE_RADIO = 0x04; 664 int UPDATE_BT = 0x08; 665 int UPDATE_RPM = 0x10; 666 int UPDATE_DISPLAY = 0x20; 667 int UPDATE_ALL = 668 UPDATE_CPU | UPDATE_WIFI | UPDATE_RADIO | UPDATE_BT | UPDATE_RPM | UPDATE_DISPLAY; 669 670 @IntDef(flag = true, prefix = "UPDATE_", value = { 671 UPDATE_CPU, 672 UPDATE_WIFI, 673 UPDATE_RADIO, 674 UPDATE_BT, 675 UPDATE_RPM, 676 UPDATE_DISPLAY, 677 UPDATE_ALL, 678 }) 679 @Retention(RetentionPolicy.SOURCE) 680 public @interface ExternalUpdateFlag { 681 } 682 scheduleSync(String reason, int flags)683 Future<?> scheduleSync(String reason, int flags); scheduleCpuSyncDueToRemovedUid(int uid)684 Future<?> scheduleCpuSyncDueToRemovedUid(int uid); scheduleReadProcStateCpuTimes(boolean onBattery, boolean onBatteryScreenOff, long delayMillis)685 Future<?> scheduleReadProcStateCpuTimes(boolean onBattery, boolean onBatteryScreenOff, 686 long delayMillis); scheduleCopyFromAllUidsCpuTimes(boolean onBattery, boolean onBatteryScreenOff)687 Future<?> scheduleCopyFromAllUidsCpuTimes(boolean onBattery, boolean onBatteryScreenOff); scheduleCpuSyncDueToSettingChange()688 Future<?> scheduleCpuSyncDueToSettingChange(); 689 /** 690 * Schedule a sync because of a screen state change. 691 */ scheduleSyncDueToScreenStateChange(int flags, boolean onBattery, boolean onBatteryScreenOff, int screenState)692 Future<?> scheduleSyncDueToScreenStateChange(int flags, boolean onBattery, 693 boolean onBatteryScreenOff, int screenState); scheduleCpuSyncDueToWakelockChange(long delayMillis)694 Future<?> scheduleCpuSyncDueToWakelockChange(long delayMillis); cancelCpuSyncDueToWakelockChange()695 void cancelCpuSyncDueToWakelockChange(); scheduleSyncDueToBatteryLevelChange(long delayMillis)696 Future<?> scheduleSyncDueToBatteryLevelChange(long delayMillis); 697 } 698 699 public Handler mHandler; 700 private ExternalStatsSync mExternalSync = null; 701 @VisibleForTesting 702 protected UserInfoProvider mUserInfoProvider = null; 703 704 private BatteryCallback mCallback; 705 706 /** 707 * Mapping isolated uids to the actual owning app uid. 708 */ 709 final SparseIntArray mIsolatedUids = new SparseIntArray(); 710 711 /** 712 * The statistics we have collected organized by uids. 713 */ 714 final SparseArray<BatteryStatsImpl.Uid> mUidStats = new SparseArray<>(); 715 716 // A set of pools of currently active timers. When a timer is queried, we will divide the 717 // elapsed time by the number of active timers to arrive at that timer's share of the time. 718 // In order to do this, we must refresh each timer whenever the number of active timers 719 // changes. 720 @VisibleForTesting 721 @UnsupportedAppUsage 722 protected ArrayList<StopwatchTimer> mPartialTimers = new ArrayList<>(); 723 @UnsupportedAppUsage 724 final ArrayList<StopwatchTimer> mFullTimers = new ArrayList<>(); 725 @UnsupportedAppUsage 726 final ArrayList<StopwatchTimer> mWindowTimers = new ArrayList<>(); 727 final ArrayList<StopwatchTimer> mDrawTimers = new ArrayList<>(); 728 final SparseArray<ArrayList<StopwatchTimer>> mSensorTimers = new SparseArray<>(); 729 final ArrayList<StopwatchTimer> mWifiRunningTimers = new ArrayList<>(); 730 final ArrayList<StopwatchTimer> mFullWifiLockTimers = new ArrayList<>(); 731 final ArrayList<StopwatchTimer> mWifiMulticastTimers = new ArrayList<>(); 732 final ArrayList<StopwatchTimer> mWifiScanTimers = new ArrayList<>(); 733 final SparseArray<ArrayList<StopwatchTimer>> mWifiBatchedScanTimers = new SparseArray<>(); 734 final ArrayList<StopwatchTimer> mAudioTurnedOnTimers = new ArrayList<>(); 735 final ArrayList<StopwatchTimer> mVideoTurnedOnTimers = new ArrayList<>(); 736 final ArrayList<StopwatchTimer> mFlashlightTurnedOnTimers = new ArrayList<>(); 737 final ArrayList<StopwatchTimer> mCameraTurnedOnTimers = new ArrayList<>(); 738 final ArrayList<StopwatchTimer> mBluetoothScanOnTimers = new ArrayList<>(); 739 740 // Last partial timers we use for distributing CPU usage. 741 @VisibleForTesting 742 protected ArrayList<StopwatchTimer> mLastPartialTimers = new ArrayList<>(); 743 744 // These are the objects that will want to do something when the device 745 // is unplugged from power. 746 protected final TimeBase mOnBatteryTimeBase = new TimeBase(true); 747 748 // These are the objects that will want to do something when the device 749 // is unplugged from power *and* the screen is off or doze. 750 protected final TimeBase mOnBatteryScreenOffTimeBase = new TimeBase(true); 751 752 // Set to true when we want to distribute CPU across wakelocks for the next 753 // CPU update, even if we aren't currently running wake locks. 754 boolean mDistributeWakelockCpu; 755 756 private boolean mSystemReady; 757 boolean mShuttingDown; 758 759 final HistoryEventTracker mActiveEvents = new HistoryEventTracker(); 760 761 long mHistoryBaseTimeMs; 762 protected boolean mHaveBatteryLevel = false; 763 protected boolean mRecordingHistory = false; 764 int mNumHistoryItems; 765 766 final HashMap<HistoryTag, Integer> mHistoryTagPool = new HashMap<>(); 767 final Parcel mHistoryBuffer = Parcel.obtain(); 768 final HistoryItem mHistoryLastWritten = new HistoryItem(); 769 final HistoryItem mHistoryLastLastWritten = new HistoryItem(); 770 final HistoryItem mHistoryAddTmp = new HistoryItem(); 771 int mNextHistoryTagIdx = 0; 772 int mNumHistoryTagChars = 0; 773 int mHistoryBufferLastPos = -1; 774 int mActiveHistoryStates = 0xffffffff; 775 int mActiveHistoryStates2 = 0xffffffff; 776 long mLastHistoryElapsedRealtimeMs = 0; 777 long mTrackRunningHistoryElapsedRealtimeMs = 0; 778 long mTrackRunningHistoryUptimeMs = 0; 779 780 @NonNull 781 final BatteryStatsHistory mBatteryStatsHistory; 782 783 final HistoryItem mHistoryCur = new HistoryItem(); 784 785 HistoryItem mHistory; 786 HistoryItem mHistoryEnd; 787 HistoryItem mHistoryLastEnd; 788 HistoryItem mHistoryCache; 789 790 // Used by computeHistoryStepDetails 791 HistoryStepDetails mLastHistoryStepDetails = null; 792 byte mLastHistoryStepLevel = 0; 793 final HistoryStepDetails mCurHistoryStepDetails = new HistoryStepDetails(); 794 final HistoryStepDetails mReadHistoryStepDetails = new HistoryStepDetails(); 795 final HistoryStepDetails mTmpHistoryStepDetails = new HistoryStepDetails(); 796 797 /** 798 * Total time (in milliseconds) spent executing in user code. 799 */ 800 long mLastStepCpuUserTimeMs; 801 long mCurStepCpuUserTimeMs; 802 /** 803 * Total time (in milliseconds) spent executing in kernel code. 804 */ 805 long mLastStepCpuSystemTimeMs; 806 long mCurStepCpuSystemTimeMs; 807 /** 808 * Times from /proc/stat (but measured in milliseconds). 809 */ 810 long mLastStepStatUserTimeMs; 811 long mLastStepStatSystemTimeMs; 812 long mLastStepStatIOWaitTimeMs; 813 long mLastStepStatIrqTimeMs; 814 long mLastStepStatSoftIrqTimeMs; 815 long mLastStepStatIdleTimeMs; 816 long mCurStepStatUserTimeMs; 817 long mCurStepStatSystemTimeMs; 818 long mCurStepStatIOWaitTimeMs; 819 long mCurStepStatIrqTimeMs; 820 long mCurStepStatSoftIrqTimeMs; 821 long mCurStepStatIdleTimeMs; 822 823 private BatteryStatsHistoryIterator mBatteryStatsHistoryIterator; 824 private HistoryItem mHistoryIterator; 825 private boolean mReadOverflow; 826 827 int mStartCount; 828 829 /** 830 * Set to true when a reset occurs, informing us that the next time BatteryExternalStatsWorker 831 * gives us data, we mustn't process it since this data includes pre-reset-period data. 832 */ 833 @GuardedBy("this") 834 boolean mIgnoreNextExternalStats = false; 835 836 long mStartClockTimeMs; 837 String mStartPlatformVersion; 838 String mEndPlatformVersion; 839 840 long mUptimeUs; 841 long mUptimeStartUs; 842 long mRealtimeUs; 843 long mRealtimeStartUs; 844 845 int mWakeLockNesting; 846 boolean mWakeLockImportant; 847 public boolean mRecordAllHistory; 848 boolean mNoAutoReset; 849 850 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) 851 protected int mScreenState = Display.STATE_UNKNOWN; 852 StopwatchTimer mScreenOnTimer; 853 StopwatchTimer mScreenDozeTimer; 854 855 int mScreenBrightnessBin = -1; 856 final StopwatchTimer[] mScreenBrightnessTimer = 857 new StopwatchTimer[NUM_SCREEN_BRIGHTNESS_BINS]; 858 859 boolean mPretendScreenOff; 860 861 boolean mInteractive; 862 StopwatchTimer mInteractiveTimer; 863 864 boolean mPowerSaveModeEnabled; 865 StopwatchTimer mPowerSaveModeEnabledTimer; 866 867 boolean mDeviceIdling; 868 StopwatchTimer mDeviceIdlingTimer; 869 870 boolean mDeviceLightIdling; 871 StopwatchTimer mDeviceLightIdlingTimer; 872 873 int mDeviceIdleMode; 874 long mLastIdleTimeStartMs; 875 long mLongestLightIdleTimeMs; 876 long mLongestFullIdleTimeMs; 877 StopwatchTimer mDeviceIdleModeLightTimer; 878 StopwatchTimer mDeviceIdleModeFullTimer; 879 880 boolean mPhoneOn; 881 StopwatchTimer mPhoneOnTimer; 882 883 int mAudioOnNesting; 884 StopwatchTimer mAudioOnTimer; 885 886 int mVideoOnNesting; 887 StopwatchTimer mVideoOnTimer; 888 889 int mFlashlightOnNesting; 890 StopwatchTimer mFlashlightOnTimer; 891 892 int mCameraOnNesting; 893 StopwatchTimer mCameraOnTimer; 894 895 private static final int USB_DATA_UNKNOWN = 0; 896 private static final int USB_DATA_DISCONNECTED = 1; 897 private static final int USB_DATA_CONNECTED = 2; 898 int mUsbDataState = USB_DATA_UNKNOWN; 899 900 int mGpsSignalQualityBin = -1; 901 final StopwatchTimer[] mGpsSignalQualityTimer = 902 new StopwatchTimer[GnssSignalQuality.NUM_GNSS_SIGNAL_QUALITY_LEVELS]; 903 904 int mPhoneSignalStrengthBin = -1; 905 int mPhoneSignalStrengthBinRaw = -1; 906 final StopwatchTimer[] mPhoneSignalStrengthsTimer = 907 new StopwatchTimer[CellSignalStrength.getNumSignalStrengthLevels()]; 908 909 StopwatchTimer mPhoneSignalScanningTimer; 910 911 int mPhoneDataConnectionType = -1; 912 final StopwatchTimer[] mPhoneDataConnectionsTimer = 913 new StopwatchTimer[NUM_DATA_CONNECTION_TYPES]; 914 915 final LongSamplingCounter[] mNetworkByteActivityCounters = 916 new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES]; 917 918 final LongSamplingCounter[] mNetworkPacketActivityCounters = 919 new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES]; 920 921 /** 922 * The WiFi Overall wakelock timer 923 * This timer tracks the actual aggregate time for which MC wakelocks are enabled 924 * since addition of per UID timers would not result in an accurate value due to overlapp of 925 * per uid wakelock timers 926 */ 927 StopwatchTimer mWifiMulticastWakelockTimer; 928 929 /** 930 * The WiFi controller activity (time in tx, rx, idle, and power consumed) for the device. 931 */ 932 ControllerActivityCounterImpl mWifiActivity; 933 934 /** 935 * The Bluetooth controller activity (time in tx, rx, idle, and power consumed) for the device. 936 */ 937 ControllerActivityCounterImpl mBluetoothActivity; 938 939 /** 940 * The Modem controller activity (time in tx, rx, idle, and power consumed) for the device. 941 */ 942 ControllerActivityCounterImpl mModemActivity; 943 944 /** 945 * Whether the device supports WiFi controller energy reporting. This is set to true on 946 * the first WiFi energy report. See {@link #mWifiActivity}. 947 */ 948 boolean mHasWifiReporting = false; 949 950 /** 951 * Whether the device supports Bluetooth controller energy reporting. This is set to true on 952 * the first Bluetooth energy report. See {@link #mBluetoothActivity}. 953 */ 954 boolean mHasBluetoothReporting = false; 955 956 /** 957 * Whether the device supports Modem controller energy reporting. This is set to true on 958 * the first Modem energy report. See {@link #mModemActivity}. 959 */ 960 boolean mHasModemReporting = false; 961 962 boolean mWifiOn; 963 StopwatchTimer mWifiOnTimer; 964 965 boolean mGlobalWifiRunning; 966 StopwatchTimer mGlobalWifiRunningTimer; 967 968 int mWifiState = -1; 969 final StopwatchTimer[] mWifiStateTimer = new StopwatchTimer[NUM_WIFI_STATES]; 970 971 int mWifiSupplState = -1; 972 final StopwatchTimer[] mWifiSupplStateTimer = new StopwatchTimer[NUM_WIFI_SUPPL_STATES]; 973 974 int mWifiSignalStrengthBin = -1; 975 final StopwatchTimer[] mWifiSignalStrengthsTimer = 976 new StopwatchTimer[NUM_WIFI_SIGNAL_STRENGTH_BINS]; 977 978 StopwatchTimer mWifiActiveTimer; 979 980 int mBluetoothScanNesting; 981 StopwatchTimer mBluetoothScanTimer; 982 983 int mMobileRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW; 984 long mMobileRadioActiveStartTimeMs; 985 StopwatchTimer mMobileRadioActiveTimer; 986 StopwatchTimer mMobileRadioActivePerAppTimer; 987 LongSamplingCounter mMobileRadioActiveAdjustedTime; 988 LongSamplingCounter mMobileRadioActiveUnknownTime; 989 LongSamplingCounter mMobileRadioActiveUnknownCount; 990 991 int mWifiRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW; 992 993 /** 994 * Accumulated global (generally, device-wide total) charge consumption of various consumers 995 * while on battery. 996 * Its '<b>custom</b> power buckets' correspond to the 997 * {@link android.hardware.power.stats.EnergyConsumer.ordinal}s of (custom) energy consumer 998 * type {@link android.hardware.power.stats.EnergyConsumerType#OTHER}). 999 * 1000 * If energy consumer data is completely unavailable this will be null. 1001 */ 1002 @GuardedBy("this") 1003 @VisibleForTesting 1004 protected @Nullable MeasuredEnergyStats mGlobalMeasuredEnergyStats; 1005 /** Last known screen state. Needed for apportioning display energy. */ 1006 int mScreenStateAtLastEnergyMeasurement = Display.STATE_UNKNOWN; 1007 /** Bluetooth Power calculator for attributing measured bluetooth charge consumption to uids */ 1008 @Nullable BluetoothPowerCalculator mBluetoothPowerCalculator = null; 1009 /** Cpu Power calculator for attributing measured cpu charge consumption to uids */ 1010 @Nullable CpuPowerCalculator mCpuPowerCalculator = null; 1011 /** Mobile Radio Power calculator for attributing measured radio charge consumption to uids */ 1012 @Nullable 1013 MobileRadioPowerCalculator mMobileRadioPowerCalculator = null; 1014 /** Wifi Power calculator for attributing measured wifi charge consumption to uids */ 1015 @Nullable WifiPowerCalculator mWifiPowerCalculator = null; 1016 1017 /** 1018 * These provide time bases that discount the time the device is plugged 1019 * in to power. 1020 */ 1021 boolean mOnBattery; 1022 @VisibleForTesting 1023 protected boolean mOnBatteryInternal; 1024 1025 /** 1026 * External reporting of whether the device is actually charging. 1027 */ 1028 boolean mCharging = true; 1029 int mLastChargingStateLevel; 1030 1031 /* 1032 * These keep track of battery levels (1-100) at the last plug event and the last unplug event. 1033 */ 1034 int mDischargeStartLevel; 1035 int mDischargeUnplugLevel; 1036 int mDischargePlugLevel; 1037 int mDischargeCurrentLevel; 1038 int mCurrentBatteryLevel; 1039 int mLowDischargeAmountSinceCharge; 1040 int mHighDischargeAmountSinceCharge; 1041 int mDischargeScreenOnUnplugLevel; 1042 int mDischargeScreenOffUnplugLevel; 1043 int mDischargeScreenDozeUnplugLevel; 1044 int mDischargeAmountScreenOn; 1045 int mDischargeAmountScreenOnSinceCharge; 1046 int mDischargeAmountScreenOff; 1047 int mDischargeAmountScreenOffSinceCharge; 1048 int mDischargeAmountScreenDoze; 1049 int mDischargeAmountScreenDozeSinceCharge; 1050 1051 private LongSamplingCounter mDischargeScreenOffCounter; 1052 private LongSamplingCounter mDischargeScreenDozeCounter; 1053 private LongSamplingCounter mDischargeCounter; 1054 private LongSamplingCounter mDischargeLightDozeCounter; 1055 private LongSamplingCounter mDischargeDeepDozeCounter; 1056 1057 static final int MAX_LEVEL_STEPS = 200; 1058 1059 int mInitStepMode = 0; 1060 int mCurStepMode = 0; 1061 int mModStepMode = 0; 1062 1063 int mLastDischargeStepLevel; 1064 int mMinDischargeStepLevel; 1065 final LevelStepTracker mDischargeStepTracker = new LevelStepTracker(MAX_LEVEL_STEPS); 1066 final LevelStepTracker mDailyDischargeStepTracker = new LevelStepTracker(MAX_LEVEL_STEPS*2); 1067 ArrayList<PackageChange> mDailyPackageChanges; 1068 1069 int mLastChargeStepLevel; 1070 int mMaxChargeStepLevel; 1071 final LevelStepTracker mChargeStepTracker = new LevelStepTracker(MAX_LEVEL_STEPS); 1072 final LevelStepTracker mDailyChargeStepTracker = new LevelStepTracker(MAX_LEVEL_STEPS*2); 1073 1074 static final int MAX_DAILY_ITEMS = 10; 1075 1076 long mDailyStartTimeMs = 0; 1077 long mNextMinDailyDeadlineMs = 0; 1078 long mNextMaxDailyDeadlineMs = 0; 1079 1080 final ArrayList<DailyItem> mDailyItems = new ArrayList<>(); 1081 1082 long mLastWriteTimeMs = 0; // Milliseconds 1083 1084 private int mPhoneServiceState = -1; 1085 private int mPhoneServiceStateRaw = -1; 1086 private int mPhoneSimStateRaw = -1; 1087 1088 private int mNumConnectivityChange; 1089 1090 private int mBatteryVoltageMv = -1; 1091 private int mEstimatedBatteryCapacityMah = -1; 1092 1093 private int mLastLearnedBatteryCapacityUah = -1; 1094 private int mMinLearnedBatteryCapacityUah = -1; 1095 private int mMaxLearnedBatteryCapacityUah = -1; 1096 1097 private long mBatteryTimeToFullSeconds = -1; 1098 1099 private long[] mCpuFreqs; 1100 1101 /** 1102 * Times spent by the system server threads handling incoming binder requests. 1103 */ 1104 private LongSamplingCounterArray mBinderThreadCpuTimesUs; 1105 1106 @VisibleForTesting 1107 protected PowerProfile mPowerProfile; 1108 1109 @VisibleForTesting 1110 @GuardedBy("this") 1111 protected final Constants mConstants; 1112 1113 /* 1114 * Holds a SamplingTimer associated with each Resource Power Manager state and voter, 1115 * recording their times when on-battery (regardless of screen state). 1116 */ 1117 private final HashMap<String, SamplingTimer> mRpmStats = new HashMap<>(); 1118 /** Times for each Resource Power Manager state and voter when screen-off and on-battery. */ 1119 private final HashMap<String, SamplingTimer> mScreenOffRpmStats = new HashMap<>(); 1120 1121 @Override getRpmStats()1122 public Map<String, ? extends Timer> getRpmStats() { 1123 return mRpmStats; 1124 } 1125 1126 // TODO: Note: screenOffRpmStats has been disabled via SCREEN_OFF_RPM_STATS_ENABLED. 1127 @Override getScreenOffRpmStats()1128 public Map<String, ? extends Timer> getScreenOffRpmStats() { 1129 return mScreenOffRpmStats; 1130 } 1131 1132 /* 1133 * Holds a SamplingTimer associated with each kernel wakelock name being tracked. 1134 */ 1135 private final HashMap<String, SamplingTimer> mKernelWakelockStats = new HashMap<>(); 1136 1137 @UnsupportedAppUsage getKernelWakelockStats()1138 public Map<String, ? extends Timer> getKernelWakelockStats() { 1139 return mKernelWakelockStats; 1140 } 1141 1142 String mLastWakeupReason = null; 1143 long mLastWakeupUptimeMs = 0; 1144 private final HashMap<String, SamplingTimer> mWakeupReasonStats = new HashMap<>(); 1145 getWakeupReasonStats()1146 public Map<String, ? extends Timer> getWakeupReasonStats() { 1147 return mWakeupReasonStats; 1148 } 1149 1150 @Override getUahDischarge(int which)1151 public long getUahDischarge(int which) { 1152 return mDischargeCounter.getCountLocked(which); 1153 } 1154 1155 @Override getUahDischargeScreenOff(int which)1156 public long getUahDischargeScreenOff(int which) { 1157 return mDischargeScreenOffCounter.getCountLocked(which); 1158 } 1159 1160 @Override getUahDischargeScreenDoze(int which)1161 public long getUahDischargeScreenDoze(int which) { 1162 return mDischargeScreenDozeCounter.getCountLocked(which); 1163 } 1164 1165 @Override getUahDischargeLightDoze(int which)1166 public long getUahDischargeLightDoze(int which) { 1167 return mDischargeLightDozeCounter.getCountLocked(which); 1168 } 1169 1170 @Override getUahDischargeDeepDoze(int which)1171 public long getUahDischargeDeepDoze(int which) { 1172 return mDischargeDeepDozeCounter.getCountLocked(which); 1173 } 1174 1175 @Override getEstimatedBatteryCapacity()1176 public int getEstimatedBatteryCapacity() { 1177 return mEstimatedBatteryCapacityMah; 1178 } 1179 1180 @Override getLearnedBatteryCapacity()1181 public int getLearnedBatteryCapacity() { 1182 return mLastLearnedBatteryCapacityUah; 1183 } 1184 1185 @Override getMinLearnedBatteryCapacity()1186 public int getMinLearnedBatteryCapacity() { 1187 return mMinLearnedBatteryCapacityUah; 1188 } 1189 1190 @Override getMaxLearnedBatteryCapacity()1191 public int getMaxLearnedBatteryCapacity() { 1192 return mMaxLearnedBatteryCapacityUah; 1193 } 1194 BatteryStatsImpl()1195 public BatteryStatsImpl() { 1196 this(new SystemClocks()); 1197 } 1198 BatteryStatsImpl(Clocks clocks)1199 public BatteryStatsImpl(Clocks clocks) { 1200 init(clocks); 1201 mStartClockTimeMs = clocks.currentTimeMillis(); 1202 mStatsFile = null; 1203 mCheckinFile = null; 1204 mDailyFile = null; 1205 mBatteryStatsHistory = new BatteryStatsHistory(mHistoryBuffer); 1206 mHandler = null; 1207 mPlatformIdleStateCallback = null; 1208 mMeasuredEnergyRetriever = null; 1209 mUserInfoProvider = null; 1210 mConstants = new Constants(mHandler); 1211 clearHistoryLocked(); 1212 } 1213 init(Clocks clocks)1214 private void init(Clocks clocks) { 1215 mClocks = clocks; 1216 } 1217 1218 /** 1219 * TimeBase observer. 1220 */ 1221 public interface TimeBaseObs { onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)1222 void onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs); onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)1223 void onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs); 1224 1225 /** 1226 * Reset the observer's state, returns true if the timer/counter is inactive 1227 * so it can be destroyed. 1228 * @param detachIfReset detach if true, no-op if false. 1229 * @return Returns true if the timer/counter is inactive and can be destroyed. 1230 */ reset(boolean detachIfReset)1231 default boolean reset(boolean detachIfReset) { 1232 return reset(detachIfReset, SystemClock.elapsedRealtime() * 1000); 1233 } 1234 1235 /** 1236 * @see #reset(boolean) 1237 * @param detachIfReset detach if true, no-op if false. 1238 * @param elapsedRealtimeUs the timestamp when this reset is actually reequested 1239 * @return Returns true if the timer/counter is inactive and can be destroyed. 1240 */ reset(boolean detachIfReset, long elapsedRealtimeUs)1241 boolean reset(boolean detachIfReset, long elapsedRealtimeUs); 1242 1243 /** 1244 * Detach the observer from TimeBase. 1245 */ detach()1246 void detach(); 1247 } 1248 1249 // methods are protected not private to be VisibleForTesting 1250 public static class TimeBase { 1251 protected final Collection<TimeBaseObs> mObservers; 1252 1253 // All below time metrics are in microseconds. 1254 protected long mUptimeUs; 1255 protected long mRealtimeUs; 1256 1257 protected boolean mRunning; 1258 1259 protected long mPastUptimeUs; 1260 protected long mUptimeStartUs; 1261 protected long mPastRealtimeUs; 1262 protected long mRealtimeStartUs; 1263 protected long mUnpluggedUptimeUs; 1264 protected long mUnpluggedRealtimeUs; 1265 dump(PrintWriter pw, String prefix)1266 public void dump(PrintWriter pw, String prefix) { 1267 StringBuilder sb = new StringBuilder(128); 1268 pw.print(prefix); pw.print("mRunning="); pw.println(mRunning); 1269 sb.setLength(0); 1270 sb.append(prefix); 1271 sb.append("mUptime="); 1272 formatTimeMs(sb, mUptimeUs / 1000); 1273 pw.println(sb.toString()); 1274 sb.setLength(0); 1275 sb.append(prefix); 1276 sb.append("mRealtime="); 1277 formatTimeMs(sb, mRealtimeUs / 1000); 1278 pw.println(sb.toString()); 1279 sb.setLength(0); 1280 sb.append(prefix); 1281 sb.append("mPastUptime="); 1282 formatTimeMs(sb, mPastUptimeUs / 1000); sb.append("mUptimeStart="); 1283 formatTimeMs(sb, mUptimeStartUs / 1000); 1284 sb.append("mUnpluggedUptime="); formatTimeMs(sb, mUnpluggedUptimeUs / 1000); 1285 pw.println(sb.toString()); 1286 sb.setLength(0); 1287 sb.append(prefix); 1288 sb.append("mPastRealtime="); 1289 formatTimeMs(sb, mPastRealtimeUs / 1000); sb.append("mRealtimeStart="); 1290 formatTimeMs(sb, mRealtimeStartUs / 1000); 1291 sb.append("mUnpluggedRealtime="); formatTimeMs(sb, mUnpluggedRealtimeUs / 1000); 1292 pw.println(sb.toString()); 1293 } 1294 /** 1295 * The mObservers of TimeBase in BatteryStatsImpl object can contain up to 20k entries. 1296 * The mObservers of TimeBase in BatteryStatsImpl.Uid object only contains a few or tens of 1297 * entries. 1298 * mObservers must have good performance on add(), remove(), also be memory efficient. 1299 * This is why we provide isLongList parameter for long and short list user cases. 1300 * @param isLongList If true, use HashSet for mObservers list. 1301 * If false, use ArrayList for mObservers list. 1302 */ TimeBase(boolean isLongList)1303 public TimeBase(boolean isLongList) { 1304 mObservers = isLongList ? new HashSet<>() : new ArrayList<>(); 1305 } 1306 TimeBase()1307 public TimeBase() { 1308 this(false); 1309 } 1310 add(TimeBaseObs observer)1311 public void add(TimeBaseObs observer) { 1312 mObservers.add(observer); 1313 } 1314 remove(TimeBaseObs observer)1315 public void remove(TimeBaseObs observer) { 1316 mObservers.remove(observer); 1317 } 1318 hasObserver(TimeBaseObs observer)1319 public boolean hasObserver(TimeBaseObs observer) { 1320 return mObservers.contains(observer); 1321 } 1322 init(long uptimeUs, long elapsedRealtimeUs)1323 public void init(long uptimeUs, long elapsedRealtimeUs) { 1324 mRealtimeUs = 0; 1325 mUptimeUs = 0; 1326 mPastUptimeUs = 0; 1327 mPastRealtimeUs = 0; 1328 mUptimeStartUs = uptimeUs; 1329 mRealtimeStartUs = elapsedRealtimeUs; 1330 mUnpluggedUptimeUs = getUptime(mUptimeStartUs); 1331 mUnpluggedRealtimeUs = getRealtime(mRealtimeStartUs); 1332 } 1333 reset(long uptimeUs, long elapsedRealtimeUs)1334 public void reset(long uptimeUs, long elapsedRealtimeUs) { 1335 if (!mRunning) { 1336 mPastUptimeUs = 0; 1337 mPastRealtimeUs = 0; 1338 } else { 1339 mUptimeStartUs = uptimeUs; 1340 mRealtimeStartUs = elapsedRealtimeUs; 1341 // TODO: Since mUptimeStartUs was just reset and we are running, getUptime will 1342 // just return mPastUptimeUs. Also, are we sure we don't want to reset that? 1343 mUnpluggedUptimeUs = getUptime(uptimeUs); 1344 // TODO: likewise. 1345 mUnpluggedRealtimeUs = getRealtime(elapsedRealtimeUs); 1346 } 1347 } 1348 computeUptime(long curTimeUs, int which)1349 public long computeUptime(long curTimeUs, int which) { 1350 return mUptimeUs + getUptime(curTimeUs); 1351 } 1352 computeRealtime(long curTimeUs, int which)1353 public long computeRealtime(long curTimeUs, int which) { 1354 return mRealtimeUs + getRealtime(curTimeUs); 1355 } 1356 getUptime(long curTimeUs)1357 public long getUptime(long curTimeUs) { 1358 long time = mPastUptimeUs; 1359 if (mRunning) { 1360 time += curTimeUs - mUptimeStartUs; 1361 } 1362 return time; 1363 } 1364 getRealtime(long curTimeUs)1365 public long getRealtime(long curTimeUs) { 1366 long time = mPastRealtimeUs; 1367 if (mRunning) { 1368 time += curTimeUs - mRealtimeStartUs; 1369 } 1370 return time; 1371 } 1372 getUptimeStart()1373 public long getUptimeStart() { 1374 return mUptimeStartUs; 1375 } 1376 getRealtimeStart()1377 public long getRealtimeStart() { 1378 return mRealtimeStartUs; 1379 } 1380 isRunning()1381 public boolean isRunning() { 1382 return mRunning; 1383 } 1384 setRunning(boolean running, long uptimeUs, long elapsedRealtimeUs)1385 public boolean setRunning(boolean running, long uptimeUs, long elapsedRealtimeUs) { 1386 if (mRunning != running) { 1387 mRunning = running; 1388 if (running) { 1389 mUptimeStartUs = uptimeUs; 1390 mRealtimeStartUs = elapsedRealtimeUs; 1391 long batteryUptimeUs = mUnpluggedUptimeUs = getUptime(uptimeUs); 1392 long batteryRealtimeUs = mUnpluggedRealtimeUs = getRealtime(elapsedRealtimeUs); 1393 // Normally we do not use Iterator in framework code to avoid alloc/dealloc 1394 // Iterator object, here is an exception because mObservers' type is Collection 1395 // instead of list. 1396 final Iterator<TimeBaseObs> iter = mObservers.iterator(); 1397 while (iter.hasNext()) { 1398 iter.next().onTimeStarted( 1399 elapsedRealtimeUs, batteryUptimeUs, batteryRealtimeUs); 1400 } 1401 } else { 1402 mPastUptimeUs += uptimeUs - mUptimeStartUs; 1403 mPastRealtimeUs += elapsedRealtimeUs - mRealtimeStartUs; 1404 long batteryUptimeUs = getUptime(uptimeUs); 1405 long batteryRealtimeUs = getRealtime(elapsedRealtimeUs); 1406 // Normally we do not use Iterator in framework code to avoid alloc/dealloc 1407 // Iterator object, here is an exception because mObservers' type is Collection 1408 // instead of list. 1409 final Iterator<TimeBaseObs> iter = mObservers.iterator(); 1410 while (iter.hasNext()) { 1411 iter.next().onTimeStopped( 1412 elapsedRealtimeUs, batteryUptimeUs, batteryRealtimeUs); 1413 } 1414 } 1415 return true; 1416 } 1417 return false; 1418 } 1419 readSummaryFromParcel(Parcel in)1420 public void readSummaryFromParcel(Parcel in) { 1421 mUptimeUs = in.readLong(); 1422 mRealtimeUs = in.readLong(); 1423 } 1424 writeSummaryToParcel(Parcel out, long uptimeUs, long elapsedRealtimeUs)1425 public void writeSummaryToParcel(Parcel out, long uptimeUs, long elapsedRealtimeUs) { 1426 out.writeLong(computeUptime(uptimeUs, STATS_SINCE_CHARGED)); 1427 out.writeLong(computeRealtime(elapsedRealtimeUs, STATS_SINCE_CHARGED)); 1428 } 1429 readFromParcel(Parcel in)1430 public void readFromParcel(Parcel in) { 1431 mRunning = false; 1432 mUptimeUs = in.readLong(); 1433 mPastUptimeUs = in.readLong(); 1434 mUptimeStartUs = in.readLong(); 1435 mRealtimeUs = in.readLong(); 1436 mPastRealtimeUs = in.readLong(); 1437 mRealtimeStartUs = in.readLong(); 1438 mUnpluggedUptimeUs = in.readLong(); 1439 mUnpluggedRealtimeUs = in.readLong(); 1440 } 1441 writeToParcel(Parcel out, long uptimeUs, long elapsedRealtimeUs)1442 public void writeToParcel(Parcel out, long uptimeUs, long elapsedRealtimeUs) { 1443 final long runningUptime = getUptime(uptimeUs); 1444 final long runningRealtime = getRealtime(elapsedRealtimeUs); 1445 out.writeLong(mUptimeUs); 1446 out.writeLong(runningUptime); 1447 out.writeLong(mUptimeStartUs); 1448 out.writeLong(mRealtimeUs); 1449 out.writeLong(runningRealtime); 1450 out.writeLong(mRealtimeStartUs); 1451 out.writeLong(mUnpluggedUptimeUs); 1452 out.writeLong(mUnpluggedRealtimeUs); 1453 } 1454 } 1455 1456 /** 1457 * State for keeping track of counting information. 1458 */ 1459 public static class Counter extends BatteryStats.Counter implements TimeBaseObs { 1460 @UnsupportedAppUsage 1461 final AtomicInteger mCount = new AtomicInteger(); 1462 final TimeBase mTimeBase; 1463 Counter(TimeBase timeBase, Parcel in)1464 public Counter(TimeBase timeBase, Parcel in) { 1465 mTimeBase = timeBase; 1466 mCount.set(in.readInt()); 1467 timeBase.add(this); 1468 } 1469 Counter(TimeBase timeBase)1470 public Counter(TimeBase timeBase) { 1471 mTimeBase = timeBase; 1472 timeBase.add(this); 1473 } 1474 writeToParcel(Parcel out)1475 public void writeToParcel(Parcel out) { 1476 out.writeInt(mCount.get()); 1477 } 1478 1479 @Override onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)1480 public void onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { 1481 } 1482 1483 @Override onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)1484 public void onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { 1485 } 1486 1487 /** 1488 * Writes a possibly null Counter to a Parcel. 1489 * 1490 * @param out the Parcel to be written to. 1491 * @param counter a Counter, or null. 1492 */ writeCounterToParcel(Parcel out, @Nullable Counter counter)1493 public static void writeCounterToParcel(Parcel out, @Nullable Counter counter) { 1494 if (counter == null) { 1495 out.writeInt(0); // indicates null 1496 return; 1497 } 1498 out.writeInt(1); // indicates non-null 1499 1500 counter.writeToParcel(out); 1501 } 1502 1503 /** 1504 * Reads a Counter that was written using {@link #writeCounterToParcel(Parcel, Counter)}. 1505 * @param timeBase the timebase to assign to the Counter 1506 * @param in the parcel to read from 1507 * @return the Counter or null. 1508 */ 1509 @Nullable readCounterFromParcel(TimeBase timeBase, Parcel in)1510 public static Counter readCounterFromParcel(TimeBase timeBase, Parcel in) { 1511 if (in.readInt() == 0) { 1512 return null; 1513 } 1514 return new Counter(timeBase, in); 1515 } 1516 1517 @Override getCountLocked(int which)1518 public int getCountLocked(int which) { 1519 return mCount.get(); 1520 } 1521 logState(Printer pw, String prefix)1522 public void logState(Printer pw, String prefix) { 1523 pw.println(prefix + "mCount=" + mCount.get()); 1524 } 1525 1526 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) stepAtomic()1527 public void stepAtomic() { 1528 if (mTimeBase.isRunning()) { 1529 mCount.incrementAndGet(); 1530 } 1531 } 1532 addAtomic(int delta)1533 void addAtomic(int delta) { 1534 if (mTimeBase.isRunning()) { 1535 mCount.addAndGet(delta); 1536 } 1537 } 1538 1539 /** 1540 * Clear state of this counter. 1541 */ 1542 @Override reset(boolean detachIfReset, long elapsedRealtimeUs )1543 public boolean reset(boolean detachIfReset, long elapsedRealtimeUs /* unused */) { 1544 mCount.set(0); 1545 if (detachIfReset) { 1546 detach(); 1547 } 1548 return true; 1549 } 1550 1551 @Override detach()1552 public void detach() { 1553 mTimeBase.remove(this); 1554 } 1555 1556 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) writeSummaryFromParcelLocked(Parcel out)1557 public void writeSummaryFromParcelLocked(Parcel out) { 1558 out.writeInt(mCount.get()); 1559 } 1560 1561 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) readSummaryFromParcelLocked(Parcel in)1562 public void readSummaryFromParcelLocked(Parcel in) { 1563 mCount.set(in.readInt()); 1564 } 1565 } 1566 1567 @VisibleForTesting 1568 public static class LongSamplingCounterArray extends LongCounterArray implements TimeBaseObs { 1569 final TimeBase mTimeBase; 1570 public long[] mCounts; 1571 LongSamplingCounterArray(TimeBase timeBase, Parcel in)1572 private LongSamplingCounterArray(TimeBase timeBase, Parcel in) { 1573 mTimeBase = timeBase; 1574 mCounts = in.createLongArray(); 1575 timeBase.add(this); 1576 } 1577 LongSamplingCounterArray(TimeBase timeBase)1578 public LongSamplingCounterArray(TimeBase timeBase) { 1579 mTimeBase = timeBase; 1580 timeBase.add(this); 1581 } 1582 writeToParcel(Parcel out)1583 private void writeToParcel(Parcel out) { 1584 out.writeLongArray(mCounts); 1585 } 1586 1587 @Override onTimeStarted(long elapsedRealTimeUs, long baseUptimeUs, long baseRealtimeUs)1588 public void onTimeStarted(long elapsedRealTimeUs, long baseUptimeUs, long baseRealtimeUs) { 1589 } 1590 1591 @Override onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)1592 public void onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { 1593 } 1594 1595 @Override getCountsLocked(int which)1596 public long[] getCountsLocked(int which) { 1597 return mCounts == null ? null : Arrays.copyOf(mCounts, mCounts.length); 1598 } 1599 1600 @Override logState(Printer pw, String prefix)1601 public void logState(Printer pw, String prefix) { 1602 pw.println(prefix + "mCounts=" + Arrays.toString(mCounts)); 1603 } 1604 addCountLocked(long[] counts)1605 public void addCountLocked(long[] counts) { 1606 addCountLocked(counts, mTimeBase.isRunning()); 1607 } 1608 addCountLocked(long[] counts, boolean isRunning)1609 public void addCountLocked(long[] counts, boolean isRunning) { 1610 if (counts == null) { 1611 return; 1612 } 1613 if (isRunning) { 1614 if (mCounts == null) { 1615 mCounts = new long[counts.length]; 1616 } 1617 for (int i = 0; i < counts.length; ++i) { 1618 mCounts[i] += counts[i]; 1619 } 1620 } 1621 } 1622 getSize()1623 public int getSize() { 1624 return mCounts == null ? 0 : mCounts.length; 1625 } 1626 1627 /** 1628 * Clear state of this counter. 1629 */ 1630 @Override reset(boolean detachIfReset, long elapsedRealtimeUs )1631 public boolean reset(boolean detachIfReset, long elapsedRealtimeUs /* unused */) { 1632 if (mCounts != null) { 1633 Arrays.fill(mCounts, 0); 1634 } 1635 if (detachIfReset) { 1636 detach(); 1637 } 1638 return true; 1639 } 1640 1641 @Override detach()1642 public void detach() { 1643 mTimeBase.remove(this); 1644 } 1645 writeSummaryToParcelLocked(Parcel out)1646 private void writeSummaryToParcelLocked(Parcel out) { 1647 out.writeLongArray(mCounts); 1648 } 1649 readSummaryFromParcelLocked(Parcel in)1650 private void readSummaryFromParcelLocked(Parcel in) { 1651 mCounts = in.createLongArray(); 1652 } 1653 writeToParcel(Parcel out, LongSamplingCounterArray counterArray)1654 public static void writeToParcel(Parcel out, LongSamplingCounterArray counterArray) { 1655 if (counterArray != null) { 1656 out.writeInt(1); 1657 counterArray.writeToParcel(out); 1658 } else { 1659 out.writeInt(0); 1660 } 1661 } 1662 readFromParcel(Parcel in, TimeBase timeBase)1663 public static LongSamplingCounterArray readFromParcel(Parcel in, TimeBase timeBase) { 1664 if (in.readInt() != 0) { 1665 return new LongSamplingCounterArray(timeBase, in); 1666 } else { 1667 return null; 1668 } 1669 } 1670 writeSummaryToParcelLocked(Parcel out, LongSamplingCounterArray counterArray)1671 public static void writeSummaryToParcelLocked(Parcel out, 1672 LongSamplingCounterArray counterArray) { 1673 if (counterArray != null) { 1674 out.writeInt(1); 1675 counterArray.writeSummaryToParcelLocked(out); 1676 } else { 1677 out.writeInt(0); 1678 } 1679 } 1680 readSummaryFromParcelLocked(Parcel in, TimeBase timeBase)1681 public static LongSamplingCounterArray readSummaryFromParcelLocked(Parcel in, 1682 TimeBase timeBase) { 1683 if (in.readInt() != 0) { 1684 final LongSamplingCounterArray counterArray 1685 = new LongSamplingCounterArray(timeBase); 1686 counterArray.readSummaryFromParcelLocked(in); 1687 return counterArray; 1688 } else { 1689 return null; 1690 } 1691 } 1692 } 1693 1694 @VisibleForTesting 1695 public static class LongSamplingCounter extends LongCounter implements TimeBaseObs { 1696 final TimeBase mTimeBase; 1697 private long mCount; 1698 LongSamplingCounter(TimeBase timeBase, Parcel in)1699 public LongSamplingCounter(TimeBase timeBase, Parcel in) { 1700 mTimeBase = timeBase; 1701 mCount = in.readLong(); 1702 timeBase.add(this); 1703 } 1704 LongSamplingCounter(TimeBase timeBase)1705 public LongSamplingCounter(TimeBase timeBase) { 1706 mTimeBase = timeBase; 1707 timeBase.add(this); 1708 } 1709 writeToParcel(Parcel out)1710 public void writeToParcel(Parcel out) { 1711 out.writeLong(mCount); 1712 } 1713 1714 @Override onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)1715 public void onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { 1716 } 1717 1718 @Override onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)1719 public void onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { 1720 } 1721 getCountLocked(int which)1722 public long getCountLocked(int which) { 1723 return mCount; 1724 } 1725 1726 @Override logState(Printer pw, String prefix)1727 public void logState(Printer pw, String prefix) { 1728 pw.println(prefix + "mCount=" + mCount); 1729 } 1730 addCountLocked(long count)1731 public void addCountLocked(long count) { 1732 addCountLocked(count, mTimeBase.isRunning()); 1733 } 1734 addCountLocked(long count, boolean isRunning)1735 public void addCountLocked(long count, boolean isRunning) { 1736 if (isRunning) { 1737 mCount += count; 1738 } 1739 } 1740 1741 /** 1742 * Clear state of this counter. 1743 */ 1744 @Override reset(boolean detachIfReset, long elapsedRealtimeUs )1745 public boolean reset(boolean detachIfReset, long elapsedRealtimeUs /* unused */) { 1746 mCount = 0; 1747 if (detachIfReset) { 1748 detach(); 1749 } 1750 return true; 1751 } 1752 1753 @Override detach()1754 public void detach() { 1755 mTimeBase.remove(this); 1756 } 1757 writeSummaryFromParcelLocked(Parcel out)1758 public void writeSummaryFromParcelLocked(Parcel out) { 1759 out.writeLong(mCount); 1760 } 1761 readSummaryFromParcelLocked(Parcel in)1762 public void readSummaryFromParcelLocked(Parcel in) { 1763 mCount = in.readLong(); 1764 } 1765 } 1766 1767 /** 1768 * State for keeping track of timing information. 1769 */ 1770 public static abstract class Timer extends BatteryStats.Timer implements TimeBaseObs { 1771 protected final Clocks mClocks; 1772 protected final int mType; 1773 protected final TimeBase mTimeBase; 1774 1775 protected int mCount; 1776 1777 // Times are in microseconds for better accuracy when dividing by the 1778 // lock count, and are in "battery realtime" units. 1779 1780 /** 1781 * The total time we have accumulated since the start of the original 1782 * boot, to the last time something interesting happened in the 1783 * current run. 1784 */ 1785 protected long mTotalTimeUs; 1786 1787 /** 1788 * The total time this timer has been running until the latest mark has been set. 1789 * Subtract this from mTotalTimeUs to get the time spent running since the mark was set. 1790 */ 1791 protected long mTimeBeforeMarkUs; 1792 1793 /** 1794 * Constructs from a parcel. 1795 * @param type 1796 * @param timeBase 1797 * @param in 1798 */ Timer(Clocks clocks, int type, TimeBase timeBase, Parcel in)1799 public Timer(Clocks clocks, int type, TimeBase timeBase, Parcel in) { 1800 mClocks = clocks; 1801 mType = type; 1802 mTimeBase = timeBase; 1803 1804 mCount = in.readInt(); 1805 mTotalTimeUs = in.readLong(); 1806 mTimeBeforeMarkUs = in.readLong(); 1807 timeBase.add(this); 1808 if (DEBUG) Log.i(TAG, "**** READ TIMER #" + mType + ": mTotalTime=" + mTotalTimeUs); 1809 } 1810 Timer(Clocks clocks, int type, TimeBase timeBase)1811 public Timer(Clocks clocks, int type, TimeBase timeBase) { 1812 mClocks = clocks; 1813 mType = type; 1814 mTimeBase = timeBase; 1815 timeBase.add(this); 1816 } 1817 writeToParcel(Parcel out, long elapsedRealtimeUs)1818 public void writeToParcel(Parcel out, long elapsedRealtimeUs) { 1819 if (DEBUG) { 1820 Log.i(TAG, "**** WRITING TIMER #" + mType + ": mTotalTime=" 1821 + computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs), 1822 elapsedRealtimeUs)); 1823 } 1824 out.writeInt(computeCurrentCountLocked()); 1825 out.writeLong(computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs), 1826 elapsedRealtimeUs)); 1827 out.writeLong(mTimeBeforeMarkUs); 1828 } 1829 computeRunTimeLocked(long curBatteryRealtime, long elapsedRealtimeUs)1830 protected abstract long computeRunTimeLocked(long curBatteryRealtime, 1831 long elapsedRealtimeUs); 1832 computeCurrentCountLocked()1833 protected abstract int computeCurrentCountLocked(); 1834 1835 /** 1836 * Clear state of this timer. Returns true if the timer is inactive 1837 * so can be completely dropped. 1838 */ 1839 @Override reset(boolean detachIfReset)1840 public boolean reset(boolean detachIfReset) { 1841 return reset(detachIfReset, mClocks.elapsedRealtime() * 1000); 1842 } 1843 1844 @Override reset(boolean detachIfReset, long elapsedRealtimeUs )1845 public boolean reset(boolean detachIfReset, long elapsedRealtimeUs /* unused */) { 1846 mTotalTimeUs = mTimeBeforeMarkUs = 0; 1847 mCount = 0; 1848 if (detachIfReset) { 1849 detach(); 1850 } 1851 return true; 1852 } 1853 1854 @Override detach()1855 public void detach() { 1856 mTimeBase.remove(this); 1857 } 1858 1859 @Override onTimeStarted(long elapsedRealtimeUs, long timeBaseUptimeUs, long baseRealtimeUs)1860 public void onTimeStarted(long elapsedRealtimeUs, long timeBaseUptimeUs, 1861 long baseRealtimeUs) { 1862 } 1863 1864 @Override onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)1865 public void onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { 1866 if (DEBUG && mType < 0) { 1867 Log.v(TAG, "plug #" + mType + ": realtime=" + baseRealtimeUs 1868 + " old mTotalTime=" + mTotalTimeUs); 1869 } 1870 mTotalTimeUs = computeRunTimeLocked(baseRealtimeUs, elapsedRealtimeUs); 1871 mCount = computeCurrentCountLocked(); 1872 if (DEBUG && mType < 0) { 1873 Log.v(TAG, "plug #" + mType + ": new mTotalTime=" + mTotalTimeUs); 1874 } 1875 } 1876 1877 /** 1878 * Writes a possibly null Timer to a Parcel. 1879 * 1880 * @param out the Parcel to be written to. 1881 * @param timer a Timer, or null. 1882 */ 1883 @UnsupportedAppUsage writeTimerToParcel(Parcel out, Timer timer, long elapsedRealtimeUs)1884 public static void writeTimerToParcel(Parcel out, Timer timer, long elapsedRealtimeUs) { 1885 if (timer == null) { 1886 out.writeInt(0); // indicates null 1887 return; 1888 } 1889 out.writeInt(1); // indicates non-null 1890 timer.writeToParcel(out, elapsedRealtimeUs); 1891 } 1892 1893 @Override 1894 @UnsupportedAppUsage getTotalTimeLocked(long elapsedRealtimeUs, int which)1895 public long getTotalTimeLocked(long elapsedRealtimeUs, int which) { 1896 return computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs), 1897 elapsedRealtimeUs); 1898 } 1899 1900 @Override 1901 @UnsupportedAppUsage getCountLocked(int which)1902 public int getCountLocked(int which) { 1903 return computeCurrentCountLocked(); 1904 } 1905 1906 @Override getTimeSinceMarkLocked(long elapsedRealtimeUs)1907 public long getTimeSinceMarkLocked(long elapsedRealtimeUs) { 1908 long val = computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs), 1909 elapsedRealtimeUs); 1910 return val - mTimeBeforeMarkUs; 1911 } 1912 1913 @Override logState(Printer pw, String prefix)1914 public void logState(Printer pw, String prefix) { 1915 pw.println(prefix + "mCount=" + mCount); 1916 pw.println(prefix + "mTotalTime=" + mTotalTimeUs); 1917 } 1918 1919 writeSummaryFromParcelLocked(Parcel out, long elapsedRealtimeUs)1920 public void writeSummaryFromParcelLocked(Parcel out, long elapsedRealtimeUs) { 1921 long runTimeUs = computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs), 1922 elapsedRealtimeUs); 1923 out.writeLong(runTimeUs); 1924 out.writeInt(computeCurrentCountLocked()); 1925 } 1926 readSummaryFromParcelLocked(Parcel in)1927 public void readSummaryFromParcelLocked(Parcel in) { 1928 // Multiply by 1000 for backwards compatibility 1929 mTotalTimeUs = in.readLong(); 1930 mCount = in.readInt(); 1931 // When reading the summary, we set the mark to be the latest information. 1932 mTimeBeforeMarkUs = mTotalTimeUs; 1933 } 1934 } 1935 1936 /** 1937 * A counter meant to accept monotonically increasing values to its {@link #update(long, int)} 1938 * method. The state of the timer according to its {@link TimeBase} will determine how much 1939 * of the value is recorded. 1940 * 1941 * If the value being recorded resets, {@link #endSample()} can be called in order to 1942 * account for the change. If the value passed in to {@link #update(long, int)} decreased 1943 * between calls, the {@link #endSample()} is automatically called and the new value is 1944 * expected to increase monotonically from that point on. 1945 */ 1946 public static class SamplingTimer extends Timer { 1947 1948 /** 1949 * The most recent reported count from /proc/wakelocks. 1950 */ 1951 int mCurrentReportedCount; 1952 1953 /** 1954 * The reported count from /proc/wakelocks when unplug() was last 1955 * called. 1956 */ 1957 int mUnpluggedReportedCount; 1958 1959 /** 1960 * The most recent reported total_time from /proc/wakelocks. 1961 */ 1962 long mCurrentReportedTotalTimeUs; 1963 1964 1965 /** 1966 * The reported total_time from /proc/wakelocks when unplug() was last 1967 * called. 1968 */ 1969 long mUnpluggedReportedTotalTimeUs; 1970 1971 /** 1972 * Whether we are currently in a discharge cycle. 1973 */ 1974 boolean mTimeBaseRunning; 1975 1976 /** 1977 * Whether we are currently recording reported values. 1978 */ 1979 boolean mTrackingReportedValues; 1980 1981 /* 1982 * A sequence counter, incremented once for each update of the stats. 1983 */ 1984 int mUpdateVersion; 1985 1986 @VisibleForTesting SamplingTimer(Clocks clocks, TimeBase timeBase, Parcel in)1987 public SamplingTimer(Clocks clocks, TimeBase timeBase, Parcel in) { 1988 super(clocks, 0, timeBase, in); 1989 mCurrentReportedCount = in.readInt(); 1990 mUnpluggedReportedCount = in.readInt(); 1991 mCurrentReportedTotalTimeUs = in.readLong(); 1992 mUnpluggedReportedTotalTimeUs = in.readLong(); 1993 mTrackingReportedValues = in.readInt() == 1; 1994 mTimeBaseRunning = timeBase.isRunning(); 1995 } 1996 1997 @VisibleForTesting SamplingTimer(Clocks clocks, TimeBase timeBase)1998 public SamplingTimer(Clocks clocks, TimeBase timeBase) { 1999 super(clocks, 0, timeBase); 2000 mTrackingReportedValues = false; 2001 mTimeBaseRunning = timeBase.isRunning(); 2002 } 2003 2004 /** 2005 * Ends the current sample, allowing subsequent values to {@link #update(long, int)} to 2006 * be less than the values used for a previous invocation. 2007 */ endSample()2008 public void endSample() { 2009 endSample(mClocks.elapsedRealtime() * 1000); 2010 } 2011 2012 /** 2013 * @see #endSample() 2014 */ endSample(long elapsedRealtimeUs)2015 public void endSample(long elapsedRealtimeUs) { 2016 mTotalTimeUs = computeRunTimeLocked(0 /* unused by us */, elapsedRealtimeUs); 2017 mCount = computeCurrentCountLocked(); 2018 mUnpluggedReportedTotalTimeUs = mCurrentReportedTotalTimeUs = 0; 2019 mUnpluggedReportedCount = mCurrentReportedCount = 0; 2020 mTrackingReportedValues = false; 2021 } 2022 setUpdateVersion(int version)2023 public void setUpdateVersion(int version) { 2024 mUpdateVersion = version; 2025 } 2026 getUpdateVersion()2027 public int getUpdateVersion() { 2028 return mUpdateVersion; 2029 } 2030 2031 /** 2032 * Updates the current recorded values. These are meant to be monotonically increasing 2033 * and cumulative. If you are dealing with deltas, use {@link #add(long, int)}. 2034 * 2035 * If the values being recorded have been reset, the monotonically increasing requirement 2036 * will be broken. In this case, {@link #endSample()} is automatically called and 2037 * the total value of totalTimeUs and count are recorded, starting a new monotonically 2038 * increasing sample. 2039 * 2040 * @param totalTimeUs total time of sample in microseconds. 2041 * @param count total number of times the event being sampled occurred. 2042 */ updated(long totalTimeUs, int count)2043 public void updated(long totalTimeUs, int count) { 2044 update(totalTimeUs, count, mClocks.elapsedRealtime() * 1000); 2045 } 2046 2047 /** 2048 * @see #update(long, int) 2049 */ update(long totalTimeUs, int count, long elapsedRealtimeUs)2050 public void update(long totalTimeUs, int count, long elapsedRealtimeUs) { 2051 if (mTimeBaseRunning && !mTrackingReportedValues) { 2052 // Updating the reported value for the first time. 2053 mUnpluggedReportedTotalTimeUs = totalTimeUs; 2054 mUnpluggedReportedCount = count; 2055 } 2056 2057 mTrackingReportedValues = true; 2058 2059 if (totalTimeUs < mCurrentReportedTotalTimeUs || count < mCurrentReportedCount) { 2060 endSample(elapsedRealtimeUs); 2061 } 2062 2063 mCurrentReportedTotalTimeUs = totalTimeUs; 2064 mCurrentReportedCount = count; 2065 } 2066 2067 /** 2068 * Adds deltaTime and deltaCount to the current sample. 2069 * 2070 * @param deltaTime additional time recorded since the last sampled event, in microseconds. 2071 * @param deltaCount additional number of times the event being sampled occurred. 2072 */ add(long deltaTimeUs, int deltaCount)2073 public void add(long deltaTimeUs, int deltaCount) { 2074 add(deltaTimeUs, deltaCount, mClocks.elapsedRealtime() * 1000); 2075 } 2076 2077 /** 2078 * @see #add(long, int) 2079 */ add(long deltaTimeUs, int deltaCount, long elapsedRealtimeUs)2080 public void add(long deltaTimeUs, int deltaCount, long elapsedRealtimeUs) { 2081 update(mCurrentReportedTotalTimeUs + deltaTimeUs, mCurrentReportedCount + deltaCount, 2082 elapsedRealtimeUs); 2083 } 2084 2085 @Override onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)2086 public void onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { 2087 super.onTimeStarted(elapsedRealtimeUs, baseUptimeUs, baseRealtimeUs); 2088 if (mTrackingReportedValues) { 2089 mUnpluggedReportedTotalTimeUs = mCurrentReportedTotalTimeUs; 2090 mUnpluggedReportedCount = mCurrentReportedCount; 2091 } 2092 mTimeBaseRunning = true; 2093 } 2094 2095 @Override onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)2096 public void onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { 2097 super.onTimeStopped(elapsedRealtimeUs, baseUptimeUs, baseRealtimeUs); 2098 mTimeBaseRunning = false; 2099 } 2100 2101 @Override logState(Printer pw, String prefix)2102 public void logState(Printer pw, String prefix) { 2103 super.logState(pw, prefix); 2104 pw.println(prefix + "mCurrentReportedCount=" + mCurrentReportedCount 2105 + " mUnpluggedReportedCount=" + mUnpluggedReportedCount 2106 + " mCurrentReportedTotalTime=" + mCurrentReportedTotalTimeUs 2107 + " mUnpluggedReportedTotalTime=" + mUnpluggedReportedTotalTimeUs); 2108 } 2109 2110 @Override computeRunTimeLocked(long curBatteryRealtime, long elapsedRealtimeUs)2111 protected long computeRunTimeLocked(long curBatteryRealtime, long elapsedRealtimeUs) { 2112 return mTotalTimeUs + (mTimeBaseRunning && mTrackingReportedValues 2113 ? mCurrentReportedTotalTimeUs - mUnpluggedReportedTotalTimeUs : 0); 2114 } 2115 2116 @Override computeCurrentCountLocked()2117 protected int computeCurrentCountLocked() { 2118 return mCount + (mTimeBaseRunning && mTrackingReportedValues 2119 ? mCurrentReportedCount - mUnpluggedReportedCount : 0); 2120 } 2121 2122 @Override writeToParcel(Parcel out, long elapsedRealtimeUs)2123 public void writeToParcel(Parcel out, long elapsedRealtimeUs) { 2124 super.writeToParcel(out, elapsedRealtimeUs); 2125 out.writeInt(mCurrentReportedCount); 2126 out.writeInt(mUnpluggedReportedCount); 2127 out.writeLong(mCurrentReportedTotalTimeUs); 2128 out.writeLong(mUnpluggedReportedTotalTimeUs); 2129 out.writeInt(mTrackingReportedValues ? 1 : 0); 2130 } 2131 2132 @Override reset(boolean detachIfReset, long elapsedRealtimeUs)2133 public boolean reset(boolean detachIfReset, long elapsedRealtimeUs) { 2134 super.reset(detachIfReset, elapsedRealtimeUs); 2135 mTrackingReportedValues = false; 2136 mUnpluggedReportedTotalTimeUs = 0; 2137 mUnpluggedReportedCount = 0; 2138 return true; 2139 } 2140 } 2141 2142 /** 2143 * A timer that increments in batches. It does not run for durations, but just jumps 2144 * for a pre-determined amount. 2145 */ 2146 public static class BatchTimer extends Timer { 2147 final Uid mUid; 2148 2149 /** 2150 * The last time at which we updated the timer. This is in elapsed realtime microseconds. 2151 */ 2152 long mLastAddedTimeUs; 2153 2154 /** 2155 * The last duration that we added to the timer. This is in microseconds. 2156 */ 2157 long mLastAddedDurationUs; 2158 2159 /** 2160 * Whether we are currently in a discharge cycle. 2161 */ 2162 boolean mInDischarge; 2163 BatchTimer(Clocks clocks, Uid uid, int type, TimeBase timeBase, Parcel in)2164 BatchTimer(Clocks clocks, Uid uid, int type, TimeBase timeBase, Parcel in) { 2165 super(clocks, type, timeBase, in); 2166 mUid = uid; 2167 mLastAddedTimeUs = in.readLong(); 2168 mLastAddedDurationUs = in.readLong(); 2169 mInDischarge = timeBase.isRunning(); 2170 } 2171 BatchTimer(Clocks clocks, Uid uid, int type, TimeBase timeBase)2172 BatchTimer(Clocks clocks, Uid uid, int type, TimeBase timeBase) { 2173 super(clocks, type, timeBase); 2174 mUid = uid; 2175 mInDischarge = timeBase.isRunning(); 2176 } 2177 2178 @Override writeToParcel(Parcel out, long elapsedRealtimeUs)2179 public void writeToParcel(Parcel out, long elapsedRealtimeUs) { 2180 super.writeToParcel(out, elapsedRealtimeUs); 2181 out.writeLong(mLastAddedTimeUs); 2182 out.writeLong(mLastAddedDurationUs); 2183 } 2184 2185 @Override onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)2186 public void onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { 2187 recomputeLastDuration(elapsedRealtimeUs, false); 2188 mInDischarge = false; 2189 super.onTimeStopped(elapsedRealtimeUs, baseUptimeUs, baseRealtimeUs); 2190 } 2191 2192 @Override onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)2193 public void onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { 2194 recomputeLastDuration(elapsedRealtimeUs, false); 2195 mInDischarge = true; 2196 // If we are still within the last added duration, then re-added whatever remains. 2197 if (mLastAddedTimeUs == elapsedRealtimeUs) { 2198 mTotalTimeUs += mLastAddedDurationUs; 2199 } 2200 super.onTimeStarted(elapsedRealtimeUs, baseUptimeUs, baseRealtimeUs); 2201 } 2202 2203 @Override logState(Printer pw, String prefix)2204 public void logState(Printer pw, String prefix) { 2205 super.logState(pw, prefix); 2206 pw.println(prefix + "mLastAddedTime=" + mLastAddedTimeUs 2207 + " mLastAddedDuration=" + mLastAddedDurationUs); 2208 } 2209 computeOverage(long curTimeUs)2210 private long computeOverage(long curTimeUs) { 2211 if (mLastAddedTimeUs > 0) { 2212 return mLastAddedDurationUs - curTimeUs; 2213 } 2214 return 0; 2215 } 2216 recomputeLastDuration(long curTimeUs, boolean abort)2217 private void recomputeLastDuration(long curTimeUs, boolean abort) { 2218 final long overage = computeOverage(curTimeUs); 2219 if (overage > 0) { 2220 // Aborting before the duration ran out -- roll back the remaining 2221 // duration. Only do this if currently discharging; otherwise we didn't 2222 // actually add the time. 2223 if (mInDischarge) { 2224 mTotalTimeUs -= overage; 2225 } 2226 if (abort) { 2227 mLastAddedTimeUs = 0; 2228 } else { 2229 mLastAddedTimeUs = curTimeUs; 2230 mLastAddedDurationUs -= overage; 2231 } 2232 } 2233 } 2234 addDuration(BatteryStatsImpl stats, long durationMs)2235 public void addDuration(BatteryStatsImpl stats, long durationMs) { 2236 addDuration(stats, durationMs, mClocks.elapsedRealtime()); 2237 } 2238 addDuration(BatteryStatsImpl stats, long durationMs, long elapsedRealtimeMs)2239 public void addDuration(BatteryStatsImpl stats, long durationMs, long elapsedRealtimeMs) { 2240 final long nowUs = elapsedRealtimeMs * 1000; 2241 recomputeLastDuration(nowUs, true); 2242 mLastAddedTimeUs = nowUs; 2243 mLastAddedDurationUs = durationMs * 1000; 2244 if (mInDischarge) { 2245 mTotalTimeUs += mLastAddedDurationUs; 2246 mCount++; 2247 } 2248 } 2249 abortLastDuration(BatteryStatsImpl stats)2250 public void abortLastDuration(BatteryStatsImpl stats) { 2251 abortLastDuration(stats, mClocks.elapsedRealtime()); 2252 } 2253 abortLastDuration(BatteryStatsImpl stats, long elapsedRealtimeMs)2254 public void abortLastDuration(BatteryStatsImpl stats, long elapsedRealtimeMs) { 2255 final long nowUs = elapsedRealtimeMs * 1000; 2256 recomputeLastDuration(nowUs, true); 2257 } 2258 2259 @Override computeCurrentCountLocked()2260 protected int computeCurrentCountLocked() { 2261 return mCount; 2262 } 2263 2264 @Override computeRunTimeLocked(long curBatteryRealtimeUs, long elapsedRealtimeUs)2265 protected long computeRunTimeLocked(long curBatteryRealtimeUs, long elapsedRealtimeUs) { 2266 final long overage = computeOverage(elapsedRealtimeUs); 2267 if (overage > 0) { 2268 return mTotalTimeUs = overage; 2269 } 2270 return mTotalTimeUs; 2271 } 2272 2273 @Override reset(boolean detachIfReset, long elapsedRealtimeUs)2274 public boolean reset(boolean detachIfReset, long elapsedRealtimeUs) { 2275 recomputeLastDuration(elapsedRealtimeUs, true); 2276 boolean stillActive = mLastAddedTimeUs == elapsedRealtimeUs; 2277 super.reset(!stillActive && detachIfReset, elapsedRealtimeUs); 2278 return !stillActive; 2279 } 2280 } 2281 2282 2283 /** 2284 * A StopwatchTimer that also tracks the total and max individual 2285 * time spent active according to the given timebase. Whereas 2286 * StopwatchTimer apportions the time amongst all in the pool, 2287 * the total and max durations are not apportioned. 2288 */ 2289 public static class DurationTimer extends StopwatchTimer { 2290 /** 2291 * The time (in ms) that the timer was last acquired or the time base 2292 * last (re-)started. Increasing the nesting depth does not reset this time. 2293 * 2294 * -1 if the timer is currently not running or the time base is not running. 2295 * 2296 * If written to a parcel, the start time is reset, as is mNesting in the base class 2297 * StopwatchTimer. 2298 */ 2299 long mStartTimeMs = -1; 2300 2301 /** 2302 * The longest time period (in ms) that the timer has been active. Not pooled. 2303 */ 2304 long mMaxDurationMs; 2305 2306 /** 2307 * The time (in ms) that that the timer has been active since most recent 2308 * stopRunningLocked() or reset(). Not pooled. 2309 */ 2310 long mCurrentDurationMs; 2311 2312 /** 2313 * The total time (in ms) that that the timer has been active since most recent reset() 2314 * prior to the current startRunningLocked. This is the sum of all past currentDurations 2315 * (but not including the present currentDuration) since reset. Not pooled. 2316 */ 2317 long mTotalDurationMs; 2318 DurationTimer(Clocks clocks, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, TimeBase timeBase, Parcel in)2319 public DurationTimer(Clocks clocks, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, 2320 TimeBase timeBase, Parcel in) { 2321 super(clocks, uid, type, timerPool, timeBase, in); 2322 mMaxDurationMs = in.readLong(); 2323 mTotalDurationMs = in.readLong(); 2324 mCurrentDurationMs = in.readLong(); 2325 } 2326 DurationTimer(Clocks clocks, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, TimeBase timeBase)2327 public DurationTimer(Clocks clocks, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, 2328 TimeBase timeBase) { 2329 super(clocks, uid, type, timerPool, timeBase); 2330 } 2331 2332 @Override writeToParcel(Parcel out, long elapsedRealtimeUs)2333 public void writeToParcel(Parcel out, long elapsedRealtimeUs) { 2334 super.writeToParcel(out, elapsedRealtimeUs); 2335 out.writeLong(getMaxDurationMsLocked(elapsedRealtimeUs / 1000)); 2336 out.writeLong(mTotalDurationMs); 2337 out.writeLong(getCurrentDurationMsLocked(elapsedRealtimeUs / 1000)); 2338 } 2339 2340 /** 2341 * Write the summary to the parcel. 2342 * 2343 * Since the time base is probably meaningless after we come back, reading 2344 * from this will have the effect of stopping the timer. So here all we write 2345 * is the max and total durations. 2346 */ 2347 @Override writeSummaryFromParcelLocked(Parcel out, long elapsedRealtimeUs)2348 public void writeSummaryFromParcelLocked(Parcel out, long elapsedRealtimeUs) { 2349 super.writeSummaryFromParcelLocked(out, elapsedRealtimeUs); 2350 out.writeLong(getMaxDurationMsLocked(elapsedRealtimeUs / 1000)); 2351 out.writeLong(getTotalDurationMsLocked(elapsedRealtimeUs / 1000)); 2352 } 2353 2354 /** 2355 * Read the summary parcel. 2356 * 2357 * Has the side effect of stopping the timer. 2358 */ 2359 @Override readSummaryFromParcelLocked(Parcel in)2360 public void readSummaryFromParcelLocked(Parcel in) { 2361 super.readSummaryFromParcelLocked(in); 2362 mMaxDurationMs = in.readLong(); 2363 mTotalDurationMs = in.readLong(); 2364 mStartTimeMs = -1; 2365 mCurrentDurationMs = 0; 2366 } 2367 2368 /** 2369 * The TimeBase time started (again). 2370 * 2371 * If the timer is also running, store the start time. 2372 */ onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)2373 public void onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { 2374 super.onTimeStarted(elapsedRealtimeUs, baseUptimeUs, baseRealtimeUs); 2375 if (mNesting > 0) { 2376 mStartTimeMs = baseRealtimeUs / 1000; 2377 } 2378 } 2379 2380 /** 2381 * The TimeBase stopped running. 2382 * 2383 * If the timer is running, add the duration into mCurrentDurationMs. 2384 */ 2385 @Override onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)2386 public void onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { 2387 super.onTimeStopped(elapsedRealtimeUs, baseUptimeUs, baseRealtimeUs); 2388 if (mNesting > 0) { 2389 // baseRealtimeUs has already been converted to the timebase's realtime. 2390 mCurrentDurationMs += (baseRealtimeUs / 1000) - mStartTimeMs; 2391 } 2392 mStartTimeMs = -1; 2393 } 2394 2395 @Override logState(Printer pw, String prefix)2396 public void logState(Printer pw, String prefix) { 2397 super.logState(pw, prefix); 2398 } 2399 2400 @Override startRunningLocked(long elapsedRealtimeMs)2401 public void startRunningLocked(long elapsedRealtimeMs) { 2402 super.startRunningLocked(elapsedRealtimeMs); 2403 if (mNesting == 1 && mTimeBase.isRunning()) { 2404 // Just started 2405 mStartTimeMs = mTimeBase.getRealtime(elapsedRealtimeMs * 1000) / 1000; 2406 } 2407 } 2408 2409 /** 2410 * Decrements the mNesting ref-count on this timer. 2411 * 2412 * If it actually stopped (mNesting went to 0), then possibly update 2413 * mMaxDuration if the current duration was the longest ever. 2414 */ 2415 @Override stopRunningLocked(long elapsedRealtimeMs)2416 public void stopRunningLocked(long elapsedRealtimeMs) { 2417 if (mNesting == 1) { 2418 final long durationMs = getCurrentDurationMsLocked(elapsedRealtimeMs); 2419 mTotalDurationMs += durationMs; 2420 if (durationMs > mMaxDurationMs) { 2421 mMaxDurationMs = durationMs; 2422 } 2423 mStartTimeMs = -1; 2424 mCurrentDurationMs = 0; 2425 } 2426 // super method decrements mNesting, which getCurrentDurationMsLocked relies on, 2427 // so call super.stopRunningLocked after calling getCurrentDurationMsLocked. 2428 super.stopRunningLocked(elapsedRealtimeMs); 2429 } 2430 2431 @Override reset(boolean detachIfReset, long elapsedRealtimeUs)2432 public boolean reset(boolean detachIfReset, long elapsedRealtimeUs) { 2433 boolean result = super.reset(detachIfReset, elapsedRealtimeUs); 2434 mMaxDurationMs = 0; 2435 mTotalDurationMs = 0; 2436 mCurrentDurationMs = 0; 2437 if (mNesting > 0) { 2438 mStartTimeMs = mTimeBase.getRealtime(elapsedRealtimeUs) / 1000; 2439 } else { 2440 mStartTimeMs = -1; 2441 } 2442 return result; 2443 } 2444 2445 /** 2446 * Returns the max duration that this timer has ever seen. 2447 * 2448 * Note that this time is NOT split between the timers in the timer group that 2449 * this timer is attached to. It is the TOTAL time. 2450 */ 2451 @Override getMaxDurationMsLocked(long elapsedRealtimeMs)2452 public long getMaxDurationMsLocked(long elapsedRealtimeMs) { 2453 if (mNesting > 0) { 2454 final long durationMs = getCurrentDurationMsLocked(elapsedRealtimeMs); 2455 if (durationMs > mMaxDurationMs) { 2456 return durationMs; 2457 } 2458 } 2459 return mMaxDurationMs; 2460 } 2461 2462 /** 2463 * Returns the time since the timer was started. 2464 * Returns 0 if the timer is not currently running. 2465 * 2466 * Note that this time is NOT split between the timers in the timer group that 2467 * this timer is attached to. It is the TOTAL time. 2468 * 2469 * Note that if running timer is parceled and unparceled, this method will return 2470 * current duration value at the time of parceling even though timer may not be 2471 * currently running. 2472 */ 2473 @Override getCurrentDurationMsLocked(long elapsedRealtimeMs)2474 public long getCurrentDurationMsLocked(long elapsedRealtimeMs) { 2475 long durationMs = mCurrentDurationMs; 2476 if (mNesting > 0 && mTimeBase.isRunning()) { 2477 durationMs += (mTimeBase.getRealtime(elapsedRealtimeMs * 1000) / 1000) 2478 - mStartTimeMs; 2479 } 2480 return durationMs; 2481 } 2482 2483 /** 2484 * Returns the total cumulative duration that this timer has been on since reset(). 2485 * If mTimerPool == null, this should be the same 2486 * as getTotalTimeLocked(elapsedRealtimeMs*1000, STATS_SINCE_CHARGED)/1000. 2487 * 2488 * Note that this time is NOT split between the timers in the timer group that 2489 * this timer is attached to. It is the TOTAL time. For this reason, if mTimerPool != null, 2490 * the result will not be equivalent to getTotalTimeLocked. 2491 */ 2492 @Override getTotalDurationMsLocked(long elapsedRealtimeMs)2493 public long getTotalDurationMsLocked(long elapsedRealtimeMs) { 2494 return mTotalDurationMs + getCurrentDurationMsLocked(elapsedRealtimeMs); 2495 } 2496 } 2497 2498 /** 2499 * State for keeping track of timing information. 2500 */ 2501 public static class StopwatchTimer extends Timer { 2502 final Uid mUid; 2503 final ArrayList<StopwatchTimer> mTimerPool; 2504 2505 int mNesting; 2506 2507 /** 2508 * The last time at which we updated the timer. If mNesting is > 0, 2509 * subtract this from the current battery time to find the amount of 2510 * time we have been running since we last computed an update. 2511 */ 2512 long mUpdateTimeUs; 2513 2514 /** 2515 * The total time at which the timer was acquired, to determine if it 2516 * was actually held for an interesting duration. If time base was not running when timer 2517 * was acquired, will be -1. 2518 */ 2519 long mAcquireTimeUs = -1; 2520 2521 long mTimeoutUs; 2522 2523 /** 2524 * For partial wake locks, keep track of whether we are in the list 2525 * to consume CPU cycles. 2526 */ 2527 @VisibleForTesting 2528 public boolean mInList; 2529 StopwatchTimer(Clocks clocks, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, TimeBase timeBase, Parcel in)2530 public StopwatchTimer(Clocks clocks, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, 2531 TimeBase timeBase, Parcel in) { 2532 super(clocks, type, timeBase, in); 2533 mUid = uid; 2534 mTimerPool = timerPool; 2535 mUpdateTimeUs = in.readLong(); 2536 } 2537 StopwatchTimer(Clocks clocks, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, TimeBase timeBase)2538 public StopwatchTimer(Clocks clocks, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, 2539 TimeBase timeBase) { 2540 super(clocks, type, timeBase); 2541 mUid = uid; 2542 mTimerPool = timerPool; 2543 } 2544 setTimeout(long timeoutUs)2545 public void setTimeout(long timeoutUs) { 2546 mTimeoutUs = timeoutUs; 2547 } 2548 writeToParcel(Parcel out, long elapsedRealtimeUs)2549 public void writeToParcel(Parcel out, long elapsedRealtimeUs) { 2550 super.writeToParcel(out, elapsedRealtimeUs); 2551 out.writeLong(mUpdateTimeUs); 2552 } 2553 onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)2554 public void onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { 2555 if (mNesting > 0) { 2556 if (DEBUG && mType < 0) { 2557 Log.v(TAG, "old mUpdateTime=" + mUpdateTimeUs); 2558 } 2559 super.onTimeStopped(elapsedRealtimeUs, baseUptimeUs, baseRealtimeUs); 2560 mUpdateTimeUs = baseRealtimeUs; 2561 if (DEBUG && mType < 0) { 2562 Log.v(TAG, "new mUpdateTime=" + mUpdateTimeUs); 2563 } 2564 } 2565 } 2566 logState(Printer pw, String prefix)2567 public void logState(Printer pw, String prefix) { 2568 super.logState(pw, prefix); 2569 pw.println(prefix + "mNesting=" + mNesting + " mUpdateTime=" + mUpdateTimeUs 2570 + " mAcquireTime=" + mAcquireTimeUs); 2571 } 2572 startRunningLocked(long elapsedRealtimeMs)2573 public void startRunningLocked(long elapsedRealtimeMs) { 2574 if (mNesting++ == 0) { 2575 final long batteryRealtimeUs = mTimeBase.getRealtime(elapsedRealtimeMs * 1000); 2576 mUpdateTimeUs = batteryRealtimeUs; 2577 if (mTimerPool != null) { 2578 // Accumulate time to all currently active timers before adding 2579 // this new one to the pool. 2580 refreshTimersLocked(batteryRealtimeUs, mTimerPool, null); 2581 // Add this timer to the active pool 2582 mTimerPool.add(this); 2583 } 2584 if (mTimeBase.isRunning()) { 2585 // Increment the count 2586 mCount++; 2587 mAcquireTimeUs = mTotalTimeUs; 2588 } else { 2589 mAcquireTimeUs = -1; 2590 } 2591 if (DEBUG && mType < 0) { 2592 Log.v(TAG, "start #" + mType + ": mUpdateTime=" + mUpdateTimeUs 2593 + " mTotalTime=" + mTotalTimeUs + " mCount=" + mCount 2594 + " mAcquireTime=" + mAcquireTimeUs); 2595 } 2596 } 2597 } 2598 isRunningLocked()2599 public boolean isRunningLocked() { 2600 return mNesting > 0; 2601 } 2602 stopRunningLocked(long elapsedRealtimeMs)2603 public void stopRunningLocked(long elapsedRealtimeMs) { 2604 // Ignore attempt to stop a timer that isn't running 2605 if (mNesting == 0) { 2606 return; 2607 } 2608 if (--mNesting == 0) { 2609 final long batteryRealtimeUs = mTimeBase.getRealtime(elapsedRealtimeMs * 1000); 2610 if (mTimerPool != null) { 2611 // Accumulate time to all active counters, scaled by the total 2612 // active in the pool, before taking this one out of the pool. 2613 refreshTimersLocked(batteryRealtimeUs, mTimerPool, null); 2614 // Remove this timer from the active pool 2615 mTimerPool.remove(this); 2616 } else { 2617 mNesting = 1; 2618 mTotalTimeUs = computeRunTimeLocked(batteryRealtimeUs, 2619 elapsedRealtimeMs * 1000); 2620 mNesting = 0; 2621 } 2622 2623 if (DEBUG && mType < 0) { 2624 Log.v(TAG, "stop #" + mType + ": mUpdateTime=" + mUpdateTimeUs 2625 + " mTotalTime=" + mTotalTimeUs + " mCount=" + mCount 2626 + " mAcquireTime=" + mAcquireTimeUs); 2627 } 2628 2629 if (mAcquireTimeUs >= 0 && mTotalTimeUs == mAcquireTimeUs) { 2630 // If there was no change in the time, then discard this 2631 // count. A somewhat cheezy strategy, but hey. 2632 mCount--; 2633 } 2634 } 2635 } 2636 stopAllRunningLocked(long elapsedRealtimeMs)2637 public void stopAllRunningLocked(long elapsedRealtimeMs) { 2638 if (mNesting > 0) { 2639 mNesting = 1; 2640 stopRunningLocked(elapsedRealtimeMs); 2641 } 2642 } 2643 2644 // Update the total time for all other running Timers with the same type as this Timer 2645 // due to a change in timer count refreshTimersLocked(long batteryRealtimeUs, final ArrayList<StopwatchTimer> pool, StopwatchTimer self)2646 private static long refreshTimersLocked(long batteryRealtimeUs, 2647 final ArrayList<StopwatchTimer> pool, StopwatchTimer self) { 2648 long selfTimeUs = 0; 2649 final int N = pool.size(); 2650 for (int i=N-1; i>= 0; i--) { 2651 final StopwatchTimer t = pool.get(i); 2652 long heldTimeUs = batteryRealtimeUs - t.mUpdateTimeUs; 2653 if (heldTimeUs > 0) { 2654 final long myTimeUs = heldTimeUs / N; 2655 if (t == self) { 2656 selfTimeUs = myTimeUs; 2657 } 2658 t.mTotalTimeUs += myTimeUs; 2659 } 2660 t.mUpdateTimeUs = batteryRealtimeUs; 2661 } 2662 return selfTimeUs; 2663 } 2664 2665 @Override computeRunTimeLocked(long curBatteryRealtimeUs, long elapsedRealtimeUs)2666 protected long computeRunTimeLocked(long curBatteryRealtimeUs, long elapsedRealtimeUs) { 2667 if (mTimeoutUs > 0 && curBatteryRealtimeUs > mUpdateTimeUs + mTimeoutUs) { 2668 curBatteryRealtimeUs = mUpdateTimeUs + mTimeoutUs; 2669 } 2670 return mTotalTimeUs + (mNesting > 0 2671 ? (curBatteryRealtimeUs - mUpdateTimeUs) 2672 / (mTimerPool != null ? mTimerPool.size() : 1) 2673 : 0); 2674 } 2675 2676 @Override computeCurrentCountLocked()2677 protected int computeCurrentCountLocked() { 2678 return mCount; 2679 } 2680 2681 @Override reset(boolean detachIfReset, long elapsedRealtimeUs)2682 public boolean reset(boolean detachIfReset, long elapsedRealtimeUs) { 2683 boolean canDetach = mNesting <= 0; 2684 super.reset(canDetach && detachIfReset, elapsedRealtimeUs); 2685 if (mNesting > 0) { 2686 mUpdateTimeUs = mTimeBase.getRealtime(elapsedRealtimeUs); 2687 } 2688 // To ensure mCount isn't decreased to -1 if timer is stopped later. 2689 mAcquireTimeUs = -1; 2690 return canDetach; 2691 } 2692 2693 @Override 2694 @UnsupportedAppUsage detach()2695 public void detach() { 2696 super.detach(); 2697 if (mTimerPool != null) { 2698 mTimerPool.remove(this); 2699 } 2700 } 2701 2702 @Override readSummaryFromParcelLocked(Parcel in)2703 public void readSummaryFromParcelLocked(Parcel in) { 2704 super.readSummaryFromParcelLocked(in); 2705 mNesting = 0; 2706 } 2707 2708 /** 2709 * Set the mark so that we can query later for the total time the timer has 2710 * accumulated since this point. The timer can be running or not. 2711 * 2712 * @param elapsedRealtimeMs the current elapsed realtime in milliseconds. 2713 */ setMark(long elapsedRealtimeMs)2714 public void setMark(long elapsedRealtimeMs) { 2715 final long batteryRealtimeUs = mTimeBase.getRealtime(elapsedRealtimeMs * 1000); 2716 if (mNesting > 0) { 2717 // We are running. 2718 if (mTimerPool != null) { 2719 refreshTimersLocked(batteryRealtimeUs, mTimerPool, this); 2720 } else { 2721 mTotalTimeUs += batteryRealtimeUs - mUpdateTimeUs; 2722 mUpdateTimeUs = batteryRealtimeUs; 2723 } 2724 } 2725 mTimeBeforeMarkUs = mTotalTimeUs; 2726 } 2727 } 2728 2729 /** 2730 * State for keeping track of two DurationTimers with different TimeBases, presumably where one 2731 * TimeBase is effectively a subset of the other. 2732 */ 2733 public static class DualTimer extends DurationTimer { 2734 // This class both is a DurationTimer and also holds a second DurationTimer. 2735 // The main timer (this) typically tracks the total time. It may be pooled (but since it's a 2736 // durationTimer, it also has the unpooled getTotalDurationMsLocked() for 2737 // STATS_SINCE_CHARGED). 2738 // mSubTimer typically tracks only part of the total time, such as background time, as 2739 // determined by a subTimeBase. It is NOT pooled. 2740 private final DurationTimer mSubTimer; 2741 2742 /** 2743 * Creates a DualTimer to hold a main timer (this) and a mSubTimer. 2744 * The main timer (this) is based on the given timeBase and timerPool. 2745 * The mSubTimer is based on the given subTimeBase. The mSubTimer is not pooled, even if 2746 * the main timer is. 2747 */ DualTimer(Clocks clocks, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, TimeBase timeBase, TimeBase subTimeBase, Parcel in)2748 public DualTimer(Clocks clocks, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, 2749 TimeBase timeBase, TimeBase subTimeBase, Parcel in) { 2750 super(clocks, uid, type, timerPool, timeBase, in); 2751 mSubTimer = new DurationTimer(clocks, uid, type, null, subTimeBase, in); 2752 } 2753 2754 /** 2755 * Creates a DualTimer to hold a main timer (this) and a mSubTimer. 2756 * The main timer (this) is based on the given timeBase and timerPool. 2757 * The mSubTimer is based on the given subTimeBase. The mSubTimer is not pooled, even if 2758 * the main timer is. 2759 */ DualTimer(Clocks clocks, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, TimeBase timeBase, TimeBase subTimeBase)2760 public DualTimer(Clocks clocks, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, 2761 TimeBase timeBase, TimeBase subTimeBase) { 2762 super(clocks, uid, type, timerPool, timeBase); 2763 mSubTimer = new DurationTimer(clocks, uid, type, null, subTimeBase); 2764 } 2765 2766 /** Get the secondary timer. */ 2767 @Override getSubTimer()2768 public DurationTimer getSubTimer() { 2769 return mSubTimer; 2770 } 2771 2772 @Override startRunningLocked(long elapsedRealtimeMs)2773 public void startRunningLocked(long elapsedRealtimeMs) { 2774 super.startRunningLocked(elapsedRealtimeMs); 2775 mSubTimer.startRunningLocked(elapsedRealtimeMs); 2776 } 2777 2778 @Override stopRunningLocked(long elapsedRealtimeMs)2779 public void stopRunningLocked(long elapsedRealtimeMs) { 2780 super.stopRunningLocked(elapsedRealtimeMs); 2781 mSubTimer.stopRunningLocked(elapsedRealtimeMs); 2782 } 2783 2784 @Override stopAllRunningLocked(long elapsedRealtimeMs)2785 public void stopAllRunningLocked(long elapsedRealtimeMs) { 2786 super.stopAllRunningLocked(elapsedRealtimeMs); 2787 mSubTimer.stopAllRunningLocked(elapsedRealtimeMs); 2788 } 2789 2790 @Override reset(boolean detachIfReset, long elapsedRealtimeUs)2791 public boolean reset(boolean detachIfReset, long elapsedRealtimeUs) { 2792 boolean active = false; 2793 // Do not detach the subTimer explicitly since that'll be done by DualTimer.detach(). 2794 active |= !mSubTimer.reset(false, elapsedRealtimeUs); 2795 active |= !super.reset(detachIfReset, elapsedRealtimeUs); 2796 return !active; 2797 } 2798 2799 @Override detach()2800 public void detach() { 2801 mSubTimer.detach(); 2802 super.detach(); 2803 } 2804 2805 @Override writeToParcel(Parcel out, long elapsedRealtimeUs)2806 public void writeToParcel(Parcel out, long elapsedRealtimeUs) { 2807 super.writeToParcel(out, elapsedRealtimeUs); 2808 mSubTimer.writeToParcel(out, elapsedRealtimeUs); 2809 } 2810 2811 @Override writeSummaryFromParcelLocked(Parcel out, long elapsedRealtimeUs)2812 public void writeSummaryFromParcelLocked(Parcel out, long elapsedRealtimeUs) { 2813 super.writeSummaryFromParcelLocked(out, elapsedRealtimeUs); 2814 mSubTimer.writeSummaryFromParcelLocked(out, elapsedRealtimeUs); 2815 } 2816 2817 @Override readSummaryFromParcelLocked(Parcel in)2818 public void readSummaryFromParcelLocked(Parcel in) { 2819 super.readSummaryFromParcelLocked(in); 2820 mSubTimer.readSummaryFromParcelLocked(in); 2821 } 2822 } 2823 2824 2825 public abstract class OverflowArrayMap<T> { 2826 private static final String OVERFLOW_NAME = "*overflow*"; 2827 2828 final int mUid; 2829 final ArrayMap<String, T> mMap = new ArrayMap<>(); 2830 T mCurOverflow; 2831 ArrayMap<String, MutableInt> mActiveOverflow; 2832 long mLastOverflowTimeMs; 2833 long mLastOverflowFinishTimeMs; 2834 long mLastClearTimeMs; 2835 long mLastCleanupTimeMs; 2836 OverflowArrayMap(int uid)2837 public OverflowArrayMap(int uid) { 2838 mUid = uid; 2839 } 2840 getMap()2841 public ArrayMap<String, T> getMap() { 2842 return mMap; 2843 } 2844 clear()2845 public void clear() { 2846 mLastClearTimeMs = SystemClock.elapsedRealtime(); 2847 mMap.clear(); 2848 mCurOverflow = null; 2849 mActiveOverflow = null; 2850 } 2851 add(String name, T obj)2852 public void add(String name, T obj) { 2853 if (name == null) { 2854 name = ""; 2855 } 2856 mMap.put(name, obj); 2857 if (OVERFLOW_NAME.equals(name)) { 2858 mCurOverflow = obj; 2859 } 2860 } 2861 cleanup(long elapsedRealtimeMs)2862 public void cleanup(long elapsedRealtimeMs) { 2863 mLastCleanupTimeMs = elapsedRealtimeMs; 2864 if (mActiveOverflow != null) { 2865 if (mActiveOverflow.size() == 0) { 2866 mActiveOverflow = null; 2867 } 2868 } 2869 if (mActiveOverflow == null) { 2870 // There is no currently active overflow, so we should no longer have 2871 // an overflow entry. 2872 if (mMap.containsKey(OVERFLOW_NAME)) { 2873 Slog.wtf(TAG, "Cleaning up with no active overflow, but have overflow entry " 2874 + mMap.get(OVERFLOW_NAME)); 2875 mMap.remove(OVERFLOW_NAME); 2876 } 2877 mCurOverflow = null; 2878 } else { 2879 // There is currently active overflow, so we should still have an overflow entry. 2880 if (mCurOverflow == null || !mMap.containsKey(OVERFLOW_NAME)) { 2881 Slog.wtf(TAG, "Cleaning up with active overflow, but no overflow entry: cur=" 2882 + mCurOverflow + " map=" + mMap.get(OVERFLOW_NAME)); 2883 } 2884 } 2885 } 2886 startObject(String name, long elapsedRealtimeMs)2887 public T startObject(String name, long elapsedRealtimeMs) { 2888 if (name == null) { 2889 name = ""; 2890 } 2891 T obj = mMap.get(name); 2892 if (obj != null) { 2893 return obj; 2894 } 2895 2896 // No object exists for the given name, but do we currently have it 2897 // running as part of the overflow? 2898 if (mActiveOverflow != null) { 2899 MutableInt over = mActiveOverflow.get(name); 2900 if (over != null) { 2901 // We are already actively counting this name in the overflow object. 2902 obj = mCurOverflow; 2903 if (obj == null) { 2904 // Shouldn't be here, but we'll try to recover. 2905 Slog.wtf(TAG, "Have active overflow " + name + " but null overflow"); 2906 obj = mCurOverflow = instantiateObject(); 2907 mMap.put(OVERFLOW_NAME, obj); 2908 } 2909 over.value++; 2910 return obj; 2911 } 2912 } 2913 2914 // No object exists for given name nor in the overflow; we need to make 2915 // a new one. 2916 final int N = mMap.size(); 2917 if (N >= MAX_WAKELOCKS_PER_UID) { 2918 // Went over the limit on number of objects to track; this one goes 2919 // in to the overflow. 2920 obj = mCurOverflow; 2921 if (obj == null) { 2922 // Need to start overflow now... 2923 obj = mCurOverflow = instantiateObject(); 2924 mMap.put(OVERFLOW_NAME, obj); 2925 } 2926 if (mActiveOverflow == null) { 2927 mActiveOverflow = new ArrayMap<>(); 2928 } 2929 mActiveOverflow.put(name, new MutableInt(1)); 2930 mLastOverflowTimeMs = elapsedRealtimeMs; 2931 return obj; 2932 } 2933 2934 // Normal case where we just need to make a new object. 2935 obj = instantiateObject(); 2936 mMap.put(name, obj); 2937 return obj; 2938 } 2939 stopObject(String name, long elapsedRealtimeMs)2940 public T stopObject(String name, long elapsedRealtimeMs) { 2941 if (name == null) { 2942 name = ""; 2943 } 2944 T obj = mMap.get(name); 2945 if (obj != null) { 2946 return obj; 2947 } 2948 2949 // No object exists for the given name, but do we currently have it 2950 // running as part of the overflow? 2951 if (mActiveOverflow != null) { 2952 MutableInt over = mActiveOverflow.get(name); 2953 if (over != null) { 2954 // We are already actively counting this name in the overflow object. 2955 obj = mCurOverflow; 2956 if (obj != null) { 2957 over.value--; 2958 if (over.value <= 0) { 2959 mActiveOverflow.remove(name); 2960 mLastOverflowFinishTimeMs = elapsedRealtimeMs; 2961 } 2962 return obj; 2963 } 2964 } 2965 } 2966 2967 // Huh, they are stopping an active operation but we can't find one! 2968 // That's not good. 2969 StringBuilder sb = new StringBuilder(); 2970 sb.append("Unable to find object for "); 2971 sb.append(name); 2972 sb.append(" in uid "); 2973 sb.append(mUid); 2974 sb.append(" mapsize="); 2975 sb.append(mMap.size()); 2976 sb.append(" activeoverflow="); 2977 sb.append(mActiveOverflow); 2978 sb.append(" curoverflow="); 2979 sb.append(mCurOverflow); 2980 long now = elapsedRealtimeMs; 2981 if (mLastOverflowTimeMs != 0) { 2982 sb.append(" lastOverflowTime="); 2983 TimeUtils.formatDuration(mLastOverflowTimeMs - now, sb); 2984 } 2985 if (mLastOverflowFinishTimeMs != 0) { 2986 sb.append(" lastOverflowFinishTime="); 2987 TimeUtils.formatDuration(mLastOverflowFinishTimeMs - now, sb); 2988 } 2989 if (mLastClearTimeMs != 0) { 2990 sb.append(" lastClearTime="); 2991 TimeUtils.formatDuration(mLastClearTimeMs - now, sb); 2992 } 2993 if (mLastCleanupTimeMs != 0) { 2994 sb.append(" lastCleanupTime="); 2995 TimeUtils.formatDuration(mLastCleanupTimeMs - now, sb); 2996 } 2997 Slog.wtf(TAG, sb.toString()); 2998 return null; 2999 } 3000 instantiateObject()3001 public abstract T instantiateObject(); 3002 } 3003 3004 public static class ControllerActivityCounterImpl extends ControllerActivityCounter 3005 implements Parcelable { 3006 private final LongSamplingCounter mIdleTimeMillis; 3007 private final LongSamplingCounter mScanTimeMillis; 3008 private final LongSamplingCounter mSleepTimeMillis; 3009 private final LongSamplingCounter mRxTimeMillis; 3010 private final LongSamplingCounter[] mTxTimeMillis; 3011 private final LongSamplingCounter mPowerDrainMaMs; 3012 private final LongSamplingCounter mMonitoredRailChargeConsumedMaMs; 3013 ControllerActivityCounterImpl(TimeBase timeBase, int numTxStates)3014 public ControllerActivityCounterImpl(TimeBase timeBase, int numTxStates) { 3015 mIdleTimeMillis = new LongSamplingCounter(timeBase); 3016 mScanTimeMillis = new LongSamplingCounter(timeBase); 3017 mSleepTimeMillis = new LongSamplingCounter(timeBase); 3018 mRxTimeMillis = new LongSamplingCounter(timeBase); 3019 mTxTimeMillis = new LongSamplingCounter[numTxStates]; 3020 for (int i = 0; i < numTxStates; i++) { 3021 mTxTimeMillis[i] = new LongSamplingCounter(timeBase); 3022 } 3023 mPowerDrainMaMs = new LongSamplingCounter(timeBase); 3024 mMonitoredRailChargeConsumedMaMs = new LongSamplingCounter(timeBase); 3025 } 3026 ControllerActivityCounterImpl(TimeBase timeBase, int numTxStates, Parcel in)3027 public ControllerActivityCounterImpl(TimeBase timeBase, int numTxStates, Parcel in) { 3028 mIdleTimeMillis = new LongSamplingCounter(timeBase, in); 3029 mScanTimeMillis = new LongSamplingCounter(timeBase, in); 3030 mSleepTimeMillis = new LongSamplingCounter(timeBase, in); 3031 mRxTimeMillis = new LongSamplingCounter(timeBase, in); 3032 final int recordedTxStates = in.readInt(); 3033 if (recordedTxStates != numTxStates) { 3034 throw new ParcelFormatException("inconsistent tx state lengths"); 3035 } 3036 3037 mTxTimeMillis = new LongSamplingCounter[numTxStates]; 3038 for (int i = 0; i < numTxStates; i++) { 3039 mTxTimeMillis[i] = new LongSamplingCounter(timeBase, in); 3040 } 3041 mPowerDrainMaMs = new LongSamplingCounter(timeBase, in); 3042 mMonitoredRailChargeConsumedMaMs = new LongSamplingCounter(timeBase, in); 3043 } 3044 readSummaryFromParcel(Parcel in)3045 public void readSummaryFromParcel(Parcel in) { 3046 mIdleTimeMillis.readSummaryFromParcelLocked(in); 3047 mScanTimeMillis.readSummaryFromParcelLocked(in); 3048 mSleepTimeMillis.readSummaryFromParcelLocked(in); 3049 mRxTimeMillis.readSummaryFromParcelLocked(in); 3050 final int recordedTxStates = in.readInt(); 3051 if (recordedTxStates != mTxTimeMillis.length) { 3052 throw new ParcelFormatException("inconsistent tx state lengths"); 3053 } 3054 for (LongSamplingCounter counter : mTxTimeMillis) { 3055 counter.readSummaryFromParcelLocked(in); 3056 } 3057 mPowerDrainMaMs.readSummaryFromParcelLocked(in); 3058 mMonitoredRailChargeConsumedMaMs.readSummaryFromParcelLocked(in); 3059 } 3060 3061 @Override describeContents()3062 public int describeContents() { 3063 return 0; 3064 } 3065 writeSummaryToParcel(Parcel dest)3066 public void writeSummaryToParcel(Parcel dest) { 3067 mIdleTimeMillis.writeSummaryFromParcelLocked(dest); 3068 mScanTimeMillis.writeSummaryFromParcelLocked(dest); 3069 mSleepTimeMillis.writeSummaryFromParcelLocked(dest); 3070 mRxTimeMillis.writeSummaryFromParcelLocked(dest); 3071 dest.writeInt(mTxTimeMillis.length); 3072 for (LongSamplingCounter counter : mTxTimeMillis) { 3073 counter.writeSummaryFromParcelLocked(dest); 3074 } 3075 mPowerDrainMaMs.writeSummaryFromParcelLocked(dest); 3076 mMonitoredRailChargeConsumedMaMs.writeSummaryFromParcelLocked(dest); 3077 } 3078 3079 @Override writeToParcel(Parcel dest, int flags)3080 public void writeToParcel(Parcel dest, int flags) { 3081 mIdleTimeMillis.writeToParcel(dest); 3082 mScanTimeMillis.writeToParcel(dest); 3083 mSleepTimeMillis.writeToParcel(dest); 3084 mRxTimeMillis.writeToParcel(dest); 3085 dest.writeInt(mTxTimeMillis.length); 3086 for (LongSamplingCounter counter : mTxTimeMillis) { 3087 counter.writeToParcel(dest); 3088 } 3089 mPowerDrainMaMs.writeToParcel(dest); 3090 mMonitoredRailChargeConsumedMaMs.writeToParcel(dest); 3091 } 3092 reset(boolean detachIfReset, long elapsedRealtimeUs)3093 public void reset(boolean detachIfReset, long elapsedRealtimeUs) { 3094 mIdleTimeMillis.reset(detachIfReset, elapsedRealtimeUs); 3095 mScanTimeMillis.reset(detachIfReset, elapsedRealtimeUs); 3096 mSleepTimeMillis.reset(detachIfReset, elapsedRealtimeUs); 3097 mRxTimeMillis.reset(detachIfReset, elapsedRealtimeUs); 3098 for (LongSamplingCounter counter : mTxTimeMillis) { 3099 counter.reset(detachIfReset, elapsedRealtimeUs); 3100 } 3101 mPowerDrainMaMs.reset(detachIfReset, elapsedRealtimeUs); 3102 mMonitoredRailChargeConsumedMaMs.reset(detachIfReset, elapsedRealtimeUs); 3103 } 3104 detach()3105 public void detach() { 3106 mIdleTimeMillis.detach(); 3107 mScanTimeMillis.detach(); 3108 mSleepTimeMillis.detach(); 3109 mRxTimeMillis.detach(); 3110 for (LongSamplingCounter counter : mTxTimeMillis) { 3111 counter.detach(); 3112 } 3113 mPowerDrainMaMs.detach(); 3114 mMonitoredRailChargeConsumedMaMs.detach(); 3115 } 3116 3117 /** 3118 * @return a LongSamplingCounter, measuring time spent in the idle state in 3119 * milliseconds. 3120 */ 3121 @Override getIdleTimeCounter()3122 public LongSamplingCounter getIdleTimeCounter() { 3123 return mIdleTimeMillis; 3124 } 3125 3126 /** 3127 * @return a LongSamplingCounter, measuring time spent in the scan state in 3128 * milliseconds. 3129 */ 3130 @Override getScanTimeCounter()3131 public LongSamplingCounter getScanTimeCounter() { 3132 return mScanTimeMillis; 3133 } 3134 3135 /** 3136 * @return a LongSamplingCounter, measuring time spent in the sleep state in 3137 * milliseconds. 3138 */ 3139 @Override getSleepTimeCounter()3140 public LongSamplingCounter getSleepTimeCounter() { 3141 return mSleepTimeMillis; 3142 } 3143 3144 /** 3145 * @return a LongSamplingCounter, measuring time spent in the receive state in 3146 * milliseconds. 3147 */ 3148 @Override getRxTimeCounter()3149 public LongSamplingCounter getRxTimeCounter() { 3150 return mRxTimeMillis; 3151 } 3152 3153 /** 3154 * @return a LongSamplingCounter[], measuring time spent in various transmit states in 3155 * milliseconds. 3156 */ 3157 @Override getTxTimeCounters()3158 public LongSamplingCounter[] getTxTimeCounters() { 3159 return mTxTimeMillis; 3160 } 3161 3162 /** 3163 * @return a LongSamplingCounter, measuring power use in milli-ampere milliseconds (mAmS). 3164 */ 3165 @Override getPowerCounter()3166 public LongSamplingCounter getPowerCounter() { 3167 return mPowerDrainMaMs; 3168 } 3169 3170 /** 3171 * @return a LongSamplingCounter, measuring actual monitored rail energy consumed 3172 * milli-ampere milli-seconds (mAmS). 3173 */ 3174 @Override getMonitoredRailChargeConsumedMaMs()3175 public LongSamplingCounter getMonitoredRailChargeConsumedMaMs() { 3176 return mMonitoredRailChargeConsumedMaMs; 3177 } 3178 } 3179 3180 /** Get Resource Power Manager stats. Create a new one if it doesn't already exist. */ getRpmTimerLocked(String name)3181 public SamplingTimer getRpmTimerLocked(String name) { 3182 SamplingTimer rpmt = mRpmStats.get(name); 3183 if (rpmt == null) { 3184 rpmt = new SamplingTimer(mClocks, mOnBatteryTimeBase); 3185 mRpmStats.put(name, rpmt); 3186 } 3187 return rpmt; 3188 } 3189 3190 /** Get Screen-off Resource Power Manager stats. Create new one if it doesn't already exist. */ getScreenOffRpmTimerLocked(String name)3191 public SamplingTimer getScreenOffRpmTimerLocked(String name) { 3192 SamplingTimer rpmt = mScreenOffRpmStats.get(name); 3193 if (rpmt == null) { 3194 rpmt = new SamplingTimer(mClocks, mOnBatteryScreenOffTimeBase); 3195 mScreenOffRpmStats.put(name, rpmt); 3196 } 3197 return rpmt; 3198 } 3199 3200 /* 3201 * Get the wakeup reason counter, and create a new one if one 3202 * doesn't already exist. 3203 */ getWakeupReasonTimerLocked(String name)3204 public SamplingTimer getWakeupReasonTimerLocked(String name) { 3205 SamplingTimer timer = mWakeupReasonStats.get(name); 3206 if (timer == null) { 3207 timer = new SamplingTimer(mClocks, mOnBatteryTimeBase); 3208 mWakeupReasonStats.put(name, timer); 3209 } 3210 return timer; 3211 } 3212 3213 /* 3214 * Get the KernelWakelockTimer associated with name, and create a new one if one 3215 * doesn't already exist. 3216 */ getKernelWakelockTimerLocked(String name)3217 public SamplingTimer getKernelWakelockTimerLocked(String name) { 3218 SamplingTimer kwlt = mKernelWakelockStats.get(name); 3219 if (kwlt == null) { 3220 kwlt = new SamplingTimer(mClocks, mOnBatteryScreenOffTimeBase); 3221 mKernelWakelockStats.put(name, kwlt); 3222 } 3223 return kwlt; 3224 } 3225 getKernelMemoryTimerLocked(long bucket)3226 public SamplingTimer getKernelMemoryTimerLocked(long bucket) { 3227 SamplingTimer kmt = mKernelMemoryStats.get(bucket); 3228 if (kmt == null) { 3229 kmt = new SamplingTimer(mClocks, mOnBatteryTimeBase); 3230 mKernelMemoryStats.put(bucket, kmt); 3231 } 3232 return kmt; 3233 } 3234 writeHistoryTag(HistoryTag tag)3235 private int writeHistoryTag(HistoryTag tag) { 3236 Integer idxObj = mHistoryTagPool.get(tag); 3237 int idx; 3238 if (idxObj != null) { 3239 idx = idxObj; 3240 } else { 3241 idx = mNextHistoryTagIdx; 3242 HistoryTag key = new HistoryTag(); 3243 key.setTo(tag); 3244 tag.poolIdx = idx; 3245 mHistoryTagPool.put(key, idx); 3246 mNextHistoryTagIdx++; 3247 mNumHistoryTagChars += key.string.length() + 1; 3248 } 3249 return idx; 3250 } 3251 3252 /* 3253 The history delta format uses flags to denote further data in subsequent ints in the parcel. 3254 3255 There is always the first token, which may contain the delta time, or an indicator of 3256 the length of the time (int or long) following this token. 3257 3258 First token: always present, 3259 31 23 15 7 0 3260 █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█ 3261 3262 T: the delta time if it is <= 0x7fffd. Otherwise 0x7fffe indicates an int immediately 3263 follows containing the time, and 0x7ffff indicates a long immediately follows with the 3264 delta time. 3265 A: battery level changed and an int follows with battery data. 3266 B: state changed and an int follows with state change data. 3267 C: state2 has changed and an int follows with state2 change data. 3268 D: wakelock/wakereason has changed and an wakelock/wakereason struct follows. 3269 E: event data has changed and an event struct follows. 3270 F: battery charge in coulombs has changed and an int with the charge follows. 3271 G: state flag denoting that the mobile radio was active. 3272 H: state flag denoting that the wifi radio was active. 3273 I: state flag denoting that a wifi scan occurred. 3274 J: state flag denoting that a wifi full lock was held. 3275 K: state flag denoting that the gps was on. 3276 L: state flag denoting that a wakelock was held. 3277 M: state flag denoting that the cpu was running. 3278 3279 Time int/long: if T in the first token is 0x7ffff or 0x7fffe, then an int or long follows 3280 with the time delta. 3281 3282 Battery level int: if A in the first token is set, 3283 31 23 15 7 0 3284 █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█ 3285 3286 D: indicates that extra history details follow. 3287 V: the battery voltage. 3288 T: the battery temperature. 3289 L: the battery level (out of 100). 3290 3291 State change int: if B in the first token is set, 3292 31 23 15 7 0 3293 █S|S|S|H|H|H|P|P█F|E|D|C|B| | |A█ | | | | | | | █ | | | | | | | █ 3294 3295 A: wifi multicast was on. 3296 B: battery was plugged in. 3297 C: screen was on. 3298 D: phone was scanning for signal. 3299 E: audio was on. 3300 F: a sensor was active. 3301 3302 State2 change int: if C in the first token is set, 3303 31 23 15 7 0 3304 █M|L|K|J|I|H|H|G█F|E|D|C| | | | █ | | | | | | | █ |B|B|B|A|A|A|A█ 3305 3306 A: 4 bits indicating the wifi supplicant state: {@link BatteryStats#WIFI_SUPPL_STATE_NAMES}. 3307 B: 3 bits indicating the wifi signal strength: 0, 1, 2, 3, 4. 3308 C: a bluetooth scan was active. 3309 D: the camera was active. 3310 E: bluetooth was on. 3311 F: a phone call was active. 3312 G: the device was charging. 3313 H: 2 bits indicating the device-idle (doze) state: off, light, full 3314 I: the flashlight was on. 3315 J: wifi was on. 3316 K: wifi was running. 3317 L: video was playing. 3318 M: power save mode was on. 3319 3320 Wakelock/wakereason struct: if D in the first token is set, 3321 TODO(adamlesinski): describe wakelock/wakereason struct. 3322 3323 Event struct: if E in the first token is set, 3324 TODO(adamlesinski): describe the event struct. 3325 3326 History step details struct: if D in the battery level int is set, 3327 TODO(adamlesinski): describe the history step details struct. 3328 3329 Battery charge int: if F in the first token is set, an int representing the battery charge 3330 in coulombs follows. 3331 */ 3332 3333 // Part of initial delta int that specifies the time delta. 3334 static final int DELTA_TIME_MASK = 0x7ffff; 3335 static final int DELTA_TIME_LONG = 0x7ffff; // The delta is a following long 3336 static final int DELTA_TIME_INT = 0x7fffe; // The delta is a following int 3337 static final int DELTA_TIME_ABS = 0x7fffd; // Following is an entire abs update. 3338 // Flag in delta int: a new battery level int follows. 3339 static final int DELTA_BATTERY_LEVEL_FLAG = 0x00080000; 3340 // Flag in delta int: a new full state and battery status int follows. 3341 static final int DELTA_STATE_FLAG = 0x00100000; 3342 // Flag in delta int: a new full state2 int follows. 3343 static final int DELTA_STATE2_FLAG = 0x00200000; 3344 // Flag in delta int: contains a wakelock or wakeReason tag. 3345 static final int DELTA_WAKELOCK_FLAG = 0x00400000; 3346 // Flag in delta int: contains an event description. 3347 static final int DELTA_EVENT_FLAG = 0x00800000; 3348 // Flag in delta int: contains the battery charge count in uAh. 3349 static final int DELTA_BATTERY_CHARGE_FLAG = 0x01000000; 3350 // These upper bits are the frequently changing state bits. 3351 static final int DELTA_STATE_MASK = 0xfe000000; 3352 3353 // These are the pieces of battery state that are packed in to the upper bits of 3354 // the state int that have been packed in to the first delta int. They must fit 3355 // in STATE_BATTERY_MASK. 3356 static final int STATE_BATTERY_MASK = 0xff000000; 3357 static final int STATE_BATTERY_STATUS_MASK = 0x00000007; 3358 static final int STATE_BATTERY_STATUS_SHIFT = 29; 3359 static final int STATE_BATTERY_HEALTH_MASK = 0x00000007; 3360 static final int STATE_BATTERY_HEALTH_SHIFT = 26; 3361 static final int STATE_BATTERY_PLUG_MASK = 0x00000003; 3362 static final int STATE_BATTERY_PLUG_SHIFT = 24; 3363 3364 // We use the low bit of the battery state int to indicate that we have full details 3365 // from a battery level change. 3366 static final int BATTERY_DELTA_LEVEL_FLAG = 0x00000001; 3367 writeHistoryDelta(Parcel dest, HistoryItem cur, HistoryItem last)3368 public void writeHistoryDelta(Parcel dest, HistoryItem cur, HistoryItem last) { 3369 if (last == null || cur.cmd != HistoryItem.CMD_UPDATE) { 3370 dest.writeInt(DELTA_TIME_ABS); 3371 cur.writeToParcel(dest, 0); 3372 return; 3373 } 3374 3375 final long deltaTime = cur.time - last.time; 3376 final int lastBatteryLevelInt = buildBatteryLevelInt(last); 3377 final int lastStateInt = buildStateInt(last); 3378 3379 int deltaTimeToken; 3380 if (deltaTime < 0 || deltaTime > Integer.MAX_VALUE) { 3381 deltaTimeToken = DELTA_TIME_LONG; 3382 } else if (deltaTime >= DELTA_TIME_ABS) { 3383 deltaTimeToken = DELTA_TIME_INT; 3384 } else { 3385 deltaTimeToken = (int)deltaTime; 3386 } 3387 int firstToken = deltaTimeToken | (cur.states&DELTA_STATE_MASK); 3388 final int includeStepDetails = mLastHistoryStepLevel > cur.batteryLevel 3389 ? BATTERY_DELTA_LEVEL_FLAG : 0; 3390 final boolean computeStepDetails = includeStepDetails != 0 3391 || mLastHistoryStepDetails == null; 3392 final int batteryLevelInt = buildBatteryLevelInt(cur) | includeStepDetails; 3393 final boolean batteryLevelIntChanged = batteryLevelInt != lastBatteryLevelInt; 3394 if (batteryLevelIntChanged) { 3395 firstToken |= DELTA_BATTERY_LEVEL_FLAG; 3396 } 3397 final int stateInt = buildStateInt(cur); 3398 final boolean stateIntChanged = stateInt != lastStateInt; 3399 if (stateIntChanged) { 3400 firstToken |= DELTA_STATE_FLAG; 3401 } 3402 final boolean state2IntChanged = cur.states2 != last.states2; 3403 if (state2IntChanged) { 3404 firstToken |= DELTA_STATE2_FLAG; 3405 } 3406 if (cur.wakelockTag != null || cur.wakeReasonTag != null) { 3407 firstToken |= DELTA_WAKELOCK_FLAG; 3408 } 3409 if (cur.eventCode != HistoryItem.EVENT_NONE) { 3410 firstToken |= DELTA_EVENT_FLAG; 3411 } 3412 3413 final boolean batteryChargeChanged = cur.batteryChargeUah != last.batteryChargeUah; 3414 if (batteryChargeChanged) { 3415 firstToken |= DELTA_BATTERY_CHARGE_FLAG; 3416 } 3417 dest.writeInt(firstToken); 3418 if (DEBUG) Slog.i(TAG, "WRITE DELTA: firstToken=0x" + Integer.toHexString(firstToken) 3419 + " deltaTime=" + deltaTime); 3420 3421 if (deltaTimeToken >= DELTA_TIME_INT) { 3422 if (deltaTimeToken == DELTA_TIME_INT) { 3423 if (DEBUG) Slog.i(TAG, "WRITE DELTA: int deltaTime=" + (int)deltaTime); 3424 dest.writeInt((int)deltaTime); 3425 } else { 3426 if (DEBUG) Slog.i(TAG, "WRITE DELTA: long deltaTime=" + deltaTime); 3427 dest.writeLong(deltaTime); 3428 } 3429 } 3430 if (batteryLevelIntChanged) { 3431 dest.writeInt(batteryLevelInt); 3432 if (DEBUG) Slog.i(TAG, "WRITE DELTA: batteryToken=0x" 3433 + Integer.toHexString(batteryLevelInt) 3434 + " batteryLevel=" + cur.batteryLevel 3435 + " batteryTemp=" + cur.batteryTemperature 3436 + " batteryVolt=" + (int)cur.batteryVoltage); 3437 } 3438 if (stateIntChanged) { 3439 dest.writeInt(stateInt); 3440 if (DEBUG) Slog.i(TAG, "WRITE DELTA: stateToken=0x" 3441 + Integer.toHexString(stateInt) 3442 + " batteryStatus=" + cur.batteryStatus 3443 + " batteryHealth=" + cur.batteryHealth 3444 + " batteryPlugType=" + cur.batteryPlugType 3445 + " states=0x" + Integer.toHexString(cur.states)); 3446 } 3447 if (state2IntChanged) { 3448 dest.writeInt(cur.states2); 3449 if (DEBUG) Slog.i(TAG, "WRITE DELTA: states2=0x" 3450 + Integer.toHexString(cur.states2)); 3451 } 3452 if (cur.wakelockTag != null || cur.wakeReasonTag != null) { 3453 int wakeLockIndex; 3454 int wakeReasonIndex; 3455 if (cur.wakelockTag != null) { 3456 wakeLockIndex = writeHistoryTag(cur.wakelockTag); 3457 if (DEBUG) Slog.i(TAG, "WRITE DELTA: wakelockTag=#" + cur.wakelockTag.poolIdx 3458 + " " + cur.wakelockTag.uid + ":" + cur.wakelockTag.string); 3459 } else { 3460 wakeLockIndex = 0xffff; 3461 } 3462 if (cur.wakeReasonTag != null) { 3463 wakeReasonIndex = writeHistoryTag(cur.wakeReasonTag); 3464 if (DEBUG) Slog.i(TAG, "WRITE DELTA: wakeReasonTag=#" + cur.wakeReasonTag.poolIdx 3465 + " " + cur.wakeReasonTag.uid + ":" + cur.wakeReasonTag.string); 3466 } else { 3467 wakeReasonIndex = 0xffff; 3468 } 3469 dest.writeInt((wakeReasonIndex<<16) | wakeLockIndex); 3470 } 3471 if (cur.eventCode != HistoryItem.EVENT_NONE) { 3472 int index = writeHistoryTag(cur.eventTag); 3473 int codeAndIndex = (cur.eventCode&0xffff) | (index<<16); 3474 dest.writeInt(codeAndIndex); 3475 if (DEBUG) Slog.i(TAG, "WRITE DELTA: event=" + cur.eventCode + " tag=#" 3476 + cur.eventTag.poolIdx + " " + cur.eventTag.uid + ":" 3477 + cur.eventTag.string); 3478 } 3479 if (computeStepDetails) { 3480 if (mPlatformIdleStateCallback != null) { 3481 mCurHistoryStepDetails.statSubsystemPowerState = 3482 mPlatformIdleStateCallback.getSubsystemLowPowerStats(); 3483 if (DEBUG) Slog.i(TAG, "WRITE SubsystemPowerState:" + 3484 mCurHistoryStepDetails.statSubsystemPowerState); 3485 3486 } 3487 computeHistoryStepDetails(mCurHistoryStepDetails, mLastHistoryStepDetails); 3488 if (includeStepDetails != 0) { 3489 mCurHistoryStepDetails.writeToParcel(dest); 3490 } 3491 cur.stepDetails = mCurHistoryStepDetails; 3492 mLastHistoryStepDetails = mCurHistoryStepDetails; 3493 } else { 3494 cur.stepDetails = null; 3495 } 3496 if (mLastHistoryStepLevel < cur.batteryLevel) { 3497 mLastHistoryStepDetails = null; 3498 } 3499 mLastHistoryStepLevel = cur.batteryLevel; 3500 3501 if (batteryChargeChanged) { 3502 if (DEBUG) Slog.i(TAG, "WRITE DELTA: batteryChargeUah=" + cur.batteryChargeUah); 3503 dest.writeInt(cur.batteryChargeUah); 3504 } 3505 dest.writeDouble(cur.modemRailChargeMah); 3506 dest.writeDouble(cur.wifiRailChargeMah); 3507 } 3508 buildBatteryLevelInt(HistoryItem h)3509 private int buildBatteryLevelInt(HistoryItem h) { 3510 return ((((int)h.batteryLevel)<<25)&0xfe000000) 3511 | ((((int)h.batteryTemperature)<<15)&0x01ff8000) 3512 | ((((int)h.batteryVoltage)<<1)&0x00007ffe); 3513 } 3514 readBatteryLevelInt(int batteryLevelInt, HistoryItem out)3515 private void readBatteryLevelInt(int batteryLevelInt, HistoryItem out) { 3516 out.batteryLevel = (byte)((batteryLevelInt & 0xfe000000) >>> 25); 3517 out.batteryTemperature = (short)((batteryLevelInt & 0x01ff8000) >>> 15); 3518 out.batteryVoltage = (char)((batteryLevelInt & 0x00007ffe) >>> 1); 3519 } 3520 buildStateInt(HistoryItem h)3521 private int buildStateInt(HistoryItem h) { 3522 int plugType = 0; 3523 if ((h.batteryPlugType&BatteryManager.BATTERY_PLUGGED_AC) != 0) { 3524 plugType = 1; 3525 } else if ((h.batteryPlugType&BatteryManager.BATTERY_PLUGGED_USB) != 0) { 3526 plugType = 2; 3527 } else if ((h.batteryPlugType&BatteryManager.BATTERY_PLUGGED_WIRELESS) != 0) { 3528 plugType = 3; 3529 } 3530 return ((h.batteryStatus&STATE_BATTERY_STATUS_MASK)<<STATE_BATTERY_STATUS_SHIFT) 3531 | ((h.batteryHealth&STATE_BATTERY_HEALTH_MASK)<<STATE_BATTERY_HEALTH_SHIFT) 3532 | ((plugType&STATE_BATTERY_PLUG_MASK)<<STATE_BATTERY_PLUG_SHIFT) 3533 | (h.states&(~STATE_BATTERY_MASK)); 3534 } 3535 computeHistoryStepDetails(final HistoryStepDetails out, final HistoryStepDetails last)3536 private void computeHistoryStepDetails(final HistoryStepDetails out, 3537 final HistoryStepDetails last) { 3538 final HistoryStepDetails tmp = last != null ? mTmpHistoryStepDetails : out; 3539 3540 // Perform a CPU update right after we do this collection, so we have started 3541 // collecting good data for the next step. 3542 requestImmediateCpuUpdate(); 3543 3544 if (last == null) { 3545 // We are not generating a delta, so all we need to do is reset the stats 3546 // we will later be doing a delta from. 3547 final int NU = mUidStats.size(); 3548 for (int i=0; i<NU; i++) { 3549 final BatteryStatsImpl.Uid uid = mUidStats.valueAt(i); 3550 uid.mLastStepUserTimeMs = uid.mCurStepUserTimeMs; 3551 uid.mLastStepSystemTimeMs = uid.mCurStepSystemTimeMs; 3552 } 3553 mLastStepCpuUserTimeMs = mCurStepCpuUserTimeMs; 3554 mLastStepCpuSystemTimeMs = mCurStepCpuSystemTimeMs; 3555 mLastStepStatUserTimeMs = mCurStepStatUserTimeMs; 3556 mLastStepStatSystemTimeMs = mCurStepStatSystemTimeMs; 3557 mLastStepStatIOWaitTimeMs = mCurStepStatIOWaitTimeMs; 3558 mLastStepStatIrqTimeMs = mCurStepStatIrqTimeMs; 3559 mLastStepStatSoftIrqTimeMs = mCurStepStatSoftIrqTimeMs; 3560 mLastStepStatIdleTimeMs = mCurStepStatIdleTimeMs; 3561 tmp.clear(); 3562 return; 3563 } 3564 if (DEBUG) { 3565 Slog.d(TAG, "Step stats last: user=" + mLastStepCpuUserTimeMs + " sys=" 3566 + mLastStepStatSystemTimeMs + " io=" + mLastStepStatIOWaitTimeMs 3567 + " irq=" + mLastStepStatIrqTimeMs + " sirq=" 3568 + mLastStepStatSoftIrqTimeMs + " idle=" + mLastStepStatIdleTimeMs); 3569 Slog.d(TAG, "Step stats cur: user=" + mCurStepCpuUserTimeMs + " sys=" 3570 + mCurStepStatSystemTimeMs + " io=" + mCurStepStatIOWaitTimeMs 3571 + " irq=" + mCurStepStatIrqTimeMs + " sirq=" 3572 + mCurStepStatSoftIrqTimeMs + " idle=" + mCurStepStatIdleTimeMs); 3573 } 3574 out.userTime = (int) (mCurStepCpuUserTimeMs - mLastStepCpuUserTimeMs); 3575 out.systemTime = (int) (mCurStepCpuSystemTimeMs - mLastStepCpuSystemTimeMs); 3576 out.statUserTime = (int) (mCurStepStatUserTimeMs - mLastStepStatUserTimeMs); 3577 out.statSystemTime = (int) (mCurStepStatSystemTimeMs - mLastStepStatSystemTimeMs); 3578 out.statIOWaitTime = (int) (mCurStepStatIOWaitTimeMs - mLastStepStatIOWaitTimeMs); 3579 out.statIrqTime = (int) (mCurStepStatIrqTimeMs - mLastStepStatIrqTimeMs); 3580 out.statSoftIrqTime = (int) (mCurStepStatSoftIrqTimeMs - mLastStepStatSoftIrqTimeMs); 3581 out.statIdlTime = (int) (mCurStepStatIdleTimeMs - mLastStepStatIdleTimeMs); 3582 out.appCpuUid1 = out.appCpuUid2 = out.appCpuUid3 = -1; 3583 out.appCpuUTime1 = out.appCpuUTime2 = out.appCpuUTime3 = 0; 3584 out.appCpuSTime1 = out.appCpuSTime2 = out.appCpuSTime3 = 0; 3585 final int NU = mUidStats.size(); 3586 for (int i=0; i<NU; i++) { 3587 final BatteryStatsImpl.Uid uid = mUidStats.valueAt(i); 3588 final int totalUTimeMs = (int) (uid.mCurStepUserTimeMs - uid.mLastStepUserTimeMs); 3589 final int totalSTimeMs = (int) (uid.mCurStepSystemTimeMs - uid.mLastStepSystemTimeMs); 3590 final int totalTimeMs = totalUTimeMs + totalSTimeMs; 3591 uid.mLastStepUserTimeMs = uid.mCurStepUserTimeMs; 3592 uid.mLastStepSystemTimeMs = uid.mCurStepSystemTimeMs; 3593 if (totalTimeMs <= (out.appCpuUTime3 + out.appCpuSTime3)) { 3594 continue; 3595 } 3596 if (totalTimeMs <= (out.appCpuUTime2 + out.appCpuSTime2)) { 3597 out.appCpuUid3 = uid.mUid; 3598 out.appCpuUTime3 = totalUTimeMs; 3599 out.appCpuSTime3 = totalSTimeMs; 3600 } else { 3601 out.appCpuUid3 = out.appCpuUid2; 3602 out.appCpuUTime3 = out.appCpuUTime2; 3603 out.appCpuSTime3 = out.appCpuSTime2; 3604 if (totalTimeMs <= (out.appCpuUTime1 + out.appCpuSTime1)) { 3605 out.appCpuUid2 = uid.mUid; 3606 out.appCpuUTime2 = totalUTimeMs; 3607 out.appCpuSTime2 = totalSTimeMs; 3608 } else { 3609 out.appCpuUid2 = out.appCpuUid1; 3610 out.appCpuUTime2 = out.appCpuUTime1; 3611 out.appCpuSTime2 = out.appCpuSTime1; 3612 out.appCpuUid1 = uid.mUid; 3613 out.appCpuUTime1 = totalUTimeMs; 3614 out.appCpuSTime1 = totalSTimeMs; 3615 } 3616 } 3617 } 3618 mLastStepCpuUserTimeMs = mCurStepCpuUserTimeMs; 3619 mLastStepCpuSystemTimeMs = mCurStepCpuSystemTimeMs; 3620 mLastStepStatUserTimeMs = mCurStepStatUserTimeMs; 3621 mLastStepStatSystemTimeMs = mCurStepStatSystemTimeMs; 3622 mLastStepStatIOWaitTimeMs = mCurStepStatIOWaitTimeMs; 3623 mLastStepStatIrqTimeMs = mCurStepStatIrqTimeMs; 3624 mLastStepStatSoftIrqTimeMs = mCurStepStatSoftIrqTimeMs; 3625 mLastStepStatIdleTimeMs = mCurStepStatIdleTimeMs; 3626 } 3627 3628 @Override commitCurrentHistoryBatchLocked()3629 public void commitCurrentHistoryBatchLocked() { 3630 mHistoryLastWritten.cmd = HistoryItem.CMD_NULL; 3631 } 3632 createFakeHistoryEvents(long numEvents)3633 public void createFakeHistoryEvents(long numEvents) { 3634 final long elapsedRealtimeMs = mClocks.elapsedRealtime(); 3635 final long uptimeMs = mClocks.uptimeMillis(); 3636 for(long i = 0; i < numEvents; i++) { 3637 noteLongPartialWakelockStart("name1", "historyName1", 1000, 3638 elapsedRealtimeMs, uptimeMs); 3639 noteLongPartialWakelockFinish("name1", "historyName1", 1000, 3640 elapsedRealtimeMs, uptimeMs); 3641 } 3642 } 3643 addHistoryBufferLocked(long elapsedRealtimeMs, long uptimeMs, HistoryItem cur)3644 void addHistoryBufferLocked(long elapsedRealtimeMs, long uptimeMs, HistoryItem cur) { 3645 if (!mHaveBatteryLevel || !mRecordingHistory) { 3646 return; 3647 } 3648 3649 final long timeDiffMs = (mHistoryBaseTimeMs + elapsedRealtimeMs) - mHistoryLastWritten.time; 3650 final int diffStates = mHistoryLastWritten.states^(cur.states&mActiveHistoryStates); 3651 final int diffStates2 = mHistoryLastWritten.states2^(cur.states2&mActiveHistoryStates2); 3652 final int lastDiffStates = mHistoryLastWritten.states^mHistoryLastLastWritten.states; 3653 final int lastDiffStates2 = mHistoryLastWritten.states2^mHistoryLastLastWritten.states2; 3654 if (DEBUG) { 3655 Slog.i(TAG, "ADD: tdelta=" + timeDiffMs + " diff=" 3656 + Integer.toHexString(diffStates) + " lastDiff=" 3657 + Integer.toHexString(lastDiffStates) + " diff2=" 3658 + Integer.toHexString(diffStates2) + " lastDiff2=" 3659 + Integer.toHexString(lastDiffStates2)); 3660 } 3661 if (mHistoryBufferLastPos >= 0 && mHistoryLastWritten.cmd == HistoryItem.CMD_UPDATE 3662 && timeDiffMs < 1000 && (diffStates & lastDiffStates) == 0 3663 && (diffStates2&lastDiffStates2) == 0 3664 && (mHistoryLastWritten.wakelockTag == null || cur.wakelockTag == null) 3665 && (mHistoryLastWritten.wakeReasonTag == null || cur.wakeReasonTag == null) 3666 && mHistoryLastWritten.stepDetails == null 3667 && (mHistoryLastWritten.eventCode == HistoryItem.EVENT_NONE 3668 || cur.eventCode == HistoryItem.EVENT_NONE) 3669 && mHistoryLastWritten.batteryLevel == cur.batteryLevel 3670 && mHistoryLastWritten.batteryStatus == cur.batteryStatus 3671 && mHistoryLastWritten.batteryHealth == cur.batteryHealth 3672 && mHistoryLastWritten.batteryPlugType == cur.batteryPlugType 3673 && mHistoryLastWritten.batteryTemperature == cur.batteryTemperature 3674 && mHistoryLastWritten.batteryVoltage == cur.batteryVoltage) { 3675 // We can merge this new change in with the last one. Merging is 3676 // allowed as long as only the states have changed, and within those states 3677 // as long as no bit has changed both between now and the last entry, as 3678 // well as the last entry and the one before it (so we capture any toggles). 3679 if (DEBUG) Slog.i(TAG, "ADD: rewinding back to " + mHistoryBufferLastPos); 3680 mHistoryBuffer.setDataSize(mHistoryBufferLastPos); 3681 mHistoryBuffer.setDataPosition(mHistoryBufferLastPos); 3682 mHistoryBufferLastPos = -1; 3683 elapsedRealtimeMs = mHistoryLastWritten.time - mHistoryBaseTimeMs; 3684 // If the last written history had a wakelock tag, we need to retain it. 3685 // Note that the condition above made sure that we aren't in a case where 3686 // both it and the current history item have a wakelock tag. 3687 if (mHistoryLastWritten.wakelockTag != null) { 3688 cur.wakelockTag = cur.localWakelockTag; 3689 cur.wakelockTag.setTo(mHistoryLastWritten.wakelockTag); 3690 } 3691 // If the last written history had a wake reason tag, we need to retain it. 3692 // Note that the condition above made sure that we aren't in a case where 3693 // both it and the current history item have a wakelock tag. 3694 if (mHistoryLastWritten.wakeReasonTag != null) { 3695 cur.wakeReasonTag = cur.localWakeReasonTag; 3696 cur.wakeReasonTag.setTo(mHistoryLastWritten.wakeReasonTag); 3697 } 3698 // If the last written history had an event, we need to retain it. 3699 // Note that the condition above made sure that we aren't in a case where 3700 // both it and the current history item have an event. 3701 if (mHistoryLastWritten.eventCode != HistoryItem.EVENT_NONE) { 3702 cur.eventCode = mHistoryLastWritten.eventCode; 3703 cur.eventTag = cur.localEventTag; 3704 cur.eventTag.setTo(mHistoryLastWritten.eventTag); 3705 } 3706 mHistoryLastWritten.setTo(mHistoryLastLastWritten); 3707 } 3708 final int dataSize = mHistoryBuffer.dataSize(); 3709 3710 if (dataSize >= mConstants.MAX_HISTORY_BUFFER) { 3711 //open a new history file. 3712 final long start = SystemClock.uptimeMillis(); 3713 writeHistoryLocked(true); 3714 if (DEBUG) { 3715 Slog.d(TAG, "addHistoryBufferLocked writeHistoryLocked takes ms:" 3716 + (SystemClock.uptimeMillis() - start)); 3717 } 3718 mBatteryStatsHistory.startNextFile(); 3719 mHistoryBuffer.setDataSize(0); 3720 mHistoryBuffer.setDataPosition(0); 3721 mHistoryBuffer.setDataCapacity(mConstants.MAX_HISTORY_BUFFER / 2); 3722 mHistoryBufferLastPos = -1; 3723 HistoryItem newItem = new HistoryItem(); 3724 newItem.setTo(cur); 3725 startRecordingHistory(elapsedRealtimeMs, uptimeMs, false); 3726 addHistoryBufferLocked(elapsedRealtimeMs, HistoryItem.CMD_UPDATE, newItem); 3727 return; 3728 } 3729 3730 if (dataSize == 0) { 3731 // The history is currently empty; we need it to start with a time stamp. 3732 cur.currentTime = mClocks.currentTimeMillis(); 3733 addHistoryBufferLocked(elapsedRealtimeMs, HistoryItem.CMD_RESET, cur); 3734 } 3735 addHistoryBufferLocked(elapsedRealtimeMs, HistoryItem.CMD_UPDATE, cur); 3736 } 3737 addHistoryBufferLocked(long elapsedRealtimeMs, byte cmd, HistoryItem cur)3738 private void addHistoryBufferLocked(long elapsedRealtimeMs, byte cmd, HistoryItem cur) { 3739 if (mBatteryStatsHistoryIterator != null) { 3740 throw new IllegalStateException("Can't do this while iterating history!"); 3741 } 3742 mHistoryBufferLastPos = mHistoryBuffer.dataPosition(); 3743 mHistoryLastLastWritten.setTo(mHistoryLastWritten); 3744 mHistoryLastWritten.setTo(mHistoryBaseTimeMs + elapsedRealtimeMs, cmd, cur); 3745 mHistoryLastWritten.states &= mActiveHistoryStates; 3746 mHistoryLastWritten.states2 &= mActiveHistoryStates2; 3747 writeHistoryDelta(mHistoryBuffer, mHistoryLastWritten, mHistoryLastLastWritten); 3748 mLastHistoryElapsedRealtimeMs = elapsedRealtimeMs; 3749 cur.wakelockTag = null; 3750 cur.wakeReasonTag = null; 3751 cur.eventCode = HistoryItem.EVENT_NONE; 3752 cur.eventTag = null; 3753 if (DEBUG_HISTORY) Slog.i(TAG, "Writing history buffer: was " + mHistoryBufferLastPos 3754 + " now " + mHistoryBuffer.dataPosition() 3755 + " size is now " + mHistoryBuffer.dataSize()); 3756 } 3757 3758 int mChangedStates = 0; 3759 int mChangedStates2 = 0; 3760 addHistoryRecordLocked(long elapsedRealtimeMs, long uptimeMs)3761 void addHistoryRecordLocked(long elapsedRealtimeMs, long uptimeMs) { 3762 if (mTrackRunningHistoryElapsedRealtimeMs != 0) { 3763 final long diffElapsedMs = elapsedRealtimeMs - mTrackRunningHistoryElapsedRealtimeMs; 3764 final long diffUptimeMs = uptimeMs - mTrackRunningHistoryUptimeMs; 3765 if (diffUptimeMs < (diffElapsedMs - 20)) { 3766 final long wakeElapsedTimeMs = elapsedRealtimeMs - (diffElapsedMs - diffUptimeMs); 3767 mHistoryAddTmp.setTo(mHistoryLastWritten); 3768 mHistoryAddTmp.wakelockTag = null; 3769 mHistoryAddTmp.wakeReasonTag = null; 3770 mHistoryAddTmp.eventCode = HistoryItem.EVENT_NONE; 3771 mHistoryAddTmp.states &= ~HistoryItem.STATE_CPU_RUNNING_FLAG; 3772 addHistoryRecordInnerLocked(wakeElapsedTimeMs, uptimeMs, mHistoryAddTmp); 3773 } 3774 } 3775 mHistoryCur.states |= HistoryItem.STATE_CPU_RUNNING_FLAG; 3776 mTrackRunningHistoryElapsedRealtimeMs = elapsedRealtimeMs; 3777 mTrackRunningHistoryUptimeMs = uptimeMs; 3778 addHistoryRecordInnerLocked(elapsedRealtimeMs, uptimeMs, mHistoryCur); 3779 } 3780 addHistoryRecordInnerLocked(long elapsedRealtimeMs, long uptimeMs, HistoryItem cur)3781 void addHistoryRecordInnerLocked(long elapsedRealtimeMs, long uptimeMs, HistoryItem cur) { 3782 addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, cur); 3783 } 3784 addHistoryEventLocked(long elapsedRealtimeMs, long uptimeMs, int code, String name, int uid)3785 public void addHistoryEventLocked(long elapsedRealtimeMs, long uptimeMs, int code, 3786 String name, int uid) { 3787 mHistoryCur.eventCode = code; 3788 mHistoryCur.eventTag = mHistoryCur.localEventTag; 3789 mHistoryCur.eventTag.string = name; 3790 mHistoryCur.eventTag.uid = uid; 3791 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 3792 } 3793 addHistoryRecordLocked(long elapsedRealtimeMs, long uptimeMs, byte cmd, HistoryItem cur)3794 void addHistoryRecordLocked(long elapsedRealtimeMs, long uptimeMs, byte cmd, HistoryItem cur) { 3795 HistoryItem rec = mHistoryCache; 3796 if (rec != null) { 3797 mHistoryCache = rec.next; 3798 } else { 3799 rec = new HistoryItem(); 3800 } 3801 rec.setTo(mHistoryBaseTimeMs + elapsedRealtimeMs, cmd, cur); 3802 3803 addHistoryRecordLocked(rec); 3804 } 3805 addHistoryRecordLocked(HistoryItem rec)3806 void addHistoryRecordLocked(HistoryItem rec) { 3807 mNumHistoryItems++; 3808 rec.next = null; 3809 mHistoryLastEnd = mHistoryEnd; 3810 if (mHistoryEnd != null) { 3811 mHistoryEnd.next = rec; 3812 mHistoryEnd = rec; 3813 } else { 3814 mHistory = mHistoryEnd = rec; 3815 } 3816 } 3817 clearHistoryLocked()3818 void clearHistoryLocked() { 3819 if (DEBUG_HISTORY) Slog.i(TAG, "********** CLEARING HISTORY!"); 3820 mHistoryBaseTimeMs = 0; 3821 mLastHistoryElapsedRealtimeMs = 0; 3822 mTrackRunningHistoryElapsedRealtimeMs = 0; 3823 mTrackRunningHistoryUptimeMs = 0; 3824 3825 mHistoryBuffer.setDataSize(0); 3826 mHistoryBuffer.setDataPosition(0); 3827 mHistoryBuffer.setDataCapacity(mConstants.MAX_HISTORY_BUFFER / 2); 3828 mHistoryLastLastWritten.clear(); 3829 mHistoryLastWritten.clear(); 3830 mHistoryTagPool.clear(); 3831 mNextHistoryTagIdx = 0; 3832 mNumHistoryTagChars = 0; 3833 mHistoryBufferLastPos = -1; 3834 mActiveHistoryStates = 0xffffffff; 3835 mActiveHistoryStates2 = 0xffffffff; 3836 } 3837 3838 @GuardedBy("this") updateTimeBasesLocked(boolean unplugged, int screenState, long uptimeUs, long realtimeUs)3839 public void updateTimeBasesLocked(boolean unplugged, int screenState, long uptimeUs, 3840 long realtimeUs) { 3841 final boolean screenOff = !Display.isOnState(screenState); 3842 final boolean updateOnBatteryTimeBase = unplugged != mOnBatteryTimeBase.isRunning(); 3843 final boolean updateOnBatteryScreenOffTimeBase = 3844 (unplugged && screenOff) != mOnBatteryScreenOffTimeBase.isRunning(); 3845 3846 if (updateOnBatteryScreenOffTimeBase || updateOnBatteryTimeBase) { 3847 if (updateOnBatteryScreenOffTimeBase) { 3848 updateKernelWakelocksLocked(realtimeUs); 3849 updateBatteryPropertiesLocked(); 3850 } 3851 // This if{} is only necessary due to SCREEN_OFF_RPM_STATS_ENABLED, which exists because 3852 // updateRpmStatsLocked is too slow to run each screen change. When the speed is 3853 // improved, remove the surrounding if{}. 3854 if (SCREEN_OFF_RPM_STATS_ENABLED || updateOnBatteryTimeBase) { 3855 // if either OnBattery or OnBatteryScreenOfftimebase changes. 3856 updateRpmStatsLocked(realtimeUs); 3857 } 3858 if (DEBUG_ENERGY_CPU) { 3859 Slog.d(TAG, "Updating cpu time because screen is now " 3860 + Display.stateToString(screenState) 3861 + " and battery is " + (unplugged ? "on" : "off")); 3862 } 3863 3864 mOnBatteryTimeBase.setRunning(unplugged, uptimeUs, realtimeUs); 3865 if (updateOnBatteryTimeBase) { 3866 for (int i = mUidStats.size() - 1; i >= 0; --i) { 3867 mUidStats.valueAt(i).updateOnBatteryBgTimeBase(uptimeUs, realtimeUs); 3868 } 3869 } 3870 if (updateOnBatteryScreenOffTimeBase) { 3871 mOnBatteryScreenOffTimeBase.setRunning(unplugged && screenOff, 3872 uptimeUs, realtimeUs); 3873 for (int i = mUidStats.size() - 1; i >= 0; --i) { 3874 mUidStats.valueAt(i).updateOnBatteryScreenOffBgTimeBase(uptimeUs, realtimeUs); 3875 } 3876 } 3877 } 3878 } 3879 updateBatteryPropertiesLocked()3880 private void updateBatteryPropertiesLocked() { 3881 try { 3882 IBatteryPropertiesRegistrar registrar = IBatteryPropertiesRegistrar.Stub.asInterface( 3883 ServiceManager.getService("batteryproperties")); 3884 if (registrar != null) { 3885 registrar.scheduleUpdate(); 3886 } 3887 } catch (RemoteException e) { 3888 // Ignore. 3889 } 3890 } 3891 addIsolatedUidLocked(int isolatedUid, int appUid)3892 public void addIsolatedUidLocked(int isolatedUid, int appUid) { 3893 addIsolatedUidLocked(isolatedUid, appUid, 3894 mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 3895 } 3896 addIsolatedUidLocked(int isolatedUid, int appUid, long elapsedRealtimeMs, long uptimeMs)3897 public void addIsolatedUidLocked(int isolatedUid, int appUid, 3898 long elapsedRealtimeMs, long uptimeMs) { 3899 mIsolatedUids.put(isolatedUid, appUid); 3900 final Uid u = getUidStatsLocked(appUid, elapsedRealtimeMs, uptimeMs); 3901 u.addIsolatedUid(isolatedUid); 3902 } 3903 3904 /** 3905 * Schedules a read of the latest cpu times before removing the isolated UID. 3906 * @see #removeIsolatedUidLocked(int, int, int) 3907 */ scheduleRemoveIsolatedUidLocked(int isolatedUid, int appUid)3908 public void scheduleRemoveIsolatedUidLocked(int isolatedUid, int appUid) { 3909 int curUid = mIsolatedUids.get(isolatedUid, -1); 3910 if (curUid == appUid) { 3911 if (mExternalSync != null) { 3912 mExternalSync.scheduleCpuSyncDueToRemovedUid(isolatedUid); 3913 } 3914 } 3915 } 3916 3917 /** 3918 * This should only be called after the cpu times have been read. 3919 * @see #scheduleRemoveIsolatedUidLocked(int, int) 3920 */ 3921 @GuardedBy("this") removeIsolatedUidLocked(int isolatedUid, long elapsedRealtimeMs, long uptimeMs)3922 public void removeIsolatedUidLocked(int isolatedUid, long elapsedRealtimeMs, long uptimeMs) { 3923 final int idx = mIsolatedUids.indexOfKey(isolatedUid); 3924 if (idx >= 0) { 3925 final int ownerUid = mIsolatedUids.valueAt(idx); 3926 final Uid u = getUidStatsLocked(ownerUid, elapsedRealtimeMs, uptimeMs); 3927 u.removeIsolatedUid(isolatedUid); 3928 mIsolatedUids.removeAt(idx); 3929 } 3930 mPendingRemovedUids.add(new UidToRemove(isolatedUid, elapsedRealtimeMs)); 3931 } 3932 mapUid(int uid)3933 public int mapUid(int uid) { 3934 int isolated = mIsolatedUids.get(uid, -1); 3935 return isolated > 0 ? isolated : uid; 3936 } 3937 noteEventLocked(int code, String name, int uid)3938 public void noteEventLocked(int code, String name, int uid) { 3939 noteEventLocked(code, name, uid, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 3940 } 3941 noteEventLocked(int code, String name, int uid, long elapsedRealtimeMs, long uptimeMs)3942 public void noteEventLocked(int code, String name, int uid, 3943 long elapsedRealtimeMs, long uptimeMs) { 3944 uid = mapUid(uid); 3945 if (!mActiveEvents.updateState(code, name, uid, 0)) { 3946 return; 3947 } 3948 addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, code, name, uid); 3949 } 3950 noteCurrentTimeChangedLocked()3951 public void noteCurrentTimeChangedLocked() { 3952 final long currentTime = mClocks.currentTimeMillis(); 3953 final long elapsedRealtime = mClocks.elapsedRealtime(); 3954 final long uptime = mClocks.uptimeMillis(); 3955 noteCurrentTimeChangedLocked(currentTime, elapsedRealtime, uptime); 3956 } 3957 noteCurrentTimeChangedLocked(long currentTimeMs, long elapsedRealtimeMs, long uptimeMs)3958 public void noteCurrentTimeChangedLocked(long currentTimeMs, 3959 long elapsedRealtimeMs, long uptimeMs) { 3960 recordCurrentTimeChangeLocked(currentTimeMs, elapsedRealtimeMs, uptimeMs); 3961 } 3962 noteProcessStartLocked(String name, int uid)3963 public void noteProcessStartLocked(String name, int uid) { 3964 noteProcessStartLocked(name, uid, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 3965 } 3966 noteProcessStartLocked(String name, int uid, long elapsedRealtimeMs, long uptimeMs)3967 public void noteProcessStartLocked(String name, int uid, 3968 long elapsedRealtimeMs, long uptimeMs) { 3969 uid = mapUid(uid); 3970 if (isOnBattery()) { 3971 Uid u = getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs); 3972 u.getProcessStatsLocked(name).incStartsLocked(); 3973 } 3974 if (!mActiveEvents.updateState(HistoryItem.EVENT_PROC_START, name, uid, 0)) { 3975 return; 3976 } 3977 if (!mRecordAllHistory) { 3978 return; 3979 } 3980 addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_PROC_START, name, uid); 3981 } 3982 noteProcessCrashLocked(String name, int uid)3983 public void noteProcessCrashLocked(String name, int uid) { 3984 noteProcessCrashLocked(name, uid, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 3985 } 3986 noteProcessCrashLocked(String name, int uid, long elapsedRealtimeMs, long uptimeMs)3987 public void noteProcessCrashLocked(String name, int uid, 3988 long elapsedRealtimeMs, long uptimeMs) { 3989 uid = mapUid(uid); 3990 if (isOnBattery()) { 3991 Uid u = getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs); 3992 u.getProcessStatsLocked(name).incNumCrashesLocked(); 3993 } 3994 } 3995 noteProcessAnrLocked(String name, int uid)3996 public void noteProcessAnrLocked(String name, int uid) { 3997 noteProcessAnrLocked(name, uid, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 3998 } 3999 noteProcessAnrLocked(String name, int uid, long elapsedRealtimeMs, long uptimeMs)4000 public void noteProcessAnrLocked(String name, int uid, long elapsedRealtimeMs, long uptimeMs) { 4001 uid = mapUid(uid); 4002 if (isOnBattery()) { 4003 Uid u = getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs); 4004 u.getProcessStatsLocked(name).incNumAnrsLocked(); 4005 } 4006 } 4007 noteUidProcessStateLocked(int uid, int state)4008 public void noteUidProcessStateLocked(int uid, int state) { 4009 noteUidProcessStateLocked(uid, state, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 4010 } 4011 noteUidProcessStateLocked(int uid, int state, long elapsedRealtimeMs, long uptimeMs)4012 public void noteUidProcessStateLocked(int uid, int state, 4013 long elapsedRealtimeMs, long uptimeMs) { 4014 int parentUid = mapUid(uid); 4015 if (uid != parentUid) { 4016 // Isolated UIDs process state is already rolled up into parent, so no need to track 4017 // Otherwise the parent's process state will get downgraded incorrectly 4018 return; 4019 } 4020 // TODO(b/155216561): It is possible for isolated uids to be in a higher 4021 // state than its parent uid. We should track the highest state within the union of host 4022 // and isolated uids rather than only the parent uid. 4023 FrameworkStatsLog.write(FrameworkStatsLog.UID_PROCESS_STATE_CHANGED, uid, 4024 ActivityManager.processStateAmToProto(state)); 4025 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 4026 .updateUidProcessStateLocked(state, elapsedRealtimeMs, uptimeMs); 4027 } 4028 noteProcessFinishLocked(String name, int uid)4029 public void noteProcessFinishLocked(String name, int uid) { 4030 noteProcessFinishLocked(name, uid, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 4031 } 4032 noteProcessFinishLocked(String name, int uid, long elapsedRealtimeMs, long uptimeMs)4033 public void noteProcessFinishLocked(String name, int uid, 4034 long elapsedRealtimeMs, long uptimeMs) { 4035 uid = mapUid(uid); 4036 if (!mActiveEvents.updateState(HistoryItem.EVENT_PROC_FINISH, name, uid, 0)) { 4037 return; 4038 } 4039 if (!mRecordAllHistory) { 4040 return; 4041 } 4042 addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_PROC_FINISH, 4043 name, uid); 4044 } 4045 noteSyncStartLocked(String name, int uid)4046 public void noteSyncStartLocked(String name, int uid) { 4047 noteSyncStartLocked(name, uid, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 4048 } 4049 noteSyncStartLocked(String name, int uid, long elapsedRealtimeMs, long uptimeMs)4050 public void noteSyncStartLocked(String name, int uid, long elapsedRealtimeMs, long uptimeMs) { 4051 uid = mapUid(uid); 4052 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 4053 .noteStartSyncLocked(name, elapsedRealtimeMs); 4054 if (!mActiveEvents.updateState(HistoryItem.EVENT_SYNC_START, name, uid, 0)) { 4055 return; 4056 } 4057 addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_SYNC_START, name, uid); 4058 } 4059 noteSyncFinishLocked(String name, int uid)4060 public void noteSyncFinishLocked(String name, int uid) { 4061 noteSyncFinishLocked(name, uid, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 4062 } 4063 noteSyncFinishLocked(String name, int uid, long elapsedRealtimeMs, long uptimeMs)4064 public void noteSyncFinishLocked(String name, int uid, long elapsedRealtimeMs, long uptimeMs) { 4065 uid = mapUid(uid); 4066 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 4067 .noteStopSyncLocked(name, elapsedRealtimeMs); 4068 if (!mActiveEvents.updateState(HistoryItem.EVENT_SYNC_FINISH, name, uid, 0)) { 4069 return; 4070 } 4071 addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_SYNC_FINISH, 4072 name, uid); 4073 } 4074 noteJobStartLocked(String name, int uid)4075 public void noteJobStartLocked(String name, int uid) { 4076 noteJobStartLocked(name, uid, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 4077 } 4078 noteJobStartLocked(String name, int uid, long elapsedRealtimeMs, long uptimeMs)4079 public void noteJobStartLocked(String name, int uid, long elapsedRealtimeMs, long uptimeMs) { 4080 uid = mapUid(uid); 4081 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 4082 .noteStartJobLocked(name, elapsedRealtimeMs); 4083 if (!mActiveEvents.updateState(HistoryItem.EVENT_JOB_START, name, uid, 0)) { 4084 return; 4085 } 4086 addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_JOB_START, name, uid); 4087 } 4088 noteJobFinishLocked(String name, int uid, int stopReason)4089 public void noteJobFinishLocked(String name, int uid, int stopReason) { 4090 noteJobFinishLocked(name, uid, stopReason, 4091 mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 4092 } 4093 noteJobFinishLocked(String name, int uid, int stopReason, long elapsedRealtimeMs, long uptimeMs)4094 public void noteJobFinishLocked(String name, int uid, int stopReason, 4095 long elapsedRealtimeMs, long uptimeMs) { 4096 uid = mapUid(uid); 4097 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 4098 .noteStopJobLocked(name, elapsedRealtimeMs, stopReason); 4099 if (!mActiveEvents.updateState(HistoryItem.EVENT_JOB_FINISH, name, uid, 0)) { 4100 return; 4101 } 4102 addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_JOB_FINISH, name, uid); 4103 } 4104 noteJobsDeferredLocked(int uid, int numDeferred, long sinceLast)4105 public void noteJobsDeferredLocked(int uid, int numDeferred, long sinceLast) { 4106 noteJobsDeferredLocked(uid, numDeferred, sinceLast, 4107 mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 4108 } 4109 noteJobsDeferredLocked(int uid, int numDeferred, long sinceLast, long elapsedRealtimeMs, long uptimeMs)4110 public void noteJobsDeferredLocked(int uid, int numDeferred, long sinceLast, 4111 long elapsedRealtimeMs, long uptimeMs) { 4112 uid = mapUid(uid); 4113 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 4114 .noteJobsDeferredLocked(numDeferred, sinceLast); 4115 } 4116 noteAlarmStartLocked(String name, WorkSource workSource, int uid)4117 public void noteAlarmStartLocked(String name, WorkSource workSource, int uid) { 4118 noteAlarmStartLocked(name, workSource, uid, 4119 mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 4120 } 4121 noteAlarmStartLocked(String name, WorkSource workSource, int uid, long elapsedRealtimeMs, long uptimeMs)4122 public void noteAlarmStartLocked(String name, WorkSource workSource, int uid, 4123 long elapsedRealtimeMs, long uptimeMs) { 4124 noteAlarmStartOrFinishLocked(HistoryItem.EVENT_ALARM_START, name, workSource, uid, 4125 elapsedRealtimeMs, uptimeMs); 4126 } 4127 noteAlarmFinishLocked(String name, WorkSource workSource, int uid)4128 public void noteAlarmFinishLocked(String name, WorkSource workSource, int uid) { 4129 noteAlarmFinishLocked(name, workSource, uid, 4130 mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 4131 } 4132 noteAlarmFinishLocked(String name, WorkSource workSource, int uid, long elapsedRealtimeMs, long uptimeMs)4133 public void noteAlarmFinishLocked(String name, WorkSource workSource, int uid, 4134 long elapsedRealtimeMs, long uptimeMs) { 4135 noteAlarmStartOrFinishLocked(HistoryItem.EVENT_ALARM_FINISH, name, workSource, uid, 4136 elapsedRealtimeMs, uptimeMs); 4137 } 4138 noteAlarmStartOrFinishLocked(int historyItem, String name, WorkSource workSource, int uid)4139 private void noteAlarmStartOrFinishLocked(int historyItem, String name, WorkSource workSource, 4140 int uid) { 4141 noteAlarmStartOrFinishLocked(historyItem, name, workSource, uid, 4142 mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 4143 } 4144 noteAlarmStartOrFinishLocked(int historyItem, String name, WorkSource workSource, int uid, long elapsedRealtimeMs, long uptimeMs)4145 private void noteAlarmStartOrFinishLocked(int historyItem, String name, WorkSource workSource, 4146 int uid, long elapsedRealtimeMs, long uptimeMs) { 4147 if (!mRecordAllHistory) { 4148 return; 4149 } 4150 4151 if (workSource != null) { 4152 for (int i = 0; i < workSource.size(); ++i) { 4153 uid = mapUid(workSource.getUid(i)); 4154 if (mActiveEvents.updateState(historyItem, name, uid, 0)) { 4155 addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, historyItem, name, uid); 4156 } 4157 } 4158 4159 List<WorkChain> workChains = workSource.getWorkChains(); 4160 if (workChains != null) { 4161 for (int i = 0; i < workChains.size(); ++i) { 4162 uid = mapUid(workChains.get(i).getAttributionUid()); 4163 if (mActiveEvents.updateState(historyItem, name, uid, 0)) { 4164 addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, historyItem, name, uid); 4165 } 4166 } 4167 } 4168 } else { 4169 uid = mapUid(uid); 4170 4171 if (mActiveEvents.updateState(historyItem, name, uid, 0)) { 4172 addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, historyItem, name, uid); 4173 } 4174 } 4175 } 4176 noteWakupAlarmLocked(String packageName, int uid, WorkSource workSource, String tag)4177 public void noteWakupAlarmLocked(String packageName, int uid, WorkSource workSource, 4178 String tag) { 4179 noteWakupAlarmLocked(packageName, uid, workSource, tag, 4180 mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 4181 } 4182 noteWakupAlarmLocked(String packageName, int uid, WorkSource workSource, String tag, long elapsedRealtimeMs, long uptimeMs)4183 public void noteWakupAlarmLocked(String packageName, int uid, WorkSource workSource, 4184 String tag, long elapsedRealtimeMs, long uptimeMs) { 4185 if (workSource != null) { 4186 for (int i = 0; i < workSource.size(); ++i) { 4187 uid = workSource.getUid(i); 4188 final String workSourceName = workSource.getPackageName(i); 4189 4190 if (isOnBattery()) { 4191 BatteryStatsImpl.Uid.Pkg pkg = getPackageStatsLocked(uid, 4192 workSourceName != null ? workSourceName : packageName, 4193 elapsedRealtimeMs, uptimeMs); 4194 pkg.noteWakeupAlarmLocked(tag); 4195 } 4196 } 4197 4198 List<WorkChain> workChains = workSource.getWorkChains(); 4199 if (workChains != null) { 4200 for (int i = 0; i < workChains.size(); ++i) { 4201 final WorkChain wc = workChains.get(i); 4202 uid = wc.getAttributionUid(); 4203 4204 if (isOnBattery()) { 4205 BatteryStatsImpl.Uid.Pkg pkg = getPackageStatsLocked(uid, packageName, 4206 elapsedRealtimeMs, uptimeMs); 4207 pkg.noteWakeupAlarmLocked(tag); 4208 } 4209 } 4210 } 4211 } else { 4212 if (isOnBattery()) { 4213 BatteryStatsImpl.Uid.Pkg pkg = getPackageStatsLocked(uid, packageName, 4214 elapsedRealtimeMs, uptimeMs); 4215 pkg.noteWakeupAlarmLocked(tag); 4216 } 4217 } 4218 } 4219 requestWakelockCpuUpdate()4220 private void requestWakelockCpuUpdate() { 4221 mExternalSync.scheduleCpuSyncDueToWakelockChange(DELAY_UPDATE_WAKELOCKS); 4222 } 4223 requestImmediateCpuUpdate()4224 private void requestImmediateCpuUpdate() { 4225 mExternalSync.scheduleCpuSyncDueToWakelockChange(0 /* delayMillis */); 4226 } 4227 setRecordAllHistoryLocked(boolean enabled)4228 public void setRecordAllHistoryLocked(boolean enabled) { 4229 mRecordAllHistory = enabled; 4230 if (!enabled) { 4231 // Clear out any existing state. 4232 mActiveEvents.removeEvents(HistoryItem.EVENT_WAKE_LOCK); 4233 mActiveEvents.removeEvents(HistoryItem.EVENT_ALARM); 4234 // Record the currently running processes as stopping, now that we are no 4235 // longer tracking them. 4236 HashMap<String, SparseIntArray> active = mActiveEvents.getStateForEvent( 4237 HistoryItem.EVENT_PROC); 4238 if (active != null) { 4239 long mSecRealtime = mClocks.elapsedRealtime(); 4240 final long mSecUptime = mClocks.uptimeMillis(); 4241 for (HashMap.Entry<String, SparseIntArray> ent : active.entrySet()) { 4242 SparseIntArray uids = ent.getValue(); 4243 for (int j=0; j<uids.size(); j++) { 4244 addHistoryEventLocked(mSecRealtime, mSecUptime, 4245 HistoryItem.EVENT_PROC_FINISH, ent.getKey(), uids.keyAt(j)); 4246 } 4247 } 4248 } 4249 } else { 4250 // Record the currently running processes as starting, now that we are tracking them. 4251 HashMap<String, SparseIntArray> active = mActiveEvents.getStateForEvent( 4252 HistoryItem.EVENT_PROC); 4253 if (active != null) { 4254 long mSecRealtime = mClocks.elapsedRealtime(); 4255 final long mSecUptime = mClocks.uptimeMillis(); 4256 for (HashMap.Entry<String, SparseIntArray> ent : active.entrySet()) { 4257 SparseIntArray uids = ent.getValue(); 4258 for (int j=0; j<uids.size(); j++) { 4259 addHistoryEventLocked(mSecRealtime, mSecUptime, 4260 HistoryItem.EVENT_PROC_START, ent.getKey(), uids.keyAt(j)); 4261 } 4262 } 4263 } 4264 } 4265 } 4266 setNoAutoReset(boolean enabled)4267 public void setNoAutoReset(boolean enabled) { 4268 mNoAutoReset = enabled; 4269 } 4270 setPretendScreenOff(boolean pretendScreenOff)4271 public void setPretendScreenOff(boolean pretendScreenOff) { 4272 if (mPretendScreenOff != pretendScreenOff) { 4273 mPretendScreenOff = pretendScreenOff; 4274 noteScreenStateLocked(pretendScreenOff ? Display.STATE_OFF : Display.STATE_ON, 4275 mClocks.elapsedRealtime(), mClocks.uptimeMillis(), mClocks.currentTimeMillis()); 4276 } 4277 } 4278 4279 private String mInitialAcquireWakeName; 4280 private int mInitialAcquireWakeUid = -1; 4281 noteStartWakeLocked(int uid, int pid, WorkChain wc, String name, String historyName, int type, boolean unimportantForLogging)4282 public void noteStartWakeLocked(int uid, int pid, WorkChain wc, String name, String historyName, 4283 int type, boolean unimportantForLogging) { 4284 noteStartWakeLocked(uid, pid, wc, name, historyName, type, unimportantForLogging, 4285 mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 4286 } 4287 noteStartWakeLocked(int uid, int pid, WorkChain wc, String name, String historyName, int type, boolean unimportantForLogging, long elapsedRealtimeMs, long uptimeMs)4288 public void noteStartWakeLocked(int uid, int pid, WorkChain wc, String name, String historyName, 4289 int type, boolean unimportantForLogging, long elapsedRealtimeMs, long uptimeMs) { 4290 uid = mapUid(uid); 4291 if (type == WAKE_TYPE_PARTIAL) { 4292 // Only care about partial wake locks, since full wake locks 4293 // will be canceled when the user puts the screen to sleep. 4294 aggregateLastWakeupUptimeLocked(elapsedRealtimeMs, uptimeMs); 4295 if (historyName == null) { 4296 historyName = name; 4297 } 4298 if (mRecordAllHistory) { 4299 if (mActiveEvents.updateState(HistoryItem.EVENT_WAKE_LOCK_START, historyName, 4300 uid, 0)) { 4301 addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, 4302 HistoryItem.EVENT_WAKE_LOCK_START, historyName, uid); 4303 } 4304 } 4305 if (mWakeLockNesting == 0) { 4306 mHistoryCur.states |= HistoryItem.STATE_WAKE_LOCK_FLAG; 4307 if (DEBUG_HISTORY) Slog.v(TAG, "Start wake lock to: " 4308 + Integer.toHexString(mHistoryCur.states)); 4309 mHistoryCur.wakelockTag = mHistoryCur.localWakelockTag; 4310 mHistoryCur.wakelockTag.string = mInitialAcquireWakeName = historyName; 4311 mHistoryCur.wakelockTag.uid = mInitialAcquireWakeUid = uid; 4312 mWakeLockImportant = !unimportantForLogging; 4313 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 4314 } else if (!mWakeLockImportant && !unimportantForLogging 4315 && mHistoryLastWritten.cmd == HistoryItem.CMD_UPDATE) { 4316 if (mHistoryLastWritten.wakelockTag != null) { 4317 // We'll try to update the last tag. 4318 mHistoryLastWritten.wakelockTag = null; 4319 mHistoryCur.wakelockTag = mHistoryCur.localWakelockTag; 4320 mHistoryCur.wakelockTag.string = mInitialAcquireWakeName = historyName; 4321 mHistoryCur.wakelockTag.uid = mInitialAcquireWakeUid = uid; 4322 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 4323 } 4324 mWakeLockImportant = true; 4325 } 4326 mWakeLockNesting++; 4327 } 4328 if (uid >= 0) { 4329 if (mOnBatteryScreenOffTimeBase.isRunning()) { 4330 // We only update the cpu time when a wake lock is acquired if the screen is off. 4331 // If the screen is on, we don't distribute the power amongst partial wakelocks. 4332 if (DEBUG_ENERGY_CPU) { 4333 Slog.d(TAG, "Updating cpu time because of +wake_lock"); 4334 } 4335 requestWakelockCpuUpdate(); 4336 } 4337 4338 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 4339 .noteStartWakeLocked(pid, name, type, elapsedRealtimeMs); 4340 4341 if (wc != null) { 4342 FrameworkStatsLog.write(FrameworkStatsLog.WAKELOCK_STATE_CHANGED, wc.getUids(), 4343 wc.getTags(), getPowerManagerWakeLockLevel(type), name, 4344 FrameworkStatsLog.WAKELOCK_STATE_CHANGED__STATE__ACQUIRE); 4345 } else { 4346 FrameworkStatsLog.write_non_chained(FrameworkStatsLog.WAKELOCK_STATE_CHANGED, uid, 4347 null, getPowerManagerWakeLockLevel(type), name, 4348 FrameworkStatsLog.WAKELOCK_STATE_CHANGED__STATE__ACQUIRE); 4349 } 4350 } 4351 } 4352 noteStopWakeLocked(int uid, int pid, WorkChain wc, String name, String historyName, int type)4353 public void noteStopWakeLocked(int uid, int pid, WorkChain wc, String name, String historyName, 4354 int type) { 4355 noteStopWakeLocked(uid, pid, wc, name, historyName, type, 4356 mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 4357 } 4358 noteStopWakeLocked(int uid, int pid, WorkChain wc, String name, String historyName, int type, long elapsedRealtimeMs, long uptimeMs)4359 public void noteStopWakeLocked(int uid, int pid, WorkChain wc, String name, String historyName, 4360 int type, long elapsedRealtimeMs, long uptimeMs) { 4361 uid = mapUid(uid); 4362 if (type == WAKE_TYPE_PARTIAL) { 4363 mWakeLockNesting--; 4364 if (mRecordAllHistory) { 4365 if (historyName == null) { 4366 historyName = name; 4367 } 4368 if (mActiveEvents.updateState(HistoryItem.EVENT_WAKE_LOCK_FINISH, historyName, 4369 uid, 0)) { 4370 addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, 4371 HistoryItem.EVENT_WAKE_LOCK_FINISH, historyName, uid); 4372 } 4373 } 4374 if (mWakeLockNesting == 0) { 4375 mHistoryCur.states &= ~HistoryItem.STATE_WAKE_LOCK_FLAG; 4376 if (DEBUG_HISTORY) Slog.v(TAG, "Stop wake lock to: " 4377 + Integer.toHexString(mHistoryCur.states)); 4378 mInitialAcquireWakeName = null; 4379 mInitialAcquireWakeUid = -1; 4380 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 4381 } 4382 } 4383 if (uid >= 0) { 4384 if (mOnBatteryScreenOffTimeBase.isRunning()) { 4385 if (DEBUG_ENERGY_CPU) { 4386 Slog.d(TAG, "Updating cpu time because of -wake_lock"); 4387 } 4388 requestWakelockCpuUpdate(); 4389 } 4390 4391 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 4392 .noteStopWakeLocked(pid, name, type, elapsedRealtimeMs); 4393 if (wc != null) { 4394 FrameworkStatsLog.write(FrameworkStatsLog.WAKELOCK_STATE_CHANGED, wc.getUids(), 4395 wc.getTags(), getPowerManagerWakeLockLevel(type), name, 4396 FrameworkStatsLog.WAKELOCK_STATE_CHANGED__STATE__RELEASE); 4397 } else { 4398 FrameworkStatsLog.write_non_chained(FrameworkStatsLog.WAKELOCK_STATE_CHANGED, uid, 4399 null, getPowerManagerWakeLockLevel(type), name, 4400 FrameworkStatsLog.WAKELOCK_STATE_CHANGED__STATE__RELEASE); 4401 } 4402 } 4403 } 4404 4405 /** 4406 * Converts BatteryStats wakelock types back into PowerManager wakelock levels. 4407 * This is the inverse map of Notifier.getBatteryStatsWakeLockMonitorType(). 4408 * These are estimations, since batterystats loses some of the original data. 4409 * TODO: Delete this. Instead, FrameworkStatsLog.write should be called from 4410 * PowerManager's Notifier. 4411 */ getPowerManagerWakeLockLevel(int battertStatsWakelockType)4412 private int getPowerManagerWakeLockLevel(int battertStatsWakelockType) { 4413 switch (battertStatsWakelockType) { 4414 // PowerManager.PARTIAL_WAKE_LOCK or PROXIMITY_SCREEN_OFF_WAKE_LOCK 4415 case BatteryStats.WAKE_TYPE_PARTIAL: 4416 return PowerManager.PARTIAL_WAKE_LOCK; 4417 4418 // PowerManager.SCREEN_DIM_WAKE_LOCK or SCREEN_BRIGHT_WAKE_LOCK 4419 case BatteryStats.WAKE_TYPE_FULL: 4420 return PowerManager.FULL_WAKE_LOCK; 4421 4422 case BatteryStats.WAKE_TYPE_DRAW: 4423 return PowerManager.DRAW_WAKE_LOCK; 4424 4425 // It appears that nothing can ever make a Window and PowerManager lacks an equivalent. 4426 case BatteryStats.WAKE_TYPE_WINDOW: 4427 Slog.e(TAG, "Illegal window wakelock type observed in batterystats."); 4428 return -1; 4429 4430 default: 4431 Slog.e(TAG, "Illegal wakelock type in batterystats: " + battertStatsWakelockType); 4432 return -1; 4433 } 4434 } 4435 noteStartWakeFromSourceLocked(WorkSource ws, int pid, String name, String historyName, int type, boolean unimportantForLogging)4436 public void noteStartWakeFromSourceLocked(WorkSource ws, int pid, String name, 4437 String historyName, int type, boolean unimportantForLogging) { 4438 noteStartWakeFromSourceLocked(ws, pid, name, historyName, type, unimportantForLogging, 4439 mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 4440 } 4441 noteStartWakeFromSourceLocked(WorkSource ws, int pid, String name, String historyName, int type, boolean unimportantForLogging, long elapsedRealtimeMs, long uptimeMs)4442 public void noteStartWakeFromSourceLocked(WorkSource ws, int pid, String name, 4443 String historyName, int type, boolean unimportantForLogging, 4444 long elapsedRealtimeMs, long uptimeMs) { 4445 final int N = ws.size(); 4446 for (int i=0; i<N; i++) { 4447 noteStartWakeLocked(ws.getUid(i), pid, null, name, historyName, type, 4448 unimportantForLogging, elapsedRealtimeMs, uptimeMs); 4449 } 4450 4451 List<WorkChain> wcs = ws.getWorkChains(); 4452 if (wcs != null) { 4453 for (int i = 0; i < wcs.size(); ++i) { 4454 final WorkChain wc = wcs.get(i); 4455 noteStartWakeLocked(wc.getAttributionUid(), pid, wc, name, historyName, type, 4456 unimportantForLogging, elapsedRealtimeMs, uptimeMs); 4457 } 4458 } 4459 } 4460 noteChangeWakelockFromSourceLocked(WorkSource ws, int pid, String name, String historyName, int type, WorkSource newWs, int newPid, String newName, String newHistoryName, int newType, boolean newUnimportantForLogging)4461 public void noteChangeWakelockFromSourceLocked(WorkSource ws, int pid, String name, 4462 String historyName, int type, WorkSource newWs, int newPid, String newName, 4463 String newHistoryName, int newType, boolean newUnimportantForLogging) { 4464 noteChangeWakelockFromSourceLocked(ws, pid, name, historyName, type, newWs, newPid, 4465 newName, newHistoryName, newType, newUnimportantForLogging, 4466 mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 4467 } 4468 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)4469 public void noteChangeWakelockFromSourceLocked(WorkSource ws, int pid, String name, 4470 String historyName, int type, WorkSource newWs, int newPid, String newName, 4471 String newHistoryName, int newType, boolean newUnimportantForLogging, 4472 long elapsedRealtimeMs, long uptimeMs) { 4473 List<WorkChain>[] wcs = WorkSource.diffChains(ws, newWs); 4474 4475 // For correct semantics, we start the need worksources first, so that we won't 4476 // make inappropriate history items as if all wake locks went away and new ones 4477 // appeared. This is okay because tracking of wake locks allows nesting. 4478 // 4479 // First the starts : 4480 final int NN = newWs.size(); 4481 for (int i=0; i<NN; i++) { 4482 noteStartWakeLocked(newWs.getUid(i), newPid, null, newName, newHistoryName, newType, 4483 newUnimportantForLogging, elapsedRealtimeMs, uptimeMs); 4484 } 4485 if (wcs != null) { 4486 List<WorkChain> newChains = wcs[0]; 4487 if (newChains != null) { 4488 for (int i = 0; i < newChains.size(); ++i) { 4489 final WorkChain newChain = newChains.get(i); 4490 noteStartWakeLocked(newChain.getAttributionUid(), newPid, newChain, newName, 4491 newHistoryName, newType, newUnimportantForLogging, elapsedRealtimeMs, 4492 uptimeMs); 4493 } 4494 } 4495 } 4496 4497 // Then the stops : 4498 final int NO = ws.size(); 4499 for (int i=0; i<NO; i++) { 4500 noteStopWakeLocked(ws.getUid(i), pid, null, name, historyName, type, elapsedRealtimeMs, 4501 uptimeMs); 4502 } 4503 if (wcs != null) { 4504 List<WorkChain> goneChains = wcs[1]; 4505 if (goneChains != null) { 4506 for (int i = 0; i < goneChains.size(); ++i) { 4507 final WorkChain goneChain = goneChains.get(i); 4508 noteStopWakeLocked(goneChain.getAttributionUid(), pid, goneChain, name, 4509 historyName, type, elapsedRealtimeMs, uptimeMs); 4510 } 4511 } 4512 } 4513 } 4514 noteStopWakeFromSourceLocked(WorkSource ws, int pid, String name, String historyName, int type)4515 public void noteStopWakeFromSourceLocked(WorkSource ws, int pid, String name, 4516 String historyName, int type) { 4517 noteStopWakeFromSourceLocked(ws, pid, name, historyName, type, 4518 mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 4519 } 4520 noteStopWakeFromSourceLocked(WorkSource ws, int pid, String name, String historyName, int type, long elapsedRealtimeMs, long uptimeMs)4521 public void noteStopWakeFromSourceLocked(WorkSource ws, int pid, String name, 4522 String historyName, int type, long elapsedRealtimeMs, long uptimeMs) { 4523 final int N = ws.size(); 4524 for (int i=0; i<N; i++) { 4525 noteStopWakeLocked(ws.getUid(i), pid, null, name, historyName, type, elapsedRealtimeMs, 4526 uptimeMs); 4527 } 4528 4529 List<WorkChain> wcs = ws.getWorkChains(); 4530 if (wcs != null) { 4531 for (int i = 0; i < wcs.size(); ++i) { 4532 final WorkChain wc = wcs.get(i); 4533 noteStopWakeLocked(wc.getAttributionUid(), pid, wc, name, historyName, type, 4534 elapsedRealtimeMs, uptimeMs); 4535 } 4536 } 4537 } 4538 noteLongPartialWakelockStart(String name, String historyName, int uid)4539 public void noteLongPartialWakelockStart(String name, String historyName, int uid) { 4540 noteLongPartialWakelockStart(name, historyName, uid, 4541 mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 4542 } 4543 noteLongPartialWakelockStart(String name, String historyName, int uid, long elapsedRealtimeMs, long uptimeMs)4544 public void noteLongPartialWakelockStart(String name, String historyName, int uid, 4545 long elapsedRealtimeMs, long uptimeMs) { 4546 uid = mapUid(uid); 4547 noteLongPartialWakeLockStartInternal(name, historyName, uid, elapsedRealtimeMs, uptimeMs); 4548 } 4549 noteLongPartialWakelockStartFromSource(String name, String historyName, WorkSource workSource)4550 public void noteLongPartialWakelockStartFromSource(String name, String historyName, 4551 WorkSource workSource) { 4552 noteLongPartialWakelockStartFromSource(name, historyName, workSource, 4553 mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 4554 } 4555 noteLongPartialWakelockStartFromSource(String name, String historyName, WorkSource workSource, long elapsedRealtimeMs, long uptimeMs)4556 public void noteLongPartialWakelockStartFromSource(String name, String historyName, 4557 WorkSource workSource, long elapsedRealtimeMs, long uptimeMs) { 4558 final int N = workSource.size(); 4559 for (int i = 0; i < N; ++i) { 4560 final int uid = mapUid(workSource.getUid(i)); 4561 noteLongPartialWakeLockStartInternal(name, historyName, uid, 4562 elapsedRealtimeMs, uptimeMs); 4563 } 4564 4565 final List<WorkChain> workChains = workSource.getWorkChains(); 4566 if (workChains != null) { 4567 for (int i = 0; i < workChains.size(); ++i) { 4568 final WorkChain workChain = workChains.get(i); 4569 final int uid = workChain.getAttributionUid(); 4570 noteLongPartialWakeLockStartInternal(name, historyName, uid, 4571 elapsedRealtimeMs, uptimeMs); 4572 } 4573 } 4574 } 4575 noteLongPartialWakeLockStartInternal(String name, String historyName, int uid, long elapsedRealtimeMs, long uptimeMs)4576 private void noteLongPartialWakeLockStartInternal(String name, String historyName, int uid, 4577 long elapsedRealtimeMs, long uptimeMs) { 4578 if (historyName == null) { 4579 historyName = name; 4580 } 4581 if (!mActiveEvents.updateState(HistoryItem.EVENT_LONG_WAKE_LOCK_START, historyName, uid, 4582 0)) { 4583 return; 4584 } 4585 addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_LONG_WAKE_LOCK_START, 4586 historyName, uid); 4587 } 4588 noteLongPartialWakelockFinish(String name, String historyName, int uid)4589 public void noteLongPartialWakelockFinish(String name, String historyName, int uid) { 4590 noteLongPartialWakelockFinish(name, historyName, uid, 4591 mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 4592 } 4593 noteLongPartialWakelockFinish(String name, String historyName, int uid, long elapsedRealtimeMs, long uptimeMs)4594 public void noteLongPartialWakelockFinish(String name, String historyName, int uid, 4595 long elapsedRealtimeMs, long uptimeMs) { 4596 uid = mapUid(uid); 4597 noteLongPartialWakeLockFinishInternal(name, historyName, uid, elapsedRealtimeMs, uptimeMs); 4598 } 4599 noteLongPartialWakelockFinishFromSource(String name, String historyName, WorkSource workSource)4600 public void noteLongPartialWakelockFinishFromSource(String name, String historyName, 4601 WorkSource workSource) { 4602 noteLongPartialWakelockFinishFromSource(name, historyName, workSource, 4603 mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 4604 } 4605 noteLongPartialWakelockFinishFromSource(String name, String historyName, WorkSource workSource, long elapsedRealtimeMs, long uptimeMs)4606 public void noteLongPartialWakelockFinishFromSource(String name, String historyName, 4607 WorkSource workSource, long elapsedRealtimeMs, long uptimeMs) { 4608 final int N = workSource.size(); 4609 for (int i = 0; i < N; ++i) { 4610 final int uid = mapUid(workSource.getUid(i)); 4611 noteLongPartialWakeLockFinishInternal(name, historyName, uid, 4612 elapsedRealtimeMs, uptimeMs); 4613 } 4614 4615 final List<WorkChain> workChains = workSource.getWorkChains(); 4616 if (workChains != null) { 4617 for (int i = 0; i < workChains.size(); ++i) { 4618 final WorkChain workChain = workChains.get(i); 4619 final int uid = workChain.getAttributionUid(); 4620 noteLongPartialWakeLockFinishInternal(name, historyName, uid, 4621 elapsedRealtimeMs, uptimeMs); 4622 } 4623 } 4624 } 4625 noteLongPartialWakeLockFinishInternal(String name, String historyName, int uid, long elapsedRealtimeMs, long uptimeMs)4626 private void noteLongPartialWakeLockFinishInternal(String name, String historyName, int uid, 4627 long elapsedRealtimeMs, long uptimeMs) { 4628 if (historyName == null) { 4629 historyName = name; 4630 } 4631 if (!mActiveEvents.updateState(HistoryItem.EVENT_LONG_WAKE_LOCK_FINISH, historyName, uid, 4632 0)) { 4633 return; 4634 } 4635 addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_LONG_WAKE_LOCK_FINISH, 4636 historyName, uid); 4637 } 4638 aggregateLastWakeupUptimeLocked(long elapsedRealtimeMs, long uptimeMs)4639 void aggregateLastWakeupUptimeLocked(long elapsedRealtimeMs, long uptimeMs) { 4640 if (mLastWakeupReason != null) { 4641 long deltaUptimeMs = uptimeMs - mLastWakeupUptimeMs; 4642 SamplingTimer timer = getWakeupReasonTimerLocked(mLastWakeupReason); 4643 timer.add(deltaUptimeMs * 1000, 1, elapsedRealtimeMs); // time in in microseconds 4644 FrameworkStatsLog.write(FrameworkStatsLog.KERNEL_WAKEUP_REPORTED, mLastWakeupReason, 4645 /* duration_usec */ deltaUptimeMs * 1000); 4646 mLastWakeupReason = null; 4647 } 4648 } 4649 noteWakeupReasonLocked(String reason)4650 public void noteWakeupReasonLocked(String reason) { 4651 noteWakeupReasonLocked(reason, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 4652 } 4653 noteWakeupReasonLocked(String reason, long elapsedRealtimeMs, long uptimeMs)4654 public void noteWakeupReasonLocked(String reason, long elapsedRealtimeMs, long uptimeMs) { 4655 if (DEBUG_HISTORY) Slog.v(TAG, "Wakeup reason \"" + reason +"\": " 4656 + Integer.toHexString(mHistoryCur.states)); 4657 aggregateLastWakeupUptimeLocked(elapsedRealtimeMs, uptimeMs); 4658 mHistoryCur.wakeReasonTag = mHistoryCur.localWakeReasonTag; 4659 mHistoryCur.wakeReasonTag.string = reason; 4660 mHistoryCur.wakeReasonTag.uid = 0; 4661 mLastWakeupReason = reason; 4662 mLastWakeupUptimeMs = uptimeMs; 4663 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 4664 } 4665 startAddingCpuLocked()4666 public boolean startAddingCpuLocked() { 4667 mExternalSync.cancelCpuSyncDueToWakelockChange(); 4668 return mOnBatteryInternal; 4669 } 4670 finishAddingCpuLocked(int totalUTimeMs, int totalSTimeMs, int statUserTimeMs, int statSystemTimeMs, int statIOWaitTimeMs, int statIrqTimeMs, int statSoftIrqTimeMs, int statIdleTimeMs)4671 public void finishAddingCpuLocked(int totalUTimeMs, int totalSTimeMs, int statUserTimeMs, 4672 int statSystemTimeMs, int statIOWaitTimeMs, int statIrqTimeMs, 4673 int statSoftIrqTimeMs, int statIdleTimeMs) { 4674 if (DEBUG) { 4675 Slog.d(TAG, "Adding cpu: tuser=" + totalUTimeMs + " tsys=" + totalSTimeMs 4676 + " user=" + statUserTimeMs + " sys=" + statSystemTimeMs 4677 + " io=" + statIOWaitTimeMs + " irq=" + statIrqTimeMs 4678 + " sirq=" + statSoftIrqTimeMs + " idle=" + statIdleTimeMs); 4679 } 4680 mCurStepCpuUserTimeMs += totalUTimeMs; 4681 mCurStepCpuSystemTimeMs += totalSTimeMs; 4682 mCurStepStatUserTimeMs += statUserTimeMs; 4683 mCurStepStatSystemTimeMs += statSystemTimeMs; 4684 mCurStepStatIOWaitTimeMs += statIOWaitTimeMs; 4685 mCurStepStatIrqTimeMs += statIrqTimeMs; 4686 mCurStepStatSoftIrqTimeMs += statSoftIrqTimeMs; 4687 mCurStepStatIdleTimeMs += statIdleTimeMs; 4688 } 4689 noteProcessDiedLocked(int uid, int pid)4690 public void noteProcessDiedLocked(int uid, int pid) { 4691 uid = mapUid(uid); 4692 Uid u = mUidStats.get(uid); 4693 if (u != null) { 4694 u.mPids.remove(pid); 4695 } 4696 } 4697 getProcessWakeTime(int uid, int pid, long realtimeMs)4698 public long getProcessWakeTime(int uid, int pid, long realtimeMs) { 4699 uid = mapUid(uid); 4700 Uid u = mUidStats.get(uid); 4701 if (u != null) { 4702 Uid.Pid p = u.mPids.get(pid); 4703 if (p != null) { 4704 return p.mWakeSumMs + (p.mWakeNesting > 0 ? (realtimeMs - p.mWakeStartMs) : 0); 4705 } 4706 } 4707 return 0; 4708 } 4709 reportExcessiveCpuLocked(int uid, String proc, long overTimeMs, long usedTimeMs)4710 public void reportExcessiveCpuLocked(int uid, String proc, long overTimeMs, long usedTimeMs) { 4711 uid = mapUid(uid); 4712 Uid u = mUidStats.get(uid); 4713 if (u != null) { 4714 u.reportExcessiveCpuLocked(proc, overTimeMs, usedTimeMs); 4715 } 4716 } 4717 4718 int mSensorNesting; 4719 noteStartSensorLocked(int uid, int sensor)4720 public void noteStartSensorLocked(int uid, int sensor) { 4721 noteStartSensorLocked(uid, sensor, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 4722 } 4723 noteStartSensorLocked(int uid, int sensor, long elapsedRealtimeMs, long uptimeMs)4724 public void noteStartSensorLocked(int uid, int sensor, long elapsedRealtimeMs, long uptimeMs) { 4725 uid = mapUid(uid); 4726 if (mSensorNesting == 0) { 4727 mHistoryCur.states |= HistoryItem.STATE_SENSOR_ON_FLAG; 4728 if (DEBUG_HISTORY) Slog.v(TAG, "Start sensor to: " 4729 + Integer.toHexString(mHistoryCur.states)); 4730 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 4731 } 4732 mSensorNesting++; 4733 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 4734 .noteStartSensor(sensor, elapsedRealtimeMs); 4735 } 4736 noteStopSensorLocked(int uid, int sensor)4737 public void noteStopSensorLocked(int uid, int sensor) { 4738 noteStopSensorLocked(uid, sensor, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 4739 } 4740 noteStopSensorLocked(int uid, int sensor, long elapsedRealtimeMs, long uptimeMs)4741 public void noteStopSensorLocked(int uid, int sensor, long elapsedRealtimeMs, long uptimeMs) { 4742 uid = mapUid(uid); 4743 mSensorNesting--; 4744 if (mSensorNesting == 0) { 4745 mHistoryCur.states &= ~HistoryItem.STATE_SENSOR_ON_FLAG; 4746 if (DEBUG_HISTORY) Slog.v(TAG, "Stop sensor to: " 4747 + Integer.toHexString(mHistoryCur.states)); 4748 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 4749 } 4750 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 4751 .noteStopSensor(sensor, elapsedRealtimeMs); 4752 } 4753 4754 int mGpsNesting; 4755 noteGpsChangedLocked(WorkSource oldWs, WorkSource newWs)4756 public void noteGpsChangedLocked(WorkSource oldWs, WorkSource newWs) { 4757 noteGpsChangedLocked(oldWs, newWs, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 4758 } 4759 noteGpsChangedLocked(WorkSource oldWs, WorkSource newWs, long elapsedRealtimeMs, long uptimeMs)4760 public void noteGpsChangedLocked(WorkSource oldWs, WorkSource newWs, 4761 long elapsedRealtimeMs, long uptimeMs) { 4762 for (int i = 0; i < newWs.size(); ++i) { 4763 noteStartGpsLocked(newWs.getUid(i), null, elapsedRealtimeMs, uptimeMs); 4764 } 4765 4766 for (int i = 0; i < oldWs.size(); ++i) { 4767 noteStopGpsLocked((oldWs.getUid(i)), null, elapsedRealtimeMs, uptimeMs); 4768 } 4769 4770 List<WorkChain>[] wcs = WorkSource.diffChains(oldWs, newWs); 4771 if (wcs != null) { 4772 if (wcs[0] != null) { 4773 final List<WorkChain> newChains = wcs[0]; 4774 for (int i = 0; i < newChains.size(); ++i) { 4775 noteStartGpsLocked(-1, newChains.get(i), elapsedRealtimeMs, uptimeMs); 4776 } 4777 } 4778 4779 if (wcs[1] != null) { 4780 final List<WorkChain> goneChains = wcs[1]; 4781 for (int i = 0; i < goneChains.size(); ++i) { 4782 noteStopGpsLocked(-1, goneChains.get(i), elapsedRealtimeMs, uptimeMs); 4783 } 4784 } 4785 } 4786 } 4787 noteStartGpsLocked(int uid, WorkChain workChain, long elapsedRealtimeMs, long uptimeMs)4788 private void noteStartGpsLocked(int uid, WorkChain workChain, 4789 long elapsedRealtimeMs, long uptimeMs) { 4790 uid = getAttributionUid(uid, workChain); 4791 if (mGpsNesting == 0) { 4792 mHistoryCur.states |= HistoryItem.STATE_GPS_ON_FLAG; 4793 if (DEBUG_HISTORY) Slog.v(TAG, "Start GPS to: " 4794 + Integer.toHexString(mHistoryCur.states)); 4795 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 4796 } 4797 mGpsNesting++; 4798 4799 if (workChain == null) { 4800 FrameworkStatsLog.write_non_chained(FrameworkStatsLog.GPS_SCAN_STATE_CHANGED, uid, null, 4801 FrameworkStatsLog.GPS_SCAN_STATE_CHANGED__STATE__ON); 4802 } else { 4803 FrameworkStatsLog.write(FrameworkStatsLog.GPS_SCAN_STATE_CHANGED, 4804 workChain.getUids(), workChain.getTags(), 4805 FrameworkStatsLog.GPS_SCAN_STATE_CHANGED__STATE__ON); 4806 } 4807 4808 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs).noteStartGps(elapsedRealtimeMs); 4809 } 4810 noteStopGpsLocked(int uid, WorkChain workChain, long elapsedRealtimeMs, long uptimeMs)4811 private void noteStopGpsLocked(int uid, WorkChain workChain, 4812 long elapsedRealtimeMs, long uptimeMs) { 4813 uid = getAttributionUid(uid, workChain); 4814 mGpsNesting--; 4815 if (mGpsNesting == 0) { 4816 mHistoryCur.states &= ~HistoryItem.STATE_GPS_ON_FLAG; 4817 if (DEBUG_HISTORY) Slog.v(TAG, "Stop GPS to: " 4818 + Integer.toHexString(mHistoryCur.states)); 4819 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 4820 stopAllGpsSignalQualityTimersLocked(-1, elapsedRealtimeMs); 4821 mGpsSignalQualityBin = -1; 4822 } 4823 4824 if (workChain == null) { 4825 FrameworkStatsLog.write_non_chained(FrameworkStatsLog.GPS_SCAN_STATE_CHANGED, uid, null, 4826 FrameworkStatsLog.GPS_SCAN_STATE_CHANGED__STATE__OFF); 4827 } else { 4828 FrameworkStatsLog.write(FrameworkStatsLog.GPS_SCAN_STATE_CHANGED, workChain.getUids(), 4829 workChain.getTags(), FrameworkStatsLog.GPS_SCAN_STATE_CHANGED__STATE__OFF); 4830 } 4831 4832 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs).noteStopGps(elapsedRealtimeMs); 4833 } 4834 noteGpsSignalQualityLocked(int signalLevel)4835 public void noteGpsSignalQualityLocked(int signalLevel) { 4836 noteGpsSignalQualityLocked(signalLevel, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 4837 } 4838 noteGpsSignalQualityLocked(int signalLevel, long elapsedRealtimeMs, long uptimeMs)4839 public void noteGpsSignalQualityLocked(int signalLevel, long elapsedRealtimeMs, long uptimeMs) { 4840 if (mGpsNesting == 0) { 4841 return; 4842 } 4843 if (signalLevel < 0 || signalLevel >= mGpsSignalQualityTimer.length) { 4844 stopAllGpsSignalQualityTimersLocked(-1, elapsedRealtimeMs); 4845 return; 4846 } 4847 if (mGpsSignalQualityBin != signalLevel) { 4848 if (mGpsSignalQualityBin >= 0) { 4849 mGpsSignalQualityTimer[mGpsSignalQualityBin].stopRunningLocked(elapsedRealtimeMs); 4850 } 4851 if(!mGpsSignalQualityTimer[signalLevel].isRunningLocked()) { 4852 mGpsSignalQualityTimer[signalLevel].startRunningLocked(elapsedRealtimeMs); 4853 } 4854 mHistoryCur.states2 = (mHistoryCur.states2&~HistoryItem.STATE2_GPS_SIGNAL_QUALITY_MASK) 4855 | (signalLevel << HistoryItem.STATE2_GPS_SIGNAL_QUALITY_SHIFT); 4856 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 4857 mGpsSignalQualityBin = signalLevel; 4858 } 4859 return; 4860 } 4861 4862 @GuardedBy("this") noteScreenStateLocked(int state)4863 public void noteScreenStateLocked(int state) { 4864 noteScreenStateLocked(state, mClocks.elapsedRealtime(), mClocks.uptimeMillis(), 4865 mClocks.currentTimeMillis()); 4866 } 4867 4868 @GuardedBy("this") noteScreenStateLocked(int state, long elapsedRealtimeMs, long uptimeMs, long currentTimeMs)4869 public void noteScreenStateLocked(int state, 4870 long elapsedRealtimeMs, long uptimeMs, long currentTimeMs) { 4871 state = mPretendScreenOff ? Display.STATE_OFF : state; 4872 4873 // Battery stats relies on there being 4 states. To accommodate this, new states beyond the 4874 // original 4 are mapped to one of the originals. 4875 if (state > MAX_TRACKED_SCREEN_STATE) { 4876 switch (state) { 4877 case Display.STATE_VR: 4878 state = Display.STATE_ON; 4879 break; 4880 default: 4881 Slog.wtf(TAG, "Unknown screen state (not mapped): " + state); 4882 break; 4883 } 4884 } 4885 4886 if (mScreenState != state) { 4887 recordDailyStatsIfNeededLocked(true, currentTimeMs); 4888 final int oldState = mScreenState; 4889 mScreenState = state; 4890 if (DEBUG) Slog.v(TAG, "Screen state: oldState=" + Display.stateToString(oldState) 4891 + ", newState=" + Display.stateToString(state)); 4892 4893 if (state != Display.STATE_UNKNOWN) { 4894 int stepState = state-1; 4895 if ((stepState & STEP_LEVEL_MODE_SCREEN_STATE) == stepState) { 4896 mModStepMode |= (mCurStepMode & STEP_LEVEL_MODE_SCREEN_STATE) ^ stepState; 4897 mCurStepMode = (mCurStepMode & ~STEP_LEVEL_MODE_SCREEN_STATE) | stepState; 4898 } else { 4899 Slog.wtf(TAG, "Unexpected screen state: " + state); 4900 } 4901 } 4902 4903 boolean updateHistory = false; 4904 if (Display.isDozeState(state) && !Display.isDozeState(oldState)) { 4905 mHistoryCur.states |= HistoryItem.STATE_SCREEN_DOZE_FLAG; 4906 mScreenDozeTimer.startRunningLocked(elapsedRealtimeMs); 4907 updateHistory = true; 4908 } else if (Display.isDozeState(oldState) && !Display.isDozeState(state)) { 4909 mHistoryCur.states &= ~HistoryItem.STATE_SCREEN_DOZE_FLAG; 4910 mScreenDozeTimer.stopRunningLocked(elapsedRealtimeMs); 4911 updateHistory = true; 4912 } 4913 if (Display.isOnState(state)) { 4914 mHistoryCur.states |= HistoryItem.STATE_SCREEN_ON_FLAG; 4915 if (DEBUG_HISTORY) Slog.v(TAG, "Screen on to: " 4916 + Integer.toHexString(mHistoryCur.states)); 4917 mScreenOnTimer.startRunningLocked(elapsedRealtimeMs); 4918 if (mScreenBrightnessBin >= 0) { 4919 mScreenBrightnessTimer[mScreenBrightnessBin] 4920 .startRunningLocked(elapsedRealtimeMs); 4921 } 4922 updateHistory = true; 4923 } else if (Display.isOnState(oldState)) { 4924 mHistoryCur.states &= ~HistoryItem.STATE_SCREEN_ON_FLAG; 4925 if (DEBUG_HISTORY) Slog.v(TAG, "Screen off to: " 4926 + Integer.toHexString(mHistoryCur.states)); 4927 mScreenOnTimer.stopRunningLocked(elapsedRealtimeMs); 4928 if (mScreenBrightnessBin >= 0) { 4929 mScreenBrightnessTimer[mScreenBrightnessBin] 4930 .stopRunningLocked(elapsedRealtimeMs); 4931 } 4932 updateHistory = true; 4933 } 4934 if (updateHistory) { 4935 if (DEBUG_HISTORY) Slog.v(TAG, "Screen state to: " 4936 + Display.stateToString(state)); 4937 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 4938 } 4939 // TODO: (Probably overkill) Have mGlobalMeasuredEnergyStats store supported flags and 4940 // only update DISPLAY if it is. Currently overkill since CPU is scheduled anyway. 4941 final int updateFlag = ExternalStatsSync.UPDATE_CPU | ExternalStatsSync.UPDATE_DISPLAY; 4942 mExternalSync.scheduleSyncDueToScreenStateChange(updateFlag, 4943 mOnBatteryTimeBase.isRunning(), mOnBatteryScreenOffTimeBase.isRunning(), state); 4944 if (Display.isOnState(state)) { 4945 updateTimeBasesLocked(mOnBatteryTimeBase.isRunning(), state, 4946 uptimeMs * 1000, elapsedRealtimeMs * 1000); 4947 // Fake a wake lock, so we consider the device waked as long as the screen is on. 4948 noteStartWakeLocked(-1, -1, null, "screen", null, WAKE_TYPE_PARTIAL, false, 4949 elapsedRealtimeMs, uptimeMs); 4950 } else if (Display.isOnState(oldState)) { 4951 noteStopWakeLocked(-1, -1, null, "screen", "screen", WAKE_TYPE_PARTIAL, 4952 elapsedRealtimeMs, uptimeMs); 4953 updateTimeBasesLocked(mOnBatteryTimeBase.isRunning(), state, 4954 uptimeMs * 1000, elapsedRealtimeMs * 1000); 4955 } 4956 // Update discharge amounts. 4957 if (mOnBatteryInternal) { 4958 updateDischargeScreenLevelsLocked(oldState, state); 4959 } 4960 } 4961 } 4962 4963 @UnsupportedAppUsage noteScreenBrightnessLocked(int brightness)4964 public void noteScreenBrightnessLocked(int brightness) { 4965 noteScreenBrightnessLocked(brightness, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 4966 } 4967 noteScreenBrightnessLocked(int brightness, long elapsedRealtimeMs, long uptimeMs)4968 public void noteScreenBrightnessLocked(int brightness, long elapsedRealtimeMs, long uptimeMs) { 4969 // Bin the brightness. 4970 int bin = brightness / (256/NUM_SCREEN_BRIGHTNESS_BINS); 4971 if (bin < 0) bin = 0; 4972 else if (bin >= NUM_SCREEN_BRIGHTNESS_BINS) bin = NUM_SCREEN_BRIGHTNESS_BINS-1; 4973 if (mScreenBrightnessBin != bin) { 4974 mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_BRIGHTNESS_MASK) 4975 | (bin << HistoryItem.STATE_BRIGHTNESS_SHIFT); 4976 if (DEBUG_HISTORY) Slog.v(TAG, "Screen brightness " + bin + " to: " 4977 + Integer.toHexString(mHistoryCur.states)); 4978 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 4979 if (mScreenState == Display.STATE_ON) { 4980 if (mScreenBrightnessBin >= 0) { 4981 mScreenBrightnessTimer[mScreenBrightnessBin] 4982 .stopRunningLocked(elapsedRealtimeMs); 4983 } 4984 mScreenBrightnessTimer[bin] 4985 .startRunningLocked(elapsedRealtimeMs); 4986 } 4987 mScreenBrightnessBin = bin; 4988 } 4989 } 4990 4991 @UnsupportedAppUsage noteUserActivityLocked(int uid, int event)4992 public void noteUserActivityLocked(int uid, int event) { 4993 noteUserActivityLocked(uid, event, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 4994 } 4995 noteUserActivityLocked(int uid, int event, long elapsedRealtimeMs, long uptimeMs)4996 public void noteUserActivityLocked(int uid, int event, long elapsedRealtimeMs, long uptimeMs) { 4997 if (mOnBatteryInternal) { 4998 uid = mapUid(uid); 4999 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs).noteUserActivityLocked(event); 5000 } 5001 } 5002 noteWakeUpLocked(String reason, int reasonUid)5003 public void noteWakeUpLocked(String reason, int reasonUid) { 5004 noteWakeUpLocked(reason, reasonUid, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 5005 } 5006 noteWakeUpLocked(String reason, int reasonUid, long elapsedRealtimeMs, long uptimeMs)5007 public void noteWakeUpLocked(String reason, int reasonUid, 5008 long elapsedRealtimeMs, long uptimeMs) { 5009 addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_SCREEN_WAKE_UP, 5010 reason, reasonUid); 5011 } 5012 noteInteractiveLocked(boolean interactive)5013 public void noteInteractiveLocked(boolean interactive) { 5014 noteInteractiveLocked(interactive, mClocks.elapsedRealtime()); 5015 } 5016 noteInteractiveLocked(boolean interactive, long elapsedRealtimeMs)5017 public void noteInteractiveLocked(boolean interactive, long elapsedRealtimeMs) { 5018 if (mInteractive != interactive) { 5019 mInteractive = interactive; 5020 if (DEBUG) Slog.v(TAG, "Interactive: " + interactive); 5021 if (interactive) { 5022 mInteractiveTimer.startRunningLocked(elapsedRealtimeMs); 5023 } else { 5024 mInteractiveTimer.stopRunningLocked(elapsedRealtimeMs); 5025 } 5026 } 5027 } 5028 noteConnectivityChangedLocked(int type, String extra)5029 public void noteConnectivityChangedLocked(int type, String extra) { 5030 noteConnectivityChangedLocked(type, extra, 5031 mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 5032 } 5033 noteConnectivityChangedLocked(int type, String extra, long elapsedRealtimeMs, long uptimeMs)5034 public void noteConnectivityChangedLocked(int type, String extra, 5035 long elapsedRealtimeMs, long uptimeMs) { 5036 addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_CONNECTIVITY_CHANGED, 5037 extra, type); 5038 mNumConnectivityChange++; 5039 } 5040 noteMobileRadioApWakeupLocked(final long elapsedRealtimeMillis, final long uptimeMillis, int uid)5041 private void noteMobileRadioApWakeupLocked(final long elapsedRealtimeMillis, 5042 final long uptimeMillis, int uid) { 5043 uid = mapUid(uid); 5044 addHistoryEventLocked(elapsedRealtimeMillis, uptimeMillis, HistoryItem.EVENT_WAKEUP_AP, "", 5045 uid); 5046 getUidStatsLocked(uid, elapsedRealtimeMillis, uptimeMillis).noteMobileRadioApWakeupLocked(); 5047 } 5048 5049 /** 5050 * Updates the radio power state and returns true if an external stats collection should occur. 5051 */ noteMobileRadioPowerStateLocked(int powerState, long timestampNs, int uid)5052 public boolean noteMobileRadioPowerStateLocked(int powerState, long timestampNs, int uid) { 5053 return noteMobileRadioPowerStateLocked(powerState, timestampNs, uid, 5054 mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 5055 } 5056 noteMobileRadioPowerStateLocked(int powerState, long timestampNs, int uid, long elapsedRealtimeMs, long uptimeMs)5057 public boolean noteMobileRadioPowerStateLocked(int powerState, long timestampNs, int uid, 5058 long elapsedRealtimeMs, long uptimeMs) { 5059 if (mMobileRadioPowerState != powerState) { 5060 long realElapsedRealtimeMs; 5061 final boolean active = 5062 powerState == DataConnectionRealTimeInfo.DC_POWER_STATE_MEDIUM 5063 || powerState == DataConnectionRealTimeInfo.DC_POWER_STATE_HIGH; 5064 if (active) { 5065 if (uid > 0) { 5066 noteMobileRadioApWakeupLocked(elapsedRealtimeMs, uptimeMs, uid); 5067 } 5068 5069 mMobileRadioActiveStartTimeMs = realElapsedRealtimeMs = timestampNs / (1000 * 1000); 5070 mHistoryCur.states |= HistoryItem.STATE_MOBILE_RADIO_ACTIVE_FLAG; 5071 } else { 5072 realElapsedRealtimeMs = timestampNs / (1000*1000); 5073 long lastUpdateTimeMs = mMobileRadioActiveStartTimeMs; 5074 if (realElapsedRealtimeMs < lastUpdateTimeMs) { 5075 Slog.wtf(TAG, "Data connection inactive timestamp " + realElapsedRealtimeMs 5076 + " is before start time " + lastUpdateTimeMs); 5077 realElapsedRealtimeMs = elapsedRealtimeMs; 5078 } else if (realElapsedRealtimeMs < elapsedRealtimeMs) { 5079 mMobileRadioActiveAdjustedTime.addCountLocked(elapsedRealtimeMs 5080 - realElapsedRealtimeMs); 5081 } 5082 mHistoryCur.states &= ~HistoryItem.STATE_MOBILE_RADIO_ACTIVE_FLAG; 5083 } 5084 if (DEBUG_HISTORY) Slog.v(TAG, "Mobile network active " + active + " to: " 5085 + Integer.toHexString(mHistoryCur.states)); 5086 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 5087 mMobileRadioPowerState = powerState; 5088 if (active) { 5089 mMobileRadioActiveTimer.startRunningLocked(elapsedRealtimeMs); 5090 mMobileRadioActivePerAppTimer.startRunningLocked(elapsedRealtimeMs); 5091 } else { 5092 mMobileRadioActiveTimer.stopRunningLocked(realElapsedRealtimeMs); 5093 mMobileRadioActivePerAppTimer.stopRunningLocked(realElapsedRealtimeMs); 5094 // Tell the caller to collect radio network/power stats. 5095 return true; 5096 } 5097 } 5098 return false; 5099 } 5100 notePowerSaveModeLocked(boolean enabled)5101 public void notePowerSaveModeLocked(boolean enabled) { 5102 notePowerSaveModeLocked(enabled, mClocks.elapsedRealtime(), mClocks.uptimeMillis(), false); 5103 } 5104 5105 /** 5106 * Handles power save mode state changes. 5107 */ notePowerSaveModeLocked(boolean enabled, long elapsedRealtimeMs, long uptimeMs, boolean forceLog)5108 public void notePowerSaveModeLocked(boolean enabled, long elapsedRealtimeMs, long uptimeMs, 5109 boolean forceLog) { 5110 if (mPowerSaveModeEnabled != enabled) { 5111 int stepState = enabled ? STEP_LEVEL_MODE_POWER_SAVE : 0; 5112 mModStepMode |= (mCurStepMode & STEP_LEVEL_MODE_POWER_SAVE) ^ stepState; 5113 mCurStepMode = (mCurStepMode & ~STEP_LEVEL_MODE_POWER_SAVE) | stepState; 5114 mPowerSaveModeEnabled = enabled; 5115 if (enabled) { 5116 mHistoryCur.states2 |= HistoryItem.STATE2_POWER_SAVE_FLAG; 5117 if (DEBUG_HISTORY) { 5118 Slog.v(TAG, "Power save mode enabled to: " 5119 + Integer.toHexString(mHistoryCur.states2)); 5120 } 5121 mPowerSaveModeEnabledTimer.startRunningLocked(elapsedRealtimeMs); 5122 } else { 5123 mHistoryCur.states2 &= ~HistoryItem.STATE2_POWER_SAVE_FLAG; 5124 if (DEBUG_HISTORY) { 5125 Slog.v(TAG, "Power save mode disabled to: " 5126 + Integer.toHexString(mHistoryCur.states2)); 5127 } 5128 mPowerSaveModeEnabledTimer.stopRunningLocked(elapsedRealtimeMs); 5129 } 5130 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 5131 FrameworkStatsLog.write(FrameworkStatsLog.BATTERY_SAVER_MODE_STATE_CHANGED, 5132 enabled 5133 ? FrameworkStatsLog.BATTERY_SAVER_MODE_STATE_CHANGED__STATE__ON 5134 : FrameworkStatsLog.BATTERY_SAVER_MODE_STATE_CHANGED__STATE__OFF); 5135 } else if (forceLog) { 5136 // Log an initial value for BATTERY_SAVER_MODE_STATE_CHANGED in order to 5137 // allow the atom to read all future state changes. 5138 FrameworkStatsLog.write(FrameworkStatsLog.BATTERY_SAVER_MODE_STATE_CHANGED, 5139 enabled 5140 ? FrameworkStatsLog.BATTERY_SAVER_MODE_STATE_CHANGED__STATE__ON 5141 : FrameworkStatsLog.BATTERY_SAVER_MODE_STATE_CHANGED__STATE__OFF); 5142 } 5143 } 5144 noteDeviceIdleModeLocked(final int mode, String activeReason, int activeUid)5145 public void noteDeviceIdleModeLocked(final int mode, String activeReason, int activeUid) { 5146 noteDeviceIdleModeLocked(mode, activeReason, activeUid, 5147 mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 5148 } 5149 noteDeviceIdleModeLocked(final int mode, String activeReason, int activeUid, long elapsedRealtimeMs, long uptimeMs)5150 public void noteDeviceIdleModeLocked(final int mode, String activeReason, int activeUid, 5151 long elapsedRealtimeMs, long uptimeMs) { 5152 boolean nowIdling = mode == DEVICE_IDLE_MODE_DEEP; 5153 if (mDeviceIdling && !nowIdling && activeReason == null) { 5154 // We don't go out of general idling mode until explicitly taken out of 5155 // device idle through going active or significant motion. 5156 nowIdling = true; 5157 } 5158 boolean nowLightIdling = mode == DEVICE_IDLE_MODE_LIGHT; 5159 if (mDeviceLightIdling && !nowLightIdling && !nowIdling && activeReason == null) { 5160 // We don't go out of general light idling mode until explicitly taken out of 5161 // device idle through going active or significant motion. 5162 nowLightIdling = true; 5163 } 5164 if (activeReason != null && (mDeviceIdling || mDeviceLightIdling)) { 5165 addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_ACTIVE, 5166 activeReason, activeUid); 5167 } 5168 if (mDeviceIdling != nowIdling || mDeviceLightIdling != nowLightIdling) { 5169 int statsmode; 5170 if (nowIdling) statsmode = DEVICE_IDLE_MODE_DEEP; 5171 else if (nowLightIdling) statsmode = DEVICE_IDLE_MODE_LIGHT; 5172 else statsmode = DEVICE_IDLE_MODE_OFF; 5173 FrameworkStatsLog.write(FrameworkStatsLog.DEVICE_IDLING_MODE_STATE_CHANGED, statsmode); 5174 } 5175 if (mDeviceIdling != nowIdling) { 5176 mDeviceIdling = nowIdling; 5177 int stepState = nowIdling ? STEP_LEVEL_MODE_DEVICE_IDLE : 0; 5178 mModStepMode |= (mCurStepMode&STEP_LEVEL_MODE_DEVICE_IDLE) ^ stepState; 5179 mCurStepMode = (mCurStepMode&~STEP_LEVEL_MODE_DEVICE_IDLE) | stepState; 5180 if (nowIdling) { 5181 mDeviceIdlingTimer.startRunningLocked(elapsedRealtimeMs); 5182 } else { 5183 mDeviceIdlingTimer.stopRunningLocked(elapsedRealtimeMs); 5184 } 5185 } 5186 if (mDeviceLightIdling != nowLightIdling) { 5187 mDeviceLightIdling = nowLightIdling; 5188 if (nowLightIdling) { 5189 mDeviceLightIdlingTimer.startRunningLocked(elapsedRealtimeMs); 5190 } else { 5191 mDeviceLightIdlingTimer.stopRunningLocked(elapsedRealtimeMs); 5192 } 5193 } 5194 if (mDeviceIdleMode != mode) { 5195 mHistoryCur.states2 = (mHistoryCur.states2 & ~HistoryItem.STATE2_DEVICE_IDLE_MASK) 5196 | (mode << HistoryItem.STATE2_DEVICE_IDLE_SHIFT); 5197 if (DEBUG_HISTORY) Slog.v(TAG, "Device idle mode changed to: " 5198 + Integer.toHexString(mHistoryCur.states2)); 5199 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 5200 long lastDuration = elapsedRealtimeMs - mLastIdleTimeStartMs; 5201 mLastIdleTimeStartMs = elapsedRealtimeMs; 5202 if (mDeviceIdleMode == DEVICE_IDLE_MODE_LIGHT) { 5203 if (lastDuration > mLongestLightIdleTimeMs) { 5204 mLongestLightIdleTimeMs = lastDuration; 5205 } 5206 mDeviceIdleModeLightTimer.stopRunningLocked(elapsedRealtimeMs); 5207 } else if (mDeviceIdleMode == DEVICE_IDLE_MODE_DEEP) { 5208 if (lastDuration > mLongestFullIdleTimeMs) { 5209 mLongestFullIdleTimeMs = lastDuration; 5210 } 5211 mDeviceIdleModeFullTimer.stopRunningLocked(elapsedRealtimeMs); 5212 } 5213 if (mode == DEVICE_IDLE_MODE_LIGHT) { 5214 mDeviceIdleModeLightTimer.startRunningLocked(elapsedRealtimeMs); 5215 } else if (mode == DEVICE_IDLE_MODE_DEEP) { 5216 mDeviceIdleModeFullTimer.startRunningLocked(elapsedRealtimeMs); 5217 } 5218 mDeviceIdleMode = mode; 5219 FrameworkStatsLog.write(FrameworkStatsLog.DEVICE_IDLE_MODE_STATE_CHANGED, mode); 5220 } 5221 } 5222 notePackageInstalledLocked(String pkgName, long versionCode)5223 public void notePackageInstalledLocked(String pkgName, long versionCode) { 5224 notePackageInstalledLocked(pkgName, versionCode, 5225 mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 5226 } 5227 notePackageInstalledLocked(String pkgName, long versionCode, long elapsedRealtimeMs, long uptimeMs)5228 public void notePackageInstalledLocked(String pkgName, long versionCode, 5229 long elapsedRealtimeMs, long uptimeMs) { 5230 // XXX need to figure out what to do with long version codes. 5231 addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_PACKAGE_INSTALLED, 5232 pkgName, (int)versionCode); 5233 PackageChange pc = new PackageChange(); 5234 pc.mPackageName = pkgName; 5235 pc.mUpdate = true; 5236 pc.mVersionCode = versionCode; 5237 addPackageChange(pc); 5238 } 5239 notePackageUninstalledLocked(String pkgName)5240 public void notePackageUninstalledLocked(String pkgName) { 5241 notePackageUninstalledLocked(pkgName, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 5242 } 5243 notePackageUninstalledLocked(String pkgName, long elapsedRealtimeMs, long uptimeMs)5244 public void notePackageUninstalledLocked(String pkgName, 5245 long elapsedRealtimeMs, long uptimeMs) { 5246 addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, 5247 HistoryItem.EVENT_PACKAGE_UNINSTALLED, pkgName, 0); 5248 PackageChange pc = new PackageChange(); 5249 pc.mPackageName = pkgName; 5250 pc.mUpdate = true; 5251 addPackageChange(pc); 5252 } 5253 addPackageChange(PackageChange pc)5254 private void addPackageChange(PackageChange pc) { 5255 if (mDailyPackageChanges == null) { 5256 mDailyPackageChanges = new ArrayList<>(); 5257 } 5258 mDailyPackageChanges.add(pc); 5259 } 5260 stopAllGpsSignalQualityTimersLocked(int except)5261 void stopAllGpsSignalQualityTimersLocked(int except) { 5262 stopAllGpsSignalQualityTimersLocked(except, mClocks.elapsedRealtime()); 5263 } 5264 stopAllGpsSignalQualityTimersLocked(int except, long elapsedRealtimeMs)5265 void stopAllGpsSignalQualityTimersLocked(int except, long elapsedRealtimeMs) { 5266 for (int i = 0; i < mGpsSignalQualityTimer.length; i++) { 5267 if (i == except) { 5268 continue; 5269 } 5270 while (mGpsSignalQualityTimer[i].isRunningLocked()) { 5271 mGpsSignalQualityTimer[i].stopRunningLocked(elapsedRealtimeMs); 5272 } 5273 } 5274 } 5275 5276 @UnsupportedAppUsage notePhoneOnLocked()5277 public void notePhoneOnLocked() { 5278 notePhoneOnLocked(mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 5279 } 5280 notePhoneOnLocked(long elapsedRealtimeMs, long uptimeMs)5281 public void notePhoneOnLocked(long elapsedRealtimeMs, long uptimeMs) { 5282 if (!mPhoneOn) { 5283 mHistoryCur.states2 |= HistoryItem.STATE2_PHONE_IN_CALL_FLAG; 5284 if (DEBUG_HISTORY) Slog.v(TAG, "Phone on to: " 5285 + Integer.toHexString(mHistoryCur.states)); 5286 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 5287 mPhoneOn = true; 5288 mPhoneOnTimer.startRunningLocked(elapsedRealtimeMs); 5289 } 5290 } 5291 5292 @UnsupportedAppUsage notePhoneOffLocked()5293 public void notePhoneOffLocked() { 5294 notePhoneOffLocked(mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 5295 } 5296 notePhoneOffLocked(long elapsedRealtimeMs, long uptimeMs)5297 public void notePhoneOffLocked(long elapsedRealtimeMs, long uptimeMs) { 5298 if (mPhoneOn) { 5299 mHistoryCur.states2 &= ~HistoryItem.STATE2_PHONE_IN_CALL_FLAG; 5300 if (DEBUG_HISTORY) Slog.v(TAG, "Phone off to: " 5301 + Integer.toHexString(mHistoryCur.states)); 5302 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 5303 mPhoneOn = false; 5304 mPhoneOnTimer.stopRunningLocked(elapsedRealtimeMs); 5305 } 5306 } 5307 registerUsbStateReceiver(Context context)5308 private void registerUsbStateReceiver(Context context) { 5309 final IntentFilter usbStateFilter = new IntentFilter(); 5310 usbStateFilter.addAction(UsbManager.ACTION_USB_STATE); 5311 context.registerReceiver(new BroadcastReceiver() { 5312 @Override 5313 public void onReceive(Context context, Intent intent) { 5314 final boolean state = intent.getBooleanExtra(UsbManager.USB_CONNECTED, false); 5315 synchronized (BatteryStatsImpl.this) { 5316 noteUsbConnectionStateLocked(state, mClocks.elapsedRealtime(), 5317 mClocks.uptimeMillis()); 5318 } 5319 } 5320 }, usbStateFilter); 5321 synchronized (this) { 5322 if (mUsbDataState == USB_DATA_UNKNOWN) { 5323 final Intent usbState = context.registerReceiver(null, usbStateFilter); 5324 final boolean initState = usbState != null && usbState.getBooleanExtra( 5325 UsbManager.USB_CONNECTED, false); 5326 noteUsbConnectionStateLocked(initState, mClocks.elapsedRealtime(), 5327 mClocks.uptimeMillis()); 5328 } 5329 } 5330 } 5331 noteUsbConnectionStateLocked(boolean connected, long elapsedRealtimeMs, long uptimeMs)5332 private void noteUsbConnectionStateLocked(boolean connected, long elapsedRealtimeMs, 5333 long uptimeMs) { 5334 int newState = connected ? USB_DATA_CONNECTED : USB_DATA_DISCONNECTED; 5335 if (mUsbDataState != newState) { 5336 mUsbDataState = newState; 5337 if (connected) { 5338 mHistoryCur.states2 |= HistoryItem.STATE2_USB_DATA_LINK_FLAG; 5339 } else { 5340 mHistoryCur.states2 &= ~HistoryItem.STATE2_USB_DATA_LINK_FLAG; 5341 } 5342 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 5343 } 5344 } 5345 stopAllPhoneSignalStrengthTimersLocked(int except, long elapsedRealtimeMs)5346 void stopAllPhoneSignalStrengthTimersLocked(int except, long elapsedRealtimeMs) { 5347 for (int i = 0; i < CellSignalStrength.getNumSignalStrengthLevels(); i++) { 5348 if (i == except) { 5349 continue; 5350 } 5351 while (mPhoneSignalStrengthsTimer[i].isRunningLocked()) { 5352 mPhoneSignalStrengthsTimer[i].stopRunningLocked(elapsedRealtimeMs); 5353 } 5354 } 5355 } 5356 fixPhoneServiceState(int state, int signalBin)5357 private int fixPhoneServiceState(int state, int signalBin) { 5358 if (mPhoneSimStateRaw == TelephonyManager.SIM_STATE_ABSENT) { 5359 // In this case we will always be STATE_OUT_OF_SERVICE, so need 5360 // to infer that we are scanning from other data. 5361 if (state == ServiceState.STATE_OUT_OF_SERVICE 5362 && signalBin > CellSignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN) { 5363 state = ServiceState.STATE_IN_SERVICE; 5364 } 5365 } 5366 5367 return state; 5368 } 5369 updateAllPhoneStateLocked(int state, int simState, int strengthBin, long elapsedRealtimeMs, long uptimeMs)5370 private void updateAllPhoneStateLocked(int state, int simState, int strengthBin, 5371 long elapsedRealtimeMs, long uptimeMs) { 5372 boolean scanning = false; 5373 boolean newHistory = false; 5374 5375 mPhoneServiceStateRaw = state; 5376 mPhoneSimStateRaw = simState; 5377 mPhoneSignalStrengthBinRaw = strengthBin; 5378 5379 if (simState == TelephonyManager.SIM_STATE_ABSENT) { 5380 // In this case we will always be STATE_OUT_OF_SERVICE, so need 5381 // to infer that we are scanning from other data. 5382 if (state == ServiceState.STATE_OUT_OF_SERVICE 5383 && strengthBin > CellSignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN) { 5384 state = ServiceState.STATE_IN_SERVICE; 5385 } 5386 } 5387 5388 // If the phone is powered off, stop all timers. 5389 if (state == ServiceState.STATE_POWER_OFF) { 5390 strengthBin = -1; 5391 5392 // If we are in service, make sure the correct signal string timer is running. 5393 } else if (state == ServiceState.STATE_IN_SERVICE) { 5394 // Bin will be changed below. 5395 5396 // If we're out of service, we are in the lowest signal strength 5397 // bin and have the scanning bit set. 5398 } else if (state == ServiceState.STATE_OUT_OF_SERVICE) { 5399 scanning = true; 5400 strengthBin = CellSignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN; 5401 if (!mPhoneSignalScanningTimer.isRunningLocked()) { 5402 mHistoryCur.states |= HistoryItem.STATE_PHONE_SCANNING_FLAG; 5403 newHistory = true; 5404 if (DEBUG_HISTORY) Slog.v(TAG, "Phone started scanning to: " 5405 + Integer.toHexString(mHistoryCur.states)); 5406 mPhoneSignalScanningTimer.startRunningLocked(elapsedRealtimeMs); 5407 FrameworkStatsLog.write(FrameworkStatsLog.PHONE_SERVICE_STATE_CHANGED, state, 5408 simState, strengthBin); 5409 } 5410 } 5411 5412 if (!scanning) { 5413 // If we are no longer scanning, then stop the scanning timer. 5414 if (mPhoneSignalScanningTimer.isRunningLocked()) { 5415 mHistoryCur.states &= ~HistoryItem.STATE_PHONE_SCANNING_FLAG; 5416 if (DEBUG_HISTORY) Slog.v(TAG, "Phone stopped scanning to: " 5417 + Integer.toHexString(mHistoryCur.states)); 5418 newHistory = true; 5419 mPhoneSignalScanningTimer.stopRunningLocked(elapsedRealtimeMs); 5420 FrameworkStatsLog.write(FrameworkStatsLog.PHONE_SERVICE_STATE_CHANGED, state, 5421 simState, strengthBin); 5422 } 5423 } 5424 5425 if (mPhoneServiceState != state) { 5426 mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_PHONE_STATE_MASK) 5427 | (state << HistoryItem.STATE_PHONE_STATE_SHIFT); 5428 if (DEBUG_HISTORY) Slog.v(TAG, "Phone state " + state + " to: " 5429 + Integer.toHexString(mHistoryCur.states)); 5430 newHistory = true; 5431 mPhoneServiceState = state; 5432 } 5433 5434 if (mPhoneSignalStrengthBin != strengthBin) { 5435 if (mPhoneSignalStrengthBin >= 0) { 5436 mPhoneSignalStrengthsTimer[mPhoneSignalStrengthBin].stopRunningLocked( 5437 elapsedRealtimeMs); 5438 } 5439 if (strengthBin >= 0) { 5440 if (!mPhoneSignalStrengthsTimer[strengthBin].isRunningLocked()) { 5441 mPhoneSignalStrengthsTimer[strengthBin].startRunningLocked(elapsedRealtimeMs); 5442 } 5443 mHistoryCur.states = 5444 (mHistoryCur.states & ~HistoryItem.STATE_PHONE_SIGNAL_STRENGTH_MASK) 5445 | (strengthBin << HistoryItem.STATE_PHONE_SIGNAL_STRENGTH_SHIFT); 5446 if (DEBUG_HISTORY) Slog.v(TAG, "Signal strength " + strengthBin + " to: " 5447 + Integer.toHexString(mHistoryCur.states)); 5448 newHistory = true; 5449 FrameworkStatsLog.write( 5450 FrameworkStatsLog.PHONE_SIGNAL_STRENGTH_CHANGED, strengthBin); 5451 } else { 5452 stopAllPhoneSignalStrengthTimersLocked(-1, elapsedRealtimeMs); 5453 } 5454 mPhoneSignalStrengthBin = strengthBin; 5455 } 5456 5457 if (newHistory) { 5458 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 5459 } 5460 } 5461 5462 /** 5463 * Telephony stack updates the phone state. 5464 * @param state phone state from ServiceState.getState() 5465 */ notePhoneStateLocked(int state, int simState)5466 public void notePhoneStateLocked(int state, int simState) { 5467 notePhoneStateLocked(state, simState, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 5468 } 5469 notePhoneStateLocked(int state, int simState, long elapsedRealtimeMs, long uptimeMs)5470 public void notePhoneStateLocked(int state, int simState, 5471 long elapsedRealtimeMs, long uptimeMs) { 5472 updateAllPhoneStateLocked(state, simState, mPhoneSignalStrengthBinRaw, 5473 elapsedRealtimeMs, uptimeMs); 5474 } 5475 5476 @UnsupportedAppUsage notePhoneSignalStrengthLocked(SignalStrength signalStrength)5477 public void notePhoneSignalStrengthLocked(SignalStrength signalStrength) { 5478 notePhoneSignalStrengthLocked(signalStrength, 5479 mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 5480 } 5481 notePhoneSignalStrengthLocked(SignalStrength signalStrength, long elapsedRealtimeMs, long uptimeMs)5482 public void notePhoneSignalStrengthLocked(SignalStrength signalStrength, 5483 long elapsedRealtimeMs, long uptimeMs) { 5484 // Bin the strength. 5485 int bin = signalStrength.getLevel(); 5486 updateAllPhoneStateLocked(mPhoneServiceStateRaw, mPhoneSimStateRaw, bin, 5487 elapsedRealtimeMs, uptimeMs); 5488 } 5489 5490 @UnsupportedAppUsage notePhoneDataConnectionStateLocked(int dataType, boolean hasData, int serviceType)5491 public void notePhoneDataConnectionStateLocked(int dataType, boolean hasData, int serviceType) { 5492 notePhoneDataConnectionStateLocked(dataType, hasData, serviceType, 5493 mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 5494 } 5495 notePhoneDataConnectionStateLocked(int dataType, boolean hasData, int serviceType, long elapsedRealtimeMs, long uptimeMs)5496 public void notePhoneDataConnectionStateLocked(int dataType, boolean hasData, int serviceType, 5497 long elapsedRealtimeMs, long uptimeMs) { 5498 // BatteryStats uses 0 to represent no network type. 5499 // Telephony does not have a concept of no network type, and uses 0 to represent unknown. 5500 // Unknown is included in DATA_CONNECTION_OTHER. 5501 int bin = DATA_CONNECTION_OUT_OF_SERVICE; 5502 if (hasData) { 5503 if (dataType > 0 && dataType <= TelephonyManager.getAllNetworkTypes().length) { 5504 bin = dataType; 5505 } else { 5506 switch (serviceType) { 5507 case ServiceState.STATE_OUT_OF_SERVICE: 5508 bin = DATA_CONNECTION_OUT_OF_SERVICE; 5509 break; 5510 case ServiceState.STATE_EMERGENCY_ONLY: 5511 bin = DATA_CONNECTION_EMERGENCY_SERVICE; 5512 break; 5513 default: 5514 bin = DATA_CONNECTION_OTHER; 5515 break; 5516 } 5517 } 5518 } 5519 if (DEBUG) Log.i(TAG, "Phone Data Connection -> " + dataType + " = " + hasData); 5520 if (mPhoneDataConnectionType != bin) { 5521 mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_DATA_CONNECTION_MASK) 5522 | (bin << HistoryItem.STATE_DATA_CONNECTION_SHIFT); 5523 if (DEBUG_HISTORY) Slog.v(TAG, "Data connection " + bin + " to: " 5524 + Integer.toHexString(mHistoryCur.states)); 5525 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 5526 if (mPhoneDataConnectionType >= 0) { 5527 mPhoneDataConnectionsTimer[mPhoneDataConnectionType].stopRunningLocked( 5528 elapsedRealtimeMs); 5529 } 5530 mPhoneDataConnectionType = bin; 5531 mPhoneDataConnectionsTimer[bin].startRunningLocked(elapsedRealtimeMs); 5532 } 5533 } 5534 noteWifiOnLocked()5535 public void noteWifiOnLocked() { 5536 noteWifiOnLocked(mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 5537 } 5538 noteWifiOnLocked(long elapsedRealtimeMs, long uptimeMs)5539 public void noteWifiOnLocked(long elapsedRealtimeMs, long uptimeMs) { 5540 if (!mWifiOn) { 5541 mHistoryCur.states2 |= HistoryItem.STATE2_WIFI_ON_FLAG; 5542 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI on to: " 5543 + Integer.toHexString(mHistoryCur.states)); 5544 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 5545 mWifiOn = true; 5546 mWifiOnTimer.startRunningLocked(elapsedRealtimeMs); 5547 scheduleSyncExternalStatsLocked("wifi-off", ExternalStatsSync.UPDATE_WIFI); 5548 } 5549 } 5550 noteWifiOffLocked()5551 public void noteWifiOffLocked() { 5552 noteWifiOffLocked(mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 5553 } 5554 noteWifiOffLocked(long elapsedRealtimeMs, long uptimeMs)5555 public void noteWifiOffLocked(long elapsedRealtimeMs, long uptimeMs) { 5556 if (mWifiOn) { 5557 mHistoryCur.states2 &= ~HistoryItem.STATE2_WIFI_ON_FLAG; 5558 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI off to: " 5559 + Integer.toHexString(mHistoryCur.states)); 5560 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 5561 mWifiOn = false; 5562 mWifiOnTimer.stopRunningLocked(elapsedRealtimeMs); 5563 scheduleSyncExternalStatsLocked("wifi-on", ExternalStatsSync.UPDATE_WIFI); 5564 } 5565 } 5566 5567 @UnsupportedAppUsage noteAudioOnLocked(int uid)5568 public void noteAudioOnLocked(int uid) { 5569 noteAudioOnLocked(uid, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 5570 } 5571 noteAudioOnLocked(int uid, long elapsedRealtimeMs, long uptimeMs)5572 public void noteAudioOnLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 5573 uid = mapUid(uid); 5574 if (mAudioOnNesting == 0) { 5575 mHistoryCur.states |= HistoryItem.STATE_AUDIO_ON_FLAG; 5576 if (DEBUG_HISTORY) Slog.v(TAG, "Audio on to: " 5577 + Integer.toHexString(mHistoryCur.states)); 5578 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 5579 mAudioOnTimer.startRunningLocked(elapsedRealtimeMs); 5580 } 5581 mAudioOnNesting++; 5582 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 5583 .noteAudioTurnedOnLocked(elapsedRealtimeMs); 5584 } 5585 5586 @UnsupportedAppUsage noteAudioOffLocked(int uid)5587 public void noteAudioOffLocked(int uid) { 5588 noteAudioOffLocked(uid, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 5589 } 5590 noteAudioOffLocked(int uid, long elapsedRealtimeMs, long uptimeMs)5591 public void noteAudioOffLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 5592 if (mAudioOnNesting == 0) { 5593 return; 5594 } 5595 uid = mapUid(uid); 5596 if (--mAudioOnNesting == 0) { 5597 mHistoryCur.states &= ~HistoryItem.STATE_AUDIO_ON_FLAG; 5598 if (DEBUG_HISTORY) Slog.v(TAG, "Audio off to: " 5599 + Integer.toHexString(mHistoryCur.states)); 5600 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 5601 mAudioOnTimer.stopRunningLocked(elapsedRealtimeMs); 5602 } 5603 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 5604 .noteAudioTurnedOffLocked(elapsedRealtimeMs); 5605 } 5606 5607 @UnsupportedAppUsage noteVideoOnLocked(int uid)5608 public void noteVideoOnLocked(int uid) { 5609 noteVideoOnLocked(uid, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 5610 } 5611 noteVideoOnLocked(int uid, long elapsedRealtimeMs, long uptimeMs)5612 public void noteVideoOnLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 5613 uid = mapUid(uid); 5614 if (mVideoOnNesting == 0) { 5615 mHistoryCur.states2 |= HistoryItem.STATE2_VIDEO_ON_FLAG; 5616 if (DEBUG_HISTORY) Slog.v(TAG, "Video on to: " 5617 + Integer.toHexString(mHistoryCur.states)); 5618 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 5619 mVideoOnTimer.startRunningLocked(elapsedRealtimeMs); 5620 } 5621 mVideoOnNesting++; 5622 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 5623 .noteVideoTurnedOnLocked(elapsedRealtimeMs); 5624 } 5625 5626 @UnsupportedAppUsage noteVideoOffLocked(int uid)5627 public void noteVideoOffLocked(int uid) { 5628 noteVideoOffLocked(uid, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 5629 } 5630 noteVideoOffLocked(int uid, long elapsedRealtimeMs, long uptimeMs)5631 public void noteVideoOffLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 5632 if (mVideoOnNesting == 0) { 5633 return; 5634 } 5635 uid = mapUid(uid); 5636 if (--mVideoOnNesting == 0) { 5637 mHistoryCur.states2 &= ~HistoryItem.STATE2_VIDEO_ON_FLAG; 5638 if (DEBUG_HISTORY) Slog.v(TAG, "Video off to: " 5639 + Integer.toHexString(mHistoryCur.states)); 5640 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 5641 mVideoOnTimer.stopRunningLocked(elapsedRealtimeMs); 5642 } 5643 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 5644 .noteVideoTurnedOffLocked(elapsedRealtimeMs); 5645 } 5646 noteResetAudioLocked()5647 public void noteResetAudioLocked() { 5648 noteResetAudioLocked(mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 5649 } 5650 noteResetAudioLocked(long elapsedRealtimeMs, long uptimeMs)5651 public void noteResetAudioLocked(long elapsedRealtimeMs, long uptimeMs) { 5652 if (mAudioOnNesting > 0) { 5653 mAudioOnNesting = 0; 5654 mHistoryCur.states &= ~HistoryItem.STATE_AUDIO_ON_FLAG; 5655 if (DEBUG_HISTORY) Slog.v(TAG, "Audio off to: " 5656 + Integer.toHexString(mHistoryCur.states)); 5657 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 5658 mAudioOnTimer.stopAllRunningLocked(elapsedRealtimeMs); 5659 for (int i=0; i<mUidStats.size(); i++) { 5660 BatteryStatsImpl.Uid uid = mUidStats.valueAt(i); 5661 uid.noteResetAudioLocked(elapsedRealtimeMs); 5662 } 5663 } 5664 } 5665 noteResetVideoLocked()5666 public void noteResetVideoLocked() { 5667 noteResetVideoLocked(mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 5668 } 5669 noteResetVideoLocked(long elapsedRealtimeMs, long uptimeMs)5670 public void noteResetVideoLocked(long elapsedRealtimeMs, long uptimeMs) { 5671 if (mVideoOnNesting > 0) { 5672 mVideoOnNesting = 0; 5673 mHistoryCur.states2 &= ~HistoryItem.STATE2_VIDEO_ON_FLAG; 5674 if (DEBUG_HISTORY) Slog.v(TAG, "Video off to: " 5675 + Integer.toHexString(mHistoryCur.states)); 5676 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 5677 mVideoOnTimer.stopAllRunningLocked(elapsedRealtimeMs); 5678 for (int i=0; i<mUidStats.size(); i++) { 5679 BatteryStatsImpl.Uid uid = mUidStats.valueAt(i); 5680 uid.noteResetVideoLocked(elapsedRealtimeMs); 5681 } 5682 } 5683 } 5684 noteActivityResumedLocked(int uid)5685 public void noteActivityResumedLocked(int uid) { 5686 noteActivityResumedLocked(uid, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 5687 } 5688 noteActivityResumedLocked(int uid, long elapsedRealtimeMs, long uptimeMs)5689 public void noteActivityResumedLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 5690 uid = mapUid(uid); 5691 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 5692 .noteActivityResumedLocked(elapsedRealtimeMs); 5693 } 5694 noteActivityPausedLocked(int uid)5695 public void noteActivityPausedLocked(int uid) { 5696 noteActivityPausedLocked(uid, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 5697 } 5698 noteActivityPausedLocked(int uid, long elapsedRealtimeMs, long uptimeMs)5699 public void noteActivityPausedLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 5700 uid = mapUid(uid); 5701 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 5702 .noteActivityPausedLocked(elapsedRealtimeMs); 5703 } 5704 noteVibratorOnLocked(int uid, long durationMillis)5705 public void noteVibratorOnLocked(int uid, long durationMillis) { 5706 noteVibratorOnLocked(uid, durationMillis, 5707 mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 5708 } 5709 noteVibratorOnLocked(int uid, long durationMillis, long elapsedRealtimeMs, long uptimeMs)5710 public void noteVibratorOnLocked(int uid, long durationMillis, 5711 long elapsedRealtimeMs, long uptimeMs) { 5712 uid = mapUid(uid); 5713 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 5714 .noteVibratorOnLocked(durationMillis, elapsedRealtimeMs); 5715 } 5716 noteVibratorOffLocked(int uid)5717 public void noteVibratorOffLocked(int uid) { 5718 noteVibratorOffLocked(uid, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 5719 } 5720 noteVibratorOffLocked(int uid, long elapsedRealtimeMs, long uptimeMs)5721 public void noteVibratorOffLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 5722 uid = mapUid(uid); 5723 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 5724 .noteVibratorOffLocked(elapsedRealtimeMs); 5725 } 5726 noteFlashlightOnLocked(int uid)5727 public void noteFlashlightOnLocked(int uid) { 5728 noteFlashlightOnLocked(uid, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 5729 } 5730 noteFlashlightOnLocked(int uid, long elapsedRealtimeMs, long uptimeMs)5731 public void noteFlashlightOnLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 5732 uid = mapUid(uid); 5733 if (mFlashlightOnNesting++ == 0) { 5734 mHistoryCur.states2 |= HistoryItem.STATE2_FLASHLIGHT_FLAG; 5735 if (DEBUG_HISTORY) Slog.v(TAG, "Flashlight on to: " 5736 + Integer.toHexString(mHistoryCur.states2)); 5737 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 5738 mFlashlightOnTimer.startRunningLocked(elapsedRealtimeMs); 5739 } 5740 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 5741 .noteFlashlightTurnedOnLocked(elapsedRealtimeMs); 5742 } 5743 noteFlashlightOffLocked(int uid)5744 public void noteFlashlightOffLocked(int uid) { 5745 noteFlashlightOffLocked(uid, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 5746 } 5747 noteFlashlightOffLocked(int uid, long elapsedRealtimeMs, long uptimeMs)5748 public void noteFlashlightOffLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 5749 if (mFlashlightOnNesting == 0) { 5750 return; 5751 } 5752 uid = mapUid(uid); 5753 if (--mFlashlightOnNesting == 0) { 5754 mHistoryCur.states2 &= ~HistoryItem.STATE2_FLASHLIGHT_FLAG; 5755 if (DEBUG_HISTORY) Slog.v(TAG, "Flashlight off to: " 5756 + Integer.toHexString(mHistoryCur.states2)); 5757 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 5758 mFlashlightOnTimer.stopRunningLocked(elapsedRealtimeMs); 5759 } 5760 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 5761 .noteFlashlightTurnedOffLocked(elapsedRealtimeMs); 5762 } 5763 noteCameraOnLocked(int uid)5764 public void noteCameraOnLocked(int uid) { 5765 noteCameraOnLocked(uid, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 5766 } 5767 noteCameraOnLocked(int uid, long elapsedRealtimeMs, long uptimeMs)5768 public void noteCameraOnLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 5769 uid = mapUid(uid); 5770 if (mCameraOnNesting++ == 0) { 5771 mHistoryCur.states2 |= HistoryItem.STATE2_CAMERA_FLAG; 5772 if (DEBUG_HISTORY) Slog.v(TAG, "Camera on to: " 5773 + Integer.toHexString(mHistoryCur.states2)); 5774 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 5775 mCameraOnTimer.startRunningLocked(elapsedRealtimeMs); 5776 } 5777 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 5778 .noteCameraTurnedOnLocked(elapsedRealtimeMs); 5779 } 5780 noteCameraOffLocked(int uid)5781 public void noteCameraOffLocked(int uid) { 5782 noteCameraOffLocked(uid, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 5783 } 5784 noteCameraOffLocked(int uid, long elapsedRealtimeMs, long uptimeMs)5785 public void noteCameraOffLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 5786 if (mCameraOnNesting == 0) { 5787 return; 5788 } 5789 uid = mapUid(uid); 5790 if (--mCameraOnNesting == 0) { 5791 mHistoryCur.states2 &= ~HistoryItem.STATE2_CAMERA_FLAG; 5792 if (DEBUG_HISTORY) Slog.v(TAG, "Camera off to: " 5793 + Integer.toHexString(mHistoryCur.states2)); 5794 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 5795 mCameraOnTimer.stopRunningLocked(elapsedRealtimeMs); 5796 } 5797 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 5798 .noteCameraTurnedOffLocked(elapsedRealtimeMs); 5799 } 5800 noteResetCameraLocked()5801 public void noteResetCameraLocked() { 5802 noteResetCameraLocked(mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 5803 } 5804 noteResetCameraLocked(long elapsedRealtimeMs, long uptimeMs)5805 public void noteResetCameraLocked(long elapsedRealtimeMs, long uptimeMs) { 5806 if (mCameraOnNesting > 0) { 5807 mCameraOnNesting = 0; 5808 mHistoryCur.states2 &= ~HistoryItem.STATE2_CAMERA_FLAG; 5809 if (DEBUG_HISTORY) Slog.v(TAG, "Camera off to: " 5810 + Integer.toHexString(mHistoryCur.states2)); 5811 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 5812 mCameraOnTimer.stopAllRunningLocked(elapsedRealtimeMs); 5813 for (int i=0; i<mUidStats.size(); i++) { 5814 BatteryStatsImpl.Uid uid = mUidStats.valueAt(i); 5815 uid.noteResetCameraLocked(elapsedRealtimeMs); 5816 } 5817 } 5818 } 5819 noteResetFlashlightLocked()5820 public void noteResetFlashlightLocked() { 5821 noteResetFlashlightLocked(mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 5822 } 5823 noteResetFlashlightLocked(long elapsedRealtimeMs, long uptimeMs)5824 public void noteResetFlashlightLocked(long elapsedRealtimeMs, long uptimeMs) { 5825 if (mFlashlightOnNesting > 0) { 5826 mFlashlightOnNesting = 0; 5827 mHistoryCur.states2 &= ~HistoryItem.STATE2_FLASHLIGHT_FLAG; 5828 if (DEBUG_HISTORY) Slog.v(TAG, "Flashlight off to: " 5829 + Integer.toHexString(mHistoryCur.states2)); 5830 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 5831 mFlashlightOnTimer.stopAllRunningLocked(elapsedRealtimeMs); 5832 for (int i=0; i<mUidStats.size(); i++) { 5833 BatteryStatsImpl.Uid uid = mUidStats.valueAt(i); 5834 uid.noteResetFlashlightLocked(elapsedRealtimeMs); 5835 } 5836 } 5837 } 5838 noteBluetoothScanStartedLocked(WorkChain workChain, int uid, boolean isUnoptimized, long elapsedRealtimeMs, long uptimeMs)5839 private void noteBluetoothScanStartedLocked(WorkChain workChain, int uid, 5840 boolean isUnoptimized, long elapsedRealtimeMs, long uptimeMs) { 5841 uid = getAttributionUid(uid, workChain); 5842 if (mBluetoothScanNesting == 0) { 5843 mHistoryCur.states2 |= HistoryItem.STATE2_BLUETOOTH_SCAN_FLAG; 5844 if (DEBUG_HISTORY) Slog.v(TAG, "BLE scan started for: " 5845 + Integer.toHexString(mHistoryCur.states2)); 5846 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 5847 mBluetoothScanTimer.startRunningLocked(elapsedRealtimeMs); 5848 } 5849 mBluetoothScanNesting++; 5850 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 5851 .noteBluetoothScanStartedLocked(elapsedRealtimeMs, isUnoptimized); 5852 } 5853 noteBluetoothScanStartedFromSourceLocked(WorkSource ws, boolean isUnoptimized)5854 public void noteBluetoothScanStartedFromSourceLocked(WorkSource ws, boolean isUnoptimized) { 5855 noteBluetoothScanStartedFromSourceLocked(ws, isUnoptimized, 5856 mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 5857 } 5858 noteBluetoothScanStartedFromSourceLocked(WorkSource ws, boolean isUnoptimized, long elapsedRealtimeMs, long uptimeMs)5859 public void noteBluetoothScanStartedFromSourceLocked(WorkSource ws, boolean isUnoptimized, 5860 long elapsedRealtimeMs, long uptimeMs) { 5861 final int N = ws.size(); 5862 for (int i = 0; i < N; i++) { 5863 noteBluetoothScanStartedLocked(null, ws.getUid(i), isUnoptimized, 5864 elapsedRealtimeMs, uptimeMs); 5865 } 5866 5867 final List<WorkChain> workChains = ws.getWorkChains(); 5868 if (workChains != null) { 5869 for (int i = 0; i < workChains.size(); ++i) { 5870 noteBluetoothScanStartedLocked(workChains.get(i), -1, isUnoptimized, 5871 elapsedRealtimeMs, uptimeMs); 5872 } 5873 } 5874 } 5875 noteBluetoothScanStoppedLocked(WorkChain workChain, int uid, boolean isUnoptimized, long elapsedRealtimeMs, long uptimeMs)5876 private void noteBluetoothScanStoppedLocked(WorkChain workChain, int uid, 5877 boolean isUnoptimized, long elapsedRealtimeMs, long uptimeMs) { 5878 uid = getAttributionUid(uid, workChain); 5879 mBluetoothScanNesting--; 5880 if (mBluetoothScanNesting == 0) { 5881 mHistoryCur.states2 &= ~HistoryItem.STATE2_BLUETOOTH_SCAN_FLAG; 5882 if (DEBUG_HISTORY) Slog.v(TAG, "BLE scan stopped for: " 5883 + Integer.toHexString(mHistoryCur.states2)); 5884 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 5885 mBluetoothScanTimer.stopRunningLocked(elapsedRealtimeMs); 5886 } 5887 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 5888 .noteBluetoothScanStoppedLocked(elapsedRealtimeMs, isUnoptimized); 5889 } 5890 getAttributionUid(int uid, WorkChain workChain)5891 private int getAttributionUid(int uid, WorkChain workChain) { 5892 if (workChain != null) { 5893 return mapUid(workChain.getAttributionUid()); 5894 } 5895 5896 return mapUid(uid); 5897 } 5898 noteBluetoothScanStoppedFromSourceLocked(WorkSource ws, boolean isUnoptimized)5899 public void noteBluetoothScanStoppedFromSourceLocked(WorkSource ws, boolean isUnoptimized) { 5900 noteBluetoothScanStoppedFromSourceLocked(ws, isUnoptimized, 5901 mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 5902 } 5903 noteBluetoothScanStoppedFromSourceLocked(WorkSource ws, boolean isUnoptimized, long elapsedRealtimeMs, long uptimeMs)5904 public void noteBluetoothScanStoppedFromSourceLocked(WorkSource ws, boolean isUnoptimized, 5905 long elapsedRealtimeMs, long uptimeMs) { 5906 final int N = ws.size(); 5907 for (int i = 0; i < N; i++) { 5908 noteBluetoothScanStoppedLocked(null, ws.getUid(i), isUnoptimized, 5909 elapsedRealtimeMs, uptimeMs); 5910 } 5911 5912 final List<WorkChain> workChains = ws.getWorkChains(); 5913 if (workChains != null) { 5914 for (int i = 0; i < workChains.size(); ++i) { 5915 noteBluetoothScanStoppedLocked(workChains.get(i), -1, isUnoptimized, 5916 elapsedRealtimeMs, uptimeMs); 5917 } 5918 } 5919 } 5920 noteResetBluetoothScanLocked()5921 public void noteResetBluetoothScanLocked() { 5922 noteResetBluetoothScanLocked(mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 5923 } 5924 noteResetBluetoothScanLocked(long elapsedRealtimeMs, long uptimeMs)5925 public void noteResetBluetoothScanLocked(long elapsedRealtimeMs, long uptimeMs) { 5926 if (mBluetoothScanNesting > 0) { 5927 mBluetoothScanNesting = 0; 5928 mHistoryCur.states2 &= ~HistoryItem.STATE2_BLUETOOTH_SCAN_FLAG; 5929 if (DEBUG_HISTORY) Slog.v(TAG, "BLE can stopped for: " 5930 + Integer.toHexString(mHistoryCur.states2)); 5931 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 5932 mBluetoothScanTimer.stopAllRunningLocked(elapsedRealtimeMs); 5933 for (int i=0; i<mUidStats.size(); i++) { 5934 BatteryStatsImpl.Uid uid = mUidStats.valueAt(i); 5935 uid.noteResetBluetoothScanLocked(elapsedRealtimeMs); 5936 } 5937 } 5938 } 5939 noteBluetoothScanResultsFromSourceLocked(WorkSource ws, int numNewResults)5940 public void noteBluetoothScanResultsFromSourceLocked(WorkSource ws, int numNewResults) { 5941 noteBluetoothScanResultsFromSourceLocked(ws, numNewResults, 5942 mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 5943 } 5944 noteBluetoothScanResultsFromSourceLocked(WorkSource ws, int numNewResults, long elapsedRealtimeMs, long uptimeMs)5945 public void noteBluetoothScanResultsFromSourceLocked(WorkSource ws, int numNewResults, 5946 long elapsedRealtimeMs, long uptimeMs) { 5947 final int N = ws.size(); 5948 for (int i = 0; i < N; i++) { 5949 int uid = mapUid(ws.getUid(i)); 5950 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 5951 .noteBluetoothScanResultsLocked(numNewResults); 5952 } 5953 5954 final List<WorkChain> workChains = ws.getWorkChains(); 5955 if (workChains != null) { 5956 for (int i = 0; i < workChains.size(); ++i) { 5957 final WorkChain wc = workChains.get(i); 5958 int uid = mapUid(wc.getAttributionUid()); 5959 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 5960 .noteBluetoothScanResultsLocked(numNewResults); 5961 } 5962 } 5963 } 5964 noteWifiRadioApWakeupLocked(final long elapsedRealtimeMillis, final long uptimeMillis, int uid)5965 private void noteWifiRadioApWakeupLocked(final long elapsedRealtimeMillis, 5966 final long uptimeMillis, int uid) { 5967 uid = mapUid(uid); 5968 addHistoryEventLocked(elapsedRealtimeMillis, uptimeMillis, HistoryItem.EVENT_WAKEUP_AP, "", 5969 uid); 5970 getUidStatsLocked(uid, elapsedRealtimeMillis, uptimeMillis).noteWifiRadioApWakeupLocked(); 5971 } 5972 noteWifiRadioPowerState(int powerState, long timestampNs, int uid)5973 public void noteWifiRadioPowerState(int powerState, long timestampNs, int uid) { 5974 noteWifiRadioPowerState(powerState, timestampNs, uid, 5975 mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 5976 } 5977 noteWifiRadioPowerState(int powerState, long timestampNs, int uid, long elapsedRealtimeMs, long uptimeMs)5978 public void noteWifiRadioPowerState(int powerState, long timestampNs, int uid, 5979 long elapsedRealtimeMs, long uptimeMs) { 5980 if (mWifiRadioPowerState != powerState) { 5981 final boolean active = 5982 powerState == DataConnectionRealTimeInfo.DC_POWER_STATE_MEDIUM 5983 || powerState == DataConnectionRealTimeInfo.DC_POWER_STATE_HIGH; 5984 if (active) { 5985 if (uid > 0) { 5986 noteWifiRadioApWakeupLocked(elapsedRealtimeMs, uptimeMs, uid); 5987 } 5988 mHistoryCur.states |= HistoryItem.STATE_WIFI_RADIO_ACTIVE_FLAG; 5989 mWifiActiveTimer.startRunningLocked(elapsedRealtimeMs); 5990 } else { 5991 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_RADIO_ACTIVE_FLAG; 5992 mWifiActiveTimer.stopRunningLocked(timestampNs / (1000 * 1000)); 5993 } 5994 if (DEBUG_HISTORY) Slog.v(TAG, "Wifi network active " + active + " to: " 5995 + Integer.toHexString(mHistoryCur.states)); 5996 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 5997 mWifiRadioPowerState = powerState; 5998 } 5999 } 6000 noteWifiRunningLocked(WorkSource ws)6001 public void noteWifiRunningLocked(WorkSource ws) { 6002 noteWifiRunningLocked(ws, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 6003 } 6004 noteWifiRunningLocked(WorkSource ws, long elapsedRealtimeMs, long uptimeMs)6005 public void noteWifiRunningLocked(WorkSource ws, long elapsedRealtimeMs, long uptimeMs) { 6006 if (!mGlobalWifiRunning) { 6007 mHistoryCur.states2 |= HistoryItem.STATE2_WIFI_RUNNING_FLAG; 6008 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI running to: " 6009 + Integer.toHexString(mHistoryCur.states)); 6010 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 6011 mGlobalWifiRunning = true; 6012 mGlobalWifiRunningTimer.startRunningLocked(elapsedRealtimeMs); 6013 int N = ws.size(); 6014 for (int i=0; i<N; i++) { 6015 int uid = mapUid(ws.getUid(i)); 6016 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6017 .noteWifiRunningLocked(elapsedRealtimeMs); 6018 } 6019 6020 List<WorkChain> workChains = ws.getWorkChains(); 6021 if (workChains != null) { 6022 for (int i = 0; i < workChains.size(); ++i) { 6023 int uid = mapUid(workChains.get(i).getAttributionUid()); 6024 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6025 .noteWifiRunningLocked(elapsedRealtimeMs); 6026 } 6027 } 6028 6029 scheduleSyncExternalStatsLocked("wifi-running", ExternalStatsSync.UPDATE_WIFI); 6030 } else { 6031 Log.w(TAG, "noteWifiRunningLocked -- called while WIFI running"); 6032 } 6033 } 6034 noteWifiRunningChangedLocked(WorkSource oldWs, WorkSource newWs)6035 public void noteWifiRunningChangedLocked(WorkSource oldWs, WorkSource newWs) { 6036 noteWifiRunningChangedLocked(oldWs, newWs, 6037 mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 6038 } 6039 noteWifiRunningChangedLocked(WorkSource oldWs, WorkSource newWs, long elapsedRealtimeMs, long uptimeMs)6040 public void noteWifiRunningChangedLocked(WorkSource oldWs, WorkSource newWs, 6041 long elapsedRealtimeMs, long uptimeMs) { 6042 if (mGlobalWifiRunning) { 6043 int N = oldWs.size(); 6044 for (int i=0; i<N; i++) { 6045 int uid = mapUid(oldWs.getUid(i)); 6046 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6047 .noteWifiStoppedLocked(elapsedRealtimeMs); 6048 } 6049 6050 List<WorkChain> workChains = oldWs.getWorkChains(); 6051 if (workChains != null) { 6052 for (int i = 0; i < workChains.size(); ++i) { 6053 int uid = mapUid(workChains.get(i).getAttributionUid()); 6054 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6055 .noteWifiStoppedLocked(elapsedRealtimeMs); 6056 } 6057 } 6058 6059 N = newWs.size(); 6060 for (int i=0; i<N; i++) { 6061 int uid = mapUid(newWs.getUid(i)); 6062 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6063 .noteWifiRunningLocked(elapsedRealtimeMs); 6064 } 6065 6066 workChains = newWs.getWorkChains(); 6067 if (workChains != null) { 6068 for (int i = 0; i < workChains.size(); ++i) { 6069 int uid = mapUid(workChains.get(i).getAttributionUid()); 6070 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6071 .noteWifiRunningLocked(elapsedRealtimeMs); 6072 } 6073 } 6074 } else { 6075 Log.w(TAG, "noteWifiRunningChangedLocked -- called while WIFI not running"); 6076 } 6077 } 6078 noteWifiStoppedLocked(WorkSource ws)6079 public void noteWifiStoppedLocked(WorkSource ws) { 6080 noteWifiStoppedLocked(ws, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 6081 } 6082 noteWifiStoppedLocked(WorkSource ws, long elapsedRealtimeMs, long uptimeMs)6083 public void noteWifiStoppedLocked(WorkSource ws, long elapsedRealtimeMs, long uptimeMs) { 6084 if (mGlobalWifiRunning) { 6085 mHistoryCur.states2 &= ~HistoryItem.STATE2_WIFI_RUNNING_FLAG; 6086 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI stopped to: " 6087 + Integer.toHexString(mHistoryCur.states)); 6088 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 6089 mGlobalWifiRunning = false; 6090 mGlobalWifiRunningTimer.stopRunningLocked(elapsedRealtimeMs); 6091 int N = ws.size(); 6092 for (int i=0; i<N; i++) { 6093 int uid = mapUid(ws.getUid(i)); 6094 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6095 .noteWifiStoppedLocked(elapsedRealtimeMs); 6096 } 6097 6098 List<WorkChain> workChains = ws.getWorkChains(); 6099 if (workChains != null) { 6100 for (int i = 0; i < workChains.size(); ++i) { 6101 int uid = mapUid(workChains.get(i).getAttributionUid()); 6102 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6103 .noteWifiStoppedLocked(elapsedRealtimeMs); 6104 } 6105 } 6106 6107 scheduleSyncExternalStatsLocked("wifi-stopped", ExternalStatsSync.UPDATE_WIFI); 6108 } else { 6109 Log.w(TAG, "noteWifiStoppedLocked -- called while WIFI not running"); 6110 } 6111 } 6112 noteWifiStateLocked(int wifiState, String accessPoint)6113 public void noteWifiStateLocked(int wifiState, String accessPoint) { 6114 noteWifiStateLocked(wifiState, accessPoint, mClocks.elapsedRealtime()); 6115 } 6116 noteWifiStateLocked(int wifiState, String accessPoint, long elapsedRealtimeMs)6117 public void noteWifiStateLocked(int wifiState, String accessPoint, long elapsedRealtimeMs) { 6118 if (DEBUG) Log.i(TAG, "WiFi state -> " + wifiState); 6119 if (mWifiState != wifiState) { 6120 if (mWifiState >= 0) { 6121 mWifiStateTimer[mWifiState].stopRunningLocked(elapsedRealtimeMs); 6122 } 6123 mWifiState = wifiState; 6124 mWifiStateTimer[wifiState].startRunningLocked(elapsedRealtimeMs); 6125 scheduleSyncExternalStatsLocked("wifi-state", ExternalStatsSync.UPDATE_WIFI); 6126 } 6127 } 6128 noteWifiSupplicantStateChangedLocked(int supplState, boolean failedAuth)6129 public void noteWifiSupplicantStateChangedLocked(int supplState, boolean failedAuth) { 6130 noteWifiSupplicantStateChangedLocked(supplState, failedAuth, 6131 mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 6132 } 6133 noteWifiSupplicantStateChangedLocked(int supplState, boolean failedAuth, long elapsedRealtimeMs, long uptimeMs)6134 public void noteWifiSupplicantStateChangedLocked(int supplState, boolean failedAuth, 6135 long elapsedRealtimeMs, long uptimeMs) { 6136 if (DEBUG) Log.i(TAG, "WiFi suppl state -> " + supplState); 6137 if (mWifiSupplState != supplState) { 6138 if (mWifiSupplState >= 0) { 6139 mWifiSupplStateTimer[mWifiSupplState].stopRunningLocked(elapsedRealtimeMs); 6140 } 6141 mWifiSupplState = supplState; 6142 mWifiSupplStateTimer[supplState].startRunningLocked(elapsedRealtimeMs); 6143 mHistoryCur.states2 = 6144 (mHistoryCur.states2&~HistoryItem.STATE2_WIFI_SUPPL_STATE_MASK) 6145 | (supplState << HistoryItem.STATE2_WIFI_SUPPL_STATE_SHIFT); 6146 if (DEBUG_HISTORY) Slog.v(TAG, "Wifi suppl state " + supplState + " to: " 6147 + Integer.toHexString(mHistoryCur.states2)); 6148 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 6149 } 6150 } 6151 stopAllWifiSignalStrengthTimersLocked(int except, long elapsedRealtimeMs)6152 void stopAllWifiSignalStrengthTimersLocked(int except, long elapsedRealtimeMs) { 6153 for (int i = 0; i < NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { 6154 if (i == except) { 6155 continue; 6156 } 6157 while (mWifiSignalStrengthsTimer[i].isRunningLocked()) { 6158 mWifiSignalStrengthsTimer[i].stopRunningLocked(elapsedRealtimeMs); 6159 } 6160 } 6161 } 6162 noteWifiRssiChangedLocked(int newRssi)6163 public void noteWifiRssiChangedLocked(int newRssi) { 6164 noteWifiRssiChangedLocked(newRssi, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 6165 } 6166 noteWifiRssiChangedLocked(int newRssi, long elapsedRealtimeMs, long uptimeMs)6167 public void noteWifiRssiChangedLocked(int newRssi, long elapsedRealtimeMs, long uptimeMs) { 6168 int strengthBin = WifiManager.calculateSignalLevel(newRssi, NUM_WIFI_SIGNAL_STRENGTH_BINS); 6169 if (DEBUG) Log.i(TAG, "WiFi rssi -> " + newRssi + " bin=" + strengthBin); 6170 if (mWifiSignalStrengthBin != strengthBin) { 6171 if (mWifiSignalStrengthBin >= 0) { 6172 mWifiSignalStrengthsTimer[mWifiSignalStrengthBin].stopRunningLocked( 6173 elapsedRealtimeMs); 6174 } 6175 if (strengthBin >= 0) { 6176 if (!mWifiSignalStrengthsTimer[strengthBin].isRunningLocked()) { 6177 mWifiSignalStrengthsTimer[strengthBin].startRunningLocked(elapsedRealtimeMs); 6178 } 6179 mHistoryCur.states2 = 6180 (mHistoryCur.states2&~HistoryItem.STATE2_WIFI_SIGNAL_STRENGTH_MASK) 6181 | (strengthBin << HistoryItem.STATE2_WIFI_SIGNAL_STRENGTH_SHIFT); 6182 if (DEBUG_HISTORY) Slog.v(TAG, "Wifi signal strength " + strengthBin + " to: " 6183 + Integer.toHexString(mHistoryCur.states2)); 6184 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 6185 } else { 6186 stopAllWifiSignalStrengthTimersLocked(-1, elapsedRealtimeMs); 6187 } 6188 mWifiSignalStrengthBin = strengthBin; 6189 } 6190 } 6191 6192 int mWifiFullLockNesting = 0; 6193 6194 @UnsupportedAppUsage noteFullWifiLockAcquiredLocked(int uid)6195 public void noteFullWifiLockAcquiredLocked(int uid) { 6196 noteFullWifiLockAcquiredLocked(uid, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 6197 } 6198 noteFullWifiLockAcquiredLocked(int uid, long elapsedRealtimeMs, long uptimeMs)6199 public void noteFullWifiLockAcquiredLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 6200 if (mWifiFullLockNesting == 0) { 6201 mHistoryCur.states |= HistoryItem.STATE_WIFI_FULL_LOCK_FLAG; 6202 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI full lock on to: " 6203 + Integer.toHexString(mHistoryCur.states)); 6204 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 6205 } 6206 mWifiFullLockNesting++; 6207 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6208 .noteFullWifiLockAcquiredLocked(elapsedRealtimeMs); 6209 } 6210 6211 @UnsupportedAppUsage noteFullWifiLockReleasedLocked(int uid)6212 public void noteFullWifiLockReleasedLocked(int uid) { 6213 noteFullWifiLockReleasedLocked(uid, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 6214 } 6215 noteFullWifiLockReleasedLocked(int uid, long elapsedRealtimeMs, long uptimeMs)6216 public void noteFullWifiLockReleasedLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 6217 mWifiFullLockNesting--; 6218 if (mWifiFullLockNesting == 0) { 6219 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_FULL_LOCK_FLAG; 6220 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI full lock off to: " 6221 + Integer.toHexString(mHistoryCur.states)); 6222 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 6223 } 6224 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6225 .noteFullWifiLockReleasedLocked(elapsedRealtimeMs); 6226 } 6227 6228 int mWifiScanNesting = 0; 6229 noteWifiScanStartedLocked(int uid)6230 public void noteWifiScanStartedLocked(int uid) { 6231 noteWifiScanStartedLocked(uid, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 6232 } 6233 noteWifiScanStartedLocked(int uid, long elapsedRealtimeMs, long uptimeMs)6234 public void noteWifiScanStartedLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 6235 if (mWifiScanNesting == 0) { 6236 mHistoryCur.states |= HistoryItem.STATE_WIFI_SCAN_FLAG; 6237 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI scan started for: " 6238 + Integer.toHexString(mHistoryCur.states)); 6239 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 6240 } 6241 mWifiScanNesting++; 6242 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6243 .noteWifiScanStartedLocked(elapsedRealtimeMs); 6244 } 6245 noteWifiScanStoppedLocked(int uid)6246 public void noteWifiScanStoppedLocked(int uid) { 6247 noteWifiScanStoppedLocked(uid, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 6248 } 6249 noteWifiScanStoppedLocked(int uid, long elapsedRealtimeMs, long uptimeMs)6250 public void noteWifiScanStoppedLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 6251 mWifiScanNesting--; 6252 if (mWifiScanNesting == 0) { 6253 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_SCAN_FLAG; 6254 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI scan stopped for: " 6255 + Integer.toHexString(mHistoryCur.states)); 6256 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 6257 } 6258 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6259 .noteWifiScanStoppedLocked(elapsedRealtimeMs); 6260 } 6261 noteWifiBatchedScanStartedLocked(int uid, int csph)6262 public void noteWifiBatchedScanStartedLocked(int uid, int csph) { 6263 noteWifiBatchedScanStartedLocked(uid, csph, 6264 mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 6265 } 6266 noteWifiBatchedScanStartedLocked(int uid, int csph, long elapsedRealtimeMs, long uptimeMs)6267 public void noteWifiBatchedScanStartedLocked(int uid, int csph, 6268 long elapsedRealtimeMs, long uptimeMs) { 6269 uid = mapUid(uid); 6270 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6271 .noteWifiBatchedScanStartedLocked(csph, elapsedRealtimeMs); 6272 } 6273 noteWifiBatchedScanStoppedLocked(int uid)6274 public void noteWifiBatchedScanStoppedLocked(int uid) { 6275 noteWifiBatchedScanStoppedLocked(uid, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 6276 } 6277 noteWifiBatchedScanStoppedLocked(int uid, long elapsedRealtimeMs, long uptimeMs)6278 public void noteWifiBatchedScanStoppedLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 6279 uid = mapUid(uid); 6280 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6281 .noteWifiBatchedScanStoppedLocked(elapsedRealtimeMs); 6282 } 6283 6284 int mWifiMulticastNesting = 0; 6285 6286 @UnsupportedAppUsage noteWifiMulticastEnabledLocked(int uid)6287 public void noteWifiMulticastEnabledLocked(int uid) { 6288 noteWifiMulticastEnabledLocked(uid, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 6289 } 6290 noteWifiMulticastEnabledLocked(int uid, long elapsedRealtimeMs, long uptimeMs)6291 public void noteWifiMulticastEnabledLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 6292 uid = mapUid(uid); 6293 if (mWifiMulticastNesting == 0) { 6294 mHistoryCur.states |= HistoryItem.STATE_WIFI_MULTICAST_ON_FLAG; 6295 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI multicast on to: " 6296 + Integer.toHexString(mHistoryCur.states)); 6297 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 6298 6299 // Start Wifi Multicast overall timer 6300 if (!mWifiMulticastWakelockTimer.isRunningLocked()) { 6301 if (DEBUG_HISTORY) Slog.v(TAG, "WiFi Multicast Overall Timer Started"); 6302 mWifiMulticastWakelockTimer.startRunningLocked(elapsedRealtimeMs); 6303 } 6304 } 6305 mWifiMulticastNesting++; 6306 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6307 .noteWifiMulticastEnabledLocked(elapsedRealtimeMs); 6308 } 6309 6310 @UnsupportedAppUsage noteWifiMulticastDisabledLocked(int uid)6311 public void noteWifiMulticastDisabledLocked(int uid) { 6312 noteWifiMulticastDisabledLocked(uid, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 6313 } 6314 noteWifiMulticastDisabledLocked(int uid, long elapsedRealtimeMs, long uptimeMs)6315 public void noteWifiMulticastDisabledLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 6316 uid = mapUid(uid); 6317 mWifiMulticastNesting--; 6318 if (mWifiMulticastNesting == 0) { 6319 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_MULTICAST_ON_FLAG; 6320 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI multicast off to: " 6321 + Integer.toHexString(mHistoryCur.states)); 6322 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 6323 6324 // Stop Wifi Multicast overall timer 6325 if (mWifiMulticastWakelockTimer.isRunningLocked()) { 6326 if (DEBUG_HISTORY) Slog.v(TAG, "Multicast Overall Timer Stopped"); 6327 mWifiMulticastWakelockTimer.stopRunningLocked(elapsedRealtimeMs); 6328 } 6329 } 6330 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6331 .noteWifiMulticastDisabledLocked(elapsedRealtimeMs); 6332 } 6333 noteFullWifiLockAcquiredFromSourceLocked(WorkSource ws)6334 public void noteFullWifiLockAcquiredFromSourceLocked(WorkSource ws) { 6335 noteFullWifiLockAcquiredFromSourceLocked(ws, 6336 mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 6337 } 6338 noteFullWifiLockAcquiredFromSourceLocked(WorkSource ws, long elapsedRealtimeMs, long uptimeMs)6339 public void noteFullWifiLockAcquiredFromSourceLocked(WorkSource ws, 6340 long elapsedRealtimeMs, long uptimeMs) { 6341 int N = ws.size(); 6342 for (int i=0; i<N; i++) { 6343 final int uid = mapUid(ws.getUid(i)); 6344 noteFullWifiLockAcquiredLocked(uid, elapsedRealtimeMs, uptimeMs); 6345 } 6346 6347 final List<WorkChain> workChains = ws.getWorkChains(); 6348 if (workChains != null) { 6349 for (int i = 0; i < workChains.size(); ++i) { 6350 final WorkChain workChain = workChains.get(i); 6351 final int uid = mapUid(workChain.getAttributionUid()); 6352 noteFullWifiLockAcquiredLocked(uid, elapsedRealtimeMs, uptimeMs); 6353 } 6354 } 6355 } 6356 noteFullWifiLockReleasedFromSourceLocked(WorkSource ws)6357 public void noteFullWifiLockReleasedFromSourceLocked(WorkSource ws) { 6358 noteFullWifiLockReleasedFromSourceLocked(ws, 6359 mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 6360 } 6361 noteFullWifiLockReleasedFromSourceLocked(WorkSource ws, long elapsedRealtimeMs, long uptimeMs)6362 public void noteFullWifiLockReleasedFromSourceLocked(WorkSource ws, 6363 long elapsedRealtimeMs, long uptimeMs) { 6364 int N = ws.size(); 6365 for (int i=0; i<N; i++) { 6366 final int uid = mapUid(ws.getUid(i)); 6367 noteFullWifiLockReleasedLocked(uid, elapsedRealtimeMs, uptimeMs); 6368 } 6369 6370 final List<WorkChain> workChains = ws.getWorkChains(); 6371 if (workChains != null) { 6372 for (int i = 0; i < workChains.size(); ++i) { 6373 final WorkChain workChain = workChains.get(i); 6374 final int uid = mapUid(workChain.getAttributionUid()); 6375 noteFullWifiLockReleasedLocked(uid, elapsedRealtimeMs, uptimeMs); 6376 } 6377 } 6378 } 6379 noteWifiScanStartedFromSourceLocked(WorkSource ws)6380 public void noteWifiScanStartedFromSourceLocked(WorkSource ws) { 6381 noteWifiScanStartedFromSourceLocked(ws, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 6382 } 6383 noteWifiScanStartedFromSourceLocked(WorkSource ws, long elapsedRealtimeMs, long uptimeMs)6384 public void noteWifiScanStartedFromSourceLocked(WorkSource ws, 6385 long elapsedRealtimeMs, long uptimeMs) { 6386 int N = ws.size(); 6387 for (int i=0; i<N; i++) { 6388 final int uid = mapUid(ws.getUid(i)); 6389 noteWifiScanStartedLocked(uid, elapsedRealtimeMs, uptimeMs); 6390 } 6391 6392 final List<WorkChain> workChains = ws.getWorkChains(); 6393 if (workChains != null) { 6394 for (int i = 0; i < workChains.size(); ++i) { 6395 final WorkChain workChain = workChains.get(i); 6396 final int uid = mapUid(workChain.getAttributionUid()); 6397 noteWifiScanStartedLocked(uid, elapsedRealtimeMs, uptimeMs); 6398 } 6399 } 6400 } 6401 noteWifiScanStoppedFromSourceLocked(WorkSource ws)6402 public void noteWifiScanStoppedFromSourceLocked(WorkSource ws) { 6403 noteWifiScanStoppedFromSourceLocked(ws, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 6404 } 6405 noteWifiScanStoppedFromSourceLocked(WorkSource ws, long elapsedRealtimeMs, long uptimeMs)6406 public void noteWifiScanStoppedFromSourceLocked(WorkSource ws, 6407 long elapsedRealtimeMs, long uptimeMs) { 6408 int N = ws.size(); 6409 for (int i=0; i<N; i++) { 6410 final int uid = mapUid(ws.getUid(i)); 6411 noteWifiScanStoppedLocked(uid, elapsedRealtimeMs, uptimeMs); 6412 } 6413 6414 final List<WorkChain> workChains = ws.getWorkChains(); 6415 if (workChains != null) { 6416 for (int i = 0; i < workChains.size(); ++i) { 6417 final WorkChain workChain = workChains.get(i); 6418 final int uid = mapUid(workChain.getAttributionUid()); 6419 noteWifiScanStoppedLocked(uid, elapsedRealtimeMs, uptimeMs); 6420 } 6421 } 6422 } 6423 noteWifiBatchedScanStartedFromSourceLocked(WorkSource ws, int csph)6424 public void noteWifiBatchedScanStartedFromSourceLocked(WorkSource ws, int csph) { 6425 noteWifiBatchedScanStartedFromSourceLocked(ws, csph, 6426 mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 6427 } 6428 noteWifiBatchedScanStartedFromSourceLocked(WorkSource ws, int csph, long elapsedRealtimeMs, long uptimeMs)6429 public void noteWifiBatchedScanStartedFromSourceLocked(WorkSource ws, int csph, 6430 long elapsedRealtimeMs, long uptimeMs) { 6431 int N = ws.size(); 6432 for (int i=0; i<N; i++) { 6433 noteWifiBatchedScanStartedLocked(ws.getUid(i), csph, elapsedRealtimeMs, uptimeMs); 6434 } 6435 6436 final List<WorkChain> workChains = ws.getWorkChains(); 6437 if (workChains != null) { 6438 for (int i = 0; i < workChains.size(); ++i) { 6439 noteWifiBatchedScanStartedLocked(workChains.get(i).getAttributionUid(), csph, 6440 elapsedRealtimeMs, uptimeMs); 6441 } 6442 } 6443 } 6444 noteWifiBatchedScanStoppedFromSourceLocked(WorkSource ws)6445 public void noteWifiBatchedScanStoppedFromSourceLocked(WorkSource ws) { 6446 noteWifiBatchedScanStoppedFromSourceLocked(ws, 6447 mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 6448 } noteWifiBatchedScanStoppedFromSourceLocked(WorkSource ws, long elapsedRealtimeMs, long uptimeMs)6449 public void noteWifiBatchedScanStoppedFromSourceLocked(WorkSource ws, 6450 long elapsedRealtimeMs, long uptimeMs) { 6451 int N = ws.size(); 6452 for (int i=0; i<N; i++) { 6453 noteWifiBatchedScanStoppedLocked(ws.getUid(i), elapsedRealtimeMs, uptimeMs); 6454 } 6455 6456 final List<WorkChain> workChains = ws.getWorkChains(); 6457 if (workChains != null) { 6458 for (int i = 0; i < workChains.size(); ++i) { 6459 noteWifiBatchedScanStoppedLocked(workChains.get(i).getAttributionUid(), 6460 elapsedRealtimeMs, uptimeMs); 6461 } 6462 } 6463 } 6464 includeInStringArray(String[] array, String str)6465 private static String[] includeInStringArray(String[] array, String str) { 6466 if (ArrayUtils.indexOf(array, str) >= 0) { 6467 return array; 6468 } 6469 String[] newArray = new String[array.length+1]; 6470 System.arraycopy(array, 0, newArray, 0, array.length); 6471 newArray[array.length] = str; 6472 return newArray; 6473 } 6474 excludeFromStringArray(String[] array, String str)6475 private static String[] excludeFromStringArray(String[] array, String str) { 6476 int index = ArrayUtils.indexOf(array, str); 6477 if (index >= 0) { 6478 String[] newArray = new String[array.length-1]; 6479 if (index > 0) { 6480 System.arraycopy(array, 0, newArray, 0, index); 6481 } 6482 if (index < array.length-1) { 6483 System.arraycopy(array, index+1, newArray, index, array.length-index-1); 6484 } 6485 return newArray; 6486 } 6487 return array; 6488 } 6489 6490 /** @hide */ noteNetworkInterfaceForTransports(String iface, int[] transportTypes)6491 public void noteNetworkInterfaceForTransports(String iface, int[] transportTypes) { 6492 if (TextUtils.isEmpty(iface)) return; 6493 final int displayTransport = NetworkCapabilitiesUtils.getDisplayTransport(transportTypes); 6494 6495 synchronized (mModemNetworkLock) { 6496 if (displayTransport == TRANSPORT_CELLULAR) { 6497 mModemIfaces = includeInStringArray(mModemIfaces, iface); 6498 if (DEBUG) Slog.d(TAG, "Note mobile iface " + iface + ": " + mModemIfaces); 6499 } else { 6500 mModemIfaces = excludeFromStringArray(mModemIfaces, iface); 6501 if (DEBUG) Slog.d(TAG, "Note non-mobile iface " + iface + ": " + mModemIfaces); 6502 } 6503 } 6504 6505 synchronized (mWifiNetworkLock) { 6506 if (displayTransport == TRANSPORT_WIFI) { 6507 mWifiIfaces = includeInStringArray(mWifiIfaces, iface); 6508 if (DEBUG) Slog.d(TAG, "Note wifi iface " + iface + ": " + mWifiIfaces); 6509 } else { 6510 mWifiIfaces = excludeFromStringArray(mWifiIfaces, iface); 6511 if (DEBUG) Slog.d(TAG, "Note non-wifi iface " + iface + ": " + mWifiIfaces); 6512 } 6513 } 6514 } 6515 6516 /** 6517 * Records timing data related to an incoming Binder call in order to attribute 6518 * the power consumption to the calling app. 6519 */ noteBinderCallStats(int workSourceUid, long incrementalCallCount, Collection<BinderCallsStats.CallStat> callStats)6520 public void noteBinderCallStats(int workSourceUid, long incrementalCallCount, 6521 Collection<BinderCallsStats.CallStat> callStats) { 6522 noteBinderCallStats(workSourceUid, incrementalCallCount, callStats, 6523 mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 6524 } 6525 noteBinderCallStats(int workSourceUid, long incrementalCallCount, Collection<BinderCallsStats.CallStat> callStats, long elapsedRealtimeMs, long uptimeMs)6526 public void noteBinderCallStats(int workSourceUid, long incrementalCallCount, 6527 Collection<BinderCallsStats.CallStat> callStats, 6528 long elapsedRealtimeMs, long uptimeMs) { 6529 synchronized (this) { 6530 getUidStatsLocked(workSourceUid, elapsedRealtimeMs, uptimeMs) 6531 .noteBinderCallStatsLocked(incrementalCallCount, callStats); 6532 } 6533 } 6534 6535 /** 6536 * Takes note of native IDs of threads taking incoming binder calls. The CPU time 6537 * of these threads is attributed to the apps making those binder calls. 6538 */ noteBinderThreadNativeIds(int[] binderThreadNativeTids)6539 public void noteBinderThreadNativeIds(int[] binderThreadNativeTids) { 6540 mSystemServerCpuThreadReader.setBinderThreadNativeTids(binderThreadNativeTids); 6541 } 6542 6543 /** 6544 * Estimates the proportion of system server CPU activity handling incoming binder calls 6545 * that can be attributed to each app 6546 */ 6547 @VisibleForTesting updateSystemServiceCallStats()6548 public void updateSystemServiceCallStats() { 6549 // Start off by computing the average duration of recorded binder calls, 6550 // regardless of which binder or transaction. We will use this as a fallback 6551 // for calls that were not sampled at all. 6552 int totalRecordedCallCount = 0; 6553 long totalRecordedCallTimeMicros = 0; 6554 for (int i = 0; i < mUidStats.size(); i++) { 6555 Uid uid = mUidStats.valueAt(i); 6556 ArraySet<BinderCallStats> binderCallStats = uid.mBinderCallStats; 6557 for (int j = binderCallStats.size() - 1; j >= 0; j--) { 6558 BinderCallStats stats = binderCallStats.valueAt(j); 6559 totalRecordedCallCount += stats.recordedCallCount; 6560 totalRecordedCallTimeMicros += stats.recordedCpuTimeMicros; 6561 } 6562 } 6563 6564 long totalSystemServiceTimeMicros = 0; 6565 6566 // For every UID, use recorded durations of sampled binder calls to estimate 6567 // the total time the system server spent handling requests from this UID. 6568 for (int i = 0; i < mUidStats.size(); i++) { 6569 Uid uid = mUidStats.valueAt(i); 6570 6571 long totalTimeForUidUs = 0; 6572 int totalCallCountForUid = 0; 6573 ArraySet<BinderCallStats> binderCallStats = uid.mBinderCallStats; 6574 for (int j = binderCallStats.size() - 1; j >= 0; j--) { 6575 BinderCallStats stats = binderCallStats.valueAt(j); 6576 totalCallCountForUid += stats.callCount; 6577 if (stats.recordedCallCount > 0) { 6578 totalTimeForUidUs += 6579 stats.callCount * stats.recordedCpuTimeMicros / stats.recordedCallCount; 6580 } else if (totalRecordedCallCount > 0) { 6581 totalTimeForUidUs += 6582 stats.callCount * totalRecordedCallTimeMicros / totalRecordedCallCount; 6583 } 6584 } 6585 6586 if (totalCallCountForUid < uid.mBinderCallCount && totalRecordedCallCount > 0) { 6587 // Estimate remaining calls, which were not tracked because of binder call 6588 // stats sampling 6589 totalTimeForUidUs += 6590 (uid.mBinderCallCount - totalCallCountForUid) * totalRecordedCallTimeMicros 6591 / totalRecordedCallCount; 6592 } 6593 6594 uid.mSystemServiceTimeUs = totalTimeForUidUs; 6595 totalSystemServiceTimeMicros += totalTimeForUidUs; 6596 } 6597 6598 for (int i = 0; i < mUidStats.size(); i++) { 6599 Uid uid = mUidStats.valueAt(i); 6600 if (totalSystemServiceTimeMicros > 0) { 6601 uid.mProportionalSystemServiceUsage = 6602 (double) uid.mSystemServiceTimeUs / totalSystemServiceTimeMicros; 6603 } else { 6604 uid.mProportionalSystemServiceUsage = 0; 6605 } 6606 } 6607 } 6608 getWifiIfaces()6609 public String[] getWifiIfaces() { 6610 synchronized (mWifiNetworkLock) { 6611 return mWifiIfaces; 6612 } 6613 } 6614 getMobileIfaces()6615 public String[] getMobileIfaces() { 6616 synchronized (mModemNetworkLock) { 6617 return mModemIfaces; 6618 } 6619 } 6620 6621 @UnsupportedAppUsage getScreenOnTime(long elapsedRealtimeUs, int which)6622 @Override public long getScreenOnTime(long elapsedRealtimeUs, int which) { 6623 return mScreenOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 6624 } 6625 getScreenOnCount(int which)6626 @Override public int getScreenOnCount(int which) { 6627 return mScreenOnTimer.getCountLocked(which); 6628 } 6629 getScreenDozeTime(long elapsedRealtimeUs, int which)6630 @Override public long getScreenDozeTime(long elapsedRealtimeUs, int which) { 6631 return mScreenDozeTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 6632 } 6633 getScreenDozeCount(int which)6634 @Override public int getScreenDozeCount(int which) { 6635 return mScreenDozeTimer.getCountLocked(which); 6636 } 6637 6638 @UnsupportedAppUsage getScreenBrightnessTime(int brightnessBin, long elapsedRealtimeUs, int which)6639 @Override public long getScreenBrightnessTime(int brightnessBin, 6640 long elapsedRealtimeUs, int which) { 6641 return mScreenBrightnessTimer[brightnessBin].getTotalTimeLocked( 6642 elapsedRealtimeUs, which); 6643 } 6644 getScreenBrightnessTimer(int brightnessBin)6645 @Override public Timer getScreenBrightnessTimer(int brightnessBin) { 6646 return mScreenBrightnessTimer[brightnessBin]; 6647 } 6648 getInteractiveTime(long elapsedRealtimeUs, int which)6649 @Override public long getInteractiveTime(long elapsedRealtimeUs, int which) { 6650 return mInteractiveTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 6651 } 6652 getPowerSaveModeEnabledTime(long elapsedRealtimeUs, int which)6653 @Override public long getPowerSaveModeEnabledTime(long elapsedRealtimeUs, int which) { 6654 return mPowerSaveModeEnabledTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 6655 } 6656 getPowerSaveModeEnabledCount(int which)6657 @Override public int getPowerSaveModeEnabledCount(int which) { 6658 return mPowerSaveModeEnabledTimer.getCountLocked(which); 6659 } 6660 getDeviceIdleModeTime(int mode, long elapsedRealtimeUs, int which)6661 @Override public long getDeviceIdleModeTime(int mode, long elapsedRealtimeUs, 6662 int which) { 6663 switch (mode) { 6664 case DEVICE_IDLE_MODE_LIGHT: 6665 return mDeviceIdleModeLightTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 6666 case DEVICE_IDLE_MODE_DEEP: 6667 return mDeviceIdleModeFullTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 6668 } 6669 return 0; 6670 } 6671 getDeviceIdleModeCount(int mode, int which)6672 @Override public int getDeviceIdleModeCount(int mode, int which) { 6673 switch (mode) { 6674 case DEVICE_IDLE_MODE_LIGHT: 6675 return mDeviceIdleModeLightTimer.getCountLocked(which); 6676 case DEVICE_IDLE_MODE_DEEP: 6677 return mDeviceIdleModeFullTimer.getCountLocked(which); 6678 } 6679 return 0; 6680 } 6681 getLongestDeviceIdleModeTime(int mode)6682 @Override public long getLongestDeviceIdleModeTime(int mode) { 6683 switch (mode) { 6684 case DEVICE_IDLE_MODE_LIGHT: 6685 return mLongestLightIdleTimeMs; 6686 case DEVICE_IDLE_MODE_DEEP: 6687 return mLongestFullIdleTimeMs; 6688 } 6689 return 0; 6690 } 6691 getDeviceIdlingTime(int mode, long elapsedRealtimeUs, int which)6692 @Override public long getDeviceIdlingTime(int mode, long elapsedRealtimeUs, int which) { 6693 switch (mode) { 6694 case DEVICE_IDLE_MODE_LIGHT: 6695 return mDeviceLightIdlingTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 6696 case DEVICE_IDLE_MODE_DEEP: 6697 return mDeviceIdlingTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 6698 } 6699 return 0; 6700 } 6701 getDeviceIdlingCount(int mode, int which)6702 @Override public int getDeviceIdlingCount(int mode, int which) { 6703 switch (mode) { 6704 case DEVICE_IDLE_MODE_LIGHT: 6705 return mDeviceLightIdlingTimer.getCountLocked(which); 6706 case DEVICE_IDLE_MODE_DEEP: 6707 return mDeviceIdlingTimer.getCountLocked(which); 6708 } 6709 return 0; 6710 } 6711 getNumConnectivityChange(int which)6712 @Override public int getNumConnectivityChange(int which) { 6713 return mNumConnectivityChange; 6714 } 6715 getGpsSignalQualityTime(int strengthBin, long elapsedRealtimeUs, int which)6716 @Override public long getGpsSignalQualityTime(int strengthBin, 6717 long elapsedRealtimeUs, int which) { 6718 if (strengthBin < 0 || strengthBin >= mGpsSignalQualityTimer.length) { 6719 return 0; 6720 } 6721 return mGpsSignalQualityTimer[strengthBin].getTotalTimeLocked( 6722 elapsedRealtimeUs, which); 6723 } 6724 getGpsBatteryDrainMaMs()6725 @Override public long getGpsBatteryDrainMaMs() { 6726 final double opVolt = mPowerProfile.getAveragePower( 6727 PowerProfile.POWER_GPS_OPERATING_VOLTAGE) / 1000.0; 6728 if (opVolt == 0) { 6729 return 0; 6730 } 6731 double energyUsedMaMs = 0.0; 6732 final int which = STATS_SINCE_CHARGED; 6733 final long rawRealtimeUs = SystemClock.elapsedRealtime() * 1000; 6734 for(int i=0; i < mGpsSignalQualityTimer.length; i++) { 6735 energyUsedMaMs 6736 += mPowerProfile.getAveragePower(PowerProfile.POWER_GPS_SIGNAL_QUALITY_BASED, i) 6737 * (getGpsSignalQualityTime(i, rawRealtimeUs, which) / 1000); 6738 } 6739 return (long) energyUsedMaMs; 6740 } 6741 6742 @UnsupportedAppUsage getPhoneOnTime(long elapsedRealtimeUs, int which)6743 @Override public long getPhoneOnTime(long elapsedRealtimeUs, int which) { 6744 return mPhoneOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 6745 } 6746 getPhoneOnCount(int which)6747 @Override public int getPhoneOnCount(int which) { 6748 return mPhoneOnTimer.getCountLocked(which); 6749 } 6750 6751 @UnsupportedAppUsage getPhoneSignalStrengthTime(int strengthBin, long elapsedRealtimeUs, int which)6752 @Override public long getPhoneSignalStrengthTime(int strengthBin, 6753 long elapsedRealtimeUs, int which) { 6754 return mPhoneSignalStrengthsTimer[strengthBin].getTotalTimeLocked( 6755 elapsedRealtimeUs, which); 6756 } 6757 6758 @UnsupportedAppUsage getPhoneSignalScanningTime( long elapsedRealtimeUs, int which)6759 @Override public long getPhoneSignalScanningTime( 6760 long elapsedRealtimeUs, int which) { 6761 return mPhoneSignalScanningTimer.getTotalTimeLocked( 6762 elapsedRealtimeUs, which); 6763 } 6764 getPhoneSignalScanningTimer()6765 @Override public Timer getPhoneSignalScanningTimer() { 6766 return mPhoneSignalScanningTimer; 6767 } 6768 6769 @UnsupportedAppUsage getPhoneSignalStrengthCount(int strengthBin, int which)6770 @Override public int getPhoneSignalStrengthCount(int strengthBin, int which) { 6771 return mPhoneSignalStrengthsTimer[strengthBin].getCountLocked(which); 6772 } 6773 getPhoneSignalStrengthTimer(int strengthBin)6774 @Override public Timer getPhoneSignalStrengthTimer(int strengthBin) { 6775 return mPhoneSignalStrengthsTimer[strengthBin]; 6776 } 6777 6778 @UnsupportedAppUsage getPhoneDataConnectionTime(int dataType, long elapsedRealtimeUs, int which)6779 @Override public long getPhoneDataConnectionTime(int dataType, 6780 long elapsedRealtimeUs, int which) { 6781 return mPhoneDataConnectionsTimer[dataType].getTotalTimeLocked( 6782 elapsedRealtimeUs, which); 6783 } 6784 6785 @UnsupportedAppUsage getPhoneDataConnectionCount(int dataType, int which)6786 @Override public int getPhoneDataConnectionCount(int dataType, int which) { 6787 return mPhoneDataConnectionsTimer[dataType].getCountLocked(which); 6788 } 6789 getPhoneDataConnectionTimer(int dataType)6790 @Override public Timer getPhoneDataConnectionTimer(int dataType) { 6791 return mPhoneDataConnectionsTimer[dataType]; 6792 } 6793 6794 @UnsupportedAppUsage getMobileRadioActiveTime(long elapsedRealtimeUs, int which)6795 @Override public long getMobileRadioActiveTime(long elapsedRealtimeUs, int which) { 6796 return mMobileRadioActiveTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 6797 } 6798 getMobileRadioActiveCount(int which)6799 @Override public int getMobileRadioActiveCount(int which) { 6800 return mMobileRadioActiveTimer.getCountLocked(which); 6801 } 6802 getMobileRadioActiveAdjustedTime(int which)6803 @Override public long getMobileRadioActiveAdjustedTime(int which) { 6804 return mMobileRadioActiveAdjustedTime.getCountLocked(which); 6805 } 6806 getMobileRadioActiveUnknownTime(int which)6807 @Override public long getMobileRadioActiveUnknownTime(int which) { 6808 return mMobileRadioActiveUnknownTime.getCountLocked(which); 6809 } 6810 getMobileRadioActiveUnknownCount(int which)6811 @Override public int getMobileRadioActiveUnknownCount(int which) { 6812 return (int)mMobileRadioActiveUnknownCount.getCountLocked(which); 6813 } 6814 getWifiMulticastWakelockTime( long elapsedRealtimeUs, int which)6815 @Override public long getWifiMulticastWakelockTime( 6816 long elapsedRealtimeUs, int which) { 6817 return mWifiMulticastWakelockTimer.getTotalTimeLocked( 6818 elapsedRealtimeUs, which); 6819 } 6820 getWifiMulticastWakelockCount(int which)6821 @Override public int getWifiMulticastWakelockCount(int which) { 6822 return mWifiMulticastWakelockTimer.getCountLocked(which); 6823 } 6824 6825 @UnsupportedAppUsage getWifiOnTime(long elapsedRealtimeUs, int which)6826 @Override public long getWifiOnTime(long elapsedRealtimeUs, int which) { 6827 return mWifiOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 6828 } 6829 getWifiActiveTime(long elapsedRealtimeUs, int which)6830 @Override public long getWifiActiveTime(long elapsedRealtimeUs, int which) { 6831 return mWifiActiveTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 6832 } 6833 6834 @UnsupportedAppUsage getGlobalWifiRunningTime(long elapsedRealtimeUs, int which)6835 @Override public long getGlobalWifiRunningTime(long elapsedRealtimeUs, int which) { 6836 return mGlobalWifiRunningTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 6837 } 6838 getWifiStateTime(int wifiState, long elapsedRealtimeUs, int which)6839 @Override public long getWifiStateTime(int wifiState, 6840 long elapsedRealtimeUs, int which) { 6841 return mWifiStateTimer[wifiState].getTotalTimeLocked( 6842 elapsedRealtimeUs, which); 6843 } 6844 getWifiStateCount(int wifiState, int which)6845 @Override public int getWifiStateCount(int wifiState, int which) { 6846 return mWifiStateTimer[wifiState].getCountLocked(which); 6847 } 6848 getWifiStateTimer(int wifiState)6849 @Override public Timer getWifiStateTimer(int wifiState) { 6850 return mWifiStateTimer[wifiState]; 6851 } 6852 getWifiSupplStateTime(int state, long elapsedRealtimeUs, int which)6853 @Override public long getWifiSupplStateTime(int state, 6854 long elapsedRealtimeUs, int which) { 6855 return mWifiSupplStateTimer[state].getTotalTimeLocked( 6856 elapsedRealtimeUs, which); 6857 } 6858 getWifiSupplStateCount(int state, int which)6859 @Override public int getWifiSupplStateCount(int state, int which) { 6860 return mWifiSupplStateTimer[state].getCountLocked(which); 6861 } 6862 getWifiSupplStateTimer(int state)6863 @Override public Timer getWifiSupplStateTimer(int state) { 6864 return mWifiSupplStateTimer[state]; 6865 } 6866 getWifiSignalStrengthTime(int strengthBin, long elapsedRealtimeUs, int which)6867 @Override public long getWifiSignalStrengthTime(int strengthBin, 6868 long elapsedRealtimeUs, int which) { 6869 return mWifiSignalStrengthsTimer[strengthBin].getTotalTimeLocked( 6870 elapsedRealtimeUs, which); 6871 } 6872 getWifiSignalStrengthCount(int strengthBin, int which)6873 @Override public int getWifiSignalStrengthCount(int strengthBin, int which) { 6874 return mWifiSignalStrengthsTimer[strengthBin].getCountLocked(which); 6875 } 6876 getWifiSignalStrengthTimer(int strengthBin)6877 @Override public Timer getWifiSignalStrengthTimer(int strengthBin) { 6878 return mWifiSignalStrengthsTimer[strengthBin]; 6879 } 6880 6881 @Override getBluetoothControllerActivity()6882 public ControllerActivityCounter getBluetoothControllerActivity() { 6883 return mBluetoothActivity; 6884 } 6885 6886 @Override getWifiControllerActivity()6887 public ControllerActivityCounter getWifiControllerActivity() { 6888 return mWifiActivity; 6889 } 6890 6891 @Override getModemControllerActivity()6892 public ControllerActivityCounter getModemControllerActivity() { 6893 return mModemActivity; 6894 } 6895 6896 @Override hasBluetoothActivityReporting()6897 public boolean hasBluetoothActivityReporting() { 6898 return mHasBluetoothReporting; 6899 } 6900 6901 @Override hasWifiActivityReporting()6902 public boolean hasWifiActivityReporting() { 6903 return mHasWifiReporting; 6904 } 6905 6906 @Override hasModemActivityReporting()6907 public boolean hasModemActivityReporting() { 6908 return mHasModemReporting; 6909 } 6910 6911 @Override getFlashlightOnTime(long elapsedRealtimeUs, int which)6912 public long getFlashlightOnTime(long elapsedRealtimeUs, int which) { 6913 return mFlashlightOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 6914 } 6915 6916 @Override getFlashlightOnCount(int which)6917 public long getFlashlightOnCount(int which) { 6918 return mFlashlightOnTimer.getCountLocked(which); 6919 } 6920 6921 @Override getCameraOnTime(long elapsedRealtimeUs, int which)6922 public long getCameraOnTime(long elapsedRealtimeUs, int which) { 6923 return mCameraOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 6924 } 6925 6926 @Override getBluetoothScanTime(long elapsedRealtimeUs, int which)6927 public long getBluetoothScanTime(long elapsedRealtimeUs, int which) { 6928 return mBluetoothScanTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 6929 } 6930 6931 @Override 6932 @UnsupportedAppUsage getNetworkActivityBytes(int type, int which)6933 public long getNetworkActivityBytes(int type, int which) { 6934 if (type >= 0 && type < mNetworkByteActivityCounters.length) { 6935 return mNetworkByteActivityCounters[type].getCountLocked(which); 6936 } else { 6937 return 0; 6938 } 6939 } 6940 6941 @Override getNetworkActivityPackets(int type, int which)6942 public long getNetworkActivityPackets(int type, int which) { 6943 if (type >= 0 && type < mNetworkPacketActivityCounters.length) { 6944 return mNetworkPacketActivityCounters[type].getCountLocked(which); 6945 } else { 6946 return 0; 6947 } 6948 } 6949 6950 @Override getBluetoothMeasuredBatteryConsumptionUC()6951 public long getBluetoothMeasuredBatteryConsumptionUC() { 6952 return getPowerBucketConsumptionUC(MeasuredEnergyStats.POWER_BUCKET_BLUETOOTH); 6953 } 6954 6955 @Override getCpuMeasuredBatteryConsumptionUC()6956 public long getCpuMeasuredBatteryConsumptionUC() { 6957 return getPowerBucketConsumptionUC(MeasuredEnergyStats.POWER_BUCKET_CPU); 6958 } 6959 6960 @Override getGnssMeasuredBatteryConsumptionUC()6961 public long getGnssMeasuredBatteryConsumptionUC() { 6962 return getPowerBucketConsumptionUC(MeasuredEnergyStats.POWER_BUCKET_GNSS); 6963 } 6964 6965 @Override getMobileRadioMeasuredBatteryConsumptionUC()6966 public long getMobileRadioMeasuredBatteryConsumptionUC() { 6967 return getPowerBucketConsumptionUC(MeasuredEnergyStats.POWER_BUCKET_MOBILE_RADIO); 6968 } 6969 6970 @Override getScreenOnMeasuredBatteryConsumptionUC()6971 public long getScreenOnMeasuredBatteryConsumptionUC() { 6972 return getPowerBucketConsumptionUC(MeasuredEnergyStats.POWER_BUCKET_SCREEN_ON); 6973 } 6974 6975 @Override getScreenDozeMeasuredBatteryConsumptionUC()6976 public long getScreenDozeMeasuredBatteryConsumptionUC() { 6977 return getPowerBucketConsumptionUC(MeasuredEnergyStats.POWER_BUCKET_SCREEN_DOZE); 6978 } 6979 6980 @Override getWifiMeasuredBatteryConsumptionUC()6981 public long getWifiMeasuredBatteryConsumptionUC() { 6982 return getPowerBucketConsumptionUC(MeasuredEnergyStats.POWER_BUCKET_WIFI); 6983 } 6984 6985 /** 6986 * Returns the consumption (in microcoulombs) that the given standard power bucket consumed. 6987 * Will return {@link #POWER_DATA_UNAVAILABLE} if data is unavailable 6988 * 6989 * @param bucket standard power bucket of interest 6990 * @return charge (in microcoulombs) used for this power bucket 6991 */ getPowerBucketConsumptionUC(@tandardPowerBucket int bucket)6992 private long getPowerBucketConsumptionUC(@StandardPowerBucket int bucket) { 6993 if (mGlobalMeasuredEnergyStats == null) { 6994 return POWER_DATA_UNAVAILABLE; 6995 } 6996 return mGlobalMeasuredEnergyStats.getAccumulatedStandardBucketCharge(bucket); 6997 } 6998 6999 @Override getCustomConsumerMeasuredBatteryConsumptionUC()7000 public @Nullable long[] getCustomConsumerMeasuredBatteryConsumptionUC() { 7001 if (mGlobalMeasuredEnergyStats == null) { 7002 return null; 7003 } 7004 return mGlobalMeasuredEnergyStats.getAccumulatedCustomBucketCharges(); 7005 } 7006 7007 /** 7008 * Returns the names of custom power components. 7009 */ 7010 @Override getCustomEnergyConsumerNames()7011 public @NonNull String[] getCustomEnergyConsumerNames() { 7012 if (mGlobalMeasuredEnergyStats == null) { 7013 return new String[0]; 7014 } 7015 final String[] names = mGlobalMeasuredEnergyStats.getCustomBucketNames(); 7016 for (int i = 0; i < names.length; i++) { 7017 if (TextUtils.isEmpty(names[i])) { 7018 names[i] = "CUSTOM_" + BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID + i; 7019 } 7020 } 7021 return names; 7022 } 7023 getStartClockTime()7024 @Override public long getStartClockTime() { 7025 final long currentTimeMs = mClocks.currentTimeMillis(); 7026 if ((currentTimeMs > MILLISECONDS_IN_YEAR 7027 && mStartClockTimeMs < (currentTimeMs - MILLISECONDS_IN_YEAR)) 7028 || (mStartClockTimeMs > currentTimeMs)) { 7029 // If the start clock time has changed by more than a year, then presumably 7030 // the previous time was completely bogus. So we are going to figure out a 7031 // new time based on how much time has elapsed since we started counting. 7032 recordCurrentTimeChangeLocked(currentTimeMs, mClocks.elapsedRealtime(), 7033 mClocks.uptimeMillis()); 7034 return currentTimeMs - (mClocks.elapsedRealtime() - (mRealtimeStartUs / 1000)); 7035 } 7036 return mStartClockTimeMs; 7037 } 7038 getStartPlatformVersion()7039 @Override public String getStartPlatformVersion() { 7040 return mStartPlatformVersion; 7041 } 7042 getEndPlatformVersion()7043 @Override public String getEndPlatformVersion() { 7044 return mEndPlatformVersion; 7045 } 7046 getParcelVersion()7047 @Override public int getParcelVersion() { 7048 return VERSION; 7049 } 7050 getIsOnBattery()7051 @Override public boolean getIsOnBattery() { 7052 return mOnBattery; 7053 } 7054 getStatsStartRealtime()7055 @Override public long getStatsStartRealtime() { 7056 return mRealtimeStartUs; 7057 } 7058 7059 @UnsupportedAppUsage getUidStats()7060 @Override public SparseArray<? extends BatteryStats.Uid> getUidStats() { 7061 return mUidStats; 7062 } 7063 resetIfNotNull(T t, boolean detachIfReset, long elapsedRealtimeUs)7064 private static <T extends TimeBaseObs> boolean resetIfNotNull(T t, boolean detachIfReset, 7065 long elapsedRealtimeUs) { 7066 if (t != null) { 7067 return t.reset(detachIfReset, elapsedRealtimeUs); 7068 } 7069 return true; 7070 } 7071 resetIfNotNull(T[] t, boolean detachIfReset, long elapsedRealtimeUs)7072 private static <T extends TimeBaseObs> boolean resetIfNotNull(T[] t, boolean detachIfReset, 7073 long elapsedRealtimeUs) { 7074 if (t != null) { 7075 boolean ret = true; 7076 for (int i = 0; i < t.length; i++) { 7077 ret &= resetIfNotNull(t[i], detachIfReset, elapsedRealtimeUs); 7078 } 7079 return ret; 7080 } 7081 return true; 7082 } 7083 resetIfNotNull(T[][] t, boolean detachIfReset, long elapsedRealtimeUs)7084 private static <T extends TimeBaseObs> boolean resetIfNotNull(T[][] t, boolean detachIfReset, 7085 long elapsedRealtimeUs) { 7086 if (t != null) { 7087 boolean ret = true; 7088 for (int i = 0; i < t.length; i++) { 7089 ret &= resetIfNotNull(t[i], detachIfReset, elapsedRealtimeUs); 7090 } 7091 return ret; 7092 } 7093 return true; 7094 } 7095 resetIfNotNull(ControllerActivityCounterImpl counter, boolean detachIfReset, long elapsedRealtimeUs)7096 private static boolean resetIfNotNull(ControllerActivityCounterImpl counter, 7097 boolean detachIfReset, long elapsedRealtimeUs) { 7098 if (counter != null) { 7099 counter.reset(detachIfReset, elapsedRealtimeUs); 7100 } 7101 return true; 7102 } 7103 detachIfNotNull(T t)7104 private static <T extends TimeBaseObs> void detachIfNotNull(T t) { 7105 if (t != null) { 7106 t.detach(); 7107 } 7108 } 7109 detachIfNotNull(T[] t)7110 private static <T extends TimeBaseObs> void detachIfNotNull(T[] t) { 7111 if (t != null) { 7112 for (int i = 0; i < t.length; i++) { 7113 detachIfNotNull(t[i]); 7114 } 7115 } 7116 } 7117 detachIfNotNull(T[][] t)7118 private static <T extends TimeBaseObs> void detachIfNotNull(T[][] t) { 7119 if (t != null) { 7120 for (int i = 0; i < t.length; i++) { 7121 detachIfNotNull(t[i]); 7122 } 7123 } 7124 } 7125 detachIfNotNull(ControllerActivityCounterImpl counter)7126 private static void detachIfNotNull(ControllerActivityCounterImpl counter) { 7127 if (counter != null) { 7128 counter.detach(); 7129 } 7130 } 7131 7132 /** 7133 * Accumulates stats for a specific binder transaction. 7134 */ 7135 @VisibleForTesting 7136 protected static class BinderCallStats { 7137 static final Comparator<BinderCallStats> COMPARATOR = 7138 Comparator.comparing(BinderCallStats::getClassName) 7139 .thenComparing(BinderCallStats::getMethodName); 7140 7141 public Class<? extends Binder> binderClass; 7142 public int transactionCode; 7143 public String methodName; 7144 7145 public long callCount; 7146 public long recordedCallCount; 7147 public long recordedCpuTimeMicros; 7148 7149 7150 @Override hashCode()7151 public int hashCode() { 7152 return binderClass.hashCode() * 31 + transactionCode; 7153 } 7154 7155 @Override equals(Object obj)7156 public boolean equals(Object obj) { 7157 if (!(obj instanceof BinderCallStats)) { 7158 return false; 7159 } 7160 BinderCallStats bcsk = (BinderCallStats) obj; 7161 return binderClass.equals(bcsk.binderClass) && transactionCode == bcsk.transactionCode; 7162 } 7163 getClassName()7164 public String getClassName() { 7165 return binderClass.getName(); 7166 } 7167 getMethodName()7168 public String getMethodName() { 7169 return methodName; 7170 } 7171 7172 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) ensureMethodName(BinderTransactionNameResolver resolver)7173 public void ensureMethodName(BinderTransactionNameResolver resolver) { 7174 if (methodName == null) { 7175 methodName = resolver.getMethodName(binderClass, transactionCode); 7176 } 7177 } 7178 7179 @Override toString()7180 public String toString() { 7181 return "BinderCallStats{" 7182 + binderClass 7183 + " transaction=" + transactionCode 7184 + " callCount=" + callCount 7185 + " recordedCallCount=" + recordedCallCount 7186 + " recorderCpuTimeMicros=" + recordedCpuTimeMicros 7187 + "}"; 7188 } 7189 } 7190 7191 /** 7192 * The statistics associated with a particular uid. 7193 */ 7194 public static class Uid extends BatteryStats.Uid { 7195 /** 7196 * BatteryStatsImpl that we are associated with. 7197 */ 7198 protected BatteryStatsImpl mBsi; 7199 7200 final int mUid; 7201 7202 /** TimeBase for when uid is in background and device is on battery. */ 7203 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) 7204 public final TimeBase mOnBatteryBackgroundTimeBase; 7205 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) 7206 public final TimeBase mOnBatteryScreenOffBackgroundTimeBase; 7207 7208 boolean mWifiRunning; 7209 StopwatchTimer mWifiRunningTimer; 7210 7211 boolean mFullWifiLockOut; 7212 StopwatchTimer mFullWifiLockTimer; 7213 7214 boolean mWifiScanStarted; 7215 DualTimer mWifiScanTimer; 7216 7217 static final int NO_BATCHED_SCAN_STARTED = -1; 7218 int mWifiBatchedScanBinStarted = NO_BATCHED_SCAN_STARTED; 7219 StopwatchTimer[] mWifiBatchedScanTimer; 7220 7221 int mWifiMulticastWakelockCount; 7222 StopwatchTimer mWifiMulticastTimer; 7223 7224 StopwatchTimer mAudioTurnedOnTimer; 7225 StopwatchTimer mVideoTurnedOnTimer; 7226 StopwatchTimer mFlashlightTurnedOnTimer; 7227 StopwatchTimer mCameraTurnedOnTimer; 7228 StopwatchTimer mForegroundActivityTimer; 7229 StopwatchTimer mForegroundServiceTimer; 7230 /** Total time spent by the uid holding any partial wakelocks. */ 7231 DualTimer mAggregatedPartialWakelockTimer; 7232 DualTimer mBluetoothScanTimer; 7233 DualTimer mBluetoothUnoptimizedScanTimer; 7234 Counter mBluetoothScanResultCounter; 7235 Counter mBluetoothScanResultBgCounter; 7236 7237 int mProcessState = ActivityManager.PROCESS_STATE_NONEXISTENT; 7238 StopwatchTimer[] mProcessStateTimer; 7239 7240 boolean mInForegroundService = false; 7241 7242 BatchTimer mVibratorOnTimer; 7243 7244 Counter[] mUserActivityCounters; 7245 7246 LongSamplingCounter[] mNetworkByteActivityCounters; 7247 LongSamplingCounter[] mNetworkPacketActivityCounters; 7248 LongSamplingCounter mMobileRadioActiveTime; 7249 LongSamplingCounter mMobileRadioActiveCount; 7250 7251 /** 7252 * How many times this UID woke up the Application Processor due to a Mobile radio packet. 7253 */ 7254 private LongSamplingCounter mMobileRadioApWakeupCount; 7255 7256 /** 7257 * How many times this UID woke up the Application Processor due to a Wifi packet. 7258 */ 7259 private LongSamplingCounter mWifiRadioApWakeupCount; 7260 7261 /** 7262 * The amount of time this uid has kept the WiFi controller in idle, tx, and rx mode. 7263 * Can be null if the UID has had no such activity. 7264 */ 7265 private ControllerActivityCounterImpl mWifiControllerActivity; 7266 7267 /** 7268 * The amount of time this uid has kept the Bluetooth controller in idle, tx, and rx mode. 7269 * Can be null if the UID has had no such activity. 7270 */ 7271 private ControllerActivityCounterImpl mBluetoothControllerActivity; 7272 7273 /** 7274 * The amount of time this uid has kept the Modem controller in idle, tx, and rx mode. 7275 * Can be null if the UID has had no such activity. 7276 */ 7277 private ControllerActivityCounterImpl mModemControllerActivity; 7278 7279 /** 7280 * The CPU times we had at the last history details update. 7281 */ 7282 long mLastStepUserTimeMs; 7283 long mLastStepSystemTimeMs; 7284 long mCurStepUserTimeMs; 7285 long mCurStepSystemTimeMs; 7286 7287 LongSamplingCounter mUserCpuTime; 7288 LongSamplingCounter mSystemCpuTime; 7289 LongSamplingCounter[][] mCpuClusterSpeedTimesUs; 7290 LongSamplingCounter mCpuActiveTimeMs; 7291 7292 LongSamplingCounterArray mCpuFreqTimeMs; 7293 LongSamplingCounterArray mScreenOffCpuFreqTimeMs; 7294 LongSamplingCounterArray mCpuClusterTimesMs; 7295 7296 LongSamplingCounterArray[] mProcStateTimeMs; 7297 LongSamplingCounterArray[] mProcStateScreenOffTimeMs; 7298 7299 IntArray mChildUids; 7300 7301 /** 7302 * The statistics we have collected for this uid's wake locks. 7303 */ 7304 final OverflowArrayMap<Wakelock> mWakelockStats; 7305 7306 /** 7307 * The statistics we have collected for this uid's syncs. 7308 */ 7309 final OverflowArrayMap<DualTimer> mSyncStats; 7310 7311 /** 7312 * The statistics we have collected for this uid's jobs. 7313 */ 7314 final OverflowArrayMap<DualTimer> mJobStats; 7315 7316 /** 7317 * Count of the jobs that have completed and the reasons why they completed. 7318 */ 7319 final ArrayMap<String, SparseIntArray> mJobCompletions = new ArrayMap<>(); 7320 7321 /** 7322 * Count of app launch events that had associated deferred job counts or info about 7323 * last time a job was run. 7324 */ 7325 Counter mJobsDeferredEventCount; 7326 7327 /** 7328 * Count of deferred jobs that were pending when the app was launched or brought to 7329 * the foreground through a user interaction. 7330 */ 7331 Counter mJobsDeferredCount; 7332 7333 /** 7334 * Sum of time since the last time a job was run for this app before it was launched. 7335 */ 7336 LongSamplingCounter mJobsFreshnessTimeMs; 7337 7338 /** 7339 * Array of counts of instances where the time since the last job was run for the app 7340 * fell within one of the thresholds in {@link #JOB_FRESHNESS_BUCKETS}. 7341 */ 7342 final Counter[] mJobsFreshnessBuckets; 7343 7344 /** 7345 * The statistics we have collected for this uid's sensor activations. 7346 */ 7347 final SparseArray<Sensor> mSensorStats = new SparseArray<>(); 7348 7349 /** 7350 * The statistics we have collected for this uid's processes. 7351 */ 7352 final ArrayMap<String, Proc> mProcessStats = new ArrayMap<>(); 7353 7354 /** 7355 * The statistics we have collected for this uid's processes. 7356 */ 7357 final ArrayMap<String, Pkg> mPackageStats = new ArrayMap<>(); 7358 7359 /** 7360 * The transient wake stats we have collected for this uid's pids. 7361 */ 7362 final SparseArray<Pid> mPids = new SparseArray<>(); 7363 7364 /** 7365 * Grand total of system server binder calls made by this uid. 7366 */ 7367 private long mBinderCallCount; 7368 7369 /** 7370 * Detailed information about system server binder calls made by this uid. 7371 */ 7372 private final ArraySet<BinderCallStats> mBinderCallStats = new ArraySet<>(); 7373 7374 /** 7375 * Measured charge consumption by this uid while on battery. 7376 * Its '<b>custom</b> power buckets' correspond to the 7377 * {@link android.hardware.power.stats.EnergyConsumer.ordinal}s of (custom) energy consumer 7378 * type {@link android.hardware.power.stats.EnergyConsumerType#OTHER}). 7379 * 7380 * Will be null if energy consumer data is completely unavailable (in which case 7381 * {@link #mGlobalMeasuredEnergyStats} will also be null) or if the power usage by this uid 7382 * is 0 for every bucket. 7383 */ 7384 private MeasuredEnergyStats mUidMeasuredEnergyStats; 7385 7386 /** 7387 * Estimated total time spent by the system server handling requests from this uid. 7388 */ 7389 private long mSystemServiceTimeUs; 7390 7391 /** 7392 * Estimated proportion of system server binder call CPU cost for this uid. 7393 */ 7394 private double mProportionalSystemServiceUsage; 7395 Uid(BatteryStatsImpl bsi, int uid)7396 public Uid(BatteryStatsImpl bsi, int uid) { 7397 this(bsi, uid, bsi.mClocks.elapsedRealtime(), bsi.mClocks.uptimeMillis()); 7398 } 7399 Uid(BatteryStatsImpl bsi, int uid, long elapsedRealtimeMs, long uptimeMs)7400 public Uid(BatteryStatsImpl bsi, int uid, long elapsedRealtimeMs, long uptimeMs) { 7401 mBsi = bsi; 7402 mUid = uid; 7403 7404 /* Observer list of TimeBase object in Uid is short */ 7405 mOnBatteryBackgroundTimeBase = new TimeBase(false); 7406 mOnBatteryBackgroundTimeBase.init(uptimeMs * 1000, elapsedRealtimeMs * 1000); 7407 /* Observer list of TimeBase object in Uid is short */ 7408 mOnBatteryScreenOffBackgroundTimeBase = new TimeBase(false); 7409 mOnBatteryScreenOffBackgroundTimeBase.init(uptimeMs * 1000, elapsedRealtimeMs * 1000); 7410 7411 mUserCpuTime = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); 7412 mSystemCpuTime = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); 7413 mCpuActiveTimeMs = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); 7414 mCpuClusterTimesMs = new LongSamplingCounterArray(mBsi.mOnBatteryTimeBase); 7415 7416 mWakelockStats = mBsi.new OverflowArrayMap<Wakelock>(uid) { 7417 @Override public Wakelock instantiateObject() { 7418 return new Wakelock(mBsi, Uid.this); 7419 } 7420 }; 7421 mSyncStats = mBsi.new OverflowArrayMap<DualTimer>(uid) { 7422 @Override public DualTimer instantiateObject() { 7423 return new DualTimer(mBsi.mClocks, Uid.this, SYNC, null, 7424 mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase); 7425 } 7426 }; 7427 mJobStats = mBsi.new OverflowArrayMap<DualTimer>(uid) { 7428 @Override public DualTimer instantiateObject() { 7429 return new DualTimer(mBsi.mClocks, Uid.this, JOB, null, 7430 mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase); 7431 } 7432 }; 7433 7434 mWifiRunningTimer = new StopwatchTimer(mBsi.mClocks, this, WIFI_RUNNING, 7435 mBsi.mWifiRunningTimers, mBsi.mOnBatteryTimeBase); 7436 mFullWifiLockTimer = new StopwatchTimer(mBsi.mClocks, this, FULL_WIFI_LOCK, 7437 mBsi.mFullWifiLockTimers, mBsi.mOnBatteryTimeBase); 7438 mWifiScanTimer = new DualTimer(mBsi.mClocks, this, WIFI_SCAN, 7439 mBsi.mWifiScanTimers, mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase); 7440 mWifiBatchedScanTimer = new StopwatchTimer[NUM_WIFI_BATCHED_SCAN_BINS]; 7441 mWifiMulticastTimer = new StopwatchTimer(mBsi.mClocks, this, WIFI_MULTICAST_ENABLED, 7442 mBsi.mWifiMulticastTimers, mBsi.mOnBatteryTimeBase); 7443 mProcessStateTimer = new StopwatchTimer[NUM_PROCESS_STATE]; 7444 mJobsDeferredEventCount = new Counter(mBsi.mOnBatteryTimeBase); 7445 mJobsDeferredCount = new Counter(mBsi.mOnBatteryTimeBase); 7446 mJobsFreshnessTimeMs = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); 7447 mJobsFreshnessBuckets = new Counter[JOB_FRESHNESS_BUCKETS.length]; 7448 } 7449 7450 @VisibleForTesting setProcessStateForTest(int procState)7451 public void setProcessStateForTest(int procState) { 7452 mProcessState = procState; 7453 } 7454 7455 @Override getCpuFreqTimes(int which)7456 public long[] getCpuFreqTimes(int which) { 7457 return nullIfAllZeros(mCpuFreqTimeMs, which); 7458 } 7459 7460 @Override getScreenOffCpuFreqTimes(int which)7461 public long[] getScreenOffCpuFreqTimes(int which) { 7462 return nullIfAllZeros(mScreenOffCpuFreqTimeMs, which); 7463 } 7464 7465 @Override getCpuActiveTime()7466 public long getCpuActiveTime() { 7467 return mCpuActiveTimeMs.getCountLocked(STATS_SINCE_CHARGED); 7468 } 7469 7470 @Override getCpuClusterTimes()7471 public long[] getCpuClusterTimes() { 7472 return nullIfAllZeros(mCpuClusterTimesMs, STATS_SINCE_CHARGED); 7473 } 7474 7475 @Override getCpuFreqTimes(int which, int procState)7476 public long[] getCpuFreqTimes(int which, int procState) { 7477 if (which < 0 || which >= NUM_PROCESS_STATE) { 7478 return null; 7479 } 7480 if (mProcStateTimeMs == null) { 7481 return null; 7482 } 7483 if (!mBsi.mPerProcStateCpuTimesAvailable) { 7484 mProcStateTimeMs = null; 7485 return null; 7486 } 7487 return nullIfAllZeros(mProcStateTimeMs[procState], which); 7488 } 7489 7490 @Override getScreenOffCpuFreqTimes(int which, int procState)7491 public long[] getScreenOffCpuFreqTimes(int which, int procState) { 7492 if (which < 0 || which >= NUM_PROCESS_STATE) { 7493 return null; 7494 } 7495 if (mProcStateScreenOffTimeMs == null) { 7496 return null; 7497 } 7498 if (!mBsi.mPerProcStateCpuTimesAvailable) { 7499 mProcStateScreenOffTimeMs = null; 7500 return null; 7501 } 7502 return nullIfAllZeros(mProcStateScreenOffTimeMs[procState], which); 7503 } 7504 getBinderCallCount()7505 public long getBinderCallCount() { 7506 return mBinderCallCount; 7507 } 7508 7509 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE) getBinderCallStats()7510 public ArraySet<BinderCallStats> getBinderCallStats() { 7511 return mBinderCallStats; 7512 } 7513 7514 @Override getProportionalSystemServiceUsage()7515 public double getProportionalSystemServiceUsage() { 7516 return mProportionalSystemServiceUsage; 7517 } 7518 addIsolatedUid(int isolatedUid)7519 public void addIsolatedUid(int isolatedUid) { 7520 if (mChildUids == null) { 7521 mChildUids = new IntArray(); 7522 } else if (mChildUids.indexOf(isolatedUid) >= 0) { 7523 return; 7524 } 7525 mChildUids.add(isolatedUid); 7526 } 7527 removeIsolatedUid(int isolatedUid)7528 public void removeIsolatedUid(int isolatedUid) { 7529 final int idx = mChildUids == null ? -1 : mChildUids.indexOf(isolatedUid); 7530 if (idx < 0) { 7531 return; 7532 } 7533 mChildUids.remove(idx); 7534 } 7535 nullIfAllZeros(LongSamplingCounterArray cpuTimesMs, int which)7536 private long[] nullIfAllZeros(LongSamplingCounterArray cpuTimesMs, int which) { 7537 if (cpuTimesMs == null) { 7538 return null; 7539 } 7540 final long[] counts = cpuTimesMs.getCountsLocked(which); 7541 if (counts == null) { 7542 return null; 7543 } 7544 // Return counts only if at least one of the elements is non-zero. 7545 for (int i = counts.length - 1; i >= 0; --i) { 7546 if (counts[i] != 0) { 7547 return counts; 7548 } 7549 } 7550 return null; 7551 } 7552 addProcStateTimesMs(int procState, long[] cpuTimesMs, boolean onBattery)7553 private void addProcStateTimesMs(int procState, long[] cpuTimesMs, boolean onBattery) { 7554 if (mProcStateTimeMs == null) { 7555 mProcStateTimeMs = new LongSamplingCounterArray[NUM_PROCESS_STATE]; 7556 } 7557 if (mProcStateTimeMs[procState] == null 7558 || mProcStateTimeMs[procState].getSize() != cpuTimesMs.length) { 7559 detachIfNotNull(mProcStateTimeMs[procState]); 7560 mProcStateTimeMs[procState] = new LongSamplingCounterArray( 7561 mBsi.mOnBatteryTimeBase); 7562 } 7563 mProcStateTimeMs[procState].addCountLocked(cpuTimesMs, onBattery); 7564 } 7565 addProcStateScreenOffTimesMs(int procState, long[] cpuTimesMs, boolean onBatteryScreenOff)7566 private void addProcStateScreenOffTimesMs(int procState, long[] cpuTimesMs, 7567 boolean onBatteryScreenOff) { 7568 if (mProcStateScreenOffTimeMs == null) { 7569 mProcStateScreenOffTimeMs = new LongSamplingCounterArray[NUM_PROCESS_STATE]; 7570 } 7571 if (mProcStateScreenOffTimeMs[procState] == null 7572 || mProcStateScreenOffTimeMs[procState].getSize() != cpuTimesMs.length) { 7573 detachIfNotNull(mProcStateScreenOffTimeMs[procState]); 7574 mProcStateScreenOffTimeMs[procState] = new LongSamplingCounterArray( 7575 mBsi.mOnBatteryScreenOffTimeBase); 7576 } 7577 mProcStateScreenOffTimeMs[procState].addCountLocked(cpuTimesMs, onBatteryScreenOff); 7578 } 7579 7580 @Override getAggregatedPartialWakelockTimer()7581 public Timer getAggregatedPartialWakelockTimer() { 7582 return mAggregatedPartialWakelockTimer; 7583 } 7584 7585 @Override 7586 @UnsupportedAppUsage getWakelockStats()7587 public ArrayMap<String, ? extends BatteryStats.Uid.Wakelock> getWakelockStats() { 7588 return mWakelockStats.getMap(); 7589 } 7590 7591 @Override getMulticastWakelockStats()7592 public Timer getMulticastWakelockStats() { 7593 return mWifiMulticastTimer; 7594 } 7595 7596 @Override getSyncStats()7597 public ArrayMap<String, ? extends BatteryStats.Timer> getSyncStats() { 7598 return mSyncStats.getMap(); 7599 } 7600 7601 @Override getJobStats()7602 public ArrayMap<String, ? extends BatteryStats.Timer> getJobStats() { 7603 return mJobStats.getMap(); 7604 } 7605 7606 @Override getJobCompletionStats()7607 public ArrayMap<String, SparseIntArray> getJobCompletionStats() { 7608 return mJobCompletions; 7609 } 7610 7611 @Override 7612 @UnsupportedAppUsage getSensorStats()7613 public SparseArray<? extends BatteryStats.Uid.Sensor> getSensorStats() { 7614 return mSensorStats; 7615 } 7616 7617 @Override 7618 @UnsupportedAppUsage getProcessStats()7619 public ArrayMap<String, ? extends BatteryStats.Uid.Proc> getProcessStats() { 7620 return mProcessStats; 7621 } 7622 7623 @Override getPackageStats()7624 public ArrayMap<String, ? extends BatteryStats.Uid.Pkg> getPackageStats() { 7625 return mPackageStats; 7626 } 7627 7628 @Override 7629 @UnsupportedAppUsage getUid()7630 public int getUid() { 7631 return mUid; 7632 } 7633 7634 @Override noteWifiRunningLocked(long elapsedRealtimeMs)7635 public void noteWifiRunningLocked(long elapsedRealtimeMs) { 7636 if (!mWifiRunning) { 7637 mWifiRunning = true; 7638 if (mWifiRunningTimer == null) { 7639 mWifiRunningTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, WIFI_RUNNING, 7640 mBsi.mWifiRunningTimers, mBsi.mOnBatteryTimeBase); 7641 } 7642 mWifiRunningTimer.startRunningLocked(elapsedRealtimeMs); 7643 } 7644 } 7645 7646 @Override noteWifiStoppedLocked(long elapsedRealtimeMs)7647 public void noteWifiStoppedLocked(long elapsedRealtimeMs) { 7648 if (mWifiRunning) { 7649 mWifiRunning = false; 7650 mWifiRunningTimer.stopRunningLocked(elapsedRealtimeMs); 7651 } 7652 } 7653 7654 @Override noteFullWifiLockAcquiredLocked(long elapsedRealtimeMs)7655 public void noteFullWifiLockAcquiredLocked(long elapsedRealtimeMs) { 7656 if (!mFullWifiLockOut) { 7657 mFullWifiLockOut = true; 7658 if (mFullWifiLockTimer == null) { 7659 mFullWifiLockTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, FULL_WIFI_LOCK, 7660 mBsi.mFullWifiLockTimers, mBsi.mOnBatteryTimeBase); 7661 } 7662 mFullWifiLockTimer.startRunningLocked(elapsedRealtimeMs); 7663 } 7664 } 7665 7666 @Override noteFullWifiLockReleasedLocked(long elapsedRealtimeMs)7667 public void noteFullWifiLockReleasedLocked(long elapsedRealtimeMs) { 7668 if (mFullWifiLockOut) { 7669 mFullWifiLockOut = false; 7670 mFullWifiLockTimer.stopRunningLocked(elapsedRealtimeMs); 7671 } 7672 } 7673 7674 @Override noteWifiScanStartedLocked(long elapsedRealtimeMs)7675 public void noteWifiScanStartedLocked(long elapsedRealtimeMs) { 7676 if (!mWifiScanStarted) { 7677 mWifiScanStarted = true; 7678 if (mWifiScanTimer == null) { 7679 mWifiScanTimer = new DualTimer(mBsi.mClocks, Uid.this, WIFI_SCAN, 7680 mBsi.mWifiScanTimers, mBsi.mOnBatteryTimeBase, 7681 mOnBatteryBackgroundTimeBase); 7682 } 7683 mWifiScanTimer.startRunningLocked(elapsedRealtimeMs); 7684 } 7685 } 7686 7687 @Override noteWifiScanStoppedLocked(long elapsedRealtimeMs)7688 public void noteWifiScanStoppedLocked(long elapsedRealtimeMs) { 7689 if (mWifiScanStarted) { 7690 mWifiScanStarted = false; 7691 mWifiScanTimer.stopRunningLocked(elapsedRealtimeMs); 7692 } 7693 } 7694 7695 @Override noteWifiBatchedScanStartedLocked(int csph, long elapsedRealtimeMs)7696 public void noteWifiBatchedScanStartedLocked(int csph, long elapsedRealtimeMs) { 7697 int bin = 0; 7698 while (csph > 8 && bin < NUM_WIFI_BATCHED_SCAN_BINS-1) { 7699 csph = csph >> 3; 7700 bin++; 7701 } 7702 7703 if (mWifiBatchedScanBinStarted == bin) return; 7704 7705 if (mWifiBatchedScanBinStarted != NO_BATCHED_SCAN_STARTED) { 7706 mWifiBatchedScanTimer[mWifiBatchedScanBinStarted]. 7707 stopRunningLocked(elapsedRealtimeMs); 7708 } 7709 mWifiBatchedScanBinStarted = bin; 7710 if (mWifiBatchedScanTimer[bin] == null) { 7711 makeWifiBatchedScanBin(bin, null); 7712 } 7713 mWifiBatchedScanTimer[bin].startRunningLocked(elapsedRealtimeMs); 7714 } 7715 7716 @Override noteWifiBatchedScanStoppedLocked(long elapsedRealtimeMs)7717 public void noteWifiBatchedScanStoppedLocked(long elapsedRealtimeMs) { 7718 if (mWifiBatchedScanBinStarted != NO_BATCHED_SCAN_STARTED) { 7719 mWifiBatchedScanTimer[mWifiBatchedScanBinStarted]. 7720 stopRunningLocked(elapsedRealtimeMs); 7721 mWifiBatchedScanBinStarted = NO_BATCHED_SCAN_STARTED; 7722 } 7723 } 7724 7725 @Override noteWifiMulticastEnabledLocked(long elapsedRealtimeMs)7726 public void noteWifiMulticastEnabledLocked(long elapsedRealtimeMs) { 7727 if (mWifiMulticastWakelockCount == 0) { 7728 if (mWifiMulticastTimer == null) { 7729 mWifiMulticastTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, 7730 WIFI_MULTICAST_ENABLED, mBsi.mWifiMulticastTimers, mBsi.mOnBatteryTimeBase); 7731 } 7732 mWifiMulticastTimer.startRunningLocked(elapsedRealtimeMs); 7733 } 7734 mWifiMulticastWakelockCount++; 7735 } 7736 7737 @Override noteWifiMulticastDisabledLocked(long elapsedRealtimeMs)7738 public void noteWifiMulticastDisabledLocked(long elapsedRealtimeMs) { 7739 if (mWifiMulticastWakelockCount == 0) { 7740 return; 7741 } 7742 7743 mWifiMulticastWakelockCount--; 7744 if (mWifiMulticastWakelockCount == 0) { 7745 mWifiMulticastTimer.stopRunningLocked(elapsedRealtimeMs); 7746 } 7747 } 7748 7749 @Override getWifiControllerActivity()7750 public ControllerActivityCounter getWifiControllerActivity() { 7751 return mWifiControllerActivity; 7752 } 7753 7754 @Override getBluetoothControllerActivity()7755 public ControllerActivityCounter getBluetoothControllerActivity() { 7756 return mBluetoothControllerActivity; 7757 } 7758 7759 @Override getModemControllerActivity()7760 public ControllerActivityCounter getModemControllerActivity() { 7761 return mModemControllerActivity; 7762 } 7763 getOrCreateWifiControllerActivityLocked()7764 public ControllerActivityCounterImpl getOrCreateWifiControllerActivityLocked() { 7765 if (mWifiControllerActivity == null) { 7766 mWifiControllerActivity = new ControllerActivityCounterImpl(mBsi.mOnBatteryTimeBase, 7767 NUM_BT_TX_LEVELS); 7768 } 7769 return mWifiControllerActivity; 7770 } 7771 getOrCreateBluetoothControllerActivityLocked()7772 public ControllerActivityCounterImpl getOrCreateBluetoothControllerActivityLocked() { 7773 if (mBluetoothControllerActivity == null) { 7774 mBluetoothControllerActivity = new ControllerActivityCounterImpl(mBsi.mOnBatteryTimeBase, 7775 NUM_BT_TX_LEVELS); 7776 } 7777 return mBluetoothControllerActivity; 7778 } 7779 getOrCreateModemControllerActivityLocked()7780 public ControllerActivityCounterImpl getOrCreateModemControllerActivityLocked() { 7781 if (mModemControllerActivity == null) { 7782 mModemControllerActivity = new ControllerActivityCounterImpl(mBsi.mOnBatteryTimeBase, 7783 ModemActivityInfo.getNumTxPowerLevels()); 7784 } 7785 return mModemControllerActivity; 7786 } 7787 getOrCreateMeasuredEnergyStatsLocked()7788 private MeasuredEnergyStats getOrCreateMeasuredEnergyStatsLocked() { 7789 if (mUidMeasuredEnergyStats == null) { 7790 mUidMeasuredEnergyStats = 7791 MeasuredEnergyStats.createFromTemplate(mBsi.mGlobalMeasuredEnergyStats); 7792 } 7793 return mUidMeasuredEnergyStats; 7794 } 7795 7796 /** Adds the given charge to the given standard power bucket for this uid. */ addChargeToStandardBucketLocked(long chargeDeltaUC, @StandardPowerBucket int powerBucket)7797 private void addChargeToStandardBucketLocked(long chargeDeltaUC, 7798 @StandardPowerBucket int powerBucket) { 7799 getOrCreateMeasuredEnergyStatsLocked().updateStandardBucket(powerBucket, chargeDeltaUC); 7800 } 7801 7802 /** Adds the given charge to the given custom power bucket for this uid. */ addChargeToCustomBucketLocked(long chargeDeltaUC, int powerBucket)7803 private void addChargeToCustomBucketLocked(long chargeDeltaUC, int powerBucket) { 7804 getOrCreateMeasuredEnergyStatsLocked().updateCustomBucket(powerBucket, chargeDeltaUC); 7805 } 7806 7807 /** 7808 * Returns the battery consumption (in microcoulomb) of this uid for a standard power bucket 7809 * of interest. 7810 * @param bucket standard power bucket of interest 7811 * @return consumption (in microcolombs) used by this uid for this power bucket 7812 */ getMeasuredBatteryConsumptionUC(@tandardPowerBucket int bucket)7813 public long getMeasuredBatteryConsumptionUC(@StandardPowerBucket int bucket) { 7814 if (mBsi.mGlobalMeasuredEnergyStats == null 7815 || !mBsi.mGlobalMeasuredEnergyStats.isStandardBucketSupported(bucket)) { 7816 return POWER_DATA_UNAVAILABLE; 7817 } 7818 if (mUidMeasuredEnergyStats == null) { 7819 return 0L; // It is supported, but was never filled, so it must be 0 7820 } 7821 return mUidMeasuredEnergyStats.getAccumulatedStandardBucketCharge(bucket); 7822 } 7823 7824 @Override getCustomConsumerMeasuredBatteryConsumptionUC()7825 public long[] getCustomConsumerMeasuredBatteryConsumptionUC() { 7826 if (mBsi.mGlobalMeasuredEnergyStats == null) { 7827 return null; 7828 } 7829 if (mUidMeasuredEnergyStats == null) { 7830 // Custom buckets may exist. But all values for this uid are 0 so we report all 0s. 7831 return new long[mBsi.mGlobalMeasuredEnergyStats.getNumberCustomPowerBuckets()]; 7832 } 7833 return mUidMeasuredEnergyStats.getAccumulatedCustomBucketCharges(); 7834 } 7835 7836 @Override getBluetoothMeasuredBatteryConsumptionUC()7837 public long getBluetoothMeasuredBatteryConsumptionUC() { 7838 return getMeasuredBatteryConsumptionUC(MeasuredEnergyStats.POWER_BUCKET_BLUETOOTH); 7839 } 7840 7841 @Override getCpuMeasuredBatteryConsumptionUC()7842 public long getCpuMeasuredBatteryConsumptionUC() { 7843 return getMeasuredBatteryConsumptionUC(MeasuredEnergyStats.POWER_BUCKET_CPU); 7844 } 7845 7846 @Override getGnssMeasuredBatteryConsumptionUC()7847 public long getGnssMeasuredBatteryConsumptionUC() { 7848 return getMeasuredBatteryConsumptionUC(MeasuredEnergyStats.POWER_BUCKET_GNSS); 7849 } 7850 7851 @Override getMobileRadioMeasuredBatteryConsumptionUC()7852 public long getMobileRadioMeasuredBatteryConsumptionUC() { 7853 return getMeasuredBatteryConsumptionUC(MeasuredEnergyStats.POWER_BUCKET_MOBILE_RADIO); 7854 } 7855 7856 @Override getScreenOnMeasuredBatteryConsumptionUC()7857 public long getScreenOnMeasuredBatteryConsumptionUC() { 7858 return getMeasuredBatteryConsumptionUC(MeasuredEnergyStats.POWER_BUCKET_SCREEN_ON); 7859 } 7860 7861 @Override getWifiMeasuredBatteryConsumptionUC()7862 public long getWifiMeasuredBatteryConsumptionUC() { 7863 return getMeasuredBatteryConsumptionUC(MeasuredEnergyStats.POWER_BUCKET_WIFI); 7864 } 7865 7866 /** 7867 * Gets the minimum of the uid's foreground activity time and its PROCESS_STATE_TOP time 7868 * since last marked. Also sets the mark time for both these timers. 7869 * 7870 * @see BatteryStatsHelper#getProcessForegroundTimeMs 7871 * 7872 * @param doCalc if true, then calculate the minimum; else don't bother and return 0. Either 7873 * way, the mark is set. 7874 */ markProcessForegroundTimeUs(long elapsedRealtimeMs, boolean doCalc)7875 private long markProcessForegroundTimeUs(long elapsedRealtimeMs, 7876 boolean doCalc) { 7877 long fgTimeUs = 0; 7878 final StopwatchTimer fgTimer = mForegroundActivityTimer; 7879 if (fgTimer != null) { 7880 if (doCalc) fgTimeUs = fgTimer.getTimeSinceMarkLocked(elapsedRealtimeMs * 1000); 7881 fgTimer.setMark(elapsedRealtimeMs); 7882 } 7883 7884 long topTimeUs = 0; 7885 final StopwatchTimer topTimer = mProcessStateTimer[PROCESS_STATE_TOP]; 7886 if (topTimer != null) { 7887 if (doCalc) topTimeUs = topTimer.getTimeSinceMarkLocked(elapsedRealtimeMs * 1000); 7888 topTimer.setMark(elapsedRealtimeMs); 7889 } 7890 7891 // Return the min of the two 7892 return (topTimeUs < fgTimeUs) ? topTimeUs : fgTimeUs; 7893 } 7894 7895 7896 /** 7897 * Gets the uid's time spent using the GNSS since last marked. Also sets the mark time for 7898 * the GNSS timer. 7899 */ markGnssTimeUs(long elapsedRealtimeMs)7900 private long markGnssTimeUs(long elapsedRealtimeMs) { 7901 final Sensor sensor = mSensorStats.get(Sensor.GPS); 7902 if (sensor == null) { 7903 return 0; 7904 } 7905 7906 final StopwatchTimer timer = sensor.mTimer; 7907 if (timer == null) { 7908 return 0; 7909 } 7910 7911 final long gnssTimeUs = timer.getTimeSinceMarkLocked(elapsedRealtimeMs * 1000); 7912 timer.setMark(elapsedRealtimeMs); 7913 return gnssTimeUs; 7914 } 7915 createAudioTurnedOnTimerLocked()7916 public StopwatchTimer createAudioTurnedOnTimerLocked() { 7917 if (mAudioTurnedOnTimer == null) { 7918 mAudioTurnedOnTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, AUDIO_TURNED_ON, 7919 mBsi.mAudioTurnedOnTimers, mBsi.mOnBatteryTimeBase); 7920 } 7921 return mAudioTurnedOnTimer; 7922 } 7923 noteAudioTurnedOnLocked(long elapsedRealtimeMs)7924 public void noteAudioTurnedOnLocked(long elapsedRealtimeMs) { 7925 createAudioTurnedOnTimerLocked().startRunningLocked(elapsedRealtimeMs); 7926 } 7927 noteAudioTurnedOffLocked(long elapsedRealtimeMs)7928 public void noteAudioTurnedOffLocked(long elapsedRealtimeMs) { 7929 if (mAudioTurnedOnTimer != null) { 7930 mAudioTurnedOnTimer.stopRunningLocked(elapsedRealtimeMs); 7931 } 7932 } 7933 noteResetAudioLocked(long elapsedRealtimeMs)7934 public void noteResetAudioLocked(long elapsedRealtimeMs) { 7935 if (mAudioTurnedOnTimer != null) { 7936 mAudioTurnedOnTimer.stopAllRunningLocked(elapsedRealtimeMs); 7937 } 7938 } 7939 createVideoTurnedOnTimerLocked()7940 public StopwatchTimer createVideoTurnedOnTimerLocked() { 7941 if (mVideoTurnedOnTimer == null) { 7942 mVideoTurnedOnTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, VIDEO_TURNED_ON, 7943 mBsi.mVideoTurnedOnTimers, mBsi.mOnBatteryTimeBase); 7944 } 7945 return mVideoTurnedOnTimer; 7946 } 7947 noteVideoTurnedOnLocked(long elapsedRealtimeMs)7948 public void noteVideoTurnedOnLocked(long elapsedRealtimeMs) { 7949 createVideoTurnedOnTimerLocked().startRunningLocked(elapsedRealtimeMs); 7950 } 7951 noteVideoTurnedOffLocked(long elapsedRealtimeMs)7952 public void noteVideoTurnedOffLocked(long elapsedRealtimeMs) { 7953 if (mVideoTurnedOnTimer != null) { 7954 mVideoTurnedOnTimer.stopRunningLocked(elapsedRealtimeMs); 7955 } 7956 } 7957 noteResetVideoLocked(long elapsedRealtimeMs)7958 public void noteResetVideoLocked(long elapsedRealtimeMs) { 7959 if (mVideoTurnedOnTimer != null) { 7960 mVideoTurnedOnTimer.stopAllRunningLocked(elapsedRealtimeMs); 7961 } 7962 } 7963 createFlashlightTurnedOnTimerLocked()7964 public StopwatchTimer createFlashlightTurnedOnTimerLocked() { 7965 if (mFlashlightTurnedOnTimer == null) { 7966 mFlashlightTurnedOnTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, 7967 FLASHLIGHT_TURNED_ON, mBsi.mFlashlightTurnedOnTimers, mBsi.mOnBatteryTimeBase); 7968 } 7969 return mFlashlightTurnedOnTimer; 7970 } 7971 noteFlashlightTurnedOnLocked(long elapsedRealtimeMs)7972 public void noteFlashlightTurnedOnLocked(long elapsedRealtimeMs) { 7973 createFlashlightTurnedOnTimerLocked().startRunningLocked(elapsedRealtimeMs); 7974 } 7975 noteFlashlightTurnedOffLocked(long elapsedRealtimeMs)7976 public void noteFlashlightTurnedOffLocked(long elapsedRealtimeMs) { 7977 if (mFlashlightTurnedOnTimer != null) { 7978 mFlashlightTurnedOnTimer.stopRunningLocked(elapsedRealtimeMs); 7979 } 7980 } 7981 noteResetFlashlightLocked(long elapsedRealtimeMs)7982 public void noteResetFlashlightLocked(long elapsedRealtimeMs) { 7983 if (mFlashlightTurnedOnTimer != null) { 7984 mFlashlightTurnedOnTimer.stopAllRunningLocked(elapsedRealtimeMs); 7985 } 7986 } 7987 createCameraTurnedOnTimerLocked()7988 public StopwatchTimer createCameraTurnedOnTimerLocked() { 7989 if (mCameraTurnedOnTimer == null) { 7990 mCameraTurnedOnTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, CAMERA_TURNED_ON, 7991 mBsi.mCameraTurnedOnTimers, mBsi.mOnBatteryTimeBase); 7992 } 7993 return mCameraTurnedOnTimer; 7994 } 7995 noteCameraTurnedOnLocked(long elapsedRealtimeMs)7996 public void noteCameraTurnedOnLocked(long elapsedRealtimeMs) { 7997 createCameraTurnedOnTimerLocked().startRunningLocked(elapsedRealtimeMs); 7998 } 7999 noteCameraTurnedOffLocked(long elapsedRealtimeMs)8000 public void noteCameraTurnedOffLocked(long elapsedRealtimeMs) { 8001 if (mCameraTurnedOnTimer != null) { 8002 mCameraTurnedOnTimer.stopRunningLocked(elapsedRealtimeMs); 8003 } 8004 } 8005 noteResetCameraLocked(long elapsedRealtimeMs)8006 public void noteResetCameraLocked(long elapsedRealtimeMs) { 8007 if (mCameraTurnedOnTimer != null) { 8008 mCameraTurnedOnTimer.stopAllRunningLocked(elapsedRealtimeMs); 8009 } 8010 } 8011 createForegroundActivityTimerLocked()8012 public StopwatchTimer createForegroundActivityTimerLocked() { 8013 if (mForegroundActivityTimer == null) { 8014 mForegroundActivityTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, 8015 FOREGROUND_ACTIVITY, null, mBsi.mOnBatteryTimeBase); 8016 } 8017 return mForegroundActivityTimer; 8018 } 8019 createForegroundServiceTimerLocked()8020 public StopwatchTimer createForegroundServiceTimerLocked() { 8021 if (mForegroundServiceTimer == null) { 8022 mForegroundServiceTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, 8023 FOREGROUND_SERVICE, null, mBsi.mOnBatteryTimeBase); 8024 } 8025 return mForegroundServiceTimer; 8026 } 8027 createAggregatedPartialWakelockTimerLocked()8028 public DualTimer createAggregatedPartialWakelockTimerLocked() { 8029 if (mAggregatedPartialWakelockTimer == null) { 8030 mAggregatedPartialWakelockTimer = new DualTimer(mBsi.mClocks, this, 8031 AGGREGATED_WAKE_TYPE_PARTIAL, null, 8032 mBsi.mOnBatteryScreenOffTimeBase, mOnBatteryScreenOffBackgroundTimeBase); 8033 } 8034 return mAggregatedPartialWakelockTimer; 8035 } 8036 createBluetoothScanTimerLocked()8037 public DualTimer createBluetoothScanTimerLocked() { 8038 if (mBluetoothScanTimer == null) { 8039 mBluetoothScanTimer = new DualTimer(mBsi.mClocks, Uid.this, BLUETOOTH_SCAN_ON, 8040 mBsi.mBluetoothScanOnTimers, mBsi.mOnBatteryTimeBase, 8041 mOnBatteryBackgroundTimeBase); 8042 } 8043 return mBluetoothScanTimer; 8044 } 8045 createBluetoothUnoptimizedScanTimerLocked()8046 public DualTimer createBluetoothUnoptimizedScanTimerLocked() { 8047 if (mBluetoothUnoptimizedScanTimer == null) { 8048 mBluetoothUnoptimizedScanTimer = new DualTimer(mBsi.mClocks, Uid.this, 8049 BLUETOOTH_UNOPTIMIZED_SCAN_ON, null, 8050 mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase); 8051 } 8052 return mBluetoothUnoptimizedScanTimer; 8053 } 8054 noteBluetoothScanStartedLocked(long elapsedRealtimeMs, boolean isUnoptimized)8055 public void noteBluetoothScanStartedLocked(long elapsedRealtimeMs, 8056 boolean isUnoptimized) { 8057 createBluetoothScanTimerLocked().startRunningLocked(elapsedRealtimeMs); 8058 if (isUnoptimized) { 8059 createBluetoothUnoptimizedScanTimerLocked().startRunningLocked(elapsedRealtimeMs); 8060 } 8061 } 8062 noteBluetoothScanStoppedLocked(long elapsedRealtimeMs, boolean isUnoptimized)8063 public void noteBluetoothScanStoppedLocked(long elapsedRealtimeMs, boolean isUnoptimized) { 8064 if (mBluetoothScanTimer != null) { 8065 mBluetoothScanTimer.stopRunningLocked(elapsedRealtimeMs); 8066 } 8067 if (isUnoptimized && mBluetoothUnoptimizedScanTimer != null) { 8068 mBluetoothUnoptimizedScanTimer.stopRunningLocked(elapsedRealtimeMs); 8069 } 8070 } 8071 noteResetBluetoothScanLocked(long elapsedRealtimeMs)8072 public void noteResetBluetoothScanLocked(long elapsedRealtimeMs) { 8073 if (mBluetoothScanTimer != null) { 8074 mBluetoothScanTimer.stopAllRunningLocked(elapsedRealtimeMs); 8075 } 8076 if (mBluetoothUnoptimizedScanTimer != null) { 8077 mBluetoothUnoptimizedScanTimer.stopAllRunningLocked(elapsedRealtimeMs); 8078 } 8079 } 8080 createBluetoothScanResultCounterLocked()8081 public Counter createBluetoothScanResultCounterLocked() { 8082 if (mBluetoothScanResultCounter == null) { 8083 mBluetoothScanResultCounter = new Counter(mBsi.mOnBatteryTimeBase); 8084 } 8085 return mBluetoothScanResultCounter; 8086 } 8087 createBluetoothScanResultBgCounterLocked()8088 public Counter createBluetoothScanResultBgCounterLocked() { 8089 if (mBluetoothScanResultBgCounter == null) { 8090 mBluetoothScanResultBgCounter = new Counter(mOnBatteryBackgroundTimeBase); 8091 } 8092 return mBluetoothScanResultBgCounter; 8093 } 8094 noteBluetoothScanResultsLocked(int numNewResults)8095 public void noteBluetoothScanResultsLocked(int numNewResults) { 8096 createBluetoothScanResultCounterLocked().addAtomic(numNewResults); 8097 // Uses background timebase, so the count will only be incremented if uid in background. 8098 createBluetoothScanResultBgCounterLocked().addAtomic(numNewResults); 8099 } 8100 8101 @Override noteActivityResumedLocked(long elapsedRealtimeMs)8102 public void noteActivityResumedLocked(long elapsedRealtimeMs) { 8103 // We always start, since we want multiple foreground PIDs to nest 8104 createForegroundActivityTimerLocked().startRunningLocked(elapsedRealtimeMs); 8105 } 8106 8107 @Override noteActivityPausedLocked(long elapsedRealtimeMs)8108 public void noteActivityPausedLocked(long elapsedRealtimeMs) { 8109 if (mForegroundActivityTimer != null) { 8110 mForegroundActivityTimer.stopRunningLocked(elapsedRealtimeMs); 8111 } 8112 } 8113 noteForegroundServiceResumedLocked(long elapsedRealtimeMs)8114 public void noteForegroundServiceResumedLocked(long elapsedRealtimeMs) { 8115 createForegroundServiceTimerLocked().startRunningLocked(elapsedRealtimeMs); 8116 } 8117 noteForegroundServicePausedLocked(long elapsedRealtimeMs)8118 public void noteForegroundServicePausedLocked(long elapsedRealtimeMs) { 8119 if (mForegroundServiceTimer != null) { 8120 mForegroundServiceTimer.stopRunningLocked(elapsedRealtimeMs); 8121 } 8122 } 8123 createVibratorOnTimerLocked()8124 public BatchTimer createVibratorOnTimerLocked() { 8125 if (mVibratorOnTimer == null) { 8126 mVibratorOnTimer = new BatchTimer(mBsi.mClocks, Uid.this, VIBRATOR_ON, 8127 mBsi.mOnBatteryTimeBase); 8128 } 8129 return mVibratorOnTimer; 8130 } 8131 noteVibratorOnLocked(long durationMillis, long elapsedRealtimeMs)8132 public void noteVibratorOnLocked(long durationMillis, long elapsedRealtimeMs) { 8133 createVibratorOnTimerLocked().addDuration(mBsi, durationMillis, elapsedRealtimeMs); 8134 } 8135 noteVibratorOffLocked(long elapsedRealtimeMs)8136 public void noteVibratorOffLocked(long elapsedRealtimeMs) { 8137 if (mVibratorOnTimer != null) { 8138 mVibratorOnTimer.abortLastDuration(mBsi, elapsedRealtimeMs); 8139 } 8140 } 8141 8142 @Override 8143 @UnsupportedAppUsage getWifiRunningTime(long elapsedRealtimeUs, int which)8144 public long getWifiRunningTime(long elapsedRealtimeUs, int which) { 8145 if (mWifiRunningTimer == null) { 8146 return 0; 8147 } 8148 return mWifiRunningTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 8149 } 8150 8151 @Override getFullWifiLockTime(long elapsedRealtimeUs, int which)8152 public long getFullWifiLockTime(long elapsedRealtimeUs, int which) { 8153 if (mFullWifiLockTimer == null) { 8154 return 0; 8155 } 8156 return mFullWifiLockTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 8157 } 8158 8159 @Override 8160 @UnsupportedAppUsage getWifiScanTime(long elapsedRealtimeUs, int which)8161 public long getWifiScanTime(long elapsedRealtimeUs, int which) { 8162 if (mWifiScanTimer == null) { 8163 return 0; 8164 } 8165 return mWifiScanTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 8166 } 8167 8168 @Override getWifiScanCount(int which)8169 public int getWifiScanCount(int which) { 8170 if (mWifiScanTimer == null) { 8171 return 0; 8172 } 8173 return mWifiScanTimer.getCountLocked(which); 8174 } 8175 8176 @Override getWifiScanTimer()8177 public Timer getWifiScanTimer() { 8178 return mWifiScanTimer; 8179 } 8180 8181 @Override getWifiScanBackgroundCount(int which)8182 public int getWifiScanBackgroundCount(int which) { 8183 if (mWifiScanTimer == null || mWifiScanTimer.getSubTimer() == null) { 8184 return 0; 8185 } 8186 return mWifiScanTimer.getSubTimer().getCountLocked(which); 8187 } 8188 8189 @Override getWifiScanActualTime(final long elapsedRealtimeUs)8190 public long getWifiScanActualTime(final long elapsedRealtimeUs) { 8191 if (mWifiScanTimer == null) { 8192 return 0; 8193 } 8194 final long elapsedRealtimeMs = (elapsedRealtimeUs + 500) / 1000; 8195 return mWifiScanTimer.getTotalDurationMsLocked(elapsedRealtimeMs) * 1000; 8196 } 8197 8198 @Override getWifiScanBackgroundTime(final long elapsedRealtimeUs)8199 public long getWifiScanBackgroundTime(final long elapsedRealtimeUs) { 8200 if (mWifiScanTimer == null || mWifiScanTimer.getSubTimer() == null) { 8201 return 0; 8202 } 8203 final long elapsedRealtimeMs = (elapsedRealtimeUs + 500) / 1000; 8204 return mWifiScanTimer.getSubTimer().getTotalDurationMsLocked(elapsedRealtimeMs) * 1000; 8205 } 8206 8207 @Override getWifiScanBackgroundTimer()8208 public Timer getWifiScanBackgroundTimer() { 8209 if (mWifiScanTimer == null) { 8210 return null; 8211 } 8212 return mWifiScanTimer.getSubTimer(); 8213 } 8214 8215 @Override getWifiBatchedScanTime(int csphBin, long elapsedRealtimeUs, int which)8216 public long getWifiBatchedScanTime(int csphBin, long elapsedRealtimeUs, int which) { 8217 if (csphBin < 0 || csphBin >= NUM_WIFI_BATCHED_SCAN_BINS) return 0; 8218 if (mWifiBatchedScanTimer[csphBin] == null) { 8219 return 0; 8220 } 8221 return mWifiBatchedScanTimer[csphBin].getTotalTimeLocked(elapsedRealtimeUs, which); 8222 } 8223 8224 @Override getWifiBatchedScanCount(int csphBin, int which)8225 public int getWifiBatchedScanCount(int csphBin, int which) { 8226 if (csphBin < 0 || csphBin >= NUM_WIFI_BATCHED_SCAN_BINS) return 0; 8227 if (mWifiBatchedScanTimer[csphBin] == null) { 8228 return 0; 8229 } 8230 return mWifiBatchedScanTimer[csphBin].getCountLocked(which); 8231 } 8232 8233 @Override getWifiMulticastTime(long elapsedRealtimeUs, int which)8234 public long getWifiMulticastTime(long elapsedRealtimeUs, int which) { 8235 if (mWifiMulticastTimer == null) { 8236 return 0; 8237 } 8238 return mWifiMulticastTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 8239 } 8240 8241 @Override getAudioTurnedOnTimer()8242 public Timer getAudioTurnedOnTimer() { 8243 return mAudioTurnedOnTimer; 8244 } 8245 8246 @Override getVideoTurnedOnTimer()8247 public Timer getVideoTurnedOnTimer() { 8248 return mVideoTurnedOnTimer; 8249 } 8250 8251 @Override getFlashlightTurnedOnTimer()8252 public Timer getFlashlightTurnedOnTimer() { 8253 return mFlashlightTurnedOnTimer; 8254 } 8255 8256 @Override getCameraTurnedOnTimer()8257 public Timer getCameraTurnedOnTimer() { 8258 return mCameraTurnedOnTimer; 8259 } 8260 8261 @Override getForegroundActivityTimer()8262 public Timer getForegroundActivityTimer() { 8263 return mForegroundActivityTimer; 8264 } 8265 8266 @Override getForegroundServiceTimer()8267 public Timer getForegroundServiceTimer() { 8268 return mForegroundServiceTimer; 8269 } 8270 8271 @Override getBluetoothScanTimer()8272 public Timer getBluetoothScanTimer() { 8273 return mBluetoothScanTimer; 8274 } 8275 8276 @Override getBluetoothScanBackgroundTimer()8277 public Timer getBluetoothScanBackgroundTimer() { 8278 if (mBluetoothScanTimer == null) { 8279 return null; 8280 } 8281 return mBluetoothScanTimer.getSubTimer(); 8282 } 8283 8284 @Override getBluetoothUnoptimizedScanTimer()8285 public Timer getBluetoothUnoptimizedScanTimer() { 8286 return mBluetoothUnoptimizedScanTimer; 8287 } 8288 8289 @Override getBluetoothUnoptimizedScanBackgroundTimer()8290 public Timer getBluetoothUnoptimizedScanBackgroundTimer() { 8291 if (mBluetoothUnoptimizedScanTimer == null) { 8292 return null; 8293 } 8294 return mBluetoothUnoptimizedScanTimer.getSubTimer(); 8295 } 8296 8297 @Override getBluetoothScanResultCounter()8298 public Counter getBluetoothScanResultCounter() { 8299 return mBluetoothScanResultCounter; 8300 } 8301 8302 @Override getBluetoothScanResultBgCounter()8303 public Counter getBluetoothScanResultBgCounter() { 8304 return mBluetoothScanResultBgCounter; 8305 } 8306 makeProcessState(int i, Parcel in)8307 void makeProcessState(int i, Parcel in) { 8308 if (i < 0 || i >= NUM_PROCESS_STATE) return; 8309 8310 detachIfNotNull(mProcessStateTimer[i]); 8311 if (in == null) { 8312 mProcessStateTimer[i] = new StopwatchTimer(mBsi.mClocks, this, PROCESS_STATE, null, 8313 mBsi.mOnBatteryTimeBase); 8314 } else { 8315 mProcessStateTimer[i] = new StopwatchTimer(mBsi.mClocks, this, PROCESS_STATE, null, 8316 mBsi.mOnBatteryTimeBase, in); 8317 } 8318 } 8319 8320 @Override getProcessStateTime(int state, long elapsedRealtimeUs, int which)8321 public long getProcessStateTime(int state, long elapsedRealtimeUs, int which) { 8322 if (state < 0 || state >= NUM_PROCESS_STATE) return 0; 8323 if (mProcessStateTimer[state] == null) { 8324 return 0; 8325 } 8326 return mProcessStateTimer[state].getTotalTimeLocked(elapsedRealtimeUs, which); 8327 } 8328 8329 @Override getProcessStateTimer(int state)8330 public Timer getProcessStateTimer(int state) { 8331 if (state < 0 || state >= NUM_PROCESS_STATE) return null; 8332 return mProcessStateTimer[state]; 8333 } 8334 8335 @Override getVibratorOnTimer()8336 public Timer getVibratorOnTimer() { 8337 return mVibratorOnTimer; 8338 } 8339 8340 @Override noteUserActivityLocked(int type)8341 public void noteUserActivityLocked(int type) { 8342 if (mUserActivityCounters == null) { 8343 initUserActivityLocked(); 8344 } 8345 if (type >= 0 && type < NUM_USER_ACTIVITY_TYPES) { 8346 mUserActivityCounters[type].stepAtomic(); 8347 } else { 8348 Slog.w(TAG, "Unknown user activity type " + type + " was specified.", 8349 new Throwable()); 8350 } 8351 } 8352 8353 @Override hasUserActivity()8354 public boolean hasUserActivity() { 8355 return mUserActivityCounters != null; 8356 } 8357 8358 @Override getUserActivityCount(int type, int which)8359 public int getUserActivityCount(int type, int which) { 8360 if (mUserActivityCounters == null) { 8361 return 0; 8362 } 8363 return mUserActivityCounters[type].getCountLocked(which); 8364 } 8365 makeWifiBatchedScanBin(int i, Parcel in)8366 void makeWifiBatchedScanBin(int i, Parcel in) { 8367 if (i < 0 || i >= NUM_WIFI_BATCHED_SCAN_BINS) return; 8368 8369 ArrayList<StopwatchTimer> collected = mBsi.mWifiBatchedScanTimers.get(i); 8370 if (collected == null) { 8371 collected = new ArrayList<StopwatchTimer>(); 8372 mBsi.mWifiBatchedScanTimers.put(i, collected); 8373 } 8374 detachIfNotNull(mWifiBatchedScanTimer[i]); 8375 if (in == null) { 8376 mWifiBatchedScanTimer[i] = new StopwatchTimer(mBsi.mClocks, this, WIFI_BATCHED_SCAN, 8377 collected, mBsi.mOnBatteryTimeBase); 8378 } else { 8379 mWifiBatchedScanTimer[i] = new StopwatchTimer(mBsi.mClocks, this, WIFI_BATCHED_SCAN, 8380 collected, mBsi.mOnBatteryTimeBase, in); 8381 } 8382 } 8383 8384 initUserActivityLocked()8385 void initUserActivityLocked() { 8386 detachIfNotNull(mUserActivityCounters); 8387 mUserActivityCounters = new Counter[NUM_USER_ACTIVITY_TYPES]; 8388 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) { 8389 mUserActivityCounters[i] = new Counter(mBsi.mOnBatteryTimeBase); 8390 } 8391 } 8392 noteNetworkActivityLocked(int type, long deltaBytes, long deltaPackets)8393 void noteNetworkActivityLocked(int type, long deltaBytes, long deltaPackets) { 8394 if (mNetworkByteActivityCounters == null) { 8395 initNetworkActivityLocked(); 8396 } 8397 if (type >= 0 && type < NUM_NETWORK_ACTIVITY_TYPES) { 8398 mNetworkByteActivityCounters[type].addCountLocked(deltaBytes); 8399 mNetworkPacketActivityCounters[type].addCountLocked(deltaPackets); 8400 } else { 8401 Slog.w(TAG, "Unknown network activity type " + type + " was specified.", 8402 new Throwable()); 8403 } 8404 } 8405 noteMobileRadioActiveTimeLocked(long batteryUptime)8406 void noteMobileRadioActiveTimeLocked(long batteryUptime) { 8407 if (mNetworkByteActivityCounters == null) { 8408 initNetworkActivityLocked(); 8409 } 8410 mMobileRadioActiveTime.addCountLocked(batteryUptime); 8411 mMobileRadioActiveCount.addCountLocked(1); 8412 } 8413 8414 @Override hasNetworkActivity()8415 public boolean hasNetworkActivity() { 8416 return mNetworkByteActivityCounters != null; 8417 } 8418 8419 @Override getNetworkActivityBytes(int type, int which)8420 public long getNetworkActivityBytes(int type, int which) { 8421 if (mNetworkByteActivityCounters != null && type >= 0 8422 && type < mNetworkByteActivityCounters.length) { 8423 return mNetworkByteActivityCounters[type].getCountLocked(which); 8424 } else { 8425 return 0; 8426 } 8427 } 8428 8429 @Override getNetworkActivityPackets(int type, int which)8430 public long getNetworkActivityPackets(int type, int which) { 8431 if (mNetworkPacketActivityCounters != null && type >= 0 8432 && type < mNetworkPacketActivityCounters.length) { 8433 return mNetworkPacketActivityCounters[type].getCountLocked(which); 8434 } else { 8435 return 0; 8436 } 8437 } 8438 8439 @Override getMobileRadioActiveTime(int which)8440 public long getMobileRadioActiveTime(int which) { 8441 return mMobileRadioActiveTime != null 8442 ? mMobileRadioActiveTime.getCountLocked(which) : 0; 8443 } 8444 8445 @Override getMobileRadioActiveCount(int which)8446 public int getMobileRadioActiveCount(int which) { 8447 return mMobileRadioActiveCount != null 8448 ? (int)mMobileRadioActiveCount.getCountLocked(which) : 0; 8449 } 8450 8451 @Override getUserCpuTimeUs(int which)8452 public long getUserCpuTimeUs(int which) { 8453 return mUserCpuTime.getCountLocked(which); 8454 } 8455 8456 @Override getSystemCpuTimeUs(int which)8457 public long getSystemCpuTimeUs(int which) { 8458 return mSystemCpuTime.getCountLocked(which); 8459 } 8460 8461 @Override getTimeAtCpuSpeed(int cluster, int step, int which)8462 public long getTimeAtCpuSpeed(int cluster, int step, int which) { 8463 if (mCpuClusterSpeedTimesUs != null) { 8464 if (cluster >= 0 && cluster < mCpuClusterSpeedTimesUs.length) { 8465 final LongSamplingCounter[] cpuSpeedTimesUs = mCpuClusterSpeedTimesUs[cluster]; 8466 if (cpuSpeedTimesUs != null) { 8467 if (step >= 0 && step < cpuSpeedTimesUs.length) { 8468 final LongSamplingCounter c = cpuSpeedTimesUs[step]; 8469 if (c != null) { 8470 return c.getCountLocked(which); 8471 } 8472 } 8473 } 8474 } 8475 } 8476 return 0; 8477 } 8478 noteMobileRadioApWakeupLocked()8479 public void noteMobileRadioApWakeupLocked() { 8480 if (mMobileRadioApWakeupCount == null) { 8481 mMobileRadioApWakeupCount = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); 8482 } 8483 mMobileRadioApWakeupCount.addCountLocked(1); 8484 } 8485 8486 @Override getMobileRadioApWakeupCount(int which)8487 public long getMobileRadioApWakeupCount(int which) { 8488 if (mMobileRadioApWakeupCount != null) { 8489 return mMobileRadioApWakeupCount.getCountLocked(which); 8490 } 8491 return 0; 8492 } 8493 noteWifiRadioApWakeupLocked()8494 public void noteWifiRadioApWakeupLocked() { 8495 if (mWifiRadioApWakeupCount == null) { 8496 mWifiRadioApWakeupCount = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); 8497 } 8498 mWifiRadioApWakeupCount.addCountLocked(1); 8499 } 8500 8501 @Override getWifiRadioApWakeupCount(int which)8502 public long getWifiRadioApWakeupCount(int which) { 8503 if (mWifiRadioApWakeupCount != null) { 8504 return mWifiRadioApWakeupCount.getCountLocked(which); 8505 } 8506 return 0; 8507 } 8508 8509 @Override getDeferredJobsCheckinLineLocked(StringBuilder sb, int which)8510 public void getDeferredJobsCheckinLineLocked(StringBuilder sb, int which) { 8511 sb.setLength(0); 8512 final int deferredEventCount = mJobsDeferredEventCount.getCountLocked(which); 8513 if (deferredEventCount == 0) { 8514 return; 8515 } 8516 final int deferredCount = mJobsDeferredCount.getCountLocked(which); 8517 final long totalLatency = mJobsFreshnessTimeMs.getCountLocked(which); 8518 sb.append(deferredEventCount); sb.append(','); 8519 sb.append(deferredCount); sb.append(','); 8520 sb.append(totalLatency); 8521 for (int i = 0; i < JOB_FRESHNESS_BUCKETS.length; i++) { 8522 if (mJobsFreshnessBuckets[i] == null) { 8523 sb.append(",0"); 8524 } else { 8525 sb.append(","); 8526 sb.append(mJobsFreshnessBuckets[i].getCountLocked(which)); 8527 } 8528 } 8529 } 8530 8531 @Override getDeferredJobsLineLocked(StringBuilder sb, int which)8532 public void getDeferredJobsLineLocked(StringBuilder sb, int which) { 8533 sb.setLength(0); 8534 final int deferredEventCount = mJobsDeferredEventCount.getCountLocked(which); 8535 if (deferredEventCount == 0) { 8536 return; 8537 } 8538 final int deferredCount = mJobsDeferredCount.getCountLocked(which); 8539 final long totalLatency = mJobsFreshnessTimeMs.getCountLocked(which); 8540 sb.append("times="); sb.append(deferredEventCount); sb.append(", "); 8541 sb.append("count="); sb.append(deferredCount); sb.append(", "); 8542 sb.append("totalLatencyMs="); sb.append(totalLatency); sb.append(", "); 8543 for (int i = 0; i < JOB_FRESHNESS_BUCKETS.length; i++) { 8544 sb.append("<"); sb.append(JOB_FRESHNESS_BUCKETS[i]); sb.append("ms="); 8545 if (mJobsFreshnessBuckets[i] == null) { 8546 sb.append("0"); 8547 } else { 8548 sb.append(mJobsFreshnessBuckets[i].getCountLocked(which)); 8549 } 8550 sb.append(" "); 8551 } 8552 } 8553 initNetworkActivityLocked()8554 void initNetworkActivityLocked() { 8555 detachIfNotNull(mNetworkByteActivityCounters); 8556 mNetworkByteActivityCounters = new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES]; 8557 detachIfNotNull(mNetworkPacketActivityCounters); 8558 mNetworkPacketActivityCounters = new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES]; 8559 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 8560 mNetworkByteActivityCounters[i] = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); 8561 mNetworkPacketActivityCounters[i] = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); 8562 } 8563 detachIfNotNull(mMobileRadioActiveTime); 8564 mMobileRadioActiveTime = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); 8565 detachIfNotNull(mMobileRadioActiveCount); 8566 mMobileRadioActiveCount = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); 8567 } 8568 8569 /** 8570 * Clear all stats for this uid. Returns true if the uid is completely 8571 * inactive so can be dropped. 8572 */ 8573 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) reset(long uptimeUs, long realtimeUs)8574 public boolean reset(long uptimeUs, long realtimeUs) { 8575 boolean active = false; 8576 8577 mOnBatteryBackgroundTimeBase.init(uptimeUs, realtimeUs); 8578 mOnBatteryScreenOffBackgroundTimeBase.init(uptimeUs, realtimeUs); 8579 8580 if (mWifiRunningTimer != null) { 8581 active |= !mWifiRunningTimer.reset(false, realtimeUs); 8582 active |= mWifiRunning; 8583 } 8584 if (mFullWifiLockTimer != null) { 8585 active |= !mFullWifiLockTimer.reset(false, realtimeUs); 8586 active |= mFullWifiLockOut; 8587 } 8588 if (mWifiScanTimer != null) { 8589 active |= !mWifiScanTimer.reset(false, realtimeUs); 8590 active |= mWifiScanStarted; 8591 } 8592 if (mWifiBatchedScanTimer != null) { 8593 for (int i = 0; i < NUM_WIFI_BATCHED_SCAN_BINS; i++) { 8594 if (mWifiBatchedScanTimer[i] != null) { 8595 active |= !mWifiBatchedScanTimer[i].reset(false, realtimeUs); 8596 } 8597 } 8598 active |= (mWifiBatchedScanBinStarted != NO_BATCHED_SCAN_STARTED); 8599 } 8600 if (mWifiMulticastTimer != null) { 8601 active |= !mWifiMulticastTimer.reset(false, realtimeUs); 8602 active |= (mWifiMulticastWakelockCount > 0); 8603 } 8604 8605 active |= !resetIfNotNull(mAudioTurnedOnTimer, false, realtimeUs); 8606 active |= !resetIfNotNull(mVideoTurnedOnTimer, false, realtimeUs); 8607 active |= !resetIfNotNull(mFlashlightTurnedOnTimer, false, realtimeUs); 8608 active |= !resetIfNotNull(mCameraTurnedOnTimer, false, realtimeUs); 8609 active |= !resetIfNotNull(mForegroundActivityTimer, false, realtimeUs); 8610 active |= !resetIfNotNull(mForegroundServiceTimer, false, realtimeUs); 8611 active |= !resetIfNotNull(mAggregatedPartialWakelockTimer, false, realtimeUs); 8612 active |= !resetIfNotNull(mBluetoothScanTimer, false, realtimeUs); 8613 active |= !resetIfNotNull(mBluetoothUnoptimizedScanTimer, false, realtimeUs); 8614 8615 resetIfNotNull(mBluetoothScanResultCounter, false, realtimeUs); 8616 resetIfNotNull(mBluetoothScanResultBgCounter, false, realtimeUs); 8617 8618 if (mProcessStateTimer != null) { 8619 for (int i = 0; i < NUM_PROCESS_STATE; i++) { 8620 active |= !resetIfNotNull(mProcessStateTimer[i], false, realtimeUs); 8621 } 8622 active |= (mProcessState != ActivityManager.PROCESS_STATE_NONEXISTENT); 8623 } 8624 if (mVibratorOnTimer != null) { 8625 if (mVibratorOnTimer.reset(false, realtimeUs)) { 8626 mVibratorOnTimer.detach(); 8627 mVibratorOnTimer = null; 8628 } else { 8629 active = true; 8630 } 8631 } 8632 8633 resetIfNotNull(mUserActivityCounters, false, realtimeUs); 8634 8635 resetIfNotNull(mNetworkByteActivityCounters, false, realtimeUs); 8636 resetIfNotNull(mNetworkPacketActivityCounters, false, realtimeUs); 8637 resetIfNotNull(mMobileRadioActiveTime, false, realtimeUs); 8638 resetIfNotNull(mMobileRadioActiveCount, false, realtimeUs); 8639 8640 resetIfNotNull(mWifiControllerActivity, false, realtimeUs); 8641 resetIfNotNull(mBluetoothControllerActivity, false, realtimeUs); 8642 resetIfNotNull(mModemControllerActivity, false, realtimeUs); 8643 8644 MeasuredEnergyStats.resetIfNotNull(mUidMeasuredEnergyStats); 8645 8646 resetIfNotNull(mUserCpuTime, false, realtimeUs); 8647 resetIfNotNull(mSystemCpuTime, false, realtimeUs); 8648 8649 resetIfNotNull(mCpuClusterSpeedTimesUs, false, realtimeUs); 8650 8651 resetIfNotNull(mCpuFreqTimeMs, false, realtimeUs /* unused */); 8652 resetIfNotNull(mScreenOffCpuFreqTimeMs, false, realtimeUs /* unused */); 8653 8654 8655 resetIfNotNull(mCpuActiveTimeMs, false, realtimeUs /* unused */); 8656 resetIfNotNull(mCpuClusterTimesMs, false, realtimeUs /* unused */); 8657 8658 resetIfNotNull(mProcStateTimeMs, false, realtimeUs /* unused */); 8659 8660 resetIfNotNull(mProcStateScreenOffTimeMs, false, realtimeUs /* unused */); 8661 8662 resetIfNotNull(mMobileRadioApWakeupCount, false, realtimeUs); 8663 8664 resetIfNotNull(mWifiRadioApWakeupCount, false, realtimeUs); 8665 8666 8667 final ArrayMap<String, Wakelock> wakeStats = mWakelockStats.getMap(); 8668 for (int iw=wakeStats.size()-1; iw>=0; iw--) { 8669 Wakelock wl = wakeStats.valueAt(iw); 8670 if (wl.reset(realtimeUs)) { 8671 wakeStats.removeAt(iw); 8672 } else { 8673 active = true; 8674 } 8675 } 8676 final long realtimeMs = realtimeUs / 1000; 8677 mWakelockStats.cleanup(realtimeMs); 8678 final ArrayMap<String, DualTimer> syncStats = mSyncStats.getMap(); 8679 for (int is=syncStats.size()-1; is>=0; is--) { 8680 DualTimer timer = syncStats.valueAt(is); 8681 if (timer.reset(false, realtimeUs)) { 8682 syncStats.removeAt(is); 8683 timer.detach(); 8684 } else { 8685 active = true; 8686 } 8687 } 8688 mSyncStats.cleanup(realtimeMs); 8689 final ArrayMap<String, DualTimer> jobStats = mJobStats.getMap(); 8690 for (int ij=jobStats.size()-1; ij>=0; ij--) { 8691 DualTimer timer = jobStats.valueAt(ij); 8692 if (timer.reset(false, realtimeUs)) { 8693 jobStats.removeAt(ij); 8694 timer.detach(); 8695 } else { 8696 active = true; 8697 } 8698 } 8699 mJobStats.cleanup(realtimeMs); 8700 mJobCompletions.clear(); 8701 8702 resetIfNotNull(mJobsDeferredEventCount, false, realtimeUs); 8703 resetIfNotNull(mJobsDeferredCount, false, realtimeUs); 8704 resetIfNotNull(mJobsFreshnessTimeMs, false, realtimeUs /* unused */); 8705 resetIfNotNull(mJobsFreshnessBuckets, false, realtimeUs); 8706 8707 for (int ise = mSensorStats.size() - 1; ise >= 0; ise--) { 8708 Sensor s = mSensorStats.valueAt(ise); 8709 if (s.reset(realtimeUs)) { 8710 mSensorStats.removeAt(ise); 8711 } else { 8712 active = true; 8713 } 8714 } 8715 8716 for (int ip = mProcessStats.size() - 1; ip >= 0; ip--) { 8717 Proc proc = mProcessStats.valueAt(ip); 8718 proc.detach(); 8719 } 8720 mProcessStats.clear(); 8721 8722 for (int i = mPids.size() - 1; i >= 0; i--) { 8723 Pid pid = mPids.valueAt(i); 8724 if (pid.mWakeNesting > 0) { 8725 active = true; 8726 } else { 8727 mPids.removeAt(i); 8728 } 8729 } 8730 8731 8732 for(int i = mPackageStats.size() - 1; i >= 0; i--) { 8733 Pkg p = mPackageStats.valueAt(i); 8734 p.detach(); 8735 } 8736 mPackageStats.clear(); 8737 8738 mBinderCallCount = 0; 8739 mBinderCallStats.clear(); 8740 8741 mProportionalSystemServiceUsage = 0; 8742 8743 mLastStepUserTimeMs = mLastStepSystemTimeMs = 0; 8744 mCurStepUserTimeMs = mCurStepSystemTimeMs = 0; 8745 8746 8747 return !active; 8748 } 8749 8750 /** 8751 * This method MUST be called whenever the Uid object is destructed, otherwise it is a 8752 * memory leak in {@link TimeBase#mObservers} list. 8753 * Typically the Uid object is destructed when it is removed from 8754 * {@link BatteryStatsImpl#mUidStats} 8755 */ detachFromTimeBase()8756 void detachFromTimeBase() { 8757 detachIfNotNull(mWifiRunningTimer); 8758 detachIfNotNull(mFullWifiLockTimer); 8759 detachIfNotNull(mWifiScanTimer); 8760 detachIfNotNull(mWifiBatchedScanTimer); 8761 detachIfNotNull(mWifiMulticastTimer); 8762 detachIfNotNull(mAudioTurnedOnTimer); 8763 detachIfNotNull(mVideoTurnedOnTimer); 8764 detachIfNotNull(mFlashlightTurnedOnTimer); 8765 8766 detachIfNotNull(mCameraTurnedOnTimer); 8767 detachIfNotNull(mForegroundActivityTimer); 8768 detachIfNotNull(mForegroundServiceTimer); 8769 8770 detachIfNotNull(mAggregatedPartialWakelockTimer); 8771 8772 detachIfNotNull(mBluetoothScanTimer); 8773 detachIfNotNull(mBluetoothUnoptimizedScanTimer); 8774 detachIfNotNull(mBluetoothScanResultCounter); 8775 detachIfNotNull(mBluetoothScanResultBgCounter); 8776 8777 detachIfNotNull(mProcessStateTimer); 8778 8779 detachIfNotNull(mVibratorOnTimer); 8780 8781 detachIfNotNull(mUserActivityCounters); 8782 8783 detachIfNotNull(mNetworkByteActivityCounters); 8784 detachIfNotNull(mNetworkPacketActivityCounters); 8785 8786 detachIfNotNull(mMobileRadioActiveTime); 8787 detachIfNotNull(mMobileRadioActiveCount); 8788 detachIfNotNull(mMobileRadioApWakeupCount); 8789 detachIfNotNull(mWifiRadioApWakeupCount); 8790 8791 detachIfNotNull(mWifiControllerActivity); 8792 detachIfNotNull(mBluetoothControllerActivity); 8793 detachIfNotNull(mModemControllerActivity); 8794 8795 mPids.clear(); 8796 8797 detachIfNotNull(mUserCpuTime); 8798 detachIfNotNull(mSystemCpuTime); 8799 8800 detachIfNotNull(mCpuClusterSpeedTimesUs); 8801 8802 detachIfNotNull(mCpuActiveTimeMs); 8803 detachIfNotNull(mCpuFreqTimeMs); 8804 8805 detachIfNotNull(mScreenOffCpuFreqTimeMs); 8806 8807 detachIfNotNull(mCpuClusterTimesMs); 8808 8809 detachIfNotNull(mProcStateTimeMs); 8810 8811 detachIfNotNull(mProcStateScreenOffTimeMs); 8812 8813 final ArrayMap<String, Wakelock> wakeStats = mWakelockStats.getMap(); 8814 for (int iw = wakeStats.size() - 1; iw >= 0; iw--) { 8815 Wakelock wl = wakeStats.valueAt(iw); 8816 wl.detachFromTimeBase(); 8817 } 8818 final ArrayMap<String, DualTimer> syncStats = mSyncStats.getMap(); 8819 for (int is = syncStats.size() - 1; is >= 0; is--) { 8820 DualTimer timer = syncStats.valueAt(is); 8821 detachIfNotNull(timer); 8822 } 8823 final ArrayMap<String, DualTimer> jobStats = mJobStats.getMap(); 8824 for (int ij = jobStats.size() - 1; ij >= 0; ij--) { 8825 DualTimer timer = jobStats.valueAt(ij); 8826 detachIfNotNull(timer); 8827 } 8828 8829 detachIfNotNull(mJobsDeferredEventCount); 8830 detachIfNotNull(mJobsDeferredCount); 8831 detachIfNotNull(mJobsFreshnessTimeMs); 8832 detachIfNotNull(mJobsFreshnessBuckets); 8833 8834 8835 for (int ise = mSensorStats.size() - 1; ise >= 0; ise--) { 8836 Sensor s = mSensorStats.valueAt(ise); 8837 s.detachFromTimeBase(); 8838 } 8839 8840 for (int ip= mProcessStats.size() - 1; ip >= 0; ip--) { 8841 Proc proc = mProcessStats.valueAt(ip); 8842 proc.detach(); 8843 } 8844 mProcessStats.clear(); 8845 8846 for(int i = mPackageStats.size() - 1; i >= 0; i--) { 8847 Pkg p = mPackageStats.valueAt(i); 8848 p.detach(); 8849 } 8850 mPackageStats.clear(); 8851 } 8852 writeJobCompletionsToParcelLocked(Parcel out)8853 void writeJobCompletionsToParcelLocked(Parcel out) { 8854 int NJC = mJobCompletions.size(); 8855 out.writeInt(NJC); 8856 for (int ijc=0; ijc<NJC; ijc++) { 8857 out.writeString(mJobCompletions.keyAt(ijc)); 8858 SparseIntArray types = mJobCompletions.valueAt(ijc); 8859 int NT = types.size(); 8860 out.writeInt(NT); 8861 for (int it=0; it<NT; it++) { 8862 out.writeInt(types.keyAt(it)); 8863 out.writeInt(types.valueAt(it)); 8864 } 8865 } 8866 } 8867 writeToParcelLocked(Parcel out, long uptimeUs, long elapsedRealtimeUs)8868 void writeToParcelLocked(Parcel out, long uptimeUs, long elapsedRealtimeUs) { 8869 mOnBatteryBackgroundTimeBase.writeToParcel(out, uptimeUs, elapsedRealtimeUs); 8870 mOnBatteryScreenOffBackgroundTimeBase.writeToParcel(out, uptimeUs, elapsedRealtimeUs); 8871 8872 final ArrayMap<String, Wakelock> wakeStats = mWakelockStats.getMap(); 8873 int NW = wakeStats.size(); 8874 out.writeInt(NW); 8875 for (int iw=0; iw<NW; iw++) { 8876 out.writeString(wakeStats.keyAt(iw)); 8877 Uid.Wakelock wakelock = wakeStats.valueAt(iw); 8878 wakelock.writeToParcelLocked(out, elapsedRealtimeUs); 8879 } 8880 8881 final ArrayMap<String, DualTimer> syncStats = mSyncStats.getMap(); 8882 int NS = syncStats.size(); 8883 out.writeInt(NS); 8884 for (int is=0; is<NS; is++) { 8885 out.writeString(syncStats.keyAt(is)); 8886 DualTimer timer = syncStats.valueAt(is); 8887 Timer.writeTimerToParcel(out, timer, elapsedRealtimeUs); 8888 } 8889 8890 final ArrayMap<String, DualTimer> jobStats = mJobStats.getMap(); 8891 int NJ = jobStats.size(); 8892 out.writeInt(NJ); 8893 for (int ij=0; ij<NJ; ij++) { 8894 out.writeString(jobStats.keyAt(ij)); 8895 DualTimer timer = jobStats.valueAt(ij); 8896 Timer.writeTimerToParcel(out, timer, elapsedRealtimeUs); 8897 } 8898 8899 writeJobCompletionsToParcelLocked(out); 8900 8901 mJobsDeferredEventCount.writeToParcel(out); 8902 mJobsDeferredCount.writeToParcel(out); 8903 mJobsFreshnessTimeMs.writeToParcel(out); 8904 for (int i = 0; i < JOB_FRESHNESS_BUCKETS.length; i++) { 8905 Counter.writeCounterToParcel(out, mJobsFreshnessBuckets[i]); 8906 } 8907 8908 int NSE = mSensorStats.size(); 8909 out.writeInt(NSE); 8910 for (int ise=0; ise<NSE; ise++) { 8911 out.writeInt(mSensorStats.keyAt(ise)); 8912 Uid.Sensor sensor = mSensorStats.valueAt(ise); 8913 sensor.writeToParcelLocked(out, elapsedRealtimeUs); 8914 } 8915 8916 int NP = mProcessStats.size(); 8917 out.writeInt(NP); 8918 for (int ip=0; ip<NP; ip++) { 8919 out.writeString(mProcessStats.keyAt(ip)); 8920 Uid.Proc proc = mProcessStats.valueAt(ip); 8921 proc.writeToParcelLocked(out); 8922 } 8923 8924 out.writeInt(mPackageStats.size()); 8925 for (Map.Entry<String, Uid.Pkg> pkgEntry : mPackageStats.entrySet()) { 8926 out.writeString(pkgEntry.getKey()); 8927 Uid.Pkg pkg = pkgEntry.getValue(); 8928 pkg.writeToParcelLocked(out); 8929 } 8930 8931 if (mWifiRunningTimer != null) { 8932 out.writeInt(1); 8933 mWifiRunningTimer.writeToParcel(out, elapsedRealtimeUs); 8934 } else { 8935 out.writeInt(0); 8936 } 8937 if (mFullWifiLockTimer != null) { 8938 out.writeInt(1); 8939 mFullWifiLockTimer.writeToParcel(out, elapsedRealtimeUs); 8940 } else { 8941 out.writeInt(0); 8942 } 8943 if (mWifiScanTimer != null) { 8944 out.writeInt(1); 8945 mWifiScanTimer.writeToParcel(out, elapsedRealtimeUs); 8946 } else { 8947 out.writeInt(0); 8948 } 8949 for (int i = 0; i < NUM_WIFI_BATCHED_SCAN_BINS; i++) { 8950 if (mWifiBatchedScanTimer[i] != null) { 8951 out.writeInt(1); 8952 mWifiBatchedScanTimer[i].writeToParcel(out, elapsedRealtimeUs); 8953 } else { 8954 out.writeInt(0); 8955 } 8956 } 8957 if (mWifiMulticastTimer != null) { 8958 out.writeInt(1); 8959 mWifiMulticastTimer.writeToParcel(out, elapsedRealtimeUs); 8960 } else { 8961 out.writeInt(0); 8962 } 8963 8964 if (mAudioTurnedOnTimer != null) { 8965 out.writeInt(1); 8966 mAudioTurnedOnTimer.writeToParcel(out, elapsedRealtimeUs); 8967 } else { 8968 out.writeInt(0); 8969 } 8970 if (mVideoTurnedOnTimer != null) { 8971 out.writeInt(1); 8972 mVideoTurnedOnTimer.writeToParcel(out, elapsedRealtimeUs); 8973 } else { 8974 out.writeInt(0); 8975 } 8976 if (mFlashlightTurnedOnTimer != null) { 8977 out.writeInt(1); 8978 mFlashlightTurnedOnTimer.writeToParcel(out, elapsedRealtimeUs); 8979 } else { 8980 out.writeInt(0); 8981 } 8982 if (mCameraTurnedOnTimer != null) { 8983 out.writeInt(1); 8984 mCameraTurnedOnTimer.writeToParcel(out, elapsedRealtimeUs); 8985 } else { 8986 out.writeInt(0); 8987 } 8988 if (mForegroundActivityTimer != null) { 8989 out.writeInt(1); 8990 mForegroundActivityTimer.writeToParcel(out, elapsedRealtimeUs); 8991 } else { 8992 out.writeInt(0); 8993 } 8994 if (mForegroundServiceTimer != null) { 8995 out.writeInt(1); 8996 mForegroundServiceTimer.writeToParcel(out, elapsedRealtimeUs); 8997 } else { 8998 out.writeInt(0); 8999 } 9000 if (mAggregatedPartialWakelockTimer != null) { 9001 out.writeInt(1); 9002 mAggregatedPartialWakelockTimer.writeToParcel(out, elapsedRealtimeUs); 9003 } else { 9004 out.writeInt(0); 9005 } 9006 if (mBluetoothScanTimer != null) { 9007 out.writeInt(1); 9008 mBluetoothScanTimer.writeToParcel(out, elapsedRealtimeUs); 9009 } else { 9010 out.writeInt(0); 9011 } 9012 if (mBluetoothUnoptimizedScanTimer != null) { 9013 out.writeInt(1); 9014 mBluetoothUnoptimizedScanTimer.writeToParcel(out, elapsedRealtimeUs); 9015 } else { 9016 out.writeInt(0); 9017 } 9018 if (mBluetoothScanResultCounter != null) { 9019 out.writeInt(1); 9020 mBluetoothScanResultCounter.writeToParcel(out); 9021 } else { 9022 out.writeInt(0); 9023 } 9024 if (mBluetoothScanResultBgCounter != null) { 9025 out.writeInt(1); 9026 mBluetoothScanResultBgCounter.writeToParcel(out); 9027 } else { 9028 out.writeInt(0); 9029 } 9030 for (int i = 0; i < NUM_PROCESS_STATE; i++) { 9031 if (mProcessStateTimer[i] != null) { 9032 out.writeInt(1); 9033 mProcessStateTimer[i].writeToParcel(out, elapsedRealtimeUs); 9034 } else { 9035 out.writeInt(0); 9036 } 9037 } 9038 if (mVibratorOnTimer != null) { 9039 out.writeInt(1); 9040 mVibratorOnTimer.writeToParcel(out, elapsedRealtimeUs); 9041 } else { 9042 out.writeInt(0); 9043 } 9044 if (mUserActivityCounters != null) { 9045 out.writeInt(1); 9046 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) { 9047 mUserActivityCounters[i].writeToParcel(out); 9048 } 9049 } else { 9050 out.writeInt(0); 9051 } 9052 if (mNetworkByteActivityCounters != null) { 9053 out.writeInt(1); 9054 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 9055 mNetworkByteActivityCounters[i].writeToParcel(out); 9056 mNetworkPacketActivityCounters[i].writeToParcel(out); 9057 } 9058 mMobileRadioActiveTime.writeToParcel(out); 9059 mMobileRadioActiveCount.writeToParcel(out); 9060 } else { 9061 out.writeInt(0); 9062 } 9063 9064 if (mWifiControllerActivity != null) { 9065 out.writeInt(1); 9066 mWifiControllerActivity.writeToParcel(out, 0); 9067 } else { 9068 out.writeInt(0); 9069 } 9070 9071 if (mBluetoothControllerActivity != null) { 9072 out.writeInt(1); 9073 mBluetoothControllerActivity.writeToParcel(out, 0); 9074 } else { 9075 out.writeInt(0); 9076 } 9077 9078 if (mModemControllerActivity != null) { 9079 out.writeInt(1); 9080 mModemControllerActivity.writeToParcel(out, 0); 9081 } else { 9082 out.writeInt(0); 9083 } 9084 9085 if (mUidMeasuredEnergyStats != null) { 9086 out.writeInt(1); 9087 mUidMeasuredEnergyStats.writeToParcel(out); 9088 } else { 9089 out.writeInt(0); 9090 } 9091 9092 mUserCpuTime.writeToParcel(out); 9093 mSystemCpuTime.writeToParcel(out); 9094 9095 mBsi.writeCpuSpeedCountersToParcel(out, mCpuClusterSpeedTimesUs); 9096 9097 LongSamplingCounterArray.writeToParcel(out, mCpuFreqTimeMs); 9098 LongSamplingCounterArray.writeToParcel(out, mScreenOffCpuFreqTimeMs); 9099 9100 mCpuActiveTimeMs.writeToParcel(out); 9101 mCpuClusterTimesMs.writeToParcel(out); 9102 9103 if (mProcStateTimeMs != null) { 9104 out.writeInt(mProcStateTimeMs.length); 9105 for (LongSamplingCounterArray counters : mProcStateTimeMs) { 9106 LongSamplingCounterArray.writeToParcel(out, counters); 9107 } 9108 } else { 9109 out.writeInt(0); 9110 } 9111 if (mProcStateScreenOffTimeMs != null) { 9112 out.writeInt(mProcStateScreenOffTimeMs.length); 9113 for (LongSamplingCounterArray counters : mProcStateScreenOffTimeMs) { 9114 LongSamplingCounterArray.writeToParcel(out, counters); 9115 } 9116 } else { 9117 out.writeInt(0); 9118 } 9119 9120 if (mMobileRadioApWakeupCount != null) { 9121 out.writeInt(1); 9122 mMobileRadioApWakeupCount.writeToParcel(out); 9123 } else { 9124 out.writeInt(0); 9125 } 9126 9127 if (mWifiRadioApWakeupCount != null) { 9128 out.writeInt(1); 9129 mWifiRadioApWakeupCount.writeToParcel(out); 9130 } else { 9131 out.writeInt(0); 9132 } 9133 out.writeDouble(mProportionalSystemServiceUsage); 9134 } 9135 readJobCompletionsFromParcelLocked(Parcel in)9136 void readJobCompletionsFromParcelLocked(Parcel in) { 9137 int numJobCompletions = in.readInt(); 9138 mJobCompletions.clear(); 9139 for (int j = 0; j < numJobCompletions; j++) { 9140 String jobName = in.readString(); 9141 int numTypes = in.readInt(); 9142 if (numTypes > 0) { 9143 SparseIntArray types = new SparseIntArray(); 9144 for (int k = 0; k < numTypes; k++) { 9145 int type = in.readInt(); 9146 int count = in.readInt(); 9147 types.put(type, count); 9148 } 9149 mJobCompletions.put(jobName, types); 9150 } 9151 } 9152 } 9153 readFromParcelLocked(TimeBase timeBase, TimeBase screenOffTimeBase, Parcel in)9154 void readFromParcelLocked(TimeBase timeBase, TimeBase screenOffTimeBase, Parcel in) { 9155 mOnBatteryBackgroundTimeBase.readFromParcel(in); 9156 mOnBatteryScreenOffBackgroundTimeBase.readFromParcel(in); 9157 9158 int numWakelocks = in.readInt(); 9159 mWakelockStats.clear(); 9160 for (int j = 0; j < numWakelocks; j++) { 9161 String wakelockName = in.readString(); 9162 Uid.Wakelock wakelock = new Wakelock(mBsi, this); 9163 wakelock.readFromParcelLocked( 9164 timeBase, screenOffTimeBase, mOnBatteryScreenOffBackgroundTimeBase, in); 9165 mWakelockStats.add(wakelockName, wakelock); 9166 } 9167 9168 int numSyncs = in.readInt(); 9169 mSyncStats.clear(); 9170 for (int j = 0; j < numSyncs; j++) { 9171 String syncName = in.readString(); 9172 if (in.readInt() != 0) { 9173 mSyncStats.add(syncName, new DualTimer(mBsi.mClocks, Uid.this, SYNC, null, 9174 mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase, in)); 9175 } 9176 } 9177 9178 int numJobs = in.readInt(); 9179 mJobStats.clear(); 9180 for (int j = 0; j < numJobs; j++) { 9181 String jobName = in.readString(); 9182 if (in.readInt() != 0) { 9183 mJobStats.add(jobName, new DualTimer(mBsi.mClocks, Uid.this, JOB, null, 9184 mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase, in)); 9185 } 9186 } 9187 9188 readJobCompletionsFromParcelLocked(in); 9189 9190 mJobsDeferredEventCount = new Counter(mBsi.mOnBatteryTimeBase, in); 9191 mJobsDeferredCount = new Counter(mBsi.mOnBatteryTimeBase, in); 9192 mJobsFreshnessTimeMs = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in); 9193 for (int i = 0; i < JOB_FRESHNESS_BUCKETS.length; i++) { 9194 mJobsFreshnessBuckets[i] = Counter.readCounterFromParcel(mBsi.mOnBatteryTimeBase, 9195 in); 9196 } 9197 9198 int numSensors = in.readInt(); 9199 mSensorStats.clear(); 9200 for (int k = 0; k < numSensors; k++) { 9201 int sensorNumber = in.readInt(); 9202 Uid.Sensor sensor = new Sensor(mBsi, this, sensorNumber); 9203 sensor.readFromParcelLocked(mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase, 9204 in); 9205 mSensorStats.put(sensorNumber, sensor); 9206 } 9207 9208 int numProcs = in.readInt(); 9209 mProcessStats.clear(); 9210 for (int k = 0; k < numProcs; k++) { 9211 String processName = in.readString(); 9212 Uid.Proc proc = new Proc(mBsi, processName); 9213 proc.readFromParcelLocked(in); 9214 mProcessStats.put(processName, proc); 9215 } 9216 9217 int numPkgs = in.readInt(); 9218 mPackageStats.clear(); 9219 for (int l = 0; l < numPkgs; l++) { 9220 String packageName = in.readString(); 9221 Uid.Pkg pkg = new Pkg(mBsi); 9222 pkg.readFromParcelLocked(in); 9223 mPackageStats.put(packageName, pkg); 9224 } 9225 9226 mWifiRunning = false; 9227 if (in.readInt() != 0) { 9228 mWifiRunningTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, WIFI_RUNNING, 9229 mBsi.mWifiRunningTimers, mBsi.mOnBatteryTimeBase, in); 9230 } else { 9231 mWifiRunningTimer = null; 9232 } 9233 mFullWifiLockOut = false; 9234 if (in.readInt() != 0) { 9235 mFullWifiLockTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, FULL_WIFI_LOCK, 9236 mBsi.mFullWifiLockTimers, mBsi.mOnBatteryTimeBase, in); 9237 } else { 9238 mFullWifiLockTimer = null; 9239 } 9240 mWifiScanStarted = false; 9241 if (in.readInt() != 0) { 9242 mWifiScanTimer = new DualTimer(mBsi.mClocks, Uid.this, WIFI_SCAN, 9243 mBsi.mWifiScanTimers, mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase, 9244 in); 9245 } else { 9246 mWifiScanTimer = null; 9247 } 9248 mWifiBatchedScanBinStarted = NO_BATCHED_SCAN_STARTED; 9249 for (int i = 0; i < NUM_WIFI_BATCHED_SCAN_BINS; i++) { 9250 if (in.readInt() != 0) { 9251 makeWifiBatchedScanBin(i, in); 9252 } else { 9253 mWifiBatchedScanTimer[i] = null; 9254 } 9255 } 9256 mWifiMulticastWakelockCount = 0; 9257 if (in.readInt() != 0) { 9258 mWifiMulticastTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, WIFI_MULTICAST_ENABLED, 9259 mBsi.mWifiMulticastTimers, mBsi.mOnBatteryTimeBase, in); 9260 } else { 9261 mWifiMulticastTimer = null; 9262 } 9263 if (in.readInt() != 0) { 9264 mAudioTurnedOnTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, AUDIO_TURNED_ON, 9265 mBsi.mAudioTurnedOnTimers, mBsi.mOnBatteryTimeBase, in); 9266 } else { 9267 mAudioTurnedOnTimer = null; 9268 } 9269 if (in.readInt() != 0) { 9270 mVideoTurnedOnTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, VIDEO_TURNED_ON, 9271 mBsi.mVideoTurnedOnTimers, mBsi.mOnBatteryTimeBase, in); 9272 } else { 9273 mVideoTurnedOnTimer = null; 9274 } 9275 if (in.readInt() != 0) { 9276 mFlashlightTurnedOnTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, 9277 FLASHLIGHT_TURNED_ON, mBsi.mFlashlightTurnedOnTimers, mBsi.mOnBatteryTimeBase, in); 9278 } else { 9279 mFlashlightTurnedOnTimer = null; 9280 } 9281 if (in.readInt() != 0) { 9282 mCameraTurnedOnTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, CAMERA_TURNED_ON, 9283 mBsi.mCameraTurnedOnTimers, mBsi.mOnBatteryTimeBase, in); 9284 } else { 9285 mCameraTurnedOnTimer = null; 9286 } 9287 if (in.readInt() != 0) { 9288 mForegroundActivityTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, 9289 FOREGROUND_ACTIVITY, null, mBsi.mOnBatteryTimeBase, in); 9290 } else { 9291 mForegroundActivityTimer = null; 9292 } 9293 if (in.readInt() != 0) { 9294 mForegroundServiceTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, 9295 FOREGROUND_SERVICE, null, mBsi.mOnBatteryTimeBase, in); 9296 } else { 9297 mForegroundServiceTimer = null; 9298 } 9299 if (in.readInt() != 0) { 9300 mAggregatedPartialWakelockTimer = new DualTimer(mBsi.mClocks, this, 9301 AGGREGATED_WAKE_TYPE_PARTIAL, null, 9302 mBsi.mOnBatteryScreenOffTimeBase, mOnBatteryScreenOffBackgroundTimeBase, 9303 in); 9304 } else { 9305 mAggregatedPartialWakelockTimer = null; 9306 } 9307 if (in.readInt() != 0) { 9308 mBluetoothScanTimer = new DualTimer(mBsi.mClocks, Uid.this, BLUETOOTH_SCAN_ON, 9309 mBsi.mBluetoothScanOnTimers, mBsi.mOnBatteryTimeBase, 9310 mOnBatteryBackgroundTimeBase, in); 9311 } else { 9312 mBluetoothScanTimer = null; 9313 } 9314 if (in.readInt() != 0) { 9315 mBluetoothUnoptimizedScanTimer = new DualTimer(mBsi.mClocks, Uid.this, 9316 BLUETOOTH_UNOPTIMIZED_SCAN_ON, null, 9317 mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase, in); 9318 } else { 9319 mBluetoothUnoptimizedScanTimer = null; 9320 } 9321 if (in.readInt() != 0) { 9322 mBluetoothScanResultCounter = new Counter(mBsi.mOnBatteryTimeBase, in); 9323 } else { 9324 mBluetoothScanResultCounter = null; 9325 } 9326 if (in.readInt() != 0) { 9327 mBluetoothScanResultBgCounter = new Counter(mOnBatteryBackgroundTimeBase, in); 9328 } else { 9329 mBluetoothScanResultBgCounter = null; 9330 } 9331 mProcessState = ActivityManager.PROCESS_STATE_NONEXISTENT; 9332 for (int i = 0; i < NUM_PROCESS_STATE; i++) { 9333 if (in.readInt() != 0) { 9334 makeProcessState(i, in); 9335 } else { 9336 mProcessStateTimer[i] = null; 9337 } 9338 } 9339 if (in.readInt() != 0) { 9340 mVibratorOnTimer = new BatchTimer(mBsi.mClocks, Uid.this, VIBRATOR_ON, 9341 mBsi.mOnBatteryTimeBase, in); 9342 } else { 9343 mVibratorOnTimer = null; 9344 } 9345 if (in.readInt() != 0) { 9346 mUserActivityCounters = new Counter[NUM_USER_ACTIVITY_TYPES]; 9347 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) { 9348 mUserActivityCounters[i] = new Counter(mBsi.mOnBatteryTimeBase, in); 9349 } 9350 } else { 9351 mUserActivityCounters = null; 9352 } 9353 if (in.readInt() != 0) { 9354 mNetworkByteActivityCounters = new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES]; 9355 mNetworkPacketActivityCounters 9356 = new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES]; 9357 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 9358 mNetworkByteActivityCounters[i] 9359 = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in); 9360 mNetworkPacketActivityCounters[i] 9361 = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in); 9362 } 9363 mMobileRadioActiveTime = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in); 9364 mMobileRadioActiveCount = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in); 9365 } else { 9366 mNetworkByteActivityCounters = null; 9367 mNetworkPacketActivityCounters = null; 9368 } 9369 9370 if (in.readInt() != 0) { 9371 mWifiControllerActivity = new ControllerActivityCounterImpl(mBsi.mOnBatteryTimeBase, 9372 NUM_WIFI_TX_LEVELS, in); 9373 } else { 9374 mWifiControllerActivity = null; 9375 } 9376 9377 if (in.readInt() != 0) { 9378 mBluetoothControllerActivity = new ControllerActivityCounterImpl(mBsi.mOnBatteryTimeBase, 9379 NUM_BT_TX_LEVELS, in); 9380 } else { 9381 mBluetoothControllerActivity = null; 9382 } 9383 9384 if (in.readInt() != 0) { 9385 mModemControllerActivity = new ControllerActivityCounterImpl(mBsi.mOnBatteryTimeBase, 9386 ModemActivityInfo.getNumTxPowerLevels(), in); 9387 } else { 9388 mModemControllerActivity = null; 9389 } 9390 9391 if (in.readInt() != 0) { 9392 mUidMeasuredEnergyStats = new MeasuredEnergyStats(in); 9393 } 9394 9395 mUserCpuTime = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in); 9396 mSystemCpuTime = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in); 9397 9398 mCpuClusterSpeedTimesUs = mBsi.readCpuSpeedCountersFromParcel(in); 9399 9400 mCpuFreqTimeMs = LongSamplingCounterArray.readFromParcel(in, mBsi.mOnBatteryTimeBase); 9401 mScreenOffCpuFreqTimeMs = LongSamplingCounterArray.readFromParcel( 9402 in, mBsi.mOnBatteryScreenOffTimeBase); 9403 9404 mCpuActiveTimeMs = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in); 9405 mCpuClusterTimesMs = new LongSamplingCounterArray(mBsi.mOnBatteryTimeBase, in); 9406 9407 int length = in.readInt(); 9408 if (length == NUM_PROCESS_STATE) { 9409 mProcStateTimeMs = new LongSamplingCounterArray[length]; 9410 for (int procState = 0; procState < length; ++procState) { 9411 mProcStateTimeMs[procState] = LongSamplingCounterArray.readFromParcel( 9412 in, mBsi.mOnBatteryTimeBase); 9413 } 9414 } else { 9415 mProcStateTimeMs = null; 9416 } 9417 length = in.readInt(); 9418 if (length == NUM_PROCESS_STATE) { 9419 mProcStateScreenOffTimeMs = new LongSamplingCounterArray[length]; 9420 for (int procState = 0; procState < length; ++procState) { 9421 mProcStateScreenOffTimeMs[procState] = LongSamplingCounterArray.readFromParcel( 9422 in, mBsi.mOnBatteryScreenOffTimeBase); 9423 } 9424 } else { 9425 mProcStateScreenOffTimeMs = null; 9426 } 9427 9428 if (in.readInt() != 0) { 9429 mMobileRadioApWakeupCount = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in); 9430 } else { 9431 mMobileRadioApWakeupCount = null; 9432 } 9433 9434 if (in.readInt() != 0) { 9435 mWifiRadioApWakeupCount = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in); 9436 } else { 9437 mWifiRadioApWakeupCount = null; 9438 } 9439 9440 mProportionalSystemServiceUsage = in.readDouble(); 9441 } 9442 noteJobsDeferredLocked(int numDeferred, long sinceLast)9443 public void noteJobsDeferredLocked(int numDeferred, long sinceLast) { 9444 mJobsDeferredEventCount.addAtomic(1); 9445 mJobsDeferredCount.addAtomic(numDeferred); 9446 if (sinceLast != 0) { 9447 // Add the total time, which can be divided by the event count to get an average 9448 mJobsFreshnessTimeMs.addCountLocked(sinceLast); 9449 // Also keep track of how many times there were in these different buckets. 9450 for (int i = 0; i < JOB_FRESHNESS_BUCKETS.length; i++) { 9451 if (sinceLast < JOB_FRESHNESS_BUCKETS[i]) { 9452 if (mJobsFreshnessBuckets[i] == null) { 9453 mJobsFreshnessBuckets[i] = new Counter( 9454 mBsi.mOnBatteryTimeBase); 9455 } 9456 mJobsFreshnessBuckets[i].addAtomic(1); 9457 break; 9458 } 9459 } 9460 } 9461 } 9462 9463 // Reusable object used as a key to lookup values in mBinderCallStats 9464 private static BinderCallStats sTempBinderCallStats = new BinderCallStats(); 9465 9466 /** 9467 * Notes incoming binder call stats associated with this work source UID. 9468 */ noteBinderCallStatsLocked(long incrementalCallCount, Collection<BinderCallsStats.CallStat> callStats)9469 public void noteBinderCallStatsLocked(long incrementalCallCount, 9470 Collection<BinderCallsStats.CallStat> callStats) { 9471 if (DEBUG) { 9472 Slog.d(TAG, "noteBinderCalls() workSourceUid = [" + mUid + "], " 9473 + " incrementalCallCount: " + incrementalCallCount + " callStats = [" 9474 + new ArrayList<>(callStats) + "]"); 9475 } 9476 mBinderCallCount += incrementalCallCount; 9477 for (BinderCallsStats.CallStat stat : callStats) { 9478 BinderCallStats bcs; 9479 sTempBinderCallStats.binderClass = stat.binderClass; 9480 sTempBinderCallStats.transactionCode = stat.transactionCode; 9481 int index = mBinderCallStats.indexOf(sTempBinderCallStats); 9482 if (index >= 0) { 9483 bcs = mBinderCallStats.valueAt(index); 9484 } else { 9485 bcs = new BinderCallStats(); 9486 bcs.binderClass = stat.binderClass; 9487 bcs.transactionCode = stat.transactionCode; 9488 mBinderCallStats.add(bcs); 9489 } 9490 9491 bcs.callCount += stat.incrementalCallCount; 9492 bcs.recordedCallCount = stat.recordedCallCount; 9493 bcs.recordedCpuTimeMicros = stat.cpuTimeMicros; 9494 } 9495 } 9496 9497 /** 9498 * The statistics associated with a particular wake lock. 9499 */ 9500 public static class Wakelock extends BatteryStats.Uid.Wakelock { 9501 /** 9502 * BatteryStatsImpl that we are associated with. 9503 */ 9504 protected BatteryStatsImpl mBsi; 9505 9506 /** 9507 * BatteryStatsImpl that we are associated with. 9508 */ 9509 protected Uid mUid; 9510 9511 /** 9512 * How long (in ms) this uid has been keeping the device partially awake. 9513 * Tracks both the total time and the time while the app was in the background. 9514 */ 9515 DualTimer mTimerPartial; 9516 9517 /** 9518 * How long (in ms) this uid has been keeping the device fully awake. 9519 */ 9520 StopwatchTimer mTimerFull; 9521 9522 /** 9523 * How long (in ms) this uid has had a window keeping the device awake. 9524 */ 9525 StopwatchTimer mTimerWindow; 9526 9527 /** 9528 * How long (in ms) this uid has had a draw wake lock. 9529 */ 9530 StopwatchTimer mTimerDraw; 9531 Wakelock(BatteryStatsImpl bsi, Uid uid)9532 public Wakelock(BatteryStatsImpl bsi, Uid uid) { 9533 mBsi = bsi; 9534 mUid = uid; 9535 } 9536 9537 /** 9538 * Reads a possibly null Timer from a Parcel. The timer is associated with the 9539 * proper timer pool from the given BatteryStatsImpl object. 9540 * 9541 * @param in the Parcel to be read from. 9542 * return a new Timer, or null. 9543 */ readStopwatchTimerFromParcel(int type, ArrayList<StopwatchTimer> pool, TimeBase timeBase, Parcel in)9544 private StopwatchTimer readStopwatchTimerFromParcel(int type, 9545 ArrayList<StopwatchTimer> pool, TimeBase timeBase, Parcel in) { 9546 if (in.readInt() == 0) { 9547 return null; 9548 } 9549 9550 return new StopwatchTimer(mBsi.mClocks, mUid, type, pool, timeBase, in); 9551 } 9552 9553 /** 9554 * Reads a possibly null Timer from a Parcel. The timer is associated with the 9555 * proper timer pool from the given BatteryStatsImpl object. 9556 * 9557 * @param in the Parcel to be read from. 9558 * return a new Timer, or null. 9559 */ readDualTimerFromParcel(int type, ArrayList<StopwatchTimer> pool, TimeBase timeBase, TimeBase bgTimeBase, Parcel in)9560 private DualTimer readDualTimerFromParcel(int type, ArrayList<StopwatchTimer> pool, 9561 TimeBase timeBase, TimeBase bgTimeBase, Parcel in) { 9562 if (in.readInt() == 0) { 9563 return null; 9564 } 9565 9566 return new DualTimer(mBsi.mClocks, mUid, type, pool, timeBase, bgTimeBase, in); 9567 } 9568 reset(long elapsedRealtimeUs)9569 boolean reset(long elapsedRealtimeUs) { 9570 boolean wlactive = false; 9571 9572 wlactive |= !resetIfNotNull(mTimerFull, false, elapsedRealtimeUs); 9573 wlactive |= !resetIfNotNull(mTimerPartial, false, elapsedRealtimeUs); 9574 wlactive |= !resetIfNotNull(mTimerWindow, false, elapsedRealtimeUs); 9575 wlactive |= !resetIfNotNull(mTimerDraw, false, elapsedRealtimeUs); 9576 9577 if (!wlactive) { 9578 detachIfNotNull(mTimerFull); 9579 mTimerFull = null; 9580 9581 detachIfNotNull(mTimerPartial); 9582 mTimerPartial = null; 9583 9584 detachIfNotNull(mTimerWindow); 9585 mTimerWindow = null; 9586 9587 detachIfNotNull(mTimerDraw); 9588 mTimerDraw = null; 9589 } 9590 return !wlactive; 9591 } 9592 readFromParcelLocked(TimeBase timeBase, TimeBase screenOffTimeBase, TimeBase screenOffBgTimeBase, Parcel in)9593 void readFromParcelLocked(TimeBase timeBase, TimeBase screenOffTimeBase, 9594 TimeBase screenOffBgTimeBase, Parcel in) { 9595 mTimerPartial = readDualTimerFromParcel(WAKE_TYPE_PARTIAL, 9596 mBsi.mPartialTimers, screenOffTimeBase, screenOffBgTimeBase, in); 9597 mTimerFull = readStopwatchTimerFromParcel(WAKE_TYPE_FULL, 9598 mBsi.mFullTimers, timeBase, in); 9599 mTimerWindow = readStopwatchTimerFromParcel(WAKE_TYPE_WINDOW, 9600 mBsi.mWindowTimers, timeBase, in); 9601 mTimerDraw = readStopwatchTimerFromParcel(WAKE_TYPE_DRAW, 9602 mBsi.mDrawTimers, timeBase, in); 9603 } 9604 writeToParcelLocked(Parcel out, long elapsedRealtimeUs)9605 void writeToParcelLocked(Parcel out, long elapsedRealtimeUs) { 9606 Timer.writeTimerToParcel(out, mTimerPartial, elapsedRealtimeUs); 9607 Timer.writeTimerToParcel(out, mTimerFull, elapsedRealtimeUs); 9608 Timer.writeTimerToParcel(out, mTimerWindow, elapsedRealtimeUs); 9609 Timer.writeTimerToParcel(out, mTimerDraw, elapsedRealtimeUs); 9610 } 9611 9612 @Override 9613 @UnsupportedAppUsage getWakeTime(int type)9614 public Timer getWakeTime(int type) { 9615 switch (type) { 9616 case WAKE_TYPE_FULL: return mTimerFull; 9617 case WAKE_TYPE_PARTIAL: return mTimerPartial; 9618 case WAKE_TYPE_WINDOW: return mTimerWindow; 9619 case WAKE_TYPE_DRAW: return mTimerDraw; 9620 default: throw new IllegalArgumentException("type = " + type); 9621 } 9622 } 9623 detachFromTimeBase()9624 public void detachFromTimeBase() { 9625 detachIfNotNull(mTimerPartial); 9626 detachIfNotNull(mTimerFull); 9627 detachIfNotNull(mTimerWindow); 9628 detachIfNotNull(mTimerDraw); 9629 } 9630 } 9631 9632 public static class Sensor extends BatteryStats.Uid.Sensor { 9633 /** 9634 * BatteryStatsImpl that we are associated with. 9635 */ 9636 protected BatteryStatsImpl mBsi; 9637 9638 /** 9639 * Uid that we are associated with. 9640 */ 9641 protected Uid mUid; 9642 9643 final int mHandle; 9644 DualTimer mTimer; 9645 Sensor(BatteryStatsImpl bsi, Uid uid, int handle)9646 public Sensor(BatteryStatsImpl bsi, Uid uid, int handle) { 9647 mBsi = bsi; 9648 mUid = uid; 9649 mHandle = handle; 9650 } 9651 readTimersFromParcel( TimeBase timeBase, TimeBase bgTimeBase, Parcel in)9652 private DualTimer readTimersFromParcel( 9653 TimeBase timeBase, TimeBase bgTimeBase, Parcel in) { 9654 if (in.readInt() == 0) { 9655 return null; 9656 } 9657 9658 ArrayList<StopwatchTimer> pool = mBsi.mSensorTimers.get(mHandle); 9659 if (pool == null) { 9660 pool = new ArrayList<StopwatchTimer>(); 9661 mBsi.mSensorTimers.put(mHandle, pool); 9662 } 9663 return new DualTimer(mBsi.mClocks, mUid, 0, pool, timeBase, bgTimeBase, in); 9664 } 9665 reset(long elapsedRealtimeUs)9666 boolean reset(long elapsedRealtimeUs) { 9667 if (mTimer.reset(true, elapsedRealtimeUs)) { 9668 mTimer = null; 9669 return true; 9670 } 9671 return false; 9672 } 9673 readFromParcelLocked(TimeBase timeBase, TimeBase bgTimeBase, Parcel in)9674 void readFromParcelLocked(TimeBase timeBase, TimeBase bgTimeBase, Parcel in) { 9675 mTimer = readTimersFromParcel(timeBase, bgTimeBase, in); 9676 } 9677 writeToParcelLocked(Parcel out, long elapsedRealtimeUs)9678 void writeToParcelLocked(Parcel out, long elapsedRealtimeUs) { 9679 Timer.writeTimerToParcel(out, mTimer, elapsedRealtimeUs); 9680 } 9681 9682 @Override 9683 @UnsupportedAppUsage getSensorTime()9684 public Timer getSensorTime() { 9685 return mTimer; 9686 } 9687 9688 @Override getSensorBackgroundTime()9689 public Timer getSensorBackgroundTime() { 9690 if (mTimer == null) { 9691 return null; 9692 } 9693 return mTimer.getSubTimer(); 9694 } 9695 9696 @Override 9697 @UnsupportedAppUsage getHandle()9698 public int getHandle() { 9699 return mHandle; 9700 } 9701 detachFromTimeBase()9702 public void detachFromTimeBase() { 9703 detachIfNotNull(mTimer); 9704 } 9705 } 9706 9707 /** 9708 * The statistics associated with a particular process. 9709 */ 9710 public static class Proc extends BatteryStats.Uid.Proc implements TimeBaseObs { 9711 /** 9712 * BatteryStatsImpl that we are associated with. 9713 */ 9714 protected BatteryStatsImpl mBsi; 9715 9716 /** 9717 * The name of this process. 9718 */ 9719 final String mName; 9720 9721 /** 9722 * Remains true until removed from the stats. 9723 */ 9724 boolean mActive = true; 9725 9726 /** 9727 * Total time (in ms) spent executing in user code. 9728 */ 9729 long mUserTimeMs; 9730 9731 /** 9732 * Total time (in ms) spent executing in kernel code. 9733 */ 9734 long mSystemTimeMs; 9735 9736 /** 9737 * Amount of time (in ms) the process was running in the foreground. 9738 */ 9739 long mForegroundTimeMs; 9740 9741 /** 9742 * Number of times the process has been started. 9743 */ 9744 int mStarts; 9745 9746 /** 9747 * Number of times the process has crashed. 9748 */ 9749 int mNumCrashes; 9750 9751 /** 9752 * Number of times the process has had an ANR. 9753 */ 9754 int mNumAnrs; 9755 9756 ArrayList<ExcessivePower> mExcessivePower; 9757 Proc(BatteryStatsImpl bsi, String name)9758 public Proc(BatteryStatsImpl bsi, String name) { 9759 mBsi = bsi; 9760 mName = name; 9761 mBsi.mOnBatteryTimeBase.add(this); 9762 } 9763 onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)9764 public void onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, 9765 long baseRealtimeUs) { 9766 } 9767 onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)9768 public void onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, 9769 long baseRealtimeUs) { 9770 } 9771 9772 @Override reset(boolean detachIfReset, long elapsedRealtimeUs)9773 public boolean reset(boolean detachIfReset, long elapsedRealtimeUs) { 9774 if (detachIfReset) { 9775 this.detach(); 9776 } 9777 return true; 9778 } 9779 9780 @Override detach()9781 public void detach() { 9782 mActive = false; 9783 mBsi.mOnBatteryTimeBase.remove(this); 9784 } 9785 countExcessivePowers()9786 public int countExcessivePowers() { 9787 return mExcessivePower != null ? mExcessivePower.size() : 0; 9788 } 9789 getExcessivePower(int i)9790 public ExcessivePower getExcessivePower(int i) { 9791 if (mExcessivePower != null) { 9792 return mExcessivePower.get(i); 9793 } 9794 return null; 9795 } 9796 addExcessiveCpu(long overTimeMs, long usedTimeMs)9797 public void addExcessiveCpu(long overTimeMs, long usedTimeMs) { 9798 if (mExcessivePower == null) { 9799 mExcessivePower = new ArrayList<ExcessivePower>(); 9800 } 9801 ExcessivePower ew = new ExcessivePower(); 9802 ew.type = ExcessivePower.TYPE_CPU; 9803 ew.overTime = overTimeMs; 9804 ew.usedTime = usedTimeMs; 9805 mExcessivePower.add(ew); 9806 } 9807 writeExcessivePowerToParcelLocked(Parcel out)9808 void writeExcessivePowerToParcelLocked(Parcel out) { 9809 if (mExcessivePower == null) { 9810 out.writeInt(0); 9811 return; 9812 } 9813 9814 final int N = mExcessivePower.size(); 9815 out.writeInt(N); 9816 for (int i=0; i<N; i++) { 9817 ExcessivePower ew = mExcessivePower.get(i); 9818 out.writeInt(ew.type); 9819 out.writeLong(ew.overTime); 9820 out.writeLong(ew.usedTime); 9821 } 9822 } 9823 readExcessivePowerFromParcelLocked(Parcel in)9824 void readExcessivePowerFromParcelLocked(Parcel in) { 9825 final int N = in.readInt(); 9826 if (N == 0) { 9827 mExcessivePower = null; 9828 return; 9829 } 9830 9831 if (N > 10000) { 9832 throw new ParcelFormatException( 9833 "File corrupt: too many excessive power entries " + N); 9834 } 9835 9836 mExcessivePower = new ArrayList<>(); 9837 for (int i=0; i<N; i++) { 9838 ExcessivePower ew = new ExcessivePower(); 9839 ew.type = in.readInt(); 9840 ew.overTime = in.readLong(); 9841 ew.usedTime = in.readLong(); 9842 mExcessivePower.add(ew); 9843 } 9844 } 9845 writeToParcelLocked(Parcel out)9846 void writeToParcelLocked(Parcel out) { 9847 out.writeLong(mUserTimeMs); 9848 out.writeLong(mSystemTimeMs); 9849 out.writeLong(mForegroundTimeMs); 9850 out.writeInt(mStarts); 9851 out.writeInt(mNumCrashes); 9852 out.writeInt(mNumAnrs); 9853 writeExcessivePowerToParcelLocked(out); 9854 } 9855 readFromParcelLocked(Parcel in)9856 void readFromParcelLocked(Parcel in) { 9857 mUserTimeMs = in.readLong(); 9858 mSystemTimeMs = in.readLong(); 9859 mForegroundTimeMs = in.readLong(); 9860 mStarts = in.readInt(); 9861 mNumCrashes = in.readInt(); 9862 mNumAnrs = in.readInt(); 9863 readExcessivePowerFromParcelLocked(in); 9864 } 9865 9866 @UnsupportedAppUsage addCpuTimeLocked(int utimeMs, int stimeMs)9867 public void addCpuTimeLocked(int utimeMs, int stimeMs) { 9868 addCpuTimeLocked(utimeMs, stimeMs, mBsi.mOnBatteryTimeBase.isRunning()); 9869 } 9870 addCpuTimeLocked(int utimeMs, int stimeMs, boolean isRunning)9871 public void addCpuTimeLocked(int utimeMs, int stimeMs, boolean isRunning) { 9872 if (isRunning) { 9873 mUserTimeMs += utimeMs; 9874 mSystemTimeMs += stimeMs; 9875 } 9876 } 9877 9878 @UnsupportedAppUsage addForegroundTimeLocked(long ttimeMs)9879 public void addForegroundTimeLocked(long ttimeMs) { 9880 mForegroundTimeMs += ttimeMs; 9881 } 9882 9883 @UnsupportedAppUsage incStartsLocked()9884 public void incStartsLocked() { 9885 mStarts++; 9886 } 9887 incNumCrashesLocked()9888 public void incNumCrashesLocked() { 9889 mNumCrashes++; 9890 } 9891 incNumAnrsLocked()9892 public void incNumAnrsLocked() { 9893 mNumAnrs++; 9894 } 9895 9896 @Override isActive()9897 public boolean isActive() { 9898 return mActive; 9899 } 9900 9901 @Override 9902 @UnsupportedAppUsage getUserTime(int which)9903 public long getUserTime(int which) { 9904 return mUserTimeMs; 9905 } 9906 9907 @Override 9908 @UnsupportedAppUsage getSystemTime(int which)9909 public long getSystemTime(int which) { 9910 return mSystemTimeMs; 9911 } 9912 9913 @Override 9914 @UnsupportedAppUsage getForegroundTime(int which)9915 public long getForegroundTime(int which) { 9916 return mForegroundTimeMs; 9917 } 9918 9919 @Override 9920 @UnsupportedAppUsage getStarts(int which)9921 public int getStarts(int which) { 9922 return mStarts; 9923 } 9924 9925 @Override getNumCrashes(int which)9926 public int getNumCrashes(int which) { 9927 return mNumCrashes; 9928 } 9929 9930 @Override getNumAnrs(int which)9931 public int getNumAnrs(int which) { 9932 return mNumAnrs; 9933 } 9934 } 9935 9936 /** 9937 * The statistics associated with a particular package. 9938 */ 9939 public static class Pkg extends BatteryStats.Uid.Pkg implements TimeBaseObs { 9940 /** 9941 * BatteryStatsImpl that we are associated with. 9942 */ 9943 protected BatteryStatsImpl mBsi; 9944 9945 /** 9946 * Number of times wakeup alarms have occurred for this app. 9947 * On screen-off timebase starting in report v25. 9948 */ 9949 ArrayMap<String, Counter> mWakeupAlarms = new ArrayMap<>(); 9950 9951 /** 9952 * The statics we have collected for this package's services. 9953 */ 9954 final ArrayMap<String, Serv> mServiceStats = new ArrayMap<>(); 9955 Pkg(BatteryStatsImpl bsi)9956 public Pkg(BatteryStatsImpl bsi) { 9957 mBsi = bsi; 9958 mBsi.mOnBatteryScreenOffTimeBase.add(this); 9959 } 9960 onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)9961 public void onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, 9962 long baseRealtimeUs) { 9963 } 9964 onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)9965 public void onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, 9966 long baseRealtimeUs) { 9967 } 9968 9969 @Override reset(boolean detachIfReset, long elapsedRealtimeUs)9970 public boolean reset(boolean detachIfReset, long elapsedRealtimeUs) { 9971 if (detachIfReset) { 9972 this.detach(); 9973 } 9974 return true; 9975 } 9976 9977 @Override detach()9978 public void detach() { 9979 mBsi.mOnBatteryScreenOffTimeBase.remove(this); 9980 for (int j = mWakeupAlarms.size() - 1; j >= 0; j--) { 9981 detachIfNotNull(mWakeupAlarms.valueAt(j)); 9982 } 9983 for (int j = mServiceStats.size() - 1; j >= 0; j--) { 9984 detachIfNotNull(mServiceStats.valueAt(j)); 9985 } 9986 } 9987 readFromParcelLocked(Parcel in)9988 void readFromParcelLocked(Parcel in) { 9989 int numWA = in.readInt(); 9990 mWakeupAlarms.clear(); 9991 for (int i=0; i<numWA; i++) { 9992 String tag = in.readString(); 9993 mWakeupAlarms.put(tag, new Counter(mBsi.mOnBatteryScreenOffTimeBase, in)); 9994 } 9995 9996 int numServs = in.readInt(); 9997 mServiceStats.clear(); 9998 for (int m = 0; m < numServs; m++) { 9999 String serviceName = in.readString(); 10000 Uid.Pkg.Serv serv = new Serv(mBsi); 10001 mServiceStats.put(serviceName, serv); 10002 10003 serv.readFromParcelLocked(in); 10004 } 10005 } 10006 writeToParcelLocked(Parcel out)10007 void writeToParcelLocked(Parcel out) { 10008 int numWA = mWakeupAlarms.size(); 10009 out.writeInt(numWA); 10010 for (int i=0; i<numWA; i++) { 10011 out.writeString(mWakeupAlarms.keyAt(i)); 10012 mWakeupAlarms.valueAt(i).writeToParcel(out); 10013 } 10014 10015 final int NS = mServiceStats.size(); 10016 out.writeInt(NS); 10017 for (int i=0; i<NS; i++) { 10018 out.writeString(mServiceStats.keyAt(i)); 10019 Uid.Pkg.Serv serv = mServiceStats.valueAt(i); 10020 serv.writeToParcelLocked(out); 10021 } 10022 } 10023 10024 @Override getWakeupAlarmStats()10025 public ArrayMap<String, ? extends BatteryStats.Counter> getWakeupAlarmStats() { 10026 return mWakeupAlarms; 10027 } 10028 noteWakeupAlarmLocked(String tag)10029 public void noteWakeupAlarmLocked(String tag) { 10030 Counter c = mWakeupAlarms.get(tag); 10031 if (c == null) { 10032 c = new Counter(mBsi.mOnBatteryScreenOffTimeBase); 10033 mWakeupAlarms.put(tag, c); 10034 } 10035 c.stepAtomic(); 10036 } 10037 10038 @Override getServiceStats()10039 public ArrayMap<String, ? extends BatteryStats.Uid.Pkg.Serv> getServiceStats() { 10040 return mServiceStats; 10041 } 10042 10043 /** 10044 * The statistics associated with a particular service. 10045 */ 10046 public static class Serv extends BatteryStats.Uid.Pkg.Serv implements TimeBaseObs { 10047 /** 10048 * BatteryStatsImpl that we are associated with. 10049 */ 10050 protected BatteryStatsImpl mBsi; 10051 10052 /** 10053 * The android package in which this service resides. 10054 */ 10055 protected Pkg mPkg; 10056 10057 /** 10058 * Total time (ms in battery uptime) the service has been left started. 10059 */ 10060 protected long mStartTimeMs; 10061 10062 /** 10063 * If service has been started and not yet stopped, this is 10064 * when it was started. 10065 */ 10066 protected long mRunningSinceMs; 10067 10068 /** 10069 * True if we are currently running. 10070 */ 10071 protected boolean mRunning; 10072 10073 /** 10074 * Total number of times startService() has been called. 10075 */ 10076 protected int mStarts; 10077 10078 /** 10079 * Total time (ms in battery uptime) the service has been left launched. 10080 */ 10081 protected long mLaunchedTimeMs; 10082 10083 /** 10084 * If service has been launched and not yet exited, this is 10085 * when it was launched (ms in battery uptime). 10086 */ 10087 protected long mLaunchedSinceMs; 10088 10089 /** 10090 * True if we are currently launched. 10091 */ 10092 protected boolean mLaunched; 10093 10094 /** 10095 * Total number times the service has been launched. 10096 */ 10097 protected int mLaunches; 10098 10099 /** 10100 * Construct a Serv. Also adds it to the on-battery time base as a listener. 10101 */ Serv(BatteryStatsImpl bsi)10102 public Serv(BatteryStatsImpl bsi) { 10103 mBsi = bsi; 10104 mBsi.mOnBatteryTimeBase.add(this); 10105 } 10106 onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)10107 public void onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, 10108 long baseRealtimeUs) { 10109 } 10110 onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)10111 public void onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, 10112 long baseRealtimeUs) { 10113 } 10114 10115 @Override reset(boolean detachIfReset, long elapsedRealtimeUs)10116 public boolean reset(boolean detachIfReset, long elapsedRealtimeUs) { 10117 if (detachIfReset) { 10118 this.detach(); 10119 } 10120 return true; 10121 } 10122 10123 /** 10124 * Remove this Serv as a listener from the time base. 10125 Ms*/ 10126 @Override detach()10127 public void detach() { 10128 mBsi.mOnBatteryTimeBase.remove(this); 10129 } 10130 readFromParcelLocked(Parcel in)10131 public void readFromParcelLocked(Parcel in) { 10132 mStartTimeMs = in.readLong(); 10133 mRunningSinceMs = in.readLong(); 10134 mRunning = in.readInt() != 0; 10135 mStarts = in.readInt(); 10136 mLaunchedTimeMs = in.readLong(); 10137 mLaunchedSinceMs = in.readLong(); 10138 mLaunched = in.readInt() != 0; 10139 mLaunches = in.readInt(); 10140 } 10141 writeToParcelLocked(Parcel out)10142 public void writeToParcelLocked(Parcel out) { 10143 out.writeLong(mStartTimeMs); 10144 out.writeLong(mRunningSinceMs); 10145 out.writeInt(mRunning ? 1 : 0); 10146 out.writeInt(mStarts); 10147 out.writeLong(mLaunchedTimeMs); 10148 out.writeLong(mLaunchedSinceMs); 10149 out.writeInt(mLaunched ? 1 : 0); 10150 out.writeInt(mLaunches); 10151 } 10152 getLaunchTimeToNowLocked(long batteryUptimeMs)10153 public long getLaunchTimeToNowLocked(long batteryUptimeMs) { 10154 if (!mLaunched) return mLaunchedTimeMs; 10155 return mLaunchedTimeMs + batteryUptimeMs - mLaunchedSinceMs; 10156 } 10157 getStartTimeToNowLocked(long batteryUptimeMs)10158 public long getStartTimeToNowLocked(long batteryUptimeMs) { 10159 if (!mRunning) return mStartTimeMs; 10160 return mStartTimeMs + batteryUptimeMs - mRunningSinceMs; 10161 } 10162 10163 @UnsupportedAppUsage startLaunchedLocked()10164 public void startLaunchedLocked() { 10165 startLaunchedLocked(mBsi.mClocks.uptimeMillis()); 10166 } 10167 startLaunchedLocked(long uptimeMs)10168 public void startLaunchedLocked(long uptimeMs) { 10169 if (!mLaunched) { 10170 mLaunches++; 10171 mLaunchedSinceMs = mBsi.getBatteryUptimeLocked(uptimeMs) / 1000; 10172 mLaunched = true; 10173 } 10174 } 10175 10176 @UnsupportedAppUsage stopLaunchedLocked()10177 public void stopLaunchedLocked() { 10178 stopLaunchedLocked(mBsi.mClocks.uptimeMillis()); 10179 } 10180 stopLaunchedLocked(long uptimeMs)10181 public void stopLaunchedLocked(long uptimeMs) { 10182 if (mLaunched) { 10183 long timeMs = mBsi.getBatteryUptimeLocked(uptimeMs) / 1000 10184 - mLaunchedSinceMs; 10185 if (timeMs > 0) { 10186 mLaunchedTimeMs += timeMs; 10187 } else { 10188 mLaunches--; 10189 } 10190 mLaunched = false; 10191 } 10192 } 10193 10194 @UnsupportedAppUsage startRunningLocked()10195 public void startRunningLocked() { 10196 startRunningLocked(mBsi.mClocks.uptimeMillis()); 10197 } 10198 startRunningLocked(long uptimeMs)10199 public void startRunningLocked(long uptimeMs) { 10200 if (!mRunning) { 10201 mStarts++; 10202 mRunningSinceMs = mBsi.getBatteryUptimeLocked(uptimeMs) / 1000; 10203 mRunning = true; 10204 } 10205 } 10206 10207 @UnsupportedAppUsage stopRunningLocked()10208 public void stopRunningLocked() { 10209 stopRunningLocked(mBsi.mClocks.uptimeMillis()); 10210 } 10211 stopRunningLocked(long uptimeMs)10212 public void stopRunningLocked(long uptimeMs) { 10213 if (mRunning) { 10214 long timeMs = mBsi.getBatteryUptimeLocked(uptimeMs) / 1000 10215 - mRunningSinceMs; 10216 if (timeMs > 0) { 10217 mStartTimeMs += timeMs; 10218 } else { 10219 mStarts--; 10220 } 10221 mRunning = false; 10222 } 10223 } 10224 10225 @UnsupportedAppUsage getBatteryStats()10226 public BatteryStatsImpl getBatteryStats() { 10227 return mBsi; 10228 } 10229 10230 @Override getLaunches(int which)10231 public int getLaunches(int which) { 10232 return mLaunches; 10233 } 10234 10235 @Override getStartTime(long now, int which)10236 public long getStartTime(long now, int which) { 10237 return getStartTimeToNowLocked(now); 10238 } 10239 10240 @Override getStarts(int which)10241 public int getStarts(int which) { 10242 return mStarts; 10243 } 10244 } 10245 newServiceStatsLocked()10246 final Serv newServiceStatsLocked() { 10247 return new Serv(mBsi); 10248 } 10249 } 10250 10251 /** 10252 * Retrieve the statistics object for a particular process, creating 10253 * if needed. 10254 */ getProcessStatsLocked(String name)10255 public Proc getProcessStatsLocked(String name) { 10256 Proc ps = mProcessStats.get(name); 10257 if (ps == null) { 10258 ps = new Proc(mBsi, name); 10259 mProcessStats.put(name, ps); 10260 } 10261 10262 return ps; 10263 } 10264 10265 @GuardedBy("mBsi") updateUidProcessStateLocked(int procState)10266 public void updateUidProcessStateLocked(int procState) { 10267 updateUidProcessStateLocked(procState, 10268 mBsi.mClocks.elapsedRealtime(), mBsi.mClocks.uptimeMillis()); 10269 } 10270 updateUidProcessStateLocked(int procState, long elapsedRealtimeMs, long uptimeMs)10271 public void updateUidProcessStateLocked(int procState, 10272 long elapsedRealtimeMs, long uptimeMs) { 10273 int uidRunningState; 10274 // Make special note of Foreground Services 10275 final boolean userAwareService = 10276 (ActivityManager.isForegroundService(procState)); 10277 uidRunningState = BatteryStats.mapToInternalProcessState(procState); 10278 10279 if (mProcessState == uidRunningState && userAwareService == mInForegroundService) { 10280 return; 10281 } 10282 10283 if (mProcessState != uidRunningState) { 10284 if (mProcessState != ActivityManager.PROCESS_STATE_NONEXISTENT) { 10285 mProcessStateTimer[mProcessState].stopRunningLocked(elapsedRealtimeMs); 10286 10287 if (mBsi.trackPerProcStateCpuTimes()) { 10288 if (mBsi.mPendingUids.size() == 0) { 10289 mBsi.mExternalSync.scheduleReadProcStateCpuTimes( 10290 mBsi.mOnBatteryTimeBase.isRunning(), 10291 mBsi.mOnBatteryScreenOffTimeBase.isRunning(), 10292 mBsi.mConstants.PROC_STATE_CPU_TIMES_READ_DELAY_MS); 10293 mBsi.mNumSingleUidCpuTimeReads++; 10294 } else { 10295 mBsi.mNumBatchedSingleUidCpuTimeReads++; 10296 } 10297 if (mBsi.mPendingUids.indexOfKey(mUid) < 0 10298 || ArrayUtils.contains(CRITICAL_PROC_STATES, mProcessState)) { 10299 mBsi.mPendingUids.put(mUid, mProcessState); 10300 } 10301 } else { 10302 mBsi.mPendingUids.clear(); 10303 } 10304 } 10305 mProcessState = uidRunningState; 10306 if (uidRunningState != ActivityManager.PROCESS_STATE_NONEXISTENT) { 10307 if (mProcessStateTimer[uidRunningState] == null) { 10308 makeProcessState(uidRunningState, null); 10309 } 10310 mProcessStateTimer[uidRunningState].startRunningLocked(elapsedRealtimeMs); 10311 } 10312 10313 updateOnBatteryBgTimeBase(uptimeMs * 1000, elapsedRealtimeMs * 1000); 10314 updateOnBatteryScreenOffBgTimeBase(uptimeMs * 1000, elapsedRealtimeMs * 1000); 10315 } 10316 10317 if (userAwareService != mInForegroundService) { 10318 if (userAwareService) { 10319 noteForegroundServiceResumedLocked(elapsedRealtimeMs); 10320 } else { 10321 noteForegroundServicePausedLocked(elapsedRealtimeMs); 10322 } 10323 mInForegroundService = userAwareService; 10324 } 10325 } 10326 10327 /** Whether to consider Uid to be in the background for background timebase purposes. */ isInBackground()10328 public boolean isInBackground() { 10329 // Note that PROCESS_STATE_CACHED and ActivityManager.PROCESS_STATE_NONEXISTENT is 10330 // also considered to be 'background' for our purposes, because it's not foreground. 10331 return mProcessState >= PROCESS_STATE_BACKGROUND; 10332 } 10333 updateOnBatteryBgTimeBase(long uptimeUs, long realtimeUs)10334 public boolean updateOnBatteryBgTimeBase(long uptimeUs, long realtimeUs) { 10335 boolean on = mBsi.mOnBatteryTimeBase.isRunning() && isInBackground(); 10336 return mOnBatteryBackgroundTimeBase.setRunning(on, uptimeUs, realtimeUs); 10337 } 10338 updateOnBatteryScreenOffBgTimeBase(long uptimeUs, long realtimeUs)10339 public boolean updateOnBatteryScreenOffBgTimeBase(long uptimeUs, long realtimeUs) { 10340 boolean on = mBsi.mOnBatteryScreenOffTimeBase.isRunning() && isInBackground(); 10341 return mOnBatteryScreenOffBackgroundTimeBase.setRunning(on, uptimeUs, realtimeUs); 10342 } 10343 getPidStats()10344 public SparseArray<? extends Pid> getPidStats() { 10345 return mPids; 10346 } 10347 getPidStatsLocked(int pid)10348 public Pid getPidStatsLocked(int pid) { 10349 Pid p = mPids.get(pid); 10350 if (p == null) { 10351 p = new Pid(); 10352 mPids.put(pid, p); 10353 } 10354 return p; 10355 } 10356 10357 /** 10358 * Retrieve the statistics object for a particular service, creating 10359 * if needed. 10360 */ getPackageStatsLocked(String name)10361 public Pkg getPackageStatsLocked(String name) { 10362 Pkg ps = mPackageStats.get(name); 10363 if (ps == null) { 10364 ps = new Pkg(mBsi); 10365 mPackageStats.put(name, ps); 10366 } 10367 10368 return ps; 10369 } 10370 10371 /** 10372 * Retrieve the statistics object for a particular service, creating 10373 * if needed. 10374 */ getServiceStatsLocked(String pkg, String serv)10375 public Pkg.Serv getServiceStatsLocked(String pkg, String serv) { 10376 Pkg ps = getPackageStatsLocked(pkg); 10377 Pkg.Serv ss = ps.mServiceStats.get(serv); 10378 if (ss == null) { 10379 ss = ps.newServiceStatsLocked(); 10380 ps.mServiceStats.put(serv, ss); 10381 } 10382 10383 return ss; 10384 } 10385 readSyncSummaryFromParcelLocked(String name, Parcel in)10386 public void readSyncSummaryFromParcelLocked(String name, Parcel in) { 10387 DualTimer timer = mSyncStats.instantiateObject(); 10388 timer.readSummaryFromParcelLocked(in); 10389 mSyncStats.add(name, timer); 10390 } 10391 readJobSummaryFromParcelLocked(String name, Parcel in)10392 public void readJobSummaryFromParcelLocked(String name, Parcel in) { 10393 DualTimer timer = mJobStats.instantiateObject(); 10394 timer.readSummaryFromParcelLocked(in); 10395 mJobStats.add(name, timer); 10396 } 10397 readWakeSummaryFromParcelLocked(String wlName, Parcel in)10398 public void readWakeSummaryFromParcelLocked(String wlName, Parcel in) { 10399 Wakelock wl = new Wakelock(mBsi, this); 10400 mWakelockStats.add(wlName, wl); 10401 if (in.readInt() != 0) { 10402 getWakelockTimerLocked(wl, WAKE_TYPE_FULL).readSummaryFromParcelLocked(in); 10403 } 10404 if (in.readInt() != 0) { 10405 getWakelockTimerLocked(wl, WAKE_TYPE_PARTIAL).readSummaryFromParcelLocked(in); 10406 } 10407 if (in.readInt() != 0) { 10408 getWakelockTimerLocked(wl, WAKE_TYPE_WINDOW).readSummaryFromParcelLocked(in); 10409 } 10410 if (in.readInt() != 0) { 10411 getWakelockTimerLocked(wl, WAKE_TYPE_DRAW).readSummaryFromParcelLocked(in); 10412 } 10413 } 10414 getSensorTimerLocked(int sensor, boolean create)10415 public DualTimer getSensorTimerLocked(int sensor, boolean create) { 10416 Sensor se = mSensorStats.get(sensor); 10417 if (se == null) { 10418 if (!create) { 10419 return null; 10420 } 10421 se = new Sensor(mBsi, this, sensor); 10422 mSensorStats.put(sensor, se); 10423 } 10424 DualTimer t = se.mTimer; 10425 if (t != null) { 10426 return t; 10427 } 10428 ArrayList<StopwatchTimer> timers = mBsi.mSensorTimers.get(sensor); 10429 if (timers == null) { 10430 timers = new ArrayList<StopwatchTimer>(); 10431 mBsi.mSensorTimers.put(sensor, timers); 10432 } 10433 t = new DualTimer(mBsi.mClocks, this, BatteryStats.SENSOR, timers, 10434 mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase); 10435 se.mTimer = t; 10436 return t; 10437 } 10438 noteStartSyncLocked(String name, long elapsedRealtimeMs)10439 public void noteStartSyncLocked(String name, long elapsedRealtimeMs) { 10440 DualTimer t = mSyncStats.startObject(name, elapsedRealtimeMs); 10441 if (t != null) { 10442 t.startRunningLocked(elapsedRealtimeMs); 10443 } 10444 } 10445 noteStopSyncLocked(String name, long elapsedRealtimeMs)10446 public void noteStopSyncLocked(String name, long elapsedRealtimeMs) { 10447 DualTimer t = mSyncStats.stopObject(name, elapsedRealtimeMs); 10448 if (t != null) { 10449 t.stopRunningLocked(elapsedRealtimeMs); 10450 } 10451 } 10452 noteStartJobLocked(String name, long elapsedRealtimeMs)10453 public void noteStartJobLocked(String name, long elapsedRealtimeMs) { 10454 DualTimer t = mJobStats.startObject(name, elapsedRealtimeMs); 10455 if (t != null) { 10456 t.startRunningLocked(elapsedRealtimeMs); 10457 } 10458 } 10459 noteStopJobLocked(String name, long elapsedRealtimeMs, int stopReason)10460 public void noteStopJobLocked(String name, long elapsedRealtimeMs, int stopReason) { 10461 DualTimer t = mJobStats.stopObject(name, elapsedRealtimeMs); 10462 if (t != null) { 10463 t.stopRunningLocked(elapsedRealtimeMs); 10464 } 10465 if (mBsi.mOnBatteryTimeBase.isRunning()) { 10466 SparseIntArray types = mJobCompletions.get(name); 10467 if (types == null) { 10468 types = new SparseIntArray(); 10469 mJobCompletions.put(name, types); 10470 } 10471 int last = types.get(stopReason, 0); 10472 types.put(stopReason, last + 1); 10473 } 10474 } 10475 getWakelockTimerLocked(Wakelock wl, int type)10476 public StopwatchTimer getWakelockTimerLocked(Wakelock wl, int type) { 10477 if (wl == null) { 10478 return null; 10479 } 10480 switch (type) { 10481 case WAKE_TYPE_PARTIAL: { 10482 DualTimer t = wl.mTimerPartial; 10483 if (t == null) { 10484 t = new DualTimer(mBsi.mClocks, this, WAKE_TYPE_PARTIAL, 10485 mBsi.mPartialTimers, mBsi.mOnBatteryScreenOffTimeBase, 10486 mOnBatteryScreenOffBackgroundTimeBase); 10487 wl.mTimerPartial = t; 10488 } 10489 return t; 10490 } 10491 case WAKE_TYPE_FULL: { 10492 StopwatchTimer t = wl.mTimerFull; 10493 if (t == null) { 10494 t = new StopwatchTimer(mBsi.mClocks, this, WAKE_TYPE_FULL, 10495 mBsi.mFullTimers, mBsi.mOnBatteryTimeBase); 10496 wl.mTimerFull = t; 10497 } 10498 return t; 10499 } 10500 case WAKE_TYPE_WINDOW: { 10501 StopwatchTimer t = wl.mTimerWindow; 10502 if (t == null) { 10503 t = new StopwatchTimer(mBsi.mClocks, this, WAKE_TYPE_WINDOW, 10504 mBsi.mWindowTimers, mBsi.mOnBatteryTimeBase); 10505 wl.mTimerWindow = t; 10506 } 10507 return t; 10508 } 10509 case WAKE_TYPE_DRAW: { 10510 StopwatchTimer t = wl.mTimerDraw; 10511 if (t == null) { 10512 t = new StopwatchTimer(mBsi.mClocks, this, WAKE_TYPE_DRAW, 10513 mBsi.mDrawTimers, mBsi.mOnBatteryTimeBase); 10514 wl.mTimerDraw = t; 10515 } 10516 return t; 10517 } 10518 default: 10519 throw new IllegalArgumentException("type=" + type); 10520 } 10521 } 10522 noteStartWakeLocked(int pid, String name, int type, long elapsedRealtimeMs)10523 public void noteStartWakeLocked(int pid, String name, int type, long elapsedRealtimeMs) { 10524 Wakelock wl = mWakelockStats.startObject(name, elapsedRealtimeMs); 10525 if (wl != null) { 10526 getWakelockTimerLocked(wl, type).startRunningLocked(elapsedRealtimeMs); 10527 } 10528 if (type == WAKE_TYPE_PARTIAL) { 10529 createAggregatedPartialWakelockTimerLocked().startRunningLocked(elapsedRealtimeMs); 10530 if (pid >= 0) { 10531 Pid p = getPidStatsLocked(pid); 10532 if (p.mWakeNesting++ == 0) { 10533 p.mWakeStartMs = elapsedRealtimeMs; 10534 } 10535 } 10536 } 10537 } 10538 noteStopWakeLocked(int pid, String name, int type, long elapsedRealtimeMs)10539 public void noteStopWakeLocked(int pid, String name, int type, long elapsedRealtimeMs) { 10540 Wakelock wl = mWakelockStats.stopObject(name, elapsedRealtimeMs); 10541 if (wl != null) { 10542 StopwatchTimer wlt = getWakelockTimerLocked(wl, type); 10543 wlt.stopRunningLocked(elapsedRealtimeMs); 10544 } 10545 if (type == WAKE_TYPE_PARTIAL) { 10546 if (mAggregatedPartialWakelockTimer != null) { 10547 mAggregatedPartialWakelockTimer.stopRunningLocked(elapsedRealtimeMs); 10548 } 10549 if (pid >= 0) { 10550 Pid p = mPids.get(pid); 10551 if (p != null && p.mWakeNesting > 0) { 10552 if (p.mWakeNesting-- == 1) { 10553 p.mWakeSumMs += elapsedRealtimeMs - p.mWakeStartMs; 10554 p.mWakeStartMs = 0; 10555 } 10556 } 10557 } 10558 } 10559 } 10560 reportExcessiveCpuLocked(String proc, long overTimeMs, long usedTimeMs)10561 public void reportExcessiveCpuLocked(String proc, long overTimeMs, long usedTimeMs) { 10562 Proc p = getProcessStatsLocked(proc); 10563 if (p != null) { 10564 p.addExcessiveCpu(overTimeMs, usedTimeMs); 10565 } 10566 } 10567 noteStartSensor(int sensor, long elapsedRealtimeMs)10568 public void noteStartSensor(int sensor, long elapsedRealtimeMs) { 10569 DualTimer t = getSensorTimerLocked(sensor, /* create= */ true); 10570 t.startRunningLocked(elapsedRealtimeMs); 10571 } 10572 noteStopSensor(int sensor, long elapsedRealtimeMs)10573 public void noteStopSensor(int sensor, long elapsedRealtimeMs) { 10574 // Don't create a timer if one doesn't already exist 10575 DualTimer t = getSensorTimerLocked(sensor, false); 10576 if (t != null) { 10577 t.stopRunningLocked(elapsedRealtimeMs); 10578 } 10579 } 10580 noteStartGps(long elapsedRealtimeMs)10581 public void noteStartGps(long elapsedRealtimeMs) { 10582 noteStartSensor(Sensor.GPS, elapsedRealtimeMs); 10583 } 10584 noteStopGps(long elapsedRealtimeMs)10585 public void noteStopGps(long elapsedRealtimeMs) { 10586 noteStopSensor(Sensor.GPS, elapsedRealtimeMs); 10587 } 10588 getBatteryStats()10589 public BatteryStatsImpl getBatteryStats() { 10590 return mBsi; 10591 } 10592 } 10593 getCpuFreqs()10594 public long[] getCpuFreqs() { 10595 return mCpuFreqs; 10596 } 10597 BatteryStatsImpl(File systemDir, Handler handler, PlatformIdleStateCallback cb, MeasuredEnergyRetriever energyStatsCb, UserInfoProvider userInfoProvider)10598 public BatteryStatsImpl(File systemDir, Handler handler, PlatformIdleStateCallback cb, 10599 MeasuredEnergyRetriever energyStatsCb, UserInfoProvider userInfoProvider) { 10600 this(new SystemClocks(), systemDir, handler, cb, energyStatsCb, userInfoProvider); 10601 } 10602 BatteryStatsImpl(Clocks clocks, File systemDir, Handler handler, PlatformIdleStateCallback cb, MeasuredEnergyRetriever energyStatsCb, UserInfoProvider userInfoProvider)10603 private BatteryStatsImpl(Clocks clocks, File systemDir, Handler handler, 10604 PlatformIdleStateCallback cb, MeasuredEnergyRetriever energyStatsCb, 10605 UserInfoProvider userInfoProvider) { 10606 init(clocks); 10607 10608 if (systemDir == null) { 10609 mStatsFile = null; 10610 mBatteryStatsHistory = new BatteryStatsHistory(mHistoryBuffer); 10611 } else { 10612 mStatsFile = new AtomicFile(new File(systemDir, "batterystats.bin")); 10613 mBatteryStatsHistory = new BatteryStatsHistory(this, systemDir, mHistoryBuffer); 10614 } 10615 mCheckinFile = new AtomicFile(new File(systemDir, "batterystats-checkin.bin")); 10616 mDailyFile = new AtomicFile(new File(systemDir, "batterystats-daily.xml")); 10617 mHandler = new MyHandler(handler.getLooper()); 10618 mConstants = new Constants(mHandler); 10619 mStartCount++; 10620 initTimersAndCounters(); 10621 mOnBattery = mOnBatteryInternal = false; 10622 long uptimeUs = mClocks.uptimeMillis() * 1000; 10623 long realtimeUs = mClocks.elapsedRealtime() * 1000; 10624 initTimes(uptimeUs, realtimeUs); 10625 mStartPlatformVersion = mEndPlatformVersion = Build.ID; 10626 initDischarge(realtimeUs); 10627 clearHistoryLocked(); 10628 updateDailyDeadlineLocked(); 10629 mPlatformIdleStateCallback = cb; 10630 mMeasuredEnergyRetriever = energyStatsCb; 10631 mUserInfoProvider = userInfoProvider; 10632 10633 // Notify statsd that the system is initially not in doze. 10634 mDeviceIdleMode = DEVICE_IDLE_MODE_OFF; 10635 FrameworkStatsLog.write(FrameworkStatsLog.DEVICE_IDLE_MODE_STATE_CHANGED, mDeviceIdleMode); 10636 } 10637 10638 @VisibleForTesting initTimersAndCounters()10639 protected void initTimersAndCounters() { 10640 mScreenOnTimer = new StopwatchTimer(mClocks, null, -1, null, mOnBatteryTimeBase); 10641 mScreenDozeTimer = new StopwatchTimer(mClocks, null, -1, null, mOnBatteryTimeBase); 10642 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 10643 mScreenBrightnessTimer[i] = new StopwatchTimer(mClocks, null, -100-i, null, 10644 mOnBatteryTimeBase); 10645 } 10646 mInteractiveTimer = new StopwatchTimer(mClocks, null, -10, null, mOnBatteryTimeBase); 10647 mPowerSaveModeEnabledTimer = new StopwatchTimer(mClocks, null, -2, null, 10648 mOnBatteryTimeBase); 10649 mDeviceIdleModeLightTimer = new StopwatchTimer(mClocks, null, -11, null, 10650 mOnBatteryTimeBase); 10651 mDeviceIdleModeFullTimer = new StopwatchTimer(mClocks, null, -14, null, mOnBatteryTimeBase); 10652 mDeviceLightIdlingTimer = new StopwatchTimer(mClocks, null, -15, null, mOnBatteryTimeBase); 10653 mDeviceIdlingTimer = new StopwatchTimer(mClocks, null, -12, null, mOnBatteryTimeBase); 10654 mPhoneOnTimer = new StopwatchTimer(mClocks, null, -3, null, mOnBatteryTimeBase); 10655 for (int i = 0; i < CellSignalStrength.getNumSignalStrengthLevels(); i++) { 10656 mPhoneSignalStrengthsTimer[i] = new StopwatchTimer(mClocks, null, -200-i, null, 10657 mOnBatteryTimeBase); 10658 } 10659 mPhoneSignalScanningTimer = new StopwatchTimer(mClocks, null, -200+1, null, 10660 mOnBatteryTimeBase); 10661 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 10662 mPhoneDataConnectionsTimer[i] = new StopwatchTimer(mClocks, null, -300-i, null, 10663 mOnBatteryTimeBase); 10664 } 10665 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 10666 mNetworkByteActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase); 10667 mNetworkPacketActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase); 10668 } 10669 mWifiActivity = new ControllerActivityCounterImpl(mOnBatteryTimeBase, NUM_WIFI_TX_LEVELS); 10670 mBluetoothActivity = new ControllerActivityCounterImpl(mOnBatteryTimeBase, 10671 NUM_BT_TX_LEVELS); 10672 mModemActivity = new ControllerActivityCounterImpl(mOnBatteryTimeBase, 10673 ModemActivityInfo.getNumTxPowerLevels()); 10674 mMobileRadioActiveTimer = new StopwatchTimer(mClocks, null, -400, null, mOnBatteryTimeBase); 10675 mMobileRadioActivePerAppTimer = new StopwatchTimer(mClocks, null, -401, null, 10676 mOnBatteryTimeBase); 10677 mMobileRadioActiveAdjustedTime = new LongSamplingCounter(mOnBatteryTimeBase); 10678 mMobileRadioActiveUnknownTime = new LongSamplingCounter(mOnBatteryTimeBase); 10679 mMobileRadioActiveUnknownCount = new LongSamplingCounter(mOnBatteryTimeBase); 10680 mWifiMulticastWakelockTimer = new StopwatchTimer(mClocks, null, 10681 WIFI_AGGREGATE_MULTICAST_ENABLED, null, mOnBatteryTimeBase); 10682 mWifiOnTimer = new StopwatchTimer(mClocks, null, -4, null, mOnBatteryTimeBase); 10683 mGlobalWifiRunningTimer = new StopwatchTimer(mClocks, null, -5, null, mOnBatteryTimeBase); 10684 for (int i=0; i<NUM_WIFI_STATES; i++) { 10685 mWifiStateTimer[i] = new StopwatchTimer(mClocks, null, -600-i, null, 10686 mOnBatteryTimeBase); 10687 } 10688 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) { 10689 mWifiSupplStateTimer[i] = new StopwatchTimer(mClocks, null, -700-i, null, 10690 mOnBatteryTimeBase); 10691 } 10692 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { 10693 mWifiSignalStrengthsTimer[i] = new StopwatchTimer(mClocks, null, -800-i, null, 10694 mOnBatteryTimeBase); 10695 } 10696 mWifiActiveTimer = new StopwatchTimer(mClocks, null, -900, null, mOnBatteryTimeBase); 10697 for (int i=0; i< mGpsSignalQualityTimer.length; i++) { 10698 mGpsSignalQualityTimer[i] = new StopwatchTimer(mClocks, null, -1000-i, null, 10699 mOnBatteryTimeBase); 10700 } 10701 mAudioOnTimer = new StopwatchTimer(mClocks, null, -7, null, mOnBatteryTimeBase); 10702 mVideoOnTimer = new StopwatchTimer(mClocks, null, -8, null, mOnBatteryTimeBase); 10703 mFlashlightOnTimer = new StopwatchTimer(mClocks, null, -9, null, mOnBatteryTimeBase); 10704 mCameraOnTimer = new StopwatchTimer(mClocks, null, -13, null, mOnBatteryTimeBase); 10705 mBluetoothScanTimer = new StopwatchTimer(mClocks, null, -14, null, mOnBatteryTimeBase); 10706 mDischargeScreenOffCounter = new LongSamplingCounter(mOnBatteryScreenOffTimeBase); 10707 mDischargeScreenDozeCounter = new LongSamplingCounter(mOnBatteryTimeBase); 10708 mDischargeLightDozeCounter = new LongSamplingCounter(mOnBatteryTimeBase); 10709 mDischargeDeepDozeCounter = new LongSamplingCounter(mOnBatteryTimeBase); 10710 mDischargeCounter = new LongSamplingCounter(mOnBatteryTimeBase); 10711 mDischargeStartLevel = 0; 10712 mDischargeUnplugLevel = 0; 10713 mDischargePlugLevel = -1; 10714 mDischargeCurrentLevel = 0; 10715 mCurrentBatteryLevel = 0; 10716 } 10717 10718 @UnsupportedAppUsage BatteryStatsImpl(Parcel p)10719 public BatteryStatsImpl(Parcel p) { 10720 this(new SystemClocks(), p); 10721 } 10722 BatteryStatsImpl(Clocks clocks, Parcel p)10723 public BatteryStatsImpl(Clocks clocks, Parcel p) { 10724 init(clocks); 10725 mStatsFile = null; 10726 mCheckinFile = null; 10727 mDailyFile = null; 10728 mHandler = null; 10729 mExternalSync = null; 10730 mConstants = new Constants(mHandler); 10731 clearHistoryLocked(); 10732 mBatteryStatsHistory = new BatteryStatsHistory(mHistoryBuffer); 10733 readFromParcel(p); 10734 mPlatformIdleStateCallback = null; 10735 mMeasuredEnergyRetriever = null; 10736 } 10737 setPowerProfileLocked(PowerProfile profile)10738 public void setPowerProfileLocked(PowerProfile profile) { 10739 mPowerProfile = profile; 10740 10741 // We need to initialize the KernelCpuSpeedReaders to read from 10742 // the first cpu of each core. Once we have the PowerProfile, we have access to this 10743 // information. 10744 final int numClusters = mPowerProfile.getNumCpuClusters(); 10745 mKernelCpuSpeedReaders = new KernelCpuSpeedReader[numClusters]; 10746 int firstCpuOfCluster = 0; 10747 for (int i = 0; i < numClusters; i++) { 10748 final int numSpeedSteps = mPowerProfile.getNumSpeedStepsInCpuCluster(i); 10749 mKernelCpuSpeedReaders[i] = new KernelCpuSpeedReader(firstCpuOfCluster, 10750 numSpeedSteps); 10751 firstCpuOfCluster += mPowerProfile.getNumCoresInCpuCluster(i); 10752 } 10753 10754 if (mEstimatedBatteryCapacityMah == -1) { 10755 // Initialize the estimated battery capacity to a known preset one. 10756 mEstimatedBatteryCapacityMah = (int) mPowerProfile.getBatteryCapacity(); 10757 } 10758 } 10759 getPowerProfile()10760 PowerProfile getPowerProfile() { 10761 return mPowerProfile; 10762 } 10763 10764 /** 10765 * Starts tracking CPU time-in-state for threads of the system server process, 10766 * keeping a separate account of threads receiving incoming binder calls. 10767 */ startTrackingSystemServerCpuTime()10768 public void startTrackingSystemServerCpuTime() { 10769 mSystemServerCpuThreadReader.startTrackingThreadCpuTime(); 10770 } 10771 getSystemServiceCpuThreadTimes()10772 public SystemServiceCpuThreadTimes getSystemServiceCpuThreadTimes() { 10773 return mSystemServerCpuThreadReader.readAbsolute(); 10774 } 10775 setCallback(BatteryCallback cb)10776 public void setCallback(BatteryCallback cb) { 10777 mCallback = cb; 10778 } 10779 setRadioScanningTimeoutLocked(long timeoutUs)10780 public void setRadioScanningTimeoutLocked(long timeoutUs) { 10781 if (mPhoneSignalScanningTimer != null) { 10782 mPhoneSignalScanningTimer.setTimeout(timeoutUs); 10783 } 10784 } 10785 setExternalStatsSyncLocked(ExternalStatsSync sync)10786 public void setExternalStatsSyncLocked(ExternalStatsSync sync) { 10787 mExternalSync = sync; 10788 } 10789 updateDailyDeadlineLocked()10790 public void updateDailyDeadlineLocked() { 10791 // Get the current time. 10792 long currentTimeMs = mDailyStartTimeMs = mClocks.currentTimeMillis(); 10793 Calendar calDeadline = Calendar.getInstance(); 10794 calDeadline.setTimeInMillis(currentTimeMs); 10795 10796 // Move time up to the next day, ranging from 1am to 3pm. 10797 calDeadline.set(Calendar.DAY_OF_YEAR, calDeadline.get(Calendar.DAY_OF_YEAR) + 1); 10798 calDeadline.set(Calendar.MILLISECOND, 0); 10799 calDeadline.set(Calendar.SECOND, 0); 10800 calDeadline.set(Calendar.MINUTE, 0); 10801 calDeadline.set(Calendar.HOUR_OF_DAY, 1); 10802 mNextMinDailyDeadlineMs = calDeadline.getTimeInMillis(); 10803 calDeadline.set(Calendar.HOUR_OF_DAY, 3); 10804 mNextMaxDailyDeadlineMs = calDeadline.getTimeInMillis(); 10805 } 10806 recordDailyStatsIfNeededLocked(boolean settled, long currentTimeMs)10807 public void recordDailyStatsIfNeededLocked(boolean settled, long currentTimeMs) { 10808 if (currentTimeMs >= mNextMaxDailyDeadlineMs) { 10809 recordDailyStatsLocked(); 10810 } else if (settled && currentTimeMs >= mNextMinDailyDeadlineMs) { 10811 recordDailyStatsLocked(); 10812 } else if (currentTimeMs < (mDailyStartTimeMs - (1000 * 60 * 60 * 24))) { 10813 recordDailyStatsLocked(); 10814 } 10815 } 10816 recordDailyStatsLocked()10817 public void recordDailyStatsLocked() { 10818 DailyItem item = new DailyItem(); 10819 item.mStartTime = mDailyStartTimeMs; 10820 item.mEndTime = mClocks.currentTimeMillis(); 10821 boolean hasData = false; 10822 if (mDailyDischargeStepTracker.mNumStepDurations > 0) { 10823 hasData = true; 10824 item.mDischargeSteps = new LevelStepTracker( 10825 mDailyDischargeStepTracker.mNumStepDurations, 10826 mDailyDischargeStepTracker.mStepDurations); 10827 } 10828 if (mDailyChargeStepTracker.mNumStepDurations > 0) { 10829 hasData = true; 10830 item.mChargeSteps = new LevelStepTracker( 10831 mDailyChargeStepTracker.mNumStepDurations, 10832 mDailyChargeStepTracker.mStepDurations); 10833 } 10834 if (mDailyPackageChanges != null) { 10835 hasData = true; 10836 item.mPackageChanges = mDailyPackageChanges; 10837 mDailyPackageChanges = null; 10838 } 10839 mDailyDischargeStepTracker.init(); 10840 mDailyChargeStepTracker.init(); 10841 updateDailyDeadlineLocked(); 10842 10843 if (hasData) { 10844 final long startTimeMs = SystemClock.uptimeMillis(); 10845 mDailyItems.add(item); 10846 while (mDailyItems.size() > MAX_DAILY_ITEMS) { 10847 mDailyItems.remove(0); 10848 } 10849 final ByteArrayOutputStream memStream = new ByteArrayOutputStream(); 10850 try { 10851 TypedXmlSerializer out = Xml.resolveSerializer(memStream); 10852 writeDailyItemsLocked(out); 10853 final long initialTimeMs = SystemClock.uptimeMillis() - startTimeMs; 10854 BackgroundThread.getHandler().post(new Runnable() { 10855 @Override 10856 public void run() { 10857 synchronized (mCheckinFile) { 10858 final long startTimeMs2 = SystemClock.uptimeMillis(); 10859 FileOutputStream stream = null; 10860 try { 10861 stream = mDailyFile.startWrite(); 10862 memStream.writeTo(stream); 10863 stream.flush(); 10864 mDailyFile.finishWrite(stream); 10865 com.android.internal.logging.EventLogTags.writeCommitSysConfigFile( 10866 "batterystats-daily", 10867 initialTimeMs + SystemClock.uptimeMillis() - startTimeMs2); 10868 } catch (IOException e) { 10869 Slog.w("BatteryStats", 10870 "Error writing battery daily items", e); 10871 mDailyFile.failWrite(stream); 10872 } 10873 } 10874 } 10875 }); 10876 } catch (IOException e) { 10877 } 10878 } 10879 } 10880 writeDailyItemsLocked(TypedXmlSerializer out)10881 private void writeDailyItemsLocked(TypedXmlSerializer out) throws IOException { 10882 StringBuilder sb = new StringBuilder(64); 10883 out.startDocument(null, true); 10884 out.startTag(null, "daily-items"); 10885 for (int i=0; i<mDailyItems.size(); i++) { 10886 final DailyItem dit = mDailyItems.get(i); 10887 out.startTag(null, "item"); 10888 out.attributeLong(null, "start", dit.mStartTime); 10889 out.attributeLong(null, "end", dit.mEndTime); 10890 writeDailyLevelSteps(out, "dis", dit.mDischargeSteps, sb); 10891 writeDailyLevelSteps(out, "chg", dit.mChargeSteps, sb); 10892 if (dit.mPackageChanges != null) { 10893 for (int j=0; j<dit.mPackageChanges.size(); j++) { 10894 PackageChange pc = dit.mPackageChanges.get(j); 10895 if (pc.mUpdate) { 10896 out.startTag(null, "upd"); 10897 out.attribute(null, "pkg", pc.mPackageName); 10898 out.attributeLong(null, "ver", pc.mVersionCode); 10899 out.endTag(null, "upd"); 10900 } else { 10901 out.startTag(null, "rem"); 10902 out.attribute(null, "pkg", pc.mPackageName); 10903 out.endTag(null, "rem"); 10904 } 10905 } 10906 } 10907 out.endTag(null, "item"); 10908 } 10909 out.endTag(null, "daily-items"); 10910 out.endDocument(); 10911 } 10912 writeDailyLevelSteps(TypedXmlSerializer out, String tag, LevelStepTracker steps, StringBuilder tmpBuilder)10913 private void writeDailyLevelSteps(TypedXmlSerializer out, String tag, LevelStepTracker steps, 10914 StringBuilder tmpBuilder) throws IOException { 10915 if (steps != null) { 10916 out.startTag(null, tag); 10917 out.attributeInt(null, "n", steps.mNumStepDurations); 10918 for (int i=0; i<steps.mNumStepDurations; i++) { 10919 out.startTag(null, "s"); 10920 tmpBuilder.setLength(0); 10921 steps.encodeEntryAt(i, tmpBuilder); 10922 out.attribute(null, "v", tmpBuilder.toString()); 10923 out.endTag(null, "s"); 10924 } 10925 out.endTag(null, tag); 10926 } 10927 } 10928 readDailyStatsLocked()10929 public void readDailyStatsLocked() { 10930 Slog.d(TAG, "Reading daily items from " + mDailyFile.getBaseFile()); 10931 mDailyItems.clear(); 10932 FileInputStream stream; 10933 try { 10934 stream = mDailyFile.openRead(); 10935 } catch (FileNotFoundException e) { 10936 return; 10937 } 10938 try { 10939 TypedXmlPullParser parser = Xml.resolvePullParser(stream); 10940 readDailyItemsLocked(parser); 10941 } catch (IOException e) { 10942 } finally { 10943 try { 10944 stream.close(); 10945 } catch (IOException e) { 10946 } 10947 } 10948 } 10949 readDailyItemsLocked(TypedXmlPullParser parser)10950 private void readDailyItemsLocked(TypedXmlPullParser parser) { 10951 try { 10952 int type; 10953 while ((type = parser.next()) != XmlPullParser.START_TAG 10954 && type != XmlPullParser.END_DOCUMENT) { 10955 ; 10956 } 10957 10958 if (type != XmlPullParser.START_TAG) { 10959 throw new IllegalStateException("no start tag found"); 10960 } 10961 10962 int outerDepth = parser.getDepth(); 10963 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 10964 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 10965 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 10966 continue; 10967 } 10968 10969 String tagName = parser.getName(); 10970 if (tagName.equals("item")) { 10971 readDailyItemTagLocked(parser); 10972 } else { 10973 Slog.w(TAG, "Unknown element under <daily-items>: " 10974 + parser.getName()); 10975 XmlUtils.skipCurrentTag(parser); 10976 } 10977 } 10978 10979 } catch (IllegalStateException e) { 10980 Slog.w(TAG, "Failed parsing daily " + e); 10981 } catch (NullPointerException e) { 10982 Slog.w(TAG, "Failed parsing daily " + e); 10983 } catch (NumberFormatException e) { 10984 Slog.w(TAG, "Failed parsing daily " + e); 10985 } catch (XmlPullParserException e) { 10986 Slog.w(TAG, "Failed parsing daily " + e); 10987 } catch (IOException e) { 10988 Slog.w(TAG, "Failed parsing daily " + e); 10989 } catch (IndexOutOfBoundsException e) { 10990 Slog.w(TAG, "Failed parsing daily " + e); 10991 } 10992 } 10993 readDailyItemTagLocked(TypedXmlPullParser parser)10994 void readDailyItemTagLocked(TypedXmlPullParser parser) throws NumberFormatException, 10995 XmlPullParserException, IOException { 10996 DailyItem dit = new DailyItem(); 10997 dit.mStartTime = parser.getAttributeLong(null, "start", 0); 10998 dit.mEndTime = parser.getAttributeLong(null, "end", 0); 10999 int outerDepth = parser.getDepth(); 11000 int type; 11001 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 11002 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 11003 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 11004 continue; 11005 } 11006 11007 String tagName = parser.getName(); 11008 if (tagName.equals("dis")) { 11009 readDailyItemTagDetailsLocked(parser, dit, false, "dis"); 11010 } else if (tagName.equals("chg")) { 11011 readDailyItemTagDetailsLocked(parser, dit, true, "chg"); 11012 } else if (tagName.equals("upd")) { 11013 if (dit.mPackageChanges == null) { 11014 dit.mPackageChanges = new ArrayList<>(); 11015 } 11016 PackageChange pc = new PackageChange(); 11017 pc.mUpdate = true; 11018 pc.mPackageName = parser.getAttributeValue(null, "pkg"); 11019 pc.mVersionCode = parser.getAttributeLong(null, "ver", 0); 11020 dit.mPackageChanges.add(pc); 11021 XmlUtils.skipCurrentTag(parser); 11022 } else if (tagName.equals("rem")) { 11023 if (dit.mPackageChanges == null) { 11024 dit.mPackageChanges = new ArrayList<>(); 11025 } 11026 PackageChange pc = new PackageChange(); 11027 pc.mUpdate = false; 11028 pc.mPackageName = parser.getAttributeValue(null, "pkg"); 11029 dit.mPackageChanges.add(pc); 11030 XmlUtils.skipCurrentTag(parser); 11031 } else { 11032 Slog.w(TAG, "Unknown element under <item>: " 11033 + parser.getName()); 11034 XmlUtils.skipCurrentTag(parser); 11035 } 11036 } 11037 mDailyItems.add(dit); 11038 } 11039 readDailyItemTagDetailsLocked(TypedXmlPullParser parser, DailyItem dit, boolean isCharge, String tag)11040 void readDailyItemTagDetailsLocked(TypedXmlPullParser parser, DailyItem dit, boolean isCharge, 11041 String tag) 11042 throws NumberFormatException, XmlPullParserException, IOException { 11043 final int num = parser.getAttributeInt(null, "n", -1); 11044 if (num == -1) { 11045 Slog.w(TAG, "Missing 'n' attribute at " + parser.getPositionDescription()); 11046 XmlUtils.skipCurrentTag(parser); 11047 return; 11048 } 11049 LevelStepTracker steps = new LevelStepTracker(num); 11050 if (isCharge) { 11051 dit.mChargeSteps = steps; 11052 } else { 11053 dit.mDischargeSteps = steps; 11054 } 11055 int i = 0; 11056 int outerDepth = parser.getDepth(); 11057 int type; 11058 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 11059 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 11060 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 11061 continue; 11062 } 11063 11064 String tagName = parser.getName(); 11065 if ("s".equals(tagName)) { 11066 if (i < num) { 11067 String valueAttr = parser.getAttributeValue(null, "v"); 11068 if (valueAttr != null) { 11069 steps.decodeEntryAt(i, valueAttr); 11070 i++; 11071 } 11072 } 11073 } else { 11074 Slog.w(TAG, "Unknown element under <" + tag + ">: " 11075 + parser.getName()); 11076 XmlUtils.skipCurrentTag(parser); 11077 } 11078 } 11079 steps.mNumStepDurations = i; 11080 } 11081 11082 @Override getDailyItemLocked(int daysAgo)11083 public DailyItem getDailyItemLocked(int daysAgo) { 11084 int index = mDailyItems.size()-1-daysAgo; 11085 return index >= 0 ? mDailyItems.get(index) : null; 11086 } 11087 11088 @Override getCurrentDailyStartTime()11089 public long getCurrentDailyStartTime() { 11090 return mDailyStartTimeMs; 11091 } 11092 11093 @Override getNextMinDailyDeadline()11094 public long getNextMinDailyDeadline() { 11095 return mNextMinDailyDeadlineMs; 11096 } 11097 11098 @Override getNextMaxDailyDeadline()11099 public long getNextMaxDailyDeadline() { 11100 return mNextMaxDailyDeadlineMs; 11101 } 11102 getHistoryTotalSize()11103 public int getHistoryTotalSize() { 11104 return mConstants.MAX_HISTORY_BUFFER * mConstants.MAX_HISTORY_FILES; 11105 } 11106 getHistoryUsedSize()11107 public int getHistoryUsedSize() { 11108 return mBatteryStatsHistory.getHistoryUsedSize(); 11109 } 11110 11111 @Override 11112 @UnsupportedAppUsage startIteratingHistoryLocked()11113 public boolean startIteratingHistoryLocked() { 11114 mReadOverflow = false; 11115 mBatteryStatsHistoryIterator = createBatteryStatsHistoryIterator(); 11116 return true; 11117 } 11118 11119 /** 11120 * Creates an iterator for battery stats history. 11121 */ 11122 @VisibleForTesting createBatteryStatsHistoryIterator()11123 public BatteryStatsHistoryIterator createBatteryStatsHistoryIterator() { 11124 ArrayList<HistoryTag> tags = new ArrayList<>(mHistoryTagPool.size()); 11125 for (Map.Entry<HistoryTag, Integer> entry: mHistoryTagPool.entrySet()) { 11126 final HistoryTag tag = entry.getKey(); 11127 tag.poolIdx = entry.getValue(); 11128 tags.add(tag); 11129 } 11130 11131 return new BatteryStatsHistoryIterator(mBatteryStatsHistory, tags); 11132 } 11133 11134 @Override getHistoryStringPoolSize()11135 public int getHistoryStringPoolSize() { 11136 return mBatteryStatsHistoryIterator.getHistoryStringPoolSize(); 11137 } 11138 11139 @Override getHistoryStringPoolBytes()11140 public int getHistoryStringPoolBytes() { 11141 return mBatteryStatsHistoryIterator.getHistoryStringPoolBytes(); 11142 } 11143 11144 @Override getHistoryTagPoolString(int index)11145 public String getHistoryTagPoolString(int index) { 11146 return mBatteryStatsHistoryIterator.getHistoryTagPoolString(index); 11147 } 11148 11149 @Override getHistoryTagPoolUid(int index)11150 public int getHistoryTagPoolUid(int index) { 11151 return mBatteryStatsHistoryIterator.getHistoryTagPoolUid(index); 11152 } 11153 11154 @Override 11155 @UnsupportedAppUsage getNextHistoryLocked(HistoryItem out)11156 public boolean getNextHistoryLocked(HistoryItem out) { 11157 return mBatteryStatsHistoryIterator.next(out); 11158 } 11159 11160 @Override finishIteratingHistoryLocked()11161 public void finishIteratingHistoryLocked() { 11162 mBatteryStatsHistoryIterator = null; 11163 } 11164 11165 @Override getHistoryBaseTime()11166 public long getHistoryBaseTime() { 11167 return mHistoryBaseTimeMs; 11168 } 11169 11170 @Override getStartCount()11171 public int getStartCount() { 11172 return mStartCount; 11173 } 11174 11175 @UnsupportedAppUsage isOnBattery()11176 public boolean isOnBattery() { 11177 return mOnBattery; 11178 } 11179 isCharging()11180 public boolean isCharging() { 11181 return mCharging; 11182 } 11183 initTimes(long uptimeUs, long realtimeUs)11184 void initTimes(long uptimeUs, long realtimeUs) { 11185 mStartClockTimeMs = mClocks.currentTimeMillis(); 11186 mOnBatteryTimeBase.init(uptimeUs, realtimeUs); 11187 mOnBatteryScreenOffTimeBase.init(uptimeUs, realtimeUs); 11188 mRealtimeUs = 0; 11189 mUptimeUs = 0; 11190 mRealtimeStartUs = realtimeUs; 11191 mUptimeStartUs = uptimeUs; 11192 } 11193 initDischarge(long elapsedRealtimeUs)11194 void initDischarge(long elapsedRealtimeUs) { 11195 mLowDischargeAmountSinceCharge = 0; 11196 mHighDischargeAmountSinceCharge = 0; 11197 mDischargeAmountScreenOn = 0; 11198 mDischargeAmountScreenOnSinceCharge = 0; 11199 mDischargeAmountScreenOff = 0; 11200 mDischargeAmountScreenOffSinceCharge = 0; 11201 mDischargeAmountScreenDoze = 0; 11202 mDischargeAmountScreenDozeSinceCharge = 0; 11203 mDischargeStepTracker.init(); 11204 mChargeStepTracker.init(); 11205 mDischargeScreenOffCounter.reset(false, elapsedRealtimeUs); 11206 mDischargeScreenDozeCounter.reset(false, elapsedRealtimeUs); 11207 mDischargeLightDozeCounter.reset(false, elapsedRealtimeUs); 11208 mDischargeDeepDozeCounter.reset(false, elapsedRealtimeUs); 11209 mDischargeCounter.reset(false, elapsedRealtimeUs); 11210 } 11211 setBatteryResetListener(BatteryResetListener batteryResetListener)11212 public void setBatteryResetListener(BatteryResetListener batteryResetListener) { 11213 mBatteryResetListener = batteryResetListener; 11214 } 11215 resetAllStatsCmdLocked()11216 public void resetAllStatsCmdLocked() { 11217 final long mSecUptime = mClocks.uptimeMillis(); 11218 long uptimeUs = mSecUptime * 1000; 11219 long mSecRealtime = mClocks.elapsedRealtime(); 11220 long realtimeUs = mSecRealtime * 1000; 11221 resetAllStatsLocked(mSecUptime, mSecRealtime, RESET_REASON_ADB_COMMAND); 11222 mDischargeStartLevel = mHistoryCur.batteryLevel; 11223 pullPendingStateUpdatesLocked(); 11224 addHistoryRecordLocked(mSecRealtime, mSecUptime); 11225 mDischargeCurrentLevel = mDischargeUnplugLevel = mDischargePlugLevel 11226 = mCurrentBatteryLevel = mHistoryCur.batteryLevel; 11227 mOnBatteryTimeBase.reset(uptimeUs, realtimeUs); 11228 mOnBatteryScreenOffTimeBase.reset(uptimeUs, realtimeUs); 11229 if ((mHistoryCur.states&HistoryItem.STATE_BATTERY_PLUGGED_FLAG) == 0) { 11230 if (Display.isOnState(mScreenState)) { 11231 mDischargeScreenOnUnplugLevel = mHistoryCur.batteryLevel; 11232 mDischargeScreenDozeUnplugLevel = 0; 11233 mDischargeScreenOffUnplugLevel = 0; 11234 } else if (Display.isDozeState(mScreenState)) { 11235 mDischargeScreenOnUnplugLevel = 0; 11236 mDischargeScreenDozeUnplugLevel = mHistoryCur.batteryLevel; 11237 mDischargeScreenOffUnplugLevel = 0; 11238 } else { 11239 mDischargeScreenOnUnplugLevel = 0; 11240 mDischargeScreenDozeUnplugLevel = 0; 11241 mDischargeScreenOffUnplugLevel = mHistoryCur.batteryLevel; 11242 } 11243 mDischargeAmountScreenOn = 0; 11244 mDischargeAmountScreenOff = 0; 11245 mDischargeAmountScreenDoze = 0; 11246 } 11247 initActiveHistoryEventsLocked(mSecRealtime, mSecUptime); 11248 } 11249 resetAllStatsLocked(long uptimeMillis, long elapsedRealtimeMillis, int resetReason)11250 private void resetAllStatsLocked(long uptimeMillis, long elapsedRealtimeMillis, 11251 int resetReason) { 11252 if (mBatteryResetListener != null) { 11253 mBatteryResetListener.prepareForBatteryStatsReset(resetReason); 11254 } 11255 11256 final long uptimeUs = uptimeMillis * 1000; 11257 final long elapsedRealtimeUs = elapsedRealtimeMillis * 1000; 11258 mStartCount = 0; 11259 initTimes(uptimeUs, elapsedRealtimeUs); 11260 mScreenOnTimer.reset(false, elapsedRealtimeUs); 11261 mScreenDozeTimer.reset(false, elapsedRealtimeUs); 11262 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 11263 mScreenBrightnessTimer[i].reset(false, elapsedRealtimeUs); 11264 } 11265 11266 if (mPowerProfile != null) { 11267 mEstimatedBatteryCapacityMah = (int) mPowerProfile.getBatteryCapacity(); 11268 } else { 11269 mEstimatedBatteryCapacityMah = -1; 11270 } 11271 mLastLearnedBatteryCapacityUah = -1; 11272 mMinLearnedBatteryCapacityUah = -1; 11273 mMaxLearnedBatteryCapacityUah = -1; 11274 mInteractiveTimer.reset(false, elapsedRealtimeUs); 11275 mPowerSaveModeEnabledTimer.reset(false, elapsedRealtimeUs); 11276 mLastIdleTimeStartMs = elapsedRealtimeMillis; 11277 mLongestLightIdleTimeMs = 0; 11278 mLongestFullIdleTimeMs = 0; 11279 mDeviceIdleModeLightTimer.reset(false, elapsedRealtimeUs); 11280 mDeviceIdleModeFullTimer.reset(false, elapsedRealtimeUs); 11281 mDeviceLightIdlingTimer.reset(false, elapsedRealtimeUs); 11282 mDeviceIdlingTimer.reset(false, elapsedRealtimeUs); 11283 mPhoneOnTimer.reset(false, elapsedRealtimeUs); 11284 mAudioOnTimer.reset(false, elapsedRealtimeUs); 11285 mVideoOnTimer.reset(false, elapsedRealtimeUs); 11286 mFlashlightOnTimer.reset(false, elapsedRealtimeUs); 11287 mCameraOnTimer.reset(false, elapsedRealtimeUs); 11288 mBluetoothScanTimer.reset(false, elapsedRealtimeUs); 11289 for (int i = 0; i < CellSignalStrength.getNumSignalStrengthLevels(); i++) { 11290 mPhoneSignalStrengthsTimer[i].reset(false, elapsedRealtimeUs); 11291 } 11292 mPhoneSignalScanningTimer.reset(false, elapsedRealtimeUs); 11293 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 11294 mPhoneDataConnectionsTimer[i].reset(false, elapsedRealtimeUs); 11295 } 11296 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 11297 mNetworkByteActivityCounters[i].reset(false, elapsedRealtimeUs); 11298 mNetworkPacketActivityCounters[i].reset(false, elapsedRealtimeUs); 11299 } 11300 mMobileRadioActiveTimer.reset(false, elapsedRealtimeUs); 11301 mMobileRadioActivePerAppTimer.reset(false, elapsedRealtimeUs); 11302 mMobileRadioActiveAdjustedTime.reset(false, elapsedRealtimeUs); 11303 mMobileRadioActiveUnknownTime.reset(false, elapsedRealtimeUs); 11304 mMobileRadioActiveUnknownCount.reset(false, elapsedRealtimeUs); 11305 mWifiOnTimer.reset(false, elapsedRealtimeUs); 11306 mGlobalWifiRunningTimer.reset(false, elapsedRealtimeUs); 11307 for (int i=0; i<NUM_WIFI_STATES; i++) { 11308 mWifiStateTimer[i].reset(false, elapsedRealtimeUs); 11309 } 11310 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) { 11311 mWifiSupplStateTimer[i].reset(false, elapsedRealtimeUs); 11312 } 11313 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { 11314 mWifiSignalStrengthsTimer[i].reset(false, elapsedRealtimeUs); 11315 } 11316 mWifiMulticastWakelockTimer.reset(false, elapsedRealtimeUs); 11317 mWifiActiveTimer.reset(false, elapsedRealtimeUs); 11318 mWifiActivity.reset(false, elapsedRealtimeUs); 11319 for (int i=0; i< mGpsSignalQualityTimer.length; i++) { 11320 mGpsSignalQualityTimer[i].reset(false, elapsedRealtimeUs); 11321 } 11322 mBluetoothActivity.reset(false, elapsedRealtimeUs); 11323 mModemActivity.reset(false, elapsedRealtimeUs); 11324 mNumConnectivityChange = 0; 11325 11326 for (int i=0; i<mUidStats.size(); i++) { 11327 if (mUidStats.valueAt(i).reset(uptimeUs, elapsedRealtimeUs)) { 11328 mUidStats.valueAt(i).detachFromTimeBase(); 11329 mUidStats.remove(mUidStats.keyAt(i)); 11330 i--; 11331 } 11332 } 11333 11334 if (mRpmStats.size() > 0) { 11335 for (SamplingTimer timer : mRpmStats.values()) { 11336 mOnBatteryTimeBase.remove(timer); 11337 } 11338 mRpmStats.clear(); 11339 } 11340 if (mScreenOffRpmStats.size() > 0) { 11341 for (SamplingTimer timer : mScreenOffRpmStats.values()) { 11342 mOnBatteryScreenOffTimeBase.remove(timer); 11343 } 11344 mScreenOffRpmStats.clear(); 11345 } 11346 11347 if (mKernelWakelockStats.size() > 0) { 11348 for (SamplingTimer timer : mKernelWakelockStats.values()) { 11349 mOnBatteryScreenOffTimeBase.remove(timer); 11350 } 11351 mKernelWakelockStats.clear(); 11352 } 11353 11354 if (mKernelMemoryStats.size() > 0) { 11355 for (int i = 0; i < mKernelMemoryStats.size(); i++) { 11356 mOnBatteryTimeBase.remove(mKernelMemoryStats.valueAt(i)); 11357 } 11358 mKernelMemoryStats.clear(); 11359 } 11360 11361 if (mWakeupReasonStats.size() > 0) { 11362 for (SamplingTimer timer : mWakeupReasonStats.values()) { 11363 mOnBatteryTimeBase.remove(timer); 11364 } 11365 mWakeupReasonStats.clear(); 11366 } 11367 11368 mTmpRailStats.reset(); 11369 11370 MeasuredEnergyStats.resetIfNotNull(mGlobalMeasuredEnergyStats); 11371 11372 resetIfNotNull(mBinderThreadCpuTimesUs, false, elapsedRealtimeUs); 11373 11374 mLastHistoryStepDetails = null; 11375 mLastStepCpuUserTimeMs = mLastStepCpuSystemTimeMs = 0; 11376 mCurStepCpuUserTimeMs = mCurStepCpuSystemTimeMs = 0; 11377 mLastStepCpuUserTimeMs = mCurStepCpuUserTimeMs = 0; 11378 mLastStepCpuSystemTimeMs = mCurStepCpuSystemTimeMs = 0; 11379 mLastStepStatUserTimeMs = mCurStepStatUserTimeMs = 0; 11380 mLastStepStatSystemTimeMs = mCurStepStatSystemTimeMs = 0; 11381 mLastStepStatIOWaitTimeMs = mCurStepStatIOWaitTimeMs = 0; 11382 mLastStepStatIrqTimeMs = mCurStepStatIrqTimeMs = 0; 11383 mLastStepStatSoftIrqTimeMs = mCurStepStatSoftIrqTimeMs = 0; 11384 mLastStepStatIdleTimeMs = mCurStepStatIdleTimeMs = 0; 11385 11386 mNumAllUidCpuTimeReads = 0; 11387 mNumUidsRemoved = 0; 11388 11389 initDischarge(elapsedRealtimeUs); 11390 11391 clearHistoryLocked(); 11392 if (mBatteryStatsHistory != null) { 11393 mBatteryStatsHistory.resetAllFiles(); 11394 } 11395 11396 // Flush external data, gathering snapshots, but don't process it since it is pre-reset data 11397 mIgnoreNextExternalStats = true; 11398 mExternalSync.scheduleSync("reset", ExternalStatsSync.UPDATE_ALL); 11399 11400 mHandler.sendEmptyMessage(MSG_REPORT_RESET_STATS); 11401 } 11402 initActiveHistoryEventsLocked(long elapsedRealtimeMs, long uptimeMs)11403 private void initActiveHistoryEventsLocked(long elapsedRealtimeMs, long uptimeMs) { 11404 for (int i=0; i<HistoryItem.EVENT_COUNT; i++) { 11405 if (!mRecordAllHistory && i == HistoryItem.EVENT_PROC) { 11406 // Not recording process starts/stops. 11407 continue; 11408 } 11409 HashMap<String, SparseIntArray> active = mActiveEvents.getStateForEvent(i); 11410 if (active == null) { 11411 continue; 11412 } 11413 for (HashMap.Entry<String, SparseIntArray> ent : active.entrySet()) { 11414 SparseIntArray uids = ent.getValue(); 11415 for (int j=0; j<uids.size(); j++) { 11416 addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, i, ent.getKey(), 11417 uids.keyAt(j)); 11418 } 11419 } 11420 } 11421 } 11422 updateDischargeScreenLevelsLocked(int oldState, int newState)11423 void updateDischargeScreenLevelsLocked(int oldState, int newState) { 11424 updateOldDischargeScreenLevelLocked(oldState); 11425 updateNewDischargeScreenLevelLocked(newState); 11426 } 11427 updateOldDischargeScreenLevelLocked(int state)11428 private void updateOldDischargeScreenLevelLocked(int state) { 11429 if (Display.isOnState(state)) { 11430 int diff = mDischargeScreenOnUnplugLevel - mDischargeCurrentLevel; 11431 if (diff > 0) { 11432 mDischargeAmountScreenOn += diff; 11433 mDischargeAmountScreenOnSinceCharge += diff; 11434 } 11435 } else if (Display.isDozeState(state)) { 11436 int diff = mDischargeScreenDozeUnplugLevel - mDischargeCurrentLevel; 11437 if (diff > 0) { 11438 mDischargeAmountScreenDoze += diff; 11439 mDischargeAmountScreenDozeSinceCharge += diff; 11440 } 11441 } else if (Display.isOffState(state)) { 11442 int diff = mDischargeScreenOffUnplugLevel - mDischargeCurrentLevel; 11443 if (diff > 0) { 11444 mDischargeAmountScreenOff += diff; 11445 mDischargeAmountScreenOffSinceCharge += diff; 11446 } 11447 } 11448 } 11449 updateNewDischargeScreenLevelLocked(int state)11450 private void updateNewDischargeScreenLevelLocked(int state) { 11451 if (Display.isOnState(state)) { 11452 mDischargeScreenOnUnplugLevel = mDischargeCurrentLevel; 11453 mDischargeScreenOffUnplugLevel = 0; 11454 mDischargeScreenDozeUnplugLevel = 0; 11455 } else if (Display.isDozeState(state)) { 11456 mDischargeScreenOnUnplugLevel = 0; 11457 mDischargeScreenDozeUnplugLevel = mDischargeCurrentLevel; 11458 mDischargeScreenOffUnplugLevel = 0; 11459 } else if (Display.isOffState(state)) { 11460 mDischargeScreenOnUnplugLevel = 0; 11461 mDischargeScreenDozeUnplugLevel = 0; 11462 mDischargeScreenOffUnplugLevel = mDischargeCurrentLevel; 11463 } 11464 } 11465 pullPendingStateUpdatesLocked()11466 public void pullPendingStateUpdatesLocked() { 11467 if (mOnBatteryInternal) { 11468 updateDischargeScreenLevelsLocked(mScreenState, mScreenState); 11469 } 11470 } 11471 11472 private final Pools.Pool<NetworkStats> mNetworkStatsPool = new Pools.SynchronizedPool<>(6); 11473 11474 private final Object mWifiNetworkLock = new Object(); 11475 11476 @GuardedBy("mWifiNetworkLock") 11477 private String[] mWifiIfaces = EmptyArray.STRING; 11478 11479 @GuardedBy("mWifiNetworkLock") 11480 private NetworkStats mLastWifiNetworkStats = new NetworkStats(0, -1); 11481 11482 private final Object mModemNetworkLock = new Object(); 11483 11484 @GuardedBy("mModemNetworkLock") 11485 private String[] mModemIfaces = EmptyArray.STRING; 11486 11487 @GuardedBy("mModemNetworkLock") 11488 private NetworkStats mLastModemNetworkStats = new NetworkStats(0, -1); 11489 11490 @VisibleForTesting readNetworkStatsLocked(String[] ifaces)11491 protected NetworkStats readNetworkStatsLocked(String[] ifaces) { 11492 try { 11493 if (!ArrayUtils.isEmpty(ifaces)) { 11494 INetworkStatsService statsService = INetworkStatsService.Stub.asInterface( 11495 ServiceManager.getService(Context.NETWORK_STATS_SERVICE)); 11496 if (statsService != null) { 11497 return statsService.getDetailedUidStats(ifaces); 11498 } else { 11499 Slog.e(TAG, "Failed to get networkStatsService "); 11500 } 11501 } 11502 } catch (RemoteException e) { 11503 Slog.e(TAG, "failed to read network stats for ifaces: " + Arrays.toString(ifaces) + e); 11504 } 11505 return null; 11506 } 11507 11508 /** 11509 * Distribute WiFi energy info and network traffic to apps. 11510 * @param info The energy information from the WiFi controller. 11511 */ updateWifiState(@ullable final WifiActivityEnergyInfo info, final long consumedChargeUC, long elapsedRealtimeMs, long uptimeMs)11512 public void updateWifiState(@Nullable final WifiActivityEnergyInfo info, 11513 final long consumedChargeUC, long elapsedRealtimeMs, long uptimeMs) { 11514 if (DEBUG_ENERGY) { 11515 Slog.d(TAG, "Updating wifi stats: " + Arrays.toString(mWifiIfaces)); 11516 } 11517 11518 // Grab a separate lock to acquire the network stats, which may do I/O. 11519 NetworkStats delta = null; 11520 synchronized (mWifiNetworkLock) { 11521 final NetworkStats latestStats = readNetworkStatsLocked(mWifiIfaces); 11522 if (latestStats != null) { 11523 delta = NetworkStats.subtract(latestStats, mLastWifiNetworkStats, null, null, 11524 mNetworkStatsPool.acquire()); 11525 mNetworkStatsPool.release(mLastWifiNetworkStats); 11526 mLastWifiNetworkStats = latestStats; 11527 } 11528 } 11529 11530 synchronized (this) { 11531 if (!mOnBatteryInternal || mIgnoreNextExternalStats) { 11532 if (delta != null) { 11533 mNetworkStatsPool.release(delta); 11534 } 11535 if (mIgnoreNextExternalStats) { 11536 // TODO: Strictly speaking, we should re-mark all 5 timers for each uid (and the 11537 // global one) here like we do for display. But I'm not sure it's worth the 11538 // complicated code for a codepath that shouldn't ever actually happen in real 11539 // life. 11540 } 11541 return; 11542 } 11543 11544 final SparseDoubleArray uidEstimatedConsumptionMah = 11545 (mGlobalMeasuredEnergyStats != null 11546 && mWifiPowerCalculator != null && consumedChargeUC > 0) ? 11547 new SparseDoubleArray() : null; 11548 double totalEstimatedConsumptionMah = 0; 11549 11550 SparseLongArray rxPackets = new SparseLongArray(); 11551 SparseLongArray txPackets = new SparseLongArray(); 11552 long totalTxPackets = 0; 11553 long totalRxPackets = 0; 11554 if (delta != null) { 11555 NetworkStats.Entry entry = new NetworkStats.Entry(); 11556 final int size = delta.size(); 11557 for (int i = 0; i < size; i++) { 11558 entry = delta.getValues(i, entry); 11559 11560 if (DEBUG_ENERGY) { 11561 Slog.d(TAG, "Wifi uid " + entry.uid + ": delta rx=" + entry.rxBytes 11562 + " tx=" + entry.txBytes + " rxPackets=" + entry.rxPackets 11563 + " txPackets=" + entry.txPackets); 11564 } 11565 11566 if (entry.rxBytes == 0 && entry.txBytes == 0) { 11567 // Skip the lookup below since there is no work to do. 11568 continue; 11569 } 11570 11571 final Uid u = getUidStatsLocked(mapUid(entry.uid), elapsedRealtimeMs, uptimeMs); 11572 if (entry.rxBytes != 0) { 11573 u.noteNetworkActivityLocked(NETWORK_WIFI_RX_DATA, entry.rxBytes, 11574 entry.rxPackets); 11575 if (entry.set == NetworkStats.SET_DEFAULT) { // Background transfers 11576 u.noteNetworkActivityLocked(NETWORK_WIFI_BG_RX_DATA, entry.rxBytes, 11577 entry.rxPackets); 11578 } 11579 mNetworkByteActivityCounters[NETWORK_WIFI_RX_DATA].addCountLocked( 11580 entry.rxBytes); 11581 mNetworkPacketActivityCounters[NETWORK_WIFI_RX_DATA].addCountLocked( 11582 entry.rxPackets); 11583 11584 // TODO(b/182845426): What if u was a mapped isolated uid? Shouldn't we sum? 11585 rxPackets.put(u.getUid(), entry.rxPackets); 11586 11587 // Sum the total number of packets so that the Rx Power can 11588 // be evenly distributed amongst the apps. 11589 totalRxPackets += entry.rxPackets; 11590 } 11591 11592 if (entry.txBytes != 0) { 11593 u.noteNetworkActivityLocked(NETWORK_WIFI_TX_DATA, entry.txBytes, 11594 entry.txPackets); 11595 if (entry.set == NetworkStats.SET_DEFAULT) { // Background transfers 11596 u.noteNetworkActivityLocked(NETWORK_WIFI_BG_TX_DATA, entry.txBytes, 11597 entry.txPackets); 11598 } 11599 mNetworkByteActivityCounters[NETWORK_WIFI_TX_DATA].addCountLocked( 11600 entry.txBytes); 11601 mNetworkPacketActivityCounters[NETWORK_WIFI_TX_DATA].addCountLocked( 11602 entry.txPackets); 11603 11604 // TODO(b/182845426): What if u was a mapped isolated uid? Shouldn't we sum? 11605 txPackets.put(u.getUid(), entry.txPackets); 11606 11607 // Sum the total number of packets so that the Tx Power can 11608 // be evenly distributed amongst the apps. 11609 totalTxPackets += entry.txPackets; 11610 } 11611 11612 // Calculate consumed energy for this uid. Only do so if WifiReporting isn't 11613 // enabled (if it is, we'll do it later instead using info). 11614 if (uidEstimatedConsumptionMah != null && info == null && !mHasWifiReporting) { 11615 final long uidRunningMs = u.mWifiRunningTimer 11616 .getTimeSinceMarkLocked(elapsedRealtimeMs * 1000) / 1000; 11617 if (uidRunningMs > 0) u.mWifiRunningTimer.setMark(elapsedRealtimeMs); 11618 11619 final long uidScanMs = u.mWifiScanTimer 11620 .getTimeSinceMarkLocked(elapsedRealtimeMs * 1000) / 1000; 11621 if (uidScanMs > 0) u.mWifiScanTimer.setMark(elapsedRealtimeMs); 11622 11623 long uidBatchScanMs = 0; 11624 for (int bn = 0; bn < BatteryStats.Uid.NUM_WIFI_BATCHED_SCAN_BINS; bn++) { 11625 if (u.mWifiBatchedScanTimer[bn] != null) { 11626 long bnMs = u.mWifiBatchedScanTimer[bn] 11627 .getTimeSinceMarkLocked(elapsedRealtimeMs * 1000) / 1000; 11628 if (bnMs > 0) { 11629 u.mWifiBatchedScanTimer[bn].setMark(elapsedRealtimeMs); 11630 } 11631 uidBatchScanMs += bnMs; 11632 } 11633 } 11634 11635 uidEstimatedConsumptionMah.add(u.getUid(), 11636 mWifiPowerCalculator.calcPowerWithoutControllerDataMah( 11637 entry.rxPackets, entry.txPackets, 11638 uidRunningMs, uidScanMs, uidBatchScanMs)); 11639 } 11640 } 11641 mNetworkStatsPool.release(delta); 11642 delta = null; 11643 } 11644 11645 if (info != null) { 11646 mHasWifiReporting = true; 11647 11648 // Measured in mAms 11649 final long txTimeMs = info.getControllerTxDurationMillis(); 11650 final long rxTimeMs = info.getControllerRxDurationMillis(); 11651 final long scanTimeMs = info.getControllerScanDurationMillis(); 11652 final long idleTimeMs = info.getControllerIdleDurationMillis(); 11653 final long totalTimeMs = txTimeMs + rxTimeMs + idleTimeMs; 11654 11655 long leftOverRxTimeMs = rxTimeMs; 11656 long leftOverTxTimeMs = txTimeMs; 11657 11658 if (DEBUG_ENERGY) { 11659 Slog.d(TAG, "------ BEGIN WiFi power blaming ------"); 11660 Slog.d(TAG, " Tx Time: " + txTimeMs + " ms"); 11661 Slog.d(TAG, " Rx Time: " + rxTimeMs + " ms"); 11662 Slog.d(TAG, " Idle Time: " + idleTimeMs + " ms"); 11663 Slog.d(TAG, " Total Time: " + totalTimeMs + " ms"); 11664 Slog.d(TAG, " Scan Time: " + scanTimeMs + " ms"); 11665 } 11666 11667 long totalWifiLockTimeMs = 0; 11668 long totalScanTimeMs = 0; 11669 11670 // On the first pass, collect some totals so that we can normalize power 11671 // calculations if we need to. 11672 final int uidStatsSize = mUidStats.size(); 11673 for (int i = 0; i < uidStatsSize; i++) { 11674 final Uid uid = mUidStats.valueAt(i); 11675 11676 // Sum the total scan power for all apps. 11677 totalScanTimeMs += uid.mWifiScanTimer.getTimeSinceMarkLocked( 11678 elapsedRealtimeMs * 1000) / 1000; 11679 11680 // Sum the total time holding wifi lock for all apps. 11681 totalWifiLockTimeMs += uid.mFullWifiLockTimer.getTimeSinceMarkLocked( 11682 elapsedRealtimeMs * 1000) / 1000; 11683 } 11684 11685 if (DEBUG_ENERGY && totalScanTimeMs > rxTimeMs) { 11686 Slog.d(TAG, 11687 " !Estimated scan time > Actual rx time (" + totalScanTimeMs + " ms > " 11688 + rxTimeMs + " ms). Normalizing scan time."); 11689 } 11690 if (DEBUG_ENERGY && totalScanTimeMs > txTimeMs) { 11691 Slog.d(TAG, 11692 " !Estimated scan time > Actual tx time (" + totalScanTimeMs + " ms > " 11693 + txTimeMs + " ms). Normalizing scan time."); 11694 } 11695 11696 // Actually assign and distribute power usage to apps. 11697 for (int i = 0; i < uidStatsSize; i++) { 11698 final Uid uid = mUidStats.valueAt(i); 11699 11700 final long scanTimeSinceMarkMs = uid.mWifiScanTimer.getTimeSinceMarkLocked( 11701 elapsedRealtimeMs * 1000) / 1000; 11702 long scanRxTimeSinceMarkMs = scanTimeSinceMarkMs; // not final 11703 long scanTxTimeSinceMarkMs = scanTimeSinceMarkMs; // not final 11704 if (scanTimeSinceMarkMs > 0) { 11705 // Set the new mark so that next time we get new data since this point. 11706 uid.mWifiScanTimer.setMark(elapsedRealtimeMs); 11707 11708 // Our total scan time is more than the reported Tx/Rx time. 11709 // This is possible because the cost of a scan is approximate. 11710 // Let's normalize the result so that we evenly blame each app 11711 // scanning. 11712 // 11713 // This means that we may have apps that transmitted/received packets not be 11714 // blamed for this, but this is fine as scans are relatively more expensive. 11715 if (totalScanTimeMs > rxTimeMs) { 11716 scanRxTimeSinceMarkMs = (rxTimeMs * scanRxTimeSinceMarkMs) / 11717 totalScanTimeMs; 11718 } 11719 if (totalScanTimeMs > txTimeMs) { 11720 scanTxTimeSinceMarkMs = (txTimeMs * scanTxTimeSinceMarkMs) / 11721 totalScanTimeMs; 11722 } 11723 11724 if (DEBUG_ENERGY) { 11725 Slog.d(TAG, " ScanTime for UID " + uid.getUid() + ": Rx:" 11726 + scanRxTimeSinceMarkMs + " ms Tx:" 11727 + scanTxTimeSinceMarkMs + " ms)"); 11728 } 11729 11730 ControllerActivityCounterImpl activityCounter = 11731 uid.getOrCreateWifiControllerActivityLocked(); 11732 activityCounter.getRxTimeCounter().addCountLocked(scanRxTimeSinceMarkMs); 11733 activityCounter.getTxTimeCounters()[0].addCountLocked( 11734 scanTxTimeSinceMarkMs); 11735 leftOverRxTimeMs -= scanRxTimeSinceMarkMs; 11736 leftOverTxTimeMs -= scanTxTimeSinceMarkMs; 11737 } 11738 11739 // Distribute evenly the power consumed while Idle to each app holding a WiFi 11740 // lock. 11741 long myIdleTimeMs = 0; 11742 final long wifiLockTimeSinceMarkMs = 11743 uid.mFullWifiLockTimer.getTimeSinceMarkLocked( 11744 elapsedRealtimeMs * 1000) / 1000; 11745 if (wifiLockTimeSinceMarkMs > 0) { 11746 // Set the new mark so that next time we get new data since this point. 11747 uid.mFullWifiLockTimer.setMark(elapsedRealtimeMs); 11748 11749 myIdleTimeMs = (wifiLockTimeSinceMarkMs * idleTimeMs) / totalWifiLockTimeMs; 11750 if (DEBUG_ENERGY) { 11751 Slog.d(TAG, " IdleTime for UID " + uid.getUid() + ": " 11752 + myIdleTimeMs + " ms"); 11753 } 11754 uid.getOrCreateWifiControllerActivityLocked().getIdleTimeCounter() 11755 .addCountLocked(myIdleTimeMs); 11756 } 11757 11758 if (uidEstimatedConsumptionMah != null) { 11759 double uidEstMah = mWifiPowerCalculator.calcPowerFromControllerDataMah( 11760 scanRxTimeSinceMarkMs, scanTxTimeSinceMarkMs, myIdleTimeMs); 11761 uidEstimatedConsumptionMah.add(uid.getUid(), uidEstMah); 11762 } 11763 } 11764 11765 if (DEBUG_ENERGY) { 11766 Slog.d(TAG, " New RxPower: " + leftOverRxTimeMs + " ms"); 11767 Slog.d(TAG, " New TxPower: " + leftOverTxTimeMs + " ms"); 11768 } 11769 11770 // Distribute the remaining Tx power appropriately between all apps that transmitted 11771 // packets. 11772 for (int i = 0; i < txPackets.size(); i++) { 11773 final Uid uid = getUidStatsLocked(txPackets.keyAt(i), 11774 elapsedRealtimeMs, uptimeMs); 11775 final long myTxTimeMs = (txPackets.valueAt(i) * leftOverTxTimeMs) 11776 / totalTxPackets; 11777 if (DEBUG_ENERGY) { 11778 Slog.d(TAG, " TxTime for UID " + uid.getUid() + ": " + myTxTimeMs + " ms"); 11779 } 11780 uid.getOrCreateWifiControllerActivityLocked().getTxTimeCounters()[0] 11781 .addCountLocked(myTxTimeMs); 11782 if (uidEstimatedConsumptionMah != null) { 11783 uidEstimatedConsumptionMah.add(uid.getUid(), 11784 mWifiPowerCalculator.calcPowerFromControllerDataMah( 11785 0, myTxTimeMs, 0)); 11786 } 11787 } 11788 11789 // Distribute the remaining Rx power appropriately between all apps that received 11790 // packets. 11791 for (int i = 0; i < rxPackets.size(); i++) { 11792 final Uid uid = getUidStatsLocked(rxPackets.keyAt(i), 11793 elapsedRealtimeMs, uptimeMs); 11794 final long myRxTimeMs = (rxPackets.valueAt(i) * leftOverRxTimeMs) 11795 / totalRxPackets; 11796 if (DEBUG_ENERGY) { 11797 Slog.d(TAG, " RxTime for UID " + uid.getUid() + ": " + myRxTimeMs + " ms"); 11798 } 11799 uid.getOrCreateWifiControllerActivityLocked().getRxTimeCounter() 11800 .addCountLocked(myRxTimeMs); 11801 if (uidEstimatedConsumptionMah != null) { 11802 uidEstimatedConsumptionMah.add(uid.getUid(), 11803 mWifiPowerCalculator.calcPowerFromControllerDataMah( 11804 myRxTimeMs, 0, 0)); 11805 } 11806 } 11807 11808 // Any left over power use will be picked up by the WiFi category in BatteryStatsHelper. 11809 11810 11811 // Update WiFi controller stats. 11812 mWifiActivity.getRxTimeCounter().addCountLocked( 11813 info.getControllerRxDurationMillis()); 11814 mWifiActivity.getTxTimeCounters()[0].addCountLocked( 11815 info.getControllerTxDurationMillis()); 11816 mWifiActivity.getScanTimeCounter().addCountLocked( 11817 info.getControllerScanDurationMillis()); 11818 mWifiActivity.getIdleTimeCounter().addCountLocked( 11819 info.getControllerIdleDurationMillis()); 11820 11821 // POWER_WIFI_CONTROLLER_OPERATING_VOLTAGE is measured in mV, so convert to V. 11822 final double opVolt = mPowerProfile.getAveragePower( 11823 PowerProfile.POWER_WIFI_CONTROLLER_OPERATING_VOLTAGE) / 1000.0; 11824 double controllerMaMs = 0; 11825 if (opVolt != 0) { 11826 // We store the power drain as mAms. 11827 controllerMaMs = info.getControllerEnergyUsedMicroJoules() / opVolt; 11828 mWifiActivity.getPowerCounter().addCountLocked((long) controllerMaMs); 11829 } 11830 // Converting uWs to mAms. 11831 // Conversion: (uWs * (1000ms / 1s) * (1mW / 1000uW)) / mV = mAms 11832 long monitoredRailChargeConsumedMaMs = 11833 (long) (mTmpRailStats.getWifiTotalEnergyUseduWs() / opVolt); 11834 mWifiActivity.getMonitoredRailChargeConsumedMaMs().addCountLocked( 11835 monitoredRailChargeConsumedMaMs); 11836 mHistoryCur.wifiRailChargeMah += 11837 (monitoredRailChargeConsumedMaMs / MILLISECONDS_IN_HOUR); 11838 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 11839 mTmpRailStats.resetWifiTotalEnergyUsed(); 11840 11841 if (uidEstimatedConsumptionMah != null) { 11842 totalEstimatedConsumptionMah = Math.max(controllerMaMs / MILLISECONDS_IN_HOUR, 11843 mWifiPowerCalculator.calcPowerFromControllerDataMah( 11844 rxTimeMs, txTimeMs, idleTimeMs)); 11845 } 11846 } 11847 11848 // Update the MeasuredEnergyStats information. 11849 if (uidEstimatedConsumptionMah != null) { 11850 mGlobalMeasuredEnergyStats.updateStandardBucket( 11851 MeasuredEnergyStats.POWER_BUCKET_WIFI, consumedChargeUC); 11852 11853 // Now calculate the consumption for each uid, according to its proportional usage. 11854 if (!mHasWifiReporting) { 11855 final long globalTimeMs = mGlobalWifiRunningTimer 11856 .getTimeSinceMarkLocked(elapsedRealtimeMs * 1000) / 1000; 11857 mGlobalWifiRunningTimer.setMark(elapsedRealtimeMs); 11858 totalEstimatedConsumptionMah = mWifiPowerCalculator 11859 .calcGlobalPowerWithoutControllerDataMah(globalTimeMs); 11860 } 11861 distributeEnergyToUidsLocked(MeasuredEnergyStats.POWER_BUCKET_WIFI, 11862 consumedChargeUC, uidEstimatedConsumptionMah, totalEstimatedConsumptionMah); 11863 } 11864 } 11865 } 11866 11867 private ModemActivityInfo mLastModemActivityInfo = null; 11868 11869 /** 11870 * Distribute Cell radio energy info and network traffic to apps. 11871 */ noteModemControllerActivity(@ullable final ModemActivityInfo activityInfo, final long consumedChargeUC, long elapsedRealtimeMs, long uptimeMs)11872 public void noteModemControllerActivity(@Nullable final ModemActivityInfo activityInfo, 11873 final long consumedChargeUC, long elapsedRealtimeMs, long uptimeMs) { 11874 if (DEBUG_ENERGY) { 11875 Slog.d(TAG, "Updating mobile radio stats with " + activityInfo); 11876 } 11877 ModemActivityInfo deltaInfo = mLastModemActivityInfo == null ? activityInfo 11878 : mLastModemActivityInfo.getDelta(activityInfo); 11879 mLastModemActivityInfo = activityInfo; 11880 11881 // Add modem tx power to history. 11882 addModemTxPowerToHistory(deltaInfo, elapsedRealtimeMs, uptimeMs); 11883 11884 // Grab a separate lock to acquire the network stats, which may do I/O. 11885 NetworkStats delta = null; 11886 synchronized (mModemNetworkLock) { 11887 final NetworkStats latestStats = readNetworkStatsLocked(mModemIfaces); 11888 if (latestStats != null) { 11889 delta = NetworkStats.subtract(latestStats, mLastModemNetworkStats, null, null, 11890 mNetworkStatsPool.acquire()); 11891 mNetworkStatsPool.release(mLastModemNetworkStats); 11892 mLastModemNetworkStats = latestStats; 11893 } 11894 } 11895 11896 synchronized (this) { 11897 if (!mOnBatteryInternal || mIgnoreNextExternalStats) { 11898 if (delta != null) { 11899 mNetworkStatsPool.release(delta); 11900 } 11901 return; 11902 } 11903 11904 final SparseDoubleArray uidEstimatedConsumptionMah; 11905 if (consumedChargeUC > 0 && mMobileRadioPowerCalculator != null 11906 && mGlobalMeasuredEnergyStats != null) { 11907 mGlobalMeasuredEnergyStats.updateStandardBucket( 11908 MeasuredEnergyStats.POWER_BUCKET_MOBILE_RADIO, consumedChargeUC); 11909 uidEstimatedConsumptionMah = new SparseDoubleArray(); 11910 } else { 11911 uidEstimatedConsumptionMah = null; 11912 } 11913 11914 if (deltaInfo != null) { 11915 mHasModemReporting = true; 11916 mModemActivity.getIdleTimeCounter().addCountLocked( 11917 deltaInfo.getIdleTimeMillis()); 11918 mModemActivity.getSleepTimeCounter().addCountLocked( 11919 deltaInfo.getSleepTimeMillis()); 11920 mModemActivity.getRxTimeCounter().addCountLocked(deltaInfo.getReceiveTimeMillis()); 11921 for (int lvl = 0; lvl < ModemActivityInfo.getNumTxPowerLevels(); lvl++) { 11922 mModemActivity.getTxTimeCounters()[lvl] 11923 .addCountLocked(deltaInfo.getTransmitDurationMillisAtPowerLevel(lvl)); 11924 } 11925 11926 // POWER_MODEM_CONTROLLER_OPERATING_VOLTAGE is measured in mV, so convert to V. 11927 final double opVolt = mPowerProfile.getAveragePower( 11928 PowerProfile.POWER_MODEM_CONTROLLER_OPERATING_VOLTAGE) / 1000.0; 11929 if (opVolt != 0) { 11930 double energyUsed = 11931 deltaInfo.getSleepTimeMillis() * 11932 mPowerProfile.getAveragePower(PowerProfile.POWER_MODEM_CONTROLLER_SLEEP) 11933 + deltaInfo.getIdleTimeMillis() * 11934 mPowerProfile.getAveragePower(PowerProfile.POWER_MODEM_CONTROLLER_IDLE) 11935 + deltaInfo.getReceiveTimeMillis() * 11936 mPowerProfile.getAveragePower(PowerProfile.POWER_MODEM_CONTROLLER_RX); 11937 for (int i = 0; i < Math.min(ModemActivityInfo.getNumTxPowerLevels(), 11938 CellSignalStrength.getNumSignalStrengthLevels()); i++) { 11939 energyUsed += deltaInfo.getTransmitDurationMillisAtPowerLevel(i) 11940 * mPowerProfile.getAveragePower( 11941 PowerProfile.POWER_MODEM_CONTROLLER_TX, i); 11942 } 11943 11944 // We store the power drain as mAms. 11945 mModemActivity.getPowerCounter().addCountLocked((long) energyUsed); 11946 // Converting uWs to mAms. 11947 // Conversion: (uWs * (1000ms / 1s) * (1mW / 1000uW)) / mV = mAms 11948 long monitoredRailChargeConsumedMaMs = 11949 (long) (mTmpRailStats.getCellularTotalEnergyUseduWs() / opVolt); 11950 mModemActivity.getMonitoredRailChargeConsumedMaMs().addCountLocked( 11951 monitoredRailChargeConsumedMaMs); 11952 mHistoryCur.modemRailChargeMah += 11953 (monitoredRailChargeConsumedMaMs / MILLISECONDS_IN_HOUR); 11954 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 11955 mTmpRailStats.resetCellularTotalEnergyUsed(); 11956 } 11957 } 11958 long totalAppRadioTimeUs = mMobileRadioActivePerAppTimer.getTimeSinceMarkLocked( 11959 elapsedRealtimeMs * 1000); 11960 mMobileRadioActivePerAppTimer.setMark(elapsedRealtimeMs); 11961 11962 long totalRxPackets = 0; 11963 long totalTxPackets = 0; 11964 if (delta != null) { 11965 NetworkStats.Entry entry = new NetworkStats.Entry(); 11966 final int size = delta.size(); 11967 for (int i = 0; i < size; i++) { 11968 entry = delta.getValues(i, entry); 11969 if (entry.rxPackets == 0 && entry.txPackets == 0) { 11970 continue; 11971 } 11972 11973 if (DEBUG_ENERGY) { 11974 Slog.d(TAG, "Mobile uid " + entry.uid + ": delta rx=" + entry.rxBytes 11975 + " tx=" + entry.txBytes + " rxPackets=" + entry.rxPackets 11976 + " txPackets=" + entry.txPackets); 11977 } 11978 11979 totalRxPackets += entry.rxPackets; 11980 totalTxPackets += entry.txPackets; 11981 11982 final Uid u = getUidStatsLocked(mapUid(entry.uid), elapsedRealtimeMs, uptimeMs); 11983 u.noteNetworkActivityLocked(NETWORK_MOBILE_RX_DATA, entry.rxBytes, 11984 entry.rxPackets); 11985 u.noteNetworkActivityLocked(NETWORK_MOBILE_TX_DATA, entry.txBytes, 11986 entry.txPackets); 11987 if (entry.set == NetworkStats.SET_DEFAULT) { // Background transfers 11988 u.noteNetworkActivityLocked(NETWORK_MOBILE_BG_RX_DATA, 11989 entry.rxBytes, entry.rxPackets); 11990 u.noteNetworkActivityLocked(NETWORK_MOBILE_BG_TX_DATA, 11991 entry.txBytes, entry.txPackets); 11992 } 11993 11994 mNetworkByteActivityCounters[NETWORK_MOBILE_RX_DATA].addCountLocked( 11995 entry.rxBytes); 11996 mNetworkByteActivityCounters[NETWORK_MOBILE_TX_DATA].addCountLocked( 11997 entry.txBytes); 11998 mNetworkPacketActivityCounters[NETWORK_MOBILE_RX_DATA].addCountLocked( 11999 entry.rxPackets); 12000 mNetworkPacketActivityCounters[NETWORK_MOBILE_TX_DATA].addCountLocked( 12001 entry.txPackets); 12002 } 12003 12004 // Now distribute proportional blame to the apps that did networking. 12005 long totalPackets = totalRxPackets + totalTxPackets; 12006 if (totalPackets > 0) { 12007 for (int i = 0; i < size; i++) { 12008 entry = delta.getValues(i, entry); 12009 if (entry.rxPackets == 0 && entry.txPackets == 0) { 12010 continue; 12011 } 12012 12013 final Uid u = getUidStatsLocked(mapUid(entry.uid), 12014 elapsedRealtimeMs, uptimeMs); 12015 12016 // Distribute total radio active time in to this app. 12017 final long appPackets = entry.rxPackets + entry.txPackets; 12018 final long appRadioTimeUs = 12019 (totalAppRadioTimeUs * appPackets) / totalPackets; 12020 u.noteMobileRadioActiveTimeLocked(appRadioTimeUs); 12021 12022 // Distribute measured mobile radio charge consumption based on app radio 12023 // active time 12024 if (uidEstimatedConsumptionMah != null) { 12025 uidEstimatedConsumptionMah.add(u.getUid(), 12026 mMobileRadioPowerCalculator.calcPowerFromRadioActiveDurationMah( 12027 appRadioTimeUs / 1000)); 12028 } 12029 12030 // Remove this app from the totals, so that we don't lose any time 12031 // due to rounding. 12032 totalAppRadioTimeUs -= appRadioTimeUs; 12033 totalPackets -= appPackets; 12034 12035 if (deltaInfo != null) { 12036 ControllerActivityCounterImpl activityCounter = 12037 u.getOrCreateModemControllerActivityLocked(); 12038 if (totalRxPackets > 0 && entry.rxPackets > 0) { 12039 final long rxMs = (entry.rxPackets 12040 * deltaInfo.getReceiveTimeMillis()) / totalRxPackets; 12041 activityCounter.getRxTimeCounter().addCountLocked(rxMs); 12042 } 12043 12044 if (totalTxPackets > 0 && entry.txPackets > 0) { 12045 for (int lvl = 0; lvl < ModemActivityInfo.getNumTxPowerLevels(); 12046 lvl++) { 12047 long txMs = entry.txPackets 12048 * deltaInfo.getTransmitDurationMillisAtPowerLevel(lvl); 12049 txMs /= totalTxPackets; 12050 activityCounter.getTxTimeCounters()[lvl].addCountLocked(txMs); 12051 } 12052 } 12053 } 12054 } 12055 } 12056 12057 if (totalAppRadioTimeUs > 0) { 12058 // Whoops, there is some radio time we can't blame on an app! 12059 mMobileRadioActiveUnknownTime.addCountLocked(totalAppRadioTimeUs); 12060 mMobileRadioActiveUnknownCount.addCountLocked(1); 12061 } 12062 12063 12064 // Update the MeasuredEnergyStats information. 12065 if (uidEstimatedConsumptionMah != null) { 12066 double totalEstimatedConsumptionMah = 0.0; 12067 12068 // Estimate total active radio power consumption since last mark. 12069 final long totalRadioTimeMs = mMobileRadioActiveTimer.getTimeSinceMarkLocked( 12070 elapsedRealtimeMs * 1000) / 1000; 12071 mMobileRadioActiveTimer.setMark(elapsedRealtimeMs); 12072 totalEstimatedConsumptionMah += 12073 mMobileRadioPowerCalculator.calcPowerFromRadioActiveDurationMah( 12074 totalRadioTimeMs); 12075 12076 // Estimate idle power consumption at each signal strength level 12077 final int numSignalStrengthLevels = mPhoneSignalStrengthsTimer.length; 12078 for (int strengthLevel = 0; strengthLevel < numSignalStrengthLevels; 12079 strengthLevel++) { 12080 final long strengthLevelDurationMs = 12081 mPhoneSignalStrengthsTimer[strengthLevel].getTimeSinceMarkLocked( 12082 elapsedRealtimeMs * 1000) / 1000; 12083 mPhoneSignalStrengthsTimer[strengthLevel].setMark(elapsedRealtimeMs); 12084 12085 totalEstimatedConsumptionMah += 12086 mMobileRadioPowerCalculator.calcIdlePowerAtSignalStrengthMah( 12087 strengthLevelDurationMs, strengthLevel); 12088 } 12089 12090 // Estimate total active radio power consumption since last mark. 12091 final long scanTimeMs = mPhoneSignalScanningTimer.getTimeSinceMarkLocked( 12092 elapsedRealtimeMs * 1000) / 1000; 12093 mPhoneSignalScanningTimer.setMark(elapsedRealtimeMs); 12094 totalEstimatedConsumptionMah += 12095 mMobileRadioPowerCalculator.calcScanTimePowerMah(scanTimeMs); 12096 12097 distributeEnergyToUidsLocked(MeasuredEnergyStats.POWER_BUCKET_MOBILE_RADIO, 12098 consumedChargeUC, uidEstimatedConsumptionMah, 12099 totalEstimatedConsumptionMah); 12100 } 12101 12102 mNetworkStatsPool.release(delta); 12103 delta = null; 12104 } 12105 } 12106 } 12107 12108 /** 12109 * Add modem tx power to history 12110 * Device is said to be in high cellular transmit power when it has spent most of the transmit 12111 * time at the highest power level. 12112 * @param activityInfo 12113 */ addModemTxPowerToHistory(final ModemActivityInfo activityInfo, long elapsedRealtimeMs, long uptimeMs)12114 private synchronized void addModemTxPowerToHistory(final ModemActivityInfo activityInfo, 12115 long elapsedRealtimeMs, long uptimeMs) { 12116 if (activityInfo == null) { 12117 return; 12118 } 12119 int levelMaxTimeSpent = 0; 12120 for (int i = 1; i < ModemActivityInfo.getNumTxPowerLevels(); i++) { 12121 if (activityInfo.getTransmitDurationMillisAtPowerLevel(i) 12122 > activityInfo.getTransmitDurationMillisAtPowerLevel(levelMaxTimeSpent)) { 12123 levelMaxTimeSpent = i; 12124 } 12125 } 12126 if (levelMaxTimeSpent == ModemActivityInfo.getNumTxPowerLevels() - 1) { 12127 mHistoryCur.states2 |= HistoryItem.STATE2_CELLULAR_HIGH_TX_POWER_FLAG; 12128 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 12129 } 12130 } 12131 12132 private final class BluetoothActivityInfoCache { 12133 long idleTimeMs; 12134 long rxTimeMs; 12135 long txTimeMs; 12136 long energy; 12137 12138 SparseLongArray uidRxBytes = new SparseLongArray(); 12139 SparseLongArray uidTxBytes = new SparseLongArray(); 12140 set(BluetoothActivityEnergyInfo info)12141 void set(BluetoothActivityEnergyInfo info) { 12142 idleTimeMs = info.getControllerIdleTimeMillis(); 12143 rxTimeMs = info.getControllerRxTimeMillis(); 12144 txTimeMs = info.getControllerTxTimeMillis(); 12145 energy = info.getControllerEnergyUsed(); 12146 if (info.getUidTraffic() != null) { 12147 for (UidTraffic traffic : info.getUidTraffic()) { 12148 uidRxBytes.put(traffic.getUid(), traffic.getRxBytes()); 12149 uidTxBytes.put(traffic.getUid(), traffic.getTxBytes()); 12150 } 12151 } 12152 } 12153 reset()12154 void reset() { 12155 idleTimeMs = 0; 12156 rxTimeMs = 0; 12157 txTimeMs = 0; 12158 energy = 0; 12159 uidRxBytes.clear(); 12160 uidTxBytes.clear(); 12161 } 12162 } 12163 12164 private final BluetoothActivityInfoCache mLastBluetoothActivityInfo 12165 = new BluetoothActivityInfoCache(); 12166 12167 /** 12168 * Distribute Bluetooth energy info and network traffic to apps. 12169 * 12170 * @param info The accumulated energy information from the bluetooth controller. 12171 */ updateBluetoothStateLocked(@ullable final BluetoothActivityEnergyInfo info, final long consumedChargeUC, long elapsedRealtimeMs, long uptimeMs)12172 public void updateBluetoothStateLocked(@Nullable final BluetoothActivityEnergyInfo info, 12173 final long consumedChargeUC, long elapsedRealtimeMs, long uptimeMs) { 12174 if (DEBUG_ENERGY) { 12175 Slog.d(TAG, "Updating bluetooth stats: " + info); 12176 } 12177 12178 if (info == null) { 12179 return; 12180 } 12181 if (!mOnBatteryInternal || mIgnoreNextExternalStats) { 12182 mLastBluetoothActivityInfo.set(info); 12183 return; 12184 } 12185 12186 mHasBluetoothReporting = true; 12187 12188 if (info.getControllerRxTimeMillis() < mLastBluetoothActivityInfo.rxTimeMs 12189 || info.getControllerTxTimeMillis() < mLastBluetoothActivityInfo.txTimeMs 12190 || info.getControllerIdleTimeMillis() < mLastBluetoothActivityInfo.idleTimeMs 12191 || info.getControllerEnergyUsed() < mLastBluetoothActivityInfo.energy) { 12192 // A drop in accumulated Bluetooth stats is a sign of a Bluetooth crash. 12193 // Reset the preserved previous snapshot in order to restart accumulating deltas. 12194 mLastBluetoothActivityInfo.reset(); 12195 } 12196 12197 final long rxTimeMs = 12198 info.getControllerRxTimeMillis() - mLastBluetoothActivityInfo.rxTimeMs; 12199 final long txTimeMs = 12200 info.getControllerTxTimeMillis() - mLastBluetoothActivityInfo.txTimeMs; 12201 final long idleTimeMs = 12202 info.getControllerIdleTimeMillis() - mLastBluetoothActivityInfo.idleTimeMs; 12203 12204 if (DEBUG_ENERGY) { 12205 Slog.d(TAG, "------ BEGIN BLE power blaming ------"); 12206 Slog.d(TAG, " Tx Time: " + txTimeMs + " ms"); 12207 Slog.d(TAG, " Rx Time: " + rxTimeMs + " ms"); 12208 Slog.d(TAG, " Idle Time: " + idleTimeMs + " ms"); 12209 } 12210 12211 final SparseDoubleArray uidEstimatedConsumptionMah = 12212 (mGlobalMeasuredEnergyStats != null 12213 && mBluetoothPowerCalculator != null && consumedChargeUC > 0) ? 12214 new SparseDoubleArray() : null; 12215 12216 long totalScanTimeMs = 0; 12217 12218 final int uidCount = mUidStats.size(); 12219 for (int i = 0; i < uidCount; i++) { 12220 final Uid u = mUidStats.valueAt(i); 12221 if (u.mBluetoothScanTimer == null) { 12222 continue; 12223 } 12224 12225 totalScanTimeMs += u.mBluetoothScanTimer.getTimeSinceMarkLocked( 12226 elapsedRealtimeMs * 1000) / 1000; 12227 } 12228 12229 final boolean normalizeScanRxTime = (totalScanTimeMs > rxTimeMs); 12230 final boolean normalizeScanTxTime = (totalScanTimeMs > txTimeMs); 12231 12232 if (DEBUG_ENERGY) { 12233 Slog.d(TAG, "Normalizing scan power for RX=" + normalizeScanRxTime 12234 + " TX=" + normalizeScanTxTime); 12235 } 12236 12237 long leftOverRxTimeMs = rxTimeMs; 12238 long leftOverTxTimeMs = txTimeMs; 12239 12240 for (int i = 0; i < uidCount; i++) { 12241 final Uid u = mUidStats.valueAt(i); 12242 if (u.mBluetoothScanTimer == null) { 12243 continue; 12244 } 12245 12246 long scanTimeSinceMarkMs = u.mBluetoothScanTimer.getTimeSinceMarkLocked( 12247 elapsedRealtimeMs * 1000) / 1000; 12248 if (scanTimeSinceMarkMs > 0) { 12249 // Set the new mark so that next time we get new data since this point. 12250 u.mBluetoothScanTimer.setMark(elapsedRealtimeMs); 12251 12252 long scanTimeRxSinceMarkMs = scanTimeSinceMarkMs; 12253 long scanTimeTxSinceMarkMs = scanTimeSinceMarkMs; 12254 12255 if (normalizeScanRxTime) { 12256 // Scan time is longer than the total rx time in the controller, 12257 // so distribute the scan time proportionately. This means regular traffic 12258 // will not blamed, but scans are more expensive anyways. 12259 scanTimeRxSinceMarkMs = (rxTimeMs * scanTimeRxSinceMarkMs) / totalScanTimeMs; 12260 } 12261 12262 if (normalizeScanTxTime) { 12263 // Scan time is longer than the total tx time in the controller, 12264 // so distribute the scan time proportionately. This means regular traffic 12265 // will not blamed, but scans are more expensive anyways. 12266 scanTimeTxSinceMarkMs = (txTimeMs * scanTimeTxSinceMarkMs) / totalScanTimeMs; 12267 } 12268 12269 final ControllerActivityCounterImpl counter = 12270 u.getOrCreateBluetoothControllerActivityLocked(); 12271 counter.getRxTimeCounter().addCountLocked(scanTimeRxSinceMarkMs); 12272 counter.getTxTimeCounters()[0].addCountLocked(scanTimeTxSinceMarkMs); 12273 12274 if (uidEstimatedConsumptionMah != null) { 12275 uidEstimatedConsumptionMah.add(u.getUid(), 12276 mBluetoothPowerCalculator.calculatePowerMah( 12277 scanTimeRxSinceMarkMs, scanTimeTxSinceMarkMs, 0)); 12278 } 12279 12280 leftOverRxTimeMs -= scanTimeRxSinceMarkMs; 12281 leftOverTxTimeMs -= scanTimeTxSinceMarkMs; 12282 } 12283 } 12284 12285 if (DEBUG_ENERGY) { 12286 Slog.d(TAG, "Left over time for traffic RX=" + leftOverRxTimeMs + " TX=" 12287 + leftOverTxTimeMs); 12288 } 12289 12290 // 12291 // Now distribute blame to apps that did bluetooth traffic. 12292 // 12293 12294 long totalTxBytes = 0; 12295 long totalRxBytes = 0; 12296 12297 final UidTraffic[] uidTraffic = info.getUidTraffic(); 12298 final int numUids = uidTraffic != null ? uidTraffic.length : 0; 12299 for (int i = 0; i < numUids; i++) { 12300 final UidTraffic traffic = uidTraffic[i]; 12301 final long rxBytes = traffic.getRxBytes() - mLastBluetoothActivityInfo.uidRxBytes.get( 12302 traffic.getUid()); 12303 final long txBytes = traffic.getTxBytes() - mLastBluetoothActivityInfo.uidTxBytes.get( 12304 traffic.getUid()); 12305 12306 // Add to the global counters. 12307 mNetworkByteActivityCounters[NETWORK_BT_RX_DATA].addCountLocked(rxBytes); 12308 mNetworkByteActivityCounters[NETWORK_BT_TX_DATA].addCountLocked(txBytes); 12309 12310 // Add to the UID counters. 12311 final Uid u = getUidStatsLocked(mapUid(traffic.getUid()), elapsedRealtimeMs, uptimeMs); 12312 u.noteNetworkActivityLocked(NETWORK_BT_RX_DATA, rxBytes, 0); 12313 u.noteNetworkActivityLocked(NETWORK_BT_TX_DATA, txBytes, 0); 12314 12315 // Calculate the total traffic. 12316 totalRxBytes += rxBytes; 12317 totalTxBytes += txBytes; 12318 } 12319 12320 if ((totalTxBytes != 0 || totalRxBytes != 0) && (leftOverRxTimeMs != 0 12321 || leftOverTxTimeMs != 0)) { 12322 for (int i = 0; i < numUids; i++) { 12323 final UidTraffic traffic = uidTraffic[i]; 12324 final int uid = traffic.getUid(); 12325 final long rxBytes = 12326 traffic.getRxBytes() - mLastBluetoothActivityInfo.uidRxBytes.get(uid); 12327 final long txBytes = 12328 traffic.getTxBytes() - mLastBluetoothActivityInfo.uidTxBytes.get(uid); 12329 12330 final Uid u = getUidStatsLocked(mapUid(uid), elapsedRealtimeMs, uptimeMs); 12331 final ControllerActivityCounterImpl counter = 12332 u.getOrCreateBluetoothControllerActivityLocked(); 12333 12334 if (totalRxBytes > 0 && rxBytes > 0) { 12335 final long timeRxMs = (leftOverRxTimeMs * rxBytes) / totalRxBytes; 12336 if (DEBUG_ENERGY) { 12337 Slog.d(TAG, "UID=" + uid + " rx_bytes=" + rxBytes + " rx_time=" + timeRxMs); 12338 } 12339 counter.getRxTimeCounter().addCountLocked(timeRxMs); 12340 12341 if (uidEstimatedConsumptionMah != null) { 12342 uidEstimatedConsumptionMah.add(u.getUid(), 12343 mBluetoothPowerCalculator.calculatePowerMah(timeRxMs, 0, 0)); 12344 } 12345 } 12346 12347 if (totalTxBytes > 0 && txBytes > 0) { 12348 final long timeTxMs = (leftOverTxTimeMs * txBytes) / totalTxBytes; 12349 if (DEBUG_ENERGY) { 12350 Slog.d(TAG, "UID=" + uid + " tx_bytes=" + txBytes + " tx_time=" + timeTxMs); 12351 } 12352 counter.getTxTimeCounters()[0].addCountLocked(timeTxMs); 12353 12354 if (uidEstimatedConsumptionMah != null) { 12355 uidEstimatedConsumptionMah.add(u.getUid(), 12356 mBluetoothPowerCalculator.calculatePowerMah(0, timeTxMs, 0)); 12357 } 12358 } 12359 } 12360 } 12361 12362 mBluetoothActivity.getRxTimeCounter().addCountLocked(rxTimeMs); 12363 mBluetoothActivity.getTxTimeCounters()[0].addCountLocked(txTimeMs); 12364 mBluetoothActivity.getIdleTimeCounter().addCountLocked(idleTimeMs); 12365 12366 // POWER_BLUETOOTH_CONTROLLER_OPERATING_VOLTAGE is measured in mV, so convert to V. 12367 final double opVolt = mPowerProfile.getAveragePower( 12368 PowerProfile.POWER_BLUETOOTH_CONTROLLER_OPERATING_VOLTAGE) / 1000.0; 12369 double controllerMaMs = 0; 12370 if (opVolt != 0) { 12371 controllerMaMs = (info.getControllerEnergyUsed() - mLastBluetoothActivityInfo.energy) 12372 / opVolt; 12373 // We store the power drain as mAms. 12374 mBluetoothActivity.getPowerCounter().addCountLocked((long) controllerMaMs); 12375 } 12376 12377 // Update the MeasuredEnergyStats information. 12378 if (uidEstimatedConsumptionMah != null) { 12379 mGlobalMeasuredEnergyStats.updateStandardBucket( 12380 MeasuredEnergyStats.POWER_BUCKET_BLUETOOTH, consumedChargeUC); 12381 12382 double totalEstimatedMah 12383 = mBluetoothPowerCalculator.calculatePowerMah(rxTimeMs, txTimeMs, idleTimeMs); 12384 totalEstimatedMah = Math.max(totalEstimatedMah, controllerMaMs / MILLISECONDS_IN_HOUR); 12385 distributeEnergyToUidsLocked(MeasuredEnergyStats.POWER_BUCKET_BLUETOOTH, 12386 consumedChargeUC, uidEstimatedConsumptionMah, totalEstimatedMah); 12387 } 12388 12389 mLastBluetoothActivityInfo.set(info); 12390 } 12391 /** 12392 * Read Resource Power Manager (RPM) state and voter times. 12393 * If RPM stats were fetched more recently than RPM_STATS_UPDATE_FREQ_MS ago, uses the old data 12394 * instead of fetching it anew. 12395 * 12396 * Note: This should be called without synchronizing this BatteryStatsImpl object 12397 */ fillLowPowerStats()12398 public void fillLowPowerStats() { 12399 if (mPlatformIdleStateCallback == null) return; 12400 12401 RpmStats rpmStats = new RpmStats(); 12402 long now = SystemClock.elapsedRealtime(); 12403 if (now - mLastRpmStatsUpdateTimeMs >= RPM_STATS_UPDATE_FREQ_MS) { 12404 mPlatformIdleStateCallback.fillLowPowerStats(rpmStats); 12405 synchronized (this) { 12406 mTmpRpmStats = rpmStats; 12407 mLastRpmStatsUpdateTimeMs = now; 12408 } 12409 } 12410 } 12411 12412 /** 12413 * Record Resource Power Manager (RPM) state and voter times. 12414 * TODO(b/185252376): Remove this logging. PowerStatsService logs the same data more 12415 * efficiently. 12416 */ updateRpmStatsLocked(long elapsedRealtimeUs)12417 public void updateRpmStatsLocked(long elapsedRealtimeUs) { 12418 if (mTmpRpmStats == null) return; 12419 12420 for (Map.Entry<String, RpmStats.PowerStatePlatformSleepState> pstate 12421 : mTmpRpmStats.mPlatformLowPowerStats.entrySet()) { 12422 12423 // Update values for this platform state. 12424 final String pName = pstate.getKey(); 12425 final long pTimeUs = pstate.getValue().mTimeMs * 1000; 12426 final int pCount = pstate.getValue().mCount; 12427 getRpmTimerLocked(pName).update(pTimeUs, pCount, elapsedRealtimeUs); 12428 if (SCREEN_OFF_RPM_STATS_ENABLED) { 12429 getScreenOffRpmTimerLocked(pName).update(pTimeUs, pCount, elapsedRealtimeUs); 12430 } 12431 12432 // Update values for each voter of this platform state. 12433 for (Map.Entry<String, RpmStats.PowerStateElement> voter 12434 : pstate.getValue().mVoters.entrySet()) { 12435 final String vName = pName + "." + voter.getKey(); 12436 final long vTimeUs = voter.getValue().mTimeMs * 1000; 12437 final int vCount = voter.getValue().mCount; 12438 getRpmTimerLocked(vName).update(vTimeUs, vCount, elapsedRealtimeUs); 12439 if (SCREEN_OFF_RPM_STATS_ENABLED) { 12440 getScreenOffRpmTimerLocked(vName).update(vTimeUs, vCount, elapsedRealtimeUs); 12441 } 12442 } 12443 } 12444 12445 for (Map.Entry<String, RpmStats.PowerStateSubsystem> subsys 12446 : mTmpRpmStats.mSubsystemLowPowerStats.entrySet()) { 12447 12448 final String subsysName = subsys.getKey(); 12449 for (Map.Entry<String, RpmStats.PowerStateElement> sstate 12450 : subsys.getValue().mStates.entrySet()) { 12451 final String name = subsysName + "." + sstate.getKey(); 12452 final long timeUs = sstate.getValue().mTimeMs * 1000; 12453 final int count = sstate.getValue().mCount; 12454 getRpmTimerLocked(name).update(timeUs, count, elapsedRealtimeUs); 12455 if (SCREEN_OFF_RPM_STATS_ENABLED) { 12456 getScreenOffRpmTimerLocked(name).update(timeUs, count, elapsedRealtimeUs); 12457 } 12458 } 12459 } 12460 } 12461 12462 /** 12463 * Accumulate Cpu charge consumption and distribute it to the correct state and the apps. 12464 * Only call if device is on battery. 12465 * 12466 * @param clusterChargeUC amount of charge (microcoulombs) consumed by each Cpu Cluster 12467 * @param accumulator collection of calculated uid cpu power consumption to smear 12468 * clusterChargeUC against. 12469 */ 12470 @GuardedBy("this") updateCpuMeasuredEnergyStatsLocked(@onNull long[] clusterChargeUC, @NonNull CpuDeltaPowerAccumulator accumulator)12471 private void updateCpuMeasuredEnergyStatsLocked(@NonNull long[] clusterChargeUC, 12472 @NonNull CpuDeltaPowerAccumulator accumulator) { 12473 if (DEBUG_ENERGY) { 12474 Slog.d(TAG, 12475 "Updating cpu cluster stats: " + clusterChargeUC.toString()); 12476 } 12477 if (mGlobalMeasuredEnergyStats == null) { 12478 return; 12479 } 12480 12481 final int numClusters = clusterChargeUC.length; 12482 long totalCpuChargeUC = 0; 12483 for (int i = 0; i < numClusters; i++) { 12484 totalCpuChargeUC += clusterChargeUC[i]; 12485 } 12486 if (totalCpuChargeUC <= 0) return; 12487 12488 mGlobalMeasuredEnergyStats.updateStandardBucket(MeasuredEnergyStats.POWER_BUCKET_CPU, 12489 totalCpuChargeUC); 12490 12491 // Calculate the measured microcoulombs/calculated milliamp-hour charge ratio for each 12492 // cluster to normalize each uid's estimated power usage against actual power usage for 12493 // a given cluster. 12494 final double[] clusterChargeRatio = new double[numClusters]; 12495 for (int cluster = 0; cluster < numClusters; cluster++) { 12496 12497 final double totalClusterChargeMah = accumulator.totalClusterChargesMah[cluster]; 12498 if (totalClusterChargeMah <= 0.0) { 12499 // This cluster did not have any work on it, since last update. 12500 // Avoid dividing by zero. 12501 clusterChargeRatio[cluster] = 0.0; 12502 } else { 12503 clusterChargeRatio[cluster] = 12504 clusterChargeUC[cluster] / accumulator.totalClusterChargesMah[cluster]; 12505 } 12506 } 12507 12508 // Assign and distribute power usage to apps based on their calculated cpu cluster charge. 12509 final long uidChargeArraySize = accumulator.perUidCpuClusterChargesMah.size(); 12510 for (int i = 0; i < uidChargeArraySize; i++) { 12511 final Uid uid = accumulator.perUidCpuClusterChargesMah.keyAt(i); 12512 final double[] uidClusterChargesMah = accumulator.perUidCpuClusterChargesMah.valueAt(i); 12513 12514 // Iterate each cpu cluster and sum the proportional measured cpu cluster charge to 12515 // get the total cpu charge consumed by a uid. 12516 long uidCpuChargeUC = 0; 12517 for (int cluster = 0; cluster < numClusters; cluster++) { 12518 final double uidClusterChargeMah = uidClusterChargesMah[cluster]; 12519 12520 // Proportionally allocate the measured cpu cluster charge to a uid using the 12521 // measured charge/calculated charge ratio. Add 0.5 to round the proportional 12522 // charge double to the nearest long value. 12523 final long uidClusterChargeUC = 12524 (long) (uidClusterChargeMah * clusterChargeRatio[cluster] 12525 + 0.5); 12526 12527 uidCpuChargeUC += uidClusterChargeUC; 12528 } 12529 12530 if (uidCpuChargeUC < 0) { 12531 Slog.wtf(TAG, 12532 "Unexpected proportional measured charge (" + uidCpuChargeUC + ") for uid " 12533 + uid.mUid); 12534 continue; 12535 } 12536 12537 uid.addChargeToStandardBucketLocked(uidCpuChargeUC, 12538 MeasuredEnergyStats.POWER_BUCKET_CPU); 12539 } 12540 } 12541 12542 /** 12543 * Accumulate Display charge consumption and distribute it to the correct state and the apps. 12544 * 12545 * NOTE: The algorithm used makes the strong assumption that app foreground activity time 12546 * is always 0 when the screen is not "ON" and whenever the rail energy is 0 (if supported). 12547 * To the extent that those assumptions are violated, the algorithm will err. 12548 * 12549 * @param chargeUC amount of charge (microcoulombs) used by Display since this was last called. 12550 * @param screenState screen state at the time this data collection was scheduled 12551 */ 12552 @GuardedBy("this") updateDisplayMeasuredEnergyStatsLocked(long chargeUC, int screenState, long elapsedRealtimeMs)12553 public void updateDisplayMeasuredEnergyStatsLocked(long chargeUC, int screenState, 12554 long elapsedRealtimeMs) { 12555 if (DEBUG_ENERGY) Slog.d(TAG, "Updating display stats: " + chargeUC); 12556 if (mGlobalMeasuredEnergyStats == null) { 12557 return; 12558 } 12559 12560 final @StandardPowerBucket int powerBucket = 12561 MeasuredEnergyStats.getDisplayPowerBucket(mScreenStateAtLastEnergyMeasurement); 12562 mScreenStateAtLastEnergyMeasurement = screenState; 12563 12564 if (!mOnBatteryInternal || chargeUC <= 0) { 12565 // There's nothing further to update. 12566 return; 12567 } 12568 if (mIgnoreNextExternalStats) { 12569 // Although under ordinary resets we won't get here, and typically a new sync will 12570 // happen right after the reset, strictly speaking we need to set all mark times to now. 12571 final int uidStatsSize = mUidStats.size(); 12572 for (int i = 0; i < uidStatsSize; i++) { 12573 final Uid uid = mUidStats.valueAt(i); 12574 uid.markProcessForegroundTimeUs(elapsedRealtimeMs, false); 12575 } 12576 return; 12577 } 12578 12579 mGlobalMeasuredEnergyStats.updateStandardBucket(powerBucket, chargeUC); 12580 12581 // Now we blame individual apps, but only if the display was ON. 12582 if (powerBucket != MeasuredEnergyStats.POWER_BUCKET_SCREEN_ON) { 12583 return; 12584 } 12585 // TODO(b/175726779): Consider unifying the code with the non-rail display power blaming. 12586 12587 // NOTE: fg time is NOT pooled. If two uids are both somehow in fg, then that time is 12588 // 'double counted' and will simply exceed the realtime that elapsed. 12589 // If multidisplay becomes a reality, this is probably more reasonable than pooling. 12590 12591 // Collect total time since mark so that we can normalize power. 12592 final SparseDoubleArray fgTimeUsArray = new SparseDoubleArray(); 12593 final long elapsedRealtimeUs = elapsedRealtimeMs * 1000; 12594 // TODO(b/175726779): Update and optimize the algorithm (e.g. avoid iterating over ALL uids) 12595 final int uidStatsSize = mUidStats.size(); 12596 for (int i = 0; i < uidStatsSize; i++) { 12597 final Uid uid = mUidStats.valueAt(i); 12598 final long fgTimeUs = uid.markProcessForegroundTimeUs(elapsedRealtimeMs, true); 12599 if (fgTimeUs == 0) continue; 12600 fgTimeUsArray.put(uid.getUid(), (double) fgTimeUs); 12601 } 12602 distributeEnergyToUidsLocked(powerBucket, chargeUC, fgTimeUsArray, 0); 12603 } 12604 12605 /** 12606 * Accumulate GNSS charge consumption and distribute it to the correct state and the apps. 12607 * 12608 * @param chargeUC amount of charge (microcoulombs) used by GNSS since this was last called. 12609 */ 12610 @GuardedBy("this") updateGnssMeasuredEnergyStatsLocked(long chargeUC, long elapsedRealtimeMs)12611 public void updateGnssMeasuredEnergyStatsLocked(long chargeUC, long elapsedRealtimeMs) { 12612 if (DEBUG_ENERGY) Slog.d(TAG, "Updating gnss stats: " + chargeUC); 12613 if (mGlobalMeasuredEnergyStats == null) { 12614 return; 12615 } 12616 12617 if (!mOnBatteryInternal || chargeUC <= 0) { 12618 // There's nothing further to update. 12619 return; 12620 } 12621 if (mIgnoreNextExternalStats) { 12622 // Although under ordinary resets we won't get here, and typically a new sync will 12623 // happen right after the reset, strictly speaking we need to set all mark times to now. 12624 final int uidStatsSize = mUidStats.size(); 12625 for (int i = 0; i < uidStatsSize; i++) { 12626 final Uid uid = mUidStats.valueAt(i); 12627 uid.markGnssTimeUs(elapsedRealtimeMs); 12628 } 12629 return; 12630 } 12631 12632 mGlobalMeasuredEnergyStats.updateStandardBucket(MeasuredEnergyStats.POWER_BUCKET_GNSS, 12633 chargeUC); 12634 12635 // Collect the per uid time since mark so that we can normalize power. 12636 final SparseDoubleArray gnssTimeUsArray = new SparseDoubleArray(); 12637 // TODO(b/175726779): Update and optimize the algorithm (e.g. avoid iterating over ALL uids) 12638 final int uidStatsSize = mUidStats.size(); 12639 for (int i = 0; i < uidStatsSize; i++) { 12640 final Uid uid = mUidStats.valueAt(i); 12641 final long gnssTimeUs = uid.markGnssTimeUs(elapsedRealtimeMs); 12642 if (gnssTimeUs == 0) continue; 12643 gnssTimeUsArray.put(uid.getUid(), (double) gnssTimeUs); 12644 } 12645 distributeEnergyToUidsLocked(MeasuredEnergyStats.POWER_BUCKET_GNSS, chargeUC, 12646 gnssTimeUsArray, 0); 12647 } 12648 12649 /** 12650 * Accumulate Custom power bucket charge, globally and for each app. 12651 * 12652 * @param totalChargeUC charge (microcoulombs) used for this bucket since this was last called. 12653 * @param uidCharges map of uid->charge (microcoulombs) for this bucket since last called. 12654 * Data inside uidCharges will not be modified (treated immutable). 12655 * Uids not already known to BatteryStats will be ignored. 12656 */ updateCustomMeasuredEnergyStatsLocked(int customPowerBucket, long totalChargeUC, @Nullable SparseLongArray uidCharges)12657 public void updateCustomMeasuredEnergyStatsLocked(int customPowerBucket, 12658 long totalChargeUC, @Nullable SparseLongArray uidCharges) { 12659 if (DEBUG_ENERGY) { 12660 Slog.d(TAG, "Updating attributed measured charge stats for custom bucket " 12661 + customPowerBucket 12662 + " with total charge " + totalChargeUC 12663 + " and uid charges " + String.valueOf(uidCharges)); 12664 } 12665 if (mGlobalMeasuredEnergyStats == null) return; 12666 if (!mOnBatteryInternal || mIgnoreNextExternalStats || totalChargeUC <= 0) return; 12667 12668 mGlobalMeasuredEnergyStats.updateCustomBucket(customPowerBucket, totalChargeUC); 12669 12670 if (uidCharges == null) return; 12671 final int numUids = uidCharges.size(); 12672 for (int i = 0; i < numUids; i++) { 12673 final int uidInt = mapUid(uidCharges.keyAt(i)); 12674 final long uidChargeUC = uidCharges.valueAt(i); 12675 if (uidChargeUC == 0) continue; 12676 final Uid uidObj = getAvailableUidStatsLocked(uidInt); 12677 if (uidObj != null) { 12678 uidObj.addChargeToCustomBucketLocked(uidChargeUC, customPowerBucket); 12679 } else { 12680 // Ignore any uid not already known to BatteryStats, rather than creating a new Uid. 12681 // Otherwise we could end up reviving dead Uids. Note that the CPU data is updated 12682 // first, so any uid that has used any CPU should already be known to BatteryStats. 12683 // Recently removed uids (especially common for isolated uids) can reach this path 12684 // and are ignored. 12685 if (!Process.isIsolated(uidInt)) { 12686 Slog.w(TAG, "Received measured charge " + totalChargeUC + " for custom bucket " 12687 + customPowerBucket + " for non-existent uid " + uidInt); 12688 } 12689 } 12690 } 12691 } 12692 12693 /** 12694 * Attributes energy (for the given bucket) to each uid according to the following formula: 12695 * blamedEnergy[uid] = totalEnergy * ratioNumerators[uid] / ratioDenominator; 12696 * <p>Does nothing if ratioDenominator is 0. 12697 * 12698 * <p>Here, ratioDenominator = max(sumOfAllRatioNumerators, minRatioDenominator), 12699 * so if given minRatioDenominator <= 0, then sumOfAllRatioNumerators will be used implicitly. 12700 * 12701 * <p>Note that ratioNumerators and minRatioDenominator must use the same units, but need not 12702 * use the same units as totalConsumedChargeUC (which must be in microcoulombs). 12703 * 12704 * <p>A consequence of minRatioDenominator is that the sum over all uids might be less than 12705 * totalConsumedChargeUC. This is intentional; the remainder is purposefully unnaccounted rather 12706 * than incorrectly blamed on uids, and implies unknown (non-uid) sources of drain. 12707 * 12708 * <p>All uids in ratioNumerators must exist in mUidStats already. 12709 */ distributeEnergyToUidsLocked(@tandardPowerBucket int bucket, long totalConsumedChargeUC, SparseDoubleArray ratioNumerators, double minRatioDenominator)12710 private void distributeEnergyToUidsLocked(@StandardPowerBucket int bucket, 12711 long totalConsumedChargeUC, SparseDoubleArray ratioNumerators, 12712 double minRatioDenominator) { 12713 12714 // If the sum of all app usage was greater than the total, use that instead: 12715 double sumRatioNumerators = 0; 12716 for (int i = ratioNumerators.size() - 1; i >= 0; i--) { 12717 sumRatioNumerators += ratioNumerators.valueAt(i); 12718 } 12719 final double ratioDenominator = Math.max(sumRatioNumerators, minRatioDenominator); 12720 if (ratioDenominator <= 0) return; 12721 12722 for (int i = ratioNumerators.size() - 1; i >= 0; i--) { 12723 final Uid uid = getAvailableUidStatsLocked(ratioNumerators.keyAt(i)); 12724 final double ratioNumerator = ratioNumerators.valueAt(i); 12725 final long uidActualUC 12726 = (long) (totalConsumedChargeUC * ratioNumerator / ratioDenominator + 0.5); 12727 uid.addChargeToStandardBucketLocked(uidActualUC, bucket); 12728 } 12729 } 12730 12731 /** 12732 * Read and record Rail Energy data. 12733 */ updateRailStatsLocked()12734 public void updateRailStatsLocked() { 12735 if (mMeasuredEnergyRetriever == null || !mTmpRailStats.isRailStatsAvailable()) { 12736 return; 12737 } 12738 mMeasuredEnergyRetriever.fillRailDataStats(mTmpRailStats); 12739 } 12740 12741 /** Informs that external stats data has been completely flushed. */ informThatAllExternalStatsAreFlushed()12742 public void informThatAllExternalStatsAreFlushed() { 12743 synchronized (this) { 12744 // Any data from the pre-reset era is flushed, so we can henceforth process future data. 12745 mIgnoreNextExternalStats = false; 12746 } 12747 } 12748 12749 /** 12750 * Read and distribute kernel wake lock use across apps. 12751 */ updateKernelWakelocksLocked()12752 public void updateKernelWakelocksLocked() { 12753 updateKernelWakelocksLocked(mClocks.elapsedRealtime() * 1000); 12754 } 12755 12756 /** 12757 * @see #updateKernelWakelocksLocked() 12758 */ updateKernelWakelocksLocked(long elapsedRealtimeUs)12759 public void updateKernelWakelocksLocked(long elapsedRealtimeUs) { 12760 final KernelWakelockStats wakelockStats = mKernelWakelockReader.readKernelWakelockStats( 12761 mTmpWakelockStats); 12762 if (wakelockStats == null) { 12763 // Not crashing might make board bringup easier. 12764 Slog.w(TAG, "Couldn't get kernel wake lock stats"); 12765 return; 12766 } 12767 12768 for (Map.Entry<String, KernelWakelockStats.Entry> ent : wakelockStats.entrySet()) { 12769 String name = ent.getKey(); 12770 KernelWakelockStats.Entry kws = ent.getValue(); 12771 12772 SamplingTimer kwlt = mKernelWakelockStats.get(name); 12773 if (kwlt == null) { 12774 kwlt = new SamplingTimer(mClocks, mOnBatteryScreenOffTimeBase); 12775 mKernelWakelockStats.put(name, kwlt); 12776 } 12777 12778 kwlt.update(kws.mTotalTime, kws.mCount, elapsedRealtimeUs); 12779 kwlt.setUpdateVersion(kws.mVersion); 12780 } 12781 12782 int numWakelocksSetStale = 0; 12783 // Set timers to stale if they didn't appear in /d/wakeup_sources (or /proc/wakelocks) 12784 // this time. 12785 for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) { 12786 SamplingTimer st = ent.getValue(); 12787 if (st.getUpdateVersion() != wakelockStats.kernelWakelockVersion) { 12788 st.endSample(elapsedRealtimeUs); 12789 numWakelocksSetStale++; 12790 } 12791 } 12792 12793 // Record whether we've seen a non-zero time (for debugging b/22716723). 12794 if (wakelockStats.isEmpty()) { 12795 Slog.wtf(TAG, "All kernel wakelocks had time of zero"); 12796 } 12797 12798 if (numWakelocksSetStale == mKernelWakelockStats.size()) { 12799 Slog.wtf(TAG, "All kernel wakelocks were set stale. new version=" + 12800 wakelockStats.kernelWakelockVersion); 12801 } 12802 } 12803 12804 // We use an anonymous class to access these variables, 12805 // so they can't live on the stack or they'd have to be 12806 // final MutableLong objects (more allocations). 12807 // Used in updateCpuTimeLocked(). 12808 long mTempTotalCpuUserTimeUs; 12809 long mTempTotalCpuSystemTimeUs; 12810 long[][] mWakeLockAllocationsUs; 12811 12812 /** 12813 * Reads the newest memory stats from the kernel. 12814 */ updateKernelMemoryBandwidthLocked()12815 public void updateKernelMemoryBandwidthLocked() { 12816 updateKernelMemoryBandwidthLocked(mClocks.elapsedRealtime() * 1000); 12817 } 12818 updateKernelMemoryBandwidthLocked(long elapsedRealtimeUs)12819 public void updateKernelMemoryBandwidthLocked(long elapsedRealtimeUs) { 12820 mKernelMemoryBandwidthStats.updateStats(); 12821 LongSparseLongArray bandwidthEntries = mKernelMemoryBandwidthStats.getBandwidthEntries(); 12822 final int bandwidthEntryCount = bandwidthEntries.size(); 12823 int index; 12824 for (int i = 0; i < bandwidthEntryCount; i++) { 12825 SamplingTimer timer; 12826 if ((index = mKernelMemoryStats.indexOfKey(bandwidthEntries.keyAt(i))) >= 0) { 12827 timer = mKernelMemoryStats.valueAt(index); 12828 } else { 12829 timer = new SamplingTimer(mClocks, mOnBatteryTimeBase); 12830 mKernelMemoryStats.put(bandwidthEntries.keyAt(i), timer); 12831 } 12832 timer.update(bandwidthEntries.valueAt(i), 1, elapsedRealtimeUs); 12833 if (DEBUG_MEMORY) { 12834 Slog.d(TAG, String.format("Added entry %d and updated timer to: " 12835 + "mUnpluggedReportedTotalTimeUs %d size %d", bandwidthEntries.keyAt(i), 12836 mKernelMemoryStats.get( 12837 bandwidthEntries.keyAt(i)).mUnpluggedReportedTotalTimeUs, 12838 mKernelMemoryStats.size())); 12839 } 12840 } 12841 } 12842 isOnBatteryLocked()12843 public boolean isOnBatteryLocked() { 12844 return mOnBatteryTimeBase.isRunning(); 12845 } 12846 isOnBatteryScreenOffLocked()12847 public boolean isOnBatteryScreenOffLocked() { 12848 return mOnBatteryScreenOffTimeBase.isRunning(); 12849 } 12850 12851 /** 12852 * Object for calculating and accumulating the estimated cpu power used while reading the 12853 * various cpu kernel files. 12854 */ 12855 @VisibleForTesting 12856 public static class CpuDeltaPowerAccumulator { 12857 // Keeps track of total charge used per cluster. 12858 public final double[] totalClusterChargesMah; 12859 // Keeps track of charge used per cluster per uid. 12860 public final ArrayMap<Uid, double[]> perUidCpuClusterChargesMah; 12861 12862 private final CpuPowerCalculator mCalculator; 12863 private Uid mCachedUid = null; 12864 private double[] mUidClusterCache = null; 12865 CpuDeltaPowerAccumulator(CpuPowerCalculator calculator, int nClusters)12866 CpuDeltaPowerAccumulator(CpuPowerCalculator calculator, int nClusters) { 12867 mCalculator = calculator; 12868 totalClusterChargesMah = new double[nClusters]; 12869 perUidCpuClusterChargesMah = new ArrayMap<>(); 12870 } 12871 12872 /** Add per cpu cluster durations to the currently cached uid. */ addCpuClusterDurationsMs(Uid uid, long[] durationsMs)12873 public void addCpuClusterDurationsMs(Uid uid, long[] durationsMs) { 12874 final double[] uidChargesMah = getOrCreateUidCpuClusterCharges(uid); 12875 for (int cluster = 0; cluster < durationsMs.length; cluster++) { 12876 final double estimatedDeltaMah = mCalculator.calculatePerCpuClusterPowerMah(cluster, 12877 durationsMs[cluster]); 12878 uidChargesMah[cluster] += estimatedDeltaMah; 12879 totalClusterChargesMah[cluster] += estimatedDeltaMah; 12880 } 12881 } 12882 12883 /** Add per speed per cpu cluster durations to the currently cached uid. */ addCpuClusterSpeedDurationsMs(Uid uid, int cluster, int speed, long durationsMs)12884 public void addCpuClusterSpeedDurationsMs(Uid uid, int cluster, int speed, 12885 long durationsMs) { 12886 final double[] uidChargesMah = getOrCreateUidCpuClusterCharges(uid); 12887 final double estimatedDeltaMah = mCalculator.calculatePerCpuFreqPowerMah(cluster, speed, 12888 durationsMs); 12889 uidChargesMah[cluster] += estimatedDeltaMah; 12890 totalClusterChargesMah[cluster] += estimatedDeltaMah; 12891 } 12892 getOrCreateUidCpuClusterCharges(Uid uid)12893 private double[] getOrCreateUidCpuClusterCharges(Uid uid) { 12894 // Repeated additions on the same uid is very likely. 12895 // Skip a lookup if getting the same uid as the last get. 12896 if (uid == mCachedUid) return mUidClusterCache; 12897 12898 double[] uidChargesMah = perUidCpuClusterChargesMah.get(uid); 12899 if (uidChargesMah == null) { 12900 uidChargesMah = new double[totalClusterChargesMah.length]; 12901 perUidCpuClusterChargesMah.put(uid, uidChargesMah); 12902 } 12903 mCachedUid = uid; 12904 mUidClusterCache = uidChargesMah; 12905 return uidChargesMah; 12906 } 12907 } 12908 12909 /** 12910 * Read and distribute CPU usage across apps. If their are partial wakelocks being held 12911 * and we are on battery with screen off, we give more of the cpu time to those apps holding 12912 * wakelocks. If the screen is on, we just assign the actual cpu time an app used. 12913 * It's possible this will be invoked after the internal battery/screen states are updated, so 12914 * passing the appropriate battery/screen states to try attribute the cpu times to correct 12915 * buckets. 12916 */ 12917 @GuardedBy("this") updateCpuTimeLocked(boolean onBattery, boolean onBatteryScreenOff, long[] measuredCpuClusterChargeUC)12918 public void updateCpuTimeLocked(boolean onBattery, boolean onBatteryScreenOff, 12919 long[] measuredCpuClusterChargeUC) { 12920 if (mPowerProfile == null) { 12921 return; 12922 } 12923 12924 if (DEBUG_ENERGY_CPU) { 12925 Slog.d(TAG, "!Cpu updating!"); 12926 } 12927 12928 if (mCpuFreqs == null) { 12929 mCpuFreqs = mCpuUidFreqTimeReader.readFreqs(mPowerProfile); 12930 } 12931 12932 // Calculate the wakelocks we have to distribute amongst. The system is excluded as it is 12933 // usually holding the wakelock on behalf of an app. 12934 // And Only distribute cpu power to wakelocks if the screen is off and we're on battery. 12935 ArrayList<StopwatchTimer> partialTimersToConsider = null; 12936 if (onBatteryScreenOff) { 12937 partialTimersToConsider = new ArrayList<>(); 12938 for (int i = mPartialTimers.size() - 1; i >= 0; --i) { 12939 final StopwatchTimer timer = mPartialTimers.get(i); 12940 // Since the collection and blaming of wakelocks can be scheduled to run after 12941 // some delay, the mPartialTimers list may have new entries. We can't blame 12942 // the newly added timer for past cpu time, so we only consider timers that 12943 // were present for one round of collection. Once a timer has gone through 12944 // a round of collection, its mInList field is set to true. 12945 if (timer.mInList && timer.mUid != null && timer.mUid.mUid != Process.SYSTEM_UID) { 12946 partialTimersToConsider.add(timer); 12947 } 12948 } 12949 } 12950 markPartialTimersAsEligible(); 12951 12952 // When the battery is not on, we don't attribute the cpu times to any timers but we still 12953 // need to take the snapshots. 12954 if (!onBattery) { 12955 mCpuUidUserSysTimeReader.readDelta(false, null); 12956 mCpuUidFreqTimeReader.readDelta(false, null); 12957 mNumAllUidCpuTimeReads += 2; 12958 if (mConstants.TRACK_CPU_ACTIVE_CLUSTER_TIME) { 12959 mCpuUidActiveTimeReader.readDelta(false, null); 12960 mCpuUidClusterTimeReader.readDelta(false, null); 12961 mNumAllUidCpuTimeReads += 2; 12962 } 12963 for (int cluster = mKernelCpuSpeedReaders.length - 1; cluster >= 0; --cluster) { 12964 mKernelCpuSpeedReaders[cluster].readDelta(); 12965 } 12966 mSystemServerCpuThreadReader.readDelta(); 12967 return; 12968 } 12969 12970 mUserInfoProvider.refreshUserIds(); 12971 final SparseLongArray updatedUids = mCpuUidFreqTimeReader.perClusterTimesAvailable() 12972 ? null : new SparseLongArray(); 12973 12974 final CpuDeltaPowerAccumulator powerAccumulator; 12975 if (mGlobalMeasuredEnergyStats != null 12976 && mGlobalMeasuredEnergyStats.isStandardBucketSupported( 12977 MeasuredEnergyStats.POWER_BUCKET_CPU) && mCpuPowerCalculator != null) { 12978 if (measuredCpuClusterChargeUC == null) { 12979 Slog.wtf(TAG, 12980 "POWER_BUCKET_CPU supported but no measured Cpu Cluster charge reported " 12981 + "on updateCpuTimeLocked!"); 12982 powerAccumulator = null; 12983 } else { 12984 // Cpu Measured Energy is supported, create an object to accumulate the estimated 12985 // charge consumption since the last cpu update 12986 final int numClusters = mPowerProfile.getNumCpuClusters(); 12987 powerAccumulator = new CpuDeltaPowerAccumulator(mCpuPowerCalculator, numClusters); 12988 } 12989 } else { 12990 powerAccumulator = null; 12991 } 12992 12993 readKernelUidCpuTimesLocked(partialTimersToConsider, updatedUids, onBattery); 12994 // updatedUids=null means /proc/uid_time_in_state provides snapshots of per-cluster cpu 12995 // freqs, so no need to approximate these values. 12996 if (updatedUids != null) { 12997 updateClusterSpeedTimes(updatedUids, onBattery, powerAccumulator); 12998 } 12999 readKernelUidCpuFreqTimesLocked(partialTimersToConsider, onBattery, onBatteryScreenOff, 13000 powerAccumulator); 13001 mNumAllUidCpuTimeReads += 2; 13002 if (mConstants.TRACK_CPU_ACTIVE_CLUSTER_TIME) { 13003 // Cpu Active times do not get any info ony how to attribute measured Cpu Cluster 13004 // charge, so not need to provide the powerAccumulator 13005 readKernelUidCpuActiveTimesLocked(onBattery); 13006 readKernelUidCpuClusterTimesLocked(onBattery, powerAccumulator); 13007 mNumAllUidCpuTimeReads += 2; 13008 } 13009 13010 updateSystemServerThreadStats(); 13011 13012 if (powerAccumulator != null) { 13013 updateCpuMeasuredEnergyStatsLocked(measuredCpuClusterChargeUC, powerAccumulator); 13014 } 13015 } 13016 13017 /** 13018 * Estimates the proportion of the System Server CPU activity (per cluster per speed) 13019 * spent on handling incoming binder calls. 13020 */ 13021 @VisibleForTesting updateSystemServerThreadStats()13022 public void updateSystemServerThreadStats() { 13023 // There are some simplifying assumptions made in this algorithm 13024 // 1) We assume that if a thread handles incoming binder calls, all of its activity 13025 // is spent doing that. Most incoming calls are handled by threads allocated 13026 // by the native layer in the binder thread pool, so this assumption is reasonable. 13027 // 2) We use the aggregate CPU time spent in different threads as a proxy for the CPU 13028 // cost. In reality, in multi-core CPUs, the CPU cost may not be linearly 13029 // affected by additional threads. 13030 13031 SystemServerCpuThreadReader.SystemServiceCpuThreadTimes systemServiceCpuThreadTimes = 13032 mSystemServerCpuThreadReader.readDelta(); 13033 if (systemServiceCpuThreadTimes == null) { 13034 return; 13035 } 13036 13037 if (mBinderThreadCpuTimesUs == null) { 13038 mBinderThreadCpuTimesUs = new LongSamplingCounterArray(mOnBatteryTimeBase); 13039 } 13040 mBinderThreadCpuTimesUs.addCountLocked(systemServiceCpuThreadTimes.binderThreadCpuTimesUs); 13041 13042 if (DEBUG_BINDER_STATS) { 13043 Slog.d(TAG, "System server threads per CPU cluster (incoming binder threads)"); 13044 long binderThreadTimeMs = 0; 13045 int cpuIndex = 0; 13046 final long[] binderThreadCpuTimesUs = mBinderThreadCpuTimesUs.getCountsLocked( 13047 BatteryStats.STATS_SINCE_CHARGED); 13048 int index = 0; 13049 int numCpuClusters = mPowerProfile.getNumCpuClusters(); 13050 for (int cluster = 0; cluster < numCpuClusters; cluster++) { 13051 StringBuilder sb = new StringBuilder(); 13052 sb.append("cpu").append(cpuIndex).append(": ["); 13053 int numSpeeds = mPowerProfile.getNumSpeedStepsInCpuCluster(cluster); 13054 for (int speed = 0; speed < numSpeeds; speed++) { 13055 if (speed != 0) { 13056 sb.append(", "); 13057 } 13058 long binderCountMs = binderThreadCpuTimesUs[index] / 1000; 13059 sb.append(TextUtils.formatSimple("%10d", binderCountMs)); 13060 13061 binderThreadTimeMs += binderCountMs; 13062 index++; 13063 } 13064 cpuIndex += mPowerProfile.getNumCoresInCpuCluster(cluster); 13065 Slog.d(TAG, sb.toString()); 13066 } 13067 } 13068 } 13069 13070 /** 13071 * Mark the current partial timers as gone through a collection so that they will be 13072 * considered in the next cpu times distribution to wakelock holders. 13073 */ 13074 @VisibleForTesting markPartialTimersAsEligible()13075 public void markPartialTimersAsEligible() { 13076 if (ArrayUtils.referenceEquals(mPartialTimers, mLastPartialTimers)) { 13077 // No difference, so each timer is now considered for the next collection. 13078 for (int i = mPartialTimers.size() - 1; i >= 0; --i) { 13079 mPartialTimers.get(i).mInList = true; 13080 } 13081 } else { 13082 // The lists are different, meaning we added (or removed a timer) since the last 13083 // collection. 13084 for (int i = mLastPartialTimers.size() - 1; i >= 0; --i) { 13085 mLastPartialTimers.get(i).mInList = false; 13086 } 13087 mLastPartialTimers.clear(); 13088 13089 // Mark the current timers as gone through a collection. 13090 final int numPartialTimers = mPartialTimers.size(); 13091 for (int i = 0; i < numPartialTimers; ++i) { 13092 final StopwatchTimer timer = mPartialTimers.get(i); 13093 timer.mInList = true; 13094 mLastPartialTimers.add(timer); 13095 } 13096 } 13097 } 13098 13099 /** 13100 * Take snapshot of cpu times (aggregated over all uids) at different frequencies and 13101 * calculate cpu times spent by each uid at different frequencies. Will also add estimated 13102 * power consumptions, if powerAccumulator data structure is provided. 13103 * 13104 * @param updatedUids The uids for which times spent at different frequencies are calculated. 13105 * @param onBattery whether or not this is onBattery 13106 * @param powerAccumulator object to accumulate the estimated cluster charge consumption. 13107 */ 13108 @VisibleForTesting updateClusterSpeedTimes(@onNull SparseLongArray updatedUids, boolean onBattery, @Nullable CpuDeltaPowerAccumulator powerAccumulator)13109 public void updateClusterSpeedTimes(@NonNull SparseLongArray updatedUids, boolean onBattery, 13110 @Nullable CpuDeltaPowerAccumulator powerAccumulator) { 13111 long totalCpuClustersTimeMs = 0; 13112 // Read the time spent for each cluster at various cpu frequencies. 13113 final long[][] clusterSpeedTimesMs = new long[mKernelCpuSpeedReaders.length][]; 13114 for (int cluster = 0; cluster < mKernelCpuSpeedReaders.length; cluster++) { 13115 clusterSpeedTimesMs[cluster] = mKernelCpuSpeedReaders[cluster].readDelta(); 13116 if (clusterSpeedTimesMs[cluster] != null) { 13117 for (int speed = clusterSpeedTimesMs[cluster].length - 1; speed >= 0; --speed) { 13118 totalCpuClustersTimeMs += clusterSpeedTimesMs[cluster][speed]; 13119 } 13120 } 13121 } 13122 if (totalCpuClustersTimeMs != 0) { 13123 // We have cpu times per freq aggregated over all uids but we need the times per uid. 13124 // So, we distribute total time spent by an uid to different cpu freqs based on the 13125 // amount of time cpu was running at that freq. 13126 final int updatedUidsCount = updatedUids.size(); 13127 final long elapsedRealtimeMs = mClocks.elapsedRealtime(); 13128 final long uptimeMs = mClocks.uptimeMillis(); 13129 for (int i = 0; i < updatedUidsCount; ++i) { 13130 final Uid u = getUidStatsLocked(updatedUids.keyAt(i), elapsedRealtimeMs, uptimeMs); 13131 final long appCpuTimeUs = updatedUids.valueAt(i); 13132 // Add the cpu speeds to this UID. 13133 final int numClusters = mPowerProfile.getNumCpuClusters(); 13134 if (u.mCpuClusterSpeedTimesUs == null || 13135 u.mCpuClusterSpeedTimesUs.length != numClusters) { 13136 u.mCpuClusterSpeedTimesUs = new LongSamplingCounter[numClusters][]; 13137 } 13138 13139 for (int cluster = 0; cluster < clusterSpeedTimesMs.length; cluster++) { 13140 final int speedsInCluster = clusterSpeedTimesMs[cluster].length; 13141 if (u.mCpuClusterSpeedTimesUs[cluster] == null || speedsInCluster != 13142 u.mCpuClusterSpeedTimesUs[cluster].length) { 13143 u.mCpuClusterSpeedTimesUs[cluster] 13144 = new LongSamplingCounter[speedsInCluster]; 13145 } 13146 13147 final LongSamplingCounter[] cpuSpeeds = u.mCpuClusterSpeedTimesUs[cluster]; 13148 for (int speed = 0; speed < speedsInCluster; speed++) { 13149 if (cpuSpeeds[speed] == null) { 13150 cpuSpeeds[speed] = new LongSamplingCounter(mOnBatteryTimeBase); 13151 } 13152 final long deltaSpeedCount = appCpuTimeUs 13153 * clusterSpeedTimesMs[cluster][speed] 13154 / totalCpuClustersTimeMs; 13155 cpuSpeeds[speed].addCountLocked(deltaSpeedCount, onBattery); 13156 13157 if (powerAccumulator != null) { 13158 powerAccumulator.addCpuClusterSpeedDurationsMs(u, cluster, 13159 speed, deltaSpeedCount); 13160 } 13161 } 13162 } 13163 } 13164 } 13165 } 13166 13167 /** 13168 * Take a snapshot of the cpu times spent by each uid and update the corresponding counters. 13169 * If {@param partialTimers} is not null and empty, then we assign a portion of cpu times to 13170 * wakelock holders. 13171 * 13172 * @param partialTimers The wakelock holders among which the cpu times will be distributed. 13173 * @param updatedUids If not null, then the uids found in the snapshot will be added to this. 13174 */ 13175 @VisibleForTesting readKernelUidCpuTimesLocked(@ullable ArrayList<StopwatchTimer> partialTimers, @Nullable SparseLongArray updatedUids, boolean onBattery)13176 public void readKernelUidCpuTimesLocked(@Nullable ArrayList<StopwatchTimer> partialTimers, 13177 @Nullable SparseLongArray updatedUids, boolean onBattery) { 13178 mTempTotalCpuUserTimeUs = mTempTotalCpuSystemTimeUs = 0; 13179 final int numWakelocks = partialTimers == null ? 0 : partialTimers.size(); 13180 final long startTimeMs = mClocks.uptimeMillis(); 13181 final long elapsedRealtimeMs = mClocks.elapsedRealtime(); 13182 13183 mCpuUidUserSysTimeReader.readDelta(false, (uid, timesUs) -> { 13184 long userTimeUs = timesUs[0], systemTimeUs = timesUs[1]; 13185 13186 uid = mapUid(uid); 13187 if (Process.isIsolated(uid)) { 13188 // This could happen if the isolated uid mapping was removed before that process 13189 // was actually killed. 13190 if (DEBUG) Slog.d(TAG, "Got readings for an isolated uid: " + uid); 13191 return; 13192 } 13193 if (!mUserInfoProvider.exists(UserHandle.getUserId(uid))) { 13194 if (DEBUG) Slog.d(TAG, "Got readings for an invalid user's uid " + uid); 13195 return; 13196 } 13197 final Uid u = getUidStatsLocked(uid, elapsedRealtimeMs, startTimeMs); 13198 13199 // Accumulate the total system and user time. 13200 mTempTotalCpuUserTimeUs += userTimeUs; 13201 mTempTotalCpuSystemTimeUs += systemTimeUs; 13202 13203 StringBuilder sb = null; 13204 if (DEBUG_ENERGY_CPU) { 13205 sb = new StringBuilder(); 13206 sb.append(" got time for uid=").append(u.mUid).append(": u="); 13207 TimeUtils.formatDuration(userTimeUs / 1000, sb); 13208 sb.append(" s="); 13209 TimeUtils.formatDuration(systemTimeUs / 1000, sb); 13210 sb.append("\n"); 13211 } 13212 13213 if (numWakelocks > 0) { 13214 // We have wakelocks being held, so only give a portion of the 13215 // time to the process. The rest will be distributed among wakelock 13216 // holders. 13217 userTimeUs = (userTimeUs * WAKE_LOCK_WEIGHT) / 100; 13218 systemTimeUs = (systemTimeUs * WAKE_LOCK_WEIGHT) / 100; 13219 } 13220 13221 if (sb != null) { 13222 sb.append(" adding to uid=").append(u.mUid).append(": u="); 13223 TimeUtils.formatDuration(userTimeUs / 1000, sb); 13224 sb.append(" s="); 13225 TimeUtils.formatDuration(systemTimeUs / 1000, sb); 13226 Slog.d(TAG, sb.toString()); 13227 } 13228 13229 u.mUserCpuTime.addCountLocked(userTimeUs, onBattery); 13230 u.mSystemCpuTime.addCountLocked(systemTimeUs, onBattery); 13231 if (updatedUids != null) { 13232 updatedUids.put(u.getUid(), userTimeUs + systemTimeUs); 13233 } 13234 }); 13235 13236 final long elapsedTimeMs = mClocks.uptimeMillis() - startTimeMs; 13237 if (DEBUG_ENERGY_CPU || elapsedTimeMs >= 100) { 13238 Slog.d(TAG, "Reading cpu stats took " + elapsedTimeMs + "ms"); 13239 } 13240 13241 if (numWakelocks > 0) { 13242 // Distribute a portion of the total cpu time to wakelock holders. 13243 mTempTotalCpuUserTimeUs = (mTempTotalCpuUserTimeUs * (100 - WAKE_LOCK_WEIGHT)) / 100; 13244 mTempTotalCpuSystemTimeUs = 13245 (mTempTotalCpuSystemTimeUs * (100 - WAKE_LOCK_WEIGHT)) / 100; 13246 13247 for (int i = 0; i < numWakelocks; ++i) { 13248 final StopwatchTimer timer = partialTimers.get(i); 13249 final int userTimeUs = (int) (mTempTotalCpuUserTimeUs / (numWakelocks - i)); 13250 final int systemTimeUs = (int) (mTempTotalCpuSystemTimeUs / (numWakelocks - i)); 13251 13252 if (DEBUG_ENERGY_CPU) { 13253 final StringBuilder sb = new StringBuilder(); 13254 sb.append(" Distributing wakelock uid=").append(timer.mUid.mUid) 13255 .append(": u="); 13256 TimeUtils.formatDuration(userTimeUs / 1000, sb); 13257 sb.append(" s="); 13258 TimeUtils.formatDuration(systemTimeUs / 1000, sb); 13259 Slog.d(TAG, sb.toString()); 13260 } 13261 13262 timer.mUid.mUserCpuTime.addCountLocked(userTimeUs, onBattery); 13263 timer.mUid.mSystemCpuTime.addCountLocked(systemTimeUs, onBattery); 13264 if (updatedUids != null) { 13265 final int uid = timer.mUid.getUid(); 13266 updatedUids.put(uid, updatedUids.get(uid, 0) + userTimeUs + systemTimeUs); 13267 } 13268 13269 final Uid.Proc proc = timer.mUid.getProcessStatsLocked("*wakelock*"); 13270 proc.addCpuTimeLocked(userTimeUs / 1000, systemTimeUs / 1000, onBattery); 13271 13272 mTempTotalCpuUserTimeUs -= userTimeUs; 13273 mTempTotalCpuSystemTimeUs -= systemTimeUs; 13274 } 13275 } 13276 } 13277 13278 /** 13279 * Take a snapshot of the cpu times spent by each uid in each freq and update the 13280 * corresponding counters. Will also add estimated power consumptions, if powerAccumulator 13281 * data structure is provided. 13282 * 13283 * @param partialTimers The wakelock holders among which the cpu freq times will be distributed. 13284 * @param onBattery whether or not this is onBattery 13285 * @param onBatteryScreenOff whether or not this is onBattery with the screen off. 13286 * @param powerAccumulator object to accumulate the estimated cluster charge consumption. 13287 */ 13288 @VisibleForTesting readKernelUidCpuFreqTimesLocked(@ullable ArrayList<StopwatchTimer> partialTimers, boolean onBattery, boolean onBatteryScreenOff, @Nullable CpuDeltaPowerAccumulator powerAccumulator)13289 public void readKernelUidCpuFreqTimesLocked(@Nullable ArrayList<StopwatchTimer> partialTimers, 13290 boolean onBattery, boolean onBatteryScreenOff, 13291 @Nullable CpuDeltaPowerAccumulator powerAccumulator) { 13292 final boolean perClusterTimesAvailable = 13293 mCpuUidFreqTimeReader.perClusterTimesAvailable(); 13294 final int numWakelocks = partialTimers == null ? 0 : partialTimers.size(); 13295 final int numClusters = mPowerProfile.getNumCpuClusters(); 13296 mWakeLockAllocationsUs = null; 13297 final long startTimeMs = mClocks.uptimeMillis(); 13298 final long elapsedRealtimeMs = mClocks.elapsedRealtime(); 13299 // If power is being accumulated for attribution, data needs to be read immediately. 13300 final boolean forceRead = powerAccumulator != null; 13301 mCpuUidFreqTimeReader.readDelta(forceRead, (uid, cpuFreqTimeMs) -> { 13302 uid = mapUid(uid); 13303 if (Process.isIsolated(uid)) { 13304 if (DEBUG) Slog.d(TAG, "Got freq readings for an isolated uid: " + uid); 13305 return; 13306 } 13307 if (!mUserInfoProvider.exists(UserHandle.getUserId(uid))) { 13308 if (DEBUG) Slog.d(TAG, "Got freq readings for an invalid user's uid " + uid); 13309 return; 13310 } 13311 final Uid u = getUidStatsLocked(uid, elapsedRealtimeMs, startTimeMs); 13312 if (u.mCpuFreqTimeMs == null || u.mCpuFreqTimeMs.getSize() != cpuFreqTimeMs.length) { 13313 detachIfNotNull(u.mCpuFreqTimeMs); 13314 u.mCpuFreqTimeMs = new LongSamplingCounterArray(mOnBatteryTimeBase); 13315 } 13316 u.mCpuFreqTimeMs.addCountLocked(cpuFreqTimeMs, onBattery); 13317 if (u.mScreenOffCpuFreqTimeMs == null || 13318 u.mScreenOffCpuFreqTimeMs.getSize() != cpuFreqTimeMs.length) { 13319 detachIfNotNull(u.mScreenOffCpuFreqTimeMs); 13320 u.mScreenOffCpuFreqTimeMs = new LongSamplingCounterArray( 13321 mOnBatteryScreenOffTimeBase); 13322 } 13323 u.mScreenOffCpuFreqTimeMs.addCountLocked(cpuFreqTimeMs, onBatteryScreenOff); 13324 13325 if (perClusterTimesAvailable) { 13326 if (u.mCpuClusterSpeedTimesUs == null || 13327 u.mCpuClusterSpeedTimesUs.length != numClusters) { 13328 detachIfNotNull(u.mCpuClusterSpeedTimesUs); 13329 u.mCpuClusterSpeedTimesUs = new LongSamplingCounter[numClusters][]; 13330 } 13331 if (numWakelocks > 0 && mWakeLockAllocationsUs == null) { 13332 mWakeLockAllocationsUs = new long[numClusters][]; 13333 } 13334 13335 int freqIndex = 0; 13336 for (int cluster = 0; cluster < numClusters; ++cluster) { 13337 final int speedsInCluster = mPowerProfile.getNumSpeedStepsInCpuCluster(cluster); 13338 if (u.mCpuClusterSpeedTimesUs[cluster] == null || 13339 u.mCpuClusterSpeedTimesUs[cluster].length != speedsInCluster) { 13340 detachIfNotNull(u.mCpuClusterSpeedTimesUs[cluster]); 13341 u.mCpuClusterSpeedTimesUs[cluster] 13342 = new LongSamplingCounter[speedsInCluster]; 13343 } 13344 if (numWakelocks > 0 && mWakeLockAllocationsUs[cluster] == null) { 13345 mWakeLockAllocationsUs[cluster] = new long[speedsInCluster]; 13346 } 13347 final LongSamplingCounter[] cpuTimesUs = u.mCpuClusterSpeedTimesUs[cluster]; 13348 for (int speed = 0; speed < speedsInCluster; ++speed) { 13349 if (cpuTimesUs[speed] == null) { 13350 cpuTimesUs[speed] = new LongSamplingCounter(mOnBatteryTimeBase); 13351 } 13352 final long appAllocationUs; 13353 if (mWakeLockAllocationsUs != null) { 13354 appAllocationUs = 13355 (cpuFreqTimeMs[freqIndex] * 1000 * WAKE_LOCK_WEIGHT) / 100; 13356 mWakeLockAllocationsUs[cluster][speed] += 13357 (cpuFreqTimeMs[freqIndex] * 1000 - appAllocationUs); 13358 } else { 13359 appAllocationUs = cpuFreqTimeMs[freqIndex] * 1000; 13360 } 13361 cpuTimesUs[speed].addCountLocked(appAllocationUs, onBattery); 13362 13363 if (powerAccumulator != null) { 13364 powerAccumulator.addCpuClusterSpeedDurationsMs(u, cluster, 13365 speed, appAllocationUs / 1000); 13366 } 13367 freqIndex++; 13368 } 13369 } 13370 } 13371 }); 13372 13373 final long elapsedTimeMs = mClocks.uptimeMillis() - startTimeMs; 13374 if (DEBUG_ENERGY_CPU || elapsedTimeMs >= 100) { 13375 Slog.d(TAG, "Reading cpu freq times took " + elapsedTimeMs + "ms"); 13376 } 13377 13378 if (mWakeLockAllocationsUs != null) { 13379 for (int i = 0; i < numWakelocks; ++i) { 13380 final Uid u = partialTimers.get(i).mUid; 13381 if (u.mCpuClusterSpeedTimesUs == null || 13382 u.mCpuClusterSpeedTimesUs.length != numClusters) { 13383 detachIfNotNull(u.mCpuClusterSpeedTimesUs); 13384 u.mCpuClusterSpeedTimesUs = new LongSamplingCounter[numClusters][]; 13385 } 13386 13387 for (int cluster = 0; cluster < numClusters; ++cluster) { 13388 final int speedsInCluster = mPowerProfile.getNumSpeedStepsInCpuCluster(cluster); 13389 if (u.mCpuClusterSpeedTimesUs[cluster] == null || 13390 u.mCpuClusterSpeedTimesUs[cluster].length != speedsInCluster) { 13391 detachIfNotNull(u.mCpuClusterSpeedTimesUs[cluster]); 13392 u.mCpuClusterSpeedTimesUs[cluster] 13393 = new LongSamplingCounter[speedsInCluster]; 13394 } 13395 final LongSamplingCounter[] cpuTimeUs = u.mCpuClusterSpeedTimesUs[cluster]; 13396 for (int speed = 0; speed < speedsInCluster; ++speed) { 13397 if (cpuTimeUs[speed] == null) { 13398 cpuTimeUs[speed] = new LongSamplingCounter(mOnBatteryTimeBase); 13399 } 13400 final long allocationUs = 13401 mWakeLockAllocationsUs[cluster][speed] / (numWakelocks - i); 13402 cpuTimeUs[speed].addCountLocked(allocationUs, onBattery); 13403 mWakeLockAllocationsUs[cluster][speed] -= allocationUs; 13404 13405 if (powerAccumulator != null) { 13406 powerAccumulator.addCpuClusterSpeedDurationsMs(u, cluster, 13407 speed, allocationUs / 1000); 13408 } 13409 } 13410 } 13411 } 13412 } 13413 } 13414 13415 /** 13416 * Take a snapshot of the cpu active times spent by each uid and update the corresponding 13417 * counters. 13418 */ 13419 @VisibleForTesting readKernelUidCpuActiveTimesLocked(boolean onBattery)13420 public void readKernelUidCpuActiveTimesLocked(boolean onBattery) { 13421 final long startTimeMs = mClocks.uptimeMillis(); 13422 final long elapsedRealtimeMs = mClocks.elapsedRealtime(); 13423 mCpuUidActiveTimeReader.readDelta(false, (uid, cpuActiveTimesMs) -> { 13424 uid = mapUid(uid); 13425 if (Process.isIsolated(uid)) { 13426 if (DEBUG) Slog.w(TAG, "Got active times for an isolated uid: " + uid); 13427 return; 13428 } 13429 if (!mUserInfoProvider.exists(UserHandle.getUserId(uid))) { 13430 if (DEBUG) Slog.w(TAG, "Got active times for an invalid user's uid " + uid); 13431 return; 13432 } 13433 final Uid u = getUidStatsLocked(uid, elapsedRealtimeMs, startTimeMs); 13434 u.mCpuActiveTimeMs.addCountLocked(cpuActiveTimesMs, onBattery); 13435 }); 13436 13437 final long elapsedTimeMs = mClocks.uptimeMillis() - startTimeMs; 13438 if (DEBUG_ENERGY_CPU || elapsedTimeMs >= 100) { 13439 Slog.d(TAG, "Reading cpu active times took " + elapsedTimeMs + "ms"); 13440 } 13441 } 13442 13443 /** 13444 * Take a snapshot of the cpu cluster times spent by each uid and update the corresponding 13445 * counters. Will also add estimated power consumptions, if powerAccumulator data structure 13446 * is provided. 13447 * 13448 * @param onBattery whether or not this is onBattery 13449 * @param powerAccumulator object to accumulate the estimated cluster charge consumption. 13450 */ 13451 @VisibleForTesting readKernelUidCpuClusterTimesLocked(boolean onBattery, @Nullable CpuDeltaPowerAccumulator powerAccumulator)13452 public void readKernelUidCpuClusterTimesLocked(boolean onBattery, 13453 @Nullable CpuDeltaPowerAccumulator powerAccumulator) { 13454 final long startTimeMs = mClocks.uptimeMillis(); 13455 final long elapsedRealtimeMs = mClocks.elapsedRealtime(); 13456 // If power is being accumulated for attribution, data needs to be read immediately. 13457 final boolean forceRead = powerAccumulator != null; 13458 mCpuUidClusterTimeReader.readDelta(forceRead, (uid, cpuClusterTimesMs) -> { 13459 uid = mapUid(uid); 13460 if (Process.isIsolated(uid)) { 13461 if (DEBUG) Slog.w(TAG, "Got cluster times for an isolated uid: " + uid); 13462 return; 13463 } 13464 if (!mUserInfoProvider.exists(UserHandle.getUserId(uid))) { 13465 if (DEBUG) Slog.w(TAG, "Got cluster times for an invalid user's uid " + uid); 13466 return; 13467 } 13468 final Uid u = getUidStatsLocked(uid, elapsedRealtimeMs, startTimeMs); 13469 u.mCpuClusterTimesMs.addCountLocked(cpuClusterTimesMs, onBattery); 13470 13471 if (powerAccumulator != null) { 13472 powerAccumulator.addCpuClusterDurationsMs(u, cpuClusterTimesMs); 13473 } 13474 }); 13475 13476 final long elapsedTimeMs = mClocks.uptimeMillis() - startTimeMs; 13477 if (DEBUG_ENERGY_CPU || elapsedTimeMs >= 100) { 13478 Slog.d(TAG, "Reading cpu cluster times took " + elapsedTimeMs + "ms"); 13479 } 13480 } 13481 setChargingLocked(boolean charging)13482 boolean setChargingLocked(boolean charging) { 13483 // if the device is no longer charging, remove the callback 13484 // if the device is now charging, it means that this is either called 13485 // 1. directly when level >= 90 13486 // 2. or from within the runnable that we deferred 13487 // For 1. if we have an existing callback, remove it, since we will immediately send a 13488 // ACTION_CHARGING 13489 // For 2. we remove existing callback so we don't send multiple ACTION_CHARGING 13490 mHandler.removeCallbacks(mDeferSetCharging); 13491 if (mCharging != charging) { 13492 mCharging = charging; 13493 if (charging) { 13494 mHistoryCur.states2 |= HistoryItem.STATE2_CHARGING_FLAG; 13495 } else { 13496 mHistoryCur.states2 &= ~HistoryItem.STATE2_CHARGING_FLAG; 13497 } 13498 mHandler.sendEmptyMessage(MSG_REPORT_CHARGING); 13499 return true; 13500 } 13501 return false; 13502 } 13503 13504 /** 13505 * Notifies BatteryStatsImpl that the system server is ready. 13506 */ onSystemReady()13507 public void onSystemReady() { 13508 mSystemReady = true; 13509 } 13510 13511 @GuardedBy("this") setOnBatteryLocked(final long mSecRealtime, final long mSecUptime, final boolean onBattery, final int oldStatus, final int level, final int chargeUah)13512 protected void setOnBatteryLocked(final long mSecRealtime, final long mSecUptime, 13513 final boolean onBattery, final int oldStatus, final int level, final int chargeUah) { 13514 boolean doWrite = false; 13515 Message m = mHandler.obtainMessage(MSG_REPORT_POWER_CHANGE); 13516 m.arg1 = onBattery ? 1 : 0; 13517 mHandler.sendMessage(m); 13518 13519 final long uptimeUs = mSecUptime * 1000; 13520 final long realtimeUs = mSecRealtime * 1000; 13521 final int screenState = mScreenState; 13522 if (onBattery) { 13523 // We will reset our status if we are unplugging after the 13524 // battery was last full, or the level is at 100, or 13525 // we have gone through a significant charge (from a very low 13526 // level to a now very high level). 13527 // Also, we will reset the stats if battery got partially charged 13528 // and discharged repeatedly without ever reaching the full charge. 13529 // This reset is done in order to prevent stats sessions from going on forever. 13530 // Exceedingly long battery sessions would lead to an overflow of 13531 // data structures such as mWakeupReasonStats. 13532 boolean reset = false; 13533 if (!mNoAutoReset && mSystemReady 13534 && (oldStatus == BatteryManager.BATTERY_STATUS_FULL 13535 || level >= 90 13536 || (mDischargeCurrentLevel < 20 && level >= 80) 13537 || getHighDischargeAmountSinceCharge() >= 200)) { 13538 Slog.i(TAG, "Resetting battery stats: level=" + level + " status=" + oldStatus 13539 + " dischargeLevel=" + mDischargeCurrentLevel 13540 + " lowAmount=" + getLowDischargeAmountSinceCharge() 13541 + " highAmount=" + getHighDischargeAmountSinceCharge()); 13542 // Before we write, collect a snapshot of the final aggregated 13543 // stats to be reported in the next checkin. Only do this if we have 13544 // a sufficient amount of data to make it interesting. 13545 if (getLowDischargeAmountSinceCharge() >= 20) { 13546 final long startTimeMs = SystemClock.uptimeMillis(); 13547 final Parcel parcel = Parcel.obtain(); 13548 writeSummaryToParcel(parcel, true); 13549 final long initialTimeMs = SystemClock.uptimeMillis() - startTimeMs; 13550 BackgroundThread.getHandler().post(new Runnable() { 13551 @Override public void run() { 13552 synchronized (mCheckinFile) { 13553 final long startTimeMs2 = SystemClock.uptimeMillis(); 13554 FileOutputStream stream = null; 13555 try { 13556 stream = mCheckinFile.startWrite(); 13557 stream.write(parcel.marshall()); 13558 stream.flush(); 13559 mCheckinFile.finishWrite(stream); 13560 com.android.internal.logging.EventLogTags.writeCommitSysConfigFile( 13561 "batterystats-checkin", initialTimeMs 13562 + SystemClock.uptimeMillis() - startTimeMs2); 13563 } catch (IOException e) { 13564 Slog.w("BatteryStats", 13565 "Error writing checkin battery statistics", e); 13566 mCheckinFile.failWrite(stream); 13567 } finally { 13568 parcel.recycle(); 13569 } 13570 } 13571 } 13572 }); 13573 } 13574 doWrite = true; 13575 resetAllStatsLocked(mSecUptime, mSecRealtime, RESET_REASON_FULL_CHARGE); 13576 if (chargeUah > 0 && level > 0) { 13577 // Only use the reported coulomb charge value if it is supported and reported. 13578 mEstimatedBatteryCapacityMah = (int) ((chargeUah / 1000) / (level / 100.0)); 13579 } 13580 mDischargeStartLevel = level; 13581 reset = true; 13582 mDischargeStepTracker.init(); 13583 } 13584 if (mCharging) { 13585 setChargingLocked(false); 13586 } 13587 mLastChargingStateLevel = level; 13588 mOnBattery = mOnBatteryInternal = true; 13589 mLastDischargeStepLevel = level; 13590 mMinDischargeStepLevel = level; 13591 mDischargeStepTracker.clearTime(); 13592 mDailyDischargeStepTracker.clearTime(); 13593 mInitStepMode = mCurStepMode; 13594 mModStepMode = 0; 13595 pullPendingStateUpdatesLocked(); 13596 mHistoryCur.batteryLevel = (byte)level; 13597 mHistoryCur.states &= ~HistoryItem.STATE_BATTERY_PLUGGED_FLAG; 13598 if (DEBUG_HISTORY) Slog.v(TAG, "Battery unplugged to: " 13599 + Integer.toHexString(mHistoryCur.states)); 13600 if (reset) { 13601 mRecordingHistory = true; 13602 startRecordingHistory(mSecRealtime, mSecUptime, reset); 13603 } 13604 addHistoryRecordLocked(mSecRealtime, mSecUptime); 13605 mDischargeCurrentLevel = mDischargeUnplugLevel = level; 13606 if (Display.isOnState(screenState)) { 13607 mDischargeScreenOnUnplugLevel = level; 13608 mDischargeScreenDozeUnplugLevel = 0; 13609 mDischargeScreenOffUnplugLevel = 0; 13610 } else if (Display.isDozeState(screenState)) { 13611 mDischargeScreenOnUnplugLevel = 0; 13612 mDischargeScreenDozeUnplugLevel = level; 13613 mDischargeScreenOffUnplugLevel = 0; 13614 } else { 13615 mDischargeScreenOnUnplugLevel = 0; 13616 mDischargeScreenDozeUnplugLevel = 0; 13617 mDischargeScreenOffUnplugLevel = level; 13618 } 13619 mDischargeAmountScreenOn = 0; 13620 mDischargeAmountScreenDoze = 0; 13621 mDischargeAmountScreenOff = 0; 13622 updateTimeBasesLocked(true, screenState, uptimeUs, realtimeUs); 13623 } else { 13624 mLastChargingStateLevel = level; 13625 mOnBattery = mOnBatteryInternal = false; 13626 pullPendingStateUpdatesLocked(); 13627 mHistoryCur.batteryLevel = (byte)level; 13628 mHistoryCur.states |= HistoryItem.STATE_BATTERY_PLUGGED_FLAG; 13629 if (DEBUG_HISTORY) Slog.v(TAG, "Battery plugged to: " 13630 + Integer.toHexString(mHistoryCur.states)); 13631 addHistoryRecordLocked(mSecRealtime, mSecUptime); 13632 mDischargeCurrentLevel = mDischargePlugLevel = level; 13633 if (level < mDischargeUnplugLevel) { 13634 mLowDischargeAmountSinceCharge += mDischargeUnplugLevel-level-1; 13635 mHighDischargeAmountSinceCharge += mDischargeUnplugLevel-level; 13636 } 13637 updateDischargeScreenLevelsLocked(screenState, screenState); 13638 updateTimeBasesLocked(false, screenState, uptimeUs, realtimeUs); 13639 mChargeStepTracker.init(); 13640 mLastChargeStepLevel = level; 13641 mMaxChargeStepLevel = level; 13642 mInitStepMode = mCurStepMode; 13643 mModStepMode = 0; 13644 } 13645 if (doWrite || (mLastWriteTimeMs + (60 * 1000)) < mSecRealtime) { 13646 if (mStatsFile != null && mBatteryStatsHistory.getActiveFile() != null) { 13647 writeAsyncLocked(); 13648 } 13649 } 13650 } 13651 startRecordingHistory(final long elapsedRealtimeMs, final long uptimeMs, boolean reset)13652 private void startRecordingHistory(final long elapsedRealtimeMs, final long uptimeMs, 13653 boolean reset) { 13654 mRecordingHistory = true; 13655 mHistoryCur.currentTime = mClocks.currentTimeMillis(); 13656 addHistoryBufferLocked(elapsedRealtimeMs, 13657 reset ? HistoryItem.CMD_RESET : HistoryItem.CMD_CURRENT_TIME, 13658 mHistoryCur); 13659 mHistoryCur.currentTime = 0; 13660 if (reset) { 13661 initActiveHistoryEventsLocked(elapsedRealtimeMs, uptimeMs); 13662 } 13663 } 13664 recordCurrentTimeChangeLocked(final long currentTimeMs, final long elapsedRealtimeMs, final long uptimeMs)13665 private void recordCurrentTimeChangeLocked(final long currentTimeMs, 13666 final long elapsedRealtimeMs, final long uptimeMs) { 13667 if (mRecordingHistory) { 13668 mHistoryCur.currentTime = currentTimeMs; 13669 addHistoryBufferLocked(elapsedRealtimeMs, HistoryItem.CMD_CURRENT_TIME, mHistoryCur); 13670 mHistoryCur.currentTime = 0; 13671 } 13672 } 13673 recordShutdownLocked(final long currentTimeMs, final long elapsedRealtimeMs)13674 private void recordShutdownLocked(final long currentTimeMs, final long elapsedRealtimeMs) { 13675 if (mRecordingHistory) { 13676 mHistoryCur.currentTime = currentTimeMs; 13677 addHistoryBufferLocked(elapsedRealtimeMs, HistoryItem.CMD_SHUTDOWN, mHistoryCur); 13678 mHistoryCur.currentTime = 0; 13679 } 13680 } 13681 scheduleSyncExternalStatsLocked(String reason, int updateFlags)13682 private void scheduleSyncExternalStatsLocked(String reason, int updateFlags) { 13683 if (mExternalSync != null) { 13684 mExternalSync.scheduleSync(reason, updateFlags); 13685 } 13686 } 13687 13688 // This should probably be exposed in the API, though it's not critical 13689 public static final int BATTERY_PLUGGED_NONE = OsProtoEnums.BATTERY_PLUGGED_NONE; // = 0 13690 13691 @GuardedBy("this") setBatteryStateLocked(final int status, final int health, final int plugType, final int level, int temp, final int voltageMv, final int chargeUah, final int chargeFullUah, final long chargeTimeToFullSeconds)13692 public void setBatteryStateLocked(final int status, final int health, final int plugType, 13693 final int level, /* not final */ int temp, final int voltageMv, final int chargeUah, 13694 final int chargeFullUah, final long chargeTimeToFullSeconds) { 13695 setBatteryStateLocked(status, health, plugType, level, temp, voltageMv, chargeUah, 13696 chargeFullUah, chargeTimeToFullSeconds, 13697 mClocks.elapsedRealtime(), mClocks.uptimeMillis(), mClocks.currentTimeMillis()); 13698 } 13699 setBatteryStateLocked(final int status, final int health, final int plugType, final int level, int temp, final int voltageMv, final int chargeUah, final int chargeFullUah, final long chargeTimeToFullSeconds, final long elapsedRealtimeMs, final long uptimeMs, final long currentTimeMs)13700 public void setBatteryStateLocked(final int status, final int health, final int plugType, 13701 final int level, /* not final */ int temp, final int voltageMv, final int chargeUah, 13702 final int chargeFullUah, final long chargeTimeToFullSeconds, 13703 final long elapsedRealtimeMs, final long uptimeMs, final long currentTimeMs) { 13704 // Temperature is encoded without the signed bit, so clamp any negative temperatures to 0. 13705 temp = Math.max(0, temp); 13706 13707 reportChangesToStatsLog(mHaveBatteryLevel ? mHistoryCur : null, 13708 status, plugType, level); 13709 13710 final boolean onBattery = isOnBattery(plugType, status); 13711 if (!mHaveBatteryLevel) { 13712 mHaveBatteryLevel = true; 13713 // We start out assuming that the device is plugged in (not 13714 // on battery). If our first report is now that we are indeed 13715 // plugged in, then twiddle our state to correctly reflect that 13716 // since we won't be going through the full setOnBattery(). 13717 if (onBattery == mOnBattery) { 13718 if (onBattery) { 13719 mHistoryCur.states &= ~HistoryItem.STATE_BATTERY_PLUGGED_FLAG; 13720 } else { 13721 mHistoryCur.states |= HistoryItem.STATE_BATTERY_PLUGGED_FLAG; 13722 } 13723 } 13724 // Always start out assuming charging, that will be updated later. 13725 mHistoryCur.states2 |= HistoryItem.STATE2_CHARGING_FLAG; 13726 mHistoryCur.batteryStatus = (byte)status; 13727 mHistoryCur.batteryLevel = (byte)level; 13728 mHistoryCur.batteryChargeUah = chargeUah; 13729 mMaxChargeStepLevel = mMinDischargeStepLevel = 13730 mLastChargeStepLevel = mLastDischargeStepLevel = level; 13731 mLastChargingStateLevel = level; 13732 } else if (mCurrentBatteryLevel != level || mOnBattery != onBattery) { 13733 recordDailyStatsIfNeededLocked(level >= 100 && onBattery, currentTimeMs); 13734 } 13735 int oldStatus = mHistoryCur.batteryStatus; 13736 if (onBattery) { 13737 mDischargeCurrentLevel = level; 13738 if (!mRecordingHistory) { 13739 mRecordingHistory = true; 13740 startRecordingHistory(elapsedRealtimeMs, uptimeMs, true); 13741 } 13742 } else if (level < 96 && 13743 status != BatteryManager.BATTERY_STATUS_UNKNOWN) { 13744 if (!mRecordingHistory) { 13745 mRecordingHistory = true; 13746 startRecordingHistory(elapsedRealtimeMs, uptimeMs, true); 13747 } 13748 } 13749 mBatteryVoltageMv = voltageMv; 13750 mCurrentBatteryLevel = level; 13751 if (mDischargePlugLevel < 0) { 13752 mDischargePlugLevel = level; 13753 } 13754 13755 if (onBattery != mOnBattery) { 13756 mHistoryCur.batteryLevel = (byte)level; 13757 mHistoryCur.batteryStatus = (byte)status; 13758 mHistoryCur.batteryHealth = (byte)health; 13759 mHistoryCur.batteryPlugType = (byte)plugType; 13760 mHistoryCur.batteryTemperature = (short)temp; 13761 mHistoryCur.batteryVoltage = (char) voltageMv; 13762 if (chargeUah < mHistoryCur.batteryChargeUah) { 13763 // Only record discharges 13764 final long chargeDiff = mHistoryCur.batteryChargeUah - chargeUah; 13765 mDischargeCounter.addCountLocked(chargeDiff); 13766 mDischargeScreenOffCounter.addCountLocked(chargeDiff); 13767 if (Display.isDozeState(mScreenState)) { 13768 mDischargeScreenDozeCounter.addCountLocked(chargeDiff); 13769 } 13770 if (mDeviceIdleMode == DEVICE_IDLE_MODE_LIGHT) { 13771 mDischargeLightDozeCounter.addCountLocked(chargeDiff); 13772 } else if (mDeviceIdleMode == DEVICE_IDLE_MODE_DEEP) { 13773 mDischargeDeepDozeCounter.addCountLocked(chargeDiff); 13774 } 13775 } 13776 mHistoryCur.batteryChargeUah = chargeUah; 13777 setOnBatteryLocked(elapsedRealtimeMs, uptimeMs, onBattery, oldStatus, level, chargeUah); 13778 } else { 13779 boolean changed = false; 13780 if (mHistoryCur.batteryLevel != level) { 13781 mHistoryCur.batteryLevel = (byte)level; 13782 changed = true; 13783 13784 // TODO(adamlesinski): Schedule the creation of a HistoryStepDetails record 13785 // which will pull external stats. 13786 mExternalSync.scheduleSyncDueToBatteryLevelChange( 13787 mConstants.BATTERY_LEVEL_COLLECTION_DELAY_MS); 13788 } 13789 if (mHistoryCur.batteryStatus != status) { 13790 mHistoryCur.batteryStatus = (byte)status; 13791 changed = true; 13792 } 13793 if (mHistoryCur.batteryHealth != health) { 13794 mHistoryCur.batteryHealth = (byte)health; 13795 changed = true; 13796 } 13797 if (mHistoryCur.batteryPlugType != plugType) { 13798 mHistoryCur.batteryPlugType = (byte)plugType; 13799 changed = true; 13800 } 13801 if (temp >= (mHistoryCur.batteryTemperature+10) 13802 || temp <= (mHistoryCur.batteryTemperature-10)) { 13803 mHistoryCur.batteryTemperature = (short)temp; 13804 changed = true; 13805 } 13806 if (voltageMv > (mHistoryCur.batteryVoltage + 20) 13807 || voltageMv < (mHistoryCur.batteryVoltage - 20)) { 13808 mHistoryCur.batteryVoltage = (char) voltageMv; 13809 changed = true; 13810 } 13811 if (chargeUah >= (mHistoryCur.batteryChargeUah + 10) 13812 || chargeUah <= (mHistoryCur.batteryChargeUah - 10)) { 13813 if (chargeUah < mHistoryCur.batteryChargeUah) { 13814 // Only record discharges 13815 final long chargeDiff = mHistoryCur.batteryChargeUah - chargeUah; 13816 mDischargeCounter.addCountLocked(chargeDiff); 13817 mDischargeScreenOffCounter.addCountLocked(chargeDiff); 13818 if (Display.isDozeState(mScreenState)) { 13819 mDischargeScreenDozeCounter.addCountLocked(chargeDiff); 13820 } 13821 if (mDeviceIdleMode == DEVICE_IDLE_MODE_LIGHT) { 13822 mDischargeLightDozeCounter.addCountLocked(chargeDiff); 13823 } else if (mDeviceIdleMode == DEVICE_IDLE_MODE_DEEP) { 13824 mDischargeDeepDozeCounter.addCountLocked(chargeDiff); 13825 } 13826 } 13827 mHistoryCur.batteryChargeUah = chargeUah; 13828 changed = true; 13829 } 13830 long modeBits = (((long)mInitStepMode) << STEP_LEVEL_INITIAL_MODE_SHIFT) 13831 | (((long)mModStepMode) << STEP_LEVEL_MODIFIED_MODE_SHIFT) 13832 | (((long)(level&0xff)) << STEP_LEVEL_LEVEL_SHIFT); 13833 if (onBattery) { 13834 changed |= setChargingLocked(false); 13835 if (mLastDischargeStepLevel != level && mMinDischargeStepLevel > level) { 13836 mDischargeStepTracker.addLevelSteps(mLastDischargeStepLevel - level, 13837 modeBits, elapsedRealtimeMs); 13838 mDailyDischargeStepTracker.addLevelSteps(mLastDischargeStepLevel - level, 13839 modeBits, elapsedRealtimeMs); 13840 mLastDischargeStepLevel = level; 13841 mMinDischargeStepLevel = level; 13842 mInitStepMode = mCurStepMode; 13843 mModStepMode = 0; 13844 } 13845 } else { 13846 if (level >= 90) { 13847 // If the battery level is at least 90%, always consider the device to be 13848 // charging even if it happens to go down a level. 13849 changed |= setChargingLocked(true); 13850 } else if (!mCharging) { 13851 if (mLastChargeStepLevel < level) { 13852 // We have not reported that we are charging, but the level has gone up, 13853 // but we would like to not have tons of activity from charging-constraint 13854 // jobs, so instead of reporting ACTION_CHARGING immediately, we defer it. 13855 if (!mHandler.hasCallbacks(mDeferSetCharging)) { 13856 mHandler.postDelayed( 13857 mDeferSetCharging, 13858 mConstants.BATTERY_CHARGED_DELAY_MS); 13859 } 13860 } else if (mLastChargeStepLevel > level) { 13861 // if we had deferred a runnable due to charge level increasing, but then 13862 // later the charge level drops (could be due to thermal issues), we don't 13863 // want to trigger the deferred runnable, so remove it here 13864 mHandler.removeCallbacks(mDeferSetCharging); 13865 } 13866 } else { 13867 if (mLastChargeStepLevel > level) { 13868 // We had reported that the device was charging, but here we are with 13869 // power connected and the level going down. Looks like the current 13870 // power supplied isn't enough, so consider the device to now be 13871 // discharging. 13872 changed |= setChargingLocked(false); 13873 } 13874 } 13875 if (mLastChargeStepLevel != level && mMaxChargeStepLevel < level) { 13876 mChargeStepTracker.addLevelSteps(level - mLastChargeStepLevel, 13877 modeBits, elapsedRealtimeMs); 13878 mDailyChargeStepTracker.addLevelSteps(level - mLastChargeStepLevel, 13879 modeBits, elapsedRealtimeMs); 13880 mMaxChargeStepLevel = level; 13881 mInitStepMode = mCurStepMode; 13882 mModStepMode = 0; 13883 } 13884 mLastChargeStepLevel = level; 13885 } 13886 if (changed) { 13887 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 13888 } 13889 } 13890 if (!onBattery && 13891 (status == BatteryManager.BATTERY_STATUS_FULL || 13892 status == BatteryManager.BATTERY_STATUS_UNKNOWN)) { 13893 // We don't record history while we are plugged in and fully charged 13894 // (or when battery is not present). The next time we are 13895 // unplugged, history will be cleared. 13896 mRecordingHistory = DEBUG; 13897 } 13898 13899 mLastLearnedBatteryCapacityUah = chargeFullUah; 13900 if (mMinLearnedBatteryCapacityUah == -1) { 13901 mMinLearnedBatteryCapacityUah = chargeFullUah; 13902 } else { 13903 mMinLearnedBatteryCapacityUah = Math.min(mMinLearnedBatteryCapacityUah, chargeFullUah); 13904 } 13905 mMaxLearnedBatteryCapacityUah = Math.max(mMaxLearnedBatteryCapacityUah, chargeFullUah); 13906 13907 mBatteryTimeToFullSeconds = chargeTimeToFullSeconds; 13908 } 13909 isOnBattery(int plugType, int status)13910 public static boolean isOnBattery(int plugType, int status) { 13911 return plugType == BATTERY_PLUGGED_NONE && status != BatteryManager.BATTERY_STATUS_UNKNOWN; 13912 } 13913 13914 // Inform StatsLog of setBatteryState changes. 13915 // If this is the first reporting, pass in recentPast == null. reportChangesToStatsLog(HistoryItem recentPast, final int status, final int plugType, final int level)13916 private void reportChangesToStatsLog(HistoryItem recentPast, 13917 final int status, final int plugType, final int level) { 13918 13919 if (recentPast == null || recentPast.batteryStatus != status) { 13920 FrameworkStatsLog.write(FrameworkStatsLog.CHARGING_STATE_CHANGED, status); 13921 } 13922 if (recentPast == null || recentPast.batteryPlugType != plugType) { 13923 FrameworkStatsLog.write(FrameworkStatsLog.PLUGGED_STATE_CHANGED, plugType); 13924 } 13925 if (recentPast == null || recentPast.batteryLevel != level) { 13926 FrameworkStatsLog.write(FrameworkStatsLog.BATTERY_LEVEL_CHANGED, level); 13927 } 13928 } 13929 13930 @UnsupportedAppUsage getAwakeTimeBattery()13931 public long getAwakeTimeBattery() { 13932 // This previously evaluated to mOnBatteryTimeBase.getUptime(getBatteryUptimeLocked()); 13933 // for over a decade, but surely that was a mistake. 13934 return getBatteryUptimeLocked(mClocks.uptimeMillis()); 13935 } 13936 13937 @UnsupportedAppUsage getAwakeTimePlugged()13938 public long getAwakeTimePlugged() { 13939 return (mClocks.uptimeMillis() * 1000) - getAwakeTimeBattery(); 13940 } 13941 13942 @Override computeUptime(long curTimeUs, int which)13943 public long computeUptime(long curTimeUs, int which) { 13944 return mUptimeUs + (curTimeUs - mUptimeStartUs); 13945 } 13946 13947 @Override computeRealtime(long curTimeUs, int which)13948 public long computeRealtime(long curTimeUs, int which) { 13949 return mRealtimeUs + (curTimeUs - mRealtimeStartUs); 13950 } 13951 13952 @Override 13953 @UnsupportedAppUsage computeBatteryUptime(long curTimeUs, int which)13954 public long computeBatteryUptime(long curTimeUs, int which) { 13955 return mOnBatteryTimeBase.computeUptime(curTimeUs, which); 13956 } 13957 13958 @Override 13959 @UnsupportedAppUsage computeBatteryRealtime(long curTimeUs, int which)13960 public long computeBatteryRealtime(long curTimeUs, int which) { 13961 return mOnBatteryTimeBase.computeRealtime(curTimeUs, which); 13962 } 13963 13964 @Override computeBatteryScreenOffUptime(long curTimeUs, int which)13965 public long computeBatteryScreenOffUptime(long curTimeUs, int which) { 13966 return mOnBatteryScreenOffTimeBase.computeUptime(curTimeUs, which); 13967 } 13968 13969 @Override computeBatteryScreenOffRealtime(long curTimeUs, int which)13970 public long computeBatteryScreenOffRealtime(long curTimeUs, int which) { 13971 return mOnBatteryScreenOffTimeBase.computeRealtime(curTimeUs, which); 13972 } 13973 computeTimePerLevel(long[] steps, int numSteps)13974 private long computeTimePerLevel(long[] steps, int numSteps) { 13975 // For now we'll do a simple average across all steps. 13976 if (numSteps <= 0) { 13977 return -1; 13978 } 13979 long total = 0; 13980 for (int i=0; i<numSteps; i++) { 13981 total += steps[i] & STEP_LEVEL_TIME_MASK; 13982 } 13983 return total / numSteps; 13984 /* 13985 long[] buckets = new long[numSteps]; 13986 int numBuckets = 0; 13987 int numToAverage = 4; 13988 int i = 0; 13989 while (i < numSteps) { 13990 long totalTime = 0; 13991 int num = 0; 13992 for (int j=0; j<numToAverage && (i+j)<numSteps; j++) { 13993 totalTime += steps[i+j] & STEP_LEVEL_TIME_MASK; 13994 num++; 13995 } 13996 buckets[numBuckets] = totalTime / num; 13997 numBuckets++; 13998 numToAverage *= 2; 13999 i += num; 14000 } 14001 if (numBuckets < 1) { 14002 return -1; 14003 } 14004 long averageTime = buckets[numBuckets-1]; 14005 for (i=numBuckets-2; i>=0; i--) { 14006 averageTime = (averageTime + buckets[i]) / 2; 14007 } 14008 return averageTime; 14009 */ 14010 } 14011 14012 @Override 14013 @UnsupportedAppUsage computeBatteryTimeRemaining(long curTime)14014 public long computeBatteryTimeRemaining(long curTime) { 14015 if (!mOnBattery) { 14016 return -1; 14017 } 14018 /* Simple implementation just looks at the average discharge per level across the 14019 entire sample period. 14020 int discharge = (getLowDischargeAmountSinceCharge()+getHighDischargeAmountSinceCharge())/2; 14021 if (discharge < 2) { 14022 return -1; 14023 } 14024 long duration = computeBatteryRealtime(curTime, STATS_SINCE_CHARGED); 14025 if (duration < 1000*1000) { 14026 return -1; 14027 } 14028 long usPerLevel = duration/discharge; 14029 return usPerLevel * mCurrentBatteryLevel; 14030 */ 14031 if (mDischargeStepTracker.mNumStepDurations < 1) { 14032 return -1; 14033 } 14034 long msPerLevel = mDischargeStepTracker.computeTimePerLevel(); 14035 if (msPerLevel <= 0) { 14036 return -1; 14037 } 14038 return (msPerLevel * mCurrentBatteryLevel) * 1000; 14039 } 14040 14041 @Override getDischargeLevelStepTracker()14042 public LevelStepTracker getDischargeLevelStepTracker() { 14043 return mDischargeStepTracker; 14044 } 14045 14046 @Override getDailyDischargeLevelStepTracker()14047 public LevelStepTracker getDailyDischargeLevelStepTracker() { 14048 return mDailyDischargeStepTracker; 14049 } 14050 14051 @Override computeChargeTimeRemaining(long curTime)14052 public long computeChargeTimeRemaining(long curTime) { 14053 if (mOnBattery) { 14054 // Not yet working. 14055 return -1; 14056 } 14057 if (mBatteryTimeToFullSeconds >= 0) { 14058 return mBatteryTimeToFullSeconds * (1000 * 1000); // s to us 14059 } 14060 // Else use algorithmic approach 14061 if (mChargeStepTracker.mNumStepDurations < 1) { 14062 return -1; 14063 } 14064 long msPerLevel = mChargeStepTracker.computeTimePerLevel(); 14065 if (msPerLevel <= 0) { 14066 return -1; 14067 } 14068 return (msPerLevel * (100 - mCurrentBatteryLevel)) * 1000; 14069 } 14070 14071 /*@hide */ getCellularBatteryStats()14072 public CellularBatteryStats getCellularBatteryStats() { 14073 final int which = STATS_SINCE_CHARGED; 14074 final long rawRealTimeUs = SystemClock.elapsedRealtime() * 1000; 14075 final ControllerActivityCounter counter = getModemControllerActivity(); 14076 final long sleepTimeMs = counter.getSleepTimeCounter().getCountLocked(which); 14077 final long idleTimeMs = counter.getIdleTimeCounter().getCountLocked(which); 14078 final long rxTimeMs = counter.getRxTimeCounter().getCountLocked(which); 14079 final long energyConsumedMaMs = counter.getPowerCounter().getCountLocked(which); 14080 final long monitoredRailChargeConsumedMaMs = 14081 counter.getMonitoredRailChargeConsumedMaMs().getCountLocked(which); 14082 long[] timeInRatMs = new long[BatteryStats.NUM_DATA_CONNECTION_TYPES]; 14083 for (int i = 0; i < timeInRatMs.length; i++) { 14084 timeInRatMs[i] = getPhoneDataConnectionTime(i, rawRealTimeUs, which) / 1000; 14085 } 14086 long[] timeInRxSignalStrengthLevelMs = 14087 new long[CellSignalStrength.getNumSignalStrengthLevels()]; 14088 for (int i = 0; i < timeInRxSignalStrengthLevelMs.length; i++) { 14089 timeInRxSignalStrengthLevelMs[i] = 14090 getPhoneSignalStrengthTime(i, rawRealTimeUs, which) / 1000; 14091 } 14092 long[] txTimeMs = new long[Math.min(ModemActivityInfo.getNumTxPowerLevels(), 14093 counter.getTxTimeCounters().length)]; 14094 long totalTxTimeMs = 0; 14095 for (int i = 0; i < txTimeMs.length; i++) { 14096 txTimeMs[i] = counter.getTxTimeCounters()[i].getCountLocked(which); 14097 totalTxTimeMs += txTimeMs[i]; 14098 } 14099 14100 return new CellularBatteryStats(computeBatteryRealtime(rawRealTimeUs, which) / 1000, 14101 getMobileRadioActiveTime(rawRealTimeUs, which) / 1000, 14102 getNetworkActivityPackets(NETWORK_MOBILE_TX_DATA, which), 14103 getNetworkActivityBytes(NETWORK_MOBILE_TX_DATA, which), 14104 getNetworkActivityPackets(NETWORK_MOBILE_RX_DATA, which), 14105 getNetworkActivityBytes(NETWORK_MOBILE_RX_DATA, which), 14106 sleepTimeMs, idleTimeMs, rxTimeMs, energyConsumedMaMs, timeInRatMs, 14107 timeInRxSignalStrengthLevelMs, txTimeMs, 14108 monitoredRailChargeConsumedMaMs); 14109 } 14110 14111 /*@hide */ getWifiBatteryStats()14112 public WifiBatteryStats getWifiBatteryStats() { 14113 final int which = STATS_SINCE_CHARGED; 14114 final long rawRealTimeUs = SystemClock.elapsedRealtime() * 1000; 14115 final ControllerActivityCounter counter = getWifiControllerActivity(); 14116 final long idleTimeMs = counter.getIdleTimeCounter().getCountLocked(which); 14117 final long scanTimeMs = counter.getScanTimeCounter().getCountLocked(which); 14118 final long rxTimeMs = counter.getRxTimeCounter().getCountLocked(which); 14119 final long txTimeMs = counter.getTxTimeCounters()[0].getCountLocked(which); 14120 final long totalControllerActivityTimeMs 14121 = computeBatteryRealtime(SystemClock.elapsedRealtime() * 1000, which) / 1000; 14122 final long sleepTimeMs 14123 = totalControllerActivityTimeMs - (idleTimeMs + rxTimeMs + txTimeMs); 14124 final long energyConsumedMaMs = counter.getPowerCounter().getCountLocked(which); 14125 final long monitoredRailChargeConsumedMaMs = 14126 counter.getMonitoredRailChargeConsumedMaMs().getCountLocked(which); 14127 long numAppScanRequest = 0; 14128 for (int i = 0; i < mUidStats.size(); i++) { 14129 numAppScanRequest += mUidStats.valueAt(i).mWifiScanTimer.getCountLocked(which); 14130 } 14131 long[] timeInStateMs = new long[NUM_WIFI_STATES]; 14132 for (int i=0; i<NUM_WIFI_STATES; i++) { 14133 timeInStateMs[i] = getWifiStateTime(i, rawRealTimeUs, which) / 1000; 14134 } 14135 long[] timeInSupplStateMs = new long[NUM_WIFI_SUPPL_STATES]; 14136 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) { 14137 timeInSupplStateMs[i] = getWifiSupplStateTime(i, rawRealTimeUs, which) / 1000; 14138 } 14139 long[] timeSignalStrengthTimeMs = new long[NUM_WIFI_SIGNAL_STRENGTH_BINS]; 14140 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { 14141 timeSignalStrengthTimeMs[i] = getWifiSignalStrengthTime(i, rawRealTimeUs, which) / 1000; 14142 } 14143 return new WifiBatteryStats( 14144 computeBatteryRealtime(rawRealTimeUs, which) / 1000, 14145 getWifiActiveTime(rawRealTimeUs, which) / 1000, 14146 getNetworkActivityPackets(NETWORK_WIFI_TX_DATA, which), 14147 getNetworkActivityBytes(NETWORK_WIFI_TX_DATA, which), 14148 getNetworkActivityPackets(NETWORK_WIFI_RX_DATA, which), 14149 getNetworkActivityBytes(NETWORK_WIFI_RX_DATA, which), 14150 sleepTimeMs, scanTimeMs, idleTimeMs, rxTimeMs, txTimeMs, energyConsumedMaMs, 14151 numAppScanRequest, timeInStateMs, timeSignalStrengthTimeMs, timeInSupplStateMs, 14152 monitoredRailChargeConsumedMaMs); 14153 } 14154 14155 /*@hide */ getGpsBatteryStats()14156 public GpsBatteryStats getGpsBatteryStats() { 14157 GpsBatteryStats s = new GpsBatteryStats(); 14158 final int which = STATS_SINCE_CHARGED; 14159 final long rawRealTimeUs = SystemClock.elapsedRealtime() * 1000; 14160 s.setLoggingDurationMs(computeBatteryRealtime(rawRealTimeUs, which) / 1000); 14161 s.setEnergyConsumedMaMs(getGpsBatteryDrainMaMs()); 14162 long[] time = new long[mGpsSignalQualityTimer.length]; 14163 for (int i=0; i<time.length; i++) { 14164 time[i] = getGpsSignalQualityTime(i, rawRealTimeUs, which) / 1000; 14165 } 14166 s.setTimeInGpsSignalQualityLevel(time); 14167 return s; 14168 } 14169 14170 @Override getChargeLevelStepTracker()14171 public LevelStepTracker getChargeLevelStepTracker() { 14172 return mChargeStepTracker; 14173 } 14174 14175 @Override getDailyChargeLevelStepTracker()14176 public LevelStepTracker getDailyChargeLevelStepTracker() { 14177 return mDailyChargeStepTracker; 14178 } 14179 14180 @Override getDailyPackageChanges()14181 public ArrayList<PackageChange> getDailyPackageChanges() { 14182 return mDailyPackageChanges; 14183 } 14184 14185 /** 14186 * @return battery uptime in microseconds 14187 */ getBatteryUptimeLocked()14188 protected long getBatteryUptimeLocked() { 14189 return getBatteryUptimeLocked(mClocks.uptimeMillis()); 14190 } 14191 14192 /** 14193 * @return battery uptime in microseconds 14194 */ getBatteryUptimeLocked(long uptimeMs)14195 protected long getBatteryUptimeLocked(long uptimeMs) { 14196 return mOnBatteryTimeBase.getUptime(uptimeMs * 1000); 14197 } 14198 14199 @Override getBatteryUptime(long curTimeUs)14200 public long getBatteryUptime(long curTimeUs) { 14201 return mOnBatteryTimeBase.getUptime(curTimeUs); 14202 } 14203 14204 @Override 14205 @UnsupportedAppUsage getBatteryRealtime(long curTimeUs)14206 public long getBatteryRealtime(long curTimeUs) { 14207 return mOnBatteryTimeBase.getRealtime(curTimeUs); 14208 } 14209 14210 @Override 14211 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) getDischargeStartLevel()14212 public int getDischargeStartLevel() { 14213 synchronized(this) { 14214 return getDischargeStartLevelLocked(); 14215 } 14216 } 14217 getDischargeStartLevelLocked()14218 public int getDischargeStartLevelLocked() { 14219 return mDischargeUnplugLevel; 14220 } 14221 14222 @Override 14223 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) getDischargeCurrentLevel()14224 public int getDischargeCurrentLevel() { 14225 synchronized(this) { 14226 return getDischargeCurrentLevelLocked(); 14227 } 14228 } 14229 getDischargeCurrentLevelLocked()14230 public int getDischargeCurrentLevelLocked() { 14231 return mDischargeCurrentLevel; 14232 } 14233 14234 @Override getLowDischargeAmountSinceCharge()14235 public int getLowDischargeAmountSinceCharge() { 14236 synchronized(this) { 14237 int val = mLowDischargeAmountSinceCharge; 14238 if (mOnBattery && mDischargeCurrentLevel < mDischargeUnplugLevel) { 14239 val += mDischargeUnplugLevel-mDischargeCurrentLevel-1; 14240 } 14241 return val; 14242 } 14243 } 14244 14245 @Override getHighDischargeAmountSinceCharge()14246 public int getHighDischargeAmountSinceCharge() { 14247 synchronized(this) { 14248 int val = mHighDischargeAmountSinceCharge; 14249 if (mOnBattery && mDischargeCurrentLevel < mDischargeUnplugLevel) { 14250 val += mDischargeUnplugLevel-mDischargeCurrentLevel; 14251 } 14252 return val; 14253 } 14254 } 14255 14256 @Override 14257 @UnsupportedAppUsage getDischargeAmount(int which)14258 public int getDischargeAmount(int which) { 14259 int dischargeAmount = which == STATS_SINCE_CHARGED 14260 ? getHighDischargeAmountSinceCharge() 14261 : (getDischargeStartLevel() - getDischargeCurrentLevel()); 14262 if (dischargeAmount < 0) { 14263 dischargeAmount = 0; 14264 } 14265 return dischargeAmount; 14266 } 14267 14268 @Override 14269 @UnsupportedAppUsage getDischargeAmountScreenOn()14270 public int getDischargeAmountScreenOn() { 14271 synchronized(this) { 14272 int val = mDischargeAmountScreenOn; 14273 if (mOnBattery && Display.isOnState(mScreenState) 14274 && mDischargeCurrentLevel < mDischargeScreenOnUnplugLevel) { 14275 val += mDischargeScreenOnUnplugLevel-mDischargeCurrentLevel; 14276 } 14277 return val; 14278 } 14279 } 14280 14281 @Override getDischargeAmountScreenOnSinceCharge()14282 public int getDischargeAmountScreenOnSinceCharge() { 14283 synchronized(this) { 14284 int val = mDischargeAmountScreenOnSinceCharge; 14285 if (mOnBattery && Display.isOnState(mScreenState) 14286 && mDischargeCurrentLevel < mDischargeScreenOnUnplugLevel) { 14287 val += mDischargeScreenOnUnplugLevel-mDischargeCurrentLevel; 14288 } 14289 return val; 14290 } 14291 } 14292 14293 @Override 14294 @UnsupportedAppUsage getDischargeAmountScreenOff()14295 public int getDischargeAmountScreenOff() { 14296 synchronized(this) { 14297 int val = mDischargeAmountScreenOff; 14298 if (mOnBattery && Display.isOffState(mScreenState) 14299 && mDischargeCurrentLevel < mDischargeScreenOffUnplugLevel) { 14300 val += mDischargeScreenOffUnplugLevel-mDischargeCurrentLevel; 14301 } 14302 // For backward compatibility, doze discharge is counted into screen off. 14303 return val + getDischargeAmountScreenDoze(); 14304 } 14305 } 14306 14307 @Override getDischargeAmountScreenOffSinceCharge()14308 public int getDischargeAmountScreenOffSinceCharge() { 14309 synchronized(this) { 14310 int val = mDischargeAmountScreenOffSinceCharge; 14311 if (mOnBattery && Display.isOffState(mScreenState) 14312 && mDischargeCurrentLevel < mDischargeScreenOffUnplugLevel) { 14313 val += mDischargeScreenOffUnplugLevel-mDischargeCurrentLevel; 14314 } 14315 // For backward compatibility, doze discharge is counted into screen off. 14316 return val + getDischargeAmountScreenDozeSinceCharge(); 14317 } 14318 } 14319 14320 @Override getDischargeAmountScreenDoze()14321 public int getDischargeAmountScreenDoze() { 14322 synchronized(this) { 14323 int val = mDischargeAmountScreenDoze; 14324 if (mOnBattery && Display.isDozeState(mScreenState) 14325 && mDischargeCurrentLevel < mDischargeScreenDozeUnplugLevel) { 14326 val += mDischargeScreenDozeUnplugLevel-mDischargeCurrentLevel; 14327 } 14328 return val; 14329 } 14330 } 14331 14332 @Override getDischargeAmountScreenDozeSinceCharge()14333 public int getDischargeAmountScreenDozeSinceCharge() { 14334 synchronized(this) { 14335 int val = mDischargeAmountScreenDozeSinceCharge; 14336 if (mOnBattery && Display.isDozeState(mScreenState) 14337 && mDischargeCurrentLevel < mDischargeScreenDozeUnplugLevel) { 14338 val += mDischargeScreenDozeUnplugLevel-mDischargeCurrentLevel; 14339 } 14340 return val; 14341 } 14342 } 14343 14344 14345 /** 14346 * Estimates the time spent by the system server handling incoming binder requests. 14347 */ 14348 @Override getSystemServiceTimeAtCpuSpeeds()14349 public long[] getSystemServiceTimeAtCpuSpeeds() { 14350 if (mBinderThreadCpuTimesUs == null) { 14351 return null; 14352 } 14353 14354 return mBinderThreadCpuTimesUs.getCountsLocked(BatteryStats.STATS_SINCE_CHARGED); 14355 } 14356 14357 /** 14358 * Retrieve the statistics object for a particular uid, creating if needed. 14359 */ 14360 @UnsupportedAppUsage getUidStatsLocked(int uid)14361 public Uid getUidStatsLocked(int uid) { 14362 return getUidStatsLocked(uid, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 14363 } 14364 getUidStatsLocked(int uid, long elapsedRealtimeMs, long uptimeMs)14365 public Uid getUidStatsLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 14366 Uid u = mUidStats.get(uid); 14367 if (u == null) { 14368 u = new Uid(this, uid, elapsedRealtimeMs, uptimeMs); 14369 mUidStats.put(uid, u); 14370 } 14371 return u; 14372 } 14373 14374 /** 14375 * Retrieve the statistics object for a particular uid. Returns null if the object is not 14376 * available. 14377 */ getAvailableUidStatsLocked(int uid)14378 public Uid getAvailableUidStatsLocked(int uid) { 14379 Uid u = mUidStats.get(uid); 14380 return u; 14381 } 14382 onCleanupUserLocked(int userId, long elapsedRealtimeMs)14383 public void onCleanupUserLocked(int userId, long elapsedRealtimeMs) { 14384 final int firstUidForUser = UserHandle.getUid(userId, 0); 14385 final int lastUidForUser = UserHandle.getUid(userId, UserHandle.PER_USER_RANGE - 1); 14386 mPendingRemovedUids.add( 14387 new UidToRemove(firstUidForUser, lastUidForUser, elapsedRealtimeMs)); 14388 } 14389 onUserRemovedLocked(int userId)14390 public void onUserRemovedLocked(int userId) { 14391 final int firstUidForUser = UserHandle.getUid(userId, 0); 14392 final int lastUidForUser = UserHandle.getUid(userId, UserHandle.PER_USER_RANGE - 1); 14393 mUidStats.put(firstUidForUser, null); 14394 mUidStats.put(lastUidForUser, null); 14395 final int firstIndex = mUidStats.indexOfKey(firstUidForUser); 14396 final int lastIndex = mUidStats.indexOfKey(lastUidForUser); 14397 for (int i = firstIndex; i <= lastIndex; i++) { 14398 final Uid uid = mUidStats.valueAt(i); 14399 if (uid != null) { 14400 uid.detachFromTimeBase(); 14401 } 14402 } 14403 mUidStats.removeAtRange(firstIndex, lastIndex - firstIndex + 1); 14404 } 14405 14406 /** 14407 * Remove the statistics object for a particular uid. 14408 */ 14409 @UnsupportedAppUsage removeUidStatsLocked(int uid)14410 public void removeUidStatsLocked(int uid) { 14411 removeUidStatsLocked(uid, mClocks.elapsedRealtime()); 14412 } 14413 14414 /** 14415 * @see #removeUidStatsLocked(int) 14416 */ removeUidStatsLocked(int uid, long elapsedRealtimeMs)14417 public void removeUidStatsLocked(int uid, long elapsedRealtimeMs) { 14418 final Uid u = mUidStats.get(uid); 14419 if (u != null) { 14420 u.detachFromTimeBase(); 14421 } 14422 mUidStats.remove(uid); 14423 mPendingRemovedUids.add(new UidToRemove(uid, elapsedRealtimeMs)); 14424 } 14425 14426 /** 14427 * Retrieve the statistics object for a particular process, creating 14428 * if needed. 14429 */ 14430 @UnsupportedAppUsage getProcessStatsLocked(int uid, String name)14431 public Uid.Proc getProcessStatsLocked(int uid, String name) { 14432 return getProcessStatsLocked(uid, name, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 14433 } 14434 14435 /** 14436 * @see #getProcessStatsLocked(int, String) 14437 */ getProcessStatsLocked(int uid, String name, long elapsedRealtimeMs, long uptimeMs)14438 public Uid.Proc getProcessStatsLocked(int uid, String name, 14439 long elapsedRealtimeMs, long uptimeMs) { 14440 uid = mapUid(uid); 14441 Uid u = getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs); 14442 return u.getProcessStatsLocked(name); 14443 } 14444 14445 /** 14446 * Retrieve the statistics object for a particular process, creating 14447 * if needed. 14448 */ 14449 @UnsupportedAppUsage getPackageStatsLocked(int uid, String pkg)14450 public Uid.Pkg getPackageStatsLocked(int uid, String pkg) { 14451 return getPackageStatsLocked(uid, pkg, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 14452 } 14453 14454 /** 14455 * @see getPackageStatsLocked(int, String) 14456 */ getPackageStatsLocked(int uid, String pkg, long elapsedRealtimeMs, long uptimeMs)14457 public Uid.Pkg getPackageStatsLocked(int uid, String pkg, 14458 long elapsedRealtimeMs, long uptimeMs) { 14459 uid = mapUid(uid); 14460 Uid u = getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs); 14461 return u.getPackageStatsLocked(pkg); 14462 } 14463 14464 /** 14465 * Retrieve the statistics object for a particular service, creating 14466 * if needed. 14467 */ 14468 @UnsupportedAppUsage getServiceStatsLocked(int uid, String pkg, String name)14469 public Uid.Pkg.Serv getServiceStatsLocked(int uid, String pkg, String name) { 14470 return getServiceStatsLocked(uid, pkg, name, 14471 mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 14472 } 14473 getServiceStatsLocked(int uid, String pkg, String name, long elapsedRealtimeMs, long uptimeMs)14474 public Uid.Pkg.Serv getServiceStatsLocked(int uid, String pkg, String name, 14475 long elapsedRealtimeMs, long uptimeMs) { 14476 uid = mapUid(uid); 14477 Uid u = getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs); 14478 return u.getServiceStatsLocked(pkg, name); 14479 } 14480 shutdownLocked()14481 public void shutdownLocked() { 14482 recordShutdownLocked(mClocks.currentTimeMillis(), mClocks.elapsedRealtime()); 14483 writeSyncLocked(); 14484 mShuttingDown = true; 14485 } 14486 trackPerProcStateCpuTimes()14487 public boolean trackPerProcStateCpuTimes() { 14488 return mConstants.TRACK_CPU_TIMES_BY_PROC_STATE && mPerProcStateCpuTimesAvailable; 14489 } 14490 systemServicesReady(Context context)14491 public void systemServicesReady(Context context) { 14492 mConstants.startObserving(context.getContentResolver()); 14493 registerUsbStateReceiver(context); 14494 } 14495 14496 /** 14497 * Initialize the measured charge stats data structures. 14498 * 14499 * @param supportedStandardBuckets boolean array indicating which {@link StandardPowerBucket}s 14500 * are currently supported. If null, none are supported 14501 * (regardless of customBucketNames). 14502 * @param customBucketNames names of custom (OTHER) EnergyConsumers on this device 14503 */ 14504 @GuardedBy("this") initMeasuredEnergyStatsLocked(@ullable boolean[] supportedStandardBuckets, String[] customBucketNames)14505 public void initMeasuredEnergyStatsLocked(@Nullable boolean[] supportedStandardBuckets, 14506 String[] customBucketNames) { 14507 boolean supportedBucketMismatch = false; 14508 mScreenStateAtLastEnergyMeasurement = mScreenState; 14509 14510 if (supportedStandardBuckets == null) { 14511 if (mGlobalMeasuredEnergyStats != null) { 14512 // Measured energy no longer supported, wipe out the existing data. 14513 supportedBucketMismatch = true; 14514 } 14515 } else { 14516 if (mGlobalMeasuredEnergyStats == null) { 14517 mGlobalMeasuredEnergyStats = 14518 new MeasuredEnergyStats(supportedStandardBuckets, customBucketNames); 14519 } else { 14520 supportedBucketMismatch = !mGlobalMeasuredEnergyStats.isSupportEqualTo( 14521 supportedStandardBuckets, customBucketNames); 14522 } 14523 14524 if (supportedStandardBuckets[MeasuredEnergyStats.POWER_BUCKET_BLUETOOTH]) { 14525 mBluetoothPowerCalculator = new BluetoothPowerCalculator(mPowerProfile); 14526 } 14527 if (supportedStandardBuckets[MeasuredEnergyStats.POWER_BUCKET_CPU]) { 14528 mCpuPowerCalculator = new CpuPowerCalculator(mPowerProfile); 14529 } 14530 if (supportedStandardBuckets[MeasuredEnergyStats.POWER_BUCKET_MOBILE_RADIO]) { 14531 mMobileRadioPowerCalculator = new MobileRadioPowerCalculator(mPowerProfile); 14532 } 14533 if (supportedStandardBuckets[MeasuredEnergyStats.POWER_BUCKET_WIFI]) { 14534 mWifiPowerCalculator = new WifiPowerCalculator(mPowerProfile); 14535 } 14536 } 14537 14538 if (supportedBucketMismatch) { 14539 mGlobalMeasuredEnergyStats = supportedStandardBuckets == null 14540 ? null : new MeasuredEnergyStats(supportedStandardBuckets, customBucketNames); 14541 // Supported power buckets changed since last boot. 14542 // Existing data is no longer reliable. 14543 resetAllStatsLocked(SystemClock.uptimeMillis(), SystemClock.elapsedRealtime(), 14544 RESET_REASON_MEASURED_ENERGY_BUCKETS_CHANGE); 14545 } 14546 } 14547 14548 /** Get the last known Battery voltage (in millivolts), returns -1 if unknown */ 14549 @GuardedBy("this") getBatteryVoltageMvLocked()14550 public int getBatteryVoltageMvLocked() { 14551 return mBatteryVoltageMv; 14552 } 14553 14554 @VisibleForTesting 14555 public final class Constants extends ContentObserver { 14556 public static final String KEY_TRACK_CPU_TIMES_BY_PROC_STATE 14557 = "track_cpu_times_by_proc_state"; 14558 public static final String KEY_TRACK_CPU_ACTIVE_CLUSTER_TIME 14559 = "track_cpu_active_cluster_time"; 14560 public static final String KEY_PROC_STATE_CPU_TIMES_READ_DELAY_MS 14561 = "proc_state_cpu_times_read_delay_ms"; 14562 public static final String KEY_KERNEL_UID_READERS_THROTTLE_TIME 14563 = "kernel_uid_readers_throttle_time"; 14564 public static final String KEY_UID_REMOVE_DELAY_MS 14565 = "uid_remove_delay_ms"; 14566 public static final String KEY_EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS 14567 = "external_stats_collection_rate_limit_ms"; 14568 public static final String KEY_BATTERY_LEVEL_COLLECTION_DELAY_MS 14569 = "battery_level_collection_delay_ms"; 14570 public static final String KEY_MAX_HISTORY_FILES = "max_history_files"; 14571 public static final String KEY_MAX_HISTORY_BUFFER_KB = "max_history_buffer_kb"; 14572 public static final String KEY_BATTERY_CHARGED_DELAY_MS = 14573 "battery_charged_delay_ms"; 14574 14575 private static final boolean DEFAULT_TRACK_CPU_TIMES_BY_PROC_STATE = false; 14576 private static final boolean DEFAULT_TRACK_CPU_ACTIVE_CLUSTER_TIME = true; 14577 private static final long DEFAULT_PROC_STATE_CPU_TIMES_READ_DELAY_MS = 5_000; 14578 private static final long DEFAULT_KERNEL_UID_READERS_THROTTLE_TIME = 1_000; 14579 private static final long DEFAULT_UID_REMOVE_DELAY_MS = 5L * 60L * 1000L; 14580 private static final long DEFAULT_EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS = 600_000; 14581 private static final long DEFAULT_BATTERY_LEVEL_COLLECTION_DELAY_MS = 300_000; 14582 private static final int DEFAULT_MAX_HISTORY_FILES = 32; 14583 private static final int DEFAULT_MAX_HISTORY_BUFFER_KB = 128; /*Kilo Bytes*/ 14584 private static final int DEFAULT_MAX_HISTORY_FILES_LOW_RAM_DEVICE = 64; 14585 private static final int DEFAULT_MAX_HISTORY_BUFFER_LOW_RAM_DEVICE_KB = 64; /*Kilo Bytes*/ 14586 private static final int DEFAULT_BATTERY_CHARGED_DELAY_MS = 900000; /* 15 min */ 14587 14588 public boolean TRACK_CPU_TIMES_BY_PROC_STATE = DEFAULT_TRACK_CPU_TIMES_BY_PROC_STATE; 14589 public boolean TRACK_CPU_ACTIVE_CLUSTER_TIME = DEFAULT_TRACK_CPU_ACTIVE_CLUSTER_TIME; 14590 public long PROC_STATE_CPU_TIMES_READ_DELAY_MS = DEFAULT_PROC_STATE_CPU_TIMES_READ_DELAY_MS; 14591 /* Do not set default value for KERNEL_UID_READERS_THROTTLE_TIME. Need to trigger an 14592 * update when startObserving. */ 14593 public long KERNEL_UID_READERS_THROTTLE_TIME; 14594 public long UID_REMOVE_DELAY_MS = DEFAULT_UID_REMOVE_DELAY_MS; 14595 public long EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS 14596 = DEFAULT_EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS; 14597 public long BATTERY_LEVEL_COLLECTION_DELAY_MS 14598 = DEFAULT_BATTERY_LEVEL_COLLECTION_DELAY_MS; 14599 public int MAX_HISTORY_FILES; 14600 public int MAX_HISTORY_BUFFER; /*Bytes*/ 14601 public int BATTERY_CHARGED_DELAY_MS = DEFAULT_BATTERY_CHARGED_DELAY_MS; 14602 14603 private ContentResolver mResolver; 14604 private final KeyValueListParser mParser = new KeyValueListParser(','); 14605 Constants(Handler handler)14606 public Constants(Handler handler) { 14607 super(handler); 14608 if (ActivityManager.isLowRamDeviceStatic()) { 14609 MAX_HISTORY_FILES = DEFAULT_MAX_HISTORY_FILES_LOW_RAM_DEVICE; 14610 MAX_HISTORY_BUFFER = DEFAULT_MAX_HISTORY_BUFFER_LOW_RAM_DEVICE_KB * 1024; 14611 } else { 14612 MAX_HISTORY_FILES = DEFAULT_MAX_HISTORY_FILES; 14613 MAX_HISTORY_BUFFER = DEFAULT_MAX_HISTORY_BUFFER_KB * 1024; 14614 } 14615 } 14616 startObserving(ContentResolver resolver)14617 public void startObserving(ContentResolver resolver) { 14618 mResolver = resolver; 14619 mResolver.registerContentObserver( 14620 Settings.Global.getUriFor(Settings.Global.BATTERY_STATS_CONSTANTS), 14621 false /* notifyForDescendants */, this); 14622 mResolver.registerContentObserver( 14623 Settings.Global.getUriFor(Settings.Global.BATTERY_CHARGING_STATE_UPDATE_DELAY), 14624 false /* notifyForDescendants */, this); 14625 updateConstants(); 14626 } 14627 14628 @Override onChange(boolean selfChange, Uri uri)14629 public void onChange(boolean selfChange, Uri uri) { 14630 if (uri.equals( 14631 Settings.Global.getUriFor( 14632 Settings.Global.BATTERY_CHARGING_STATE_UPDATE_DELAY))) { 14633 synchronized (BatteryStatsImpl.this) { 14634 updateBatteryChargedDelayMsLocked(); 14635 } 14636 return; 14637 } 14638 updateConstants(); 14639 } 14640 updateConstants()14641 private void updateConstants() { 14642 synchronized (BatteryStatsImpl.this) { 14643 try { 14644 mParser.setString(Settings.Global.getString(mResolver, 14645 Settings.Global.BATTERY_STATS_CONSTANTS)); 14646 } catch (IllegalArgumentException e) { 14647 // Failed to parse the settings string, log this and move on 14648 // with defaults. 14649 Slog.e(TAG, "Bad batterystats settings", e); 14650 } 14651 14652 updateTrackCpuTimesByProcStateLocked(TRACK_CPU_TIMES_BY_PROC_STATE, 14653 mParser.getBoolean(KEY_TRACK_CPU_TIMES_BY_PROC_STATE, 14654 DEFAULT_TRACK_CPU_TIMES_BY_PROC_STATE)); 14655 TRACK_CPU_ACTIVE_CLUSTER_TIME = mParser.getBoolean( 14656 KEY_TRACK_CPU_ACTIVE_CLUSTER_TIME, DEFAULT_TRACK_CPU_ACTIVE_CLUSTER_TIME); 14657 updateProcStateCpuTimesReadDelayMs(PROC_STATE_CPU_TIMES_READ_DELAY_MS, 14658 mParser.getLong(KEY_PROC_STATE_CPU_TIMES_READ_DELAY_MS, 14659 DEFAULT_PROC_STATE_CPU_TIMES_READ_DELAY_MS)); 14660 updateKernelUidReadersThrottleTime(KERNEL_UID_READERS_THROTTLE_TIME, 14661 mParser.getLong(KEY_KERNEL_UID_READERS_THROTTLE_TIME, 14662 DEFAULT_KERNEL_UID_READERS_THROTTLE_TIME)); 14663 updateUidRemoveDelay( 14664 mParser.getLong(KEY_UID_REMOVE_DELAY_MS, DEFAULT_UID_REMOVE_DELAY_MS)); 14665 EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS = mParser.getLong( 14666 KEY_EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS, 14667 DEFAULT_EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS); 14668 BATTERY_LEVEL_COLLECTION_DELAY_MS = mParser.getLong( 14669 KEY_BATTERY_LEVEL_COLLECTION_DELAY_MS, 14670 DEFAULT_BATTERY_LEVEL_COLLECTION_DELAY_MS); 14671 14672 MAX_HISTORY_FILES = mParser.getInt(KEY_MAX_HISTORY_FILES, 14673 ActivityManager.isLowRamDeviceStatic() ? 14674 DEFAULT_MAX_HISTORY_FILES_LOW_RAM_DEVICE 14675 : DEFAULT_MAX_HISTORY_FILES); 14676 MAX_HISTORY_BUFFER = mParser.getInt(KEY_MAX_HISTORY_BUFFER_KB, 14677 ActivityManager.isLowRamDeviceStatic() ? 14678 DEFAULT_MAX_HISTORY_BUFFER_LOW_RAM_DEVICE_KB 14679 : DEFAULT_MAX_HISTORY_BUFFER_KB) 14680 * 1024; 14681 updateBatteryChargedDelayMsLocked(); 14682 } 14683 } 14684 updateBatteryChargedDelayMsLocked()14685 private void updateBatteryChargedDelayMsLocked() { 14686 // a negative value indicates that we should ignore this override 14687 final int delay = Settings.Global.getInt(mResolver, 14688 Settings.Global.BATTERY_CHARGING_STATE_UPDATE_DELAY, 14689 -1); 14690 14691 BATTERY_CHARGED_DELAY_MS = delay >= 0 ? delay : mParser.getInt( 14692 KEY_BATTERY_CHARGED_DELAY_MS, 14693 DEFAULT_BATTERY_CHARGED_DELAY_MS); 14694 } 14695 updateTrackCpuTimesByProcStateLocked(boolean wasEnabled, boolean isEnabled)14696 private void updateTrackCpuTimesByProcStateLocked(boolean wasEnabled, boolean isEnabled) { 14697 TRACK_CPU_TIMES_BY_PROC_STATE = isEnabled; 14698 if (isEnabled && !wasEnabled) { 14699 mIsPerProcessStateCpuDataStale = true; 14700 mExternalSync.scheduleCpuSyncDueToSettingChange(); 14701 14702 mNumSingleUidCpuTimeReads = 0; 14703 mNumBatchedSingleUidCpuTimeReads = 0; 14704 mCpuTimeReadsTrackingStartTimeMs = mClocks.uptimeMillis(); 14705 } 14706 } 14707 updateProcStateCpuTimesReadDelayMs(long oldDelayMillis, long newDelayMillis)14708 private void updateProcStateCpuTimesReadDelayMs(long oldDelayMillis, long newDelayMillis) { 14709 PROC_STATE_CPU_TIMES_READ_DELAY_MS = newDelayMillis; 14710 if (oldDelayMillis != newDelayMillis) { 14711 mNumSingleUidCpuTimeReads = 0; 14712 mNumBatchedSingleUidCpuTimeReads = 0; 14713 mCpuTimeReadsTrackingStartTimeMs = mClocks.uptimeMillis(); 14714 } 14715 } 14716 updateKernelUidReadersThrottleTime(long oldTimeMs, long newTimeMs)14717 private void updateKernelUidReadersThrottleTime(long oldTimeMs, long newTimeMs) { 14718 KERNEL_UID_READERS_THROTTLE_TIME = newTimeMs; 14719 if (oldTimeMs != newTimeMs) { 14720 mCpuUidUserSysTimeReader.setThrottle(KERNEL_UID_READERS_THROTTLE_TIME); 14721 mCpuUidFreqTimeReader.setThrottle(KERNEL_UID_READERS_THROTTLE_TIME); 14722 mCpuUidActiveTimeReader.setThrottle(KERNEL_UID_READERS_THROTTLE_TIME); 14723 mCpuUidClusterTimeReader 14724 .setThrottle(KERNEL_UID_READERS_THROTTLE_TIME); 14725 } 14726 } 14727 updateUidRemoveDelay(long newTimeMs)14728 private void updateUidRemoveDelay(long newTimeMs) { 14729 UID_REMOVE_DELAY_MS = newTimeMs; 14730 clearPendingRemovedUids(); 14731 } 14732 dumpLocked(PrintWriter pw)14733 public void dumpLocked(PrintWriter pw) { 14734 pw.print(KEY_TRACK_CPU_TIMES_BY_PROC_STATE); pw.print("="); 14735 pw.println(TRACK_CPU_TIMES_BY_PROC_STATE); 14736 pw.print(KEY_TRACK_CPU_ACTIVE_CLUSTER_TIME); pw.print("="); 14737 pw.println(TRACK_CPU_ACTIVE_CLUSTER_TIME); 14738 pw.print(KEY_PROC_STATE_CPU_TIMES_READ_DELAY_MS); pw.print("="); 14739 pw.println(PROC_STATE_CPU_TIMES_READ_DELAY_MS); 14740 pw.print(KEY_KERNEL_UID_READERS_THROTTLE_TIME); pw.print("="); 14741 pw.println(KERNEL_UID_READERS_THROTTLE_TIME); 14742 pw.print(KEY_EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS); pw.print("="); 14743 pw.println(EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS); 14744 pw.print(KEY_BATTERY_LEVEL_COLLECTION_DELAY_MS); pw.print("="); 14745 pw.println(BATTERY_LEVEL_COLLECTION_DELAY_MS); 14746 pw.print(KEY_MAX_HISTORY_FILES); pw.print("="); 14747 pw.println(MAX_HISTORY_FILES); 14748 pw.print(KEY_MAX_HISTORY_BUFFER_KB); pw.print("="); 14749 pw.println(MAX_HISTORY_BUFFER/1024); 14750 pw.print(KEY_BATTERY_CHARGED_DELAY_MS); pw.print("="); 14751 pw.println(BATTERY_CHARGED_DELAY_MS); 14752 } 14753 } 14754 getExternalStatsCollectionRateLimitMs()14755 public long getExternalStatsCollectionRateLimitMs() { 14756 synchronized (this) { 14757 return mConstants.EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS; 14758 } 14759 } 14760 14761 @GuardedBy("this") dumpConstantsLocked(PrintWriter pw)14762 public void dumpConstantsLocked(PrintWriter pw) { 14763 final IndentingPrintWriter iPw = new IndentingPrintWriter(pw, " "); 14764 iPw.println("BatteryStats constants:"); 14765 iPw.increaseIndent(); 14766 mConstants.dumpLocked(iPw); 14767 iPw.decreaseIndent(); 14768 } 14769 14770 @GuardedBy("this") dumpCpuStatsLocked(PrintWriter pw)14771 public void dumpCpuStatsLocked(PrintWriter pw) { 14772 int size = mUidStats.size(); 14773 pw.println("Per UID CPU user & system time in ms:"); 14774 for (int i = 0; i < size; i++) { 14775 int u = mUidStats.keyAt(i); 14776 Uid uid = mUidStats.get(u); 14777 pw.print(" "); pw.print(u); pw.print(": "); 14778 pw.print(uid.getUserCpuTimeUs(STATS_SINCE_CHARGED) / 1000); pw.print(" "); 14779 pw.println(uid.getSystemCpuTimeUs(STATS_SINCE_CHARGED) / 1000); 14780 } 14781 14782 pw.println("Per UID CPU active time in ms:"); 14783 for (int i = 0; i < size; i++) { 14784 int u = mUidStats.keyAt(i); 14785 Uid uid = mUidStats.get(u); 14786 if (uid.getCpuActiveTime() > 0) { 14787 pw.print(" "); pw.print(u); pw.print(": "); pw.println(uid.getCpuActiveTime()); 14788 } 14789 } 14790 pw.println("Per UID CPU cluster time in ms:"); 14791 for (int i = 0; i < size; i++) { 14792 int u = mUidStats.keyAt(i); 14793 long[] times = mUidStats.get(u).getCpuClusterTimes(); 14794 if (times != null) { 14795 pw.print(" "); pw.print(u); pw.print(": "); pw.println(Arrays.toString(times)); 14796 } 14797 } 14798 pw.println("Per UID CPU frequency time in ms:"); 14799 for (int i = 0; i < size; i++) { 14800 int u = mUidStats.keyAt(i); 14801 long[] times = mUidStats.get(u).getCpuFreqTimes(STATS_SINCE_CHARGED); 14802 if (times != null) { 14803 pw.print(" "); pw.print(u); pw.print(": "); pw.println(Arrays.toString(times)); 14804 } 14805 } 14806 14807 updateSystemServiceCallStats(); 14808 if (mBinderThreadCpuTimesUs != null) { 14809 pw.println("Per UID System server binder time in ms:"); 14810 long[] systemServiceTimeAtCpuSpeeds = getSystemServiceTimeAtCpuSpeeds(); 14811 for (int i = 0; i < size; i++) { 14812 int u = mUidStats.keyAt(i); 14813 Uid uid = mUidStats.get(u); 14814 double proportionalSystemServiceUsage = uid.getProportionalSystemServiceUsage(); 14815 long timeUs = 0; 14816 for (int j = systemServiceTimeAtCpuSpeeds.length - 1; j >= 0; j--) { 14817 timeUs += systemServiceTimeAtCpuSpeeds[j] * proportionalSystemServiceUsage; 14818 } 14819 14820 pw.print(" "); 14821 pw.print(u); 14822 pw.print(": "); 14823 pw.println(timeUs / 1000); 14824 } 14825 } 14826 } 14827 14828 /** 14829 * Dump measured charge stats 14830 */ 14831 @GuardedBy("this") dumpMeasuredEnergyStatsLocked(PrintWriter pw)14832 public void dumpMeasuredEnergyStatsLocked(PrintWriter pw) { 14833 pw.printf("On battery measured charge stats (microcoulombs) \n"); 14834 if (mGlobalMeasuredEnergyStats == null) { 14835 pw.printf(" Not supported on this device.\n"); 14836 return; 14837 } 14838 14839 dumpMeasuredEnergyStatsLocked(pw, "global usage", mGlobalMeasuredEnergyStats); 14840 14841 int size = mUidStats.size(); 14842 for (int i = 0; i < size; i++) { 14843 final int u = mUidStats.keyAt(i); 14844 final Uid uid = mUidStats.get(u); 14845 final String name = "uid " + uid.mUid; 14846 dumpMeasuredEnergyStatsLocked(pw, name, uid.mUidMeasuredEnergyStats); 14847 } 14848 } 14849 14850 /** Dump measured charge stats for the given uid */ 14851 @GuardedBy("this") dumpMeasuredEnergyStatsLocked(PrintWriter pw, String name, MeasuredEnergyStats stats)14852 private void dumpMeasuredEnergyStatsLocked(PrintWriter pw, String name, 14853 MeasuredEnergyStats stats) { 14854 if (stats == null) return; 14855 final IndentingPrintWriter iPw = new IndentingPrintWriter(pw, " "); 14856 iPw.increaseIndent(); 14857 iPw.printf("%s:\n", name); 14858 iPw.increaseIndent(); 14859 stats.dump(iPw); 14860 iPw.decreaseIndent(); 14861 } 14862 14863 final ReentrantLock mWriteLock = new ReentrantLock(); 14864 writeAsyncLocked()14865 public void writeAsyncLocked() { 14866 writeStatsLocked(false); 14867 writeHistoryLocked(false); 14868 } 14869 writeSyncLocked()14870 public void writeSyncLocked() { 14871 writeStatsLocked(true); 14872 writeHistoryLocked(true); 14873 } 14874 writeStatsLocked(boolean sync)14875 void writeStatsLocked(boolean sync) { 14876 if (mStatsFile == null) { 14877 Slog.w(TAG, 14878 "writeStatsLocked: no file associated with this instance"); 14879 return; 14880 } 14881 14882 if (mShuttingDown) { 14883 return; 14884 } 14885 14886 final Parcel p = Parcel.obtain(); 14887 final long start = SystemClock.uptimeMillis(); 14888 writeSummaryToParcel(p, false/*history is in separate file*/); 14889 if (DEBUG) { 14890 Slog.d(TAG, "writeSummaryToParcel duration ms:" 14891 + (SystemClock.uptimeMillis() - start) + " bytes:" + p.dataSize()); 14892 } 14893 mLastWriteTimeMs = mClocks.elapsedRealtime(); 14894 writeParcelToFileLocked(p, mStatsFile, sync); 14895 } 14896 writeHistoryLocked(boolean sync)14897 void writeHistoryLocked(boolean sync) { 14898 if (mBatteryStatsHistory.getActiveFile() == null) { 14899 Slog.w(TAG, 14900 "writeHistoryLocked: no history file associated with this instance"); 14901 return; 14902 } 14903 14904 if (mShuttingDown) { 14905 return; 14906 } 14907 14908 Parcel p = Parcel.obtain(); 14909 final long start = SystemClock.uptimeMillis(); 14910 writeHistoryBuffer(p, true); 14911 if (DEBUG) { 14912 Slog.d(TAG, "writeHistoryBuffer duration ms:" 14913 + (SystemClock.uptimeMillis() - start) + " bytes:" + p.dataSize()); 14914 } 14915 writeParcelToFileLocked(p, mBatteryStatsHistory.getActiveFile(), sync); 14916 } 14917 writeParcelToFileLocked(Parcel p, AtomicFile file, boolean sync)14918 void writeParcelToFileLocked(Parcel p, AtomicFile file, boolean sync) { 14919 if (sync) { 14920 commitPendingDataToDisk(p, file); 14921 } else { 14922 BackgroundThread.getHandler().post(new Runnable() { 14923 @Override public void run() { 14924 commitPendingDataToDisk(p, file); 14925 } 14926 }); 14927 } 14928 } 14929 commitPendingDataToDisk(Parcel p, AtomicFile file)14930 private void commitPendingDataToDisk(Parcel p, AtomicFile file) { 14931 mWriteLock.lock(); 14932 FileOutputStream fos = null; 14933 try { 14934 final long startTimeMs = SystemClock.uptimeMillis(); 14935 fos = file.startWrite(); 14936 fos.write(p.marshall()); 14937 fos.flush(); 14938 file.finishWrite(fos); 14939 if (DEBUG) { 14940 Slog.d(TAG, "commitPendingDataToDisk file:" + file.getBaseFile().getPath() 14941 + " duration ms:" + (SystemClock.uptimeMillis() - startTimeMs) 14942 + " bytes:" + p.dataSize()); 14943 } 14944 com.android.internal.logging.EventLogTags.writeCommitSysConfigFile( 14945 "batterystats", SystemClock.uptimeMillis() - startTimeMs); 14946 } catch (IOException e) { 14947 Slog.w(TAG, "Error writing battery statistics", e); 14948 file.failWrite(fos); 14949 } finally { 14950 p.recycle(); 14951 mWriteLock.unlock(); 14952 } 14953 } 14954 14955 @UnsupportedAppUsage readLocked()14956 public void readLocked() { 14957 if (mDailyFile != null) { 14958 readDailyStatsLocked(); 14959 } 14960 14961 if (mStatsFile == null) { 14962 Slog.w(TAG, "readLocked: no file associated with this instance"); 14963 return; 14964 } 14965 14966 final AtomicFile activeHistoryFile = mBatteryStatsHistory.getActiveFile(); 14967 if (activeHistoryFile == null) { 14968 Slog.w(TAG, 14969 "readLocked: no history file associated with this instance"); 14970 return; 14971 } 14972 14973 mUidStats.clear(); 14974 14975 Parcel stats = Parcel.obtain(); 14976 try { 14977 final long start = SystemClock.uptimeMillis(); 14978 if (mStatsFile.exists()) { 14979 byte[] raw = mStatsFile.readFully(); 14980 stats.unmarshall(raw, 0, raw.length); 14981 stats.setDataPosition(0); 14982 readSummaryFromParcel(stats); 14983 if (DEBUG) { 14984 Slog.d(TAG, "readLocked stats file:" + mStatsFile.getBaseFile().getPath() 14985 + " bytes:" + raw.length + " takes ms:" + (SystemClock.uptimeMillis() 14986 - start)); 14987 } 14988 } 14989 } catch (Exception e) { 14990 Slog.e(TAG, "Error reading battery statistics", e); 14991 resetAllStatsLocked(SystemClock.uptimeMillis(), SystemClock.elapsedRealtime(), 14992 RESET_REASON_CORRUPT_FILE); 14993 } finally { 14994 stats.recycle(); 14995 } 14996 14997 Parcel history = Parcel.obtain(); 14998 try { 14999 final long start = SystemClock.uptimeMillis(); 15000 if (activeHistoryFile.exists()) { 15001 byte[] raw = activeHistoryFile.readFully(); 15002 if (raw.length > 0) { 15003 history.unmarshall(raw, 0, raw.length); 15004 history.setDataPosition(0); 15005 readHistoryBuffer(history); 15006 } 15007 if (DEBUG) { 15008 Slog.d(TAG, "readLocked history file::" 15009 + activeHistoryFile.getBaseFile().getPath() 15010 + " bytes:" + raw.length + " takes ms:" + (SystemClock.uptimeMillis() 15011 - start)); 15012 } 15013 } 15014 } catch (Exception e) { 15015 Slog.e(TAG, "Error reading battery history", e); 15016 clearHistoryLocked(); 15017 mBatteryStatsHistory.resetAllFiles(); 15018 } finally { 15019 history.recycle(); 15020 } 15021 15022 mEndPlatformVersion = Build.ID; 15023 15024 if (mHistoryBuffer.dataPosition() > 0 15025 || mBatteryStatsHistory.getFilesNumbers().size() > 1) { 15026 mRecordingHistory = true; 15027 final long elapsedRealtimeMs = mClocks.elapsedRealtime(); 15028 final long uptimeMs = mClocks.uptimeMillis(); 15029 addHistoryBufferLocked(elapsedRealtimeMs, HistoryItem.CMD_START, mHistoryCur); 15030 startRecordingHistory(elapsedRealtimeMs, uptimeMs, false); 15031 } 15032 15033 recordDailyStatsIfNeededLocked(false, mClocks.currentTimeMillis()); 15034 } 15035 describeContents()15036 public int describeContents() { 15037 return 0; 15038 } 15039 readHistoryBuffer(Parcel in)15040 void readHistoryBuffer(Parcel in) throws ParcelFormatException { 15041 final int version = in.readInt(); 15042 if (version != VERSION) { 15043 Slog.w("BatteryStats", "readHistoryBuffer: version got " + version 15044 + ", expected " + VERSION + "; erasing old stats"); 15045 return; 15046 } 15047 15048 final long historyBaseTime = in.readLong(); 15049 15050 mHistoryBuffer.setDataSize(0); 15051 mHistoryBuffer.setDataPosition(0); 15052 15053 int bufSize = in.readInt(); 15054 int curPos = in.dataPosition(); 15055 if (bufSize >= (mConstants.MAX_HISTORY_BUFFER*100)) { 15056 throw new ParcelFormatException("File corrupt: history data buffer too large " + 15057 bufSize); 15058 } else if ((bufSize&~3) != bufSize) { 15059 throw new ParcelFormatException("File corrupt: history data buffer not aligned " + 15060 bufSize); 15061 } else { 15062 if (DEBUG_HISTORY) Slog.i(TAG, "***************** READING NEW HISTORY: " + bufSize 15063 + " bytes at " + curPos); 15064 mHistoryBuffer.appendFrom(in, curPos, bufSize); 15065 in.setDataPosition(curPos + bufSize); 15066 } 15067 15068 if (DEBUG_HISTORY) { 15069 StringBuilder sb = new StringBuilder(128); 15070 sb.append("****************** OLD mHistoryBaseTimeMs: "); 15071 TimeUtils.formatDuration(mHistoryBaseTimeMs, sb); 15072 Slog.i(TAG, sb.toString()); 15073 } 15074 mHistoryBaseTimeMs = historyBaseTime; 15075 if (DEBUG_HISTORY) { 15076 StringBuilder sb = new StringBuilder(128); 15077 sb.append("****************** NEW mHistoryBaseTimeMs: "); 15078 TimeUtils.formatDuration(mHistoryBaseTimeMs, sb); 15079 Slog.i(TAG, sb.toString()); 15080 } 15081 15082 // We are just arbitrarily going to insert 1 minute from the sample of 15083 // the last run until samples in this run. 15084 if (mHistoryBaseTimeMs > 0) { 15085 long oldnow = mClocks.elapsedRealtime(); 15086 mHistoryBaseTimeMs = mHistoryBaseTimeMs - oldnow + 1; 15087 if (DEBUG_HISTORY) { 15088 StringBuilder sb = new StringBuilder(128); 15089 sb.append("****************** ADJUSTED mHistoryBaseTimeMs: "); 15090 TimeUtils.formatDuration(mHistoryBaseTimeMs, sb); 15091 Slog.i(TAG, sb.toString()); 15092 } 15093 } 15094 } 15095 writeHistoryBuffer(Parcel out, boolean inclData)15096 void writeHistoryBuffer(Parcel out, boolean inclData) { 15097 if (DEBUG_HISTORY) { 15098 StringBuilder sb = new StringBuilder(128); 15099 sb.append("****************** WRITING mHistoryBaseTimeMs: "); 15100 TimeUtils.formatDuration(mHistoryBaseTimeMs, sb); 15101 sb.append(" mLastHistoryElapsedRealtimeMs: "); 15102 TimeUtils.formatDuration(mLastHistoryElapsedRealtimeMs, sb); 15103 Slog.i(TAG, sb.toString()); 15104 } 15105 out.writeInt(VERSION); 15106 out.writeLong(mHistoryBaseTimeMs + mLastHistoryElapsedRealtimeMs); 15107 if (!inclData) { 15108 out.writeInt(0); 15109 out.writeInt(0); 15110 return; 15111 } 15112 15113 out.writeInt(mHistoryBuffer.dataSize()); 15114 if (DEBUG_HISTORY) Slog.i(TAG, "***************** WRITING HISTORY: " 15115 + mHistoryBuffer.dataSize() + " bytes at " + out.dataPosition()); 15116 out.appendFrom(mHistoryBuffer, 0, mHistoryBuffer.dataSize()); 15117 } 15118 readSummaryFromParcel(Parcel in)15119 public void readSummaryFromParcel(Parcel in) throws ParcelFormatException { 15120 final int version = in.readInt(); 15121 if (version != VERSION) { 15122 Slog.w("BatteryStats", "readFromParcel: version got " + version 15123 + ", expected " + VERSION + "; erasing old stats"); 15124 return; 15125 } 15126 15127 boolean inclHistory = in.readBoolean(); 15128 if (inclHistory) { 15129 readHistoryBuffer(in); 15130 mBatteryStatsHistory.readFromParcel(in); 15131 } 15132 15133 mHistoryTagPool.clear(); 15134 mNextHistoryTagIdx = 0; 15135 mNumHistoryTagChars = 0; 15136 15137 int numTags = in.readInt(); 15138 for (int i=0; i<numTags; i++) { 15139 int idx = in.readInt(); 15140 String str = in.readString(); 15141 if (str == null) { 15142 throw new ParcelFormatException("null history tag string"); 15143 } 15144 int uid = in.readInt(); 15145 HistoryTag tag = new HistoryTag(); 15146 tag.string = str; 15147 tag.uid = uid; 15148 tag.poolIdx = idx; 15149 mHistoryTagPool.put(tag, idx); 15150 if (idx >= mNextHistoryTagIdx) { 15151 mNextHistoryTagIdx = idx+1; 15152 } 15153 mNumHistoryTagChars += tag.string.length() + 1; 15154 } 15155 15156 mStartCount = in.readInt(); 15157 mUptimeUs = in.readLong(); 15158 mRealtimeUs = in.readLong(); 15159 mStartClockTimeMs = in.readLong(); 15160 mStartPlatformVersion = in.readString(); 15161 mEndPlatformVersion = in.readString(); 15162 mOnBatteryTimeBase.readSummaryFromParcel(in); 15163 mOnBatteryScreenOffTimeBase.readSummaryFromParcel(in); 15164 mDischargeUnplugLevel = in.readInt(); 15165 mDischargePlugLevel = in.readInt(); 15166 mDischargeCurrentLevel = in.readInt(); 15167 mCurrentBatteryLevel = in.readInt(); 15168 mEstimatedBatteryCapacityMah = in.readInt(); 15169 mLastLearnedBatteryCapacityUah = in.readInt(); 15170 mMinLearnedBatteryCapacityUah = in.readInt(); 15171 mMaxLearnedBatteryCapacityUah = in.readInt(); 15172 mLowDischargeAmountSinceCharge = in.readInt(); 15173 mHighDischargeAmountSinceCharge = in.readInt(); 15174 mDischargeAmountScreenOnSinceCharge = in.readInt(); 15175 mDischargeAmountScreenOffSinceCharge = in.readInt(); 15176 mDischargeAmountScreenDozeSinceCharge = in.readInt(); 15177 mDischargeStepTracker.readFromParcel(in); 15178 mChargeStepTracker.readFromParcel(in); 15179 mDailyDischargeStepTracker.readFromParcel(in); 15180 mDailyChargeStepTracker.readFromParcel(in); 15181 mDischargeCounter.readSummaryFromParcelLocked(in); 15182 mDischargeScreenOffCounter.readSummaryFromParcelLocked(in); 15183 mDischargeScreenDozeCounter.readSummaryFromParcelLocked(in); 15184 mDischargeLightDozeCounter.readSummaryFromParcelLocked(in); 15185 mDischargeDeepDozeCounter.readSummaryFromParcelLocked(in); 15186 int NPKG = in.readInt(); 15187 if (NPKG > 0) { 15188 mDailyPackageChanges = new ArrayList<>(NPKG); 15189 while (NPKG > 0) { 15190 NPKG--; 15191 PackageChange pc = new PackageChange(); 15192 pc.mPackageName = in.readString(); 15193 pc.mUpdate = in.readInt() != 0; 15194 pc.mVersionCode = in.readLong(); 15195 mDailyPackageChanges.add(pc); 15196 } 15197 } else { 15198 mDailyPackageChanges = null; 15199 } 15200 mDailyStartTimeMs = in.readLong(); 15201 mNextMinDailyDeadlineMs = in.readLong(); 15202 mNextMaxDailyDeadlineMs = in.readLong(); 15203 mBatteryTimeToFullSeconds = in.readLong(); 15204 15205 /** 15206 * WARNING: Supported buckets may have changed across boots. Bucket mismatch is handled 15207 * later when {@link #initMeasuredEnergyStatsLocked} is called. 15208 */ 15209 mGlobalMeasuredEnergyStats = MeasuredEnergyStats.createAndReadSummaryFromParcel(in); 15210 15211 mStartCount++; 15212 15213 mScreenState = Display.STATE_UNKNOWN; 15214 mScreenOnTimer.readSummaryFromParcelLocked(in); 15215 mScreenDozeTimer.readSummaryFromParcelLocked(in); 15216 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 15217 mScreenBrightnessTimer[i].readSummaryFromParcelLocked(in); 15218 } 15219 mInteractive = false; 15220 mInteractiveTimer.readSummaryFromParcelLocked(in); 15221 mPhoneOn = false; 15222 mPowerSaveModeEnabledTimer.readSummaryFromParcelLocked(in); 15223 mLongestLightIdleTimeMs = in.readLong(); 15224 mLongestFullIdleTimeMs = in.readLong(); 15225 mDeviceIdleModeLightTimer.readSummaryFromParcelLocked(in); 15226 mDeviceIdleModeFullTimer.readSummaryFromParcelLocked(in); 15227 mDeviceLightIdlingTimer.readSummaryFromParcelLocked(in); 15228 mDeviceIdlingTimer.readSummaryFromParcelLocked(in); 15229 mPhoneOnTimer.readSummaryFromParcelLocked(in); 15230 for (int i = 0; i < CellSignalStrength.getNumSignalStrengthLevels(); i++) { 15231 mPhoneSignalStrengthsTimer[i].readSummaryFromParcelLocked(in); 15232 } 15233 mPhoneSignalScanningTimer.readSummaryFromParcelLocked(in); 15234 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 15235 mPhoneDataConnectionsTimer[i].readSummaryFromParcelLocked(in); 15236 } 15237 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 15238 mNetworkByteActivityCounters[i].readSummaryFromParcelLocked(in); 15239 mNetworkPacketActivityCounters[i].readSummaryFromParcelLocked(in); 15240 } 15241 mMobileRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW; 15242 mMobileRadioActiveTimer.readSummaryFromParcelLocked(in); 15243 mMobileRadioActivePerAppTimer.readSummaryFromParcelLocked(in); 15244 mMobileRadioActiveAdjustedTime.readSummaryFromParcelLocked(in); 15245 mMobileRadioActiveUnknownTime.readSummaryFromParcelLocked(in); 15246 mMobileRadioActiveUnknownCount.readSummaryFromParcelLocked(in); 15247 mWifiMulticastWakelockTimer.readSummaryFromParcelLocked(in); 15248 mWifiRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW; 15249 mWifiOn = false; 15250 mWifiOnTimer.readSummaryFromParcelLocked(in); 15251 mGlobalWifiRunning = false; 15252 mGlobalWifiRunningTimer.readSummaryFromParcelLocked(in); 15253 for (int i=0; i<NUM_WIFI_STATES; i++) { 15254 mWifiStateTimer[i].readSummaryFromParcelLocked(in); 15255 } 15256 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) { 15257 mWifiSupplStateTimer[i].readSummaryFromParcelLocked(in); 15258 } 15259 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { 15260 mWifiSignalStrengthsTimer[i].readSummaryFromParcelLocked(in); 15261 } 15262 mWifiActiveTimer.readSummaryFromParcelLocked(in); 15263 mWifiActivity.readSummaryFromParcel(in); 15264 for (int i=0; i<mGpsSignalQualityTimer.length; i++) { 15265 mGpsSignalQualityTimer[i].readSummaryFromParcelLocked(in); 15266 } 15267 mBluetoothActivity.readSummaryFromParcel(in); 15268 mModemActivity.readSummaryFromParcel(in); 15269 mHasWifiReporting = in.readInt() != 0; 15270 mHasBluetoothReporting = in.readInt() != 0; 15271 mHasModemReporting = in.readInt() != 0; 15272 15273 mNumConnectivityChange = in.readInt(); 15274 mFlashlightOnNesting = 0; 15275 mFlashlightOnTimer.readSummaryFromParcelLocked(in); 15276 mCameraOnNesting = 0; 15277 mCameraOnTimer.readSummaryFromParcelLocked(in); 15278 mBluetoothScanNesting = 0; 15279 mBluetoothScanTimer.readSummaryFromParcelLocked(in); 15280 15281 int NRPMS = in.readInt(); 15282 if (NRPMS > 10000) { 15283 throw new ParcelFormatException("File corrupt: too many rpm stats " + NRPMS); 15284 } 15285 for (int irpm = 0; irpm < NRPMS; irpm++) { 15286 if (in.readInt() != 0) { 15287 String rpmName = in.readString(); 15288 getRpmTimerLocked(rpmName).readSummaryFromParcelLocked(in); 15289 } 15290 } 15291 int NSORPMS = in.readInt(); 15292 if (NSORPMS > 10000) { 15293 throw new ParcelFormatException("File corrupt: too many screen-off rpm stats " + NSORPMS); 15294 } 15295 for (int irpm = 0; irpm < NSORPMS; irpm++) { 15296 if (in.readInt() != 0) { 15297 String rpmName = in.readString(); 15298 getScreenOffRpmTimerLocked(rpmName).readSummaryFromParcelLocked(in); 15299 } 15300 } 15301 15302 int NKW = in.readInt(); 15303 if (NKW > 10000) { 15304 throw new ParcelFormatException("File corrupt: too many kernel wake locks " + NKW); 15305 } 15306 for (int ikw = 0; ikw < NKW; ikw++) { 15307 if (in.readInt() != 0) { 15308 String kwltName = in.readString(); 15309 getKernelWakelockTimerLocked(kwltName).readSummaryFromParcelLocked(in); 15310 } 15311 } 15312 15313 int NWR = in.readInt(); 15314 if (NWR > 10000) { 15315 throw new ParcelFormatException("File corrupt: too many wakeup reasons " + NWR); 15316 } 15317 for (int iwr = 0; iwr < NWR; iwr++) { 15318 if (in.readInt() != 0) { 15319 String reasonName = in.readString(); 15320 getWakeupReasonTimerLocked(reasonName).readSummaryFromParcelLocked(in); 15321 } 15322 } 15323 15324 int NMS = in.readInt(); 15325 for (int ims = 0; ims < NMS; ims++) { 15326 if (in.readInt() != 0) { 15327 long kmstName = in.readLong(); 15328 getKernelMemoryTimerLocked(kmstName).readSummaryFromParcelLocked(in); 15329 } 15330 } 15331 15332 final int NU = in.readInt(); 15333 if (NU > 10000) { 15334 throw new ParcelFormatException("File corrupt: too many uids " + NU); 15335 } 15336 final long elapsedRealtimeMs = mClocks.elapsedRealtime(); 15337 final long uptimeMs = mClocks.uptimeMillis(); 15338 for (int iu = 0; iu < NU; iu++) { 15339 int uid = in.readInt(); 15340 Uid u = new Uid(this, uid, elapsedRealtimeMs, uptimeMs); 15341 mUidStats.put(uid, u); 15342 15343 u.mOnBatteryBackgroundTimeBase.readSummaryFromParcel(in); 15344 u.mOnBatteryScreenOffBackgroundTimeBase.readSummaryFromParcel(in); 15345 15346 u.mWifiRunning = false; 15347 if (in.readInt() != 0) { 15348 u.mWifiRunningTimer.readSummaryFromParcelLocked(in); 15349 } 15350 u.mFullWifiLockOut = false; 15351 if (in.readInt() != 0) { 15352 u.mFullWifiLockTimer.readSummaryFromParcelLocked(in); 15353 } 15354 u.mWifiScanStarted = false; 15355 if (in.readInt() != 0) { 15356 u.mWifiScanTimer.readSummaryFromParcelLocked(in); 15357 } 15358 u.mWifiBatchedScanBinStarted = Uid.NO_BATCHED_SCAN_STARTED; 15359 for (int i = 0; i < Uid.NUM_WIFI_BATCHED_SCAN_BINS; i++) { 15360 if (in.readInt() != 0) { 15361 u.makeWifiBatchedScanBin(i, null); 15362 u.mWifiBatchedScanTimer[i].readSummaryFromParcelLocked(in); 15363 } 15364 } 15365 u.mWifiMulticastWakelockCount = 0; 15366 if (in.readInt() != 0) { 15367 u.mWifiMulticastTimer.readSummaryFromParcelLocked(in); 15368 } 15369 if (in.readInt() != 0) { 15370 u.createAudioTurnedOnTimerLocked().readSummaryFromParcelLocked(in); 15371 } 15372 if (in.readInt() != 0) { 15373 u.createVideoTurnedOnTimerLocked().readSummaryFromParcelLocked(in); 15374 } 15375 if (in.readInt() != 0) { 15376 u.createFlashlightTurnedOnTimerLocked().readSummaryFromParcelLocked(in); 15377 } 15378 if (in.readInt() != 0) { 15379 u.createCameraTurnedOnTimerLocked().readSummaryFromParcelLocked(in); 15380 } 15381 if (in.readInt() != 0) { 15382 u.createForegroundActivityTimerLocked().readSummaryFromParcelLocked(in); 15383 } 15384 if (in.readInt() != 0) { 15385 u.createForegroundServiceTimerLocked().readSummaryFromParcelLocked(in); 15386 } 15387 if (in.readInt() != 0) { 15388 u.createAggregatedPartialWakelockTimerLocked().readSummaryFromParcelLocked(in); 15389 } 15390 if (in.readInt() != 0) { 15391 u.createBluetoothScanTimerLocked().readSummaryFromParcelLocked(in); 15392 } 15393 if (in.readInt() != 0) { 15394 u.createBluetoothUnoptimizedScanTimerLocked().readSummaryFromParcelLocked(in); 15395 } 15396 if (in.readInt() != 0) { 15397 u.createBluetoothScanResultCounterLocked().readSummaryFromParcelLocked(in); 15398 } 15399 if (in.readInt() != 0) { 15400 u.createBluetoothScanResultBgCounterLocked().readSummaryFromParcelLocked(in); 15401 } 15402 u.mProcessState = ActivityManager.PROCESS_STATE_NONEXISTENT; 15403 for (int i = 0; i < Uid.NUM_PROCESS_STATE; i++) { 15404 if (in.readInt() != 0) { 15405 u.makeProcessState(i, null); 15406 u.mProcessStateTimer[i].readSummaryFromParcelLocked(in); 15407 } 15408 } 15409 if (in.readInt() != 0) { 15410 u.createVibratorOnTimerLocked().readSummaryFromParcelLocked(in); 15411 } 15412 15413 if (in.readInt() != 0) { 15414 if (u.mUserActivityCounters == null) { 15415 u.initUserActivityLocked(); 15416 } 15417 for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) { 15418 u.mUserActivityCounters[i].readSummaryFromParcelLocked(in); 15419 } 15420 } 15421 15422 if (in.readInt() != 0) { 15423 if (u.mNetworkByteActivityCounters == null) { 15424 u.initNetworkActivityLocked(); 15425 } 15426 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 15427 u.mNetworkByteActivityCounters[i].readSummaryFromParcelLocked(in); 15428 u.mNetworkPacketActivityCounters[i].readSummaryFromParcelLocked(in); 15429 } 15430 u.mMobileRadioActiveTime.readSummaryFromParcelLocked(in); 15431 u.mMobileRadioActiveCount.readSummaryFromParcelLocked(in); 15432 } 15433 15434 u.mUserCpuTime.readSummaryFromParcelLocked(in); 15435 u.mSystemCpuTime.readSummaryFromParcelLocked(in); 15436 15437 if (in.readInt() != 0) { 15438 final int numClusters = in.readInt(); 15439 if (mPowerProfile != null && mPowerProfile.getNumCpuClusters() != numClusters) { 15440 throw new ParcelFormatException("Incompatible cpu cluster arrangement"); 15441 } 15442 detachIfNotNull(u.mCpuClusterSpeedTimesUs); 15443 u.mCpuClusterSpeedTimesUs = new LongSamplingCounter[numClusters][]; 15444 for (int cluster = 0; cluster < numClusters; cluster++) { 15445 if (in.readInt() != 0) { 15446 final int NSB = in.readInt(); 15447 if (mPowerProfile != null && 15448 mPowerProfile.getNumSpeedStepsInCpuCluster(cluster) != NSB) { 15449 throw new ParcelFormatException("File corrupt: too many speed bins " + 15450 NSB); 15451 } 15452 15453 u.mCpuClusterSpeedTimesUs[cluster] = new LongSamplingCounter[NSB]; 15454 for (int speed = 0; speed < NSB; speed++) { 15455 if (in.readInt() != 0) { 15456 u.mCpuClusterSpeedTimesUs[cluster][speed] = new LongSamplingCounter( 15457 mOnBatteryTimeBase); 15458 u.mCpuClusterSpeedTimesUs[cluster][speed].readSummaryFromParcelLocked(in); 15459 } 15460 } 15461 } else { 15462 u.mCpuClusterSpeedTimesUs[cluster] = null; 15463 } 15464 } 15465 } else { 15466 detachIfNotNull(u.mCpuClusterSpeedTimesUs); 15467 u.mCpuClusterSpeedTimesUs = null; 15468 } 15469 15470 detachIfNotNull(u.mCpuFreqTimeMs); 15471 u.mCpuFreqTimeMs = LongSamplingCounterArray.readSummaryFromParcelLocked( 15472 in, mOnBatteryTimeBase); 15473 detachIfNotNull(u.mScreenOffCpuFreqTimeMs); 15474 u.mScreenOffCpuFreqTimeMs = LongSamplingCounterArray.readSummaryFromParcelLocked( 15475 in, mOnBatteryScreenOffTimeBase); 15476 15477 u.mCpuActiveTimeMs.readSummaryFromParcelLocked(in); 15478 u.mCpuClusterTimesMs.readSummaryFromParcelLocked(in); 15479 15480 int length = in.readInt(); 15481 if (length == Uid.NUM_PROCESS_STATE) { 15482 detachIfNotNull(u.mProcStateTimeMs); 15483 u.mProcStateTimeMs = new LongSamplingCounterArray[length]; 15484 for (int procState = 0; procState < length; ++procState) { 15485 u.mProcStateTimeMs[procState] 15486 = LongSamplingCounterArray.readSummaryFromParcelLocked( 15487 in, mOnBatteryTimeBase); 15488 } 15489 } else { 15490 detachIfNotNull(u.mProcStateTimeMs); 15491 u.mProcStateTimeMs = null; 15492 } 15493 length = in.readInt(); 15494 if (length == Uid.NUM_PROCESS_STATE) { 15495 detachIfNotNull(u.mProcStateScreenOffTimeMs); 15496 u.mProcStateScreenOffTimeMs = new LongSamplingCounterArray[length]; 15497 for (int procState = 0; procState < length; ++procState) { 15498 u.mProcStateScreenOffTimeMs[procState] 15499 = LongSamplingCounterArray.readSummaryFromParcelLocked( 15500 in, mOnBatteryScreenOffTimeBase); 15501 } 15502 } else { 15503 detachIfNotNull(u.mProcStateScreenOffTimeMs); 15504 u.mProcStateScreenOffTimeMs = null; 15505 } 15506 15507 if (in.readInt() != 0) { 15508 detachIfNotNull(u.mMobileRadioApWakeupCount); 15509 u.mMobileRadioApWakeupCount = new LongSamplingCounter(mOnBatteryTimeBase); 15510 u.mMobileRadioApWakeupCount.readSummaryFromParcelLocked(in); 15511 } else { 15512 detachIfNotNull(u.mMobileRadioApWakeupCount); 15513 u.mMobileRadioApWakeupCount = null; 15514 } 15515 15516 if (in.readInt() != 0) { 15517 detachIfNotNull(u.mWifiRadioApWakeupCount); 15518 u.mWifiRadioApWakeupCount = new LongSamplingCounter(mOnBatteryTimeBase); 15519 u.mWifiRadioApWakeupCount.readSummaryFromParcelLocked(in); 15520 } else { 15521 detachIfNotNull(u.mWifiRadioApWakeupCount); 15522 u.mWifiRadioApWakeupCount = null; 15523 } 15524 15525 u.mUidMeasuredEnergyStats = MeasuredEnergyStats.createAndReadSummaryFromParcel(in, 15526 /* template */ mGlobalMeasuredEnergyStats); 15527 15528 int NW = in.readInt(); 15529 if (NW > (MAX_WAKELOCKS_PER_UID+1)) { 15530 throw new ParcelFormatException("File corrupt: too many wake locks " + NW); 15531 } 15532 for (int iw = 0; iw < NW; iw++) { 15533 String wlName = in.readString(); 15534 u.readWakeSummaryFromParcelLocked(wlName, in); 15535 } 15536 15537 int NS = in.readInt(); 15538 if (NS > (MAX_WAKELOCKS_PER_UID+1)) { 15539 throw new ParcelFormatException("File corrupt: too many syncs " + NS); 15540 } 15541 for (int is = 0; is < NS; is++) { 15542 String name = in.readString(); 15543 u.readSyncSummaryFromParcelLocked(name, in); 15544 } 15545 15546 int NJ = in.readInt(); 15547 if (NJ > (MAX_WAKELOCKS_PER_UID+1)) { 15548 throw new ParcelFormatException("File corrupt: too many job timers " + NJ); 15549 } 15550 for (int ij = 0; ij < NJ; ij++) { 15551 String name = in.readString(); 15552 u.readJobSummaryFromParcelLocked(name, in); 15553 } 15554 15555 u.readJobCompletionsFromParcelLocked(in); 15556 15557 u.mJobsDeferredEventCount.readSummaryFromParcelLocked(in); 15558 u.mJobsDeferredCount.readSummaryFromParcelLocked(in); 15559 u.mJobsFreshnessTimeMs.readSummaryFromParcelLocked(in); 15560 detachIfNotNull(u.mJobsFreshnessBuckets); 15561 for (int i = 0; i < JOB_FRESHNESS_BUCKETS.length; i++) { 15562 if (in.readInt() != 0) { 15563 u.mJobsFreshnessBuckets[i] = new Counter(u.mBsi.mOnBatteryTimeBase); 15564 u.mJobsFreshnessBuckets[i].readSummaryFromParcelLocked(in); 15565 } 15566 } 15567 15568 int NP = in.readInt(); 15569 if (NP > 1000) { 15570 throw new ParcelFormatException("File corrupt: too many sensors " + NP); 15571 } 15572 for (int is = 0; is < NP; is++) { 15573 int seNumber = in.readInt(); 15574 if (in.readInt() != 0) { 15575 u.getSensorTimerLocked(seNumber, true).readSummaryFromParcelLocked(in); 15576 } 15577 } 15578 15579 NP = in.readInt(); 15580 if (NP > 1000) { 15581 throw new ParcelFormatException("File corrupt: too many processes " + NP); 15582 } 15583 for (int ip = 0; ip < NP; ip++) { 15584 String procName = in.readString(); 15585 Uid.Proc p = u.getProcessStatsLocked(procName); 15586 p.mUserTimeMs = in.readLong(); 15587 p.mSystemTimeMs = in.readLong(); 15588 p.mForegroundTimeMs = in.readLong(); 15589 p.mStarts = in.readInt(); 15590 p.mNumCrashes = in.readInt(); 15591 p.mNumAnrs = in.readInt(); 15592 p.readExcessivePowerFromParcelLocked(in); 15593 } 15594 15595 NP = in.readInt(); 15596 if (NP > 10000) { 15597 throw new ParcelFormatException("File corrupt: too many packages " + NP); 15598 } 15599 for (int ip = 0; ip < NP; ip++) { 15600 String pkgName = in.readString(); 15601 detachIfNotNull(u.mPackageStats.get(pkgName)); 15602 Uid.Pkg p = u.getPackageStatsLocked(pkgName); 15603 final int NWA = in.readInt(); 15604 if (NWA > 10000) { 15605 throw new ParcelFormatException("File corrupt: too many wakeup alarms " + NWA); 15606 } 15607 p.mWakeupAlarms.clear(); 15608 for (int iwa = 0; iwa < NWA; iwa++) { 15609 String tag = in.readString(); 15610 Counter c = new Counter(mOnBatteryScreenOffTimeBase); 15611 c.readSummaryFromParcelLocked(in); 15612 p.mWakeupAlarms.put(tag, c); 15613 } 15614 NS = in.readInt(); 15615 if (NS > 10000) { 15616 throw new ParcelFormatException("File corrupt: too many services " + NS); 15617 } 15618 for (int is = 0; is < NS; is++) { 15619 String servName = in.readString(); 15620 Uid.Pkg.Serv s = u.getServiceStatsLocked(pkgName, servName); 15621 s.mStartTimeMs = in.readLong(); 15622 s.mStarts = in.readInt(); 15623 s.mLaunches = in.readInt(); 15624 } 15625 } 15626 } 15627 15628 mBinderThreadCpuTimesUs = 15629 LongSamplingCounterArray.readSummaryFromParcelLocked(in, mOnBatteryTimeBase); 15630 } 15631 15632 /** 15633 * Writes a summary of the statistics to a Parcel, in a format suitable to be written to 15634 * disk. This format does not allow a lossless round-trip. 15635 * 15636 * @param out the Parcel to be written to. 15637 */ writeSummaryToParcel(Parcel out, boolean inclHistory)15638 public void writeSummaryToParcel(Parcel out, boolean inclHistory) { 15639 pullPendingStateUpdatesLocked(); 15640 15641 // Pull the clock time. This may update the time and make a new history entry 15642 // if we had originally pulled a time before the RTC was set. 15643 getStartClockTime(); 15644 15645 final long NOW_SYS = mClocks.uptimeMillis() * 1000; 15646 final long NOWREAL_SYS = mClocks.elapsedRealtime() * 1000; 15647 15648 out.writeInt(VERSION); 15649 15650 out.writeBoolean(inclHistory); 15651 if (inclHistory) { 15652 writeHistoryBuffer(out, true); 15653 mBatteryStatsHistory.writeToParcel(out); 15654 } 15655 15656 out.writeInt(mHistoryTagPool.size()); 15657 for (HashMap.Entry<HistoryTag, Integer> ent : mHistoryTagPool.entrySet()) { 15658 HistoryTag tag = ent.getKey(); 15659 out.writeInt(ent.getValue()); 15660 out.writeString(tag.string); 15661 out.writeInt(tag.uid); 15662 } 15663 15664 out.writeInt(mStartCount); 15665 out.writeLong(computeUptime(NOW_SYS, STATS_SINCE_CHARGED)); 15666 out.writeLong(computeRealtime(NOWREAL_SYS, STATS_SINCE_CHARGED)); 15667 out.writeLong(mStartClockTimeMs); 15668 out.writeString(mStartPlatformVersion); 15669 out.writeString(mEndPlatformVersion); 15670 mOnBatteryTimeBase.writeSummaryToParcel(out, NOW_SYS, NOWREAL_SYS); 15671 mOnBatteryScreenOffTimeBase.writeSummaryToParcel(out, NOW_SYS, NOWREAL_SYS); 15672 out.writeInt(mDischargeUnplugLevel); 15673 out.writeInt(mDischargePlugLevel); 15674 out.writeInt(mDischargeCurrentLevel); 15675 out.writeInt(mCurrentBatteryLevel); 15676 out.writeInt(mEstimatedBatteryCapacityMah); 15677 out.writeInt(mLastLearnedBatteryCapacityUah); 15678 out.writeInt(mMinLearnedBatteryCapacityUah); 15679 out.writeInt(mMaxLearnedBatteryCapacityUah); 15680 out.writeInt(getLowDischargeAmountSinceCharge()); 15681 out.writeInt(getHighDischargeAmountSinceCharge()); 15682 out.writeInt(getDischargeAmountScreenOnSinceCharge()); 15683 out.writeInt(getDischargeAmountScreenOffSinceCharge()); 15684 out.writeInt(getDischargeAmountScreenDozeSinceCharge()); 15685 mDischargeStepTracker.writeToParcel(out); 15686 mChargeStepTracker.writeToParcel(out); 15687 mDailyDischargeStepTracker.writeToParcel(out); 15688 mDailyChargeStepTracker.writeToParcel(out); 15689 mDischargeCounter.writeSummaryFromParcelLocked(out); 15690 mDischargeScreenOffCounter.writeSummaryFromParcelLocked(out); 15691 mDischargeScreenDozeCounter.writeSummaryFromParcelLocked(out); 15692 mDischargeLightDozeCounter.writeSummaryFromParcelLocked(out); 15693 mDischargeDeepDozeCounter.writeSummaryFromParcelLocked(out); 15694 if (mDailyPackageChanges != null) { 15695 final int NPKG = mDailyPackageChanges.size(); 15696 out.writeInt(NPKG); 15697 for (int i=0; i<NPKG; i++) { 15698 PackageChange pc = mDailyPackageChanges.get(i); 15699 out.writeString(pc.mPackageName); 15700 out.writeInt(pc.mUpdate ? 1 : 0); 15701 out.writeLong(pc.mVersionCode); 15702 } 15703 } else { 15704 out.writeInt(0); 15705 } 15706 out.writeLong(mDailyStartTimeMs); 15707 out.writeLong(mNextMinDailyDeadlineMs); 15708 out.writeLong(mNextMaxDailyDeadlineMs); 15709 out.writeLong(mBatteryTimeToFullSeconds); 15710 15711 MeasuredEnergyStats.writeSummaryToParcel(mGlobalMeasuredEnergyStats, out, false, false); 15712 15713 mScreenOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 15714 mScreenDozeTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 15715 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 15716 mScreenBrightnessTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS); 15717 } 15718 mInteractiveTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 15719 mPowerSaveModeEnabledTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 15720 out.writeLong(mLongestLightIdleTimeMs); 15721 out.writeLong(mLongestFullIdleTimeMs); 15722 mDeviceIdleModeLightTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 15723 mDeviceIdleModeFullTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 15724 mDeviceLightIdlingTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 15725 mDeviceIdlingTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 15726 mPhoneOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 15727 for (int i = 0; i < CellSignalStrength.getNumSignalStrengthLevels(); i++) { 15728 mPhoneSignalStrengthsTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS); 15729 } 15730 mPhoneSignalScanningTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 15731 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 15732 mPhoneDataConnectionsTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS); 15733 } 15734 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 15735 mNetworkByteActivityCounters[i].writeSummaryFromParcelLocked(out); 15736 mNetworkPacketActivityCounters[i].writeSummaryFromParcelLocked(out); 15737 } 15738 mMobileRadioActiveTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 15739 mMobileRadioActivePerAppTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 15740 mMobileRadioActiveAdjustedTime.writeSummaryFromParcelLocked(out); 15741 mMobileRadioActiveUnknownTime.writeSummaryFromParcelLocked(out); 15742 mMobileRadioActiveUnknownCount.writeSummaryFromParcelLocked(out); 15743 mWifiMulticastWakelockTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 15744 mWifiOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 15745 mGlobalWifiRunningTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 15746 for (int i=0; i<NUM_WIFI_STATES; i++) { 15747 mWifiStateTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS); 15748 } 15749 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) { 15750 mWifiSupplStateTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS); 15751 } 15752 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { 15753 mWifiSignalStrengthsTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS); 15754 } 15755 mWifiActiveTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 15756 mWifiActivity.writeSummaryToParcel(out); 15757 for (int i=0; i< mGpsSignalQualityTimer.length; i++) { 15758 mGpsSignalQualityTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS); 15759 } 15760 mBluetoothActivity.writeSummaryToParcel(out); 15761 mModemActivity.writeSummaryToParcel(out); 15762 out.writeInt(mHasWifiReporting ? 1 : 0); 15763 out.writeInt(mHasBluetoothReporting ? 1 : 0); 15764 out.writeInt(mHasModemReporting ? 1 : 0); 15765 15766 out.writeInt(mNumConnectivityChange); 15767 mFlashlightOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 15768 mCameraOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 15769 mBluetoothScanTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 15770 15771 out.writeInt(mRpmStats.size()); 15772 for (Map.Entry<String, SamplingTimer> ent : mRpmStats.entrySet()) { 15773 Timer rpmt = ent.getValue(); 15774 if (rpmt != null) { 15775 out.writeInt(1); 15776 out.writeString(ent.getKey()); 15777 rpmt.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 15778 } else { 15779 out.writeInt(0); 15780 } 15781 } 15782 out.writeInt(mScreenOffRpmStats.size()); 15783 for (Map.Entry<String, SamplingTimer> ent : mScreenOffRpmStats.entrySet()) { 15784 Timer rpmt = ent.getValue(); 15785 if (rpmt != null) { 15786 out.writeInt(1); 15787 out.writeString(ent.getKey()); 15788 rpmt.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 15789 } else { 15790 out.writeInt(0); 15791 } 15792 } 15793 15794 out.writeInt(mKernelWakelockStats.size()); 15795 for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) { 15796 Timer kwlt = ent.getValue(); 15797 if (kwlt != null) { 15798 out.writeInt(1); 15799 out.writeString(ent.getKey()); 15800 kwlt.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 15801 } else { 15802 out.writeInt(0); 15803 } 15804 } 15805 15806 out.writeInt(mWakeupReasonStats.size()); 15807 for (Map.Entry<String, SamplingTimer> ent : mWakeupReasonStats.entrySet()) { 15808 SamplingTimer timer = ent.getValue(); 15809 if (timer != null) { 15810 out.writeInt(1); 15811 out.writeString(ent.getKey()); 15812 timer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 15813 } else { 15814 out.writeInt(0); 15815 } 15816 } 15817 15818 out.writeInt(mKernelMemoryStats.size()); 15819 for (int i = 0; i < mKernelMemoryStats.size(); i++) { 15820 Timer kmt = mKernelMemoryStats.valueAt(i); 15821 if (kmt != null) { 15822 out.writeInt(1); 15823 out.writeLong(mKernelMemoryStats.keyAt(i)); 15824 kmt.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 15825 } else { 15826 out.writeInt(0); 15827 } 15828 } 15829 15830 final int NU = mUidStats.size(); 15831 out.writeInt(NU); 15832 for (int iu = 0; iu < NU; iu++) { 15833 out.writeInt(mUidStats.keyAt(iu)); 15834 Uid u = mUidStats.valueAt(iu); 15835 15836 u.mOnBatteryBackgroundTimeBase.writeSummaryToParcel(out, NOW_SYS, NOWREAL_SYS); 15837 u.mOnBatteryScreenOffBackgroundTimeBase.writeSummaryToParcel(out, NOW_SYS, NOWREAL_SYS); 15838 15839 if (u.mWifiRunningTimer != null) { 15840 out.writeInt(1); 15841 u.mWifiRunningTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 15842 } else { 15843 out.writeInt(0); 15844 } 15845 if (u.mFullWifiLockTimer != null) { 15846 out.writeInt(1); 15847 u.mFullWifiLockTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 15848 } else { 15849 out.writeInt(0); 15850 } 15851 if (u.mWifiScanTimer != null) { 15852 out.writeInt(1); 15853 u.mWifiScanTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 15854 } else { 15855 out.writeInt(0); 15856 } 15857 for (int i = 0; i < Uid.NUM_WIFI_BATCHED_SCAN_BINS; i++) { 15858 if (u.mWifiBatchedScanTimer[i] != null) { 15859 out.writeInt(1); 15860 u.mWifiBatchedScanTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS); 15861 } else { 15862 out.writeInt(0); 15863 } 15864 } 15865 if (u.mWifiMulticastTimer != null) { 15866 out.writeInt(1); 15867 u.mWifiMulticastTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 15868 } else { 15869 out.writeInt(0); 15870 } 15871 if (u.mAudioTurnedOnTimer != null) { 15872 out.writeInt(1); 15873 u.mAudioTurnedOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 15874 } else { 15875 out.writeInt(0); 15876 } 15877 if (u.mVideoTurnedOnTimer != null) { 15878 out.writeInt(1); 15879 u.mVideoTurnedOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 15880 } else { 15881 out.writeInt(0); 15882 } 15883 if (u.mFlashlightTurnedOnTimer != null) { 15884 out.writeInt(1); 15885 u.mFlashlightTurnedOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 15886 } else { 15887 out.writeInt(0); 15888 } 15889 if (u.mCameraTurnedOnTimer != null) { 15890 out.writeInt(1); 15891 u.mCameraTurnedOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 15892 } else { 15893 out.writeInt(0); 15894 } 15895 if (u.mForegroundActivityTimer != null) { 15896 out.writeInt(1); 15897 u.mForegroundActivityTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 15898 } else { 15899 out.writeInt(0); 15900 } 15901 if (u.mForegroundServiceTimer != null) { 15902 out.writeInt(1); 15903 u.mForegroundServiceTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 15904 } else { 15905 out.writeInt(0); 15906 } 15907 if (u.mAggregatedPartialWakelockTimer != null) { 15908 out.writeInt(1); 15909 u.mAggregatedPartialWakelockTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 15910 } else { 15911 out.writeInt(0); 15912 } 15913 if (u.mBluetoothScanTimer != null) { 15914 out.writeInt(1); 15915 u.mBluetoothScanTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 15916 } else { 15917 out.writeInt(0); 15918 } 15919 if (u.mBluetoothUnoptimizedScanTimer != null) { 15920 out.writeInt(1); 15921 u.mBluetoothUnoptimizedScanTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 15922 } else { 15923 out.writeInt(0); 15924 } 15925 if (u.mBluetoothScanResultCounter != null) { 15926 out.writeInt(1); 15927 u.mBluetoothScanResultCounter.writeSummaryFromParcelLocked(out); 15928 } else { 15929 out.writeInt(0); 15930 } 15931 if (u.mBluetoothScanResultBgCounter != null) { 15932 out.writeInt(1); 15933 u.mBluetoothScanResultBgCounter.writeSummaryFromParcelLocked(out); 15934 } else { 15935 out.writeInt(0); 15936 } 15937 for (int i = 0; i < Uid.NUM_PROCESS_STATE; i++) { 15938 if (u.mProcessStateTimer[i] != null) { 15939 out.writeInt(1); 15940 u.mProcessStateTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS); 15941 } else { 15942 out.writeInt(0); 15943 } 15944 } 15945 if (u.mVibratorOnTimer != null) { 15946 out.writeInt(1); 15947 u.mVibratorOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 15948 } else { 15949 out.writeInt(0); 15950 } 15951 15952 if (u.mUserActivityCounters == null) { 15953 out.writeInt(0); 15954 } else { 15955 out.writeInt(1); 15956 for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) { 15957 u.mUserActivityCounters[i].writeSummaryFromParcelLocked(out); 15958 } 15959 } 15960 15961 if (u.mNetworkByteActivityCounters == null) { 15962 out.writeInt(0); 15963 } else { 15964 out.writeInt(1); 15965 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 15966 u.mNetworkByteActivityCounters[i].writeSummaryFromParcelLocked(out); 15967 u.mNetworkPacketActivityCounters[i].writeSummaryFromParcelLocked(out); 15968 } 15969 u.mMobileRadioActiveTime.writeSummaryFromParcelLocked(out); 15970 u.mMobileRadioActiveCount.writeSummaryFromParcelLocked(out); 15971 } 15972 15973 u.mUserCpuTime.writeSummaryFromParcelLocked(out); 15974 u.mSystemCpuTime.writeSummaryFromParcelLocked(out); 15975 15976 if (u.mCpuClusterSpeedTimesUs != null) { 15977 out.writeInt(1); 15978 out.writeInt(u.mCpuClusterSpeedTimesUs.length); 15979 for (LongSamplingCounter[] cpuSpeeds : u.mCpuClusterSpeedTimesUs) { 15980 if (cpuSpeeds != null) { 15981 out.writeInt(1); 15982 out.writeInt(cpuSpeeds.length); 15983 for (LongSamplingCounter c : cpuSpeeds) { 15984 if (c != null) { 15985 out.writeInt(1); 15986 c.writeSummaryFromParcelLocked(out); 15987 } else { 15988 out.writeInt(0); 15989 } 15990 } 15991 } else { 15992 out.writeInt(0); 15993 } 15994 } 15995 } else { 15996 out.writeInt(0); 15997 } 15998 15999 LongSamplingCounterArray.writeSummaryToParcelLocked(out, u.mCpuFreqTimeMs); 16000 LongSamplingCounterArray.writeSummaryToParcelLocked(out, u.mScreenOffCpuFreqTimeMs); 16001 16002 u.mCpuActiveTimeMs.writeSummaryFromParcelLocked(out); 16003 u.mCpuClusterTimesMs.writeSummaryToParcelLocked(out); 16004 16005 if (u.mProcStateTimeMs != null) { 16006 out.writeInt(u.mProcStateTimeMs.length); 16007 for (LongSamplingCounterArray counters : u.mProcStateTimeMs) { 16008 LongSamplingCounterArray.writeSummaryToParcelLocked(out, counters); 16009 } 16010 } else { 16011 out.writeInt(0); 16012 } 16013 if (u.mProcStateScreenOffTimeMs != null) { 16014 out.writeInt(u.mProcStateScreenOffTimeMs.length); 16015 for (LongSamplingCounterArray counters : u.mProcStateScreenOffTimeMs) { 16016 LongSamplingCounterArray.writeSummaryToParcelLocked(out, counters); 16017 } 16018 } else { 16019 out.writeInt(0); 16020 } 16021 16022 if (u.mMobileRadioApWakeupCount != null) { 16023 out.writeInt(1); 16024 u.mMobileRadioApWakeupCount.writeSummaryFromParcelLocked(out); 16025 } else { 16026 out.writeInt(0); 16027 } 16028 16029 if (u.mWifiRadioApWakeupCount != null) { 16030 out.writeInt(1); 16031 u.mWifiRadioApWakeupCount.writeSummaryFromParcelLocked(out); 16032 } else { 16033 out.writeInt(0); 16034 } 16035 16036 MeasuredEnergyStats.writeSummaryToParcel(u.mUidMeasuredEnergyStats, out, true, true); 16037 16038 final ArrayMap<String, Uid.Wakelock> wakeStats = u.mWakelockStats.getMap(); 16039 int NW = wakeStats.size(); 16040 out.writeInt(NW); 16041 for (int iw=0; iw<NW; iw++) { 16042 out.writeString(wakeStats.keyAt(iw)); 16043 Uid.Wakelock wl = wakeStats.valueAt(iw); 16044 if (wl.mTimerFull != null) { 16045 out.writeInt(1); 16046 wl.mTimerFull.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 16047 } else { 16048 out.writeInt(0); 16049 } 16050 if (wl.mTimerPartial != null) { 16051 out.writeInt(1); 16052 wl.mTimerPartial.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 16053 } else { 16054 out.writeInt(0); 16055 } 16056 if (wl.mTimerWindow != null) { 16057 out.writeInt(1); 16058 wl.mTimerWindow.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 16059 } else { 16060 out.writeInt(0); 16061 } 16062 if (wl.mTimerDraw != null) { 16063 out.writeInt(1); 16064 wl.mTimerDraw.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 16065 } else { 16066 out.writeInt(0); 16067 } 16068 } 16069 16070 final ArrayMap<String, DualTimer> syncStats = u.mSyncStats.getMap(); 16071 int NS = syncStats.size(); 16072 out.writeInt(NS); 16073 for (int is=0; is<NS; is++) { 16074 out.writeString(syncStats.keyAt(is)); 16075 syncStats.valueAt(is).writeSummaryFromParcelLocked(out, NOWREAL_SYS); 16076 } 16077 16078 final ArrayMap<String, DualTimer> jobStats = u.mJobStats.getMap(); 16079 int NJ = jobStats.size(); 16080 out.writeInt(NJ); 16081 for (int ij=0; ij<NJ; ij++) { 16082 out.writeString(jobStats.keyAt(ij)); 16083 jobStats.valueAt(ij).writeSummaryFromParcelLocked(out, NOWREAL_SYS); 16084 } 16085 16086 u.writeJobCompletionsToParcelLocked(out); 16087 16088 u.mJobsDeferredEventCount.writeSummaryFromParcelLocked(out); 16089 u.mJobsDeferredCount.writeSummaryFromParcelLocked(out); 16090 u.mJobsFreshnessTimeMs.writeSummaryFromParcelLocked(out); 16091 for (int i = 0; i < JOB_FRESHNESS_BUCKETS.length; i++) { 16092 if (u.mJobsFreshnessBuckets[i] != null) { 16093 out.writeInt(1); 16094 u.mJobsFreshnessBuckets[i].writeSummaryFromParcelLocked(out); 16095 } else { 16096 out.writeInt(0); 16097 } 16098 } 16099 16100 int NSE = u.mSensorStats.size(); 16101 out.writeInt(NSE); 16102 for (int ise=0; ise<NSE; ise++) { 16103 out.writeInt(u.mSensorStats.keyAt(ise)); 16104 Uid.Sensor se = u.mSensorStats.valueAt(ise); 16105 if (se.mTimer != null) { 16106 out.writeInt(1); 16107 se.mTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 16108 } else { 16109 out.writeInt(0); 16110 } 16111 } 16112 16113 int NP = u.mProcessStats.size(); 16114 out.writeInt(NP); 16115 for (int ip=0; ip<NP; ip++) { 16116 out.writeString(u.mProcessStats.keyAt(ip)); 16117 Uid.Proc ps = u.mProcessStats.valueAt(ip); 16118 out.writeLong(ps.mUserTimeMs); 16119 out.writeLong(ps.mSystemTimeMs); 16120 out.writeLong(ps.mForegroundTimeMs); 16121 out.writeInt(ps.mStarts); 16122 out.writeInt(ps.mNumCrashes); 16123 out.writeInt(ps.mNumAnrs); 16124 ps.writeExcessivePowerToParcelLocked(out); 16125 } 16126 16127 NP = u.mPackageStats.size(); 16128 out.writeInt(NP); 16129 if (NP > 0) { 16130 for (Map.Entry<String, BatteryStatsImpl.Uid.Pkg> ent 16131 : u.mPackageStats.entrySet()) { 16132 out.writeString(ent.getKey()); 16133 Uid.Pkg ps = ent.getValue(); 16134 final int NWA = ps.mWakeupAlarms.size(); 16135 out.writeInt(NWA); 16136 for (int iwa=0; iwa<NWA; iwa++) { 16137 out.writeString(ps.mWakeupAlarms.keyAt(iwa)); 16138 ps.mWakeupAlarms.valueAt(iwa).writeSummaryFromParcelLocked(out); 16139 } 16140 NS = ps.mServiceStats.size(); 16141 out.writeInt(NS); 16142 for (int is=0; is<NS; is++) { 16143 out.writeString(ps.mServiceStats.keyAt(is)); 16144 BatteryStatsImpl.Uid.Pkg.Serv ss = ps.mServiceStats.valueAt(is); 16145 long time = ss.getStartTimeToNowLocked( 16146 mOnBatteryTimeBase.getUptime(NOW_SYS) / 1000); 16147 out.writeLong(time); 16148 out.writeInt(ss.mStarts); 16149 out.writeInt(ss.mLaunches); 16150 } 16151 } 16152 } 16153 } 16154 16155 LongSamplingCounterArray.writeSummaryToParcelLocked(out, mBinderThreadCpuTimesUs); 16156 } 16157 readFromParcel(Parcel in)16158 public void readFromParcel(Parcel in) { 16159 readFromParcelLocked(in); 16160 } 16161 readFromParcelLocked(Parcel in)16162 void readFromParcelLocked(Parcel in) { 16163 int magic = in.readInt(); 16164 if (magic != MAGIC) { 16165 throw new ParcelFormatException("Bad magic number: #" + Integer.toHexString(magic)); 16166 } 16167 16168 readHistoryBuffer(in); 16169 mBatteryStatsHistory.readFromParcel(in); 16170 16171 mStartCount = in.readInt(); 16172 mStartClockTimeMs = in.readLong(); 16173 mStartPlatformVersion = in.readString(); 16174 mEndPlatformVersion = in.readString(); 16175 mUptimeUs = in.readLong(); 16176 mUptimeStartUs = in.readLong(); 16177 mRealtimeUs = in.readLong(); 16178 mRealtimeStartUs = in.readLong(); 16179 mOnBattery = in.readInt() != 0; 16180 mEstimatedBatteryCapacityMah = in.readInt(); 16181 mLastLearnedBatteryCapacityUah = in.readInt(); 16182 mMinLearnedBatteryCapacityUah = in.readInt(); 16183 mMaxLearnedBatteryCapacityUah = in.readInt(); 16184 mOnBatteryInternal = false; // we are no longer really running. 16185 mOnBatteryTimeBase.readFromParcel(in); 16186 mOnBatteryScreenOffTimeBase.readFromParcel(in); 16187 16188 mScreenState = Display.STATE_UNKNOWN; 16189 mScreenOnTimer = new StopwatchTimer(mClocks, null, -1, null, mOnBatteryTimeBase, in); 16190 mScreenDozeTimer = new StopwatchTimer(mClocks, null, -1, null, mOnBatteryTimeBase, in); 16191 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 16192 mScreenBrightnessTimer[i] = new StopwatchTimer(mClocks, null, -100-i, null, 16193 mOnBatteryTimeBase, in); 16194 } 16195 mInteractive = false; 16196 mInteractiveTimer = new StopwatchTimer(mClocks, null, -10, null, mOnBatteryTimeBase, in); 16197 mPhoneOn = false; 16198 mPowerSaveModeEnabledTimer = new StopwatchTimer(mClocks, null, -2, null, 16199 mOnBatteryTimeBase, in); 16200 mLongestLightIdleTimeMs = in.readLong(); 16201 mLongestFullIdleTimeMs = in.readLong(); 16202 mDeviceIdleModeLightTimer = new StopwatchTimer(mClocks, null, -14, null, 16203 mOnBatteryTimeBase, in); 16204 mDeviceIdleModeFullTimer = new StopwatchTimer(mClocks, null, -11, null, 16205 mOnBatteryTimeBase, in); 16206 mDeviceLightIdlingTimer = new StopwatchTimer(mClocks, null, -15, null, 16207 mOnBatteryTimeBase, in); 16208 mDeviceIdlingTimer = new StopwatchTimer(mClocks, null, -12, null, mOnBatteryTimeBase, in); 16209 mPhoneOnTimer = new StopwatchTimer(mClocks, null, -3, null, mOnBatteryTimeBase, in); 16210 for (int i = 0; i < CellSignalStrength.getNumSignalStrengthLevels(); i++) { 16211 mPhoneSignalStrengthsTimer[i] = new StopwatchTimer(mClocks, null, -200-i, 16212 null, mOnBatteryTimeBase, in); 16213 } 16214 mPhoneSignalScanningTimer = new StopwatchTimer(mClocks, null, -200+1, null, 16215 mOnBatteryTimeBase, in); 16216 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 16217 mPhoneDataConnectionsTimer[i] = new StopwatchTimer(mClocks, null, -300-i, 16218 null, mOnBatteryTimeBase, in); 16219 } 16220 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 16221 mNetworkByteActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase, in); 16222 mNetworkPacketActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase, in); 16223 } 16224 mMobileRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW; 16225 mMobileRadioActiveTimer = new StopwatchTimer(mClocks, null, -400, null, 16226 mOnBatteryTimeBase, in); 16227 mMobileRadioActivePerAppTimer = new StopwatchTimer(mClocks, null, -401, null, 16228 mOnBatteryTimeBase, in); 16229 mMobileRadioActiveAdjustedTime = new LongSamplingCounter(mOnBatteryTimeBase, in); 16230 mMobileRadioActiveUnknownTime = new LongSamplingCounter(mOnBatteryTimeBase, in); 16231 mMobileRadioActiveUnknownCount = new LongSamplingCounter(mOnBatteryTimeBase, in); 16232 mWifiMulticastWakelockTimer = new StopwatchTimer(mClocks, null, -4, null, 16233 mOnBatteryTimeBase, in); 16234 mWifiRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW; 16235 mWifiOn = false; 16236 mWifiOnTimer = new StopwatchTimer(mClocks, null, -4, null, mOnBatteryTimeBase, in); 16237 mGlobalWifiRunning = false; 16238 mGlobalWifiRunningTimer = new StopwatchTimer(mClocks, null, -5, null, 16239 mOnBatteryTimeBase, in); 16240 for (int i=0; i<NUM_WIFI_STATES; i++) { 16241 mWifiStateTimer[i] = new StopwatchTimer(mClocks, null, -600-i, 16242 null, mOnBatteryTimeBase, in); 16243 } 16244 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) { 16245 mWifiSupplStateTimer[i] = new StopwatchTimer(mClocks, null, -700-i, 16246 null, mOnBatteryTimeBase, in); 16247 } 16248 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { 16249 mWifiSignalStrengthsTimer[i] = new StopwatchTimer(mClocks, null, -800-i, 16250 null, mOnBatteryTimeBase, in); 16251 } 16252 mWifiActiveTimer = new StopwatchTimer(mClocks, null, -900, null, 16253 mOnBatteryTimeBase, in); 16254 mWifiActivity = new ControllerActivityCounterImpl(mOnBatteryTimeBase, 16255 NUM_WIFI_TX_LEVELS, in); 16256 for (int i=0; i<mGpsSignalQualityTimer.length; i++) { 16257 mGpsSignalQualityTimer[i] = new StopwatchTimer(mClocks, null, -1000-i, 16258 null, mOnBatteryTimeBase, in); 16259 } 16260 mBluetoothActivity = new ControllerActivityCounterImpl(mOnBatteryTimeBase, 16261 NUM_BT_TX_LEVELS, in); 16262 mModemActivity = new ControllerActivityCounterImpl(mOnBatteryTimeBase, 16263 ModemActivityInfo.getNumTxPowerLevels(), in); 16264 mHasWifiReporting = in.readInt() != 0; 16265 mHasBluetoothReporting = in.readInt() != 0; 16266 mHasModemReporting = in.readInt() != 0; 16267 16268 mNumConnectivityChange = in.readInt(); 16269 mAudioOnNesting = 0; 16270 // TODO: It's likely a mistake that mAudioOnTimer/mVideoOnTimer don't write/read to parcel! 16271 mAudioOnTimer = new StopwatchTimer(mClocks, null, -7, null, mOnBatteryTimeBase); 16272 mVideoOnNesting = 0; 16273 mVideoOnTimer = new StopwatchTimer(mClocks, null, -8, null, mOnBatteryTimeBase); 16274 mFlashlightOnNesting = 0; 16275 mFlashlightOnTimer = new StopwatchTimer(mClocks, null, -9, null, mOnBatteryTimeBase, in); 16276 mCameraOnNesting = 0; 16277 mCameraOnTimer = new StopwatchTimer(mClocks, null, -13, null, mOnBatteryTimeBase, in); 16278 mBluetoothScanNesting = 0; 16279 mBluetoothScanTimer = new StopwatchTimer(mClocks, null, -14, null, mOnBatteryTimeBase, in); 16280 mDischargeUnplugLevel = in.readInt(); 16281 mDischargePlugLevel = in.readInt(); 16282 mDischargeCurrentLevel = in.readInt(); 16283 mCurrentBatteryLevel = in.readInt(); 16284 mLowDischargeAmountSinceCharge = in.readInt(); 16285 mHighDischargeAmountSinceCharge = in.readInt(); 16286 mDischargeAmountScreenOn = in.readInt(); 16287 mDischargeAmountScreenOnSinceCharge = in.readInt(); 16288 mDischargeAmountScreenOff = in.readInt(); 16289 mDischargeAmountScreenOffSinceCharge = in.readInt(); 16290 mDischargeAmountScreenDoze = in.readInt(); 16291 mDischargeAmountScreenDozeSinceCharge = in.readInt(); 16292 mDischargeStepTracker.readFromParcel(in); 16293 mChargeStepTracker.readFromParcel(in); 16294 mDischargeCounter = new LongSamplingCounter(mOnBatteryTimeBase, in); 16295 mDischargeScreenOffCounter = new LongSamplingCounter(mOnBatteryScreenOffTimeBase, in); 16296 mDischargeScreenDozeCounter = new LongSamplingCounter(mOnBatteryTimeBase, in); 16297 mDischargeLightDozeCounter = new LongSamplingCounter(mOnBatteryTimeBase, in); 16298 mDischargeDeepDozeCounter = new LongSamplingCounter(mOnBatteryTimeBase, in); 16299 mLastWriteTimeMs = in.readLong(); 16300 mBatteryTimeToFullSeconds = in.readLong(); 16301 16302 if (in.readInt() != 0) { 16303 mGlobalMeasuredEnergyStats = new MeasuredEnergyStats(in); 16304 } 16305 16306 mRpmStats.clear(); 16307 int NRPMS = in.readInt(); 16308 for (int irpm = 0; irpm < NRPMS; irpm++) { 16309 if (in.readInt() != 0) { 16310 String rpmName = in.readString(); 16311 SamplingTimer rpmt = new SamplingTimer(mClocks, mOnBatteryTimeBase, in); 16312 mRpmStats.put(rpmName, rpmt); 16313 } 16314 } 16315 mScreenOffRpmStats.clear(); 16316 int NSORPMS = in.readInt(); 16317 for (int irpm = 0; irpm < NSORPMS; irpm++) { 16318 if (in.readInt() != 0) { 16319 String rpmName = in.readString(); 16320 SamplingTimer rpmt = new SamplingTimer(mClocks, mOnBatteryScreenOffTimeBase, in); 16321 mScreenOffRpmStats.put(rpmName, rpmt); 16322 } 16323 } 16324 16325 mKernelWakelockStats.clear(); 16326 int NKW = in.readInt(); 16327 for (int ikw = 0; ikw < NKW; ikw++) { 16328 if (in.readInt() != 0) { 16329 String wakelockName = in.readString(); 16330 SamplingTimer kwlt = new SamplingTimer(mClocks, mOnBatteryScreenOffTimeBase, in); 16331 mKernelWakelockStats.put(wakelockName, kwlt); 16332 } 16333 } 16334 16335 mWakeupReasonStats.clear(); 16336 int NWR = in.readInt(); 16337 for (int iwr = 0; iwr < NWR; iwr++) { 16338 if (in.readInt() != 0) { 16339 String reasonName = in.readString(); 16340 SamplingTimer timer = new SamplingTimer(mClocks, mOnBatteryTimeBase, in); 16341 mWakeupReasonStats.put(reasonName, timer); 16342 } 16343 } 16344 16345 mKernelMemoryStats.clear(); 16346 int nmt = in.readInt(); 16347 for (int imt = 0; imt < nmt; imt++) { 16348 if (in.readInt() != 0) { 16349 Long bucket = in.readLong(); 16350 SamplingTimer kmt = new SamplingTimer(mClocks, mOnBatteryTimeBase, in); 16351 mKernelMemoryStats.put(bucket, kmt); 16352 } 16353 } 16354 16355 mPartialTimers.clear(); 16356 mFullTimers.clear(); 16357 mWindowTimers.clear(); 16358 mWifiRunningTimers.clear(); 16359 mFullWifiLockTimers.clear(); 16360 mWifiScanTimers.clear(); 16361 mWifiBatchedScanTimers.clear(); 16362 mWifiMulticastTimers.clear(); 16363 mAudioTurnedOnTimers.clear(); 16364 mVideoTurnedOnTimers.clear(); 16365 mFlashlightTurnedOnTimers.clear(); 16366 mCameraTurnedOnTimers.clear(); 16367 16368 int numUids = in.readInt(); 16369 mUidStats.clear(); 16370 final long elapsedRealtimeMs = mClocks.elapsedRealtime(); 16371 final long uptimeMs = mClocks.uptimeMillis(); 16372 for (int i = 0; i < numUids; i++) { 16373 int uid = in.readInt(); 16374 Uid u = new Uid(this, uid, elapsedRealtimeMs, uptimeMs); 16375 u.readFromParcelLocked(mOnBatteryTimeBase, mOnBatteryScreenOffTimeBase, in); 16376 mUidStats.append(uid, u); 16377 } 16378 16379 mBinderThreadCpuTimesUs = LongSamplingCounterArray.readFromParcel(in, mOnBatteryTimeBase); 16380 } 16381 writeToParcel(Parcel out, int flags)16382 public void writeToParcel(Parcel out, int flags) { 16383 writeToParcelLocked(out, true, flags); 16384 } 16385 writeToParcelWithoutUids(Parcel out, int flags)16386 public void writeToParcelWithoutUids(Parcel out, int flags) { 16387 writeToParcelLocked(out, false, flags); 16388 } 16389 16390 @SuppressWarnings("unused") writeToParcelLocked(Parcel out, boolean inclUids, int flags)16391 void writeToParcelLocked(Parcel out, boolean inclUids, int flags) { 16392 // Need to update with current kernel wake lock counts. 16393 pullPendingStateUpdatesLocked(); 16394 16395 updateSystemServiceCallStats(); 16396 16397 // Pull the clock time. This may update the time and make a new history entry 16398 // if we had originally pulled a time before the RTC was set. 16399 getStartClockTime(); 16400 16401 final long uSecUptime = mClocks.uptimeMillis() * 1000; 16402 final long uSecRealtime = mClocks.elapsedRealtime() * 1000; 16403 final long batteryRealtime = mOnBatteryTimeBase.getRealtime(uSecRealtime); 16404 final long batteryScreenOffRealtime = mOnBatteryScreenOffTimeBase.getRealtime(uSecRealtime); 16405 16406 out.writeInt(MAGIC); 16407 16408 writeHistoryBuffer(out, true); 16409 mBatteryStatsHistory.writeToParcel(out); 16410 16411 out.writeInt(mStartCount); 16412 out.writeLong(mStartClockTimeMs); 16413 out.writeString(mStartPlatformVersion); 16414 out.writeString(mEndPlatformVersion); 16415 out.writeLong(mUptimeUs); 16416 out.writeLong(mUptimeStartUs); 16417 out.writeLong(mRealtimeUs); 16418 out.writeLong(mRealtimeStartUs); 16419 out.writeInt(mOnBattery ? 1 : 0); 16420 out.writeInt(mEstimatedBatteryCapacityMah); 16421 out.writeInt(mLastLearnedBatteryCapacityUah); 16422 out.writeInt(mMinLearnedBatteryCapacityUah); 16423 out.writeInt(mMaxLearnedBatteryCapacityUah); 16424 mOnBatteryTimeBase.writeToParcel(out, uSecUptime, uSecRealtime); 16425 mOnBatteryScreenOffTimeBase.writeToParcel(out, uSecUptime, uSecRealtime); 16426 16427 mScreenOnTimer.writeToParcel(out, uSecRealtime); 16428 mScreenDozeTimer.writeToParcel(out, uSecRealtime); 16429 for (int i = 0; i < NUM_SCREEN_BRIGHTNESS_BINS; i++) { 16430 mScreenBrightnessTimer[i].writeToParcel(out, uSecRealtime); 16431 } 16432 mInteractiveTimer.writeToParcel(out, uSecRealtime); 16433 mPowerSaveModeEnabledTimer.writeToParcel(out, uSecRealtime); 16434 out.writeLong(mLongestLightIdleTimeMs); 16435 out.writeLong(mLongestFullIdleTimeMs); 16436 mDeviceIdleModeLightTimer.writeToParcel(out, uSecRealtime); 16437 mDeviceIdleModeFullTimer.writeToParcel(out, uSecRealtime); 16438 mDeviceLightIdlingTimer.writeToParcel(out, uSecRealtime); 16439 mDeviceIdlingTimer.writeToParcel(out, uSecRealtime); 16440 mPhoneOnTimer.writeToParcel(out, uSecRealtime); 16441 for (int i = 0; i < CellSignalStrength.getNumSignalStrengthLevels(); i++) { 16442 mPhoneSignalStrengthsTimer[i].writeToParcel(out, uSecRealtime); 16443 } 16444 mPhoneSignalScanningTimer.writeToParcel(out, uSecRealtime); 16445 for (int i = 0; i < NUM_DATA_CONNECTION_TYPES; i++) { 16446 mPhoneDataConnectionsTimer[i].writeToParcel(out, uSecRealtime); 16447 } 16448 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 16449 mNetworkByteActivityCounters[i].writeToParcel(out); 16450 mNetworkPacketActivityCounters[i].writeToParcel(out); 16451 } 16452 mMobileRadioActiveTimer.writeToParcel(out, uSecRealtime); 16453 mMobileRadioActivePerAppTimer.writeToParcel(out, uSecRealtime); 16454 mMobileRadioActiveAdjustedTime.writeToParcel(out); 16455 mMobileRadioActiveUnknownTime.writeToParcel(out); 16456 mMobileRadioActiveUnknownCount.writeToParcel(out); 16457 mWifiMulticastWakelockTimer.writeToParcel(out, uSecRealtime); 16458 mWifiOnTimer.writeToParcel(out, uSecRealtime); 16459 mGlobalWifiRunningTimer.writeToParcel(out, uSecRealtime); 16460 for (int i = 0; i < NUM_WIFI_STATES; i++) { 16461 mWifiStateTimer[i].writeToParcel(out, uSecRealtime); 16462 } 16463 for (int i = 0; i < NUM_WIFI_SUPPL_STATES; i++) { 16464 mWifiSupplStateTimer[i].writeToParcel(out, uSecRealtime); 16465 } 16466 for (int i = 0; i < NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { 16467 mWifiSignalStrengthsTimer[i].writeToParcel(out, uSecRealtime); 16468 } 16469 mWifiActiveTimer.writeToParcel(out, uSecRealtime); 16470 mWifiActivity.writeToParcel(out, 0); 16471 for (int i = 0; i < mGpsSignalQualityTimer.length; i++) { 16472 mGpsSignalQualityTimer[i].writeToParcel(out, uSecRealtime); 16473 } 16474 mBluetoothActivity.writeToParcel(out, 0); 16475 mModemActivity.writeToParcel(out, 0); 16476 out.writeInt(mHasWifiReporting ? 1 : 0); 16477 out.writeInt(mHasBluetoothReporting ? 1 : 0); 16478 out.writeInt(mHasModemReporting ? 1 : 0); 16479 16480 out.writeInt(mNumConnectivityChange); 16481 mFlashlightOnTimer.writeToParcel(out, uSecRealtime); 16482 mCameraOnTimer.writeToParcel(out, uSecRealtime); 16483 mBluetoothScanTimer.writeToParcel(out, uSecRealtime); 16484 out.writeInt(mDischargeUnplugLevel); 16485 out.writeInt(mDischargePlugLevel); 16486 out.writeInt(mDischargeCurrentLevel); 16487 out.writeInt(mCurrentBatteryLevel); 16488 out.writeInt(mLowDischargeAmountSinceCharge); 16489 out.writeInt(mHighDischargeAmountSinceCharge); 16490 out.writeInt(mDischargeAmountScreenOn); 16491 out.writeInt(mDischargeAmountScreenOnSinceCharge); 16492 out.writeInt(mDischargeAmountScreenOff); 16493 out.writeInt(mDischargeAmountScreenOffSinceCharge); 16494 out.writeInt(mDischargeAmountScreenDoze); 16495 out.writeInt(mDischargeAmountScreenDozeSinceCharge); 16496 mDischargeStepTracker.writeToParcel(out); 16497 mChargeStepTracker.writeToParcel(out); 16498 mDischargeCounter.writeToParcel(out); 16499 mDischargeScreenOffCounter.writeToParcel(out); 16500 mDischargeScreenDozeCounter.writeToParcel(out); 16501 mDischargeLightDozeCounter.writeToParcel(out); 16502 mDischargeDeepDozeCounter.writeToParcel(out); 16503 out.writeLong(mLastWriteTimeMs); 16504 out.writeLong(mBatteryTimeToFullSeconds); 16505 16506 if (mGlobalMeasuredEnergyStats != null) { 16507 out.writeInt(1); 16508 mGlobalMeasuredEnergyStats.writeToParcel(out); 16509 } else { 16510 out.writeInt(0); 16511 } 16512 16513 out.writeInt(mRpmStats.size()); 16514 for (Map.Entry<String, SamplingTimer> ent : mRpmStats.entrySet()) { 16515 SamplingTimer rpmt = ent.getValue(); 16516 if (rpmt != null) { 16517 out.writeInt(1); 16518 out.writeString(ent.getKey()); 16519 rpmt.writeToParcel(out, uSecRealtime); 16520 } else { 16521 out.writeInt(0); 16522 } 16523 } 16524 out.writeInt(mScreenOffRpmStats.size()); 16525 for (Map.Entry<String, SamplingTimer> ent : mScreenOffRpmStats.entrySet()) { 16526 SamplingTimer rpmt = ent.getValue(); 16527 if (rpmt != null) { 16528 out.writeInt(1); 16529 out.writeString(ent.getKey()); 16530 rpmt.writeToParcel(out, uSecRealtime); 16531 } else { 16532 out.writeInt(0); 16533 } 16534 } 16535 16536 if (inclUids) { 16537 out.writeInt(mKernelWakelockStats.size()); 16538 for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) { 16539 SamplingTimer kwlt = ent.getValue(); 16540 if (kwlt != null) { 16541 out.writeInt(1); 16542 out.writeString(ent.getKey()); 16543 kwlt.writeToParcel(out, uSecRealtime); 16544 } else { 16545 out.writeInt(0); 16546 } 16547 } 16548 out.writeInt(mWakeupReasonStats.size()); 16549 for (Map.Entry<String, SamplingTimer> ent : mWakeupReasonStats.entrySet()) { 16550 SamplingTimer timer = ent.getValue(); 16551 if (timer != null) { 16552 out.writeInt(1); 16553 out.writeString(ent.getKey()); 16554 timer.writeToParcel(out, uSecRealtime); 16555 } else { 16556 out.writeInt(0); 16557 } 16558 } 16559 } else { 16560 out.writeInt(0); 16561 out.writeInt(0); 16562 } 16563 16564 out.writeInt(mKernelMemoryStats.size()); 16565 for (int i = 0; i < mKernelMemoryStats.size(); i++) { 16566 SamplingTimer kmt = mKernelMemoryStats.valueAt(i); 16567 if (kmt != null) { 16568 out.writeInt(1); 16569 out.writeLong(mKernelMemoryStats.keyAt(i)); 16570 kmt.writeToParcel(out, uSecRealtime); 16571 } else { 16572 out.writeInt(0); 16573 } 16574 } 16575 16576 if (inclUids) { 16577 int size = mUidStats.size(); 16578 out.writeInt(size); 16579 for (int i = 0; i < size; i++) { 16580 out.writeInt(mUidStats.keyAt(i)); 16581 Uid uid = mUidStats.valueAt(i); 16582 16583 uid.writeToParcelLocked(out, uSecUptime, uSecRealtime); 16584 } 16585 } else { 16586 out.writeInt(0); 16587 } 16588 LongSamplingCounterArray.writeToParcel(out, mBinderThreadCpuTimesUs); 16589 } 16590 writeCpuSpeedCountersToParcel(Parcel out, LongSamplingCounter[][] counters)16591 private void writeCpuSpeedCountersToParcel(Parcel out, LongSamplingCounter[][] counters) { 16592 if (counters == null) { 16593 out.writeInt(0); 16594 return; 16595 } 16596 16597 out.writeInt(1); 16598 out.writeInt(counters.length); 16599 for (int i = 0; i < counters.length; i++) { 16600 LongSamplingCounter[] counterArray = counters[i]; 16601 if (counterArray == null) { 16602 out.writeInt(0); 16603 continue; 16604 } 16605 16606 out.writeInt(1); 16607 out.writeInt(counterArray.length); 16608 for (int j = 0; j < counterArray.length; j++) { 16609 LongSamplingCounter c = counterArray[j]; 16610 if (c != null) { 16611 out.writeInt(1); 16612 c.writeToParcel(out); 16613 } else { 16614 out.writeInt(0); 16615 } 16616 } 16617 } 16618 } 16619 readCpuSpeedCountersFromParcel(Parcel in)16620 private LongSamplingCounter[][] readCpuSpeedCountersFromParcel(Parcel in) { 16621 LongSamplingCounter[][] counters; 16622 if (in.readInt() != 0) { 16623 int numCpuClusters = in.readInt(); 16624 if (mPowerProfile != null 16625 && mPowerProfile.getNumCpuClusters() != numCpuClusters) { 16626 throw new ParcelFormatException("Incompatible number of cpu clusters"); 16627 } 16628 16629 counters = new LongSamplingCounter[numCpuClusters][]; 16630 for (int cluster = 0; cluster < numCpuClusters; cluster++) { 16631 if (in.readInt() != 0) { 16632 int numSpeeds = in.readInt(); 16633 if (mPowerProfile != null 16634 && mPowerProfile.getNumSpeedStepsInCpuCluster(cluster) != numSpeeds) { 16635 throw new ParcelFormatException("Incompatible number of cpu speeds"); 16636 } 16637 16638 final LongSamplingCounter[] cpuSpeeds = new LongSamplingCounter[numSpeeds]; 16639 counters[cluster] = cpuSpeeds; 16640 for (int speed = 0; speed < numSpeeds; speed++) { 16641 if (in.readInt() != 0) { 16642 cpuSpeeds[speed] = new LongSamplingCounter(mOnBatteryTimeBase, in); 16643 } 16644 } 16645 } else { 16646 counters[cluster] = null; 16647 } 16648 } 16649 } else { 16650 counters = null; 16651 } 16652 16653 return counters; 16654 } 16655 16656 @UnsupportedAppUsage 16657 public static final Parcelable.Creator<BatteryStatsImpl> CREATOR = 16658 new Parcelable.Creator<BatteryStatsImpl>() { 16659 public BatteryStatsImpl createFromParcel(Parcel in) { 16660 return new BatteryStatsImpl(in); 16661 } 16662 16663 public BatteryStatsImpl[] newArray(int size) { 16664 return new BatteryStatsImpl[size]; 16665 } 16666 }; 16667 prepareForDumpLocked()16668 public void prepareForDumpLocked() { 16669 // Need to retrieve current kernel wake lock stats before printing. 16670 pullPendingStateUpdatesLocked(); 16671 16672 // Pull the clock time. This may update the time and make a new history entry 16673 // if we had originally pulled a time before the RTC was set. 16674 getStartClockTime(); 16675 16676 updateSystemServiceCallStats(); 16677 } 16678 dumpLocked(Context context, PrintWriter pw, int flags, int reqUid, long histStart)16679 public void dumpLocked(Context context, PrintWriter pw, int flags, int reqUid, long histStart) { 16680 if (DEBUG) { 16681 pw.println("mOnBatteryTimeBase:"); 16682 mOnBatteryTimeBase.dump(pw, " "); 16683 pw.println("mOnBatteryScreenOffTimeBase:"); 16684 mOnBatteryScreenOffTimeBase.dump(pw, " "); 16685 Printer pr = new PrintWriterPrinter(pw); 16686 pr.println("*** Screen on timer:"); 16687 mScreenOnTimer.logState(pr, " "); 16688 pr.println("*** Screen doze timer:"); 16689 mScreenDozeTimer.logState(pr, " "); 16690 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 16691 pr.println("*** Screen brightness #" + i + ":"); 16692 mScreenBrightnessTimer[i].logState(pr, " "); 16693 } 16694 pr.println("*** Interactive timer:"); 16695 mInteractiveTimer.logState(pr, " "); 16696 pr.println("*** Power save mode timer:"); 16697 mPowerSaveModeEnabledTimer.logState(pr, " "); 16698 pr.println("*** Device idle mode light timer:"); 16699 mDeviceIdleModeLightTimer.logState(pr, " "); 16700 pr.println("*** Device idle mode full timer:"); 16701 mDeviceIdleModeFullTimer.logState(pr, " "); 16702 pr.println("*** Device light idling timer:"); 16703 mDeviceLightIdlingTimer.logState(pr, " "); 16704 pr.println("*** Device idling timer:"); 16705 mDeviceIdlingTimer.logState(pr, " "); 16706 pr.println("*** Phone timer:"); 16707 mPhoneOnTimer.logState(pr, " "); 16708 for (int i = 0; i < CellSignalStrength.getNumSignalStrengthLevels(); i++) { 16709 pr.println("*** Phone signal strength #" + i + ":"); 16710 mPhoneSignalStrengthsTimer[i].logState(pr, " "); 16711 } 16712 pr.println("*** Signal scanning :"); 16713 mPhoneSignalScanningTimer.logState(pr, " "); 16714 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 16715 pr.println("*** Data connection type #" + i + ":"); 16716 mPhoneDataConnectionsTimer[i].logState(pr, " "); 16717 } 16718 pr.println("*** mMobileRadioPowerState=" + mMobileRadioPowerState); 16719 pr.println("*** Mobile network active timer:"); 16720 mMobileRadioActiveTimer.logState(pr, " "); 16721 pr.println("*** Mobile network active adjusted timer:"); 16722 mMobileRadioActiveAdjustedTime.logState(pr, " "); 16723 pr.println("*** Wifi Multicast WakeLock Timer:"); 16724 mWifiMulticastWakelockTimer.logState(pr, " "); 16725 pr.println("*** mWifiRadioPowerState=" + mWifiRadioPowerState); 16726 pr.println("*** Wifi timer:"); 16727 mWifiOnTimer.logState(pr, " "); 16728 pr.println("*** WifiRunning timer:"); 16729 mGlobalWifiRunningTimer.logState(pr, " "); 16730 for (int i=0; i<NUM_WIFI_STATES; i++) { 16731 pr.println("*** Wifi state #" + i + ":"); 16732 mWifiStateTimer[i].logState(pr, " "); 16733 } 16734 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) { 16735 pr.println("*** Wifi suppl state #" + i + ":"); 16736 mWifiSupplStateTimer[i].logState(pr, " "); 16737 } 16738 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { 16739 pr.println("*** Wifi signal strength #" + i + ":"); 16740 mWifiSignalStrengthsTimer[i].logState(pr, " "); 16741 } 16742 for (int i=0; i<mGpsSignalQualityTimer.length; i++) { 16743 pr.println("*** GPS signal quality #" + i + ":"); 16744 mGpsSignalQualityTimer[i].logState(pr, " "); 16745 } 16746 pr.println("*** Flashlight timer:"); 16747 mFlashlightOnTimer.logState(pr, " "); 16748 pr.println("*** Camera timer:"); 16749 mCameraOnTimer.logState(pr, " "); 16750 } 16751 super.dumpLocked(context, pw, flags, reqUid, histStart); 16752 16753 pw.print("Total cpu time reads: "); 16754 pw.println(mNumSingleUidCpuTimeReads); 16755 pw.print("Batched cpu time reads: "); 16756 pw.println(mNumBatchedSingleUidCpuTimeReads); 16757 pw.print("Batching Duration (min): "); 16758 pw.println((mClocks.uptimeMillis() - mCpuTimeReadsTrackingStartTimeMs) / (60 * 1000)); 16759 pw.print("All UID cpu time reads since the later of device start or stats reset: "); 16760 pw.println(mNumAllUidCpuTimeReads); 16761 pw.print("UIDs removed since the later of device start or stats reset: "); 16762 pw.println(mNumUidsRemoved); 16763 16764 pw.println(); 16765 dumpConstantsLocked(pw); 16766 16767 pw.println(); 16768 dumpMeasuredEnergyStatsLocked(pw); 16769 } 16770 } 16771