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, int[] perDisplayScreenStates)692 Future<?> scheduleSyncDueToScreenStateChange(int flags, boolean onBattery, 693 boolean onBatteryScreenOff, int screenState, int[] perDisplayScreenStates); 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 * Internal reference count of isolated uids. 712 */ 713 final SparseIntArray mIsolatedUidRefCounts = new SparseIntArray(); 714 715 /** 716 * The statistics we have collected organized by uids. 717 */ 718 final SparseArray<BatteryStatsImpl.Uid> mUidStats = new SparseArray<>(); 719 720 // A set of pools of currently active timers. When a timer is queried, we will divide the 721 // elapsed time by the number of active timers to arrive at that timer's share of the time. 722 // In order to do this, we must refresh each timer whenever the number of active timers 723 // changes. 724 @VisibleForTesting 725 @UnsupportedAppUsage 726 protected ArrayList<StopwatchTimer> mPartialTimers = new ArrayList<>(); 727 @UnsupportedAppUsage 728 final ArrayList<StopwatchTimer> mFullTimers = new ArrayList<>(); 729 @UnsupportedAppUsage 730 final ArrayList<StopwatchTimer> mWindowTimers = new ArrayList<>(); 731 final ArrayList<StopwatchTimer> mDrawTimers = new ArrayList<>(); 732 final SparseArray<ArrayList<StopwatchTimer>> mSensorTimers = new SparseArray<>(); 733 final ArrayList<StopwatchTimer> mWifiRunningTimers = new ArrayList<>(); 734 final ArrayList<StopwatchTimer> mFullWifiLockTimers = new ArrayList<>(); 735 final ArrayList<StopwatchTimer> mWifiMulticastTimers = new ArrayList<>(); 736 final ArrayList<StopwatchTimer> mWifiScanTimers = new ArrayList<>(); 737 final SparseArray<ArrayList<StopwatchTimer>> mWifiBatchedScanTimers = new SparseArray<>(); 738 final ArrayList<StopwatchTimer> mAudioTurnedOnTimers = new ArrayList<>(); 739 final ArrayList<StopwatchTimer> mVideoTurnedOnTimers = new ArrayList<>(); 740 final ArrayList<StopwatchTimer> mFlashlightTurnedOnTimers = new ArrayList<>(); 741 final ArrayList<StopwatchTimer> mCameraTurnedOnTimers = new ArrayList<>(); 742 final ArrayList<StopwatchTimer> mBluetoothScanOnTimers = new ArrayList<>(); 743 744 // Last partial timers we use for distributing CPU usage. 745 @VisibleForTesting 746 protected ArrayList<StopwatchTimer> mLastPartialTimers = new ArrayList<>(); 747 748 // These are the objects that will want to do something when the device 749 // is unplugged from power. 750 protected final TimeBase mOnBatteryTimeBase = new TimeBase(true); 751 752 // These are the objects that will want to do something when the device 753 // is unplugged from power *and* the screen is off or doze. 754 protected final TimeBase mOnBatteryScreenOffTimeBase = new TimeBase(true); 755 756 // Set to true when we want to distribute CPU across wakelocks for the next 757 // CPU update, even if we aren't currently running wake locks. 758 boolean mDistributeWakelockCpu; 759 760 private boolean mSystemReady; 761 boolean mShuttingDown; 762 763 final HistoryEventTracker mActiveEvents = new HistoryEventTracker(); 764 765 long mHistoryBaseTimeMs; 766 protected boolean mHaveBatteryLevel = false; 767 protected boolean mRecordingHistory = false; 768 int mNumHistoryItems; 769 770 final HashMap<HistoryTag, Integer> mHistoryTagPool = new HashMap<>(); 771 final Parcel mHistoryBuffer = Parcel.obtain(); 772 final HistoryItem mHistoryLastWritten = new HistoryItem(); 773 final HistoryItem mHistoryLastLastWritten = new HistoryItem(); 774 final HistoryItem mHistoryAddTmp = new HistoryItem(); 775 int mNextHistoryTagIdx = 0; 776 int mNumHistoryTagChars = 0; 777 int mHistoryBufferLastPos = -1; 778 int mActiveHistoryStates = 0xffffffff; 779 int mActiveHistoryStates2 = 0xffffffff; 780 long mLastHistoryElapsedRealtimeMs = 0; 781 long mTrackRunningHistoryElapsedRealtimeMs = 0; 782 long mTrackRunningHistoryUptimeMs = 0; 783 784 @NonNull 785 final BatteryStatsHistory mBatteryStatsHistory; 786 787 final HistoryItem mHistoryCur = new HistoryItem(); 788 789 HistoryItem mHistory; 790 HistoryItem mHistoryEnd; 791 HistoryItem mHistoryLastEnd; 792 HistoryItem mHistoryCache; 793 794 // Used by computeHistoryStepDetails 795 HistoryStepDetails mLastHistoryStepDetails = null; 796 byte mLastHistoryStepLevel = 0; 797 final HistoryStepDetails mCurHistoryStepDetails = new HistoryStepDetails(); 798 final HistoryStepDetails mReadHistoryStepDetails = new HistoryStepDetails(); 799 final HistoryStepDetails mTmpHistoryStepDetails = new HistoryStepDetails(); 800 801 /** 802 * Total time (in milliseconds) spent executing in user code. 803 */ 804 long mLastStepCpuUserTimeMs; 805 long mCurStepCpuUserTimeMs; 806 /** 807 * Total time (in milliseconds) spent executing in kernel code. 808 */ 809 long mLastStepCpuSystemTimeMs; 810 long mCurStepCpuSystemTimeMs; 811 /** 812 * Times from /proc/stat (but measured in milliseconds). 813 */ 814 long mLastStepStatUserTimeMs; 815 long mLastStepStatSystemTimeMs; 816 long mLastStepStatIOWaitTimeMs; 817 long mLastStepStatIrqTimeMs; 818 long mLastStepStatSoftIrqTimeMs; 819 long mLastStepStatIdleTimeMs; 820 long mCurStepStatUserTimeMs; 821 long mCurStepStatSystemTimeMs; 822 long mCurStepStatIOWaitTimeMs; 823 long mCurStepStatIrqTimeMs; 824 long mCurStepStatSoftIrqTimeMs; 825 long mCurStepStatIdleTimeMs; 826 827 private BatteryStatsHistoryIterator mBatteryStatsHistoryIterator; 828 private HistoryItem mHistoryIterator; 829 private boolean mReadOverflow; 830 831 int mStartCount; 832 833 /** 834 * Set to true when a reset occurs, informing us that the next time BatteryExternalStatsWorker 835 * gives us data, we mustn't process it since this data includes pre-reset-period data. 836 */ 837 @GuardedBy("this") 838 boolean mIgnoreNextExternalStats = false; 839 840 long mStartClockTimeMs; 841 String mStartPlatformVersion; 842 String mEndPlatformVersion; 843 844 long mUptimeUs; 845 long mUptimeStartUs; 846 long mRealtimeUs; 847 long mRealtimeStartUs; 848 849 int mWakeLockNesting; 850 boolean mWakeLockImportant; 851 public boolean mRecordAllHistory; 852 boolean mNoAutoReset; 853 854 /** 855 * Overall screen state. For multidisplay devices, this represents the current highest screen 856 * state of the displays. 857 */ 858 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) 859 protected int mScreenState = Display.STATE_UNKNOWN; 860 /** 861 * Overall screen on timer. For multidisplay devices, this represents the time spent with at 862 * least one display in the screen on state. 863 */ 864 StopwatchTimer mScreenOnTimer; 865 /** 866 * Overall screen doze timer. For multidisplay devices, this represents the time spent with 867 * screen doze being the highest screen state. 868 */ 869 StopwatchTimer mScreenDozeTimer; 870 /** 871 * Overall screen brightness bin. For multidisplay devices, this represents the current 872 * brightest screen. 873 */ 874 int mScreenBrightnessBin = -1; 875 /** 876 * Overall screen brightness timers. For multidisplay devices, the {@link mScreenBrightnessBin} 877 * timer will be active at any given time 878 */ 879 final StopwatchTimer[] mScreenBrightnessTimer = 880 new StopwatchTimer[NUM_SCREEN_BRIGHTNESS_BINS]; 881 882 boolean mPretendScreenOff; 883 884 private static class DisplayBatteryStats { 885 /** 886 * Per display screen state. 887 */ 888 public int screenState = Display.STATE_UNKNOWN; 889 /** 890 * Per display screen on timers. 891 */ 892 public StopwatchTimer screenOnTimer; 893 /** 894 * Per display screen doze timers. 895 */ 896 public StopwatchTimer screenDozeTimer; 897 /** 898 * Per display screen brightness bins. 899 */ 900 public int screenBrightnessBin = -1; 901 /** 902 * Per display screen brightness timers. 903 */ 904 public StopwatchTimer[] screenBrightnessTimers = 905 new StopwatchTimer[NUM_SCREEN_BRIGHTNESS_BINS]; 906 /** 907 * Per display screen state the last time {@link #updateDisplayMeasuredEnergyStatsLocked} 908 * was called. 909 */ 910 public int screenStateAtLastEnergyMeasurement = Display.STATE_UNKNOWN; 911 DisplayBatteryStats(Clocks clocks, TimeBase timeBase)912 DisplayBatteryStats(Clocks clocks, TimeBase timeBase) { 913 screenOnTimer = new StopwatchTimer(clocks, null, -1, null, 914 timeBase); 915 screenDozeTimer = new StopwatchTimer(clocks, null, -1, null, 916 timeBase); 917 for (int i = 0; i < NUM_SCREEN_BRIGHTNESS_BINS; i++) { 918 screenBrightnessTimers[i] = new StopwatchTimer(clocks, null, -100 - i, null, 919 timeBase); 920 } 921 } 922 923 /** 924 * Reset display timers. 925 */ reset(long elapsedRealtimeUs)926 public void reset(long elapsedRealtimeUs) { 927 screenOnTimer.reset(false, elapsedRealtimeUs); 928 screenDozeTimer.reset(false, elapsedRealtimeUs); 929 for (int i = 0; i < NUM_SCREEN_BRIGHTNESS_BINS; i++) { 930 screenBrightnessTimers[i].reset(false, elapsedRealtimeUs); 931 } 932 } 933 } 934 935 DisplayBatteryStats[] mPerDisplayBatteryStats; 936 937 private int mDisplayMismatchWtfCount = 0; 938 939 boolean mInteractive; 940 StopwatchTimer mInteractiveTimer; 941 942 boolean mPowerSaveModeEnabled; 943 StopwatchTimer mPowerSaveModeEnabledTimer; 944 945 boolean mDeviceIdling; 946 StopwatchTimer mDeviceIdlingTimer; 947 948 boolean mDeviceLightIdling; 949 StopwatchTimer mDeviceLightIdlingTimer; 950 951 int mDeviceIdleMode; 952 long mLastIdleTimeStartMs; 953 long mLongestLightIdleTimeMs; 954 long mLongestFullIdleTimeMs; 955 StopwatchTimer mDeviceIdleModeLightTimer; 956 StopwatchTimer mDeviceIdleModeFullTimer; 957 958 boolean mPhoneOn; 959 StopwatchTimer mPhoneOnTimer; 960 961 int mAudioOnNesting; 962 StopwatchTimer mAudioOnTimer; 963 964 int mVideoOnNesting; 965 StopwatchTimer mVideoOnTimer; 966 967 int mFlashlightOnNesting; 968 StopwatchTimer mFlashlightOnTimer; 969 970 int mCameraOnNesting; 971 StopwatchTimer mCameraOnTimer; 972 973 private static final int USB_DATA_UNKNOWN = 0; 974 private static final int USB_DATA_DISCONNECTED = 1; 975 private static final int USB_DATA_CONNECTED = 2; 976 int mUsbDataState = USB_DATA_UNKNOWN; 977 978 int mGpsSignalQualityBin = -1; 979 final StopwatchTimer[] mGpsSignalQualityTimer = 980 new StopwatchTimer[GnssSignalQuality.NUM_GNSS_SIGNAL_QUALITY_LEVELS]; 981 982 int mPhoneSignalStrengthBin = -1; 983 int mPhoneSignalStrengthBinRaw = -1; 984 final StopwatchTimer[] mPhoneSignalStrengthsTimer = 985 new StopwatchTimer[CellSignalStrength.getNumSignalStrengthLevels()]; 986 987 StopwatchTimer mPhoneSignalScanningTimer; 988 989 int mPhoneDataConnectionType = -1; 990 final StopwatchTimer[] mPhoneDataConnectionsTimer = 991 new StopwatchTimer[NUM_DATA_CONNECTION_TYPES]; 992 993 final LongSamplingCounter[] mNetworkByteActivityCounters = 994 new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES]; 995 996 final LongSamplingCounter[] mNetworkPacketActivityCounters = 997 new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES]; 998 999 /** 1000 * The WiFi Overall wakelock timer 1001 * This timer tracks the actual aggregate time for which MC wakelocks are enabled 1002 * since addition of per UID timers would not result in an accurate value due to overlapp of 1003 * per uid wakelock timers 1004 */ 1005 StopwatchTimer mWifiMulticastWakelockTimer; 1006 1007 /** 1008 * The WiFi controller activity (time in tx, rx, idle, and power consumed) for the device. 1009 */ 1010 ControllerActivityCounterImpl mWifiActivity; 1011 1012 /** 1013 * The Bluetooth controller activity (time in tx, rx, idle, and power consumed) for the device. 1014 */ 1015 ControllerActivityCounterImpl mBluetoothActivity; 1016 1017 /** 1018 * The Modem controller activity (time in tx, rx, idle, and power consumed) for the device. 1019 */ 1020 ControllerActivityCounterImpl mModemActivity; 1021 1022 /** 1023 * Whether the device supports WiFi controller energy reporting. This is set to true on 1024 * the first WiFi energy report. See {@link #mWifiActivity}. 1025 */ 1026 boolean mHasWifiReporting = false; 1027 1028 /** 1029 * Whether the device supports Bluetooth controller energy reporting. This is set to true on 1030 * the first Bluetooth energy report. See {@link #mBluetoothActivity}. 1031 */ 1032 boolean mHasBluetoothReporting = false; 1033 1034 /** 1035 * Whether the device supports Modem controller energy reporting. This is set to true on 1036 * the first Modem energy report. See {@link #mModemActivity}. 1037 */ 1038 boolean mHasModemReporting = false; 1039 1040 boolean mWifiOn; 1041 StopwatchTimer mWifiOnTimer; 1042 1043 boolean mGlobalWifiRunning; 1044 StopwatchTimer mGlobalWifiRunningTimer; 1045 1046 int mWifiState = -1; 1047 final StopwatchTimer[] mWifiStateTimer = new StopwatchTimer[NUM_WIFI_STATES]; 1048 1049 int mWifiSupplState = -1; 1050 final StopwatchTimer[] mWifiSupplStateTimer = new StopwatchTimer[NUM_WIFI_SUPPL_STATES]; 1051 1052 int mWifiSignalStrengthBin = -1; 1053 final StopwatchTimer[] mWifiSignalStrengthsTimer = 1054 new StopwatchTimer[NUM_WIFI_SIGNAL_STRENGTH_BINS]; 1055 1056 StopwatchTimer mWifiActiveTimer; 1057 1058 int mBluetoothScanNesting; 1059 StopwatchTimer mBluetoothScanTimer; 1060 1061 int mMobileRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW; 1062 long mMobileRadioActiveStartTimeMs; 1063 StopwatchTimer mMobileRadioActiveTimer; 1064 StopwatchTimer mMobileRadioActivePerAppTimer; 1065 LongSamplingCounter mMobileRadioActiveAdjustedTime; 1066 LongSamplingCounter mMobileRadioActiveUnknownTime; 1067 LongSamplingCounter mMobileRadioActiveUnknownCount; 1068 1069 int mWifiRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW; 1070 1071 /** 1072 * Accumulated global (generally, device-wide total) charge consumption of various consumers 1073 * while on battery. 1074 * Its '<b>custom</b> power buckets' correspond to the 1075 * {@link android.hardware.power.stats.EnergyConsumer.ordinal}s of (custom) energy consumer 1076 * type {@link android.hardware.power.stats.EnergyConsumerType#OTHER}). 1077 * 1078 * If energy consumer data is completely unavailable this will be null. 1079 */ 1080 @GuardedBy("this") 1081 @VisibleForTesting 1082 protected @Nullable MeasuredEnergyStats mGlobalMeasuredEnergyStats; 1083 /** Bluetooth Power calculator for attributing measured bluetooth charge consumption to uids */ 1084 @Nullable BluetoothPowerCalculator mBluetoothPowerCalculator = null; 1085 /** Cpu Power calculator for attributing measured cpu charge consumption to uids */ 1086 @Nullable CpuPowerCalculator mCpuPowerCalculator = null; 1087 /** Mobile Radio Power calculator for attributing measured radio charge consumption to uids */ 1088 @Nullable 1089 MobileRadioPowerCalculator mMobileRadioPowerCalculator = null; 1090 /** Wifi Power calculator for attributing measured wifi charge consumption to uids */ 1091 @Nullable WifiPowerCalculator mWifiPowerCalculator = null; 1092 1093 /** 1094 * These provide time bases that discount the time the device is plugged 1095 * in to power. 1096 */ 1097 boolean mOnBattery; 1098 @VisibleForTesting 1099 protected boolean mOnBatteryInternal; 1100 1101 /** 1102 * External reporting of whether the device is actually charging. 1103 */ 1104 boolean mCharging = true; 1105 int mLastChargingStateLevel; 1106 1107 /* 1108 * These keep track of battery levels (1-100) at the last plug event and the last unplug event. 1109 */ 1110 int mDischargeStartLevel; 1111 int mDischargeUnplugLevel; 1112 int mDischargePlugLevel; 1113 int mDischargeCurrentLevel; 1114 int mCurrentBatteryLevel; 1115 int mLowDischargeAmountSinceCharge; 1116 int mHighDischargeAmountSinceCharge; 1117 int mDischargeScreenOnUnplugLevel; 1118 int mDischargeScreenOffUnplugLevel; 1119 int mDischargeScreenDozeUnplugLevel; 1120 int mDischargeAmountScreenOn; 1121 int mDischargeAmountScreenOnSinceCharge; 1122 int mDischargeAmountScreenOff; 1123 int mDischargeAmountScreenOffSinceCharge; 1124 int mDischargeAmountScreenDoze; 1125 int mDischargeAmountScreenDozeSinceCharge; 1126 1127 private LongSamplingCounter mDischargeScreenOffCounter; 1128 private LongSamplingCounter mDischargeScreenDozeCounter; 1129 private LongSamplingCounter mDischargeCounter; 1130 private LongSamplingCounter mDischargeLightDozeCounter; 1131 private LongSamplingCounter mDischargeDeepDozeCounter; 1132 1133 static final int MAX_LEVEL_STEPS = 200; 1134 1135 int mInitStepMode = 0; 1136 int mCurStepMode = 0; 1137 int mModStepMode = 0; 1138 1139 int mLastDischargeStepLevel; 1140 int mMinDischargeStepLevel; 1141 final LevelStepTracker mDischargeStepTracker = new LevelStepTracker(MAX_LEVEL_STEPS); 1142 final LevelStepTracker mDailyDischargeStepTracker = new LevelStepTracker(MAX_LEVEL_STEPS*2); 1143 ArrayList<PackageChange> mDailyPackageChanges; 1144 1145 int mLastChargeStepLevel; 1146 int mMaxChargeStepLevel; 1147 final LevelStepTracker mChargeStepTracker = new LevelStepTracker(MAX_LEVEL_STEPS); 1148 final LevelStepTracker mDailyChargeStepTracker = new LevelStepTracker(MAX_LEVEL_STEPS*2); 1149 1150 static final int MAX_DAILY_ITEMS = 10; 1151 1152 long mDailyStartTimeMs = 0; 1153 long mNextMinDailyDeadlineMs = 0; 1154 long mNextMaxDailyDeadlineMs = 0; 1155 1156 final ArrayList<DailyItem> mDailyItems = new ArrayList<>(); 1157 1158 long mLastWriteTimeMs = 0; // Milliseconds 1159 1160 private int mPhoneServiceState = -1; 1161 private int mPhoneServiceStateRaw = -1; 1162 private int mPhoneSimStateRaw = -1; 1163 1164 private int mNumConnectivityChange; 1165 1166 private int mBatteryVoltageMv = -1; 1167 private int mEstimatedBatteryCapacityMah = -1; 1168 1169 private int mLastLearnedBatteryCapacityUah = -1; 1170 private int mMinLearnedBatteryCapacityUah = -1; 1171 private int mMaxLearnedBatteryCapacityUah = -1; 1172 1173 private long mBatteryTimeToFullSeconds = -1; 1174 1175 private long[] mCpuFreqs; 1176 1177 /** 1178 * Times spent by the system server threads handling incoming binder requests. 1179 */ 1180 private LongSamplingCounterArray mBinderThreadCpuTimesUs; 1181 1182 @VisibleForTesting 1183 protected PowerProfile mPowerProfile; 1184 1185 @VisibleForTesting 1186 @GuardedBy("this") 1187 protected final Constants mConstants; 1188 1189 /* 1190 * Holds a SamplingTimer associated with each Resource Power Manager state and voter, 1191 * recording their times when on-battery (regardless of screen state). 1192 */ 1193 private final HashMap<String, SamplingTimer> mRpmStats = new HashMap<>(); 1194 /** Times for each Resource Power Manager state and voter when screen-off and on-battery. */ 1195 private final HashMap<String, SamplingTimer> mScreenOffRpmStats = new HashMap<>(); 1196 1197 @Override getRpmStats()1198 public Map<String, ? extends Timer> getRpmStats() { 1199 return mRpmStats; 1200 } 1201 1202 // TODO: Note: screenOffRpmStats has been disabled via SCREEN_OFF_RPM_STATS_ENABLED. 1203 @Override getScreenOffRpmStats()1204 public Map<String, ? extends Timer> getScreenOffRpmStats() { 1205 return mScreenOffRpmStats; 1206 } 1207 1208 /* 1209 * Holds a SamplingTimer associated with each kernel wakelock name being tracked. 1210 */ 1211 private final HashMap<String, SamplingTimer> mKernelWakelockStats = new HashMap<>(); 1212 1213 @UnsupportedAppUsage getKernelWakelockStats()1214 public Map<String, ? extends Timer> getKernelWakelockStats() { 1215 return mKernelWakelockStats; 1216 } 1217 1218 String mLastWakeupReason = null; 1219 long mLastWakeupUptimeMs = 0; 1220 private final HashMap<String, SamplingTimer> mWakeupReasonStats = new HashMap<>(); 1221 getWakeupReasonStats()1222 public Map<String, ? extends Timer> getWakeupReasonStats() { 1223 return mWakeupReasonStats; 1224 } 1225 1226 @Override getUahDischarge(int which)1227 public long getUahDischarge(int which) { 1228 return mDischargeCounter.getCountLocked(which); 1229 } 1230 1231 @Override getUahDischargeScreenOff(int which)1232 public long getUahDischargeScreenOff(int which) { 1233 return mDischargeScreenOffCounter.getCountLocked(which); 1234 } 1235 1236 @Override getUahDischargeScreenDoze(int which)1237 public long getUahDischargeScreenDoze(int which) { 1238 return mDischargeScreenDozeCounter.getCountLocked(which); 1239 } 1240 1241 @Override getUahDischargeLightDoze(int which)1242 public long getUahDischargeLightDoze(int which) { 1243 return mDischargeLightDozeCounter.getCountLocked(which); 1244 } 1245 1246 @Override getUahDischargeDeepDoze(int which)1247 public long getUahDischargeDeepDoze(int which) { 1248 return mDischargeDeepDozeCounter.getCountLocked(which); 1249 } 1250 1251 @Override getEstimatedBatteryCapacity()1252 public int getEstimatedBatteryCapacity() { 1253 return mEstimatedBatteryCapacityMah; 1254 } 1255 1256 @Override getLearnedBatteryCapacity()1257 public int getLearnedBatteryCapacity() { 1258 return mLastLearnedBatteryCapacityUah; 1259 } 1260 1261 @Override getMinLearnedBatteryCapacity()1262 public int getMinLearnedBatteryCapacity() { 1263 return mMinLearnedBatteryCapacityUah; 1264 } 1265 1266 @Override getMaxLearnedBatteryCapacity()1267 public int getMaxLearnedBatteryCapacity() { 1268 return mMaxLearnedBatteryCapacityUah; 1269 } 1270 BatteryStatsImpl()1271 public BatteryStatsImpl() { 1272 this(new SystemClocks()); 1273 } 1274 BatteryStatsImpl(Clocks clocks)1275 public BatteryStatsImpl(Clocks clocks) { 1276 init(clocks); 1277 mStartClockTimeMs = clocks.currentTimeMillis(); 1278 mStatsFile = null; 1279 mCheckinFile = null; 1280 mDailyFile = null; 1281 mBatteryStatsHistory = new BatteryStatsHistory(mHistoryBuffer); 1282 mHandler = null; 1283 mPlatformIdleStateCallback = null; 1284 mMeasuredEnergyRetriever = null; 1285 mUserInfoProvider = null; 1286 mConstants = new Constants(mHandler); 1287 clearHistoryLocked(); 1288 } 1289 init(Clocks clocks)1290 private void init(Clocks clocks) { 1291 mClocks = clocks; 1292 } 1293 1294 /** 1295 * TimeBase observer. 1296 */ 1297 public interface TimeBaseObs { onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)1298 void onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs); onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)1299 void onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs); 1300 1301 /** 1302 * Reset the observer's state, returns true if the timer/counter is inactive 1303 * so it can be destroyed. 1304 * @param detachIfReset detach if true, no-op if false. 1305 * @return Returns true if the timer/counter is inactive and can be destroyed. 1306 */ reset(boolean detachIfReset)1307 default boolean reset(boolean detachIfReset) { 1308 return reset(detachIfReset, SystemClock.elapsedRealtime() * 1000); 1309 } 1310 1311 /** 1312 * @see #reset(boolean) 1313 * @param detachIfReset detach if true, no-op if false. 1314 * @param elapsedRealtimeUs the timestamp when this reset is actually reequested 1315 * @return Returns true if the timer/counter is inactive and can be destroyed. 1316 */ reset(boolean detachIfReset, long elapsedRealtimeUs)1317 boolean reset(boolean detachIfReset, long elapsedRealtimeUs); 1318 1319 /** 1320 * Detach the observer from TimeBase. 1321 */ detach()1322 void detach(); 1323 } 1324 1325 // methods are protected not private to be VisibleForTesting 1326 public static class TimeBase { 1327 protected final Collection<TimeBaseObs> mObservers; 1328 1329 // All below time metrics are in microseconds. 1330 protected long mUptimeUs; 1331 protected long mRealtimeUs; 1332 1333 protected boolean mRunning; 1334 1335 protected long mPastUptimeUs; 1336 protected long mUptimeStartUs; 1337 protected long mPastRealtimeUs; 1338 protected long mRealtimeStartUs; 1339 protected long mUnpluggedUptimeUs; 1340 protected long mUnpluggedRealtimeUs; 1341 dump(PrintWriter pw, String prefix)1342 public void dump(PrintWriter pw, String prefix) { 1343 StringBuilder sb = new StringBuilder(128); 1344 pw.print(prefix); pw.print("mRunning="); pw.println(mRunning); 1345 sb.setLength(0); 1346 sb.append(prefix); 1347 sb.append("mUptime="); 1348 formatTimeMs(sb, mUptimeUs / 1000); 1349 pw.println(sb.toString()); 1350 sb.setLength(0); 1351 sb.append(prefix); 1352 sb.append("mRealtime="); 1353 formatTimeMs(sb, mRealtimeUs / 1000); 1354 pw.println(sb.toString()); 1355 sb.setLength(0); 1356 sb.append(prefix); 1357 sb.append("mPastUptime="); 1358 formatTimeMs(sb, mPastUptimeUs / 1000); sb.append("mUptimeStart="); 1359 formatTimeMs(sb, mUptimeStartUs / 1000); 1360 sb.append("mUnpluggedUptime="); formatTimeMs(sb, mUnpluggedUptimeUs / 1000); 1361 pw.println(sb.toString()); 1362 sb.setLength(0); 1363 sb.append(prefix); 1364 sb.append("mPastRealtime="); 1365 formatTimeMs(sb, mPastRealtimeUs / 1000); sb.append("mRealtimeStart="); 1366 formatTimeMs(sb, mRealtimeStartUs / 1000); 1367 sb.append("mUnpluggedRealtime="); formatTimeMs(sb, mUnpluggedRealtimeUs / 1000); 1368 pw.println(sb.toString()); 1369 } 1370 /** 1371 * The mObservers of TimeBase in BatteryStatsImpl object can contain up to 20k entries. 1372 * The mObservers of TimeBase in BatteryStatsImpl.Uid object only contains a few or tens of 1373 * entries. 1374 * mObservers must have good performance on add(), remove(), also be memory efficient. 1375 * This is why we provide isLongList parameter for long and short list user cases. 1376 * @param isLongList If true, use HashSet for mObservers list. 1377 * If false, use ArrayList for mObservers list. 1378 */ TimeBase(boolean isLongList)1379 public TimeBase(boolean isLongList) { 1380 mObservers = isLongList ? new HashSet<>() : new ArrayList<>(); 1381 } 1382 TimeBase()1383 public TimeBase() { 1384 this(false); 1385 } 1386 add(TimeBaseObs observer)1387 public void add(TimeBaseObs observer) { 1388 mObservers.add(observer); 1389 } 1390 remove(TimeBaseObs observer)1391 public void remove(TimeBaseObs observer) { 1392 mObservers.remove(observer); 1393 } 1394 hasObserver(TimeBaseObs observer)1395 public boolean hasObserver(TimeBaseObs observer) { 1396 return mObservers.contains(observer); 1397 } 1398 init(long uptimeUs, long elapsedRealtimeUs)1399 public void init(long uptimeUs, long elapsedRealtimeUs) { 1400 mRealtimeUs = 0; 1401 mUptimeUs = 0; 1402 mPastUptimeUs = 0; 1403 mPastRealtimeUs = 0; 1404 mUptimeStartUs = uptimeUs; 1405 mRealtimeStartUs = elapsedRealtimeUs; 1406 mUnpluggedUptimeUs = getUptime(mUptimeStartUs); 1407 mUnpluggedRealtimeUs = getRealtime(mRealtimeStartUs); 1408 } 1409 reset(long uptimeUs, long elapsedRealtimeUs)1410 public void reset(long uptimeUs, long elapsedRealtimeUs) { 1411 if (!mRunning) { 1412 mPastUptimeUs = 0; 1413 mPastRealtimeUs = 0; 1414 } else { 1415 mUptimeStartUs = uptimeUs; 1416 mRealtimeStartUs = elapsedRealtimeUs; 1417 // TODO: Since mUptimeStartUs was just reset and we are running, getUptime will 1418 // just return mPastUptimeUs. Also, are we sure we don't want to reset that? 1419 mUnpluggedUptimeUs = getUptime(uptimeUs); 1420 // TODO: likewise. 1421 mUnpluggedRealtimeUs = getRealtime(elapsedRealtimeUs); 1422 } 1423 } 1424 computeUptime(long curTimeUs, int which)1425 public long computeUptime(long curTimeUs, int which) { 1426 return mUptimeUs + getUptime(curTimeUs); 1427 } 1428 computeRealtime(long curTimeUs, int which)1429 public long computeRealtime(long curTimeUs, int which) { 1430 return mRealtimeUs + getRealtime(curTimeUs); 1431 } 1432 getUptime(long curTimeUs)1433 public long getUptime(long curTimeUs) { 1434 long time = mPastUptimeUs; 1435 if (mRunning) { 1436 time += curTimeUs - mUptimeStartUs; 1437 } 1438 return time; 1439 } 1440 getRealtime(long curTimeUs)1441 public long getRealtime(long curTimeUs) { 1442 long time = mPastRealtimeUs; 1443 if (mRunning) { 1444 time += curTimeUs - mRealtimeStartUs; 1445 } 1446 return time; 1447 } 1448 getUptimeStart()1449 public long getUptimeStart() { 1450 return mUptimeStartUs; 1451 } 1452 getRealtimeStart()1453 public long getRealtimeStart() { 1454 return mRealtimeStartUs; 1455 } 1456 isRunning()1457 public boolean isRunning() { 1458 return mRunning; 1459 } 1460 setRunning(boolean running, long uptimeUs, long elapsedRealtimeUs)1461 public boolean setRunning(boolean running, long uptimeUs, long elapsedRealtimeUs) { 1462 if (mRunning != running) { 1463 mRunning = running; 1464 if (running) { 1465 mUptimeStartUs = uptimeUs; 1466 mRealtimeStartUs = elapsedRealtimeUs; 1467 long batteryUptimeUs = mUnpluggedUptimeUs = getUptime(uptimeUs); 1468 long batteryRealtimeUs = mUnpluggedRealtimeUs = getRealtime(elapsedRealtimeUs); 1469 // Normally we do not use Iterator in framework code to avoid alloc/dealloc 1470 // Iterator object, here is an exception because mObservers' type is Collection 1471 // instead of list. 1472 final Iterator<TimeBaseObs> iter = mObservers.iterator(); 1473 while (iter.hasNext()) { 1474 iter.next().onTimeStarted( 1475 elapsedRealtimeUs, batteryUptimeUs, batteryRealtimeUs); 1476 } 1477 } else { 1478 mPastUptimeUs += uptimeUs - mUptimeStartUs; 1479 mPastRealtimeUs += elapsedRealtimeUs - mRealtimeStartUs; 1480 long batteryUptimeUs = getUptime(uptimeUs); 1481 long batteryRealtimeUs = getRealtime(elapsedRealtimeUs); 1482 // Normally we do not use Iterator in framework code to avoid alloc/dealloc 1483 // Iterator object, here is an exception because mObservers' type is Collection 1484 // instead of list. 1485 final Iterator<TimeBaseObs> iter = mObservers.iterator(); 1486 while (iter.hasNext()) { 1487 iter.next().onTimeStopped( 1488 elapsedRealtimeUs, batteryUptimeUs, batteryRealtimeUs); 1489 } 1490 } 1491 return true; 1492 } 1493 return false; 1494 } 1495 readSummaryFromParcel(Parcel in)1496 public void readSummaryFromParcel(Parcel in) { 1497 mUptimeUs = in.readLong(); 1498 mRealtimeUs = in.readLong(); 1499 } 1500 writeSummaryToParcel(Parcel out, long uptimeUs, long elapsedRealtimeUs)1501 public void writeSummaryToParcel(Parcel out, long uptimeUs, long elapsedRealtimeUs) { 1502 out.writeLong(computeUptime(uptimeUs, STATS_SINCE_CHARGED)); 1503 out.writeLong(computeRealtime(elapsedRealtimeUs, STATS_SINCE_CHARGED)); 1504 } 1505 readFromParcel(Parcel in)1506 public void readFromParcel(Parcel in) { 1507 mRunning = false; 1508 mUptimeUs = in.readLong(); 1509 mPastUptimeUs = in.readLong(); 1510 mUptimeStartUs = in.readLong(); 1511 mRealtimeUs = in.readLong(); 1512 mPastRealtimeUs = in.readLong(); 1513 mRealtimeStartUs = in.readLong(); 1514 mUnpluggedUptimeUs = in.readLong(); 1515 mUnpluggedRealtimeUs = in.readLong(); 1516 } 1517 writeToParcel(Parcel out, long uptimeUs, long elapsedRealtimeUs)1518 public void writeToParcel(Parcel out, long uptimeUs, long elapsedRealtimeUs) { 1519 final long runningUptime = getUptime(uptimeUs); 1520 final long runningRealtime = getRealtime(elapsedRealtimeUs); 1521 out.writeLong(mUptimeUs); 1522 out.writeLong(runningUptime); 1523 out.writeLong(mUptimeStartUs); 1524 out.writeLong(mRealtimeUs); 1525 out.writeLong(runningRealtime); 1526 out.writeLong(mRealtimeStartUs); 1527 out.writeLong(mUnpluggedUptimeUs); 1528 out.writeLong(mUnpluggedRealtimeUs); 1529 } 1530 } 1531 1532 /** 1533 * State for keeping track of counting information. 1534 */ 1535 public static class Counter extends BatteryStats.Counter implements TimeBaseObs { 1536 @UnsupportedAppUsage 1537 final AtomicInteger mCount = new AtomicInteger(); 1538 final TimeBase mTimeBase; 1539 Counter(TimeBase timeBase, Parcel in)1540 public Counter(TimeBase timeBase, Parcel in) { 1541 mTimeBase = timeBase; 1542 mCount.set(in.readInt()); 1543 timeBase.add(this); 1544 } 1545 Counter(TimeBase timeBase)1546 public Counter(TimeBase timeBase) { 1547 mTimeBase = timeBase; 1548 timeBase.add(this); 1549 } 1550 writeToParcel(Parcel out)1551 public void writeToParcel(Parcel out) { 1552 out.writeInt(mCount.get()); 1553 } 1554 1555 @Override onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)1556 public void onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { 1557 } 1558 1559 @Override onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)1560 public void onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { 1561 } 1562 1563 /** 1564 * Writes a possibly null Counter to a Parcel. 1565 * 1566 * @param out the Parcel to be written to. 1567 * @param counter a Counter, or null. 1568 */ writeCounterToParcel(Parcel out, @Nullable Counter counter)1569 public static void writeCounterToParcel(Parcel out, @Nullable Counter counter) { 1570 if (counter == null) { 1571 out.writeInt(0); // indicates null 1572 return; 1573 } 1574 out.writeInt(1); // indicates non-null 1575 1576 counter.writeToParcel(out); 1577 } 1578 1579 /** 1580 * Reads a Counter that was written using {@link #writeCounterToParcel(Parcel, Counter)}. 1581 * @param timeBase the timebase to assign to the Counter 1582 * @param in the parcel to read from 1583 * @return the Counter or null. 1584 */ 1585 @Nullable readCounterFromParcel(TimeBase timeBase, Parcel in)1586 public static Counter readCounterFromParcel(TimeBase timeBase, Parcel in) { 1587 if (in.readInt() == 0) { 1588 return null; 1589 } 1590 return new Counter(timeBase, in); 1591 } 1592 1593 @Override getCountLocked(int which)1594 public int getCountLocked(int which) { 1595 return mCount.get(); 1596 } 1597 logState(Printer pw, String prefix)1598 public void logState(Printer pw, String prefix) { 1599 pw.println(prefix + "mCount=" + mCount.get()); 1600 } 1601 1602 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) stepAtomic()1603 public void stepAtomic() { 1604 if (mTimeBase.isRunning()) { 1605 mCount.incrementAndGet(); 1606 } 1607 } 1608 addAtomic(int delta)1609 void addAtomic(int delta) { 1610 if (mTimeBase.isRunning()) { 1611 mCount.addAndGet(delta); 1612 } 1613 } 1614 1615 /** 1616 * Clear state of this counter. 1617 */ 1618 @Override reset(boolean detachIfReset, long elapsedRealtimeUs )1619 public boolean reset(boolean detachIfReset, long elapsedRealtimeUs /* unused */) { 1620 mCount.set(0); 1621 if (detachIfReset) { 1622 detach(); 1623 } 1624 return true; 1625 } 1626 1627 @Override detach()1628 public void detach() { 1629 mTimeBase.remove(this); 1630 } 1631 1632 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) writeSummaryFromParcelLocked(Parcel out)1633 public void writeSummaryFromParcelLocked(Parcel out) { 1634 out.writeInt(mCount.get()); 1635 } 1636 1637 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) readSummaryFromParcelLocked(Parcel in)1638 public void readSummaryFromParcelLocked(Parcel in) { 1639 mCount.set(in.readInt()); 1640 } 1641 } 1642 1643 @VisibleForTesting 1644 public static class LongSamplingCounterArray extends LongCounterArray implements TimeBaseObs { 1645 final TimeBase mTimeBase; 1646 public long[] mCounts; 1647 LongSamplingCounterArray(TimeBase timeBase, Parcel in)1648 private LongSamplingCounterArray(TimeBase timeBase, Parcel in) { 1649 mTimeBase = timeBase; 1650 mCounts = in.createLongArray(); 1651 timeBase.add(this); 1652 } 1653 LongSamplingCounterArray(TimeBase timeBase)1654 public LongSamplingCounterArray(TimeBase timeBase) { 1655 mTimeBase = timeBase; 1656 timeBase.add(this); 1657 } 1658 writeToParcel(Parcel out)1659 private void writeToParcel(Parcel out) { 1660 out.writeLongArray(mCounts); 1661 } 1662 1663 @Override onTimeStarted(long elapsedRealTimeUs, long baseUptimeUs, long baseRealtimeUs)1664 public void onTimeStarted(long elapsedRealTimeUs, long baseUptimeUs, long baseRealtimeUs) { 1665 } 1666 1667 @Override onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)1668 public void onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { 1669 } 1670 1671 @Override getCountsLocked(int which)1672 public long[] getCountsLocked(int which) { 1673 return mCounts == null ? null : Arrays.copyOf(mCounts, mCounts.length); 1674 } 1675 1676 @Override logState(Printer pw, String prefix)1677 public void logState(Printer pw, String prefix) { 1678 pw.println(prefix + "mCounts=" + Arrays.toString(mCounts)); 1679 } 1680 addCountLocked(long[] counts)1681 public void addCountLocked(long[] counts) { 1682 addCountLocked(counts, mTimeBase.isRunning()); 1683 } 1684 addCountLocked(long[] counts, boolean isRunning)1685 public void addCountLocked(long[] counts, boolean isRunning) { 1686 if (counts == null) { 1687 return; 1688 } 1689 if (isRunning) { 1690 if (mCounts == null) { 1691 mCounts = new long[counts.length]; 1692 } 1693 for (int i = 0; i < counts.length; ++i) { 1694 mCounts[i] += counts[i]; 1695 } 1696 } 1697 } 1698 getSize()1699 public int getSize() { 1700 return mCounts == null ? 0 : mCounts.length; 1701 } 1702 1703 /** 1704 * Clear state of this counter. 1705 */ 1706 @Override reset(boolean detachIfReset, long elapsedRealtimeUs )1707 public boolean reset(boolean detachIfReset, long elapsedRealtimeUs /* unused */) { 1708 if (mCounts != null) { 1709 Arrays.fill(mCounts, 0); 1710 } 1711 if (detachIfReset) { 1712 detach(); 1713 } 1714 return true; 1715 } 1716 1717 @Override detach()1718 public void detach() { 1719 mTimeBase.remove(this); 1720 } 1721 writeSummaryToParcelLocked(Parcel out)1722 private void writeSummaryToParcelLocked(Parcel out) { 1723 out.writeLongArray(mCounts); 1724 } 1725 readSummaryFromParcelLocked(Parcel in)1726 private void readSummaryFromParcelLocked(Parcel in) { 1727 mCounts = in.createLongArray(); 1728 } 1729 writeToParcel(Parcel out, LongSamplingCounterArray counterArray)1730 public static void writeToParcel(Parcel out, LongSamplingCounterArray counterArray) { 1731 if (counterArray != null) { 1732 out.writeInt(1); 1733 counterArray.writeToParcel(out); 1734 } else { 1735 out.writeInt(0); 1736 } 1737 } 1738 readFromParcel(Parcel in, TimeBase timeBase)1739 public static LongSamplingCounterArray readFromParcel(Parcel in, TimeBase timeBase) { 1740 if (in.readInt() != 0) { 1741 return new LongSamplingCounterArray(timeBase, in); 1742 } else { 1743 return null; 1744 } 1745 } 1746 writeSummaryToParcelLocked(Parcel out, LongSamplingCounterArray counterArray)1747 public static void writeSummaryToParcelLocked(Parcel out, 1748 LongSamplingCounterArray counterArray) { 1749 if (counterArray != null) { 1750 out.writeInt(1); 1751 counterArray.writeSummaryToParcelLocked(out); 1752 } else { 1753 out.writeInt(0); 1754 } 1755 } 1756 readSummaryFromParcelLocked(Parcel in, TimeBase timeBase)1757 public static LongSamplingCounterArray readSummaryFromParcelLocked(Parcel in, 1758 TimeBase timeBase) { 1759 if (in.readInt() != 0) { 1760 final LongSamplingCounterArray counterArray 1761 = new LongSamplingCounterArray(timeBase); 1762 counterArray.readSummaryFromParcelLocked(in); 1763 return counterArray; 1764 } else { 1765 return null; 1766 } 1767 } 1768 } 1769 1770 @VisibleForTesting 1771 public static class LongSamplingCounter extends LongCounter implements TimeBaseObs { 1772 final TimeBase mTimeBase; 1773 private long mCount; 1774 LongSamplingCounter(TimeBase timeBase, Parcel in)1775 public LongSamplingCounter(TimeBase timeBase, Parcel in) { 1776 mTimeBase = timeBase; 1777 mCount = in.readLong(); 1778 timeBase.add(this); 1779 } 1780 LongSamplingCounter(TimeBase timeBase)1781 public LongSamplingCounter(TimeBase timeBase) { 1782 mTimeBase = timeBase; 1783 timeBase.add(this); 1784 } 1785 writeToParcel(Parcel out)1786 public void writeToParcel(Parcel out) { 1787 out.writeLong(mCount); 1788 } 1789 1790 @Override onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)1791 public void onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { 1792 } 1793 1794 @Override onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)1795 public void onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { 1796 } 1797 getCountLocked(int which)1798 public long getCountLocked(int which) { 1799 return mCount; 1800 } 1801 1802 @Override logState(Printer pw, String prefix)1803 public void logState(Printer pw, String prefix) { 1804 pw.println(prefix + "mCount=" + mCount); 1805 } 1806 addCountLocked(long count)1807 public void addCountLocked(long count) { 1808 addCountLocked(count, mTimeBase.isRunning()); 1809 } 1810 addCountLocked(long count, boolean isRunning)1811 public void addCountLocked(long count, boolean isRunning) { 1812 if (isRunning) { 1813 mCount += count; 1814 } 1815 } 1816 1817 /** 1818 * Clear state of this counter. 1819 */ 1820 @Override reset(boolean detachIfReset, long elapsedRealtimeUs )1821 public boolean reset(boolean detachIfReset, long elapsedRealtimeUs /* unused */) { 1822 mCount = 0; 1823 if (detachIfReset) { 1824 detach(); 1825 } 1826 return true; 1827 } 1828 1829 @Override detach()1830 public void detach() { 1831 mTimeBase.remove(this); 1832 } 1833 writeSummaryFromParcelLocked(Parcel out)1834 public void writeSummaryFromParcelLocked(Parcel out) { 1835 out.writeLong(mCount); 1836 } 1837 readSummaryFromParcelLocked(Parcel in)1838 public void readSummaryFromParcelLocked(Parcel in) { 1839 mCount = in.readLong(); 1840 } 1841 } 1842 1843 /** 1844 * State for keeping track of timing information. 1845 */ 1846 public static abstract class Timer extends BatteryStats.Timer implements TimeBaseObs { 1847 protected final Clocks mClocks; 1848 protected final int mType; 1849 protected final TimeBase mTimeBase; 1850 1851 protected int mCount; 1852 1853 // Times are in microseconds for better accuracy when dividing by the 1854 // lock count, and are in "battery realtime" units. 1855 1856 /** 1857 * The total time we have accumulated since the start of the original 1858 * boot, to the last time something interesting happened in the 1859 * current run. 1860 */ 1861 protected long mTotalTimeUs; 1862 1863 /** 1864 * The total time this timer has been running until the latest mark has been set. 1865 * Subtract this from mTotalTimeUs to get the time spent running since the mark was set. 1866 */ 1867 protected long mTimeBeforeMarkUs; 1868 1869 /** 1870 * Constructs from a parcel. 1871 * @param type 1872 * @param timeBase 1873 * @param in 1874 */ Timer(Clocks clocks, int type, TimeBase timeBase, Parcel in)1875 public Timer(Clocks clocks, int type, TimeBase timeBase, Parcel in) { 1876 mClocks = clocks; 1877 mType = type; 1878 mTimeBase = timeBase; 1879 1880 mCount = in.readInt(); 1881 mTotalTimeUs = in.readLong(); 1882 mTimeBeforeMarkUs = in.readLong(); 1883 timeBase.add(this); 1884 if (DEBUG) Log.i(TAG, "**** READ TIMER #" + mType + ": mTotalTime=" + mTotalTimeUs); 1885 } 1886 Timer(Clocks clocks, int type, TimeBase timeBase)1887 public Timer(Clocks clocks, int type, TimeBase timeBase) { 1888 mClocks = clocks; 1889 mType = type; 1890 mTimeBase = timeBase; 1891 timeBase.add(this); 1892 } 1893 writeToParcel(Parcel out, long elapsedRealtimeUs)1894 public void writeToParcel(Parcel out, long elapsedRealtimeUs) { 1895 if (DEBUG) { 1896 Log.i(TAG, "**** WRITING TIMER #" + mType + ": mTotalTime=" 1897 + computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs), 1898 elapsedRealtimeUs)); 1899 } 1900 out.writeInt(computeCurrentCountLocked()); 1901 out.writeLong(computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs), 1902 elapsedRealtimeUs)); 1903 out.writeLong(mTimeBeforeMarkUs); 1904 } 1905 computeRunTimeLocked(long curBatteryRealtime, long elapsedRealtimeUs)1906 protected abstract long computeRunTimeLocked(long curBatteryRealtime, 1907 long elapsedRealtimeUs); 1908 computeCurrentCountLocked()1909 protected abstract int computeCurrentCountLocked(); 1910 1911 /** 1912 * Clear state of this timer. Returns true if the timer is inactive 1913 * so can be completely dropped. 1914 */ 1915 @Override reset(boolean detachIfReset)1916 public boolean reset(boolean detachIfReset) { 1917 return reset(detachIfReset, mClocks.elapsedRealtime() * 1000); 1918 } 1919 1920 @Override reset(boolean detachIfReset, long elapsedRealtimeUs )1921 public boolean reset(boolean detachIfReset, long elapsedRealtimeUs /* unused */) { 1922 mTotalTimeUs = mTimeBeforeMarkUs = 0; 1923 mCount = 0; 1924 if (detachIfReset) { 1925 detach(); 1926 } 1927 return true; 1928 } 1929 1930 @Override detach()1931 public void detach() { 1932 mTimeBase.remove(this); 1933 } 1934 1935 @Override onTimeStarted(long elapsedRealtimeUs, long timeBaseUptimeUs, long baseRealtimeUs)1936 public void onTimeStarted(long elapsedRealtimeUs, long timeBaseUptimeUs, 1937 long baseRealtimeUs) { 1938 } 1939 1940 @Override onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)1941 public void onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { 1942 if (DEBUG && mType < 0) { 1943 Log.v(TAG, "plug #" + mType + ": realtime=" + baseRealtimeUs 1944 + " old mTotalTime=" + mTotalTimeUs); 1945 } 1946 mTotalTimeUs = computeRunTimeLocked(baseRealtimeUs, elapsedRealtimeUs); 1947 mCount = computeCurrentCountLocked(); 1948 if (DEBUG && mType < 0) { 1949 Log.v(TAG, "plug #" + mType + ": new mTotalTime=" + mTotalTimeUs); 1950 } 1951 } 1952 1953 /** 1954 * Writes a possibly null Timer to a Parcel. 1955 * 1956 * @param out the Parcel to be written to. 1957 * @param timer a Timer, or null. 1958 */ 1959 @UnsupportedAppUsage writeTimerToParcel(Parcel out, Timer timer, long elapsedRealtimeUs)1960 public static void writeTimerToParcel(Parcel out, Timer timer, long elapsedRealtimeUs) { 1961 if (timer == null) { 1962 out.writeInt(0); // indicates null 1963 return; 1964 } 1965 out.writeInt(1); // indicates non-null 1966 timer.writeToParcel(out, elapsedRealtimeUs); 1967 } 1968 1969 @Override 1970 @UnsupportedAppUsage getTotalTimeLocked(long elapsedRealtimeUs, int which)1971 public long getTotalTimeLocked(long elapsedRealtimeUs, int which) { 1972 return computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs), 1973 elapsedRealtimeUs); 1974 } 1975 1976 @Override 1977 @UnsupportedAppUsage getCountLocked(int which)1978 public int getCountLocked(int which) { 1979 return computeCurrentCountLocked(); 1980 } 1981 1982 @Override getTimeSinceMarkLocked(long elapsedRealtimeUs)1983 public long getTimeSinceMarkLocked(long elapsedRealtimeUs) { 1984 long val = computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs), 1985 elapsedRealtimeUs); 1986 return val - mTimeBeforeMarkUs; 1987 } 1988 1989 @Override logState(Printer pw, String prefix)1990 public void logState(Printer pw, String prefix) { 1991 pw.println(prefix + "mCount=" + mCount); 1992 pw.println(prefix + "mTotalTime=" + mTotalTimeUs); 1993 } 1994 1995 writeSummaryFromParcelLocked(Parcel out, long elapsedRealtimeUs)1996 public void writeSummaryFromParcelLocked(Parcel out, long elapsedRealtimeUs) { 1997 long runTimeUs = computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs), 1998 elapsedRealtimeUs); 1999 out.writeLong(runTimeUs); 2000 out.writeInt(computeCurrentCountLocked()); 2001 } 2002 readSummaryFromParcelLocked(Parcel in)2003 public void readSummaryFromParcelLocked(Parcel in) { 2004 // Multiply by 1000 for backwards compatibility 2005 mTotalTimeUs = in.readLong(); 2006 mCount = in.readInt(); 2007 // When reading the summary, we set the mark to be the latest information. 2008 mTimeBeforeMarkUs = mTotalTimeUs; 2009 } 2010 } 2011 2012 /** 2013 * A counter meant to accept monotonically increasing values to its {@link #update(long, int)} 2014 * method. The state of the timer according to its {@link TimeBase} will determine how much 2015 * of the value is recorded. 2016 * 2017 * If the value being recorded resets, {@link #endSample()} can be called in order to 2018 * account for the change. If the value passed in to {@link #update(long, int)} decreased 2019 * between calls, the {@link #endSample()} is automatically called and the new value is 2020 * expected to increase monotonically from that point on. 2021 */ 2022 public static class SamplingTimer extends Timer { 2023 2024 /** 2025 * The most recent reported count from /proc/wakelocks. 2026 */ 2027 int mCurrentReportedCount; 2028 2029 /** 2030 * The reported count from /proc/wakelocks when unplug() was last 2031 * called. 2032 */ 2033 int mUnpluggedReportedCount; 2034 2035 /** 2036 * The most recent reported total_time from /proc/wakelocks. 2037 */ 2038 long mCurrentReportedTotalTimeUs; 2039 2040 2041 /** 2042 * The reported total_time from /proc/wakelocks when unplug() was last 2043 * called. 2044 */ 2045 long mUnpluggedReportedTotalTimeUs; 2046 2047 /** 2048 * Whether we are currently in a discharge cycle. 2049 */ 2050 boolean mTimeBaseRunning; 2051 2052 /** 2053 * Whether we are currently recording reported values. 2054 */ 2055 boolean mTrackingReportedValues; 2056 2057 /* 2058 * A sequence counter, incremented once for each update of the stats. 2059 */ 2060 int mUpdateVersion; 2061 2062 @VisibleForTesting SamplingTimer(Clocks clocks, TimeBase timeBase, Parcel in)2063 public SamplingTimer(Clocks clocks, TimeBase timeBase, Parcel in) { 2064 super(clocks, 0, timeBase, in); 2065 mCurrentReportedCount = in.readInt(); 2066 mUnpluggedReportedCount = in.readInt(); 2067 mCurrentReportedTotalTimeUs = in.readLong(); 2068 mUnpluggedReportedTotalTimeUs = in.readLong(); 2069 mTrackingReportedValues = in.readInt() == 1; 2070 mTimeBaseRunning = timeBase.isRunning(); 2071 } 2072 2073 @VisibleForTesting SamplingTimer(Clocks clocks, TimeBase timeBase)2074 public SamplingTimer(Clocks clocks, TimeBase timeBase) { 2075 super(clocks, 0, timeBase); 2076 mTrackingReportedValues = false; 2077 mTimeBaseRunning = timeBase.isRunning(); 2078 } 2079 2080 /** 2081 * Ends the current sample, allowing subsequent values to {@link #update(long, int)} to 2082 * be less than the values used for a previous invocation. 2083 */ endSample()2084 public void endSample() { 2085 endSample(mClocks.elapsedRealtime() * 1000); 2086 } 2087 2088 /** 2089 * @see #endSample() 2090 */ endSample(long elapsedRealtimeUs)2091 public void endSample(long elapsedRealtimeUs) { 2092 mTotalTimeUs = computeRunTimeLocked(0 /* unused by us */, elapsedRealtimeUs); 2093 mCount = computeCurrentCountLocked(); 2094 mUnpluggedReportedTotalTimeUs = mCurrentReportedTotalTimeUs = 0; 2095 mUnpluggedReportedCount = mCurrentReportedCount = 0; 2096 mTrackingReportedValues = false; 2097 } 2098 setUpdateVersion(int version)2099 public void setUpdateVersion(int version) { 2100 mUpdateVersion = version; 2101 } 2102 getUpdateVersion()2103 public int getUpdateVersion() { 2104 return mUpdateVersion; 2105 } 2106 2107 /** 2108 * Updates the current recorded values. These are meant to be monotonically increasing 2109 * and cumulative. If you are dealing with deltas, use {@link #add(long, int)}. 2110 * 2111 * If the values being recorded have been reset, the monotonically increasing requirement 2112 * will be broken. In this case, {@link #endSample()} is automatically called and 2113 * the total value of totalTimeUs and count are recorded, starting a new monotonically 2114 * increasing sample. 2115 * 2116 * @param totalTimeUs total time of sample in microseconds. 2117 * @param count total number of times the event being sampled occurred. 2118 */ updated(long totalTimeUs, int count)2119 public void updated(long totalTimeUs, int count) { 2120 update(totalTimeUs, count, mClocks.elapsedRealtime() * 1000); 2121 } 2122 2123 /** 2124 * @see #update(long, int) 2125 */ update(long totalTimeUs, int count, long elapsedRealtimeUs)2126 public void update(long totalTimeUs, int count, long elapsedRealtimeUs) { 2127 if (mTimeBaseRunning && !mTrackingReportedValues) { 2128 // Updating the reported value for the first time. 2129 mUnpluggedReportedTotalTimeUs = totalTimeUs; 2130 mUnpluggedReportedCount = count; 2131 } 2132 2133 mTrackingReportedValues = true; 2134 2135 if (totalTimeUs < mCurrentReportedTotalTimeUs || count < mCurrentReportedCount) { 2136 endSample(elapsedRealtimeUs); 2137 } 2138 2139 mCurrentReportedTotalTimeUs = totalTimeUs; 2140 mCurrentReportedCount = count; 2141 } 2142 2143 /** 2144 * Adds deltaTime and deltaCount to the current sample. 2145 * 2146 * @param deltaTime additional time recorded since the last sampled event, in microseconds. 2147 * @param deltaCount additional number of times the event being sampled occurred. 2148 */ add(long deltaTimeUs, int deltaCount)2149 public void add(long deltaTimeUs, int deltaCount) { 2150 add(deltaTimeUs, deltaCount, mClocks.elapsedRealtime() * 1000); 2151 } 2152 2153 /** 2154 * @see #add(long, int) 2155 */ add(long deltaTimeUs, int deltaCount, long elapsedRealtimeUs)2156 public void add(long deltaTimeUs, int deltaCount, long elapsedRealtimeUs) { 2157 update(mCurrentReportedTotalTimeUs + deltaTimeUs, mCurrentReportedCount + deltaCount, 2158 elapsedRealtimeUs); 2159 } 2160 2161 @Override onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)2162 public void onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { 2163 super.onTimeStarted(elapsedRealtimeUs, baseUptimeUs, baseRealtimeUs); 2164 if (mTrackingReportedValues) { 2165 mUnpluggedReportedTotalTimeUs = mCurrentReportedTotalTimeUs; 2166 mUnpluggedReportedCount = mCurrentReportedCount; 2167 } 2168 mTimeBaseRunning = true; 2169 } 2170 2171 @Override onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)2172 public void onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { 2173 super.onTimeStopped(elapsedRealtimeUs, baseUptimeUs, baseRealtimeUs); 2174 mTimeBaseRunning = false; 2175 } 2176 2177 @Override logState(Printer pw, String prefix)2178 public void logState(Printer pw, String prefix) { 2179 super.logState(pw, prefix); 2180 pw.println(prefix + "mCurrentReportedCount=" + mCurrentReportedCount 2181 + " mUnpluggedReportedCount=" + mUnpluggedReportedCount 2182 + " mCurrentReportedTotalTime=" + mCurrentReportedTotalTimeUs 2183 + " mUnpluggedReportedTotalTime=" + mUnpluggedReportedTotalTimeUs); 2184 } 2185 2186 @Override computeRunTimeLocked(long curBatteryRealtime, long elapsedRealtimeUs)2187 protected long computeRunTimeLocked(long curBatteryRealtime, long elapsedRealtimeUs) { 2188 return mTotalTimeUs + (mTimeBaseRunning && mTrackingReportedValues 2189 ? mCurrentReportedTotalTimeUs - mUnpluggedReportedTotalTimeUs : 0); 2190 } 2191 2192 @Override computeCurrentCountLocked()2193 protected int computeCurrentCountLocked() { 2194 return mCount + (mTimeBaseRunning && mTrackingReportedValues 2195 ? mCurrentReportedCount - mUnpluggedReportedCount : 0); 2196 } 2197 2198 @Override writeToParcel(Parcel out, long elapsedRealtimeUs)2199 public void writeToParcel(Parcel out, long elapsedRealtimeUs) { 2200 super.writeToParcel(out, elapsedRealtimeUs); 2201 out.writeInt(mCurrentReportedCount); 2202 out.writeInt(mUnpluggedReportedCount); 2203 out.writeLong(mCurrentReportedTotalTimeUs); 2204 out.writeLong(mUnpluggedReportedTotalTimeUs); 2205 out.writeInt(mTrackingReportedValues ? 1 : 0); 2206 } 2207 2208 @Override reset(boolean detachIfReset, long elapsedRealtimeUs)2209 public boolean reset(boolean detachIfReset, long elapsedRealtimeUs) { 2210 super.reset(detachIfReset, elapsedRealtimeUs); 2211 mTrackingReportedValues = false; 2212 mUnpluggedReportedTotalTimeUs = 0; 2213 mUnpluggedReportedCount = 0; 2214 return true; 2215 } 2216 } 2217 2218 /** 2219 * A timer that increments in batches. It does not run for durations, but just jumps 2220 * for a pre-determined amount. 2221 */ 2222 public static class BatchTimer extends Timer { 2223 final Uid mUid; 2224 2225 /** 2226 * The last time at which we updated the timer. This is in elapsed realtime microseconds. 2227 */ 2228 long mLastAddedTimeUs; 2229 2230 /** 2231 * The last duration that we added to the timer. This is in microseconds. 2232 */ 2233 long mLastAddedDurationUs; 2234 2235 /** 2236 * Whether we are currently in a discharge cycle. 2237 */ 2238 boolean mInDischarge; 2239 BatchTimer(Clocks clocks, Uid uid, int type, TimeBase timeBase, Parcel in)2240 BatchTimer(Clocks clocks, Uid uid, int type, TimeBase timeBase, Parcel in) { 2241 super(clocks, type, timeBase, in); 2242 mUid = uid; 2243 mLastAddedTimeUs = in.readLong(); 2244 mLastAddedDurationUs = in.readLong(); 2245 mInDischarge = timeBase.isRunning(); 2246 } 2247 BatchTimer(Clocks clocks, Uid uid, int type, TimeBase timeBase)2248 BatchTimer(Clocks clocks, Uid uid, int type, TimeBase timeBase) { 2249 super(clocks, type, timeBase); 2250 mUid = uid; 2251 mInDischarge = timeBase.isRunning(); 2252 } 2253 2254 @Override writeToParcel(Parcel out, long elapsedRealtimeUs)2255 public void writeToParcel(Parcel out, long elapsedRealtimeUs) { 2256 super.writeToParcel(out, elapsedRealtimeUs); 2257 out.writeLong(mLastAddedTimeUs); 2258 out.writeLong(mLastAddedDurationUs); 2259 } 2260 2261 @Override onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)2262 public void onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { 2263 recomputeLastDuration(elapsedRealtimeUs, false); 2264 mInDischarge = false; 2265 super.onTimeStopped(elapsedRealtimeUs, baseUptimeUs, baseRealtimeUs); 2266 } 2267 2268 @Override onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)2269 public void onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { 2270 recomputeLastDuration(elapsedRealtimeUs, false); 2271 mInDischarge = true; 2272 // If we are still within the last added duration, then re-added whatever remains. 2273 if (mLastAddedTimeUs == elapsedRealtimeUs) { 2274 mTotalTimeUs += mLastAddedDurationUs; 2275 } 2276 super.onTimeStarted(elapsedRealtimeUs, baseUptimeUs, baseRealtimeUs); 2277 } 2278 2279 @Override logState(Printer pw, String prefix)2280 public void logState(Printer pw, String prefix) { 2281 super.logState(pw, prefix); 2282 pw.println(prefix + "mLastAddedTime=" + mLastAddedTimeUs 2283 + " mLastAddedDuration=" + mLastAddedDurationUs); 2284 } 2285 computeOverage(long curTimeUs)2286 private long computeOverage(long curTimeUs) { 2287 if (mLastAddedTimeUs > 0) { 2288 return mLastAddedDurationUs - curTimeUs; 2289 } 2290 return 0; 2291 } 2292 recomputeLastDuration(long curTimeUs, boolean abort)2293 private void recomputeLastDuration(long curTimeUs, boolean abort) { 2294 final long overage = computeOverage(curTimeUs); 2295 if (overage > 0) { 2296 // Aborting before the duration ran out -- roll back the remaining 2297 // duration. Only do this if currently discharging; otherwise we didn't 2298 // actually add the time. 2299 if (mInDischarge) { 2300 mTotalTimeUs -= overage; 2301 } 2302 if (abort) { 2303 mLastAddedTimeUs = 0; 2304 } else { 2305 mLastAddedTimeUs = curTimeUs; 2306 mLastAddedDurationUs -= overage; 2307 } 2308 } 2309 } 2310 addDuration(BatteryStatsImpl stats, long durationMs)2311 public void addDuration(BatteryStatsImpl stats, long durationMs) { 2312 addDuration(stats, durationMs, mClocks.elapsedRealtime()); 2313 } 2314 addDuration(BatteryStatsImpl stats, long durationMs, long elapsedRealtimeMs)2315 public void addDuration(BatteryStatsImpl stats, long durationMs, long elapsedRealtimeMs) { 2316 final long nowUs = elapsedRealtimeMs * 1000; 2317 recomputeLastDuration(nowUs, true); 2318 mLastAddedTimeUs = nowUs; 2319 mLastAddedDurationUs = durationMs * 1000; 2320 if (mInDischarge) { 2321 mTotalTimeUs += mLastAddedDurationUs; 2322 mCount++; 2323 } 2324 } 2325 abortLastDuration(BatteryStatsImpl stats)2326 public void abortLastDuration(BatteryStatsImpl stats) { 2327 abortLastDuration(stats, mClocks.elapsedRealtime()); 2328 } 2329 abortLastDuration(BatteryStatsImpl stats, long elapsedRealtimeMs)2330 public void abortLastDuration(BatteryStatsImpl stats, long elapsedRealtimeMs) { 2331 final long nowUs = elapsedRealtimeMs * 1000; 2332 recomputeLastDuration(nowUs, true); 2333 } 2334 2335 @Override computeCurrentCountLocked()2336 protected int computeCurrentCountLocked() { 2337 return mCount; 2338 } 2339 2340 @Override computeRunTimeLocked(long curBatteryRealtimeUs, long elapsedRealtimeUs)2341 protected long computeRunTimeLocked(long curBatteryRealtimeUs, long elapsedRealtimeUs) { 2342 final long overage = computeOverage(elapsedRealtimeUs); 2343 if (overage > 0) { 2344 return mTotalTimeUs = overage; 2345 } 2346 return mTotalTimeUs; 2347 } 2348 2349 @Override reset(boolean detachIfReset, long elapsedRealtimeUs)2350 public boolean reset(boolean detachIfReset, long elapsedRealtimeUs) { 2351 recomputeLastDuration(elapsedRealtimeUs, true); 2352 boolean stillActive = mLastAddedTimeUs == elapsedRealtimeUs; 2353 super.reset(!stillActive && detachIfReset, elapsedRealtimeUs); 2354 return !stillActive; 2355 } 2356 } 2357 2358 2359 /** 2360 * A StopwatchTimer that also tracks the total and max individual 2361 * time spent active according to the given timebase. Whereas 2362 * StopwatchTimer apportions the time amongst all in the pool, 2363 * the total and max durations are not apportioned. 2364 */ 2365 public static class DurationTimer extends StopwatchTimer { 2366 /** 2367 * The time (in ms) that the timer was last acquired or the time base 2368 * last (re-)started. Increasing the nesting depth does not reset this time. 2369 * 2370 * -1 if the timer is currently not running or the time base is not running. 2371 * 2372 * If written to a parcel, the start time is reset, as is mNesting in the base class 2373 * StopwatchTimer. 2374 */ 2375 long mStartTimeMs = -1; 2376 2377 /** 2378 * The longest time period (in ms) that the timer has been active. Not pooled. 2379 */ 2380 long mMaxDurationMs; 2381 2382 /** 2383 * The time (in ms) that that the timer has been active since most recent 2384 * stopRunningLocked() or reset(). Not pooled. 2385 */ 2386 long mCurrentDurationMs; 2387 2388 /** 2389 * The total time (in ms) that that the timer has been active since most recent reset() 2390 * prior to the current startRunningLocked. This is the sum of all past currentDurations 2391 * (but not including the present currentDuration) since reset. Not pooled. 2392 */ 2393 long mTotalDurationMs; 2394 DurationTimer(Clocks clocks, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, TimeBase timeBase, Parcel in)2395 public DurationTimer(Clocks clocks, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, 2396 TimeBase timeBase, Parcel in) { 2397 super(clocks, uid, type, timerPool, timeBase, in); 2398 mMaxDurationMs = in.readLong(); 2399 mTotalDurationMs = in.readLong(); 2400 mCurrentDurationMs = in.readLong(); 2401 } 2402 DurationTimer(Clocks clocks, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, TimeBase timeBase)2403 public DurationTimer(Clocks clocks, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, 2404 TimeBase timeBase) { 2405 super(clocks, uid, type, timerPool, timeBase); 2406 } 2407 2408 @Override writeToParcel(Parcel out, long elapsedRealtimeUs)2409 public void writeToParcel(Parcel out, long elapsedRealtimeUs) { 2410 super.writeToParcel(out, elapsedRealtimeUs); 2411 out.writeLong(getMaxDurationMsLocked(elapsedRealtimeUs / 1000)); 2412 out.writeLong(mTotalDurationMs); 2413 out.writeLong(getCurrentDurationMsLocked(elapsedRealtimeUs / 1000)); 2414 } 2415 2416 /** 2417 * Write the summary to the parcel. 2418 * 2419 * Since the time base is probably meaningless after we come back, reading 2420 * from this will have the effect of stopping the timer. So here all we write 2421 * is the max and total durations. 2422 */ 2423 @Override writeSummaryFromParcelLocked(Parcel out, long elapsedRealtimeUs)2424 public void writeSummaryFromParcelLocked(Parcel out, long elapsedRealtimeUs) { 2425 super.writeSummaryFromParcelLocked(out, elapsedRealtimeUs); 2426 out.writeLong(getMaxDurationMsLocked(elapsedRealtimeUs / 1000)); 2427 out.writeLong(getTotalDurationMsLocked(elapsedRealtimeUs / 1000)); 2428 } 2429 2430 /** 2431 * Read the summary parcel. 2432 * 2433 * Has the side effect of stopping the timer. 2434 */ 2435 @Override readSummaryFromParcelLocked(Parcel in)2436 public void readSummaryFromParcelLocked(Parcel in) { 2437 super.readSummaryFromParcelLocked(in); 2438 mMaxDurationMs = in.readLong(); 2439 mTotalDurationMs = in.readLong(); 2440 mStartTimeMs = -1; 2441 mCurrentDurationMs = 0; 2442 } 2443 2444 /** 2445 * The TimeBase time started (again). 2446 * 2447 * If the timer is also running, store the start time. 2448 */ onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)2449 public void onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { 2450 super.onTimeStarted(elapsedRealtimeUs, baseUptimeUs, baseRealtimeUs); 2451 if (mNesting > 0) { 2452 mStartTimeMs = baseRealtimeUs / 1000; 2453 } 2454 } 2455 2456 /** 2457 * The TimeBase stopped running. 2458 * 2459 * If the timer is running, add the duration into mCurrentDurationMs. 2460 */ 2461 @Override onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)2462 public void onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { 2463 super.onTimeStopped(elapsedRealtimeUs, baseUptimeUs, baseRealtimeUs); 2464 if (mNesting > 0) { 2465 // baseRealtimeUs has already been converted to the timebase's realtime. 2466 mCurrentDurationMs += (baseRealtimeUs / 1000) - mStartTimeMs; 2467 } 2468 mStartTimeMs = -1; 2469 } 2470 2471 @Override logState(Printer pw, String prefix)2472 public void logState(Printer pw, String prefix) { 2473 super.logState(pw, prefix); 2474 } 2475 2476 @Override startRunningLocked(long elapsedRealtimeMs)2477 public void startRunningLocked(long elapsedRealtimeMs) { 2478 super.startRunningLocked(elapsedRealtimeMs); 2479 if (mNesting == 1 && mTimeBase.isRunning()) { 2480 // Just started 2481 mStartTimeMs = mTimeBase.getRealtime(elapsedRealtimeMs * 1000) / 1000; 2482 } 2483 } 2484 2485 /** 2486 * Decrements the mNesting ref-count on this timer. 2487 * 2488 * If it actually stopped (mNesting went to 0), then possibly update 2489 * mMaxDuration if the current duration was the longest ever. 2490 */ 2491 @Override stopRunningLocked(long elapsedRealtimeMs)2492 public void stopRunningLocked(long elapsedRealtimeMs) { 2493 if (mNesting == 1) { 2494 final long durationMs = getCurrentDurationMsLocked(elapsedRealtimeMs); 2495 mTotalDurationMs += durationMs; 2496 if (durationMs > mMaxDurationMs) { 2497 mMaxDurationMs = durationMs; 2498 } 2499 mStartTimeMs = -1; 2500 mCurrentDurationMs = 0; 2501 } 2502 // super method decrements mNesting, which getCurrentDurationMsLocked relies on, 2503 // so call super.stopRunningLocked after calling getCurrentDurationMsLocked. 2504 super.stopRunningLocked(elapsedRealtimeMs); 2505 } 2506 2507 @Override reset(boolean detachIfReset, long elapsedRealtimeUs)2508 public boolean reset(boolean detachIfReset, long elapsedRealtimeUs) { 2509 boolean result = super.reset(detachIfReset, elapsedRealtimeUs); 2510 mMaxDurationMs = 0; 2511 mTotalDurationMs = 0; 2512 mCurrentDurationMs = 0; 2513 if (mNesting > 0) { 2514 mStartTimeMs = mTimeBase.getRealtime(elapsedRealtimeUs) / 1000; 2515 } else { 2516 mStartTimeMs = -1; 2517 } 2518 return result; 2519 } 2520 2521 /** 2522 * Returns the max duration that this timer has ever seen. 2523 * 2524 * Note that this time is NOT split between the timers in the timer group that 2525 * this timer is attached to. It is the TOTAL time. 2526 */ 2527 @Override getMaxDurationMsLocked(long elapsedRealtimeMs)2528 public long getMaxDurationMsLocked(long elapsedRealtimeMs) { 2529 if (mNesting > 0) { 2530 final long durationMs = getCurrentDurationMsLocked(elapsedRealtimeMs); 2531 if (durationMs > mMaxDurationMs) { 2532 return durationMs; 2533 } 2534 } 2535 return mMaxDurationMs; 2536 } 2537 2538 /** 2539 * Returns the time since the timer was started. 2540 * Returns 0 if the timer is not currently running. 2541 * 2542 * Note that this time is NOT split between the timers in the timer group that 2543 * this timer is attached to. It is the TOTAL time. 2544 * 2545 * Note that if running timer is parceled and unparceled, this method will return 2546 * current duration value at the time of parceling even though timer may not be 2547 * currently running. 2548 */ 2549 @Override getCurrentDurationMsLocked(long elapsedRealtimeMs)2550 public long getCurrentDurationMsLocked(long elapsedRealtimeMs) { 2551 long durationMs = mCurrentDurationMs; 2552 if (mNesting > 0 && mTimeBase.isRunning()) { 2553 durationMs += (mTimeBase.getRealtime(elapsedRealtimeMs * 1000) / 1000) 2554 - mStartTimeMs; 2555 } 2556 return durationMs; 2557 } 2558 2559 /** 2560 * Returns the total cumulative duration that this timer has been on since reset(). 2561 * If mTimerPool == null, this should be the same 2562 * as getTotalTimeLocked(elapsedRealtimeMs*1000, STATS_SINCE_CHARGED)/1000. 2563 * 2564 * Note that this time is NOT split between the timers in the timer group that 2565 * this timer is attached to. It is the TOTAL time. For this reason, if mTimerPool != null, 2566 * the result will not be equivalent to getTotalTimeLocked. 2567 */ 2568 @Override getTotalDurationMsLocked(long elapsedRealtimeMs)2569 public long getTotalDurationMsLocked(long elapsedRealtimeMs) { 2570 return mTotalDurationMs + getCurrentDurationMsLocked(elapsedRealtimeMs); 2571 } 2572 } 2573 2574 /** 2575 * State for keeping track of timing information. 2576 */ 2577 public static class StopwatchTimer extends Timer { 2578 final Uid mUid; 2579 final ArrayList<StopwatchTimer> mTimerPool; 2580 2581 int mNesting; 2582 2583 /** 2584 * The last time at which we updated the timer. If mNesting is > 0, 2585 * subtract this from the current battery time to find the amount of 2586 * time we have been running since we last computed an update. 2587 */ 2588 long mUpdateTimeUs; 2589 2590 /** 2591 * The total time at which the timer was acquired, to determine if it 2592 * was actually held for an interesting duration. If time base was not running when timer 2593 * was acquired, will be -1. 2594 */ 2595 long mAcquireTimeUs = -1; 2596 2597 long mTimeoutUs; 2598 2599 /** 2600 * For partial wake locks, keep track of whether we are in the list 2601 * to consume CPU cycles. 2602 */ 2603 @VisibleForTesting 2604 public boolean mInList; 2605 StopwatchTimer(Clocks clocks, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, TimeBase timeBase, Parcel in)2606 public StopwatchTimer(Clocks clocks, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, 2607 TimeBase timeBase, Parcel in) { 2608 super(clocks, type, timeBase, in); 2609 mUid = uid; 2610 mTimerPool = timerPool; 2611 mUpdateTimeUs = in.readLong(); 2612 } 2613 StopwatchTimer(Clocks clocks, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, TimeBase timeBase)2614 public StopwatchTimer(Clocks clocks, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, 2615 TimeBase timeBase) { 2616 super(clocks, type, timeBase); 2617 mUid = uid; 2618 mTimerPool = timerPool; 2619 } 2620 setTimeout(long timeoutUs)2621 public void setTimeout(long timeoutUs) { 2622 mTimeoutUs = timeoutUs; 2623 } 2624 writeToParcel(Parcel out, long elapsedRealtimeUs)2625 public void writeToParcel(Parcel out, long elapsedRealtimeUs) { 2626 super.writeToParcel(out, elapsedRealtimeUs); 2627 out.writeLong(mUpdateTimeUs); 2628 } 2629 onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)2630 public void onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { 2631 if (mNesting > 0) { 2632 if (DEBUG && mType < 0) { 2633 Log.v(TAG, "old mUpdateTime=" + mUpdateTimeUs); 2634 } 2635 super.onTimeStopped(elapsedRealtimeUs, baseUptimeUs, baseRealtimeUs); 2636 mUpdateTimeUs = baseRealtimeUs; 2637 if (DEBUG && mType < 0) { 2638 Log.v(TAG, "new mUpdateTime=" + mUpdateTimeUs); 2639 } 2640 } 2641 } 2642 logState(Printer pw, String prefix)2643 public void logState(Printer pw, String prefix) { 2644 super.logState(pw, prefix); 2645 pw.println(prefix + "mNesting=" + mNesting + " mUpdateTime=" + mUpdateTimeUs 2646 + " mAcquireTime=" + mAcquireTimeUs); 2647 } 2648 startRunningLocked(long elapsedRealtimeMs)2649 public void startRunningLocked(long elapsedRealtimeMs) { 2650 if (mNesting++ == 0) { 2651 final long batteryRealtimeUs = mTimeBase.getRealtime(elapsedRealtimeMs * 1000); 2652 mUpdateTimeUs = batteryRealtimeUs; 2653 if (mTimerPool != null) { 2654 // Accumulate time to all currently active timers before adding 2655 // this new one to the pool. 2656 refreshTimersLocked(batteryRealtimeUs, mTimerPool, null); 2657 // Add this timer to the active pool 2658 mTimerPool.add(this); 2659 } 2660 if (mTimeBase.isRunning()) { 2661 // Increment the count 2662 mCount++; 2663 mAcquireTimeUs = mTotalTimeUs; 2664 } else { 2665 mAcquireTimeUs = -1; 2666 } 2667 if (DEBUG && mType < 0) { 2668 Log.v(TAG, "start #" + mType + ": mUpdateTime=" + mUpdateTimeUs 2669 + " mTotalTime=" + mTotalTimeUs + " mCount=" + mCount 2670 + " mAcquireTime=" + mAcquireTimeUs); 2671 } 2672 } 2673 } 2674 isRunningLocked()2675 public boolean isRunningLocked() { 2676 return mNesting > 0; 2677 } 2678 stopRunningLocked(long elapsedRealtimeMs)2679 public void stopRunningLocked(long elapsedRealtimeMs) { 2680 // Ignore attempt to stop a timer that isn't running 2681 if (mNesting == 0) { 2682 return; 2683 } 2684 if (--mNesting == 0) { 2685 final long batteryRealtimeUs = mTimeBase.getRealtime(elapsedRealtimeMs * 1000); 2686 if (mTimerPool != null) { 2687 // Accumulate time to all active counters, scaled by the total 2688 // active in the pool, before taking this one out of the pool. 2689 refreshTimersLocked(batteryRealtimeUs, mTimerPool, null); 2690 // Remove this timer from the active pool 2691 mTimerPool.remove(this); 2692 } else { 2693 mNesting = 1; 2694 mTotalTimeUs = computeRunTimeLocked(batteryRealtimeUs, 2695 elapsedRealtimeMs * 1000); 2696 mNesting = 0; 2697 } 2698 2699 if (DEBUG && mType < 0) { 2700 Log.v(TAG, "stop #" + mType + ": mUpdateTime=" + mUpdateTimeUs 2701 + " mTotalTime=" + mTotalTimeUs + " mCount=" + mCount 2702 + " mAcquireTime=" + mAcquireTimeUs); 2703 } 2704 2705 if (mAcquireTimeUs >= 0 && mTotalTimeUs == mAcquireTimeUs) { 2706 // If there was no change in the time, then discard this 2707 // count. A somewhat cheezy strategy, but hey. 2708 mCount--; 2709 } 2710 } 2711 } 2712 stopAllRunningLocked(long elapsedRealtimeMs)2713 public void stopAllRunningLocked(long elapsedRealtimeMs) { 2714 if (mNesting > 0) { 2715 mNesting = 1; 2716 stopRunningLocked(elapsedRealtimeMs); 2717 } 2718 } 2719 2720 // Update the total time for all other running Timers with the same type as this Timer 2721 // due to a change in timer count refreshTimersLocked(long batteryRealtimeUs, final ArrayList<StopwatchTimer> pool, StopwatchTimer self)2722 private static long refreshTimersLocked(long batteryRealtimeUs, 2723 final ArrayList<StopwatchTimer> pool, StopwatchTimer self) { 2724 long selfTimeUs = 0; 2725 final int N = pool.size(); 2726 for (int i=N-1; i>= 0; i--) { 2727 final StopwatchTimer t = pool.get(i); 2728 long heldTimeUs = batteryRealtimeUs - t.mUpdateTimeUs; 2729 if (heldTimeUs > 0) { 2730 final long myTimeUs = heldTimeUs / N; 2731 if (t == self) { 2732 selfTimeUs = myTimeUs; 2733 } 2734 t.mTotalTimeUs += myTimeUs; 2735 } 2736 t.mUpdateTimeUs = batteryRealtimeUs; 2737 } 2738 return selfTimeUs; 2739 } 2740 2741 @Override computeRunTimeLocked(long curBatteryRealtimeUs, long elapsedRealtimeUs)2742 protected long computeRunTimeLocked(long curBatteryRealtimeUs, long elapsedRealtimeUs) { 2743 if (mTimeoutUs > 0 && curBatteryRealtimeUs > mUpdateTimeUs + mTimeoutUs) { 2744 curBatteryRealtimeUs = mUpdateTimeUs + mTimeoutUs; 2745 } 2746 return mTotalTimeUs + (mNesting > 0 2747 ? (curBatteryRealtimeUs - mUpdateTimeUs) 2748 / (mTimerPool != null ? mTimerPool.size() : 1) 2749 : 0); 2750 } 2751 2752 @Override computeCurrentCountLocked()2753 protected int computeCurrentCountLocked() { 2754 return mCount; 2755 } 2756 2757 @Override reset(boolean detachIfReset, long elapsedRealtimeUs)2758 public boolean reset(boolean detachIfReset, long elapsedRealtimeUs) { 2759 boolean canDetach = mNesting <= 0; 2760 super.reset(canDetach && detachIfReset, elapsedRealtimeUs); 2761 if (mNesting > 0) { 2762 mUpdateTimeUs = mTimeBase.getRealtime(elapsedRealtimeUs); 2763 } 2764 // To ensure mCount isn't decreased to -1 if timer is stopped later. 2765 mAcquireTimeUs = -1; 2766 return canDetach; 2767 } 2768 2769 @Override 2770 @UnsupportedAppUsage detach()2771 public void detach() { 2772 super.detach(); 2773 if (mTimerPool != null) { 2774 mTimerPool.remove(this); 2775 } 2776 } 2777 2778 @Override readSummaryFromParcelLocked(Parcel in)2779 public void readSummaryFromParcelLocked(Parcel in) { 2780 super.readSummaryFromParcelLocked(in); 2781 mNesting = 0; 2782 } 2783 2784 /** 2785 * Set the mark so that we can query later for the total time the timer has 2786 * accumulated since this point. The timer can be running or not. 2787 * 2788 * @param elapsedRealtimeMs the current elapsed realtime in milliseconds. 2789 */ setMark(long elapsedRealtimeMs)2790 public void setMark(long elapsedRealtimeMs) { 2791 final long batteryRealtimeUs = mTimeBase.getRealtime(elapsedRealtimeMs * 1000); 2792 if (mNesting > 0) { 2793 // We are running. 2794 if (mTimerPool != null) { 2795 refreshTimersLocked(batteryRealtimeUs, mTimerPool, this); 2796 } else { 2797 mTotalTimeUs += batteryRealtimeUs - mUpdateTimeUs; 2798 mUpdateTimeUs = batteryRealtimeUs; 2799 } 2800 } 2801 mTimeBeforeMarkUs = mTotalTimeUs; 2802 } 2803 } 2804 2805 /** 2806 * State for keeping track of two DurationTimers with different TimeBases, presumably where one 2807 * TimeBase is effectively a subset of the other. 2808 */ 2809 public static class DualTimer extends DurationTimer { 2810 // This class both is a DurationTimer and also holds a second DurationTimer. 2811 // The main timer (this) typically tracks the total time. It may be pooled (but since it's a 2812 // durationTimer, it also has the unpooled getTotalDurationMsLocked() for 2813 // STATS_SINCE_CHARGED). 2814 // mSubTimer typically tracks only part of the total time, such as background time, as 2815 // determined by a subTimeBase. It is NOT pooled. 2816 private final DurationTimer mSubTimer; 2817 2818 /** 2819 * Creates a DualTimer to hold a main timer (this) and a mSubTimer. 2820 * The main timer (this) is based on the given timeBase and timerPool. 2821 * The mSubTimer is based on the given subTimeBase. The mSubTimer is not pooled, even if 2822 * the main timer is. 2823 */ DualTimer(Clocks clocks, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, TimeBase timeBase, TimeBase subTimeBase, Parcel in)2824 public DualTimer(Clocks clocks, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, 2825 TimeBase timeBase, TimeBase subTimeBase, Parcel in) { 2826 super(clocks, uid, type, timerPool, timeBase, in); 2827 mSubTimer = new DurationTimer(clocks, uid, type, null, subTimeBase, in); 2828 } 2829 2830 /** 2831 * Creates a DualTimer to hold a main timer (this) and a mSubTimer. 2832 * The main timer (this) is based on the given timeBase and timerPool. 2833 * The mSubTimer is based on the given subTimeBase. The mSubTimer is not pooled, even if 2834 * the main timer is. 2835 */ DualTimer(Clocks clocks, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, TimeBase timeBase, TimeBase subTimeBase)2836 public DualTimer(Clocks clocks, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, 2837 TimeBase timeBase, TimeBase subTimeBase) { 2838 super(clocks, uid, type, timerPool, timeBase); 2839 mSubTimer = new DurationTimer(clocks, uid, type, null, subTimeBase); 2840 } 2841 2842 /** Get the secondary timer. */ 2843 @Override getSubTimer()2844 public DurationTimer getSubTimer() { 2845 return mSubTimer; 2846 } 2847 2848 @Override startRunningLocked(long elapsedRealtimeMs)2849 public void startRunningLocked(long elapsedRealtimeMs) { 2850 super.startRunningLocked(elapsedRealtimeMs); 2851 mSubTimer.startRunningLocked(elapsedRealtimeMs); 2852 } 2853 2854 @Override stopRunningLocked(long elapsedRealtimeMs)2855 public void stopRunningLocked(long elapsedRealtimeMs) { 2856 super.stopRunningLocked(elapsedRealtimeMs); 2857 mSubTimer.stopRunningLocked(elapsedRealtimeMs); 2858 } 2859 2860 @Override stopAllRunningLocked(long elapsedRealtimeMs)2861 public void stopAllRunningLocked(long elapsedRealtimeMs) { 2862 super.stopAllRunningLocked(elapsedRealtimeMs); 2863 mSubTimer.stopAllRunningLocked(elapsedRealtimeMs); 2864 } 2865 2866 @Override reset(boolean detachIfReset, long elapsedRealtimeUs)2867 public boolean reset(boolean detachIfReset, long elapsedRealtimeUs) { 2868 boolean active = false; 2869 // Do not detach the subTimer explicitly since that'll be done by DualTimer.detach(). 2870 active |= !mSubTimer.reset(false, elapsedRealtimeUs); 2871 active |= !super.reset(detachIfReset, elapsedRealtimeUs); 2872 return !active; 2873 } 2874 2875 @Override detach()2876 public void detach() { 2877 mSubTimer.detach(); 2878 super.detach(); 2879 } 2880 2881 @Override writeToParcel(Parcel out, long elapsedRealtimeUs)2882 public void writeToParcel(Parcel out, long elapsedRealtimeUs) { 2883 super.writeToParcel(out, elapsedRealtimeUs); 2884 mSubTimer.writeToParcel(out, elapsedRealtimeUs); 2885 } 2886 2887 @Override writeSummaryFromParcelLocked(Parcel out, long elapsedRealtimeUs)2888 public void writeSummaryFromParcelLocked(Parcel out, long elapsedRealtimeUs) { 2889 super.writeSummaryFromParcelLocked(out, elapsedRealtimeUs); 2890 mSubTimer.writeSummaryFromParcelLocked(out, elapsedRealtimeUs); 2891 } 2892 2893 @Override readSummaryFromParcelLocked(Parcel in)2894 public void readSummaryFromParcelLocked(Parcel in) { 2895 super.readSummaryFromParcelLocked(in); 2896 mSubTimer.readSummaryFromParcelLocked(in); 2897 } 2898 } 2899 2900 2901 public abstract class OverflowArrayMap<T> { 2902 private static final String OVERFLOW_NAME = "*overflow*"; 2903 2904 final int mUid; 2905 final ArrayMap<String, T> mMap = new ArrayMap<>(); 2906 T mCurOverflow; 2907 ArrayMap<String, MutableInt> mActiveOverflow; 2908 long mLastOverflowTimeMs; 2909 long mLastOverflowFinishTimeMs; 2910 long mLastClearTimeMs; 2911 long mLastCleanupTimeMs; 2912 OverflowArrayMap(int uid)2913 public OverflowArrayMap(int uid) { 2914 mUid = uid; 2915 } 2916 getMap()2917 public ArrayMap<String, T> getMap() { 2918 return mMap; 2919 } 2920 clear()2921 public void clear() { 2922 mLastClearTimeMs = SystemClock.elapsedRealtime(); 2923 mMap.clear(); 2924 mCurOverflow = null; 2925 mActiveOverflow = null; 2926 } 2927 add(String name, T obj)2928 public void add(String name, T obj) { 2929 if (name == null) { 2930 name = ""; 2931 } 2932 mMap.put(name, obj); 2933 if (OVERFLOW_NAME.equals(name)) { 2934 mCurOverflow = obj; 2935 } 2936 } 2937 cleanup(long elapsedRealtimeMs)2938 public void cleanup(long elapsedRealtimeMs) { 2939 mLastCleanupTimeMs = elapsedRealtimeMs; 2940 if (mActiveOverflow != null) { 2941 if (mActiveOverflow.size() == 0) { 2942 mActiveOverflow = null; 2943 } 2944 } 2945 if (mActiveOverflow == null) { 2946 // There is no currently active overflow, so we should no longer have 2947 // an overflow entry. 2948 if (mMap.containsKey(OVERFLOW_NAME)) { 2949 Slog.wtf(TAG, "Cleaning up with no active overflow, but have overflow entry " 2950 + mMap.get(OVERFLOW_NAME)); 2951 mMap.remove(OVERFLOW_NAME); 2952 } 2953 mCurOverflow = null; 2954 } else { 2955 // There is currently active overflow, so we should still have an overflow entry. 2956 if (mCurOverflow == null || !mMap.containsKey(OVERFLOW_NAME)) { 2957 Slog.wtf(TAG, "Cleaning up with active overflow, but no overflow entry: cur=" 2958 + mCurOverflow + " map=" + mMap.get(OVERFLOW_NAME)); 2959 } 2960 } 2961 } 2962 startObject(String name, long elapsedRealtimeMs)2963 public T startObject(String name, long elapsedRealtimeMs) { 2964 if (name == null) { 2965 name = ""; 2966 } 2967 T obj = mMap.get(name); 2968 if (obj != null) { 2969 return obj; 2970 } 2971 2972 // No object exists for the given name, but do we currently have it 2973 // running as part of the overflow? 2974 if (mActiveOverflow != null) { 2975 MutableInt over = mActiveOverflow.get(name); 2976 if (over != null) { 2977 // We are already actively counting this name in the overflow object. 2978 obj = mCurOverflow; 2979 if (obj == null) { 2980 // Shouldn't be here, but we'll try to recover. 2981 Slog.wtf(TAG, "Have active overflow " + name + " but null overflow"); 2982 obj = mCurOverflow = instantiateObject(); 2983 mMap.put(OVERFLOW_NAME, obj); 2984 } 2985 over.value++; 2986 return obj; 2987 } 2988 } 2989 2990 // No object exists for given name nor in the overflow; we need to make 2991 // a new one. 2992 final int N = mMap.size(); 2993 if (N >= MAX_WAKELOCKS_PER_UID) { 2994 // Went over the limit on number of objects to track; this one goes 2995 // in to the overflow. 2996 obj = mCurOverflow; 2997 if (obj == null) { 2998 // Need to start overflow now... 2999 obj = mCurOverflow = instantiateObject(); 3000 mMap.put(OVERFLOW_NAME, obj); 3001 } 3002 if (mActiveOverflow == null) { 3003 mActiveOverflow = new ArrayMap<>(); 3004 } 3005 mActiveOverflow.put(name, new MutableInt(1)); 3006 mLastOverflowTimeMs = elapsedRealtimeMs; 3007 return obj; 3008 } 3009 3010 // Normal case where we just need to make a new object. 3011 obj = instantiateObject(); 3012 mMap.put(name, obj); 3013 return obj; 3014 } 3015 stopObject(String name, long elapsedRealtimeMs)3016 public T stopObject(String name, long elapsedRealtimeMs) { 3017 if (name == null) { 3018 name = ""; 3019 } 3020 T obj = mMap.get(name); 3021 if (obj != null) { 3022 return obj; 3023 } 3024 3025 // No object exists for the given name, but do we currently have it 3026 // running as part of the overflow? 3027 if (mActiveOverflow != null) { 3028 MutableInt over = mActiveOverflow.get(name); 3029 if (over != null) { 3030 // We are already actively counting this name in the overflow object. 3031 obj = mCurOverflow; 3032 if (obj != null) { 3033 over.value--; 3034 if (over.value <= 0) { 3035 mActiveOverflow.remove(name); 3036 mLastOverflowFinishTimeMs = elapsedRealtimeMs; 3037 } 3038 return obj; 3039 } 3040 } 3041 } 3042 3043 // Huh, they are stopping an active operation but we can't find one! 3044 // That's not good. 3045 StringBuilder sb = new StringBuilder(); 3046 sb.append("Unable to find object for "); 3047 sb.append(name); 3048 sb.append(" in uid "); 3049 sb.append(mUid); 3050 sb.append(" mapsize="); 3051 sb.append(mMap.size()); 3052 sb.append(" activeoverflow="); 3053 sb.append(mActiveOverflow); 3054 sb.append(" curoverflow="); 3055 sb.append(mCurOverflow); 3056 long now = elapsedRealtimeMs; 3057 if (mLastOverflowTimeMs != 0) { 3058 sb.append(" lastOverflowTime="); 3059 TimeUtils.formatDuration(mLastOverflowTimeMs - now, sb); 3060 } 3061 if (mLastOverflowFinishTimeMs != 0) { 3062 sb.append(" lastOverflowFinishTime="); 3063 TimeUtils.formatDuration(mLastOverflowFinishTimeMs - now, sb); 3064 } 3065 if (mLastClearTimeMs != 0) { 3066 sb.append(" lastClearTime="); 3067 TimeUtils.formatDuration(mLastClearTimeMs - now, sb); 3068 } 3069 if (mLastCleanupTimeMs != 0) { 3070 sb.append(" lastCleanupTime="); 3071 TimeUtils.formatDuration(mLastCleanupTimeMs - now, sb); 3072 } 3073 Slog.wtf(TAG, sb.toString()); 3074 return null; 3075 } 3076 instantiateObject()3077 public abstract T instantiateObject(); 3078 } 3079 3080 public static class ControllerActivityCounterImpl extends ControllerActivityCounter 3081 implements Parcelable { 3082 private final LongSamplingCounter mIdleTimeMillis; 3083 private final LongSamplingCounter mScanTimeMillis; 3084 private final LongSamplingCounter mSleepTimeMillis; 3085 private final LongSamplingCounter mRxTimeMillis; 3086 private final LongSamplingCounter[] mTxTimeMillis; 3087 private final LongSamplingCounter mPowerDrainMaMs; 3088 private final LongSamplingCounter mMonitoredRailChargeConsumedMaMs; 3089 ControllerActivityCounterImpl(TimeBase timeBase, int numTxStates)3090 public ControllerActivityCounterImpl(TimeBase timeBase, int numTxStates) { 3091 mIdleTimeMillis = new LongSamplingCounter(timeBase); 3092 mScanTimeMillis = new LongSamplingCounter(timeBase); 3093 mSleepTimeMillis = new LongSamplingCounter(timeBase); 3094 mRxTimeMillis = new LongSamplingCounter(timeBase); 3095 mTxTimeMillis = new LongSamplingCounter[numTxStates]; 3096 for (int i = 0; i < numTxStates; i++) { 3097 mTxTimeMillis[i] = new LongSamplingCounter(timeBase); 3098 } 3099 mPowerDrainMaMs = new LongSamplingCounter(timeBase); 3100 mMonitoredRailChargeConsumedMaMs = new LongSamplingCounter(timeBase); 3101 } 3102 ControllerActivityCounterImpl(TimeBase timeBase, int numTxStates, Parcel in)3103 public ControllerActivityCounterImpl(TimeBase timeBase, int numTxStates, Parcel in) { 3104 mIdleTimeMillis = new LongSamplingCounter(timeBase, in); 3105 mScanTimeMillis = new LongSamplingCounter(timeBase, in); 3106 mSleepTimeMillis = new LongSamplingCounter(timeBase, in); 3107 mRxTimeMillis = new LongSamplingCounter(timeBase, in); 3108 final int recordedTxStates = in.readInt(); 3109 if (recordedTxStates != numTxStates) { 3110 throw new ParcelFormatException("inconsistent tx state lengths"); 3111 } 3112 3113 mTxTimeMillis = new LongSamplingCounter[numTxStates]; 3114 for (int i = 0; i < numTxStates; i++) { 3115 mTxTimeMillis[i] = new LongSamplingCounter(timeBase, in); 3116 } 3117 mPowerDrainMaMs = new LongSamplingCounter(timeBase, in); 3118 mMonitoredRailChargeConsumedMaMs = new LongSamplingCounter(timeBase, in); 3119 } 3120 readSummaryFromParcel(Parcel in)3121 public void readSummaryFromParcel(Parcel in) { 3122 mIdleTimeMillis.readSummaryFromParcelLocked(in); 3123 mScanTimeMillis.readSummaryFromParcelLocked(in); 3124 mSleepTimeMillis.readSummaryFromParcelLocked(in); 3125 mRxTimeMillis.readSummaryFromParcelLocked(in); 3126 final int recordedTxStates = in.readInt(); 3127 if (recordedTxStates != mTxTimeMillis.length) { 3128 throw new ParcelFormatException("inconsistent tx state lengths"); 3129 } 3130 for (LongSamplingCounter counter : mTxTimeMillis) { 3131 counter.readSummaryFromParcelLocked(in); 3132 } 3133 mPowerDrainMaMs.readSummaryFromParcelLocked(in); 3134 mMonitoredRailChargeConsumedMaMs.readSummaryFromParcelLocked(in); 3135 } 3136 3137 @Override describeContents()3138 public int describeContents() { 3139 return 0; 3140 } 3141 writeSummaryToParcel(Parcel dest)3142 public void writeSummaryToParcel(Parcel dest) { 3143 mIdleTimeMillis.writeSummaryFromParcelLocked(dest); 3144 mScanTimeMillis.writeSummaryFromParcelLocked(dest); 3145 mSleepTimeMillis.writeSummaryFromParcelLocked(dest); 3146 mRxTimeMillis.writeSummaryFromParcelLocked(dest); 3147 dest.writeInt(mTxTimeMillis.length); 3148 for (LongSamplingCounter counter : mTxTimeMillis) { 3149 counter.writeSummaryFromParcelLocked(dest); 3150 } 3151 mPowerDrainMaMs.writeSummaryFromParcelLocked(dest); 3152 mMonitoredRailChargeConsumedMaMs.writeSummaryFromParcelLocked(dest); 3153 } 3154 3155 @Override writeToParcel(Parcel dest, int flags)3156 public void writeToParcel(Parcel dest, int flags) { 3157 mIdleTimeMillis.writeToParcel(dest); 3158 mScanTimeMillis.writeToParcel(dest); 3159 mSleepTimeMillis.writeToParcel(dest); 3160 mRxTimeMillis.writeToParcel(dest); 3161 dest.writeInt(mTxTimeMillis.length); 3162 for (LongSamplingCounter counter : mTxTimeMillis) { 3163 counter.writeToParcel(dest); 3164 } 3165 mPowerDrainMaMs.writeToParcel(dest); 3166 mMonitoredRailChargeConsumedMaMs.writeToParcel(dest); 3167 } 3168 reset(boolean detachIfReset, long elapsedRealtimeUs)3169 public void reset(boolean detachIfReset, long elapsedRealtimeUs) { 3170 mIdleTimeMillis.reset(detachIfReset, elapsedRealtimeUs); 3171 mScanTimeMillis.reset(detachIfReset, elapsedRealtimeUs); 3172 mSleepTimeMillis.reset(detachIfReset, elapsedRealtimeUs); 3173 mRxTimeMillis.reset(detachIfReset, elapsedRealtimeUs); 3174 for (LongSamplingCounter counter : mTxTimeMillis) { 3175 counter.reset(detachIfReset, elapsedRealtimeUs); 3176 } 3177 mPowerDrainMaMs.reset(detachIfReset, elapsedRealtimeUs); 3178 mMonitoredRailChargeConsumedMaMs.reset(detachIfReset, elapsedRealtimeUs); 3179 } 3180 detach()3181 public void detach() { 3182 mIdleTimeMillis.detach(); 3183 mScanTimeMillis.detach(); 3184 mSleepTimeMillis.detach(); 3185 mRxTimeMillis.detach(); 3186 for (LongSamplingCounter counter : mTxTimeMillis) { 3187 counter.detach(); 3188 } 3189 mPowerDrainMaMs.detach(); 3190 mMonitoredRailChargeConsumedMaMs.detach(); 3191 } 3192 3193 /** 3194 * @return a LongSamplingCounter, measuring time spent in the idle state in 3195 * milliseconds. 3196 */ 3197 @Override getIdleTimeCounter()3198 public LongSamplingCounter getIdleTimeCounter() { 3199 return mIdleTimeMillis; 3200 } 3201 3202 /** 3203 * @return a LongSamplingCounter, measuring time spent in the scan state in 3204 * milliseconds. 3205 */ 3206 @Override getScanTimeCounter()3207 public LongSamplingCounter getScanTimeCounter() { 3208 return mScanTimeMillis; 3209 } 3210 3211 /** 3212 * @return a LongSamplingCounter, measuring time spent in the sleep state in 3213 * milliseconds. 3214 */ 3215 @Override getSleepTimeCounter()3216 public LongSamplingCounter getSleepTimeCounter() { 3217 return mSleepTimeMillis; 3218 } 3219 3220 /** 3221 * @return a LongSamplingCounter, measuring time spent in the receive state in 3222 * milliseconds. 3223 */ 3224 @Override getRxTimeCounter()3225 public LongSamplingCounter getRxTimeCounter() { 3226 return mRxTimeMillis; 3227 } 3228 3229 /** 3230 * @return a LongSamplingCounter[], measuring time spent in various transmit states in 3231 * milliseconds. 3232 */ 3233 @Override getTxTimeCounters()3234 public LongSamplingCounter[] getTxTimeCounters() { 3235 return mTxTimeMillis; 3236 } 3237 3238 /** 3239 * @return a LongSamplingCounter, measuring power use in milli-ampere milliseconds (mAmS). 3240 */ 3241 @Override getPowerCounter()3242 public LongSamplingCounter getPowerCounter() { 3243 return mPowerDrainMaMs; 3244 } 3245 3246 /** 3247 * @return a LongSamplingCounter, measuring actual monitored rail energy consumed 3248 * milli-ampere milli-seconds (mAmS). 3249 */ 3250 @Override getMonitoredRailChargeConsumedMaMs()3251 public LongSamplingCounter getMonitoredRailChargeConsumedMaMs() { 3252 return mMonitoredRailChargeConsumedMaMs; 3253 } 3254 } 3255 3256 /** Get Resource Power Manager stats. Create a new one if it doesn't already exist. */ getRpmTimerLocked(String name)3257 public SamplingTimer getRpmTimerLocked(String name) { 3258 SamplingTimer rpmt = mRpmStats.get(name); 3259 if (rpmt == null) { 3260 rpmt = new SamplingTimer(mClocks, mOnBatteryTimeBase); 3261 mRpmStats.put(name, rpmt); 3262 } 3263 return rpmt; 3264 } 3265 3266 /** Get Screen-off Resource Power Manager stats. Create new one if it doesn't already exist. */ getScreenOffRpmTimerLocked(String name)3267 public SamplingTimer getScreenOffRpmTimerLocked(String name) { 3268 SamplingTimer rpmt = mScreenOffRpmStats.get(name); 3269 if (rpmt == null) { 3270 rpmt = new SamplingTimer(mClocks, mOnBatteryScreenOffTimeBase); 3271 mScreenOffRpmStats.put(name, rpmt); 3272 } 3273 return rpmt; 3274 } 3275 3276 /* 3277 * Get the wakeup reason counter, and create a new one if one 3278 * doesn't already exist. 3279 */ getWakeupReasonTimerLocked(String name)3280 public SamplingTimer getWakeupReasonTimerLocked(String name) { 3281 SamplingTimer timer = mWakeupReasonStats.get(name); 3282 if (timer == null) { 3283 timer = new SamplingTimer(mClocks, mOnBatteryTimeBase); 3284 mWakeupReasonStats.put(name, timer); 3285 } 3286 return timer; 3287 } 3288 3289 /* 3290 * Get the KernelWakelockTimer associated with name, and create a new one if one 3291 * doesn't already exist. 3292 */ getKernelWakelockTimerLocked(String name)3293 public SamplingTimer getKernelWakelockTimerLocked(String name) { 3294 SamplingTimer kwlt = mKernelWakelockStats.get(name); 3295 if (kwlt == null) { 3296 kwlt = new SamplingTimer(mClocks, mOnBatteryScreenOffTimeBase); 3297 mKernelWakelockStats.put(name, kwlt); 3298 } 3299 return kwlt; 3300 } 3301 getKernelMemoryTimerLocked(long bucket)3302 public SamplingTimer getKernelMemoryTimerLocked(long bucket) { 3303 SamplingTimer kmt = mKernelMemoryStats.get(bucket); 3304 if (kmt == null) { 3305 kmt = new SamplingTimer(mClocks, mOnBatteryTimeBase); 3306 mKernelMemoryStats.put(bucket, kmt); 3307 } 3308 return kmt; 3309 } 3310 writeHistoryTag(HistoryTag tag)3311 private int writeHistoryTag(HistoryTag tag) { 3312 Integer idxObj = mHistoryTagPool.get(tag); 3313 int idx; 3314 if (idxObj != null) { 3315 idx = idxObj; 3316 } else { 3317 idx = mNextHistoryTagIdx; 3318 HistoryTag key = new HistoryTag(); 3319 key.setTo(tag); 3320 tag.poolIdx = idx; 3321 mHistoryTagPool.put(key, idx); 3322 mNextHistoryTagIdx++; 3323 mNumHistoryTagChars += key.string.length() + 1; 3324 } 3325 return idx; 3326 } 3327 3328 /* 3329 The history delta format uses flags to denote further data in subsequent ints in the parcel. 3330 3331 There is always the first token, which may contain the delta time, or an indicator of 3332 the length of the time (int or long) following this token. 3333 3334 First token: always present, 3335 31 23 15 7 0 3336 █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█ 3337 3338 T: the delta time if it is <= 0x7fffd. Otherwise 0x7fffe indicates an int immediately 3339 follows containing the time, and 0x7ffff indicates a long immediately follows with the 3340 delta time. 3341 A: battery level changed and an int follows with battery data. 3342 B: state changed and an int follows with state change data. 3343 C: state2 has changed and an int follows with state2 change data. 3344 D: wakelock/wakereason has changed and an wakelock/wakereason struct follows. 3345 E: event data has changed and an event struct follows. 3346 F: battery charge in coulombs has changed and an int with the charge follows. 3347 G: state flag denoting that the mobile radio was active. 3348 H: state flag denoting that the wifi radio was active. 3349 I: state flag denoting that a wifi scan occurred. 3350 J: state flag denoting that a wifi full lock was held. 3351 K: state flag denoting that the gps was on. 3352 L: state flag denoting that a wakelock was held. 3353 M: state flag denoting that the cpu was running. 3354 3355 Time int/long: if T in the first token is 0x7ffff or 0x7fffe, then an int or long follows 3356 with the time delta. 3357 3358 Battery level int: if A in the first token is set, 3359 31 23 15 7 0 3360 █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█ 3361 3362 D: indicates that extra history details follow. 3363 V: the battery voltage. 3364 T: the battery temperature. 3365 L: the battery level (out of 100). 3366 3367 State change int: if B in the first token is set, 3368 31 23 15 7 0 3369 █S|S|S|H|H|H|P|P█F|E|D|C|B| | |A█ | | | | | | | █ | | | | | | | █ 3370 3371 A: wifi multicast was on. 3372 B: battery was plugged in. 3373 C: screen was on. 3374 D: phone was scanning for signal. 3375 E: audio was on. 3376 F: a sensor was active. 3377 3378 State2 change int: if C in the first token is set, 3379 31 23 15 7 0 3380 █M|L|K|J|I|H|H|G█F|E|D|C| | | | █ | | | | | | | █ |B|B|B|A|A|A|A█ 3381 3382 A: 4 bits indicating the wifi supplicant state: {@link BatteryStats#WIFI_SUPPL_STATE_NAMES}. 3383 B: 3 bits indicating the wifi signal strength: 0, 1, 2, 3, 4. 3384 C: a bluetooth scan was active. 3385 D: the camera was active. 3386 E: bluetooth was on. 3387 F: a phone call was active. 3388 G: the device was charging. 3389 H: 2 bits indicating the device-idle (doze) state: off, light, full 3390 I: the flashlight was on. 3391 J: wifi was on. 3392 K: wifi was running. 3393 L: video was playing. 3394 M: power save mode was on. 3395 3396 Wakelock/wakereason struct: if D in the first token is set, 3397 TODO(adamlesinski): describe wakelock/wakereason struct. 3398 3399 Event struct: if E in the first token is set, 3400 TODO(adamlesinski): describe the event struct. 3401 3402 History step details struct: if D in the battery level int is set, 3403 TODO(adamlesinski): describe the history step details struct. 3404 3405 Battery charge int: if F in the first token is set, an int representing the battery charge 3406 in coulombs follows. 3407 */ 3408 3409 // Part of initial delta int that specifies the time delta. 3410 static final int DELTA_TIME_MASK = 0x7ffff; 3411 static final int DELTA_TIME_LONG = 0x7ffff; // The delta is a following long 3412 static final int DELTA_TIME_INT = 0x7fffe; // The delta is a following int 3413 static final int DELTA_TIME_ABS = 0x7fffd; // Following is an entire abs update. 3414 // Flag in delta int: a new battery level int follows. 3415 static final int DELTA_BATTERY_LEVEL_FLAG = 0x00080000; 3416 // Flag in delta int: a new full state and battery status int follows. 3417 static final int DELTA_STATE_FLAG = 0x00100000; 3418 // Flag in delta int: a new full state2 int follows. 3419 static final int DELTA_STATE2_FLAG = 0x00200000; 3420 // Flag in delta int: contains a wakelock or wakeReason tag. 3421 static final int DELTA_WAKELOCK_FLAG = 0x00400000; 3422 // Flag in delta int: contains an event description. 3423 static final int DELTA_EVENT_FLAG = 0x00800000; 3424 // Flag in delta int: contains the battery charge count in uAh. 3425 static final int DELTA_BATTERY_CHARGE_FLAG = 0x01000000; 3426 // These upper bits are the frequently changing state bits. 3427 static final int DELTA_STATE_MASK = 0xfe000000; 3428 3429 // These are the pieces of battery state that are packed in to the upper bits of 3430 // the state int that have been packed in to the first delta int. They must fit 3431 // in STATE_BATTERY_MASK. 3432 static final int STATE_BATTERY_MASK = 0xff000000; 3433 static final int STATE_BATTERY_STATUS_MASK = 0x00000007; 3434 static final int STATE_BATTERY_STATUS_SHIFT = 29; 3435 static final int STATE_BATTERY_HEALTH_MASK = 0x00000007; 3436 static final int STATE_BATTERY_HEALTH_SHIFT = 26; 3437 static final int STATE_BATTERY_PLUG_MASK = 0x00000003; 3438 static final int STATE_BATTERY_PLUG_SHIFT = 24; 3439 3440 // We use the low bit of the battery state int to indicate that we have full details 3441 // from a battery level change. 3442 static final int BATTERY_DELTA_LEVEL_FLAG = 0x00000001; 3443 writeHistoryDelta(Parcel dest, HistoryItem cur, HistoryItem last)3444 public void writeHistoryDelta(Parcel dest, HistoryItem cur, HistoryItem last) { 3445 if (last == null || cur.cmd != HistoryItem.CMD_UPDATE) { 3446 dest.writeInt(DELTA_TIME_ABS); 3447 cur.writeToParcel(dest, 0); 3448 return; 3449 } 3450 3451 final long deltaTime = cur.time - last.time; 3452 final int lastBatteryLevelInt = buildBatteryLevelInt(last); 3453 final int lastStateInt = buildStateInt(last); 3454 3455 int deltaTimeToken; 3456 if (deltaTime < 0 || deltaTime > Integer.MAX_VALUE) { 3457 deltaTimeToken = DELTA_TIME_LONG; 3458 } else if (deltaTime >= DELTA_TIME_ABS) { 3459 deltaTimeToken = DELTA_TIME_INT; 3460 } else { 3461 deltaTimeToken = (int)deltaTime; 3462 } 3463 int firstToken = deltaTimeToken | (cur.states&DELTA_STATE_MASK); 3464 final int includeStepDetails = mLastHistoryStepLevel > cur.batteryLevel 3465 ? BATTERY_DELTA_LEVEL_FLAG : 0; 3466 final boolean computeStepDetails = includeStepDetails != 0 3467 || mLastHistoryStepDetails == null; 3468 final int batteryLevelInt = buildBatteryLevelInt(cur) | includeStepDetails; 3469 final boolean batteryLevelIntChanged = batteryLevelInt != lastBatteryLevelInt; 3470 if (batteryLevelIntChanged) { 3471 firstToken |= DELTA_BATTERY_LEVEL_FLAG; 3472 } 3473 final int stateInt = buildStateInt(cur); 3474 final boolean stateIntChanged = stateInt != lastStateInt; 3475 if (stateIntChanged) { 3476 firstToken |= DELTA_STATE_FLAG; 3477 } 3478 final boolean state2IntChanged = cur.states2 != last.states2; 3479 if (state2IntChanged) { 3480 firstToken |= DELTA_STATE2_FLAG; 3481 } 3482 if (cur.wakelockTag != null || cur.wakeReasonTag != null) { 3483 firstToken |= DELTA_WAKELOCK_FLAG; 3484 } 3485 if (cur.eventCode != HistoryItem.EVENT_NONE) { 3486 firstToken |= DELTA_EVENT_FLAG; 3487 } 3488 3489 final boolean batteryChargeChanged = cur.batteryChargeUah != last.batteryChargeUah; 3490 if (batteryChargeChanged) { 3491 firstToken |= DELTA_BATTERY_CHARGE_FLAG; 3492 } 3493 dest.writeInt(firstToken); 3494 if (DEBUG) Slog.i(TAG, "WRITE DELTA: firstToken=0x" + Integer.toHexString(firstToken) 3495 + " deltaTime=" + deltaTime); 3496 3497 if (deltaTimeToken >= DELTA_TIME_INT) { 3498 if (deltaTimeToken == DELTA_TIME_INT) { 3499 if (DEBUG) Slog.i(TAG, "WRITE DELTA: int deltaTime=" + (int)deltaTime); 3500 dest.writeInt((int)deltaTime); 3501 } else { 3502 if (DEBUG) Slog.i(TAG, "WRITE DELTA: long deltaTime=" + deltaTime); 3503 dest.writeLong(deltaTime); 3504 } 3505 } 3506 if (batteryLevelIntChanged) { 3507 dest.writeInt(batteryLevelInt); 3508 if (DEBUG) Slog.i(TAG, "WRITE DELTA: batteryToken=0x" 3509 + Integer.toHexString(batteryLevelInt) 3510 + " batteryLevel=" + cur.batteryLevel 3511 + " batteryTemp=" + cur.batteryTemperature 3512 + " batteryVolt=" + (int)cur.batteryVoltage); 3513 } 3514 if (stateIntChanged) { 3515 dest.writeInt(stateInt); 3516 if (DEBUG) Slog.i(TAG, "WRITE DELTA: stateToken=0x" 3517 + Integer.toHexString(stateInt) 3518 + " batteryStatus=" + cur.batteryStatus 3519 + " batteryHealth=" + cur.batteryHealth 3520 + " batteryPlugType=" + cur.batteryPlugType 3521 + " states=0x" + Integer.toHexString(cur.states)); 3522 } 3523 if (state2IntChanged) { 3524 dest.writeInt(cur.states2); 3525 if (DEBUG) Slog.i(TAG, "WRITE DELTA: states2=0x" 3526 + Integer.toHexString(cur.states2)); 3527 } 3528 if (cur.wakelockTag != null || cur.wakeReasonTag != null) { 3529 int wakeLockIndex; 3530 int wakeReasonIndex; 3531 if (cur.wakelockTag != null) { 3532 wakeLockIndex = writeHistoryTag(cur.wakelockTag); 3533 if (DEBUG) Slog.i(TAG, "WRITE DELTA: wakelockTag=#" + cur.wakelockTag.poolIdx 3534 + " " + cur.wakelockTag.uid + ":" + cur.wakelockTag.string); 3535 } else { 3536 wakeLockIndex = 0xffff; 3537 } 3538 if (cur.wakeReasonTag != null) { 3539 wakeReasonIndex = writeHistoryTag(cur.wakeReasonTag); 3540 if (DEBUG) Slog.i(TAG, "WRITE DELTA: wakeReasonTag=#" + cur.wakeReasonTag.poolIdx 3541 + " " + cur.wakeReasonTag.uid + ":" + cur.wakeReasonTag.string); 3542 } else { 3543 wakeReasonIndex = 0xffff; 3544 } 3545 dest.writeInt((wakeReasonIndex<<16) | wakeLockIndex); 3546 } 3547 if (cur.eventCode != HistoryItem.EVENT_NONE) { 3548 int index = writeHistoryTag(cur.eventTag); 3549 int codeAndIndex = (cur.eventCode&0xffff) | (index<<16); 3550 dest.writeInt(codeAndIndex); 3551 if (DEBUG) Slog.i(TAG, "WRITE DELTA: event=" + cur.eventCode + " tag=#" 3552 + cur.eventTag.poolIdx + " " + cur.eventTag.uid + ":" 3553 + cur.eventTag.string); 3554 } 3555 if (computeStepDetails) { 3556 if (mPlatformIdleStateCallback != null) { 3557 mCurHistoryStepDetails.statSubsystemPowerState = 3558 mPlatformIdleStateCallback.getSubsystemLowPowerStats(); 3559 if (DEBUG) Slog.i(TAG, "WRITE SubsystemPowerState:" + 3560 mCurHistoryStepDetails.statSubsystemPowerState); 3561 3562 } 3563 computeHistoryStepDetails(mCurHistoryStepDetails, mLastHistoryStepDetails); 3564 if (includeStepDetails != 0) { 3565 mCurHistoryStepDetails.writeToParcel(dest); 3566 } 3567 cur.stepDetails = mCurHistoryStepDetails; 3568 mLastHistoryStepDetails = mCurHistoryStepDetails; 3569 } else { 3570 cur.stepDetails = null; 3571 } 3572 if (mLastHistoryStepLevel < cur.batteryLevel) { 3573 mLastHistoryStepDetails = null; 3574 } 3575 mLastHistoryStepLevel = cur.batteryLevel; 3576 3577 if (batteryChargeChanged) { 3578 if (DEBUG) Slog.i(TAG, "WRITE DELTA: batteryChargeUah=" + cur.batteryChargeUah); 3579 dest.writeInt(cur.batteryChargeUah); 3580 } 3581 dest.writeDouble(cur.modemRailChargeMah); 3582 dest.writeDouble(cur.wifiRailChargeMah); 3583 } 3584 buildBatteryLevelInt(HistoryItem h)3585 private int buildBatteryLevelInt(HistoryItem h) { 3586 return ((((int)h.batteryLevel)<<25)&0xfe000000) 3587 | ((((int)h.batteryTemperature)<<15)&0x01ff8000) 3588 | ((((int)h.batteryVoltage)<<1)&0x00007ffe); 3589 } 3590 readBatteryLevelInt(int batteryLevelInt, HistoryItem out)3591 private void readBatteryLevelInt(int batteryLevelInt, HistoryItem out) { 3592 out.batteryLevel = (byte)((batteryLevelInt & 0xfe000000) >>> 25); 3593 out.batteryTemperature = (short)((batteryLevelInt & 0x01ff8000) >>> 15); 3594 out.batteryVoltage = (char)((batteryLevelInt & 0x00007ffe) >>> 1); 3595 } 3596 buildStateInt(HistoryItem h)3597 private int buildStateInt(HistoryItem h) { 3598 int plugType = 0; 3599 if ((h.batteryPlugType&BatteryManager.BATTERY_PLUGGED_AC) != 0) { 3600 plugType = 1; 3601 } else if ((h.batteryPlugType&BatteryManager.BATTERY_PLUGGED_USB) != 0) { 3602 plugType = 2; 3603 } else if ((h.batteryPlugType&BatteryManager.BATTERY_PLUGGED_WIRELESS) != 0) { 3604 plugType = 3; 3605 } 3606 return ((h.batteryStatus&STATE_BATTERY_STATUS_MASK)<<STATE_BATTERY_STATUS_SHIFT) 3607 | ((h.batteryHealth&STATE_BATTERY_HEALTH_MASK)<<STATE_BATTERY_HEALTH_SHIFT) 3608 | ((plugType&STATE_BATTERY_PLUG_MASK)<<STATE_BATTERY_PLUG_SHIFT) 3609 | (h.states&(~STATE_BATTERY_MASK)); 3610 } 3611 computeHistoryStepDetails(final HistoryStepDetails out, final HistoryStepDetails last)3612 private void computeHistoryStepDetails(final HistoryStepDetails out, 3613 final HistoryStepDetails last) { 3614 final HistoryStepDetails tmp = last != null ? mTmpHistoryStepDetails : out; 3615 3616 // Perform a CPU update right after we do this collection, so we have started 3617 // collecting good data for the next step. 3618 requestImmediateCpuUpdate(); 3619 3620 if (last == null) { 3621 // We are not generating a delta, so all we need to do is reset the stats 3622 // we will later be doing a delta from. 3623 final int NU = mUidStats.size(); 3624 for (int i=0; i<NU; i++) { 3625 final BatteryStatsImpl.Uid uid = mUidStats.valueAt(i); 3626 uid.mLastStepUserTimeMs = uid.mCurStepUserTimeMs; 3627 uid.mLastStepSystemTimeMs = uid.mCurStepSystemTimeMs; 3628 } 3629 mLastStepCpuUserTimeMs = mCurStepCpuUserTimeMs; 3630 mLastStepCpuSystemTimeMs = mCurStepCpuSystemTimeMs; 3631 mLastStepStatUserTimeMs = mCurStepStatUserTimeMs; 3632 mLastStepStatSystemTimeMs = mCurStepStatSystemTimeMs; 3633 mLastStepStatIOWaitTimeMs = mCurStepStatIOWaitTimeMs; 3634 mLastStepStatIrqTimeMs = mCurStepStatIrqTimeMs; 3635 mLastStepStatSoftIrqTimeMs = mCurStepStatSoftIrqTimeMs; 3636 mLastStepStatIdleTimeMs = mCurStepStatIdleTimeMs; 3637 tmp.clear(); 3638 return; 3639 } 3640 if (DEBUG) { 3641 Slog.d(TAG, "Step stats last: user=" + mLastStepCpuUserTimeMs + " sys=" 3642 + mLastStepStatSystemTimeMs + " io=" + mLastStepStatIOWaitTimeMs 3643 + " irq=" + mLastStepStatIrqTimeMs + " sirq=" 3644 + mLastStepStatSoftIrqTimeMs + " idle=" + mLastStepStatIdleTimeMs); 3645 Slog.d(TAG, "Step stats cur: user=" + mCurStepCpuUserTimeMs + " sys=" 3646 + mCurStepStatSystemTimeMs + " io=" + mCurStepStatIOWaitTimeMs 3647 + " irq=" + mCurStepStatIrqTimeMs + " sirq=" 3648 + mCurStepStatSoftIrqTimeMs + " idle=" + mCurStepStatIdleTimeMs); 3649 } 3650 out.userTime = (int) (mCurStepCpuUserTimeMs - mLastStepCpuUserTimeMs); 3651 out.systemTime = (int) (mCurStepCpuSystemTimeMs - mLastStepCpuSystemTimeMs); 3652 out.statUserTime = (int) (mCurStepStatUserTimeMs - mLastStepStatUserTimeMs); 3653 out.statSystemTime = (int) (mCurStepStatSystemTimeMs - mLastStepStatSystemTimeMs); 3654 out.statIOWaitTime = (int) (mCurStepStatIOWaitTimeMs - mLastStepStatIOWaitTimeMs); 3655 out.statIrqTime = (int) (mCurStepStatIrqTimeMs - mLastStepStatIrqTimeMs); 3656 out.statSoftIrqTime = (int) (mCurStepStatSoftIrqTimeMs - mLastStepStatSoftIrqTimeMs); 3657 out.statIdlTime = (int) (mCurStepStatIdleTimeMs - mLastStepStatIdleTimeMs); 3658 out.appCpuUid1 = out.appCpuUid2 = out.appCpuUid3 = -1; 3659 out.appCpuUTime1 = out.appCpuUTime2 = out.appCpuUTime3 = 0; 3660 out.appCpuSTime1 = out.appCpuSTime2 = out.appCpuSTime3 = 0; 3661 final int NU = mUidStats.size(); 3662 for (int i=0; i<NU; i++) { 3663 final BatteryStatsImpl.Uid uid = mUidStats.valueAt(i); 3664 final int totalUTimeMs = (int) (uid.mCurStepUserTimeMs - uid.mLastStepUserTimeMs); 3665 final int totalSTimeMs = (int) (uid.mCurStepSystemTimeMs - uid.mLastStepSystemTimeMs); 3666 final int totalTimeMs = totalUTimeMs + totalSTimeMs; 3667 uid.mLastStepUserTimeMs = uid.mCurStepUserTimeMs; 3668 uid.mLastStepSystemTimeMs = uid.mCurStepSystemTimeMs; 3669 if (totalTimeMs <= (out.appCpuUTime3 + out.appCpuSTime3)) { 3670 continue; 3671 } 3672 if (totalTimeMs <= (out.appCpuUTime2 + out.appCpuSTime2)) { 3673 out.appCpuUid3 = uid.mUid; 3674 out.appCpuUTime3 = totalUTimeMs; 3675 out.appCpuSTime3 = totalSTimeMs; 3676 } else { 3677 out.appCpuUid3 = out.appCpuUid2; 3678 out.appCpuUTime3 = out.appCpuUTime2; 3679 out.appCpuSTime3 = out.appCpuSTime2; 3680 if (totalTimeMs <= (out.appCpuUTime1 + out.appCpuSTime1)) { 3681 out.appCpuUid2 = uid.mUid; 3682 out.appCpuUTime2 = totalUTimeMs; 3683 out.appCpuSTime2 = totalSTimeMs; 3684 } else { 3685 out.appCpuUid2 = out.appCpuUid1; 3686 out.appCpuUTime2 = out.appCpuUTime1; 3687 out.appCpuSTime2 = out.appCpuSTime1; 3688 out.appCpuUid1 = uid.mUid; 3689 out.appCpuUTime1 = totalUTimeMs; 3690 out.appCpuSTime1 = totalSTimeMs; 3691 } 3692 } 3693 } 3694 mLastStepCpuUserTimeMs = mCurStepCpuUserTimeMs; 3695 mLastStepCpuSystemTimeMs = mCurStepCpuSystemTimeMs; 3696 mLastStepStatUserTimeMs = mCurStepStatUserTimeMs; 3697 mLastStepStatSystemTimeMs = mCurStepStatSystemTimeMs; 3698 mLastStepStatIOWaitTimeMs = mCurStepStatIOWaitTimeMs; 3699 mLastStepStatIrqTimeMs = mCurStepStatIrqTimeMs; 3700 mLastStepStatSoftIrqTimeMs = mCurStepStatSoftIrqTimeMs; 3701 mLastStepStatIdleTimeMs = mCurStepStatIdleTimeMs; 3702 } 3703 3704 @Override commitCurrentHistoryBatchLocked()3705 public void commitCurrentHistoryBatchLocked() { 3706 mHistoryLastWritten.cmd = HistoryItem.CMD_NULL; 3707 } 3708 createFakeHistoryEvents(long numEvents)3709 public void createFakeHistoryEvents(long numEvents) { 3710 final long elapsedRealtimeMs = mClocks.elapsedRealtime(); 3711 final long uptimeMs = mClocks.uptimeMillis(); 3712 for(long i = 0; i < numEvents; i++) { 3713 noteLongPartialWakelockStart("name1", "historyName1", 1000, 3714 elapsedRealtimeMs, uptimeMs); 3715 noteLongPartialWakelockFinish("name1", "historyName1", 1000, 3716 elapsedRealtimeMs, uptimeMs); 3717 } 3718 } 3719 addHistoryBufferLocked(long elapsedRealtimeMs, long uptimeMs, HistoryItem cur)3720 void addHistoryBufferLocked(long elapsedRealtimeMs, long uptimeMs, HistoryItem cur) { 3721 if (!mHaveBatteryLevel || !mRecordingHistory) { 3722 return; 3723 } 3724 3725 final long timeDiffMs = (mHistoryBaseTimeMs + elapsedRealtimeMs) - mHistoryLastWritten.time; 3726 final int diffStates = mHistoryLastWritten.states^(cur.states&mActiveHistoryStates); 3727 final int diffStates2 = mHistoryLastWritten.states2^(cur.states2&mActiveHistoryStates2); 3728 final int lastDiffStates = mHistoryLastWritten.states^mHistoryLastLastWritten.states; 3729 final int lastDiffStates2 = mHistoryLastWritten.states2^mHistoryLastLastWritten.states2; 3730 if (DEBUG) { 3731 Slog.i(TAG, "ADD: tdelta=" + timeDiffMs + " diff=" 3732 + Integer.toHexString(diffStates) + " lastDiff=" 3733 + Integer.toHexString(lastDiffStates) + " diff2=" 3734 + Integer.toHexString(diffStates2) + " lastDiff2=" 3735 + Integer.toHexString(lastDiffStates2)); 3736 } 3737 if (mHistoryBufferLastPos >= 0 && mHistoryLastWritten.cmd == HistoryItem.CMD_UPDATE 3738 && timeDiffMs < 1000 && (diffStates & lastDiffStates) == 0 3739 && (diffStates2&lastDiffStates2) == 0 3740 && (mHistoryLastWritten.wakelockTag == null || cur.wakelockTag == null) 3741 && (mHistoryLastWritten.wakeReasonTag == null || cur.wakeReasonTag == null) 3742 && mHistoryLastWritten.stepDetails == null 3743 && (mHistoryLastWritten.eventCode == HistoryItem.EVENT_NONE 3744 || cur.eventCode == HistoryItem.EVENT_NONE) 3745 && mHistoryLastWritten.batteryLevel == cur.batteryLevel 3746 && mHistoryLastWritten.batteryStatus == cur.batteryStatus 3747 && mHistoryLastWritten.batteryHealth == cur.batteryHealth 3748 && mHistoryLastWritten.batteryPlugType == cur.batteryPlugType 3749 && mHistoryLastWritten.batteryTemperature == cur.batteryTemperature 3750 && mHistoryLastWritten.batteryVoltage == cur.batteryVoltage) { 3751 // We can merge this new change in with the last one. Merging is 3752 // allowed as long as only the states have changed, and within those states 3753 // as long as no bit has changed both between now and the last entry, as 3754 // well as the last entry and the one before it (so we capture any toggles). 3755 if (DEBUG) Slog.i(TAG, "ADD: rewinding back to " + mHistoryBufferLastPos); 3756 mHistoryBuffer.setDataSize(mHistoryBufferLastPos); 3757 mHistoryBuffer.setDataPosition(mHistoryBufferLastPos); 3758 mHistoryBufferLastPos = -1; 3759 elapsedRealtimeMs = mHistoryLastWritten.time - mHistoryBaseTimeMs; 3760 // If the last written history had a wakelock tag, we need to retain it. 3761 // Note that the condition above made sure that we aren't in a case where 3762 // both it and the current history item have a wakelock tag. 3763 if (mHistoryLastWritten.wakelockTag != null) { 3764 cur.wakelockTag = cur.localWakelockTag; 3765 cur.wakelockTag.setTo(mHistoryLastWritten.wakelockTag); 3766 } 3767 // If the last written history had a wake reason tag, we need to retain it. 3768 // Note that the condition above made sure that we aren't in a case where 3769 // both it and the current history item have a wakelock tag. 3770 if (mHistoryLastWritten.wakeReasonTag != null) { 3771 cur.wakeReasonTag = cur.localWakeReasonTag; 3772 cur.wakeReasonTag.setTo(mHistoryLastWritten.wakeReasonTag); 3773 } 3774 // If the last written history had an event, we need to retain it. 3775 // Note that the condition above made sure that we aren't in a case where 3776 // both it and the current history item have an event. 3777 if (mHistoryLastWritten.eventCode != HistoryItem.EVENT_NONE) { 3778 cur.eventCode = mHistoryLastWritten.eventCode; 3779 cur.eventTag = cur.localEventTag; 3780 cur.eventTag.setTo(mHistoryLastWritten.eventTag); 3781 } 3782 mHistoryLastWritten.setTo(mHistoryLastLastWritten); 3783 } 3784 final int dataSize = mHistoryBuffer.dataSize(); 3785 3786 if (dataSize >= mConstants.MAX_HISTORY_BUFFER) { 3787 //open a new history file. 3788 final long start = SystemClock.uptimeMillis(); 3789 writeHistoryLocked(true); 3790 if (DEBUG) { 3791 Slog.d(TAG, "addHistoryBufferLocked writeHistoryLocked takes ms:" 3792 + (SystemClock.uptimeMillis() - start)); 3793 } 3794 mBatteryStatsHistory.startNextFile(); 3795 mHistoryBuffer.setDataSize(0); 3796 mHistoryBuffer.setDataPosition(0); 3797 mHistoryBuffer.setDataCapacity(mConstants.MAX_HISTORY_BUFFER / 2); 3798 mHistoryBufferLastPos = -1; 3799 HistoryItem newItem = new HistoryItem(); 3800 newItem.setTo(cur); 3801 startRecordingHistory(elapsedRealtimeMs, uptimeMs, false); 3802 addHistoryBufferLocked(elapsedRealtimeMs, HistoryItem.CMD_UPDATE, newItem); 3803 return; 3804 } 3805 3806 if (dataSize == 0) { 3807 // The history is currently empty; we need it to start with a time stamp. 3808 cur.currentTime = mClocks.currentTimeMillis(); 3809 addHistoryBufferLocked(elapsedRealtimeMs, HistoryItem.CMD_RESET, cur); 3810 } 3811 addHistoryBufferLocked(elapsedRealtimeMs, HistoryItem.CMD_UPDATE, cur); 3812 } 3813 addHistoryBufferLocked(long elapsedRealtimeMs, byte cmd, HistoryItem cur)3814 private void addHistoryBufferLocked(long elapsedRealtimeMs, byte cmd, HistoryItem cur) { 3815 if (mBatteryStatsHistoryIterator != null) { 3816 throw new IllegalStateException("Can't do this while iterating history!"); 3817 } 3818 mHistoryBufferLastPos = mHistoryBuffer.dataPosition(); 3819 mHistoryLastLastWritten.setTo(mHistoryLastWritten); 3820 mHistoryLastWritten.setTo(mHistoryBaseTimeMs + elapsedRealtimeMs, cmd, cur); 3821 mHistoryLastWritten.states &= mActiveHistoryStates; 3822 mHistoryLastWritten.states2 &= mActiveHistoryStates2; 3823 writeHistoryDelta(mHistoryBuffer, mHistoryLastWritten, mHistoryLastLastWritten); 3824 mLastHistoryElapsedRealtimeMs = elapsedRealtimeMs; 3825 cur.wakelockTag = null; 3826 cur.wakeReasonTag = null; 3827 cur.eventCode = HistoryItem.EVENT_NONE; 3828 cur.eventTag = null; 3829 if (DEBUG_HISTORY) Slog.i(TAG, "Writing history buffer: was " + mHistoryBufferLastPos 3830 + " now " + mHistoryBuffer.dataPosition() 3831 + " size is now " + mHistoryBuffer.dataSize()); 3832 } 3833 3834 int mChangedStates = 0; 3835 int mChangedStates2 = 0; 3836 addHistoryRecordLocked(long elapsedRealtimeMs, long uptimeMs)3837 void addHistoryRecordLocked(long elapsedRealtimeMs, long uptimeMs) { 3838 if (mTrackRunningHistoryElapsedRealtimeMs != 0) { 3839 final long diffElapsedMs = elapsedRealtimeMs - mTrackRunningHistoryElapsedRealtimeMs; 3840 final long diffUptimeMs = uptimeMs - mTrackRunningHistoryUptimeMs; 3841 if (diffUptimeMs < (diffElapsedMs - 20)) { 3842 final long wakeElapsedTimeMs = elapsedRealtimeMs - (diffElapsedMs - diffUptimeMs); 3843 mHistoryAddTmp.setTo(mHistoryLastWritten); 3844 mHistoryAddTmp.wakelockTag = null; 3845 mHistoryAddTmp.wakeReasonTag = null; 3846 mHistoryAddTmp.eventCode = HistoryItem.EVENT_NONE; 3847 mHistoryAddTmp.states &= ~HistoryItem.STATE_CPU_RUNNING_FLAG; 3848 addHistoryRecordInnerLocked(wakeElapsedTimeMs, uptimeMs, mHistoryAddTmp); 3849 } 3850 } 3851 mHistoryCur.states |= HistoryItem.STATE_CPU_RUNNING_FLAG; 3852 mTrackRunningHistoryElapsedRealtimeMs = elapsedRealtimeMs; 3853 mTrackRunningHistoryUptimeMs = uptimeMs; 3854 addHistoryRecordInnerLocked(elapsedRealtimeMs, uptimeMs, mHistoryCur); 3855 } 3856 addHistoryRecordInnerLocked(long elapsedRealtimeMs, long uptimeMs, HistoryItem cur)3857 void addHistoryRecordInnerLocked(long elapsedRealtimeMs, long uptimeMs, HistoryItem cur) { 3858 addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, cur); 3859 } 3860 addHistoryEventLocked(long elapsedRealtimeMs, long uptimeMs, int code, String name, int uid)3861 public void addHistoryEventLocked(long elapsedRealtimeMs, long uptimeMs, int code, 3862 String name, int uid) { 3863 mHistoryCur.eventCode = code; 3864 mHistoryCur.eventTag = mHistoryCur.localEventTag; 3865 mHistoryCur.eventTag.string = name; 3866 mHistoryCur.eventTag.uid = uid; 3867 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 3868 } 3869 addHistoryRecordLocked(long elapsedRealtimeMs, long uptimeMs, byte cmd, HistoryItem cur)3870 void addHistoryRecordLocked(long elapsedRealtimeMs, long uptimeMs, byte cmd, HistoryItem cur) { 3871 HistoryItem rec = mHistoryCache; 3872 if (rec != null) { 3873 mHistoryCache = rec.next; 3874 } else { 3875 rec = new HistoryItem(); 3876 } 3877 rec.setTo(mHistoryBaseTimeMs + elapsedRealtimeMs, cmd, cur); 3878 3879 addHistoryRecordLocked(rec); 3880 } 3881 addHistoryRecordLocked(HistoryItem rec)3882 void addHistoryRecordLocked(HistoryItem rec) { 3883 mNumHistoryItems++; 3884 rec.next = null; 3885 mHistoryLastEnd = mHistoryEnd; 3886 if (mHistoryEnd != null) { 3887 mHistoryEnd.next = rec; 3888 mHistoryEnd = rec; 3889 } else { 3890 mHistory = mHistoryEnd = rec; 3891 } 3892 } 3893 clearHistoryLocked()3894 void clearHistoryLocked() { 3895 if (DEBUG_HISTORY) Slog.i(TAG, "********** CLEARING HISTORY!"); 3896 mHistoryBaseTimeMs = 0; 3897 mLastHistoryElapsedRealtimeMs = 0; 3898 mTrackRunningHistoryElapsedRealtimeMs = 0; 3899 mTrackRunningHistoryUptimeMs = 0; 3900 3901 mHistoryBuffer.setDataSize(0); 3902 mHistoryBuffer.setDataPosition(0); 3903 mHistoryBuffer.setDataCapacity(mConstants.MAX_HISTORY_BUFFER / 2); 3904 mHistoryLastLastWritten.clear(); 3905 mHistoryLastWritten.clear(); 3906 mHistoryTagPool.clear(); 3907 mNextHistoryTagIdx = 0; 3908 mNumHistoryTagChars = 0; 3909 mHistoryBufferLastPos = -1; 3910 mActiveHistoryStates = 0xffffffff; 3911 mActiveHistoryStates2 = 0xffffffff; 3912 } 3913 3914 @GuardedBy("this") updateTimeBasesLocked(boolean unplugged, int screenState, long uptimeUs, long realtimeUs)3915 public void updateTimeBasesLocked(boolean unplugged, int screenState, long uptimeUs, 3916 long realtimeUs) { 3917 final boolean screenOff = !Display.isOnState(screenState); 3918 final boolean updateOnBatteryTimeBase = unplugged != mOnBatteryTimeBase.isRunning(); 3919 final boolean updateOnBatteryScreenOffTimeBase = 3920 (unplugged && screenOff) != mOnBatteryScreenOffTimeBase.isRunning(); 3921 3922 if (updateOnBatteryScreenOffTimeBase || updateOnBatteryTimeBase) { 3923 if (updateOnBatteryScreenOffTimeBase) { 3924 updateKernelWakelocksLocked(realtimeUs); 3925 updateBatteryPropertiesLocked(); 3926 } 3927 // This if{} is only necessary due to SCREEN_OFF_RPM_STATS_ENABLED, which exists because 3928 // updateRpmStatsLocked is too slow to run each screen change. When the speed is 3929 // improved, remove the surrounding if{}. 3930 if (SCREEN_OFF_RPM_STATS_ENABLED || updateOnBatteryTimeBase) { 3931 // if either OnBattery or OnBatteryScreenOfftimebase changes. 3932 updateRpmStatsLocked(realtimeUs); 3933 } 3934 if (DEBUG_ENERGY_CPU) { 3935 Slog.d(TAG, "Updating cpu time because screen is now " 3936 + Display.stateToString(screenState) 3937 + " and battery is " + (unplugged ? "on" : "off")); 3938 } 3939 3940 mOnBatteryTimeBase.setRunning(unplugged, uptimeUs, realtimeUs); 3941 if (updateOnBatteryTimeBase) { 3942 for (int i = mUidStats.size() - 1; i >= 0; --i) { 3943 mUidStats.valueAt(i).updateOnBatteryBgTimeBase(uptimeUs, realtimeUs); 3944 } 3945 } 3946 if (updateOnBatteryScreenOffTimeBase) { 3947 mOnBatteryScreenOffTimeBase.setRunning(unplugged && screenOff, 3948 uptimeUs, realtimeUs); 3949 for (int i = mUidStats.size() - 1; i >= 0; --i) { 3950 mUidStats.valueAt(i).updateOnBatteryScreenOffBgTimeBase(uptimeUs, realtimeUs); 3951 } 3952 } 3953 } 3954 } 3955 updateBatteryPropertiesLocked()3956 private void updateBatteryPropertiesLocked() { 3957 try { 3958 IBatteryPropertiesRegistrar registrar = IBatteryPropertiesRegistrar.Stub.asInterface( 3959 ServiceManager.getService("batteryproperties")); 3960 if (registrar != null) { 3961 registrar.scheduleUpdate(); 3962 } 3963 } catch (RemoteException e) { 3964 // Ignore. 3965 } 3966 } 3967 addIsolatedUidLocked(int isolatedUid, int appUid)3968 public void addIsolatedUidLocked(int isolatedUid, int appUid) { 3969 addIsolatedUidLocked(isolatedUid, appUid, 3970 mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 3971 } 3972 addIsolatedUidLocked(int isolatedUid, int appUid, long elapsedRealtimeMs, long uptimeMs)3973 public void addIsolatedUidLocked(int isolatedUid, int appUid, 3974 long elapsedRealtimeMs, long uptimeMs) { 3975 mIsolatedUids.put(isolatedUid, appUid); 3976 mIsolatedUidRefCounts.put(isolatedUid, 1); 3977 final Uid u = getUidStatsLocked(appUid, elapsedRealtimeMs, uptimeMs); 3978 u.addIsolatedUid(isolatedUid); 3979 } 3980 3981 /** 3982 * Schedules a read of the latest cpu times before removing the isolated UID. 3983 * @see #removeIsolatedUidLocked(int, int, int) 3984 */ scheduleRemoveIsolatedUidLocked(int isolatedUid, int appUid)3985 public void scheduleRemoveIsolatedUidLocked(int isolatedUid, int appUid) { 3986 int curUid = mIsolatedUids.get(isolatedUid, -1); 3987 if (curUid == appUid) { 3988 if (mExternalSync != null) { 3989 mExternalSync.scheduleCpuSyncDueToRemovedUid(isolatedUid); 3990 } 3991 } 3992 } 3993 3994 /** 3995 * Isolated uid should only be removed after all wakelocks associated with the uid are stopped 3996 * and the cpu time-in-state has been read one last time for the uid. 3997 * 3998 * @see #scheduleRemoveIsolatedUidLocked(int, int) 3999 * 4000 * @return true if the isolated uid is actually removed. 4001 */ 4002 @GuardedBy("this") maybeRemoveIsolatedUidLocked(int isolatedUid, long elapsedRealtimeMs, long uptimeMs)4003 public boolean maybeRemoveIsolatedUidLocked(int isolatedUid, long elapsedRealtimeMs, 4004 long uptimeMs) { 4005 final int refCount = mIsolatedUidRefCounts.get(isolatedUid, 0) - 1; 4006 if (refCount > 0) { 4007 // Isolated uid is still being tracked 4008 mIsolatedUidRefCounts.put(isolatedUid, refCount); 4009 return false; 4010 } 4011 4012 final int idx = mIsolatedUids.indexOfKey(isolatedUid); 4013 if (idx >= 0) { 4014 final int ownerUid = mIsolatedUids.valueAt(idx); 4015 final Uid u = getUidStatsLocked(ownerUid, elapsedRealtimeMs, uptimeMs); 4016 u.removeIsolatedUid(isolatedUid); 4017 mIsolatedUids.removeAt(idx); 4018 mIsolatedUidRefCounts.delete(isolatedUid); 4019 } else { 4020 Slog.w(TAG, "Attempted to remove untracked isolated uid (" + isolatedUid + ")"); 4021 } 4022 mPendingRemovedUids.add(new UidToRemove(isolatedUid, elapsedRealtimeMs)); 4023 4024 return true; 4025 } 4026 4027 /** 4028 * Increment the ref count for an isolated uid. 4029 * call #maybeRemoveIsolatedUidLocked to decrement. 4030 */ incrementIsolatedUidRefCount(int uid)4031 public void incrementIsolatedUidRefCount(int uid) { 4032 final int refCount = mIsolatedUidRefCounts.get(uid, 0); 4033 if (refCount <= 0) { 4034 // Uid is not mapped or referenced 4035 Slog.w(TAG, 4036 "Attempted to increment ref counted of untracked isolated uid (" + uid + ")"); 4037 return; 4038 } 4039 mIsolatedUidRefCounts.put(uid, refCount + 1); 4040 } 4041 mapUid(int uid)4042 public int mapUid(int uid) { 4043 int isolated = mIsolatedUids.get(uid, -1); 4044 return isolated > 0 ? isolated : uid; 4045 } 4046 noteEventLocked(int code, String name, int uid)4047 public void noteEventLocked(int code, String name, int uid) { 4048 noteEventLocked(code, name, uid, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 4049 } 4050 noteEventLocked(int code, String name, int uid, long elapsedRealtimeMs, long uptimeMs)4051 public void noteEventLocked(int code, String name, int uid, 4052 long elapsedRealtimeMs, long uptimeMs) { 4053 uid = mapUid(uid); 4054 if (!mActiveEvents.updateState(code, name, uid, 0)) { 4055 return; 4056 } 4057 addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, code, name, uid); 4058 } 4059 noteCurrentTimeChangedLocked()4060 public void noteCurrentTimeChangedLocked() { 4061 final long currentTime = mClocks.currentTimeMillis(); 4062 final long elapsedRealtime = mClocks.elapsedRealtime(); 4063 final long uptime = mClocks.uptimeMillis(); 4064 noteCurrentTimeChangedLocked(currentTime, elapsedRealtime, uptime); 4065 } 4066 noteCurrentTimeChangedLocked(long currentTimeMs, long elapsedRealtimeMs, long uptimeMs)4067 public void noteCurrentTimeChangedLocked(long currentTimeMs, 4068 long elapsedRealtimeMs, long uptimeMs) { 4069 recordCurrentTimeChangeLocked(currentTimeMs, elapsedRealtimeMs, uptimeMs); 4070 } 4071 noteProcessStartLocked(String name, int uid)4072 public void noteProcessStartLocked(String name, int uid) { 4073 noteProcessStartLocked(name, uid, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 4074 } 4075 noteProcessStartLocked(String name, int uid, long elapsedRealtimeMs, long uptimeMs)4076 public void noteProcessStartLocked(String name, int uid, 4077 long elapsedRealtimeMs, long uptimeMs) { 4078 uid = mapUid(uid); 4079 if (isOnBattery()) { 4080 Uid u = getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs); 4081 u.getProcessStatsLocked(name).incStartsLocked(); 4082 } 4083 if (!mActiveEvents.updateState(HistoryItem.EVENT_PROC_START, name, uid, 0)) { 4084 return; 4085 } 4086 if (!mRecordAllHistory) { 4087 return; 4088 } 4089 addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_PROC_START, name, uid); 4090 } 4091 noteProcessCrashLocked(String name, int uid)4092 public void noteProcessCrashLocked(String name, int uid) { 4093 noteProcessCrashLocked(name, uid, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 4094 } 4095 noteProcessCrashLocked(String name, int uid, long elapsedRealtimeMs, long uptimeMs)4096 public void noteProcessCrashLocked(String name, int uid, 4097 long elapsedRealtimeMs, long uptimeMs) { 4098 uid = mapUid(uid); 4099 if (isOnBattery()) { 4100 Uid u = getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs); 4101 u.getProcessStatsLocked(name).incNumCrashesLocked(); 4102 } 4103 } 4104 noteProcessAnrLocked(String name, int uid)4105 public void noteProcessAnrLocked(String name, int uid) { 4106 noteProcessAnrLocked(name, uid, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 4107 } 4108 noteProcessAnrLocked(String name, int uid, long elapsedRealtimeMs, long uptimeMs)4109 public void noteProcessAnrLocked(String name, int uid, long elapsedRealtimeMs, long uptimeMs) { 4110 uid = mapUid(uid); 4111 if (isOnBattery()) { 4112 Uid u = getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs); 4113 u.getProcessStatsLocked(name).incNumAnrsLocked(); 4114 } 4115 } 4116 noteUidProcessStateLocked(int uid, int state)4117 public void noteUidProcessStateLocked(int uid, int state) { 4118 noteUidProcessStateLocked(uid, state, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 4119 } 4120 noteUidProcessStateLocked(int uid, int state, long elapsedRealtimeMs, long uptimeMs)4121 public void noteUidProcessStateLocked(int uid, int state, 4122 long elapsedRealtimeMs, long uptimeMs) { 4123 int parentUid = mapUid(uid); 4124 if (uid != parentUid) { 4125 // Isolated UIDs process state is already rolled up into parent, so no need to track 4126 // Otherwise the parent's process state will get downgraded incorrectly 4127 return; 4128 } 4129 // TODO(b/155216561): It is possible for isolated uids to be in a higher 4130 // state than its parent uid. We should track the highest state within the union of host 4131 // and isolated uids rather than only the parent uid. 4132 FrameworkStatsLog.write(FrameworkStatsLog.UID_PROCESS_STATE_CHANGED, uid, 4133 ActivityManager.processStateAmToProto(state)); 4134 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 4135 .updateUidProcessStateLocked(state, elapsedRealtimeMs, uptimeMs); 4136 } 4137 noteProcessFinishLocked(String name, int uid)4138 public void noteProcessFinishLocked(String name, int uid) { 4139 noteProcessFinishLocked(name, uid, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 4140 } 4141 noteProcessFinishLocked(String name, int uid, long elapsedRealtimeMs, long uptimeMs)4142 public void noteProcessFinishLocked(String name, int uid, 4143 long elapsedRealtimeMs, long uptimeMs) { 4144 uid = mapUid(uid); 4145 if (!mActiveEvents.updateState(HistoryItem.EVENT_PROC_FINISH, name, uid, 0)) { 4146 return; 4147 } 4148 if (!mRecordAllHistory) { 4149 return; 4150 } 4151 addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_PROC_FINISH, 4152 name, uid); 4153 } 4154 noteSyncStartLocked(String name, int uid)4155 public void noteSyncStartLocked(String name, int uid) { 4156 noteSyncStartLocked(name, uid, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 4157 } 4158 noteSyncStartLocked(String name, int uid, long elapsedRealtimeMs, long uptimeMs)4159 public void noteSyncStartLocked(String name, int uid, long elapsedRealtimeMs, long uptimeMs) { 4160 uid = mapUid(uid); 4161 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 4162 .noteStartSyncLocked(name, elapsedRealtimeMs); 4163 if (!mActiveEvents.updateState(HistoryItem.EVENT_SYNC_START, name, uid, 0)) { 4164 return; 4165 } 4166 addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_SYNC_START, name, uid); 4167 } 4168 noteSyncFinishLocked(String name, int uid)4169 public void noteSyncFinishLocked(String name, int uid) { 4170 noteSyncFinishLocked(name, uid, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 4171 } 4172 noteSyncFinishLocked(String name, int uid, long elapsedRealtimeMs, long uptimeMs)4173 public void noteSyncFinishLocked(String name, int uid, long elapsedRealtimeMs, long uptimeMs) { 4174 uid = mapUid(uid); 4175 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 4176 .noteStopSyncLocked(name, elapsedRealtimeMs); 4177 if (!mActiveEvents.updateState(HistoryItem.EVENT_SYNC_FINISH, name, uid, 0)) { 4178 return; 4179 } 4180 addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_SYNC_FINISH, 4181 name, uid); 4182 } 4183 noteJobStartLocked(String name, int uid)4184 public void noteJobStartLocked(String name, int uid) { 4185 noteJobStartLocked(name, uid, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 4186 } 4187 noteJobStartLocked(String name, int uid, long elapsedRealtimeMs, long uptimeMs)4188 public void noteJobStartLocked(String name, int uid, long elapsedRealtimeMs, long uptimeMs) { 4189 uid = mapUid(uid); 4190 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 4191 .noteStartJobLocked(name, elapsedRealtimeMs); 4192 if (!mActiveEvents.updateState(HistoryItem.EVENT_JOB_START, name, uid, 0)) { 4193 return; 4194 } 4195 addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_JOB_START, name, uid); 4196 } 4197 noteJobFinishLocked(String name, int uid, int stopReason)4198 public void noteJobFinishLocked(String name, int uid, int stopReason) { 4199 noteJobFinishLocked(name, uid, stopReason, 4200 mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 4201 } 4202 noteJobFinishLocked(String name, int uid, int stopReason, long elapsedRealtimeMs, long uptimeMs)4203 public void noteJobFinishLocked(String name, int uid, int stopReason, 4204 long elapsedRealtimeMs, long uptimeMs) { 4205 uid = mapUid(uid); 4206 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 4207 .noteStopJobLocked(name, elapsedRealtimeMs, stopReason); 4208 if (!mActiveEvents.updateState(HistoryItem.EVENT_JOB_FINISH, name, uid, 0)) { 4209 return; 4210 } 4211 addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_JOB_FINISH, name, uid); 4212 } 4213 noteJobsDeferredLocked(int uid, int numDeferred, long sinceLast)4214 public void noteJobsDeferredLocked(int uid, int numDeferred, long sinceLast) { 4215 noteJobsDeferredLocked(uid, numDeferred, sinceLast, 4216 mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 4217 } 4218 noteJobsDeferredLocked(int uid, int numDeferred, long sinceLast, long elapsedRealtimeMs, long uptimeMs)4219 public void noteJobsDeferredLocked(int uid, int numDeferred, long sinceLast, 4220 long elapsedRealtimeMs, long uptimeMs) { 4221 uid = mapUid(uid); 4222 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 4223 .noteJobsDeferredLocked(numDeferred, sinceLast); 4224 } 4225 noteAlarmStartLocked(String name, WorkSource workSource, int uid)4226 public void noteAlarmStartLocked(String name, WorkSource workSource, int uid) { 4227 noteAlarmStartLocked(name, workSource, uid, 4228 mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 4229 } 4230 noteAlarmStartLocked(String name, WorkSource workSource, int uid, long elapsedRealtimeMs, long uptimeMs)4231 public void noteAlarmStartLocked(String name, WorkSource workSource, int uid, 4232 long elapsedRealtimeMs, long uptimeMs) { 4233 noteAlarmStartOrFinishLocked(HistoryItem.EVENT_ALARM_START, name, workSource, uid, 4234 elapsedRealtimeMs, uptimeMs); 4235 } 4236 noteAlarmFinishLocked(String name, WorkSource workSource, int uid)4237 public void noteAlarmFinishLocked(String name, WorkSource workSource, int uid) { 4238 noteAlarmFinishLocked(name, workSource, uid, 4239 mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 4240 } 4241 noteAlarmFinishLocked(String name, WorkSource workSource, int uid, long elapsedRealtimeMs, long uptimeMs)4242 public void noteAlarmFinishLocked(String name, WorkSource workSource, int uid, 4243 long elapsedRealtimeMs, long uptimeMs) { 4244 noteAlarmStartOrFinishLocked(HistoryItem.EVENT_ALARM_FINISH, name, workSource, uid, 4245 elapsedRealtimeMs, uptimeMs); 4246 } 4247 noteAlarmStartOrFinishLocked(int historyItem, String name, WorkSource workSource, int uid)4248 private void noteAlarmStartOrFinishLocked(int historyItem, String name, WorkSource workSource, 4249 int uid) { 4250 noteAlarmStartOrFinishLocked(historyItem, name, workSource, uid, 4251 mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 4252 } 4253 noteAlarmStartOrFinishLocked(int historyItem, String name, WorkSource workSource, int uid, long elapsedRealtimeMs, long uptimeMs)4254 private void noteAlarmStartOrFinishLocked(int historyItem, String name, WorkSource workSource, 4255 int uid, long elapsedRealtimeMs, long uptimeMs) { 4256 if (!mRecordAllHistory) { 4257 return; 4258 } 4259 4260 if (workSource != null) { 4261 for (int i = 0; i < workSource.size(); ++i) { 4262 uid = mapUid(workSource.getUid(i)); 4263 if (mActiveEvents.updateState(historyItem, name, uid, 0)) { 4264 addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, historyItem, name, uid); 4265 } 4266 } 4267 4268 List<WorkChain> workChains = workSource.getWorkChains(); 4269 if (workChains != null) { 4270 for (int i = 0; i < workChains.size(); ++i) { 4271 uid = mapUid(workChains.get(i).getAttributionUid()); 4272 if (mActiveEvents.updateState(historyItem, name, uid, 0)) { 4273 addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, historyItem, name, uid); 4274 } 4275 } 4276 } 4277 } else { 4278 uid = mapUid(uid); 4279 4280 if (mActiveEvents.updateState(historyItem, name, uid, 0)) { 4281 addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, historyItem, name, uid); 4282 } 4283 } 4284 } 4285 noteWakupAlarmLocked(String packageName, int uid, WorkSource workSource, String tag)4286 public void noteWakupAlarmLocked(String packageName, int uid, WorkSource workSource, 4287 String tag) { 4288 noteWakupAlarmLocked(packageName, uid, workSource, tag, 4289 mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 4290 } 4291 noteWakupAlarmLocked(String packageName, int uid, WorkSource workSource, String tag, long elapsedRealtimeMs, long uptimeMs)4292 public void noteWakupAlarmLocked(String packageName, int uid, WorkSource workSource, 4293 String tag, long elapsedRealtimeMs, long uptimeMs) { 4294 if (workSource != null) { 4295 for (int i = 0; i < workSource.size(); ++i) { 4296 uid = workSource.getUid(i); 4297 final String workSourceName = workSource.getPackageName(i); 4298 4299 if (isOnBattery()) { 4300 BatteryStatsImpl.Uid.Pkg pkg = getPackageStatsLocked(uid, 4301 workSourceName != null ? workSourceName : packageName, 4302 elapsedRealtimeMs, uptimeMs); 4303 pkg.noteWakeupAlarmLocked(tag); 4304 } 4305 } 4306 4307 List<WorkChain> workChains = workSource.getWorkChains(); 4308 if (workChains != null) { 4309 for (int i = 0; i < workChains.size(); ++i) { 4310 final WorkChain wc = workChains.get(i); 4311 uid = wc.getAttributionUid(); 4312 4313 if (isOnBattery()) { 4314 BatteryStatsImpl.Uid.Pkg pkg = getPackageStatsLocked(uid, packageName, 4315 elapsedRealtimeMs, uptimeMs); 4316 pkg.noteWakeupAlarmLocked(tag); 4317 } 4318 } 4319 } 4320 } else { 4321 if (isOnBattery()) { 4322 BatteryStatsImpl.Uid.Pkg pkg = getPackageStatsLocked(uid, packageName, 4323 elapsedRealtimeMs, uptimeMs); 4324 pkg.noteWakeupAlarmLocked(tag); 4325 } 4326 } 4327 } 4328 requestWakelockCpuUpdate()4329 private void requestWakelockCpuUpdate() { 4330 mExternalSync.scheduleCpuSyncDueToWakelockChange(DELAY_UPDATE_WAKELOCKS); 4331 } 4332 requestImmediateCpuUpdate()4333 private void requestImmediateCpuUpdate() { 4334 mExternalSync.scheduleCpuSyncDueToWakelockChange(0 /* delayMillis */); 4335 } 4336 setRecordAllHistoryLocked(boolean enabled)4337 public void setRecordAllHistoryLocked(boolean enabled) { 4338 mRecordAllHistory = enabled; 4339 if (!enabled) { 4340 // Clear out any existing state. 4341 mActiveEvents.removeEvents(HistoryItem.EVENT_WAKE_LOCK); 4342 mActiveEvents.removeEvents(HistoryItem.EVENT_ALARM); 4343 // Record the currently running processes as stopping, now that we are no 4344 // longer tracking them. 4345 HashMap<String, SparseIntArray> active = mActiveEvents.getStateForEvent( 4346 HistoryItem.EVENT_PROC); 4347 if (active != null) { 4348 long mSecRealtime = mClocks.elapsedRealtime(); 4349 final long mSecUptime = mClocks.uptimeMillis(); 4350 for (HashMap.Entry<String, SparseIntArray> ent : active.entrySet()) { 4351 SparseIntArray uids = ent.getValue(); 4352 for (int j=0; j<uids.size(); j++) { 4353 addHistoryEventLocked(mSecRealtime, mSecUptime, 4354 HistoryItem.EVENT_PROC_FINISH, ent.getKey(), uids.keyAt(j)); 4355 } 4356 } 4357 } 4358 } else { 4359 // Record the currently running processes as starting, now that we are tracking them. 4360 HashMap<String, SparseIntArray> active = mActiveEvents.getStateForEvent( 4361 HistoryItem.EVENT_PROC); 4362 if (active != null) { 4363 long mSecRealtime = mClocks.elapsedRealtime(); 4364 final long mSecUptime = mClocks.uptimeMillis(); 4365 for (HashMap.Entry<String, SparseIntArray> ent : active.entrySet()) { 4366 SparseIntArray uids = ent.getValue(); 4367 for (int j=0; j<uids.size(); j++) { 4368 addHistoryEventLocked(mSecRealtime, mSecUptime, 4369 HistoryItem.EVENT_PROC_START, ent.getKey(), uids.keyAt(j)); 4370 } 4371 } 4372 } 4373 } 4374 } 4375 setNoAutoReset(boolean enabled)4376 public void setNoAutoReset(boolean enabled) { 4377 mNoAutoReset = enabled; 4378 } 4379 setPretendScreenOff(boolean pretendScreenOff)4380 public void setPretendScreenOff(boolean pretendScreenOff) { 4381 if (mPretendScreenOff != pretendScreenOff) { 4382 mPretendScreenOff = pretendScreenOff; 4383 final int primaryScreenState = mPerDisplayBatteryStats[0].screenState; 4384 noteScreenStateLocked(0, primaryScreenState, 4385 mClocks.elapsedRealtime(), mClocks.uptimeMillis(), 4386 mClocks.currentTimeMillis()); 4387 } 4388 } 4389 4390 private String mInitialAcquireWakeName; 4391 private int mInitialAcquireWakeUid = -1; 4392 noteStartWakeLocked(int uid, int pid, WorkChain wc, String name, String historyName, int type, boolean unimportantForLogging)4393 public void noteStartWakeLocked(int uid, int pid, WorkChain wc, String name, String historyName, 4394 int type, boolean unimportantForLogging) { 4395 noteStartWakeLocked(uid, pid, wc, name, historyName, type, unimportantForLogging, 4396 mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 4397 } 4398 noteStartWakeLocked(int uid, int pid, WorkChain wc, String name, String historyName, int type, boolean unimportantForLogging, long elapsedRealtimeMs, long uptimeMs)4399 public void noteStartWakeLocked(int uid, int pid, WorkChain wc, String name, String historyName, 4400 int type, boolean unimportantForLogging, long elapsedRealtimeMs, long uptimeMs) { 4401 final int mappedUid = mapUid(uid); 4402 if (type == WAKE_TYPE_PARTIAL) { 4403 // Only care about partial wake locks, since full wake locks 4404 // will be canceled when the user puts the screen to sleep. 4405 aggregateLastWakeupUptimeLocked(elapsedRealtimeMs, uptimeMs); 4406 if (historyName == null) { 4407 historyName = name; 4408 } 4409 if (mRecordAllHistory) { 4410 if (mActiveEvents.updateState(HistoryItem.EVENT_WAKE_LOCK_START, historyName, 4411 mappedUid, 0)) { 4412 addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, 4413 HistoryItem.EVENT_WAKE_LOCK_START, historyName, mappedUid); 4414 } 4415 } 4416 if (mWakeLockNesting == 0) { 4417 mHistoryCur.states |= HistoryItem.STATE_WAKE_LOCK_FLAG; 4418 if (DEBUG_HISTORY) Slog.v(TAG, "Start wake lock to: " 4419 + Integer.toHexString(mHistoryCur.states)); 4420 mHistoryCur.wakelockTag = mHistoryCur.localWakelockTag; 4421 mHistoryCur.wakelockTag.string = mInitialAcquireWakeName = historyName; 4422 mHistoryCur.wakelockTag.uid = mInitialAcquireWakeUid = mappedUid; 4423 mWakeLockImportant = !unimportantForLogging; 4424 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 4425 } else if (!mWakeLockImportant && !unimportantForLogging 4426 && mHistoryLastWritten.cmd == HistoryItem.CMD_UPDATE) { 4427 if (mHistoryLastWritten.wakelockTag != null) { 4428 // We'll try to update the last tag. 4429 mHistoryLastWritten.wakelockTag = null; 4430 mHistoryCur.wakelockTag = mHistoryCur.localWakelockTag; 4431 mHistoryCur.wakelockTag.string = mInitialAcquireWakeName = historyName; 4432 mHistoryCur.wakelockTag.uid = mInitialAcquireWakeUid = mappedUid; 4433 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 4434 } 4435 mWakeLockImportant = true; 4436 } 4437 mWakeLockNesting++; 4438 } 4439 if (mappedUid >= 0) { 4440 if (mappedUid != uid) { 4441 // Prevent the isolated uid mapping from being removed while the wakelock is 4442 // being held. 4443 incrementIsolatedUidRefCount(uid); 4444 } 4445 if (mOnBatteryScreenOffTimeBase.isRunning()) { 4446 // We only update the cpu time when a wake lock is acquired if the screen is off. 4447 // If the screen is on, we don't distribute the power amongst partial wakelocks. 4448 if (DEBUG_ENERGY_CPU) { 4449 Slog.d(TAG, "Updating cpu time because of +wake_lock"); 4450 } 4451 requestWakelockCpuUpdate(); 4452 } 4453 4454 getUidStatsLocked(mappedUid, elapsedRealtimeMs, uptimeMs) 4455 .noteStartWakeLocked(pid, name, type, elapsedRealtimeMs); 4456 4457 if (wc != null) { 4458 FrameworkStatsLog.write(FrameworkStatsLog.WAKELOCK_STATE_CHANGED, wc.getUids(), 4459 wc.getTags(), getPowerManagerWakeLockLevel(type), name, 4460 FrameworkStatsLog.WAKELOCK_STATE_CHANGED__STATE__ACQUIRE); 4461 } else { 4462 FrameworkStatsLog.write_non_chained(FrameworkStatsLog.WAKELOCK_STATE_CHANGED, 4463 mappedUid, null, getPowerManagerWakeLockLevel(type), name, 4464 FrameworkStatsLog.WAKELOCK_STATE_CHANGED__STATE__ACQUIRE); 4465 } 4466 } 4467 } 4468 noteStopWakeLocked(int uid, int pid, WorkChain wc, String name, String historyName, int type)4469 public void noteStopWakeLocked(int uid, int pid, WorkChain wc, String name, String historyName, 4470 int type) { 4471 noteStopWakeLocked(uid, pid, wc, name, historyName, type, 4472 mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 4473 } 4474 noteStopWakeLocked(int uid, int pid, WorkChain wc, String name, String historyName, int type, long elapsedRealtimeMs, long uptimeMs)4475 public void noteStopWakeLocked(int uid, int pid, WorkChain wc, String name, String historyName, 4476 int type, long elapsedRealtimeMs, long uptimeMs) { 4477 final int mappedUid = mapUid(uid); 4478 if (type == WAKE_TYPE_PARTIAL) { 4479 mWakeLockNesting--; 4480 if (mRecordAllHistory) { 4481 if (historyName == null) { 4482 historyName = name; 4483 } 4484 if (mActiveEvents.updateState(HistoryItem.EVENT_WAKE_LOCK_FINISH, historyName, 4485 mappedUid, 0)) { 4486 addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, 4487 HistoryItem.EVENT_WAKE_LOCK_FINISH, historyName, mappedUid); 4488 } 4489 } 4490 if (mWakeLockNesting == 0) { 4491 mHistoryCur.states &= ~HistoryItem.STATE_WAKE_LOCK_FLAG; 4492 if (DEBUG_HISTORY) Slog.v(TAG, "Stop wake lock to: " 4493 + Integer.toHexString(mHistoryCur.states)); 4494 mInitialAcquireWakeName = null; 4495 mInitialAcquireWakeUid = -1; 4496 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 4497 } 4498 } 4499 if (mappedUid >= 0) { 4500 if (mOnBatteryScreenOffTimeBase.isRunning()) { 4501 if (DEBUG_ENERGY_CPU) { 4502 Slog.d(TAG, "Updating cpu time because of -wake_lock"); 4503 } 4504 requestWakelockCpuUpdate(); 4505 } 4506 4507 getUidStatsLocked(mappedUid, elapsedRealtimeMs, uptimeMs) 4508 .noteStopWakeLocked(pid, name, type, elapsedRealtimeMs); 4509 if (wc != null) { 4510 FrameworkStatsLog.write(FrameworkStatsLog.WAKELOCK_STATE_CHANGED, wc.getUids(), 4511 wc.getTags(), getPowerManagerWakeLockLevel(type), name, 4512 FrameworkStatsLog.WAKELOCK_STATE_CHANGED__STATE__RELEASE); 4513 } else { 4514 FrameworkStatsLog.write_non_chained(FrameworkStatsLog.WAKELOCK_STATE_CHANGED, 4515 mappedUid, null, getPowerManagerWakeLockLevel(type), name, 4516 FrameworkStatsLog.WAKELOCK_STATE_CHANGED__STATE__RELEASE); 4517 } 4518 4519 if (mappedUid != uid) { 4520 // Decrement the ref count for the isolated uid and delete the mapping if uneeded. 4521 maybeRemoveIsolatedUidLocked(uid, elapsedRealtimeMs, uptimeMs); 4522 } 4523 } 4524 } 4525 4526 /** 4527 * Converts BatteryStats wakelock types back into PowerManager wakelock levels. 4528 * This is the inverse map of Notifier.getBatteryStatsWakeLockMonitorType(). 4529 * These are estimations, since batterystats loses some of the original data. 4530 * TODO: Delete this. Instead, FrameworkStatsLog.write should be called from 4531 * PowerManager's Notifier. 4532 */ getPowerManagerWakeLockLevel(int battertStatsWakelockType)4533 private int getPowerManagerWakeLockLevel(int battertStatsWakelockType) { 4534 switch (battertStatsWakelockType) { 4535 // PowerManager.PARTIAL_WAKE_LOCK or PROXIMITY_SCREEN_OFF_WAKE_LOCK 4536 case BatteryStats.WAKE_TYPE_PARTIAL: 4537 return PowerManager.PARTIAL_WAKE_LOCK; 4538 4539 // PowerManager.SCREEN_DIM_WAKE_LOCK or SCREEN_BRIGHT_WAKE_LOCK 4540 case BatteryStats.WAKE_TYPE_FULL: 4541 return PowerManager.FULL_WAKE_LOCK; 4542 4543 case BatteryStats.WAKE_TYPE_DRAW: 4544 return PowerManager.DRAW_WAKE_LOCK; 4545 4546 // It appears that nothing can ever make a Window and PowerManager lacks an equivalent. 4547 case BatteryStats.WAKE_TYPE_WINDOW: 4548 Slog.e(TAG, "Illegal window wakelock type observed in batterystats."); 4549 return -1; 4550 4551 default: 4552 Slog.e(TAG, "Illegal wakelock type in batterystats: " + battertStatsWakelockType); 4553 return -1; 4554 } 4555 } 4556 noteStartWakeFromSourceLocked(WorkSource ws, int pid, String name, String historyName, int type, boolean unimportantForLogging)4557 public void noteStartWakeFromSourceLocked(WorkSource ws, int pid, String name, 4558 String historyName, int type, boolean unimportantForLogging) { 4559 noteStartWakeFromSourceLocked(ws, pid, name, historyName, type, unimportantForLogging, 4560 mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 4561 } 4562 noteStartWakeFromSourceLocked(WorkSource ws, int pid, String name, String historyName, int type, boolean unimportantForLogging, long elapsedRealtimeMs, long uptimeMs)4563 public void noteStartWakeFromSourceLocked(WorkSource ws, int pid, String name, 4564 String historyName, int type, boolean unimportantForLogging, 4565 long elapsedRealtimeMs, long uptimeMs) { 4566 final int N = ws.size(); 4567 for (int i=0; i<N; i++) { 4568 noteStartWakeLocked(ws.getUid(i), pid, null, name, historyName, type, 4569 unimportantForLogging, elapsedRealtimeMs, uptimeMs); 4570 } 4571 4572 List<WorkChain> wcs = ws.getWorkChains(); 4573 if (wcs != null) { 4574 for (int i = 0; i < wcs.size(); ++i) { 4575 final WorkChain wc = wcs.get(i); 4576 noteStartWakeLocked(wc.getAttributionUid(), pid, wc, name, historyName, type, 4577 unimportantForLogging, elapsedRealtimeMs, uptimeMs); 4578 } 4579 } 4580 } 4581 noteChangeWakelockFromSourceLocked(WorkSource ws, int pid, String name, String historyName, int type, WorkSource newWs, int newPid, String newName, String newHistoryName, int newType, boolean newUnimportantForLogging)4582 public void noteChangeWakelockFromSourceLocked(WorkSource ws, int pid, String name, 4583 String historyName, int type, WorkSource newWs, int newPid, String newName, 4584 String newHistoryName, int newType, boolean newUnimportantForLogging) { 4585 noteChangeWakelockFromSourceLocked(ws, pid, name, historyName, type, newWs, newPid, 4586 newName, newHistoryName, newType, newUnimportantForLogging, 4587 mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 4588 } 4589 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)4590 public void noteChangeWakelockFromSourceLocked(WorkSource ws, int pid, String name, 4591 String historyName, int type, WorkSource newWs, int newPid, String newName, 4592 String newHistoryName, int newType, boolean newUnimportantForLogging, 4593 long elapsedRealtimeMs, long uptimeMs) { 4594 List<WorkChain>[] wcs = WorkSource.diffChains(ws, newWs); 4595 4596 // For correct semantics, we start the need worksources first, so that we won't 4597 // make inappropriate history items as if all wake locks went away and new ones 4598 // appeared. This is okay because tracking of wake locks allows nesting. 4599 // 4600 // First the starts : 4601 final int NN = newWs.size(); 4602 for (int i=0; i<NN; i++) { 4603 noteStartWakeLocked(newWs.getUid(i), newPid, null, newName, newHistoryName, newType, 4604 newUnimportantForLogging, elapsedRealtimeMs, uptimeMs); 4605 } 4606 if (wcs != null) { 4607 List<WorkChain> newChains = wcs[0]; 4608 if (newChains != null) { 4609 for (int i = 0; i < newChains.size(); ++i) { 4610 final WorkChain newChain = newChains.get(i); 4611 noteStartWakeLocked(newChain.getAttributionUid(), newPid, newChain, newName, 4612 newHistoryName, newType, newUnimportantForLogging, elapsedRealtimeMs, 4613 uptimeMs); 4614 } 4615 } 4616 } 4617 4618 // Then the stops : 4619 final int NO = ws.size(); 4620 for (int i=0; i<NO; i++) { 4621 noteStopWakeLocked(ws.getUid(i), pid, null, name, historyName, type, elapsedRealtimeMs, 4622 uptimeMs); 4623 } 4624 if (wcs != null) { 4625 List<WorkChain> goneChains = wcs[1]; 4626 if (goneChains != null) { 4627 for (int i = 0; i < goneChains.size(); ++i) { 4628 final WorkChain goneChain = goneChains.get(i); 4629 noteStopWakeLocked(goneChain.getAttributionUid(), pid, goneChain, name, 4630 historyName, type, elapsedRealtimeMs, uptimeMs); 4631 } 4632 } 4633 } 4634 } 4635 noteStopWakeFromSourceLocked(WorkSource ws, int pid, String name, String historyName, int type)4636 public void noteStopWakeFromSourceLocked(WorkSource ws, int pid, String name, 4637 String historyName, int type) { 4638 noteStopWakeFromSourceLocked(ws, pid, name, historyName, type, 4639 mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 4640 } 4641 noteStopWakeFromSourceLocked(WorkSource ws, int pid, String name, String historyName, int type, long elapsedRealtimeMs, long uptimeMs)4642 public void noteStopWakeFromSourceLocked(WorkSource ws, int pid, String name, 4643 String historyName, int type, long elapsedRealtimeMs, long uptimeMs) { 4644 final int N = ws.size(); 4645 for (int i=0; i<N; i++) { 4646 noteStopWakeLocked(ws.getUid(i), pid, null, name, historyName, type, elapsedRealtimeMs, 4647 uptimeMs); 4648 } 4649 4650 List<WorkChain> wcs = ws.getWorkChains(); 4651 if (wcs != null) { 4652 for (int i = 0; i < wcs.size(); ++i) { 4653 final WorkChain wc = wcs.get(i); 4654 noteStopWakeLocked(wc.getAttributionUid(), pid, wc, name, historyName, type, 4655 elapsedRealtimeMs, uptimeMs); 4656 } 4657 } 4658 } 4659 noteLongPartialWakelockStart(String name, String historyName, int uid)4660 public void noteLongPartialWakelockStart(String name, String historyName, int uid) { 4661 noteLongPartialWakelockStart(name, historyName, uid, 4662 mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 4663 } 4664 noteLongPartialWakelockStart(String name, String historyName, int uid, long elapsedRealtimeMs, long uptimeMs)4665 public void noteLongPartialWakelockStart(String name, String historyName, int uid, 4666 long elapsedRealtimeMs, long uptimeMs) { 4667 uid = mapUid(uid); 4668 noteLongPartialWakeLockStartInternal(name, historyName, uid, elapsedRealtimeMs, uptimeMs); 4669 } 4670 noteLongPartialWakelockStartFromSource(String name, String historyName, WorkSource workSource)4671 public void noteLongPartialWakelockStartFromSource(String name, String historyName, 4672 WorkSource workSource) { 4673 noteLongPartialWakelockStartFromSource(name, historyName, workSource, 4674 mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 4675 } 4676 noteLongPartialWakelockStartFromSource(String name, String historyName, WorkSource workSource, long elapsedRealtimeMs, long uptimeMs)4677 public void noteLongPartialWakelockStartFromSource(String name, String historyName, 4678 WorkSource workSource, long elapsedRealtimeMs, long uptimeMs) { 4679 final int N = workSource.size(); 4680 for (int i = 0; i < N; ++i) { 4681 final int uid = mapUid(workSource.getUid(i)); 4682 noteLongPartialWakeLockStartInternal(name, historyName, uid, 4683 elapsedRealtimeMs, uptimeMs); 4684 } 4685 4686 final List<WorkChain> workChains = workSource.getWorkChains(); 4687 if (workChains != null) { 4688 for (int i = 0; i < workChains.size(); ++i) { 4689 final WorkChain workChain = workChains.get(i); 4690 final int uid = workChain.getAttributionUid(); 4691 noteLongPartialWakeLockStartInternal(name, historyName, uid, 4692 elapsedRealtimeMs, uptimeMs); 4693 } 4694 } 4695 } 4696 noteLongPartialWakeLockStartInternal(String name, String historyName, int uid, long elapsedRealtimeMs, long uptimeMs)4697 private void noteLongPartialWakeLockStartInternal(String name, String historyName, int uid, 4698 long elapsedRealtimeMs, long uptimeMs) { 4699 if (historyName == null) { 4700 historyName = name; 4701 } 4702 if (!mActiveEvents.updateState(HistoryItem.EVENT_LONG_WAKE_LOCK_START, historyName, uid, 4703 0)) { 4704 return; 4705 } 4706 addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_LONG_WAKE_LOCK_START, 4707 historyName, uid); 4708 } 4709 noteLongPartialWakelockFinish(String name, String historyName, int uid)4710 public void noteLongPartialWakelockFinish(String name, String historyName, int uid) { 4711 noteLongPartialWakelockFinish(name, historyName, uid, 4712 mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 4713 } 4714 noteLongPartialWakelockFinish(String name, String historyName, int uid, long elapsedRealtimeMs, long uptimeMs)4715 public void noteLongPartialWakelockFinish(String name, String historyName, int uid, 4716 long elapsedRealtimeMs, long uptimeMs) { 4717 uid = mapUid(uid); 4718 noteLongPartialWakeLockFinishInternal(name, historyName, uid, elapsedRealtimeMs, uptimeMs); 4719 } 4720 noteLongPartialWakelockFinishFromSource(String name, String historyName, WorkSource workSource)4721 public void noteLongPartialWakelockFinishFromSource(String name, String historyName, 4722 WorkSource workSource) { 4723 noteLongPartialWakelockFinishFromSource(name, historyName, workSource, 4724 mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 4725 } 4726 noteLongPartialWakelockFinishFromSource(String name, String historyName, WorkSource workSource, long elapsedRealtimeMs, long uptimeMs)4727 public void noteLongPartialWakelockFinishFromSource(String name, String historyName, 4728 WorkSource workSource, long elapsedRealtimeMs, long uptimeMs) { 4729 final int N = workSource.size(); 4730 for (int i = 0; i < N; ++i) { 4731 final int uid = mapUid(workSource.getUid(i)); 4732 noteLongPartialWakeLockFinishInternal(name, historyName, uid, 4733 elapsedRealtimeMs, uptimeMs); 4734 } 4735 4736 final List<WorkChain> workChains = workSource.getWorkChains(); 4737 if (workChains != null) { 4738 for (int i = 0; i < workChains.size(); ++i) { 4739 final WorkChain workChain = workChains.get(i); 4740 final int uid = workChain.getAttributionUid(); 4741 noteLongPartialWakeLockFinishInternal(name, historyName, uid, 4742 elapsedRealtimeMs, uptimeMs); 4743 } 4744 } 4745 } 4746 noteLongPartialWakeLockFinishInternal(String name, String historyName, int uid, long elapsedRealtimeMs, long uptimeMs)4747 private void noteLongPartialWakeLockFinishInternal(String name, String historyName, int uid, 4748 long elapsedRealtimeMs, long uptimeMs) { 4749 if (historyName == null) { 4750 historyName = name; 4751 } 4752 if (!mActiveEvents.updateState(HistoryItem.EVENT_LONG_WAKE_LOCK_FINISH, historyName, uid, 4753 0)) { 4754 return; 4755 } 4756 addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_LONG_WAKE_LOCK_FINISH, 4757 historyName, uid); 4758 } 4759 aggregateLastWakeupUptimeLocked(long elapsedRealtimeMs, long uptimeMs)4760 void aggregateLastWakeupUptimeLocked(long elapsedRealtimeMs, long uptimeMs) { 4761 if (mLastWakeupReason != null) { 4762 long deltaUptimeMs = uptimeMs - mLastWakeupUptimeMs; 4763 SamplingTimer timer = getWakeupReasonTimerLocked(mLastWakeupReason); 4764 timer.add(deltaUptimeMs * 1000, 1, elapsedRealtimeMs); // time in in microseconds 4765 FrameworkStatsLog.write(FrameworkStatsLog.KERNEL_WAKEUP_REPORTED, mLastWakeupReason, 4766 /* duration_usec */ deltaUptimeMs * 1000); 4767 mLastWakeupReason = null; 4768 } 4769 } 4770 noteWakeupReasonLocked(String reason)4771 public void noteWakeupReasonLocked(String reason) { 4772 noteWakeupReasonLocked(reason, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 4773 } 4774 noteWakeupReasonLocked(String reason, long elapsedRealtimeMs, long uptimeMs)4775 public void noteWakeupReasonLocked(String reason, long elapsedRealtimeMs, long uptimeMs) { 4776 if (DEBUG_HISTORY) Slog.v(TAG, "Wakeup reason \"" + reason +"\": " 4777 + Integer.toHexString(mHistoryCur.states)); 4778 aggregateLastWakeupUptimeLocked(elapsedRealtimeMs, uptimeMs); 4779 mHistoryCur.wakeReasonTag = mHistoryCur.localWakeReasonTag; 4780 mHistoryCur.wakeReasonTag.string = reason; 4781 mHistoryCur.wakeReasonTag.uid = 0; 4782 mLastWakeupReason = reason; 4783 mLastWakeupUptimeMs = uptimeMs; 4784 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 4785 } 4786 startAddingCpuLocked()4787 public boolean startAddingCpuLocked() { 4788 mExternalSync.cancelCpuSyncDueToWakelockChange(); 4789 return mOnBatteryInternal; 4790 } 4791 finishAddingCpuLocked(int totalUTimeMs, int totalSTimeMs, int statUserTimeMs, int statSystemTimeMs, int statIOWaitTimeMs, int statIrqTimeMs, int statSoftIrqTimeMs, int statIdleTimeMs)4792 public void finishAddingCpuLocked(int totalUTimeMs, int totalSTimeMs, int statUserTimeMs, 4793 int statSystemTimeMs, int statIOWaitTimeMs, int statIrqTimeMs, 4794 int statSoftIrqTimeMs, int statIdleTimeMs) { 4795 if (DEBUG) { 4796 Slog.d(TAG, "Adding cpu: tuser=" + totalUTimeMs + " tsys=" + totalSTimeMs 4797 + " user=" + statUserTimeMs + " sys=" + statSystemTimeMs 4798 + " io=" + statIOWaitTimeMs + " irq=" + statIrqTimeMs 4799 + " sirq=" + statSoftIrqTimeMs + " idle=" + statIdleTimeMs); 4800 } 4801 mCurStepCpuUserTimeMs += totalUTimeMs; 4802 mCurStepCpuSystemTimeMs += totalSTimeMs; 4803 mCurStepStatUserTimeMs += statUserTimeMs; 4804 mCurStepStatSystemTimeMs += statSystemTimeMs; 4805 mCurStepStatIOWaitTimeMs += statIOWaitTimeMs; 4806 mCurStepStatIrqTimeMs += statIrqTimeMs; 4807 mCurStepStatSoftIrqTimeMs += statSoftIrqTimeMs; 4808 mCurStepStatIdleTimeMs += statIdleTimeMs; 4809 } 4810 noteProcessDiedLocked(int uid, int pid)4811 public void noteProcessDiedLocked(int uid, int pid) { 4812 uid = mapUid(uid); 4813 Uid u = mUidStats.get(uid); 4814 if (u != null) { 4815 u.mPids.remove(pid); 4816 } 4817 } 4818 getProcessWakeTime(int uid, int pid, long realtimeMs)4819 public long getProcessWakeTime(int uid, int pid, long realtimeMs) { 4820 uid = mapUid(uid); 4821 Uid u = mUidStats.get(uid); 4822 if (u != null) { 4823 Uid.Pid p = u.mPids.get(pid); 4824 if (p != null) { 4825 return p.mWakeSumMs + (p.mWakeNesting > 0 ? (realtimeMs - p.mWakeStartMs) : 0); 4826 } 4827 } 4828 return 0; 4829 } 4830 reportExcessiveCpuLocked(int uid, String proc, long overTimeMs, long usedTimeMs)4831 public void reportExcessiveCpuLocked(int uid, String proc, long overTimeMs, long usedTimeMs) { 4832 uid = mapUid(uid); 4833 Uid u = mUidStats.get(uid); 4834 if (u != null) { 4835 u.reportExcessiveCpuLocked(proc, overTimeMs, usedTimeMs); 4836 } 4837 } 4838 4839 int mSensorNesting; 4840 noteStartSensorLocked(int uid, int sensor)4841 public void noteStartSensorLocked(int uid, int sensor) { 4842 noteStartSensorLocked(uid, sensor, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 4843 } 4844 noteStartSensorLocked(int uid, int sensor, long elapsedRealtimeMs, long uptimeMs)4845 public void noteStartSensorLocked(int uid, int sensor, long elapsedRealtimeMs, long uptimeMs) { 4846 uid = mapUid(uid); 4847 if (mSensorNesting == 0) { 4848 mHistoryCur.states |= HistoryItem.STATE_SENSOR_ON_FLAG; 4849 if (DEBUG_HISTORY) Slog.v(TAG, "Start sensor to: " 4850 + Integer.toHexString(mHistoryCur.states)); 4851 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 4852 } 4853 mSensorNesting++; 4854 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 4855 .noteStartSensor(sensor, elapsedRealtimeMs); 4856 } 4857 noteStopSensorLocked(int uid, int sensor)4858 public void noteStopSensorLocked(int uid, int sensor) { 4859 noteStopSensorLocked(uid, sensor, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 4860 } 4861 noteStopSensorLocked(int uid, int sensor, long elapsedRealtimeMs, long uptimeMs)4862 public void noteStopSensorLocked(int uid, int sensor, long elapsedRealtimeMs, long uptimeMs) { 4863 uid = mapUid(uid); 4864 mSensorNesting--; 4865 if (mSensorNesting == 0) { 4866 mHistoryCur.states &= ~HistoryItem.STATE_SENSOR_ON_FLAG; 4867 if (DEBUG_HISTORY) Slog.v(TAG, "Stop sensor to: " 4868 + Integer.toHexString(mHistoryCur.states)); 4869 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 4870 } 4871 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 4872 .noteStopSensor(sensor, elapsedRealtimeMs); 4873 } 4874 4875 int mGpsNesting; 4876 noteGpsChangedLocked(WorkSource oldWs, WorkSource newWs)4877 public void noteGpsChangedLocked(WorkSource oldWs, WorkSource newWs) { 4878 noteGpsChangedLocked(oldWs, newWs, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 4879 } 4880 noteGpsChangedLocked(WorkSource oldWs, WorkSource newWs, long elapsedRealtimeMs, long uptimeMs)4881 public void noteGpsChangedLocked(WorkSource oldWs, WorkSource newWs, 4882 long elapsedRealtimeMs, long uptimeMs) { 4883 for (int i = 0; i < newWs.size(); ++i) { 4884 noteStartGpsLocked(newWs.getUid(i), null, elapsedRealtimeMs, uptimeMs); 4885 } 4886 4887 for (int i = 0; i < oldWs.size(); ++i) { 4888 noteStopGpsLocked((oldWs.getUid(i)), null, elapsedRealtimeMs, uptimeMs); 4889 } 4890 4891 List<WorkChain>[] wcs = WorkSource.diffChains(oldWs, newWs); 4892 if (wcs != null) { 4893 if (wcs[0] != null) { 4894 final List<WorkChain> newChains = wcs[0]; 4895 for (int i = 0; i < newChains.size(); ++i) { 4896 noteStartGpsLocked(-1, newChains.get(i), elapsedRealtimeMs, uptimeMs); 4897 } 4898 } 4899 4900 if (wcs[1] != null) { 4901 final List<WorkChain> goneChains = wcs[1]; 4902 for (int i = 0; i < goneChains.size(); ++i) { 4903 noteStopGpsLocked(-1, goneChains.get(i), elapsedRealtimeMs, uptimeMs); 4904 } 4905 } 4906 } 4907 } 4908 noteStartGpsLocked(int uid, WorkChain workChain, long elapsedRealtimeMs, long uptimeMs)4909 private void noteStartGpsLocked(int uid, WorkChain workChain, 4910 long elapsedRealtimeMs, long uptimeMs) { 4911 uid = getAttributionUid(uid, workChain); 4912 if (mGpsNesting == 0) { 4913 mHistoryCur.states |= HistoryItem.STATE_GPS_ON_FLAG; 4914 if (DEBUG_HISTORY) Slog.v(TAG, "Start GPS to: " 4915 + Integer.toHexString(mHistoryCur.states)); 4916 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 4917 } 4918 mGpsNesting++; 4919 4920 if (workChain == null) { 4921 FrameworkStatsLog.write_non_chained(FrameworkStatsLog.GPS_SCAN_STATE_CHANGED, uid, null, 4922 FrameworkStatsLog.GPS_SCAN_STATE_CHANGED__STATE__ON); 4923 } else { 4924 FrameworkStatsLog.write(FrameworkStatsLog.GPS_SCAN_STATE_CHANGED, 4925 workChain.getUids(), workChain.getTags(), 4926 FrameworkStatsLog.GPS_SCAN_STATE_CHANGED__STATE__ON); 4927 } 4928 4929 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs).noteStartGps(elapsedRealtimeMs); 4930 } 4931 noteStopGpsLocked(int uid, WorkChain workChain, long elapsedRealtimeMs, long uptimeMs)4932 private void noteStopGpsLocked(int uid, WorkChain workChain, 4933 long elapsedRealtimeMs, long uptimeMs) { 4934 uid = getAttributionUid(uid, workChain); 4935 mGpsNesting--; 4936 if (mGpsNesting == 0) { 4937 mHistoryCur.states &= ~HistoryItem.STATE_GPS_ON_FLAG; 4938 if (DEBUG_HISTORY) Slog.v(TAG, "Stop GPS to: " 4939 + Integer.toHexString(mHistoryCur.states)); 4940 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 4941 stopAllGpsSignalQualityTimersLocked(-1, elapsedRealtimeMs); 4942 mGpsSignalQualityBin = -1; 4943 } 4944 4945 if (workChain == null) { 4946 FrameworkStatsLog.write_non_chained(FrameworkStatsLog.GPS_SCAN_STATE_CHANGED, uid, null, 4947 FrameworkStatsLog.GPS_SCAN_STATE_CHANGED__STATE__OFF); 4948 } else { 4949 FrameworkStatsLog.write(FrameworkStatsLog.GPS_SCAN_STATE_CHANGED, workChain.getUids(), 4950 workChain.getTags(), FrameworkStatsLog.GPS_SCAN_STATE_CHANGED__STATE__OFF); 4951 } 4952 4953 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs).noteStopGps(elapsedRealtimeMs); 4954 } 4955 noteGpsSignalQualityLocked(int signalLevel)4956 public void noteGpsSignalQualityLocked(int signalLevel) { 4957 noteGpsSignalQualityLocked(signalLevel, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 4958 } 4959 noteGpsSignalQualityLocked(int signalLevel, long elapsedRealtimeMs, long uptimeMs)4960 public void noteGpsSignalQualityLocked(int signalLevel, long elapsedRealtimeMs, long uptimeMs) { 4961 if (mGpsNesting == 0) { 4962 return; 4963 } 4964 if (signalLevel < 0 || signalLevel >= mGpsSignalQualityTimer.length) { 4965 stopAllGpsSignalQualityTimersLocked(-1, elapsedRealtimeMs); 4966 return; 4967 } 4968 if (mGpsSignalQualityBin != signalLevel) { 4969 if (mGpsSignalQualityBin >= 0) { 4970 mGpsSignalQualityTimer[mGpsSignalQualityBin].stopRunningLocked(elapsedRealtimeMs); 4971 } 4972 if(!mGpsSignalQualityTimer[signalLevel].isRunningLocked()) { 4973 mGpsSignalQualityTimer[signalLevel].startRunningLocked(elapsedRealtimeMs); 4974 } 4975 mHistoryCur.states2 = (mHistoryCur.states2&~HistoryItem.STATE2_GPS_SIGNAL_QUALITY_MASK) 4976 | (signalLevel << HistoryItem.STATE2_GPS_SIGNAL_QUALITY_SHIFT); 4977 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 4978 mGpsSignalQualityBin = signalLevel; 4979 } 4980 return; 4981 } 4982 4983 @GuardedBy("this") noteScreenStateLocked(int display, int state)4984 public void noteScreenStateLocked(int display, int state) { 4985 noteScreenStateLocked(display, state, mClocks.elapsedRealtime(), mClocks.uptimeMillis(), 4986 mClocks.currentTimeMillis()); 4987 } 4988 4989 @GuardedBy("this") noteScreenStateLocked(int display, int displayState, long elapsedRealtimeMs, long uptimeMs, long currentTimeMs)4990 public void noteScreenStateLocked(int display, int displayState, 4991 long elapsedRealtimeMs, long uptimeMs, long currentTimeMs) { 4992 // Battery stats relies on there being 4 states. To accommodate this, new states beyond the 4993 // original 4 are mapped to one of the originals. 4994 if (displayState > MAX_TRACKED_SCREEN_STATE) { 4995 if (Display.isOnState(displayState)) { 4996 displayState = Display.STATE_ON; 4997 } else if (Display.isDozeState(displayState)) { 4998 if (Display.isSuspendedState(displayState)) { 4999 displayState = Display.STATE_DOZE_SUSPEND; 5000 } else { 5001 displayState = Display.STATE_DOZE; 5002 } 5003 } else if (Display.isOffState(displayState)) { 5004 displayState = Display.STATE_OFF; 5005 } else { 5006 Slog.wtf(TAG, "Unknown screen state (not mapped): " + displayState); 5007 displayState = Display.STATE_UNKNOWN; 5008 } 5009 } 5010 // As of this point, displayState should be mapped to one of: 5011 // - Display.STATE_ON, 5012 // - Display.STATE_DOZE 5013 // - Display.STATE_DOZE_SUSPEND 5014 // - Display.STATE_OFF 5015 // - Display.STATE_UNKNOWN 5016 5017 int state; 5018 int overallBin = mScreenBrightnessBin; 5019 int externalUpdateFlag = 0; 5020 boolean shouldScheduleSync = false; 5021 final int numDisplay = mPerDisplayBatteryStats.length; 5022 if (display < 0 || display >= numDisplay) { 5023 Slog.wtf(TAG, "Unexpected note screen state for display " + display + " (only " 5024 + mPerDisplayBatteryStats.length + " displays exist...)"); 5025 return; 5026 } 5027 final DisplayBatteryStats displayStats = mPerDisplayBatteryStats[display]; 5028 final int oldDisplayState = displayStats.screenState; 5029 5030 if (oldDisplayState == displayState) { 5031 // Nothing changed 5032 state = mScreenState; 5033 } else { 5034 displayStats.screenState = displayState; 5035 5036 // Stop timer for previous display state. 5037 switch (oldDisplayState) { 5038 case Display.STATE_ON: 5039 displayStats.screenOnTimer.stopRunningLocked(elapsedRealtimeMs); 5040 final int bin = displayStats.screenBrightnessBin; 5041 if (bin >= 0) { 5042 displayStats.screenBrightnessTimers[bin].stopRunningLocked( 5043 elapsedRealtimeMs); 5044 } 5045 overallBin = evaluateOverallScreenBrightnessBinLocked(); 5046 shouldScheduleSync = true; 5047 break; 5048 case Display.STATE_DOZE: 5049 // Transition from doze to doze suspend can be ignored. 5050 if (displayState == Display.STATE_DOZE_SUSPEND) break; 5051 displayStats.screenDozeTimer.stopRunningLocked(elapsedRealtimeMs); 5052 shouldScheduleSync = true; 5053 break; 5054 case Display.STATE_DOZE_SUSPEND: 5055 // Transition from doze suspend to doze can be ignored. 5056 if (displayState == Display.STATE_DOZE) break; 5057 displayStats.screenDozeTimer.stopRunningLocked(elapsedRealtimeMs); 5058 shouldScheduleSync = true; 5059 break; 5060 case Display.STATE_OFF: // fallthrough 5061 case Display.STATE_UNKNOWN: 5062 // Not tracked by timers. 5063 break; 5064 default: 5065 Slog.wtf(TAG, 5066 "Attempted to stop timer for unexpected display state " + display); 5067 } 5068 5069 // Start timer for new display state. 5070 switch (displayState) { 5071 case Display.STATE_ON: 5072 displayStats.screenOnTimer.startRunningLocked(elapsedRealtimeMs); 5073 final int bin = displayStats.screenBrightnessBin; 5074 if (bin >= 0) { 5075 displayStats.screenBrightnessTimers[bin].startRunningLocked( 5076 elapsedRealtimeMs); 5077 } 5078 overallBin = evaluateOverallScreenBrightnessBinLocked(); 5079 shouldScheduleSync = true; 5080 break; 5081 case Display.STATE_DOZE: 5082 // Transition from doze suspend to doze can be ignored. 5083 if (oldDisplayState == Display.STATE_DOZE_SUSPEND) break; 5084 displayStats.screenDozeTimer.startRunningLocked(elapsedRealtimeMs); 5085 shouldScheduleSync = true; 5086 break; 5087 case Display.STATE_DOZE_SUSPEND: 5088 // Transition from doze to doze suspend can be ignored. 5089 if (oldDisplayState == Display.STATE_DOZE) break; 5090 displayStats.screenDozeTimer.startRunningLocked(elapsedRealtimeMs); 5091 shouldScheduleSync = true; 5092 break; 5093 case Display.STATE_OFF: // fallthrough 5094 case Display.STATE_UNKNOWN: 5095 // Not tracked by timers. 5096 break; 5097 default: 5098 Slog.wtf(TAG, 5099 "Attempted to start timer for unexpected display state " + displayState 5100 + " for display " + display); 5101 } 5102 5103 if (shouldScheduleSync 5104 && mGlobalMeasuredEnergyStats != null 5105 && mGlobalMeasuredEnergyStats.isStandardBucketSupported( 5106 MeasuredEnergyStats.POWER_BUCKET_SCREEN_ON)) { 5107 // Display measured energy stats is available. Prepare to schedule an 5108 // external sync. 5109 externalUpdateFlag |= ExternalStatsSync.UPDATE_DISPLAY; 5110 } 5111 5112 // Reevaluate most important display screen state. 5113 state = Display.STATE_UNKNOWN; 5114 for (int i = 0; i < numDisplay; i++) { 5115 final int tempState = mPerDisplayBatteryStats[i].screenState; 5116 if (tempState == Display.STATE_ON 5117 || state == Display.STATE_ON) { 5118 state = Display.STATE_ON; 5119 } else if (tempState == Display.STATE_DOZE 5120 || state == Display.STATE_DOZE) { 5121 state = Display.STATE_DOZE; 5122 } else if (tempState == Display.STATE_DOZE_SUSPEND 5123 || state == Display.STATE_DOZE_SUSPEND) { 5124 state = Display.STATE_DOZE_SUSPEND; 5125 } else if (tempState == Display.STATE_OFF 5126 || state == Display.STATE_OFF) { 5127 state = Display.STATE_OFF; 5128 } 5129 } 5130 } 5131 5132 final boolean batteryRunning = mOnBatteryTimeBase.isRunning(); 5133 final boolean batteryScreenOffRunning = mOnBatteryScreenOffTimeBase.isRunning(); 5134 5135 state = mPretendScreenOff ? Display.STATE_OFF : state; 5136 if (mScreenState != state) { 5137 recordDailyStatsIfNeededLocked(true, currentTimeMs); 5138 final int oldState = mScreenState; 5139 mScreenState = state; 5140 if (DEBUG) Slog.v(TAG, "Screen state: oldState=" + Display.stateToString(oldState) 5141 + ", newState=" + Display.stateToString(state)); 5142 5143 if (state != Display.STATE_UNKNOWN) { 5144 int stepState = state-1; 5145 if ((stepState & STEP_LEVEL_MODE_SCREEN_STATE) == stepState) { 5146 mModStepMode |= (mCurStepMode & STEP_LEVEL_MODE_SCREEN_STATE) ^ stepState; 5147 mCurStepMode = (mCurStepMode & ~STEP_LEVEL_MODE_SCREEN_STATE) | stepState; 5148 } else { 5149 Slog.wtf(TAG, "Unexpected screen state: " + state); 5150 } 5151 } 5152 5153 boolean updateHistory = false; 5154 if (Display.isDozeState(state) && !Display.isDozeState(oldState)) { 5155 mHistoryCur.states |= HistoryItem.STATE_SCREEN_DOZE_FLAG; 5156 mScreenDozeTimer.startRunningLocked(elapsedRealtimeMs); 5157 updateHistory = true; 5158 } else if (Display.isDozeState(oldState) && !Display.isDozeState(state)) { 5159 mHistoryCur.states &= ~HistoryItem.STATE_SCREEN_DOZE_FLAG; 5160 mScreenDozeTimer.stopRunningLocked(elapsedRealtimeMs); 5161 updateHistory = true; 5162 } 5163 if (Display.isOnState(state)) { 5164 mHistoryCur.states |= HistoryItem.STATE_SCREEN_ON_FLAG; 5165 if (DEBUG_HISTORY) Slog.v(TAG, "Screen on to: " 5166 + Integer.toHexString(mHistoryCur.states)); 5167 mScreenOnTimer.startRunningLocked(elapsedRealtimeMs); 5168 if (mScreenBrightnessBin >= 0) { 5169 mScreenBrightnessTimer[mScreenBrightnessBin] 5170 .startRunningLocked(elapsedRealtimeMs); 5171 } 5172 updateHistory = true; 5173 } else if (Display.isOnState(oldState)) { 5174 mHistoryCur.states &= ~HistoryItem.STATE_SCREEN_ON_FLAG; 5175 if (DEBUG_HISTORY) Slog.v(TAG, "Screen off to: " 5176 + Integer.toHexString(mHistoryCur.states)); 5177 mScreenOnTimer.stopRunningLocked(elapsedRealtimeMs); 5178 if (mScreenBrightnessBin >= 0) { 5179 mScreenBrightnessTimer[mScreenBrightnessBin] 5180 .stopRunningLocked(elapsedRealtimeMs); 5181 } 5182 updateHistory = true; 5183 } 5184 if (updateHistory) { 5185 if (DEBUG_HISTORY) Slog.v(TAG, "Screen state to: " 5186 + Display.stateToString(state)); 5187 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 5188 } 5189 5190 // Per screen state Cpu stats needed. Prepare to schedule an external sync. 5191 externalUpdateFlag |= ExternalStatsSync.UPDATE_CPU; 5192 shouldScheduleSync = true; 5193 5194 if (Display.isOnState(state)) { 5195 updateTimeBasesLocked(mOnBatteryTimeBase.isRunning(), state, 5196 uptimeMs * 1000, elapsedRealtimeMs * 1000); 5197 // Fake a wake lock, so we consider the device waked as long as the screen is on. 5198 noteStartWakeLocked(-1, -1, null, "screen", null, WAKE_TYPE_PARTIAL, false, 5199 elapsedRealtimeMs, uptimeMs); 5200 } else if (Display.isOnState(oldState)) { 5201 noteStopWakeLocked(-1, -1, null, "screen", "screen", WAKE_TYPE_PARTIAL, 5202 elapsedRealtimeMs, uptimeMs); 5203 updateTimeBasesLocked(mOnBatteryTimeBase.isRunning(), state, 5204 uptimeMs * 1000, elapsedRealtimeMs * 1000); 5205 } 5206 // Update discharge amounts. 5207 if (mOnBatteryInternal) { 5208 updateDischargeScreenLevelsLocked(oldState, state); 5209 } 5210 } 5211 5212 // Changing display states might have changed the screen used to determine the overall 5213 // brightness. 5214 maybeUpdateOverallScreenBrightness(overallBin, elapsedRealtimeMs, uptimeMs); 5215 5216 if (shouldScheduleSync) { 5217 final int numDisplays = mPerDisplayBatteryStats.length; 5218 final int[] displayStates = new int[numDisplays]; 5219 for (int i = 0; i < numDisplays; i++) { 5220 displayStates[i] = mPerDisplayBatteryStats[i].screenState; 5221 } 5222 mExternalSync.scheduleSyncDueToScreenStateChange(externalUpdateFlag, 5223 batteryRunning, batteryScreenOffRunning, state, displayStates); 5224 } 5225 } 5226 5227 @UnsupportedAppUsage noteScreenBrightnessLocked(int brightness)5228 public void noteScreenBrightnessLocked(int brightness) { 5229 noteScreenBrightnessLocked(0, brightness); 5230 } 5231 5232 /** 5233 * Note screen brightness change for a display. 5234 */ noteScreenBrightnessLocked(int display, int brightness)5235 public void noteScreenBrightnessLocked(int display, int brightness) { 5236 noteScreenBrightnessLocked(display, brightness, mClocks.elapsedRealtime(), 5237 mClocks.uptimeMillis()); 5238 } 5239 5240 5241 /** 5242 * Note screen brightness change for a display. 5243 */ noteScreenBrightnessLocked(int display, int brightness, long elapsedRealtimeMs, long uptimeMs)5244 public void noteScreenBrightnessLocked(int display, int brightness, long elapsedRealtimeMs, 5245 long uptimeMs) { 5246 // Bin the brightness. 5247 int bin = brightness / (256/NUM_SCREEN_BRIGHTNESS_BINS); 5248 if (bin < 0) bin = 0; 5249 else if (bin >= NUM_SCREEN_BRIGHTNESS_BINS) bin = NUM_SCREEN_BRIGHTNESS_BINS-1; 5250 5251 final int overallBin; 5252 5253 final int numDisplays = mPerDisplayBatteryStats.length; 5254 if (display < 0 || display >= numDisplays) { 5255 Slog.wtf(TAG, "Unexpected note screen brightness for display " + display + " (only " 5256 + mPerDisplayBatteryStats.length + " displays exist...)"); 5257 return; 5258 } 5259 5260 final DisplayBatteryStats displayStats = mPerDisplayBatteryStats[display]; 5261 final int oldBin = displayStats.screenBrightnessBin; 5262 if (oldBin == bin) { 5263 // Nothing changed 5264 overallBin = mScreenBrightnessBin; 5265 } else { 5266 displayStats.screenBrightnessBin = bin; 5267 if (displayStats.screenState == Display.STATE_ON) { 5268 if (oldBin >= 0) { 5269 displayStats.screenBrightnessTimers[oldBin].stopRunningLocked( 5270 elapsedRealtimeMs); 5271 } 5272 displayStats.screenBrightnessTimers[bin].startRunningLocked( 5273 elapsedRealtimeMs); 5274 } 5275 overallBin = evaluateOverallScreenBrightnessBinLocked(); 5276 } 5277 5278 maybeUpdateOverallScreenBrightness(overallBin, elapsedRealtimeMs, uptimeMs); 5279 } 5280 evaluateOverallScreenBrightnessBinLocked()5281 private int evaluateOverallScreenBrightnessBinLocked() { 5282 int overallBin = -1; 5283 final int numDisplays = getDisplayCount(); 5284 for (int display = 0; display < numDisplays; display++) { 5285 final int displayBrightnessBin; 5286 if (mPerDisplayBatteryStats[display].screenState == Display.STATE_ON) { 5287 displayBrightnessBin = mPerDisplayBatteryStats[display].screenBrightnessBin; 5288 } else { 5289 displayBrightnessBin = -1; 5290 } 5291 if (displayBrightnessBin > overallBin) { 5292 overallBin = displayBrightnessBin; 5293 } 5294 } 5295 return overallBin; 5296 } 5297 maybeUpdateOverallScreenBrightness(int overallBin, long elapsedRealtimeMs, long uptimeMs)5298 private void maybeUpdateOverallScreenBrightness(int overallBin, long elapsedRealtimeMs, 5299 long uptimeMs) { 5300 if (mScreenBrightnessBin != overallBin) { 5301 if (overallBin >= 0) { 5302 mHistoryCur.states = (mHistoryCur.states & ~HistoryItem.STATE_BRIGHTNESS_MASK) 5303 | (overallBin << HistoryItem.STATE_BRIGHTNESS_SHIFT); 5304 if (DEBUG_HISTORY) { 5305 Slog.v(TAG, "Screen brightness " + overallBin + " to: " 5306 + Integer.toHexString(mHistoryCur.states)); 5307 } 5308 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 5309 } 5310 if (mScreenState == Display.STATE_ON) { 5311 if (mScreenBrightnessBin >= 0) { 5312 mScreenBrightnessTimer[mScreenBrightnessBin] 5313 .stopRunningLocked(elapsedRealtimeMs); 5314 } 5315 if (overallBin >= 0) { 5316 mScreenBrightnessTimer[overallBin] 5317 .startRunningLocked(elapsedRealtimeMs); 5318 } 5319 } 5320 mScreenBrightnessBin = overallBin; 5321 } 5322 } 5323 5324 @UnsupportedAppUsage noteUserActivityLocked(int uid, int event)5325 public void noteUserActivityLocked(int uid, int event) { 5326 noteUserActivityLocked(uid, event, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 5327 } 5328 noteUserActivityLocked(int uid, int event, long elapsedRealtimeMs, long uptimeMs)5329 public void noteUserActivityLocked(int uid, int event, long elapsedRealtimeMs, long uptimeMs) { 5330 if (mOnBatteryInternal) { 5331 uid = mapUid(uid); 5332 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs).noteUserActivityLocked(event); 5333 } 5334 } 5335 noteWakeUpLocked(String reason, int reasonUid)5336 public void noteWakeUpLocked(String reason, int reasonUid) { 5337 noteWakeUpLocked(reason, reasonUid, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 5338 } 5339 noteWakeUpLocked(String reason, int reasonUid, long elapsedRealtimeMs, long uptimeMs)5340 public void noteWakeUpLocked(String reason, int reasonUid, 5341 long elapsedRealtimeMs, long uptimeMs) { 5342 addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_SCREEN_WAKE_UP, 5343 reason, reasonUid); 5344 } 5345 noteInteractiveLocked(boolean interactive)5346 public void noteInteractiveLocked(boolean interactive) { 5347 noteInteractiveLocked(interactive, mClocks.elapsedRealtime()); 5348 } 5349 noteInteractiveLocked(boolean interactive, long elapsedRealtimeMs)5350 public void noteInteractiveLocked(boolean interactive, long elapsedRealtimeMs) { 5351 if (mInteractive != interactive) { 5352 mInteractive = interactive; 5353 if (DEBUG) Slog.v(TAG, "Interactive: " + interactive); 5354 if (interactive) { 5355 mInteractiveTimer.startRunningLocked(elapsedRealtimeMs); 5356 } else { 5357 mInteractiveTimer.stopRunningLocked(elapsedRealtimeMs); 5358 } 5359 } 5360 } 5361 noteConnectivityChangedLocked(int type, String extra)5362 public void noteConnectivityChangedLocked(int type, String extra) { 5363 noteConnectivityChangedLocked(type, extra, 5364 mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 5365 } 5366 noteConnectivityChangedLocked(int type, String extra, long elapsedRealtimeMs, long uptimeMs)5367 public void noteConnectivityChangedLocked(int type, String extra, 5368 long elapsedRealtimeMs, long uptimeMs) { 5369 addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_CONNECTIVITY_CHANGED, 5370 extra, type); 5371 mNumConnectivityChange++; 5372 } 5373 noteMobileRadioApWakeupLocked(final long elapsedRealtimeMillis, final long uptimeMillis, int uid)5374 private void noteMobileRadioApWakeupLocked(final long elapsedRealtimeMillis, 5375 final long uptimeMillis, int uid) { 5376 uid = mapUid(uid); 5377 addHistoryEventLocked(elapsedRealtimeMillis, uptimeMillis, HistoryItem.EVENT_WAKEUP_AP, "", 5378 uid); 5379 getUidStatsLocked(uid, elapsedRealtimeMillis, uptimeMillis).noteMobileRadioApWakeupLocked(); 5380 } 5381 5382 /** 5383 * Updates the radio power state and returns true if an external stats collection should occur. 5384 */ noteMobileRadioPowerStateLocked(int powerState, long timestampNs, int uid)5385 public boolean noteMobileRadioPowerStateLocked(int powerState, long timestampNs, int uid) { 5386 return noteMobileRadioPowerStateLocked(powerState, timestampNs, uid, 5387 mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 5388 } 5389 noteMobileRadioPowerStateLocked(int powerState, long timestampNs, int uid, long elapsedRealtimeMs, long uptimeMs)5390 public boolean noteMobileRadioPowerStateLocked(int powerState, long timestampNs, int uid, 5391 long elapsedRealtimeMs, long uptimeMs) { 5392 if (mMobileRadioPowerState != powerState) { 5393 long realElapsedRealtimeMs; 5394 final boolean active = 5395 powerState == DataConnectionRealTimeInfo.DC_POWER_STATE_MEDIUM 5396 || powerState == DataConnectionRealTimeInfo.DC_POWER_STATE_HIGH; 5397 if (active) { 5398 if (uid > 0) { 5399 noteMobileRadioApWakeupLocked(elapsedRealtimeMs, uptimeMs, uid); 5400 } 5401 5402 mMobileRadioActiveStartTimeMs = realElapsedRealtimeMs = timestampNs / (1000 * 1000); 5403 mHistoryCur.states |= HistoryItem.STATE_MOBILE_RADIO_ACTIVE_FLAG; 5404 } else { 5405 realElapsedRealtimeMs = timestampNs / (1000*1000); 5406 long lastUpdateTimeMs = mMobileRadioActiveStartTimeMs; 5407 if (realElapsedRealtimeMs < lastUpdateTimeMs) { 5408 Slog.wtf(TAG, "Data connection inactive timestamp " + realElapsedRealtimeMs 5409 + " is before start time " + lastUpdateTimeMs); 5410 realElapsedRealtimeMs = elapsedRealtimeMs; 5411 } else if (realElapsedRealtimeMs < elapsedRealtimeMs) { 5412 mMobileRadioActiveAdjustedTime.addCountLocked(elapsedRealtimeMs 5413 - realElapsedRealtimeMs); 5414 } 5415 mHistoryCur.states &= ~HistoryItem.STATE_MOBILE_RADIO_ACTIVE_FLAG; 5416 } 5417 if (DEBUG_HISTORY) Slog.v(TAG, "Mobile network active " + active + " to: " 5418 + Integer.toHexString(mHistoryCur.states)); 5419 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 5420 mMobileRadioPowerState = powerState; 5421 if (active) { 5422 mMobileRadioActiveTimer.startRunningLocked(elapsedRealtimeMs); 5423 mMobileRadioActivePerAppTimer.startRunningLocked(elapsedRealtimeMs); 5424 } else { 5425 mMobileRadioActiveTimer.stopRunningLocked(realElapsedRealtimeMs); 5426 mMobileRadioActivePerAppTimer.stopRunningLocked(realElapsedRealtimeMs); 5427 // Tell the caller to collect radio network/power stats. 5428 return true; 5429 } 5430 } 5431 return false; 5432 } 5433 notePowerSaveModeLocked(boolean enabled)5434 public void notePowerSaveModeLocked(boolean enabled) { 5435 notePowerSaveModeLocked(enabled, mClocks.elapsedRealtime(), mClocks.uptimeMillis(), false); 5436 } 5437 5438 /** 5439 * Handles power save mode state changes. 5440 */ notePowerSaveModeLocked(boolean enabled, long elapsedRealtimeMs, long uptimeMs, boolean forceLog)5441 public void notePowerSaveModeLocked(boolean enabled, long elapsedRealtimeMs, long uptimeMs, 5442 boolean forceLog) { 5443 if (mPowerSaveModeEnabled != enabled) { 5444 int stepState = enabled ? STEP_LEVEL_MODE_POWER_SAVE : 0; 5445 mModStepMode |= (mCurStepMode & STEP_LEVEL_MODE_POWER_SAVE) ^ stepState; 5446 mCurStepMode = (mCurStepMode & ~STEP_LEVEL_MODE_POWER_SAVE) | stepState; 5447 mPowerSaveModeEnabled = enabled; 5448 if (enabled) { 5449 mHistoryCur.states2 |= HistoryItem.STATE2_POWER_SAVE_FLAG; 5450 if (DEBUG_HISTORY) { 5451 Slog.v(TAG, "Power save mode enabled to: " 5452 + Integer.toHexString(mHistoryCur.states2)); 5453 } 5454 mPowerSaveModeEnabledTimer.startRunningLocked(elapsedRealtimeMs); 5455 } else { 5456 mHistoryCur.states2 &= ~HistoryItem.STATE2_POWER_SAVE_FLAG; 5457 if (DEBUG_HISTORY) { 5458 Slog.v(TAG, "Power save mode disabled to: " 5459 + Integer.toHexString(mHistoryCur.states2)); 5460 } 5461 mPowerSaveModeEnabledTimer.stopRunningLocked(elapsedRealtimeMs); 5462 } 5463 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 5464 FrameworkStatsLog.write(FrameworkStatsLog.BATTERY_SAVER_MODE_STATE_CHANGED, 5465 enabled 5466 ? FrameworkStatsLog.BATTERY_SAVER_MODE_STATE_CHANGED__STATE__ON 5467 : FrameworkStatsLog.BATTERY_SAVER_MODE_STATE_CHANGED__STATE__OFF); 5468 } else if (forceLog) { 5469 // Log an initial value for BATTERY_SAVER_MODE_STATE_CHANGED in order to 5470 // allow the atom to read all future state changes. 5471 FrameworkStatsLog.write(FrameworkStatsLog.BATTERY_SAVER_MODE_STATE_CHANGED, 5472 enabled 5473 ? FrameworkStatsLog.BATTERY_SAVER_MODE_STATE_CHANGED__STATE__ON 5474 : FrameworkStatsLog.BATTERY_SAVER_MODE_STATE_CHANGED__STATE__OFF); 5475 } 5476 } 5477 noteDeviceIdleModeLocked(final int mode, String activeReason, int activeUid)5478 public void noteDeviceIdleModeLocked(final int mode, String activeReason, int activeUid) { 5479 noteDeviceIdleModeLocked(mode, activeReason, activeUid, 5480 mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 5481 } 5482 noteDeviceIdleModeLocked(final int mode, String activeReason, int activeUid, long elapsedRealtimeMs, long uptimeMs)5483 public void noteDeviceIdleModeLocked(final int mode, String activeReason, int activeUid, 5484 long elapsedRealtimeMs, long uptimeMs) { 5485 boolean nowIdling = mode == DEVICE_IDLE_MODE_DEEP; 5486 if (mDeviceIdling && !nowIdling && activeReason == null) { 5487 // We don't go out of general idling mode until explicitly taken out of 5488 // device idle through going active or significant motion. 5489 nowIdling = true; 5490 } 5491 boolean nowLightIdling = mode == DEVICE_IDLE_MODE_LIGHT; 5492 if (mDeviceLightIdling && !nowLightIdling && !nowIdling && activeReason == null) { 5493 // We don't go out of general light idling mode until explicitly taken out of 5494 // device idle through going active or significant motion. 5495 nowLightIdling = true; 5496 } 5497 if (activeReason != null && (mDeviceIdling || mDeviceLightIdling)) { 5498 addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_ACTIVE, 5499 activeReason, activeUid); 5500 } 5501 if (mDeviceIdling != nowIdling || mDeviceLightIdling != nowLightIdling) { 5502 int statsmode; 5503 if (nowIdling) statsmode = DEVICE_IDLE_MODE_DEEP; 5504 else if (nowLightIdling) statsmode = DEVICE_IDLE_MODE_LIGHT; 5505 else statsmode = DEVICE_IDLE_MODE_OFF; 5506 FrameworkStatsLog.write(FrameworkStatsLog.DEVICE_IDLING_MODE_STATE_CHANGED, statsmode); 5507 } 5508 if (mDeviceIdling != nowIdling) { 5509 mDeviceIdling = nowIdling; 5510 int stepState = nowIdling ? STEP_LEVEL_MODE_DEVICE_IDLE : 0; 5511 mModStepMode |= (mCurStepMode&STEP_LEVEL_MODE_DEVICE_IDLE) ^ stepState; 5512 mCurStepMode = (mCurStepMode&~STEP_LEVEL_MODE_DEVICE_IDLE) | stepState; 5513 if (nowIdling) { 5514 mDeviceIdlingTimer.startRunningLocked(elapsedRealtimeMs); 5515 } else { 5516 mDeviceIdlingTimer.stopRunningLocked(elapsedRealtimeMs); 5517 } 5518 } 5519 if (mDeviceLightIdling != nowLightIdling) { 5520 mDeviceLightIdling = nowLightIdling; 5521 if (nowLightIdling) { 5522 mDeviceLightIdlingTimer.startRunningLocked(elapsedRealtimeMs); 5523 } else { 5524 mDeviceLightIdlingTimer.stopRunningLocked(elapsedRealtimeMs); 5525 } 5526 } 5527 if (mDeviceIdleMode != mode) { 5528 mHistoryCur.states2 = (mHistoryCur.states2 & ~HistoryItem.STATE2_DEVICE_IDLE_MASK) 5529 | (mode << HistoryItem.STATE2_DEVICE_IDLE_SHIFT); 5530 if (DEBUG_HISTORY) Slog.v(TAG, "Device idle mode changed to: " 5531 + Integer.toHexString(mHistoryCur.states2)); 5532 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 5533 long lastDuration = elapsedRealtimeMs - mLastIdleTimeStartMs; 5534 mLastIdleTimeStartMs = elapsedRealtimeMs; 5535 if (mDeviceIdleMode == DEVICE_IDLE_MODE_LIGHT) { 5536 if (lastDuration > mLongestLightIdleTimeMs) { 5537 mLongestLightIdleTimeMs = lastDuration; 5538 } 5539 mDeviceIdleModeLightTimer.stopRunningLocked(elapsedRealtimeMs); 5540 } else if (mDeviceIdleMode == DEVICE_IDLE_MODE_DEEP) { 5541 if (lastDuration > mLongestFullIdleTimeMs) { 5542 mLongestFullIdleTimeMs = lastDuration; 5543 } 5544 mDeviceIdleModeFullTimer.stopRunningLocked(elapsedRealtimeMs); 5545 } 5546 if (mode == DEVICE_IDLE_MODE_LIGHT) { 5547 mDeviceIdleModeLightTimer.startRunningLocked(elapsedRealtimeMs); 5548 } else if (mode == DEVICE_IDLE_MODE_DEEP) { 5549 mDeviceIdleModeFullTimer.startRunningLocked(elapsedRealtimeMs); 5550 } 5551 mDeviceIdleMode = mode; 5552 FrameworkStatsLog.write(FrameworkStatsLog.DEVICE_IDLE_MODE_STATE_CHANGED, mode); 5553 } 5554 } 5555 notePackageInstalledLocked(String pkgName, long versionCode)5556 public void notePackageInstalledLocked(String pkgName, long versionCode) { 5557 notePackageInstalledLocked(pkgName, versionCode, 5558 mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 5559 } 5560 notePackageInstalledLocked(String pkgName, long versionCode, long elapsedRealtimeMs, long uptimeMs)5561 public void notePackageInstalledLocked(String pkgName, long versionCode, 5562 long elapsedRealtimeMs, long uptimeMs) { 5563 // XXX need to figure out what to do with long version codes. 5564 addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_PACKAGE_INSTALLED, 5565 pkgName, (int)versionCode); 5566 PackageChange pc = new PackageChange(); 5567 pc.mPackageName = pkgName; 5568 pc.mUpdate = true; 5569 pc.mVersionCode = versionCode; 5570 addPackageChange(pc); 5571 } 5572 notePackageUninstalledLocked(String pkgName)5573 public void notePackageUninstalledLocked(String pkgName) { 5574 notePackageUninstalledLocked(pkgName, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 5575 } 5576 notePackageUninstalledLocked(String pkgName, long elapsedRealtimeMs, long uptimeMs)5577 public void notePackageUninstalledLocked(String pkgName, 5578 long elapsedRealtimeMs, long uptimeMs) { 5579 addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, 5580 HistoryItem.EVENT_PACKAGE_UNINSTALLED, pkgName, 0); 5581 PackageChange pc = new PackageChange(); 5582 pc.mPackageName = pkgName; 5583 pc.mUpdate = true; 5584 addPackageChange(pc); 5585 } 5586 addPackageChange(PackageChange pc)5587 private void addPackageChange(PackageChange pc) { 5588 if (mDailyPackageChanges == null) { 5589 mDailyPackageChanges = new ArrayList<>(); 5590 } 5591 mDailyPackageChanges.add(pc); 5592 } 5593 stopAllGpsSignalQualityTimersLocked(int except)5594 void stopAllGpsSignalQualityTimersLocked(int except) { 5595 stopAllGpsSignalQualityTimersLocked(except, mClocks.elapsedRealtime()); 5596 } 5597 stopAllGpsSignalQualityTimersLocked(int except, long elapsedRealtimeMs)5598 void stopAllGpsSignalQualityTimersLocked(int except, long elapsedRealtimeMs) { 5599 for (int i = 0; i < mGpsSignalQualityTimer.length; i++) { 5600 if (i == except) { 5601 continue; 5602 } 5603 while (mGpsSignalQualityTimer[i].isRunningLocked()) { 5604 mGpsSignalQualityTimer[i].stopRunningLocked(elapsedRealtimeMs); 5605 } 5606 } 5607 } 5608 5609 @UnsupportedAppUsage notePhoneOnLocked()5610 public void notePhoneOnLocked() { 5611 notePhoneOnLocked(mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 5612 } 5613 notePhoneOnLocked(long elapsedRealtimeMs, long uptimeMs)5614 public void notePhoneOnLocked(long elapsedRealtimeMs, long uptimeMs) { 5615 if (!mPhoneOn) { 5616 mHistoryCur.states2 |= HistoryItem.STATE2_PHONE_IN_CALL_FLAG; 5617 if (DEBUG_HISTORY) Slog.v(TAG, "Phone on to: " 5618 + Integer.toHexString(mHistoryCur.states)); 5619 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 5620 mPhoneOn = true; 5621 mPhoneOnTimer.startRunningLocked(elapsedRealtimeMs); 5622 } 5623 } 5624 5625 @UnsupportedAppUsage notePhoneOffLocked()5626 public void notePhoneOffLocked() { 5627 notePhoneOffLocked(mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 5628 } 5629 notePhoneOffLocked(long elapsedRealtimeMs, long uptimeMs)5630 public void notePhoneOffLocked(long elapsedRealtimeMs, long uptimeMs) { 5631 if (mPhoneOn) { 5632 mHistoryCur.states2 &= ~HistoryItem.STATE2_PHONE_IN_CALL_FLAG; 5633 if (DEBUG_HISTORY) Slog.v(TAG, "Phone off to: " 5634 + Integer.toHexString(mHistoryCur.states)); 5635 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 5636 mPhoneOn = false; 5637 mPhoneOnTimer.stopRunningLocked(elapsedRealtimeMs); 5638 } 5639 } 5640 registerUsbStateReceiver(Context context)5641 private void registerUsbStateReceiver(Context context) { 5642 final IntentFilter usbStateFilter = new IntentFilter(); 5643 usbStateFilter.addAction(UsbManager.ACTION_USB_STATE); 5644 context.registerReceiver(new BroadcastReceiver() { 5645 @Override 5646 public void onReceive(Context context, Intent intent) { 5647 final boolean state = intent.getBooleanExtra(UsbManager.USB_CONNECTED, false); 5648 synchronized (BatteryStatsImpl.this) { 5649 noteUsbConnectionStateLocked(state, mClocks.elapsedRealtime(), 5650 mClocks.uptimeMillis()); 5651 } 5652 } 5653 }, usbStateFilter); 5654 synchronized (this) { 5655 if (mUsbDataState == USB_DATA_UNKNOWN) { 5656 final Intent usbState = context.registerReceiver(null, usbStateFilter); 5657 final boolean initState = usbState != null && usbState.getBooleanExtra( 5658 UsbManager.USB_CONNECTED, false); 5659 noteUsbConnectionStateLocked(initState, mClocks.elapsedRealtime(), 5660 mClocks.uptimeMillis()); 5661 } 5662 } 5663 } 5664 noteUsbConnectionStateLocked(boolean connected, long elapsedRealtimeMs, long uptimeMs)5665 private void noteUsbConnectionStateLocked(boolean connected, long elapsedRealtimeMs, 5666 long uptimeMs) { 5667 int newState = connected ? USB_DATA_CONNECTED : USB_DATA_DISCONNECTED; 5668 if (mUsbDataState != newState) { 5669 mUsbDataState = newState; 5670 if (connected) { 5671 mHistoryCur.states2 |= HistoryItem.STATE2_USB_DATA_LINK_FLAG; 5672 } else { 5673 mHistoryCur.states2 &= ~HistoryItem.STATE2_USB_DATA_LINK_FLAG; 5674 } 5675 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 5676 } 5677 } 5678 stopAllPhoneSignalStrengthTimersLocked(int except, long elapsedRealtimeMs)5679 void stopAllPhoneSignalStrengthTimersLocked(int except, long elapsedRealtimeMs) { 5680 for (int i = 0; i < CellSignalStrength.getNumSignalStrengthLevels(); i++) { 5681 if (i == except) { 5682 continue; 5683 } 5684 while (mPhoneSignalStrengthsTimer[i].isRunningLocked()) { 5685 mPhoneSignalStrengthsTimer[i].stopRunningLocked(elapsedRealtimeMs); 5686 } 5687 } 5688 } 5689 fixPhoneServiceState(int state, int signalBin)5690 private int fixPhoneServiceState(int state, int signalBin) { 5691 if (mPhoneSimStateRaw == TelephonyManager.SIM_STATE_ABSENT) { 5692 // In this case we will always be STATE_OUT_OF_SERVICE, so need 5693 // to infer that we are scanning from other data. 5694 if (state == ServiceState.STATE_OUT_OF_SERVICE 5695 && signalBin > CellSignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN) { 5696 state = ServiceState.STATE_IN_SERVICE; 5697 } 5698 } 5699 5700 return state; 5701 } 5702 updateAllPhoneStateLocked(int state, int simState, int strengthBin, long elapsedRealtimeMs, long uptimeMs)5703 private void updateAllPhoneStateLocked(int state, int simState, int strengthBin, 5704 long elapsedRealtimeMs, long uptimeMs) { 5705 boolean scanning = false; 5706 boolean newHistory = false; 5707 5708 mPhoneServiceStateRaw = state; 5709 mPhoneSimStateRaw = simState; 5710 mPhoneSignalStrengthBinRaw = strengthBin; 5711 5712 if (simState == TelephonyManager.SIM_STATE_ABSENT) { 5713 // In this case we will always be STATE_OUT_OF_SERVICE, so need 5714 // to infer that we are scanning from other data. 5715 if (state == ServiceState.STATE_OUT_OF_SERVICE 5716 && strengthBin > CellSignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN) { 5717 state = ServiceState.STATE_IN_SERVICE; 5718 } 5719 } 5720 5721 // If the phone is powered off, stop all timers. 5722 if (state == ServiceState.STATE_POWER_OFF) { 5723 strengthBin = -1; 5724 5725 // If we are in service, make sure the correct signal string timer is running. 5726 } else if (state == ServiceState.STATE_IN_SERVICE) { 5727 // Bin will be changed below. 5728 5729 // If we're out of service, we are in the lowest signal strength 5730 // bin and have the scanning bit set. 5731 } else if (state == ServiceState.STATE_OUT_OF_SERVICE) { 5732 scanning = true; 5733 strengthBin = CellSignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN; 5734 if (!mPhoneSignalScanningTimer.isRunningLocked()) { 5735 mHistoryCur.states |= HistoryItem.STATE_PHONE_SCANNING_FLAG; 5736 newHistory = true; 5737 if (DEBUG_HISTORY) Slog.v(TAG, "Phone started scanning to: " 5738 + Integer.toHexString(mHistoryCur.states)); 5739 mPhoneSignalScanningTimer.startRunningLocked(elapsedRealtimeMs); 5740 FrameworkStatsLog.write(FrameworkStatsLog.PHONE_SERVICE_STATE_CHANGED, state, 5741 simState, strengthBin); 5742 } 5743 } 5744 5745 if (!scanning) { 5746 // If we are no longer scanning, then stop the scanning timer. 5747 if (mPhoneSignalScanningTimer.isRunningLocked()) { 5748 mHistoryCur.states &= ~HistoryItem.STATE_PHONE_SCANNING_FLAG; 5749 if (DEBUG_HISTORY) Slog.v(TAG, "Phone stopped scanning to: " 5750 + Integer.toHexString(mHistoryCur.states)); 5751 newHistory = true; 5752 mPhoneSignalScanningTimer.stopRunningLocked(elapsedRealtimeMs); 5753 FrameworkStatsLog.write(FrameworkStatsLog.PHONE_SERVICE_STATE_CHANGED, state, 5754 simState, strengthBin); 5755 } 5756 } 5757 5758 if (mPhoneServiceState != state) { 5759 mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_PHONE_STATE_MASK) 5760 | (state << HistoryItem.STATE_PHONE_STATE_SHIFT); 5761 if (DEBUG_HISTORY) Slog.v(TAG, "Phone state " + state + " to: " 5762 + Integer.toHexString(mHistoryCur.states)); 5763 newHistory = true; 5764 mPhoneServiceState = state; 5765 } 5766 5767 if (mPhoneSignalStrengthBin != strengthBin) { 5768 if (mPhoneSignalStrengthBin >= 0) { 5769 mPhoneSignalStrengthsTimer[mPhoneSignalStrengthBin].stopRunningLocked( 5770 elapsedRealtimeMs); 5771 } 5772 if (strengthBin >= 0) { 5773 if (!mPhoneSignalStrengthsTimer[strengthBin].isRunningLocked()) { 5774 mPhoneSignalStrengthsTimer[strengthBin].startRunningLocked(elapsedRealtimeMs); 5775 } 5776 mHistoryCur.states = 5777 (mHistoryCur.states & ~HistoryItem.STATE_PHONE_SIGNAL_STRENGTH_MASK) 5778 | (strengthBin << HistoryItem.STATE_PHONE_SIGNAL_STRENGTH_SHIFT); 5779 if (DEBUG_HISTORY) Slog.v(TAG, "Signal strength " + strengthBin + " to: " 5780 + Integer.toHexString(mHistoryCur.states)); 5781 newHistory = true; 5782 FrameworkStatsLog.write( 5783 FrameworkStatsLog.PHONE_SIGNAL_STRENGTH_CHANGED, strengthBin); 5784 } else { 5785 stopAllPhoneSignalStrengthTimersLocked(-1, elapsedRealtimeMs); 5786 } 5787 mPhoneSignalStrengthBin = strengthBin; 5788 } 5789 5790 if (newHistory) { 5791 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 5792 } 5793 } 5794 5795 /** 5796 * Telephony stack updates the phone state. 5797 * @param state phone state from ServiceState.getState() 5798 */ notePhoneStateLocked(int state, int simState)5799 public void notePhoneStateLocked(int state, int simState) { 5800 notePhoneStateLocked(state, simState, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 5801 } 5802 notePhoneStateLocked(int state, int simState, long elapsedRealtimeMs, long uptimeMs)5803 public void notePhoneStateLocked(int state, int simState, 5804 long elapsedRealtimeMs, long uptimeMs) { 5805 updateAllPhoneStateLocked(state, simState, mPhoneSignalStrengthBinRaw, 5806 elapsedRealtimeMs, uptimeMs); 5807 } 5808 5809 @UnsupportedAppUsage notePhoneSignalStrengthLocked(SignalStrength signalStrength)5810 public void notePhoneSignalStrengthLocked(SignalStrength signalStrength) { 5811 notePhoneSignalStrengthLocked(signalStrength, 5812 mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 5813 } 5814 notePhoneSignalStrengthLocked(SignalStrength signalStrength, long elapsedRealtimeMs, long uptimeMs)5815 public void notePhoneSignalStrengthLocked(SignalStrength signalStrength, 5816 long elapsedRealtimeMs, long uptimeMs) { 5817 // Bin the strength. 5818 int bin = signalStrength.getLevel(); 5819 updateAllPhoneStateLocked(mPhoneServiceStateRaw, mPhoneSimStateRaw, bin, 5820 elapsedRealtimeMs, uptimeMs); 5821 } 5822 5823 @UnsupportedAppUsage notePhoneDataConnectionStateLocked(int dataType, boolean hasData, int serviceType)5824 public void notePhoneDataConnectionStateLocked(int dataType, boolean hasData, int serviceType) { 5825 notePhoneDataConnectionStateLocked(dataType, hasData, serviceType, 5826 mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 5827 } 5828 notePhoneDataConnectionStateLocked(int dataType, boolean hasData, int serviceType, long elapsedRealtimeMs, long uptimeMs)5829 public void notePhoneDataConnectionStateLocked(int dataType, boolean hasData, int serviceType, 5830 long elapsedRealtimeMs, long uptimeMs) { 5831 // BatteryStats uses 0 to represent no network type. 5832 // Telephony does not have a concept of no network type, and uses 0 to represent unknown. 5833 // Unknown is included in DATA_CONNECTION_OTHER. 5834 int bin = DATA_CONNECTION_OUT_OF_SERVICE; 5835 if (hasData) { 5836 if (dataType > 0 && dataType <= TelephonyManager.getAllNetworkTypes().length) { 5837 bin = dataType; 5838 } else { 5839 switch (serviceType) { 5840 case ServiceState.STATE_OUT_OF_SERVICE: 5841 bin = DATA_CONNECTION_OUT_OF_SERVICE; 5842 break; 5843 case ServiceState.STATE_EMERGENCY_ONLY: 5844 bin = DATA_CONNECTION_EMERGENCY_SERVICE; 5845 break; 5846 default: 5847 bin = DATA_CONNECTION_OTHER; 5848 break; 5849 } 5850 } 5851 } 5852 if (DEBUG) Log.i(TAG, "Phone Data Connection -> " + dataType + " = " + hasData); 5853 if (mPhoneDataConnectionType != bin) { 5854 mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_DATA_CONNECTION_MASK) 5855 | (bin << HistoryItem.STATE_DATA_CONNECTION_SHIFT); 5856 if (DEBUG_HISTORY) Slog.v(TAG, "Data connection " + bin + " to: " 5857 + Integer.toHexString(mHistoryCur.states)); 5858 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 5859 if (mPhoneDataConnectionType >= 0) { 5860 mPhoneDataConnectionsTimer[mPhoneDataConnectionType].stopRunningLocked( 5861 elapsedRealtimeMs); 5862 } 5863 mPhoneDataConnectionType = bin; 5864 mPhoneDataConnectionsTimer[bin].startRunningLocked(elapsedRealtimeMs); 5865 } 5866 } 5867 noteWifiOnLocked()5868 public void noteWifiOnLocked() { 5869 noteWifiOnLocked(mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 5870 } 5871 noteWifiOnLocked(long elapsedRealtimeMs, long uptimeMs)5872 public void noteWifiOnLocked(long elapsedRealtimeMs, long uptimeMs) { 5873 if (!mWifiOn) { 5874 mHistoryCur.states2 |= HistoryItem.STATE2_WIFI_ON_FLAG; 5875 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI on to: " 5876 + Integer.toHexString(mHistoryCur.states)); 5877 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 5878 mWifiOn = true; 5879 mWifiOnTimer.startRunningLocked(elapsedRealtimeMs); 5880 scheduleSyncExternalStatsLocked("wifi-off", ExternalStatsSync.UPDATE_WIFI); 5881 } 5882 } 5883 noteWifiOffLocked()5884 public void noteWifiOffLocked() { 5885 noteWifiOffLocked(mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 5886 } 5887 noteWifiOffLocked(long elapsedRealtimeMs, long uptimeMs)5888 public void noteWifiOffLocked(long elapsedRealtimeMs, long uptimeMs) { 5889 if (mWifiOn) { 5890 mHistoryCur.states2 &= ~HistoryItem.STATE2_WIFI_ON_FLAG; 5891 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI off to: " 5892 + Integer.toHexString(mHistoryCur.states)); 5893 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 5894 mWifiOn = false; 5895 mWifiOnTimer.stopRunningLocked(elapsedRealtimeMs); 5896 scheduleSyncExternalStatsLocked("wifi-on", ExternalStatsSync.UPDATE_WIFI); 5897 } 5898 } 5899 5900 @UnsupportedAppUsage noteAudioOnLocked(int uid)5901 public void noteAudioOnLocked(int uid) { 5902 noteAudioOnLocked(uid, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 5903 } 5904 noteAudioOnLocked(int uid, long elapsedRealtimeMs, long uptimeMs)5905 public void noteAudioOnLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 5906 uid = mapUid(uid); 5907 if (mAudioOnNesting == 0) { 5908 mHistoryCur.states |= HistoryItem.STATE_AUDIO_ON_FLAG; 5909 if (DEBUG_HISTORY) Slog.v(TAG, "Audio on to: " 5910 + Integer.toHexString(mHistoryCur.states)); 5911 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 5912 mAudioOnTimer.startRunningLocked(elapsedRealtimeMs); 5913 } 5914 mAudioOnNesting++; 5915 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 5916 .noteAudioTurnedOnLocked(elapsedRealtimeMs); 5917 } 5918 5919 @UnsupportedAppUsage noteAudioOffLocked(int uid)5920 public void noteAudioOffLocked(int uid) { 5921 noteAudioOffLocked(uid, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 5922 } 5923 noteAudioOffLocked(int uid, long elapsedRealtimeMs, long uptimeMs)5924 public void noteAudioOffLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 5925 if (mAudioOnNesting == 0) { 5926 return; 5927 } 5928 uid = mapUid(uid); 5929 if (--mAudioOnNesting == 0) { 5930 mHistoryCur.states &= ~HistoryItem.STATE_AUDIO_ON_FLAG; 5931 if (DEBUG_HISTORY) Slog.v(TAG, "Audio off to: " 5932 + Integer.toHexString(mHistoryCur.states)); 5933 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 5934 mAudioOnTimer.stopRunningLocked(elapsedRealtimeMs); 5935 } 5936 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 5937 .noteAudioTurnedOffLocked(elapsedRealtimeMs); 5938 } 5939 5940 @UnsupportedAppUsage noteVideoOnLocked(int uid)5941 public void noteVideoOnLocked(int uid) { 5942 noteVideoOnLocked(uid, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 5943 } 5944 noteVideoOnLocked(int uid, long elapsedRealtimeMs, long uptimeMs)5945 public void noteVideoOnLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 5946 uid = mapUid(uid); 5947 if (mVideoOnNesting == 0) { 5948 mHistoryCur.states2 |= HistoryItem.STATE2_VIDEO_ON_FLAG; 5949 if (DEBUG_HISTORY) Slog.v(TAG, "Video on to: " 5950 + Integer.toHexString(mHistoryCur.states)); 5951 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 5952 mVideoOnTimer.startRunningLocked(elapsedRealtimeMs); 5953 } 5954 mVideoOnNesting++; 5955 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 5956 .noteVideoTurnedOnLocked(elapsedRealtimeMs); 5957 } 5958 5959 @UnsupportedAppUsage noteVideoOffLocked(int uid)5960 public void noteVideoOffLocked(int uid) { 5961 noteVideoOffLocked(uid, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 5962 } 5963 noteVideoOffLocked(int uid, long elapsedRealtimeMs, long uptimeMs)5964 public void noteVideoOffLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 5965 if (mVideoOnNesting == 0) { 5966 return; 5967 } 5968 uid = mapUid(uid); 5969 if (--mVideoOnNesting == 0) { 5970 mHistoryCur.states2 &= ~HistoryItem.STATE2_VIDEO_ON_FLAG; 5971 if (DEBUG_HISTORY) Slog.v(TAG, "Video off to: " 5972 + Integer.toHexString(mHistoryCur.states)); 5973 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 5974 mVideoOnTimer.stopRunningLocked(elapsedRealtimeMs); 5975 } 5976 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 5977 .noteVideoTurnedOffLocked(elapsedRealtimeMs); 5978 } 5979 noteResetAudioLocked()5980 public void noteResetAudioLocked() { 5981 noteResetAudioLocked(mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 5982 } 5983 noteResetAudioLocked(long elapsedRealtimeMs, long uptimeMs)5984 public void noteResetAudioLocked(long elapsedRealtimeMs, long uptimeMs) { 5985 if (mAudioOnNesting > 0) { 5986 mAudioOnNesting = 0; 5987 mHistoryCur.states &= ~HistoryItem.STATE_AUDIO_ON_FLAG; 5988 if (DEBUG_HISTORY) Slog.v(TAG, "Audio off to: " 5989 + Integer.toHexString(mHistoryCur.states)); 5990 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 5991 mAudioOnTimer.stopAllRunningLocked(elapsedRealtimeMs); 5992 for (int i=0; i<mUidStats.size(); i++) { 5993 BatteryStatsImpl.Uid uid = mUidStats.valueAt(i); 5994 uid.noteResetAudioLocked(elapsedRealtimeMs); 5995 } 5996 } 5997 } 5998 noteResetVideoLocked()5999 public void noteResetVideoLocked() { 6000 noteResetVideoLocked(mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 6001 } 6002 noteResetVideoLocked(long elapsedRealtimeMs, long uptimeMs)6003 public void noteResetVideoLocked(long elapsedRealtimeMs, long uptimeMs) { 6004 if (mVideoOnNesting > 0) { 6005 mVideoOnNesting = 0; 6006 mHistoryCur.states2 &= ~HistoryItem.STATE2_VIDEO_ON_FLAG; 6007 if (DEBUG_HISTORY) Slog.v(TAG, "Video off to: " 6008 + Integer.toHexString(mHistoryCur.states)); 6009 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 6010 mVideoOnTimer.stopAllRunningLocked(elapsedRealtimeMs); 6011 for (int i=0; i<mUidStats.size(); i++) { 6012 BatteryStatsImpl.Uid uid = mUidStats.valueAt(i); 6013 uid.noteResetVideoLocked(elapsedRealtimeMs); 6014 } 6015 } 6016 } 6017 noteActivityResumedLocked(int uid)6018 public void noteActivityResumedLocked(int uid) { 6019 noteActivityResumedLocked(uid, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 6020 } 6021 noteActivityResumedLocked(int uid, long elapsedRealtimeMs, long uptimeMs)6022 public void noteActivityResumedLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 6023 uid = mapUid(uid); 6024 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6025 .noteActivityResumedLocked(elapsedRealtimeMs); 6026 } 6027 noteActivityPausedLocked(int uid)6028 public void noteActivityPausedLocked(int uid) { 6029 noteActivityPausedLocked(uid, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 6030 } 6031 noteActivityPausedLocked(int uid, long elapsedRealtimeMs, long uptimeMs)6032 public void noteActivityPausedLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 6033 uid = mapUid(uid); 6034 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6035 .noteActivityPausedLocked(elapsedRealtimeMs); 6036 } 6037 noteVibratorOnLocked(int uid, long durationMillis)6038 public void noteVibratorOnLocked(int uid, long durationMillis) { 6039 noteVibratorOnLocked(uid, durationMillis, 6040 mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 6041 } 6042 noteVibratorOnLocked(int uid, long durationMillis, long elapsedRealtimeMs, long uptimeMs)6043 public void noteVibratorOnLocked(int uid, long durationMillis, 6044 long elapsedRealtimeMs, long uptimeMs) { 6045 uid = mapUid(uid); 6046 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6047 .noteVibratorOnLocked(durationMillis, elapsedRealtimeMs); 6048 } 6049 noteVibratorOffLocked(int uid)6050 public void noteVibratorOffLocked(int uid) { 6051 noteVibratorOffLocked(uid, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 6052 } 6053 noteVibratorOffLocked(int uid, long elapsedRealtimeMs, long uptimeMs)6054 public void noteVibratorOffLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 6055 uid = mapUid(uid); 6056 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6057 .noteVibratorOffLocked(elapsedRealtimeMs); 6058 } 6059 noteFlashlightOnLocked(int uid)6060 public void noteFlashlightOnLocked(int uid) { 6061 noteFlashlightOnLocked(uid, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 6062 } 6063 noteFlashlightOnLocked(int uid, long elapsedRealtimeMs, long uptimeMs)6064 public void noteFlashlightOnLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 6065 uid = mapUid(uid); 6066 if (mFlashlightOnNesting++ == 0) { 6067 mHistoryCur.states2 |= HistoryItem.STATE2_FLASHLIGHT_FLAG; 6068 if (DEBUG_HISTORY) Slog.v(TAG, "Flashlight on to: " 6069 + Integer.toHexString(mHistoryCur.states2)); 6070 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 6071 mFlashlightOnTimer.startRunningLocked(elapsedRealtimeMs); 6072 } 6073 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6074 .noteFlashlightTurnedOnLocked(elapsedRealtimeMs); 6075 } 6076 noteFlashlightOffLocked(int uid)6077 public void noteFlashlightOffLocked(int uid) { 6078 noteFlashlightOffLocked(uid, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 6079 } 6080 noteFlashlightOffLocked(int uid, long elapsedRealtimeMs, long uptimeMs)6081 public void noteFlashlightOffLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 6082 if (mFlashlightOnNesting == 0) { 6083 return; 6084 } 6085 uid = mapUid(uid); 6086 if (--mFlashlightOnNesting == 0) { 6087 mHistoryCur.states2 &= ~HistoryItem.STATE2_FLASHLIGHT_FLAG; 6088 if (DEBUG_HISTORY) Slog.v(TAG, "Flashlight off to: " 6089 + Integer.toHexString(mHistoryCur.states2)); 6090 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 6091 mFlashlightOnTimer.stopRunningLocked(elapsedRealtimeMs); 6092 } 6093 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6094 .noteFlashlightTurnedOffLocked(elapsedRealtimeMs); 6095 } 6096 noteCameraOnLocked(int uid)6097 public void noteCameraOnLocked(int uid) { 6098 noteCameraOnLocked(uid, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 6099 } 6100 noteCameraOnLocked(int uid, long elapsedRealtimeMs, long uptimeMs)6101 public void noteCameraOnLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 6102 uid = mapUid(uid); 6103 if (mCameraOnNesting++ == 0) { 6104 mHistoryCur.states2 |= HistoryItem.STATE2_CAMERA_FLAG; 6105 if (DEBUG_HISTORY) Slog.v(TAG, "Camera on to: " 6106 + Integer.toHexString(mHistoryCur.states2)); 6107 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 6108 mCameraOnTimer.startRunningLocked(elapsedRealtimeMs); 6109 } 6110 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6111 .noteCameraTurnedOnLocked(elapsedRealtimeMs); 6112 } 6113 noteCameraOffLocked(int uid)6114 public void noteCameraOffLocked(int uid) { 6115 noteCameraOffLocked(uid, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 6116 } 6117 noteCameraOffLocked(int uid, long elapsedRealtimeMs, long uptimeMs)6118 public void noteCameraOffLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 6119 if (mCameraOnNesting == 0) { 6120 return; 6121 } 6122 uid = mapUid(uid); 6123 if (--mCameraOnNesting == 0) { 6124 mHistoryCur.states2 &= ~HistoryItem.STATE2_CAMERA_FLAG; 6125 if (DEBUG_HISTORY) Slog.v(TAG, "Camera off to: " 6126 + Integer.toHexString(mHistoryCur.states2)); 6127 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 6128 mCameraOnTimer.stopRunningLocked(elapsedRealtimeMs); 6129 } 6130 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6131 .noteCameraTurnedOffLocked(elapsedRealtimeMs); 6132 } 6133 noteResetCameraLocked()6134 public void noteResetCameraLocked() { 6135 noteResetCameraLocked(mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 6136 } 6137 noteResetCameraLocked(long elapsedRealtimeMs, long uptimeMs)6138 public void noteResetCameraLocked(long elapsedRealtimeMs, long uptimeMs) { 6139 if (mCameraOnNesting > 0) { 6140 mCameraOnNesting = 0; 6141 mHistoryCur.states2 &= ~HistoryItem.STATE2_CAMERA_FLAG; 6142 if (DEBUG_HISTORY) Slog.v(TAG, "Camera off to: " 6143 + Integer.toHexString(mHistoryCur.states2)); 6144 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 6145 mCameraOnTimer.stopAllRunningLocked(elapsedRealtimeMs); 6146 for (int i=0; i<mUidStats.size(); i++) { 6147 BatteryStatsImpl.Uid uid = mUidStats.valueAt(i); 6148 uid.noteResetCameraLocked(elapsedRealtimeMs); 6149 } 6150 } 6151 } 6152 noteResetFlashlightLocked()6153 public void noteResetFlashlightLocked() { 6154 noteResetFlashlightLocked(mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 6155 } 6156 noteResetFlashlightLocked(long elapsedRealtimeMs, long uptimeMs)6157 public void noteResetFlashlightLocked(long elapsedRealtimeMs, long uptimeMs) { 6158 if (mFlashlightOnNesting > 0) { 6159 mFlashlightOnNesting = 0; 6160 mHistoryCur.states2 &= ~HistoryItem.STATE2_FLASHLIGHT_FLAG; 6161 if (DEBUG_HISTORY) Slog.v(TAG, "Flashlight off to: " 6162 + Integer.toHexString(mHistoryCur.states2)); 6163 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 6164 mFlashlightOnTimer.stopAllRunningLocked(elapsedRealtimeMs); 6165 for (int i=0; i<mUidStats.size(); i++) { 6166 BatteryStatsImpl.Uid uid = mUidStats.valueAt(i); 6167 uid.noteResetFlashlightLocked(elapsedRealtimeMs); 6168 } 6169 } 6170 } 6171 noteBluetoothScanStartedLocked(WorkChain workChain, int uid, boolean isUnoptimized, long elapsedRealtimeMs, long uptimeMs)6172 private void noteBluetoothScanStartedLocked(WorkChain workChain, int uid, 6173 boolean isUnoptimized, long elapsedRealtimeMs, long uptimeMs) { 6174 uid = getAttributionUid(uid, workChain); 6175 if (mBluetoothScanNesting == 0) { 6176 mHistoryCur.states2 |= HistoryItem.STATE2_BLUETOOTH_SCAN_FLAG; 6177 if (DEBUG_HISTORY) Slog.v(TAG, "BLE scan started for: " 6178 + Integer.toHexString(mHistoryCur.states2)); 6179 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 6180 mBluetoothScanTimer.startRunningLocked(elapsedRealtimeMs); 6181 } 6182 mBluetoothScanNesting++; 6183 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6184 .noteBluetoothScanStartedLocked(elapsedRealtimeMs, isUnoptimized); 6185 } 6186 noteBluetoothScanStartedFromSourceLocked(WorkSource ws, boolean isUnoptimized)6187 public void noteBluetoothScanStartedFromSourceLocked(WorkSource ws, boolean isUnoptimized) { 6188 noteBluetoothScanStartedFromSourceLocked(ws, isUnoptimized, 6189 mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 6190 } 6191 noteBluetoothScanStartedFromSourceLocked(WorkSource ws, boolean isUnoptimized, long elapsedRealtimeMs, long uptimeMs)6192 public void noteBluetoothScanStartedFromSourceLocked(WorkSource ws, boolean isUnoptimized, 6193 long elapsedRealtimeMs, long uptimeMs) { 6194 final int N = ws.size(); 6195 for (int i = 0; i < N; i++) { 6196 noteBluetoothScanStartedLocked(null, ws.getUid(i), isUnoptimized, 6197 elapsedRealtimeMs, uptimeMs); 6198 } 6199 6200 final List<WorkChain> workChains = ws.getWorkChains(); 6201 if (workChains != null) { 6202 for (int i = 0; i < workChains.size(); ++i) { 6203 noteBluetoothScanStartedLocked(workChains.get(i), -1, isUnoptimized, 6204 elapsedRealtimeMs, uptimeMs); 6205 } 6206 } 6207 } 6208 noteBluetoothScanStoppedLocked(WorkChain workChain, int uid, boolean isUnoptimized, long elapsedRealtimeMs, long uptimeMs)6209 private void noteBluetoothScanStoppedLocked(WorkChain workChain, int uid, 6210 boolean isUnoptimized, long elapsedRealtimeMs, long uptimeMs) { 6211 uid = getAttributionUid(uid, workChain); 6212 mBluetoothScanNesting--; 6213 if (mBluetoothScanNesting == 0) { 6214 mHistoryCur.states2 &= ~HistoryItem.STATE2_BLUETOOTH_SCAN_FLAG; 6215 if (DEBUG_HISTORY) Slog.v(TAG, "BLE scan stopped for: " 6216 + Integer.toHexString(mHistoryCur.states2)); 6217 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 6218 mBluetoothScanTimer.stopRunningLocked(elapsedRealtimeMs); 6219 } 6220 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6221 .noteBluetoothScanStoppedLocked(elapsedRealtimeMs, isUnoptimized); 6222 } 6223 getAttributionUid(int uid, WorkChain workChain)6224 private int getAttributionUid(int uid, WorkChain workChain) { 6225 if (workChain != null) { 6226 return mapUid(workChain.getAttributionUid()); 6227 } 6228 6229 return mapUid(uid); 6230 } 6231 noteBluetoothScanStoppedFromSourceLocked(WorkSource ws, boolean isUnoptimized)6232 public void noteBluetoothScanStoppedFromSourceLocked(WorkSource ws, boolean isUnoptimized) { 6233 noteBluetoothScanStoppedFromSourceLocked(ws, isUnoptimized, 6234 mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 6235 } 6236 noteBluetoothScanStoppedFromSourceLocked(WorkSource ws, boolean isUnoptimized, long elapsedRealtimeMs, long uptimeMs)6237 public void noteBluetoothScanStoppedFromSourceLocked(WorkSource ws, boolean isUnoptimized, 6238 long elapsedRealtimeMs, long uptimeMs) { 6239 final int N = ws.size(); 6240 for (int i = 0; i < N; i++) { 6241 noteBluetoothScanStoppedLocked(null, ws.getUid(i), isUnoptimized, 6242 elapsedRealtimeMs, uptimeMs); 6243 } 6244 6245 final List<WorkChain> workChains = ws.getWorkChains(); 6246 if (workChains != null) { 6247 for (int i = 0; i < workChains.size(); ++i) { 6248 noteBluetoothScanStoppedLocked(workChains.get(i), -1, isUnoptimized, 6249 elapsedRealtimeMs, uptimeMs); 6250 } 6251 } 6252 } 6253 noteResetBluetoothScanLocked()6254 public void noteResetBluetoothScanLocked() { 6255 noteResetBluetoothScanLocked(mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 6256 } 6257 noteResetBluetoothScanLocked(long elapsedRealtimeMs, long uptimeMs)6258 public void noteResetBluetoothScanLocked(long elapsedRealtimeMs, long uptimeMs) { 6259 if (mBluetoothScanNesting > 0) { 6260 mBluetoothScanNesting = 0; 6261 mHistoryCur.states2 &= ~HistoryItem.STATE2_BLUETOOTH_SCAN_FLAG; 6262 if (DEBUG_HISTORY) Slog.v(TAG, "BLE can stopped for: " 6263 + Integer.toHexString(mHistoryCur.states2)); 6264 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 6265 mBluetoothScanTimer.stopAllRunningLocked(elapsedRealtimeMs); 6266 for (int i=0; i<mUidStats.size(); i++) { 6267 BatteryStatsImpl.Uid uid = mUidStats.valueAt(i); 6268 uid.noteResetBluetoothScanLocked(elapsedRealtimeMs); 6269 } 6270 } 6271 } 6272 noteBluetoothScanResultsFromSourceLocked(WorkSource ws, int numNewResults)6273 public void noteBluetoothScanResultsFromSourceLocked(WorkSource ws, int numNewResults) { 6274 noteBluetoothScanResultsFromSourceLocked(ws, numNewResults, 6275 mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 6276 } 6277 noteBluetoothScanResultsFromSourceLocked(WorkSource ws, int numNewResults, long elapsedRealtimeMs, long uptimeMs)6278 public void noteBluetoothScanResultsFromSourceLocked(WorkSource ws, int numNewResults, 6279 long elapsedRealtimeMs, long uptimeMs) { 6280 final int N = ws.size(); 6281 for (int i = 0; i < N; i++) { 6282 int uid = mapUid(ws.getUid(i)); 6283 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6284 .noteBluetoothScanResultsLocked(numNewResults); 6285 } 6286 6287 final List<WorkChain> workChains = ws.getWorkChains(); 6288 if (workChains != null) { 6289 for (int i = 0; i < workChains.size(); ++i) { 6290 final WorkChain wc = workChains.get(i); 6291 int uid = mapUid(wc.getAttributionUid()); 6292 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6293 .noteBluetoothScanResultsLocked(numNewResults); 6294 } 6295 } 6296 } 6297 noteWifiRadioApWakeupLocked(final long elapsedRealtimeMillis, final long uptimeMillis, int uid)6298 private void noteWifiRadioApWakeupLocked(final long elapsedRealtimeMillis, 6299 final long uptimeMillis, int uid) { 6300 uid = mapUid(uid); 6301 addHistoryEventLocked(elapsedRealtimeMillis, uptimeMillis, HistoryItem.EVENT_WAKEUP_AP, "", 6302 uid); 6303 getUidStatsLocked(uid, elapsedRealtimeMillis, uptimeMillis).noteWifiRadioApWakeupLocked(); 6304 } 6305 noteWifiRadioPowerState(int powerState, long timestampNs, int uid)6306 public void noteWifiRadioPowerState(int powerState, long timestampNs, int uid) { 6307 noteWifiRadioPowerState(powerState, timestampNs, uid, 6308 mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 6309 } 6310 noteWifiRadioPowerState(int powerState, long timestampNs, int uid, long elapsedRealtimeMs, long uptimeMs)6311 public void noteWifiRadioPowerState(int powerState, long timestampNs, int uid, 6312 long elapsedRealtimeMs, long uptimeMs) { 6313 if (mWifiRadioPowerState != powerState) { 6314 final boolean active = 6315 powerState == DataConnectionRealTimeInfo.DC_POWER_STATE_MEDIUM 6316 || powerState == DataConnectionRealTimeInfo.DC_POWER_STATE_HIGH; 6317 if (active) { 6318 if (uid > 0) { 6319 noteWifiRadioApWakeupLocked(elapsedRealtimeMs, uptimeMs, uid); 6320 } 6321 mHistoryCur.states |= HistoryItem.STATE_WIFI_RADIO_ACTIVE_FLAG; 6322 mWifiActiveTimer.startRunningLocked(elapsedRealtimeMs); 6323 } else { 6324 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_RADIO_ACTIVE_FLAG; 6325 mWifiActiveTimer.stopRunningLocked(timestampNs / (1000 * 1000)); 6326 } 6327 if (DEBUG_HISTORY) Slog.v(TAG, "Wifi network active " + active + " to: " 6328 + Integer.toHexString(mHistoryCur.states)); 6329 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 6330 mWifiRadioPowerState = powerState; 6331 } 6332 } 6333 noteWifiRunningLocked(WorkSource ws)6334 public void noteWifiRunningLocked(WorkSource ws) { 6335 noteWifiRunningLocked(ws, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 6336 } 6337 noteWifiRunningLocked(WorkSource ws, long elapsedRealtimeMs, long uptimeMs)6338 public void noteWifiRunningLocked(WorkSource ws, long elapsedRealtimeMs, long uptimeMs) { 6339 if (!mGlobalWifiRunning) { 6340 mHistoryCur.states2 |= HistoryItem.STATE2_WIFI_RUNNING_FLAG; 6341 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI running to: " 6342 + Integer.toHexString(mHistoryCur.states)); 6343 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 6344 mGlobalWifiRunning = true; 6345 mGlobalWifiRunningTimer.startRunningLocked(elapsedRealtimeMs); 6346 int N = ws.size(); 6347 for (int i=0; i<N; i++) { 6348 int uid = mapUid(ws.getUid(i)); 6349 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6350 .noteWifiRunningLocked(elapsedRealtimeMs); 6351 } 6352 6353 List<WorkChain> workChains = ws.getWorkChains(); 6354 if (workChains != null) { 6355 for (int i = 0; i < workChains.size(); ++i) { 6356 int uid = mapUid(workChains.get(i).getAttributionUid()); 6357 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6358 .noteWifiRunningLocked(elapsedRealtimeMs); 6359 } 6360 } 6361 6362 scheduleSyncExternalStatsLocked("wifi-running", ExternalStatsSync.UPDATE_WIFI); 6363 } else { 6364 Log.w(TAG, "noteWifiRunningLocked -- called while WIFI running"); 6365 } 6366 } 6367 noteWifiRunningChangedLocked(WorkSource oldWs, WorkSource newWs)6368 public void noteWifiRunningChangedLocked(WorkSource oldWs, WorkSource newWs) { 6369 noteWifiRunningChangedLocked(oldWs, newWs, 6370 mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 6371 } 6372 noteWifiRunningChangedLocked(WorkSource oldWs, WorkSource newWs, long elapsedRealtimeMs, long uptimeMs)6373 public void noteWifiRunningChangedLocked(WorkSource oldWs, WorkSource newWs, 6374 long elapsedRealtimeMs, long uptimeMs) { 6375 if (mGlobalWifiRunning) { 6376 int N = oldWs.size(); 6377 for (int i=0; i<N; i++) { 6378 int uid = mapUid(oldWs.getUid(i)); 6379 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6380 .noteWifiStoppedLocked(elapsedRealtimeMs); 6381 } 6382 6383 List<WorkChain> workChains = oldWs.getWorkChains(); 6384 if (workChains != null) { 6385 for (int i = 0; i < workChains.size(); ++i) { 6386 int uid = mapUid(workChains.get(i).getAttributionUid()); 6387 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6388 .noteWifiStoppedLocked(elapsedRealtimeMs); 6389 } 6390 } 6391 6392 N = newWs.size(); 6393 for (int i=0; i<N; i++) { 6394 int uid = mapUid(newWs.getUid(i)); 6395 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6396 .noteWifiRunningLocked(elapsedRealtimeMs); 6397 } 6398 6399 workChains = newWs.getWorkChains(); 6400 if (workChains != null) { 6401 for (int i = 0; i < workChains.size(); ++i) { 6402 int uid = mapUid(workChains.get(i).getAttributionUid()); 6403 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6404 .noteWifiRunningLocked(elapsedRealtimeMs); 6405 } 6406 } 6407 } else { 6408 Log.w(TAG, "noteWifiRunningChangedLocked -- called while WIFI not running"); 6409 } 6410 } 6411 noteWifiStoppedLocked(WorkSource ws)6412 public void noteWifiStoppedLocked(WorkSource ws) { 6413 noteWifiStoppedLocked(ws, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 6414 } 6415 noteWifiStoppedLocked(WorkSource ws, long elapsedRealtimeMs, long uptimeMs)6416 public void noteWifiStoppedLocked(WorkSource ws, long elapsedRealtimeMs, long uptimeMs) { 6417 if (mGlobalWifiRunning) { 6418 mHistoryCur.states2 &= ~HistoryItem.STATE2_WIFI_RUNNING_FLAG; 6419 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI stopped to: " 6420 + Integer.toHexString(mHistoryCur.states)); 6421 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 6422 mGlobalWifiRunning = false; 6423 mGlobalWifiRunningTimer.stopRunningLocked(elapsedRealtimeMs); 6424 int N = ws.size(); 6425 for (int i=0; i<N; i++) { 6426 int uid = mapUid(ws.getUid(i)); 6427 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6428 .noteWifiStoppedLocked(elapsedRealtimeMs); 6429 } 6430 6431 List<WorkChain> workChains = ws.getWorkChains(); 6432 if (workChains != null) { 6433 for (int i = 0; i < workChains.size(); ++i) { 6434 int uid = mapUid(workChains.get(i).getAttributionUid()); 6435 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6436 .noteWifiStoppedLocked(elapsedRealtimeMs); 6437 } 6438 } 6439 6440 scheduleSyncExternalStatsLocked("wifi-stopped", ExternalStatsSync.UPDATE_WIFI); 6441 } else { 6442 Log.w(TAG, "noteWifiStoppedLocked -- called while WIFI not running"); 6443 } 6444 } 6445 noteWifiStateLocked(int wifiState, String accessPoint)6446 public void noteWifiStateLocked(int wifiState, String accessPoint) { 6447 noteWifiStateLocked(wifiState, accessPoint, mClocks.elapsedRealtime()); 6448 } 6449 noteWifiStateLocked(int wifiState, String accessPoint, long elapsedRealtimeMs)6450 public void noteWifiStateLocked(int wifiState, String accessPoint, long elapsedRealtimeMs) { 6451 if (DEBUG) Log.i(TAG, "WiFi state -> " + wifiState); 6452 if (mWifiState != wifiState) { 6453 if (mWifiState >= 0) { 6454 mWifiStateTimer[mWifiState].stopRunningLocked(elapsedRealtimeMs); 6455 } 6456 mWifiState = wifiState; 6457 mWifiStateTimer[wifiState].startRunningLocked(elapsedRealtimeMs); 6458 scheduleSyncExternalStatsLocked("wifi-state", ExternalStatsSync.UPDATE_WIFI); 6459 } 6460 } 6461 noteWifiSupplicantStateChangedLocked(int supplState, boolean failedAuth)6462 public void noteWifiSupplicantStateChangedLocked(int supplState, boolean failedAuth) { 6463 noteWifiSupplicantStateChangedLocked(supplState, failedAuth, 6464 mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 6465 } 6466 noteWifiSupplicantStateChangedLocked(int supplState, boolean failedAuth, long elapsedRealtimeMs, long uptimeMs)6467 public void noteWifiSupplicantStateChangedLocked(int supplState, boolean failedAuth, 6468 long elapsedRealtimeMs, long uptimeMs) { 6469 if (DEBUG) Log.i(TAG, "WiFi suppl state -> " + supplState); 6470 if (mWifiSupplState != supplState) { 6471 if (mWifiSupplState >= 0) { 6472 mWifiSupplStateTimer[mWifiSupplState].stopRunningLocked(elapsedRealtimeMs); 6473 } 6474 mWifiSupplState = supplState; 6475 mWifiSupplStateTimer[supplState].startRunningLocked(elapsedRealtimeMs); 6476 mHistoryCur.states2 = 6477 (mHistoryCur.states2&~HistoryItem.STATE2_WIFI_SUPPL_STATE_MASK) 6478 | (supplState << HistoryItem.STATE2_WIFI_SUPPL_STATE_SHIFT); 6479 if (DEBUG_HISTORY) Slog.v(TAG, "Wifi suppl state " + supplState + " to: " 6480 + Integer.toHexString(mHistoryCur.states2)); 6481 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 6482 } 6483 } 6484 stopAllWifiSignalStrengthTimersLocked(int except, long elapsedRealtimeMs)6485 void stopAllWifiSignalStrengthTimersLocked(int except, long elapsedRealtimeMs) { 6486 for (int i = 0; i < NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { 6487 if (i == except) { 6488 continue; 6489 } 6490 while (mWifiSignalStrengthsTimer[i].isRunningLocked()) { 6491 mWifiSignalStrengthsTimer[i].stopRunningLocked(elapsedRealtimeMs); 6492 } 6493 } 6494 } 6495 noteWifiRssiChangedLocked(int newRssi)6496 public void noteWifiRssiChangedLocked(int newRssi) { 6497 noteWifiRssiChangedLocked(newRssi, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 6498 } 6499 noteWifiRssiChangedLocked(int newRssi, long elapsedRealtimeMs, long uptimeMs)6500 public void noteWifiRssiChangedLocked(int newRssi, long elapsedRealtimeMs, long uptimeMs) { 6501 int strengthBin = WifiManager.calculateSignalLevel(newRssi, NUM_WIFI_SIGNAL_STRENGTH_BINS); 6502 if (DEBUG) Log.i(TAG, "WiFi rssi -> " + newRssi + " bin=" + strengthBin); 6503 if (mWifiSignalStrengthBin != strengthBin) { 6504 if (mWifiSignalStrengthBin >= 0) { 6505 mWifiSignalStrengthsTimer[mWifiSignalStrengthBin].stopRunningLocked( 6506 elapsedRealtimeMs); 6507 } 6508 if (strengthBin >= 0) { 6509 if (!mWifiSignalStrengthsTimer[strengthBin].isRunningLocked()) { 6510 mWifiSignalStrengthsTimer[strengthBin].startRunningLocked(elapsedRealtimeMs); 6511 } 6512 mHistoryCur.states2 = 6513 (mHistoryCur.states2&~HistoryItem.STATE2_WIFI_SIGNAL_STRENGTH_MASK) 6514 | (strengthBin << HistoryItem.STATE2_WIFI_SIGNAL_STRENGTH_SHIFT); 6515 if (DEBUG_HISTORY) Slog.v(TAG, "Wifi signal strength " + strengthBin + " to: " 6516 + Integer.toHexString(mHistoryCur.states2)); 6517 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 6518 } else { 6519 stopAllWifiSignalStrengthTimersLocked(-1, elapsedRealtimeMs); 6520 } 6521 mWifiSignalStrengthBin = strengthBin; 6522 } 6523 } 6524 6525 int mWifiFullLockNesting = 0; 6526 6527 @UnsupportedAppUsage noteFullWifiLockAcquiredLocked(int uid)6528 public void noteFullWifiLockAcquiredLocked(int uid) { 6529 noteFullWifiLockAcquiredLocked(uid, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 6530 } 6531 noteFullWifiLockAcquiredLocked(int uid, long elapsedRealtimeMs, long uptimeMs)6532 public void noteFullWifiLockAcquiredLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 6533 if (mWifiFullLockNesting == 0) { 6534 mHistoryCur.states |= HistoryItem.STATE_WIFI_FULL_LOCK_FLAG; 6535 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI full lock on to: " 6536 + Integer.toHexString(mHistoryCur.states)); 6537 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 6538 } 6539 mWifiFullLockNesting++; 6540 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6541 .noteFullWifiLockAcquiredLocked(elapsedRealtimeMs); 6542 } 6543 6544 @UnsupportedAppUsage noteFullWifiLockReleasedLocked(int uid)6545 public void noteFullWifiLockReleasedLocked(int uid) { 6546 noteFullWifiLockReleasedLocked(uid, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 6547 } 6548 noteFullWifiLockReleasedLocked(int uid, long elapsedRealtimeMs, long uptimeMs)6549 public void noteFullWifiLockReleasedLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 6550 mWifiFullLockNesting--; 6551 if (mWifiFullLockNesting == 0) { 6552 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_FULL_LOCK_FLAG; 6553 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI full lock off to: " 6554 + Integer.toHexString(mHistoryCur.states)); 6555 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 6556 } 6557 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6558 .noteFullWifiLockReleasedLocked(elapsedRealtimeMs); 6559 } 6560 6561 int mWifiScanNesting = 0; 6562 noteWifiScanStartedLocked(int uid)6563 public void noteWifiScanStartedLocked(int uid) { 6564 noteWifiScanStartedLocked(uid, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 6565 } 6566 noteWifiScanStartedLocked(int uid, long elapsedRealtimeMs, long uptimeMs)6567 public void noteWifiScanStartedLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 6568 if (mWifiScanNesting == 0) { 6569 mHistoryCur.states |= HistoryItem.STATE_WIFI_SCAN_FLAG; 6570 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI scan started for: " 6571 + Integer.toHexString(mHistoryCur.states)); 6572 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 6573 } 6574 mWifiScanNesting++; 6575 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6576 .noteWifiScanStartedLocked(elapsedRealtimeMs); 6577 } 6578 noteWifiScanStoppedLocked(int uid)6579 public void noteWifiScanStoppedLocked(int uid) { 6580 noteWifiScanStoppedLocked(uid, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 6581 } 6582 noteWifiScanStoppedLocked(int uid, long elapsedRealtimeMs, long uptimeMs)6583 public void noteWifiScanStoppedLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 6584 mWifiScanNesting--; 6585 if (mWifiScanNesting == 0) { 6586 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_SCAN_FLAG; 6587 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI scan stopped for: " 6588 + Integer.toHexString(mHistoryCur.states)); 6589 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 6590 } 6591 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6592 .noteWifiScanStoppedLocked(elapsedRealtimeMs); 6593 } 6594 noteWifiBatchedScanStartedLocked(int uid, int csph)6595 public void noteWifiBatchedScanStartedLocked(int uid, int csph) { 6596 noteWifiBatchedScanStartedLocked(uid, csph, 6597 mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 6598 } 6599 noteWifiBatchedScanStartedLocked(int uid, int csph, long elapsedRealtimeMs, long uptimeMs)6600 public void noteWifiBatchedScanStartedLocked(int uid, int csph, 6601 long elapsedRealtimeMs, long uptimeMs) { 6602 uid = mapUid(uid); 6603 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6604 .noteWifiBatchedScanStartedLocked(csph, elapsedRealtimeMs); 6605 } 6606 noteWifiBatchedScanStoppedLocked(int uid)6607 public void noteWifiBatchedScanStoppedLocked(int uid) { 6608 noteWifiBatchedScanStoppedLocked(uid, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 6609 } 6610 noteWifiBatchedScanStoppedLocked(int uid, long elapsedRealtimeMs, long uptimeMs)6611 public void noteWifiBatchedScanStoppedLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 6612 uid = mapUid(uid); 6613 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6614 .noteWifiBatchedScanStoppedLocked(elapsedRealtimeMs); 6615 } 6616 6617 int mWifiMulticastNesting = 0; 6618 6619 @UnsupportedAppUsage noteWifiMulticastEnabledLocked(int uid)6620 public void noteWifiMulticastEnabledLocked(int uid) { 6621 noteWifiMulticastEnabledLocked(uid, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 6622 } 6623 noteWifiMulticastEnabledLocked(int uid, long elapsedRealtimeMs, long uptimeMs)6624 public void noteWifiMulticastEnabledLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 6625 uid = mapUid(uid); 6626 if (mWifiMulticastNesting == 0) { 6627 mHistoryCur.states |= HistoryItem.STATE_WIFI_MULTICAST_ON_FLAG; 6628 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI multicast on to: " 6629 + Integer.toHexString(mHistoryCur.states)); 6630 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 6631 6632 // Start Wifi Multicast overall timer 6633 if (!mWifiMulticastWakelockTimer.isRunningLocked()) { 6634 if (DEBUG_HISTORY) Slog.v(TAG, "WiFi Multicast Overall Timer Started"); 6635 mWifiMulticastWakelockTimer.startRunningLocked(elapsedRealtimeMs); 6636 } 6637 } 6638 mWifiMulticastNesting++; 6639 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6640 .noteWifiMulticastEnabledLocked(elapsedRealtimeMs); 6641 } 6642 6643 @UnsupportedAppUsage noteWifiMulticastDisabledLocked(int uid)6644 public void noteWifiMulticastDisabledLocked(int uid) { 6645 noteWifiMulticastDisabledLocked(uid, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 6646 } 6647 noteWifiMulticastDisabledLocked(int uid, long elapsedRealtimeMs, long uptimeMs)6648 public void noteWifiMulticastDisabledLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 6649 uid = mapUid(uid); 6650 mWifiMulticastNesting--; 6651 if (mWifiMulticastNesting == 0) { 6652 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_MULTICAST_ON_FLAG; 6653 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI multicast off to: " 6654 + Integer.toHexString(mHistoryCur.states)); 6655 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 6656 6657 // Stop Wifi Multicast overall timer 6658 if (mWifiMulticastWakelockTimer.isRunningLocked()) { 6659 if (DEBUG_HISTORY) Slog.v(TAG, "Multicast Overall Timer Stopped"); 6660 mWifiMulticastWakelockTimer.stopRunningLocked(elapsedRealtimeMs); 6661 } 6662 } 6663 getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) 6664 .noteWifiMulticastDisabledLocked(elapsedRealtimeMs); 6665 } 6666 noteFullWifiLockAcquiredFromSourceLocked(WorkSource ws)6667 public void noteFullWifiLockAcquiredFromSourceLocked(WorkSource ws) { 6668 noteFullWifiLockAcquiredFromSourceLocked(ws, 6669 mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 6670 } 6671 noteFullWifiLockAcquiredFromSourceLocked(WorkSource ws, long elapsedRealtimeMs, long uptimeMs)6672 public void noteFullWifiLockAcquiredFromSourceLocked(WorkSource ws, 6673 long elapsedRealtimeMs, long uptimeMs) { 6674 int N = ws.size(); 6675 for (int i=0; i<N; i++) { 6676 final int uid = mapUid(ws.getUid(i)); 6677 noteFullWifiLockAcquiredLocked(uid, elapsedRealtimeMs, uptimeMs); 6678 } 6679 6680 final List<WorkChain> workChains = ws.getWorkChains(); 6681 if (workChains != null) { 6682 for (int i = 0; i < workChains.size(); ++i) { 6683 final WorkChain workChain = workChains.get(i); 6684 final int uid = mapUid(workChain.getAttributionUid()); 6685 noteFullWifiLockAcquiredLocked(uid, elapsedRealtimeMs, uptimeMs); 6686 } 6687 } 6688 } 6689 noteFullWifiLockReleasedFromSourceLocked(WorkSource ws)6690 public void noteFullWifiLockReleasedFromSourceLocked(WorkSource ws) { 6691 noteFullWifiLockReleasedFromSourceLocked(ws, 6692 mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 6693 } 6694 noteFullWifiLockReleasedFromSourceLocked(WorkSource ws, long elapsedRealtimeMs, long uptimeMs)6695 public void noteFullWifiLockReleasedFromSourceLocked(WorkSource ws, 6696 long elapsedRealtimeMs, long uptimeMs) { 6697 int N = ws.size(); 6698 for (int i=0; i<N; i++) { 6699 final int uid = mapUid(ws.getUid(i)); 6700 noteFullWifiLockReleasedLocked(uid, elapsedRealtimeMs, uptimeMs); 6701 } 6702 6703 final List<WorkChain> workChains = ws.getWorkChains(); 6704 if (workChains != null) { 6705 for (int i = 0; i < workChains.size(); ++i) { 6706 final WorkChain workChain = workChains.get(i); 6707 final int uid = mapUid(workChain.getAttributionUid()); 6708 noteFullWifiLockReleasedLocked(uid, elapsedRealtimeMs, uptimeMs); 6709 } 6710 } 6711 } 6712 noteWifiScanStartedFromSourceLocked(WorkSource ws)6713 public void noteWifiScanStartedFromSourceLocked(WorkSource ws) { 6714 noteWifiScanStartedFromSourceLocked(ws, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 6715 } 6716 noteWifiScanStartedFromSourceLocked(WorkSource ws, long elapsedRealtimeMs, long uptimeMs)6717 public void noteWifiScanStartedFromSourceLocked(WorkSource ws, 6718 long elapsedRealtimeMs, long uptimeMs) { 6719 int N = ws.size(); 6720 for (int i=0; i<N; i++) { 6721 final int uid = mapUid(ws.getUid(i)); 6722 noteWifiScanStartedLocked(uid, elapsedRealtimeMs, uptimeMs); 6723 } 6724 6725 final List<WorkChain> workChains = ws.getWorkChains(); 6726 if (workChains != null) { 6727 for (int i = 0; i < workChains.size(); ++i) { 6728 final WorkChain workChain = workChains.get(i); 6729 final int uid = mapUid(workChain.getAttributionUid()); 6730 noteWifiScanStartedLocked(uid, elapsedRealtimeMs, uptimeMs); 6731 } 6732 } 6733 } 6734 noteWifiScanStoppedFromSourceLocked(WorkSource ws)6735 public void noteWifiScanStoppedFromSourceLocked(WorkSource ws) { 6736 noteWifiScanStoppedFromSourceLocked(ws, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 6737 } 6738 noteWifiScanStoppedFromSourceLocked(WorkSource ws, long elapsedRealtimeMs, long uptimeMs)6739 public void noteWifiScanStoppedFromSourceLocked(WorkSource ws, 6740 long elapsedRealtimeMs, long uptimeMs) { 6741 int N = ws.size(); 6742 for (int i=0; i<N; i++) { 6743 final int uid = mapUid(ws.getUid(i)); 6744 noteWifiScanStoppedLocked(uid, elapsedRealtimeMs, uptimeMs); 6745 } 6746 6747 final List<WorkChain> workChains = ws.getWorkChains(); 6748 if (workChains != null) { 6749 for (int i = 0; i < workChains.size(); ++i) { 6750 final WorkChain workChain = workChains.get(i); 6751 final int uid = mapUid(workChain.getAttributionUid()); 6752 noteWifiScanStoppedLocked(uid, elapsedRealtimeMs, uptimeMs); 6753 } 6754 } 6755 } 6756 noteWifiBatchedScanStartedFromSourceLocked(WorkSource ws, int csph)6757 public void noteWifiBatchedScanStartedFromSourceLocked(WorkSource ws, int csph) { 6758 noteWifiBatchedScanStartedFromSourceLocked(ws, csph, 6759 mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 6760 } 6761 noteWifiBatchedScanStartedFromSourceLocked(WorkSource ws, int csph, long elapsedRealtimeMs, long uptimeMs)6762 public void noteWifiBatchedScanStartedFromSourceLocked(WorkSource ws, int csph, 6763 long elapsedRealtimeMs, long uptimeMs) { 6764 int N = ws.size(); 6765 for (int i=0; i<N; i++) { 6766 noteWifiBatchedScanStartedLocked(ws.getUid(i), csph, elapsedRealtimeMs, uptimeMs); 6767 } 6768 6769 final List<WorkChain> workChains = ws.getWorkChains(); 6770 if (workChains != null) { 6771 for (int i = 0; i < workChains.size(); ++i) { 6772 noteWifiBatchedScanStartedLocked(workChains.get(i).getAttributionUid(), csph, 6773 elapsedRealtimeMs, uptimeMs); 6774 } 6775 } 6776 } 6777 noteWifiBatchedScanStoppedFromSourceLocked(WorkSource ws)6778 public void noteWifiBatchedScanStoppedFromSourceLocked(WorkSource ws) { 6779 noteWifiBatchedScanStoppedFromSourceLocked(ws, 6780 mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 6781 } noteWifiBatchedScanStoppedFromSourceLocked(WorkSource ws, long elapsedRealtimeMs, long uptimeMs)6782 public void noteWifiBatchedScanStoppedFromSourceLocked(WorkSource ws, 6783 long elapsedRealtimeMs, long uptimeMs) { 6784 int N = ws.size(); 6785 for (int i=0; i<N; i++) { 6786 noteWifiBatchedScanStoppedLocked(ws.getUid(i), elapsedRealtimeMs, uptimeMs); 6787 } 6788 6789 final List<WorkChain> workChains = ws.getWorkChains(); 6790 if (workChains != null) { 6791 for (int i = 0; i < workChains.size(); ++i) { 6792 noteWifiBatchedScanStoppedLocked(workChains.get(i).getAttributionUid(), 6793 elapsedRealtimeMs, uptimeMs); 6794 } 6795 } 6796 } 6797 includeInStringArray(String[] array, String str)6798 private static String[] includeInStringArray(String[] array, String str) { 6799 if (ArrayUtils.indexOf(array, str) >= 0) { 6800 return array; 6801 } 6802 String[] newArray = new String[array.length+1]; 6803 System.arraycopy(array, 0, newArray, 0, array.length); 6804 newArray[array.length] = str; 6805 return newArray; 6806 } 6807 excludeFromStringArray(String[] array, String str)6808 private static String[] excludeFromStringArray(String[] array, String str) { 6809 int index = ArrayUtils.indexOf(array, str); 6810 if (index >= 0) { 6811 String[] newArray = new String[array.length-1]; 6812 if (index > 0) { 6813 System.arraycopy(array, 0, newArray, 0, index); 6814 } 6815 if (index < array.length-1) { 6816 System.arraycopy(array, index+1, newArray, index, array.length-index-1); 6817 } 6818 return newArray; 6819 } 6820 return array; 6821 } 6822 6823 /** @hide */ noteNetworkInterfaceForTransports(String iface, int[] transportTypes)6824 public void noteNetworkInterfaceForTransports(String iface, int[] transportTypes) { 6825 if (TextUtils.isEmpty(iface)) return; 6826 final int displayTransport = NetworkCapabilitiesUtils.getDisplayTransport(transportTypes); 6827 6828 synchronized (mModemNetworkLock) { 6829 if (displayTransport == TRANSPORT_CELLULAR) { 6830 mModemIfaces = includeInStringArray(mModemIfaces, iface); 6831 if (DEBUG) Slog.d(TAG, "Note mobile iface " + iface + ": " + mModemIfaces); 6832 } else { 6833 mModemIfaces = excludeFromStringArray(mModemIfaces, iface); 6834 if (DEBUG) Slog.d(TAG, "Note non-mobile iface " + iface + ": " + mModemIfaces); 6835 } 6836 } 6837 6838 synchronized (mWifiNetworkLock) { 6839 if (displayTransport == TRANSPORT_WIFI) { 6840 mWifiIfaces = includeInStringArray(mWifiIfaces, iface); 6841 if (DEBUG) Slog.d(TAG, "Note wifi iface " + iface + ": " + mWifiIfaces); 6842 } else { 6843 mWifiIfaces = excludeFromStringArray(mWifiIfaces, iface); 6844 if (DEBUG) Slog.d(TAG, "Note non-wifi iface " + iface + ": " + mWifiIfaces); 6845 } 6846 } 6847 } 6848 6849 /** 6850 * Records timing data related to an incoming Binder call in order to attribute 6851 * the power consumption to the calling app. 6852 */ noteBinderCallStats(int workSourceUid, long incrementalCallCount, Collection<BinderCallsStats.CallStat> callStats)6853 public void noteBinderCallStats(int workSourceUid, long incrementalCallCount, 6854 Collection<BinderCallsStats.CallStat> callStats) { 6855 noteBinderCallStats(workSourceUid, incrementalCallCount, callStats, 6856 mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 6857 } 6858 noteBinderCallStats(int workSourceUid, long incrementalCallCount, Collection<BinderCallsStats.CallStat> callStats, long elapsedRealtimeMs, long uptimeMs)6859 public void noteBinderCallStats(int workSourceUid, long incrementalCallCount, 6860 Collection<BinderCallsStats.CallStat> callStats, 6861 long elapsedRealtimeMs, long uptimeMs) { 6862 synchronized (this) { 6863 getUidStatsLocked(workSourceUid, elapsedRealtimeMs, uptimeMs) 6864 .noteBinderCallStatsLocked(incrementalCallCount, callStats); 6865 } 6866 } 6867 6868 /** 6869 * Takes note of native IDs of threads taking incoming binder calls. The CPU time 6870 * of these threads is attributed to the apps making those binder calls. 6871 */ noteBinderThreadNativeIds(int[] binderThreadNativeTids)6872 public void noteBinderThreadNativeIds(int[] binderThreadNativeTids) { 6873 mSystemServerCpuThreadReader.setBinderThreadNativeTids(binderThreadNativeTids); 6874 } 6875 6876 /** 6877 * Estimates the proportion of system server CPU activity handling incoming binder calls 6878 * that can be attributed to each app 6879 */ 6880 @VisibleForTesting updateSystemServiceCallStats()6881 public void updateSystemServiceCallStats() { 6882 // Start off by computing the average duration of recorded binder calls, 6883 // regardless of which binder or transaction. We will use this as a fallback 6884 // for calls that were not sampled at all. 6885 int totalRecordedCallCount = 0; 6886 long totalRecordedCallTimeMicros = 0; 6887 for (int i = 0; i < mUidStats.size(); i++) { 6888 Uid uid = mUidStats.valueAt(i); 6889 ArraySet<BinderCallStats> binderCallStats = uid.mBinderCallStats; 6890 for (int j = binderCallStats.size() - 1; j >= 0; j--) { 6891 BinderCallStats stats = binderCallStats.valueAt(j); 6892 totalRecordedCallCount += stats.recordedCallCount; 6893 totalRecordedCallTimeMicros += stats.recordedCpuTimeMicros; 6894 } 6895 } 6896 6897 long totalSystemServiceTimeMicros = 0; 6898 6899 // For every UID, use recorded durations of sampled binder calls to estimate 6900 // the total time the system server spent handling requests from this UID. 6901 for (int i = 0; i < mUidStats.size(); i++) { 6902 Uid uid = mUidStats.valueAt(i); 6903 6904 long totalTimeForUidUs = 0; 6905 int totalCallCountForUid = 0; 6906 ArraySet<BinderCallStats> binderCallStats = uid.mBinderCallStats; 6907 for (int j = binderCallStats.size() - 1; j >= 0; j--) { 6908 BinderCallStats stats = binderCallStats.valueAt(j); 6909 totalCallCountForUid += stats.callCount; 6910 if (stats.recordedCallCount > 0) { 6911 totalTimeForUidUs += 6912 stats.callCount * stats.recordedCpuTimeMicros / stats.recordedCallCount; 6913 } else if (totalRecordedCallCount > 0) { 6914 totalTimeForUidUs += 6915 stats.callCount * totalRecordedCallTimeMicros / totalRecordedCallCount; 6916 } 6917 } 6918 6919 if (totalCallCountForUid < uid.mBinderCallCount && totalRecordedCallCount > 0) { 6920 // Estimate remaining calls, which were not tracked because of binder call 6921 // stats sampling 6922 totalTimeForUidUs += 6923 (uid.mBinderCallCount - totalCallCountForUid) * totalRecordedCallTimeMicros 6924 / totalRecordedCallCount; 6925 } 6926 6927 uid.mSystemServiceTimeUs = totalTimeForUidUs; 6928 totalSystemServiceTimeMicros += totalTimeForUidUs; 6929 } 6930 6931 for (int i = 0; i < mUidStats.size(); i++) { 6932 Uid uid = mUidStats.valueAt(i); 6933 if (totalSystemServiceTimeMicros > 0) { 6934 uid.mProportionalSystemServiceUsage = 6935 (double) uid.mSystemServiceTimeUs / totalSystemServiceTimeMicros; 6936 } else { 6937 uid.mProportionalSystemServiceUsage = 0; 6938 } 6939 } 6940 } 6941 getWifiIfaces()6942 public String[] getWifiIfaces() { 6943 synchronized (mWifiNetworkLock) { 6944 return mWifiIfaces; 6945 } 6946 } 6947 getMobileIfaces()6948 public String[] getMobileIfaces() { 6949 synchronized (mModemNetworkLock) { 6950 return mModemIfaces; 6951 } 6952 } 6953 6954 @UnsupportedAppUsage getScreenOnTime(long elapsedRealtimeUs, int which)6955 @Override public long getScreenOnTime(long elapsedRealtimeUs, int which) { 6956 return mScreenOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 6957 } 6958 getScreenOnCount(int which)6959 @Override public int getScreenOnCount(int which) { 6960 return mScreenOnTimer.getCountLocked(which); 6961 } 6962 getScreenDozeTime(long elapsedRealtimeUs, int which)6963 @Override public long getScreenDozeTime(long elapsedRealtimeUs, int which) { 6964 return mScreenDozeTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 6965 } 6966 getScreenDozeCount(int which)6967 @Override public int getScreenDozeCount(int which) { 6968 return mScreenDozeTimer.getCountLocked(which); 6969 } 6970 6971 @UnsupportedAppUsage getScreenBrightnessTime(int brightnessBin, long elapsedRealtimeUs, int which)6972 @Override public long getScreenBrightnessTime(int brightnessBin, 6973 long elapsedRealtimeUs, int which) { 6974 return mScreenBrightnessTimer[brightnessBin].getTotalTimeLocked( 6975 elapsedRealtimeUs, which); 6976 } 6977 getScreenBrightnessTimer(int brightnessBin)6978 @Override public Timer getScreenBrightnessTimer(int brightnessBin) { 6979 return mScreenBrightnessTimer[brightnessBin]; 6980 } 6981 6982 @Override getDisplayCount()6983 public int getDisplayCount() { 6984 return mPerDisplayBatteryStats.length; 6985 } 6986 6987 @Override getDisplayScreenOnTime(int display, long elapsedRealtimeUs)6988 public long getDisplayScreenOnTime(int display, long elapsedRealtimeUs) { 6989 return mPerDisplayBatteryStats[display].screenOnTimer.getTotalTimeLocked(elapsedRealtimeUs, 6990 STATS_SINCE_CHARGED); 6991 } 6992 6993 @Override getDisplayScreenDozeTime(int display, long elapsedRealtimeUs)6994 public long getDisplayScreenDozeTime(int display, long elapsedRealtimeUs) { 6995 return mPerDisplayBatteryStats[display].screenDozeTimer.getTotalTimeLocked( 6996 elapsedRealtimeUs, STATS_SINCE_CHARGED); 6997 } 6998 6999 @Override getDisplayScreenBrightnessTime(int display, int brightnessBin, long elapsedRealtimeUs)7000 public long getDisplayScreenBrightnessTime(int display, int brightnessBin, 7001 long elapsedRealtimeUs) { 7002 final DisplayBatteryStats displayStats = mPerDisplayBatteryStats[display]; 7003 return displayStats.screenBrightnessTimers[brightnessBin].getTotalTimeLocked( 7004 elapsedRealtimeUs, STATS_SINCE_CHARGED); 7005 } 7006 getInteractiveTime(long elapsedRealtimeUs, int which)7007 @Override public long getInteractiveTime(long elapsedRealtimeUs, int which) { 7008 return mInteractiveTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 7009 } 7010 getPowerSaveModeEnabledTime(long elapsedRealtimeUs, int which)7011 @Override public long getPowerSaveModeEnabledTime(long elapsedRealtimeUs, int which) { 7012 return mPowerSaveModeEnabledTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 7013 } 7014 getPowerSaveModeEnabledCount(int which)7015 @Override public int getPowerSaveModeEnabledCount(int which) { 7016 return mPowerSaveModeEnabledTimer.getCountLocked(which); 7017 } 7018 getDeviceIdleModeTime(int mode, long elapsedRealtimeUs, int which)7019 @Override public long getDeviceIdleModeTime(int mode, long elapsedRealtimeUs, 7020 int which) { 7021 switch (mode) { 7022 case DEVICE_IDLE_MODE_LIGHT: 7023 return mDeviceIdleModeLightTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 7024 case DEVICE_IDLE_MODE_DEEP: 7025 return mDeviceIdleModeFullTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 7026 } 7027 return 0; 7028 } 7029 getDeviceIdleModeCount(int mode, int which)7030 @Override public int getDeviceIdleModeCount(int mode, int which) { 7031 switch (mode) { 7032 case DEVICE_IDLE_MODE_LIGHT: 7033 return mDeviceIdleModeLightTimer.getCountLocked(which); 7034 case DEVICE_IDLE_MODE_DEEP: 7035 return mDeviceIdleModeFullTimer.getCountLocked(which); 7036 } 7037 return 0; 7038 } 7039 getLongestDeviceIdleModeTime(int mode)7040 @Override public long getLongestDeviceIdleModeTime(int mode) { 7041 switch (mode) { 7042 case DEVICE_IDLE_MODE_LIGHT: 7043 return mLongestLightIdleTimeMs; 7044 case DEVICE_IDLE_MODE_DEEP: 7045 return mLongestFullIdleTimeMs; 7046 } 7047 return 0; 7048 } 7049 getDeviceIdlingTime(int mode, long elapsedRealtimeUs, int which)7050 @Override public long getDeviceIdlingTime(int mode, long elapsedRealtimeUs, int which) { 7051 switch (mode) { 7052 case DEVICE_IDLE_MODE_LIGHT: 7053 return mDeviceLightIdlingTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 7054 case DEVICE_IDLE_MODE_DEEP: 7055 return mDeviceIdlingTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 7056 } 7057 return 0; 7058 } 7059 getDeviceIdlingCount(int mode, int which)7060 @Override public int getDeviceIdlingCount(int mode, int which) { 7061 switch (mode) { 7062 case DEVICE_IDLE_MODE_LIGHT: 7063 return mDeviceLightIdlingTimer.getCountLocked(which); 7064 case DEVICE_IDLE_MODE_DEEP: 7065 return mDeviceIdlingTimer.getCountLocked(which); 7066 } 7067 return 0; 7068 } 7069 getNumConnectivityChange(int which)7070 @Override public int getNumConnectivityChange(int which) { 7071 return mNumConnectivityChange; 7072 } 7073 getGpsSignalQualityTime(int strengthBin, long elapsedRealtimeUs, int which)7074 @Override public long getGpsSignalQualityTime(int strengthBin, 7075 long elapsedRealtimeUs, int which) { 7076 if (strengthBin < 0 || strengthBin >= mGpsSignalQualityTimer.length) { 7077 return 0; 7078 } 7079 return mGpsSignalQualityTimer[strengthBin].getTotalTimeLocked( 7080 elapsedRealtimeUs, which); 7081 } 7082 getGpsBatteryDrainMaMs()7083 @Override public long getGpsBatteryDrainMaMs() { 7084 final double opVolt = mPowerProfile.getAveragePower( 7085 PowerProfile.POWER_GPS_OPERATING_VOLTAGE) / 1000.0; 7086 if (opVolt == 0) { 7087 return 0; 7088 } 7089 double energyUsedMaMs = 0.0; 7090 final int which = STATS_SINCE_CHARGED; 7091 final long rawRealtimeUs = SystemClock.elapsedRealtime() * 1000; 7092 for(int i=0; i < mGpsSignalQualityTimer.length; i++) { 7093 energyUsedMaMs 7094 += mPowerProfile.getAveragePower(PowerProfile.POWER_GPS_SIGNAL_QUALITY_BASED, i) 7095 * (getGpsSignalQualityTime(i, rawRealtimeUs, which) / 1000); 7096 } 7097 return (long) energyUsedMaMs; 7098 } 7099 7100 @UnsupportedAppUsage getPhoneOnTime(long elapsedRealtimeUs, int which)7101 @Override public long getPhoneOnTime(long elapsedRealtimeUs, int which) { 7102 return mPhoneOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 7103 } 7104 getPhoneOnCount(int which)7105 @Override public int getPhoneOnCount(int which) { 7106 return mPhoneOnTimer.getCountLocked(which); 7107 } 7108 7109 @UnsupportedAppUsage getPhoneSignalStrengthTime(int strengthBin, long elapsedRealtimeUs, int which)7110 @Override public long getPhoneSignalStrengthTime(int strengthBin, 7111 long elapsedRealtimeUs, int which) { 7112 return mPhoneSignalStrengthsTimer[strengthBin].getTotalTimeLocked( 7113 elapsedRealtimeUs, which); 7114 } 7115 7116 @UnsupportedAppUsage getPhoneSignalScanningTime( long elapsedRealtimeUs, int which)7117 @Override public long getPhoneSignalScanningTime( 7118 long elapsedRealtimeUs, int which) { 7119 return mPhoneSignalScanningTimer.getTotalTimeLocked( 7120 elapsedRealtimeUs, which); 7121 } 7122 getPhoneSignalScanningTimer()7123 @Override public Timer getPhoneSignalScanningTimer() { 7124 return mPhoneSignalScanningTimer; 7125 } 7126 7127 @UnsupportedAppUsage getPhoneSignalStrengthCount(int strengthBin, int which)7128 @Override public int getPhoneSignalStrengthCount(int strengthBin, int which) { 7129 return mPhoneSignalStrengthsTimer[strengthBin].getCountLocked(which); 7130 } 7131 getPhoneSignalStrengthTimer(int strengthBin)7132 @Override public Timer getPhoneSignalStrengthTimer(int strengthBin) { 7133 return mPhoneSignalStrengthsTimer[strengthBin]; 7134 } 7135 7136 @UnsupportedAppUsage getPhoneDataConnectionTime(int dataType, long elapsedRealtimeUs, int which)7137 @Override public long getPhoneDataConnectionTime(int dataType, 7138 long elapsedRealtimeUs, int which) { 7139 return mPhoneDataConnectionsTimer[dataType].getTotalTimeLocked( 7140 elapsedRealtimeUs, which); 7141 } 7142 7143 @UnsupportedAppUsage getPhoneDataConnectionCount(int dataType, int which)7144 @Override public int getPhoneDataConnectionCount(int dataType, int which) { 7145 return mPhoneDataConnectionsTimer[dataType].getCountLocked(which); 7146 } 7147 getPhoneDataConnectionTimer(int dataType)7148 @Override public Timer getPhoneDataConnectionTimer(int dataType) { 7149 return mPhoneDataConnectionsTimer[dataType]; 7150 } 7151 7152 @UnsupportedAppUsage getMobileRadioActiveTime(long elapsedRealtimeUs, int which)7153 @Override public long getMobileRadioActiveTime(long elapsedRealtimeUs, int which) { 7154 return mMobileRadioActiveTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 7155 } 7156 getMobileRadioActiveCount(int which)7157 @Override public int getMobileRadioActiveCount(int which) { 7158 return mMobileRadioActiveTimer.getCountLocked(which); 7159 } 7160 getMobileRadioActiveAdjustedTime(int which)7161 @Override public long getMobileRadioActiveAdjustedTime(int which) { 7162 return mMobileRadioActiveAdjustedTime.getCountLocked(which); 7163 } 7164 getMobileRadioActiveUnknownTime(int which)7165 @Override public long getMobileRadioActiveUnknownTime(int which) { 7166 return mMobileRadioActiveUnknownTime.getCountLocked(which); 7167 } 7168 getMobileRadioActiveUnknownCount(int which)7169 @Override public int getMobileRadioActiveUnknownCount(int which) { 7170 return (int)mMobileRadioActiveUnknownCount.getCountLocked(which); 7171 } 7172 getWifiMulticastWakelockTime( long elapsedRealtimeUs, int which)7173 @Override public long getWifiMulticastWakelockTime( 7174 long elapsedRealtimeUs, int which) { 7175 return mWifiMulticastWakelockTimer.getTotalTimeLocked( 7176 elapsedRealtimeUs, which); 7177 } 7178 getWifiMulticastWakelockCount(int which)7179 @Override public int getWifiMulticastWakelockCount(int which) { 7180 return mWifiMulticastWakelockTimer.getCountLocked(which); 7181 } 7182 7183 @UnsupportedAppUsage getWifiOnTime(long elapsedRealtimeUs, int which)7184 @Override public long getWifiOnTime(long elapsedRealtimeUs, int which) { 7185 return mWifiOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 7186 } 7187 getWifiActiveTime(long elapsedRealtimeUs, int which)7188 @Override public long getWifiActiveTime(long elapsedRealtimeUs, int which) { 7189 return mWifiActiveTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 7190 } 7191 7192 @UnsupportedAppUsage getGlobalWifiRunningTime(long elapsedRealtimeUs, int which)7193 @Override public long getGlobalWifiRunningTime(long elapsedRealtimeUs, int which) { 7194 return mGlobalWifiRunningTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 7195 } 7196 getWifiStateTime(int wifiState, long elapsedRealtimeUs, int which)7197 @Override public long getWifiStateTime(int wifiState, 7198 long elapsedRealtimeUs, int which) { 7199 return mWifiStateTimer[wifiState].getTotalTimeLocked( 7200 elapsedRealtimeUs, which); 7201 } 7202 getWifiStateCount(int wifiState, int which)7203 @Override public int getWifiStateCount(int wifiState, int which) { 7204 return mWifiStateTimer[wifiState].getCountLocked(which); 7205 } 7206 getWifiStateTimer(int wifiState)7207 @Override public Timer getWifiStateTimer(int wifiState) { 7208 return mWifiStateTimer[wifiState]; 7209 } 7210 getWifiSupplStateTime(int state, long elapsedRealtimeUs, int which)7211 @Override public long getWifiSupplStateTime(int state, 7212 long elapsedRealtimeUs, int which) { 7213 return mWifiSupplStateTimer[state].getTotalTimeLocked( 7214 elapsedRealtimeUs, which); 7215 } 7216 getWifiSupplStateCount(int state, int which)7217 @Override public int getWifiSupplStateCount(int state, int which) { 7218 return mWifiSupplStateTimer[state].getCountLocked(which); 7219 } 7220 getWifiSupplStateTimer(int state)7221 @Override public Timer getWifiSupplStateTimer(int state) { 7222 return mWifiSupplStateTimer[state]; 7223 } 7224 getWifiSignalStrengthTime(int strengthBin, long elapsedRealtimeUs, int which)7225 @Override public long getWifiSignalStrengthTime(int strengthBin, 7226 long elapsedRealtimeUs, int which) { 7227 return mWifiSignalStrengthsTimer[strengthBin].getTotalTimeLocked( 7228 elapsedRealtimeUs, which); 7229 } 7230 getWifiSignalStrengthCount(int strengthBin, int which)7231 @Override public int getWifiSignalStrengthCount(int strengthBin, int which) { 7232 return mWifiSignalStrengthsTimer[strengthBin].getCountLocked(which); 7233 } 7234 getWifiSignalStrengthTimer(int strengthBin)7235 @Override public Timer getWifiSignalStrengthTimer(int strengthBin) { 7236 return mWifiSignalStrengthsTimer[strengthBin]; 7237 } 7238 7239 @Override getBluetoothControllerActivity()7240 public ControllerActivityCounter getBluetoothControllerActivity() { 7241 return mBluetoothActivity; 7242 } 7243 7244 @Override getWifiControllerActivity()7245 public ControllerActivityCounter getWifiControllerActivity() { 7246 return mWifiActivity; 7247 } 7248 7249 @Override getModemControllerActivity()7250 public ControllerActivityCounter getModemControllerActivity() { 7251 return mModemActivity; 7252 } 7253 7254 @Override hasBluetoothActivityReporting()7255 public boolean hasBluetoothActivityReporting() { 7256 return mHasBluetoothReporting; 7257 } 7258 7259 @Override hasWifiActivityReporting()7260 public boolean hasWifiActivityReporting() { 7261 return mHasWifiReporting; 7262 } 7263 7264 @Override hasModemActivityReporting()7265 public boolean hasModemActivityReporting() { 7266 return mHasModemReporting; 7267 } 7268 7269 @Override getFlashlightOnTime(long elapsedRealtimeUs, int which)7270 public long getFlashlightOnTime(long elapsedRealtimeUs, int which) { 7271 return mFlashlightOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 7272 } 7273 7274 @Override getFlashlightOnCount(int which)7275 public long getFlashlightOnCount(int which) { 7276 return mFlashlightOnTimer.getCountLocked(which); 7277 } 7278 7279 @Override getCameraOnTime(long elapsedRealtimeUs, int which)7280 public long getCameraOnTime(long elapsedRealtimeUs, int which) { 7281 return mCameraOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 7282 } 7283 7284 @Override getBluetoothScanTime(long elapsedRealtimeUs, int which)7285 public long getBluetoothScanTime(long elapsedRealtimeUs, int which) { 7286 return mBluetoothScanTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 7287 } 7288 7289 @Override 7290 @UnsupportedAppUsage getNetworkActivityBytes(int type, int which)7291 public long getNetworkActivityBytes(int type, int which) { 7292 if (type >= 0 && type < mNetworkByteActivityCounters.length) { 7293 return mNetworkByteActivityCounters[type].getCountLocked(which); 7294 } else { 7295 return 0; 7296 } 7297 } 7298 7299 @Override getNetworkActivityPackets(int type, int which)7300 public long getNetworkActivityPackets(int type, int which) { 7301 if (type >= 0 && type < mNetworkPacketActivityCounters.length) { 7302 return mNetworkPacketActivityCounters[type].getCountLocked(which); 7303 } else { 7304 return 0; 7305 } 7306 } 7307 7308 @Override getBluetoothMeasuredBatteryConsumptionUC()7309 public long getBluetoothMeasuredBatteryConsumptionUC() { 7310 return getPowerBucketConsumptionUC(MeasuredEnergyStats.POWER_BUCKET_BLUETOOTH); 7311 } 7312 7313 @Override getCpuMeasuredBatteryConsumptionUC()7314 public long getCpuMeasuredBatteryConsumptionUC() { 7315 return getPowerBucketConsumptionUC(MeasuredEnergyStats.POWER_BUCKET_CPU); 7316 } 7317 7318 @Override getGnssMeasuredBatteryConsumptionUC()7319 public long getGnssMeasuredBatteryConsumptionUC() { 7320 return getPowerBucketConsumptionUC(MeasuredEnergyStats.POWER_BUCKET_GNSS); 7321 } 7322 7323 @Override getMobileRadioMeasuredBatteryConsumptionUC()7324 public long getMobileRadioMeasuredBatteryConsumptionUC() { 7325 return getPowerBucketConsumptionUC(MeasuredEnergyStats.POWER_BUCKET_MOBILE_RADIO); 7326 } 7327 7328 @Override getScreenOnMeasuredBatteryConsumptionUC()7329 public long getScreenOnMeasuredBatteryConsumptionUC() { 7330 return getPowerBucketConsumptionUC(MeasuredEnergyStats.POWER_BUCKET_SCREEN_ON); 7331 } 7332 7333 @Override getScreenDozeMeasuredBatteryConsumptionUC()7334 public long getScreenDozeMeasuredBatteryConsumptionUC() { 7335 return getPowerBucketConsumptionUC(MeasuredEnergyStats.POWER_BUCKET_SCREEN_DOZE); 7336 } 7337 7338 @Override getWifiMeasuredBatteryConsumptionUC()7339 public long getWifiMeasuredBatteryConsumptionUC() { 7340 return getPowerBucketConsumptionUC(MeasuredEnergyStats.POWER_BUCKET_WIFI); 7341 } 7342 7343 /** 7344 * Returns the consumption (in microcoulombs) that the given standard power bucket consumed. 7345 * Will return {@link #POWER_DATA_UNAVAILABLE} if data is unavailable 7346 * 7347 * @param bucket standard power bucket of interest 7348 * @return charge (in microcoulombs) used for this power bucket 7349 */ getPowerBucketConsumptionUC(@tandardPowerBucket int bucket)7350 private long getPowerBucketConsumptionUC(@StandardPowerBucket int bucket) { 7351 if (mGlobalMeasuredEnergyStats == null) { 7352 return POWER_DATA_UNAVAILABLE; 7353 } 7354 return mGlobalMeasuredEnergyStats.getAccumulatedStandardBucketCharge(bucket); 7355 } 7356 7357 @Override getCustomConsumerMeasuredBatteryConsumptionUC()7358 public @Nullable long[] getCustomConsumerMeasuredBatteryConsumptionUC() { 7359 if (mGlobalMeasuredEnergyStats == null) { 7360 return null; 7361 } 7362 return mGlobalMeasuredEnergyStats.getAccumulatedCustomBucketCharges(); 7363 } 7364 7365 /** 7366 * Returns the names of custom power components. 7367 */ 7368 @Override getCustomEnergyConsumerNames()7369 public @NonNull String[] getCustomEnergyConsumerNames() { 7370 if (mGlobalMeasuredEnergyStats == null) { 7371 return new String[0]; 7372 } 7373 final String[] names = mGlobalMeasuredEnergyStats.getCustomBucketNames(); 7374 for (int i = 0; i < names.length; i++) { 7375 if (TextUtils.isEmpty(names[i])) { 7376 names[i] = "CUSTOM_" + BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID + i; 7377 } 7378 } 7379 return names; 7380 } 7381 getStartClockTime()7382 @Override public long getStartClockTime() { 7383 final long currentTimeMs = mClocks.currentTimeMillis(); 7384 if ((currentTimeMs > MILLISECONDS_IN_YEAR 7385 && mStartClockTimeMs < (currentTimeMs - MILLISECONDS_IN_YEAR)) 7386 || (mStartClockTimeMs > currentTimeMs)) { 7387 // If the start clock time has changed by more than a year, then presumably 7388 // the previous time was completely bogus. So we are going to figure out a 7389 // new time based on how much time has elapsed since we started counting. 7390 recordCurrentTimeChangeLocked(currentTimeMs, mClocks.elapsedRealtime(), 7391 mClocks.uptimeMillis()); 7392 return currentTimeMs - (mClocks.elapsedRealtime() - (mRealtimeStartUs / 1000)); 7393 } 7394 return mStartClockTimeMs; 7395 } 7396 getStartPlatformVersion()7397 @Override public String getStartPlatformVersion() { 7398 return mStartPlatformVersion; 7399 } 7400 getEndPlatformVersion()7401 @Override public String getEndPlatformVersion() { 7402 return mEndPlatformVersion; 7403 } 7404 getParcelVersion()7405 @Override public int getParcelVersion() { 7406 return VERSION; 7407 } 7408 getIsOnBattery()7409 @Override public boolean getIsOnBattery() { 7410 return mOnBattery; 7411 } 7412 getStatsStartRealtime()7413 @Override public long getStatsStartRealtime() { 7414 return mRealtimeStartUs; 7415 } 7416 7417 @UnsupportedAppUsage getUidStats()7418 @Override public SparseArray<? extends BatteryStats.Uid> getUidStats() { 7419 return mUidStats; 7420 } 7421 resetIfNotNull(T t, boolean detachIfReset, long elapsedRealtimeUs)7422 private static <T extends TimeBaseObs> boolean resetIfNotNull(T t, boolean detachIfReset, 7423 long elapsedRealtimeUs) { 7424 if (t != null) { 7425 return t.reset(detachIfReset, elapsedRealtimeUs); 7426 } 7427 return true; 7428 } 7429 resetIfNotNull(T[] t, boolean detachIfReset, long elapsedRealtimeUs)7430 private static <T extends TimeBaseObs> boolean resetIfNotNull(T[] t, boolean detachIfReset, 7431 long elapsedRealtimeUs) { 7432 if (t != null) { 7433 boolean ret = true; 7434 for (int i = 0; i < t.length; i++) { 7435 ret &= resetIfNotNull(t[i], detachIfReset, elapsedRealtimeUs); 7436 } 7437 return ret; 7438 } 7439 return true; 7440 } 7441 resetIfNotNull(T[][] t, boolean detachIfReset, long elapsedRealtimeUs)7442 private static <T extends TimeBaseObs> boolean resetIfNotNull(T[][] t, boolean detachIfReset, 7443 long elapsedRealtimeUs) { 7444 if (t != null) { 7445 boolean ret = true; 7446 for (int i = 0; i < t.length; i++) { 7447 ret &= resetIfNotNull(t[i], detachIfReset, elapsedRealtimeUs); 7448 } 7449 return ret; 7450 } 7451 return true; 7452 } 7453 resetIfNotNull(ControllerActivityCounterImpl counter, boolean detachIfReset, long elapsedRealtimeUs)7454 private static boolean resetIfNotNull(ControllerActivityCounterImpl counter, 7455 boolean detachIfReset, long elapsedRealtimeUs) { 7456 if (counter != null) { 7457 counter.reset(detachIfReset, elapsedRealtimeUs); 7458 } 7459 return true; 7460 } 7461 detachIfNotNull(T t)7462 private static <T extends TimeBaseObs> void detachIfNotNull(T t) { 7463 if (t != null) { 7464 t.detach(); 7465 } 7466 } 7467 detachIfNotNull(T[] t)7468 private static <T extends TimeBaseObs> void detachIfNotNull(T[] t) { 7469 if (t != null) { 7470 for (int i = 0; i < t.length; i++) { 7471 detachIfNotNull(t[i]); 7472 } 7473 } 7474 } 7475 detachIfNotNull(T[][] t)7476 private static <T extends TimeBaseObs> void detachIfNotNull(T[][] t) { 7477 if (t != null) { 7478 for (int i = 0; i < t.length; i++) { 7479 detachIfNotNull(t[i]); 7480 } 7481 } 7482 } 7483 detachIfNotNull(ControllerActivityCounterImpl counter)7484 private static void detachIfNotNull(ControllerActivityCounterImpl counter) { 7485 if (counter != null) { 7486 counter.detach(); 7487 } 7488 } 7489 7490 /** 7491 * Accumulates stats for a specific binder transaction. 7492 */ 7493 @VisibleForTesting 7494 protected static class BinderCallStats { 7495 static final Comparator<BinderCallStats> COMPARATOR = 7496 Comparator.comparing(BinderCallStats::getClassName) 7497 .thenComparing(BinderCallStats::getMethodName); 7498 7499 public Class<? extends Binder> binderClass; 7500 public int transactionCode; 7501 public String methodName; 7502 7503 public long callCount; 7504 public long recordedCallCount; 7505 public long recordedCpuTimeMicros; 7506 7507 7508 @Override hashCode()7509 public int hashCode() { 7510 return binderClass.hashCode() * 31 + transactionCode; 7511 } 7512 7513 @Override equals(Object obj)7514 public boolean equals(Object obj) { 7515 if (!(obj instanceof BinderCallStats)) { 7516 return false; 7517 } 7518 BinderCallStats bcsk = (BinderCallStats) obj; 7519 return binderClass.equals(bcsk.binderClass) && transactionCode == bcsk.transactionCode; 7520 } 7521 getClassName()7522 public String getClassName() { 7523 return binderClass.getName(); 7524 } 7525 getMethodName()7526 public String getMethodName() { 7527 return methodName; 7528 } 7529 7530 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) ensureMethodName(BinderTransactionNameResolver resolver)7531 public void ensureMethodName(BinderTransactionNameResolver resolver) { 7532 if (methodName == null) { 7533 methodName = resolver.getMethodName(binderClass, transactionCode); 7534 } 7535 } 7536 7537 @Override toString()7538 public String toString() { 7539 return "BinderCallStats{" 7540 + binderClass 7541 + " transaction=" + transactionCode 7542 + " callCount=" + callCount 7543 + " recordedCallCount=" + recordedCallCount 7544 + " recorderCpuTimeMicros=" + recordedCpuTimeMicros 7545 + "}"; 7546 } 7547 } 7548 7549 /** 7550 * The statistics associated with a particular uid. 7551 */ 7552 public static class Uid extends BatteryStats.Uid { 7553 /** 7554 * BatteryStatsImpl that we are associated with. 7555 */ 7556 protected BatteryStatsImpl mBsi; 7557 7558 final int mUid; 7559 7560 /** TimeBase for when uid is in background and device is on battery. */ 7561 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) 7562 public final TimeBase mOnBatteryBackgroundTimeBase; 7563 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) 7564 public final TimeBase mOnBatteryScreenOffBackgroundTimeBase; 7565 7566 boolean mWifiRunning; 7567 StopwatchTimer mWifiRunningTimer; 7568 7569 boolean mFullWifiLockOut; 7570 StopwatchTimer mFullWifiLockTimer; 7571 7572 boolean mWifiScanStarted; 7573 DualTimer mWifiScanTimer; 7574 7575 static final int NO_BATCHED_SCAN_STARTED = -1; 7576 int mWifiBatchedScanBinStarted = NO_BATCHED_SCAN_STARTED; 7577 StopwatchTimer[] mWifiBatchedScanTimer; 7578 7579 int mWifiMulticastWakelockCount; 7580 StopwatchTimer mWifiMulticastTimer; 7581 7582 StopwatchTimer mAudioTurnedOnTimer; 7583 StopwatchTimer mVideoTurnedOnTimer; 7584 StopwatchTimer mFlashlightTurnedOnTimer; 7585 StopwatchTimer mCameraTurnedOnTimer; 7586 StopwatchTimer mForegroundActivityTimer; 7587 StopwatchTimer mForegroundServiceTimer; 7588 /** Total time spent by the uid holding any partial wakelocks. */ 7589 DualTimer mAggregatedPartialWakelockTimer; 7590 DualTimer mBluetoothScanTimer; 7591 DualTimer mBluetoothUnoptimizedScanTimer; 7592 Counter mBluetoothScanResultCounter; 7593 Counter mBluetoothScanResultBgCounter; 7594 7595 int mProcessState = ActivityManager.PROCESS_STATE_NONEXISTENT; 7596 StopwatchTimer[] mProcessStateTimer; 7597 7598 boolean mInForegroundService = false; 7599 7600 BatchTimer mVibratorOnTimer; 7601 7602 Counter[] mUserActivityCounters; 7603 7604 LongSamplingCounter[] mNetworkByteActivityCounters; 7605 LongSamplingCounter[] mNetworkPacketActivityCounters; 7606 LongSamplingCounter mMobileRadioActiveTime; 7607 LongSamplingCounter mMobileRadioActiveCount; 7608 7609 /** 7610 * How many times this UID woke up the Application Processor due to a Mobile radio packet. 7611 */ 7612 private LongSamplingCounter mMobileRadioApWakeupCount; 7613 7614 /** 7615 * How many times this UID woke up the Application Processor due to a Wifi packet. 7616 */ 7617 private LongSamplingCounter mWifiRadioApWakeupCount; 7618 7619 /** 7620 * The amount of time this uid has kept the WiFi controller in idle, tx, and rx mode. 7621 * Can be null if the UID has had no such activity. 7622 */ 7623 private ControllerActivityCounterImpl mWifiControllerActivity; 7624 7625 /** 7626 * The amount of time this uid has kept the Bluetooth controller in idle, tx, and rx mode. 7627 * Can be null if the UID has had no such activity. 7628 */ 7629 private ControllerActivityCounterImpl mBluetoothControllerActivity; 7630 7631 /** 7632 * The amount of time this uid has kept the Modem controller in idle, tx, and rx mode. 7633 * Can be null if the UID has had no such activity. 7634 */ 7635 private ControllerActivityCounterImpl mModemControllerActivity; 7636 7637 /** 7638 * The CPU times we had at the last history details update. 7639 */ 7640 long mLastStepUserTimeMs; 7641 long mLastStepSystemTimeMs; 7642 long mCurStepUserTimeMs; 7643 long mCurStepSystemTimeMs; 7644 7645 LongSamplingCounter mUserCpuTime; 7646 LongSamplingCounter mSystemCpuTime; 7647 LongSamplingCounter[][] mCpuClusterSpeedTimesUs; 7648 LongSamplingCounter mCpuActiveTimeMs; 7649 7650 LongSamplingCounterArray mCpuFreqTimeMs; 7651 LongSamplingCounterArray mScreenOffCpuFreqTimeMs; 7652 LongSamplingCounterArray mCpuClusterTimesMs; 7653 7654 LongSamplingCounterArray[] mProcStateTimeMs; 7655 LongSamplingCounterArray[] mProcStateScreenOffTimeMs; 7656 7657 IntArray mChildUids; 7658 7659 /** 7660 * The statistics we have collected for this uid's wake locks. 7661 */ 7662 final OverflowArrayMap<Wakelock> mWakelockStats; 7663 7664 /** 7665 * The statistics we have collected for this uid's syncs. 7666 */ 7667 final OverflowArrayMap<DualTimer> mSyncStats; 7668 7669 /** 7670 * The statistics we have collected for this uid's jobs. 7671 */ 7672 final OverflowArrayMap<DualTimer> mJobStats; 7673 7674 /** 7675 * Count of the jobs that have completed and the reasons why they completed. 7676 */ 7677 final ArrayMap<String, SparseIntArray> mJobCompletions = new ArrayMap<>(); 7678 7679 /** 7680 * Count of app launch events that had associated deferred job counts or info about 7681 * last time a job was run. 7682 */ 7683 Counter mJobsDeferredEventCount; 7684 7685 /** 7686 * Count of deferred jobs that were pending when the app was launched or brought to 7687 * the foreground through a user interaction. 7688 */ 7689 Counter mJobsDeferredCount; 7690 7691 /** 7692 * Sum of time since the last time a job was run for this app before it was launched. 7693 */ 7694 LongSamplingCounter mJobsFreshnessTimeMs; 7695 7696 /** 7697 * Array of counts of instances where the time since the last job was run for the app 7698 * fell within one of the thresholds in {@link #JOB_FRESHNESS_BUCKETS}. 7699 */ 7700 final Counter[] mJobsFreshnessBuckets; 7701 7702 /** 7703 * The statistics we have collected for this uid's sensor activations. 7704 */ 7705 final SparseArray<Sensor> mSensorStats = new SparseArray<>(); 7706 7707 /** 7708 * The statistics we have collected for this uid's processes. 7709 */ 7710 final ArrayMap<String, Proc> mProcessStats = new ArrayMap<>(); 7711 7712 /** 7713 * The statistics we have collected for this uid's processes. 7714 */ 7715 final ArrayMap<String, Pkg> mPackageStats = new ArrayMap<>(); 7716 7717 /** 7718 * The transient wake stats we have collected for this uid's pids. 7719 */ 7720 final SparseArray<Pid> mPids = new SparseArray<>(); 7721 7722 /** 7723 * Grand total of system server binder calls made by this uid. 7724 */ 7725 private long mBinderCallCount; 7726 7727 /** 7728 * Detailed information about system server binder calls made by this uid. 7729 */ 7730 private final ArraySet<BinderCallStats> mBinderCallStats = new ArraySet<>(); 7731 7732 /** 7733 * Measured charge consumption by this uid while on battery. 7734 * Its '<b>custom</b> power buckets' correspond to the 7735 * {@link android.hardware.power.stats.EnergyConsumer.ordinal}s of (custom) energy consumer 7736 * type {@link android.hardware.power.stats.EnergyConsumerType#OTHER}). 7737 * 7738 * Will be null if energy consumer data is completely unavailable (in which case 7739 * {@link #mGlobalMeasuredEnergyStats} will also be null) or if the power usage by this uid 7740 * is 0 for every bucket. 7741 */ 7742 private MeasuredEnergyStats mUidMeasuredEnergyStats; 7743 7744 /** 7745 * Estimated total time spent by the system server handling requests from this uid. 7746 */ 7747 private long mSystemServiceTimeUs; 7748 7749 /** 7750 * Estimated proportion of system server binder call CPU cost for this uid. 7751 */ 7752 private double mProportionalSystemServiceUsage; 7753 Uid(BatteryStatsImpl bsi, int uid)7754 public Uid(BatteryStatsImpl bsi, int uid) { 7755 this(bsi, uid, bsi.mClocks.elapsedRealtime(), bsi.mClocks.uptimeMillis()); 7756 } 7757 Uid(BatteryStatsImpl bsi, int uid, long elapsedRealtimeMs, long uptimeMs)7758 public Uid(BatteryStatsImpl bsi, int uid, long elapsedRealtimeMs, long uptimeMs) { 7759 mBsi = bsi; 7760 mUid = uid; 7761 7762 /* Observer list of TimeBase object in Uid is short */ 7763 mOnBatteryBackgroundTimeBase = new TimeBase(false); 7764 mOnBatteryBackgroundTimeBase.init(uptimeMs * 1000, elapsedRealtimeMs * 1000); 7765 /* Observer list of TimeBase object in Uid is short */ 7766 mOnBatteryScreenOffBackgroundTimeBase = new TimeBase(false); 7767 mOnBatteryScreenOffBackgroundTimeBase.init(uptimeMs * 1000, elapsedRealtimeMs * 1000); 7768 7769 mUserCpuTime = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); 7770 mSystemCpuTime = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); 7771 mCpuActiveTimeMs = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); 7772 mCpuClusterTimesMs = new LongSamplingCounterArray(mBsi.mOnBatteryTimeBase); 7773 7774 mWakelockStats = mBsi.new OverflowArrayMap<Wakelock>(uid) { 7775 @Override public Wakelock instantiateObject() { 7776 return new Wakelock(mBsi, Uid.this); 7777 } 7778 }; 7779 mSyncStats = mBsi.new OverflowArrayMap<DualTimer>(uid) { 7780 @Override public DualTimer instantiateObject() { 7781 return new DualTimer(mBsi.mClocks, Uid.this, SYNC, null, 7782 mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase); 7783 } 7784 }; 7785 mJobStats = mBsi.new OverflowArrayMap<DualTimer>(uid) { 7786 @Override public DualTimer instantiateObject() { 7787 return new DualTimer(mBsi.mClocks, Uid.this, JOB, null, 7788 mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase); 7789 } 7790 }; 7791 7792 mWifiRunningTimer = new StopwatchTimer(mBsi.mClocks, this, WIFI_RUNNING, 7793 mBsi.mWifiRunningTimers, mBsi.mOnBatteryTimeBase); 7794 mFullWifiLockTimer = new StopwatchTimer(mBsi.mClocks, this, FULL_WIFI_LOCK, 7795 mBsi.mFullWifiLockTimers, mBsi.mOnBatteryTimeBase); 7796 mWifiScanTimer = new DualTimer(mBsi.mClocks, this, WIFI_SCAN, 7797 mBsi.mWifiScanTimers, mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase); 7798 mWifiBatchedScanTimer = new StopwatchTimer[NUM_WIFI_BATCHED_SCAN_BINS]; 7799 mWifiMulticastTimer = new StopwatchTimer(mBsi.mClocks, this, WIFI_MULTICAST_ENABLED, 7800 mBsi.mWifiMulticastTimers, mBsi.mOnBatteryTimeBase); 7801 mProcessStateTimer = new StopwatchTimer[NUM_PROCESS_STATE]; 7802 mJobsDeferredEventCount = new Counter(mBsi.mOnBatteryTimeBase); 7803 mJobsDeferredCount = new Counter(mBsi.mOnBatteryTimeBase); 7804 mJobsFreshnessTimeMs = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); 7805 mJobsFreshnessBuckets = new Counter[JOB_FRESHNESS_BUCKETS.length]; 7806 } 7807 7808 @VisibleForTesting setProcessStateForTest(int procState)7809 public void setProcessStateForTest(int procState) { 7810 mProcessState = procState; 7811 } 7812 7813 @Override getCpuFreqTimes(int which)7814 public long[] getCpuFreqTimes(int which) { 7815 return nullIfAllZeros(mCpuFreqTimeMs, which); 7816 } 7817 7818 @Override getScreenOffCpuFreqTimes(int which)7819 public long[] getScreenOffCpuFreqTimes(int which) { 7820 return nullIfAllZeros(mScreenOffCpuFreqTimeMs, which); 7821 } 7822 7823 @Override getCpuActiveTime()7824 public long getCpuActiveTime() { 7825 return mCpuActiveTimeMs.getCountLocked(STATS_SINCE_CHARGED); 7826 } 7827 7828 @Override getCpuClusterTimes()7829 public long[] getCpuClusterTimes() { 7830 return nullIfAllZeros(mCpuClusterTimesMs, STATS_SINCE_CHARGED); 7831 } 7832 7833 @Override getCpuFreqTimes(int which, int procState)7834 public long[] getCpuFreqTimes(int which, int procState) { 7835 if (which < 0 || which >= NUM_PROCESS_STATE) { 7836 return null; 7837 } 7838 if (mProcStateTimeMs == null) { 7839 return null; 7840 } 7841 if (!mBsi.mPerProcStateCpuTimesAvailable) { 7842 mProcStateTimeMs = null; 7843 return null; 7844 } 7845 return nullIfAllZeros(mProcStateTimeMs[procState], which); 7846 } 7847 7848 @Override getScreenOffCpuFreqTimes(int which, int procState)7849 public long[] getScreenOffCpuFreqTimes(int which, int procState) { 7850 if (which < 0 || which >= NUM_PROCESS_STATE) { 7851 return null; 7852 } 7853 if (mProcStateScreenOffTimeMs == null) { 7854 return null; 7855 } 7856 if (!mBsi.mPerProcStateCpuTimesAvailable) { 7857 mProcStateScreenOffTimeMs = null; 7858 return null; 7859 } 7860 return nullIfAllZeros(mProcStateScreenOffTimeMs[procState], which); 7861 } 7862 getBinderCallCount()7863 public long getBinderCallCount() { 7864 return mBinderCallCount; 7865 } 7866 7867 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE) getBinderCallStats()7868 public ArraySet<BinderCallStats> getBinderCallStats() { 7869 return mBinderCallStats; 7870 } 7871 7872 @Override getProportionalSystemServiceUsage()7873 public double getProportionalSystemServiceUsage() { 7874 return mProportionalSystemServiceUsage; 7875 } 7876 addIsolatedUid(int isolatedUid)7877 public void addIsolatedUid(int isolatedUid) { 7878 if (mChildUids == null) { 7879 mChildUids = new IntArray(); 7880 } else if (mChildUids.indexOf(isolatedUid) >= 0) { 7881 return; 7882 } 7883 mChildUids.add(isolatedUid); 7884 } 7885 removeIsolatedUid(int isolatedUid)7886 public void removeIsolatedUid(int isolatedUid) { 7887 final int idx = mChildUids == null ? -1 : mChildUids.indexOf(isolatedUid); 7888 if (idx < 0) { 7889 return; 7890 } 7891 mChildUids.remove(idx); 7892 } 7893 nullIfAllZeros(LongSamplingCounterArray cpuTimesMs, int which)7894 private long[] nullIfAllZeros(LongSamplingCounterArray cpuTimesMs, int which) { 7895 if (cpuTimesMs == null) { 7896 return null; 7897 } 7898 final long[] counts = cpuTimesMs.getCountsLocked(which); 7899 if (counts == null) { 7900 return null; 7901 } 7902 // Return counts only if at least one of the elements is non-zero. 7903 for (int i = counts.length - 1; i >= 0; --i) { 7904 if (counts[i] != 0) { 7905 return counts; 7906 } 7907 } 7908 return null; 7909 } 7910 addProcStateTimesMs(int procState, long[] cpuTimesMs, boolean onBattery)7911 private void addProcStateTimesMs(int procState, long[] cpuTimesMs, boolean onBattery) { 7912 if (mProcStateTimeMs == null) { 7913 mProcStateTimeMs = new LongSamplingCounterArray[NUM_PROCESS_STATE]; 7914 } 7915 if (mProcStateTimeMs[procState] == null 7916 || mProcStateTimeMs[procState].getSize() != cpuTimesMs.length) { 7917 detachIfNotNull(mProcStateTimeMs[procState]); 7918 mProcStateTimeMs[procState] = new LongSamplingCounterArray( 7919 mBsi.mOnBatteryTimeBase); 7920 } 7921 mProcStateTimeMs[procState].addCountLocked(cpuTimesMs, onBattery); 7922 } 7923 addProcStateScreenOffTimesMs(int procState, long[] cpuTimesMs, boolean onBatteryScreenOff)7924 private void addProcStateScreenOffTimesMs(int procState, long[] cpuTimesMs, 7925 boolean onBatteryScreenOff) { 7926 if (mProcStateScreenOffTimeMs == null) { 7927 mProcStateScreenOffTimeMs = new LongSamplingCounterArray[NUM_PROCESS_STATE]; 7928 } 7929 if (mProcStateScreenOffTimeMs[procState] == null 7930 || mProcStateScreenOffTimeMs[procState].getSize() != cpuTimesMs.length) { 7931 detachIfNotNull(mProcStateScreenOffTimeMs[procState]); 7932 mProcStateScreenOffTimeMs[procState] = new LongSamplingCounterArray( 7933 mBsi.mOnBatteryScreenOffTimeBase); 7934 } 7935 mProcStateScreenOffTimeMs[procState].addCountLocked(cpuTimesMs, onBatteryScreenOff); 7936 } 7937 7938 @Override getAggregatedPartialWakelockTimer()7939 public Timer getAggregatedPartialWakelockTimer() { 7940 return mAggregatedPartialWakelockTimer; 7941 } 7942 7943 @Override 7944 @UnsupportedAppUsage getWakelockStats()7945 public ArrayMap<String, ? extends BatteryStats.Uid.Wakelock> getWakelockStats() { 7946 return mWakelockStats.getMap(); 7947 } 7948 7949 @Override getMulticastWakelockStats()7950 public Timer getMulticastWakelockStats() { 7951 return mWifiMulticastTimer; 7952 } 7953 7954 @Override getSyncStats()7955 public ArrayMap<String, ? extends BatteryStats.Timer> getSyncStats() { 7956 return mSyncStats.getMap(); 7957 } 7958 7959 @Override getJobStats()7960 public ArrayMap<String, ? extends BatteryStats.Timer> getJobStats() { 7961 return mJobStats.getMap(); 7962 } 7963 7964 @Override getJobCompletionStats()7965 public ArrayMap<String, SparseIntArray> getJobCompletionStats() { 7966 return mJobCompletions; 7967 } 7968 7969 @Override 7970 @UnsupportedAppUsage getSensorStats()7971 public SparseArray<? extends BatteryStats.Uid.Sensor> getSensorStats() { 7972 return mSensorStats; 7973 } 7974 7975 @Override 7976 @UnsupportedAppUsage getProcessStats()7977 public ArrayMap<String, ? extends BatteryStats.Uid.Proc> getProcessStats() { 7978 return mProcessStats; 7979 } 7980 7981 @Override getPackageStats()7982 public ArrayMap<String, ? extends BatteryStats.Uid.Pkg> getPackageStats() { 7983 return mPackageStats; 7984 } 7985 7986 @Override 7987 @UnsupportedAppUsage getUid()7988 public int getUid() { 7989 return mUid; 7990 } 7991 7992 @Override noteWifiRunningLocked(long elapsedRealtimeMs)7993 public void noteWifiRunningLocked(long elapsedRealtimeMs) { 7994 if (!mWifiRunning) { 7995 mWifiRunning = true; 7996 if (mWifiRunningTimer == null) { 7997 mWifiRunningTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, WIFI_RUNNING, 7998 mBsi.mWifiRunningTimers, mBsi.mOnBatteryTimeBase); 7999 } 8000 mWifiRunningTimer.startRunningLocked(elapsedRealtimeMs); 8001 } 8002 } 8003 8004 @Override noteWifiStoppedLocked(long elapsedRealtimeMs)8005 public void noteWifiStoppedLocked(long elapsedRealtimeMs) { 8006 if (mWifiRunning) { 8007 mWifiRunning = false; 8008 mWifiRunningTimer.stopRunningLocked(elapsedRealtimeMs); 8009 } 8010 } 8011 8012 @Override noteFullWifiLockAcquiredLocked(long elapsedRealtimeMs)8013 public void noteFullWifiLockAcquiredLocked(long elapsedRealtimeMs) { 8014 if (!mFullWifiLockOut) { 8015 mFullWifiLockOut = true; 8016 if (mFullWifiLockTimer == null) { 8017 mFullWifiLockTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, FULL_WIFI_LOCK, 8018 mBsi.mFullWifiLockTimers, mBsi.mOnBatteryTimeBase); 8019 } 8020 mFullWifiLockTimer.startRunningLocked(elapsedRealtimeMs); 8021 } 8022 } 8023 8024 @Override noteFullWifiLockReleasedLocked(long elapsedRealtimeMs)8025 public void noteFullWifiLockReleasedLocked(long elapsedRealtimeMs) { 8026 if (mFullWifiLockOut) { 8027 mFullWifiLockOut = false; 8028 mFullWifiLockTimer.stopRunningLocked(elapsedRealtimeMs); 8029 } 8030 } 8031 8032 @Override noteWifiScanStartedLocked(long elapsedRealtimeMs)8033 public void noteWifiScanStartedLocked(long elapsedRealtimeMs) { 8034 if (!mWifiScanStarted) { 8035 mWifiScanStarted = true; 8036 if (mWifiScanTimer == null) { 8037 mWifiScanTimer = new DualTimer(mBsi.mClocks, Uid.this, WIFI_SCAN, 8038 mBsi.mWifiScanTimers, mBsi.mOnBatteryTimeBase, 8039 mOnBatteryBackgroundTimeBase); 8040 } 8041 mWifiScanTimer.startRunningLocked(elapsedRealtimeMs); 8042 } 8043 } 8044 8045 @Override noteWifiScanStoppedLocked(long elapsedRealtimeMs)8046 public void noteWifiScanStoppedLocked(long elapsedRealtimeMs) { 8047 if (mWifiScanStarted) { 8048 mWifiScanStarted = false; 8049 mWifiScanTimer.stopRunningLocked(elapsedRealtimeMs); 8050 } 8051 } 8052 8053 @Override noteWifiBatchedScanStartedLocked(int csph, long elapsedRealtimeMs)8054 public void noteWifiBatchedScanStartedLocked(int csph, long elapsedRealtimeMs) { 8055 int bin = 0; 8056 while (csph > 8 && bin < NUM_WIFI_BATCHED_SCAN_BINS-1) { 8057 csph = csph >> 3; 8058 bin++; 8059 } 8060 8061 if (mWifiBatchedScanBinStarted == bin) return; 8062 8063 if (mWifiBatchedScanBinStarted != NO_BATCHED_SCAN_STARTED) { 8064 mWifiBatchedScanTimer[mWifiBatchedScanBinStarted]. 8065 stopRunningLocked(elapsedRealtimeMs); 8066 } 8067 mWifiBatchedScanBinStarted = bin; 8068 if (mWifiBatchedScanTimer[bin] == null) { 8069 makeWifiBatchedScanBin(bin, null); 8070 } 8071 mWifiBatchedScanTimer[bin].startRunningLocked(elapsedRealtimeMs); 8072 } 8073 8074 @Override noteWifiBatchedScanStoppedLocked(long elapsedRealtimeMs)8075 public void noteWifiBatchedScanStoppedLocked(long elapsedRealtimeMs) { 8076 if (mWifiBatchedScanBinStarted != NO_BATCHED_SCAN_STARTED) { 8077 mWifiBatchedScanTimer[mWifiBatchedScanBinStarted]. 8078 stopRunningLocked(elapsedRealtimeMs); 8079 mWifiBatchedScanBinStarted = NO_BATCHED_SCAN_STARTED; 8080 } 8081 } 8082 8083 @Override noteWifiMulticastEnabledLocked(long elapsedRealtimeMs)8084 public void noteWifiMulticastEnabledLocked(long elapsedRealtimeMs) { 8085 if (mWifiMulticastWakelockCount == 0) { 8086 if (mWifiMulticastTimer == null) { 8087 mWifiMulticastTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, 8088 WIFI_MULTICAST_ENABLED, mBsi.mWifiMulticastTimers, mBsi.mOnBatteryTimeBase); 8089 } 8090 mWifiMulticastTimer.startRunningLocked(elapsedRealtimeMs); 8091 } 8092 mWifiMulticastWakelockCount++; 8093 } 8094 8095 @Override noteWifiMulticastDisabledLocked(long elapsedRealtimeMs)8096 public void noteWifiMulticastDisabledLocked(long elapsedRealtimeMs) { 8097 if (mWifiMulticastWakelockCount == 0) { 8098 return; 8099 } 8100 8101 mWifiMulticastWakelockCount--; 8102 if (mWifiMulticastWakelockCount == 0) { 8103 mWifiMulticastTimer.stopRunningLocked(elapsedRealtimeMs); 8104 } 8105 } 8106 8107 @Override getWifiControllerActivity()8108 public ControllerActivityCounter getWifiControllerActivity() { 8109 return mWifiControllerActivity; 8110 } 8111 8112 @Override getBluetoothControllerActivity()8113 public ControllerActivityCounter getBluetoothControllerActivity() { 8114 return mBluetoothControllerActivity; 8115 } 8116 8117 @Override getModemControllerActivity()8118 public ControllerActivityCounter getModemControllerActivity() { 8119 return mModemControllerActivity; 8120 } 8121 getOrCreateWifiControllerActivityLocked()8122 public ControllerActivityCounterImpl getOrCreateWifiControllerActivityLocked() { 8123 if (mWifiControllerActivity == null) { 8124 mWifiControllerActivity = new ControllerActivityCounterImpl(mBsi.mOnBatteryTimeBase, 8125 NUM_BT_TX_LEVELS); 8126 } 8127 return mWifiControllerActivity; 8128 } 8129 getOrCreateBluetoothControllerActivityLocked()8130 public ControllerActivityCounterImpl getOrCreateBluetoothControllerActivityLocked() { 8131 if (mBluetoothControllerActivity == null) { 8132 mBluetoothControllerActivity = new ControllerActivityCounterImpl(mBsi.mOnBatteryTimeBase, 8133 NUM_BT_TX_LEVELS); 8134 } 8135 return mBluetoothControllerActivity; 8136 } 8137 getOrCreateModemControllerActivityLocked()8138 public ControllerActivityCounterImpl getOrCreateModemControllerActivityLocked() { 8139 if (mModemControllerActivity == null) { 8140 mModemControllerActivity = new ControllerActivityCounterImpl(mBsi.mOnBatteryTimeBase, 8141 ModemActivityInfo.getNumTxPowerLevels()); 8142 } 8143 return mModemControllerActivity; 8144 } 8145 getOrCreateMeasuredEnergyStatsLocked()8146 private MeasuredEnergyStats getOrCreateMeasuredEnergyStatsLocked() { 8147 if (mUidMeasuredEnergyStats == null) { 8148 mUidMeasuredEnergyStats = 8149 MeasuredEnergyStats.createFromTemplate(mBsi.mGlobalMeasuredEnergyStats); 8150 } 8151 return mUidMeasuredEnergyStats; 8152 } 8153 8154 /** Adds the given charge to the given standard power bucket for this uid. */ addChargeToStandardBucketLocked(long chargeDeltaUC, @StandardPowerBucket int powerBucket)8155 private void addChargeToStandardBucketLocked(long chargeDeltaUC, 8156 @StandardPowerBucket int powerBucket) { 8157 getOrCreateMeasuredEnergyStatsLocked().updateStandardBucket(powerBucket, chargeDeltaUC); 8158 } 8159 8160 /** Adds the given charge to the given custom power bucket for this uid. */ addChargeToCustomBucketLocked(long chargeDeltaUC, int powerBucket)8161 private void addChargeToCustomBucketLocked(long chargeDeltaUC, int powerBucket) { 8162 getOrCreateMeasuredEnergyStatsLocked().updateCustomBucket(powerBucket, chargeDeltaUC); 8163 } 8164 8165 /** 8166 * Returns the battery consumption (in microcoulomb) of this uid for a standard power bucket 8167 * of interest. 8168 * @param bucket standard power bucket of interest 8169 * @return consumption (in microcolombs) used by this uid for this power bucket 8170 */ getMeasuredBatteryConsumptionUC(@tandardPowerBucket int bucket)8171 public long getMeasuredBatteryConsumptionUC(@StandardPowerBucket int bucket) { 8172 if (mBsi.mGlobalMeasuredEnergyStats == null 8173 || !mBsi.mGlobalMeasuredEnergyStats.isStandardBucketSupported(bucket)) { 8174 return POWER_DATA_UNAVAILABLE; 8175 } 8176 if (mUidMeasuredEnergyStats == null) { 8177 return 0L; // It is supported, but was never filled, so it must be 0 8178 } 8179 return mUidMeasuredEnergyStats.getAccumulatedStandardBucketCharge(bucket); 8180 } 8181 8182 @Override getCustomConsumerMeasuredBatteryConsumptionUC()8183 public long[] getCustomConsumerMeasuredBatteryConsumptionUC() { 8184 if (mBsi.mGlobalMeasuredEnergyStats == null) { 8185 return null; 8186 } 8187 if (mUidMeasuredEnergyStats == null) { 8188 // Custom buckets may exist. But all values for this uid are 0 so we report all 0s. 8189 return new long[mBsi.mGlobalMeasuredEnergyStats.getNumberCustomPowerBuckets()]; 8190 } 8191 return mUidMeasuredEnergyStats.getAccumulatedCustomBucketCharges(); 8192 } 8193 8194 @Override getBluetoothMeasuredBatteryConsumptionUC()8195 public long getBluetoothMeasuredBatteryConsumptionUC() { 8196 return getMeasuredBatteryConsumptionUC(MeasuredEnergyStats.POWER_BUCKET_BLUETOOTH); 8197 } 8198 8199 @Override getCpuMeasuredBatteryConsumptionUC()8200 public long getCpuMeasuredBatteryConsumptionUC() { 8201 return getMeasuredBatteryConsumptionUC(MeasuredEnergyStats.POWER_BUCKET_CPU); 8202 } 8203 8204 @Override getGnssMeasuredBatteryConsumptionUC()8205 public long getGnssMeasuredBatteryConsumptionUC() { 8206 return getMeasuredBatteryConsumptionUC(MeasuredEnergyStats.POWER_BUCKET_GNSS); 8207 } 8208 8209 @Override getMobileRadioMeasuredBatteryConsumptionUC()8210 public long getMobileRadioMeasuredBatteryConsumptionUC() { 8211 return getMeasuredBatteryConsumptionUC(MeasuredEnergyStats.POWER_BUCKET_MOBILE_RADIO); 8212 } 8213 8214 @Override getScreenOnMeasuredBatteryConsumptionUC()8215 public long getScreenOnMeasuredBatteryConsumptionUC() { 8216 return getMeasuredBatteryConsumptionUC(MeasuredEnergyStats.POWER_BUCKET_SCREEN_ON); 8217 } 8218 8219 @Override getWifiMeasuredBatteryConsumptionUC()8220 public long getWifiMeasuredBatteryConsumptionUC() { 8221 return getMeasuredBatteryConsumptionUC(MeasuredEnergyStats.POWER_BUCKET_WIFI); 8222 } 8223 8224 /** 8225 * Gets the minimum of the uid's foreground activity time and its PROCESS_STATE_TOP time 8226 * since last marked. Also sets the mark time for both these timers. 8227 * 8228 * @see BatteryStatsHelper#getProcessForegroundTimeMs 8229 * 8230 * @param doCalc if true, then calculate the minimum; else don't bother and return 0. Either 8231 * way, the mark is set. 8232 */ markProcessForegroundTimeUs(long elapsedRealtimeMs, boolean doCalc)8233 private long markProcessForegroundTimeUs(long elapsedRealtimeMs, 8234 boolean doCalc) { 8235 long fgTimeUs = 0; 8236 final StopwatchTimer fgTimer = mForegroundActivityTimer; 8237 if (fgTimer != null) { 8238 if (doCalc) fgTimeUs = fgTimer.getTimeSinceMarkLocked(elapsedRealtimeMs * 1000); 8239 fgTimer.setMark(elapsedRealtimeMs); 8240 } 8241 8242 long topTimeUs = 0; 8243 final StopwatchTimer topTimer = mProcessStateTimer[PROCESS_STATE_TOP]; 8244 if (topTimer != null) { 8245 if (doCalc) topTimeUs = topTimer.getTimeSinceMarkLocked(elapsedRealtimeMs * 1000); 8246 topTimer.setMark(elapsedRealtimeMs); 8247 } 8248 8249 // Return the min of the two 8250 return (topTimeUs < fgTimeUs) ? topTimeUs : fgTimeUs; 8251 } 8252 8253 8254 /** 8255 * Gets the uid's time spent using the GNSS since last marked. Also sets the mark time for 8256 * the GNSS timer. 8257 */ markGnssTimeUs(long elapsedRealtimeMs)8258 private long markGnssTimeUs(long elapsedRealtimeMs) { 8259 final Sensor sensor = mSensorStats.get(Sensor.GPS); 8260 if (sensor == null) { 8261 return 0; 8262 } 8263 8264 final StopwatchTimer timer = sensor.mTimer; 8265 if (timer == null) { 8266 return 0; 8267 } 8268 8269 final long gnssTimeUs = timer.getTimeSinceMarkLocked(elapsedRealtimeMs * 1000); 8270 timer.setMark(elapsedRealtimeMs); 8271 return gnssTimeUs; 8272 } 8273 createAudioTurnedOnTimerLocked()8274 public StopwatchTimer createAudioTurnedOnTimerLocked() { 8275 if (mAudioTurnedOnTimer == null) { 8276 mAudioTurnedOnTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, AUDIO_TURNED_ON, 8277 mBsi.mAudioTurnedOnTimers, mBsi.mOnBatteryTimeBase); 8278 } 8279 return mAudioTurnedOnTimer; 8280 } 8281 noteAudioTurnedOnLocked(long elapsedRealtimeMs)8282 public void noteAudioTurnedOnLocked(long elapsedRealtimeMs) { 8283 createAudioTurnedOnTimerLocked().startRunningLocked(elapsedRealtimeMs); 8284 } 8285 noteAudioTurnedOffLocked(long elapsedRealtimeMs)8286 public void noteAudioTurnedOffLocked(long elapsedRealtimeMs) { 8287 if (mAudioTurnedOnTimer != null) { 8288 mAudioTurnedOnTimer.stopRunningLocked(elapsedRealtimeMs); 8289 } 8290 } 8291 noteResetAudioLocked(long elapsedRealtimeMs)8292 public void noteResetAudioLocked(long elapsedRealtimeMs) { 8293 if (mAudioTurnedOnTimer != null) { 8294 mAudioTurnedOnTimer.stopAllRunningLocked(elapsedRealtimeMs); 8295 } 8296 } 8297 createVideoTurnedOnTimerLocked()8298 public StopwatchTimer createVideoTurnedOnTimerLocked() { 8299 if (mVideoTurnedOnTimer == null) { 8300 mVideoTurnedOnTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, VIDEO_TURNED_ON, 8301 mBsi.mVideoTurnedOnTimers, mBsi.mOnBatteryTimeBase); 8302 } 8303 return mVideoTurnedOnTimer; 8304 } 8305 noteVideoTurnedOnLocked(long elapsedRealtimeMs)8306 public void noteVideoTurnedOnLocked(long elapsedRealtimeMs) { 8307 createVideoTurnedOnTimerLocked().startRunningLocked(elapsedRealtimeMs); 8308 } 8309 noteVideoTurnedOffLocked(long elapsedRealtimeMs)8310 public void noteVideoTurnedOffLocked(long elapsedRealtimeMs) { 8311 if (mVideoTurnedOnTimer != null) { 8312 mVideoTurnedOnTimer.stopRunningLocked(elapsedRealtimeMs); 8313 } 8314 } 8315 noteResetVideoLocked(long elapsedRealtimeMs)8316 public void noteResetVideoLocked(long elapsedRealtimeMs) { 8317 if (mVideoTurnedOnTimer != null) { 8318 mVideoTurnedOnTimer.stopAllRunningLocked(elapsedRealtimeMs); 8319 } 8320 } 8321 createFlashlightTurnedOnTimerLocked()8322 public StopwatchTimer createFlashlightTurnedOnTimerLocked() { 8323 if (mFlashlightTurnedOnTimer == null) { 8324 mFlashlightTurnedOnTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, 8325 FLASHLIGHT_TURNED_ON, mBsi.mFlashlightTurnedOnTimers, mBsi.mOnBatteryTimeBase); 8326 } 8327 return mFlashlightTurnedOnTimer; 8328 } 8329 noteFlashlightTurnedOnLocked(long elapsedRealtimeMs)8330 public void noteFlashlightTurnedOnLocked(long elapsedRealtimeMs) { 8331 createFlashlightTurnedOnTimerLocked().startRunningLocked(elapsedRealtimeMs); 8332 } 8333 noteFlashlightTurnedOffLocked(long elapsedRealtimeMs)8334 public void noteFlashlightTurnedOffLocked(long elapsedRealtimeMs) { 8335 if (mFlashlightTurnedOnTimer != null) { 8336 mFlashlightTurnedOnTimer.stopRunningLocked(elapsedRealtimeMs); 8337 } 8338 } 8339 noteResetFlashlightLocked(long elapsedRealtimeMs)8340 public void noteResetFlashlightLocked(long elapsedRealtimeMs) { 8341 if (mFlashlightTurnedOnTimer != null) { 8342 mFlashlightTurnedOnTimer.stopAllRunningLocked(elapsedRealtimeMs); 8343 } 8344 } 8345 createCameraTurnedOnTimerLocked()8346 public StopwatchTimer createCameraTurnedOnTimerLocked() { 8347 if (mCameraTurnedOnTimer == null) { 8348 mCameraTurnedOnTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, CAMERA_TURNED_ON, 8349 mBsi.mCameraTurnedOnTimers, mBsi.mOnBatteryTimeBase); 8350 } 8351 return mCameraTurnedOnTimer; 8352 } 8353 noteCameraTurnedOnLocked(long elapsedRealtimeMs)8354 public void noteCameraTurnedOnLocked(long elapsedRealtimeMs) { 8355 createCameraTurnedOnTimerLocked().startRunningLocked(elapsedRealtimeMs); 8356 } 8357 noteCameraTurnedOffLocked(long elapsedRealtimeMs)8358 public void noteCameraTurnedOffLocked(long elapsedRealtimeMs) { 8359 if (mCameraTurnedOnTimer != null) { 8360 mCameraTurnedOnTimer.stopRunningLocked(elapsedRealtimeMs); 8361 } 8362 } 8363 noteResetCameraLocked(long elapsedRealtimeMs)8364 public void noteResetCameraLocked(long elapsedRealtimeMs) { 8365 if (mCameraTurnedOnTimer != null) { 8366 mCameraTurnedOnTimer.stopAllRunningLocked(elapsedRealtimeMs); 8367 } 8368 } 8369 createForegroundActivityTimerLocked()8370 public StopwatchTimer createForegroundActivityTimerLocked() { 8371 if (mForegroundActivityTimer == null) { 8372 mForegroundActivityTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, 8373 FOREGROUND_ACTIVITY, null, mBsi.mOnBatteryTimeBase); 8374 } 8375 return mForegroundActivityTimer; 8376 } 8377 createForegroundServiceTimerLocked()8378 public StopwatchTimer createForegroundServiceTimerLocked() { 8379 if (mForegroundServiceTimer == null) { 8380 mForegroundServiceTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, 8381 FOREGROUND_SERVICE, null, mBsi.mOnBatteryTimeBase); 8382 } 8383 return mForegroundServiceTimer; 8384 } 8385 createAggregatedPartialWakelockTimerLocked()8386 public DualTimer createAggregatedPartialWakelockTimerLocked() { 8387 if (mAggregatedPartialWakelockTimer == null) { 8388 mAggregatedPartialWakelockTimer = new DualTimer(mBsi.mClocks, this, 8389 AGGREGATED_WAKE_TYPE_PARTIAL, null, 8390 mBsi.mOnBatteryScreenOffTimeBase, mOnBatteryScreenOffBackgroundTimeBase); 8391 } 8392 return mAggregatedPartialWakelockTimer; 8393 } 8394 createBluetoothScanTimerLocked()8395 public DualTimer createBluetoothScanTimerLocked() { 8396 if (mBluetoothScanTimer == null) { 8397 mBluetoothScanTimer = new DualTimer(mBsi.mClocks, Uid.this, BLUETOOTH_SCAN_ON, 8398 mBsi.mBluetoothScanOnTimers, mBsi.mOnBatteryTimeBase, 8399 mOnBatteryBackgroundTimeBase); 8400 } 8401 return mBluetoothScanTimer; 8402 } 8403 createBluetoothUnoptimizedScanTimerLocked()8404 public DualTimer createBluetoothUnoptimizedScanTimerLocked() { 8405 if (mBluetoothUnoptimizedScanTimer == null) { 8406 mBluetoothUnoptimizedScanTimer = new DualTimer(mBsi.mClocks, Uid.this, 8407 BLUETOOTH_UNOPTIMIZED_SCAN_ON, null, 8408 mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase); 8409 } 8410 return mBluetoothUnoptimizedScanTimer; 8411 } 8412 noteBluetoothScanStartedLocked(long elapsedRealtimeMs, boolean isUnoptimized)8413 public void noteBluetoothScanStartedLocked(long elapsedRealtimeMs, 8414 boolean isUnoptimized) { 8415 createBluetoothScanTimerLocked().startRunningLocked(elapsedRealtimeMs); 8416 if (isUnoptimized) { 8417 createBluetoothUnoptimizedScanTimerLocked().startRunningLocked(elapsedRealtimeMs); 8418 } 8419 } 8420 noteBluetoothScanStoppedLocked(long elapsedRealtimeMs, boolean isUnoptimized)8421 public void noteBluetoothScanStoppedLocked(long elapsedRealtimeMs, boolean isUnoptimized) { 8422 if (mBluetoothScanTimer != null) { 8423 mBluetoothScanTimer.stopRunningLocked(elapsedRealtimeMs); 8424 } 8425 if (isUnoptimized && mBluetoothUnoptimizedScanTimer != null) { 8426 mBluetoothUnoptimizedScanTimer.stopRunningLocked(elapsedRealtimeMs); 8427 } 8428 } 8429 noteResetBluetoothScanLocked(long elapsedRealtimeMs)8430 public void noteResetBluetoothScanLocked(long elapsedRealtimeMs) { 8431 if (mBluetoothScanTimer != null) { 8432 mBluetoothScanTimer.stopAllRunningLocked(elapsedRealtimeMs); 8433 } 8434 if (mBluetoothUnoptimizedScanTimer != null) { 8435 mBluetoothUnoptimizedScanTimer.stopAllRunningLocked(elapsedRealtimeMs); 8436 } 8437 } 8438 createBluetoothScanResultCounterLocked()8439 public Counter createBluetoothScanResultCounterLocked() { 8440 if (mBluetoothScanResultCounter == null) { 8441 mBluetoothScanResultCounter = new Counter(mBsi.mOnBatteryTimeBase); 8442 } 8443 return mBluetoothScanResultCounter; 8444 } 8445 createBluetoothScanResultBgCounterLocked()8446 public Counter createBluetoothScanResultBgCounterLocked() { 8447 if (mBluetoothScanResultBgCounter == null) { 8448 mBluetoothScanResultBgCounter = new Counter(mOnBatteryBackgroundTimeBase); 8449 } 8450 return mBluetoothScanResultBgCounter; 8451 } 8452 noteBluetoothScanResultsLocked(int numNewResults)8453 public void noteBluetoothScanResultsLocked(int numNewResults) { 8454 createBluetoothScanResultCounterLocked().addAtomic(numNewResults); 8455 // Uses background timebase, so the count will only be incremented if uid in background. 8456 createBluetoothScanResultBgCounterLocked().addAtomic(numNewResults); 8457 } 8458 8459 @Override noteActivityResumedLocked(long elapsedRealtimeMs)8460 public void noteActivityResumedLocked(long elapsedRealtimeMs) { 8461 // We always start, since we want multiple foreground PIDs to nest 8462 createForegroundActivityTimerLocked().startRunningLocked(elapsedRealtimeMs); 8463 } 8464 8465 @Override noteActivityPausedLocked(long elapsedRealtimeMs)8466 public void noteActivityPausedLocked(long elapsedRealtimeMs) { 8467 if (mForegroundActivityTimer != null) { 8468 mForegroundActivityTimer.stopRunningLocked(elapsedRealtimeMs); 8469 } 8470 } 8471 noteForegroundServiceResumedLocked(long elapsedRealtimeMs)8472 public void noteForegroundServiceResumedLocked(long elapsedRealtimeMs) { 8473 createForegroundServiceTimerLocked().startRunningLocked(elapsedRealtimeMs); 8474 } 8475 noteForegroundServicePausedLocked(long elapsedRealtimeMs)8476 public void noteForegroundServicePausedLocked(long elapsedRealtimeMs) { 8477 if (mForegroundServiceTimer != null) { 8478 mForegroundServiceTimer.stopRunningLocked(elapsedRealtimeMs); 8479 } 8480 } 8481 createVibratorOnTimerLocked()8482 public BatchTimer createVibratorOnTimerLocked() { 8483 if (mVibratorOnTimer == null) { 8484 mVibratorOnTimer = new BatchTimer(mBsi.mClocks, Uid.this, VIBRATOR_ON, 8485 mBsi.mOnBatteryTimeBase); 8486 } 8487 return mVibratorOnTimer; 8488 } 8489 noteVibratorOnLocked(long durationMillis, long elapsedRealtimeMs)8490 public void noteVibratorOnLocked(long durationMillis, long elapsedRealtimeMs) { 8491 createVibratorOnTimerLocked().addDuration(mBsi, durationMillis, elapsedRealtimeMs); 8492 } 8493 noteVibratorOffLocked(long elapsedRealtimeMs)8494 public void noteVibratorOffLocked(long elapsedRealtimeMs) { 8495 if (mVibratorOnTimer != null) { 8496 mVibratorOnTimer.abortLastDuration(mBsi, elapsedRealtimeMs); 8497 } 8498 } 8499 8500 @Override 8501 @UnsupportedAppUsage getWifiRunningTime(long elapsedRealtimeUs, int which)8502 public long getWifiRunningTime(long elapsedRealtimeUs, int which) { 8503 if (mWifiRunningTimer == null) { 8504 return 0; 8505 } 8506 return mWifiRunningTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 8507 } 8508 8509 @Override getFullWifiLockTime(long elapsedRealtimeUs, int which)8510 public long getFullWifiLockTime(long elapsedRealtimeUs, int which) { 8511 if (mFullWifiLockTimer == null) { 8512 return 0; 8513 } 8514 return mFullWifiLockTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 8515 } 8516 8517 @Override 8518 @UnsupportedAppUsage getWifiScanTime(long elapsedRealtimeUs, int which)8519 public long getWifiScanTime(long elapsedRealtimeUs, int which) { 8520 if (mWifiScanTimer == null) { 8521 return 0; 8522 } 8523 return mWifiScanTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 8524 } 8525 8526 @Override getWifiScanCount(int which)8527 public int getWifiScanCount(int which) { 8528 if (mWifiScanTimer == null) { 8529 return 0; 8530 } 8531 return mWifiScanTimer.getCountLocked(which); 8532 } 8533 8534 @Override getWifiScanTimer()8535 public Timer getWifiScanTimer() { 8536 return mWifiScanTimer; 8537 } 8538 8539 @Override getWifiScanBackgroundCount(int which)8540 public int getWifiScanBackgroundCount(int which) { 8541 if (mWifiScanTimer == null || mWifiScanTimer.getSubTimer() == null) { 8542 return 0; 8543 } 8544 return mWifiScanTimer.getSubTimer().getCountLocked(which); 8545 } 8546 8547 @Override getWifiScanActualTime(final long elapsedRealtimeUs)8548 public long getWifiScanActualTime(final long elapsedRealtimeUs) { 8549 if (mWifiScanTimer == null) { 8550 return 0; 8551 } 8552 final long elapsedRealtimeMs = (elapsedRealtimeUs + 500) / 1000; 8553 return mWifiScanTimer.getTotalDurationMsLocked(elapsedRealtimeMs) * 1000; 8554 } 8555 8556 @Override getWifiScanBackgroundTime(final long elapsedRealtimeUs)8557 public long getWifiScanBackgroundTime(final long elapsedRealtimeUs) { 8558 if (mWifiScanTimer == null || mWifiScanTimer.getSubTimer() == null) { 8559 return 0; 8560 } 8561 final long elapsedRealtimeMs = (elapsedRealtimeUs + 500) / 1000; 8562 return mWifiScanTimer.getSubTimer().getTotalDurationMsLocked(elapsedRealtimeMs) * 1000; 8563 } 8564 8565 @Override getWifiScanBackgroundTimer()8566 public Timer getWifiScanBackgroundTimer() { 8567 if (mWifiScanTimer == null) { 8568 return null; 8569 } 8570 return mWifiScanTimer.getSubTimer(); 8571 } 8572 8573 @Override getWifiBatchedScanTime(int csphBin, long elapsedRealtimeUs, int which)8574 public long getWifiBatchedScanTime(int csphBin, long elapsedRealtimeUs, int which) { 8575 if (csphBin < 0 || csphBin >= NUM_WIFI_BATCHED_SCAN_BINS) return 0; 8576 if (mWifiBatchedScanTimer[csphBin] == null) { 8577 return 0; 8578 } 8579 return mWifiBatchedScanTimer[csphBin].getTotalTimeLocked(elapsedRealtimeUs, which); 8580 } 8581 8582 @Override getWifiBatchedScanCount(int csphBin, int which)8583 public int getWifiBatchedScanCount(int csphBin, int which) { 8584 if (csphBin < 0 || csphBin >= NUM_WIFI_BATCHED_SCAN_BINS) return 0; 8585 if (mWifiBatchedScanTimer[csphBin] == null) { 8586 return 0; 8587 } 8588 return mWifiBatchedScanTimer[csphBin].getCountLocked(which); 8589 } 8590 8591 @Override getWifiMulticastTime(long elapsedRealtimeUs, int which)8592 public long getWifiMulticastTime(long elapsedRealtimeUs, int which) { 8593 if (mWifiMulticastTimer == null) { 8594 return 0; 8595 } 8596 return mWifiMulticastTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 8597 } 8598 8599 @Override getAudioTurnedOnTimer()8600 public Timer getAudioTurnedOnTimer() { 8601 return mAudioTurnedOnTimer; 8602 } 8603 8604 @Override getVideoTurnedOnTimer()8605 public Timer getVideoTurnedOnTimer() { 8606 return mVideoTurnedOnTimer; 8607 } 8608 8609 @Override getFlashlightTurnedOnTimer()8610 public Timer getFlashlightTurnedOnTimer() { 8611 return mFlashlightTurnedOnTimer; 8612 } 8613 8614 @Override getCameraTurnedOnTimer()8615 public Timer getCameraTurnedOnTimer() { 8616 return mCameraTurnedOnTimer; 8617 } 8618 8619 @Override getForegroundActivityTimer()8620 public Timer getForegroundActivityTimer() { 8621 return mForegroundActivityTimer; 8622 } 8623 8624 @Override getForegroundServiceTimer()8625 public Timer getForegroundServiceTimer() { 8626 return mForegroundServiceTimer; 8627 } 8628 8629 @Override getBluetoothScanTimer()8630 public Timer getBluetoothScanTimer() { 8631 return mBluetoothScanTimer; 8632 } 8633 8634 @Override getBluetoothScanBackgroundTimer()8635 public Timer getBluetoothScanBackgroundTimer() { 8636 if (mBluetoothScanTimer == null) { 8637 return null; 8638 } 8639 return mBluetoothScanTimer.getSubTimer(); 8640 } 8641 8642 @Override getBluetoothUnoptimizedScanTimer()8643 public Timer getBluetoothUnoptimizedScanTimer() { 8644 return mBluetoothUnoptimizedScanTimer; 8645 } 8646 8647 @Override getBluetoothUnoptimizedScanBackgroundTimer()8648 public Timer getBluetoothUnoptimizedScanBackgroundTimer() { 8649 if (mBluetoothUnoptimizedScanTimer == null) { 8650 return null; 8651 } 8652 return mBluetoothUnoptimizedScanTimer.getSubTimer(); 8653 } 8654 8655 @Override getBluetoothScanResultCounter()8656 public Counter getBluetoothScanResultCounter() { 8657 return mBluetoothScanResultCounter; 8658 } 8659 8660 @Override getBluetoothScanResultBgCounter()8661 public Counter getBluetoothScanResultBgCounter() { 8662 return mBluetoothScanResultBgCounter; 8663 } 8664 makeProcessState(int i, Parcel in)8665 void makeProcessState(int i, Parcel in) { 8666 if (i < 0 || i >= NUM_PROCESS_STATE) return; 8667 8668 detachIfNotNull(mProcessStateTimer[i]); 8669 if (in == null) { 8670 mProcessStateTimer[i] = new StopwatchTimer(mBsi.mClocks, this, PROCESS_STATE, null, 8671 mBsi.mOnBatteryTimeBase); 8672 } else { 8673 mProcessStateTimer[i] = new StopwatchTimer(mBsi.mClocks, this, PROCESS_STATE, null, 8674 mBsi.mOnBatteryTimeBase, in); 8675 } 8676 } 8677 8678 @Override getProcessStateTime(int state, long elapsedRealtimeUs, int which)8679 public long getProcessStateTime(int state, long elapsedRealtimeUs, int which) { 8680 if (state < 0 || state >= NUM_PROCESS_STATE) return 0; 8681 if (mProcessStateTimer[state] == null) { 8682 return 0; 8683 } 8684 return mProcessStateTimer[state].getTotalTimeLocked(elapsedRealtimeUs, which); 8685 } 8686 8687 @Override getProcessStateTimer(int state)8688 public Timer getProcessStateTimer(int state) { 8689 if (state < 0 || state >= NUM_PROCESS_STATE) return null; 8690 return mProcessStateTimer[state]; 8691 } 8692 8693 @Override getVibratorOnTimer()8694 public Timer getVibratorOnTimer() { 8695 return mVibratorOnTimer; 8696 } 8697 8698 @Override noteUserActivityLocked(int type)8699 public void noteUserActivityLocked(int type) { 8700 if (mUserActivityCounters == null) { 8701 initUserActivityLocked(); 8702 } 8703 if (type >= 0 && type < NUM_USER_ACTIVITY_TYPES) { 8704 mUserActivityCounters[type].stepAtomic(); 8705 } else { 8706 Slog.w(TAG, "Unknown user activity type " + type + " was specified.", 8707 new Throwable()); 8708 } 8709 } 8710 8711 @Override hasUserActivity()8712 public boolean hasUserActivity() { 8713 return mUserActivityCounters != null; 8714 } 8715 8716 @Override getUserActivityCount(int type, int which)8717 public int getUserActivityCount(int type, int which) { 8718 if (mUserActivityCounters == null) { 8719 return 0; 8720 } 8721 return mUserActivityCounters[type].getCountLocked(which); 8722 } 8723 makeWifiBatchedScanBin(int i, Parcel in)8724 void makeWifiBatchedScanBin(int i, Parcel in) { 8725 if (i < 0 || i >= NUM_WIFI_BATCHED_SCAN_BINS) return; 8726 8727 ArrayList<StopwatchTimer> collected = mBsi.mWifiBatchedScanTimers.get(i); 8728 if (collected == null) { 8729 collected = new ArrayList<StopwatchTimer>(); 8730 mBsi.mWifiBatchedScanTimers.put(i, collected); 8731 } 8732 detachIfNotNull(mWifiBatchedScanTimer[i]); 8733 if (in == null) { 8734 mWifiBatchedScanTimer[i] = new StopwatchTimer(mBsi.mClocks, this, WIFI_BATCHED_SCAN, 8735 collected, mBsi.mOnBatteryTimeBase); 8736 } else { 8737 mWifiBatchedScanTimer[i] = new StopwatchTimer(mBsi.mClocks, this, WIFI_BATCHED_SCAN, 8738 collected, mBsi.mOnBatteryTimeBase, in); 8739 } 8740 } 8741 8742 initUserActivityLocked()8743 void initUserActivityLocked() { 8744 detachIfNotNull(mUserActivityCounters); 8745 mUserActivityCounters = new Counter[NUM_USER_ACTIVITY_TYPES]; 8746 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) { 8747 mUserActivityCounters[i] = new Counter(mBsi.mOnBatteryTimeBase); 8748 } 8749 } 8750 noteNetworkActivityLocked(int type, long deltaBytes, long deltaPackets)8751 void noteNetworkActivityLocked(int type, long deltaBytes, long deltaPackets) { 8752 if (mNetworkByteActivityCounters == null) { 8753 initNetworkActivityLocked(); 8754 } 8755 if (type >= 0 && type < NUM_NETWORK_ACTIVITY_TYPES) { 8756 mNetworkByteActivityCounters[type].addCountLocked(deltaBytes); 8757 mNetworkPacketActivityCounters[type].addCountLocked(deltaPackets); 8758 } else { 8759 Slog.w(TAG, "Unknown network activity type " + type + " was specified.", 8760 new Throwable()); 8761 } 8762 } 8763 noteMobileRadioActiveTimeLocked(long batteryUptime)8764 void noteMobileRadioActiveTimeLocked(long batteryUptime) { 8765 if (mNetworkByteActivityCounters == null) { 8766 initNetworkActivityLocked(); 8767 } 8768 mMobileRadioActiveTime.addCountLocked(batteryUptime); 8769 mMobileRadioActiveCount.addCountLocked(1); 8770 } 8771 8772 @Override hasNetworkActivity()8773 public boolean hasNetworkActivity() { 8774 return mNetworkByteActivityCounters != null; 8775 } 8776 8777 @Override getNetworkActivityBytes(int type, int which)8778 public long getNetworkActivityBytes(int type, int which) { 8779 if (mNetworkByteActivityCounters != null && type >= 0 8780 && type < mNetworkByteActivityCounters.length) { 8781 return mNetworkByteActivityCounters[type].getCountLocked(which); 8782 } else { 8783 return 0; 8784 } 8785 } 8786 8787 @Override getNetworkActivityPackets(int type, int which)8788 public long getNetworkActivityPackets(int type, int which) { 8789 if (mNetworkPacketActivityCounters != null && type >= 0 8790 && type < mNetworkPacketActivityCounters.length) { 8791 return mNetworkPacketActivityCounters[type].getCountLocked(which); 8792 } else { 8793 return 0; 8794 } 8795 } 8796 8797 @Override getMobileRadioActiveTime(int which)8798 public long getMobileRadioActiveTime(int which) { 8799 return mMobileRadioActiveTime != null 8800 ? mMobileRadioActiveTime.getCountLocked(which) : 0; 8801 } 8802 8803 @Override getMobileRadioActiveCount(int which)8804 public int getMobileRadioActiveCount(int which) { 8805 return mMobileRadioActiveCount != null 8806 ? (int)mMobileRadioActiveCount.getCountLocked(which) : 0; 8807 } 8808 8809 @Override getUserCpuTimeUs(int which)8810 public long getUserCpuTimeUs(int which) { 8811 return mUserCpuTime.getCountLocked(which); 8812 } 8813 8814 @Override getSystemCpuTimeUs(int which)8815 public long getSystemCpuTimeUs(int which) { 8816 return mSystemCpuTime.getCountLocked(which); 8817 } 8818 8819 @Override getTimeAtCpuSpeed(int cluster, int step, int which)8820 public long getTimeAtCpuSpeed(int cluster, int step, int which) { 8821 if (mCpuClusterSpeedTimesUs != null) { 8822 if (cluster >= 0 && cluster < mCpuClusterSpeedTimesUs.length) { 8823 final LongSamplingCounter[] cpuSpeedTimesUs = mCpuClusterSpeedTimesUs[cluster]; 8824 if (cpuSpeedTimesUs != null) { 8825 if (step >= 0 && step < cpuSpeedTimesUs.length) { 8826 final LongSamplingCounter c = cpuSpeedTimesUs[step]; 8827 if (c != null) { 8828 return c.getCountLocked(which); 8829 } 8830 } 8831 } 8832 } 8833 } 8834 return 0; 8835 } 8836 noteMobileRadioApWakeupLocked()8837 public void noteMobileRadioApWakeupLocked() { 8838 if (mMobileRadioApWakeupCount == null) { 8839 mMobileRadioApWakeupCount = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); 8840 } 8841 mMobileRadioApWakeupCount.addCountLocked(1); 8842 } 8843 8844 @Override getMobileRadioApWakeupCount(int which)8845 public long getMobileRadioApWakeupCount(int which) { 8846 if (mMobileRadioApWakeupCount != null) { 8847 return mMobileRadioApWakeupCount.getCountLocked(which); 8848 } 8849 return 0; 8850 } 8851 noteWifiRadioApWakeupLocked()8852 public void noteWifiRadioApWakeupLocked() { 8853 if (mWifiRadioApWakeupCount == null) { 8854 mWifiRadioApWakeupCount = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); 8855 } 8856 mWifiRadioApWakeupCount.addCountLocked(1); 8857 } 8858 8859 @Override getWifiRadioApWakeupCount(int which)8860 public long getWifiRadioApWakeupCount(int which) { 8861 if (mWifiRadioApWakeupCount != null) { 8862 return mWifiRadioApWakeupCount.getCountLocked(which); 8863 } 8864 return 0; 8865 } 8866 8867 @Override getDeferredJobsCheckinLineLocked(StringBuilder sb, int which)8868 public void getDeferredJobsCheckinLineLocked(StringBuilder sb, int which) { 8869 sb.setLength(0); 8870 final int deferredEventCount = mJobsDeferredEventCount.getCountLocked(which); 8871 if (deferredEventCount == 0) { 8872 return; 8873 } 8874 final int deferredCount = mJobsDeferredCount.getCountLocked(which); 8875 final long totalLatency = mJobsFreshnessTimeMs.getCountLocked(which); 8876 sb.append(deferredEventCount); sb.append(','); 8877 sb.append(deferredCount); sb.append(','); 8878 sb.append(totalLatency); 8879 for (int i = 0; i < JOB_FRESHNESS_BUCKETS.length; i++) { 8880 if (mJobsFreshnessBuckets[i] == null) { 8881 sb.append(",0"); 8882 } else { 8883 sb.append(","); 8884 sb.append(mJobsFreshnessBuckets[i].getCountLocked(which)); 8885 } 8886 } 8887 } 8888 8889 @Override getDeferredJobsLineLocked(StringBuilder sb, int which)8890 public void getDeferredJobsLineLocked(StringBuilder sb, int which) { 8891 sb.setLength(0); 8892 final int deferredEventCount = mJobsDeferredEventCount.getCountLocked(which); 8893 if (deferredEventCount == 0) { 8894 return; 8895 } 8896 final int deferredCount = mJobsDeferredCount.getCountLocked(which); 8897 final long totalLatency = mJobsFreshnessTimeMs.getCountLocked(which); 8898 sb.append("times="); sb.append(deferredEventCount); sb.append(", "); 8899 sb.append("count="); sb.append(deferredCount); sb.append(", "); 8900 sb.append("totalLatencyMs="); sb.append(totalLatency); sb.append(", "); 8901 for (int i = 0; i < JOB_FRESHNESS_BUCKETS.length; i++) { 8902 sb.append("<"); sb.append(JOB_FRESHNESS_BUCKETS[i]); sb.append("ms="); 8903 if (mJobsFreshnessBuckets[i] == null) { 8904 sb.append("0"); 8905 } else { 8906 sb.append(mJobsFreshnessBuckets[i].getCountLocked(which)); 8907 } 8908 sb.append(" "); 8909 } 8910 } 8911 initNetworkActivityLocked()8912 void initNetworkActivityLocked() { 8913 detachIfNotNull(mNetworkByteActivityCounters); 8914 mNetworkByteActivityCounters = new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES]; 8915 detachIfNotNull(mNetworkPacketActivityCounters); 8916 mNetworkPacketActivityCounters = new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES]; 8917 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 8918 mNetworkByteActivityCounters[i] = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); 8919 mNetworkPacketActivityCounters[i] = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); 8920 } 8921 detachIfNotNull(mMobileRadioActiveTime); 8922 mMobileRadioActiveTime = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); 8923 detachIfNotNull(mMobileRadioActiveCount); 8924 mMobileRadioActiveCount = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); 8925 } 8926 8927 /** 8928 * Clear all stats for this uid. Returns true if the uid is completely 8929 * inactive so can be dropped. 8930 */ 8931 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) reset(long uptimeUs, long realtimeUs, int resetReason)8932 public boolean reset(long uptimeUs, long realtimeUs, int resetReason) { 8933 boolean active = false; 8934 8935 mOnBatteryBackgroundTimeBase.init(uptimeUs, realtimeUs); 8936 mOnBatteryScreenOffBackgroundTimeBase.init(uptimeUs, realtimeUs); 8937 8938 if (mWifiRunningTimer != null) { 8939 active |= !mWifiRunningTimer.reset(false, realtimeUs); 8940 active |= mWifiRunning; 8941 } 8942 if (mFullWifiLockTimer != null) { 8943 active |= !mFullWifiLockTimer.reset(false, realtimeUs); 8944 active |= mFullWifiLockOut; 8945 } 8946 if (mWifiScanTimer != null) { 8947 active |= !mWifiScanTimer.reset(false, realtimeUs); 8948 active |= mWifiScanStarted; 8949 } 8950 if (mWifiBatchedScanTimer != null) { 8951 for (int i = 0; i < NUM_WIFI_BATCHED_SCAN_BINS; i++) { 8952 if (mWifiBatchedScanTimer[i] != null) { 8953 active |= !mWifiBatchedScanTimer[i].reset(false, realtimeUs); 8954 } 8955 } 8956 active |= (mWifiBatchedScanBinStarted != NO_BATCHED_SCAN_STARTED); 8957 } 8958 if (mWifiMulticastTimer != null) { 8959 active |= !mWifiMulticastTimer.reset(false, realtimeUs); 8960 active |= (mWifiMulticastWakelockCount > 0); 8961 } 8962 8963 active |= !resetIfNotNull(mAudioTurnedOnTimer, false, realtimeUs); 8964 active |= !resetIfNotNull(mVideoTurnedOnTimer, false, realtimeUs); 8965 active |= !resetIfNotNull(mFlashlightTurnedOnTimer, false, realtimeUs); 8966 active |= !resetIfNotNull(mCameraTurnedOnTimer, false, realtimeUs); 8967 active |= !resetIfNotNull(mForegroundActivityTimer, false, realtimeUs); 8968 active |= !resetIfNotNull(mForegroundServiceTimer, false, realtimeUs); 8969 active |= !resetIfNotNull(mAggregatedPartialWakelockTimer, false, realtimeUs); 8970 active |= !resetIfNotNull(mBluetoothScanTimer, false, realtimeUs); 8971 active |= !resetIfNotNull(mBluetoothUnoptimizedScanTimer, false, realtimeUs); 8972 8973 resetIfNotNull(mBluetoothScanResultCounter, false, realtimeUs); 8974 resetIfNotNull(mBluetoothScanResultBgCounter, false, realtimeUs); 8975 8976 if (mProcessStateTimer != null) { 8977 for (int i = 0; i < NUM_PROCESS_STATE; i++) { 8978 active |= !resetIfNotNull(mProcessStateTimer[i], false, realtimeUs); 8979 } 8980 active |= (mProcessState != ActivityManager.PROCESS_STATE_NONEXISTENT); 8981 } 8982 if (mVibratorOnTimer != null) { 8983 if (mVibratorOnTimer.reset(false, realtimeUs)) { 8984 mVibratorOnTimer.detach(); 8985 mVibratorOnTimer = null; 8986 } else { 8987 active = true; 8988 } 8989 } 8990 8991 resetIfNotNull(mUserActivityCounters, false, realtimeUs); 8992 8993 resetIfNotNull(mNetworkByteActivityCounters, false, realtimeUs); 8994 resetIfNotNull(mNetworkPacketActivityCounters, false, realtimeUs); 8995 resetIfNotNull(mMobileRadioActiveTime, false, realtimeUs); 8996 resetIfNotNull(mMobileRadioActiveCount, false, realtimeUs); 8997 8998 resetIfNotNull(mWifiControllerActivity, false, realtimeUs); 8999 resetIfNotNull(mBluetoothControllerActivity, false, realtimeUs); 9000 resetIfNotNull(mModemControllerActivity, false, realtimeUs); 9001 9002 if (resetReason == RESET_REASON_MEASURED_ENERGY_BUCKETS_CHANGE) { 9003 mUidMeasuredEnergyStats = null; 9004 } else { 9005 MeasuredEnergyStats.resetIfNotNull(mUidMeasuredEnergyStats); 9006 } 9007 9008 resetIfNotNull(mUserCpuTime, false, realtimeUs); 9009 resetIfNotNull(mSystemCpuTime, false, realtimeUs); 9010 9011 resetIfNotNull(mCpuClusterSpeedTimesUs, false, realtimeUs); 9012 9013 resetIfNotNull(mCpuFreqTimeMs, false, realtimeUs /* unused */); 9014 resetIfNotNull(mScreenOffCpuFreqTimeMs, false, realtimeUs /* unused */); 9015 9016 9017 resetIfNotNull(mCpuActiveTimeMs, false, realtimeUs /* unused */); 9018 resetIfNotNull(mCpuClusterTimesMs, false, realtimeUs /* unused */); 9019 9020 resetIfNotNull(mProcStateTimeMs, false, realtimeUs /* unused */); 9021 9022 resetIfNotNull(mProcStateScreenOffTimeMs, false, realtimeUs /* unused */); 9023 9024 resetIfNotNull(mMobileRadioApWakeupCount, false, realtimeUs); 9025 9026 resetIfNotNull(mWifiRadioApWakeupCount, false, realtimeUs); 9027 9028 9029 final ArrayMap<String, Wakelock> wakeStats = mWakelockStats.getMap(); 9030 for (int iw=wakeStats.size()-1; iw>=0; iw--) { 9031 Wakelock wl = wakeStats.valueAt(iw); 9032 if (wl.reset(realtimeUs)) { 9033 wakeStats.removeAt(iw); 9034 } else { 9035 active = true; 9036 } 9037 } 9038 final long realtimeMs = realtimeUs / 1000; 9039 mWakelockStats.cleanup(realtimeMs); 9040 final ArrayMap<String, DualTimer> syncStats = mSyncStats.getMap(); 9041 for (int is=syncStats.size()-1; is>=0; is--) { 9042 DualTimer timer = syncStats.valueAt(is); 9043 if (timer.reset(false, realtimeUs)) { 9044 syncStats.removeAt(is); 9045 timer.detach(); 9046 } else { 9047 active = true; 9048 } 9049 } 9050 mSyncStats.cleanup(realtimeMs); 9051 final ArrayMap<String, DualTimer> jobStats = mJobStats.getMap(); 9052 for (int ij=jobStats.size()-1; ij>=0; ij--) { 9053 DualTimer timer = jobStats.valueAt(ij); 9054 if (timer.reset(false, realtimeUs)) { 9055 jobStats.removeAt(ij); 9056 timer.detach(); 9057 } else { 9058 active = true; 9059 } 9060 } 9061 mJobStats.cleanup(realtimeMs); 9062 mJobCompletions.clear(); 9063 9064 resetIfNotNull(mJobsDeferredEventCount, false, realtimeUs); 9065 resetIfNotNull(mJobsDeferredCount, false, realtimeUs); 9066 resetIfNotNull(mJobsFreshnessTimeMs, false, realtimeUs /* unused */); 9067 resetIfNotNull(mJobsFreshnessBuckets, false, realtimeUs); 9068 9069 for (int ise = mSensorStats.size() - 1; ise >= 0; ise--) { 9070 Sensor s = mSensorStats.valueAt(ise); 9071 if (s.reset(realtimeUs)) { 9072 mSensorStats.removeAt(ise); 9073 } else { 9074 active = true; 9075 } 9076 } 9077 9078 for (int ip = mProcessStats.size() - 1; ip >= 0; ip--) { 9079 Proc proc = mProcessStats.valueAt(ip); 9080 proc.detach(); 9081 } 9082 mProcessStats.clear(); 9083 9084 for (int i = mPids.size() - 1; i >= 0; i--) { 9085 Pid pid = mPids.valueAt(i); 9086 if (pid.mWakeNesting > 0) { 9087 active = true; 9088 } else { 9089 mPids.removeAt(i); 9090 } 9091 } 9092 9093 9094 for(int i = mPackageStats.size() - 1; i >= 0; i--) { 9095 Pkg p = mPackageStats.valueAt(i); 9096 p.detach(); 9097 } 9098 mPackageStats.clear(); 9099 9100 mBinderCallCount = 0; 9101 mBinderCallStats.clear(); 9102 9103 mProportionalSystemServiceUsage = 0; 9104 9105 mLastStepUserTimeMs = mLastStepSystemTimeMs = 0; 9106 mCurStepUserTimeMs = mCurStepSystemTimeMs = 0; 9107 9108 9109 return !active; 9110 } 9111 9112 /** 9113 * This method MUST be called whenever the Uid object is destructed, otherwise it is a 9114 * memory leak in {@link TimeBase#mObservers} list. 9115 * Typically the Uid object is destructed when it is removed from 9116 * {@link BatteryStatsImpl#mUidStats} 9117 */ detachFromTimeBase()9118 void detachFromTimeBase() { 9119 detachIfNotNull(mWifiRunningTimer); 9120 detachIfNotNull(mFullWifiLockTimer); 9121 detachIfNotNull(mWifiScanTimer); 9122 detachIfNotNull(mWifiBatchedScanTimer); 9123 detachIfNotNull(mWifiMulticastTimer); 9124 detachIfNotNull(mAudioTurnedOnTimer); 9125 detachIfNotNull(mVideoTurnedOnTimer); 9126 detachIfNotNull(mFlashlightTurnedOnTimer); 9127 9128 detachIfNotNull(mCameraTurnedOnTimer); 9129 detachIfNotNull(mForegroundActivityTimer); 9130 detachIfNotNull(mForegroundServiceTimer); 9131 9132 detachIfNotNull(mAggregatedPartialWakelockTimer); 9133 9134 detachIfNotNull(mBluetoothScanTimer); 9135 detachIfNotNull(mBluetoothUnoptimizedScanTimer); 9136 detachIfNotNull(mBluetoothScanResultCounter); 9137 detachIfNotNull(mBluetoothScanResultBgCounter); 9138 9139 detachIfNotNull(mProcessStateTimer); 9140 9141 detachIfNotNull(mVibratorOnTimer); 9142 9143 detachIfNotNull(mUserActivityCounters); 9144 9145 detachIfNotNull(mNetworkByteActivityCounters); 9146 detachIfNotNull(mNetworkPacketActivityCounters); 9147 9148 detachIfNotNull(mMobileRadioActiveTime); 9149 detachIfNotNull(mMobileRadioActiveCount); 9150 detachIfNotNull(mMobileRadioApWakeupCount); 9151 detachIfNotNull(mWifiRadioApWakeupCount); 9152 9153 detachIfNotNull(mWifiControllerActivity); 9154 detachIfNotNull(mBluetoothControllerActivity); 9155 detachIfNotNull(mModemControllerActivity); 9156 9157 mPids.clear(); 9158 9159 detachIfNotNull(mUserCpuTime); 9160 detachIfNotNull(mSystemCpuTime); 9161 9162 detachIfNotNull(mCpuClusterSpeedTimesUs); 9163 9164 detachIfNotNull(mCpuActiveTimeMs); 9165 detachIfNotNull(mCpuFreqTimeMs); 9166 9167 detachIfNotNull(mScreenOffCpuFreqTimeMs); 9168 9169 detachIfNotNull(mCpuClusterTimesMs); 9170 9171 detachIfNotNull(mProcStateTimeMs); 9172 9173 detachIfNotNull(mProcStateScreenOffTimeMs); 9174 9175 final ArrayMap<String, Wakelock> wakeStats = mWakelockStats.getMap(); 9176 for (int iw = wakeStats.size() - 1; iw >= 0; iw--) { 9177 Wakelock wl = wakeStats.valueAt(iw); 9178 wl.detachFromTimeBase(); 9179 } 9180 final ArrayMap<String, DualTimer> syncStats = mSyncStats.getMap(); 9181 for (int is = syncStats.size() - 1; is >= 0; is--) { 9182 DualTimer timer = syncStats.valueAt(is); 9183 detachIfNotNull(timer); 9184 } 9185 final ArrayMap<String, DualTimer> jobStats = mJobStats.getMap(); 9186 for (int ij = jobStats.size() - 1; ij >= 0; ij--) { 9187 DualTimer timer = jobStats.valueAt(ij); 9188 detachIfNotNull(timer); 9189 } 9190 9191 detachIfNotNull(mJobsDeferredEventCount); 9192 detachIfNotNull(mJobsDeferredCount); 9193 detachIfNotNull(mJobsFreshnessTimeMs); 9194 detachIfNotNull(mJobsFreshnessBuckets); 9195 9196 9197 for (int ise = mSensorStats.size() - 1; ise >= 0; ise--) { 9198 Sensor s = mSensorStats.valueAt(ise); 9199 s.detachFromTimeBase(); 9200 } 9201 9202 for (int ip= mProcessStats.size() - 1; ip >= 0; ip--) { 9203 Proc proc = mProcessStats.valueAt(ip); 9204 proc.detach(); 9205 } 9206 mProcessStats.clear(); 9207 9208 for(int i = mPackageStats.size() - 1; i >= 0; i--) { 9209 Pkg p = mPackageStats.valueAt(i); 9210 p.detach(); 9211 } 9212 mPackageStats.clear(); 9213 } 9214 writeJobCompletionsToParcelLocked(Parcel out)9215 void writeJobCompletionsToParcelLocked(Parcel out) { 9216 int NJC = mJobCompletions.size(); 9217 out.writeInt(NJC); 9218 for (int ijc=0; ijc<NJC; ijc++) { 9219 out.writeString(mJobCompletions.keyAt(ijc)); 9220 SparseIntArray types = mJobCompletions.valueAt(ijc); 9221 int NT = types.size(); 9222 out.writeInt(NT); 9223 for (int it=0; it<NT; it++) { 9224 out.writeInt(types.keyAt(it)); 9225 out.writeInt(types.valueAt(it)); 9226 } 9227 } 9228 } 9229 writeToParcelLocked(Parcel out, long uptimeUs, long elapsedRealtimeUs)9230 void writeToParcelLocked(Parcel out, long uptimeUs, long elapsedRealtimeUs) { 9231 mOnBatteryBackgroundTimeBase.writeToParcel(out, uptimeUs, elapsedRealtimeUs); 9232 mOnBatteryScreenOffBackgroundTimeBase.writeToParcel(out, uptimeUs, elapsedRealtimeUs); 9233 9234 final ArrayMap<String, Wakelock> wakeStats = mWakelockStats.getMap(); 9235 int NW = wakeStats.size(); 9236 out.writeInt(NW); 9237 for (int iw=0; iw<NW; iw++) { 9238 out.writeString(wakeStats.keyAt(iw)); 9239 Uid.Wakelock wakelock = wakeStats.valueAt(iw); 9240 wakelock.writeToParcelLocked(out, elapsedRealtimeUs); 9241 } 9242 9243 final ArrayMap<String, DualTimer> syncStats = mSyncStats.getMap(); 9244 int NS = syncStats.size(); 9245 out.writeInt(NS); 9246 for (int is=0; is<NS; is++) { 9247 out.writeString(syncStats.keyAt(is)); 9248 DualTimer timer = syncStats.valueAt(is); 9249 Timer.writeTimerToParcel(out, timer, elapsedRealtimeUs); 9250 } 9251 9252 final ArrayMap<String, DualTimer> jobStats = mJobStats.getMap(); 9253 int NJ = jobStats.size(); 9254 out.writeInt(NJ); 9255 for (int ij=0; ij<NJ; ij++) { 9256 out.writeString(jobStats.keyAt(ij)); 9257 DualTimer timer = jobStats.valueAt(ij); 9258 Timer.writeTimerToParcel(out, timer, elapsedRealtimeUs); 9259 } 9260 9261 writeJobCompletionsToParcelLocked(out); 9262 9263 mJobsDeferredEventCount.writeToParcel(out); 9264 mJobsDeferredCount.writeToParcel(out); 9265 mJobsFreshnessTimeMs.writeToParcel(out); 9266 for (int i = 0; i < JOB_FRESHNESS_BUCKETS.length; i++) { 9267 Counter.writeCounterToParcel(out, mJobsFreshnessBuckets[i]); 9268 } 9269 9270 int NSE = mSensorStats.size(); 9271 out.writeInt(NSE); 9272 for (int ise=0; ise<NSE; ise++) { 9273 out.writeInt(mSensorStats.keyAt(ise)); 9274 Uid.Sensor sensor = mSensorStats.valueAt(ise); 9275 sensor.writeToParcelLocked(out, elapsedRealtimeUs); 9276 } 9277 9278 int NP = mProcessStats.size(); 9279 out.writeInt(NP); 9280 for (int ip=0; ip<NP; ip++) { 9281 out.writeString(mProcessStats.keyAt(ip)); 9282 Uid.Proc proc = mProcessStats.valueAt(ip); 9283 proc.writeToParcelLocked(out); 9284 } 9285 9286 out.writeInt(mPackageStats.size()); 9287 for (Map.Entry<String, Uid.Pkg> pkgEntry : mPackageStats.entrySet()) { 9288 out.writeString(pkgEntry.getKey()); 9289 Uid.Pkg pkg = pkgEntry.getValue(); 9290 pkg.writeToParcelLocked(out); 9291 } 9292 9293 if (mWifiRunningTimer != null) { 9294 out.writeInt(1); 9295 mWifiRunningTimer.writeToParcel(out, elapsedRealtimeUs); 9296 } else { 9297 out.writeInt(0); 9298 } 9299 if (mFullWifiLockTimer != null) { 9300 out.writeInt(1); 9301 mFullWifiLockTimer.writeToParcel(out, elapsedRealtimeUs); 9302 } else { 9303 out.writeInt(0); 9304 } 9305 if (mWifiScanTimer != null) { 9306 out.writeInt(1); 9307 mWifiScanTimer.writeToParcel(out, elapsedRealtimeUs); 9308 } else { 9309 out.writeInt(0); 9310 } 9311 for (int i = 0; i < NUM_WIFI_BATCHED_SCAN_BINS; i++) { 9312 if (mWifiBatchedScanTimer[i] != null) { 9313 out.writeInt(1); 9314 mWifiBatchedScanTimer[i].writeToParcel(out, elapsedRealtimeUs); 9315 } else { 9316 out.writeInt(0); 9317 } 9318 } 9319 if (mWifiMulticastTimer != null) { 9320 out.writeInt(1); 9321 mWifiMulticastTimer.writeToParcel(out, elapsedRealtimeUs); 9322 } else { 9323 out.writeInt(0); 9324 } 9325 9326 if (mAudioTurnedOnTimer != null) { 9327 out.writeInt(1); 9328 mAudioTurnedOnTimer.writeToParcel(out, elapsedRealtimeUs); 9329 } else { 9330 out.writeInt(0); 9331 } 9332 if (mVideoTurnedOnTimer != null) { 9333 out.writeInt(1); 9334 mVideoTurnedOnTimer.writeToParcel(out, elapsedRealtimeUs); 9335 } else { 9336 out.writeInt(0); 9337 } 9338 if (mFlashlightTurnedOnTimer != null) { 9339 out.writeInt(1); 9340 mFlashlightTurnedOnTimer.writeToParcel(out, elapsedRealtimeUs); 9341 } else { 9342 out.writeInt(0); 9343 } 9344 if (mCameraTurnedOnTimer != null) { 9345 out.writeInt(1); 9346 mCameraTurnedOnTimer.writeToParcel(out, elapsedRealtimeUs); 9347 } else { 9348 out.writeInt(0); 9349 } 9350 if (mForegroundActivityTimer != null) { 9351 out.writeInt(1); 9352 mForegroundActivityTimer.writeToParcel(out, elapsedRealtimeUs); 9353 } else { 9354 out.writeInt(0); 9355 } 9356 if (mForegroundServiceTimer != null) { 9357 out.writeInt(1); 9358 mForegroundServiceTimer.writeToParcel(out, elapsedRealtimeUs); 9359 } else { 9360 out.writeInt(0); 9361 } 9362 if (mAggregatedPartialWakelockTimer != null) { 9363 out.writeInt(1); 9364 mAggregatedPartialWakelockTimer.writeToParcel(out, elapsedRealtimeUs); 9365 } else { 9366 out.writeInt(0); 9367 } 9368 if (mBluetoothScanTimer != null) { 9369 out.writeInt(1); 9370 mBluetoothScanTimer.writeToParcel(out, elapsedRealtimeUs); 9371 } else { 9372 out.writeInt(0); 9373 } 9374 if (mBluetoothUnoptimizedScanTimer != null) { 9375 out.writeInt(1); 9376 mBluetoothUnoptimizedScanTimer.writeToParcel(out, elapsedRealtimeUs); 9377 } else { 9378 out.writeInt(0); 9379 } 9380 if (mBluetoothScanResultCounter != null) { 9381 out.writeInt(1); 9382 mBluetoothScanResultCounter.writeToParcel(out); 9383 } else { 9384 out.writeInt(0); 9385 } 9386 if (mBluetoothScanResultBgCounter != null) { 9387 out.writeInt(1); 9388 mBluetoothScanResultBgCounter.writeToParcel(out); 9389 } else { 9390 out.writeInt(0); 9391 } 9392 for (int i = 0; i < NUM_PROCESS_STATE; i++) { 9393 if (mProcessStateTimer[i] != null) { 9394 out.writeInt(1); 9395 mProcessStateTimer[i].writeToParcel(out, elapsedRealtimeUs); 9396 } else { 9397 out.writeInt(0); 9398 } 9399 } 9400 if (mVibratorOnTimer != null) { 9401 out.writeInt(1); 9402 mVibratorOnTimer.writeToParcel(out, elapsedRealtimeUs); 9403 } else { 9404 out.writeInt(0); 9405 } 9406 if (mUserActivityCounters != null) { 9407 out.writeInt(1); 9408 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) { 9409 mUserActivityCounters[i].writeToParcel(out); 9410 } 9411 } else { 9412 out.writeInt(0); 9413 } 9414 if (mNetworkByteActivityCounters != null) { 9415 out.writeInt(1); 9416 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 9417 mNetworkByteActivityCounters[i].writeToParcel(out); 9418 mNetworkPacketActivityCounters[i].writeToParcel(out); 9419 } 9420 mMobileRadioActiveTime.writeToParcel(out); 9421 mMobileRadioActiveCount.writeToParcel(out); 9422 } else { 9423 out.writeInt(0); 9424 } 9425 9426 if (mWifiControllerActivity != null) { 9427 out.writeInt(1); 9428 mWifiControllerActivity.writeToParcel(out, 0); 9429 } else { 9430 out.writeInt(0); 9431 } 9432 9433 if (mBluetoothControllerActivity != null) { 9434 out.writeInt(1); 9435 mBluetoothControllerActivity.writeToParcel(out, 0); 9436 } else { 9437 out.writeInt(0); 9438 } 9439 9440 if (mModemControllerActivity != null) { 9441 out.writeInt(1); 9442 mModemControllerActivity.writeToParcel(out, 0); 9443 } else { 9444 out.writeInt(0); 9445 } 9446 9447 if (mUidMeasuredEnergyStats != null) { 9448 out.writeInt(1); 9449 mUidMeasuredEnergyStats.writeToParcel(out); 9450 } else { 9451 out.writeInt(0); 9452 } 9453 9454 mUserCpuTime.writeToParcel(out); 9455 mSystemCpuTime.writeToParcel(out); 9456 9457 mBsi.writeCpuSpeedCountersToParcel(out, mCpuClusterSpeedTimesUs); 9458 9459 LongSamplingCounterArray.writeToParcel(out, mCpuFreqTimeMs); 9460 LongSamplingCounterArray.writeToParcel(out, mScreenOffCpuFreqTimeMs); 9461 9462 mCpuActiveTimeMs.writeToParcel(out); 9463 mCpuClusterTimesMs.writeToParcel(out); 9464 9465 if (mProcStateTimeMs != null) { 9466 out.writeInt(mProcStateTimeMs.length); 9467 for (LongSamplingCounterArray counters : mProcStateTimeMs) { 9468 LongSamplingCounterArray.writeToParcel(out, counters); 9469 } 9470 } else { 9471 out.writeInt(0); 9472 } 9473 if (mProcStateScreenOffTimeMs != null) { 9474 out.writeInt(mProcStateScreenOffTimeMs.length); 9475 for (LongSamplingCounterArray counters : mProcStateScreenOffTimeMs) { 9476 LongSamplingCounterArray.writeToParcel(out, counters); 9477 } 9478 } else { 9479 out.writeInt(0); 9480 } 9481 9482 if (mMobileRadioApWakeupCount != null) { 9483 out.writeInt(1); 9484 mMobileRadioApWakeupCount.writeToParcel(out); 9485 } else { 9486 out.writeInt(0); 9487 } 9488 9489 if (mWifiRadioApWakeupCount != null) { 9490 out.writeInt(1); 9491 mWifiRadioApWakeupCount.writeToParcel(out); 9492 } else { 9493 out.writeInt(0); 9494 } 9495 out.writeDouble(mProportionalSystemServiceUsage); 9496 } 9497 readJobCompletionsFromParcelLocked(Parcel in)9498 void readJobCompletionsFromParcelLocked(Parcel in) { 9499 int numJobCompletions = in.readInt(); 9500 mJobCompletions.clear(); 9501 for (int j = 0; j < numJobCompletions; j++) { 9502 String jobName = in.readString(); 9503 int numTypes = in.readInt(); 9504 if (numTypes > 0) { 9505 SparseIntArray types = new SparseIntArray(); 9506 for (int k = 0; k < numTypes; k++) { 9507 int type = in.readInt(); 9508 int count = in.readInt(); 9509 types.put(type, count); 9510 } 9511 mJobCompletions.put(jobName, types); 9512 } 9513 } 9514 } 9515 readFromParcelLocked(TimeBase timeBase, TimeBase screenOffTimeBase, Parcel in)9516 void readFromParcelLocked(TimeBase timeBase, TimeBase screenOffTimeBase, Parcel in) { 9517 mOnBatteryBackgroundTimeBase.readFromParcel(in); 9518 mOnBatteryScreenOffBackgroundTimeBase.readFromParcel(in); 9519 9520 int numWakelocks = in.readInt(); 9521 mWakelockStats.clear(); 9522 for (int j = 0; j < numWakelocks; j++) { 9523 String wakelockName = in.readString(); 9524 Uid.Wakelock wakelock = new Wakelock(mBsi, this); 9525 wakelock.readFromParcelLocked( 9526 timeBase, screenOffTimeBase, mOnBatteryScreenOffBackgroundTimeBase, in); 9527 mWakelockStats.add(wakelockName, wakelock); 9528 } 9529 9530 int numSyncs = in.readInt(); 9531 mSyncStats.clear(); 9532 for (int j = 0; j < numSyncs; j++) { 9533 String syncName = in.readString(); 9534 if (in.readInt() != 0) { 9535 mSyncStats.add(syncName, new DualTimer(mBsi.mClocks, Uid.this, SYNC, null, 9536 mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase, in)); 9537 } 9538 } 9539 9540 int numJobs = in.readInt(); 9541 mJobStats.clear(); 9542 for (int j = 0; j < numJobs; j++) { 9543 String jobName = in.readString(); 9544 if (in.readInt() != 0) { 9545 mJobStats.add(jobName, new DualTimer(mBsi.mClocks, Uid.this, JOB, null, 9546 mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase, in)); 9547 } 9548 } 9549 9550 readJobCompletionsFromParcelLocked(in); 9551 9552 mJobsDeferredEventCount = new Counter(mBsi.mOnBatteryTimeBase, in); 9553 mJobsDeferredCount = new Counter(mBsi.mOnBatteryTimeBase, in); 9554 mJobsFreshnessTimeMs = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in); 9555 for (int i = 0; i < JOB_FRESHNESS_BUCKETS.length; i++) { 9556 mJobsFreshnessBuckets[i] = Counter.readCounterFromParcel(mBsi.mOnBatteryTimeBase, 9557 in); 9558 } 9559 9560 int numSensors = in.readInt(); 9561 mSensorStats.clear(); 9562 for (int k = 0; k < numSensors; k++) { 9563 int sensorNumber = in.readInt(); 9564 Uid.Sensor sensor = new Sensor(mBsi, this, sensorNumber); 9565 sensor.readFromParcelLocked(mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase, 9566 in); 9567 mSensorStats.put(sensorNumber, sensor); 9568 } 9569 9570 int numProcs = in.readInt(); 9571 mProcessStats.clear(); 9572 for (int k = 0; k < numProcs; k++) { 9573 String processName = in.readString(); 9574 Uid.Proc proc = new Proc(mBsi, processName); 9575 proc.readFromParcelLocked(in); 9576 mProcessStats.put(processName, proc); 9577 } 9578 9579 int numPkgs = in.readInt(); 9580 mPackageStats.clear(); 9581 for (int l = 0; l < numPkgs; l++) { 9582 String packageName = in.readString(); 9583 Uid.Pkg pkg = new Pkg(mBsi); 9584 pkg.readFromParcelLocked(in); 9585 mPackageStats.put(packageName, pkg); 9586 } 9587 9588 mWifiRunning = false; 9589 if (in.readInt() != 0) { 9590 mWifiRunningTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, WIFI_RUNNING, 9591 mBsi.mWifiRunningTimers, mBsi.mOnBatteryTimeBase, in); 9592 } else { 9593 mWifiRunningTimer = null; 9594 } 9595 mFullWifiLockOut = false; 9596 if (in.readInt() != 0) { 9597 mFullWifiLockTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, FULL_WIFI_LOCK, 9598 mBsi.mFullWifiLockTimers, mBsi.mOnBatteryTimeBase, in); 9599 } else { 9600 mFullWifiLockTimer = null; 9601 } 9602 mWifiScanStarted = false; 9603 if (in.readInt() != 0) { 9604 mWifiScanTimer = new DualTimer(mBsi.mClocks, Uid.this, WIFI_SCAN, 9605 mBsi.mWifiScanTimers, mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase, 9606 in); 9607 } else { 9608 mWifiScanTimer = null; 9609 } 9610 mWifiBatchedScanBinStarted = NO_BATCHED_SCAN_STARTED; 9611 for (int i = 0; i < NUM_WIFI_BATCHED_SCAN_BINS; i++) { 9612 if (in.readInt() != 0) { 9613 makeWifiBatchedScanBin(i, in); 9614 } else { 9615 mWifiBatchedScanTimer[i] = null; 9616 } 9617 } 9618 mWifiMulticastWakelockCount = 0; 9619 if (in.readInt() != 0) { 9620 mWifiMulticastTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, WIFI_MULTICAST_ENABLED, 9621 mBsi.mWifiMulticastTimers, mBsi.mOnBatteryTimeBase, in); 9622 } else { 9623 mWifiMulticastTimer = null; 9624 } 9625 if (in.readInt() != 0) { 9626 mAudioTurnedOnTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, AUDIO_TURNED_ON, 9627 mBsi.mAudioTurnedOnTimers, mBsi.mOnBatteryTimeBase, in); 9628 } else { 9629 mAudioTurnedOnTimer = null; 9630 } 9631 if (in.readInt() != 0) { 9632 mVideoTurnedOnTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, VIDEO_TURNED_ON, 9633 mBsi.mVideoTurnedOnTimers, mBsi.mOnBatteryTimeBase, in); 9634 } else { 9635 mVideoTurnedOnTimer = null; 9636 } 9637 if (in.readInt() != 0) { 9638 mFlashlightTurnedOnTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, 9639 FLASHLIGHT_TURNED_ON, mBsi.mFlashlightTurnedOnTimers, mBsi.mOnBatteryTimeBase, in); 9640 } else { 9641 mFlashlightTurnedOnTimer = null; 9642 } 9643 if (in.readInt() != 0) { 9644 mCameraTurnedOnTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, CAMERA_TURNED_ON, 9645 mBsi.mCameraTurnedOnTimers, mBsi.mOnBatteryTimeBase, in); 9646 } else { 9647 mCameraTurnedOnTimer = null; 9648 } 9649 if (in.readInt() != 0) { 9650 mForegroundActivityTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, 9651 FOREGROUND_ACTIVITY, null, mBsi.mOnBatteryTimeBase, in); 9652 } else { 9653 mForegroundActivityTimer = null; 9654 } 9655 if (in.readInt() != 0) { 9656 mForegroundServiceTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, 9657 FOREGROUND_SERVICE, null, mBsi.mOnBatteryTimeBase, in); 9658 } else { 9659 mForegroundServiceTimer = null; 9660 } 9661 if (in.readInt() != 0) { 9662 mAggregatedPartialWakelockTimer = new DualTimer(mBsi.mClocks, this, 9663 AGGREGATED_WAKE_TYPE_PARTIAL, null, 9664 mBsi.mOnBatteryScreenOffTimeBase, mOnBatteryScreenOffBackgroundTimeBase, 9665 in); 9666 } else { 9667 mAggregatedPartialWakelockTimer = null; 9668 } 9669 if (in.readInt() != 0) { 9670 mBluetoothScanTimer = new DualTimer(mBsi.mClocks, Uid.this, BLUETOOTH_SCAN_ON, 9671 mBsi.mBluetoothScanOnTimers, mBsi.mOnBatteryTimeBase, 9672 mOnBatteryBackgroundTimeBase, in); 9673 } else { 9674 mBluetoothScanTimer = null; 9675 } 9676 if (in.readInt() != 0) { 9677 mBluetoothUnoptimizedScanTimer = new DualTimer(mBsi.mClocks, Uid.this, 9678 BLUETOOTH_UNOPTIMIZED_SCAN_ON, null, 9679 mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase, in); 9680 } else { 9681 mBluetoothUnoptimizedScanTimer = null; 9682 } 9683 if (in.readInt() != 0) { 9684 mBluetoothScanResultCounter = new Counter(mBsi.mOnBatteryTimeBase, in); 9685 } else { 9686 mBluetoothScanResultCounter = null; 9687 } 9688 if (in.readInt() != 0) { 9689 mBluetoothScanResultBgCounter = new Counter(mOnBatteryBackgroundTimeBase, in); 9690 } else { 9691 mBluetoothScanResultBgCounter = null; 9692 } 9693 mProcessState = ActivityManager.PROCESS_STATE_NONEXISTENT; 9694 for (int i = 0; i < NUM_PROCESS_STATE; i++) { 9695 if (in.readInt() != 0) { 9696 makeProcessState(i, in); 9697 } else { 9698 mProcessStateTimer[i] = null; 9699 } 9700 } 9701 if (in.readInt() != 0) { 9702 mVibratorOnTimer = new BatchTimer(mBsi.mClocks, Uid.this, VIBRATOR_ON, 9703 mBsi.mOnBatteryTimeBase, in); 9704 } else { 9705 mVibratorOnTimer = null; 9706 } 9707 if (in.readInt() != 0) { 9708 mUserActivityCounters = new Counter[NUM_USER_ACTIVITY_TYPES]; 9709 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) { 9710 mUserActivityCounters[i] = new Counter(mBsi.mOnBatteryTimeBase, in); 9711 } 9712 } else { 9713 mUserActivityCounters = null; 9714 } 9715 if (in.readInt() != 0) { 9716 mNetworkByteActivityCounters = new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES]; 9717 mNetworkPacketActivityCounters 9718 = new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES]; 9719 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 9720 mNetworkByteActivityCounters[i] 9721 = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in); 9722 mNetworkPacketActivityCounters[i] 9723 = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in); 9724 } 9725 mMobileRadioActiveTime = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in); 9726 mMobileRadioActiveCount = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in); 9727 } else { 9728 mNetworkByteActivityCounters = null; 9729 mNetworkPacketActivityCounters = null; 9730 } 9731 9732 if (in.readInt() != 0) { 9733 mWifiControllerActivity = new ControllerActivityCounterImpl(mBsi.mOnBatteryTimeBase, 9734 NUM_WIFI_TX_LEVELS, in); 9735 } else { 9736 mWifiControllerActivity = null; 9737 } 9738 9739 if (in.readInt() != 0) { 9740 mBluetoothControllerActivity = new ControllerActivityCounterImpl(mBsi.mOnBatteryTimeBase, 9741 NUM_BT_TX_LEVELS, in); 9742 } else { 9743 mBluetoothControllerActivity = null; 9744 } 9745 9746 if (in.readInt() != 0) { 9747 mModemControllerActivity = new ControllerActivityCounterImpl(mBsi.mOnBatteryTimeBase, 9748 ModemActivityInfo.getNumTxPowerLevels(), in); 9749 } else { 9750 mModemControllerActivity = null; 9751 } 9752 9753 if (in.readInt() != 0) { 9754 mUidMeasuredEnergyStats = new MeasuredEnergyStats(in); 9755 } 9756 9757 mUserCpuTime = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in); 9758 mSystemCpuTime = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in); 9759 9760 mCpuClusterSpeedTimesUs = mBsi.readCpuSpeedCountersFromParcel(in); 9761 9762 mCpuFreqTimeMs = LongSamplingCounterArray.readFromParcel(in, mBsi.mOnBatteryTimeBase); 9763 mScreenOffCpuFreqTimeMs = LongSamplingCounterArray.readFromParcel( 9764 in, mBsi.mOnBatteryScreenOffTimeBase); 9765 9766 mCpuActiveTimeMs = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in); 9767 mCpuClusterTimesMs = new LongSamplingCounterArray(mBsi.mOnBatteryTimeBase, in); 9768 9769 int length = in.readInt(); 9770 if (length == NUM_PROCESS_STATE) { 9771 mProcStateTimeMs = new LongSamplingCounterArray[length]; 9772 for (int procState = 0; procState < length; ++procState) { 9773 mProcStateTimeMs[procState] = LongSamplingCounterArray.readFromParcel( 9774 in, mBsi.mOnBatteryTimeBase); 9775 } 9776 } else { 9777 mProcStateTimeMs = null; 9778 } 9779 length = in.readInt(); 9780 if (length == NUM_PROCESS_STATE) { 9781 mProcStateScreenOffTimeMs = new LongSamplingCounterArray[length]; 9782 for (int procState = 0; procState < length; ++procState) { 9783 mProcStateScreenOffTimeMs[procState] = LongSamplingCounterArray.readFromParcel( 9784 in, mBsi.mOnBatteryScreenOffTimeBase); 9785 } 9786 } else { 9787 mProcStateScreenOffTimeMs = null; 9788 } 9789 9790 if (in.readInt() != 0) { 9791 mMobileRadioApWakeupCount = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in); 9792 } else { 9793 mMobileRadioApWakeupCount = null; 9794 } 9795 9796 if (in.readInt() != 0) { 9797 mWifiRadioApWakeupCount = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in); 9798 } else { 9799 mWifiRadioApWakeupCount = null; 9800 } 9801 9802 mProportionalSystemServiceUsage = in.readDouble(); 9803 } 9804 noteJobsDeferredLocked(int numDeferred, long sinceLast)9805 public void noteJobsDeferredLocked(int numDeferred, long sinceLast) { 9806 mJobsDeferredEventCount.addAtomic(1); 9807 mJobsDeferredCount.addAtomic(numDeferred); 9808 if (sinceLast != 0) { 9809 // Add the total time, which can be divided by the event count to get an average 9810 mJobsFreshnessTimeMs.addCountLocked(sinceLast); 9811 // Also keep track of how many times there were in these different buckets. 9812 for (int i = 0; i < JOB_FRESHNESS_BUCKETS.length; i++) { 9813 if (sinceLast < JOB_FRESHNESS_BUCKETS[i]) { 9814 if (mJobsFreshnessBuckets[i] == null) { 9815 mJobsFreshnessBuckets[i] = new Counter( 9816 mBsi.mOnBatteryTimeBase); 9817 } 9818 mJobsFreshnessBuckets[i].addAtomic(1); 9819 break; 9820 } 9821 } 9822 } 9823 } 9824 9825 // Reusable object used as a key to lookup values in mBinderCallStats 9826 private static BinderCallStats sTempBinderCallStats = new BinderCallStats(); 9827 9828 /** 9829 * Notes incoming binder call stats associated with this work source UID. 9830 */ noteBinderCallStatsLocked(long incrementalCallCount, Collection<BinderCallsStats.CallStat> callStats)9831 public void noteBinderCallStatsLocked(long incrementalCallCount, 9832 Collection<BinderCallsStats.CallStat> callStats) { 9833 if (DEBUG) { 9834 Slog.d(TAG, "noteBinderCalls() workSourceUid = [" + mUid + "], " 9835 + " incrementalCallCount: " + incrementalCallCount + " callStats = [" 9836 + new ArrayList<>(callStats) + "]"); 9837 } 9838 mBinderCallCount += incrementalCallCount; 9839 for (BinderCallsStats.CallStat stat : callStats) { 9840 BinderCallStats bcs; 9841 sTempBinderCallStats.binderClass = stat.binderClass; 9842 sTempBinderCallStats.transactionCode = stat.transactionCode; 9843 int index = mBinderCallStats.indexOf(sTempBinderCallStats); 9844 if (index >= 0) { 9845 bcs = mBinderCallStats.valueAt(index); 9846 } else { 9847 bcs = new BinderCallStats(); 9848 bcs.binderClass = stat.binderClass; 9849 bcs.transactionCode = stat.transactionCode; 9850 mBinderCallStats.add(bcs); 9851 } 9852 9853 bcs.callCount += stat.incrementalCallCount; 9854 bcs.recordedCallCount = stat.recordedCallCount; 9855 bcs.recordedCpuTimeMicros = stat.cpuTimeMicros; 9856 } 9857 } 9858 9859 /** 9860 * The statistics associated with a particular wake lock. 9861 */ 9862 public static class Wakelock extends BatteryStats.Uid.Wakelock { 9863 /** 9864 * BatteryStatsImpl that we are associated with. 9865 */ 9866 protected BatteryStatsImpl mBsi; 9867 9868 /** 9869 * BatteryStatsImpl that we are associated with. 9870 */ 9871 protected Uid mUid; 9872 9873 /** 9874 * How long (in ms) this uid has been keeping the device partially awake. 9875 * Tracks both the total time and the time while the app was in the background. 9876 */ 9877 DualTimer mTimerPartial; 9878 9879 /** 9880 * How long (in ms) this uid has been keeping the device fully awake. 9881 */ 9882 StopwatchTimer mTimerFull; 9883 9884 /** 9885 * How long (in ms) this uid has had a window keeping the device awake. 9886 */ 9887 StopwatchTimer mTimerWindow; 9888 9889 /** 9890 * How long (in ms) this uid has had a draw wake lock. 9891 */ 9892 StopwatchTimer mTimerDraw; 9893 Wakelock(BatteryStatsImpl bsi, Uid uid)9894 public Wakelock(BatteryStatsImpl bsi, Uid uid) { 9895 mBsi = bsi; 9896 mUid = uid; 9897 } 9898 9899 /** 9900 * Reads a possibly null Timer from a Parcel. The timer is associated with the 9901 * proper timer pool from the given BatteryStatsImpl object. 9902 * 9903 * @param in the Parcel to be read from. 9904 * return a new Timer, or null. 9905 */ readStopwatchTimerFromParcel(int type, ArrayList<StopwatchTimer> pool, TimeBase timeBase, Parcel in)9906 private StopwatchTimer readStopwatchTimerFromParcel(int type, 9907 ArrayList<StopwatchTimer> pool, TimeBase timeBase, Parcel in) { 9908 if (in.readInt() == 0) { 9909 return null; 9910 } 9911 9912 return new StopwatchTimer(mBsi.mClocks, mUid, type, pool, timeBase, in); 9913 } 9914 9915 /** 9916 * Reads a possibly null Timer from a Parcel. The timer is associated with the 9917 * proper timer pool from the given BatteryStatsImpl object. 9918 * 9919 * @param in the Parcel to be read from. 9920 * return a new Timer, or null. 9921 */ readDualTimerFromParcel(int type, ArrayList<StopwatchTimer> pool, TimeBase timeBase, TimeBase bgTimeBase, Parcel in)9922 private DualTimer readDualTimerFromParcel(int type, ArrayList<StopwatchTimer> pool, 9923 TimeBase timeBase, TimeBase bgTimeBase, Parcel in) { 9924 if (in.readInt() == 0) { 9925 return null; 9926 } 9927 9928 return new DualTimer(mBsi.mClocks, mUid, type, pool, timeBase, bgTimeBase, in); 9929 } 9930 reset(long elapsedRealtimeUs)9931 boolean reset(long elapsedRealtimeUs) { 9932 boolean wlactive = false; 9933 9934 wlactive |= !resetIfNotNull(mTimerFull, false, elapsedRealtimeUs); 9935 wlactive |= !resetIfNotNull(mTimerPartial, false, elapsedRealtimeUs); 9936 wlactive |= !resetIfNotNull(mTimerWindow, false, elapsedRealtimeUs); 9937 wlactive |= !resetIfNotNull(mTimerDraw, false, elapsedRealtimeUs); 9938 9939 if (!wlactive) { 9940 detachIfNotNull(mTimerFull); 9941 mTimerFull = null; 9942 9943 detachIfNotNull(mTimerPartial); 9944 mTimerPartial = null; 9945 9946 detachIfNotNull(mTimerWindow); 9947 mTimerWindow = null; 9948 9949 detachIfNotNull(mTimerDraw); 9950 mTimerDraw = null; 9951 } 9952 return !wlactive; 9953 } 9954 readFromParcelLocked(TimeBase timeBase, TimeBase screenOffTimeBase, TimeBase screenOffBgTimeBase, Parcel in)9955 void readFromParcelLocked(TimeBase timeBase, TimeBase screenOffTimeBase, 9956 TimeBase screenOffBgTimeBase, Parcel in) { 9957 mTimerPartial = readDualTimerFromParcel(WAKE_TYPE_PARTIAL, 9958 mBsi.mPartialTimers, screenOffTimeBase, screenOffBgTimeBase, in); 9959 mTimerFull = readStopwatchTimerFromParcel(WAKE_TYPE_FULL, 9960 mBsi.mFullTimers, timeBase, in); 9961 mTimerWindow = readStopwatchTimerFromParcel(WAKE_TYPE_WINDOW, 9962 mBsi.mWindowTimers, timeBase, in); 9963 mTimerDraw = readStopwatchTimerFromParcel(WAKE_TYPE_DRAW, 9964 mBsi.mDrawTimers, timeBase, in); 9965 } 9966 writeToParcelLocked(Parcel out, long elapsedRealtimeUs)9967 void writeToParcelLocked(Parcel out, long elapsedRealtimeUs) { 9968 Timer.writeTimerToParcel(out, mTimerPartial, elapsedRealtimeUs); 9969 Timer.writeTimerToParcel(out, mTimerFull, elapsedRealtimeUs); 9970 Timer.writeTimerToParcel(out, mTimerWindow, elapsedRealtimeUs); 9971 Timer.writeTimerToParcel(out, mTimerDraw, elapsedRealtimeUs); 9972 } 9973 9974 @Override 9975 @UnsupportedAppUsage getWakeTime(int type)9976 public Timer getWakeTime(int type) { 9977 switch (type) { 9978 case WAKE_TYPE_FULL: return mTimerFull; 9979 case WAKE_TYPE_PARTIAL: return mTimerPartial; 9980 case WAKE_TYPE_WINDOW: return mTimerWindow; 9981 case WAKE_TYPE_DRAW: return mTimerDraw; 9982 default: throw new IllegalArgumentException("type = " + type); 9983 } 9984 } 9985 detachFromTimeBase()9986 public void detachFromTimeBase() { 9987 detachIfNotNull(mTimerPartial); 9988 detachIfNotNull(mTimerFull); 9989 detachIfNotNull(mTimerWindow); 9990 detachIfNotNull(mTimerDraw); 9991 } 9992 } 9993 9994 public static class Sensor extends BatteryStats.Uid.Sensor { 9995 /** 9996 * BatteryStatsImpl that we are associated with. 9997 */ 9998 protected BatteryStatsImpl mBsi; 9999 10000 /** 10001 * Uid that we are associated with. 10002 */ 10003 protected Uid mUid; 10004 10005 final int mHandle; 10006 DualTimer mTimer; 10007 Sensor(BatteryStatsImpl bsi, Uid uid, int handle)10008 public Sensor(BatteryStatsImpl bsi, Uid uid, int handle) { 10009 mBsi = bsi; 10010 mUid = uid; 10011 mHandle = handle; 10012 } 10013 readTimersFromParcel( TimeBase timeBase, TimeBase bgTimeBase, Parcel in)10014 private DualTimer readTimersFromParcel( 10015 TimeBase timeBase, TimeBase bgTimeBase, Parcel in) { 10016 if (in.readInt() == 0) { 10017 return null; 10018 } 10019 10020 ArrayList<StopwatchTimer> pool = mBsi.mSensorTimers.get(mHandle); 10021 if (pool == null) { 10022 pool = new ArrayList<StopwatchTimer>(); 10023 mBsi.mSensorTimers.put(mHandle, pool); 10024 } 10025 return new DualTimer(mBsi.mClocks, mUid, 0, pool, timeBase, bgTimeBase, in); 10026 } 10027 reset(long elapsedRealtimeUs)10028 boolean reset(long elapsedRealtimeUs) { 10029 if (mTimer.reset(true, elapsedRealtimeUs)) { 10030 mTimer = null; 10031 return true; 10032 } 10033 return false; 10034 } 10035 readFromParcelLocked(TimeBase timeBase, TimeBase bgTimeBase, Parcel in)10036 void readFromParcelLocked(TimeBase timeBase, TimeBase bgTimeBase, Parcel in) { 10037 mTimer = readTimersFromParcel(timeBase, bgTimeBase, in); 10038 } 10039 writeToParcelLocked(Parcel out, long elapsedRealtimeUs)10040 void writeToParcelLocked(Parcel out, long elapsedRealtimeUs) { 10041 Timer.writeTimerToParcel(out, mTimer, elapsedRealtimeUs); 10042 } 10043 10044 @Override 10045 @UnsupportedAppUsage getSensorTime()10046 public Timer getSensorTime() { 10047 return mTimer; 10048 } 10049 10050 @Override getSensorBackgroundTime()10051 public Timer getSensorBackgroundTime() { 10052 if (mTimer == null) { 10053 return null; 10054 } 10055 return mTimer.getSubTimer(); 10056 } 10057 10058 @Override 10059 @UnsupportedAppUsage getHandle()10060 public int getHandle() { 10061 return mHandle; 10062 } 10063 detachFromTimeBase()10064 public void detachFromTimeBase() { 10065 detachIfNotNull(mTimer); 10066 } 10067 } 10068 10069 /** 10070 * The statistics associated with a particular process. 10071 */ 10072 public static class Proc extends BatteryStats.Uid.Proc implements TimeBaseObs { 10073 /** 10074 * BatteryStatsImpl that we are associated with. 10075 */ 10076 protected BatteryStatsImpl mBsi; 10077 10078 /** 10079 * The name of this process. 10080 */ 10081 final String mName; 10082 10083 /** 10084 * Remains true until removed from the stats. 10085 */ 10086 boolean mActive = true; 10087 10088 /** 10089 * Total time (in ms) spent executing in user code. 10090 */ 10091 long mUserTimeMs; 10092 10093 /** 10094 * Total time (in ms) spent executing in kernel code. 10095 */ 10096 long mSystemTimeMs; 10097 10098 /** 10099 * Amount of time (in ms) the process was running in the foreground. 10100 */ 10101 long mForegroundTimeMs; 10102 10103 /** 10104 * Number of times the process has been started. 10105 */ 10106 int mStarts; 10107 10108 /** 10109 * Number of times the process has crashed. 10110 */ 10111 int mNumCrashes; 10112 10113 /** 10114 * Number of times the process has had an ANR. 10115 */ 10116 int mNumAnrs; 10117 10118 ArrayList<ExcessivePower> mExcessivePower; 10119 Proc(BatteryStatsImpl bsi, String name)10120 public Proc(BatteryStatsImpl bsi, String name) { 10121 mBsi = bsi; 10122 mName = name; 10123 mBsi.mOnBatteryTimeBase.add(this); 10124 } 10125 onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)10126 public void onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, 10127 long baseRealtimeUs) { 10128 } 10129 onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)10130 public void onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, 10131 long baseRealtimeUs) { 10132 } 10133 10134 @Override reset(boolean detachIfReset, long elapsedRealtimeUs)10135 public boolean reset(boolean detachIfReset, long elapsedRealtimeUs) { 10136 if (detachIfReset) { 10137 this.detach(); 10138 } 10139 return true; 10140 } 10141 10142 @Override detach()10143 public void detach() { 10144 mActive = false; 10145 mBsi.mOnBatteryTimeBase.remove(this); 10146 } 10147 countExcessivePowers()10148 public int countExcessivePowers() { 10149 return mExcessivePower != null ? mExcessivePower.size() : 0; 10150 } 10151 getExcessivePower(int i)10152 public ExcessivePower getExcessivePower(int i) { 10153 if (mExcessivePower != null) { 10154 return mExcessivePower.get(i); 10155 } 10156 return null; 10157 } 10158 addExcessiveCpu(long overTimeMs, long usedTimeMs)10159 public void addExcessiveCpu(long overTimeMs, long usedTimeMs) { 10160 if (mExcessivePower == null) { 10161 mExcessivePower = new ArrayList<ExcessivePower>(); 10162 } 10163 ExcessivePower ew = new ExcessivePower(); 10164 ew.type = ExcessivePower.TYPE_CPU; 10165 ew.overTime = overTimeMs; 10166 ew.usedTime = usedTimeMs; 10167 mExcessivePower.add(ew); 10168 } 10169 writeExcessivePowerToParcelLocked(Parcel out)10170 void writeExcessivePowerToParcelLocked(Parcel out) { 10171 if (mExcessivePower == null) { 10172 out.writeInt(0); 10173 return; 10174 } 10175 10176 final int N = mExcessivePower.size(); 10177 out.writeInt(N); 10178 for (int i=0; i<N; i++) { 10179 ExcessivePower ew = mExcessivePower.get(i); 10180 out.writeInt(ew.type); 10181 out.writeLong(ew.overTime); 10182 out.writeLong(ew.usedTime); 10183 } 10184 } 10185 readExcessivePowerFromParcelLocked(Parcel in)10186 void readExcessivePowerFromParcelLocked(Parcel in) { 10187 final int N = in.readInt(); 10188 if (N == 0) { 10189 mExcessivePower = null; 10190 return; 10191 } 10192 10193 if (N > 10000) { 10194 throw new ParcelFormatException( 10195 "File corrupt: too many excessive power entries " + N); 10196 } 10197 10198 mExcessivePower = new ArrayList<>(); 10199 for (int i=0; i<N; i++) { 10200 ExcessivePower ew = new ExcessivePower(); 10201 ew.type = in.readInt(); 10202 ew.overTime = in.readLong(); 10203 ew.usedTime = in.readLong(); 10204 mExcessivePower.add(ew); 10205 } 10206 } 10207 writeToParcelLocked(Parcel out)10208 void writeToParcelLocked(Parcel out) { 10209 out.writeLong(mUserTimeMs); 10210 out.writeLong(mSystemTimeMs); 10211 out.writeLong(mForegroundTimeMs); 10212 out.writeInt(mStarts); 10213 out.writeInt(mNumCrashes); 10214 out.writeInt(mNumAnrs); 10215 writeExcessivePowerToParcelLocked(out); 10216 } 10217 readFromParcelLocked(Parcel in)10218 void readFromParcelLocked(Parcel in) { 10219 mUserTimeMs = in.readLong(); 10220 mSystemTimeMs = in.readLong(); 10221 mForegroundTimeMs = in.readLong(); 10222 mStarts = in.readInt(); 10223 mNumCrashes = in.readInt(); 10224 mNumAnrs = in.readInt(); 10225 readExcessivePowerFromParcelLocked(in); 10226 } 10227 10228 @UnsupportedAppUsage addCpuTimeLocked(int utimeMs, int stimeMs)10229 public void addCpuTimeLocked(int utimeMs, int stimeMs) { 10230 addCpuTimeLocked(utimeMs, stimeMs, mBsi.mOnBatteryTimeBase.isRunning()); 10231 } 10232 addCpuTimeLocked(int utimeMs, int stimeMs, boolean isRunning)10233 public void addCpuTimeLocked(int utimeMs, int stimeMs, boolean isRunning) { 10234 if (isRunning) { 10235 mUserTimeMs += utimeMs; 10236 mSystemTimeMs += stimeMs; 10237 } 10238 } 10239 10240 @UnsupportedAppUsage addForegroundTimeLocked(long ttimeMs)10241 public void addForegroundTimeLocked(long ttimeMs) { 10242 mForegroundTimeMs += ttimeMs; 10243 } 10244 10245 @UnsupportedAppUsage incStartsLocked()10246 public void incStartsLocked() { 10247 mStarts++; 10248 } 10249 incNumCrashesLocked()10250 public void incNumCrashesLocked() { 10251 mNumCrashes++; 10252 } 10253 incNumAnrsLocked()10254 public void incNumAnrsLocked() { 10255 mNumAnrs++; 10256 } 10257 10258 @Override isActive()10259 public boolean isActive() { 10260 return mActive; 10261 } 10262 10263 @Override 10264 @UnsupportedAppUsage getUserTime(int which)10265 public long getUserTime(int which) { 10266 return mUserTimeMs; 10267 } 10268 10269 @Override 10270 @UnsupportedAppUsage getSystemTime(int which)10271 public long getSystemTime(int which) { 10272 return mSystemTimeMs; 10273 } 10274 10275 @Override 10276 @UnsupportedAppUsage getForegroundTime(int which)10277 public long getForegroundTime(int which) { 10278 return mForegroundTimeMs; 10279 } 10280 10281 @Override 10282 @UnsupportedAppUsage getStarts(int which)10283 public int getStarts(int which) { 10284 return mStarts; 10285 } 10286 10287 @Override getNumCrashes(int which)10288 public int getNumCrashes(int which) { 10289 return mNumCrashes; 10290 } 10291 10292 @Override getNumAnrs(int which)10293 public int getNumAnrs(int which) { 10294 return mNumAnrs; 10295 } 10296 } 10297 10298 /** 10299 * The statistics associated with a particular package. 10300 */ 10301 public static class Pkg extends BatteryStats.Uid.Pkg implements TimeBaseObs { 10302 /** 10303 * BatteryStatsImpl that we are associated with. 10304 */ 10305 protected BatteryStatsImpl mBsi; 10306 10307 /** 10308 * Number of times wakeup alarms have occurred for this app. 10309 * On screen-off timebase starting in report v25. 10310 */ 10311 ArrayMap<String, Counter> mWakeupAlarms = new ArrayMap<>(); 10312 10313 /** 10314 * The statics we have collected for this package's services. 10315 */ 10316 final ArrayMap<String, Serv> mServiceStats = new ArrayMap<>(); 10317 Pkg(BatteryStatsImpl bsi)10318 public Pkg(BatteryStatsImpl bsi) { 10319 mBsi = bsi; 10320 mBsi.mOnBatteryScreenOffTimeBase.add(this); 10321 } 10322 onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)10323 public void onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, 10324 long baseRealtimeUs) { 10325 } 10326 onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)10327 public void onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, 10328 long baseRealtimeUs) { 10329 } 10330 10331 @Override reset(boolean detachIfReset, long elapsedRealtimeUs)10332 public boolean reset(boolean detachIfReset, long elapsedRealtimeUs) { 10333 if (detachIfReset) { 10334 this.detach(); 10335 } 10336 return true; 10337 } 10338 10339 @Override detach()10340 public void detach() { 10341 mBsi.mOnBatteryScreenOffTimeBase.remove(this); 10342 for (int j = mWakeupAlarms.size() - 1; j >= 0; j--) { 10343 detachIfNotNull(mWakeupAlarms.valueAt(j)); 10344 } 10345 for (int j = mServiceStats.size() - 1; j >= 0; j--) { 10346 detachIfNotNull(mServiceStats.valueAt(j)); 10347 } 10348 } 10349 readFromParcelLocked(Parcel in)10350 void readFromParcelLocked(Parcel in) { 10351 int numWA = in.readInt(); 10352 mWakeupAlarms.clear(); 10353 for (int i=0; i<numWA; i++) { 10354 String tag = in.readString(); 10355 mWakeupAlarms.put(tag, new Counter(mBsi.mOnBatteryScreenOffTimeBase, in)); 10356 } 10357 10358 int numServs = in.readInt(); 10359 mServiceStats.clear(); 10360 for (int m = 0; m < numServs; m++) { 10361 String serviceName = in.readString(); 10362 Uid.Pkg.Serv serv = new Serv(mBsi); 10363 mServiceStats.put(serviceName, serv); 10364 10365 serv.readFromParcelLocked(in); 10366 } 10367 } 10368 writeToParcelLocked(Parcel out)10369 void writeToParcelLocked(Parcel out) { 10370 int numWA = mWakeupAlarms.size(); 10371 out.writeInt(numWA); 10372 for (int i=0; i<numWA; i++) { 10373 out.writeString(mWakeupAlarms.keyAt(i)); 10374 mWakeupAlarms.valueAt(i).writeToParcel(out); 10375 } 10376 10377 final int NS = mServiceStats.size(); 10378 out.writeInt(NS); 10379 for (int i=0; i<NS; i++) { 10380 out.writeString(mServiceStats.keyAt(i)); 10381 Uid.Pkg.Serv serv = mServiceStats.valueAt(i); 10382 serv.writeToParcelLocked(out); 10383 } 10384 } 10385 10386 @Override getWakeupAlarmStats()10387 public ArrayMap<String, ? extends BatteryStats.Counter> getWakeupAlarmStats() { 10388 return mWakeupAlarms; 10389 } 10390 noteWakeupAlarmLocked(String tag)10391 public void noteWakeupAlarmLocked(String tag) { 10392 Counter c = mWakeupAlarms.get(tag); 10393 if (c == null) { 10394 c = new Counter(mBsi.mOnBatteryScreenOffTimeBase); 10395 mWakeupAlarms.put(tag, c); 10396 } 10397 c.stepAtomic(); 10398 } 10399 10400 @Override getServiceStats()10401 public ArrayMap<String, ? extends BatteryStats.Uid.Pkg.Serv> getServiceStats() { 10402 return mServiceStats; 10403 } 10404 10405 /** 10406 * The statistics associated with a particular service. 10407 */ 10408 public static class Serv extends BatteryStats.Uid.Pkg.Serv implements TimeBaseObs { 10409 /** 10410 * BatteryStatsImpl that we are associated with. 10411 */ 10412 protected BatteryStatsImpl mBsi; 10413 10414 /** 10415 * The android package in which this service resides. 10416 */ 10417 protected Pkg mPkg; 10418 10419 /** 10420 * Total time (ms in battery uptime) the service has been left started. 10421 */ 10422 protected long mStartTimeMs; 10423 10424 /** 10425 * If service has been started and not yet stopped, this is 10426 * when it was started. 10427 */ 10428 protected long mRunningSinceMs; 10429 10430 /** 10431 * True if we are currently running. 10432 */ 10433 protected boolean mRunning; 10434 10435 /** 10436 * Total number of times startService() has been called. 10437 */ 10438 protected int mStarts; 10439 10440 /** 10441 * Total time (ms in battery uptime) the service has been left launched. 10442 */ 10443 protected long mLaunchedTimeMs; 10444 10445 /** 10446 * If service has been launched and not yet exited, this is 10447 * when it was launched (ms in battery uptime). 10448 */ 10449 protected long mLaunchedSinceMs; 10450 10451 /** 10452 * True if we are currently launched. 10453 */ 10454 protected boolean mLaunched; 10455 10456 /** 10457 * Total number times the service has been launched. 10458 */ 10459 protected int mLaunches; 10460 10461 /** 10462 * Construct a Serv. Also adds it to the on-battery time base as a listener. 10463 */ Serv(BatteryStatsImpl bsi)10464 public Serv(BatteryStatsImpl bsi) { 10465 mBsi = bsi; 10466 mBsi.mOnBatteryTimeBase.add(this); 10467 } 10468 onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)10469 public void onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, 10470 long baseRealtimeUs) { 10471 } 10472 onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs)10473 public void onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, 10474 long baseRealtimeUs) { 10475 } 10476 10477 @Override reset(boolean detachIfReset, long elapsedRealtimeUs)10478 public boolean reset(boolean detachIfReset, long elapsedRealtimeUs) { 10479 if (detachIfReset) { 10480 this.detach(); 10481 } 10482 return true; 10483 } 10484 10485 /** 10486 * Remove this Serv as a listener from the time base. 10487 Ms*/ 10488 @Override detach()10489 public void detach() { 10490 mBsi.mOnBatteryTimeBase.remove(this); 10491 } 10492 readFromParcelLocked(Parcel in)10493 public void readFromParcelLocked(Parcel in) { 10494 mStartTimeMs = in.readLong(); 10495 mRunningSinceMs = in.readLong(); 10496 mRunning = in.readInt() != 0; 10497 mStarts = in.readInt(); 10498 mLaunchedTimeMs = in.readLong(); 10499 mLaunchedSinceMs = in.readLong(); 10500 mLaunched = in.readInt() != 0; 10501 mLaunches = in.readInt(); 10502 } 10503 writeToParcelLocked(Parcel out)10504 public void writeToParcelLocked(Parcel out) { 10505 out.writeLong(mStartTimeMs); 10506 out.writeLong(mRunningSinceMs); 10507 out.writeInt(mRunning ? 1 : 0); 10508 out.writeInt(mStarts); 10509 out.writeLong(mLaunchedTimeMs); 10510 out.writeLong(mLaunchedSinceMs); 10511 out.writeInt(mLaunched ? 1 : 0); 10512 out.writeInt(mLaunches); 10513 } 10514 getLaunchTimeToNowLocked(long batteryUptimeMs)10515 public long getLaunchTimeToNowLocked(long batteryUptimeMs) { 10516 if (!mLaunched) return mLaunchedTimeMs; 10517 return mLaunchedTimeMs + batteryUptimeMs - mLaunchedSinceMs; 10518 } 10519 getStartTimeToNowLocked(long batteryUptimeMs)10520 public long getStartTimeToNowLocked(long batteryUptimeMs) { 10521 if (!mRunning) return mStartTimeMs; 10522 return mStartTimeMs + batteryUptimeMs - mRunningSinceMs; 10523 } 10524 10525 @UnsupportedAppUsage startLaunchedLocked()10526 public void startLaunchedLocked() { 10527 startLaunchedLocked(mBsi.mClocks.uptimeMillis()); 10528 } 10529 startLaunchedLocked(long uptimeMs)10530 public void startLaunchedLocked(long uptimeMs) { 10531 if (!mLaunched) { 10532 mLaunches++; 10533 mLaunchedSinceMs = mBsi.getBatteryUptimeLocked(uptimeMs) / 1000; 10534 mLaunched = true; 10535 } 10536 } 10537 10538 @UnsupportedAppUsage stopLaunchedLocked()10539 public void stopLaunchedLocked() { 10540 stopLaunchedLocked(mBsi.mClocks.uptimeMillis()); 10541 } 10542 stopLaunchedLocked(long uptimeMs)10543 public void stopLaunchedLocked(long uptimeMs) { 10544 if (mLaunched) { 10545 long timeMs = mBsi.getBatteryUptimeLocked(uptimeMs) / 1000 10546 - mLaunchedSinceMs; 10547 if (timeMs > 0) { 10548 mLaunchedTimeMs += timeMs; 10549 } else { 10550 mLaunches--; 10551 } 10552 mLaunched = false; 10553 } 10554 } 10555 10556 @UnsupportedAppUsage startRunningLocked()10557 public void startRunningLocked() { 10558 startRunningLocked(mBsi.mClocks.uptimeMillis()); 10559 } 10560 startRunningLocked(long uptimeMs)10561 public void startRunningLocked(long uptimeMs) { 10562 if (!mRunning) { 10563 mStarts++; 10564 mRunningSinceMs = mBsi.getBatteryUptimeLocked(uptimeMs) / 1000; 10565 mRunning = true; 10566 } 10567 } 10568 10569 @UnsupportedAppUsage stopRunningLocked()10570 public void stopRunningLocked() { 10571 stopRunningLocked(mBsi.mClocks.uptimeMillis()); 10572 } 10573 stopRunningLocked(long uptimeMs)10574 public void stopRunningLocked(long uptimeMs) { 10575 if (mRunning) { 10576 long timeMs = mBsi.getBatteryUptimeLocked(uptimeMs) / 1000 10577 - mRunningSinceMs; 10578 if (timeMs > 0) { 10579 mStartTimeMs += timeMs; 10580 } else { 10581 mStarts--; 10582 } 10583 mRunning = false; 10584 } 10585 } 10586 10587 @UnsupportedAppUsage getBatteryStats()10588 public BatteryStatsImpl getBatteryStats() { 10589 return mBsi; 10590 } 10591 10592 @Override getLaunches(int which)10593 public int getLaunches(int which) { 10594 return mLaunches; 10595 } 10596 10597 @Override getStartTime(long now, int which)10598 public long getStartTime(long now, int which) { 10599 return getStartTimeToNowLocked(now); 10600 } 10601 10602 @Override getStarts(int which)10603 public int getStarts(int which) { 10604 return mStarts; 10605 } 10606 } 10607 newServiceStatsLocked()10608 final Serv newServiceStatsLocked() { 10609 return new Serv(mBsi); 10610 } 10611 } 10612 10613 /** 10614 * Retrieve the statistics object for a particular process, creating 10615 * if needed. 10616 */ getProcessStatsLocked(String name)10617 public Proc getProcessStatsLocked(String name) { 10618 Proc ps = mProcessStats.get(name); 10619 if (ps == null) { 10620 ps = new Proc(mBsi, name); 10621 mProcessStats.put(name, ps); 10622 } 10623 10624 return ps; 10625 } 10626 10627 @GuardedBy("mBsi") updateUidProcessStateLocked(int procState)10628 public void updateUidProcessStateLocked(int procState) { 10629 updateUidProcessStateLocked(procState, 10630 mBsi.mClocks.elapsedRealtime(), mBsi.mClocks.uptimeMillis()); 10631 } 10632 updateUidProcessStateLocked(int procState, long elapsedRealtimeMs, long uptimeMs)10633 public void updateUidProcessStateLocked(int procState, 10634 long elapsedRealtimeMs, long uptimeMs) { 10635 int uidRunningState; 10636 // Make special note of Foreground Services 10637 final boolean userAwareService = 10638 (ActivityManager.isForegroundService(procState)); 10639 uidRunningState = BatteryStats.mapToInternalProcessState(procState); 10640 10641 if (mProcessState == uidRunningState && userAwareService == mInForegroundService) { 10642 return; 10643 } 10644 10645 if (mProcessState != uidRunningState) { 10646 if (mProcessState != ActivityManager.PROCESS_STATE_NONEXISTENT) { 10647 mProcessStateTimer[mProcessState].stopRunningLocked(elapsedRealtimeMs); 10648 10649 if (mBsi.trackPerProcStateCpuTimes()) { 10650 if (mBsi.mPendingUids.size() == 0) { 10651 mBsi.mExternalSync.scheduleReadProcStateCpuTimes( 10652 mBsi.mOnBatteryTimeBase.isRunning(), 10653 mBsi.mOnBatteryScreenOffTimeBase.isRunning(), 10654 mBsi.mConstants.PROC_STATE_CPU_TIMES_READ_DELAY_MS); 10655 mBsi.mNumSingleUidCpuTimeReads++; 10656 } else { 10657 mBsi.mNumBatchedSingleUidCpuTimeReads++; 10658 } 10659 if (mBsi.mPendingUids.indexOfKey(mUid) < 0 10660 || ArrayUtils.contains(CRITICAL_PROC_STATES, mProcessState)) { 10661 mBsi.mPendingUids.put(mUid, mProcessState); 10662 } 10663 } else { 10664 mBsi.mPendingUids.clear(); 10665 } 10666 } 10667 mProcessState = uidRunningState; 10668 if (uidRunningState != ActivityManager.PROCESS_STATE_NONEXISTENT) { 10669 if (mProcessStateTimer[uidRunningState] == null) { 10670 makeProcessState(uidRunningState, null); 10671 } 10672 mProcessStateTimer[uidRunningState].startRunningLocked(elapsedRealtimeMs); 10673 } 10674 10675 updateOnBatteryBgTimeBase(uptimeMs * 1000, elapsedRealtimeMs * 1000); 10676 updateOnBatteryScreenOffBgTimeBase(uptimeMs * 1000, elapsedRealtimeMs * 1000); 10677 } 10678 10679 if (userAwareService != mInForegroundService) { 10680 if (userAwareService) { 10681 noteForegroundServiceResumedLocked(elapsedRealtimeMs); 10682 } else { 10683 noteForegroundServicePausedLocked(elapsedRealtimeMs); 10684 } 10685 mInForegroundService = userAwareService; 10686 } 10687 } 10688 10689 /** Whether to consider Uid to be in the background for background timebase purposes. */ isInBackground()10690 public boolean isInBackground() { 10691 // Note that PROCESS_STATE_CACHED and ActivityManager.PROCESS_STATE_NONEXISTENT is 10692 // also considered to be 'background' for our purposes, because it's not foreground. 10693 return mProcessState >= PROCESS_STATE_BACKGROUND; 10694 } 10695 updateOnBatteryBgTimeBase(long uptimeUs, long realtimeUs)10696 public boolean updateOnBatteryBgTimeBase(long uptimeUs, long realtimeUs) { 10697 boolean on = mBsi.mOnBatteryTimeBase.isRunning() && isInBackground(); 10698 return mOnBatteryBackgroundTimeBase.setRunning(on, uptimeUs, realtimeUs); 10699 } 10700 updateOnBatteryScreenOffBgTimeBase(long uptimeUs, long realtimeUs)10701 public boolean updateOnBatteryScreenOffBgTimeBase(long uptimeUs, long realtimeUs) { 10702 boolean on = mBsi.mOnBatteryScreenOffTimeBase.isRunning() && isInBackground(); 10703 return mOnBatteryScreenOffBackgroundTimeBase.setRunning(on, uptimeUs, realtimeUs); 10704 } 10705 getPidStats()10706 public SparseArray<? extends Pid> getPidStats() { 10707 return mPids; 10708 } 10709 getPidStatsLocked(int pid)10710 public Pid getPidStatsLocked(int pid) { 10711 Pid p = mPids.get(pid); 10712 if (p == null) { 10713 p = new Pid(); 10714 mPids.put(pid, p); 10715 } 10716 return p; 10717 } 10718 10719 /** 10720 * Retrieve the statistics object for a particular service, creating 10721 * if needed. 10722 */ getPackageStatsLocked(String name)10723 public Pkg getPackageStatsLocked(String name) { 10724 Pkg ps = mPackageStats.get(name); 10725 if (ps == null) { 10726 ps = new Pkg(mBsi); 10727 mPackageStats.put(name, ps); 10728 } 10729 10730 return ps; 10731 } 10732 10733 /** 10734 * Retrieve the statistics object for a particular service, creating 10735 * if needed. 10736 */ getServiceStatsLocked(String pkg, String serv)10737 public Pkg.Serv getServiceStatsLocked(String pkg, String serv) { 10738 Pkg ps = getPackageStatsLocked(pkg); 10739 Pkg.Serv ss = ps.mServiceStats.get(serv); 10740 if (ss == null) { 10741 ss = ps.newServiceStatsLocked(); 10742 ps.mServiceStats.put(serv, ss); 10743 } 10744 10745 return ss; 10746 } 10747 readSyncSummaryFromParcelLocked(String name, Parcel in)10748 public void readSyncSummaryFromParcelLocked(String name, Parcel in) { 10749 DualTimer timer = mSyncStats.instantiateObject(); 10750 timer.readSummaryFromParcelLocked(in); 10751 mSyncStats.add(name, timer); 10752 } 10753 readJobSummaryFromParcelLocked(String name, Parcel in)10754 public void readJobSummaryFromParcelLocked(String name, Parcel in) { 10755 DualTimer timer = mJobStats.instantiateObject(); 10756 timer.readSummaryFromParcelLocked(in); 10757 mJobStats.add(name, timer); 10758 } 10759 readWakeSummaryFromParcelLocked(String wlName, Parcel in)10760 public void readWakeSummaryFromParcelLocked(String wlName, Parcel in) { 10761 Wakelock wl = new Wakelock(mBsi, this); 10762 mWakelockStats.add(wlName, wl); 10763 if (in.readInt() != 0) { 10764 getWakelockTimerLocked(wl, WAKE_TYPE_FULL).readSummaryFromParcelLocked(in); 10765 } 10766 if (in.readInt() != 0) { 10767 getWakelockTimerLocked(wl, WAKE_TYPE_PARTIAL).readSummaryFromParcelLocked(in); 10768 } 10769 if (in.readInt() != 0) { 10770 getWakelockTimerLocked(wl, WAKE_TYPE_WINDOW).readSummaryFromParcelLocked(in); 10771 } 10772 if (in.readInt() != 0) { 10773 getWakelockTimerLocked(wl, WAKE_TYPE_DRAW).readSummaryFromParcelLocked(in); 10774 } 10775 } 10776 getSensorTimerLocked(int sensor, boolean create)10777 public DualTimer getSensorTimerLocked(int sensor, boolean create) { 10778 Sensor se = mSensorStats.get(sensor); 10779 if (se == null) { 10780 if (!create) { 10781 return null; 10782 } 10783 se = new Sensor(mBsi, this, sensor); 10784 mSensorStats.put(sensor, se); 10785 } 10786 DualTimer t = se.mTimer; 10787 if (t != null) { 10788 return t; 10789 } 10790 ArrayList<StopwatchTimer> timers = mBsi.mSensorTimers.get(sensor); 10791 if (timers == null) { 10792 timers = new ArrayList<StopwatchTimer>(); 10793 mBsi.mSensorTimers.put(sensor, timers); 10794 } 10795 t = new DualTimer(mBsi.mClocks, this, BatteryStats.SENSOR, timers, 10796 mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase); 10797 se.mTimer = t; 10798 return t; 10799 } 10800 noteStartSyncLocked(String name, long elapsedRealtimeMs)10801 public void noteStartSyncLocked(String name, long elapsedRealtimeMs) { 10802 DualTimer t = mSyncStats.startObject(name, elapsedRealtimeMs); 10803 if (t != null) { 10804 t.startRunningLocked(elapsedRealtimeMs); 10805 } 10806 } 10807 noteStopSyncLocked(String name, long elapsedRealtimeMs)10808 public void noteStopSyncLocked(String name, long elapsedRealtimeMs) { 10809 DualTimer t = mSyncStats.stopObject(name, elapsedRealtimeMs); 10810 if (t != null) { 10811 t.stopRunningLocked(elapsedRealtimeMs); 10812 } 10813 } 10814 noteStartJobLocked(String name, long elapsedRealtimeMs)10815 public void noteStartJobLocked(String name, long elapsedRealtimeMs) { 10816 DualTimer t = mJobStats.startObject(name, elapsedRealtimeMs); 10817 if (t != null) { 10818 t.startRunningLocked(elapsedRealtimeMs); 10819 } 10820 } 10821 noteStopJobLocked(String name, long elapsedRealtimeMs, int stopReason)10822 public void noteStopJobLocked(String name, long elapsedRealtimeMs, int stopReason) { 10823 DualTimer t = mJobStats.stopObject(name, elapsedRealtimeMs); 10824 if (t != null) { 10825 t.stopRunningLocked(elapsedRealtimeMs); 10826 } 10827 if (mBsi.mOnBatteryTimeBase.isRunning()) { 10828 SparseIntArray types = mJobCompletions.get(name); 10829 if (types == null) { 10830 types = new SparseIntArray(); 10831 mJobCompletions.put(name, types); 10832 } 10833 int last = types.get(stopReason, 0); 10834 types.put(stopReason, last + 1); 10835 } 10836 } 10837 getWakelockTimerLocked(Wakelock wl, int type)10838 public StopwatchTimer getWakelockTimerLocked(Wakelock wl, int type) { 10839 if (wl == null) { 10840 return null; 10841 } 10842 switch (type) { 10843 case WAKE_TYPE_PARTIAL: { 10844 DualTimer t = wl.mTimerPartial; 10845 if (t == null) { 10846 t = new DualTimer(mBsi.mClocks, this, WAKE_TYPE_PARTIAL, 10847 mBsi.mPartialTimers, mBsi.mOnBatteryScreenOffTimeBase, 10848 mOnBatteryScreenOffBackgroundTimeBase); 10849 wl.mTimerPartial = t; 10850 } 10851 return t; 10852 } 10853 case WAKE_TYPE_FULL: { 10854 StopwatchTimer t = wl.mTimerFull; 10855 if (t == null) { 10856 t = new StopwatchTimer(mBsi.mClocks, this, WAKE_TYPE_FULL, 10857 mBsi.mFullTimers, mBsi.mOnBatteryTimeBase); 10858 wl.mTimerFull = t; 10859 } 10860 return t; 10861 } 10862 case WAKE_TYPE_WINDOW: { 10863 StopwatchTimer t = wl.mTimerWindow; 10864 if (t == null) { 10865 t = new StopwatchTimer(mBsi.mClocks, this, WAKE_TYPE_WINDOW, 10866 mBsi.mWindowTimers, mBsi.mOnBatteryTimeBase); 10867 wl.mTimerWindow = t; 10868 } 10869 return t; 10870 } 10871 case WAKE_TYPE_DRAW: { 10872 StopwatchTimer t = wl.mTimerDraw; 10873 if (t == null) { 10874 t = new StopwatchTimer(mBsi.mClocks, this, WAKE_TYPE_DRAW, 10875 mBsi.mDrawTimers, mBsi.mOnBatteryTimeBase); 10876 wl.mTimerDraw = t; 10877 } 10878 return t; 10879 } 10880 default: 10881 throw new IllegalArgumentException("type=" + type); 10882 } 10883 } 10884 noteStartWakeLocked(int pid, String name, int type, long elapsedRealtimeMs)10885 public void noteStartWakeLocked(int pid, String name, int type, long elapsedRealtimeMs) { 10886 Wakelock wl = mWakelockStats.startObject(name, elapsedRealtimeMs); 10887 if (wl != null) { 10888 getWakelockTimerLocked(wl, type).startRunningLocked(elapsedRealtimeMs); 10889 } 10890 if (type == WAKE_TYPE_PARTIAL) { 10891 createAggregatedPartialWakelockTimerLocked().startRunningLocked(elapsedRealtimeMs); 10892 if (pid >= 0) { 10893 Pid p = getPidStatsLocked(pid); 10894 if (p.mWakeNesting++ == 0) { 10895 p.mWakeStartMs = elapsedRealtimeMs; 10896 } 10897 } 10898 } 10899 } 10900 noteStopWakeLocked(int pid, String name, int type, long elapsedRealtimeMs)10901 public void noteStopWakeLocked(int pid, String name, int type, long elapsedRealtimeMs) { 10902 Wakelock wl = mWakelockStats.stopObject(name, elapsedRealtimeMs); 10903 if (wl != null) { 10904 StopwatchTimer wlt = getWakelockTimerLocked(wl, type); 10905 wlt.stopRunningLocked(elapsedRealtimeMs); 10906 } 10907 if (type == WAKE_TYPE_PARTIAL) { 10908 if (mAggregatedPartialWakelockTimer != null) { 10909 mAggregatedPartialWakelockTimer.stopRunningLocked(elapsedRealtimeMs); 10910 } 10911 if (pid >= 0) { 10912 Pid p = mPids.get(pid); 10913 if (p != null && p.mWakeNesting > 0) { 10914 if (p.mWakeNesting-- == 1) { 10915 p.mWakeSumMs += elapsedRealtimeMs - p.mWakeStartMs; 10916 p.mWakeStartMs = 0; 10917 } 10918 } 10919 } 10920 } 10921 } 10922 reportExcessiveCpuLocked(String proc, long overTimeMs, long usedTimeMs)10923 public void reportExcessiveCpuLocked(String proc, long overTimeMs, long usedTimeMs) { 10924 Proc p = getProcessStatsLocked(proc); 10925 if (p != null) { 10926 p.addExcessiveCpu(overTimeMs, usedTimeMs); 10927 } 10928 } 10929 noteStartSensor(int sensor, long elapsedRealtimeMs)10930 public void noteStartSensor(int sensor, long elapsedRealtimeMs) { 10931 DualTimer t = getSensorTimerLocked(sensor, /* create= */ true); 10932 t.startRunningLocked(elapsedRealtimeMs); 10933 } 10934 noteStopSensor(int sensor, long elapsedRealtimeMs)10935 public void noteStopSensor(int sensor, long elapsedRealtimeMs) { 10936 // Don't create a timer if one doesn't already exist 10937 DualTimer t = getSensorTimerLocked(sensor, false); 10938 if (t != null) { 10939 t.stopRunningLocked(elapsedRealtimeMs); 10940 } 10941 } 10942 noteStartGps(long elapsedRealtimeMs)10943 public void noteStartGps(long elapsedRealtimeMs) { 10944 noteStartSensor(Sensor.GPS, elapsedRealtimeMs); 10945 } 10946 noteStopGps(long elapsedRealtimeMs)10947 public void noteStopGps(long elapsedRealtimeMs) { 10948 noteStopSensor(Sensor.GPS, elapsedRealtimeMs); 10949 } 10950 getBatteryStats()10951 public BatteryStatsImpl getBatteryStats() { 10952 return mBsi; 10953 } 10954 } 10955 getCpuFreqs()10956 public long[] getCpuFreqs() { 10957 return mCpuFreqs; 10958 } 10959 BatteryStatsImpl(File systemDir, Handler handler, PlatformIdleStateCallback cb, MeasuredEnergyRetriever energyStatsCb, UserInfoProvider userInfoProvider)10960 public BatteryStatsImpl(File systemDir, Handler handler, PlatformIdleStateCallback cb, 10961 MeasuredEnergyRetriever energyStatsCb, UserInfoProvider userInfoProvider) { 10962 this(new SystemClocks(), systemDir, handler, cb, energyStatsCb, userInfoProvider); 10963 } 10964 BatteryStatsImpl(Clocks clocks, File systemDir, Handler handler, PlatformIdleStateCallback cb, MeasuredEnergyRetriever energyStatsCb, UserInfoProvider userInfoProvider)10965 private BatteryStatsImpl(Clocks clocks, File systemDir, Handler handler, 10966 PlatformIdleStateCallback cb, MeasuredEnergyRetriever energyStatsCb, 10967 UserInfoProvider userInfoProvider) { 10968 init(clocks); 10969 10970 if (systemDir == null) { 10971 mStatsFile = null; 10972 mBatteryStatsHistory = new BatteryStatsHistory(mHistoryBuffer); 10973 } else { 10974 mStatsFile = new AtomicFile(new File(systemDir, "batterystats.bin")); 10975 mBatteryStatsHistory = new BatteryStatsHistory(this, systemDir, mHistoryBuffer); 10976 } 10977 mCheckinFile = new AtomicFile(new File(systemDir, "batterystats-checkin.bin")); 10978 mDailyFile = new AtomicFile(new File(systemDir, "batterystats-daily.xml")); 10979 mHandler = new MyHandler(handler.getLooper()); 10980 mConstants = new Constants(mHandler); 10981 mStartCount++; 10982 initTimersAndCounters(); 10983 mOnBattery = mOnBatteryInternal = false; 10984 long uptimeUs = mClocks.uptimeMillis() * 1000; 10985 long realtimeUs = mClocks.elapsedRealtime() * 1000; 10986 initTimes(uptimeUs, realtimeUs); 10987 mStartPlatformVersion = mEndPlatformVersion = Build.ID; 10988 initDischarge(realtimeUs); 10989 clearHistoryLocked(); 10990 updateDailyDeadlineLocked(); 10991 mPlatformIdleStateCallback = cb; 10992 mMeasuredEnergyRetriever = energyStatsCb; 10993 mUserInfoProvider = userInfoProvider; 10994 10995 // Notify statsd that the system is initially not in doze. 10996 mDeviceIdleMode = DEVICE_IDLE_MODE_OFF; 10997 FrameworkStatsLog.write(FrameworkStatsLog.DEVICE_IDLE_MODE_STATE_CHANGED, mDeviceIdleMode); 10998 } 10999 11000 @VisibleForTesting initTimersAndCounters()11001 protected void initTimersAndCounters() { 11002 mScreenOnTimer = new StopwatchTimer(mClocks, null, -1, null, mOnBatteryTimeBase); 11003 mScreenDozeTimer = new StopwatchTimer(mClocks, null, -1, null, mOnBatteryTimeBase); 11004 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 11005 mScreenBrightnessTimer[i] = new StopwatchTimer(mClocks, null, -100-i, null, 11006 mOnBatteryTimeBase); 11007 } 11008 11009 mPerDisplayBatteryStats = new DisplayBatteryStats[1]; 11010 mPerDisplayBatteryStats[0] = new DisplayBatteryStats(mClocks, mOnBatteryTimeBase); 11011 11012 mInteractiveTimer = new StopwatchTimer(mClocks, null, -10, null, mOnBatteryTimeBase); 11013 mPowerSaveModeEnabledTimer = new StopwatchTimer(mClocks, null, -2, null, 11014 mOnBatteryTimeBase); 11015 mDeviceIdleModeLightTimer = new StopwatchTimer(mClocks, null, -11, null, 11016 mOnBatteryTimeBase); 11017 mDeviceIdleModeFullTimer = new StopwatchTimer(mClocks, null, -14, null, mOnBatteryTimeBase); 11018 mDeviceLightIdlingTimer = new StopwatchTimer(mClocks, null, -15, null, mOnBatteryTimeBase); 11019 mDeviceIdlingTimer = new StopwatchTimer(mClocks, null, -12, null, mOnBatteryTimeBase); 11020 mPhoneOnTimer = new StopwatchTimer(mClocks, null, -3, null, mOnBatteryTimeBase); 11021 for (int i = 0; i < CellSignalStrength.getNumSignalStrengthLevels(); i++) { 11022 mPhoneSignalStrengthsTimer[i] = new StopwatchTimer(mClocks, null, -200-i, null, 11023 mOnBatteryTimeBase); 11024 } 11025 mPhoneSignalScanningTimer = new StopwatchTimer(mClocks, null, -200+1, null, 11026 mOnBatteryTimeBase); 11027 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 11028 mPhoneDataConnectionsTimer[i] = new StopwatchTimer(mClocks, null, -300-i, null, 11029 mOnBatteryTimeBase); 11030 } 11031 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 11032 mNetworkByteActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase); 11033 mNetworkPacketActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase); 11034 } 11035 mWifiActivity = new ControllerActivityCounterImpl(mOnBatteryTimeBase, NUM_WIFI_TX_LEVELS); 11036 mBluetoothActivity = new ControllerActivityCounterImpl(mOnBatteryTimeBase, 11037 NUM_BT_TX_LEVELS); 11038 mModemActivity = new ControllerActivityCounterImpl(mOnBatteryTimeBase, 11039 ModemActivityInfo.getNumTxPowerLevels()); 11040 mMobileRadioActiveTimer = new StopwatchTimer(mClocks, null, -400, null, mOnBatteryTimeBase); 11041 mMobileRadioActivePerAppTimer = new StopwatchTimer(mClocks, null, -401, null, 11042 mOnBatteryTimeBase); 11043 mMobileRadioActiveAdjustedTime = new LongSamplingCounter(mOnBatteryTimeBase); 11044 mMobileRadioActiveUnknownTime = new LongSamplingCounter(mOnBatteryTimeBase); 11045 mMobileRadioActiveUnknownCount = new LongSamplingCounter(mOnBatteryTimeBase); 11046 mWifiMulticastWakelockTimer = new StopwatchTimer(mClocks, null, 11047 WIFI_AGGREGATE_MULTICAST_ENABLED, null, mOnBatteryTimeBase); 11048 mWifiOnTimer = new StopwatchTimer(mClocks, null, -4, null, mOnBatteryTimeBase); 11049 mGlobalWifiRunningTimer = new StopwatchTimer(mClocks, null, -5, null, mOnBatteryTimeBase); 11050 for (int i=0; i<NUM_WIFI_STATES; i++) { 11051 mWifiStateTimer[i] = new StopwatchTimer(mClocks, null, -600-i, null, 11052 mOnBatteryTimeBase); 11053 } 11054 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) { 11055 mWifiSupplStateTimer[i] = new StopwatchTimer(mClocks, null, -700-i, null, 11056 mOnBatteryTimeBase); 11057 } 11058 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { 11059 mWifiSignalStrengthsTimer[i] = new StopwatchTimer(mClocks, null, -800-i, null, 11060 mOnBatteryTimeBase); 11061 } 11062 mWifiActiveTimer = new StopwatchTimer(mClocks, null, -900, null, mOnBatteryTimeBase); 11063 for (int i=0; i< mGpsSignalQualityTimer.length; i++) { 11064 mGpsSignalQualityTimer[i] = new StopwatchTimer(mClocks, null, -1000-i, null, 11065 mOnBatteryTimeBase); 11066 } 11067 mAudioOnTimer = new StopwatchTimer(mClocks, null, -7, null, mOnBatteryTimeBase); 11068 mVideoOnTimer = new StopwatchTimer(mClocks, null, -8, null, mOnBatteryTimeBase); 11069 mFlashlightOnTimer = new StopwatchTimer(mClocks, null, -9, null, mOnBatteryTimeBase); 11070 mCameraOnTimer = new StopwatchTimer(mClocks, null, -13, null, mOnBatteryTimeBase); 11071 mBluetoothScanTimer = new StopwatchTimer(mClocks, null, -14, null, mOnBatteryTimeBase); 11072 mDischargeScreenOffCounter = new LongSamplingCounter(mOnBatteryScreenOffTimeBase); 11073 mDischargeScreenDozeCounter = new LongSamplingCounter(mOnBatteryTimeBase); 11074 mDischargeLightDozeCounter = new LongSamplingCounter(mOnBatteryTimeBase); 11075 mDischargeDeepDozeCounter = new LongSamplingCounter(mOnBatteryTimeBase); 11076 mDischargeCounter = new LongSamplingCounter(mOnBatteryTimeBase); 11077 mDischargeStartLevel = 0; 11078 mDischargeUnplugLevel = 0; 11079 mDischargePlugLevel = -1; 11080 mDischargeCurrentLevel = 0; 11081 mCurrentBatteryLevel = 0; 11082 } 11083 11084 @UnsupportedAppUsage BatteryStatsImpl(Parcel p)11085 public BatteryStatsImpl(Parcel p) { 11086 this(new SystemClocks(), p); 11087 } 11088 BatteryStatsImpl(Clocks clocks, Parcel p)11089 public BatteryStatsImpl(Clocks clocks, Parcel p) { 11090 init(clocks); 11091 mStatsFile = null; 11092 mCheckinFile = null; 11093 mDailyFile = null; 11094 mHandler = null; 11095 mExternalSync = null; 11096 mConstants = new Constants(mHandler); 11097 clearHistoryLocked(); 11098 mBatteryStatsHistory = new BatteryStatsHistory(mHistoryBuffer); 11099 readFromParcel(p); 11100 mPlatformIdleStateCallback = null; 11101 mMeasuredEnergyRetriever = null; 11102 } 11103 setPowerProfileLocked(PowerProfile profile)11104 public void setPowerProfileLocked(PowerProfile profile) { 11105 mPowerProfile = profile; 11106 11107 // We need to initialize the KernelCpuSpeedReaders to read from 11108 // the first cpu of each core. Once we have the PowerProfile, we have access to this 11109 // information. 11110 final int numClusters = mPowerProfile.getNumCpuClusters(); 11111 mKernelCpuSpeedReaders = new KernelCpuSpeedReader[numClusters]; 11112 int firstCpuOfCluster = 0; 11113 for (int i = 0; i < numClusters; i++) { 11114 final int numSpeedSteps = mPowerProfile.getNumSpeedStepsInCpuCluster(i); 11115 mKernelCpuSpeedReaders[i] = new KernelCpuSpeedReader(firstCpuOfCluster, 11116 numSpeedSteps); 11117 firstCpuOfCluster += mPowerProfile.getNumCoresInCpuCluster(i); 11118 } 11119 11120 if (mEstimatedBatteryCapacityMah == -1) { 11121 // Initialize the estimated battery capacity to a known preset one. 11122 mEstimatedBatteryCapacityMah = (int) mPowerProfile.getBatteryCapacity(); 11123 } 11124 11125 setDisplayCountLocked(mPowerProfile.getNumDisplays()); 11126 } 11127 getPowerProfile()11128 PowerProfile getPowerProfile() { 11129 return mPowerProfile; 11130 } 11131 11132 /** 11133 * Starts tracking CPU time-in-state for threads of the system server process, 11134 * keeping a separate account of threads receiving incoming binder calls. 11135 */ startTrackingSystemServerCpuTime()11136 public void startTrackingSystemServerCpuTime() { 11137 mSystemServerCpuThreadReader.startTrackingThreadCpuTime(); 11138 } 11139 getSystemServiceCpuThreadTimes()11140 public SystemServiceCpuThreadTimes getSystemServiceCpuThreadTimes() { 11141 return mSystemServerCpuThreadReader.readAbsolute(); 11142 } 11143 setCallback(BatteryCallback cb)11144 public void setCallback(BatteryCallback cb) { 11145 mCallback = cb; 11146 } 11147 setRadioScanningTimeoutLocked(long timeoutUs)11148 public void setRadioScanningTimeoutLocked(long timeoutUs) { 11149 if (mPhoneSignalScanningTimer != null) { 11150 mPhoneSignalScanningTimer.setTimeout(timeoutUs); 11151 } 11152 } 11153 setExternalStatsSyncLocked(ExternalStatsSync sync)11154 public void setExternalStatsSyncLocked(ExternalStatsSync sync) { 11155 mExternalSync = sync; 11156 } 11157 11158 /** 11159 * Initialize and set multi display timers and states. 11160 */ setDisplayCountLocked(int numDisplays)11161 public void setDisplayCountLocked(int numDisplays) { 11162 mPerDisplayBatteryStats = new DisplayBatteryStats[numDisplays]; 11163 for (int i = 0; i < numDisplays; i++) { 11164 mPerDisplayBatteryStats[i] = new DisplayBatteryStats(mClocks, mOnBatteryTimeBase); 11165 } 11166 } 11167 updateDailyDeadlineLocked()11168 public void updateDailyDeadlineLocked() { 11169 // Get the current time. 11170 long currentTimeMs = mDailyStartTimeMs = mClocks.currentTimeMillis(); 11171 Calendar calDeadline = Calendar.getInstance(); 11172 calDeadline.setTimeInMillis(currentTimeMs); 11173 11174 // Move time up to the next day, ranging from 1am to 3pm. 11175 calDeadline.set(Calendar.DAY_OF_YEAR, calDeadline.get(Calendar.DAY_OF_YEAR) + 1); 11176 calDeadline.set(Calendar.MILLISECOND, 0); 11177 calDeadline.set(Calendar.SECOND, 0); 11178 calDeadline.set(Calendar.MINUTE, 0); 11179 calDeadline.set(Calendar.HOUR_OF_DAY, 1); 11180 mNextMinDailyDeadlineMs = calDeadline.getTimeInMillis(); 11181 calDeadline.set(Calendar.HOUR_OF_DAY, 3); 11182 mNextMaxDailyDeadlineMs = calDeadline.getTimeInMillis(); 11183 } 11184 recordDailyStatsIfNeededLocked(boolean settled, long currentTimeMs)11185 public void recordDailyStatsIfNeededLocked(boolean settled, long currentTimeMs) { 11186 if (currentTimeMs >= mNextMaxDailyDeadlineMs) { 11187 recordDailyStatsLocked(); 11188 } else if (settled && currentTimeMs >= mNextMinDailyDeadlineMs) { 11189 recordDailyStatsLocked(); 11190 } else if (currentTimeMs < (mDailyStartTimeMs - (1000 * 60 * 60 * 24))) { 11191 recordDailyStatsLocked(); 11192 } 11193 } 11194 recordDailyStatsLocked()11195 public void recordDailyStatsLocked() { 11196 DailyItem item = new DailyItem(); 11197 item.mStartTime = mDailyStartTimeMs; 11198 item.mEndTime = mClocks.currentTimeMillis(); 11199 boolean hasData = false; 11200 if (mDailyDischargeStepTracker.mNumStepDurations > 0) { 11201 hasData = true; 11202 item.mDischargeSteps = new LevelStepTracker( 11203 mDailyDischargeStepTracker.mNumStepDurations, 11204 mDailyDischargeStepTracker.mStepDurations); 11205 } 11206 if (mDailyChargeStepTracker.mNumStepDurations > 0) { 11207 hasData = true; 11208 item.mChargeSteps = new LevelStepTracker( 11209 mDailyChargeStepTracker.mNumStepDurations, 11210 mDailyChargeStepTracker.mStepDurations); 11211 } 11212 if (mDailyPackageChanges != null) { 11213 hasData = true; 11214 item.mPackageChanges = mDailyPackageChanges; 11215 mDailyPackageChanges = null; 11216 } 11217 mDailyDischargeStepTracker.init(); 11218 mDailyChargeStepTracker.init(); 11219 updateDailyDeadlineLocked(); 11220 11221 if (hasData) { 11222 final long startTimeMs = SystemClock.uptimeMillis(); 11223 mDailyItems.add(item); 11224 while (mDailyItems.size() > MAX_DAILY_ITEMS) { 11225 mDailyItems.remove(0); 11226 } 11227 final ByteArrayOutputStream memStream = new ByteArrayOutputStream(); 11228 try { 11229 TypedXmlSerializer out = Xml.resolveSerializer(memStream); 11230 writeDailyItemsLocked(out); 11231 final long initialTimeMs = SystemClock.uptimeMillis() - startTimeMs; 11232 BackgroundThread.getHandler().post(new Runnable() { 11233 @Override 11234 public void run() { 11235 synchronized (mCheckinFile) { 11236 final long startTimeMs2 = SystemClock.uptimeMillis(); 11237 FileOutputStream stream = null; 11238 try { 11239 stream = mDailyFile.startWrite(); 11240 memStream.writeTo(stream); 11241 stream.flush(); 11242 mDailyFile.finishWrite(stream); 11243 com.android.internal.logging.EventLogTags.writeCommitSysConfigFile( 11244 "batterystats-daily", 11245 initialTimeMs + SystemClock.uptimeMillis() - startTimeMs2); 11246 } catch (IOException e) { 11247 Slog.w("BatteryStats", 11248 "Error writing battery daily items", e); 11249 mDailyFile.failWrite(stream); 11250 } 11251 } 11252 } 11253 }); 11254 } catch (IOException e) { 11255 } 11256 } 11257 } 11258 writeDailyItemsLocked(TypedXmlSerializer out)11259 private void writeDailyItemsLocked(TypedXmlSerializer out) throws IOException { 11260 StringBuilder sb = new StringBuilder(64); 11261 out.startDocument(null, true); 11262 out.startTag(null, "daily-items"); 11263 for (int i=0; i<mDailyItems.size(); i++) { 11264 final DailyItem dit = mDailyItems.get(i); 11265 out.startTag(null, "item"); 11266 out.attributeLong(null, "start", dit.mStartTime); 11267 out.attributeLong(null, "end", dit.mEndTime); 11268 writeDailyLevelSteps(out, "dis", dit.mDischargeSteps, sb); 11269 writeDailyLevelSteps(out, "chg", dit.mChargeSteps, sb); 11270 if (dit.mPackageChanges != null) { 11271 for (int j=0; j<dit.mPackageChanges.size(); j++) { 11272 PackageChange pc = dit.mPackageChanges.get(j); 11273 if (pc.mUpdate) { 11274 out.startTag(null, "upd"); 11275 out.attribute(null, "pkg", pc.mPackageName); 11276 out.attributeLong(null, "ver", pc.mVersionCode); 11277 out.endTag(null, "upd"); 11278 } else { 11279 out.startTag(null, "rem"); 11280 out.attribute(null, "pkg", pc.mPackageName); 11281 out.endTag(null, "rem"); 11282 } 11283 } 11284 } 11285 out.endTag(null, "item"); 11286 } 11287 out.endTag(null, "daily-items"); 11288 out.endDocument(); 11289 } 11290 writeDailyLevelSteps(TypedXmlSerializer out, String tag, LevelStepTracker steps, StringBuilder tmpBuilder)11291 private void writeDailyLevelSteps(TypedXmlSerializer out, String tag, LevelStepTracker steps, 11292 StringBuilder tmpBuilder) throws IOException { 11293 if (steps != null) { 11294 out.startTag(null, tag); 11295 out.attributeInt(null, "n", steps.mNumStepDurations); 11296 for (int i=0; i<steps.mNumStepDurations; i++) { 11297 out.startTag(null, "s"); 11298 tmpBuilder.setLength(0); 11299 steps.encodeEntryAt(i, tmpBuilder); 11300 out.attribute(null, "v", tmpBuilder.toString()); 11301 out.endTag(null, "s"); 11302 } 11303 out.endTag(null, tag); 11304 } 11305 } 11306 readDailyStatsLocked()11307 public void readDailyStatsLocked() { 11308 Slog.d(TAG, "Reading daily items from " + mDailyFile.getBaseFile()); 11309 mDailyItems.clear(); 11310 FileInputStream stream; 11311 try { 11312 stream = mDailyFile.openRead(); 11313 } catch (FileNotFoundException e) { 11314 return; 11315 } 11316 try { 11317 TypedXmlPullParser parser = Xml.resolvePullParser(stream); 11318 readDailyItemsLocked(parser); 11319 } catch (IOException e) { 11320 } finally { 11321 try { 11322 stream.close(); 11323 } catch (IOException e) { 11324 } 11325 } 11326 } 11327 readDailyItemsLocked(TypedXmlPullParser parser)11328 private void readDailyItemsLocked(TypedXmlPullParser parser) { 11329 try { 11330 int type; 11331 while ((type = parser.next()) != XmlPullParser.START_TAG 11332 && type != XmlPullParser.END_DOCUMENT) { 11333 ; 11334 } 11335 11336 if (type != XmlPullParser.START_TAG) { 11337 throw new IllegalStateException("no start tag found"); 11338 } 11339 11340 int outerDepth = parser.getDepth(); 11341 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 11342 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 11343 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 11344 continue; 11345 } 11346 11347 String tagName = parser.getName(); 11348 if (tagName.equals("item")) { 11349 readDailyItemTagLocked(parser); 11350 } else { 11351 Slog.w(TAG, "Unknown element under <daily-items>: " 11352 + parser.getName()); 11353 XmlUtils.skipCurrentTag(parser); 11354 } 11355 } 11356 11357 } catch (IllegalStateException e) { 11358 Slog.w(TAG, "Failed parsing daily " + e); 11359 } catch (NullPointerException e) { 11360 Slog.w(TAG, "Failed parsing daily " + e); 11361 } catch (NumberFormatException e) { 11362 Slog.w(TAG, "Failed parsing daily " + e); 11363 } catch (XmlPullParserException e) { 11364 Slog.w(TAG, "Failed parsing daily " + e); 11365 } catch (IOException e) { 11366 Slog.w(TAG, "Failed parsing daily " + e); 11367 } catch (IndexOutOfBoundsException e) { 11368 Slog.w(TAG, "Failed parsing daily " + e); 11369 } 11370 } 11371 readDailyItemTagLocked(TypedXmlPullParser parser)11372 void readDailyItemTagLocked(TypedXmlPullParser parser) throws NumberFormatException, 11373 XmlPullParserException, IOException { 11374 DailyItem dit = new DailyItem(); 11375 dit.mStartTime = parser.getAttributeLong(null, "start", 0); 11376 dit.mEndTime = parser.getAttributeLong(null, "end", 0); 11377 int outerDepth = parser.getDepth(); 11378 int type; 11379 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 11380 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 11381 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 11382 continue; 11383 } 11384 11385 String tagName = parser.getName(); 11386 if (tagName.equals("dis")) { 11387 readDailyItemTagDetailsLocked(parser, dit, false, "dis"); 11388 } else if (tagName.equals("chg")) { 11389 readDailyItemTagDetailsLocked(parser, dit, true, "chg"); 11390 } else if (tagName.equals("upd")) { 11391 if (dit.mPackageChanges == null) { 11392 dit.mPackageChanges = new ArrayList<>(); 11393 } 11394 PackageChange pc = new PackageChange(); 11395 pc.mUpdate = true; 11396 pc.mPackageName = parser.getAttributeValue(null, "pkg"); 11397 pc.mVersionCode = parser.getAttributeLong(null, "ver", 0); 11398 dit.mPackageChanges.add(pc); 11399 XmlUtils.skipCurrentTag(parser); 11400 } else if (tagName.equals("rem")) { 11401 if (dit.mPackageChanges == null) { 11402 dit.mPackageChanges = new ArrayList<>(); 11403 } 11404 PackageChange pc = new PackageChange(); 11405 pc.mUpdate = false; 11406 pc.mPackageName = parser.getAttributeValue(null, "pkg"); 11407 dit.mPackageChanges.add(pc); 11408 XmlUtils.skipCurrentTag(parser); 11409 } else { 11410 Slog.w(TAG, "Unknown element under <item>: " 11411 + parser.getName()); 11412 XmlUtils.skipCurrentTag(parser); 11413 } 11414 } 11415 mDailyItems.add(dit); 11416 } 11417 readDailyItemTagDetailsLocked(TypedXmlPullParser parser, DailyItem dit, boolean isCharge, String tag)11418 void readDailyItemTagDetailsLocked(TypedXmlPullParser parser, DailyItem dit, boolean isCharge, 11419 String tag) 11420 throws NumberFormatException, XmlPullParserException, IOException { 11421 final int num = parser.getAttributeInt(null, "n", -1); 11422 if (num == -1) { 11423 Slog.w(TAG, "Missing 'n' attribute at " + parser.getPositionDescription()); 11424 XmlUtils.skipCurrentTag(parser); 11425 return; 11426 } 11427 LevelStepTracker steps = new LevelStepTracker(num); 11428 if (isCharge) { 11429 dit.mChargeSteps = steps; 11430 } else { 11431 dit.mDischargeSteps = steps; 11432 } 11433 int i = 0; 11434 int outerDepth = parser.getDepth(); 11435 int type; 11436 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 11437 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 11438 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 11439 continue; 11440 } 11441 11442 String tagName = parser.getName(); 11443 if ("s".equals(tagName)) { 11444 if (i < num) { 11445 String valueAttr = parser.getAttributeValue(null, "v"); 11446 if (valueAttr != null) { 11447 steps.decodeEntryAt(i, valueAttr); 11448 i++; 11449 } 11450 } 11451 } else { 11452 Slog.w(TAG, "Unknown element under <" + tag + ">: " 11453 + parser.getName()); 11454 XmlUtils.skipCurrentTag(parser); 11455 } 11456 } 11457 steps.mNumStepDurations = i; 11458 } 11459 11460 @Override getDailyItemLocked(int daysAgo)11461 public DailyItem getDailyItemLocked(int daysAgo) { 11462 int index = mDailyItems.size()-1-daysAgo; 11463 return index >= 0 ? mDailyItems.get(index) : null; 11464 } 11465 11466 @Override getCurrentDailyStartTime()11467 public long getCurrentDailyStartTime() { 11468 return mDailyStartTimeMs; 11469 } 11470 11471 @Override getNextMinDailyDeadline()11472 public long getNextMinDailyDeadline() { 11473 return mNextMinDailyDeadlineMs; 11474 } 11475 11476 @Override getNextMaxDailyDeadline()11477 public long getNextMaxDailyDeadline() { 11478 return mNextMaxDailyDeadlineMs; 11479 } 11480 getHistoryTotalSize()11481 public int getHistoryTotalSize() { 11482 return mConstants.MAX_HISTORY_BUFFER * mConstants.MAX_HISTORY_FILES; 11483 } 11484 getHistoryUsedSize()11485 public int getHistoryUsedSize() { 11486 return mBatteryStatsHistory.getHistoryUsedSize(); 11487 } 11488 11489 @Override 11490 @UnsupportedAppUsage startIteratingHistoryLocked()11491 public boolean startIteratingHistoryLocked() { 11492 mReadOverflow = false; 11493 mBatteryStatsHistoryIterator = createBatteryStatsHistoryIterator(); 11494 return true; 11495 } 11496 11497 /** 11498 * Creates an iterator for battery stats history. 11499 */ 11500 @VisibleForTesting createBatteryStatsHistoryIterator()11501 public BatteryStatsHistoryIterator createBatteryStatsHistoryIterator() { 11502 ArrayList<HistoryTag> tags = new ArrayList<>(mHistoryTagPool.size()); 11503 for (Map.Entry<HistoryTag, Integer> entry: mHistoryTagPool.entrySet()) { 11504 final HistoryTag tag = entry.getKey(); 11505 tag.poolIdx = entry.getValue(); 11506 tags.add(tag); 11507 } 11508 11509 return new BatteryStatsHistoryIterator(mBatteryStatsHistory, tags); 11510 } 11511 11512 @Override getHistoryStringPoolSize()11513 public int getHistoryStringPoolSize() { 11514 return mBatteryStatsHistoryIterator.getHistoryStringPoolSize(); 11515 } 11516 11517 @Override getHistoryStringPoolBytes()11518 public int getHistoryStringPoolBytes() { 11519 return mBatteryStatsHistoryIterator.getHistoryStringPoolBytes(); 11520 } 11521 11522 @Override getHistoryTagPoolString(int index)11523 public String getHistoryTagPoolString(int index) { 11524 return mBatteryStatsHistoryIterator.getHistoryTagPoolString(index); 11525 } 11526 11527 @Override getHistoryTagPoolUid(int index)11528 public int getHistoryTagPoolUid(int index) { 11529 return mBatteryStatsHistoryIterator.getHistoryTagPoolUid(index); 11530 } 11531 11532 @Override 11533 @UnsupportedAppUsage getNextHistoryLocked(HistoryItem out)11534 public boolean getNextHistoryLocked(HistoryItem out) { 11535 return mBatteryStatsHistoryIterator.next(out); 11536 } 11537 11538 @Override finishIteratingHistoryLocked()11539 public void finishIteratingHistoryLocked() { 11540 mBatteryStatsHistoryIterator = null; 11541 } 11542 11543 @Override getHistoryBaseTime()11544 public long getHistoryBaseTime() { 11545 return mHistoryBaseTimeMs; 11546 } 11547 11548 @Override getStartCount()11549 public int getStartCount() { 11550 return mStartCount; 11551 } 11552 11553 @UnsupportedAppUsage isOnBattery()11554 public boolean isOnBattery() { 11555 return mOnBattery; 11556 } 11557 isCharging()11558 public boolean isCharging() { 11559 return mCharging; 11560 } 11561 initTimes(long uptimeUs, long realtimeUs)11562 void initTimes(long uptimeUs, long realtimeUs) { 11563 mStartClockTimeMs = mClocks.currentTimeMillis(); 11564 mOnBatteryTimeBase.init(uptimeUs, realtimeUs); 11565 mOnBatteryScreenOffTimeBase.init(uptimeUs, realtimeUs); 11566 mRealtimeUs = 0; 11567 mUptimeUs = 0; 11568 mRealtimeStartUs = realtimeUs; 11569 mUptimeStartUs = uptimeUs; 11570 } 11571 initDischarge(long elapsedRealtimeUs)11572 void initDischarge(long elapsedRealtimeUs) { 11573 mLowDischargeAmountSinceCharge = 0; 11574 mHighDischargeAmountSinceCharge = 0; 11575 mDischargeAmountScreenOn = 0; 11576 mDischargeAmountScreenOnSinceCharge = 0; 11577 mDischargeAmountScreenOff = 0; 11578 mDischargeAmountScreenOffSinceCharge = 0; 11579 mDischargeAmountScreenDoze = 0; 11580 mDischargeAmountScreenDozeSinceCharge = 0; 11581 mDischargeStepTracker.init(); 11582 mChargeStepTracker.init(); 11583 mDischargeScreenOffCounter.reset(false, elapsedRealtimeUs); 11584 mDischargeScreenDozeCounter.reset(false, elapsedRealtimeUs); 11585 mDischargeLightDozeCounter.reset(false, elapsedRealtimeUs); 11586 mDischargeDeepDozeCounter.reset(false, elapsedRealtimeUs); 11587 mDischargeCounter.reset(false, elapsedRealtimeUs); 11588 } 11589 setBatteryResetListener(BatteryResetListener batteryResetListener)11590 public void setBatteryResetListener(BatteryResetListener batteryResetListener) { 11591 mBatteryResetListener = batteryResetListener; 11592 } 11593 resetAllStatsCmdLocked()11594 public void resetAllStatsCmdLocked() { 11595 final long mSecUptime = mClocks.uptimeMillis(); 11596 long uptimeUs = mSecUptime * 1000; 11597 long mSecRealtime = mClocks.elapsedRealtime(); 11598 long realtimeUs = mSecRealtime * 1000; 11599 resetAllStatsLocked(mSecUptime, mSecRealtime, RESET_REASON_ADB_COMMAND); 11600 mDischargeStartLevel = mHistoryCur.batteryLevel; 11601 pullPendingStateUpdatesLocked(); 11602 addHistoryRecordLocked(mSecRealtime, mSecUptime); 11603 mDischargeCurrentLevel = mDischargeUnplugLevel = mDischargePlugLevel 11604 = mCurrentBatteryLevel = mHistoryCur.batteryLevel; 11605 mOnBatteryTimeBase.reset(uptimeUs, realtimeUs); 11606 mOnBatteryScreenOffTimeBase.reset(uptimeUs, realtimeUs); 11607 if ((mHistoryCur.states&HistoryItem.STATE_BATTERY_PLUGGED_FLAG) == 0) { 11608 if (Display.isOnState(mScreenState)) { 11609 mDischargeScreenOnUnplugLevel = mHistoryCur.batteryLevel; 11610 mDischargeScreenDozeUnplugLevel = 0; 11611 mDischargeScreenOffUnplugLevel = 0; 11612 } else if (Display.isDozeState(mScreenState)) { 11613 mDischargeScreenOnUnplugLevel = 0; 11614 mDischargeScreenDozeUnplugLevel = mHistoryCur.batteryLevel; 11615 mDischargeScreenOffUnplugLevel = 0; 11616 } else { 11617 mDischargeScreenOnUnplugLevel = 0; 11618 mDischargeScreenDozeUnplugLevel = 0; 11619 mDischargeScreenOffUnplugLevel = mHistoryCur.batteryLevel; 11620 } 11621 mDischargeAmountScreenOn = 0; 11622 mDischargeAmountScreenOff = 0; 11623 mDischargeAmountScreenDoze = 0; 11624 } 11625 initActiveHistoryEventsLocked(mSecRealtime, mSecUptime); 11626 } 11627 resetAllStatsLocked(long uptimeMillis, long elapsedRealtimeMillis, int resetReason)11628 private void resetAllStatsLocked(long uptimeMillis, long elapsedRealtimeMillis, 11629 int resetReason) { 11630 if (mBatteryResetListener != null) { 11631 mBatteryResetListener.prepareForBatteryStatsReset(resetReason); 11632 } 11633 11634 final long uptimeUs = uptimeMillis * 1000; 11635 final long elapsedRealtimeUs = elapsedRealtimeMillis * 1000; 11636 mStartCount = 0; 11637 initTimes(uptimeUs, elapsedRealtimeUs); 11638 mScreenOnTimer.reset(false, elapsedRealtimeUs); 11639 mScreenDozeTimer.reset(false, elapsedRealtimeUs); 11640 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 11641 mScreenBrightnessTimer[i].reset(false, elapsedRealtimeUs); 11642 } 11643 11644 final int numDisplays = mPerDisplayBatteryStats.length; 11645 for (int i = 0; i < numDisplays; i++) { 11646 mPerDisplayBatteryStats[i].reset(elapsedRealtimeUs); 11647 } 11648 11649 if (mPowerProfile != null) { 11650 mEstimatedBatteryCapacityMah = (int) mPowerProfile.getBatteryCapacity(); 11651 } else { 11652 mEstimatedBatteryCapacityMah = -1; 11653 } 11654 mLastLearnedBatteryCapacityUah = -1; 11655 mMinLearnedBatteryCapacityUah = -1; 11656 mMaxLearnedBatteryCapacityUah = -1; 11657 mInteractiveTimer.reset(false, elapsedRealtimeUs); 11658 mPowerSaveModeEnabledTimer.reset(false, elapsedRealtimeUs); 11659 mLastIdleTimeStartMs = elapsedRealtimeMillis; 11660 mLongestLightIdleTimeMs = 0; 11661 mLongestFullIdleTimeMs = 0; 11662 mDeviceIdleModeLightTimer.reset(false, elapsedRealtimeUs); 11663 mDeviceIdleModeFullTimer.reset(false, elapsedRealtimeUs); 11664 mDeviceLightIdlingTimer.reset(false, elapsedRealtimeUs); 11665 mDeviceIdlingTimer.reset(false, elapsedRealtimeUs); 11666 mPhoneOnTimer.reset(false, elapsedRealtimeUs); 11667 mAudioOnTimer.reset(false, elapsedRealtimeUs); 11668 mVideoOnTimer.reset(false, elapsedRealtimeUs); 11669 mFlashlightOnTimer.reset(false, elapsedRealtimeUs); 11670 mCameraOnTimer.reset(false, elapsedRealtimeUs); 11671 mBluetoothScanTimer.reset(false, elapsedRealtimeUs); 11672 for (int i = 0; i < CellSignalStrength.getNumSignalStrengthLevels(); i++) { 11673 mPhoneSignalStrengthsTimer[i].reset(false, elapsedRealtimeUs); 11674 } 11675 mPhoneSignalScanningTimer.reset(false, elapsedRealtimeUs); 11676 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 11677 mPhoneDataConnectionsTimer[i].reset(false, elapsedRealtimeUs); 11678 } 11679 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 11680 mNetworkByteActivityCounters[i].reset(false, elapsedRealtimeUs); 11681 mNetworkPacketActivityCounters[i].reset(false, elapsedRealtimeUs); 11682 } 11683 mMobileRadioActiveTimer.reset(false, elapsedRealtimeUs); 11684 mMobileRadioActivePerAppTimer.reset(false, elapsedRealtimeUs); 11685 mMobileRadioActiveAdjustedTime.reset(false, elapsedRealtimeUs); 11686 mMobileRadioActiveUnknownTime.reset(false, elapsedRealtimeUs); 11687 mMobileRadioActiveUnknownCount.reset(false, elapsedRealtimeUs); 11688 mWifiOnTimer.reset(false, elapsedRealtimeUs); 11689 mGlobalWifiRunningTimer.reset(false, elapsedRealtimeUs); 11690 for (int i=0; i<NUM_WIFI_STATES; i++) { 11691 mWifiStateTimer[i].reset(false, elapsedRealtimeUs); 11692 } 11693 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) { 11694 mWifiSupplStateTimer[i].reset(false, elapsedRealtimeUs); 11695 } 11696 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { 11697 mWifiSignalStrengthsTimer[i].reset(false, elapsedRealtimeUs); 11698 } 11699 mWifiMulticastWakelockTimer.reset(false, elapsedRealtimeUs); 11700 mWifiActiveTimer.reset(false, elapsedRealtimeUs); 11701 mWifiActivity.reset(false, elapsedRealtimeUs); 11702 for (int i=0; i< mGpsSignalQualityTimer.length; i++) { 11703 mGpsSignalQualityTimer[i].reset(false, elapsedRealtimeUs); 11704 } 11705 mBluetoothActivity.reset(false, elapsedRealtimeUs); 11706 mModemActivity.reset(false, elapsedRealtimeUs); 11707 mNumConnectivityChange = 0; 11708 11709 for (int i=0; i<mUidStats.size(); i++) { 11710 if (mUidStats.valueAt(i).reset(uptimeUs, elapsedRealtimeUs, resetReason)) { 11711 mUidStats.valueAt(i).detachFromTimeBase(); 11712 mUidStats.remove(mUidStats.keyAt(i)); 11713 i--; 11714 } 11715 } 11716 11717 if (mRpmStats.size() > 0) { 11718 for (SamplingTimer timer : mRpmStats.values()) { 11719 mOnBatteryTimeBase.remove(timer); 11720 } 11721 mRpmStats.clear(); 11722 } 11723 if (mScreenOffRpmStats.size() > 0) { 11724 for (SamplingTimer timer : mScreenOffRpmStats.values()) { 11725 mOnBatteryScreenOffTimeBase.remove(timer); 11726 } 11727 mScreenOffRpmStats.clear(); 11728 } 11729 11730 if (mKernelWakelockStats.size() > 0) { 11731 for (SamplingTimer timer : mKernelWakelockStats.values()) { 11732 mOnBatteryScreenOffTimeBase.remove(timer); 11733 } 11734 mKernelWakelockStats.clear(); 11735 } 11736 11737 if (mKernelMemoryStats.size() > 0) { 11738 for (int i = 0; i < mKernelMemoryStats.size(); i++) { 11739 mOnBatteryTimeBase.remove(mKernelMemoryStats.valueAt(i)); 11740 } 11741 mKernelMemoryStats.clear(); 11742 } 11743 11744 if (mWakeupReasonStats.size() > 0) { 11745 for (SamplingTimer timer : mWakeupReasonStats.values()) { 11746 mOnBatteryTimeBase.remove(timer); 11747 } 11748 mWakeupReasonStats.clear(); 11749 } 11750 11751 mTmpRailStats.reset(); 11752 11753 MeasuredEnergyStats.resetIfNotNull(mGlobalMeasuredEnergyStats); 11754 11755 resetIfNotNull(mBinderThreadCpuTimesUs, false, elapsedRealtimeUs); 11756 11757 mLastHistoryStepDetails = null; 11758 mLastStepCpuUserTimeMs = mLastStepCpuSystemTimeMs = 0; 11759 mCurStepCpuUserTimeMs = mCurStepCpuSystemTimeMs = 0; 11760 mLastStepCpuUserTimeMs = mCurStepCpuUserTimeMs = 0; 11761 mLastStepCpuSystemTimeMs = mCurStepCpuSystemTimeMs = 0; 11762 mLastStepStatUserTimeMs = mCurStepStatUserTimeMs = 0; 11763 mLastStepStatSystemTimeMs = mCurStepStatSystemTimeMs = 0; 11764 mLastStepStatIOWaitTimeMs = mCurStepStatIOWaitTimeMs = 0; 11765 mLastStepStatIrqTimeMs = mCurStepStatIrqTimeMs = 0; 11766 mLastStepStatSoftIrqTimeMs = mCurStepStatSoftIrqTimeMs = 0; 11767 mLastStepStatIdleTimeMs = mCurStepStatIdleTimeMs = 0; 11768 11769 mNumAllUidCpuTimeReads = 0; 11770 mNumUidsRemoved = 0; 11771 11772 initDischarge(elapsedRealtimeUs); 11773 11774 clearHistoryLocked(); 11775 if (mBatteryStatsHistory != null) { 11776 mBatteryStatsHistory.resetAllFiles(); 11777 } 11778 11779 // Flush external data, gathering snapshots, but don't process it since it is pre-reset data 11780 mIgnoreNextExternalStats = true; 11781 mExternalSync.scheduleSync("reset", ExternalStatsSync.UPDATE_ALL); 11782 11783 mHandler.sendEmptyMessage(MSG_REPORT_RESET_STATS); 11784 } 11785 initActiveHistoryEventsLocked(long elapsedRealtimeMs, long uptimeMs)11786 private void initActiveHistoryEventsLocked(long elapsedRealtimeMs, long uptimeMs) { 11787 for (int i=0; i<HistoryItem.EVENT_COUNT; i++) { 11788 if (!mRecordAllHistory && i == HistoryItem.EVENT_PROC) { 11789 // Not recording process starts/stops. 11790 continue; 11791 } 11792 HashMap<String, SparseIntArray> active = mActiveEvents.getStateForEvent(i); 11793 if (active == null) { 11794 continue; 11795 } 11796 for (HashMap.Entry<String, SparseIntArray> ent : active.entrySet()) { 11797 SparseIntArray uids = ent.getValue(); 11798 for (int j=0; j<uids.size(); j++) { 11799 addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, i, ent.getKey(), 11800 uids.keyAt(j)); 11801 } 11802 } 11803 } 11804 } 11805 updateDischargeScreenLevelsLocked(int oldState, int newState)11806 void updateDischargeScreenLevelsLocked(int oldState, int newState) { 11807 updateOldDischargeScreenLevelLocked(oldState); 11808 updateNewDischargeScreenLevelLocked(newState); 11809 } 11810 updateOldDischargeScreenLevelLocked(int state)11811 private void updateOldDischargeScreenLevelLocked(int state) { 11812 if (Display.isOnState(state)) { 11813 int diff = mDischargeScreenOnUnplugLevel - mDischargeCurrentLevel; 11814 if (diff > 0) { 11815 mDischargeAmountScreenOn += diff; 11816 mDischargeAmountScreenOnSinceCharge += diff; 11817 } 11818 } else if (Display.isDozeState(state)) { 11819 int diff = mDischargeScreenDozeUnplugLevel - mDischargeCurrentLevel; 11820 if (diff > 0) { 11821 mDischargeAmountScreenDoze += diff; 11822 mDischargeAmountScreenDozeSinceCharge += diff; 11823 } 11824 } else if (Display.isOffState(state)) { 11825 int diff = mDischargeScreenOffUnplugLevel - mDischargeCurrentLevel; 11826 if (diff > 0) { 11827 mDischargeAmountScreenOff += diff; 11828 mDischargeAmountScreenOffSinceCharge += diff; 11829 } 11830 } 11831 } 11832 updateNewDischargeScreenLevelLocked(int state)11833 private void updateNewDischargeScreenLevelLocked(int state) { 11834 if (Display.isOnState(state)) { 11835 mDischargeScreenOnUnplugLevel = mDischargeCurrentLevel; 11836 mDischargeScreenOffUnplugLevel = 0; 11837 mDischargeScreenDozeUnplugLevel = 0; 11838 } else if (Display.isDozeState(state)) { 11839 mDischargeScreenOnUnplugLevel = 0; 11840 mDischargeScreenDozeUnplugLevel = mDischargeCurrentLevel; 11841 mDischargeScreenOffUnplugLevel = 0; 11842 } else if (Display.isOffState(state)) { 11843 mDischargeScreenOnUnplugLevel = 0; 11844 mDischargeScreenDozeUnplugLevel = 0; 11845 mDischargeScreenOffUnplugLevel = mDischargeCurrentLevel; 11846 } 11847 } 11848 pullPendingStateUpdatesLocked()11849 public void pullPendingStateUpdatesLocked() { 11850 if (mOnBatteryInternal) { 11851 updateDischargeScreenLevelsLocked(mScreenState, mScreenState); 11852 } 11853 } 11854 11855 private final Pools.Pool<NetworkStats> mNetworkStatsPool = new Pools.SynchronizedPool<>(6); 11856 11857 private final Object mWifiNetworkLock = new Object(); 11858 11859 @GuardedBy("mWifiNetworkLock") 11860 private String[] mWifiIfaces = EmptyArray.STRING; 11861 11862 @GuardedBy("mWifiNetworkLock") 11863 private NetworkStats mLastWifiNetworkStats = new NetworkStats(0, -1); 11864 11865 private final Object mModemNetworkLock = new Object(); 11866 11867 @GuardedBy("mModemNetworkLock") 11868 private String[] mModemIfaces = EmptyArray.STRING; 11869 11870 @GuardedBy("mModemNetworkLock") 11871 private NetworkStats mLastModemNetworkStats = new NetworkStats(0, -1); 11872 11873 @VisibleForTesting readNetworkStatsLocked(String[] ifaces)11874 protected NetworkStats readNetworkStatsLocked(String[] ifaces) { 11875 try { 11876 if (!ArrayUtils.isEmpty(ifaces)) { 11877 INetworkStatsService statsService = INetworkStatsService.Stub.asInterface( 11878 ServiceManager.getService(Context.NETWORK_STATS_SERVICE)); 11879 if (statsService != null) { 11880 return statsService.getDetailedUidStats(ifaces); 11881 } else { 11882 Slog.e(TAG, "Failed to get networkStatsService "); 11883 } 11884 } 11885 } catch (RemoteException e) { 11886 Slog.e(TAG, "failed to read network stats for ifaces: " + Arrays.toString(ifaces) + e); 11887 } 11888 return null; 11889 } 11890 11891 /** 11892 * Distribute WiFi energy info and network traffic to apps. 11893 * @param info The energy information from the WiFi controller. 11894 */ updateWifiState(@ullable final WifiActivityEnergyInfo info, final long consumedChargeUC, long elapsedRealtimeMs, long uptimeMs)11895 public void updateWifiState(@Nullable final WifiActivityEnergyInfo info, 11896 final long consumedChargeUC, long elapsedRealtimeMs, long uptimeMs) { 11897 if (DEBUG_ENERGY) { 11898 Slog.d(TAG, "Updating wifi stats: " + Arrays.toString(mWifiIfaces)); 11899 } 11900 11901 // Grab a separate lock to acquire the network stats, which may do I/O. 11902 NetworkStats delta = null; 11903 synchronized (mWifiNetworkLock) { 11904 final NetworkStats latestStats = readNetworkStatsLocked(mWifiIfaces); 11905 if (latestStats != null) { 11906 delta = NetworkStats.subtract(latestStats, mLastWifiNetworkStats, null, null, 11907 mNetworkStatsPool.acquire()); 11908 mNetworkStatsPool.release(mLastWifiNetworkStats); 11909 mLastWifiNetworkStats = latestStats; 11910 } 11911 } 11912 11913 synchronized (this) { 11914 if (!mOnBatteryInternal || mIgnoreNextExternalStats) { 11915 if (delta != null) { 11916 mNetworkStatsPool.release(delta); 11917 } 11918 if (mIgnoreNextExternalStats) { 11919 // TODO: Strictly speaking, we should re-mark all 5 timers for each uid (and the 11920 // global one) here like we do for display. But I'm not sure it's worth the 11921 // complicated code for a codepath that shouldn't ever actually happen in real 11922 // life. 11923 } 11924 return; 11925 } 11926 11927 final SparseDoubleArray uidEstimatedConsumptionMah = 11928 (mGlobalMeasuredEnergyStats != null 11929 && mWifiPowerCalculator != null && consumedChargeUC > 0) ? 11930 new SparseDoubleArray() : null; 11931 double totalEstimatedConsumptionMah = 0; 11932 11933 SparseLongArray rxPackets = new SparseLongArray(); 11934 SparseLongArray txPackets = new SparseLongArray(); 11935 long totalTxPackets = 0; 11936 long totalRxPackets = 0; 11937 if (delta != null) { 11938 NetworkStats.Entry entry = new NetworkStats.Entry(); 11939 final int size = delta.size(); 11940 for (int i = 0; i < size; i++) { 11941 entry = delta.getValues(i, entry); 11942 11943 if (DEBUG_ENERGY) { 11944 Slog.d(TAG, "Wifi uid " + entry.uid + ": delta rx=" + entry.rxBytes 11945 + " tx=" + entry.txBytes + " rxPackets=" + entry.rxPackets 11946 + " txPackets=" + entry.txPackets); 11947 } 11948 11949 if (entry.rxBytes == 0 && entry.txBytes == 0) { 11950 // Skip the lookup below since there is no work to do. 11951 continue; 11952 } 11953 11954 final Uid u = getUidStatsLocked(mapUid(entry.uid), elapsedRealtimeMs, uptimeMs); 11955 if (entry.rxBytes != 0) { 11956 u.noteNetworkActivityLocked(NETWORK_WIFI_RX_DATA, entry.rxBytes, 11957 entry.rxPackets); 11958 if (entry.set == NetworkStats.SET_DEFAULT) { // Background transfers 11959 u.noteNetworkActivityLocked(NETWORK_WIFI_BG_RX_DATA, entry.rxBytes, 11960 entry.rxPackets); 11961 } 11962 mNetworkByteActivityCounters[NETWORK_WIFI_RX_DATA].addCountLocked( 11963 entry.rxBytes); 11964 mNetworkPacketActivityCounters[NETWORK_WIFI_RX_DATA].addCountLocked( 11965 entry.rxPackets); 11966 11967 // TODO(b/182845426): What if u was a mapped isolated uid? Shouldn't we sum? 11968 rxPackets.put(u.getUid(), entry.rxPackets); 11969 11970 // Sum the total number of packets so that the Rx Power can 11971 // be evenly distributed amongst the apps. 11972 totalRxPackets += entry.rxPackets; 11973 } 11974 11975 if (entry.txBytes != 0) { 11976 u.noteNetworkActivityLocked(NETWORK_WIFI_TX_DATA, entry.txBytes, 11977 entry.txPackets); 11978 if (entry.set == NetworkStats.SET_DEFAULT) { // Background transfers 11979 u.noteNetworkActivityLocked(NETWORK_WIFI_BG_TX_DATA, entry.txBytes, 11980 entry.txPackets); 11981 } 11982 mNetworkByteActivityCounters[NETWORK_WIFI_TX_DATA].addCountLocked( 11983 entry.txBytes); 11984 mNetworkPacketActivityCounters[NETWORK_WIFI_TX_DATA].addCountLocked( 11985 entry.txPackets); 11986 11987 // TODO(b/182845426): What if u was a mapped isolated uid? Shouldn't we sum? 11988 txPackets.put(u.getUid(), entry.txPackets); 11989 11990 // Sum the total number of packets so that the Tx Power can 11991 // be evenly distributed amongst the apps. 11992 totalTxPackets += entry.txPackets; 11993 } 11994 11995 // Calculate consumed energy for this uid. Only do so if WifiReporting isn't 11996 // enabled (if it is, we'll do it later instead using info). 11997 if (uidEstimatedConsumptionMah != null && info == null && !mHasWifiReporting) { 11998 final long uidRunningMs = u.mWifiRunningTimer 11999 .getTimeSinceMarkLocked(elapsedRealtimeMs * 1000) / 1000; 12000 if (uidRunningMs > 0) u.mWifiRunningTimer.setMark(elapsedRealtimeMs); 12001 12002 final long uidScanMs = u.mWifiScanTimer 12003 .getTimeSinceMarkLocked(elapsedRealtimeMs * 1000) / 1000; 12004 if (uidScanMs > 0) u.mWifiScanTimer.setMark(elapsedRealtimeMs); 12005 12006 long uidBatchScanMs = 0; 12007 for (int bn = 0; bn < BatteryStats.Uid.NUM_WIFI_BATCHED_SCAN_BINS; bn++) { 12008 if (u.mWifiBatchedScanTimer[bn] != null) { 12009 long bnMs = u.mWifiBatchedScanTimer[bn] 12010 .getTimeSinceMarkLocked(elapsedRealtimeMs * 1000) / 1000; 12011 if (bnMs > 0) { 12012 u.mWifiBatchedScanTimer[bn].setMark(elapsedRealtimeMs); 12013 } 12014 uidBatchScanMs += bnMs; 12015 } 12016 } 12017 12018 uidEstimatedConsumptionMah.add(u.getUid(), 12019 mWifiPowerCalculator.calcPowerWithoutControllerDataMah( 12020 entry.rxPackets, entry.txPackets, 12021 uidRunningMs, uidScanMs, uidBatchScanMs)); 12022 } 12023 } 12024 mNetworkStatsPool.release(delta); 12025 delta = null; 12026 } 12027 12028 if (info != null) { 12029 mHasWifiReporting = true; 12030 12031 // Measured in mAms 12032 final long txTimeMs = info.getControllerTxDurationMillis(); 12033 final long rxTimeMs = info.getControllerRxDurationMillis(); 12034 final long scanTimeMs = info.getControllerScanDurationMillis(); 12035 final long idleTimeMs = info.getControllerIdleDurationMillis(); 12036 final long totalTimeMs = txTimeMs + rxTimeMs + idleTimeMs; 12037 12038 long leftOverRxTimeMs = rxTimeMs; 12039 long leftOverTxTimeMs = txTimeMs; 12040 12041 if (DEBUG_ENERGY) { 12042 Slog.d(TAG, "------ BEGIN WiFi power blaming ------"); 12043 Slog.d(TAG, " Tx Time: " + txTimeMs + " ms"); 12044 Slog.d(TAG, " Rx Time: " + rxTimeMs + " ms"); 12045 Slog.d(TAG, " Idle Time: " + idleTimeMs + " ms"); 12046 Slog.d(TAG, " Total Time: " + totalTimeMs + " ms"); 12047 Slog.d(TAG, " Scan Time: " + scanTimeMs + " ms"); 12048 } 12049 12050 long totalWifiLockTimeMs = 0; 12051 long totalScanTimeMs = 0; 12052 12053 // On the first pass, collect some totals so that we can normalize power 12054 // calculations if we need to. 12055 final int uidStatsSize = mUidStats.size(); 12056 for (int i = 0; i < uidStatsSize; i++) { 12057 final Uid uid = mUidStats.valueAt(i); 12058 12059 // Sum the total scan power for all apps. 12060 totalScanTimeMs += uid.mWifiScanTimer.getTimeSinceMarkLocked( 12061 elapsedRealtimeMs * 1000) / 1000; 12062 12063 // Sum the total time holding wifi lock for all apps. 12064 totalWifiLockTimeMs += uid.mFullWifiLockTimer.getTimeSinceMarkLocked( 12065 elapsedRealtimeMs * 1000) / 1000; 12066 } 12067 12068 if (DEBUG_ENERGY && totalScanTimeMs > rxTimeMs) { 12069 Slog.d(TAG, 12070 " !Estimated scan time > Actual rx time (" + totalScanTimeMs + " ms > " 12071 + rxTimeMs + " ms). Normalizing scan time."); 12072 } 12073 if (DEBUG_ENERGY && totalScanTimeMs > txTimeMs) { 12074 Slog.d(TAG, 12075 " !Estimated scan time > Actual tx time (" + totalScanTimeMs + " ms > " 12076 + txTimeMs + " ms). Normalizing scan time."); 12077 } 12078 12079 // Actually assign and distribute power usage to apps. 12080 for (int i = 0; i < uidStatsSize; i++) { 12081 final Uid uid = mUidStats.valueAt(i); 12082 12083 final long scanTimeSinceMarkMs = uid.mWifiScanTimer.getTimeSinceMarkLocked( 12084 elapsedRealtimeMs * 1000) / 1000; 12085 long scanRxTimeSinceMarkMs = scanTimeSinceMarkMs; // not final 12086 long scanTxTimeSinceMarkMs = scanTimeSinceMarkMs; // not final 12087 if (scanTimeSinceMarkMs > 0) { 12088 // Set the new mark so that next time we get new data since this point. 12089 uid.mWifiScanTimer.setMark(elapsedRealtimeMs); 12090 12091 // Our total scan time is more than the reported Tx/Rx time. 12092 // This is possible because the cost of a scan is approximate. 12093 // Let's normalize the result so that we evenly blame each app 12094 // scanning. 12095 // 12096 // This means that we may have apps that transmitted/received packets not be 12097 // blamed for this, but this is fine as scans are relatively more expensive. 12098 if (totalScanTimeMs > rxTimeMs) { 12099 scanRxTimeSinceMarkMs = (rxTimeMs * scanRxTimeSinceMarkMs) / 12100 totalScanTimeMs; 12101 } 12102 if (totalScanTimeMs > txTimeMs) { 12103 scanTxTimeSinceMarkMs = (txTimeMs * scanTxTimeSinceMarkMs) / 12104 totalScanTimeMs; 12105 } 12106 12107 if (DEBUG_ENERGY) { 12108 Slog.d(TAG, " ScanTime for UID " + uid.getUid() + ": Rx:" 12109 + scanRxTimeSinceMarkMs + " ms Tx:" 12110 + scanTxTimeSinceMarkMs + " ms)"); 12111 } 12112 12113 ControllerActivityCounterImpl activityCounter = 12114 uid.getOrCreateWifiControllerActivityLocked(); 12115 activityCounter.getRxTimeCounter().addCountLocked(scanRxTimeSinceMarkMs); 12116 activityCounter.getTxTimeCounters()[0].addCountLocked( 12117 scanTxTimeSinceMarkMs); 12118 leftOverRxTimeMs -= scanRxTimeSinceMarkMs; 12119 leftOverTxTimeMs -= scanTxTimeSinceMarkMs; 12120 } 12121 12122 // Distribute evenly the power consumed while Idle to each app holding a WiFi 12123 // lock. 12124 long myIdleTimeMs = 0; 12125 final long wifiLockTimeSinceMarkMs = 12126 uid.mFullWifiLockTimer.getTimeSinceMarkLocked( 12127 elapsedRealtimeMs * 1000) / 1000; 12128 if (wifiLockTimeSinceMarkMs > 0) { 12129 // Set the new mark so that next time we get new data since this point. 12130 uid.mFullWifiLockTimer.setMark(elapsedRealtimeMs); 12131 12132 myIdleTimeMs = (wifiLockTimeSinceMarkMs * idleTimeMs) / totalWifiLockTimeMs; 12133 if (DEBUG_ENERGY) { 12134 Slog.d(TAG, " IdleTime for UID " + uid.getUid() + ": " 12135 + myIdleTimeMs + " ms"); 12136 } 12137 uid.getOrCreateWifiControllerActivityLocked().getIdleTimeCounter() 12138 .addCountLocked(myIdleTimeMs); 12139 } 12140 12141 if (uidEstimatedConsumptionMah != null) { 12142 double uidEstMah = mWifiPowerCalculator.calcPowerFromControllerDataMah( 12143 scanRxTimeSinceMarkMs, scanTxTimeSinceMarkMs, myIdleTimeMs); 12144 uidEstimatedConsumptionMah.add(uid.getUid(), uidEstMah); 12145 } 12146 } 12147 12148 if (DEBUG_ENERGY) { 12149 Slog.d(TAG, " New RxPower: " + leftOverRxTimeMs + " ms"); 12150 Slog.d(TAG, " New TxPower: " + leftOverTxTimeMs + " ms"); 12151 } 12152 12153 // Distribute the remaining Tx power appropriately between all apps that transmitted 12154 // packets. 12155 for (int i = 0; i < txPackets.size(); i++) { 12156 final Uid uid = getUidStatsLocked(txPackets.keyAt(i), 12157 elapsedRealtimeMs, uptimeMs); 12158 final long myTxTimeMs = (txPackets.valueAt(i) * leftOverTxTimeMs) 12159 / totalTxPackets; 12160 if (DEBUG_ENERGY) { 12161 Slog.d(TAG, " TxTime for UID " + uid.getUid() + ": " + myTxTimeMs + " ms"); 12162 } 12163 uid.getOrCreateWifiControllerActivityLocked().getTxTimeCounters()[0] 12164 .addCountLocked(myTxTimeMs); 12165 if (uidEstimatedConsumptionMah != null) { 12166 uidEstimatedConsumptionMah.add(uid.getUid(), 12167 mWifiPowerCalculator.calcPowerFromControllerDataMah( 12168 0, myTxTimeMs, 0)); 12169 } 12170 } 12171 12172 // Distribute the remaining Rx power appropriately between all apps that received 12173 // packets. 12174 for (int i = 0; i < rxPackets.size(); i++) { 12175 final Uid uid = getUidStatsLocked(rxPackets.keyAt(i), 12176 elapsedRealtimeMs, uptimeMs); 12177 final long myRxTimeMs = (rxPackets.valueAt(i) * leftOverRxTimeMs) 12178 / totalRxPackets; 12179 if (DEBUG_ENERGY) { 12180 Slog.d(TAG, " RxTime for UID " + uid.getUid() + ": " + myRxTimeMs + " ms"); 12181 } 12182 uid.getOrCreateWifiControllerActivityLocked().getRxTimeCounter() 12183 .addCountLocked(myRxTimeMs); 12184 if (uidEstimatedConsumptionMah != null) { 12185 uidEstimatedConsumptionMah.add(uid.getUid(), 12186 mWifiPowerCalculator.calcPowerFromControllerDataMah( 12187 myRxTimeMs, 0, 0)); 12188 } 12189 } 12190 12191 // Any left over power use will be picked up by the WiFi category in BatteryStatsHelper. 12192 12193 12194 // Update WiFi controller stats. 12195 mWifiActivity.getRxTimeCounter().addCountLocked( 12196 info.getControllerRxDurationMillis()); 12197 mWifiActivity.getTxTimeCounters()[0].addCountLocked( 12198 info.getControllerTxDurationMillis()); 12199 mWifiActivity.getScanTimeCounter().addCountLocked( 12200 info.getControllerScanDurationMillis()); 12201 mWifiActivity.getIdleTimeCounter().addCountLocked( 12202 info.getControllerIdleDurationMillis()); 12203 12204 // POWER_WIFI_CONTROLLER_OPERATING_VOLTAGE is measured in mV, so convert to V. 12205 final double opVolt = mPowerProfile.getAveragePower( 12206 PowerProfile.POWER_WIFI_CONTROLLER_OPERATING_VOLTAGE) / 1000.0; 12207 double controllerMaMs = 0; 12208 if (opVolt != 0) { 12209 // We store the power drain as mAms. 12210 controllerMaMs = info.getControllerEnergyUsedMicroJoules() / opVolt; 12211 mWifiActivity.getPowerCounter().addCountLocked((long) controllerMaMs); 12212 } 12213 // Converting uWs to mAms. 12214 // Conversion: (uWs * (1000ms / 1s) * (1mW / 1000uW)) / mV = mAms 12215 long monitoredRailChargeConsumedMaMs = 12216 (long) (mTmpRailStats.getWifiTotalEnergyUseduWs() / opVolt); 12217 mWifiActivity.getMonitoredRailChargeConsumedMaMs().addCountLocked( 12218 monitoredRailChargeConsumedMaMs); 12219 mHistoryCur.wifiRailChargeMah += 12220 (monitoredRailChargeConsumedMaMs / MILLISECONDS_IN_HOUR); 12221 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 12222 mTmpRailStats.resetWifiTotalEnergyUsed(); 12223 12224 if (uidEstimatedConsumptionMah != null) { 12225 totalEstimatedConsumptionMah = Math.max(controllerMaMs / MILLISECONDS_IN_HOUR, 12226 mWifiPowerCalculator.calcPowerFromControllerDataMah( 12227 rxTimeMs, txTimeMs, idleTimeMs)); 12228 } 12229 } 12230 12231 // Update the MeasuredEnergyStats information. 12232 if (uidEstimatedConsumptionMah != null) { 12233 mGlobalMeasuredEnergyStats.updateStandardBucket( 12234 MeasuredEnergyStats.POWER_BUCKET_WIFI, consumedChargeUC); 12235 12236 // Now calculate the consumption for each uid, according to its proportional usage. 12237 if (!mHasWifiReporting) { 12238 final long globalTimeMs = mGlobalWifiRunningTimer 12239 .getTimeSinceMarkLocked(elapsedRealtimeMs * 1000) / 1000; 12240 mGlobalWifiRunningTimer.setMark(elapsedRealtimeMs); 12241 totalEstimatedConsumptionMah = mWifiPowerCalculator 12242 .calcGlobalPowerWithoutControllerDataMah(globalTimeMs); 12243 } 12244 distributeEnergyToUidsLocked(MeasuredEnergyStats.POWER_BUCKET_WIFI, 12245 consumedChargeUC, uidEstimatedConsumptionMah, totalEstimatedConsumptionMah); 12246 } 12247 } 12248 } 12249 12250 private ModemActivityInfo mLastModemActivityInfo = null; 12251 12252 /** 12253 * Distribute Cell radio energy info and network traffic to apps. 12254 */ noteModemControllerActivity(@ullable final ModemActivityInfo activityInfo, final long consumedChargeUC, long elapsedRealtimeMs, long uptimeMs)12255 public void noteModemControllerActivity(@Nullable final ModemActivityInfo activityInfo, 12256 final long consumedChargeUC, long elapsedRealtimeMs, long uptimeMs) { 12257 if (DEBUG_ENERGY) { 12258 Slog.d(TAG, "Updating mobile radio stats with " + activityInfo); 12259 } 12260 ModemActivityInfo deltaInfo = mLastModemActivityInfo == null ? activityInfo 12261 : mLastModemActivityInfo.getDelta(activityInfo); 12262 mLastModemActivityInfo = activityInfo; 12263 12264 // Add modem tx power to history. 12265 addModemTxPowerToHistory(deltaInfo, elapsedRealtimeMs, uptimeMs); 12266 12267 // Grab a separate lock to acquire the network stats, which may do I/O. 12268 NetworkStats delta = null; 12269 synchronized (mModemNetworkLock) { 12270 final NetworkStats latestStats = readNetworkStatsLocked(mModemIfaces); 12271 if (latestStats != null) { 12272 delta = NetworkStats.subtract(latestStats, mLastModemNetworkStats, null, null, 12273 mNetworkStatsPool.acquire()); 12274 mNetworkStatsPool.release(mLastModemNetworkStats); 12275 mLastModemNetworkStats = latestStats; 12276 } 12277 } 12278 12279 synchronized (this) { 12280 if (!mOnBatteryInternal || mIgnoreNextExternalStats) { 12281 if (delta != null) { 12282 mNetworkStatsPool.release(delta); 12283 } 12284 return; 12285 } 12286 12287 final SparseDoubleArray uidEstimatedConsumptionMah; 12288 if (consumedChargeUC > 0 && mMobileRadioPowerCalculator != null 12289 && mGlobalMeasuredEnergyStats != null) { 12290 mGlobalMeasuredEnergyStats.updateStandardBucket( 12291 MeasuredEnergyStats.POWER_BUCKET_MOBILE_RADIO, consumedChargeUC); 12292 uidEstimatedConsumptionMah = new SparseDoubleArray(); 12293 } else { 12294 uidEstimatedConsumptionMah = null; 12295 } 12296 12297 if (deltaInfo != null) { 12298 mHasModemReporting = true; 12299 mModemActivity.getIdleTimeCounter().addCountLocked( 12300 deltaInfo.getIdleTimeMillis()); 12301 mModemActivity.getSleepTimeCounter().addCountLocked( 12302 deltaInfo.getSleepTimeMillis()); 12303 mModemActivity.getRxTimeCounter().addCountLocked(deltaInfo.getReceiveTimeMillis()); 12304 for (int lvl = 0; lvl < ModemActivityInfo.getNumTxPowerLevels(); lvl++) { 12305 mModemActivity.getTxTimeCounters()[lvl] 12306 .addCountLocked(deltaInfo.getTransmitDurationMillisAtPowerLevel(lvl)); 12307 } 12308 12309 // POWER_MODEM_CONTROLLER_OPERATING_VOLTAGE is measured in mV, so convert to V. 12310 final double opVolt = mPowerProfile.getAveragePower( 12311 PowerProfile.POWER_MODEM_CONTROLLER_OPERATING_VOLTAGE) / 1000.0; 12312 if (opVolt != 0) { 12313 double energyUsed = 12314 deltaInfo.getSleepTimeMillis() * 12315 mPowerProfile.getAveragePower(PowerProfile.POWER_MODEM_CONTROLLER_SLEEP) 12316 + deltaInfo.getIdleTimeMillis() * 12317 mPowerProfile.getAveragePower(PowerProfile.POWER_MODEM_CONTROLLER_IDLE) 12318 + deltaInfo.getReceiveTimeMillis() * 12319 mPowerProfile.getAveragePower(PowerProfile.POWER_MODEM_CONTROLLER_RX); 12320 for (int i = 0; i < Math.min(ModemActivityInfo.getNumTxPowerLevels(), 12321 CellSignalStrength.getNumSignalStrengthLevels()); i++) { 12322 energyUsed += deltaInfo.getTransmitDurationMillisAtPowerLevel(i) 12323 * mPowerProfile.getAveragePower( 12324 PowerProfile.POWER_MODEM_CONTROLLER_TX, i); 12325 } 12326 12327 // We store the power drain as mAms. 12328 mModemActivity.getPowerCounter().addCountLocked((long) energyUsed); 12329 // Converting uWs to mAms. 12330 // Conversion: (uWs * (1000ms / 1s) * (1mW / 1000uW)) / mV = mAms 12331 long monitoredRailChargeConsumedMaMs = 12332 (long) (mTmpRailStats.getCellularTotalEnergyUseduWs() / opVolt); 12333 mModemActivity.getMonitoredRailChargeConsumedMaMs().addCountLocked( 12334 monitoredRailChargeConsumedMaMs); 12335 mHistoryCur.modemRailChargeMah += 12336 (monitoredRailChargeConsumedMaMs / MILLISECONDS_IN_HOUR); 12337 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 12338 mTmpRailStats.resetCellularTotalEnergyUsed(); 12339 } 12340 } 12341 long totalAppRadioTimeUs = mMobileRadioActivePerAppTimer.getTimeSinceMarkLocked( 12342 elapsedRealtimeMs * 1000); 12343 mMobileRadioActivePerAppTimer.setMark(elapsedRealtimeMs); 12344 12345 long totalRxPackets = 0; 12346 long totalTxPackets = 0; 12347 if (delta != null) { 12348 NetworkStats.Entry entry = new NetworkStats.Entry(); 12349 final int size = delta.size(); 12350 for (int i = 0; i < size; i++) { 12351 entry = delta.getValues(i, entry); 12352 if (entry.rxPackets == 0 && entry.txPackets == 0) { 12353 continue; 12354 } 12355 12356 if (DEBUG_ENERGY) { 12357 Slog.d(TAG, "Mobile uid " + entry.uid + ": delta rx=" + entry.rxBytes 12358 + " tx=" + entry.txBytes + " rxPackets=" + entry.rxPackets 12359 + " txPackets=" + entry.txPackets); 12360 } 12361 12362 totalRxPackets += entry.rxPackets; 12363 totalTxPackets += entry.txPackets; 12364 12365 final Uid u = getUidStatsLocked(mapUid(entry.uid), elapsedRealtimeMs, uptimeMs); 12366 u.noteNetworkActivityLocked(NETWORK_MOBILE_RX_DATA, entry.rxBytes, 12367 entry.rxPackets); 12368 u.noteNetworkActivityLocked(NETWORK_MOBILE_TX_DATA, entry.txBytes, 12369 entry.txPackets); 12370 if (entry.set == NetworkStats.SET_DEFAULT) { // Background transfers 12371 u.noteNetworkActivityLocked(NETWORK_MOBILE_BG_RX_DATA, 12372 entry.rxBytes, entry.rxPackets); 12373 u.noteNetworkActivityLocked(NETWORK_MOBILE_BG_TX_DATA, 12374 entry.txBytes, entry.txPackets); 12375 } 12376 12377 mNetworkByteActivityCounters[NETWORK_MOBILE_RX_DATA].addCountLocked( 12378 entry.rxBytes); 12379 mNetworkByteActivityCounters[NETWORK_MOBILE_TX_DATA].addCountLocked( 12380 entry.txBytes); 12381 mNetworkPacketActivityCounters[NETWORK_MOBILE_RX_DATA].addCountLocked( 12382 entry.rxPackets); 12383 mNetworkPacketActivityCounters[NETWORK_MOBILE_TX_DATA].addCountLocked( 12384 entry.txPackets); 12385 } 12386 12387 // Now distribute proportional blame to the apps that did networking. 12388 long totalPackets = totalRxPackets + totalTxPackets; 12389 if (totalPackets > 0) { 12390 for (int i = 0; i < size; i++) { 12391 entry = delta.getValues(i, entry); 12392 if (entry.rxPackets == 0 && entry.txPackets == 0) { 12393 continue; 12394 } 12395 12396 final Uid u = getUidStatsLocked(mapUid(entry.uid), 12397 elapsedRealtimeMs, uptimeMs); 12398 12399 // Distribute total radio active time in to this app. 12400 final long appPackets = entry.rxPackets + entry.txPackets; 12401 final long appRadioTimeUs = 12402 (totalAppRadioTimeUs * appPackets) / totalPackets; 12403 u.noteMobileRadioActiveTimeLocked(appRadioTimeUs); 12404 12405 // Distribute measured mobile radio charge consumption based on app radio 12406 // active time 12407 if (uidEstimatedConsumptionMah != null) { 12408 uidEstimatedConsumptionMah.add(u.getUid(), 12409 mMobileRadioPowerCalculator.calcPowerFromRadioActiveDurationMah( 12410 appRadioTimeUs / 1000)); 12411 } 12412 12413 // Remove this app from the totals, so that we don't lose any time 12414 // due to rounding. 12415 totalAppRadioTimeUs -= appRadioTimeUs; 12416 totalPackets -= appPackets; 12417 12418 if (deltaInfo != null) { 12419 ControllerActivityCounterImpl activityCounter = 12420 u.getOrCreateModemControllerActivityLocked(); 12421 if (totalRxPackets > 0 && entry.rxPackets > 0) { 12422 final long rxMs = (entry.rxPackets 12423 * deltaInfo.getReceiveTimeMillis()) / totalRxPackets; 12424 activityCounter.getRxTimeCounter().addCountLocked(rxMs); 12425 } 12426 12427 if (totalTxPackets > 0 && entry.txPackets > 0) { 12428 for (int lvl = 0; lvl < ModemActivityInfo.getNumTxPowerLevels(); 12429 lvl++) { 12430 long txMs = entry.txPackets 12431 * deltaInfo.getTransmitDurationMillisAtPowerLevel(lvl); 12432 txMs /= totalTxPackets; 12433 activityCounter.getTxTimeCounters()[lvl].addCountLocked(txMs); 12434 } 12435 } 12436 } 12437 } 12438 } 12439 12440 if (totalAppRadioTimeUs > 0) { 12441 // Whoops, there is some radio time we can't blame on an app! 12442 mMobileRadioActiveUnknownTime.addCountLocked(totalAppRadioTimeUs); 12443 mMobileRadioActiveUnknownCount.addCountLocked(1); 12444 } 12445 12446 12447 // Update the MeasuredEnergyStats information. 12448 if (uidEstimatedConsumptionMah != null) { 12449 double totalEstimatedConsumptionMah = 0.0; 12450 12451 // Estimate total active radio power consumption since last mark. 12452 final long totalRadioTimeMs = mMobileRadioActiveTimer.getTimeSinceMarkLocked( 12453 elapsedRealtimeMs * 1000) / 1000; 12454 mMobileRadioActiveTimer.setMark(elapsedRealtimeMs); 12455 totalEstimatedConsumptionMah += 12456 mMobileRadioPowerCalculator.calcPowerFromRadioActiveDurationMah( 12457 totalRadioTimeMs); 12458 12459 // Estimate idle power consumption at each signal strength level 12460 final int numSignalStrengthLevels = mPhoneSignalStrengthsTimer.length; 12461 for (int strengthLevel = 0; strengthLevel < numSignalStrengthLevels; 12462 strengthLevel++) { 12463 final long strengthLevelDurationMs = 12464 mPhoneSignalStrengthsTimer[strengthLevel].getTimeSinceMarkLocked( 12465 elapsedRealtimeMs * 1000) / 1000; 12466 mPhoneSignalStrengthsTimer[strengthLevel].setMark(elapsedRealtimeMs); 12467 12468 totalEstimatedConsumptionMah += 12469 mMobileRadioPowerCalculator.calcIdlePowerAtSignalStrengthMah( 12470 strengthLevelDurationMs, strengthLevel); 12471 } 12472 12473 // Estimate total active radio power consumption since last mark. 12474 final long scanTimeMs = mPhoneSignalScanningTimer.getTimeSinceMarkLocked( 12475 elapsedRealtimeMs * 1000) / 1000; 12476 mPhoneSignalScanningTimer.setMark(elapsedRealtimeMs); 12477 totalEstimatedConsumptionMah += 12478 mMobileRadioPowerCalculator.calcScanTimePowerMah(scanTimeMs); 12479 12480 distributeEnergyToUidsLocked(MeasuredEnergyStats.POWER_BUCKET_MOBILE_RADIO, 12481 consumedChargeUC, uidEstimatedConsumptionMah, 12482 totalEstimatedConsumptionMah); 12483 } 12484 12485 mNetworkStatsPool.release(delta); 12486 delta = null; 12487 } 12488 } 12489 } 12490 12491 /** 12492 * Add modem tx power to history 12493 * Device is said to be in high cellular transmit power when it has spent most of the transmit 12494 * time at the highest power level. 12495 * @param activityInfo 12496 */ addModemTxPowerToHistory(final ModemActivityInfo activityInfo, long elapsedRealtimeMs, long uptimeMs)12497 private synchronized void addModemTxPowerToHistory(final ModemActivityInfo activityInfo, 12498 long elapsedRealtimeMs, long uptimeMs) { 12499 if (activityInfo == null) { 12500 return; 12501 } 12502 int levelMaxTimeSpent = 0; 12503 for (int i = 1; i < ModemActivityInfo.getNumTxPowerLevels(); i++) { 12504 if (activityInfo.getTransmitDurationMillisAtPowerLevel(i) 12505 > activityInfo.getTransmitDurationMillisAtPowerLevel(levelMaxTimeSpent)) { 12506 levelMaxTimeSpent = i; 12507 } 12508 } 12509 if (levelMaxTimeSpent == ModemActivityInfo.getNumTxPowerLevels() - 1) { 12510 mHistoryCur.states2 |= HistoryItem.STATE2_CELLULAR_HIGH_TX_POWER_FLAG; 12511 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 12512 } 12513 } 12514 12515 private final class BluetoothActivityInfoCache { 12516 long idleTimeMs; 12517 long rxTimeMs; 12518 long txTimeMs; 12519 long energy; 12520 12521 SparseLongArray uidRxBytes = new SparseLongArray(); 12522 SparseLongArray uidTxBytes = new SparseLongArray(); 12523 set(BluetoothActivityEnergyInfo info)12524 void set(BluetoothActivityEnergyInfo info) { 12525 idleTimeMs = info.getControllerIdleTimeMillis(); 12526 rxTimeMs = info.getControllerRxTimeMillis(); 12527 txTimeMs = info.getControllerTxTimeMillis(); 12528 energy = info.getControllerEnergyUsed(); 12529 if (info.getUidTraffic() != null) { 12530 for (UidTraffic traffic : info.getUidTraffic()) { 12531 uidRxBytes.put(traffic.getUid(), traffic.getRxBytes()); 12532 uidTxBytes.put(traffic.getUid(), traffic.getTxBytes()); 12533 } 12534 } 12535 } 12536 reset()12537 void reset() { 12538 idleTimeMs = 0; 12539 rxTimeMs = 0; 12540 txTimeMs = 0; 12541 energy = 0; 12542 uidRxBytes.clear(); 12543 uidTxBytes.clear(); 12544 } 12545 } 12546 12547 private final BluetoothActivityInfoCache mLastBluetoothActivityInfo 12548 = new BluetoothActivityInfoCache(); 12549 12550 /** 12551 * Distribute Bluetooth energy info and network traffic to apps. 12552 * 12553 * @param info The accumulated energy information from the bluetooth controller. 12554 */ updateBluetoothStateLocked(@ullable final BluetoothActivityEnergyInfo info, final long consumedChargeUC, long elapsedRealtimeMs, long uptimeMs)12555 public void updateBluetoothStateLocked(@Nullable final BluetoothActivityEnergyInfo info, 12556 final long consumedChargeUC, long elapsedRealtimeMs, long uptimeMs) { 12557 if (DEBUG_ENERGY) { 12558 Slog.d(TAG, "Updating bluetooth stats: " + info); 12559 } 12560 12561 if (info == null) { 12562 return; 12563 } 12564 if (!mOnBatteryInternal || mIgnoreNextExternalStats) { 12565 mLastBluetoothActivityInfo.set(info); 12566 return; 12567 } 12568 12569 mHasBluetoothReporting = true; 12570 12571 if (info.getControllerRxTimeMillis() < mLastBluetoothActivityInfo.rxTimeMs 12572 || info.getControllerTxTimeMillis() < mLastBluetoothActivityInfo.txTimeMs 12573 || info.getControllerIdleTimeMillis() < mLastBluetoothActivityInfo.idleTimeMs 12574 || info.getControllerEnergyUsed() < mLastBluetoothActivityInfo.energy) { 12575 // A drop in accumulated Bluetooth stats is a sign of a Bluetooth crash. 12576 // Reset the preserved previous snapshot in order to restart accumulating deltas. 12577 mLastBluetoothActivityInfo.reset(); 12578 } 12579 12580 final long rxTimeMs = 12581 info.getControllerRxTimeMillis() - mLastBluetoothActivityInfo.rxTimeMs; 12582 final long txTimeMs = 12583 info.getControllerTxTimeMillis() - mLastBluetoothActivityInfo.txTimeMs; 12584 final long idleTimeMs = 12585 info.getControllerIdleTimeMillis() - mLastBluetoothActivityInfo.idleTimeMs; 12586 12587 if (DEBUG_ENERGY) { 12588 Slog.d(TAG, "------ BEGIN BLE power blaming ------"); 12589 Slog.d(TAG, " Tx Time: " + txTimeMs + " ms"); 12590 Slog.d(TAG, " Rx Time: " + rxTimeMs + " ms"); 12591 Slog.d(TAG, " Idle Time: " + idleTimeMs + " ms"); 12592 } 12593 12594 final SparseDoubleArray uidEstimatedConsumptionMah = 12595 (mGlobalMeasuredEnergyStats != null 12596 && mBluetoothPowerCalculator != null && consumedChargeUC > 0) ? 12597 new SparseDoubleArray() : null; 12598 12599 long totalScanTimeMs = 0; 12600 12601 final int uidCount = mUidStats.size(); 12602 for (int i = 0; i < uidCount; i++) { 12603 final Uid u = mUidStats.valueAt(i); 12604 if (u.mBluetoothScanTimer == null) { 12605 continue; 12606 } 12607 12608 totalScanTimeMs += u.mBluetoothScanTimer.getTimeSinceMarkLocked( 12609 elapsedRealtimeMs * 1000) / 1000; 12610 } 12611 12612 final boolean normalizeScanRxTime = (totalScanTimeMs > rxTimeMs); 12613 final boolean normalizeScanTxTime = (totalScanTimeMs > txTimeMs); 12614 12615 if (DEBUG_ENERGY) { 12616 Slog.d(TAG, "Normalizing scan power for RX=" + normalizeScanRxTime 12617 + " TX=" + normalizeScanTxTime); 12618 } 12619 12620 long leftOverRxTimeMs = rxTimeMs; 12621 long leftOverTxTimeMs = txTimeMs; 12622 12623 for (int i = 0; i < uidCount; i++) { 12624 final Uid u = mUidStats.valueAt(i); 12625 if (u.mBluetoothScanTimer == null) { 12626 continue; 12627 } 12628 12629 long scanTimeSinceMarkMs = u.mBluetoothScanTimer.getTimeSinceMarkLocked( 12630 elapsedRealtimeMs * 1000) / 1000; 12631 if (scanTimeSinceMarkMs > 0) { 12632 // Set the new mark so that next time we get new data since this point. 12633 u.mBluetoothScanTimer.setMark(elapsedRealtimeMs); 12634 12635 long scanTimeRxSinceMarkMs = scanTimeSinceMarkMs; 12636 long scanTimeTxSinceMarkMs = scanTimeSinceMarkMs; 12637 12638 if (normalizeScanRxTime) { 12639 // Scan time is longer than the total rx time in the controller, 12640 // so distribute the scan time proportionately. This means regular traffic 12641 // will not blamed, but scans are more expensive anyways. 12642 scanTimeRxSinceMarkMs = (rxTimeMs * scanTimeRxSinceMarkMs) / totalScanTimeMs; 12643 } 12644 12645 if (normalizeScanTxTime) { 12646 // Scan time is longer than the total tx time in the controller, 12647 // so distribute the scan time proportionately. This means regular traffic 12648 // will not blamed, but scans are more expensive anyways. 12649 scanTimeTxSinceMarkMs = (txTimeMs * scanTimeTxSinceMarkMs) / totalScanTimeMs; 12650 } 12651 12652 final ControllerActivityCounterImpl counter = 12653 u.getOrCreateBluetoothControllerActivityLocked(); 12654 counter.getRxTimeCounter().addCountLocked(scanTimeRxSinceMarkMs); 12655 counter.getTxTimeCounters()[0].addCountLocked(scanTimeTxSinceMarkMs); 12656 12657 if (uidEstimatedConsumptionMah != null) { 12658 uidEstimatedConsumptionMah.add(u.getUid(), 12659 mBluetoothPowerCalculator.calculatePowerMah( 12660 scanTimeRxSinceMarkMs, scanTimeTxSinceMarkMs, 0)); 12661 } 12662 12663 leftOverRxTimeMs -= scanTimeRxSinceMarkMs; 12664 leftOverTxTimeMs -= scanTimeTxSinceMarkMs; 12665 } 12666 } 12667 12668 if (DEBUG_ENERGY) { 12669 Slog.d(TAG, "Left over time for traffic RX=" + leftOverRxTimeMs + " TX=" 12670 + leftOverTxTimeMs); 12671 } 12672 12673 // 12674 // Now distribute blame to apps that did bluetooth traffic. 12675 // 12676 12677 long totalTxBytes = 0; 12678 long totalRxBytes = 0; 12679 12680 final UidTraffic[] uidTraffic = info.getUidTraffic(); 12681 final int numUids = uidTraffic != null ? uidTraffic.length : 0; 12682 for (int i = 0; i < numUids; i++) { 12683 final UidTraffic traffic = uidTraffic[i]; 12684 final long rxBytes = traffic.getRxBytes() - mLastBluetoothActivityInfo.uidRxBytes.get( 12685 traffic.getUid()); 12686 final long txBytes = traffic.getTxBytes() - mLastBluetoothActivityInfo.uidTxBytes.get( 12687 traffic.getUid()); 12688 12689 // Add to the global counters. 12690 mNetworkByteActivityCounters[NETWORK_BT_RX_DATA].addCountLocked(rxBytes); 12691 mNetworkByteActivityCounters[NETWORK_BT_TX_DATA].addCountLocked(txBytes); 12692 12693 // Add to the UID counters. 12694 final Uid u = getUidStatsLocked(mapUid(traffic.getUid()), elapsedRealtimeMs, uptimeMs); 12695 u.noteNetworkActivityLocked(NETWORK_BT_RX_DATA, rxBytes, 0); 12696 u.noteNetworkActivityLocked(NETWORK_BT_TX_DATA, txBytes, 0); 12697 12698 // Calculate the total traffic. 12699 totalRxBytes += rxBytes; 12700 totalTxBytes += txBytes; 12701 } 12702 12703 if ((totalTxBytes != 0 || totalRxBytes != 0) && (leftOverRxTimeMs != 0 12704 || leftOverTxTimeMs != 0)) { 12705 for (int i = 0; i < numUids; i++) { 12706 final UidTraffic traffic = uidTraffic[i]; 12707 final int uid = traffic.getUid(); 12708 final long rxBytes = 12709 traffic.getRxBytes() - mLastBluetoothActivityInfo.uidRxBytes.get(uid); 12710 final long txBytes = 12711 traffic.getTxBytes() - mLastBluetoothActivityInfo.uidTxBytes.get(uid); 12712 12713 final Uid u = getUidStatsLocked(mapUid(uid), elapsedRealtimeMs, uptimeMs); 12714 final ControllerActivityCounterImpl counter = 12715 u.getOrCreateBluetoothControllerActivityLocked(); 12716 12717 if (totalRxBytes > 0 && rxBytes > 0) { 12718 final long timeRxMs = (leftOverRxTimeMs * rxBytes) / totalRxBytes; 12719 if (DEBUG_ENERGY) { 12720 Slog.d(TAG, "UID=" + uid + " rx_bytes=" + rxBytes + " rx_time=" + timeRxMs); 12721 } 12722 counter.getRxTimeCounter().addCountLocked(timeRxMs); 12723 12724 if (uidEstimatedConsumptionMah != null) { 12725 uidEstimatedConsumptionMah.add(u.getUid(), 12726 mBluetoothPowerCalculator.calculatePowerMah(timeRxMs, 0, 0)); 12727 } 12728 } 12729 12730 if (totalTxBytes > 0 && txBytes > 0) { 12731 final long timeTxMs = (leftOverTxTimeMs * txBytes) / totalTxBytes; 12732 if (DEBUG_ENERGY) { 12733 Slog.d(TAG, "UID=" + uid + " tx_bytes=" + txBytes + " tx_time=" + timeTxMs); 12734 } 12735 counter.getTxTimeCounters()[0].addCountLocked(timeTxMs); 12736 12737 if (uidEstimatedConsumptionMah != null) { 12738 uidEstimatedConsumptionMah.add(u.getUid(), 12739 mBluetoothPowerCalculator.calculatePowerMah(0, timeTxMs, 0)); 12740 } 12741 } 12742 } 12743 } 12744 12745 mBluetoothActivity.getRxTimeCounter().addCountLocked(rxTimeMs); 12746 mBluetoothActivity.getTxTimeCounters()[0].addCountLocked(txTimeMs); 12747 mBluetoothActivity.getIdleTimeCounter().addCountLocked(idleTimeMs); 12748 12749 // POWER_BLUETOOTH_CONTROLLER_OPERATING_VOLTAGE is measured in mV, so convert to V. 12750 final double opVolt = mPowerProfile.getAveragePower( 12751 PowerProfile.POWER_BLUETOOTH_CONTROLLER_OPERATING_VOLTAGE) / 1000.0; 12752 double controllerMaMs = 0; 12753 if (opVolt != 0) { 12754 controllerMaMs = (info.getControllerEnergyUsed() - mLastBluetoothActivityInfo.energy) 12755 / opVolt; 12756 // We store the power drain as mAms. 12757 mBluetoothActivity.getPowerCounter().addCountLocked((long) controllerMaMs); 12758 } 12759 12760 // Update the MeasuredEnergyStats information. 12761 if (uidEstimatedConsumptionMah != null) { 12762 mGlobalMeasuredEnergyStats.updateStandardBucket( 12763 MeasuredEnergyStats.POWER_BUCKET_BLUETOOTH, consumedChargeUC); 12764 12765 double totalEstimatedMah 12766 = mBluetoothPowerCalculator.calculatePowerMah(rxTimeMs, txTimeMs, idleTimeMs); 12767 totalEstimatedMah = Math.max(totalEstimatedMah, controllerMaMs / MILLISECONDS_IN_HOUR); 12768 distributeEnergyToUidsLocked(MeasuredEnergyStats.POWER_BUCKET_BLUETOOTH, 12769 consumedChargeUC, uidEstimatedConsumptionMah, totalEstimatedMah); 12770 } 12771 12772 mLastBluetoothActivityInfo.set(info); 12773 } 12774 /** 12775 * Read Resource Power Manager (RPM) state and voter times. 12776 * If RPM stats were fetched more recently than RPM_STATS_UPDATE_FREQ_MS ago, uses the old data 12777 * instead of fetching it anew. 12778 * 12779 * Note: This should be called without synchronizing this BatteryStatsImpl object 12780 */ fillLowPowerStats()12781 public void fillLowPowerStats() { 12782 if (mPlatformIdleStateCallback == null) return; 12783 12784 RpmStats rpmStats = new RpmStats(); 12785 long now = SystemClock.elapsedRealtime(); 12786 if (now - mLastRpmStatsUpdateTimeMs >= RPM_STATS_UPDATE_FREQ_MS) { 12787 mPlatformIdleStateCallback.fillLowPowerStats(rpmStats); 12788 synchronized (this) { 12789 mTmpRpmStats = rpmStats; 12790 mLastRpmStatsUpdateTimeMs = now; 12791 } 12792 } 12793 } 12794 12795 /** 12796 * Record Resource Power Manager (RPM) state and voter times. 12797 * TODO(b/185252376): Remove this logging. PowerStatsService logs the same data more 12798 * efficiently. 12799 */ updateRpmStatsLocked(long elapsedRealtimeUs)12800 public void updateRpmStatsLocked(long elapsedRealtimeUs) { 12801 if (mTmpRpmStats == null) return; 12802 12803 for (Map.Entry<String, RpmStats.PowerStatePlatformSleepState> pstate 12804 : mTmpRpmStats.mPlatformLowPowerStats.entrySet()) { 12805 12806 // Update values for this platform state. 12807 final String pName = pstate.getKey(); 12808 final long pTimeUs = pstate.getValue().mTimeMs * 1000; 12809 final int pCount = pstate.getValue().mCount; 12810 getRpmTimerLocked(pName).update(pTimeUs, pCount, elapsedRealtimeUs); 12811 if (SCREEN_OFF_RPM_STATS_ENABLED) { 12812 getScreenOffRpmTimerLocked(pName).update(pTimeUs, pCount, elapsedRealtimeUs); 12813 } 12814 12815 // Update values for each voter of this platform state. 12816 for (Map.Entry<String, RpmStats.PowerStateElement> voter 12817 : pstate.getValue().mVoters.entrySet()) { 12818 final String vName = pName + "." + voter.getKey(); 12819 final long vTimeUs = voter.getValue().mTimeMs * 1000; 12820 final int vCount = voter.getValue().mCount; 12821 getRpmTimerLocked(vName).update(vTimeUs, vCount, elapsedRealtimeUs); 12822 if (SCREEN_OFF_RPM_STATS_ENABLED) { 12823 getScreenOffRpmTimerLocked(vName).update(vTimeUs, vCount, elapsedRealtimeUs); 12824 } 12825 } 12826 } 12827 12828 for (Map.Entry<String, RpmStats.PowerStateSubsystem> subsys 12829 : mTmpRpmStats.mSubsystemLowPowerStats.entrySet()) { 12830 12831 final String subsysName = subsys.getKey(); 12832 for (Map.Entry<String, RpmStats.PowerStateElement> sstate 12833 : subsys.getValue().mStates.entrySet()) { 12834 final String name = subsysName + "." + sstate.getKey(); 12835 final long timeUs = sstate.getValue().mTimeMs * 1000; 12836 final int count = sstate.getValue().mCount; 12837 getRpmTimerLocked(name).update(timeUs, count, elapsedRealtimeUs); 12838 if (SCREEN_OFF_RPM_STATS_ENABLED) { 12839 getScreenOffRpmTimerLocked(name).update(timeUs, count, elapsedRealtimeUs); 12840 } 12841 } 12842 } 12843 } 12844 12845 /** 12846 * Accumulate Cpu charge consumption and distribute it to the correct state and the apps. 12847 * Only call if device is on battery. 12848 * 12849 * @param clusterChargeUC amount of charge (microcoulombs) consumed by each Cpu Cluster 12850 * @param accumulator collection of calculated uid cpu power consumption to smear 12851 * clusterChargeUC against. 12852 */ 12853 @GuardedBy("this") updateCpuMeasuredEnergyStatsLocked(@onNull long[] clusterChargeUC, @NonNull CpuDeltaPowerAccumulator accumulator)12854 private void updateCpuMeasuredEnergyStatsLocked(@NonNull long[] clusterChargeUC, 12855 @NonNull CpuDeltaPowerAccumulator accumulator) { 12856 if (DEBUG_ENERGY) { 12857 Slog.d(TAG, 12858 "Updating cpu cluster stats: " + clusterChargeUC.toString()); 12859 } 12860 if (mGlobalMeasuredEnergyStats == null) { 12861 return; 12862 } 12863 12864 final int numClusters = clusterChargeUC.length; 12865 long totalCpuChargeUC = 0; 12866 for (int i = 0; i < numClusters; i++) { 12867 totalCpuChargeUC += clusterChargeUC[i]; 12868 } 12869 if (totalCpuChargeUC <= 0) return; 12870 12871 mGlobalMeasuredEnergyStats.updateStandardBucket(MeasuredEnergyStats.POWER_BUCKET_CPU, 12872 totalCpuChargeUC); 12873 12874 // Calculate the measured microcoulombs/calculated milliamp-hour charge ratio for each 12875 // cluster to normalize each uid's estimated power usage against actual power usage for 12876 // a given cluster. 12877 final double[] clusterChargeRatio = new double[numClusters]; 12878 for (int cluster = 0; cluster < numClusters; cluster++) { 12879 12880 final double totalClusterChargeMah = accumulator.totalClusterChargesMah[cluster]; 12881 if (totalClusterChargeMah <= 0.0) { 12882 // This cluster did not have any work on it, since last update. 12883 // Avoid dividing by zero. 12884 clusterChargeRatio[cluster] = 0.0; 12885 } else { 12886 clusterChargeRatio[cluster] = 12887 clusterChargeUC[cluster] / accumulator.totalClusterChargesMah[cluster]; 12888 } 12889 } 12890 12891 // Assign and distribute power usage to apps based on their calculated cpu cluster charge. 12892 final long uidChargeArraySize = accumulator.perUidCpuClusterChargesMah.size(); 12893 for (int i = 0; i < uidChargeArraySize; i++) { 12894 final Uid uid = accumulator.perUidCpuClusterChargesMah.keyAt(i); 12895 final double[] uidClusterChargesMah = accumulator.perUidCpuClusterChargesMah.valueAt(i); 12896 12897 // Iterate each cpu cluster and sum the proportional measured cpu cluster charge to 12898 // get the total cpu charge consumed by a uid. 12899 long uidCpuChargeUC = 0; 12900 for (int cluster = 0; cluster < numClusters; cluster++) { 12901 final double uidClusterChargeMah = uidClusterChargesMah[cluster]; 12902 12903 // Proportionally allocate the measured cpu cluster charge to a uid using the 12904 // measured charge/calculated charge ratio. Add 0.5 to round the proportional 12905 // charge double to the nearest long value. 12906 final long uidClusterChargeUC = 12907 (long) (uidClusterChargeMah * clusterChargeRatio[cluster] 12908 + 0.5); 12909 12910 uidCpuChargeUC += uidClusterChargeUC; 12911 } 12912 12913 if (uidCpuChargeUC < 0) { 12914 Slog.wtf(TAG, 12915 "Unexpected proportional measured charge (" + uidCpuChargeUC + ") for uid " 12916 + uid.mUid); 12917 continue; 12918 } 12919 12920 uid.addChargeToStandardBucketLocked(uidCpuChargeUC, 12921 MeasuredEnergyStats.POWER_BUCKET_CPU); 12922 } 12923 } 12924 12925 /** 12926 * Accumulate Display charge consumption and distribute it to the correct state and the apps. 12927 * 12928 * NOTE: The algorithm used makes the strong assumption that app foreground activity time 12929 * is always 0 when the screen is not "ON" and whenever the rail energy is 0 (if supported). 12930 * To the extent that those assumptions are violated, the algorithm will err. 12931 * 12932 * @param chargesUC amount of charge (microcoulombs) used by each Display since this was last 12933 * called. 12934 * @param screenStates each screen state at the time this data collection was scheduled 12935 */ 12936 @GuardedBy("this") updateDisplayMeasuredEnergyStatsLocked(long[] chargesUC, int[] screenStates, long elapsedRealtimeMs)12937 public void updateDisplayMeasuredEnergyStatsLocked(long[] chargesUC, int[] screenStates, 12938 long elapsedRealtimeMs) { 12939 if (DEBUG_ENERGY) Slog.d(TAG, "Updating display stats: " + Arrays.toString(chargesUC)); 12940 if (mGlobalMeasuredEnergyStats == null) { 12941 return; 12942 } 12943 12944 final int numDisplays; 12945 if (mPerDisplayBatteryStats.length == screenStates.length) { 12946 numDisplays = screenStates.length; 12947 } else { 12948 // if this point is reached, it will be reached every display state change. 12949 // Rate limit the wtf logging to once every 100 display updates. 12950 if (mDisplayMismatchWtfCount++ % 100 == 0) { 12951 Slog.wtf(TAG, "Mismatch between PowerProfile reported display count (" 12952 + mPerDisplayBatteryStats.length 12953 + ") and PowerStatsHal reported display count (" + screenStates.length 12954 + ")"); 12955 } 12956 // Keep the show going, use the shorter of the two. 12957 numDisplays = mPerDisplayBatteryStats.length < screenStates.length 12958 ? mPerDisplayBatteryStats.length : screenStates.length; 12959 } 12960 12961 final int[] oldScreenStates = new int[numDisplays]; 12962 for (int i = 0; i < numDisplays; i++) { 12963 final int screenState = screenStates[i]; 12964 oldScreenStates[i] = mPerDisplayBatteryStats[i].screenStateAtLastEnergyMeasurement; 12965 mPerDisplayBatteryStats[i].screenStateAtLastEnergyMeasurement = screenState; 12966 } 12967 12968 if (!mOnBatteryInternal) { 12969 // There's nothing further to update. 12970 return; 12971 } 12972 if (mIgnoreNextExternalStats) { 12973 // Although under ordinary resets we won't get here, and typically a new sync will 12974 // happen right after the reset, strictly speaking we need to set all mark times to now. 12975 final int uidStatsSize = mUidStats.size(); 12976 for (int i = 0; i < uidStatsSize; i++) { 12977 final Uid uid = mUidStats.valueAt(i); 12978 uid.markProcessForegroundTimeUs(elapsedRealtimeMs, false); 12979 } 12980 return; 12981 } 12982 12983 long totalScreenOnChargeUC = 0; 12984 for (int i = 0; i < numDisplays; i++) { 12985 final long chargeUC = chargesUC[i]; 12986 if (chargeUC <= 0) { 12987 // There's nothing further to update. 12988 continue; 12989 } 12990 12991 final @StandardPowerBucket int powerBucket = 12992 MeasuredEnergyStats.getDisplayPowerBucket(oldScreenStates[i]); 12993 mGlobalMeasuredEnergyStats.updateStandardBucket(powerBucket, chargeUC); 12994 if (powerBucket == MeasuredEnergyStats.POWER_BUCKET_SCREEN_ON) { 12995 totalScreenOnChargeUC += chargeUC; 12996 } 12997 } 12998 12999 // Now we blame individual apps, but only if the display was ON. 13000 if (totalScreenOnChargeUC <= 0) { 13001 return; 13002 } 13003 // TODO(b/175726779): Consider unifying the code with the non-rail display power blaming. 13004 13005 // NOTE: fg time is NOT pooled. If two uids are both somehow in fg, then that time is 13006 // 'double counted' and will simply exceed the realtime that elapsed. 13007 // TODO(b/175726779): collect per display uid visibility for display power attribution. 13008 13009 // Collect total time since mark so that we can normalize power. 13010 final SparseDoubleArray fgTimeUsArray = new SparseDoubleArray(); 13011 final long elapsedRealtimeUs = elapsedRealtimeMs * 1000; 13012 // TODO(b/175726779): Update and optimize the algorithm (e.g. avoid iterating over ALL uids) 13013 final int uidStatsSize = mUidStats.size(); 13014 for (int i = 0; i < uidStatsSize; i++) { 13015 final Uid uid = mUidStats.valueAt(i); 13016 final long fgTimeUs = uid.markProcessForegroundTimeUs(elapsedRealtimeMs, true); 13017 if (fgTimeUs == 0) continue; 13018 fgTimeUsArray.put(uid.getUid(), (double) fgTimeUs); 13019 } 13020 distributeEnergyToUidsLocked(MeasuredEnergyStats.POWER_BUCKET_SCREEN_ON, 13021 totalScreenOnChargeUC, fgTimeUsArray, 0); 13022 } 13023 13024 /** 13025 * Accumulate GNSS charge consumption and distribute it to the correct state and the apps. 13026 * 13027 * @param chargeUC amount of charge (microcoulombs) used by GNSS since this was last called. 13028 */ 13029 @GuardedBy("this") 13030 public void updateGnssMeasuredEnergyStatsLocked(long chargeUC, long elapsedRealtimeMs) { 13031 if (DEBUG_ENERGY) Slog.d(TAG, "Updating gnss stats: " + chargeUC); 13032 if (mGlobalMeasuredEnergyStats == null) { 13033 return; 13034 } 13035 13036 if (!mOnBatteryInternal || chargeUC <= 0) { 13037 // There's nothing further to update. 13038 return; 13039 } 13040 if (mIgnoreNextExternalStats) { 13041 // Although under ordinary resets we won't get here, and typically a new sync will 13042 // happen right after the reset, strictly speaking we need to set all mark times to now. 13043 final int uidStatsSize = mUidStats.size(); 13044 for (int i = 0; i < uidStatsSize; i++) { 13045 final Uid uid = mUidStats.valueAt(i); 13046 uid.markGnssTimeUs(elapsedRealtimeMs); 13047 } 13048 return; 13049 } 13050 13051 mGlobalMeasuredEnergyStats.updateStandardBucket(MeasuredEnergyStats.POWER_BUCKET_GNSS, 13052 chargeUC); 13053 13054 // Collect the per uid time since mark so that we can normalize power. 13055 final SparseDoubleArray gnssTimeUsArray = new SparseDoubleArray(); 13056 // TODO(b/175726779): Update and optimize the algorithm (e.g. avoid iterating over ALL uids) 13057 final int uidStatsSize = mUidStats.size(); 13058 for (int i = 0; i < uidStatsSize; i++) { 13059 final Uid uid = mUidStats.valueAt(i); 13060 final long gnssTimeUs = uid.markGnssTimeUs(elapsedRealtimeMs); 13061 if (gnssTimeUs == 0) continue; 13062 gnssTimeUsArray.put(uid.getUid(), (double) gnssTimeUs); 13063 } 13064 distributeEnergyToUidsLocked(MeasuredEnergyStats.POWER_BUCKET_GNSS, chargeUC, 13065 gnssTimeUsArray, 0); 13066 } 13067 13068 /** 13069 * Accumulate Custom power bucket charge, globally and for each app. 13070 * 13071 * @param totalChargeUC charge (microcoulombs) used for this bucket since this was last called. 13072 * @param uidCharges map of uid->charge (microcoulombs) for this bucket since last called. 13073 * Data inside uidCharges will not be modified (treated immutable). 13074 * Uids not already known to BatteryStats will be ignored. 13075 */ 13076 public void updateCustomMeasuredEnergyStatsLocked(int customPowerBucket, 13077 long totalChargeUC, @Nullable SparseLongArray uidCharges) { 13078 if (DEBUG_ENERGY) { 13079 Slog.d(TAG, "Updating attributed measured charge stats for custom bucket " 13080 + customPowerBucket 13081 + " with total charge " + totalChargeUC 13082 + " and uid charges " + String.valueOf(uidCharges)); 13083 } 13084 if (mGlobalMeasuredEnergyStats == null) return; 13085 if (!mOnBatteryInternal || mIgnoreNextExternalStats || totalChargeUC <= 0) return; 13086 13087 mGlobalMeasuredEnergyStats.updateCustomBucket(customPowerBucket, totalChargeUC); 13088 13089 if (uidCharges == null) return; 13090 final int numUids = uidCharges.size(); 13091 for (int i = 0; i < numUids; i++) { 13092 final int uidInt = mapUid(uidCharges.keyAt(i)); 13093 final long uidChargeUC = uidCharges.valueAt(i); 13094 if (uidChargeUC == 0) continue; 13095 final Uid uidObj = getAvailableUidStatsLocked(uidInt); 13096 if (uidObj != null) { 13097 uidObj.addChargeToCustomBucketLocked(uidChargeUC, customPowerBucket); 13098 } else { 13099 // Ignore any uid not already known to BatteryStats, rather than creating a new Uid. 13100 // Otherwise we could end up reviving dead Uids. Note that the CPU data is updated 13101 // first, so any uid that has used any CPU should already be known to BatteryStats. 13102 // Recently removed uids (especially common for isolated uids) can reach this path 13103 // and are ignored. 13104 if (!Process.isIsolated(uidInt)) { 13105 Slog.w(TAG, "Received measured charge " + totalChargeUC + " for custom bucket " 13106 + customPowerBucket + " for non-existent uid " + uidInt); 13107 } 13108 } 13109 } 13110 } 13111 13112 /** 13113 * Attributes energy (for the given bucket) to each uid according to the following formula: 13114 * blamedEnergy[uid] = totalEnergy * ratioNumerators[uid] / ratioDenominator; 13115 * <p>Does nothing if ratioDenominator is 0. 13116 * 13117 * <p>Here, ratioDenominator = max(sumOfAllRatioNumerators, minRatioDenominator), 13118 * so if given minRatioDenominator <= 0, then sumOfAllRatioNumerators will be used implicitly. 13119 * 13120 * <p>Note that ratioNumerators and minRatioDenominator must use the same units, but need not 13121 * use the same units as totalConsumedChargeUC (which must be in microcoulombs). 13122 * 13123 * <p>A consequence of minRatioDenominator is that the sum over all uids might be less than 13124 * totalConsumedChargeUC. This is intentional; the remainder is purposefully unnaccounted rather 13125 * than incorrectly blamed on uids, and implies unknown (non-uid) sources of drain. 13126 * 13127 * <p>All uids in ratioNumerators must exist in mUidStats already. 13128 */ 13129 private void distributeEnergyToUidsLocked(@StandardPowerBucket int bucket, 13130 long totalConsumedChargeUC, SparseDoubleArray ratioNumerators, 13131 double minRatioDenominator) { 13132 13133 // If the sum of all app usage was greater than the total, use that instead: 13134 double sumRatioNumerators = 0; 13135 for (int i = ratioNumerators.size() - 1; i >= 0; i--) { 13136 sumRatioNumerators += ratioNumerators.valueAt(i); 13137 } 13138 final double ratioDenominator = Math.max(sumRatioNumerators, minRatioDenominator); 13139 if (ratioDenominator <= 0) return; 13140 13141 for (int i = ratioNumerators.size() - 1; i >= 0; i--) { 13142 final Uid uid = getAvailableUidStatsLocked(ratioNumerators.keyAt(i)); 13143 final double ratioNumerator = ratioNumerators.valueAt(i); 13144 final long uidActualUC 13145 = (long) (totalConsumedChargeUC * ratioNumerator / ratioDenominator + 0.5); 13146 uid.addChargeToStandardBucketLocked(uidActualUC, bucket); 13147 } 13148 } 13149 13150 /** 13151 * Read and record Rail Energy data. 13152 */ 13153 public void updateRailStatsLocked() { 13154 if (mMeasuredEnergyRetriever == null || !mTmpRailStats.isRailStatsAvailable()) { 13155 return; 13156 } 13157 mMeasuredEnergyRetriever.fillRailDataStats(mTmpRailStats); 13158 } 13159 13160 /** Informs that external stats data has been completely flushed. */ 13161 public void informThatAllExternalStatsAreFlushed() { 13162 synchronized (this) { 13163 // Any data from the pre-reset era is flushed, so we can henceforth process future data. 13164 mIgnoreNextExternalStats = false; 13165 } 13166 } 13167 13168 /** 13169 * Read and distribute kernel wake lock use across apps. 13170 */ 13171 public void updateKernelWakelocksLocked() { 13172 updateKernelWakelocksLocked(mClocks.elapsedRealtime() * 1000); 13173 } 13174 13175 /** 13176 * @see #updateKernelWakelocksLocked() 13177 */ 13178 public void updateKernelWakelocksLocked(long elapsedRealtimeUs) { 13179 final KernelWakelockStats wakelockStats = mKernelWakelockReader.readKernelWakelockStats( 13180 mTmpWakelockStats); 13181 if (wakelockStats == null) { 13182 // Not crashing might make board bringup easier. 13183 Slog.w(TAG, "Couldn't get kernel wake lock stats"); 13184 return; 13185 } 13186 13187 for (Map.Entry<String, KernelWakelockStats.Entry> ent : wakelockStats.entrySet()) { 13188 String name = ent.getKey(); 13189 KernelWakelockStats.Entry kws = ent.getValue(); 13190 13191 SamplingTimer kwlt = mKernelWakelockStats.get(name); 13192 if (kwlt == null) { 13193 kwlt = new SamplingTimer(mClocks, mOnBatteryScreenOffTimeBase); 13194 mKernelWakelockStats.put(name, kwlt); 13195 } 13196 13197 kwlt.update(kws.mTotalTime, kws.mCount, elapsedRealtimeUs); 13198 kwlt.setUpdateVersion(kws.mVersion); 13199 } 13200 13201 int numWakelocksSetStale = 0; 13202 // Set timers to stale if they didn't appear in /d/wakeup_sources (or /proc/wakelocks) 13203 // this time. 13204 for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) { 13205 SamplingTimer st = ent.getValue(); 13206 if (st.getUpdateVersion() != wakelockStats.kernelWakelockVersion) { 13207 st.endSample(elapsedRealtimeUs); 13208 numWakelocksSetStale++; 13209 } 13210 } 13211 13212 // Record whether we've seen a non-zero time (for debugging b/22716723). 13213 if (wakelockStats.isEmpty()) { 13214 Slog.wtf(TAG, "All kernel wakelocks had time of zero"); 13215 } 13216 13217 if (numWakelocksSetStale == mKernelWakelockStats.size()) { 13218 Slog.wtf(TAG, "All kernel wakelocks were set stale. new version=" + 13219 wakelockStats.kernelWakelockVersion); 13220 } 13221 } 13222 13223 // We use an anonymous class to access these variables, 13224 // so they can't live on the stack or they'd have to be 13225 // final MutableLong objects (more allocations). 13226 // Used in updateCpuTimeLocked(). 13227 long mTempTotalCpuUserTimeUs; 13228 long mTempTotalCpuSystemTimeUs; 13229 long[][] mWakeLockAllocationsUs; 13230 13231 /** 13232 * Reads the newest memory stats from the kernel. 13233 */ 13234 public void updateKernelMemoryBandwidthLocked() { 13235 updateKernelMemoryBandwidthLocked(mClocks.elapsedRealtime() * 1000); 13236 } 13237 13238 public void updateKernelMemoryBandwidthLocked(long elapsedRealtimeUs) { 13239 mKernelMemoryBandwidthStats.updateStats(); 13240 LongSparseLongArray bandwidthEntries = mKernelMemoryBandwidthStats.getBandwidthEntries(); 13241 final int bandwidthEntryCount = bandwidthEntries.size(); 13242 int index; 13243 for (int i = 0; i < bandwidthEntryCount; i++) { 13244 SamplingTimer timer; 13245 if ((index = mKernelMemoryStats.indexOfKey(bandwidthEntries.keyAt(i))) >= 0) { 13246 timer = mKernelMemoryStats.valueAt(index); 13247 } else { 13248 timer = new SamplingTimer(mClocks, mOnBatteryTimeBase); 13249 mKernelMemoryStats.put(bandwidthEntries.keyAt(i), timer); 13250 } 13251 timer.update(bandwidthEntries.valueAt(i), 1, elapsedRealtimeUs); 13252 if (DEBUG_MEMORY) { 13253 Slog.d(TAG, String.format("Added entry %d and updated timer to: " 13254 + "mUnpluggedReportedTotalTimeUs %d size %d", bandwidthEntries.keyAt(i), 13255 mKernelMemoryStats.get( 13256 bandwidthEntries.keyAt(i)).mUnpluggedReportedTotalTimeUs, 13257 mKernelMemoryStats.size())); 13258 } 13259 } 13260 } 13261 13262 public boolean isOnBatteryLocked() { 13263 return mOnBatteryTimeBase.isRunning(); 13264 } 13265 13266 public boolean isOnBatteryScreenOffLocked() { 13267 return mOnBatteryScreenOffTimeBase.isRunning(); 13268 } 13269 13270 /** 13271 * Object for calculating and accumulating the estimated cpu power used while reading the 13272 * various cpu kernel files. 13273 */ 13274 @VisibleForTesting 13275 public static class CpuDeltaPowerAccumulator { 13276 // Keeps track of total charge used per cluster. 13277 public final double[] totalClusterChargesMah; 13278 // Keeps track of charge used per cluster per uid. 13279 public final ArrayMap<Uid, double[]> perUidCpuClusterChargesMah; 13280 13281 private final CpuPowerCalculator mCalculator; 13282 private Uid mCachedUid = null; 13283 private double[] mUidClusterCache = null; 13284 13285 CpuDeltaPowerAccumulator(CpuPowerCalculator calculator, int nClusters) { 13286 mCalculator = calculator; 13287 totalClusterChargesMah = new double[nClusters]; 13288 perUidCpuClusterChargesMah = new ArrayMap<>(); 13289 } 13290 13291 /** Add per cpu cluster durations to the currently cached uid. */ 13292 public void addCpuClusterDurationsMs(Uid uid, long[] durationsMs) { 13293 final double[] uidChargesMah = getOrCreateUidCpuClusterCharges(uid); 13294 for (int cluster = 0; cluster < durationsMs.length; cluster++) { 13295 final double estimatedDeltaMah = mCalculator.calculatePerCpuClusterPowerMah(cluster, 13296 durationsMs[cluster]); 13297 uidChargesMah[cluster] += estimatedDeltaMah; 13298 totalClusterChargesMah[cluster] += estimatedDeltaMah; 13299 } 13300 } 13301 13302 /** Add per speed per cpu cluster durations to the currently cached uid. */ 13303 public void addCpuClusterSpeedDurationsMs(Uid uid, int cluster, int speed, 13304 long durationsMs) { 13305 final double[] uidChargesMah = getOrCreateUidCpuClusterCharges(uid); 13306 final double estimatedDeltaMah = mCalculator.calculatePerCpuFreqPowerMah(cluster, speed, 13307 durationsMs); 13308 uidChargesMah[cluster] += estimatedDeltaMah; 13309 totalClusterChargesMah[cluster] += estimatedDeltaMah; 13310 } 13311 13312 private double[] getOrCreateUidCpuClusterCharges(Uid uid) { 13313 // Repeated additions on the same uid is very likely. 13314 // Skip a lookup if getting the same uid as the last get. 13315 if (uid == mCachedUid) return mUidClusterCache; 13316 13317 double[] uidChargesMah = perUidCpuClusterChargesMah.get(uid); 13318 if (uidChargesMah == null) { 13319 uidChargesMah = new double[totalClusterChargesMah.length]; 13320 perUidCpuClusterChargesMah.put(uid, uidChargesMah); 13321 } 13322 mCachedUid = uid; 13323 mUidClusterCache = uidChargesMah; 13324 return uidChargesMah; 13325 } 13326 } 13327 13328 /** 13329 * Read and distribute CPU usage across apps. If their are partial wakelocks being held 13330 * and we are on battery with screen off, we give more of the cpu time to those apps holding 13331 * wakelocks. If the screen is on, we just assign the actual cpu time an app used. 13332 * It's possible this will be invoked after the internal battery/screen states are updated, so 13333 * passing the appropriate battery/screen states to try attribute the cpu times to correct 13334 * buckets. 13335 */ 13336 @GuardedBy("this") 13337 public void updateCpuTimeLocked(boolean onBattery, boolean onBatteryScreenOff, 13338 long[] measuredCpuClusterChargeUC) { 13339 if (mPowerProfile == null) { 13340 return; 13341 } 13342 13343 if (DEBUG_ENERGY_CPU) { 13344 Slog.d(TAG, "!Cpu updating!"); 13345 } 13346 13347 if (mCpuFreqs == null) { 13348 mCpuFreqs = mCpuUidFreqTimeReader.readFreqs(mPowerProfile); 13349 } 13350 13351 // Calculate the wakelocks we have to distribute amongst. The system is excluded as it is 13352 // usually holding the wakelock on behalf of an app. 13353 // And Only distribute cpu power to wakelocks if the screen is off and we're on battery. 13354 ArrayList<StopwatchTimer> partialTimersToConsider = null; 13355 if (onBatteryScreenOff) { 13356 partialTimersToConsider = new ArrayList<>(); 13357 for (int i = mPartialTimers.size() - 1; i >= 0; --i) { 13358 final StopwatchTimer timer = mPartialTimers.get(i); 13359 // Since the collection and blaming of wakelocks can be scheduled to run after 13360 // some delay, the mPartialTimers list may have new entries. We can't blame 13361 // the newly added timer for past cpu time, so we only consider timers that 13362 // were present for one round of collection. Once a timer has gone through 13363 // a round of collection, its mInList field is set to true. 13364 if (timer.mInList && timer.mUid != null && timer.mUid.mUid != Process.SYSTEM_UID) { 13365 partialTimersToConsider.add(timer); 13366 } 13367 } 13368 } 13369 markPartialTimersAsEligible(); 13370 13371 // When the battery is not on, we don't attribute the cpu times to any timers but we still 13372 // need to take the snapshots. 13373 if (!onBattery) { 13374 mCpuUidUserSysTimeReader.readDelta(false, null); 13375 mCpuUidFreqTimeReader.readDelta(false, null); 13376 mNumAllUidCpuTimeReads += 2; 13377 if (mConstants.TRACK_CPU_ACTIVE_CLUSTER_TIME) { 13378 mCpuUidActiveTimeReader.readDelta(false, null); 13379 mCpuUidClusterTimeReader.readDelta(false, null); 13380 mNumAllUidCpuTimeReads += 2; 13381 } 13382 for (int cluster = mKernelCpuSpeedReaders.length - 1; cluster >= 0; --cluster) { 13383 mKernelCpuSpeedReaders[cluster].readDelta(); 13384 } 13385 mSystemServerCpuThreadReader.readDelta(); 13386 return; 13387 } 13388 13389 mUserInfoProvider.refreshUserIds(); 13390 final SparseLongArray updatedUids = mCpuUidFreqTimeReader.perClusterTimesAvailable() 13391 ? null : new SparseLongArray(); 13392 13393 final CpuDeltaPowerAccumulator powerAccumulator; 13394 if (mGlobalMeasuredEnergyStats != null 13395 && mGlobalMeasuredEnergyStats.isStandardBucketSupported( 13396 MeasuredEnergyStats.POWER_BUCKET_CPU) && mCpuPowerCalculator != null) { 13397 if (measuredCpuClusterChargeUC == null) { 13398 Slog.wtf(TAG, 13399 "POWER_BUCKET_CPU supported but no measured Cpu Cluster charge reported " 13400 + "on updateCpuTimeLocked!"); 13401 powerAccumulator = null; 13402 } else { 13403 // Cpu Measured Energy is supported, create an object to accumulate the estimated 13404 // charge consumption since the last cpu update 13405 final int numClusters = mPowerProfile.getNumCpuClusters(); 13406 powerAccumulator = new CpuDeltaPowerAccumulator(mCpuPowerCalculator, numClusters); 13407 } 13408 } else { 13409 powerAccumulator = null; 13410 } 13411 13412 readKernelUidCpuTimesLocked(partialTimersToConsider, updatedUids, onBattery); 13413 // updatedUids=null means /proc/uid_time_in_state provides snapshots of per-cluster cpu 13414 // freqs, so no need to approximate these values. 13415 if (updatedUids != null) { 13416 updateClusterSpeedTimes(updatedUids, onBattery, powerAccumulator); 13417 } 13418 readKernelUidCpuFreqTimesLocked(partialTimersToConsider, onBattery, onBatteryScreenOff, 13419 powerAccumulator); 13420 mNumAllUidCpuTimeReads += 2; 13421 if (mConstants.TRACK_CPU_ACTIVE_CLUSTER_TIME) { 13422 // Cpu Active times do not get any info ony how to attribute measured Cpu Cluster 13423 // charge, so not need to provide the powerAccumulator 13424 readKernelUidCpuActiveTimesLocked(onBattery); 13425 readKernelUidCpuClusterTimesLocked(onBattery, powerAccumulator); 13426 mNumAllUidCpuTimeReads += 2; 13427 } 13428 13429 updateSystemServerThreadStats(); 13430 13431 if (powerAccumulator != null) { 13432 updateCpuMeasuredEnergyStatsLocked(measuredCpuClusterChargeUC, powerAccumulator); 13433 } 13434 } 13435 13436 /** 13437 * Estimates the proportion of the System Server CPU activity (per cluster per speed) 13438 * spent on handling incoming binder calls. 13439 */ 13440 @VisibleForTesting 13441 public void updateSystemServerThreadStats() { 13442 // There are some simplifying assumptions made in this algorithm 13443 // 1) We assume that if a thread handles incoming binder calls, all of its activity 13444 // is spent doing that. Most incoming calls are handled by threads allocated 13445 // by the native layer in the binder thread pool, so this assumption is reasonable. 13446 // 2) We use the aggregate CPU time spent in different threads as a proxy for the CPU 13447 // cost. In reality, in multi-core CPUs, the CPU cost may not be linearly 13448 // affected by additional threads. 13449 13450 SystemServerCpuThreadReader.SystemServiceCpuThreadTimes systemServiceCpuThreadTimes = 13451 mSystemServerCpuThreadReader.readDelta(); 13452 if (systemServiceCpuThreadTimes == null) { 13453 return; 13454 } 13455 13456 if (mBinderThreadCpuTimesUs == null) { 13457 mBinderThreadCpuTimesUs = new LongSamplingCounterArray(mOnBatteryTimeBase); 13458 } 13459 mBinderThreadCpuTimesUs.addCountLocked(systemServiceCpuThreadTimes.binderThreadCpuTimesUs); 13460 13461 if (DEBUG_BINDER_STATS) { 13462 Slog.d(TAG, "System server threads per CPU cluster (incoming binder threads)"); 13463 long binderThreadTimeMs = 0; 13464 int cpuIndex = 0; 13465 final long[] binderThreadCpuTimesUs = mBinderThreadCpuTimesUs.getCountsLocked( 13466 BatteryStats.STATS_SINCE_CHARGED); 13467 int index = 0; 13468 int numCpuClusters = mPowerProfile.getNumCpuClusters(); 13469 for (int cluster = 0; cluster < numCpuClusters; cluster++) { 13470 StringBuilder sb = new StringBuilder(); 13471 sb.append("cpu").append(cpuIndex).append(": ["); 13472 int numSpeeds = mPowerProfile.getNumSpeedStepsInCpuCluster(cluster); 13473 for (int speed = 0; speed < numSpeeds; speed++) { 13474 if (speed != 0) { 13475 sb.append(", "); 13476 } 13477 long binderCountMs = binderThreadCpuTimesUs[index] / 1000; 13478 sb.append(TextUtils.formatSimple("%10d", binderCountMs)); 13479 13480 binderThreadTimeMs += binderCountMs; 13481 index++; 13482 } 13483 cpuIndex += mPowerProfile.getNumCoresInCpuCluster(cluster); 13484 Slog.d(TAG, sb.toString()); 13485 } 13486 } 13487 } 13488 13489 /** 13490 * Mark the current partial timers as gone through a collection so that they will be 13491 * considered in the next cpu times distribution to wakelock holders. 13492 */ 13493 @VisibleForTesting 13494 public void markPartialTimersAsEligible() { 13495 if (ArrayUtils.referenceEquals(mPartialTimers, mLastPartialTimers)) { 13496 // No difference, so each timer is now considered for the next collection. 13497 for (int i = mPartialTimers.size() - 1; i >= 0; --i) { 13498 mPartialTimers.get(i).mInList = true; 13499 } 13500 } else { 13501 // The lists are different, meaning we added (or removed a timer) since the last 13502 // collection. 13503 for (int i = mLastPartialTimers.size() - 1; i >= 0; --i) { 13504 mLastPartialTimers.get(i).mInList = false; 13505 } 13506 mLastPartialTimers.clear(); 13507 13508 // Mark the current timers as gone through a collection. 13509 final int numPartialTimers = mPartialTimers.size(); 13510 for (int i = 0; i < numPartialTimers; ++i) { 13511 final StopwatchTimer timer = mPartialTimers.get(i); 13512 timer.mInList = true; 13513 mLastPartialTimers.add(timer); 13514 } 13515 } 13516 } 13517 13518 /** 13519 * Take snapshot of cpu times (aggregated over all uids) at different frequencies and 13520 * calculate cpu times spent by each uid at different frequencies. Will also add estimated 13521 * power consumptions, if powerAccumulator data structure is provided. 13522 * 13523 * @param updatedUids The uids for which times spent at different frequencies are calculated. 13524 * @param onBattery whether or not this is onBattery 13525 * @param powerAccumulator object to accumulate the estimated cluster charge consumption. 13526 */ 13527 @VisibleForTesting 13528 public void updateClusterSpeedTimes(@NonNull SparseLongArray updatedUids, boolean onBattery, 13529 @Nullable CpuDeltaPowerAccumulator powerAccumulator) { 13530 long totalCpuClustersTimeMs = 0; 13531 // Read the time spent for each cluster at various cpu frequencies. 13532 final long[][] clusterSpeedTimesMs = new long[mKernelCpuSpeedReaders.length][]; 13533 for (int cluster = 0; cluster < mKernelCpuSpeedReaders.length; cluster++) { 13534 clusterSpeedTimesMs[cluster] = mKernelCpuSpeedReaders[cluster].readDelta(); 13535 if (clusterSpeedTimesMs[cluster] != null) { 13536 for (int speed = clusterSpeedTimesMs[cluster].length - 1; speed >= 0; --speed) { 13537 totalCpuClustersTimeMs += clusterSpeedTimesMs[cluster][speed]; 13538 } 13539 } 13540 } 13541 if (totalCpuClustersTimeMs != 0) { 13542 // We have cpu times per freq aggregated over all uids but we need the times per uid. 13543 // So, we distribute total time spent by an uid to different cpu freqs based on the 13544 // amount of time cpu was running at that freq. 13545 final int updatedUidsCount = updatedUids.size(); 13546 final long elapsedRealtimeMs = mClocks.elapsedRealtime(); 13547 final long uptimeMs = mClocks.uptimeMillis(); 13548 for (int i = 0; i < updatedUidsCount; ++i) { 13549 final Uid u = getUidStatsLocked(updatedUids.keyAt(i), elapsedRealtimeMs, uptimeMs); 13550 final long appCpuTimeUs = updatedUids.valueAt(i); 13551 // Add the cpu speeds to this UID. 13552 final int numClusters = mPowerProfile.getNumCpuClusters(); 13553 if (u.mCpuClusterSpeedTimesUs == null || 13554 u.mCpuClusterSpeedTimesUs.length != numClusters) { 13555 u.mCpuClusterSpeedTimesUs = new LongSamplingCounter[numClusters][]; 13556 } 13557 13558 for (int cluster = 0; cluster < clusterSpeedTimesMs.length; cluster++) { 13559 final int speedsInCluster = clusterSpeedTimesMs[cluster].length; 13560 if (u.mCpuClusterSpeedTimesUs[cluster] == null || speedsInCluster != 13561 u.mCpuClusterSpeedTimesUs[cluster].length) { 13562 u.mCpuClusterSpeedTimesUs[cluster] 13563 = new LongSamplingCounter[speedsInCluster]; 13564 } 13565 13566 final LongSamplingCounter[] cpuSpeeds = u.mCpuClusterSpeedTimesUs[cluster]; 13567 for (int speed = 0; speed < speedsInCluster; speed++) { 13568 if (cpuSpeeds[speed] == null) { 13569 cpuSpeeds[speed] = new LongSamplingCounter(mOnBatteryTimeBase); 13570 } 13571 final long deltaSpeedCount = appCpuTimeUs 13572 * clusterSpeedTimesMs[cluster][speed] 13573 / totalCpuClustersTimeMs; 13574 cpuSpeeds[speed].addCountLocked(deltaSpeedCount, onBattery); 13575 13576 if (powerAccumulator != null) { 13577 powerAccumulator.addCpuClusterSpeedDurationsMs(u, cluster, 13578 speed, deltaSpeedCount); 13579 } 13580 } 13581 } 13582 } 13583 } 13584 } 13585 13586 /** 13587 * Take a snapshot of the cpu times spent by each uid and update the corresponding counters. 13588 * If {@param partialTimers} is not null and empty, then we assign a portion of cpu times to 13589 * wakelock holders. 13590 * 13591 * @param partialTimers The wakelock holders among which the cpu times will be distributed. 13592 * @param updatedUids If not null, then the uids found in the snapshot will be added to this. 13593 */ 13594 @VisibleForTesting 13595 public void readKernelUidCpuTimesLocked(@Nullable ArrayList<StopwatchTimer> partialTimers, 13596 @Nullable SparseLongArray updatedUids, boolean onBattery) { 13597 mTempTotalCpuUserTimeUs = mTempTotalCpuSystemTimeUs = 0; 13598 final int numWakelocks = partialTimers == null ? 0 : partialTimers.size(); 13599 final long startTimeMs = mClocks.uptimeMillis(); 13600 final long elapsedRealtimeMs = mClocks.elapsedRealtime(); 13601 13602 mCpuUidUserSysTimeReader.readDelta(false, (uid, timesUs) -> { 13603 long userTimeUs = timesUs[0], systemTimeUs = timesUs[1]; 13604 13605 uid = mapUid(uid); 13606 if (Process.isIsolated(uid)) { 13607 // This could happen if the isolated uid mapping was removed before that process 13608 // was actually killed. 13609 if (DEBUG) Slog.d(TAG, "Got readings for an isolated uid: " + uid); 13610 return; 13611 } 13612 if (!mUserInfoProvider.exists(UserHandle.getUserId(uid))) { 13613 if (DEBUG) Slog.d(TAG, "Got readings for an invalid user's uid " + uid); 13614 return; 13615 } 13616 final Uid u = getUidStatsLocked(uid, elapsedRealtimeMs, startTimeMs); 13617 13618 // Accumulate the total system and user time. 13619 mTempTotalCpuUserTimeUs += userTimeUs; 13620 mTempTotalCpuSystemTimeUs += systemTimeUs; 13621 13622 StringBuilder sb = null; 13623 if (DEBUG_ENERGY_CPU) { 13624 sb = new StringBuilder(); 13625 sb.append(" got time for uid=").append(u.mUid).append(": u="); 13626 TimeUtils.formatDuration(userTimeUs / 1000, sb); 13627 sb.append(" s="); 13628 TimeUtils.formatDuration(systemTimeUs / 1000, sb); 13629 sb.append("\n"); 13630 } 13631 13632 if (numWakelocks > 0) { 13633 // We have wakelocks being held, so only give a portion of the 13634 // time to the process. The rest will be distributed among wakelock 13635 // holders. 13636 userTimeUs = (userTimeUs * WAKE_LOCK_WEIGHT) / 100; 13637 systemTimeUs = (systemTimeUs * WAKE_LOCK_WEIGHT) / 100; 13638 } 13639 13640 if (sb != null) { 13641 sb.append(" adding to uid=").append(u.mUid).append(": u="); 13642 TimeUtils.formatDuration(userTimeUs / 1000, sb); 13643 sb.append(" s="); 13644 TimeUtils.formatDuration(systemTimeUs / 1000, sb); 13645 Slog.d(TAG, sb.toString()); 13646 } 13647 13648 u.mUserCpuTime.addCountLocked(userTimeUs, onBattery); 13649 u.mSystemCpuTime.addCountLocked(systemTimeUs, onBattery); 13650 if (updatedUids != null) { 13651 updatedUids.put(u.getUid(), userTimeUs + systemTimeUs); 13652 } 13653 }); 13654 13655 final long elapsedTimeMs = mClocks.uptimeMillis() - startTimeMs; 13656 if (DEBUG_ENERGY_CPU || elapsedTimeMs >= 100) { 13657 Slog.d(TAG, "Reading cpu stats took " + elapsedTimeMs + "ms"); 13658 } 13659 13660 if (numWakelocks > 0) { 13661 // Distribute a portion of the total cpu time to wakelock holders. 13662 mTempTotalCpuUserTimeUs = (mTempTotalCpuUserTimeUs * (100 - WAKE_LOCK_WEIGHT)) / 100; 13663 mTempTotalCpuSystemTimeUs = 13664 (mTempTotalCpuSystemTimeUs * (100 - WAKE_LOCK_WEIGHT)) / 100; 13665 13666 for (int i = 0; i < numWakelocks; ++i) { 13667 final StopwatchTimer timer = partialTimers.get(i); 13668 final int userTimeUs = (int) (mTempTotalCpuUserTimeUs / (numWakelocks - i)); 13669 final int systemTimeUs = (int) (mTempTotalCpuSystemTimeUs / (numWakelocks - i)); 13670 13671 if (DEBUG_ENERGY_CPU) { 13672 final StringBuilder sb = new StringBuilder(); 13673 sb.append(" Distributing wakelock uid=").append(timer.mUid.mUid) 13674 .append(": u="); 13675 TimeUtils.formatDuration(userTimeUs / 1000, sb); 13676 sb.append(" s="); 13677 TimeUtils.formatDuration(systemTimeUs / 1000, sb); 13678 Slog.d(TAG, sb.toString()); 13679 } 13680 13681 timer.mUid.mUserCpuTime.addCountLocked(userTimeUs, onBattery); 13682 timer.mUid.mSystemCpuTime.addCountLocked(systemTimeUs, onBattery); 13683 if (updatedUids != null) { 13684 final int uid = timer.mUid.getUid(); 13685 updatedUids.put(uid, updatedUids.get(uid, 0) + userTimeUs + systemTimeUs); 13686 } 13687 13688 final Uid.Proc proc = timer.mUid.getProcessStatsLocked("*wakelock*"); 13689 proc.addCpuTimeLocked(userTimeUs / 1000, systemTimeUs / 1000, onBattery); 13690 13691 mTempTotalCpuUserTimeUs -= userTimeUs; 13692 mTempTotalCpuSystemTimeUs -= systemTimeUs; 13693 } 13694 } 13695 } 13696 13697 /** 13698 * Take a snapshot of the cpu times spent by each uid in each freq and update the 13699 * corresponding counters. Will also add estimated power consumptions, if powerAccumulator 13700 * data structure is provided. 13701 * 13702 * @param partialTimers The wakelock holders among which the cpu freq times will be distributed. 13703 * @param onBattery whether or not this is onBattery 13704 * @param onBatteryScreenOff whether or not this is onBattery with the screen off. 13705 * @param powerAccumulator object to accumulate the estimated cluster charge consumption. 13706 */ 13707 @VisibleForTesting 13708 public void readKernelUidCpuFreqTimesLocked(@Nullable ArrayList<StopwatchTimer> partialTimers, 13709 boolean onBattery, boolean onBatteryScreenOff, 13710 @Nullable CpuDeltaPowerAccumulator powerAccumulator) { 13711 final boolean perClusterTimesAvailable = 13712 mCpuUidFreqTimeReader.perClusterTimesAvailable(); 13713 final int numWakelocks = partialTimers == null ? 0 : partialTimers.size(); 13714 final int numClusters = mPowerProfile.getNumCpuClusters(); 13715 mWakeLockAllocationsUs = null; 13716 final long startTimeMs = mClocks.uptimeMillis(); 13717 final long elapsedRealtimeMs = mClocks.elapsedRealtime(); 13718 // If power is being accumulated for attribution, data needs to be read immediately. 13719 final boolean forceRead = powerAccumulator != null; 13720 mCpuUidFreqTimeReader.readDelta(forceRead, (uid, cpuFreqTimeMs) -> { 13721 uid = mapUid(uid); 13722 if (Process.isIsolated(uid)) { 13723 if (DEBUG) Slog.d(TAG, "Got freq readings for an isolated uid: " + uid); 13724 return; 13725 } 13726 if (!mUserInfoProvider.exists(UserHandle.getUserId(uid))) { 13727 if (DEBUG) Slog.d(TAG, "Got freq readings for an invalid user's uid " + uid); 13728 return; 13729 } 13730 final Uid u = getUidStatsLocked(uid, elapsedRealtimeMs, startTimeMs); 13731 if (u.mCpuFreqTimeMs == null || u.mCpuFreqTimeMs.getSize() != cpuFreqTimeMs.length) { 13732 detachIfNotNull(u.mCpuFreqTimeMs); 13733 u.mCpuFreqTimeMs = new LongSamplingCounterArray(mOnBatteryTimeBase); 13734 } 13735 u.mCpuFreqTimeMs.addCountLocked(cpuFreqTimeMs, onBattery); 13736 if (u.mScreenOffCpuFreqTimeMs == null || 13737 u.mScreenOffCpuFreqTimeMs.getSize() != cpuFreqTimeMs.length) { 13738 detachIfNotNull(u.mScreenOffCpuFreqTimeMs); 13739 u.mScreenOffCpuFreqTimeMs = new LongSamplingCounterArray( 13740 mOnBatteryScreenOffTimeBase); 13741 } 13742 u.mScreenOffCpuFreqTimeMs.addCountLocked(cpuFreqTimeMs, onBatteryScreenOff); 13743 13744 if (perClusterTimesAvailable) { 13745 if (u.mCpuClusterSpeedTimesUs == null || 13746 u.mCpuClusterSpeedTimesUs.length != numClusters) { 13747 detachIfNotNull(u.mCpuClusterSpeedTimesUs); 13748 u.mCpuClusterSpeedTimesUs = new LongSamplingCounter[numClusters][]; 13749 } 13750 if (numWakelocks > 0 && mWakeLockAllocationsUs == null) { 13751 mWakeLockAllocationsUs = new long[numClusters][]; 13752 } 13753 13754 int freqIndex = 0; 13755 for (int cluster = 0; cluster < numClusters; ++cluster) { 13756 final int speedsInCluster = mPowerProfile.getNumSpeedStepsInCpuCluster(cluster); 13757 if (u.mCpuClusterSpeedTimesUs[cluster] == null || 13758 u.mCpuClusterSpeedTimesUs[cluster].length != speedsInCluster) { 13759 detachIfNotNull(u.mCpuClusterSpeedTimesUs[cluster]); 13760 u.mCpuClusterSpeedTimesUs[cluster] 13761 = new LongSamplingCounter[speedsInCluster]; 13762 } 13763 if (numWakelocks > 0 && mWakeLockAllocationsUs[cluster] == null) { 13764 mWakeLockAllocationsUs[cluster] = new long[speedsInCluster]; 13765 } 13766 final LongSamplingCounter[] cpuTimesUs = u.mCpuClusterSpeedTimesUs[cluster]; 13767 for (int speed = 0; speed < speedsInCluster; ++speed) { 13768 if (cpuTimesUs[speed] == null) { 13769 cpuTimesUs[speed] = new LongSamplingCounter(mOnBatteryTimeBase); 13770 } 13771 final long appAllocationUs; 13772 if (mWakeLockAllocationsUs != null) { 13773 appAllocationUs = 13774 (cpuFreqTimeMs[freqIndex] * 1000 * WAKE_LOCK_WEIGHT) / 100; 13775 mWakeLockAllocationsUs[cluster][speed] += 13776 (cpuFreqTimeMs[freqIndex] * 1000 - appAllocationUs); 13777 } else { 13778 appAllocationUs = cpuFreqTimeMs[freqIndex] * 1000; 13779 } 13780 cpuTimesUs[speed].addCountLocked(appAllocationUs, onBattery); 13781 13782 if (powerAccumulator != null) { 13783 powerAccumulator.addCpuClusterSpeedDurationsMs(u, cluster, 13784 speed, appAllocationUs / 1000); 13785 } 13786 freqIndex++; 13787 } 13788 } 13789 } 13790 }); 13791 13792 final long elapsedTimeMs = mClocks.uptimeMillis() - startTimeMs; 13793 if (DEBUG_ENERGY_CPU || elapsedTimeMs >= 100) { 13794 Slog.d(TAG, "Reading cpu freq times took " + elapsedTimeMs + "ms"); 13795 } 13796 13797 if (mWakeLockAllocationsUs != null) { 13798 for (int i = 0; i < numWakelocks; ++i) { 13799 final Uid u = partialTimers.get(i).mUid; 13800 if (u.mCpuClusterSpeedTimesUs == null || 13801 u.mCpuClusterSpeedTimesUs.length != numClusters) { 13802 detachIfNotNull(u.mCpuClusterSpeedTimesUs); 13803 u.mCpuClusterSpeedTimesUs = new LongSamplingCounter[numClusters][]; 13804 } 13805 13806 for (int cluster = 0; cluster < numClusters; ++cluster) { 13807 final int speedsInCluster = mPowerProfile.getNumSpeedStepsInCpuCluster(cluster); 13808 if (u.mCpuClusterSpeedTimesUs[cluster] == null || 13809 u.mCpuClusterSpeedTimesUs[cluster].length != speedsInCluster) { 13810 detachIfNotNull(u.mCpuClusterSpeedTimesUs[cluster]); 13811 u.mCpuClusterSpeedTimesUs[cluster] 13812 = new LongSamplingCounter[speedsInCluster]; 13813 } 13814 final LongSamplingCounter[] cpuTimeUs = u.mCpuClusterSpeedTimesUs[cluster]; 13815 for (int speed = 0; speed < speedsInCluster; ++speed) { 13816 if (cpuTimeUs[speed] == null) { 13817 cpuTimeUs[speed] = new LongSamplingCounter(mOnBatteryTimeBase); 13818 } 13819 final long allocationUs = 13820 mWakeLockAllocationsUs[cluster][speed] / (numWakelocks - i); 13821 cpuTimeUs[speed].addCountLocked(allocationUs, onBattery); 13822 mWakeLockAllocationsUs[cluster][speed] -= allocationUs; 13823 13824 if (powerAccumulator != null) { 13825 powerAccumulator.addCpuClusterSpeedDurationsMs(u, cluster, 13826 speed, allocationUs / 1000); 13827 } 13828 } 13829 } 13830 } 13831 } 13832 } 13833 13834 /** 13835 * Take a snapshot of the cpu active times spent by each uid and update the corresponding 13836 * counters. 13837 */ 13838 @VisibleForTesting 13839 public void readKernelUidCpuActiveTimesLocked(boolean onBattery) { 13840 final long startTimeMs = mClocks.uptimeMillis(); 13841 final long elapsedRealtimeMs = mClocks.elapsedRealtime(); 13842 mCpuUidActiveTimeReader.readDelta(false, (uid, cpuActiveTimesMs) -> { 13843 uid = mapUid(uid); 13844 if (Process.isIsolated(uid)) { 13845 if (DEBUG) Slog.w(TAG, "Got active times for an isolated uid: " + uid); 13846 return; 13847 } 13848 if (!mUserInfoProvider.exists(UserHandle.getUserId(uid))) { 13849 if (DEBUG) Slog.w(TAG, "Got active times for an invalid user's uid " + uid); 13850 return; 13851 } 13852 final Uid u = getUidStatsLocked(uid, elapsedRealtimeMs, startTimeMs); 13853 u.mCpuActiveTimeMs.addCountLocked(cpuActiveTimesMs, onBattery); 13854 }); 13855 13856 final long elapsedTimeMs = mClocks.uptimeMillis() - startTimeMs; 13857 if (DEBUG_ENERGY_CPU || elapsedTimeMs >= 100) { 13858 Slog.d(TAG, "Reading cpu active times took " + elapsedTimeMs + "ms"); 13859 } 13860 } 13861 13862 /** 13863 * Take a snapshot of the cpu cluster times spent by each uid and update the corresponding 13864 * counters. Will also add estimated power consumptions, if powerAccumulator data structure 13865 * is provided. 13866 * 13867 * @param onBattery whether or not this is onBattery 13868 * @param powerAccumulator object to accumulate the estimated cluster charge consumption. 13869 */ 13870 @VisibleForTesting 13871 public void readKernelUidCpuClusterTimesLocked(boolean onBattery, 13872 @Nullable CpuDeltaPowerAccumulator powerAccumulator) { 13873 final long startTimeMs = mClocks.uptimeMillis(); 13874 final long elapsedRealtimeMs = mClocks.elapsedRealtime(); 13875 // If power is being accumulated for attribution, data needs to be read immediately. 13876 final boolean forceRead = powerAccumulator != null; 13877 mCpuUidClusterTimeReader.readDelta(forceRead, (uid, cpuClusterTimesMs) -> { 13878 uid = mapUid(uid); 13879 if (Process.isIsolated(uid)) { 13880 if (DEBUG) Slog.w(TAG, "Got cluster times for an isolated uid: " + uid); 13881 return; 13882 } 13883 if (!mUserInfoProvider.exists(UserHandle.getUserId(uid))) { 13884 if (DEBUG) Slog.w(TAG, "Got cluster times for an invalid user's uid " + uid); 13885 return; 13886 } 13887 final Uid u = getUidStatsLocked(uid, elapsedRealtimeMs, startTimeMs); 13888 u.mCpuClusterTimesMs.addCountLocked(cpuClusterTimesMs, onBattery); 13889 13890 if (powerAccumulator != null) { 13891 powerAccumulator.addCpuClusterDurationsMs(u, cpuClusterTimesMs); 13892 } 13893 }); 13894 13895 final long elapsedTimeMs = mClocks.uptimeMillis() - startTimeMs; 13896 if (DEBUG_ENERGY_CPU || elapsedTimeMs >= 100) { 13897 Slog.d(TAG, "Reading cpu cluster times took " + elapsedTimeMs + "ms"); 13898 } 13899 } 13900 13901 boolean setChargingLocked(boolean charging) { 13902 // if the device is no longer charging, remove the callback 13903 // if the device is now charging, it means that this is either called 13904 // 1. directly when level >= 90 13905 // 2. or from within the runnable that we deferred 13906 // For 1. if we have an existing callback, remove it, since we will immediately send a 13907 // ACTION_CHARGING 13908 // For 2. we remove existing callback so we don't send multiple ACTION_CHARGING 13909 mHandler.removeCallbacks(mDeferSetCharging); 13910 if (mCharging != charging) { 13911 mCharging = charging; 13912 if (charging) { 13913 mHistoryCur.states2 |= HistoryItem.STATE2_CHARGING_FLAG; 13914 } else { 13915 mHistoryCur.states2 &= ~HistoryItem.STATE2_CHARGING_FLAG; 13916 } 13917 mHandler.sendEmptyMessage(MSG_REPORT_CHARGING); 13918 return true; 13919 } 13920 return false; 13921 } 13922 13923 /** 13924 * Notifies BatteryStatsImpl that the system server is ready. 13925 */ 13926 public void onSystemReady() { 13927 mSystemReady = true; 13928 } 13929 13930 @GuardedBy("this") 13931 protected void setOnBatteryLocked(final long mSecRealtime, final long mSecUptime, 13932 final boolean onBattery, final int oldStatus, final int level, final int chargeUah) { 13933 boolean doWrite = false; 13934 Message m = mHandler.obtainMessage(MSG_REPORT_POWER_CHANGE); 13935 m.arg1 = onBattery ? 1 : 0; 13936 mHandler.sendMessage(m); 13937 13938 final long uptimeUs = mSecUptime * 1000; 13939 final long realtimeUs = mSecRealtime * 1000; 13940 final int screenState = mScreenState; 13941 if (onBattery) { 13942 // We will reset our status if we are unplugging after the 13943 // battery was last full, or the level is at 100, or 13944 // we have gone through a significant charge (from a very low 13945 // level to a now very high level). 13946 // Also, we will reset the stats if battery got partially charged 13947 // and discharged repeatedly without ever reaching the full charge. 13948 // This reset is done in order to prevent stats sessions from going on forever. 13949 // Exceedingly long battery sessions would lead to an overflow of 13950 // data structures such as mWakeupReasonStats. 13951 boolean reset = false; 13952 if (!mNoAutoReset && mSystemReady 13953 && (oldStatus == BatteryManager.BATTERY_STATUS_FULL 13954 || level >= 90 13955 || (mDischargeCurrentLevel < 20 && level >= 80) 13956 || getHighDischargeAmountSinceCharge() >= 200)) { 13957 Slog.i(TAG, "Resetting battery stats: level=" + level + " status=" + oldStatus 13958 + " dischargeLevel=" + mDischargeCurrentLevel 13959 + " lowAmount=" + getLowDischargeAmountSinceCharge() 13960 + " highAmount=" + getHighDischargeAmountSinceCharge()); 13961 // Before we write, collect a snapshot of the final aggregated 13962 // stats to be reported in the next checkin. Only do this if we have 13963 // a sufficient amount of data to make it interesting. 13964 if (getLowDischargeAmountSinceCharge() >= 20) { 13965 final long startTimeMs = SystemClock.uptimeMillis(); 13966 final Parcel parcel = Parcel.obtain(); 13967 writeSummaryToParcel(parcel, true); 13968 final long initialTimeMs = SystemClock.uptimeMillis() - startTimeMs; 13969 BackgroundThread.getHandler().post(new Runnable() { 13970 @Override public void run() { 13971 synchronized (mCheckinFile) { 13972 final long startTimeMs2 = SystemClock.uptimeMillis(); 13973 FileOutputStream stream = null; 13974 try { 13975 stream = mCheckinFile.startWrite(); 13976 stream.write(parcel.marshall()); 13977 stream.flush(); 13978 mCheckinFile.finishWrite(stream); 13979 com.android.internal.logging.EventLogTags.writeCommitSysConfigFile( 13980 "batterystats-checkin", initialTimeMs 13981 + SystemClock.uptimeMillis() - startTimeMs2); 13982 } catch (IOException e) { 13983 Slog.w("BatteryStats", 13984 "Error writing checkin battery statistics", e); 13985 mCheckinFile.failWrite(stream); 13986 } finally { 13987 parcel.recycle(); 13988 } 13989 } 13990 } 13991 }); 13992 } 13993 doWrite = true; 13994 resetAllStatsLocked(mSecUptime, mSecRealtime, RESET_REASON_FULL_CHARGE); 13995 if (chargeUah > 0 && level > 0) { 13996 // Only use the reported coulomb charge value if it is supported and reported. 13997 mEstimatedBatteryCapacityMah = (int) ((chargeUah / 1000) / (level / 100.0)); 13998 } 13999 mDischargeStartLevel = level; 14000 reset = true; 14001 mDischargeStepTracker.init(); 14002 } 14003 if (mCharging) { 14004 setChargingLocked(false); 14005 } 14006 mLastChargingStateLevel = level; 14007 mOnBattery = mOnBatteryInternal = true; 14008 mLastDischargeStepLevel = level; 14009 mMinDischargeStepLevel = level; 14010 mDischargeStepTracker.clearTime(); 14011 mDailyDischargeStepTracker.clearTime(); 14012 mInitStepMode = mCurStepMode; 14013 mModStepMode = 0; 14014 pullPendingStateUpdatesLocked(); 14015 mHistoryCur.batteryLevel = (byte)level; 14016 mHistoryCur.states &= ~HistoryItem.STATE_BATTERY_PLUGGED_FLAG; 14017 if (DEBUG_HISTORY) Slog.v(TAG, "Battery unplugged to: " 14018 + Integer.toHexString(mHistoryCur.states)); 14019 if (reset) { 14020 mRecordingHistory = true; 14021 startRecordingHistory(mSecRealtime, mSecUptime, reset); 14022 } 14023 addHistoryRecordLocked(mSecRealtime, mSecUptime); 14024 mDischargeCurrentLevel = mDischargeUnplugLevel = level; 14025 if (Display.isOnState(screenState)) { 14026 mDischargeScreenOnUnplugLevel = level; 14027 mDischargeScreenDozeUnplugLevel = 0; 14028 mDischargeScreenOffUnplugLevel = 0; 14029 } else if (Display.isDozeState(screenState)) { 14030 mDischargeScreenOnUnplugLevel = 0; 14031 mDischargeScreenDozeUnplugLevel = level; 14032 mDischargeScreenOffUnplugLevel = 0; 14033 } else { 14034 mDischargeScreenOnUnplugLevel = 0; 14035 mDischargeScreenDozeUnplugLevel = 0; 14036 mDischargeScreenOffUnplugLevel = level; 14037 } 14038 mDischargeAmountScreenOn = 0; 14039 mDischargeAmountScreenDoze = 0; 14040 mDischargeAmountScreenOff = 0; 14041 updateTimeBasesLocked(true, screenState, uptimeUs, realtimeUs); 14042 } else { 14043 mLastChargingStateLevel = level; 14044 mOnBattery = mOnBatteryInternal = false; 14045 pullPendingStateUpdatesLocked(); 14046 mHistoryCur.batteryLevel = (byte)level; 14047 mHistoryCur.states |= HistoryItem.STATE_BATTERY_PLUGGED_FLAG; 14048 if (DEBUG_HISTORY) Slog.v(TAG, "Battery plugged to: " 14049 + Integer.toHexString(mHistoryCur.states)); 14050 addHistoryRecordLocked(mSecRealtime, mSecUptime); 14051 mDischargeCurrentLevel = mDischargePlugLevel = level; 14052 if (level < mDischargeUnplugLevel) { 14053 mLowDischargeAmountSinceCharge += mDischargeUnplugLevel-level-1; 14054 mHighDischargeAmountSinceCharge += mDischargeUnplugLevel-level; 14055 } 14056 updateDischargeScreenLevelsLocked(screenState, screenState); 14057 updateTimeBasesLocked(false, screenState, uptimeUs, realtimeUs); 14058 mChargeStepTracker.init(); 14059 mLastChargeStepLevel = level; 14060 mMaxChargeStepLevel = level; 14061 mInitStepMode = mCurStepMode; 14062 mModStepMode = 0; 14063 } 14064 if (doWrite || (mLastWriteTimeMs + (60 * 1000)) < mSecRealtime) { 14065 if (mStatsFile != null && mBatteryStatsHistory.getActiveFile() != null) { 14066 writeAsyncLocked(); 14067 } 14068 } 14069 } 14070 14071 private void startRecordingHistory(final long elapsedRealtimeMs, final long uptimeMs, 14072 boolean reset) { 14073 mRecordingHistory = true; 14074 mHistoryCur.currentTime = mClocks.currentTimeMillis(); 14075 addHistoryBufferLocked(elapsedRealtimeMs, 14076 reset ? HistoryItem.CMD_RESET : HistoryItem.CMD_CURRENT_TIME, 14077 mHistoryCur); 14078 mHistoryCur.currentTime = 0; 14079 if (reset) { 14080 initActiveHistoryEventsLocked(elapsedRealtimeMs, uptimeMs); 14081 } 14082 } 14083 14084 private void recordCurrentTimeChangeLocked(final long currentTimeMs, 14085 final long elapsedRealtimeMs, final long uptimeMs) { 14086 if (mRecordingHistory) { 14087 mHistoryCur.currentTime = currentTimeMs; 14088 addHistoryBufferLocked(elapsedRealtimeMs, HistoryItem.CMD_CURRENT_TIME, mHistoryCur); 14089 mHistoryCur.currentTime = 0; 14090 } 14091 } 14092 14093 private void recordShutdownLocked(final long currentTimeMs, final long elapsedRealtimeMs) { 14094 if (mRecordingHistory) { 14095 mHistoryCur.currentTime = currentTimeMs; 14096 addHistoryBufferLocked(elapsedRealtimeMs, HistoryItem.CMD_SHUTDOWN, mHistoryCur); 14097 mHistoryCur.currentTime = 0; 14098 } 14099 } 14100 14101 private void scheduleSyncExternalStatsLocked(String reason, int updateFlags) { 14102 if (mExternalSync != null) { 14103 mExternalSync.scheduleSync(reason, updateFlags); 14104 } 14105 } 14106 14107 // This should probably be exposed in the API, though it's not critical 14108 public static final int BATTERY_PLUGGED_NONE = OsProtoEnums.BATTERY_PLUGGED_NONE; // = 0 14109 14110 @GuardedBy("this") 14111 public void setBatteryStateLocked(final int status, final int health, final int plugType, 14112 final int level, /* not final */ int temp, final int voltageMv, final int chargeUah, 14113 final int chargeFullUah, final long chargeTimeToFullSeconds) { 14114 setBatteryStateLocked(status, health, plugType, level, temp, voltageMv, chargeUah, 14115 chargeFullUah, chargeTimeToFullSeconds, 14116 mClocks.elapsedRealtime(), mClocks.uptimeMillis(), mClocks.currentTimeMillis()); 14117 } 14118 14119 public void setBatteryStateLocked(final int status, final int health, final int plugType, 14120 final int level, /* not final */ int temp, final int voltageMv, final int chargeUah, 14121 final int chargeFullUah, final long chargeTimeToFullSeconds, 14122 final long elapsedRealtimeMs, final long uptimeMs, final long currentTimeMs) { 14123 // Temperature is encoded without the signed bit, so clamp any negative temperatures to 0. 14124 temp = Math.max(0, temp); 14125 14126 reportChangesToStatsLog(mHaveBatteryLevel ? mHistoryCur : null, 14127 status, plugType, level); 14128 14129 final boolean onBattery = isOnBattery(plugType, status); 14130 if (!mHaveBatteryLevel) { 14131 mHaveBatteryLevel = true; 14132 // We start out assuming that the device is plugged in (not 14133 // on battery). If our first report is now that we are indeed 14134 // plugged in, then twiddle our state to correctly reflect that 14135 // since we won't be going through the full setOnBattery(). 14136 if (onBattery == mOnBattery) { 14137 if (onBattery) { 14138 mHistoryCur.states &= ~HistoryItem.STATE_BATTERY_PLUGGED_FLAG; 14139 } else { 14140 mHistoryCur.states |= HistoryItem.STATE_BATTERY_PLUGGED_FLAG; 14141 } 14142 } 14143 // Always start out assuming charging, that will be updated later. 14144 mHistoryCur.states2 |= HistoryItem.STATE2_CHARGING_FLAG; 14145 mHistoryCur.batteryStatus = (byte)status; 14146 mHistoryCur.batteryLevel = (byte)level; 14147 mHistoryCur.batteryChargeUah = chargeUah; 14148 mMaxChargeStepLevel = mMinDischargeStepLevel = 14149 mLastChargeStepLevel = mLastDischargeStepLevel = level; 14150 mLastChargingStateLevel = level; 14151 } else if (mCurrentBatteryLevel != level || mOnBattery != onBattery) { 14152 recordDailyStatsIfNeededLocked(level >= 100 && onBattery, currentTimeMs); 14153 } 14154 int oldStatus = mHistoryCur.batteryStatus; 14155 if (onBattery) { 14156 mDischargeCurrentLevel = level; 14157 if (!mRecordingHistory) { 14158 mRecordingHistory = true; 14159 startRecordingHistory(elapsedRealtimeMs, uptimeMs, true); 14160 } 14161 } else if (level < 96 && 14162 status != BatteryManager.BATTERY_STATUS_UNKNOWN) { 14163 if (!mRecordingHistory) { 14164 mRecordingHistory = true; 14165 startRecordingHistory(elapsedRealtimeMs, uptimeMs, true); 14166 } 14167 } 14168 mBatteryVoltageMv = voltageMv; 14169 mCurrentBatteryLevel = level; 14170 if (mDischargePlugLevel < 0) { 14171 mDischargePlugLevel = level; 14172 } 14173 14174 if (onBattery != mOnBattery) { 14175 mHistoryCur.batteryLevel = (byte)level; 14176 mHistoryCur.batteryStatus = (byte)status; 14177 mHistoryCur.batteryHealth = (byte)health; 14178 mHistoryCur.batteryPlugType = (byte)plugType; 14179 mHistoryCur.batteryTemperature = (short)temp; 14180 mHistoryCur.batteryVoltage = (char) voltageMv; 14181 if (chargeUah < mHistoryCur.batteryChargeUah) { 14182 // Only record discharges 14183 final long chargeDiff = mHistoryCur.batteryChargeUah - chargeUah; 14184 mDischargeCounter.addCountLocked(chargeDiff); 14185 mDischargeScreenOffCounter.addCountLocked(chargeDiff); 14186 if (Display.isDozeState(mScreenState)) { 14187 mDischargeScreenDozeCounter.addCountLocked(chargeDiff); 14188 } 14189 if (mDeviceIdleMode == DEVICE_IDLE_MODE_LIGHT) { 14190 mDischargeLightDozeCounter.addCountLocked(chargeDiff); 14191 } else if (mDeviceIdleMode == DEVICE_IDLE_MODE_DEEP) { 14192 mDischargeDeepDozeCounter.addCountLocked(chargeDiff); 14193 } 14194 } 14195 mHistoryCur.batteryChargeUah = chargeUah; 14196 setOnBatteryLocked(elapsedRealtimeMs, uptimeMs, onBattery, oldStatus, level, chargeUah); 14197 } else { 14198 boolean changed = false; 14199 if (mHistoryCur.batteryLevel != level) { 14200 mHistoryCur.batteryLevel = (byte)level; 14201 changed = true; 14202 14203 // TODO(adamlesinski): Schedule the creation of a HistoryStepDetails record 14204 // which will pull external stats. 14205 mExternalSync.scheduleSyncDueToBatteryLevelChange( 14206 mConstants.BATTERY_LEVEL_COLLECTION_DELAY_MS); 14207 } 14208 if (mHistoryCur.batteryStatus != status) { 14209 mHistoryCur.batteryStatus = (byte)status; 14210 changed = true; 14211 } 14212 if (mHistoryCur.batteryHealth != health) { 14213 mHistoryCur.batteryHealth = (byte)health; 14214 changed = true; 14215 } 14216 if (mHistoryCur.batteryPlugType != plugType) { 14217 mHistoryCur.batteryPlugType = (byte)plugType; 14218 changed = true; 14219 } 14220 if (temp >= (mHistoryCur.batteryTemperature+10) 14221 || temp <= (mHistoryCur.batteryTemperature-10)) { 14222 mHistoryCur.batteryTemperature = (short)temp; 14223 changed = true; 14224 } 14225 if (voltageMv > (mHistoryCur.batteryVoltage + 20) 14226 || voltageMv < (mHistoryCur.batteryVoltage - 20)) { 14227 mHistoryCur.batteryVoltage = (char) voltageMv; 14228 changed = true; 14229 } 14230 if (chargeUah >= (mHistoryCur.batteryChargeUah + 10) 14231 || chargeUah <= (mHistoryCur.batteryChargeUah - 10)) { 14232 if (chargeUah < mHistoryCur.batteryChargeUah) { 14233 // Only record discharges 14234 final long chargeDiff = mHistoryCur.batteryChargeUah - chargeUah; 14235 mDischargeCounter.addCountLocked(chargeDiff); 14236 mDischargeScreenOffCounter.addCountLocked(chargeDiff); 14237 if (Display.isDozeState(mScreenState)) { 14238 mDischargeScreenDozeCounter.addCountLocked(chargeDiff); 14239 } 14240 if (mDeviceIdleMode == DEVICE_IDLE_MODE_LIGHT) { 14241 mDischargeLightDozeCounter.addCountLocked(chargeDiff); 14242 } else if (mDeviceIdleMode == DEVICE_IDLE_MODE_DEEP) { 14243 mDischargeDeepDozeCounter.addCountLocked(chargeDiff); 14244 } 14245 } 14246 mHistoryCur.batteryChargeUah = chargeUah; 14247 changed = true; 14248 } 14249 long modeBits = (((long)mInitStepMode) << STEP_LEVEL_INITIAL_MODE_SHIFT) 14250 | (((long)mModStepMode) << STEP_LEVEL_MODIFIED_MODE_SHIFT) 14251 | (((long)(level&0xff)) << STEP_LEVEL_LEVEL_SHIFT); 14252 if (onBattery) { 14253 changed |= setChargingLocked(false); 14254 if (mLastDischargeStepLevel != level && mMinDischargeStepLevel > level) { 14255 mDischargeStepTracker.addLevelSteps(mLastDischargeStepLevel - level, 14256 modeBits, elapsedRealtimeMs); 14257 mDailyDischargeStepTracker.addLevelSteps(mLastDischargeStepLevel - level, 14258 modeBits, elapsedRealtimeMs); 14259 mLastDischargeStepLevel = level; 14260 mMinDischargeStepLevel = level; 14261 mInitStepMode = mCurStepMode; 14262 mModStepMode = 0; 14263 } 14264 } else { 14265 if (level >= 90) { 14266 // If the battery level is at least 90%, always consider the device to be 14267 // charging even if it happens to go down a level. 14268 changed |= setChargingLocked(true); 14269 } else if (!mCharging) { 14270 if (mLastChargeStepLevel < level) { 14271 // We have not reported that we are charging, but the level has gone up, 14272 // but we would like to not have tons of activity from charging-constraint 14273 // jobs, so instead of reporting ACTION_CHARGING immediately, we defer it. 14274 if (!mHandler.hasCallbacks(mDeferSetCharging)) { 14275 mHandler.postDelayed( 14276 mDeferSetCharging, 14277 mConstants.BATTERY_CHARGED_DELAY_MS); 14278 } 14279 } else if (mLastChargeStepLevel > level) { 14280 // if we had deferred a runnable due to charge level increasing, but then 14281 // later the charge level drops (could be due to thermal issues), we don't 14282 // want to trigger the deferred runnable, so remove it here 14283 mHandler.removeCallbacks(mDeferSetCharging); 14284 } 14285 } else { 14286 if (mLastChargeStepLevel > level) { 14287 // We had reported that the device was charging, but here we are with 14288 // power connected and the level going down. Looks like the current 14289 // power supplied isn't enough, so consider the device to now be 14290 // discharging. 14291 changed |= setChargingLocked(false); 14292 } 14293 } 14294 if (mLastChargeStepLevel != level && mMaxChargeStepLevel < level) { 14295 mChargeStepTracker.addLevelSteps(level - mLastChargeStepLevel, 14296 modeBits, elapsedRealtimeMs); 14297 mDailyChargeStepTracker.addLevelSteps(level - mLastChargeStepLevel, 14298 modeBits, elapsedRealtimeMs); 14299 mMaxChargeStepLevel = level; 14300 mInitStepMode = mCurStepMode; 14301 mModStepMode = 0; 14302 } 14303 mLastChargeStepLevel = level; 14304 } 14305 if (changed) { 14306 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 14307 } 14308 } 14309 if (!onBattery && 14310 (status == BatteryManager.BATTERY_STATUS_FULL || 14311 status == BatteryManager.BATTERY_STATUS_UNKNOWN)) { 14312 // We don't record history while we are plugged in and fully charged 14313 // (or when battery is not present). The next time we are 14314 // unplugged, history will be cleared. 14315 mRecordingHistory = DEBUG; 14316 } 14317 14318 mLastLearnedBatteryCapacityUah = chargeFullUah; 14319 if (mMinLearnedBatteryCapacityUah == -1) { 14320 mMinLearnedBatteryCapacityUah = chargeFullUah; 14321 } else { 14322 mMinLearnedBatteryCapacityUah = Math.min(mMinLearnedBatteryCapacityUah, chargeFullUah); 14323 } 14324 mMaxLearnedBatteryCapacityUah = Math.max(mMaxLearnedBatteryCapacityUah, chargeFullUah); 14325 14326 mBatteryTimeToFullSeconds = chargeTimeToFullSeconds; 14327 } 14328 14329 public static boolean isOnBattery(int plugType, int status) { 14330 return plugType == BATTERY_PLUGGED_NONE && status != BatteryManager.BATTERY_STATUS_UNKNOWN; 14331 } 14332 14333 // Inform StatsLog of setBatteryState changes. 14334 // If this is the first reporting, pass in recentPast == null. 14335 private void reportChangesToStatsLog(HistoryItem recentPast, 14336 final int status, final int plugType, final int level) { 14337 14338 if (recentPast == null || recentPast.batteryStatus != status) { 14339 FrameworkStatsLog.write(FrameworkStatsLog.CHARGING_STATE_CHANGED, status); 14340 } 14341 if (recentPast == null || recentPast.batteryPlugType != plugType) { 14342 FrameworkStatsLog.write(FrameworkStatsLog.PLUGGED_STATE_CHANGED, plugType); 14343 } 14344 if (recentPast == null || recentPast.batteryLevel != level) { 14345 FrameworkStatsLog.write(FrameworkStatsLog.BATTERY_LEVEL_CHANGED, level); 14346 } 14347 } 14348 14349 @UnsupportedAppUsage 14350 public long getAwakeTimeBattery() { 14351 // This previously evaluated to mOnBatteryTimeBase.getUptime(getBatteryUptimeLocked()); 14352 // for over a decade, but surely that was a mistake. 14353 return getBatteryUptimeLocked(mClocks.uptimeMillis()); 14354 } 14355 14356 @UnsupportedAppUsage 14357 public long getAwakeTimePlugged() { 14358 return (mClocks.uptimeMillis() * 1000) - getAwakeTimeBattery(); 14359 } 14360 14361 @Override 14362 public long computeUptime(long curTimeUs, int which) { 14363 return mUptimeUs + (curTimeUs - mUptimeStartUs); 14364 } 14365 14366 @Override 14367 public long computeRealtime(long curTimeUs, int which) { 14368 return mRealtimeUs + (curTimeUs - mRealtimeStartUs); 14369 } 14370 14371 @Override 14372 @UnsupportedAppUsage 14373 public long computeBatteryUptime(long curTimeUs, int which) { 14374 return mOnBatteryTimeBase.computeUptime(curTimeUs, which); 14375 } 14376 14377 @Override 14378 @UnsupportedAppUsage 14379 public long computeBatteryRealtime(long curTimeUs, int which) { 14380 return mOnBatteryTimeBase.computeRealtime(curTimeUs, which); 14381 } 14382 14383 @Override 14384 public long computeBatteryScreenOffUptime(long curTimeUs, int which) { 14385 return mOnBatteryScreenOffTimeBase.computeUptime(curTimeUs, which); 14386 } 14387 14388 @Override 14389 public long computeBatteryScreenOffRealtime(long curTimeUs, int which) { 14390 return mOnBatteryScreenOffTimeBase.computeRealtime(curTimeUs, which); 14391 } 14392 14393 private long computeTimePerLevel(long[] steps, int numSteps) { 14394 // For now we'll do a simple average across all steps. 14395 if (numSteps <= 0) { 14396 return -1; 14397 } 14398 long total = 0; 14399 for (int i=0; i<numSteps; i++) { 14400 total += steps[i] & STEP_LEVEL_TIME_MASK; 14401 } 14402 return total / numSteps; 14403 /* 14404 long[] buckets = new long[numSteps]; 14405 int numBuckets = 0; 14406 int numToAverage = 4; 14407 int i = 0; 14408 while (i < numSteps) { 14409 long totalTime = 0; 14410 int num = 0; 14411 for (int j=0; j<numToAverage && (i+j)<numSteps; j++) { 14412 totalTime += steps[i+j] & STEP_LEVEL_TIME_MASK; 14413 num++; 14414 } 14415 buckets[numBuckets] = totalTime / num; 14416 numBuckets++; 14417 numToAverage *= 2; 14418 i += num; 14419 } 14420 if (numBuckets < 1) { 14421 return -1; 14422 } 14423 long averageTime = buckets[numBuckets-1]; 14424 for (i=numBuckets-2; i>=0; i--) { 14425 averageTime = (averageTime + buckets[i]) / 2; 14426 } 14427 return averageTime; 14428 */ 14429 } 14430 14431 @Override 14432 @UnsupportedAppUsage 14433 public long computeBatteryTimeRemaining(long curTime) { 14434 if (!mOnBattery) { 14435 return -1; 14436 } 14437 /* Simple implementation just looks at the average discharge per level across the 14438 entire sample period. 14439 int discharge = (getLowDischargeAmountSinceCharge()+getHighDischargeAmountSinceCharge())/2; 14440 if (discharge < 2) { 14441 return -1; 14442 } 14443 long duration = computeBatteryRealtime(curTime, STATS_SINCE_CHARGED); 14444 if (duration < 1000*1000) { 14445 return -1; 14446 } 14447 long usPerLevel = duration/discharge; 14448 return usPerLevel * mCurrentBatteryLevel; 14449 */ 14450 if (mDischargeStepTracker.mNumStepDurations < 1) { 14451 return -1; 14452 } 14453 long msPerLevel = mDischargeStepTracker.computeTimePerLevel(); 14454 if (msPerLevel <= 0) { 14455 return -1; 14456 } 14457 return (msPerLevel * mCurrentBatteryLevel) * 1000; 14458 } 14459 14460 @Override 14461 public LevelStepTracker getDischargeLevelStepTracker() { 14462 return mDischargeStepTracker; 14463 } 14464 14465 @Override 14466 public LevelStepTracker getDailyDischargeLevelStepTracker() { 14467 return mDailyDischargeStepTracker; 14468 } 14469 14470 @Override 14471 public long computeChargeTimeRemaining(long curTime) { 14472 if (mOnBattery) { 14473 // Not yet working. 14474 return -1; 14475 } 14476 if (mBatteryTimeToFullSeconds >= 0) { 14477 return mBatteryTimeToFullSeconds * (1000 * 1000); // s to us 14478 } 14479 // Else use algorithmic approach 14480 if (mChargeStepTracker.mNumStepDurations < 1) { 14481 return -1; 14482 } 14483 long msPerLevel = mChargeStepTracker.computeTimePerLevel(); 14484 if (msPerLevel <= 0) { 14485 return -1; 14486 } 14487 return (msPerLevel * (100 - mCurrentBatteryLevel)) * 1000; 14488 } 14489 14490 /*@hide */ 14491 public CellularBatteryStats getCellularBatteryStats() { 14492 final int which = STATS_SINCE_CHARGED; 14493 final long rawRealTimeUs = SystemClock.elapsedRealtime() * 1000; 14494 final ControllerActivityCounter counter = getModemControllerActivity(); 14495 final long sleepTimeMs = counter.getSleepTimeCounter().getCountLocked(which); 14496 final long idleTimeMs = counter.getIdleTimeCounter().getCountLocked(which); 14497 final long rxTimeMs = counter.getRxTimeCounter().getCountLocked(which); 14498 final long energyConsumedMaMs = counter.getPowerCounter().getCountLocked(which); 14499 final long monitoredRailChargeConsumedMaMs = 14500 counter.getMonitoredRailChargeConsumedMaMs().getCountLocked(which); 14501 long[] timeInRatMs = new long[BatteryStats.NUM_DATA_CONNECTION_TYPES]; 14502 for (int i = 0; i < timeInRatMs.length; i++) { 14503 timeInRatMs[i] = getPhoneDataConnectionTime(i, rawRealTimeUs, which) / 1000; 14504 } 14505 long[] timeInRxSignalStrengthLevelMs = 14506 new long[CellSignalStrength.getNumSignalStrengthLevels()]; 14507 for (int i = 0; i < timeInRxSignalStrengthLevelMs.length; i++) { 14508 timeInRxSignalStrengthLevelMs[i] = 14509 getPhoneSignalStrengthTime(i, rawRealTimeUs, which) / 1000; 14510 } 14511 long[] txTimeMs = new long[Math.min(ModemActivityInfo.getNumTxPowerLevels(), 14512 counter.getTxTimeCounters().length)]; 14513 long totalTxTimeMs = 0; 14514 for (int i = 0; i < txTimeMs.length; i++) { 14515 txTimeMs[i] = counter.getTxTimeCounters()[i].getCountLocked(which); 14516 totalTxTimeMs += txTimeMs[i]; 14517 } 14518 14519 return new CellularBatteryStats(computeBatteryRealtime(rawRealTimeUs, which) / 1000, 14520 getMobileRadioActiveTime(rawRealTimeUs, which) / 1000, 14521 getNetworkActivityPackets(NETWORK_MOBILE_TX_DATA, which), 14522 getNetworkActivityBytes(NETWORK_MOBILE_TX_DATA, which), 14523 getNetworkActivityPackets(NETWORK_MOBILE_RX_DATA, which), 14524 getNetworkActivityBytes(NETWORK_MOBILE_RX_DATA, which), 14525 sleepTimeMs, idleTimeMs, rxTimeMs, energyConsumedMaMs, timeInRatMs, 14526 timeInRxSignalStrengthLevelMs, txTimeMs, 14527 monitoredRailChargeConsumedMaMs); 14528 } 14529 14530 /*@hide */ 14531 public WifiBatteryStats getWifiBatteryStats() { 14532 final int which = STATS_SINCE_CHARGED; 14533 final long rawRealTimeUs = SystemClock.elapsedRealtime() * 1000; 14534 final ControllerActivityCounter counter = getWifiControllerActivity(); 14535 final long idleTimeMs = counter.getIdleTimeCounter().getCountLocked(which); 14536 final long scanTimeMs = counter.getScanTimeCounter().getCountLocked(which); 14537 final long rxTimeMs = counter.getRxTimeCounter().getCountLocked(which); 14538 final long txTimeMs = counter.getTxTimeCounters()[0].getCountLocked(which); 14539 final long totalControllerActivityTimeMs 14540 = computeBatteryRealtime(SystemClock.elapsedRealtime() * 1000, which) / 1000; 14541 final long sleepTimeMs 14542 = totalControllerActivityTimeMs - (idleTimeMs + rxTimeMs + txTimeMs); 14543 final long energyConsumedMaMs = counter.getPowerCounter().getCountLocked(which); 14544 final long monitoredRailChargeConsumedMaMs = 14545 counter.getMonitoredRailChargeConsumedMaMs().getCountLocked(which); 14546 long numAppScanRequest = 0; 14547 for (int i = 0; i < mUidStats.size(); i++) { 14548 numAppScanRequest += mUidStats.valueAt(i).mWifiScanTimer.getCountLocked(which); 14549 } 14550 long[] timeInStateMs = new long[NUM_WIFI_STATES]; 14551 for (int i=0; i<NUM_WIFI_STATES; i++) { 14552 timeInStateMs[i] = getWifiStateTime(i, rawRealTimeUs, which) / 1000; 14553 } 14554 long[] timeInSupplStateMs = new long[NUM_WIFI_SUPPL_STATES]; 14555 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) { 14556 timeInSupplStateMs[i] = getWifiSupplStateTime(i, rawRealTimeUs, which) / 1000; 14557 } 14558 long[] timeSignalStrengthTimeMs = new long[NUM_WIFI_SIGNAL_STRENGTH_BINS]; 14559 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { 14560 timeSignalStrengthTimeMs[i] = getWifiSignalStrengthTime(i, rawRealTimeUs, which) / 1000; 14561 } 14562 return new WifiBatteryStats( 14563 computeBatteryRealtime(rawRealTimeUs, which) / 1000, 14564 getWifiActiveTime(rawRealTimeUs, which) / 1000, 14565 getNetworkActivityPackets(NETWORK_WIFI_TX_DATA, which), 14566 getNetworkActivityBytes(NETWORK_WIFI_TX_DATA, which), 14567 getNetworkActivityPackets(NETWORK_WIFI_RX_DATA, which), 14568 getNetworkActivityBytes(NETWORK_WIFI_RX_DATA, which), 14569 sleepTimeMs, scanTimeMs, idleTimeMs, rxTimeMs, txTimeMs, energyConsumedMaMs, 14570 numAppScanRequest, timeInStateMs, timeSignalStrengthTimeMs, timeInSupplStateMs, 14571 monitoredRailChargeConsumedMaMs); 14572 } 14573 14574 /*@hide */ 14575 public GpsBatteryStats getGpsBatteryStats() { 14576 GpsBatteryStats s = new GpsBatteryStats(); 14577 final int which = STATS_SINCE_CHARGED; 14578 final long rawRealTimeUs = SystemClock.elapsedRealtime() * 1000; 14579 s.setLoggingDurationMs(computeBatteryRealtime(rawRealTimeUs, which) / 1000); 14580 s.setEnergyConsumedMaMs(getGpsBatteryDrainMaMs()); 14581 long[] time = new long[mGpsSignalQualityTimer.length]; 14582 for (int i=0; i<time.length; i++) { 14583 time[i] = getGpsSignalQualityTime(i, rawRealTimeUs, which) / 1000; 14584 } 14585 s.setTimeInGpsSignalQualityLevel(time); 14586 return s; 14587 } 14588 14589 @Override 14590 public LevelStepTracker getChargeLevelStepTracker() { 14591 return mChargeStepTracker; 14592 } 14593 14594 @Override 14595 public LevelStepTracker getDailyChargeLevelStepTracker() { 14596 return mDailyChargeStepTracker; 14597 } 14598 14599 @Override 14600 public ArrayList<PackageChange> getDailyPackageChanges() { 14601 return mDailyPackageChanges; 14602 } 14603 14604 /** 14605 * @return battery uptime in microseconds 14606 */ 14607 protected long getBatteryUptimeLocked() { 14608 return getBatteryUptimeLocked(mClocks.uptimeMillis()); 14609 } 14610 14611 /** 14612 * @return battery uptime in microseconds 14613 */ 14614 protected long getBatteryUptimeLocked(long uptimeMs) { 14615 return mOnBatteryTimeBase.getUptime(uptimeMs * 1000); 14616 } 14617 14618 @Override 14619 public long getBatteryUptime(long curTimeUs) { 14620 return mOnBatteryTimeBase.getUptime(curTimeUs); 14621 } 14622 14623 @Override 14624 @UnsupportedAppUsage 14625 public long getBatteryRealtime(long curTimeUs) { 14626 return mOnBatteryTimeBase.getRealtime(curTimeUs); 14627 } 14628 14629 @Override 14630 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) 14631 public int getDischargeStartLevel() { 14632 synchronized(this) { 14633 return getDischargeStartLevelLocked(); 14634 } 14635 } 14636 14637 public int getDischargeStartLevelLocked() { 14638 return mDischargeUnplugLevel; 14639 } 14640 14641 @Override 14642 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) 14643 public int getDischargeCurrentLevel() { 14644 synchronized(this) { 14645 return getDischargeCurrentLevelLocked(); 14646 } 14647 } 14648 14649 public int getDischargeCurrentLevelLocked() { 14650 return mDischargeCurrentLevel; 14651 } 14652 14653 @Override 14654 public int getLowDischargeAmountSinceCharge() { 14655 synchronized(this) { 14656 int val = mLowDischargeAmountSinceCharge; 14657 if (mOnBattery && mDischargeCurrentLevel < mDischargeUnplugLevel) { 14658 val += mDischargeUnplugLevel-mDischargeCurrentLevel-1; 14659 } 14660 return val; 14661 } 14662 } 14663 14664 @Override 14665 public int getHighDischargeAmountSinceCharge() { 14666 synchronized(this) { 14667 int val = mHighDischargeAmountSinceCharge; 14668 if (mOnBattery && mDischargeCurrentLevel < mDischargeUnplugLevel) { 14669 val += mDischargeUnplugLevel-mDischargeCurrentLevel; 14670 } 14671 return val; 14672 } 14673 } 14674 14675 @Override 14676 @UnsupportedAppUsage 14677 public int getDischargeAmount(int which) { 14678 int dischargeAmount = which == STATS_SINCE_CHARGED 14679 ? getHighDischargeAmountSinceCharge() 14680 : (getDischargeStartLevel() - getDischargeCurrentLevel()); 14681 if (dischargeAmount < 0) { 14682 dischargeAmount = 0; 14683 } 14684 return dischargeAmount; 14685 } 14686 14687 @Override 14688 @UnsupportedAppUsage 14689 public int getDischargeAmountScreenOn() { 14690 synchronized(this) { 14691 int val = mDischargeAmountScreenOn; 14692 if (mOnBattery && Display.isOnState(mScreenState) 14693 && mDischargeCurrentLevel < mDischargeScreenOnUnplugLevel) { 14694 val += mDischargeScreenOnUnplugLevel-mDischargeCurrentLevel; 14695 } 14696 return val; 14697 } 14698 } 14699 14700 @Override 14701 public int getDischargeAmountScreenOnSinceCharge() { 14702 synchronized(this) { 14703 int val = mDischargeAmountScreenOnSinceCharge; 14704 if (mOnBattery && Display.isOnState(mScreenState) 14705 && mDischargeCurrentLevel < mDischargeScreenOnUnplugLevel) { 14706 val += mDischargeScreenOnUnplugLevel-mDischargeCurrentLevel; 14707 } 14708 return val; 14709 } 14710 } 14711 14712 @Override 14713 @UnsupportedAppUsage 14714 public int getDischargeAmountScreenOff() { 14715 synchronized(this) { 14716 int val = mDischargeAmountScreenOff; 14717 if (mOnBattery && Display.isOffState(mScreenState) 14718 && mDischargeCurrentLevel < mDischargeScreenOffUnplugLevel) { 14719 val += mDischargeScreenOffUnplugLevel-mDischargeCurrentLevel; 14720 } 14721 // For backward compatibility, doze discharge is counted into screen off. 14722 return val + getDischargeAmountScreenDoze(); 14723 } 14724 } 14725 14726 @Override 14727 public int getDischargeAmountScreenOffSinceCharge() { 14728 synchronized(this) { 14729 int val = mDischargeAmountScreenOffSinceCharge; 14730 if (mOnBattery && Display.isOffState(mScreenState) 14731 && mDischargeCurrentLevel < mDischargeScreenOffUnplugLevel) { 14732 val += mDischargeScreenOffUnplugLevel-mDischargeCurrentLevel; 14733 } 14734 // For backward compatibility, doze discharge is counted into screen off. 14735 return val + getDischargeAmountScreenDozeSinceCharge(); 14736 } 14737 } 14738 14739 @Override 14740 public int getDischargeAmountScreenDoze() { 14741 synchronized(this) { 14742 int val = mDischargeAmountScreenDoze; 14743 if (mOnBattery && Display.isDozeState(mScreenState) 14744 && mDischargeCurrentLevel < mDischargeScreenDozeUnplugLevel) { 14745 val += mDischargeScreenDozeUnplugLevel-mDischargeCurrentLevel; 14746 } 14747 return val; 14748 } 14749 } 14750 14751 @Override 14752 public int getDischargeAmountScreenDozeSinceCharge() { 14753 synchronized(this) { 14754 int val = mDischargeAmountScreenDozeSinceCharge; 14755 if (mOnBattery && Display.isDozeState(mScreenState) 14756 && mDischargeCurrentLevel < mDischargeScreenDozeUnplugLevel) { 14757 val += mDischargeScreenDozeUnplugLevel-mDischargeCurrentLevel; 14758 } 14759 return val; 14760 } 14761 } 14762 14763 14764 /** 14765 * Estimates the time spent by the system server handling incoming binder requests. 14766 */ 14767 @Override 14768 public long[] getSystemServiceTimeAtCpuSpeeds() { 14769 if (mBinderThreadCpuTimesUs == null) { 14770 return null; 14771 } 14772 14773 return mBinderThreadCpuTimesUs.getCountsLocked(BatteryStats.STATS_SINCE_CHARGED); 14774 } 14775 14776 /** 14777 * Retrieve the statistics object for a particular uid, creating if needed. 14778 */ 14779 @UnsupportedAppUsage 14780 public Uid getUidStatsLocked(int uid) { 14781 return getUidStatsLocked(uid, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 14782 } 14783 14784 public Uid getUidStatsLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { 14785 Uid u = mUidStats.get(uid); 14786 if (u == null) { 14787 u = new Uid(this, uid, elapsedRealtimeMs, uptimeMs); 14788 mUidStats.put(uid, u); 14789 } 14790 return u; 14791 } 14792 14793 /** 14794 * Retrieve the statistics object for a particular uid. Returns null if the object is not 14795 * available. 14796 */ 14797 public Uid getAvailableUidStatsLocked(int uid) { 14798 Uid u = mUidStats.get(uid); 14799 return u; 14800 } 14801 14802 public void onCleanupUserLocked(int userId, long elapsedRealtimeMs) { 14803 final int firstUidForUser = UserHandle.getUid(userId, 0); 14804 final int lastUidForUser = UserHandle.getUid(userId, UserHandle.PER_USER_RANGE - 1); 14805 mPendingRemovedUids.add( 14806 new UidToRemove(firstUidForUser, lastUidForUser, elapsedRealtimeMs)); 14807 } 14808 14809 public void onUserRemovedLocked(int userId) { 14810 final int firstUidForUser = UserHandle.getUid(userId, 0); 14811 final int lastUidForUser = UserHandle.getUid(userId, UserHandle.PER_USER_RANGE - 1); 14812 mUidStats.put(firstUidForUser, null); 14813 mUidStats.put(lastUidForUser, null); 14814 final int firstIndex = mUidStats.indexOfKey(firstUidForUser); 14815 final int lastIndex = mUidStats.indexOfKey(lastUidForUser); 14816 for (int i = firstIndex; i <= lastIndex; i++) { 14817 final Uid uid = mUidStats.valueAt(i); 14818 if (uid != null) { 14819 uid.detachFromTimeBase(); 14820 } 14821 } 14822 mUidStats.removeAtRange(firstIndex, lastIndex - firstIndex + 1); 14823 } 14824 14825 /** 14826 * Remove the statistics object for a particular uid. 14827 */ 14828 @UnsupportedAppUsage 14829 public void removeUidStatsLocked(int uid) { 14830 removeUidStatsLocked(uid, mClocks.elapsedRealtime()); 14831 } 14832 14833 /** 14834 * @see #removeUidStatsLocked(int) 14835 */ 14836 public void removeUidStatsLocked(int uid, long elapsedRealtimeMs) { 14837 final Uid u = mUidStats.get(uid); 14838 if (u != null) { 14839 u.detachFromTimeBase(); 14840 } 14841 mUidStats.remove(uid); 14842 mPendingRemovedUids.add(new UidToRemove(uid, elapsedRealtimeMs)); 14843 } 14844 14845 /** 14846 * Retrieve the statistics object for a particular process, creating 14847 * if needed. 14848 */ 14849 @UnsupportedAppUsage 14850 public Uid.Proc getProcessStatsLocked(int uid, String name) { 14851 return getProcessStatsLocked(uid, name, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 14852 } 14853 14854 /** 14855 * @see #getProcessStatsLocked(int, String) 14856 */ 14857 public Uid.Proc getProcessStatsLocked(int uid, String name, 14858 long elapsedRealtimeMs, long uptimeMs) { 14859 uid = mapUid(uid); 14860 Uid u = getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs); 14861 return u.getProcessStatsLocked(name); 14862 } 14863 14864 /** 14865 * Retrieve the statistics object for a particular process, creating 14866 * if needed. 14867 */ 14868 @UnsupportedAppUsage 14869 public Uid.Pkg getPackageStatsLocked(int uid, String pkg) { 14870 return getPackageStatsLocked(uid, pkg, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 14871 } 14872 14873 /** 14874 * @see getPackageStatsLocked(int, String) 14875 */ 14876 public Uid.Pkg getPackageStatsLocked(int uid, String pkg, 14877 long elapsedRealtimeMs, long uptimeMs) { 14878 uid = mapUid(uid); 14879 Uid u = getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs); 14880 return u.getPackageStatsLocked(pkg); 14881 } 14882 14883 /** 14884 * Retrieve the statistics object for a particular service, creating 14885 * if needed. 14886 */ 14887 @UnsupportedAppUsage 14888 public Uid.Pkg.Serv getServiceStatsLocked(int uid, String pkg, String name) { 14889 return getServiceStatsLocked(uid, pkg, name, 14890 mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 14891 } 14892 14893 public Uid.Pkg.Serv getServiceStatsLocked(int uid, String pkg, String name, 14894 long elapsedRealtimeMs, long uptimeMs) { 14895 uid = mapUid(uid); 14896 Uid u = getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs); 14897 return u.getServiceStatsLocked(pkg, name); 14898 } 14899 14900 public void shutdownLocked() { 14901 recordShutdownLocked(mClocks.currentTimeMillis(), mClocks.elapsedRealtime()); 14902 writeSyncLocked(); 14903 mShuttingDown = true; 14904 } 14905 14906 public boolean trackPerProcStateCpuTimes() { 14907 return mConstants.TRACK_CPU_TIMES_BY_PROC_STATE && mPerProcStateCpuTimesAvailable; 14908 } 14909 14910 public void systemServicesReady(Context context) { 14911 mConstants.startObserving(context.getContentResolver()); 14912 registerUsbStateReceiver(context); 14913 } 14914 14915 /** 14916 * Initialize the measured charge stats data structures. 14917 * 14918 * @param supportedStandardBuckets boolean array indicating which {@link StandardPowerBucket}s 14919 * are currently supported. If null, none are supported 14920 * (regardless of customBucketNames). 14921 * @param customBucketNames names of custom (OTHER) EnergyConsumers on this device 14922 */ 14923 @GuardedBy("this") 14924 public void initMeasuredEnergyStatsLocked(@Nullable boolean[] supportedStandardBuckets, 14925 String[] customBucketNames) { 14926 boolean supportedBucketMismatch = false; 14927 14928 final int numDisplays = mPerDisplayBatteryStats.length; 14929 for (int i = 0; i < numDisplays; i++) { 14930 final int screenState = mPerDisplayBatteryStats[i].screenState; 14931 mPerDisplayBatteryStats[i].screenStateAtLastEnergyMeasurement = screenState; 14932 } 14933 14934 if (supportedStandardBuckets == null) { 14935 if (mGlobalMeasuredEnergyStats != null) { 14936 // Measured energy no longer supported, wipe out the existing data. 14937 supportedBucketMismatch = true; 14938 } 14939 } else { 14940 if (mGlobalMeasuredEnergyStats == null) { 14941 mGlobalMeasuredEnergyStats = 14942 new MeasuredEnergyStats(supportedStandardBuckets, customBucketNames); 14943 } else { 14944 supportedBucketMismatch = !mGlobalMeasuredEnergyStats.isSupportEqualTo( 14945 supportedStandardBuckets, customBucketNames); 14946 } 14947 14948 if (supportedStandardBuckets[MeasuredEnergyStats.POWER_BUCKET_BLUETOOTH]) { 14949 mBluetoothPowerCalculator = new BluetoothPowerCalculator(mPowerProfile); 14950 } 14951 if (supportedStandardBuckets[MeasuredEnergyStats.POWER_BUCKET_CPU]) { 14952 mCpuPowerCalculator = new CpuPowerCalculator(mPowerProfile); 14953 } 14954 if (supportedStandardBuckets[MeasuredEnergyStats.POWER_BUCKET_MOBILE_RADIO]) { 14955 mMobileRadioPowerCalculator = new MobileRadioPowerCalculator(mPowerProfile); 14956 } 14957 if (supportedStandardBuckets[MeasuredEnergyStats.POWER_BUCKET_WIFI]) { 14958 mWifiPowerCalculator = new WifiPowerCalculator(mPowerProfile); 14959 } 14960 } 14961 14962 if (supportedBucketMismatch) { 14963 mGlobalMeasuredEnergyStats = supportedStandardBuckets == null 14964 ? null : new MeasuredEnergyStats(supportedStandardBuckets, customBucketNames); 14965 // Supported power buckets changed since last boot. 14966 // Existing data is no longer reliable. 14967 resetAllStatsLocked(SystemClock.uptimeMillis(), SystemClock.elapsedRealtime(), 14968 RESET_REASON_MEASURED_ENERGY_BUCKETS_CHANGE); 14969 } 14970 } 14971 14972 /** Get the last known Battery voltage (in millivolts), returns -1 if unknown */ 14973 @GuardedBy("this") 14974 public int getBatteryVoltageMvLocked() { 14975 return mBatteryVoltageMv; 14976 } 14977 14978 @VisibleForTesting 14979 public final class Constants extends ContentObserver { 14980 public static final String KEY_TRACK_CPU_TIMES_BY_PROC_STATE 14981 = "track_cpu_times_by_proc_state"; 14982 public static final String KEY_TRACK_CPU_ACTIVE_CLUSTER_TIME 14983 = "track_cpu_active_cluster_time"; 14984 public static final String KEY_PROC_STATE_CPU_TIMES_READ_DELAY_MS 14985 = "proc_state_cpu_times_read_delay_ms"; 14986 public static final String KEY_KERNEL_UID_READERS_THROTTLE_TIME 14987 = "kernel_uid_readers_throttle_time"; 14988 public static final String KEY_UID_REMOVE_DELAY_MS 14989 = "uid_remove_delay_ms"; 14990 public static final String KEY_EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS 14991 = "external_stats_collection_rate_limit_ms"; 14992 public static final String KEY_BATTERY_LEVEL_COLLECTION_DELAY_MS 14993 = "battery_level_collection_delay_ms"; 14994 public static final String KEY_MAX_HISTORY_FILES = "max_history_files"; 14995 public static final String KEY_MAX_HISTORY_BUFFER_KB = "max_history_buffer_kb"; 14996 public static final String KEY_BATTERY_CHARGED_DELAY_MS = 14997 "battery_charged_delay_ms"; 14998 14999 private static final boolean DEFAULT_TRACK_CPU_TIMES_BY_PROC_STATE = false; 15000 private static final boolean DEFAULT_TRACK_CPU_ACTIVE_CLUSTER_TIME = true; 15001 private static final long DEFAULT_PROC_STATE_CPU_TIMES_READ_DELAY_MS = 5_000; 15002 private static final long DEFAULT_KERNEL_UID_READERS_THROTTLE_TIME = 1_000; 15003 private static final long DEFAULT_UID_REMOVE_DELAY_MS = 5L * 60L * 1000L; 15004 private static final long DEFAULT_EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS = 600_000; 15005 private static final long DEFAULT_BATTERY_LEVEL_COLLECTION_DELAY_MS = 300_000; 15006 private static final int DEFAULT_MAX_HISTORY_FILES = 32; 15007 private static final int DEFAULT_MAX_HISTORY_BUFFER_KB = 128; /*Kilo Bytes*/ 15008 private static final int DEFAULT_MAX_HISTORY_FILES_LOW_RAM_DEVICE = 64; 15009 private static final int DEFAULT_MAX_HISTORY_BUFFER_LOW_RAM_DEVICE_KB = 64; /*Kilo Bytes*/ 15010 private static final int DEFAULT_BATTERY_CHARGED_DELAY_MS = 900000; /* 15 min */ 15011 15012 public boolean TRACK_CPU_TIMES_BY_PROC_STATE = DEFAULT_TRACK_CPU_TIMES_BY_PROC_STATE; 15013 public boolean TRACK_CPU_ACTIVE_CLUSTER_TIME = DEFAULT_TRACK_CPU_ACTIVE_CLUSTER_TIME; 15014 public long PROC_STATE_CPU_TIMES_READ_DELAY_MS = DEFAULT_PROC_STATE_CPU_TIMES_READ_DELAY_MS; 15015 /* Do not set default value for KERNEL_UID_READERS_THROTTLE_TIME. Need to trigger an 15016 * update when startObserving. */ 15017 public long KERNEL_UID_READERS_THROTTLE_TIME; 15018 public long UID_REMOVE_DELAY_MS = DEFAULT_UID_REMOVE_DELAY_MS; 15019 public long EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS 15020 = DEFAULT_EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS; 15021 public long BATTERY_LEVEL_COLLECTION_DELAY_MS 15022 = DEFAULT_BATTERY_LEVEL_COLLECTION_DELAY_MS; 15023 public int MAX_HISTORY_FILES; 15024 public int MAX_HISTORY_BUFFER; /*Bytes*/ 15025 public int BATTERY_CHARGED_DELAY_MS = DEFAULT_BATTERY_CHARGED_DELAY_MS; 15026 15027 private ContentResolver mResolver; 15028 private final KeyValueListParser mParser = new KeyValueListParser(','); 15029 15030 public Constants(Handler handler) { 15031 super(handler); 15032 if (ActivityManager.isLowRamDeviceStatic()) { 15033 MAX_HISTORY_FILES = DEFAULT_MAX_HISTORY_FILES_LOW_RAM_DEVICE; 15034 MAX_HISTORY_BUFFER = DEFAULT_MAX_HISTORY_BUFFER_LOW_RAM_DEVICE_KB * 1024; 15035 } else { 15036 MAX_HISTORY_FILES = DEFAULT_MAX_HISTORY_FILES; 15037 MAX_HISTORY_BUFFER = DEFAULT_MAX_HISTORY_BUFFER_KB * 1024; 15038 } 15039 } 15040 15041 public void startObserving(ContentResolver resolver) { 15042 mResolver = resolver; 15043 mResolver.registerContentObserver( 15044 Settings.Global.getUriFor(Settings.Global.BATTERY_STATS_CONSTANTS), 15045 false /* notifyForDescendants */, this); 15046 mResolver.registerContentObserver( 15047 Settings.Global.getUriFor(Settings.Global.BATTERY_CHARGING_STATE_UPDATE_DELAY), 15048 false /* notifyForDescendants */, this); 15049 updateConstants(); 15050 } 15051 15052 @Override 15053 public void onChange(boolean selfChange, Uri uri) { 15054 if (uri.equals( 15055 Settings.Global.getUriFor( 15056 Settings.Global.BATTERY_CHARGING_STATE_UPDATE_DELAY))) { 15057 synchronized (BatteryStatsImpl.this) { 15058 updateBatteryChargedDelayMsLocked(); 15059 } 15060 return; 15061 } 15062 updateConstants(); 15063 } 15064 15065 private void updateConstants() { 15066 synchronized (BatteryStatsImpl.this) { 15067 try { 15068 mParser.setString(Settings.Global.getString(mResolver, 15069 Settings.Global.BATTERY_STATS_CONSTANTS)); 15070 } catch (IllegalArgumentException e) { 15071 // Failed to parse the settings string, log this and move on 15072 // with defaults. 15073 Slog.e(TAG, "Bad batterystats settings", e); 15074 } 15075 15076 updateTrackCpuTimesByProcStateLocked(TRACK_CPU_TIMES_BY_PROC_STATE, 15077 mParser.getBoolean(KEY_TRACK_CPU_TIMES_BY_PROC_STATE, 15078 DEFAULT_TRACK_CPU_TIMES_BY_PROC_STATE)); 15079 TRACK_CPU_ACTIVE_CLUSTER_TIME = mParser.getBoolean( 15080 KEY_TRACK_CPU_ACTIVE_CLUSTER_TIME, DEFAULT_TRACK_CPU_ACTIVE_CLUSTER_TIME); 15081 updateProcStateCpuTimesReadDelayMs(PROC_STATE_CPU_TIMES_READ_DELAY_MS, 15082 mParser.getLong(KEY_PROC_STATE_CPU_TIMES_READ_DELAY_MS, 15083 DEFAULT_PROC_STATE_CPU_TIMES_READ_DELAY_MS)); 15084 updateKernelUidReadersThrottleTime(KERNEL_UID_READERS_THROTTLE_TIME, 15085 mParser.getLong(KEY_KERNEL_UID_READERS_THROTTLE_TIME, 15086 DEFAULT_KERNEL_UID_READERS_THROTTLE_TIME)); 15087 updateUidRemoveDelay( 15088 mParser.getLong(KEY_UID_REMOVE_DELAY_MS, DEFAULT_UID_REMOVE_DELAY_MS)); 15089 EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS = mParser.getLong( 15090 KEY_EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS, 15091 DEFAULT_EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS); 15092 BATTERY_LEVEL_COLLECTION_DELAY_MS = mParser.getLong( 15093 KEY_BATTERY_LEVEL_COLLECTION_DELAY_MS, 15094 DEFAULT_BATTERY_LEVEL_COLLECTION_DELAY_MS); 15095 15096 MAX_HISTORY_FILES = mParser.getInt(KEY_MAX_HISTORY_FILES, 15097 ActivityManager.isLowRamDeviceStatic() ? 15098 DEFAULT_MAX_HISTORY_FILES_LOW_RAM_DEVICE 15099 : DEFAULT_MAX_HISTORY_FILES); 15100 MAX_HISTORY_BUFFER = mParser.getInt(KEY_MAX_HISTORY_BUFFER_KB, 15101 ActivityManager.isLowRamDeviceStatic() ? 15102 DEFAULT_MAX_HISTORY_BUFFER_LOW_RAM_DEVICE_KB 15103 : DEFAULT_MAX_HISTORY_BUFFER_KB) 15104 * 1024; 15105 updateBatteryChargedDelayMsLocked(); 15106 } 15107 } 15108 15109 private void updateBatteryChargedDelayMsLocked() { 15110 // a negative value indicates that we should ignore this override 15111 final int delay = Settings.Global.getInt(mResolver, 15112 Settings.Global.BATTERY_CHARGING_STATE_UPDATE_DELAY, 15113 -1); 15114 15115 BATTERY_CHARGED_DELAY_MS = delay >= 0 ? delay : mParser.getInt( 15116 KEY_BATTERY_CHARGED_DELAY_MS, 15117 DEFAULT_BATTERY_CHARGED_DELAY_MS); 15118 } 15119 15120 private void updateTrackCpuTimesByProcStateLocked(boolean wasEnabled, boolean isEnabled) { 15121 TRACK_CPU_TIMES_BY_PROC_STATE = isEnabled; 15122 if (isEnabled && !wasEnabled) { 15123 mIsPerProcessStateCpuDataStale = true; 15124 mExternalSync.scheduleCpuSyncDueToSettingChange(); 15125 15126 mNumSingleUidCpuTimeReads = 0; 15127 mNumBatchedSingleUidCpuTimeReads = 0; 15128 mCpuTimeReadsTrackingStartTimeMs = mClocks.uptimeMillis(); 15129 } 15130 } 15131 15132 private void updateProcStateCpuTimesReadDelayMs(long oldDelayMillis, long newDelayMillis) { 15133 PROC_STATE_CPU_TIMES_READ_DELAY_MS = newDelayMillis; 15134 if (oldDelayMillis != newDelayMillis) { 15135 mNumSingleUidCpuTimeReads = 0; 15136 mNumBatchedSingleUidCpuTimeReads = 0; 15137 mCpuTimeReadsTrackingStartTimeMs = mClocks.uptimeMillis(); 15138 } 15139 } 15140 15141 private void updateKernelUidReadersThrottleTime(long oldTimeMs, long newTimeMs) { 15142 KERNEL_UID_READERS_THROTTLE_TIME = newTimeMs; 15143 if (oldTimeMs != newTimeMs) { 15144 mCpuUidUserSysTimeReader.setThrottle(KERNEL_UID_READERS_THROTTLE_TIME); 15145 mCpuUidFreqTimeReader.setThrottle(KERNEL_UID_READERS_THROTTLE_TIME); 15146 mCpuUidActiveTimeReader.setThrottle(KERNEL_UID_READERS_THROTTLE_TIME); 15147 mCpuUidClusterTimeReader 15148 .setThrottle(KERNEL_UID_READERS_THROTTLE_TIME); 15149 } 15150 } 15151 15152 private void updateUidRemoveDelay(long newTimeMs) { 15153 UID_REMOVE_DELAY_MS = newTimeMs; 15154 clearPendingRemovedUids(); 15155 } 15156 15157 public void dumpLocked(PrintWriter pw) { 15158 pw.print(KEY_TRACK_CPU_TIMES_BY_PROC_STATE); pw.print("="); 15159 pw.println(TRACK_CPU_TIMES_BY_PROC_STATE); 15160 pw.print(KEY_TRACK_CPU_ACTIVE_CLUSTER_TIME); pw.print("="); 15161 pw.println(TRACK_CPU_ACTIVE_CLUSTER_TIME); 15162 pw.print(KEY_PROC_STATE_CPU_TIMES_READ_DELAY_MS); pw.print("="); 15163 pw.println(PROC_STATE_CPU_TIMES_READ_DELAY_MS); 15164 pw.print(KEY_KERNEL_UID_READERS_THROTTLE_TIME); pw.print("="); 15165 pw.println(KERNEL_UID_READERS_THROTTLE_TIME); 15166 pw.print(KEY_EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS); pw.print("="); 15167 pw.println(EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS); 15168 pw.print(KEY_BATTERY_LEVEL_COLLECTION_DELAY_MS); pw.print("="); 15169 pw.println(BATTERY_LEVEL_COLLECTION_DELAY_MS); 15170 pw.print(KEY_MAX_HISTORY_FILES); pw.print("="); 15171 pw.println(MAX_HISTORY_FILES); 15172 pw.print(KEY_MAX_HISTORY_BUFFER_KB); pw.print("="); 15173 pw.println(MAX_HISTORY_BUFFER/1024); 15174 pw.print(KEY_BATTERY_CHARGED_DELAY_MS); pw.print("="); 15175 pw.println(BATTERY_CHARGED_DELAY_MS); 15176 } 15177 } 15178 15179 public long getExternalStatsCollectionRateLimitMs() { 15180 synchronized (this) { 15181 return mConstants.EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS; 15182 } 15183 } 15184 15185 @GuardedBy("this") 15186 public void dumpConstantsLocked(PrintWriter pw) { 15187 final IndentingPrintWriter iPw = new IndentingPrintWriter(pw, " "); 15188 iPw.println("BatteryStats constants:"); 15189 iPw.increaseIndent(); 15190 mConstants.dumpLocked(iPw); 15191 iPw.decreaseIndent(); 15192 } 15193 15194 @GuardedBy("this") 15195 public void dumpCpuStatsLocked(PrintWriter pw) { 15196 int size = mUidStats.size(); 15197 pw.println("Per UID CPU user & system time in ms:"); 15198 for (int i = 0; i < size; i++) { 15199 int u = mUidStats.keyAt(i); 15200 Uid uid = mUidStats.get(u); 15201 pw.print(" "); pw.print(u); pw.print(": "); 15202 pw.print(uid.getUserCpuTimeUs(STATS_SINCE_CHARGED) / 1000); pw.print(" "); 15203 pw.println(uid.getSystemCpuTimeUs(STATS_SINCE_CHARGED) / 1000); 15204 } 15205 15206 pw.println("Per UID CPU active time in ms:"); 15207 for (int i = 0; i < size; i++) { 15208 int u = mUidStats.keyAt(i); 15209 Uid uid = mUidStats.get(u); 15210 if (uid.getCpuActiveTime() > 0) { 15211 pw.print(" "); pw.print(u); pw.print(": "); pw.println(uid.getCpuActiveTime()); 15212 } 15213 } 15214 pw.println("Per UID CPU cluster time in ms:"); 15215 for (int i = 0; i < size; i++) { 15216 int u = mUidStats.keyAt(i); 15217 long[] times = mUidStats.get(u).getCpuClusterTimes(); 15218 if (times != null) { 15219 pw.print(" "); pw.print(u); pw.print(": "); pw.println(Arrays.toString(times)); 15220 } 15221 } 15222 pw.println("Per UID CPU frequency time in ms:"); 15223 for (int i = 0; i < size; i++) { 15224 int u = mUidStats.keyAt(i); 15225 long[] times = mUidStats.get(u).getCpuFreqTimes(STATS_SINCE_CHARGED); 15226 if (times != null) { 15227 pw.print(" "); pw.print(u); pw.print(": "); pw.println(Arrays.toString(times)); 15228 } 15229 } 15230 15231 updateSystemServiceCallStats(); 15232 if (mBinderThreadCpuTimesUs != null) { 15233 pw.println("Per UID System server binder time in ms:"); 15234 long[] systemServiceTimeAtCpuSpeeds = getSystemServiceTimeAtCpuSpeeds(); 15235 for (int i = 0; i < size; i++) { 15236 int u = mUidStats.keyAt(i); 15237 Uid uid = mUidStats.get(u); 15238 double proportionalSystemServiceUsage = uid.getProportionalSystemServiceUsage(); 15239 long timeUs = 0; 15240 for (int j = systemServiceTimeAtCpuSpeeds.length - 1; j >= 0; j--) { 15241 timeUs += systemServiceTimeAtCpuSpeeds[j] * proportionalSystemServiceUsage; 15242 } 15243 15244 pw.print(" "); 15245 pw.print(u); 15246 pw.print(": "); 15247 pw.println(timeUs / 1000); 15248 } 15249 } 15250 } 15251 15252 /** 15253 * Dump measured charge stats 15254 */ 15255 @GuardedBy("this") 15256 public void dumpMeasuredEnergyStatsLocked(PrintWriter pw) { 15257 pw.printf("On battery measured charge stats (microcoulombs) \n"); 15258 if (mGlobalMeasuredEnergyStats == null) { 15259 pw.printf(" Not supported on this device.\n"); 15260 return; 15261 } 15262 15263 dumpMeasuredEnergyStatsLocked(pw, "global usage", mGlobalMeasuredEnergyStats); 15264 15265 int size = mUidStats.size(); 15266 for (int i = 0; i < size; i++) { 15267 final int u = mUidStats.keyAt(i); 15268 final Uid uid = mUidStats.get(u); 15269 final String name = "uid " + uid.mUid; 15270 dumpMeasuredEnergyStatsLocked(pw, name, uid.mUidMeasuredEnergyStats); 15271 } 15272 } 15273 15274 /** Dump measured charge stats for the given uid */ 15275 @GuardedBy("this") 15276 private void dumpMeasuredEnergyStatsLocked(PrintWriter pw, String name, 15277 MeasuredEnergyStats stats) { 15278 if (stats == null) return; 15279 final IndentingPrintWriter iPw = new IndentingPrintWriter(pw, " "); 15280 iPw.increaseIndent(); 15281 iPw.printf("%s:\n", name); 15282 iPw.increaseIndent(); 15283 stats.dump(iPw); 15284 iPw.decreaseIndent(); 15285 } 15286 15287 final ReentrantLock mWriteLock = new ReentrantLock(); 15288 15289 public void writeAsyncLocked() { 15290 writeStatsLocked(false); 15291 writeHistoryLocked(false); 15292 } 15293 15294 public void writeSyncLocked() { 15295 writeStatsLocked(true); 15296 writeHistoryLocked(true); 15297 } 15298 15299 void writeStatsLocked(boolean sync) { 15300 if (mStatsFile == null) { 15301 Slog.w(TAG, 15302 "writeStatsLocked: no file associated with this instance"); 15303 return; 15304 } 15305 15306 if (mShuttingDown) { 15307 return; 15308 } 15309 15310 final Parcel p = Parcel.obtain(); 15311 final long start = SystemClock.uptimeMillis(); 15312 writeSummaryToParcel(p, false/*history is in separate file*/); 15313 if (DEBUG) { 15314 Slog.d(TAG, "writeSummaryToParcel duration ms:" 15315 + (SystemClock.uptimeMillis() - start) + " bytes:" + p.dataSize()); 15316 } 15317 mLastWriteTimeMs = mClocks.elapsedRealtime(); 15318 writeParcelToFileLocked(p, mStatsFile, sync); 15319 } 15320 15321 void writeHistoryLocked(boolean sync) { 15322 if (mBatteryStatsHistory.getActiveFile() == null) { 15323 Slog.w(TAG, 15324 "writeHistoryLocked: no history file associated with this instance"); 15325 return; 15326 } 15327 15328 if (mShuttingDown) { 15329 return; 15330 } 15331 15332 Parcel p = Parcel.obtain(); 15333 final long start = SystemClock.uptimeMillis(); 15334 writeHistoryBuffer(p, true); 15335 if (DEBUG) { 15336 Slog.d(TAG, "writeHistoryBuffer duration ms:" 15337 + (SystemClock.uptimeMillis() - start) + " bytes:" + p.dataSize()); 15338 } 15339 writeParcelToFileLocked(p, mBatteryStatsHistory.getActiveFile(), sync); 15340 } 15341 15342 void writeParcelToFileLocked(Parcel p, AtomicFile file, boolean sync) { 15343 if (sync) { 15344 commitPendingDataToDisk(p, file); 15345 } else { 15346 BackgroundThread.getHandler().post(new Runnable() { 15347 @Override public void run() { 15348 commitPendingDataToDisk(p, file); 15349 } 15350 }); 15351 } 15352 } 15353 15354 private void commitPendingDataToDisk(Parcel p, AtomicFile file) { 15355 mWriteLock.lock(); 15356 FileOutputStream fos = null; 15357 try { 15358 final long startTimeMs = SystemClock.uptimeMillis(); 15359 fos = file.startWrite(); 15360 fos.write(p.marshall()); 15361 fos.flush(); 15362 file.finishWrite(fos); 15363 if (DEBUG) { 15364 Slog.d(TAG, "commitPendingDataToDisk file:" + file.getBaseFile().getPath() 15365 + " duration ms:" + (SystemClock.uptimeMillis() - startTimeMs) 15366 + " bytes:" + p.dataSize()); 15367 } 15368 com.android.internal.logging.EventLogTags.writeCommitSysConfigFile( 15369 "batterystats", SystemClock.uptimeMillis() - startTimeMs); 15370 } catch (IOException e) { 15371 Slog.w(TAG, "Error writing battery statistics", e); 15372 file.failWrite(fos); 15373 } finally { 15374 p.recycle(); 15375 mWriteLock.unlock(); 15376 } 15377 } 15378 15379 @UnsupportedAppUsage 15380 public void readLocked() { 15381 if (mDailyFile != null) { 15382 readDailyStatsLocked(); 15383 } 15384 15385 if (mStatsFile == null) { 15386 Slog.w(TAG, "readLocked: no file associated with this instance"); 15387 return; 15388 } 15389 15390 final AtomicFile activeHistoryFile = mBatteryStatsHistory.getActiveFile(); 15391 if (activeHistoryFile == null) { 15392 Slog.w(TAG, 15393 "readLocked: no history file associated with this instance"); 15394 return; 15395 } 15396 15397 mUidStats.clear(); 15398 15399 Parcel stats = Parcel.obtain(); 15400 try { 15401 final long start = SystemClock.uptimeMillis(); 15402 if (mStatsFile.exists()) { 15403 byte[] raw = mStatsFile.readFully(); 15404 stats.unmarshall(raw, 0, raw.length); 15405 stats.setDataPosition(0); 15406 readSummaryFromParcel(stats); 15407 if (DEBUG) { 15408 Slog.d(TAG, "readLocked stats file:" + mStatsFile.getBaseFile().getPath() 15409 + " bytes:" + raw.length + " takes ms:" + (SystemClock.uptimeMillis() 15410 - start)); 15411 } 15412 } 15413 } catch (Exception e) { 15414 Slog.e(TAG, "Error reading battery statistics", e); 15415 resetAllStatsLocked(SystemClock.uptimeMillis(), SystemClock.elapsedRealtime(), 15416 RESET_REASON_CORRUPT_FILE); 15417 } finally { 15418 stats.recycle(); 15419 } 15420 15421 Parcel history = Parcel.obtain(); 15422 try { 15423 final long start = SystemClock.uptimeMillis(); 15424 if (activeHistoryFile.exists()) { 15425 byte[] raw = activeHistoryFile.readFully(); 15426 if (raw.length > 0) { 15427 history.unmarshall(raw, 0, raw.length); 15428 history.setDataPosition(0); 15429 readHistoryBuffer(history); 15430 } 15431 if (DEBUG) { 15432 Slog.d(TAG, "readLocked history file::" 15433 + activeHistoryFile.getBaseFile().getPath() 15434 + " bytes:" + raw.length + " takes ms:" + (SystemClock.uptimeMillis() 15435 - start)); 15436 } 15437 } 15438 } catch (Exception e) { 15439 Slog.e(TAG, "Error reading battery history", e); 15440 clearHistoryLocked(); 15441 mBatteryStatsHistory.resetAllFiles(); 15442 } finally { 15443 history.recycle(); 15444 } 15445 15446 mEndPlatformVersion = Build.ID; 15447 15448 if (mHistoryBuffer.dataPosition() > 0 15449 || mBatteryStatsHistory.getFilesNumbers().size() > 1) { 15450 mRecordingHistory = true; 15451 final long elapsedRealtimeMs = mClocks.elapsedRealtime(); 15452 final long uptimeMs = mClocks.uptimeMillis(); 15453 addHistoryBufferLocked(elapsedRealtimeMs, HistoryItem.CMD_START, mHistoryCur); 15454 startRecordingHistory(elapsedRealtimeMs, uptimeMs, false); 15455 } 15456 15457 recordDailyStatsIfNeededLocked(false, mClocks.currentTimeMillis()); 15458 } 15459 15460 public int describeContents() { 15461 return 0; 15462 } 15463 15464 void readHistoryBuffer(Parcel in) throws ParcelFormatException { 15465 final int version = in.readInt(); 15466 if (version != VERSION) { 15467 Slog.w("BatteryStats", "readHistoryBuffer: version got " + version 15468 + ", expected " + VERSION + "; erasing old stats"); 15469 return; 15470 } 15471 15472 final long historyBaseTime = in.readLong(); 15473 15474 mHistoryBuffer.setDataSize(0); 15475 mHistoryBuffer.setDataPosition(0); 15476 15477 int bufSize = in.readInt(); 15478 int curPos = in.dataPosition(); 15479 if (bufSize >= (mConstants.MAX_HISTORY_BUFFER*100)) { 15480 throw new ParcelFormatException("File corrupt: history data buffer too large " + 15481 bufSize); 15482 } else if ((bufSize&~3) != bufSize) { 15483 throw new ParcelFormatException("File corrupt: history data buffer not aligned " + 15484 bufSize); 15485 } else { 15486 if (DEBUG_HISTORY) Slog.i(TAG, "***************** READING NEW HISTORY: " + bufSize 15487 + " bytes at " + curPos); 15488 mHistoryBuffer.appendFrom(in, curPos, bufSize); 15489 in.setDataPosition(curPos + bufSize); 15490 } 15491 15492 if (DEBUG_HISTORY) { 15493 StringBuilder sb = new StringBuilder(128); 15494 sb.append("****************** OLD mHistoryBaseTimeMs: "); 15495 TimeUtils.formatDuration(mHistoryBaseTimeMs, sb); 15496 Slog.i(TAG, sb.toString()); 15497 } 15498 mHistoryBaseTimeMs = historyBaseTime; 15499 if (DEBUG_HISTORY) { 15500 StringBuilder sb = new StringBuilder(128); 15501 sb.append("****************** NEW mHistoryBaseTimeMs: "); 15502 TimeUtils.formatDuration(mHistoryBaseTimeMs, sb); 15503 Slog.i(TAG, sb.toString()); 15504 } 15505 15506 // We are just arbitrarily going to insert 1 minute from the sample of 15507 // the last run until samples in this run. 15508 if (mHistoryBaseTimeMs > 0) { 15509 long oldnow = mClocks.elapsedRealtime(); 15510 mHistoryBaseTimeMs = mHistoryBaseTimeMs - oldnow + 1; 15511 if (DEBUG_HISTORY) { 15512 StringBuilder sb = new StringBuilder(128); 15513 sb.append("****************** ADJUSTED mHistoryBaseTimeMs: "); 15514 TimeUtils.formatDuration(mHistoryBaseTimeMs, sb); 15515 Slog.i(TAG, sb.toString()); 15516 } 15517 } 15518 } 15519 15520 void writeHistoryBuffer(Parcel out, boolean inclData) { 15521 if (DEBUG_HISTORY) { 15522 StringBuilder sb = new StringBuilder(128); 15523 sb.append("****************** WRITING mHistoryBaseTimeMs: "); 15524 TimeUtils.formatDuration(mHistoryBaseTimeMs, sb); 15525 sb.append(" mLastHistoryElapsedRealtimeMs: "); 15526 TimeUtils.formatDuration(mLastHistoryElapsedRealtimeMs, sb); 15527 Slog.i(TAG, sb.toString()); 15528 } 15529 out.writeInt(VERSION); 15530 out.writeLong(mHistoryBaseTimeMs + mLastHistoryElapsedRealtimeMs); 15531 if (!inclData) { 15532 out.writeInt(0); 15533 out.writeInt(0); 15534 return; 15535 } 15536 15537 out.writeInt(mHistoryBuffer.dataSize()); 15538 if (DEBUG_HISTORY) Slog.i(TAG, "***************** WRITING HISTORY: " 15539 + mHistoryBuffer.dataSize() + " bytes at " + out.dataPosition()); 15540 out.appendFrom(mHistoryBuffer, 0, mHistoryBuffer.dataSize()); 15541 } 15542 15543 public void readSummaryFromParcel(Parcel in) throws ParcelFormatException { 15544 final int version = in.readInt(); 15545 if (version != VERSION) { 15546 Slog.w("BatteryStats", "readFromParcel: version got " + version 15547 + ", expected " + VERSION + "; erasing old stats"); 15548 return; 15549 } 15550 15551 boolean inclHistory = in.readBoolean(); 15552 if (inclHistory) { 15553 readHistoryBuffer(in); 15554 mBatteryStatsHistory.readFromParcel(in); 15555 } 15556 15557 mHistoryTagPool.clear(); 15558 mNextHistoryTagIdx = 0; 15559 mNumHistoryTagChars = 0; 15560 15561 int numTags = in.readInt(); 15562 for (int i=0; i<numTags; i++) { 15563 int idx = in.readInt(); 15564 String str = in.readString(); 15565 if (str == null) { 15566 throw new ParcelFormatException("null history tag string"); 15567 } 15568 int uid = in.readInt(); 15569 HistoryTag tag = new HistoryTag(); 15570 tag.string = str; 15571 tag.uid = uid; 15572 tag.poolIdx = idx; 15573 mHistoryTagPool.put(tag, idx); 15574 if (idx >= mNextHistoryTagIdx) { 15575 mNextHistoryTagIdx = idx+1; 15576 } 15577 mNumHistoryTagChars += tag.string.length() + 1; 15578 } 15579 15580 mStartCount = in.readInt(); 15581 mUptimeUs = in.readLong(); 15582 mRealtimeUs = in.readLong(); 15583 mStartClockTimeMs = in.readLong(); 15584 mStartPlatformVersion = in.readString(); 15585 mEndPlatformVersion = in.readString(); 15586 mOnBatteryTimeBase.readSummaryFromParcel(in); 15587 mOnBatteryScreenOffTimeBase.readSummaryFromParcel(in); 15588 mDischargeUnplugLevel = in.readInt(); 15589 mDischargePlugLevel = in.readInt(); 15590 mDischargeCurrentLevel = in.readInt(); 15591 mCurrentBatteryLevel = in.readInt(); 15592 mEstimatedBatteryCapacityMah = in.readInt(); 15593 mLastLearnedBatteryCapacityUah = in.readInt(); 15594 mMinLearnedBatteryCapacityUah = in.readInt(); 15595 mMaxLearnedBatteryCapacityUah = in.readInt(); 15596 mLowDischargeAmountSinceCharge = in.readInt(); 15597 mHighDischargeAmountSinceCharge = in.readInt(); 15598 mDischargeAmountScreenOnSinceCharge = in.readInt(); 15599 mDischargeAmountScreenOffSinceCharge = in.readInt(); 15600 mDischargeAmountScreenDozeSinceCharge = in.readInt(); 15601 mDischargeStepTracker.readFromParcel(in); 15602 mChargeStepTracker.readFromParcel(in); 15603 mDailyDischargeStepTracker.readFromParcel(in); 15604 mDailyChargeStepTracker.readFromParcel(in); 15605 mDischargeCounter.readSummaryFromParcelLocked(in); 15606 mDischargeScreenOffCounter.readSummaryFromParcelLocked(in); 15607 mDischargeScreenDozeCounter.readSummaryFromParcelLocked(in); 15608 mDischargeLightDozeCounter.readSummaryFromParcelLocked(in); 15609 mDischargeDeepDozeCounter.readSummaryFromParcelLocked(in); 15610 int NPKG = in.readInt(); 15611 if (NPKG > 0) { 15612 mDailyPackageChanges = new ArrayList<>(NPKG); 15613 while (NPKG > 0) { 15614 NPKG--; 15615 PackageChange pc = new PackageChange(); 15616 pc.mPackageName = in.readString(); 15617 pc.mUpdate = in.readInt() != 0; 15618 pc.mVersionCode = in.readLong(); 15619 mDailyPackageChanges.add(pc); 15620 } 15621 } else { 15622 mDailyPackageChanges = null; 15623 } 15624 mDailyStartTimeMs = in.readLong(); 15625 mNextMinDailyDeadlineMs = in.readLong(); 15626 mNextMaxDailyDeadlineMs = in.readLong(); 15627 mBatteryTimeToFullSeconds = in.readLong(); 15628 15629 /** 15630 * WARNING: Supported buckets may have changed across boots. Bucket mismatch is handled 15631 * later when {@link #initMeasuredEnergyStatsLocked} is called. 15632 */ 15633 mGlobalMeasuredEnergyStats = MeasuredEnergyStats.createAndReadSummaryFromParcel(in); 15634 15635 mStartCount++; 15636 15637 mScreenState = Display.STATE_UNKNOWN; 15638 mScreenOnTimer.readSummaryFromParcelLocked(in); 15639 mScreenDozeTimer.readSummaryFromParcelLocked(in); 15640 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 15641 mScreenBrightnessTimer[i].readSummaryFromParcelLocked(in); 15642 } 15643 mInteractive = false; 15644 mInteractiveTimer.readSummaryFromParcelLocked(in); 15645 mPhoneOn = false; 15646 mPowerSaveModeEnabledTimer.readSummaryFromParcelLocked(in); 15647 mLongestLightIdleTimeMs = in.readLong(); 15648 mLongestFullIdleTimeMs = in.readLong(); 15649 mDeviceIdleModeLightTimer.readSummaryFromParcelLocked(in); 15650 mDeviceIdleModeFullTimer.readSummaryFromParcelLocked(in); 15651 mDeviceLightIdlingTimer.readSummaryFromParcelLocked(in); 15652 mDeviceIdlingTimer.readSummaryFromParcelLocked(in); 15653 mPhoneOnTimer.readSummaryFromParcelLocked(in); 15654 for (int i = 0; i < CellSignalStrength.getNumSignalStrengthLevels(); i++) { 15655 mPhoneSignalStrengthsTimer[i].readSummaryFromParcelLocked(in); 15656 } 15657 mPhoneSignalScanningTimer.readSummaryFromParcelLocked(in); 15658 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 15659 mPhoneDataConnectionsTimer[i].readSummaryFromParcelLocked(in); 15660 } 15661 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 15662 mNetworkByteActivityCounters[i].readSummaryFromParcelLocked(in); 15663 mNetworkPacketActivityCounters[i].readSummaryFromParcelLocked(in); 15664 } 15665 mMobileRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW; 15666 mMobileRadioActiveTimer.readSummaryFromParcelLocked(in); 15667 mMobileRadioActivePerAppTimer.readSummaryFromParcelLocked(in); 15668 mMobileRadioActiveAdjustedTime.readSummaryFromParcelLocked(in); 15669 mMobileRadioActiveUnknownTime.readSummaryFromParcelLocked(in); 15670 mMobileRadioActiveUnknownCount.readSummaryFromParcelLocked(in); 15671 mWifiMulticastWakelockTimer.readSummaryFromParcelLocked(in); 15672 mWifiRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW; 15673 mWifiOn = false; 15674 mWifiOnTimer.readSummaryFromParcelLocked(in); 15675 mGlobalWifiRunning = false; 15676 mGlobalWifiRunningTimer.readSummaryFromParcelLocked(in); 15677 for (int i=0; i<NUM_WIFI_STATES; i++) { 15678 mWifiStateTimer[i].readSummaryFromParcelLocked(in); 15679 } 15680 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) { 15681 mWifiSupplStateTimer[i].readSummaryFromParcelLocked(in); 15682 } 15683 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { 15684 mWifiSignalStrengthsTimer[i].readSummaryFromParcelLocked(in); 15685 } 15686 mWifiActiveTimer.readSummaryFromParcelLocked(in); 15687 mWifiActivity.readSummaryFromParcel(in); 15688 for (int i=0; i<mGpsSignalQualityTimer.length; i++) { 15689 mGpsSignalQualityTimer[i].readSummaryFromParcelLocked(in); 15690 } 15691 mBluetoothActivity.readSummaryFromParcel(in); 15692 mModemActivity.readSummaryFromParcel(in); 15693 mHasWifiReporting = in.readInt() != 0; 15694 mHasBluetoothReporting = in.readInt() != 0; 15695 mHasModemReporting = in.readInt() != 0; 15696 15697 mNumConnectivityChange = in.readInt(); 15698 mFlashlightOnNesting = 0; 15699 mFlashlightOnTimer.readSummaryFromParcelLocked(in); 15700 mCameraOnNesting = 0; 15701 mCameraOnTimer.readSummaryFromParcelLocked(in); 15702 mBluetoothScanNesting = 0; 15703 mBluetoothScanTimer.readSummaryFromParcelLocked(in); 15704 15705 int NRPMS = in.readInt(); 15706 if (NRPMS > 10000) { 15707 throw new ParcelFormatException("File corrupt: too many rpm stats " + NRPMS); 15708 } 15709 for (int irpm = 0; irpm < NRPMS; irpm++) { 15710 if (in.readInt() != 0) { 15711 String rpmName = in.readString(); 15712 getRpmTimerLocked(rpmName).readSummaryFromParcelLocked(in); 15713 } 15714 } 15715 int NSORPMS = in.readInt(); 15716 if (NSORPMS > 10000) { 15717 throw new ParcelFormatException("File corrupt: too many screen-off rpm stats " + NSORPMS); 15718 } 15719 for (int irpm = 0; irpm < NSORPMS; irpm++) { 15720 if (in.readInt() != 0) { 15721 String rpmName = in.readString(); 15722 getScreenOffRpmTimerLocked(rpmName).readSummaryFromParcelLocked(in); 15723 } 15724 } 15725 15726 int NKW = in.readInt(); 15727 if (NKW > 10000) { 15728 throw new ParcelFormatException("File corrupt: too many kernel wake locks " + NKW); 15729 } 15730 for (int ikw = 0; ikw < NKW; ikw++) { 15731 if (in.readInt() != 0) { 15732 String kwltName = in.readString(); 15733 getKernelWakelockTimerLocked(kwltName).readSummaryFromParcelLocked(in); 15734 } 15735 } 15736 15737 int NWR = in.readInt(); 15738 if (NWR > 10000) { 15739 throw new ParcelFormatException("File corrupt: too many wakeup reasons " + NWR); 15740 } 15741 for (int iwr = 0; iwr < NWR; iwr++) { 15742 if (in.readInt() != 0) { 15743 String reasonName = in.readString(); 15744 getWakeupReasonTimerLocked(reasonName).readSummaryFromParcelLocked(in); 15745 } 15746 } 15747 15748 int NMS = in.readInt(); 15749 for (int ims = 0; ims < NMS; ims++) { 15750 if (in.readInt() != 0) { 15751 long kmstName = in.readLong(); 15752 getKernelMemoryTimerLocked(kmstName).readSummaryFromParcelLocked(in); 15753 } 15754 } 15755 15756 final int NU = in.readInt(); 15757 if (NU > 10000) { 15758 throw new ParcelFormatException("File corrupt: too many uids " + NU); 15759 } 15760 final long elapsedRealtimeMs = mClocks.elapsedRealtime(); 15761 final long uptimeMs = mClocks.uptimeMillis(); 15762 for (int iu = 0; iu < NU; iu++) { 15763 int uid = in.readInt(); 15764 Uid u = new Uid(this, uid, elapsedRealtimeMs, uptimeMs); 15765 mUidStats.put(uid, u); 15766 15767 u.mOnBatteryBackgroundTimeBase.readSummaryFromParcel(in); 15768 u.mOnBatteryScreenOffBackgroundTimeBase.readSummaryFromParcel(in); 15769 15770 u.mWifiRunning = false; 15771 if (in.readInt() != 0) { 15772 u.mWifiRunningTimer.readSummaryFromParcelLocked(in); 15773 } 15774 u.mFullWifiLockOut = false; 15775 if (in.readInt() != 0) { 15776 u.mFullWifiLockTimer.readSummaryFromParcelLocked(in); 15777 } 15778 u.mWifiScanStarted = false; 15779 if (in.readInt() != 0) { 15780 u.mWifiScanTimer.readSummaryFromParcelLocked(in); 15781 } 15782 u.mWifiBatchedScanBinStarted = Uid.NO_BATCHED_SCAN_STARTED; 15783 for (int i = 0; i < Uid.NUM_WIFI_BATCHED_SCAN_BINS; i++) { 15784 if (in.readInt() != 0) { 15785 u.makeWifiBatchedScanBin(i, null); 15786 u.mWifiBatchedScanTimer[i].readSummaryFromParcelLocked(in); 15787 } 15788 } 15789 u.mWifiMulticastWakelockCount = 0; 15790 if (in.readInt() != 0) { 15791 u.mWifiMulticastTimer.readSummaryFromParcelLocked(in); 15792 } 15793 if (in.readInt() != 0) { 15794 u.createAudioTurnedOnTimerLocked().readSummaryFromParcelLocked(in); 15795 } 15796 if (in.readInt() != 0) { 15797 u.createVideoTurnedOnTimerLocked().readSummaryFromParcelLocked(in); 15798 } 15799 if (in.readInt() != 0) { 15800 u.createFlashlightTurnedOnTimerLocked().readSummaryFromParcelLocked(in); 15801 } 15802 if (in.readInt() != 0) { 15803 u.createCameraTurnedOnTimerLocked().readSummaryFromParcelLocked(in); 15804 } 15805 if (in.readInt() != 0) { 15806 u.createForegroundActivityTimerLocked().readSummaryFromParcelLocked(in); 15807 } 15808 if (in.readInt() != 0) { 15809 u.createForegroundServiceTimerLocked().readSummaryFromParcelLocked(in); 15810 } 15811 if (in.readInt() != 0) { 15812 u.createAggregatedPartialWakelockTimerLocked().readSummaryFromParcelLocked(in); 15813 } 15814 if (in.readInt() != 0) { 15815 u.createBluetoothScanTimerLocked().readSummaryFromParcelLocked(in); 15816 } 15817 if (in.readInt() != 0) { 15818 u.createBluetoothUnoptimizedScanTimerLocked().readSummaryFromParcelLocked(in); 15819 } 15820 if (in.readInt() != 0) { 15821 u.createBluetoothScanResultCounterLocked().readSummaryFromParcelLocked(in); 15822 } 15823 if (in.readInt() != 0) { 15824 u.createBluetoothScanResultBgCounterLocked().readSummaryFromParcelLocked(in); 15825 } 15826 u.mProcessState = ActivityManager.PROCESS_STATE_NONEXISTENT; 15827 for (int i = 0; i < Uid.NUM_PROCESS_STATE; i++) { 15828 if (in.readInt() != 0) { 15829 u.makeProcessState(i, null); 15830 u.mProcessStateTimer[i].readSummaryFromParcelLocked(in); 15831 } 15832 } 15833 if (in.readInt() != 0) { 15834 u.createVibratorOnTimerLocked().readSummaryFromParcelLocked(in); 15835 } 15836 15837 if (in.readInt() != 0) { 15838 if (u.mUserActivityCounters == null) { 15839 u.initUserActivityLocked(); 15840 } 15841 for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) { 15842 u.mUserActivityCounters[i].readSummaryFromParcelLocked(in); 15843 } 15844 } 15845 15846 if (in.readInt() != 0) { 15847 if (u.mNetworkByteActivityCounters == null) { 15848 u.initNetworkActivityLocked(); 15849 } 15850 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 15851 u.mNetworkByteActivityCounters[i].readSummaryFromParcelLocked(in); 15852 u.mNetworkPacketActivityCounters[i].readSummaryFromParcelLocked(in); 15853 } 15854 u.mMobileRadioActiveTime.readSummaryFromParcelLocked(in); 15855 u.mMobileRadioActiveCount.readSummaryFromParcelLocked(in); 15856 } 15857 15858 u.mUserCpuTime.readSummaryFromParcelLocked(in); 15859 u.mSystemCpuTime.readSummaryFromParcelLocked(in); 15860 15861 if (in.readInt() != 0) { 15862 final int numClusters = in.readInt(); 15863 if (mPowerProfile != null && mPowerProfile.getNumCpuClusters() != numClusters) { 15864 throw new ParcelFormatException("Incompatible cpu cluster arrangement"); 15865 } 15866 detachIfNotNull(u.mCpuClusterSpeedTimesUs); 15867 u.mCpuClusterSpeedTimesUs = new LongSamplingCounter[numClusters][]; 15868 for (int cluster = 0; cluster < numClusters; cluster++) { 15869 if (in.readInt() != 0) { 15870 final int NSB = in.readInt(); 15871 if (mPowerProfile != null && 15872 mPowerProfile.getNumSpeedStepsInCpuCluster(cluster) != NSB) { 15873 throw new ParcelFormatException("File corrupt: too many speed bins " + 15874 NSB); 15875 } 15876 15877 u.mCpuClusterSpeedTimesUs[cluster] = new LongSamplingCounter[NSB]; 15878 for (int speed = 0; speed < NSB; speed++) { 15879 if (in.readInt() != 0) { 15880 u.mCpuClusterSpeedTimesUs[cluster][speed] = new LongSamplingCounter( 15881 mOnBatteryTimeBase); 15882 u.mCpuClusterSpeedTimesUs[cluster][speed].readSummaryFromParcelLocked(in); 15883 } 15884 } 15885 } else { 15886 u.mCpuClusterSpeedTimesUs[cluster] = null; 15887 } 15888 } 15889 } else { 15890 detachIfNotNull(u.mCpuClusterSpeedTimesUs); 15891 u.mCpuClusterSpeedTimesUs = null; 15892 } 15893 15894 detachIfNotNull(u.mCpuFreqTimeMs); 15895 u.mCpuFreqTimeMs = LongSamplingCounterArray.readSummaryFromParcelLocked( 15896 in, mOnBatteryTimeBase); 15897 detachIfNotNull(u.mScreenOffCpuFreqTimeMs); 15898 u.mScreenOffCpuFreqTimeMs = LongSamplingCounterArray.readSummaryFromParcelLocked( 15899 in, mOnBatteryScreenOffTimeBase); 15900 15901 u.mCpuActiveTimeMs.readSummaryFromParcelLocked(in); 15902 u.mCpuClusterTimesMs.readSummaryFromParcelLocked(in); 15903 15904 int length = in.readInt(); 15905 if (length == Uid.NUM_PROCESS_STATE) { 15906 detachIfNotNull(u.mProcStateTimeMs); 15907 u.mProcStateTimeMs = new LongSamplingCounterArray[length]; 15908 for (int procState = 0; procState < length; ++procState) { 15909 u.mProcStateTimeMs[procState] 15910 = LongSamplingCounterArray.readSummaryFromParcelLocked( 15911 in, mOnBatteryTimeBase); 15912 } 15913 } else { 15914 detachIfNotNull(u.mProcStateTimeMs); 15915 u.mProcStateTimeMs = null; 15916 } 15917 length = in.readInt(); 15918 if (length == Uid.NUM_PROCESS_STATE) { 15919 detachIfNotNull(u.mProcStateScreenOffTimeMs); 15920 u.mProcStateScreenOffTimeMs = new LongSamplingCounterArray[length]; 15921 for (int procState = 0; procState < length; ++procState) { 15922 u.mProcStateScreenOffTimeMs[procState] 15923 = LongSamplingCounterArray.readSummaryFromParcelLocked( 15924 in, mOnBatteryScreenOffTimeBase); 15925 } 15926 } else { 15927 detachIfNotNull(u.mProcStateScreenOffTimeMs); 15928 u.mProcStateScreenOffTimeMs = null; 15929 } 15930 15931 if (in.readInt() != 0) { 15932 detachIfNotNull(u.mMobileRadioApWakeupCount); 15933 u.mMobileRadioApWakeupCount = new LongSamplingCounter(mOnBatteryTimeBase); 15934 u.mMobileRadioApWakeupCount.readSummaryFromParcelLocked(in); 15935 } else { 15936 detachIfNotNull(u.mMobileRadioApWakeupCount); 15937 u.mMobileRadioApWakeupCount = null; 15938 } 15939 15940 if (in.readInt() != 0) { 15941 detachIfNotNull(u.mWifiRadioApWakeupCount); 15942 u.mWifiRadioApWakeupCount = new LongSamplingCounter(mOnBatteryTimeBase); 15943 u.mWifiRadioApWakeupCount.readSummaryFromParcelLocked(in); 15944 } else { 15945 detachIfNotNull(u.mWifiRadioApWakeupCount); 15946 u.mWifiRadioApWakeupCount = null; 15947 } 15948 15949 u.mUidMeasuredEnergyStats = MeasuredEnergyStats.createAndReadSummaryFromParcel(in, 15950 /* template */ mGlobalMeasuredEnergyStats); 15951 15952 int NW = in.readInt(); 15953 if (NW > (MAX_WAKELOCKS_PER_UID+1)) { 15954 throw new ParcelFormatException("File corrupt: too many wake locks " + NW); 15955 } 15956 for (int iw = 0; iw < NW; iw++) { 15957 String wlName = in.readString(); 15958 u.readWakeSummaryFromParcelLocked(wlName, in); 15959 } 15960 15961 int NS = in.readInt(); 15962 if (NS > (MAX_WAKELOCKS_PER_UID+1)) { 15963 throw new ParcelFormatException("File corrupt: too many syncs " + NS); 15964 } 15965 for (int is = 0; is < NS; is++) { 15966 String name = in.readString(); 15967 u.readSyncSummaryFromParcelLocked(name, in); 15968 } 15969 15970 int NJ = in.readInt(); 15971 if (NJ > (MAX_WAKELOCKS_PER_UID+1)) { 15972 throw new ParcelFormatException("File corrupt: too many job timers " + NJ); 15973 } 15974 for (int ij = 0; ij < NJ; ij++) { 15975 String name = in.readString(); 15976 u.readJobSummaryFromParcelLocked(name, in); 15977 } 15978 15979 u.readJobCompletionsFromParcelLocked(in); 15980 15981 u.mJobsDeferredEventCount.readSummaryFromParcelLocked(in); 15982 u.mJobsDeferredCount.readSummaryFromParcelLocked(in); 15983 u.mJobsFreshnessTimeMs.readSummaryFromParcelLocked(in); 15984 detachIfNotNull(u.mJobsFreshnessBuckets); 15985 for (int i = 0; i < JOB_FRESHNESS_BUCKETS.length; i++) { 15986 if (in.readInt() != 0) { 15987 u.mJobsFreshnessBuckets[i] = new Counter(u.mBsi.mOnBatteryTimeBase); 15988 u.mJobsFreshnessBuckets[i].readSummaryFromParcelLocked(in); 15989 } 15990 } 15991 15992 int NP = in.readInt(); 15993 if (NP > 1000) { 15994 throw new ParcelFormatException("File corrupt: too many sensors " + NP); 15995 } 15996 for (int is = 0; is < NP; is++) { 15997 int seNumber = in.readInt(); 15998 if (in.readInt() != 0) { 15999 u.getSensorTimerLocked(seNumber, true).readSummaryFromParcelLocked(in); 16000 } 16001 } 16002 16003 NP = in.readInt(); 16004 if (NP > 1000) { 16005 throw new ParcelFormatException("File corrupt: too many processes " + NP); 16006 } 16007 for (int ip = 0; ip < NP; ip++) { 16008 String procName = in.readString(); 16009 Uid.Proc p = u.getProcessStatsLocked(procName); 16010 p.mUserTimeMs = in.readLong(); 16011 p.mSystemTimeMs = in.readLong(); 16012 p.mForegroundTimeMs = in.readLong(); 16013 p.mStarts = in.readInt(); 16014 p.mNumCrashes = in.readInt(); 16015 p.mNumAnrs = in.readInt(); 16016 p.readExcessivePowerFromParcelLocked(in); 16017 } 16018 16019 NP = in.readInt(); 16020 if (NP > 10000) { 16021 throw new ParcelFormatException("File corrupt: too many packages " + NP); 16022 } 16023 for (int ip = 0; ip < NP; ip++) { 16024 String pkgName = in.readString(); 16025 detachIfNotNull(u.mPackageStats.get(pkgName)); 16026 Uid.Pkg p = u.getPackageStatsLocked(pkgName); 16027 final int NWA = in.readInt(); 16028 if (NWA > 10000) { 16029 throw new ParcelFormatException("File corrupt: too many wakeup alarms " + NWA); 16030 } 16031 p.mWakeupAlarms.clear(); 16032 for (int iwa = 0; iwa < NWA; iwa++) { 16033 String tag = in.readString(); 16034 Counter c = new Counter(mOnBatteryScreenOffTimeBase); 16035 c.readSummaryFromParcelLocked(in); 16036 p.mWakeupAlarms.put(tag, c); 16037 } 16038 NS = in.readInt(); 16039 if (NS > 10000) { 16040 throw new ParcelFormatException("File corrupt: too many services " + NS); 16041 } 16042 for (int is = 0; is < NS; is++) { 16043 String servName = in.readString(); 16044 Uid.Pkg.Serv s = u.getServiceStatsLocked(pkgName, servName); 16045 s.mStartTimeMs = in.readLong(); 16046 s.mStarts = in.readInt(); 16047 s.mLaunches = in.readInt(); 16048 } 16049 } 16050 } 16051 16052 mBinderThreadCpuTimesUs = 16053 LongSamplingCounterArray.readSummaryFromParcelLocked(in, mOnBatteryTimeBase); 16054 } 16055 16056 /** 16057 * Writes a summary of the statistics to a Parcel, in a format suitable to be written to 16058 * disk. This format does not allow a lossless round-trip. 16059 * 16060 * @param out the Parcel to be written to. 16061 */ 16062 public void writeSummaryToParcel(Parcel out, boolean inclHistory) { 16063 pullPendingStateUpdatesLocked(); 16064 16065 // Pull the clock time. This may update the time and make a new history entry 16066 // if we had originally pulled a time before the RTC was set. 16067 getStartClockTime(); 16068 16069 final long NOW_SYS = mClocks.uptimeMillis() * 1000; 16070 final long NOWREAL_SYS = mClocks.elapsedRealtime() * 1000; 16071 16072 out.writeInt(VERSION); 16073 16074 out.writeBoolean(inclHistory); 16075 if (inclHistory) { 16076 writeHistoryBuffer(out, true); 16077 mBatteryStatsHistory.writeToParcel(out); 16078 } 16079 16080 out.writeInt(mHistoryTagPool.size()); 16081 for (HashMap.Entry<HistoryTag, Integer> ent : mHistoryTagPool.entrySet()) { 16082 HistoryTag tag = ent.getKey(); 16083 out.writeInt(ent.getValue()); 16084 out.writeString(tag.string); 16085 out.writeInt(tag.uid); 16086 } 16087 16088 out.writeInt(mStartCount); 16089 out.writeLong(computeUptime(NOW_SYS, STATS_SINCE_CHARGED)); 16090 out.writeLong(computeRealtime(NOWREAL_SYS, STATS_SINCE_CHARGED)); 16091 out.writeLong(mStartClockTimeMs); 16092 out.writeString(mStartPlatformVersion); 16093 out.writeString(mEndPlatformVersion); 16094 mOnBatteryTimeBase.writeSummaryToParcel(out, NOW_SYS, NOWREAL_SYS); 16095 mOnBatteryScreenOffTimeBase.writeSummaryToParcel(out, NOW_SYS, NOWREAL_SYS); 16096 out.writeInt(mDischargeUnplugLevel); 16097 out.writeInt(mDischargePlugLevel); 16098 out.writeInt(mDischargeCurrentLevel); 16099 out.writeInt(mCurrentBatteryLevel); 16100 out.writeInt(mEstimatedBatteryCapacityMah); 16101 out.writeInt(mLastLearnedBatteryCapacityUah); 16102 out.writeInt(mMinLearnedBatteryCapacityUah); 16103 out.writeInt(mMaxLearnedBatteryCapacityUah); 16104 out.writeInt(getLowDischargeAmountSinceCharge()); 16105 out.writeInt(getHighDischargeAmountSinceCharge()); 16106 out.writeInt(getDischargeAmountScreenOnSinceCharge()); 16107 out.writeInt(getDischargeAmountScreenOffSinceCharge()); 16108 out.writeInt(getDischargeAmountScreenDozeSinceCharge()); 16109 mDischargeStepTracker.writeToParcel(out); 16110 mChargeStepTracker.writeToParcel(out); 16111 mDailyDischargeStepTracker.writeToParcel(out); 16112 mDailyChargeStepTracker.writeToParcel(out); 16113 mDischargeCounter.writeSummaryFromParcelLocked(out); 16114 mDischargeScreenOffCounter.writeSummaryFromParcelLocked(out); 16115 mDischargeScreenDozeCounter.writeSummaryFromParcelLocked(out); 16116 mDischargeLightDozeCounter.writeSummaryFromParcelLocked(out); 16117 mDischargeDeepDozeCounter.writeSummaryFromParcelLocked(out); 16118 if (mDailyPackageChanges != null) { 16119 final int NPKG = mDailyPackageChanges.size(); 16120 out.writeInt(NPKG); 16121 for (int i=0; i<NPKG; i++) { 16122 PackageChange pc = mDailyPackageChanges.get(i); 16123 out.writeString(pc.mPackageName); 16124 out.writeInt(pc.mUpdate ? 1 : 0); 16125 out.writeLong(pc.mVersionCode); 16126 } 16127 } else { 16128 out.writeInt(0); 16129 } 16130 out.writeLong(mDailyStartTimeMs); 16131 out.writeLong(mNextMinDailyDeadlineMs); 16132 out.writeLong(mNextMaxDailyDeadlineMs); 16133 out.writeLong(mBatteryTimeToFullSeconds); 16134 16135 MeasuredEnergyStats.writeSummaryToParcel(mGlobalMeasuredEnergyStats, out, false, false); 16136 16137 mScreenOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 16138 mScreenDozeTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 16139 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 16140 mScreenBrightnessTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS); 16141 } 16142 mInteractiveTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 16143 mPowerSaveModeEnabledTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 16144 out.writeLong(mLongestLightIdleTimeMs); 16145 out.writeLong(mLongestFullIdleTimeMs); 16146 mDeviceIdleModeLightTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 16147 mDeviceIdleModeFullTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 16148 mDeviceLightIdlingTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 16149 mDeviceIdlingTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 16150 mPhoneOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 16151 for (int i = 0; i < CellSignalStrength.getNumSignalStrengthLevels(); i++) { 16152 mPhoneSignalStrengthsTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS); 16153 } 16154 mPhoneSignalScanningTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 16155 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 16156 mPhoneDataConnectionsTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS); 16157 } 16158 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 16159 mNetworkByteActivityCounters[i].writeSummaryFromParcelLocked(out); 16160 mNetworkPacketActivityCounters[i].writeSummaryFromParcelLocked(out); 16161 } 16162 mMobileRadioActiveTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 16163 mMobileRadioActivePerAppTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 16164 mMobileRadioActiveAdjustedTime.writeSummaryFromParcelLocked(out); 16165 mMobileRadioActiveUnknownTime.writeSummaryFromParcelLocked(out); 16166 mMobileRadioActiveUnknownCount.writeSummaryFromParcelLocked(out); 16167 mWifiMulticastWakelockTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 16168 mWifiOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 16169 mGlobalWifiRunningTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 16170 for (int i=0; i<NUM_WIFI_STATES; i++) { 16171 mWifiStateTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS); 16172 } 16173 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) { 16174 mWifiSupplStateTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS); 16175 } 16176 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { 16177 mWifiSignalStrengthsTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS); 16178 } 16179 mWifiActiveTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 16180 mWifiActivity.writeSummaryToParcel(out); 16181 for (int i=0; i< mGpsSignalQualityTimer.length; i++) { 16182 mGpsSignalQualityTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS); 16183 } 16184 mBluetoothActivity.writeSummaryToParcel(out); 16185 mModemActivity.writeSummaryToParcel(out); 16186 out.writeInt(mHasWifiReporting ? 1 : 0); 16187 out.writeInt(mHasBluetoothReporting ? 1 : 0); 16188 out.writeInt(mHasModemReporting ? 1 : 0); 16189 16190 out.writeInt(mNumConnectivityChange); 16191 mFlashlightOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 16192 mCameraOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 16193 mBluetoothScanTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 16194 16195 out.writeInt(mRpmStats.size()); 16196 for (Map.Entry<String, SamplingTimer> ent : mRpmStats.entrySet()) { 16197 Timer rpmt = ent.getValue(); 16198 if (rpmt != null) { 16199 out.writeInt(1); 16200 out.writeString(ent.getKey()); 16201 rpmt.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 16202 } else { 16203 out.writeInt(0); 16204 } 16205 } 16206 out.writeInt(mScreenOffRpmStats.size()); 16207 for (Map.Entry<String, SamplingTimer> ent : mScreenOffRpmStats.entrySet()) { 16208 Timer rpmt = ent.getValue(); 16209 if (rpmt != null) { 16210 out.writeInt(1); 16211 out.writeString(ent.getKey()); 16212 rpmt.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 16213 } else { 16214 out.writeInt(0); 16215 } 16216 } 16217 16218 out.writeInt(mKernelWakelockStats.size()); 16219 for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) { 16220 Timer kwlt = ent.getValue(); 16221 if (kwlt != null) { 16222 out.writeInt(1); 16223 out.writeString(ent.getKey()); 16224 kwlt.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 16225 } else { 16226 out.writeInt(0); 16227 } 16228 } 16229 16230 out.writeInt(mWakeupReasonStats.size()); 16231 for (Map.Entry<String, SamplingTimer> ent : mWakeupReasonStats.entrySet()) { 16232 SamplingTimer timer = ent.getValue(); 16233 if (timer != null) { 16234 out.writeInt(1); 16235 out.writeString(ent.getKey()); 16236 timer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 16237 } else { 16238 out.writeInt(0); 16239 } 16240 } 16241 16242 out.writeInt(mKernelMemoryStats.size()); 16243 for (int i = 0; i < mKernelMemoryStats.size(); i++) { 16244 Timer kmt = mKernelMemoryStats.valueAt(i); 16245 if (kmt != null) { 16246 out.writeInt(1); 16247 out.writeLong(mKernelMemoryStats.keyAt(i)); 16248 kmt.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 16249 } else { 16250 out.writeInt(0); 16251 } 16252 } 16253 16254 final int NU = mUidStats.size(); 16255 out.writeInt(NU); 16256 for (int iu = 0; iu < NU; iu++) { 16257 out.writeInt(mUidStats.keyAt(iu)); 16258 Uid u = mUidStats.valueAt(iu); 16259 16260 u.mOnBatteryBackgroundTimeBase.writeSummaryToParcel(out, NOW_SYS, NOWREAL_SYS); 16261 u.mOnBatteryScreenOffBackgroundTimeBase.writeSummaryToParcel(out, NOW_SYS, NOWREAL_SYS); 16262 16263 if (u.mWifiRunningTimer != null) { 16264 out.writeInt(1); 16265 u.mWifiRunningTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 16266 } else { 16267 out.writeInt(0); 16268 } 16269 if (u.mFullWifiLockTimer != null) { 16270 out.writeInt(1); 16271 u.mFullWifiLockTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 16272 } else { 16273 out.writeInt(0); 16274 } 16275 if (u.mWifiScanTimer != null) { 16276 out.writeInt(1); 16277 u.mWifiScanTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 16278 } else { 16279 out.writeInt(0); 16280 } 16281 for (int i = 0; i < Uid.NUM_WIFI_BATCHED_SCAN_BINS; i++) { 16282 if (u.mWifiBatchedScanTimer[i] != null) { 16283 out.writeInt(1); 16284 u.mWifiBatchedScanTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS); 16285 } else { 16286 out.writeInt(0); 16287 } 16288 } 16289 if (u.mWifiMulticastTimer != null) { 16290 out.writeInt(1); 16291 u.mWifiMulticastTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 16292 } else { 16293 out.writeInt(0); 16294 } 16295 if (u.mAudioTurnedOnTimer != null) { 16296 out.writeInt(1); 16297 u.mAudioTurnedOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 16298 } else { 16299 out.writeInt(0); 16300 } 16301 if (u.mVideoTurnedOnTimer != null) { 16302 out.writeInt(1); 16303 u.mVideoTurnedOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 16304 } else { 16305 out.writeInt(0); 16306 } 16307 if (u.mFlashlightTurnedOnTimer != null) { 16308 out.writeInt(1); 16309 u.mFlashlightTurnedOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 16310 } else { 16311 out.writeInt(0); 16312 } 16313 if (u.mCameraTurnedOnTimer != null) { 16314 out.writeInt(1); 16315 u.mCameraTurnedOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 16316 } else { 16317 out.writeInt(0); 16318 } 16319 if (u.mForegroundActivityTimer != null) { 16320 out.writeInt(1); 16321 u.mForegroundActivityTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 16322 } else { 16323 out.writeInt(0); 16324 } 16325 if (u.mForegroundServiceTimer != null) { 16326 out.writeInt(1); 16327 u.mForegroundServiceTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 16328 } else { 16329 out.writeInt(0); 16330 } 16331 if (u.mAggregatedPartialWakelockTimer != null) { 16332 out.writeInt(1); 16333 u.mAggregatedPartialWakelockTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 16334 } else { 16335 out.writeInt(0); 16336 } 16337 if (u.mBluetoothScanTimer != null) { 16338 out.writeInt(1); 16339 u.mBluetoothScanTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 16340 } else { 16341 out.writeInt(0); 16342 } 16343 if (u.mBluetoothUnoptimizedScanTimer != null) { 16344 out.writeInt(1); 16345 u.mBluetoothUnoptimizedScanTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 16346 } else { 16347 out.writeInt(0); 16348 } 16349 if (u.mBluetoothScanResultCounter != null) { 16350 out.writeInt(1); 16351 u.mBluetoothScanResultCounter.writeSummaryFromParcelLocked(out); 16352 } else { 16353 out.writeInt(0); 16354 } 16355 if (u.mBluetoothScanResultBgCounter != null) { 16356 out.writeInt(1); 16357 u.mBluetoothScanResultBgCounter.writeSummaryFromParcelLocked(out); 16358 } else { 16359 out.writeInt(0); 16360 } 16361 for (int i = 0; i < Uid.NUM_PROCESS_STATE; i++) { 16362 if (u.mProcessStateTimer[i] != null) { 16363 out.writeInt(1); 16364 u.mProcessStateTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS); 16365 } else { 16366 out.writeInt(0); 16367 } 16368 } 16369 if (u.mVibratorOnTimer != null) { 16370 out.writeInt(1); 16371 u.mVibratorOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 16372 } else { 16373 out.writeInt(0); 16374 } 16375 16376 if (u.mUserActivityCounters == null) { 16377 out.writeInt(0); 16378 } else { 16379 out.writeInt(1); 16380 for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) { 16381 u.mUserActivityCounters[i].writeSummaryFromParcelLocked(out); 16382 } 16383 } 16384 16385 if (u.mNetworkByteActivityCounters == null) { 16386 out.writeInt(0); 16387 } else { 16388 out.writeInt(1); 16389 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 16390 u.mNetworkByteActivityCounters[i].writeSummaryFromParcelLocked(out); 16391 u.mNetworkPacketActivityCounters[i].writeSummaryFromParcelLocked(out); 16392 } 16393 u.mMobileRadioActiveTime.writeSummaryFromParcelLocked(out); 16394 u.mMobileRadioActiveCount.writeSummaryFromParcelLocked(out); 16395 } 16396 16397 u.mUserCpuTime.writeSummaryFromParcelLocked(out); 16398 u.mSystemCpuTime.writeSummaryFromParcelLocked(out); 16399 16400 if (u.mCpuClusterSpeedTimesUs != null) { 16401 out.writeInt(1); 16402 out.writeInt(u.mCpuClusterSpeedTimesUs.length); 16403 for (LongSamplingCounter[] cpuSpeeds : u.mCpuClusterSpeedTimesUs) { 16404 if (cpuSpeeds != null) { 16405 out.writeInt(1); 16406 out.writeInt(cpuSpeeds.length); 16407 for (LongSamplingCounter c : cpuSpeeds) { 16408 if (c != null) { 16409 out.writeInt(1); 16410 c.writeSummaryFromParcelLocked(out); 16411 } else { 16412 out.writeInt(0); 16413 } 16414 } 16415 } else { 16416 out.writeInt(0); 16417 } 16418 } 16419 } else { 16420 out.writeInt(0); 16421 } 16422 16423 LongSamplingCounterArray.writeSummaryToParcelLocked(out, u.mCpuFreqTimeMs); 16424 LongSamplingCounterArray.writeSummaryToParcelLocked(out, u.mScreenOffCpuFreqTimeMs); 16425 16426 u.mCpuActiveTimeMs.writeSummaryFromParcelLocked(out); 16427 u.mCpuClusterTimesMs.writeSummaryToParcelLocked(out); 16428 16429 if (u.mProcStateTimeMs != null) { 16430 out.writeInt(u.mProcStateTimeMs.length); 16431 for (LongSamplingCounterArray counters : u.mProcStateTimeMs) { 16432 LongSamplingCounterArray.writeSummaryToParcelLocked(out, counters); 16433 } 16434 } else { 16435 out.writeInt(0); 16436 } 16437 if (u.mProcStateScreenOffTimeMs != null) { 16438 out.writeInt(u.mProcStateScreenOffTimeMs.length); 16439 for (LongSamplingCounterArray counters : u.mProcStateScreenOffTimeMs) { 16440 LongSamplingCounterArray.writeSummaryToParcelLocked(out, counters); 16441 } 16442 } else { 16443 out.writeInt(0); 16444 } 16445 16446 if (u.mMobileRadioApWakeupCount != null) { 16447 out.writeInt(1); 16448 u.mMobileRadioApWakeupCount.writeSummaryFromParcelLocked(out); 16449 } else { 16450 out.writeInt(0); 16451 } 16452 16453 if (u.mWifiRadioApWakeupCount != null) { 16454 out.writeInt(1); 16455 u.mWifiRadioApWakeupCount.writeSummaryFromParcelLocked(out); 16456 } else { 16457 out.writeInt(0); 16458 } 16459 16460 MeasuredEnergyStats.writeSummaryToParcel(u.mUidMeasuredEnergyStats, out, true, true); 16461 16462 final ArrayMap<String, Uid.Wakelock> wakeStats = u.mWakelockStats.getMap(); 16463 int NW = wakeStats.size(); 16464 out.writeInt(NW); 16465 for (int iw=0; iw<NW; iw++) { 16466 out.writeString(wakeStats.keyAt(iw)); 16467 Uid.Wakelock wl = wakeStats.valueAt(iw); 16468 if (wl.mTimerFull != null) { 16469 out.writeInt(1); 16470 wl.mTimerFull.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 16471 } else { 16472 out.writeInt(0); 16473 } 16474 if (wl.mTimerPartial != null) { 16475 out.writeInt(1); 16476 wl.mTimerPartial.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 16477 } else { 16478 out.writeInt(0); 16479 } 16480 if (wl.mTimerWindow != null) { 16481 out.writeInt(1); 16482 wl.mTimerWindow.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 16483 } else { 16484 out.writeInt(0); 16485 } 16486 if (wl.mTimerDraw != null) { 16487 out.writeInt(1); 16488 wl.mTimerDraw.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 16489 } else { 16490 out.writeInt(0); 16491 } 16492 } 16493 16494 final ArrayMap<String, DualTimer> syncStats = u.mSyncStats.getMap(); 16495 int NS = syncStats.size(); 16496 out.writeInt(NS); 16497 for (int is=0; is<NS; is++) { 16498 out.writeString(syncStats.keyAt(is)); 16499 syncStats.valueAt(is).writeSummaryFromParcelLocked(out, NOWREAL_SYS); 16500 } 16501 16502 final ArrayMap<String, DualTimer> jobStats = u.mJobStats.getMap(); 16503 int NJ = jobStats.size(); 16504 out.writeInt(NJ); 16505 for (int ij=0; ij<NJ; ij++) { 16506 out.writeString(jobStats.keyAt(ij)); 16507 jobStats.valueAt(ij).writeSummaryFromParcelLocked(out, NOWREAL_SYS); 16508 } 16509 16510 u.writeJobCompletionsToParcelLocked(out); 16511 16512 u.mJobsDeferredEventCount.writeSummaryFromParcelLocked(out); 16513 u.mJobsDeferredCount.writeSummaryFromParcelLocked(out); 16514 u.mJobsFreshnessTimeMs.writeSummaryFromParcelLocked(out); 16515 for (int i = 0; i < JOB_FRESHNESS_BUCKETS.length; i++) { 16516 if (u.mJobsFreshnessBuckets[i] != null) { 16517 out.writeInt(1); 16518 u.mJobsFreshnessBuckets[i].writeSummaryFromParcelLocked(out); 16519 } else { 16520 out.writeInt(0); 16521 } 16522 } 16523 16524 int NSE = u.mSensorStats.size(); 16525 out.writeInt(NSE); 16526 for (int ise=0; ise<NSE; ise++) { 16527 out.writeInt(u.mSensorStats.keyAt(ise)); 16528 Uid.Sensor se = u.mSensorStats.valueAt(ise); 16529 if (se.mTimer != null) { 16530 out.writeInt(1); 16531 se.mTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 16532 } else { 16533 out.writeInt(0); 16534 } 16535 } 16536 16537 int NP = u.mProcessStats.size(); 16538 out.writeInt(NP); 16539 for (int ip=0; ip<NP; ip++) { 16540 out.writeString(u.mProcessStats.keyAt(ip)); 16541 Uid.Proc ps = u.mProcessStats.valueAt(ip); 16542 out.writeLong(ps.mUserTimeMs); 16543 out.writeLong(ps.mSystemTimeMs); 16544 out.writeLong(ps.mForegroundTimeMs); 16545 out.writeInt(ps.mStarts); 16546 out.writeInt(ps.mNumCrashes); 16547 out.writeInt(ps.mNumAnrs); 16548 ps.writeExcessivePowerToParcelLocked(out); 16549 } 16550 16551 NP = u.mPackageStats.size(); 16552 out.writeInt(NP); 16553 if (NP > 0) { 16554 for (Map.Entry<String, BatteryStatsImpl.Uid.Pkg> ent 16555 : u.mPackageStats.entrySet()) { 16556 out.writeString(ent.getKey()); 16557 Uid.Pkg ps = ent.getValue(); 16558 final int NWA = ps.mWakeupAlarms.size(); 16559 out.writeInt(NWA); 16560 for (int iwa=0; iwa<NWA; iwa++) { 16561 out.writeString(ps.mWakeupAlarms.keyAt(iwa)); 16562 ps.mWakeupAlarms.valueAt(iwa).writeSummaryFromParcelLocked(out); 16563 } 16564 NS = ps.mServiceStats.size(); 16565 out.writeInt(NS); 16566 for (int is=0; is<NS; is++) { 16567 out.writeString(ps.mServiceStats.keyAt(is)); 16568 BatteryStatsImpl.Uid.Pkg.Serv ss = ps.mServiceStats.valueAt(is); 16569 long time = ss.getStartTimeToNowLocked( 16570 mOnBatteryTimeBase.getUptime(NOW_SYS) / 1000); 16571 out.writeLong(time); 16572 out.writeInt(ss.mStarts); 16573 out.writeInt(ss.mLaunches); 16574 } 16575 } 16576 } 16577 } 16578 16579 LongSamplingCounterArray.writeSummaryToParcelLocked(out, mBinderThreadCpuTimesUs); 16580 } 16581 16582 public void readFromParcel(Parcel in) { 16583 readFromParcelLocked(in); 16584 } 16585 16586 void readFromParcelLocked(Parcel in) { 16587 int magic = in.readInt(); 16588 if (magic != MAGIC) { 16589 throw new ParcelFormatException("Bad magic number: #" + Integer.toHexString(magic)); 16590 } 16591 16592 readHistoryBuffer(in); 16593 mBatteryStatsHistory.readFromParcel(in); 16594 16595 mStartCount = in.readInt(); 16596 mStartClockTimeMs = in.readLong(); 16597 mStartPlatformVersion = in.readString(); 16598 mEndPlatformVersion = in.readString(); 16599 mUptimeUs = in.readLong(); 16600 mUptimeStartUs = in.readLong(); 16601 mRealtimeUs = in.readLong(); 16602 mRealtimeStartUs = in.readLong(); 16603 mOnBattery = in.readInt() != 0; 16604 mEstimatedBatteryCapacityMah = in.readInt(); 16605 mLastLearnedBatteryCapacityUah = in.readInt(); 16606 mMinLearnedBatteryCapacityUah = in.readInt(); 16607 mMaxLearnedBatteryCapacityUah = in.readInt(); 16608 mOnBatteryInternal = false; // we are no longer really running. 16609 mOnBatteryTimeBase.readFromParcel(in); 16610 mOnBatteryScreenOffTimeBase.readFromParcel(in); 16611 16612 mScreenState = Display.STATE_UNKNOWN; 16613 mScreenOnTimer = new StopwatchTimer(mClocks, null, -1, null, mOnBatteryTimeBase, in); 16614 mScreenDozeTimer = new StopwatchTimer(mClocks, null, -1, null, mOnBatteryTimeBase, in); 16615 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 16616 mScreenBrightnessTimer[i] = new StopwatchTimer(mClocks, null, -100-i, null, 16617 mOnBatteryTimeBase, in); 16618 } 16619 mInteractive = false; 16620 mInteractiveTimer = new StopwatchTimer(mClocks, null, -10, null, mOnBatteryTimeBase, in); 16621 mPhoneOn = false; 16622 mPowerSaveModeEnabledTimer = new StopwatchTimer(mClocks, null, -2, null, 16623 mOnBatteryTimeBase, in); 16624 mLongestLightIdleTimeMs = in.readLong(); 16625 mLongestFullIdleTimeMs = in.readLong(); 16626 mDeviceIdleModeLightTimer = new StopwatchTimer(mClocks, null, -14, null, 16627 mOnBatteryTimeBase, in); 16628 mDeviceIdleModeFullTimer = new StopwatchTimer(mClocks, null, -11, null, 16629 mOnBatteryTimeBase, in); 16630 mDeviceLightIdlingTimer = new StopwatchTimer(mClocks, null, -15, null, 16631 mOnBatteryTimeBase, in); 16632 mDeviceIdlingTimer = new StopwatchTimer(mClocks, null, -12, null, mOnBatteryTimeBase, in); 16633 mPhoneOnTimer = new StopwatchTimer(mClocks, null, -3, null, mOnBatteryTimeBase, in); 16634 for (int i = 0; i < CellSignalStrength.getNumSignalStrengthLevels(); i++) { 16635 mPhoneSignalStrengthsTimer[i] = new StopwatchTimer(mClocks, null, -200-i, 16636 null, mOnBatteryTimeBase, in); 16637 } 16638 mPhoneSignalScanningTimer = new StopwatchTimer(mClocks, null, -200+1, null, 16639 mOnBatteryTimeBase, in); 16640 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 16641 mPhoneDataConnectionsTimer[i] = new StopwatchTimer(mClocks, null, -300-i, 16642 null, mOnBatteryTimeBase, in); 16643 } 16644 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 16645 mNetworkByteActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase, in); 16646 mNetworkPacketActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase, in); 16647 } 16648 mMobileRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW; 16649 mMobileRadioActiveTimer = new StopwatchTimer(mClocks, null, -400, null, 16650 mOnBatteryTimeBase, in); 16651 mMobileRadioActivePerAppTimer = new StopwatchTimer(mClocks, null, -401, null, 16652 mOnBatteryTimeBase, in); 16653 mMobileRadioActiveAdjustedTime = new LongSamplingCounter(mOnBatteryTimeBase, in); 16654 mMobileRadioActiveUnknownTime = new LongSamplingCounter(mOnBatteryTimeBase, in); 16655 mMobileRadioActiveUnknownCount = new LongSamplingCounter(mOnBatteryTimeBase, in); 16656 mWifiMulticastWakelockTimer = new StopwatchTimer(mClocks, null, -4, null, 16657 mOnBatteryTimeBase, in); 16658 mWifiRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW; 16659 mWifiOn = false; 16660 mWifiOnTimer = new StopwatchTimer(mClocks, null, -4, null, mOnBatteryTimeBase, in); 16661 mGlobalWifiRunning = false; 16662 mGlobalWifiRunningTimer = new StopwatchTimer(mClocks, null, -5, null, 16663 mOnBatteryTimeBase, in); 16664 for (int i=0; i<NUM_WIFI_STATES; i++) { 16665 mWifiStateTimer[i] = new StopwatchTimer(mClocks, null, -600-i, 16666 null, mOnBatteryTimeBase, in); 16667 } 16668 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) { 16669 mWifiSupplStateTimer[i] = new StopwatchTimer(mClocks, null, -700-i, 16670 null, mOnBatteryTimeBase, in); 16671 } 16672 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { 16673 mWifiSignalStrengthsTimer[i] = new StopwatchTimer(mClocks, null, -800-i, 16674 null, mOnBatteryTimeBase, in); 16675 } 16676 mWifiActiveTimer = new StopwatchTimer(mClocks, null, -900, null, 16677 mOnBatteryTimeBase, in); 16678 mWifiActivity = new ControllerActivityCounterImpl(mOnBatteryTimeBase, 16679 NUM_WIFI_TX_LEVELS, in); 16680 for (int i=0; i<mGpsSignalQualityTimer.length; i++) { 16681 mGpsSignalQualityTimer[i] = new StopwatchTimer(mClocks, null, -1000-i, 16682 null, mOnBatteryTimeBase, in); 16683 } 16684 mBluetoothActivity = new ControllerActivityCounterImpl(mOnBatteryTimeBase, 16685 NUM_BT_TX_LEVELS, in); 16686 mModemActivity = new ControllerActivityCounterImpl(mOnBatteryTimeBase, 16687 ModemActivityInfo.getNumTxPowerLevels(), in); 16688 mHasWifiReporting = in.readInt() != 0; 16689 mHasBluetoothReporting = in.readInt() != 0; 16690 mHasModemReporting = in.readInt() != 0; 16691 16692 mNumConnectivityChange = in.readInt(); 16693 mAudioOnNesting = 0; 16694 // TODO: It's likely a mistake that mAudioOnTimer/mVideoOnTimer don't write/read to parcel! 16695 mAudioOnTimer = new StopwatchTimer(mClocks, null, -7, null, mOnBatteryTimeBase); 16696 mVideoOnNesting = 0; 16697 mVideoOnTimer = new StopwatchTimer(mClocks, null, -8, null, mOnBatteryTimeBase); 16698 mFlashlightOnNesting = 0; 16699 mFlashlightOnTimer = new StopwatchTimer(mClocks, null, -9, null, mOnBatteryTimeBase, in); 16700 mCameraOnNesting = 0; 16701 mCameraOnTimer = new StopwatchTimer(mClocks, null, -13, null, mOnBatteryTimeBase, in); 16702 mBluetoothScanNesting = 0; 16703 mBluetoothScanTimer = new StopwatchTimer(mClocks, null, -14, null, mOnBatteryTimeBase, in); 16704 mDischargeUnplugLevel = in.readInt(); 16705 mDischargePlugLevel = in.readInt(); 16706 mDischargeCurrentLevel = in.readInt(); 16707 mCurrentBatteryLevel = in.readInt(); 16708 mLowDischargeAmountSinceCharge = in.readInt(); 16709 mHighDischargeAmountSinceCharge = in.readInt(); 16710 mDischargeAmountScreenOn = in.readInt(); 16711 mDischargeAmountScreenOnSinceCharge = in.readInt(); 16712 mDischargeAmountScreenOff = in.readInt(); 16713 mDischargeAmountScreenOffSinceCharge = in.readInt(); 16714 mDischargeAmountScreenDoze = in.readInt(); 16715 mDischargeAmountScreenDozeSinceCharge = in.readInt(); 16716 mDischargeStepTracker.readFromParcel(in); 16717 mChargeStepTracker.readFromParcel(in); 16718 mDischargeCounter = new LongSamplingCounter(mOnBatteryTimeBase, in); 16719 mDischargeScreenOffCounter = new LongSamplingCounter(mOnBatteryScreenOffTimeBase, in); 16720 mDischargeScreenDozeCounter = new LongSamplingCounter(mOnBatteryTimeBase, in); 16721 mDischargeLightDozeCounter = new LongSamplingCounter(mOnBatteryTimeBase, in); 16722 mDischargeDeepDozeCounter = new LongSamplingCounter(mOnBatteryTimeBase, in); 16723 mLastWriteTimeMs = in.readLong(); 16724 mBatteryTimeToFullSeconds = in.readLong(); 16725 16726 if (in.readInt() != 0) { 16727 mGlobalMeasuredEnergyStats = new MeasuredEnergyStats(in); 16728 } 16729 16730 mRpmStats.clear(); 16731 int NRPMS = in.readInt(); 16732 for (int irpm = 0; irpm < NRPMS; irpm++) { 16733 if (in.readInt() != 0) { 16734 String rpmName = in.readString(); 16735 SamplingTimer rpmt = new SamplingTimer(mClocks, mOnBatteryTimeBase, in); 16736 mRpmStats.put(rpmName, rpmt); 16737 } 16738 } 16739 mScreenOffRpmStats.clear(); 16740 int NSORPMS = in.readInt(); 16741 for (int irpm = 0; irpm < NSORPMS; irpm++) { 16742 if (in.readInt() != 0) { 16743 String rpmName = in.readString(); 16744 SamplingTimer rpmt = new SamplingTimer(mClocks, mOnBatteryScreenOffTimeBase, in); 16745 mScreenOffRpmStats.put(rpmName, rpmt); 16746 } 16747 } 16748 16749 mKernelWakelockStats.clear(); 16750 int NKW = in.readInt(); 16751 for (int ikw = 0; ikw < NKW; ikw++) { 16752 if (in.readInt() != 0) { 16753 String wakelockName = in.readString(); 16754 SamplingTimer kwlt = new SamplingTimer(mClocks, mOnBatteryScreenOffTimeBase, in); 16755 mKernelWakelockStats.put(wakelockName, kwlt); 16756 } 16757 } 16758 16759 mWakeupReasonStats.clear(); 16760 int NWR = in.readInt(); 16761 for (int iwr = 0; iwr < NWR; iwr++) { 16762 if (in.readInt() != 0) { 16763 String reasonName = in.readString(); 16764 SamplingTimer timer = new SamplingTimer(mClocks, mOnBatteryTimeBase, in); 16765 mWakeupReasonStats.put(reasonName, timer); 16766 } 16767 } 16768 16769 mKernelMemoryStats.clear(); 16770 int nmt = in.readInt(); 16771 for (int imt = 0; imt < nmt; imt++) { 16772 if (in.readInt() != 0) { 16773 Long bucket = in.readLong(); 16774 SamplingTimer kmt = new SamplingTimer(mClocks, mOnBatteryTimeBase, in); 16775 mKernelMemoryStats.put(bucket, kmt); 16776 } 16777 } 16778 16779 mPartialTimers.clear(); 16780 mFullTimers.clear(); 16781 mWindowTimers.clear(); 16782 mWifiRunningTimers.clear(); 16783 mFullWifiLockTimers.clear(); 16784 mWifiScanTimers.clear(); 16785 mWifiBatchedScanTimers.clear(); 16786 mWifiMulticastTimers.clear(); 16787 mAudioTurnedOnTimers.clear(); 16788 mVideoTurnedOnTimers.clear(); 16789 mFlashlightTurnedOnTimers.clear(); 16790 mCameraTurnedOnTimers.clear(); 16791 16792 int numUids = in.readInt(); 16793 mUidStats.clear(); 16794 final long elapsedRealtimeMs = mClocks.elapsedRealtime(); 16795 final long uptimeMs = mClocks.uptimeMillis(); 16796 for (int i = 0; i < numUids; i++) { 16797 int uid = in.readInt(); 16798 Uid u = new Uid(this, uid, elapsedRealtimeMs, uptimeMs); 16799 u.readFromParcelLocked(mOnBatteryTimeBase, mOnBatteryScreenOffTimeBase, in); 16800 mUidStats.append(uid, u); 16801 } 16802 16803 mBinderThreadCpuTimesUs = LongSamplingCounterArray.readFromParcel(in, mOnBatteryTimeBase); 16804 } 16805 16806 public void writeToParcel(Parcel out, int flags) { 16807 writeToParcelLocked(out, true, flags); 16808 } 16809 16810 public void writeToParcelWithoutUids(Parcel out, int flags) { 16811 writeToParcelLocked(out, false, flags); 16812 } 16813 16814 @SuppressWarnings("unused") 16815 void writeToParcelLocked(Parcel out, boolean inclUids, int flags) { 16816 // Need to update with current kernel wake lock counts. 16817 pullPendingStateUpdatesLocked(); 16818 16819 updateSystemServiceCallStats(); 16820 16821 // Pull the clock time. This may update the time and make a new history entry 16822 // if we had originally pulled a time before the RTC was set. 16823 getStartClockTime(); 16824 16825 final long uSecUptime = mClocks.uptimeMillis() * 1000; 16826 final long uSecRealtime = mClocks.elapsedRealtime() * 1000; 16827 final long batteryRealtime = mOnBatteryTimeBase.getRealtime(uSecRealtime); 16828 final long batteryScreenOffRealtime = mOnBatteryScreenOffTimeBase.getRealtime(uSecRealtime); 16829 16830 out.writeInt(MAGIC); 16831 16832 writeHistoryBuffer(out, true); 16833 mBatteryStatsHistory.writeToParcel(out); 16834 16835 out.writeInt(mStartCount); 16836 out.writeLong(mStartClockTimeMs); 16837 out.writeString(mStartPlatformVersion); 16838 out.writeString(mEndPlatformVersion); 16839 out.writeLong(mUptimeUs); 16840 out.writeLong(mUptimeStartUs); 16841 out.writeLong(mRealtimeUs); 16842 out.writeLong(mRealtimeStartUs); 16843 out.writeInt(mOnBattery ? 1 : 0); 16844 out.writeInt(mEstimatedBatteryCapacityMah); 16845 out.writeInt(mLastLearnedBatteryCapacityUah); 16846 out.writeInt(mMinLearnedBatteryCapacityUah); 16847 out.writeInt(mMaxLearnedBatteryCapacityUah); 16848 mOnBatteryTimeBase.writeToParcel(out, uSecUptime, uSecRealtime); 16849 mOnBatteryScreenOffTimeBase.writeToParcel(out, uSecUptime, uSecRealtime); 16850 16851 mScreenOnTimer.writeToParcel(out, uSecRealtime); 16852 mScreenDozeTimer.writeToParcel(out, uSecRealtime); 16853 for (int i = 0; i < NUM_SCREEN_BRIGHTNESS_BINS; i++) { 16854 mScreenBrightnessTimer[i].writeToParcel(out, uSecRealtime); 16855 } 16856 mInteractiveTimer.writeToParcel(out, uSecRealtime); 16857 mPowerSaveModeEnabledTimer.writeToParcel(out, uSecRealtime); 16858 out.writeLong(mLongestLightIdleTimeMs); 16859 out.writeLong(mLongestFullIdleTimeMs); 16860 mDeviceIdleModeLightTimer.writeToParcel(out, uSecRealtime); 16861 mDeviceIdleModeFullTimer.writeToParcel(out, uSecRealtime); 16862 mDeviceLightIdlingTimer.writeToParcel(out, uSecRealtime); 16863 mDeviceIdlingTimer.writeToParcel(out, uSecRealtime); 16864 mPhoneOnTimer.writeToParcel(out, uSecRealtime); 16865 for (int i = 0; i < CellSignalStrength.getNumSignalStrengthLevels(); i++) { 16866 mPhoneSignalStrengthsTimer[i].writeToParcel(out, uSecRealtime); 16867 } 16868 mPhoneSignalScanningTimer.writeToParcel(out, uSecRealtime); 16869 for (int i = 0; i < NUM_DATA_CONNECTION_TYPES; i++) { 16870 mPhoneDataConnectionsTimer[i].writeToParcel(out, uSecRealtime); 16871 } 16872 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 16873 mNetworkByteActivityCounters[i].writeToParcel(out); 16874 mNetworkPacketActivityCounters[i].writeToParcel(out); 16875 } 16876 mMobileRadioActiveTimer.writeToParcel(out, uSecRealtime); 16877 mMobileRadioActivePerAppTimer.writeToParcel(out, uSecRealtime); 16878 mMobileRadioActiveAdjustedTime.writeToParcel(out); 16879 mMobileRadioActiveUnknownTime.writeToParcel(out); 16880 mMobileRadioActiveUnknownCount.writeToParcel(out); 16881 mWifiMulticastWakelockTimer.writeToParcel(out, uSecRealtime); 16882 mWifiOnTimer.writeToParcel(out, uSecRealtime); 16883 mGlobalWifiRunningTimer.writeToParcel(out, uSecRealtime); 16884 for (int i = 0; i < NUM_WIFI_STATES; i++) { 16885 mWifiStateTimer[i].writeToParcel(out, uSecRealtime); 16886 } 16887 for (int i = 0; i < NUM_WIFI_SUPPL_STATES; i++) { 16888 mWifiSupplStateTimer[i].writeToParcel(out, uSecRealtime); 16889 } 16890 for (int i = 0; i < NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { 16891 mWifiSignalStrengthsTimer[i].writeToParcel(out, uSecRealtime); 16892 } 16893 mWifiActiveTimer.writeToParcel(out, uSecRealtime); 16894 mWifiActivity.writeToParcel(out, 0); 16895 for (int i = 0; i < mGpsSignalQualityTimer.length; i++) { 16896 mGpsSignalQualityTimer[i].writeToParcel(out, uSecRealtime); 16897 } 16898 mBluetoothActivity.writeToParcel(out, 0); 16899 mModemActivity.writeToParcel(out, 0); 16900 out.writeInt(mHasWifiReporting ? 1 : 0); 16901 out.writeInt(mHasBluetoothReporting ? 1 : 0); 16902 out.writeInt(mHasModemReporting ? 1 : 0); 16903 16904 out.writeInt(mNumConnectivityChange); 16905 mFlashlightOnTimer.writeToParcel(out, uSecRealtime); 16906 mCameraOnTimer.writeToParcel(out, uSecRealtime); 16907 mBluetoothScanTimer.writeToParcel(out, uSecRealtime); 16908 out.writeInt(mDischargeUnplugLevel); 16909 out.writeInt(mDischargePlugLevel); 16910 out.writeInt(mDischargeCurrentLevel); 16911 out.writeInt(mCurrentBatteryLevel); 16912 out.writeInt(mLowDischargeAmountSinceCharge); 16913 out.writeInt(mHighDischargeAmountSinceCharge); 16914 out.writeInt(mDischargeAmountScreenOn); 16915 out.writeInt(mDischargeAmountScreenOnSinceCharge); 16916 out.writeInt(mDischargeAmountScreenOff); 16917 out.writeInt(mDischargeAmountScreenOffSinceCharge); 16918 out.writeInt(mDischargeAmountScreenDoze); 16919 out.writeInt(mDischargeAmountScreenDozeSinceCharge); 16920 mDischargeStepTracker.writeToParcel(out); 16921 mChargeStepTracker.writeToParcel(out); 16922 mDischargeCounter.writeToParcel(out); 16923 mDischargeScreenOffCounter.writeToParcel(out); 16924 mDischargeScreenDozeCounter.writeToParcel(out); 16925 mDischargeLightDozeCounter.writeToParcel(out); 16926 mDischargeDeepDozeCounter.writeToParcel(out); 16927 out.writeLong(mLastWriteTimeMs); 16928 out.writeLong(mBatteryTimeToFullSeconds); 16929 16930 if (mGlobalMeasuredEnergyStats != null) { 16931 out.writeInt(1); 16932 mGlobalMeasuredEnergyStats.writeToParcel(out); 16933 } else { 16934 out.writeInt(0); 16935 } 16936 16937 out.writeInt(mRpmStats.size()); 16938 for (Map.Entry<String, SamplingTimer> ent : mRpmStats.entrySet()) { 16939 SamplingTimer rpmt = ent.getValue(); 16940 if (rpmt != null) { 16941 out.writeInt(1); 16942 out.writeString(ent.getKey()); 16943 rpmt.writeToParcel(out, uSecRealtime); 16944 } else { 16945 out.writeInt(0); 16946 } 16947 } 16948 out.writeInt(mScreenOffRpmStats.size()); 16949 for (Map.Entry<String, SamplingTimer> ent : mScreenOffRpmStats.entrySet()) { 16950 SamplingTimer rpmt = ent.getValue(); 16951 if (rpmt != null) { 16952 out.writeInt(1); 16953 out.writeString(ent.getKey()); 16954 rpmt.writeToParcel(out, uSecRealtime); 16955 } else { 16956 out.writeInt(0); 16957 } 16958 } 16959 16960 if (inclUids) { 16961 out.writeInt(mKernelWakelockStats.size()); 16962 for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) { 16963 SamplingTimer kwlt = ent.getValue(); 16964 if (kwlt != null) { 16965 out.writeInt(1); 16966 out.writeString(ent.getKey()); 16967 kwlt.writeToParcel(out, uSecRealtime); 16968 } else { 16969 out.writeInt(0); 16970 } 16971 } 16972 out.writeInt(mWakeupReasonStats.size()); 16973 for (Map.Entry<String, SamplingTimer> ent : mWakeupReasonStats.entrySet()) { 16974 SamplingTimer timer = ent.getValue(); 16975 if (timer != null) { 16976 out.writeInt(1); 16977 out.writeString(ent.getKey()); 16978 timer.writeToParcel(out, uSecRealtime); 16979 } else { 16980 out.writeInt(0); 16981 } 16982 } 16983 } else { 16984 out.writeInt(0); 16985 out.writeInt(0); 16986 } 16987 16988 out.writeInt(mKernelMemoryStats.size()); 16989 for (int i = 0; i < mKernelMemoryStats.size(); i++) { 16990 SamplingTimer kmt = mKernelMemoryStats.valueAt(i); 16991 if (kmt != null) { 16992 out.writeInt(1); 16993 out.writeLong(mKernelMemoryStats.keyAt(i)); 16994 kmt.writeToParcel(out, uSecRealtime); 16995 } else { 16996 out.writeInt(0); 16997 } 16998 } 16999 17000 if (inclUids) { 17001 int size = mUidStats.size(); 17002 out.writeInt(size); 17003 for (int i = 0; i < size; i++) { 17004 out.writeInt(mUidStats.keyAt(i)); 17005 Uid uid = mUidStats.valueAt(i); 17006 17007 uid.writeToParcelLocked(out, uSecUptime, uSecRealtime); 17008 } 17009 } else { 17010 out.writeInt(0); 17011 } 17012 LongSamplingCounterArray.writeToParcel(out, mBinderThreadCpuTimesUs); 17013 } 17014 17015 private void writeCpuSpeedCountersToParcel(Parcel out, LongSamplingCounter[][] counters) { 17016 if (counters == null) { 17017 out.writeInt(0); 17018 return; 17019 } 17020 17021 out.writeInt(1); 17022 out.writeInt(counters.length); 17023 for (int i = 0; i < counters.length; i++) { 17024 LongSamplingCounter[] counterArray = counters[i]; 17025 if (counterArray == null) { 17026 out.writeInt(0); 17027 continue; 17028 } 17029 17030 out.writeInt(1); 17031 out.writeInt(counterArray.length); 17032 for (int j = 0; j < counterArray.length; j++) { 17033 LongSamplingCounter c = counterArray[j]; 17034 if (c != null) { 17035 out.writeInt(1); 17036 c.writeToParcel(out); 17037 } else { 17038 out.writeInt(0); 17039 } 17040 } 17041 } 17042 } 17043 17044 private LongSamplingCounter[][] readCpuSpeedCountersFromParcel(Parcel in) { 17045 LongSamplingCounter[][] counters; 17046 if (in.readInt() != 0) { 17047 int numCpuClusters = in.readInt(); 17048 if (mPowerProfile != null 17049 && mPowerProfile.getNumCpuClusters() != numCpuClusters) { 17050 throw new ParcelFormatException("Incompatible number of cpu clusters"); 17051 } 17052 17053 counters = new LongSamplingCounter[numCpuClusters][]; 17054 for (int cluster = 0; cluster < numCpuClusters; cluster++) { 17055 if (in.readInt() != 0) { 17056 int numSpeeds = in.readInt(); 17057 if (mPowerProfile != null 17058 && mPowerProfile.getNumSpeedStepsInCpuCluster(cluster) != numSpeeds) { 17059 throw new ParcelFormatException("Incompatible number of cpu speeds"); 17060 } 17061 17062 final LongSamplingCounter[] cpuSpeeds = new LongSamplingCounter[numSpeeds]; 17063 counters[cluster] = cpuSpeeds; 17064 for (int speed = 0; speed < numSpeeds; speed++) { 17065 if (in.readInt() != 0) { 17066 cpuSpeeds[speed] = new LongSamplingCounter(mOnBatteryTimeBase, in); 17067 } 17068 } 17069 } else { 17070 counters[cluster] = null; 17071 } 17072 } 17073 } else { 17074 counters = null; 17075 } 17076 17077 return counters; 17078 } 17079 17080 @UnsupportedAppUsage 17081 public static final Parcelable.Creator<BatteryStatsImpl> CREATOR = 17082 new Parcelable.Creator<BatteryStatsImpl>() { 17083 public BatteryStatsImpl createFromParcel(Parcel in) { 17084 return new BatteryStatsImpl(in); 17085 } 17086 17087 public BatteryStatsImpl[] newArray(int size) { 17088 return new BatteryStatsImpl[size]; 17089 } 17090 }; 17091 17092 public void prepareForDumpLocked() { 17093 // Need to retrieve current kernel wake lock stats before printing. 17094 pullPendingStateUpdatesLocked(); 17095 17096 // Pull the clock time. This may update the time and make a new history entry 17097 // if we had originally pulled a time before the RTC was set. 17098 getStartClockTime(); 17099 17100 updateSystemServiceCallStats(); 17101 } 17102 17103 public void dumpLocked(Context context, PrintWriter pw, int flags, int reqUid, long histStart) { 17104 if (DEBUG) { 17105 pw.println("mOnBatteryTimeBase:"); 17106 mOnBatteryTimeBase.dump(pw, " "); 17107 pw.println("mOnBatteryScreenOffTimeBase:"); 17108 mOnBatteryScreenOffTimeBase.dump(pw, " "); 17109 Printer pr = new PrintWriterPrinter(pw); 17110 pr.println("*** Screen on timer:"); 17111 mScreenOnTimer.logState(pr, " "); 17112 pr.println("*** Screen doze timer:"); 17113 mScreenDozeTimer.logState(pr, " "); 17114 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 17115 pr.println("*** Screen brightness #" + i + ":"); 17116 mScreenBrightnessTimer[i].logState(pr, " "); 17117 } 17118 pr.println("*** Interactive timer:"); 17119 mInteractiveTimer.logState(pr, " "); 17120 pr.println("*** Power save mode timer:"); 17121 mPowerSaveModeEnabledTimer.logState(pr, " "); 17122 pr.println("*** Device idle mode light timer:"); 17123 mDeviceIdleModeLightTimer.logState(pr, " "); 17124 pr.println("*** Device idle mode full timer:"); 17125 mDeviceIdleModeFullTimer.logState(pr, " "); 17126 pr.println("*** Device light idling timer:"); 17127 mDeviceLightIdlingTimer.logState(pr, " "); 17128 pr.println("*** Device idling timer:"); 17129 mDeviceIdlingTimer.logState(pr, " "); 17130 pr.println("*** Phone timer:"); 17131 mPhoneOnTimer.logState(pr, " "); 17132 for (int i = 0; i < CellSignalStrength.getNumSignalStrengthLevels(); i++) { 17133 pr.println("*** Phone signal strength #" + i + ":"); 17134 mPhoneSignalStrengthsTimer[i].logState(pr, " "); 17135 } 17136 pr.println("*** Signal scanning :"); 17137 mPhoneSignalScanningTimer.logState(pr, " "); 17138 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 17139 pr.println("*** Data connection type #" + i + ":"); 17140 mPhoneDataConnectionsTimer[i].logState(pr, " "); 17141 } 17142 pr.println("*** mMobileRadioPowerState=" + mMobileRadioPowerState); 17143 pr.println("*** Mobile network active timer:"); 17144 mMobileRadioActiveTimer.logState(pr, " "); 17145 pr.println("*** Mobile network active adjusted timer:"); 17146 mMobileRadioActiveAdjustedTime.logState(pr, " "); 17147 pr.println("*** Wifi Multicast WakeLock Timer:"); 17148 mWifiMulticastWakelockTimer.logState(pr, " "); 17149 pr.println("*** mWifiRadioPowerState=" + mWifiRadioPowerState); 17150 pr.println("*** Wifi timer:"); 17151 mWifiOnTimer.logState(pr, " "); 17152 pr.println("*** WifiRunning timer:"); 17153 mGlobalWifiRunningTimer.logState(pr, " "); 17154 for (int i=0; i<NUM_WIFI_STATES; i++) { 17155 pr.println("*** Wifi state #" + i + ":"); 17156 mWifiStateTimer[i].logState(pr, " "); 17157 } 17158 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) { 17159 pr.println("*** Wifi suppl state #" + i + ":"); 17160 mWifiSupplStateTimer[i].logState(pr, " "); 17161 } 17162 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { 17163 pr.println("*** Wifi signal strength #" + i + ":"); 17164 mWifiSignalStrengthsTimer[i].logState(pr, " "); 17165 } 17166 for (int i=0; i<mGpsSignalQualityTimer.length; i++) { 17167 pr.println("*** GPS signal quality #" + i + ":"); 17168 mGpsSignalQualityTimer[i].logState(pr, " "); 17169 } 17170 pr.println("*** Flashlight timer:"); 17171 mFlashlightOnTimer.logState(pr, " "); 17172 pr.println("*** Camera timer:"); 17173 mCameraOnTimer.logState(pr, " "); 17174 } 17175 super.dumpLocked(context, pw, flags, reqUid, histStart); 17176 17177 pw.print("Total cpu time reads: "); 17178 pw.println(mNumSingleUidCpuTimeReads); 17179 pw.print("Batched cpu time reads: "); 17180 pw.println(mNumBatchedSingleUidCpuTimeReads); 17181 pw.print("Batching Duration (min): "); 17182 pw.println((mClocks.uptimeMillis() - mCpuTimeReadsTrackingStartTimeMs) / (60 * 1000)); 17183 pw.print("All UID cpu time reads since the later of device start or stats reset: "); 17184 pw.println(mNumAllUidCpuTimeReads); 17185 pw.print("UIDs removed since the later of device start or stats reset: "); 17186 pw.println(mNumUidsRemoved); 17187 17188 pw.println("Currently mapped isolated uids:"); 17189 final int numIsolatedUids = mIsolatedUids.size(); 17190 for (int i = 0; i < numIsolatedUids; i++) { 17191 final int isolatedUid = mIsolatedUids.keyAt(i); 17192 final int ownerUid = mIsolatedUids.valueAt(i); 17193 final int refCount = mIsolatedUidRefCounts.get(isolatedUid); 17194 pw.println(" " + isolatedUid + "->" + ownerUid + " (ref count = " + refCount + ")"); 17195 } 17196 17197 pw.println(); 17198 dumpConstantsLocked(pw); 17199 17200 pw.println(); 17201 dumpMeasuredEnergyStatsLocked(pw); 17202 } 17203 } 17204