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.os.BatteryStatsManager.NUM_WIFI_STATES; 20 import static android.os.BatteryStatsManager.NUM_WIFI_SUPPL_STATES; 21 22 import android.annotation.NonNull; 23 import android.annotation.Nullable; 24 import android.app.ActivityManager; 25 import android.bluetooth.BluetoothActivityEnergyInfo; 26 import android.bluetooth.UidTraffic; 27 import android.compat.annotation.UnsupportedAppUsage; 28 import android.content.BroadcastReceiver; 29 import android.content.ContentResolver; 30 import android.content.Context; 31 import android.content.Intent; 32 import android.content.IntentFilter; 33 import android.database.ContentObserver; 34 import android.hardware.usb.UsbManager; 35 import android.net.ConnectivityManager; 36 import android.net.INetworkStatsService; 37 import android.net.NetworkStats; 38 import android.net.Uri; 39 import android.net.wifi.WifiManager; 40 import android.os.BatteryManager; 41 import android.os.BatteryStats; 42 import android.os.Build; 43 import android.os.Handler; 44 import android.os.IBatteryPropertiesRegistrar; 45 import android.os.Looper; 46 import android.os.Message; 47 import android.os.OsProtoEnums; 48 import android.os.Parcel; 49 import android.os.ParcelFormatException; 50 import android.os.Parcelable; 51 import android.os.PowerManager; 52 import android.os.Process; 53 import android.os.RemoteException; 54 import android.os.ServiceManager; 55 import android.os.SystemClock; 56 import android.os.UserHandle; 57 import android.os.WorkSource; 58 import android.os.WorkSource.WorkChain; 59 import android.os.connectivity.CellularBatteryStats; 60 import android.os.connectivity.GpsBatteryStats; 61 import android.os.connectivity.WifiActivityEnergyInfo; 62 import android.os.connectivity.WifiBatteryStats; 63 import android.provider.Settings; 64 import android.telephony.CellSignalStrength; 65 import android.telephony.DataConnectionRealTimeInfo; 66 import android.telephony.ModemActivityInfo; 67 import android.telephony.ModemActivityInfo.TransmitPower; 68 import android.telephony.ServiceState; 69 import android.telephony.SignalStrength; 70 import android.telephony.TelephonyManager; 71 import android.text.TextUtils; 72 import android.util.ArrayMap; 73 import android.util.AtomicFile; 74 import android.util.IntArray; 75 import android.util.KeyValueListParser; 76 import android.util.Log; 77 import android.util.LogWriter; 78 import android.util.LongSparseArray; 79 import android.util.LongSparseLongArray; 80 import android.util.MutableInt; 81 import android.util.Pools; 82 import android.util.PrintWriterPrinter; 83 import android.util.Printer; 84 import android.util.Slog; 85 import android.util.SparseArray; 86 import android.util.SparseIntArray; 87 import android.util.SparseLongArray; 88 import android.util.TimeUtils; 89 import android.util.Xml; 90 import android.view.Display; 91 92 import com.android.internal.annotations.GuardedBy; 93 import com.android.internal.annotations.VisibleForTesting; 94 import com.android.internal.location.gnssmetrics.GnssMetrics; 95 import com.android.internal.os.KernelCpuUidTimeReader.KernelCpuUidActiveTimeReader; 96 import com.android.internal.os.KernelCpuUidTimeReader.KernelCpuUidClusterTimeReader; 97 import com.android.internal.os.KernelCpuUidTimeReader.KernelCpuUidFreqTimeReader; 98 import com.android.internal.os.KernelCpuUidTimeReader.KernelCpuUidUserSysTimeReader; 99 import com.android.internal.util.ArrayUtils; 100 import com.android.internal.util.FastPrintWriter; 101 import com.android.internal.util.FastXmlSerializer; 102 import com.android.internal.util.FrameworkStatsLog; 103 import com.android.internal.util.XmlUtils; 104 105 import libcore.util.EmptyArray; 106 107 import org.xmlpull.v1.XmlPullParser; 108 import org.xmlpull.v1.XmlPullParserException; 109 import org.xmlpull.v1.XmlSerializer; 110 111 import java.io.ByteArrayOutputStream; 112 import java.io.File; 113 import java.io.FileInputStream; 114 import java.io.FileNotFoundException; 115 import java.io.FileOutputStream; 116 import java.io.IOException; 117 import java.io.PrintWriter; 118 import java.nio.charset.StandardCharsets; 119 import java.util.ArrayList; 120 import java.util.Arrays; 121 import java.util.Calendar; 122 import java.util.Collection; 123 import java.util.HashMap; 124 import java.util.HashSet; 125 import java.util.Iterator; 126 import java.util.LinkedList; 127 import java.util.List; 128 import java.util.Map; 129 import java.util.Queue; 130 import java.util.concurrent.Future; 131 import java.util.concurrent.atomic.AtomicInteger; 132 import java.util.concurrent.locks.ReentrantLock; 133 134 /** 135 * All information we are collecting about things that can happen that impact 136 * battery life. All times are represented in microseconds except where indicated 137 * otherwise. 138 */ 139 public class BatteryStatsImpl extends BatteryStats { 140 private static final String TAG = "BatteryStatsImpl"; 141 private static final boolean DEBUG = false; 142 public static final boolean DEBUG_ENERGY = false; 143 private static final boolean DEBUG_ENERGY_CPU = DEBUG_ENERGY; 144 private static final boolean DEBUG_MEMORY = false; 145 private static final boolean DEBUG_HISTORY = false; 146 private static final boolean USE_OLD_HISTORY = false; // for debugging. 147 148 // TODO: remove "tcp" from network methods, since we measure total stats. 149 150 // In-memory Parcel magic number, used to detect attempts to unmarshall bad data 151 private static final int MAGIC = 0xBA757475; // 'BATSTATS' 152 153 // Current on-disk Parcel version 154 static final int VERSION = 186 + (USE_OLD_HISTORY ? 1000 : 0); 155 156 // The maximum number of names wakelocks we will keep track of 157 // per uid; once the limit is reached, we batch the remaining wakelocks 158 // in to one common name. 159 private static final int MAX_WAKELOCKS_PER_UID; 160 161 static { 162 if (ActivityManager.isLowRamDeviceStatic()) { 163 MAX_WAKELOCKS_PER_UID = 40; 164 } else { 165 MAX_WAKELOCKS_PER_UID = 200; 166 } 167 } 168 169 // Number of transmit power states the Wifi controller can be in. 170 private static final int NUM_WIFI_TX_LEVELS = 1; 171 172 // Number of transmit power states the Bluetooth controller can be in. 173 private static final int NUM_BT_TX_LEVELS = 1; 174 175 /** 176 * Holding a wakelock costs more than just using the cpu. 177 * Currently, we assign only half the cpu time to an app that is running but 178 * not holding a wakelock. The apps holding wakelocks get the rest of the blame. 179 * If no app is holding a wakelock, then the distribution is normal. 180 */ 181 @VisibleForTesting 182 public static final int WAKE_LOCK_WEIGHT = 50; 183 184 protected Clocks mClocks; 185 186 private final AtomicFile mStatsFile; 187 public final AtomicFile mCheckinFile; 188 public final AtomicFile mDailyFile; 189 190 static final int MSG_REPORT_CPU_UPDATE_NEEDED = 1; 191 static final int MSG_REPORT_POWER_CHANGE = 2; 192 static final int MSG_REPORT_CHARGING = 3; 193 static final int MSG_REPORT_RESET_STATS = 4; 194 static final long DELAY_UPDATE_WAKELOCKS = 5*1000; 195 196 private static final double MILLISECONDS_IN_HOUR = 3600 * 1000; 197 private static final long MILLISECONDS_IN_YEAR = 365 * 24 * 3600 * 1000L; 198 199 private final KernelWakelockReader mKernelWakelockReader = new KernelWakelockReader(); 200 private final KernelWakelockStats mTmpWakelockStats = new KernelWakelockStats(); 201 202 @VisibleForTesting 203 protected KernelCpuUidUserSysTimeReader mCpuUidUserSysTimeReader = 204 new KernelCpuUidUserSysTimeReader(true); 205 @VisibleForTesting 206 protected KernelCpuSpeedReader[] mKernelCpuSpeedReaders; 207 @VisibleForTesting 208 protected KernelCpuUidFreqTimeReader mCpuUidFreqTimeReader = 209 new KernelCpuUidFreqTimeReader(true); 210 @VisibleForTesting 211 protected KernelCpuUidActiveTimeReader mCpuUidActiveTimeReader = 212 new KernelCpuUidActiveTimeReader(true); 213 @VisibleForTesting 214 protected KernelCpuUidClusterTimeReader mCpuUidClusterTimeReader = 215 new KernelCpuUidClusterTimeReader(true); 216 @VisibleForTesting 217 protected KernelSingleUidTimeReader mKernelSingleUidTimeReader; 218 219 private final KernelMemoryBandwidthStats mKernelMemoryBandwidthStats 220 = new KernelMemoryBandwidthStats(); 221 private final LongSparseArray<SamplingTimer> mKernelMemoryStats = new LongSparseArray<>(); getKernelMemoryStats()222 public LongSparseArray<SamplingTimer> getKernelMemoryStats() { 223 return mKernelMemoryStats; 224 } 225 226 @GuardedBy("this") 227 public boolean mPerProcStateCpuTimesAvailable = true; 228 229 /** 230 * When per process state cpu times tracking is off, cpu times in KernelSingleUidTimeReader are 231 * not updated. So, when the setting is turned on later, we would end up with huge cpu time 232 * deltas. This flag tracks the case where tracking is turned on from off so that we won't 233 * end up attributing the huge deltas to wrong buckets. 234 */ 235 @GuardedBy("this") 236 private boolean mIsPerProcessStateCpuDataStale; 237 238 /** 239 * Uids for which per-procstate cpu times need to be updated. 240 * 241 * Contains uid -> procState mappings. 242 */ 243 @GuardedBy("this") 244 @VisibleForTesting 245 protected final SparseIntArray mPendingUids = new SparseIntArray(); 246 247 @GuardedBy("this") 248 private long mNumSingleUidCpuTimeReads; 249 @GuardedBy("this") 250 private long mNumBatchedSingleUidCpuTimeReads; 251 @GuardedBy("this") 252 private long mCpuTimeReadsTrackingStartTime = SystemClock.uptimeMillis(); 253 @GuardedBy("this") 254 private int mNumUidsRemoved; 255 @GuardedBy("this") 256 private int mNumAllUidCpuTimeReads; 257 258 /** Container for Resource Power Manager stats. Updated by updateRpmStatsLocked. */ 259 private final RpmStats mTmpRpmStats = new RpmStats(); 260 /** The soonest the RPM stats can be updated after it was last updated. */ 261 private static final long RPM_STATS_UPDATE_FREQ_MS = 1000; 262 /** Last time that RPM stats were updated by updateRpmStatsLocked. */ 263 private long mLastRpmStatsUpdateTimeMs = -RPM_STATS_UPDATE_FREQ_MS; 264 265 /** Container for Rail Energy Data stats. */ 266 private final RailStats mTmpRailStats = new RailStats(); 267 /** 268 * Use a queue to delay removing UIDs from {@link KernelCpuUidUserSysTimeReader}, 269 * {@link KernelCpuUidActiveTimeReader}, {@link KernelCpuUidClusterTimeReader}, 270 * {@link KernelCpuUidFreqTimeReader} and from the Kernel. 271 * 272 * Isolated and invalid UID info must be removed to conserve memory. However, STATSD and 273 * Batterystats both need to access UID cpu time. To resolve this race condition, only 274 * Batterystats shall remove UIDs, and a delay {@link Constants#UID_REMOVE_DELAY_MS} is 275 * implemented so that STATSD can capture those UID times before they are deleted. 276 */ 277 @GuardedBy("this") 278 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) 279 protected Queue<UidToRemove> mPendingRemovedUids = new LinkedList<>(); 280 281 @VisibleForTesting 282 public final class UidToRemove { 283 int startUid; 284 int endUid; 285 long timeAddedInQueue; 286 287 /** Remove just one UID */ UidToRemove(int uid, long timestamp)288 public UidToRemove(int uid, long timestamp) { 289 this(uid, uid, timestamp); 290 } 291 292 /** Remove a range of UIDs, startUid must be smaller than endUid. */ UidToRemove(int startUid, int endUid, long timestamp)293 public UidToRemove(int startUid, int endUid, long timestamp) { 294 this.startUid = startUid; 295 this.endUid = endUid; 296 timeAddedInQueue = timestamp; 297 } 298 remove()299 void remove() { 300 if (startUid == endUid) { 301 mCpuUidUserSysTimeReader.removeUid(startUid); 302 mCpuUidFreqTimeReader.removeUid(startUid); 303 if (mConstants.TRACK_CPU_ACTIVE_CLUSTER_TIME) { 304 mCpuUidActiveTimeReader.removeUid(startUid); 305 mCpuUidClusterTimeReader.removeUid(startUid); 306 } 307 if (mKernelSingleUidTimeReader != null) { 308 mKernelSingleUidTimeReader.removeUid(startUid); 309 } 310 mNumUidsRemoved++; 311 } else if (startUid < endUid) { 312 mCpuUidFreqTimeReader.removeUidsInRange(startUid, endUid); 313 mCpuUidUserSysTimeReader.removeUidsInRange(startUid, endUid); 314 if (mConstants.TRACK_CPU_ACTIVE_CLUSTER_TIME) { 315 mCpuUidActiveTimeReader.removeUidsInRange(startUid, endUid); 316 mCpuUidClusterTimeReader.removeUidsInRange(startUid, endUid); 317 } 318 if (mKernelSingleUidTimeReader != null) { 319 mKernelSingleUidTimeReader.removeUidsInRange(startUid, endUid); 320 } 321 // Treat as one. We don't know how many uids there are in between. 322 mNumUidsRemoved++; 323 } else { 324 Slog.w(TAG, "End UID " + endUid + " is smaller than start UID " + startUid); 325 } 326 } 327 } 328 329 public interface BatteryCallback { batteryNeedsCpuUpdate()330 public void batteryNeedsCpuUpdate(); batteryPowerChanged(boolean onBattery)331 public void batteryPowerChanged(boolean onBattery); batterySendBroadcast(Intent intent)332 public void batterySendBroadcast(Intent intent); batteryStatsReset()333 public void batteryStatsReset(); 334 } 335 336 public interface PlatformIdleStateCallback { fillLowPowerStats(RpmStats rpmStats)337 public void fillLowPowerStats(RpmStats rpmStats); getPlatformLowPowerStats()338 public String getPlatformLowPowerStats(); getSubsystemLowPowerStats()339 public String getSubsystemLowPowerStats(); 340 } 341 342 /** interface to update rail information for power monitor */ 343 public interface RailEnergyDataCallback { 344 /** Function to fill the map for the rail data stats 345 * Used for power monitoring feature 346 * @param railStats 347 */ fillRailDataStats(RailStats railStats)348 void fillRailDataStats(RailStats railStats); 349 } 350 351 public static abstract class UserInfoProvider { 352 private int[] userIds; getUserIds()353 protected abstract @Nullable int[] getUserIds(); 354 @VisibleForTesting refreshUserIds()355 public final void refreshUserIds() { 356 userIds = getUserIds(); 357 } 358 @VisibleForTesting exists(int userId)359 public boolean exists(int userId) { 360 return userIds != null ? ArrayUtils.contains(userIds, userId) : true; 361 } 362 } 363 364 private final PlatformIdleStateCallback mPlatformIdleStateCallback; 365 366 private final Runnable mDeferSetCharging = new Runnable() { 367 @Override 368 public void run() { 369 synchronized (BatteryStatsImpl.this) { 370 if (mOnBattery) { 371 // if the device gets unplugged in the time between this runnable being 372 // executed and the lock being taken, we don't want to set charging state 373 return; 374 } 375 boolean changed = setChargingLocked(true); 376 if (changed) { 377 final long uptime = mClocks.uptimeMillis(); 378 final long elapsedRealtime = mClocks.elapsedRealtime(); 379 addHistoryRecordLocked(elapsedRealtime, uptime); 380 } 381 } 382 } 383 }; 384 385 public final RailEnergyDataCallback mRailEnergyDataCallback; 386 387 /** 388 * This handler is running on {@link BackgroundThread}. 389 */ 390 final class MyHandler extends Handler { MyHandler(Looper looper)391 public MyHandler(Looper looper) { 392 super(looper, null, true); 393 } 394 395 @Override handleMessage(Message msg)396 public void handleMessage(Message msg) { 397 BatteryCallback cb = mCallback; 398 switch (msg.what) { 399 case MSG_REPORT_CPU_UPDATE_NEEDED: 400 if (cb != null) { 401 cb.batteryNeedsCpuUpdate(); 402 } 403 break; 404 case MSG_REPORT_POWER_CHANGE: 405 if (cb != null) { 406 cb.batteryPowerChanged(msg.arg1 != 0); 407 } 408 break; 409 case MSG_REPORT_CHARGING: 410 if (cb != null) { 411 final String action; 412 synchronized (BatteryStatsImpl.this) { 413 action = mCharging ? BatteryManager.ACTION_CHARGING 414 : BatteryManager.ACTION_DISCHARGING; 415 } 416 Intent intent = new Intent(action); 417 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); 418 cb.batterySendBroadcast(intent); 419 } 420 break; 421 case MSG_REPORT_RESET_STATS: 422 if (cb != null) { 423 cb.batteryStatsReset(); 424 } 425 } 426 } 427 } 428 postBatteryNeedsCpuUpdateMsg()429 public void postBatteryNeedsCpuUpdateMsg() { 430 mHandler.sendEmptyMessage(MSG_REPORT_CPU_UPDATE_NEEDED); 431 } 432 433 /** 434 * Update per-freq cpu times for all the uids in {@link #mPendingUids}. 435 */ updateProcStateCpuTimes(boolean onBattery, boolean onBatteryScreenOff)436 public void updateProcStateCpuTimes(boolean onBattery, boolean onBatteryScreenOff) { 437 final SparseIntArray uidStates; 438 synchronized (BatteryStatsImpl.this) { 439 if (!mConstants.TRACK_CPU_TIMES_BY_PROC_STATE) { 440 return; 441 } 442 if(!initKernelSingleUidTimeReaderLocked()) { 443 return; 444 } 445 // If the KernelSingleUidTimeReader has stale cpu times, then we shouldn't try to 446 // compute deltas since it might result in mis-attributing cpu times to wrong states. 447 if (mIsPerProcessStateCpuDataStale) { 448 mPendingUids.clear(); 449 return; 450 } 451 452 if (mPendingUids.size() == 0) { 453 return; 454 } 455 uidStates = mPendingUids.clone(); 456 mPendingUids.clear(); 457 } 458 for (int i = uidStates.size() - 1; i >= 0; --i) { 459 final int uid = uidStates.keyAt(i); 460 final int procState = uidStates.valueAt(i); 461 final int[] isolatedUids; 462 final Uid u; 463 synchronized (BatteryStatsImpl.this) { 464 // It's possible that uid no longer exists and any internal references have 465 // already been deleted, so using {@link #getAvailableUidStatsLocked} to avoid 466 // creating an UidStats object if it doesn't already exist. 467 u = getAvailableUidStatsLocked(uid); 468 if (u == null) { 469 continue; 470 } 471 if (u.mChildUids == null) { 472 isolatedUids = null; 473 } else { 474 isolatedUids = u.mChildUids.toArray(); 475 for (int j = isolatedUids.length - 1; j >= 0; --j) { 476 isolatedUids[j] = u.mChildUids.get(j); 477 } 478 } 479 } 480 long[] cpuTimesMs = mKernelSingleUidTimeReader.readDeltaMs(uid); 481 if (isolatedUids != null) { 482 for (int j = isolatedUids.length - 1; j >= 0; --j) { 483 cpuTimesMs = addCpuTimes(cpuTimesMs, 484 mKernelSingleUidTimeReader.readDeltaMs(isolatedUids[j])); 485 } 486 } 487 if (onBattery && cpuTimesMs != null) { 488 synchronized (BatteryStatsImpl.this) { 489 u.addProcStateTimesMs(procState, cpuTimesMs, onBattery); 490 u.addProcStateScreenOffTimesMs(procState, cpuTimesMs, onBatteryScreenOff); 491 } 492 } 493 } 494 } 495 clearPendingRemovedUids()496 public void clearPendingRemovedUids() { 497 long cutOffTime = mClocks.elapsedRealtime() - mConstants.UID_REMOVE_DELAY_MS; 498 while (!mPendingRemovedUids.isEmpty() 499 && mPendingRemovedUids.peek().timeAddedInQueue < cutOffTime) { 500 mPendingRemovedUids.poll().remove(); 501 } 502 } 503 copyFromAllUidsCpuTimes()504 public void copyFromAllUidsCpuTimes() { 505 synchronized (BatteryStatsImpl.this) { 506 copyFromAllUidsCpuTimes( 507 mOnBatteryTimeBase.isRunning(), mOnBatteryScreenOffTimeBase.isRunning()); 508 } 509 } 510 511 /** 512 * When the battery/screen state changes, we don't attribute the cpu times to any process 513 * but we still need to snapshots of all uids to get correct deltas later on. Since we 514 * already read this data for updating per-freq cpu times, we can use the same data for 515 * per-procstate cpu times. 516 */ copyFromAllUidsCpuTimes(boolean onBattery, boolean onBatteryScreenOff)517 public void copyFromAllUidsCpuTimes(boolean onBattery, boolean onBatteryScreenOff) { 518 synchronized (BatteryStatsImpl.this) { 519 if (!mConstants.TRACK_CPU_TIMES_BY_PROC_STATE) { 520 return; 521 } 522 if(!initKernelSingleUidTimeReaderLocked()) { 523 return; 524 } 525 526 final SparseArray<long[]> allUidCpuFreqTimesMs = 527 mCpuUidFreqTimeReader.getAllUidCpuFreqTimeMs(); 528 // If the KernelSingleUidTimeReader has stale cpu times, then we shouldn't try to 529 // compute deltas since it might result in mis-attributing cpu times to wrong states. 530 if (mIsPerProcessStateCpuDataStale) { 531 mKernelSingleUidTimeReader.setAllUidsCpuTimesMs(allUidCpuFreqTimesMs); 532 mIsPerProcessStateCpuDataStale = false; 533 mPendingUids.clear(); 534 return; 535 } 536 for (int i = allUidCpuFreqTimesMs.size() - 1; i >= 0; --i) { 537 final int uid = allUidCpuFreqTimesMs.keyAt(i); 538 final Uid u = getAvailableUidStatsLocked(mapUid(uid)); 539 if (u == null) { 540 continue; 541 } 542 final long[] cpuTimesMs = allUidCpuFreqTimesMs.valueAt(i); 543 if (cpuTimesMs == null) { 544 continue; 545 } 546 final long[] deltaTimesMs = mKernelSingleUidTimeReader.computeDelta( 547 uid, cpuTimesMs.clone()); 548 if (onBattery && deltaTimesMs != null) { 549 final int procState; 550 final int idx = mPendingUids.indexOfKey(uid); 551 if (idx >= 0) { 552 procState = mPendingUids.valueAt(idx); 553 mPendingUids.removeAt(idx); 554 } else { 555 procState = u.mProcessState; 556 } 557 if (procState >= 0 && procState < Uid.NUM_PROCESS_STATE) { 558 u.addProcStateTimesMs(procState, deltaTimesMs, onBattery); 559 u.addProcStateScreenOffTimesMs(procState, deltaTimesMs, onBatteryScreenOff); 560 } 561 } 562 } 563 } 564 } 565 566 @VisibleForTesting addCpuTimes(long[] timesA, long[] timesB)567 public long[] addCpuTimes(long[] timesA, long[] timesB) { 568 if (timesA != null && timesB != null) { 569 for (int i = timesA.length - 1; i >= 0; --i) { 570 timesA[i] += timesB[i]; 571 } 572 return timesA; 573 } 574 return timesA == null ? (timesB == null ? null : timesB) : timesA; 575 } 576 577 @GuardedBy("this") initKernelSingleUidTimeReaderLocked()578 private boolean initKernelSingleUidTimeReaderLocked() { 579 if (mKernelSingleUidTimeReader == null) { 580 if (mPowerProfile == null) { 581 return false; 582 } 583 if (mCpuFreqs == null) { 584 mCpuFreqs = mCpuUidFreqTimeReader.readFreqs(mPowerProfile); 585 } 586 if (mCpuFreqs != null) { 587 mKernelSingleUidTimeReader = new KernelSingleUidTimeReader(mCpuFreqs.length); 588 } else { 589 mPerProcStateCpuTimesAvailable = mCpuUidFreqTimeReader.allUidTimesAvailable(); 590 return false; 591 } 592 } 593 mPerProcStateCpuTimesAvailable = mCpuUidFreqTimeReader.allUidTimesAvailable() 594 && mKernelSingleUidTimeReader.singleUidCpuTimesAvailable(); 595 return true; 596 } 597 598 public interface Clocks { elapsedRealtime()599 public long elapsedRealtime(); uptimeMillis()600 public long uptimeMillis(); 601 } 602 603 public static class SystemClocks implements Clocks { elapsedRealtime()604 public long elapsedRealtime() { 605 return SystemClock.elapsedRealtime(); 606 } 607 uptimeMillis()608 public long uptimeMillis() { 609 return SystemClock.uptimeMillis(); 610 } 611 } 612 613 public interface ExternalStatsSync { 614 int UPDATE_CPU = 0x01; 615 int UPDATE_WIFI = 0x02; 616 int UPDATE_RADIO = 0x04; 617 int UPDATE_BT = 0x08; 618 int UPDATE_RPM = 0x10; // 16 619 int UPDATE_ALL = UPDATE_CPU | UPDATE_WIFI | UPDATE_RADIO | UPDATE_BT | UPDATE_RPM; 620 scheduleSync(String reason, int flags)621 Future<?> scheduleSync(String reason, int flags); scheduleCpuSyncDueToRemovedUid(int uid)622 Future<?> scheduleCpuSyncDueToRemovedUid(int uid); scheduleReadProcStateCpuTimes(boolean onBattery, boolean onBatteryScreenOff, long delayMillis)623 Future<?> scheduleReadProcStateCpuTimes(boolean onBattery, boolean onBatteryScreenOff, 624 long delayMillis); scheduleCopyFromAllUidsCpuTimes(boolean onBattery, boolean onBatteryScreenOff)625 Future<?> scheduleCopyFromAllUidsCpuTimes(boolean onBattery, boolean onBatteryScreenOff); scheduleCpuSyncDueToSettingChange()626 Future<?> scheduleCpuSyncDueToSettingChange(); scheduleCpuSyncDueToScreenStateChange(boolean onBattery, boolean onBatteryScreenOff)627 Future<?> scheduleCpuSyncDueToScreenStateChange(boolean onBattery, 628 boolean onBatteryScreenOff); scheduleCpuSyncDueToWakelockChange(long delayMillis)629 Future<?> scheduleCpuSyncDueToWakelockChange(long delayMillis); cancelCpuSyncDueToWakelockChange()630 void cancelCpuSyncDueToWakelockChange(); scheduleSyncDueToBatteryLevelChange(long delayMillis)631 Future<?> scheduleSyncDueToBatteryLevelChange(long delayMillis); 632 } 633 634 public Handler mHandler; 635 private ExternalStatsSync mExternalSync = null; 636 @VisibleForTesting 637 protected UserInfoProvider mUserInfoProvider = null; 638 639 private BatteryCallback mCallback; 640 641 /** 642 * Mapping isolated uids to the actual owning app uid. 643 */ 644 final SparseIntArray mIsolatedUids = new SparseIntArray(); 645 646 /** 647 * The statistics we have collected organized by uids. 648 */ 649 final SparseArray<BatteryStatsImpl.Uid> mUidStats = new SparseArray<>(); 650 651 // A set of pools of currently active timers. When a timer is queried, we will divide the 652 // elapsed time by the number of active timers to arrive at that timer's share of the time. 653 // In order to do this, we must refresh each timer whenever the number of active timers 654 // changes. 655 @VisibleForTesting 656 @UnsupportedAppUsage 657 protected ArrayList<StopwatchTimer> mPartialTimers = new ArrayList<>(); 658 @UnsupportedAppUsage 659 final ArrayList<StopwatchTimer> mFullTimers = new ArrayList<>(); 660 @UnsupportedAppUsage 661 final ArrayList<StopwatchTimer> mWindowTimers = new ArrayList<>(); 662 final ArrayList<StopwatchTimer> mDrawTimers = new ArrayList<>(); 663 final SparseArray<ArrayList<StopwatchTimer>> mSensorTimers = new SparseArray<>(); 664 final ArrayList<StopwatchTimer> mWifiRunningTimers = new ArrayList<>(); 665 final ArrayList<StopwatchTimer> mFullWifiLockTimers = new ArrayList<>(); 666 final ArrayList<StopwatchTimer> mWifiMulticastTimers = new ArrayList<>(); 667 final ArrayList<StopwatchTimer> mWifiScanTimers = new ArrayList<>(); 668 final SparseArray<ArrayList<StopwatchTimer>> mWifiBatchedScanTimers = new SparseArray<>(); 669 final ArrayList<StopwatchTimer> mAudioTurnedOnTimers = new ArrayList<>(); 670 final ArrayList<StopwatchTimer> mVideoTurnedOnTimers = new ArrayList<>(); 671 final ArrayList<StopwatchTimer> mFlashlightTurnedOnTimers = new ArrayList<>(); 672 final ArrayList<StopwatchTimer> mCameraTurnedOnTimers = new ArrayList<>(); 673 final ArrayList<StopwatchTimer> mBluetoothScanOnTimers = new ArrayList<>(); 674 675 // Last partial timers we use for distributing CPU usage. 676 @VisibleForTesting 677 protected ArrayList<StopwatchTimer> mLastPartialTimers = new ArrayList<>(); 678 679 // These are the objects that will want to do something when the device 680 // is unplugged from power. 681 protected final TimeBase mOnBatteryTimeBase = new TimeBase(true); 682 683 // These are the objects that will want to do something when the device 684 // is unplugged from power *and* the screen is off or doze. 685 protected final TimeBase mOnBatteryScreenOffTimeBase = new TimeBase(true); 686 687 // Set to true when we want to distribute CPU across wakelocks for the next 688 // CPU update, even if we aren't currently running wake locks. 689 boolean mDistributeWakelockCpu; 690 691 boolean mShuttingDown; 692 693 final HistoryEventTracker mActiveEvents = new HistoryEventTracker(); 694 695 long mHistoryBaseTime; 696 protected boolean mHaveBatteryLevel = false; 697 protected boolean mRecordingHistory = false; 698 int mNumHistoryItems; 699 700 final Parcel mHistoryBuffer = Parcel.obtain(); 701 final HistoryItem mHistoryLastWritten = new HistoryItem(); 702 final HistoryItem mHistoryLastLastWritten = new HistoryItem(); 703 final HistoryItem mHistoryReadTmp = new HistoryItem(); 704 final HistoryItem mHistoryAddTmp = new HistoryItem(); 705 final HashMap<HistoryTag, Integer> mHistoryTagPool = new HashMap<>(); 706 String[] mReadHistoryStrings; 707 int[] mReadHistoryUids; 708 int mReadHistoryChars; 709 int mNextHistoryTagIdx = 0; 710 int mNumHistoryTagChars = 0; 711 int mHistoryBufferLastPos = -1; 712 int mActiveHistoryStates = 0xffffffff; 713 int mActiveHistoryStates2 = 0xffffffff; 714 long mLastHistoryElapsedRealtime = 0; 715 long mTrackRunningHistoryElapsedRealtime = 0; 716 long mTrackRunningHistoryUptime = 0; 717 718 final BatteryStatsHistory mBatteryStatsHistory; 719 720 final HistoryItem mHistoryCur = new HistoryItem(); 721 722 HistoryItem mHistory; 723 HistoryItem mHistoryEnd; 724 HistoryItem mHistoryLastEnd; 725 HistoryItem mHistoryCache; 726 727 // Used by computeHistoryStepDetails 728 HistoryStepDetails mLastHistoryStepDetails = null; 729 byte mLastHistoryStepLevel = 0; 730 final HistoryStepDetails mCurHistoryStepDetails = new HistoryStepDetails(); 731 final HistoryStepDetails mReadHistoryStepDetails = new HistoryStepDetails(); 732 final HistoryStepDetails mTmpHistoryStepDetails = new HistoryStepDetails(); 733 734 /** 735 * Total time (in milliseconds) spent executing in user code. 736 */ 737 long mLastStepCpuUserTime; 738 long mCurStepCpuUserTime; 739 /** 740 * Total time (in milliseconds) spent executing in kernel code. 741 */ 742 long mLastStepCpuSystemTime; 743 long mCurStepCpuSystemTime; 744 /** 745 * Times from /proc/stat (but measured in milliseconds). 746 */ 747 long mLastStepStatUserTime; 748 long mLastStepStatSystemTime; 749 long mLastStepStatIOWaitTime; 750 long mLastStepStatIrqTime; 751 long mLastStepStatSoftIrqTime; 752 long mLastStepStatIdleTime; 753 long mCurStepStatUserTime; 754 long mCurStepStatSystemTime; 755 long mCurStepStatIOWaitTime; 756 long mCurStepStatIrqTime; 757 long mCurStepStatSoftIrqTime; 758 long mCurStepStatIdleTime; 759 760 private HistoryItem mHistoryIterator; 761 private boolean mReadOverflow; 762 private boolean mIteratingHistory; 763 764 int mStartCount; 765 766 long mStartClockTime; 767 String mStartPlatformVersion; 768 String mEndPlatformVersion; 769 770 long mUptime; 771 long mUptimeStart; 772 long mRealtime; 773 long mRealtimeStart; 774 775 int mWakeLockNesting; 776 boolean mWakeLockImportant; 777 public boolean mRecordAllHistory; 778 boolean mNoAutoReset; 779 780 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) 781 protected int mScreenState = Display.STATE_UNKNOWN; 782 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) 783 protected StopwatchTimer mScreenOnTimer; 784 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) 785 protected StopwatchTimer mScreenDozeTimer; 786 787 int mScreenBrightnessBin = -1; 788 final StopwatchTimer[] mScreenBrightnessTimer = new StopwatchTimer[NUM_SCREEN_BRIGHTNESS_BINS]; 789 790 boolean mPretendScreenOff; 791 792 boolean mInteractive; 793 StopwatchTimer mInteractiveTimer; 794 795 boolean mPowerSaveModeEnabled; 796 StopwatchTimer mPowerSaveModeEnabledTimer; 797 798 boolean mDeviceIdling; 799 StopwatchTimer mDeviceIdlingTimer; 800 801 boolean mDeviceLightIdling; 802 StopwatchTimer mDeviceLightIdlingTimer; 803 804 int mDeviceIdleMode; 805 long mLastIdleTimeStart; 806 long mLongestLightIdleTime; 807 long mLongestFullIdleTime; 808 StopwatchTimer mDeviceIdleModeLightTimer; 809 StopwatchTimer mDeviceIdleModeFullTimer; 810 811 boolean mPhoneOn; 812 StopwatchTimer mPhoneOnTimer; 813 814 int mAudioOnNesting; 815 StopwatchTimer mAudioOnTimer; 816 817 int mVideoOnNesting; 818 StopwatchTimer mVideoOnTimer; 819 820 int mFlashlightOnNesting; 821 StopwatchTimer mFlashlightOnTimer; 822 823 int mCameraOnNesting; 824 StopwatchTimer mCameraOnTimer; 825 826 private static final int USB_DATA_UNKNOWN = 0; 827 private static final int USB_DATA_DISCONNECTED = 1; 828 private static final int USB_DATA_CONNECTED = 2; 829 int mUsbDataState = USB_DATA_UNKNOWN; 830 831 int mGpsSignalQualityBin = -1; 832 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) 833 protected final StopwatchTimer[] mGpsSignalQualityTimer = 834 new StopwatchTimer[GnssMetrics.NUM_GPS_SIGNAL_QUALITY_LEVELS]; 835 836 int mPhoneSignalStrengthBin = -1; 837 int mPhoneSignalStrengthBinRaw = -1; 838 final StopwatchTimer[] mPhoneSignalStrengthsTimer = 839 new StopwatchTimer[CellSignalStrength.getNumSignalStrengthLevels()]; 840 841 StopwatchTimer mPhoneSignalScanningTimer; 842 843 int mPhoneDataConnectionType = -1; 844 final StopwatchTimer[] mPhoneDataConnectionsTimer = 845 new StopwatchTimer[NUM_DATA_CONNECTION_TYPES]; 846 847 final LongSamplingCounter[] mNetworkByteActivityCounters = 848 new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES]; 849 final LongSamplingCounter[] mNetworkPacketActivityCounters = 850 new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES]; 851 852 /** 853 * The WiFi Overall wakelock timer 854 * This timer tracks the actual aggregate time for which MC wakelocks are enabled 855 * since addition of per UID timers would not result in an accurate value due to overlapp of 856 * per uid wakelock timers 857 */ 858 StopwatchTimer mWifiMulticastWakelockTimer; 859 860 /** 861 * The WiFi controller activity (time in tx, rx, idle, and power consumed) for the device. 862 */ 863 ControllerActivityCounterImpl mWifiActivity; 864 865 /** 866 * The Bluetooth controller activity (time in tx, rx, idle, and power consumed) for the device. 867 */ 868 ControllerActivityCounterImpl mBluetoothActivity; 869 870 /** 871 * The Modem controller activity (time in tx, rx, idle, and power consumed) for the device. 872 */ 873 ControllerActivityCounterImpl mModemActivity; 874 875 /** 876 * Whether the device supports WiFi controller energy reporting. This is set to true on 877 * the first WiFi energy report. See {@link #mWifiActivity}. 878 */ 879 boolean mHasWifiReporting = false; 880 881 /** 882 * Whether the device supports Bluetooth controller energy reporting. This is set to true on 883 * the first Bluetooth energy report. See {@link #mBluetoothActivity}. 884 */ 885 boolean mHasBluetoothReporting = false; 886 887 /** 888 * Whether the device supports Modem controller energy reporting. This is set to true on 889 * the first Modem energy report. See {@link #mModemActivity}. 890 */ 891 boolean mHasModemReporting = false; 892 893 boolean mWifiOn; 894 StopwatchTimer mWifiOnTimer; 895 896 boolean mGlobalWifiRunning; 897 StopwatchTimer mGlobalWifiRunningTimer; 898 899 int mWifiState = -1; 900 final StopwatchTimer[] mWifiStateTimer = new StopwatchTimer[NUM_WIFI_STATES]; 901 902 int mWifiSupplState = -1; 903 final StopwatchTimer[] mWifiSupplStateTimer = new StopwatchTimer[NUM_WIFI_SUPPL_STATES]; 904 905 int mWifiSignalStrengthBin = -1; 906 final StopwatchTimer[] mWifiSignalStrengthsTimer = 907 new StopwatchTimer[NUM_WIFI_SIGNAL_STRENGTH_BINS]; 908 909 StopwatchTimer mWifiActiveTimer; 910 911 int mBluetoothScanNesting; 912 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) 913 protected StopwatchTimer mBluetoothScanTimer; 914 915 int mMobileRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW; 916 long mMobileRadioActiveStartTime; 917 StopwatchTimer mMobileRadioActiveTimer; 918 StopwatchTimer mMobileRadioActivePerAppTimer; 919 LongSamplingCounter mMobileRadioActiveAdjustedTime; 920 LongSamplingCounter mMobileRadioActiveUnknownTime; 921 LongSamplingCounter mMobileRadioActiveUnknownCount; 922 923 int mWifiRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW; 924 925 /** 926 * These provide time bases that discount the time the device is plugged 927 * in to power. 928 */ 929 boolean mOnBattery; 930 @VisibleForTesting 931 protected boolean mOnBatteryInternal; 932 933 /** 934 * External reporting of whether the device is actually charging. 935 */ 936 boolean mCharging = true; 937 int mLastChargingStateLevel; 938 939 /* 940 * These keep track of battery levels (1-100) at the last plug event and the last unplug event. 941 */ 942 int mDischargeStartLevel; 943 int mDischargeUnplugLevel; 944 int mDischargePlugLevel; 945 int mDischargeCurrentLevel; 946 int mCurrentBatteryLevel; 947 int mLowDischargeAmountSinceCharge; 948 int mHighDischargeAmountSinceCharge; 949 int mDischargeScreenOnUnplugLevel; 950 int mDischargeScreenOffUnplugLevel; 951 int mDischargeScreenDozeUnplugLevel; 952 int mDischargeAmountScreenOn; 953 int mDischargeAmountScreenOnSinceCharge; 954 int mDischargeAmountScreenOff; 955 int mDischargeAmountScreenOffSinceCharge; 956 int mDischargeAmountScreenDoze; 957 int mDischargeAmountScreenDozeSinceCharge; 958 959 private LongSamplingCounter mDischargeScreenOffCounter; 960 private LongSamplingCounter mDischargeScreenDozeCounter; 961 private LongSamplingCounter mDischargeCounter; 962 private LongSamplingCounter mDischargeLightDozeCounter; 963 private LongSamplingCounter mDischargeDeepDozeCounter; 964 965 static final int MAX_LEVEL_STEPS = 200; 966 967 int mInitStepMode = 0; 968 int mCurStepMode = 0; 969 int mModStepMode = 0; 970 971 int mLastDischargeStepLevel; 972 int mMinDischargeStepLevel; 973 final LevelStepTracker mDischargeStepTracker = new LevelStepTracker(MAX_LEVEL_STEPS); 974 final LevelStepTracker mDailyDischargeStepTracker = new LevelStepTracker(MAX_LEVEL_STEPS*2); 975 ArrayList<PackageChange> mDailyPackageChanges; 976 977 int mLastChargeStepLevel; 978 int mMaxChargeStepLevel; 979 final LevelStepTracker mChargeStepTracker = new LevelStepTracker(MAX_LEVEL_STEPS); 980 final LevelStepTracker mDailyChargeStepTracker = new LevelStepTracker(MAX_LEVEL_STEPS*2); 981 982 static final int MAX_DAILY_ITEMS = 10; 983 984 long mDailyStartTime = 0; 985 long mNextMinDailyDeadline = 0; 986 long mNextMaxDailyDeadline = 0; 987 988 final ArrayList<DailyItem> mDailyItems = new ArrayList<>(); 989 990 long mLastWriteTime = 0; // Milliseconds 991 992 private int mPhoneServiceState = -1; 993 private int mPhoneServiceStateRaw = -1; 994 private int mPhoneSimStateRaw = -1; 995 996 private int mNumConnectivityChange; 997 998 private int mEstimatedBatteryCapacity = -1; 999 1000 private int mMinLearnedBatteryCapacity = -1; 1001 private int mMaxLearnedBatteryCapacity = -1; 1002 1003 private long mBatteryTimeToFullSeconds = -1; 1004 1005 private long[] mCpuFreqs; 1006 1007 @VisibleForTesting 1008 protected PowerProfile mPowerProfile; 1009 1010 @GuardedBy("this") 1011 final Constants mConstants; 1012 1013 /* 1014 * Holds a SamplingTimer associated with each Resource Power Manager state and voter, 1015 * recording their times when on-battery (regardless of screen state). 1016 */ 1017 private final HashMap<String, SamplingTimer> mRpmStats = new HashMap<>(); 1018 /** Times for each Resource Power Manager state and voter when screen-off and on-battery. */ 1019 private final HashMap<String, SamplingTimer> mScreenOffRpmStats = new HashMap<>(); 1020 1021 @Override getRpmStats()1022 public Map<String, ? extends Timer> getRpmStats() { 1023 return mRpmStats; 1024 } 1025 1026 // TODO: Note: screenOffRpmStats has been disabled via SCREEN_OFF_RPM_STATS_ENABLED. 1027 @Override getScreenOffRpmStats()1028 public Map<String, ? extends Timer> getScreenOffRpmStats() { 1029 return mScreenOffRpmStats; 1030 } 1031 1032 /* 1033 * Holds a SamplingTimer associated with each kernel wakelock name being tracked. 1034 */ 1035 private final HashMap<String, SamplingTimer> mKernelWakelockStats = new HashMap<>(); 1036 1037 @UnsupportedAppUsage getKernelWakelockStats()1038 public Map<String, ? extends Timer> getKernelWakelockStats() { 1039 return mKernelWakelockStats; 1040 } 1041 1042 String mLastWakeupReason = null; 1043 long mLastWakeupUptimeMs = 0; 1044 private final HashMap<String, SamplingTimer> mWakeupReasonStats = new HashMap<>(); 1045 getWakeupReasonStats()1046 public Map<String, ? extends Timer> getWakeupReasonStats() { 1047 return mWakeupReasonStats; 1048 } 1049 1050 @Override getUahDischarge(int which)1051 public long getUahDischarge(int which) { 1052 return mDischargeCounter.getCountLocked(which); 1053 } 1054 1055 @Override getUahDischargeScreenOff(int which)1056 public long getUahDischargeScreenOff(int which) { 1057 return mDischargeScreenOffCounter.getCountLocked(which); 1058 } 1059 1060 @Override getUahDischargeScreenDoze(int which)1061 public long getUahDischargeScreenDoze(int which) { 1062 return mDischargeScreenDozeCounter.getCountLocked(which); 1063 } 1064 1065 @Override getUahDischargeLightDoze(int which)1066 public long getUahDischargeLightDoze(int which) { 1067 return mDischargeLightDozeCounter.getCountLocked(which); 1068 } 1069 1070 @Override getUahDischargeDeepDoze(int which)1071 public long getUahDischargeDeepDoze(int which) { 1072 return mDischargeDeepDozeCounter.getCountLocked(which); 1073 } 1074 1075 @Override getEstimatedBatteryCapacity()1076 public int getEstimatedBatteryCapacity() { 1077 return mEstimatedBatteryCapacity; 1078 } 1079 1080 @Override getMinLearnedBatteryCapacity()1081 public int getMinLearnedBatteryCapacity() { 1082 return mMinLearnedBatteryCapacity; 1083 } 1084 1085 @Override getMaxLearnedBatteryCapacity()1086 public int getMaxLearnedBatteryCapacity() { 1087 return mMaxLearnedBatteryCapacity; 1088 } 1089 BatteryStatsImpl()1090 public BatteryStatsImpl() { 1091 this(new SystemClocks()); 1092 } 1093 BatteryStatsImpl(Clocks clocks)1094 public BatteryStatsImpl(Clocks clocks) { 1095 init(clocks); 1096 mStatsFile = null; 1097 mCheckinFile = null; 1098 mDailyFile = null; 1099 mBatteryStatsHistory = null; 1100 mHandler = null; 1101 mPlatformIdleStateCallback = null; 1102 mRailEnergyDataCallback = null; 1103 mUserInfoProvider = null; 1104 mConstants = new Constants(mHandler); 1105 clearHistoryLocked(); 1106 } 1107 init(Clocks clocks)1108 private void init(Clocks clocks) { 1109 mClocks = clocks; 1110 } 1111 1112 /** 1113 * TimeBase observer. 1114 */ 1115 public interface TimeBaseObs { onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime)1116 void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime); onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime)1117 void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime); 1118 1119 /** 1120 * Reset the observer's state, returns true if the timer/counter is inactive 1121 * so it can be destroyed. 1122 * @param detachIfReset detach if true, no-op if false. 1123 * @return Returns true if the timer/counter is inactive and can be destroyed. 1124 */ reset(boolean detachIfReset)1125 boolean reset(boolean detachIfReset); 1126 /** 1127 * Detach the observer from TimeBase. 1128 */ detach()1129 void detach(); 1130 } 1131 1132 // methods are protected not private to be VisibleForTesting 1133 public static class TimeBase { 1134 protected final Collection<TimeBaseObs> mObservers; 1135 protected long mUptime; 1136 protected long mRealtime; 1137 1138 protected boolean mRunning; 1139 1140 protected long mPastUptime; 1141 protected long mUptimeStart; 1142 protected long mPastRealtime; 1143 protected long mRealtimeStart; 1144 protected long mUnpluggedUptime; 1145 protected long mUnpluggedRealtime; 1146 dump(PrintWriter pw, String prefix)1147 public void dump(PrintWriter pw, String prefix) { 1148 StringBuilder sb = new StringBuilder(128); 1149 pw.print(prefix); pw.print("mRunning="); pw.println(mRunning); 1150 sb.setLength(0); 1151 sb.append(prefix); 1152 sb.append("mUptime="); 1153 formatTimeMs(sb, mUptime / 1000); 1154 pw.println(sb.toString()); 1155 sb.setLength(0); 1156 sb.append(prefix); 1157 sb.append("mRealtime="); 1158 formatTimeMs(sb, mRealtime / 1000); 1159 pw.println(sb.toString()); 1160 sb.setLength(0); 1161 sb.append(prefix); 1162 sb.append("mPastUptime="); 1163 formatTimeMs(sb, mPastUptime / 1000); sb.append("mUptimeStart="); 1164 formatTimeMs(sb, mUptimeStart / 1000); 1165 sb.append("mUnpluggedUptime="); formatTimeMs(sb, mUnpluggedUptime / 1000); 1166 pw.println(sb.toString()); 1167 sb.setLength(0); 1168 sb.append(prefix); 1169 sb.append("mPastRealtime="); 1170 formatTimeMs(sb, mPastRealtime / 1000); sb.append("mRealtimeStart="); 1171 formatTimeMs(sb, mRealtimeStart / 1000); 1172 sb.append("mUnpluggedRealtime="); formatTimeMs(sb, mUnpluggedRealtime / 1000); 1173 pw.println(sb.toString()); 1174 } 1175 /** 1176 * The mObservers of TimeBase in BatteryStatsImpl object can contain up to 20k entries. 1177 * The mObservers of TimeBase in BatteryStatsImpl.Uid object only contains a few or tens of 1178 * entries. 1179 * mObservers must have good performance on add(), remove(), also be memory efficient. 1180 * This is why we provide isLongList parameter for long and short list user cases. 1181 * @param isLongList If true, use HashSet for mObservers list. 1182 * If false, use ArrayList for mObservers list. 1183 */ TimeBase(boolean isLongList)1184 public TimeBase(boolean isLongList) { 1185 mObservers = isLongList ? new HashSet<>() : new ArrayList<>(); 1186 } 1187 TimeBase()1188 public TimeBase() { 1189 this(false); 1190 } 1191 add(TimeBaseObs observer)1192 public void add(TimeBaseObs observer) { 1193 mObservers.add(observer); 1194 } 1195 remove(TimeBaseObs observer)1196 public void remove(TimeBaseObs observer) { 1197 mObservers.remove(observer); 1198 } 1199 hasObserver(TimeBaseObs observer)1200 public boolean hasObserver(TimeBaseObs observer) { 1201 return mObservers.contains(observer); 1202 } 1203 init(long uptime, long realtime)1204 public void init(long uptime, long realtime) { 1205 mRealtime = 0; 1206 mUptime = 0; 1207 mPastUptime = 0; 1208 mPastRealtime = 0; 1209 mUptimeStart = uptime; 1210 mRealtimeStart = realtime; 1211 mUnpluggedUptime = getUptime(mUptimeStart); 1212 mUnpluggedRealtime = getRealtime(mRealtimeStart); 1213 } 1214 reset(long uptime, long realtime)1215 public void reset(long uptime, long realtime) { 1216 if (!mRunning) { 1217 mPastUptime = 0; 1218 mPastRealtime = 0; 1219 } else { 1220 mUptimeStart = uptime; 1221 mRealtimeStart = realtime; 1222 // TODO: Since mUptimeStart was just reset and we are running, getUptime will 1223 // just return mPastUptime. Also, are we sure we don't want to reset that? 1224 mUnpluggedUptime = getUptime(uptime); 1225 // TODO: likewise. 1226 mUnpluggedRealtime = getRealtime(realtime); 1227 } 1228 } 1229 computeUptime(long curTime, int which)1230 public long computeUptime(long curTime, int which) { 1231 return mUptime + getUptime(curTime); 1232 } 1233 computeRealtime(long curTime, int which)1234 public long computeRealtime(long curTime, int which) { 1235 return mRealtime + getRealtime(curTime); 1236 } 1237 getUptime(long curTime)1238 public long getUptime(long curTime) { 1239 long time = mPastUptime; 1240 if (mRunning) { 1241 time += curTime - mUptimeStart; 1242 } 1243 return time; 1244 } 1245 getRealtime(long curTime)1246 public long getRealtime(long curTime) { 1247 long time = mPastRealtime; 1248 if (mRunning) { 1249 time += curTime - mRealtimeStart; 1250 } 1251 return time; 1252 } 1253 getUptimeStart()1254 public long getUptimeStart() { 1255 return mUptimeStart; 1256 } 1257 getRealtimeStart()1258 public long getRealtimeStart() { 1259 return mRealtimeStart; 1260 } 1261 isRunning()1262 public boolean isRunning() { 1263 return mRunning; 1264 } 1265 setRunning(boolean running, long uptime, long realtime)1266 public boolean setRunning(boolean running, long uptime, long realtime) { 1267 if (mRunning != running) { 1268 mRunning = running; 1269 if (running) { 1270 mUptimeStart = uptime; 1271 mRealtimeStart = realtime; 1272 long batteryUptime = mUnpluggedUptime = getUptime(uptime); 1273 long batteryRealtime = mUnpluggedRealtime = getRealtime(realtime); 1274 // Normally we do not use Iterator in framework code to avoid alloc/dealloc 1275 // Iterator object, here is an exception because mObservers' type is Collection 1276 // instead of list. 1277 final Iterator<TimeBaseObs> iter = mObservers.iterator(); 1278 while (iter.hasNext()) { 1279 iter.next().onTimeStarted(realtime, batteryUptime, batteryRealtime); 1280 } 1281 } else { 1282 mPastUptime += uptime - mUptimeStart; 1283 mPastRealtime += realtime - mRealtimeStart; 1284 long batteryUptime = getUptime(uptime); 1285 long batteryRealtime = getRealtime(realtime); 1286 // Normally we do not use Iterator in framework code to avoid alloc/dealloc 1287 // Iterator object, here is an exception because mObservers' type is Collection 1288 // instead of list. 1289 final Iterator<TimeBaseObs> iter = mObservers.iterator(); 1290 while (iter.hasNext()) { 1291 iter.next().onTimeStopped(realtime, batteryUptime, batteryRealtime); 1292 } 1293 } 1294 return true; 1295 } 1296 return false; 1297 } 1298 readSummaryFromParcel(Parcel in)1299 public void readSummaryFromParcel(Parcel in) { 1300 mUptime = in.readLong(); 1301 mRealtime = in.readLong(); 1302 } 1303 writeSummaryToParcel(Parcel out, long uptime, long realtime)1304 public void writeSummaryToParcel(Parcel out, long uptime, long realtime) { 1305 out.writeLong(computeUptime(uptime, STATS_SINCE_CHARGED)); 1306 out.writeLong(computeRealtime(realtime, STATS_SINCE_CHARGED)); 1307 } 1308 readFromParcel(Parcel in)1309 public void readFromParcel(Parcel in) { 1310 mRunning = false; 1311 mUptime = in.readLong(); 1312 mPastUptime = in.readLong(); 1313 mUptimeStart = in.readLong(); 1314 mRealtime = in.readLong(); 1315 mPastRealtime = in.readLong(); 1316 mRealtimeStart = in.readLong(); 1317 mUnpluggedUptime = in.readLong(); 1318 mUnpluggedRealtime = in.readLong(); 1319 } 1320 writeToParcel(Parcel out, long uptime, long realtime)1321 public void writeToParcel(Parcel out, long uptime, long realtime) { 1322 final long runningUptime = getUptime(uptime); 1323 final long runningRealtime = getRealtime(realtime); 1324 out.writeLong(mUptime); 1325 out.writeLong(runningUptime); 1326 out.writeLong(mUptimeStart); 1327 out.writeLong(mRealtime); 1328 out.writeLong(runningRealtime); 1329 out.writeLong(mRealtimeStart); 1330 out.writeLong(mUnpluggedUptime); 1331 out.writeLong(mUnpluggedRealtime); 1332 } 1333 } 1334 1335 /** 1336 * State for keeping track of counting information. 1337 */ 1338 public static class Counter extends BatteryStats.Counter implements TimeBaseObs { 1339 @UnsupportedAppUsage 1340 final AtomicInteger mCount = new AtomicInteger(); 1341 final TimeBase mTimeBase; 1342 Counter(TimeBase timeBase, Parcel in)1343 public Counter(TimeBase timeBase, Parcel in) { 1344 mTimeBase = timeBase; 1345 mCount.set(in.readInt()); 1346 timeBase.add(this); 1347 } 1348 Counter(TimeBase timeBase)1349 public Counter(TimeBase timeBase) { 1350 mTimeBase = timeBase; 1351 timeBase.add(this); 1352 } 1353 writeToParcel(Parcel out)1354 public void writeToParcel(Parcel out) { 1355 out.writeInt(mCount.get()); 1356 } 1357 1358 @Override onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime)1359 public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) { 1360 } 1361 1362 @Override onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime)1363 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) { 1364 } 1365 1366 /** 1367 * Writes a possibly null Counter to a Parcel. 1368 * 1369 * @param out the Parcel to be written to. 1370 * @param counter a Counter, or null. 1371 */ writeCounterToParcel(Parcel out, @Nullable Counter counter)1372 public static void writeCounterToParcel(Parcel out, @Nullable Counter counter) { 1373 if (counter == null) { 1374 out.writeInt(0); // indicates null 1375 return; 1376 } 1377 out.writeInt(1); // indicates non-null 1378 1379 counter.writeToParcel(out); 1380 } 1381 1382 /** 1383 * Reads a Counter that was written using {@link #writeCounterToParcel(Parcel, Counter)}. 1384 * @param timeBase the timebase to assign to the Counter 1385 * @param in the parcel to read from 1386 * @return the Counter or null. 1387 */ readCounterFromParcel(TimeBase timeBase, Parcel in)1388 public static @Nullable Counter readCounterFromParcel(TimeBase timeBase, Parcel in) { 1389 if (in.readInt() == 0) { 1390 return null; 1391 } 1392 return new Counter(timeBase, in); 1393 } 1394 1395 @Override getCountLocked(int which)1396 public int getCountLocked(int which) { 1397 return mCount.get(); 1398 } 1399 logState(Printer pw, String prefix)1400 public void logState(Printer pw, String prefix) { 1401 pw.println(prefix + "mCount=" + mCount.get()); 1402 } 1403 1404 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) stepAtomic()1405 public void stepAtomic() { 1406 if (mTimeBase.isRunning()) { 1407 mCount.incrementAndGet(); 1408 } 1409 } 1410 addAtomic(int delta)1411 void addAtomic(int delta) { 1412 if (mTimeBase.isRunning()) { 1413 mCount.addAndGet(delta); 1414 } 1415 } 1416 1417 /** 1418 * Clear state of this counter. 1419 */ 1420 @Override reset(boolean detachIfReset)1421 public boolean reset(boolean detachIfReset) { 1422 mCount.set(0); 1423 if (detachIfReset) { 1424 detach(); 1425 } 1426 return true; 1427 } 1428 1429 @Override detach()1430 public void detach() { 1431 mTimeBase.remove(this); 1432 } 1433 1434 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) writeSummaryFromParcelLocked(Parcel out)1435 public void writeSummaryFromParcelLocked(Parcel out) { 1436 out.writeInt(mCount.get()); 1437 } 1438 1439 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) readSummaryFromParcelLocked(Parcel in)1440 public void readSummaryFromParcelLocked(Parcel in) { 1441 mCount.set(in.readInt()); 1442 } 1443 } 1444 1445 @VisibleForTesting 1446 public static class LongSamplingCounterArray extends LongCounterArray implements TimeBaseObs { 1447 final TimeBase mTimeBase; 1448 public long[] mCounts; 1449 LongSamplingCounterArray(TimeBase timeBase, Parcel in)1450 private LongSamplingCounterArray(TimeBase timeBase, Parcel in) { 1451 mTimeBase = timeBase; 1452 mCounts = in.createLongArray(); 1453 timeBase.add(this); 1454 } 1455 LongSamplingCounterArray(TimeBase timeBase)1456 public LongSamplingCounterArray(TimeBase timeBase) { 1457 mTimeBase = timeBase; 1458 timeBase.add(this); 1459 } 1460 writeToParcel(Parcel out)1461 private void writeToParcel(Parcel out) { 1462 out.writeLongArray(mCounts); 1463 } 1464 1465 @Override onTimeStarted(long elapsedRealTime, long baseUptime, long baseRealtime)1466 public void onTimeStarted(long elapsedRealTime, long baseUptime, long baseRealtime) { 1467 } 1468 1469 @Override onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime)1470 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) { 1471 } 1472 1473 @Override getCountsLocked(int which)1474 public long[] getCountsLocked(int which) { 1475 return mCounts == null ? null : Arrays.copyOf(mCounts, mCounts.length); 1476 } 1477 1478 @Override logState(Printer pw, String prefix)1479 public void logState(Printer pw, String prefix) { 1480 pw.println(prefix + "mCounts=" + Arrays.toString(mCounts)); 1481 } 1482 addCountLocked(long[] counts)1483 public void addCountLocked(long[] counts) { 1484 addCountLocked(counts, mTimeBase.isRunning()); 1485 } 1486 addCountLocked(long[] counts, boolean isRunning)1487 public void addCountLocked(long[] counts, boolean isRunning) { 1488 if (counts == null) { 1489 return; 1490 } 1491 if (isRunning) { 1492 if (mCounts == null) { 1493 mCounts = new long[counts.length]; 1494 } 1495 for (int i = 0; i < counts.length; ++i) { 1496 mCounts[i] += counts[i]; 1497 } 1498 } 1499 } 1500 getSize()1501 public int getSize() { 1502 return mCounts == null ? 0 : mCounts.length; 1503 } 1504 1505 /** 1506 * Clear state of this counter. 1507 */ 1508 @Override reset(boolean detachIfReset)1509 public boolean reset(boolean detachIfReset) { 1510 if (mCounts != null) { 1511 Arrays.fill(mCounts, 0); 1512 } 1513 if (detachIfReset) { 1514 detach(); 1515 } 1516 return true; 1517 } 1518 1519 @Override detach()1520 public void detach() { 1521 mTimeBase.remove(this); 1522 } 1523 writeSummaryToParcelLocked(Parcel out)1524 private void writeSummaryToParcelLocked(Parcel out) { 1525 out.writeLongArray(mCounts); 1526 } 1527 readSummaryFromParcelLocked(Parcel in)1528 private void readSummaryFromParcelLocked(Parcel in) { 1529 mCounts = in.createLongArray(); 1530 } 1531 writeToParcel(Parcel out, LongSamplingCounterArray counterArray)1532 public static void writeToParcel(Parcel out, LongSamplingCounterArray counterArray) { 1533 if (counterArray != null) { 1534 out.writeInt(1); 1535 counterArray.writeToParcel(out); 1536 } else { 1537 out.writeInt(0); 1538 } 1539 } 1540 readFromParcel(Parcel in, TimeBase timeBase)1541 public static LongSamplingCounterArray readFromParcel(Parcel in, TimeBase timeBase) { 1542 if (in.readInt() != 0) { 1543 return new LongSamplingCounterArray(timeBase, in); 1544 } else { 1545 return null; 1546 } 1547 } 1548 writeSummaryToParcelLocked(Parcel out, LongSamplingCounterArray counterArray)1549 public static void writeSummaryToParcelLocked(Parcel out, 1550 LongSamplingCounterArray counterArray) { 1551 if (counterArray != null) { 1552 out.writeInt(1); 1553 counterArray.writeSummaryToParcelLocked(out); 1554 } else { 1555 out.writeInt(0); 1556 } 1557 } 1558 readSummaryFromParcelLocked(Parcel in, TimeBase timeBase)1559 public static LongSamplingCounterArray readSummaryFromParcelLocked(Parcel in, 1560 TimeBase timeBase) { 1561 if (in.readInt() != 0) { 1562 final LongSamplingCounterArray counterArray 1563 = new LongSamplingCounterArray(timeBase); 1564 counterArray.readSummaryFromParcelLocked(in); 1565 return counterArray; 1566 } else { 1567 return null; 1568 } 1569 } 1570 } 1571 1572 @VisibleForTesting 1573 public static class LongSamplingCounter extends LongCounter implements TimeBaseObs { 1574 final TimeBase mTimeBase; 1575 private long mCount; 1576 LongSamplingCounter(TimeBase timeBase, Parcel in)1577 public LongSamplingCounter(TimeBase timeBase, Parcel in) { 1578 mTimeBase = timeBase; 1579 mCount = in.readLong(); 1580 timeBase.add(this); 1581 } 1582 LongSamplingCounter(TimeBase timeBase)1583 public LongSamplingCounter(TimeBase timeBase) { 1584 mTimeBase = timeBase; 1585 timeBase.add(this); 1586 } 1587 writeToParcel(Parcel out)1588 public void writeToParcel(Parcel out) { 1589 out.writeLong(mCount); 1590 } 1591 1592 @Override onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime)1593 public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) { 1594 } 1595 1596 @Override onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime)1597 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) { 1598 } 1599 getCountLocked(int which)1600 public long getCountLocked(int which) { 1601 return mCount; 1602 } 1603 1604 @Override logState(Printer pw, String prefix)1605 public void logState(Printer pw, String prefix) { 1606 pw.println(prefix + "mCount=" + mCount); 1607 } 1608 addCountLocked(long count)1609 public void addCountLocked(long count) { 1610 addCountLocked(count, mTimeBase.isRunning()); 1611 } 1612 addCountLocked(long count, boolean isRunning)1613 public void addCountLocked(long count, boolean isRunning) { 1614 if (isRunning) { 1615 mCount += count; 1616 } 1617 } 1618 1619 /** 1620 * Clear state of this counter. 1621 */ 1622 @Override reset(boolean detachIfReset)1623 public boolean reset(boolean detachIfReset) { 1624 mCount = 0; 1625 if (detachIfReset) { 1626 detach(); 1627 } 1628 return true; 1629 } 1630 1631 @Override detach()1632 public void detach() { 1633 mTimeBase.remove(this); 1634 } 1635 writeSummaryFromParcelLocked(Parcel out)1636 public void writeSummaryFromParcelLocked(Parcel out) { 1637 out.writeLong(mCount); 1638 } 1639 readSummaryFromParcelLocked(Parcel in)1640 public void readSummaryFromParcelLocked(Parcel in) { 1641 mCount = in.readLong(); 1642 } 1643 } 1644 1645 /** 1646 * State for keeping track of timing information. 1647 */ 1648 public static abstract class Timer extends BatteryStats.Timer implements TimeBaseObs { 1649 protected final Clocks mClocks; 1650 protected final int mType; 1651 protected final TimeBase mTimeBase; 1652 1653 protected int mCount; 1654 1655 // Times are in microseconds for better accuracy when dividing by the 1656 // lock count, and are in "battery realtime" units. 1657 1658 /** 1659 * The total time we have accumulated since the start of the original 1660 * boot, to the last time something interesting happened in the 1661 * current run. 1662 */ 1663 protected long mTotalTime; 1664 1665 /** 1666 * The total time this timer has been running until the latest mark has been set. 1667 * Subtract this from mTotalTime to get the time spent running since the mark was set. 1668 */ 1669 protected long mTimeBeforeMark; 1670 1671 /** 1672 * Constructs from a parcel. 1673 * @param type 1674 * @param timeBase 1675 * @param in 1676 */ Timer(Clocks clocks, int type, TimeBase timeBase, Parcel in)1677 public Timer(Clocks clocks, int type, TimeBase timeBase, Parcel in) { 1678 mClocks = clocks; 1679 mType = type; 1680 mTimeBase = timeBase; 1681 1682 mCount = in.readInt(); 1683 mTotalTime = in.readLong(); 1684 mTimeBeforeMark = in.readLong(); 1685 timeBase.add(this); 1686 if (DEBUG) Log.i(TAG, "**** READ TIMER #" + mType + ": mTotalTime=" + mTotalTime); 1687 } 1688 Timer(Clocks clocks, int type, TimeBase timeBase)1689 public Timer(Clocks clocks, int type, TimeBase timeBase) { 1690 mClocks = clocks; 1691 mType = type; 1692 mTimeBase = timeBase; 1693 timeBase.add(this); 1694 } 1695 writeToParcel(Parcel out, long elapsedRealtimeUs)1696 public void writeToParcel(Parcel out, long elapsedRealtimeUs) { 1697 if (DEBUG) { 1698 Log.i(TAG, "**** WRITING TIMER #" + mType + ": mTotalTime=" 1699 + computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs))); 1700 } 1701 out.writeInt(computeCurrentCountLocked()); 1702 out.writeLong(computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs))); 1703 out.writeLong(mTimeBeforeMark); 1704 } 1705 computeRunTimeLocked(long curBatteryRealtime)1706 protected abstract long computeRunTimeLocked(long curBatteryRealtime); 1707 computeCurrentCountLocked()1708 protected abstract int computeCurrentCountLocked(); 1709 1710 /** 1711 * Clear state of this timer. Returns true if the timer is inactive 1712 * so can be completely dropped. 1713 */ 1714 @Override reset(boolean detachIfReset)1715 public boolean reset(boolean detachIfReset) { 1716 mTotalTime = mTimeBeforeMark = 0; 1717 mCount = 0; 1718 if (detachIfReset) { 1719 detach(); 1720 } 1721 return true; 1722 } 1723 1724 @Override detach()1725 public void detach() { 1726 mTimeBase.remove(this); 1727 } 1728 1729 @Override onTimeStarted(long elapsedRealtime, long timeBaseUptime, long baseRealtime)1730 public void onTimeStarted(long elapsedRealtime, long timeBaseUptime, long baseRealtime) { 1731 } 1732 1733 @Override onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime)1734 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) { 1735 if (DEBUG && mType < 0) { 1736 Log.v(TAG, "plug #" + mType + ": realtime=" + baseRealtime 1737 + " old mTotalTime=" + mTotalTime); 1738 } 1739 mTotalTime = computeRunTimeLocked(baseRealtime); 1740 mCount = computeCurrentCountLocked(); 1741 if (DEBUG && mType < 0) { 1742 Log.v(TAG, "plug #" + mType + ": new mTotalTime=" + mTotalTime); 1743 } 1744 } 1745 1746 /** 1747 * Writes a possibly null Timer to a Parcel. 1748 * 1749 * @param out the Parcel to be written to. 1750 * @param timer a Timer, or null. 1751 */ 1752 @UnsupportedAppUsage writeTimerToParcel(Parcel out, Timer timer, long elapsedRealtimeUs)1753 public static void writeTimerToParcel(Parcel out, Timer timer, long elapsedRealtimeUs) { 1754 if (timer == null) { 1755 out.writeInt(0); // indicates null 1756 return; 1757 } 1758 out.writeInt(1); // indicates non-null 1759 timer.writeToParcel(out, elapsedRealtimeUs); 1760 } 1761 1762 @Override 1763 @UnsupportedAppUsage getTotalTimeLocked(long elapsedRealtimeUs, int which)1764 public long getTotalTimeLocked(long elapsedRealtimeUs, int which) { 1765 return computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs)); 1766 } 1767 1768 @Override 1769 @UnsupportedAppUsage getCountLocked(int which)1770 public int getCountLocked(int which) { 1771 return computeCurrentCountLocked(); 1772 } 1773 1774 @Override getTimeSinceMarkLocked(long elapsedRealtimeUs)1775 public long getTimeSinceMarkLocked(long elapsedRealtimeUs) { 1776 long val = computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs)); 1777 return val - mTimeBeforeMark; 1778 } 1779 1780 @Override logState(Printer pw, String prefix)1781 public void logState(Printer pw, String prefix) { 1782 pw.println(prefix + "mCount=" + mCount); 1783 pw.println(prefix + "mTotalTime=" + mTotalTime); 1784 } 1785 1786 writeSummaryFromParcelLocked(Parcel out, long elapsedRealtimeUs)1787 public void writeSummaryFromParcelLocked(Parcel out, long elapsedRealtimeUs) { 1788 long runTime = computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs)); 1789 out.writeLong(runTime); 1790 out.writeInt(computeCurrentCountLocked()); 1791 } 1792 readSummaryFromParcelLocked(Parcel in)1793 public void readSummaryFromParcelLocked(Parcel in) { 1794 // Multiply by 1000 for backwards compatibility 1795 mTotalTime = in.readLong(); 1796 mCount = in.readInt(); 1797 // When reading the summary, we set the mark to be the latest information. 1798 mTimeBeforeMark = mTotalTime; 1799 } 1800 } 1801 1802 /** 1803 * A counter meant to accept monotonically increasing values to its {@link #update(long, int)} 1804 * method. The state of the timer according to its {@link TimeBase} will determine how much 1805 * of the value is recorded. 1806 * 1807 * If the value being recorded resets, {@link #endSample()} can be called in order to 1808 * account for the change. If the value passed in to {@link #update(long, int)} decreased 1809 * between calls, the {@link #endSample()} is automatically called and the new value is 1810 * expected to increase monotonically from that point on. 1811 */ 1812 public static class SamplingTimer extends Timer { 1813 1814 /** 1815 * The most recent reported count from /proc/wakelocks. 1816 */ 1817 int mCurrentReportedCount; 1818 1819 /** 1820 * The reported count from /proc/wakelocks when unplug() was last 1821 * called. 1822 */ 1823 int mUnpluggedReportedCount; 1824 1825 /** 1826 * The most recent reported total_time from /proc/wakelocks. 1827 */ 1828 long mCurrentReportedTotalTime; 1829 1830 1831 /** 1832 * The reported total_time from /proc/wakelocks when unplug() was last 1833 * called. 1834 */ 1835 long mUnpluggedReportedTotalTime; 1836 1837 /** 1838 * Whether we are currently in a discharge cycle. 1839 */ 1840 boolean mTimeBaseRunning; 1841 1842 /** 1843 * Whether we are currently recording reported values. 1844 */ 1845 boolean mTrackingReportedValues; 1846 1847 /* 1848 * A sequence counter, incremented once for each update of the stats. 1849 */ 1850 int mUpdateVersion; 1851 1852 @VisibleForTesting SamplingTimer(Clocks clocks, TimeBase timeBase, Parcel in)1853 public SamplingTimer(Clocks clocks, TimeBase timeBase, Parcel in) { 1854 super(clocks, 0, timeBase, in); 1855 mCurrentReportedCount = in.readInt(); 1856 mUnpluggedReportedCount = in.readInt(); 1857 mCurrentReportedTotalTime = in.readLong(); 1858 mUnpluggedReportedTotalTime = in.readLong(); 1859 mTrackingReportedValues = in.readInt() == 1; 1860 mTimeBaseRunning = timeBase.isRunning(); 1861 } 1862 1863 @VisibleForTesting SamplingTimer(Clocks clocks, TimeBase timeBase)1864 public SamplingTimer(Clocks clocks, TimeBase timeBase) { 1865 super(clocks, 0, timeBase); 1866 mTrackingReportedValues = false; 1867 mTimeBaseRunning = timeBase.isRunning(); 1868 } 1869 1870 /** 1871 * Ends the current sample, allowing subsequent values to {@link #update(long, int)} to 1872 * be less than the values used for a previous invocation. 1873 */ endSample()1874 public void endSample() { 1875 mTotalTime = computeRunTimeLocked(0 /* unused by us */); 1876 mCount = computeCurrentCountLocked(); 1877 mUnpluggedReportedTotalTime = mCurrentReportedTotalTime = 0; 1878 mUnpluggedReportedCount = mCurrentReportedCount = 0; 1879 mTrackingReportedValues = false; 1880 } 1881 setUpdateVersion(int version)1882 public void setUpdateVersion(int version) { 1883 mUpdateVersion = version; 1884 } 1885 getUpdateVersion()1886 public int getUpdateVersion() { 1887 return mUpdateVersion; 1888 } 1889 1890 /** 1891 * Updates the current recorded values. These are meant to be monotonically increasing 1892 * and cumulative. If you are dealing with deltas, use {@link #add(long, int)}. 1893 * 1894 * If the values being recorded have been reset, the monotonically increasing requirement 1895 * will be broken. In this case, {@link #endSample()} is automatically called and 1896 * the total value of totalTime and count are recorded, starting a new monotonically 1897 * increasing sample. 1898 * 1899 * @param totalTime total time of sample in microseconds. 1900 * @param count total number of times the event being sampled occurred. 1901 */ update(long totalTime, int count)1902 public void update(long totalTime, int count) { 1903 if (mTimeBaseRunning && !mTrackingReportedValues) { 1904 // Updating the reported value for the first time. 1905 mUnpluggedReportedTotalTime = totalTime; 1906 mUnpluggedReportedCount = count; 1907 } 1908 1909 mTrackingReportedValues = true; 1910 1911 if (totalTime < mCurrentReportedTotalTime || count < mCurrentReportedCount) { 1912 endSample(); 1913 } 1914 1915 mCurrentReportedTotalTime = totalTime; 1916 mCurrentReportedCount = count; 1917 } 1918 1919 /** 1920 * Adds deltaTime and deltaCount to the current sample. 1921 * 1922 * @param deltaTime additional time recorded since the last sampled event, in microseconds. 1923 * @param deltaCount additional number of times the event being sampled occurred. 1924 */ add(long deltaTime, int deltaCount)1925 public void add(long deltaTime, int deltaCount) { 1926 update(mCurrentReportedTotalTime + deltaTime, mCurrentReportedCount + deltaCount); 1927 } 1928 1929 @Override onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime)1930 public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) { 1931 super.onTimeStarted(elapsedRealtime, baseUptime, baseRealtime); 1932 if (mTrackingReportedValues) { 1933 mUnpluggedReportedTotalTime = mCurrentReportedTotalTime; 1934 mUnpluggedReportedCount = mCurrentReportedCount; 1935 } 1936 mTimeBaseRunning = true; 1937 } 1938 1939 @Override onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime)1940 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) { 1941 super.onTimeStopped(elapsedRealtime, baseUptime, baseRealtime); 1942 mTimeBaseRunning = false; 1943 } 1944 1945 @Override logState(Printer pw, String prefix)1946 public void logState(Printer pw, String prefix) { 1947 super.logState(pw, prefix); 1948 pw.println(prefix + "mCurrentReportedCount=" + mCurrentReportedCount 1949 + " mUnpluggedReportedCount=" + mUnpluggedReportedCount 1950 + " mCurrentReportedTotalTime=" + mCurrentReportedTotalTime 1951 + " mUnpluggedReportedTotalTime=" + mUnpluggedReportedTotalTime); 1952 } 1953 1954 @Override computeRunTimeLocked(long curBatteryRealtime)1955 protected long computeRunTimeLocked(long curBatteryRealtime) { 1956 return mTotalTime + (mTimeBaseRunning && mTrackingReportedValues 1957 ? mCurrentReportedTotalTime - mUnpluggedReportedTotalTime : 0); 1958 } 1959 1960 @Override computeCurrentCountLocked()1961 protected int computeCurrentCountLocked() { 1962 return mCount + (mTimeBaseRunning && mTrackingReportedValues 1963 ? mCurrentReportedCount - mUnpluggedReportedCount : 0); 1964 } 1965 1966 @Override writeToParcel(Parcel out, long elapsedRealtimeUs)1967 public void writeToParcel(Parcel out, long elapsedRealtimeUs) { 1968 super.writeToParcel(out, elapsedRealtimeUs); 1969 out.writeInt(mCurrentReportedCount); 1970 out.writeInt(mUnpluggedReportedCount); 1971 out.writeLong(mCurrentReportedTotalTime); 1972 out.writeLong(mUnpluggedReportedTotalTime); 1973 out.writeInt(mTrackingReportedValues ? 1 : 0); 1974 } 1975 1976 @Override reset(boolean detachIfReset)1977 public boolean reset(boolean detachIfReset) { 1978 super.reset(detachIfReset); 1979 mTrackingReportedValues = false; 1980 mUnpluggedReportedTotalTime = 0; 1981 mUnpluggedReportedCount = 0; 1982 return true; 1983 } 1984 } 1985 1986 /** 1987 * A timer that increments in batches. It does not run for durations, but just jumps 1988 * for a pre-determined amount. 1989 */ 1990 public static class BatchTimer extends Timer { 1991 final Uid mUid; 1992 1993 /** 1994 * The last time at which we updated the timer. This is in elapsed realtime microseconds. 1995 */ 1996 long mLastAddedTime; 1997 1998 /** 1999 * The last duration that we added to the timer. This is in microseconds. 2000 */ 2001 long mLastAddedDuration; 2002 2003 /** 2004 * Whether we are currently in a discharge cycle. 2005 */ 2006 boolean mInDischarge; 2007 BatchTimer(Clocks clocks, Uid uid, int type, TimeBase timeBase, Parcel in)2008 BatchTimer(Clocks clocks, Uid uid, int type, TimeBase timeBase, Parcel in) { 2009 super(clocks, type, timeBase, in); 2010 mUid = uid; 2011 mLastAddedTime = in.readLong(); 2012 mLastAddedDuration = in.readLong(); 2013 mInDischarge = timeBase.isRunning(); 2014 } 2015 BatchTimer(Clocks clocks, Uid uid, int type, TimeBase timeBase)2016 BatchTimer(Clocks clocks, Uid uid, int type, TimeBase timeBase) { 2017 super(clocks, type, timeBase); 2018 mUid = uid; 2019 mInDischarge = timeBase.isRunning(); 2020 } 2021 2022 @Override writeToParcel(Parcel out, long elapsedRealtimeUs)2023 public void writeToParcel(Parcel out, long elapsedRealtimeUs) { 2024 super.writeToParcel(out, elapsedRealtimeUs); 2025 out.writeLong(mLastAddedTime); 2026 out.writeLong(mLastAddedDuration); 2027 } 2028 2029 @Override onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime)2030 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) { 2031 recomputeLastDuration(mClocks.elapsedRealtime() * 1000, false); 2032 mInDischarge = false; 2033 super.onTimeStopped(elapsedRealtime, baseUptime, baseRealtime); 2034 } 2035 2036 @Override onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime)2037 public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) { 2038 recomputeLastDuration(elapsedRealtime, false); 2039 mInDischarge = true; 2040 // If we are still within the last added duration, then re-added whatever remains. 2041 if (mLastAddedTime == elapsedRealtime) { 2042 mTotalTime += mLastAddedDuration; 2043 } 2044 super.onTimeStarted(elapsedRealtime, baseUptime, baseRealtime); 2045 } 2046 2047 @Override logState(Printer pw, String prefix)2048 public void logState(Printer pw, String prefix) { 2049 super.logState(pw, prefix); 2050 pw.println(prefix + "mLastAddedTime=" + mLastAddedTime 2051 + " mLastAddedDuration=" + mLastAddedDuration); 2052 } 2053 computeOverage(long curTime)2054 private long computeOverage(long curTime) { 2055 if (mLastAddedTime > 0) { 2056 return mLastAddedDuration - curTime; 2057 } 2058 return 0; 2059 } 2060 recomputeLastDuration(long curTime, boolean abort)2061 private void recomputeLastDuration(long curTime, boolean abort) { 2062 final long overage = computeOverage(curTime); 2063 if (overage > 0) { 2064 // Aborting before the duration ran out -- roll back the remaining 2065 // duration. Only do this if currently discharging; otherwise we didn't 2066 // actually add the time. 2067 if (mInDischarge) { 2068 mTotalTime -= overage; 2069 } 2070 if (abort) { 2071 mLastAddedTime = 0; 2072 } else { 2073 mLastAddedTime = curTime; 2074 mLastAddedDuration -= overage; 2075 } 2076 } 2077 } 2078 addDuration(BatteryStatsImpl stats, long durationMillis)2079 public void addDuration(BatteryStatsImpl stats, long durationMillis) { 2080 final long now = mClocks.elapsedRealtime() * 1000; 2081 recomputeLastDuration(now, true); 2082 mLastAddedTime = now; 2083 mLastAddedDuration = durationMillis * 1000; 2084 if (mInDischarge) { 2085 mTotalTime += mLastAddedDuration; 2086 mCount++; 2087 } 2088 } 2089 abortLastDuration(BatteryStatsImpl stats)2090 public void abortLastDuration(BatteryStatsImpl stats) { 2091 final long now = mClocks.elapsedRealtime() * 1000; 2092 recomputeLastDuration(now, true); 2093 } 2094 2095 @Override computeCurrentCountLocked()2096 protected int computeCurrentCountLocked() { 2097 return mCount; 2098 } 2099 2100 @Override computeRunTimeLocked(long curBatteryRealtime)2101 protected long computeRunTimeLocked(long curBatteryRealtime) { 2102 final long overage = computeOverage(mClocks.elapsedRealtime() * 1000); 2103 if (overage > 0) { 2104 return mTotalTime = overage; 2105 } 2106 return mTotalTime; 2107 } 2108 2109 @Override reset(boolean detachIfReset)2110 public boolean reset(boolean detachIfReset) { 2111 final long now = mClocks.elapsedRealtime() * 1000; 2112 recomputeLastDuration(now, true); 2113 boolean stillActive = mLastAddedTime == now; 2114 super.reset(!stillActive && detachIfReset); 2115 return !stillActive; 2116 } 2117 } 2118 2119 2120 /** 2121 * A StopwatchTimer that also tracks the total and max individual 2122 * time spent active according to the given timebase. Whereas 2123 * StopwatchTimer apportions the time amongst all in the pool, 2124 * the total and max durations are not apportioned. 2125 */ 2126 public static class DurationTimer extends StopwatchTimer { 2127 /** 2128 * The time (in ms) that the timer was last acquired or the time base 2129 * last (re-)started. Increasing the nesting depth does not reset this time. 2130 * 2131 * -1 if the timer is currently not running or the time base is not running. 2132 * 2133 * If written to a parcel, the start time is reset, as is mNesting in the base class 2134 * StopwatchTimer. 2135 */ 2136 long mStartTimeMs = -1; 2137 2138 /** 2139 * The longest time period (in ms) that the timer has been active. Not pooled. 2140 */ 2141 long mMaxDurationMs; 2142 2143 /** 2144 * The time (in ms) that that the timer has been active since most recent 2145 * stopRunningLocked() or reset(). Not pooled. 2146 */ 2147 long mCurrentDurationMs; 2148 2149 /** 2150 * The total time (in ms) that that the timer has been active since most recent reset() 2151 * prior to the current startRunningLocked. This is the sum of all past currentDurations 2152 * (but not including the present currentDuration) since reset. Not pooled. 2153 */ 2154 long mTotalDurationMs; 2155 DurationTimer(Clocks clocks, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, TimeBase timeBase, Parcel in)2156 public DurationTimer(Clocks clocks, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, 2157 TimeBase timeBase, Parcel in) { 2158 super(clocks, uid, type, timerPool, timeBase, in); 2159 mMaxDurationMs = in.readLong(); 2160 mTotalDurationMs = in.readLong(); 2161 mCurrentDurationMs = in.readLong(); 2162 } 2163 DurationTimer(Clocks clocks, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, TimeBase timeBase)2164 public DurationTimer(Clocks clocks, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, 2165 TimeBase timeBase) { 2166 super(clocks, uid, type, timerPool, timeBase); 2167 } 2168 2169 @Override writeToParcel(Parcel out, long elapsedRealtimeUs)2170 public void writeToParcel(Parcel out, long elapsedRealtimeUs) { 2171 super.writeToParcel(out, elapsedRealtimeUs); 2172 out.writeLong(getMaxDurationMsLocked(elapsedRealtimeUs / 1000)); 2173 out.writeLong(mTotalDurationMs); 2174 out.writeLong(getCurrentDurationMsLocked(elapsedRealtimeUs / 1000)); 2175 } 2176 2177 /** 2178 * Write the summary to the parcel. 2179 * 2180 * Since the time base is probably meaningless after we come back, reading 2181 * from this will have the effect of stopping the timer. So here all we write 2182 * is the max and total durations. 2183 */ 2184 @Override writeSummaryFromParcelLocked(Parcel out, long elapsedRealtimeUs)2185 public void writeSummaryFromParcelLocked(Parcel out, long elapsedRealtimeUs) { 2186 super.writeSummaryFromParcelLocked(out, elapsedRealtimeUs); 2187 out.writeLong(getMaxDurationMsLocked(elapsedRealtimeUs / 1000)); 2188 out.writeLong(getTotalDurationMsLocked(elapsedRealtimeUs / 1000)); 2189 } 2190 2191 /** 2192 * Read the summary parcel. 2193 * 2194 * Has the side effect of stopping the timer. 2195 */ 2196 @Override readSummaryFromParcelLocked(Parcel in)2197 public void readSummaryFromParcelLocked(Parcel in) { 2198 super.readSummaryFromParcelLocked(in); 2199 mMaxDurationMs = in.readLong(); 2200 mTotalDurationMs = in.readLong(); 2201 mStartTimeMs = -1; 2202 mCurrentDurationMs = 0; 2203 } 2204 2205 /** 2206 * The TimeBase time started (again). 2207 * 2208 * If the timer is also running, store the start time. 2209 */ onTimeStarted(long elapsedRealtimeUs, long baseUptime, long baseRealtime)2210 public void onTimeStarted(long elapsedRealtimeUs, long baseUptime, long baseRealtime) { 2211 super.onTimeStarted(elapsedRealtimeUs, baseUptime, baseRealtime); 2212 if (mNesting > 0) { 2213 mStartTimeMs = baseRealtime / 1000; 2214 } 2215 } 2216 2217 /** 2218 * The TimeBase stopped running. 2219 * 2220 * If the timer is running, add the duration into mCurrentDurationMs. 2221 */ 2222 @Override onTimeStopped(long elapsedRealtimeUs, long baseUptime, long baseRealtimeUs)2223 public void onTimeStopped(long elapsedRealtimeUs, long baseUptime, long baseRealtimeUs) { 2224 super.onTimeStopped(elapsedRealtimeUs, baseUptime, baseRealtimeUs); 2225 if (mNesting > 0) { 2226 // baseRealtimeUs has already been converted to the timebase's realtime. 2227 mCurrentDurationMs += (baseRealtimeUs / 1000) - mStartTimeMs; 2228 } 2229 mStartTimeMs = -1; 2230 } 2231 2232 @Override logState(Printer pw, String prefix)2233 public void logState(Printer pw, String prefix) { 2234 super.logState(pw, prefix); 2235 } 2236 2237 @Override startRunningLocked(long elapsedRealtimeMs)2238 public void startRunningLocked(long elapsedRealtimeMs) { 2239 super.startRunningLocked(elapsedRealtimeMs); 2240 if (mNesting == 1 && mTimeBase.isRunning()) { 2241 // Just started 2242 mStartTimeMs = mTimeBase.getRealtime(elapsedRealtimeMs * 1000) / 1000; 2243 } 2244 } 2245 2246 /** 2247 * Decrements the mNesting ref-count on this timer. 2248 * 2249 * If it actually stopped (mNesting went to 0), then possibly update 2250 * mMaxDuration if the current duration was the longest ever. 2251 */ 2252 @Override stopRunningLocked(long elapsedRealtimeMs)2253 public void stopRunningLocked(long elapsedRealtimeMs) { 2254 if (mNesting == 1) { 2255 final long durationMs = getCurrentDurationMsLocked(elapsedRealtimeMs); 2256 mTotalDurationMs += durationMs; 2257 if (durationMs > mMaxDurationMs) { 2258 mMaxDurationMs = durationMs; 2259 } 2260 mStartTimeMs = -1; 2261 mCurrentDurationMs = 0; 2262 } 2263 // super method decrements mNesting, which getCurrentDurationMsLocked relies on, 2264 // so call super.stopRunningLocked after calling getCurrentDurationMsLocked. 2265 super.stopRunningLocked(elapsedRealtimeMs); 2266 } 2267 2268 @Override reset(boolean detachIfReset)2269 public boolean reset(boolean detachIfReset) { 2270 boolean result = super.reset(detachIfReset); 2271 mMaxDurationMs = 0; 2272 mTotalDurationMs = 0; 2273 mCurrentDurationMs = 0; 2274 if (mNesting > 0) { 2275 mStartTimeMs = mTimeBase.getRealtime(mClocks.elapsedRealtime() * 1000) / 1000; 2276 } else { 2277 mStartTimeMs = -1; 2278 } 2279 return result; 2280 } 2281 2282 /** 2283 * Returns the max duration that this timer has ever seen. 2284 * 2285 * Note that this time is NOT split between the timers in the timer group that 2286 * this timer is attached to. It is the TOTAL time. 2287 */ 2288 @Override getMaxDurationMsLocked(long elapsedRealtimeMs)2289 public long getMaxDurationMsLocked(long elapsedRealtimeMs) { 2290 if (mNesting > 0) { 2291 final long durationMs = getCurrentDurationMsLocked(elapsedRealtimeMs); 2292 if (durationMs > mMaxDurationMs) { 2293 return durationMs; 2294 } 2295 } 2296 return mMaxDurationMs; 2297 } 2298 2299 /** 2300 * Returns the time since the timer was started. 2301 * Returns 0 if the timer is not currently running. 2302 * 2303 * Note that this time is NOT split between the timers in the timer group that 2304 * this timer is attached to. It is the TOTAL time. 2305 * 2306 * Note that if running timer is parceled and unparceled, this method will return 2307 * current duration value at the time of parceling even though timer may not be 2308 * currently running. 2309 */ 2310 @Override getCurrentDurationMsLocked(long elapsedRealtimeMs)2311 public long getCurrentDurationMsLocked(long elapsedRealtimeMs) { 2312 long durationMs = mCurrentDurationMs; 2313 if (mNesting > 0 && mTimeBase.isRunning()) { 2314 durationMs += (mTimeBase.getRealtime(elapsedRealtimeMs * 1000) / 1000) 2315 - mStartTimeMs; 2316 } 2317 return durationMs; 2318 } 2319 2320 /** 2321 * Returns the total cumulative duration that this timer has been on since reset(). 2322 * If mTimerPool == null, this should be the same 2323 * as getTotalTimeLocked(elapsedRealtimeMs*1000, STATS_SINCE_CHARGED)/1000. 2324 * 2325 * Note that this time is NOT split between the timers in the timer group that 2326 * this timer is attached to. It is the TOTAL time. For this reason, if mTimerPool != null, 2327 * the result will not be equivalent to getTotalTimeLocked. 2328 */ 2329 @Override getTotalDurationMsLocked(long elapsedRealtimeMs)2330 public long getTotalDurationMsLocked(long elapsedRealtimeMs) { 2331 return mTotalDurationMs + getCurrentDurationMsLocked(elapsedRealtimeMs); 2332 } 2333 } 2334 2335 /** 2336 * State for keeping track of timing information. 2337 */ 2338 public static class StopwatchTimer extends Timer { 2339 final Uid mUid; 2340 final ArrayList<StopwatchTimer> mTimerPool; 2341 2342 int mNesting; 2343 2344 /** 2345 * The last time at which we updated the timer. If mNesting is > 0, 2346 * subtract this from the current battery time to find the amount of 2347 * time we have been running since we last computed an update. 2348 */ 2349 long mUpdateTime; 2350 2351 /** 2352 * The total time at which the timer was acquired, to determine if it 2353 * was actually held for an interesting duration. If time base was not running when timer 2354 * was acquired, will be -1. 2355 */ 2356 long mAcquireTime = -1; 2357 2358 long mTimeout; 2359 2360 /** 2361 * For partial wake locks, keep track of whether we are in the list 2362 * to consume CPU cycles. 2363 */ 2364 @VisibleForTesting 2365 public boolean mInList; 2366 StopwatchTimer(Clocks clocks, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, TimeBase timeBase, Parcel in)2367 public StopwatchTimer(Clocks clocks, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, 2368 TimeBase timeBase, Parcel in) { 2369 super(clocks, type, timeBase, in); 2370 mUid = uid; 2371 mTimerPool = timerPool; 2372 mUpdateTime = in.readLong(); 2373 } 2374 StopwatchTimer(Clocks clocks, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, TimeBase timeBase)2375 public StopwatchTimer(Clocks clocks, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, 2376 TimeBase timeBase) { 2377 super(clocks, type, timeBase); 2378 mUid = uid; 2379 mTimerPool = timerPool; 2380 } 2381 setTimeout(long timeout)2382 public void setTimeout(long timeout) { 2383 mTimeout = timeout; 2384 } 2385 writeToParcel(Parcel out, long elapsedRealtimeUs)2386 public void writeToParcel(Parcel out, long elapsedRealtimeUs) { 2387 super.writeToParcel(out, elapsedRealtimeUs); 2388 out.writeLong(mUpdateTime); 2389 } 2390 onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime)2391 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) { 2392 if (mNesting > 0) { 2393 if (DEBUG && mType < 0) { 2394 Log.v(TAG, "old mUpdateTime=" + mUpdateTime); 2395 } 2396 super.onTimeStopped(elapsedRealtime, baseUptime, baseRealtime); 2397 mUpdateTime = baseRealtime; 2398 if (DEBUG && mType < 0) { 2399 Log.v(TAG, "new mUpdateTime=" + mUpdateTime); 2400 } 2401 } 2402 } 2403 logState(Printer pw, String prefix)2404 public void logState(Printer pw, String prefix) { 2405 super.logState(pw, prefix); 2406 pw.println(prefix + "mNesting=" + mNesting + " mUpdateTime=" + mUpdateTime 2407 + " mAcquireTime=" + mAcquireTime); 2408 } 2409 startRunningLocked(long elapsedRealtimeMs)2410 public void startRunningLocked(long elapsedRealtimeMs) { 2411 if (mNesting++ == 0) { 2412 final long batteryRealtime = mTimeBase.getRealtime(elapsedRealtimeMs * 1000); 2413 mUpdateTime = batteryRealtime; 2414 if (mTimerPool != null) { 2415 // Accumulate time to all currently active timers before adding 2416 // this new one to the pool. 2417 refreshTimersLocked(batteryRealtime, mTimerPool, null); 2418 // Add this timer to the active pool 2419 mTimerPool.add(this); 2420 } 2421 if (mTimeBase.isRunning()) { 2422 // Increment the count 2423 mCount++; 2424 mAcquireTime = mTotalTime; 2425 } else { 2426 mAcquireTime = -1; 2427 } 2428 if (DEBUG && mType < 0) { 2429 Log.v(TAG, "start #" + mType + ": mUpdateTime=" + mUpdateTime 2430 + " mTotalTime=" + mTotalTime + " mCount=" + mCount 2431 + " mAcquireTime=" + mAcquireTime); 2432 } 2433 } 2434 } 2435 isRunningLocked()2436 public boolean isRunningLocked() { 2437 return mNesting > 0; 2438 } 2439 stopRunningLocked(long elapsedRealtimeMs)2440 public void stopRunningLocked(long elapsedRealtimeMs) { 2441 // Ignore attempt to stop a timer that isn't running 2442 if (mNesting == 0) { 2443 return; 2444 } 2445 if (--mNesting == 0) { 2446 final long batteryRealtime = mTimeBase.getRealtime(elapsedRealtimeMs * 1000); 2447 if (mTimerPool != null) { 2448 // Accumulate time to all active counters, scaled by the total 2449 // active in the pool, before taking this one out of the pool. 2450 refreshTimersLocked(batteryRealtime, mTimerPool, null); 2451 // Remove this timer from the active pool 2452 mTimerPool.remove(this); 2453 } else { 2454 mNesting = 1; 2455 mTotalTime = computeRunTimeLocked(batteryRealtime); 2456 mNesting = 0; 2457 } 2458 2459 if (DEBUG && mType < 0) { 2460 Log.v(TAG, "stop #" + mType + ": mUpdateTime=" + mUpdateTime 2461 + " mTotalTime=" + mTotalTime + " mCount=" + mCount 2462 + " mAcquireTime=" + mAcquireTime); 2463 } 2464 2465 if (mAcquireTime >= 0 && mTotalTime == mAcquireTime) { 2466 // If there was no change in the time, then discard this 2467 // count. A somewhat cheezy strategy, but hey. 2468 mCount--; 2469 } 2470 } 2471 } 2472 stopAllRunningLocked(long elapsedRealtimeMs)2473 public void stopAllRunningLocked(long elapsedRealtimeMs) { 2474 if (mNesting > 0) { 2475 mNesting = 1; 2476 stopRunningLocked(elapsedRealtimeMs); 2477 } 2478 } 2479 2480 // Update the total time for all other running Timers with the same type as this Timer 2481 // due to a change in timer count refreshTimersLocked(long batteryRealtime, final ArrayList<StopwatchTimer> pool, StopwatchTimer self)2482 private static long refreshTimersLocked(long batteryRealtime, 2483 final ArrayList<StopwatchTimer> pool, StopwatchTimer self) { 2484 long selfTime = 0; 2485 final int N = pool.size(); 2486 for (int i=N-1; i>= 0; i--) { 2487 final StopwatchTimer t = pool.get(i); 2488 long heldTime = batteryRealtime - t.mUpdateTime; 2489 if (heldTime > 0) { 2490 final long myTime = heldTime / N; 2491 if (t == self) { 2492 selfTime = myTime; 2493 } 2494 t.mTotalTime += myTime; 2495 } 2496 t.mUpdateTime = batteryRealtime; 2497 } 2498 return selfTime; 2499 } 2500 2501 @Override computeRunTimeLocked(long curBatteryRealtime)2502 protected long computeRunTimeLocked(long curBatteryRealtime) { 2503 if (mTimeout > 0 && curBatteryRealtime > mUpdateTime + mTimeout) { 2504 curBatteryRealtime = mUpdateTime + mTimeout; 2505 } 2506 return mTotalTime + (mNesting > 0 2507 ? (curBatteryRealtime - mUpdateTime) 2508 / (mTimerPool != null ? mTimerPool.size() : 1) 2509 : 0); 2510 } 2511 2512 @Override computeCurrentCountLocked()2513 protected int computeCurrentCountLocked() { 2514 return mCount; 2515 } 2516 2517 @Override reset(boolean detachIfReset)2518 public boolean reset(boolean detachIfReset) { 2519 boolean canDetach = mNesting <= 0; 2520 super.reset(canDetach && detachIfReset); 2521 if (mNesting > 0) { 2522 mUpdateTime = mTimeBase.getRealtime(mClocks.elapsedRealtime() * 1000); 2523 } 2524 mAcquireTime = -1; // to ensure mCount isn't decreased to -1 if timer is stopped later. 2525 return canDetach; 2526 } 2527 2528 @Override 2529 @UnsupportedAppUsage detach()2530 public void detach() { 2531 super.detach(); 2532 if (mTimerPool != null) { 2533 mTimerPool.remove(this); 2534 } 2535 } 2536 2537 @Override readSummaryFromParcelLocked(Parcel in)2538 public void readSummaryFromParcelLocked(Parcel in) { 2539 super.readSummaryFromParcelLocked(in); 2540 mNesting = 0; 2541 } 2542 2543 /** 2544 * Set the mark so that we can query later for the total time the timer has 2545 * accumulated since this point. The timer can be running or not. 2546 * 2547 * @param elapsedRealtimeMs the current elapsed realtime in milliseconds. 2548 */ setMark(long elapsedRealtimeMs)2549 public void setMark(long elapsedRealtimeMs) { 2550 final long batteryRealtime = mTimeBase.getRealtime(elapsedRealtimeMs * 1000); 2551 if (mNesting > 0) { 2552 // We are running. 2553 if (mTimerPool != null) { 2554 refreshTimersLocked(batteryRealtime, mTimerPool, this); 2555 } else { 2556 mTotalTime += batteryRealtime - mUpdateTime; 2557 mUpdateTime = batteryRealtime; 2558 } 2559 } 2560 mTimeBeforeMark = mTotalTime; 2561 } 2562 } 2563 2564 /** 2565 * State for keeping track of two DurationTimers with different TimeBases, presumably where one 2566 * TimeBase is effectively a subset of the other. 2567 */ 2568 public static class DualTimer extends DurationTimer { 2569 // This class both is a DurationTimer and also holds a second DurationTimer. 2570 // The main timer (this) typically tracks the total time. It may be pooled (but since it's a 2571 // durationTimer, it also has the unpooled getTotalDurationMsLocked() for 2572 // STATS_SINCE_CHARGED). 2573 // mSubTimer typically tracks only part of the total time, such as background time, as 2574 // determined by a subTimeBase. It is NOT pooled. 2575 private final DurationTimer mSubTimer; 2576 2577 /** 2578 * Creates a DualTimer to hold a main timer (this) and a mSubTimer. 2579 * The main timer (this) is based on the given timeBase and timerPool. 2580 * The mSubTimer is based on the given subTimeBase. The mSubTimer is not pooled, even if 2581 * the main timer is. 2582 */ DualTimer(Clocks clocks, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, TimeBase timeBase, TimeBase subTimeBase, Parcel in)2583 public DualTimer(Clocks clocks, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, 2584 TimeBase timeBase, TimeBase subTimeBase, Parcel in) { 2585 super(clocks, uid, type, timerPool, timeBase, in); 2586 mSubTimer = new DurationTimer(clocks, uid, type, null, subTimeBase, in); 2587 } 2588 2589 /** 2590 * Creates a DualTimer to hold a main timer (this) and a mSubTimer. 2591 * The main timer (this) is based on the given timeBase and timerPool. 2592 * The mSubTimer is based on the given subTimeBase. The mSubTimer is not pooled, even if 2593 * the main timer is. 2594 */ DualTimer(Clocks clocks, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, TimeBase timeBase, TimeBase subTimeBase)2595 public DualTimer(Clocks clocks, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, 2596 TimeBase timeBase, TimeBase subTimeBase) { 2597 super(clocks, uid, type, timerPool, timeBase); 2598 mSubTimer = new DurationTimer(clocks, uid, type, null, subTimeBase); 2599 } 2600 2601 /** Get the secondary timer. */ 2602 @Override getSubTimer()2603 public DurationTimer getSubTimer() { 2604 return mSubTimer; 2605 } 2606 2607 @Override startRunningLocked(long elapsedRealtimeMs)2608 public void startRunningLocked(long elapsedRealtimeMs) { 2609 super.startRunningLocked(elapsedRealtimeMs); 2610 mSubTimer.startRunningLocked(elapsedRealtimeMs); 2611 } 2612 2613 @Override stopRunningLocked(long elapsedRealtimeMs)2614 public void stopRunningLocked(long elapsedRealtimeMs) { 2615 super.stopRunningLocked(elapsedRealtimeMs); 2616 mSubTimer.stopRunningLocked(elapsedRealtimeMs); 2617 } 2618 2619 @Override stopAllRunningLocked(long elapsedRealtimeMs)2620 public void stopAllRunningLocked(long elapsedRealtimeMs) { 2621 super.stopAllRunningLocked(elapsedRealtimeMs); 2622 mSubTimer.stopAllRunningLocked(elapsedRealtimeMs); 2623 } 2624 2625 @Override reset(boolean detachIfReset)2626 public boolean reset(boolean detachIfReset) { 2627 boolean active = false; 2628 // Do not detach the subTimer explicitly since that'll be done by DualTimer.detach(). 2629 active |= !mSubTimer.reset(false); 2630 active |= !super.reset(detachIfReset); 2631 return !active; 2632 } 2633 2634 @Override detach()2635 public void detach() { 2636 mSubTimer.detach(); 2637 super.detach(); 2638 } 2639 2640 @Override writeToParcel(Parcel out, long elapsedRealtimeUs)2641 public void writeToParcel(Parcel out, long elapsedRealtimeUs) { 2642 super.writeToParcel(out, elapsedRealtimeUs); 2643 mSubTimer.writeToParcel(out, elapsedRealtimeUs); 2644 } 2645 2646 @Override writeSummaryFromParcelLocked(Parcel out, long elapsedRealtimeUs)2647 public void writeSummaryFromParcelLocked(Parcel out, long elapsedRealtimeUs) { 2648 super.writeSummaryFromParcelLocked(out, elapsedRealtimeUs); 2649 mSubTimer.writeSummaryFromParcelLocked(out, elapsedRealtimeUs); 2650 } 2651 2652 @Override readSummaryFromParcelLocked(Parcel in)2653 public void readSummaryFromParcelLocked(Parcel in) { 2654 super.readSummaryFromParcelLocked(in); 2655 mSubTimer.readSummaryFromParcelLocked(in); 2656 } 2657 } 2658 2659 2660 public abstract class OverflowArrayMap<T> { 2661 private static final String OVERFLOW_NAME = "*overflow*"; 2662 2663 final int mUid; 2664 final ArrayMap<String, T> mMap = new ArrayMap<>(); 2665 T mCurOverflow; 2666 ArrayMap<String, MutableInt> mActiveOverflow; 2667 long mLastOverflowTime; 2668 long mLastOverflowFinishTime; 2669 long mLastClearTime; 2670 long mLastCleanupTime; 2671 OverflowArrayMap(int uid)2672 public OverflowArrayMap(int uid) { 2673 mUid = uid; 2674 } 2675 getMap()2676 public ArrayMap<String, T> getMap() { 2677 return mMap; 2678 } 2679 clear()2680 public void clear() { 2681 mLastClearTime = SystemClock.elapsedRealtime(); 2682 mMap.clear(); 2683 mCurOverflow = null; 2684 mActiveOverflow = null; 2685 } 2686 add(String name, T obj)2687 public void add(String name, T obj) { 2688 if (name == null) { 2689 name = ""; 2690 } 2691 mMap.put(name, obj); 2692 if (OVERFLOW_NAME.equals(name)) { 2693 mCurOverflow = obj; 2694 } 2695 } 2696 cleanup()2697 public void cleanup() { 2698 mLastCleanupTime = SystemClock.elapsedRealtime(); 2699 if (mActiveOverflow != null) { 2700 if (mActiveOverflow.size() == 0) { 2701 mActiveOverflow = null; 2702 } 2703 } 2704 if (mActiveOverflow == null) { 2705 // There is no currently active overflow, so we should no longer have 2706 // an overflow entry. 2707 if (mMap.containsKey(OVERFLOW_NAME)) { 2708 Slog.wtf(TAG, "Cleaning up with no active overflow, but have overflow entry " 2709 + mMap.get(OVERFLOW_NAME)); 2710 mMap.remove(OVERFLOW_NAME); 2711 } 2712 mCurOverflow = null; 2713 } else { 2714 // There is currently active overflow, so we should still have an overflow entry. 2715 if (mCurOverflow == null || !mMap.containsKey(OVERFLOW_NAME)) { 2716 Slog.wtf(TAG, "Cleaning up with active overflow, but no overflow entry: cur=" 2717 + mCurOverflow + " map=" + mMap.get(OVERFLOW_NAME)); 2718 } 2719 } 2720 } 2721 startObject(String name)2722 public T startObject(String name) { 2723 if (name == null) { 2724 name = ""; 2725 } 2726 T obj = mMap.get(name); 2727 if (obj != null) { 2728 return obj; 2729 } 2730 2731 // No object exists for the given name, but do we currently have it 2732 // running as part of the overflow? 2733 if (mActiveOverflow != null) { 2734 MutableInt over = mActiveOverflow.get(name); 2735 if (over != null) { 2736 // We are already actively counting this name in the overflow object. 2737 obj = mCurOverflow; 2738 if (obj == null) { 2739 // Shouldn't be here, but we'll try to recover. 2740 Slog.wtf(TAG, "Have active overflow " + name + " but null overflow"); 2741 obj = mCurOverflow = instantiateObject(); 2742 mMap.put(OVERFLOW_NAME, obj); 2743 } 2744 over.value++; 2745 return obj; 2746 } 2747 } 2748 2749 // No object exists for given name nor in the overflow; we need to make 2750 // a new one. 2751 final int N = mMap.size(); 2752 if (N >= MAX_WAKELOCKS_PER_UID) { 2753 // Went over the limit on number of objects to track; this one goes 2754 // in to the overflow. 2755 obj = mCurOverflow; 2756 if (obj == null) { 2757 // Need to start overflow now... 2758 obj = mCurOverflow = instantiateObject(); 2759 mMap.put(OVERFLOW_NAME, obj); 2760 } 2761 if (mActiveOverflow == null) { 2762 mActiveOverflow = new ArrayMap<>(); 2763 } 2764 mActiveOverflow.put(name, new MutableInt(1)); 2765 mLastOverflowTime = SystemClock.elapsedRealtime(); 2766 return obj; 2767 } 2768 2769 // Normal case where we just need to make a new object. 2770 obj = instantiateObject(); 2771 mMap.put(name, obj); 2772 return obj; 2773 } 2774 stopObject(String name)2775 public T stopObject(String name) { 2776 if (name == null) { 2777 name = ""; 2778 } 2779 T obj = mMap.get(name); 2780 if (obj != null) { 2781 return obj; 2782 } 2783 2784 // No object exists for the given name, but do we currently have it 2785 // running as part of the overflow? 2786 if (mActiveOverflow != null) { 2787 MutableInt over = mActiveOverflow.get(name); 2788 if (over != null) { 2789 // We are already actively counting this name in the overflow object. 2790 obj = mCurOverflow; 2791 if (obj != null) { 2792 over.value--; 2793 if (over.value <= 0) { 2794 mActiveOverflow.remove(name); 2795 mLastOverflowFinishTime = SystemClock.elapsedRealtime(); 2796 } 2797 return obj; 2798 } 2799 } 2800 } 2801 2802 // Huh, they are stopping an active operation but we can't find one! 2803 // That's not good. 2804 StringBuilder sb = new StringBuilder(); 2805 sb.append("Unable to find object for "); 2806 sb.append(name); 2807 sb.append(" in uid "); 2808 sb.append(mUid); 2809 sb.append(" mapsize="); 2810 sb.append(mMap.size()); 2811 sb.append(" activeoverflow="); 2812 sb.append(mActiveOverflow); 2813 sb.append(" curoverflow="); 2814 sb.append(mCurOverflow); 2815 long now = SystemClock.elapsedRealtime(); 2816 if (mLastOverflowTime != 0) { 2817 sb.append(" lastOverflowTime="); 2818 TimeUtils.formatDuration(mLastOverflowTime-now, sb); 2819 } 2820 if (mLastOverflowFinishTime != 0) { 2821 sb.append(" lastOverflowFinishTime="); 2822 TimeUtils.formatDuration(mLastOverflowFinishTime-now, sb); 2823 } 2824 if (mLastClearTime != 0) { 2825 sb.append(" lastClearTime="); 2826 TimeUtils.formatDuration(mLastClearTime-now, sb); 2827 } 2828 if (mLastCleanupTime != 0) { 2829 sb.append(" lastCleanupTime="); 2830 TimeUtils.formatDuration(mLastCleanupTime-now, sb); 2831 } 2832 Slog.wtf(TAG, sb.toString()); 2833 return null; 2834 } 2835 instantiateObject()2836 public abstract T instantiateObject(); 2837 } 2838 2839 public static class ControllerActivityCounterImpl extends ControllerActivityCounter 2840 implements Parcelable { 2841 private final LongSamplingCounter mIdleTimeMillis; 2842 private final LongSamplingCounter mScanTimeMillis; 2843 private final LongSamplingCounter mSleepTimeMillis; 2844 private final LongSamplingCounter mRxTimeMillis; 2845 private final LongSamplingCounter[] mTxTimeMillis; 2846 private final LongSamplingCounter mPowerDrainMaMs; 2847 private final LongSamplingCounter mMonitoredRailChargeConsumedMaMs; 2848 ControllerActivityCounterImpl(TimeBase timeBase, int numTxStates)2849 public ControllerActivityCounterImpl(TimeBase timeBase, int numTxStates) { 2850 mIdleTimeMillis = new LongSamplingCounter(timeBase); 2851 mScanTimeMillis = new LongSamplingCounter(timeBase); 2852 mSleepTimeMillis = new LongSamplingCounter(timeBase); 2853 mRxTimeMillis = new LongSamplingCounter(timeBase); 2854 mTxTimeMillis = new LongSamplingCounter[numTxStates]; 2855 for (int i = 0; i < numTxStates; i++) { 2856 mTxTimeMillis[i] = new LongSamplingCounter(timeBase); 2857 } 2858 mPowerDrainMaMs = new LongSamplingCounter(timeBase); 2859 mMonitoredRailChargeConsumedMaMs = new LongSamplingCounter(timeBase); 2860 } 2861 ControllerActivityCounterImpl(TimeBase timeBase, int numTxStates, Parcel in)2862 public ControllerActivityCounterImpl(TimeBase timeBase, int numTxStates, Parcel in) { 2863 mIdleTimeMillis = new LongSamplingCounter(timeBase, in); 2864 mScanTimeMillis = new LongSamplingCounter(timeBase, in); 2865 mSleepTimeMillis = new LongSamplingCounter(timeBase, in); 2866 mRxTimeMillis = new LongSamplingCounter(timeBase, in); 2867 final int recordedTxStates = in.readInt(); 2868 if (recordedTxStates != numTxStates) { 2869 throw new ParcelFormatException("inconsistent tx state lengths"); 2870 } 2871 2872 mTxTimeMillis = new LongSamplingCounter[numTxStates]; 2873 for (int i = 0; i < numTxStates; i++) { 2874 mTxTimeMillis[i] = new LongSamplingCounter(timeBase, in); 2875 } 2876 mPowerDrainMaMs = new LongSamplingCounter(timeBase, in); 2877 mMonitoredRailChargeConsumedMaMs = new LongSamplingCounter(timeBase, in); 2878 } 2879 readSummaryFromParcel(Parcel in)2880 public void readSummaryFromParcel(Parcel in) { 2881 mIdleTimeMillis.readSummaryFromParcelLocked(in); 2882 mScanTimeMillis.readSummaryFromParcelLocked(in); 2883 mSleepTimeMillis.readSummaryFromParcelLocked(in); 2884 mRxTimeMillis.readSummaryFromParcelLocked(in); 2885 final int recordedTxStates = in.readInt(); 2886 if (recordedTxStates != mTxTimeMillis.length) { 2887 throw new ParcelFormatException("inconsistent tx state lengths"); 2888 } 2889 for (LongSamplingCounter counter : mTxTimeMillis) { 2890 counter.readSummaryFromParcelLocked(in); 2891 } 2892 mPowerDrainMaMs.readSummaryFromParcelLocked(in); 2893 mMonitoredRailChargeConsumedMaMs.readSummaryFromParcelLocked(in); 2894 } 2895 2896 @Override describeContents()2897 public int describeContents() { 2898 return 0; 2899 } 2900 writeSummaryToParcel(Parcel dest)2901 public void writeSummaryToParcel(Parcel dest) { 2902 mIdleTimeMillis.writeSummaryFromParcelLocked(dest); 2903 mScanTimeMillis.writeSummaryFromParcelLocked(dest); 2904 mSleepTimeMillis.writeSummaryFromParcelLocked(dest); 2905 mRxTimeMillis.writeSummaryFromParcelLocked(dest); 2906 dest.writeInt(mTxTimeMillis.length); 2907 for (LongSamplingCounter counter : mTxTimeMillis) { 2908 counter.writeSummaryFromParcelLocked(dest); 2909 } 2910 mPowerDrainMaMs.writeSummaryFromParcelLocked(dest); 2911 mMonitoredRailChargeConsumedMaMs.writeSummaryFromParcelLocked(dest); 2912 } 2913 2914 @Override writeToParcel(Parcel dest, int flags)2915 public void writeToParcel(Parcel dest, int flags) { 2916 mIdleTimeMillis.writeToParcel(dest); 2917 mScanTimeMillis.writeToParcel(dest); 2918 mSleepTimeMillis.writeToParcel(dest); 2919 mRxTimeMillis.writeToParcel(dest); 2920 dest.writeInt(mTxTimeMillis.length); 2921 for (LongSamplingCounter counter : mTxTimeMillis) { 2922 counter.writeToParcel(dest); 2923 } 2924 mPowerDrainMaMs.writeToParcel(dest); 2925 mMonitoredRailChargeConsumedMaMs.writeToParcel(dest); 2926 } 2927 reset(boolean detachIfReset)2928 public void reset(boolean detachIfReset) { 2929 mIdleTimeMillis.reset(detachIfReset); 2930 mScanTimeMillis.reset(detachIfReset); 2931 mSleepTimeMillis.reset(detachIfReset); 2932 mRxTimeMillis.reset(detachIfReset); 2933 for (LongSamplingCounter counter : mTxTimeMillis) { 2934 counter.reset(detachIfReset); 2935 } 2936 mPowerDrainMaMs.reset(detachIfReset); 2937 mMonitoredRailChargeConsumedMaMs.reset(detachIfReset); 2938 } 2939 detach()2940 public void detach() { 2941 mIdleTimeMillis.detach(); 2942 mScanTimeMillis.detach(); 2943 mSleepTimeMillis.detach(); 2944 mRxTimeMillis.detach(); 2945 for (LongSamplingCounter counter : mTxTimeMillis) { 2946 counter.detach(); 2947 } 2948 mPowerDrainMaMs.detach(); 2949 mMonitoredRailChargeConsumedMaMs.detach(); 2950 } 2951 2952 /** 2953 * @return a LongSamplingCounter, measuring time spent in the idle state in 2954 * milliseconds. 2955 */ 2956 @Override getIdleTimeCounter()2957 public LongSamplingCounter getIdleTimeCounter() { 2958 return mIdleTimeMillis; 2959 } 2960 2961 /** 2962 * @return a LongSamplingCounter, measuring time spent in the scan state in 2963 * milliseconds. 2964 */ 2965 @Override getScanTimeCounter()2966 public LongSamplingCounter getScanTimeCounter() { 2967 return mScanTimeMillis; 2968 } 2969 2970 /** 2971 * @return a LongSamplingCounter, measuring time spent in the sleep state in 2972 * milliseconds. 2973 */ 2974 @Override getSleepTimeCounter()2975 public LongSamplingCounter getSleepTimeCounter() { 2976 return mSleepTimeMillis; 2977 } 2978 2979 /** 2980 * @return a LongSamplingCounter, measuring time spent in the receive state in 2981 * milliseconds. 2982 */ 2983 @Override getRxTimeCounter()2984 public LongSamplingCounter getRxTimeCounter() { 2985 return mRxTimeMillis; 2986 } 2987 2988 /** 2989 * @return a LongSamplingCounter[], measuring time spent in various transmit states in 2990 * milliseconds. 2991 */ 2992 @Override getTxTimeCounters()2993 public LongSamplingCounter[] getTxTimeCounters() { 2994 return mTxTimeMillis; 2995 } 2996 2997 /** 2998 * @return a LongSamplingCounter, measuring power use in milli-ampere milliseconds (mAmS). 2999 */ 3000 @Override getPowerCounter()3001 public LongSamplingCounter getPowerCounter() { 3002 return mPowerDrainMaMs; 3003 } 3004 3005 /** 3006 * @return a LongSamplingCounter, measuring actual monitored rail energy consumed 3007 * milli-ampere milli-seconds (mAmS). 3008 */ 3009 @Override getMonitoredRailChargeConsumedMaMs()3010 public LongSamplingCounter getMonitoredRailChargeConsumedMaMs() { 3011 return mMonitoredRailChargeConsumedMaMs; 3012 } 3013 } 3014 3015 /** Get Resource Power Manager stats. Create a new one if it doesn't already exist. */ getRpmTimerLocked(String name)3016 public SamplingTimer getRpmTimerLocked(String name) { 3017 SamplingTimer rpmt = mRpmStats.get(name); 3018 if (rpmt == null) { 3019 rpmt = new SamplingTimer(mClocks, mOnBatteryTimeBase); 3020 mRpmStats.put(name, rpmt); 3021 } 3022 return rpmt; 3023 } 3024 3025 /** Get Screen-off Resource Power Manager stats. Create new one if it doesn't already exist. */ getScreenOffRpmTimerLocked(String name)3026 public SamplingTimer getScreenOffRpmTimerLocked(String name) { 3027 SamplingTimer rpmt = mScreenOffRpmStats.get(name); 3028 if (rpmt == null) { 3029 rpmt = new SamplingTimer(mClocks, mOnBatteryScreenOffTimeBase); 3030 mScreenOffRpmStats.put(name, rpmt); 3031 } 3032 return rpmt; 3033 } 3034 3035 /* 3036 * Get the wakeup reason counter, and create a new one if one 3037 * doesn't already exist. 3038 */ getWakeupReasonTimerLocked(String name)3039 public SamplingTimer getWakeupReasonTimerLocked(String name) { 3040 SamplingTimer timer = mWakeupReasonStats.get(name); 3041 if (timer == null) { 3042 timer = new SamplingTimer(mClocks, mOnBatteryTimeBase); 3043 mWakeupReasonStats.put(name, timer); 3044 } 3045 return timer; 3046 } 3047 3048 /* 3049 * Get the KernelWakelockTimer associated with name, and create a new one if one 3050 * doesn't already exist. 3051 */ getKernelWakelockTimerLocked(String name)3052 public SamplingTimer getKernelWakelockTimerLocked(String name) { 3053 SamplingTimer kwlt = mKernelWakelockStats.get(name); 3054 if (kwlt == null) { 3055 kwlt = new SamplingTimer(mClocks, mOnBatteryScreenOffTimeBase); 3056 mKernelWakelockStats.put(name, kwlt); 3057 } 3058 return kwlt; 3059 } 3060 getKernelMemoryTimerLocked(long bucket)3061 public SamplingTimer getKernelMemoryTimerLocked(long bucket) { 3062 SamplingTimer kmt = mKernelMemoryStats.get(bucket); 3063 if (kmt == null) { 3064 kmt = new SamplingTimer(mClocks, mOnBatteryTimeBase); 3065 mKernelMemoryStats.put(bucket, kmt); 3066 } 3067 return kmt; 3068 } 3069 writeHistoryTag(HistoryTag tag)3070 private int writeHistoryTag(HistoryTag tag) { 3071 Integer idxObj = mHistoryTagPool.get(tag); 3072 int idx; 3073 if (idxObj != null) { 3074 idx = idxObj; 3075 } else { 3076 idx = mNextHistoryTagIdx; 3077 HistoryTag key = new HistoryTag(); 3078 key.setTo(tag); 3079 tag.poolIdx = idx; 3080 mHistoryTagPool.put(key, idx); 3081 mNextHistoryTagIdx++; 3082 mNumHistoryTagChars += key.string.length() + 1; 3083 } 3084 return idx; 3085 } 3086 readHistoryTag(int index, HistoryTag tag)3087 private void readHistoryTag(int index, HistoryTag tag) { 3088 if (index < mReadHistoryStrings.length) { 3089 tag.string = mReadHistoryStrings[index]; 3090 tag.uid = mReadHistoryUids[index]; 3091 } else { 3092 tag.string = null; 3093 tag.uid = 0; 3094 } 3095 tag.poolIdx = index; 3096 } 3097 3098 /* 3099 The history delta format uses flags to denote further data in subsequent ints in the parcel. 3100 3101 There is always the first token, which may contain the delta time, or an indicator of 3102 the length of the time (int or long) following this token. 3103 3104 First token: always present, 3105 31 23 15 7 0 3106 █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█ 3107 3108 T: the delta time if it is <= 0x7fffd. Otherwise 0x7fffe indicates an int immediately 3109 follows containing the time, and 0x7ffff indicates a long immediately follows with the 3110 delta time. 3111 A: battery level changed and an int follows with battery data. 3112 B: state changed and an int follows with state change data. 3113 C: state2 has changed and an int follows with state2 change data. 3114 D: wakelock/wakereason has changed and an wakelock/wakereason struct follows. 3115 E: event data has changed and an event struct follows. 3116 F: battery charge in coulombs has changed and an int with the charge follows. 3117 G: state flag denoting that the mobile radio was active. 3118 H: state flag denoting that the wifi radio was active. 3119 I: state flag denoting that a wifi scan occurred. 3120 J: state flag denoting that a wifi full lock was held. 3121 K: state flag denoting that the gps was on. 3122 L: state flag denoting that a wakelock was held. 3123 M: state flag denoting that the cpu was running. 3124 3125 Time int/long: if T in the first token is 0x7ffff or 0x7fffe, then an int or long follows 3126 with the time delta. 3127 3128 Battery level int: if A in the first token is set, 3129 31 23 15 7 0 3130 █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█ 3131 3132 D: indicates that extra history details follow. 3133 V: the battery voltage. 3134 T: the battery temperature. 3135 L: the battery level (out of 100). 3136 3137 State change int: if B in the first token is set, 3138 31 23 15 7 0 3139 █S|S|S|H|H|H|P|P█F|E|D|C|B| | |A█ | | | | | | | █ | | | | | | | █ 3140 3141 A: wifi multicast was on. 3142 B: battery was plugged in. 3143 C: screen was on. 3144 D: phone was scanning for signal. 3145 E: audio was on. 3146 F: a sensor was active. 3147 3148 State2 change int: if C in the first token is set, 3149 31 23 15 7 0 3150 █M|L|K|J|I|H|H|G█F|E|D|C| | | | █ | | | | | | | █ |B|B|B|A|A|A|A█ 3151 3152 A: 4 bits indicating the wifi supplicant state: {@link BatteryStats#WIFI_SUPPL_STATE_NAMES}. 3153 B: 3 bits indicating the wifi signal strength: 0, 1, 2, 3, 4. 3154 C: a bluetooth scan was active. 3155 D: the camera was active. 3156 E: bluetooth was on. 3157 F: a phone call was active. 3158 G: the device was charging. 3159 H: 2 bits indicating the device-idle (doze) state: off, light, full 3160 I: the flashlight was on. 3161 J: wifi was on. 3162 K: wifi was running. 3163 L: video was playing. 3164 M: power save mode was on. 3165 3166 Wakelock/wakereason struct: if D in the first token is set, 3167 TODO(adamlesinski): describe wakelock/wakereason struct. 3168 3169 Event struct: if E in the first token is set, 3170 TODO(adamlesinski): describe the event struct. 3171 3172 History step details struct: if D in the battery level int is set, 3173 TODO(adamlesinski): describe the history step details struct. 3174 3175 Battery charge int: if F in the first token is set, an int representing the battery charge 3176 in coulombs follows. 3177 */ 3178 3179 // Part of initial delta int that specifies the time delta. 3180 static final int DELTA_TIME_MASK = 0x7ffff; 3181 static final int DELTA_TIME_LONG = 0x7ffff; // The delta is a following long 3182 static final int DELTA_TIME_INT = 0x7fffe; // The delta is a following int 3183 static final int DELTA_TIME_ABS = 0x7fffd; // Following is an entire abs update. 3184 // Flag in delta int: a new battery level int follows. 3185 static final int DELTA_BATTERY_LEVEL_FLAG = 0x00080000; 3186 // Flag in delta int: a new full state and battery status int follows. 3187 static final int DELTA_STATE_FLAG = 0x00100000; 3188 // Flag in delta int: a new full state2 int follows. 3189 static final int DELTA_STATE2_FLAG = 0x00200000; 3190 // Flag in delta int: contains a wakelock or wakeReason tag. 3191 static final int DELTA_WAKELOCK_FLAG = 0x00400000; 3192 // Flag in delta int: contains an event description. 3193 static final int DELTA_EVENT_FLAG = 0x00800000; 3194 // Flag in delta int: contains the battery charge count in uAh. 3195 static final int DELTA_BATTERY_CHARGE_FLAG = 0x01000000; 3196 // These upper bits are the frequently changing state bits. 3197 static final int DELTA_STATE_MASK = 0xfe000000; 3198 3199 // These are the pieces of battery state that are packed in to the upper bits of 3200 // the state int that have been packed in to the first delta int. They must fit 3201 // in STATE_BATTERY_MASK. 3202 static final int STATE_BATTERY_MASK = 0xff000000; 3203 static final int STATE_BATTERY_STATUS_MASK = 0x00000007; 3204 static final int STATE_BATTERY_STATUS_SHIFT = 29; 3205 static final int STATE_BATTERY_HEALTH_MASK = 0x00000007; 3206 static final int STATE_BATTERY_HEALTH_SHIFT = 26; 3207 static final int STATE_BATTERY_PLUG_MASK = 0x00000003; 3208 static final int STATE_BATTERY_PLUG_SHIFT = 24; 3209 3210 // We use the low bit of the battery state int to indicate that we have full details 3211 // from a battery level change. 3212 static final int BATTERY_DELTA_LEVEL_FLAG = 0x00000001; 3213 writeHistoryDelta(Parcel dest, HistoryItem cur, HistoryItem last)3214 public void writeHistoryDelta(Parcel dest, HistoryItem cur, HistoryItem last) { 3215 if (last == null || cur.cmd != HistoryItem.CMD_UPDATE) { 3216 dest.writeInt(DELTA_TIME_ABS); 3217 cur.writeToParcel(dest, 0); 3218 return; 3219 } 3220 3221 final long deltaTime = cur.time - last.time; 3222 final int lastBatteryLevelInt = buildBatteryLevelInt(last); 3223 final int lastStateInt = buildStateInt(last); 3224 3225 int deltaTimeToken; 3226 if (deltaTime < 0 || deltaTime > Integer.MAX_VALUE) { 3227 deltaTimeToken = DELTA_TIME_LONG; 3228 } else if (deltaTime >= DELTA_TIME_ABS) { 3229 deltaTimeToken = DELTA_TIME_INT; 3230 } else { 3231 deltaTimeToken = (int)deltaTime; 3232 } 3233 int firstToken = deltaTimeToken | (cur.states&DELTA_STATE_MASK); 3234 final int includeStepDetails = mLastHistoryStepLevel > cur.batteryLevel 3235 ? BATTERY_DELTA_LEVEL_FLAG : 0; 3236 final boolean computeStepDetails = includeStepDetails != 0 3237 || mLastHistoryStepDetails == null; 3238 final int batteryLevelInt = buildBatteryLevelInt(cur) | includeStepDetails; 3239 final boolean batteryLevelIntChanged = batteryLevelInt != lastBatteryLevelInt; 3240 if (batteryLevelIntChanged) { 3241 firstToken |= DELTA_BATTERY_LEVEL_FLAG; 3242 } 3243 final int stateInt = buildStateInt(cur); 3244 final boolean stateIntChanged = stateInt != lastStateInt; 3245 if (stateIntChanged) { 3246 firstToken |= DELTA_STATE_FLAG; 3247 } 3248 final boolean state2IntChanged = cur.states2 != last.states2; 3249 if (state2IntChanged) { 3250 firstToken |= DELTA_STATE2_FLAG; 3251 } 3252 if (cur.wakelockTag != null || cur.wakeReasonTag != null) { 3253 firstToken |= DELTA_WAKELOCK_FLAG; 3254 } 3255 if (cur.eventCode != HistoryItem.EVENT_NONE) { 3256 firstToken |= DELTA_EVENT_FLAG; 3257 } 3258 3259 final boolean batteryChargeChanged = cur.batteryChargeUAh != last.batteryChargeUAh; 3260 if (batteryChargeChanged) { 3261 firstToken |= DELTA_BATTERY_CHARGE_FLAG; 3262 } 3263 dest.writeInt(firstToken); 3264 if (DEBUG) Slog.i(TAG, "WRITE DELTA: firstToken=0x" + Integer.toHexString(firstToken) 3265 + " deltaTime=" + deltaTime); 3266 3267 if (deltaTimeToken >= DELTA_TIME_INT) { 3268 if (deltaTimeToken == DELTA_TIME_INT) { 3269 if (DEBUG) Slog.i(TAG, "WRITE DELTA: int deltaTime=" + (int)deltaTime); 3270 dest.writeInt((int)deltaTime); 3271 } else { 3272 if (DEBUG) Slog.i(TAG, "WRITE DELTA: long deltaTime=" + deltaTime); 3273 dest.writeLong(deltaTime); 3274 } 3275 } 3276 if (batteryLevelIntChanged) { 3277 dest.writeInt(batteryLevelInt); 3278 if (DEBUG) Slog.i(TAG, "WRITE DELTA: batteryToken=0x" 3279 + Integer.toHexString(batteryLevelInt) 3280 + " batteryLevel=" + cur.batteryLevel 3281 + " batteryTemp=" + cur.batteryTemperature 3282 + " batteryVolt=" + (int)cur.batteryVoltage); 3283 } 3284 if (stateIntChanged) { 3285 dest.writeInt(stateInt); 3286 if (DEBUG) Slog.i(TAG, "WRITE DELTA: stateToken=0x" 3287 + Integer.toHexString(stateInt) 3288 + " batteryStatus=" + cur.batteryStatus 3289 + " batteryHealth=" + cur.batteryHealth 3290 + " batteryPlugType=" + cur.batteryPlugType 3291 + " states=0x" + Integer.toHexString(cur.states)); 3292 } 3293 if (state2IntChanged) { 3294 dest.writeInt(cur.states2); 3295 if (DEBUG) Slog.i(TAG, "WRITE DELTA: states2=0x" 3296 + Integer.toHexString(cur.states2)); 3297 } 3298 if (cur.wakelockTag != null || cur.wakeReasonTag != null) { 3299 int wakeLockIndex; 3300 int wakeReasonIndex; 3301 if (cur.wakelockTag != null) { 3302 wakeLockIndex = writeHistoryTag(cur.wakelockTag); 3303 if (DEBUG) Slog.i(TAG, "WRITE DELTA: wakelockTag=#" + cur.wakelockTag.poolIdx 3304 + " " + cur.wakelockTag.uid + ":" + cur.wakelockTag.string); 3305 } else { 3306 wakeLockIndex = 0xffff; 3307 } 3308 if (cur.wakeReasonTag != null) { 3309 wakeReasonIndex = writeHistoryTag(cur.wakeReasonTag); 3310 if (DEBUG) Slog.i(TAG, "WRITE DELTA: wakeReasonTag=#" + cur.wakeReasonTag.poolIdx 3311 + " " + cur.wakeReasonTag.uid + ":" + cur.wakeReasonTag.string); 3312 } else { 3313 wakeReasonIndex = 0xffff; 3314 } 3315 dest.writeInt((wakeReasonIndex<<16) | wakeLockIndex); 3316 } 3317 if (cur.eventCode != HistoryItem.EVENT_NONE) { 3318 int index = writeHistoryTag(cur.eventTag); 3319 int codeAndIndex = (cur.eventCode&0xffff) | (index<<16); 3320 dest.writeInt(codeAndIndex); 3321 if (DEBUG) Slog.i(TAG, "WRITE DELTA: event=" + cur.eventCode + " tag=#" 3322 + cur.eventTag.poolIdx + " " + cur.eventTag.uid + ":" 3323 + cur.eventTag.string); 3324 } 3325 if (computeStepDetails) { 3326 if (mPlatformIdleStateCallback != null) { 3327 mCurHistoryStepDetails.statPlatformIdleState = 3328 mPlatformIdleStateCallback.getPlatformLowPowerStats(); 3329 if (DEBUG) Slog.i(TAG, "WRITE PlatformIdleState:" + 3330 mCurHistoryStepDetails.statPlatformIdleState); 3331 3332 mCurHistoryStepDetails.statSubsystemPowerState = 3333 mPlatformIdleStateCallback.getSubsystemLowPowerStats(); 3334 if (DEBUG) Slog.i(TAG, "WRITE SubsystemPowerState:" + 3335 mCurHistoryStepDetails.statSubsystemPowerState); 3336 3337 } 3338 computeHistoryStepDetails(mCurHistoryStepDetails, mLastHistoryStepDetails); 3339 if (includeStepDetails != 0) { 3340 mCurHistoryStepDetails.writeToParcel(dest); 3341 } 3342 cur.stepDetails = mCurHistoryStepDetails; 3343 mLastHistoryStepDetails = mCurHistoryStepDetails; 3344 } else { 3345 cur.stepDetails = null; 3346 } 3347 if (mLastHistoryStepLevel < cur.batteryLevel) { 3348 mLastHistoryStepDetails = null; 3349 } 3350 mLastHistoryStepLevel = cur.batteryLevel; 3351 3352 if (batteryChargeChanged) { 3353 if (DEBUG) Slog.i(TAG, "WRITE DELTA: batteryChargeUAh=" + cur.batteryChargeUAh); 3354 dest.writeInt(cur.batteryChargeUAh); 3355 } 3356 dest.writeDouble(cur.modemRailChargeMah); 3357 dest.writeDouble(cur.wifiRailChargeMah); 3358 } 3359 buildBatteryLevelInt(HistoryItem h)3360 private int buildBatteryLevelInt(HistoryItem h) { 3361 return ((((int)h.batteryLevel)<<25)&0xfe000000) 3362 | ((((int)h.batteryTemperature)<<15)&0x01ff8000) 3363 | ((((int)h.batteryVoltage)<<1)&0x00007ffe); 3364 } 3365 readBatteryLevelInt(int batteryLevelInt, HistoryItem out)3366 private void readBatteryLevelInt(int batteryLevelInt, HistoryItem out) { 3367 out.batteryLevel = (byte)((batteryLevelInt & 0xfe000000) >>> 25); 3368 out.batteryTemperature = (short)((batteryLevelInt & 0x01ff8000) >>> 15); 3369 out.batteryVoltage = (char)((batteryLevelInt & 0x00007ffe) >>> 1); 3370 } 3371 buildStateInt(HistoryItem h)3372 private int buildStateInt(HistoryItem h) { 3373 int plugType = 0; 3374 if ((h.batteryPlugType&BatteryManager.BATTERY_PLUGGED_AC) != 0) { 3375 plugType = 1; 3376 } else if ((h.batteryPlugType&BatteryManager.BATTERY_PLUGGED_USB) != 0) { 3377 plugType = 2; 3378 } else if ((h.batteryPlugType&BatteryManager.BATTERY_PLUGGED_WIRELESS) != 0) { 3379 plugType = 3; 3380 } 3381 return ((h.batteryStatus&STATE_BATTERY_STATUS_MASK)<<STATE_BATTERY_STATUS_SHIFT) 3382 | ((h.batteryHealth&STATE_BATTERY_HEALTH_MASK)<<STATE_BATTERY_HEALTH_SHIFT) 3383 | ((plugType&STATE_BATTERY_PLUG_MASK)<<STATE_BATTERY_PLUG_SHIFT) 3384 | (h.states&(~STATE_BATTERY_MASK)); 3385 } 3386 computeHistoryStepDetails(final HistoryStepDetails out, final HistoryStepDetails last)3387 private void computeHistoryStepDetails(final HistoryStepDetails out, 3388 final HistoryStepDetails last) { 3389 final HistoryStepDetails tmp = last != null ? mTmpHistoryStepDetails : out; 3390 3391 // Perform a CPU update right after we do this collection, so we have started 3392 // collecting good data for the next step. 3393 requestImmediateCpuUpdate(); 3394 3395 if (last == null) { 3396 // We are not generating a delta, so all we need to do is reset the stats 3397 // we will later be doing a delta from. 3398 final int NU = mUidStats.size(); 3399 for (int i=0; i<NU; i++) { 3400 final BatteryStatsImpl.Uid uid = mUidStats.valueAt(i); 3401 uid.mLastStepUserTime = uid.mCurStepUserTime; 3402 uid.mLastStepSystemTime = uid.mCurStepSystemTime; 3403 } 3404 mLastStepCpuUserTime = mCurStepCpuUserTime; 3405 mLastStepCpuSystemTime = mCurStepCpuSystemTime; 3406 mLastStepStatUserTime = mCurStepStatUserTime; 3407 mLastStepStatSystemTime = mCurStepStatSystemTime; 3408 mLastStepStatIOWaitTime = mCurStepStatIOWaitTime; 3409 mLastStepStatIrqTime = mCurStepStatIrqTime; 3410 mLastStepStatSoftIrqTime = mCurStepStatSoftIrqTime; 3411 mLastStepStatIdleTime = mCurStepStatIdleTime; 3412 tmp.clear(); 3413 return; 3414 } 3415 if (DEBUG) { 3416 Slog.d(TAG, "Step stats last: user=" + mLastStepCpuUserTime + " sys=" 3417 + mLastStepStatSystemTime + " io=" + mLastStepStatIOWaitTime 3418 + " irq=" + mLastStepStatIrqTime + " sirq=" 3419 + mLastStepStatSoftIrqTime + " idle=" + mLastStepStatIdleTime); 3420 Slog.d(TAG, "Step stats cur: user=" + mCurStepCpuUserTime + " sys=" 3421 + mCurStepStatSystemTime + " io=" + mCurStepStatIOWaitTime 3422 + " irq=" + mCurStepStatIrqTime + " sirq=" 3423 + mCurStepStatSoftIrqTime + " idle=" + mCurStepStatIdleTime); 3424 } 3425 out.userTime = (int)(mCurStepCpuUserTime - mLastStepCpuUserTime); 3426 out.systemTime = (int)(mCurStepCpuSystemTime - mLastStepCpuSystemTime); 3427 out.statUserTime = (int)(mCurStepStatUserTime - mLastStepStatUserTime); 3428 out.statSystemTime = (int)(mCurStepStatSystemTime - mLastStepStatSystemTime); 3429 out.statIOWaitTime = (int)(mCurStepStatIOWaitTime - mLastStepStatIOWaitTime); 3430 out.statIrqTime = (int)(mCurStepStatIrqTime - mLastStepStatIrqTime); 3431 out.statSoftIrqTime = (int)(mCurStepStatSoftIrqTime - mLastStepStatSoftIrqTime); 3432 out.statIdlTime = (int)(mCurStepStatIdleTime - mLastStepStatIdleTime); 3433 out.appCpuUid1 = out.appCpuUid2 = out.appCpuUid3 = -1; 3434 out.appCpuUTime1 = out.appCpuUTime2 = out.appCpuUTime3 = 0; 3435 out.appCpuSTime1 = out.appCpuSTime2 = out.appCpuSTime3 = 0; 3436 final int NU = mUidStats.size(); 3437 for (int i=0; i<NU; i++) { 3438 final BatteryStatsImpl.Uid uid = mUidStats.valueAt(i); 3439 final int totalUTime = (int)(uid.mCurStepUserTime - uid.mLastStepUserTime); 3440 final int totalSTime = (int)(uid.mCurStepSystemTime - uid.mLastStepSystemTime); 3441 final int totalTime = totalUTime + totalSTime; 3442 uid.mLastStepUserTime = uid.mCurStepUserTime; 3443 uid.mLastStepSystemTime = uid.mCurStepSystemTime; 3444 if (totalTime <= (out.appCpuUTime3+out.appCpuSTime3)) { 3445 continue; 3446 } 3447 if (totalTime <= (out.appCpuUTime2+out.appCpuSTime2)) { 3448 out.appCpuUid3 = uid.mUid; 3449 out.appCpuUTime3 = totalUTime; 3450 out.appCpuSTime3 = totalSTime; 3451 } else { 3452 out.appCpuUid3 = out.appCpuUid2; 3453 out.appCpuUTime3 = out.appCpuUTime2; 3454 out.appCpuSTime3 = out.appCpuSTime2; 3455 if (totalTime <= (out.appCpuUTime1+out.appCpuSTime1)) { 3456 out.appCpuUid2 = uid.mUid; 3457 out.appCpuUTime2 = totalUTime; 3458 out.appCpuSTime2 = totalSTime; 3459 } else { 3460 out.appCpuUid2 = out.appCpuUid1; 3461 out.appCpuUTime2 = out.appCpuUTime1; 3462 out.appCpuSTime2 = out.appCpuSTime1; 3463 out.appCpuUid1 = uid.mUid; 3464 out.appCpuUTime1 = totalUTime; 3465 out.appCpuSTime1 = totalSTime; 3466 } 3467 } 3468 } 3469 mLastStepCpuUserTime = mCurStepCpuUserTime; 3470 mLastStepCpuSystemTime = mCurStepCpuSystemTime; 3471 mLastStepStatUserTime = mCurStepStatUserTime; 3472 mLastStepStatSystemTime = mCurStepStatSystemTime; 3473 mLastStepStatIOWaitTime = mCurStepStatIOWaitTime; 3474 mLastStepStatIrqTime = mCurStepStatIrqTime; 3475 mLastStepStatSoftIrqTime = mCurStepStatSoftIrqTime; 3476 mLastStepStatIdleTime = mCurStepStatIdleTime; 3477 } 3478 readHistoryDelta(Parcel src, HistoryItem cur)3479 public void readHistoryDelta(Parcel src, HistoryItem cur) { 3480 int firstToken = src.readInt(); 3481 int deltaTimeToken = firstToken&DELTA_TIME_MASK; 3482 cur.cmd = HistoryItem.CMD_UPDATE; 3483 cur.numReadInts = 1; 3484 if (DEBUG) Slog.i(TAG, "READ DELTA: firstToken=0x" + Integer.toHexString(firstToken) 3485 + " deltaTimeToken=" + deltaTimeToken); 3486 3487 if (deltaTimeToken < DELTA_TIME_ABS) { 3488 cur.time += deltaTimeToken; 3489 } else if (deltaTimeToken == DELTA_TIME_ABS) { 3490 cur.readFromParcel(src); 3491 if (DEBUG) Slog.i(TAG, "READ DELTA: ABS time=" + cur.time); 3492 return; 3493 } else if (deltaTimeToken == DELTA_TIME_INT) { 3494 int delta = src.readInt(); 3495 cur.time += delta; 3496 cur.numReadInts += 1; 3497 if (DEBUG) Slog.i(TAG, "READ DELTA: time delta=" + delta + " new time=" + cur.time); 3498 } else { 3499 long delta = src.readLong(); 3500 if (DEBUG) Slog.i(TAG, "READ DELTA: time delta=" + delta + " new time=" + cur.time); 3501 cur.time += delta; 3502 cur.numReadInts += 2; 3503 } 3504 3505 final int batteryLevelInt; 3506 if ((firstToken&DELTA_BATTERY_LEVEL_FLAG) != 0) { 3507 batteryLevelInt = src.readInt(); 3508 readBatteryLevelInt(batteryLevelInt, cur); 3509 cur.numReadInts += 1; 3510 if (DEBUG) Slog.i(TAG, "READ DELTA: batteryToken=0x" 3511 + Integer.toHexString(batteryLevelInt) 3512 + " batteryLevel=" + cur.batteryLevel 3513 + " batteryTemp=" + cur.batteryTemperature 3514 + " batteryVolt=" + (int)cur.batteryVoltage); 3515 } else { 3516 batteryLevelInt = 0; 3517 } 3518 3519 if ((firstToken&DELTA_STATE_FLAG) != 0) { 3520 int stateInt = src.readInt(); 3521 cur.states = (firstToken&DELTA_STATE_MASK) | (stateInt&(~STATE_BATTERY_MASK)); 3522 cur.batteryStatus = (byte)((stateInt>>STATE_BATTERY_STATUS_SHIFT) 3523 & STATE_BATTERY_STATUS_MASK); 3524 cur.batteryHealth = (byte)((stateInt>>STATE_BATTERY_HEALTH_SHIFT) 3525 & STATE_BATTERY_HEALTH_MASK); 3526 cur.batteryPlugType = (byte)((stateInt>>STATE_BATTERY_PLUG_SHIFT) 3527 & STATE_BATTERY_PLUG_MASK); 3528 switch (cur.batteryPlugType) { 3529 case 1: 3530 cur.batteryPlugType = BatteryManager.BATTERY_PLUGGED_AC; 3531 break; 3532 case 2: 3533 cur.batteryPlugType = BatteryManager.BATTERY_PLUGGED_USB; 3534 break; 3535 case 3: 3536 cur.batteryPlugType = BatteryManager.BATTERY_PLUGGED_WIRELESS; 3537 break; 3538 } 3539 cur.numReadInts += 1; 3540 if (DEBUG) Slog.i(TAG, "READ DELTA: stateToken=0x" 3541 + Integer.toHexString(stateInt) 3542 + " batteryStatus=" + cur.batteryStatus 3543 + " batteryHealth=" + cur.batteryHealth 3544 + " batteryPlugType=" + cur.batteryPlugType 3545 + " states=0x" + Integer.toHexString(cur.states)); 3546 } else { 3547 cur.states = (firstToken&DELTA_STATE_MASK) | (cur.states&(~STATE_BATTERY_MASK)); 3548 } 3549 3550 if ((firstToken&DELTA_STATE2_FLAG) != 0) { 3551 cur.states2 = src.readInt(); 3552 if (DEBUG) Slog.i(TAG, "READ DELTA: states2=0x" 3553 + Integer.toHexString(cur.states2)); 3554 } 3555 3556 if ((firstToken&DELTA_WAKELOCK_FLAG) != 0) { 3557 int indexes = src.readInt(); 3558 int wakeLockIndex = indexes&0xffff; 3559 int wakeReasonIndex = (indexes>>16)&0xffff; 3560 if (wakeLockIndex != 0xffff) { 3561 cur.wakelockTag = cur.localWakelockTag; 3562 readHistoryTag(wakeLockIndex, cur.wakelockTag); 3563 if (DEBUG) Slog.i(TAG, "READ DELTA: wakelockTag=#" + cur.wakelockTag.poolIdx 3564 + " " + cur.wakelockTag.uid + ":" + cur.wakelockTag.string); 3565 } else { 3566 cur.wakelockTag = null; 3567 } 3568 if (wakeReasonIndex != 0xffff) { 3569 cur.wakeReasonTag = cur.localWakeReasonTag; 3570 readHistoryTag(wakeReasonIndex, cur.wakeReasonTag); 3571 if (DEBUG) Slog.i(TAG, "READ DELTA: wakeReasonTag=#" + cur.wakeReasonTag.poolIdx 3572 + " " + cur.wakeReasonTag.uid + ":" + cur.wakeReasonTag.string); 3573 } else { 3574 cur.wakeReasonTag = null; 3575 } 3576 cur.numReadInts += 1; 3577 } else { 3578 cur.wakelockTag = null; 3579 cur.wakeReasonTag = null; 3580 } 3581 3582 if ((firstToken&DELTA_EVENT_FLAG) != 0) { 3583 cur.eventTag = cur.localEventTag; 3584 final int codeAndIndex = src.readInt(); 3585 cur.eventCode = (codeAndIndex&0xffff); 3586 final int index = ((codeAndIndex>>16)&0xffff); 3587 readHistoryTag(index, cur.eventTag); 3588 cur.numReadInts += 1; 3589 if (DEBUG) Slog.i(TAG, "READ DELTA: event=" + cur.eventCode + " tag=#" 3590 + cur.eventTag.poolIdx + " " + cur.eventTag.uid + ":" 3591 + cur.eventTag.string); 3592 } else { 3593 cur.eventCode = HistoryItem.EVENT_NONE; 3594 } 3595 3596 if ((batteryLevelInt&BATTERY_DELTA_LEVEL_FLAG) != 0) { 3597 cur.stepDetails = mReadHistoryStepDetails; 3598 cur.stepDetails.readFromParcel(src); 3599 } else { 3600 cur.stepDetails = null; 3601 } 3602 3603 if ((firstToken&DELTA_BATTERY_CHARGE_FLAG) != 0) { 3604 cur.batteryChargeUAh = src.readInt(); 3605 } 3606 cur.modemRailChargeMah = src.readDouble(); 3607 cur.wifiRailChargeMah = src.readDouble(); 3608 } 3609 3610 @Override commitCurrentHistoryBatchLocked()3611 public void commitCurrentHistoryBatchLocked() { 3612 mHistoryLastWritten.cmd = HistoryItem.CMD_NULL; 3613 } 3614 createFakeHistoryEvents(long numEvents)3615 public void createFakeHistoryEvents(long numEvents) { 3616 for(long i = 0; i < numEvents; i++) { 3617 noteLongPartialWakelockStart("name1", "historyName1", 1000); 3618 noteLongPartialWakelockFinish("name1", "historyName1", 1000); 3619 } 3620 } 3621 addHistoryBufferLocked(long elapsedRealtimeMs, HistoryItem cur)3622 void addHistoryBufferLocked(long elapsedRealtimeMs, HistoryItem cur) { 3623 if (!mHaveBatteryLevel || !mRecordingHistory) { 3624 return; 3625 } 3626 3627 final long timeDiff = (mHistoryBaseTime+elapsedRealtimeMs) - mHistoryLastWritten.time; 3628 final int diffStates = mHistoryLastWritten.states^(cur.states&mActiveHistoryStates); 3629 final int diffStates2 = mHistoryLastWritten.states2^(cur.states2&mActiveHistoryStates2); 3630 final int lastDiffStates = mHistoryLastWritten.states^mHistoryLastLastWritten.states; 3631 final int lastDiffStates2 = mHistoryLastWritten.states2^mHistoryLastLastWritten.states2; 3632 if (DEBUG) Slog.i(TAG, "ADD: tdelta=" + timeDiff + " diff=" 3633 + Integer.toHexString(diffStates) + " lastDiff=" 3634 + Integer.toHexString(lastDiffStates) + " diff2=" 3635 + Integer.toHexString(diffStates2) + " lastDiff2=" 3636 + Integer.toHexString(lastDiffStates2)); 3637 if (mHistoryBufferLastPos >= 0 && mHistoryLastWritten.cmd == HistoryItem.CMD_UPDATE 3638 && timeDiff < 1000 && (diffStates&lastDiffStates) == 0 3639 && (diffStates2&lastDiffStates2) == 0 3640 && (mHistoryLastWritten.wakelockTag == null || cur.wakelockTag == null) 3641 && (mHistoryLastWritten.wakeReasonTag == null || cur.wakeReasonTag == null) 3642 && mHistoryLastWritten.stepDetails == null 3643 && (mHistoryLastWritten.eventCode == HistoryItem.EVENT_NONE 3644 || cur.eventCode == HistoryItem.EVENT_NONE) 3645 && mHistoryLastWritten.batteryLevel == cur.batteryLevel 3646 && mHistoryLastWritten.batteryStatus == cur.batteryStatus 3647 && mHistoryLastWritten.batteryHealth == cur.batteryHealth 3648 && mHistoryLastWritten.batteryPlugType == cur.batteryPlugType 3649 && mHistoryLastWritten.batteryTemperature == cur.batteryTemperature 3650 && mHistoryLastWritten.batteryVoltage == cur.batteryVoltage) { 3651 // We can merge this new change in with the last one. Merging is 3652 // allowed as long as only the states have changed, and within those states 3653 // as long as no bit has changed both between now and the last entry, as 3654 // well as the last entry and the one before it (so we capture any toggles). 3655 if (DEBUG) Slog.i(TAG, "ADD: rewinding back to " + mHistoryBufferLastPos); 3656 mHistoryBuffer.setDataSize(mHistoryBufferLastPos); 3657 mHistoryBuffer.setDataPosition(mHistoryBufferLastPos); 3658 mHistoryBufferLastPos = -1; 3659 elapsedRealtimeMs = mHistoryLastWritten.time - mHistoryBaseTime; 3660 // If the last written history had a wakelock tag, we need to retain it. 3661 // Note that the condition above made sure that we aren't in a case where 3662 // both it and the current history item have a wakelock tag. 3663 if (mHistoryLastWritten.wakelockTag != null) { 3664 cur.wakelockTag = cur.localWakelockTag; 3665 cur.wakelockTag.setTo(mHistoryLastWritten.wakelockTag); 3666 } 3667 // If the last written history had a wake reason tag, we need to retain it. 3668 // Note that the condition above made sure that we aren't in a case where 3669 // both it and the current history item have a wakelock tag. 3670 if (mHistoryLastWritten.wakeReasonTag != null) { 3671 cur.wakeReasonTag = cur.localWakeReasonTag; 3672 cur.wakeReasonTag.setTo(mHistoryLastWritten.wakeReasonTag); 3673 } 3674 // If the last written history had an event, we need to retain it. 3675 // Note that the condition above made sure that we aren't in a case where 3676 // both it and the current history item have an event. 3677 if (mHistoryLastWritten.eventCode != HistoryItem.EVENT_NONE) { 3678 cur.eventCode = mHistoryLastWritten.eventCode; 3679 cur.eventTag = cur.localEventTag; 3680 cur.eventTag.setTo(mHistoryLastWritten.eventTag); 3681 } 3682 mHistoryLastWritten.setTo(mHistoryLastLastWritten); 3683 } 3684 final int dataSize = mHistoryBuffer.dataSize(); 3685 3686 if (dataSize >= mConstants.MAX_HISTORY_BUFFER) { 3687 //open a new history file. 3688 final long start = SystemClock.uptimeMillis(); 3689 writeHistoryLocked(true); 3690 if (DEBUG) { 3691 Slog.d(TAG, "addHistoryBufferLocked writeHistoryLocked takes ms:" 3692 + (SystemClock.uptimeMillis() - start)); 3693 } 3694 mBatteryStatsHistory.startNextFile(); 3695 mHistoryBuffer.setDataSize(0); 3696 mHistoryBuffer.setDataPosition(0); 3697 mHistoryBuffer.setDataCapacity(mConstants.MAX_HISTORY_BUFFER / 2); 3698 mHistoryBufferLastPos = -1; 3699 final long elapsedRealtime = mClocks.elapsedRealtime(); 3700 final long uptime = mClocks.uptimeMillis(); 3701 HistoryItem newItem = new HistoryItem(); 3702 newItem.setTo(cur); 3703 startRecordingHistory(elapsedRealtime, uptime, false); 3704 addHistoryBufferLocked(elapsedRealtimeMs, HistoryItem.CMD_UPDATE, newItem); 3705 return; 3706 } 3707 3708 if (dataSize == 0) { 3709 // The history is currently empty; we need it to start with a time stamp. 3710 cur.currentTime = System.currentTimeMillis(); 3711 addHistoryBufferLocked(elapsedRealtimeMs, HistoryItem.CMD_RESET, cur); 3712 } 3713 addHistoryBufferLocked(elapsedRealtimeMs, HistoryItem.CMD_UPDATE, cur); 3714 } 3715 addHistoryBufferLocked(long elapsedRealtimeMs, byte cmd, HistoryItem cur)3716 private void addHistoryBufferLocked(long elapsedRealtimeMs, byte cmd, HistoryItem cur) { 3717 if (mIteratingHistory) { 3718 throw new IllegalStateException("Can't do this while iterating history!"); 3719 } 3720 mHistoryBufferLastPos = mHistoryBuffer.dataPosition(); 3721 mHistoryLastLastWritten.setTo(mHistoryLastWritten); 3722 mHistoryLastWritten.setTo(mHistoryBaseTime + elapsedRealtimeMs, cmd, cur); 3723 mHistoryLastWritten.states &= mActiveHistoryStates; 3724 mHistoryLastWritten.states2 &= mActiveHistoryStates2; 3725 writeHistoryDelta(mHistoryBuffer, mHistoryLastWritten, mHistoryLastLastWritten); 3726 mLastHistoryElapsedRealtime = elapsedRealtimeMs; 3727 cur.wakelockTag = null; 3728 cur.wakeReasonTag = null; 3729 cur.eventCode = HistoryItem.EVENT_NONE; 3730 cur.eventTag = null; 3731 if (DEBUG_HISTORY) Slog.i(TAG, "Writing history buffer: was " + mHistoryBufferLastPos 3732 + " now " + mHistoryBuffer.dataPosition() 3733 + " size is now " + mHistoryBuffer.dataSize()); 3734 } 3735 3736 int mChangedStates = 0; 3737 int mChangedStates2 = 0; 3738 addHistoryRecordLocked(long elapsedRealtimeMs, long uptimeMs)3739 void addHistoryRecordLocked(long elapsedRealtimeMs, long uptimeMs) { 3740 if (mTrackRunningHistoryElapsedRealtime != 0) { 3741 final long diffElapsed = elapsedRealtimeMs - mTrackRunningHistoryElapsedRealtime; 3742 final long diffUptime = uptimeMs - mTrackRunningHistoryUptime; 3743 if (diffUptime < (diffElapsed-20)) { 3744 final long wakeElapsedTime = elapsedRealtimeMs - (diffElapsed - diffUptime); 3745 mHistoryAddTmp.setTo(mHistoryLastWritten); 3746 mHistoryAddTmp.wakelockTag = null; 3747 mHistoryAddTmp.wakeReasonTag = null; 3748 mHistoryAddTmp.eventCode = HistoryItem.EVENT_NONE; 3749 mHistoryAddTmp.states &= ~HistoryItem.STATE_CPU_RUNNING_FLAG; 3750 addHistoryRecordInnerLocked(wakeElapsedTime, mHistoryAddTmp); 3751 } 3752 } 3753 mHistoryCur.states |= HistoryItem.STATE_CPU_RUNNING_FLAG; 3754 mTrackRunningHistoryElapsedRealtime = elapsedRealtimeMs; 3755 mTrackRunningHistoryUptime = uptimeMs; 3756 addHistoryRecordInnerLocked(elapsedRealtimeMs, mHistoryCur); 3757 } 3758 addHistoryRecordInnerLocked(long elapsedRealtimeMs, HistoryItem cur)3759 void addHistoryRecordInnerLocked(long elapsedRealtimeMs, HistoryItem cur) { 3760 addHistoryBufferLocked(elapsedRealtimeMs, cur); 3761 3762 if (!USE_OLD_HISTORY) { 3763 return; 3764 } 3765 3766 if (!mHaveBatteryLevel || !mRecordingHistory) { 3767 return; 3768 } 3769 3770 // If the current time is basically the same as the last time, 3771 // and no states have since the last recorded entry changed and 3772 // are now resetting back to their original value, then just collapse 3773 // into one record. 3774 if (mHistoryEnd != null && mHistoryEnd.cmd == HistoryItem.CMD_UPDATE 3775 && (mHistoryBaseTime+elapsedRealtimeMs) < (mHistoryEnd.time+1000) 3776 && ((mHistoryEnd.states^cur.states)&mChangedStates&mActiveHistoryStates) == 0 3777 && ((mHistoryEnd.states2^cur.states2)&mChangedStates2&mActiveHistoryStates2) == 0) { 3778 // If the current is the same as the one before, then we no 3779 // longer need the entry. 3780 if (mHistoryLastEnd != null && mHistoryLastEnd.cmd == HistoryItem.CMD_UPDATE 3781 && (mHistoryBaseTime+elapsedRealtimeMs) < (mHistoryEnd.time+500) 3782 && mHistoryLastEnd.sameNonEvent(cur)) { 3783 mHistoryLastEnd.next = null; 3784 mHistoryEnd.next = mHistoryCache; 3785 mHistoryCache = mHistoryEnd; 3786 mHistoryEnd = mHistoryLastEnd; 3787 mHistoryLastEnd = null; 3788 } else { 3789 mChangedStates |= mHistoryEnd.states^(cur.states&mActiveHistoryStates); 3790 mChangedStates2 |= mHistoryEnd.states^(cur.states2&mActiveHistoryStates2); 3791 mHistoryEnd.setTo(mHistoryEnd.time, HistoryItem.CMD_UPDATE, cur); 3792 } 3793 return; 3794 } 3795 3796 mChangedStates = 0; 3797 mChangedStates2 = 0; 3798 addHistoryBufferLocked(elapsedRealtimeMs, HistoryItem.CMD_UPDATE, cur); 3799 } 3800 addHistoryEventLocked(long elapsedRealtimeMs, long uptimeMs, int code, String name, int uid)3801 public void addHistoryEventLocked(long elapsedRealtimeMs, long uptimeMs, int code, 3802 String name, int uid) { 3803 mHistoryCur.eventCode = code; 3804 mHistoryCur.eventTag = mHistoryCur.localEventTag; 3805 mHistoryCur.eventTag.string = name; 3806 mHistoryCur.eventTag.uid = uid; 3807 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 3808 } 3809 addHistoryRecordLocked(long elapsedRealtimeMs, long uptimeMs, byte cmd, HistoryItem cur)3810 void addHistoryRecordLocked(long elapsedRealtimeMs, long uptimeMs, byte cmd, HistoryItem cur) { 3811 HistoryItem rec = mHistoryCache; 3812 if (rec != null) { 3813 mHistoryCache = rec.next; 3814 } else { 3815 rec = new HistoryItem(); 3816 } 3817 rec.setTo(mHistoryBaseTime + elapsedRealtimeMs, cmd, cur); 3818 3819 addHistoryRecordLocked(rec); 3820 } 3821 addHistoryRecordLocked(HistoryItem rec)3822 void addHistoryRecordLocked(HistoryItem rec) { 3823 mNumHistoryItems++; 3824 rec.next = null; 3825 mHistoryLastEnd = mHistoryEnd; 3826 if (mHistoryEnd != null) { 3827 mHistoryEnd.next = rec; 3828 mHistoryEnd = rec; 3829 } else { 3830 mHistory = mHistoryEnd = rec; 3831 } 3832 } 3833 clearHistoryLocked()3834 void clearHistoryLocked() { 3835 if (DEBUG_HISTORY) Slog.i(TAG, "********** CLEARING HISTORY!"); 3836 if (USE_OLD_HISTORY) { 3837 if (mHistory != null) { 3838 mHistoryEnd.next = mHistoryCache; 3839 mHistoryCache = mHistory; 3840 mHistory = mHistoryLastEnd = mHistoryEnd = null; 3841 } 3842 mNumHistoryItems = 0; 3843 } 3844 3845 mHistoryBaseTime = 0; 3846 mLastHistoryElapsedRealtime = 0; 3847 mTrackRunningHistoryElapsedRealtime = 0; 3848 mTrackRunningHistoryUptime = 0; 3849 3850 mHistoryBuffer.setDataSize(0); 3851 mHistoryBuffer.setDataPosition(0); 3852 mHistoryBuffer.setDataCapacity(mConstants.MAX_HISTORY_BUFFER / 2); 3853 mHistoryLastLastWritten.clear(); 3854 mHistoryLastWritten.clear(); 3855 mHistoryTagPool.clear(); 3856 mNextHistoryTagIdx = 0; 3857 mNumHistoryTagChars = 0; 3858 mHistoryBufferLastPos = -1; 3859 mActiveHistoryStates = 0xffffffff; 3860 mActiveHistoryStates2 = 0xffffffff; 3861 } 3862 3863 @GuardedBy("this") updateTimeBasesLocked(boolean unplugged, int screenState, long uptime, long realtime)3864 public void updateTimeBasesLocked(boolean unplugged, int screenState, long uptime, 3865 long realtime) { 3866 final boolean screenOff = !isScreenOn(screenState); 3867 final boolean updateOnBatteryTimeBase = unplugged != mOnBatteryTimeBase.isRunning(); 3868 final boolean updateOnBatteryScreenOffTimeBase = 3869 (unplugged && screenOff) != mOnBatteryScreenOffTimeBase.isRunning(); 3870 3871 if (updateOnBatteryScreenOffTimeBase || updateOnBatteryTimeBase) { 3872 if (updateOnBatteryScreenOffTimeBase) { 3873 updateKernelWakelocksLocked(); 3874 updateBatteryPropertiesLocked(); 3875 } 3876 // This if{} is only necessary due to SCREEN_OFF_RPM_STATS_ENABLED, which exists because 3877 // updateRpmStatsLocked is too slow to run each screen change. When the speed is 3878 // improved, remove the surrounding if{}. 3879 if (SCREEN_OFF_RPM_STATS_ENABLED || updateOnBatteryTimeBase) { 3880 updateRpmStatsLocked(); // if either OnBattery or OnBatteryScreenOff timebase changes. 3881 } 3882 if (DEBUG_ENERGY_CPU) { 3883 Slog.d(TAG, "Updating cpu time because screen is now " 3884 + Display.stateToString(screenState) 3885 + " and battery is " + (unplugged ? "on" : "off")); 3886 } 3887 3888 mOnBatteryTimeBase.setRunning(unplugged, uptime, realtime); 3889 if (updateOnBatteryTimeBase) { 3890 for (int i = mUidStats.size() - 1; i >= 0; --i) { 3891 mUidStats.valueAt(i).updateOnBatteryBgTimeBase(uptime, realtime); 3892 } 3893 } 3894 if (updateOnBatteryScreenOffTimeBase) { 3895 mOnBatteryScreenOffTimeBase.setRunning(unplugged && screenOff, uptime, realtime); 3896 for (int i = mUidStats.size() - 1; i >= 0; --i) { 3897 mUidStats.valueAt(i).updateOnBatteryScreenOffBgTimeBase(uptime, realtime); 3898 } 3899 } 3900 } 3901 } 3902 updateBatteryPropertiesLocked()3903 private void updateBatteryPropertiesLocked() { 3904 try { 3905 IBatteryPropertiesRegistrar registrar = IBatteryPropertiesRegistrar.Stub.asInterface( 3906 ServiceManager.getService("batteryproperties")); 3907 if (registrar != null) { 3908 registrar.scheduleUpdate(); 3909 } 3910 } catch (RemoteException e) { 3911 // Ignore. 3912 } 3913 } 3914 addIsolatedUidLocked(int isolatedUid, int appUid)3915 public void addIsolatedUidLocked(int isolatedUid, int appUid) { 3916 mIsolatedUids.put(isolatedUid, appUid); 3917 final Uid u = getUidStatsLocked(appUid); 3918 u.addIsolatedUid(isolatedUid); 3919 } 3920 3921 /** 3922 * Schedules a read of the latest cpu times before removing the isolated UID. 3923 * @see #removeIsolatedUidLocked(int) 3924 */ scheduleRemoveIsolatedUidLocked(int isolatedUid, int appUid)3925 public void scheduleRemoveIsolatedUidLocked(int isolatedUid, int appUid) { 3926 int curUid = mIsolatedUids.get(isolatedUid, -1); 3927 if (curUid == appUid) { 3928 if (mExternalSync != null) { 3929 mExternalSync.scheduleCpuSyncDueToRemovedUid(isolatedUid); 3930 } 3931 } 3932 } 3933 3934 /** 3935 * This should only be called after the cpu times have been read. 3936 * @see #scheduleRemoveIsolatedUidLocked(int, int) 3937 */ 3938 @GuardedBy("this") removeIsolatedUidLocked(int isolatedUid)3939 public void removeIsolatedUidLocked(int isolatedUid) { 3940 final int idx = mIsolatedUids.indexOfKey(isolatedUid); 3941 if (idx >= 0) { 3942 final int ownerUid = mIsolatedUids.valueAt(idx); 3943 final Uid u = getUidStatsLocked(ownerUid); 3944 u.removeIsolatedUid(isolatedUid); 3945 mIsolatedUids.removeAt(idx); 3946 } 3947 mPendingRemovedUids.add(new UidToRemove(isolatedUid, mClocks.elapsedRealtime())); 3948 } 3949 mapUid(int uid)3950 public int mapUid(int uid) { 3951 int isolated = mIsolatedUids.get(uid, -1); 3952 return isolated > 0 ? isolated : uid; 3953 } 3954 noteEventLocked(int code, String name, int uid)3955 public void noteEventLocked(int code, String name, int uid) { 3956 uid = mapUid(uid); 3957 if (!mActiveEvents.updateState(code, name, uid, 0)) { 3958 return; 3959 } 3960 final long elapsedRealtime = mClocks.elapsedRealtime(); 3961 final long uptime = mClocks.uptimeMillis(); 3962 addHistoryEventLocked(elapsedRealtime, uptime, code, name, uid); 3963 } 3964 noteCurrentTimeChangedLocked()3965 public void noteCurrentTimeChangedLocked() { 3966 final long currentTime = System.currentTimeMillis(); 3967 final long elapsedRealtime = mClocks.elapsedRealtime(); 3968 final long uptime = mClocks.uptimeMillis(); 3969 recordCurrentTimeChangeLocked(currentTime, elapsedRealtime, uptime); 3970 } 3971 noteProcessStartLocked(String name, int uid)3972 public void noteProcessStartLocked(String name, int uid) { 3973 uid = mapUid(uid); 3974 if (isOnBattery()) { 3975 Uid u = getUidStatsLocked(uid); 3976 u.getProcessStatsLocked(name).incStartsLocked(); 3977 } 3978 if (!mActiveEvents.updateState(HistoryItem.EVENT_PROC_START, name, uid, 0)) { 3979 return; 3980 } 3981 if (!mRecordAllHistory) { 3982 return; 3983 } 3984 final long elapsedRealtime = mClocks.elapsedRealtime(); 3985 final long uptime = mClocks.uptimeMillis(); 3986 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_PROC_START, name, uid); 3987 } 3988 noteProcessCrashLocked(String name, int uid)3989 public void noteProcessCrashLocked(String name, int uid) { 3990 uid = mapUid(uid); 3991 if (isOnBattery()) { 3992 Uid u = getUidStatsLocked(uid); 3993 u.getProcessStatsLocked(name).incNumCrashesLocked(); 3994 } 3995 } 3996 noteProcessAnrLocked(String name, int uid)3997 public void noteProcessAnrLocked(String name, int uid) { 3998 uid = mapUid(uid); 3999 if (isOnBattery()) { 4000 Uid u = getUidStatsLocked(uid); 4001 u.getProcessStatsLocked(name).incNumAnrsLocked(); 4002 } 4003 } 4004 noteUidProcessStateLocked(int uid, int state)4005 public void noteUidProcessStateLocked(int uid, int state) { 4006 int parentUid = mapUid(uid); 4007 if (uid != parentUid) { 4008 // Isolated UIDs process state is already rolled up into parent, so no need to track 4009 // Otherwise the parent's process state will get downgraded incorrectly 4010 return; 4011 } 4012 // TODO(b/155216561): It is possible for isolated uids to be in a higher 4013 // state than its parent uid. We should track the highest state within the union of host 4014 // and isolated uids rather than only the parent uid. 4015 FrameworkStatsLog.write(FrameworkStatsLog.UID_PROCESS_STATE_CHANGED, uid, 4016 ActivityManager.processStateAmToProto(state)); 4017 getUidStatsLocked(uid).updateUidProcessStateLocked(state); 4018 } 4019 noteProcessFinishLocked(String name, int uid)4020 public void noteProcessFinishLocked(String name, int uid) { 4021 uid = mapUid(uid); 4022 if (!mActiveEvents.updateState(HistoryItem.EVENT_PROC_FINISH, name, uid, 0)) { 4023 return; 4024 } 4025 if (!mRecordAllHistory) { 4026 return; 4027 } 4028 final long elapsedRealtime = mClocks.elapsedRealtime(); 4029 final long uptime = mClocks.uptimeMillis(); 4030 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_PROC_FINISH, name, uid); 4031 } 4032 noteSyncStartLocked(String name, int uid)4033 public void noteSyncStartLocked(String name, int uid) { 4034 uid = mapUid(uid); 4035 final long elapsedRealtime = mClocks.elapsedRealtime(); 4036 final long uptime = mClocks.uptimeMillis(); 4037 getUidStatsLocked(uid).noteStartSyncLocked(name, elapsedRealtime); 4038 if (!mActiveEvents.updateState(HistoryItem.EVENT_SYNC_START, name, uid, 0)) { 4039 return; 4040 } 4041 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_SYNC_START, name, uid); 4042 } 4043 noteSyncFinishLocked(String name, int uid)4044 public void noteSyncFinishLocked(String name, int uid) { 4045 uid = mapUid(uid); 4046 final long elapsedRealtime = mClocks.elapsedRealtime(); 4047 final long uptime = mClocks.uptimeMillis(); 4048 getUidStatsLocked(uid).noteStopSyncLocked(name, elapsedRealtime); 4049 if (!mActiveEvents.updateState(HistoryItem.EVENT_SYNC_FINISH, name, uid, 0)) { 4050 return; 4051 } 4052 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_SYNC_FINISH, name, uid); 4053 } 4054 noteJobStartLocked(String name, int uid)4055 public void noteJobStartLocked(String name, int uid) { 4056 uid = mapUid(uid); 4057 final long elapsedRealtime = mClocks.elapsedRealtime(); 4058 final long uptime = mClocks.uptimeMillis(); 4059 getUidStatsLocked(uid).noteStartJobLocked(name, elapsedRealtime); 4060 if (!mActiveEvents.updateState(HistoryItem.EVENT_JOB_START, name, uid, 0)) { 4061 return; 4062 } 4063 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_JOB_START, name, uid); 4064 } 4065 noteJobFinishLocked(String name, int uid, int stopReason)4066 public void noteJobFinishLocked(String name, int uid, int stopReason) { 4067 uid = mapUid(uid); 4068 final long elapsedRealtime = mClocks.elapsedRealtime(); 4069 final long uptime = mClocks.uptimeMillis(); 4070 getUidStatsLocked(uid).noteStopJobLocked(name, elapsedRealtime, stopReason); 4071 if (!mActiveEvents.updateState(HistoryItem.EVENT_JOB_FINISH, name, uid, 0)) { 4072 return; 4073 } 4074 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_JOB_FINISH, name, uid); 4075 } 4076 noteJobsDeferredLocked(int uid, int numDeferred, long sinceLast)4077 public void noteJobsDeferredLocked(int uid, int numDeferred, long sinceLast) { 4078 uid = mapUid(uid); 4079 getUidStatsLocked(uid).noteJobsDeferredLocked(numDeferred, sinceLast); 4080 } 4081 noteAlarmStartLocked(String name, WorkSource workSource, int uid)4082 public void noteAlarmStartLocked(String name, WorkSource workSource, int uid) { 4083 noteAlarmStartOrFinishLocked(HistoryItem.EVENT_ALARM_START, name, workSource, uid); 4084 } 4085 noteAlarmFinishLocked(String name, WorkSource workSource, int uid)4086 public void noteAlarmFinishLocked(String name, WorkSource workSource, int uid) { 4087 noteAlarmStartOrFinishLocked(HistoryItem.EVENT_ALARM_FINISH, name, workSource, uid); 4088 } 4089 noteAlarmStartOrFinishLocked(int historyItem, String name, WorkSource workSource, int uid)4090 private void noteAlarmStartOrFinishLocked(int historyItem, String name, WorkSource workSource, 4091 int uid) { 4092 if (!mRecordAllHistory) { 4093 return; 4094 } 4095 4096 final long elapsedRealtime = mClocks.elapsedRealtime(); 4097 final long uptime = mClocks.uptimeMillis(); 4098 4099 if (workSource != null) { 4100 for (int i = 0; i < workSource.size(); ++i) { 4101 uid = mapUid(workSource.getUid(i)); 4102 if (mActiveEvents.updateState(historyItem, name, uid, 0)) { 4103 addHistoryEventLocked(elapsedRealtime, uptime, historyItem, name, uid); 4104 } 4105 } 4106 4107 List<WorkChain> workChains = workSource.getWorkChains(); 4108 if (workChains != null) { 4109 for (int i = 0; i < workChains.size(); ++i) { 4110 uid = mapUid(workChains.get(i).getAttributionUid()); 4111 if (mActiveEvents.updateState(historyItem, name, uid, 0)) { 4112 addHistoryEventLocked(elapsedRealtime, uptime, historyItem, name, uid); 4113 } 4114 } 4115 } 4116 } else { 4117 uid = mapUid(uid); 4118 4119 if (mActiveEvents.updateState(historyItem, name, uid, 0)) { 4120 addHistoryEventLocked(elapsedRealtime, uptime, historyItem, name, uid); 4121 } 4122 } 4123 } 4124 noteWakupAlarmLocked(String packageName, int uid, WorkSource workSource, String tag)4125 public void noteWakupAlarmLocked(String packageName, int uid, WorkSource workSource, 4126 String tag) { 4127 if (workSource != null) { 4128 for (int i = 0; i < workSource.size(); ++i) { 4129 uid = workSource.getUid(i); 4130 final String workSourceName = workSource.getPackageName(i); 4131 4132 if (isOnBattery()) { 4133 BatteryStatsImpl.Uid.Pkg pkg = getPackageStatsLocked(uid, 4134 workSourceName != null ? workSourceName : packageName); 4135 pkg.noteWakeupAlarmLocked(tag); 4136 } 4137 } 4138 4139 List<WorkChain> workChains = workSource.getWorkChains(); 4140 if (workChains != null) { 4141 for (int i = 0; i < workChains.size(); ++i) { 4142 final WorkChain wc = workChains.get(i); 4143 uid = wc.getAttributionUid(); 4144 4145 if (isOnBattery()) { 4146 BatteryStatsImpl.Uid.Pkg pkg = getPackageStatsLocked(uid, packageName); 4147 pkg.noteWakeupAlarmLocked(tag); 4148 } 4149 } 4150 } 4151 } else { 4152 if (isOnBattery()) { 4153 BatteryStatsImpl.Uid.Pkg pkg = getPackageStatsLocked(uid, packageName); 4154 pkg.noteWakeupAlarmLocked(tag); 4155 } 4156 } 4157 } 4158 requestWakelockCpuUpdate()4159 private void requestWakelockCpuUpdate() { 4160 mExternalSync.scheduleCpuSyncDueToWakelockChange(DELAY_UPDATE_WAKELOCKS); 4161 } 4162 requestImmediateCpuUpdate()4163 private void requestImmediateCpuUpdate() { 4164 mExternalSync.scheduleCpuSyncDueToWakelockChange(0 /* delayMillis */); 4165 } 4166 setRecordAllHistoryLocked(boolean enabled)4167 public void setRecordAllHistoryLocked(boolean enabled) { 4168 mRecordAllHistory = enabled; 4169 if (!enabled) { 4170 // Clear out any existing state. 4171 mActiveEvents.removeEvents(HistoryItem.EVENT_WAKE_LOCK); 4172 mActiveEvents.removeEvents(HistoryItem.EVENT_ALARM); 4173 // Record the currently running processes as stopping, now that we are no 4174 // longer tracking them. 4175 HashMap<String, SparseIntArray> active = mActiveEvents.getStateForEvent( 4176 HistoryItem.EVENT_PROC); 4177 if (active != null) { 4178 long mSecRealtime = mClocks.elapsedRealtime(); 4179 final long mSecUptime = mClocks.uptimeMillis(); 4180 for (HashMap.Entry<String, SparseIntArray> ent : active.entrySet()) { 4181 SparseIntArray uids = ent.getValue(); 4182 for (int j=0; j<uids.size(); j++) { 4183 addHistoryEventLocked(mSecRealtime, mSecUptime, 4184 HistoryItem.EVENT_PROC_FINISH, ent.getKey(), uids.keyAt(j)); 4185 } 4186 } 4187 } 4188 } else { 4189 // Record the currently running processes as starting, now that we are tracking them. 4190 HashMap<String, SparseIntArray> active = mActiveEvents.getStateForEvent( 4191 HistoryItem.EVENT_PROC); 4192 if (active != null) { 4193 long mSecRealtime = mClocks.elapsedRealtime(); 4194 final long mSecUptime = mClocks.uptimeMillis(); 4195 for (HashMap.Entry<String, SparseIntArray> ent : active.entrySet()) { 4196 SparseIntArray uids = ent.getValue(); 4197 for (int j=0; j<uids.size(); j++) { 4198 addHistoryEventLocked(mSecRealtime, mSecUptime, 4199 HistoryItem.EVENT_PROC_START, ent.getKey(), uids.keyAt(j)); 4200 } 4201 } 4202 } 4203 } 4204 } 4205 setNoAutoReset(boolean enabled)4206 public void setNoAutoReset(boolean enabled) { 4207 mNoAutoReset = enabled; 4208 } 4209 setPretendScreenOff(boolean pretendScreenOff)4210 public void setPretendScreenOff(boolean pretendScreenOff) { 4211 if (mPretendScreenOff != pretendScreenOff) { 4212 mPretendScreenOff = pretendScreenOff; 4213 noteScreenStateLocked(pretendScreenOff ? Display.STATE_OFF : Display.STATE_ON); 4214 } 4215 } 4216 4217 private String mInitialAcquireWakeName; 4218 private int mInitialAcquireWakeUid = -1; 4219 noteStartWakeLocked(int uid, int pid, WorkChain wc, String name, String historyName, int type, boolean unimportantForLogging, long elapsedRealtime, long uptime)4220 public void noteStartWakeLocked(int uid, int pid, WorkChain wc, String name, String historyName, 4221 int type, boolean unimportantForLogging, long elapsedRealtime, long uptime) { 4222 uid = mapUid(uid); 4223 if (type == WAKE_TYPE_PARTIAL) { 4224 // Only care about partial wake locks, since full wake locks 4225 // will be canceled when the user puts the screen to sleep. 4226 aggregateLastWakeupUptimeLocked(uptime); 4227 if (historyName == null) { 4228 historyName = name; 4229 } 4230 if (mRecordAllHistory) { 4231 if (mActiveEvents.updateState(HistoryItem.EVENT_WAKE_LOCK_START, historyName, 4232 uid, 0)) { 4233 addHistoryEventLocked(elapsedRealtime, uptime, 4234 HistoryItem.EVENT_WAKE_LOCK_START, historyName, uid); 4235 } 4236 } 4237 if (mWakeLockNesting == 0) { 4238 mHistoryCur.states |= HistoryItem.STATE_WAKE_LOCK_FLAG; 4239 if (DEBUG_HISTORY) Slog.v(TAG, "Start wake lock to: " 4240 + Integer.toHexString(mHistoryCur.states)); 4241 mHistoryCur.wakelockTag = mHistoryCur.localWakelockTag; 4242 mHistoryCur.wakelockTag.string = mInitialAcquireWakeName = historyName; 4243 mHistoryCur.wakelockTag.uid = mInitialAcquireWakeUid = uid; 4244 mWakeLockImportant = !unimportantForLogging; 4245 addHistoryRecordLocked(elapsedRealtime, uptime); 4246 } else if (!mWakeLockImportant && !unimportantForLogging 4247 && mHistoryLastWritten.cmd == HistoryItem.CMD_UPDATE) { 4248 if (mHistoryLastWritten.wakelockTag != null) { 4249 // We'll try to update the last tag. 4250 mHistoryLastWritten.wakelockTag = null; 4251 mHistoryCur.wakelockTag = mHistoryCur.localWakelockTag; 4252 mHistoryCur.wakelockTag.string = mInitialAcquireWakeName = historyName; 4253 mHistoryCur.wakelockTag.uid = mInitialAcquireWakeUid = uid; 4254 addHistoryRecordLocked(elapsedRealtime, uptime); 4255 } 4256 mWakeLockImportant = true; 4257 } 4258 mWakeLockNesting++; 4259 } 4260 if (uid >= 0) { 4261 if (mOnBatteryScreenOffTimeBase.isRunning()) { 4262 // We only update the cpu time when a wake lock is acquired if the screen is off. 4263 // If the screen is on, we don't distribute the power amongst partial wakelocks. 4264 if (DEBUG_ENERGY_CPU) { 4265 Slog.d(TAG, "Updating cpu time because of +wake_lock"); 4266 } 4267 requestWakelockCpuUpdate(); 4268 } 4269 4270 getUidStatsLocked(uid).noteStartWakeLocked(pid, name, type, elapsedRealtime); 4271 4272 if (wc != null) { 4273 FrameworkStatsLog.write(FrameworkStatsLog.WAKELOCK_STATE_CHANGED, wc.getUids(), 4274 wc.getTags(), getPowerManagerWakeLockLevel(type), name, 4275 FrameworkStatsLog.WAKELOCK_STATE_CHANGED__STATE__ACQUIRE); 4276 } else { 4277 FrameworkStatsLog.write_non_chained(FrameworkStatsLog.WAKELOCK_STATE_CHANGED, uid, 4278 null, getPowerManagerWakeLockLevel(type), name, 4279 FrameworkStatsLog.WAKELOCK_STATE_CHANGED__STATE__ACQUIRE); 4280 } 4281 } 4282 } 4283 noteStopWakeLocked(int uid, int pid, WorkChain wc, String name, String historyName, int type, long elapsedRealtime, long uptime)4284 public void noteStopWakeLocked(int uid, int pid, WorkChain wc, String name, String historyName, 4285 int type, long elapsedRealtime, long uptime) { 4286 uid = mapUid(uid); 4287 if (type == WAKE_TYPE_PARTIAL) { 4288 mWakeLockNesting--; 4289 if (mRecordAllHistory) { 4290 if (historyName == null) { 4291 historyName = name; 4292 } 4293 if (mActiveEvents.updateState(HistoryItem.EVENT_WAKE_LOCK_FINISH, historyName, 4294 uid, 0)) { 4295 addHistoryEventLocked(elapsedRealtime, uptime, 4296 HistoryItem.EVENT_WAKE_LOCK_FINISH, historyName, uid); 4297 } 4298 } 4299 if (mWakeLockNesting == 0) { 4300 mHistoryCur.states &= ~HistoryItem.STATE_WAKE_LOCK_FLAG; 4301 if (DEBUG_HISTORY) Slog.v(TAG, "Stop wake lock to: " 4302 + Integer.toHexString(mHistoryCur.states)); 4303 mInitialAcquireWakeName = null; 4304 mInitialAcquireWakeUid = -1; 4305 addHistoryRecordLocked(elapsedRealtime, uptime); 4306 } 4307 } 4308 if (uid >= 0) { 4309 if (mOnBatteryScreenOffTimeBase.isRunning()) { 4310 if (DEBUG_ENERGY_CPU) { 4311 Slog.d(TAG, "Updating cpu time because of -wake_lock"); 4312 } 4313 requestWakelockCpuUpdate(); 4314 } 4315 4316 getUidStatsLocked(uid).noteStopWakeLocked(pid, name, type, elapsedRealtime); 4317 if (wc != null) { 4318 FrameworkStatsLog.write(FrameworkStatsLog.WAKELOCK_STATE_CHANGED, wc.getUids(), 4319 wc.getTags(), getPowerManagerWakeLockLevel(type), name, 4320 FrameworkStatsLog.WAKELOCK_STATE_CHANGED__STATE__RELEASE); 4321 } else { 4322 FrameworkStatsLog.write_non_chained(FrameworkStatsLog.WAKELOCK_STATE_CHANGED, uid, 4323 null, getPowerManagerWakeLockLevel(type), name, 4324 FrameworkStatsLog.WAKELOCK_STATE_CHANGED__STATE__RELEASE); 4325 } 4326 } 4327 } 4328 4329 /** 4330 * Converts BatteryStats wakelock types back into PowerManager wakelock levels. 4331 * This is the inverse map of Notifier.getBatteryStatsWakeLockMonitorType(). 4332 * These are estimations, since batterystats loses some of the original data. 4333 * TODO: Delete this. Instead, FrameworkStatsLog.write should be called from 4334 * PowerManager's Notifier. 4335 */ getPowerManagerWakeLockLevel(int battertStatsWakelockType)4336 private int getPowerManagerWakeLockLevel(int battertStatsWakelockType) { 4337 switch (battertStatsWakelockType) { 4338 // PowerManager.PARTIAL_WAKE_LOCK or PROXIMITY_SCREEN_OFF_WAKE_LOCK 4339 case BatteryStats.WAKE_TYPE_PARTIAL: 4340 return PowerManager.PARTIAL_WAKE_LOCK; 4341 4342 // PowerManager.SCREEN_DIM_WAKE_LOCK or SCREEN_BRIGHT_WAKE_LOCK 4343 case BatteryStats.WAKE_TYPE_FULL: 4344 return PowerManager.FULL_WAKE_LOCK; 4345 4346 case BatteryStats.WAKE_TYPE_DRAW: 4347 return PowerManager.DRAW_WAKE_LOCK; 4348 4349 // It appears that nothing can ever make a Window and PowerManager lacks an equivalent. 4350 case BatteryStats.WAKE_TYPE_WINDOW: 4351 Slog.e(TAG, "Illegal window wakelock type observed in batterystats."); 4352 return -1; 4353 4354 default: 4355 Slog.e(TAG, "Illegal wakelock type in batterystats: " + battertStatsWakelockType); 4356 return -1; 4357 } 4358 } 4359 noteStartWakeFromSourceLocked(WorkSource ws, int pid, String name, String historyName, int type, boolean unimportantForLogging)4360 public void noteStartWakeFromSourceLocked(WorkSource ws, int pid, String name, 4361 String historyName, int type, boolean unimportantForLogging) { 4362 final long elapsedRealtime = mClocks.elapsedRealtime(); 4363 final long uptime = mClocks.uptimeMillis(); 4364 final int N = ws.size(); 4365 for (int i=0; i<N; i++) { 4366 noteStartWakeLocked(ws.getUid(i), pid, null, name, historyName, type, 4367 unimportantForLogging, elapsedRealtime, uptime); 4368 } 4369 4370 List<WorkChain> wcs = ws.getWorkChains(); 4371 if (wcs != null) { 4372 for (int i = 0; i < wcs.size(); ++i) { 4373 final WorkChain wc = wcs.get(i); 4374 noteStartWakeLocked(wc.getAttributionUid(), pid, wc, name, historyName, type, 4375 unimportantForLogging, elapsedRealtime, uptime); 4376 } 4377 } 4378 } 4379 noteChangeWakelockFromSourceLocked(WorkSource ws, int pid, String name, String historyName, int type, WorkSource newWs, int newPid, String newName, String newHistoryName, int newType, boolean newUnimportantForLogging)4380 public void noteChangeWakelockFromSourceLocked(WorkSource ws, int pid, String name, 4381 String historyName, int type, WorkSource newWs, int newPid, String newName, 4382 String newHistoryName, int newType, boolean newUnimportantForLogging) { 4383 final long elapsedRealtime = mClocks.elapsedRealtime(); 4384 final long uptime = mClocks.uptimeMillis(); 4385 4386 List<WorkChain>[] wcs = WorkSource.diffChains(ws, newWs); 4387 4388 // For correct semantics, we start the need worksources first, so that we won't 4389 // make inappropriate history items as if all wake locks went away and new ones 4390 // appeared. This is okay because tracking of wake locks allows nesting. 4391 // 4392 // First the starts : 4393 final int NN = newWs.size(); 4394 for (int i=0; i<NN; i++) { 4395 noteStartWakeLocked(newWs.getUid(i), newPid, null, newName, newHistoryName, newType, 4396 newUnimportantForLogging, elapsedRealtime, uptime); 4397 } 4398 if (wcs != null) { 4399 List<WorkChain> newChains = wcs[0]; 4400 if (newChains != null) { 4401 for (int i = 0; i < newChains.size(); ++i) { 4402 final WorkChain newChain = newChains.get(i); 4403 noteStartWakeLocked(newChain.getAttributionUid(), newPid, newChain, newName, 4404 newHistoryName, newType, newUnimportantForLogging, elapsedRealtime, 4405 uptime); 4406 } 4407 } 4408 } 4409 4410 // Then the stops : 4411 final int NO = ws.size(); 4412 for (int i=0; i<NO; i++) { 4413 noteStopWakeLocked(ws.getUid(i), pid, null, name, historyName, type, elapsedRealtime, 4414 uptime); 4415 } 4416 if (wcs != null) { 4417 List<WorkChain> goneChains = wcs[1]; 4418 if (goneChains != null) { 4419 for (int i = 0; i < goneChains.size(); ++i) { 4420 final WorkChain goneChain = goneChains.get(i); 4421 noteStopWakeLocked(goneChain.getAttributionUid(), pid, goneChain, name, 4422 historyName, type, elapsedRealtime, uptime); 4423 } 4424 } 4425 } 4426 } 4427 noteStopWakeFromSourceLocked(WorkSource ws, int pid, String name, String historyName, int type)4428 public void noteStopWakeFromSourceLocked(WorkSource ws, int pid, String name, 4429 String historyName, int type) { 4430 final long elapsedRealtime = mClocks.elapsedRealtime(); 4431 final long uptime = mClocks.uptimeMillis(); 4432 final int N = ws.size(); 4433 for (int i=0; i<N; i++) { 4434 noteStopWakeLocked(ws.getUid(i), pid, null, name, historyName, type, elapsedRealtime, 4435 uptime); 4436 } 4437 4438 List<WorkChain> wcs = ws.getWorkChains(); 4439 if (wcs != null) { 4440 for (int i = 0; i < wcs.size(); ++i) { 4441 final WorkChain wc = wcs.get(i); 4442 noteStopWakeLocked(wc.getAttributionUid(), pid, wc, name, historyName, type, 4443 elapsedRealtime, uptime); 4444 } 4445 } 4446 } 4447 noteLongPartialWakelockStart(String name, String historyName, int uid)4448 public void noteLongPartialWakelockStart(String name, String historyName, int uid) { 4449 uid = mapUid(uid); 4450 noteLongPartialWakeLockStartInternal(name, historyName, uid); 4451 } 4452 noteLongPartialWakelockStartFromSource(String name, String historyName, WorkSource workSource)4453 public void noteLongPartialWakelockStartFromSource(String name, String historyName, 4454 WorkSource workSource) { 4455 final int N = workSource.size(); 4456 for (int i = 0; i < N; ++i) { 4457 final int uid = mapUid(workSource.getUid(i)); 4458 noteLongPartialWakeLockStartInternal(name, historyName, uid); 4459 } 4460 4461 final List<WorkChain> workChains = workSource.getWorkChains(); 4462 if (workChains != null) { 4463 for (int i = 0; i < workChains.size(); ++i) { 4464 final WorkChain workChain = workChains.get(i); 4465 final int uid = workChain.getAttributionUid(); 4466 noteLongPartialWakeLockStartInternal(name, historyName, uid); 4467 } 4468 } 4469 } 4470 noteLongPartialWakeLockStartInternal(String name, String historyName, int uid)4471 private void noteLongPartialWakeLockStartInternal(String name, String historyName, int uid) { 4472 final long elapsedRealtime = mClocks.elapsedRealtime(); 4473 final long uptime = mClocks.uptimeMillis(); 4474 if (historyName == null) { 4475 historyName = name; 4476 } 4477 if (!mActiveEvents.updateState(HistoryItem.EVENT_LONG_WAKE_LOCK_START, historyName, uid, 4478 0)) { 4479 return; 4480 } 4481 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_LONG_WAKE_LOCK_START, 4482 historyName, uid); 4483 } 4484 noteLongPartialWakelockFinish(String name, String historyName, int uid)4485 public void noteLongPartialWakelockFinish(String name, String historyName, int uid) { 4486 uid = mapUid(uid); 4487 noteLongPartialWakeLockFinishInternal(name, historyName, uid); 4488 } 4489 noteLongPartialWakelockFinishFromSource(String name, String historyName, WorkSource workSource)4490 public void noteLongPartialWakelockFinishFromSource(String name, String historyName, 4491 WorkSource workSource) { 4492 final int N = workSource.size(); 4493 for (int i = 0; i < N; ++i) { 4494 final int uid = mapUid(workSource.getUid(i)); 4495 noteLongPartialWakeLockFinishInternal(name, historyName, uid); 4496 } 4497 4498 final List<WorkChain> workChains = workSource.getWorkChains(); 4499 if (workChains != null) { 4500 for (int i = 0; i < workChains.size(); ++i) { 4501 final WorkChain workChain = workChains.get(i); 4502 final int uid = workChain.getAttributionUid(); 4503 noteLongPartialWakeLockFinishInternal(name, historyName, uid); 4504 } 4505 } 4506 } 4507 noteLongPartialWakeLockFinishInternal(String name, String historyName, int uid)4508 private void noteLongPartialWakeLockFinishInternal(String name, String historyName, int uid) { 4509 final long elapsedRealtime = mClocks.elapsedRealtime(); 4510 final long uptime = mClocks.uptimeMillis(); 4511 if (historyName == null) { 4512 historyName = name; 4513 } 4514 if (!mActiveEvents.updateState(HistoryItem.EVENT_LONG_WAKE_LOCK_FINISH, historyName, uid, 4515 0)) { 4516 return; 4517 } 4518 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_LONG_WAKE_LOCK_FINISH, 4519 historyName, uid); 4520 } 4521 aggregateLastWakeupUptimeLocked(long uptimeMs)4522 void aggregateLastWakeupUptimeLocked(long uptimeMs) { 4523 if (mLastWakeupReason != null) { 4524 long deltaUptime = uptimeMs - mLastWakeupUptimeMs; 4525 SamplingTimer timer = getWakeupReasonTimerLocked(mLastWakeupReason); 4526 timer.add(deltaUptime * 1000, 1); // time in in microseconds 4527 FrameworkStatsLog.write(FrameworkStatsLog.KERNEL_WAKEUP_REPORTED, mLastWakeupReason, 4528 /* duration_usec */ deltaUptime * 1000); 4529 mLastWakeupReason = null; 4530 } 4531 } 4532 noteWakeupReasonLocked(String reason)4533 public void noteWakeupReasonLocked(String reason) { 4534 final long elapsedRealtime = mClocks.elapsedRealtime(); 4535 final long uptime = mClocks.uptimeMillis(); 4536 if (DEBUG_HISTORY) Slog.v(TAG, "Wakeup reason \"" + reason +"\": " 4537 + Integer.toHexString(mHistoryCur.states)); 4538 aggregateLastWakeupUptimeLocked(uptime); 4539 mHistoryCur.wakeReasonTag = mHistoryCur.localWakeReasonTag; 4540 mHistoryCur.wakeReasonTag.string = reason; 4541 mHistoryCur.wakeReasonTag.uid = 0; 4542 mLastWakeupReason = reason; 4543 mLastWakeupUptimeMs = uptime; 4544 addHistoryRecordLocked(elapsedRealtime, uptime); 4545 } 4546 startAddingCpuLocked()4547 public boolean startAddingCpuLocked() { 4548 mExternalSync.cancelCpuSyncDueToWakelockChange(); 4549 return mOnBatteryInternal; 4550 } 4551 finishAddingCpuLocked(int totalUTime, int totalSTime, int statUserTime, int statSystemTime, int statIOWaitTime, int statIrqTime, int statSoftIrqTime, int statIdleTime)4552 public void finishAddingCpuLocked(int totalUTime, int totalSTime, int statUserTime, 4553 int statSystemTime, int statIOWaitTime, int statIrqTime, 4554 int statSoftIrqTime, int statIdleTime) { 4555 if (DEBUG) Slog.d(TAG, "Adding cpu: tuser=" + totalUTime + " tsys=" + totalSTime 4556 + " user=" + statUserTime + " sys=" + statSystemTime 4557 + " io=" + statIOWaitTime + " irq=" + statIrqTime 4558 + " sirq=" + statSoftIrqTime + " idle=" + statIdleTime); 4559 mCurStepCpuUserTime += totalUTime; 4560 mCurStepCpuSystemTime += totalSTime; 4561 mCurStepStatUserTime += statUserTime; 4562 mCurStepStatSystemTime += statSystemTime; 4563 mCurStepStatIOWaitTime += statIOWaitTime; 4564 mCurStepStatIrqTime += statIrqTime; 4565 mCurStepStatSoftIrqTime += statSoftIrqTime; 4566 mCurStepStatIdleTime += statIdleTime; 4567 } 4568 noteProcessDiedLocked(int uid, int pid)4569 public void noteProcessDiedLocked(int uid, int pid) { 4570 uid = mapUid(uid); 4571 Uid u = mUidStats.get(uid); 4572 if (u != null) { 4573 u.mPids.remove(pid); 4574 } 4575 } 4576 getProcessWakeTime(int uid, int pid, long realtime)4577 public long getProcessWakeTime(int uid, int pid, long realtime) { 4578 uid = mapUid(uid); 4579 Uid u = mUidStats.get(uid); 4580 if (u != null) { 4581 Uid.Pid p = u.mPids.get(pid); 4582 if (p != null) { 4583 return p.mWakeSumMs + (p.mWakeNesting > 0 ? (realtime - p.mWakeStartMs) : 0); 4584 } 4585 } 4586 return 0; 4587 } 4588 reportExcessiveCpuLocked(int uid, String proc, long overTime, long usedTime)4589 public void reportExcessiveCpuLocked(int uid, String proc, long overTime, long usedTime) { 4590 uid = mapUid(uid); 4591 Uid u = mUidStats.get(uid); 4592 if (u != null) { 4593 u.reportExcessiveCpuLocked(proc, overTime, usedTime); 4594 } 4595 } 4596 4597 int mSensorNesting; 4598 noteStartSensorLocked(int uid, int sensor)4599 public void noteStartSensorLocked(int uid, int sensor) { 4600 uid = mapUid(uid); 4601 final long elapsedRealtime = mClocks.elapsedRealtime(); 4602 final long uptime = mClocks.uptimeMillis(); 4603 if (mSensorNesting == 0) { 4604 mHistoryCur.states |= HistoryItem.STATE_SENSOR_ON_FLAG; 4605 if (DEBUG_HISTORY) Slog.v(TAG, "Start sensor to: " 4606 + Integer.toHexString(mHistoryCur.states)); 4607 addHistoryRecordLocked(elapsedRealtime, uptime); 4608 } 4609 mSensorNesting++; 4610 getUidStatsLocked(uid).noteStartSensor(sensor, elapsedRealtime); 4611 } 4612 noteStopSensorLocked(int uid, int sensor)4613 public void noteStopSensorLocked(int uid, int sensor) { 4614 uid = mapUid(uid); 4615 final long elapsedRealtime = mClocks.elapsedRealtime(); 4616 final long uptime = mClocks.uptimeMillis(); 4617 mSensorNesting--; 4618 if (mSensorNesting == 0) { 4619 mHistoryCur.states &= ~HistoryItem.STATE_SENSOR_ON_FLAG; 4620 if (DEBUG_HISTORY) Slog.v(TAG, "Stop sensor to: " 4621 + Integer.toHexString(mHistoryCur.states)); 4622 addHistoryRecordLocked(elapsedRealtime, uptime); 4623 } 4624 getUidStatsLocked(uid).noteStopSensor(sensor, elapsedRealtime); 4625 } 4626 4627 int mGpsNesting; 4628 noteGpsChangedLocked(WorkSource oldWs, WorkSource newWs)4629 public void noteGpsChangedLocked(WorkSource oldWs, WorkSource newWs) { 4630 for (int i = 0; i < newWs.size(); ++i) { 4631 noteStartGpsLocked(newWs.getUid(i), null); 4632 } 4633 4634 for (int i = 0; i < oldWs.size(); ++i) { 4635 noteStopGpsLocked((oldWs.getUid(i)), null); 4636 } 4637 4638 List<WorkChain>[] wcs = WorkSource.diffChains(oldWs, newWs); 4639 if (wcs != null) { 4640 if (wcs[0] != null) { 4641 final List<WorkChain> newChains = wcs[0]; 4642 for (int i = 0; i < newChains.size(); ++i) { 4643 noteStartGpsLocked(-1, newChains.get(i)); 4644 } 4645 } 4646 4647 if (wcs[1] != null) { 4648 final List<WorkChain> goneChains = wcs[1]; 4649 for (int i = 0; i < goneChains.size(); ++i) { 4650 noteStopGpsLocked(-1, goneChains.get(i)); 4651 } 4652 } 4653 } 4654 } 4655 noteStartGpsLocked(int uid, WorkChain workChain)4656 private void noteStartGpsLocked(int uid, WorkChain workChain) { 4657 uid = getAttributionUid(uid, workChain); 4658 final long elapsedRealtime = mClocks.elapsedRealtime(); 4659 final long uptime = mClocks.uptimeMillis(); 4660 if (mGpsNesting == 0) { 4661 mHistoryCur.states |= HistoryItem.STATE_GPS_ON_FLAG; 4662 if (DEBUG_HISTORY) Slog.v(TAG, "Start GPS to: " 4663 + Integer.toHexString(mHistoryCur.states)); 4664 addHistoryRecordLocked(elapsedRealtime, uptime); 4665 } 4666 mGpsNesting++; 4667 4668 if (workChain == null) { 4669 FrameworkStatsLog.write_non_chained(FrameworkStatsLog.GPS_SCAN_STATE_CHANGED, uid, null, 4670 FrameworkStatsLog.GPS_SCAN_STATE_CHANGED__STATE__ON); 4671 } else { 4672 FrameworkStatsLog.write(FrameworkStatsLog.GPS_SCAN_STATE_CHANGED, 4673 workChain.getUids(), workChain.getTags(), 4674 FrameworkStatsLog.GPS_SCAN_STATE_CHANGED__STATE__ON); 4675 } 4676 4677 getUidStatsLocked(uid).noteStartGps(elapsedRealtime); 4678 } 4679 noteStopGpsLocked(int uid, WorkChain workChain)4680 private void noteStopGpsLocked(int uid, WorkChain workChain) { 4681 uid = getAttributionUid(uid, workChain); 4682 final long elapsedRealtime = mClocks.elapsedRealtime(); 4683 final long uptime = mClocks.uptimeMillis(); 4684 mGpsNesting--; 4685 if (mGpsNesting == 0) { 4686 mHistoryCur.states &= ~HistoryItem.STATE_GPS_ON_FLAG; 4687 if (DEBUG_HISTORY) Slog.v(TAG, "Stop GPS to: " 4688 + Integer.toHexString(mHistoryCur.states)); 4689 addHistoryRecordLocked(elapsedRealtime, uptime); 4690 stopAllGpsSignalQualityTimersLocked(-1); 4691 mGpsSignalQualityBin = -1; 4692 } 4693 4694 if (workChain == null) { 4695 FrameworkStatsLog.write_non_chained(FrameworkStatsLog.GPS_SCAN_STATE_CHANGED, uid, null, 4696 FrameworkStatsLog.GPS_SCAN_STATE_CHANGED__STATE__OFF); 4697 } else { 4698 FrameworkStatsLog.write(FrameworkStatsLog.GPS_SCAN_STATE_CHANGED, workChain.getUids(), 4699 workChain.getTags(), FrameworkStatsLog.GPS_SCAN_STATE_CHANGED__STATE__OFF); 4700 } 4701 4702 getUidStatsLocked(uid).noteStopGps(elapsedRealtime); 4703 } 4704 noteGpsSignalQualityLocked(int signalLevel)4705 public void noteGpsSignalQualityLocked(int signalLevel) { 4706 if (mGpsNesting == 0) { 4707 return; 4708 } 4709 if (signalLevel < 0 || signalLevel >= GnssMetrics.NUM_GPS_SIGNAL_QUALITY_LEVELS) { 4710 stopAllGpsSignalQualityTimersLocked(-1); 4711 return; 4712 } 4713 final long elapsedRealtime = mClocks.elapsedRealtime(); 4714 final long uptime = mClocks.uptimeMillis(); 4715 if (mGpsSignalQualityBin != signalLevel) { 4716 if (mGpsSignalQualityBin >= 0) { 4717 mGpsSignalQualityTimer[mGpsSignalQualityBin].stopRunningLocked(elapsedRealtime); 4718 } 4719 if(!mGpsSignalQualityTimer[signalLevel].isRunningLocked()) { 4720 mGpsSignalQualityTimer[signalLevel].startRunningLocked(elapsedRealtime); 4721 } 4722 mHistoryCur.states2 = (mHistoryCur.states2&~HistoryItem.STATE2_GPS_SIGNAL_QUALITY_MASK) 4723 | (signalLevel << HistoryItem.STATE2_GPS_SIGNAL_QUALITY_SHIFT); 4724 addHistoryRecordLocked(elapsedRealtime, uptime); 4725 mGpsSignalQualityBin = signalLevel; 4726 } 4727 return; 4728 } 4729 4730 @GuardedBy("this") noteScreenStateLocked(int state)4731 public void noteScreenStateLocked(int state) { 4732 state = mPretendScreenOff ? Display.STATE_OFF : state; 4733 4734 // Battery stats relies on there being 4 states. To accommodate this, new states beyond the 4735 // original 4 are mapped to one of the originals. 4736 if (state > MAX_TRACKED_SCREEN_STATE) { 4737 switch (state) { 4738 case Display.STATE_VR: 4739 state = Display.STATE_ON; 4740 break; 4741 default: 4742 Slog.wtf(TAG, "Unknown screen state (not mapped): " + state); 4743 break; 4744 } 4745 } 4746 4747 if (mScreenState != state) { 4748 recordDailyStatsIfNeededLocked(true); 4749 final int oldState = mScreenState; 4750 mScreenState = state; 4751 if (DEBUG) Slog.v(TAG, "Screen state: oldState=" + Display.stateToString(oldState) 4752 + ", newState=" + Display.stateToString(state)); 4753 4754 if (state != Display.STATE_UNKNOWN) { 4755 int stepState = state-1; 4756 if ((stepState & STEP_LEVEL_MODE_SCREEN_STATE) == stepState) { 4757 mModStepMode |= (mCurStepMode & STEP_LEVEL_MODE_SCREEN_STATE) ^ stepState; 4758 mCurStepMode = (mCurStepMode & ~STEP_LEVEL_MODE_SCREEN_STATE) | stepState; 4759 } else { 4760 Slog.wtf(TAG, "Unexpected screen state: " + state); 4761 } 4762 } 4763 4764 final long elapsedRealtime = mClocks.elapsedRealtime(); 4765 final long uptime = mClocks.uptimeMillis(); 4766 4767 boolean updateHistory = false; 4768 if (isScreenDoze(state) && !isScreenDoze(oldState)) { 4769 mHistoryCur.states |= HistoryItem.STATE_SCREEN_DOZE_FLAG; 4770 mScreenDozeTimer.startRunningLocked(elapsedRealtime); 4771 updateHistory = true; 4772 } else if (isScreenDoze(oldState) && !isScreenDoze(state)) { 4773 mHistoryCur.states &= ~HistoryItem.STATE_SCREEN_DOZE_FLAG; 4774 mScreenDozeTimer.stopRunningLocked(elapsedRealtime); 4775 updateHistory = true; 4776 } 4777 if (isScreenOn(state)) { 4778 mHistoryCur.states |= HistoryItem.STATE_SCREEN_ON_FLAG; 4779 if (DEBUG_HISTORY) Slog.v(TAG, "Screen on to: " 4780 + Integer.toHexString(mHistoryCur.states)); 4781 mScreenOnTimer.startRunningLocked(elapsedRealtime); 4782 if (mScreenBrightnessBin >= 0) { 4783 mScreenBrightnessTimer[mScreenBrightnessBin].startRunningLocked(elapsedRealtime); 4784 } 4785 updateHistory = true; 4786 } else if (isScreenOn(oldState)) { 4787 mHistoryCur.states &= ~HistoryItem.STATE_SCREEN_ON_FLAG; 4788 if (DEBUG_HISTORY) Slog.v(TAG, "Screen off to: " 4789 + Integer.toHexString(mHistoryCur.states)); 4790 mScreenOnTimer.stopRunningLocked(elapsedRealtime); 4791 if (mScreenBrightnessBin >= 0) { 4792 mScreenBrightnessTimer[mScreenBrightnessBin].stopRunningLocked(elapsedRealtime); 4793 } 4794 updateHistory = true; 4795 } 4796 if (updateHistory) { 4797 if (DEBUG_HISTORY) Slog.v(TAG, "Screen state to: " 4798 + Display.stateToString(state)); 4799 addHistoryRecordLocked(elapsedRealtime, uptime); 4800 } 4801 mExternalSync.scheduleCpuSyncDueToScreenStateChange( 4802 mOnBatteryTimeBase.isRunning(), mOnBatteryScreenOffTimeBase.isRunning()); 4803 if (isScreenOn(state)) { 4804 updateTimeBasesLocked(mOnBatteryTimeBase.isRunning(), state, 4805 mClocks.uptimeMillis() * 1000, elapsedRealtime * 1000); 4806 // Fake a wake lock, so we consider the device waked as long as the screen is on. 4807 noteStartWakeLocked(-1, -1, null, "screen", null, WAKE_TYPE_PARTIAL, false, 4808 elapsedRealtime, uptime); 4809 } else if (isScreenOn(oldState)) { 4810 noteStopWakeLocked(-1, -1, null, "screen", "screen", WAKE_TYPE_PARTIAL, 4811 elapsedRealtime, uptime); 4812 updateTimeBasesLocked(mOnBatteryTimeBase.isRunning(), state, 4813 mClocks.uptimeMillis() * 1000, elapsedRealtime * 1000); 4814 } 4815 // Update discharge amounts. 4816 if (mOnBatteryInternal) { 4817 updateDischargeScreenLevelsLocked(oldState, state); 4818 } 4819 } 4820 } 4821 4822 @UnsupportedAppUsage noteScreenBrightnessLocked(int brightness)4823 public void noteScreenBrightnessLocked(int brightness) { 4824 // Bin the brightness. 4825 int bin = brightness / (256/NUM_SCREEN_BRIGHTNESS_BINS); 4826 if (bin < 0) bin = 0; 4827 else if (bin >= NUM_SCREEN_BRIGHTNESS_BINS) bin = NUM_SCREEN_BRIGHTNESS_BINS-1; 4828 if (mScreenBrightnessBin != bin) { 4829 final long elapsedRealtime = mClocks.elapsedRealtime(); 4830 final long uptime = mClocks.uptimeMillis(); 4831 mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_BRIGHTNESS_MASK) 4832 | (bin << HistoryItem.STATE_BRIGHTNESS_SHIFT); 4833 if (DEBUG_HISTORY) Slog.v(TAG, "Screen brightness " + bin + " to: " 4834 + Integer.toHexString(mHistoryCur.states)); 4835 addHistoryRecordLocked(elapsedRealtime, uptime); 4836 if (mScreenState == Display.STATE_ON) { 4837 if (mScreenBrightnessBin >= 0) { 4838 mScreenBrightnessTimer[mScreenBrightnessBin].stopRunningLocked(elapsedRealtime); 4839 } 4840 mScreenBrightnessTimer[bin].startRunningLocked(elapsedRealtime); 4841 } 4842 mScreenBrightnessBin = bin; 4843 } 4844 } 4845 4846 @UnsupportedAppUsage noteUserActivityLocked(int uid, int event)4847 public void noteUserActivityLocked(int uid, int event) { 4848 if (mOnBatteryInternal) { 4849 uid = mapUid(uid); 4850 getUidStatsLocked(uid).noteUserActivityLocked(event); 4851 } 4852 } 4853 noteWakeUpLocked(String reason, int reasonUid)4854 public void noteWakeUpLocked(String reason, int reasonUid) { 4855 final long elapsedRealtime = mClocks.elapsedRealtime(); 4856 final long uptime = mClocks.uptimeMillis(); 4857 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_SCREEN_WAKE_UP, 4858 reason, reasonUid); 4859 } 4860 noteInteractiveLocked(boolean interactive)4861 public void noteInteractiveLocked(boolean interactive) { 4862 if (mInteractive != interactive) { 4863 final long elapsedRealtime = mClocks.elapsedRealtime(); 4864 mInteractive = interactive; 4865 if (DEBUG) Slog.v(TAG, "Interactive: " + interactive); 4866 if (interactive) { 4867 mInteractiveTimer.startRunningLocked(elapsedRealtime); 4868 } else { 4869 mInteractiveTimer.stopRunningLocked(elapsedRealtime); 4870 } 4871 } 4872 } 4873 noteConnectivityChangedLocked(int type, String extra)4874 public void noteConnectivityChangedLocked(int type, String extra) { 4875 final long elapsedRealtime = mClocks.elapsedRealtime(); 4876 final long uptime = mClocks.uptimeMillis(); 4877 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_CONNECTIVITY_CHANGED, 4878 extra, type); 4879 mNumConnectivityChange++; 4880 } 4881 noteMobileRadioApWakeupLocked(final long elapsedRealtimeMillis, final long uptimeMillis, int uid)4882 private void noteMobileRadioApWakeupLocked(final long elapsedRealtimeMillis, 4883 final long uptimeMillis, int uid) { 4884 uid = mapUid(uid); 4885 addHistoryEventLocked(elapsedRealtimeMillis, uptimeMillis, HistoryItem.EVENT_WAKEUP_AP, "", 4886 uid); 4887 getUidStatsLocked(uid).noteMobileRadioApWakeupLocked(); 4888 } 4889 4890 /** 4891 * Updates the radio power state and returns true if an external stats collection should occur. 4892 */ noteMobileRadioPowerStateLocked(int powerState, long timestampNs, int uid)4893 public boolean noteMobileRadioPowerStateLocked(int powerState, long timestampNs, int uid) { 4894 final long elapsedRealtime = mClocks.elapsedRealtime(); 4895 final long uptime = mClocks.uptimeMillis(); 4896 if (mMobileRadioPowerState != powerState) { 4897 long realElapsedRealtimeMs; 4898 final boolean active = 4899 powerState == DataConnectionRealTimeInfo.DC_POWER_STATE_MEDIUM 4900 || powerState == DataConnectionRealTimeInfo.DC_POWER_STATE_HIGH; 4901 if (active) { 4902 if (uid > 0) { 4903 noteMobileRadioApWakeupLocked(elapsedRealtime, uptime, uid); 4904 } 4905 4906 mMobileRadioActiveStartTime = realElapsedRealtimeMs = timestampNs / (1000 * 1000); 4907 mHistoryCur.states |= HistoryItem.STATE_MOBILE_RADIO_ACTIVE_FLAG; 4908 } else { 4909 realElapsedRealtimeMs = timestampNs / (1000*1000); 4910 long lastUpdateTimeMs = mMobileRadioActiveStartTime; 4911 if (realElapsedRealtimeMs < lastUpdateTimeMs) { 4912 Slog.wtf(TAG, "Data connection inactive timestamp " + realElapsedRealtimeMs 4913 + " is before start time " + lastUpdateTimeMs); 4914 realElapsedRealtimeMs = elapsedRealtime; 4915 } else if (realElapsedRealtimeMs < elapsedRealtime) { 4916 mMobileRadioActiveAdjustedTime.addCountLocked(elapsedRealtime 4917 - realElapsedRealtimeMs); 4918 } 4919 mHistoryCur.states &= ~HistoryItem.STATE_MOBILE_RADIO_ACTIVE_FLAG; 4920 } 4921 if (DEBUG_HISTORY) Slog.v(TAG, "Mobile network active " + active + " to: " 4922 + Integer.toHexString(mHistoryCur.states)); 4923 addHistoryRecordLocked(elapsedRealtime, uptime); 4924 mMobileRadioPowerState = powerState; 4925 if (active) { 4926 mMobileRadioActiveTimer.startRunningLocked(elapsedRealtime); 4927 mMobileRadioActivePerAppTimer.startRunningLocked(elapsedRealtime); 4928 } else { 4929 mMobileRadioActiveTimer.stopRunningLocked(realElapsedRealtimeMs); 4930 mMobileRadioActivePerAppTimer.stopRunningLocked(realElapsedRealtimeMs); 4931 // Tell the caller to collect radio network/power stats. 4932 return true; 4933 } 4934 } 4935 return false; 4936 } 4937 notePowerSaveModeLocked(boolean enabled)4938 public void notePowerSaveModeLocked(boolean enabled) { 4939 if (mPowerSaveModeEnabled != enabled) { 4940 int stepState = enabled ? STEP_LEVEL_MODE_POWER_SAVE : 0; 4941 mModStepMode |= (mCurStepMode&STEP_LEVEL_MODE_POWER_SAVE) ^ stepState; 4942 mCurStepMode = (mCurStepMode&~STEP_LEVEL_MODE_POWER_SAVE) | stepState; 4943 final long elapsedRealtime = mClocks.elapsedRealtime(); 4944 final long uptime = mClocks.uptimeMillis(); 4945 mPowerSaveModeEnabled = enabled; 4946 if (enabled) { 4947 mHistoryCur.states2 |= HistoryItem.STATE2_POWER_SAVE_FLAG; 4948 if (DEBUG_HISTORY) Slog.v(TAG, "Power save mode enabled to: " 4949 + Integer.toHexString(mHistoryCur.states2)); 4950 mPowerSaveModeEnabledTimer.startRunningLocked(elapsedRealtime); 4951 } else { 4952 mHistoryCur.states2 &= ~HistoryItem.STATE2_POWER_SAVE_FLAG; 4953 if (DEBUG_HISTORY) Slog.v(TAG, "Power save mode disabled to: " 4954 + Integer.toHexString(mHistoryCur.states2)); 4955 mPowerSaveModeEnabledTimer.stopRunningLocked(elapsedRealtime); 4956 } 4957 addHistoryRecordLocked(elapsedRealtime, uptime); 4958 FrameworkStatsLog.write(FrameworkStatsLog.BATTERY_SAVER_MODE_STATE_CHANGED, 4959 enabled 4960 ? FrameworkStatsLog.BATTERY_SAVER_MODE_STATE_CHANGED__STATE__ON 4961 : FrameworkStatsLog.BATTERY_SAVER_MODE_STATE_CHANGED__STATE__OFF); 4962 } 4963 } 4964 noteDeviceIdleModeLocked(final int mode, String activeReason, int activeUid)4965 public void noteDeviceIdleModeLocked(final int mode, String activeReason, int activeUid) { 4966 final long elapsedRealtime = mClocks.elapsedRealtime(); 4967 final long uptime = mClocks.uptimeMillis(); 4968 boolean nowIdling = mode == DEVICE_IDLE_MODE_DEEP; 4969 if (mDeviceIdling && !nowIdling && activeReason == null) { 4970 // We don't go out of general idling mode until explicitly taken out of 4971 // device idle through going active or significant motion. 4972 nowIdling = true; 4973 } 4974 boolean nowLightIdling = mode == DEVICE_IDLE_MODE_LIGHT; 4975 if (mDeviceLightIdling && !nowLightIdling && !nowIdling && activeReason == null) { 4976 // We don't go out of general light idling mode until explicitly taken out of 4977 // device idle through going active or significant motion. 4978 nowLightIdling = true; 4979 } 4980 if (activeReason != null && (mDeviceIdling || mDeviceLightIdling)) { 4981 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_ACTIVE, 4982 activeReason, activeUid); 4983 } 4984 if (mDeviceIdling != nowIdling || mDeviceLightIdling != nowLightIdling) { 4985 int statsmode; 4986 if (nowIdling) statsmode = DEVICE_IDLE_MODE_DEEP; 4987 else if (nowLightIdling) statsmode = DEVICE_IDLE_MODE_LIGHT; 4988 else statsmode = DEVICE_IDLE_MODE_OFF; 4989 FrameworkStatsLog.write(FrameworkStatsLog.DEVICE_IDLING_MODE_STATE_CHANGED, statsmode); 4990 } 4991 if (mDeviceIdling != nowIdling) { 4992 mDeviceIdling = nowIdling; 4993 int stepState = nowIdling ? STEP_LEVEL_MODE_DEVICE_IDLE : 0; 4994 mModStepMode |= (mCurStepMode&STEP_LEVEL_MODE_DEVICE_IDLE) ^ stepState; 4995 mCurStepMode = (mCurStepMode&~STEP_LEVEL_MODE_DEVICE_IDLE) | stepState; 4996 if (nowIdling) { 4997 mDeviceIdlingTimer.startRunningLocked(elapsedRealtime); 4998 } else { 4999 mDeviceIdlingTimer.stopRunningLocked(elapsedRealtime); 5000 } 5001 } 5002 if (mDeviceLightIdling != nowLightIdling) { 5003 mDeviceLightIdling = nowLightIdling; 5004 if (nowLightIdling) { 5005 mDeviceLightIdlingTimer.startRunningLocked(elapsedRealtime); 5006 } else { 5007 mDeviceLightIdlingTimer.stopRunningLocked(elapsedRealtime); 5008 } 5009 } 5010 if (mDeviceIdleMode != mode) { 5011 mHistoryCur.states2 = (mHistoryCur.states2 & ~HistoryItem.STATE2_DEVICE_IDLE_MASK) 5012 | (mode << HistoryItem.STATE2_DEVICE_IDLE_SHIFT); 5013 if (DEBUG_HISTORY) Slog.v(TAG, "Device idle mode changed to: " 5014 + Integer.toHexString(mHistoryCur.states2)); 5015 addHistoryRecordLocked(elapsedRealtime, uptime); 5016 long lastDuration = elapsedRealtime - mLastIdleTimeStart; 5017 mLastIdleTimeStart = elapsedRealtime; 5018 if (mDeviceIdleMode == DEVICE_IDLE_MODE_LIGHT) { 5019 if (lastDuration > mLongestLightIdleTime) { 5020 mLongestLightIdleTime = lastDuration; 5021 } 5022 mDeviceIdleModeLightTimer.stopRunningLocked(elapsedRealtime); 5023 } else if (mDeviceIdleMode == DEVICE_IDLE_MODE_DEEP) { 5024 if (lastDuration > mLongestFullIdleTime) { 5025 mLongestFullIdleTime = lastDuration; 5026 } 5027 mDeviceIdleModeFullTimer.stopRunningLocked(elapsedRealtime); 5028 } 5029 if (mode == DEVICE_IDLE_MODE_LIGHT) { 5030 mDeviceIdleModeLightTimer.startRunningLocked(elapsedRealtime); 5031 } else if (mode == DEVICE_IDLE_MODE_DEEP) { 5032 mDeviceIdleModeFullTimer.startRunningLocked(elapsedRealtime); 5033 } 5034 mDeviceIdleMode = mode; 5035 FrameworkStatsLog.write(FrameworkStatsLog.DEVICE_IDLE_MODE_STATE_CHANGED, mode); 5036 } 5037 } 5038 notePackageInstalledLocked(String pkgName, long versionCode)5039 public void notePackageInstalledLocked(String pkgName, long versionCode) { 5040 final long elapsedRealtime = mClocks.elapsedRealtime(); 5041 final long uptime = mClocks.uptimeMillis(); 5042 // XXX need to figure out what to do with long version codes. 5043 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_PACKAGE_INSTALLED, 5044 pkgName, (int)versionCode); 5045 PackageChange pc = new PackageChange(); 5046 pc.mPackageName = pkgName; 5047 pc.mUpdate = true; 5048 pc.mVersionCode = versionCode; 5049 addPackageChange(pc); 5050 } 5051 notePackageUninstalledLocked(String pkgName)5052 public void notePackageUninstalledLocked(String pkgName) { 5053 final long elapsedRealtime = mClocks.elapsedRealtime(); 5054 final long uptime = mClocks.uptimeMillis(); 5055 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_PACKAGE_UNINSTALLED, 5056 pkgName, 0); 5057 PackageChange pc = new PackageChange(); 5058 pc.mPackageName = pkgName; 5059 pc.mUpdate = true; 5060 addPackageChange(pc); 5061 } 5062 addPackageChange(PackageChange pc)5063 private void addPackageChange(PackageChange pc) { 5064 if (mDailyPackageChanges == null) { 5065 mDailyPackageChanges = new ArrayList<>(); 5066 } 5067 mDailyPackageChanges.add(pc); 5068 } 5069 stopAllGpsSignalQualityTimersLocked(int except)5070 void stopAllGpsSignalQualityTimersLocked(int except) { 5071 final long elapsedRealtime = mClocks.elapsedRealtime(); 5072 for (int i = 0; i < GnssMetrics.NUM_GPS_SIGNAL_QUALITY_LEVELS; i++) { 5073 if (i == except) { 5074 continue; 5075 } 5076 while (mGpsSignalQualityTimer[i].isRunningLocked()) { 5077 mGpsSignalQualityTimer[i].stopRunningLocked(elapsedRealtime); 5078 } 5079 } 5080 } 5081 5082 @UnsupportedAppUsage notePhoneOnLocked()5083 public void notePhoneOnLocked() { 5084 if (!mPhoneOn) { 5085 final long elapsedRealtime = mClocks.elapsedRealtime(); 5086 final long uptime = mClocks.uptimeMillis(); 5087 mHistoryCur.states2 |= HistoryItem.STATE2_PHONE_IN_CALL_FLAG; 5088 if (DEBUG_HISTORY) Slog.v(TAG, "Phone on to: " 5089 + Integer.toHexString(mHistoryCur.states)); 5090 addHistoryRecordLocked(elapsedRealtime, uptime); 5091 mPhoneOn = true; 5092 mPhoneOnTimer.startRunningLocked(elapsedRealtime); 5093 } 5094 } 5095 5096 @UnsupportedAppUsage notePhoneOffLocked()5097 public void notePhoneOffLocked() { 5098 if (mPhoneOn) { 5099 final long elapsedRealtime = mClocks.elapsedRealtime(); 5100 final long uptime = mClocks.uptimeMillis(); 5101 mHistoryCur.states2 &= ~HistoryItem.STATE2_PHONE_IN_CALL_FLAG; 5102 if (DEBUG_HISTORY) Slog.v(TAG, "Phone off to: " 5103 + Integer.toHexString(mHistoryCur.states)); 5104 addHistoryRecordLocked(elapsedRealtime, uptime); 5105 mPhoneOn = false; 5106 mPhoneOnTimer.stopRunningLocked(elapsedRealtime); 5107 } 5108 } 5109 registerUsbStateReceiver(Context context)5110 private void registerUsbStateReceiver(Context context) { 5111 final IntentFilter usbStateFilter = new IntentFilter(); 5112 usbStateFilter.addAction(UsbManager.ACTION_USB_STATE); 5113 context.registerReceiver(new BroadcastReceiver() { 5114 @Override 5115 public void onReceive(Context context, Intent intent) { 5116 final boolean state = intent.getBooleanExtra(UsbManager.USB_CONNECTED, false); 5117 synchronized (BatteryStatsImpl.this) { 5118 noteUsbConnectionStateLocked(state); 5119 } 5120 } 5121 }, usbStateFilter); 5122 synchronized (this) { 5123 if (mUsbDataState == USB_DATA_UNKNOWN) { 5124 final Intent usbState = context.registerReceiver(null, usbStateFilter); 5125 final boolean initState = usbState != null && usbState.getBooleanExtra( 5126 UsbManager.USB_CONNECTED, false); 5127 noteUsbConnectionStateLocked(initState); 5128 } 5129 } 5130 } 5131 noteUsbConnectionStateLocked(boolean connected)5132 private void noteUsbConnectionStateLocked(boolean connected) { 5133 int newState = connected ? USB_DATA_CONNECTED : USB_DATA_DISCONNECTED; 5134 if (mUsbDataState != newState) { 5135 mUsbDataState = newState; 5136 if (connected) { 5137 mHistoryCur.states2 |= HistoryItem.STATE2_USB_DATA_LINK_FLAG; 5138 } else { 5139 mHistoryCur.states2 &= ~HistoryItem.STATE2_USB_DATA_LINK_FLAG; 5140 } 5141 addHistoryRecordLocked(mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 5142 } 5143 } 5144 stopAllPhoneSignalStrengthTimersLocked(int except)5145 void stopAllPhoneSignalStrengthTimersLocked(int except) { 5146 final long elapsedRealtime = mClocks.elapsedRealtime(); 5147 for (int i = 0; i < CellSignalStrength.getNumSignalStrengthLevels(); i++) { 5148 if (i == except) { 5149 continue; 5150 } 5151 while (mPhoneSignalStrengthsTimer[i].isRunningLocked()) { 5152 mPhoneSignalStrengthsTimer[i].stopRunningLocked(elapsedRealtime); 5153 } 5154 } 5155 } 5156 fixPhoneServiceState(int state, int signalBin)5157 private int fixPhoneServiceState(int state, int signalBin) { 5158 if (mPhoneSimStateRaw == TelephonyManager.SIM_STATE_ABSENT) { 5159 // In this case we will always be STATE_OUT_OF_SERVICE, so need 5160 // to infer that we are scanning from other data. 5161 if (state == ServiceState.STATE_OUT_OF_SERVICE 5162 && signalBin > CellSignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN) { 5163 state = ServiceState.STATE_IN_SERVICE; 5164 } 5165 } 5166 5167 return state; 5168 } 5169 updateAllPhoneStateLocked(int state, int simState, int strengthBin)5170 private void updateAllPhoneStateLocked(int state, int simState, int strengthBin) { 5171 boolean scanning = false; 5172 boolean newHistory = false; 5173 5174 mPhoneServiceStateRaw = state; 5175 mPhoneSimStateRaw = simState; 5176 mPhoneSignalStrengthBinRaw = strengthBin; 5177 5178 final long elapsedRealtime = mClocks.elapsedRealtime(); 5179 final long uptime = mClocks.uptimeMillis(); 5180 5181 if (simState == TelephonyManager.SIM_STATE_ABSENT) { 5182 // In this case we will always be STATE_OUT_OF_SERVICE, so need 5183 // to infer that we are scanning from other data. 5184 if (state == ServiceState.STATE_OUT_OF_SERVICE 5185 && strengthBin > CellSignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN) { 5186 state = ServiceState.STATE_IN_SERVICE; 5187 } 5188 } 5189 5190 // If the phone is powered off, stop all timers. 5191 if (state == ServiceState.STATE_POWER_OFF) { 5192 strengthBin = -1; 5193 5194 // If we are in service, make sure the correct signal string timer is running. 5195 } else if (state == ServiceState.STATE_IN_SERVICE) { 5196 // Bin will be changed below. 5197 5198 // If we're out of service, we are in the lowest signal strength 5199 // bin and have the scanning bit set. 5200 } else if (state == ServiceState.STATE_OUT_OF_SERVICE) { 5201 scanning = true; 5202 strengthBin = CellSignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN; 5203 if (!mPhoneSignalScanningTimer.isRunningLocked()) { 5204 mHistoryCur.states |= HistoryItem.STATE_PHONE_SCANNING_FLAG; 5205 newHistory = true; 5206 if (DEBUG_HISTORY) Slog.v(TAG, "Phone started scanning to: " 5207 + Integer.toHexString(mHistoryCur.states)); 5208 mPhoneSignalScanningTimer.startRunningLocked(elapsedRealtime); 5209 FrameworkStatsLog.write(FrameworkStatsLog.PHONE_SERVICE_STATE_CHANGED, state, 5210 simState, strengthBin); 5211 } 5212 } 5213 5214 if (!scanning) { 5215 // If we are no longer scanning, then stop the scanning timer. 5216 if (mPhoneSignalScanningTimer.isRunningLocked()) { 5217 mHistoryCur.states &= ~HistoryItem.STATE_PHONE_SCANNING_FLAG; 5218 if (DEBUG_HISTORY) Slog.v(TAG, "Phone stopped scanning to: " 5219 + Integer.toHexString(mHistoryCur.states)); 5220 newHistory = true; 5221 mPhoneSignalScanningTimer.stopRunningLocked(elapsedRealtime); 5222 FrameworkStatsLog.write(FrameworkStatsLog.PHONE_SERVICE_STATE_CHANGED, state, 5223 simState, strengthBin); 5224 } 5225 } 5226 5227 if (mPhoneServiceState != state) { 5228 mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_PHONE_STATE_MASK) 5229 | (state << HistoryItem.STATE_PHONE_STATE_SHIFT); 5230 if (DEBUG_HISTORY) Slog.v(TAG, "Phone state " + state + " to: " 5231 + Integer.toHexString(mHistoryCur.states)); 5232 newHistory = true; 5233 mPhoneServiceState = state; 5234 } 5235 5236 if (mPhoneSignalStrengthBin != strengthBin) { 5237 if (mPhoneSignalStrengthBin >= 0) { 5238 mPhoneSignalStrengthsTimer[mPhoneSignalStrengthBin].stopRunningLocked( 5239 elapsedRealtime); 5240 } 5241 if (strengthBin >= 0) { 5242 if (!mPhoneSignalStrengthsTimer[strengthBin].isRunningLocked()) { 5243 mPhoneSignalStrengthsTimer[strengthBin].startRunningLocked(elapsedRealtime); 5244 } 5245 mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_PHONE_SIGNAL_STRENGTH_MASK) 5246 | (strengthBin << HistoryItem.STATE_PHONE_SIGNAL_STRENGTH_SHIFT); 5247 if (DEBUG_HISTORY) Slog.v(TAG, "Signal strength " + strengthBin + " to: " 5248 + Integer.toHexString(mHistoryCur.states)); 5249 newHistory = true; 5250 FrameworkStatsLog.write( 5251 FrameworkStatsLog.PHONE_SIGNAL_STRENGTH_CHANGED, strengthBin); 5252 } else { 5253 stopAllPhoneSignalStrengthTimersLocked(-1); 5254 } 5255 mPhoneSignalStrengthBin = strengthBin; 5256 } 5257 5258 if (newHistory) { 5259 addHistoryRecordLocked(elapsedRealtime, uptime); 5260 } 5261 } 5262 5263 /** 5264 * Telephony stack updates the phone state. 5265 * @param state phone state from ServiceState.getState() 5266 */ notePhoneStateLocked(int state, int simState)5267 public void notePhoneStateLocked(int state, int simState) { 5268 updateAllPhoneStateLocked(state, simState, mPhoneSignalStrengthBinRaw); 5269 } 5270 5271 @UnsupportedAppUsage notePhoneSignalStrengthLocked(SignalStrength signalStrength)5272 public void notePhoneSignalStrengthLocked(SignalStrength signalStrength) { 5273 // Bin the strength. 5274 int bin = signalStrength.getLevel(); 5275 updateAllPhoneStateLocked(mPhoneServiceStateRaw, mPhoneSimStateRaw, bin); 5276 } 5277 5278 @UnsupportedAppUsage notePhoneDataConnectionStateLocked(int dataType, boolean hasData, int serviceType)5279 public void notePhoneDataConnectionStateLocked(int dataType, boolean hasData, int serviceType) { 5280 // BatteryStats uses 0 to represent no network type. 5281 // Telephony does not have a concept of no network type, and uses 0 to represent unknown. 5282 // Unknown is included in DATA_CONNECTION_OTHER. 5283 int bin = DATA_CONNECTION_OUT_OF_SERVICE; 5284 if (hasData) { 5285 if (dataType > 0 && dataType <= TelephonyManager.getAllNetworkTypes().length) { 5286 bin = dataType; 5287 } else { 5288 switch (serviceType) { 5289 case ServiceState.STATE_OUT_OF_SERVICE: 5290 bin = DATA_CONNECTION_OUT_OF_SERVICE; 5291 break; 5292 case ServiceState.STATE_EMERGENCY_ONLY: 5293 bin = DATA_CONNECTION_EMERGENCY_SERVICE; 5294 break; 5295 default: 5296 bin = DATA_CONNECTION_OTHER; 5297 break; 5298 } 5299 } 5300 } 5301 if (DEBUG) Log.i(TAG, "Phone Data Connection -> " + dataType + " = " + hasData); 5302 if (mPhoneDataConnectionType != bin) { 5303 final long elapsedRealtime = mClocks.elapsedRealtime(); 5304 final long uptime = mClocks.uptimeMillis(); 5305 mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_DATA_CONNECTION_MASK) 5306 | (bin << HistoryItem.STATE_DATA_CONNECTION_SHIFT); 5307 if (DEBUG_HISTORY) Slog.v(TAG, "Data connection " + bin + " to: " 5308 + Integer.toHexString(mHistoryCur.states)); 5309 addHistoryRecordLocked(elapsedRealtime, uptime); 5310 if (mPhoneDataConnectionType >= 0) { 5311 mPhoneDataConnectionsTimer[mPhoneDataConnectionType].stopRunningLocked( 5312 elapsedRealtime); 5313 } 5314 mPhoneDataConnectionType = bin; 5315 mPhoneDataConnectionsTimer[bin].startRunningLocked(elapsedRealtime); 5316 } 5317 } 5318 noteWifiOnLocked()5319 public void noteWifiOnLocked() { 5320 if (!mWifiOn) { 5321 final long elapsedRealtime = mClocks.elapsedRealtime(); 5322 final long uptime = mClocks.uptimeMillis(); 5323 mHistoryCur.states2 |= HistoryItem.STATE2_WIFI_ON_FLAG; 5324 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI on to: " 5325 + Integer.toHexString(mHistoryCur.states)); 5326 addHistoryRecordLocked(elapsedRealtime, uptime); 5327 mWifiOn = true; 5328 mWifiOnTimer.startRunningLocked(elapsedRealtime); 5329 scheduleSyncExternalStatsLocked("wifi-off", ExternalStatsSync.UPDATE_WIFI); 5330 } 5331 } 5332 noteWifiOffLocked()5333 public void noteWifiOffLocked() { 5334 final long elapsedRealtime = mClocks.elapsedRealtime(); 5335 final long uptime = mClocks.uptimeMillis(); 5336 if (mWifiOn) { 5337 mHistoryCur.states2 &= ~HistoryItem.STATE2_WIFI_ON_FLAG; 5338 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI off to: " 5339 + Integer.toHexString(mHistoryCur.states)); 5340 addHistoryRecordLocked(elapsedRealtime, uptime); 5341 mWifiOn = false; 5342 mWifiOnTimer.stopRunningLocked(elapsedRealtime); 5343 scheduleSyncExternalStatsLocked("wifi-on", ExternalStatsSync.UPDATE_WIFI); 5344 } 5345 } 5346 5347 @UnsupportedAppUsage noteAudioOnLocked(int uid)5348 public void noteAudioOnLocked(int uid) { 5349 uid = mapUid(uid); 5350 final long elapsedRealtime = mClocks.elapsedRealtime(); 5351 final long uptime = mClocks.uptimeMillis(); 5352 if (mAudioOnNesting == 0) { 5353 mHistoryCur.states |= HistoryItem.STATE_AUDIO_ON_FLAG; 5354 if (DEBUG_HISTORY) Slog.v(TAG, "Audio on to: " 5355 + Integer.toHexString(mHistoryCur.states)); 5356 addHistoryRecordLocked(elapsedRealtime, uptime); 5357 mAudioOnTimer.startRunningLocked(elapsedRealtime); 5358 } 5359 mAudioOnNesting++; 5360 getUidStatsLocked(uid).noteAudioTurnedOnLocked(elapsedRealtime); 5361 } 5362 5363 @UnsupportedAppUsage noteAudioOffLocked(int uid)5364 public void noteAudioOffLocked(int uid) { 5365 if (mAudioOnNesting == 0) { 5366 return; 5367 } 5368 uid = mapUid(uid); 5369 final long elapsedRealtime = mClocks.elapsedRealtime(); 5370 final long uptime = mClocks.uptimeMillis(); 5371 if (--mAudioOnNesting == 0) { 5372 mHistoryCur.states &= ~HistoryItem.STATE_AUDIO_ON_FLAG; 5373 if (DEBUG_HISTORY) Slog.v(TAG, "Audio off to: " 5374 + Integer.toHexString(mHistoryCur.states)); 5375 addHistoryRecordLocked(elapsedRealtime, uptime); 5376 mAudioOnTimer.stopRunningLocked(elapsedRealtime); 5377 } 5378 getUidStatsLocked(uid).noteAudioTurnedOffLocked(elapsedRealtime); 5379 } 5380 5381 @UnsupportedAppUsage noteVideoOnLocked(int uid)5382 public void noteVideoOnLocked(int uid) { 5383 uid = mapUid(uid); 5384 final long elapsedRealtime = mClocks.elapsedRealtime(); 5385 final long uptime = mClocks.uptimeMillis(); 5386 if (mVideoOnNesting == 0) { 5387 mHistoryCur.states2 |= HistoryItem.STATE2_VIDEO_ON_FLAG; 5388 if (DEBUG_HISTORY) Slog.v(TAG, "Video on to: " 5389 + Integer.toHexString(mHistoryCur.states)); 5390 addHistoryRecordLocked(elapsedRealtime, uptime); 5391 mVideoOnTimer.startRunningLocked(elapsedRealtime); 5392 } 5393 mVideoOnNesting++; 5394 getUidStatsLocked(uid).noteVideoTurnedOnLocked(elapsedRealtime); 5395 } 5396 5397 @UnsupportedAppUsage noteVideoOffLocked(int uid)5398 public void noteVideoOffLocked(int uid) { 5399 if (mVideoOnNesting == 0) { 5400 return; 5401 } 5402 uid = mapUid(uid); 5403 final long elapsedRealtime = mClocks.elapsedRealtime(); 5404 final long uptime = mClocks.uptimeMillis(); 5405 if (--mVideoOnNesting == 0) { 5406 mHistoryCur.states2 &= ~HistoryItem.STATE2_VIDEO_ON_FLAG; 5407 if (DEBUG_HISTORY) Slog.v(TAG, "Video off to: " 5408 + Integer.toHexString(mHistoryCur.states)); 5409 addHistoryRecordLocked(elapsedRealtime, uptime); 5410 mVideoOnTimer.stopRunningLocked(elapsedRealtime); 5411 } 5412 getUidStatsLocked(uid).noteVideoTurnedOffLocked(elapsedRealtime); 5413 } 5414 noteResetAudioLocked()5415 public void noteResetAudioLocked() { 5416 if (mAudioOnNesting > 0) { 5417 final long elapsedRealtime = mClocks.elapsedRealtime(); 5418 final long uptime = mClocks.uptimeMillis(); 5419 mAudioOnNesting = 0; 5420 mHistoryCur.states &= ~HistoryItem.STATE_AUDIO_ON_FLAG; 5421 if (DEBUG_HISTORY) Slog.v(TAG, "Audio off to: " 5422 + Integer.toHexString(mHistoryCur.states)); 5423 addHistoryRecordLocked(elapsedRealtime, uptime); 5424 mAudioOnTimer.stopAllRunningLocked(elapsedRealtime); 5425 for (int i=0; i<mUidStats.size(); i++) { 5426 BatteryStatsImpl.Uid uid = mUidStats.valueAt(i); 5427 uid.noteResetAudioLocked(elapsedRealtime); 5428 } 5429 } 5430 } 5431 noteResetVideoLocked()5432 public void noteResetVideoLocked() { 5433 if (mVideoOnNesting > 0) { 5434 final long elapsedRealtime = mClocks.elapsedRealtime(); 5435 final long uptime = mClocks.uptimeMillis(); 5436 mAudioOnNesting = 0; 5437 mHistoryCur.states2 &= ~HistoryItem.STATE2_VIDEO_ON_FLAG; 5438 if (DEBUG_HISTORY) Slog.v(TAG, "Video off to: " 5439 + Integer.toHexString(mHistoryCur.states)); 5440 addHistoryRecordLocked(elapsedRealtime, uptime); 5441 mVideoOnTimer.stopAllRunningLocked(elapsedRealtime); 5442 for (int i=0; i<mUidStats.size(); i++) { 5443 BatteryStatsImpl.Uid uid = mUidStats.valueAt(i); 5444 uid.noteResetVideoLocked(elapsedRealtime); 5445 } 5446 } 5447 } 5448 noteActivityResumedLocked(int uid)5449 public void noteActivityResumedLocked(int uid) { 5450 uid = mapUid(uid); 5451 getUidStatsLocked(uid).noteActivityResumedLocked(mClocks.elapsedRealtime()); 5452 } 5453 noteActivityPausedLocked(int uid)5454 public void noteActivityPausedLocked(int uid) { 5455 uid = mapUid(uid); 5456 getUidStatsLocked(uid).noteActivityPausedLocked(mClocks.elapsedRealtime()); 5457 } 5458 noteVibratorOnLocked(int uid, long durationMillis)5459 public void noteVibratorOnLocked(int uid, long durationMillis) { 5460 uid = mapUid(uid); 5461 getUidStatsLocked(uid).noteVibratorOnLocked(durationMillis); 5462 } 5463 noteVibratorOffLocked(int uid)5464 public void noteVibratorOffLocked(int uid) { 5465 uid = mapUid(uid); 5466 getUidStatsLocked(uid).noteVibratorOffLocked(); 5467 } 5468 noteFlashlightOnLocked(int uid)5469 public void noteFlashlightOnLocked(int uid) { 5470 uid = mapUid(uid); 5471 final long elapsedRealtime = mClocks.elapsedRealtime(); 5472 final long uptime = mClocks.uptimeMillis(); 5473 if (mFlashlightOnNesting++ == 0) { 5474 mHistoryCur.states2 |= HistoryItem.STATE2_FLASHLIGHT_FLAG; 5475 if (DEBUG_HISTORY) Slog.v(TAG, "Flashlight on to: " 5476 + Integer.toHexString(mHistoryCur.states2)); 5477 addHistoryRecordLocked(elapsedRealtime, uptime); 5478 mFlashlightOnTimer.startRunningLocked(elapsedRealtime); 5479 } 5480 getUidStatsLocked(uid).noteFlashlightTurnedOnLocked(elapsedRealtime); 5481 } 5482 noteFlashlightOffLocked(int uid)5483 public void noteFlashlightOffLocked(int uid) { 5484 if (mFlashlightOnNesting == 0) { 5485 return; 5486 } 5487 uid = mapUid(uid); 5488 final long elapsedRealtime = mClocks.elapsedRealtime(); 5489 final long uptime = mClocks.uptimeMillis(); 5490 if (--mFlashlightOnNesting == 0) { 5491 mHistoryCur.states2 &= ~HistoryItem.STATE2_FLASHLIGHT_FLAG; 5492 if (DEBUG_HISTORY) Slog.v(TAG, "Flashlight off to: " 5493 + Integer.toHexString(mHistoryCur.states2)); 5494 addHistoryRecordLocked(elapsedRealtime, uptime); 5495 mFlashlightOnTimer.stopRunningLocked(elapsedRealtime); 5496 } 5497 getUidStatsLocked(uid).noteFlashlightTurnedOffLocked(elapsedRealtime); 5498 } 5499 noteCameraOnLocked(int uid)5500 public void noteCameraOnLocked(int uid) { 5501 uid = mapUid(uid); 5502 final long elapsedRealtime = mClocks.elapsedRealtime(); 5503 final long uptime = mClocks.uptimeMillis(); 5504 if (mCameraOnNesting++ == 0) { 5505 mHistoryCur.states2 |= HistoryItem.STATE2_CAMERA_FLAG; 5506 if (DEBUG_HISTORY) Slog.v(TAG, "Camera on to: " 5507 + Integer.toHexString(mHistoryCur.states2)); 5508 addHistoryRecordLocked(elapsedRealtime, uptime); 5509 mCameraOnTimer.startRunningLocked(elapsedRealtime); 5510 } 5511 getUidStatsLocked(uid).noteCameraTurnedOnLocked(elapsedRealtime); 5512 } 5513 noteCameraOffLocked(int uid)5514 public void noteCameraOffLocked(int uid) { 5515 if (mCameraOnNesting == 0) { 5516 return; 5517 } 5518 uid = mapUid(uid); 5519 final long elapsedRealtime = mClocks.elapsedRealtime(); 5520 final long uptime = mClocks.uptimeMillis(); 5521 if (--mCameraOnNesting == 0) { 5522 mHistoryCur.states2 &= ~HistoryItem.STATE2_CAMERA_FLAG; 5523 if (DEBUG_HISTORY) Slog.v(TAG, "Camera off to: " 5524 + Integer.toHexString(mHistoryCur.states2)); 5525 addHistoryRecordLocked(elapsedRealtime, uptime); 5526 mCameraOnTimer.stopRunningLocked(elapsedRealtime); 5527 } 5528 getUidStatsLocked(uid).noteCameraTurnedOffLocked(elapsedRealtime); 5529 } 5530 noteResetCameraLocked()5531 public void noteResetCameraLocked() { 5532 if (mCameraOnNesting > 0) { 5533 final long elapsedRealtime = mClocks.elapsedRealtime(); 5534 final long uptime = mClocks.uptimeMillis(); 5535 mCameraOnNesting = 0; 5536 mHistoryCur.states2 &= ~HistoryItem.STATE2_CAMERA_FLAG; 5537 if (DEBUG_HISTORY) Slog.v(TAG, "Camera off to: " 5538 + Integer.toHexString(mHistoryCur.states2)); 5539 addHistoryRecordLocked(elapsedRealtime, uptime); 5540 mCameraOnTimer.stopAllRunningLocked(elapsedRealtime); 5541 for (int i=0; i<mUidStats.size(); i++) { 5542 BatteryStatsImpl.Uid uid = mUidStats.valueAt(i); 5543 uid.noteResetCameraLocked(elapsedRealtime); 5544 } 5545 } 5546 } 5547 noteResetFlashlightLocked()5548 public void noteResetFlashlightLocked() { 5549 if (mFlashlightOnNesting > 0) { 5550 final long elapsedRealtime = mClocks.elapsedRealtime(); 5551 final long uptime = mClocks.uptimeMillis(); 5552 mFlashlightOnNesting = 0; 5553 mHistoryCur.states2 &= ~HistoryItem.STATE2_FLASHLIGHT_FLAG; 5554 if (DEBUG_HISTORY) Slog.v(TAG, "Flashlight off to: " 5555 + Integer.toHexString(mHistoryCur.states2)); 5556 addHistoryRecordLocked(elapsedRealtime, uptime); 5557 mFlashlightOnTimer.stopAllRunningLocked(elapsedRealtime); 5558 for (int i=0; i<mUidStats.size(); i++) { 5559 BatteryStatsImpl.Uid uid = mUidStats.valueAt(i); 5560 uid.noteResetFlashlightLocked(elapsedRealtime); 5561 } 5562 } 5563 } 5564 noteBluetoothScanStartedLocked(WorkChain workChain, int uid, boolean isUnoptimized)5565 private void noteBluetoothScanStartedLocked(WorkChain workChain, int uid, 5566 boolean isUnoptimized) { 5567 uid = getAttributionUid(uid, workChain); 5568 final long elapsedRealtime = mClocks.elapsedRealtime(); 5569 final long uptime = mClocks.uptimeMillis(); 5570 if (mBluetoothScanNesting == 0) { 5571 mHistoryCur.states2 |= HistoryItem.STATE2_BLUETOOTH_SCAN_FLAG; 5572 if (DEBUG_HISTORY) Slog.v(TAG, "BLE scan started for: " 5573 + Integer.toHexString(mHistoryCur.states2)); 5574 addHistoryRecordLocked(elapsedRealtime, uptime); 5575 mBluetoothScanTimer.startRunningLocked(elapsedRealtime); 5576 } 5577 mBluetoothScanNesting++; 5578 getUidStatsLocked(uid).noteBluetoothScanStartedLocked(elapsedRealtime, isUnoptimized); 5579 } 5580 noteBluetoothScanStartedFromSourceLocked(WorkSource ws, boolean isUnoptimized)5581 public void noteBluetoothScanStartedFromSourceLocked(WorkSource ws, boolean isUnoptimized) { 5582 final int N = ws.size(); 5583 for (int i = 0; i < N; i++) { 5584 noteBluetoothScanStartedLocked(null, ws.getUid(i), isUnoptimized); 5585 } 5586 5587 final List<WorkChain> workChains = ws.getWorkChains(); 5588 if (workChains != null) { 5589 for (int i = 0; i < workChains.size(); ++i) { 5590 noteBluetoothScanStartedLocked(workChains.get(i), -1, isUnoptimized); 5591 } 5592 } 5593 } 5594 noteBluetoothScanStoppedLocked(WorkChain workChain, int uid, boolean isUnoptimized)5595 private void noteBluetoothScanStoppedLocked(WorkChain workChain, int uid, 5596 boolean isUnoptimized) { 5597 uid = getAttributionUid(uid, workChain); 5598 final long elapsedRealtime = mClocks.elapsedRealtime(); 5599 final long uptime = mClocks.uptimeMillis(); 5600 mBluetoothScanNesting--; 5601 if (mBluetoothScanNesting == 0) { 5602 mHistoryCur.states2 &= ~HistoryItem.STATE2_BLUETOOTH_SCAN_FLAG; 5603 if (DEBUG_HISTORY) Slog.v(TAG, "BLE scan stopped for: " 5604 + Integer.toHexString(mHistoryCur.states2)); 5605 addHistoryRecordLocked(elapsedRealtime, uptime); 5606 mBluetoothScanTimer.stopRunningLocked(elapsedRealtime); 5607 } 5608 getUidStatsLocked(uid).noteBluetoothScanStoppedLocked(elapsedRealtime, isUnoptimized); 5609 } 5610 getAttributionUid(int uid, WorkChain workChain)5611 private int getAttributionUid(int uid, WorkChain workChain) { 5612 if (workChain != null) { 5613 return mapUid(workChain.getAttributionUid()); 5614 } 5615 5616 return mapUid(uid); 5617 } 5618 noteBluetoothScanStoppedFromSourceLocked(WorkSource ws, boolean isUnoptimized)5619 public void noteBluetoothScanStoppedFromSourceLocked(WorkSource ws, boolean isUnoptimized) { 5620 final int N = ws.size(); 5621 for (int i = 0; i < N; i++) { 5622 noteBluetoothScanStoppedLocked(null, ws.getUid(i), isUnoptimized); 5623 } 5624 5625 final List<WorkChain> workChains = ws.getWorkChains(); 5626 if (workChains != null) { 5627 for (int i = 0; i < workChains.size(); ++i) { 5628 noteBluetoothScanStoppedLocked(workChains.get(i), -1, isUnoptimized); 5629 } 5630 } 5631 } 5632 noteResetBluetoothScanLocked()5633 public void noteResetBluetoothScanLocked() { 5634 if (mBluetoothScanNesting > 0) { 5635 final long elapsedRealtime = mClocks.elapsedRealtime(); 5636 final long uptime = mClocks.uptimeMillis(); 5637 mBluetoothScanNesting = 0; 5638 mHistoryCur.states2 &= ~HistoryItem.STATE2_BLUETOOTH_SCAN_FLAG; 5639 if (DEBUG_HISTORY) Slog.v(TAG, "BLE can stopped for: " 5640 + Integer.toHexString(mHistoryCur.states2)); 5641 addHistoryRecordLocked(elapsedRealtime, uptime); 5642 mBluetoothScanTimer.stopAllRunningLocked(elapsedRealtime); 5643 for (int i=0; i<mUidStats.size(); i++) { 5644 BatteryStatsImpl.Uid uid = mUidStats.valueAt(i); 5645 uid.noteResetBluetoothScanLocked(elapsedRealtime); 5646 } 5647 } 5648 } 5649 noteBluetoothScanResultsFromSourceLocked(WorkSource ws, int numNewResults)5650 public void noteBluetoothScanResultsFromSourceLocked(WorkSource ws, int numNewResults) { 5651 final int N = ws.size(); 5652 for (int i = 0; i < N; i++) { 5653 int uid = mapUid(ws.getUid(i)); 5654 getUidStatsLocked(uid).noteBluetoothScanResultsLocked(numNewResults); 5655 } 5656 5657 final List<WorkChain> workChains = ws.getWorkChains(); 5658 if (workChains != null) { 5659 for (int i = 0; i < workChains.size(); ++i) { 5660 final WorkChain wc = workChains.get(i); 5661 int uid = mapUid(wc.getAttributionUid()); 5662 getUidStatsLocked(uid).noteBluetoothScanResultsLocked(numNewResults); 5663 } 5664 } 5665 } 5666 noteWifiRadioApWakeupLocked(final long elapsedRealtimeMillis, final long uptimeMillis, int uid)5667 private void noteWifiRadioApWakeupLocked(final long elapsedRealtimeMillis, 5668 final long uptimeMillis, int uid) { 5669 uid = mapUid(uid); 5670 addHistoryEventLocked(elapsedRealtimeMillis, uptimeMillis, HistoryItem.EVENT_WAKEUP_AP, "", 5671 uid); 5672 getUidStatsLocked(uid).noteWifiRadioApWakeupLocked(); 5673 } 5674 noteWifiRadioPowerState(int powerState, long timestampNs, int uid)5675 public void noteWifiRadioPowerState(int powerState, long timestampNs, int uid) { 5676 final long elapsedRealtime = mClocks.elapsedRealtime(); 5677 final long uptime = mClocks.uptimeMillis(); 5678 if (mWifiRadioPowerState != powerState) { 5679 final boolean active = 5680 powerState == DataConnectionRealTimeInfo.DC_POWER_STATE_MEDIUM 5681 || powerState == DataConnectionRealTimeInfo.DC_POWER_STATE_HIGH; 5682 if (active) { 5683 if (uid > 0) { 5684 noteWifiRadioApWakeupLocked(elapsedRealtime, uptime, uid); 5685 } 5686 mHistoryCur.states |= HistoryItem.STATE_WIFI_RADIO_ACTIVE_FLAG; 5687 mWifiActiveTimer.startRunningLocked(elapsedRealtime); 5688 } else { 5689 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_RADIO_ACTIVE_FLAG; 5690 mWifiActiveTimer.stopRunningLocked( 5691 timestampNs / (1000 * 1000)); 5692 } 5693 if (DEBUG_HISTORY) Slog.v(TAG, "Wifi network active " + active + " to: " 5694 + Integer.toHexString(mHistoryCur.states)); 5695 addHistoryRecordLocked(elapsedRealtime, uptime); 5696 mWifiRadioPowerState = powerState; 5697 } 5698 } 5699 noteWifiRunningLocked(WorkSource ws)5700 public void noteWifiRunningLocked(WorkSource ws) { 5701 if (!mGlobalWifiRunning) { 5702 final long elapsedRealtime = mClocks.elapsedRealtime(); 5703 final long uptime = mClocks.uptimeMillis(); 5704 mHistoryCur.states2 |= HistoryItem.STATE2_WIFI_RUNNING_FLAG; 5705 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI running to: " 5706 + Integer.toHexString(mHistoryCur.states)); 5707 addHistoryRecordLocked(elapsedRealtime, uptime); 5708 mGlobalWifiRunning = true; 5709 mGlobalWifiRunningTimer.startRunningLocked(elapsedRealtime); 5710 int N = ws.size(); 5711 for (int i=0; i<N; i++) { 5712 int uid = mapUid(ws.getUid(i)); 5713 getUidStatsLocked(uid).noteWifiRunningLocked(elapsedRealtime); 5714 } 5715 5716 List<WorkChain> workChains = ws.getWorkChains(); 5717 if (workChains != null) { 5718 for (int i = 0; i < workChains.size(); ++i) { 5719 int uid = mapUid(workChains.get(i).getAttributionUid()); 5720 getUidStatsLocked(uid).noteWifiRunningLocked(elapsedRealtime); 5721 } 5722 } 5723 5724 scheduleSyncExternalStatsLocked("wifi-running", ExternalStatsSync.UPDATE_WIFI); 5725 } else { 5726 Log.w(TAG, "noteWifiRunningLocked -- called while WIFI running"); 5727 } 5728 } 5729 noteWifiRunningChangedLocked(WorkSource oldWs, WorkSource newWs)5730 public void noteWifiRunningChangedLocked(WorkSource oldWs, WorkSource newWs) { 5731 if (mGlobalWifiRunning) { 5732 final long elapsedRealtime = mClocks.elapsedRealtime(); 5733 int N = oldWs.size(); 5734 for (int i=0; i<N; i++) { 5735 int uid = mapUid(oldWs.getUid(i)); 5736 getUidStatsLocked(uid).noteWifiStoppedLocked(elapsedRealtime); 5737 } 5738 5739 List<WorkChain> workChains = oldWs.getWorkChains(); 5740 if (workChains != null) { 5741 for (int i = 0; i < workChains.size(); ++i) { 5742 int uid = mapUid(workChains.get(i).getAttributionUid()); 5743 getUidStatsLocked(uid).noteWifiStoppedLocked(elapsedRealtime); 5744 } 5745 } 5746 5747 N = newWs.size(); 5748 for (int i=0; i<N; i++) { 5749 int uid = mapUid(newWs.getUid(i)); 5750 getUidStatsLocked(uid).noteWifiRunningLocked(elapsedRealtime); 5751 } 5752 5753 workChains = newWs.getWorkChains(); 5754 if (workChains != null) { 5755 for (int i = 0; i < workChains.size(); ++i) { 5756 int uid = mapUid(workChains.get(i).getAttributionUid()); 5757 getUidStatsLocked(uid).noteWifiRunningLocked(elapsedRealtime); 5758 } 5759 } 5760 } else { 5761 Log.w(TAG, "noteWifiRunningChangedLocked -- called while WIFI not running"); 5762 } 5763 } 5764 noteWifiStoppedLocked(WorkSource ws)5765 public void noteWifiStoppedLocked(WorkSource ws) { 5766 if (mGlobalWifiRunning) { 5767 final long elapsedRealtime = mClocks.elapsedRealtime(); 5768 final long uptime = mClocks.uptimeMillis(); 5769 mHistoryCur.states2 &= ~HistoryItem.STATE2_WIFI_RUNNING_FLAG; 5770 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI stopped to: " 5771 + Integer.toHexString(mHistoryCur.states)); 5772 addHistoryRecordLocked(elapsedRealtime, uptime); 5773 mGlobalWifiRunning = false; 5774 mGlobalWifiRunningTimer.stopRunningLocked(elapsedRealtime); 5775 int N = ws.size(); 5776 for (int i=0; i<N; i++) { 5777 int uid = mapUid(ws.getUid(i)); 5778 getUidStatsLocked(uid).noteWifiStoppedLocked(elapsedRealtime); 5779 } 5780 5781 List<WorkChain> workChains = ws.getWorkChains(); 5782 if (workChains != null) { 5783 for (int i = 0; i < workChains.size(); ++i) { 5784 int uid = mapUid(workChains.get(i).getAttributionUid()); 5785 getUidStatsLocked(uid).noteWifiStoppedLocked(elapsedRealtime); 5786 } 5787 } 5788 5789 scheduleSyncExternalStatsLocked("wifi-stopped", ExternalStatsSync.UPDATE_WIFI); 5790 } else { 5791 Log.w(TAG, "noteWifiStoppedLocked -- called while WIFI not running"); 5792 } 5793 } 5794 noteWifiStateLocked(int wifiState, String accessPoint)5795 public void noteWifiStateLocked(int wifiState, String accessPoint) { 5796 if (DEBUG) Log.i(TAG, "WiFi state -> " + wifiState); 5797 if (mWifiState != wifiState) { 5798 final long elapsedRealtime = mClocks.elapsedRealtime(); 5799 if (mWifiState >= 0) { 5800 mWifiStateTimer[mWifiState].stopRunningLocked(elapsedRealtime); 5801 } 5802 mWifiState = wifiState; 5803 mWifiStateTimer[wifiState].startRunningLocked(elapsedRealtime); 5804 scheduleSyncExternalStatsLocked("wifi-state", ExternalStatsSync.UPDATE_WIFI); 5805 } 5806 } 5807 noteWifiSupplicantStateChangedLocked(int supplState, boolean failedAuth)5808 public void noteWifiSupplicantStateChangedLocked(int supplState, boolean failedAuth) { 5809 if (DEBUG) Log.i(TAG, "WiFi suppl state -> " + supplState); 5810 if (mWifiSupplState != supplState) { 5811 final long elapsedRealtime = mClocks.elapsedRealtime(); 5812 final long uptime = mClocks.uptimeMillis(); 5813 if (mWifiSupplState >= 0) { 5814 mWifiSupplStateTimer[mWifiSupplState].stopRunningLocked(elapsedRealtime); 5815 } 5816 mWifiSupplState = supplState; 5817 mWifiSupplStateTimer[supplState].startRunningLocked(elapsedRealtime); 5818 mHistoryCur.states2 = 5819 (mHistoryCur.states2&~HistoryItem.STATE2_WIFI_SUPPL_STATE_MASK) 5820 | (supplState << HistoryItem.STATE2_WIFI_SUPPL_STATE_SHIFT); 5821 if (DEBUG_HISTORY) Slog.v(TAG, "Wifi suppl state " + supplState + " to: " 5822 + Integer.toHexString(mHistoryCur.states2)); 5823 addHistoryRecordLocked(elapsedRealtime, uptime); 5824 } 5825 } 5826 stopAllWifiSignalStrengthTimersLocked(int except)5827 void stopAllWifiSignalStrengthTimersLocked(int except) { 5828 final long elapsedRealtime = mClocks.elapsedRealtime(); 5829 for (int i = 0; i < NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { 5830 if (i == except) { 5831 continue; 5832 } 5833 while (mWifiSignalStrengthsTimer[i].isRunningLocked()) { 5834 mWifiSignalStrengthsTimer[i].stopRunningLocked(elapsedRealtime); 5835 } 5836 } 5837 } 5838 noteWifiRssiChangedLocked(int newRssi)5839 public void noteWifiRssiChangedLocked(int newRssi) { 5840 int strengthBin = WifiManager.calculateSignalLevel(newRssi, NUM_WIFI_SIGNAL_STRENGTH_BINS); 5841 if (DEBUG) Log.i(TAG, "WiFi rssi -> " + newRssi + " bin=" + strengthBin); 5842 if (mWifiSignalStrengthBin != strengthBin) { 5843 final long elapsedRealtime = mClocks.elapsedRealtime(); 5844 final long uptime = mClocks.uptimeMillis(); 5845 if (mWifiSignalStrengthBin >= 0) { 5846 mWifiSignalStrengthsTimer[mWifiSignalStrengthBin].stopRunningLocked( 5847 elapsedRealtime); 5848 } 5849 if (strengthBin >= 0) { 5850 if (!mWifiSignalStrengthsTimer[strengthBin].isRunningLocked()) { 5851 mWifiSignalStrengthsTimer[strengthBin].startRunningLocked(elapsedRealtime); 5852 } 5853 mHistoryCur.states2 = 5854 (mHistoryCur.states2&~HistoryItem.STATE2_WIFI_SIGNAL_STRENGTH_MASK) 5855 | (strengthBin << HistoryItem.STATE2_WIFI_SIGNAL_STRENGTH_SHIFT); 5856 if (DEBUG_HISTORY) Slog.v(TAG, "Wifi signal strength " + strengthBin + " to: " 5857 + Integer.toHexString(mHistoryCur.states2)); 5858 addHistoryRecordLocked(elapsedRealtime, uptime); 5859 } else { 5860 stopAllWifiSignalStrengthTimersLocked(-1); 5861 } 5862 mWifiSignalStrengthBin = strengthBin; 5863 } 5864 } 5865 5866 int mWifiFullLockNesting = 0; 5867 5868 @UnsupportedAppUsage noteFullWifiLockAcquiredLocked(int uid)5869 public void noteFullWifiLockAcquiredLocked(int uid) { 5870 final long elapsedRealtime = mClocks.elapsedRealtime(); 5871 final long uptime = mClocks.uptimeMillis(); 5872 if (mWifiFullLockNesting == 0) { 5873 mHistoryCur.states |= HistoryItem.STATE_WIFI_FULL_LOCK_FLAG; 5874 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI full lock on to: " 5875 + Integer.toHexString(mHistoryCur.states)); 5876 addHistoryRecordLocked(elapsedRealtime, uptime); 5877 } 5878 mWifiFullLockNesting++; 5879 getUidStatsLocked(uid).noteFullWifiLockAcquiredLocked(elapsedRealtime); 5880 } 5881 5882 @UnsupportedAppUsage noteFullWifiLockReleasedLocked(int uid)5883 public void noteFullWifiLockReleasedLocked(int uid) { 5884 final long elapsedRealtime = mClocks.elapsedRealtime(); 5885 final long uptime = mClocks.uptimeMillis(); 5886 mWifiFullLockNesting--; 5887 if (mWifiFullLockNesting == 0) { 5888 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_FULL_LOCK_FLAG; 5889 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI full lock off to: " 5890 + Integer.toHexString(mHistoryCur.states)); 5891 addHistoryRecordLocked(elapsedRealtime, uptime); 5892 } 5893 getUidStatsLocked(uid).noteFullWifiLockReleasedLocked(elapsedRealtime); 5894 } 5895 5896 int mWifiScanNesting = 0; 5897 noteWifiScanStartedLocked(int uid)5898 public void noteWifiScanStartedLocked(int uid) { 5899 final long elapsedRealtime = mClocks.elapsedRealtime(); 5900 final long uptime = mClocks.uptimeMillis(); 5901 if (mWifiScanNesting == 0) { 5902 mHistoryCur.states |= HistoryItem.STATE_WIFI_SCAN_FLAG; 5903 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI scan started for: " 5904 + Integer.toHexString(mHistoryCur.states)); 5905 addHistoryRecordLocked(elapsedRealtime, uptime); 5906 } 5907 mWifiScanNesting++; 5908 getUidStatsLocked(uid).noteWifiScanStartedLocked(elapsedRealtime); 5909 } 5910 noteWifiScanStoppedLocked(int uid)5911 public void noteWifiScanStoppedLocked(int uid) { 5912 final long elapsedRealtime = mClocks.elapsedRealtime(); 5913 final long uptime = mClocks.uptimeMillis(); 5914 mWifiScanNesting--; 5915 if (mWifiScanNesting == 0) { 5916 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_SCAN_FLAG; 5917 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI scan stopped for: " 5918 + Integer.toHexString(mHistoryCur.states)); 5919 addHistoryRecordLocked(elapsedRealtime, uptime); 5920 } 5921 getUidStatsLocked(uid).noteWifiScanStoppedLocked(elapsedRealtime); 5922 } 5923 noteWifiBatchedScanStartedLocked(int uid, int csph)5924 public void noteWifiBatchedScanStartedLocked(int uid, int csph) { 5925 uid = mapUid(uid); 5926 final long elapsedRealtime = mClocks.elapsedRealtime(); 5927 getUidStatsLocked(uid).noteWifiBatchedScanStartedLocked(csph, elapsedRealtime); 5928 } 5929 noteWifiBatchedScanStoppedLocked(int uid)5930 public void noteWifiBatchedScanStoppedLocked(int uid) { 5931 uid = mapUid(uid); 5932 final long elapsedRealtime = mClocks.elapsedRealtime(); 5933 getUidStatsLocked(uid).noteWifiBatchedScanStoppedLocked(elapsedRealtime); 5934 } 5935 5936 int mWifiMulticastNesting = 0; 5937 5938 @UnsupportedAppUsage noteWifiMulticastEnabledLocked(int uid)5939 public void noteWifiMulticastEnabledLocked(int uid) { 5940 uid = mapUid(uid); 5941 final long elapsedRealtime = mClocks.elapsedRealtime(); 5942 final long uptime = mClocks.uptimeMillis(); 5943 if (mWifiMulticastNesting == 0) { 5944 mHistoryCur.states |= HistoryItem.STATE_WIFI_MULTICAST_ON_FLAG; 5945 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI multicast on to: " 5946 + Integer.toHexString(mHistoryCur.states)); 5947 addHistoryRecordLocked(elapsedRealtime, uptime); 5948 5949 // Start Wifi Multicast overall timer 5950 if (!mWifiMulticastWakelockTimer.isRunningLocked()) { 5951 if (DEBUG_HISTORY) Slog.v(TAG, "WiFi Multicast Overall Timer Started"); 5952 mWifiMulticastWakelockTimer.startRunningLocked(elapsedRealtime); 5953 } 5954 } 5955 mWifiMulticastNesting++; 5956 getUidStatsLocked(uid).noteWifiMulticastEnabledLocked(elapsedRealtime); 5957 } 5958 5959 @UnsupportedAppUsage noteWifiMulticastDisabledLocked(int uid)5960 public void noteWifiMulticastDisabledLocked(int uid) { 5961 uid = mapUid(uid); 5962 final long elapsedRealtime = mClocks.elapsedRealtime(); 5963 final long uptime = mClocks.uptimeMillis(); 5964 mWifiMulticastNesting--; 5965 if (mWifiMulticastNesting == 0) { 5966 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_MULTICAST_ON_FLAG; 5967 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI multicast off to: " 5968 + Integer.toHexString(mHistoryCur.states)); 5969 addHistoryRecordLocked(elapsedRealtime, uptime); 5970 5971 // Stop Wifi Multicast overall timer 5972 if (mWifiMulticastWakelockTimer.isRunningLocked()) { 5973 if (DEBUG_HISTORY) Slog.v(TAG, "Multicast Overall Timer Stopped"); 5974 mWifiMulticastWakelockTimer.stopRunningLocked(elapsedRealtime); 5975 } 5976 } 5977 getUidStatsLocked(uid).noteWifiMulticastDisabledLocked(elapsedRealtime); 5978 } 5979 noteFullWifiLockAcquiredFromSourceLocked(WorkSource ws)5980 public void noteFullWifiLockAcquiredFromSourceLocked(WorkSource ws) { 5981 int N = ws.size(); 5982 for (int i=0; i<N; i++) { 5983 final int uid = mapUid(ws.getUid(i)); 5984 noteFullWifiLockAcquiredLocked(uid); 5985 } 5986 5987 final List<WorkChain> workChains = ws.getWorkChains(); 5988 if (workChains != null) { 5989 for (int i = 0; i < workChains.size(); ++i) { 5990 final WorkChain workChain = workChains.get(i); 5991 final int uid = mapUid(workChain.getAttributionUid()); 5992 noteFullWifiLockAcquiredLocked(uid); 5993 } 5994 } 5995 } 5996 noteFullWifiLockReleasedFromSourceLocked(WorkSource ws)5997 public void noteFullWifiLockReleasedFromSourceLocked(WorkSource ws) { 5998 int N = ws.size(); 5999 for (int i=0; i<N; i++) { 6000 final int uid = mapUid(ws.getUid(i)); 6001 noteFullWifiLockReleasedLocked(uid); 6002 } 6003 6004 final List<WorkChain> workChains = ws.getWorkChains(); 6005 if (workChains != null) { 6006 for (int i = 0; i < workChains.size(); ++i) { 6007 final WorkChain workChain = workChains.get(i); 6008 final int uid = mapUid(workChain.getAttributionUid()); 6009 noteFullWifiLockReleasedLocked(uid); 6010 } 6011 } 6012 } 6013 noteWifiScanStartedFromSourceLocked(WorkSource ws)6014 public void noteWifiScanStartedFromSourceLocked(WorkSource ws) { 6015 int N = ws.size(); 6016 for (int i=0; i<N; i++) { 6017 final int uid = mapUid(ws.getUid(i)); 6018 noteWifiScanStartedLocked(uid); 6019 } 6020 6021 final List<WorkChain> workChains = ws.getWorkChains(); 6022 if (workChains != null) { 6023 for (int i = 0; i < workChains.size(); ++i) { 6024 final WorkChain workChain = workChains.get(i); 6025 final int uid = mapUid(workChain.getAttributionUid()); 6026 noteWifiScanStartedLocked(uid); 6027 } 6028 } 6029 } 6030 noteWifiScanStoppedFromSourceLocked(WorkSource ws)6031 public void noteWifiScanStoppedFromSourceLocked(WorkSource ws) { 6032 int N = ws.size(); 6033 for (int i=0; i<N; i++) { 6034 final int uid = mapUid(ws.getUid(i)); 6035 noteWifiScanStoppedLocked(uid); 6036 } 6037 6038 final List<WorkChain> workChains = ws.getWorkChains(); 6039 if (workChains != null) { 6040 for (int i = 0; i < workChains.size(); ++i) { 6041 final WorkChain workChain = workChains.get(i); 6042 final int uid = mapUid(workChain.getAttributionUid()); 6043 noteWifiScanStoppedLocked(uid); 6044 } 6045 } 6046 } 6047 noteWifiBatchedScanStartedFromSourceLocked(WorkSource ws, int csph)6048 public void noteWifiBatchedScanStartedFromSourceLocked(WorkSource ws, int csph) { 6049 int N = ws.size(); 6050 for (int i=0; i<N; i++) { 6051 noteWifiBatchedScanStartedLocked(ws.getUid(i), csph); 6052 } 6053 6054 final List<WorkChain> workChains = ws.getWorkChains(); 6055 if (workChains != null) { 6056 for (int i = 0; i < workChains.size(); ++i) { 6057 noteWifiBatchedScanStartedLocked(workChains.get(i).getAttributionUid(), csph); 6058 } 6059 } 6060 } 6061 noteWifiBatchedScanStoppedFromSourceLocked(WorkSource ws)6062 public void noteWifiBatchedScanStoppedFromSourceLocked(WorkSource ws) { 6063 int N = ws.size(); 6064 for (int i=0; i<N; i++) { 6065 noteWifiBatchedScanStoppedLocked(ws.getUid(i)); 6066 } 6067 6068 final List<WorkChain> workChains = ws.getWorkChains(); 6069 if (workChains != null) { 6070 for (int i = 0; i < workChains.size(); ++i) { 6071 noteWifiBatchedScanStoppedLocked(workChains.get(i).getAttributionUid()); 6072 } 6073 } 6074 } 6075 includeInStringArray(String[] array, String str)6076 private static String[] includeInStringArray(String[] array, String str) { 6077 if (ArrayUtils.indexOf(array, str) >= 0) { 6078 return array; 6079 } 6080 String[] newArray = new String[array.length+1]; 6081 System.arraycopy(array, 0, newArray, 0, array.length); 6082 newArray[array.length] = str; 6083 return newArray; 6084 } 6085 excludeFromStringArray(String[] array, String str)6086 private static String[] excludeFromStringArray(String[] array, String str) { 6087 int index = ArrayUtils.indexOf(array, str); 6088 if (index >= 0) { 6089 String[] newArray = new String[array.length-1]; 6090 if (index > 0) { 6091 System.arraycopy(array, 0, newArray, 0, index); 6092 } 6093 if (index < array.length-1) { 6094 System.arraycopy(array, index+1, newArray, index, array.length-index-1); 6095 } 6096 return newArray; 6097 } 6098 return array; 6099 } 6100 6101 /** @hide */ noteNetworkInterfaceType(String iface, int networkType)6102 public void noteNetworkInterfaceType(String iface, int networkType) { 6103 if (TextUtils.isEmpty(iface)) return; 6104 6105 synchronized (mModemNetworkLock) { 6106 if (ConnectivityManager.isNetworkTypeMobile(networkType)) { 6107 mModemIfaces = includeInStringArray(mModemIfaces, iface); 6108 if (DEBUG) Slog.d(TAG, "Note mobile iface " + iface + ": " + mModemIfaces); 6109 } else { 6110 mModemIfaces = excludeFromStringArray(mModemIfaces, iface); 6111 if (DEBUG) Slog.d(TAG, "Note non-mobile iface " + iface + ": " + mModemIfaces); 6112 } 6113 } 6114 6115 synchronized (mWifiNetworkLock) { 6116 if (ConnectivityManager.isNetworkTypeWifi(networkType)) { 6117 mWifiIfaces = includeInStringArray(mWifiIfaces, iface); 6118 if (DEBUG) Slog.d(TAG, "Note wifi iface " + iface + ": " + mWifiIfaces); 6119 } else { 6120 mWifiIfaces = excludeFromStringArray(mWifiIfaces, iface); 6121 if (DEBUG) Slog.d(TAG, "Note non-wifi iface " + iface + ": " + mWifiIfaces); 6122 } 6123 } 6124 } 6125 getWifiIfaces()6126 public String[] getWifiIfaces() { 6127 synchronized (mWifiNetworkLock) { 6128 return mWifiIfaces; 6129 } 6130 } 6131 getMobileIfaces()6132 public String[] getMobileIfaces() { 6133 synchronized (mModemNetworkLock) { 6134 return mModemIfaces; 6135 } 6136 } 6137 6138 @UnsupportedAppUsage getScreenOnTime(long elapsedRealtimeUs, int which)6139 @Override public long getScreenOnTime(long elapsedRealtimeUs, int which) { 6140 return mScreenOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 6141 } 6142 getScreenOnCount(int which)6143 @Override public int getScreenOnCount(int which) { 6144 return mScreenOnTimer.getCountLocked(which); 6145 } 6146 getScreenDozeTime(long elapsedRealtimeUs, int which)6147 @Override public long getScreenDozeTime(long elapsedRealtimeUs, int which) { 6148 return mScreenDozeTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 6149 } 6150 getScreenDozeCount(int which)6151 @Override public int getScreenDozeCount(int which) { 6152 return mScreenDozeTimer.getCountLocked(which); 6153 } 6154 6155 @UnsupportedAppUsage getScreenBrightnessTime(int brightnessBin, long elapsedRealtimeUs, int which)6156 @Override public long getScreenBrightnessTime(int brightnessBin, 6157 long elapsedRealtimeUs, int which) { 6158 return mScreenBrightnessTimer[brightnessBin].getTotalTimeLocked( 6159 elapsedRealtimeUs, which); 6160 } 6161 getScreenBrightnessTimer(int brightnessBin)6162 @Override public Timer getScreenBrightnessTimer(int brightnessBin) { 6163 return mScreenBrightnessTimer[brightnessBin]; 6164 } 6165 getInteractiveTime(long elapsedRealtimeUs, int which)6166 @Override public long getInteractiveTime(long elapsedRealtimeUs, int which) { 6167 return mInteractiveTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 6168 } 6169 getPowerSaveModeEnabledTime(long elapsedRealtimeUs, int which)6170 @Override public long getPowerSaveModeEnabledTime(long elapsedRealtimeUs, int which) { 6171 return mPowerSaveModeEnabledTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 6172 } 6173 getPowerSaveModeEnabledCount(int which)6174 @Override public int getPowerSaveModeEnabledCount(int which) { 6175 return mPowerSaveModeEnabledTimer.getCountLocked(which); 6176 } 6177 getDeviceIdleModeTime(int mode, long elapsedRealtimeUs, int which)6178 @Override public long getDeviceIdleModeTime(int mode, long elapsedRealtimeUs, 6179 int which) { 6180 switch (mode) { 6181 case DEVICE_IDLE_MODE_LIGHT: 6182 return mDeviceIdleModeLightTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 6183 case DEVICE_IDLE_MODE_DEEP: 6184 return mDeviceIdleModeFullTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 6185 } 6186 return 0; 6187 } 6188 getDeviceIdleModeCount(int mode, int which)6189 @Override public int getDeviceIdleModeCount(int mode, int which) { 6190 switch (mode) { 6191 case DEVICE_IDLE_MODE_LIGHT: 6192 return mDeviceIdleModeLightTimer.getCountLocked(which); 6193 case DEVICE_IDLE_MODE_DEEP: 6194 return mDeviceIdleModeFullTimer.getCountLocked(which); 6195 } 6196 return 0; 6197 } 6198 getLongestDeviceIdleModeTime(int mode)6199 @Override public long getLongestDeviceIdleModeTime(int mode) { 6200 switch (mode) { 6201 case DEVICE_IDLE_MODE_LIGHT: 6202 return mLongestLightIdleTime; 6203 case DEVICE_IDLE_MODE_DEEP: 6204 return mLongestFullIdleTime; 6205 } 6206 return 0; 6207 } 6208 getDeviceIdlingTime(int mode, long elapsedRealtimeUs, int which)6209 @Override public long getDeviceIdlingTime(int mode, long elapsedRealtimeUs, int which) { 6210 switch (mode) { 6211 case DEVICE_IDLE_MODE_LIGHT: 6212 return mDeviceLightIdlingTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 6213 case DEVICE_IDLE_MODE_DEEP: 6214 return mDeviceIdlingTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 6215 } 6216 return 0; 6217 } 6218 getDeviceIdlingCount(int mode, int which)6219 @Override public int getDeviceIdlingCount(int mode, int which) { 6220 switch (mode) { 6221 case DEVICE_IDLE_MODE_LIGHT: 6222 return mDeviceLightIdlingTimer.getCountLocked(which); 6223 case DEVICE_IDLE_MODE_DEEP: 6224 return mDeviceIdlingTimer.getCountLocked(which); 6225 } 6226 return 0; 6227 } 6228 getNumConnectivityChange(int which)6229 @Override public int getNumConnectivityChange(int which) { 6230 return mNumConnectivityChange; 6231 } 6232 getGpsSignalQualityTime(int strengthBin, long elapsedRealtimeUs, int which)6233 @Override public long getGpsSignalQualityTime(int strengthBin, 6234 long elapsedRealtimeUs, int which) { 6235 if (strengthBin < 0 || strengthBin >= GnssMetrics.NUM_GPS_SIGNAL_QUALITY_LEVELS) { 6236 return 0; 6237 } 6238 return mGpsSignalQualityTimer[strengthBin].getTotalTimeLocked( 6239 elapsedRealtimeUs, which); 6240 } 6241 getGpsBatteryDrainMaMs()6242 @Override public long getGpsBatteryDrainMaMs() { 6243 final double opVolt = mPowerProfile.getAveragePower( 6244 PowerProfile.POWER_GPS_OPERATING_VOLTAGE) / 1000.0; 6245 if (opVolt == 0) { 6246 return 0; 6247 } 6248 double energyUsedMaMs = 0.0; 6249 final int which = STATS_SINCE_CHARGED; 6250 final long rawRealtime = SystemClock.elapsedRealtime() * 1000; 6251 for(int i=0; i < GnssMetrics.NUM_GPS_SIGNAL_QUALITY_LEVELS; i++) { 6252 energyUsedMaMs 6253 += mPowerProfile.getAveragePower(PowerProfile.POWER_GPS_SIGNAL_QUALITY_BASED, i) 6254 * (getGpsSignalQualityTime(i, rawRealtime, which) / 1000); 6255 } 6256 return (long) energyUsedMaMs; 6257 } 6258 6259 @UnsupportedAppUsage getPhoneOnTime(long elapsedRealtimeUs, int which)6260 @Override public long getPhoneOnTime(long elapsedRealtimeUs, int which) { 6261 return mPhoneOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 6262 } 6263 getPhoneOnCount(int which)6264 @Override public int getPhoneOnCount(int which) { 6265 return mPhoneOnTimer.getCountLocked(which); 6266 } 6267 6268 @UnsupportedAppUsage getPhoneSignalStrengthTime(int strengthBin, long elapsedRealtimeUs, int which)6269 @Override public long getPhoneSignalStrengthTime(int strengthBin, 6270 long elapsedRealtimeUs, int which) { 6271 return mPhoneSignalStrengthsTimer[strengthBin].getTotalTimeLocked( 6272 elapsedRealtimeUs, which); 6273 } 6274 6275 @UnsupportedAppUsage getPhoneSignalScanningTime( long elapsedRealtimeUs, int which)6276 @Override public long getPhoneSignalScanningTime( 6277 long elapsedRealtimeUs, int which) { 6278 return mPhoneSignalScanningTimer.getTotalTimeLocked( 6279 elapsedRealtimeUs, which); 6280 } 6281 getPhoneSignalScanningTimer()6282 @Override public Timer getPhoneSignalScanningTimer() { 6283 return mPhoneSignalScanningTimer; 6284 } 6285 6286 @UnsupportedAppUsage getPhoneSignalStrengthCount(int strengthBin, int which)6287 @Override public int getPhoneSignalStrengthCount(int strengthBin, int which) { 6288 return mPhoneSignalStrengthsTimer[strengthBin].getCountLocked(which); 6289 } 6290 getPhoneSignalStrengthTimer(int strengthBin)6291 @Override public Timer getPhoneSignalStrengthTimer(int strengthBin) { 6292 return mPhoneSignalStrengthsTimer[strengthBin]; 6293 } 6294 6295 @UnsupportedAppUsage getPhoneDataConnectionTime(int dataType, long elapsedRealtimeUs, int which)6296 @Override public long getPhoneDataConnectionTime(int dataType, 6297 long elapsedRealtimeUs, int which) { 6298 return mPhoneDataConnectionsTimer[dataType].getTotalTimeLocked( 6299 elapsedRealtimeUs, which); 6300 } 6301 6302 @UnsupportedAppUsage getPhoneDataConnectionCount(int dataType, int which)6303 @Override public int getPhoneDataConnectionCount(int dataType, int which) { 6304 return mPhoneDataConnectionsTimer[dataType].getCountLocked(which); 6305 } 6306 getPhoneDataConnectionTimer(int dataType)6307 @Override public Timer getPhoneDataConnectionTimer(int dataType) { 6308 return mPhoneDataConnectionsTimer[dataType]; 6309 } 6310 6311 @UnsupportedAppUsage getMobileRadioActiveTime(long elapsedRealtimeUs, int which)6312 @Override public long getMobileRadioActiveTime(long elapsedRealtimeUs, int which) { 6313 return mMobileRadioActiveTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 6314 } 6315 getMobileRadioActiveCount(int which)6316 @Override public int getMobileRadioActiveCount(int which) { 6317 return mMobileRadioActiveTimer.getCountLocked(which); 6318 } 6319 getMobileRadioActiveAdjustedTime(int which)6320 @Override public long getMobileRadioActiveAdjustedTime(int which) { 6321 return mMobileRadioActiveAdjustedTime.getCountLocked(which); 6322 } 6323 getMobileRadioActiveUnknownTime(int which)6324 @Override public long getMobileRadioActiveUnknownTime(int which) { 6325 return mMobileRadioActiveUnknownTime.getCountLocked(which); 6326 } 6327 getMobileRadioActiveUnknownCount(int which)6328 @Override public int getMobileRadioActiveUnknownCount(int which) { 6329 return (int)mMobileRadioActiveUnknownCount.getCountLocked(which); 6330 } 6331 getWifiMulticastWakelockTime( long elapsedRealtimeUs, int which)6332 @Override public long getWifiMulticastWakelockTime( 6333 long elapsedRealtimeUs, int which) { 6334 return mWifiMulticastWakelockTimer.getTotalTimeLocked( 6335 elapsedRealtimeUs, which); 6336 } 6337 getWifiMulticastWakelockCount(int which)6338 @Override public int getWifiMulticastWakelockCount(int which) { 6339 return mWifiMulticastWakelockTimer.getCountLocked(which); 6340 } 6341 6342 @UnsupportedAppUsage getWifiOnTime(long elapsedRealtimeUs, int which)6343 @Override public long getWifiOnTime(long elapsedRealtimeUs, int which) { 6344 return mWifiOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 6345 } 6346 getWifiActiveTime(long elapsedRealtimeUs, int which)6347 @Override public long getWifiActiveTime(long elapsedRealtimeUs, int which) { 6348 return mWifiActiveTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 6349 } 6350 6351 @UnsupportedAppUsage getGlobalWifiRunningTime(long elapsedRealtimeUs, int which)6352 @Override public long getGlobalWifiRunningTime(long elapsedRealtimeUs, int which) { 6353 return mGlobalWifiRunningTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 6354 } 6355 getWifiStateTime(int wifiState, long elapsedRealtimeUs, int which)6356 @Override public long getWifiStateTime(int wifiState, 6357 long elapsedRealtimeUs, int which) { 6358 return mWifiStateTimer[wifiState].getTotalTimeLocked( 6359 elapsedRealtimeUs, which); 6360 } 6361 getWifiStateCount(int wifiState, int which)6362 @Override public int getWifiStateCount(int wifiState, int which) { 6363 return mWifiStateTimer[wifiState].getCountLocked(which); 6364 } 6365 getWifiStateTimer(int wifiState)6366 @Override public Timer getWifiStateTimer(int wifiState) { 6367 return mWifiStateTimer[wifiState]; 6368 } 6369 getWifiSupplStateTime(int state, long elapsedRealtimeUs, int which)6370 @Override public long getWifiSupplStateTime(int state, 6371 long elapsedRealtimeUs, int which) { 6372 return mWifiSupplStateTimer[state].getTotalTimeLocked( 6373 elapsedRealtimeUs, which); 6374 } 6375 getWifiSupplStateCount(int state, int which)6376 @Override public int getWifiSupplStateCount(int state, int which) { 6377 return mWifiSupplStateTimer[state].getCountLocked(which); 6378 } 6379 getWifiSupplStateTimer(int state)6380 @Override public Timer getWifiSupplStateTimer(int state) { 6381 return mWifiSupplStateTimer[state]; 6382 } 6383 getWifiSignalStrengthTime(int strengthBin, long elapsedRealtimeUs, int which)6384 @Override public long getWifiSignalStrengthTime(int strengthBin, 6385 long elapsedRealtimeUs, int which) { 6386 return mWifiSignalStrengthsTimer[strengthBin].getTotalTimeLocked( 6387 elapsedRealtimeUs, which); 6388 } 6389 getWifiSignalStrengthCount(int strengthBin, int which)6390 @Override public int getWifiSignalStrengthCount(int strengthBin, int which) { 6391 return mWifiSignalStrengthsTimer[strengthBin].getCountLocked(which); 6392 } 6393 getWifiSignalStrengthTimer(int strengthBin)6394 @Override public Timer getWifiSignalStrengthTimer(int strengthBin) { 6395 return mWifiSignalStrengthsTimer[strengthBin]; 6396 } 6397 6398 @Override getBluetoothControllerActivity()6399 public ControllerActivityCounter getBluetoothControllerActivity() { 6400 return mBluetoothActivity; 6401 } 6402 6403 @Override getWifiControllerActivity()6404 public ControllerActivityCounter getWifiControllerActivity() { 6405 return mWifiActivity; 6406 } 6407 6408 @Override getModemControllerActivity()6409 public ControllerActivityCounter getModemControllerActivity() { 6410 return mModemActivity; 6411 } 6412 6413 @Override hasBluetoothActivityReporting()6414 public boolean hasBluetoothActivityReporting() { 6415 return mHasBluetoothReporting; 6416 } 6417 6418 @Override hasWifiActivityReporting()6419 public boolean hasWifiActivityReporting() { 6420 return mHasWifiReporting; 6421 } 6422 6423 @Override hasModemActivityReporting()6424 public boolean hasModemActivityReporting() { 6425 return mHasModemReporting; 6426 } 6427 6428 @Override getFlashlightOnTime(long elapsedRealtimeUs, int which)6429 public long getFlashlightOnTime(long elapsedRealtimeUs, int which) { 6430 return mFlashlightOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 6431 } 6432 6433 @Override getFlashlightOnCount(int which)6434 public long getFlashlightOnCount(int which) { 6435 return mFlashlightOnTimer.getCountLocked(which); 6436 } 6437 6438 @Override getCameraOnTime(long elapsedRealtimeUs, int which)6439 public long getCameraOnTime(long elapsedRealtimeUs, int which) { 6440 return mCameraOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 6441 } 6442 6443 @Override getBluetoothScanTime(long elapsedRealtimeUs, int which)6444 public long getBluetoothScanTime(long elapsedRealtimeUs, int which) { 6445 return mBluetoothScanTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 6446 } 6447 6448 @Override 6449 @UnsupportedAppUsage getNetworkActivityBytes(int type, int which)6450 public long getNetworkActivityBytes(int type, int which) { 6451 if (type >= 0 && type < mNetworkByteActivityCounters.length) { 6452 return mNetworkByteActivityCounters[type].getCountLocked(which); 6453 } else { 6454 return 0; 6455 } 6456 } 6457 6458 @Override getNetworkActivityPackets(int type, int which)6459 public long getNetworkActivityPackets(int type, int which) { 6460 if (type >= 0 && type < mNetworkPacketActivityCounters.length) { 6461 return mNetworkPacketActivityCounters[type].getCountLocked(which); 6462 } else { 6463 return 0; 6464 } 6465 } 6466 getStartClockTime()6467 @Override public long getStartClockTime() { 6468 final long currentTime = System.currentTimeMillis(); 6469 if ((currentTime > MILLISECONDS_IN_YEAR 6470 && mStartClockTime < (currentTime - MILLISECONDS_IN_YEAR)) 6471 || (mStartClockTime > currentTime)) { 6472 // If the start clock time has changed by more than a year, then presumably 6473 // the previous time was completely bogus. So we are going to figure out a 6474 // new time based on how much time has elapsed since we started counting. 6475 recordCurrentTimeChangeLocked(currentTime, mClocks.elapsedRealtime(), 6476 mClocks.uptimeMillis()); 6477 return currentTime - (mClocks.elapsedRealtime() - (mRealtimeStart / 1000)); 6478 } 6479 return mStartClockTime; 6480 } 6481 getStartPlatformVersion()6482 @Override public String getStartPlatformVersion() { 6483 return mStartPlatformVersion; 6484 } 6485 getEndPlatformVersion()6486 @Override public String getEndPlatformVersion() { 6487 return mEndPlatformVersion; 6488 } 6489 getParcelVersion()6490 @Override public int getParcelVersion() { 6491 return VERSION; 6492 } 6493 getIsOnBattery()6494 @Override public boolean getIsOnBattery() { 6495 return mOnBattery; 6496 } 6497 6498 @UnsupportedAppUsage getUidStats()6499 @Override public SparseArray<? extends BatteryStats.Uid> getUidStats() { 6500 return mUidStats; 6501 } 6502 resetIfNotNull(T t, boolean detachIfReset)6503 private static <T extends TimeBaseObs> boolean resetIfNotNull(T t, boolean detachIfReset) { 6504 if (t != null) { 6505 return t.reset(detachIfReset); 6506 } 6507 return true; 6508 } 6509 resetIfNotNull(T[] t, boolean detachIfReset)6510 private static <T extends TimeBaseObs> boolean resetIfNotNull(T[] t, boolean detachIfReset) { 6511 if (t != null) { 6512 boolean ret = true; 6513 for (int i = 0; i < t.length; i++) { 6514 ret &= resetIfNotNull(t[i], detachIfReset); 6515 } 6516 return ret; 6517 } 6518 return true; 6519 } 6520 resetIfNotNull(T[][] t, boolean detachIfReset)6521 private static <T extends TimeBaseObs> boolean resetIfNotNull(T[][] t, boolean detachIfReset) { 6522 if (t != null) { 6523 boolean ret = true; 6524 for (int i = 0; i < t.length; i++) { 6525 ret &= resetIfNotNull(t[i], detachIfReset); 6526 } 6527 return ret; 6528 } 6529 return true; 6530 } 6531 resetIfNotNull(ControllerActivityCounterImpl counter, boolean detachIfReset)6532 private static boolean resetIfNotNull(ControllerActivityCounterImpl counter, 6533 boolean detachIfReset) { 6534 if (counter != null) { 6535 counter.reset(detachIfReset); 6536 } 6537 return true; 6538 } 6539 detachIfNotNull(T t)6540 private static <T extends TimeBaseObs> void detachIfNotNull(T t) { 6541 if (t != null) { 6542 t.detach(); 6543 } 6544 } 6545 detachIfNotNull(T[] t)6546 private static <T extends TimeBaseObs> void detachIfNotNull(T[] t) { 6547 if (t != null) { 6548 for (int i = 0; i < t.length; i++) { 6549 detachIfNotNull(t[i]); 6550 } 6551 } 6552 } 6553 detachIfNotNull(T[][] t)6554 private static <T extends TimeBaseObs> void detachIfNotNull(T[][] t) { 6555 if (t != null) { 6556 for (int i = 0; i < t.length; i++) { 6557 detachIfNotNull(t[i]); 6558 } 6559 } 6560 } 6561 detachIfNotNull(ControllerActivityCounterImpl counter)6562 private static void detachIfNotNull(ControllerActivityCounterImpl counter) { 6563 if (counter != null) { 6564 counter.detach(); 6565 } 6566 } 6567 6568 /** 6569 * The statistics associated with a particular uid. 6570 */ 6571 public static class Uid extends BatteryStats.Uid { 6572 /** 6573 * BatteryStatsImpl that we are associated with. 6574 */ 6575 protected BatteryStatsImpl mBsi; 6576 6577 final int mUid; 6578 6579 /** TimeBase for when uid is in background and device is on battery. */ 6580 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) 6581 public final TimeBase mOnBatteryBackgroundTimeBase; 6582 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) 6583 public final TimeBase mOnBatteryScreenOffBackgroundTimeBase; 6584 6585 boolean mWifiRunning; 6586 StopwatchTimer mWifiRunningTimer; 6587 6588 boolean mFullWifiLockOut; 6589 StopwatchTimer mFullWifiLockTimer; 6590 6591 boolean mWifiScanStarted; 6592 DualTimer mWifiScanTimer; 6593 6594 static final int NO_BATCHED_SCAN_STARTED = -1; 6595 int mWifiBatchedScanBinStarted = NO_BATCHED_SCAN_STARTED; 6596 StopwatchTimer[] mWifiBatchedScanTimer; 6597 6598 int mWifiMulticastWakelockCount; 6599 StopwatchTimer mWifiMulticastTimer; 6600 6601 StopwatchTimer mAudioTurnedOnTimer; 6602 StopwatchTimer mVideoTurnedOnTimer; 6603 StopwatchTimer mFlashlightTurnedOnTimer; 6604 StopwatchTimer mCameraTurnedOnTimer; 6605 StopwatchTimer mForegroundActivityTimer; 6606 StopwatchTimer mForegroundServiceTimer; 6607 /** Total time spent by the uid holding any partial wakelocks. */ 6608 DualTimer mAggregatedPartialWakelockTimer; 6609 DualTimer mBluetoothScanTimer; 6610 DualTimer mBluetoothUnoptimizedScanTimer; 6611 Counter mBluetoothScanResultCounter; 6612 Counter mBluetoothScanResultBgCounter; 6613 6614 int mProcessState = ActivityManager.PROCESS_STATE_NONEXISTENT; 6615 StopwatchTimer[] mProcessStateTimer; 6616 6617 boolean mInForegroundService = false; 6618 6619 BatchTimer mVibratorOnTimer; 6620 6621 Counter[] mUserActivityCounters; 6622 6623 LongSamplingCounter[] mNetworkByteActivityCounters; 6624 LongSamplingCounter[] mNetworkPacketActivityCounters; 6625 LongSamplingCounter mMobileRadioActiveTime; 6626 LongSamplingCounter mMobileRadioActiveCount; 6627 6628 /** 6629 * How many times this UID woke up the Application Processor due to a Mobile radio packet. 6630 */ 6631 private LongSamplingCounter mMobileRadioApWakeupCount; 6632 6633 /** 6634 * How many times this UID woke up the Application Processor due to a Wifi packet. 6635 */ 6636 private LongSamplingCounter mWifiRadioApWakeupCount; 6637 6638 /** 6639 * The amount of time this uid has kept the WiFi controller in idle, tx, and rx mode. 6640 * Can be null if the UID has had no such activity. 6641 */ 6642 private ControllerActivityCounterImpl mWifiControllerActivity; 6643 6644 /** 6645 * The amount of time this uid has kept the Bluetooth controller in idle, tx, and rx mode. 6646 * Can be null if the UID has had no such activity. 6647 */ 6648 private ControllerActivityCounterImpl mBluetoothControllerActivity; 6649 6650 /** 6651 * The amount of time this uid has kept the Modem controller in idle, tx, and rx mode. 6652 * Can be null if the UID has had no such activity. 6653 */ 6654 private ControllerActivityCounterImpl mModemControllerActivity; 6655 6656 /** 6657 * The CPU times we had at the last history details update. 6658 */ 6659 long mLastStepUserTime; 6660 long mLastStepSystemTime; 6661 long mCurStepUserTime; 6662 long mCurStepSystemTime; 6663 6664 LongSamplingCounter mUserCpuTime; 6665 LongSamplingCounter mSystemCpuTime; 6666 LongSamplingCounter[][] mCpuClusterSpeedTimesUs; 6667 LongSamplingCounter mCpuActiveTimeMs; 6668 6669 LongSamplingCounterArray mCpuFreqTimeMs; 6670 LongSamplingCounterArray mScreenOffCpuFreqTimeMs; 6671 LongSamplingCounterArray mCpuClusterTimesMs; 6672 6673 LongSamplingCounterArray[] mProcStateTimeMs; 6674 LongSamplingCounterArray[] mProcStateScreenOffTimeMs; 6675 6676 IntArray mChildUids; 6677 6678 /** 6679 * The statistics we have collected for this uid's wake locks. 6680 */ 6681 final OverflowArrayMap<Wakelock> mWakelockStats; 6682 6683 /** 6684 * The statistics we have collected for this uid's syncs. 6685 */ 6686 final OverflowArrayMap<DualTimer> mSyncStats; 6687 6688 /** 6689 * The statistics we have collected for this uid's jobs. 6690 */ 6691 final OverflowArrayMap<DualTimer> mJobStats; 6692 6693 /** 6694 * Count of the jobs that have completed and the reasons why they completed. 6695 */ 6696 final ArrayMap<String, SparseIntArray> mJobCompletions = new ArrayMap<>(); 6697 6698 /** 6699 * Count of app launch events that had associated deferred job counts or info about 6700 * last time a job was run. 6701 */ 6702 Counter mJobsDeferredEventCount; 6703 6704 /** 6705 * Count of deferred jobs that were pending when the app was launched or brought to 6706 * the foreground through a user interaction. 6707 */ 6708 Counter mJobsDeferredCount; 6709 6710 /** 6711 * Sum of time since the last time a job was run for this app before it was launched. 6712 */ 6713 LongSamplingCounter mJobsFreshnessTimeMs; 6714 6715 /** 6716 * Array of counts of instances where the time since the last job was run for the app 6717 * fell within one of the thresholds in {@link #JOB_FRESHNESS_BUCKETS}. 6718 */ 6719 final Counter[] mJobsFreshnessBuckets; 6720 6721 /** 6722 * The statistics we have collected for this uid's sensor activations. 6723 */ 6724 final SparseArray<Sensor> mSensorStats = new SparseArray<>(); 6725 6726 /** 6727 * The statistics we have collected for this uid's processes. 6728 */ 6729 final ArrayMap<String, Proc> mProcessStats = new ArrayMap<>(); 6730 6731 /** 6732 * The statistics we have collected for this uid's processes. 6733 */ 6734 final ArrayMap<String, Pkg> mPackageStats = new ArrayMap<>(); 6735 6736 /** 6737 * The transient wake stats we have collected for this uid's pids. 6738 */ 6739 final SparseArray<Pid> mPids = new SparseArray<>(); 6740 Uid(BatteryStatsImpl bsi, int uid)6741 public Uid(BatteryStatsImpl bsi, int uid) { 6742 mBsi = bsi; 6743 mUid = uid; 6744 6745 /* Observer list of TimeBase object in Uid is short */ 6746 mOnBatteryBackgroundTimeBase = new TimeBase(false); 6747 mOnBatteryBackgroundTimeBase.init(mBsi.mClocks.uptimeMillis() * 1000, 6748 mBsi.mClocks.elapsedRealtime() * 1000); 6749 /* Observer list of TimeBase object in Uid is short */ 6750 mOnBatteryScreenOffBackgroundTimeBase = new TimeBase(false); 6751 mOnBatteryScreenOffBackgroundTimeBase.init(mBsi.mClocks.uptimeMillis() * 1000, 6752 mBsi.mClocks.elapsedRealtime() * 1000); 6753 6754 mUserCpuTime = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); 6755 mSystemCpuTime = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); 6756 mCpuActiveTimeMs = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); 6757 mCpuClusterTimesMs = new LongSamplingCounterArray(mBsi.mOnBatteryTimeBase); 6758 6759 mWakelockStats = mBsi.new OverflowArrayMap<Wakelock>(uid) { 6760 @Override public Wakelock instantiateObject() { 6761 return new Wakelock(mBsi, Uid.this); 6762 } 6763 }; 6764 mSyncStats = mBsi.new OverflowArrayMap<DualTimer>(uid) { 6765 @Override public DualTimer instantiateObject() { 6766 return new DualTimer(mBsi.mClocks, Uid.this, SYNC, null, 6767 mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase); 6768 } 6769 }; 6770 mJobStats = mBsi.new OverflowArrayMap<DualTimer>(uid) { 6771 @Override public DualTimer instantiateObject() { 6772 return new DualTimer(mBsi.mClocks, Uid.this, JOB, null, 6773 mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase); 6774 } 6775 }; 6776 6777 mWifiRunningTimer = new StopwatchTimer(mBsi.mClocks, this, WIFI_RUNNING, 6778 mBsi.mWifiRunningTimers, mBsi.mOnBatteryTimeBase); 6779 mFullWifiLockTimer = new StopwatchTimer(mBsi.mClocks, this, FULL_WIFI_LOCK, 6780 mBsi.mFullWifiLockTimers, mBsi.mOnBatteryTimeBase); 6781 mWifiScanTimer = new DualTimer(mBsi.mClocks, this, WIFI_SCAN, 6782 mBsi.mWifiScanTimers, mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase); 6783 mWifiBatchedScanTimer = new StopwatchTimer[NUM_WIFI_BATCHED_SCAN_BINS]; 6784 mWifiMulticastTimer = new StopwatchTimer(mBsi.mClocks, this, WIFI_MULTICAST_ENABLED, 6785 mBsi.mWifiMulticastTimers, mBsi.mOnBatteryTimeBase); 6786 mProcessStateTimer = new StopwatchTimer[NUM_PROCESS_STATE]; 6787 mJobsDeferredEventCount = new Counter(mBsi.mOnBatteryTimeBase); 6788 mJobsDeferredCount = new Counter(mBsi.mOnBatteryTimeBase); 6789 mJobsFreshnessTimeMs = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); 6790 mJobsFreshnessBuckets = new Counter[JOB_FRESHNESS_BUCKETS.length]; 6791 } 6792 6793 @VisibleForTesting setProcessStateForTest(int procState)6794 public void setProcessStateForTest(int procState) { 6795 mProcessState = procState; 6796 } 6797 6798 @Override getCpuFreqTimes(int which)6799 public long[] getCpuFreqTimes(int which) { 6800 return nullIfAllZeros(mCpuFreqTimeMs, which); 6801 } 6802 6803 @Override getScreenOffCpuFreqTimes(int which)6804 public long[] getScreenOffCpuFreqTimes(int which) { 6805 return nullIfAllZeros(mScreenOffCpuFreqTimeMs, which); 6806 } 6807 6808 @Override getCpuActiveTime()6809 public long getCpuActiveTime() { 6810 return mCpuActiveTimeMs.getCountLocked(STATS_SINCE_CHARGED); 6811 } 6812 6813 @Override getCpuClusterTimes()6814 public long[] getCpuClusterTimes() { 6815 return nullIfAllZeros(mCpuClusterTimesMs, STATS_SINCE_CHARGED); 6816 } 6817 6818 6819 @Override getCpuFreqTimes(int which, int procState)6820 public long[] getCpuFreqTimes(int which, int procState) { 6821 if (which < 0 || which >= NUM_PROCESS_STATE) { 6822 return null; 6823 } 6824 if (mProcStateTimeMs == null) { 6825 return null; 6826 } 6827 if (!mBsi.mPerProcStateCpuTimesAvailable) { 6828 mProcStateTimeMs = null; 6829 return null; 6830 } 6831 return nullIfAllZeros(mProcStateTimeMs[procState], which); 6832 } 6833 6834 @Override getScreenOffCpuFreqTimes(int which, int procState)6835 public long[] getScreenOffCpuFreqTimes(int which, int procState) { 6836 if (which < 0 || which >= NUM_PROCESS_STATE) { 6837 return null; 6838 } 6839 if (mProcStateScreenOffTimeMs == null) { 6840 return null; 6841 } 6842 if (!mBsi.mPerProcStateCpuTimesAvailable) { 6843 mProcStateScreenOffTimeMs = null; 6844 return null; 6845 } 6846 return nullIfAllZeros(mProcStateScreenOffTimeMs[procState], which); 6847 } 6848 addIsolatedUid(int isolatedUid)6849 public void addIsolatedUid(int isolatedUid) { 6850 if (mChildUids == null) { 6851 mChildUids = new IntArray(); 6852 } else if (mChildUids.indexOf(isolatedUid) >= 0) { 6853 return; 6854 } 6855 mChildUids.add(isolatedUid); 6856 } 6857 removeIsolatedUid(int isolatedUid)6858 public void removeIsolatedUid(int isolatedUid) { 6859 final int idx = mChildUids == null ? -1 : mChildUids.indexOf(isolatedUid); 6860 if (idx < 0) { 6861 return; 6862 } 6863 mChildUids.remove(idx); 6864 } 6865 nullIfAllZeros(LongSamplingCounterArray cpuTimesMs, int which)6866 private long[] nullIfAllZeros(LongSamplingCounterArray cpuTimesMs, int which) { 6867 if (cpuTimesMs == null) { 6868 return null; 6869 } 6870 final long[] counts = cpuTimesMs.getCountsLocked(which); 6871 if (counts == null) { 6872 return null; 6873 } 6874 // Return counts only if at least one of the elements is non-zero. 6875 for (int i = counts.length - 1; i >= 0; --i) { 6876 if (counts[i] != 0) { 6877 return counts; 6878 } 6879 } 6880 return null; 6881 } 6882 addProcStateTimesMs(int procState, long[] cpuTimesMs, boolean onBattery)6883 private void addProcStateTimesMs(int procState, long[] cpuTimesMs, boolean onBattery) { 6884 if (mProcStateTimeMs == null) { 6885 mProcStateTimeMs = new LongSamplingCounterArray[NUM_PROCESS_STATE]; 6886 } 6887 if (mProcStateTimeMs[procState] == null 6888 || mProcStateTimeMs[procState].getSize() != cpuTimesMs.length) { 6889 detachIfNotNull(mProcStateTimeMs[procState]); 6890 mProcStateTimeMs[procState] = new LongSamplingCounterArray( 6891 mBsi.mOnBatteryTimeBase); 6892 } 6893 mProcStateTimeMs[procState].addCountLocked(cpuTimesMs, onBattery); 6894 } 6895 addProcStateScreenOffTimesMs(int procState, long[] cpuTimesMs, boolean onBatteryScreenOff)6896 private void addProcStateScreenOffTimesMs(int procState, long[] cpuTimesMs, 6897 boolean onBatteryScreenOff) { 6898 if (mProcStateScreenOffTimeMs == null) { 6899 mProcStateScreenOffTimeMs = new LongSamplingCounterArray[NUM_PROCESS_STATE]; 6900 } 6901 if (mProcStateScreenOffTimeMs[procState] == null 6902 || mProcStateScreenOffTimeMs[procState].getSize() != cpuTimesMs.length) { 6903 detachIfNotNull(mProcStateScreenOffTimeMs[procState]); 6904 mProcStateScreenOffTimeMs[procState] = new LongSamplingCounterArray( 6905 mBsi.mOnBatteryScreenOffTimeBase); 6906 } 6907 mProcStateScreenOffTimeMs[procState].addCountLocked(cpuTimesMs, onBatteryScreenOff); 6908 } 6909 6910 @Override getAggregatedPartialWakelockTimer()6911 public Timer getAggregatedPartialWakelockTimer() { 6912 return mAggregatedPartialWakelockTimer; 6913 } 6914 6915 @Override 6916 @UnsupportedAppUsage getWakelockStats()6917 public ArrayMap<String, ? extends BatteryStats.Uid.Wakelock> getWakelockStats() { 6918 return mWakelockStats.getMap(); 6919 } 6920 6921 @Override getMulticastWakelockStats()6922 public Timer getMulticastWakelockStats() { 6923 return mWifiMulticastTimer; 6924 } 6925 6926 @Override getSyncStats()6927 public ArrayMap<String, ? extends BatteryStats.Timer> getSyncStats() { 6928 return mSyncStats.getMap(); 6929 } 6930 6931 @Override getJobStats()6932 public ArrayMap<String, ? extends BatteryStats.Timer> getJobStats() { 6933 return mJobStats.getMap(); 6934 } 6935 6936 @Override getJobCompletionStats()6937 public ArrayMap<String, SparseIntArray> getJobCompletionStats() { 6938 return mJobCompletions; 6939 } 6940 6941 @Override 6942 @UnsupportedAppUsage getSensorStats()6943 public SparseArray<? extends BatteryStats.Uid.Sensor> getSensorStats() { 6944 return mSensorStats; 6945 } 6946 6947 @Override 6948 @UnsupportedAppUsage getProcessStats()6949 public ArrayMap<String, ? extends BatteryStats.Uid.Proc> getProcessStats() { 6950 return mProcessStats; 6951 } 6952 6953 @Override getPackageStats()6954 public ArrayMap<String, ? extends BatteryStats.Uid.Pkg> getPackageStats() { 6955 return mPackageStats; 6956 } 6957 6958 @Override 6959 @UnsupportedAppUsage getUid()6960 public int getUid() { 6961 return mUid; 6962 } 6963 6964 @Override noteWifiRunningLocked(long elapsedRealtimeMs)6965 public void noteWifiRunningLocked(long elapsedRealtimeMs) { 6966 if (!mWifiRunning) { 6967 mWifiRunning = true; 6968 if (mWifiRunningTimer == null) { 6969 mWifiRunningTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, WIFI_RUNNING, 6970 mBsi.mWifiRunningTimers, mBsi.mOnBatteryTimeBase); 6971 } 6972 mWifiRunningTimer.startRunningLocked(elapsedRealtimeMs); 6973 } 6974 } 6975 6976 @Override noteWifiStoppedLocked(long elapsedRealtimeMs)6977 public void noteWifiStoppedLocked(long elapsedRealtimeMs) { 6978 if (mWifiRunning) { 6979 mWifiRunning = false; 6980 mWifiRunningTimer.stopRunningLocked(elapsedRealtimeMs); 6981 } 6982 } 6983 6984 @Override noteFullWifiLockAcquiredLocked(long elapsedRealtimeMs)6985 public void noteFullWifiLockAcquiredLocked(long elapsedRealtimeMs) { 6986 if (!mFullWifiLockOut) { 6987 mFullWifiLockOut = true; 6988 if (mFullWifiLockTimer == null) { 6989 mFullWifiLockTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, FULL_WIFI_LOCK, 6990 mBsi.mFullWifiLockTimers, mBsi.mOnBatteryTimeBase); 6991 } 6992 mFullWifiLockTimer.startRunningLocked(elapsedRealtimeMs); 6993 } 6994 } 6995 6996 @Override noteFullWifiLockReleasedLocked(long elapsedRealtimeMs)6997 public void noteFullWifiLockReleasedLocked(long elapsedRealtimeMs) { 6998 if (mFullWifiLockOut) { 6999 mFullWifiLockOut = false; 7000 mFullWifiLockTimer.stopRunningLocked(elapsedRealtimeMs); 7001 } 7002 } 7003 7004 @Override noteWifiScanStartedLocked(long elapsedRealtimeMs)7005 public void noteWifiScanStartedLocked(long elapsedRealtimeMs) { 7006 if (!mWifiScanStarted) { 7007 mWifiScanStarted = true; 7008 if (mWifiScanTimer == null) { 7009 mWifiScanTimer = new DualTimer(mBsi.mClocks, Uid.this, WIFI_SCAN, 7010 mBsi.mWifiScanTimers, mBsi.mOnBatteryTimeBase, 7011 mOnBatteryBackgroundTimeBase); 7012 } 7013 mWifiScanTimer.startRunningLocked(elapsedRealtimeMs); 7014 } 7015 } 7016 7017 @Override noteWifiScanStoppedLocked(long elapsedRealtimeMs)7018 public void noteWifiScanStoppedLocked(long elapsedRealtimeMs) { 7019 if (mWifiScanStarted) { 7020 mWifiScanStarted = false; 7021 mWifiScanTimer.stopRunningLocked(elapsedRealtimeMs); 7022 } 7023 } 7024 7025 @Override noteWifiBatchedScanStartedLocked(int csph, long elapsedRealtimeMs)7026 public void noteWifiBatchedScanStartedLocked(int csph, long elapsedRealtimeMs) { 7027 int bin = 0; 7028 while (csph > 8 && bin < NUM_WIFI_BATCHED_SCAN_BINS-1) { 7029 csph = csph >> 3; 7030 bin++; 7031 } 7032 7033 if (mWifiBatchedScanBinStarted == bin) return; 7034 7035 if (mWifiBatchedScanBinStarted != NO_BATCHED_SCAN_STARTED) { 7036 mWifiBatchedScanTimer[mWifiBatchedScanBinStarted]. 7037 stopRunningLocked(elapsedRealtimeMs); 7038 } 7039 mWifiBatchedScanBinStarted = bin; 7040 if (mWifiBatchedScanTimer[bin] == null) { 7041 makeWifiBatchedScanBin(bin, null); 7042 } 7043 mWifiBatchedScanTimer[bin].startRunningLocked(elapsedRealtimeMs); 7044 } 7045 7046 @Override noteWifiBatchedScanStoppedLocked(long elapsedRealtimeMs)7047 public void noteWifiBatchedScanStoppedLocked(long elapsedRealtimeMs) { 7048 if (mWifiBatchedScanBinStarted != NO_BATCHED_SCAN_STARTED) { 7049 mWifiBatchedScanTimer[mWifiBatchedScanBinStarted]. 7050 stopRunningLocked(elapsedRealtimeMs); 7051 mWifiBatchedScanBinStarted = NO_BATCHED_SCAN_STARTED; 7052 } 7053 } 7054 7055 @Override noteWifiMulticastEnabledLocked(long elapsedRealtimeMs)7056 public void noteWifiMulticastEnabledLocked(long elapsedRealtimeMs) { 7057 if (mWifiMulticastWakelockCount == 0) { 7058 if (mWifiMulticastTimer == null) { 7059 mWifiMulticastTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, 7060 WIFI_MULTICAST_ENABLED, mBsi.mWifiMulticastTimers, mBsi.mOnBatteryTimeBase); 7061 } 7062 mWifiMulticastTimer.startRunningLocked(elapsedRealtimeMs); 7063 } 7064 mWifiMulticastWakelockCount++; 7065 } 7066 7067 @Override noteWifiMulticastDisabledLocked(long elapsedRealtimeMs)7068 public void noteWifiMulticastDisabledLocked(long elapsedRealtimeMs) { 7069 if (mWifiMulticastWakelockCount == 0) { 7070 return; 7071 } 7072 7073 mWifiMulticastWakelockCount--; 7074 if (mWifiMulticastWakelockCount == 0) { 7075 mWifiMulticastTimer.stopRunningLocked(elapsedRealtimeMs); 7076 } 7077 } 7078 7079 @Override getWifiControllerActivity()7080 public ControllerActivityCounter getWifiControllerActivity() { 7081 return mWifiControllerActivity; 7082 } 7083 7084 @Override getBluetoothControllerActivity()7085 public ControllerActivityCounter getBluetoothControllerActivity() { 7086 return mBluetoothControllerActivity; 7087 } 7088 7089 @Override getModemControllerActivity()7090 public ControllerActivityCounter getModemControllerActivity() { 7091 return mModemControllerActivity; 7092 } 7093 getOrCreateWifiControllerActivityLocked()7094 public ControllerActivityCounterImpl getOrCreateWifiControllerActivityLocked() { 7095 if (mWifiControllerActivity == null) { 7096 mWifiControllerActivity = new ControllerActivityCounterImpl(mBsi.mOnBatteryTimeBase, 7097 NUM_BT_TX_LEVELS); 7098 } 7099 return mWifiControllerActivity; 7100 } 7101 getOrCreateBluetoothControllerActivityLocked()7102 public ControllerActivityCounterImpl getOrCreateBluetoothControllerActivityLocked() { 7103 if (mBluetoothControllerActivity == null) { 7104 mBluetoothControllerActivity = new ControllerActivityCounterImpl(mBsi.mOnBatteryTimeBase, 7105 NUM_BT_TX_LEVELS); 7106 } 7107 return mBluetoothControllerActivity; 7108 } 7109 getOrCreateModemControllerActivityLocked()7110 public ControllerActivityCounterImpl getOrCreateModemControllerActivityLocked() { 7111 if (mModemControllerActivity == null) { 7112 mModemControllerActivity = new ControllerActivityCounterImpl(mBsi.mOnBatteryTimeBase, 7113 ModemActivityInfo.TX_POWER_LEVELS); 7114 } 7115 return mModemControllerActivity; 7116 } 7117 createAudioTurnedOnTimerLocked()7118 public StopwatchTimer createAudioTurnedOnTimerLocked() { 7119 if (mAudioTurnedOnTimer == null) { 7120 mAudioTurnedOnTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, AUDIO_TURNED_ON, 7121 mBsi.mAudioTurnedOnTimers, mBsi.mOnBatteryTimeBase); 7122 } 7123 return mAudioTurnedOnTimer; 7124 } 7125 noteAudioTurnedOnLocked(long elapsedRealtimeMs)7126 public void noteAudioTurnedOnLocked(long elapsedRealtimeMs) { 7127 createAudioTurnedOnTimerLocked().startRunningLocked(elapsedRealtimeMs); 7128 } 7129 noteAudioTurnedOffLocked(long elapsedRealtimeMs)7130 public void noteAudioTurnedOffLocked(long elapsedRealtimeMs) { 7131 if (mAudioTurnedOnTimer != null) { 7132 mAudioTurnedOnTimer.stopRunningLocked(elapsedRealtimeMs); 7133 } 7134 } 7135 noteResetAudioLocked(long elapsedRealtimeMs)7136 public void noteResetAudioLocked(long elapsedRealtimeMs) { 7137 if (mAudioTurnedOnTimer != null) { 7138 mAudioTurnedOnTimer.stopAllRunningLocked(elapsedRealtimeMs); 7139 } 7140 } 7141 createVideoTurnedOnTimerLocked()7142 public StopwatchTimer createVideoTurnedOnTimerLocked() { 7143 if (mVideoTurnedOnTimer == null) { 7144 mVideoTurnedOnTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, VIDEO_TURNED_ON, 7145 mBsi.mVideoTurnedOnTimers, mBsi.mOnBatteryTimeBase); 7146 } 7147 return mVideoTurnedOnTimer; 7148 } 7149 noteVideoTurnedOnLocked(long elapsedRealtimeMs)7150 public void noteVideoTurnedOnLocked(long elapsedRealtimeMs) { 7151 createVideoTurnedOnTimerLocked().startRunningLocked(elapsedRealtimeMs); 7152 } 7153 noteVideoTurnedOffLocked(long elapsedRealtimeMs)7154 public void noteVideoTurnedOffLocked(long elapsedRealtimeMs) { 7155 if (mVideoTurnedOnTimer != null) { 7156 mVideoTurnedOnTimer.stopRunningLocked(elapsedRealtimeMs); 7157 } 7158 } 7159 noteResetVideoLocked(long elapsedRealtimeMs)7160 public void noteResetVideoLocked(long elapsedRealtimeMs) { 7161 if (mVideoTurnedOnTimer != null) { 7162 mVideoTurnedOnTimer.stopAllRunningLocked(elapsedRealtimeMs); 7163 } 7164 } 7165 createFlashlightTurnedOnTimerLocked()7166 public StopwatchTimer createFlashlightTurnedOnTimerLocked() { 7167 if (mFlashlightTurnedOnTimer == null) { 7168 mFlashlightTurnedOnTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, 7169 FLASHLIGHT_TURNED_ON, mBsi.mFlashlightTurnedOnTimers, mBsi.mOnBatteryTimeBase); 7170 } 7171 return mFlashlightTurnedOnTimer; 7172 } 7173 noteFlashlightTurnedOnLocked(long elapsedRealtimeMs)7174 public void noteFlashlightTurnedOnLocked(long elapsedRealtimeMs) { 7175 createFlashlightTurnedOnTimerLocked().startRunningLocked(elapsedRealtimeMs); 7176 } 7177 noteFlashlightTurnedOffLocked(long elapsedRealtimeMs)7178 public void noteFlashlightTurnedOffLocked(long elapsedRealtimeMs) { 7179 if (mFlashlightTurnedOnTimer != null) { 7180 mFlashlightTurnedOnTimer.stopRunningLocked(elapsedRealtimeMs); 7181 } 7182 } 7183 noteResetFlashlightLocked(long elapsedRealtimeMs)7184 public void noteResetFlashlightLocked(long elapsedRealtimeMs) { 7185 if (mFlashlightTurnedOnTimer != null) { 7186 mFlashlightTurnedOnTimer.stopAllRunningLocked(elapsedRealtimeMs); 7187 } 7188 } 7189 createCameraTurnedOnTimerLocked()7190 public StopwatchTimer createCameraTurnedOnTimerLocked() { 7191 if (mCameraTurnedOnTimer == null) { 7192 mCameraTurnedOnTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, CAMERA_TURNED_ON, 7193 mBsi.mCameraTurnedOnTimers, mBsi.mOnBatteryTimeBase); 7194 } 7195 return mCameraTurnedOnTimer; 7196 } 7197 noteCameraTurnedOnLocked(long elapsedRealtimeMs)7198 public void noteCameraTurnedOnLocked(long elapsedRealtimeMs) { 7199 createCameraTurnedOnTimerLocked().startRunningLocked(elapsedRealtimeMs); 7200 } 7201 noteCameraTurnedOffLocked(long elapsedRealtimeMs)7202 public void noteCameraTurnedOffLocked(long elapsedRealtimeMs) { 7203 if (mCameraTurnedOnTimer != null) { 7204 mCameraTurnedOnTimer.stopRunningLocked(elapsedRealtimeMs); 7205 } 7206 } 7207 noteResetCameraLocked(long elapsedRealtimeMs)7208 public void noteResetCameraLocked(long elapsedRealtimeMs) { 7209 if (mCameraTurnedOnTimer != null) { 7210 mCameraTurnedOnTimer.stopAllRunningLocked(elapsedRealtimeMs); 7211 } 7212 } 7213 createForegroundActivityTimerLocked()7214 public StopwatchTimer createForegroundActivityTimerLocked() { 7215 if (mForegroundActivityTimer == null) { 7216 mForegroundActivityTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, 7217 FOREGROUND_ACTIVITY, null, mBsi.mOnBatteryTimeBase); 7218 } 7219 return mForegroundActivityTimer; 7220 } 7221 createForegroundServiceTimerLocked()7222 public StopwatchTimer createForegroundServiceTimerLocked() { 7223 if (mForegroundServiceTimer == null) { 7224 mForegroundServiceTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, 7225 FOREGROUND_SERVICE, null, mBsi.mOnBatteryTimeBase); 7226 } 7227 return mForegroundServiceTimer; 7228 } 7229 createAggregatedPartialWakelockTimerLocked()7230 public DualTimer createAggregatedPartialWakelockTimerLocked() { 7231 if (mAggregatedPartialWakelockTimer == null) { 7232 mAggregatedPartialWakelockTimer = new DualTimer(mBsi.mClocks, this, 7233 AGGREGATED_WAKE_TYPE_PARTIAL, null, 7234 mBsi.mOnBatteryScreenOffTimeBase, mOnBatteryScreenOffBackgroundTimeBase); 7235 } 7236 return mAggregatedPartialWakelockTimer; 7237 } 7238 createBluetoothScanTimerLocked()7239 public DualTimer createBluetoothScanTimerLocked() { 7240 if (mBluetoothScanTimer == null) { 7241 mBluetoothScanTimer = new DualTimer(mBsi.mClocks, Uid.this, BLUETOOTH_SCAN_ON, 7242 mBsi.mBluetoothScanOnTimers, mBsi.mOnBatteryTimeBase, 7243 mOnBatteryBackgroundTimeBase); 7244 } 7245 return mBluetoothScanTimer; 7246 } 7247 createBluetoothUnoptimizedScanTimerLocked()7248 public DualTimer createBluetoothUnoptimizedScanTimerLocked() { 7249 if (mBluetoothUnoptimizedScanTimer == null) { 7250 mBluetoothUnoptimizedScanTimer = new DualTimer(mBsi.mClocks, Uid.this, 7251 BLUETOOTH_UNOPTIMIZED_SCAN_ON, null, 7252 mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase); 7253 } 7254 return mBluetoothUnoptimizedScanTimer; 7255 } 7256 noteBluetoothScanStartedLocked(long elapsedRealtimeMs, boolean isUnoptimized)7257 public void noteBluetoothScanStartedLocked(long elapsedRealtimeMs, 7258 boolean isUnoptimized) { 7259 createBluetoothScanTimerLocked().startRunningLocked(elapsedRealtimeMs); 7260 if (isUnoptimized) { 7261 createBluetoothUnoptimizedScanTimerLocked().startRunningLocked(elapsedRealtimeMs); 7262 } 7263 } 7264 noteBluetoothScanStoppedLocked(long elapsedRealtimeMs, boolean isUnoptimized)7265 public void noteBluetoothScanStoppedLocked(long elapsedRealtimeMs, boolean isUnoptimized) { 7266 if (mBluetoothScanTimer != null) { 7267 mBluetoothScanTimer.stopRunningLocked(elapsedRealtimeMs); 7268 } 7269 if (isUnoptimized && mBluetoothUnoptimizedScanTimer != null) { 7270 mBluetoothUnoptimizedScanTimer.stopRunningLocked(elapsedRealtimeMs); 7271 } 7272 } 7273 noteResetBluetoothScanLocked(long elapsedRealtimeMs)7274 public void noteResetBluetoothScanLocked(long elapsedRealtimeMs) { 7275 if (mBluetoothScanTimer != null) { 7276 mBluetoothScanTimer.stopAllRunningLocked(elapsedRealtimeMs); 7277 } 7278 if (mBluetoothUnoptimizedScanTimer != null) { 7279 mBluetoothUnoptimizedScanTimer.stopAllRunningLocked(elapsedRealtimeMs); 7280 } 7281 } 7282 createBluetoothScanResultCounterLocked()7283 public Counter createBluetoothScanResultCounterLocked() { 7284 if (mBluetoothScanResultCounter == null) { 7285 mBluetoothScanResultCounter = new Counter(mBsi.mOnBatteryTimeBase); 7286 } 7287 return mBluetoothScanResultCounter; 7288 } 7289 createBluetoothScanResultBgCounterLocked()7290 public Counter createBluetoothScanResultBgCounterLocked() { 7291 if (mBluetoothScanResultBgCounter == null) { 7292 mBluetoothScanResultBgCounter = new Counter(mOnBatteryBackgroundTimeBase); 7293 } 7294 return mBluetoothScanResultBgCounter; 7295 } 7296 noteBluetoothScanResultsLocked(int numNewResults)7297 public void noteBluetoothScanResultsLocked(int numNewResults) { 7298 createBluetoothScanResultCounterLocked().addAtomic(numNewResults); 7299 // Uses background timebase, so the count will only be incremented if uid in background. 7300 createBluetoothScanResultBgCounterLocked().addAtomic(numNewResults); 7301 } 7302 7303 @Override noteActivityResumedLocked(long elapsedRealtimeMs)7304 public void noteActivityResumedLocked(long elapsedRealtimeMs) { 7305 // We always start, since we want multiple foreground PIDs to nest 7306 createForegroundActivityTimerLocked().startRunningLocked(elapsedRealtimeMs); 7307 } 7308 7309 @Override noteActivityPausedLocked(long elapsedRealtimeMs)7310 public void noteActivityPausedLocked(long elapsedRealtimeMs) { 7311 if (mForegroundActivityTimer != null) { 7312 mForegroundActivityTimer.stopRunningLocked(elapsedRealtimeMs); 7313 } 7314 } 7315 noteForegroundServiceResumedLocked(long elapsedRealtimeMs)7316 public void noteForegroundServiceResumedLocked(long elapsedRealtimeMs) { 7317 createForegroundServiceTimerLocked().startRunningLocked(elapsedRealtimeMs); 7318 } 7319 noteForegroundServicePausedLocked(long elapsedRealtimeMs)7320 public void noteForegroundServicePausedLocked(long elapsedRealtimeMs) { 7321 if (mForegroundServiceTimer != null) { 7322 mForegroundServiceTimer.stopRunningLocked(elapsedRealtimeMs); 7323 } 7324 } 7325 createVibratorOnTimerLocked()7326 public BatchTimer createVibratorOnTimerLocked() { 7327 if (mVibratorOnTimer == null) { 7328 mVibratorOnTimer = new BatchTimer(mBsi.mClocks, Uid.this, VIBRATOR_ON, 7329 mBsi.mOnBatteryTimeBase); 7330 } 7331 return mVibratorOnTimer; 7332 } 7333 noteVibratorOnLocked(long durationMillis)7334 public void noteVibratorOnLocked(long durationMillis) { 7335 createVibratorOnTimerLocked().addDuration(mBsi, durationMillis); 7336 } 7337 noteVibratorOffLocked()7338 public void noteVibratorOffLocked() { 7339 if (mVibratorOnTimer != null) { 7340 mVibratorOnTimer.abortLastDuration(mBsi); 7341 } 7342 } 7343 7344 @Override 7345 @UnsupportedAppUsage getWifiRunningTime(long elapsedRealtimeUs, int which)7346 public long getWifiRunningTime(long elapsedRealtimeUs, int which) { 7347 if (mWifiRunningTimer == null) { 7348 return 0; 7349 } 7350 return mWifiRunningTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 7351 } 7352 7353 @Override getFullWifiLockTime(long elapsedRealtimeUs, int which)7354 public long getFullWifiLockTime(long elapsedRealtimeUs, int which) { 7355 if (mFullWifiLockTimer == null) { 7356 return 0; 7357 } 7358 return mFullWifiLockTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 7359 } 7360 7361 @Override 7362 @UnsupportedAppUsage getWifiScanTime(long elapsedRealtimeUs, int which)7363 public long getWifiScanTime(long elapsedRealtimeUs, int which) { 7364 if (mWifiScanTimer == null) { 7365 return 0; 7366 } 7367 return mWifiScanTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 7368 } 7369 7370 @Override getWifiScanCount(int which)7371 public int getWifiScanCount(int which) { 7372 if (mWifiScanTimer == null) { 7373 return 0; 7374 } 7375 return mWifiScanTimer.getCountLocked(which); 7376 } 7377 7378 @Override getWifiScanTimer()7379 public Timer getWifiScanTimer() { 7380 return mWifiScanTimer; 7381 } 7382 7383 @Override getWifiScanBackgroundCount(int which)7384 public int getWifiScanBackgroundCount(int which) { 7385 if (mWifiScanTimer == null || mWifiScanTimer.getSubTimer() == null) { 7386 return 0; 7387 } 7388 return mWifiScanTimer.getSubTimer().getCountLocked(which); 7389 } 7390 7391 @Override getWifiScanActualTime(final long elapsedRealtimeUs)7392 public long getWifiScanActualTime(final long elapsedRealtimeUs) { 7393 if (mWifiScanTimer == null) { 7394 return 0; 7395 } 7396 final long elapsedRealtimeMs = (elapsedRealtimeUs + 500) / 1000; 7397 return mWifiScanTimer.getTotalDurationMsLocked(elapsedRealtimeMs) * 1000; 7398 } 7399 7400 @Override getWifiScanBackgroundTime(final long elapsedRealtimeUs)7401 public long getWifiScanBackgroundTime(final long elapsedRealtimeUs) { 7402 if (mWifiScanTimer == null || mWifiScanTimer.getSubTimer() == null) { 7403 return 0; 7404 } 7405 final long elapsedRealtimeMs = (elapsedRealtimeUs + 500) / 1000; 7406 return mWifiScanTimer.getSubTimer().getTotalDurationMsLocked(elapsedRealtimeMs) * 1000; 7407 } 7408 7409 @Override getWifiScanBackgroundTimer()7410 public Timer getWifiScanBackgroundTimer() { 7411 if (mWifiScanTimer == null) { 7412 return null; 7413 } 7414 return mWifiScanTimer.getSubTimer(); 7415 } 7416 7417 @Override getWifiBatchedScanTime(int csphBin, long elapsedRealtimeUs, int which)7418 public long getWifiBatchedScanTime(int csphBin, long elapsedRealtimeUs, int which) { 7419 if (csphBin < 0 || csphBin >= NUM_WIFI_BATCHED_SCAN_BINS) return 0; 7420 if (mWifiBatchedScanTimer[csphBin] == null) { 7421 return 0; 7422 } 7423 return mWifiBatchedScanTimer[csphBin].getTotalTimeLocked(elapsedRealtimeUs, which); 7424 } 7425 7426 @Override getWifiBatchedScanCount(int csphBin, int which)7427 public int getWifiBatchedScanCount(int csphBin, int which) { 7428 if (csphBin < 0 || csphBin >= NUM_WIFI_BATCHED_SCAN_BINS) return 0; 7429 if (mWifiBatchedScanTimer[csphBin] == null) { 7430 return 0; 7431 } 7432 return mWifiBatchedScanTimer[csphBin].getCountLocked(which); 7433 } 7434 7435 @Override getWifiMulticastTime(long elapsedRealtimeUs, int which)7436 public long getWifiMulticastTime(long elapsedRealtimeUs, int which) { 7437 if (mWifiMulticastTimer == null) { 7438 return 0; 7439 } 7440 return mWifiMulticastTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 7441 } 7442 7443 @Override getAudioTurnedOnTimer()7444 public Timer getAudioTurnedOnTimer() { 7445 return mAudioTurnedOnTimer; 7446 } 7447 7448 @Override getVideoTurnedOnTimer()7449 public Timer getVideoTurnedOnTimer() { 7450 return mVideoTurnedOnTimer; 7451 } 7452 7453 @Override getFlashlightTurnedOnTimer()7454 public Timer getFlashlightTurnedOnTimer() { 7455 return mFlashlightTurnedOnTimer; 7456 } 7457 7458 @Override getCameraTurnedOnTimer()7459 public Timer getCameraTurnedOnTimer() { 7460 return mCameraTurnedOnTimer; 7461 } 7462 7463 @Override getForegroundActivityTimer()7464 public Timer getForegroundActivityTimer() { 7465 return mForegroundActivityTimer; 7466 } 7467 7468 @Override getForegroundServiceTimer()7469 public Timer getForegroundServiceTimer() { 7470 return mForegroundServiceTimer; 7471 } 7472 7473 @Override getBluetoothScanTimer()7474 public Timer getBluetoothScanTimer() { 7475 return mBluetoothScanTimer; 7476 } 7477 7478 @Override getBluetoothScanBackgroundTimer()7479 public Timer getBluetoothScanBackgroundTimer() { 7480 if (mBluetoothScanTimer == null) { 7481 return null; 7482 } 7483 return mBluetoothScanTimer.getSubTimer(); 7484 } 7485 7486 @Override getBluetoothUnoptimizedScanTimer()7487 public Timer getBluetoothUnoptimizedScanTimer() { 7488 return mBluetoothUnoptimizedScanTimer; 7489 } 7490 7491 @Override getBluetoothUnoptimizedScanBackgroundTimer()7492 public Timer getBluetoothUnoptimizedScanBackgroundTimer() { 7493 if (mBluetoothUnoptimizedScanTimer == null) { 7494 return null; 7495 } 7496 return mBluetoothUnoptimizedScanTimer.getSubTimer(); 7497 } 7498 7499 @Override getBluetoothScanResultCounter()7500 public Counter getBluetoothScanResultCounter() { 7501 return mBluetoothScanResultCounter; 7502 } 7503 7504 @Override getBluetoothScanResultBgCounter()7505 public Counter getBluetoothScanResultBgCounter() { 7506 return mBluetoothScanResultBgCounter; 7507 } 7508 makeProcessState(int i, Parcel in)7509 void makeProcessState(int i, Parcel in) { 7510 if (i < 0 || i >= NUM_PROCESS_STATE) return; 7511 7512 detachIfNotNull(mProcessStateTimer[i]); 7513 if (in == null) { 7514 mProcessStateTimer[i] = new StopwatchTimer(mBsi.mClocks, this, PROCESS_STATE, null, 7515 mBsi.mOnBatteryTimeBase); 7516 } else { 7517 mProcessStateTimer[i] = new StopwatchTimer(mBsi.mClocks, this, PROCESS_STATE, null, 7518 mBsi.mOnBatteryTimeBase, in); 7519 } 7520 } 7521 7522 @Override getProcessStateTime(int state, long elapsedRealtimeUs, int which)7523 public long getProcessStateTime(int state, long elapsedRealtimeUs, int which) { 7524 if (state < 0 || state >= NUM_PROCESS_STATE) return 0; 7525 if (mProcessStateTimer[state] == null) { 7526 return 0; 7527 } 7528 return mProcessStateTimer[state].getTotalTimeLocked(elapsedRealtimeUs, which); 7529 } 7530 7531 @Override getProcessStateTimer(int state)7532 public Timer getProcessStateTimer(int state) { 7533 if (state < 0 || state >= NUM_PROCESS_STATE) return null; 7534 return mProcessStateTimer[state]; 7535 } 7536 7537 @Override getVibratorOnTimer()7538 public Timer getVibratorOnTimer() { 7539 return mVibratorOnTimer; 7540 } 7541 7542 @Override noteUserActivityLocked(int type)7543 public void noteUserActivityLocked(int type) { 7544 if (mUserActivityCounters == null) { 7545 initUserActivityLocked(); 7546 } 7547 if (type >= 0 && type < NUM_USER_ACTIVITY_TYPES) { 7548 mUserActivityCounters[type].stepAtomic(); 7549 } else { 7550 Slog.w(TAG, "Unknown user activity type " + type + " was specified.", 7551 new Throwable()); 7552 } 7553 } 7554 7555 @Override hasUserActivity()7556 public boolean hasUserActivity() { 7557 return mUserActivityCounters != null; 7558 } 7559 7560 @Override getUserActivityCount(int type, int which)7561 public int getUserActivityCount(int type, int which) { 7562 if (mUserActivityCounters == null) { 7563 return 0; 7564 } 7565 return mUserActivityCounters[type].getCountLocked(which); 7566 } 7567 makeWifiBatchedScanBin(int i, Parcel in)7568 void makeWifiBatchedScanBin(int i, Parcel in) { 7569 if (i < 0 || i >= NUM_WIFI_BATCHED_SCAN_BINS) return; 7570 7571 ArrayList<StopwatchTimer> collected = mBsi.mWifiBatchedScanTimers.get(i); 7572 if (collected == null) { 7573 collected = new ArrayList<StopwatchTimer>(); 7574 mBsi.mWifiBatchedScanTimers.put(i, collected); 7575 } 7576 detachIfNotNull(mWifiBatchedScanTimer[i]); 7577 if (in == null) { 7578 mWifiBatchedScanTimer[i] = new StopwatchTimer(mBsi.mClocks, this, WIFI_BATCHED_SCAN, 7579 collected, mBsi.mOnBatteryTimeBase); 7580 } else { 7581 mWifiBatchedScanTimer[i] = new StopwatchTimer(mBsi.mClocks, this, WIFI_BATCHED_SCAN, 7582 collected, mBsi.mOnBatteryTimeBase, in); 7583 } 7584 } 7585 7586 initUserActivityLocked()7587 void initUserActivityLocked() { 7588 detachIfNotNull(mUserActivityCounters); 7589 mUserActivityCounters = new Counter[NUM_USER_ACTIVITY_TYPES]; 7590 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) { 7591 mUserActivityCounters[i] = new Counter(mBsi.mOnBatteryTimeBase); 7592 } 7593 } 7594 noteNetworkActivityLocked(int type, long deltaBytes, long deltaPackets)7595 void noteNetworkActivityLocked(int type, long deltaBytes, long deltaPackets) { 7596 if (mNetworkByteActivityCounters == null) { 7597 initNetworkActivityLocked(); 7598 } 7599 if (type >= 0 && type < NUM_NETWORK_ACTIVITY_TYPES) { 7600 mNetworkByteActivityCounters[type].addCountLocked(deltaBytes); 7601 mNetworkPacketActivityCounters[type].addCountLocked(deltaPackets); 7602 } else { 7603 Slog.w(TAG, "Unknown network activity type " + type + " was specified.", 7604 new Throwable()); 7605 } 7606 } 7607 noteMobileRadioActiveTimeLocked(long batteryUptime)7608 void noteMobileRadioActiveTimeLocked(long batteryUptime) { 7609 if (mNetworkByteActivityCounters == null) { 7610 initNetworkActivityLocked(); 7611 } 7612 mMobileRadioActiveTime.addCountLocked(batteryUptime); 7613 mMobileRadioActiveCount.addCountLocked(1); 7614 } 7615 7616 @Override hasNetworkActivity()7617 public boolean hasNetworkActivity() { 7618 return mNetworkByteActivityCounters != null; 7619 } 7620 7621 @Override getNetworkActivityBytes(int type, int which)7622 public long getNetworkActivityBytes(int type, int which) { 7623 if (mNetworkByteActivityCounters != null && type >= 0 7624 && type < mNetworkByteActivityCounters.length) { 7625 return mNetworkByteActivityCounters[type].getCountLocked(which); 7626 } else { 7627 return 0; 7628 } 7629 } 7630 7631 @Override getNetworkActivityPackets(int type, int which)7632 public long getNetworkActivityPackets(int type, int which) { 7633 if (mNetworkPacketActivityCounters != null && type >= 0 7634 && type < mNetworkPacketActivityCounters.length) { 7635 return mNetworkPacketActivityCounters[type].getCountLocked(which); 7636 } else { 7637 return 0; 7638 } 7639 } 7640 7641 @Override getMobileRadioActiveTime(int which)7642 public long getMobileRadioActiveTime(int which) { 7643 return mMobileRadioActiveTime != null 7644 ? mMobileRadioActiveTime.getCountLocked(which) : 0; 7645 } 7646 7647 @Override getMobileRadioActiveCount(int which)7648 public int getMobileRadioActiveCount(int which) { 7649 return mMobileRadioActiveCount != null 7650 ? (int)mMobileRadioActiveCount.getCountLocked(which) : 0; 7651 } 7652 7653 @Override getUserCpuTimeUs(int which)7654 public long getUserCpuTimeUs(int which) { 7655 return mUserCpuTime.getCountLocked(which); 7656 } 7657 7658 @Override getSystemCpuTimeUs(int which)7659 public long getSystemCpuTimeUs(int which) { 7660 return mSystemCpuTime.getCountLocked(which); 7661 } 7662 7663 @Override getTimeAtCpuSpeed(int cluster, int step, int which)7664 public long getTimeAtCpuSpeed(int cluster, int step, int which) { 7665 if (mCpuClusterSpeedTimesUs != null) { 7666 if (cluster >= 0 && cluster < mCpuClusterSpeedTimesUs.length) { 7667 final LongSamplingCounter[] cpuSpeedTimesUs = mCpuClusterSpeedTimesUs[cluster]; 7668 if (cpuSpeedTimesUs != null) { 7669 if (step >= 0 && step < cpuSpeedTimesUs.length) { 7670 final LongSamplingCounter c = cpuSpeedTimesUs[step]; 7671 if (c != null) { 7672 return c.getCountLocked(which); 7673 } 7674 } 7675 } 7676 } 7677 } 7678 return 0; 7679 } 7680 noteMobileRadioApWakeupLocked()7681 public void noteMobileRadioApWakeupLocked() { 7682 if (mMobileRadioApWakeupCount == null) { 7683 mMobileRadioApWakeupCount = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); 7684 } 7685 mMobileRadioApWakeupCount.addCountLocked(1); 7686 } 7687 7688 @Override getMobileRadioApWakeupCount(int which)7689 public long getMobileRadioApWakeupCount(int which) { 7690 if (mMobileRadioApWakeupCount != null) { 7691 return mMobileRadioApWakeupCount.getCountLocked(which); 7692 } 7693 return 0; 7694 } 7695 noteWifiRadioApWakeupLocked()7696 public void noteWifiRadioApWakeupLocked() { 7697 if (mWifiRadioApWakeupCount == null) { 7698 mWifiRadioApWakeupCount = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); 7699 } 7700 mWifiRadioApWakeupCount.addCountLocked(1); 7701 } 7702 7703 @Override getWifiRadioApWakeupCount(int which)7704 public long getWifiRadioApWakeupCount(int which) { 7705 if (mWifiRadioApWakeupCount != null) { 7706 return mWifiRadioApWakeupCount.getCountLocked(which); 7707 } 7708 return 0; 7709 } 7710 7711 @Override getDeferredJobsCheckinLineLocked(StringBuilder sb, int which)7712 public void getDeferredJobsCheckinLineLocked(StringBuilder sb, int which) { 7713 sb.setLength(0); 7714 final int deferredEventCount = mJobsDeferredEventCount.getCountLocked(which); 7715 if (deferredEventCount == 0) { 7716 return; 7717 } 7718 final int deferredCount = mJobsDeferredCount.getCountLocked(which); 7719 final long totalLatency = mJobsFreshnessTimeMs.getCountLocked(which); 7720 sb.append(deferredEventCount); sb.append(','); 7721 sb.append(deferredCount); sb.append(','); 7722 sb.append(totalLatency); 7723 for (int i = 0; i < JOB_FRESHNESS_BUCKETS.length; i++) { 7724 if (mJobsFreshnessBuckets[i] == null) { 7725 sb.append(",0"); 7726 } else { 7727 sb.append(","); 7728 sb.append(mJobsFreshnessBuckets[i].getCountLocked(which)); 7729 } 7730 } 7731 } 7732 7733 @Override getDeferredJobsLineLocked(StringBuilder sb, int which)7734 public void getDeferredJobsLineLocked(StringBuilder sb, int which) { 7735 sb.setLength(0); 7736 final int deferredEventCount = mJobsDeferredEventCount.getCountLocked(which); 7737 if (deferredEventCount == 0) { 7738 return; 7739 } 7740 final int deferredCount = mJobsDeferredCount.getCountLocked(which); 7741 final long totalLatency = mJobsFreshnessTimeMs.getCountLocked(which); 7742 sb.append("times="); sb.append(deferredEventCount); sb.append(", "); 7743 sb.append("count="); sb.append(deferredCount); sb.append(", "); 7744 sb.append("totalLatencyMs="); sb.append(totalLatency); sb.append(", "); 7745 for (int i = 0; i < JOB_FRESHNESS_BUCKETS.length; i++) { 7746 sb.append("<"); sb.append(JOB_FRESHNESS_BUCKETS[i]); sb.append("ms="); 7747 if (mJobsFreshnessBuckets[i] == null) { 7748 sb.append("0"); 7749 } else { 7750 sb.append(mJobsFreshnessBuckets[i].getCountLocked(which)); 7751 } 7752 sb.append(" "); 7753 } 7754 } 7755 initNetworkActivityLocked()7756 void initNetworkActivityLocked() { 7757 detachIfNotNull(mNetworkByteActivityCounters); 7758 mNetworkByteActivityCounters = new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES]; 7759 detachIfNotNull(mNetworkPacketActivityCounters); 7760 mNetworkPacketActivityCounters = new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES]; 7761 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 7762 mNetworkByteActivityCounters[i] = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); 7763 mNetworkPacketActivityCounters[i] = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); 7764 } 7765 detachIfNotNull(mMobileRadioActiveTime); 7766 mMobileRadioActiveTime = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); 7767 detachIfNotNull(mMobileRadioActiveCount); 7768 mMobileRadioActiveCount = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); 7769 } 7770 7771 /** 7772 * Clear all stats for this uid. Returns true if the uid is completely 7773 * inactive so can be dropped. 7774 */ 7775 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) reset(long uptime, long realtime)7776 public boolean reset(long uptime, long realtime) { 7777 boolean active = false; 7778 7779 mOnBatteryBackgroundTimeBase.init(uptime, realtime); 7780 mOnBatteryScreenOffBackgroundTimeBase.init(uptime, realtime); 7781 7782 if (mWifiRunningTimer != null) { 7783 active |= !mWifiRunningTimer.reset(false); 7784 active |= mWifiRunning; 7785 } 7786 if (mFullWifiLockTimer != null) { 7787 active |= !mFullWifiLockTimer.reset(false); 7788 active |= mFullWifiLockOut; 7789 } 7790 if (mWifiScanTimer != null) { 7791 active |= !mWifiScanTimer.reset(false); 7792 active |= mWifiScanStarted; 7793 } 7794 if (mWifiBatchedScanTimer != null) { 7795 for (int i = 0; i < NUM_WIFI_BATCHED_SCAN_BINS; i++) { 7796 if (mWifiBatchedScanTimer[i] != null) { 7797 active |= !mWifiBatchedScanTimer[i].reset(false); 7798 } 7799 } 7800 active |= (mWifiBatchedScanBinStarted != NO_BATCHED_SCAN_STARTED); 7801 } 7802 if (mWifiMulticastTimer != null) { 7803 active |= !mWifiMulticastTimer.reset(false); 7804 active |= (mWifiMulticastWakelockCount > 0); 7805 } 7806 7807 active |= !resetIfNotNull(mAudioTurnedOnTimer, false); 7808 active |= !resetIfNotNull(mVideoTurnedOnTimer, false); 7809 active |= !resetIfNotNull(mFlashlightTurnedOnTimer, false); 7810 active |= !resetIfNotNull(mCameraTurnedOnTimer, false); 7811 active |= !resetIfNotNull(mForegroundActivityTimer, false); 7812 active |= !resetIfNotNull(mForegroundServiceTimer, false); 7813 active |= !resetIfNotNull(mAggregatedPartialWakelockTimer, false); 7814 active |= !resetIfNotNull(mBluetoothScanTimer, false); 7815 active |= !resetIfNotNull(mBluetoothUnoptimizedScanTimer, false); 7816 7817 resetIfNotNull(mBluetoothScanResultCounter, false); 7818 resetIfNotNull(mBluetoothScanResultBgCounter, false); 7819 7820 if (mProcessStateTimer != null) { 7821 for (int i = 0; i < NUM_PROCESS_STATE; i++) { 7822 active |= !resetIfNotNull(mProcessStateTimer[i], false); 7823 } 7824 active |= (mProcessState != ActivityManager.PROCESS_STATE_NONEXISTENT); 7825 } 7826 if (mVibratorOnTimer != null) { 7827 if (mVibratorOnTimer.reset(false)) { 7828 mVibratorOnTimer.detach(); 7829 mVibratorOnTimer = null; 7830 } else { 7831 active = true; 7832 } 7833 } 7834 7835 resetIfNotNull(mUserActivityCounters, false); 7836 7837 resetIfNotNull(mNetworkByteActivityCounters, false); 7838 resetIfNotNull(mNetworkPacketActivityCounters, false); 7839 resetIfNotNull(mMobileRadioActiveTime, false); 7840 resetIfNotNull(mMobileRadioActiveCount, false); 7841 7842 resetIfNotNull(mWifiControllerActivity, false); 7843 resetIfNotNull(mBluetoothControllerActivity, false); 7844 resetIfNotNull(mModemControllerActivity, false); 7845 7846 resetIfNotNull(mUserCpuTime, false); 7847 resetIfNotNull(mSystemCpuTime, false); 7848 7849 resetIfNotNull(mCpuClusterSpeedTimesUs, false); 7850 7851 resetIfNotNull(mCpuFreqTimeMs, false); 7852 resetIfNotNull(mScreenOffCpuFreqTimeMs, false); 7853 7854 7855 resetIfNotNull(mCpuActiveTimeMs, false); 7856 resetIfNotNull(mCpuClusterTimesMs, false); 7857 7858 resetIfNotNull(mProcStateTimeMs, false); 7859 7860 resetIfNotNull(mProcStateScreenOffTimeMs, false); 7861 7862 resetIfNotNull(mMobileRadioApWakeupCount, false); 7863 7864 resetIfNotNull(mWifiRadioApWakeupCount, false); 7865 7866 7867 final ArrayMap<String, Wakelock> wakeStats = mWakelockStats.getMap(); 7868 for (int iw=wakeStats.size()-1; iw>=0; iw--) { 7869 Wakelock wl = wakeStats.valueAt(iw); 7870 if (wl.reset()) { 7871 wakeStats.removeAt(iw); 7872 } else { 7873 active = true; 7874 } 7875 } 7876 mWakelockStats.cleanup(); 7877 final ArrayMap<String, DualTimer> syncStats = mSyncStats.getMap(); 7878 for (int is=syncStats.size()-1; is>=0; is--) { 7879 DualTimer timer = syncStats.valueAt(is); 7880 if (timer.reset(false)) { 7881 syncStats.removeAt(is); 7882 timer.detach(); 7883 } else { 7884 active = true; 7885 } 7886 } 7887 mSyncStats.cleanup(); 7888 final ArrayMap<String, DualTimer> jobStats = mJobStats.getMap(); 7889 for (int ij=jobStats.size()-1; ij>=0; ij--) { 7890 DualTimer timer = jobStats.valueAt(ij); 7891 if (timer.reset(false)) { 7892 jobStats.removeAt(ij); 7893 timer.detach(); 7894 } else { 7895 active = true; 7896 } 7897 } 7898 mJobStats.cleanup(); 7899 mJobCompletions.clear(); 7900 7901 resetIfNotNull(mJobsDeferredEventCount, false); 7902 resetIfNotNull(mJobsDeferredCount, false); 7903 resetIfNotNull(mJobsFreshnessTimeMs, false); 7904 resetIfNotNull(mJobsFreshnessBuckets, false); 7905 7906 for (int ise = mSensorStats.size() - 1; ise >= 0; ise--) { 7907 Sensor s = mSensorStats.valueAt(ise); 7908 if (s.reset()) { 7909 mSensorStats.removeAt(ise); 7910 } else { 7911 active = true; 7912 } 7913 } 7914 7915 for (int ip = mProcessStats.size() - 1; ip >= 0; ip--) { 7916 Proc proc = mProcessStats.valueAt(ip); 7917 proc.detach(); 7918 } 7919 mProcessStats.clear(); 7920 7921 for (int i = mPids.size() - 1; i >= 0; i--) { 7922 Pid pid = mPids.valueAt(i); 7923 if (pid.mWakeNesting > 0) { 7924 active = true; 7925 } else { 7926 mPids.removeAt(i); 7927 } 7928 } 7929 7930 7931 for(int i = mPackageStats.size() - 1; i >= 0; i--) { 7932 Pkg p = mPackageStats.valueAt(i); 7933 p.detach(); 7934 } 7935 mPackageStats.clear(); 7936 7937 mLastStepUserTime = mLastStepSystemTime = 0; 7938 mCurStepUserTime = mCurStepSystemTime = 0; 7939 7940 return !active; 7941 } 7942 7943 /** 7944 * This method MUST be called whenever the Uid object is destructed, otherwise it is a 7945 * memory leak in {@link TimeBase#mObservers} list. 7946 * Typically the Uid object is destructed when it is removed from 7947 * {@link BatteryStatsImpl#mUidStats} 7948 */ detachFromTimeBase()7949 void detachFromTimeBase() { 7950 detachIfNotNull(mWifiRunningTimer); 7951 detachIfNotNull(mFullWifiLockTimer); 7952 detachIfNotNull(mWifiScanTimer); 7953 detachIfNotNull(mWifiBatchedScanTimer); 7954 detachIfNotNull(mWifiMulticastTimer); 7955 detachIfNotNull(mAudioTurnedOnTimer); 7956 detachIfNotNull(mVideoTurnedOnTimer); 7957 detachIfNotNull(mFlashlightTurnedOnTimer); 7958 7959 detachIfNotNull(mCameraTurnedOnTimer); 7960 detachIfNotNull(mForegroundActivityTimer); 7961 detachIfNotNull(mForegroundServiceTimer); 7962 7963 detachIfNotNull(mAggregatedPartialWakelockTimer); 7964 7965 detachIfNotNull(mBluetoothScanTimer); 7966 detachIfNotNull(mBluetoothUnoptimizedScanTimer); 7967 detachIfNotNull(mBluetoothScanResultCounter); 7968 detachIfNotNull(mBluetoothScanResultBgCounter); 7969 7970 detachIfNotNull(mProcessStateTimer); 7971 7972 detachIfNotNull(mVibratorOnTimer); 7973 7974 detachIfNotNull(mUserActivityCounters); 7975 7976 detachIfNotNull(mNetworkByteActivityCounters); 7977 detachIfNotNull(mNetworkPacketActivityCounters); 7978 7979 detachIfNotNull(mMobileRadioActiveTime); 7980 detachIfNotNull(mMobileRadioActiveCount); 7981 detachIfNotNull(mMobileRadioApWakeupCount); 7982 detachIfNotNull(mWifiRadioApWakeupCount); 7983 7984 detachIfNotNull(mWifiControllerActivity); 7985 detachIfNotNull(mBluetoothControllerActivity); 7986 detachIfNotNull(mModemControllerActivity); 7987 7988 mPids.clear(); 7989 7990 detachIfNotNull(mUserCpuTime); 7991 detachIfNotNull(mSystemCpuTime); 7992 7993 detachIfNotNull(mCpuClusterSpeedTimesUs); 7994 7995 detachIfNotNull(mCpuActiveTimeMs); 7996 detachIfNotNull(mCpuFreqTimeMs); 7997 7998 detachIfNotNull(mScreenOffCpuFreqTimeMs); 7999 8000 detachIfNotNull(mCpuClusterTimesMs); 8001 8002 detachIfNotNull(mProcStateTimeMs); 8003 8004 detachIfNotNull(mProcStateScreenOffTimeMs); 8005 8006 final ArrayMap<String, Wakelock> wakeStats = mWakelockStats.getMap(); 8007 for (int iw = wakeStats.size() - 1; iw >= 0; iw--) { 8008 Wakelock wl = wakeStats.valueAt(iw); 8009 wl.detachFromTimeBase(); 8010 } 8011 final ArrayMap<String, DualTimer> syncStats = mSyncStats.getMap(); 8012 for (int is = syncStats.size() - 1; is >= 0; is--) { 8013 DualTimer timer = syncStats.valueAt(is); 8014 detachIfNotNull(timer); 8015 } 8016 final ArrayMap<String, DualTimer> jobStats = mJobStats.getMap(); 8017 for (int ij = jobStats.size() - 1; ij >= 0; ij--) { 8018 DualTimer timer = jobStats.valueAt(ij); 8019 detachIfNotNull(timer); 8020 } 8021 8022 detachIfNotNull(mJobsDeferredEventCount); 8023 detachIfNotNull(mJobsDeferredCount); 8024 detachIfNotNull(mJobsFreshnessTimeMs); 8025 detachIfNotNull(mJobsFreshnessBuckets); 8026 8027 8028 for (int ise = mSensorStats.size() - 1; ise >= 0; ise--) { 8029 Sensor s = mSensorStats.valueAt(ise); 8030 s.detachFromTimeBase(); 8031 } 8032 8033 for (int ip= mProcessStats.size() - 1; ip >= 0; ip--) { 8034 Proc proc = mProcessStats.valueAt(ip); 8035 proc.detach(); 8036 } 8037 mProcessStats.clear(); 8038 8039 for(int i = mPackageStats.size() - 1; i >= 0; i--) { 8040 Pkg p = mPackageStats.valueAt(i); 8041 p.detach(); 8042 } 8043 mPackageStats.clear(); 8044 } 8045 writeJobCompletionsToParcelLocked(Parcel out)8046 void writeJobCompletionsToParcelLocked(Parcel out) { 8047 int NJC = mJobCompletions.size(); 8048 out.writeInt(NJC); 8049 for (int ijc=0; ijc<NJC; ijc++) { 8050 out.writeString(mJobCompletions.keyAt(ijc)); 8051 SparseIntArray types = mJobCompletions.valueAt(ijc); 8052 int NT = types.size(); 8053 out.writeInt(NT); 8054 for (int it=0; it<NT; it++) { 8055 out.writeInt(types.keyAt(it)); 8056 out.writeInt(types.valueAt(it)); 8057 } 8058 } 8059 } 8060 writeToParcelLocked(Parcel out, long uptimeUs, long elapsedRealtimeUs)8061 void writeToParcelLocked(Parcel out, long uptimeUs, long elapsedRealtimeUs) { 8062 mOnBatteryBackgroundTimeBase.writeToParcel(out, uptimeUs, elapsedRealtimeUs); 8063 mOnBatteryScreenOffBackgroundTimeBase.writeToParcel(out, uptimeUs, elapsedRealtimeUs); 8064 8065 final ArrayMap<String, Wakelock> wakeStats = mWakelockStats.getMap(); 8066 int NW = wakeStats.size(); 8067 out.writeInt(NW); 8068 for (int iw=0; iw<NW; iw++) { 8069 out.writeString(wakeStats.keyAt(iw)); 8070 Uid.Wakelock wakelock = wakeStats.valueAt(iw); 8071 wakelock.writeToParcelLocked(out, elapsedRealtimeUs); 8072 } 8073 8074 final ArrayMap<String, DualTimer> syncStats = mSyncStats.getMap(); 8075 int NS = syncStats.size(); 8076 out.writeInt(NS); 8077 for (int is=0; is<NS; is++) { 8078 out.writeString(syncStats.keyAt(is)); 8079 DualTimer timer = syncStats.valueAt(is); 8080 Timer.writeTimerToParcel(out, timer, elapsedRealtimeUs); 8081 } 8082 8083 final ArrayMap<String, DualTimer> jobStats = mJobStats.getMap(); 8084 int NJ = jobStats.size(); 8085 out.writeInt(NJ); 8086 for (int ij=0; ij<NJ; ij++) { 8087 out.writeString(jobStats.keyAt(ij)); 8088 DualTimer timer = jobStats.valueAt(ij); 8089 Timer.writeTimerToParcel(out, timer, elapsedRealtimeUs); 8090 } 8091 8092 writeJobCompletionsToParcelLocked(out); 8093 8094 mJobsDeferredEventCount.writeToParcel(out); 8095 mJobsDeferredCount.writeToParcel(out); 8096 mJobsFreshnessTimeMs.writeToParcel(out); 8097 for (int i = 0; i < JOB_FRESHNESS_BUCKETS.length; i++) { 8098 Counter.writeCounterToParcel(out, mJobsFreshnessBuckets[i]); 8099 } 8100 8101 int NSE = mSensorStats.size(); 8102 out.writeInt(NSE); 8103 for (int ise=0; ise<NSE; ise++) { 8104 out.writeInt(mSensorStats.keyAt(ise)); 8105 Uid.Sensor sensor = mSensorStats.valueAt(ise); 8106 sensor.writeToParcelLocked(out, elapsedRealtimeUs); 8107 } 8108 8109 int NP = mProcessStats.size(); 8110 out.writeInt(NP); 8111 for (int ip=0; ip<NP; ip++) { 8112 out.writeString(mProcessStats.keyAt(ip)); 8113 Uid.Proc proc = mProcessStats.valueAt(ip); 8114 proc.writeToParcelLocked(out); 8115 } 8116 8117 out.writeInt(mPackageStats.size()); 8118 for (Map.Entry<String, Uid.Pkg> pkgEntry : mPackageStats.entrySet()) { 8119 out.writeString(pkgEntry.getKey()); 8120 Uid.Pkg pkg = pkgEntry.getValue(); 8121 pkg.writeToParcelLocked(out); 8122 } 8123 8124 if (mWifiRunningTimer != null) { 8125 out.writeInt(1); 8126 mWifiRunningTimer.writeToParcel(out, elapsedRealtimeUs); 8127 } else { 8128 out.writeInt(0); 8129 } 8130 if (mFullWifiLockTimer != null) { 8131 out.writeInt(1); 8132 mFullWifiLockTimer.writeToParcel(out, elapsedRealtimeUs); 8133 } else { 8134 out.writeInt(0); 8135 } 8136 if (mWifiScanTimer != null) { 8137 out.writeInt(1); 8138 mWifiScanTimer.writeToParcel(out, elapsedRealtimeUs); 8139 } else { 8140 out.writeInt(0); 8141 } 8142 for (int i = 0; i < NUM_WIFI_BATCHED_SCAN_BINS; i++) { 8143 if (mWifiBatchedScanTimer[i] != null) { 8144 out.writeInt(1); 8145 mWifiBatchedScanTimer[i].writeToParcel(out, elapsedRealtimeUs); 8146 } else { 8147 out.writeInt(0); 8148 } 8149 } 8150 if (mWifiMulticastTimer != null) { 8151 out.writeInt(1); 8152 mWifiMulticastTimer.writeToParcel(out, elapsedRealtimeUs); 8153 } else { 8154 out.writeInt(0); 8155 } 8156 8157 if (mAudioTurnedOnTimer != null) { 8158 out.writeInt(1); 8159 mAudioTurnedOnTimer.writeToParcel(out, elapsedRealtimeUs); 8160 } else { 8161 out.writeInt(0); 8162 } 8163 if (mVideoTurnedOnTimer != null) { 8164 out.writeInt(1); 8165 mVideoTurnedOnTimer.writeToParcel(out, elapsedRealtimeUs); 8166 } else { 8167 out.writeInt(0); 8168 } 8169 if (mFlashlightTurnedOnTimer != null) { 8170 out.writeInt(1); 8171 mFlashlightTurnedOnTimer.writeToParcel(out, elapsedRealtimeUs); 8172 } else { 8173 out.writeInt(0); 8174 } 8175 if (mCameraTurnedOnTimer != null) { 8176 out.writeInt(1); 8177 mCameraTurnedOnTimer.writeToParcel(out, elapsedRealtimeUs); 8178 } else { 8179 out.writeInt(0); 8180 } 8181 if (mForegroundActivityTimer != null) { 8182 out.writeInt(1); 8183 mForegroundActivityTimer.writeToParcel(out, elapsedRealtimeUs); 8184 } else { 8185 out.writeInt(0); 8186 } 8187 if (mForegroundServiceTimer != null) { 8188 out.writeInt(1); 8189 mForegroundServiceTimer.writeToParcel(out, elapsedRealtimeUs); 8190 } else { 8191 out.writeInt(0); 8192 } 8193 if (mAggregatedPartialWakelockTimer != null) { 8194 out.writeInt(1); 8195 mAggregatedPartialWakelockTimer.writeToParcel(out, elapsedRealtimeUs); 8196 } else { 8197 out.writeInt(0); 8198 } 8199 if (mBluetoothScanTimer != null) { 8200 out.writeInt(1); 8201 mBluetoothScanTimer.writeToParcel(out, elapsedRealtimeUs); 8202 } else { 8203 out.writeInt(0); 8204 } 8205 if (mBluetoothUnoptimizedScanTimer != null) { 8206 out.writeInt(1); 8207 mBluetoothUnoptimizedScanTimer.writeToParcel(out, elapsedRealtimeUs); 8208 } else { 8209 out.writeInt(0); 8210 } 8211 if (mBluetoothScanResultCounter != null) { 8212 out.writeInt(1); 8213 mBluetoothScanResultCounter.writeToParcel(out); 8214 } else { 8215 out.writeInt(0); 8216 } 8217 if (mBluetoothScanResultBgCounter != null) { 8218 out.writeInt(1); 8219 mBluetoothScanResultBgCounter.writeToParcel(out); 8220 } else { 8221 out.writeInt(0); 8222 } 8223 for (int i = 0; i < NUM_PROCESS_STATE; i++) { 8224 if (mProcessStateTimer[i] != null) { 8225 out.writeInt(1); 8226 mProcessStateTimer[i].writeToParcel(out, elapsedRealtimeUs); 8227 } else { 8228 out.writeInt(0); 8229 } 8230 } 8231 if (mVibratorOnTimer != null) { 8232 out.writeInt(1); 8233 mVibratorOnTimer.writeToParcel(out, elapsedRealtimeUs); 8234 } else { 8235 out.writeInt(0); 8236 } 8237 if (mUserActivityCounters != null) { 8238 out.writeInt(1); 8239 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) { 8240 mUserActivityCounters[i].writeToParcel(out); 8241 } 8242 } else { 8243 out.writeInt(0); 8244 } 8245 if (mNetworkByteActivityCounters != null) { 8246 out.writeInt(1); 8247 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 8248 mNetworkByteActivityCounters[i].writeToParcel(out); 8249 mNetworkPacketActivityCounters[i].writeToParcel(out); 8250 } 8251 mMobileRadioActiveTime.writeToParcel(out); 8252 mMobileRadioActiveCount.writeToParcel(out); 8253 } else { 8254 out.writeInt(0); 8255 } 8256 8257 if (mWifiControllerActivity != null) { 8258 out.writeInt(1); 8259 mWifiControllerActivity.writeToParcel(out, 0); 8260 } else { 8261 out.writeInt(0); 8262 } 8263 8264 if (mBluetoothControllerActivity != null) { 8265 out.writeInt(1); 8266 mBluetoothControllerActivity.writeToParcel(out, 0); 8267 } else { 8268 out.writeInt(0); 8269 } 8270 8271 if (mModemControllerActivity != null) { 8272 out.writeInt(1); 8273 mModemControllerActivity.writeToParcel(out, 0); 8274 } else { 8275 out.writeInt(0); 8276 } 8277 8278 mUserCpuTime.writeToParcel(out); 8279 mSystemCpuTime.writeToParcel(out); 8280 8281 if (mCpuClusterSpeedTimesUs != null) { 8282 out.writeInt(1); 8283 out.writeInt(mCpuClusterSpeedTimesUs.length); 8284 for (LongSamplingCounter[] cpuSpeeds : mCpuClusterSpeedTimesUs) { 8285 if (cpuSpeeds != null) { 8286 out.writeInt(1); 8287 out.writeInt(cpuSpeeds.length); 8288 for (LongSamplingCounter c : cpuSpeeds) { 8289 if (c != null) { 8290 out.writeInt(1); 8291 c.writeToParcel(out); 8292 } else { 8293 out.writeInt(0); 8294 } 8295 } 8296 } else { 8297 out.writeInt(0); 8298 } 8299 } 8300 } else { 8301 out.writeInt(0); 8302 } 8303 8304 LongSamplingCounterArray.writeToParcel(out, mCpuFreqTimeMs); 8305 LongSamplingCounterArray.writeToParcel(out, mScreenOffCpuFreqTimeMs); 8306 8307 mCpuActiveTimeMs.writeToParcel(out); 8308 mCpuClusterTimesMs.writeToParcel(out); 8309 8310 if (mProcStateTimeMs != null) { 8311 out.writeInt(mProcStateTimeMs.length); 8312 for (LongSamplingCounterArray counters : mProcStateTimeMs) { 8313 LongSamplingCounterArray.writeToParcel(out, counters); 8314 } 8315 } else { 8316 out.writeInt(0); 8317 } 8318 if (mProcStateScreenOffTimeMs != null) { 8319 out.writeInt(mProcStateScreenOffTimeMs.length); 8320 for (LongSamplingCounterArray counters : mProcStateScreenOffTimeMs) { 8321 LongSamplingCounterArray.writeToParcel(out, counters); 8322 } 8323 } else { 8324 out.writeInt(0); 8325 } 8326 8327 if (mMobileRadioApWakeupCount != null) { 8328 out.writeInt(1); 8329 mMobileRadioApWakeupCount.writeToParcel(out); 8330 } else { 8331 out.writeInt(0); 8332 } 8333 8334 if (mWifiRadioApWakeupCount != null) { 8335 out.writeInt(1); 8336 mWifiRadioApWakeupCount.writeToParcel(out); 8337 } else { 8338 out.writeInt(0); 8339 } 8340 } 8341 readJobCompletionsFromParcelLocked(Parcel in)8342 void readJobCompletionsFromParcelLocked(Parcel in) { 8343 int numJobCompletions = in.readInt(); 8344 mJobCompletions.clear(); 8345 for (int j = 0; j < numJobCompletions; j++) { 8346 String jobName = in.readString(); 8347 int numTypes = in.readInt(); 8348 if (numTypes > 0) { 8349 SparseIntArray types = new SparseIntArray(); 8350 for (int k = 0; k < numTypes; k++) { 8351 int type = in.readInt(); 8352 int count = in.readInt(); 8353 types.put(type, count); 8354 } 8355 mJobCompletions.put(jobName, types); 8356 } 8357 } 8358 } 8359 readFromParcelLocked(TimeBase timeBase, TimeBase screenOffTimeBase, Parcel in)8360 void readFromParcelLocked(TimeBase timeBase, TimeBase screenOffTimeBase, Parcel in) { 8361 mOnBatteryBackgroundTimeBase.readFromParcel(in); 8362 mOnBatteryScreenOffBackgroundTimeBase.readFromParcel(in); 8363 8364 int numWakelocks = in.readInt(); 8365 mWakelockStats.clear(); 8366 for (int j = 0; j < numWakelocks; j++) { 8367 String wakelockName = in.readString(); 8368 Uid.Wakelock wakelock = new Wakelock(mBsi, this); 8369 wakelock.readFromParcelLocked( 8370 timeBase, screenOffTimeBase, mOnBatteryScreenOffBackgroundTimeBase, in); 8371 mWakelockStats.add(wakelockName, wakelock); 8372 } 8373 8374 int numSyncs = in.readInt(); 8375 mSyncStats.clear(); 8376 for (int j = 0; j < numSyncs; j++) { 8377 String syncName = in.readString(); 8378 if (in.readInt() != 0) { 8379 mSyncStats.add(syncName, new DualTimer(mBsi.mClocks, Uid.this, SYNC, null, 8380 mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase, in)); 8381 } 8382 } 8383 8384 int numJobs = in.readInt(); 8385 mJobStats.clear(); 8386 for (int j = 0; j < numJobs; j++) { 8387 String jobName = in.readString(); 8388 if (in.readInt() != 0) { 8389 mJobStats.add(jobName, new DualTimer(mBsi.mClocks, Uid.this, JOB, null, 8390 mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase, in)); 8391 } 8392 } 8393 8394 readJobCompletionsFromParcelLocked(in); 8395 8396 mJobsDeferredEventCount = new Counter(mBsi.mOnBatteryTimeBase, in); 8397 mJobsDeferredCount = new Counter(mBsi.mOnBatteryTimeBase, in); 8398 mJobsFreshnessTimeMs = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in); 8399 for (int i = 0; i < JOB_FRESHNESS_BUCKETS.length; i++) { 8400 mJobsFreshnessBuckets[i] = Counter.readCounterFromParcel(mBsi.mOnBatteryTimeBase, 8401 in); 8402 } 8403 8404 int numSensors = in.readInt(); 8405 mSensorStats.clear(); 8406 for (int k = 0; k < numSensors; k++) { 8407 int sensorNumber = in.readInt(); 8408 Uid.Sensor sensor = new Sensor(mBsi, this, sensorNumber); 8409 sensor.readFromParcelLocked(mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase, 8410 in); 8411 mSensorStats.put(sensorNumber, sensor); 8412 } 8413 8414 int numProcs = in.readInt(); 8415 mProcessStats.clear(); 8416 for (int k = 0; k < numProcs; k++) { 8417 String processName = in.readString(); 8418 Uid.Proc proc = new Proc(mBsi, processName); 8419 proc.readFromParcelLocked(in); 8420 mProcessStats.put(processName, proc); 8421 } 8422 8423 int numPkgs = in.readInt(); 8424 mPackageStats.clear(); 8425 for (int l = 0; l < numPkgs; l++) { 8426 String packageName = in.readString(); 8427 Uid.Pkg pkg = new Pkg(mBsi); 8428 pkg.readFromParcelLocked(in); 8429 mPackageStats.put(packageName, pkg); 8430 } 8431 8432 mWifiRunning = false; 8433 if (in.readInt() != 0) { 8434 mWifiRunningTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, WIFI_RUNNING, 8435 mBsi.mWifiRunningTimers, mBsi.mOnBatteryTimeBase, in); 8436 } else { 8437 mWifiRunningTimer = null; 8438 } 8439 mFullWifiLockOut = false; 8440 if (in.readInt() != 0) { 8441 mFullWifiLockTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, FULL_WIFI_LOCK, 8442 mBsi.mFullWifiLockTimers, mBsi.mOnBatteryTimeBase, in); 8443 } else { 8444 mFullWifiLockTimer = null; 8445 } 8446 mWifiScanStarted = false; 8447 if (in.readInt() != 0) { 8448 mWifiScanTimer = new DualTimer(mBsi.mClocks, Uid.this, WIFI_SCAN, 8449 mBsi.mWifiScanTimers, mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase, 8450 in); 8451 } else { 8452 mWifiScanTimer = null; 8453 } 8454 mWifiBatchedScanBinStarted = NO_BATCHED_SCAN_STARTED; 8455 for (int i = 0; i < NUM_WIFI_BATCHED_SCAN_BINS; i++) { 8456 if (in.readInt() != 0) { 8457 makeWifiBatchedScanBin(i, in); 8458 } else { 8459 mWifiBatchedScanTimer[i] = null; 8460 } 8461 } 8462 mWifiMulticastWakelockCount = 0; 8463 if (in.readInt() != 0) { 8464 mWifiMulticastTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, WIFI_MULTICAST_ENABLED, 8465 mBsi.mWifiMulticastTimers, mBsi.mOnBatteryTimeBase, in); 8466 } else { 8467 mWifiMulticastTimer = null; 8468 } 8469 if (in.readInt() != 0) { 8470 mAudioTurnedOnTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, AUDIO_TURNED_ON, 8471 mBsi.mAudioTurnedOnTimers, mBsi.mOnBatteryTimeBase, in); 8472 } else { 8473 mAudioTurnedOnTimer = null; 8474 } 8475 if (in.readInt() != 0) { 8476 mVideoTurnedOnTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, VIDEO_TURNED_ON, 8477 mBsi.mVideoTurnedOnTimers, mBsi.mOnBatteryTimeBase, in); 8478 } else { 8479 mVideoTurnedOnTimer = null; 8480 } 8481 if (in.readInt() != 0) { 8482 mFlashlightTurnedOnTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, 8483 FLASHLIGHT_TURNED_ON, mBsi.mFlashlightTurnedOnTimers, mBsi.mOnBatteryTimeBase, in); 8484 } else { 8485 mFlashlightTurnedOnTimer = null; 8486 } 8487 if (in.readInt() != 0) { 8488 mCameraTurnedOnTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, CAMERA_TURNED_ON, 8489 mBsi.mCameraTurnedOnTimers, mBsi.mOnBatteryTimeBase, in); 8490 } else { 8491 mCameraTurnedOnTimer = null; 8492 } 8493 if (in.readInt() != 0) { 8494 mForegroundActivityTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, 8495 FOREGROUND_ACTIVITY, null, mBsi.mOnBatteryTimeBase, in); 8496 } else { 8497 mForegroundActivityTimer = null; 8498 } 8499 if (in.readInt() != 0) { 8500 mForegroundServiceTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, 8501 FOREGROUND_SERVICE, null, mBsi.mOnBatteryTimeBase, in); 8502 } else { 8503 mForegroundServiceTimer = null; 8504 } 8505 if (in.readInt() != 0) { 8506 mAggregatedPartialWakelockTimer = new DualTimer(mBsi.mClocks, this, 8507 AGGREGATED_WAKE_TYPE_PARTIAL, null, 8508 mBsi.mOnBatteryScreenOffTimeBase, mOnBatteryScreenOffBackgroundTimeBase, 8509 in); 8510 } else { 8511 mAggregatedPartialWakelockTimer = null; 8512 } 8513 if (in.readInt() != 0) { 8514 mBluetoothScanTimer = new DualTimer(mBsi.mClocks, Uid.this, BLUETOOTH_SCAN_ON, 8515 mBsi.mBluetoothScanOnTimers, mBsi.mOnBatteryTimeBase, 8516 mOnBatteryBackgroundTimeBase, in); 8517 } else { 8518 mBluetoothScanTimer = null; 8519 } 8520 if (in.readInt() != 0) { 8521 mBluetoothUnoptimizedScanTimer = new DualTimer(mBsi.mClocks, Uid.this, 8522 BLUETOOTH_UNOPTIMIZED_SCAN_ON, null, 8523 mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase, in); 8524 } else { 8525 mBluetoothUnoptimizedScanTimer = null; 8526 } 8527 if (in.readInt() != 0) { 8528 mBluetoothScanResultCounter = new Counter(mBsi.mOnBatteryTimeBase, in); 8529 } else { 8530 mBluetoothScanResultCounter = null; 8531 } 8532 if (in.readInt() != 0) { 8533 mBluetoothScanResultBgCounter = new Counter(mOnBatteryBackgroundTimeBase, in); 8534 } else { 8535 mBluetoothScanResultBgCounter = null; 8536 } 8537 mProcessState = ActivityManager.PROCESS_STATE_NONEXISTENT; 8538 for (int i = 0; i < NUM_PROCESS_STATE; i++) { 8539 if (in.readInt() != 0) { 8540 makeProcessState(i, in); 8541 } else { 8542 mProcessStateTimer[i] = null; 8543 } 8544 } 8545 if (in.readInt() != 0) { 8546 mVibratorOnTimer = new BatchTimer(mBsi.mClocks, Uid.this, VIBRATOR_ON, 8547 mBsi.mOnBatteryTimeBase, in); 8548 } else { 8549 mVibratorOnTimer = null; 8550 } 8551 if (in.readInt() != 0) { 8552 mUserActivityCounters = new Counter[NUM_USER_ACTIVITY_TYPES]; 8553 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) { 8554 mUserActivityCounters[i] = new Counter(mBsi.mOnBatteryTimeBase, in); 8555 } 8556 } else { 8557 mUserActivityCounters = null; 8558 } 8559 if (in.readInt() != 0) { 8560 mNetworkByteActivityCounters = new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES]; 8561 mNetworkPacketActivityCounters 8562 = new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES]; 8563 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 8564 mNetworkByteActivityCounters[i] 8565 = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in); 8566 mNetworkPacketActivityCounters[i] 8567 = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in); 8568 } 8569 mMobileRadioActiveTime = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in); 8570 mMobileRadioActiveCount = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in); 8571 } else { 8572 mNetworkByteActivityCounters = null; 8573 mNetworkPacketActivityCounters = null; 8574 } 8575 8576 if (in.readInt() != 0) { 8577 mWifiControllerActivity = new ControllerActivityCounterImpl(mBsi.mOnBatteryTimeBase, 8578 NUM_WIFI_TX_LEVELS, in); 8579 } else { 8580 mWifiControllerActivity = null; 8581 } 8582 8583 if (in.readInt() != 0) { 8584 mBluetoothControllerActivity = new ControllerActivityCounterImpl(mBsi.mOnBatteryTimeBase, 8585 NUM_BT_TX_LEVELS, in); 8586 } else { 8587 mBluetoothControllerActivity = null; 8588 } 8589 8590 if (in.readInt() != 0) { 8591 mModemControllerActivity = new ControllerActivityCounterImpl(mBsi.mOnBatteryTimeBase, 8592 ModemActivityInfo.TX_POWER_LEVELS, in); 8593 } else { 8594 mModemControllerActivity = null; 8595 } 8596 8597 mUserCpuTime = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in); 8598 mSystemCpuTime = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in); 8599 8600 if (in.readInt() != 0) { 8601 int numCpuClusters = in.readInt(); 8602 if (mBsi.mPowerProfile != null && mBsi.mPowerProfile.getNumCpuClusters() != numCpuClusters) { 8603 throw new ParcelFormatException("Incompatible number of cpu clusters"); 8604 } 8605 8606 mCpuClusterSpeedTimesUs = new LongSamplingCounter[numCpuClusters][]; 8607 for (int cluster = 0; cluster < numCpuClusters; cluster++) { 8608 if (in.readInt() != 0) { 8609 int numSpeeds = in.readInt(); 8610 if (mBsi.mPowerProfile != null && 8611 mBsi.mPowerProfile.getNumSpeedStepsInCpuCluster(cluster) != numSpeeds) { 8612 throw new ParcelFormatException("Incompatible number of cpu speeds"); 8613 } 8614 8615 final LongSamplingCounter[] cpuSpeeds = new LongSamplingCounter[numSpeeds]; 8616 mCpuClusterSpeedTimesUs[cluster] = cpuSpeeds; 8617 for (int speed = 0; speed < numSpeeds; speed++) { 8618 if (in.readInt() != 0) { 8619 cpuSpeeds[speed] = new LongSamplingCounter( 8620 mBsi.mOnBatteryTimeBase, in); 8621 } 8622 } 8623 } else { 8624 mCpuClusterSpeedTimesUs[cluster] = null; 8625 } 8626 } 8627 } else { 8628 mCpuClusterSpeedTimesUs = null; 8629 } 8630 8631 mCpuFreqTimeMs = LongSamplingCounterArray.readFromParcel(in, mBsi.mOnBatteryTimeBase); 8632 mScreenOffCpuFreqTimeMs = LongSamplingCounterArray.readFromParcel( 8633 in, mBsi.mOnBatteryScreenOffTimeBase); 8634 8635 mCpuActiveTimeMs = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in); 8636 mCpuClusterTimesMs = new LongSamplingCounterArray(mBsi.mOnBatteryTimeBase, in); 8637 8638 int length = in.readInt(); 8639 if (length == NUM_PROCESS_STATE) { 8640 mProcStateTimeMs = new LongSamplingCounterArray[length]; 8641 for (int procState = 0; procState < length; ++procState) { 8642 mProcStateTimeMs[procState] = LongSamplingCounterArray.readFromParcel( 8643 in, mBsi.mOnBatteryTimeBase); 8644 } 8645 } else { 8646 mProcStateTimeMs = null; 8647 } 8648 length = in.readInt(); 8649 if (length == NUM_PROCESS_STATE) { 8650 mProcStateScreenOffTimeMs = new LongSamplingCounterArray[length]; 8651 for (int procState = 0; procState < length; ++procState) { 8652 mProcStateScreenOffTimeMs[procState] = LongSamplingCounterArray.readFromParcel( 8653 in, mBsi.mOnBatteryScreenOffTimeBase); 8654 } 8655 } else { 8656 mProcStateScreenOffTimeMs = null; 8657 } 8658 8659 if (in.readInt() != 0) { 8660 mMobileRadioApWakeupCount = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in); 8661 } else { 8662 mMobileRadioApWakeupCount = null; 8663 } 8664 8665 if (in.readInt() != 0) { 8666 mWifiRadioApWakeupCount = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in); 8667 } else { 8668 mWifiRadioApWakeupCount = null; 8669 } 8670 } 8671 noteJobsDeferredLocked(int numDeferred, long sinceLast)8672 public void noteJobsDeferredLocked(int numDeferred, long sinceLast) { 8673 mJobsDeferredEventCount.addAtomic(1); 8674 mJobsDeferredCount.addAtomic(numDeferred); 8675 if (sinceLast != 0) { 8676 // Add the total time, which can be divided by the event count to get an average 8677 mJobsFreshnessTimeMs.addCountLocked(sinceLast); 8678 // Also keep track of how many times there were in these different buckets. 8679 for (int i = 0; i < JOB_FRESHNESS_BUCKETS.length; i++) { 8680 if (sinceLast < JOB_FRESHNESS_BUCKETS[i]) { 8681 if (mJobsFreshnessBuckets[i] == null) { 8682 mJobsFreshnessBuckets[i] = new Counter( 8683 mBsi.mOnBatteryTimeBase); 8684 } 8685 mJobsFreshnessBuckets[i].addAtomic(1); 8686 break; 8687 } 8688 } 8689 } 8690 } 8691 8692 /** 8693 * The statistics associated with a particular wake lock. 8694 */ 8695 public static class Wakelock extends BatteryStats.Uid.Wakelock { 8696 /** 8697 * BatteryStatsImpl that we are associated with. 8698 */ 8699 protected BatteryStatsImpl mBsi; 8700 8701 /** 8702 * BatteryStatsImpl that we are associated with. 8703 */ 8704 protected Uid mUid; 8705 8706 /** 8707 * How long (in ms) this uid has been keeping the device partially awake. 8708 * Tracks both the total time and the time while the app was in the background. 8709 */ 8710 DualTimer mTimerPartial; 8711 8712 /** 8713 * How long (in ms) this uid has been keeping the device fully awake. 8714 */ 8715 StopwatchTimer mTimerFull; 8716 8717 /** 8718 * How long (in ms) this uid has had a window keeping the device awake. 8719 */ 8720 StopwatchTimer mTimerWindow; 8721 8722 /** 8723 * How long (in ms) this uid has had a draw wake lock. 8724 */ 8725 StopwatchTimer mTimerDraw; 8726 Wakelock(BatteryStatsImpl bsi, Uid uid)8727 public Wakelock(BatteryStatsImpl bsi, Uid uid) { 8728 mBsi = bsi; 8729 mUid = uid; 8730 } 8731 8732 /** 8733 * Reads a possibly null Timer from a Parcel. The timer is associated with the 8734 * proper timer pool from the given BatteryStatsImpl object. 8735 * 8736 * @param in the Parcel to be read from. 8737 * return a new Timer, or null. 8738 */ readStopwatchTimerFromParcel(int type, ArrayList<StopwatchTimer> pool, TimeBase timeBase, Parcel in)8739 private StopwatchTimer readStopwatchTimerFromParcel(int type, 8740 ArrayList<StopwatchTimer> pool, TimeBase timeBase, Parcel in) { 8741 if (in.readInt() == 0) { 8742 return null; 8743 } 8744 8745 return new StopwatchTimer(mBsi.mClocks, mUid, type, pool, timeBase, in); 8746 } 8747 8748 /** 8749 * Reads a possibly null Timer from a Parcel. The timer is associated with the 8750 * proper timer pool from the given BatteryStatsImpl object. 8751 * 8752 * @param in the Parcel to be read from. 8753 * return a new Timer, or null. 8754 */ readDualTimerFromParcel(int type, ArrayList<StopwatchTimer> pool, TimeBase timeBase, TimeBase bgTimeBase, Parcel in)8755 private DualTimer readDualTimerFromParcel(int type, ArrayList<StopwatchTimer> pool, 8756 TimeBase timeBase, TimeBase bgTimeBase, Parcel in) { 8757 if (in.readInt() == 0) { 8758 return null; 8759 } 8760 8761 return new DualTimer(mBsi.mClocks, mUid, type, pool, timeBase, bgTimeBase, in); 8762 } 8763 reset()8764 boolean reset() { 8765 boolean wlactive = false; 8766 8767 wlactive |= !resetIfNotNull(mTimerFull,false); 8768 wlactive |= !resetIfNotNull(mTimerPartial,false); 8769 wlactive |= !resetIfNotNull(mTimerWindow,false); 8770 wlactive |= !resetIfNotNull(mTimerDraw,false); 8771 8772 if (!wlactive) { 8773 detachIfNotNull(mTimerFull); 8774 mTimerFull = null; 8775 8776 detachIfNotNull(mTimerPartial); 8777 mTimerPartial = null; 8778 8779 detachIfNotNull(mTimerWindow); 8780 mTimerWindow = null; 8781 8782 detachIfNotNull(mTimerDraw); 8783 mTimerDraw = null; 8784 } 8785 return !wlactive; 8786 } 8787 readFromParcelLocked(TimeBase timeBase, TimeBase screenOffTimeBase, TimeBase screenOffBgTimeBase, Parcel in)8788 void readFromParcelLocked(TimeBase timeBase, TimeBase screenOffTimeBase, 8789 TimeBase screenOffBgTimeBase, Parcel in) { 8790 mTimerPartial = readDualTimerFromParcel(WAKE_TYPE_PARTIAL, 8791 mBsi.mPartialTimers, screenOffTimeBase, screenOffBgTimeBase, in); 8792 mTimerFull = readStopwatchTimerFromParcel(WAKE_TYPE_FULL, 8793 mBsi.mFullTimers, timeBase, in); 8794 mTimerWindow = readStopwatchTimerFromParcel(WAKE_TYPE_WINDOW, 8795 mBsi.mWindowTimers, timeBase, in); 8796 mTimerDraw = readStopwatchTimerFromParcel(WAKE_TYPE_DRAW, 8797 mBsi.mDrawTimers, timeBase, in); 8798 } 8799 writeToParcelLocked(Parcel out, long elapsedRealtimeUs)8800 void writeToParcelLocked(Parcel out, long elapsedRealtimeUs) { 8801 Timer.writeTimerToParcel(out, mTimerPartial, elapsedRealtimeUs); 8802 Timer.writeTimerToParcel(out, mTimerFull, elapsedRealtimeUs); 8803 Timer.writeTimerToParcel(out, mTimerWindow, elapsedRealtimeUs); 8804 Timer.writeTimerToParcel(out, mTimerDraw, elapsedRealtimeUs); 8805 } 8806 8807 @Override 8808 @UnsupportedAppUsage getWakeTime(int type)8809 public Timer getWakeTime(int type) { 8810 switch (type) { 8811 case WAKE_TYPE_FULL: return mTimerFull; 8812 case WAKE_TYPE_PARTIAL: return mTimerPartial; 8813 case WAKE_TYPE_WINDOW: return mTimerWindow; 8814 case WAKE_TYPE_DRAW: return mTimerDraw; 8815 default: throw new IllegalArgumentException("type = " + type); 8816 } 8817 } 8818 detachFromTimeBase()8819 public void detachFromTimeBase() { 8820 detachIfNotNull(mTimerPartial); 8821 detachIfNotNull(mTimerFull); 8822 detachIfNotNull(mTimerWindow); 8823 detachIfNotNull(mTimerDraw); 8824 } 8825 } 8826 8827 public static class Sensor extends BatteryStats.Uid.Sensor { 8828 /** 8829 * BatteryStatsImpl that we are associated with. 8830 */ 8831 protected BatteryStatsImpl mBsi; 8832 8833 /** 8834 * Uid that we are associated with. 8835 */ 8836 protected Uid mUid; 8837 8838 final int mHandle; 8839 DualTimer mTimer; 8840 Sensor(BatteryStatsImpl bsi, Uid uid, int handle)8841 public Sensor(BatteryStatsImpl bsi, Uid uid, int handle) { 8842 mBsi = bsi; 8843 mUid = uid; 8844 mHandle = handle; 8845 } 8846 readTimersFromParcel( TimeBase timeBase, TimeBase bgTimeBase, Parcel in)8847 private DualTimer readTimersFromParcel( 8848 TimeBase timeBase, TimeBase bgTimeBase, Parcel in) { 8849 if (in.readInt() == 0) { 8850 return null; 8851 } 8852 8853 ArrayList<StopwatchTimer> pool = mBsi.mSensorTimers.get(mHandle); 8854 if (pool == null) { 8855 pool = new ArrayList<StopwatchTimer>(); 8856 mBsi.mSensorTimers.put(mHandle, pool); 8857 } 8858 return new DualTimer(mBsi.mClocks, mUid, 0, pool, timeBase, bgTimeBase, in); 8859 } 8860 reset()8861 boolean reset() { 8862 if (mTimer.reset(true)) { 8863 mTimer = null; 8864 return true; 8865 } 8866 return false; 8867 } 8868 readFromParcelLocked(TimeBase timeBase, TimeBase bgTimeBase, Parcel in)8869 void readFromParcelLocked(TimeBase timeBase, TimeBase bgTimeBase, Parcel in) { 8870 mTimer = readTimersFromParcel(timeBase, bgTimeBase, in); 8871 } 8872 writeToParcelLocked(Parcel out, long elapsedRealtimeUs)8873 void writeToParcelLocked(Parcel out, long elapsedRealtimeUs) { 8874 Timer.writeTimerToParcel(out, mTimer, elapsedRealtimeUs); 8875 } 8876 8877 @Override 8878 @UnsupportedAppUsage getSensorTime()8879 public Timer getSensorTime() { 8880 return mTimer; 8881 } 8882 8883 @Override getSensorBackgroundTime()8884 public Timer getSensorBackgroundTime() { 8885 if (mTimer == null) { 8886 return null; 8887 } 8888 return mTimer.getSubTimer(); 8889 } 8890 8891 @Override 8892 @UnsupportedAppUsage getHandle()8893 public int getHandle() { 8894 return mHandle; 8895 } 8896 detachFromTimeBase()8897 public void detachFromTimeBase() { 8898 detachIfNotNull(mTimer); 8899 } 8900 } 8901 8902 /** 8903 * The statistics associated with a particular process. 8904 */ 8905 public static class Proc extends BatteryStats.Uid.Proc implements TimeBaseObs { 8906 /** 8907 * BatteryStatsImpl that we are associated with. 8908 */ 8909 protected BatteryStatsImpl mBsi; 8910 8911 /** 8912 * The name of this process. 8913 */ 8914 final String mName; 8915 8916 /** 8917 * Remains true until removed from the stats. 8918 */ 8919 boolean mActive = true; 8920 8921 /** 8922 * Total time (in ms) spent executing in user code. 8923 */ 8924 long mUserTime; 8925 8926 /** 8927 * Total time (in ms) spent executing in kernel code. 8928 */ 8929 long mSystemTime; 8930 8931 /** 8932 * Amount of time (in ms) the process was running in the foreground. 8933 */ 8934 long mForegroundTime; 8935 8936 /** 8937 * Number of times the process has been started. 8938 */ 8939 int mStarts; 8940 8941 /** 8942 * Number of times the process has crashed. 8943 */ 8944 int mNumCrashes; 8945 8946 /** 8947 * Number of times the process has had an ANR. 8948 */ 8949 int mNumAnrs; 8950 8951 ArrayList<ExcessivePower> mExcessivePower; 8952 Proc(BatteryStatsImpl bsi, String name)8953 public Proc(BatteryStatsImpl bsi, String name) { 8954 mBsi = bsi; 8955 mName = name; 8956 mBsi.mOnBatteryTimeBase.add(this); 8957 } 8958 onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime)8959 public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) { 8960 } 8961 onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime)8962 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) { 8963 } 8964 8965 @Override reset(boolean detachIfReset)8966 public boolean reset(boolean detachIfReset) { 8967 if (detachIfReset) { 8968 this.detach(); 8969 } 8970 return true; 8971 } 8972 8973 @Override detach()8974 public void detach() { 8975 mActive = false; 8976 mBsi.mOnBatteryTimeBase.remove(this); 8977 } 8978 countExcessivePowers()8979 public int countExcessivePowers() { 8980 return mExcessivePower != null ? mExcessivePower.size() : 0; 8981 } 8982 getExcessivePower(int i)8983 public ExcessivePower getExcessivePower(int i) { 8984 if (mExcessivePower != null) { 8985 return mExcessivePower.get(i); 8986 } 8987 return null; 8988 } 8989 addExcessiveCpu(long overTime, long usedTime)8990 public void addExcessiveCpu(long overTime, long usedTime) { 8991 if (mExcessivePower == null) { 8992 mExcessivePower = new ArrayList<ExcessivePower>(); 8993 } 8994 ExcessivePower ew = new ExcessivePower(); 8995 ew.type = ExcessivePower.TYPE_CPU; 8996 ew.overTime = overTime; 8997 ew.usedTime = usedTime; 8998 mExcessivePower.add(ew); 8999 } 9000 writeExcessivePowerToParcelLocked(Parcel out)9001 void writeExcessivePowerToParcelLocked(Parcel out) { 9002 if (mExcessivePower == null) { 9003 out.writeInt(0); 9004 return; 9005 } 9006 9007 final int N = mExcessivePower.size(); 9008 out.writeInt(N); 9009 for (int i=0; i<N; i++) { 9010 ExcessivePower ew = mExcessivePower.get(i); 9011 out.writeInt(ew.type); 9012 out.writeLong(ew.overTime); 9013 out.writeLong(ew.usedTime); 9014 } 9015 } 9016 readExcessivePowerFromParcelLocked(Parcel in)9017 void readExcessivePowerFromParcelLocked(Parcel in) { 9018 final int N = in.readInt(); 9019 if (N == 0) { 9020 mExcessivePower = null; 9021 return; 9022 } 9023 9024 if (N > 10000) { 9025 throw new ParcelFormatException( 9026 "File corrupt: too many excessive power entries " + N); 9027 } 9028 9029 mExcessivePower = new ArrayList<>(); 9030 for (int i=0; i<N; i++) { 9031 ExcessivePower ew = new ExcessivePower(); 9032 ew.type = in.readInt(); 9033 ew.overTime = in.readLong(); 9034 ew.usedTime = in.readLong(); 9035 mExcessivePower.add(ew); 9036 } 9037 } 9038 writeToParcelLocked(Parcel out)9039 void writeToParcelLocked(Parcel out) { 9040 out.writeLong(mUserTime); 9041 out.writeLong(mSystemTime); 9042 out.writeLong(mForegroundTime); 9043 out.writeInt(mStarts); 9044 out.writeInt(mNumCrashes); 9045 out.writeInt(mNumAnrs); 9046 writeExcessivePowerToParcelLocked(out); 9047 } 9048 readFromParcelLocked(Parcel in)9049 void readFromParcelLocked(Parcel in) { 9050 mUserTime = in.readLong(); 9051 mSystemTime = in.readLong(); 9052 mForegroundTime = in.readLong(); 9053 mStarts = in.readInt(); 9054 mNumCrashes = in.readInt(); 9055 mNumAnrs = in.readInt(); 9056 readExcessivePowerFromParcelLocked(in); 9057 } 9058 9059 @UnsupportedAppUsage addCpuTimeLocked(int utime, int stime)9060 public void addCpuTimeLocked(int utime, int stime) { 9061 addCpuTimeLocked(utime, stime, mBsi.mOnBatteryTimeBase.isRunning()); 9062 } 9063 addCpuTimeLocked(int utime, int stime, boolean isRunning)9064 public void addCpuTimeLocked(int utime, int stime, boolean isRunning) { 9065 if (isRunning) { 9066 mUserTime += utime; 9067 mSystemTime += stime; 9068 } 9069 } 9070 9071 @UnsupportedAppUsage addForegroundTimeLocked(long ttime)9072 public void addForegroundTimeLocked(long ttime) { 9073 mForegroundTime += ttime; 9074 } 9075 9076 @UnsupportedAppUsage incStartsLocked()9077 public void incStartsLocked() { 9078 mStarts++; 9079 } 9080 incNumCrashesLocked()9081 public void incNumCrashesLocked() { 9082 mNumCrashes++; 9083 } 9084 incNumAnrsLocked()9085 public void incNumAnrsLocked() { 9086 mNumAnrs++; 9087 } 9088 9089 @Override isActive()9090 public boolean isActive() { 9091 return mActive; 9092 } 9093 9094 @Override 9095 @UnsupportedAppUsage getUserTime(int which)9096 public long getUserTime(int which) { 9097 return mUserTime; 9098 } 9099 9100 @Override 9101 @UnsupportedAppUsage getSystemTime(int which)9102 public long getSystemTime(int which) { 9103 return mSystemTime; 9104 } 9105 9106 @Override 9107 @UnsupportedAppUsage getForegroundTime(int which)9108 public long getForegroundTime(int which) { 9109 return mForegroundTime; 9110 } 9111 9112 @Override 9113 @UnsupportedAppUsage getStarts(int which)9114 public int getStarts(int which) { 9115 return mStarts; 9116 } 9117 9118 @Override getNumCrashes(int which)9119 public int getNumCrashes(int which) { 9120 return mNumCrashes; 9121 } 9122 9123 @Override getNumAnrs(int which)9124 public int getNumAnrs(int which) { 9125 return mNumAnrs; 9126 } 9127 } 9128 9129 /** 9130 * The statistics associated with a particular package. 9131 */ 9132 public static class Pkg extends BatteryStats.Uid.Pkg implements TimeBaseObs { 9133 /** 9134 * BatteryStatsImpl that we are associated with. 9135 */ 9136 protected BatteryStatsImpl mBsi; 9137 9138 /** 9139 * Number of times wakeup alarms have occurred for this app. 9140 * On screen-off timebase starting in report v25. 9141 */ 9142 ArrayMap<String, Counter> mWakeupAlarms = new ArrayMap<>(); 9143 9144 /** 9145 * The statics we have collected for this package's services. 9146 */ 9147 final ArrayMap<String, Serv> mServiceStats = new ArrayMap<>(); 9148 Pkg(BatteryStatsImpl bsi)9149 public Pkg(BatteryStatsImpl bsi) { 9150 mBsi = bsi; 9151 mBsi.mOnBatteryScreenOffTimeBase.add(this); 9152 } 9153 onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime)9154 public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) { 9155 } 9156 onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime)9157 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) { 9158 } 9159 9160 @Override reset(boolean detachIfReset)9161 public boolean reset(boolean detachIfReset) { 9162 if (detachIfReset) { 9163 this.detach(); 9164 } 9165 return true; 9166 } 9167 9168 @Override detach()9169 public void detach() { 9170 mBsi.mOnBatteryScreenOffTimeBase.remove(this); 9171 for (int j = mWakeupAlarms.size() - 1; j >= 0; j--) { 9172 detachIfNotNull(mWakeupAlarms.valueAt(j)); 9173 } 9174 for (int j = mServiceStats.size() - 1; j >= 0; j--) { 9175 detachIfNotNull(mServiceStats.valueAt(j)); 9176 } 9177 } 9178 readFromParcelLocked(Parcel in)9179 void readFromParcelLocked(Parcel in) { 9180 int numWA = in.readInt(); 9181 mWakeupAlarms.clear(); 9182 for (int i=0; i<numWA; i++) { 9183 String tag = in.readString(); 9184 mWakeupAlarms.put(tag, new Counter(mBsi.mOnBatteryScreenOffTimeBase, in)); 9185 } 9186 9187 int numServs = in.readInt(); 9188 mServiceStats.clear(); 9189 for (int m = 0; m < numServs; m++) { 9190 String serviceName = in.readString(); 9191 Uid.Pkg.Serv serv = new Serv(mBsi); 9192 mServiceStats.put(serviceName, serv); 9193 9194 serv.readFromParcelLocked(in); 9195 } 9196 } 9197 writeToParcelLocked(Parcel out)9198 void writeToParcelLocked(Parcel out) { 9199 int numWA = mWakeupAlarms.size(); 9200 out.writeInt(numWA); 9201 for (int i=0; i<numWA; i++) { 9202 out.writeString(mWakeupAlarms.keyAt(i)); 9203 mWakeupAlarms.valueAt(i).writeToParcel(out); 9204 } 9205 9206 final int NS = mServiceStats.size(); 9207 out.writeInt(NS); 9208 for (int i=0; i<NS; i++) { 9209 out.writeString(mServiceStats.keyAt(i)); 9210 Uid.Pkg.Serv serv = mServiceStats.valueAt(i); 9211 serv.writeToParcelLocked(out); 9212 } 9213 } 9214 9215 @Override getWakeupAlarmStats()9216 public ArrayMap<String, ? extends BatteryStats.Counter> getWakeupAlarmStats() { 9217 return mWakeupAlarms; 9218 } 9219 noteWakeupAlarmLocked(String tag)9220 public void noteWakeupAlarmLocked(String tag) { 9221 Counter c = mWakeupAlarms.get(tag); 9222 if (c == null) { 9223 c = new Counter(mBsi.mOnBatteryScreenOffTimeBase); 9224 mWakeupAlarms.put(tag, c); 9225 } 9226 c.stepAtomic(); 9227 } 9228 9229 @Override getServiceStats()9230 public ArrayMap<String, ? extends BatteryStats.Uid.Pkg.Serv> getServiceStats() { 9231 return mServiceStats; 9232 } 9233 9234 /** 9235 * The statistics associated with a particular service. 9236 */ 9237 public static class Serv extends BatteryStats.Uid.Pkg.Serv implements TimeBaseObs { 9238 /** 9239 * BatteryStatsImpl that we are associated with. 9240 */ 9241 protected BatteryStatsImpl mBsi; 9242 9243 /** 9244 * The android package in which this service resides. 9245 */ 9246 protected Pkg mPkg; 9247 9248 /** 9249 * Total time (ms in battery uptime) the service has been left started. 9250 */ 9251 protected long mStartTime; 9252 9253 /** 9254 * If service has been started and not yet stopped, this is 9255 * when it was started. 9256 */ 9257 protected long mRunningSince; 9258 9259 /** 9260 * True if we are currently running. 9261 */ 9262 protected boolean mRunning; 9263 9264 /** 9265 * Total number of times startService() has been called. 9266 */ 9267 protected int mStarts; 9268 9269 /** 9270 * Total time (ms in battery uptime) the service has been left launched. 9271 */ 9272 protected long mLaunchedTime; 9273 9274 /** 9275 * If service has been launched and not yet exited, this is 9276 * when it was launched (ms in battery uptime). 9277 */ 9278 protected long mLaunchedSince; 9279 9280 /** 9281 * True if we are currently launched. 9282 */ 9283 protected boolean mLaunched; 9284 9285 /** 9286 * Total number times the service has been launched. 9287 */ 9288 protected int mLaunches; 9289 9290 /** 9291 * Construct a Serv. Also adds it to the on-battery time base as a listener. 9292 */ Serv(BatteryStatsImpl bsi)9293 public Serv(BatteryStatsImpl bsi) { 9294 mBsi = bsi; 9295 mBsi.mOnBatteryTimeBase.add(this); 9296 } 9297 onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime)9298 public void onTimeStarted(long elapsedRealtime, long baseUptime, 9299 long baseRealtime) { 9300 } 9301 onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime)9302 public void onTimeStopped(long elapsedRealtime, long baseUptime, 9303 long baseRealtime) { 9304 } 9305 9306 @Override reset(boolean detachIfReset)9307 public boolean reset(boolean detachIfReset) { 9308 if (detachIfReset) { 9309 this.detach(); 9310 } 9311 return true; 9312 } 9313 9314 /** 9315 * Remove this Serv as a listener from the time base. 9316 */ 9317 @Override detach()9318 public void detach() { 9319 mBsi.mOnBatteryTimeBase.remove(this); 9320 } 9321 readFromParcelLocked(Parcel in)9322 public void readFromParcelLocked(Parcel in) { 9323 mStartTime = in.readLong(); 9324 mRunningSince = in.readLong(); 9325 mRunning = in.readInt() != 0; 9326 mStarts = in.readInt(); 9327 mLaunchedTime = in.readLong(); 9328 mLaunchedSince = in.readLong(); 9329 mLaunched = in.readInt() != 0; 9330 mLaunches = in.readInt(); 9331 } 9332 writeToParcelLocked(Parcel out)9333 public void writeToParcelLocked(Parcel out) { 9334 out.writeLong(mStartTime); 9335 out.writeLong(mRunningSince); 9336 out.writeInt(mRunning ? 1 : 0); 9337 out.writeInt(mStarts); 9338 out.writeLong(mLaunchedTime); 9339 out.writeLong(mLaunchedSince); 9340 out.writeInt(mLaunched ? 1 : 0); 9341 out.writeInt(mLaunches); 9342 } 9343 getLaunchTimeToNowLocked(long batteryUptime)9344 public long getLaunchTimeToNowLocked(long batteryUptime) { 9345 if (!mLaunched) return mLaunchedTime; 9346 return mLaunchedTime + batteryUptime - mLaunchedSince; 9347 } 9348 getStartTimeToNowLocked(long batteryUptime)9349 public long getStartTimeToNowLocked(long batteryUptime) { 9350 if (!mRunning) return mStartTime; 9351 return mStartTime + batteryUptime - mRunningSince; 9352 } 9353 9354 @UnsupportedAppUsage startLaunchedLocked()9355 public void startLaunchedLocked() { 9356 if (!mLaunched) { 9357 mLaunches++; 9358 mLaunchedSince = mBsi.getBatteryUptimeLocked(); 9359 mLaunched = true; 9360 } 9361 } 9362 9363 @UnsupportedAppUsage stopLaunchedLocked()9364 public void stopLaunchedLocked() { 9365 if (mLaunched) { 9366 long time = mBsi.getBatteryUptimeLocked() - mLaunchedSince; 9367 if (time > 0) { 9368 mLaunchedTime += time; 9369 } else { 9370 mLaunches--; 9371 } 9372 mLaunched = false; 9373 } 9374 } 9375 9376 @UnsupportedAppUsage startRunningLocked()9377 public void startRunningLocked() { 9378 if (!mRunning) { 9379 mStarts++; 9380 mRunningSince = mBsi.getBatteryUptimeLocked(); 9381 mRunning = true; 9382 } 9383 } 9384 9385 @UnsupportedAppUsage stopRunningLocked()9386 public void stopRunningLocked() { 9387 if (mRunning) { 9388 long time = mBsi.getBatteryUptimeLocked() - mRunningSince; 9389 if (time > 0) { 9390 mStartTime += time; 9391 } else { 9392 mStarts--; 9393 } 9394 mRunning = false; 9395 } 9396 } 9397 9398 @UnsupportedAppUsage getBatteryStats()9399 public BatteryStatsImpl getBatteryStats() { 9400 return mBsi; 9401 } 9402 9403 @Override getLaunches(int which)9404 public int getLaunches(int which) { 9405 return mLaunches; 9406 } 9407 9408 @Override getStartTime(long now, int which)9409 public long getStartTime(long now, int which) { 9410 return getStartTimeToNowLocked(now); 9411 } 9412 9413 @Override getStarts(int which)9414 public int getStarts(int which) { 9415 return mStarts; 9416 } 9417 } 9418 newServiceStatsLocked()9419 final Serv newServiceStatsLocked() { 9420 return new Serv(mBsi); 9421 } 9422 } 9423 9424 /** 9425 * Retrieve the statistics object for a particular process, creating 9426 * if needed. 9427 */ getProcessStatsLocked(String name)9428 public Proc getProcessStatsLocked(String name) { 9429 Proc ps = mProcessStats.get(name); 9430 if (ps == null) { 9431 ps = new Proc(mBsi, name); 9432 mProcessStats.put(name, ps); 9433 } 9434 9435 return ps; 9436 } 9437 9438 @GuardedBy("mBsi") updateUidProcessStateLocked(int procState)9439 public void updateUidProcessStateLocked(int procState) { 9440 int uidRunningState; 9441 // Make special note of Foreground Services 9442 final boolean userAwareService = 9443 (ActivityManager.isForegroundService(procState)); 9444 uidRunningState = BatteryStats.mapToInternalProcessState(procState); 9445 9446 if (mProcessState == uidRunningState && userAwareService == mInForegroundService) { 9447 return; 9448 } 9449 9450 final long elapsedRealtimeMs = mBsi.mClocks.elapsedRealtime(); 9451 if (mProcessState != uidRunningState) { 9452 final long uptimeMs = mBsi.mClocks.uptimeMillis(); 9453 9454 if (mProcessState != ActivityManager.PROCESS_STATE_NONEXISTENT) { 9455 mProcessStateTimer[mProcessState].stopRunningLocked(elapsedRealtimeMs); 9456 9457 if (mBsi.trackPerProcStateCpuTimes()) { 9458 if (mBsi.mPendingUids.size() == 0) { 9459 mBsi.mExternalSync.scheduleReadProcStateCpuTimes( 9460 mBsi.mOnBatteryTimeBase.isRunning(), 9461 mBsi.mOnBatteryScreenOffTimeBase.isRunning(), 9462 mBsi.mConstants.PROC_STATE_CPU_TIMES_READ_DELAY_MS); 9463 mBsi.mNumSingleUidCpuTimeReads++; 9464 } else { 9465 mBsi.mNumBatchedSingleUidCpuTimeReads++; 9466 } 9467 if (mBsi.mPendingUids.indexOfKey(mUid) < 0 9468 || ArrayUtils.contains(CRITICAL_PROC_STATES, mProcessState)) { 9469 mBsi.mPendingUids.put(mUid, mProcessState); 9470 } 9471 } else { 9472 mBsi.mPendingUids.clear(); 9473 } 9474 } 9475 mProcessState = uidRunningState; 9476 if (uidRunningState != ActivityManager.PROCESS_STATE_NONEXISTENT) { 9477 if (mProcessStateTimer[uidRunningState] == null) { 9478 makeProcessState(uidRunningState, null); 9479 } 9480 mProcessStateTimer[uidRunningState].startRunningLocked(elapsedRealtimeMs); 9481 } 9482 9483 updateOnBatteryBgTimeBase(uptimeMs * 1000, elapsedRealtimeMs * 1000); 9484 updateOnBatteryScreenOffBgTimeBase(uptimeMs * 1000, elapsedRealtimeMs * 1000); 9485 } 9486 9487 if (userAwareService != mInForegroundService) { 9488 if (userAwareService) { 9489 noteForegroundServiceResumedLocked(elapsedRealtimeMs); 9490 } else { 9491 noteForegroundServicePausedLocked(elapsedRealtimeMs); 9492 } 9493 mInForegroundService = userAwareService; 9494 } 9495 } 9496 9497 /** Whether to consider Uid to be in the background for background timebase purposes. */ isInBackground()9498 public boolean isInBackground() { 9499 // Note that PROCESS_STATE_CACHED and ActivityManager.PROCESS_STATE_NONEXISTENT is 9500 // also considered to be 'background' for our purposes, because it's not foreground. 9501 return mProcessState >= PROCESS_STATE_BACKGROUND; 9502 } 9503 updateOnBatteryBgTimeBase(long uptimeUs, long realtimeUs)9504 public boolean updateOnBatteryBgTimeBase(long uptimeUs, long realtimeUs) { 9505 boolean on = mBsi.mOnBatteryTimeBase.isRunning() && isInBackground(); 9506 return mOnBatteryBackgroundTimeBase.setRunning(on, uptimeUs, realtimeUs); 9507 } 9508 updateOnBatteryScreenOffBgTimeBase(long uptimeUs, long realtimeUs)9509 public boolean updateOnBatteryScreenOffBgTimeBase(long uptimeUs, long realtimeUs) { 9510 boolean on = mBsi.mOnBatteryScreenOffTimeBase.isRunning() && isInBackground(); 9511 return mOnBatteryScreenOffBackgroundTimeBase.setRunning(on, uptimeUs, realtimeUs); 9512 } 9513 getPidStats()9514 public SparseArray<? extends Pid> getPidStats() { 9515 return mPids; 9516 } 9517 getPidStatsLocked(int pid)9518 public Pid getPidStatsLocked(int pid) { 9519 Pid p = mPids.get(pid); 9520 if (p == null) { 9521 p = new Pid(); 9522 mPids.put(pid, p); 9523 } 9524 return p; 9525 } 9526 9527 /** 9528 * Retrieve the statistics object for a particular service, creating 9529 * if needed. 9530 */ getPackageStatsLocked(String name)9531 public Pkg getPackageStatsLocked(String name) { 9532 Pkg ps = mPackageStats.get(name); 9533 if (ps == null) { 9534 ps = new Pkg(mBsi); 9535 mPackageStats.put(name, ps); 9536 } 9537 9538 return ps; 9539 } 9540 9541 /** 9542 * Retrieve the statistics object for a particular service, creating 9543 * if needed. 9544 */ getServiceStatsLocked(String pkg, String serv)9545 public Pkg.Serv getServiceStatsLocked(String pkg, String serv) { 9546 Pkg ps = getPackageStatsLocked(pkg); 9547 Pkg.Serv ss = ps.mServiceStats.get(serv); 9548 if (ss == null) { 9549 ss = ps.newServiceStatsLocked(); 9550 ps.mServiceStats.put(serv, ss); 9551 } 9552 9553 return ss; 9554 } 9555 readSyncSummaryFromParcelLocked(String name, Parcel in)9556 public void readSyncSummaryFromParcelLocked(String name, Parcel in) { 9557 DualTimer timer = mSyncStats.instantiateObject(); 9558 timer.readSummaryFromParcelLocked(in); 9559 mSyncStats.add(name, timer); 9560 } 9561 readJobSummaryFromParcelLocked(String name, Parcel in)9562 public void readJobSummaryFromParcelLocked(String name, Parcel in) { 9563 DualTimer timer = mJobStats.instantiateObject(); 9564 timer.readSummaryFromParcelLocked(in); 9565 mJobStats.add(name, timer); 9566 } 9567 readWakeSummaryFromParcelLocked(String wlName, Parcel in)9568 public void readWakeSummaryFromParcelLocked(String wlName, Parcel in) { 9569 Wakelock wl = new Wakelock(mBsi, this); 9570 mWakelockStats.add(wlName, wl); 9571 if (in.readInt() != 0) { 9572 getWakelockTimerLocked(wl, WAKE_TYPE_FULL).readSummaryFromParcelLocked(in); 9573 } 9574 if (in.readInt() != 0) { 9575 getWakelockTimerLocked(wl, WAKE_TYPE_PARTIAL).readSummaryFromParcelLocked(in); 9576 } 9577 if (in.readInt() != 0) { 9578 getWakelockTimerLocked(wl, WAKE_TYPE_WINDOW).readSummaryFromParcelLocked(in); 9579 } 9580 if (in.readInt() != 0) { 9581 getWakelockTimerLocked(wl, WAKE_TYPE_DRAW).readSummaryFromParcelLocked(in); 9582 } 9583 } 9584 getSensorTimerLocked(int sensor, boolean create)9585 public DualTimer getSensorTimerLocked(int sensor, boolean create) { 9586 Sensor se = mSensorStats.get(sensor); 9587 if (se == null) { 9588 if (!create) { 9589 return null; 9590 } 9591 se = new Sensor(mBsi, this, sensor); 9592 mSensorStats.put(sensor, se); 9593 } 9594 DualTimer t = se.mTimer; 9595 if (t != null) { 9596 return t; 9597 } 9598 ArrayList<StopwatchTimer> timers = mBsi.mSensorTimers.get(sensor); 9599 if (timers == null) { 9600 timers = new ArrayList<StopwatchTimer>(); 9601 mBsi.mSensorTimers.put(sensor, timers); 9602 } 9603 t = new DualTimer(mBsi.mClocks, this, BatteryStats.SENSOR, timers, 9604 mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase); 9605 se.mTimer = t; 9606 return t; 9607 } 9608 noteStartSyncLocked(String name, long elapsedRealtimeMs)9609 public void noteStartSyncLocked(String name, long elapsedRealtimeMs) { 9610 DualTimer t = mSyncStats.startObject(name); 9611 if (t != null) { 9612 t.startRunningLocked(elapsedRealtimeMs); 9613 } 9614 } 9615 noteStopSyncLocked(String name, long elapsedRealtimeMs)9616 public void noteStopSyncLocked(String name, long elapsedRealtimeMs) { 9617 DualTimer t = mSyncStats.stopObject(name); 9618 if (t != null) { 9619 t.stopRunningLocked(elapsedRealtimeMs); 9620 } 9621 } 9622 noteStartJobLocked(String name, long elapsedRealtimeMs)9623 public void noteStartJobLocked(String name, long elapsedRealtimeMs) { 9624 DualTimer t = mJobStats.startObject(name); 9625 if (t != null) { 9626 t.startRunningLocked(elapsedRealtimeMs); 9627 } 9628 } 9629 noteStopJobLocked(String name, long elapsedRealtimeMs, int stopReason)9630 public void noteStopJobLocked(String name, long elapsedRealtimeMs, int stopReason) { 9631 DualTimer t = mJobStats.stopObject(name); 9632 if (t != null) { 9633 t.stopRunningLocked(elapsedRealtimeMs); 9634 } 9635 if (mBsi.mOnBatteryTimeBase.isRunning()) { 9636 SparseIntArray types = mJobCompletions.get(name); 9637 if (types == null) { 9638 types = new SparseIntArray(); 9639 mJobCompletions.put(name, types); 9640 } 9641 int last = types.get(stopReason, 0); 9642 types.put(stopReason, last + 1); 9643 } 9644 } 9645 getWakelockTimerLocked(Wakelock wl, int type)9646 public StopwatchTimer getWakelockTimerLocked(Wakelock wl, int type) { 9647 if (wl == null) { 9648 return null; 9649 } 9650 switch (type) { 9651 case WAKE_TYPE_PARTIAL: { 9652 DualTimer t = wl.mTimerPartial; 9653 if (t == null) { 9654 t = new DualTimer(mBsi.mClocks, this, WAKE_TYPE_PARTIAL, 9655 mBsi.mPartialTimers, mBsi.mOnBatteryScreenOffTimeBase, 9656 mOnBatteryScreenOffBackgroundTimeBase); 9657 wl.mTimerPartial = t; 9658 } 9659 return t; 9660 } 9661 case WAKE_TYPE_FULL: { 9662 StopwatchTimer t = wl.mTimerFull; 9663 if (t == null) { 9664 t = new StopwatchTimer(mBsi.mClocks, this, WAKE_TYPE_FULL, 9665 mBsi.mFullTimers, mBsi.mOnBatteryTimeBase); 9666 wl.mTimerFull = t; 9667 } 9668 return t; 9669 } 9670 case WAKE_TYPE_WINDOW: { 9671 StopwatchTimer t = wl.mTimerWindow; 9672 if (t == null) { 9673 t = new StopwatchTimer(mBsi.mClocks, this, WAKE_TYPE_WINDOW, 9674 mBsi.mWindowTimers, mBsi.mOnBatteryTimeBase); 9675 wl.mTimerWindow = t; 9676 } 9677 return t; 9678 } 9679 case WAKE_TYPE_DRAW: { 9680 StopwatchTimer t = wl.mTimerDraw; 9681 if (t == null) { 9682 t = new StopwatchTimer(mBsi.mClocks, this, WAKE_TYPE_DRAW, 9683 mBsi.mDrawTimers, mBsi.mOnBatteryTimeBase); 9684 wl.mTimerDraw = t; 9685 } 9686 return t; 9687 } 9688 default: 9689 throw new IllegalArgumentException("type=" + type); 9690 } 9691 } 9692 noteStartWakeLocked(int pid, String name, int type, long elapsedRealtimeMs)9693 public void noteStartWakeLocked(int pid, String name, int type, long elapsedRealtimeMs) { 9694 Wakelock wl = mWakelockStats.startObject(name); 9695 if (wl != null) { 9696 getWakelockTimerLocked(wl, type).startRunningLocked(elapsedRealtimeMs); 9697 } 9698 if (type == WAKE_TYPE_PARTIAL) { 9699 createAggregatedPartialWakelockTimerLocked().startRunningLocked(elapsedRealtimeMs); 9700 if (pid >= 0) { 9701 Pid p = getPidStatsLocked(pid); 9702 if (p.mWakeNesting++ == 0) { 9703 p.mWakeStartMs = elapsedRealtimeMs; 9704 } 9705 } 9706 } 9707 } 9708 noteStopWakeLocked(int pid, String name, int type, long elapsedRealtimeMs)9709 public void noteStopWakeLocked(int pid, String name, int type, long elapsedRealtimeMs) { 9710 Wakelock wl = mWakelockStats.stopObject(name); 9711 if (wl != null) { 9712 StopwatchTimer wlt = getWakelockTimerLocked(wl, type); 9713 wlt.stopRunningLocked(elapsedRealtimeMs); 9714 } 9715 if (type == WAKE_TYPE_PARTIAL) { 9716 if (mAggregatedPartialWakelockTimer != null) { 9717 mAggregatedPartialWakelockTimer.stopRunningLocked(elapsedRealtimeMs); 9718 } 9719 if (pid >= 0) { 9720 Pid p = mPids.get(pid); 9721 if (p != null && p.mWakeNesting > 0) { 9722 if (p.mWakeNesting-- == 1) { 9723 p.mWakeSumMs += elapsedRealtimeMs - p.mWakeStartMs; 9724 p.mWakeStartMs = 0; 9725 } 9726 } 9727 } 9728 } 9729 } 9730 reportExcessiveCpuLocked(String proc, long overTime, long usedTime)9731 public void reportExcessiveCpuLocked(String proc, long overTime, long usedTime) { 9732 Proc p = getProcessStatsLocked(proc); 9733 if (p != null) { 9734 p.addExcessiveCpu(overTime, usedTime); 9735 } 9736 } 9737 noteStartSensor(int sensor, long elapsedRealtimeMs)9738 public void noteStartSensor(int sensor, long elapsedRealtimeMs) { 9739 DualTimer t = getSensorTimerLocked(sensor, /* create= */ true); 9740 t.startRunningLocked(elapsedRealtimeMs); 9741 } 9742 noteStopSensor(int sensor, long elapsedRealtimeMs)9743 public void noteStopSensor(int sensor, long elapsedRealtimeMs) { 9744 // Don't create a timer if one doesn't already exist 9745 DualTimer t = getSensorTimerLocked(sensor, false); 9746 if (t != null) { 9747 t.stopRunningLocked(elapsedRealtimeMs); 9748 } 9749 } 9750 noteStartGps(long elapsedRealtimeMs)9751 public void noteStartGps(long elapsedRealtimeMs) { 9752 noteStartSensor(Sensor.GPS, elapsedRealtimeMs); 9753 } 9754 noteStopGps(long elapsedRealtimeMs)9755 public void noteStopGps(long elapsedRealtimeMs) { 9756 noteStopSensor(Sensor.GPS, elapsedRealtimeMs); 9757 } 9758 getBatteryStats()9759 public BatteryStatsImpl getBatteryStats() { 9760 return mBsi; 9761 } 9762 } 9763 getCpuFreqs()9764 public long[] getCpuFreqs() { 9765 return mCpuFreqs; 9766 } 9767 BatteryStatsImpl(File systemDir, Handler handler, PlatformIdleStateCallback cb, RailEnergyDataCallback railStatsCb, UserInfoProvider userInfoProvider)9768 public BatteryStatsImpl(File systemDir, Handler handler, PlatformIdleStateCallback cb, 9769 RailEnergyDataCallback railStatsCb, UserInfoProvider userInfoProvider) { 9770 this(new SystemClocks(), systemDir, handler, cb, railStatsCb, userInfoProvider); 9771 } 9772 BatteryStatsImpl(Clocks clocks, File systemDir, Handler handler, PlatformIdleStateCallback cb, RailEnergyDataCallback railStatsCb, UserInfoProvider userInfoProvider)9773 private BatteryStatsImpl(Clocks clocks, File systemDir, Handler handler, 9774 PlatformIdleStateCallback cb, RailEnergyDataCallback railStatsCb, 9775 UserInfoProvider userInfoProvider) { 9776 init(clocks); 9777 9778 9779 if (systemDir == null) { 9780 mStatsFile = null; 9781 mBatteryStatsHistory = new BatteryStatsHistory(this, mHistoryBuffer); 9782 } else { 9783 mStatsFile = new AtomicFile(new File(systemDir, "batterystats.bin")); 9784 mBatteryStatsHistory = new BatteryStatsHistory(this, systemDir, mHistoryBuffer); 9785 } 9786 mCheckinFile = new AtomicFile(new File(systemDir, "batterystats-checkin.bin")); 9787 mDailyFile = new AtomicFile(new File(systemDir, "batterystats-daily.xml")); 9788 mHandler = new MyHandler(handler.getLooper()); 9789 mConstants = new Constants(mHandler); 9790 mStartCount++; 9791 mScreenOnTimer = new StopwatchTimer(mClocks, null, -1, null, mOnBatteryTimeBase); 9792 mScreenDozeTimer = new StopwatchTimer(mClocks, null, -1, null, mOnBatteryTimeBase); 9793 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 9794 mScreenBrightnessTimer[i] = new StopwatchTimer(mClocks, null, -100-i, null, 9795 mOnBatteryTimeBase); 9796 } 9797 mInteractiveTimer = new StopwatchTimer(mClocks, null, -10, null, mOnBatteryTimeBase); 9798 mPowerSaveModeEnabledTimer = new StopwatchTimer(mClocks, null, -2, null, 9799 mOnBatteryTimeBase); 9800 mDeviceIdleModeLightTimer = new StopwatchTimer(mClocks, null, -11, null, 9801 mOnBatteryTimeBase); 9802 mDeviceIdleModeFullTimer = new StopwatchTimer(mClocks, null, -14, null, mOnBatteryTimeBase); 9803 mDeviceLightIdlingTimer = new StopwatchTimer(mClocks, null, -15, null, mOnBatteryTimeBase); 9804 mDeviceIdlingTimer = new StopwatchTimer(mClocks, null, -12, null, mOnBatteryTimeBase); 9805 mPhoneOnTimer = new StopwatchTimer(mClocks, null, -3, null, mOnBatteryTimeBase); 9806 for (int i = 0; i < CellSignalStrength.getNumSignalStrengthLevels(); i++) { 9807 mPhoneSignalStrengthsTimer[i] = new StopwatchTimer(mClocks, null, -200-i, null, 9808 mOnBatteryTimeBase); 9809 } 9810 mPhoneSignalScanningTimer = new StopwatchTimer(mClocks, null, -200+1, null, 9811 mOnBatteryTimeBase); 9812 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 9813 mPhoneDataConnectionsTimer[i] = new StopwatchTimer(mClocks, null, -300-i, null, 9814 mOnBatteryTimeBase); 9815 } 9816 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 9817 mNetworkByteActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase); 9818 mNetworkPacketActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase); 9819 } 9820 mWifiActivity = new ControllerActivityCounterImpl(mOnBatteryTimeBase, NUM_WIFI_TX_LEVELS); 9821 mBluetoothActivity = new ControllerActivityCounterImpl(mOnBatteryTimeBase, 9822 NUM_BT_TX_LEVELS); 9823 mModemActivity = new ControllerActivityCounterImpl(mOnBatteryTimeBase, 9824 ModemActivityInfo.TX_POWER_LEVELS); 9825 mMobileRadioActiveTimer = new StopwatchTimer(mClocks, null, -400, null, mOnBatteryTimeBase); 9826 mMobileRadioActivePerAppTimer = new StopwatchTimer(mClocks, null, -401, null, 9827 mOnBatteryTimeBase); 9828 mMobileRadioActiveAdjustedTime = new LongSamplingCounter(mOnBatteryTimeBase); 9829 mMobileRadioActiveUnknownTime = new LongSamplingCounter(mOnBatteryTimeBase); 9830 mMobileRadioActiveUnknownCount = new LongSamplingCounter(mOnBatteryTimeBase); 9831 mWifiMulticastWakelockTimer = new StopwatchTimer(mClocks, null, 9832 WIFI_AGGREGATE_MULTICAST_ENABLED, null, mOnBatteryTimeBase); 9833 mWifiOnTimer = new StopwatchTimer(mClocks, null, -4, null, mOnBatteryTimeBase); 9834 mGlobalWifiRunningTimer = new StopwatchTimer(mClocks, null, -5, null, mOnBatteryTimeBase); 9835 for (int i=0; i<NUM_WIFI_STATES; i++) { 9836 mWifiStateTimer[i] = new StopwatchTimer(mClocks, null, -600-i, null, 9837 mOnBatteryTimeBase); 9838 } 9839 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) { 9840 mWifiSupplStateTimer[i] = new StopwatchTimer(mClocks, null, -700-i, null, 9841 mOnBatteryTimeBase); 9842 } 9843 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { 9844 mWifiSignalStrengthsTimer[i] = new StopwatchTimer(mClocks, null, -800-i, null, 9845 mOnBatteryTimeBase); 9846 } 9847 mWifiActiveTimer = new StopwatchTimer(mClocks, null, -900, null, mOnBatteryTimeBase); 9848 for (int i=0; i< GnssMetrics.NUM_GPS_SIGNAL_QUALITY_LEVELS; i++) { 9849 mGpsSignalQualityTimer[i] = new StopwatchTimer(mClocks, null, -1000-i, null, 9850 mOnBatteryTimeBase); 9851 } 9852 mAudioOnTimer = new StopwatchTimer(mClocks, null, -7, null, mOnBatteryTimeBase); 9853 mVideoOnTimer = new StopwatchTimer(mClocks, null, -8, null, mOnBatteryTimeBase); 9854 mFlashlightOnTimer = new StopwatchTimer(mClocks, null, -9, null, mOnBatteryTimeBase); 9855 mCameraOnTimer = new StopwatchTimer(mClocks, null, -13, null, mOnBatteryTimeBase); 9856 mBluetoothScanTimer = new StopwatchTimer(mClocks, null, -14, null, mOnBatteryTimeBase); 9857 mDischargeScreenOffCounter = new LongSamplingCounter(mOnBatteryScreenOffTimeBase); 9858 mDischargeScreenDozeCounter = new LongSamplingCounter(mOnBatteryTimeBase); 9859 mDischargeLightDozeCounter = new LongSamplingCounter(mOnBatteryTimeBase); 9860 mDischargeDeepDozeCounter = new LongSamplingCounter(mOnBatteryTimeBase); 9861 mDischargeCounter = new LongSamplingCounter(mOnBatteryTimeBase); 9862 mOnBattery = mOnBatteryInternal = false; 9863 long uptime = mClocks.uptimeMillis() * 1000; 9864 long realtime = mClocks.elapsedRealtime() * 1000; 9865 initTimes(uptime, realtime); 9866 mStartPlatformVersion = mEndPlatformVersion = Build.ID; 9867 mDischargeStartLevel = 0; 9868 mDischargeUnplugLevel = 0; 9869 mDischargePlugLevel = -1; 9870 mDischargeCurrentLevel = 0; 9871 mCurrentBatteryLevel = 0; 9872 initDischarge(); 9873 clearHistoryLocked(); 9874 updateDailyDeadlineLocked(); 9875 mPlatformIdleStateCallback = cb; 9876 mRailEnergyDataCallback = railStatsCb; 9877 mUserInfoProvider = userInfoProvider; 9878 9879 // Notify statsd that the system is initially not in doze. 9880 mDeviceIdleMode = DEVICE_IDLE_MODE_OFF; 9881 FrameworkStatsLog.write(FrameworkStatsLog.DEVICE_IDLE_MODE_STATE_CHANGED, mDeviceIdleMode); 9882 } 9883 9884 @UnsupportedAppUsage BatteryStatsImpl(Parcel p)9885 public BatteryStatsImpl(Parcel p) { 9886 this(new SystemClocks(), p); 9887 } 9888 BatteryStatsImpl(Clocks clocks, Parcel p)9889 public BatteryStatsImpl(Clocks clocks, Parcel p) { 9890 init(clocks); 9891 mStatsFile = null; 9892 mCheckinFile = null; 9893 mDailyFile = null; 9894 mHandler = null; 9895 mExternalSync = null; 9896 mConstants = new Constants(mHandler); 9897 clearHistoryLocked(); 9898 mBatteryStatsHistory = new BatteryStatsHistory(this, mHistoryBuffer); 9899 readFromParcel(p); 9900 mPlatformIdleStateCallback = null; 9901 mRailEnergyDataCallback = null; 9902 } 9903 setPowerProfileLocked(PowerProfile profile)9904 public void setPowerProfileLocked(PowerProfile profile) { 9905 mPowerProfile = profile; 9906 9907 // We need to initialize the KernelCpuSpeedReaders to read from 9908 // the first cpu of each core. Once we have the PowerProfile, we have access to this 9909 // information. 9910 final int numClusters = mPowerProfile.getNumCpuClusters(); 9911 mKernelCpuSpeedReaders = new KernelCpuSpeedReader[numClusters]; 9912 int firstCpuOfCluster = 0; 9913 for (int i = 0; i < numClusters; i++) { 9914 final int numSpeedSteps = mPowerProfile.getNumSpeedStepsInCpuCluster(i); 9915 mKernelCpuSpeedReaders[i] = new KernelCpuSpeedReader(firstCpuOfCluster, 9916 numSpeedSteps); 9917 firstCpuOfCluster += mPowerProfile.getNumCoresInCpuCluster(i); 9918 } 9919 9920 if (mEstimatedBatteryCapacity == -1) { 9921 // Initialize the estimated battery capacity to a known preset one. 9922 mEstimatedBatteryCapacity = (int) mPowerProfile.getBatteryCapacity(); 9923 } 9924 } 9925 setCallback(BatteryCallback cb)9926 public void setCallback(BatteryCallback cb) { 9927 mCallback = cb; 9928 } 9929 setRadioScanningTimeoutLocked(long timeout)9930 public void setRadioScanningTimeoutLocked(long timeout) { 9931 if (mPhoneSignalScanningTimer != null) { 9932 mPhoneSignalScanningTimer.setTimeout(timeout); 9933 } 9934 } 9935 setExternalStatsSyncLocked(ExternalStatsSync sync)9936 public void setExternalStatsSyncLocked(ExternalStatsSync sync) { 9937 mExternalSync = sync; 9938 } 9939 updateDailyDeadlineLocked()9940 public void updateDailyDeadlineLocked() { 9941 // Get the current time. 9942 long currentTime = mDailyStartTime = System.currentTimeMillis(); 9943 Calendar calDeadline = Calendar.getInstance(); 9944 calDeadline.setTimeInMillis(currentTime); 9945 9946 // Move time up to the next day, ranging from 1am to 3pm. 9947 calDeadline.set(Calendar.DAY_OF_YEAR, calDeadline.get(Calendar.DAY_OF_YEAR) + 1); 9948 calDeadline.set(Calendar.MILLISECOND, 0); 9949 calDeadline.set(Calendar.SECOND, 0); 9950 calDeadline.set(Calendar.MINUTE, 0); 9951 calDeadline.set(Calendar.HOUR_OF_DAY, 1); 9952 mNextMinDailyDeadline = calDeadline.getTimeInMillis(); 9953 calDeadline.set(Calendar.HOUR_OF_DAY, 3); 9954 mNextMaxDailyDeadline = calDeadline.getTimeInMillis(); 9955 } 9956 recordDailyStatsIfNeededLocked(boolean settled)9957 public void recordDailyStatsIfNeededLocked(boolean settled) { 9958 long currentTime = System.currentTimeMillis(); 9959 if (currentTime >= mNextMaxDailyDeadline) { 9960 recordDailyStatsLocked(); 9961 } else if (settled && currentTime >= mNextMinDailyDeadline) { 9962 recordDailyStatsLocked(); 9963 } else if (currentTime < (mDailyStartTime-(1000*60*60*24))) { 9964 recordDailyStatsLocked(); 9965 } 9966 } 9967 recordDailyStatsLocked()9968 public void recordDailyStatsLocked() { 9969 DailyItem item = new DailyItem(); 9970 item.mStartTime = mDailyStartTime; 9971 item.mEndTime = System.currentTimeMillis(); 9972 boolean hasData = false; 9973 if (mDailyDischargeStepTracker.mNumStepDurations > 0) { 9974 hasData = true; 9975 item.mDischargeSteps = new LevelStepTracker( 9976 mDailyDischargeStepTracker.mNumStepDurations, 9977 mDailyDischargeStepTracker.mStepDurations); 9978 } 9979 if (mDailyChargeStepTracker.mNumStepDurations > 0) { 9980 hasData = true; 9981 item.mChargeSteps = new LevelStepTracker( 9982 mDailyChargeStepTracker.mNumStepDurations, 9983 mDailyChargeStepTracker.mStepDurations); 9984 } 9985 if (mDailyPackageChanges != null) { 9986 hasData = true; 9987 item.mPackageChanges = mDailyPackageChanges; 9988 mDailyPackageChanges = null; 9989 } 9990 mDailyDischargeStepTracker.init(); 9991 mDailyChargeStepTracker.init(); 9992 updateDailyDeadlineLocked(); 9993 9994 if (hasData) { 9995 final long startTime = SystemClock.uptimeMillis(); 9996 mDailyItems.add(item); 9997 while (mDailyItems.size() > MAX_DAILY_ITEMS) { 9998 mDailyItems.remove(0); 9999 } 10000 final ByteArrayOutputStream memStream = new ByteArrayOutputStream(); 10001 try { 10002 XmlSerializer out = new FastXmlSerializer(); 10003 out.setOutput(memStream, StandardCharsets.UTF_8.name()); 10004 writeDailyItemsLocked(out); 10005 final long initialTime = SystemClock.uptimeMillis() - startTime; 10006 BackgroundThread.getHandler().post(new Runnable() { 10007 @Override 10008 public void run() { 10009 synchronized (mCheckinFile) { 10010 final long startTime2 = SystemClock.uptimeMillis(); 10011 FileOutputStream stream = null; 10012 try { 10013 stream = mDailyFile.startWrite(); 10014 memStream.writeTo(stream); 10015 stream.flush(); 10016 mDailyFile.finishWrite(stream); 10017 com.android.internal.logging.EventLogTags.writeCommitSysConfigFile( 10018 "batterystats-daily", 10019 initialTime + SystemClock.uptimeMillis() - startTime2); 10020 } catch (IOException e) { 10021 Slog.w("BatteryStats", 10022 "Error writing battery daily items", e); 10023 mDailyFile.failWrite(stream); 10024 } 10025 } 10026 } 10027 }); 10028 } catch (IOException e) { 10029 } 10030 } 10031 } 10032 writeDailyItemsLocked(XmlSerializer out)10033 private void writeDailyItemsLocked(XmlSerializer out) throws IOException { 10034 StringBuilder sb = new StringBuilder(64); 10035 out.startDocument(null, true); 10036 out.startTag(null, "daily-items"); 10037 for (int i=0; i<mDailyItems.size(); i++) { 10038 final DailyItem dit = mDailyItems.get(i); 10039 out.startTag(null, "item"); 10040 out.attribute(null, "start", Long.toString(dit.mStartTime)); 10041 out.attribute(null, "end", Long.toString(dit.mEndTime)); 10042 writeDailyLevelSteps(out, "dis", dit.mDischargeSteps, sb); 10043 writeDailyLevelSteps(out, "chg", dit.mChargeSteps, sb); 10044 if (dit.mPackageChanges != null) { 10045 for (int j=0; j<dit.mPackageChanges.size(); j++) { 10046 PackageChange pc = dit.mPackageChanges.get(j); 10047 if (pc.mUpdate) { 10048 out.startTag(null, "upd"); 10049 out.attribute(null, "pkg", pc.mPackageName); 10050 out.attribute(null, "ver", Long.toString(pc.mVersionCode)); 10051 out.endTag(null, "upd"); 10052 } else { 10053 out.startTag(null, "rem"); 10054 out.attribute(null, "pkg", pc.mPackageName); 10055 out.endTag(null, "rem"); 10056 } 10057 } 10058 } 10059 out.endTag(null, "item"); 10060 } 10061 out.endTag(null, "daily-items"); 10062 out.endDocument(); 10063 } 10064 writeDailyLevelSteps(XmlSerializer out, String tag, LevelStepTracker steps, StringBuilder tmpBuilder)10065 private void writeDailyLevelSteps(XmlSerializer out, String tag, LevelStepTracker steps, 10066 StringBuilder tmpBuilder) throws IOException { 10067 if (steps != null) { 10068 out.startTag(null, tag); 10069 out.attribute(null, "n", Integer.toString(steps.mNumStepDurations)); 10070 for (int i=0; i<steps.mNumStepDurations; i++) { 10071 out.startTag(null, "s"); 10072 tmpBuilder.setLength(0); 10073 steps.encodeEntryAt(i, tmpBuilder); 10074 out.attribute(null, "v", tmpBuilder.toString()); 10075 out.endTag(null, "s"); 10076 } 10077 out.endTag(null, tag); 10078 } 10079 } 10080 readDailyStatsLocked()10081 public void readDailyStatsLocked() { 10082 Slog.d(TAG, "Reading daily items from " + mDailyFile.getBaseFile()); 10083 mDailyItems.clear(); 10084 FileInputStream stream; 10085 try { 10086 stream = mDailyFile.openRead(); 10087 } catch (FileNotFoundException e) { 10088 return; 10089 } 10090 try { 10091 XmlPullParser parser = Xml.newPullParser(); 10092 parser.setInput(stream, StandardCharsets.UTF_8.name()); 10093 readDailyItemsLocked(parser); 10094 } catch (XmlPullParserException e) { 10095 } finally { 10096 try { 10097 stream.close(); 10098 } catch (IOException e) { 10099 } 10100 } 10101 } 10102 readDailyItemsLocked(XmlPullParser parser)10103 private void readDailyItemsLocked(XmlPullParser parser) { 10104 try { 10105 int type; 10106 while ((type = parser.next()) != XmlPullParser.START_TAG 10107 && type != XmlPullParser.END_DOCUMENT) { 10108 ; 10109 } 10110 10111 if (type != XmlPullParser.START_TAG) { 10112 throw new IllegalStateException("no start tag found"); 10113 } 10114 10115 int outerDepth = parser.getDepth(); 10116 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 10117 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 10118 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 10119 continue; 10120 } 10121 10122 String tagName = parser.getName(); 10123 if (tagName.equals("item")) { 10124 readDailyItemTagLocked(parser); 10125 } else { 10126 Slog.w(TAG, "Unknown element under <daily-items>: " 10127 + parser.getName()); 10128 XmlUtils.skipCurrentTag(parser); 10129 } 10130 } 10131 10132 } catch (IllegalStateException e) { 10133 Slog.w(TAG, "Failed parsing daily " + e); 10134 } catch (NullPointerException e) { 10135 Slog.w(TAG, "Failed parsing daily " + e); 10136 } catch (NumberFormatException e) { 10137 Slog.w(TAG, "Failed parsing daily " + e); 10138 } catch (XmlPullParserException e) { 10139 Slog.w(TAG, "Failed parsing daily " + e); 10140 } catch (IOException e) { 10141 Slog.w(TAG, "Failed parsing daily " + e); 10142 } catch (IndexOutOfBoundsException e) { 10143 Slog.w(TAG, "Failed parsing daily " + e); 10144 } 10145 } 10146 readDailyItemTagLocked(XmlPullParser parser)10147 void readDailyItemTagLocked(XmlPullParser parser) throws NumberFormatException, 10148 XmlPullParserException, IOException { 10149 DailyItem dit = new DailyItem(); 10150 String attr = parser.getAttributeValue(null, "start"); 10151 if (attr != null) { 10152 dit.mStartTime = Long.parseLong(attr); 10153 } 10154 attr = parser.getAttributeValue(null, "end"); 10155 if (attr != null) { 10156 dit.mEndTime = Long.parseLong(attr); 10157 } 10158 int outerDepth = parser.getDepth(); 10159 int type; 10160 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 10161 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 10162 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 10163 continue; 10164 } 10165 10166 String tagName = parser.getName(); 10167 if (tagName.equals("dis")) { 10168 readDailyItemTagDetailsLocked(parser, dit, false, "dis"); 10169 } else if (tagName.equals("chg")) { 10170 readDailyItemTagDetailsLocked(parser, dit, true, "chg"); 10171 } else if (tagName.equals("upd")) { 10172 if (dit.mPackageChanges == null) { 10173 dit.mPackageChanges = new ArrayList<>(); 10174 } 10175 PackageChange pc = new PackageChange(); 10176 pc.mUpdate = true; 10177 pc.mPackageName = parser.getAttributeValue(null, "pkg"); 10178 String verStr = parser.getAttributeValue(null, "ver"); 10179 pc.mVersionCode = verStr != null ? Long.parseLong(verStr) : 0; 10180 dit.mPackageChanges.add(pc); 10181 XmlUtils.skipCurrentTag(parser); 10182 } else if (tagName.equals("rem")) { 10183 if (dit.mPackageChanges == null) { 10184 dit.mPackageChanges = new ArrayList<>(); 10185 } 10186 PackageChange pc = new PackageChange(); 10187 pc.mUpdate = false; 10188 pc.mPackageName = parser.getAttributeValue(null, "pkg"); 10189 dit.mPackageChanges.add(pc); 10190 XmlUtils.skipCurrentTag(parser); 10191 } else { 10192 Slog.w(TAG, "Unknown element under <item>: " 10193 + parser.getName()); 10194 XmlUtils.skipCurrentTag(parser); 10195 } 10196 } 10197 mDailyItems.add(dit); 10198 } 10199 readDailyItemTagDetailsLocked(XmlPullParser parser, DailyItem dit, boolean isCharge, String tag)10200 void readDailyItemTagDetailsLocked(XmlPullParser parser, DailyItem dit, boolean isCharge, 10201 String tag) 10202 throws NumberFormatException, XmlPullParserException, IOException { 10203 final String numAttr = parser.getAttributeValue(null, "n"); 10204 if (numAttr == null) { 10205 Slog.w(TAG, "Missing 'n' attribute at " + parser.getPositionDescription()); 10206 XmlUtils.skipCurrentTag(parser); 10207 return; 10208 } 10209 final int num = Integer.parseInt(numAttr); 10210 LevelStepTracker steps = new LevelStepTracker(num); 10211 if (isCharge) { 10212 dit.mChargeSteps = steps; 10213 } else { 10214 dit.mDischargeSteps = steps; 10215 } 10216 int i = 0; 10217 int outerDepth = parser.getDepth(); 10218 int type; 10219 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 10220 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 10221 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 10222 continue; 10223 } 10224 10225 String tagName = parser.getName(); 10226 if ("s".equals(tagName)) { 10227 if (i < num) { 10228 String valueAttr = parser.getAttributeValue(null, "v"); 10229 if (valueAttr != null) { 10230 steps.decodeEntryAt(i, valueAttr); 10231 i++; 10232 } 10233 } 10234 } else { 10235 Slog.w(TAG, "Unknown element under <" + tag + ">: " 10236 + parser.getName()); 10237 XmlUtils.skipCurrentTag(parser); 10238 } 10239 } 10240 steps.mNumStepDurations = i; 10241 } 10242 10243 @Override getDailyItemLocked(int daysAgo)10244 public DailyItem getDailyItemLocked(int daysAgo) { 10245 int index = mDailyItems.size()-1-daysAgo; 10246 return index >= 0 ? mDailyItems.get(index) : null; 10247 } 10248 10249 @Override getCurrentDailyStartTime()10250 public long getCurrentDailyStartTime() { 10251 return mDailyStartTime; 10252 } 10253 10254 @Override getNextMinDailyDeadline()10255 public long getNextMinDailyDeadline() { 10256 return mNextMinDailyDeadline; 10257 } 10258 10259 @Override getNextMaxDailyDeadline()10260 public long getNextMaxDailyDeadline() { 10261 return mNextMaxDailyDeadline; 10262 } 10263 10264 @Override startIteratingOldHistoryLocked()10265 public boolean startIteratingOldHistoryLocked() { 10266 if (DEBUG_HISTORY) Slog.i(TAG, "ITERATING: buff size=" + mHistoryBuffer.dataSize() 10267 + " pos=" + mHistoryBuffer.dataPosition()); 10268 if ((mHistoryIterator = mHistory) == null) { 10269 return false; 10270 } 10271 mHistoryBuffer.setDataPosition(0); 10272 mHistoryReadTmp.clear(); 10273 mReadOverflow = false; 10274 mIteratingHistory = true; 10275 return true; 10276 } 10277 10278 @Override getNextOldHistoryLocked(HistoryItem out)10279 public boolean getNextOldHistoryLocked(HistoryItem out) { 10280 boolean end = mHistoryBuffer.dataPosition() >= mHistoryBuffer.dataSize(); 10281 if (!end) { 10282 readHistoryDelta(mHistoryBuffer, mHistoryReadTmp); 10283 mReadOverflow |= mHistoryReadTmp.cmd == HistoryItem.CMD_OVERFLOW; 10284 } 10285 HistoryItem cur = mHistoryIterator; 10286 if (cur == null) { 10287 if (!mReadOverflow && !end) { 10288 Slog.w(TAG, "Old history ends before new history!"); 10289 } 10290 return false; 10291 } 10292 out.setTo(cur); 10293 mHistoryIterator = cur.next; 10294 if (!mReadOverflow) { 10295 if (end) { 10296 Slog.w(TAG, "New history ends before old history!"); 10297 } else if (!out.same(mHistoryReadTmp)) { 10298 PrintWriter pw = new FastPrintWriter(new LogWriter(android.util.Log.WARN, TAG)); 10299 pw.println("Histories differ!"); 10300 pw.println("Old history:"); 10301 (new HistoryPrinter()).printNextItem(pw, out, 0, false, true); 10302 pw.println("New history:"); 10303 (new HistoryPrinter()).printNextItem(pw, mHistoryReadTmp, 0, false, 10304 true); 10305 pw.flush(); 10306 } 10307 } 10308 return true; 10309 } 10310 10311 @Override finishIteratingOldHistoryLocked()10312 public void finishIteratingOldHistoryLocked() { 10313 mIteratingHistory = false; 10314 mHistoryBuffer.setDataPosition(mHistoryBuffer.dataSize()); 10315 mHistoryIterator = null; 10316 } 10317 getHistoryTotalSize()10318 public int getHistoryTotalSize() { 10319 return mConstants.MAX_HISTORY_BUFFER * mConstants.MAX_HISTORY_FILES; 10320 } 10321 getHistoryUsedSize()10322 public int getHistoryUsedSize() { 10323 return mBatteryStatsHistory.getHistoryUsedSize(); 10324 } 10325 10326 @Override 10327 @UnsupportedAppUsage startIteratingHistoryLocked()10328 public boolean startIteratingHistoryLocked() { 10329 mBatteryStatsHistory.startIteratingHistory(); 10330 mReadOverflow = false; 10331 mIteratingHistory = true; 10332 mReadHistoryStrings = new String[mHistoryTagPool.size()]; 10333 mReadHistoryUids = new int[mHistoryTagPool.size()]; 10334 mReadHistoryChars = 0; 10335 for (HashMap.Entry<HistoryTag, Integer> ent : mHistoryTagPool.entrySet()) { 10336 final HistoryTag tag = ent.getKey(); 10337 final int idx = ent.getValue(); 10338 mReadHistoryStrings[idx] = tag.string; 10339 mReadHistoryUids[idx] = tag.uid; 10340 mReadHistoryChars += tag.string.length() + 1; 10341 } 10342 return true; 10343 } 10344 10345 @Override getHistoryStringPoolSize()10346 public int getHistoryStringPoolSize() { 10347 return mReadHistoryStrings.length; 10348 } 10349 10350 @Override getHistoryStringPoolBytes()10351 public int getHistoryStringPoolBytes() { 10352 // Each entry is a fixed 12 bytes: 4 for index, 4 for uid, 4 for string size 10353 // Each string character is 2 bytes. 10354 return (mReadHistoryStrings.length * 12) + (mReadHistoryChars * 2); 10355 } 10356 10357 @Override getHistoryTagPoolString(int index)10358 public String getHistoryTagPoolString(int index) { 10359 return mReadHistoryStrings[index]; 10360 } 10361 10362 @Override getHistoryTagPoolUid(int index)10363 public int getHistoryTagPoolUid(int index) { 10364 return mReadHistoryUids[index]; 10365 } 10366 10367 @Override 10368 @UnsupportedAppUsage getNextHistoryLocked(HistoryItem out)10369 public boolean getNextHistoryLocked(HistoryItem out) { 10370 Parcel p = mBatteryStatsHistory.getNextParcel(out); 10371 if (p == null) { 10372 return false; 10373 } 10374 final long lastRealtime = out.time; 10375 final long lastWalltime = out.currentTime; 10376 readHistoryDelta(p, out); 10377 if (out.cmd != HistoryItem.CMD_CURRENT_TIME 10378 && out.cmd != HistoryItem.CMD_RESET && lastWalltime != 0) { 10379 out.currentTime = lastWalltime + (out.time - lastRealtime); 10380 } 10381 return true; 10382 } 10383 10384 @Override finishIteratingHistoryLocked()10385 public void finishIteratingHistoryLocked() { 10386 mBatteryStatsHistory.finishIteratingHistory(); 10387 mIteratingHistory = false; 10388 mReadHistoryStrings = null; 10389 mReadHistoryUids = null; 10390 } 10391 10392 @Override getHistoryBaseTime()10393 public long getHistoryBaseTime() { 10394 return mHistoryBaseTime; 10395 } 10396 10397 @Override getStartCount()10398 public int getStartCount() { 10399 return mStartCount; 10400 } 10401 10402 @UnsupportedAppUsage isOnBattery()10403 public boolean isOnBattery() { 10404 return mOnBattery; 10405 } 10406 isCharging()10407 public boolean isCharging() { 10408 return mCharging; 10409 } 10410 isScreenOn(int state)10411 public boolean isScreenOn(int state) { 10412 return state == Display.STATE_ON || state == Display.STATE_VR 10413 || state == Display.STATE_ON_SUSPEND; 10414 } 10415 isScreenOff(int state)10416 public boolean isScreenOff(int state) { 10417 return state == Display.STATE_OFF; 10418 } 10419 isScreenDoze(int state)10420 public boolean isScreenDoze(int state) { 10421 return state == Display.STATE_DOZE || state == Display.STATE_DOZE_SUSPEND; 10422 } 10423 initTimes(long uptime, long realtime)10424 void initTimes(long uptime, long realtime) { 10425 mStartClockTime = System.currentTimeMillis(); 10426 mOnBatteryTimeBase.init(uptime, realtime); 10427 mOnBatteryScreenOffTimeBase.init(uptime, realtime); 10428 mRealtime = 0; 10429 mUptime = 0; 10430 mRealtimeStart = realtime; 10431 mUptimeStart = uptime; 10432 } 10433 initDischarge()10434 void initDischarge() { 10435 mLowDischargeAmountSinceCharge = 0; 10436 mHighDischargeAmountSinceCharge = 0; 10437 mDischargeAmountScreenOn = 0; 10438 mDischargeAmountScreenOnSinceCharge = 0; 10439 mDischargeAmountScreenOff = 0; 10440 mDischargeAmountScreenOffSinceCharge = 0; 10441 mDischargeAmountScreenDoze = 0; 10442 mDischargeAmountScreenDozeSinceCharge = 0; 10443 mDischargeStepTracker.init(); 10444 mChargeStepTracker.init(); 10445 mDischargeScreenOffCounter.reset(false); 10446 mDischargeScreenDozeCounter.reset(false); 10447 mDischargeLightDozeCounter.reset(false); 10448 mDischargeDeepDozeCounter.reset(false); 10449 mDischargeCounter.reset(false); 10450 } 10451 resetAllStatsCmdLocked()10452 public void resetAllStatsCmdLocked() { 10453 resetAllStatsLocked(); 10454 final long mSecUptime = mClocks.uptimeMillis(); 10455 long uptime = mSecUptime * 1000; 10456 long mSecRealtime = mClocks.elapsedRealtime(); 10457 long realtime = mSecRealtime * 1000; 10458 mDischargeStartLevel = mHistoryCur.batteryLevel; 10459 pullPendingStateUpdatesLocked(); 10460 addHistoryRecordLocked(mSecRealtime, mSecUptime); 10461 mDischargeCurrentLevel = mDischargeUnplugLevel = mDischargePlugLevel 10462 = mCurrentBatteryLevel = mHistoryCur.batteryLevel; 10463 mOnBatteryTimeBase.reset(uptime, realtime); 10464 mOnBatteryScreenOffTimeBase.reset(uptime, realtime); 10465 if ((mHistoryCur.states&HistoryItem.STATE_BATTERY_PLUGGED_FLAG) == 0) { 10466 if (isScreenOn(mScreenState)) { 10467 mDischargeScreenOnUnplugLevel = mHistoryCur.batteryLevel; 10468 mDischargeScreenDozeUnplugLevel = 0; 10469 mDischargeScreenOffUnplugLevel = 0; 10470 } else if (isScreenDoze(mScreenState)) { 10471 mDischargeScreenOnUnplugLevel = 0; 10472 mDischargeScreenDozeUnplugLevel = mHistoryCur.batteryLevel; 10473 mDischargeScreenOffUnplugLevel = 0; 10474 } else { 10475 mDischargeScreenOnUnplugLevel = 0; 10476 mDischargeScreenDozeUnplugLevel = 0; 10477 mDischargeScreenOffUnplugLevel = mHistoryCur.batteryLevel; 10478 } 10479 mDischargeAmountScreenOn = 0; 10480 mDischargeAmountScreenOff = 0; 10481 mDischargeAmountScreenDoze = 0; 10482 } 10483 initActiveHistoryEventsLocked(mSecRealtime, mSecUptime); 10484 } 10485 resetAllStatsLocked()10486 private void resetAllStatsLocked() { 10487 final long uptimeMillis = mClocks.uptimeMillis(); 10488 final long elapsedRealtimeMillis = mClocks.elapsedRealtime(); 10489 mStartCount = 0; 10490 initTimes(uptimeMillis * 1000, elapsedRealtimeMillis * 1000); 10491 mScreenOnTimer.reset(false); 10492 mScreenDozeTimer.reset(false); 10493 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 10494 mScreenBrightnessTimer[i].reset(false); 10495 } 10496 10497 if (mPowerProfile != null) { 10498 mEstimatedBatteryCapacity = (int) mPowerProfile.getBatteryCapacity(); 10499 } else { 10500 mEstimatedBatteryCapacity = -1; 10501 } 10502 mMinLearnedBatteryCapacity = -1; 10503 mMaxLearnedBatteryCapacity = -1; 10504 mInteractiveTimer.reset(false); 10505 mPowerSaveModeEnabledTimer.reset(false); 10506 mLastIdleTimeStart = elapsedRealtimeMillis; 10507 mLongestLightIdleTime = 0; 10508 mLongestFullIdleTime = 0; 10509 mDeviceIdleModeLightTimer.reset(false); 10510 mDeviceIdleModeFullTimer.reset(false); 10511 mDeviceLightIdlingTimer.reset(false); 10512 mDeviceIdlingTimer.reset(false); 10513 mPhoneOnTimer.reset(false); 10514 mAudioOnTimer.reset(false); 10515 mVideoOnTimer.reset(false); 10516 mFlashlightOnTimer.reset(false); 10517 mCameraOnTimer.reset(false); 10518 mBluetoothScanTimer.reset(false); 10519 for (int i = 0; i < CellSignalStrength.getNumSignalStrengthLevels(); i++) { 10520 mPhoneSignalStrengthsTimer[i].reset(false); 10521 } 10522 mPhoneSignalScanningTimer.reset(false); 10523 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 10524 mPhoneDataConnectionsTimer[i].reset(false); 10525 } 10526 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 10527 mNetworkByteActivityCounters[i].reset(false); 10528 mNetworkPacketActivityCounters[i].reset(false); 10529 } 10530 mMobileRadioActiveTimer.reset(false); 10531 mMobileRadioActivePerAppTimer.reset(false); 10532 mMobileRadioActiveAdjustedTime.reset(false); 10533 mMobileRadioActiveUnknownTime.reset(false); 10534 mMobileRadioActiveUnknownCount.reset(false); 10535 mWifiOnTimer.reset(false); 10536 mGlobalWifiRunningTimer.reset(false); 10537 for (int i=0; i<NUM_WIFI_STATES; i++) { 10538 mWifiStateTimer[i].reset(false); 10539 } 10540 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) { 10541 mWifiSupplStateTimer[i].reset(false); 10542 } 10543 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { 10544 mWifiSignalStrengthsTimer[i].reset(false); 10545 } 10546 mWifiMulticastWakelockTimer.reset(false); 10547 mWifiActiveTimer.reset(false); 10548 mWifiActivity.reset(false); 10549 for (int i=0; i< GnssMetrics.NUM_GPS_SIGNAL_QUALITY_LEVELS; i++) { 10550 mGpsSignalQualityTimer[i].reset(false); 10551 } 10552 mBluetoothActivity.reset(false); 10553 mModemActivity.reset(false); 10554 mNumConnectivityChange = 0; 10555 10556 for (int i=0; i<mUidStats.size(); i++) { 10557 if (mUidStats.valueAt(i).reset(uptimeMillis * 1000, elapsedRealtimeMillis * 1000)) { 10558 mUidStats.valueAt(i).detachFromTimeBase(); 10559 mUidStats.remove(mUidStats.keyAt(i)); 10560 i--; 10561 } 10562 } 10563 10564 if (mRpmStats.size() > 0) { 10565 for (SamplingTimer timer : mRpmStats.values()) { 10566 mOnBatteryTimeBase.remove(timer); 10567 } 10568 mRpmStats.clear(); 10569 } 10570 if (mScreenOffRpmStats.size() > 0) { 10571 for (SamplingTimer timer : mScreenOffRpmStats.values()) { 10572 mOnBatteryScreenOffTimeBase.remove(timer); 10573 } 10574 mScreenOffRpmStats.clear(); 10575 } 10576 10577 if (mKernelWakelockStats.size() > 0) { 10578 for (SamplingTimer timer : mKernelWakelockStats.values()) { 10579 mOnBatteryScreenOffTimeBase.remove(timer); 10580 } 10581 mKernelWakelockStats.clear(); 10582 } 10583 10584 if (mKernelMemoryStats.size() > 0) { 10585 for (int i = 0; i < mKernelMemoryStats.size(); i++) { 10586 mOnBatteryTimeBase.remove(mKernelMemoryStats.valueAt(i)); 10587 } 10588 mKernelMemoryStats.clear(); 10589 } 10590 10591 if (mWakeupReasonStats.size() > 0) { 10592 for (SamplingTimer timer : mWakeupReasonStats.values()) { 10593 mOnBatteryTimeBase.remove(timer); 10594 } 10595 mWakeupReasonStats.clear(); 10596 } 10597 10598 mTmpRailStats.reset(); 10599 10600 mLastHistoryStepDetails = null; 10601 mLastStepCpuUserTime = mLastStepCpuSystemTime = 0; 10602 mCurStepCpuUserTime = mCurStepCpuSystemTime = 0; 10603 mLastStepCpuUserTime = mCurStepCpuUserTime = 0; 10604 mLastStepCpuSystemTime = mCurStepCpuSystemTime = 0; 10605 mLastStepStatUserTime = mCurStepStatUserTime = 0; 10606 mLastStepStatSystemTime = mCurStepStatSystemTime = 0; 10607 mLastStepStatIOWaitTime = mCurStepStatIOWaitTime = 0; 10608 mLastStepStatIrqTime = mCurStepStatIrqTime = 0; 10609 mLastStepStatSoftIrqTime = mCurStepStatSoftIrqTime = 0; 10610 mLastStepStatIdleTime = mCurStepStatIdleTime = 0; 10611 10612 mNumAllUidCpuTimeReads = 0; 10613 mNumUidsRemoved = 0; 10614 10615 initDischarge(); 10616 10617 clearHistoryLocked(); 10618 mBatteryStatsHistory.resetAllFiles(); 10619 10620 mHandler.sendEmptyMessage(MSG_REPORT_RESET_STATS); 10621 } 10622 initActiveHistoryEventsLocked(long elapsedRealtimeMs, long uptimeMs)10623 private void initActiveHistoryEventsLocked(long elapsedRealtimeMs, long uptimeMs) { 10624 for (int i=0; i<HistoryItem.EVENT_COUNT; i++) { 10625 if (!mRecordAllHistory && i == HistoryItem.EVENT_PROC) { 10626 // Not recording process starts/stops. 10627 continue; 10628 } 10629 HashMap<String, SparseIntArray> active = mActiveEvents.getStateForEvent(i); 10630 if (active == null) { 10631 continue; 10632 } 10633 for (HashMap.Entry<String, SparseIntArray> ent : active.entrySet()) { 10634 SparseIntArray uids = ent.getValue(); 10635 for (int j=0; j<uids.size(); j++) { 10636 addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, i, ent.getKey(), 10637 uids.keyAt(j)); 10638 } 10639 } 10640 } 10641 } 10642 updateDischargeScreenLevelsLocked(int oldState, int newState)10643 void updateDischargeScreenLevelsLocked(int oldState, int newState) { 10644 updateOldDischargeScreenLevelLocked(oldState); 10645 updateNewDischargeScreenLevelLocked(newState); 10646 } 10647 updateOldDischargeScreenLevelLocked(int state)10648 private void updateOldDischargeScreenLevelLocked(int state) { 10649 if (isScreenOn(state)) { 10650 int diff = mDischargeScreenOnUnplugLevel - mDischargeCurrentLevel; 10651 if (diff > 0) { 10652 mDischargeAmountScreenOn += diff; 10653 mDischargeAmountScreenOnSinceCharge += diff; 10654 } 10655 } else if (isScreenDoze(state)) { 10656 int diff = mDischargeScreenDozeUnplugLevel - mDischargeCurrentLevel; 10657 if (diff > 0) { 10658 mDischargeAmountScreenDoze += diff; 10659 mDischargeAmountScreenDozeSinceCharge += diff; 10660 } 10661 } else if (isScreenOff(state)){ 10662 int diff = mDischargeScreenOffUnplugLevel - mDischargeCurrentLevel; 10663 if (diff > 0) { 10664 mDischargeAmountScreenOff += diff; 10665 mDischargeAmountScreenOffSinceCharge += diff; 10666 } 10667 } 10668 } 10669 updateNewDischargeScreenLevelLocked(int state)10670 private void updateNewDischargeScreenLevelLocked(int state) { 10671 if (isScreenOn(state)) { 10672 mDischargeScreenOnUnplugLevel = mDischargeCurrentLevel; 10673 mDischargeScreenOffUnplugLevel = 0; 10674 mDischargeScreenDozeUnplugLevel = 0; 10675 } else if (isScreenDoze(state)){ 10676 mDischargeScreenOnUnplugLevel = 0; 10677 mDischargeScreenDozeUnplugLevel = mDischargeCurrentLevel; 10678 mDischargeScreenOffUnplugLevel = 0; 10679 } else if (isScreenOff(state)) { 10680 mDischargeScreenOnUnplugLevel = 0; 10681 mDischargeScreenDozeUnplugLevel = 0; 10682 mDischargeScreenOffUnplugLevel = mDischargeCurrentLevel; 10683 } 10684 } 10685 pullPendingStateUpdatesLocked()10686 public void pullPendingStateUpdatesLocked() { 10687 if (mOnBatteryInternal) { 10688 updateDischargeScreenLevelsLocked(mScreenState, mScreenState); 10689 } 10690 } 10691 10692 private final Pools.Pool<NetworkStats> mNetworkStatsPool = new Pools.SynchronizedPool<>(6); 10693 10694 private final Object mWifiNetworkLock = new Object(); 10695 10696 @GuardedBy("mWifiNetworkLock") 10697 private String[] mWifiIfaces = EmptyArray.STRING; 10698 10699 @GuardedBy("mWifiNetworkLock") 10700 private NetworkStats mLastWifiNetworkStats = new NetworkStats(0, -1); 10701 10702 private final Object mModemNetworkLock = new Object(); 10703 10704 @GuardedBy("mModemNetworkLock") 10705 private String[] mModemIfaces = EmptyArray.STRING; 10706 10707 @GuardedBy("mModemNetworkLock") 10708 private NetworkStats mLastModemNetworkStats = new NetworkStats(0, -1); 10709 readNetworkStatsLocked(String[] ifaces)10710 private NetworkStats readNetworkStatsLocked(String[] ifaces) { 10711 try { 10712 if (!ArrayUtils.isEmpty(ifaces)) { 10713 INetworkStatsService statsService = INetworkStatsService.Stub.asInterface( 10714 ServiceManager.getService(Context.NETWORK_STATS_SERVICE)); 10715 if (statsService != null) { 10716 return statsService.getDetailedUidStats(ifaces); 10717 } else { 10718 Slog.e(TAG, "Failed to get networkStatsService "); 10719 } 10720 } 10721 } catch (RemoteException e) { 10722 Slog.e(TAG, "failed to read network stats for ifaces: " + Arrays.toString(ifaces) + e); 10723 } 10724 return null; 10725 } 10726 10727 /** 10728 * Distribute WiFi energy info and network traffic to apps. 10729 * @param info The energy information from the WiFi controller. 10730 */ updateWifiState(@ullable final WifiActivityEnergyInfo info)10731 public void updateWifiState(@Nullable final WifiActivityEnergyInfo info) { 10732 if (DEBUG_ENERGY) { 10733 Slog.d(TAG, "Updating wifi stats: " + Arrays.toString(mWifiIfaces)); 10734 } 10735 10736 // Grab a separate lock to acquire the network stats, which may do I/O. 10737 NetworkStats delta = null; 10738 synchronized (mWifiNetworkLock) { 10739 final NetworkStats latestStats = readNetworkStatsLocked(mWifiIfaces); 10740 if (latestStats != null) { 10741 delta = NetworkStats.subtract(latestStats, mLastWifiNetworkStats, null, null, 10742 mNetworkStatsPool.acquire()); 10743 mNetworkStatsPool.release(mLastWifiNetworkStats); 10744 mLastWifiNetworkStats = latestStats; 10745 } 10746 } 10747 10748 synchronized (this) { 10749 if (!mOnBatteryInternal) { 10750 if (delta != null) { 10751 mNetworkStatsPool.release(delta); 10752 } 10753 return; 10754 } 10755 10756 final long elapsedRealtimeMs = mClocks.elapsedRealtime(); 10757 SparseLongArray rxPackets = new SparseLongArray(); 10758 SparseLongArray txPackets = new SparseLongArray(); 10759 long totalTxPackets = 0; 10760 long totalRxPackets = 0; 10761 if (delta != null) { 10762 NetworkStats.Entry entry = new NetworkStats.Entry(); 10763 final int size = delta.size(); 10764 for (int i = 0; i < size; i++) { 10765 entry = delta.getValues(i, entry); 10766 10767 if (DEBUG_ENERGY) { 10768 Slog.d(TAG, "Wifi uid " + entry.uid + ": delta rx=" + entry.rxBytes 10769 + " tx=" + entry.txBytes + " rxPackets=" + entry.rxPackets 10770 + " txPackets=" + entry.txPackets); 10771 } 10772 10773 if (entry.rxBytes == 0 && entry.txBytes == 0) { 10774 // Skip the lookup below since there is no work to do. 10775 continue; 10776 } 10777 10778 final Uid u = getUidStatsLocked(mapUid(entry.uid)); 10779 if (entry.rxBytes != 0) { 10780 u.noteNetworkActivityLocked(NETWORK_WIFI_RX_DATA, entry.rxBytes, 10781 entry.rxPackets); 10782 if (entry.set == NetworkStats.SET_DEFAULT) { // Background transfers 10783 u.noteNetworkActivityLocked(NETWORK_WIFI_BG_RX_DATA, entry.rxBytes, 10784 entry.rxPackets); 10785 } 10786 mNetworkByteActivityCounters[NETWORK_WIFI_RX_DATA].addCountLocked( 10787 entry.rxBytes); 10788 mNetworkPacketActivityCounters[NETWORK_WIFI_RX_DATA].addCountLocked( 10789 entry.rxPackets); 10790 10791 rxPackets.put(u.getUid(), entry.rxPackets); 10792 10793 // Sum the total number of packets so that the Rx Power can 10794 // be evenly distributed amongst the apps. 10795 totalRxPackets += entry.rxPackets; 10796 } 10797 10798 if (entry.txBytes != 0) { 10799 u.noteNetworkActivityLocked(NETWORK_WIFI_TX_DATA, entry.txBytes, 10800 entry.txPackets); 10801 if (entry.set == NetworkStats.SET_DEFAULT) { // Background transfers 10802 u.noteNetworkActivityLocked(NETWORK_WIFI_BG_TX_DATA, entry.txBytes, 10803 entry.txPackets); 10804 } 10805 mNetworkByteActivityCounters[NETWORK_WIFI_TX_DATA].addCountLocked( 10806 entry.txBytes); 10807 mNetworkPacketActivityCounters[NETWORK_WIFI_TX_DATA].addCountLocked( 10808 entry.txPackets); 10809 10810 txPackets.put(u.getUid(), entry.txPackets); 10811 10812 // Sum the total number of packets so that the Tx Power can 10813 // be evenly distributed amongst the apps. 10814 totalTxPackets += entry.txPackets; 10815 } 10816 } 10817 mNetworkStatsPool.release(delta); 10818 delta = null; 10819 } 10820 10821 if (info != null) { 10822 mHasWifiReporting = true; 10823 10824 // Measured in mAms 10825 final long txTimeMs = info.getControllerTxDurationMillis(); 10826 final long rxTimeMs = info.getControllerRxDurationMillis(); 10827 final long scanTimeMs = info.getControllerScanDurationMillis(); 10828 final long idleTimeMs = info.getControllerIdleDurationMillis(); 10829 final long totalTimeMs = txTimeMs + rxTimeMs + idleTimeMs; 10830 10831 long leftOverRxTimeMs = rxTimeMs; 10832 long leftOverTxTimeMs = txTimeMs; 10833 10834 if (DEBUG_ENERGY) { 10835 Slog.d(TAG, "------ BEGIN WiFi power blaming ------"); 10836 Slog.d(TAG, " Tx Time: " + txTimeMs + " ms"); 10837 Slog.d(TAG, " Rx Time: " + rxTimeMs + " ms"); 10838 Slog.d(TAG, " Idle Time: " + idleTimeMs + " ms"); 10839 Slog.d(TAG, " Total Time: " + totalTimeMs + " ms"); 10840 Slog.d(TAG, " Scan Time: " + scanTimeMs + " ms"); 10841 } 10842 10843 long totalWifiLockTimeMs = 0; 10844 long totalScanTimeMs = 0; 10845 10846 // On the first pass, collect some totals so that we can normalize power 10847 // calculations if we need to. 10848 final int uidStatsSize = mUidStats.size(); 10849 for (int i = 0; i < uidStatsSize; i++) { 10850 final Uid uid = mUidStats.valueAt(i); 10851 10852 // Sum the total scan power for all apps. 10853 totalScanTimeMs += uid.mWifiScanTimer.getTimeSinceMarkLocked( 10854 elapsedRealtimeMs * 1000) / 1000; 10855 10856 // Sum the total time holding wifi lock for all apps. 10857 totalWifiLockTimeMs += uid.mFullWifiLockTimer.getTimeSinceMarkLocked( 10858 elapsedRealtimeMs * 1000) / 1000; 10859 } 10860 10861 if (DEBUG_ENERGY && totalScanTimeMs > rxTimeMs) { 10862 Slog.d(TAG, 10863 " !Estimated scan time > Actual rx time (" + totalScanTimeMs + " ms > " 10864 + rxTimeMs + " ms). Normalizing scan time."); 10865 } 10866 if (DEBUG_ENERGY && totalScanTimeMs > txTimeMs) { 10867 Slog.d(TAG, 10868 " !Estimated scan time > Actual tx time (" + totalScanTimeMs + " ms > " 10869 + txTimeMs + " ms). Normalizing scan time."); 10870 } 10871 10872 // Actually assign and distribute power usage to apps. 10873 for (int i = 0; i < uidStatsSize; i++) { 10874 final Uid uid = mUidStats.valueAt(i); 10875 10876 long scanTimeSinceMarkMs = uid.mWifiScanTimer.getTimeSinceMarkLocked( 10877 elapsedRealtimeMs * 1000) / 1000; 10878 if (scanTimeSinceMarkMs > 0) { 10879 // Set the new mark so that next time we get new data since this point. 10880 uid.mWifiScanTimer.setMark(elapsedRealtimeMs); 10881 10882 long scanRxTimeSinceMarkMs = scanTimeSinceMarkMs; 10883 long scanTxTimeSinceMarkMs = scanTimeSinceMarkMs; 10884 10885 // Our total scan time is more than the reported Tx/Rx time. 10886 // This is possible because the cost of a scan is approximate. 10887 // Let's normalize the result so that we evenly blame each app 10888 // scanning. 10889 // 10890 // This means that we may have apps that transmitted/received packets not be 10891 // blamed for this, but this is fine as scans are relatively more expensive. 10892 if (totalScanTimeMs > rxTimeMs) { 10893 scanRxTimeSinceMarkMs = (rxTimeMs * scanRxTimeSinceMarkMs) / 10894 totalScanTimeMs; 10895 } 10896 if (totalScanTimeMs > txTimeMs) { 10897 scanTxTimeSinceMarkMs = (txTimeMs * scanTxTimeSinceMarkMs) / 10898 totalScanTimeMs; 10899 } 10900 10901 if (DEBUG_ENERGY) { 10902 Slog.d(TAG, " ScanTime for UID " + uid.getUid() + ": Rx:" 10903 + scanRxTimeSinceMarkMs + " ms Tx:" 10904 + scanTxTimeSinceMarkMs + " ms)"); 10905 } 10906 10907 ControllerActivityCounterImpl activityCounter = 10908 uid.getOrCreateWifiControllerActivityLocked(); 10909 activityCounter.getRxTimeCounter().addCountLocked(scanRxTimeSinceMarkMs); 10910 activityCounter.getTxTimeCounters()[0].addCountLocked( 10911 scanTxTimeSinceMarkMs); 10912 leftOverRxTimeMs -= scanRxTimeSinceMarkMs; 10913 leftOverTxTimeMs -= scanTxTimeSinceMarkMs; 10914 } 10915 10916 // Distribute evenly the power consumed while Idle to each app holding a WiFi 10917 // lock. 10918 final long wifiLockTimeSinceMarkMs = 10919 uid.mFullWifiLockTimer.getTimeSinceMarkLocked( 10920 elapsedRealtimeMs * 1000) / 1000; 10921 if (wifiLockTimeSinceMarkMs > 0) { 10922 // Set the new mark so that next time we get new data since this point. 10923 uid.mFullWifiLockTimer.setMark(elapsedRealtimeMs); 10924 10925 final long myIdleTimeMs = (wifiLockTimeSinceMarkMs * idleTimeMs) 10926 / totalWifiLockTimeMs; 10927 if (DEBUG_ENERGY) { 10928 Slog.d(TAG, " IdleTime for UID " + uid.getUid() + ": " 10929 + myIdleTimeMs + " ms"); 10930 } 10931 uid.getOrCreateWifiControllerActivityLocked().getIdleTimeCounter() 10932 .addCountLocked(myIdleTimeMs); 10933 } 10934 } 10935 10936 if (DEBUG_ENERGY) { 10937 Slog.d(TAG, " New RxPower: " + leftOverRxTimeMs + " ms"); 10938 Slog.d(TAG, " New TxPower: " + leftOverTxTimeMs + " ms"); 10939 } 10940 10941 // Distribute the remaining Tx power appropriately between all apps that transmitted 10942 // packets. 10943 for (int i = 0; i < txPackets.size(); i++) { 10944 final Uid uid = getUidStatsLocked(txPackets.keyAt(i)); 10945 final long myTxTimeMs = (txPackets.valueAt(i) * leftOverTxTimeMs) 10946 / totalTxPackets; 10947 if (DEBUG_ENERGY) { 10948 Slog.d(TAG, " TxTime for UID " + uid.getUid() + ": " + myTxTimeMs + " ms"); 10949 } 10950 uid.getOrCreateWifiControllerActivityLocked().getTxTimeCounters()[0] 10951 .addCountLocked(myTxTimeMs); 10952 } 10953 10954 // Distribute the remaining Rx power appropriately between all apps that received 10955 // packets. 10956 for (int i = 0; i < rxPackets.size(); i++) { 10957 final Uid uid = getUidStatsLocked(rxPackets.keyAt(i)); 10958 final long myRxTimeMs = (rxPackets.valueAt(i) * leftOverRxTimeMs) 10959 / totalRxPackets; 10960 if (DEBUG_ENERGY) { 10961 Slog.d(TAG, " RxTime for UID " + uid.getUid() + ": " + myRxTimeMs + " ms"); 10962 } 10963 uid.getOrCreateWifiControllerActivityLocked().getRxTimeCounter() 10964 .addCountLocked(myRxTimeMs); 10965 } 10966 10967 // Any left over power use will be picked up by the WiFi category in BatteryStatsHelper. 10968 10969 10970 // Update WiFi controller stats. 10971 mWifiActivity.getRxTimeCounter().addCountLocked( 10972 info.getControllerRxDurationMillis()); 10973 mWifiActivity.getTxTimeCounters()[0].addCountLocked( 10974 info.getControllerTxDurationMillis()); 10975 mWifiActivity.getScanTimeCounter().addCountLocked( 10976 info.getControllerScanDurationMillis()); 10977 mWifiActivity.getIdleTimeCounter().addCountLocked( 10978 info.getControllerIdleDurationMillis()); 10979 10980 // POWER_WIFI_CONTROLLER_OPERATING_VOLTAGE is measured in mV, so convert to V. 10981 final double opVolt = mPowerProfile.getAveragePower( 10982 PowerProfile.POWER_WIFI_CONTROLLER_OPERATING_VOLTAGE) / 1000.0; 10983 if (opVolt != 0) { 10984 // We store the power drain as mAms. 10985 mWifiActivity.getPowerCounter().addCountLocked( 10986 (long) (info.getControllerEnergyUsedMicroJoules() / opVolt)); 10987 } 10988 // Converting uWs to mAms. 10989 // Conversion: (uWs * (1000ms / 1s) * (1mW / 1000uW)) / mV = mAms 10990 long monitoredRailChargeConsumedMaMs = 10991 (long) (mTmpRailStats.getWifiTotalEnergyUseduWs() / opVolt); 10992 mWifiActivity.getMonitoredRailChargeConsumedMaMs().addCountLocked( 10993 monitoredRailChargeConsumedMaMs); 10994 mHistoryCur.wifiRailChargeMah += 10995 (monitoredRailChargeConsumedMaMs / MILLISECONDS_IN_HOUR); 10996 addHistoryRecordLocked(mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 10997 mTmpRailStats.resetWifiTotalEnergyUsed(); 10998 } 10999 } 11000 } 11001 11002 private ModemActivityInfo mLastModemActivityInfo = 11003 new ModemActivityInfo(0, 0, 0, new int[0], 0); 11004 getDeltaModemActivityInfo(ModemActivityInfo activityInfo)11005 private ModemActivityInfo getDeltaModemActivityInfo(ModemActivityInfo activityInfo) { 11006 if (activityInfo == null) { 11007 return null; 11008 } 11009 int[] txTimeMs = new int[ModemActivityInfo.TX_POWER_LEVELS]; 11010 for (int i = 0; i < ModemActivityInfo.TX_POWER_LEVELS; i++) { 11011 txTimeMs[i] = activityInfo.getTransmitPowerInfo().get(i).getTimeInMillis() 11012 - mLastModemActivityInfo.getTransmitPowerInfo().get(i).getTimeInMillis(); 11013 } 11014 ModemActivityInfo deltaInfo = new ModemActivityInfo(activityInfo.getTimestamp(), 11015 activityInfo.getSleepTimeMillis() - mLastModemActivityInfo.getSleepTimeMillis(), 11016 activityInfo.getIdleTimeMillis() - mLastModemActivityInfo.getIdleTimeMillis(), 11017 txTimeMs, 11018 activityInfo.getReceiveTimeMillis() - mLastModemActivityInfo.getReceiveTimeMillis()); 11019 mLastModemActivityInfo = activityInfo; 11020 return deltaInfo; 11021 } 11022 11023 /** 11024 * Distribute Cell radio energy info and network traffic to apps. 11025 */ updateMobileRadioState(@ullable final ModemActivityInfo activityInfo)11026 public void updateMobileRadioState(@Nullable final ModemActivityInfo activityInfo) { 11027 if (DEBUG_ENERGY) { 11028 Slog.d(TAG, "Updating mobile radio stats with " + activityInfo); 11029 } 11030 ModemActivityInfo deltaInfo = getDeltaModemActivityInfo(activityInfo); 11031 11032 // Add modem tx power to history. 11033 addModemTxPowerToHistory(deltaInfo); 11034 11035 // Grab a separate lock to acquire the network stats, which may do I/O. 11036 NetworkStats delta = null; 11037 synchronized (mModemNetworkLock) { 11038 final NetworkStats latestStats = readNetworkStatsLocked(mModemIfaces); 11039 if (latestStats != null) { 11040 delta = NetworkStats.subtract(latestStats, mLastModemNetworkStats, null, null, 11041 mNetworkStatsPool.acquire()); 11042 mNetworkStatsPool.release(mLastModemNetworkStats); 11043 mLastModemNetworkStats = latestStats; 11044 } 11045 } 11046 11047 synchronized (this) { 11048 if (!mOnBatteryInternal) { 11049 if (delta != null) { 11050 mNetworkStatsPool.release(delta); 11051 } 11052 return; 11053 } 11054 11055 if (deltaInfo != null) { 11056 mHasModemReporting = true; 11057 mModemActivity.getIdleTimeCounter().addCountLocked( 11058 deltaInfo.getIdleTimeMillis()); 11059 mModemActivity.getSleepTimeCounter().addCountLocked( 11060 deltaInfo.getSleepTimeMillis()); 11061 mModemActivity.getRxTimeCounter().addCountLocked(deltaInfo.getReceiveTimeMillis()); 11062 for (int lvl = 0; lvl < ModemActivityInfo.TX_POWER_LEVELS; lvl++) { 11063 mModemActivity.getTxTimeCounters()[lvl] 11064 .addCountLocked(deltaInfo.getTransmitPowerInfo() 11065 .get(lvl).getTimeInMillis()); 11066 } 11067 11068 // POWER_MODEM_CONTROLLER_OPERATING_VOLTAGE is measured in mV, so convert to V. 11069 final double opVolt = mPowerProfile.getAveragePower( 11070 PowerProfile.POWER_MODEM_CONTROLLER_OPERATING_VOLTAGE) / 1000.0; 11071 if (opVolt != 0) { 11072 double energyUsed = 11073 deltaInfo.getSleepTimeMillis() * 11074 mPowerProfile.getAveragePower(PowerProfile.POWER_MODEM_CONTROLLER_SLEEP) 11075 + deltaInfo.getIdleTimeMillis() * 11076 mPowerProfile.getAveragePower(PowerProfile.POWER_MODEM_CONTROLLER_IDLE) 11077 + deltaInfo.getReceiveTimeMillis() * 11078 mPowerProfile.getAveragePower(PowerProfile.POWER_MODEM_CONTROLLER_RX); 11079 List<TransmitPower> txPowerInfo = deltaInfo.getTransmitPowerInfo(); 11080 for (int i = 0; i < Math.min(txPowerInfo.size(), 11081 CellSignalStrength.getNumSignalStrengthLevels()); i++) { 11082 energyUsed += txPowerInfo.get(i).getTimeInMillis() * mPowerProfile 11083 .getAveragePower(PowerProfile.POWER_MODEM_CONTROLLER_TX, i); 11084 } 11085 11086 // We store the power drain as mAms. 11087 mModemActivity.getPowerCounter().addCountLocked((long) energyUsed); 11088 // Converting uWs to mAms. 11089 // Conversion: (uWs * (1000ms / 1s) * (1mW / 1000uW)) / mV = mAms 11090 long monitoredRailChargeConsumedMaMs = 11091 (long) (mTmpRailStats.getCellularTotalEnergyUseduWs() / opVolt); 11092 mModemActivity.getMonitoredRailChargeConsumedMaMs().addCountLocked( 11093 monitoredRailChargeConsumedMaMs); 11094 mHistoryCur.modemRailChargeMah += 11095 (monitoredRailChargeConsumedMaMs / MILLISECONDS_IN_HOUR); 11096 addHistoryRecordLocked(mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 11097 mTmpRailStats.resetCellularTotalEnergyUsed(); 11098 } 11099 } 11100 final long elapsedRealtimeMs = mClocks.elapsedRealtime(); 11101 long radioTime = mMobileRadioActivePerAppTimer.getTimeSinceMarkLocked( 11102 elapsedRealtimeMs * 1000); 11103 mMobileRadioActivePerAppTimer.setMark(elapsedRealtimeMs); 11104 11105 long totalRxPackets = 0; 11106 long totalTxPackets = 0; 11107 if (delta != null) { 11108 NetworkStats.Entry entry = new NetworkStats.Entry(); 11109 final int size = delta.size(); 11110 for (int i = 0; i < size; i++) { 11111 entry = delta.getValues(i, entry); 11112 if (entry.rxPackets == 0 && entry.txPackets == 0) { 11113 continue; 11114 } 11115 11116 if (DEBUG_ENERGY) { 11117 Slog.d(TAG, "Mobile uid " + entry.uid + ": delta rx=" + entry.rxBytes 11118 + " tx=" + entry.txBytes + " rxPackets=" + entry.rxPackets 11119 + " txPackets=" + entry.txPackets); 11120 } 11121 11122 totalRxPackets += entry.rxPackets; 11123 totalTxPackets += entry.txPackets; 11124 11125 final Uid u = getUidStatsLocked(mapUid(entry.uid)); 11126 u.noteNetworkActivityLocked(NETWORK_MOBILE_RX_DATA, entry.rxBytes, 11127 entry.rxPackets); 11128 u.noteNetworkActivityLocked(NETWORK_MOBILE_TX_DATA, entry.txBytes, 11129 entry.txPackets); 11130 if (entry.set == NetworkStats.SET_DEFAULT) { // Background transfers 11131 u.noteNetworkActivityLocked(NETWORK_MOBILE_BG_RX_DATA, 11132 entry.rxBytes, entry.rxPackets); 11133 u.noteNetworkActivityLocked(NETWORK_MOBILE_BG_TX_DATA, 11134 entry.txBytes, entry.txPackets); 11135 } 11136 11137 mNetworkByteActivityCounters[NETWORK_MOBILE_RX_DATA].addCountLocked( 11138 entry.rxBytes); 11139 mNetworkByteActivityCounters[NETWORK_MOBILE_TX_DATA].addCountLocked( 11140 entry.txBytes); 11141 mNetworkPacketActivityCounters[NETWORK_MOBILE_RX_DATA].addCountLocked( 11142 entry.rxPackets); 11143 mNetworkPacketActivityCounters[NETWORK_MOBILE_TX_DATA].addCountLocked( 11144 entry.txPackets); 11145 } 11146 11147 // Now distribute proportional blame to the apps that did networking. 11148 long totalPackets = totalRxPackets + totalTxPackets; 11149 if (totalPackets > 0) { 11150 for (int i = 0; i < size; i++) { 11151 entry = delta.getValues(i, entry); 11152 if (entry.rxPackets == 0 && entry.txPackets == 0) { 11153 continue; 11154 } 11155 11156 final Uid u = getUidStatsLocked(mapUid(entry.uid)); 11157 11158 // Distribute total radio active time in to this app. 11159 final long appPackets = entry.rxPackets + entry.txPackets; 11160 final long appRadioTime = (radioTime * appPackets) / totalPackets; 11161 u.noteMobileRadioActiveTimeLocked(appRadioTime); 11162 11163 // Remove this app from the totals, so that we don't lose any time 11164 // due to rounding. 11165 radioTime -= appRadioTime; 11166 totalPackets -= appPackets; 11167 11168 if (deltaInfo != null) { 11169 ControllerActivityCounterImpl activityCounter = 11170 u.getOrCreateModemControllerActivityLocked(); 11171 if (totalRxPackets > 0 && entry.rxPackets > 0) { 11172 final long rxMs = (entry.rxPackets 11173 * deltaInfo.getReceiveTimeMillis()) / totalRxPackets; 11174 activityCounter.getRxTimeCounter().addCountLocked(rxMs); 11175 } 11176 11177 if (totalTxPackets > 0 && entry.txPackets > 0) { 11178 for (int lvl = 0; lvl < ModemActivityInfo.TX_POWER_LEVELS; lvl++) { 11179 long txMs = 11180 entry.txPackets * deltaInfo.getTransmitPowerInfo() 11181 .get(lvl).getTimeInMillis(); 11182 txMs /= totalTxPackets; 11183 activityCounter.getTxTimeCounters()[lvl].addCountLocked(txMs); 11184 } 11185 } 11186 } 11187 } 11188 } 11189 11190 if (radioTime > 0) { 11191 // Whoops, there is some radio time we can't blame on an app! 11192 mMobileRadioActiveUnknownTime.addCountLocked(radioTime); 11193 mMobileRadioActiveUnknownCount.addCountLocked(1); 11194 } 11195 11196 mNetworkStatsPool.release(delta); 11197 delta = null; 11198 } 11199 } 11200 } 11201 11202 /** 11203 * Add modem tx power to history 11204 * Device is said to be in high cellular transmit power when it has spent most of the transmit 11205 * time at the highest power level. 11206 * @param activityInfo 11207 */ addModemTxPowerToHistory(final ModemActivityInfo activityInfo)11208 private synchronized void addModemTxPowerToHistory(final ModemActivityInfo activityInfo) { 11209 if (activityInfo == null) { 11210 return; 11211 } 11212 List<TransmitPower> txPowerInfo = activityInfo.getTransmitPowerInfo(); 11213 if (txPowerInfo == null || txPowerInfo.size() != ModemActivityInfo.TX_POWER_LEVELS) { 11214 return; 11215 } 11216 final long elapsedRealtime = mClocks.elapsedRealtime(); 11217 final long uptime = mClocks.uptimeMillis(); 11218 int levelMaxTimeSpent = 0; 11219 for (int i = 1; i < txPowerInfo.size(); i++) { 11220 if (txPowerInfo.get(i).getTimeInMillis() > txPowerInfo.get(levelMaxTimeSpent) 11221 .getTimeInMillis()) { 11222 levelMaxTimeSpent = i; 11223 } 11224 } 11225 if (levelMaxTimeSpent == ModemActivityInfo.TX_POWER_LEVELS - 1) { 11226 mHistoryCur.states2 |= HistoryItem.STATE2_CELLULAR_HIGH_TX_POWER_FLAG; 11227 addHistoryRecordLocked(elapsedRealtime, uptime); 11228 } 11229 } 11230 11231 private final class BluetoothActivityInfoCache { 11232 long idleTimeMs; 11233 long rxTimeMs; 11234 long txTimeMs; 11235 long energy; 11236 11237 SparseLongArray uidRxBytes = new SparseLongArray(); 11238 SparseLongArray uidTxBytes = new SparseLongArray(); 11239 set(BluetoothActivityEnergyInfo info)11240 void set(BluetoothActivityEnergyInfo info) { 11241 idleTimeMs = info.getControllerIdleTimeMillis(); 11242 rxTimeMs = info.getControllerRxTimeMillis(); 11243 txTimeMs = info.getControllerTxTimeMillis(); 11244 energy = info.getControllerEnergyUsed(); 11245 if (info.getUidTraffic() != null) { 11246 for (UidTraffic traffic : info.getUidTraffic()) { 11247 uidRxBytes.put(traffic.getUid(), traffic.getRxBytes()); 11248 uidTxBytes.put(traffic.getUid(), traffic.getTxBytes()); 11249 } 11250 } 11251 } 11252 } 11253 11254 private final BluetoothActivityInfoCache mLastBluetoothActivityInfo 11255 = new BluetoothActivityInfoCache(); 11256 11257 /** 11258 * Distribute Bluetooth energy info and network traffic to apps. 11259 * 11260 * @param info The energy information from the bluetooth controller. 11261 */ updateBluetoothStateLocked(@ullable final BluetoothActivityEnergyInfo info)11262 public void updateBluetoothStateLocked(@Nullable final BluetoothActivityEnergyInfo info) { 11263 if (DEBUG_ENERGY) { 11264 Slog.d(TAG, "Updating bluetooth stats: " + info); 11265 } 11266 11267 if (info == null || !mOnBatteryInternal) { 11268 return; 11269 } 11270 11271 mHasBluetoothReporting = true; 11272 11273 final long elapsedRealtimeMs = mClocks.elapsedRealtime(); 11274 final long rxTimeMs = 11275 info.getControllerRxTimeMillis() - mLastBluetoothActivityInfo.rxTimeMs; 11276 final long txTimeMs = 11277 info.getControllerTxTimeMillis() - mLastBluetoothActivityInfo.txTimeMs; 11278 final long idleTimeMs = 11279 info.getControllerIdleTimeMillis() - mLastBluetoothActivityInfo.idleTimeMs; 11280 11281 if (DEBUG_ENERGY) { 11282 Slog.d(TAG, "------ BEGIN BLE power blaming ------"); 11283 Slog.d(TAG, " Tx Time: " + txTimeMs + " ms"); 11284 Slog.d(TAG, " Rx Time: " + rxTimeMs + " ms"); 11285 Slog.d(TAG, " Idle Time: " + idleTimeMs + " ms"); 11286 } 11287 11288 long totalScanTimeMs = 0; 11289 11290 final int uidCount = mUidStats.size(); 11291 for (int i = 0; i < uidCount; i++) { 11292 final Uid u = mUidStats.valueAt(i); 11293 if (u.mBluetoothScanTimer == null) { 11294 continue; 11295 } 11296 11297 totalScanTimeMs += u.mBluetoothScanTimer.getTimeSinceMarkLocked( 11298 elapsedRealtimeMs * 1000) / 1000; 11299 } 11300 11301 final boolean normalizeScanRxTime = (totalScanTimeMs > rxTimeMs); 11302 final boolean normalizeScanTxTime = (totalScanTimeMs > txTimeMs); 11303 11304 if (DEBUG_ENERGY) { 11305 Slog.d(TAG, "Normalizing scan power for RX=" + normalizeScanRxTime 11306 + " TX=" + normalizeScanTxTime); 11307 } 11308 11309 long leftOverRxTimeMs = rxTimeMs; 11310 long leftOverTxTimeMs = txTimeMs; 11311 11312 for (int i = 0; i < uidCount; i++) { 11313 final Uid u = mUidStats.valueAt(i); 11314 if (u.mBluetoothScanTimer == null) { 11315 continue; 11316 } 11317 11318 long scanTimeSinceMarkMs = u.mBluetoothScanTimer.getTimeSinceMarkLocked( 11319 elapsedRealtimeMs * 1000) / 1000; 11320 if (scanTimeSinceMarkMs > 0) { 11321 // Set the new mark so that next time we get new data since this point. 11322 u.mBluetoothScanTimer.setMark(elapsedRealtimeMs); 11323 11324 long scanTimeRxSinceMarkMs = scanTimeSinceMarkMs; 11325 long scanTimeTxSinceMarkMs = scanTimeSinceMarkMs; 11326 11327 if (normalizeScanRxTime) { 11328 // Scan time is longer than the total rx time in the controller, 11329 // so distribute the scan time proportionately. This means regular traffic 11330 // will not blamed, but scans are more expensive anyways. 11331 scanTimeRxSinceMarkMs = (rxTimeMs * scanTimeRxSinceMarkMs) / totalScanTimeMs; 11332 } 11333 11334 if (normalizeScanTxTime) { 11335 // Scan time is longer than the total tx time in the controller, 11336 // so distribute the scan time proportionately. This means regular traffic 11337 // will not blamed, but scans are more expensive anyways. 11338 scanTimeTxSinceMarkMs = (txTimeMs * scanTimeTxSinceMarkMs) / totalScanTimeMs; 11339 } 11340 11341 final ControllerActivityCounterImpl counter = 11342 u.getOrCreateBluetoothControllerActivityLocked(); 11343 counter.getRxTimeCounter().addCountLocked(scanTimeRxSinceMarkMs); 11344 counter.getTxTimeCounters()[0].addCountLocked(scanTimeTxSinceMarkMs); 11345 11346 leftOverRxTimeMs -= scanTimeRxSinceMarkMs; 11347 leftOverTxTimeMs -= scanTimeTxSinceMarkMs; 11348 } 11349 } 11350 11351 if (DEBUG_ENERGY) { 11352 Slog.d(TAG, "Left over time for traffic RX=" + leftOverRxTimeMs + " TX=" 11353 + leftOverTxTimeMs); 11354 } 11355 11356 // 11357 // Now distribute blame to apps that did bluetooth traffic. 11358 // 11359 11360 long totalTxBytes = 0; 11361 long totalRxBytes = 0; 11362 11363 final UidTraffic[] uidTraffic = info.getUidTraffic(); 11364 final int numUids = uidTraffic != null ? uidTraffic.length : 0; 11365 for (int i = 0; i < numUids; i++) { 11366 final UidTraffic traffic = uidTraffic[i]; 11367 final long rxBytes = traffic.getRxBytes() - mLastBluetoothActivityInfo.uidRxBytes.get( 11368 traffic.getUid()); 11369 final long txBytes = traffic.getTxBytes() - mLastBluetoothActivityInfo.uidTxBytes.get( 11370 traffic.getUid()); 11371 11372 // Add to the global counters. 11373 mNetworkByteActivityCounters[NETWORK_BT_RX_DATA].addCountLocked(rxBytes); 11374 mNetworkByteActivityCounters[NETWORK_BT_TX_DATA].addCountLocked(txBytes); 11375 11376 // Add to the UID counters. 11377 final Uid u = getUidStatsLocked(mapUid(traffic.getUid())); 11378 u.noteNetworkActivityLocked(NETWORK_BT_RX_DATA, rxBytes, 0); 11379 u.noteNetworkActivityLocked(NETWORK_BT_TX_DATA, txBytes, 0); 11380 11381 // Calculate the total traffic. 11382 totalRxBytes += rxBytes; 11383 totalTxBytes += txBytes; 11384 } 11385 11386 if ((totalTxBytes != 0 || totalRxBytes != 0) && (leftOverRxTimeMs != 0 11387 || leftOverTxTimeMs != 0)) { 11388 for (int i = 0; i < numUids; i++) { 11389 final UidTraffic traffic = uidTraffic[i]; 11390 final int uid = traffic.getUid(); 11391 final long rxBytes = 11392 traffic.getRxBytes() - mLastBluetoothActivityInfo.uidRxBytes.get(uid); 11393 final long txBytes = 11394 traffic.getTxBytes() - mLastBluetoothActivityInfo.uidTxBytes.get(uid); 11395 11396 final Uid u = getUidStatsLocked(mapUid(uid)); 11397 final ControllerActivityCounterImpl counter = 11398 u.getOrCreateBluetoothControllerActivityLocked(); 11399 11400 if (totalRxBytes > 0 && rxBytes > 0) { 11401 final long timeRxMs = (leftOverRxTimeMs * rxBytes) / totalRxBytes; 11402 if (DEBUG_ENERGY) { 11403 Slog.d(TAG, "UID=" + uid + " rx_bytes=" + rxBytes + " rx_time=" + timeRxMs); 11404 } 11405 counter.getRxTimeCounter().addCountLocked(timeRxMs); 11406 } 11407 11408 if (totalTxBytes > 0 && txBytes > 0) { 11409 final long timeTxMs = (leftOverTxTimeMs * txBytes) / totalTxBytes; 11410 if (DEBUG_ENERGY) { 11411 Slog.d(TAG, "UID=" + uid + " tx_bytes=" + txBytes + " tx_time=" + timeTxMs); 11412 } 11413 counter.getTxTimeCounters()[0].addCountLocked(timeTxMs); 11414 } 11415 } 11416 } 11417 11418 mBluetoothActivity.getRxTimeCounter().addCountLocked(rxTimeMs); 11419 mBluetoothActivity.getTxTimeCounters()[0].addCountLocked(txTimeMs); 11420 mBluetoothActivity.getIdleTimeCounter().addCountLocked(idleTimeMs); 11421 11422 // POWER_BLUETOOTH_CONTROLLER_OPERATING_VOLTAGE is measured in mV, so convert to V. 11423 final double opVolt = mPowerProfile.getAveragePower( 11424 PowerProfile.POWER_BLUETOOTH_CONTROLLER_OPERATING_VOLTAGE) / 1000.0; 11425 if (opVolt != 0) { 11426 // We store the power drain as mAms. 11427 mBluetoothActivity.getPowerCounter().addCountLocked( 11428 (long) ((info.getControllerEnergyUsed() - mLastBluetoothActivityInfo.energy) 11429 / opVolt)); 11430 } 11431 mLastBluetoothActivityInfo.set(info); 11432 } 11433 11434 /** 11435 * Read and record Resource Power Manager (RPM) state and voter times. 11436 * If RPM stats were fetched more recently than RPM_STATS_UPDATE_FREQ_MS ago, uses the old data 11437 * instead of fetching it anew. 11438 */ updateRpmStatsLocked()11439 public void updateRpmStatsLocked() { 11440 if (mPlatformIdleStateCallback == null) return; 11441 long now = SystemClock.elapsedRealtime(); 11442 if (now - mLastRpmStatsUpdateTimeMs >= RPM_STATS_UPDATE_FREQ_MS) { 11443 mPlatformIdleStateCallback.fillLowPowerStats(mTmpRpmStats); 11444 mLastRpmStatsUpdateTimeMs = now; 11445 } 11446 11447 for (Map.Entry<String, RpmStats.PowerStatePlatformSleepState> pstate 11448 : mTmpRpmStats.mPlatformLowPowerStats.entrySet()) { 11449 11450 // Update values for this platform state. 11451 final String pName = pstate.getKey(); 11452 final long pTimeUs = pstate.getValue().mTimeMs * 1000; 11453 final int pCount = pstate.getValue().mCount; 11454 getRpmTimerLocked(pName).update(pTimeUs, pCount); 11455 if (SCREEN_OFF_RPM_STATS_ENABLED) { 11456 getScreenOffRpmTimerLocked(pName).update(pTimeUs, pCount); 11457 } 11458 11459 // Update values for each voter of this platform state. 11460 for (Map.Entry<String, RpmStats.PowerStateElement> voter 11461 : pstate.getValue().mVoters.entrySet()) { 11462 final String vName = pName + "." + voter.getKey(); 11463 final long vTimeUs = voter.getValue().mTimeMs * 1000; 11464 final int vCount = voter.getValue().mCount; 11465 getRpmTimerLocked(vName).update(vTimeUs, vCount); 11466 if (SCREEN_OFF_RPM_STATS_ENABLED) { 11467 getScreenOffRpmTimerLocked(vName).update(vTimeUs, vCount); 11468 } 11469 } 11470 } 11471 11472 for (Map.Entry<String, RpmStats.PowerStateSubsystem> subsys 11473 : mTmpRpmStats.mSubsystemLowPowerStats.entrySet()) { 11474 11475 final String subsysName = subsys.getKey(); 11476 for (Map.Entry<String, RpmStats.PowerStateElement> sstate 11477 : subsys.getValue().mStates.entrySet()) { 11478 final String name = subsysName + "." + sstate.getKey(); 11479 final long timeUs = sstate.getValue().mTimeMs * 1000; 11480 final int count = sstate.getValue().mCount; 11481 getRpmTimerLocked(name).update(timeUs, count); 11482 if (SCREEN_OFF_RPM_STATS_ENABLED) { 11483 getScreenOffRpmTimerLocked(name).update(timeUs, count); 11484 } 11485 } 11486 } 11487 } 11488 11489 /** 11490 * Read and record Rail Energy data. 11491 */ updateRailStatsLocked()11492 public void updateRailStatsLocked() { 11493 if (mRailEnergyDataCallback == null || !mTmpRailStats.isRailStatsAvailable()) { 11494 return; 11495 } 11496 mRailEnergyDataCallback.fillRailDataStats(mTmpRailStats); 11497 } 11498 11499 /** 11500 * Read and distribute kernel wake lock use across apps. 11501 */ updateKernelWakelocksLocked()11502 public void updateKernelWakelocksLocked() { 11503 final KernelWakelockStats wakelockStats = mKernelWakelockReader.readKernelWakelockStats( 11504 mTmpWakelockStats); 11505 if (wakelockStats == null) { 11506 // Not crashing might make board bringup easier. 11507 Slog.w(TAG, "Couldn't get kernel wake lock stats"); 11508 return; 11509 } 11510 11511 for (Map.Entry<String, KernelWakelockStats.Entry> ent : wakelockStats.entrySet()) { 11512 String name = ent.getKey(); 11513 KernelWakelockStats.Entry kws = ent.getValue(); 11514 11515 SamplingTimer kwlt = mKernelWakelockStats.get(name); 11516 if (kwlt == null) { 11517 kwlt = new SamplingTimer(mClocks, mOnBatteryScreenOffTimeBase); 11518 mKernelWakelockStats.put(name, kwlt); 11519 } 11520 11521 kwlt.update(kws.mTotalTime, kws.mCount); 11522 kwlt.setUpdateVersion(kws.mVersion); 11523 } 11524 11525 int numWakelocksSetStale = 0; 11526 // Set timers to stale if they didn't appear in /d/wakeup_sources (or /proc/wakelocks) 11527 // this time. 11528 for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) { 11529 SamplingTimer st = ent.getValue(); 11530 if (st.getUpdateVersion() != wakelockStats.kernelWakelockVersion) { 11531 st.endSample(); 11532 numWakelocksSetStale++; 11533 } 11534 } 11535 11536 // Record whether we've seen a non-zero time (for debugging b/22716723). 11537 if (wakelockStats.isEmpty()) { 11538 Slog.wtf(TAG, "All kernel wakelocks had time of zero"); 11539 } 11540 11541 if (numWakelocksSetStale == mKernelWakelockStats.size()) { 11542 Slog.wtf(TAG, "All kernel wakelocks were set stale. new version=" + 11543 wakelockStats.kernelWakelockVersion); 11544 } 11545 } 11546 11547 // We use an anonymous class to access these variables, 11548 // so they can't live on the stack or they'd have to be 11549 // final MutableLong objects (more allocations). 11550 // Used in updateCpuTimeLocked(). 11551 long mTempTotalCpuUserTimeUs; 11552 long mTempTotalCpuSystemTimeUs; 11553 long[][] mWakeLockAllocationsUs; 11554 11555 /** 11556 * Reads the newest memory stats from the kernel. 11557 */ updateKernelMemoryBandwidthLocked()11558 public void updateKernelMemoryBandwidthLocked() { 11559 mKernelMemoryBandwidthStats.updateStats(); 11560 LongSparseLongArray bandwidthEntries = mKernelMemoryBandwidthStats.getBandwidthEntries(); 11561 final int bandwidthEntryCount = bandwidthEntries.size(); 11562 int index; 11563 for (int i = 0; i < bandwidthEntryCount; i++) { 11564 SamplingTimer timer; 11565 if ((index = mKernelMemoryStats.indexOfKey(bandwidthEntries.keyAt(i))) >= 0) { 11566 timer = mKernelMemoryStats.valueAt(index); 11567 } else { 11568 timer = new SamplingTimer(mClocks, mOnBatteryTimeBase); 11569 mKernelMemoryStats.put(bandwidthEntries.keyAt(i), timer); 11570 } 11571 timer.update(bandwidthEntries.valueAt(i), 1); 11572 if (DEBUG_MEMORY) { 11573 Slog.d(TAG, String.format("Added entry %d and updated timer to: " 11574 + "mUnpluggedReportedTotalTime %d size %d", bandwidthEntries.keyAt(i), 11575 mKernelMemoryStats.get( 11576 bandwidthEntries.keyAt(i)).mUnpluggedReportedTotalTime, 11577 mKernelMemoryStats.size())); 11578 } 11579 } 11580 } 11581 isOnBatteryLocked()11582 public boolean isOnBatteryLocked() { 11583 return mOnBatteryTimeBase.isRunning(); 11584 } 11585 isOnBatteryScreenOffLocked()11586 public boolean isOnBatteryScreenOffLocked() { 11587 return mOnBatteryScreenOffTimeBase.isRunning(); 11588 } 11589 11590 /** 11591 * Read and distribute CPU usage across apps. If their are partial wakelocks being held 11592 * and we are on battery with screen off, we give more of the cpu time to those apps holding 11593 * wakelocks. If the screen is on, we just assign the actual cpu time an app used. 11594 * It's possible this will be invoked after the internal battery/screen states are updated, so 11595 * passing the appropriate battery/screen states to try attribute the cpu times to correct 11596 * buckets. 11597 */ 11598 @GuardedBy("this") updateCpuTimeLocked(boolean onBattery, boolean onBatteryScreenOff)11599 public void updateCpuTimeLocked(boolean onBattery, boolean onBatteryScreenOff) { 11600 if (mPowerProfile == null) { 11601 return; 11602 } 11603 11604 if (DEBUG_ENERGY_CPU) { 11605 Slog.d(TAG, "!Cpu updating!"); 11606 } 11607 11608 if (mCpuFreqs == null) { 11609 mCpuFreqs = mCpuUidFreqTimeReader.readFreqs(mPowerProfile); 11610 } 11611 11612 // Calculate the wakelocks we have to distribute amongst. The system is excluded as it is 11613 // usually holding the wakelock on behalf of an app. 11614 // And Only distribute cpu power to wakelocks if the screen is off and we're on battery. 11615 ArrayList<StopwatchTimer> partialTimersToConsider = null; 11616 if (onBatteryScreenOff) { 11617 partialTimersToConsider = new ArrayList<>(); 11618 for (int i = mPartialTimers.size() - 1; i >= 0; --i) { 11619 final StopwatchTimer timer = mPartialTimers.get(i); 11620 // Since the collection and blaming of wakelocks can be scheduled to run after 11621 // some delay, the mPartialTimers list may have new entries. We can't blame 11622 // the newly added timer for past cpu time, so we only consider timers that 11623 // were present for one round of collection. Once a timer has gone through 11624 // a round of collection, its mInList field is set to true. 11625 if (timer.mInList && timer.mUid != null && timer.mUid.mUid != Process.SYSTEM_UID) { 11626 partialTimersToConsider.add(timer); 11627 } 11628 } 11629 } 11630 markPartialTimersAsEligible(); 11631 11632 // When the battery is not on, we don't attribute the cpu times to any timers but we still 11633 // need to take the snapshots. 11634 if (!onBattery) { 11635 mCpuUidUserSysTimeReader.readDelta(null); 11636 mCpuUidFreqTimeReader.readDelta(null); 11637 mNumAllUidCpuTimeReads += 2; 11638 if (mConstants.TRACK_CPU_ACTIVE_CLUSTER_TIME) { 11639 mCpuUidActiveTimeReader.readDelta(null); 11640 mCpuUidClusterTimeReader.readDelta(null); 11641 mNumAllUidCpuTimeReads += 2; 11642 } 11643 for (int cluster = mKernelCpuSpeedReaders.length - 1; cluster >= 0; --cluster) { 11644 mKernelCpuSpeedReaders[cluster].readDelta(); 11645 } 11646 return; 11647 } 11648 11649 mUserInfoProvider.refreshUserIds(); 11650 final SparseLongArray updatedUids = mCpuUidFreqTimeReader.perClusterTimesAvailable() 11651 ? null : new SparseLongArray(); 11652 readKernelUidCpuTimesLocked(partialTimersToConsider, updatedUids, onBattery); 11653 // updatedUids=null means /proc/uid_time_in_state provides snapshots of per-cluster cpu 11654 // freqs, so no need to approximate these values. 11655 if (updatedUids != null) { 11656 updateClusterSpeedTimes(updatedUids, onBattery); 11657 } 11658 readKernelUidCpuFreqTimesLocked(partialTimersToConsider, onBattery, onBatteryScreenOff); 11659 mNumAllUidCpuTimeReads += 2; 11660 if (mConstants.TRACK_CPU_ACTIVE_CLUSTER_TIME) { 11661 readKernelUidCpuActiveTimesLocked(onBattery); 11662 readKernelUidCpuClusterTimesLocked(onBattery); 11663 mNumAllUidCpuTimeReads += 2; 11664 } 11665 } 11666 11667 /** 11668 * Mark the current partial timers as gone through a collection so that they will be 11669 * considered in the next cpu times distribution to wakelock holders. 11670 */ 11671 @VisibleForTesting markPartialTimersAsEligible()11672 public void markPartialTimersAsEligible() { 11673 if (ArrayUtils.referenceEquals(mPartialTimers, mLastPartialTimers)) { 11674 // No difference, so each timer is now considered for the next collection. 11675 for (int i = mPartialTimers.size() - 1; i >= 0; --i) { 11676 mPartialTimers.get(i).mInList = true; 11677 } 11678 } else { 11679 // The lists are different, meaning we added (or removed a timer) since the last 11680 // collection. 11681 for (int i = mLastPartialTimers.size() - 1; i >= 0; --i) { 11682 mLastPartialTimers.get(i).mInList = false; 11683 } 11684 mLastPartialTimers.clear(); 11685 11686 // Mark the current timers as gone through a collection. 11687 final int numPartialTimers = mPartialTimers.size(); 11688 for (int i = 0; i < numPartialTimers; ++i) { 11689 final StopwatchTimer timer = mPartialTimers.get(i); 11690 timer.mInList = true; 11691 mLastPartialTimers.add(timer); 11692 } 11693 } 11694 } 11695 11696 /** 11697 * Take snapshot of cpu times (aggregated over all uids) at different frequencies and 11698 * calculate cpu times spent by each uid at different frequencies. 11699 * 11700 * @param updatedUids The uids for which times spent at different frequencies are calculated. 11701 */ 11702 @VisibleForTesting updateClusterSpeedTimes(@onNull SparseLongArray updatedUids, boolean onBattery)11703 public void updateClusterSpeedTimes(@NonNull SparseLongArray updatedUids, boolean onBattery) { 11704 long totalCpuClustersTimeMs = 0; 11705 // Read the time spent for each cluster at various cpu frequencies. 11706 final long[][] clusterSpeedTimesMs = new long[mKernelCpuSpeedReaders.length][]; 11707 for (int cluster = 0; cluster < mKernelCpuSpeedReaders.length; cluster++) { 11708 clusterSpeedTimesMs[cluster] = mKernelCpuSpeedReaders[cluster].readDelta(); 11709 if (clusterSpeedTimesMs[cluster] != null) { 11710 for (int speed = clusterSpeedTimesMs[cluster].length - 1; speed >= 0; --speed) { 11711 totalCpuClustersTimeMs += clusterSpeedTimesMs[cluster][speed]; 11712 } 11713 } 11714 } 11715 if (totalCpuClustersTimeMs != 0) { 11716 // We have cpu times per freq aggregated over all uids but we need the times per uid. 11717 // So, we distribute total time spent by an uid to different cpu freqs based on the 11718 // amount of time cpu was running at that freq. 11719 final int updatedUidsCount = updatedUids.size(); 11720 for (int i = 0; i < updatedUidsCount; ++i) { 11721 final Uid u = getUidStatsLocked(updatedUids.keyAt(i)); 11722 final long appCpuTimeUs = updatedUids.valueAt(i); 11723 // Add the cpu speeds to this UID. 11724 final int numClusters = mPowerProfile.getNumCpuClusters(); 11725 if (u.mCpuClusterSpeedTimesUs == null || 11726 u.mCpuClusterSpeedTimesUs.length != numClusters) { 11727 u.mCpuClusterSpeedTimesUs = new LongSamplingCounter[numClusters][]; 11728 } 11729 11730 for (int cluster = 0; cluster < clusterSpeedTimesMs.length; cluster++) { 11731 final int speedsInCluster = clusterSpeedTimesMs[cluster].length; 11732 if (u.mCpuClusterSpeedTimesUs[cluster] == null || speedsInCluster != 11733 u.mCpuClusterSpeedTimesUs[cluster].length) { 11734 u.mCpuClusterSpeedTimesUs[cluster] 11735 = new LongSamplingCounter[speedsInCluster]; 11736 } 11737 11738 final LongSamplingCounter[] cpuSpeeds = u.mCpuClusterSpeedTimesUs[cluster]; 11739 for (int speed = 0; speed < speedsInCluster; speed++) { 11740 if (cpuSpeeds[speed] == null) { 11741 cpuSpeeds[speed] = new LongSamplingCounter(mOnBatteryTimeBase); 11742 } 11743 cpuSpeeds[speed].addCountLocked(appCpuTimeUs 11744 * clusterSpeedTimesMs[cluster][speed] 11745 / totalCpuClustersTimeMs, onBattery); 11746 } 11747 } 11748 } 11749 } 11750 } 11751 11752 /** 11753 * Take a snapshot of the cpu times spent by each uid and update the corresponding counters. 11754 * If {@param partialTimers} is not null and empty, then we assign a portion of cpu times to 11755 * wakelock holders. 11756 * 11757 * @param partialTimers The wakelock holders among which the cpu times will be distributed. 11758 * @param updatedUids If not null, then the uids found in the snapshot will be added to this. 11759 */ 11760 @VisibleForTesting readKernelUidCpuTimesLocked(@ullable ArrayList<StopwatchTimer> partialTimers, @Nullable SparseLongArray updatedUids, boolean onBattery)11761 public void readKernelUidCpuTimesLocked(@Nullable ArrayList<StopwatchTimer> partialTimers, 11762 @Nullable SparseLongArray updatedUids, boolean onBattery) { 11763 mTempTotalCpuUserTimeUs = mTempTotalCpuSystemTimeUs = 0; 11764 final int numWakelocks = partialTimers == null ? 0 : partialTimers.size(); 11765 final long startTimeMs = mClocks.uptimeMillis(); 11766 11767 mCpuUidUserSysTimeReader.readDelta((uid, timesUs) -> { 11768 long userTimeUs = timesUs[0], systemTimeUs = timesUs[1]; 11769 11770 uid = mapUid(uid); 11771 if (Process.isIsolated(uid)) { 11772 // This could happen if the isolated uid mapping was removed before that process 11773 // was actually killed. 11774 mCpuUidUserSysTimeReader.removeUid(uid); 11775 Slog.d(TAG, "Got readings for an isolated uid with no mapping: " + uid); 11776 return; 11777 } 11778 if (!mUserInfoProvider.exists(UserHandle.getUserId(uid))) { 11779 Slog.d(TAG, "Got readings for an invalid user's uid " + uid); 11780 mCpuUidUserSysTimeReader.removeUid(uid); 11781 return; 11782 } 11783 final Uid u = getUidStatsLocked(uid); 11784 11785 // Accumulate the total system and user time. 11786 mTempTotalCpuUserTimeUs += userTimeUs; 11787 mTempTotalCpuSystemTimeUs += systemTimeUs; 11788 11789 StringBuilder sb = null; 11790 if (DEBUG_ENERGY_CPU) { 11791 sb = new StringBuilder(); 11792 sb.append(" got time for uid=").append(u.mUid).append(": u="); 11793 TimeUtils.formatDuration(userTimeUs / 1000, sb); 11794 sb.append(" s="); 11795 TimeUtils.formatDuration(systemTimeUs / 1000, sb); 11796 sb.append("\n"); 11797 } 11798 11799 if (numWakelocks > 0) { 11800 // We have wakelocks being held, so only give a portion of the 11801 // time to the process. The rest will be distributed among wakelock 11802 // holders. 11803 userTimeUs = (userTimeUs * WAKE_LOCK_WEIGHT) / 100; 11804 systemTimeUs = (systemTimeUs * WAKE_LOCK_WEIGHT) / 100; 11805 } 11806 11807 if (sb != null) { 11808 sb.append(" adding to uid=").append(u.mUid).append(": u="); 11809 TimeUtils.formatDuration(userTimeUs / 1000, sb); 11810 sb.append(" s="); 11811 TimeUtils.formatDuration(systemTimeUs / 1000, sb); 11812 Slog.d(TAG, sb.toString()); 11813 } 11814 11815 u.mUserCpuTime.addCountLocked(userTimeUs, onBattery); 11816 u.mSystemCpuTime.addCountLocked(systemTimeUs, onBattery); 11817 if (updatedUids != null) { 11818 updatedUids.put(u.getUid(), userTimeUs + systemTimeUs); 11819 } 11820 }); 11821 11822 final long elapsedTimeMs = mClocks.uptimeMillis() - startTimeMs; 11823 if (DEBUG_ENERGY_CPU || elapsedTimeMs >= 100) { 11824 Slog.d(TAG, "Reading cpu stats took " + elapsedTimeMs + "ms"); 11825 } 11826 11827 if (numWakelocks > 0) { 11828 // Distribute a portion of the total cpu time to wakelock holders. 11829 mTempTotalCpuUserTimeUs = (mTempTotalCpuUserTimeUs * (100 - WAKE_LOCK_WEIGHT)) / 100; 11830 mTempTotalCpuSystemTimeUs = 11831 (mTempTotalCpuSystemTimeUs * (100 - WAKE_LOCK_WEIGHT)) / 100; 11832 11833 for (int i = 0; i < numWakelocks; ++i) { 11834 final StopwatchTimer timer = partialTimers.get(i); 11835 final int userTimeUs = (int) (mTempTotalCpuUserTimeUs / (numWakelocks - i)); 11836 final int systemTimeUs = (int) (mTempTotalCpuSystemTimeUs / (numWakelocks - i)); 11837 11838 if (DEBUG_ENERGY_CPU) { 11839 final StringBuilder sb = new StringBuilder(); 11840 sb.append(" Distributing wakelock uid=").append(timer.mUid.mUid) 11841 .append(": u="); 11842 TimeUtils.formatDuration(userTimeUs / 1000, sb); 11843 sb.append(" s="); 11844 TimeUtils.formatDuration(systemTimeUs / 1000, sb); 11845 Slog.d(TAG, sb.toString()); 11846 } 11847 11848 timer.mUid.mUserCpuTime.addCountLocked(userTimeUs, onBattery); 11849 timer.mUid.mSystemCpuTime.addCountLocked(systemTimeUs, onBattery); 11850 if (updatedUids != null) { 11851 final int uid = timer.mUid.getUid(); 11852 updatedUids.put(uid, updatedUids.get(uid, 0) + userTimeUs + systemTimeUs); 11853 } 11854 11855 final Uid.Proc proc = timer.mUid.getProcessStatsLocked("*wakelock*"); 11856 proc.addCpuTimeLocked(userTimeUs / 1000, systemTimeUs / 1000, onBattery); 11857 11858 mTempTotalCpuUserTimeUs -= userTimeUs; 11859 mTempTotalCpuSystemTimeUs -= systemTimeUs; 11860 } 11861 } 11862 } 11863 11864 /** 11865 * Take a snapshot of the cpu times spent by each uid in each freq and update the 11866 * corresponding counters. 11867 * 11868 * @param partialTimers The wakelock holders among which the cpu freq times will be distributed. 11869 */ 11870 @VisibleForTesting readKernelUidCpuFreqTimesLocked(@ullable ArrayList<StopwatchTimer> partialTimers, boolean onBattery, boolean onBatteryScreenOff)11871 public void readKernelUidCpuFreqTimesLocked(@Nullable ArrayList<StopwatchTimer> partialTimers, 11872 boolean onBattery, boolean onBatteryScreenOff) { 11873 final boolean perClusterTimesAvailable = 11874 mCpuUidFreqTimeReader.perClusterTimesAvailable(); 11875 final int numWakelocks = partialTimers == null ? 0 : partialTimers.size(); 11876 final int numClusters = mPowerProfile.getNumCpuClusters(); 11877 mWakeLockAllocationsUs = null; 11878 final long startTimeMs = mClocks.uptimeMillis(); 11879 mCpuUidFreqTimeReader.readDelta((uid, cpuFreqTimeMs) -> { 11880 uid = mapUid(uid); 11881 if (Process.isIsolated(uid)) { 11882 mCpuUidFreqTimeReader.removeUid(uid); 11883 Slog.d(TAG, "Got freq readings for an isolated uid with no mapping: " + uid); 11884 return; 11885 } 11886 if (!mUserInfoProvider.exists(UserHandle.getUserId(uid))) { 11887 Slog.d(TAG, "Got freq readings for an invalid user's uid " + uid); 11888 mCpuUidFreqTimeReader.removeUid(uid); 11889 return; 11890 } 11891 final Uid u = getUidStatsLocked(uid); 11892 if (u.mCpuFreqTimeMs == null || u.mCpuFreqTimeMs.getSize() != cpuFreqTimeMs.length) { 11893 detachIfNotNull(u.mCpuFreqTimeMs); 11894 u.mCpuFreqTimeMs = new LongSamplingCounterArray(mOnBatteryTimeBase); 11895 } 11896 u.mCpuFreqTimeMs.addCountLocked(cpuFreqTimeMs, onBattery); 11897 if (u.mScreenOffCpuFreqTimeMs == null || 11898 u.mScreenOffCpuFreqTimeMs.getSize() != cpuFreqTimeMs.length) { 11899 detachIfNotNull(u.mScreenOffCpuFreqTimeMs); 11900 u.mScreenOffCpuFreqTimeMs = new LongSamplingCounterArray( 11901 mOnBatteryScreenOffTimeBase); 11902 } 11903 u.mScreenOffCpuFreqTimeMs.addCountLocked(cpuFreqTimeMs, onBatteryScreenOff); 11904 11905 if (perClusterTimesAvailable) { 11906 if (u.mCpuClusterSpeedTimesUs == null || 11907 u.mCpuClusterSpeedTimesUs.length != numClusters) { 11908 detachIfNotNull(u.mCpuClusterSpeedTimesUs); 11909 u.mCpuClusterSpeedTimesUs = new LongSamplingCounter[numClusters][]; 11910 } 11911 if (numWakelocks > 0 && mWakeLockAllocationsUs == null) { 11912 mWakeLockAllocationsUs = new long[numClusters][]; 11913 } 11914 11915 int freqIndex = 0; 11916 for (int cluster = 0; cluster < numClusters; ++cluster) { 11917 final int speedsInCluster = mPowerProfile.getNumSpeedStepsInCpuCluster(cluster); 11918 if (u.mCpuClusterSpeedTimesUs[cluster] == null || 11919 u.mCpuClusterSpeedTimesUs[cluster].length != speedsInCluster) { 11920 detachIfNotNull(u.mCpuClusterSpeedTimesUs[cluster]); 11921 u.mCpuClusterSpeedTimesUs[cluster] 11922 = new LongSamplingCounter[speedsInCluster]; 11923 } 11924 if (numWakelocks > 0 && mWakeLockAllocationsUs[cluster] == null) { 11925 mWakeLockAllocationsUs[cluster] = new long[speedsInCluster]; 11926 } 11927 final LongSamplingCounter[] cpuTimesUs = u.mCpuClusterSpeedTimesUs[cluster]; 11928 for (int speed = 0; speed < speedsInCluster; ++speed) { 11929 if (cpuTimesUs[speed] == null) { 11930 cpuTimesUs[speed] = new LongSamplingCounter(mOnBatteryTimeBase); 11931 } 11932 final long appAllocationUs; 11933 if (mWakeLockAllocationsUs != null) { 11934 appAllocationUs = 11935 (cpuFreqTimeMs[freqIndex] * 1000 * WAKE_LOCK_WEIGHT) / 100; 11936 mWakeLockAllocationsUs[cluster][speed] += 11937 (cpuFreqTimeMs[freqIndex] * 1000 - appAllocationUs); 11938 } else { 11939 appAllocationUs = cpuFreqTimeMs[freqIndex] * 1000; 11940 } 11941 cpuTimesUs[speed].addCountLocked(appAllocationUs, onBattery); 11942 freqIndex++; 11943 } 11944 } 11945 } 11946 }); 11947 11948 final long elapsedTimeMs = mClocks.uptimeMillis() - startTimeMs; 11949 if (DEBUG_ENERGY_CPU || elapsedTimeMs >= 100) { 11950 Slog.d(TAG, "Reading cpu freq times took " + elapsedTimeMs + "ms"); 11951 } 11952 11953 if (mWakeLockAllocationsUs != null) { 11954 for (int i = 0; i < numWakelocks; ++i) { 11955 final Uid u = partialTimers.get(i).mUid; 11956 if (u.mCpuClusterSpeedTimesUs == null || 11957 u.mCpuClusterSpeedTimesUs.length != numClusters) { 11958 detachIfNotNull(u.mCpuClusterSpeedTimesUs); 11959 u.mCpuClusterSpeedTimesUs = new LongSamplingCounter[numClusters][]; 11960 } 11961 11962 for (int cluster = 0; cluster < numClusters; ++cluster) { 11963 final int speedsInCluster = mPowerProfile.getNumSpeedStepsInCpuCluster(cluster); 11964 if (u.mCpuClusterSpeedTimesUs[cluster] == null || 11965 u.mCpuClusterSpeedTimesUs[cluster].length != speedsInCluster) { 11966 detachIfNotNull(u.mCpuClusterSpeedTimesUs[cluster]); 11967 u.mCpuClusterSpeedTimesUs[cluster] 11968 = new LongSamplingCounter[speedsInCluster]; 11969 } 11970 final LongSamplingCounter[] cpuTimeUs = u.mCpuClusterSpeedTimesUs[cluster]; 11971 for (int speed = 0; speed < speedsInCluster; ++speed) { 11972 if (cpuTimeUs[speed] == null) { 11973 cpuTimeUs[speed] = new LongSamplingCounter(mOnBatteryTimeBase); 11974 } 11975 final long allocationUs = 11976 mWakeLockAllocationsUs[cluster][speed] / (numWakelocks - i); 11977 cpuTimeUs[speed].addCountLocked(allocationUs, onBattery); 11978 mWakeLockAllocationsUs[cluster][speed] -= allocationUs; 11979 } 11980 } 11981 } 11982 } 11983 } 11984 11985 /** 11986 * Take a snapshot of the cpu active times spent by each uid and update the corresponding 11987 * counters. 11988 */ 11989 @VisibleForTesting readKernelUidCpuActiveTimesLocked(boolean onBattery)11990 public void readKernelUidCpuActiveTimesLocked(boolean onBattery) { 11991 final long startTimeMs = mClocks.uptimeMillis(); 11992 mCpuUidActiveTimeReader.readDelta((uid, cpuActiveTimesMs) -> { 11993 uid = mapUid(uid); 11994 if (Process.isIsolated(uid)) { 11995 mCpuUidActiveTimeReader.removeUid(uid); 11996 Slog.w(TAG, "Got active times for an isolated uid with no mapping: " + uid); 11997 return; 11998 } 11999 if (!mUserInfoProvider.exists(UserHandle.getUserId(uid))) { 12000 Slog.w(TAG, "Got active times for an invalid user's uid " + uid); 12001 mCpuUidActiveTimeReader.removeUid(uid); 12002 return; 12003 } 12004 final Uid u = getUidStatsLocked(uid); 12005 u.mCpuActiveTimeMs.addCountLocked(cpuActiveTimesMs, onBattery); 12006 }); 12007 12008 final long elapsedTimeMs = mClocks.uptimeMillis() - startTimeMs; 12009 if (DEBUG_ENERGY_CPU || elapsedTimeMs >= 100) { 12010 Slog.d(TAG, "Reading cpu active times took " + elapsedTimeMs + "ms"); 12011 } 12012 } 12013 12014 /** 12015 * Take a snapshot of the cpu cluster times spent by each uid and update the corresponding 12016 * counters. 12017 */ 12018 @VisibleForTesting readKernelUidCpuClusterTimesLocked(boolean onBattery)12019 public void readKernelUidCpuClusterTimesLocked(boolean onBattery) { 12020 final long startTimeMs = mClocks.uptimeMillis(); 12021 mCpuUidClusterTimeReader.readDelta((uid, cpuClusterTimesMs) -> { 12022 uid = mapUid(uid); 12023 if (Process.isIsolated(uid)) { 12024 mCpuUidClusterTimeReader.removeUid(uid); 12025 Slog.w(TAG, "Got cluster times for an isolated uid with no mapping: " + uid); 12026 return; 12027 } 12028 if (!mUserInfoProvider.exists(UserHandle.getUserId(uid))) { 12029 Slog.w(TAG, "Got cluster times for an invalid user's uid " + uid); 12030 mCpuUidClusterTimeReader.removeUid(uid); 12031 return; 12032 } 12033 final Uid u = getUidStatsLocked(uid); 12034 u.mCpuClusterTimesMs.addCountLocked(cpuClusterTimesMs, onBattery); 12035 }); 12036 12037 final long elapsedTimeMs = mClocks.uptimeMillis() - startTimeMs; 12038 if (DEBUG_ENERGY_CPU || elapsedTimeMs >= 100) { 12039 Slog.d(TAG, "Reading cpu cluster times took " + elapsedTimeMs + "ms"); 12040 } 12041 } 12042 setChargingLocked(boolean charging)12043 boolean setChargingLocked(boolean charging) { 12044 // if the device is no longer charging, remove the callback 12045 // if the device is now charging, it means that this is either called 12046 // 1. directly when level >= 90 12047 // 2. or from within the runnable that we deferred 12048 // For 1. if we have an existing callback, remove it, since we will immediately send a 12049 // ACTION_CHARGING 12050 // For 2. we remove existing callback so we don't send multiple ACTION_CHARGING 12051 mHandler.removeCallbacks(mDeferSetCharging); 12052 if (mCharging != charging) { 12053 mCharging = charging; 12054 if (charging) { 12055 mHistoryCur.states2 |= HistoryItem.STATE2_CHARGING_FLAG; 12056 } else { 12057 mHistoryCur.states2 &= ~HistoryItem.STATE2_CHARGING_FLAG; 12058 } 12059 mHandler.sendEmptyMessage(MSG_REPORT_CHARGING); 12060 return true; 12061 } 12062 return false; 12063 } 12064 12065 @GuardedBy("this") setOnBatteryLocked(final long mSecRealtime, final long mSecUptime, final boolean onBattery, final int oldStatus, final int level, final int chargeUAh)12066 protected void setOnBatteryLocked(final long mSecRealtime, final long mSecUptime, 12067 final boolean onBattery, final int oldStatus, final int level, final int chargeUAh) { 12068 boolean doWrite = false; 12069 Message m = mHandler.obtainMessage(MSG_REPORT_POWER_CHANGE); 12070 m.arg1 = onBattery ? 1 : 0; 12071 mHandler.sendMessage(m); 12072 12073 final long uptime = mSecUptime * 1000; 12074 final long realtime = mSecRealtime * 1000; 12075 final int screenState = mScreenState; 12076 if (onBattery) { 12077 // We will reset our status if we are unplugging after the 12078 // battery was last full, or the level is at 100, or 12079 // we have gone through a significant charge (from a very low 12080 // level to a now very high level). 12081 boolean reset = false; 12082 if (!mNoAutoReset && (oldStatus == BatteryManager.BATTERY_STATUS_FULL 12083 || level >= 90 12084 || (mDischargeCurrentLevel < 20 && level >= 80))) { 12085 Slog.i(TAG, "Resetting battery stats: level=" + level + " status=" + oldStatus 12086 + " dischargeLevel=" + mDischargeCurrentLevel 12087 + " lowAmount=" + getLowDischargeAmountSinceCharge() 12088 + " highAmount=" + getHighDischargeAmountSinceCharge()); 12089 // Before we write, collect a snapshot of the final aggregated 12090 // stats to be reported in the next checkin. Only do this if we have 12091 // a sufficient amount of data to make it interesting. 12092 if (getLowDischargeAmountSinceCharge() >= 20) { 12093 final long startTime = SystemClock.uptimeMillis(); 12094 final Parcel parcel = Parcel.obtain(); 12095 writeSummaryToParcel(parcel, true); 12096 final long initialTime = SystemClock.uptimeMillis() - startTime; 12097 BackgroundThread.getHandler().post(new Runnable() { 12098 @Override public void run() { 12099 synchronized (mCheckinFile) { 12100 final long startTime2 = SystemClock.uptimeMillis(); 12101 FileOutputStream stream = null; 12102 try { 12103 stream = mCheckinFile.startWrite(); 12104 stream.write(parcel.marshall()); 12105 stream.flush(); 12106 mCheckinFile.finishWrite(stream); 12107 com.android.internal.logging.EventLogTags.writeCommitSysConfigFile( 12108 "batterystats-checkin", 12109 initialTime + SystemClock.uptimeMillis() - startTime2); 12110 } catch (IOException e) { 12111 Slog.w("BatteryStats", 12112 "Error writing checkin battery statistics", e); 12113 mCheckinFile.failWrite(stream); 12114 } finally { 12115 parcel.recycle(); 12116 } 12117 } 12118 } 12119 }); 12120 } 12121 doWrite = true; 12122 resetAllStatsLocked(); 12123 if (chargeUAh > 0 && level > 0) { 12124 // Only use the reported coulomb charge value if it is supported and reported. 12125 mEstimatedBatteryCapacity = (int) ((chargeUAh / 1000) / (level / 100.0)); 12126 } 12127 mDischargeStartLevel = level; 12128 reset = true; 12129 mDischargeStepTracker.init(); 12130 } 12131 if (mCharging) { 12132 setChargingLocked(false); 12133 } 12134 mLastChargingStateLevel = level; 12135 mOnBattery = mOnBatteryInternal = true; 12136 mLastDischargeStepLevel = level; 12137 mMinDischargeStepLevel = level; 12138 mDischargeStepTracker.clearTime(); 12139 mDailyDischargeStepTracker.clearTime(); 12140 mInitStepMode = mCurStepMode; 12141 mModStepMode = 0; 12142 pullPendingStateUpdatesLocked(); 12143 mHistoryCur.batteryLevel = (byte)level; 12144 mHistoryCur.states &= ~HistoryItem.STATE_BATTERY_PLUGGED_FLAG; 12145 if (DEBUG_HISTORY) Slog.v(TAG, "Battery unplugged to: " 12146 + Integer.toHexString(mHistoryCur.states)); 12147 if (reset) { 12148 mRecordingHistory = true; 12149 startRecordingHistory(mSecRealtime, mSecUptime, reset); 12150 } 12151 addHistoryRecordLocked(mSecRealtime, mSecUptime); 12152 mDischargeCurrentLevel = mDischargeUnplugLevel = level; 12153 if (isScreenOn(screenState)) { 12154 mDischargeScreenOnUnplugLevel = level; 12155 mDischargeScreenDozeUnplugLevel = 0; 12156 mDischargeScreenOffUnplugLevel = 0; 12157 } else if (isScreenDoze(screenState)) { 12158 mDischargeScreenOnUnplugLevel = 0; 12159 mDischargeScreenDozeUnplugLevel = level; 12160 mDischargeScreenOffUnplugLevel = 0; 12161 } else { 12162 mDischargeScreenOnUnplugLevel = 0; 12163 mDischargeScreenDozeUnplugLevel = 0; 12164 mDischargeScreenOffUnplugLevel = level; 12165 } 12166 mDischargeAmountScreenOn = 0; 12167 mDischargeAmountScreenDoze = 0; 12168 mDischargeAmountScreenOff = 0; 12169 updateTimeBasesLocked(true, screenState, uptime, realtime); 12170 } else { 12171 mLastChargingStateLevel = level; 12172 mOnBattery = mOnBatteryInternal = false; 12173 pullPendingStateUpdatesLocked(); 12174 mHistoryCur.batteryLevel = (byte)level; 12175 mHistoryCur.states |= HistoryItem.STATE_BATTERY_PLUGGED_FLAG; 12176 if (DEBUG_HISTORY) Slog.v(TAG, "Battery plugged to: " 12177 + Integer.toHexString(mHistoryCur.states)); 12178 addHistoryRecordLocked(mSecRealtime, mSecUptime); 12179 mDischargeCurrentLevel = mDischargePlugLevel = level; 12180 if (level < mDischargeUnplugLevel) { 12181 mLowDischargeAmountSinceCharge += mDischargeUnplugLevel-level-1; 12182 mHighDischargeAmountSinceCharge += mDischargeUnplugLevel-level; 12183 } 12184 updateDischargeScreenLevelsLocked(screenState, screenState); 12185 updateTimeBasesLocked(false, screenState, uptime, realtime); 12186 mChargeStepTracker.init(); 12187 mLastChargeStepLevel = level; 12188 mMaxChargeStepLevel = level; 12189 mInitStepMode = mCurStepMode; 12190 mModStepMode = 0; 12191 } 12192 if (doWrite || (mLastWriteTime + (60 * 1000)) < mSecRealtime) { 12193 if (mStatsFile != null && mBatteryStatsHistory.getActiveFile() != null) { 12194 writeAsyncLocked(); 12195 } 12196 } 12197 } 12198 startRecordingHistory(final long elapsedRealtimeMs, final long uptimeMs, boolean reset)12199 private void startRecordingHistory(final long elapsedRealtimeMs, final long uptimeMs, 12200 boolean reset) { 12201 mRecordingHistory = true; 12202 mHistoryCur.currentTime = System.currentTimeMillis(); 12203 addHistoryBufferLocked(elapsedRealtimeMs, 12204 reset ? HistoryItem.CMD_RESET : HistoryItem.CMD_CURRENT_TIME, 12205 mHistoryCur); 12206 mHistoryCur.currentTime = 0; 12207 if (reset) { 12208 initActiveHistoryEventsLocked(elapsedRealtimeMs, uptimeMs); 12209 } 12210 } 12211 recordCurrentTimeChangeLocked(final long currentTime, final long elapsedRealtimeMs, final long uptimeMs)12212 private void recordCurrentTimeChangeLocked(final long currentTime, final long elapsedRealtimeMs, 12213 final long uptimeMs) { 12214 if (mRecordingHistory) { 12215 mHistoryCur.currentTime = currentTime; 12216 addHistoryBufferLocked(elapsedRealtimeMs, HistoryItem.CMD_CURRENT_TIME, mHistoryCur); 12217 mHistoryCur.currentTime = 0; 12218 } 12219 } 12220 recordShutdownLocked(final long elapsedRealtimeMs, final long uptimeMs)12221 private void recordShutdownLocked(final long elapsedRealtimeMs, final long uptimeMs) { 12222 if (mRecordingHistory) { 12223 mHistoryCur.currentTime = System.currentTimeMillis(); 12224 addHistoryBufferLocked(elapsedRealtimeMs, HistoryItem.CMD_SHUTDOWN, mHistoryCur); 12225 mHistoryCur.currentTime = 0; 12226 } 12227 } 12228 scheduleSyncExternalStatsLocked(String reason, int updateFlags)12229 private void scheduleSyncExternalStatsLocked(String reason, int updateFlags) { 12230 if (mExternalSync != null) { 12231 mExternalSync.scheduleSync(reason, updateFlags); 12232 } 12233 } 12234 12235 // This should probably be exposed in the API, though it's not critical 12236 public static final int BATTERY_PLUGGED_NONE = OsProtoEnums.BATTERY_PLUGGED_NONE; // = 0 12237 12238 @GuardedBy("this") setBatteryStateLocked(final int status, final int health, final int plugType, final int level, int temp, final int volt, final int chargeUAh, final int chargeFullUAh, final long chargeTimeToFullSeconds)12239 public void setBatteryStateLocked(final int status, final int health, final int plugType, 12240 final int level, /* not final */ int temp, final int volt, final int chargeUAh, 12241 final int chargeFullUAh, final long chargeTimeToFullSeconds) { 12242 // Temperature is encoded without the signed bit, so clamp any negative temperatures to 0. 12243 temp = Math.max(0, temp); 12244 12245 reportChangesToStatsLog(mHaveBatteryLevel ? mHistoryCur : null, 12246 status, plugType, level); 12247 12248 final boolean onBattery = isOnBattery(plugType, status); 12249 final long uptime = mClocks.uptimeMillis(); 12250 final long elapsedRealtime = mClocks.elapsedRealtime(); 12251 if (!mHaveBatteryLevel) { 12252 mHaveBatteryLevel = true; 12253 // We start out assuming that the device is plugged in (not 12254 // on battery). If our first report is now that we are indeed 12255 // plugged in, then twiddle our state to correctly reflect that 12256 // since we won't be going through the full setOnBattery(). 12257 if (onBattery == mOnBattery) { 12258 if (onBattery) { 12259 mHistoryCur.states &= ~HistoryItem.STATE_BATTERY_PLUGGED_FLAG; 12260 } else { 12261 mHistoryCur.states |= HistoryItem.STATE_BATTERY_PLUGGED_FLAG; 12262 } 12263 } 12264 // Always start out assuming charging, that will be updated later. 12265 mHistoryCur.states2 |= HistoryItem.STATE2_CHARGING_FLAG; 12266 mHistoryCur.batteryStatus = (byte)status; 12267 mHistoryCur.batteryLevel = (byte)level; 12268 mHistoryCur.batteryChargeUAh = chargeUAh; 12269 mMaxChargeStepLevel = mMinDischargeStepLevel = 12270 mLastChargeStepLevel = mLastDischargeStepLevel = level; 12271 mLastChargingStateLevel = level; 12272 } else if (mCurrentBatteryLevel != level || mOnBattery != onBattery) { 12273 recordDailyStatsIfNeededLocked(level >= 100 && onBattery); 12274 } 12275 int oldStatus = mHistoryCur.batteryStatus; 12276 if (onBattery) { 12277 mDischargeCurrentLevel = level; 12278 if (!mRecordingHistory) { 12279 mRecordingHistory = true; 12280 startRecordingHistory(elapsedRealtime, uptime, true); 12281 } 12282 } else if (level < 96 && 12283 status != BatteryManager.BATTERY_STATUS_UNKNOWN) { 12284 if (!mRecordingHistory) { 12285 mRecordingHistory = true; 12286 startRecordingHistory(elapsedRealtime, uptime, true); 12287 } 12288 } 12289 mCurrentBatteryLevel = level; 12290 if (mDischargePlugLevel < 0) { 12291 mDischargePlugLevel = level; 12292 } 12293 12294 if (onBattery != mOnBattery) { 12295 mHistoryCur.batteryLevel = (byte)level; 12296 mHistoryCur.batteryStatus = (byte)status; 12297 mHistoryCur.batteryHealth = (byte)health; 12298 mHistoryCur.batteryPlugType = (byte)plugType; 12299 mHistoryCur.batteryTemperature = (short)temp; 12300 mHistoryCur.batteryVoltage = (char)volt; 12301 if (chargeUAh < mHistoryCur.batteryChargeUAh) { 12302 // Only record discharges 12303 final long chargeDiff = mHistoryCur.batteryChargeUAh - chargeUAh; 12304 mDischargeCounter.addCountLocked(chargeDiff); 12305 mDischargeScreenOffCounter.addCountLocked(chargeDiff); 12306 if (isScreenDoze(mScreenState)) { 12307 mDischargeScreenDozeCounter.addCountLocked(chargeDiff); 12308 } 12309 if (mDeviceIdleMode == DEVICE_IDLE_MODE_LIGHT) { 12310 mDischargeLightDozeCounter.addCountLocked(chargeDiff); 12311 } else if (mDeviceIdleMode == DEVICE_IDLE_MODE_DEEP) { 12312 mDischargeDeepDozeCounter.addCountLocked(chargeDiff); 12313 } 12314 } 12315 mHistoryCur.batteryChargeUAh = chargeUAh; 12316 setOnBatteryLocked(elapsedRealtime, uptime, onBattery, oldStatus, level, chargeUAh); 12317 } else { 12318 boolean changed = false; 12319 if (mHistoryCur.batteryLevel != level) { 12320 mHistoryCur.batteryLevel = (byte)level; 12321 changed = true; 12322 12323 // TODO(adamlesinski): Schedule the creation of a HistoryStepDetails record 12324 // which will pull external stats. 12325 mExternalSync.scheduleSyncDueToBatteryLevelChange( 12326 mConstants.BATTERY_LEVEL_COLLECTION_DELAY_MS); 12327 } 12328 if (mHistoryCur.batteryStatus != status) { 12329 mHistoryCur.batteryStatus = (byte)status; 12330 changed = true; 12331 } 12332 if (mHistoryCur.batteryHealth != health) { 12333 mHistoryCur.batteryHealth = (byte)health; 12334 changed = true; 12335 } 12336 if (mHistoryCur.batteryPlugType != plugType) { 12337 mHistoryCur.batteryPlugType = (byte)plugType; 12338 changed = true; 12339 } 12340 if (temp >= (mHistoryCur.batteryTemperature+10) 12341 || temp <= (mHistoryCur.batteryTemperature-10)) { 12342 mHistoryCur.batteryTemperature = (short)temp; 12343 changed = true; 12344 } 12345 if (volt > (mHistoryCur.batteryVoltage+20) 12346 || volt < (mHistoryCur.batteryVoltage-20)) { 12347 mHistoryCur.batteryVoltage = (char)volt; 12348 changed = true; 12349 } 12350 if (chargeUAh >= (mHistoryCur.batteryChargeUAh+10) 12351 || chargeUAh <= (mHistoryCur.batteryChargeUAh-10)) { 12352 if (chargeUAh < mHistoryCur.batteryChargeUAh) { 12353 // Only record discharges 12354 final long chargeDiff = mHistoryCur.batteryChargeUAh - chargeUAh; 12355 mDischargeCounter.addCountLocked(chargeDiff); 12356 mDischargeScreenOffCounter.addCountLocked(chargeDiff); 12357 if (isScreenDoze(mScreenState)) { 12358 mDischargeScreenDozeCounter.addCountLocked(chargeDiff); 12359 } 12360 if (mDeviceIdleMode == DEVICE_IDLE_MODE_LIGHT) { 12361 mDischargeLightDozeCounter.addCountLocked(chargeDiff); 12362 } else if (mDeviceIdleMode == DEVICE_IDLE_MODE_DEEP) { 12363 mDischargeDeepDozeCounter.addCountLocked(chargeDiff); 12364 } 12365 } 12366 mHistoryCur.batteryChargeUAh = chargeUAh; 12367 changed = true; 12368 } 12369 long modeBits = (((long)mInitStepMode) << STEP_LEVEL_INITIAL_MODE_SHIFT) 12370 | (((long)mModStepMode) << STEP_LEVEL_MODIFIED_MODE_SHIFT) 12371 | (((long)(level&0xff)) << STEP_LEVEL_LEVEL_SHIFT); 12372 if (onBattery) { 12373 changed |= setChargingLocked(false); 12374 if (mLastDischargeStepLevel != level && mMinDischargeStepLevel > level) { 12375 mDischargeStepTracker.addLevelSteps(mLastDischargeStepLevel - level, 12376 modeBits, elapsedRealtime); 12377 mDailyDischargeStepTracker.addLevelSteps(mLastDischargeStepLevel - level, 12378 modeBits, elapsedRealtime); 12379 mLastDischargeStepLevel = level; 12380 mMinDischargeStepLevel = level; 12381 mInitStepMode = mCurStepMode; 12382 mModStepMode = 0; 12383 } 12384 } else { 12385 if (level >= 90) { 12386 // If the battery level is at least 90%, always consider the device to be 12387 // charging even if it happens to go down a level. 12388 changed |= setChargingLocked(true); 12389 } else if (!mCharging) { 12390 if (mLastChargeStepLevel < level) { 12391 // We have not reported that we are charging, but the level has gone up, 12392 // but we would like to not have tons of activity from charging-constraint 12393 // jobs, so instead of reporting ACTION_CHARGING immediately, we defer it. 12394 if (!mHandler.hasCallbacks(mDeferSetCharging)) { 12395 mHandler.postDelayed( 12396 mDeferSetCharging, 12397 mConstants.BATTERY_CHARGED_DELAY_MS); 12398 } 12399 } else if (mLastChargeStepLevel > level) { 12400 // if we had deferred a runnable due to charge level increasing, but then 12401 // later the charge level drops (could be due to thermal issues), we don't 12402 // want to trigger the deferred runnable, so remove it here 12403 mHandler.removeCallbacks(mDeferSetCharging); 12404 } 12405 } else { 12406 if (mLastChargeStepLevel > level) { 12407 // We had reported that the device was charging, but here we are with 12408 // power connected and the level going down. Looks like the current 12409 // power supplied isn't enough, so consider the device to now be 12410 // discharging. 12411 changed |= setChargingLocked(false); 12412 } 12413 } 12414 if (mLastChargeStepLevel != level && mMaxChargeStepLevel < level) { 12415 mChargeStepTracker.addLevelSteps(level - mLastChargeStepLevel, 12416 modeBits, elapsedRealtime); 12417 mDailyChargeStepTracker.addLevelSteps(level - mLastChargeStepLevel, 12418 modeBits, elapsedRealtime); 12419 mMaxChargeStepLevel = level; 12420 mInitStepMode = mCurStepMode; 12421 mModStepMode = 0; 12422 } 12423 mLastChargeStepLevel = level; 12424 } 12425 if (changed) { 12426 addHistoryRecordLocked(elapsedRealtime, uptime); 12427 } 12428 } 12429 if (!onBattery && 12430 (status == BatteryManager.BATTERY_STATUS_FULL || 12431 status == BatteryManager.BATTERY_STATUS_UNKNOWN)) { 12432 // We don't record history while we are plugged in and fully charged 12433 // (or when battery is not present). The next time we are 12434 // unplugged, history will be cleared. 12435 mRecordingHistory = DEBUG; 12436 } 12437 12438 if (mMinLearnedBatteryCapacity == -1) { 12439 mMinLearnedBatteryCapacity = chargeFullUAh; 12440 } else { 12441 mMinLearnedBatteryCapacity = Math.min(mMinLearnedBatteryCapacity, chargeFullUAh); 12442 } 12443 mMaxLearnedBatteryCapacity = Math.max(mMaxLearnedBatteryCapacity, chargeFullUAh); 12444 12445 mBatteryTimeToFullSeconds = chargeTimeToFullSeconds; 12446 } 12447 isOnBattery(int plugType, int status)12448 public static boolean isOnBattery(int plugType, int status) { 12449 return plugType == BATTERY_PLUGGED_NONE && status != BatteryManager.BATTERY_STATUS_UNKNOWN; 12450 } 12451 12452 // Inform StatsLog of setBatteryState changes. 12453 // If this is the first reporting, pass in recentPast == null. reportChangesToStatsLog(HistoryItem recentPast, final int status, final int plugType, final int level)12454 private void reportChangesToStatsLog(HistoryItem recentPast, 12455 final int status, final int plugType, final int level) { 12456 12457 if (recentPast == null || recentPast.batteryStatus != status) { 12458 FrameworkStatsLog.write(FrameworkStatsLog.CHARGING_STATE_CHANGED, status); 12459 } 12460 if (recentPast == null || recentPast.batteryPlugType != plugType) { 12461 FrameworkStatsLog.write(FrameworkStatsLog.PLUGGED_STATE_CHANGED, plugType); 12462 } 12463 if (recentPast == null || recentPast.batteryLevel != level) { 12464 FrameworkStatsLog.write(FrameworkStatsLog.BATTERY_LEVEL_CHANGED, level); 12465 } 12466 } 12467 12468 @UnsupportedAppUsage getAwakeTimeBattery()12469 public long getAwakeTimeBattery() { 12470 // This previously evaluated to mOnBatteryTimeBase.getUptime(getBatteryUptimeLocked()); 12471 // for over a decade, but surely that was a mistake. 12472 return getBatteryUptimeLocked(); 12473 } 12474 12475 @UnsupportedAppUsage getAwakeTimePlugged()12476 public long getAwakeTimePlugged() { 12477 return (mClocks.uptimeMillis() * 1000) - getAwakeTimeBattery(); 12478 } 12479 12480 @Override computeUptime(long curTime, int which)12481 public long computeUptime(long curTime, int which) { 12482 return mUptime + (curTime - mUptimeStart); 12483 } 12484 12485 @Override computeRealtime(long curTime, int which)12486 public long computeRealtime(long curTime, int which) { 12487 return mRealtime + (curTime - mRealtimeStart); 12488 } 12489 12490 @Override 12491 @UnsupportedAppUsage computeBatteryUptime(long curTime, int which)12492 public long computeBatteryUptime(long curTime, int which) { 12493 return mOnBatteryTimeBase.computeUptime(curTime, which); 12494 } 12495 12496 @Override 12497 @UnsupportedAppUsage computeBatteryRealtime(long curTime, int which)12498 public long computeBatteryRealtime(long curTime, int which) { 12499 return mOnBatteryTimeBase.computeRealtime(curTime, which); 12500 } 12501 12502 @Override computeBatteryScreenOffUptime(long curTime, int which)12503 public long computeBatteryScreenOffUptime(long curTime, int which) { 12504 return mOnBatteryScreenOffTimeBase.computeUptime(curTime, which); 12505 } 12506 12507 @Override computeBatteryScreenOffRealtime(long curTime, int which)12508 public long computeBatteryScreenOffRealtime(long curTime, int which) { 12509 return mOnBatteryScreenOffTimeBase.computeRealtime(curTime, which); 12510 } 12511 computeTimePerLevel(long[] steps, int numSteps)12512 private long computeTimePerLevel(long[] steps, int numSteps) { 12513 // For now we'll do a simple average across all steps. 12514 if (numSteps <= 0) { 12515 return -1; 12516 } 12517 long total = 0; 12518 for (int i=0; i<numSteps; i++) { 12519 total += steps[i] & STEP_LEVEL_TIME_MASK; 12520 } 12521 return total / numSteps; 12522 /* 12523 long[] buckets = new long[numSteps]; 12524 int numBuckets = 0; 12525 int numToAverage = 4; 12526 int i = 0; 12527 while (i < numSteps) { 12528 long totalTime = 0; 12529 int num = 0; 12530 for (int j=0; j<numToAverage && (i+j)<numSteps; j++) { 12531 totalTime += steps[i+j] & STEP_LEVEL_TIME_MASK; 12532 num++; 12533 } 12534 buckets[numBuckets] = totalTime / num; 12535 numBuckets++; 12536 numToAverage *= 2; 12537 i += num; 12538 } 12539 if (numBuckets < 1) { 12540 return -1; 12541 } 12542 long averageTime = buckets[numBuckets-1]; 12543 for (i=numBuckets-2; i>=0; i--) { 12544 averageTime = (averageTime + buckets[i]) / 2; 12545 } 12546 return averageTime; 12547 */ 12548 } 12549 12550 @Override 12551 @UnsupportedAppUsage computeBatteryTimeRemaining(long curTime)12552 public long computeBatteryTimeRemaining(long curTime) { 12553 if (!mOnBattery) { 12554 return -1; 12555 } 12556 /* Simple implementation just looks at the average discharge per level across the 12557 entire sample period. 12558 int discharge = (getLowDischargeAmountSinceCharge()+getHighDischargeAmountSinceCharge())/2; 12559 if (discharge < 2) { 12560 return -1; 12561 } 12562 long duration = computeBatteryRealtime(curTime, STATS_SINCE_CHARGED); 12563 if (duration < 1000*1000) { 12564 return -1; 12565 } 12566 long usPerLevel = duration/discharge; 12567 return usPerLevel * mCurrentBatteryLevel; 12568 */ 12569 if (mDischargeStepTracker.mNumStepDurations < 1) { 12570 return -1; 12571 } 12572 long msPerLevel = mDischargeStepTracker.computeTimePerLevel(); 12573 if (msPerLevel <= 0) { 12574 return -1; 12575 } 12576 return (msPerLevel * mCurrentBatteryLevel) * 1000; 12577 } 12578 12579 @Override getDischargeLevelStepTracker()12580 public LevelStepTracker getDischargeLevelStepTracker() { 12581 return mDischargeStepTracker; 12582 } 12583 12584 @Override getDailyDischargeLevelStepTracker()12585 public LevelStepTracker getDailyDischargeLevelStepTracker() { 12586 return mDailyDischargeStepTracker; 12587 } 12588 12589 @Override computeChargeTimeRemaining(long curTime)12590 public long computeChargeTimeRemaining(long curTime) { 12591 if (mOnBattery) { 12592 // Not yet working. 12593 return -1; 12594 } 12595 if (mBatteryTimeToFullSeconds >= 0) { 12596 return mBatteryTimeToFullSeconds * (1000 * 1000); // s to us 12597 } 12598 // Else use algorithmic approach 12599 if (mChargeStepTracker.mNumStepDurations < 1) { 12600 return -1; 12601 } 12602 long msPerLevel = mChargeStepTracker.computeTimePerLevel(); 12603 if (msPerLevel <= 0) { 12604 return -1; 12605 } 12606 return (msPerLevel * (100 - mCurrentBatteryLevel)) * 1000; 12607 } 12608 12609 /*@hide */ getCellularBatteryStats()12610 public CellularBatteryStats getCellularBatteryStats() { 12611 final int which = STATS_SINCE_CHARGED; 12612 final long rawRealTime = SystemClock.elapsedRealtime() * 1000; 12613 final ControllerActivityCounter counter = getModemControllerActivity(); 12614 final long sleepTimeMs = counter.getSleepTimeCounter().getCountLocked(which); 12615 final long idleTimeMs = counter.getIdleTimeCounter().getCountLocked(which); 12616 final long rxTimeMs = counter.getRxTimeCounter().getCountLocked(which); 12617 final long energyConsumedMaMs = counter.getPowerCounter().getCountLocked(which); 12618 final long monitoredRailChargeConsumedMaMs = 12619 counter.getMonitoredRailChargeConsumedMaMs().getCountLocked(which); 12620 long[] timeInRatMs = new long[BatteryStats.NUM_DATA_CONNECTION_TYPES]; 12621 for (int i = 0; i < timeInRatMs.length; i++) { 12622 timeInRatMs[i] = getPhoneDataConnectionTime(i, rawRealTime, which) / 1000; 12623 } 12624 long[] timeInRxSignalStrengthLevelMs = 12625 new long[CellSignalStrength.getNumSignalStrengthLevels()]; 12626 for (int i = 0; i < timeInRxSignalStrengthLevelMs.length; i++) { 12627 timeInRxSignalStrengthLevelMs[i] 12628 = getPhoneSignalStrengthTime(i, rawRealTime, which) / 1000; 12629 } 12630 long[] txTimeMs = new long[Math.min(ModemActivityInfo.TX_POWER_LEVELS, 12631 counter.getTxTimeCounters().length)]; 12632 long totalTxTimeMs = 0; 12633 for (int i = 0; i < txTimeMs.length; i++) { 12634 txTimeMs[i] = counter.getTxTimeCounters()[i].getCountLocked(which); 12635 totalTxTimeMs += txTimeMs[i]; 12636 } 12637 12638 return new CellularBatteryStats(computeBatteryRealtime(rawRealTime, which) / 1000, 12639 getMobileRadioActiveTime(rawRealTime, which) / 1000, 12640 getNetworkActivityPackets(NETWORK_MOBILE_TX_DATA, which), 12641 getNetworkActivityBytes(NETWORK_MOBILE_TX_DATA, which), 12642 getNetworkActivityPackets(NETWORK_MOBILE_RX_DATA, which), 12643 getNetworkActivityBytes(NETWORK_MOBILE_RX_DATA, which), 12644 sleepTimeMs, idleTimeMs, rxTimeMs, energyConsumedMaMs, timeInRatMs, 12645 timeInRxSignalStrengthLevelMs, txTimeMs, 12646 monitoredRailChargeConsumedMaMs); 12647 } 12648 12649 /*@hide */ getWifiBatteryStats()12650 public WifiBatteryStats getWifiBatteryStats() { 12651 final int which = STATS_SINCE_CHARGED; 12652 final long rawRealTime = SystemClock.elapsedRealtime() * 1000; 12653 final ControllerActivityCounter counter = getWifiControllerActivity(); 12654 final long idleTimeMs = counter.getIdleTimeCounter().getCountLocked(which); 12655 final long scanTimeMs = counter.getScanTimeCounter().getCountLocked(which); 12656 final long rxTimeMs = counter.getRxTimeCounter().getCountLocked(which); 12657 final long txTimeMs = counter.getTxTimeCounters()[0].getCountLocked(which); 12658 final long totalControllerActivityTimeMs 12659 = computeBatteryRealtime(SystemClock.elapsedRealtime() * 1000, which) / 1000; 12660 final long sleepTimeMs 12661 = totalControllerActivityTimeMs - (idleTimeMs + rxTimeMs + txTimeMs); 12662 final long energyConsumedMaMs = counter.getPowerCounter().getCountLocked(which); 12663 final long monitoredRailChargeConsumedMaMs = 12664 counter.getMonitoredRailChargeConsumedMaMs().getCountLocked(which); 12665 long numAppScanRequest = 0; 12666 for (int i = 0; i < mUidStats.size(); i++) { 12667 numAppScanRequest += mUidStats.valueAt(i).mWifiScanTimer.getCountLocked(which); 12668 } 12669 long[] timeInStateMs = new long[NUM_WIFI_STATES]; 12670 for (int i=0; i<NUM_WIFI_STATES; i++) { 12671 timeInStateMs[i] = getWifiStateTime(i, rawRealTime, which) / 1000; 12672 } 12673 long[] timeInSupplStateMs = new long[NUM_WIFI_SUPPL_STATES]; 12674 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) { 12675 timeInSupplStateMs[i] = getWifiSupplStateTime(i, rawRealTime, which) / 1000; 12676 } 12677 long[] timeSignalStrengthTimeMs = new long[NUM_WIFI_SIGNAL_STRENGTH_BINS]; 12678 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { 12679 timeSignalStrengthTimeMs[i] = getWifiSignalStrengthTime(i, rawRealTime, which) / 1000; 12680 } 12681 return new WifiBatteryStats( 12682 computeBatteryRealtime(rawRealTime, which) / 1000, 12683 getWifiActiveTime(rawRealTime, which) / 1000, 12684 getNetworkActivityPackets(NETWORK_WIFI_TX_DATA, which), 12685 getNetworkActivityBytes(NETWORK_WIFI_TX_DATA, which), 12686 getNetworkActivityPackets(NETWORK_WIFI_RX_DATA, which), 12687 getNetworkActivityBytes(NETWORK_WIFI_RX_DATA, which), 12688 sleepTimeMs, scanTimeMs, idleTimeMs, rxTimeMs, txTimeMs, energyConsumedMaMs, 12689 numAppScanRequest, timeInStateMs, timeSignalStrengthTimeMs, timeInSupplStateMs, 12690 monitoredRailChargeConsumedMaMs); 12691 } 12692 12693 /*@hide */ getGpsBatteryStats()12694 public GpsBatteryStats getGpsBatteryStats() { 12695 GpsBatteryStats s = new GpsBatteryStats(); 12696 final int which = STATS_SINCE_CHARGED; 12697 final long rawRealTime = SystemClock.elapsedRealtime() * 1000; 12698 s.setLoggingDurationMs(computeBatteryRealtime(rawRealTime, which) / 1000); 12699 s.setEnergyConsumedMaMs(getGpsBatteryDrainMaMs()); 12700 long[] time = new long[GnssMetrics.NUM_GPS_SIGNAL_QUALITY_LEVELS]; 12701 for (int i=0; i<time.length; i++) { 12702 time[i] = getGpsSignalQualityTime(i, rawRealTime, which) / 1000; 12703 } 12704 s.setTimeInGpsSignalQualityLevel(time); 12705 return s; 12706 } 12707 12708 @Override getChargeLevelStepTracker()12709 public LevelStepTracker getChargeLevelStepTracker() { 12710 return mChargeStepTracker; 12711 } 12712 12713 @Override getDailyChargeLevelStepTracker()12714 public LevelStepTracker getDailyChargeLevelStepTracker() { 12715 return mDailyChargeStepTracker; 12716 } 12717 12718 @Override getDailyPackageChanges()12719 public ArrayList<PackageChange> getDailyPackageChanges() { 12720 return mDailyPackageChanges; 12721 } 12722 getBatteryUptimeLocked()12723 protected long getBatteryUptimeLocked() { 12724 return mOnBatteryTimeBase.getUptime(mClocks.uptimeMillis() * 1000); 12725 } 12726 12727 @Override getBatteryUptime(long curTime)12728 public long getBatteryUptime(long curTime) { 12729 return mOnBatteryTimeBase.getUptime(curTime); 12730 } 12731 12732 @Override 12733 @UnsupportedAppUsage getBatteryRealtime(long curTime)12734 public long getBatteryRealtime(long curTime) { 12735 return mOnBatteryTimeBase.getRealtime(curTime); 12736 } 12737 12738 @Override 12739 @UnsupportedAppUsage getDischargeStartLevel()12740 public int getDischargeStartLevel() { 12741 synchronized(this) { 12742 return getDischargeStartLevelLocked(); 12743 } 12744 } 12745 getDischargeStartLevelLocked()12746 public int getDischargeStartLevelLocked() { 12747 return mDischargeUnplugLevel; 12748 } 12749 12750 @Override 12751 @UnsupportedAppUsage getDischargeCurrentLevel()12752 public int getDischargeCurrentLevel() { 12753 synchronized(this) { 12754 return getDischargeCurrentLevelLocked(); 12755 } 12756 } 12757 getDischargeCurrentLevelLocked()12758 public int getDischargeCurrentLevelLocked() { 12759 return mDischargeCurrentLevel; 12760 } 12761 12762 @Override getLowDischargeAmountSinceCharge()12763 public int getLowDischargeAmountSinceCharge() { 12764 synchronized(this) { 12765 int val = mLowDischargeAmountSinceCharge; 12766 if (mOnBattery && mDischargeCurrentLevel < mDischargeUnplugLevel) { 12767 val += mDischargeUnplugLevel-mDischargeCurrentLevel-1; 12768 } 12769 return val; 12770 } 12771 } 12772 12773 @Override getHighDischargeAmountSinceCharge()12774 public int getHighDischargeAmountSinceCharge() { 12775 synchronized(this) { 12776 int val = mHighDischargeAmountSinceCharge; 12777 if (mOnBattery && mDischargeCurrentLevel < mDischargeUnplugLevel) { 12778 val += mDischargeUnplugLevel-mDischargeCurrentLevel; 12779 } 12780 return val; 12781 } 12782 } 12783 12784 @Override 12785 @UnsupportedAppUsage getDischargeAmount(int which)12786 public int getDischargeAmount(int which) { 12787 int dischargeAmount = which == STATS_SINCE_CHARGED 12788 ? getHighDischargeAmountSinceCharge() 12789 : (getDischargeStartLevel() - getDischargeCurrentLevel()); 12790 if (dischargeAmount < 0) { 12791 dischargeAmount = 0; 12792 } 12793 return dischargeAmount; 12794 } 12795 12796 @Override 12797 @UnsupportedAppUsage getDischargeAmountScreenOn()12798 public int getDischargeAmountScreenOn() { 12799 synchronized(this) { 12800 int val = mDischargeAmountScreenOn; 12801 if (mOnBattery && isScreenOn(mScreenState) 12802 && mDischargeCurrentLevel < mDischargeScreenOnUnplugLevel) { 12803 val += mDischargeScreenOnUnplugLevel-mDischargeCurrentLevel; 12804 } 12805 return val; 12806 } 12807 } 12808 12809 @Override getDischargeAmountScreenOnSinceCharge()12810 public int getDischargeAmountScreenOnSinceCharge() { 12811 synchronized(this) { 12812 int val = mDischargeAmountScreenOnSinceCharge; 12813 if (mOnBattery && isScreenOn(mScreenState) 12814 && mDischargeCurrentLevel < mDischargeScreenOnUnplugLevel) { 12815 val += mDischargeScreenOnUnplugLevel-mDischargeCurrentLevel; 12816 } 12817 return val; 12818 } 12819 } 12820 12821 @Override 12822 @UnsupportedAppUsage getDischargeAmountScreenOff()12823 public int getDischargeAmountScreenOff() { 12824 synchronized(this) { 12825 int val = mDischargeAmountScreenOff; 12826 if (mOnBattery && isScreenOff(mScreenState) 12827 && mDischargeCurrentLevel < mDischargeScreenOffUnplugLevel) { 12828 val += mDischargeScreenOffUnplugLevel-mDischargeCurrentLevel; 12829 } 12830 // For backward compatibility, doze discharge is counted into screen off. 12831 return val + getDischargeAmountScreenDoze(); 12832 } 12833 } 12834 12835 @Override getDischargeAmountScreenOffSinceCharge()12836 public int getDischargeAmountScreenOffSinceCharge() { 12837 synchronized(this) { 12838 int val = mDischargeAmountScreenOffSinceCharge; 12839 if (mOnBattery && isScreenOff(mScreenState) 12840 && mDischargeCurrentLevel < mDischargeScreenOffUnplugLevel) { 12841 val += mDischargeScreenOffUnplugLevel-mDischargeCurrentLevel; 12842 } 12843 // For backward compatibility, doze discharge is counted into screen off. 12844 return val + getDischargeAmountScreenDozeSinceCharge(); 12845 } 12846 } 12847 12848 @Override getDischargeAmountScreenDoze()12849 public int getDischargeAmountScreenDoze() { 12850 synchronized(this) { 12851 int val = mDischargeAmountScreenDoze; 12852 if (mOnBattery && isScreenDoze(mScreenState) 12853 && mDischargeCurrentLevel < mDischargeScreenDozeUnplugLevel) { 12854 val += mDischargeScreenDozeUnplugLevel-mDischargeCurrentLevel; 12855 } 12856 return val; 12857 } 12858 } 12859 12860 @Override getDischargeAmountScreenDozeSinceCharge()12861 public int getDischargeAmountScreenDozeSinceCharge() { 12862 synchronized(this) { 12863 int val = mDischargeAmountScreenDozeSinceCharge; 12864 if (mOnBattery && isScreenDoze(mScreenState) 12865 && mDischargeCurrentLevel < mDischargeScreenDozeUnplugLevel) { 12866 val += mDischargeScreenDozeUnplugLevel-mDischargeCurrentLevel; 12867 } 12868 return val; 12869 } 12870 } 12871 12872 /** 12873 * Retrieve the statistics object for a particular uid, creating if needed. 12874 */ 12875 @UnsupportedAppUsage getUidStatsLocked(int uid)12876 public Uid getUidStatsLocked(int uid) { 12877 Uid u = mUidStats.get(uid); 12878 if (u == null) { 12879 u = new Uid(this, uid); 12880 mUidStats.put(uid, u); 12881 } 12882 return u; 12883 } 12884 12885 /** 12886 * Retrieve the statistics object for a particular uid. Returns null if the object is not 12887 * available. 12888 */ getAvailableUidStatsLocked(int uid)12889 public Uid getAvailableUidStatsLocked(int uid) { 12890 Uid u = mUidStats.get(uid); 12891 return u; 12892 } 12893 onCleanupUserLocked(int userId)12894 public void onCleanupUserLocked(int userId) { 12895 final int firstUidForUser = UserHandle.getUid(userId, 0); 12896 final int lastUidForUser = UserHandle.getUid(userId, UserHandle.PER_USER_RANGE - 1); 12897 mPendingRemovedUids.add( 12898 new UidToRemove(firstUidForUser, lastUidForUser, mClocks.elapsedRealtime())); 12899 } 12900 onUserRemovedLocked(int userId)12901 public void onUserRemovedLocked(int userId) { 12902 final int firstUidForUser = UserHandle.getUid(userId, 0); 12903 final int lastUidForUser = UserHandle.getUid(userId, UserHandle.PER_USER_RANGE - 1); 12904 mUidStats.put(firstUidForUser, null); 12905 mUidStats.put(lastUidForUser, null); 12906 final int firstIndex = mUidStats.indexOfKey(firstUidForUser); 12907 final int lastIndex = mUidStats.indexOfKey(lastUidForUser); 12908 for (int i = firstIndex; i <= lastIndex; i++) { 12909 final Uid uid = mUidStats.valueAt(i); 12910 if (uid != null) { 12911 uid.detachFromTimeBase(); 12912 } 12913 } 12914 mUidStats.removeAtRange(firstIndex, lastIndex - firstIndex + 1); 12915 } 12916 12917 /** 12918 * Remove the statistics object for a particular uid. 12919 */ 12920 @UnsupportedAppUsage removeUidStatsLocked(int uid)12921 public void removeUidStatsLocked(int uid) { 12922 final Uid u = mUidStats.get(uid); 12923 if (u != null) { 12924 u.detachFromTimeBase(); 12925 } 12926 mUidStats.remove(uid); 12927 mPendingRemovedUids.add(new UidToRemove(uid, mClocks.elapsedRealtime())); 12928 } 12929 12930 /** 12931 * Retrieve the statistics object for a particular process, creating 12932 * if needed. 12933 */ 12934 @UnsupportedAppUsage getProcessStatsLocked(int uid, String name)12935 public Uid.Proc getProcessStatsLocked(int uid, String name) { 12936 uid = mapUid(uid); 12937 Uid u = getUidStatsLocked(uid); 12938 return u.getProcessStatsLocked(name); 12939 } 12940 12941 /** 12942 * Retrieve the statistics object for a particular process, creating 12943 * if needed. 12944 */ 12945 @UnsupportedAppUsage getPackageStatsLocked(int uid, String pkg)12946 public Uid.Pkg getPackageStatsLocked(int uid, String pkg) { 12947 uid = mapUid(uid); 12948 Uid u = getUidStatsLocked(uid); 12949 return u.getPackageStatsLocked(pkg); 12950 } 12951 12952 /** 12953 * Retrieve the statistics object for a particular service, creating 12954 * if needed. 12955 */ 12956 @UnsupportedAppUsage getServiceStatsLocked(int uid, String pkg, String name)12957 public Uid.Pkg.Serv getServiceStatsLocked(int uid, String pkg, String name) { 12958 uid = mapUid(uid); 12959 Uid u = getUidStatsLocked(uid); 12960 return u.getServiceStatsLocked(pkg, name); 12961 } 12962 shutdownLocked()12963 public void shutdownLocked() { 12964 recordShutdownLocked(mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 12965 writeSyncLocked(); 12966 mShuttingDown = true; 12967 } 12968 trackPerProcStateCpuTimes()12969 public boolean trackPerProcStateCpuTimes() { 12970 return mConstants.TRACK_CPU_TIMES_BY_PROC_STATE && mPerProcStateCpuTimesAvailable; 12971 } 12972 systemServicesReady(Context context)12973 public void systemServicesReady(Context context) { 12974 mConstants.startObserving(context.getContentResolver()); 12975 registerUsbStateReceiver(context); 12976 } 12977 12978 @VisibleForTesting 12979 public final class Constants extends ContentObserver { 12980 public static final String KEY_TRACK_CPU_TIMES_BY_PROC_STATE 12981 = "track_cpu_times_by_proc_state"; 12982 public static final String KEY_TRACK_CPU_ACTIVE_CLUSTER_TIME 12983 = "track_cpu_active_cluster_time"; 12984 public static final String KEY_PROC_STATE_CPU_TIMES_READ_DELAY_MS 12985 = "proc_state_cpu_times_read_delay_ms"; 12986 public static final String KEY_KERNEL_UID_READERS_THROTTLE_TIME 12987 = "kernel_uid_readers_throttle_time"; 12988 public static final String KEY_UID_REMOVE_DELAY_MS 12989 = "uid_remove_delay_ms"; 12990 public static final String KEY_EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS 12991 = "external_stats_collection_rate_limit_ms"; 12992 public static final String KEY_BATTERY_LEVEL_COLLECTION_DELAY_MS 12993 = "battery_level_collection_delay_ms"; 12994 public static final String KEY_MAX_HISTORY_FILES = "max_history_files"; 12995 public static final String KEY_MAX_HISTORY_BUFFER_KB = "max_history_buffer_kb"; 12996 public static final String KEY_BATTERY_CHARGED_DELAY_MS = 12997 "battery_charged_delay_ms"; 12998 12999 private static final boolean DEFAULT_TRACK_CPU_TIMES_BY_PROC_STATE = false; 13000 private static final boolean DEFAULT_TRACK_CPU_ACTIVE_CLUSTER_TIME = true; 13001 private static final long DEFAULT_PROC_STATE_CPU_TIMES_READ_DELAY_MS = 5_000; 13002 private static final long DEFAULT_KERNEL_UID_READERS_THROTTLE_TIME = 1_000; 13003 private static final long DEFAULT_UID_REMOVE_DELAY_MS = 5L * 60L * 1000L; 13004 private static final long DEFAULT_EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS = 600_000; 13005 private static final long DEFAULT_BATTERY_LEVEL_COLLECTION_DELAY_MS = 300_000; 13006 private static final int DEFAULT_MAX_HISTORY_FILES = 32; 13007 private static final int DEFAULT_MAX_HISTORY_BUFFER_KB = 128; /*Kilo Bytes*/ 13008 private static final int DEFAULT_MAX_HISTORY_FILES_LOW_RAM_DEVICE = 64; 13009 private static final int DEFAULT_MAX_HISTORY_BUFFER_LOW_RAM_DEVICE_KB = 64; /*Kilo Bytes*/ 13010 private static final int DEFAULT_BATTERY_CHARGED_DELAY_MS = 900000; /* 15 min */ 13011 13012 public boolean TRACK_CPU_TIMES_BY_PROC_STATE = DEFAULT_TRACK_CPU_TIMES_BY_PROC_STATE; 13013 public boolean TRACK_CPU_ACTIVE_CLUSTER_TIME = DEFAULT_TRACK_CPU_ACTIVE_CLUSTER_TIME; 13014 public long PROC_STATE_CPU_TIMES_READ_DELAY_MS = DEFAULT_PROC_STATE_CPU_TIMES_READ_DELAY_MS; 13015 /* Do not set default value for KERNEL_UID_READERS_THROTTLE_TIME. Need to trigger an 13016 * update when startObserving. */ 13017 public long KERNEL_UID_READERS_THROTTLE_TIME; 13018 public long UID_REMOVE_DELAY_MS = DEFAULT_UID_REMOVE_DELAY_MS; 13019 public long EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS 13020 = DEFAULT_EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS; 13021 public long BATTERY_LEVEL_COLLECTION_DELAY_MS 13022 = DEFAULT_BATTERY_LEVEL_COLLECTION_DELAY_MS; 13023 public int MAX_HISTORY_FILES; 13024 public int MAX_HISTORY_BUFFER; /*Bytes*/ 13025 public int BATTERY_CHARGED_DELAY_MS = DEFAULT_BATTERY_CHARGED_DELAY_MS; 13026 13027 private ContentResolver mResolver; 13028 private final KeyValueListParser mParser = new KeyValueListParser(','); 13029 Constants(Handler handler)13030 public Constants(Handler handler) { 13031 super(handler); 13032 if (ActivityManager.isLowRamDeviceStatic()) { 13033 MAX_HISTORY_FILES = DEFAULT_MAX_HISTORY_FILES_LOW_RAM_DEVICE; 13034 MAX_HISTORY_BUFFER = DEFAULT_MAX_HISTORY_BUFFER_LOW_RAM_DEVICE_KB * 1024; 13035 } else { 13036 MAX_HISTORY_FILES = DEFAULT_MAX_HISTORY_FILES; 13037 MAX_HISTORY_BUFFER = DEFAULT_MAX_HISTORY_BUFFER_KB * 1024; 13038 } 13039 } 13040 startObserving(ContentResolver resolver)13041 public void startObserving(ContentResolver resolver) { 13042 mResolver = resolver; 13043 mResolver.registerContentObserver( 13044 Settings.Global.getUriFor(Settings.Global.BATTERY_STATS_CONSTANTS), 13045 false /* notifyForDescendants */, this); 13046 mResolver.registerContentObserver( 13047 Settings.Global.getUriFor(Settings.Global.BATTERY_CHARGING_STATE_UPDATE_DELAY), 13048 false /* notifyForDescendants */, this); 13049 updateConstants(); 13050 } 13051 13052 @Override onChange(boolean selfChange, Uri uri)13053 public void onChange(boolean selfChange, Uri uri) { 13054 if (uri.equals( 13055 Settings.Global.getUriFor( 13056 Settings.Global.BATTERY_CHARGING_STATE_UPDATE_DELAY))) { 13057 synchronized (BatteryStatsImpl.this) { 13058 updateBatteryChargedDelayMsLocked(); 13059 } 13060 return; 13061 } 13062 updateConstants(); 13063 } 13064 updateConstants()13065 private void updateConstants() { 13066 synchronized (BatteryStatsImpl.this) { 13067 try { 13068 mParser.setString(Settings.Global.getString(mResolver, 13069 Settings.Global.BATTERY_STATS_CONSTANTS)); 13070 } catch (IllegalArgumentException e) { 13071 // Failed to parse the settings string, log this and move on 13072 // with defaults. 13073 Slog.e(TAG, "Bad batterystats settings", e); 13074 } 13075 13076 updateTrackCpuTimesByProcStateLocked(TRACK_CPU_TIMES_BY_PROC_STATE, 13077 mParser.getBoolean(KEY_TRACK_CPU_TIMES_BY_PROC_STATE, 13078 DEFAULT_TRACK_CPU_TIMES_BY_PROC_STATE)); 13079 TRACK_CPU_ACTIVE_CLUSTER_TIME = mParser.getBoolean( 13080 KEY_TRACK_CPU_ACTIVE_CLUSTER_TIME, DEFAULT_TRACK_CPU_ACTIVE_CLUSTER_TIME); 13081 updateProcStateCpuTimesReadDelayMs(PROC_STATE_CPU_TIMES_READ_DELAY_MS, 13082 mParser.getLong(KEY_PROC_STATE_CPU_TIMES_READ_DELAY_MS, 13083 DEFAULT_PROC_STATE_CPU_TIMES_READ_DELAY_MS)); 13084 updateKernelUidReadersThrottleTime(KERNEL_UID_READERS_THROTTLE_TIME, 13085 mParser.getLong(KEY_KERNEL_UID_READERS_THROTTLE_TIME, 13086 DEFAULT_KERNEL_UID_READERS_THROTTLE_TIME)); 13087 updateUidRemoveDelay( 13088 mParser.getLong(KEY_UID_REMOVE_DELAY_MS, DEFAULT_UID_REMOVE_DELAY_MS)); 13089 EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS = mParser.getLong( 13090 KEY_EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS, 13091 DEFAULT_EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS); 13092 BATTERY_LEVEL_COLLECTION_DELAY_MS = mParser.getLong( 13093 KEY_BATTERY_LEVEL_COLLECTION_DELAY_MS, 13094 DEFAULT_BATTERY_LEVEL_COLLECTION_DELAY_MS); 13095 13096 MAX_HISTORY_FILES = mParser.getInt(KEY_MAX_HISTORY_FILES, 13097 ActivityManager.isLowRamDeviceStatic() ? 13098 DEFAULT_MAX_HISTORY_FILES_LOW_RAM_DEVICE 13099 : DEFAULT_MAX_HISTORY_FILES); 13100 MAX_HISTORY_BUFFER = mParser.getInt(KEY_MAX_HISTORY_BUFFER_KB, 13101 ActivityManager.isLowRamDeviceStatic() ? 13102 DEFAULT_MAX_HISTORY_BUFFER_LOW_RAM_DEVICE_KB 13103 : DEFAULT_MAX_HISTORY_BUFFER_KB) 13104 * 1024; 13105 updateBatteryChargedDelayMsLocked(); 13106 } 13107 } 13108 updateBatteryChargedDelayMsLocked()13109 private void updateBatteryChargedDelayMsLocked() { 13110 // a negative value indicates that we should ignore this override 13111 final int delay = Settings.Global.getInt(mResolver, 13112 Settings.Global.BATTERY_CHARGING_STATE_UPDATE_DELAY, 13113 -1); 13114 13115 BATTERY_CHARGED_DELAY_MS = delay >= 0 ? delay : mParser.getInt( 13116 KEY_BATTERY_CHARGED_DELAY_MS, 13117 DEFAULT_BATTERY_CHARGED_DELAY_MS); 13118 } 13119 updateTrackCpuTimesByProcStateLocked(boolean wasEnabled, boolean isEnabled)13120 private void updateTrackCpuTimesByProcStateLocked(boolean wasEnabled, boolean isEnabled) { 13121 TRACK_CPU_TIMES_BY_PROC_STATE = isEnabled; 13122 if (isEnabled && !wasEnabled) { 13123 mIsPerProcessStateCpuDataStale = true; 13124 mExternalSync.scheduleCpuSyncDueToSettingChange(); 13125 13126 mNumSingleUidCpuTimeReads = 0; 13127 mNumBatchedSingleUidCpuTimeReads = 0; 13128 mCpuTimeReadsTrackingStartTime = mClocks.uptimeMillis(); 13129 } 13130 } 13131 updateProcStateCpuTimesReadDelayMs(long oldDelayMillis, long newDelayMillis)13132 private void updateProcStateCpuTimesReadDelayMs(long oldDelayMillis, long newDelayMillis) { 13133 PROC_STATE_CPU_TIMES_READ_DELAY_MS = newDelayMillis; 13134 if (oldDelayMillis != newDelayMillis) { 13135 mNumSingleUidCpuTimeReads = 0; 13136 mNumBatchedSingleUidCpuTimeReads = 0; 13137 mCpuTimeReadsTrackingStartTime = mClocks.uptimeMillis(); 13138 } 13139 } 13140 updateKernelUidReadersThrottleTime(long oldTimeMs, long newTimeMs)13141 private void updateKernelUidReadersThrottleTime(long oldTimeMs, long newTimeMs) { 13142 KERNEL_UID_READERS_THROTTLE_TIME = newTimeMs; 13143 if (oldTimeMs != newTimeMs) { 13144 mCpuUidUserSysTimeReader.setThrottle(KERNEL_UID_READERS_THROTTLE_TIME); 13145 mCpuUidFreqTimeReader.setThrottle(KERNEL_UID_READERS_THROTTLE_TIME); 13146 mCpuUidActiveTimeReader.setThrottle(KERNEL_UID_READERS_THROTTLE_TIME); 13147 mCpuUidClusterTimeReader 13148 .setThrottle(KERNEL_UID_READERS_THROTTLE_TIME); 13149 } 13150 } 13151 updateUidRemoveDelay(long newTimeMs)13152 private void updateUidRemoveDelay(long newTimeMs) { 13153 UID_REMOVE_DELAY_MS = newTimeMs; 13154 clearPendingRemovedUids(); 13155 } 13156 dumpLocked(PrintWriter pw)13157 public void dumpLocked(PrintWriter pw) { 13158 pw.print(KEY_TRACK_CPU_TIMES_BY_PROC_STATE); pw.print("="); 13159 pw.println(TRACK_CPU_TIMES_BY_PROC_STATE); 13160 pw.print(KEY_TRACK_CPU_ACTIVE_CLUSTER_TIME); pw.print("="); 13161 pw.println(TRACK_CPU_ACTIVE_CLUSTER_TIME); 13162 pw.print(KEY_PROC_STATE_CPU_TIMES_READ_DELAY_MS); pw.print("="); 13163 pw.println(PROC_STATE_CPU_TIMES_READ_DELAY_MS); 13164 pw.print(KEY_KERNEL_UID_READERS_THROTTLE_TIME); pw.print("="); 13165 pw.println(KERNEL_UID_READERS_THROTTLE_TIME); 13166 pw.print(KEY_EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS); pw.print("="); 13167 pw.println(EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS); 13168 pw.print(KEY_BATTERY_LEVEL_COLLECTION_DELAY_MS); pw.print("="); 13169 pw.println(BATTERY_LEVEL_COLLECTION_DELAY_MS); 13170 pw.print(KEY_MAX_HISTORY_FILES); pw.print("="); 13171 pw.println(MAX_HISTORY_FILES); 13172 pw.print(KEY_MAX_HISTORY_BUFFER_KB); pw.print("="); 13173 pw.println(MAX_HISTORY_BUFFER/1024); 13174 pw.print(KEY_BATTERY_CHARGED_DELAY_MS); pw.print("="); 13175 pw.println(BATTERY_CHARGED_DELAY_MS); 13176 } 13177 } 13178 getExternalStatsCollectionRateLimitMs()13179 public long getExternalStatsCollectionRateLimitMs() { 13180 synchronized (this) { 13181 return mConstants.EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS; 13182 } 13183 } 13184 13185 @GuardedBy("this") dumpConstantsLocked(PrintWriter pw)13186 public void dumpConstantsLocked(PrintWriter pw) { 13187 mConstants.dumpLocked(pw); 13188 } 13189 13190 @GuardedBy("this") dumpCpuStatsLocked(PrintWriter pw)13191 public void dumpCpuStatsLocked(PrintWriter pw) { 13192 int size = mUidStats.size(); 13193 pw.println("Per UID CPU user & system time in ms:"); 13194 for (int i = 0; i < size; i++) { 13195 int u = mUidStats.keyAt(i); 13196 Uid uid = mUidStats.get(u); 13197 pw.print(" "); pw.print(u); pw.print(": "); 13198 pw.print(uid.getUserCpuTimeUs(STATS_SINCE_CHARGED) / 1000); pw.print(" "); 13199 pw.println(uid.getSystemCpuTimeUs(STATS_SINCE_CHARGED) / 1000); 13200 } 13201 pw.println("Per UID CPU active time in ms:"); 13202 for (int i = 0; i < size; i++) { 13203 int u = mUidStats.keyAt(i); 13204 Uid uid = mUidStats.get(u); 13205 if (uid.getCpuActiveTime() > 0) { 13206 pw.print(" "); pw.print(u); pw.print(": "); pw.println(uid.getCpuActiveTime()); 13207 } 13208 } 13209 pw.println("Per UID CPU cluster time in ms:"); 13210 for (int i = 0; i < size; i++) { 13211 int u = mUidStats.keyAt(i); 13212 long[] times = mUidStats.get(u).getCpuClusterTimes(); 13213 if (times != null) { 13214 pw.print(" "); pw.print(u); pw.print(": "); pw.println(Arrays.toString(times)); 13215 } 13216 } 13217 pw.println("Per UID CPU frequency time in ms:"); 13218 for (int i = 0; i < size; i++) { 13219 int u = mUidStats.keyAt(i); 13220 long[] times = mUidStats.get(u).getCpuFreqTimes(STATS_SINCE_CHARGED); 13221 if (times != null) { 13222 pw.print(" "); pw.print(u); pw.print(": "); pw.println(Arrays.toString(times)); 13223 } 13224 } 13225 } 13226 13227 final ReentrantLock mWriteLock = new ReentrantLock(); 13228 writeAsyncLocked()13229 public void writeAsyncLocked() { 13230 writeStatsLocked(false); 13231 writeHistoryLocked(false); 13232 } 13233 writeSyncLocked()13234 public void writeSyncLocked() { 13235 writeStatsLocked(true); 13236 writeHistoryLocked(true); 13237 } 13238 writeStatsLocked(boolean sync)13239 void writeStatsLocked(boolean sync) { 13240 if (mStatsFile == null) { 13241 Slog.w(TAG, 13242 "writeStatsLocked: no file associated with this instance"); 13243 return; 13244 } 13245 13246 if (mShuttingDown) { 13247 return; 13248 } 13249 13250 final Parcel p = Parcel.obtain(); 13251 final long start = SystemClock.uptimeMillis(); 13252 writeSummaryToParcel(p, false/*history is in separate file*/); 13253 if (DEBUG) { 13254 Slog.d(TAG, "writeSummaryToParcel duration ms:" 13255 + (SystemClock.uptimeMillis() - start) + " bytes:" + p.dataSize()); 13256 } 13257 mLastWriteTime = mClocks.elapsedRealtime(); 13258 writeParcelToFileLocked(p, mStatsFile, sync); 13259 } 13260 writeHistoryLocked(boolean sync)13261 void writeHistoryLocked(boolean sync) { 13262 if (mBatteryStatsHistory.getActiveFile() == null) { 13263 Slog.w(TAG, 13264 "writeHistoryLocked: no history file associated with this instance"); 13265 return; 13266 } 13267 13268 if (mShuttingDown) { 13269 return; 13270 } 13271 13272 Parcel p = Parcel.obtain(); 13273 final long start = SystemClock.uptimeMillis(); 13274 writeHistoryBuffer(p, true, true); 13275 if (DEBUG) { 13276 Slog.d(TAG, "writeHistoryBuffer duration ms:" 13277 + (SystemClock.uptimeMillis() - start) + " bytes:" + p.dataSize()); 13278 } 13279 writeParcelToFileLocked(p, mBatteryStatsHistory.getActiveFile(), sync); 13280 } 13281 writeParcelToFileLocked(Parcel p, AtomicFile file, boolean sync)13282 void writeParcelToFileLocked(Parcel p, AtomicFile file, boolean sync) { 13283 if (sync) { 13284 commitPendingDataToDisk(p, file); 13285 } else { 13286 BackgroundThread.getHandler().post(new Runnable() { 13287 @Override public void run() { 13288 commitPendingDataToDisk(p, file); 13289 } 13290 }); 13291 } 13292 } 13293 commitPendingDataToDisk(Parcel p, AtomicFile file)13294 private void commitPendingDataToDisk(Parcel p, AtomicFile file) { 13295 mWriteLock.lock(); 13296 FileOutputStream fos = null; 13297 try { 13298 final long startTime = SystemClock.uptimeMillis(); 13299 fos = file.startWrite(); 13300 fos.write(p.marshall()); 13301 fos.flush(); 13302 file.finishWrite(fos); 13303 if (DEBUG) { 13304 Slog.d(TAG, "commitPendingDataToDisk file:" + file.getBaseFile().getPath() 13305 + " duration ms:" + (SystemClock.uptimeMillis() - startTime) 13306 + " bytes:" + p.dataSize()); 13307 } 13308 com.android.internal.logging.EventLogTags.writeCommitSysConfigFile( 13309 "batterystats", SystemClock.uptimeMillis() - startTime); 13310 } catch (IOException e) { 13311 Slog.w(TAG, "Error writing battery statistics", e); 13312 file.failWrite(fos); 13313 } finally { 13314 p.recycle(); 13315 mWriteLock.unlock(); 13316 } 13317 } 13318 13319 @UnsupportedAppUsage readLocked()13320 public void readLocked() { 13321 if (mDailyFile != null) { 13322 readDailyStatsLocked(); 13323 } 13324 13325 if (mStatsFile == null) { 13326 Slog.w(TAG, "readLocked: no file associated with this instance"); 13327 return; 13328 } 13329 13330 final AtomicFile activeHistoryFile = mBatteryStatsHistory.getActiveFile(); 13331 if (activeHistoryFile == null) { 13332 Slog.w(TAG, 13333 "readLocked: no history file associated with this instance"); 13334 return; 13335 } 13336 13337 mUidStats.clear(); 13338 13339 Parcel stats = Parcel.obtain(); 13340 try { 13341 final long start = SystemClock.uptimeMillis(); 13342 if (mStatsFile.exists()) { 13343 byte[] raw = mStatsFile.readFully(); 13344 stats.unmarshall(raw, 0, raw.length); 13345 stats.setDataPosition(0); 13346 readSummaryFromParcel(stats); 13347 if (DEBUG) { 13348 Slog.d(TAG, "readLocked stats file:" + mStatsFile.getBaseFile().getPath() 13349 + " bytes:" + raw.length + " takes ms:" + (SystemClock.uptimeMillis() 13350 - start)); 13351 } 13352 } 13353 } catch (Exception e) { 13354 Slog.e(TAG, "Error reading battery statistics", e); 13355 resetAllStatsLocked(); 13356 } finally { 13357 stats.recycle(); 13358 } 13359 13360 Parcel history = Parcel.obtain(); 13361 try { 13362 final long start = SystemClock.uptimeMillis(); 13363 if (activeHistoryFile.exists()) { 13364 byte[] raw = activeHistoryFile.readFully(); 13365 if (raw.length > 0) { 13366 history.unmarshall(raw, 0, raw.length); 13367 history.setDataPosition(0); 13368 readHistoryBuffer(history, true); 13369 } 13370 if (DEBUG) { 13371 Slog.d(TAG, "readLocked history file::" 13372 + activeHistoryFile.getBaseFile().getPath() 13373 + " bytes:" + raw.length + " takes ms:" + (SystemClock.uptimeMillis() 13374 - start)); 13375 } 13376 } 13377 } catch (Exception e) { 13378 Slog.e(TAG, "Error reading battery history", e); 13379 clearHistoryLocked(); 13380 mBatteryStatsHistory.resetAllFiles(); 13381 } finally { 13382 history.recycle(); 13383 } 13384 13385 mEndPlatformVersion = Build.ID; 13386 13387 if (mHistoryBuffer.dataPosition() > 0 13388 || mBatteryStatsHistory.getFilesNumbers().size() > 1) { 13389 mRecordingHistory = true; 13390 final long elapsedRealtime = mClocks.elapsedRealtime(); 13391 final long uptime = mClocks.uptimeMillis(); 13392 if (USE_OLD_HISTORY) { 13393 addHistoryRecordLocked(elapsedRealtime, uptime, HistoryItem.CMD_START, mHistoryCur); 13394 } 13395 addHistoryBufferLocked(elapsedRealtime, HistoryItem.CMD_START, mHistoryCur); 13396 startRecordingHistory(elapsedRealtime, uptime, false); 13397 } 13398 13399 recordDailyStatsIfNeededLocked(false); 13400 } 13401 describeContents()13402 public int describeContents() { 13403 return 0; 13404 } 13405 readHistoryBuffer(Parcel in, boolean andOldHistory)13406 void readHistoryBuffer(Parcel in, boolean andOldHistory) throws ParcelFormatException { 13407 final int version = in.readInt(); 13408 if (version != VERSION) { 13409 Slog.w("BatteryStats", "readHistoryBuffer: version got " + version 13410 + ", expected " + VERSION + "; erasing old stats"); 13411 return; 13412 } 13413 13414 final long historyBaseTime = in.readLong(); 13415 13416 mHistoryBuffer.setDataSize(0); 13417 mHistoryBuffer.setDataPosition(0); 13418 13419 int bufSize = in.readInt(); 13420 int curPos = in.dataPosition(); 13421 if (bufSize >= (mConstants.MAX_HISTORY_BUFFER*100)) { 13422 throw new ParcelFormatException("File corrupt: history data buffer too large " + 13423 bufSize); 13424 } else if ((bufSize&~3) != bufSize) { 13425 throw new ParcelFormatException("File corrupt: history data buffer not aligned " + 13426 bufSize); 13427 } else { 13428 if (DEBUG_HISTORY) Slog.i(TAG, "***************** READING NEW HISTORY: " + bufSize 13429 + " bytes at " + curPos); 13430 mHistoryBuffer.appendFrom(in, curPos, bufSize); 13431 in.setDataPosition(curPos + bufSize); 13432 } 13433 13434 if (andOldHistory) { 13435 readOldHistory(in); 13436 } 13437 13438 if (DEBUG_HISTORY) { 13439 StringBuilder sb = new StringBuilder(128); 13440 sb.append("****************** OLD mHistoryBaseTime: "); 13441 TimeUtils.formatDuration(mHistoryBaseTime, sb); 13442 Slog.i(TAG, sb.toString()); 13443 } 13444 mHistoryBaseTime = historyBaseTime; 13445 if (DEBUG_HISTORY) { 13446 StringBuilder sb = new StringBuilder(128); 13447 sb.append("****************** NEW mHistoryBaseTime: "); 13448 TimeUtils.formatDuration(mHistoryBaseTime, sb); 13449 Slog.i(TAG, sb.toString()); 13450 } 13451 13452 // We are just arbitrarily going to insert 1 minute from the sample of 13453 // the last run until samples in this run. 13454 if (mHistoryBaseTime > 0) { 13455 long oldnow = mClocks.elapsedRealtime(); 13456 mHistoryBaseTime = mHistoryBaseTime - oldnow + 1; 13457 if (DEBUG_HISTORY) { 13458 StringBuilder sb = new StringBuilder(128); 13459 sb.append("****************** ADJUSTED mHistoryBaseTime: "); 13460 TimeUtils.formatDuration(mHistoryBaseTime, sb); 13461 Slog.i(TAG, sb.toString()); 13462 } 13463 } 13464 } 13465 readOldHistory(Parcel in)13466 void readOldHistory(Parcel in) { 13467 if (!USE_OLD_HISTORY) { 13468 return; 13469 } 13470 mHistory = mHistoryEnd = mHistoryCache = null; 13471 while (in.dataAvail() > 0) { 13472 HistoryItem rec = new HistoryItem(in); 13473 addHistoryRecordLocked(rec); 13474 } 13475 } 13476 writeHistoryBuffer(Parcel out, boolean inclData, boolean andOldHistory)13477 void writeHistoryBuffer(Parcel out, boolean inclData, boolean andOldHistory) { 13478 if (DEBUG_HISTORY) { 13479 StringBuilder sb = new StringBuilder(128); 13480 sb.append("****************** WRITING mHistoryBaseTime: "); 13481 TimeUtils.formatDuration(mHistoryBaseTime, sb); 13482 sb.append(" mLastHistoryElapsedRealtime: "); 13483 TimeUtils.formatDuration(mLastHistoryElapsedRealtime, sb); 13484 Slog.i(TAG, sb.toString()); 13485 } 13486 out.writeInt(VERSION); 13487 out.writeLong(mHistoryBaseTime + mLastHistoryElapsedRealtime); 13488 if (!inclData) { 13489 out.writeInt(0); 13490 out.writeInt(0); 13491 return; 13492 } 13493 13494 out.writeInt(mHistoryBuffer.dataSize()); 13495 if (DEBUG_HISTORY) Slog.i(TAG, "***************** WRITING HISTORY: " 13496 + mHistoryBuffer.dataSize() + " bytes at " + out.dataPosition()); 13497 out.appendFrom(mHistoryBuffer, 0, mHistoryBuffer.dataSize()); 13498 13499 if (andOldHistory) { 13500 writeOldHistory(out); 13501 } 13502 } 13503 writeOldHistory(Parcel out)13504 void writeOldHistory(Parcel out) { 13505 if (!USE_OLD_HISTORY) { 13506 return; 13507 } 13508 HistoryItem rec = mHistory; 13509 while (rec != null) { 13510 if (rec.time >= 0) rec.writeToParcel(out, 0); 13511 rec = rec.next; 13512 } 13513 out.writeLong(-1); 13514 } 13515 readSummaryFromParcel(Parcel in)13516 public void readSummaryFromParcel(Parcel in) throws ParcelFormatException { 13517 final int version = in.readInt(); 13518 if (version != VERSION) { 13519 Slog.w("BatteryStats", "readFromParcel: version got " + version 13520 + ", expected " + VERSION + "; erasing old stats"); 13521 return; 13522 } 13523 13524 boolean inclHistory = in.readBoolean(); 13525 if (inclHistory) { 13526 readHistoryBuffer(in, true); 13527 mBatteryStatsHistory.readFromParcel(in); 13528 } 13529 13530 mHistoryTagPool.clear(); 13531 mNextHistoryTagIdx = 0; 13532 mNumHistoryTagChars = 0; 13533 13534 int numTags = in.readInt(); 13535 for (int i=0; i<numTags; i++) { 13536 int idx = in.readInt(); 13537 String str = in.readString(); 13538 if (str == null) { 13539 throw new ParcelFormatException("null history tag string"); 13540 } 13541 int uid = in.readInt(); 13542 HistoryTag tag = new HistoryTag(); 13543 tag.string = str; 13544 tag.uid = uid; 13545 tag.poolIdx = idx; 13546 mHistoryTagPool.put(tag, idx); 13547 if (idx >= mNextHistoryTagIdx) { 13548 mNextHistoryTagIdx = idx+1; 13549 } 13550 mNumHistoryTagChars += tag.string.length() + 1; 13551 } 13552 13553 mStartCount = in.readInt(); 13554 mUptime = in.readLong(); 13555 mRealtime = in.readLong(); 13556 mStartClockTime = in.readLong(); 13557 mStartPlatformVersion = in.readString(); 13558 mEndPlatformVersion = in.readString(); 13559 mOnBatteryTimeBase.readSummaryFromParcel(in); 13560 mOnBatteryScreenOffTimeBase.readSummaryFromParcel(in); 13561 mDischargeUnplugLevel = in.readInt(); 13562 mDischargePlugLevel = in.readInt(); 13563 mDischargeCurrentLevel = in.readInt(); 13564 mCurrentBatteryLevel = in.readInt(); 13565 mEstimatedBatteryCapacity = in.readInt(); 13566 mMinLearnedBatteryCapacity = in.readInt(); 13567 mMaxLearnedBatteryCapacity = in.readInt(); 13568 mLowDischargeAmountSinceCharge = in.readInt(); 13569 mHighDischargeAmountSinceCharge = in.readInt(); 13570 mDischargeAmountScreenOnSinceCharge = in.readInt(); 13571 mDischargeAmountScreenOffSinceCharge = in.readInt(); 13572 mDischargeAmountScreenDozeSinceCharge = in.readInt(); 13573 mDischargeStepTracker.readFromParcel(in); 13574 mChargeStepTracker.readFromParcel(in); 13575 mDailyDischargeStepTracker.readFromParcel(in); 13576 mDailyChargeStepTracker.readFromParcel(in); 13577 mDischargeCounter.readSummaryFromParcelLocked(in); 13578 mDischargeScreenOffCounter.readSummaryFromParcelLocked(in); 13579 mDischargeScreenDozeCounter.readSummaryFromParcelLocked(in); 13580 mDischargeLightDozeCounter.readSummaryFromParcelLocked(in); 13581 mDischargeDeepDozeCounter.readSummaryFromParcelLocked(in); 13582 int NPKG = in.readInt(); 13583 if (NPKG > 0) { 13584 mDailyPackageChanges = new ArrayList<>(NPKG); 13585 while (NPKG > 0) { 13586 NPKG--; 13587 PackageChange pc = new PackageChange(); 13588 pc.mPackageName = in.readString(); 13589 pc.mUpdate = in.readInt() != 0; 13590 pc.mVersionCode = in.readLong(); 13591 mDailyPackageChanges.add(pc); 13592 } 13593 } else { 13594 mDailyPackageChanges = null; 13595 } 13596 mDailyStartTime = in.readLong(); 13597 mNextMinDailyDeadline = in.readLong(); 13598 mNextMaxDailyDeadline = in.readLong(); 13599 13600 mStartCount++; 13601 13602 mScreenState = Display.STATE_UNKNOWN; 13603 mScreenOnTimer.readSummaryFromParcelLocked(in); 13604 mScreenDozeTimer.readSummaryFromParcelLocked(in); 13605 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 13606 mScreenBrightnessTimer[i].readSummaryFromParcelLocked(in); 13607 } 13608 mInteractive = false; 13609 mInteractiveTimer.readSummaryFromParcelLocked(in); 13610 mPhoneOn = false; 13611 mPowerSaveModeEnabledTimer.readSummaryFromParcelLocked(in); 13612 mLongestLightIdleTime = in.readLong(); 13613 mLongestFullIdleTime = in.readLong(); 13614 mDeviceIdleModeLightTimer.readSummaryFromParcelLocked(in); 13615 mDeviceIdleModeFullTimer.readSummaryFromParcelLocked(in); 13616 mDeviceLightIdlingTimer.readSummaryFromParcelLocked(in); 13617 mDeviceIdlingTimer.readSummaryFromParcelLocked(in); 13618 mPhoneOnTimer.readSummaryFromParcelLocked(in); 13619 for (int i = 0; i < CellSignalStrength.getNumSignalStrengthLevels(); i++) { 13620 mPhoneSignalStrengthsTimer[i].readSummaryFromParcelLocked(in); 13621 } 13622 mPhoneSignalScanningTimer.readSummaryFromParcelLocked(in); 13623 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 13624 mPhoneDataConnectionsTimer[i].readSummaryFromParcelLocked(in); 13625 } 13626 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 13627 mNetworkByteActivityCounters[i].readSummaryFromParcelLocked(in); 13628 mNetworkPacketActivityCounters[i].readSummaryFromParcelLocked(in); 13629 } 13630 mMobileRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW; 13631 mMobileRadioActiveTimer.readSummaryFromParcelLocked(in); 13632 mMobileRadioActivePerAppTimer.readSummaryFromParcelLocked(in); 13633 mMobileRadioActiveAdjustedTime.readSummaryFromParcelLocked(in); 13634 mMobileRadioActiveUnknownTime.readSummaryFromParcelLocked(in); 13635 mMobileRadioActiveUnknownCount.readSummaryFromParcelLocked(in); 13636 mWifiMulticastWakelockTimer.readSummaryFromParcelLocked(in); 13637 mWifiRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW; 13638 mWifiOn = false; 13639 mWifiOnTimer.readSummaryFromParcelLocked(in); 13640 mGlobalWifiRunning = false; 13641 mGlobalWifiRunningTimer.readSummaryFromParcelLocked(in); 13642 for (int i=0; i<NUM_WIFI_STATES; i++) { 13643 mWifiStateTimer[i].readSummaryFromParcelLocked(in); 13644 } 13645 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) { 13646 mWifiSupplStateTimer[i].readSummaryFromParcelLocked(in); 13647 } 13648 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { 13649 mWifiSignalStrengthsTimer[i].readSummaryFromParcelLocked(in); 13650 } 13651 mWifiActiveTimer.readSummaryFromParcelLocked(in); 13652 mWifiActivity.readSummaryFromParcel(in); 13653 for (int i=0; i<GnssMetrics.NUM_GPS_SIGNAL_QUALITY_LEVELS; i++) { 13654 mGpsSignalQualityTimer[i].readSummaryFromParcelLocked(in); 13655 } 13656 mBluetoothActivity.readSummaryFromParcel(in); 13657 mModemActivity.readSummaryFromParcel(in); 13658 mHasWifiReporting = in.readInt() != 0; 13659 mHasBluetoothReporting = in.readInt() != 0; 13660 mHasModemReporting = in.readInt() != 0; 13661 13662 mNumConnectivityChange = in.readInt(); 13663 mFlashlightOnNesting = 0; 13664 mFlashlightOnTimer.readSummaryFromParcelLocked(in); 13665 mCameraOnNesting = 0; 13666 mCameraOnTimer.readSummaryFromParcelLocked(in); 13667 mBluetoothScanNesting = 0; 13668 mBluetoothScanTimer.readSummaryFromParcelLocked(in); 13669 13670 int NRPMS = in.readInt(); 13671 if (NRPMS > 10000) { 13672 throw new ParcelFormatException("File corrupt: too many rpm stats " + NRPMS); 13673 } 13674 for (int irpm = 0; irpm < NRPMS; irpm++) { 13675 if (in.readInt() != 0) { 13676 String rpmName = in.readString(); 13677 getRpmTimerLocked(rpmName).readSummaryFromParcelLocked(in); 13678 } 13679 } 13680 int NSORPMS = in.readInt(); 13681 if (NSORPMS > 10000) { 13682 throw new ParcelFormatException("File corrupt: too many screen-off rpm stats " + NSORPMS); 13683 } 13684 for (int irpm = 0; irpm < NSORPMS; irpm++) { 13685 if (in.readInt() != 0) { 13686 String rpmName = in.readString(); 13687 getScreenOffRpmTimerLocked(rpmName).readSummaryFromParcelLocked(in); 13688 } 13689 } 13690 13691 int NKW = in.readInt(); 13692 if (NKW > 10000) { 13693 throw new ParcelFormatException("File corrupt: too many kernel wake locks " + NKW); 13694 } 13695 for (int ikw = 0; ikw < NKW; ikw++) { 13696 if (in.readInt() != 0) { 13697 String kwltName = in.readString(); 13698 getKernelWakelockTimerLocked(kwltName).readSummaryFromParcelLocked(in); 13699 } 13700 } 13701 13702 int NWR = in.readInt(); 13703 if (NWR > 10000) { 13704 throw new ParcelFormatException("File corrupt: too many wakeup reasons " + NWR); 13705 } 13706 for (int iwr = 0; iwr < NWR; iwr++) { 13707 if (in.readInt() != 0) { 13708 String reasonName = in.readString(); 13709 getWakeupReasonTimerLocked(reasonName).readSummaryFromParcelLocked(in); 13710 } 13711 } 13712 13713 int NMS = in.readInt(); 13714 for (int ims = 0; ims < NMS; ims++) { 13715 if (in.readInt() != 0) { 13716 long kmstName = in.readLong(); 13717 getKernelMemoryTimerLocked(kmstName).readSummaryFromParcelLocked(in); 13718 } 13719 } 13720 13721 final int NU = in.readInt(); 13722 if (NU > 10000) { 13723 throw new ParcelFormatException("File corrupt: too many uids " + NU); 13724 } 13725 for (int iu = 0; iu < NU; iu++) { 13726 int uid = in.readInt(); 13727 Uid u = new Uid(this, uid); 13728 mUidStats.put(uid, u); 13729 13730 u.mOnBatteryBackgroundTimeBase.readSummaryFromParcel(in); 13731 u.mOnBatteryScreenOffBackgroundTimeBase.readSummaryFromParcel(in); 13732 13733 u.mWifiRunning = false; 13734 if (in.readInt() != 0) { 13735 u.mWifiRunningTimer.readSummaryFromParcelLocked(in); 13736 } 13737 u.mFullWifiLockOut = false; 13738 if (in.readInt() != 0) { 13739 u.mFullWifiLockTimer.readSummaryFromParcelLocked(in); 13740 } 13741 u.mWifiScanStarted = false; 13742 if (in.readInt() != 0) { 13743 u.mWifiScanTimer.readSummaryFromParcelLocked(in); 13744 } 13745 u.mWifiBatchedScanBinStarted = Uid.NO_BATCHED_SCAN_STARTED; 13746 for (int i = 0; i < Uid.NUM_WIFI_BATCHED_SCAN_BINS; i++) { 13747 if (in.readInt() != 0) { 13748 u.makeWifiBatchedScanBin(i, null); 13749 u.mWifiBatchedScanTimer[i].readSummaryFromParcelLocked(in); 13750 } 13751 } 13752 u.mWifiMulticastWakelockCount = 0; 13753 if (in.readInt() != 0) { 13754 u.mWifiMulticastTimer.readSummaryFromParcelLocked(in); 13755 } 13756 if (in.readInt() != 0) { 13757 u.createAudioTurnedOnTimerLocked().readSummaryFromParcelLocked(in); 13758 } 13759 if (in.readInt() != 0) { 13760 u.createVideoTurnedOnTimerLocked().readSummaryFromParcelLocked(in); 13761 } 13762 if (in.readInt() != 0) { 13763 u.createFlashlightTurnedOnTimerLocked().readSummaryFromParcelLocked(in); 13764 } 13765 if (in.readInt() != 0) { 13766 u.createCameraTurnedOnTimerLocked().readSummaryFromParcelLocked(in); 13767 } 13768 if (in.readInt() != 0) { 13769 u.createForegroundActivityTimerLocked().readSummaryFromParcelLocked(in); 13770 } 13771 if (in.readInt() != 0) { 13772 u.createForegroundServiceTimerLocked().readSummaryFromParcelLocked(in); 13773 } 13774 if (in.readInt() != 0) { 13775 u.createAggregatedPartialWakelockTimerLocked().readSummaryFromParcelLocked(in); 13776 } 13777 if (in.readInt() != 0) { 13778 u.createBluetoothScanTimerLocked().readSummaryFromParcelLocked(in); 13779 } 13780 if (in.readInt() != 0) { 13781 u.createBluetoothUnoptimizedScanTimerLocked().readSummaryFromParcelLocked(in); 13782 } 13783 if (in.readInt() != 0) { 13784 u.createBluetoothScanResultCounterLocked().readSummaryFromParcelLocked(in); 13785 } 13786 if (in.readInt() != 0) { 13787 u.createBluetoothScanResultBgCounterLocked().readSummaryFromParcelLocked(in); 13788 } 13789 u.mProcessState = ActivityManager.PROCESS_STATE_NONEXISTENT; 13790 for (int i = 0; i < Uid.NUM_PROCESS_STATE; i++) { 13791 if (in.readInt() != 0) { 13792 u.makeProcessState(i, null); 13793 u.mProcessStateTimer[i].readSummaryFromParcelLocked(in); 13794 } 13795 } 13796 if (in.readInt() != 0) { 13797 u.createVibratorOnTimerLocked().readSummaryFromParcelLocked(in); 13798 } 13799 13800 if (in.readInt() != 0) { 13801 if (u.mUserActivityCounters == null) { 13802 u.initUserActivityLocked(); 13803 } 13804 for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) { 13805 u.mUserActivityCounters[i].readSummaryFromParcelLocked(in); 13806 } 13807 } 13808 13809 if (in.readInt() != 0) { 13810 if (u.mNetworkByteActivityCounters == null) { 13811 u.initNetworkActivityLocked(); 13812 } 13813 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 13814 u.mNetworkByteActivityCounters[i].readSummaryFromParcelLocked(in); 13815 u.mNetworkPacketActivityCounters[i].readSummaryFromParcelLocked(in); 13816 } 13817 u.mMobileRadioActiveTime.readSummaryFromParcelLocked(in); 13818 u.mMobileRadioActiveCount.readSummaryFromParcelLocked(in); 13819 } 13820 13821 u.mUserCpuTime.readSummaryFromParcelLocked(in); 13822 u.mSystemCpuTime.readSummaryFromParcelLocked(in); 13823 13824 if (in.readInt() != 0) { 13825 final int numClusters = in.readInt(); 13826 if (mPowerProfile != null && mPowerProfile.getNumCpuClusters() != numClusters) { 13827 throw new ParcelFormatException("Incompatible cpu cluster arrangement"); 13828 } 13829 detachIfNotNull(u.mCpuClusterSpeedTimesUs); 13830 u.mCpuClusterSpeedTimesUs = new LongSamplingCounter[numClusters][]; 13831 for (int cluster = 0; cluster < numClusters; cluster++) { 13832 if (in.readInt() != 0) { 13833 final int NSB = in.readInt(); 13834 if (mPowerProfile != null && 13835 mPowerProfile.getNumSpeedStepsInCpuCluster(cluster) != NSB) { 13836 throw new ParcelFormatException("File corrupt: too many speed bins " + 13837 NSB); 13838 } 13839 13840 u.mCpuClusterSpeedTimesUs[cluster] = new LongSamplingCounter[NSB]; 13841 for (int speed = 0; speed < NSB; speed++) { 13842 if (in.readInt() != 0) { 13843 u.mCpuClusterSpeedTimesUs[cluster][speed] = new LongSamplingCounter( 13844 mOnBatteryTimeBase); 13845 u.mCpuClusterSpeedTimesUs[cluster][speed].readSummaryFromParcelLocked(in); 13846 } 13847 } 13848 } else { 13849 u.mCpuClusterSpeedTimesUs[cluster] = null; 13850 } 13851 } 13852 } else { 13853 detachIfNotNull(u.mCpuClusterSpeedTimesUs); 13854 u.mCpuClusterSpeedTimesUs = null; 13855 } 13856 13857 detachIfNotNull(u.mCpuFreqTimeMs); 13858 u.mCpuFreqTimeMs = LongSamplingCounterArray.readSummaryFromParcelLocked( 13859 in, mOnBatteryTimeBase); 13860 detachIfNotNull(u.mScreenOffCpuFreqTimeMs); 13861 u.mScreenOffCpuFreqTimeMs = LongSamplingCounterArray.readSummaryFromParcelLocked( 13862 in, mOnBatteryScreenOffTimeBase); 13863 13864 u.mCpuActiveTimeMs.readSummaryFromParcelLocked(in); 13865 u.mCpuClusterTimesMs.readSummaryFromParcelLocked(in); 13866 13867 int length = in.readInt(); 13868 if (length == Uid.NUM_PROCESS_STATE) { 13869 detachIfNotNull(u.mProcStateTimeMs); 13870 u.mProcStateTimeMs = new LongSamplingCounterArray[length]; 13871 for (int procState = 0; procState < length; ++procState) { 13872 u.mProcStateTimeMs[procState] 13873 = LongSamplingCounterArray.readSummaryFromParcelLocked( 13874 in, mOnBatteryTimeBase); 13875 } 13876 } else { 13877 detachIfNotNull(u.mProcStateTimeMs); 13878 u.mProcStateTimeMs = null; 13879 } 13880 length = in.readInt(); 13881 if (length == Uid.NUM_PROCESS_STATE) { 13882 detachIfNotNull(u.mProcStateScreenOffTimeMs); 13883 u.mProcStateScreenOffTimeMs = new LongSamplingCounterArray[length]; 13884 for (int procState = 0; procState < length; ++procState) { 13885 u.mProcStateScreenOffTimeMs[procState] 13886 = LongSamplingCounterArray.readSummaryFromParcelLocked( 13887 in, mOnBatteryScreenOffTimeBase); 13888 } 13889 } else { 13890 detachIfNotNull(u.mProcStateScreenOffTimeMs); 13891 u.mProcStateScreenOffTimeMs = null; 13892 } 13893 13894 if (in.readInt() != 0) { 13895 detachIfNotNull(u.mMobileRadioApWakeupCount); 13896 u.mMobileRadioApWakeupCount = new LongSamplingCounter(mOnBatteryTimeBase); 13897 u.mMobileRadioApWakeupCount.readSummaryFromParcelLocked(in); 13898 } else { 13899 detachIfNotNull(u.mMobileRadioApWakeupCount); 13900 u.mMobileRadioApWakeupCount = null; 13901 } 13902 13903 if (in.readInt() != 0) { 13904 detachIfNotNull(u.mWifiRadioApWakeupCount); 13905 u.mWifiRadioApWakeupCount = new LongSamplingCounter(mOnBatteryTimeBase); 13906 u.mWifiRadioApWakeupCount.readSummaryFromParcelLocked(in); 13907 } else { 13908 detachIfNotNull(u.mWifiRadioApWakeupCount); 13909 u.mWifiRadioApWakeupCount = null; 13910 } 13911 13912 int NW = in.readInt(); 13913 if (NW > (MAX_WAKELOCKS_PER_UID+1)) { 13914 throw new ParcelFormatException("File corrupt: too many wake locks " + NW); 13915 } 13916 for (int iw = 0; iw < NW; iw++) { 13917 String wlName = in.readString(); 13918 u.readWakeSummaryFromParcelLocked(wlName, in); 13919 } 13920 13921 int NS = in.readInt(); 13922 if (NS > (MAX_WAKELOCKS_PER_UID+1)) { 13923 throw new ParcelFormatException("File corrupt: too many syncs " + NS); 13924 } 13925 for (int is = 0; is < NS; is++) { 13926 String name = in.readString(); 13927 u.readSyncSummaryFromParcelLocked(name, in); 13928 } 13929 13930 int NJ = in.readInt(); 13931 if (NJ > (MAX_WAKELOCKS_PER_UID+1)) { 13932 throw new ParcelFormatException("File corrupt: too many job timers " + NJ); 13933 } 13934 for (int ij = 0; ij < NJ; ij++) { 13935 String name = in.readString(); 13936 u.readJobSummaryFromParcelLocked(name, in); 13937 } 13938 13939 u.readJobCompletionsFromParcelLocked(in); 13940 13941 u.mJobsDeferredEventCount.readSummaryFromParcelLocked(in); 13942 u.mJobsDeferredCount.readSummaryFromParcelLocked(in); 13943 u.mJobsFreshnessTimeMs.readSummaryFromParcelLocked(in); 13944 detachIfNotNull(u.mJobsFreshnessBuckets); 13945 for (int i = 0; i < JOB_FRESHNESS_BUCKETS.length; i++) { 13946 if (in.readInt() != 0) { 13947 u.mJobsFreshnessBuckets[i] = new Counter(u.mBsi.mOnBatteryTimeBase); 13948 u.mJobsFreshnessBuckets[i].readSummaryFromParcelLocked(in); 13949 } 13950 } 13951 13952 int NP = in.readInt(); 13953 if (NP > 1000) { 13954 throw new ParcelFormatException("File corrupt: too many sensors " + NP); 13955 } 13956 for (int is = 0; is < NP; is++) { 13957 int seNumber = in.readInt(); 13958 if (in.readInt() != 0) { 13959 u.getSensorTimerLocked(seNumber, true).readSummaryFromParcelLocked(in); 13960 } 13961 } 13962 13963 NP = in.readInt(); 13964 if (NP > 1000) { 13965 throw new ParcelFormatException("File corrupt: too many processes " + NP); 13966 } 13967 for (int ip = 0; ip < NP; ip++) { 13968 String procName = in.readString(); 13969 Uid.Proc p = u.getProcessStatsLocked(procName); 13970 p.mUserTime = in.readLong(); 13971 p.mSystemTime = in.readLong(); 13972 p.mForegroundTime = in.readLong(); 13973 p.mStarts = in.readInt(); 13974 p.mNumCrashes = in.readInt(); 13975 p.mNumAnrs = in.readInt(); 13976 p.readExcessivePowerFromParcelLocked(in); 13977 } 13978 13979 NP = in.readInt(); 13980 if (NP > 10000) { 13981 throw new ParcelFormatException("File corrupt: too many packages " + NP); 13982 } 13983 for (int ip = 0; ip < NP; ip++) { 13984 String pkgName = in.readString(); 13985 detachIfNotNull(u.mPackageStats.get(pkgName)); 13986 Uid.Pkg p = u.getPackageStatsLocked(pkgName); 13987 final int NWA = in.readInt(); 13988 if (NWA > 10000) { 13989 throw new ParcelFormatException("File corrupt: too many wakeup alarms " + NWA); 13990 } 13991 p.mWakeupAlarms.clear(); 13992 for (int iwa = 0; iwa < NWA; iwa++) { 13993 String tag = in.readString(); 13994 Counter c = new Counter(mOnBatteryScreenOffTimeBase); 13995 c.readSummaryFromParcelLocked(in); 13996 p.mWakeupAlarms.put(tag, c); 13997 } 13998 NS = in.readInt(); 13999 if (NS > 10000) { 14000 throw new ParcelFormatException("File corrupt: too many services " + NS); 14001 } 14002 for (int is = 0; is < NS; is++) { 14003 String servName = in.readString(); 14004 Uid.Pkg.Serv s = u.getServiceStatsLocked(pkgName, servName); 14005 s.mStartTime = in.readLong(); 14006 s.mStarts = in.readInt(); 14007 s.mLaunches = in.readInt(); 14008 } 14009 } 14010 } 14011 } 14012 14013 /** 14014 * Writes a summary of the statistics to a Parcel, in a format suitable to be written to 14015 * disk. This format does not allow a lossless round-trip. 14016 * 14017 * @param out the Parcel to be written to. 14018 */ writeSummaryToParcel(Parcel out, boolean inclHistory)14019 public void writeSummaryToParcel(Parcel out, boolean inclHistory) { 14020 pullPendingStateUpdatesLocked(); 14021 14022 // Pull the clock time. This may update the time and make a new history entry 14023 // if we had originally pulled a time before the RTC was set. 14024 getStartClockTime(); 14025 14026 final long NOW_SYS = mClocks.uptimeMillis() * 1000; 14027 final long NOWREAL_SYS = mClocks.elapsedRealtime() * 1000; 14028 14029 out.writeInt(VERSION); 14030 14031 out.writeBoolean(inclHistory); 14032 if (inclHistory) { 14033 writeHistoryBuffer(out, true, true); 14034 mBatteryStatsHistory.writeToParcel(out); 14035 } 14036 14037 out.writeInt(mHistoryTagPool.size()); 14038 for (HashMap.Entry<HistoryTag, Integer> ent : mHistoryTagPool.entrySet()) { 14039 HistoryTag tag = ent.getKey(); 14040 out.writeInt(ent.getValue()); 14041 out.writeString(tag.string); 14042 out.writeInt(tag.uid); 14043 } 14044 14045 out.writeInt(mStartCount); 14046 out.writeLong(computeUptime(NOW_SYS, STATS_SINCE_CHARGED)); 14047 out.writeLong(computeRealtime(NOWREAL_SYS, STATS_SINCE_CHARGED)); 14048 out.writeLong(mStartClockTime); 14049 out.writeString(mStartPlatformVersion); 14050 out.writeString(mEndPlatformVersion); 14051 mOnBatteryTimeBase.writeSummaryToParcel(out, NOW_SYS, NOWREAL_SYS); 14052 mOnBatteryScreenOffTimeBase.writeSummaryToParcel(out, NOW_SYS, NOWREAL_SYS); 14053 out.writeInt(mDischargeUnplugLevel); 14054 out.writeInt(mDischargePlugLevel); 14055 out.writeInt(mDischargeCurrentLevel); 14056 out.writeInt(mCurrentBatteryLevel); 14057 out.writeInt(mEstimatedBatteryCapacity); 14058 out.writeInt(mMinLearnedBatteryCapacity); 14059 out.writeInt(mMaxLearnedBatteryCapacity); 14060 out.writeInt(getLowDischargeAmountSinceCharge()); 14061 out.writeInt(getHighDischargeAmountSinceCharge()); 14062 out.writeInt(getDischargeAmountScreenOnSinceCharge()); 14063 out.writeInt(getDischargeAmountScreenOffSinceCharge()); 14064 out.writeInt(getDischargeAmountScreenDozeSinceCharge()); 14065 mDischargeStepTracker.writeToParcel(out); 14066 mChargeStepTracker.writeToParcel(out); 14067 mDailyDischargeStepTracker.writeToParcel(out); 14068 mDailyChargeStepTracker.writeToParcel(out); 14069 mDischargeCounter.writeSummaryFromParcelLocked(out); 14070 mDischargeScreenOffCounter.writeSummaryFromParcelLocked(out); 14071 mDischargeScreenDozeCounter.writeSummaryFromParcelLocked(out); 14072 mDischargeLightDozeCounter.writeSummaryFromParcelLocked(out); 14073 mDischargeDeepDozeCounter.writeSummaryFromParcelLocked(out); 14074 if (mDailyPackageChanges != null) { 14075 final int NPKG = mDailyPackageChanges.size(); 14076 out.writeInt(NPKG); 14077 for (int i=0; i<NPKG; i++) { 14078 PackageChange pc = mDailyPackageChanges.get(i); 14079 out.writeString(pc.mPackageName); 14080 out.writeInt(pc.mUpdate ? 1 : 0); 14081 out.writeLong(pc.mVersionCode); 14082 } 14083 } else { 14084 out.writeInt(0); 14085 } 14086 out.writeLong(mDailyStartTime); 14087 out.writeLong(mNextMinDailyDeadline); 14088 out.writeLong(mNextMaxDailyDeadline); 14089 14090 mScreenOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14091 mScreenDozeTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14092 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 14093 mScreenBrightnessTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14094 } 14095 mInteractiveTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14096 mPowerSaveModeEnabledTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14097 out.writeLong(mLongestLightIdleTime); 14098 out.writeLong(mLongestFullIdleTime); 14099 mDeviceIdleModeLightTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14100 mDeviceIdleModeFullTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14101 mDeviceLightIdlingTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14102 mDeviceIdlingTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14103 mPhoneOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14104 for (int i = 0; i < CellSignalStrength.getNumSignalStrengthLevels(); i++) { 14105 mPhoneSignalStrengthsTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14106 } 14107 mPhoneSignalScanningTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14108 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 14109 mPhoneDataConnectionsTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14110 } 14111 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 14112 mNetworkByteActivityCounters[i].writeSummaryFromParcelLocked(out); 14113 mNetworkPacketActivityCounters[i].writeSummaryFromParcelLocked(out); 14114 } 14115 mMobileRadioActiveTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14116 mMobileRadioActivePerAppTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14117 mMobileRadioActiveAdjustedTime.writeSummaryFromParcelLocked(out); 14118 mMobileRadioActiveUnknownTime.writeSummaryFromParcelLocked(out); 14119 mMobileRadioActiveUnknownCount.writeSummaryFromParcelLocked(out); 14120 mWifiMulticastWakelockTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14121 mWifiOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14122 mGlobalWifiRunningTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14123 for (int i=0; i<NUM_WIFI_STATES; i++) { 14124 mWifiStateTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14125 } 14126 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) { 14127 mWifiSupplStateTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14128 } 14129 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { 14130 mWifiSignalStrengthsTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14131 } 14132 mWifiActiveTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14133 mWifiActivity.writeSummaryToParcel(out); 14134 for (int i=0; i< GnssMetrics.NUM_GPS_SIGNAL_QUALITY_LEVELS; i++) { 14135 mGpsSignalQualityTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14136 } 14137 mBluetoothActivity.writeSummaryToParcel(out); 14138 mModemActivity.writeSummaryToParcel(out); 14139 out.writeInt(mHasWifiReporting ? 1 : 0); 14140 out.writeInt(mHasBluetoothReporting ? 1 : 0); 14141 out.writeInt(mHasModemReporting ? 1 : 0); 14142 14143 out.writeInt(mNumConnectivityChange); 14144 mFlashlightOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14145 mCameraOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14146 mBluetoothScanTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14147 14148 out.writeInt(mRpmStats.size()); 14149 for (Map.Entry<String, SamplingTimer> ent : mRpmStats.entrySet()) { 14150 Timer rpmt = ent.getValue(); 14151 if (rpmt != null) { 14152 out.writeInt(1); 14153 out.writeString(ent.getKey()); 14154 rpmt.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14155 } else { 14156 out.writeInt(0); 14157 } 14158 } 14159 out.writeInt(mScreenOffRpmStats.size()); 14160 for (Map.Entry<String, SamplingTimer> ent : mScreenOffRpmStats.entrySet()) { 14161 Timer rpmt = ent.getValue(); 14162 if (rpmt != null) { 14163 out.writeInt(1); 14164 out.writeString(ent.getKey()); 14165 rpmt.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14166 } else { 14167 out.writeInt(0); 14168 } 14169 } 14170 14171 out.writeInt(mKernelWakelockStats.size()); 14172 for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) { 14173 Timer kwlt = ent.getValue(); 14174 if (kwlt != null) { 14175 out.writeInt(1); 14176 out.writeString(ent.getKey()); 14177 kwlt.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14178 } else { 14179 out.writeInt(0); 14180 } 14181 } 14182 14183 out.writeInt(mWakeupReasonStats.size()); 14184 for (Map.Entry<String, SamplingTimer> ent : mWakeupReasonStats.entrySet()) { 14185 SamplingTimer timer = ent.getValue(); 14186 if (timer != null) { 14187 out.writeInt(1); 14188 out.writeString(ent.getKey()); 14189 timer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14190 } else { 14191 out.writeInt(0); 14192 } 14193 } 14194 14195 out.writeInt(mKernelMemoryStats.size()); 14196 for (int i = 0; i < mKernelMemoryStats.size(); i++) { 14197 Timer kmt = mKernelMemoryStats.valueAt(i); 14198 if (kmt != null) { 14199 out.writeInt(1); 14200 out.writeLong(mKernelMemoryStats.keyAt(i)); 14201 kmt.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14202 } else { 14203 out.writeInt(0); 14204 } 14205 } 14206 14207 final int NU = mUidStats.size(); 14208 out.writeInt(NU); 14209 for (int iu = 0; iu < NU; iu++) { 14210 out.writeInt(mUidStats.keyAt(iu)); 14211 Uid u = mUidStats.valueAt(iu); 14212 14213 u.mOnBatteryBackgroundTimeBase.writeSummaryToParcel(out, NOW_SYS, NOWREAL_SYS); 14214 u.mOnBatteryScreenOffBackgroundTimeBase.writeSummaryToParcel(out, NOW_SYS, NOWREAL_SYS); 14215 14216 if (u.mWifiRunningTimer != null) { 14217 out.writeInt(1); 14218 u.mWifiRunningTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14219 } else { 14220 out.writeInt(0); 14221 } 14222 if (u.mFullWifiLockTimer != null) { 14223 out.writeInt(1); 14224 u.mFullWifiLockTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14225 } else { 14226 out.writeInt(0); 14227 } 14228 if (u.mWifiScanTimer != null) { 14229 out.writeInt(1); 14230 u.mWifiScanTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14231 } else { 14232 out.writeInt(0); 14233 } 14234 for (int i = 0; i < Uid.NUM_WIFI_BATCHED_SCAN_BINS; i++) { 14235 if (u.mWifiBatchedScanTimer[i] != null) { 14236 out.writeInt(1); 14237 u.mWifiBatchedScanTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14238 } else { 14239 out.writeInt(0); 14240 } 14241 } 14242 if (u.mWifiMulticastTimer != null) { 14243 out.writeInt(1); 14244 u.mWifiMulticastTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14245 } else { 14246 out.writeInt(0); 14247 } 14248 if (u.mAudioTurnedOnTimer != null) { 14249 out.writeInt(1); 14250 u.mAudioTurnedOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14251 } else { 14252 out.writeInt(0); 14253 } 14254 if (u.mVideoTurnedOnTimer != null) { 14255 out.writeInt(1); 14256 u.mVideoTurnedOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14257 } else { 14258 out.writeInt(0); 14259 } 14260 if (u.mFlashlightTurnedOnTimer != null) { 14261 out.writeInt(1); 14262 u.mFlashlightTurnedOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14263 } else { 14264 out.writeInt(0); 14265 } 14266 if (u.mCameraTurnedOnTimer != null) { 14267 out.writeInt(1); 14268 u.mCameraTurnedOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14269 } else { 14270 out.writeInt(0); 14271 } 14272 if (u.mForegroundActivityTimer != null) { 14273 out.writeInt(1); 14274 u.mForegroundActivityTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14275 } else { 14276 out.writeInt(0); 14277 } 14278 if (u.mForegroundServiceTimer != null) { 14279 out.writeInt(1); 14280 u.mForegroundServiceTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14281 } else { 14282 out.writeInt(0); 14283 } 14284 if (u.mAggregatedPartialWakelockTimer != null) { 14285 out.writeInt(1); 14286 u.mAggregatedPartialWakelockTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14287 } else { 14288 out.writeInt(0); 14289 } 14290 if (u.mBluetoothScanTimer != null) { 14291 out.writeInt(1); 14292 u.mBluetoothScanTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14293 } else { 14294 out.writeInt(0); 14295 } 14296 if (u.mBluetoothUnoptimizedScanTimer != null) { 14297 out.writeInt(1); 14298 u.mBluetoothUnoptimizedScanTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14299 } else { 14300 out.writeInt(0); 14301 } 14302 if (u.mBluetoothScanResultCounter != null) { 14303 out.writeInt(1); 14304 u.mBluetoothScanResultCounter.writeSummaryFromParcelLocked(out); 14305 } else { 14306 out.writeInt(0); 14307 } 14308 if (u.mBluetoothScanResultBgCounter != null) { 14309 out.writeInt(1); 14310 u.mBluetoothScanResultBgCounter.writeSummaryFromParcelLocked(out); 14311 } else { 14312 out.writeInt(0); 14313 } 14314 for (int i = 0; i < Uid.NUM_PROCESS_STATE; i++) { 14315 if (u.mProcessStateTimer[i] != null) { 14316 out.writeInt(1); 14317 u.mProcessStateTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14318 } else { 14319 out.writeInt(0); 14320 } 14321 } 14322 if (u.mVibratorOnTimer != null) { 14323 out.writeInt(1); 14324 u.mVibratorOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14325 } else { 14326 out.writeInt(0); 14327 } 14328 14329 if (u.mUserActivityCounters == null) { 14330 out.writeInt(0); 14331 } else { 14332 out.writeInt(1); 14333 for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) { 14334 u.mUserActivityCounters[i].writeSummaryFromParcelLocked(out); 14335 } 14336 } 14337 14338 if (u.mNetworkByteActivityCounters == null) { 14339 out.writeInt(0); 14340 } else { 14341 out.writeInt(1); 14342 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 14343 u.mNetworkByteActivityCounters[i].writeSummaryFromParcelLocked(out); 14344 u.mNetworkPacketActivityCounters[i].writeSummaryFromParcelLocked(out); 14345 } 14346 u.mMobileRadioActiveTime.writeSummaryFromParcelLocked(out); 14347 u.mMobileRadioActiveCount.writeSummaryFromParcelLocked(out); 14348 } 14349 14350 u.mUserCpuTime.writeSummaryFromParcelLocked(out); 14351 u.mSystemCpuTime.writeSummaryFromParcelLocked(out); 14352 14353 if (u.mCpuClusterSpeedTimesUs != null) { 14354 out.writeInt(1); 14355 out.writeInt(u.mCpuClusterSpeedTimesUs.length); 14356 for (LongSamplingCounter[] cpuSpeeds : u.mCpuClusterSpeedTimesUs) { 14357 if (cpuSpeeds != null) { 14358 out.writeInt(1); 14359 out.writeInt(cpuSpeeds.length); 14360 for (LongSamplingCounter c : cpuSpeeds) { 14361 if (c != null) { 14362 out.writeInt(1); 14363 c.writeSummaryFromParcelLocked(out); 14364 } else { 14365 out.writeInt(0); 14366 } 14367 } 14368 } else { 14369 out.writeInt(0); 14370 } 14371 } 14372 } else { 14373 out.writeInt(0); 14374 } 14375 14376 LongSamplingCounterArray.writeSummaryToParcelLocked(out, u.mCpuFreqTimeMs); 14377 LongSamplingCounterArray.writeSummaryToParcelLocked(out, u.mScreenOffCpuFreqTimeMs); 14378 14379 u.mCpuActiveTimeMs.writeSummaryFromParcelLocked(out); 14380 u.mCpuClusterTimesMs.writeSummaryToParcelLocked(out); 14381 14382 if (u.mProcStateTimeMs != null) { 14383 out.writeInt(u.mProcStateTimeMs.length); 14384 for (LongSamplingCounterArray counters : u.mProcStateTimeMs) { 14385 LongSamplingCounterArray.writeSummaryToParcelLocked(out, counters); 14386 } 14387 } else { 14388 out.writeInt(0); 14389 } 14390 if (u.mProcStateScreenOffTimeMs != null) { 14391 out.writeInt(u.mProcStateScreenOffTimeMs.length); 14392 for (LongSamplingCounterArray counters : u.mProcStateScreenOffTimeMs) { 14393 LongSamplingCounterArray.writeSummaryToParcelLocked(out, counters); 14394 } 14395 } else { 14396 out.writeInt(0); 14397 } 14398 14399 if (u.mMobileRadioApWakeupCount != null) { 14400 out.writeInt(1); 14401 u.mMobileRadioApWakeupCount.writeSummaryFromParcelLocked(out); 14402 } else { 14403 out.writeInt(0); 14404 } 14405 14406 if (u.mWifiRadioApWakeupCount != null) { 14407 out.writeInt(1); 14408 u.mWifiRadioApWakeupCount.writeSummaryFromParcelLocked(out); 14409 } else { 14410 out.writeInt(0); 14411 } 14412 14413 final ArrayMap<String, Uid.Wakelock> wakeStats = u.mWakelockStats.getMap(); 14414 int NW = wakeStats.size(); 14415 out.writeInt(NW); 14416 for (int iw=0; iw<NW; iw++) { 14417 out.writeString(wakeStats.keyAt(iw)); 14418 Uid.Wakelock wl = wakeStats.valueAt(iw); 14419 if (wl.mTimerFull != null) { 14420 out.writeInt(1); 14421 wl.mTimerFull.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14422 } else { 14423 out.writeInt(0); 14424 } 14425 if (wl.mTimerPartial != null) { 14426 out.writeInt(1); 14427 wl.mTimerPartial.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14428 } else { 14429 out.writeInt(0); 14430 } 14431 if (wl.mTimerWindow != null) { 14432 out.writeInt(1); 14433 wl.mTimerWindow.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14434 } else { 14435 out.writeInt(0); 14436 } 14437 if (wl.mTimerDraw != null) { 14438 out.writeInt(1); 14439 wl.mTimerDraw.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14440 } else { 14441 out.writeInt(0); 14442 } 14443 } 14444 14445 final ArrayMap<String, DualTimer> syncStats = u.mSyncStats.getMap(); 14446 int NS = syncStats.size(); 14447 out.writeInt(NS); 14448 for (int is=0; is<NS; is++) { 14449 out.writeString(syncStats.keyAt(is)); 14450 syncStats.valueAt(is).writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14451 } 14452 14453 final ArrayMap<String, DualTimer> jobStats = u.mJobStats.getMap(); 14454 int NJ = jobStats.size(); 14455 out.writeInt(NJ); 14456 for (int ij=0; ij<NJ; ij++) { 14457 out.writeString(jobStats.keyAt(ij)); 14458 jobStats.valueAt(ij).writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14459 } 14460 14461 u.writeJobCompletionsToParcelLocked(out); 14462 14463 u.mJobsDeferredEventCount.writeSummaryFromParcelLocked(out); 14464 u.mJobsDeferredCount.writeSummaryFromParcelLocked(out); 14465 u.mJobsFreshnessTimeMs.writeSummaryFromParcelLocked(out); 14466 for (int i = 0; i < JOB_FRESHNESS_BUCKETS.length; i++) { 14467 if (u.mJobsFreshnessBuckets[i] != null) { 14468 out.writeInt(1); 14469 u.mJobsFreshnessBuckets[i].writeSummaryFromParcelLocked(out); 14470 } else { 14471 out.writeInt(0); 14472 } 14473 } 14474 14475 int NSE = u.mSensorStats.size(); 14476 out.writeInt(NSE); 14477 for (int ise=0; ise<NSE; ise++) { 14478 out.writeInt(u.mSensorStats.keyAt(ise)); 14479 Uid.Sensor se = u.mSensorStats.valueAt(ise); 14480 if (se.mTimer != null) { 14481 out.writeInt(1); 14482 se.mTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14483 } else { 14484 out.writeInt(0); 14485 } 14486 } 14487 14488 int NP = u.mProcessStats.size(); 14489 out.writeInt(NP); 14490 for (int ip=0; ip<NP; ip++) { 14491 out.writeString(u.mProcessStats.keyAt(ip)); 14492 Uid.Proc ps = u.mProcessStats.valueAt(ip); 14493 out.writeLong(ps.mUserTime); 14494 out.writeLong(ps.mSystemTime); 14495 out.writeLong(ps.mForegroundTime); 14496 out.writeInt(ps.mStarts); 14497 out.writeInt(ps.mNumCrashes); 14498 out.writeInt(ps.mNumAnrs); 14499 ps.writeExcessivePowerToParcelLocked(out); 14500 } 14501 14502 NP = u.mPackageStats.size(); 14503 out.writeInt(NP); 14504 if (NP > 0) { 14505 for (Map.Entry<String, BatteryStatsImpl.Uid.Pkg> ent 14506 : u.mPackageStats.entrySet()) { 14507 out.writeString(ent.getKey()); 14508 Uid.Pkg ps = ent.getValue(); 14509 final int NWA = ps.mWakeupAlarms.size(); 14510 out.writeInt(NWA); 14511 for (int iwa=0; iwa<NWA; iwa++) { 14512 out.writeString(ps.mWakeupAlarms.keyAt(iwa)); 14513 ps.mWakeupAlarms.valueAt(iwa).writeSummaryFromParcelLocked(out); 14514 } 14515 NS = ps.mServiceStats.size(); 14516 out.writeInt(NS); 14517 for (int is=0; is<NS; is++) { 14518 out.writeString(ps.mServiceStats.keyAt(is)); 14519 BatteryStatsImpl.Uid.Pkg.Serv ss = ps.mServiceStats.valueAt(is); 14520 long time = ss.getStartTimeToNowLocked( 14521 mOnBatteryTimeBase.getUptime(NOW_SYS)); 14522 out.writeLong(time); 14523 out.writeInt(ss.mStarts); 14524 out.writeInt(ss.mLaunches); 14525 } 14526 } 14527 } 14528 } 14529 } 14530 readFromParcel(Parcel in)14531 public void readFromParcel(Parcel in) { 14532 readFromParcelLocked(in); 14533 } 14534 readFromParcelLocked(Parcel in)14535 void readFromParcelLocked(Parcel in) { 14536 int magic = in.readInt(); 14537 if (magic != MAGIC) { 14538 throw new ParcelFormatException("Bad magic number: #" + Integer.toHexString(magic)); 14539 } 14540 14541 readHistoryBuffer(in, false); 14542 mBatteryStatsHistory.readFromParcel(in); 14543 14544 mStartCount = in.readInt(); 14545 mStartClockTime = in.readLong(); 14546 mStartPlatformVersion = in.readString(); 14547 mEndPlatformVersion = in.readString(); 14548 mUptime = in.readLong(); 14549 mUptimeStart = in.readLong(); 14550 mRealtime = in.readLong(); 14551 mRealtimeStart = in.readLong(); 14552 mOnBattery = in.readInt() != 0; 14553 mEstimatedBatteryCapacity = in.readInt(); 14554 mMinLearnedBatteryCapacity = in.readInt(); 14555 mMaxLearnedBatteryCapacity = in.readInt(); 14556 mOnBatteryInternal = false; // we are no longer really running. 14557 mOnBatteryTimeBase.readFromParcel(in); 14558 mOnBatteryScreenOffTimeBase.readFromParcel(in); 14559 14560 mScreenState = Display.STATE_UNKNOWN; 14561 mScreenOnTimer = new StopwatchTimer(mClocks, null, -1, null, mOnBatteryTimeBase, in); 14562 mScreenDozeTimer = new StopwatchTimer(mClocks, null, -1, null, mOnBatteryTimeBase, in); 14563 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 14564 mScreenBrightnessTimer[i] = new StopwatchTimer(mClocks, null, -100-i, null, 14565 mOnBatteryTimeBase, in); 14566 } 14567 mInteractive = false; 14568 mInteractiveTimer = new StopwatchTimer(mClocks, null, -10, null, mOnBatteryTimeBase, in); 14569 mPhoneOn = false; 14570 mPowerSaveModeEnabledTimer = new StopwatchTimer(mClocks, null, -2, null, 14571 mOnBatteryTimeBase, in); 14572 mLongestLightIdleTime = in.readLong(); 14573 mLongestFullIdleTime = in.readLong(); 14574 mDeviceIdleModeLightTimer = new StopwatchTimer(mClocks, null, -14, null, 14575 mOnBatteryTimeBase, in); 14576 mDeviceIdleModeFullTimer = new StopwatchTimer(mClocks, null, -11, null, 14577 mOnBatteryTimeBase, in); 14578 mDeviceLightIdlingTimer = new StopwatchTimer(mClocks, null, -15, null, 14579 mOnBatteryTimeBase, in); 14580 mDeviceIdlingTimer = new StopwatchTimer(mClocks, null, -12, null, mOnBatteryTimeBase, in); 14581 mPhoneOnTimer = new StopwatchTimer(mClocks, null, -3, null, mOnBatteryTimeBase, in); 14582 for (int i = 0; i < CellSignalStrength.getNumSignalStrengthLevels(); i++) { 14583 mPhoneSignalStrengthsTimer[i] = new StopwatchTimer(mClocks, null, -200-i, 14584 null, mOnBatteryTimeBase, in); 14585 } 14586 mPhoneSignalScanningTimer = new StopwatchTimer(mClocks, null, -200+1, null, 14587 mOnBatteryTimeBase, in); 14588 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 14589 mPhoneDataConnectionsTimer[i] = new StopwatchTimer(mClocks, null, -300-i, 14590 null, mOnBatteryTimeBase, in); 14591 } 14592 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 14593 mNetworkByteActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase, in); 14594 mNetworkPacketActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase, in); 14595 } 14596 mMobileRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW; 14597 mMobileRadioActiveTimer = new StopwatchTimer(mClocks, null, -400, null, 14598 mOnBatteryTimeBase, in); 14599 mMobileRadioActivePerAppTimer = new StopwatchTimer(mClocks, null, -401, null, 14600 mOnBatteryTimeBase, in); 14601 mMobileRadioActiveAdjustedTime = new LongSamplingCounter(mOnBatteryTimeBase, in); 14602 mMobileRadioActiveUnknownTime = new LongSamplingCounter(mOnBatteryTimeBase, in); 14603 mMobileRadioActiveUnknownCount = new LongSamplingCounter(mOnBatteryTimeBase, in); 14604 mWifiMulticastWakelockTimer = new StopwatchTimer(mClocks, null, -4, null, 14605 mOnBatteryTimeBase, in); 14606 mWifiRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW; 14607 mWifiOn = false; 14608 mWifiOnTimer = new StopwatchTimer(mClocks, null, -4, null, mOnBatteryTimeBase, in); 14609 mGlobalWifiRunning = false; 14610 mGlobalWifiRunningTimer = new StopwatchTimer(mClocks, null, -5, null, 14611 mOnBatteryTimeBase, in); 14612 for (int i=0; i<NUM_WIFI_STATES; i++) { 14613 mWifiStateTimer[i] = new StopwatchTimer(mClocks, null, -600-i, 14614 null, mOnBatteryTimeBase, in); 14615 } 14616 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) { 14617 mWifiSupplStateTimer[i] = new StopwatchTimer(mClocks, null, -700-i, 14618 null, mOnBatteryTimeBase, in); 14619 } 14620 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { 14621 mWifiSignalStrengthsTimer[i] = new StopwatchTimer(mClocks, null, -800-i, 14622 null, mOnBatteryTimeBase, in); 14623 } 14624 mWifiActiveTimer = new StopwatchTimer(mClocks, null, -900, null, 14625 mOnBatteryTimeBase, in); 14626 mWifiActivity = new ControllerActivityCounterImpl(mOnBatteryTimeBase, 14627 NUM_WIFI_TX_LEVELS, in); 14628 for (int i=0; i<GnssMetrics.NUM_GPS_SIGNAL_QUALITY_LEVELS; i++) { 14629 mGpsSignalQualityTimer[i] = new StopwatchTimer(mClocks, null, -1000-i, 14630 null, mOnBatteryTimeBase, in); 14631 } 14632 mBluetoothActivity = new ControllerActivityCounterImpl(mOnBatteryTimeBase, 14633 NUM_BT_TX_LEVELS, in); 14634 mModemActivity = new ControllerActivityCounterImpl(mOnBatteryTimeBase, 14635 ModemActivityInfo.TX_POWER_LEVELS, in); 14636 mHasWifiReporting = in.readInt() != 0; 14637 mHasBluetoothReporting = in.readInt() != 0; 14638 mHasModemReporting = in.readInt() != 0; 14639 14640 mNumConnectivityChange = in.readInt(); 14641 mAudioOnNesting = 0; 14642 // TODO: It's likely a mistake that mAudioOnTimer/mVideoOnTimer don't write/read to parcel! 14643 mAudioOnTimer = new StopwatchTimer(mClocks, null, -7, null, mOnBatteryTimeBase); 14644 mVideoOnNesting = 0; 14645 mVideoOnTimer = new StopwatchTimer(mClocks, null, -8, null, mOnBatteryTimeBase); 14646 mFlashlightOnNesting = 0; 14647 mFlashlightOnTimer = new StopwatchTimer(mClocks, null, -9, null, mOnBatteryTimeBase, in); 14648 mCameraOnNesting = 0; 14649 mCameraOnTimer = new StopwatchTimer(mClocks, null, -13, null, mOnBatteryTimeBase, in); 14650 mBluetoothScanNesting = 0; 14651 mBluetoothScanTimer = new StopwatchTimer(mClocks, null, -14, null, mOnBatteryTimeBase, in); 14652 mDischargeUnplugLevel = in.readInt(); 14653 mDischargePlugLevel = in.readInt(); 14654 mDischargeCurrentLevel = in.readInt(); 14655 mCurrentBatteryLevel = in.readInt(); 14656 mLowDischargeAmountSinceCharge = in.readInt(); 14657 mHighDischargeAmountSinceCharge = in.readInt(); 14658 mDischargeAmountScreenOn = in.readInt(); 14659 mDischargeAmountScreenOnSinceCharge = in.readInt(); 14660 mDischargeAmountScreenOff = in.readInt(); 14661 mDischargeAmountScreenOffSinceCharge = in.readInt(); 14662 mDischargeAmountScreenDoze = in.readInt(); 14663 mDischargeAmountScreenDozeSinceCharge = in.readInt(); 14664 mDischargeStepTracker.readFromParcel(in); 14665 mChargeStepTracker.readFromParcel(in); 14666 mDischargeCounter = new LongSamplingCounter(mOnBatteryTimeBase, in); 14667 mDischargeScreenOffCounter = new LongSamplingCounter(mOnBatteryScreenOffTimeBase, in); 14668 mDischargeScreenDozeCounter = new LongSamplingCounter(mOnBatteryTimeBase, in); 14669 mDischargeLightDozeCounter = new LongSamplingCounter(mOnBatteryTimeBase, in); 14670 mDischargeDeepDozeCounter = new LongSamplingCounter(mOnBatteryTimeBase, in); 14671 mLastWriteTime = in.readLong(); 14672 14673 mRpmStats.clear(); 14674 int NRPMS = in.readInt(); 14675 for (int irpm = 0; irpm < NRPMS; irpm++) { 14676 if (in.readInt() != 0) { 14677 String rpmName = in.readString(); 14678 SamplingTimer rpmt = new SamplingTimer(mClocks, mOnBatteryTimeBase, in); 14679 mRpmStats.put(rpmName, rpmt); 14680 } 14681 } 14682 mScreenOffRpmStats.clear(); 14683 int NSORPMS = in.readInt(); 14684 for (int irpm = 0; irpm < NSORPMS; irpm++) { 14685 if (in.readInt() != 0) { 14686 String rpmName = in.readString(); 14687 SamplingTimer rpmt = new SamplingTimer(mClocks, mOnBatteryScreenOffTimeBase, in); 14688 mScreenOffRpmStats.put(rpmName, rpmt); 14689 } 14690 } 14691 14692 mKernelWakelockStats.clear(); 14693 int NKW = in.readInt(); 14694 for (int ikw = 0; ikw < NKW; ikw++) { 14695 if (in.readInt() != 0) { 14696 String wakelockName = in.readString(); 14697 SamplingTimer kwlt = new SamplingTimer(mClocks, mOnBatteryScreenOffTimeBase, in); 14698 mKernelWakelockStats.put(wakelockName, kwlt); 14699 } 14700 } 14701 14702 mWakeupReasonStats.clear(); 14703 int NWR = in.readInt(); 14704 for (int iwr = 0; iwr < NWR; iwr++) { 14705 if (in.readInt() != 0) { 14706 String reasonName = in.readString(); 14707 SamplingTimer timer = new SamplingTimer(mClocks, mOnBatteryTimeBase, in); 14708 mWakeupReasonStats.put(reasonName, timer); 14709 } 14710 } 14711 14712 mKernelMemoryStats.clear(); 14713 int nmt = in.readInt(); 14714 for (int imt = 0; imt < nmt; imt++) { 14715 if (in.readInt() != 0) { 14716 Long bucket = in.readLong(); 14717 SamplingTimer kmt = new SamplingTimer(mClocks, mOnBatteryTimeBase, in); 14718 mKernelMemoryStats.put(bucket, kmt); 14719 } 14720 } 14721 14722 mPartialTimers.clear(); 14723 mFullTimers.clear(); 14724 mWindowTimers.clear(); 14725 mWifiRunningTimers.clear(); 14726 mFullWifiLockTimers.clear(); 14727 mWifiScanTimers.clear(); 14728 mWifiBatchedScanTimers.clear(); 14729 mWifiMulticastTimers.clear(); 14730 mAudioTurnedOnTimers.clear(); 14731 mVideoTurnedOnTimers.clear(); 14732 mFlashlightTurnedOnTimers.clear(); 14733 mCameraTurnedOnTimers.clear(); 14734 14735 int numUids = in.readInt(); 14736 mUidStats.clear(); 14737 for (int i = 0; i < numUids; i++) { 14738 int uid = in.readInt(); 14739 Uid u = new Uid(this, uid); 14740 u.readFromParcelLocked(mOnBatteryTimeBase, mOnBatteryScreenOffTimeBase, in); 14741 mUidStats.append(uid, u); 14742 } 14743 } 14744 writeToParcel(Parcel out, int flags)14745 public void writeToParcel(Parcel out, int flags) { 14746 writeToParcelLocked(out, true, flags); 14747 } 14748 writeToParcelWithoutUids(Parcel out, int flags)14749 public void writeToParcelWithoutUids(Parcel out, int flags) { 14750 writeToParcelLocked(out, false, flags); 14751 } 14752 14753 @SuppressWarnings("unused") writeToParcelLocked(Parcel out, boolean inclUids, int flags)14754 void writeToParcelLocked(Parcel out, boolean inclUids, int flags) { 14755 // Need to update with current kernel wake lock counts. 14756 pullPendingStateUpdatesLocked(); 14757 14758 // Pull the clock time. This may update the time and make a new history entry 14759 // if we had originally pulled a time before the RTC was set. 14760 getStartClockTime(); 14761 14762 final long uSecUptime = mClocks.uptimeMillis() * 1000; 14763 final long uSecRealtime = mClocks.elapsedRealtime() * 1000; 14764 final long batteryRealtime = mOnBatteryTimeBase.getRealtime(uSecRealtime); 14765 final long batteryScreenOffRealtime = mOnBatteryScreenOffTimeBase.getRealtime(uSecRealtime); 14766 14767 out.writeInt(MAGIC); 14768 14769 writeHistoryBuffer(out, true, false); 14770 mBatteryStatsHistory.writeToParcel(out); 14771 14772 out.writeInt(mStartCount); 14773 out.writeLong(mStartClockTime); 14774 out.writeString(mStartPlatformVersion); 14775 out.writeString(mEndPlatformVersion); 14776 out.writeLong(mUptime); 14777 out.writeLong(mUptimeStart); 14778 out.writeLong(mRealtime); 14779 out.writeLong(mRealtimeStart); 14780 out.writeInt(mOnBattery ? 1 : 0); 14781 out.writeInt(mEstimatedBatteryCapacity); 14782 out.writeInt(mMinLearnedBatteryCapacity); 14783 out.writeInt(mMaxLearnedBatteryCapacity); 14784 mOnBatteryTimeBase.writeToParcel(out, uSecUptime, uSecRealtime); 14785 mOnBatteryScreenOffTimeBase.writeToParcel(out, uSecUptime, uSecRealtime); 14786 14787 mScreenOnTimer.writeToParcel(out, uSecRealtime); 14788 mScreenDozeTimer.writeToParcel(out, uSecRealtime); 14789 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 14790 mScreenBrightnessTimer[i].writeToParcel(out, uSecRealtime); 14791 } 14792 mInteractiveTimer.writeToParcel(out, uSecRealtime); 14793 mPowerSaveModeEnabledTimer.writeToParcel(out, uSecRealtime); 14794 out.writeLong(mLongestLightIdleTime); 14795 out.writeLong(mLongestFullIdleTime); 14796 mDeviceIdleModeLightTimer.writeToParcel(out, uSecRealtime); 14797 mDeviceIdleModeFullTimer.writeToParcel(out, uSecRealtime); 14798 mDeviceLightIdlingTimer.writeToParcel(out, uSecRealtime); 14799 mDeviceIdlingTimer.writeToParcel(out, uSecRealtime); 14800 mPhoneOnTimer.writeToParcel(out, uSecRealtime); 14801 for (int i = 0; i < CellSignalStrength.getNumSignalStrengthLevels(); i++) { 14802 mPhoneSignalStrengthsTimer[i].writeToParcel(out, uSecRealtime); 14803 } 14804 mPhoneSignalScanningTimer.writeToParcel(out, uSecRealtime); 14805 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 14806 mPhoneDataConnectionsTimer[i].writeToParcel(out, uSecRealtime); 14807 } 14808 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 14809 mNetworkByteActivityCounters[i].writeToParcel(out); 14810 mNetworkPacketActivityCounters[i].writeToParcel(out); 14811 } 14812 mMobileRadioActiveTimer.writeToParcel(out, uSecRealtime); 14813 mMobileRadioActivePerAppTimer.writeToParcel(out, uSecRealtime); 14814 mMobileRadioActiveAdjustedTime.writeToParcel(out); 14815 mMobileRadioActiveUnknownTime.writeToParcel(out); 14816 mMobileRadioActiveUnknownCount.writeToParcel(out); 14817 mWifiMulticastWakelockTimer.writeToParcel(out, uSecRealtime); 14818 mWifiOnTimer.writeToParcel(out, uSecRealtime); 14819 mGlobalWifiRunningTimer.writeToParcel(out, uSecRealtime); 14820 for (int i=0; i<NUM_WIFI_STATES; i++) { 14821 mWifiStateTimer[i].writeToParcel(out, uSecRealtime); 14822 } 14823 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) { 14824 mWifiSupplStateTimer[i].writeToParcel(out, uSecRealtime); 14825 } 14826 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { 14827 mWifiSignalStrengthsTimer[i].writeToParcel(out, uSecRealtime); 14828 } 14829 mWifiActiveTimer.writeToParcel(out, uSecRealtime); 14830 mWifiActivity.writeToParcel(out, 0); 14831 for (int i=0; i< GnssMetrics.NUM_GPS_SIGNAL_QUALITY_LEVELS; i++) { 14832 mGpsSignalQualityTimer[i].writeToParcel(out, uSecRealtime); 14833 } 14834 mBluetoothActivity.writeToParcel(out, 0); 14835 mModemActivity.writeToParcel(out, 0); 14836 out.writeInt(mHasWifiReporting ? 1 : 0); 14837 out.writeInt(mHasBluetoothReporting ? 1 : 0); 14838 out.writeInt(mHasModemReporting ? 1 : 0); 14839 14840 out.writeInt(mNumConnectivityChange); 14841 mFlashlightOnTimer.writeToParcel(out, uSecRealtime); 14842 mCameraOnTimer.writeToParcel(out, uSecRealtime); 14843 mBluetoothScanTimer.writeToParcel(out, uSecRealtime); 14844 out.writeInt(mDischargeUnplugLevel); 14845 out.writeInt(mDischargePlugLevel); 14846 out.writeInt(mDischargeCurrentLevel); 14847 out.writeInt(mCurrentBatteryLevel); 14848 out.writeInt(mLowDischargeAmountSinceCharge); 14849 out.writeInt(mHighDischargeAmountSinceCharge); 14850 out.writeInt(mDischargeAmountScreenOn); 14851 out.writeInt(mDischargeAmountScreenOnSinceCharge); 14852 out.writeInt(mDischargeAmountScreenOff); 14853 out.writeInt(mDischargeAmountScreenOffSinceCharge); 14854 out.writeInt(mDischargeAmountScreenDoze); 14855 out.writeInt(mDischargeAmountScreenDozeSinceCharge); 14856 mDischargeStepTracker.writeToParcel(out); 14857 mChargeStepTracker.writeToParcel(out); 14858 mDischargeCounter.writeToParcel(out); 14859 mDischargeScreenOffCounter.writeToParcel(out); 14860 mDischargeScreenDozeCounter.writeToParcel(out); 14861 mDischargeLightDozeCounter.writeToParcel(out); 14862 mDischargeDeepDozeCounter.writeToParcel(out); 14863 out.writeLong(mLastWriteTime); 14864 14865 out.writeInt(mRpmStats.size()); 14866 for (Map.Entry<String, SamplingTimer> ent : mRpmStats.entrySet()) { 14867 SamplingTimer rpmt = ent.getValue(); 14868 if (rpmt != null) { 14869 out.writeInt(1); 14870 out.writeString(ent.getKey()); 14871 rpmt.writeToParcel(out, uSecRealtime); 14872 } else { 14873 out.writeInt(0); 14874 } 14875 } 14876 out.writeInt(mScreenOffRpmStats.size()); 14877 for (Map.Entry<String, SamplingTimer> ent : mScreenOffRpmStats.entrySet()) { 14878 SamplingTimer rpmt = ent.getValue(); 14879 if (rpmt != null) { 14880 out.writeInt(1); 14881 out.writeString(ent.getKey()); 14882 rpmt.writeToParcel(out, uSecRealtime); 14883 } else { 14884 out.writeInt(0); 14885 } 14886 } 14887 14888 if (inclUids) { 14889 out.writeInt(mKernelWakelockStats.size()); 14890 for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) { 14891 SamplingTimer kwlt = ent.getValue(); 14892 if (kwlt != null) { 14893 out.writeInt(1); 14894 out.writeString(ent.getKey()); 14895 kwlt.writeToParcel(out, uSecRealtime); 14896 } else { 14897 out.writeInt(0); 14898 } 14899 } 14900 out.writeInt(mWakeupReasonStats.size()); 14901 for (Map.Entry<String, SamplingTimer> ent : mWakeupReasonStats.entrySet()) { 14902 SamplingTimer timer = ent.getValue(); 14903 if (timer != null) { 14904 out.writeInt(1); 14905 out.writeString(ent.getKey()); 14906 timer.writeToParcel(out, uSecRealtime); 14907 } else { 14908 out.writeInt(0); 14909 } 14910 } 14911 } else { 14912 out.writeInt(0); 14913 out.writeInt(0); 14914 } 14915 14916 out.writeInt(mKernelMemoryStats.size()); 14917 for (int i = 0; i < mKernelMemoryStats.size(); i++) { 14918 SamplingTimer kmt = mKernelMemoryStats.valueAt(i); 14919 if (kmt != null) { 14920 out.writeInt(1); 14921 out.writeLong(mKernelMemoryStats.keyAt(i)); 14922 kmt.writeToParcel(out, uSecRealtime); 14923 } else { 14924 out.writeInt(0); 14925 } 14926 } 14927 14928 if (inclUids) { 14929 int size = mUidStats.size(); 14930 out.writeInt(size); 14931 for (int i = 0; i < size; i++) { 14932 out.writeInt(mUidStats.keyAt(i)); 14933 Uid uid = mUidStats.valueAt(i); 14934 14935 uid.writeToParcelLocked(out, uSecUptime, uSecRealtime); 14936 } 14937 } else { 14938 out.writeInt(0); 14939 } 14940 } 14941 14942 @UnsupportedAppUsage 14943 public static final Parcelable.Creator<BatteryStatsImpl> CREATOR = 14944 new Parcelable.Creator<BatteryStatsImpl>() { 14945 public BatteryStatsImpl createFromParcel(Parcel in) { 14946 return new BatteryStatsImpl(in); 14947 } 14948 14949 public BatteryStatsImpl[] newArray(int size) { 14950 return new BatteryStatsImpl[size]; 14951 } 14952 }; 14953 prepareForDumpLocked()14954 public void prepareForDumpLocked() { 14955 // Need to retrieve current kernel wake lock stats before printing. 14956 pullPendingStateUpdatesLocked(); 14957 14958 // Pull the clock time. This may update the time and make a new history entry 14959 // if we had originally pulled a time before the RTC was set. 14960 getStartClockTime(); 14961 } 14962 dumpLocked(Context context, PrintWriter pw, int flags, int reqUid, long histStart)14963 public void dumpLocked(Context context, PrintWriter pw, int flags, int reqUid, long histStart) { 14964 if (DEBUG) { 14965 pw.println("mOnBatteryTimeBase:"); 14966 mOnBatteryTimeBase.dump(pw, " "); 14967 pw.println("mOnBatteryScreenOffTimeBase:"); 14968 mOnBatteryScreenOffTimeBase.dump(pw, " "); 14969 Printer pr = new PrintWriterPrinter(pw); 14970 pr.println("*** Screen on timer:"); 14971 mScreenOnTimer.logState(pr, " "); 14972 pr.println("*** Screen doze timer:"); 14973 mScreenDozeTimer.logState(pr, " "); 14974 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 14975 pr.println("*** Screen brightness #" + i + ":"); 14976 mScreenBrightnessTimer[i].logState(pr, " "); 14977 } 14978 pr.println("*** Interactive timer:"); 14979 mInteractiveTimer.logState(pr, " "); 14980 pr.println("*** Power save mode timer:"); 14981 mPowerSaveModeEnabledTimer.logState(pr, " "); 14982 pr.println("*** Device idle mode light timer:"); 14983 mDeviceIdleModeLightTimer.logState(pr, " "); 14984 pr.println("*** Device idle mode full timer:"); 14985 mDeviceIdleModeFullTimer.logState(pr, " "); 14986 pr.println("*** Device light idling timer:"); 14987 mDeviceLightIdlingTimer.logState(pr, " "); 14988 pr.println("*** Device idling timer:"); 14989 mDeviceIdlingTimer.logState(pr, " "); 14990 pr.println("*** Phone timer:"); 14991 mPhoneOnTimer.logState(pr, " "); 14992 for (int i = 0; i < CellSignalStrength.getNumSignalStrengthLevels(); i++) { 14993 pr.println("*** Phone signal strength #" + i + ":"); 14994 mPhoneSignalStrengthsTimer[i].logState(pr, " "); 14995 } 14996 pr.println("*** Signal scanning :"); 14997 mPhoneSignalScanningTimer.logState(pr, " "); 14998 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 14999 pr.println("*** Data connection type #" + i + ":"); 15000 mPhoneDataConnectionsTimer[i].logState(pr, " "); 15001 } 15002 pr.println("*** mMobileRadioPowerState=" + mMobileRadioPowerState); 15003 pr.println("*** Mobile network active timer:"); 15004 mMobileRadioActiveTimer.logState(pr, " "); 15005 pr.println("*** Mobile network active adjusted timer:"); 15006 mMobileRadioActiveAdjustedTime.logState(pr, " "); 15007 pr.println("*** Wifi Multicast WakeLock Timer:"); 15008 mWifiMulticastWakelockTimer.logState(pr, " "); 15009 pr.println("*** mWifiRadioPowerState=" + mWifiRadioPowerState); 15010 pr.println("*** Wifi timer:"); 15011 mWifiOnTimer.logState(pr, " "); 15012 pr.println("*** WifiRunning timer:"); 15013 mGlobalWifiRunningTimer.logState(pr, " "); 15014 for (int i=0; i<NUM_WIFI_STATES; i++) { 15015 pr.println("*** Wifi state #" + i + ":"); 15016 mWifiStateTimer[i].logState(pr, " "); 15017 } 15018 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) { 15019 pr.println("*** Wifi suppl state #" + i + ":"); 15020 mWifiSupplStateTimer[i].logState(pr, " "); 15021 } 15022 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { 15023 pr.println("*** Wifi signal strength #" + i + ":"); 15024 mWifiSignalStrengthsTimer[i].logState(pr, " "); 15025 } 15026 for (int i=0; i<GnssMetrics.NUM_GPS_SIGNAL_QUALITY_LEVELS; i++) { 15027 pr.println("*** GPS signal quality #" + i + ":"); 15028 mGpsSignalQualityTimer[i].logState(pr, " "); 15029 } 15030 pr.println("*** Flashlight timer:"); 15031 mFlashlightOnTimer.logState(pr, " "); 15032 pr.println("*** Camera timer:"); 15033 mCameraOnTimer.logState(pr, " "); 15034 } 15035 super.dumpLocked(context, pw, flags, reqUid, histStart); 15036 pw.print("Total cpu time reads: "); 15037 pw.println(mNumSingleUidCpuTimeReads); 15038 pw.print("Batched cpu time reads: "); 15039 pw.println(mNumBatchedSingleUidCpuTimeReads); 15040 pw.print("Batching Duration (min): "); 15041 pw.println((mClocks.uptimeMillis() - mCpuTimeReadsTrackingStartTime) / (60 * 1000)); 15042 pw.print("All UID cpu time reads since the later of device start or stats reset: "); 15043 pw.println(mNumAllUidCpuTimeReads); 15044 pw.print("UIDs removed since the later of device start or stats reset: "); 15045 pw.println(mNumUidsRemoved); 15046 } 15047 } 15048