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 android.annotation.NonNull; 20 import android.annotation.Nullable; 21 import android.app.ActivityManager; 22 import android.bluetooth.BluetoothActivityEnergyInfo; 23 import android.bluetooth.UidTraffic; 24 import android.compat.annotation.UnsupportedAppUsage; 25 import android.content.BroadcastReceiver; 26 import android.content.ContentResolver; 27 import android.content.Context; 28 import android.content.Intent; 29 import android.content.IntentFilter; 30 import android.database.ContentObserver; 31 import android.hardware.usb.UsbManager; 32 import android.net.ConnectivityManager; 33 import android.net.INetworkStatsService; 34 import android.net.NetworkStats; 35 import android.net.Uri; 36 import android.net.wifi.WifiActivityEnergyInfo; 37 import android.net.wifi.WifiManager; 38 import android.os.BatteryManager; 39 import android.os.BatteryStats; 40 import android.os.Build; 41 import android.os.Handler; 42 import android.os.IBatteryPropertiesRegistrar; 43 import android.os.Looper; 44 import android.os.Message; 45 import android.os.OsProtoEnums; 46 import android.os.Parcel; 47 import android.os.ParcelFormatException; 48 import android.os.Parcelable; 49 import android.os.PowerManager; 50 import android.os.Process; 51 import android.os.RemoteException; 52 import android.os.ServiceManager; 53 import android.os.SystemClock; 54 import android.os.UserHandle; 55 import android.os.WorkSource; 56 import android.os.WorkSource.WorkChain; 57 import android.os.connectivity.CellularBatteryStats; 58 import android.os.connectivity.GpsBatteryStats; 59 import android.os.connectivity.WifiBatteryStats; 60 import android.provider.Settings; 61 import android.telephony.CellSignalStrength; 62 import android.telephony.DataConnectionRealTimeInfo; 63 import android.telephony.ModemActivityInfo; 64 import android.telephony.ModemActivityInfo.TransmitPower; 65 import android.telephony.ServiceState; 66 import android.telephony.SignalStrength; 67 import android.telephony.TelephonyManager; 68 import android.text.TextUtils; 69 import android.util.ArrayMap; 70 import android.util.IntArray; 71 import android.util.KeyValueListParser; 72 import android.util.Log; 73 import android.util.LogWriter; 74 import android.util.LongSparseArray; 75 import android.util.LongSparseLongArray; 76 import android.util.MutableInt; 77 import android.util.Pools; 78 import android.util.PrintWriterPrinter; 79 import android.util.Printer; 80 import android.util.Slog; 81 import android.util.SparseArray; 82 import android.util.SparseIntArray; 83 import android.util.SparseLongArray; 84 import android.util.StatsLog; 85 import android.util.TimeUtils; 86 import android.util.Xml; 87 import android.view.Display; 88 89 import com.android.internal.annotations.GuardedBy; 90 import com.android.internal.annotations.VisibleForTesting; 91 import com.android.internal.location.gnssmetrics.GnssMetrics; 92 import com.android.internal.os.KernelCpuUidTimeReader.KernelCpuUidActiveTimeReader; 93 import com.android.internal.os.KernelCpuUidTimeReader.KernelCpuUidClusterTimeReader; 94 import com.android.internal.os.KernelCpuUidTimeReader.KernelCpuUidFreqTimeReader; 95 import com.android.internal.os.KernelCpuUidTimeReader.KernelCpuUidUserSysTimeReader; 96 import com.android.internal.util.ArrayUtils; 97 import com.android.internal.util.FastPrintWriter; 98 import com.android.internal.util.FastXmlSerializer; 99 import com.android.internal.util.XmlUtils; 100 101 import libcore.util.EmptyArray; 102 103 import org.xmlpull.v1.XmlPullParser; 104 import org.xmlpull.v1.XmlPullParserException; 105 import org.xmlpull.v1.XmlSerializer; 106 107 import java.io.ByteArrayOutputStream; 108 import java.io.File; 109 import java.io.FileInputStream; 110 import java.io.FileNotFoundException; 111 import java.io.FileOutputStream; 112 import java.io.IOException; 113 import java.io.PrintWriter; 114 import java.nio.charset.StandardCharsets; 115 import java.util.ArrayList; 116 import java.util.Arrays; 117 import java.util.Calendar; 118 import java.util.Collection; 119 import java.util.HashMap; 120 import java.util.HashSet; 121 import java.util.Iterator; 122 import java.util.LinkedList; 123 import java.util.List; 124 import java.util.Map; 125 import java.util.Queue; 126 import java.util.concurrent.Future; 127 import java.util.concurrent.atomic.AtomicInteger; 128 import java.util.concurrent.locks.ReentrantLock; 129 130 /** 131 * All information we are collecting about things that can happen that impact 132 * battery life. All times are represented in microseconds except where indicated 133 * otherwise. 134 */ 135 public class BatteryStatsImpl extends BatteryStats { 136 private static final String TAG = "BatteryStatsImpl"; 137 private static final boolean DEBUG = false; 138 public static final boolean DEBUG_ENERGY = false; 139 private static final boolean DEBUG_ENERGY_CPU = DEBUG_ENERGY; 140 private static final boolean DEBUG_MEMORY = false; 141 private static final boolean DEBUG_HISTORY = false; 142 private static final boolean USE_OLD_HISTORY = false; // for debugging. 143 144 // TODO: remove "tcp" from network methods, since we measure total stats. 145 146 // In-memory Parcel magic number, used to detect attempts to unmarshall bad data 147 private static final int MAGIC = 0xBA757475; // 'BATSTATS' 148 149 // Current on-disk Parcel version 150 static final int VERSION = 186 + (USE_OLD_HISTORY ? 1000 : 0); 151 152 // The maximum number of names wakelocks we will keep track of 153 // per uid; once the limit is reached, we batch the remaining wakelocks 154 // in to one common name. 155 private static final int MAX_WAKELOCKS_PER_UID; 156 157 static { 158 if (ActivityManager.isLowRamDeviceStatic()) { 159 MAX_WAKELOCKS_PER_UID = 40; 160 } else { 161 MAX_WAKELOCKS_PER_UID = 200; 162 } 163 } 164 165 // Number of transmit power states the Wifi controller can be in. 166 private static final int NUM_WIFI_TX_LEVELS = 1; 167 168 // Number of transmit power states the Bluetooth controller can be in. 169 private static final int NUM_BT_TX_LEVELS = 1; 170 171 /** 172 * Holding a wakelock costs more than just using the cpu. 173 * Currently, we assign only half the cpu time to an app that is running but 174 * not holding a wakelock. The apps holding wakelocks get the rest of the blame. 175 * If no app is holding a wakelock, then the distribution is normal. 176 */ 177 @VisibleForTesting 178 public static final int WAKE_LOCK_WEIGHT = 50; 179 180 protected Clocks mClocks; 181 182 private final AtomicFile mStatsFile; 183 public final AtomicFile mCheckinFile; 184 public final AtomicFile mDailyFile; 185 186 static final int MSG_REPORT_CPU_UPDATE_NEEDED = 1; 187 static final int MSG_REPORT_POWER_CHANGE = 2; 188 static final int MSG_REPORT_CHARGING = 3; 189 static final int MSG_REPORT_RESET_STATS = 4; 190 static final long DELAY_UPDATE_WAKELOCKS = 5*1000; 191 192 private static final double MILLISECONDS_IN_HOUR = 3600 * 1000; 193 private static final long MILLISECONDS_IN_YEAR = 365 * 24 * 3600 * 1000L; 194 195 private final KernelWakelockReader mKernelWakelockReader = new KernelWakelockReader(); 196 private final KernelWakelockStats mTmpWakelockStats = new KernelWakelockStats(); 197 198 @VisibleForTesting 199 protected KernelCpuUidUserSysTimeReader mCpuUidUserSysTimeReader = 200 new KernelCpuUidUserSysTimeReader(true); 201 @VisibleForTesting 202 protected KernelCpuSpeedReader[] mKernelCpuSpeedReaders; 203 @VisibleForTesting 204 protected KernelCpuUidFreqTimeReader mCpuUidFreqTimeReader = 205 new KernelCpuUidFreqTimeReader(true); 206 @VisibleForTesting 207 protected KernelCpuUidActiveTimeReader mCpuUidActiveTimeReader = 208 new KernelCpuUidActiveTimeReader(true); 209 @VisibleForTesting 210 protected KernelCpuUidClusterTimeReader mCpuUidClusterTimeReader = 211 new KernelCpuUidClusterTimeReader(true); 212 @VisibleForTesting 213 protected KernelSingleUidTimeReader mKernelSingleUidTimeReader; 214 215 private final KernelMemoryBandwidthStats mKernelMemoryBandwidthStats 216 = new KernelMemoryBandwidthStats(); 217 private final LongSparseArray<SamplingTimer> mKernelMemoryStats = new LongSparseArray<>(); getKernelMemoryStats()218 public LongSparseArray<SamplingTimer> getKernelMemoryStats() { 219 return mKernelMemoryStats; 220 } 221 222 @GuardedBy("this") 223 public boolean mPerProcStateCpuTimesAvailable = true; 224 225 /** 226 * When per process state cpu times tracking is off, cpu times in KernelSingleUidTimeReader are 227 * not updated. So, when the setting is turned on later, we would end up with huge cpu time 228 * deltas. This flag tracks the case where tracking is turned on from off so that we won't 229 * end up attributing the huge deltas to wrong buckets. 230 */ 231 @GuardedBy("this") 232 private boolean mIsPerProcessStateCpuDataStale; 233 234 /** 235 * Uids for which per-procstate cpu times need to be updated. 236 * 237 * Contains uid -> procState mappings. 238 */ 239 @GuardedBy("this") 240 @VisibleForTesting 241 protected final SparseIntArray mPendingUids = new SparseIntArray(); 242 243 @GuardedBy("this") 244 private long mNumSingleUidCpuTimeReads; 245 @GuardedBy("this") 246 private long mNumBatchedSingleUidCpuTimeReads; 247 @GuardedBy("this") 248 private long mCpuTimeReadsTrackingStartTime = SystemClock.uptimeMillis(); 249 @GuardedBy("this") 250 private int mNumUidsRemoved; 251 @GuardedBy("this") 252 private int mNumAllUidCpuTimeReads; 253 254 /** Container for Resource Power Manager stats. Updated by updateRpmStatsLocked. */ 255 private final RpmStats mTmpRpmStats = new RpmStats(); 256 /** The soonest the RPM stats can be updated after it was last updated. */ 257 private static final long RPM_STATS_UPDATE_FREQ_MS = 1000; 258 /** Last time that RPM stats were updated by updateRpmStatsLocked. */ 259 private long mLastRpmStatsUpdateTimeMs = -RPM_STATS_UPDATE_FREQ_MS; 260 261 /** Container for Rail Energy Data stats. */ 262 private final RailStats mTmpRailStats = new RailStats(); 263 /** 264 * Use a queue to delay removing UIDs from {@link KernelCpuUidUserSysTimeReader}, 265 * {@link KernelCpuUidActiveTimeReader}, {@link KernelCpuUidClusterTimeReader}, 266 * {@link KernelCpuUidFreqTimeReader} and from the Kernel. 267 * 268 * Isolated and invalid UID info must be removed to conserve memory. However, STATSD and 269 * Batterystats both need to access UID cpu time. To resolve this race condition, only 270 * Batterystats shall remove UIDs, and a delay {@link Constants#UID_REMOVE_DELAY_MS} is 271 * implemented so that STATSD can capture those UID times before they are deleted. 272 */ 273 @GuardedBy("this") 274 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) 275 protected Queue<UidToRemove> mPendingRemovedUids = new LinkedList<>(); 276 277 @VisibleForTesting 278 public final class UidToRemove { 279 int startUid; 280 int endUid; 281 long timeAddedInQueue; 282 283 /** Remove just one UID */ UidToRemove(int uid, long timestamp)284 public UidToRemove(int uid, long timestamp) { 285 this(uid, uid, timestamp); 286 } 287 288 /** Remove a range of UIDs, startUid must be smaller than endUid. */ UidToRemove(int startUid, int endUid, long timestamp)289 public UidToRemove(int startUid, int endUid, long timestamp) { 290 this.startUid = startUid; 291 this.endUid = endUid; 292 timeAddedInQueue = timestamp; 293 } 294 remove()295 void remove() { 296 if (startUid == endUid) { 297 mCpuUidUserSysTimeReader.removeUid(startUid); 298 mCpuUidFreqTimeReader.removeUid(startUid); 299 if (mConstants.TRACK_CPU_ACTIVE_CLUSTER_TIME) { 300 mCpuUidActiveTimeReader.removeUid(startUid); 301 mCpuUidClusterTimeReader.removeUid(startUid); 302 } 303 if (mKernelSingleUidTimeReader != null) { 304 mKernelSingleUidTimeReader.removeUid(startUid); 305 } 306 mNumUidsRemoved++; 307 } else if (startUid < endUid) { 308 mCpuUidFreqTimeReader.removeUidsInRange(startUid, endUid); 309 mCpuUidUserSysTimeReader.removeUidsInRange(startUid, endUid); 310 if (mConstants.TRACK_CPU_ACTIVE_CLUSTER_TIME) { 311 mCpuUidActiveTimeReader.removeUidsInRange(startUid, endUid); 312 mCpuUidClusterTimeReader.removeUidsInRange(startUid, endUid); 313 } 314 if (mKernelSingleUidTimeReader != null) { 315 mKernelSingleUidTimeReader.removeUidsInRange(startUid, endUid); 316 } 317 // Treat as one. We don't know how many uids there are in between. 318 mNumUidsRemoved++; 319 } else { 320 Slog.w(TAG, "End UID " + endUid + " is smaller than start UID " + startUid); 321 } 322 } 323 } 324 325 public interface BatteryCallback { batteryNeedsCpuUpdate()326 public void batteryNeedsCpuUpdate(); batteryPowerChanged(boolean onBattery)327 public void batteryPowerChanged(boolean onBattery); batterySendBroadcast(Intent intent)328 public void batterySendBroadcast(Intent intent); batteryStatsReset()329 public void batteryStatsReset(); 330 } 331 332 public interface PlatformIdleStateCallback { fillLowPowerStats(RpmStats rpmStats)333 public void fillLowPowerStats(RpmStats rpmStats); getPlatformLowPowerStats()334 public String getPlatformLowPowerStats(); getSubsystemLowPowerStats()335 public String getSubsystemLowPowerStats(); 336 } 337 338 /** interface to update rail information for power monitor */ 339 public interface RailEnergyDataCallback { 340 /** Function to fill the map for the rail data stats 341 * Used for power monitoring feature 342 * @param railStats 343 */ fillRailDataStats(RailStats railStats)344 void fillRailDataStats(RailStats railStats); 345 } 346 347 public static abstract class UserInfoProvider { 348 private int[] userIds; getUserIds()349 protected abstract @Nullable int[] getUserIds(); 350 @VisibleForTesting refreshUserIds()351 public final void refreshUserIds() { 352 userIds = getUserIds(); 353 } 354 @VisibleForTesting exists(int userId)355 public boolean exists(int userId) { 356 return userIds != null ? ArrayUtils.contains(userIds, userId) : true; 357 } 358 } 359 360 private final PlatformIdleStateCallback mPlatformIdleStateCallback; 361 362 private final Runnable mDeferSetCharging = new Runnable() { 363 @Override 364 public void run() { 365 synchronized (BatteryStatsImpl.this) { 366 if (mOnBattery) { 367 // if the device gets unplugged in the time between this runnable being 368 // executed and the lock being taken, we don't want to set charging state 369 return; 370 } 371 boolean changed = setChargingLocked(true); 372 if (changed) { 373 final long uptime = mClocks.uptimeMillis(); 374 final long elapsedRealtime = mClocks.elapsedRealtime(); 375 addHistoryRecordLocked(elapsedRealtime, uptime); 376 } 377 } 378 } 379 }; 380 381 public final RailEnergyDataCallback mRailEnergyDataCallback; 382 383 /** 384 * This handler is running on {@link BackgroundThread}. 385 */ 386 final class MyHandler extends Handler { MyHandler(Looper looper)387 public MyHandler(Looper looper) { 388 super(looper, null, true); 389 } 390 391 @Override handleMessage(Message msg)392 public void handleMessage(Message msg) { 393 BatteryCallback cb = mCallback; 394 switch (msg.what) { 395 case MSG_REPORT_CPU_UPDATE_NEEDED: 396 if (cb != null) { 397 cb.batteryNeedsCpuUpdate(); 398 } 399 break; 400 case MSG_REPORT_POWER_CHANGE: 401 if (cb != null) { 402 cb.batteryPowerChanged(msg.arg1 != 0); 403 } 404 break; 405 case MSG_REPORT_CHARGING: 406 if (cb != null) { 407 final String action; 408 synchronized (BatteryStatsImpl.this) { 409 action = mCharging ? BatteryManager.ACTION_CHARGING 410 : BatteryManager.ACTION_DISCHARGING; 411 } 412 Intent intent = new Intent(action); 413 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); 414 cb.batterySendBroadcast(intent); 415 } 416 break; 417 case MSG_REPORT_RESET_STATS: 418 if (cb != null) { 419 cb.batteryStatsReset(); 420 } 421 } 422 } 423 } 424 postBatteryNeedsCpuUpdateMsg()425 public void postBatteryNeedsCpuUpdateMsg() { 426 mHandler.sendEmptyMessage(MSG_REPORT_CPU_UPDATE_NEEDED); 427 } 428 429 /** 430 * Update per-freq cpu times for all the uids in {@link #mPendingUids}. 431 */ updateProcStateCpuTimes(boolean onBattery, boolean onBatteryScreenOff)432 public void updateProcStateCpuTimes(boolean onBattery, boolean onBatteryScreenOff) { 433 final SparseIntArray uidStates; 434 synchronized (BatteryStatsImpl.this) { 435 if (!mConstants.TRACK_CPU_TIMES_BY_PROC_STATE) { 436 return; 437 } 438 if(!initKernelSingleUidTimeReaderLocked()) { 439 return; 440 } 441 // If the KernelSingleUidTimeReader has stale cpu times, then we shouldn't try to 442 // compute deltas since it might result in mis-attributing cpu times to wrong states. 443 if (mIsPerProcessStateCpuDataStale) { 444 mPendingUids.clear(); 445 return; 446 } 447 448 if (mPendingUids.size() == 0) { 449 return; 450 } 451 uidStates = mPendingUids.clone(); 452 mPendingUids.clear(); 453 } 454 for (int i = uidStates.size() - 1; i >= 0; --i) { 455 final int uid = uidStates.keyAt(i); 456 final int procState = uidStates.valueAt(i); 457 final int[] isolatedUids; 458 final Uid u; 459 synchronized (BatteryStatsImpl.this) { 460 // It's possible that uid no longer exists and any internal references have 461 // already been deleted, so using {@link #getAvailableUidStatsLocked} to avoid 462 // creating an UidStats object if it doesn't already exist. 463 u = getAvailableUidStatsLocked(uid); 464 if (u == null) { 465 continue; 466 } 467 if (u.mChildUids == null) { 468 isolatedUids = null; 469 } else { 470 isolatedUids = u.mChildUids.toArray(); 471 for (int j = isolatedUids.length - 1; j >= 0; --j) { 472 isolatedUids[j] = u.mChildUids.get(j); 473 } 474 } 475 } 476 long[] cpuTimesMs = mKernelSingleUidTimeReader.readDeltaMs(uid); 477 if (isolatedUids != null) { 478 for (int j = isolatedUids.length - 1; j >= 0; --j) { 479 cpuTimesMs = addCpuTimes(cpuTimesMs, 480 mKernelSingleUidTimeReader.readDeltaMs(isolatedUids[j])); 481 } 482 } 483 if (onBattery && cpuTimesMs != null) { 484 synchronized (BatteryStatsImpl.this) { 485 u.addProcStateTimesMs(procState, cpuTimesMs, onBattery); 486 u.addProcStateScreenOffTimesMs(procState, cpuTimesMs, onBatteryScreenOff); 487 } 488 } 489 } 490 } 491 clearPendingRemovedUids()492 public void clearPendingRemovedUids() { 493 long cutOffTime = mClocks.elapsedRealtime() - mConstants.UID_REMOVE_DELAY_MS; 494 while (!mPendingRemovedUids.isEmpty() 495 && mPendingRemovedUids.peek().timeAddedInQueue < cutOffTime) { 496 mPendingRemovedUids.poll().remove(); 497 } 498 } 499 copyFromAllUidsCpuTimes()500 public void copyFromAllUidsCpuTimes() { 501 synchronized (BatteryStatsImpl.this) { 502 copyFromAllUidsCpuTimes( 503 mOnBatteryTimeBase.isRunning(), mOnBatteryScreenOffTimeBase.isRunning()); 504 } 505 } 506 507 /** 508 * When the battery/screen state changes, we don't attribute the cpu times to any process 509 * but we still need to snapshots of all uids to get correct deltas later on. Since we 510 * already read this data for updating per-freq cpu times, we can use the same data for 511 * per-procstate cpu times. 512 */ copyFromAllUidsCpuTimes(boolean onBattery, boolean onBatteryScreenOff)513 public void copyFromAllUidsCpuTimes(boolean onBattery, boolean onBatteryScreenOff) { 514 synchronized (BatteryStatsImpl.this) { 515 if (!mConstants.TRACK_CPU_TIMES_BY_PROC_STATE) { 516 return; 517 } 518 if(!initKernelSingleUidTimeReaderLocked()) { 519 return; 520 } 521 522 final SparseArray<long[]> allUidCpuFreqTimesMs = 523 mCpuUidFreqTimeReader.getAllUidCpuFreqTimeMs(); 524 // If the KernelSingleUidTimeReader has stale cpu times, then we shouldn't try to 525 // compute deltas since it might result in mis-attributing cpu times to wrong states. 526 if (mIsPerProcessStateCpuDataStale) { 527 mKernelSingleUidTimeReader.setAllUidsCpuTimesMs(allUidCpuFreqTimesMs); 528 mIsPerProcessStateCpuDataStale = false; 529 mPendingUids.clear(); 530 return; 531 } 532 for (int i = allUidCpuFreqTimesMs.size() - 1; i >= 0; --i) { 533 final int uid = allUidCpuFreqTimesMs.keyAt(i); 534 final Uid u = getAvailableUidStatsLocked(mapUid(uid)); 535 if (u == null) { 536 continue; 537 } 538 final long[] cpuTimesMs = allUidCpuFreqTimesMs.valueAt(i); 539 if (cpuTimesMs == null) { 540 continue; 541 } 542 final long[] deltaTimesMs = mKernelSingleUidTimeReader.computeDelta( 543 uid, cpuTimesMs.clone()); 544 if (onBattery && deltaTimesMs != null) { 545 final int procState; 546 final int idx = mPendingUids.indexOfKey(uid); 547 if (idx >= 0) { 548 procState = mPendingUids.valueAt(idx); 549 mPendingUids.removeAt(idx); 550 } else { 551 procState = u.mProcessState; 552 } 553 if (procState >= 0 && procState < Uid.NUM_PROCESS_STATE) { 554 u.addProcStateTimesMs(procState, deltaTimesMs, onBattery); 555 u.addProcStateScreenOffTimesMs(procState, deltaTimesMs, onBatteryScreenOff); 556 } 557 } 558 } 559 } 560 } 561 562 @VisibleForTesting addCpuTimes(long[] timesA, long[] timesB)563 public long[] addCpuTimes(long[] timesA, long[] timesB) { 564 if (timesA != null && timesB != null) { 565 for (int i = timesA.length - 1; i >= 0; --i) { 566 timesA[i] += timesB[i]; 567 } 568 return timesA; 569 } 570 return timesA == null ? (timesB == null ? null : timesB) : timesA; 571 } 572 573 @GuardedBy("this") initKernelSingleUidTimeReaderLocked()574 private boolean initKernelSingleUidTimeReaderLocked() { 575 if (mKernelSingleUidTimeReader == null) { 576 if (mPowerProfile == null) { 577 return false; 578 } 579 if (mCpuFreqs == null) { 580 mCpuFreqs = mCpuUidFreqTimeReader.readFreqs(mPowerProfile); 581 } 582 if (mCpuFreqs != null) { 583 mKernelSingleUidTimeReader = new KernelSingleUidTimeReader(mCpuFreqs.length); 584 } else { 585 mPerProcStateCpuTimesAvailable = mCpuUidFreqTimeReader.allUidTimesAvailable(); 586 return false; 587 } 588 } 589 mPerProcStateCpuTimesAvailable = mCpuUidFreqTimeReader.allUidTimesAvailable() 590 && mKernelSingleUidTimeReader.singleUidCpuTimesAvailable(); 591 return true; 592 } 593 594 public interface Clocks { elapsedRealtime()595 public long elapsedRealtime(); uptimeMillis()596 public long uptimeMillis(); 597 } 598 599 public static class SystemClocks implements Clocks { elapsedRealtime()600 public long elapsedRealtime() { 601 return SystemClock.elapsedRealtime(); 602 } 603 uptimeMillis()604 public long uptimeMillis() { 605 return SystemClock.uptimeMillis(); 606 } 607 } 608 609 public interface ExternalStatsSync { 610 int UPDATE_CPU = 0x01; 611 int UPDATE_WIFI = 0x02; 612 int UPDATE_RADIO = 0x04; 613 int UPDATE_BT = 0x08; 614 int UPDATE_RPM = 0x10; // 16 615 int UPDATE_ALL = UPDATE_CPU | UPDATE_WIFI | UPDATE_RADIO | UPDATE_BT | UPDATE_RPM; 616 scheduleSync(String reason, int flags)617 Future<?> scheduleSync(String reason, int flags); scheduleCpuSyncDueToRemovedUid(int uid)618 Future<?> scheduleCpuSyncDueToRemovedUid(int uid); scheduleReadProcStateCpuTimes(boolean onBattery, boolean onBatteryScreenOff, long delayMillis)619 Future<?> scheduleReadProcStateCpuTimes(boolean onBattery, boolean onBatteryScreenOff, 620 long delayMillis); scheduleCopyFromAllUidsCpuTimes(boolean onBattery, boolean onBatteryScreenOff)621 Future<?> scheduleCopyFromAllUidsCpuTimes(boolean onBattery, boolean onBatteryScreenOff); scheduleCpuSyncDueToSettingChange()622 Future<?> scheduleCpuSyncDueToSettingChange(); scheduleCpuSyncDueToScreenStateChange(boolean onBattery, boolean onBatteryScreenOff)623 Future<?> scheduleCpuSyncDueToScreenStateChange(boolean onBattery, 624 boolean onBatteryScreenOff); scheduleCpuSyncDueToWakelockChange(long delayMillis)625 Future<?> scheduleCpuSyncDueToWakelockChange(long delayMillis); cancelCpuSyncDueToWakelockChange()626 void cancelCpuSyncDueToWakelockChange(); scheduleSyncDueToBatteryLevelChange(long delayMillis)627 Future<?> scheduleSyncDueToBatteryLevelChange(long delayMillis); 628 } 629 630 public Handler mHandler; 631 private ExternalStatsSync mExternalSync = null; 632 @VisibleForTesting 633 protected UserInfoProvider mUserInfoProvider = null; 634 635 private BatteryCallback mCallback; 636 637 /** 638 * Mapping isolated uids to the actual owning app uid. 639 */ 640 final SparseIntArray mIsolatedUids = new SparseIntArray(); 641 642 /** 643 * The statistics we have collected organized by uids. 644 */ 645 final SparseArray<BatteryStatsImpl.Uid> mUidStats = new SparseArray<>(); 646 647 // A set of pools of currently active timers. When a timer is queried, we will divide the 648 // elapsed time by the number of active timers to arrive at that timer's share of the time. 649 // In order to do this, we must refresh each timer whenever the number of active timers 650 // changes. 651 @VisibleForTesting 652 @UnsupportedAppUsage 653 protected ArrayList<StopwatchTimer> mPartialTimers = new ArrayList<>(); 654 @UnsupportedAppUsage 655 final ArrayList<StopwatchTimer> mFullTimers = new ArrayList<>(); 656 @UnsupportedAppUsage 657 final ArrayList<StopwatchTimer> mWindowTimers = new ArrayList<>(); 658 final ArrayList<StopwatchTimer> mDrawTimers = new ArrayList<>(); 659 final SparseArray<ArrayList<StopwatchTimer>> mSensorTimers = new SparseArray<>(); 660 final ArrayList<StopwatchTimer> mWifiRunningTimers = new ArrayList<>(); 661 final ArrayList<StopwatchTimer> mFullWifiLockTimers = new ArrayList<>(); 662 final ArrayList<StopwatchTimer> mWifiMulticastTimers = new ArrayList<>(); 663 final ArrayList<StopwatchTimer> mWifiScanTimers = new ArrayList<>(); 664 final SparseArray<ArrayList<StopwatchTimer>> mWifiBatchedScanTimers = new SparseArray<>(); 665 final ArrayList<StopwatchTimer> mAudioTurnedOnTimers = new ArrayList<>(); 666 final ArrayList<StopwatchTimer> mVideoTurnedOnTimers = new ArrayList<>(); 667 final ArrayList<StopwatchTimer> mFlashlightTurnedOnTimers = new ArrayList<>(); 668 final ArrayList<StopwatchTimer> mCameraTurnedOnTimers = new ArrayList<>(); 669 final ArrayList<StopwatchTimer> mBluetoothScanOnTimers = new ArrayList<>(); 670 671 // Last partial timers we use for distributing CPU usage. 672 @VisibleForTesting 673 protected ArrayList<StopwatchTimer> mLastPartialTimers = new ArrayList<>(); 674 675 // These are the objects that will want to do something when the device 676 // is unplugged from power. 677 protected final TimeBase mOnBatteryTimeBase = new TimeBase(true); 678 679 // These are the objects that will want to do something when the device 680 // is unplugged from power *and* the screen is off or doze. 681 protected final TimeBase mOnBatteryScreenOffTimeBase = new TimeBase(true); 682 683 // Set to true when we want to distribute CPU across wakelocks for the next 684 // CPU update, even if we aren't currently running wake locks. 685 boolean mDistributeWakelockCpu; 686 687 boolean mShuttingDown; 688 689 final HistoryEventTracker mActiveEvents = new HistoryEventTracker(); 690 691 long mHistoryBaseTime; 692 protected boolean mHaveBatteryLevel = false; 693 protected boolean mRecordingHistory = false; 694 int mNumHistoryItems; 695 696 final Parcel mHistoryBuffer = Parcel.obtain(); 697 final HistoryItem mHistoryLastWritten = new HistoryItem(); 698 final HistoryItem mHistoryLastLastWritten = new HistoryItem(); 699 final HistoryItem mHistoryReadTmp = new HistoryItem(); 700 final HistoryItem mHistoryAddTmp = new HistoryItem(); 701 final HashMap<HistoryTag, Integer> mHistoryTagPool = new HashMap<>(); 702 String[] mReadHistoryStrings; 703 int[] mReadHistoryUids; 704 int mReadHistoryChars; 705 int mNextHistoryTagIdx = 0; 706 int mNumHistoryTagChars = 0; 707 int mHistoryBufferLastPos = -1; 708 int mActiveHistoryStates = 0xffffffff; 709 int mActiveHistoryStates2 = 0xffffffff; 710 long mLastHistoryElapsedRealtime = 0; 711 long mTrackRunningHistoryElapsedRealtime = 0; 712 long mTrackRunningHistoryUptime = 0; 713 714 final BatteryStatsHistory mBatteryStatsHistory; 715 716 final HistoryItem mHistoryCur = new HistoryItem(); 717 718 HistoryItem mHistory; 719 HistoryItem mHistoryEnd; 720 HistoryItem mHistoryLastEnd; 721 HistoryItem mHistoryCache; 722 723 // Used by computeHistoryStepDetails 724 HistoryStepDetails mLastHistoryStepDetails = null; 725 byte mLastHistoryStepLevel = 0; 726 final HistoryStepDetails mCurHistoryStepDetails = new HistoryStepDetails(); 727 final HistoryStepDetails mReadHistoryStepDetails = new HistoryStepDetails(); 728 final HistoryStepDetails mTmpHistoryStepDetails = new HistoryStepDetails(); 729 730 /** 731 * Total time (in milliseconds) spent executing in user code. 732 */ 733 long mLastStepCpuUserTime; 734 long mCurStepCpuUserTime; 735 /** 736 * Total time (in milliseconds) spent executing in kernel code. 737 */ 738 long mLastStepCpuSystemTime; 739 long mCurStepCpuSystemTime; 740 /** 741 * Times from /proc/stat (but measured in milliseconds). 742 */ 743 long mLastStepStatUserTime; 744 long mLastStepStatSystemTime; 745 long mLastStepStatIOWaitTime; 746 long mLastStepStatIrqTime; 747 long mLastStepStatSoftIrqTime; 748 long mLastStepStatIdleTime; 749 long mCurStepStatUserTime; 750 long mCurStepStatSystemTime; 751 long mCurStepStatIOWaitTime; 752 long mCurStepStatIrqTime; 753 long mCurStepStatSoftIrqTime; 754 long mCurStepStatIdleTime; 755 756 private HistoryItem mHistoryIterator; 757 private boolean mReadOverflow; 758 private boolean mIteratingHistory; 759 760 int mStartCount; 761 762 long mStartClockTime; 763 String mStartPlatformVersion; 764 String mEndPlatformVersion; 765 766 long mUptime; 767 long mUptimeStart; 768 long mRealtime; 769 long mRealtimeStart; 770 771 int mWakeLockNesting; 772 boolean mWakeLockImportant; 773 public boolean mRecordAllHistory; 774 boolean mNoAutoReset; 775 776 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) 777 protected int mScreenState = Display.STATE_UNKNOWN; 778 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) 779 protected StopwatchTimer mScreenOnTimer; 780 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) 781 protected StopwatchTimer mScreenDozeTimer; 782 783 int mScreenBrightnessBin = -1; 784 final StopwatchTimer[] mScreenBrightnessTimer = new StopwatchTimer[NUM_SCREEN_BRIGHTNESS_BINS]; 785 786 boolean mPretendScreenOff; 787 788 boolean mInteractive; 789 StopwatchTimer mInteractiveTimer; 790 791 boolean mPowerSaveModeEnabled; 792 StopwatchTimer mPowerSaveModeEnabledTimer; 793 794 boolean mDeviceIdling; 795 StopwatchTimer mDeviceIdlingTimer; 796 797 boolean mDeviceLightIdling; 798 StopwatchTimer mDeviceLightIdlingTimer; 799 800 int mDeviceIdleMode; 801 long mLastIdleTimeStart; 802 long mLongestLightIdleTime; 803 long mLongestFullIdleTime; 804 StopwatchTimer mDeviceIdleModeLightTimer; 805 StopwatchTimer mDeviceIdleModeFullTimer; 806 807 boolean mPhoneOn; 808 StopwatchTimer mPhoneOnTimer; 809 810 int mAudioOnNesting; 811 StopwatchTimer mAudioOnTimer; 812 813 int mVideoOnNesting; 814 StopwatchTimer mVideoOnTimer; 815 816 int mFlashlightOnNesting; 817 StopwatchTimer mFlashlightOnTimer; 818 819 int mCameraOnNesting; 820 StopwatchTimer mCameraOnTimer; 821 822 private static final int USB_DATA_UNKNOWN = 0; 823 private static final int USB_DATA_DISCONNECTED = 1; 824 private static final int USB_DATA_CONNECTED = 2; 825 int mUsbDataState = USB_DATA_UNKNOWN; 826 827 int mGpsSignalQualityBin = -1; 828 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) 829 protected final StopwatchTimer[] mGpsSignalQualityTimer = 830 new StopwatchTimer[GnssMetrics.NUM_GPS_SIGNAL_QUALITY_LEVELS]; 831 832 int mPhoneSignalStrengthBin = -1; 833 int mPhoneSignalStrengthBinRaw = -1; 834 final StopwatchTimer[] mPhoneSignalStrengthsTimer = 835 new StopwatchTimer[CellSignalStrength.getNumSignalStrengthLevels()]; 836 837 StopwatchTimer mPhoneSignalScanningTimer; 838 839 int mPhoneDataConnectionType = -1; 840 final StopwatchTimer[] mPhoneDataConnectionsTimer = 841 new StopwatchTimer[NUM_DATA_CONNECTION_TYPES]; 842 843 final LongSamplingCounter[] mNetworkByteActivityCounters = 844 new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES]; 845 final LongSamplingCounter[] mNetworkPacketActivityCounters = 846 new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES]; 847 848 /** 849 * The WiFi Overall wakelock timer 850 * This timer tracks the actual aggregate time for which MC wakelocks are enabled 851 * since addition of per UID timers would not result in an accurate value due to overlapp of 852 * per uid wakelock timers 853 */ 854 StopwatchTimer mWifiMulticastWakelockTimer; 855 856 /** 857 * The WiFi controller activity (time in tx, rx, idle, and power consumed) for the device. 858 */ 859 ControllerActivityCounterImpl mWifiActivity; 860 861 /** 862 * The Bluetooth controller activity (time in tx, rx, idle, and power consumed) for the device. 863 */ 864 ControllerActivityCounterImpl mBluetoothActivity; 865 866 /** 867 * The Modem controller activity (time in tx, rx, idle, and power consumed) for the device. 868 */ 869 ControllerActivityCounterImpl mModemActivity; 870 871 /** 872 * Whether the device supports WiFi controller energy reporting. This is set to true on 873 * the first WiFi energy report. See {@link #mWifiActivity}. 874 */ 875 boolean mHasWifiReporting = false; 876 877 /** 878 * Whether the device supports Bluetooth controller energy reporting. This is set to true on 879 * the first Bluetooth energy report. See {@link #mBluetoothActivity}. 880 */ 881 boolean mHasBluetoothReporting = false; 882 883 /** 884 * Whether the device supports Modem controller energy reporting. This is set to true on 885 * the first Modem energy report. See {@link #mModemActivity}. 886 */ 887 boolean mHasModemReporting = false; 888 889 boolean mWifiOn; 890 StopwatchTimer mWifiOnTimer; 891 892 boolean mGlobalWifiRunning; 893 StopwatchTimer mGlobalWifiRunningTimer; 894 895 int mWifiState = -1; 896 final StopwatchTimer[] mWifiStateTimer = new StopwatchTimer[NUM_WIFI_STATES]; 897 898 int mWifiSupplState = -1; 899 final StopwatchTimer[] mWifiSupplStateTimer = new StopwatchTimer[NUM_WIFI_SUPPL_STATES]; 900 901 int mWifiSignalStrengthBin = -1; 902 final StopwatchTimer[] mWifiSignalStrengthsTimer = 903 new StopwatchTimer[NUM_WIFI_SIGNAL_STRENGTH_BINS]; 904 905 StopwatchTimer mWifiActiveTimer; 906 907 int mBluetoothScanNesting; 908 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) 909 protected StopwatchTimer mBluetoothScanTimer; 910 911 int mMobileRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW; 912 long mMobileRadioActiveStartTime; 913 StopwatchTimer mMobileRadioActiveTimer; 914 StopwatchTimer mMobileRadioActivePerAppTimer; 915 LongSamplingCounter mMobileRadioActiveAdjustedTime; 916 LongSamplingCounter mMobileRadioActiveUnknownTime; 917 LongSamplingCounter mMobileRadioActiveUnknownCount; 918 919 int mWifiRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW; 920 921 /** 922 * These provide time bases that discount the time the device is plugged 923 * in to power. 924 */ 925 boolean mOnBattery; 926 @VisibleForTesting 927 protected boolean mOnBatteryInternal; 928 929 /** 930 * External reporting of whether the device is actually charging. 931 */ 932 boolean mCharging = true; 933 int mLastChargingStateLevel; 934 935 /* 936 * These keep track of battery levels (1-100) at the last plug event and the last unplug event. 937 */ 938 int mDischargeStartLevel; 939 int mDischargeUnplugLevel; 940 int mDischargePlugLevel; 941 int mDischargeCurrentLevel; 942 int mCurrentBatteryLevel; 943 int mLowDischargeAmountSinceCharge; 944 int mHighDischargeAmountSinceCharge; 945 int mDischargeScreenOnUnplugLevel; 946 int mDischargeScreenOffUnplugLevel; 947 int mDischargeScreenDozeUnplugLevel; 948 int mDischargeAmountScreenOn; 949 int mDischargeAmountScreenOnSinceCharge; 950 int mDischargeAmountScreenOff; 951 int mDischargeAmountScreenOffSinceCharge; 952 int mDischargeAmountScreenDoze; 953 int mDischargeAmountScreenDozeSinceCharge; 954 955 private LongSamplingCounter mDischargeScreenOffCounter; 956 private LongSamplingCounter mDischargeScreenDozeCounter; 957 private LongSamplingCounter mDischargeCounter; 958 private LongSamplingCounter mDischargeLightDozeCounter; 959 private LongSamplingCounter mDischargeDeepDozeCounter; 960 961 static final int MAX_LEVEL_STEPS = 200; 962 963 int mInitStepMode = 0; 964 int mCurStepMode = 0; 965 int mModStepMode = 0; 966 967 int mLastDischargeStepLevel; 968 int mMinDischargeStepLevel; 969 final LevelStepTracker mDischargeStepTracker = new LevelStepTracker(MAX_LEVEL_STEPS); 970 final LevelStepTracker mDailyDischargeStepTracker = new LevelStepTracker(MAX_LEVEL_STEPS*2); 971 ArrayList<PackageChange> mDailyPackageChanges; 972 973 int mLastChargeStepLevel; 974 int mMaxChargeStepLevel; 975 final LevelStepTracker mChargeStepTracker = new LevelStepTracker(MAX_LEVEL_STEPS); 976 final LevelStepTracker mDailyChargeStepTracker = new LevelStepTracker(MAX_LEVEL_STEPS*2); 977 978 static final int MAX_DAILY_ITEMS = 10; 979 980 long mDailyStartTime = 0; 981 long mNextMinDailyDeadline = 0; 982 long mNextMaxDailyDeadline = 0; 983 984 final ArrayList<DailyItem> mDailyItems = new ArrayList<>(); 985 986 long mLastWriteTime = 0; // Milliseconds 987 988 private int mPhoneServiceState = -1; 989 private int mPhoneServiceStateRaw = -1; 990 private int mPhoneSimStateRaw = -1; 991 992 private int mNumConnectivityChange; 993 994 private int mEstimatedBatteryCapacity = -1; 995 996 private int mMinLearnedBatteryCapacity = -1; 997 private int mMaxLearnedBatteryCapacity = -1; 998 999 private long mBatteryTimeToFullSeconds = -1; 1000 1001 private long[] mCpuFreqs; 1002 1003 @VisibleForTesting 1004 protected PowerProfile mPowerProfile; 1005 1006 @GuardedBy("this") 1007 final Constants mConstants; 1008 1009 /* 1010 * Holds a SamplingTimer associated with each Resource Power Manager state and voter, 1011 * recording their times when on-battery (regardless of screen state). 1012 */ 1013 private final HashMap<String, SamplingTimer> mRpmStats = new HashMap<>(); 1014 /** Times for each Resource Power Manager state and voter when screen-off and on-battery. */ 1015 private final HashMap<String, SamplingTimer> mScreenOffRpmStats = new HashMap<>(); 1016 1017 @Override getRpmStats()1018 public Map<String, ? extends Timer> getRpmStats() { 1019 return mRpmStats; 1020 } 1021 1022 // TODO: Note: screenOffRpmStats has been disabled via SCREEN_OFF_RPM_STATS_ENABLED. 1023 @Override getScreenOffRpmStats()1024 public Map<String, ? extends Timer> getScreenOffRpmStats() { 1025 return mScreenOffRpmStats; 1026 } 1027 1028 /* 1029 * Holds a SamplingTimer associated with each kernel wakelock name being tracked. 1030 */ 1031 private final HashMap<String, SamplingTimer> mKernelWakelockStats = new HashMap<>(); 1032 1033 @UnsupportedAppUsage getKernelWakelockStats()1034 public Map<String, ? extends Timer> getKernelWakelockStats() { 1035 return mKernelWakelockStats; 1036 } 1037 1038 String mLastWakeupReason = null; 1039 long mLastWakeupUptimeMs = 0; 1040 private final HashMap<String, SamplingTimer> mWakeupReasonStats = new HashMap<>(); 1041 getWakeupReasonStats()1042 public Map<String, ? extends Timer> getWakeupReasonStats() { 1043 return mWakeupReasonStats; 1044 } 1045 1046 @Override getUahDischarge(int which)1047 public long getUahDischarge(int which) { 1048 return mDischargeCounter.getCountLocked(which); 1049 } 1050 1051 @Override getUahDischargeScreenOff(int which)1052 public long getUahDischargeScreenOff(int which) { 1053 return mDischargeScreenOffCounter.getCountLocked(which); 1054 } 1055 1056 @Override getUahDischargeScreenDoze(int which)1057 public long getUahDischargeScreenDoze(int which) { 1058 return mDischargeScreenDozeCounter.getCountLocked(which); 1059 } 1060 1061 @Override getUahDischargeLightDoze(int which)1062 public long getUahDischargeLightDoze(int which) { 1063 return mDischargeLightDozeCounter.getCountLocked(which); 1064 } 1065 1066 @Override getUahDischargeDeepDoze(int which)1067 public long getUahDischargeDeepDoze(int which) { 1068 return mDischargeDeepDozeCounter.getCountLocked(which); 1069 } 1070 1071 @Override getEstimatedBatteryCapacity()1072 public int getEstimatedBatteryCapacity() { 1073 return mEstimatedBatteryCapacity; 1074 } 1075 1076 @Override getMinLearnedBatteryCapacity()1077 public int getMinLearnedBatteryCapacity() { 1078 return mMinLearnedBatteryCapacity; 1079 } 1080 1081 @Override getMaxLearnedBatteryCapacity()1082 public int getMaxLearnedBatteryCapacity() { 1083 return mMaxLearnedBatteryCapacity; 1084 } 1085 BatteryStatsImpl()1086 public BatteryStatsImpl() { 1087 this(new SystemClocks()); 1088 } 1089 BatteryStatsImpl(Clocks clocks)1090 public BatteryStatsImpl(Clocks clocks) { 1091 init(clocks); 1092 mStatsFile = null; 1093 mCheckinFile = null; 1094 mDailyFile = null; 1095 mBatteryStatsHistory = null; 1096 mHandler = null; 1097 mPlatformIdleStateCallback = null; 1098 mRailEnergyDataCallback = null; 1099 mUserInfoProvider = null; 1100 mConstants = new Constants(mHandler); 1101 clearHistoryLocked(); 1102 } 1103 init(Clocks clocks)1104 private void init(Clocks clocks) { 1105 mClocks = clocks; 1106 } 1107 1108 /** 1109 * TimeBase observer. 1110 */ 1111 public interface TimeBaseObs { onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime)1112 void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime); onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime)1113 void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime); 1114 1115 /** 1116 * Reset the observer's state, returns true if the timer/counter is inactive 1117 * so it can be destroyed. 1118 * @param detachIfReset detach if true, no-op if false. 1119 * @return Returns true if the timer/counter is inactive and can be destroyed. 1120 */ reset(boolean detachIfReset)1121 boolean reset(boolean detachIfReset); 1122 /** 1123 * Detach the observer from TimeBase. 1124 */ detach()1125 void detach(); 1126 } 1127 1128 // methods are protected not private to be VisibleForTesting 1129 public static class TimeBase { 1130 protected final Collection<TimeBaseObs> mObservers; 1131 protected long mUptime; 1132 protected long mRealtime; 1133 1134 protected boolean mRunning; 1135 1136 protected long mPastUptime; 1137 protected long mUptimeStart; 1138 protected long mPastRealtime; 1139 protected long mRealtimeStart; 1140 protected long mUnpluggedUptime; 1141 protected long mUnpluggedRealtime; 1142 dump(PrintWriter pw, String prefix)1143 public void dump(PrintWriter pw, String prefix) { 1144 StringBuilder sb = new StringBuilder(128); 1145 pw.print(prefix); pw.print("mRunning="); pw.println(mRunning); 1146 sb.setLength(0); 1147 sb.append(prefix); 1148 sb.append("mUptime="); 1149 formatTimeMs(sb, mUptime / 1000); 1150 pw.println(sb.toString()); 1151 sb.setLength(0); 1152 sb.append(prefix); 1153 sb.append("mRealtime="); 1154 formatTimeMs(sb, mRealtime / 1000); 1155 pw.println(sb.toString()); 1156 sb.setLength(0); 1157 sb.append(prefix); 1158 sb.append("mPastUptime="); 1159 formatTimeMs(sb, mPastUptime / 1000); sb.append("mUptimeStart="); 1160 formatTimeMs(sb, mUptimeStart / 1000); 1161 sb.append("mUnpluggedUptime="); formatTimeMs(sb, mUnpluggedUptime / 1000); 1162 pw.println(sb.toString()); 1163 sb.setLength(0); 1164 sb.append(prefix); 1165 sb.append("mPastRealtime="); 1166 formatTimeMs(sb, mPastRealtime / 1000); sb.append("mRealtimeStart="); 1167 formatTimeMs(sb, mRealtimeStart / 1000); 1168 sb.append("mUnpluggedRealtime="); formatTimeMs(sb, mUnpluggedRealtime / 1000); 1169 pw.println(sb.toString()); 1170 } 1171 /** 1172 * The mObservers of TimeBase in BatteryStatsImpl object can contain up to 20k entries. 1173 * The mObservers of TimeBase in BatteryStatsImpl.Uid object only contains a few or tens of 1174 * entries. 1175 * mObservers must have good performance on add(), remove(), also be memory efficient. 1176 * This is why we provide isLongList parameter for long and short list user cases. 1177 * @param isLongList If true, use HashSet for mObservers list. 1178 * If false, use ArrayList for mObservers list. 1179 */ TimeBase(boolean isLongList)1180 public TimeBase(boolean isLongList) { 1181 mObservers = isLongList ? new HashSet<>() : new ArrayList<>(); 1182 } 1183 TimeBase()1184 public TimeBase() { 1185 this(false); 1186 } 1187 add(TimeBaseObs observer)1188 public void add(TimeBaseObs observer) { 1189 mObservers.add(observer); 1190 } 1191 remove(TimeBaseObs observer)1192 public void remove(TimeBaseObs observer) { 1193 mObservers.remove(observer); 1194 } 1195 hasObserver(TimeBaseObs observer)1196 public boolean hasObserver(TimeBaseObs observer) { 1197 return mObservers.contains(observer); 1198 } 1199 init(long uptime, long realtime)1200 public void init(long uptime, long realtime) { 1201 mRealtime = 0; 1202 mUptime = 0; 1203 mPastUptime = 0; 1204 mPastRealtime = 0; 1205 mUptimeStart = uptime; 1206 mRealtimeStart = realtime; 1207 mUnpluggedUptime = getUptime(mUptimeStart); 1208 mUnpluggedRealtime = getRealtime(mRealtimeStart); 1209 } 1210 reset(long uptime, long realtime)1211 public void reset(long uptime, long realtime) { 1212 if (!mRunning) { 1213 mPastUptime = 0; 1214 mPastRealtime = 0; 1215 } else { 1216 mUptimeStart = uptime; 1217 mRealtimeStart = realtime; 1218 // TODO: Since mUptimeStart was just reset and we are running, getUptime will 1219 // just return mPastUptime. Also, are we sure we don't want to reset that? 1220 mUnpluggedUptime = getUptime(uptime); 1221 // TODO: likewise. 1222 mUnpluggedRealtime = getRealtime(realtime); 1223 } 1224 } 1225 computeUptime(long curTime, int which)1226 public long computeUptime(long curTime, int which) { 1227 return mUptime + getUptime(curTime); 1228 } 1229 computeRealtime(long curTime, int which)1230 public long computeRealtime(long curTime, int which) { 1231 return mRealtime + getRealtime(curTime); 1232 } 1233 getUptime(long curTime)1234 public long getUptime(long curTime) { 1235 long time = mPastUptime; 1236 if (mRunning) { 1237 time += curTime - mUptimeStart; 1238 } 1239 return time; 1240 } 1241 getRealtime(long curTime)1242 public long getRealtime(long curTime) { 1243 long time = mPastRealtime; 1244 if (mRunning) { 1245 time += curTime - mRealtimeStart; 1246 } 1247 return time; 1248 } 1249 getUptimeStart()1250 public long getUptimeStart() { 1251 return mUptimeStart; 1252 } 1253 getRealtimeStart()1254 public long getRealtimeStart() { 1255 return mRealtimeStart; 1256 } 1257 isRunning()1258 public boolean isRunning() { 1259 return mRunning; 1260 } 1261 setRunning(boolean running, long uptime, long realtime)1262 public boolean setRunning(boolean running, long uptime, long realtime) { 1263 if (mRunning != running) { 1264 mRunning = running; 1265 if (running) { 1266 mUptimeStart = uptime; 1267 mRealtimeStart = realtime; 1268 long batteryUptime = mUnpluggedUptime = getUptime(uptime); 1269 long batteryRealtime = mUnpluggedRealtime = getRealtime(realtime); 1270 // Normally we do not use Iterator in framework code to avoid alloc/dealloc 1271 // Iterator object, here is an exception because mObservers' type is Collection 1272 // instead of list. 1273 final Iterator<TimeBaseObs> iter = mObservers.iterator(); 1274 while (iter.hasNext()) { 1275 iter.next().onTimeStarted(realtime, batteryUptime, batteryRealtime); 1276 } 1277 } else { 1278 mPastUptime += uptime - mUptimeStart; 1279 mPastRealtime += realtime - mRealtimeStart; 1280 long batteryUptime = getUptime(uptime); 1281 long batteryRealtime = getRealtime(realtime); 1282 // Normally we do not use Iterator in framework code to avoid alloc/dealloc 1283 // Iterator object, here is an exception because mObservers' type is Collection 1284 // instead of list. 1285 final Iterator<TimeBaseObs> iter = mObservers.iterator(); 1286 while (iter.hasNext()) { 1287 iter.next().onTimeStopped(realtime, batteryUptime, batteryRealtime); 1288 } 1289 } 1290 return true; 1291 } 1292 return false; 1293 } 1294 readSummaryFromParcel(Parcel in)1295 public void readSummaryFromParcel(Parcel in) { 1296 mUptime = in.readLong(); 1297 mRealtime = in.readLong(); 1298 } 1299 writeSummaryToParcel(Parcel out, long uptime, long realtime)1300 public void writeSummaryToParcel(Parcel out, long uptime, long realtime) { 1301 out.writeLong(computeUptime(uptime, STATS_SINCE_CHARGED)); 1302 out.writeLong(computeRealtime(realtime, STATS_SINCE_CHARGED)); 1303 } 1304 readFromParcel(Parcel in)1305 public void readFromParcel(Parcel in) { 1306 mRunning = false; 1307 mUptime = in.readLong(); 1308 mPastUptime = in.readLong(); 1309 mUptimeStart = in.readLong(); 1310 mRealtime = in.readLong(); 1311 mPastRealtime = in.readLong(); 1312 mRealtimeStart = in.readLong(); 1313 mUnpluggedUptime = in.readLong(); 1314 mUnpluggedRealtime = in.readLong(); 1315 } 1316 writeToParcel(Parcel out, long uptime, long realtime)1317 public void writeToParcel(Parcel out, long uptime, long realtime) { 1318 final long runningUptime = getUptime(uptime); 1319 final long runningRealtime = getRealtime(realtime); 1320 out.writeLong(mUptime); 1321 out.writeLong(runningUptime); 1322 out.writeLong(mUptimeStart); 1323 out.writeLong(mRealtime); 1324 out.writeLong(runningRealtime); 1325 out.writeLong(mRealtimeStart); 1326 out.writeLong(mUnpluggedUptime); 1327 out.writeLong(mUnpluggedRealtime); 1328 } 1329 } 1330 1331 /** 1332 * State for keeping track of counting information. 1333 */ 1334 public static class Counter extends BatteryStats.Counter implements TimeBaseObs { 1335 @UnsupportedAppUsage 1336 final AtomicInteger mCount = new AtomicInteger(); 1337 final TimeBase mTimeBase; 1338 Counter(TimeBase timeBase, Parcel in)1339 public Counter(TimeBase timeBase, Parcel in) { 1340 mTimeBase = timeBase; 1341 mCount.set(in.readInt()); 1342 timeBase.add(this); 1343 } 1344 Counter(TimeBase timeBase)1345 public Counter(TimeBase timeBase) { 1346 mTimeBase = timeBase; 1347 timeBase.add(this); 1348 } 1349 writeToParcel(Parcel out)1350 public void writeToParcel(Parcel out) { 1351 out.writeInt(mCount.get()); 1352 } 1353 1354 @Override onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime)1355 public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) { 1356 } 1357 1358 @Override onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime)1359 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) { 1360 } 1361 1362 /** 1363 * Writes a possibly null Counter to a Parcel. 1364 * 1365 * @param out the Parcel to be written to. 1366 * @param counter a Counter, or null. 1367 */ writeCounterToParcel(Parcel out, @Nullable Counter counter)1368 public static void writeCounterToParcel(Parcel out, @Nullable Counter counter) { 1369 if (counter == null) { 1370 out.writeInt(0); // indicates null 1371 return; 1372 } 1373 out.writeInt(1); // indicates non-null 1374 1375 counter.writeToParcel(out); 1376 } 1377 1378 /** 1379 * Reads a Counter that was written using {@link #writeCounterToParcel(Parcel, Counter)}. 1380 * @param timeBase the timebase to assign to the Counter 1381 * @param in the parcel to read from 1382 * @return the Counter or null. 1383 */ readCounterFromParcel(TimeBase timeBase, Parcel in)1384 public static @Nullable Counter readCounterFromParcel(TimeBase timeBase, Parcel in) { 1385 if (in.readInt() == 0) { 1386 return null; 1387 } 1388 return new Counter(timeBase, in); 1389 } 1390 1391 @Override getCountLocked(int which)1392 public int getCountLocked(int which) { 1393 return mCount.get(); 1394 } 1395 logState(Printer pw, String prefix)1396 public void logState(Printer pw, String prefix) { 1397 pw.println(prefix + "mCount=" + mCount.get()); 1398 } 1399 1400 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) stepAtomic()1401 public void stepAtomic() { 1402 if (mTimeBase.isRunning()) { 1403 mCount.incrementAndGet(); 1404 } 1405 } 1406 addAtomic(int delta)1407 void addAtomic(int delta) { 1408 if (mTimeBase.isRunning()) { 1409 mCount.addAndGet(delta); 1410 } 1411 } 1412 1413 /** 1414 * Clear state of this counter. 1415 */ 1416 @Override reset(boolean detachIfReset)1417 public boolean reset(boolean detachIfReset) { 1418 mCount.set(0); 1419 if (detachIfReset) { 1420 detach(); 1421 } 1422 return true; 1423 } 1424 1425 @Override detach()1426 public void detach() { 1427 mTimeBase.remove(this); 1428 } 1429 1430 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) writeSummaryFromParcelLocked(Parcel out)1431 public void writeSummaryFromParcelLocked(Parcel out) { 1432 out.writeInt(mCount.get()); 1433 } 1434 1435 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) readSummaryFromParcelLocked(Parcel in)1436 public void readSummaryFromParcelLocked(Parcel in) { 1437 mCount.set(in.readInt()); 1438 } 1439 } 1440 1441 @VisibleForTesting 1442 public static class LongSamplingCounterArray extends LongCounterArray implements TimeBaseObs { 1443 final TimeBase mTimeBase; 1444 public long[] mCounts; 1445 LongSamplingCounterArray(TimeBase timeBase, Parcel in)1446 private LongSamplingCounterArray(TimeBase timeBase, Parcel in) { 1447 mTimeBase = timeBase; 1448 mCounts = in.createLongArray(); 1449 timeBase.add(this); 1450 } 1451 LongSamplingCounterArray(TimeBase timeBase)1452 public LongSamplingCounterArray(TimeBase timeBase) { 1453 mTimeBase = timeBase; 1454 timeBase.add(this); 1455 } 1456 writeToParcel(Parcel out)1457 private void writeToParcel(Parcel out) { 1458 out.writeLongArray(mCounts); 1459 } 1460 1461 @Override onTimeStarted(long elapsedRealTime, long baseUptime, long baseRealtime)1462 public void onTimeStarted(long elapsedRealTime, long baseUptime, long baseRealtime) { 1463 } 1464 1465 @Override onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime)1466 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) { 1467 } 1468 1469 @Override getCountsLocked(int which)1470 public long[] getCountsLocked(int which) { 1471 return mCounts == null ? null : Arrays.copyOf(mCounts, mCounts.length); 1472 } 1473 1474 @Override logState(Printer pw, String prefix)1475 public void logState(Printer pw, String prefix) { 1476 pw.println(prefix + "mCounts=" + Arrays.toString(mCounts)); 1477 } 1478 addCountLocked(long[] counts)1479 public void addCountLocked(long[] counts) { 1480 addCountLocked(counts, mTimeBase.isRunning()); 1481 } 1482 addCountLocked(long[] counts, boolean isRunning)1483 public void addCountLocked(long[] counts, boolean isRunning) { 1484 if (counts == null) { 1485 return; 1486 } 1487 if (isRunning) { 1488 if (mCounts == null) { 1489 mCounts = new long[counts.length]; 1490 } 1491 for (int i = 0; i < counts.length; ++i) { 1492 mCounts[i] += counts[i]; 1493 } 1494 } 1495 } 1496 getSize()1497 public int getSize() { 1498 return mCounts == null ? 0 : mCounts.length; 1499 } 1500 1501 /** 1502 * Clear state of this counter. 1503 */ 1504 @Override reset(boolean detachIfReset)1505 public boolean reset(boolean detachIfReset) { 1506 if (mCounts != null) { 1507 Arrays.fill(mCounts, 0); 1508 } 1509 if (detachIfReset) { 1510 detach(); 1511 } 1512 return true; 1513 } 1514 1515 @Override detach()1516 public void detach() { 1517 mTimeBase.remove(this); 1518 } 1519 writeSummaryToParcelLocked(Parcel out)1520 private void writeSummaryToParcelLocked(Parcel out) { 1521 out.writeLongArray(mCounts); 1522 } 1523 readSummaryFromParcelLocked(Parcel in)1524 private void readSummaryFromParcelLocked(Parcel in) { 1525 mCounts = in.createLongArray(); 1526 } 1527 writeToParcel(Parcel out, LongSamplingCounterArray counterArray)1528 public static void writeToParcel(Parcel out, LongSamplingCounterArray counterArray) { 1529 if (counterArray != null) { 1530 out.writeInt(1); 1531 counterArray.writeToParcel(out); 1532 } else { 1533 out.writeInt(0); 1534 } 1535 } 1536 readFromParcel(Parcel in, TimeBase timeBase)1537 public static LongSamplingCounterArray readFromParcel(Parcel in, TimeBase timeBase) { 1538 if (in.readInt() != 0) { 1539 return new LongSamplingCounterArray(timeBase, in); 1540 } else { 1541 return null; 1542 } 1543 } 1544 writeSummaryToParcelLocked(Parcel out, LongSamplingCounterArray counterArray)1545 public static void writeSummaryToParcelLocked(Parcel out, 1546 LongSamplingCounterArray counterArray) { 1547 if (counterArray != null) { 1548 out.writeInt(1); 1549 counterArray.writeSummaryToParcelLocked(out); 1550 } else { 1551 out.writeInt(0); 1552 } 1553 } 1554 readSummaryFromParcelLocked(Parcel in, TimeBase timeBase)1555 public static LongSamplingCounterArray readSummaryFromParcelLocked(Parcel in, 1556 TimeBase timeBase) { 1557 if (in.readInt() != 0) { 1558 final LongSamplingCounterArray counterArray 1559 = new LongSamplingCounterArray(timeBase); 1560 counterArray.readSummaryFromParcelLocked(in); 1561 return counterArray; 1562 } else { 1563 return null; 1564 } 1565 } 1566 } 1567 1568 @VisibleForTesting 1569 public static class LongSamplingCounter extends LongCounter implements TimeBaseObs { 1570 final TimeBase mTimeBase; 1571 private long mCount; 1572 LongSamplingCounter(TimeBase timeBase, Parcel in)1573 public LongSamplingCounter(TimeBase timeBase, Parcel in) { 1574 mTimeBase = timeBase; 1575 mCount = in.readLong(); 1576 timeBase.add(this); 1577 } 1578 LongSamplingCounter(TimeBase timeBase)1579 public LongSamplingCounter(TimeBase timeBase) { 1580 mTimeBase = timeBase; 1581 timeBase.add(this); 1582 } 1583 writeToParcel(Parcel out)1584 public void writeToParcel(Parcel out) { 1585 out.writeLong(mCount); 1586 } 1587 1588 @Override onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime)1589 public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) { 1590 } 1591 1592 @Override onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime)1593 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) { 1594 } 1595 getCountLocked(int which)1596 public long getCountLocked(int which) { 1597 return mCount; 1598 } 1599 1600 @Override logState(Printer pw, String prefix)1601 public void logState(Printer pw, String prefix) { 1602 pw.println(prefix + "mCount=" + mCount); 1603 } 1604 addCountLocked(long count)1605 public void addCountLocked(long count) { 1606 addCountLocked(count, mTimeBase.isRunning()); 1607 } 1608 addCountLocked(long count, boolean isRunning)1609 public void addCountLocked(long count, boolean isRunning) { 1610 if (isRunning) { 1611 mCount += count; 1612 } 1613 } 1614 1615 /** 1616 * Clear state of this counter. 1617 */ 1618 @Override reset(boolean detachIfReset)1619 public boolean reset(boolean detachIfReset) { 1620 mCount = 0; 1621 if (detachIfReset) { 1622 detach(); 1623 } 1624 return true; 1625 } 1626 1627 @Override detach()1628 public void detach() { 1629 mTimeBase.remove(this); 1630 } 1631 writeSummaryFromParcelLocked(Parcel out)1632 public void writeSummaryFromParcelLocked(Parcel out) { 1633 out.writeLong(mCount); 1634 } 1635 readSummaryFromParcelLocked(Parcel in)1636 public void readSummaryFromParcelLocked(Parcel in) { 1637 mCount = in.readLong(); 1638 } 1639 } 1640 1641 /** 1642 * State for keeping track of timing information. 1643 */ 1644 public static abstract class Timer extends BatteryStats.Timer implements TimeBaseObs { 1645 protected final Clocks mClocks; 1646 protected final int mType; 1647 protected final TimeBase mTimeBase; 1648 1649 protected int mCount; 1650 1651 // Times are in microseconds for better accuracy when dividing by the 1652 // lock count, and are in "battery realtime" units. 1653 1654 /** 1655 * The total time we have accumulated since the start of the original 1656 * boot, to the last time something interesting happened in the 1657 * current run. 1658 */ 1659 protected long mTotalTime; 1660 1661 /** 1662 * The total time this timer has been running until the latest mark has been set. 1663 * Subtract this from mTotalTime to get the time spent running since the mark was set. 1664 */ 1665 protected long mTimeBeforeMark; 1666 1667 /** 1668 * Constructs from a parcel. 1669 * @param type 1670 * @param timeBase 1671 * @param in 1672 */ Timer(Clocks clocks, int type, TimeBase timeBase, Parcel in)1673 public Timer(Clocks clocks, int type, TimeBase timeBase, Parcel in) { 1674 mClocks = clocks; 1675 mType = type; 1676 mTimeBase = timeBase; 1677 1678 mCount = in.readInt(); 1679 mTotalTime = in.readLong(); 1680 mTimeBeforeMark = in.readLong(); 1681 timeBase.add(this); 1682 if (DEBUG) Log.i(TAG, "**** READ TIMER #" + mType + ": mTotalTime=" + mTotalTime); 1683 } 1684 Timer(Clocks clocks, int type, TimeBase timeBase)1685 public Timer(Clocks clocks, int type, TimeBase timeBase) { 1686 mClocks = clocks; 1687 mType = type; 1688 mTimeBase = timeBase; 1689 timeBase.add(this); 1690 } 1691 writeToParcel(Parcel out, long elapsedRealtimeUs)1692 public void writeToParcel(Parcel out, long elapsedRealtimeUs) { 1693 if (DEBUG) { 1694 Log.i(TAG, "**** WRITING TIMER #" + mType + ": mTotalTime=" 1695 + computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs))); 1696 } 1697 out.writeInt(computeCurrentCountLocked()); 1698 out.writeLong(computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs))); 1699 out.writeLong(mTimeBeforeMark); 1700 } 1701 computeRunTimeLocked(long curBatteryRealtime)1702 protected abstract long computeRunTimeLocked(long curBatteryRealtime); 1703 computeCurrentCountLocked()1704 protected abstract int computeCurrentCountLocked(); 1705 1706 /** 1707 * Clear state of this timer. Returns true if the timer is inactive 1708 * so can be completely dropped. 1709 */ 1710 @Override reset(boolean detachIfReset)1711 public boolean reset(boolean detachIfReset) { 1712 mTotalTime = mTimeBeforeMark = 0; 1713 mCount = 0; 1714 if (detachIfReset) { 1715 detach(); 1716 } 1717 return true; 1718 } 1719 1720 @Override detach()1721 public void detach() { 1722 mTimeBase.remove(this); 1723 } 1724 1725 @Override onTimeStarted(long elapsedRealtime, long timeBaseUptime, long baseRealtime)1726 public void onTimeStarted(long elapsedRealtime, long timeBaseUptime, long baseRealtime) { 1727 } 1728 1729 @Override onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime)1730 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) { 1731 if (DEBUG && mType < 0) { 1732 Log.v(TAG, "plug #" + mType + ": realtime=" + baseRealtime 1733 + " old mTotalTime=" + mTotalTime); 1734 } 1735 mTotalTime = computeRunTimeLocked(baseRealtime); 1736 mCount = computeCurrentCountLocked(); 1737 if (DEBUG && mType < 0) { 1738 Log.v(TAG, "plug #" + mType + ": new mTotalTime=" + mTotalTime); 1739 } 1740 } 1741 1742 /** 1743 * Writes a possibly null Timer to a Parcel. 1744 * 1745 * @param out the Parcel to be written to. 1746 * @param timer a Timer, or null. 1747 */ 1748 @UnsupportedAppUsage writeTimerToParcel(Parcel out, Timer timer, long elapsedRealtimeUs)1749 public static void writeTimerToParcel(Parcel out, Timer timer, long elapsedRealtimeUs) { 1750 if (timer == null) { 1751 out.writeInt(0); // indicates null 1752 return; 1753 } 1754 out.writeInt(1); // indicates non-null 1755 timer.writeToParcel(out, elapsedRealtimeUs); 1756 } 1757 1758 @Override 1759 @UnsupportedAppUsage getTotalTimeLocked(long elapsedRealtimeUs, int which)1760 public long getTotalTimeLocked(long elapsedRealtimeUs, int which) { 1761 return computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs)); 1762 } 1763 1764 @Override 1765 @UnsupportedAppUsage getCountLocked(int which)1766 public int getCountLocked(int which) { 1767 return computeCurrentCountLocked(); 1768 } 1769 1770 @Override getTimeSinceMarkLocked(long elapsedRealtimeUs)1771 public long getTimeSinceMarkLocked(long elapsedRealtimeUs) { 1772 long val = computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs)); 1773 return val - mTimeBeforeMark; 1774 } 1775 1776 @Override logState(Printer pw, String prefix)1777 public void logState(Printer pw, String prefix) { 1778 pw.println(prefix + "mCount=" + mCount); 1779 pw.println(prefix + "mTotalTime=" + mTotalTime); 1780 } 1781 1782 writeSummaryFromParcelLocked(Parcel out, long elapsedRealtimeUs)1783 public void writeSummaryFromParcelLocked(Parcel out, long elapsedRealtimeUs) { 1784 long runTime = computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs)); 1785 out.writeLong(runTime); 1786 out.writeInt(computeCurrentCountLocked()); 1787 } 1788 readSummaryFromParcelLocked(Parcel in)1789 public void readSummaryFromParcelLocked(Parcel in) { 1790 // Multiply by 1000 for backwards compatibility 1791 mTotalTime = in.readLong(); 1792 mCount = in.readInt(); 1793 // When reading the summary, we set the mark to be the latest information. 1794 mTimeBeforeMark = mTotalTime; 1795 } 1796 } 1797 1798 /** 1799 * A counter meant to accept monotonically increasing values to its {@link #update(long, int)} 1800 * method. The state of the timer according to its {@link TimeBase} will determine how much 1801 * of the value is recorded. 1802 * 1803 * If the value being recorded resets, {@link #endSample()} can be called in order to 1804 * account for the change. If the value passed in to {@link #update(long, int)} decreased 1805 * between calls, the {@link #endSample()} is automatically called and the new value is 1806 * expected to increase monotonically from that point on. 1807 */ 1808 public static class SamplingTimer extends Timer { 1809 1810 /** 1811 * The most recent reported count from /proc/wakelocks. 1812 */ 1813 int mCurrentReportedCount; 1814 1815 /** 1816 * The reported count from /proc/wakelocks when unplug() was last 1817 * called. 1818 */ 1819 int mUnpluggedReportedCount; 1820 1821 /** 1822 * The most recent reported total_time from /proc/wakelocks. 1823 */ 1824 long mCurrentReportedTotalTime; 1825 1826 1827 /** 1828 * The reported total_time from /proc/wakelocks when unplug() was last 1829 * called. 1830 */ 1831 long mUnpluggedReportedTotalTime; 1832 1833 /** 1834 * Whether we are currently in a discharge cycle. 1835 */ 1836 boolean mTimeBaseRunning; 1837 1838 /** 1839 * Whether we are currently recording reported values. 1840 */ 1841 boolean mTrackingReportedValues; 1842 1843 /* 1844 * A sequence counter, incremented once for each update of the stats. 1845 */ 1846 int mUpdateVersion; 1847 1848 @VisibleForTesting SamplingTimer(Clocks clocks, TimeBase timeBase, Parcel in)1849 public SamplingTimer(Clocks clocks, TimeBase timeBase, Parcel in) { 1850 super(clocks, 0, timeBase, in); 1851 mCurrentReportedCount = in.readInt(); 1852 mUnpluggedReportedCount = in.readInt(); 1853 mCurrentReportedTotalTime = in.readLong(); 1854 mUnpluggedReportedTotalTime = in.readLong(); 1855 mTrackingReportedValues = in.readInt() == 1; 1856 mTimeBaseRunning = timeBase.isRunning(); 1857 } 1858 1859 @VisibleForTesting SamplingTimer(Clocks clocks, TimeBase timeBase)1860 public SamplingTimer(Clocks clocks, TimeBase timeBase) { 1861 super(clocks, 0, timeBase); 1862 mTrackingReportedValues = false; 1863 mTimeBaseRunning = timeBase.isRunning(); 1864 } 1865 1866 /** 1867 * Ends the current sample, allowing subsequent values to {@link #update(long, int)} to 1868 * be less than the values used for a previous invocation. 1869 */ endSample()1870 public void endSample() { 1871 mTotalTime = computeRunTimeLocked(0 /* unused by us */); 1872 mCount = computeCurrentCountLocked(); 1873 mUnpluggedReportedTotalTime = mCurrentReportedTotalTime = 0; 1874 mUnpluggedReportedCount = mCurrentReportedCount = 0; 1875 mTrackingReportedValues = false; 1876 } 1877 setUpdateVersion(int version)1878 public void setUpdateVersion(int version) { 1879 mUpdateVersion = version; 1880 } 1881 getUpdateVersion()1882 public int getUpdateVersion() { 1883 return mUpdateVersion; 1884 } 1885 1886 /** 1887 * Updates the current recorded values. These are meant to be monotonically increasing 1888 * and cumulative. If you are dealing with deltas, use {@link #add(long, int)}. 1889 * 1890 * If the values being recorded have been reset, the monotonically increasing requirement 1891 * will be broken. In this case, {@link #endSample()} is automatically called and 1892 * the total value of totalTime and count are recorded, starting a new monotonically 1893 * increasing sample. 1894 * 1895 * @param totalTime total time of sample in microseconds. 1896 * @param count total number of times the event being sampled occurred. 1897 */ update(long totalTime, int count)1898 public void update(long totalTime, int count) { 1899 if (mTimeBaseRunning && !mTrackingReportedValues) { 1900 // Updating the reported value for the first time. 1901 mUnpluggedReportedTotalTime = totalTime; 1902 mUnpluggedReportedCount = count; 1903 } 1904 1905 mTrackingReportedValues = true; 1906 1907 if (totalTime < mCurrentReportedTotalTime || count < mCurrentReportedCount) { 1908 endSample(); 1909 } 1910 1911 mCurrentReportedTotalTime = totalTime; 1912 mCurrentReportedCount = count; 1913 } 1914 1915 /** 1916 * Adds deltaTime and deltaCount to the current sample. 1917 * 1918 * @param deltaTime additional time recorded since the last sampled event, in microseconds. 1919 * @param deltaCount additional number of times the event being sampled occurred. 1920 */ add(long deltaTime, int deltaCount)1921 public void add(long deltaTime, int deltaCount) { 1922 update(mCurrentReportedTotalTime + deltaTime, mCurrentReportedCount + deltaCount); 1923 } 1924 1925 @Override onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime)1926 public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) { 1927 super.onTimeStarted(elapsedRealtime, baseUptime, baseRealtime); 1928 if (mTrackingReportedValues) { 1929 mUnpluggedReportedTotalTime = mCurrentReportedTotalTime; 1930 mUnpluggedReportedCount = mCurrentReportedCount; 1931 } 1932 mTimeBaseRunning = true; 1933 } 1934 1935 @Override onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime)1936 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) { 1937 super.onTimeStopped(elapsedRealtime, baseUptime, baseRealtime); 1938 mTimeBaseRunning = false; 1939 } 1940 1941 @Override logState(Printer pw, String prefix)1942 public void logState(Printer pw, String prefix) { 1943 super.logState(pw, prefix); 1944 pw.println(prefix + "mCurrentReportedCount=" + mCurrentReportedCount 1945 + " mUnpluggedReportedCount=" + mUnpluggedReportedCount 1946 + " mCurrentReportedTotalTime=" + mCurrentReportedTotalTime 1947 + " mUnpluggedReportedTotalTime=" + mUnpluggedReportedTotalTime); 1948 } 1949 1950 @Override computeRunTimeLocked(long curBatteryRealtime)1951 protected long computeRunTimeLocked(long curBatteryRealtime) { 1952 return mTotalTime + (mTimeBaseRunning && mTrackingReportedValues 1953 ? mCurrentReportedTotalTime - mUnpluggedReportedTotalTime : 0); 1954 } 1955 1956 @Override computeCurrentCountLocked()1957 protected int computeCurrentCountLocked() { 1958 return mCount + (mTimeBaseRunning && mTrackingReportedValues 1959 ? mCurrentReportedCount - mUnpluggedReportedCount : 0); 1960 } 1961 1962 @Override writeToParcel(Parcel out, long elapsedRealtimeUs)1963 public void writeToParcel(Parcel out, long elapsedRealtimeUs) { 1964 super.writeToParcel(out, elapsedRealtimeUs); 1965 out.writeInt(mCurrentReportedCount); 1966 out.writeInt(mUnpluggedReportedCount); 1967 out.writeLong(mCurrentReportedTotalTime); 1968 out.writeLong(mUnpluggedReportedTotalTime); 1969 out.writeInt(mTrackingReportedValues ? 1 : 0); 1970 } 1971 1972 @Override reset(boolean detachIfReset)1973 public boolean reset(boolean detachIfReset) { 1974 super.reset(detachIfReset); 1975 mTrackingReportedValues = false; 1976 mUnpluggedReportedTotalTime = 0; 1977 mUnpluggedReportedCount = 0; 1978 return true; 1979 } 1980 } 1981 1982 /** 1983 * A timer that increments in batches. It does not run for durations, but just jumps 1984 * for a pre-determined amount. 1985 */ 1986 public static class BatchTimer extends Timer { 1987 final Uid mUid; 1988 1989 /** 1990 * The last time at which we updated the timer. This is in elapsed realtime microseconds. 1991 */ 1992 long mLastAddedTime; 1993 1994 /** 1995 * The last duration that we added to the timer. This is in microseconds. 1996 */ 1997 long mLastAddedDuration; 1998 1999 /** 2000 * Whether we are currently in a discharge cycle. 2001 */ 2002 boolean mInDischarge; 2003 BatchTimer(Clocks clocks, Uid uid, int type, TimeBase timeBase, Parcel in)2004 BatchTimer(Clocks clocks, Uid uid, int type, TimeBase timeBase, Parcel in) { 2005 super(clocks, type, timeBase, in); 2006 mUid = uid; 2007 mLastAddedTime = in.readLong(); 2008 mLastAddedDuration = in.readLong(); 2009 mInDischarge = timeBase.isRunning(); 2010 } 2011 BatchTimer(Clocks clocks, Uid uid, int type, TimeBase timeBase)2012 BatchTimer(Clocks clocks, Uid uid, int type, TimeBase timeBase) { 2013 super(clocks, type, timeBase); 2014 mUid = uid; 2015 mInDischarge = timeBase.isRunning(); 2016 } 2017 2018 @Override writeToParcel(Parcel out, long elapsedRealtimeUs)2019 public void writeToParcel(Parcel out, long elapsedRealtimeUs) { 2020 super.writeToParcel(out, elapsedRealtimeUs); 2021 out.writeLong(mLastAddedTime); 2022 out.writeLong(mLastAddedDuration); 2023 } 2024 2025 @Override onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime)2026 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) { 2027 recomputeLastDuration(mClocks.elapsedRealtime() * 1000, false); 2028 mInDischarge = false; 2029 super.onTimeStopped(elapsedRealtime, baseUptime, baseRealtime); 2030 } 2031 2032 @Override onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime)2033 public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) { 2034 recomputeLastDuration(elapsedRealtime, false); 2035 mInDischarge = true; 2036 // If we are still within the last added duration, then re-added whatever remains. 2037 if (mLastAddedTime == elapsedRealtime) { 2038 mTotalTime += mLastAddedDuration; 2039 } 2040 super.onTimeStarted(elapsedRealtime, baseUptime, baseRealtime); 2041 } 2042 2043 @Override logState(Printer pw, String prefix)2044 public void logState(Printer pw, String prefix) { 2045 super.logState(pw, prefix); 2046 pw.println(prefix + "mLastAddedTime=" + mLastAddedTime 2047 + " mLastAddedDuration=" + mLastAddedDuration); 2048 } 2049 computeOverage(long curTime)2050 private long computeOverage(long curTime) { 2051 if (mLastAddedTime > 0) { 2052 return mLastAddedDuration - curTime; 2053 } 2054 return 0; 2055 } 2056 recomputeLastDuration(long curTime, boolean abort)2057 private void recomputeLastDuration(long curTime, boolean abort) { 2058 final long overage = computeOverage(curTime); 2059 if (overage > 0) { 2060 // Aborting before the duration ran out -- roll back the remaining 2061 // duration. Only do this if currently discharging; otherwise we didn't 2062 // actually add the time. 2063 if (mInDischarge) { 2064 mTotalTime -= overage; 2065 } 2066 if (abort) { 2067 mLastAddedTime = 0; 2068 } else { 2069 mLastAddedTime = curTime; 2070 mLastAddedDuration -= overage; 2071 } 2072 } 2073 } 2074 addDuration(BatteryStatsImpl stats, long durationMillis)2075 public void addDuration(BatteryStatsImpl stats, long durationMillis) { 2076 final long now = mClocks.elapsedRealtime() * 1000; 2077 recomputeLastDuration(now, true); 2078 mLastAddedTime = now; 2079 mLastAddedDuration = durationMillis * 1000; 2080 if (mInDischarge) { 2081 mTotalTime += mLastAddedDuration; 2082 mCount++; 2083 } 2084 } 2085 abortLastDuration(BatteryStatsImpl stats)2086 public void abortLastDuration(BatteryStatsImpl stats) { 2087 final long now = mClocks.elapsedRealtime() * 1000; 2088 recomputeLastDuration(now, true); 2089 } 2090 2091 @Override computeCurrentCountLocked()2092 protected int computeCurrentCountLocked() { 2093 return mCount; 2094 } 2095 2096 @Override computeRunTimeLocked(long curBatteryRealtime)2097 protected long computeRunTimeLocked(long curBatteryRealtime) { 2098 final long overage = computeOverage(mClocks.elapsedRealtime() * 1000); 2099 if (overage > 0) { 2100 return mTotalTime = overage; 2101 } 2102 return mTotalTime; 2103 } 2104 2105 @Override reset(boolean detachIfReset)2106 public boolean reset(boolean detachIfReset) { 2107 final long now = mClocks.elapsedRealtime() * 1000; 2108 recomputeLastDuration(now, true); 2109 boolean stillActive = mLastAddedTime == now; 2110 super.reset(!stillActive && detachIfReset); 2111 return !stillActive; 2112 } 2113 } 2114 2115 2116 /** 2117 * A StopwatchTimer that also tracks the total and max individual 2118 * time spent active according to the given timebase. Whereas 2119 * StopwatchTimer apportions the time amongst all in the pool, 2120 * the total and max durations are not apportioned. 2121 */ 2122 public static class DurationTimer extends StopwatchTimer { 2123 /** 2124 * The time (in ms) that the timer was last acquired or the time base 2125 * last (re-)started. Increasing the nesting depth does not reset this time. 2126 * 2127 * -1 if the timer is currently not running or the time base is not running. 2128 * 2129 * If written to a parcel, the start time is reset, as is mNesting in the base class 2130 * StopwatchTimer. 2131 */ 2132 long mStartTimeMs = -1; 2133 2134 /** 2135 * The longest time period (in ms) that the timer has been active. Not pooled. 2136 */ 2137 long mMaxDurationMs; 2138 2139 /** 2140 * The time (in ms) that that the timer has been active since most recent 2141 * stopRunningLocked() or reset(). Not pooled. 2142 */ 2143 long mCurrentDurationMs; 2144 2145 /** 2146 * The total time (in ms) that that the timer has been active since most recent reset() 2147 * prior to the current startRunningLocked. This is the sum of all past currentDurations 2148 * (but not including the present currentDuration) since reset. Not pooled. 2149 */ 2150 long mTotalDurationMs; 2151 DurationTimer(Clocks clocks, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, TimeBase timeBase, Parcel in)2152 public DurationTimer(Clocks clocks, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, 2153 TimeBase timeBase, Parcel in) { 2154 super(clocks, uid, type, timerPool, timeBase, in); 2155 mMaxDurationMs = in.readLong(); 2156 mTotalDurationMs = in.readLong(); 2157 mCurrentDurationMs = in.readLong(); 2158 } 2159 DurationTimer(Clocks clocks, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, TimeBase timeBase)2160 public DurationTimer(Clocks clocks, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, 2161 TimeBase timeBase) { 2162 super(clocks, uid, type, timerPool, timeBase); 2163 } 2164 2165 @Override writeToParcel(Parcel out, long elapsedRealtimeUs)2166 public void writeToParcel(Parcel out, long elapsedRealtimeUs) { 2167 super.writeToParcel(out, elapsedRealtimeUs); 2168 out.writeLong(getMaxDurationMsLocked(elapsedRealtimeUs / 1000)); 2169 out.writeLong(mTotalDurationMs); 2170 out.writeLong(getCurrentDurationMsLocked(elapsedRealtimeUs / 1000)); 2171 } 2172 2173 /** 2174 * Write the summary to the parcel. 2175 * 2176 * Since the time base is probably meaningless after we come back, reading 2177 * from this will have the effect of stopping the timer. So here all we write 2178 * is the max and total durations. 2179 */ 2180 @Override writeSummaryFromParcelLocked(Parcel out, long elapsedRealtimeUs)2181 public void writeSummaryFromParcelLocked(Parcel out, long elapsedRealtimeUs) { 2182 super.writeSummaryFromParcelLocked(out, elapsedRealtimeUs); 2183 out.writeLong(getMaxDurationMsLocked(elapsedRealtimeUs / 1000)); 2184 out.writeLong(getTotalDurationMsLocked(elapsedRealtimeUs / 1000)); 2185 } 2186 2187 /** 2188 * Read the summary parcel. 2189 * 2190 * Has the side effect of stopping the timer. 2191 */ 2192 @Override readSummaryFromParcelLocked(Parcel in)2193 public void readSummaryFromParcelLocked(Parcel in) { 2194 super.readSummaryFromParcelLocked(in); 2195 mMaxDurationMs = in.readLong(); 2196 mTotalDurationMs = in.readLong(); 2197 mStartTimeMs = -1; 2198 mCurrentDurationMs = 0; 2199 } 2200 2201 /** 2202 * The TimeBase time started (again). 2203 * 2204 * If the timer is also running, store the start time. 2205 */ onTimeStarted(long elapsedRealtimeUs, long baseUptime, long baseRealtime)2206 public void onTimeStarted(long elapsedRealtimeUs, long baseUptime, long baseRealtime) { 2207 super.onTimeStarted(elapsedRealtimeUs, baseUptime, baseRealtime); 2208 if (mNesting > 0) { 2209 mStartTimeMs = baseRealtime / 1000; 2210 } 2211 } 2212 2213 /** 2214 * The TimeBase stopped running. 2215 * 2216 * If the timer is running, add the duration into mCurrentDurationMs. 2217 */ 2218 @Override onTimeStopped(long elapsedRealtimeUs, long baseUptime, long baseRealtimeUs)2219 public void onTimeStopped(long elapsedRealtimeUs, long baseUptime, long baseRealtimeUs) { 2220 super.onTimeStopped(elapsedRealtimeUs, baseUptime, baseRealtimeUs); 2221 if (mNesting > 0) { 2222 // baseRealtimeUs has already been converted to the timebase's realtime. 2223 mCurrentDurationMs += (baseRealtimeUs / 1000) - mStartTimeMs; 2224 } 2225 mStartTimeMs = -1; 2226 } 2227 2228 @Override logState(Printer pw, String prefix)2229 public void logState(Printer pw, String prefix) { 2230 super.logState(pw, prefix); 2231 } 2232 2233 @Override startRunningLocked(long elapsedRealtimeMs)2234 public void startRunningLocked(long elapsedRealtimeMs) { 2235 super.startRunningLocked(elapsedRealtimeMs); 2236 if (mNesting == 1 && mTimeBase.isRunning()) { 2237 // Just started 2238 mStartTimeMs = mTimeBase.getRealtime(elapsedRealtimeMs * 1000) / 1000; 2239 } 2240 } 2241 2242 /** 2243 * Decrements the mNesting ref-count on this timer. 2244 * 2245 * If it actually stopped (mNesting went to 0), then possibly update 2246 * mMaxDuration if the current duration was the longest ever. 2247 */ 2248 @Override stopRunningLocked(long elapsedRealtimeMs)2249 public void stopRunningLocked(long elapsedRealtimeMs) { 2250 if (mNesting == 1) { 2251 final long durationMs = getCurrentDurationMsLocked(elapsedRealtimeMs); 2252 mTotalDurationMs += durationMs; 2253 if (durationMs > mMaxDurationMs) { 2254 mMaxDurationMs = durationMs; 2255 } 2256 mStartTimeMs = -1; 2257 mCurrentDurationMs = 0; 2258 } 2259 // super method decrements mNesting, which getCurrentDurationMsLocked relies on, 2260 // so call super.stopRunningLocked after calling getCurrentDurationMsLocked. 2261 super.stopRunningLocked(elapsedRealtimeMs); 2262 } 2263 2264 @Override reset(boolean detachIfReset)2265 public boolean reset(boolean detachIfReset) { 2266 boolean result = super.reset(detachIfReset); 2267 mMaxDurationMs = 0; 2268 mTotalDurationMs = 0; 2269 mCurrentDurationMs = 0; 2270 if (mNesting > 0) { 2271 mStartTimeMs = mTimeBase.getRealtime(mClocks.elapsedRealtime() * 1000) / 1000; 2272 } else { 2273 mStartTimeMs = -1; 2274 } 2275 return result; 2276 } 2277 2278 /** 2279 * Returns the max duration that this timer has ever seen. 2280 * 2281 * Note that this time is NOT split between the timers in the timer group that 2282 * this timer is attached to. It is the TOTAL time. 2283 */ 2284 @Override getMaxDurationMsLocked(long elapsedRealtimeMs)2285 public long getMaxDurationMsLocked(long elapsedRealtimeMs) { 2286 if (mNesting > 0) { 2287 final long durationMs = getCurrentDurationMsLocked(elapsedRealtimeMs); 2288 if (durationMs > mMaxDurationMs) { 2289 return durationMs; 2290 } 2291 } 2292 return mMaxDurationMs; 2293 } 2294 2295 /** 2296 * Returns the time since the timer was started. 2297 * Returns 0 if the timer is not currently running. 2298 * 2299 * Note that this time is NOT split between the timers in the timer group that 2300 * this timer is attached to. It is the TOTAL time. 2301 * 2302 * Note that if running timer is parceled and unparceled, this method will return 2303 * current duration value at the time of parceling even though timer may not be 2304 * currently running. 2305 */ 2306 @Override getCurrentDurationMsLocked(long elapsedRealtimeMs)2307 public long getCurrentDurationMsLocked(long elapsedRealtimeMs) { 2308 long durationMs = mCurrentDurationMs; 2309 if (mNesting > 0 && mTimeBase.isRunning()) { 2310 durationMs += (mTimeBase.getRealtime(elapsedRealtimeMs * 1000) / 1000) 2311 - mStartTimeMs; 2312 } 2313 return durationMs; 2314 } 2315 2316 /** 2317 * Returns the total cumulative duration that this timer has been on since reset(). 2318 * If mTimerPool == null, this should be the same 2319 * as getTotalTimeLocked(elapsedRealtimeMs*1000, STATS_SINCE_CHARGED)/1000. 2320 * 2321 * Note that this time is NOT split between the timers in the timer group that 2322 * this timer is attached to. It is the TOTAL time. For this reason, if mTimerPool != null, 2323 * the result will not be equivalent to getTotalTimeLocked. 2324 */ 2325 @Override getTotalDurationMsLocked(long elapsedRealtimeMs)2326 public long getTotalDurationMsLocked(long elapsedRealtimeMs) { 2327 return mTotalDurationMs + getCurrentDurationMsLocked(elapsedRealtimeMs); 2328 } 2329 } 2330 2331 /** 2332 * State for keeping track of timing information. 2333 */ 2334 public static class StopwatchTimer extends Timer { 2335 final Uid mUid; 2336 final ArrayList<StopwatchTimer> mTimerPool; 2337 2338 int mNesting; 2339 2340 /** 2341 * The last time at which we updated the timer. If mNesting is > 0, 2342 * subtract this from the current battery time to find the amount of 2343 * time we have been running since we last computed an update. 2344 */ 2345 long mUpdateTime; 2346 2347 /** 2348 * The total time at which the timer was acquired, to determine if it 2349 * was actually held for an interesting duration. If time base was not running when timer 2350 * was acquired, will be -1. 2351 */ 2352 long mAcquireTime = -1; 2353 2354 long mTimeout; 2355 2356 /** 2357 * For partial wake locks, keep track of whether we are in the list 2358 * to consume CPU cycles. 2359 */ 2360 @VisibleForTesting 2361 public boolean mInList; 2362 StopwatchTimer(Clocks clocks, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, TimeBase timeBase, Parcel in)2363 public StopwatchTimer(Clocks clocks, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, 2364 TimeBase timeBase, Parcel in) { 2365 super(clocks, type, timeBase, in); 2366 mUid = uid; 2367 mTimerPool = timerPool; 2368 mUpdateTime = in.readLong(); 2369 } 2370 StopwatchTimer(Clocks clocks, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, TimeBase timeBase)2371 public StopwatchTimer(Clocks clocks, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, 2372 TimeBase timeBase) { 2373 super(clocks, type, timeBase); 2374 mUid = uid; 2375 mTimerPool = timerPool; 2376 } 2377 setTimeout(long timeout)2378 public void setTimeout(long timeout) { 2379 mTimeout = timeout; 2380 } 2381 writeToParcel(Parcel out, long elapsedRealtimeUs)2382 public void writeToParcel(Parcel out, long elapsedRealtimeUs) { 2383 super.writeToParcel(out, elapsedRealtimeUs); 2384 out.writeLong(mUpdateTime); 2385 } 2386 onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime)2387 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) { 2388 if (mNesting > 0) { 2389 if (DEBUG && mType < 0) { 2390 Log.v(TAG, "old mUpdateTime=" + mUpdateTime); 2391 } 2392 super.onTimeStopped(elapsedRealtime, baseUptime, baseRealtime); 2393 mUpdateTime = baseRealtime; 2394 if (DEBUG && mType < 0) { 2395 Log.v(TAG, "new mUpdateTime=" + mUpdateTime); 2396 } 2397 } 2398 } 2399 logState(Printer pw, String prefix)2400 public void logState(Printer pw, String prefix) { 2401 super.logState(pw, prefix); 2402 pw.println(prefix + "mNesting=" + mNesting + " mUpdateTime=" + mUpdateTime 2403 + " mAcquireTime=" + mAcquireTime); 2404 } 2405 startRunningLocked(long elapsedRealtimeMs)2406 public void startRunningLocked(long elapsedRealtimeMs) { 2407 if (mNesting++ == 0) { 2408 final long batteryRealtime = mTimeBase.getRealtime(elapsedRealtimeMs * 1000); 2409 mUpdateTime = batteryRealtime; 2410 if (mTimerPool != null) { 2411 // Accumulate time to all currently active timers before adding 2412 // this new one to the pool. 2413 refreshTimersLocked(batteryRealtime, mTimerPool, null); 2414 // Add this timer to the active pool 2415 mTimerPool.add(this); 2416 } 2417 if (mTimeBase.isRunning()) { 2418 // Increment the count 2419 mCount++; 2420 mAcquireTime = mTotalTime; 2421 } else { 2422 mAcquireTime = -1; 2423 } 2424 if (DEBUG && mType < 0) { 2425 Log.v(TAG, "start #" + mType + ": mUpdateTime=" + mUpdateTime 2426 + " mTotalTime=" + mTotalTime + " mCount=" + mCount 2427 + " mAcquireTime=" + mAcquireTime); 2428 } 2429 } 2430 } 2431 isRunningLocked()2432 public boolean isRunningLocked() { 2433 return mNesting > 0; 2434 } 2435 stopRunningLocked(long elapsedRealtimeMs)2436 public void stopRunningLocked(long elapsedRealtimeMs) { 2437 // Ignore attempt to stop a timer that isn't running 2438 if (mNesting == 0) { 2439 return; 2440 } 2441 if (--mNesting == 0) { 2442 final long batteryRealtime = mTimeBase.getRealtime(elapsedRealtimeMs * 1000); 2443 if (mTimerPool != null) { 2444 // Accumulate time to all active counters, scaled by the total 2445 // active in the pool, before taking this one out of the pool. 2446 refreshTimersLocked(batteryRealtime, mTimerPool, null); 2447 // Remove this timer from the active pool 2448 mTimerPool.remove(this); 2449 } else { 2450 mNesting = 1; 2451 mTotalTime = computeRunTimeLocked(batteryRealtime); 2452 mNesting = 0; 2453 } 2454 2455 if (DEBUG && mType < 0) { 2456 Log.v(TAG, "stop #" + mType + ": mUpdateTime=" + mUpdateTime 2457 + " mTotalTime=" + mTotalTime + " mCount=" + mCount 2458 + " mAcquireTime=" + mAcquireTime); 2459 } 2460 2461 if (mAcquireTime >= 0 && mTotalTime == mAcquireTime) { 2462 // If there was no change in the time, then discard this 2463 // count. A somewhat cheezy strategy, but hey. 2464 mCount--; 2465 } 2466 } 2467 } 2468 stopAllRunningLocked(long elapsedRealtimeMs)2469 public void stopAllRunningLocked(long elapsedRealtimeMs) { 2470 if (mNesting > 0) { 2471 mNesting = 1; 2472 stopRunningLocked(elapsedRealtimeMs); 2473 } 2474 } 2475 2476 // Update the total time for all other running Timers with the same type as this Timer 2477 // due to a change in timer count refreshTimersLocked(long batteryRealtime, final ArrayList<StopwatchTimer> pool, StopwatchTimer self)2478 private static long refreshTimersLocked(long batteryRealtime, 2479 final ArrayList<StopwatchTimer> pool, StopwatchTimer self) { 2480 long selfTime = 0; 2481 final int N = pool.size(); 2482 for (int i=N-1; i>= 0; i--) { 2483 final StopwatchTimer t = pool.get(i); 2484 long heldTime = batteryRealtime - t.mUpdateTime; 2485 if (heldTime > 0) { 2486 final long myTime = heldTime / N; 2487 if (t == self) { 2488 selfTime = myTime; 2489 } 2490 t.mTotalTime += myTime; 2491 } 2492 t.mUpdateTime = batteryRealtime; 2493 } 2494 return selfTime; 2495 } 2496 2497 @Override computeRunTimeLocked(long curBatteryRealtime)2498 protected long computeRunTimeLocked(long curBatteryRealtime) { 2499 if (mTimeout > 0 && curBatteryRealtime > mUpdateTime + mTimeout) { 2500 curBatteryRealtime = mUpdateTime + mTimeout; 2501 } 2502 return mTotalTime + (mNesting > 0 2503 ? (curBatteryRealtime - mUpdateTime) 2504 / (mTimerPool != null ? mTimerPool.size() : 1) 2505 : 0); 2506 } 2507 2508 @Override computeCurrentCountLocked()2509 protected int computeCurrentCountLocked() { 2510 return mCount; 2511 } 2512 2513 @Override reset(boolean detachIfReset)2514 public boolean reset(boolean detachIfReset) { 2515 boolean canDetach = mNesting <= 0; 2516 super.reset(canDetach && detachIfReset); 2517 if (mNesting > 0) { 2518 mUpdateTime = mTimeBase.getRealtime(mClocks.elapsedRealtime() * 1000); 2519 } 2520 mAcquireTime = -1; // to ensure mCount isn't decreased to -1 if timer is stopped later. 2521 return canDetach; 2522 } 2523 2524 @Override 2525 @UnsupportedAppUsage detach()2526 public void detach() { 2527 super.detach(); 2528 if (mTimerPool != null) { 2529 mTimerPool.remove(this); 2530 } 2531 } 2532 2533 @Override readSummaryFromParcelLocked(Parcel in)2534 public void readSummaryFromParcelLocked(Parcel in) { 2535 super.readSummaryFromParcelLocked(in); 2536 mNesting = 0; 2537 } 2538 2539 /** 2540 * Set the mark so that we can query later for the total time the timer has 2541 * accumulated since this point. The timer can be running or not. 2542 * 2543 * @param elapsedRealtimeMs the current elapsed realtime in milliseconds. 2544 */ setMark(long elapsedRealtimeMs)2545 public void setMark(long elapsedRealtimeMs) { 2546 final long batteryRealtime = mTimeBase.getRealtime(elapsedRealtimeMs * 1000); 2547 if (mNesting > 0) { 2548 // We are running. 2549 if (mTimerPool != null) { 2550 refreshTimersLocked(batteryRealtime, mTimerPool, this); 2551 } else { 2552 mTotalTime += batteryRealtime - mUpdateTime; 2553 mUpdateTime = batteryRealtime; 2554 } 2555 } 2556 mTimeBeforeMark = mTotalTime; 2557 } 2558 } 2559 2560 /** 2561 * State for keeping track of two DurationTimers with different TimeBases, presumably where one 2562 * TimeBase is effectively a subset of the other. 2563 */ 2564 public static class DualTimer extends DurationTimer { 2565 // This class both is a DurationTimer and also holds a second DurationTimer. 2566 // The main timer (this) typically tracks the total time. It may be pooled (but since it's a 2567 // durationTimer, it also has the unpooled getTotalDurationMsLocked() for 2568 // STATS_SINCE_CHARGED). 2569 // mSubTimer typically tracks only part of the total time, such as background time, as 2570 // determined by a subTimeBase. It is NOT pooled. 2571 private final DurationTimer mSubTimer; 2572 2573 /** 2574 * Creates a DualTimer to hold a main timer (this) and a mSubTimer. 2575 * The main timer (this) is based on the given timeBase and timerPool. 2576 * The mSubTimer is based on the given subTimeBase. The mSubTimer is not pooled, even if 2577 * the main timer is. 2578 */ DualTimer(Clocks clocks, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, TimeBase timeBase, TimeBase subTimeBase, Parcel in)2579 public DualTimer(Clocks clocks, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, 2580 TimeBase timeBase, TimeBase subTimeBase, Parcel in) { 2581 super(clocks, uid, type, timerPool, timeBase, in); 2582 mSubTimer = new DurationTimer(clocks, uid, type, null, subTimeBase, in); 2583 } 2584 2585 /** 2586 * Creates a DualTimer to hold a main timer (this) and a mSubTimer. 2587 * The main timer (this) is based on the given timeBase and timerPool. 2588 * The mSubTimer is based on the given subTimeBase. The mSubTimer is not pooled, even if 2589 * the main timer is. 2590 */ DualTimer(Clocks clocks, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, TimeBase timeBase, TimeBase subTimeBase)2591 public DualTimer(Clocks clocks, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, 2592 TimeBase timeBase, TimeBase subTimeBase) { 2593 super(clocks, uid, type, timerPool, timeBase); 2594 mSubTimer = new DurationTimer(clocks, uid, type, null, subTimeBase); 2595 } 2596 2597 /** Get the secondary timer. */ 2598 @Override getSubTimer()2599 public DurationTimer getSubTimer() { 2600 return mSubTimer; 2601 } 2602 2603 @Override startRunningLocked(long elapsedRealtimeMs)2604 public void startRunningLocked(long elapsedRealtimeMs) { 2605 super.startRunningLocked(elapsedRealtimeMs); 2606 mSubTimer.startRunningLocked(elapsedRealtimeMs); 2607 } 2608 2609 @Override stopRunningLocked(long elapsedRealtimeMs)2610 public void stopRunningLocked(long elapsedRealtimeMs) { 2611 super.stopRunningLocked(elapsedRealtimeMs); 2612 mSubTimer.stopRunningLocked(elapsedRealtimeMs); 2613 } 2614 2615 @Override stopAllRunningLocked(long elapsedRealtimeMs)2616 public void stopAllRunningLocked(long elapsedRealtimeMs) { 2617 super.stopAllRunningLocked(elapsedRealtimeMs); 2618 mSubTimer.stopAllRunningLocked(elapsedRealtimeMs); 2619 } 2620 2621 @Override reset(boolean detachIfReset)2622 public boolean reset(boolean detachIfReset) { 2623 boolean active = false; 2624 // Do not detach the subTimer explicitly since that'll be done by DualTimer.detach(). 2625 active |= !mSubTimer.reset(false); 2626 active |= !super.reset(detachIfReset); 2627 return !active; 2628 } 2629 2630 @Override detach()2631 public void detach() { 2632 mSubTimer.detach(); 2633 super.detach(); 2634 } 2635 2636 @Override writeToParcel(Parcel out, long elapsedRealtimeUs)2637 public void writeToParcel(Parcel out, long elapsedRealtimeUs) { 2638 super.writeToParcel(out, elapsedRealtimeUs); 2639 mSubTimer.writeToParcel(out, elapsedRealtimeUs); 2640 } 2641 2642 @Override writeSummaryFromParcelLocked(Parcel out, long elapsedRealtimeUs)2643 public void writeSummaryFromParcelLocked(Parcel out, long elapsedRealtimeUs) { 2644 super.writeSummaryFromParcelLocked(out, elapsedRealtimeUs); 2645 mSubTimer.writeSummaryFromParcelLocked(out, elapsedRealtimeUs); 2646 } 2647 2648 @Override readSummaryFromParcelLocked(Parcel in)2649 public void readSummaryFromParcelLocked(Parcel in) { 2650 super.readSummaryFromParcelLocked(in); 2651 mSubTimer.readSummaryFromParcelLocked(in); 2652 } 2653 } 2654 2655 2656 public abstract class OverflowArrayMap<T> { 2657 private static final String OVERFLOW_NAME = "*overflow*"; 2658 2659 final int mUid; 2660 final ArrayMap<String, T> mMap = new ArrayMap<>(); 2661 T mCurOverflow; 2662 ArrayMap<String, MutableInt> mActiveOverflow; 2663 long mLastOverflowTime; 2664 long mLastOverflowFinishTime; 2665 long mLastClearTime; 2666 long mLastCleanupTime; 2667 OverflowArrayMap(int uid)2668 public OverflowArrayMap(int uid) { 2669 mUid = uid; 2670 } 2671 getMap()2672 public ArrayMap<String, T> getMap() { 2673 return mMap; 2674 } 2675 clear()2676 public void clear() { 2677 mLastClearTime = SystemClock.elapsedRealtime(); 2678 mMap.clear(); 2679 mCurOverflow = null; 2680 mActiveOverflow = null; 2681 } 2682 add(String name, T obj)2683 public void add(String name, T obj) { 2684 if (name == null) { 2685 name = ""; 2686 } 2687 mMap.put(name, obj); 2688 if (OVERFLOW_NAME.equals(name)) { 2689 mCurOverflow = obj; 2690 } 2691 } 2692 cleanup()2693 public void cleanup() { 2694 mLastCleanupTime = SystemClock.elapsedRealtime(); 2695 if (mActiveOverflow != null) { 2696 if (mActiveOverflow.size() == 0) { 2697 mActiveOverflow = null; 2698 } 2699 } 2700 if (mActiveOverflow == null) { 2701 // There is no currently active overflow, so we should no longer have 2702 // an overflow entry. 2703 if (mMap.containsKey(OVERFLOW_NAME)) { 2704 Slog.wtf(TAG, "Cleaning up with no active overflow, but have overflow entry " 2705 + mMap.get(OVERFLOW_NAME)); 2706 mMap.remove(OVERFLOW_NAME); 2707 } 2708 mCurOverflow = null; 2709 } else { 2710 // There is currently active overflow, so we should still have an overflow entry. 2711 if (mCurOverflow == null || !mMap.containsKey(OVERFLOW_NAME)) { 2712 Slog.wtf(TAG, "Cleaning up with active overflow, but no overflow entry: cur=" 2713 + mCurOverflow + " map=" + mMap.get(OVERFLOW_NAME)); 2714 } 2715 } 2716 } 2717 startObject(String name)2718 public T startObject(String name) { 2719 if (name == null) { 2720 name = ""; 2721 } 2722 T obj = mMap.get(name); 2723 if (obj != null) { 2724 return obj; 2725 } 2726 2727 // No object exists for the given name, but do we currently have it 2728 // running as part of the overflow? 2729 if (mActiveOverflow != null) { 2730 MutableInt over = mActiveOverflow.get(name); 2731 if (over != null) { 2732 // We are already actively counting this name in the overflow object. 2733 obj = mCurOverflow; 2734 if (obj == null) { 2735 // Shouldn't be here, but we'll try to recover. 2736 Slog.wtf(TAG, "Have active overflow " + name + " but null overflow"); 2737 obj = mCurOverflow = instantiateObject(); 2738 mMap.put(OVERFLOW_NAME, obj); 2739 } 2740 over.value++; 2741 return obj; 2742 } 2743 } 2744 2745 // No object exists for given name nor in the overflow; we need to make 2746 // a new one. 2747 final int N = mMap.size(); 2748 if (N >= MAX_WAKELOCKS_PER_UID) { 2749 // Went over the limit on number of objects to track; this one goes 2750 // in to the overflow. 2751 obj = mCurOverflow; 2752 if (obj == null) { 2753 // Need to start overflow now... 2754 obj = mCurOverflow = instantiateObject(); 2755 mMap.put(OVERFLOW_NAME, obj); 2756 } 2757 if (mActiveOverflow == null) { 2758 mActiveOverflow = new ArrayMap<>(); 2759 } 2760 mActiveOverflow.put(name, new MutableInt(1)); 2761 mLastOverflowTime = SystemClock.elapsedRealtime(); 2762 return obj; 2763 } 2764 2765 // Normal case where we just need to make a new object. 2766 obj = instantiateObject(); 2767 mMap.put(name, obj); 2768 return obj; 2769 } 2770 stopObject(String name)2771 public T stopObject(String name) { 2772 if (name == null) { 2773 name = ""; 2774 } 2775 T obj = mMap.get(name); 2776 if (obj != null) { 2777 return obj; 2778 } 2779 2780 // No object exists for the given name, but do we currently have it 2781 // running as part of the overflow? 2782 if (mActiveOverflow != null) { 2783 MutableInt over = mActiveOverflow.get(name); 2784 if (over != null) { 2785 // We are already actively counting this name in the overflow object. 2786 obj = mCurOverflow; 2787 if (obj != null) { 2788 over.value--; 2789 if (over.value <= 0) { 2790 mActiveOverflow.remove(name); 2791 mLastOverflowFinishTime = SystemClock.elapsedRealtime(); 2792 } 2793 return obj; 2794 } 2795 } 2796 } 2797 2798 // Huh, they are stopping an active operation but we can't find one! 2799 // That's not good. 2800 StringBuilder sb = new StringBuilder(); 2801 sb.append("Unable to find object for "); 2802 sb.append(name); 2803 sb.append(" in uid "); 2804 sb.append(mUid); 2805 sb.append(" mapsize="); 2806 sb.append(mMap.size()); 2807 sb.append(" activeoverflow="); 2808 sb.append(mActiveOverflow); 2809 sb.append(" curoverflow="); 2810 sb.append(mCurOverflow); 2811 long now = SystemClock.elapsedRealtime(); 2812 if (mLastOverflowTime != 0) { 2813 sb.append(" lastOverflowTime="); 2814 TimeUtils.formatDuration(mLastOverflowTime-now, sb); 2815 } 2816 if (mLastOverflowFinishTime != 0) { 2817 sb.append(" lastOverflowFinishTime="); 2818 TimeUtils.formatDuration(mLastOverflowFinishTime-now, sb); 2819 } 2820 if (mLastClearTime != 0) { 2821 sb.append(" lastClearTime="); 2822 TimeUtils.formatDuration(mLastClearTime-now, sb); 2823 } 2824 if (mLastCleanupTime != 0) { 2825 sb.append(" lastCleanupTime="); 2826 TimeUtils.formatDuration(mLastCleanupTime-now, sb); 2827 } 2828 Slog.wtf(TAG, sb.toString()); 2829 return null; 2830 } 2831 instantiateObject()2832 public abstract T instantiateObject(); 2833 } 2834 2835 public static class ControllerActivityCounterImpl extends ControllerActivityCounter 2836 implements Parcelable { 2837 private final LongSamplingCounter mIdleTimeMillis; 2838 private final LongSamplingCounter mScanTimeMillis; 2839 private final LongSamplingCounter mSleepTimeMillis; 2840 private final LongSamplingCounter mRxTimeMillis; 2841 private final LongSamplingCounter[] mTxTimeMillis; 2842 private final LongSamplingCounter mPowerDrainMaMs; 2843 private final LongSamplingCounter mMonitoredRailChargeConsumedMaMs; 2844 ControllerActivityCounterImpl(TimeBase timeBase, int numTxStates)2845 public ControllerActivityCounterImpl(TimeBase timeBase, int numTxStates) { 2846 mIdleTimeMillis = new LongSamplingCounter(timeBase); 2847 mScanTimeMillis = new LongSamplingCounter(timeBase); 2848 mSleepTimeMillis = new LongSamplingCounter(timeBase); 2849 mRxTimeMillis = new LongSamplingCounter(timeBase); 2850 mTxTimeMillis = new LongSamplingCounter[numTxStates]; 2851 for (int i = 0; i < numTxStates; i++) { 2852 mTxTimeMillis[i] = new LongSamplingCounter(timeBase); 2853 } 2854 mPowerDrainMaMs = new LongSamplingCounter(timeBase); 2855 mMonitoredRailChargeConsumedMaMs = new LongSamplingCounter(timeBase); 2856 } 2857 ControllerActivityCounterImpl(TimeBase timeBase, int numTxStates, Parcel in)2858 public ControllerActivityCounterImpl(TimeBase timeBase, int numTxStates, Parcel in) { 2859 mIdleTimeMillis = new LongSamplingCounter(timeBase, in); 2860 mScanTimeMillis = new LongSamplingCounter(timeBase, in); 2861 mSleepTimeMillis = new LongSamplingCounter(timeBase, in); 2862 mRxTimeMillis = new LongSamplingCounter(timeBase, in); 2863 final int recordedTxStates = in.readInt(); 2864 if (recordedTxStates != numTxStates) { 2865 throw new ParcelFormatException("inconsistent tx state lengths"); 2866 } 2867 2868 mTxTimeMillis = new LongSamplingCounter[numTxStates]; 2869 for (int i = 0; i < numTxStates; i++) { 2870 mTxTimeMillis[i] = new LongSamplingCounter(timeBase, in); 2871 } 2872 mPowerDrainMaMs = new LongSamplingCounter(timeBase, in); 2873 mMonitoredRailChargeConsumedMaMs = new LongSamplingCounter(timeBase, in); 2874 } 2875 readSummaryFromParcel(Parcel in)2876 public void readSummaryFromParcel(Parcel in) { 2877 mIdleTimeMillis.readSummaryFromParcelLocked(in); 2878 mScanTimeMillis.readSummaryFromParcelLocked(in); 2879 mSleepTimeMillis.readSummaryFromParcelLocked(in); 2880 mRxTimeMillis.readSummaryFromParcelLocked(in); 2881 final int recordedTxStates = in.readInt(); 2882 if (recordedTxStates != mTxTimeMillis.length) { 2883 throw new ParcelFormatException("inconsistent tx state lengths"); 2884 } 2885 for (LongSamplingCounter counter : mTxTimeMillis) { 2886 counter.readSummaryFromParcelLocked(in); 2887 } 2888 mPowerDrainMaMs.readSummaryFromParcelLocked(in); 2889 mMonitoredRailChargeConsumedMaMs.readSummaryFromParcelLocked(in); 2890 } 2891 2892 @Override describeContents()2893 public int describeContents() { 2894 return 0; 2895 } 2896 writeSummaryToParcel(Parcel dest)2897 public void writeSummaryToParcel(Parcel dest) { 2898 mIdleTimeMillis.writeSummaryFromParcelLocked(dest); 2899 mScanTimeMillis.writeSummaryFromParcelLocked(dest); 2900 mSleepTimeMillis.writeSummaryFromParcelLocked(dest); 2901 mRxTimeMillis.writeSummaryFromParcelLocked(dest); 2902 dest.writeInt(mTxTimeMillis.length); 2903 for (LongSamplingCounter counter : mTxTimeMillis) { 2904 counter.writeSummaryFromParcelLocked(dest); 2905 } 2906 mPowerDrainMaMs.writeSummaryFromParcelLocked(dest); 2907 mMonitoredRailChargeConsumedMaMs.writeSummaryFromParcelLocked(dest); 2908 } 2909 2910 @Override writeToParcel(Parcel dest, int flags)2911 public void writeToParcel(Parcel dest, int flags) { 2912 mIdleTimeMillis.writeToParcel(dest); 2913 mScanTimeMillis.writeToParcel(dest); 2914 mSleepTimeMillis.writeToParcel(dest); 2915 mRxTimeMillis.writeToParcel(dest); 2916 dest.writeInt(mTxTimeMillis.length); 2917 for (LongSamplingCounter counter : mTxTimeMillis) { 2918 counter.writeToParcel(dest); 2919 } 2920 mPowerDrainMaMs.writeToParcel(dest); 2921 mMonitoredRailChargeConsumedMaMs.writeToParcel(dest); 2922 } 2923 reset(boolean detachIfReset)2924 public void reset(boolean detachIfReset) { 2925 mIdleTimeMillis.reset(detachIfReset); 2926 mScanTimeMillis.reset(detachIfReset); 2927 mSleepTimeMillis.reset(detachIfReset); 2928 mRxTimeMillis.reset(detachIfReset); 2929 for (LongSamplingCounter counter : mTxTimeMillis) { 2930 counter.reset(detachIfReset); 2931 } 2932 mPowerDrainMaMs.reset(detachIfReset); 2933 mMonitoredRailChargeConsumedMaMs.reset(detachIfReset); 2934 } 2935 detach()2936 public void detach() { 2937 mIdleTimeMillis.detach(); 2938 mScanTimeMillis.detach(); 2939 mSleepTimeMillis.detach(); 2940 mRxTimeMillis.detach(); 2941 for (LongSamplingCounter counter : mTxTimeMillis) { 2942 counter.detach(); 2943 } 2944 mPowerDrainMaMs.detach(); 2945 mMonitoredRailChargeConsumedMaMs.detach(); 2946 } 2947 2948 /** 2949 * @return a LongSamplingCounter, measuring time spent in the idle state in 2950 * milliseconds. 2951 */ 2952 @Override getIdleTimeCounter()2953 public LongSamplingCounter getIdleTimeCounter() { 2954 return mIdleTimeMillis; 2955 } 2956 2957 /** 2958 * @return a LongSamplingCounter, measuring time spent in the scan state in 2959 * milliseconds. 2960 */ 2961 @Override getScanTimeCounter()2962 public LongSamplingCounter getScanTimeCounter() { 2963 return mScanTimeMillis; 2964 } 2965 2966 /** 2967 * @return a LongSamplingCounter, measuring time spent in the sleep state in 2968 * milliseconds. 2969 */ 2970 @Override getSleepTimeCounter()2971 public LongSamplingCounter getSleepTimeCounter() { 2972 return mSleepTimeMillis; 2973 } 2974 2975 /** 2976 * @return a LongSamplingCounter, measuring time spent in the receive state in 2977 * milliseconds. 2978 */ 2979 @Override getRxTimeCounter()2980 public LongSamplingCounter getRxTimeCounter() { 2981 return mRxTimeMillis; 2982 } 2983 2984 /** 2985 * @return a LongSamplingCounter[], measuring time spent in various transmit states in 2986 * milliseconds. 2987 */ 2988 @Override getTxTimeCounters()2989 public LongSamplingCounter[] getTxTimeCounters() { 2990 return mTxTimeMillis; 2991 } 2992 2993 /** 2994 * @return a LongSamplingCounter, measuring power use in milli-ampere milliseconds (mAmS). 2995 */ 2996 @Override getPowerCounter()2997 public LongSamplingCounter getPowerCounter() { 2998 return mPowerDrainMaMs; 2999 } 3000 3001 /** 3002 * @return a LongSamplingCounter, measuring actual monitored rail energy consumed 3003 * milli-ampere milli-seconds (mAmS). 3004 */ 3005 @Override getMonitoredRailChargeConsumedMaMs()3006 public LongSamplingCounter getMonitoredRailChargeConsumedMaMs() { 3007 return mMonitoredRailChargeConsumedMaMs; 3008 } 3009 } 3010 3011 /** Get Resource Power Manager stats. Create a new one if it doesn't already exist. */ getRpmTimerLocked(String name)3012 public SamplingTimer getRpmTimerLocked(String name) { 3013 SamplingTimer rpmt = mRpmStats.get(name); 3014 if (rpmt == null) { 3015 rpmt = new SamplingTimer(mClocks, mOnBatteryTimeBase); 3016 mRpmStats.put(name, rpmt); 3017 } 3018 return rpmt; 3019 } 3020 3021 /** Get Screen-off Resource Power Manager stats. Create new one if it doesn't already exist. */ getScreenOffRpmTimerLocked(String name)3022 public SamplingTimer getScreenOffRpmTimerLocked(String name) { 3023 SamplingTimer rpmt = mScreenOffRpmStats.get(name); 3024 if (rpmt == null) { 3025 rpmt = new SamplingTimer(mClocks, mOnBatteryScreenOffTimeBase); 3026 mScreenOffRpmStats.put(name, rpmt); 3027 } 3028 return rpmt; 3029 } 3030 3031 /* 3032 * Get the wakeup reason counter, and create a new one if one 3033 * doesn't already exist. 3034 */ getWakeupReasonTimerLocked(String name)3035 public SamplingTimer getWakeupReasonTimerLocked(String name) { 3036 SamplingTimer timer = mWakeupReasonStats.get(name); 3037 if (timer == null) { 3038 timer = new SamplingTimer(mClocks, mOnBatteryTimeBase); 3039 mWakeupReasonStats.put(name, timer); 3040 } 3041 return timer; 3042 } 3043 3044 /* 3045 * Get the KernelWakelockTimer associated with name, and create a new one if one 3046 * doesn't already exist. 3047 */ getKernelWakelockTimerLocked(String name)3048 public SamplingTimer getKernelWakelockTimerLocked(String name) { 3049 SamplingTimer kwlt = mKernelWakelockStats.get(name); 3050 if (kwlt == null) { 3051 kwlt = new SamplingTimer(mClocks, mOnBatteryScreenOffTimeBase); 3052 mKernelWakelockStats.put(name, kwlt); 3053 } 3054 return kwlt; 3055 } 3056 getKernelMemoryTimerLocked(long bucket)3057 public SamplingTimer getKernelMemoryTimerLocked(long bucket) { 3058 SamplingTimer kmt = mKernelMemoryStats.get(bucket); 3059 if (kmt == null) { 3060 kmt = new SamplingTimer(mClocks, mOnBatteryTimeBase); 3061 mKernelMemoryStats.put(bucket, kmt); 3062 } 3063 return kmt; 3064 } 3065 writeHistoryTag(HistoryTag tag)3066 private int writeHistoryTag(HistoryTag tag) { 3067 Integer idxObj = mHistoryTagPool.get(tag); 3068 int idx; 3069 if (idxObj != null) { 3070 idx = idxObj; 3071 } else { 3072 idx = mNextHistoryTagIdx; 3073 HistoryTag key = new HistoryTag(); 3074 key.setTo(tag); 3075 tag.poolIdx = idx; 3076 mHistoryTagPool.put(key, idx); 3077 mNextHistoryTagIdx++; 3078 mNumHistoryTagChars += key.string.length() + 1; 3079 } 3080 return idx; 3081 } 3082 readHistoryTag(int index, HistoryTag tag)3083 private void readHistoryTag(int index, HistoryTag tag) { 3084 if (index < mReadHistoryStrings.length) { 3085 tag.string = mReadHistoryStrings[index]; 3086 tag.uid = mReadHistoryUids[index]; 3087 } else { 3088 tag.string = null; 3089 tag.uid = 0; 3090 } 3091 tag.poolIdx = index; 3092 } 3093 3094 /* 3095 The history delta format uses flags to denote further data in subsequent ints in the parcel. 3096 3097 There is always the first token, which may contain the delta time, or an indicator of 3098 the length of the time (int or long) following this token. 3099 3100 First token: always present, 3101 31 23 15 7 0 3102 █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█ 3103 3104 T: the delta time if it is <= 0x7fffd. Otherwise 0x7fffe indicates an int immediately 3105 follows containing the time, and 0x7ffff indicates a long immediately follows with the 3106 delta time. 3107 A: battery level changed and an int follows with battery data. 3108 B: state changed and an int follows with state change data. 3109 C: state2 has changed and an int follows with state2 change data. 3110 D: wakelock/wakereason has changed and an wakelock/wakereason struct follows. 3111 E: event data has changed and an event struct follows. 3112 F: battery charge in coulombs has changed and an int with the charge follows. 3113 G: state flag denoting that the mobile radio was active. 3114 H: state flag denoting that the wifi radio was active. 3115 I: state flag denoting that a wifi scan occurred. 3116 J: state flag denoting that a wifi full lock was held. 3117 K: state flag denoting that the gps was on. 3118 L: state flag denoting that a wakelock was held. 3119 M: state flag denoting that the cpu was running. 3120 3121 Time int/long: if T in the first token is 0x7ffff or 0x7fffe, then an int or long follows 3122 with the time delta. 3123 3124 Battery level int: if A in the first token is set, 3125 31 23 15 7 0 3126 █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█ 3127 3128 D: indicates that extra history details follow. 3129 V: the battery voltage. 3130 T: the battery temperature. 3131 L: the battery level (out of 100). 3132 3133 State change int: if B in the first token is set, 3134 31 23 15 7 0 3135 █S|S|S|H|H|H|P|P█F|E|D|C|B| | |A█ | | | | | | | █ | | | | | | | █ 3136 3137 A: wifi multicast was on. 3138 B: battery was plugged in. 3139 C: screen was on. 3140 D: phone was scanning for signal. 3141 E: audio was on. 3142 F: a sensor was active. 3143 3144 State2 change int: if C in the first token is set, 3145 31 23 15 7 0 3146 █M|L|K|J|I|H|H|G█F|E|D|C| | | | █ | | | | | | | █ |B|B|B|A|A|A|A█ 3147 3148 A: 4 bits indicating the wifi supplicant state: {@link BatteryStats#WIFI_SUPPL_STATE_NAMES}. 3149 B: 3 bits indicating the wifi signal strength: 0, 1, 2, 3, 4. 3150 C: a bluetooth scan was active. 3151 D: the camera was active. 3152 E: bluetooth was on. 3153 F: a phone call was active. 3154 G: the device was charging. 3155 H: 2 bits indicating the device-idle (doze) state: off, light, full 3156 I: the flashlight was on. 3157 J: wifi was on. 3158 K: wifi was running. 3159 L: video was playing. 3160 M: power save mode was on. 3161 3162 Wakelock/wakereason struct: if D in the first token is set, 3163 TODO(adamlesinski): describe wakelock/wakereason struct. 3164 3165 Event struct: if E in the first token is set, 3166 TODO(adamlesinski): describe the event struct. 3167 3168 History step details struct: if D in the battery level int is set, 3169 TODO(adamlesinski): describe the history step details struct. 3170 3171 Battery charge int: if F in the first token is set, an int representing the battery charge 3172 in coulombs follows. 3173 */ 3174 3175 // Part of initial delta int that specifies the time delta. 3176 static final int DELTA_TIME_MASK = 0x7ffff; 3177 static final int DELTA_TIME_LONG = 0x7ffff; // The delta is a following long 3178 static final int DELTA_TIME_INT = 0x7fffe; // The delta is a following int 3179 static final int DELTA_TIME_ABS = 0x7fffd; // Following is an entire abs update. 3180 // Flag in delta int: a new battery level int follows. 3181 static final int DELTA_BATTERY_LEVEL_FLAG = 0x00080000; 3182 // Flag in delta int: a new full state and battery status int follows. 3183 static final int DELTA_STATE_FLAG = 0x00100000; 3184 // Flag in delta int: a new full state2 int follows. 3185 static final int DELTA_STATE2_FLAG = 0x00200000; 3186 // Flag in delta int: contains a wakelock or wakeReason tag. 3187 static final int DELTA_WAKELOCK_FLAG = 0x00400000; 3188 // Flag in delta int: contains an event description. 3189 static final int DELTA_EVENT_FLAG = 0x00800000; 3190 // Flag in delta int: contains the battery charge count in uAh. 3191 static final int DELTA_BATTERY_CHARGE_FLAG = 0x01000000; 3192 // These upper bits are the frequently changing state bits. 3193 static final int DELTA_STATE_MASK = 0xfe000000; 3194 3195 // These are the pieces of battery state that are packed in to the upper bits of 3196 // the state int that have been packed in to the first delta int. They must fit 3197 // in STATE_BATTERY_MASK. 3198 static final int STATE_BATTERY_MASK = 0xff000000; 3199 static final int STATE_BATTERY_STATUS_MASK = 0x00000007; 3200 static final int STATE_BATTERY_STATUS_SHIFT = 29; 3201 static final int STATE_BATTERY_HEALTH_MASK = 0x00000007; 3202 static final int STATE_BATTERY_HEALTH_SHIFT = 26; 3203 static final int STATE_BATTERY_PLUG_MASK = 0x00000003; 3204 static final int STATE_BATTERY_PLUG_SHIFT = 24; 3205 3206 // We use the low bit of the battery state int to indicate that we have full details 3207 // from a battery level change. 3208 static final int BATTERY_DELTA_LEVEL_FLAG = 0x00000001; 3209 writeHistoryDelta(Parcel dest, HistoryItem cur, HistoryItem last)3210 public void writeHistoryDelta(Parcel dest, HistoryItem cur, HistoryItem last) { 3211 if (last == null || cur.cmd != HistoryItem.CMD_UPDATE) { 3212 dest.writeInt(DELTA_TIME_ABS); 3213 cur.writeToParcel(dest, 0); 3214 return; 3215 } 3216 3217 final long deltaTime = cur.time - last.time; 3218 final int lastBatteryLevelInt = buildBatteryLevelInt(last); 3219 final int lastStateInt = buildStateInt(last); 3220 3221 int deltaTimeToken; 3222 if (deltaTime < 0 || deltaTime > Integer.MAX_VALUE) { 3223 deltaTimeToken = DELTA_TIME_LONG; 3224 } else if (deltaTime >= DELTA_TIME_ABS) { 3225 deltaTimeToken = DELTA_TIME_INT; 3226 } else { 3227 deltaTimeToken = (int)deltaTime; 3228 } 3229 int firstToken = deltaTimeToken | (cur.states&DELTA_STATE_MASK); 3230 final int includeStepDetails = mLastHistoryStepLevel > cur.batteryLevel 3231 ? BATTERY_DELTA_LEVEL_FLAG : 0; 3232 final boolean computeStepDetails = includeStepDetails != 0 3233 || mLastHistoryStepDetails == null; 3234 final int batteryLevelInt = buildBatteryLevelInt(cur) | includeStepDetails; 3235 final boolean batteryLevelIntChanged = batteryLevelInt != lastBatteryLevelInt; 3236 if (batteryLevelIntChanged) { 3237 firstToken |= DELTA_BATTERY_LEVEL_FLAG; 3238 } 3239 final int stateInt = buildStateInt(cur); 3240 final boolean stateIntChanged = stateInt != lastStateInt; 3241 if (stateIntChanged) { 3242 firstToken |= DELTA_STATE_FLAG; 3243 } 3244 final boolean state2IntChanged = cur.states2 != last.states2; 3245 if (state2IntChanged) { 3246 firstToken |= DELTA_STATE2_FLAG; 3247 } 3248 if (cur.wakelockTag != null || cur.wakeReasonTag != null) { 3249 firstToken |= DELTA_WAKELOCK_FLAG; 3250 } 3251 if (cur.eventCode != HistoryItem.EVENT_NONE) { 3252 firstToken |= DELTA_EVENT_FLAG; 3253 } 3254 3255 final boolean batteryChargeChanged = cur.batteryChargeUAh != last.batteryChargeUAh; 3256 if (batteryChargeChanged) { 3257 firstToken |= DELTA_BATTERY_CHARGE_FLAG; 3258 } 3259 dest.writeInt(firstToken); 3260 if (DEBUG) Slog.i(TAG, "WRITE DELTA: firstToken=0x" + Integer.toHexString(firstToken) 3261 + " deltaTime=" + deltaTime); 3262 3263 if (deltaTimeToken >= DELTA_TIME_INT) { 3264 if (deltaTimeToken == DELTA_TIME_INT) { 3265 if (DEBUG) Slog.i(TAG, "WRITE DELTA: int deltaTime=" + (int)deltaTime); 3266 dest.writeInt((int)deltaTime); 3267 } else { 3268 if (DEBUG) Slog.i(TAG, "WRITE DELTA: long deltaTime=" + deltaTime); 3269 dest.writeLong(deltaTime); 3270 } 3271 } 3272 if (batteryLevelIntChanged) { 3273 dest.writeInt(batteryLevelInt); 3274 if (DEBUG) Slog.i(TAG, "WRITE DELTA: batteryToken=0x" 3275 + Integer.toHexString(batteryLevelInt) 3276 + " batteryLevel=" + cur.batteryLevel 3277 + " batteryTemp=" + cur.batteryTemperature 3278 + " batteryVolt=" + (int)cur.batteryVoltage); 3279 } 3280 if (stateIntChanged) { 3281 dest.writeInt(stateInt); 3282 if (DEBUG) Slog.i(TAG, "WRITE DELTA: stateToken=0x" 3283 + Integer.toHexString(stateInt) 3284 + " batteryStatus=" + cur.batteryStatus 3285 + " batteryHealth=" + cur.batteryHealth 3286 + " batteryPlugType=" + cur.batteryPlugType 3287 + " states=0x" + Integer.toHexString(cur.states)); 3288 } 3289 if (state2IntChanged) { 3290 dest.writeInt(cur.states2); 3291 if (DEBUG) Slog.i(TAG, "WRITE DELTA: states2=0x" 3292 + Integer.toHexString(cur.states2)); 3293 } 3294 if (cur.wakelockTag != null || cur.wakeReasonTag != null) { 3295 int wakeLockIndex; 3296 int wakeReasonIndex; 3297 if (cur.wakelockTag != null) { 3298 wakeLockIndex = writeHistoryTag(cur.wakelockTag); 3299 if (DEBUG) Slog.i(TAG, "WRITE DELTA: wakelockTag=#" + cur.wakelockTag.poolIdx 3300 + " " + cur.wakelockTag.uid + ":" + cur.wakelockTag.string); 3301 } else { 3302 wakeLockIndex = 0xffff; 3303 } 3304 if (cur.wakeReasonTag != null) { 3305 wakeReasonIndex = writeHistoryTag(cur.wakeReasonTag); 3306 if (DEBUG) Slog.i(TAG, "WRITE DELTA: wakeReasonTag=#" + cur.wakeReasonTag.poolIdx 3307 + " " + cur.wakeReasonTag.uid + ":" + cur.wakeReasonTag.string); 3308 } else { 3309 wakeReasonIndex = 0xffff; 3310 } 3311 dest.writeInt((wakeReasonIndex<<16) | wakeLockIndex); 3312 } 3313 if (cur.eventCode != HistoryItem.EVENT_NONE) { 3314 int index = writeHistoryTag(cur.eventTag); 3315 int codeAndIndex = (cur.eventCode&0xffff) | (index<<16); 3316 dest.writeInt(codeAndIndex); 3317 if (DEBUG) Slog.i(TAG, "WRITE DELTA: event=" + cur.eventCode + " tag=#" 3318 + cur.eventTag.poolIdx + " " + cur.eventTag.uid + ":" 3319 + cur.eventTag.string); 3320 } 3321 if (computeStepDetails) { 3322 if (mPlatformIdleStateCallback != null) { 3323 mCurHistoryStepDetails.statPlatformIdleState = 3324 mPlatformIdleStateCallback.getPlatformLowPowerStats(); 3325 if (DEBUG) Slog.i(TAG, "WRITE PlatformIdleState:" + 3326 mCurHistoryStepDetails.statPlatformIdleState); 3327 3328 mCurHistoryStepDetails.statSubsystemPowerState = 3329 mPlatformIdleStateCallback.getSubsystemLowPowerStats(); 3330 if (DEBUG) Slog.i(TAG, "WRITE SubsystemPowerState:" + 3331 mCurHistoryStepDetails.statSubsystemPowerState); 3332 3333 } 3334 computeHistoryStepDetails(mCurHistoryStepDetails, mLastHistoryStepDetails); 3335 if (includeStepDetails != 0) { 3336 mCurHistoryStepDetails.writeToParcel(dest); 3337 } 3338 cur.stepDetails = mCurHistoryStepDetails; 3339 mLastHistoryStepDetails = mCurHistoryStepDetails; 3340 } else { 3341 cur.stepDetails = null; 3342 } 3343 if (mLastHistoryStepLevel < cur.batteryLevel) { 3344 mLastHistoryStepDetails = null; 3345 } 3346 mLastHistoryStepLevel = cur.batteryLevel; 3347 3348 if (batteryChargeChanged) { 3349 if (DEBUG) Slog.i(TAG, "WRITE DELTA: batteryChargeUAh=" + cur.batteryChargeUAh); 3350 dest.writeInt(cur.batteryChargeUAh); 3351 } 3352 dest.writeDouble(cur.modemRailChargeMah); 3353 dest.writeDouble(cur.wifiRailChargeMah); 3354 } 3355 buildBatteryLevelInt(HistoryItem h)3356 private int buildBatteryLevelInt(HistoryItem h) { 3357 return ((((int)h.batteryLevel)<<25)&0xfe000000) 3358 | ((((int)h.batteryTemperature)<<15)&0x01ff8000) 3359 | ((((int)h.batteryVoltage)<<1)&0x00007ffe); 3360 } 3361 readBatteryLevelInt(int batteryLevelInt, HistoryItem out)3362 private void readBatteryLevelInt(int batteryLevelInt, HistoryItem out) { 3363 out.batteryLevel = (byte)((batteryLevelInt & 0xfe000000) >>> 25); 3364 out.batteryTemperature = (short)((batteryLevelInt & 0x01ff8000) >>> 15); 3365 out.batteryVoltage = (char)((batteryLevelInt & 0x00007ffe) >>> 1); 3366 } 3367 buildStateInt(HistoryItem h)3368 private int buildStateInt(HistoryItem h) { 3369 int plugType = 0; 3370 if ((h.batteryPlugType&BatteryManager.BATTERY_PLUGGED_AC) != 0) { 3371 plugType = 1; 3372 } else if ((h.batteryPlugType&BatteryManager.BATTERY_PLUGGED_USB) != 0) { 3373 plugType = 2; 3374 } else if ((h.batteryPlugType&BatteryManager.BATTERY_PLUGGED_WIRELESS) != 0) { 3375 plugType = 3; 3376 } 3377 return ((h.batteryStatus&STATE_BATTERY_STATUS_MASK)<<STATE_BATTERY_STATUS_SHIFT) 3378 | ((h.batteryHealth&STATE_BATTERY_HEALTH_MASK)<<STATE_BATTERY_HEALTH_SHIFT) 3379 | ((plugType&STATE_BATTERY_PLUG_MASK)<<STATE_BATTERY_PLUG_SHIFT) 3380 | (h.states&(~STATE_BATTERY_MASK)); 3381 } 3382 computeHistoryStepDetails(final HistoryStepDetails out, final HistoryStepDetails last)3383 private void computeHistoryStepDetails(final HistoryStepDetails out, 3384 final HistoryStepDetails last) { 3385 final HistoryStepDetails tmp = last != null ? mTmpHistoryStepDetails : out; 3386 3387 // Perform a CPU update right after we do this collection, so we have started 3388 // collecting good data for the next step. 3389 requestImmediateCpuUpdate(); 3390 3391 if (last == null) { 3392 // We are not generating a delta, so all we need to do is reset the stats 3393 // we will later be doing a delta from. 3394 final int NU = mUidStats.size(); 3395 for (int i=0; i<NU; i++) { 3396 final BatteryStatsImpl.Uid uid = mUidStats.valueAt(i); 3397 uid.mLastStepUserTime = uid.mCurStepUserTime; 3398 uid.mLastStepSystemTime = uid.mCurStepSystemTime; 3399 } 3400 mLastStepCpuUserTime = mCurStepCpuUserTime; 3401 mLastStepCpuSystemTime = mCurStepCpuSystemTime; 3402 mLastStepStatUserTime = mCurStepStatUserTime; 3403 mLastStepStatSystemTime = mCurStepStatSystemTime; 3404 mLastStepStatIOWaitTime = mCurStepStatIOWaitTime; 3405 mLastStepStatIrqTime = mCurStepStatIrqTime; 3406 mLastStepStatSoftIrqTime = mCurStepStatSoftIrqTime; 3407 mLastStepStatIdleTime = mCurStepStatIdleTime; 3408 tmp.clear(); 3409 return; 3410 } 3411 if (DEBUG) { 3412 Slog.d(TAG, "Step stats last: user=" + mLastStepCpuUserTime + " sys=" 3413 + mLastStepStatSystemTime + " io=" + mLastStepStatIOWaitTime 3414 + " irq=" + mLastStepStatIrqTime + " sirq=" 3415 + mLastStepStatSoftIrqTime + " idle=" + mLastStepStatIdleTime); 3416 Slog.d(TAG, "Step stats cur: user=" + mCurStepCpuUserTime + " sys=" 3417 + mCurStepStatSystemTime + " io=" + mCurStepStatIOWaitTime 3418 + " irq=" + mCurStepStatIrqTime + " sirq=" 3419 + mCurStepStatSoftIrqTime + " idle=" + mCurStepStatIdleTime); 3420 } 3421 out.userTime = (int)(mCurStepCpuUserTime - mLastStepCpuUserTime); 3422 out.systemTime = (int)(mCurStepCpuSystemTime - mLastStepCpuSystemTime); 3423 out.statUserTime = (int)(mCurStepStatUserTime - mLastStepStatUserTime); 3424 out.statSystemTime = (int)(mCurStepStatSystemTime - mLastStepStatSystemTime); 3425 out.statIOWaitTime = (int)(mCurStepStatIOWaitTime - mLastStepStatIOWaitTime); 3426 out.statIrqTime = (int)(mCurStepStatIrqTime - mLastStepStatIrqTime); 3427 out.statSoftIrqTime = (int)(mCurStepStatSoftIrqTime - mLastStepStatSoftIrqTime); 3428 out.statIdlTime = (int)(mCurStepStatIdleTime - mLastStepStatIdleTime); 3429 out.appCpuUid1 = out.appCpuUid2 = out.appCpuUid3 = -1; 3430 out.appCpuUTime1 = out.appCpuUTime2 = out.appCpuUTime3 = 0; 3431 out.appCpuSTime1 = out.appCpuSTime2 = out.appCpuSTime3 = 0; 3432 final int NU = mUidStats.size(); 3433 for (int i=0; i<NU; i++) { 3434 final BatteryStatsImpl.Uid uid = mUidStats.valueAt(i); 3435 final int totalUTime = (int)(uid.mCurStepUserTime - uid.mLastStepUserTime); 3436 final int totalSTime = (int)(uid.mCurStepSystemTime - uid.mLastStepSystemTime); 3437 final int totalTime = totalUTime + totalSTime; 3438 uid.mLastStepUserTime = uid.mCurStepUserTime; 3439 uid.mLastStepSystemTime = uid.mCurStepSystemTime; 3440 if (totalTime <= (out.appCpuUTime3+out.appCpuSTime3)) { 3441 continue; 3442 } 3443 if (totalTime <= (out.appCpuUTime2+out.appCpuSTime2)) { 3444 out.appCpuUid3 = uid.mUid; 3445 out.appCpuUTime3 = totalUTime; 3446 out.appCpuSTime3 = totalSTime; 3447 } else { 3448 out.appCpuUid3 = out.appCpuUid2; 3449 out.appCpuUTime3 = out.appCpuUTime2; 3450 out.appCpuSTime3 = out.appCpuSTime2; 3451 if (totalTime <= (out.appCpuUTime1+out.appCpuSTime1)) { 3452 out.appCpuUid2 = uid.mUid; 3453 out.appCpuUTime2 = totalUTime; 3454 out.appCpuSTime2 = totalSTime; 3455 } else { 3456 out.appCpuUid2 = out.appCpuUid1; 3457 out.appCpuUTime2 = out.appCpuUTime1; 3458 out.appCpuSTime2 = out.appCpuSTime1; 3459 out.appCpuUid1 = uid.mUid; 3460 out.appCpuUTime1 = totalUTime; 3461 out.appCpuSTime1 = totalSTime; 3462 } 3463 } 3464 } 3465 mLastStepCpuUserTime = mCurStepCpuUserTime; 3466 mLastStepCpuSystemTime = mCurStepCpuSystemTime; 3467 mLastStepStatUserTime = mCurStepStatUserTime; 3468 mLastStepStatSystemTime = mCurStepStatSystemTime; 3469 mLastStepStatIOWaitTime = mCurStepStatIOWaitTime; 3470 mLastStepStatIrqTime = mCurStepStatIrqTime; 3471 mLastStepStatSoftIrqTime = mCurStepStatSoftIrqTime; 3472 mLastStepStatIdleTime = mCurStepStatIdleTime; 3473 } 3474 readHistoryDelta(Parcel src, HistoryItem cur)3475 public void readHistoryDelta(Parcel src, HistoryItem cur) { 3476 int firstToken = src.readInt(); 3477 int deltaTimeToken = firstToken&DELTA_TIME_MASK; 3478 cur.cmd = HistoryItem.CMD_UPDATE; 3479 cur.numReadInts = 1; 3480 if (DEBUG) Slog.i(TAG, "READ DELTA: firstToken=0x" + Integer.toHexString(firstToken) 3481 + " deltaTimeToken=" + deltaTimeToken); 3482 3483 if (deltaTimeToken < DELTA_TIME_ABS) { 3484 cur.time += deltaTimeToken; 3485 } else if (deltaTimeToken == DELTA_TIME_ABS) { 3486 cur.time = src.readLong(); 3487 cur.numReadInts += 2; 3488 if (DEBUG) Slog.i(TAG, "READ DELTA: ABS time=" + cur.time); 3489 cur.readFromParcel(src); 3490 return; 3491 } else if (deltaTimeToken == DELTA_TIME_INT) { 3492 int delta = src.readInt(); 3493 cur.time += delta; 3494 cur.numReadInts += 1; 3495 if (DEBUG) Slog.i(TAG, "READ DELTA: time delta=" + delta + " new time=" + cur.time); 3496 } else { 3497 long delta = src.readLong(); 3498 if (DEBUG) Slog.i(TAG, "READ DELTA: time delta=" + delta + " new time=" + cur.time); 3499 cur.time += delta; 3500 cur.numReadInts += 2; 3501 } 3502 3503 final int batteryLevelInt; 3504 if ((firstToken&DELTA_BATTERY_LEVEL_FLAG) != 0) { 3505 batteryLevelInt = src.readInt(); 3506 readBatteryLevelInt(batteryLevelInt, cur); 3507 cur.numReadInts += 1; 3508 if (DEBUG) Slog.i(TAG, "READ DELTA: batteryToken=0x" 3509 + Integer.toHexString(batteryLevelInt) 3510 + " batteryLevel=" + cur.batteryLevel 3511 + " batteryTemp=" + cur.batteryTemperature 3512 + " batteryVolt=" + (int)cur.batteryVoltage); 3513 } else { 3514 batteryLevelInt = 0; 3515 } 3516 3517 if ((firstToken&DELTA_STATE_FLAG) != 0) { 3518 int stateInt = src.readInt(); 3519 cur.states = (firstToken&DELTA_STATE_MASK) | (stateInt&(~STATE_BATTERY_MASK)); 3520 cur.batteryStatus = (byte)((stateInt>>STATE_BATTERY_STATUS_SHIFT) 3521 & STATE_BATTERY_STATUS_MASK); 3522 cur.batteryHealth = (byte)((stateInt>>STATE_BATTERY_HEALTH_SHIFT) 3523 & STATE_BATTERY_HEALTH_MASK); 3524 cur.batteryPlugType = (byte)((stateInt>>STATE_BATTERY_PLUG_SHIFT) 3525 & STATE_BATTERY_PLUG_MASK); 3526 switch (cur.batteryPlugType) { 3527 case 1: 3528 cur.batteryPlugType = BatteryManager.BATTERY_PLUGGED_AC; 3529 break; 3530 case 2: 3531 cur.batteryPlugType = BatteryManager.BATTERY_PLUGGED_USB; 3532 break; 3533 case 3: 3534 cur.batteryPlugType = BatteryManager.BATTERY_PLUGGED_WIRELESS; 3535 break; 3536 } 3537 cur.numReadInts += 1; 3538 if (DEBUG) Slog.i(TAG, "READ DELTA: stateToken=0x" 3539 + Integer.toHexString(stateInt) 3540 + " batteryStatus=" + cur.batteryStatus 3541 + " batteryHealth=" + cur.batteryHealth 3542 + " batteryPlugType=" + cur.batteryPlugType 3543 + " states=0x" + Integer.toHexString(cur.states)); 3544 } else { 3545 cur.states = (firstToken&DELTA_STATE_MASK) | (cur.states&(~STATE_BATTERY_MASK)); 3546 } 3547 3548 if ((firstToken&DELTA_STATE2_FLAG) != 0) { 3549 cur.states2 = src.readInt(); 3550 if (DEBUG) Slog.i(TAG, "READ DELTA: states2=0x" 3551 + Integer.toHexString(cur.states2)); 3552 } 3553 3554 if ((firstToken&DELTA_WAKELOCK_FLAG) != 0) { 3555 int indexes = src.readInt(); 3556 int wakeLockIndex = indexes&0xffff; 3557 int wakeReasonIndex = (indexes>>16)&0xffff; 3558 if (wakeLockIndex != 0xffff) { 3559 cur.wakelockTag = cur.localWakelockTag; 3560 readHistoryTag(wakeLockIndex, cur.wakelockTag); 3561 if (DEBUG) Slog.i(TAG, "READ DELTA: wakelockTag=#" + cur.wakelockTag.poolIdx 3562 + " " + cur.wakelockTag.uid + ":" + cur.wakelockTag.string); 3563 } else { 3564 cur.wakelockTag = null; 3565 } 3566 if (wakeReasonIndex != 0xffff) { 3567 cur.wakeReasonTag = cur.localWakeReasonTag; 3568 readHistoryTag(wakeReasonIndex, cur.wakeReasonTag); 3569 if (DEBUG) Slog.i(TAG, "READ DELTA: wakeReasonTag=#" + cur.wakeReasonTag.poolIdx 3570 + " " + cur.wakeReasonTag.uid + ":" + cur.wakeReasonTag.string); 3571 } else { 3572 cur.wakeReasonTag = null; 3573 } 3574 cur.numReadInts += 1; 3575 } else { 3576 cur.wakelockTag = null; 3577 cur.wakeReasonTag = null; 3578 } 3579 3580 if ((firstToken&DELTA_EVENT_FLAG) != 0) { 3581 cur.eventTag = cur.localEventTag; 3582 final int codeAndIndex = src.readInt(); 3583 cur.eventCode = (codeAndIndex&0xffff); 3584 final int index = ((codeAndIndex>>16)&0xffff); 3585 readHistoryTag(index, cur.eventTag); 3586 cur.numReadInts += 1; 3587 if (DEBUG) Slog.i(TAG, "READ DELTA: event=" + cur.eventCode + " tag=#" 3588 + cur.eventTag.poolIdx + " " + cur.eventTag.uid + ":" 3589 + cur.eventTag.string); 3590 } else { 3591 cur.eventCode = HistoryItem.EVENT_NONE; 3592 } 3593 3594 if ((batteryLevelInt&BATTERY_DELTA_LEVEL_FLAG) != 0) { 3595 cur.stepDetails = mReadHistoryStepDetails; 3596 cur.stepDetails.readFromParcel(src); 3597 } else { 3598 cur.stepDetails = null; 3599 } 3600 3601 if ((firstToken&DELTA_BATTERY_CHARGE_FLAG) != 0) { 3602 cur.batteryChargeUAh = src.readInt(); 3603 } 3604 cur.modemRailChargeMah = src.readDouble(); 3605 cur.wifiRailChargeMah = src.readDouble(); 3606 } 3607 3608 @Override commitCurrentHistoryBatchLocked()3609 public void commitCurrentHistoryBatchLocked() { 3610 mHistoryLastWritten.cmd = HistoryItem.CMD_NULL; 3611 } 3612 createFakeHistoryEvents(long numEvents)3613 public void createFakeHistoryEvents(long numEvents) { 3614 for(long i = 0; i < numEvents; i++) { 3615 noteLongPartialWakelockStart("name1", "historyName1", 1000); 3616 noteLongPartialWakelockFinish("name1", "historyName1", 1000); 3617 } 3618 } 3619 addHistoryBufferLocked(long elapsedRealtimeMs, HistoryItem cur)3620 void addHistoryBufferLocked(long elapsedRealtimeMs, HistoryItem cur) { 3621 if (!mHaveBatteryLevel || !mRecordingHistory) { 3622 return; 3623 } 3624 3625 final long timeDiff = (mHistoryBaseTime+elapsedRealtimeMs) - mHistoryLastWritten.time; 3626 final int diffStates = mHistoryLastWritten.states^(cur.states&mActiveHistoryStates); 3627 final int diffStates2 = mHistoryLastWritten.states2^(cur.states2&mActiveHistoryStates2); 3628 final int lastDiffStates = mHistoryLastWritten.states^mHistoryLastLastWritten.states; 3629 final int lastDiffStates2 = mHistoryLastWritten.states2^mHistoryLastLastWritten.states2; 3630 if (DEBUG) Slog.i(TAG, "ADD: tdelta=" + timeDiff + " diff=" 3631 + Integer.toHexString(diffStates) + " lastDiff=" 3632 + Integer.toHexString(lastDiffStates) + " diff2=" 3633 + Integer.toHexString(diffStates2) + " lastDiff2=" 3634 + Integer.toHexString(lastDiffStates2)); 3635 if (mHistoryBufferLastPos >= 0 && mHistoryLastWritten.cmd == HistoryItem.CMD_UPDATE 3636 && timeDiff < 1000 && (diffStates&lastDiffStates) == 0 3637 && (diffStates2&lastDiffStates2) == 0 3638 && (mHistoryLastWritten.wakelockTag == null || cur.wakelockTag == null) 3639 && (mHistoryLastWritten.wakeReasonTag == null || cur.wakeReasonTag == null) 3640 && mHistoryLastWritten.stepDetails == null 3641 && (mHistoryLastWritten.eventCode == HistoryItem.EVENT_NONE 3642 || cur.eventCode == HistoryItem.EVENT_NONE) 3643 && mHistoryLastWritten.batteryLevel == cur.batteryLevel 3644 && mHistoryLastWritten.batteryStatus == cur.batteryStatus 3645 && mHistoryLastWritten.batteryHealth == cur.batteryHealth 3646 && mHistoryLastWritten.batteryPlugType == cur.batteryPlugType 3647 && mHistoryLastWritten.batteryTemperature == cur.batteryTemperature 3648 && mHistoryLastWritten.batteryVoltage == cur.batteryVoltage) { 3649 // We can merge this new change in with the last one. Merging is 3650 // allowed as long as only the states have changed, and within those states 3651 // as long as no bit has changed both between now and the last entry, as 3652 // well as the last entry and the one before it (so we capture any toggles). 3653 if (DEBUG) Slog.i(TAG, "ADD: rewinding back to " + mHistoryBufferLastPos); 3654 mHistoryBuffer.setDataSize(mHistoryBufferLastPos); 3655 mHistoryBuffer.setDataPosition(mHistoryBufferLastPos); 3656 mHistoryBufferLastPos = -1; 3657 elapsedRealtimeMs = mHistoryLastWritten.time - mHistoryBaseTime; 3658 // If the last written history had a wakelock tag, we need to retain it. 3659 // Note that the condition above made sure that we aren't in a case where 3660 // both it and the current history item have a wakelock tag. 3661 if (mHistoryLastWritten.wakelockTag != null) { 3662 cur.wakelockTag = cur.localWakelockTag; 3663 cur.wakelockTag.setTo(mHistoryLastWritten.wakelockTag); 3664 } 3665 // If the last written history had a wake reason tag, we need to retain it. 3666 // Note that the condition above made sure that we aren't in a case where 3667 // both it and the current history item have a wakelock tag. 3668 if (mHistoryLastWritten.wakeReasonTag != null) { 3669 cur.wakeReasonTag = cur.localWakeReasonTag; 3670 cur.wakeReasonTag.setTo(mHistoryLastWritten.wakeReasonTag); 3671 } 3672 // If the last written history had an event, we need to retain it. 3673 // Note that the condition above made sure that we aren't in a case where 3674 // both it and the current history item have an event. 3675 if (mHistoryLastWritten.eventCode != HistoryItem.EVENT_NONE) { 3676 cur.eventCode = mHistoryLastWritten.eventCode; 3677 cur.eventTag = cur.localEventTag; 3678 cur.eventTag.setTo(mHistoryLastWritten.eventTag); 3679 } 3680 mHistoryLastWritten.setTo(mHistoryLastLastWritten); 3681 } 3682 final int dataSize = mHistoryBuffer.dataSize(); 3683 3684 if (dataSize >= mConstants.MAX_HISTORY_BUFFER) { 3685 //open a new history file. 3686 final long start = SystemClock.uptimeMillis(); 3687 writeHistoryLocked(true); 3688 if (DEBUG) { 3689 Slog.d(TAG, "addHistoryBufferLocked writeHistoryLocked takes ms:" 3690 + (SystemClock.uptimeMillis() - start)); 3691 } 3692 mBatteryStatsHistory.startNextFile(); 3693 mHistoryBuffer.setDataSize(0); 3694 mHistoryBuffer.setDataPosition(0); 3695 mHistoryBuffer.setDataCapacity(mConstants.MAX_HISTORY_BUFFER / 2); 3696 mHistoryBufferLastPos = -1; 3697 final long elapsedRealtime = mClocks.elapsedRealtime(); 3698 final long uptime = mClocks.uptimeMillis(); 3699 HistoryItem newItem = new HistoryItem(); 3700 newItem.setTo(cur); 3701 startRecordingHistory(elapsedRealtime, uptime, false); 3702 addHistoryBufferLocked(elapsedRealtimeMs, HistoryItem.CMD_UPDATE, newItem); 3703 return; 3704 } 3705 3706 if (dataSize == 0) { 3707 // The history is currently empty; we need it to start with a time stamp. 3708 cur.currentTime = System.currentTimeMillis(); 3709 addHistoryBufferLocked(elapsedRealtimeMs, HistoryItem.CMD_RESET, cur); 3710 } 3711 addHistoryBufferLocked(elapsedRealtimeMs, HistoryItem.CMD_UPDATE, cur); 3712 } 3713 addHistoryBufferLocked(long elapsedRealtimeMs, byte cmd, HistoryItem cur)3714 private void addHistoryBufferLocked(long elapsedRealtimeMs, byte cmd, HistoryItem cur) { 3715 if (mIteratingHistory) { 3716 throw new IllegalStateException("Can't do this while iterating history!"); 3717 } 3718 mHistoryBufferLastPos = mHistoryBuffer.dataPosition(); 3719 mHistoryLastLastWritten.setTo(mHistoryLastWritten); 3720 mHistoryLastWritten.setTo(mHistoryBaseTime + elapsedRealtimeMs, cmd, cur); 3721 mHistoryLastWritten.states &= mActiveHistoryStates; 3722 mHistoryLastWritten.states2 &= mActiveHistoryStates2; 3723 writeHistoryDelta(mHistoryBuffer, mHistoryLastWritten, mHistoryLastLastWritten); 3724 mLastHistoryElapsedRealtime = elapsedRealtimeMs; 3725 cur.wakelockTag = null; 3726 cur.wakeReasonTag = null; 3727 cur.eventCode = HistoryItem.EVENT_NONE; 3728 cur.eventTag = null; 3729 if (DEBUG_HISTORY) Slog.i(TAG, "Writing history buffer: was " + mHistoryBufferLastPos 3730 + " now " + mHistoryBuffer.dataPosition() 3731 + " size is now " + mHistoryBuffer.dataSize()); 3732 } 3733 3734 int mChangedStates = 0; 3735 int mChangedStates2 = 0; 3736 addHistoryRecordLocked(long elapsedRealtimeMs, long uptimeMs)3737 void addHistoryRecordLocked(long elapsedRealtimeMs, long uptimeMs) { 3738 if (mTrackRunningHistoryElapsedRealtime != 0) { 3739 final long diffElapsed = elapsedRealtimeMs - mTrackRunningHistoryElapsedRealtime; 3740 final long diffUptime = uptimeMs - mTrackRunningHistoryUptime; 3741 if (diffUptime < (diffElapsed-20)) { 3742 final long wakeElapsedTime = elapsedRealtimeMs - (diffElapsed - diffUptime); 3743 mHistoryAddTmp.setTo(mHistoryLastWritten); 3744 mHistoryAddTmp.wakelockTag = null; 3745 mHistoryAddTmp.wakeReasonTag = null; 3746 mHistoryAddTmp.eventCode = HistoryItem.EVENT_NONE; 3747 mHistoryAddTmp.states &= ~HistoryItem.STATE_CPU_RUNNING_FLAG; 3748 addHistoryRecordInnerLocked(wakeElapsedTime, mHistoryAddTmp); 3749 } 3750 } 3751 mHistoryCur.states |= HistoryItem.STATE_CPU_RUNNING_FLAG; 3752 mTrackRunningHistoryElapsedRealtime = elapsedRealtimeMs; 3753 mTrackRunningHistoryUptime = uptimeMs; 3754 addHistoryRecordInnerLocked(elapsedRealtimeMs, mHistoryCur); 3755 } 3756 addHistoryRecordInnerLocked(long elapsedRealtimeMs, HistoryItem cur)3757 void addHistoryRecordInnerLocked(long elapsedRealtimeMs, HistoryItem cur) { 3758 addHistoryBufferLocked(elapsedRealtimeMs, cur); 3759 3760 if (!USE_OLD_HISTORY) { 3761 return; 3762 } 3763 3764 if (!mHaveBatteryLevel || !mRecordingHistory) { 3765 return; 3766 } 3767 3768 // If the current time is basically the same as the last time, 3769 // and no states have since the last recorded entry changed and 3770 // are now resetting back to their original value, then just collapse 3771 // into one record. 3772 if (mHistoryEnd != null && mHistoryEnd.cmd == HistoryItem.CMD_UPDATE 3773 && (mHistoryBaseTime+elapsedRealtimeMs) < (mHistoryEnd.time+1000) 3774 && ((mHistoryEnd.states^cur.states)&mChangedStates&mActiveHistoryStates) == 0 3775 && ((mHistoryEnd.states2^cur.states2)&mChangedStates2&mActiveHistoryStates2) == 0) { 3776 // If the current is the same as the one before, then we no 3777 // longer need the entry. 3778 if (mHistoryLastEnd != null && mHistoryLastEnd.cmd == HistoryItem.CMD_UPDATE 3779 && (mHistoryBaseTime+elapsedRealtimeMs) < (mHistoryEnd.time+500) 3780 && mHistoryLastEnd.sameNonEvent(cur)) { 3781 mHistoryLastEnd.next = null; 3782 mHistoryEnd.next = mHistoryCache; 3783 mHistoryCache = mHistoryEnd; 3784 mHistoryEnd = mHistoryLastEnd; 3785 mHistoryLastEnd = null; 3786 } else { 3787 mChangedStates |= mHistoryEnd.states^(cur.states&mActiveHistoryStates); 3788 mChangedStates2 |= mHistoryEnd.states^(cur.states2&mActiveHistoryStates2); 3789 mHistoryEnd.setTo(mHistoryEnd.time, HistoryItem.CMD_UPDATE, cur); 3790 } 3791 return; 3792 } 3793 3794 mChangedStates = 0; 3795 mChangedStates2 = 0; 3796 addHistoryBufferLocked(elapsedRealtimeMs, HistoryItem.CMD_UPDATE, cur); 3797 } 3798 addHistoryEventLocked(long elapsedRealtimeMs, long uptimeMs, int code, String name, int uid)3799 public void addHistoryEventLocked(long elapsedRealtimeMs, long uptimeMs, int code, 3800 String name, int uid) { 3801 mHistoryCur.eventCode = code; 3802 mHistoryCur.eventTag = mHistoryCur.localEventTag; 3803 mHistoryCur.eventTag.string = name; 3804 mHistoryCur.eventTag.uid = uid; 3805 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 3806 } 3807 addHistoryRecordLocked(long elapsedRealtimeMs, long uptimeMs, byte cmd, HistoryItem cur)3808 void addHistoryRecordLocked(long elapsedRealtimeMs, long uptimeMs, byte cmd, HistoryItem cur) { 3809 HistoryItem rec = mHistoryCache; 3810 if (rec != null) { 3811 mHistoryCache = rec.next; 3812 } else { 3813 rec = new HistoryItem(); 3814 } 3815 rec.setTo(mHistoryBaseTime + elapsedRealtimeMs, cmd, cur); 3816 3817 addHistoryRecordLocked(rec); 3818 } 3819 addHistoryRecordLocked(HistoryItem rec)3820 void addHistoryRecordLocked(HistoryItem rec) { 3821 mNumHistoryItems++; 3822 rec.next = null; 3823 mHistoryLastEnd = mHistoryEnd; 3824 if (mHistoryEnd != null) { 3825 mHistoryEnd.next = rec; 3826 mHistoryEnd = rec; 3827 } else { 3828 mHistory = mHistoryEnd = rec; 3829 } 3830 } 3831 clearHistoryLocked()3832 void clearHistoryLocked() { 3833 if (DEBUG_HISTORY) Slog.i(TAG, "********** CLEARING HISTORY!"); 3834 if (USE_OLD_HISTORY) { 3835 if (mHistory != null) { 3836 mHistoryEnd.next = mHistoryCache; 3837 mHistoryCache = mHistory; 3838 mHistory = mHistoryLastEnd = mHistoryEnd = null; 3839 } 3840 mNumHistoryItems = 0; 3841 } 3842 3843 mHistoryBaseTime = 0; 3844 mLastHistoryElapsedRealtime = 0; 3845 mTrackRunningHistoryElapsedRealtime = 0; 3846 mTrackRunningHistoryUptime = 0; 3847 3848 mHistoryBuffer.setDataSize(0); 3849 mHistoryBuffer.setDataPosition(0); 3850 mHistoryBuffer.setDataCapacity(mConstants.MAX_HISTORY_BUFFER / 2); 3851 mHistoryLastLastWritten.clear(); 3852 mHistoryLastWritten.clear(); 3853 mHistoryTagPool.clear(); 3854 mNextHistoryTagIdx = 0; 3855 mNumHistoryTagChars = 0; 3856 mHistoryBufferLastPos = -1; 3857 mActiveHistoryStates = 0xffffffff; 3858 mActiveHistoryStates2 = 0xffffffff; 3859 } 3860 3861 @GuardedBy("this") updateTimeBasesLocked(boolean unplugged, int screenState, long uptime, long realtime)3862 public void updateTimeBasesLocked(boolean unplugged, int screenState, long uptime, 3863 long realtime) { 3864 final boolean screenOff = !isScreenOn(screenState); 3865 final boolean updateOnBatteryTimeBase = unplugged != mOnBatteryTimeBase.isRunning(); 3866 final boolean updateOnBatteryScreenOffTimeBase = 3867 (unplugged && screenOff) != mOnBatteryScreenOffTimeBase.isRunning(); 3868 3869 if (updateOnBatteryScreenOffTimeBase || updateOnBatteryTimeBase) { 3870 if (updateOnBatteryScreenOffTimeBase) { 3871 updateKernelWakelocksLocked(); 3872 updateBatteryPropertiesLocked(); 3873 } 3874 // This if{} is only necessary due to SCREEN_OFF_RPM_STATS_ENABLED, which exists because 3875 // updateRpmStatsLocked is too slow to run each screen change. When the speed is 3876 // improved, remove the surrounding if{}. 3877 if (SCREEN_OFF_RPM_STATS_ENABLED || updateOnBatteryTimeBase) { 3878 updateRpmStatsLocked(); // if either OnBattery or OnBatteryScreenOff timebase changes. 3879 } 3880 if (DEBUG_ENERGY_CPU) { 3881 Slog.d(TAG, "Updating cpu time because screen is now " 3882 + Display.stateToString(screenState) 3883 + " and battery is " + (unplugged ? "on" : "off")); 3884 } 3885 3886 mOnBatteryTimeBase.setRunning(unplugged, uptime, realtime); 3887 if (updateOnBatteryTimeBase) { 3888 for (int i = mUidStats.size() - 1; i >= 0; --i) { 3889 mUidStats.valueAt(i).updateOnBatteryBgTimeBase(uptime, realtime); 3890 } 3891 } 3892 if (updateOnBatteryScreenOffTimeBase) { 3893 mOnBatteryScreenOffTimeBase.setRunning(unplugged && screenOff, uptime, realtime); 3894 for (int i = mUidStats.size() - 1; i >= 0; --i) { 3895 mUidStats.valueAt(i).updateOnBatteryScreenOffBgTimeBase(uptime, realtime); 3896 } 3897 } 3898 } 3899 } 3900 updateBatteryPropertiesLocked()3901 private void updateBatteryPropertiesLocked() { 3902 try { 3903 IBatteryPropertiesRegistrar registrar = IBatteryPropertiesRegistrar.Stub.asInterface( 3904 ServiceManager.getService("batteryproperties")); 3905 if (registrar != null) { 3906 registrar.scheduleUpdate(); 3907 } 3908 } catch (RemoteException e) { 3909 // Ignore. 3910 } 3911 } 3912 addIsolatedUidLocked(int isolatedUid, int appUid)3913 public void addIsolatedUidLocked(int isolatedUid, int appUid) { 3914 mIsolatedUids.put(isolatedUid, appUid); 3915 final Uid u = getUidStatsLocked(appUid); 3916 u.addIsolatedUid(isolatedUid); 3917 } 3918 3919 /** 3920 * Schedules a read of the latest cpu times before removing the isolated UID. 3921 * @see #removeIsolatedUidLocked(int) 3922 */ scheduleRemoveIsolatedUidLocked(int isolatedUid, int appUid)3923 public void scheduleRemoveIsolatedUidLocked(int isolatedUid, int appUid) { 3924 int curUid = mIsolatedUids.get(isolatedUid, -1); 3925 if (curUid == appUid) { 3926 if (mExternalSync != null) { 3927 mExternalSync.scheduleCpuSyncDueToRemovedUid(isolatedUid); 3928 } 3929 } 3930 } 3931 3932 /** 3933 * This should only be called after the cpu times have been read. 3934 * @see #scheduleRemoveIsolatedUidLocked(int, int) 3935 */ 3936 @GuardedBy("this") removeIsolatedUidLocked(int isolatedUid)3937 public void removeIsolatedUidLocked(int isolatedUid) { 3938 final int idx = mIsolatedUids.indexOfKey(isolatedUid); 3939 if (idx >= 0) { 3940 final int ownerUid = mIsolatedUids.valueAt(idx); 3941 final Uid u = getUidStatsLocked(ownerUid); 3942 u.removeIsolatedUid(isolatedUid); 3943 mIsolatedUids.removeAt(idx); 3944 } 3945 mPendingRemovedUids.add(new UidToRemove(isolatedUid, mClocks.elapsedRealtime())); 3946 } 3947 mapUid(int uid)3948 public int mapUid(int uid) { 3949 int isolated = mIsolatedUids.get(uid, -1); 3950 return isolated > 0 ? isolated : uid; 3951 } 3952 noteEventLocked(int code, String name, int uid)3953 public void noteEventLocked(int code, String name, int uid) { 3954 uid = mapUid(uid); 3955 if (!mActiveEvents.updateState(code, name, uid, 0)) { 3956 return; 3957 } 3958 final long elapsedRealtime = mClocks.elapsedRealtime(); 3959 final long uptime = mClocks.uptimeMillis(); 3960 addHistoryEventLocked(elapsedRealtime, uptime, code, name, uid); 3961 } 3962 noteCurrentTimeChangedLocked()3963 public void noteCurrentTimeChangedLocked() { 3964 final long currentTime = System.currentTimeMillis(); 3965 final long elapsedRealtime = mClocks.elapsedRealtime(); 3966 final long uptime = mClocks.uptimeMillis(); 3967 recordCurrentTimeChangeLocked(currentTime, elapsedRealtime, uptime); 3968 } 3969 noteProcessStartLocked(String name, int uid)3970 public void noteProcessStartLocked(String name, int uid) { 3971 uid = mapUid(uid); 3972 if (isOnBattery()) { 3973 Uid u = getUidStatsLocked(uid); 3974 u.getProcessStatsLocked(name).incStartsLocked(); 3975 } 3976 if (!mActiveEvents.updateState(HistoryItem.EVENT_PROC_START, name, uid, 0)) { 3977 return; 3978 } 3979 if (!mRecordAllHistory) { 3980 return; 3981 } 3982 final long elapsedRealtime = mClocks.elapsedRealtime(); 3983 final long uptime = mClocks.uptimeMillis(); 3984 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_PROC_START, name, uid); 3985 } 3986 noteProcessCrashLocked(String name, int uid)3987 public void noteProcessCrashLocked(String name, int uid) { 3988 uid = mapUid(uid); 3989 if (isOnBattery()) { 3990 Uid u = getUidStatsLocked(uid); 3991 u.getProcessStatsLocked(name).incNumCrashesLocked(); 3992 } 3993 } 3994 noteProcessAnrLocked(String name, int uid)3995 public void noteProcessAnrLocked(String name, int uid) { 3996 uid = mapUid(uid); 3997 if (isOnBattery()) { 3998 Uid u = getUidStatsLocked(uid); 3999 u.getProcessStatsLocked(name).incNumAnrsLocked(); 4000 } 4001 } 4002 noteUidProcessStateLocked(int uid, int state)4003 public void noteUidProcessStateLocked(int uid, int state) { 4004 int parentUid = mapUid(uid); 4005 if (uid != parentUid) { 4006 // Isolated UIDs process state is already rolled up into parent, so no need to track 4007 // Otherwise the parent's process state will get downgraded incorrectly 4008 return; 4009 } 4010 getUidStatsLocked(uid).updateUidProcessStateLocked(state); 4011 } 4012 noteProcessFinishLocked(String name, int uid)4013 public void noteProcessFinishLocked(String name, int uid) { 4014 uid = mapUid(uid); 4015 if (!mActiveEvents.updateState(HistoryItem.EVENT_PROC_FINISH, name, uid, 0)) { 4016 return; 4017 } 4018 if (!mRecordAllHistory) { 4019 return; 4020 } 4021 final long elapsedRealtime = mClocks.elapsedRealtime(); 4022 final long uptime = mClocks.uptimeMillis(); 4023 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_PROC_FINISH, name, uid); 4024 } 4025 noteSyncStartLocked(String name, int uid)4026 public void noteSyncStartLocked(String name, int uid) { 4027 uid = mapUid(uid); 4028 final long elapsedRealtime = mClocks.elapsedRealtime(); 4029 final long uptime = mClocks.uptimeMillis(); 4030 getUidStatsLocked(uid).noteStartSyncLocked(name, elapsedRealtime); 4031 if (!mActiveEvents.updateState(HistoryItem.EVENT_SYNC_START, name, uid, 0)) { 4032 return; 4033 } 4034 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_SYNC_START, name, uid); 4035 } 4036 noteSyncFinishLocked(String name, int uid)4037 public void noteSyncFinishLocked(String name, int uid) { 4038 uid = mapUid(uid); 4039 final long elapsedRealtime = mClocks.elapsedRealtime(); 4040 final long uptime = mClocks.uptimeMillis(); 4041 getUidStatsLocked(uid).noteStopSyncLocked(name, elapsedRealtime); 4042 if (!mActiveEvents.updateState(HistoryItem.EVENT_SYNC_FINISH, name, uid, 0)) { 4043 return; 4044 } 4045 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_SYNC_FINISH, name, uid); 4046 } 4047 noteJobStartLocked(String name, int uid)4048 public void noteJobStartLocked(String name, int uid) { 4049 uid = mapUid(uid); 4050 final long elapsedRealtime = mClocks.elapsedRealtime(); 4051 final long uptime = mClocks.uptimeMillis(); 4052 getUidStatsLocked(uid).noteStartJobLocked(name, elapsedRealtime); 4053 if (!mActiveEvents.updateState(HistoryItem.EVENT_JOB_START, name, uid, 0)) { 4054 return; 4055 } 4056 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_JOB_START, name, uid); 4057 } 4058 noteJobFinishLocked(String name, int uid, int stopReason)4059 public void noteJobFinishLocked(String name, int uid, int stopReason) { 4060 uid = mapUid(uid); 4061 final long elapsedRealtime = mClocks.elapsedRealtime(); 4062 final long uptime = mClocks.uptimeMillis(); 4063 getUidStatsLocked(uid).noteStopJobLocked(name, elapsedRealtime, stopReason); 4064 if (!mActiveEvents.updateState(HistoryItem.EVENT_JOB_FINISH, name, uid, 0)) { 4065 return; 4066 } 4067 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_JOB_FINISH, name, uid); 4068 } 4069 noteJobsDeferredLocked(int uid, int numDeferred, long sinceLast)4070 public void noteJobsDeferredLocked(int uid, int numDeferred, long sinceLast) { 4071 uid = mapUid(uid); 4072 getUidStatsLocked(uid).noteJobsDeferredLocked(numDeferred, sinceLast); 4073 } 4074 noteAlarmStartLocked(String name, WorkSource workSource, int uid)4075 public void noteAlarmStartLocked(String name, WorkSource workSource, int uid) { 4076 noteAlarmStartOrFinishLocked(HistoryItem.EVENT_ALARM_START, name, workSource, uid); 4077 } 4078 noteAlarmFinishLocked(String name, WorkSource workSource, int uid)4079 public void noteAlarmFinishLocked(String name, WorkSource workSource, int uid) { 4080 noteAlarmStartOrFinishLocked(HistoryItem.EVENT_ALARM_FINISH, name, workSource, uid); 4081 } 4082 noteAlarmStartOrFinishLocked(int historyItem, String name, WorkSource workSource, int uid)4083 private void noteAlarmStartOrFinishLocked(int historyItem, String name, WorkSource workSource, 4084 int uid) { 4085 if (!mRecordAllHistory) { 4086 return; 4087 } 4088 4089 final long elapsedRealtime = mClocks.elapsedRealtime(); 4090 final long uptime = mClocks.uptimeMillis(); 4091 4092 if (workSource != null) { 4093 for (int i = 0; i < workSource.size(); ++i) { 4094 uid = mapUid(workSource.get(i)); 4095 if (mActiveEvents.updateState(historyItem, name, uid, 0)) { 4096 addHistoryEventLocked(elapsedRealtime, uptime, historyItem, name, uid); 4097 } 4098 } 4099 4100 List<WorkChain> workChains = workSource.getWorkChains(); 4101 if (workChains != null) { 4102 for (int i = 0; i < workChains.size(); ++i) { 4103 uid = mapUid(workChains.get(i).getAttributionUid()); 4104 if (mActiveEvents.updateState(historyItem, name, uid, 0)) { 4105 addHistoryEventLocked(elapsedRealtime, uptime, historyItem, name, uid); 4106 } 4107 } 4108 } 4109 } else { 4110 uid = mapUid(uid); 4111 4112 if (mActiveEvents.updateState(historyItem, name, uid, 0)) { 4113 addHistoryEventLocked(elapsedRealtime, uptime, historyItem, name, uid); 4114 } 4115 } 4116 } 4117 noteWakupAlarmLocked(String packageName, int uid, WorkSource workSource, String tag)4118 public void noteWakupAlarmLocked(String packageName, int uid, WorkSource workSource, 4119 String tag) { 4120 if (workSource != null) { 4121 for (int i = 0; i < workSource.size(); ++i) { 4122 uid = workSource.get(i); 4123 final String workSourceName = workSource.getName(i); 4124 4125 if (isOnBattery()) { 4126 BatteryStatsImpl.Uid.Pkg pkg = getPackageStatsLocked(uid, 4127 workSourceName != null ? workSourceName : packageName); 4128 pkg.noteWakeupAlarmLocked(tag); 4129 } 4130 } 4131 4132 ArrayList<WorkChain> workChains = workSource.getWorkChains(); 4133 if (workChains != null) { 4134 for (int i = 0; i < workChains.size(); ++i) { 4135 final WorkChain wc = workChains.get(i); 4136 uid = wc.getAttributionUid(); 4137 4138 if (isOnBattery()) { 4139 BatteryStatsImpl.Uid.Pkg pkg = getPackageStatsLocked(uid, packageName); 4140 pkg.noteWakeupAlarmLocked(tag); 4141 } 4142 } 4143 } 4144 } else { 4145 if (isOnBattery()) { 4146 BatteryStatsImpl.Uid.Pkg pkg = getPackageStatsLocked(uid, packageName); 4147 pkg.noteWakeupAlarmLocked(tag); 4148 } 4149 } 4150 } 4151 requestWakelockCpuUpdate()4152 private void requestWakelockCpuUpdate() { 4153 mExternalSync.scheduleCpuSyncDueToWakelockChange(DELAY_UPDATE_WAKELOCKS); 4154 } 4155 requestImmediateCpuUpdate()4156 private void requestImmediateCpuUpdate() { 4157 mExternalSync.scheduleCpuSyncDueToWakelockChange(0 /* delayMillis */); 4158 } 4159 setRecordAllHistoryLocked(boolean enabled)4160 public void setRecordAllHistoryLocked(boolean enabled) { 4161 mRecordAllHistory = enabled; 4162 if (!enabled) { 4163 // Clear out any existing state. 4164 mActiveEvents.removeEvents(HistoryItem.EVENT_WAKE_LOCK); 4165 mActiveEvents.removeEvents(HistoryItem.EVENT_ALARM); 4166 // Record the currently running processes as stopping, now that we are no 4167 // longer tracking them. 4168 HashMap<String, SparseIntArray> active = mActiveEvents.getStateForEvent( 4169 HistoryItem.EVENT_PROC); 4170 if (active != null) { 4171 long mSecRealtime = mClocks.elapsedRealtime(); 4172 final long mSecUptime = mClocks.uptimeMillis(); 4173 for (HashMap.Entry<String, SparseIntArray> ent : active.entrySet()) { 4174 SparseIntArray uids = ent.getValue(); 4175 for (int j=0; j<uids.size(); j++) { 4176 addHistoryEventLocked(mSecRealtime, mSecUptime, 4177 HistoryItem.EVENT_PROC_FINISH, ent.getKey(), uids.keyAt(j)); 4178 } 4179 } 4180 } 4181 } else { 4182 // Record the currently running processes as starting, now that we are tracking them. 4183 HashMap<String, SparseIntArray> active = mActiveEvents.getStateForEvent( 4184 HistoryItem.EVENT_PROC); 4185 if (active != null) { 4186 long mSecRealtime = mClocks.elapsedRealtime(); 4187 final long mSecUptime = mClocks.uptimeMillis(); 4188 for (HashMap.Entry<String, SparseIntArray> ent : active.entrySet()) { 4189 SparseIntArray uids = ent.getValue(); 4190 for (int j=0; j<uids.size(); j++) { 4191 addHistoryEventLocked(mSecRealtime, mSecUptime, 4192 HistoryItem.EVENT_PROC_START, ent.getKey(), uids.keyAt(j)); 4193 } 4194 } 4195 } 4196 } 4197 } 4198 setNoAutoReset(boolean enabled)4199 public void setNoAutoReset(boolean enabled) { 4200 mNoAutoReset = enabled; 4201 } 4202 setPretendScreenOff(boolean pretendScreenOff)4203 public void setPretendScreenOff(boolean pretendScreenOff) { 4204 if (mPretendScreenOff != pretendScreenOff) { 4205 mPretendScreenOff = pretendScreenOff; 4206 noteScreenStateLocked(pretendScreenOff ? Display.STATE_OFF : Display.STATE_ON); 4207 } 4208 } 4209 4210 private String mInitialAcquireWakeName; 4211 private int mInitialAcquireWakeUid = -1; 4212 noteStartWakeLocked(int uid, int pid, WorkChain wc, String name, String historyName, int type, boolean unimportantForLogging, long elapsedRealtime, long uptime)4213 public void noteStartWakeLocked(int uid, int pid, WorkChain wc, String name, String historyName, 4214 int type, boolean unimportantForLogging, long elapsedRealtime, long uptime) { 4215 uid = mapUid(uid); 4216 if (type == WAKE_TYPE_PARTIAL) { 4217 // Only care about partial wake locks, since full wake locks 4218 // will be canceled when the user puts the screen to sleep. 4219 aggregateLastWakeupUptimeLocked(uptime); 4220 if (historyName == null) { 4221 historyName = name; 4222 } 4223 if (mRecordAllHistory) { 4224 if (mActiveEvents.updateState(HistoryItem.EVENT_WAKE_LOCK_START, historyName, 4225 uid, 0)) { 4226 addHistoryEventLocked(elapsedRealtime, uptime, 4227 HistoryItem.EVENT_WAKE_LOCK_START, historyName, uid); 4228 } 4229 } 4230 if (mWakeLockNesting == 0) { 4231 mHistoryCur.states |= HistoryItem.STATE_WAKE_LOCK_FLAG; 4232 if (DEBUG_HISTORY) Slog.v(TAG, "Start wake lock to: " 4233 + Integer.toHexString(mHistoryCur.states)); 4234 mHistoryCur.wakelockTag = mHistoryCur.localWakelockTag; 4235 mHistoryCur.wakelockTag.string = mInitialAcquireWakeName = historyName; 4236 mHistoryCur.wakelockTag.uid = mInitialAcquireWakeUid = uid; 4237 mWakeLockImportant = !unimportantForLogging; 4238 addHistoryRecordLocked(elapsedRealtime, uptime); 4239 } else if (!mWakeLockImportant && !unimportantForLogging 4240 && mHistoryLastWritten.cmd == HistoryItem.CMD_UPDATE) { 4241 if (mHistoryLastWritten.wakelockTag != null) { 4242 // We'll try to update the last tag. 4243 mHistoryLastWritten.wakelockTag = null; 4244 mHistoryCur.wakelockTag = mHistoryCur.localWakelockTag; 4245 mHistoryCur.wakelockTag.string = mInitialAcquireWakeName = historyName; 4246 mHistoryCur.wakelockTag.uid = mInitialAcquireWakeUid = uid; 4247 addHistoryRecordLocked(elapsedRealtime, uptime); 4248 } 4249 mWakeLockImportant = true; 4250 } 4251 mWakeLockNesting++; 4252 } 4253 if (uid >= 0) { 4254 if (mOnBatteryScreenOffTimeBase.isRunning()) { 4255 // We only update the cpu time when a wake lock is acquired if the screen is off. 4256 // If the screen is on, we don't distribute the power amongst partial wakelocks. 4257 if (DEBUG_ENERGY_CPU) { 4258 Slog.d(TAG, "Updating cpu time because of +wake_lock"); 4259 } 4260 requestWakelockCpuUpdate(); 4261 } 4262 4263 getUidStatsLocked(uid).noteStartWakeLocked(pid, name, type, elapsedRealtime); 4264 4265 if (wc != null) { 4266 StatsLog.write(StatsLog.WAKELOCK_STATE_CHANGED, wc.getUids(), wc.getTags(), 4267 getPowerManagerWakeLockLevel(type), name, 4268 StatsLog.WAKELOCK_STATE_CHANGED__STATE__ACQUIRE); 4269 } else { 4270 StatsLog.write_non_chained(StatsLog.WAKELOCK_STATE_CHANGED, uid, null, 4271 getPowerManagerWakeLockLevel(type), name, 4272 StatsLog.WAKELOCK_STATE_CHANGED__STATE__ACQUIRE); 4273 } 4274 } 4275 } 4276 noteStopWakeLocked(int uid, int pid, WorkChain wc, String name, String historyName, int type, long elapsedRealtime, long uptime)4277 public void noteStopWakeLocked(int uid, int pid, WorkChain wc, String name, String historyName, 4278 int type, long elapsedRealtime, long uptime) { 4279 uid = mapUid(uid); 4280 if (type == WAKE_TYPE_PARTIAL) { 4281 mWakeLockNesting--; 4282 if (mRecordAllHistory) { 4283 if (historyName == null) { 4284 historyName = name; 4285 } 4286 if (mActiveEvents.updateState(HistoryItem.EVENT_WAKE_LOCK_FINISH, historyName, 4287 uid, 0)) { 4288 addHistoryEventLocked(elapsedRealtime, uptime, 4289 HistoryItem.EVENT_WAKE_LOCK_FINISH, historyName, uid); 4290 } 4291 } 4292 if (mWakeLockNesting == 0) { 4293 mHistoryCur.states &= ~HistoryItem.STATE_WAKE_LOCK_FLAG; 4294 if (DEBUG_HISTORY) Slog.v(TAG, "Stop wake lock to: " 4295 + Integer.toHexString(mHistoryCur.states)); 4296 mInitialAcquireWakeName = null; 4297 mInitialAcquireWakeUid = -1; 4298 addHistoryRecordLocked(elapsedRealtime, uptime); 4299 } 4300 } 4301 if (uid >= 0) { 4302 if (mOnBatteryScreenOffTimeBase.isRunning()) { 4303 if (DEBUG_ENERGY_CPU) { 4304 Slog.d(TAG, "Updating cpu time because of -wake_lock"); 4305 } 4306 requestWakelockCpuUpdate(); 4307 } 4308 4309 getUidStatsLocked(uid).noteStopWakeLocked(pid, name, type, elapsedRealtime); 4310 if (wc != null) { 4311 StatsLog.write(StatsLog.WAKELOCK_STATE_CHANGED, wc.getUids(), wc.getTags(), 4312 getPowerManagerWakeLockLevel(type), name, 4313 StatsLog.WAKELOCK_STATE_CHANGED__STATE__RELEASE); 4314 } else { 4315 StatsLog.write_non_chained(StatsLog.WAKELOCK_STATE_CHANGED, uid, null, 4316 getPowerManagerWakeLockLevel(type), name, 4317 StatsLog.WAKELOCK_STATE_CHANGED__STATE__RELEASE); 4318 } 4319 } 4320 } 4321 4322 /** 4323 * Converts BatteryStats wakelock types back into PowerManager wakelock levels. 4324 * This is the inverse map of Notifier.getBatteryStatsWakeLockMonitorType(). 4325 * These are estimations, since batterystats loses some of the original data. 4326 * TODO: Delete this. Instead, StatsLog.write should be called from PowerManager's Notifier. 4327 */ getPowerManagerWakeLockLevel(int battertStatsWakelockType)4328 private int getPowerManagerWakeLockLevel(int battertStatsWakelockType) { 4329 switch (battertStatsWakelockType) { 4330 // PowerManager.PARTIAL_WAKE_LOCK or PROXIMITY_SCREEN_OFF_WAKE_LOCK 4331 case BatteryStats.WAKE_TYPE_PARTIAL: 4332 return PowerManager.PARTIAL_WAKE_LOCK; 4333 4334 // PowerManager.SCREEN_DIM_WAKE_LOCK or SCREEN_BRIGHT_WAKE_LOCK 4335 case BatteryStats.WAKE_TYPE_FULL: 4336 return PowerManager.FULL_WAKE_LOCK; 4337 4338 case BatteryStats.WAKE_TYPE_DRAW: 4339 return PowerManager.DRAW_WAKE_LOCK; 4340 4341 // It appears that nothing can ever make a Window and PowerManager lacks an equivalent. 4342 case BatteryStats.WAKE_TYPE_WINDOW: 4343 Slog.e(TAG, "Illegal window wakelock type observed in batterystats."); 4344 return -1; 4345 4346 default: 4347 Slog.e(TAG, "Illegal wakelock type in batterystats: " + battertStatsWakelockType); 4348 return -1; 4349 } 4350 } 4351 noteStartWakeFromSourceLocked(WorkSource ws, int pid, String name, String historyName, int type, boolean unimportantForLogging)4352 public void noteStartWakeFromSourceLocked(WorkSource ws, int pid, String name, 4353 String historyName, int type, boolean unimportantForLogging) { 4354 final long elapsedRealtime = mClocks.elapsedRealtime(); 4355 final long uptime = mClocks.uptimeMillis(); 4356 final int N = ws.size(); 4357 for (int i=0; i<N; i++) { 4358 noteStartWakeLocked(ws.get(i), pid, null, name, historyName, type, 4359 unimportantForLogging, elapsedRealtime, uptime); 4360 } 4361 4362 List<WorkChain> wcs = ws.getWorkChains(); 4363 if (wcs != null) { 4364 for (int i = 0; i < wcs.size(); ++i) { 4365 final WorkChain wc = wcs.get(i); 4366 noteStartWakeLocked(wc.getAttributionUid(), pid, wc, name, historyName, type, 4367 unimportantForLogging, elapsedRealtime, uptime); 4368 } 4369 } 4370 } 4371 noteChangeWakelockFromSourceLocked(WorkSource ws, int pid, String name, String historyName, int type, WorkSource newWs, int newPid, String newName, String newHistoryName, int newType, boolean newUnimportantForLogging)4372 public void noteChangeWakelockFromSourceLocked(WorkSource ws, int pid, String name, 4373 String historyName, int type, WorkSource newWs, int newPid, String newName, 4374 String newHistoryName, int newType, boolean newUnimportantForLogging) { 4375 final long elapsedRealtime = mClocks.elapsedRealtime(); 4376 final long uptime = mClocks.uptimeMillis(); 4377 4378 List<WorkChain>[] wcs = WorkSource.diffChains(ws, newWs); 4379 4380 // For correct semantics, we start the need worksources first, so that we won't 4381 // make inappropriate history items as if all wake locks went away and new ones 4382 // appeared. This is okay because tracking of wake locks allows nesting. 4383 // 4384 // First the starts : 4385 final int NN = newWs.size(); 4386 for (int i=0; i<NN; i++) { 4387 noteStartWakeLocked(newWs.get(i), newPid, null, newName, newHistoryName, newType, 4388 newUnimportantForLogging, elapsedRealtime, uptime); 4389 } 4390 if (wcs != null) { 4391 List<WorkChain> newChains = wcs[0]; 4392 if (newChains != null) { 4393 for (int i = 0; i < newChains.size(); ++i) { 4394 final WorkChain newChain = newChains.get(i); 4395 noteStartWakeLocked(newChain.getAttributionUid(), newPid, newChain, newName, 4396 newHistoryName, newType, newUnimportantForLogging, elapsedRealtime, 4397 uptime); 4398 } 4399 } 4400 } 4401 4402 // Then the stops : 4403 final int NO = ws.size(); 4404 for (int i=0; i<NO; i++) { 4405 noteStopWakeLocked(ws.get(i), pid, null, name, historyName, type, elapsedRealtime, 4406 uptime); 4407 } 4408 if (wcs != null) { 4409 List<WorkChain> goneChains = wcs[1]; 4410 if (goneChains != null) { 4411 for (int i = 0; i < goneChains.size(); ++i) { 4412 final WorkChain goneChain = goneChains.get(i); 4413 noteStopWakeLocked(goneChain.getAttributionUid(), pid, goneChain, name, 4414 historyName, type, elapsedRealtime, uptime); 4415 } 4416 } 4417 } 4418 } 4419 noteStopWakeFromSourceLocked(WorkSource ws, int pid, String name, String historyName, int type)4420 public void noteStopWakeFromSourceLocked(WorkSource ws, int pid, String name, 4421 String historyName, int type) { 4422 final long elapsedRealtime = mClocks.elapsedRealtime(); 4423 final long uptime = mClocks.uptimeMillis(); 4424 final int N = ws.size(); 4425 for (int i=0; i<N; i++) { 4426 noteStopWakeLocked(ws.get(i), pid, null, name, historyName, type, elapsedRealtime, 4427 uptime); 4428 } 4429 4430 List<WorkChain> wcs = ws.getWorkChains(); 4431 if (wcs != null) { 4432 for (int i = 0; i < wcs.size(); ++i) { 4433 final WorkChain wc = wcs.get(i); 4434 noteStopWakeLocked(wc.getAttributionUid(), pid, wc, name, historyName, type, 4435 elapsedRealtime, uptime); 4436 } 4437 } 4438 } 4439 noteLongPartialWakelockStart(String name, String historyName, int uid)4440 public void noteLongPartialWakelockStart(String name, String historyName, int uid) { 4441 uid = mapUid(uid); 4442 noteLongPartialWakeLockStartInternal(name, historyName, uid); 4443 } 4444 noteLongPartialWakelockStartFromSource(String name, String historyName, WorkSource workSource)4445 public void noteLongPartialWakelockStartFromSource(String name, String historyName, 4446 WorkSource workSource) { 4447 final int N = workSource.size(); 4448 for (int i = 0; i < N; ++i) { 4449 final int uid = mapUid(workSource.get(i)); 4450 noteLongPartialWakeLockStartInternal(name, historyName, uid); 4451 } 4452 4453 final ArrayList<WorkChain> workChains = workSource.getWorkChains(); 4454 if (workChains != null) { 4455 for (int i = 0; i < workChains.size(); ++i) { 4456 final WorkChain workChain = workChains.get(i); 4457 final int uid = workChain.getAttributionUid(); 4458 noteLongPartialWakeLockStartInternal(name, historyName, uid); 4459 } 4460 } 4461 } 4462 noteLongPartialWakeLockStartInternal(String name, String historyName, int uid)4463 private void noteLongPartialWakeLockStartInternal(String name, String historyName, int uid) { 4464 final long elapsedRealtime = mClocks.elapsedRealtime(); 4465 final long uptime = mClocks.uptimeMillis(); 4466 if (historyName == null) { 4467 historyName = name; 4468 } 4469 if (!mActiveEvents.updateState(HistoryItem.EVENT_LONG_WAKE_LOCK_START, historyName, uid, 4470 0)) { 4471 return; 4472 } 4473 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_LONG_WAKE_LOCK_START, 4474 historyName, uid); 4475 } 4476 noteLongPartialWakelockFinish(String name, String historyName, int uid)4477 public void noteLongPartialWakelockFinish(String name, String historyName, int uid) { 4478 uid = mapUid(uid); 4479 noteLongPartialWakeLockFinishInternal(name, historyName, uid); 4480 } 4481 noteLongPartialWakelockFinishFromSource(String name, String historyName, WorkSource workSource)4482 public void noteLongPartialWakelockFinishFromSource(String name, String historyName, 4483 WorkSource workSource) { 4484 final int N = workSource.size(); 4485 for (int i = 0; i < N; ++i) { 4486 final int uid = mapUid(workSource.get(i)); 4487 noteLongPartialWakeLockFinishInternal(name, historyName, uid); 4488 } 4489 4490 final ArrayList<WorkChain> workChains = workSource.getWorkChains(); 4491 if (workChains != null) { 4492 for (int i = 0; i < workChains.size(); ++i) { 4493 final WorkChain workChain = workChains.get(i); 4494 final int uid = workChain.getAttributionUid(); 4495 noteLongPartialWakeLockFinishInternal(name, historyName, uid); 4496 } 4497 } 4498 } 4499 noteLongPartialWakeLockFinishInternal(String name, String historyName, int uid)4500 private void noteLongPartialWakeLockFinishInternal(String name, String historyName, int uid) { 4501 final long elapsedRealtime = mClocks.elapsedRealtime(); 4502 final long uptime = mClocks.uptimeMillis(); 4503 if (historyName == null) { 4504 historyName = name; 4505 } 4506 if (!mActiveEvents.updateState(HistoryItem.EVENT_LONG_WAKE_LOCK_FINISH, historyName, uid, 4507 0)) { 4508 return; 4509 } 4510 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_LONG_WAKE_LOCK_FINISH, 4511 historyName, uid); 4512 } 4513 aggregateLastWakeupUptimeLocked(long uptimeMs)4514 void aggregateLastWakeupUptimeLocked(long uptimeMs) { 4515 if (mLastWakeupReason != null) { 4516 long deltaUptime = uptimeMs - mLastWakeupUptimeMs; 4517 SamplingTimer timer = getWakeupReasonTimerLocked(mLastWakeupReason); 4518 timer.add(deltaUptime * 1000, 1); // time in in microseconds 4519 StatsLog.write(StatsLog.KERNEL_WAKEUP_REPORTED, mLastWakeupReason, 4520 /* duration_usec */ deltaUptime * 1000); 4521 mLastWakeupReason = null; 4522 } 4523 } 4524 noteWakeupReasonLocked(String reason)4525 public void noteWakeupReasonLocked(String reason) { 4526 final long elapsedRealtime = mClocks.elapsedRealtime(); 4527 final long uptime = mClocks.uptimeMillis(); 4528 if (DEBUG_HISTORY) Slog.v(TAG, "Wakeup reason \"" + reason +"\": " 4529 + Integer.toHexString(mHistoryCur.states)); 4530 aggregateLastWakeupUptimeLocked(uptime); 4531 mHistoryCur.wakeReasonTag = mHistoryCur.localWakeReasonTag; 4532 mHistoryCur.wakeReasonTag.string = reason; 4533 mHistoryCur.wakeReasonTag.uid = 0; 4534 mLastWakeupReason = reason; 4535 mLastWakeupUptimeMs = uptime; 4536 addHistoryRecordLocked(elapsedRealtime, uptime); 4537 } 4538 startAddingCpuLocked()4539 public boolean startAddingCpuLocked() { 4540 mExternalSync.cancelCpuSyncDueToWakelockChange(); 4541 return mOnBatteryInternal; 4542 } 4543 finishAddingCpuLocked(int totalUTime, int totalSTime, int statUserTime, int statSystemTime, int statIOWaitTime, int statIrqTime, int statSoftIrqTime, int statIdleTime)4544 public void finishAddingCpuLocked(int totalUTime, int totalSTime, int statUserTime, 4545 int statSystemTime, int statIOWaitTime, int statIrqTime, 4546 int statSoftIrqTime, int statIdleTime) { 4547 if (DEBUG) Slog.d(TAG, "Adding cpu: tuser=" + totalUTime + " tsys=" + totalSTime 4548 + " user=" + statUserTime + " sys=" + statSystemTime 4549 + " io=" + statIOWaitTime + " irq=" + statIrqTime 4550 + " sirq=" + statSoftIrqTime + " idle=" + statIdleTime); 4551 mCurStepCpuUserTime += totalUTime; 4552 mCurStepCpuSystemTime += totalSTime; 4553 mCurStepStatUserTime += statUserTime; 4554 mCurStepStatSystemTime += statSystemTime; 4555 mCurStepStatIOWaitTime += statIOWaitTime; 4556 mCurStepStatIrqTime += statIrqTime; 4557 mCurStepStatSoftIrqTime += statSoftIrqTime; 4558 mCurStepStatIdleTime += statIdleTime; 4559 } 4560 noteProcessDiedLocked(int uid, int pid)4561 public void noteProcessDiedLocked(int uid, int pid) { 4562 uid = mapUid(uid); 4563 Uid u = mUidStats.get(uid); 4564 if (u != null) { 4565 u.mPids.remove(pid); 4566 } 4567 } 4568 getProcessWakeTime(int uid, int pid, long realtime)4569 public long getProcessWakeTime(int uid, int pid, long realtime) { 4570 uid = mapUid(uid); 4571 Uid u = mUidStats.get(uid); 4572 if (u != null) { 4573 Uid.Pid p = u.mPids.get(pid); 4574 if (p != null) { 4575 return p.mWakeSumMs + (p.mWakeNesting > 0 ? (realtime - p.mWakeStartMs) : 0); 4576 } 4577 } 4578 return 0; 4579 } 4580 reportExcessiveCpuLocked(int uid, String proc, long overTime, long usedTime)4581 public void reportExcessiveCpuLocked(int uid, String proc, long overTime, long usedTime) { 4582 uid = mapUid(uid); 4583 Uid u = mUidStats.get(uid); 4584 if (u != null) { 4585 u.reportExcessiveCpuLocked(proc, overTime, usedTime); 4586 } 4587 } 4588 4589 int mSensorNesting; 4590 noteStartSensorLocked(int uid, int sensor)4591 public void noteStartSensorLocked(int uid, int sensor) { 4592 uid = mapUid(uid); 4593 final long elapsedRealtime = mClocks.elapsedRealtime(); 4594 final long uptime = mClocks.uptimeMillis(); 4595 if (mSensorNesting == 0) { 4596 mHistoryCur.states |= HistoryItem.STATE_SENSOR_ON_FLAG; 4597 if (DEBUG_HISTORY) Slog.v(TAG, "Start sensor to: " 4598 + Integer.toHexString(mHistoryCur.states)); 4599 addHistoryRecordLocked(elapsedRealtime, uptime); 4600 } 4601 mSensorNesting++; 4602 getUidStatsLocked(uid).noteStartSensor(sensor, elapsedRealtime); 4603 } 4604 noteStopSensorLocked(int uid, int sensor)4605 public void noteStopSensorLocked(int uid, int sensor) { 4606 uid = mapUid(uid); 4607 final long elapsedRealtime = mClocks.elapsedRealtime(); 4608 final long uptime = mClocks.uptimeMillis(); 4609 mSensorNesting--; 4610 if (mSensorNesting == 0) { 4611 mHistoryCur.states &= ~HistoryItem.STATE_SENSOR_ON_FLAG; 4612 if (DEBUG_HISTORY) Slog.v(TAG, "Stop sensor to: " 4613 + Integer.toHexString(mHistoryCur.states)); 4614 addHistoryRecordLocked(elapsedRealtime, uptime); 4615 } 4616 getUidStatsLocked(uid).noteStopSensor(sensor, elapsedRealtime); 4617 } 4618 4619 int mGpsNesting; 4620 noteGpsChangedLocked(WorkSource oldWs, WorkSource newWs)4621 public void noteGpsChangedLocked(WorkSource oldWs, WorkSource newWs) { 4622 for (int i = 0; i < newWs.size(); ++i) { 4623 noteStartGpsLocked(newWs.get(i), null); 4624 } 4625 4626 for (int i = 0; i < oldWs.size(); ++i) { 4627 noteStopGpsLocked((oldWs.get(i)), null); 4628 } 4629 4630 List<WorkChain>[] wcs = WorkSource.diffChains(oldWs, newWs); 4631 if (wcs != null) { 4632 if (wcs[0] != null) { 4633 final List<WorkChain> newChains = wcs[0]; 4634 for (int i = 0; i < newChains.size(); ++i) { 4635 noteStartGpsLocked(-1, newChains.get(i)); 4636 } 4637 } 4638 4639 if (wcs[1] != null) { 4640 final List<WorkChain> goneChains = wcs[1]; 4641 for (int i = 0; i < goneChains.size(); ++i) { 4642 noteStopGpsLocked(-1, goneChains.get(i)); 4643 } 4644 } 4645 } 4646 } 4647 noteStartGpsLocked(int uid, WorkChain workChain)4648 private void noteStartGpsLocked(int uid, WorkChain workChain) { 4649 uid = getAttributionUid(uid, workChain); 4650 final long elapsedRealtime = mClocks.elapsedRealtime(); 4651 final long uptime = mClocks.uptimeMillis(); 4652 if (mGpsNesting == 0) { 4653 mHistoryCur.states |= HistoryItem.STATE_GPS_ON_FLAG; 4654 if (DEBUG_HISTORY) Slog.v(TAG, "Start GPS to: " 4655 + Integer.toHexString(mHistoryCur.states)); 4656 addHistoryRecordLocked(elapsedRealtime, uptime); 4657 } 4658 mGpsNesting++; 4659 4660 if (workChain == null) { 4661 StatsLog.write_non_chained(StatsLog.GPS_SCAN_STATE_CHANGED, uid, null, 4662 StatsLog.GPS_SCAN_STATE_CHANGED__STATE__ON); 4663 } else { 4664 StatsLog.write(StatsLog.GPS_SCAN_STATE_CHANGED, 4665 workChain.getUids(), workChain.getTags(), 4666 StatsLog.GPS_SCAN_STATE_CHANGED__STATE__ON); 4667 } 4668 4669 getUidStatsLocked(uid).noteStartGps(elapsedRealtime); 4670 } 4671 noteStopGpsLocked(int uid, WorkChain workChain)4672 private void noteStopGpsLocked(int uid, WorkChain workChain) { 4673 uid = getAttributionUid(uid, workChain); 4674 final long elapsedRealtime = mClocks.elapsedRealtime(); 4675 final long uptime = mClocks.uptimeMillis(); 4676 mGpsNesting--; 4677 if (mGpsNesting == 0) { 4678 mHistoryCur.states &= ~HistoryItem.STATE_GPS_ON_FLAG; 4679 if (DEBUG_HISTORY) Slog.v(TAG, "Stop GPS to: " 4680 + Integer.toHexString(mHistoryCur.states)); 4681 addHistoryRecordLocked(elapsedRealtime, uptime); 4682 stopAllGpsSignalQualityTimersLocked(-1); 4683 mGpsSignalQualityBin = -1; 4684 } 4685 4686 if (workChain == null) { 4687 StatsLog.write_non_chained(StatsLog.GPS_SCAN_STATE_CHANGED, uid, null, 4688 StatsLog.GPS_SCAN_STATE_CHANGED__STATE__OFF); 4689 } else { 4690 StatsLog.write(StatsLog.GPS_SCAN_STATE_CHANGED, workChain.getUids(), 4691 workChain.getTags(), StatsLog.GPS_SCAN_STATE_CHANGED__STATE__OFF); 4692 } 4693 4694 getUidStatsLocked(uid).noteStopGps(elapsedRealtime); 4695 } 4696 noteGpsSignalQualityLocked(int signalLevel)4697 public void noteGpsSignalQualityLocked(int signalLevel) { 4698 if (mGpsNesting == 0) { 4699 return; 4700 } 4701 if (signalLevel < 0 || signalLevel >= GnssMetrics.NUM_GPS_SIGNAL_QUALITY_LEVELS) { 4702 stopAllGpsSignalQualityTimersLocked(-1); 4703 return; 4704 } 4705 final long elapsedRealtime = mClocks.elapsedRealtime(); 4706 final long uptime = mClocks.uptimeMillis(); 4707 if (mGpsSignalQualityBin != signalLevel) { 4708 if (mGpsSignalQualityBin >= 0) { 4709 mGpsSignalQualityTimer[mGpsSignalQualityBin].stopRunningLocked(elapsedRealtime); 4710 } 4711 if(!mGpsSignalQualityTimer[signalLevel].isRunningLocked()) { 4712 mGpsSignalQualityTimer[signalLevel].startRunningLocked(elapsedRealtime); 4713 } 4714 mHistoryCur.states2 = (mHistoryCur.states2&~HistoryItem.STATE2_GPS_SIGNAL_QUALITY_MASK) 4715 | (signalLevel << HistoryItem.STATE2_GPS_SIGNAL_QUALITY_SHIFT); 4716 addHistoryRecordLocked(elapsedRealtime, uptime); 4717 mGpsSignalQualityBin = signalLevel; 4718 } 4719 return; 4720 } 4721 4722 @GuardedBy("this") noteScreenStateLocked(int state)4723 public void noteScreenStateLocked(int state) { 4724 state = mPretendScreenOff ? Display.STATE_OFF : state; 4725 4726 // Battery stats relies on there being 4 states. To accommodate this, new states beyond the 4727 // original 4 are mapped to one of the originals. 4728 if (state > MAX_TRACKED_SCREEN_STATE) { 4729 switch (state) { 4730 case Display.STATE_VR: 4731 state = Display.STATE_ON; 4732 break; 4733 default: 4734 Slog.wtf(TAG, "Unknown screen state (not mapped): " + state); 4735 break; 4736 } 4737 } 4738 4739 if (mScreenState != state) { 4740 recordDailyStatsIfNeededLocked(true); 4741 final int oldState = mScreenState; 4742 mScreenState = state; 4743 if (DEBUG) Slog.v(TAG, "Screen state: oldState=" + Display.stateToString(oldState) 4744 + ", newState=" + Display.stateToString(state)); 4745 4746 if (state != Display.STATE_UNKNOWN) { 4747 int stepState = state-1; 4748 if ((stepState & STEP_LEVEL_MODE_SCREEN_STATE) == stepState) { 4749 mModStepMode |= (mCurStepMode & STEP_LEVEL_MODE_SCREEN_STATE) ^ stepState; 4750 mCurStepMode = (mCurStepMode & ~STEP_LEVEL_MODE_SCREEN_STATE) | stepState; 4751 } else { 4752 Slog.wtf(TAG, "Unexpected screen state: " + state); 4753 } 4754 } 4755 4756 final long elapsedRealtime = mClocks.elapsedRealtime(); 4757 final long uptime = mClocks.uptimeMillis(); 4758 4759 boolean updateHistory = false; 4760 if (isScreenDoze(state) && !isScreenDoze(oldState)) { 4761 mHistoryCur.states |= HistoryItem.STATE_SCREEN_DOZE_FLAG; 4762 mScreenDozeTimer.startRunningLocked(elapsedRealtime); 4763 updateHistory = true; 4764 } else if (isScreenDoze(oldState) && !isScreenDoze(state)) { 4765 mHistoryCur.states &= ~HistoryItem.STATE_SCREEN_DOZE_FLAG; 4766 mScreenDozeTimer.stopRunningLocked(elapsedRealtime); 4767 updateHistory = true; 4768 } 4769 if (isScreenOn(state)) { 4770 mHistoryCur.states |= HistoryItem.STATE_SCREEN_ON_FLAG; 4771 if (DEBUG_HISTORY) Slog.v(TAG, "Screen on to: " 4772 + Integer.toHexString(mHistoryCur.states)); 4773 mScreenOnTimer.startRunningLocked(elapsedRealtime); 4774 if (mScreenBrightnessBin >= 0) { 4775 mScreenBrightnessTimer[mScreenBrightnessBin].startRunningLocked(elapsedRealtime); 4776 } 4777 updateHistory = true; 4778 } else if (isScreenOn(oldState)) { 4779 mHistoryCur.states &= ~HistoryItem.STATE_SCREEN_ON_FLAG; 4780 if (DEBUG_HISTORY) Slog.v(TAG, "Screen off to: " 4781 + Integer.toHexString(mHistoryCur.states)); 4782 mScreenOnTimer.stopRunningLocked(elapsedRealtime); 4783 if (mScreenBrightnessBin >= 0) { 4784 mScreenBrightnessTimer[mScreenBrightnessBin].stopRunningLocked(elapsedRealtime); 4785 } 4786 updateHistory = true; 4787 } 4788 if (updateHistory) { 4789 if (DEBUG_HISTORY) Slog.v(TAG, "Screen state to: " 4790 + Display.stateToString(state)); 4791 addHistoryRecordLocked(elapsedRealtime, uptime); 4792 } 4793 mExternalSync.scheduleCpuSyncDueToScreenStateChange( 4794 mOnBatteryTimeBase.isRunning(), mOnBatteryScreenOffTimeBase.isRunning()); 4795 if (isScreenOn(state)) { 4796 updateTimeBasesLocked(mOnBatteryTimeBase.isRunning(), state, 4797 mClocks.uptimeMillis() * 1000, elapsedRealtime * 1000); 4798 // Fake a wake lock, so we consider the device waked as long as the screen is on. 4799 noteStartWakeLocked(-1, -1, null, "screen", null, WAKE_TYPE_PARTIAL, false, 4800 elapsedRealtime, uptime); 4801 } else if (isScreenOn(oldState)) { 4802 noteStopWakeLocked(-1, -1, null, "screen", "screen", WAKE_TYPE_PARTIAL, 4803 elapsedRealtime, uptime); 4804 updateTimeBasesLocked(mOnBatteryTimeBase.isRunning(), state, 4805 mClocks.uptimeMillis() * 1000, elapsedRealtime * 1000); 4806 } 4807 // Update discharge amounts. 4808 if (mOnBatteryInternal) { 4809 updateDischargeScreenLevelsLocked(oldState, state); 4810 } 4811 } 4812 } 4813 4814 @UnsupportedAppUsage noteScreenBrightnessLocked(int brightness)4815 public void noteScreenBrightnessLocked(int brightness) { 4816 // Bin the brightness. 4817 int bin = brightness / (256/NUM_SCREEN_BRIGHTNESS_BINS); 4818 if (bin < 0) bin = 0; 4819 else if (bin >= NUM_SCREEN_BRIGHTNESS_BINS) bin = NUM_SCREEN_BRIGHTNESS_BINS-1; 4820 if (mScreenBrightnessBin != bin) { 4821 final long elapsedRealtime = mClocks.elapsedRealtime(); 4822 final long uptime = mClocks.uptimeMillis(); 4823 mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_BRIGHTNESS_MASK) 4824 | (bin << HistoryItem.STATE_BRIGHTNESS_SHIFT); 4825 if (DEBUG_HISTORY) Slog.v(TAG, "Screen brightness " + bin + " to: " 4826 + Integer.toHexString(mHistoryCur.states)); 4827 addHistoryRecordLocked(elapsedRealtime, uptime); 4828 if (mScreenState == Display.STATE_ON) { 4829 if (mScreenBrightnessBin >= 0) { 4830 mScreenBrightnessTimer[mScreenBrightnessBin].stopRunningLocked(elapsedRealtime); 4831 } 4832 mScreenBrightnessTimer[bin].startRunningLocked(elapsedRealtime); 4833 } 4834 mScreenBrightnessBin = bin; 4835 } 4836 } 4837 4838 @UnsupportedAppUsage noteUserActivityLocked(int uid, int event)4839 public void noteUserActivityLocked(int uid, int event) { 4840 if (mOnBatteryInternal) { 4841 uid = mapUid(uid); 4842 getUidStatsLocked(uid).noteUserActivityLocked(event); 4843 } 4844 } 4845 noteWakeUpLocked(String reason, int reasonUid)4846 public void noteWakeUpLocked(String reason, int reasonUid) { 4847 final long elapsedRealtime = mClocks.elapsedRealtime(); 4848 final long uptime = mClocks.uptimeMillis(); 4849 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_SCREEN_WAKE_UP, 4850 reason, reasonUid); 4851 } 4852 noteInteractiveLocked(boolean interactive)4853 public void noteInteractiveLocked(boolean interactive) { 4854 if (mInteractive != interactive) { 4855 final long elapsedRealtime = mClocks.elapsedRealtime(); 4856 mInteractive = interactive; 4857 if (DEBUG) Slog.v(TAG, "Interactive: " + interactive); 4858 if (interactive) { 4859 mInteractiveTimer.startRunningLocked(elapsedRealtime); 4860 } else { 4861 mInteractiveTimer.stopRunningLocked(elapsedRealtime); 4862 } 4863 } 4864 } 4865 noteConnectivityChangedLocked(int type, String extra)4866 public void noteConnectivityChangedLocked(int type, String extra) { 4867 final long elapsedRealtime = mClocks.elapsedRealtime(); 4868 final long uptime = mClocks.uptimeMillis(); 4869 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_CONNECTIVITY_CHANGED, 4870 extra, type); 4871 mNumConnectivityChange++; 4872 } 4873 noteMobileRadioApWakeupLocked(final long elapsedRealtimeMillis, final long uptimeMillis, int uid)4874 private void noteMobileRadioApWakeupLocked(final long elapsedRealtimeMillis, 4875 final long uptimeMillis, int uid) { 4876 uid = mapUid(uid); 4877 addHistoryEventLocked(elapsedRealtimeMillis, uptimeMillis, HistoryItem.EVENT_WAKEUP_AP, "", 4878 uid); 4879 getUidStatsLocked(uid).noteMobileRadioApWakeupLocked(); 4880 } 4881 4882 /** 4883 * Updates the radio power state and returns true if an external stats collection should occur. 4884 */ noteMobileRadioPowerStateLocked(int powerState, long timestampNs, int uid)4885 public boolean noteMobileRadioPowerStateLocked(int powerState, long timestampNs, int uid) { 4886 final long elapsedRealtime = mClocks.elapsedRealtime(); 4887 final long uptime = mClocks.uptimeMillis(); 4888 if (mMobileRadioPowerState != powerState) { 4889 long realElapsedRealtimeMs; 4890 final boolean active = 4891 powerState == DataConnectionRealTimeInfo.DC_POWER_STATE_MEDIUM 4892 || powerState == DataConnectionRealTimeInfo.DC_POWER_STATE_HIGH; 4893 if (active) { 4894 if (uid > 0) { 4895 noteMobileRadioApWakeupLocked(elapsedRealtime, uptime, uid); 4896 } 4897 4898 mMobileRadioActiveStartTime = realElapsedRealtimeMs = timestampNs / (1000 * 1000); 4899 mHistoryCur.states |= HistoryItem.STATE_MOBILE_RADIO_ACTIVE_FLAG; 4900 } else { 4901 realElapsedRealtimeMs = timestampNs / (1000*1000); 4902 long lastUpdateTimeMs = mMobileRadioActiveStartTime; 4903 if (realElapsedRealtimeMs < lastUpdateTimeMs) { 4904 Slog.wtf(TAG, "Data connection inactive timestamp " + realElapsedRealtimeMs 4905 + " is before start time " + lastUpdateTimeMs); 4906 realElapsedRealtimeMs = elapsedRealtime; 4907 } else if (realElapsedRealtimeMs < elapsedRealtime) { 4908 mMobileRadioActiveAdjustedTime.addCountLocked(elapsedRealtime 4909 - realElapsedRealtimeMs); 4910 } 4911 mHistoryCur.states &= ~HistoryItem.STATE_MOBILE_RADIO_ACTIVE_FLAG; 4912 } 4913 if (DEBUG_HISTORY) Slog.v(TAG, "Mobile network active " + active + " to: " 4914 + Integer.toHexString(mHistoryCur.states)); 4915 addHistoryRecordLocked(elapsedRealtime, uptime); 4916 mMobileRadioPowerState = powerState; 4917 if (active) { 4918 mMobileRadioActiveTimer.startRunningLocked(elapsedRealtime); 4919 mMobileRadioActivePerAppTimer.startRunningLocked(elapsedRealtime); 4920 } else { 4921 mMobileRadioActiveTimer.stopRunningLocked(realElapsedRealtimeMs); 4922 mMobileRadioActivePerAppTimer.stopRunningLocked(realElapsedRealtimeMs); 4923 // Tell the caller to collect radio network/power stats. 4924 return true; 4925 } 4926 } 4927 return false; 4928 } 4929 notePowerSaveModeLocked(boolean enabled)4930 public void notePowerSaveModeLocked(boolean enabled) { 4931 if (mPowerSaveModeEnabled != enabled) { 4932 int stepState = enabled ? STEP_LEVEL_MODE_POWER_SAVE : 0; 4933 mModStepMode |= (mCurStepMode&STEP_LEVEL_MODE_POWER_SAVE) ^ stepState; 4934 mCurStepMode = (mCurStepMode&~STEP_LEVEL_MODE_POWER_SAVE) | stepState; 4935 final long elapsedRealtime = mClocks.elapsedRealtime(); 4936 final long uptime = mClocks.uptimeMillis(); 4937 mPowerSaveModeEnabled = enabled; 4938 if (enabled) { 4939 mHistoryCur.states2 |= HistoryItem.STATE2_POWER_SAVE_FLAG; 4940 if (DEBUG_HISTORY) Slog.v(TAG, "Power save mode enabled to: " 4941 + Integer.toHexString(mHistoryCur.states2)); 4942 mPowerSaveModeEnabledTimer.startRunningLocked(elapsedRealtime); 4943 } else { 4944 mHistoryCur.states2 &= ~HistoryItem.STATE2_POWER_SAVE_FLAG; 4945 if (DEBUG_HISTORY) Slog.v(TAG, "Power save mode disabled to: " 4946 + Integer.toHexString(mHistoryCur.states2)); 4947 mPowerSaveModeEnabledTimer.stopRunningLocked(elapsedRealtime); 4948 } 4949 addHistoryRecordLocked(elapsedRealtime, uptime); 4950 StatsLog.write(StatsLog.BATTERY_SAVER_MODE_STATE_CHANGED, enabled ? 4951 StatsLog.BATTERY_SAVER_MODE_STATE_CHANGED__STATE__ON : 4952 StatsLog.BATTERY_SAVER_MODE_STATE_CHANGED__STATE__OFF); 4953 } 4954 } 4955 noteDeviceIdleModeLocked(final int mode, String activeReason, int activeUid)4956 public void noteDeviceIdleModeLocked(final int mode, String activeReason, int activeUid) { 4957 final long elapsedRealtime = mClocks.elapsedRealtime(); 4958 final long uptime = mClocks.uptimeMillis(); 4959 boolean nowIdling = mode == DEVICE_IDLE_MODE_DEEP; 4960 if (mDeviceIdling && !nowIdling && activeReason == null) { 4961 // We don't go out of general idling mode until explicitly taken out of 4962 // device idle through going active or significant motion. 4963 nowIdling = true; 4964 } 4965 boolean nowLightIdling = mode == DEVICE_IDLE_MODE_LIGHT; 4966 if (mDeviceLightIdling && !nowLightIdling && !nowIdling && activeReason == null) { 4967 // We don't go out of general light idling mode until explicitly taken out of 4968 // device idle through going active or significant motion. 4969 nowLightIdling = true; 4970 } 4971 if (activeReason != null && (mDeviceIdling || mDeviceLightIdling)) { 4972 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_ACTIVE, 4973 activeReason, activeUid); 4974 } 4975 if (mDeviceIdling != nowIdling || mDeviceLightIdling != nowLightIdling) { 4976 int statsmode; 4977 if (nowIdling) statsmode = DEVICE_IDLE_MODE_DEEP; 4978 else if (nowLightIdling) statsmode = DEVICE_IDLE_MODE_LIGHT; 4979 else statsmode = DEVICE_IDLE_MODE_OFF; 4980 StatsLog.write(StatsLog.DEVICE_IDLING_MODE_STATE_CHANGED, statsmode); 4981 } 4982 if (mDeviceIdling != nowIdling) { 4983 mDeviceIdling = nowIdling; 4984 int stepState = nowIdling ? STEP_LEVEL_MODE_DEVICE_IDLE : 0; 4985 mModStepMode |= (mCurStepMode&STEP_LEVEL_MODE_DEVICE_IDLE) ^ stepState; 4986 mCurStepMode = (mCurStepMode&~STEP_LEVEL_MODE_DEVICE_IDLE) | stepState; 4987 if (nowIdling) { 4988 mDeviceIdlingTimer.startRunningLocked(elapsedRealtime); 4989 } else { 4990 mDeviceIdlingTimer.stopRunningLocked(elapsedRealtime); 4991 } 4992 } 4993 if (mDeviceLightIdling != nowLightIdling) { 4994 mDeviceLightIdling = nowLightIdling; 4995 if (nowLightIdling) { 4996 mDeviceLightIdlingTimer.startRunningLocked(elapsedRealtime); 4997 } else { 4998 mDeviceLightIdlingTimer.stopRunningLocked(elapsedRealtime); 4999 } 5000 } 5001 if (mDeviceIdleMode != mode) { 5002 mHistoryCur.states2 = (mHistoryCur.states2 & ~HistoryItem.STATE2_DEVICE_IDLE_MASK) 5003 | (mode << HistoryItem.STATE2_DEVICE_IDLE_SHIFT); 5004 if (DEBUG_HISTORY) Slog.v(TAG, "Device idle mode changed to: " 5005 + Integer.toHexString(mHistoryCur.states2)); 5006 addHistoryRecordLocked(elapsedRealtime, uptime); 5007 long lastDuration = elapsedRealtime - mLastIdleTimeStart; 5008 mLastIdleTimeStart = elapsedRealtime; 5009 if (mDeviceIdleMode == DEVICE_IDLE_MODE_LIGHT) { 5010 if (lastDuration > mLongestLightIdleTime) { 5011 mLongestLightIdleTime = lastDuration; 5012 } 5013 mDeviceIdleModeLightTimer.stopRunningLocked(elapsedRealtime); 5014 } else if (mDeviceIdleMode == DEVICE_IDLE_MODE_DEEP) { 5015 if (lastDuration > mLongestFullIdleTime) { 5016 mLongestFullIdleTime = lastDuration; 5017 } 5018 mDeviceIdleModeFullTimer.stopRunningLocked(elapsedRealtime); 5019 } 5020 if (mode == DEVICE_IDLE_MODE_LIGHT) { 5021 mDeviceIdleModeLightTimer.startRunningLocked(elapsedRealtime); 5022 } else if (mode == DEVICE_IDLE_MODE_DEEP) { 5023 mDeviceIdleModeFullTimer.startRunningLocked(elapsedRealtime); 5024 } 5025 mDeviceIdleMode = mode; 5026 StatsLog.write(StatsLog.DEVICE_IDLE_MODE_STATE_CHANGED, mode); 5027 } 5028 } 5029 notePackageInstalledLocked(String pkgName, long versionCode)5030 public void notePackageInstalledLocked(String pkgName, long versionCode) { 5031 final long elapsedRealtime = mClocks.elapsedRealtime(); 5032 final long uptime = mClocks.uptimeMillis(); 5033 // XXX need to figure out what to do with long version codes. 5034 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_PACKAGE_INSTALLED, 5035 pkgName, (int)versionCode); 5036 PackageChange pc = new PackageChange(); 5037 pc.mPackageName = pkgName; 5038 pc.mUpdate = true; 5039 pc.mVersionCode = versionCode; 5040 addPackageChange(pc); 5041 } 5042 notePackageUninstalledLocked(String pkgName)5043 public void notePackageUninstalledLocked(String pkgName) { 5044 final long elapsedRealtime = mClocks.elapsedRealtime(); 5045 final long uptime = mClocks.uptimeMillis(); 5046 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_PACKAGE_UNINSTALLED, 5047 pkgName, 0); 5048 PackageChange pc = new PackageChange(); 5049 pc.mPackageName = pkgName; 5050 pc.mUpdate = true; 5051 addPackageChange(pc); 5052 } 5053 addPackageChange(PackageChange pc)5054 private void addPackageChange(PackageChange pc) { 5055 if (mDailyPackageChanges == null) { 5056 mDailyPackageChanges = new ArrayList<>(); 5057 } 5058 mDailyPackageChanges.add(pc); 5059 } 5060 stopAllGpsSignalQualityTimersLocked(int except)5061 void stopAllGpsSignalQualityTimersLocked(int except) { 5062 final long elapsedRealtime = mClocks.elapsedRealtime(); 5063 for (int i = 0; i < GnssMetrics.NUM_GPS_SIGNAL_QUALITY_LEVELS; i++) { 5064 if (i == except) { 5065 continue; 5066 } 5067 while (mGpsSignalQualityTimer[i].isRunningLocked()) { 5068 mGpsSignalQualityTimer[i].stopRunningLocked(elapsedRealtime); 5069 } 5070 } 5071 } 5072 5073 @UnsupportedAppUsage notePhoneOnLocked()5074 public void notePhoneOnLocked() { 5075 if (!mPhoneOn) { 5076 final long elapsedRealtime = mClocks.elapsedRealtime(); 5077 final long uptime = mClocks.uptimeMillis(); 5078 mHistoryCur.states2 |= HistoryItem.STATE2_PHONE_IN_CALL_FLAG; 5079 if (DEBUG_HISTORY) Slog.v(TAG, "Phone on to: " 5080 + Integer.toHexString(mHistoryCur.states)); 5081 addHistoryRecordLocked(elapsedRealtime, uptime); 5082 mPhoneOn = true; 5083 mPhoneOnTimer.startRunningLocked(elapsedRealtime); 5084 } 5085 } 5086 5087 @UnsupportedAppUsage notePhoneOffLocked()5088 public void notePhoneOffLocked() { 5089 if (mPhoneOn) { 5090 final long elapsedRealtime = mClocks.elapsedRealtime(); 5091 final long uptime = mClocks.uptimeMillis(); 5092 mHistoryCur.states2 &= ~HistoryItem.STATE2_PHONE_IN_CALL_FLAG; 5093 if (DEBUG_HISTORY) Slog.v(TAG, "Phone off to: " 5094 + Integer.toHexString(mHistoryCur.states)); 5095 addHistoryRecordLocked(elapsedRealtime, uptime); 5096 mPhoneOn = false; 5097 mPhoneOnTimer.stopRunningLocked(elapsedRealtime); 5098 } 5099 } 5100 registerUsbStateReceiver(Context context)5101 private void registerUsbStateReceiver(Context context) { 5102 final IntentFilter usbStateFilter = new IntentFilter(); 5103 usbStateFilter.addAction(UsbManager.ACTION_USB_STATE); 5104 context.registerReceiver(new BroadcastReceiver() { 5105 @Override 5106 public void onReceive(Context context, Intent intent) { 5107 final boolean state = intent.getBooleanExtra(UsbManager.USB_CONNECTED, false); 5108 synchronized (BatteryStatsImpl.this) { 5109 noteUsbConnectionStateLocked(state); 5110 } 5111 } 5112 }, usbStateFilter); 5113 synchronized (this) { 5114 if (mUsbDataState == USB_DATA_UNKNOWN) { 5115 final Intent usbState = context.registerReceiver(null, usbStateFilter); 5116 final boolean initState = usbState != null && usbState.getBooleanExtra( 5117 UsbManager.USB_CONNECTED, false); 5118 noteUsbConnectionStateLocked(initState); 5119 } 5120 } 5121 } 5122 noteUsbConnectionStateLocked(boolean connected)5123 private void noteUsbConnectionStateLocked(boolean connected) { 5124 int newState = connected ? USB_DATA_CONNECTED : USB_DATA_DISCONNECTED; 5125 if (mUsbDataState != newState) { 5126 mUsbDataState = newState; 5127 if (connected) { 5128 mHistoryCur.states2 |= HistoryItem.STATE2_USB_DATA_LINK_FLAG; 5129 } else { 5130 mHistoryCur.states2 &= ~HistoryItem.STATE2_USB_DATA_LINK_FLAG; 5131 } 5132 addHistoryRecordLocked(mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 5133 } 5134 } 5135 stopAllPhoneSignalStrengthTimersLocked(int except)5136 void stopAllPhoneSignalStrengthTimersLocked(int except) { 5137 final long elapsedRealtime = mClocks.elapsedRealtime(); 5138 for (int i = 0; i < CellSignalStrength.getNumSignalStrengthLevels(); i++) { 5139 if (i == except) { 5140 continue; 5141 } 5142 while (mPhoneSignalStrengthsTimer[i].isRunningLocked()) { 5143 mPhoneSignalStrengthsTimer[i].stopRunningLocked(elapsedRealtime); 5144 } 5145 } 5146 } 5147 fixPhoneServiceState(int state, int signalBin)5148 private int fixPhoneServiceState(int state, int signalBin) { 5149 if (mPhoneSimStateRaw == TelephonyManager.SIM_STATE_ABSENT) { 5150 // In this case we will always be STATE_OUT_OF_SERVICE, so need 5151 // to infer that we are scanning from other data. 5152 if (state == ServiceState.STATE_OUT_OF_SERVICE 5153 && signalBin > CellSignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN) { 5154 state = ServiceState.STATE_IN_SERVICE; 5155 } 5156 } 5157 5158 return state; 5159 } 5160 updateAllPhoneStateLocked(int state, int simState, int strengthBin)5161 private void updateAllPhoneStateLocked(int state, int simState, int strengthBin) { 5162 boolean scanning = false; 5163 boolean newHistory = false; 5164 5165 mPhoneServiceStateRaw = state; 5166 mPhoneSimStateRaw = simState; 5167 mPhoneSignalStrengthBinRaw = strengthBin; 5168 5169 final long elapsedRealtime = mClocks.elapsedRealtime(); 5170 final long uptime = mClocks.uptimeMillis(); 5171 5172 if (simState == TelephonyManager.SIM_STATE_ABSENT) { 5173 // In this case we will always be STATE_OUT_OF_SERVICE, so need 5174 // to infer that we are scanning from other data. 5175 if (state == ServiceState.STATE_OUT_OF_SERVICE 5176 && strengthBin > CellSignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN) { 5177 state = ServiceState.STATE_IN_SERVICE; 5178 } 5179 } 5180 5181 // If the phone is powered off, stop all timers. 5182 if (state == ServiceState.STATE_POWER_OFF) { 5183 strengthBin = -1; 5184 5185 // If we are in service, make sure the correct signal string timer is running. 5186 } else if (state == ServiceState.STATE_IN_SERVICE) { 5187 // Bin will be changed below. 5188 5189 // If we're out of service, we are in the lowest signal strength 5190 // bin and have the scanning bit set. 5191 } else if (state == ServiceState.STATE_OUT_OF_SERVICE) { 5192 scanning = true; 5193 strengthBin = CellSignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN; 5194 if (!mPhoneSignalScanningTimer.isRunningLocked()) { 5195 mHistoryCur.states |= HistoryItem.STATE_PHONE_SCANNING_FLAG; 5196 newHistory = true; 5197 if (DEBUG_HISTORY) Slog.v(TAG, "Phone started scanning to: " 5198 + Integer.toHexString(mHistoryCur.states)); 5199 mPhoneSignalScanningTimer.startRunningLocked(elapsedRealtime); 5200 StatsLog.write(StatsLog.PHONE_SERVICE_STATE_CHANGED, state, simState, strengthBin); 5201 } 5202 } 5203 5204 if (!scanning) { 5205 // If we are no longer scanning, then stop the scanning timer. 5206 if (mPhoneSignalScanningTimer.isRunningLocked()) { 5207 mHistoryCur.states &= ~HistoryItem.STATE_PHONE_SCANNING_FLAG; 5208 if (DEBUG_HISTORY) Slog.v(TAG, "Phone stopped scanning to: " 5209 + Integer.toHexString(mHistoryCur.states)); 5210 newHistory = true; 5211 mPhoneSignalScanningTimer.stopRunningLocked(elapsedRealtime); 5212 StatsLog.write(StatsLog.PHONE_SERVICE_STATE_CHANGED, state, simState, strengthBin); 5213 } 5214 } 5215 5216 if (mPhoneServiceState != state) { 5217 mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_PHONE_STATE_MASK) 5218 | (state << HistoryItem.STATE_PHONE_STATE_SHIFT); 5219 if (DEBUG_HISTORY) Slog.v(TAG, "Phone state " + state + " to: " 5220 + Integer.toHexString(mHistoryCur.states)); 5221 newHistory = true; 5222 mPhoneServiceState = state; 5223 } 5224 5225 if (mPhoneSignalStrengthBin != strengthBin) { 5226 if (mPhoneSignalStrengthBin >= 0) { 5227 mPhoneSignalStrengthsTimer[mPhoneSignalStrengthBin].stopRunningLocked( 5228 elapsedRealtime); 5229 } 5230 if (strengthBin >= 0) { 5231 if (!mPhoneSignalStrengthsTimer[strengthBin].isRunningLocked()) { 5232 mPhoneSignalStrengthsTimer[strengthBin].startRunningLocked(elapsedRealtime); 5233 } 5234 mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_PHONE_SIGNAL_STRENGTH_MASK) 5235 | (strengthBin << HistoryItem.STATE_PHONE_SIGNAL_STRENGTH_SHIFT); 5236 if (DEBUG_HISTORY) Slog.v(TAG, "Signal strength " + strengthBin + " to: " 5237 + Integer.toHexString(mHistoryCur.states)); 5238 newHistory = true; 5239 StatsLog.write(StatsLog.PHONE_SIGNAL_STRENGTH_CHANGED, strengthBin); 5240 } else { 5241 stopAllPhoneSignalStrengthTimersLocked(-1); 5242 } 5243 mPhoneSignalStrengthBin = strengthBin; 5244 } 5245 5246 if (newHistory) { 5247 addHistoryRecordLocked(elapsedRealtime, uptime); 5248 } 5249 } 5250 5251 /** 5252 * Telephony stack updates the phone state. 5253 * @param state phone state from ServiceState.getState() 5254 */ notePhoneStateLocked(int state, int simState)5255 public void notePhoneStateLocked(int state, int simState) { 5256 updateAllPhoneStateLocked(state, simState, mPhoneSignalStrengthBinRaw); 5257 } 5258 5259 @UnsupportedAppUsage notePhoneSignalStrengthLocked(SignalStrength signalStrength)5260 public void notePhoneSignalStrengthLocked(SignalStrength signalStrength) { 5261 // Bin the strength. 5262 int bin = signalStrength.getLevel(); 5263 updateAllPhoneStateLocked(mPhoneServiceStateRaw, mPhoneSimStateRaw, bin); 5264 } 5265 5266 @UnsupportedAppUsage notePhoneDataConnectionStateLocked(int dataType, boolean hasData, int serviceType)5267 public void notePhoneDataConnectionStateLocked(int dataType, boolean hasData, int serviceType) { 5268 // BatteryStats uses 0 to represent no network type. 5269 // Telephony does not have a concept of no network type, and uses 0 to represent unknown. 5270 // Unknown is included in DATA_CONNECTION_OTHER. 5271 int bin = DATA_CONNECTION_OUT_OF_SERVICE; 5272 if (hasData) { 5273 if (dataType > 0 && dataType <= TelephonyManager.getAllNetworkTypes().length) { 5274 bin = dataType; 5275 } else { 5276 switch (serviceType) { 5277 case ServiceState.STATE_OUT_OF_SERVICE: 5278 bin = DATA_CONNECTION_OUT_OF_SERVICE; 5279 break; 5280 case ServiceState.STATE_EMERGENCY_ONLY: 5281 bin = DATA_CONNECTION_EMERGENCY_SERVICE; 5282 break; 5283 default: 5284 bin = DATA_CONNECTION_OTHER; 5285 break; 5286 } 5287 } 5288 } 5289 if (DEBUG) Log.i(TAG, "Phone Data Connection -> " + dataType + " = " + hasData); 5290 if (mPhoneDataConnectionType != bin) { 5291 final long elapsedRealtime = mClocks.elapsedRealtime(); 5292 final long uptime = mClocks.uptimeMillis(); 5293 mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_DATA_CONNECTION_MASK) 5294 | (bin << HistoryItem.STATE_DATA_CONNECTION_SHIFT); 5295 if (DEBUG_HISTORY) Slog.v(TAG, "Data connection " + bin + " to: " 5296 + Integer.toHexString(mHistoryCur.states)); 5297 addHistoryRecordLocked(elapsedRealtime, uptime); 5298 if (mPhoneDataConnectionType >= 0) { 5299 mPhoneDataConnectionsTimer[mPhoneDataConnectionType].stopRunningLocked( 5300 elapsedRealtime); 5301 } 5302 mPhoneDataConnectionType = bin; 5303 mPhoneDataConnectionsTimer[bin].startRunningLocked(elapsedRealtime); 5304 } 5305 } 5306 noteWifiOnLocked()5307 public void noteWifiOnLocked() { 5308 if (!mWifiOn) { 5309 final long elapsedRealtime = mClocks.elapsedRealtime(); 5310 final long uptime = mClocks.uptimeMillis(); 5311 mHistoryCur.states2 |= HistoryItem.STATE2_WIFI_ON_FLAG; 5312 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI on to: " 5313 + Integer.toHexString(mHistoryCur.states)); 5314 addHistoryRecordLocked(elapsedRealtime, uptime); 5315 mWifiOn = true; 5316 mWifiOnTimer.startRunningLocked(elapsedRealtime); 5317 scheduleSyncExternalStatsLocked("wifi-off", ExternalStatsSync.UPDATE_WIFI); 5318 } 5319 } 5320 noteWifiOffLocked()5321 public void noteWifiOffLocked() { 5322 final long elapsedRealtime = mClocks.elapsedRealtime(); 5323 final long uptime = mClocks.uptimeMillis(); 5324 if (mWifiOn) { 5325 mHistoryCur.states2 &= ~HistoryItem.STATE2_WIFI_ON_FLAG; 5326 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI off to: " 5327 + Integer.toHexString(mHistoryCur.states)); 5328 addHistoryRecordLocked(elapsedRealtime, uptime); 5329 mWifiOn = false; 5330 mWifiOnTimer.stopRunningLocked(elapsedRealtime); 5331 scheduleSyncExternalStatsLocked("wifi-on", ExternalStatsSync.UPDATE_WIFI); 5332 } 5333 } 5334 5335 @UnsupportedAppUsage noteAudioOnLocked(int uid)5336 public void noteAudioOnLocked(int uid) { 5337 uid = mapUid(uid); 5338 final long elapsedRealtime = mClocks.elapsedRealtime(); 5339 final long uptime = mClocks.uptimeMillis(); 5340 if (mAudioOnNesting == 0) { 5341 mHistoryCur.states |= HistoryItem.STATE_AUDIO_ON_FLAG; 5342 if (DEBUG_HISTORY) Slog.v(TAG, "Audio on to: " 5343 + Integer.toHexString(mHistoryCur.states)); 5344 addHistoryRecordLocked(elapsedRealtime, uptime); 5345 mAudioOnTimer.startRunningLocked(elapsedRealtime); 5346 } 5347 mAudioOnNesting++; 5348 getUidStatsLocked(uid).noteAudioTurnedOnLocked(elapsedRealtime); 5349 } 5350 5351 @UnsupportedAppUsage noteAudioOffLocked(int uid)5352 public void noteAudioOffLocked(int uid) { 5353 if (mAudioOnNesting == 0) { 5354 return; 5355 } 5356 uid = mapUid(uid); 5357 final long elapsedRealtime = mClocks.elapsedRealtime(); 5358 final long uptime = mClocks.uptimeMillis(); 5359 if (--mAudioOnNesting == 0) { 5360 mHistoryCur.states &= ~HistoryItem.STATE_AUDIO_ON_FLAG; 5361 if (DEBUG_HISTORY) Slog.v(TAG, "Audio off to: " 5362 + Integer.toHexString(mHistoryCur.states)); 5363 addHistoryRecordLocked(elapsedRealtime, uptime); 5364 mAudioOnTimer.stopRunningLocked(elapsedRealtime); 5365 } 5366 getUidStatsLocked(uid).noteAudioTurnedOffLocked(elapsedRealtime); 5367 } 5368 5369 @UnsupportedAppUsage noteVideoOnLocked(int uid)5370 public void noteVideoOnLocked(int uid) { 5371 uid = mapUid(uid); 5372 final long elapsedRealtime = mClocks.elapsedRealtime(); 5373 final long uptime = mClocks.uptimeMillis(); 5374 if (mVideoOnNesting == 0) { 5375 mHistoryCur.states2 |= HistoryItem.STATE2_VIDEO_ON_FLAG; 5376 if (DEBUG_HISTORY) Slog.v(TAG, "Video on to: " 5377 + Integer.toHexString(mHistoryCur.states)); 5378 addHistoryRecordLocked(elapsedRealtime, uptime); 5379 mVideoOnTimer.startRunningLocked(elapsedRealtime); 5380 } 5381 mVideoOnNesting++; 5382 getUidStatsLocked(uid).noteVideoTurnedOnLocked(elapsedRealtime); 5383 } 5384 5385 @UnsupportedAppUsage noteVideoOffLocked(int uid)5386 public void noteVideoOffLocked(int uid) { 5387 if (mVideoOnNesting == 0) { 5388 return; 5389 } 5390 uid = mapUid(uid); 5391 final long elapsedRealtime = mClocks.elapsedRealtime(); 5392 final long uptime = mClocks.uptimeMillis(); 5393 if (--mVideoOnNesting == 0) { 5394 mHistoryCur.states2 &= ~HistoryItem.STATE2_VIDEO_ON_FLAG; 5395 if (DEBUG_HISTORY) Slog.v(TAG, "Video off to: " 5396 + Integer.toHexString(mHistoryCur.states)); 5397 addHistoryRecordLocked(elapsedRealtime, uptime); 5398 mVideoOnTimer.stopRunningLocked(elapsedRealtime); 5399 } 5400 getUidStatsLocked(uid).noteVideoTurnedOffLocked(elapsedRealtime); 5401 } 5402 noteResetAudioLocked()5403 public void noteResetAudioLocked() { 5404 if (mAudioOnNesting > 0) { 5405 final long elapsedRealtime = mClocks.elapsedRealtime(); 5406 final long uptime = mClocks.uptimeMillis(); 5407 mAudioOnNesting = 0; 5408 mHistoryCur.states &= ~HistoryItem.STATE_AUDIO_ON_FLAG; 5409 if (DEBUG_HISTORY) Slog.v(TAG, "Audio off to: " 5410 + Integer.toHexString(mHistoryCur.states)); 5411 addHistoryRecordLocked(elapsedRealtime, uptime); 5412 mAudioOnTimer.stopAllRunningLocked(elapsedRealtime); 5413 for (int i=0; i<mUidStats.size(); i++) { 5414 BatteryStatsImpl.Uid uid = mUidStats.valueAt(i); 5415 uid.noteResetAudioLocked(elapsedRealtime); 5416 } 5417 } 5418 } 5419 noteResetVideoLocked()5420 public void noteResetVideoLocked() { 5421 if (mVideoOnNesting > 0) { 5422 final long elapsedRealtime = mClocks.elapsedRealtime(); 5423 final long uptime = mClocks.uptimeMillis(); 5424 mVideoOnNesting = 0; 5425 mHistoryCur.states2 &= ~HistoryItem.STATE2_VIDEO_ON_FLAG; 5426 if (DEBUG_HISTORY) Slog.v(TAG, "Video off to: " 5427 + Integer.toHexString(mHistoryCur.states)); 5428 addHistoryRecordLocked(elapsedRealtime, uptime); 5429 mVideoOnTimer.stopAllRunningLocked(elapsedRealtime); 5430 for (int i=0; i<mUidStats.size(); i++) { 5431 BatteryStatsImpl.Uid uid = mUidStats.valueAt(i); 5432 uid.noteResetVideoLocked(elapsedRealtime); 5433 } 5434 } 5435 } 5436 noteActivityResumedLocked(int uid)5437 public void noteActivityResumedLocked(int uid) { 5438 uid = mapUid(uid); 5439 getUidStatsLocked(uid).noteActivityResumedLocked(mClocks.elapsedRealtime()); 5440 } 5441 noteActivityPausedLocked(int uid)5442 public void noteActivityPausedLocked(int uid) { 5443 uid = mapUid(uid); 5444 getUidStatsLocked(uid).noteActivityPausedLocked(mClocks.elapsedRealtime()); 5445 } 5446 noteVibratorOnLocked(int uid, long durationMillis)5447 public void noteVibratorOnLocked(int uid, long durationMillis) { 5448 uid = mapUid(uid); 5449 getUidStatsLocked(uid).noteVibratorOnLocked(durationMillis); 5450 } 5451 noteVibratorOffLocked(int uid)5452 public void noteVibratorOffLocked(int uid) { 5453 uid = mapUid(uid); 5454 getUidStatsLocked(uid).noteVibratorOffLocked(); 5455 } 5456 noteFlashlightOnLocked(int uid)5457 public void noteFlashlightOnLocked(int uid) { 5458 uid = mapUid(uid); 5459 final long elapsedRealtime = mClocks.elapsedRealtime(); 5460 final long uptime = mClocks.uptimeMillis(); 5461 if (mFlashlightOnNesting++ == 0) { 5462 mHistoryCur.states2 |= HistoryItem.STATE2_FLASHLIGHT_FLAG; 5463 if (DEBUG_HISTORY) Slog.v(TAG, "Flashlight on to: " 5464 + Integer.toHexString(mHistoryCur.states2)); 5465 addHistoryRecordLocked(elapsedRealtime, uptime); 5466 mFlashlightOnTimer.startRunningLocked(elapsedRealtime); 5467 } 5468 getUidStatsLocked(uid).noteFlashlightTurnedOnLocked(elapsedRealtime); 5469 } 5470 noteFlashlightOffLocked(int uid)5471 public void noteFlashlightOffLocked(int uid) { 5472 if (mFlashlightOnNesting == 0) { 5473 return; 5474 } 5475 uid = mapUid(uid); 5476 final long elapsedRealtime = mClocks.elapsedRealtime(); 5477 final long uptime = mClocks.uptimeMillis(); 5478 if (--mFlashlightOnNesting == 0) { 5479 mHistoryCur.states2 &= ~HistoryItem.STATE2_FLASHLIGHT_FLAG; 5480 if (DEBUG_HISTORY) Slog.v(TAG, "Flashlight off to: " 5481 + Integer.toHexString(mHistoryCur.states2)); 5482 addHistoryRecordLocked(elapsedRealtime, uptime); 5483 mFlashlightOnTimer.stopRunningLocked(elapsedRealtime); 5484 } 5485 getUidStatsLocked(uid).noteFlashlightTurnedOffLocked(elapsedRealtime); 5486 } 5487 noteCameraOnLocked(int uid)5488 public void noteCameraOnLocked(int uid) { 5489 uid = mapUid(uid); 5490 final long elapsedRealtime = mClocks.elapsedRealtime(); 5491 final long uptime = mClocks.uptimeMillis(); 5492 if (mCameraOnNesting++ == 0) { 5493 mHistoryCur.states2 |= HistoryItem.STATE2_CAMERA_FLAG; 5494 if (DEBUG_HISTORY) Slog.v(TAG, "Camera on to: " 5495 + Integer.toHexString(mHistoryCur.states2)); 5496 addHistoryRecordLocked(elapsedRealtime, uptime); 5497 mCameraOnTimer.startRunningLocked(elapsedRealtime); 5498 } 5499 getUidStatsLocked(uid).noteCameraTurnedOnLocked(elapsedRealtime); 5500 } 5501 noteCameraOffLocked(int uid)5502 public void noteCameraOffLocked(int uid) { 5503 if (mCameraOnNesting == 0) { 5504 return; 5505 } 5506 uid = mapUid(uid); 5507 final long elapsedRealtime = mClocks.elapsedRealtime(); 5508 final long uptime = mClocks.uptimeMillis(); 5509 if (--mCameraOnNesting == 0) { 5510 mHistoryCur.states2 &= ~HistoryItem.STATE2_CAMERA_FLAG; 5511 if (DEBUG_HISTORY) Slog.v(TAG, "Camera off to: " 5512 + Integer.toHexString(mHistoryCur.states2)); 5513 addHistoryRecordLocked(elapsedRealtime, uptime); 5514 mCameraOnTimer.stopRunningLocked(elapsedRealtime); 5515 } 5516 getUidStatsLocked(uid).noteCameraTurnedOffLocked(elapsedRealtime); 5517 } 5518 noteResetCameraLocked()5519 public void noteResetCameraLocked() { 5520 if (mCameraOnNesting > 0) { 5521 final long elapsedRealtime = mClocks.elapsedRealtime(); 5522 final long uptime = mClocks.uptimeMillis(); 5523 mCameraOnNesting = 0; 5524 mHistoryCur.states2 &= ~HistoryItem.STATE2_CAMERA_FLAG; 5525 if (DEBUG_HISTORY) Slog.v(TAG, "Camera off to: " 5526 + Integer.toHexString(mHistoryCur.states2)); 5527 addHistoryRecordLocked(elapsedRealtime, uptime); 5528 mCameraOnTimer.stopAllRunningLocked(elapsedRealtime); 5529 for (int i=0; i<mUidStats.size(); i++) { 5530 BatteryStatsImpl.Uid uid = mUidStats.valueAt(i); 5531 uid.noteResetCameraLocked(elapsedRealtime); 5532 } 5533 } 5534 } 5535 noteResetFlashlightLocked()5536 public void noteResetFlashlightLocked() { 5537 if (mFlashlightOnNesting > 0) { 5538 final long elapsedRealtime = mClocks.elapsedRealtime(); 5539 final long uptime = mClocks.uptimeMillis(); 5540 mFlashlightOnNesting = 0; 5541 mHistoryCur.states2 &= ~HistoryItem.STATE2_FLASHLIGHT_FLAG; 5542 if (DEBUG_HISTORY) Slog.v(TAG, "Flashlight off to: " 5543 + Integer.toHexString(mHistoryCur.states2)); 5544 addHistoryRecordLocked(elapsedRealtime, uptime); 5545 mFlashlightOnTimer.stopAllRunningLocked(elapsedRealtime); 5546 for (int i=0; i<mUidStats.size(); i++) { 5547 BatteryStatsImpl.Uid uid = mUidStats.valueAt(i); 5548 uid.noteResetFlashlightLocked(elapsedRealtime); 5549 } 5550 } 5551 } 5552 noteBluetoothScanStartedLocked(WorkChain workChain, int uid, boolean isUnoptimized)5553 private void noteBluetoothScanStartedLocked(WorkChain workChain, int uid, 5554 boolean isUnoptimized) { 5555 uid = getAttributionUid(uid, workChain); 5556 final long elapsedRealtime = mClocks.elapsedRealtime(); 5557 final long uptime = mClocks.uptimeMillis(); 5558 if (mBluetoothScanNesting == 0) { 5559 mHistoryCur.states2 |= HistoryItem.STATE2_BLUETOOTH_SCAN_FLAG; 5560 if (DEBUG_HISTORY) Slog.v(TAG, "BLE scan started for: " 5561 + Integer.toHexString(mHistoryCur.states2)); 5562 addHistoryRecordLocked(elapsedRealtime, uptime); 5563 mBluetoothScanTimer.startRunningLocked(elapsedRealtime); 5564 } 5565 mBluetoothScanNesting++; 5566 getUidStatsLocked(uid).noteBluetoothScanStartedLocked(elapsedRealtime, isUnoptimized); 5567 } 5568 noteBluetoothScanStartedFromSourceLocked(WorkSource ws, boolean isUnoptimized)5569 public void noteBluetoothScanStartedFromSourceLocked(WorkSource ws, boolean isUnoptimized) { 5570 final int N = ws.size(); 5571 for (int i = 0; i < N; i++) { 5572 noteBluetoothScanStartedLocked(null, ws.get(i), isUnoptimized); 5573 } 5574 5575 final List<WorkChain> workChains = ws.getWorkChains(); 5576 if (workChains != null) { 5577 for (int i = 0; i < workChains.size(); ++i) { 5578 noteBluetoothScanStartedLocked(workChains.get(i), -1, isUnoptimized); 5579 } 5580 } 5581 } 5582 noteBluetoothScanStoppedLocked(WorkChain workChain, int uid, boolean isUnoptimized)5583 private void noteBluetoothScanStoppedLocked(WorkChain workChain, int uid, 5584 boolean isUnoptimized) { 5585 uid = getAttributionUid(uid, workChain); 5586 final long elapsedRealtime = mClocks.elapsedRealtime(); 5587 final long uptime = mClocks.uptimeMillis(); 5588 mBluetoothScanNesting--; 5589 if (mBluetoothScanNesting == 0) { 5590 mHistoryCur.states2 &= ~HistoryItem.STATE2_BLUETOOTH_SCAN_FLAG; 5591 if (DEBUG_HISTORY) Slog.v(TAG, "BLE scan stopped for: " 5592 + Integer.toHexString(mHistoryCur.states2)); 5593 addHistoryRecordLocked(elapsedRealtime, uptime); 5594 mBluetoothScanTimer.stopRunningLocked(elapsedRealtime); 5595 } 5596 getUidStatsLocked(uid).noteBluetoothScanStoppedLocked(elapsedRealtime, isUnoptimized); 5597 } 5598 getAttributionUid(int uid, WorkChain workChain)5599 private int getAttributionUid(int uid, WorkChain workChain) { 5600 if (workChain != null) { 5601 return mapUid(workChain.getAttributionUid()); 5602 } 5603 5604 return mapUid(uid); 5605 } 5606 noteBluetoothScanStoppedFromSourceLocked(WorkSource ws, boolean isUnoptimized)5607 public void noteBluetoothScanStoppedFromSourceLocked(WorkSource ws, boolean isUnoptimized) { 5608 final int N = ws.size(); 5609 for (int i = 0; i < N; i++) { 5610 noteBluetoothScanStoppedLocked(null, ws.get(i), isUnoptimized); 5611 } 5612 5613 final List<WorkChain> workChains = ws.getWorkChains(); 5614 if (workChains != null) { 5615 for (int i = 0; i < workChains.size(); ++i) { 5616 noteBluetoothScanStoppedLocked(workChains.get(i), -1, isUnoptimized); 5617 } 5618 } 5619 } 5620 noteResetBluetoothScanLocked()5621 public void noteResetBluetoothScanLocked() { 5622 if (mBluetoothScanNesting > 0) { 5623 final long elapsedRealtime = mClocks.elapsedRealtime(); 5624 final long uptime = mClocks.uptimeMillis(); 5625 mBluetoothScanNesting = 0; 5626 mHistoryCur.states2 &= ~HistoryItem.STATE2_BLUETOOTH_SCAN_FLAG; 5627 if (DEBUG_HISTORY) Slog.v(TAG, "BLE can stopped for: " 5628 + Integer.toHexString(mHistoryCur.states2)); 5629 addHistoryRecordLocked(elapsedRealtime, uptime); 5630 mBluetoothScanTimer.stopAllRunningLocked(elapsedRealtime); 5631 for (int i=0; i<mUidStats.size(); i++) { 5632 BatteryStatsImpl.Uid uid = mUidStats.valueAt(i); 5633 uid.noteResetBluetoothScanLocked(elapsedRealtime); 5634 } 5635 } 5636 } 5637 noteBluetoothScanResultsFromSourceLocked(WorkSource ws, int numNewResults)5638 public void noteBluetoothScanResultsFromSourceLocked(WorkSource ws, int numNewResults) { 5639 final int N = ws.size(); 5640 for (int i = 0; i < N; i++) { 5641 int uid = mapUid(ws.get(i)); 5642 getUidStatsLocked(uid).noteBluetoothScanResultsLocked(numNewResults); 5643 } 5644 5645 final List<WorkChain> workChains = ws.getWorkChains(); 5646 if (workChains != null) { 5647 for (int i = 0; i < workChains.size(); ++i) { 5648 final WorkChain wc = workChains.get(i); 5649 int uid = mapUid(wc.getAttributionUid()); 5650 getUidStatsLocked(uid).noteBluetoothScanResultsLocked(numNewResults); 5651 } 5652 } 5653 } 5654 noteWifiRadioApWakeupLocked(final long elapsedRealtimeMillis, final long uptimeMillis, int uid)5655 private void noteWifiRadioApWakeupLocked(final long elapsedRealtimeMillis, 5656 final long uptimeMillis, int uid) { 5657 uid = mapUid(uid); 5658 addHistoryEventLocked(elapsedRealtimeMillis, uptimeMillis, HistoryItem.EVENT_WAKEUP_AP, "", 5659 uid); 5660 getUidStatsLocked(uid).noteWifiRadioApWakeupLocked(); 5661 } 5662 noteWifiRadioPowerState(int powerState, long timestampNs, int uid)5663 public void noteWifiRadioPowerState(int powerState, long timestampNs, int uid) { 5664 final long elapsedRealtime = mClocks.elapsedRealtime(); 5665 final long uptime = mClocks.uptimeMillis(); 5666 if (mWifiRadioPowerState != powerState) { 5667 final boolean active = 5668 powerState == DataConnectionRealTimeInfo.DC_POWER_STATE_MEDIUM 5669 || powerState == DataConnectionRealTimeInfo.DC_POWER_STATE_HIGH; 5670 if (active) { 5671 if (uid > 0) { 5672 noteWifiRadioApWakeupLocked(elapsedRealtime, uptime, uid); 5673 } 5674 mHistoryCur.states |= HistoryItem.STATE_WIFI_RADIO_ACTIVE_FLAG; 5675 mWifiActiveTimer.startRunningLocked(elapsedRealtime); 5676 } else { 5677 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_RADIO_ACTIVE_FLAG; 5678 mWifiActiveTimer.stopRunningLocked( 5679 timestampNs / (1000 * 1000)); 5680 } 5681 if (DEBUG_HISTORY) Slog.v(TAG, "Wifi network active " + active + " to: " 5682 + Integer.toHexString(mHistoryCur.states)); 5683 addHistoryRecordLocked(elapsedRealtime, uptime); 5684 mWifiRadioPowerState = powerState; 5685 } 5686 } 5687 noteWifiRunningLocked(WorkSource ws)5688 public void noteWifiRunningLocked(WorkSource ws) { 5689 if (!mGlobalWifiRunning) { 5690 final long elapsedRealtime = mClocks.elapsedRealtime(); 5691 final long uptime = mClocks.uptimeMillis(); 5692 mHistoryCur.states2 |= HistoryItem.STATE2_WIFI_RUNNING_FLAG; 5693 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI running to: " 5694 + Integer.toHexString(mHistoryCur.states)); 5695 addHistoryRecordLocked(elapsedRealtime, uptime); 5696 mGlobalWifiRunning = true; 5697 mGlobalWifiRunningTimer.startRunningLocked(elapsedRealtime); 5698 int N = ws.size(); 5699 for (int i=0; i<N; i++) { 5700 int uid = mapUid(ws.get(i)); 5701 getUidStatsLocked(uid).noteWifiRunningLocked(elapsedRealtime); 5702 } 5703 5704 List<WorkChain> workChains = ws.getWorkChains(); 5705 if (workChains != null) { 5706 for (int i = 0; i < workChains.size(); ++i) { 5707 int uid = mapUid(workChains.get(i).getAttributionUid()); 5708 getUidStatsLocked(uid).noteWifiRunningLocked(elapsedRealtime); 5709 } 5710 } 5711 5712 scheduleSyncExternalStatsLocked("wifi-running", ExternalStatsSync.UPDATE_WIFI); 5713 } else { 5714 Log.w(TAG, "noteWifiRunningLocked -- called while WIFI running"); 5715 } 5716 } 5717 noteWifiRunningChangedLocked(WorkSource oldWs, WorkSource newWs)5718 public void noteWifiRunningChangedLocked(WorkSource oldWs, WorkSource newWs) { 5719 if (mGlobalWifiRunning) { 5720 final long elapsedRealtime = mClocks.elapsedRealtime(); 5721 int N = oldWs.size(); 5722 for (int i=0; i<N; i++) { 5723 int uid = mapUid(oldWs.get(i)); 5724 getUidStatsLocked(uid).noteWifiStoppedLocked(elapsedRealtime); 5725 } 5726 5727 List<WorkChain> workChains = oldWs.getWorkChains(); 5728 if (workChains != null) { 5729 for (int i = 0; i < workChains.size(); ++i) { 5730 int uid = mapUid(workChains.get(i).getAttributionUid()); 5731 getUidStatsLocked(uid).noteWifiStoppedLocked(elapsedRealtime); 5732 } 5733 } 5734 5735 N = newWs.size(); 5736 for (int i=0; i<N; i++) { 5737 int uid = mapUid(newWs.get(i)); 5738 getUidStatsLocked(uid).noteWifiRunningLocked(elapsedRealtime); 5739 } 5740 5741 workChains = newWs.getWorkChains(); 5742 if (workChains != null) { 5743 for (int i = 0; i < workChains.size(); ++i) { 5744 int uid = mapUid(workChains.get(i).getAttributionUid()); 5745 getUidStatsLocked(uid).noteWifiRunningLocked(elapsedRealtime); 5746 } 5747 } 5748 } else { 5749 Log.w(TAG, "noteWifiRunningChangedLocked -- called while WIFI not running"); 5750 } 5751 } 5752 noteWifiStoppedLocked(WorkSource ws)5753 public void noteWifiStoppedLocked(WorkSource ws) { 5754 if (mGlobalWifiRunning) { 5755 final long elapsedRealtime = mClocks.elapsedRealtime(); 5756 final long uptime = mClocks.uptimeMillis(); 5757 mHistoryCur.states2 &= ~HistoryItem.STATE2_WIFI_RUNNING_FLAG; 5758 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI stopped to: " 5759 + Integer.toHexString(mHistoryCur.states)); 5760 addHistoryRecordLocked(elapsedRealtime, uptime); 5761 mGlobalWifiRunning = false; 5762 mGlobalWifiRunningTimer.stopRunningLocked(elapsedRealtime); 5763 int N = ws.size(); 5764 for (int i=0; i<N; i++) { 5765 int uid = mapUid(ws.get(i)); 5766 getUidStatsLocked(uid).noteWifiStoppedLocked(elapsedRealtime); 5767 } 5768 5769 List<WorkChain> workChains = ws.getWorkChains(); 5770 if (workChains != null) { 5771 for (int i = 0; i < workChains.size(); ++i) { 5772 int uid = mapUid(workChains.get(i).getAttributionUid()); 5773 getUidStatsLocked(uid).noteWifiStoppedLocked(elapsedRealtime); 5774 } 5775 } 5776 5777 scheduleSyncExternalStatsLocked("wifi-stopped", ExternalStatsSync.UPDATE_WIFI); 5778 } else { 5779 Log.w(TAG, "noteWifiStoppedLocked -- called while WIFI not running"); 5780 } 5781 } 5782 noteWifiStateLocked(int wifiState, String accessPoint)5783 public void noteWifiStateLocked(int wifiState, String accessPoint) { 5784 if (DEBUG) Log.i(TAG, "WiFi state -> " + wifiState); 5785 if (mWifiState != wifiState) { 5786 final long elapsedRealtime = mClocks.elapsedRealtime(); 5787 if (mWifiState >= 0) { 5788 mWifiStateTimer[mWifiState].stopRunningLocked(elapsedRealtime); 5789 } 5790 mWifiState = wifiState; 5791 mWifiStateTimer[wifiState].startRunningLocked(elapsedRealtime); 5792 scheduleSyncExternalStatsLocked("wifi-state", ExternalStatsSync.UPDATE_WIFI); 5793 } 5794 } 5795 noteWifiSupplicantStateChangedLocked(int supplState, boolean failedAuth)5796 public void noteWifiSupplicantStateChangedLocked(int supplState, boolean failedAuth) { 5797 if (DEBUG) Log.i(TAG, "WiFi suppl state -> " + supplState); 5798 if (mWifiSupplState != supplState) { 5799 final long elapsedRealtime = mClocks.elapsedRealtime(); 5800 final long uptime = mClocks.uptimeMillis(); 5801 if (mWifiSupplState >= 0) { 5802 mWifiSupplStateTimer[mWifiSupplState].stopRunningLocked(elapsedRealtime); 5803 } 5804 mWifiSupplState = supplState; 5805 mWifiSupplStateTimer[supplState].startRunningLocked(elapsedRealtime); 5806 mHistoryCur.states2 = 5807 (mHistoryCur.states2&~HistoryItem.STATE2_WIFI_SUPPL_STATE_MASK) 5808 | (supplState << HistoryItem.STATE2_WIFI_SUPPL_STATE_SHIFT); 5809 if (DEBUG_HISTORY) Slog.v(TAG, "Wifi suppl state " + supplState + " to: " 5810 + Integer.toHexString(mHistoryCur.states2)); 5811 addHistoryRecordLocked(elapsedRealtime, uptime); 5812 } 5813 } 5814 stopAllWifiSignalStrengthTimersLocked(int except)5815 void stopAllWifiSignalStrengthTimersLocked(int except) { 5816 final long elapsedRealtime = mClocks.elapsedRealtime(); 5817 for (int i = 0; i < NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { 5818 if (i == except) { 5819 continue; 5820 } 5821 while (mWifiSignalStrengthsTimer[i].isRunningLocked()) { 5822 mWifiSignalStrengthsTimer[i].stopRunningLocked(elapsedRealtime); 5823 } 5824 } 5825 } 5826 noteWifiRssiChangedLocked(int newRssi)5827 public void noteWifiRssiChangedLocked(int newRssi) { 5828 int strengthBin = WifiManager.calculateSignalLevel(newRssi, NUM_WIFI_SIGNAL_STRENGTH_BINS); 5829 if (DEBUG) Log.i(TAG, "WiFi rssi -> " + newRssi + " bin=" + strengthBin); 5830 if (mWifiSignalStrengthBin != strengthBin) { 5831 final long elapsedRealtime = mClocks.elapsedRealtime(); 5832 final long uptime = mClocks.uptimeMillis(); 5833 if (mWifiSignalStrengthBin >= 0) { 5834 mWifiSignalStrengthsTimer[mWifiSignalStrengthBin].stopRunningLocked( 5835 elapsedRealtime); 5836 } 5837 if (strengthBin >= 0) { 5838 if (!mWifiSignalStrengthsTimer[strengthBin].isRunningLocked()) { 5839 mWifiSignalStrengthsTimer[strengthBin].startRunningLocked(elapsedRealtime); 5840 } 5841 mHistoryCur.states2 = 5842 (mHistoryCur.states2&~HistoryItem.STATE2_WIFI_SIGNAL_STRENGTH_MASK) 5843 | (strengthBin << HistoryItem.STATE2_WIFI_SIGNAL_STRENGTH_SHIFT); 5844 if (DEBUG_HISTORY) Slog.v(TAG, "Wifi signal strength " + strengthBin + " to: " 5845 + Integer.toHexString(mHistoryCur.states2)); 5846 addHistoryRecordLocked(elapsedRealtime, uptime); 5847 } else { 5848 stopAllWifiSignalStrengthTimersLocked(-1); 5849 } 5850 mWifiSignalStrengthBin = strengthBin; 5851 } 5852 } 5853 5854 int mWifiFullLockNesting = 0; 5855 5856 @UnsupportedAppUsage noteFullWifiLockAcquiredLocked(int uid)5857 public void noteFullWifiLockAcquiredLocked(int uid) { 5858 final long elapsedRealtime = mClocks.elapsedRealtime(); 5859 final long uptime = mClocks.uptimeMillis(); 5860 if (mWifiFullLockNesting == 0) { 5861 mHistoryCur.states |= HistoryItem.STATE_WIFI_FULL_LOCK_FLAG; 5862 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI full lock on to: " 5863 + Integer.toHexString(mHistoryCur.states)); 5864 addHistoryRecordLocked(elapsedRealtime, uptime); 5865 } 5866 mWifiFullLockNesting++; 5867 getUidStatsLocked(uid).noteFullWifiLockAcquiredLocked(elapsedRealtime); 5868 } 5869 5870 @UnsupportedAppUsage noteFullWifiLockReleasedLocked(int uid)5871 public void noteFullWifiLockReleasedLocked(int uid) { 5872 final long elapsedRealtime = mClocks.elapsedRealtime(); 5873 final long uptime = mClocks.uptimeMillis(); 5874 mWifiFullLockNesting--; 5875 if (mWifiFullLockNesting == 0) { 5876 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_FULL_LOCK_FLAG; 5877 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI full lock off to: " 5878 + Integer.toHexString(mHistoryCur.states)); 5879 addHistoryRecordLocked(elapsedRealtime, uptime); 5880 } 5881 getUidStatsLocked(uid).noteFullWifiLockReleasedLocked(elapsedRealtime); 5882 } 5883 5884 int mWifiScanNesting = 0; 5885 noteWifiScanStartedLocked(int uid)5886 public void noteWifiScanStartedLocked(int uid) { 5887 final long elapsedRealtime = mClocks.elapsedRealtime(); 5888 final long uptime = mClocks.uptimeMillis(); 5889 if (mWifiScanNesting == 0) { 5890 mHistoryCur.states |= HistoryItem.STATE_WIFI_SCAN_FLAG; 5891 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI scan started for: " 5892 + Integer.toHexString(mHistoryCur.states)); 5893 addHistoryRecordLocked(elapsedRealtime, uptime); 5894 } 5895 mWifiScanNesting++; 5896 getUidStatsLocked(uid).noteWifiScanStartedLocked(elapsedRealtime); 5897 } 5898 noteWifiScanStoppedLocked(int uid)5899 public void noteWifiScanStoppedLocked(int uid) { 5900 final long elapsedRealtime = mClocks.elapsedRealtime(); 5901 final long uptime = mClocks.uptimeMillis(); 5902 mWifiScanNesting--; 5903 if (mWifiScanNesting == 0) { 5904 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_SCAN_FLAG; 5905 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI scan stopped for: " 5906 + Integer.toHexString(mHistoryCur.states)); 5907 addHistoryRecordLocked(elapsedRealtime, uptime); 5908 } 5909 getUidStatsLocked(uid).noteWifiScanStoppedLocked(elapsedRealtime); 5910 } 5911 noteWifiBatchedScanStartedLocked(int uid, int csph)5912 public void noteWifiBatchedScanStartedLocked(int uid, int csph) { 5913 uid = mapUid(uid); 5914 final long elapsedRealtime = mClocks.elapsedRealtime(); 5915 getUidStatsLocked(uid).noteWifiBatchedScanStartedLocked(csph, elapsedRealtime); 5916 } 5917 noteWifiBatchedScanStoppedLocked(int uid)5918 public void noteWifiBatchedScanStoppedLocked(int uid) { 5919 uid = mapUid(uid); 5920 final long elapsedRealtime = mClocks.elapsedRealtime(); 5921 getUidStatsLocked(uid).noteWifiBatchedScanStoppedLocked(elapsedRealtime); 5922 } 5923 5924 int mWifiMulticastNesting = 0; 5925 5926 @UnsupportedAppUsage noteWifiMulticastEnabledLocked(int uid)5927 public void noteWifiMulticastEnabledLocked(int uid) { 5928 uid = mapUid(uid); 5929 final long elapsedRealtime = mClocks.elapsedRealtime(); 5930 final long uptime = mClocks.uptimeMillis(); 5931 if (mWifiMulticastNesting == 0) { 5932 mHistoryCur.states |= HistoryItem.STATE_WIFI_MULTICAST_ON_FLAG; 5933 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI multicast on to: " 5934 + Integer.toHexString(mHistoryCur.states)); 5935 addHistoryRecordLocked(elapsedRealtime, uptime); 5936 5937 // Start Wifi Multicast overall timer 5938 if (!mWifiMulticastWakelockTimer.isRunningLocked()) { 5939 if (DEBUG_HISTORY) Slog.v(TAG, "WiFi Multicast Overall Timer Started"); 5940 mWifiMulticastWakelockTimer.startRunningLocked(elapsedRealtime); 5941 } 5942 } 5943 mWifiMulticastNesting++; 5944 getUidStatsLocked(uid).noteWifiMulticastEnabledLocked(elapsedRealtime); 5945 } 5946 5947 @UnsupportedAppUsage noteWifiMulticastDisabledLocked(int uid)5948 public void noteWifiMulticastDisabledLocked(int uid) { 5949 uid = mapUid(uid); 5950 final long elapsedRealtime = mClocks.elapsedRealtime(); 5951 final long uptime = mClocks.uptimeMillis(); 5952 mWifiMulticastNesting--; 5953 if (mWifiMulticastNesting == 0) { 5954 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_MULTICAST_ON_FLAG; 5955 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI multicast off to: " 5956 + Integer.toHexString(mHistoryCur.states)); 5957 addHistoryRecordLocked(elapsedRealtime, uptime); 5958 5959 // Stop Wifi Multicast overall timer 5960 if (mWifiMulticastWakelockTimer.isRunningLocked()) { 5961 if (DEBUG_HISTORY) Slog.v(TAG, "Multicast Overall Timer Stopped"); 5962 mWifiMulticastWakelockTimer.stopRunningLocked(elapsedRealtime); 5963 } 5964 } 5965 getUidStatsLocked(uid).noteWifiMulticastDisabledLocked(elapsedRealtime); 5966 } 5967 noteFullWifiLockAcquiredFromSourceLocked(WorkSource ws)5968 public void noteFullWifiLockAcquiredFromSourceLocked(WorkSource ws) { 5969 int N = ws.size(); 5970 for (int i=0; i<N; i++) { 5971 final int uid = mapUid(ws.get(i)); 5972 noteFullWifiLockAcquiredLocked(uid); 5973 } 5974 5975 final List<WorkChain> workChains = ws.getWorkChains(); 5976 if (workChains != null) { 5977 for (int i = 0; i < workChains.size(); ++i) { 5978 final WorkChain workChain = workChains.get(i); 5979 final int uid = mapUid(workChain.getAttributionUid()); 5980 noteFullWifiLockAcquiredLocked(uid); 5981 } 5982 } 5983 } 5984 noteFullWifiLockReleasedFromSourceLocked(WorkSource ws)5985 public void noteFullWifiLockReleasedFromSourceLocked(WorkSource ws) { 5986 int N = ws.size(); 5987 for (int i=0; i<N; i++) { 5988 final int uid = mapUid(ws.get(i)); 5989 noteFullWifiLockReleasedLocked(uid); 5990 } 5991 5992 final List<WorkChain> workChains = ws.getWorkChains(); 5993 if (workChains != null) { 5994 for (int i = 0; i < workChains.size(); ++i) { 5995 final WorkChain workChain = workChains.get(i); 5996 final int uid = mapUid(workChain.getAttributionUid()); 5997 noteFullWifiLockReleasedLocked(uid); 5998 } 5999 } 6000 } 6001 noteWifiScanStartedFromSourceLocked(WorkSource ws)6002 public void noteWifiScanStartedFromSourceLocked(WorkSource ws) { 6003 int N = ws.size(); 6004 for (int i=0; i<N; i++) { 6005 final int uid = mapUid(ws.get(i)); 6006 noteWifiScanStartedLocked(uid); 6007 } 6008 6009 final List<WorkChain> workChains = ws.getWorkChains(); 6010 if (workChains != null) { 6011 for (int i = 0; i < workChains.size(); ++i) { 6012 final WorkChain workChain = workChains.get(i); 6013 final int uid = mapUid(workChain.getAttributionUid()); 6014 noteWifiScanStartedLocked(uid); 6015 } 6016 } 6017 } 6018 noteWifiScanStoppedFromSourceLocked(WorkSource ws)6019 public void noteWifiScanStoppedFromSourceLocked(WorkSource ws) { 6020 int N = ws.size(); 6021 for (int i=0; i<N; i++) { 6022 final int uid = mapUid(ws.get(i)); 6023 noteWifiScanStoppedLocked(uid); 6024 } 6025 6026 final List<WorkChain> workChains = ws.getWorkChains(); 6027 if (workChains != null) { 6028 for (int i = 0; i < workChains.size(); ++i) { 6029 final WorkChain workChain = workChains.get(i); 6030 final int uid = mapUid(workChain.getAttributionUid()); 6031 noteWifiScanStoppedLocked(uid); 6032 } 6033 } 6034 } 6035 noteWifiBatchedScanStartedFromSourceLocked(WorkSource ws, int csph)6036 public void noteWifiBatchedScanStartedFromSourceLocked(WorkSource ws, int csph) { 6037 int N = ws.size(); 6038 for (int i=0; i<N; i++) { 6039 noteWifiBatchedScanStartedLocked(ws.get(i), csph); 6040 } 6041 6042 final List<WorkChain> workChains = ws.getWorkChains(); 6043 if (workChains != null) { 6044 for (int i = 0; i < workChains.size(); ++i) { 6045 noteWifiBatchedScanStartedLocked(workChains.get(i).getAttributionUid(), csph); 6046 } 6047 } 6048 } 6049 noteWifiBatchedScanStoppedFromSourceLocked(WorkSource ws)6050 public void noteWifiBatchedScanStoppedFromSourceLocked(WorkSource ws) { 6051 int N = ws.size(); 6052 for (int i=0; i<N; i++) { 6053 noteWifiBatchedScanStoppedLocked(ws.get(i)); 6054 } 6055 6056 final List<WorkChain> workChains = ws.getWorkChains(); 6057 if (workChains != null) { 6058 for (int i = 0; i < workChains.size(); ++i) { 6059 noteWifiBatchedScanStoppedLocked(workChains.get(i).getAttributionUid()); 6060 } 6061 } 6062 } 6063 includeInStringArray(String[] array, String str)6064 private static String[] includeInStringArray(String[] array, String str) { 6065 if (ArrayUtils.indexOf(array, str) >= 0) { 6066 return array; 6067 } 6068 String[] newArray = new String[array.length+1]; 6069 System.arraycopy(array, 0, newArray, 0, array.length); 6070 newArray[array.length] = str; 6071 return newArray; 6072 } 6073 excludeFromStringArray(String[] array, String str)6074 private static String[] excludeFromStringArray(String[] array, String str) { 6075 int index = ArrayUtils.indexOf(array, str); 6076 if (index >= 0) { 6077 String[] newArray = new String[array.length-1]; 6078 if (index > 0) { 6079 System.arraycopy(array, 0, newArray, 0, index); 6080 } 6081 if (index < array.length-1) { 6082 System.arraycopy(array, index+1, newArray, index, array.length-index-1); 6083 } 6084 return newArray; 6085 } 6086 return array; 6087 } 6088 noteNetworkInterfaceTypeLocked(String iface, int networkType)6089 public void noteNetworkInterfaceTypeLocked(String iface, int networkType) { 6090 if (TextUtils.isEmpty(iface)) return; 6091 6092 synchronized (mModemNetworkLock) { 6093 if (ConnectivityManager.isNetworkTypeMobile(networkType)) { 6094 mModemIfaces = includeInStringArray(mModemIfaces, iface); 6095 if (DEBUG) Slog.d(TAG, "Note mobile iface " + iface + ": " + mModemIfaces); 6096 } else { 6097 mModemIfaces = excludeFromStringArray(mModemIfaces, iface); 6098 if (DEBUG) Slog.d(TAG, "Note non-mobile iface " + iface + ": " + mModemIfaces); 6099 } 6100 } 6101 6102 synchronized (mWifiNetworkLock) { 6103 if (ConnectivityManager.isNetworkTypeWifi(networkType)) { 6104 mWifiIfaces = includeInStringArray(mWifiIfaces, iface); 6105 if (DEBUG) Slog.d(TAG, "Note wifi iface " + iface + ": " + mWifiIfaces); 6106 } else { 6107 mWifiIfaces = excludeFromStringArray(mWifiIfaces, iface); 6108 if (DEBUG) Slog.d(TAG, "Note non-wifi iface " + iface + ": " + mWifiIfaces); 6109 } 6110 } 6111 } 6112 getWifiIfaces()6113 public String[] getWifiIfaces() { 6114 synchronized (mWifiNetworkLock) { 6115 return mWifiIfaces; 6116 } 6117 } 6118 getMobileIfaces()6119 public String[] getMobileIfaces() { 6120 synchronized (mModemNetworkLock) { 6121 return mModemIfaces; 6122 } 6123 } 6124 6125 @UnsupportedAppUsage getScreenOnTime(long elapsedRealtimeUs, int which)6126 @Override public long getScreenOnTime(long elapsedRealtimeUs, int which) { 6127 return mScreenOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 6128 } 6129 getScreenOnCount(int which)6130 @Override public int getScreenOnCount(int which) { 6131 return mScreenOnTimer.getCountLocked(which); 6132 } 6133 getScreenDozeTime(long elapsedRealtimeUs, int which)6134 @Override public long getScreenDozeTime(long elapsedRealtimeUs, int which) { 6135 return mScreenDozeTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 6136 } 6137 getScreenDozeCount(int which)6138 @Override public int getScreenDozeCount(int which) { 6139 return mScreenDozeTimer.getCountLocked(which); 6140 } 6141 6142 @UnsupportedAppUsage getScreenBrightnessTime(int brightnessBin, long elapsedRealtimeUs, int which)6143 @Override public long getScreenBrightnessTime(int brightnessBin, 6144 long elapsedRealtimeUs, int which) { 6145 return mScreenBrightnessTimer[brightnessBin].getTotalTimeLocked( 6146 elapsedRealtimeUs, which); 6147 } 6148 getScreenBrightnessTimer(int brightnessBin)6149 @Override public Timer getScreenBrightnessTimer(int brightnessBin) { 6150 return mScreenBrightnessTimer[brightnessBin]; 6151 } 6152 getInteractiveTime(long elapsedRealtimeUs, int which)6153 @Override public long getInteractiveTime(long elapsedRealtimeUs, int which) { 6154 return mInteractiveTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 6155 } 6156 getPowerSaveModeEnabledTime(long elapsedRealtimeUs, int which)6157 @Override public long getPowerSaveModeEnabledTime(long elapsedRealtimeUs, int which) { 6158 return mPowerSaveModeEnabledTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 6159 } 6160 getPowerSaveModeEnabledCount(int which)6161 @Override public int getPowerSaveModeEnabledCount(int which) { 6162 return mPowerSaveModeEnabledTimer.getCountLocked(which); 6163 } 6164 getDeviceIdleModeTime(int mode, long elapsedRealtimeUs, int which)6165 @Override public long getDeviceIdleModeTime(int mode, long elapsedRealtimeUs, 6166 int which) { 6167 switch (mode) { 6168 case DEVICE_IDLE_MODE_LIGHT: 6169 return mDeviceIdleModeLightTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 6170 case DEVICE_IDLE_MODE_DEEP: 6171 return mDeviceIdleModeFullTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 6172 } 6173 return 0; 6174 } 6175 getDeviceIdleModeCount(int mode, int which)6176 @Override public int getDeviceIdleModeCount(int mode, int which) { 6177 switch (mode) { 6178 case DEVICE_IDLE_MODE_LIGHT: 6179 return mDeviceIdleModeLightTimer.getCountLocked(which); 6180 case DEVICE_IDLE_MODE_DEEP: 6181 return mDeviceIdleModeFullTimer.getCountLocked(which); 6182 } 6183 return 0; 6184 } 6185 getLongestDeviceIdleModeTime(int mode)6186 @Override public long getLongestDeviceIdleModeTime(int mode) { 6187 switch (mode) { 6188 case DEVICE_IDLE_MODE_LIGHT: 6189 return mLongestLightIdleTime; 6190 case DEVICE_IDLE_MODE_DEEP: 6191 return mLongestFullIdleTime; 6192 } 6193 return 0; 6194 } 6195 getDeviceIdlingTime(int mode, long elapsedRealtimeUs, int which)6196 @Override public long getDeviceIdlingTime(int mode, long elapsedRealtimeUs, int which) { 6197 switch (mode) { 6198 case DEVICE_IDLE_MODE_LIGHT: 6199 return mDeviceLightIdlingTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 6200 case DEVICE_IDLE_MODE_DEEP: 6201 return mDeviceIdlingTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 6202 } 6203 return 0; 6204 } 6205 getDeviceIdlingCount(int mode, int which)6206 @Override public int getDeviceIdlingCount(int mode, int which) { 6207 switch (mode) { 6208 case DEVICE_IDLE_MODE_LIGHT: 6209 return mDeviceLightIdlingTimer.getCountLocked(which); 6210 case DEVICE_IDLE_MODE_DEEP: 6211 return mDeviceIdlingTimer.getCountLocked(which); 6212 } 6213 return 0; 6214 } 6215 getNumConnectivityChange(int which)6216 @Override public int getNumConnectivityChange(int which) { 6217 return mNumConnectivityChange; 6218 } 6219 getGpsSignalQualityTime(int strengthBin, long elapsedRealtimeUs, int which)6220 @Override public long getGpsSignalQualityTime(int strengthBin, 6221 long elapsedRealtimeUs, int which) { 6222 if (strengthBin < 0 || strengthBin >= GnssMetrics.NUM_GPS_SIGNAL_QUALITY_LEVELS) { 6223 return 0; 6224 } 6225 return mGpsSignalQualityTimer[strengthBin].getTotalTimeLocked( 6226 elapsedRealtimeUs, which); 6227 } 6228 getGpsBatteryDrainMaMs()6229 @Override public long getGpsBatteryDrainMaMs() { 6230 final double opVolt = mPowerProfile.getAveragePower( 6231 PowerProfile.POWER_GPS_OPERATING_VOLTAGE) / 1000.0; 6232 if (opVolt == 0) { 6233 return 0; 6234 } 6235 double energyUsedMaMs = 0.0; 6236 final int which = STATS_SINCE_CHARGED; 6237 final long rawRealtime = SystemClock.elapsedRealtime() * 1000; 6238 for(int i=0; i < GnssMetrics.NUM_GPS_SIGNAL_QUALITY_LEVELS; i++) { 6239 energyUsedMaMs 6240 += mPowerProfile.getAveragePower(PowerProfile.POWER_GPS_SIGNAL_QUALITY_BASED, i) 6241 * (getGpsSignalQualityTime(i, rawRealtime, which) / 1000); 6242 } 6243 return (long) energyUsedMaMs; 6244 } 6245 6246 @UnsupportedAppUsage getPhoneOnTime(long elapsedRealtimeUs, int which)6247 @Override public long getPhoneOnTime(long elapsedRealtimeUs, int which) { 6248 return mPhoneOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 6249 } 6250 getPhoneOnCount(int which)6251 @Override public int getPhoneOnCount(int which) { 6252 return mPhoneOnTimer.getCountLocked(which); 6253 } 6254 6255 @UnsupportedAppUsage getPhoneSignalStrengthTime(int strengthBin, long elapsedRealtimeUs, int which)6256 @Override public long getPhoneSignalStrengthTime(int strengthBin, 6257 long elapsedRealtimeUs, int which) { 6258 return mPhoneSignalStrengthsTimer[strengthBin].getTotalTimeLocked( 6259 elapsedRealtimeUs, which); 6260 } 6261 6262 @UnsupportedAppUsage getPhoneSignalScanningTime( long elapsedRealtimeUs, int which)6263 @Override public long getPhoneSignalScanningTime( 6264 long elapsedRealtimeUs, int which) { 6265 return mPhoneSignalScanningTimer.getTotalTimeLocked( 6266 elapsedRealtimeUs, which); 6267 } 6268 getPhoneSignalScanningTimer()6269 @Override public Timer getPhoneSignalScanningTimer() { 6270 return mPhoneSignalScanningTimer; 6271 } 6272 6273 @UnsupportedAppUsage getPhoneSignalStrengthCount(int strengthBin, int which)6274 @Override public int getPhoneSignalStrengthCount(int strengthBin, int which) { 6275 return mPhoneSignalStrengthsTimer[strengthBin].getCountLocked(which); 6276 } 6277 getPhoneSignalStrengthTimer(int strengthBin)6278 @Override public Timer getPhoneSignalStrengthTimer(int strengthBin) { 6279 return mPhoneSignalStrengthsTimer[strengthBin]; 6280 } 6281 6282 @UnsupportedAppUsage getPhoneDataConnectionTime(int dataType, long elapsedRealtimeUs, int which)6283 @Override public long getPhoneDataConnectionTime(int dataType, 6284 long elapsedRealtimeUs, int which) { 6285 return mPhoneDataConnectionsTimer[dataType].getTotalTimeLocked( 6286 elapsedRealtimeUs, which); 6287 } 6288 6289 @UnsupportedAppUsage getPhoneDataConnectionCount(int dataType, int which)6290 @Override public int getPhoneDataConnectionCount(int dataType, int which) { 6291 return mPhoneDataConnectionsTimer[dataType].getCountLocked(which); 6292 } 6293 getPhoneDataConnectionTimer(int dataType)6294 @Override public Timer getPhoneDataConnectionTimer(int dataType) { 6295 return mPhoneDataConnectionsTimer[dataType]; 6296 } 6297 6298 @UnsupportedAppUsage getMobileRadioActiveTime(long elapsedRealtimeUs, int which)6299 @Override public long getMobileRadioActiveTime(long elapsedRealtimeUs, int which) { 6300 return mMobileRadioActiveTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 6301 } 6302 getMobileRadioActiveCount(int which)6303 @Override public int getMobileRadioActiveCount(int which) { 6304 return mMobileRadioActiveTimer.getCountLocked(which); 6305 } 6306 getMobileRadioActiveAdjustedTime(int which)6307 @Override public long getMobileRadioActiveAdjustedTime(int which) { 6308 return mMobileRadioActiveAdjustedTime.getCountLocked(which); 6309 } 6310 getMobileRadioActiveUnknownTime(int which)6311 @Override public long getMobileRadioActiveUnknownTime(int which) { 6312 return mMobileRadioActiveUnknownTime.getCountLocked(which); 6313 } 6314 getMobileRadioActiveUnknownCount(int which)6315 @Override public int getMobileRadioActiveUnknownCount(int which) { 6316 return (int)mMobileRadioActiveUnknownCount.getCountLocked(which); 6317 } 6318 getWifiMulticastWakelockTime( long elapsedRealtimeUs, int which)6319 @Override public long getWifiMulticastWakelockTime( 6320 long elapsedRealtimeUs, int which) { 6321 return mWifiMulticastWakelockTimer.getTotalTimeLocked( 6322 elapsedRealtimeUs, which); 6323 } 6324 getWifiMulticastWakelockCount(int which)6325 @Override public int getWifiMulticastWakelockCount(int which) { 6326 return mWifiMulticastWakelockTimer.getCountLocked(which); 6327 } 6328 6329 @UnsupportedAppUsage getWifiOnTime(long elapsedRealtimeUs, int which)6330 @Override public long getWifiOnTime(long elapsedRealtimeUs, int which) { 6331 return mWifiOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 6332 } 6333 getWifiActiveTime(long elapsedRealtimeUs, int which)6334 @Override public long getWifiActiveTime(long elapsedRealtimeUs, int which) { 6335 return mWifiActiveTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 6336 } 6337 6338 @UnsupportedAppUsage getGlobalWifiRunningTime(long elapsedRealtimeUs, int which)6339 @Override public long getGlobalWifiRunningTime(long elapsedRealtimeUs, int which) { 6340 return mGlobalWifiRunningTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 6341 } 6342 getWifiStateTime(int wifiState, long elapsedRealtimeUs, int which)6343 @Override public long getWifiStateTime(int wifiState, 6344 long elapsedRealtimeUs, int which) { 6345 return mWifiStateTimer[wifiState].getTotalTimeLocked( 6346 elapsedRealtimeUs, which); 6347 } 6348 getWifiStateCount(int wifiState, int which)6349 @Override public int getWifiStateCount(int wifiState, int which) { 6350 return mWifiStateTimer[wifiState].getCountLocked(which); 6351 } 6352 getWifiStateTimer(int wifiState)6353 @Override public Timer getWifiStateTimer(int wifiState) { 6354 return mWifiStateTimer[wifiState]; 6355 } 6356 getWifiSupplStateTime(int state, long elapsedRealtimeUs, int which)6357 @Override public long getWifiSupplStateTime(int state, 6358 long elapsedRealtimeUs, int which) { 6359 return mWifiSupplStateTimer[state].getTotalTimeLocked( 6360 elapsedRealtimeUs, which); 6361 } 6362 getWifiSupplStateCount(int state, int which)6363 @Override public int getWifiSupplStateCount(int state, int which) { 6364 return mWifiSupplStateTimer[state].getCountLocked(which); 6365 } 6366 getWifiSupplStateTimer(int state)6367 @Override public Timer getWifiSupplStateTimer(int state) { 6368 return mWifiSupplStateTimer[state]; 6369 } 6370 getWifiSignalStrengthTime(int strengthBin, long elapsedRealtimeUs, int which)6371 @Override public long getWifiSignalStrengthTime(int strengthBin, 6372 long elapsedRealtimeUs, int which) { 6373 return mWifiSignalStrengthsTimer[strengthBin].getTotalTimeLocked( 6374 elapsedRealtimeUs, which); 6375 } 6376 getWifiSignalStrengthCount(int strengthBin, int which)6377 @Override public int getWifiSignalStrengthCount(int strengthBin, int which) { 6378 return mWifiSignalStrengthsTimer[strengthBin].getCountLocked(which); 6379 } 6380 getWifiSignalStrengthTimer(int strengthBin)6381 @Override public Timer getWifiSignalStrengthTimer(int strengthBin) { 6382 return mWifiSignalStrengthsTimer[strengthBin]; 6383 } 6384 6385 @Override getBluetoothControllerActivity()6386 public ControllerActivityCounter getBluetoothControllerActivity() { 6387 return mBluetoothActivity; 6388 } 6389 6390 @Override getWifiControllerActivity()6391 public ControllerActivityCounter getWifiControllerActivity() { 6392 return mWifiActivity; 6393 } 6394 6395 @Override getModemControllerActivity()6396 public ControllerActivityCounter getModemControllerActivity() { 6397 return mModemActivity; 6398 } 6399 6400 @Override hasBluetoothActivityReporting()6401 public boolean hasBluetoothActivityReporting() { 6402 return mHasBluetoothReporting; 6403 } 6404 6405 @Override hasWifiActivityReporting()6406 public boolean hasWifiActivityReporting() { 6407 return mHasWifiReporting; 6408 } 6409 6410 @Override hasModemActivityReporting()6411 public boolean hasModemActivityReporting() { 6412 return mHasModemReporting; 6413 } 6414 6415 @Override getFlashlightOnTime(long elapsedRealtimeUs, int which)6416 public long getFlashlightOnTime(long elapsedRealtimeUs, int which) { 6417 return mFlashlightOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 6418 } 6419 6420 @Override getFlashlightOnCount(int which)6421 public long getFlashlightOnCount(int which) { 6422 return mFlashlightOnTimer.getCountLocked(which); 6423 } 6424 6425 @Override getCameraOnTime(long elapsedRealtimeUs, int which)6426 public long getCameraOnTime(long elapsedRealtimeUs, int which) { 6427 return mCameraOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 6428 } 6429 6430 @Override getBluetoothScanTime(long elapsedRealtimeUs, int which)6431 public long getBluetoothScanTime(long elapsedRealtimeUs, int which) { 6432 return mBluetoothScanTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 6433 } 6434 6435 @Override 6436 @UnsupportedAppUsage getNetworkActivityBytes(int type, int which)6437 public long getNetworkActivityBytes(int type, int which) { 6438 if (type >= 0 && type < mNetworkByteActivityCounters.length) { 6439 return mNetworkByteActivityCounters[type].getCountLocked(which); 6440 } else { 6441 return 0; 6442 } 6443 } 6444 6445 @Override getNetworkActivityPackets(int type, int which)6446 public long getNetworkActivityPackets(int type, int which) { 6447 if (type >= 0 && type < mNetworkPacketActivityCounters.length) { 6448 return mNetworkPacketActivityCounters[type].getCountLocked(which); 6449 } else { 6450 return 0; 6451 } 6452 } 6453 getStartClockTime()6454 @Override public long getStartClockTime() { 6455 final long currentTime = System.currentTimeMillis(); 6456 if ((currentTime > MILLISECONDS_IN_YEAR 6457 && mStartClockTime < (currentTime - MILLISECONDS_IN_YEAR)) 6458 || (mStartClockTime > currentTime)) { 6459 // If the start clock time has changed by more than a year, then presumably 6460 // the previous time was completely bogus. So we are going to figure out a 6461 // new time based on how much time has elapsed since we started counting. 6462 recordCurrentTimeChangeLocked(currentTime, mClocks.elapsedRealtime(), 6463 mClocks.uptimeMillis()); 6464 return currentTime - (mClocks.elapsedRealtime() - (mRealtimeStart / 1000)); 6465 } 6466 return mStartClockTime; 6467 } 6468 getStartPlatformVersion()6469 @Override public String getStartPlatformVersion() { 6470 return mStartPlatformVersion; 6471 } 6472 getEndPlatformVersion()6473 @Override public String getEndPlatformVersion() { 6474 return mEndPlatformVersion; 6475 } 6476 getParcelVersion()6477 @Override public int getParcelVersion() { 6478 return VERSION; 6479 } 6480 getIsOnBattery()6481 @Override public boolean getIsOnBattery() { 6482 return mOnBattery; 6483 } 6484 6485 @UnsupportedAppUsage getUidStats()6486 @Override public SparseArray<? extends BatteryStats.Uid> getUidStats() { 6487 return mUidStats; 6488 } 6489 resetIfNotNull(T t, boolean detachIfReset)6490 private static <T extends TimeBaseObs> boolean resetIfNotNull(T t, boolean detachIfReset) { 6491 if (t != null) { 6492 return t.reset(detachIfReset); 6493 } 6494 return true; 6495 } 6496 resetIfNotNull(T[] t, boolean detachIfReset)6497 private static <T extends TimeBaseObs> boolean resetIfNotNull(T[] t, boolean detachIfReset) { 6498 if (t != null) { 6499 boolean ret = true; 6500 for (int i = 0; i < t.length; i++) { 6501 ret &= resetIfNotNull(t[i], detachIfReset); 6502 } 6503 return ret; 6504 } 6505 return true; 6506 } 6507 resetIfNotNull(T[][] t, boolean detachIfReset)6508 private static <T extends TimeBaseObs> boolean resetIfNotNull(T[][] t, boolean detachIfReset) { 6509 if (t != null) { 6510 boolean ret = true; 6511 for (int i = 0; i < t.length; i++) { 6512 ret &= resetIfNotNull(t[i], detachIfReset); 6513 } 6514 return ret; 6515 } 6516 return true; 6517 } 6518 resetIfNotNull(ControllerActivityCounterImpl counter, boolean detachIfReset)6519 private static boolean resetIfNotNull(ControllerActivityCounterImpl counter, 6520 boolean detachIfReset) { 6521 if (counter != null) { 6522 counter.reset(detachIfReset); 6523 } 6524 return true; 6525 } 6526 detachIfNotNull(T t)6527 private static <T extends TimeBaseObs> void detachIfNotNull(T t) { 6528 if (t != null) { 6529 t.detach(); 6530 } 6531 } 6532 detachIfNotNull(T[] t)6533 private static <T extends TimeBaseObs> void detachIfNotNull(T[] t) { 6534 if (t != null) { 6535 for (int i = 0; i < t.length; i++) { 6536 detachIfNotNull(t[i]); 6537 } 6538 } 6539 } 6540 detachIfNotNull(T[][] t)6541 private static <T extends TimeBaseObs> void detachIfNotNull(T[][] t) { 6542 if (t != null) { 6543 for (int i = 0; i < t.length; i++) { 6544 detachIfNotNull(t[i]); 6545 } 6546 } 6547 } 6548 detachIfNotNull(ControllerActivityCounterImpl counter)6549 private static void detachIfNotNull(ControllerActivityCounterImpl counter) { 6550 if (counter != null) { 6551 counter.detach(); 6552 } 6553 } 6554 6555 /** 6556 * The statistics associated with a particular uid. 6557 */ 6558 public static class Uid extends BatteryStats.Uid { 6559 /** 6560 * BatteryStatsImpl that we are associated with. 6561 */ 6562 protected BatteryStatsImpl mBsi; 6563 6564 final int mUid; 6565 6566 /** TimeBase for when uid is in background and device is on battery. */ 6567 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) 6568 public final TimeBase mOnBatteryBackgroundTimeBase; 6569 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) 6570 public final TimeBase mOnBatteryScreenOffBackgroundTimeBase; 6571 6572 boolean mWifiRunning; 6573 StopwatchTimer mWifiRunningTimer; 6574 6575 boolean mFullWifiLockOut; 6576 StopwatchTimer mFullWifiLockTimer; 6577 6578 boolean mWifiScanStarted; 6579 DualTimer mWifiScanTimer; 6580 6581 static final int NO_BATCHED_SCAN_STARTED = -1; 6582 int mWifiBatchedScanBinStarted = NO_BATCHED_SCAN_STARTED; 6583 StopwatchTimer[] mWifiBatchedScanTimer; 6584 6585 int mWifiMulticastWakelockCount; 6586 StopwatchTimer mWifiMulticastTimer; 6587 6588 StopwatchTimer mAudioTurnedOnTimer; 6589 StopwatchTimer mVideoTurnedOnTimer; 6590 StopwatchTimer mFlashlightTurnedOnTimer; 6591 StopwatchTimer mCameraTurnedOnTimer; 6592 StopwatchTimer mForegroundActivityTimer; 6593 StopwatchTimer mForegroundServiceTimer; 6594 /** Total time spent by the uid holding any partial wakelocks. */ 6595 DualTimer mAggregatedPartialWakelockTimer; 6596 DualTimer mBluetoothScanTimer; 6597 DualTimer mBluetoothUnoptimizedScanTimer; 6598 Counter mBluetoothScanResultCounter; 6599 Counter mBluetoothScanResultBgCounter; 6600 6601 int mProcessState = ActivityManager.PROCESS_STATE_NONEXISTENT; 6602 StopwatchTimer[] mProcessStateTimer; 6603 6604 boolean mInForegroundService = false; 6605 6606 BatchTimer mVibratorOnTimer; 6607 6608 Counter[] mUserActivityCounters; 6609 6610 LongSamplingCounter[] mNetworkByteActivityCounters; 6611 LongSamplingCounter[] mNetworkPacketActivityCounters; 6612 LongSamplingCounter mMobileRadioActiveTime; 6613 LongSamplingCounter mMobileRadioActiveCount; 6614 6615 /** 6616 * How many times this UID woke up the Application Processor due to a Mobile radio packet. 6617 */ 6618 private LongSamplingCounter mMobileRadioApWakeupCount; 6619 6620 /** 6621 * How many times this UID woke up the Application Processor due to a Wifi packet. 6622 */ 6623 private LongSamplingCounter mWifiRadioApWakeupCount; 6624 6625 /** 6626 * The amount of time this uid has kept the WiFi controller in idle, tx, and rx mode. 6627 * Can be null if the UID has had no such activity. 6628 */ 6629 private ControllerActivityCounterImpl mWifiControllerActivity; 6630 6631 /** 6632 * The amount of time this uid has kept the Bluetooth controller in idle, tx, and rx mode. 6633 * Can be null if the UID has had no such activity. 6634 */ 6635 private ControllerActivityCounterImpl mBluetoothControllerActivity; 6636 6637 /** 6638 * The amount of time this uid has kept the Modem controller in idle, tx, and rx mode. 6639 * Can be null if the UID has had no such activity. 6640 */ 6641 private ControllerActivityCounterImpl mModemControllerActivity; 6642 6643 /** 6644 * The CPU times we had at the last history details update. 6645 */ 6646 long mLastStepUserTime; 6647 long mLastStepSystemTime; 6648 long mCurStepUserTime; 6649 long mCurStepSystemTime; 6650 6651 LongSamplingCounter mUserCpuTime; 6652 LongSamplingCounter mSystemCpuTime; 6653 LongSamplingCounter[][] mCpuClusterSpeedTimesUs; 6654 LongSamplingCounter mCpuActiveTimeMs; 6655 6656 LongSamplingCounterArray mCpuFreqTimeMs; 6657 LongSamplingCounterArray mScreenOffCpuFreqTimeMs; 6658 LongSamplingCounterArray mCpuClusterTimesMs; 6659 6660 LongSamplingCounterArray[] mProcStateTimeMs; 6661 LongSamplingCounterArray[] mProcStateScreenOffTimeMs; 6662 6663 IntArray mChildUids; 6664 6665 /** 6666 * The statistics we have collected for this uid's wake locks. 6667 */ 6668 final OverflowArrayMap<Wakelock> mWakelockStats; 6669 6670 /** 6671 * The statistics we have collected for this uid's syncs. 6672 */ 6673 final OverflowArrayMap<DualTimer> mSyncStats; 6674 6675 /** 6676 * The statistics we have collected for this uid's jobs. 6677 */ 6678 final OverflowArrayMap<DualTimer> mJobStats; 6679 6680 /** 6681 * Count of the jobs that have completed and the reasons why they completed. 6682 */ 6683 final ArrayMap<String, SparseIntArray> mJobCompletions = new ArrayMap<>(); 6684 6685 /** 6686 * Count of app launch events that had associated deferred job counts or info about 6687 * last time a job was run. 6688 */ 6689 Counter mJobsDeferredEventCount; 6690 6691 /** 6692 * Count of deferred jobs that were pending when the app was launched or brought to 6693 * the foreground through a user interaction. 6694 */ 6695 Counter mJobsDeferredCount; 6696 6697 /** 6698 * Sum of time since the last time a job was run for this app before it was launched. 6699 */ 6700 LongSamplingCounter mJobsFreshnessTimeMs; 6701 6702 /** 6703 * Array of counts of instances where the time since the last job was run for the app 6704 * fell within one of the thresholds in {@link #JOB_FRESHNESS_BUCKETS}. 6705 */ 6706 final Counter[] mJobsFreshnessBuckets; 6707 6708 /** 6709 * The statistics we have collected for this uid's sensor activations. 6710 */ 6711 final SparseArray<Sensor> mSensorStats = new SparseArray<>(); 6712 6713 /** 6714 * The statistics we have collected for this uid's processes. 6715 */ 6716 final ArrayMap<String, Proc> mProcessStats = new ArrayMap<>(); 6717 6718 /** 6719 * The statistics we have collected for this uid's processes. 6720 */ 6721 final ArrayMap<String, Pkg> mPackageStats = new ArrayMap<>(); 6722 6723 /** 6724 * The transient wake stats we have collected for this uid's pids. 6725 */ 6726 final SparseArray<Pid> mPids = new SparseArray<>(); 6727 Uid(BatteryStatsImpl bsi, int uid)6728 public Uid(BatteryStatsImpl bsi, int uid) { 6729 mBsi = bsi; 6730 mUid = uid; 6731 6732 /* Observer list of TimeBase object in Uid is short */ 6733 mOnBatteryBackgroundTimeBase = new TimeBase(false); 6734 mOnBatteryBackgroundTimeBase.init(mBsi.mClocks.uptimeMillis() * 1000, 6735 mBsi.mClocks.elapsedRealtime() * 1000); 6736 /* Observer list of TimeBase object in Uid is short */ 6737 mOnBatteryScreenOffBackgroundTimeBase = new TimeBase(false); 6738 mOnBatteryScreenOffBackgroundTimeBase.init(mBsi.mClocks.uptimeMillis() * 1000, 6739 mBsi.mClocks.elapsedRealtime() * 1000); 6740 6741 mUserCpuTime = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); 6742 mSystemCpuTime = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); 6743 mCpuActiveTimeMs = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); 6744 mCpuClusterTimesMs = new LongSamplingCounterArray(mBsi.mOnBatteryTimeBase); 6745 6746 mWakelockStats = mBsi.new OverflowArrayMap<Wakelock>(uid) { 6747 @Override public Wakelock instantiateObject() { 6748 return new Wakelock(mBsi, Uid.this); 6749 } 6750 }; 6751 mSyncStats = mBsi.new OverflowArrayMap<DualTimer>(uid) { 6752 @Override public DualTimer instantiateObject() { 6753 return new DualTimer(mBsi.mClocks, Uid.this, SYNC, null, 6754 mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase); 6755 } 6756 }; 6757 mJobStats = mBsi.new OverflowArrayMap<DualTimer>(uid) { 6758 @Override public DualTimer instantiateObject() { 6759 return new DualTimer(mBsi.mClocks, Uid.this, JOB, null, 6760 mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase); 6761 } 6762 }; 6763 6764 mWifiRunningTimer = new StopwatchTimer(mBsi.mClocks, this, WIFI_RUNNING, 6765 mBsi.mWifiRunningTimers, mBsi.mOnBatteryTimeBase); 6766 mFullWifiLockTimer = new StopwatchTimer(mBsi.mClocks, this, FULL_WIFI_LOCK, 6767 mBsi.mFullWifiLockTimers, mBsi.mOnBatteryTimeBase); 6768 mWifiScanTimer = new DualTimer(mBsi.mClocks, this, WIFI_SCAN, 6769 mBsi.mWifiScanTimers, mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase); 6770 mWifiBatchedScanTimer = new StopwatchTimer[NUM_WIFI_BATCHED_SCAN_BINS]; 6771 mWifiMulticastTimer = new StopwatchTimer(mBsi.mClocks, this, WIFI_MULTICAST_ENABLED, 6772 mBsi.mWifiMulticastTimers, mBsi.mOnBatteryTimeBase); 6773 mProcessStateTimer = new StopwatchTimer[NUM_PROCESS_STATE]; 6774 mJobsDeferredEventCount = new Counter(mBsi.mOnBatteryTimeBase); 6775 mJobsDeferredCount = new Counter(mBsi.mOnBatteryTimeBase); 6776 mJobsFreshnessTimeMs = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); 6777 mJobsFreshnessBuckets = new Counter[JOB_FRESHNESS_BUCKETS.length]; 6778 } 6779 6780 @VisibleForTesting setProcessStateForTest(int procState)6781 public void setProcessStateForTest(int procState) { 6782 mProcessState = procState; 6783 } 6784 6785 @Override getCpuFreqTimes(int which)6786 public long[] getCpuFreqTimes(int which) { 6787 return nullIfAllZeros(mCpuFreqTimeMs, which); 6788 } 6789 6790 @Override getScreenOffCpuFreqTimes(int which)6791 public long[] getScreenOffCpuFreqTimes(int which) { 6792 return nullIfAllZeros(mScreenOffCpuFreqTimeMs, which); 6793 } 6794 6795 @Override getCpuActiveTime()6796 public long getCpuActiveTime() { 6797 return mCpuActiveTimeMs.getCountLocked(STATS_SINCE_CHARGED); 6798 } 6799 6800 @Override getCpuClusterTimes()6801 public long[] getCpuClusterTimes() { 6802 return nullIfAllZeros(mCpuClusterTimesMs, STATS_SINCE_CHARGED); 6803 } 6804 6805 6806 @Override getCpuFreqTimes(int which, int procState)6807 public long[] getCpuFreqTimes(int which, int procState) { 6808 if (which < 0 || which >= NUM_PROCESS_STATE) { 6809 return null; 6810 } 6811 if (mProcStateTimeMs == null) { 6812 return null; 6813 } 6814 if (!mBsi.mPerProcStateCpuTimesAvailable) { 6815 mProcStateTimeMs = null; 6816 return null; 6817 } 6818 return nullIfAllZeros(mProcStateTimeMs[procState], which); 6819 } 6820 6821 @Override getScreenOffCpuFreqTimes(int which, int procState)6822 public long[] getScreenOffCpuFreqTimes(int which, int procState) { 6823 if (which < 0 || which >= NUM_PROCESS_STATE) { 6824 return null; 6825 } 6826 if (mProcStateScreenOffTimeMs == null) { 6827 return null; 6828 } 6829 if (!mBsi.mPerProcStateCpuTimesAvailable) { 6830 mProcStateScreenOffTimeMs = null; 6831 return null; 6832 } 6833 return nullIfAllZeros(mProcStateScreenOffTimeMs[procState], which); 6834 } 6835 addIsolatedUid(int isolatedUid)6836 public void addIsolatedUid(int isolatedUid) { 6837 if (mChildUids == null) { 6838 mChildUids = new IntArray(); 6839 } else if (mChildUids.indexOf(isolatedUid) >= 0) { 6840 return; 6841 } 6842 mChildUids.add(isolatedUid); 6843 } 6844 removeIsolatedUid(int isolatedUid)6845 public void removeIsolatedUid(int isolatedUid) { 6846 final int idx = mChildUids == null ? -1 : mChildUids.indexOf(isolatedUid); 6847 if (idx < 0) { 6848 return; 6849 } 6850 mChildUids.remove(idx); 6851 } 6852 nullIfAllZeros(LongSamplingCounterArray cpuTimesMs, int which)6853 private long[] nullIfAllZeros(LongSamplingCounterArray cpuTimesMs, int which) { 6854 if (cpuTimesMs == null) { 6855 return null; 6856 } 6857 final long[] counts = cpuTimesMs.getCountsLocked(which); 6858 if (counts == null) { 6859 return null; 6860 } 6861 // Return counts only if at least one of the elements is non-zero. 6862 for (int i = counts.length - 1; i >= 0; --i) { 6863 if (counts[i] != 0) { 6864 return counts; 6865 } 6866 } 6867 return null; 6868 } 6869 addProcStateTimesMs(int procState, long[] cpuTimesMs, boolean onBattery)6870 private void addProcStateTimesMs(int procState, long[] cpuTimesMs, boolean onBattery) { 6871 if (mProcStateTimeMs == null) { 6872 mProcStateTimeMs = new LongSamplingCounterArray[NUM_PROCESS_STATE]; 6873 } 6874 if (mProcStateTimeMs[procState] == null 6875 || mProcStateTimeMs[procState].getSize() != cpuTimesMs.length) { 6876 detachIfNotNull(mProcStateTimeMs[procState]); 6877 mProcStateTimeMs[procState] = new LongSamplingCounterArray( 6878 mBsi.mOnBatteryTimeBase); 6879 } 6880 mProcStateTimeMs[procState].addCountLocked(cpuTimesMs, onBattery); 6881 } 6882 addProcStateScreenOffTimesMs(int procState, long[] cpuTimesMs, boolean onBatteryScreenOff)6883 private void addProcStateScreenOffTimesMs(int procState, long[] cpuTimesMs, 6884 boolean onBatteryScreenOff) { 6885 if (mProcStateScreenOffTimeMs == null) { 6886 mProcStateScreenOffTimeMs = new LongSamplingCounterArray[NUM_PROCESS_STATE]; 6887 } 6888 if (mProcStateScreenOffTimeMs[procState] == null 6889 || mProcStateScreenOffTimeMs[procState].getSize() != cpuTimesMs.length) { 6890 detachIfNotNull(mProcStateScreenOffTimeMs[procState]); 6891 mProcStateScreenOffTimeMs[procState] = new LongSamplingCounterArray( 6892 mBsi.mOnBatteryScreenOffTimeBase); 6893 } 6894 mProcStateScreenOffTimeMs[procState].addCountLocked(cpuTimesMs, onBatteryScreenOff); 6895 } 6896 6897 @Override getAggregatedPartialWakelockTimer()6898 public Timer getAggregatedPartialWakelockTimer() { 6899 return mAggregatedPartialWakelockTimer; 6900 } 6901 6902 @Override 6903 @UnsupportedAppUsage getWakelockStats()6904 public ArrayMap<String, ? extends BatteryStats.Uid.Wakelock> getWakelockStats() { 6905 return mWakelockStats.getMap(); 6906 } 6907 6908 @Override getMulticastWakelockStats()6909 public Timer getMulticastWakelockStats() { 6910 return mWifiMulticastTimer; 6911 } 6912 6913 @Override getSyncStats()6914 public ArrayMap<String, ? extends BatteryStats.Timer> getSyncStats() { 6915 return mSyncStats.getMap(); 6916 } 6917 6918 @Override getJobStats()6919 public ArrayMap<String, ? extends BatteryStats.Timer> getJobStats() { 6920 return mJobStats.getMap(); 6921 } 6922 6923 @Override getJobCompletionStats()6924 public ArrayMap<String, SparseIntArray> getJobCompletionStats() { 6925 return mJobCompletions; 6926 } 6927 6928 @Override 6929 @UnsupportedAppUsage getSensorStats()6930 public SparseArray<? extends BatteryStats.Uid.Sensor> getSensorStats() { 6931 return mSensorStats; 6932 } 6933 6934 @Override 6935 @UnsupportedAppUsage getProcessStats()6936 public ArrayMap<String, ? extends BatteryStats.Uid.Proc> getProcessStats() { 6937 return mProcessStats; 6938 } 6939 6940 @Override getPackageStats()6941 public ArrayMap<String, ? extends BatteryStats.Uid.Pkg> getPackageStats() { 6942 return mPackageStats; 6943 } 6944 6945 @Override 6946 @UnsupportedAppUsage getUid()6947 public int getUid() { 6948 return mUid; 6949 } 6950 6951 @Override noteWifiRunningLocked(long elapsedRealtimeMs)6952 public void noteWifiRunningLocked(long elapsedRealtimeMs) { 6953 if (!mWifiRunning) { 6954 mWifiRunning = true; 6955 if (mWifiRunningTimer == null) { 6956 mWifiRunningTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, WIFI_RUNNING, 6957 mBsi.mWifiRunningTimers, mBsi.mOnBatteryTimeBase); 6958 } 6959 mWifiRunningTimer.startRunningLocked(elapsedRealtimeMs); 6960 } 6961 } 6962 6963 @Override noteWifiStoppedLocked(long elapsedRealtimeMs)6964 public void noteWifiStoppedLocked(long elapsedRealtimeMs) { 6965 if (mWifiRunning) { 6966 mWifiRunning = false; 6967 mWifiRunningTimer.stopRunningLocked(elapsedRealtimeMs); 6968 } 6969 } 6970 6971 @Override noteFullWifiLockAcquiredLocked(long elapsedRealtimeMs)6972 public void noteFullWifiLockAcquiredLocked(long elapsedRealtimeMs) { 6973 if (!mFullWifiLockOut) { 6974 mFullWifiLockOut = true; 6975 if (mFullWifiLockTimer == null) { 6976 mFullWifiLockTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, FULL_WIFI_LOCK, 6977 mBsi.mFullWifiLockTimers, mBsi.mOnBatteryTimeBase); 6978 } 6979 mFullWifiLockTimer.startRunningLocked(elapsedRealtimeMs); 6980 } 6981 } 6982 6983 @Override noteFullWifiLockReleasedLocked(long elapsedRealtimeMs)6984 public void noteFullWifiLockReleasedLocked(long elapsedRealtimeMs) { 6985 if (mFullWifiLockOut) { 6986 mFullWifiLockOut = false; 6987 mFullWifiLockTimer.stopRunningLocked(elapsedRealtimeMs); 6988 } 6989 } 6990 6991 @Override noteWifiScanStartedLocked(long elapsedRealtimeMs)6992 public void noteWifiScanStartedLocked(long elapsedRealtimeMs) { 6993 if (!mWifiScanStarted) { 6994 mWifiScanStarted = true; 6995 if (mWifiScanTimer == null) { 6996 mWifiScanTimer = new DualTimer(mBsi.mClocks, Uid.this, WIFI_SCAN, 6997 mBsi.mWifiScanTimers, mBsi.mOnBatteryTimeBase, 6998 mOnBatteryBackgroundTimeBase); 6999 } 7000 mWifiScanTimer.startRunningLocked(elapsedRealtimeMs); 7001 } 7002 } 7003 7004 @Override noteWifiScanStoppedLocked(long elapsedRealtimeMs)7005 public void noteWifiScanStoppedLocked(long elapsedRealtimeMs) { 7006 if (mWifiScanStarted) { 7007 mWifiScanStarted = false; 7008 mWifiScanTimer.stopRunningLocked(elapsedRealtimeMs); 7009 } 7010 } 7011 7012 @Override noteWifiBatchedScanStartedLocked(int csph, long elapsedRealtimeMs)7013 public void noteWifiBatchedScanStartedLocked(int csph, long elapsedRealtimeMs) { 7014 int bin = 0; 7015 while (csph > 8 && bin < NUM_WIFI_BATCHED_SCAN_BINS-1) { 7016 csph = csph >> 3; 7017 bin++; 7018 } 7019 7020 if (mWifiBatchedScanBinStarted == bin) return; 7021 7022 if (mWifiBatchedScanBinStarted != NO_BATCHED_SCAN_STARTED) { 7023 mWifiBatchedScanTimer[mWifiBatchedScanBinStarted]. 7024 stopRunningLocked(elapsedRealtimeMs); 7025 } 7026 mWifiBatchedScanBinStarted = bin; 7027 if (mWifiBatchedScanTimer[bin] == null) { 7028 makeWifiBatchedScanBin(bin, null); 7029 } 7030 mWifiBatchedScanTimer[bin].startRunningLocked(elapsedRealtimeMs); 7031 } 7032 7033 @Override noteWifiBatchedScanStoppedLocked(long elapsedRealtimeMs)7034 public void noteWifiBatchedScanStoppedLocked(long elapsedRealtimeMs) { 7035 if (mWifiBatchedScanBinStarted != NO_BATCHED_SCAN_STARTED) { 7036 mWifiBatchedScanTimer[mWifiBatchedScanBinStarted]. 7037 stopRunningLocked(elapsedRealtimeMs); 7038 mWifiBatchedScanBinStarted = NO_BATCHED_SCAN_STARTED; 7039 } 7040 } 7041 7042 @Override noteWifiMulticastEnabledLocked(long elapsedRealtimeMs)7043 public void noteWifiMulticastEnabledLocked(long elapsedRealtimeMs) { 7044 if (mWifiMulticastWakelockCount == 0) { 7045 if (mWifiMulticastTimer == null) { 7046 mWifiMulticastTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, 7047 WIFI_MULTICAST_ENABLED, mBsi.mWifiMulticastTimers, mBsi.mOnBatteryTimeBase); 7048 } 7049 mWifiMulticastTimer.startRunningLocked(elapsedRealtimeMs); 7050 } 7051 mWifiMulticastWakelockCount++; 7052 } 7053 7054 @Override noteWifiMulticastDisabledLocked(long elapsedRealtimeMs)7055 public void noteWifiMulticastDisabledLocked(long elapsedRealtimeMs) { 7056 if (mWifiMulticastWakelockCount == 0) { 7057 return; 7058 } 7059 7060 mWifiMulticastWakelockCount--; 7061 if (mWifiMulticastWakelockCount == 0) { 7062 mWifiMulticastTimer.stopRunningLocked(elapsedRealtimeMs); 7063 } 7064 } 7065 7066 @Override getWifiControllerActivity()7067 public ControllerActivityCounter getWifiControllerActivity() { 7068 return mWifiControllerActivity; 7069 } 7070 7071 @Override getBluetoothControllerActivity()7072 public ControllerActivityCounter getBluetoothControllerActivity() { 7073 return mBluetoothControllerActivity; 7074 } 7075 7076 @Override getModemControllerActivity()7077 public ControllerActivityCounter getModemControllerActivity() { 7078 return mModemControllerActivity; 7079 } 7080 getOrCreateWifiControllerActivityLocked()7081 public ControllerActivityCounterImpl getOrCreateWifiControllerActivityLocked() { 7082 if (mWifiControllerActivity == null) { 7083 mWifiControllerActivity = new ControllerActivityCounterImpl(mBsi.mOnBatteryTimeBase, 7084 NUM_BT_TX_LEVELS); 7085 } 7086 return mWifiControllerActivity; 7087 } 7088 getOrCreateBluetoothControllerActivityLocked()7089 public ControllerActivityCounterImpl getOrCreateBluetoothControllerActivityLocked() { 7090 if (mBluetoothControllerActivity == null) { 7091 mBluetoothControllerActivity = new ControllerActivityCounterImpl(mBsi.mOnBatteryTimeBase, 7092 NUM_BT_TX_LEVELS); 7093 } 7094 return mBluetoothControllerActivity; 7095 } 7096 getOrCreateModemControllerActivityLocked()7097 public ControllerActivityCounterImpl getOrCreateModemControllerActivityLocked() { 7098 if (mModemControllerActivity == null) { 7099 mModemControllerActivity = new ControllerActivityCounterImpl(mBsi.mOnBatteryTimeBase, 7100 ModemActivityInfo.TX_POWER_LEVELS); 7101 } 7102 return mModemControllerActivity; 7103 } 7104 createAudioTurnedOnTimerLocked()7105 public StopwatchTimer createAudioTurnedOnTimerLocked() { 7106 if (mAudioTurnedOnTimer == null) { 7107 mAudioTurnedOnTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, AUDIO_TURNED_ON, 7108 mBsi.mAudioTurnedOnTimers, mBsi.mOnBatteryTimeBase); 7109 } 7110 return mAudioTurnedOnTimer; 7111 } 7112 noteAudioTurnedOnLocked(long elapsedRealtimeMs)7113 public void noteAudioTurnedOnLocked(long elapsedRealtimeMs) { 7114 createAudioTurnedOnTimerLocked().startRunningLocked(elapsedRealtimeMs); 7115 } 7116 noteAudioTurnedOffLocked(long elapsedRealtimeMs)7117 public void noteAudioTurnedOffLocked(long elapsedRealtimeMs) { 7118 if (mAudioTurnedOnTimer != null) { 7119 mAudioTurnedOnTimer.stopRunningLocked(elapsedRealtimeMs); 7120 } 7121 } 7122 noteResetAudioLocked(long elapsedRealtimeMs)7123 public void noteResetAudioLocked(long elapsedRealtimeMs) { 7124 if (mAudioTurnedOnTimer != null) { 7125 mAudioTurnedOnTimer.stopAllRunningLocked(elapsedRealtimeMs); 7126 } 7127 } 7128 createVideoTurnedOnTimerLocked()7129 public StopwatchTimer createVideoTurnedOnTimerLocked() { 7130 if (mVideoTurnedOnTimer == null) { 7131 mVideoTurnedOnTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, VIDEO_TURNED_ON, 7132 mBsi.mVideoTurnedOnTimers, mBsi.mOnBatteryTimeBase); 7133 } 7134 return mVideoTurnedOnTimer; 7135 } 7136 noteVideoTurnedOnLocked(long elapsedRealtimeMs)7137 public void noteVideoTurnedOnLocked(long elapsedRealtimeMs) { 7138 createVideoTurnedOnTimerLocked().startRunningLocked(elapsedRealtimeMs); 7139 } 7140 noteVideoTurnedOffLocked(long elapsedRealtimeMs)7141 public void noteVideoTurnedOffLocked(long elapsedRealtimeMs) { 7142 if (mVideoTurnedOnTimer != null) { 7143 mVideoTurnedOnTimer.stopRunningLocked(elapsedRealtimeMs); 7144 } 7145 } 7146 noteResetVideoLocked(long elapsedRealtimeMs)7147 public void noteResetVideoLocked(long elapsedRealtimeMs) { 7148 if (mVideoTurnedOnTimer != null) { 7149 mVideoTurnedOnTimer.stopAllRunningLocked(elapsedRealtimeMs); 7150 } 7151 } 7152 createFlashlightTurnedOnTimerLocked()7153 public StopwatchTimer createFlashlightTurnedOnTimerLocked() { 7154 if (mFlashlightTurnedOnTimer == null) { 7155 mFlashlightTurnedOnTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, 7156 FLASHLIGHT_TURNED_ON, mBsi.mFlashlightTurnedOnTimers, mBsi.mOnBatteryTimeBase); 7157 } 7158 return mFlashlightTurnedOnTimer; 7159 } 7160 noteFlashlightTurnedOnLocked(long elapsedRealtimeMs)7161 public void noteFlashlightTurnedOnLocked(long elapsedRealtimeMs) { 7162 createFlashlightTurnedOnTimerLocked().startRunningLocked(elapsedRealtimeMs); 7163 } 7164 noteFlashlightTurnedOffLocked(long elapsedRealtimeMs)7165 public void noteFlashlightTurnedOffLocked(long elapsedRealtimeMs) { 7166 if (mFlashlightTurnedOnTimer != null) { 7167 mFlashlightTurnedOnTimer.stopRunningLocked(elapsedRealtimeMs); 7168 } 7169 } 7170 noteResetFlashlightLocked(long elapsedRealtimeMs)7171 public void noteResetFlashlightLocked(long elapsedRealtimeMs) { 7172 if (mFlashlightTurnedOnTimer != null) { 7173 mFlashlightTurnedOnTimer.stopAllRunningLocked(elapsedRealtimeMs); 7174 } 7175 } 7176 createCameraTurnedOnTimerLocked()7177 public StopwatchTimer createCameraTurnedOnTimerLocked() { 7178 if (mCameraTurnedOnTimer == null) { 7179 mCameraTurnedOnTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, CAMERA_TURNED_ON, 7180 mBsi.mCameraTurnedOnTimers, mBsi.mOnBatteryTimeBase); 7181 } 7182 return mCameraTurnedOnTimer; 7183 } 7184 noteCameraTurnedOnLocked(long elapsedRealtimeMs)7185 public void noteCameraTurnedOnLocked(long elapsedRealtimeMs) { 7186 createCameraTurnedOnTimerLocked().startRunningLocked(elapsedRealtimeMs); 7187 } 7188 noteCameraTurnedOffLocked(long elapsedRealtimeMs)7189 public void noteCameraTurnedOffLocked(long elapsedRealtimeMs) { 7190 if (mCameraTurnedOnTimer != null) { 7191 mCameraTurnedOnTimer.stopRunningLocked(elapsedRealtimeMs); 7192 } 7193 } 7194 noteResetCameraLocked(long elapsedRealtimeMs)7195 public void noteResetCameraLocked(long elapsedRealtimeMs) { 7196 if (mCameraTurnedOnTimer != null) { 7197 mCameraTurnedOnTimer.stopAllRunningLocked(elapsedRealtimeMs); 7198 } 7199 } 7200 createForegroundActivityTimerLocked()7201 public StopwatchTimer createForegroundActivityTimerLocked() { 7202 if (mForegroundActivityTimer == null) { 7203 mForegroundActivityTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, 7204 FOREGROUND_ACTIVITY, null, mBsi.mOnBatteryTimeBase); 7205 } 7206 return mForegroundActivityTimer; 7207 } 7208 createForegroundServiceTimerLocked()7209 public StopwatchTimer createForegroundServiceTimerLocked() { 7210 if (mForegroundServiceTimer == null) { 7211 mForegroundServiceTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, 7212 FOREGROUND_SERVICE, null, mBsi.mOnBatteryTimeBase); 7213 } 7214 return mForegroundServiceTimer; 7215 } 7216 createAggregatedPartialWakelockTimerLocked()7217 public DualTimer createAggregatedPartialWakelockTimerLocked() { 7218 if (mAggregatedPartialWakelockTimer == null) { 7219 mAggregatedPartialWakelockTimer = new DualTimer(mBsi.mClocks, this, 7220 AGGREGATED_WAKE_TYPE_PARTIAL, null, 7221 mBsi.mOnBatteryScreenOffTimeBase, mOnBatteryScreenOffBackgroundTimeBase); 7222 } 7223 return mAggregatedPartialWakelockTimer; 7224 } 7225 createBluetoothScanTimerLocked()7226 public DualTimer createBluetoothScanTimerLocked() { 7227 if (mBluetoothScanTimer == null) { 7228 mBluetoothScanTimer = new DualTimer(mBsi.mClocks, Uid.this, BLUETOOTH_SCAN_ON, 7229 mBsi.mBluetoothScanOnTimers, mBsi.mOnBatteryTimeBase, 7230 mOnBatteryBackgroundTimeBase); 7231 } 7232 return mBluetoothScanTimer; 7233 } 7234 createBluetoothUnoptimizedScanTimerLocked()7235 public DualTimer createBluetoothUnoptimizedScanTimerLocked() { 7236 if (mBluetoothUnoptimizedScanTimer == null) { 7237 mBluetoothUnoptimizedScanTimer = new DualTimer(mBsi.mClocks, Uid.this, 7238 BLUETOOTH_UNOPTIMIZED_SCAN_ON, null, 7239 mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase); 7240 } 7241 return mBluetoothUnoptimizedScanTimer; 7242 } 7243 noteBluetoothScanStartedLocked(long elapsedRealtimeMs, boolean isUnoptimized)7244 public void noteBluetoothScanStartedLocked(long elapsedRealtimeMs, 7245 boolean isUnoptimized) { 7246 createBluetoothScanTimerLocked().startRunningLocked(elapsedRealtimeMs); 7247 if (isUnoptimized) { 7248 createBluetoothUnoptimizedScanTimerLocked().startRunningLocked(elapsedRealtimeMs); 7249 } 7250 } 7251 noteBluetoothScanStoppedLocked(long elapsedRealtimeMs, boolean isUnoptimized)7252 public void noteBluetoothScanStoppedLocked(long elapsedRealtimeMs, boolean isUnoptimized) { 7253 if (mBluetoothScanTimer != null) { 7254 mBluetoothScanTimer.stopRunningLocked(elapsedRealtimeMs); 7255 } 7256 if (isUnoptimized && mBluetoothUnoptimizedScanTimer != null) { 7257 mBluetoothUnoptimizedScanTimer.stopRunningLocked(elapsedRealtimeMs); 7258 } 7259 } 7260 noteResetBluetoothScanLocked(long elapsedRealtimeMs)7261 public void noteResetBluetoothScanLocked(long elapsedRealtimeMs) { 7262 if (mBluetoothScanTimer != null) { 7263 mBluetoothScanTimer.stopAllRunningLocked(elapsedRealtimeMs); 7264 } 7265 if (mBluetoothUnoptimizedScanTimer != null) { 7266 mBluetoothUnoptimizedScanTimer.stopAllRunningLocked(elapsedRealtimeMs); 7267 } 7268 } 7269 createBluetoothScanResultCounterLocked()7270 public Counter createBluetoothScanResultCounterLocked() { 7271 if (mBluetoothScanResultCounter == null) { 7272 mBluetoothScanResultCounter = new Counter(mBsi.mOnBatteryTimeBase); 7273 } 7274 return mBluetoothScanResultCounter; 7275 } 7276 createBluetoothScanResultBgCounterLocked()7277 public Counter createBluetoothScanResultBgCounterLocked() { 7278 if (mBluetoothScanResultBgCounter == null) { 7279 mBluetoothScanResultBgCounter = new Counter(mOnBatteryBackgroundTimeBase); 7280 } 7281 return mBluetoothScanResultBgCounter; 7282 } 7283 noteBluetoothScanResultsLocked(int numNewResults)7284 public void noteBluetoothScanResultsLocked(int numNewResults) { 7285 createBluetoothScanResultCounterLocked().addAtomic(numNewResults); 7286 // Uses background timebase, so the count will only be incremented if uid in background. 7287 createBluetoothScanResultBgCounterLocked().addAtomic(numNewResults); 7288 } 7289 7290 @Override noteActivityResumedLocked(long elapsedRealtimeMs)7291 public void noteActivityResumedLocked(long elapsedRealtimeMs) { 7292 // We always start, since we want multiple foreground PIDs to nest 7293 createForegroundActivityTimerLocked().startRunningLocked(elapsedRealtimeMs); 7294 } 7295 7296 @Override noteActivityPausedLocked(long elapsedRealtimeMs)7297 public void noteActivityPausedLocked(long elapsedRealtimeMs) { 7298 if (mForegroundActivityTimer != null) { 7299 mForegroundActivityTimer.stopRunningLocked(elapsedRealtimeMs); 7300 } 7301 } 7302 noteForegroundServiceResumedLocked(long elapsedRealtimeMs)7303 public void noteForegroundServiceResumedLocked(long elapsedRealtimeMs) { 7304 createForegroundServiceTimerLocked().startRunningLocked(elapsedRealtimeMs); 7305 } 7306 noteForegroundServicePausedLocked(long elapsedRealtimeMs)7307 public void noteForegroundServicePausedLocked(long elapsedRealtimeMs) { 7308 if (mForegroundServiceTimer != null) { 7309 mForegroundServiceTimer.stopRunningLocked(elapsedRealtimeMs); 7310 } 7311 } 7312 createVibratorOnTimerLocked()7313 public BatchTimer createVibratorOnTimerLocked() { 7314 if (mVibratorOnTimer == null) { 7315 mVibratorOnTimer = new BatchTimer(mBsi.mClocks, Uid.this, VIBRATOR_ON, 7316 mBsi.mOnBatteryTimeBase); 7317 } 7318 return mVibratorOnTimer; 7319 } 7320 noteVibratorOnLocked(long durationMillis)7321 public void noteVibratorOnLocked(long durationMillis) { 7322 createVibratorOnTimerLocked().addDuration(mBsi, durationMillis); 7323 } 7324 noteVibratorOffLocked()7325 public void noteVibratorOffLocked() { 7326 if (mVibratorOnTimer != null) { 7327 mVibratorOnTimer.abortLastDuration(mBsi); 7328 } 7329 } 7330 7331 @Override 7332 @UnsupportedAppUsage getWifiRunningTime(long elapsedRealtimeUs, int which)7333 public long getWifiRunningTime(long elapsedRealtimeUs, int which) { 7334 if (mWifiRunningTimer == null) { 7335 return 0; 7336 } 7337 return mWifiRunningTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 7338 } 7339 7340 @Override getFullWifiLockTime(long elapsedRealtimeUs, int which)7341 public long getFullWifiLockTime(long elapsedRealtimeUs, int which) { 7342 if (mFullWifiLockTimer == null) { 7343 return 0; 7344 } 7345 return mFullWifiLockTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 7346 } 7347 7348 @Override 7349 @UnsupportedAppUsage getWifiScanTime(long elapsedRealtimeUs, int which)7350 public long getWifiScanTime(long elapsedRealtimeUs, int which) { 7351 if (mWifiScanTimer == null) { 7352 return 0; 7353 } 7354 return mWifiScanTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 7355 } 7356 7357 @Override getWifiScanCount(int which)7358 public int getWifiScanCount(int which) { 7359 if (mWifiScanTimer == null) { 7360 return 0; 7361 } 7362 return mWifiScanTimer.getCountLocked(which); 7363 } 7364 7365 @Override getWifiScanTimer()7366 public Timer getWifiScanTimer() { 7367 return mWifiScanTimer; 7368 } 7369 7370 @Override getWifiScanBackgroundCount(int which)7371 public int getWifiScanBackgroundCount(int which) { 7372 if (mWifiScanTimer == null || mWifiScanTimer.getSubTimer() == null) { 7373 return 0; 7374 } 7375 return mWifiScanTimer.getSubTimer().getCountLocked(which); 7376 } 7377 7378 @Override getWifiScanActualTime(final long elapsedRealtimeUs)7379 public long getWifiScanActualTime(final long elapsedRealtimeUs) { 7380 if (mWifiScanTimer == null) { 7381 return 0; 7382 } 7383 final long elapsedRealtimeMs = (elapsedRealtimeUs + 500) / 1000; 7384 return mWifiScanTimer.getTotalDurationMsLocked(elapsedRealtimeMs) * 1000; 7385 } 7386 7387 @Override getWifiScanBackgroundTime(final long elapsedRealtimeUs)7388 public long getWifiScanBackgroundTime(final long elapsedRealtimeUs) { 7389 if (mWifiScanTimer == null || mWifiScanTimer.getSubTimer() == null) { 7390 return 0; 7391 } 7392 final long elapsedRealtimeMs = (elapsedRealtimeUs + 500) / 1000; 7393 return mWifiScanTimer.getSubTimer().getTotalDurationMsLocked(elapsedRealtimeMs) * 1000; 7394 } 7395 7396 @Override getWifiScanBackgroundTimer()7397 public Timer getWifiScanBackgroundTimer() { 7398 if (mWifiScanTimer == null) { 7399 return null; 7400 } 7401 return mWifiScanTimer.getSubTimer(); 7402 } 7403 7404 @Override getWifiBatchedScanTime(int csphBin, long elapsedRealtimeUs, int which)7405 public long getWifiBatchedScanTime(int csphBin, long elapsedRealtimeUs, int which) { 7406 if (csphBin < 0 || csphBin >= NUM_WIFI_BATCHED_SCAN_BINS) return 0; 7407 if (mWifiBatchedScanTimer[csphBin] == null) { 7408 return 0; 7409 } 7410 return mWifiBatchedScanTimer[csphBin].getTotalTimeLocked(elapsedRealtimeUs, which); 7411 } 7412 7413 @Override getWifiBatchedScanCount(int csphBin, int which)7414 public int getWifiBatchedScanCount(int csphBin, int which) { 7415 if (csphBin < 0 || csphBin >= NUM_WIFI_BATCHED_SCAN_BINS) return 0; 7416 if (mWifiBatchedScanTimer[csphBin] == null) { 7417 return 0; 7418 } 7419 return mWifiBatchedScanTimer[csphBin].getCountLocked(which); 7420 } 7421 7422 @Override getWifiMulticastTime(long elapsedRealtimeUs, int which)7423 public long getWifiMulticastTime(long elapsedRealtimeUs, int which) { 7424 if (mWifiMulticastTimer == null) { 7425 return 0; 7426 } 7427 return mWifiMulticastTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 7428 } 7429 7430 @Override getAudioTurnedOnTimer()7431 public Timer getAudioTurnedOnTimer() { 7432 return mAudioTurnedOnTimer; 7433 } 7434 7435 @Override getVideoTurnedOnTimer()7436 public Timer getVideoTurnedOnTimer() { 7437 return mVideoTurnedOnTimer; 7438 } 7439 7440 @Override getFlashlightTurnedOnTimer()7441 public Timer getFlashlightTurnedOnTimer() { 7442 return mFlashlightTurnedOnTimer; 7443 } 7444 7445 @Override getCameraTurnedOnTimer()7446 public Timer getCameraTurnedOnTimer() { 7447 return mCameraTurnedOnTimer; 7448 } 7449 7450 @Override getForegroundActivityTimer()7451 public Timer getForegroundActivityTimer() { 7452 return mForegroundActivityTimer; 7453 } 7454 7455 @Override getForegroundServiceTimer()7456 public Timer getForegroundServiceTimer() { 7457 return mForegroundServiceTimer; 7458 } 7459 7460 @Override getBluetoothScanTimer()7461 public Timer getBluetoothScanTimer() { 7462 return mBluetoothScanTimer; 7463 } 7464 7465 @Override getBluetoothScanBackgroundTimer()7466 public Timer getBluetoothScanBackgroundTimer() { 7467 if (mBluetoothScanTimer == null) { 7468 return null; 7469 } 7470 return mBluetoothScanTimer.getSubTimer(); 7471 } 7472 7473 @Override getBluetoothUnoptimizedScanTimer()7474 public Timer getBluetoothUnoptimizedScanTimer() { 7475 return mBluetoothUnoptimizedScanTimer; 7476 } 7477 7478 @Override getBluetoothUnoptimizedScanBackgroundTimer()7479 public Timer getBluetoothUnoptimizedScanBackgroundTimer() { 7480 if (mBluetoothUnoptimizedScanTimer == null) { 7481 return null; 7482 } 7483 return mBluetoothUnoptimizedScanTimer.getSubTimer(); 7484 } 7485 7486 @Override getBluetoothScanResultCounter()7487 public Counter getBluetoothScanResultCounter() { 7488 return mBluetoothScanResultCounter; 7489 } 7490 7491 @Override getBluetoothScanResultBgCounter()7492 public Counter getBluetoothScanResultBgCounter() { 7493 return mBluetoothScanResultBgCounter; 7494 } 7495 makeProcessState(int i, Parcel in)7496 void makeProcessState(int i, Parcel in) { 7497 if (i < 0 || i >= NUM_PROCESS_STATE) return; 7498 7499 detachIfNotNull(mProcessStateTimer[i]); 7500 if (in == null) { 7501 mProcessStateTimer[i] = new StopwatchTimer(mBsi.mClocks, this, PROCESS_STATE, null, 7502 mBsi.mOnBatteryTimeBase); 7503 } else { 7504 mProcessStateTimer[i] = new StopwatchTimer(mBsi.mClocks, this, PROCESS_STATE, null, 7505 mBsi.mOnBatteryTimeBase, in); 7506 } 7507 } 7508 7509 @Override getProcessStateTime(int state, long elapsedRealtimeUs, int which)7510 public long getProcessStateTime(int state, long elapsedRealtimeUs, int which) { 7511 if (state < 0 || state >= NUM_PROCESS_STATE) return 0; 7512 if (mProcessStateTimer[state] == null) { 7513 return 0; 7514 } 7515 return mProcessStateTimer[state].getTotalTimeLocked(elapsedRealtimeUs, which); 7516 } 7517 7518 @Override getProcessStateTimer(int state)7519 public Timer getProcessStateTimer(int state) { 7520 if (state < 0 || state >= NUM_PROCESS_STATE) return null; 7521 return mProcessStateTimer[state]; 7522 } 7523 7524 @Override getVibratorOnTimer()7525 public Timer getVibratorOnTimer() { 7526 return mVibratorOnTimer; 7527 } 7528 7529 @Override noteUserActivityLocked(int type)7530 public void noteUserActivityLocked(int type) { 7531 if (mUserActivityCounters == null) { 7532 initUserActivityLocked(); 7533 } 7534 if (type >= 0 && type < NUM_USER_ACTIVITY_TYPES) { 7535 mUserActivityCounters[type].stepAtomic(); 7536 } else { 7537 Slog.w(TAG, "Unknown user activity type " + type + " was specified.", 7538 new Throwable()); 7539 } 7540 } 7541 7542 @Override hasUserActivity()7543 public boolean hasUserActivity() { 7544 return mUserActivityCounters != null; 7545 } 7546 7547 @Override getUserActivityCount(int type, int which)7548 public int getUserActivityCount(int type, int which) { 7549 if (mUserActivityCounters == null) { 7550 return 0; 7551 } 7552 return mUserActivityCounters[type].getCountLocked(which); 7553 } 7554 makeWifiBatchedScanBin(int i, Parcel in)7555 void makeWifiBatchedScanBin(int i, Parcel in) { 7556 if (i < 0 || i >= NUM_WIFI_BATCHED_SCAN_BINS) return; 7557 7558 ArrayList<StopwatchTimer> collected = mBsi.mWifiBatchedScanTimers.get(i); 7559 if (collected == null) { 7560 collected = new ArrayList<StopwatchTimer>(); 7561 mBsi.mWifiBatchedScanTimers.put(i, collected); 7562 } 7563 detachIfNotNull(mWifiBatchedScanTimer[i]); 7564 if (in == null) { 7565 mWifiBatchedScanTimer[i] = new StopwatchTimer(mBsi.mClocks, this, WIFI_BATCHED_SCAN, 7566 collected, mBsi.mOnBatteryTimeBase); 7567 } else { 7568 mWifiBatchedScanTimer[i] = new StopwatchTimer(mBsi.mClocks, this, WIFI_BATCHED_SCAN, 7569 collected, mBsi.mOnBatteryTimeBase, in); 7570 } 7571 } 7572 7573 initUserActivityLocked()7574 void initUserActivityLocked() { 7575 detachIfNotNull(mUserActivityCounters); 7576 mUserActivityCounters = new Counter[NUM_USER_ACTIVITY_TYPES]; 7577 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) { 7578 mUserActivityCounters[i] = new Counter(mBsi.mOnBatteryTimeBase); 7579 } 7580 } 7581 noteNetworkActivityLocked(int type, long deltaBytes, long deltaPackets)7582 void noteNetworkActivityLocked(int type, long deltaBytes, long deltaPackets) { 7583 if (mNetworkByteActivityCounters == null) { 7584 initNetworkActivityLocked(); 7585 } 7586 if (type >= 0 && type < NUM_NETWORK_ACTIVITY_TYPES) { 7587 mNetworkByteActivityCounters[type].addCountLocked(deltaBytes); 7588 mNetworkPacketActivityCounters[type].addCountLocked(deltaPackets); 7589 } else { 7590 Slog.w(TAG, "Unknown network activity type " + type + " was specified.", 7591 new Throwable()); 7592 } 7593 } 7594 noteMobileRadioActiveTimeLocked(long batteryUptime)7595 void noteMobileRadioActiveTimeLocked(long batteryUptime) { 7596 if (mNetworkByteActivityCounters == null) { 7597 initNetworkActivityLocked(); 7598 } 7599 mMobileRadioActiveTime.addCountLocked(batteryUptime); 7600 mMobileRadioActiveCount.addCountLocked(1); 7601 } 7602 7603 @Override hasNetworkActivity()7604 public boolean hasNetworkActivity() { 7605 return mNetworkByteActivityCounters != null; 7606 } 7607 7608 @Override getNetworkActivityBytes(int type, int which)7609 public long getNetworkActivityBytes(int type, int which) { 7610 if (mNetworkByteActivityCounters != null && type >= 0 7611 && type < mNetworkByteActivityCounters.length) { 7612 return mNetworkByteActivityCounters[type].getCountLocked(which); 7613 } else { 7614 return 0; 7615 } 7616 } 7617 7618 @Override getNetworkActivityPackets(int type, int which)7619 public long getNetworkActivityPackets(int type, int which) { 7620 if (mNetworkPacketActivityCounters != null && type >= 0 7621 && type < mNetworkPacketActivityCounters.length) { 7622 return mNetworkPacketActivityCounters[type].getCountLocked(which); 7623 } else { 7624 return 0; 7625 } 7626 } 7627 7628 @Override getMobileRadioActiveTime(int which)7629 public long getMobileRadioActiveTime(int which) { 7630 return mMobileRadioActiveTime != null 7631 ? mMobileRadioActiveTime.getCountLocked(which) : 0; 7632 } 7633 7634 @Override getMobileRadioActiveCount(int which)7635 public int getMobileRadioActiveCount(int which) { 7636 return mMobileRadioActiveCount != null 7637 ? (int)mMobileRadioActiveCount.getCountLocked(which) : 0; 7638 } 7639 7640 @Override getUserCpuTimeUs(int which)7641 public long getUserCpuTimeUs(int which) { 7642 return mUserCpuTime.getCountLocked(which); 7643 } 7644 7645 @Override getSystemCpuTimeUs(int which)7646 public long getSystemCpuTimeUs(int which) { 7647 return mSystemCpuTime.getCountLocked(which); 7648 } 7649 7650 @Override getTimeAtCpuSpeed(int cluster, int step, int which)7651 public long getTimeAtCpuSpeed(int cluster, int step, int which) { 7652 if (mCpuClusterSpeedTimesUs != null) { 7653 if (cluster >= 0 && cluster < mCpuClusterSpeedTimesUs.length) { 7654 final LongSamplingCounter[] cpuSpeedTimesUs = mCpuClusterSpeedTimesUs[cluster]; 7655 if (cpuSpeedTimesUs != null) { 7656 if (step >= 0 && step < cpuSpeedTimesUs.length) { 7657 final LongSamplingCounter c = cpuSpeedTimesUs[step]; 7658 if (c != null) { 7659 return c.getCountLocked(which); 7660 } 7661 } 7662 } 7663 } 7664 } 7665 return 0; 7666 } 7667 noteMobileRadioApWakeupLocked()7668 public void noteMobileRadioApWakeupLocked() { 7669 if (mMobileRadioApWakeupCount == null) { 7670 mMobileRadioApWakeupCount = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); 7671 } 7672 mMobileRadioApWakeupCount.addCountLocked(1); 7673 } 7674 7675 @Override getMobileRadioApWakeupCount(int which)7676 public long getMobileRadioApWakeupCount(int which) { 7677 if (mMobileRadioApWakeupCount != null) { 7678 return mMobileRadioApWakeupCount.getCountLocked(which); 7679 } 7680 return 0; 7681 } 7682 noteWifiRadioApWakeupLocked()7683 public void noteWifiRadioApWakeupLocked() { 7684 if (mWifiRadioApWakeupCount == null) { 7685 mWifiRadioApWakeupCount = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); 7686 } 7687 mWifiRadioApWakeupCount.addCountLocked(1); 7688 } 7689 7690 @Override getWifiRadioApWakeupCount(int which)7691 public long getWifiRadioApWakeupCount(int which) { 7692 if (mWifiRadioApWakeupCount != null) { 7693 return mWifiRadioApWakeupCount.getCountLocked(which); 7694 } 7695 return 0; 7696 } 7697 7698 @Override getDeferredJobsCheckinLineLocked(StringBuilder sb, int which)7699 public void getDeferredJobsCheckinLineLocked(StringBuilder sb, int which) { 7700 sb.setLength(0); 7701 final int deferredEventCount = mJobsDeferredEventCount.getCountLocked(which); 7702 if (deferredEventCount == 0) { 7703 return; 7704 } 7705 final int deferredCount = mJobsDeferredCount.getCountLocked(which); 7706 final long totalLatency = mJobsFreshnessTimeMs.getCountLocked(which); 7707 sb.append(deferredEventCount); sb.append(','); 7708 sb.append(deferredCount); sb.append(','); 7709 sb.append(totalLatency); 7710 for (int i = 0; i < JOB_FRESHNESS_BUCKETS.length; i++) { 7711 if (mJobsFreshnessBuckets[i] == null) { 7712 sb.append(",0"); 7713 } else { 7714 sb.append(","); 7715 sb.append(mJobsFreshnessBuckets[i].getCountLocked(which)); 7716 } 7717 } 7718 } 7719 7720 @Override getDeferredJobsLineLocked(StringBuilder sb, int which)7721 public void getDeferredJobsLineLocked(StringBuilder sb, int which) { 7722 sb.setLength(0); 7723 final int deferredEventCount = mJobsDeferredEventCount.getCountLocked(which); 7724 if (deferredEventCount == 0) { 7725 return; 7726 } 7727 final int deferredCount = mJobsDeferredCount.getCountLocked(which); 7728 final long totalLatency = mJobsFreshnessTimeMs.getCountLocked(which); 7729 sb.append("times="); sb.append(deferredEventCount); sb.append(", "); 7730 sb.append("count="); sb.append(deferredCount); sb.append(", "); 7731 sb.append("totalLatencyMs="); sb.append(totalLatency); sb.append(", "); 7732 for (int i = 0; i < JOB_FRESHNESS_BUCKETS.length; i++) { 7733 sb.append("<"); sb.append(JOB_FRESHNESS_BUCKETS[i]); sb.append("ms="); 7734 if (mJobsFreshnessBuckets[i] == null) { 7735 sb.append("0"); 7736 } else { 7737 sb.append(mJobsFreshnessBuckets[i].getCountLocked(which)); 7738 } 7739 sb.append(" "); 7740 } 7741 } 7742 initNetworkActivityLocked()7743 void initNetworkActivityLocked() { 7744 detachIfNotNull(mNetworkByteActivityCounters); 7745 mNetworkByteActivityCounters = new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES]; 7746 detachIfNotNull(mNetworkPacketActivityCounters); 7747 mNetworkPacketActivityCounters = new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES]; 7748 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 7749 mNetworkByteActivityCounters[i] = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); 7750 mNetworkPacketActivityCounters[i] = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); 7751 } 7752 detachIfNotNull(mMobileRadioActiveTime); 7753 mMobileRadioActiveTime = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); 7754 detachIfNotNull(mMobileRadioActiveCount); 7755 mMobileRadioActiveCount = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); 7756 } 7757 7758 /** 7759 * Clear all stats for this uid. Returns true if the uid is completely 7760 * inactive so can be dropped. 7761 */ 7762 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) reset(long uptime, long realtime)7763 public boolean reset(long uptime, long realtime) { 7764 boolean active = false; 7765 7766 mOnBatteryBackgroundTimeBase.init(uptime, realtime); 7767 mOnBatteryScreenOffBackgroundTimeBase.init(uptime, realtime); 7768 7769 if (mWifiRunningTimer != null) { 7770 active |= !mWifiRunningTimer.reset(false); 7771 active |= mWifiRunning; 7772 } 7773 if (mFullWifiLockTimer != null) { 7774 active |= !mFullWifiLockTimer.reset(false); 7775 active |= mFullWifiLockOut; 7776 } 7777 if (mWifiScanTimer != null) { 7778 active |= !mWifiScanTimer.reset(false); 7779 active |= mWifiScanStarted; 7780 } 7781 if (mWifiBatchedScanTimer != null) { 7782 for (int i = 0; i < NUM_WIFI_BATCHED_SCAN_BINS; i++) { 7783 if (mWifiBatchedScanTimer[i] != null) { 7784 active |= !mWifiBatchedScanTimer[i].reset(false); 7785 } 7786 } 7787 active |= (mWifiBatchedScanBinStarted != NO_BATCHED_SCAN_STARTED); 7788 } 7789 if (mWifiMulticastTimer != null) { 7790 active |= !mWifiMulticastTimer.reset(false); 7791 active |= (mWifiMulticastWakelockCount > 0); 7792 } 7793 7794 active |= !resetIfNotNull(mAudioTurnedOnTimer, false); 7795 active |= !resetIfNotNull(mVideoTurnedOnTimer, false); 7796 active |= !resetIfNotNull(mFlashlightTurnedOnTimer, false); 7797 active |= !resetIfNotNull(mCameraTurnedOnTimer, false); 7798 active |= !resetIfNotNull(mForegroundActivityTimer, false); 7799 active |= !resetIfNotNull(mForegroundServiceTimer, false); 7800 active |= !resetIfNotNull(mAggregatedPartialWakelockTimer, false); 7801 active |= !resetIfNotNull(mBluetoothScanTimer, false); 7802 active |= !resetIfNotNull(mBluetoothUnoptimizedScanTimer, false); 7803 7804 resetIfNotNull(mBluetoothScanResultCounter, false); 7805 resetIfNotNull(mBluetoothScanResultBgCounter, false); 7806 7807 if (mProcessStateTimer != null) { 7808 for (int i = 0; i < NUM_PROCESS_STATE; i++) { 7809 active |= !resetIfNotNull(mProcessStateTimer[i], false); 7810 } 7811 active |= (mProcessState != ActivityManager.PROCESS_STATE_NONEXISTENT); 7812 } 7813 if (mVibratorOnTimer != null) { 7814 if (mVibratorOnTimer.reset(false)) { 7815 mVibratorOnTimer.detach(); 7816 mVibratorOnTimer = null; 7817 } else { 7818 active = true; 7819 } 7820 } 7821 7822 resetIfNotNull(mUserActivityCounters, false); 7823 7824 resetIfNotNull(mNetworkByteActivityCounters, false); 7825 resetIfNotNull(mNetworkPacketActivityCounters, false); 7826 resetIfNotNull(mMobileRadioActiveTime, false); 7827 resetIfNotNull(mMobileRadioActiveCount, false); 7828 7829 resetIfNotNull(mWifiControllerActivity, false); 7830 resetIfNotNull(mBluetoothControllerActivity, false); 7831 resetIfNotNull(mModemControllerActivity, false); 7832 7833 resetIfNotNull(mUserCpuTime, false); 7834 resetIfNotNull(mSystemCpuTime, false); 7835 7836 resetIfNotNull(mCpuClusterSpeedTimesUs, false); 7837 7838 resetIfNotNull(mCpuFreqTimeMs, false); 7839 resetIfNotNull(mScreenOffCpuFreqTimeMs, false); 7840 7841 7842 resetIfNotNull(mCpuActiveTimeMs, false); 7843 resetIfNotNull(mCpuClusterTimesMs, false); 7844 7845 resetIfNotNull(mProcStateTimeMs, false); 7846 7847 resetIfNotNull(mProcStateScreenOffTimeMs, false); 7848 7849 resetIfNotNull(mMobileRadioApWakeupCount, false); 7850 7851 resetIfNotNull(mWifiRadioApWakeupCount, false); 7852 7853 7854 final ArrayMap<String, Wakelock> wakeStats = mWakelockStats.getMap(); 7855 for (int iw=wakeStats.size()-1; iw>=0; iw--) { 7856 Wakelock wl = wakeStats.valueAt(iw); 7857 if (wl.reset()) { 7858 wakeStats.removeAt(iw); 7859 } else { 7860 active = true; 7861 } 7862 } 7863 mWakelockStats.cleanup(); 7864 final ArrayMap<String, DualTimer> syncStats = mSyncStats.getMap(); 7865 for (int is=syncStats.size()-1; is>=0; is--) { 7866 DualTimer timer = syncStats.valueAt(is); 7867 if (timer.reset(false)) { 7868 syncStats.removeAt(is); 7869 timer.detach(); 7870 } else { 7871 active = true; 7872 } 7873 } 7874 mSyncStats.cleanup(); 7875 final ArrayMap<String, DualTimer> jobStats = mJobStats.getMap(); 7876 for (int ij=jobStats.size()-1; ij>=0; ij--) { 7877 DualTimer timer = jobStats.valueAt(ij); 7878 if (timer.reset(false)) { 7879 jobStats.removeAt(ij); 7880 timer.detach(); 7881 } else { 7882 active = true; 7883 } 7884 } 7885 mJobStats.cleanup(); 7886 mJobCompletions.clear(); 7887 7888 resetIfNotNull(mJobsDeferredEventCount, false); 7889 resetIfNotNull(mJobsDeferredCount, false); 7890 resetIfNotNull(mJobsFreshnessTimeMs, false); 7891 resetIfNotNull(mJobsFreshnessBuckets, false); 7892 7893 for (int ise = mSensorStats.size() - 1; ise >= 0; ise--) { 7894 Sensor s = mSensorStats.valueAt(ise); 7895 if (s.reset()) { 7896 mSensorStats.removeAt(ise); 7897 } else { 7898 active = true; 7899 } 7900 } 7901 7902 for (int ip = mProcessStats.size() - 1; ip >= 0; ip--) { 7903 Proc proc = mProcessStats.valueAt(ip); 7904 proc.detach(); 7905 } 7906 mProcessStats.clear(); 7907 7908 for (int i = mPids.size() - 1; i >= 0; i--) { 7909 Pid pid = mPids.valueAt(i); 7910 if (pid.mWakeNesting > 0) { 7911 active = true; 7912 } else { 7913 mPids.removeAt(i); 7914 } 7915 } 7916 7917 7918 for(int i = mPackageStats.size() - 1; i >= 0; i--) { 7919 Pkg p = mPackageStats.valueAt(i); 7920 p.detach(); 7921 } 7922 mPackageStats.clear(); 7923 7924 mLastStepUserTime = mLastStepSystemTime = 0; 7925 mCurStepUserTime = mCurStepSystemTime = 0; 7926 7927 return !active; 7928 } 7929 7930 /** 7931 * This method MUST be called whenever the Uid object is destructed, otherwise it is a 7932 * memory leak in {@link TimeBase#mObservers} list. 7933 * Typically the Uid object is destructed when it is removed from 7934 * {@link BatteryStatsImpl#mUidStats} 7935 */ detachFromTimeBase()7936 void detachFromTimeBase() { 7937 detachIfNotNull(mWifiRunningTimer); 7938 detachIfNotNull(mFullWifiLockTimer); 7939 detachIfNotNull(mWifiScanTimer); 7940 detachIfNotNull(mWifiBatchedScanTimer); 7941 detachIfNotNull(mWifiMulticastTimer); 7942 detachIfNotNull(mAudioTurnedOnTimer); 7943 detachIfNotNull(mVideoTurnedOnTimer); 7944 detachIfNotNull(mFlashlightTurnedOnTimer); 7945 7946 detachIfNotNull(mCameraTurnedOnTimer); 7947 detachIfNotNull(mForegroundActivityTimer); 7948 detachIfNotNull(mForegroundServiceTimer); 7949 7950 detachIfNotNull(mAggregatedPartialWakelockTimer); 7951 7952 detachIfNotNull(mBluetoothScanTimer); 7953 detachIfNotNull(mBluetoothUnoptimizedScanTimer); 7954 detachIfNotNull(mBluetoothScanResultCounter); 7955 detachIfNotNull(mBluetoothScanResultBgCounter); 7956 7957 detachIfNotNull(mProcessStateTimer); 7958 7959 detachIfNotNull(mVibratorOnTimer); 7960 7961 detachIfNotNull(mUserActivityCounters); 7962 7963 detachIfNotNull(mNetworkByteActivityCounters); 7964 detachIfNotNull(mNetworkPacketActivityCounters); 7965 7966 detachIfNotNull(mMobileRadioActiveTime); 7967 detachIfNotNull(mMobileRadioActiveCount); 7968 detachIfNotNull(mMobileRadioApWakeupCount); 7969 detachIfNotNull(mWifiRadioApWakeupCount); 7970 7971 detachIfNotNull(mWifiControllerActivity); 7972 detachIfNotNull(mBluetoothControllerActivity); 7973 detachIfNotNull(mModemControllerActivity); 7974 7975 mPids.clear(); 7976 7977 detachIfNotNull(mUserCpuTime); 7978 detachIfNotNull(mSystemCpuTime); 7979 7980 detachIfNotNull(mCpuClusterSpeedTimesUs); 7981 7982 detachIfNotNull(mCpuActiveTimeMs); 7983 detachIfNotNull(mCpuFreqTimeMs); 7984 7985 detachIfNotNull(mScreenOffCpuFreqTimeMs); 7986 7987 detachIfNotNull(mCpuClusterTimesMs); 7988 7989 detachIfNotNull(mProcStateTimeMs); 7990 7991 detachIfNotNull(mProcStateScreenOffTimeMs); 7992 7993 final ArrayMap<String, Wakelock> wakeStats = mWakelockStats.getMap(); 7994 for (int iw = wakeStats.size() - 1; iw >= 0; iw--) { 7995 Wakelock wl = wakeStats.valueAt(iw); 7996 wl.detachFromTimeBase(); 7997 } 7998 final ArrayMap<String, DualTimer> syncStats = mSyncStats.getMap(); 7999 for (int is = syncStats.size() - 1; is >= 0; is--) { 8000 DualTimer timer = syncStats.valueAt(is); 8001 detachIfNotNull(timer); 8002 } 8003 final ArrayMap<String, DualTimer> jobStats = mJobStats.getMap(); 8004 for (int ij = jobStats.size() - 1; ij >= 0; ij--) { 8005 DualTimer timer = jobStats.valueAt(ij); 8006 detachIfNotNull(timer); 8007 } 8008 8009 detachIfNotNull(mJobsDeferredEventCount); 8010 detachIfNotNull(mJobsDeferredCount); 8011 detachIfNotNull(mJobsFreshnessTimeMs); 8012 detachIfNotNull(mJobsFreshnessBuckets); 8013 8014 8015 for (int ise = mSensorStats.size() - 1; ise >= 0; ise--) { 8016 Sensor s = mSensorStats.valueAt(ise); 8017 s.detachFromTimeBase(); 8018 } 8019 8020 for (int ip= mProcessStats.size() - 1; ip >= 0; ip--) { 8021 Proc proc = mProcessStats.valueAt(ip); 8022 proc.detach(); 8023 } 8024 mProcessStats.clear(); 8025 8026 for(int i = mPackageStats.size() - 1; i >= 0; i--) { 8027 Pkg p = mPackageStats.valueAt(i); 8028 p.detach(); 8029 } 8030 mPackageStats.clear(); 8031 } 8032 writeJobCompletionsToParcelLocked(Parcel out)8033 void writeJobCompletionsToParcelLocked(Parcel out) { 8034 int NJC = mJobCompletions.size(); 8035 out.writeInt(NJC); 8036 for (int ijc=0; ijc<NJC; ijc++) { 8037 out.writeString(mJobCompletions.keyAt(ijc)); 8038 SparseIntArray types = mJobCompletions.valueAt(ijc); 8039 int NT = types.size(); 8040 out.writeInt(NT); 8041 for (int it=0; it<NT; it++) { 8042 out.writeInt(types.keyAt(it)); 8043 out.writeInt(types.valueAt(it)); 8044 } 8045 } 8046 } 8047 writeToParcelLocked(Parcel out, long uptimeUs, long elapsedRealtimeUs)8048 void writeToParcelLocked(Parcel out, long uptimeUs, long elapsedRealtimeUs) { 8049 mOnBatteryBackgroundTimeBase.writeToParcel(out, uptimeUs, elapsedRealtimeUs); 8050 mOnBatteryScreenOffBackgroundTimeBase.writeToParcel(out, uptimeUs, elapsedRealtimeUs); 8051 8052 final ArrayMap<String, Wakelock> wakeStats = mWakelockStats.getMap(); 8053 int NW = wakeStats.size(); 8054 out.writeInt(NW); 8055 for (int iw=0; iw<NW; iw++) { 8056 out.writeString(wakeStats.keyAt(iw)); 8057 Uid.Wakelock wakelock = wakeStats.valueAt(iw); 8058 wakelock.writeToParcelLocked(out, elapsedRealtimeUs); 8059 } 8060 8061 final ArrayMap<String, DualTimer> syncStats = mSyncStats.getMap(); 8062 int NS = syncStats.size(); 8063 out.writeInt(NS); 8064 for (int is=0; is<NS; is++) { 8065 out.writeString(syncStats.keyAt(is)); 8066 DualTimer timer = syncStats.valueAt(is); 8067 Timer.writeTimerToParcel(out, timer, elapsedRealtimeUs); 8068 } 8069 8070 final ArrayMap<String, DualTimer> jobStats = mJobStats.getMap(); 8071 int NJ = jobStats.size(); 8072 out.writeInt(NJ); 8073 for (int ij=0; ij<NJ; ij++) { 8074 out.writeString(jobStats.keyAt(ij)); 8075 DualTimer timer = jobStats.valueAt(ij); 8076 Timer.writeTimerToParcel(out, timer, elapsedRealtimeUs); 8077 } 8078 8079 writeJobCompletionsToParcelLocked(out); 8080 8081 mJobsDeferredEventCount.writeToParcel(out); 8082 mJobsDeferredCount.writeToParcel(out); 8083 mJobsFreshnessTimeMs.writeToParcel(out); 8084 for (int i = 0; i < JOB_FRESHNESS_BUCKETS.length; i++) { 8085 Counter.writeCounterToParcel(out, mJobsFreshnessBuckets[i]); 8086 } 8087 8088 int NSE = mSensorStats.size(); 8089 out.writeInt(NSE); 8090 for (int ise=0; ise<NSE; ise++) { 8091 out.writeInt(mSensorStats.keyAt(ise)); 8092 Uid.Sensor sensor = mSensorStats.valueAt(ise); 8093 sensor.writeToParcelLocked(out, elapsedRealtimeUs); 8094 } 8095 8096 int NP = mProcessStats.size(); 8097 out.writeInt(NP); 8098 for (int ip=0; ip<NP; ip++) { 8099 out.writeString(mProcessStats.keyAt(ip)); 8100 Uid.Proc proc = mProcessStats.valueAt(ip); 8101 proc.writeToParcelLocked(out); 8102 } 8103 8104 out.writeInt(mPackageStats.size()); 8105 for (Map.Entry<String, Uid.Pkg> pkgEntry : mPackageStats.entrySet()) { 8106 out.writeString(pkgEntry.getKey()); 8107 Uid.Pkg pkg = pkgEntry.getValue(); 8108 pkg.writeToParcelLocked(out); 8109 } 8110 8111 if (mWifiRunningTimer != null) { 8112 out.writeInt(1); 8113 mWifiRunningTimer.writeToParcel(out, elapsedRealtimeUs); 8114 } else { 8115 out.writeInt(0); 8116 } 8117 if (mFullWifiLockTimer != null) { 8118 out.writeInt(1); 8119 mFullWifiLockTimer.writeToParcel(out, elapsedRealtimeUs); 8120 } else { 8121 out.writeInt(0); 8122 } 8123 if (mWifiScanTimer != null) { 8124 out.writeInt(1); 8125 mWifiScanTimer.writeToParcel(out, elapsedRealtimeUs); 8126 } else { 8127 out.writeInt(0); 8128 } 8129 for (int i = 0; i < NUM_WIFI_BATCHED_SCAN_BINS; i++) { 8130 if (mWifiBatchedScanTimer[i] != null) { 8131 out.writeInt(1); 8132 mWifiBatchedScanTimer[i].writeToParcel(out, elapsedRealtimeUs); 8133 } else { 8134 out.writeInt(0); 8135 } 8136 } 8137 if (mWifiMulticastTimer != null) { 8138 out.writeInt(1); 8139 mWifiMulticastTimer.writeToParcel(out, elapsedRealtimeUs); 8140 } else { 8141 out.writeInt(0); 8142 } 8143 8144 if (mAudioTurnedOnTimer != null) { 8145 out.writeInt(1); 8146 mAudioTurnedOnTimer.writeToParcel(out, elapsedRealtimeUs); 8147 } else { 8148 out.writeInt(0); 8149 } 8150 if (mVideoTurnedOnTimer != null) { 8151 out.writeInt(1); 8152 mVideoTurnedOnTimer.writeToParcel(out, elapsedRealtimeUs); 8153 } else { 8154 out.writeInt(0); 8155 } 8156 if (mFlashlightTurnedOnTimer != null) { 8157 out.writeInt(1); 8158 mFlashlightTurnedOnTimer.writeToParcel(out, elapsedRealtimeUs); 8159 } else { 8160 out.writeInt(0); 8161 } 8162 if (mCameraTurnedOnTimer != null) { 8163 out.writeInt(1); 8164 mCameraTurnedOnTimer.writeToParcel(out, elapsedRealtimeUs); 8165 } else { 8166 out.writeInt(0); 8167 } 8168 if (mForegroundActivityTimer != null) { 8169 out.writeInt(1); 8170 mForegroundActivityTimer.writeToParcel(out, elapsedRealtimeUs); 8171 } else { 8172 out.writeInt(0); 8173 } 8174 if (mForegroundServiceTimer != null) { 8175 out.writeInt(1); 8176 mForegroundServiceTimer.writeToParcel(out, elapsedRealtimeUs); 8177 } else { 8178 out.writeInt(0); 8179 } 8180 if (mAggregatedPartialWakelockTimer != null) { 8181 out.writeInt(1); 8182 mAggregatedPartialWakelockTimer.writeToParcel(out, elapsedRealtimeUs); 8183 } else { 8184 out.writeInt(0); 8185 } 8186 if (mBluetoothScanTimer != null) { 8187 out.writeInt(1); 8188 mBluetoothScanTimer.writeToParcel(out, elapsedRealtimeUs); 8189 } else { 8190 out.writeInt(0); 8191 } 8192 if (mBluetoothUnoptimizedScanTimer != null) { 8193 out.writeInt(1); 8194 mBluetoothUnoptimizedScanTimer.writeToParcel(out, elapsedRealtimeUs); 8195 } else { 8196 out.writeInt(0); 8197 } 8198 if (mBluetoothScanResultCounter != null) { 8199 out.writeInt(1); 8200 mBluetoothScanResultCounter.writeToParcel(out); 8201 } else { 8202 out.writeInt(0); 8203 } 8204 if (mBluetoothScanResultBgCounter != null) { 8205 out.writeInt(1); 8206 mBluetoothScanResultBgCounter.writeToParcel(out); 8207 } else { 8208 out.writeInt(0); 8209 } 8210 for (int i = 0; i < NUM_PROCESS_STATE; i++) { 8211 if (mProcessStateTimer[i] != null) { 8212 out.writeInt(1); 8213 mProcessStateTimer[i].writeToParcel(out, elapsedRealtimeUs); 8214 } else { 8215 out.writeInt(0); 8216 } 8217 } 8218 if (mVibratorOnTimer != null) { 8219 out.writeInt(1); 8220 mVibratorOnTimer.writeToParcel(out, elapsedRealtimeUs); 8221 } else { 8222 out.writeInt(0); 8223 } 8224 if (mUserActivityCounters != null) { 8225 out.writeInt(1); 8226 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) { 8227 mUserActivityCounters[i].writeToParcel(out); 8228 } 8229 } else { 8230 out.writeInt(0); 8231 } 8232 if (mNetworkByteActivityCounters != null) { 8233 out.writeInt(1); 8234 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 8235 mNetworkByteActivityCounters[i].writeToParcel(out); 8236 mNetworkPacketActivityCounters[i].writeToParcel(out); 8237 } 8238 mMobileRadioActiveTime.writeToParcel(out); 8239 mMobileRadioActiveCount.writeToParcel(out); 8240 } else { 8241 out.writeInt(0); 8242 } 8243 8244 if (mWifiControllerActivity != null) { 8245 out.writeInt(1); 8246 mWifiControllerActivity.writeToParcel(out, 0); 8247 } else { 8248 out.writeInt(0); 8249 } 8250 8251 if (mBluetoothControllerActivity != null) { 8252 out.writeInt(1); 8253 mBluetoothControllerActivity.writeToParcel(out, 0); 8254 } else { 8255 out.writeInt(0); 8256 } 8257 8258 if (mModemControllerActivity != null) { 8259 out.writeInt(1); 8260 mModemControllerActivity.writeToParcel(out, 0); 8261 } else { 8262 out.writeInt(0); 8263 } 8264 8265 mUserCpuTime.writeToParcel(out); 8266 mSystemCpuTime.writeToParcel(out); 8267 8268 if (mCpuClusterSpeedTimesUs != null) { 8269 out.writeInt(1); 8270 out.writeInt(mCpuClusterSpeedTimesUs.length); 8271 for (LongSamplingCounter[] cpuSpeeds : mCpuClusterSpeedTimesUs) { 8272 if (cpuSpeeds != null) { 8273 out.writeInt(1); 8274 out.writeInt(cpuSpeeds.length); 8275 for (LongSamplingCounter c : cpuSpeeds) { 8276 if (c != null) { 8277 out.writeInt(1); 8278 c.writeToParcel(out); 8279 } else { 8280 out.writeInt(0); 8281 } 8282 } 8283 } else { 8284 out.writeInt(0); 8285 } 8286 } 8287 } else { 8288 out.writeInt(0); 8289 } 8290 8291 LongSamplingCounterArray.writeToParcel(out, mCpuFreqTimeMs); 8292 LongSamplingCounterArray.writeToParcel(out, mScreenOffCpuFreqTimeMs); 8293 8294 mCpuActiveTimeMs.writeToParcel(out); 8295 mCpuClusterTimesMs.writeToParcel(out); 8296 8297 if (mProcStateTimeMs != null) { 8298 out.writeInt(mProcStateTimeMs.length); 8299 for (LongSamplingCounterArray counters : mProcStateTimeMs) { 8300 LongSamplingCounterArray.writeToParcel(out, counters); 8301 } 8302 } else { 8303 out.writeInt(0); 8304 } 8305 if (mProcStateScreenOffTimeMs != null) { 8306 out.writeInt(mProcStateScreenOffTimeMs.length); 8307 for (LongSamplingCounterArray counters : mProcStateScreenOffTimeMs) { 8308 LongSamplingCounterArray.writeToParcel(out, counters); 8309 } 8310 } else { 8311 out.writeInt(0); 8312 } 8313 8314 if (mMobileRadioApWakeupCount != null) { 8315 out.writeInt(1); 8316 mMobileRadioApWakeupCount.writeToParcel(out); 8317 } else { 8318 out.writeInt(0); 8319 } 8320 8321 if (mWifiRadioApWakeupCount != null) { 8322 out.writeInt(1); 8323 mWifiRadioApWakeupCount.writeToParcel(out); 8324 } else { 8325 out.writeInt(0); 8326 } 8327 } 8328 readJobCompletionsFromParcelLocked(Parcel in)8329 void readJobCompletionsFromParcelLocked(Parcel in) { 8330 int numJobCompletions = in.readInt(); 8331 mJobCompletions.clear(); 8332 for (int j = 0; j < numJobCompletions; j++) { 8333 String jobName = in.readString(); 8334 int numTypes = in.readInt(); 8335 if (numTypes > 0) { 8336 SparseIntArray types = new SparseIntArray(); 8337 for (int k = 0; k < numTypes; k++) { 8338 int type = in.readInt(); 8339 int count = in.readInt(); 8340 types.put(type, count); 8341 } 8342 mJobCompletions.put(jobName, types); 8343 } 8344 } 8345 } 8346 readFromParcelLocked(TimeBase timeBase, TimeBase screenOffTimeBase, Parcel in)8347 void readFromParcelLocked(TimeBase timeBase, TimeBase screenOffTimeBase, Parcel in) { 8348 mOnBatteryBackgroundTimeBase.readFromParcel(in); 8349 mOnBatteryScreenOffBackgroundTimeBase.readFromParcel(in); 8350 8351 int numWakelocks = in.readInt(); 8352 mWakelockStats.clear(); 8353 for (int j = 0; j < numWakelocks; j++) { 8354 String wakelockName = in.readString(); 8355 Uid.Wakelock wakelock = new Wakelock(mBsi, this); 8356 wakelock.readFromParcelLocked( 8357 timeBase, screenOffTimeBase, mOnBatteryScreenOffBackgroundTimeBase, in); 8358 mWakelockStats.add(wakelockName, wakelock); 8359 } 8360 8361 int numSyncs = in.readInt(); 8362 mSyncStats.clear(); 8363 for (int j = 0; j < numSyncs; j++) { 8364 String syncName = in.readString(); 8365 if (in.readInt() != 0) { 8366 mSyncStats.add(syncName, new DualTimer(mBsi.mClocks, Uid.this, SYNC, null, 8367 mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase, in)); 8368 } 8369 } 8370 8371 int numJobs = in.readInt(); 8372 mJobStats.clear(); 8373 for (int j = 0; j < numJobs; j++) { 8374 String jobName = in.readString(); 8375 if (in.readInt() != 0) { 8376 mJobStats.add(jobName, new DualTimer(mBsi.mClocks, Uid.this, JOB, null, 8377 mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase, in)); 8378 } 8379 } 8380 8381 readJobCompletionsFromParcelLocked(in); 8382 8383 mJobsDeferredEventCount = new Counter(mBsi.mOnBatteryTimeBase, in); 8384 mJobsDeferredCount = new Counter(mBsi.mOnBatteryTimeBase, in); 8385 mJobsFreshnessTimeMs = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in); 8386 for (int i = 0; i < JOB_FRESHNESS_BUCKETS.length; i++) { 8387 mJobsFreshnessBuckets[i] = Counter.readCounterFromParcel(mBsi.mOnBatteryTimeBase, 8388 in); 8389 } 8390 8391 int numSensors = in.readInt(); 8392 mSensorStats.clear(); 8393 for (int k = 0; k < numSensors; k++) { 8394 int sensorNumber = in.readInt(); 8395 Uid.Sensor sensor = new Sensor(mBsi, this, sensorNumber); 8396 sensor.readFromParcelLocked(mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase, 8397 in); 8398 mSensorStats.put(sensorNumber, sensor); 8399 } 8400 8401 int numProcs = in.readInt(); 8402 mProcessStats.clear(); 8403 for (int k = 0; k < numProcs; k++) { 8404 String processName = in.readString(); 8405 Uid.Proc proc = new Proc(mBsi, processName); 8406 proc.readFromParcelLocked(in); 8407 mProcessStats.put(processName, proc); 8408 } 8409 8410 int numPkgs = in.readInt(); 8411 mPackageStats.clear(); 8412 for (int l = 0; l < numPkgs; l++) { 8413 String packageName = in.readString(); 8414 Uid.Pkg pkg = new Pkg(mBsi); 8415 pkg.readFromParcelLocked(in); 8416 mPackageStats.put(packageName, pkg); 8417 } 8418 8419 mWifiRunning = false; 8420 if (in.readInt() != 0) { 8421 mWifiRunningTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, WIFI_RUNNING, 8422 mBsi.mWifiRunningTimers, mBsi.mOnBatteryTimeBase, in); 8423 } else { 8424 mWifiRunningTimer = null; 8425 } 8426 mFullWifiLockOut = false; 8427 if (in.readInt() != 0) { 8428 mFullWifiLockTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, FULL_WIFI_LOCK, 8429 mBsi.mFullWifiLockTimers, mBsi.mOnBatteryTimeBase, in); 8430 } else { 8431 mFullWifiLockTimer = null; 8432 } 8433 mWifiScanStarted = false; 8434 if (in.readInt() != 0) { 8435 mWifiScanTimer = new DualTimer(mBsi.mClocks, Uid.this, WIFI_SCAN, 8436 mBsi.mWifiScanTimers, mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase, 8437 in); 8438 } else { 8439 mWifiScanTimer = null; 8440 } 8441 mWifiBatchedScanBinStarted = NO_BATCHED_SCAN_STARTED; 8442 for (int i = 0; i < NUM_WIFI_BATCHED_SCAN_BINS; i++) { 8443 if (in.readInt() != 0) { 8444 makeWifiBatchedScanBin(i, in); 8445 } else { 8446 mWifiBatchedScanTimer[i] = null; 8447 } 8448 } 8449 mWifiMulticastWakelockCount = 0; 8450 if (in.readInt() != 0) { 8451 mWifiMulticastTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, WIFI_MULTICAST_ENABLED, 8452 mBsi.mWifiMulticastTimers, mBsi.mOnBatteryTimeBase, in); 8453 } else { 8454 mWifiMulticastTimer = null; 8455 } 8456 if (in.readInt() != 0) { 8457 mAudioTurnedOnTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, AUDIO_TURNED_ON, 8458 mBsi.mAudioTurnedOnTimers, mBsi.mOnBatteryTimeBase, in); 8459 } else { 8460 mAudioTurnedOnTimer = null; 8461 } 8462 if (in.readInt() != 0) { 8463 mVideoTurnedOnTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, VIDEO_TURNED_ON, 8464 mBsi.mVideoTurnedOnTimers, mBsi.mOnBatteryTimeBase, in); 8465 } else { 8466 mVideoTurnedOnTimer = null; 8467 } 8468 if (in.readInt() != 0) { 8469 mFlashlightTurnedOnTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, 8470 FLASHLIGHT_TURNED_ON, mBsi.mFlashlightTurnedOnTimers, mBsi.mOnBatteryTimeBase, in); 8471 } else { 8472 mFlashlightTurnedOnTimer = null; 8473 } 8474 if (in.readInt() != 0) { 8475 mCameraTurnedOnTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, CAMERA_TURNED_ON, 8476 mBsi.mCameraTurnedOnTimers, mBsi.mOnBatteryTimeBase, in); 8477 } else { 8478 mCameraTurnedOnTimer = null; 8479 } 8480 if (in.readInt() != 0) { 8481 mForegroundActivityTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, 8482 FOREGROUND_ACTIVITY, null, mBsi.mOnBatteryTimeBase, in); 8483 } else { 8484 mForegroundActivityTimer = null; 8485 } 8486 if (in.readInt() != 0) { 8487 mForegroundServiceTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, 8488 FOREGROUND_SERVICE, null, mBsi.mOnBatteryTimeBase, in); 8489 } else { 8490 mForegroundServiceTimer = null; 8491 } 8492 if (in.readInt() != 0) { 8493 mAggregatedPartialWakelockTimer = new DualTimer(mBsi.mClocks, this, 8494 AGGREGATED_WAKE_TYPE_PARTIAL, null, 8495 mBsi.mOnBatteryScreenOffTimeBase, mOnBatteryScreenOffBackgroundTimeBase, 8496 in); 8497 } else { 8498 mAggregatedPartialWakelockTimer = null; 8499 } 8500 if (in.readInt() != 0) { 8501 mBluetoothScanTimer = new DualTimer(mBsi.mClocks, Uid.this, BLUETOOTH_SCAN_ON, 8502 mBsi.mBluetoothScanOnTimers, mBsi.mOnBatteryTimeBase, 8503 mOnBatteryBackgroundTimeBase, in); 8504 } else { 8505 mBluetoothScanTimer = null; 8506 } 8507 if (in.readInt() != 0) { 8508 mBluetoothUnoptimizedScanTimer = new DualTimer(mBsi.mClocks, Uid.this, 8509 BLUETOOTH_UNOPTIMIZED_SCAN_ON, null, 8510 mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase, in); 8511 } else { 8512 mBluetoothUnoptimizedScanTimer = null; 8513 } 8514 if (in.readInt() != 0) { 8515 mBluetoothScanResultCounter = new Counter(mBsi.mOnBatteryTimeBase, in); 8516 } else { 8517 mBluetoothScanResultCounter = null; 8518 } 8519 if (in.readInt() != 0) { 8520 mBluetoothScanResultBgCounter = new Counter(mOnBatteryBackgroundTimeBase, in); 8521 } else { 8522 mBluetoothScanResultBgCounter = null; 8523 } 8524 mProcessState = ActivityManager.PROCESS_STATE_NONEXISTENT; 8525 for (int i = 0; i < NUM_PROCESS_STATE; i++) { 8526 if (in.readInt() != 0) { 8527 makeProcessState(i, in); 8528 } else { 8529 mProcessStateTimer[i] = null; 8530 } 8531 } 8532 if (in.readInt() != 0) { 8533 mVibratorOnTimer = new BatchTimer(mBsi.mClocks, Uid.this, VIBRATOR_ON, 8534 mBsi.mOnBatteryTimeBase, in); 8535 } else { 8536 mVibratorOnTimer = null; 8537 } 8538 if (in.readInt() != 0) { 8539 mUserActivityCounters = new Counter[NUM_USER_ACTIVITY_TYPES]; 8540 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) { 8541 mUserActivityCounters[i] = new Counter(mBsi.mOnBatteryTimeBase, in); 8542 } 8543 } else { 8544 mUserActivityCounters = null; 8545 } 8546 if (in.readInt() != 0) { 8547 mNetworkByteActivityCounters = new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES]; 8548 mNetworkPacketActivityCounters 8549 = new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES]; 8550 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 8551 mNetworkByteActivityCounters[i] 8552 = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in); 8553 mNetworkPacketActivityCounters[i] 8554 = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in); 8555 } 8556 mMobileRadioActiveTime = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in); 8557 mMobileRadioActiveCount = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in); 8558 } else { 8559 mNetworkByteActivityCounters = null; 8560 mNetworkPacketActivityCounters = null; 8561 } 8562 8563 if (in.readInt() != 0) { 8564 mWifiControllerActivity = new ControllerActivityCounterImpl(mBsi.mOnBatteryTimeBase, 8565 NUM_WIFI_TX_LEVELS, in); 8566 } else { 8567 mWifiControllerActivity = null; 8568 } 8569 8570 if (in.readInt() != 0) { 8571 mBluetoothControllerActivity = new ControllerActivityCounterImpl(mBsi.mOnBatteryTimeBase, 8572 NUM_BT_TX_LEVELS, in); 8573 } else { 8574 mBluetoothControllerActivity = null; 8575 } 8576 8577 if (in.readInt() != 0) { 8578 mModemControllerActivity = new ControllerActivityCounterImpl(mBsi.mOnBatteryTimeBase, 8579 ModemActivityInfo.TX_POWER_LEVELS, in); 8580 } else { 8581 mModemControllerActivity = null; 8582 } 8583 8584 mUserCpuTime = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in); 8585 mSystemCpuTime = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in); 8586 8587 if (in.readInt() != 0) { 8588 int numCpuClusters = in.readInt(); 8589 if (mBsi.mPowerProfile != null && mBsi.mPowerProfile.getNumCpuClusters() != numCpuClusters) { 8590 throw new ParcelFormatException("Incompatible number of cpu clusters"); 8591 } 8592 8593 mCpuClusterSpeedTimesUs = new LongSamplingCounter[numCpuClusters][]; 8594 for (int cluster = 0; cluster < numCpuClusters; cluster++) { 8595 if (in.readInt() != 0) { 8596 int numSpeeds = in.readInt(); 8597 if (mBsi.mPowerProfile != null && 8598 mBsi.mPowerProfile.getNumSpeedStepsInCpuCluster(cluster) != numSpeeds) { 8599 throw new ParcelFormatException("Incompatible number of cpu speeds"); 8600 } 8601 8602 final LongSamplingCounter[] cpuSpeeds = new LongSamplingCounter[numSpeeds]; 8603 mCpuClusterSpeedTimesUs[cluster] = cpuSpeeds; 8604 for (int speed = 0; speed < numSpeeds; speed++) { 8605 if (in.readInt() != 0) { 8606 cpuSpeeds[speed] = new LongSamplingCounter( 8607 mBsi.mOnBatteryTimeBase, in); 8608 } 8609 } 8610 } else { 8611 mCpuClusterSpeedTimesUs[cluster] = null; 8612 } 8613 } 8614 } else { 8615 mCpuClusterSpeedTimesUs = null; 8616 } 8617 8618 mCpuFreqTimeMs = LongSamplingCounterArray.readFromParcel(in, mBsi.mOnBatteryTimeBase); 8619 mScreenOffCpuFreqTimeMs = LongSamplingCounterArray.readFromParcel( 8620 in, mBsi.mOnBatteryScreenOffTimeBase); 8621 8622 mCpuActiveTimeMs = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in); 8623 mCpuClusterTimesMs = new LongSamplingCounterArray(mBsi.mOnBatteryTimeBase, in); 8624 8625 int length = in.readInt(); 8626 if (length == NUM_PROCESS_STATE) { 8627 mProcStateTimeMs = new LongSamplingCounterArray[length]; 8628 for (int procState = 0; procState < length; ++procState) { 8629 mProcStateTimeMs[procState] = LongSamplingCounterArray.readFromParcel( 8630 in, mBsi.mOnBatteryTimeBase); 8631 } 8632 } else { 8633 mProcStateTimeMs = null; 8634 } 8635 length = in.readInt(); 8636 if (length == NUM_PROCESS_STATE) { 8637 mProcStateScreenOffTimeMs = new LongSamplingCounterArray[length]; 8638 for (int procState = 0; procState < length; ++procState) { 8639 mProcStateScreenOffTimeMs[procState] = LongSamplingCounterArray.readFromParcel( 8640 in, mBsi.mOnBatteryScreenOffTimeBase); 8641 } 8642 } else { 8643 mProcStateScreenOffTimeMs = null; 8644 } 8645 8646 if (in.readInt() != 0) { 8647 mMobileRadioApWakeupCount = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in); 8648 } else { 8649 mMobileRadioApWakeupCount = null; 8650 } 8651 8652 if (in.readInt() != 0) { 8653 mWifiRadioApWakeupCount = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in); 8654 } else { 8655 mWifiRadioApWakeupCount = null; 8656 } 8657 } 8658 noteJobsDeferredLocked(int numDeferred, long sinceLast)8659 public void noteJobsDeferredLocked(int numDeferred, long sinceLast) { 8660 mJobsDeferredEventCount.addAtomic(1); 8661 mJobsDeferredCount.addAtomic(numDeferred); 8662 if (sinceLast != 0) { 8663 // Add the total time, which can be divided by the event count to get an average 8664 mJobsFreshnessTimeMs.addCountLocked(sinceLast); 8665 // Also keep track of how many times there were in these different buckets. 8666 for (int i = 0; i < JOB_FRESHNESS_BUCKETS.length; i++) { 8667 if (sinceLast < JOB_FRESHNESS_BUCKETS[i]) { 8668 if (mJobsFreshnessBuckets[i] == null) { 8669 mJobsFreshnessBuckets[i] = new Counter( 8670 mBsi.mOnBatteryTimeBase); 8671 } 8672 mJobsFreshnessBuckets[i].addAtomic(1); 8673 break; 8674 } 8675 } 8676 } 8677 } 8678 8679 /** 8680 * The statistics associated with a particular wake lock. 8681 */ 8682 public static class Wakelock extends BatteryStats.Uid.Wakelock { 8683 /** 8684 * BatteryStatsImpl that we are associated with. 8685 */ 8686 protected BatteryStatsImpl mBsi; 8687 8688 /** 8689 * BatteryStatsImpl that we are associated with. 8690 */ 8691 protected Uid mUid; 8692 8693 /** 8694 * How long (in ms) this uid has been keeping the device partially awake. 8695 * Tracks both the total time and the time while the app was in the background. 8696 */ 8697 DualTimer mTimerPartial; 8698 8699 /** 8700 * How long (in ms) this uid has been keeping the device fully awake. 8701 */ 8702 StopwatchTimer mTimerFull; 8703 8704 /** 8705 * How long (in ms) this uid has had a window keeping the device awake. 8706 */ 8707 StopwatchTimer mTimerWindow; 8708 8709 /** 8710 * How long (in ms) this uid has had a draw wake lock. 8711 */ 8712 StopwatchTimer mTimerDraw; 8713 Wakelock(BatteryStatsImpl bsi, Uid uid)8714 public Wakelock(BatteryStatsImpl bsi, Uid uid) { 8715 mBsi = bsi; 8716 mUid = uid; 8717 } 8718 8719 /** 8720 * Reads a possibly null Timer from a Parcel. The timer is associated with the 8721 * proper timer pool from the given BatteryStatsImpl object. 8722 * 8723 * @param in the Parcel to be read from. 8724 * return a new Timer, or null. 8725 */ readStopwatchTimerFromParcel(int type, ArrayList<StopwatchTimer> pool, TimeBase timeBase, Parcel in)8726 private StopwatchTimer readStopwatchTimerFromParcel(int type, 8727 ArrayList<StopwatchTimer> pool, TimeBase timeBase, Parcel in) { 8728 if (in.readInt() == 0) { 8729 return null; 8730 } 8731 8732 return new StopwatchTimer(mBsi.mClocks, mUid, type, pool, timeBase, in); 8733 } 8734 8735 /** 8736 * Reads a possibly null Timer from a Parcel. The timer is associated with the 8737 * proper timer pool from the given BatteryStatsImpl object. 8738 * 8739 * @param in the Parcel to be read from. 8740 * return a new Timer, or null. 8741 */ readDualTimerFromParcel(int type, ArrayList<StopwatchTimer> pool, TimeBase timeBase, TimeBase bgTimeBase, Parcel in)8742 private DualTimer readDualTimerFromParcel(int type, ArrayList<StopwatchTimer> pool, 8743 TimeBase timeBase, TimeBase bgTimeBase, Parcel in) { 8744 if (in.readInt() == 0) { 8745 return null; 8746 } 8747 8748 return new DualTimer(mBsi.mClocks, mUid, type, pool, timeBase, bgTimeBase, in); 8749 } 8750 reset()8751 boolean reset() { 8752 boolean wlactive = false; 8753 8754 wlactive |= !resetIfNotNull(mTimerFull,false); 8755 wlactive |= !resetIfNotNull(mTimerPartial,false); 8756 wlactive |= !resetIfNotNull(mTimerWindow,false); 8757 wlactive |= !resetIfNotNull(mTimerDraw,false); 8758 8759 if (!wlactive) { 8760 detachIfNotNull(mTimerFull); 8761 mTimerFull = null; 8762 8763 detachIfNotNull(mTimerPartial); 8764 mTimerPartial = null; 8765 8766 detachIfNotNull(mTimerWindow); 8767 mTimerWindow = null; 8768 8769 detachIfNotNull(mTimerDraw); 8770 mTimerDraw = null; 8771 } 8772 return !wlactive; 8773 } 8774 readFromParcelLocked(TimeBase timeBase, TimeBase screenOffTimeBase, TimeBase screenOffBgTimeBase, Parcel in)8775 void readFromParcelLocked(TimeBase timeBase, TimeBase screenOffTimeBase, 8776 TimeBase screenOffBgTimeBase, Parcel in) { 8777 mTimerPartial = readDualTimerFromParcel(WAKE_TYPE_PARTIAL, 8778 mBsi.mPartialTimers, screenOffTimeBase, screenOffBgTimeBase, in); 8779 mTimerFull = readStopwatchTimerFromParcel(WAKE_TYPE_FULL, 8780 mBsi.mFullTimers, timeBase, in); 8781 mTimerWindow = readStopwatchTimerFromParcel(WAKE_TYPE_WINDOW, 8782 mBsi.mWindowTimers, timeBase, in); 8783 mTimerDraw = readStopwatchTimerFromParcel(WAKE_TYPE_DRAW, 8784 mBsi.mDrawTimers, timeBase, in); 8785 } 8786 writeToParcelLocked(Parcel out, long elapsedRealtimeUs)8787 void writeToParcelLocked(Parcel out, long elapsedRealtimeUs) { 8788 Timer.writeTimerToParcel(out, mTimerPartial, elapsedRealtimeUs); 8789 Timer.writeTimerToParcel(out, mTimerFull, elapsedRealtimeUs); 8790 Timer.writeTimerToParcel(out, mTimerWindow, elapsedRealtimeUs); 8791 Timer.writeTimerToParcel(out, mTimerDraw, elapsedRealtimeUs); 8792 } 8793 8794 @Override 8795 @UnsupportedAppUsage getWakeTime(int type)8796 public Timer getWakeTime(int type) { 8797 switch (type) { 8798 case WAKE_TYPE_FULL: return mTimerFull; 8799 case WAKE_TYPE_PARTIAL: return mTimerPartial; 8800 case WAKE_TYPE_WINDOW: return mTimerWindow; 8801 case WAKE_TYPE_DRAW: return mTimerDraw; 8802 default: throw new IllegalArgumentException("type = " + type); 8803 } 8804 } 8805 detachFromTimeBase()8806 public void detachFromTimeBase() { 8807 detachIfNotNull(mTimerPartial); 8808 detachIfNotNull(mTimerFull); 8809 detachIfNotNull(mTimerWindow); 8810 detachIfNotNull(mTimerDraw); 8811 } 8812 } 8813 8814 public static class Sensor extends BatteryStats.Uid.Sensor { 8815 /** 8816 * BatteryStatsImpl that we are associated with. 8817 */ 8818 protected BatteryStatsImpl mBsi; 8819 8820 /** 8821 * Uid that we are associated with. 8822 */ 8823 protected Uid mUid; 8824 8825 final int mHandle; 8826 DualTimer mTimer; 8827 Sensor(BatteryStatsImpl bsi, Uid uid, int handle)8828 public Sensor(BatteryStatsImpl bsi, Uid uid, int handle) { 8829 mBsi = bsi; 8830 mUid = uid; 8831 mHandle = handle; 8832 } 8833 readTimersFromParcel( TimeBase timeBase, TimeBase bgTimeBase, Parcel in)8834 private DualTimer readTimersFromParcel( 8835 TimeBase timeBase, TimeBase bgTimeBase, Parcel in) { 8836 if (in.readInt() == 0) { 8837 return null; 8838 } 8839 8840 ArrayList<StopwatchTimer> pool = mBsi.mSensorTimers.get(mHandle); 8841 if (pool == null) { 8842 pool = new ArrayList<StopwatchTimer>(); 8843 mBsi.mSensorTimers.put(mHandle, pool); 8844 } 8845 return new DualTimer(mBsi.mClocks, mUid, 0, pool, timeBase, bgTimeBase, in); 8846 } 8847 reset()8848 boolean reset() { 8849 if (mTimer.reset(true)) { 8850 mTimer = null; 8851 return true; 8852 } 8853 return false; 8854 } 8855 readFromParcelLocked(TimeBase timeBase, TimeBase bgTimeBase, Parcel in)8856 void readFromParcelLocked(TimeBase timeBase, TimeBase bgTimeBase, Parcel in) { 8857 mTimer = readTimersFromParcel(timeBase, bgTimeBase, in); 8858 } 8859 writeToParcelLocked(Parcel out, long elapsedRealtimeUs)8860 void writeToParcelLocked(Parcel out, long elapsedRealtimeUs) { 8861 Timer.writeTimerToParcel(out, mTimer, elapsedRealtimeUs); 8862 } 8863 8864 @Override 8865 @UnsupportedAppUsage getSensorTime()8866 public Timer getSensorTime() { 8867 return mTimer; 8868 } 8869 8870 @Override getSensorBackgroundTime()8871 public Timer getSensorBackgroundTime() { 8872 if (mTimer == null) { 8873 return null; 8874 } 8875 return mTimer.getSubTimer(); 8876 } 8877 8878 @Override 8879 @UnsupportedAppUsage getHandle()8880 public int getHandle() { 8881 return mHandle; 8882 } 8883 detachFromTimeBase()8884 public void detachFromTimeBase() { 8885 detachIfNotNull(mTimer); 8886 } 8887 } 8888 8889 /** 8890 * The statistics associated with a particular process. 8891 */ 8892 public static class Proc extends BatteryStats.Uid.Proc implements TimeBaseObs { 8893 /** 8894 * BatteryStatsImpl that we are associated with. 8895 */ 8896 protected BatteryStatsImpl mBsi; 8897 8898 /** 8899 * The name of this process. 8900 */ 8901 final String mName; 8902 8903 /** 8904 * Remains true until removed from the stats. 8905 */ 8906 boolean mActive = true; 8907 8908 /** 8909 * Total time (in ms) spent executing in user code. 8910 */ 8911 long mUserTime; 8912 8913 /** 8914 * Total time (in ms) spent executing in kernel code. 8915 */ 8916 long mSystemTime; 8917 8918 /** 8919 * Amount of time (in ms) the process was running in the foreground. 8920 */ 8921 long mForegroundTime; 8922 8923 /** 8924 * Number of times the process has been started. 8925 */ 8926 int mStarts; 8927 8928 /** 8929 * Number of times the process has crashed. 8930 */ 8931 int mNumCrashes; 8932 8933 /** 8934 * Number of times the process has had an ANR. 8935 */ 8936 int mNumAnrs; 8937 8938 ArrayList<ExcessivePower> mExcessivePower; 8939 Proc(BatteryStatsImpl bsi, String name)8940 public Proc(BatteryStatsImpl bsi, String name) { 8941 mBsi = bsi; 8942 mName = name; 8943 mBsi.mOnBatteryTimeBase.add(this); 8944 } 8945 onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime)8946 public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) { 8947 } 8948 onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime)8949 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) { 8950 } 8951 8952 @Override reset(boolean detachIfReset)8953 public boolean reset(boolean detachIfReset) { 8954 if (detachIfReset) { 8955 this.detach(); 8956 } 8957 return true; 8958 } 8959 8960 @Override detach()8961 public void detach() { 8962 mActive = false; 8963 mBsi.mOnBatteryTimeBase.remove(this); 8964 } 8965 countExcessivePowers()8966 public int countExcessivePowers() { 8967 return mExcessivePower != null ? mExcessivePower.size() : 0; 8968 } 8969 getExcessivePower(int i)8970 public ExcessivePower getExcessivePower(int i) { 8971 if (mExcessivePower != null) { 8972 return mExcessivePower.get(i); 8973 } 8974 return null; 8975 } 8976 addExcessiveCpu(long overTime, long usedTime)8977 public void addExcessiveCpu(long overTime, long usedTime) { 8978 if (mExcessivePower == null) { 8979 mExcessivePower = new ArrayList<ExcessivePower>(); 8980 } 8981 ExcessivePower ew = new ExcessivePower(); 8982 ew.type = ExcessivePower.TYPE_CPU; 8983 ew.overTime = overTime; 8984 ew.usedTime = usedTime; 8985 mExcessivePower.add(ew); 8986 } 8987 writeExcessivePowerToParcelLocked(Parcel out)8988 void writeExcessivePowerToParcelLocked(Parcel out) { 8989 if (mExcessivePower == null) { 8990 out.writeInt(0); 8991 return; 8992 } 8993 8994 final int N = mExcessivePower.size(); 8995 out.writeInt(N); 8996 for (int i=0; i<N; i++) { 8997 ExcessivePower ew = mExcessivePower.get(i); 8998 out.writeInt(ew.type); 8999 out.writeLong(ew.overTime); 9000 out.writeLong(ew.usedTime); 9001 } 9002 } 9003 readExcessivePowerFromParcelLocked(Parcel in)9004 void readExcessivePowerFromParcelLocked(Parcel in) { 9005 final int N = in.readInt(); 9006 if (N == 0) { 9007 mExcessivePower = null; 9008 return; 9009 } 9010 9011 if (N > 10000) { 9012 throw new ParcelFormatException( 9013 "File corrupt: too many excessive power entries " + N); 9014 } 9015 9016 mExcessivePower = new ArrayList<>(); 9017 for (int i=0; i<N; i++) { 9018 ExcessivePower ew = new ExcessivePower(); 9019 ew.type = in.readInt(); 9020 ew.overTime = in.readLong(); 9021 ew.usedTime = in.readLong(); 9022 mExcessivePower.add(ew); 9023 } 9024 } 9025 writeToParcelLocked(Parcel out)9026 void writeToParcelLocked(Parcel out) { 9027 out.writeLong(mUserTime); 9028 out.writeLong(mSystemTime); 9029 out.writeLong(mForegroundTime); 9030 out.writeInt(mStarts); 9031 out.writeInt(mNumCrashes); 9032 out.writeInt(mNumAnrs); 9033 writeExcessivePowerToParcelLocked(out); 9034 } 9035 readFromParcelLocked(Parcel in)9036 void readFromParcelLocked(Parcel in) { 9037 mUserTime = in.readLong(); 9038 mSystemTime = in.readLong(); 9039 mForegroundTime = in.readLong(); 9040 mStarts = in.readInt(); 9041 mNumCrashes = in.readInt(); 9042 mNumAnrs = in.readInt(); 9043 readExcessivePowerFromParcelLocked(in); 9044 } 9045 9046 @UnsupportedAppUsage addCpuTimeLocked(int utime, int stime)9047 public void addCpuTimeLocked(int utime, int stime) { 9048 addCpuTimeLocked(utime, stime, mBsi.mOnBatteryTimeBase.isRunning()); 9049 } 9050 addCpuTimeLocked(int utime, int stime, boolean isRunning)9051 public void addCpuTimeLocked(int utime, int stime, boolean isRunning) { 9052 if (isRunning) { 9053 mUserTime += utime; 9054 mSystemTime += stime; 9055 } 9056 } 9057 9058 @UnsupportedAppUsage addForegroundTimeLocked(long ttime)9059 public void addForegroundTimeLocked(long ttime) { 9060 mForegroundTime += ttime; 9061 } 9062 9063 @UnsupportedAppUsage incStartsLocked()9064 public void incStartsLocked() { 9065 mStarts++; 9066 } 9067 incNumCrashesLocked()9068 public void incNumCrashesLocked() { 9069 mNumCrashes++; 9070 } 9071 incNumAnrsLocked()9072 public void incNumAnrsLocked() { 9073 mNumAnrs++; 9074 } 9075 9076 @Override isActive()9077 public boolean isActive() { 9078 return mActive; 9079 } 9080 9081 @Override 9082 @UnsupportedAppUsage getUserTime(int which)9083 public long getUserTime(int which) { 9084 return mUserTime; 9085 } 9086 9087 @Override 9088 @UnsupportedAppUsage getSystemTime(int which)9089 public long getSystemTime(int which) { 9090 return mSystemTime; 9091 } 9092 9093 @Override 9094 @UnsupportedAppUsage getForegroundTime(int which)9095 public long getForegroundTime(int which) { 9096 return mForegroundTime; 9097 } 9098 9099 @Override 9100 @UnsupportedAppUsage getStarts(int which)9101 public int getStarts(int which) { 9102 return mStarts; 9103 } 9104 9105 @Override getNumCrashes(int which)9106 public int getNumCrashes(int which) { 9107 return mNumCrashes; 9108 } 9109 9110 @Override getNumAnrs(int which)9111 public int getNumAnrs(int which) { 9112 return mNumAnrs; 9113 } 9114 } 9115 9116 /** 9117 * The statistics associated with a particular package. 9118 */ 9119 public static class Pkg extends BatteryStats.Uid.Pkg implements TimeBaseObs { 9120 /** 9121 * BatteryStatsImpl that we are associated with. 9122 */ 9123 protected BatteryStatsImpl mBsi; 9124 9125 /** 9126 * Number of times wakeup alarms have occurred for this app. 9127 * On screen-off timebase starting in report v25. 9128 */ 9129 ArrayMap<String, Counter> mWakeupAlarms = new ArrayMap<>(); 9130 9131 /** 9132 * The statics we have collected for this package's services. 9133 */ 9134 final ArrayMap<String, Serv> mServiceStats = new ArrayMap<>(); 9135 Pkg(BatteryStatsImpl bsi)9136 public Pkg(BatteryStatsImpl bsi) { 9137 mBsi = bsi; 9138 mBsi.mOnBatteryScreenOffTimeBase.add(this); 9139 } 9140 onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime)9141 public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) { 9142 } 9143 onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime)9144 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) { 9145 } 9146 9147 @Override reset(boolean detachIfReset)9148 public boolean reset(boolean detachIfReset) { 9149 if (detachIfReset) { 9150 this.detach(); 9151 } 9152 return true; 9153 } 9154 9155 @Override detach()9156 public void detach() { 9157 mBsi.mOnBatteryScreenOffTimeBase.remove(this); 9158 for (int j = mWakeupAlarms.size() - 1; j >= 0; j--) { 9159 detachIfNotNull(mWakeupAlarms.valueAt(j)); 9160 } 9161 for (int j = mServiceStats.size() - 1; j >= 0; j--) { 9162 detachIfNotNull(mServiceStats.valueAt(j)); 9163 } 9164 } 9165 readFromParcelLocked(Parcel in)9166 void readFromParcelLocked(Parcel in) { 9167 int numWA = in.readInt(); 9168 mWakeupAlarms.clear(); 9169 for (int i=0; i<numWA; i++) { 9170 String tag = in.readString(); 9171 mWakeupAlarms.put(tag, new Counter(mBsi.mOnBatteryScreenOffTimeBase, in)); 9172 } 9173 9174 int numServs = in.readInt(); 9175 mServiceStats.clear(); 9176 for (int m = 0; m < numServs; m++) { 9177 String serviceName = in.readString(); 9178 Uid.Pkg.Serv serv = new Serv(mBsi); 9179 mServiceStats.put(serviceName, serv); 9180 9181 serv.readFromParcelLocked(in); 9182 } 9183 } 9184 writeToParcelLocked(Parcel out)9185 void writeToParcelLocked(Parcel out) { 9186 int numWA = mWakeupAlarms.size(); 9187 out.writeInt(numWA); 9188 for (int i=0; i<numWA; i++) { 9189 out.writeString(mWakeupAlarms.keyAt(i)); 9190 mWakeupAlarms.valueAt(i).writeToParcel(out); 9191 } 9192 9193 final int NS = mServiceStats.size(); 9194 out.writeInt(NS); 9195 for (int i=0; i<NS; i++) { 9196 out.writeString(mServiceStats.keyAt(i)); 9197 Uid.Pkg.Serv serv = mServiceStats.valueAt(i); 9198 serv.writeToParcelLocked(out); 9199 } 9200 } 9201 9202 @Override getWakeupAlarmStats()9203 public ArrayMap<String, ? extends BatteryStats.Counter> getWakeupAlarmStats() { 9204 return mWakeupAlarms; 9205 } 9206 noteWakeupAlarmLocked(String tag)9207 public void noteWakeupAlarmLocked(String tag) { 9208 Counter c = mWakeupAlarms.get(tag); 9209 if (c == null) { 9210 c = new Counter(mBsi.mOnBatteryScreenOffTimeBase); 9211 mWakeupAlarms.put(tag, c); 9212 } 9213 c.stepAtomic(); 9214 } 9215 9216 @Override getServiceStats()9217 public ArrayMap<String, ? extends BatteryStats.Uid.Pkg.Serv> getServiceStats() { 9218 return mServiceStats; 9219 } 9220 9221 /** 9222 * The statistics associated with a particular service. 9223 */ 9224 public static class Serv extends BatteryStats.Uid.Pkg.Serv implements TimeBaseObs { 9225 /** 9226 * BatteryStatsImpl that we are associated with. 9227 */ 9228 protected BatteryStatsImpl mBsi; 9229 9230 /** 9231 * The android package in which this service resides. 9232 */ 9233 protected Pkg mPkg; 9234 9235 /** 9236 * Total time (ms in battery uptime) the service has been left started. 9237 */ 9238 protected long mStartTime; 9239 9240 /** 9241 * If service has been started and not yet stopped, this is 9242 * when it was started. 9243 */ 9244 protected long mRunningSince; 9245 9246 /** 9247 * True if we are currently running. 9248 */ 9249 protected boolean mRunning; 9250 9251 /** 9252 * Total number of times startService() has been called. 9253 */ 9254 protected int mStarts; 9255 9256 /** 9257 * Total time (ms in battery uptime) the service has been left launched. 9258 */ 9259 protected long mLaunchedTime; 9260 9261 /** 9262 * If service has been launched and not yet exited, this is 9263 * when it was launched (ms in battery uptime). 9264 */ 9265 protected long mLaunchedSince; 9266 9267 /** 9268 * True if we are currently launched. 9269 */ 9270 protected boolean mLaunched; 9271 9272 /** 9273 * Total number times the service has been launched. 9274 */ 9275 protected int mLaunches; 9276 9277 /** 9278 * Construct a Serv. Also adds it to the on-battery time base as a listener. 9279 */ Serv(BatteryStatsImpl bsi)9280 public Serv(BatteryStatsImpl bsi) { 9281 mBsi = bsi; 9282 mBsi.mOnBatteryTimeBase.add(this); 9283 } 9284 onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime)9285 public void onTimeStarted(long elapsedRealtime, long baseUptime, 9286 long baseRealtime) { 9287 } 9288 onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime)9289 public void onTimeStopped(long elapsedRealtime, long baseUptime, 9290 long baseRealtime) { 9291 } 9292 9293 @Override reset(boolean detachIfReset)9294 public boolean reset(boolean detachIfReset) { 9295 if (detachIfReset) { 9296 this.detach(); 9297 } 9298 return true; 9299 } 9300 9301 /** 9302 * Remove this Serv as a listener from the time base. 9303 */ 9304 @Override detach()9305 public void detach() { 9306 mBsi.mOnBatteryTimeBase.remove(this); 9307 } 9308 readFromParcelLocked(Parcel in)9309 public void readFromParcelLocked(Parcel in) { 9310 mStartTime = in.readLong(); 9311 mRunningSince = in.readLong(); 9312 mRunning = in.readInt() != 0; 9313 mStarts = in.readInt(); 9314 mLaunchedTime = in.readLong(); 9315 mLaunchedSince = in.readLong(); 9316 mLaunched = in.readInt() != 0; 9317 mLaunches = in.readInt(); 9318 } 9319 writeToParcelLocked(Parcel out)9320 public void writeToParcelLocked(Parcel out) { 9321 out.writeLong(mStartTime); 9322 out.writeLong(mRunningSince); 9323 out.writeInt(mRunning ? 1 : 0); 9324 out.writeInt(mStarts); 9325 out.writeLong(mLaunchedTime); 9326 out.writeLong(mLaunchedSince); 9327 out.writeInt(mLaunched ? 1 : 0); 9328 out.writeInt(mLaunches); 9329 } 9330 getLaunchTimeToNowLocked(long batteryUptime)9331 public long getLaunchTimeToNowLocked(long batteryUptime) { 9332 if (!mLaunched) return mLaunchedTime; 9333 return mLaunchedTime + batteryUptime - mLaunchedSince; 9334 } 9335 getStartTimeToNowLocked(long batteryUptime)9336 public long getStartTimeToNowLocked(long batteryUptime) { 9337 if (!mRunning) return mStartTime; 9338 return mStartTime + batteryUptime - mRunningSince; 9339 } 9340 9341 @UnsupportedAppUsage startLaunchedLocked()9342 public void startLaunchedLocked() { 9343 if (!mLaunched) { 9344 mLaunches++; 9345 mLaunchedSince = mBsi.getBatteryUptimeLocked(); 9346 mLaunched = true; 9347 } 9348 } 9349 9350 @UnsupportedAppUsage stopLaunchedLocked()9351 public void stopLaunchedLocked() { 9352 if (mLaunched) { 9353 long time = mBsi.getBatteryUptimeLocked() - mLaunchedSince; 9354 if (time > 0) { 9355 mLaunchedTime += time; 9356 } else { 9357 mLaunches--; 9358 } 9359 mLaunched = false; 9360 } 9361 } 9362 9363 @UnsupportedAppUsage startRunningLocked()9364 public void startRunningLocked() { 9365 if (!mRunning) { 9366 mStarts++; 9367 mRunningSince = mBsi.getBatteryUptimeLocked(); 9368 mRunning = true; 9369 } 9370 } 9371 9372 @UnsupportedAppUsage stopRunningLocked()9373 public void stopRunningLocked() { 9374 if (mRunning) { 9375 long time = mBsi.getBatteryUptimeLocked() - mRunningSince; 9376 if (time > 0) { 9377 mStartTime += time; 9378 } else { 9379 mStarts--; 9380 } 9381 mRunning = false; 9382 } 9383 } 9384 9385 @UnsupportedAppUsage getBatteryStats()9386 public BatteryStatsImpl getBatteryStats() { 9387 return mBsi; 9388 } 9389 9390 @Override getLaunches(int which)9391 public int getLaunches(int which) { 9392 return mLaunches; 9393 } 9394 9395 @Override getStartTime(long now, int which)9396 public long getStartTime(long now, int which) { 9397 return getStartTimeToNowLocked(now); 9398 } 9399 9400 @Override getStarts(int which)9401 public int getStarts(int which) { 9402 return mStarts; 9403 } 9404 } 9405 newServiceStatsLocked()9406 final Serv newServiceStatsLocked() { 9407 return new Serv(mBsi); 9408 } 9409 } 9410 9411 /** 9412 * Retrieve the statistics object for a particular process, creating 9413 * if needed. 9414 */ getProcessStatsLocked(String name)9415 public Proc getProcessStatsLocked(String name) { 9416 Proc ps = mProcessStats.get(name); 9417 if (ps == null) { 9418 ps = new Proc(mBsi, name); 9419 mProcessStats.put(name, ps); 9420 } 9421 9422 return ps; 9423 } 9424 9425 @GuardedBy("mBsi") updateUidProcessStateLocked(int procState)9426 public void updateUidProcessStateLocked(int procState) { 9427 int uidRunningState; 9428 // Make special note of Foreground Services 9429 final boolean userAwareService = 9430 (ActivityManager.isForegroundService(procState)); 9431 uidRunningState = BatteryStats.mapToInternalProcessState(procState); 9432 9433 if (mProcessState == uidRunningState && userAwareService == mInForegroundService) { 9434 return; 9435 } 9436 9437 final long elapsedRealtimeMs = mBsi.mClocks.elapsedRealtime(); 9438 if (mProcessState != uidRunningState) { 9439 final long uptimeMs = mBsi.mClocks.uptimeMillis(); 9440 9441 if (mProcessState != ActivityManager.PROCESS_STATE_NONEXISTENT) { 9442 mProcessStateTimer[mProcessState].stopRunningLocked(elapsedRealtimeMs); 9443 9444 if (mBsi.trackPerProcStateCpuTimes()) { 9445 if (mBsi.mPendingUids.size() == 0) { 9446 mBsi.mExternalSync.scheduleReadProcStateCpuTimes( 9447 mBsi.mOnBatteryTimeBase.isRunning(), 9448 mBsi.mOnBatteryScreenOffTimeBase.isRunning(), 9449 mBsi.mConstants.PROC_STATE_CPU_TIMES_READ_DELAY_MS); 9450 mBsi.mNumSingleUidCpuTimeReads++; 9451 } else { 9452 mBsi.mNumBatchedSingleUidCpuTimeReads++; 9453 } 9454 if (mBsi.mPendingUids.indexOfKey(mUid) < 0 9455 || ArrayUtils.contains(CRITICAL_PROC_STATES, mProcessState)) { 9456 mBsi.mPendingUids.put(mUid, mProcessState); 9457 } 9458 } else { 9459 mBsi.mPendingUids.clear(); 9460 } 9461 } 9462 mProcessState = uidRunningState; 9463 if (uidRunningState != ActivityManager.PROCESS_STATE_NONEXISTENT) { 9464 if (mProcessStateTimer[uidRunningState] == null) { 9465 makeProcessState(uidRunningState, null); 9466 } 9467 mProcessStateTimer[uidRunningState].startRunningLocked(elapsedRealtimeMs); 9468 } 9469 9470 updateOnBatteryBgTimeBase(uptimeMs * 1000, elapsedRealtimeMs * 1000); 9471 updateOnBatteryScreenOffBgTimeBase(uptimeMs * 1000, elapsedRealtimeMs * 1000); 9472 } 9473 9474 if (userAwareService != mInForegroundService) { 9475 if (userAwareService) { 9476 noteForegroundServiceResumedLocked(elapsedRealtimeMs); 9477 } else { 9478 noteForegroundServicePausedLocked(elapsedRealtimeMs); 9479 } 9480 mInForegroundService = userAwareService; 9481 } 9482 } 9483 9484 /** Whether to consider Uid to be in the background for background timebase purposes. */ isInBackground()9485 public boolean isInBackground() { 9486 // Note that PROCESS_STATE_CACHED and ActivityManager.PROCESS_STATE_NONEXISTENT is 9487 // also considered to be 'background' for our purposes, because it's not foreground. 9488 return mProcessState >= PROCESS_STATE_BACKGROUND; 9489 } 9490 updateOnBatteryBgTimeBase(long uptimeUs, long realtimeUs)9491 public boolean updateOnBatteryBgTimeBase(long uptimeUs, long realtimeUs) { 9492 boolean on = mBsi.mOnBatteryTimeBase.isRunning() && isInBackground(); 9493 return mOnBatteryBackgroundTimeBase.setRunning(on, uptimeUs, realtimeUs); 9494 } 9495 updateOnBatteryScreenOffBgTimeBase(long uptimeUs, long realtimeUs)9496 public boolean updateOnBatteryScreenOffBgTimeBase(long uptimeUs, long realtimeUs) { 9497 boolean on = mBsi.mOnBatteryScreenOffTimeBase.isRunning() && isInBackground(); 9498 return mOnBatteryScreenOffBackgroundTimeBase.setRunning(on, uptimeUs, realtimeUs); 9499 } 9500 getPidStats()9501 public SparseArray<? extends Pid> getPidStats() { 9502 return mPids; 9503 } 9504 getPidStatsLocked(int pid)9505 public Pid getPidStatsLocked(int pid) { 9506 Pid p = mPids.get(pid); 9507 if (p == null) { 9508 p = new Pid(); 9509 mPids.put(pid, p); 9510 } 9511 return p; 9512 } 9513 9514 /** 9515 * Retrieve the statistics object for a particular service, creating 9516 * if needed. 9517 */ getPackageStatsLocked(String name)9518 public Pkg getPackageStatsLocked(String name) { 9519 Pkg ps = mPackageStats.get(name); 9520 if (ps == null) { 9521 ps = new Pkg(mBsi); 9522 mPackageStats.put(name, ps); 9523 } 9524 9525 return ps; 9526 } 9527 9528 /** 9529 * Retrieve the statistics object for a particular service, creating 9530 * if needed. 9531 */ getServiceStatsLocked(String pkg, String serv)9532 public Pkg.Serv getServiceStatsLocked(String pkg, String serv) { 9533 Pkg ps = getPackageStatsLocked(pkg); 9534 Pkg.Serv ss = ps.mServiceStats.get(serv); 9535 if (ss == null) { 9536 ss = ps.newServiceStatsLocked(); 9537 ps.mServiceStats.put(serv, ss); 9538 } 9539 9540 return ss; 9541 } 9542 readSyncSummaryFromParcelLocked(String name, Parcel in)9543 public void readSyncSummaryFromParcelLocked(String name, Parcel in) { 9544 DualTimer timer = mSyncStats.instantiateObject(); 9545 timer.readSummaryFromParcelLocked(in); 9546 mSyncStats.add(name, timer); 9547 } 9548 readJobSummaryFromParcelLocked(String name, Parcel in)9549 public void readJobSummaryFromParcelLocked(String name, Parcel in) { 9550 DualTimer timer = mJobStats.instantiateObject(); 9551 timer.readSummaryFromParcelLocked(in); 9552 mJobStats.add(name, timer); 9553 } 9554 readWakeSummaryFromParcelLocked(String wlName, Parcel in)9555 public void readWakeSummaryFromParcelLocked(String wlName, Parcel in) { 9556 Wakelock wl = new Wakelock(mBsi, this); 9557 mWakelockStats.add(wlName, wl); 9558 if (in.readInt() != 0) { 9559 getWakelockTimerLocked(wl, WAKE_TYPE_FULL).readSummaryFromParcelLocked(in); 9560 } 9561 if (in.readInt() != 0) { 9562 getWakelockTimerLocked(wl, WAKE_TYPE_PARTIAL).readSummaryFromParcelLocked(in); 9563 } 9564 if (in.readInt() != 0) { 9565 getWakelockTimerLocked(wl, WAKE_TYPE_WINDOW).readSummaryFromParcelLocked(in); 9566 } 9567 if (in.readInt() != 0) { 9568 getWakelockTimerLocked(wl, WAKE_TYPE_DRAW).readSummaryFromParcelLocked(in); 9569 } 9570 } 9571 getSensorTimerLocked(int sensor, boolean create)9572 public DualTimer getSensorTimerLocked(int sensor, boolean create) { 9573 Sensor se = mSensorStats.get(sensor); 9574 if (se == null) { 9575 if (!create) { 9576 return null; 9577 } 9578 se = new Sensor(mBsi, this, sensor); 9579 mSensorStats.put(sensor, se); 9580 } 9581 DualTimer t = se.mTimer; 9582 if (t != null) { 9583 return t; 9584 } 9585 ArrayList<StopwatchTimer> timers = mBsi.mSensorTimers.get(sensor); 9586 if (timers == null) { 9587 timers = new ArrayList<StopwatchTimer>(); 9588 mBsi.mSensorTimers.put(sensor, timers); 9589 } 9590 t = new DualTimer(mBsi.mClocks, this, BatteryStats.SENSOR, timers, 9591 mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase); 9592 se.mTimer = t; 9593 return t; 9594 } 9595 noteStartSyncLocked(String name, long elapsedRealtimeMs)9596 public void noteStartSyncLocked(String name, long elapsedRealtimeMs) { 9597 DualTimer t = mSyncStats.startObject(name); 9598 if (t != null) { 9599 t.startRunningLocked(elapsedRealtimeMs); 9600 } 9601 } 9602 noteStopSyncLocked(String name, long elapsedRealtimeMs)9603 public void noteStopSyncLocked(String name, long elapsedRealtimeMs) { 9604 DualTimer t = mSyncStats.stopObject(name); 9605 if (t != null) { 9606 t.stopRunningLocked(elapsedRealtimeMs); 9607 } 9608 } 9609 noteStartJobLocked(String name, long elapsedRealtimeMs)9610 public void noteStartJobLocked(String name, long elapsedRealtimeMs) { 9611 DualTimer t = mJobStats.startObject(name); 9612 if (t != null) { 9613 t.startRunningLocked(elapsedRealtimeMs); 9614 } 9615 } 9616 noteStopJobLocked(String name, long elapsedRealtimeMs, int stopReason)9617 public void noteStopJobLocked(String name, long elapsedRealtimeMs, int stopReason) { 9618 DualTimer t = mJobStats.stopObject(name); 9619 if (t != null) { 9620 t.stopRunningLocked(elapsedRealtimeMs); 9621 } 9622 if (mBsi.mOnBatteryTimeBase.isRunning()) { 9623 SparseIntArray types = mJobCompletions.get(name); 9624 if (types == null) { 9625 types = new SparseIntArray(); 9626 mJobCompletions.put(name, types); 9627 } 9628 int last = types.get(stopReason, 0); 9629 types.put(stopReason, last + 1); 9630 } 9631 } 9632 getWakelockTimerLocked(Wakelock wl, int type)9633 public StopwatchTimer getWakelockTimerLocked(Wakelock wl, int type) { 9634 if (wl == null) { 9635 return null; 9636 } 9637 switch (type) { 9638 case WAKE_TYPE_PARTIAL: { 9639 DualTimer t = wl.mTimerPartial; 9640 if (t == null) { 9641 t = new DualTimer(mBsi.mClocks, this, WAKE_TYPE_PARTIAL, 9642 mBsi.mPartialTimers, mBsi.mOnBatteryScreenOffTimeBase, 9643 mOnBatteryScreenOffBackgroundTimeBase); 9644 wl.mTimerPartial = t; 9645 } 9646 return t; 9647 } 9648 case WAKE_TYPE_FULL: { 9649 StopwatchTimer t = wl.mTimerFull; 9650 if (t == null) { 9651 t = new StopwatchTimer(mBsi.mClocks, this, WAKE_TYPE_FULL, 9652 mBsi.mFullTimers, mBsi.mOnBatteryTimeBase); 9653 wl.mTimerFull = t; 9654 } 9655 return t; 9656 } 9657 case WAKE_TYPE_WINDOW: { 9658 StopwatchTimer t = wl.mTimerWindow; 9659 if (t == null) { 9660 t = new StopwatchTimer(mBsi.mClocks, this, WAKE_TYPE_WINDOW, 9661 mBsi.mWindowTimers, mBsi.mOnBatteryTimeBase); 9662 wl.mTimerWindow = t; 9663 } 9664 return t; 9665 } 9666 case WAKE_TYPE_DRAW: { 9667 StopwatchTimer t = wl.mTimerDraw; 9668 if (t == null) { 9669 t = new StopwatchTimer(mBsi.mClocks, this, WAKE_TYPE_DRAW, 9670 mBsi.mDrawTimers, mBsi.mOnBatteryTimeBase); 9671 wl.mTimerDraw = t; 9672 } 9673 return t; 9674 } 9675 default: 9676 throw new IllegalArgumentException("type=" + type); 9677 } 9678 } 9679 noteStartWakeLocked(int pid, String name, int type, long elapsedRealtimeMs)9680 public void noteStartWakeLocked(int pid, String name, int type, long elapsedRealtimeMs) { 9681 Wakelock wl = mWakelockStats.startObject(name); 9682 if (wl != null) { 9683 getWakelockTimerLocked(wl, type).startRunningLocked(elapsedRealtimeMs); 9684 } 9685 if (type == WAKE_TYPE_PARTIAL) { 9686 createAggregatedPartialWakelockTimerLocked().startRunningLocked(elapsedRealtimeMs); 9687 if (pid >= 0) { 9688 Pid p = getPidStatsLocked(pid); 9689 if (p.mWakeNesting++ == 0) { 9690 p.mWakeStartMs = elapsedRealtimeMs; 9691 } 9692 } 9693 } 9694 } 9695 noteStopWakeLocked(int pid, String name, int type, long elapsedRealtimeMs)9696 public void noteStopWakeLocked(int pid, String name, int type, long elapsedRealtimeMs) { 9697 Wakelock wl = mWakelockStats.stopObject(name); 9698 if (wl != null) { 9699 StopwatchTimer wlt = getWakelockTimerLocked(wl, type); 9700 wlt.stopRunningLocked(elapsedRealtimeMs); 9701 } 9702 if (type == WAKE_TYPE_PARTIAL) { 9703 if (mAggregatedPartialWakelockTimer != null) { 9704 mAggregatedPartialWakelockTimer.stopRunningLocked(elapsedRealtimeMs); 9705 } 9706 if (pid >= 0) { 9707 Pid p = mPids.get(pid); 9708 if (p != null && p.mWakeNesting > 0) { 9709 if (p.mWakeNesting-- == 1) { 9710 p.mWakeSumMs += elapsedRealtimeMs - p.mWakeStartMs; 9711 p.mWakeStartMs = 0; 9712 } 9713 } 9714 } 9715 } 9716 } 9717 reportExcessiveCpuLocked(String proc, long overTime, long usedTime)9718 public void reportExcessiveCpuLocked(String proc, long overTime, long usedTime) { 9719 Proc p = getProcessStatsLocked(proc); 9720 if (p != null) { 9721 p.addExcessiveCpu(overTime, usedTime); 9722 } 9723 } 9724 noteStartSensor(int sensor, long elapsedRealtimeMs)9725 public void noteStartSensor(int sensor, long elapsedRealtimeMs) { 9726 DualTimer t = getSensorTimerLocked(sensor, /* create= */ true); 9727 t.startRunningLocked(elapsedRealtimeMs); 9728 } 9729 noteStopSensor(int sensor, long elapsedRealtimeMs)9730 public void noteStopSensor(int sensor, long elapsedRealtimeMs) { 9731 // Don't create a timer if one doesn't already exist 9732 DualTimer t = getSensorTimerLocked(sensor, false); 9733 if (t != null) { 9734 t.stopRunningLocked(elapsedRealtimeMs); 9735 } 9736 } 9737 noteStartGps(long elapsedRealtimeMs)9738 public void noteStartGps(long elapsedRealtimeMs) { 9739 noteStartSensor(Sensor.GPS, elapsedRealtimeMs); 9740 } 9741 noteStopGps(long elapsedRealtimeMs)9742 public void noteStopGps(long elapsedRealtimeMs) { 9743 noteStopSensor(Sensor.GPS, elapsedRealtimeMs); 9744 } 9745 getBatteryStats()9746 public BatteryStatsImpl getBatteryStats() { 9747 return mBsi; 9748 } 9749 } 9750 getCpuFreqs()9751 public long[] getCpuFreqs() { 9752 return mCpuFreqs; 9753 } 9754 BatteryStatsImpl(File systemDir, Handler handler, PlatformIdleStateCallback cb, RailEnergyDataCallback railStatsCb, UserInfoProvider userInfoProvider)9755 public BatteryStatsImpl(File systemDir, Handler handler, PlatformIdleStateCallback cb, 9756 RailEnergyDataCallback railStatsCb, UserInfoProvider userInfoProvider) { 9757 this(new SystemClocks(), systemDir, handler, cb, railStatsCb, userInfoProvider); 9758 } 9759 BatteryStatsImpl(Clocks clocks, File systemDir, Handler handler, PlatformIdleStateCallback cb, RailEnergyDataCallback railStatsCb, UserInfoProvider userInfoProvider)9760 private BatteryStatsImpl(Clocks clocks, File systemDir, Handler handler, 9761 PlatformIdleStateCallback cb, RailEnergyDataCallback railStatsCb, 9762 UserInfoProvider userInfoProvider) { 9763 init(clocks); 9764 9765 9766 if (systemDir == null) { 9767 mStatsFile = null; 9768 mBatteryStatsHistory = new BatteryStatsHistory(this, mHistoryBuffer); 9769 } else { 9770 mStatsFile = new AtomicFile(new File(systemDir, "batterystats.bin")); 9771 mBatteryStatsHistory = new BatteryStatsHistory(this, systemDir, mHistoryBuffer); 9772 } 9773 mCheckinFile = new AtomicFile(new File(systemDir, "batterystats-checkin.bin")); 9774 mDailyFile = new AtomicFile(new File(systemDir, "batterystats-daily.xml")); 9775 mHandler = new MyHandler(handler.getLooper()); 9776 mConstants = new Constants(mHandler); 9777 mStartCount++; 9778 mScreenOnTimer = new StopwatchTimer(mClocks, null, -1, null, mOnBatteryTimeBase); 9779 mScreenDozeTimer = new StopwatchTimer(mClocks, null, -1, null, mOnBatteryTimeBase); 9780 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 9781 mScreenBrightnessTimer[i] = new StopwatchTimer(mClocks, null, -100-i, null, 9782 mOnBatteryTimeBase); 9783 } 9784 mInteractiveTimer = new StopwatchTimer(mClocks, null, -10, null, mOnBatteryTimeBase); 9785 mPowerSaveModeEnabledTimer = new StopwatchTimer(mClocks, null, -2, null, 9786 mOnBatteryTimeBase); 9787 mDeviceIdleModeLightTimer = new StopwatchTimer(mClocks, null, -11, null, 9788 mOnBatteryTimeBase); 9789 mDeviceIdleModeFullTimer = new StopwatchTimer(mClocks, null, -14, null, mOnBatteryTimeBase); 9790 mDeviceLightIdlingTimer = new StopwatchTimer(mClocks, null, -15, null, mOnBatteryTimeBase); 9791 mDeviceIdlingTimer = new StopwatchTimer(mClocks, null, -12, null, mOnBatteryTimeBase); 9792 mPhoneOnTimer = new StopwatchTimer(mClocks, null, -3, null, mOnBatteryTimeBase); 9793 for (int i = 0; i < CellSignalStrength.getNumSignalStrengthLevels(); i++) { 9794 mPhoneSignalStrengthsTimer[i] = new StopwatchTimer(mClocks, null, -200-i, null, 9795 mOnBatteryTimeBase); 9796 } 9797 mPhoneSignalScanningTimer = new StopwatchTimer(mClocks, null, -200+1, null, 9798 mOnBatteryTimeBase); 9799 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 9800 mPhoneDataConnectionsTimer[i] = new StopwatchTimer(mClocks, null, -300-i, null, 9801 mOnBatteryTimeBase); 9802 } 9803 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 9804 mNetworkByteActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase); 9805 mNetworkPacketActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase); 9806 } 9807 mWifiActivity = new ControllerActivityCounterImpl(mOnBatteryTimeBase, NUM_WIFI_TX_LEVELS); 9808 mBluetoothActivity = new ControllerActivityCounterImpl(mOnBatteryTimeBase, 9809 NUM_BT_TX_LEVELS); 9810 mModemActivity = new ControllerActivityCounterImpl(mOnBatteryTimeBase, 9811 ModemActivityInfo.TX_POWER_LEVELS); 9812 mMobileRadioActiveTimer = new StopwatchTimer(mClocks, null, -400, null, mOnBatteryTimeBase); 9813 mMobileRadioActivePerAppTimer = new StopwatchTimer(mClocks, null, -401, null, 9814 mOnBatteryTimeBase); 9815 mMobileRadioActiveAdjustedTime = new LongSamplingCounter(mOnBatteryTimeBase); 9816 mMobileRadioActiveUnknownTime = new LongSamplingCounter(mOnBatteryTimeBase); 9817 mMobileRadioActiveUnknownCount = new LongSamplingCounter(mOnBatteryTimeBase); 9818 mWifiMulticastWakelockTimer = new StopwatchTimer(mClocks, null, 9819 WIFI_AGGREGATE_MULTICAST_ENABLED, null, mOnBatteryTimeBase); 9820 mWifiOnTimer = new StopwatchTimer(mClocks, null, -4, null, mOnBatteryTimeBase); 9821 mGlobalWifiRunningTimer = new StopwatchTimer(mClocks, null, -5, null, mOnBatteryTimeBase); 9822 for (int i=0; i<NUM_WIFI_STATES; i++) { 9823 mWifiStateTimer[i] = new StopwatchTimer(mClocks, null, -600-i, null, 9824 mOnBatteryTimeBase); 9825 } 9826 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) { 9827 mWifiSupplStateTimer[i] = new StopwatchTimer(mClocks, null, -700-i, null, 9828 mOnBatteryTimeBase); 9829 } 9830 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { 9831 mWifiSignalStrengthsTimer[i] = new StopwatchTimer(mClocks, null, -800-i, null, 9832 mOnBatteryTimeBase); 9833 } 9834 mWifiActiveTimer = new StopwatchTimer(mClocks, null, -900, null, mOnBatteryTimeBase); 9835 for (int i=0; i< GnssMetrics.NUM_GPS_SIGNAL_QUALITY_LEVELS; i++) { 9836 mGpsSignalQualityTimer[i] = new StopwatchTimer(mClocks, null, -1000-i, null, 9837 mOnBatteryTimeBase); 9838 } 9839 mAudioOnTimer = new StopwatchTimer(mClocks, null, -7, null, mOnBatteryTimeBase); 9840 mVideoOnTimer = new StopwatchTimer(mClocks, null, -8, null, mOnBatteryTimeBase); 9841 mFlashlightOnTimer = new StopwatchTimer(mClocks, null, -9, null, mOnBatteryTimeBase); 9842 mCameraOnTimer = new StopwatchTimer(mClocks, null, -13, null, mOnBatteryTimeBase); 9843 mBluetoothScanTimer = new StopwatchTimer(mClocks, null, -14, null, mOnBatteryTimeBase); 9844 mDischargeScreenOffCounter = new LongSamplingCounter(mOnBatteryScreenOffTimeBase); 9845 mDischargeScreenDozeCounter = new LongSamplingCounter(mOnBatteryTimeBase); 9846 mDischargeLightDozeCounter = new LongSamplingCounter(mOnBatteryTimeBase); 9847 mDischargeDeepDozeCounter = new LongSamplingCounter(mOnBatteryTimeBase); 9848 mDischargeCounter = new LongSamplingCounter(mOnBatteryTimeBase); 9849 mOnBattery = mOnBatteryInternal = false; 9850 long uptime = mClocks.uptimeMillis() * 1000; 9851 long realtime = mClocks.elapsedRealtime() * 1000; 9852 initTimes(uptime, realtime); 9853 mStartPlatformVersion = mEndPlatformVersion = Build.ID; 9854 mDischargeStartLevel = 0; 9855 mDischargeUnplugLevel = 0; 9856 mDischargePlugLevel = -1; 9857 mDischargeCurrentLevel = 0; 9858 mCurrentBatteryLevel = 0; 9859 initDischarge(); 9860 clearHistoryLocked(); 9861 updateDailyDeadlineLocked(); 9862 mPlatformIdleStateCallback = cb; 9863 mRailEnergyDataCallback = railStatsCb; 9864 mUserInfoProvider = userInfoProvider; 9865 } 9866 9867 @UnsupportedAppUsage BatteryStatsImpl(Parcel p)9868 public BatteryStatsImpl(Parcel p) { 9869 this(new SystemClocks(), p); 9870 } 9871 BatteryStatsImpl(Clocks clocks, Parcel p)9872 public BatteryStatsImpl(Clocks clocks, Parcel p) { 9873 init(clocks); 9874 mStatsFile = null; 9875 mCheckinFile = null; 9876 mDailyFile = null; 9877 mHandler = null; 9878 mExternalSync = null; 9879 mConstants = new Constants(mHandler); 9880 clearHistoryLocked(); 9881 mBatteryStatsHistory = new BatteryStatsHistory(this, mHistoryBuffer); 9882 readFromParcel(p); 9883 mPlatformIdleStateCallback = null; 9884 mRailEnergyDataCallback = null; 9885 } 9886 setPowerProfileLocked(PowerProfile profile)9887 public void setPowerProfileLocked(PowerProfile profile) { 9888 mPowerProfile = profile; 9889 9890 // We need to initialize the KernelCpuSpeedReaders to read from 9891 // the first cpu of each core. Once we have the PowerProfile, we have access to this 9892 // information. 9893 final int numClusters = mPowerProfile.getNumCpuClusters(); 9894 mKernelCpuSpeedReaders = new KernelCpuSpeedReader[numClusters]; 9895 int firstCpuOfCluster = 0; 9896 for (int i = 0; i < numClusters; i++) { 9897 final int numSpeedSteps = mPowerProfile.getNumSpeedStepsInCpuCluster(i); 9898 mKernelCpuSpeedReaders[i] = new KernelCpuSpeedReader(firstCpuOfCluster, 9899 numSpeedSteps); 9900 firstCpuOfCluster += mPowerProfile.getNumCoresInCpuCluster(i); 9901 } 9902 9903 if (mEstimatedBatteryCapacity == -1) { 9904 // Initialize the estimated battery capacity to a known preset one. 9905 mEstimatedBatteryCapacity = (int) mPowerProfile.getBatteryCapacity(); 9906 } 9907 } 9908 setCallback(BatteryCallback cb)9909 public void setCallback(BatteryCallback cb) { 9910 mCallback = cb; 9911 } 9912 setRadioScanningTimeoutLocked(long timeout)9913 public void setRadioScanningTimeoutLocked(long timeout) { 9914 if (mPhoneSignalScanningTimer != null) { 9915 mPhoneSignalScanningTimer.setTimeout(timeout); 9916 } 9917 } 9918 setExternalStatsSyncLocked(ExternalStatsSync sync)9919 public void setExternalStatsSyncLocked(ExternalStatsSync sync) { 9920 mExternalSync = sync; 9921 } 9922 updateDailyDeadlineLocked()9923 public void updateDailyDeadlineLocked() { 9924 // Get the current time. 9925 long currentTime = mDailyStartTime = System.currentTimeMillis(); 9926 Calendar calDeadline = Calendar.getInstance(); 9927 calDeadline.setTimeInMillis(currentTime); 9928 9929 // Move time up to the next day, ranging from 1am to 3pm. 9930 calDeadline.set(Calendar.DAY_OF_YEAR, calDeadline.get(Calendar.DAY_OF_YEAR) + 1); 9931 calDeadline.set(Calendar.MILLISECOND, 0); 9932 calDeadline.set(Calendar.SECOND, 0); 9933 calDeadline.set(Calendar.MINUTE, 0); 9934 calDeadline.set(Calendar.HOUR_OF_DAY, 1); 9935 mNextMinDailyDeadline = calDeadline.getTimeInMillis(); 9936 calDeadline.set(Calendar.HOUR_OF_DAY, 3); 9937 mNextMaxDailyDeadline = calDeadline.getTimeInMillis(); 9938 } 9939 recordDailyStatsIfNeededLocked(boolean settled)9940 public void recordDailyStatsIfNeededLocked(boolean settled) { 9941 long currentTime = System.currentTimeMillis(); 9942 if (currentTime >= mNextMaxDailyDeadline) { 9943 recordDailyStatsLocked(); 9944 } else if (settled && currentTime >= mNextMinDailyDeadline) { 9945 recordDailyStatsLocked(); 9946 } else if (currentTime < (mDailyStartTime-(1000*60*60*24))) { 9947 recordDailyStatsLocked(); 9948 } 9949 } 9950 recordDailyStatsLocked()9951 public void recordDailyStatsLocked() { 9952 DailyItem item = new DailyItem(); 9953 item.mStartTime = mDailyStartTime; 9954 item.mEndTime = System.currentTimeMillis(); 9955 boolean hasData = false; 9956 if (mDailyDischargeStepTracker.mNumStepDurations > 0) { 9957 hasData = true; 9958 item.mDischargeSteps = new LevelStepTracker( 9959 mDailyDischargeStepTracker.mNumStepDurations, 9960 mDailyDischargeStepTracker.mStepDurations); 9961 } 9962 if (mDailyChargeStepTracker.mNumStepDurations > 0) { 9963 hasData = true; 9964 item.mChargeSteps = new LevelStepTracker( 9965 mDailyChargeStepTracker.mNumStepDurations, 9966 mDailyChargeStepTracker.mStepDurations); 9967 } 9968 if (mDailyPackageChanges != null) { 9969 hasData = true; 9970 item.mPackageChanges = mDailyPackageChanges; 9971 mDailyPackageChanges = null; 9972 } 9973 mDailyDischargeStepTracker.init(); 9974 mDailyChargeStepTracker.init(); 9975 updateDailyDeadlineLocked(); 9976 9977 if (hasData) { 9978 final long startTime = SystemClock.uptimeMillis(); 9979 mDailyItems.add(item); 9980 while (mDailyItems.size() > MAX_DAILY_ITEMS) { 9981 mDailyItems.remove(0); 9982 } 9983 final ByteArrayOutputStream memStream = new ByteArrayOutputStream(); 9984 try { 9985 XmlSerializer out = new FastXmlSerializer(); 9986 out.setOutput(memStream, StandardCharsets.UTF_8.name()); 9987 writeDailyItemsLocked(out); 9988 final long initialTime = SystemClock.uptimeMillis() - startTime; 9989 BackgroundThread.getHandler().post(new Runnable() { 9990 @Override 9991 public void run() { 9992 synchronized (mCheckinFile) { 9993 final long startTime2 = SystemClock.uptimeMillis(); 9994 FileOutputStream stream = null; 9995 try { 9996 stream = mDailyFile.startWrite(); 9997 memStream.writeTo(stream); 9998 stream.flush(); 9999 mDailyFile.finishWrite(stream); 10000 com.android.internal.logging.EventLogTags.writeCommitSysConfigFile( 10001 "batterystats-daily", 10002 initialTime + SystemClock.uptimeMillis() - startTime2); 10003 } catch (IOException e) { 10004 Slog.w("BatteryStats", 10005 "Error writing battery daily items", e); 10006 mDailyFile.failWrite(stream); 10007 } 10008 } 10009 } 10010 }); 10011 } catch (IOException e) { 10012 } 10013 } 10014 } 10015 writeDailyItemsLocked(XmlSerializer out)10016 private void writeDailyItemsLocked(XmlSerializer out) throws IOException { 10017 StringBuilder sb = new StringBuilder(64); 10018 out.startDocument(null, true); 10019 out.startTag(null, "daily-items"); 10020 for (int i=0; i<mDailyItems.size(); i++) { 10021 final DailyItem dit = mDailyItems.get(i); 10022 out.startTag(null, "item"); 10023 out.attribute(null, "start", Long.toString(dit.mStartTime)); 10024 out.attribute(null, "end", Long.toString(dit.mEndTime)); 10025 writeDailyLevelSteps(out, "dis", dit.mDischargeSteps, sb); 10026 writeDailyLevelSteps(out, "chg", dit.mChargeSteps, sb); 10027 if (dit.mPackageChanges != null) { 10028 for (int j=0; j<dit.mPackageChanges.size(); j++) { 10029 PackageChange pc = dit.mPackageChanges.get(j); 10030 if (pc.mUpdate) { 10031 out.startTag(null, "upd"); 10032 out.attribute(null, "pkg", pc.mPackageName); 10033 out.attribute(null, "ver", Long.toString(pc.mVersionCode)); 10034 out.endTag(null, "upd"); 10035 } else { 10036 out.startTag(null, "rem"); 10037 out.attribute(null, "pkg", pc.mPackageName); 10038 out.endTag(null, "rem"); 10039 } 10040 } 10041 } 10042 out.endTag(null, "item"); 10043 } 10044 out.endTag(null, "daily-items"); 10045 out.endDocument(); 10046 } 10047 writeDailyLevelSteps(XmlSerializer out, String tag, LevelStepTracker steps, StringBuilder tmpBuilder)10048 private void writeDailyLevelSteps(XmlSerializer out, String tag, LevelStepTracker steps, 10049 StringBuilder tmpBuilder) throws IOException { 10050 if (steps != null) { 10051 out.startTag(null, tag); 10052 out.attribute(null, "n", Integer.toString(steps.mNumStepDurations)); 10053 for (int i=0; i<steps.mNumStepDurations; i++) { 10054 out.startTag(null, "s"); 10055 tmpBuilder.setLength(0); 10056 steps.encodeEntryAt(i, tmpBuilder); 10057 out.attribute(null, "v", tmpBuilder.toString()); 10058 out.endTag(null, "s"); 10059 } 10060 out.endTag(null, tag); 10061 } 10062 } 10063 readDailyStatsLocked()10064 public void readDailyStatsLocked() { 10065 Slog.d(TAG, "Reading daily items from " + mDailyFile.getBaseFile()); 10066 mDailyItems.clear(); 10067 FileInputStream stream; 10068 try { 10069 stream = mDailyFile.openRead(); 10070 } catch (FileNotFoundException e) { 10071 return; 10072 } 10073 try { 10074 XmlPullParser parser = Xml.newPullParser(); 10075 parser.setInput(stream, StandardCharsets.UTF_8.name()); 10076 readDailyItemsLocked(parser); 10077 } catch (XmlPullParserException e) { 10078 } finally { 10079 try { 10080 stream.close(); 10081 } catch (IOException e) { 10082 } 10083 } 10084 } 10085 readDailyItemsLocked(XmlPullParser parser)10086 private void readDailyItemsLocked(XmlPullParser parser) { 10087 try { 10088 int type; 10089 while ((type = parser.next()) != XmlPullParser.START_TAG 10090 && type != XmlPullParser.END_DOCUMENT) { 10091 ; 10092 } 10093 10094 if (type != XmlPullParser.START_TAG) { 10095 throw new IllegalStateException("no start tag found"); 10096 } 10097 10098 int outerDepth = parser.getDepth(); 10099 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 10100 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 10101 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 10102 continue; 10103 } 10104 10105 String tagName = parser.getName(); 10106 if (tagName.equals("item")) { 10107 readDailyItemTagLocked(parser); 10108 } else { 10109 Slog.w(TAG, "Unknown element under <daily-items>: " 10110 + parser.getName()); 10111 XmlUtils.skipCurrentTag(parser); 10112 } 10113 } 10114 10115 } catch (IllegalStateException e) { 10116 Slog.w(TAG, "Failed parsing daily " + e); 10117 } catch (NullPointerException e) { 10118 Slog.w(TAG, "Failed parsing daily " + e); 10119 } catch (NumberFormatException e) { 10120 Slog.w(TAG, "Failed parsing daily " + e); 10121 } catch (XmlPullParserException e) { 10122 Slog.w(TAG, "Failed parsing daily " + e); 10123 } catch (IOException e) { 10124 Slog.w(TAG, "Failed parsing daily " + e); 10125 } catch (IndexOutOfBoundsException e) { 10126 Slog.w(TAG, "Failed parsing daily " + e); 10127 } 10128 } 10129 readDailyItemTagLocked(XmlPullParser parser)10130 void readDailyItemTagLocked(XmlPullParser parser) throws NumberFormatException, 10131 XmlPullParserException, IOException { 10132 DailyItem dit = new DailyItem(); 10133 String attr = parser.getAttributeValue(null, "start"); 10134 if (attr != null) { 10135 dit.mStartTime = Long.parseLong(attr); 10136 } 10137 attr = parser.getAttributeValue(null, "end"); 10138 if (attr != null) { 10139 dit.mEndTime = Long.parseLong(attr); 10140 } 10141 int outerDepth = parser.getDepth(); 10142 int type; 10143 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 10144 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 10145 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 10146 continue; 10147 } 10148 10149 String tagName = parser.getName(); 10150 if (tagName.equals("dis")) { 10151 readDailyItemTagDetailsLocked(parser, dit, false, "dis"); 10152 } else if (tagName.equals("chg")) { 10153 readDailyItemTagDetailsLocked(parser, dit, true, "chg"); 10154 } else if (tagName.equals("upd")) { 10155 if (dit.mPackageChanges == null) { 10156 dit.mPackageChanges = new ArrayList<>(); 10157 } 10158 PackageChange pc = new PackageChange(); 10159 pc.mUpdate = true; 10160 pc.mPackageName = parser.getAttributeValue(null, "pkg"); 10161 String verStr = parser.getAttributeValue(null, "ver"); 10162 pc.mVersionCode = verStr != null ? Long.parseLong(verStr) : 0; 10163 dit.mPackageChanges.add(pc); 10164 XmlUtils.skipCurrentTag(parser); 10165 } else if (tagName.equals("rem")) { 10166 if (dit.mPackageChanges == null) { 10167 dit.mPackageChanges = new ArrayList<>(); 10168 } 10169 PackageChange pc = new PackageChange(); 10170 pc.mUpdate = false; 10171 pc.mPackageName = parser.getAttributeValue(null, "pkg"); 10172 dit.mPackageChanges.add(pc); 10173 XmlUtils.skipCurrentTag(parser); 10174 } else { 10175 Slog.w(TAG, "Unknown element under <item>: " 10176 + parser.getName()); 10177 XmlUtils.skipCurrentTag(parser); 10178 } 10179 } 10180 mDailyItems.add(dit); 10181 } 10182 readDailyItemTagDetailsLocked(XmlPullParser parser, DailyItem dit, boolean isCharge, String tag)10183 void readDailyItemTagDetailsLocked(XmlPullParser parser, DailyItem dit, boolean isCharge, 10184 String tag) 10185 throws NumberFormatException, XmlPullParserException, IOException { 10186 final String numAttr = parser.getAttributeValue(null, "n"); 10187 if (numAttr == null) { 10188 Slog.w(TAG, "Missing 'n' attribute at " + parser.getPositionDescription()); 10189 XmlUtils.skipCurrentTag(parser); 10190 return; 10191 } 10192 final int num = Integer.parseInt(numAttr); 10193 LevelStepTracker steps = new LevelStepTracker(num); 10194 if (isCharge) { 10195 dit.mChargeSteps = steps; 10196 } else { 10197 dit.mDischargeSteps = steps; 10198 } 10199 int i = 0; 10200 int outerDepth = parser.getDepth(); 10201 int type; 10202 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 10203 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 10204 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 10205 continue; 10206 } 10207 10208 String tagName = parser.getName(); 10209 if ("s".equals(tagName)) { 10210 if (i < num) { 10211 String valueAttr = parser.getAttributeValue(null, "v"); 10212 if (valueAttr != null) { 10213 steps.decodeEntryAt(i, valueAttr); 10214 i++; 10215 } 10216 } 10217 } else { 10218 Slog.w(TAG, "Unknown element under <" + tag + ">: " 10219 + parser.getName()); 10220 XmlUtils.skipCurrentTag(parser); 10221 } 10222 } 10223 steps.mNumStepDurations = i; 10224 } 10225 10226 @Override getDailyItemLocked(int daysAgo)10227 public DailyItem getDailyItemLocked(int daysAgo) { 10228 int index = mDailyItems.size()-1-daysAgo; 10229 return index >= 0 ? mDailyItems.get(index) : null; 10230 } 10231 10232 @Override getCurrentDailyStartTime()10233 public long getCurrentDailyStartTime() { 10234 return mDailyStartTime; 10235 } 10236 10237 @Override getNextMinDailyDeadline()10238 public long getNextMinDailyDeadline() { 10239 return mNextMinDailyDeadline; 10240 } 10241 10242 @Override getNextMaxDailyDeadline()10243 public long getNextMaxDailyDeadline() { 10244 return mNextMaxDailyDeadline; 10245 } 10246 10247 @Override startIteratingOldHistoryLocked()10248 public boolean startIteratingOldHistoryLocked() { 10249 if (DEBUG_HISTORY) Slog.i(TAG, "ITERATING: buff size=" + mHistoryBuffer.dataSize() 10250 + " pos=" + mHistoryBuffer.dataPosition()); 10251 if ((mHistoryIterator = mHistory) == null) { 10252 return false; 10253 } 10254 mHistoryBuffer.setDataPosition(0); 10255 mHistoryReadTmp.clear(); 10256 mReadOverflow = false; 10257 mIteratingHistory = true; 10258 return true; 10259 } 10260 10261 @Override getNextOldHistoryLocked(HistoryItem out)10262 public boolean getNextOldHistoryLocked(HistoryItem out) { 10263 boolean end = mHistoryBuffer.dataPosition() >= mHistoryBuffer.dataSize(); 10264 if (!end) { 10265 readHistoryDelta(mHistoryBuffer, mHistoryReadTmp); 10266 mReadOverflow |= mHistoryReadTmp.cmd == HistoryItem.CMD_OVERFLOW; 10267 } 10268 HistoryItem cur = mHistoryIterator; 10269 if (cur == null) { 10270 if (!mReadOverflow && !end) { 10271 Slog.w(TAG, "Old history ends before new history!"); 10272 } 10273 return false; 10274 } 10275 out.setTo(cur); 10276 mHistoryIterator = cur.next; 10277 if (!mReadOverflow) { 10278 if (end) { 10279 Slog.w(TAG, "New history ends before old history!"); 10280 } else if (!out.same(mHistoryReadTmp)) { 10281 PrintWriter pw = new FastPrintWriter(new LogWriter(android.util.Log.WARN, TAG)); 10282 pw.println("Histories differ!"); 10283 pw.println("Old history:"); 10284 (new HistoryPrinter()).printNextItem(pw, out, 0, false, true); 10285 pw.println("New history:"); 10286 (new HistoryPrinter()).printNextItem(pw, mHistoryReadTmp, 0, false, 10287 true); 10288 pw.flush(); 10289 } 10290 } 10291 return true; 10292 } 10293 10294 @Override finishIteratingOldHistoryLocked()10295 public void finishIteratingOldHistoryLocked() { 10296 mIteratingHistory = false; 10297 mHistoryBuffer.setDataPosition(mHistoryBuffer.dataSize()); 10298 mHistoryIterator = null; 10299 } 10300 getHistoryTotalSize()10301 public int getHistoryTotalSize() { 10302 return mConstants.MAX_HISTORY_BUFFER * mConstants.MAX_HISTORY_FILES; 10303 } 10304 getHistoryUsedSize()10305 public int getHistoryUsedSize() { 10306 return mBatteryStatsHistory.getHistoryUsedSize(); 10307 } 10308 10309 @Override 10310 @UnsupportedAppUsage startIteratingHistoryLocked()10311 public boolean startIteratingHistoryLocked() { 10312 mBatteryStatsHistory.startIteratingHistory(); 10313 mReadOverflow = false; 10314 mIteratingHistory = true; 10315 mReadHistoryStrings = new String[mHistoryTagPool.size()]; 10316 mReadHistoryUids = new int[mHistoryTagPool.size()]; 10317 mReadHistoryChars = 0; 10318 for (HashMap.Entry<HistoryTag, Integer> ent : mHistoryTagPool.entrySet()) { 10319 final HistoryTag tag = ent.getKey(); 10320 final int idx = ent.getValue(); 10321 mReadHistoryStrings[idx] = tag.string; 10322 mReadHistoryUids[idx] = tag.uid; 10323 mReadHistoryChars += tag.string.length() + 1; 10324 } 10325 return true; 10326 } 10327 10328 @Override getHistoryStringPoolSize()10329 public int getHistoryStringPoolSize() { 10330 return mReadHistoryStrings.length; 10331 } 10332 10333 @Override getHistoryStringPoolBytes()10334 public int getHistoryStringPoolBytes() { 10335 // Each entry is a fixed 12 bytes: 4 for index, 4 for uid, 4 for string size 10336 // Each string character is 2 bytes. 10337 return (mReadHistoryStrings.length * 12) + (mReadHistoryChars * 2); 10338 } 10339 10340 @Override getHistoryTagPoolString(int index)10341 public String getHistoryTagPoolString(int index) { 10342 return mReadHistoryStrings[index]; 10343 } 10344 10345 @Override getHistoryTagPoolUid(int index)10346 public int getHistoryTagPoolUid(int index) { 10347 return mReadHistoryUids[index]; 10348 } 10349 10350 @Override 10351 @UnsupportedAppUsage getNextHistoryLocked(HistoryItem out)10352 public boolean getNextHistoryLocked(HistoryItem out) { 10353 Parcel p = mBatteryStatsHistory.getNextParcel(out); 10354 if (p == null) { 10355 return false; 10356 } 10357 final long lastRealtime = out.time; 10358 final long lastWalltime = out.currentTime; 10359 readHistoryDelta(p, out); 10360 if (out.cmd != HistoryItem.CMD_CURRENT_TIME 10361 && out.cmd != HistoryItem.CMD_RESET && lastWalltime != 0) { 10362 out.currentTime = lastWalltime + (out.time - lastRealtime); 10363 } 10364 return true; 10365 } 10366 10367 @Override finishIteratingHistoryLocked()10368 public void finishIteratingHistoryLocked() { 10369 mBatteryStatsHistory.finishIteratingHistory(); 10370 mIteratingHistory = false; 10371 mReadHistoryStrings = null; 10372 mReadHistoryUids = null; 10373 } 10374 10375 @Override getHistoryBaseTime()10376 public long getHistoryBaseTime() { 10377 return mHistoryBaseTime; 10378 } 10379 10380 @Override getStartCount()10381 public int getStartCount() { 10382 return mStartCount; 10383 } 10384 10385 @UnsupportedAppUsage isOnBattery()10386 public boolean isOnBattery() { 10387 return mOnBattery; 10388 } 10389 isCharging()10390 public boolean isCharging() { 10391 return mCharging; 10392 } 10393 isScreenOn(int state)10394 public boolean isScreenOn(int state) { 10395 return state == Display.STATE_ON || state == Display.STATE_VR 10396 || state == Display.STATE_ON_SUSPEND; 10397 } 10398 isScreenOff(int state)10399 public boolean isScreenOff(int state) { 10400 return state == Display.STATE_OFF; 10401 } 10402 isScreenDoze(int state)10403 public boolean isScreenDoze(int state) { 10404 return state == Display.STATE_DOZE || state == Display.STATE_DOZE_SUSPEND; 10405 } 10406 initTimes(long uptime, long realtime)10407 void initTimes(long uptime, long realtime) { 10408 mStartClockTime = System.currentTimeMillis(); 10409 mOnBatteryTimeBase.init(uptime, realtime); 10410 mOnBatteryScreenOffTimeBase.init(uptime, realtime); 10411 mRealtime = 0; 10412 mUptime = 0; 10413 mRealtimeStart = realtime; 10414 mUptimeStart = uptime; 10415 } 10416 initDischarge()10417 void initDischarge() { 10418 mLowDischargeAmountSinceCharge = 0; 10419 mHighDischargeAmountSinceCharge = 0; 10420 mDischargeAmountScreenOn = 0; 10421 mDischargeAmountScreenOnSinceCharge = 0; 10422 mDischargeAmountScreenOff = 0; 10423 mDischargeAmountScreenOffSinceCharge = 0; 10424 mDischargeAmountScreenDoze = 0; 10425 mDischargeAmountScreenDozeSinceCharge = 0; 10426 mDischargeStepTracker.init(); 10427 mChargeStepTracker.init(); 10428 mDischargeScreenOffCounter.reset(false); 10429 mDischargeScreenDozeCounter.reset(false); 10430 mDischargeLightDozeCounter.reset(false); 10431 mDischargeDeepDozeCounter.reset(false); 10432 mDischargeCounter.reset(false); 10433 } 10434 resetAllStatsCmdLocked()10435 public void resetAllStatsCmdLocked() { 10436 resetAllStatsLocked(); 10437 final long mSecUptime = mClocks.uptimeMillis(); 10438 long uptime = mSecUptime * 1000; 10439 long mSecRealtime = mClocks.elapsedRealtime(); 10440 long realtime = mSecRealtime * 1000; 10441 mDischargeStartLevel = mHistoryCur.batteryLevel; 10442 pullPendingStateUpdatesLocked(); 10443 addHistoryRecordLocked(mSecRealtime, mSecUptime); 10444 mDischargeCurrentLevel = mDischargeUnplugLevel = mDischargePlugLevel 10445 = mCurrentBatteryLevel = mHistoryCur.batteryLevel; 10446 mOnBatteryTimeBase.reset(uptime, realtime); 10447 mOnBatteryScreenOffTimeBase.reset(uptime, realtime); 10448 if ((mHistoryCur.states&HistoryItem.STATE_BATTERY_PLUGGED_FLAG) == 0) { 10449 if (isScreenOn(mScreenState)) { 10450 mDischargeScreenOnUnplugLevel = mHistoryCur.batteryLevel; 10451 mDischargeScreenDozeUnplugLevel = 0; 10452 mDischargeScreenOffUnplugLevel = 0; 10453 } else if (isScreenDoze(mScreenState)) { 10454 mDischargeScreenOnUnplugLevel = 0; 10455 mDischargeScreenDozeUnplugLevel = mHistoryCur.batteryLevel; 10456 mDischargeScreenOffUnplugLevel = 0; 10457 } else { 10458 mDischargeScreenOnUnplugLevel = 0; 10459 mDischargeScreenDozeUnplugLevel = 0; 10460 mDischargeScreenOffUnplugLevel = mHistoryCur.batteryLevel; 10461 } 10462 mDischargeAmountScreenOn = 0; 10463 mDischargeAmountScreenOff = 0; 10464 mDischargeAmountScreenDoze = 0; 10465 } 10466 initActiveHistoryEventsLocked(mSecRealtime, mSecUptime); 10467 } 10468 resetAllStatsLocked()10469 private void resetAllStatsLocked() { 10470 final long uptimeMillis = mClocks.uptimeMillis(); 10471 final long elapsedRealtimeMillis = mClocks.elapsedRealtime(); 10472 mStartCount = 0; 10473 initTimes(uptimeMillis * 1000, elapsedRealtimeMillis * 1000); 10474 mScreenOnTimer.reset(false); 10475 mScreenDozeTimer.reset(false); 10476 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 10477 mScreenBrightnessTimer[i].reset(false); 10478 } 10479 10480 if (mPowerProfile != null) { 10481 mEstimatedBatteryCapacity = (int) mPowerProfile.getBatteryCapacity(); 10482 } else { 10483 mEstimatedBatteryCapacity = -1; 10484 } 10485 mMinLearnedBatteryCapacity = -1; 10486 mMaxLearnedBatteryCapacity = -1; 10487 mInteractiveTimer.reset(false); 10488 mPowerSaveModeEnabledTimer.reset(false); 10489 mLastIdleTimeStart = elapsedRealtimeMillis; 10490 mLongestLightIdleTime = 0; 10491 mLongestFullIdleTime = 0; 10492 mDeviceIdleModeLightTimer.reset(false); 10493 mDeviceIdleModeFullTimer.reset(false); 10494 mDeviceLightIdlingTimer.reset(false); 10495 mDeviceIdlingTimer.reset(false); 10496 mPhoneOnTimer.reset(false); 10497 mAudioOnTimer.reset(false); 10498 mVideoOnTimer.reset(false); 10499 mFlashlightOnTimer.reset(false); 10500 mCameraOnTimer.reset(false); 10501 mBluetoothScanTimer.reset(false); 10502 for (int i = 0; i < CellSignalStrength.getNumSignalStrengthLevels(); i++) { 10503 mPhoneSignalStrengthsTimer[i].reset(false); 10504 } 10505 mPhoneSignalScanningTimer.reset(false); 10506 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 10507 mPhoneDataConnectionsTimer[i].reset(false); 10508 } 10509 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 10510 mNetworkByteActivityCounters[i].reset(false); 10511 mNetworkPacketActivityCounters[i].reset(false); 10512 } 10513 mMobileRadioActiveTimer.reset(false); 10514 mMobileRadioActivePerAppTimer.reset(false); 10515 mMobileRadioActiveAdjustedTime.reset(false); 10516 mMobileRadioActiveUnknownTime.reset(false); 10517 mMobileRadioActiveUnknownCount.reset(false); 10518 mWifiOnTimer.reset(false); 10519 mGlobalWifiRunningTimer.reset(false); 10520 for (int i=0; i<NUM_WIFI_STATES; i++) { 10521 mWifiStateTimer[i].reset(false); 10522 } 10523 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) { 10524 mWifiSupplStateTimer[i].reset(false); 10525 } 10526 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { 10527 mWifiSignalStrengthsTimer[i].reset(false); 10528 } 10529 mWifiMulticastWakelockTimer.reset(false); 10530 mWifiActiveTimer.reset(false); 10531 mWifiActivity.reset(false); 10532 for (int i=0; i< GnssMetrics.NUM_GPS_SIGNAL_QUALITY_LEVELS; i++) { 10533 mGpsSignalQualityTimer[i].reset(false); 10534 } 10535 mBluetoothActivity.reset(false); 10536 mModemActivity.reset(false); 10537 mNumConnectivityChange = 0; 10538 10539 for (int i=0; i<mUidStats.size(); i++) { 10540 if (mUidStats.valueAt(i).reset(uptimeMillis * 1000, elapsedRealtimeMillis * 1000)) { 10541 mUidStats.valueAt(i).detachFromTimeBase(); 10542 mUidStats.remove(mUidStats.keyAt(i)); 10543 i--; 10544 } 10545 } 10546 10547 if (mRpmStats.size() > 0) { 10548 for (SamplingTimer timer : mRpmStats.values()) { 10549 mOnBatteryTimeBase.remove(timer); 10550 } 10551 mRpmStats.clear(); 10552 } 10553 if (mScreenOffRpmStats.size() > 0) { 10554 for (SamplingTimer timer : mScreenOffRpmStats.values()) { 10555 mOnBatteryScreenOffTimeBase.remove(timer); 10556 } 10557 mScreenOffRpmStats.clear(); 10558 } 10559 10560 if (mKernelWakelockStats.size() > 0) { 10561 for (SamplingTimer timer : mKernelWakelockStats.values()) { 10562 mOnBatteryScreenOffTimeBase.remove(timer); 10563 } 10564 mKernelWakelockStats.clear(); 10565 } 10566 10567 if (mKernelMemoryStats.size() > 0) { 10568 for (int i = 0; i < mKernelMemoryStats.size(); i++) { 10569 mOnBatteryTimeBase.remove(mKernelMemoryStats.valueAt(i)); 10570 } 10571 mKernelMemoryStats.clear(); 10572 } 10573 10574 if (mWakeupReasonStats.size() > 0) { 10575 for (SamplingTimer timer : mWakeupReasonStats.values()) { 10576 mOnBatteryTimeBase.remove(timer); 10577 } 10578 mWakeupReasonStats.clear(); 10579 } 10580 10581 mTmpRailStats.reset(); 10582 10583 mLastHistoryStepDetails = null; 10584 mLastStepCpuUserTime = mLastStepCpuSystemTime = 0; 10585 mCurStepCpuUserTime = mCurStepCpuSystemTime = 0; 10586 mLastStepCpuUserTime = mCurStepCpuUserTime = 0; 10587 mLastStepCpuSystemTime = mCurStepCpuSystemTime = 0; 10588 mLastStepStatUserTime = mCurStepStatUserTime = 0; 10589 mLastStepStatSystemTime = mCurStepStatSystemTime = 0; 10590 mLastStepStatIOWaitTime = mCurStepStatIOWaitTime = 0; 10591 mLastStepStatIrqTime = mCurStepStatIrqTime = 0; 10592 mLastStepStatSoftIrqTime = mCurStepStatSoftIrqTime = 0; 10593 mLastStepStatIdleTime = mCurStepStatIdleTime = 0; 10594 10595 mNumAllUidCpuTimeReads = 0; 10596 mNumUidsRemoved = 0; 10597 10598 initDischarge(); 10599 10600 clearHistoryLocked(); 10601 mBatteryStatsHistory.resetAllFiles(); 10602 10603 mHandler.sendEmptyMessage(MSG_REPORT_RESET_STATS); 10604 } 10605 initActiveHistoryEventsLocked(long elapsedRealtimeMs, long uptimeMs)10606 private void initActiveHistoryEventsLocked(long elapsedRealtimeMs, long uptimeMs) { 10607 for (int i=0; i<HistoryItem.EVENT_COUNT; i++) { 10608 if (!mRecordAllHistory && i == HistoryItem.EVENT_PROC) { 10609 // Not recording process starts/stops. 10610 continue; 10611 } 10612 HashMap<String, SparseIntArray> active = mActiveEvents.getStateForEvent(i); 10613 if (active == null) { 10614 continue; 10615 } 10616 for (HashMap.Entry<String, SparseIntArray> ent : active.entrySet()) { 10617 SparseIntArray uids = ent.getValue(); 10618 for (int j=0; j<uids.size(); j++) { 10619 addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, i, ent.getKey(), 10620 uids.keyAt(j)); 10621 } 10622 } 10623 } 10624 } 10625 updateDischargeScreenLevelsLocked(int oldState, int newState)10626 void updateDischargeScreenLevelsLocked(int oldState, int newState) { 10627 updateOldDischargeScreenLevelLocked(oldState); 10628 updateNewDischargeScreenLevelLocked(newState); 10629 } 10630 updateOldDischargeScreenLevelLocked(int state)10631 private void updateOldDischargeScreenLevelLocked(int state) { 10632 if (isScreenOn(state)) { 10633 int diff = mDischargeScreenOnUnplugLevel - mDischargeCurrentLevel; 10634 if (diff > 0) { 10635 mDischargeAmountScreenOn += diff; 10636 mDischargeAmountScreenOnSinceCharge += diff; 10637 } 10638 } else if (isScreenDoze(state)) { 10639 int diff = mDischargeScreenDozeUnplugLevel - mDischargeCurrentLevel; 10640 if (diff > 0) { 10641 mDischargeAmountScreenDoze += diff; 10642 mDischargeAmountScreenDozeSinceCharge += diff; 10643 } 10644 } else if (isScreenOff(state)){ 10645 int diff = mDischargeScreenOffUnplugLevel - mDischargeCurrentLevel; 10646 if (diff > 0) { 10647 mDischargeAmountScreenOff += diff; 10648 mDischargeAmountScreenOffSinceCharge += diff; 10649 } 10650 } 10651 } 10652 updateNewDischargeScreenLevelLocked(int state)10653 private void updateNewDischargeScreenLevelLocked(int state) { 10654 if (isScreenOn(state)) { 10655 mDischargeScreenOnUnplugLevel = mDischargeCurrentLevel; 10656 mDischargeScreenOffUnplugLevel = 0; 10657 mDischargeScreenDozeUnplugLevel = 0; 10658 } else if (isScreenDoze(state)){ 10659 mDischargeScreenOnUnplugLevel = 0; 10660 mDischargeScreenDozeUnplugLevel = mDischargeCurrentLevel; 10661 mDischargeScreenOffUnplugLevel = 0; 10662 } else if (isScreenOff(state)) { 10663 mDischargeScreenOnUnplugLevel = 0; 10664 mDischargeScreenDozeUnplugLevel = 0; 10665 mDischargeScreenOffUnplugLevel = mDischargeCurrentLevel; 10666 } 10667 } 10668 pullPendingStateUpdatesLocked()10669 public void pullPendingStateUpdatesLocked() { 10670 if (mOnBatteryInternal) { 10671 updateDischargeScreenLevelsLocked(mScreenState, mScreenState); 10672 } 10673 } 10674 10675 private final Pools.Pool<NetworkStats> mNetworkStatsPool = new Pools.SynchronizedPool<>(6); 10676 10677 private final Object mWifiNetworkLock = new Object(); 10678 10679 @GuardedBy("mWifiNetworkLock") 10680 private String[] mWifiIfaces = EmptyArray.STRING; 10681 10682 @GuardedBy("mWifiNetworkLock") 10683 private NetworkStats mLastWifiNetworkStats = new NetworkStats(0, -1); 10684 10685 private final Object mModemNetworkLock = new Object(); 10686 10687 @GuardedBy("mModemNetworkLock") 10688 private String[] mModemIfaces = EmptyArray.STRING; 10689 10690 @GuardedBy("mModemNetworkLock") 10691 private NetworkStats mLastModemNetworkStats = new NetworkStats(0, -1); 10692 readNetworkStatsLocked(String[] ifaces)10693 private NetworkStats readNetworkStatsLocked(String[] ifaces) { 10694 try { 10695 if (!ArrayUtils.isEmpty(ifaces)) { 10696 INetworkStatsService statsService = INetworkStatsService.Stub.asInterface( 10697 ServiceManager.getService(Context.NETWORK_STATS_SERVICE)); 10698 if (statsService != null) { 10699 return statsService.getDetailedUidStats(ifaces); 10700 } else { 10701 Slog.e(TAG, "Failed to get networkStatsService "); 10702 } 10703 } 10704 } catch (RemoteException e) { 10705 Slog.e(TAG, "failed to read network stats for ifaces: " + Arrays.toString(ifaces) + e); 10706 } 10707 return null; 10708 } 10709 10710 /** 10711 * Distribute WiFi energy info and network traffic to apps. 10712 * @param info The energy information from the WiFi controller. 10713 */ updateWifiState(@ullable final WifiActivityEnergyInfo info)10714 public void updateWifiState(@Nullable final WifiActivityEnergyInfo info) { 10715 if (DEBUG_ENERGY) { 10716 Slog.d(TAG, "Updating wifi stats: " + Arrays.toString(mWifiIfaces)); 10717 } 10718 10719 // Grab a separate lock to acquire the network stats, which may do I/O. 10720 NetworkStats delta = null; 10721 synchronized (mWifiNetworkLock) { 10722 final NetworkStats latestStats = readNetworkStatsLocked(mWifiIfaces); 10723 if (latestStats != null) { 10724 delta = NetworkStats.subtract(latestStats, mLastWifiNetworkStats, null, null, 10725 mNetworkStatsPool.acquire()); 10726 mNetworkStatsPool.release(mLastWifiNetworkStats); 10727 mLastWifiNetworkStats = latestStats; 10728 } 10729 } 10730 10731 synchronized (this) { 10732 if (!mOnBatteryInternal) { 10733 if (delta != null) { 10734 mNetworkStatsPool.release(delta); 10735 } 10736 return; 10737 } 10738 10739 final long elapsedRealtimeMs = mClocks.elapsedRealtime(); 10740 SparseLongArray rxPackets = new SparseLongArray(); 10741 SparseLongArray txPackets = new SparseLongArray(); 10742 long totalTxPackets = 0; 10743 long totalRxPackets = 0; 10744 if (delta != null) { 10745 NetworkStats.Entry entry = new NetworkStats.Entry(); 10746 final int size = delta.size(); 10747 for (int i = 0; i < size; i++) { 10748 entry = delta.getValues(i, entry); 10749 10750 if (DEBUG_ENERGY) { 10751 Slog.d(TAG, "Wifi uid " + entry.uid + ": delta rx=" + entry.rxBytes 10752 + " tx=" + entry.txBytes + " rxPackets=" + entry.rxPackets 10753 + " txPackets=" + entry.txPackets); 10754 } 10755 10756 if (entry.rxBytes == 0 && entry.txBytes == 0) { 10757 // Skip the lookup below since there is no work to do. 10758 continue; 10759 } 10760 10761 final Uid u = getUidStatsLocked(mapUid(entry.uid)); 10762 if (entry.rxBytes != 0) { 10763 u.noteNetworkActivityLocked(NETWORK_WIFI_RX_DATA, entry.rxBytes, 10764 entry.rxPackets); 10765 if (entry.set == NetworkStats.SET_DEFAULT) { // Background transfers 10766 u.noteNetworkActivityLocked(NETWORK_WIFI_BG_RX_DATA, entry.rxBytes, 10767 entry.rxPackets); 10768 } 10769 mNetworkByteActivityCounters[NETWORK_WIFI_RX_DATA].addCountLocked( 10770 entry.rxBytes); 10771 mNetworkPacketActivityCounters[NETWORK_WIFI_RX_DATA].addCountLocked( 10772 entry.rxPackets); 10773 10774 rxPackets.put(u.getUid(), entry.rxPackets); 10775 10776 // Sum the total number of packets so that the Rx Power can 10777 // be evenly distributed amongst the apps. 10778 totalRxPackets += entry.rxPackets; 10779 } 10780 10781 if (entry.txBytes != 0) { 10782 u.noteNetworkActivityLocked(NETWORK_WIFI_TX_DATA, entry.txBytes, 10783 entry.txPackets); 10784 if (entry.set == NetworkStats.SET_DEFAULT) { // Background transfers 10785 u.noteNetworkActivityLocked(NETWORK_WIFI_BG_TX_DATA, entry.txBytes, 10786 entry.txPackets); 10787 } 10788 mNetworkByteActivityCounters[NETWORK_WIFI_TX_DATA].addCountLocked( 10789 entry.txBytes); 10790 mNetworkPacketActivityCounters[NETWORK_WIFI_TX_DATA].addCountLocked( 10791 entry.txPackets); 10792 10793 txPackets.put(u.getUid(), entry.txPackets); 10794 10795 // Sum the total number of packets so that the Tx Power can 10796 // be evenly distributed amongst the apps. 10797 totalTxPackets += entry.txPackets; 10798 } 10799 } 10800 mNetworkStatsPool.release(delta); 10801 delta = null; 10802 } 10803 10804 if (info != null) { 10805 mHasWifiReporting = true; 10806 10807 // Measured in mAms 10808 final long txTimeMs = info.getControllerTxTimeMillis(); 10809 final long rxTimeMs = info.getControllerRxTimeMillis(); 10810 final long scanTimeMs = info.getControllerScanTimeMillis(); 10811 final long idleTimeMs = info.getControllerIdleTimeMillis(); 10812 final long totalTimeMs = txTimeMs + rxTimeMs + idleTimeMs; 10813 10814 long leftOverRxTimeMs = rxTimeMs; 10815 long leftOverTxTimeMs = txTimeMs; 10816 10817 if (DEBUG_ENERGY) { 10818 Slog.d(TAG, "------ BEGIN WiFi power blaming ------"); 10819 Slog.d(TAG, " Tx Time: " + txTimeMs + " ms"); 10820 Slog.d(TAG, " Rx Time: " + rxTimeMs + " ms"); 10821 Slog.d(TAG, " Idle Time: " + idleTimeMs + " ms"); 10822 Slog.d(TAG, " Total Time: " + totalTimeMs + " ms"); 10823 Slog.d(TAG, " Scan Time: " + scanTimeMs + " ms"); 10824 } 10825 10826 long totalWifiLockTimeMs = 0; 10827 long totalScanTimeMs = 0; 10828 10829 // On the first pass, collect some totals so that we can normalize power 10830 // calculations if we need to. 10831 final int uidStatsSize = mUidStats.size(); 10832 for (int i = 0; i < uidStatsSize; i++) { 10833 final Uid uid = mUidStats.valueAt(i); 10834 10835 // Sum the total scan power for all apps. 10836 totalScanTimeMs += uid.mWifiScanTimer.getTimeSinceMarkLocked( 10837 elapsedRealtimeMs * 1000) / 1000; 10838 10839 // Sum the total time holding wifi lock for all apps. 10840 totalWifiLockTimeMs += uid.mFullWifiLockTimer.getTimeSinceMarkLocked( 10841 elapsedRealtimeMs * 1000) / 1000; 10842 } 10843 10844 if (DEBUG_ENERGY && totalScanTimeMs > rxTimeMs) { 10845 Slog.d(TAG, 10846 " !Estimated scan time > Actual rx time (" + totalScanTimeMs + " ms > " 10847 + rxTimeMs + " ms). Normalizing scan time."); 10848 } 10849 if (DEBUG_ENERGY && totalScanTimeMs > txTimeMs) { 10850 Slog.d(TAG, 10851 " !Estimated scan time > Actual tx time (" + totalScanTimeMs + " ms > " 10852 + txTimeMs + " ms). Normalizing scan time."); 10853 } 10854 10855 // Actually assign and distribute power usage to apps. 10856 for (int i = 0; i < uidStatsSize; i++) { 10857 final Uid uid = mUidStats.valueAt(i); 10858 10859 long scanTimeSinceMarkMs = uid.mWifiScanTimer.getTimeSinceMarkLocked( 10860 elapsedRealtimeMs * 1000) / 1000; 10861 if (scanTimeSinceMarkMs > 0) { 10862 // Set the new mark so that next time we get new data since this point. 10863 uid.mWifiScanTimer.setMark(elapsedRealtimeMs); 10864 10865 long scanRxTimeSinceMarkMs = scanTimeSinceMarkMs; 10866 long scanTxTimeSinceMarkMs = scanTimeSinceMarkMs; 10867 10868 // Our total scan time is more than the reported Tx/Rx time. 10869 // This is possible because the cost of a scan is approximate. 10870 // Let's normalize the result so that we evenly blame each app 10871 // scanning. 10872 // 10873 // This means that we may have apps that transmitted/received packets not be 10874 // blamed for this, but this is fine as scans are relatively more expensive. 10875 if (totalScanTimeMs > rxTimeMs) { 10876 scanRxTimeSinceMarkMs = (rxTimeMs * scanRxTimeSinceMarkMs) / 10877 totalScanTimeMs; 10878 } 10879 if (totalScanTimeMs > txTimeMs) { 10880 scanTxTimeSinceMarkMs = (txTimeMs * scanTxTimeSinceMarkMs) / 10881 totalScanTimeMs; 10882 } 10883 10884 if (DEBUG_ENERGY) { 10885 Slog.d(TAG, " ScanTime for UID " + uid.getUid() + ": Rx:" 10886 + scanRxTimeSinceMarkMs + " ms Tx:" 10887 + scanTxTimeSinceMarkMs + " ms)"); 10888 } 10889 10890 ControllerActivityCounterImpl activityCounter = 10891 uid.getOrCreateWifiControllerActivityLocked(); 10892 activityCounter.getRxTimeCounter().addCountLocked(scanRxTimeSinceMarkMs); 10893 activityCounter.getTxTimeCounters()[0].addCountLocked( 10894 scanTxTimeSinceMarkMs); 10895 leftOverRxTimeMs -= scanRxTimeSinceMarkMs; 10896 leftOverTxTimeMs -= scanTxTimeSinceMarkMs; 10897 } 10898 10899 // Distribute evenly the power consumed while Idle to each app holding a WiFi 10900 // lock. 10901 final long wifiLockTimeSinceMarkMs = 10902 uid.mFullWifiLockTimer.getTimeSinceMarkLocked( 10903 elapsedRealtimeMs * 1000) / 1000; 10904 if (wifiLockTimeSinceMarkMs > 0) { 10905 // Set the new mark so that next time we get new data since this point. 10906 uid.mFullWifiLockTimer.setMark(elapsedRealtimeMs); 10907 10908 final long myIdleTimeMs = (wifiLockTimeSinceMarkMs * idleTimeMs) 10909 / totalWifiLockTimeMs; 10910 if (DEBUG_ENERGY) { 10911 Slog.d(TAG, " IdleTime for UID " + uid.getUid() + ": " 10912 + myIdleTimeMs + " ms"); 10913 } 10914 uid.getOrCreateWifiControllerActivityLocked().getIdleTimeCounter() 10915 .addCountLocked(myIdleTimeMs); 10916 } 10917 } 10918 10919 if (DEBUG_ENERGY) { 10920 Slog.d(TAG, " New RxPower: " + leftOverRxTimeMs + " ms"); 10921 Slog.d(TAG, " New TxPower: " + leftOverTxTimeMs + " ms"); 10922 } 10923 10924 // Distribute the remaining Tx power appropriately between all apps that transmitted 10925 // packets. 10926 for (int i = 0; i < txPackets.size(); i++) { 10927 final Uid uid = getUidStatsLocked(txPackets.keyAt(i)); 10928 final long myTxTimeMs = (txPackets.valueAt(i) * leftOverTxTimeMs) 10929 / totalTxPackets; 10930 if (DEBUG_ENERGY) { 10931 Slog.d(TAG, " TxTime for UID " + uid.getUid() + ": " + myTxTimeMs + " ms"); 10932 } 10933 uid.getOrCreateWifiControllerActivityLocked().getTxTimeCounters()[0] 10934 .addCountLocked(myTxTimeMs); 10935 } 10936 10937 // Distribute the remaining Rx power appropriately between all apps that received 10938 // packets. 10939 for (int i = 0; i < rxPackets.size(); i++) { 10940 final Uid uid = getUidStatsLocked(rxPackets.keyAt(i)); 10941 final long myRxTimeMs = (rxPackets.valueAt(i) * leftOverRxTimeMs) 10942 / totalRxPackets; 10943 if (DEBUG_ENERGY) { 10944 Slog.d(TAG, " RxTime for UID " + uid.getUid() + ": " + myRxTimeMs + " ms"); 10945 } 10946 uid.getOrCreateWifiControllerActivityLocked().getRxTimeCounter() 10947 .addCountLocked(myRxTimeMs); 10948 } 10949 10950 // Any left over power use will be picked up by the WiFi category in BatteryStatsHelper. 10951 10952 10953 // Update WiFi controller stats. 10954 mWifiActivity.getRxTimeCounter().addCountLocked(info.getControllerRxTimeMillis()); 10955 mWifiActivity.getTxTimeCounters()[0].addCountLocked( 10956 info.getControllerTxTimeMillis()); 10957 mWifiActivity.getScanTimeCounter().addCountLocked( 10958 info.getControllerScanTimeMillis()); 10959 mWifiActivity.getIdleTimeCounter().addCountLocked( 10960 info.getControllerIdleTimeMillis()); 10961 10962 // POWER_WIFI_CONTROLLER_OPERATING_VOLTAGE is measured in mV, so convert to V. 10963 final double opVolt = mPowerProfile.getAveragePower( 10964 PowerProfile.POWER_WIFI_CONTROLLER_OPERATING_VOLTAGE) / 1000.0; 10965 if (opVolt != 0) { 10966 // We store the power drain as mAms. 10967 mWifiActivity.getPowerCounter().addCountLocked( 10968 (long) (info.getControllerEnergyUsed() / opVolt)); 10969 } 10970 // Converting uWs to mAms. 10971 // Conversion: (uWs * (1000ms / 1s) * (1mW / 1000uW)) / mV = mAms 10972 long monitoredRailChargeConsumedMaMs = 10973 (long) (mTmpRailStats.getWifiTotalEnergyUseduWs() / opVolt); 10974 mWifiActivity.getMonitoredRailChargeConsumedMaMs().addCountLocked( 10975 monitoredRailChargeConsumedMaMs); 10976 mHistoryCur.wifiRailChargeMah += 10977 (monitoredRailChargeConsumedMaMs / MILLISECONDS_IN_HOUR); 10978 addHistoryRecordLocked(mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 10979 mTmpRailStats.resetWifiTotalEnergyUsed(); 10980 } 10981 } 10982 } 10983 10984 private ModemActivityInfo mLastModemActivityInfo = 10985 new ModemActivityInfo(0, 0, 0, new int[0], 0); 10986 getDeltaModemActivityInfo(ModemActivityInfo activityInfo)10987 private ModemActivityInfo getDeltaModemActivityInfo(ModemActivityInfo activityInfo) { 10988 if (activityInfo == null) { 10989 return null; 10990 } 10991 int[] txTimeMs = new int[ModemActivityInfo.TX_POWER_LEVELS]; 10992 for (int i = 0; i < ModemActivityInfo.TX_POWER_LEVELS; i++) { 10993 txTimeMs[i] = activityInfo.getTransmitPowerInfo().get(i).getTimeInMillis() 10994 - mLastModemActivityInfo.getTransmitPowerInfo().get(i).getTimeInMillis(); 10995 } 10996 ModemActivityInfo deltaInfo = new ModemActivityInfo(activityInfo.getTimestamp(), 10997 activityInfo.getSleepTimeMillis() - mLastModemActivityInfo.getSleepTimeMillis(), 10998 activityInfo.getIdleTimeMillis() - mLastModemActivityInfo.getIdleTimeMillis(), 10999 txTimeMs, 11000 activityInfo.getReceiveTimeMillis() - mLastModemActivityInfo.getReceiveTimeMillis()); 11001 mLastModemActivityInfo = activityInfo; 11002 return deltaInfo; 11003 } 11004 11005 /** 11006 * Distribute Cell radio energy info and network traffic to apps. 11007 */ updateMobileRadioState(@ullable final ModemActivityInfo activityInfo)11008 public void updateMobileRadioState(@Nullable final ModemActivityInfo activityInfo) { 11009 if (DEBUG_ENERGY) { 11010 Slog.d(TAG, "Updating mobile radio stats with " + activityInfo); 11011 } 11012 ModemActivityInfo deltaInfo = getDeltaModemActivityInfo(activityInfo); 11013 11014 // Add modem tx power to history. 11015 addModemTxPowerToHistory(deltaInfo); 11016 11017 // Grab a separate lock to acquire the network stats, which may do I/O. 11018 NetworkStats delta = null; 11019 synchronized (mModemNetworkLock) { 11020 final NetworkStats latestStats = readNetworkStatsLocked(mModemIfaces); 11021 if (latestStats != null) { 11022 delta = NetworkStats.subtract(latestStats, mLastModemNetworkStats, null, null, 11023 mNetworkStatsPool.acquire()); 11024 mNetworkStatsPool.release(mLastModemNetworkStats); 11025 mLastModemNetworkStats = latestStats; 11026 } 11027 } 11028 11029 synchronized (this) { 11030 if (!mOnBatteryInternal) { 11031 if (delta != null) { 11032 mNetworkStatsPool.release(delta); 11033 } 11034 return; 11035 } 11036 11037 if (deltaInfo != null) { 11038 mHasModemReporting = true; 11039 mModemActivity.getIdleTimeCounter().addCountLocked( 11040 deltaInfo.getIdleTimeMillis()); 11041 mModemActivity.getSleepTimeCounter().addCountLocked( 11042 deltaInfo.getSleepTimeMillis()); 11043 mModemActivity.getRxTimeCounter().addCountLocked(deltaInfo.getReceiveTimeMillis()); 11044 for (int lvl = 0; lvl < ModemActivityInfo.TX_POWER_LEVELS; lvl++) { 11045 mModemActivity.getTxTimeCounters()[lvl] 11046 .addCountLocked(deltaInfo.getTransmitPowerInfo() 11047 .get(lvl).getTimeInMillis()); 11048 } 11049 11050 // POWER_MODEM_CONTROLLER_OPERATING_VOLTAGE is measured in mV, so convert to V. 11051 final double opVolt = mPowerProfile.getAveragePower( 11052 PowerProfile.POWER_MODEM_CONTROLLER_OPERATING_VOLTAGE) / 1000.0; 11053 if (opVolt != 0) { 11054 double energyUsed = 11055 deltaInfo.getSleepTimeMillis() * 11056 mPowerProfile.getAveragePower(PowerProfile.POWER_MODEM_CONTROLLER_SLEEP) 11057 + deltaInfo.getIdleTimeMillis() * 11058 mPowerProfile.getAveragePower(PowerProfile.POWER_MODEM_CONTROLLER_IDLE) 11059 + deltaInfo.getReceiveTimeMillis() * 11060 mPowerProfile.getAveragePower(PowerProfile.POWER_MODEM_CONTROLLER_RX); 11061 11062 List<TransmitPower> txPowerInfo = deltaInfo.getTransmitPowerInfo(); 11063 for (int i = 0; i < Math.min(txPowerInfo.size(), 11064 SignalStrength.NUM_SIGNAL_STRENGTH_BINS); i++) { 11065 energyUsed += txPowerInfo.get(i).getTimeInMillis() * mPowerProfile 11066 .getAveragePower(PowerProfile.POWER_MODEM_CONTROLLER_TX, i); 11067 } 11068 11069 // We store the power drain as mAms. 11070 mModemActivity.getPowerCounter().addCountLocked((long) energyUsed); 11071 // Converting uWs to mAms. 11072 // Conversion: (uWs * (1000ms / 1s) * (1mW / 1000uW)) / mV = mAms 11073 long monitoredRailChargeConsumedMaMs = 11074 (long) (mTmpRailStats.getCellularTotalEnergyUseduWs() / opVolt); 11075 mModemActivity.getMonitoredRailChargeConsumedMaMs().addCountLocked( 11076 monitoredRailChargeConsumedMaMs); 11077 mHistoryCur.modemRailChargeMah += 11078 (monitoredRailChargeConsumedMaMs / MILLISECONDS_IN_HOUR); 11079 addHistoryRecordLocked(mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 11080 mTmpRailStats.resetCellularTotalEnergyUsed(); 11081 } 11082 } 11083 final long elapsedRealtimeMs = mClocks.elapsedRealtime(); 11084 long radioTime = mMobileRadioActivePerAppTimer.getTimeSinceMarkLocked( 11085 elapsedRealtimeMs * 1000); 11086 mMobileRadioActivePerAppTimer.setMark(elapsedRealtimeMs); 11087 11088 long totalRxPackets = 0; 11089 long totalTxPackets = 0; 11090 if (delta != null) { 11091 NetworkStats.Entry entry = new NetworkStats.Entry(); 11092 final int size = delta.size(); 11093 for (int i = 0; i < size; i++) { 11094 entry = delta.getValues(i, entry); 11095 if (entry.rxPackets == 0 && entry.txPackets == 0) { 11096 continue; 11097 } 11098 11099 if (DEBUG_ENERGY) { 11100 Slog.d(TAG, "Mobile uid " + entry.uid + ": delta rx=" + entry.rxBytes 11101 + " tx=" + entry.txBytes + " rxPackets=" + entry.rxPackets 11102 + " txPackets=" + entry.txPackets); 11103 } 11104 11105 totalRxPackets += entry.rxPackets; 11106 totalTxPackets += entry.txPackets; 11107 11108 final Uid u = getUidStatsLocked(mapUid(entry.uid)); 11109 u.noteNetworkActivityLocked(NETWORK_MOBILE_RX_DATA, entry.rxBytes, 11110 entry.rxPackets); 11111 u.noteNetworkActivityLocked(NETWORK_MOBILE_TX_DATA, entry.txBytes, 11112 entry.txPackets); 11113 if (entry.set == NetworkStats.SET_DEFAULT) { // Background transfers 11114 u.noteNetworkActivityLocked(NETWORK_MOBILE_BG_RX_DATA, 11115 entry.rxBytes, entry.rxPackets); 11116 u.noteNetworkActivityLocked(NETWORK_MOBILE_BG_TX_DATA, 11117 entry.txBytes, entry.txPackets); 11118 } 11119 11120 mNetworkByteActivityCounters[NETWORK_MOBILE_RX_DATA].addCountLocked( 11121 entry.rxBytes); 11122 mNetworkByteActivityCounters[NETWORK_MOBILE_TX_DATA].addCountLocked( 11123 entry.txBytes); 11124 mNetworkPacketActivityCounters[NETWORK_MOBILE_RX_DATA].addCountLocked( 11125 entry.rxPackets); 11126 mNetworkPacketActivityCounters[NETWORK_MOBILE_TX_DATA].addCountLocked( 11127 entry.txPackets); 11128 } 11129 11130 // Now distribute proportional blame to the apps that did networking. 11131 long totalPackets = totalRxPackets + totalTxPackets; 11132 if (totalPackets > 0) { 11133 for (int i = 0; i < size; i++) { 11134 entry = delta.getValues(i, entry); 11135 if (entry.rxPackets == 0 && entry.txPackets == 0) { 11136 continue; 11137 } 11138 11139 final Uid u = getUidStatsLocked(mapUid(entry.uid)); 11140 11141 // Distribute total radio active time in to this app. 11142 final long appPackets = entry.rxPackets + entry.txPackets; 11143 final long appRadioTime = (radioTime * appPackets) / totalPackets; 11144 u.noteMobileRadioActiveTimeLocked(appRadioTime); 11145 11146 // Remove this app from the totals, so that we don't lose any time 11147 // due to rounding. 11148 radioTime -= appRadioTime; 11149 totalPackets -= appPackets; 11150 11151 if (deltaInfo != null) { 11152 ControllerActivityCounterImpl activityCounter = 11153 u.getOrCreateModemControllerActivityLocked(); 11154 if (totalRxPackets > 0 && entry.rxPackets > 0) { 11155 final long rxMs = (entry.rxPackets 11156 * deltaInfo.getReceiveTimeMillis()) / totalRxPackets; 11157 activityCounter.getRxTimeCounter().addCountLocked(rxMs); 11158 } 11159 11160 if (totalTxPackets > 0 && entry.txPackets > 0) { 11161 for (int lvl = 0; lvl < ModemActivityInfo.TX_POWER_LEVELS; lvl++) { 11162 long txMs = 11163 entry.txPackets * deltaInfo.getTransmitPowerInfo() 11164 .get(lvl).getTimeInMillis(); 11165 txMs /= totalTxPackets; 11166 activityCounter.getTxTimeCounters()[lvl].addCountLocked(txMs); 11167 } 11168 } 11169 } 11170 } 11171 } 11172 11173 if (radioTime > 0) { 11174 // Whoops, there is some radio time we can't blame on an app! 11175 mMobileRadioActiveUnknownTime.addCountLocked(radioTime); 11176 mMobileRadioActiveUnknownCount.addCountLocked(1); 11177 } 11178 11179 mNetworkStatsPool.release(delta); 11180 delta = null; 11181 } 11182 } 11183 } 11184 11185 /** 11186 * Add modem tx power to history 11187 * Device is said to be in high cellular transmit power when it has spent most of the transmit 11188 * time at the highest power level. 11189 * @param activityInfo 11190 */ addModemTxPowerToHistory(final ModemActivityInfo activityInfo)11191 private synchronized void addModemTxPowerToHistory(final ModemActivityInfo activityInfo) { 11192 if (activityInfo == null) { 11193 return; 11194 } 11195 List<TransmitPower> txPowerInfo = activityInfo.getTransmitPowerInfo(); 11196 if (txPowerInfo == null || txPowerInfo.size() != ModemActivityInfo.TX_POWER_LEVELS) { 11197 return; 11198 } 11199 final long elapsedRealtime = mClocks.elapsedRealtime(); 11200 final long uptime = mClocks.uptimeMillis(); 11201 int levelMaxTimeSpent = 0; 11202 for (int i = 1; i < txPowerInfo.size(); i++) { 11203 if (txPowerInfo.get(i).getTimeInMillis() > txPowerInfo.get(levelMaxTimeSpent) 11204 .getTimeInMillis()) { 11205 levelMaxTimeSpent = i; 11206 } 11207 } 11208 if (levelMaxTimeSpent == ModemActivityInfo.TX_POWER_LEVELS - 1) { 11209 mHistoryCur.states2 |= HistoryItem.STATE2_CELLULAR_HIGH_TX_POWER_FLAG; 11210 addHistoryRecordLocked(elapsedRealtime, uptime); 11211 } 11212 } 11213 11214 private final class BluetoothActivityInfoCache { 11215 long idleTimeMs; 11216 long rxTimeMs; 11217 long txTimeMs; 11218 long energy; 11219 11220 SparseLongArray uidRxBytes = new SparseLongArray(); 11221 SparseLongArray uidTxBytes = new SparseLongArray(); 11222 set(BluetoothActivityEnergyInfo info)11223 void set(BluetoothActivityEnergyInfo info) { 11224 idleTimeMs = info.getControllerIdleTimeMillis(); 11225 rxTimeMs = info.getControllerRxTimeMillis(); 11226 txTimeMs = info.getControllerTxTimeMillis(); 11227 energy = info.getControllerEnergyUsed(); 11228 if (info.getUidTraffic() != null) { 11229 for (UidTraffic traffic : info.getUidTraffic()) { 11230 uidRxBytes.put(traffic.getUid(), traffic.getRxBytes()); 11231 uidTxBytes.put(traffic.getUid(), traffic.getTxBytes()); 11232 } 11233 } 11234 } 11235 } 11236 11237 private final BluetoothActivityInfoCache mLastBluetoothActivityInfo 11238 = new BluetoothActivityInfoCache(); 11239 11240 /** 11241 * Distribute Bluetooth energy info and network traffic to apps. 11242 * 11243 * @param info The energy information from the bluetooth controller. 11244 */ updateBluetoothStateLocked(@ullable final BluetoothActivityEnergyInfo info)11245 public void updateBluetoothStateLocked(@Nullable final BluetoothActivityEnergyInfo info) { 11246 if (DEBUG_ENERGY) { 11247 Slog.d(TAG, "Updating bluetooth stats: " + info); 11248 } 11249 11250 if (info == null || !mOnBatteryInternal) { 11251 return; 11252 } 11253 11254 mHasBluetoothReporting = true; 11255 11256 final long elapsedRealtimeMs = mClocks.elapsedRealtime(); 11257 final long rxTimeMs = 11258 info.getControllerRxTimeMillis() - mLastBluetoothActivityInfo.rxTimeMs; 11259 final long txTimeMs = 11260 info.getControllerTxTimeMillis() - mLastBluetoothActivityInfo.txTimeMs; 11261 final long idleTimeMs = 11262 info.getControllerIdleTimeMillis() - mLastBluetoothActivityInfo.idleTimeMs; 11263 11264 if (DEBUG_ENERGY) { 11265 Slog.d(TAG, "------ BEGIN BLE power blaming ------"); 11266 Slog.d(TAG, " Tx Time: " + txTimeMs + " ms"); 11267 Slog.d(TAG, " Rx Time: " + rxTimeMs + " ms"); 11268 Slog.d(TAG, " Idle Time: " + idleTimeMs + " ms"); 11269 } 11270 11271 long totalScanTimeMs = 0; 11272 11273 final int uidCount = mUidStats.size(); 11274 for (int i = 0; i < uidCount; i++) { 11275 final Uid u = mUidStats.valueAt(i); 11276 if (u.mBluetoothScanTimer == null) { 11277 continue; 11278 } 11279 11280 totalScanTimeMs += u.mBluetoothScanTimer.getTimeSinceMarkLocked( 11281 elapsedRealtimeMs * 1000) / 1000; 11282 } 11283 11284 final boolean normalizeScanRxTime = (totalScanTimeMs > rxTimeMs); 11285 final boolean normalizeScanTxTime = (totalScanTimeMs > txTimeMs); 11286 11287 if (DEBUG_ENERGY) { 11288 Slog.d(TAG, "Normalizing scan power for RX=" + normalizeScanRxTime 11289 + " TX=" + normalizeScanTxTime); 11290 } 11291 11292 long leftOverRxTimeMs = rxTimeMs; 11293 long leftOverTxTimeMs = txTimeMs; 11294 11295 for (int i = 0; i < uidCount; i++) { 11296 final Uid u = mUidStats.valueAt(i); 11297 if (u.mBluetoothScanTimer == null) { 11298 continue; 11299 } 11300 11301 long scanTimeSinceMarkMs = u.mBluetoothScanTimer.getTimeSinceMarkLocked( 11302 elapsedRealtimeMs * 1000) / 1000; 11303 if (scanTimeSinceMarkMs > 0) { 11304 // Set the new mark so that next time we get new data since this point. 11305 u.mBluetoothScanTimer.setMark(elapsedRealtimeMs); 11306 11307 long scanTimeRxSinceMarkMs = scanTimeSinceMarkMs; 11308 long scanTimeTxSinceMarkMs = scanTimeSinceMarkMs; 11309 11310 if (normalizeScanRxTime) { 11311 // Scan time is longer than the total rx time in the controller, 11312 // so distribute the scan time proportionately. This means regular traffic 11313 // will not blamed, but scans are more expensive anyways. 11314 scanTimeRxSinceMarkMs = (rxTimeMs * scanTimeRxSinceMarkMs) / totalScanTimeMs; 11315 } 11316 11317 if (normalizeScanTxTime) { 11318 // Scan time is longer than the total tx time in the controller, 11319 // so distribute the scan time proportionately. This means regular traffic 11320 // will not blamed, but scans are more expensive anyways. 11321 scanTimeTxSinceMarkMs = (txTimeMs * scanTimeTxSinceMarkMs) / totalScanTimeMs; 11322 } 11323 11324 final ControllerActivityCounterImpl counter = 11325 u.getOrCreateBluetoothControllerActivityLocked(); 11326 counter.getRxTimeCounter().addCountLocked(scanTimeRxSinceMarkMs); 11327 counter.getTxTimeCounters()[0].addCountLocked(scanTimeTxSinceMarkMs); 11328 11329 leftOverRxTimeMs -= scanTimeRxSinceMarkMs; 11330 leftOverTxTimeMs -= scanTimeTxSinceMarkMs; 11331 } 11332 } 11333 11334 if (DEBUG_ENERGY) { 11335 Slog.d(TAG, "Left over time for traffic RX=" + leftOverRxTimeMs + " TX=" 11336 + leftOverTxTimeMs); 11337 } 11338 11339 // 11340 // Now distribute blame to apps that did bluetooth traffic. 11341 // 11342 11343 long totalTxBytes = 0; 11344 long totalRxBytes = 0; 11345 11346 final UidTraffic[] uidTraffic = info.getUidTraffic(); 11347 final int numUids = uidTraffic != null ? uidTraffic.length : 0; 11348 for (int i = 0; i < numUids; i++) { 11349 final UidTraffic traffic = uidTraffic[i]; 11350 final long rxBytes = traffic.getRxBytes() - mLastBluetoothActivityInfo.uidRxBytes.get( 11351 traffic.getUid()); 11352 final long txBytes = traffic.getTxBytes() - mLastBluetoothActivityInfo.uidTxBytes.get( 11353 traffic.getUid()); 11354 11355 // Add to the global counters. 11356 mNetworkByteActivityCounters[NETWORK_BT_RX_DATA].addCountLocked(rxBytes); 11357 mNetworkByteActivityCounters[NETWORK_BT_TX_DATA].addCountLocked(txBytes); 11358 11359 // Add to the UID counters. 11360 final Uid u = getUidStatsLocked(mapUid(traffic.getUid())); 11361 u.noteNetworkActivityLocked(NETWORK_BT_RX_DATA, rxBytes, 0); 11362 u.noteNetworkActivityLocked(NETWORK_BT_TX_DATA, txBytes, 0); 11363 11364 // Calculate the total traffic. 11365 totalRxBytes += rxBytes; 11366 totalTxBytes += txBytes; 11367 } 11368 11369 if ((totalTxBytes != 0 || totalRxBytes != 0) && (leftOverRxTimeMs != 0 11370 || leftOverTxTimeMs != 0)) { 11371 for (int i = 0; i < numUids; i++) { 11372 final UidTraffic traffic = uidTraffic[i]; 11373 final int uid = traffic.getUid(); 11374 final long rxBytes = 11375 traffic.getRxBytes() - mLastBluetoothActivityInfo.uidRxBytes.get(uid); 11376 final long txBytes = 11377 traffic.getTxBytes() - mLastBluetoothActivityInfo.uidTxBytes.get(uid); 11378 11379 final Uid u = getUidStatsLocked(mapUid(uid)); 11380 final ControllerActivityCounterImpl counter = 11381 u.getOrCreateBluetoothControllerActivityLocked(); 11382 11383 if (totalRxBytes > 0 && rxBytes > 0) { 11384 final long timeRxMs = (leftOverRxTimeMs * rxBytes) / totalRxBytes; 11385 if (DEBUG_ENERGY) { 11386 Slog.d(TAG, "UID=" + uid + " rx_bytes=" + rxBytes + " rx_time=" + timeRxMs); 11387 } 11388 counter.getRxTimeCounter().addCountLocked(timeRxMs); 11389 } 11390 11391 if (totalTxBytes > 0 && txBytes > 0) { 11392 final long timeTxMs = (leftOverTxTimeMs * txBytes) / totalTxBytes; 11393 if (DEBUG_ENERGY) { 11394 Slog.d(TAG, "UID=" + uid + " tx_bytes=" + txBytes + " tx_time=" + timeTxMs); 11395 } 11396 counter.getTxTimeCounters()[0].addCountLocked(timeTxMs); 11397 } 11398 } 11399 } 11400 11401 mBluetoothActivity.getRxTimeCounter().addCountLocked(rxTimeMs); 11402 mBluetoothActivity.getTxTimeCounters()[0].addCountLocked(txTimeMs); 11403 mBluetoothActivity.getIdleTimeCounter().addCountLocked(idleTimeMs); 11404 11405 // POWER_BLUETOOTH_CONTROLLER_OPERATING_VOLTAGE is measured in mV, so convert to V. 11406 final double opVolt = mPowerProfile.getAveragePower( 11407 PowerProfile.POWER_BLUETOOTH_CONTROLLER_OPERATING_VOLTAGE) / 1000.0; 11408 if (opVolt != 0) { 11409 // We store the power drain as mAms. 11410 mBluetoothActivity.getPowerCounter().addCountLocked( 11411 (long) ((info.getControllerEnergyUsed() - mLastBluetoothActivityInfo.energy) 11412 / opVolt)); 11413 } 11414 mLastBluetoothActivityInfo.set(info); 11415 } 11416 11417 /** 11418 * Read and record Resource Power Manager (RPM) state and voter times. 11419 * If RPM stats were fetched more recently than RPM_STATS_UPDATE_FREQ_MS ago, uses the old data 11420 * instead of fetching it anew. 11421 */ updateRpmStatsLocked()11422 public void updateRpmStatsLocked() { 11423 if (mPlatformIdleStateCallback == null) return; 11424 long now = SystemClock.elapsedRealtime(); 11425 if (now - mLastRpmStatsUpdateTimeMs >= RPM_STATS_UPDATE_FREQ_MS) { 11426 mPlatformIdleStateCallback.fillLowPowerStats(mTmpRpmStats); 11427 mLastRpmStatsUpdateTimeMs = now; 11428 } 11429 11430 for (Map.Entry<String, RpmStats.PowerStatePlatformSleepState> pstate 11431 : mTmpRpmStats.mPlatformLowPowerStats.entrySet()) { 11432 11433 // Update values for this platform state. 11434 final String pName = pstate.getKey(); 11435 final long pTimeUs = pstate.getValue().mTimeMs * 1000; 11436 final int pCount = pstate.getValue().mCount; 11437 getRpmTimerLocked(pName).update(pTimeUs, pCount); 11438 if (SCREEN_OFF_RPM_STATS_ENABLED) { 11439 getScreenOffRpmTimerLocked(pName).update(pTimeUs, pCount); 11440 } 11441 11442 // Update values for each voter of this platform state. 11443 for (Map.Entry<String, RpmStats.PowerStateElement> voter 11444 : pstate.getValue().mVoters.entrySet()) { 11445 final String vName = pName + "." + voter.getKey(); 11446 final long vTimeUs = voter.getValue().mTimeMs * 1000; 11447 final int vCount = voter.getValue().mCount; 11448 getRpmTimerLocked(vName).update(vTimeUs, vCount); 11449 if (SCREEN_OFF_RPM_STATS_ENABLED) { 11450 getScreenOffRpmTimerLocked(vName).update(vTimeUs, vCount); 11451 } 11452 } 11453 } 11454 11455 for (Map.Entry<String, RpmStats.PowerStateSubsystem> subsys 11456 : mTmpRpmStats.mSubsystemLowPowerStats.entrySet()) { 11457 11458 final String subsysName = subsys.getKey(); 11459 for (Map.Entry<String, RpmStats.PowerStateElement> sstate 11460 : subsys.getValue().mStates.entrySet()) { 11461 final String name = subsysName + "." + sstate.getKey(); 11462 final long timeUs = sstate.getValue().mTimeMs * 1000; 11463 final int count = sstate.getValue().mCount; 11464 getRpmTimerLocked(name).update(timeUs, count); 11465 if (SCREEN_OFF_RPM_STATS_ENABLED) { 11466 getScreenOffRpmTimerLocked(name).update(timeUs, count); 11467 } 11468 } 11469 } 11470 } 11471 11472 /** 11473 * Read and record Rail Energy data. 11474 */ updateRailStatsLocked()11475 public void updateRailStatsLocked() { 11476 if (mRailEnergyDataCallback == null || !mTmpRailStats.isRailStatsAvailable()) { 11477 return; 11478 } 11479 mRailEnergyDataCallback.fillRailDataStats(mTmpRailStats); 11480 } 11481 11482 /** 11483 * Read and distribute kernel wake lock use across apps. 11484 */ updateKernelWakelocksLocked()11485 public void updateKernelWakelocksLocked() { 11486 final KernelWakelockStats wakelockStats = mKernelWakelockReader.readKernelWakelockStats( 11487 mTmpWakelockStats); 11488 if (wakelockStats == null) { 11489 // Not crashing might make board bringup easier. 11490 Slog.w(TAG, "Couldn't get kernel wake lock stats"); 11491 return; 11492 } 11493 11494 for (Map.Entry<String, KernelWakelockStats.Entry> ent : wakelockStats.entrySet()) { 11495 String name = ent.getKey(); 11496 KernelWakelockStats.Entry kws = ent.getValue(); 11497 11498 SamplingTimer kwlt = mKernelWakelockStats.get(name); 11499 if (kwlt == null) { 11500 kwlt = new SamplingTimer(mClocks, mOnBatteryScreenOffTimeBase); 11501 mKernelWakelockStats.put(name, kwlt); 11502 } 11503 11504 kwlt.update(kws.mTotalTime, kws.mCount); 11505 kwlt.setUpdateVersion(kws.mVersion); 11506 } 11507 11508 int numWakelocksSetStale = 0; 11509 // Set timers to stale if they didn't appear in /d/wakeup_sources (or /proc/wakelocks) 11510 // this time. 11511 for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) { 11512 SamplingTimer st = ent.getValue(); 11513 if (st.getUpdateVersion() != wakelockStats.kernelWakelockVersion) { 11514 st.endSample(); 11515 numWakelocksSetStale++; 11516 } 11517 } 11518 11519 // Record whether we've seen a non-zero time (for debugging b/22716723). 11520 if (wakelockStats.isEmpty()) { 11521 Slog.wtf(TAG, "All kernel wakelocks had time of zero"); 11522 } 11523 11524 if (numWakelocksSetStale == mKernelWakelockStats.size()) { 11525 Slog.wtf(TAG, "All kernel wakelocks were set stale. new version=" + 11526 wakelockStats.kernelWakelockVersion); 11527 } 11528 } 11529 11530 // We use an anonymous class to access these variables, 11531 // so they can't live on the stack or they'd have to be 11532 // final MutableLong objects (more allocations). 11533 // Used in updateCpuTimeLocked(). 11534 long mTempTotalCpuUserTimeUs; 11535 long mTempTotalCpuSystemTimeUs; 11536 long[][] mWakeLockAllocationsUs; 11537 11538 /** 11539 * Reads the newest memory stats from the kernel. 11540 */ updateKernelMemoryBandwidthLocked()11541 public void updateKernelMemoryBandwidthLocked() { 11542 mKernelMemoryBandwidthStats.updateStats(); 11543 LongSparseLongArray bandwidthEntries = mKernelMemoryBandwidthStats.getBandwidthEntries(); 11544 final int bandwidthEntryCount = bandwidthEntries.size(); 11545 int index; 11546 for (int i = 0; i < bandwidthEntryCount; i++) { 11547 SamplingTimer timer; 11548 if ((index = mKernelMemoryStats.indexOfKey(bandwidthEntries.keyAt(i))) >= 0) { 11549 timer = mKernelMemoryStats.valueAt(index); 11550 } else { 11551 timer = new SamplingTimer(mClocks, mOnBatteryTimeBase); 11552 mKernelMemoryStats.put(bandwidthEntries.keyAt(i), timer); 11553 } 11554 timer.update(bandwidthEntries.valueAt(i), 1); 11555 if (DEBUG_MEMORY) { 11556 Slog.d(TAG, String.format("Added entry %d and updated timer to: " 11557 + "mUnpluggedReportedTotalTime %d size %d", bandwidthEntries.keyAt(i), 11558 mKernelMemoryStats.get( 11559 bandwidthEntries.keyAt(i)).mUnpluggedReportedTotalTime, 11560 mKernelMemoryStats.size())); 11561 } 11562 } 11563 } 11564 isOnBatteryLocked()11565 public boolean isOnBatteryLocked() { 11566 return mOnBatteryTimeBase.isRunning(); 11567 } 11568 isOnBatteryScreenOffLocked()11569 public boolean isOnBatteryScreenOffLocked() { 11570 return mOnBatteryScreenOffTimeBase.isRunning(); 11571 } 11572 11573 /** 11574 * Read and distribute CPU usage across apps. If their are partial wakelocks being held 11575 * and we are on battery with screen off, we give more of the cpu time to those apps holding 11576 * wakelocks. If the screen is on, we just assign the actual cpu time an app used. 11577 * It's possible this will be invoked after the internal battery/screen states are updated, so 11578 * passing the appropriate battery/screen states to try attribute the cpu times to correct 11579 * buckets. 11580 */ 11581 @GuardedBy("this") updateCpuTimeLocked(boolean onBattery, boolean onBatteryScreenOff)11582 public void updateCpuTimeLocked(boolean onBattery, boolean onBatteryScreenOff) { 11583 if (mPowerProfile == null) { 11584 return; 11585 } 11586 11587 if (DEBUG_ENERGY_CPU) { 11588 Slog.d(TAG, "!Cpu updating!"); 11589 } 11590 11591 if (mCpuFreqs == null) { 11592 mCpuFreqs = mCpuUidFreqTimeReader.readFreqs(mPowerProfile); 11593 } 11594 11595 // Calculate the wakelocks we have to distribute amongst. The system is excluded as it is 11596 // usually holding the wakelock on behalf of an app. 11597 // And Only distribute cpu power to wakelocks if the screen is off and we're on battery. 11598 ArrayList<StopwatchTimer> partialTimersToConsider = null; 11599 if (onBatteryScreenOff) { 11600 partialTimersToConsider = new ArrayList<>(); 11601 for (int i = mPartialTimers.size() - 1; i >= 0; --i) { 11602 final StopwatchTimer timer = mPartialTimers.get(i); 11603 // Since the collection and blaming of wakelocks can be scheduled to run after 11604 // some delay, the mPartialTimers list may have new entries. We can't blame 11605 // the newly added timer for past cpu time, so we only consider timers that 11606 // were present for one round of collection. Once a timer has gone through 11607 // a round of collection, its mInList field is set to true. 11608 if (timer.mInList && timer.mUid != null && timer.mUid.mUid != Process.SYSTEM_UID) { 11609 partialTimersToConsider.add(timer); 11610 } 11611 } 11612 } 11613 markPartialTimersAsEligible(); 11614 11615 // When the battery is not on, we don't attribute the cpu times to any timers but we still 11616 // need to take the snapshots. 11617 if (!onBattery) { 11618 mCpuUidUserSysTimeReader.readDelta(null); 11619 mCpuUidFreqTimeReader.readDelta(null); 11620 mNumAllUidCpuTimeReads += 2; 11621 if (mConstants.TRACK_CPU_ACTIVE_CLUSTER_TIME) { 11622 mCpuUidActiveTimeReader.readDelta(null); 11623 mCpuUidClusterTimeReader.readDelta(null); 11624 mNumAllUidCpuTimeReads += 2; 11625 } 11626 for (int cluster = mKernelCpuSpeedReaders.length - 1; cluster >= 0; --cluster) { 11627 mKernelCpuSpeedReaders[cluster].readDelta(); 11628 } 11629 return; 11630 } 11631 11632 mUserInfoProvider.refreshUserIds(); 11633 final SparseLongArray updatedUids = mCpuUidFreqTimeReader.perClusterTimesAvailable() 11634 ? null : new SparseLongArray(); 11635 readKernelUidCpuTimesLocked(partialTimersToConsider, updatedUids, onBattery); 11636 // updatedUids=null means /proc/uid_time_in_state provides snapshots of per-cluster cpu 11637 // freqs, so no need to approximate these values. 11638 if (updatedUids != null) { 11639 updateClusterSpeedTimes(updatedUids, onBattery); 11640 } 11641 readKernelUidCpuFreqTimesLocked(partialTimersToConsider, onBattery, onBatteryScreenOff); 11642 mNumAllUidCpuTimeReads += 2; 11643 if (mConstants.TRACK_CPU_ACTIVE_CLUSTER_TIME) { 11644 readKernelUidCpuActiveTimesLocked(onBattery); 11645 readKernelUidCpuClusterTimesLocked(onBattery); 11646 mNumAllUidCpuTimeReads += 2; 11647 } 11648 } 11649 11650 /** 11651 * Mark the current partial timers as gone through a collection so that they will be 11652 * considered in the next cpu times distribution to wakelock holders. 11653 */ 11654 @VisibleForTesting markPartialTimersAsEligible()11655 public void markPartialTimersAsEligible() { 11656 if (ArrayUtils.referenceEquals(mPartialTimers, mLastPartialTimers)) { 11657 // No difference, so each timer is now considered for the next collection. 11658 for (int i = mPartialTimers.size() - 1; i >= 0; --i) { 11659 mPartialTimers.get(i).mInList = true; 11660 } 11661 } else { 11662 // The lists are different, meaning we added (or removed a timer) since the last 11663 // collection. 11664 for (int i = mLastPartialTimers.size() - 1; i >= 0; --i) { 11665 mLastPartialTimers.get(i).mInList = false; 11666 } 11667 mLastPartialTimers.clear(); 11668 11669 // Mark the current timers as gone through a collection. 11670 final int numPartialTimers = mPartialTimers.size(); 11671 for (int i = 0; i < numPartialTimers; ++i) { 11672 final StopwatchTimer timer = mPartialTimers.get(i); 11673 timer.mInList = true; 11674 mLastPartialTimers.add(timer); 11675 } 11676 } 11677 } 11678 11679 /** 11680 * Take snapshot of cpu times (aggregated over all uids) at different frequencies and 11681 * calculate cpu times spent by each uid at different frequencies. 11682 * 11683 * @param updatedUids The uids for which times spent at different frequencies are calculated. 11684 */ 11685 @VisibleForTesting updateClusterSpeedTimes(@onNull SparseLongArray updatedUids, boolean onBattery)11686 public void updateClusterSpeedTimes(@NonNull SparseLongArray updatedUids, boolean onBattery) { 11687 long totalCpuClustersTimeMs = 0; 11688 // Read the time spent for each cluster at various cpu frequencies. 11689 final long[][] clusterSpeedTimesMs = new long[mKernelCpuSpeedReaders.length][]; 11690 for (int cluster = 0; cluster < mKernelCpuSpeedReaders.length; cluster++) { 11691 clusterSpeedTimesMs[cluster] = mKernelCpuSpeedReaders[cluster].readDelta(); 11692 if (clusterSpeedTimesMs[cluster] != null) { 11693 for (int speed = clusterSpeedTimesMs[cluster].length - 1; speed >= 0; --speed) { 11694 totalCpuClustersTimeMs += clusterSpeedTimesMs[cluster][speed]; 11695 } 11696 } 11697 } 11698 if (totalCpuClustersTimeMs != 0) { 11699 // We have cpu times per freq aggregated over all uids but we need the times per uid. 11700 // So, we distribute total time spent by an uid to different cpu freqs based on the 11701 // amount of time cpu was running at that freq. 11702 final int updatedUidsCount = updatedUids.size(); 11703 for (int i = 0; i < updatedUidsCount; ++i) { 11704 final Uid u = getUidStatsLocked(updatedUids.keyAt(i)); 11705 final long appCpuTimeUs = updatedUids.valueAt(i); 11706 // Add the cpu speeds to this UID. 11707 final int numClusters = mPowerProfile.getNumCpuClusters(); 11708 if (u.mCpuClusterSpeedTimesUs == null || 11709 u.mCpuClusterSpeedTimesUs.length != numClusters) { 11710 u.mCpuClusterSpeedTimesUs = new LongSamplingCounter[numClusters][]; 11711 } 11712 11713 for (int cluster = 0; cluster < clusterSpeedTimesMs.length; cluster++) { 11714 final int speedsInCluster = clusterSpeedTimesMs[cluster].length; 11715 if (u.mCpuClusterSpeedTimesUs[cluster] == null || speedsInCluster != 11716 u.mCpuClusterSpeedTimesUs[cluster].length) { 11717 u.mCpuClusterSpeedTimesUs[cluster] 11718 = new LongSamplingCounter[speedsInCluster]; 11719 } 11720 11721 final LongSamplingCounter[] cpuSpeeds = u.mCpuClusterSpeedTimesUs[cluster]; 11722 for (int speed = 0; speed < speedsInCluster; speed++) { 11723 if (cpuSpeeds[speed] == null) { 11724 cpuSpeeds[speed] = new LongSamplingCounter(mOnBatteryTimeBase); 11725 } 11726 cpuSpeeds[speed].addCountLocked(appCpuTimeUs 11727 * clusterSpeedTimesMs[cluster][speed] 11728 / totalCpuClustersTimeMs, onBattery); 11729 } 11730 } 11731 } 11732 } 11733 } 11734 11735 /** 11736 * Take a snapshot of the cpu times spent by each uid and update the corresponding counters. 11737 * If {@param partialTimers} is not null and empty, then we assign a portion of cpu times to 11738 * wakelock holders. 11739 * 11740 * @param partialTimers The wakelock holders among which the cpu times will be distributed. 11741 * @param updatedUids If not null, then the uids found in the snapshot will be added to this. 11742 */ 11743 @VisibleForTesting readKernelUidCpuTimesLocked(@ullable ArrayList<StopwatchTimer> partialTimers, @Nullable SparseLongArray updatedUids, boolean onBattery)11744 public void readKernelUidCpuTimesLocked(@Nullable ArrayList<StopwatchTimer> partialTimers, 11745 @Nullable SparseLongArray updatedUids, boolean onBattery) { 11746 mTempTotalCpuUserTimeUs = mTempTotalCpuSystemTimeUs = 0; 11747 final int numWakelocks = partialTimers == null ? 0 : partialTimers.size(); 11748 final long startTimeMs = mClocks.uptimeMillis(); 11749 11750 mCpuUidUserSysTimeReader.readDelta((uid, timesUs) -> { 11751 long userTimeUs = timesUs[0], systemTimeUs = timesUs[1]; 11752 11753 uid = mapUid(uid); 11754 if (Process.isIsolated(uid)) { 11755 // This could happen if the isolated uid mapping was removed before that process 11756 // was actually killed. 11757 mCpuUidUserSysTimeReader.removeUid(uid); 11758 Slog.d(TAG, "Got readings for an isolated uid with no mapping: " + uid); 11759 return; 11760 } 11761 if (!mUserInfoProvider.exists(UserHandle.getUserId(uid))) { 11762 Slog.d(TAG, "Got readings for an invalid user's uid " + uid); 11763 mCpuUidUserSysTimeReader.removeUid(uid); 11764 return; 11765 } 11766 final Uid u = getUidStatsLocked(uid); 11767 11768 // Accumulate the total system and user time. 11769 mTempTotalCpuUserTimeUs += userTimeUs; 11770 mTempTotalCpuSystemTimeUs += systemTimeUs; 11771 11772 StringBuilder sb = null; 11773 if (DEBUG_ENERGY_CPU) { 11774 sb = new StringBuilder(); 11775 sb.append(" got time for uid=").append(u.mUid).append(": u="); 11776 TimeUtils.formatDuration(userTimeUs / 1000, sb); 11777 sb.append(" s="); 11778 TimeUtils.formatDuration(systemTimeUs / 1000, sb); 11779 sb.append("\n"); 11780 } 11781 11782 if (numWakelocks > 0) { 11783 // We have wakelocks being held, so only give a portion of the 11784 // time to the process. The rest will be distributed among wakelock 11785 // holders. 11786 userTimeUs = (userTimeUs * WAKE_LOCK_WEIGHT) / 100; 11787 systemTimeUs = (systemTimeUs * WAKE_LOCK_WEIGHT) / 100; 11788 } 11789 11790 if (sb != null) { 11791 sb.append(" adding to uid=").append(u.mUid).append(": u="); 11792 TimeUtils.formatDuration(userTimeUs / 1000, sb); 11793 sb.append(" s="); 11794 TimeUtils.formatDuration(systemTimeUs / 1000, sb); 11795 Slog.d(TAG, sb.toString()); 11796 } 11797 11798 u.mUserCpuTime.addCountLocked(userTimeUs, onBattery); 11799 u.mSystemCpuTime.addCountLocked(systemTimeUs, onBattery); 11800 if (updatedUids != null) { 11801 updatedUids.put(u.getUid(), userTimeUs + systemTimeUs); 11802 } 11803 }); 11804 11805 final long elapsedTimeMs = mClocks.uptimeMillis() - startTimeMs; 11806 if (DEBUG_ENERGY_CPU || elapsedTimeMs >= 100) { 11807 Slog.d(TAG, "Reading cpu stats took " + elapsedTimeMs + "ms"); 11808 } 11809 11810 if (numWakelocks > 0) { 11811 // Distribute a portion of the total cpu time to wakelock holders. 11812 mTempTotalCpuUserTimeUs = (mTempTotalCpuUserTimeUs * (100 - WAKE_LOCK_WEIGHT)) / 100; 11813 mTempTotalCpuSystemTimeUs = 11814 (mTempTotalCpuSystemTimeUs * (100 - WAKE_LOCK_WEIGHT)) / 100; 11815 11816 for (int i = 0; i < numWakelocks; ++i) { 11817 final StopwatchTimer timer = partialTimers.get(i); 11818 final int userTimeUs = (int) (mTempTotalCpuUserTimeUs / (numWakelocks - i)); 11819 final int systemTimeUs = (int) (mTempTotalCpuSystemTimeUs / (numWakelocks - i)); 11820 11821 if (DEBUG_ENERGY_CPU) { 11822 final StringBuilder sb = new StringBuilder(); 11823 sb.append(" Distributing wakelock uid=").append(timer.mUid.mUid) 11824 .append(": u="); 11825 TimeUtils.formatDuration(userTimeUs / 1000, sb); 11826 sb.append(" s="); 11827 TimeUtils.formatDuration(systemTimeUs / 1000, sb); 11828 Slog.d(TAG, sb.toString()); 11829 } 11830 11831 timer.mUid.mUserCpuTime.addCountLocked(userTimeUs, onBattery); 11832 timer.mUid.mSystemCpuTime.addCountLocked(systemTimeUs, onBattery); 11833 if (updatedUids != null) { 11834 final int uid = timer.mUid.getUid(); 11835 updatedUids.put(uid, updatedUids.get(uid, 0) + userTimeUs + systemTimeUs); 11836 } 11837 11838 final Uid.Proc proc = timer.mUid.getProcessStatsLocked("*wakelock*"); 11839 proc.addCpuTimeLocked(userTimeUs / 1000, systemTimeUs / 1000, onBattery); 11840 11841 mTempTotalCpuUserTimeUs -= userTimeUs; 11842 mTempTotalCpuSystemTimeUs -= systemTimeUs; 11843 } 11844 } 11845 } 11846 11847 /** 11848 * Take a snapshot of the cpu times spent by each uid in each freq and update the 11849 * corresponding counters. 11850 * 11851 * @param partialTimers The wakelock holders among which the cpu freq times will be distributed. 11852 */ 11853 @VisibleForTesting readKernelUidCpuFreqTimesLocked(@ullable ArrayList<StopwatchTimer> partialTimers, boolean onBattery, boolean onBatteryScreenOff)11854 public void readKernelUidCpuFreqTimesLocked(@Nullable ArrayList<StopwatchTimer> partialTimers, 11855 boolean onBattery, boolean onBatteryScreenOff) { 11856 final boolean perClusterTimesAvailable = 11857 mCpuUidFreqTimeReader.perClusterTimesAvailable(); 11858 final int numWakelocks = partialTimers == null ? 0 : partialTimers.size(); 11859 final int numClusters = mPowerProfile.getNumCpuClusters(); 11860 mWakeLockAllocationsUs = null; 11861 final long startTimeMs = mClocks.uptimeMillis(); 11862 mCpuUidFreqTimeReader.readDelta((uid, cpuFreqTimeMs) -> { 11863 uid = mapUid(uid); 11864 if (Process.isIsolated(uid)) { 11865 mCpuUidFreqTimeReader.removeUid(uid); 11866 Slog.d(TAG, "Got freq readings for an isolated uid with no mapping: " + uid); 11867 return; 11868 } 11869 if (!mUserInfoProvider.exists(UserHandle.getUserId(uid))) { 11870 Slog.d(TAG, "Got freq readings for an invalid user's uid " + uid); 11871 mCpuUidFreqTimeReader.removeUid(uid); 11872 return; 11873 } 11874 final Uid u = getUidStatsLocked(uid); 11875 if (u.mCpuFreqTimeMs == null || u.mCpuFreqTimeMs.getSize() != cpuFreqTimeMs.length) { 11876 detachIfNotNull(u.mCpuFreqTimeMs); 11877 u.mCpuFreqTimeMs = new LongSamplingCounterArray(mOnBatteryTimeBase); 11878 } 11879 u.mCpuFreqTimeMs.addCountLocked(cpuFreqTimeMs, onBattery); 11880 if (u.mScreenOffCpuFreqTimeMs == null || 11881 u.mScreenOffCpuFreqTimeMs.getSize() != cpuFreqTimeMs.length) { 11882 detachIfNotNull(u.mScreenOffCpuFreqTimeMs); 11883 u.mScreenOffCpuFreqTimeMs = new LongSamplingCounterArray( 11884 mOnBatteryScreenOffTimeBase); 11885 } 11886 u.mScreenOffCpuFreqTimeMs.addCountLocked(cpuFreqTimeMs, onBatteryScreenOff); 11887 11888 if (perClusterTimesAvailable) { 11889 if (u.mCpuClusterSpeedTimesUs == null || 11890 u.mCpuClusterSpeedTimesUs.length != numClusters) { 11891 detachIfNotNull(u.mCpuClusterSpeedTimesUs); 11892 u.mCpuClusterSpeedTimesUs = new LongSamplingCounter[numClusters][]; 11893 } 11894 if (numWakelocks > 0 && mWakeLockAllocationsUs == null) { 11895 mWakeLockAllocationsUs = new long[numClusters][]; 11896 } 11897 11898 int freqIndex = 0; 11899 for (int cluster = 0; cluster < numClusters; ++cluster) { 11900 final int speedsInCluster = mPowerProfile.getNumSpeedStepsInCpuCluster(cluster); 11901 if (u.mCpuClusterSpeedTimesUs[cluster] == null || 11902 u.mCpuClusterSpeedTimesUs[cluster].length != speedsInCluster) { 11903 detachIfNotNull(u.mCpuClusterSpeedTimesUs[cluster]); 11904 u.mCpuClusterSpeedTimesUs[cluster] 11905 = new LongSamplingCounter[speedsInCluster]; 11906 } 11907 if (numWakelocks > 0 && mWakeLockAllocationsUs[cluster] == null) { 11908 mWakeLockAllocationsUs[cluster] = new long[speedsInCluster]; 11909 } 11910 final LongSamplingCounter[] cpuTimesUs = u.mCpuClusterSpeedTimesUs[cluster]; 11911 for (int speed = 0; speed < speedsInCluster; ++speed) { 11912 if (cpuTimesUs[speed] == null) { 11913 cpuTimesUs[speed] = new LongSamplingCounter(mOnBatteryTimeBase); 11914 } 11915 final long appAllocationUs; 11916 if (mWakeLockAllocationsUs != null) { 11917 appAllocationUs = 11918 (cpuFreqTimeMs[freqIndex] * 1000 * WAKE_LOCK_WEIGHT) / 100; 11919 mWakeLockAllocationsUs[cluster][speed] += 11920 (cpuFreqTimeMs[freqIndex] * 1000 - appAllocationUs); 11921 } else { 11922 appAllocationUs = cpuFreqTimeMs[freqIndex] * 1000; 11923 } 11924 cpuTimesUs[speed].addCountLocked(appAllocationUs, onBattery); 11925 freqIndex++; 11926 } 11927 } 11928 } 11929 }); 11930 11931 final long elapsedTimeMs = mClocks.uptimeMillis() - startTimeMs; 11932 if (DEBUG_ENERGY_CPU || elapsedTimeMs >= 100) { 11933 Slog.d(TAG, "Reading cpu freq times took " + elapsedTimeMs + "ms"); 11934 } 11935 11936 if (mWakeLockAllocationsUs != null) { 11937 for (int i = 0; i < numWakelocks; ++i) { 11938 final Uid u = partialTimers.get(i).mUid; 11939 if (u.mCpuClusterSpeedTimesUs == null || 11940 u.mCpuClusterSpeedTimesUs.length != numClusters) { 11941 detachIfNotNull(u.mCpuClusterSpeedTimesUs); 11942 u.mCpuClusterSpeedTimesUs = new LongSamplingCounter[numClusters][]; 11943 } 11944 11945 for (int cluster = 0; cluster < numClusters; ++cluster) { 11946 final int speedsInCluster = mPowerProfile.getNumSpeedStepsInCpuCluster(cluster); 11947 if (u.mCpuClusterSpeedTimesUs[cluster] == null || 11948 u.mCpuClusterSpeedTimesUs[cluster].length != speedsInCluster) { 11949 detachIfNotNull(u.mCpuClusterSpeedTimesUs[cluster]); 11950 u.mCpuClusterSpeedTimesUs[cluster] 11951 = new LongSamplingCounter[speedsInCluster]; 11952 } 11953 final LongSamplingCounter[] cpuTimeUs = u.mCpuClusterSpeedTimesUs[cluster]; 11954 for (int speed = 0; speed < speedsInCluster; ++speed) { 11955 if (cpuTimeUs[speed] == null) { 11956 cpuTimeUs[speed] = new LongSamplingCounter(mOnBatteryTimeBase); 11957 } 11958 final long allocationUs = 11959 mWakeLockAllocationsUs[cluster][speed] / (numWakelocks - i); 11960 cpuTimeUs[speed].addCountLocked(allocationUs, onBattery); 11961 mWakeLockAllocationsUs[cluster][speed] -= allocationUs; 11962 } 11963 } 11964 } 11965 } 11966 } 11967 11968 /** 11969 * Take a snapshot of the cpu active times spent by each uid and update the corresponding 11970 * counters. 11971 */ 11972 @VisibleForTesting readKernelUidCpuActiveTimesLocked(boolean onBattery)11973 public void readKernelUidCpuActiveTimesLocked(boolean onBattery) { 11974 final long startTimeMs = mClocks.uptimeMillis(); 11975 mCpuUidActiveTimeReader.readDelta((uid, cpuActiveTimesMs) -> { 11976 uid = mapUid(uid); 11977 if (Process.isIsolated(uid)) { 11978 mCpuUidActiveTimeReader.removeUid(uid); 11979 Slog.w(TAG, "Got active times for an isolated uid with no mapping: " + uid); 11980 return; 11981 } 11982 if (!mUserInfoProvider.exists(UserHandle.getUserId(uid))) { 11983 Slog.w(TAG, "Got active times for an invalid user's uid " + uid); 11984 mCpuUidActiveTimeReader.removeUid(uid); 11985 return; 11986 } 11987 final Uid u = getUidStatsLocked(uid); 11988 u.mCpuActiveTimeMs.addCountLocked(cpuActiveTimesMs, onBattery); 11989 }); 11990 11991 final long elapsedTimeMs = mClocks.uptimeMillis() - startTimeMs; 11992 if (DEBUG_ENERGY_CPU || elapsedTimeMs >= 100) { 11993 Slog.d(TAG, "Reading cpu active times took " + elapsedTimeMs + "ms"); 11994 } 11995 } 11996 11997 /** 11998 * Take a snapshot of the cpu cluster times spent by each uid and update the corresponding 11999 * counters. 12000 */ 12001 @VisibleForTesting readKernelUidCpuClusterTimesLocked(boolean onBattery)12002 public void readKernelUidCpuClusterTimesLocked(boolean onBattery) { 12003 final long startTimeMs = mClocks.uptimeMillis(); 12004 mCpuUidClusterTimeReader.readDelta((uid, cpuClusterTimesMs) -> { 12005 uid = mapUid(uid); 12006 if (Process.isIsolated(uid)) { 12007 mCpuUidClusterTimeReader.removeUid(uid); 12008 Slog.w(TAG, "Got cluster times for an isolated uid with no mapping: " + uid); 12009 return; 12010 } 12011 if (!mUserInfoProvider.exists(UserHandle.getUserId(uid))) { 12012 Slog.w(TAG, "Got cluster times for an invalid user's uid " + uid); 12013 mCpuUidClusterTimeReader.removeUid(uid); 12014 return; 12015 } 12016 final Uid u = getUidStatsLocked(uid); 12017 u.mCpuClusterTimesMs.addCountLocked(cpuClusterTimesMs, onBattery); 12018 }); 12019 12020 final long elapsedTimeMs = mClocks.uptimeMillis() - startTimeMs; 12021 if (DEBUG_ENERGY_CPU || elapsedTimeMs >= 100) { 12022 Slog.d(TAG, "Reading cpu cluster times took " + elapsedTimeMs + "ms"); 12023 } 12024 } 12025 setChargingLocked(boolean charging)12026 boolean setChargingLocked(boolean charging) { 12027 // if the device is no longer charging, remove the callback 12028 // if the device is now charging, it means that this is either called 12029 // 1. directly when level >= 90 12030 // 2. or from within the runnable that we deferred 12031 // For 1. if we have an existing callback, remove it, since we will immediately send a 12032 // ACTION_CHARGING 12033 // For 2. we remove existing callback so we don't send multiple ACTION_CHARGING 12034 mHandler.removeCallbacks(mDeferSetCharging); 12035 if (mCharging != charging) { 12036 mCharging = charging; 12037 if (charging) { 12038 mHistoryCur.states2 |= HistoryItem.STATE2_CHARGING_FLAG; 12039 } else { 12040 mHistoryCur.states2 &= ~HistoryItem.STATE2_CHARGING_FLAG; 12041 } 12042 mHandler.sendEmptyMessage(MSG_REPORT_CHARGING); 12043 return true; 12044 } 12045 return false; 12046 } 12047 12048 @GuardedBy("this") setOnBatteryLocked(final long mSecRealtime, final long mSecUptime, final boolean onBattery, final int oldStatus, final int level, final int chargeUAh)12049 protected void setOnBatteryLocked(final long mSecRealtime, final long mSecUptime, 12050 final boolean onBattery, final int oldStatus, final int level, final int chargeUAh) { 12051 boolean doWrite = false; 12052 Message m = mHandler.obtainMessage(MSG_REPORT_POWER_CHANGE); 12053 m.arg1 = onBattery ? 1 : 0; 12054 mHandler.sendMessage(m); 12055 12056 final long uptime = mSecUptime * 1000; 12057 final long realtime = mSecRealtime * 1000; 12058 final int screenState = mScreenState; 12059 if (onBattery) { 12060 // We will reset our status if we are unplugging after the 12061 // battery was last full, or the level is at 100, or 12062 // we have gone through a significant charge (from a very low 12063 // level to a now very high level). 12064 boolean reset = false; 12065 if (!mNoAutoReset && (oldStatus == BatteryManager.BATTERY_STATUS_FULL 12066 || level >= 90 12067 || (mDischargeCurrentLevel < 20 && level >= 80))) { 12068 Slog.i(TAG, "Resetting battery stats: level=" + level + " status=" + oldStatus 12069 + " dischargeLevel=" + mDischargeCurrentLevel 12070 + " lowAmount=" + getLowDischargeAmountSinceCharge() 12071 + " highAmount=" + getHighDischargeAmountSinceCharge()); 12072 // Before we write, collect a snapshot of the final aggregated 12073 // stats to be reported in the next checkin. Only do this if we have 12074 // a sufficient amount of data to make it interesting. 12075 if (getLowDischargeAmountSinceCharge() >= 20) { 12076 final long startTime = SystemClock.uptimeMillis(); 12077 final Parcel parcel = Parcel.obtain(); 12078 writeSummaryToParcel(parcel, true); 12079 final long initialTime = SystemClock.uptimeMillis() - startTime; 12080 BackgroundThread.getHandler().post(new Runnable() { 12081 @Override public void run() { 12082 synchronized (mCheckinFile) { 12083 final long startTime2 = SystemClock.uptimeMillis(); 12084 FileOutputStream stream = null; 12085 try { 12086 stream = mCheckinFile.startWrite(); 12087 stream.write(parcel.marshall()); 12088 stream.flush(); 12089 mCheckinFile.finishWrite(stream); 12090 com.android.internal.logging.EventLogTags.writeCommitSysConfigFile( 12091 "batterystats-checkin", 12092 initialTime + SystemClock.uptimeMillis() - startTime2); 12093 } catch (IOException e) { 12094 Slog.w("BatteryStats", 12095 "Error writing checkin battery statistics", e); 12096 mCheckinFile.failWrite(stream); 12097 } finally { 12098 parcel.recycle(); 12099 } 12100 } 12101 } 12102 }); 12103 } 12104 doWrite = true; 12105 resetAllStatsLocked(); 12106 if (chargeUAh > 0 && level > 0) { 12107 // Only use the reported coulomb charge value if it is supported and reported. 12108 mEstimatedBatteryCapacity = (int) ((chargeUAh / 1000) / (level / 100.0)); 12109 } 12110 mDischargeStartLevel = level; 12111 reset = true; 12112 mDischargeStepTracker.init(); 12113 } 12114 if (mCharging) { 12115 setChargingLocked(false); 12116 } 12117 mLastChargingStateLevel = level; 12118 mOnBattery = mOnBatteryInternal = true; 12119 mLastDischargeStepLevel = level; 12120 mMinDischargeStepLevel = level; 12121 mDischargeStepTracker.clearTime(); 12122 mDailyDischargeStepTracker.clearTime(); 12123 mInitStepMode = mCurStepMode; 12124 mModStepMode = 0; 12125 pullPendingStateUpdatesLocked(); 12126 mHistoryCur.batteryLevel = (byte)level; 12127 mHistoryCur.states &= ~HistoryItem.STATE_BATTERY_PLUGGED_FLAG; 12128 if (DEBUG_HISTORY) Slog.v(TAG, "Battery unplugged to: " 12129 + Integer.toHexString(mHistoryCur.states)); 12130 if (reset) { 12131 mRecordingHistory = true; 12132 startRecordingHistory(mSecRealtime, mSecUptime, reset); 12133 } 12134 addHistoryRecordLocked(mSecRealtime, mSecUptime); 12135 mDischargeCurrentLevel = mDischargeUnplugLevel = level; 12136 if (isScreenOn(screenState)) { 12137 mDischargeScreenOnUnplugLevel = level; 12138 mDischargeScreenDozeUnplugLevel = 0; 12139 mDischargeScreenOffUnplugLevel = 0; 12140 } else if (isScreenDoze(screenState)) { 12141 mDischargeScreenOnUnplugLevel = 0; 12142 mDischargeScreenDozeUnplugLevel = level; 12143 mDischargeScreenOffUnplugLevel = 0; 12144 } else { 12145 mDischargeScreenOnUnplugLevel = 0; 12146 mDischargeScreenDozeUnplugLevel = 0; 12147 mDischargeScreenOffUnplugLevel = level; 12148 } 12149 mDischargeAmountScreenOn = 0; 12150 mDischargeAmountScreenDoze = 0; 12151 mDischargeAmountScreenOff = 0; 12152 updateTimeBasesLocked(true, screenState, uptime, realtime); 12153 } else { 12154 mLastChargingStateLevel = level; 12155 mOnBattery = mOnBatteryInternal = false; 12156 pullPendingStateUpdatesLocked(); 12157 mHistoryCur.batteryLevel = (byte)level; 12158 mHistoryCur.states |= HistoryItem.STATE_BATTERY_PLUGGED_FLAG; 12159 if (DEBUG_HISTORY) Slog.v(TAG, "Battery plugged to: " 12160 + Integer.toHexString(mHistoryCur.states)); 12161 addHistoryRecordLocked(mSecRealtime, mSecUptime); 12162 mDischargeCurrentLevel = mDischargePlugLevel = level; 12163 if (level < mDischargeUnplugLevel) { 12164 mLowDischargeAmountSinceCharge += mDischargeUnplugLevel-level-1; 12165 mHighDischargeAmountSinceCharge += mDischargeUnplugLevel-level; 12166 } 12167 updateDischargeScreenLevelsLocked(screenState, screenState); 12168 updateTimeBasesLocked(false, screenState, uptime, realtime); 12169 mChargeStepTracker.init(); 12170 mLastChargeStepLevel = level; 12171 mMaxChargeStepLevel = level; 12172 mInitStepMode = mCurStepMode; 12173 mModStepMode = 0; 12174 } 12175 if (doWrite || (mLastWriteTime + (60 * 1000)) < mSecRealtime) { 12176 if (mStatsFile != null && mBatteryStatsHistory.getActiveFile() != null) { 12177 writeAsyncLocked(); 12178 } 12179 } 12180 } 12181 startRecordingHistory(final long elapsedRealtimeMs, final long uptimeMs, boolean reset)12182 private void startRecordingHistory(final long elapsedRealtimeMs, final long uptimeMs, 12183 boolean reset) { 12184 mRecordingHistory = true; 12185 mHistoryCur.currentTime = System.currentTimeMillis(); 12186 addHistoryBufferLocked(elapsedRealtimeMs, 12187 reset ? HistoryItem.CMD_RESET : HistoryItem.CMD_CURRENT_TIME, 12188 mHistoryCur); 12189 mHistoryCur.currentTime = 0; 12190 if (reset) { 12191 initActiveHistoryEventsLocked(elapsedRealtimeMs, uptimeMs); 12192 } 12193 } 12194 recordCurrentTimeChangeLocked(final long currentTime, final long elapsedRealtimeMs, final long uptimeMs)12195 private void recordCurrentTimeChangeLocked(final long currentTime, final long elapsedRealtimeMs, 12196 final long uptimeMs) { 12197 if (mRecordingHistory) { 12198 mHistoryCur.currentTime = currentTime; 12199 addHistoryBufferLocked(elapsedRealtimeMs, HistoryItem.CMD_CURRENT_TIME, mHistoryCur); 12200 mHistoryCur.currentTime = 0; 12201 } 12202 } 12203 recordShutdownLocked(final long elapsedRealtimeMs, final long uptimeMs)12204 private void recordShutdownLocked(final long elapsedRealtimeMs, final long uptimeMs) { 12205 if (mRecordingHistory) { 12206 mHistoryCur.currentTime = System.currentTimeMillis(); 12207 addHistoryBufferLocked(elapsedRealtimeMs, HistoryItem.CMD_SHUTDOWN, mHistoryCur); 12208 mHistoryCur.currentTime = 0; 12209 } 12210 } 12211 scheduleSyncExternalStatsLocked(String reason, int updateFlags)12212 private void scheduleSyncExternalStatsLocked(String reason, int updateFlags) { 12213 if (mExternalSync != null) { 12214 mExternalSync.scheduleSync(reason, updateFlags); 12215 } 12216 } 12217 12218 // This should probably be exposed in the API, though it's not critical 12219 public static final int BATTERY_PLUGGED_NONE = OsProtoEnums.BATTERY_PLUGGED_NONE; // = 0 12220 12221 @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)12222 public void setBatteryStateLocked(final int status, final int health, final int plugType, 12223 final int level, /* not final */ int temp, final int volt, final int chargeUAh, 12224 final int chargeFullUAh, final long chargeTimeToFullSeconds) { 12225 // Temperature is encoded without the signed bit, so clamp any negative temperatures to 0. 12226 temp = Math.max(0, temp); 12227 12228 reportChangesToStatsLog(mHaveBatteryLevel ? mHistoryCur : null, 12229 status, plugType, level); 12230 12231 final boolean onBattery = isOnBattery(plugType, status); 12232 final long uptime = mClocks.uptimeMillis(); 12233 final long elapsedRealtime = mClocks.elapsedRealtime(); 12234 if (!mHaveBatteryLevel) { 12235 mHaveBatteryLevel = true; 12236 // We start out assuming that the device is plugged in (not 12237 // on battery). If our first report is now that we are indeed 12238 // plugged in, then twiddle our state to correctly reflect that 12239 // since we won't be going through the full setOnBattery(). 12240 if (onBattery == mOnBattery) { 12241 if (onBattery) { 12242 mHistoryCur.states &= ~HistoryItem.STATE_BATTERY_PLUGGED_FLAG; 12243 } else { 12244 mHistoryCur.states |= HistoryItem.STATE_BATTERY_PLUGGED_FLAG; 12245 } 12246 } 12247 // Always start out assuming charging, that will be updated later. 12248 mHistoryCur.states2 |= HistoryItem.STATE2_CHARGING_FLAG; 12249 mHistoryCur.batteryStatus = (byte)status; 12250 mHistoryCur.batteryLevel = (byte)level; 12251 mHistoryCur.batteryChargeUAh = chargeUAh; 12252 mMaxChargeStepLevel = mMinDischargeStepLevel = 12253 mLastChargeStepLevel = mLastDischargeStepLevel = level; 12254 mLastChargingStateLevel = level; 12255 } else if (mCurrentBatteryLevel != level || mOnBattery != onBattery) { 12256 recordDailyStatsIfNeededLocked(level >= 100 && onBattery); 12257 } 12258 int oldStatus = mHistoryCur.batteryStatus; 12259 if (onBattery) { 12260 mDischargeCurrentLevel = level; 12261 if (!mRecordingHistory) { 12262 mRecordingHistory = true; 12263 startRecordingHistory(elapsedRealtime, uptime, true); 12264 } 12265 } else if (level < 96 && 12266 status != BatteryManager.BATTERY_STATUS_UNKNOWN) { 12267 if (!mRecordingHistory) { 12268 mRecordingHistory = true; 12269 startRecordingHistory(elapsedRealtime, uptime, true); 12270 } 12271 } 12272 mCurrentBatteryLevel = level; 12273 if (mDischargePlugLevel < 0) { 12274 mDischargePlugLevel = level; 12275 } 12276 12277 if (onBattery != mOnBattery) { 12278 mHistoryCur.batteryLevel = (byte)level; 12279 mHistoryCur.batteryStatus = (byte)status; 12280 mHistoryCur.batteryHealth = (byte)health; 12281 mHistoryCur.batteryPlugType = (byte)plugType; 12282 mHistoryCur.batteryTemperature = (short)temp; 12283 mHistoryCur.batteryVoltage = (char)volt; 12284 if (chargeUAh < mHistoryCur.batteryChargeUAh) { 12285 // Only record discharges 12286 final long chargeDiff = mHistoryCur.batteryChargeUAh - chargeUAh; 12287 mDischargeCounter.addCountLocked(chargeDiff); 12288 mDischargeScreenOffCounter.addCountLocked(chargeDiff); 12289 if (isScreenDoze(mScreenState)) { 12290 mDischargeScreenDozeCounter.addCountLocked(chargeDiff); 12291 } 12292 if (mDeviceIdleMode == DEVICE_IDLE_MODE_LIGHT) { 12293 mDischargeLightDozeCounter.addCountLocked(chargeDiff); 12294 } else if (mDeviceIdleMode == DEVICE_IDLE_MODE_DEEP) { 12295 mDischargeDeepDozeCounter.addCountLocked(chargeDiff); 12296 } 12297 } 12298 mHistoryCur.batteryChargeUAh = chargeUAh; 12299 setOnBatteryLocked(elapsedRealtime, uptime, onBattery, oldStatus, level, chargeUAh); 12300 } else { 12301 boolean changed = false; 12302 if (mHistoryCur.batteryLevel != level) { 12303 mHistoryCur.batteryLevel = (byte)level; 12304 changed = true; 12305 12306 // TODO(adamlesinski): Schedule the creation of a HistoryStepDetails record 12307 // which will pull external stats. 12308 mExternalSync.scheduleSyncDueToBatteryLevelChange( 12309 mConstants.BATTERY_LEVEL_COLLECTION_DELAY_MS); 12310 } 12311 if (mHistoryCur.batteryStatus != status) { 12312 mHistoryCur.batteryStatus = (byte)status; 12313 changed = true; 12314 } 12315 if (mHistoryCur.batteryHealth != health) { 12316 mHistoryCur.batteryHealth = (byte)health; 12317 changed = true; 12318 } 12319 if (mHistoryCur.batteryPlugType != plugType) { 12320 mHistoryCur.batteryPlugType = (byte)plugType; 12321 changed = true; 12322 } 12323 if (temp >= (mHistoryCur.batteryTemperature+10) 12324 || temp <= (mHistoryCur.batteryTemperature-10)) { 12325 mHistoryCur.batteryTemperature = (short)temp; 12326 changed = true; 12327 } 12328 if (volt > (mHistoryCur.batteryVoltage+20) 12329 || volt < (mHistoryCur.batteryVoltage-20)) { 12330 mHistoryCur.batteryVoltage = (char)volt; 12331 changed = true; 12332 } 12333 if (chargeUAh >= (mHistoryCur.batteryChargeUAh+10) 12334 || chargeUAh <= (mHistoryCur.batteryChargeUAh-10)) { 12335 if (chargeUAh < mHistoryCur.batteryChargeUAh) { 12336 // Only record discharges 12337 final long chargeDiff = mHistoryCur.batteryChargeUAh - chargeUAh; 12338 mDischargeCounter.addCountLocked(chargeDiff); 12339 mDischargeScreenOffCounter.addCountLocked(chargeDiff); 12340 if (isScreenDoze(mScreenState)) { 12341 mDischargeScreenDozeCounter.addCountLocked(chargeDiff); 12342 } 12343 if (mDeviceIdleMode == DEVICE_IDLE_MODE_LIGHT) { 12344 mDischargeLightDozeCounter.addCountLocked(chargeDiff); 12345 } else if (mDeviceIdleMode == DEVICE_IDLE_MODE_DEEP) { 12346 mDischargeDeepDozeCounter.addCountLocked(chargeDiff); 12347 } 12348 } 12349 mHistoryCur.batteryChargeUAh = chargeUAh; 12350 changed = true; 12351 } 12352 long modeBits = (((long)mInitStepMode) << STEP_LEVEL_INITIAL_MODE_SHIFT) 12353 | (((long)mModStepMode) << STEP_LEVEL_MODIFIED_MODE_SHIFT) 12354 | (((long)(level&0xff)) << STEP_LEVEL_LEVEL_SHIFT); 12355 if (onBattery) { 12356 changed |= setChargingLocked(false); 12357 if (mLastDischargeStepLevel != level && mMinDischargeStepLevel > level) { 12358 mDischargeStepTracker.addLevelSteps(mLastDischargeStepLevel - level, 12359 modeBits, elapsedRealtime); 12360 mDailyDischargeStepTracker.addLevelSteps(mLastDischargeStepLevel - level, 12361 modeBits, elapsedRealtime); 12362 mLastDischargeStepLevel = level; 12363 mMinDischargeStepLevel = level; 12364 mInitStepMode = mCurStepMode; 12365 mModStepMode = 0; 12366 } 12367 } else { 12368 if (level >= 90) { 12369 // If the battery level is at least 90%, always consider the device to be 12370 // charging even if it happens to go down a level. 12371 changed |= setChargingLocked(true); 12372 } else if (!mCharging) { 12373 if (mLastChargeStepLevel < level) { 12374 // We have not reported that we are charging, but the level has gone up, 12375 // but we would like to not have tons of activity from charging-constraint 12376 // jobs, so instead of reporting ACTION_CHARGING immediately, we defer it. 12377 if (!mHandler.hasCallbacks(mDeferSetCharging)) { 12378 mHandler.postDelayed( 12379 mDeferSetCharging, 12380 mConstants.BATTERY_CHARGED_DELAY_MS); 12381 } 12382 } else if (mLastChargeStepLevel > level) { 12383 // if we had deferred a runnable due to charge level increasing, but then 12384 // later the charge level drops (could be due to thermal issues), we don't 12385 // want to trigger the deferred runnable, so remove it here 12386 mHandler.removeCallbacks(mDeferSetCharging); 12387 } 12388 } else { 12389 if (mLastChargeStepLevel > level) { 12390 // We had reported that the device was charging, but here we are with 12391 // power connected and the level going down. Looks like the current 12392 // power supplied isn't enough, so consider the device to now be 12393 // discharging. 12394 changed |= setChargingLocked(false); 12395 } 12396 } 12397 if (mLastChargeStepLevel != level && mMaxChargeStepLevel < level) { 12398 mChargeStepTracker.addLevelSteps(level - mLastChargeStepLevel, 12399 modeBits, elapsedRealtime); 12400 mDailyChargeStepTracker.addLevelSteps(level - mLastChargeStepLevel, 12401 modeBits, elapsedRealtime); 12402 mMaxChargeStepLevel = level; 12403 mInitStepMode = mCurStepMode; 12404 mModStepMode = 0; 12405 } 12406 mLastChargeStepLevel = level; 12407 } 12408 if (changed) { 12409 addHistoryRecordLocked(elapsedRealtime, uptime); 12410 } 12411 } 12412 if (!onBattery && 12413 (status == BatteryManager.BATTERY_STATUS_FULL || 12414 status == BatteryManager.BATTERY_STATUS_UNKNOWN)) { 12415 // We don't record history while we are plugged in and fully charged 12416 // (or when battery is not present). The next time we are 12417 // unplugged, history will be cleared. 12418 mRecordingHistory = DEBUG; 12419 } 12420 12421 if (mMinLearnedBatteryCapacity == -1) { 12422 mMinLearnedBatteryCapacity = chargeFullUAh; 12423 } else { 12424 mMinLearnedBatteryCapacity = Math.min(mMinLearnedBatteryCapacity, chargeFullUAh); 12425 } 12426 mMaxLearnedBatteryCapacity = Math.max(mMaxLearnedBatteryCapacity, chargeFullUAh); 12427 12428 mBatteryTimeToFullSeconds = chargeTimeToFullSeconds; 12429 } 12430 isOnBattery(int plugType, int status)12431 public static boolean isOnBattery(int plugType, int status) { 12432 return plugType == BATTERY_PLUGGED_NONE && status != BatteryManager.BATTERY_STATUS_UNKNOWN; 12433 } 12434 12435 // Inform StatsLog of setBatteryState changes. 12436 // If this is the first reporting, pass in recentPast == null. reportChangesToStatsLog(HistoryItem recentPast, final int status, final int plugType, final int level)12437 private void reportChangesToStatsLog(HistoryItem recentPast, 12438 final int status, final int plugType, final int level) { 12439 12440 if (recentPast == null || recentPast.batteryStatus != status) { 12441 StatsLog.write(StatsLog.CHARGING_STATE_CHANGED, status); 12442 } 12443 if (recentPast == null || recentPast.batteryPlugType != plugType) { 12444 StatsLog.write(StatsLog.PLUGGED_STATE_CHANGED, plugType); 12445 } 12446 if (recentPast == null || recentPast.batteryLevel != level) { 12447 StatsLog.write(StatsLog.BATTERY_LEVEL_CHANGED, level); 12448 } 12449 } 12450 12451 @UnsupportedAppUsage getAwakeTimeBattery()12452 public long getAwakeTimeBattery() { 12453 // This previously evaluated to mOnBatteryTimeBase.getUptime(getBatteryUptimeLocked()); 12454 // for over a decade, but surely that was a mistake. 12455 return getBatteryUptimeLocked(); 12456 } 12457 12458 @UnsupportedAppUsage getAwakeTimePlugged()12459 public long getAwakeTimePlugged() { 12460 return (mClocks.uptimeMillis() * 1000) - getAwakeTimeBattery(); 12461 } 12462 12463 @Override computeUptime(long curTime, int which)12464 public long computeUptime(long curTime, int which) { 12465 return mUptime + (curTime - mUptimeStart); 12466 } 12467 12468 @Override computeRealtime(long curTime, int which)12469 public long computeRealtime(long curTime, int which) { 12470 return mRealtime + (curTime - mRealtimeStart); 12471 } 12472 12473 @Override 12474 @UnsupportedAppUsage computeBatteryUptime(long curTime, int which)12475 public long computeBatteryUptime(long curTime, int which) { 12476 return mOnBatteryTimeBase.computeUptime(curTime, which); 12477 } 12478 12479 @Override 12480 @UnsupportedAppUsage computeBatteryRealtime(long curTime, int which)12481 public long computeBatteryRealtime(long curTime, int which) { 12482 return mOnBatteryTimeBase.computeRealtime(curTime, which); 12483 } 12484 12485 @Override computeBatteryScreenOffUptime(long curTime, int which)12486 public long computeBatteryScreenOffUptime(long curTime, int which) { 12487 return mOnBatteryScreenOffTimeBase.computeUptime(curTime, which); 12488 } 12489 12490 @Override computeBatteryScreenOffRealtime(long curTime, int which)12491 public long computeBatteryScreenOffRealtime(long curTime, int which) { 12492 return mOnBatteryScreenOffTimeBase.computeRealtime(curTime, which); 12493 } 12494 computeTimePerLevel(long[] steps, int numSteps)12495 private long computeTimePerLevel(long[] steps, int numSteps) { 12496 // For now we'll do a simple average across all steps. 12497 if (numSteps <= 0) { 12498 return -1; 12499 } 12500 long total = 0; 12501 for (int i=0; i<numSteps; i++) { 12502 total += steps[i] & STEP_LEVEL_TIME_MASK; 12503 } 12504 return total / numSteps; 12505 /* 12506 long[] buckets = new long[numSteps]; 12507 int numBuckets = 0; 12508 int numToAverage = 4; 12509 int i = 0; 12510 while (i < numSteps) { 12511 long totalTime = 0; 12512 int num = 0; 12513 for (int j=0; j<numToAverage && (i+j)<numSteps; j++) { 12514 totalTime += steps[i+j] & STEP_LEVEL_TIME_MASK; 12515 num++; 12516 } 12517 buckets[numBuckets] = totalTime / num; 12518 numBuckets++; 12519 numToAverage *= 2; 12520 i += num; 12521 } 12522 if (numBuckets < 1) { 12523 return -1; 12524 } 12525 long averageTime = buckets[numBuckets-1]; 12526 for (i=numBuckets-2; i>=0; i--) { 12527 averageTime = (averageTime + buckets[i]) / 2; 12528 } 12529 return averageTime; 12530 */ 12531 } 12532 12533 @Override 12534 @UnsupportedAppUsage computeBatteryTimeRemaining(long curTime)12535 public long computeBatteryTimeRemaining(long curTime) { 12536 if (!mOnBattery) { 12537 return -1; 12538 } 12539 /* Simple implementation just looks at the average discharge per level across the 12540 entire sample period. 12541 int discharge = (getLowDischargeAmountSinceCharge()+getHighDischargeAmountSinceCharge())/2; 12542 if (discharge < 2) { 12543 return -1; 12544 } 12545 long duration = computeBatteryRealtime(curTime, STATS_SINCE_CHARGED); 12546 if (duration < 1000*1000) { 12547 return -1; 12548 } 12549 long usPerLevel = duration/discharge; 12550 return usPerLevel * mCurrentBatteryLevel; 12551 */ 12552 if (mDischargeStepTracker.mNumStepDurations < 1) { 12553 return -1; 12554 } 12555 long msPerLevel = mDischargeStepTracker.computeTimePerLevel(); 12556 if (msPerLevel <= 0) { 12557 return -1; 12558 } 12559 return (msPerLevel * mCurrentBatteryLevel) * 1000; 12560 } 12561 12562 @Override getDischargeLevelStepTracker()12563 public LevelStepTracker getDischargeLevelStepTracker() { 12564 return mDischargeStepTracker; 12565 } 12566 12567 @Override getDailyDischargeLevelStepTracker()12568 public LevelStepTracker getDailyDischargeLevelStepTracker() { 12569 return mDailyDischargeStepTracker; 12570 } 12571 12572 @Override computeChargeTimeRemaining(long curTime)12573 public long computeChargeTimeRemaining(long curTime) { 12574 if (mOnBattery) { 12575 // Not yet working. 12576 return -1; 12577 } 12578 if (mBatteryTimeToFullSeconds >= 0) { 12579 return mBatteryTimeToFullSeconds * (1000 * 1000); // s to us 12580 } 12581 // Else use algorithmic approach 12582 if (mChargeStepTracker.mNumStepDurations < 1) { 12583 return -1; 12584 } 12585 long msPerLevel = mChargeStepTracker.computeTimePerLevel(); 12586 if (msPerLevel <= 0) { 12587 return -1; 12588 } 12589 return (msPerLevel * (100 - mCurrentBatteryLevel)) * 1000; 12590 } 12591 12592 /*@hide */ getCellularBatteryStats()12593 public CellularBatteryStats getCellularBatteryStats() { 12594 CellularBatteryStats s = new CellularBatteryStats(); 12595 final int which = STATS_SINCE_CHARGED; 12596 final long rawRealTime = SystemClock.elapsedRealtime() * 1000; 12597 final ControllerActivityCounter counter = getModemControllerActivity(); 12598 final long sleepTimeMs = counter.getSleepTimeCounter().getCountLocked(which); 12599 final long idleTimeMs = counter.getIdleTimeCounter().getCountLocked(which); 12600 final long rxTimeMs = counter.getRxTimeCounter().getCountLocked(which); 12601 final long energyConsumedMaMs = counter.getPowerCounter().getCountLocked(which); 12602 final long monitoredRailChargeConsumedMaMs = 12603 counter.getMonitoredRailChargeConsumedMaMs().getCountLocked(which); 12604 long[] timeInRatMs = new long[BatteryStats.NUM_DATA_CONNECTION_TYPES]; 12605 for (int i = 0; i < timeInRatMs.length; i++) { 12606 timeInRatMs[i] = getPhoneDataConnectionTime(i, rawRealTime, which) / 1000; 12607 } 12608 long[] timeInRxSignalStrengthLevelMs = 12609 new long[CellSignalStrength.getNumSignalStrengthLevels()]; 12610 for (int i = 0; i < timeInRxSignalStrengthLevelMs.length; i++) { 12611 timeInRxSignalStrengthLevelMs[i] 12612 = getPhoneSignalStrengthTime(i, rawRealTime, which) / 1000; 12613 } 12614 long[] txTimeMs = new long[Math.min(ModemActivityInfo.TX_POWER_LEVELS, 12615 counter.getTxTimeCounters().length)]; 12616 long totalTxTimeMs = 0; 12617 for (int i = 0; i < txTimeMs.length; i++) { 12618 txTimeMs[i] = counter.getTxTimeCounters()[i].getCountLocked(which); 12619 totalTxTimeMs += txTimeMs[i]; 12620 } 12621 s.setLoggingDurationMs(computeBatteryRealtime(rawRealTime, which) / 1000); 12622 s.setKernelActiveTimeMs(getMobileRadioActiveTime(rawRealTime, which) / 1000); 12623 s.setNumPacketsTx(getNetworkActivityPackets(NETWORK_MOBILE_TX_DATA, which)); 12624 s.setNumBytesTx(getNetworkActivityBytes(NETWORK_MOBILE_TX_DATA, which)); 12625 s.setNumPacketsRx(getNetworkActivityPackets(NETWORK_MOBILE_RX_DATA, which)); 12626 s.setNumBytesRx(getNetworkActivityBytes(NETWORK_MOBILE_RX_DATA, which)); 12627 s.setSleepTimeMs(sleepTimeMs); 12628 s.setIdleTimeMs(idleTimeMs); 12629 s.setRxTimeMs(rxTimeMs); 12630 s.setEnergyConsumedMaMs(energyConsumedMaMs); 12631 s.setTimeInRatMs(timeInRatMs); 12632 s.setTimeInRxSignalStrengthLevelMs(timeInRxSignalStrengthLevelMs); 12633 s.setTxTimeMs(txTimeMs); 12634 s.setMonitoredRailChargeConsumedMaMs(monitoredRailChargeConsumedMaMs); 12635 return s; 12636 } 12637 12638 /*@hide */ getWifiBatteryStats()12639 public WifiBatteryStats getWifiBatteryStats() { 12640 WifiBatteryStats s = new WifiBatteryStats(); 12641 final int which = STATS_SINCE_CHARGED; 12642 final long rawRealTime = SystemClock.elapsedRealtime() * 1000; 12643 final ControllerActivityCounter counter = getWifiControllerActivity(); 12644 final long idleTimeMs = counter.getIdleTimeCounter().getCountLocked(which); 12645 final long scanTimeMs = counter.getScanTimeCounter().getCountLocked(which); 12646 final long rxTimeMs = counter.getRxTimeCounter().getCountLocked(which); 12647 final long txTimeMs = counter.getTxTimeCounters()[0].getCountLocked(which); 12648 final long totalControllerActivityTimeMs 12649 = computeBatteryRealtime(SystemClock.elapsedRealtime() * 1000, which) / 1000; 12650 final long sleepTimeMs 12651 = totalControllerActivityTimeMs - (idleTimeMs + rxTimeMs + txTimeMs); 12652 final long energyConsumedMaMs = counter.getPowerCounter().getCountLocked(which); 12653 final long monitoredRailChargeConsumedMaMs = 12654 counter.getMonitoredRailChargeConsumedMaMs().getCountLocked(which); 12655 long numAppScanRequest = 0; 12656 for (int i = 0; i < mUidStats.size(); i++) { 12657 numAppScanRequest += mUidStats.valueAt(i).mWifiScanTimer.getCountLocked(which); 12658 } 12659 long[] timeInStateMs = new long[NUM_WIFI_STATES]; 12660 for (int i=0; i<NUM_WIFI_STATES; i++) { 12661 timeInStateMs[i] = getWifiStateTime(i, rawRealTime, which) / 1000; 12662 } 12663 long[] timeInSupplStateMs = new long[NUM_WIFI_SUPPL_STATES]; 12664 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) { 12665 timeInSupplStateMs[i] = getWifiSupplStateTime(i, rawRealTime, which) / 1000; 12666 } 12667 long[] timeSignalStrengthTimeMs = new long[NUM_WIFI_SIGNAL_STRENGTH_BINS]; 12668 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { 12669 timeSignalStrengthTimeMs[i] = getWifiSignalStrengthTime(i, rawRealTime, which) / 1000; 12670 } 12671 s.setLoggingDurationMs(computeBatteryRealtime(rawRealTime, which) / 1000); 12672 s.setKernelActiveTimeMs(getWifiActiveTime(rawRealTime, which) / 1000); 12673 s.setNumPacketsTx(getNetworkActivityPackets(NETWORK_WIFI_TX_DATA, which)); 12674 s.setNumBytesTx(getNetworkActivityBytes(NETWORK_WIFI_TX_DATA, which)); 12675 s.setNumPacketsRx(getNetworkActivityPackets(NETWORK_WIFI_RX_DATA, which)); 12676 s.setNumBytesRx(getNetworkActivityBytes(NETWORK_WIFI_RX_DATA, which)); 12677 s.setSleepTimeMs(sleepTimeMs); 12678 s.setIdleTimeMs(idleTimeMs); 12679 s.setRxTimeMs(rxTimeMs); 12680 s.setTxTimeMs(txTimeMs); 12681 s.setScanTimeMs(scanTimeMs); 12682 s.setEnergyConsumedMaMs(energyConsumedMaMs); 12683 s.setNumAppScanRequest(numAppScanRequest); 12684 s.setTimeInStateMs(timeInStateMs); 12685 s.setTimeInSupplicantStateMs(timeInSupplStateMs); 12686 s.setTimeInRxSignalStrengthLevelMs(timeSignalStrengthTimeMs); 12687 s.setMonitoredRailChargeConsumedMaMs(monitoredRailChargeConsumedMaMs); 12688 return s; 12689 } 12690 12691 /*@hide */ getGpsBatteryStats()12692 public GpsBatteryStats getGpsBatteryStats() { 12693 GpsBatteryStats s = new GpsBatteryStats(); 12694 final int which = STATS_SINCE_CHARGED; 12695 final long rawRealTime = SystemClock.elapsedRealtime() * 1000; 12696 s.setLoggingDurationMs(computeBatteryRealtime(rawRealTime, which) / 1000); 12697 s.setEnergyConsumedMaMs(getGpsBatteryDrainMaMs()); 12698 long[] time = new long[GnssMetrics.NUM_GPS_SIGNAL_QUALITY_LEVELS]; 12699 for (int i=0; i<time.length; i++) { 12700 time[i] = getGpsSignalQualityTime(i, rawRealTime, which) / 1000; 12701 } 12702 s.setTimeInGpsSignalQualityLevel(time); 12703 return s; 12704 } 12705 12706 @Override getChargeLevelStepTracker()12707 public LevelStepTracker getChargeLevelStepTracker() { 12708 return mChargeStepTracker; 12709 } 12710 12711 @Override getDailyChargeLevelStepTracker()12712 public LevelStepTracker getDailyChargeLevelStepTracker() { 12713 return mDailyChargeStepTracker; 12714 } 12715 12716 @Override getDailyPackageChanges()12717 public ArrayList<PackageChange> getDailyPackageChanges() { 12718 return mDailyPackageChanges; 12719 } 12720 getBatteryUptimeLocked()12721 protected long getBatteryUptimeLocked() { 12722 return mOnBatteryTimeBase.getUptime(mClocks.uptimeMillis() * 1000); 12723 } 12724 12725 @Override getBatteryUptime(long curTime)12726 public long getBatteryUptime(long curTime) { 12727 return mOnBatteryTimeBase.getUptime(curTime); 12728 } 12729 12730 @Override 12731 @UnsupportedAppUsage getBatteryRealtime(long curTime)12732 public long getBatteryRealtime(long curTime) { 12733 return mOnBatteryTimeBase.getRealtime(curTime); 12734 } 12735 12736 @Override 12737 @UnsupportedAppUsage getDischargeStartLevel()12738 public int getDischargeStartLevel() { 12739 synchronized(this) { 12740 return getDischargeStartLevelLocked(); 12741 } 12742 } 12743 getDischargeStartLevelLocked()12744 public int getDischargeStartLevelLocked() { 12745 return mDischargeUnplugLevel; 12746 } 12747 12748 @Override 12749 @UnsupportedAppUsage getDischargeCurrentLevel()12750 public int getDischargeCurrentLevel() { 12751 synchronized(this) { 12752 return getDischargeCurrentLevelLocked(); 12753 } 12754 } 12755 getDischargeCurrentLevelLocked()12756 public int getDischargeCurrentLevelLocked() { 12757 return mDischargeCurrentLevel; 12758 } 12759 12760 @Override getLowDischargeAmountSinceCharge()12761 public int getLowDischargeAmountSinceCharge() { 12762 synchronized(this) { 12763 int val = mLowDischargeAmountSinceCharge; 12764 if (mOnBattery && mDischargeCurrentLevel < mDischargeUnplugLevel) { 12765 val += mDischargeUnplugLevel-mDischargeCurrentLevel-1; 12766 } 12767 return val; 12768 } 12769 } 12770 12771 @Override getHighDischargeAmountSinceCharge()12772 public int getHighDischargeAmountSinceCharge() { 12773 synchronized(this) { 12774 int val = mHighDischargeAmountSinceCharge; 12775 if (mOnBattery && mDischargeCurrentLevel < mDischargeUnplugLevel) { 12776 val += mDischargeUnplugLevel-mDischargeCurrentLevel; 12777 } 12778 return val; 12779 } 12780 } 12781 12782 @Override 12783 @UnsupportedAppUsage getDischargeAmount(int which)12784 public int getDischargeAmount(int which) { 12785 int dischargeAmount = which == STATS_SINCE_CHARGED 12786 ? getHighDischargeAmountSinceCharge() 12787 : (getDischargeStartLevel() - getDischargeCurrentLevel()); 12788 if (dischargeAmount < 0) { 12789 dischargeAmount = 0; 12790 } 12791 return dischargeAmount; 12792 } 12793 12794 @Override 12795 @UnsupportedAppUsage getDischargeAmountScreenOn()12796 public int getDischargeAmountScreenOn() { 12797 synchronized(this) { 12798 int val = mDischargeAmountScreenOn; 12799 if (mOnBattery && isScreenOn(mScreenState) 12800 && mDischargeCurrentLevel < mDischargeScreenOnUnplugLevel) { 12801 val += mDischargeScreenOnUnplugLevel-mDischargeCurrentLevel; 12802 } 12803 return val; 12804 } 12805 } 12806 12807 @Override getDischargeAmountScreenOnSinceCharge()12808 public int getDischargeAmountScreenOnSinceCharge() { 12809 synchronized(this) { 12810 int val = mDischargeAmountScreenOnSinceCharge; 12811 if (mOnBattery && isScreenOn(mScreenState) 12812 && mDischargeCurrentLevel < mDischargeScreenOnUnplugLevel) { 12813 val += mDischargeScreenOnUnplugLevel-mDischargeCurrentLevel; 12814 } 12815 return val; 12816 } 12817 } 12818 12819 @Override 12820 @UnsupportedAppUsage getDischargeAmountScreenOff()12821 public int getDischargeAmountScreenOff() { 12822 synchronized(this) { 12823 int val = mDischargeAmountScreenOff; 12824 if (mOnBattery && isScreenOff(mScreenState) 12825 && mDischargeCurrentLevel < mDischargeScreenOffUnplugLevel) { 12826 val += mDischargeScreenOffUnplugLevel-mDischargeCurrentLevel; 12827 } 12828 // For backward compatibility, doze discharge is counted into screen off. 12829 return val + getDischargeAmountScreenDoze(); 12830 } 12831 } 12832 12833 @Override getDischargeAmountScreenOffSinceCharge()12834 public int getDischargeAmountScreenOffSinceCharge() { 12835 synchronized(this) { 12836 int val = mDischargeAmountScreenOffSinceCharge; 12837 if (mOnBattery && isScreenOff(mScreenState) 12838 && mDischargeCurrentLevel < mDischargeScreenOffUnplugLevel) { 12839 val += mDischargeScreenOffUnplugLevel-mDischargeCurrentLevel; 12840 } 12841 // For backward compatibility, doze discharge is counted into screen off. 12842 return val + getDischargeAmountScreenDozeSinceCharge(); 12843 } 12844 } 12845 12846 @Override getDischargeAmountScreenDoze()12847 public int getDischargeAmountScreenDoze() { 12848 synchronized(this) { 12849 int val = mDischargeAmountScreenDoze; 12850 if (mOnBattery && isScreenDoze(mScreenState) 12851 && mDischargeCurrentLevel < mDischargeScreenDozeUnplugLevel) { 12852 val += mDischargeScreenDozeUnplugLevel-mDischargeCurrentLevel; 12853 } 12854 return val; 12855 } 12856 } 12857 12858 @Override getDischargeAmountScreenDozeSinceCharge()12859 public int getDischargeAmountScreenDozeSinceCharge() { 12860 synchronized(this) { 12861 int val = mDischargeAmountScreenDozeSinceCharge; 12862 if (mOnBattery && isScreenDoze(mScreenState) 12863 && mDischargeCurrentLevel < mDischargeScreenDozeUnplugLevel) { 12864 val += mDischargeScreenDozeUnplugLevel-mDischargeCurrentLevel; 12865 } 12866 return val; 12867 } 12868 } 12869 12870 /** 12871 * Retrieve the statistics object for a particular uid, creating if needed. 12872 */ 12873 @UnsupportedAppUsage getUidStatsLocked(int uid)12874 public Uid getUidStatsLocked(int uid) { 12875 Uid u = mUidStats.get(uid); 12876 if (u == null) { 12877 u = new Uid(this, uid); 12878 mUidStats.put(uid, u); 12879 } 12880 return u; 12881 } 12882 12883 /** 12884 * Retrieve the statistics object for a particular uid. Returns null if the object is not 12885 * available. 12886 */ getAvailableUidStatsLocked(int uid)12887 public Uid getAvailableUidStatsLocked(int uid) { 12888 Uid u = mUidStats.get(uid); 12889 return u; 12890 } 12891 onCleanupUserLocked(int userId)12892 public void onCleanupUserLocked(int userId) { 12893 final int firstUidForUser = UserHandle.getUid(userId, 0); 12894 final int lastUidForUser = UserHandle.getUid(userId, UserHandle.PER_USER_RANGE - 1); 12895 mPendingRemovedUids.add( 12896 new UidToRemove(firstUidForUser, lastUidForUser, mClocks.elapsedRealtime())); 12897 } 12898 onUserRemovedLocked(int userId)12899 public void onUserRemovedLocked(int userId) { 12900 final int firstUidForUser = UserHandle.getUid(userId, 0); 12901 final int lastUidForUser = UserHandle.getUid(userId, UserHandle.PER_USER_RANGE - 1); 12902 mUidStats.put(firstUidForUser, null); 12903 mUidStats.put(lastUidForUser, null); 12904 final int firstIndex = mUidStats.indexOfKey(firstUidForUser); 12905 final int lastIndex = mUidStats.indexOfKey(lastUidForUser); 12906 for (int i = firstIndex; i <= lastIndex; i++) { 12907 final Uid uid = mUidStats.valueAt(i); 12908 if (uid != null) { 12909 uid.detachFromTimeBase(); 12910 } 12911 } 12912 mUidStats.removeAtRange(firstIndex, lastIndex - firstIndex + 1); 12913 } 12914 12915 /** 12916 * Remove the statistics object for a particular uid. 12917 */ 12918 @UnsupportedAppUsage removeUidStatsLocked(int uid)12919 public void removeUidStatsLocked(int uid) { 12920 final Uid u = mUidStats.get(uid); 12921 if (u != null) { 12922 u.detachFromTimeBase(); 12923 } 12924 mUidStats.remove(uid); 12925 mPendingRemovedUids.add(new UidToRemove(uid, mClocks.elapsedRealtime())); 12926 } 12927 12928 /** 12929 * Retrieve the statistics object for a particular process, creating 12930 * if needed. 12931 */ 12932 @UnsupportedAppUsage getProcessStatsLocked(int uid, String name)12933 public Uid.Proc getProcessStatsLocked(int uid, String name) { 12934 uid = mapUid(uid); 12935 Uid u = getUidStatsLocked(uid); 12936 return u.getProcessStatsLocked(name); 12937 } 12938 12939 /** 12940 * Retrieve the statistics object for a particular process, creating 12941 * if needed. 12942 */ 12943 @UnsupportedAppUsage getPackageStatsLocked(int uid, String pkg)12944 public Uid.Pkg getPackageStatsLocked(int uid, String pkg) { 12945 uid = mapUid(uid); 12946 Uid u = getUidStatsLocked(uid); 12947 return u.getPackageStatsLocked(pkg); 12948 } 12949 12950 /** 12951 * Retrieve the statistics object for a particular service, creating 12952 * if needed. 12953 */ 12954 @UnsupportedAppUsage getServiceStatsLocked(int uid, String pkg, String name)12955 public Uid.Pkg.Serv getServiceStatsLocked(int uid, String pkg, String name) { 12956 uid = mapUid(uid); 12957 Uid u = getUidStatsLocked(uid); 12958 return u.getServiceStatsLocked(pkg, name); 12959 } 12960 shutdownLocked()12961 public void shutdownLocked() { 12962 recordShutdownLocked(mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 12963 writeSyncLocked(); 12964 mShuttingDown = true; 12965 } 12966 trackPerProcStateCpuTimes()12967 public boolean trackPerProcStateCpuTimes() { 12968 return mConstants.TRACK_CPU_TIMES_BY_PROC_STATE && mPerProcStateCpuTimesAvailable; 12969 } 12970 systemServicesReady(Context context)12971 public void systemServicesReady(Context context) { 12972 mConstants.startObserving(context.getContentResolver()); 12973 registerUsbStateReceiver(context); 12974 } 12975 12976 @VisibleForTesting 12977 public final class Constants extends ContentObserver { 12978 public static final String KEY_TRACK_CPU_TIMES_BY_PROC_STATE 12979 = "track_cpu_times_by_proc_state"; 12980 public static final String KEY_TRACK_CPU_ACTIVE_CLUSTER_TIME 12981 = "track_cpu_active_cluster_time"; 12982 public static final String KEY_PROC_STATE_CPU_TIMES_READ_DELAY_MS 12983 = "proc_state_cpu_times_read_delay_ms"; 12984 public static final String KEY_KERNEL_UID_READERS_THROTTLE_TIME 12985 = "kernel_uid_readers_throttle_time"; 12986 public static final String KEY_UID_REMOVE_DELAY_MS 12987 = "uid_remove_delay_ms"; 12988 public static final String KEY_EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS 12989 = "external_stats_collection_rate_limit_ms"; 12990 public static final String KEY_BATTERY_LEVEL_COLLECTION_DELAY_MS 12991 = "battery_level_collection_delay_ms"; 12992 public static final String KEY_MAX_HISTORY_FILES = "max_history_files"; 12993 public static final String KEY_MAX_HISTORY_BUFFER_KB = "max_history_buffer_kb"; 12994 public static final String KEY_BATTERY_CHARGED_DELAY_MS = 12995 "battery_charged_delay_ms"; 12996 12997 private static final boolean DEFAULT_TRACK_CPU_TIMES_BY_PROC_STATE = false; 12998 private static final boolean DEFAULT_TRACK_CPU_ACTIVE_CLUSTER_TIME = true; 12999 private static final long DEFAULT_PROC_STATE_CPU_TIMES_READ_DELAY_MS = 5_000; 13000 private static final long DEFAULT_KERNEL_UID_READERS_THROTTLE_TIME = 1_000; 13001 private static final long DEFAULT_UID_REMOVE_DELAY_MS = 5L * 60L * 1000L; 13002 private static final long DEFAULT_EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS = 600_000; 13003 private static final long DEFAULT_BATTERY_LEVEL_COLLECTION_DELAY_MS = 300_000; 13004 private static final int DEFAULT_MAX_HISTORY_FILES = 32; 13005 private static final int DEFAULT_MAX_HISTORY_BUFFER_KB = 128; /*Kilo Bytes*/ 13006 private static final int DEFAULT_MAX_HISTORY_FILES_LOW_RAM_DEVICE = 64; 13007 private static final int DEFAULT_MAX_HISTORY_BUFFER_LOW_RAM_DEVICE_KB = 64; /*Kilo Bytes*/ 13008 private static final int DEFAULT_BATTERY_CHARGED_DELAY_MS = 900000; /* 15 min */ 13009 13010 public boolean TRACK_CPU_TIMES_BY_PROC_STATE = DEFAULT_TRACK_CPU_TIMES_BY_PROC_STATE; 13011 public boolean TRACK_CPU_ACTIVE_CLUSTER_TIME = DEFAULT_TRACK_CPU_ACTIVE_CLUSTER_TIME; 13012 public long PROC_STATE_CPU_TIMES_READ_DELAY_MS = DEFAULT_PROC_STATE_CPU_TIMES_READ_DELAY_MS; 13013 /* Do not set default value for KERNEL_UID_READERS_THROTTLE_TIME. Need to trigger an 13014 * update when startObserving. */ 13015 public long KERNEL_UID_READERS_THROTTLE_TIME; 13016 public long UID_REMOVE_DELAY_MS = DEFAULT_UID_REMOVE_DELAY_MS; 13017 public long EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS 13018 = DEFAULT_EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS; 13019 public long BATTERY_LEVEL_COLLECTION_DELAY_MS 13020 = DEFAULT_BATTERY_LEVEL_COLLECTION_DELAY_MS; 13021 public int MAX_HISTORY_FILES; 13022 public int MAX_HISTORY_BUFFER; /*Bytes*/ 13023 public int BATTERY_CHARGED_DELAY_MS = DEFAULT_BATTERY_CHARGED_DELAY_MS; 13024 13025 private ContentResolver mResolver; 13026 private final KeyValueListParser mParser = new KeyValueListParser(','); 13027 Constants(Handler handler)13028 public Constants(Handler handler) { 13029 super(handler); 13030 if (ActivityManager.isLowRamDeviceStatic()) { 13031 MAX_HISTORY_FILES = DEFAULT_MAX_HISTORY_FILES_LOW_RAM_DEVICE; 13032 MAX_HISTORY_BUFFER = DEFAULT_MAX_HISTORY_BUFFER_LOW_RAM_DEVICE_KB * 1024; 13033 } else { 13034 MAX_HISTORY_FILES = DEFAULT_MAX_HISTORY_FILES; 13035 MAX_HISTORY_BUFFER = DEFAULT_MAX_HISTORY_BUFFER_KB * 1024; 13036 } 13037 } 13038 startObserving(ContentResolver resolver)13039 public void startObserving(ContentResolver resolver) { 13040 mResolver = resolver; 13041 mResolver.registerContentObserver( 13042 Settings.Global.getUriFor(Settings.Global.BATTERY_STATS_CONSTANTS), 13043 false /* notifyForDescendants */, this); 13044 mResolver.registerContentObserver( 13045 Settings.Global.getUriFor(Settings.Global.BATTERY_CHARGING_STATE_UPDATE_DELAY), 13046 false /* notifyForDescendants */, this); 13047 updateConstants(); 13048 } 13049 13050 @Override onChange(boolean selfChange, Uri uri)13051 public void onChange(boolean selfChange, Uri uri) { 13052 if (uri.equals( 13053 Settings.Global.getUriFor( 13054 Settings.Global.BATTERY_CHARGING_STATE_UPDATE_DELAY))) { 13055 synchronized (BatteryStatsImpl.this) { 13056 updateBatteryChargedDelayMsLocked(); 13057 } 13058 return; 13059 } 13060 updateConstants(); 13061 } 13062 updateConstants()13063 private void updateConstants() { 13064 synchronized (BatteryStatsImpl.this) { 13065 try { 13066 mParser.setString(Settings.Global.getString(mResolver, 13067 Settings.Global.BATTERY_STATS_CONSTANTS)); 13068 } catch (IllegalArgumentException e) { 13069 // Failed to parse the settings string, log this and move on 13070 // with defaults. 13071 Slog.e(TAG, "Bad batterystats settings", e); 13072 } 13073 13074 updateTrackCpuTimesByProcStateLocked(TRACK_CPU_TIMES_BY_PROC_STATE, 13075 mParser.getBoolean(KEY_TRACK_CPU_TIMES_BY_PROC_STATE, 13076 DEFAULT_TRACK_CPU_TIMES_BY_PROC_STATE)); 13077 TRACK_CPU_ACTIVE_CLUSTER_TIME = mParser.getBoolean( 13078 KEY_TRACK_CPU_ACTIVE_CLUSTER_TIME, DEFAULT_TRACK_CPU_ACTIVE_CLUSTER_TIME); 13079 updateProcStateCpuTimesReadDelayMs(PROC_STATE_CPU_TIMES_READ_DELAY_MS, 13080 mParser.getLong(KEY_PROC_STATE_CPU_TIMES_READ_DELAY_MS, 13081 DEFAULT_PROC_STATE_CPU_TIMES_READ_DELAY_MS)); 13082 updateKernelUidReadersThrottleTime(KERNEL_UID_READERS_THROTTLE_TIME, 13083 mParser.getLong(KEY_KERNEL_UID_READERS_THROTTLE_TIME, 13084 DEFAULT_KERNEL_UID_READERS_THROTTLE_TIME)); 13085 updateUidRemoveDelay( 13086 mParser.getLong(KEY_UID_REMOVE_DELAY_MS, DEFAULT_UID_REMOVE_DELAY_MS)); 13087 EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS = mParser.getLong( 13088 KEY_EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS, 13089 DEFAULT_EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS); 13090 BATTERY_LEVEL_COLLECTION_DELAY_MS = mParser.getLong( 13091 KEY_BATTERY_LEVEL_COLLECTION_DELAY_MS, 13092 DEFAULT_BATTERY_LEVEL_COLLECTION_DELAY_MS); 13093 13094 MAX_HISTORY_FILES = mParser.getInt(KEY_MAX_HISTORY_FILES, 13095 ActivityManager.isLowRamDeviceStatic() ? 13096 DEFAULT_MAX_HISTORY_FILES_LOW_RAM_DEVICE 13097 : DEFAULT_MAX_HISTORY_FILES); 13098 MAX_HISTORY_BUFFER = mParser.getInt(KEY_MAX_HISTORY_BUFFER_KB, 13099 ActivityManager.isLowRamDeviceStatic() ? 13100 DEFAULT_MAX_HISTORY_BUFFER_LOW_RAM_DEVICE_KB 13101 : DEFAULT_MAX_HISTORY_BUFFER_KB) 13102 * 1024; 13103 updateBatteryChargedDelayMsLocked(); 13104 } 13105 } 13106 updateBatteryChargedDelayMsLocked()13107 private void updateBatteryChargedDelayMsLocked() { 13108 // a negative value indicates that we should ignore this override 13109 final int delay = Settings.Global.getInt(mResolver, 13110 Settings.Global.BATTERY_CHARGING_STATE_UPDATE_DELAY, 13111 -1); 13112 13113 BATTERY_CHARGED_DELAY_MS = delay >= 0 ? delay : mParser.getInt( 13114 KEY_BATTERY_CHARGED_DELAY_MS, 13115 DEFAULT_BATTERY_CHARGED_DELAY_MS); 13116 } 13117 updateTrackCpuTimesByProcStateLocked(boolean wasEnabled, boolean isEnabled)13118 private void updateTrackCpuTimesByProcStateLocked(boolean wasEnabled, boolean isEnabled) { 13119 TRACK_CPU_TIMES_BY_PROC_STATE = isEnabled; 13120 if (isEnabled && !wasEnabled) { 13121 mIsPerProcessStateCpuDataStale = true; 13122 mExternalSync.scheduleCpuSyncDueToSettingChange(); 13123 13124 mNumSingleUidCpuTimeReads = 0; 13125 mNumBatchedSingleUidCpuTimeReads = 0; 13126 mCpuTimeReadsTrackingStartTime = mClocks.uptimeMillis(); 13127 } 13128 } 13129 updateProcStateCpuTimesReadDelayMs(long oldDelayMillis, long newDelayMillis)13130 private void updateProcStateCpuTimesReadDelayMs(long oldDelayMillis, long newDelayMillis) { 13131 PROC_STATE_CPU_TIMES_READ_DELAY_MS = newDelayMillis; 13132 if (oldDelayMillis != newDelayMillis) { 13133 mNumSingleUidCpuTimeReads = 0; 13134 mNumBatchedSingleUidCpuTimeReads = 0; 13135 mCpuTimeReadsTrackingStartTime = mClocks.uptimeMillis(); 13136 } 13137 } 13138 updateKernelUidReadersThrottleTime(long oldTimeMs, long newTimeMs)13139 private void updateKernelUidReadersThrottleTime(long oldTimeMs, long newTimeMs) { 13140 KERNEL_UID_READERS_THROTTLE_TIME = newTimeMs; 13141 if (oldTimeMs != newTimeMs) { 13142 mCpuUidUserSysTimeReader.setThrottle(KERNEL_UID_READERS_THROTTLE_TIME); 13143 mCpuUidFreqTimeReader.setThrottle(KERNEL_UID_READERS_THROTTLE_TIME); 13144 mCpuUidActiveTimeReader.setThrottle(KERNEL_UID_READERS_THROTTLE_TIME); 13145 mCpuUidClusterTimeReader 13146 .setThrottle(KERNEL_UID_READERS_THROTTLE_TIME); 13147 } 13148 } 13149 updateUidRemoveDelay(long newTimeMs)13150 private void updateUidRemoveDelay(long newTimeMs) { 13151 UID_REMOVE_DELAY_MS = newTimeMs; 13152 clearPendingRemovedUids(); 13153 } 13154 dumpLocked(PrintWriter pw)13155 public void dumpLocked(PrintWriter pw) { 13156 pw.print(KEY_TRACK_CPU_TIMES_BY_PROC_STATE); pw.print("="); 13157 pw.println(TRACK_CPU_TIMES_BY_PROC_STATE); 13158 pw.print(KEY_TRACK_CPU_ACTIVE_CLUSTER_TIME); pw.print("="); 13159 pw.println(TRACK_CPU_ACTIVE_CLUSTER_TIME); 13160 pw.print(KEY_PROC_STATE_CPU_TIMES_READ_DELAY_MS); pw.print("="); 13161 pw.println(PROC_STATE_CPU_TIMES_READ_DELAY_MS); 13162 pw.print(KEY_KERNEL_UID_READERS_THROTTLE_TIME); pw.print("="); 13163 pw.println(KERNEL_UID_READERS_THROTTLE_TIME); 13164 pw.print(KEY_EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS); pw.print("="); 13165 pw.println(EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS); 13166 pw.print(KEY_BATTERY_LEVEL_COLLECTION_DELAY_MS); pw.print("="); 13167 pw.println(BATTERY_LEVEL_COLLECTION_DELAY_MS); 13168 pw.print(KEY_MAX_HISTORY_FILES); pw.print("="); 13169 pw.println(MAX_HISTORY_FILES); 13170 pw.print(KEY_MAX_HISTORY_BUFFER_KB); pw.print("="); 13171 pw.println(MAX_HISTORY_BUFFER/1024); 13172 pw.print(KEY_BATTERY_CHARGED_DELAY_MS); pw.print("="); 13173 pw.println(BATTERY_CHARGED_DELAY_MS); 13174 } 13175 } 13176 getExternalStatsCollectionRateLimitMs()13177 public long getExternalStatsCollectionRateLimitMs() { 13178 synchronized (this) { 13179 return mConstants.EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS; 13180 } 13181 } 13182 13183 @GuardedBy("this") dumpConstantsLocked(PrintWriter pw)13184 public void dumpConstantsLocked(PrintWriter pw) { 13185 mConstants.dumpLocked(pw); 13186 } 13187 13188 @GuardedBy("this") dumpCpuStatsLocked(PrintWriter pw)13189 public void dumpCpuStatsLocked(PrintWriter pw) { 13190 int size = mUidStats.size(); 13191 pw.println("Per UID CPU user & system time in ms:"); 13192 for (int i = 0; i < size; i++) { 13193 int u = mUidStats.keyAt(i); 13194 Uid uid = mUidStats.get(u); 13195 pw.print(" "); pw.print(u); pw.print(": "); 13196 pw.print(uid.getUserCpuTimeUs(STATS_SINCE_CHARGED) / 1000); pw.print(" "); 13197 pw.println(uid.getSystemCpuTimeUs(STATS_SINCE_CHARGED) / 1000); 13198 } 13199 pw.println("Per UID CPU active time in ms:"); 13200 for (int i = 0; i < size; i++) { 13201 int u = mUidStats.keyAt(i); 13202 Uid uid = mUidStats.get(u); 13203 if (uid.getCpuActiveTime() > 0) { 13204 pw.print(" "); pw.print(u); pw.print(": "); pw.println(uid.getCpuActiveTime()); 13205 } 13206 } 13207 pw.println("Per UID CPU cluster time in ms:"); 13208 for (int i = 0; i < size; i++) { 13209 int u = mUidStats.keyAt(i); 13210 long[] times = mUidStats.get(u).getCpuClusterTimes(); 13211 if (times != null) { 13212 pw.print(" "); pw.print(u); pw.print(": "); pw.println(Arrays.toString(times)); 13213 } 13214 } 13215 pw.println("Per UID CPU frequency time in ms:"); 13216 for (int i = 0; i < size; i++) { 13217 int u = mUidStats.keyAt(i); 13218 long[] times = mUidStats.get(u).getCpuFreqTimes(STATS_SINCE_CHARGED); 13219 if (times != null) { 13220 pw.print(" "); pw.print(u); pw.print(": "); pw.println(Arrays.toString(times)); 13221 } 13222 } 13223 } 13224 13225 final ReentrantLock mWriteLock = new ReentrantLock(); 13226 writeAsyncLocked()13227 public void writeAsyncLocked() { 13228 writeStatsLocked(false); 13229 writeHistoryLocked(false); 13230 } 13231 writeSyncLocked()13232 public void writeSyncLocked() { 13233 writeStatsLocked(true); 13234 writeHistoryLocked(true); 13235 } 13236 writeStatsLocked(boolean sync)13237 void writeStatsLocked(boolean sync) { 13238 if (mStatsFile == null) { 13239 Slog.w(TAG, 13240 "writeStatsLocked: no file associated with this instance"); 13241 return; 13242 } 13243 13244 if (mShuttingDown) { 13245 return; 13246 } 13247 13248 final Parcel p = Parcel.obtain(); 13249 final long start = SystemClock.uptimeMillis(); 13250 writeSummaryToParcel(p, false/*history is in separate file*/); 13251 if (DEBUG) { 13252 Slog.d(TAG, "writeSummaryToParcel duration ms:" 13253 + (SystemClock.uptimeMillis() - start) + " bytes:" + p.dataSize()); 13254 } 13255 mLastWriteTime = mClocks.elapsedRealtime(); 13256 writeParcelToFileLocked(p, mStatsFile, sync); 13257 } 13258 writeHistoryLocked(boolean sync)13259 void writeHistoryLocked(boolean sync) { 13260 if (mBatteryStatsHistory.getActiveFile() == null) { 13261 Slog.w(TAG, 13262 "writeHistoryLocked: no history file associated with this instance"); 13263 return; 13264 } 13265 13266 if (mShuttingDown) { 13267 return; 13268 } 13269 13270 Parcel p = Parcel.obtain(); 13271 final long start = SystemClock.uptimeMillis(); 13272 writeHistoryBuffer(p, true, true); 13273 if (DEBUG) { 13274 Slog.d(TAG, "writeHistoryBuffer duration ms:" 13275 + (SystemClock.uptimeMillis() - start) + " bytes:" + p.dataSize()); 13276 } 13277 writeParcelToFileLocked(p, mBatteryStatsHistory.getActiveFile(), sync); 13278 } 13279 writeParcelToFileLocked(Parcel p, AtomicFile file, boolean sync)13280 void writeParcelToFileLocked(Parcel p, AtomicFile file, boolean sync) { 13281 if (sync) { 13282 commitPendingDataToDisk(p, file); 13283 } else { 13284 BackgroundThread.getHandler().post(new Runnable() { 13285 @Override public void run() { 13286 commitPendingDataToDisk(p, file); 13287 } 13288 }); 13289 } 13290 } 13291 commitPendingDataToDisk(Parcel p, AtomicFile file)13292 private void commitPendingDataToDisk(Parcel p, AtomicFile file) { 13293 mWriteLock.lock(); 13294 FileOutputStream fos = null; 13295 try { 13296 final long startTime = SystemClock.uptimeMillis(); 13297 fos = file.startWrite(); 13298 fos.write(p.marshall()); 13299 fos.flush(); 13300 file.finishWrite(fos); 13301 if (DEBUG) { 13302 Slog.d(TAG, "commitPendingDataToDisk file:" + file.getBaseFile().getPath() 13303 + " duration ms:" + (SystemClock.uptimeMillis() - startTime) 13304 + " bytes:" + p.dataSize()); 13305 } 13306 com.android.internal.logging.EventLogTags.writeCommitSysConfigFile( 13307 "batterystats", SystemClock.uptimeMillis() - startTime); 13308 } catch (IOException e) { 13309 Slog.w(TAG, "Error writing battery statistics", e); 13310 file.failWrite(fos); 13311 } finally { 13312 p.recycle(); 13313 mWriteLock.unlock(); 13314 } 13315 } 13316 13317 @UnsupportedAppUsage readLocked()13318 public void readLocked() { 13319 if (mDailyFile != null) { 13320 readDailyStatsLocked(); 13321 } 13322 13323 if (mStatsFile == null) { 13324 Slog.w(TAG, "readLocked: no file associated with this instance"); 13325 return; 13326 } 13327 13328 if (mBatteryStatsHistory.getActiveFile() == null) { 13329 Slog.w(TAG, 13330 "readLocked: no history file associated with this instance"); 13331 return; 13332 } 13333 13334 mUidStats.clear(); 13335 13336 Parcel stats = Parcel.obtain(); 13337 try { 13338 final long start = SystemClock.uptimeMillis(); 13339 byte[] raw = mStatsFile.readFully(); 13340 stats.unmarshall(raw, 0, raw.length); 13341 stats.setDataPosition(0); 13342 readSummaryFromParcel(stats); 13343 if (DEBUG) { 13344 Slog.d(TAG, "readLocked stats file:" + mStatsFile.getBaseFile().getPath() 13345 + " bytes:" + raw.length + " takes ms:" + (SystemClock.uptimeMillis() 13346 - start)); 13347 } 13348 } catch (Exception e) { 13349 Slog.e(TAG, "Error reading battery statistics", e); 13350 resetAllStatsLocked(); 13351 } finally { 13352 stats.recycle(); 13353 } 13354 13355 Parcel history = Parcel.obtain(); 13356 try { 13357 final long start = SystemClock.uptimeMillis(); 13358 byte[] raw = mBatteryStatsHistory.getActiveFile().readFully(); 13359 if (raw.length > 0) { 13360 history.unmarshall(raw, 0, raw.length); 13361 history.setDataPosition(0); 13362 readHistoryBuffer(history, true); 13363 } 13364 if (DEBUG) { 13365 Slog.d(TAG, "readLocked history file::" 13366 + mBatteryStatsHistory.getActiveFile().getBaseFile().getPath() 13367 + " bytes:" + raw.length + " takes ms:" + (SystemClock.uptimeMillis() 13368 - start)); 13369 } 13370 } catch (Exception e) { 13371 Slog.e(TAG, "Error reading battery history", e); 13372 clearHistoryLocked(); 13373 mBatteryStatsHistory.resetAllFiles(); 13374 } finally { 13375 history.recycle(); 13376 } 13377 13378 mEndPlatformVersion = Build.ID; 13379 13380 if (mHistoryBuffer.dataPosition() > 0 13381 || mBatteryStatsHistory.getFilesNumbers().size() > 1) { 13382 mRecordingHistory = true; 13383 final long elapsedRealtime = mClocks.elapsedRealtime(); 13384 final long uptime = mClocks.uptimeMillis(); 13385 if (USE_OLD_HISTORY) { 13386 addHistoryRecordLocked(elapsedRealtime, uptime, HistoryItem.CMD_START, mHistoryCur); 13387 } 13388 addHistoryBufferLocked(elapsedRealtime, HistoryItem.CMD_START, mHistoryCur); 13389 startRecordingHistory(elapsedRealtime, uptime, false); 13390 } 13391 13392 recordDailyStatsIfNeededLocked(false); 13393 } 13394 describeContents()13395 public int describeContents() { 13396 return 0; 13397 } 13398 readHistoryBuffer(Parcel in, boolean andOldHistory)13399 void readHistoryBuffer(Parcel in, boolean andOldHistory) throws ParcelFormatException { 13400 final int version = in.readInt(); 13401 if (version != VERSION) { 13402 Slog.w("BatteryStats", "readHistoryBuffer: version got " + version 13403 + ", expected " + VERSION + "; erasing old stats"); 13404 return; 13405 } 13406 13407 final long historyBaseTime = in.readLong(); 13408 13409 mHistoryBuffer.setDataSize(0); 13410 mHistoryBuffer.setDataPosition(0); 13411 13412 int bufSize = in.readInt(); 13413 int curPos = in.dataPosition(); 13414 if (bufSize >= (mConstants.MAX_HISTORY_BUFFER*100)) { 13415 throw new ParcelFormatException("File corrupt: history data buffer too large " + 13416 bufSize); 13417 } else if ((bufSize&~3) != bufSize) { 13418 throw new ParcelFormatException("File corrupt: history data buffer not aligned " + 13419 bufSize); 13420 } else { 13421 if (DEBUG_HISTORY) Slog.i(TAG, "***************** READING NEW HISTORY: " + bufSize 13422 + " bytes at " + curPos); 13423 mHistoryBuffer.appendFrom(in, curPos, bufSize); 13424 in.setDataPosition(curPos + bufSize); 13425 } 13426 13427 if (andOldHistory) { 13428 readOldHistory(in); 13429 } 13430 13431 if (DEBUG_HISTORY) { 13432 StringBuilder sb = new StringBuilder(128); 13433 sb.append("****************** OLD mHistoryBaseTime: "); 13434 TimeUtils.formatDuration(mHistoryBaseTime, sb); 13435 Slog.i(TAG, sb.toString()); 13436 } 13437 mHistoryBaseTime = historyBaseTime; 13438 if (DEBUG_HISTORY) { 13439 StringBuilder sb = new StringBuilder(128); 13440 sb.append("****************** NEW mHistoryBaseTime: "); 13441 TimeUtils.formatDuration(mHistoryBaseTime, sb); 13442 Slog.i(TAG, sb.toString()); 13443 } 13444 13445 // We are just arbitrarily going to insert 1 minute from the sample of 13446 // the last run until samples in this run. 13447 if (mHistoryBaseTime > 0) { 13448 long oldnow = mClocks.elapsedRealtime(); 13449 mHistoryBaseTime = mHistoryBaseTime - oldnow + 1; 13450 if (DEBUG_HISTORY) { 13451 StringBuilder sb = new StringBuilder(128); 13452 sb.append("****************** ADJUSTED mHistoryBaseTime: "); 13453 TimeUtils.formatDuration(mHistoryBaseTime, sb); 13454 Slog.i(TAG, sb.toString()); 13455 } 13456 } 13457 } 13458 readOldHistory(Parcel in)13459 void readOldHistory(Parcel in) { 13460 if (!USE_OLD_HISTORY) { 13461 return; 13462 } 13463 mHistory = mHistoryEnd = mHistoryCache = null; 13464 long time; 13465 while (in.dataAvail() > 0 && (time=in.readLong()) >= 0) { 13466 HistoryItem rec = new HistoryItem(time, in); 13467 addHistoryRecordLocked(rec); 13468 } 13469 } 13470 writeHistoryBuffer(Parcel out, boolean inclData, boolean andOldHistory)13471 void writeHistoryBuffer(Parcel out, boolean inclData, boolean andOldHistory) { 13472 if (DEBUG_HISTORY) { 13473 StringBuilder sb = new StringBuilder(128); 13474 sb.append("****************** WRITING mHistoryBaseTime: "); 13475 TimeUtils.formatDuration(mHistoryBaseTime, sb); 13476 sb.append(" mLastHistoryElapsedRealtime: "); 13477 TimeUtils.formatDuration(mLastHistoryElapsedRealtime, sb); 13478 Slog.i(TAG, sb.toString()); 13479 } 13480 out.writeInt(VERSION); 13481 out.writeLong(mHistoryBaseTime + mLastHistoryElapsedRealtime); 13482 if (!inclData) { 13483 out.writeInt(0); 13484 out.writeInt(0); 13485 return; 13486 } 13487 13488 out.writeInt(mHistoryBuffer.dataSize()); 13489 if (DEBUG_HISTORY) Slog.i(TAG, "***************** WRITING HISTORY: " 13490 + mHistoryBuffer.dataSize() + " bytes at " + out.dataPosition()); 13491 out.appendFrom(mHistoryBuffer, 0, mHistoryBuffer.dataSize()); 13492 13493 if (andOldHistory) { 13494 writeOldHistory(out); 13495 } 13496 } 13497 writeOldHistory(Parcel out)13498 void writeOldHistory(Parcel out) { 13499 if (!USE_OLD_HISTORY) { 13500 return; 13501 } 13502 HistoryItem rec = mHistory; 13503 while (rec != null) { 13504 if (rec.time >= 0) rec.writeToParcel(out, 0); 13505 rec = rec.next; 13506 } 13507 out.writeLong(-1); 13508 } 13509 readSummaryFromParcel(Parcel in)13510 public void readSummaryFromParcel(Parcel in) throws ParcelFormatException { 13511 final int version = in.readInt(); 13512 if (version != VERSION) { 13513 Slog.w("BatteryStats", "readFromParcel: version got " + version 13514 + ", expected " + VERSION + "; erasing old stats"); 13515 return; 13516 } 13517 13518 boolean inclHistory = in.readBoolean(); 13519 if (inclHistory) { 13520 readHistoryBuffer(in, true); 13521 mBatteryStatsHistory.readFromParcel(in); 13522 } 13523 13524 mHistoryTagPool.clear(); 13525 mNextHistoryTagIdx = 0; 13526 mNumHistoryTagChars = 0; 13527 13528 int numTags = in.readInt(); 13529 for (int i=0; i<numTags; i++) { 13530 int idx = in.readInt(); 13531 String str = in.readString(); 13532 if (str == null) { 13533 throw new ParcelFormatException("null history tag string"); 13534 } 13535 int uid = in.readInt(); 13536 HistoryTag tag = new HistoryTag(); 13537 tag.string = str; 13538 tag.uid = uid; 13539 tag.poolIdx = idx; 13540 mHistoryTagPool.put(tag, idx); 13541 if (idx >= mNextHistoryTagIdx) { 13542 mNextHistoryTagIdx = idx+1; 13543 } 13544 mNumHistoryTagChars += tag.string.length() + 1; 13545 } 13546 13547 mStartCount = in.readInt(); 13548 mUptime = in.readLong(); 13549 mRealtime = in.readLong(); 13550 mStartClockTime = in.readLong(); 13551 mStartPlatformVersion = in.readString(); 13552 mEndPlatformVersion = in.readString(); 13553 mOnBatteryTimeBase.readSummaryFromParcel(in); 13554 mOnBatteryScreenOffTimeBase.readSummaryFromParcel(in); 13555 mDischargeUnplugLevel = in.readInt(); 13556 mDischargePlugLevel = in.readInt(); 13557 mDischargeCurrentLevel = in.readInt(); 13558 mCurrentBatteryLevel = in.readInt(); 13559 mEstimatedBatteryCapacity = in.readInt(); 13560 mMinLearnedBatteryCapacity = in.readInt(); 13561 mMaxLearnedBatteryCapacity = in.readInt(); 13562 mLowDischargeAmountSinceCharge = in.readInt(); 13563 mHighDischargeAmountSinceCharge = in.readInt(); 13564 mDischargeAmountScreenOnSinceCharge = in.readInt(); 13565 mDischargeAmountScreenOffSinceCharge = in.readInt(); 13566 mDischargeAmountScreenDozeSinceCharge = in.readInt(); 13567 mDischargeStepTracker.readFromParcel(in); 13568 mChargeStepTracker.readFromParcel(in); 13569 mDailyDischargeStepTracker.readFromParcel(in); 13570 mDailyChargeStepTracker.readFromParcel(in); 13571 mDischargeCounter.readSummaryFromParcelLocked(in); 13572 mDischargeScreenOffCounter.readSummaryFromParcelLocked(in); 13573 mDischargeScreenDozeCounter.readSummaryFromParcelLocked(in); 13574 mDischargeLightDozeCounter.readSummaryFromParcelLocked(in); 13575 mDischargeDeepDozeCounter.readSummaryFromParcelLocked(in); 13576 int NPKG = in.readInt(); 13577 if (NPKG > 0) { 13578 mDailyPackageChanges = new ArrayList<>(NPKG); 13579 while (NPKG > 0) { 13580 NPKG--; 13581 PackageChange pc = new PackageChange(); 13582 pc.mPackageName = in.readString(); 13583 pc.mUpdate = in.readInt() != 0; 13584 pc.mVersionCode = in.readLong(); 13585 mDailyPackageChanges.add(pc); 13586 } 13587 } else { 13588 mDailyPackageChanges = null; 13589 } 13590 mDailyStartTime = in.readLong(); 13591 mNextMinDailyDeadline = in.readLong(); 13592 mNextMaxDailyDeadline = in.readLong(); 13593 13594 mStartCount++; 13595 13596 mScreenState = Display.STATE_UNKNOWN; 13597 mScreenOnTimer.readSummaryFromParcelLocked(in); 13598 mScreenDozeTimer.readSummaryFromParcelLocked(in); 13599 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 13600 mScreenBrightnessTimer[i].readSummaryFromParcelLocked(in); 13601 } 13602 mInteractive = false; 13603 mInteractiveTimer.readSummaryFromParcelLocked(in); 13604 mPhoneOn = false; 13605 mPowerSaveModeEnabledTimer.readSummaryFromParcelLocked(in); 13606 mLongestLightIdleTime = in.readLong(); 13607 mLongestFullIdleTime = in.readLong(); 13608 mDeviceIdleModeLightTimer.readSummaryFromParcelLocked(in); 13609 mDeviceIdleModeFullTimer.readSummaryFromParcelLocked(in); 13610 mDeviceLightIdlingTimer.readSummaryFromParcelLocked(in); 13611 mDeviceIdlingTimer.readSummaryFromParcelLocked(in); 13612 mPhoneOnTimer.readSummaryFromParcelLocked(in); 13613 for (int i = 0; i < CellSignalStrength.getNumSignalStrengthLevels(); i++) { 13614 mPhoneSignalStrengthsTimer[i].readSummaryFromParcelLocked(in); 13615 } 13616 mPhoneSignalScanningTimer.readSummaryFromParcelLocked(in); 13617 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 13618 mPhoneDataConnectionsTimer[i].readSummaryFromParcelLocked(in); 13619 } 13620 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 13621 mNetworkByteActivityCounters[i].readSummaryFromParcelLocked(in); 13622 mNetworkPacketActivityCounters[i].readSummaryFromParcelLocked(in); 13623 } 13624 mMobileRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW; 13625 mMobileRadioActiveTimer.readSummaryFromParcelLocked(in); 13626 mMobileRadioActivePerAppTimer.readSummaryFromParcelLocked(in); 13627 mMobileRadioActiveAdjustedTime.readSummaryFromParcelLocked(in); 13628 mMobileRadioActiveUnknownTime.readSummaryFromParcelLocked(in); 13629 mMobileRadioActiveUnknownCount.readSummaryFromParcelLocked(in); 13630 mWifiMulticastWakelockTimer.readSummaryFromParcelLocked(in); 13631 mWifiRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW; 13632 mWifiOn = false; 13633 mWifiOnTimer.readSummaryFromParcelLocked(in); 13634 mGlobalWifiRunning = false; 13635 mGlobalWifiRunningTimer.readSummaryFromParcelLocked(in); 13636 for (int i=0; i<NUM_WIFI_STATES; i++) { 13637 mWifiStateTimer[i].readSummaryFromParcelLocked(in); 13638 } 13639 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) { 13640 mWifiSupplStateTimer[i].readSummaryFromParcelLocked(in); 13641 } 13642 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { 13643 mWifiSignalStrengthsTimer[i].readSummaryFromParcelLocked(in); 13644 } 13645 mWifiActiveTimer.readSummaryFromParcelLocked(in); 13646 mWifiActivity.readSummaryFromParcel(in); 13647 for (int i=0; i<GnssMetrics.NUM_GPS_SIGNAL_QUALITY_LEVELS; i++) { 13648 mGpsSignalQualityTimer[i].readSummaryFromParcelLocked(in); 13649 } 13650 mBluetoothActivity.readSummaryFromParcel(in); 13651 mModemActivity.readSummaryFromParcel(in); 13652 mHasWifiReporting = in.readInt() != 0; 13653 mHasBluetoothReporting = in.readInt() != 0; 13654 mHasModemReporting = in.readInt() != 0; 13655 13656 mNumConnectivityChange = in.readInt(); 13657 mFlashlightOnNesting = 0; 13658 mFlashlightOnTimer.readSummaryFromParcelLocked(in); 13659 mCameraOnNesting = 0; 13660 mCameraOnTimer.readSummaryFromParcelLocked(in); 13661 mBluetoothScanNesting = 0; 13662 mBluetoothScanTimer.readSummaryFromParcelLocked(in); 13663 13664 int NRPMS = in.readInt(); 13665 if (NRPMS > 10000) { 13666 throw new ParcelFormatException("File corrupt: too many rpm stats " + NRPMS); 13667 } 13668 for (int irpm = 0; irpm < NRPMS; irpm++) { 13669 if (in.readInt() != 0) { 13670 String rpmName = in.readString(); 13671 getRpmTimerLocked(rpmName).readSummaryFromParcelLocked(in); 13672 } 13673 } 13674 int NSORPMS = in.readInt(); 13675 if (NSORPMS > 10000) { 13676 throw new ParcelFormatException("File corrupt: too many screen-off rpm stats " + NSORPMS); 13677 } 13678 for (int irpm = 0; irpm < NSORPMS; irpm++) { 13679 if (in.readInt() != 0) { 13680 String rpmName = in.readString(); 13681 getScreenOffRpmTimerLocked(rpmName).readSummaryFromParcelLocked(in); 13682 } 13683 } 13684 13685 int NKW = in.readInt(); 13686 if (NKW > 10000) { 13687 throw new ParcelFormatException("File corrupt: too many kernel wake locks " + NKW); 13688 } 13689 for (int ikw = 0; ikw < NKW; ikw++) { 13690 if (in.readInt() != 0) { 13691 String kwltName = in.readString(); 13692 getKernelWakelockTimerLocked(kwltName).readSummaryFromParcelLocked(in); 13693 } 13694 } 13695 13696 int NWR = in.readInt(); 13697 if (NWR > 10000) { 13698 throw new ParcelFormatException("File corrupt: too many wakeup reasons " + NWR); 13699 } 13700 for (int iwr = 0; iwr < NWR; iwr++) { 13701 if (in.readInt() != 0) { 13702 String reasonName = in.readString(); 13703 getWakeupReasonTimerLocked(reasonName).readSummaryFromParcelLocked(in); 13704 } 13705 } 13706 13707 int NMS = in.readInt(); 13708 for (int ims = 0; ims < NMS; ims++) { 13709 if (in.readInt() != 0) { 13710 long kmstName = in.readLong(); 13711 getKernelMemoryTimerLocked(kmstName).readSummaryFromParcelLocked(in); 13712 } 13713 } 13714 13715 final int NU = in.readInt(); 13716 if (NU > 10000) { 13717 throw new ParcelFormatException("File corrupt: too many uids " + NU); 13718 } 13719 for (int iu = 0; iu < NU; iu++) { 13720 int uid = in.readInt(); 13721 Uid u = new Uid(this, uid); 13722 mUidStats.put(uid, u); 13723 13724 u.mOnBatteryBackgroundTimeBase.readSummaryFromParcel(in); 13725 u.mOnBatteryScreenOffBackgroundTimeBase.readSummaryFromParcel(in); 13726 13727 u.mWifiRunning = false; 13728 if (in.readInt() != 0) { 13729 u.mWifiRunningTimer.readSummaryFromParcelLocked(in); 13730 } 13731 u.mFullWifiLockOut = false; 13732 if (in.readInt() != 0) { 13733 u.mFullWifiLockTimer.readSummaryFromParcelLocked(in); 13734 } 13735 u.mWifiScanStarted = false; 13736 if (in.readInt() != 0) { 13737 u.mWifiScanTimer.readSummaryFromParcelLocked(in); 13738 } 13739 u.mWifiBatchedScanBinStarted = Uid.NO_BATCHED_SCAN_STARTED; 13740 for (int i = 0; i < Uid.NUM_WIFI_BATCHED_SCAN_BINS; i++) { 13741 if (in.readInt() != 0) { 13742 u.makeWifiBatchedScanBin(i, null); 13743 u.mWifiBatchedScanTimer[i].readSummaryFromParcelLocked(in); 13744 } 13745 } 13746 u.mWifiMulticastWakelockCount = 0; 13747 if (in.readInt() != 0) { 13748 u.mWifiMulticastTimer.readSummaryFromParcelLocked(in); 13749 } 13750 if (in.readInt() != 0) { 13751 u.createAudioTurnedOnTimerLocked().readSummaryFromParcelLocked(in); 13752 } 13753 if (in.readInt() != 0) { 13754 u.createVideoTurnedOnTimerLocked().readSummaryFromParcelLocked(in); 13755 } 13756 if (in.readInt() != 0) { 13757 u.createFlashlightTurnedOnTimerLocked().readSummaryFromParcelLocked(in); 13758 } 13759 if (in.readInt() != 0) { 13760 u.createCameraTurnedOnTimerLocked().readSummaryFromParcelLocked(in); 13761 } 13762 if (in.readInt() != 0) { 13763 u.createForegroundActivityTimerLocked().readSummaryFromParcelLocked(in); 13764 } 13765 if (in.readInt() != 0) { 13766 u.createForegroundServiceTimerLocked().readSummaryFromParcelLocked(in); 13767 } 13768 if (in.readInt() != 0) { 13769 u.createAggregatedPartialWakelockTimerLocked().readSummaryFromParcelLocked(in); 13770 } 13771 if (in.readInt() != 0) { 13772 u.createBluetoothScanTimerLocked().readSummaryFromParcelLocked(in); 13773 } 13774 if (in.readInt() != 0) { 13775 u.createBluetoothUnoptimizedScanTimerLocked().readSummaryFromParcelLocked(in); 13776 } 13777 if (in.readInt() != 0) { 13778 u.createBluetoothScanResultCounterLocked().readSummaryFromParcelLocked(in); 13779 } 13780 if (in.readInt() != 0) { 13781 u.createBluetoothScanResultBgCounterLocked().readSummaryFromParcelLocked(in); 13782 } 13783 u.mProcessState = ActivityManager.PROCESS_STATE_NONEXISTENT; 13784 for (int i = 0; i < Uid.NUM_PROCESS_STATE; i++) { 13785 if (in.readInt() != 0) { 13786 u.makeProcessState(i, null); 13787 u.mProcessStateTimer[i].readSummaryFromParcelLocked(in); 13788 } 13789 } 13790 if (in.readInt() != 0) { 13791 u.createVibratorOnTimerLocked().readSummaryFromParcelLocked(in); 13792 } 13793 13794 if (in.readInt() != 0) { 13795 if (u.mUserActivityCounters == null) { 13796 u.initUserActivityLocked(); 13797 } 13798 for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) { 13799 u.mUserActivityCounters[i].readSummaryFromParcelLocked(in); 13800 } 13801 } 13802 13803 if (in.readInt() != 0) { 13804 if (u.mNetworkByteActivityCounters == null) { 13805 u.initNetworkActivityLocked(); 13806 } 13807 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 13808 u.mNetworkByteActivityCounters[i].readSummaryFromParcelLocked(in); 13809 u.mNetworkPacketActivityCounters[i].readSummaryFromParcelLocked(in); 13810 } 13811 u.mMobileRadioActiveTime.readSummaryFromParcelLocked(in); 13812 u.mMobileRadioActiveCount.readSummaryFromParcelLocked(in); 13813 } 13814 13815 u.mUserCpuTime.readSummaryFromParcelLocked(in); 13816 u.mSystemCpuTime.readSummaryFromParcelLocked(in); 13817 13818 if (in.readInt() != 0) { 13819 final int numClusters = in.readInt(); 13820 if (mPowerProfile != null && mPowerProfile.getNumCpuClusters() != numClusters) { 13821 throw new ParcelFormatException("Incompatible cpu cluster arrangement"); 13822 } 13823 detachIfNotNull(u.mCpuClusterSpeedTimesUs); 13824 u.mCpuClusterSpeedTimesUs = new LongSamplingCounter[numClusters][]; 13825 for (int cluster = 0; cluster < numClusters; cluster++) { 13826 if (in.readInt() != 0) { 13827 final int NSB = in.readInt(); 13828 if (mPowerProfile != null && 13829 mPowerProfile.getNumSpeedStepsInCpuCluster(cluster) != NSB) { 13830 throw new ParcelFormatException("File corrupt: too many speed bins " + 13831 NSB); 13832 } 13833 13834 u.mCpuClusterSpeedTimesUs[cluster] = new LongSamplingCounter[NSB]; 13835 for (int speed = 0; speed < NSB; speed++) { 13836 if (in.readInt() != 0) { 13837 u.mCpuClusterSpeedTimesUs[cluster][speed] = new LongSamplingCounter( 13838 mOnBatteryTimeBase); 13839 u.mCpuClusterSpeedTimesUs[cluster][speed].readSummaryFromParcelLocked(in); 13840 } 13841 } 13842 } else { 13843 u.mCpuClusterSpeedTimesUs[cluster] = null; 13844 } 13845 } 13846 } else { 13847 detachIfNotNull(u.mCpuClusterSpeedTimesUs); 13848 u.mCpuClusterSpeedTimesUs = null; 13849 } 13850 13851 detachIfNotNull(u.mCpuFreqTimeMs); 13852 u.mCpuFreqTimeMs = LongSamplingCounterArray.readSummaryFromParcelLocked( 13853 in, mOnBatteryTimeBase); 13854 detachIfNotNull(u.mScreenOffCpuFreqTimeMs); 13855 u.mScreenOffCpuFreqTimeMs = LongSamplingCounterArray.readSummaryFromParcelLocked( 13856 in, mOnBatteryScreenOffTimeBase); 13857 13858 u.mCpuActiveTimeMs.readSummaryFromParcelLocked(in); 13859 u.mCpuClusterTimesMs.readSummaryFromParcelLocked(in); 13860 13861 int length = in.readInt(); 13862 if (length == Uid.NUM_PROCESS_STATE) { 13863 detachIfNotNull(u.mProcStateTimeMs); 13864 u.mProcStateTimeMs = new LongSamplingCounterArray[length]; 13865 for (int procState = 0; procState < length; ++procState) { 13866 u.mProcStateTimeMs[procState] 13867 = LongSamplingCounterArray.readSummaryFromParcelLocked( 13868 in, mOnBatteryTimeBase); 13869 } 13870 } else { 13871 detachIfNotNull(u.mProcStateTimeMs); 13872 u.mProcStateTimeMs = null; 13873 } 13874 length = in.readInt(); 13875 if (length == Uid.NUM_PROCESS_STATE) { 13876 detachIfNotNull(u.mProcStateScreenOffTimeMs); 13877 u.mProcStateScreenOffTimeMs = new LongSamplingCounterArray[length]; 13878 for (int procState = 0; procState < length; ++procState) { 13879 u.mProcStateScreenOffTimeMs[procState] 13880 = LongSamplingCounterArray.readSummaryFromParcelLocked( 13881 in, mOnBatteryScreenOffTimeBase); 13882 } 13883 } else { 13884 detachIfNotNull(u.mProcStateScreenOffTimeMs); 13885 u.mProcStateScreenOffTimeMs = null; 13886 } 13887 13888 if (in.readInt() != 0) { 13889 detachIfNotNull(u.mMobileRadioApWakeupCount); 13890 u.mMobileRadioApWakeupCount = new LongSamplingCounter(mOnBatteryTimeBase); 13891 u.mMobileRadioApWakeupCount.readSummaryFromParcelLocked(in); 13892 } else { 13893 detachIfNotNull(u.mMobileRadioApWakeupCount); 13894 u.mMobileRadioApWakeupCount = null; 13895 } 13896 13897 if (in.readInt() != 0) { 13898 detachIfNotNull(u.mWifiRadioApWakeupCount); 13899 u.mWifiRadioApWakeupCount = new LongSamplingCounter(mOnBatteryTimeBase); 13900 u.mWifiRadioApWakeupCount.readSummaryFromParcelLocked(in); 13901 } else { 13902 detachIfNotNull(u.mWifiRadioApWakeupCount); 13903 u.mWifiRadioApWakeupCount = null; 13904 } 13905 13906 int NW = in.readInt(); 13907 if (NW > (MAX_WAKELOCKS_PER_UID+1)) { 13908 throw new ParcelFormatException("File corrupt: too many wake locks " + NW); 13909 } 13910 for (int iw = 0; iw < NW; iw++) { 13911 String wlName = in.readString(); 13912 u.readWakeSummaryFromParcelLocked(wlName, in); 13913 } 13914 13915 int NS = in.readInt(); 13916 if (NS > (MAX_WAKELOCKS_PER_UID+1)) { 13917 throw new ParcelFormatException("File corrupt: too many syncs " + NS); 13918 } 13919 for (int is = 0; is < NS; is++) { 13920 String name = in.readString(); 13921 u.readSyncSummaryFromParcelLocked(name, in); 13922 } 13923 13924 int NJ = in.readInt(); 13925 if (NJ > (MAX_WAKELOCKS_PER_UID+1)) { 13926 throw new ParcelFormatException("File corrupt: too many job timers " + NJ); 13927 } 13928 for (int ij = 0; ij < NJ; ij++) { 13929 String name = in.readString(); 13930 u.readJobSummaryFromParcelLocked(name, in); 13931 } 13932 13933 u.readJobCompletionsFromParcelLocked(in); 13934 13935 u.mJobsDeferredEventCount.readSummaryFromParcelLocked(in); 13936 u.mJobsDeferredCount.readSummaryFromParcelLocked(in); 13937 u.mJobsFreshnessTimeMs.readSummaryFromParcelLocked(in); 13938 detachIfNotNull(u.mJobsFreshnessBuckets); 13939 for (int i = 0; i < JOB_FRESHNESS_BUCKETS.length; i++) { 13940 if (in.readInt() != 0) { 13941 u.mJobsFreshnessBuckets[i] = new Counter(u.mBsi.mOnBatteryTimeBase); 13942 u.mJobsFreshnessBuckets[i].readSummaryFromParcelLocked(in); 13943 } 13944 } 13945 13946 int NP = in.readInt(); 13947 if (NP > 1000) { 13948 throw new ParcelFormatException("File corrupt: too many sensors " + NP); 13949 } 13950 for (int is = 0; is < NP; is++) { 13951 int seNumber = in.readInt(); 13952 if (in.readInt() != 0) { 13953 u.getSensorTimerLocked(seNumber, true).readSummaryFromParcelLocked(in); 13954 } 13955 } 13956 13957 NP = in.readInt(); 13958 if (NP > 1000) { 13959 throw new ParcelFormatException("File corrupt: too many processes " + NP); 13960 } 13961 for (int ip = 0; ip < NP; ip++) { 13962 String procName = in.readString(); 13963 Uid.Proc p = u.getProcessStatsLocked(procName); 13964 p.mUserTime = in.readLong(); 13965 p.mSystemTime = in.readLong(); 13966 p.mForegroundTime = in.readLong(); 13967 p.mStarts = in.readInt(); 13968 p.mNumCrashes = in.readInt(); 13969 p.mNumAnrs = in.readInt(); 13970 p.readExcessivePowerFromParcelLocked(in); 13971 } 13972 13973 NP = in.readInt(); 13974 if (NP > 10000) { 13975 throw new ParcelFormatException("File corrupt: too many packages " + NP); 13976 } 13977 for (int ip = 0; ip < NP; ip++) { 13978 String pkgName = in.readString(); 13979 detachIfNotNull(u.mPackageStats.get(pkgName)); 13980 Uid.Pkg p = u.getPackageStatsLocked(pkgName); 13981 final int NWA = in.readInt(); 13982 if (NWA > 10000) { 13983 throw new ParcelFormatException("File corrupt: too many wakeup alarms " + NWA); 13984 } 13985 p.mWakeupAlarms.clear(); 13986 for (int iwa = 0; iwa < NWA; iwa++) { 13987 String tag = in.readString(); 13988 Counter c = new Counter(mOnBatteryScreenOffTimeBase); 13989 c.readSummaryFromParcelLocked(in); 13990 p.mWakeupAlarms.put(tag, c); 13991 } 13992 NS = in.readInt(); 13993 if (NS > 10000) { 13994 throw new ParcelFormatException("File corrupt: too many services " + NS); 13995 } 13996 for (int is = 0; is < NS; is++) { 13997 String servName = in.readString(); 13998 Uid.Pkg.Serv s = u.getServiceStatsLocked(pkgName, servName); 13999 s.mStartTime = in.readLong(); 14000 s.mStarts = in.readInt(); 14001 s.mLaunches = in.readInt(); 14002 } 14003 } 14004 } 14005 } 14006 14007 /** 14008 * Writes a summary of the statistics to a Parcel, in a format suitable to be written to 14009 * disk. This format does not allow a lossless round-trip. 14010 * 14011 * @param out the Parcel to be written to. 14012 */ writeSummaryToParcel(Parcel out, boolean inclHistory)14013 public void writeSummaryToParcel(Parcel out, boolean inclHistory) { 14014 pullPendingStateUpdatesLocked(); 14015 14016 // Pull the clock time. This may update the time and make a new history entry 14017 // if we had originally pulled a time before the RTC was set. 14018 getStartClockTime(); 14019 14020 final long NOW_SYS = mClocks.uptimeMillis() * 1000; 14021 final long NOWREAL_SYS = mClocks.elapsedRealtime() * 1000; 14022 14023 out.writeInt(VERSION); 14024 14025 out.writeBoolean(inclHistory); 14026 if (inclHistory) { 14027 writeHistoryBuffer(out, true, true); 14028 mBatteryStatsHistory.writeToParcel(out); 14029 } 14030 14031 out.writeInt(mHistoryTagPool.size()); 14032 for (HashMap.Entry<HistoryTag, Integer> ent : mHistoryTagPool.entrySet()) { 14033 HistoryTag tag = ent.getKey(); 14034 out.writeInt(ent.getValue()); 14035 out.writeString(tag.string); 14036 out.writeInt(tag.uid); 14037 } 14038 14039 out.writeInt(mStartCount); 14040 out.writeLong(computeUptime(NOW_SYS, STATS_SINCE_CHARGED)); 14041 out.writeLong(computeRealtime(NOWREAL_SYS, STATS_SINCE_CHARGED)); 14042 out.writeLong(mStartClockTime); 14043 out.writeString(mStartPlatformVersion); 14044 out.writeString(mEndPlatformVersion); 14045 mOnBatteryTimeBase.writeSummaryToParcel(out, NOW_SYS, NOWREAL_SYS); 14046 mOnBatteryScreenOffTimeBase.writeSummaryToParcel(out, NOW_SYS, NOWREAL_SYS); 14047 out.writeInt(mDischargeUnplugLevel); 14048 out.writeInt(mDischargePlugLevel); 14049 out.writeInt(mDischargeCurrentLevel); 14050 out.writeInt(mCurrentBatteryLevel); 14051 out.writeInt(mEstimatedBatteryCapacity); 14052 out.writeInt(mMinLearnedBatteryCapacity); 14053 out.writeInt(mMaxLearnedBatteryCapacity); 14054 out.writeInt(getLowDischargeAmountSinceCharge()); 14055 out.writeInt(getHighDischargeAmountSinceCharge()); 14056 out.writeInt(getDischargeAmountScreenOnSinceCharge()); 14057 out.writeInt(getDischargeAmountScreenOffSinceCharge()); 14058 out.writeInt(getDischargeAmountScreenDozeSinceCharge()); 14059 mDischargeStepTracker.writeToParcel(out); 14060 mChargeStepTracker.writeToParcel(out); 14061 mDailyDischargeStepTracker.writeToParcel(out); 14062 mDailyChargeStepTracker.writeToParcel(out); 14063 mDischargeCounter.writeSummaryFromParcelLocked(out); 14064 mDischargeScreenOffCounter.writeSummaryFromParcelLocked(out); 14065 mDischargeScreenDozeCounter.writeSummaryFromParcelLocked(out); 14066 mDischargeLightDozeCounter.writeSummaryFromParcelLocked(out); 14067 mDischargeDeepDozeCounter.writeSummaryFromParcelLocked(out); 14068 if (mDailyPackageChanges != null) { 14069 final int NPKG = mDailyPackageChanges.size(); 14070 out.writeInt(NPKG); 14071 for (int i=0; i<NPKG; i++) { 14072 PackageChange pc = mDailyPackageChanges.get(i); 14073 out.writeString(pc.mPackageName); 14074 out.writeInt(pc.mUpdate ? 1 : 0); 14075 out.writeLong(pc.mVersionCode); 14076 } 14077 } else { 14078 out.writeInt(0); 14079 } 14080 out.writeLong(mDailyStartTime); 14081 out.writeLong(mNextMinDailyDeadline); 14082 out.writeLong(mNextMaxDailyDeadline); 14083 14084 mScreenOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14085 mScreenDozeTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14086 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 14087 mScreenBrightnessTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14088 } 14089 mInteractiveTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14090 mPowerSaveModeEnabledTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14091 out.writeLong(mLongestLightIdleTime); 14092 out.writeLong(mLongestFullIdleTime); 14093 mDeviceIdleModeLightTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14094 mDeviceIdleModeFullTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14095 mDeviceLightIdlingTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14096 mDeviceIdlingTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14097 mPhoneOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14098 for (int i = 0; i < CellSignalStrength.getNumSignalStrengthLevels(); i++) { 14099 mPhoneSignalStrengthsTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14100 } 14101 mPhoneSignalScanningTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14102 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 14103 mPhoneDataConnectionsTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14104 } 14105 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 14106 mNetworkByteActivityCounters[i].writeSummaryFromParcelLocked(out); 14107 mNetworkPacketActivityCounters[i].writeSummaryFromParcelLocked(out); 14108 } 14109 mMobileRadioActiveTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14110 mMobileRadioActivePerAppTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14111 mMobileRadioActiveAdjustedTime.writeSummaryFromParcelLocked(out); 14112 mMobileRadioActiveUnknownTime.writeSummaryFromParcelLocked(out); 14113 mMobileRadioActiveUnknownCount.writeSummaryFromParcelLocked(out); 14114 mWifiMulticastWakelockTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14115 mWifiOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14116 mGlobalWifiRunningTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14117 for (int i=0; i<NUM_WIFI_STATES; i++) { 14118 mWifiStateTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14119 } 14120 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) { 14121 mWifiSupplStateTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14122 } 14123 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { 14124 mWifiSignalStrengthsTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14125 } 14126 mWifiActiveTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14127 mWifiActivity.writeSummaryToParcel(out); 14128 for (int i=0; i< GnssMetrics.NUM_GPS_SIGNAL_QUALITY_LEVELS; i++) { 14129 mGpsSignalQualityTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14130 } 14131 mBluetoothActivity.writeSummaryToParcel(out); 14132 mModemActivity.writeSummaryToParcel(out); 14133 out.writeInt(mHasWifiReporting ? 1 : 0); 14134 out.writeInt(mHasBluetoothReporting ? 1 : 0); 14135 out.writeInt(mHasModemReporting ? 1 : 0); 14136 14137 out.writeInt(mNumConnectivityChange); 14138 mFlashlightOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14139 mCameraOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14140 mBluetoothScanTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14141 14142 out.writeInt(mRpmStats.size()); 14143 for (Map.Entry<String, SamplingTimer> ent : mRpmStats.entrySet()) { 14144 Timer rpmt = ent.getValue(); 14145 if (rpmt != null) { 14146 out.writeInt(1); 14147 out.writeString(ent.getKey()); 14148 rpmt.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14149 } else { 14150 out.writeInt(0); 14151 } 14152 } 14153 out.writeInt(mScreenOffRpmStats.size()); 14154 for (Map.Entry<String, SamplingTimer> ent : mScreenOffRpmStats.entrySet()) { 14155 Timer rpmt = ent.getValue(); 14156 if (rpmt != null) { 14157 out.writeInt(1); 14158 out.writeString(ent.getKey()); 14159 rpmt.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14160 } else { 14161 out.writeInt(0); 14162 } 14163 } 14164 14165 out.writeInt(mKernelWakelockStats.size()); 14166 for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) { 14167 Timer kwlt = ent.getValue(); 14168 if (kwlt != null) { 14169 out.writeInt(1); 14170 out.writeString(ent.getKey()); 14171 kwlt.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14172 } else { 14173 out.writeInt(0); 14174 } 14175 } 14176 14177 out.writeInt(mWakeupReasonStats.size()); 14178 for (Map.Entry<String, SamplingTimer> ent : mWakeupReasonStats.entrySet()) { 14179 SamplingTimer timer = ent.getValue(); 14180 if (timer != null) { 14181 out.writeInt(1); 14182 out.writeString(ent.getKey()); 14183 timer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14184 } else { 14185 out.writeInt(0); 14186 } 14187 } 14188 14189 out.writeInt(mKernelMemoryStats.size()); 14190 for (int i = 0; i < mKernelMemoryStats.size(); i++) { 14191 Timer kmt = mKernelMemoryStats.valueAt(i); 14192 if (kmt != null) { 14193 out.writeInt(1); 14194 out.writeLong(mKernelMemoryStats.keyAt(i)); 14195 kmt.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14196 } else { 14197 out.writeInt(0); 14198 } 14199 } 14200 14201 final int NU = mUidStats.size(); 14202 out.writeInt(NU); 14203 for (int iu = 0; iu < NU; iu++) { 14204 out.writeInt(mUidStats.keyAt(iu)); 14205 Uid u = mUidStats.valueAt(iu); 14206 14207 u.mOnBatteryBackgroundTimeBase.writeSummaryToParcel(out, NOW_SYS, NOWREAL_SYS); 14208 u.mOnBatteryScreenOffBackgroundTimeBase.writeSummaryToParcel(out, NOW_SYS, NOWREAL_SYS); 14209 14210 if (u.mWifiRunningTimer != null) { 14211 out.writeInt(1); 14212 u.mWifiRunningTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14213 } else { 14214 out.writeInt(0); 14215 } 14216 if (u.mFullWifiLockTimer != null) { 14217 out.writeInt(1); 14218 u.mFullWifiLockTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14219 } else { 14220 out.writeInt(0); 14221 } 14222 if (u.mWifiScanTimer != null) { 14223 out.writeInt(1); 14224 u.mWifiScanTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14225 } else { 14226 out.writeInt(0); 14227 } 14228 for (int i = 0; i < Uid.NUM_WIFI_BATCHED_SCAN_BINS; i++) { 14229 if (u.mWifiBatchedScanTimer[i] != null) { 14230 out.writeInt(1); 14231 u.mWifiBatchedScanTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14232 } else { 14233 out.writeInt(0); 14234 } 14235 } 14236 if (u.mWifiMulticastTimer != null) { 14237 out.writeInt(1); 14238 u.mWifiMulticastTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14239 } else { 14240 out.writeInt(0); 14241 } 14242 if (u.mAudioTurnedOnTimer != null) { 14243 out.writeInt(1); 14244 u.mAudioTurnedOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14245 } else { 14246 out.writeInt(0); 14247 } 14248 if (u.mVideoTurnedOnTimer != null) { 14249 out.writeInt(1); 14250 u.mVideoTurnedOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14251 } else { 14252 out.writeInt(0); 14253 } 14254 if (u.mFlashlightTurnedOnTimer != null) { 14255 out.writeInt(1); 14256 u.mFlashlightTurnedOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14257 } else { 14258 out.writeInt(0); 14259 } 14260 if (u.mCameraTurnedOnTimer != null) { 14261 out.writeInt(1); 14262 u.mCameraTurnedOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14263 } else { 14264 out.writeInt(0); 14265 } 14266 if (u.mForegroundActivityTimer != null) { 14267 out.writeInt(1); 14268 u.mForegroundActivityTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14269 } else { 14270 out.writeInt(0); 14271 } 14272 if (u.mForegroundServiceTimer != null) { 14273 out.writeInt(1); 14274 u.mForegroundServiceTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14275 } else { 14276 out.writeInt(0); 14277 } 14278 if (u.mAggregatedPartialWakelockTimer != null) { 14279 out.writeInt(1); 14280 u.mAggregatedPartialWakelockTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14281 } else { 14282 out.writeInt(0); 14283 } 14284 if (u.mBluetoothScanTimer != null) { 14285 out.writeInt(1); 14286 u.mBluetoothScanTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14287 } else { 14288 out.writeInt(0); 14289 } 14290 if (u.mBluetoothUnoptimizedScanTimer != null) { 14291 out.writeInt(1); 14292 u.mBluetoothUnoptimizedScanTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14293 } else { 14294 out.writeInt(0); 14295 } 14296 if (u.mBluetoothScanResultCounter != null) { 14297 out.writeInt(1); 14298 u.mBluetoothScanResultCounter.writeSummaryFromParcelLocked(out); 14299 } else { 14300 out.writeInt(0); 14301 } 14302 if (u.mBluetoothScanResultBgCounter != null) { 14303 out.writeInt(1); 14304 u.mBluetoothScanResultBgCounter.writeSummaryFromParcelLocked(out); 14305 } else { 14306 out.writeInt(0); 14307 } 14308 for (int i = 0; i < Uid.NUM_PROCESS_STATE; i++) { 14309 if (u.mProcessStateTimer[i] != null) { 14310 out.writeInt(1); 14311 u.mProcessStateTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14312 } else { 14313 out.writeInt(0); 14314 } 14315 } 14316 if (u.mVibratorOnTimer != null) { 14317 out.writeInt(1); 14318 u.mVibratorOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14319 } else { 14320 out.writeInt(0); 14321 } 14322 14323 if (u.mUserActivityCounters == null) { 14324 out.writeInt(0); 14325 } else { 14326 out.writeInt(1); 14327 for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) { 14328 u.mUserActivityCounters[i].writeSummaryFromParcelLocked(out); 14329 } 14330 } 14331 14332 if (u.mNetworkByteActivityCounters == null) { 14333 out.writeInt(0); 14334 } else { 14335 out.writeInt(1); 14336 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 14337 u.mNetworkByteActivityCounters[i].writeSummaryFromParcelLocked(out); 14338 u.mNetworkPacketActivityCounters[i].writeSummaryFromParcelLocked(out); 14339 } 14340 u.mMobileRadioActiveTime.writeSummaryFromParcelLocked(out); 14341 u.mMobileRadioActiveCount.writeSummaryFromParcelLocked(out); 14342 } 14343 14344 u.mUserCpuTime.writeSummaryFromParcelLocked(out); 14345 u.mSystemCpuTime.writeSummaryFromParcelLocked(out); 14346 14347 if (u.mCpuClusterSpeedTimesUs != null) { 14348 out.writeInt(1); 14349 out.writeInt(u.mCpuClusterSpeedTimesUs.length); 14350 for (LongSamplingCounter[] cpuSpeeds : u.mCpuClusterSpeedTimesUs) { 14351 if (cpuSpeeds != null) { 14352 out.writeInt(1); 14353 out.writeInt(cpuSpeeds.length); 14354 for (LongSamplingCounter c : cpuSpeeds) { 14355 if (c != null) { 14356 out.writeInt(1); 14357 c.writeSummaryFromParcelLocked(out); 14358 } else { 14359 out.writeInt(0); 14360 } 14361 } 14362 } else { 14363 out.writeInt(0); 14364 } 14365 } 14366 } else { 14367 out.writeInt(0); 14368 } 14369 14370 LongSamplingCounterArray.writeSummaryToParcelLocked(out, u.mCpuFreqTimeMs); 14371 LongSamplingCounterArray.writeSummaryToParcelLocked(out, u.mScreenOffCpuFreqTimeMs); 14372 14373 u.mCpuActiveTimeMs.writeSummaryFromParcelLocked(out); 14374 u.mCpuClusterTimesMs.writeSummaryToParcelLocked(out); 14375 14376 if (u.mProcStateTimeMs != null) { 14377 out.writeInt(u.mProcStateTimeMs.length); 14378 for (LongSamplingCounterArray counters : u.mProcStateTimeMs) { 14379 LongSamplingCounterArray.writeSummaryToParcelLocked(out, counters); 14380 } 14381 } else { 14382 out.writeInt(0); 14383 } 14384 if (u.mProcStateScreenOffTimeMs != null) { 14385 out.writeInt(u.mProcStateScreenOffTimeMs.length); 14386 for (LongSamplingCounterArray counters : u.mProcStateScreenOffTimeMs) { 14387 LongSamplingCounterArray.writeSummaryToParcelLocked(out, counters); 14388 } 14389 } else { 14390 out.writeInt(0); 14391 } 14392 14393 if (u.mMobileRadioApWakeupCount != null) { 14394 out.writeInt(1); 14395 u.mMobileRadioApWakeupCount.writeSummaryFromParcelLocked(out); 14396 } else { 14397 out.writeInt(0); 14398 } 14399 14400 if (u.mWifiRadioApWakeupCount != null) { 14401 out.writeInt(1); 14402 u.mWifiRadioApWakeupCount.writeSummaryFromParcelLocked(out); 14403 } else { 14404 out.writeInt(0); 14405 } 14406 14407 final ArrayMap<String, Uid.Wakelock> wakeStats = u.mWakelockStats.getMap(); 14408 int NW = wakeStats.size(); 14409 out.writeInt(NW); 14410 for (int iw=0; iw<NW; iw++) { 14411 out.writeString(wakeStats.keyAt(iw)); 14412 Uid.Wakelock wl = wakeStats.valueAt(iw); 14413 if (wl.mTimerFull != null) { 14414 out.writeInt(1); 14415 wl.mTimerFull.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14416 } else { 14417 out.writeInt(0); 14418 } 14419 if (wl.mTimerPartial != null) { 14420 out.writeInt(1); 14421 wl.mTimerPartial.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14422 } else { 14423 out.writeInt(0); 14424 } 14425 if (wl.mTimerWindow != null) { 14426 out.writeInt(1); 14427 wl.mTimerWindow.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14428 } else { 14429 out.writeInt(0); 14430 } 14431 if (wl.mTimerDraw != null) { 14432 out.writeInt(1); 14433 wl.mTimerDraw.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14434 } else { 14435 out.writeInt(0); 14436 } 14437 } 14438 14439 final ArrayMap<String, DualTimer> syncStats = u.mSyncStats.getMap(); 14440 int NS = syncStats.size(); 14441 out.writeInt(NS); 14442 for (int is=0; is<NS; is++) { 14443 out.writeString(syncStats.keyAt(is)); 14444 syncStats.valueAt(is).writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14445 } 14446 14447 final ArrayMap<String, DualTimer> jobStats = u.mJobStats.getMap(); 14448 int NJ = jobStats.size(); 14449 out.writeInt(NJ); 14450 for (int ij=0; ij<NJ; ij++) { 14451 out.writeString(jobStats.keyAt(ij)); 14452 jobStats.valueAt(ij).writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14453 } 14454 14455 u.writeJobCompletionsToParcelLocked(out); 14456 14457 u.mJobsDeferredEventCount.writeSummaryFromParcelLocked(out); 14458 u.mJobsDeferredCount.writeSummaryFromParcelLocked(out); 14459 u.mJobsFreshnessTimeMs.writeSummaryFromParcelLocked(out); 14460 for (int i = 0; i < JOB_FRESHNESS_BUCKETS.length; i++) { 14461 if (u.mJobsFreshnessBuckets[i] != null) { 14462 out.writeInt(1); 14463 u.mJobsFreshnessBuckets[i].writeSummaryFromParcelLocked(out); 14464 } else { 14465 out.writeInt(0); 14466 } 14467 } 14468 14469 int NSE = u.mSensorStats.size(); 14470 out.writeInt(NSE); 14471 for (int ise=0; ise<NSE; ise++) { 14472 out.writeInt(u.mSensorStats.keyAt(ise)); 14473 Uid.Sensor se = u.mSensorStats.valueAt(ise); 14474 if (se.mTimer != null) { 14475 out.writeInt(1); 14476 se.mTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14477 } else { 14478 out.writeInt(0); 14479 } 14480 } 14481 14482 int NP = u.mProcessStats.size(); 14483 out.writeInt(NP); 14484 for (int ip=0; ip<NP; ip++) { 14485 out.writeString(u.mProcessStats.keyAt(ip)); 14486 Uid.Proc ps = u.mProcessStats.valueAt(ip); 14487 out.writeLong(ps.mUserTime); 14488 out.writeLong(ps.mSystemTime); 14489 out.writeLong(ps.mForegroundTime); 14490 out.writeInt(ps.mStarts); 14491 out.writeInt(ps.mNumCrashes); 14492 out.writeInt(ps.mNumAnrs); 14493 ps.writeExcessivePowerToParcelLocked(out); 14494 } 14495 14496 NP = u.mPackageStats.size(); 14497 out.writeInt(NP); 14498 if (NP > 0) { 14499 for (Map.Entry<String, BatteryStatsImpl.Uid.Pkg> ent 14500 : u.mPackageStats.entrySet()) { 14501 out.writeString(ent.getKey()); 14502 Uid.Pkg ps = ent.getValue(); 14503 final int NWA = ps.mWakeupAlarms.size(); 14504 out.writeInt(NWA); 14505 for (int iwa=0; iwa<NWA; iwa++) { 14506 out.writeString(ps.mWakeupAlarms.keyAt(iwa)); 14507 ps.mWakeupAlarms.valueAt(iwa).writeSummaryFromParcelLocked(out); 14508 } 14509 NS = ps.mServiceStats.size(); 14510 out.writeInt(NS); 14511 for (int is=0; is<NS; is++) { 14512 out.writeString(ps.mServiceStats.keyAt(is)); 14513 BatteryStatsImpl.Uid.Pkg.Serv ss = ps.mServiceStats.valueAt(is); 14514 long time = ss.getStartTimeToNowLocked( 14515 mOnBatteryTimeBase.getUptime(NOW_SYS)); 14516 out.writeLong(time); 14517 out.writeInt(ss.mStarts); 14518 out.writeInt(ss.mLaunches); 14519 } 14520 } 14521 } 14522 } 14523 } 14524 readFromParcel(Parcel in)14525 public void readFromParcel(Parcel in) { 14526 readFromParcelLocked(in); 14527 } 14528 readFromParcelLocked(Parcel in)14529 void readFromParcelLocked(Parcel in) { 14530 int magic = in.readInt(); 14531 if (magic != MAGIC) { 14532 throw new ParcelFormatException("Bad magic number: #" + Integer.toHexString(magic)); 14533 } 14534 14535 readHistoryBuffer(in, false); 14536 mBatteryStatsHistory.readFromParcel(in); 14537 14538 mStartCount = in.readInt(); 14539 mStartClockTime = in.readLong(); 14540 mStartPlatformVersion = in.readString(); 14541 mEndPlatformVersion = in.readString(); 14542 mUptime = in.readLong(); 14543 mUptimeStart = in.readLong(); 14544 mRealtime = in.readLong(); 14545 mRealtimeStart = in.readLong(); 14546 mOnBattery = in.readInt() != 0; 14547 mEstimatedBatteryCapacity = in.readInt(); 14548 mMinLearnedBatteryCapacity = in.readInt(); 14549 mMaxLearnedBatteryCapacity = in.readInt(); 14550 mOnBatteryInternal = false; // we are no longer really running. 14551 mOnBatteryTimeBase.readFromParcel(in); 14552 mOnBatteryScreenOffTimeBase.readFromParcel(in); 14553 14554 mScreenState = Display.STATE_UNKNOWN; 14555 mScreenOnTimer = new StopwatchTimer(mClocks, null, -1, null, mOnBatteryTimeBase, in); 14556 mScreenDozeTimer = new StopwatchTimer(mClocks, null, -1, null, mOnBatteryTimeBase, in); 14557 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 14558 mScreenBrightnessTimer[i] = new StopwatchTimer(mClocks, null, -100-i, null, 14559 mOnBatteryTimeBase, in); 14560 } 14561 mInteractive = false; 14562 mInteractiveTimer = new StopwatchTimer(mClocks, null, -10, null, mOnBatteryTimeBase, in); 14563 mPhoneOn = false; 14564 mPowerSaveModeEnabledTimer = new StopwatchTimer(mClocks, null, -2, null, 14565 mOnBatteryTimeBase, in); 14566 mLongestLightIdleTime = in.readLong(); 14567 mLongestFullIdleTime = in.readLong(); 14568 mDeviceIdleModeLightTimer = new StopwatchTimer(mClocks, null, -14, null, 14569 mOnBatteryTimeBase, in); 14570 mDeviceIdleModeFullTimer = new StopwatchTimer(mClocks, null, -11, null, 14571 mOnBatteryTimeBase, in); 14572 mDeviceLightIdlingTimer = new StopwatchTimer(mClocks, null, -15, null, 14573 mOnBatteryTimeBase, in); 14574 mDeviceIdlingTimer = new StopwatchTimer(mClocks, null, -12, null, mOnBatteryTimeBase, in); 14575 mPhoneOnTimer = new StopwatchTimer(mClocks, null, -3, null, mOnBatteryTimeBase, in); 14576 for (int i = 0; i < CellSignalStrength.getNumSignalStrengthLevels(); i++) { 14577 mPhoneSignalStrengthsTimer[i] = new StopwatchTimer(mClocks, null, -200-i, 14578 null, mOnBatteryTimeBase, in); 14579 } 14580 mPhoneSignalScanningTimer = new StopwatchTimer(mClocks, null, -200+1, null, 14581 mOnBatteryTimeBase, in); 14582 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 14583 mPhoneDataConnectionsTimer[i] = new StopwatchTimer(mClocks, null, -300-i, 14584 null, mOnBatteryTimeBase, in); 14585 } 14586 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 14587 mNetworkByteActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase, in); 14588 mNetworkPacketActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase, in); 14589 } 14590 mMobileRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW; 14591 mMobileRadioActiveTimer = new StopwatchTimer(mClocks, null, -400, null, 14592 mOnBatteryTimeBase, in); 14593 mMobileRadioActivePerAppTimer = new StopwatchTimer(mClocks, null, -401, null, 14594 mOnBatteryTimeBase, in); 14595 mMobileRadioActiveAdjustedTime = new LongSamplingCounter(mOnBatteryTimeBase, in); 14596 mMobileRadioActiveUnknownTime = new LongSamplingCounter(mOnBatteryTimeBase, in); 14597 mMobileRadioActiveUnknownCount = new LongSamplingCounter(mOnBatteryTimeBase, in); 14598 mWifiMulticastWakelockTimer = new StopwatchTimer(mClocks, null, -4, null, 14599 mOnBatteryTimeBase, in); 14600 mWifiRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW; 14601 mWifiOn = false; 14602 mWifiOnTimer = new StopwatchTimer(mClocks, null, -4, null, mOnBatteryTimeBase, in); 14603 mGlobalWifiRunning = false; 14604 mGlobalWifiRunningTimer = new StopwatchTimer(mClocks, null, -5, null, 14605 mOnBatteryTimeBase, in); 14606 for (int i=0; i<NUM_WIFI_STATES; i++) { 14607 mWifiStateTimer[i] = new StopwatchTimer(mClocks, null, -600-i, 14608 null, mOnBatteryTimeBase, in); 14609 } 14610 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) { 14611 mWifiSupplStateTimer[i] = new StopwatchTimer(mClocks, null, -700-i, 14612 null, mOnBatteryTimeBase, in); 14613 } 14614 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { 14615 mWifiSignalStrengthsTimer[i] = new StopwatchTimer(mClocks, null, -800-i, 14616 null, mOnBatteryTimeBase, in); 14617 } 14618 mWifiActiveTimer = new StopwatchTimer(mClocks, null, -900, null, 14619 mOnBatteryTimeBase, in); 14620 mWifiActivity = new ControllerActivityCounterImpl(mOnBatteryTimeBase, 14621 NUM_WIFI_TX_LEVELS, in); 14622 for (int i=0; i<GnssMetrics.NUM_GPS_SIGNAL_QUALITY_LEVELS; i++) { 14623 mGpsSignalQualityTimer[i] = new StopwatchTimer(mClocks, null, -1000-i, 14624 null, mOnBatteryTimeBase, in); 14625 } 14626 mBluetoothActivity = new ControllerActivityCounterImpl(mOnBatteryTimeBase, 14627 NUM_BT_TX_LEVELS, in); 14628 mModemActivity = new ControllerActivityCounterImpl(mOnBatteryTimeBase, 14629 ModemActivityInfo.TX_POWER_LEVELS, in); 14630 mHasWifiReporting = in.readInt() != 0; 14631 mHasBluetoothReporting = in.readInt() != 0; 14632 mHasModemReporting = in.readInt() != 0; 14633 14634 mNumConnectivityChange = in.readInt(); 14635 mAudioOnNesting = 0; 14636 // TODO: It's likely a mistake that mAudioOnTimer/mVideoOnTimer don't write/read to parcel! 14637 mAudioOnTimer = new StopwatchTimer(mClocks, null, -7, null, mOnBatteryTimeBase); 14638 mVideoOnNesting = 0; 14639 mVideoOnTimer = new StopwatchTimer(mClocks, null, -8, null, mOnBatteryTimeBase); 14640 mFlashlightOnNesting = 0; 14641 mFlashlightOnTimer = new StopwatchTimer(mClocks, null, -9, null, mOnBatteryTimeBase, in); 14642 mCameraOnNesting = 0; 14643 mCameraOnTimer = new StopwatchTimer(mClocks, null, -13, null, mOnBatteryTimeBase, in); 14644 mBluetoothScanNesting = 0; 14645 mBluetoothScanTimer = new StopwatchTimer(mClocks, null, -14, null, mOnBatteryTimeBase, in); 14646 mDischargeUnplugLevel = in.readInt(); 14647 mDischargePlugLevel = in.readInt(); 14648 mDischargeCurrentLevel = in.readInt(); 14649 mCurrentBatteryLevel = in.readInt(); 14650 mLowDischargeAmountSinceCharge = in.readInt(); 14651 mHighDischargeAmountSinceCharge = in.readInt(); 14652 mDischargeAmountScreenOn = in.readInt(); 14653 mDischargeAmountScreenOnSinceCharge = in.readInt(); 14654 mDischargeAmountScreenOff = in.readInt(); 14655 mDischargeAmountScreenOffSinceCharge = in.readInt(); 14656 mDischargeAmountScreenDoze = in.readInt(); 14657 mDischargeAmountScreenDozeSinceCharge = in.readInt(); 14658 mDischargeStepTracker.readFromParcel(in); 14659 mChargeStepTracker.readFromParcel(in); 14660 mDischargeCounter = new LongSamplingCounter(mOnBatteryTimeBase, in); 14661 mDischargeScreenOffCounter = new LongSamplingCounter(mOnBatteryScreenOffTimeBase, in); 14662 mDischargeScreenDozeCounter = new LongSamplingCounter(mOnBatteryTimeBase, in); 14663 mDischargeLightDozeCounter = new LongSamplingCounter(mOnBatteryTimeBase, in); 14664 mDischargeDeepDozeCounter = new LongSamplingCounter(mOnBatteryTimeBase, in); 14665 mLastWriteTime = in.readLong(); 14666 14667 mRpmStats.clear(); 14668 int NRPMS = in.readInt(); 14669 for (int irpm = 0; irpm < NRPMS; irpm++) { 14670 if (in.readInt() != 0) { 14671 String rpmName = in.readString(); 14672 SamplingTimer rpmt = new SamplingTimer(mClocks, mOnBatteryTimeBase, in); 14673 mRpmStats.put(rpmName, rpmt); 14674 } 14675 } 14676 mScreenOffRpmStats.clear(); 14677 int NSORPMS = in.readInt(); 14678 for (int irpm = 0; irpm < NSORPMS; irpm++) { 14679 if (in.readInt() != 0) { 14680 String rpmName = in.readString(); 14681 SamplingTimer rpmt = new SamplingTimer(mClocks, mOnBatteryScreenOffTimeBase, in); 14682 mScreenOffRpmStats.put(rpmName, rpmt); 14683 } 14684 } 14685 14686 mKernelWakelockStats.clear(); 14687 int NKW = in.readInt(); 14688 for (int ikw = 0; ikw < NKW; ikw++) { 14689 if (in.readInt() != 0) { 14690 String wakelockName = in.readString(); 14691 SamplingTimer kwlt = new SamplingTimer(mClocks, mOnBatteryScreenOffTimeBase, in); 14692 mKernelWakelockStats.put(wakelockName, kwlt); 14693 } 14694 } 14695 14696 mWakeupReasonStats.clear(); 14697 int NWR = in.readInt(); 14698 for (int iwr = 0; iwr < NWR; iwr++) { 14699 if (in.readInt() != 0) { 14700 String reasonName = in.readString(); 14701 SamplingTimer timer = new SamplingTimer(mClocks, mOnBatteryTimeBase, in); 14702 mWakeupReasonStats.put(reasonName, timer); 14703 } 14704 } 14705 14706 mKernelMemoryStats.clear(); 14707 int nmt = in.readInt(); 14708 for (int imt = 0; imt < nmt; imt++) { 14709 if (in.readInt() != 0) { 14710 Long bucket = in.readLong(); 14711 SamplingTimer kmt = new SamplingTimer(mClocks, mOnBatteryTimeBase, in); 14712 mKernelMemoryStats.put(bucket, kmt); 14713 } 14714 } 14715 14716 mPartialTimers.clear(); 14717 mFullTimers.clear(); 14718 mWindowTimers.clear(); 14719 mWifiRunningTimers.clear(); 14720 mFullWifiLockTimers.clear(); 14721 mWifiScanTimers.clear(); 14722 mWifiBatchedScanTimers.clear(); 14723 mWifiMulticastTimers.clear(); 14724 mAudioTurnedOnTimers.clear(); 14725 mVideoTurnedOnTimers.clear(); 14726 mFlashlightTurnedOnTimers.clear(); 14727 mCameraTurnedOnTimers.clear(); 14728 14729 int numUids = in.readInt(); 14730 mUidStats.clear(); 14731 for (int i = 0; i < numUids; i++) { 14732 int uid = in.readInt(); 14733 Uid u = new Uid(this, uid); 14734 u.readFromParcelLocked(mOnBatteryTimeBase, mOnBatteryScreenOffTimeBase, in); 14735 mUidStats.append(uid, u); 14736 } 14737 } 14738 writeToParcel(Parcel out, int flags)14739 public void writeToParcel(Parcel out, int flags) { 14740 writeToParcelLocked(out, true, flags); 14741 } 14742 writeToParcelWithoutUids(Parcel out, int flags)14743 public void writeToParcelWithoutUids(Parcel out, int flags) { 14744 writeToParcelLocked(out, false, flags); 14745 } 14746 14747 @SuppressWarnings("unused") writeToParcelLocked(Parcel out, boolean inclUids, int flags)14748 void writeToParcelLocked(Parcel out, boolean inclUids, int flags) { 14749 // Need to update with current kernel wake lock counts. 14750 pullPendingStateUpdatesLocked(); 14751 14752 // Pull the clock time. This may update the time and make a new history entry 14753 // if we had originally pulled a time before the RTC was set. 14754 getStartClockTime(); 14755 14756 final long uSecUptime = mClocks.uptimeMillis() * 1000; 14757 final long uSecRealtime = mClocks.elapsedRealtime() * 1000; 14758 final long batteryRealtime = mOnBatteryTimeBase.getRealtime(uSecRealtime); 14759 final long batteryScreenOffRealtime = mOnBatteryScreenOffTimeBase.getRealtime(uSecRealtime); 14760 14761 out.writeInt(MAGIC); 14762 14763 writeHistoryBuffer(out, true, false); 14764 mBatteryStatsHistory.writeToParcel(out); 14765 14766 out.writeInt(mStartCount); 14767 out.writeLong(mStartClockTime); 14768 out.writeString(mStartPlatformVersion); 14769 out.writeString(mEndPlatformVersion); 14770 out.writeLong(mUptime); 14771 out.writeLong(mUptimeStart); 14772 out.writeLong(mRealtime); 14773 out.writeLong(mRealtimeStart); 14774 out.writeInt(mOnBattery ? 1 : 0); 14775 out.writeInt(mEstimatedBatteryCapacity); 14776 out.writeInt(mMinLearnedBatteryCapacity); 14777 out.writeInt(mMaxLearnedBatteryCapacity); 14778 mOnBatteryTimeBase.writeToParcel(out, uSecUptime, uSecRealtime); 14779 mOnBatteryScreenOffTimeBase.writeToParcel(out, uSecUptime, uSecRealtime); 14780 14781 mScreenOnTimer.writeToParcel(out, uSecRealtime); 14782 mScreenDozeTimer.writeToParcel(out, uSecRealtime); 14783 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 14784 mScreenBrightnessTimer[i].writeToParcel(out, uSecRealtime); 14785 } 14786 mInteractiveTimer.writeToParcel(out, uSecRealtime); 14787 mPowerSaveModeEnabledTimer.writeToParcel(out, uSecRealtime); 14788 out.writeLong(mLongestLightIdleTime); 14789 out.writeLong(mLongestFullIdleTime); 14790 mDeviceIdleModeLightTimer.writeToParcel(out, uSecRealtime); 14791 mDeviceIdleModeFullTimer.writeToParcel(out, uSecRealtime); 14792 mDeviceLightIdlingTimer.writeToParcel(out, uSecRealtime); 14793 mDeviceIdlingTimer.writeToParcel(out, uSecRealtime); 14794 mPhoneOnTimer.writeToParcel(out, uSecRealtime); 14795 for (int i = 0; i < CellSignalStrength.getNumSignalStrengthLevels(); i++) { 14796 mPhoneSignalStrengthsTimer[i].writeToParcel(out, uSecRealtime); 14797 } 14798 mPhoneSignalScanningTimer.writeToParcel(out, uSecRealtime); 14799 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 14800 mPhoneDataConnectionsTimer[i].writeToParcel(out, uSecRealtime); 14801 } 14802 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 14803 mNetworkByteActivityCounters[i].writeToParcel(out); 14804 mNetworkPacketActivityCounters[i].writeToParcel(out); 14805 } 14806 mMobileRadioActiveTimer.writeToParcel(out, uSecRealtime); 14807 mMobileRadioActivePerAppTimer.writeToParcel(out, uSecRealtime); 14808 mMobileRadioActiveAdjustedTime.writeToParcel(out); 14809 mMobileRadioActiveUnknownTime.writeToParcel(out); 14810 mMobileRadioActiveUnknownCount.writeToParcel(out); 14811 mWifiMulticastWakelockTimer.writeToParcel(out, uSecRealtime); 14812 mWifiOnTimer.writeToParcel(out, uSecRealtime); 14813 mGlobalWifiRunningTimer.writeToParcel(out, uSecRealtime); 14814 for (int i=0; i<NUM_WIFI_STATES; i++) { 14815 mWifiStateTimer[i].writeToParcel(out, uSecRealtime); 14816 } 14817 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) { 14818 mWifiSupplStateTimer[i].writeToParcel(out, uSecRealtime); 14819 } 14820 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { 14821 mWifiSignalStrengthsTimer[i].writeToParcel(out, uSecRealtime); 14822 } 14823 mWifiActiveTimer.writeToParcel(out, uSecRealtime); 14824 mWifiActivity.writeToParcel(out, 0); 14825 for (int i=0; i< GnssMetrics.NUM_GPS_SIGNAL_QUALITY_LEVELS; i++) { 14826 mGpsSignalQualityTimer[i].writeToParcel(out, uSecRealtime); 14827 } 14828 mBluetoothActivity.writeToParcel(out, 0); 14829 mModemActivity.writeToParcel(out, 0); 14830 out.writeInt(mHasWifiReporting ? 1 : 0); 14831 out.writeInt(mHasBluetoothReporting ? 1 : 0); 14832 out.writeInt(mHasModemReporting ? 1 : 0); 14833 14834 out.writeInt(mNumConnectivityChange); 14835 mFlashlightOnTimer.writeToParcel(out, uSecRealtime); 14836 mCameraOnTimer.writeToParcel(out, uSecRealtime); 14837 mBluetoothScanTimer.writeToParcel(out, uSecRealtime); 14838 out.writeInt(mDischargeUnplugLevel); 14839 out.writeInt(mDischargePlugLevel); 14840 out.writeInt(mDischargeCurrentLevel); 14841 out.writeInt(mCurrentBatteryLevel); 14842 out.writeInt(mLowDischargeAmountSinceCharge); 14843 out.writeInt(mHighDischargeAmountSinceCharge); 14844 out.writeInt(mDischargeAmountScreenOn); 14845 out.writeInt(mDischargeAmountScreenOnSinceCharge); 14846 out.writeInt(mDischargeAmountScreenOff); 14847 out.writeInt(mDischargeAmountScreenOffSinceCharge); 14848 out.writeInt(mDischargeAmountScreenDoze); 14849 out.writeInt(mDischargeAmountScreenDozeSinceCharge); 14850 mDischargeStepTracker.writeToParcel(out); 14851 mChargeStepTracker.writeToParcel(out); 14852 mDischargeCounter.writeToParcel(out); 14853 mDischargeScreenOffCounter.writeToParcel(out); 14854 mDischargeScreenDozeCounter.writeToParcel(out); 14855 mDischargeLightDozeCounter.writeToParcel(out); 14856 mDischargeDeepDozeCounter.writeToParcel(out); 14857 out.writeLong(mLastWriteTime); 14858 14859 out.writeInt(mRpmStats.size()); 14860 for (Map.Entry<String, SamplingTimer> ent : mRpmStats.entrySet()) { 14861 SamplingTimer rpmt = ent.getValue(); 14862 if (rpmt != null) { 14863 out.writeInt(1); 14864 out.writeString(ent.getKey()); 14865 rpmt.writeToParcel(out, uSecRealtime); 14866 } else { 14867 out.writeInt(0); 14868 } 14869 } 14870 out.writeInt(mScreenOffRpmStats.size()); 14871 for (Map.Entry<String, SamplingTimer> ent : mScreenOffRpmStats.entrySet()) { 14872 SamplingTimer rpmt = ent.getValue(); 14873 if (rpmt != null) { 14874 out.writeInt(1); 14875 out.writeString(ent.getKey()); 14876 rpmt.writeToParcel(out, uSecRealtime); 14877 } else { 14878 out.writeInt(0); 14879 } 14880 } 14881 14882 if (inclUids) { 14883 out.writeInt(mKernelWakelockStats.size()); 14884 for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) { 14885 SamplingTimer kwlt = ent.getValue(); 14886 if (kwlt != null) { 14887 out.writeInt(1); 14888 out.writeString(ent.getKey()); 14889 kwlt.writeToParcel(out, uSecRealtime); 14890 } else { 14891 out.writeInt(0); 14892 } 14893 } 14894 out.writeInt(mWakeupReasonStats.size()); 14895 for (Map.Entry<String, SamplingTimer> ent : mWakeupReasonStats.entrySet()) { 14896 SamplingTimer timer = ent.getValue(); 14897 if (timer != null) { 14898 out.writeInt(1); 14899 out.writeString(ent.getKey()); 14900 timer.writeToParcel(out, uSecRealtime); 14901 } else { 14902 out.writeInt(0); 14903 } 14904 } 14905 } else { 14906 out.writeInt(0); 14907 out.writeInt(0); 14908 } 14909 14910 out.writeInt(mKernelMemoryStats.size()); 14911 for (int i = 0; i < mKernelMemoryStats.size(); i++) { 14912 SamplingTimer kmt = mKernelMemoryStats.valueAt(i); 14913 if (kmt != null) { 14914 out.writeInt(1); 14915 out.writeLong(mKernelMemoryStats.keyAt(i)); 14916 kmt.writeToParcel(out, uSecRealtime); 14917 } else { 14918 out.writeInt(0); 14919 } 14920 } 14921 14922 if (inclUids) { 14923 int size = mUidStats.size(); 14924 out.writeInt(size); 14925 for (int i = 0; i < size; i++) { 14926 out.writeInt(mUidStats.keyAt(i)); 14927 Uid uid = mUidStats.valueAt(i); 14928 14929 uid.writeToParcelLocked(out, uSecUptime, uSecRealtime); 14930 } 14931 } else { 14932 out.writeInt(0); 14933 } 14934 } 14935 14936 @UnsupportedAppUsage 14937 public static final Parcelable.Creator<BatteryStatsImpl> CREATOR = 14938 new Parcelable.Creator<BatteryStatsImpl>() { 14939 public BatteryStatsImpl createFromParcel(Parcel in) { 14940 return new BatteryStatsImpl(in); 14941 } 14942 14943 public BatteryStatsImpl[] newArray(int size) { 14944 return new BatteryStatsImpl[size]; 14945 } 14946 }; 14947 prepareForDumpLocked()14948 public void prepareForDumpLocked() { 14949 // Need to retrieve current kernel wake lock stats before printing. 14950 pullPendingStateUpdatesLocked(); 14951 14952 // Pull the clock time. This may update the time and make a new history entry 14953 // if we had originally pulled a time before the RTC was set. 14954 getStartClockTime(); 14955 } 14956 dumpLocked(Context context, PrintWriter pw, int flags, int reqUid, long histStart)14957 public void dumpLocked(Context context, PrintWriter pw, int flags, int reqUid, long histStart) { 14958 if (DEBUG) { 14959 pw.println("mOnBatteryTimeBase:"); 14960 mOnBatteryTimeBase.dump(pw, " "); 14961 pw.println("mOnBatteryScreenOffTimeBase:"); 14962 mOnBatteryScreenOffTimeBase.dump(pw, " "); 14963 Printer pr = new PrintWriterPrinter(pw); 14964 pr.println("*** Screen on timer:"); 14965 mScreenOnTimer.logState(pr, " "); 14966 pr.println("*** Screen doze timer:"); 14967 mScreenDozeTimer.logState(pr, " "); 14968 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 14969 pr.println("*** Screen brightness #" + i + ":"); 14970 mScreenBrightnessTimer[i].logState(pr, " "); 14971 } 14972 pr.println("*** Interactive timer:"); 14973 mInteractiveTimer.logState(pr, " "); 14974 pr.println("*** Power save mode timer:"); 14975 mPowerSaveModeEnabledTimer.logState(pr, " "); 14976 pr.println("*** Device idle mode light timer:"); 14977 mDeviceIdleModeLightTimer.logState(pr, " "); 14978 pr.println("*** Device idle mode full timer:"); 14979 mDeviceIdleModeFullTimer.logState(pr, " "); 14980 pr.println("*** Device light idling timer:"); 14981 mDeviceLightIdlingTimer.logState(pr, " "); 14982 pr.println("*** Device idling timer:"); 14983 mDeviceIdlingTimer.logState(pr, " "); 14984 pr.println("*** Phone timer:"); 14985 mPhoneOnTimer.logState(pr, " "); 14986 for (int i = 0; i < CellSignalStrength.getNumSignalStrengthLevels(); i++) { 14987 pr.println("*** Phone signal strength #" + i + ":"); 14988 mPhoneSignalStrengthsTimer[i].logState(pr, " "); 14989 } 14990 pr.println("*** Signal scanning :"); 14991 mPhoneSignalScanningTimer.logState(pr, " "); 14992 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 14993 pr.println("*** Data connection type #" + i + ":"); 14994 mPhoneDataConnectionsTimer[i].logState(pr, " "); 14995 } 14996 pr.println("*** mMobileRadioPowerState=" + mMobileRadioPowerState); 14997 pr.println("*** Mobile network active timer:"); 14998 mMobileRadioActiveTimer.logState(pr, " "); 14999 pr.println("*** Mobile network active adjusted timer:"); 15000 mMobileRadioActiveAdjustedTime.logState(pr, " "); 15001 pr.println("*** Wifi Multicast WakeLock Timer:"); 15002 mWifiMulticastWakelockTimer.logState(pr, " "); 15003 pr.println("*** mWifiRadioPowerState=" + mWifiRadioPowerState); 15004 pr.println("*** Wifi timer:"); 15005 mWifiOnTimer.logState(pr, " "); 15006 pr.println("*** WifiRunning timer:"); 15007 mGlobalWifiRunningTimer.logState(pr, " "); 15008 for (int i=0; i<NUM_WIFI_STATES; i++) { 15009 pr.println("*** Wifi state #" + i + ":"); 15010 mWifiStateTimer[i].logState(pr, " "); 15011 } 15012 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) { 15013 pr.println("*** Wifi suppl state #" + i + ":"); 15014 mWifiSupplStateTimer[i].logState(pr, " "); 15015 } 15016 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { 15017 pr.println("*** Wifi signal strength #" + i + ":"); 15018 mWifiSignalStrengthsTimer[i].logState(pr, " "); 15019 } 15020 for (int i=0; i<GnssMetrics.NUM_GPS_SIGNAL_QUALITY_LEVELS; i++) { 15021 pr.println("*** GPS signal quality #" + i + ":"); 15022 mGpsSignalQualityTimer[i].logState(pr, " "); 15023 } 15024 pr.println("*** Flashlight timer:"); 15025 mFlashlightOnTimer.logState(pr, " "); 15026 pr.println("*** Camera timer:"); 15027 mCameraOnTimer.logState(pr, " "); 15028 } 15029 super.dumpLocked(context, pw, flags, reqUid, histStart); 15030 pw.print("Total cpu time reads: "); 15031 pw.println(mNumSingleUidCpuTimeReads); 15032 pw.print("Batched cpu time reads: "); 15033 pw.println(mNumBatchedSingleUidCpuTimeReads); 15034 pw.print("Batching Duration (min): "); 15035 pw.println((mClocks.uptimeMillis() - mCpuTimeReadsTrackingStartTime) / (60 * 1000)); 15036 pw.print("All UID cpu time reads since the later of device start or stats reset: "); 15037 pw.println(mNumAllUidCpuTimeReads); 15038 pw.print("UIDs removed since the later of device start or stats reset: "); 15039 pw.println(mNumUidsRemoved); 15040 } 15041 } 15042