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.annotation.UnsupportedAppUsage; 22 import android.app.ActivityManager; 23 import android.bluetooth.BluetoothActivityEnergyInfo; 24 import android.bluetooth.UidTraffic; 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.DataConnectionRealTimeInfo; 62 import android.telephony.ModemActivityInfo; 63 import android.telephony.ServiceState; 64 import android.telephony.SignalStrength; 65 import android.telephony.TelephonyManager; 66 import android.text.TextUtils; 67 import android.util.ArrayMap; 68 import android.util.IntArray; 69 import android.util.KeyValueListParser; 70 import android.util.Log; 71 import android.util.LogWriter; 72 import android.util.LongSparseArray; 73 import android.util.LongSparseLongArray; 74 import android.util.MutableInt; 75 import android.util.Pools; 76 import android.util.PrintWriterPrinter; 77 import android.util.Printer; 78 import android.util.Slog; 79 import android.util.SparseArray; 80 import android.util.SparseIntArray; 81 import android.util.SparseLongArray; 82 import android.util.StatsLog; 83 import android.util.TimeUtils; 84 import android.util.Xml; 85 import android.view.Display; 86 87 import com.android.internal.annotations.GuardedBy; 88 import com.android.internal.annotations.VisibleForTesting; 89 import com.android.internal.location.gnssmetrics.GnssMetrics; 90 import com.android.internal.os.KernelCpuUidTimeReader.KernelCpuUidActiveTimeReader; 91 import com.android.internal.os.KernelCpuUidTimeReader.KernelCpuUidClusterTimeReader; 92 import com.android.internal.os.KernelCpuUidTimeReader.KernelCpuUidFreqTimeReader; 93 import com.android.internal.os.KernelCpuUidTimeReader.KernelCpuUidUserSysTimeReader; 94 import com.android.internal.util.ArrayUtils; 95 import com.android.internal.util.FastPrintWriter; 96 import com.android.internal.util.FastXmlSerializer; 97 import com.android.internal.util.XmlUtils; 98 99 import libcore.util.EmptyArray; 100 101 import org.xmlpull.v1.XmlPullParser; 102 import org.xmlpull.v1.XmlPullParserException; 103 import org.xmlpull.v1.XmlSerializer; 104 105 import java.io.ByteArrayOutputStream; 106 import java.io.File; 107 import java.io.FileInputStream; 108 import java.io.FileNotFoundException; 109 import java.io.FileOutputStream; 110 import java.io.IOException; 111 import java.io.PrintWriter; 112 import java.nio.charset.StandardCharsets; 113 import java.util.ArrayList; 114 import java.util.Arrays; 115 import java.util.Calendar; 116 import java.util.Collection; 117 import java.util.HashMap; 118 import java.util.HashSet; 119 import java.util.Iterator; 120 import java.util.LinkedList; 121 import java.util.List; 122 import java.util.Map; 123 import java.util.Queue; 124 import java.util.concurrent.Future; 125 import java.util.concurrent.atomic.AtomicInteger; 126 import java.util.concurrent.locks.ReentrantLock; 127 128 /** 129 * All information we are collecting about things that can happen that impact 130 * battery life. All times are represented in microseconds except where indicated 131 * otherwise. 132 */ 133 public class BatteryStatsImpl extends BatteryStats { 134 private static final String TAG = "BatteryStatsImpl"; 135 private static final boolean DEBUG = false; 136 public static final boolean DEBUG_ENERGY = false; 137 private static final boolean DEBUG_ENERGY_CPU = DEBUG_ENERGY; 138 private static final boolean DEBUG_MEMORY = false; 139 private static final boolean DEBUG_HISTORY = false; 140 private static final boolean USE_OLD_HISTORY = false; // for debugging. 141 142 // TODO: remove "tcp" from network methods, since we measure total stats. 143 144 // In-memory Parcel magic number, used to detect attempts to unmarshall bad data 145 private static final int MAGIC = 0xBA757475; // 'BATSTATS' 146 147 // Current on-disk Parcel version 148 static final int VERSION = 186 + (USE_OLD_HISTORY ? 1000 : 0); 149 150 // The maximum number of names wakelocks we will keep track of 151 // per uid; once the limit is reached, we batch the remaining wakelocks 152 // in to one common name. 153 private static final int MAX_WAKELOCKS_PER_UID; 154 155 static { 156 if (ActivityManager.isLowRamDeviceStatic()) { 157 MAX_WAKELOCKS_PER_UID = 40; 158 } else { 159 MAX_WAKELOCKS_PER_UID = 200; 160 } 161 } 162 163 // Number of transmit power states the Wifi controller can be in. 164 private static final int NUM_WIFI_TX_LEVELS = 1; 165 166 // Number of transmit power states the Bluetooth controller can be in. 167 private static final int NUM_BT_TX_LEVELS = 1; 168 169 /** 170 * Holding a wakelock costs more than just using the cpu. 171 * Currently, we assign only half the cpu time to an app that is running but 172 * not holding a wakelock. The apps holding wakelocks get the rest of the blame. 173 * If no app is holding a wakelock, then the distribution is normal. 174 */ 175 @VisibleForTesting 176 public static final int WAKE_LOCK_WEIGHT = 50; 177 178 protected Clocks mClocks; 179 180 private final AtomicFile mStatsFile; 181 public final AtomicFile mCheckinFile; 182 public final AtomicFile mDailyFile; 183 184 static final int MSG_REPORT_CPU_UPDATE_NEEDED = 1; 185 static final int MSG_REPORT_POWER_CHANGE = 2; 186 static final int MSG_REPORT_CHARGING = 3; 187 static final int MSG_REPORT_RESET_STATS = 4; 188 static final long DELAY_UPDATE_WAKELOCKS = 5*1000; 189 190 private static final double MILLISECONDS_IN_HOUR = 3600 * 1000; 191 private static final long MILLISECONDS_IN_YEAR = 365 * 24 * 3600 * 1000L; 192 193 private final KernelWakelockReader mKernelWakelockReader = new KernelWakelockReader(); 194 private final KernelWakelockStats mTmpWakelockStats = new KernelWakelockStats(); 195 196 @VisibleForTesting 197 protected KernelCpuUidUserSysTimeReader mCpuUidUserSysTimeReader = 198 new KernelCpuUidUserSysTimeReader(true); 199 @VisibleForTesting 200 protected KernelCpuSpeedReader[] mKernelCpuSpeedReaders; 201 @VisibleForTesting 202 protected KernelCpuUidFreqTimeReader mCpuUidFreqTimeReader = 203 new KernelCpuUidFreqTimeReader(true); 204 @VisibleForTesting 205 protected KernelCpuUidActiveTimeReader mCpuUidActiveTimeReader = 206 new KernelCpuUidActiveTimeReader(true); 207 @VisibleForTesting 208 protected KernelCpuUidClusterTimeReader mCpuUidClusterTimeReader = 209 new KernelCpuUidClusterTimeReader(true); 210 @VisibleForTesting 211 protected KernelSingleUidTimeReader mKernelSingleUidTimeReader; 212 213 private final KernelMemoryBandwidthStats mKernelMemoryBandwidthStats 214 = new KernelMemoryBandwidthStats(); 215 private final LongSparseArray<SamplingTimer> mKernelMemoryStats = new LongSparseArray<>(); getKernelMemoryStats()216 public LongSparseArray<SamplingTimer> getKernelMemoryStats() { 217 return mKernelMemoryStats; 218 } 219 220 @GuardedBy("this") 221 public boolean mPerProcStateCpuTimesAvailable = true; 222 223 /** 224 * When per process state cpu times tracking is off, cpu times in KernelSingleUidTimeReader are 225 * not updated. So, when the setting is turned on later, we would end up with huge cpu time 226 * deltas. This flag tracks the case where tracking is turned on from off so that we won't 227 * end up attributing the huge deltas to wrong buckets. 228 */ 229 @GuardedBy("this") 230 private boolean mIsPerProcessStateCpuDataStale; 231 232 /** 233 * Uids for which per-procstate cpu times need to be updated. 234 * 235 * Contains uid -> procState mappings. 236 */ 237 @GuardedBy("this") 238 @VisibleForTesting 239 protected final SparseIntArray mPendingUids = new SparseIntArray(); 240 241 @GuardedBy("this") 242 private long mNumSingleUidCpuTimeReads; 243 @GuardedBy("this") 244 private long mNumBatchedSingleUidCpuTimeReads; 245 @GuardedBy("this") 246 private long mCpuTimeReadsTrackingStartTime = SystemClock.uptimeMillis(); 247 @GuardedBy("this") 248 private int mNumUidsRemoved; 249 @GuardedBy("this") 250 private int mNumAllUidCpuTimeReads; 251 252 /** Container for Resource Power Manager stats. Updated by updateRpmStatsLocked. */ 253 private final RpmStats mTmpRpmStats = new RpmStats(); 254 /** The soonest the RPM stats can be updated after it was last updated. */ 255 private static final long RPM_STATS_UPDATE_FREQ_MS = 1000; 256 /** Last time that RPM stats were updated by updateRpmStatsLocked. */ 257 private long mLastRpmStatsUpdateTimeMs = -RPM_STATS_UPDATE_FREQ_MS; 258 259 /** Container for Rail Energy Data stats. */ 260 private final RailStats mTmpRailStats = new RailStats(); 261 /** 262 * Use a queue to delay removing UIDs from {@link KernelCpuUidUserSysTimeReader}, 263 * {@link KernelCpuUidActiveTimeReader}, {@link KernelCpuUidClusterTimeReader}, 264 * {@link KernelCpuUidFreqTimeReader} and from the Kernel. 265 * 266 * Isolated and invalid UID info must be removed to conserve memory. However, STATSD and 267 * Batterystats both need to access UID cpu time. To resolve this race condition, only 268 * Batterystats shall remove UIDs, and a delay {@link Constants#UID_REMOVE_DELAY_MS} is 269 * implemented so that STATSD can capture those UID times before they are deleted. 270 */ 271 @GuardedBy("this") 272 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) 273 protected Queue<UidToRemove> mPendingRemovedUids = new LinkedList<>(); 274 275 @VisibleForTesting 276 public final class UidToRemove { 277 int startUid; 278 int endUid; 279 long timeAddedInQueue; 280 281 /** Remove just one UID */ UidToRemove(int uid, long timestamp)282 public UidToRemove(int uid, long timestamp) { 283 this(uid, uid, timestamp); 284 } 285 286 /** Remove a range of UIDs, startUid must be smaller than endUid. */ UidToRemove(int startUid, int endUid, long timestamp)287 public UidToRemove(int startUid, int endUid, long timestamp) { 288 this.startUid = startUid; 289 this.endUid = endUid; 290 timeAddedInQueue = timestamp; 291 } 292 remove()293 void remove() { 294 if (startUid == endUid) { 295 mCpuUidUserSysTimeReader.removeUid(startUid); 296 mCpuUidFreqTimeReader.removeUid(startUid); 297 if (mConstants.TRACK_CPU_ACTIVE_CLUSTER_TIME) { 298 mCpuUidActiveTimeReader.removeUid(startUid); 299 mCpuUidClusterTimeReader.removeUid(startUid); 300 } 301 if (mKernelSingleUidTimeReader != null) { 302 mKernelSingleUidTimeReader.removeUid(startUid); 303 } 304 mNumUidsRemoved++; 305 } else if (startUid < endUid) { 306 mCpuUidFreqTimeReader.removeUidsInRange(startUid, endUid); 307 mCpuUidUserSysTimeReader.removeUidsInRange(startUid, endUid); 308 if (mConstants.TRACK_CPU_ACTIVE_CLUSTER_TIME) { 309 mCpuUidActiveTimeReader.removeUidsInRange(startUid, endUid); 310 mCpuUidClusterTimeReader.removeUidsInRange(startUid, endUid); 311 } 312 if (mKernelSingleUidTimeReader != null) { 313 mKernelSingleUidTimeReader.removeUidsInRange(startUid, endUid); 314 } 315 // Treat as one. We don't know how many uids there are in between. 316 mNumUidsRemoved++; 317 } else { 318 Slog.w(TAG, "End UID " + endUid + " is smaller than start UID " + startUid); 319 } 320 } 321 } 322 323 public interface BatteryCallback { batteryNeedsCpuUpdate()324 public void batteryNeedsCpuUpdate(); batteryPowerChanged(boolean onBattery)325 public void batteryPowerChanged(boolean onBattery); batterySendBroadcast(Intent intent)326 public void batterySendBroadcast(Intent intent); batteryStatsReset()327 public void batteryStatsReset(); 328 } 329 330 public interface PlatformIdleStateCallback { fillLowPowerStats(RpmStats rpmStats)331 public void fillLowPowerStats(RpmStats rpmStats); getPlatformLowPowerStats()332 public String getPlatformLowPowerStats(); getSubsystemLowPowerStats()333 public String getSubsystemLowPowerStats(); 334 } 335 336 /** interface to update rail information for power monitor */ 337 public interface RailEnergyDataCallback { 338 /** Function to fill the map for the rail data stats 339 * Used for power monitoring feature 340 * @param railStats 341 */ fillRailDataStats(RailStats railStats)342 void fillRailDataStats(RailStats railStats); 343 } 344 345 public static abstract class UserInfoProvider { 346 private int[] userIds; getUserIds()347 protected abstract @Nullable int[] getUserIds(); 348 @VisibleForTesting refreshUserIds()349 public final void refreshUserIds() { 350 userIds = getUserIds(); 351 } 352 @VisibleForTesting exists(int userId)353 public boolean exists(int userId) { 354 return userIds != null ? ArrayUtils.contains(userIds, userId) : true; 355 } 356 } 357 358 private final PlatformIdleStateCallback mPlatformIdleStateCallback; 359 360 private final Runnable mDeferSetCharging = new Runnable() { 361 @Override 362 public void run() { 363 synchronized (BatteryStatsImpl.this) { 364 if (mOnBattery) { 365 // if the device gets unplugged in the time between this runnable being 366 // executed and the lock being taken, we don't want to set charging state 367 return; 368 } 369 boolean changed = setChargingLocked(true); 370 if (changed) { 371 final long uptime = mClocks.uptimeMillis(); 372 final long elapsedRealtime = mClocks.elapsedRealtime(); 373 addHistoryRecordLocked(elapsedRealtime, uptime); 374 } 375 } 376 } 377 }; 378 379 public final RailEnergyDataCallback mRailEnergyDataCallback; 380 381 /** 382 * This handler is running on {@link BackgroundThread}. 383 */ 384 final class MyHandler extends Handler { MyHandler(Looper looper)385 public MyHandler(Looper looper) { 386 super(looper, null, true); 387 } 388 389 @Override handleMessage(Message msg)390 public void handleMessage(Message msg) { 391 BatteryCallback cb = mCallback; 392 switch (msg.what) { 393 case MSG_REPORT_CPU_UPDATE_NEEDED: 394 if (cb != null) { 395 cb.batteryNeedsCpuUpdate(); 396 } 397 break; 398 case MSG_REPORT_POWER_CHANGE: 399 if (cb != null) { 400 cb.batteryPowerChanged(msg.arg1 != 0); 401 } 402 break; 403 case MSG_REPORT_CHARGING: 404 if (cb != null) { 405 final String action; 406 synchronized (BatteryStatsImpl.this) { 407 action = mCharging ? BatteryManager.ACTION_CHARGING 408 : BatteryManager.ACTION_DISCHARGING; 409 } 410 Intent intent = new Intent(action); 411 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); 412 cb.batterySendBroadcast(intent); 413 } 414 break; 415 case MSG_REPORT_RESET_STATS: 416 if (cb != null) { 417 cb.batteryStatsReset(); 418 } 419 } 420 } 421 } 422 postBatteryNeedsCpuUpdateMsg()423 public void postBatteryNeedsCpuUpdateMsg() { 424 mHandler.sendEmptyMessage(MSG_REPORT_CPU_UPDATE_NEEDED); 425 } 426 427 /** 428 * Update per-freq cpu times for all the uids in {@link #mPendingUids}. 429 */ updateProcStateCpuTimes(boolean onBattery, boolean onBatteryScreenOff)430 public void updateProcStateCpuTimes(boolean onBattery, boolean onBatteryScreenOff) { 431 final SparseIntArray uidStates; 432 synchronized (BatteryStatsImpl.this) { 433 if (!mConstants.TRACK_CPU_TIMES_BY_PROC_STATE) { 434 return; 435 } 436 if(!initKernelSingleUidTimeReaderLocked()) { 437 return; 438 } 439 // If the KernelSingleUidTimeReader has stale cpu times, then we shouldn't try to 440 // compute deltas since it might result in mis-attributing cpu times to wrong states. 441 if (mIsPerProcessStateCpuDataStale) { 442 mPendingUids.clear(); 443 return; 444 } 445 446 if (mPendingUids.size() == 0) { 447 return; 448 } 449 uidStates = mPendingUids.clone(); 450 mPendingUids.clear(); 451 } 452 for (int i = uidStates.size() - 1; i >= 0; --i) { 453 final int uid = uidStates.keyAt(i); 454 final int procState = uidStates.valueAt(i); 455 final int[] isolatedUids; 456 final Uid u; 457 synchronized (BatteryStatsImpl.this) { 458 // It's possible that uid no longer exists and any internal references have 459 // already been deleted, so using {@link #getAvailableUidStatsLocked} to avoid 460 // creating an UidStats object if it doesn't already exist. 461 u = getAvailableUidStatsLocked(uid); 462 if (u == null) { 463 continue; 464 } 465 if (u.mChildUids == null) { 466 isolatedUids = null; 467 } else { 468 isolatedUids = u.mChildUids.toArray(); 469 for (int j = isolatedUids.length - 1; j >= 0; --j) { 470 isolatedUids[j] = u.mChildUids.get(j); 471 } 472 } 473 } 474 long[] cpuTimesMs = mKernelSingleUidTimeReader.readDeltaMs(uid); 475 if (isolatedUids != null) { 476 for (int j = isolatedUids.length - 1; j >= 0; --j) { 477 cpuTimesMs = addCpuTimes(cpuTimesMs, 478 mKernelSingleUidTimeReader.readDeltaMs(isolatedUids[j])); 479 } 480 } 481 if (onBattery && cpuTimesMs != null) { 482 synchronized (BatteryStatsImpl.this) { 483 u.addProcStateTimesMs(procState, cpuTimesMs, onBattery); 484 u.addProcStateScreenOffTimesMs(procState, cpuTimesMs, onBatteryScreenOff); 485 } 486 } 487 } 488 } 489 clearPendingRemovedUids()490 public void clearPendingRemovedUids() { 491 long cutOffTime = mClocks.elapsedRealtime() - mConstants.UID_REMOVE_DELAY_MS; 492 while (!mPendingRemovedUids.isEmpty() 493 && mPendingRemovedUids.peek().timeAddedInQueue < cutOffTime) { 494 mPendingRemovedUids.poll().remove(); 495 } 496 } 497 copyFromAllUidsCpuTimes()498 public void copyFromAllUidsCpuTimes() { 499 synchronized (BatteryStatsImpl.this) { 500 copyFromAllUidsCpuTimes( 501 mOnBatteryTimeBase.isRunning(), mOnBatteryScreenOffTimeBase.isRunning()); 502 } 503 } 504 505 /** 506 * When the battery/screen state changes, we don't attribute the cpu times to any process 507 * but we still need to snapshots of all uids to get correct deltas later on. Since we 508 * already read this data for updating per-freq cpu times, we can use the same data for 509 * per-procstate cpu times. 510 */ copyFromAllUidsCpuTimes(boolean onBattery, boolean onBatteryScreenOff)511 public void copyFromAllUidsCpuTimes(boolean onBattery, boolean onBatteryScreenOff) { 512 synchronized (BatteryStatsImpl.this) { 513 if (!mConstants.TRACK_CPU_TIMES_BY_PROC_STATE) { 514 return; 515 } 516 if(!initKernelSingleUidTimeReaderLocked()) { 517 return; 518 } 519 520 final SparseArray<long[]> allUidCpuFreqTimesMs = 521 mCpuUidFreqTimeReader.getAllUidCpuFreqTimeMs(); 522 // If the KernelSingleUidTimeReader has stale cpu times, then we shouldn't try to 523 // compute deltas since it might result in mis-attributing cpu times to wrong states. 524 if (mIsPerProcessStateCpuDataStale) { 525 mKernelSingleUidTimeReader.setAllUidsCpuTimesMs(allUidCpuFreqTimesMs); 526 mIsPerProcessStateCpuDataStale = false; 527 mPendingUids.clear(); 528 return; 529 } 530 for (int i = allUidCpuFreqTimesMs.size() - 1; i >= 0; --i) { 531 final int uid = allUidCpuFreqTimesMs.keyAt(i); 532 final Uid u = getAvailableUidStatsLocked(mapUid(uid)); 533 if (u == null) { 534 continue; 535 } 536 final long[] cpuTimesMs = allUidCpuFreqTimesMs.valueAt(i); 537 if (cpuTimesMs == null) { 538 continue; 539 } 540 final long[] deltaTimesMs = mKernelSingleUidTimeReader.computeDelta( 541 uid, cpuTimesMs.clone()); 542 if (onBattery && deltaTimesMs != null) { 543 final int procState; 544 final int idx = mPendingUids.indexOfKey(uid); 545 if (idx >= 0) { 546 procState = mPendingUids.valueAt(idx); 547 mPendingUids.removeAt(idx); 548 } else { 549 procState = u.mProcessState; 550 } 551 if (procState >= 0 && procState < Uid.NUM_PROCESS_STATE) { 552 u.addProcStateTimesMs(procState, deltaTimesMs, onBattery); 553 u.addProcStateScreenOffTimesMs(procState, deltaTimesMs, onBatteryScreenOff); 554 } 555 } 556 } 557 } 558 } 559 560 @VisibleForTesting addCpuTimes(long[] timesA, long[] timesB)561 public long[] addCpuTimes(long[] timesA, long[] timesB) { 562 if (timesA != null && timesB != null) { 563 for (int i = timesA.length - 1; i >= 0; --i) { 564 timesA[i] += timesB[i]; 565 } 566 return timesA; 567 } 568 return timesA == null ? (timesB == null ? null : timesB) : timesA; 569 } 570 571 @GuardedBy("this") initKernelSingleUidTimeReaderLocked()572 private boolean initKernelSingleUidTimeReaderLocked() { 573 if (mKernelSingleUidTimeReader == null) { 574 if (mPowerProfile == null) { 575 return false; 576 } 577 if (mCpuFreqs == null) { 578 mCpuFreqs = mCpuUidFreqTimeReader.readFreqs(mPowerProfile); 579 } 580 if (mCpuFreqs != null) { 581 mKernelSingleUidTimeReader = new KernelSingleUidTimeReader(mCpuFreqs.length); 582 } else { 583 mPerProcStateCpuTimesAvailable = mCpuUidFreqTimeReader.allUidTimesAvailable(); 584 return false; 585 } 586 } 587 mPerProcStateCpuTimesAvailable = mCpuUidFreqTimeReader.allUidTimesAvailable() 588 && mKernelSingleUidTimeReader.singleUidCpuTimesAvailable(); 589 return true; 590 } 591 592 public interface Clocks { elapsedRealtime()593 public long elapsedRealtime(); uptimeMillis()594 public long uptimeMillis(); 595 } 596 597 public static class SystemClocks implements Clocks { elapsedRealtime()598 public long elapsedRealtime() { 599 return SystemClock.elapsedRealtime(); 600 } 601 uptimeMillis()602 public long uptimeMillis() { 603 return SystemClock.uptimeMillis(); 604 } 605 } 606 607 public interface ExternalStatsSync { 608 int UPDATE_CPU = 0x01; 609 int UPDATE_WIFI = 0x02; 610 int UPDATE_RADIO = 0x04; 611 int UPDATE_BT = 0x08; 612 int UPDATE_RPM = 0x10; // 16 613 int UPDATE_ALL = UPDATE_CPU | UPDATE_WIFI | UPDATE_RADIO | UPDATE_BT | UPDATE_RPM; 614 scheduleSync(String reason, int flags)615 Future<?> scheduleSync(String reason, int flags); scheduleCpuSyncDueToRemovedUid(int uid)616 Future<?> scheduleCpuSyncDueToRemovedUid(int uid); scheduleReadProcStateCpuTimes(boolean onBattery, boolean onBatteryScreenOff, long delayMillis)617 Future<?> scheduleReadProcStateCpuTimes(boolean onBattery, boolean onBatteryScreenOff, 618 long delayMillis); scheduleCopyFromAllUidsCpuTimes(boolean onBattery, boolean onBatteryScreenOff)619 Future<?> scheduleCopyFromAllUidsCpuTimes(boolean onBattery, boolean onBatteryScreenOff); scheduleCpuSyncDueToSettingChange()620 Future<?> scheduleCpuSyncDueToSettingChange(); scheduleCpuSyncDueToScreenStateChange(boolean onBattery, boolean onBatteryScreenOff)621 Future<?> scheduleCpuSyncDueToScreenStateChange(boolean onBattery, 622 boolean onBatteryScreenOff); scheduleCpuSyncDueToWakelockChange(long delayMillis)623 Future<?> scheduleCpuSyncDueToWakelockChange(long delayMillis); cancelCpuSyncDueToWakelockChange()624 void cancelCpuSyncDueToWakelockChange(); scheduleSyncDueToBatteryLevelChange(long delayMillis)625 Future<?> scheduleSyncDueToBatteryLevelChange(long delayMillis); 626 } 627 628 public Handler mHandler; 629 private ExternalStatsSync mExternalSync = null; 630 @VisibleForTesting 631 protected UserInfoProvider mUserInfoProvider = null; 632 633 private BatteryCallback mCallback; 634 635 /** 636 * Mapping isolated uids to the actual owning app uid. 637 */ 638 final SparseIntArray mIsolatedUids = new SparseIntArray(); 639 640 /** 641 * The statistics we have collected organized by uids. 642 */ 643 final SparseArray<BatteryStatsImpl.Uid> mUidStats = new SparseArray<>(); 644 645 // A set of pools of currently active timers. When a timer is queried, we will divide the 646 // elapsed time by the number of active timers to arrive at that timer's share of the time. 647 // In order to do this, we must refresh each timer whenever the number of active timers 648 // changes. 649 @VisibleForTesting 650 @UnsupportedAppUsage 651 protected ArrayList<StopwatchTimer> mPartialTimers = new ArrayList<>(); 652 @UnsupportedAppUsage 653 final ArrayList<StopwatchTimer> mFullTimers = new ArrayList<>(); 654 @UnsupportedAppUsage 655 final ArrayList<StopwatchTimer> mWindowTimers = new ArrayList<>(); 656 final ArrayList<StopwatchTimer> mDrawTimers = new ArrayList<>(); 657 final SparseArray<ArrayList<StopwatchTimer>> mSensorTimers = new SparseArray<>(); 658 final ArrayList<StopwatchTimer> mWifiRunningTimers = new ArrayList<>(); 659 final ArrayList<StopwatchTimer> mFullWifiLockTimers = new ArrayList<>(); 660 final ArrayList<StopwatchTimer> mWifiMulticastTimers = new ArrayList<>(); 661 final ArrayList<StopwatchTimer> mWifiScanTimers = new ArrayList<>(); 662 final SparseArray<ArrayList<StopwatchTimer>> mWifiBatchedScanTimers = new SparseArray<>(); 663 final ArrayList<StopwatchTimer> mAudioTurnedOnTimers = new ArrayList<>(); 664 final ArrayList<StopwatchTimer> mVideoTurnedOnTimers = new ArrayList<>(); 665 final ArrayList<StopwatchTimer> mFlashlightTurnedOnTimers = new ArrayList<>(); 666 final ArrayList<StopwatchTimer> mCameraTurnedOnTimers = new ArrayList<>(); 667 final ArrayList<StopwatchTimer> mBluetoothScanOnTimers = new ArrayList<>(); 668 669 // Last partial timers we use for distributing CPU usage. 670 @VisibleForTesting 671 protected ArrayList<StopwatchTimer> mLastPartialTimers = new ArrayList<>(); 672 673 // These are the objects that will want to do something when the device 674 // is unplugged from power. 675 protected final TimeBase mOnBatteryTimeBase = new TimeBase(true); 676 677 // These are the objects that will want to do something when the device 678 // is unplugged from power *and* the screen is off or doze. 679 protected final TimeBase mOnBatteryScreenOffTimeBase = new TimeBase(true); 680 681 // Set to true when we want to distribute CPU across wakelocks for the next 682 // CPU update, even if we aren't currently running wake locks. 683 boolean mDistributeWakelockCpu; 684 685 boolean mShuttingDown; 686 687 final HistoryEventTracker mActiveEvents = new HistoryEventTracker(); 688 689 long mHistoryBaseTime; 690 protected boolean mHaveBatteryLevel = false; 691 protected boolean mRecordingHistory = false; 692 int mNumHistoryItems; 693 694 final Parcel mHistoryBuffer = Parcel.obtain(); 695 final HistoryItem mHistoryLastWritten = new HistoryItem(); 696 final HistoryItem mHistoryLastLastWritten = new HistoryItem(); 697 final HistoryItem mHistoryReadTmp = new HistoryItem(); 698 final HistoryItem mHistoryAddTmp = new HistoryItem(); 699 final HashMap<HistoryTag, Integer> mHistoryTagPool = new HashMap<>(); 700 String[] mReadHistoryStrings; 701 int[] mReadHistoryUids; 702 int mReadHistoryChars; 703 int mNextHistoryTagIdx = 0; 704 int mNumHistoryTagChars = 0; 705 int mHistoryBufferLastPos = -1; 706 int mActiveHistoryStates = 0xffffffff; 707 int mActiveHistoryStates2 = 0xffffffff; 708 long mLastHistoryElapsedRealtime = 0; 709 long mTrackRunningHistoryElapsedRealtime = 0; 710 long mTrackRunningHistoryUptime = 0; 711 712 final BatteryStatsHistory mBatteryStatsHistory; 713 714 final HistoryItem mHistoryCur = new HistoryItem(); 715 716 HistoryItem mHistory; 717 HistoryItem mHistoryEnd; 718 HistoryItem mHistoryLastEnd; 719 HistoryItem mHistoryCache; 720 721 // Used by computeHistoryStepDetails 722 HistoryStepDetails mLastHistoryStepDetails = null; 723 byte mLastHistoryStepLevel = 0; 724 final HistoryStepDetails mCurHistoryStepDetails = new HistoryStepDetails(); 725 final HistoryStepDetails mReadHistoryStepDetails = new HistoryStepDetails(); 726 final HistoryStepDetails mTmpHistoryStepDetails = new HistoryStepDetails(); 727 728 /** 729 * Total time (in milliseconds) spent executing in user code. 730 */ 731 long mLastStepCpuUserTime; 732 long mCurStepCpuUserTime; 733 /** 734 * Total time (in milliseconds) spent executing in kernel code. 735 */ 736 long mLastStepCpuSystemTime; 737 long mCurStepCpuSystemTime; 738 /** 739 * Times from /proc/stat (but measured in milliseconds). 740 */ 741 long mLastStepStatUserTime; 742 long mLastStepStatSystemTime; 743 long mLastStepStatIOWaitTime; 744 long mLastStepStatIrqTime; 745 long mLastStepStatSoftIrqTime; 746 long mLastStepStatIdleTime; 747 long mCurStepStatUserTime; 748 long mCurStepStatSystemTime; 749 long mCurStepStatIOWaitTime; 750 long mCurStepStatIrqTime; 751 long mCurStepStatSoftIrqTime; 752 long mCurStepStatIdleTime; 753 754 private HistoryItem mHistoryIterator; 755 private boolean mReadOverflow; 756 private boolean mIteratingHistory; 757 758 int mStartCount; 759 760 long mStartClockTime; 761 String mStartPlatformVersion; 762 String mEndPlatformVersion; 763 764 long mUptime; 765 long mUptimeStart; 766 long mRealtime; 767 long mRealtimeStart; 768 769 int mWakeLockNesting; 770 boolean mWakeLockImportant; 771 public boolean mRecordAllHistory; 772 boolean mNoAutoReset; 773 774 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) 775 protected int mScreenState = Display.STATE_UNKNOWN; 776 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) 777 protected StopwatchTimer mScreenOnTimer; 778 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) 779 protected StopwatchTimer mScreenDozeTimer; 780 781 int mScreenBrightnessBin = -1; 782 final StopwatchTimer[] mScreenBrightnessTimer = new StopwatchTimer[NUM_SCREEN_BRIGHTNESS_BINS]; 783 784 boolean mPretendScreenOff; 785 786 boolean mInteractive; 787 StopwatchTimer mInteractiveTimer; 788 789 boolean mPowerSaveModeEnabled; 790 StopwatchTimer mPowerSaveModeEnabledTimer; 791 792 boolean mDeviceIdling; 793 StopwatchTimer mDeviceIdlingTimer; 794 795 boolean mDeviceLightIdling; 796 StopwatchTimer mDeviceLightIdlingTimer; 797 798 int mDeviceIdleMode; 799 long mLastIdleTimeStart; 800 long mLongestLightIdleTime; 801 long mLongestFullIdleTime; 802 StopwatchTimer mDeviceIdleModeLightTimer; 803 StopwatchTimer mDeviceIdleModeFullTimer; 804 805 boolean mPhoneOn; 806 StopwatchTimer mPhoneOnTimer; 807 808 int mAudioOnNesting; 809 StopwatchTimer mAudioOnTimer; 810 811 int mVideoOnNesting; 812 StopwatchTimer mVideoOnTimer; 813 814 int mFlashlightOnNesting; 815 StopwatchTimer mFlashlightOnTimer; 816 817 int mCameraOnNesting; 818 StopwatchTimer mCameraOnTimer; 819 820 private static final int USB_DATA_UNKNOWN = 0; 821 private static final int USB_DATA_DISCONNECTED = 1; 822 private static final int USB_DATA_CONNECTED = 2; 823 int mUsbDataState = USB_DATA_UNKNOWN; 824 825 int mGpsSignalQualityBin = -1; 826 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) 827 protected final StopwatchTimer[] mGpsSignalQualityTimer = 828 new StopwatchTimer[GnssMetrics.NUM_GPS_SIGNAL_QUALITY_LEVELS]; 829 830 int mPhoneSignalStrengthBin = -1; 831 int mPhoneSignalStrengthBinRaw = -1; 832 final StopwatchTimer[] mPhoneSignalStrengthsTimer = 833 new StopwatchTimer[SignalStrength.NUM_SIGNAL_STRENGTH_BINS]; 834 835 StopwatchTimer mPhoneSignalScanningTimer; 836 837 int mPhoneDataConnectionType = -1; 838 final StopwatchTimer[] mPhoneDataConnectionsTimer = 839 new StopwatchTimer[NUM_DATA_CONNECTION_TYPES]; 840 841 final LongSamplingCounter[] mNetworkByteActivityCounters = 842 new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES]; 843 final LongSamplingCounter[] mNetworkPacketActivityCounters = 844 new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES]; 845 846 /** 847 * The WiFi Overall wakelock timer 848 * This timer tracks the actual aggregate time for which MC wakelocks are enabled 849 * since addition of per UID timers would not result in an accurate value due to overlapp of 850 * per uid wakelock timers 851 */ 852 StopwatchTimer mWifiMulticastWakelockTimer; 853 854 /** 855 * The WiFi controller activity (time in tx, rx, idle, and power consumed) for the device. 856 */ 857 ControllerActivityCounterImpl mWifiActivity; 858 859 /** 860 * The Bluetooth controller activity (time in tx, rx, idle, and power consumed) for the device. 861 */ 862 ControllerActivityCounterImpl mBluetoothActivity; 863 864 /** 865 * The Modem controller activity (time in tx, rx, idle, and power consumed) for the device. 866 */ 867 ControllerActivityCounterImpl mModemActivity; 868 869 /** 870 * Whether the device supports WiFi controller energy reporting. This is set to true on 871 * the first WiFi energy report. See {@link #mWifiActivity}. 872 */ 873 boolean mHasWifiReporting = false; 874 875 /** 876 * Whether the device supports Bluetooth controller energy reporting. This is set to true on 877 * the first Bluetooth energy report. See {@link #mBluetoothActivity}. 878 */ 879 boolean mHasBluetoothReporting = false; 880 881 /** 882 * Whether the device supports Modem controller energy reporting. This is set to true on 883 * the first Modem energy report. See {@link #mModemActivity}. 884 */ 885 boolean mHasModemReporting = false; 886 887 boolean mWifiOn; 888 StopwatchTimer mWifiOnTimer; 889 890 boolean mGlobalWifiRunning; 891 StopwatchTimer mGlobalWifiRunningTimer; 892 893 int mWifiState = -1; 894 final StopwatchTimer[] mWifiStateTimer = new StopwatchTimer[NUM_WIFI_STATES]; 895 896 int mWifiSupplState = -1; 897 final StopwatchTimer[] mWifiSupplStateTimer = new StopwatchTimer[NUM_WIFI_SUPPL_STATES]; 898 899 int mWifiSignalStrengthBin = -1; 900 final StopwatchTimer[] mWifiSignalStrengthsTimer = 901 new StopwatchTimer[NUM_WIFI_SIGNAL_STRENGTH_BINS]; 902 903 StopwatchTimer mWifiActiveTimer; 904 905 int mBluetoothScanNesting; 906 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) 907 protected StopwatchTimer mBluetoothScanTimer; 908 909 boolean mIsCellularTxPowerHigh = false; 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[] mCpuFreqs; 1000 1001 @VisibleForTesting 1002 protected PowerProfile mPowerProfile; 1003 1004 @GuardedBy("this") 1005 final Constants mConstants; 1006 1007 /* 1008 * Holds a SamplingTimer associated with each Resource Power Manager state and voter, 1009 * recording their times when on-battery (regardless of screen state). 1010 */ 1011 private final HashMap<String, SamplingTimer> mRpmStats = new HashMap<>(); 1012 /** Times for each Resource Power Manager state and voter when screen-off and on-battery. */ 1013 private final HashMap<String, SamplingTimer> mScreenOffRpmStats = new HashMap<>(); 1014 1015 @Override getRpmStats()1016 public Map<String, ? extends Timer> getRpmStats() { 1017 return mRpmStats; 1018 } 1019 1020 // TODO: Note: screenOffRpmStats has been disabled via SCREEN_OFF_RPM_STATS_ENABLED. 1021 @Override getScreenOffRpmStats()1022 public Map<String, ? extends Timer> getScreenOffRpmStats() { 1023 return mScreenOffRpmStats; 1024 } 1025 1026 /* 1027 * Holds a SamplingTimer associated with each kernel wakelock name being tracked. 1028 */ 1029 private final HashMap<String, SamplingTimer> mKernelWakelockStats = new HashMap<>(); 1030 1031 @UnsupportedAppUsage getKernelWakelockStats()1032 public Map<String, ? extends Timer> getKernelWakelockStats() { 1033 return mKernelWakelockStats; 1034 } 1035 1036 String mLastWakeupReason = null; 1037 long mLastWakeupUptimeMs = 0; 1038 private final HashMap<String, SamplingTimer> mWakeupReasonStats = new HashMap<>(); 1039 getWakeupReasonStats()1040 public Map<String, ? extends Timer> getWakeupReasonStats() { 1041 return mWakeupReasonStats; 1042 } 1043 1044 @Override getUahDischarge(int which)1045 public long getUahDischarge(int which) { 1046 return mDischargeCounter.getCountLocked(which); 1047 } 1048 1049 @Override getUahDischargeScreenOff(int which)1050 public long getUahDischargeScreenOff(int which) { 1051 return mDischargeScreenOffCounter.getCountLocked(which); 1052 } 1053 1054 @Override getUahDischargeScreenDoze(int which)1055 public long getUahDischargeScreenDoze(int which) { 1056 return mDischargeScreenDozeCounter.getCountLocked(which); 1057 } 1058 1059 @Override getUahDischargeLightDoze(int which)1060 public long getUahDischargeLightDoze(int which) { 1061 return mDischargeLightDozeCounter.getCountLocked(which); 1062 } 1063 1064 @Override getUahDischargeDeepDoze(int which)1065 public long getUahDischargeDeepDoze(int which) { 1066 return mDischargeDeepDozeCounter.getCountLocked(which); 1067 } 1068 1069 @Override getEstimatedBatteryCapacity()1070 public int getEstimatedBatteryCapacity() { 1071 return mEstimatedBatteryCapacity; 1072 } 1073 1074 @Override getMinLearnedBatteryCapacity()1075 public int getMinLearnedBatteryCapacity() { 1076 return mMinLearnedBatteryCapacity; 1077 } 1078 1079 @Override getMaxLearnedBatteryCapacity()1080 public int getMaxLearnedBatteryCapacity() { 1081 return mMaxLearnedBatteryCapacity; 1082 } 1083 BatteryStatsImpl()1084 public BatteryStatsImpl() { 1085 this(new SystemClocks()); 1086 } 1087 BatteryStatsImpl(Clocks clocks)1088 public BatteryStatsImpl(Clocks clocks) { 1089 init(clocks); 1090 mStatsFile = null; 1091 mCheckinFile = null; 1092 mDailyFile = null; 1093 mBatteryStatsHistory = null; 1094 mHandler = null; 1095 mPlatformIdleStateCallback = null; 1096 mRailEnergyDataCallback = null; 1097 mUserInfoProvider = null; 1098 mConstants = new Constants(mHandler); 1099 clearHistoryLocked(); 1100 } 1101 init(Clocks clocks)1102 private void init(Clocks clocks) { 1103 mClocks = clocks; 1104 } 1105 1106 /** 1107 * TimeBase observer. 1108 */ 1109 public interface TimeBaseObs { onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime)1110 void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime); onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime)1111 void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime); 1112 1113 /** 1114 * Reset the observer's state, returns true if the timer/counter is inactive 1115 * so it can be destroyed. 1116 * @param detachIfReset detach if true, no-op if false. 1117 * @return Returns true if the timer/counter is inactive and can be destroyed. 1118 */ reset(boolean detachIfReset)1119 boolean reset(boolean detachIfReset); 1120 /** 1121 * Detach the observer from TimeBase. 1122 */ detach()1123 void detach(); 1124 } 1125 1126 // methods are protected not private to be VisibleForTesting 1127 public static class TimeBase { 1128 protected final Collection<TimeBaseObs> mObservers; 1129 protected long mUptime; 1130 protected long mRealtime; 1131 1132 protected boolean mRunning; 1133 1134 protected long mPastUptime; 1135 protected long mUptimeStart; 1136 protected long mPastRealtime; 1137 protected long mRealtimeStart; 1138 protected long mUnpluggedUptime; 1139 protected long mUnpluggedRealtime; 1140 dump(PrintWriter pw, String prefix)1141 public void dump(PrintWriter pw, String prefix) { 1142 StringBuilder sb = new StringBuilder(128); 1143 pw.print(prefix); pw.print("mRunning="); pw.println(mRunning); 1144 sb.setLength(0); 1145 sb.append(prefix); 1146 sb.append("mUptime="); 1147 formatTimeMs(sb, mUptime / 1000); 1148 pw.println(sb.toString()); 1149 sb.setLength(0); 1150 sb.append(prefix); 1151 sb.append("mRealtime="); 1152 formatTimeMs(sb, mRealtime / 1000); 1153 pw.println(sb.toString()); 1154 sb.setLength(0); 1155 sb.append(prefix); 1156 sb.append("mPastUptime="); 1157 formatTimeMs(sb, mPastUptime / 1000); sb.append("mUptimeStart="); 1158 formatTimeMs(sb, mUptimeStart / 1000); 1159 sb.append("mUnpluggedUptime="); formatTimeMs(sb, mUnpluggedUptime / 1000); 1160 pw.println(sb.toString()); 1161 sb.setLength(0); 1162 sb.append(prefix); 1163 sb.append("mPastRealtime="); 1164 formatTimeMs(sb, mPastRealtime / 1000); sb.append("mRealtimeStart="); 1165 formatTimeMs(sb, mRealtimeStart / 1000); 1166 sb.append("mUnpluggedRealtime="); formatTimeMs(sb, mUnpluggedRealtime / 1000); 1167 pw.println(sb.toString()); 1168 } 1169 /** 1170 * The mObservers of TimeBase in BatteryStatsImpl object can contain up to 20k entries. 1171 * The mObservers of TimeBase in BatteryStatsImpl.Uid object only contains a few or tens of 1172 * entries. 1173 * mObservers must have good performance on add(), remove(), also be memory efficient. 1174 * This is why we provide isLongList parameter for long and short list user cases. 1175 * @param isLongList If true, use HashSet for mObservers list. 1176 * If false, use ArrayList for mObservers list. 1177 */ TimeBase(boolean isLongList)1178 public TimeBase(boolean isLongList) { 1179 mObservers = isLongList ? new HashSet<>() : new ArrayList<>(); 1180 } 1181 TimeBase()1182 public TimeBase() { 1183 this(false); 1184 } 1185 add(TimeBaseObs observer)1186 public void add(TimeBaseObs observer) { 1187 mObservers.add(observer); 1188 } 1189 remove(TimeBaseObs observer)1190 public void remove(TimeBaseObs observer) { 1191 mObservers.remove(observer); 1192 } 1193 hasObserver(TimeBaseObs observer)1194 public boolean hasObserver(TimeBaseObs observer) { 1195 return mObservers.contains(observer); 1196 } 1197 init(long uptime, long realtime)1198 public void init(long uptime, long realtime) { 1199 mRealtime = 0; 1200 mUptime = 0; 1201 mPastUptime = 0; 1202 mPastRealtime = 0; 1203 mUptimeStart = uptime; 1204 mRealtimeStart = realtime; 1205 mUnpluggedUptime = getUptime(mUptimeStart); 1206 mUnpluggedRealtime = getRealtime(mRealtimeStart); 1207 } 1208 reset(long uptime, long realtime)1209 public void reset(long uptime, long realtime) { 1210 if (!mRunning) { 1211 mPastUptime = 0; 1212 mPastRealtime = 0; 1213 } else { 1214 mUptimeStart = uptime; 1215 mRealtimeStart = realtime; 1216 // TODO: Since mUptimeStart was just reset and we are running, getUptime will 1217 // just return mPastUptime. Also, are we sure we don't want to reset that? 1218 mUnpluggedUptime = getUptime(uptime); 1219 // TODO: likewise. 1220 mUnpluggedRealtime = getRealtime(realtime); 1221 } 1222 } 1223 computeUptime(long curTime, int which)1224 public long computeUptime(long curTime, int which) { 1225 return mUptime + getUptime(curTime); 1226 } 1227 computeRealtime(long curTime, int which)1228 public long computeRealtime(long curTime, int which) { 1229 return mRealtime + getRealtime(curTime); 1230 } 1231 getUptime(long curTime)1232 public long getUptime(long curTime) { 1233 long time = mPastUptime; 1234 if (mRunning) { 1235 time += curTime - mUptimeStart; 1236 } 1237 return time; 1238 } 1239 getRealtime(long curTime)1240 public long getRealtime(long curTime) { 1241 long time = mPastRealtime; 1242 if (mRunning) { 1243 time += curTime - mRealtimeStart; 1244 } 1245 return time; 1246 } 1247 getUptimeStart()1248 public long getUptimeStart() { 1249 return mUptimeStart; 1250 } 1251 getRealtimeStart()1252 public long getRealtimeStart() { 1253 return mRealtimeStart; 1254 } 1255 isRunning()1256 public boolean isRunning() { 1257 return mRunning; 1258 } 1259 setRunning(boolean running, long uptime, long realtime)1260 public boolean setRunning(boolean running, long uptime, long realtime) { 1261 if (mRunning != running) { 1262 mRunning = running; 1263 if (running) { 1264 mUptimeStart = uptime; 1265 mRealtimeStart = realtime; 1266 long batteryUptime = mUnpluggedUptime = getUptime(uptime); 1267 long batteryRealtime = mUnpluggedRealtime = getRealtime(realtime); 1268 // Normally we do not use Iterator in framework code to avoid alloc/dealloc 1269 // Iterator object, here is an exception because mObservers' type is Collection 1270 // instead of list. 1271 final Iterator<TimeBaseObs> iter = mObservers.iterator(); 1272 while (iter.hasNext()) { 1273 iter.next().onTimeStarted(realtime, batteryUptime, batteryRealtime); 1274 } 1275 } else { 1276 mPastUptime += uptime - mUptimeStart; 1277 mPastRealtime += realtime - mRealtimeStart; 1278 long batteryUptime = getUptime(uptime); 1279 long batteryRealtime = getRealtime(realtime); 1280 // Normally we do not use Iterator in framework code to avoid alloc/dealloc 1281 // Iterator object, here is an exception because mObservers' type is Collection 1282 // instead of list. 1283 final Iterator<TimeBaseObs> iter = mObservers.iterator(); 1284 while (iter.hasNext()) { 1285 iter.next().onTimeStopped(realtime, batteryUptime, batteryRealtime); 1286 } 1287 } 1288 return true; 1289 } 1290 return false; 1291 } 1292 readSummaryFromParcel(Parcel in)1293 public void readSummaryFromParcel(Parcel in) { 1294 mUptime = in.readLong(); 1295 mRealtime = in.readLong(); 1296 } 1297 writeSummaryToParcel(Parcel out, long uptime, long realtime)1298 public void writeSummaryToParcel(Parcel out, long uptime, long realtime) { 1299 out.writeLong(computeUptime(uptime, STATS_SINCE_CHARGED)); 1300 out.writeLong(computeRealtime(realtime, STATS_SINCE_CHARGED)); 1301 } 1302 readFromParcel(Parcel in)1303 public void readFromParcel(Parcel in) { 1304 mRunning = false; 1305 mUptime = in.readLong(); 1306 mPastUptime = in.readLong(); 1307 mUptimeStart = in.readLong(); 1308 mRealtime = in.readLong(); 1309 mPastRealtime = in.readLong(); 1310 mRealtimeStart = in.readLong(); 1311 mUnpluggedUptime = in.readLong(); 1312 mUnpluggedRealtime = in.readLong(); 1313 } 1314 writeToParcel(Parcel out, long uptime, long realtime)1315 public void writeToParcel(Parcel out, long uptime, long realtime) { 1316 final long runningUptime = getUptime(uptime); 1317 final long runningRealtime = getRealtime(realtime); 1318 out.writeLong(mUptime); 1319 out.writeLong(runningUptime); 1320 out.writeLong(mUptimeStart); 1321 out.writeLong(mRealtime); 1322 out.writeLong(runningRealtime); 1323 out.writeLong(mRealtimeStart); 1324 out.writeLong(mUnpluggedUptime); 1325 out.writeLong(mUnpluggedRealtime); 1326 } 1327 } 1328 1329 /** 1330 * State for keeping track of counting information. 1331 */ 1332 public static class Counter extends BatteryStats.Counter implements TimeBaseObs { 1333 @UnsupportedAppUsage 1334 final AtomicInteger mCount = new AtomicInteger(); 1335 final TimeBase mTimeBase; 1336 Counter(TimeBase timeBase, Parcel in)1337 public Counter(TimeBase timeBase, Parcel in) { 1338 mTimeBase = timeBase; 1339 mCount.set(in.readInt()); 1340 timeBase.add(this); 1341 } 1342 Counter(TimeBase timeBase)1343 public Counter(TimeBase timeBase) { 1344 mTimeBase = timeBase; 1345 timeBase.add(this); 1346 } 1347 writeToParcel(Parcel out)1348 public void writeToParcel(Parcel out) { 1349 out.writeInt(mCount.get()); 1350 } 1351 1352 @Override onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime)1353 public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) { 1354 } 1355 1356 @Override onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime)1357 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) { 1358 } 1359 1360 /** 1361 * Writes a possibly null Counter to a Parcel. 1362 * 1363 * @param out the Parcel to be written to. 1364 * @param counter a Counter, or null. 1365 */ writeCounterToParcel(Parcel out, @Nullable Counter counter)1366 public static void writeCounterToParcel(Parcel out, @Nullable Counter counter) { 1367 if (counter == null) { 1368 out.writeInt(0); // indicates null 1369 return; 1370 } 1371 out.writeInt(1); // indicates non-null 1372 1373 counter.writeToParcel(out); 1374 } 1375 1376 /** 1377 * Reads a Counter that was written using {@link #writeCounterToParcel(Parcel, Counter)}. 1378 * @param timeBase the timebase to assign to the Counter 1379 * @param in the parcel to read from 1380 * @return the Counter or null. 1381 */ readCounterFromParcel(TimeBase timeBase, Parcel in)1382 public static @Nullable Counter readCounterFromParcel(TimeBase timeBase, Parcel in) { 1383 if (in.readInt() == 0) { 1384 return null; 1385 } 1386 return new Counter(timeBase, in); 1387 } 1388 1389 @Override getCountLocked(int which)1390 public int getCountLocked(int which) { 1391 return mCount.get(); 1392 } 1393 logState(Printer pw, String prefix)1394 public void logState(Printer pw, String prefix) { 1395 pw.println(prefix + "mCount=" + mCount.get()); 1396 } 1397 1398 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) stepAtomic()1399 public void stepAtomic() { 1400 if (mTimeBase.isRunning()) { 1401 mCount.incrementAndGet(); 1402 } 1403 } 1404 addAtomic(int delta)1405 void addAtomic(int delta) { 1406 if (mTimeBase.isRunning()) { 1407 mCount.addAndGet(delta); 1408 } 1409 } 1410 1411 /** 1412 * Clear state of this counter. 1413 */ 1414 @Override reset(boolean detachIfReset)1415 public boolean reset(boolean detachIfReset) { 1416 mCount.set(0); 1417 if (detachIfReset) { 1418 detach(); 1419 } 1420 return true; 1421 } 1422 1423 @Override detach()1424 public void detach() { 1425 mTimeBase.remove(this); 1426 } 1427 1428 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) writeSummaryFromParcelLocked(Parcel out)1429 public void writeSummaryFromParcelLocked(Parcel out) { 1430 out.writeInt(mCount.get()); 1431 } 1432 1433 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) readSummaryFromParcelLocked(Parcel in)1434 public void readSummaryFromParcelLocked(Parcel in) { 1435 mCount.set(in.readInt()); 1436 } 1437 } 1438 1439 @VisibleForTesting 1440 public static class LongSamplingCounterArray extends LongCounterArray implements TimeBaseObs { 1441 final TimeBase mTimeBase; 1442 public long[] mCounts; 1443 LongSamplingCounterArray(TimeBase timeBase, Parcel in)1444 private LongSamplingCounterArray(TimeBase timeBase, Parcel in) { 1445 mTimeBase = timeBase; 1446 mCounts = in.createLongArray(); 1447 timeBase.add(this); 1448 } 1449 LongSamplingCounterArray(TimeBase timeBase)1450 public LongSamplingCounterArray(TimeBase timeBase) { 1451 mTimeBase = timeBase; 1452 timeBase.add(this); 1453 } 1454 writeToParcel(Parcel out)1455 private void writeToParcel(Parcel out) { 1456 out.writeLongArray(mCounts); 1457 } 1458 1459 @Override onTimeStarted(long elapsedRealTime, long baseUptime, long baseRealtime)1460 public void onTimeStarted(long elapsedRealTime, long baseUptime, long baseRealtime) { 1461 } 1462 1463 @Override onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime)1464 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) { 1465 } 1466 1467 @Override getCountsLocked(int which)1468 public long[] getCountsLocked(int which) { 1469 return mCounts == null ? null : Arrays.copyOf(mCounts, mCounts.length); 1470 } 1471 1472 @Override logState(Printer pw, String prefix)1473 public void logState(Printer pw, String prefix) { 1474 pw.println(prefix + "mCounts=" + Arrays.toString(mCounts)); 1475 } 1476 addCountLocked(long[] counts)1477 public void addCountLocked(long[] counts) { 1478 addCountLocked(counts, mTimeBase.isRunning()); 1479 } 1480 addCountLocked(long[] counts, boolean isRunning)1481 public void addCountLocked(long[] counts, boolean isRunning) { 1482 if (counts == null) { 1483 return; 1484 } 1485 if (isRunning) { 1486 if (mCounts == null) { 1487 mCounts = new long[counts.length]; 1488 } 1489 for (int i = 0; i < counts.length; ++i) { 1490 mCounts[i] += counts[i]; 1491 } 1492 } 1493 } 1494 getSize()1495 public int getSize() { 1496 return mCounts == null ? 0 : mCounts.length; 1497 } 1498 1499 /** 1500 * Clear state of this counter. 1501 */ 1502 @Override reset(boolean detachIfReset)1503 public boolean reset(boolean detachIfReset) { 1504 if (mCounts != null) { 1505 Arrays.fill(mCounts, 0); 1506 } 1507 if (detachIfReset) { 1508 detach(); 1509 } 1510 return true; 1511 } 1512 1513 @Override detach()1514 public void detach() { 1515 mTimeBase.remove(this); 1516 } 1517 writeSummaryToParcelLocked(Parcel out)1518 private void writeSummaryToParcelLocked(Parcel out) { 1519 out.writeLongArray(mCounts); 1520 } 1521 readSummaryFromParcelLocked(Parcel in)1522 private void readSummaryFromParcelLocked(Parcel in) { 1523 mCounts = in.createLongArray(); 1524 } 1525 writeToParcel(Parcel out, LongSamplingCounterArray counterArray)1526 public static void writeToParcel(Parcel out, LongSamplingCounterArray counterArray) { 1527 if (counterArray != null) { 1528 out.writeInt(1); 1529 counterArray.writeToParcel(out); 1530 } else { 1531 out.writeInt(0); 1532 } 1533 } 1534 readFromParcel(Parcel in, TimeBase timeBase)1535 public static LongSamplingCounterArray readFromParcel(Parcel in, TimeBase timeBase) { 1536 if (in.readInt() != 0) { 1537 return new LongSamplingCounterArray(timeBase, in); 1538 } else { 1539 return null; 1540 } 1541 } 1542 writeSummaryToParcelLocked(Parcel out, LongSamplingCounterArray counterArray)1543 public static void writeSummaryToParcelLocked(Parcel out, 1544 LongSamplingCounterArray counterArray) { 1545 if (counterArray != null) { 1546 out.writeInt(1); 1547 counterArray.writeSummaryToParcelLocked(out); 1548 } else { 1549 out.writeInt(0); 1550 } 1551 } 1552 readSummaryFromParcelLocked(Parcel in, TimeBase timeBase)1553 public static LongSamplingCounterArray readSummaryFromParcelLocked(Parcel in, 1554 TimeBase timeBase) { 1555 if (in.readInt() != 0) { 1556 final LongSamplingCounterArray counterArray 1557 = new LongSamplingCounterArray(timeBase); 1558 counterArray.readSummaryFromParcelLocked(in); 1559 return counterArray; 1560 } else { 1561 return null; 1562 } 1563 } 1564 } 1565 1566 @VisibleForTesting 1567 public static class LongSamplingCounter extends LongCounter implements TimeBaseObs { 1568 final TimeBase mTimeBase; 1569 private long mCount; 1570 LongSamplingCounter(TimeBase timeBase, Parcel in)1571 public LongSamplingCounter(TimeBase timeBase, Parcel in) { 1572 mTimeBase = timeBase; 1573 mCount = in.readLong(); 1574 timeBase.add(this); 1575 } 1576 LongSamplingCounter(TimeBase timeBase)1577 public LongSamplingCounter(TimeBase timeBase) { 1578 mTimeBase = timeBase; 1579 timeBase.add(this); 1580 } 1581 writeToParcel(Parcel out)1582 public void writeToParcel(Parcel out) { 1583 out.writeLong(mCount); 1584 } 1585 1586 @Override onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime)1587 public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) { 1588 } 1589 1590 @Override onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime)1591 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) { 1592 } 1593 getCountLocked(int which)1594 public long getCountLocked(int which) { 1595 return mCount; 1596 } 1597 1598 @Override logState(Printer pw, String prefix)1599 public void logState(Printer pw, String prefix) { 1600 pw.println(prefix + "mCount=" + mCount); 1601 } 1602 addCountLocked(long count)1603 public void addCountLocked(long count) { 1604 addCountLocked(count, mTimeBase.isRunning()); 1605 } 1606 addCountLocked(long count, boolean isRunning)1607 public void addCountLocked(long count, boolean isRunning) { 1608 if (isRunning) { 1609 mCount += count; 1610 } 1611 } 1612 1613 /** 1614 * Clear state of this counter. 1615 */ 1616 @Override reset(boolean detachIfReset)1617 public boolean reset(boolean detachIfReset) { 1618 mCount = 0; 1619 if (detachIfReset) { 1620 detach(); 1621 } 1622 return true; 1623 } 1624 1625 @Override detach()1626 public void detach() { 1627 mTimeBase.remove(this); 1628 } 1629 writeSummaryFromParcelLocked(Parcel out)1630 public void writeSummaryFromParcelLocked(Parcel out) { 1631 out.writeLong(mCount); 1632 } 1633 readSummaryFromParcelLocked(Parcel in)1634 public void readSummaryFromParcelLocked(Parcel in) { 1635 mCount = in.readLong(); 1636 } 1637 } 1638 1639 /** 1640 * State for keeping track of timing information. 1641 */ 1642 public static abstract class Timer extends BatteryStats.Timer implements TimeBaseObs { 1643 protected final Clocks mClocks; 1644 protected final int mType; 1645 protected final TimeBase mTimeBase; 1646 1647 protected int mCount; 1648 1649 // Times are in microseconds for better accuracy when dividing by the 1650 // lock count, and are in "battery realtime" units. 1651 1652 /** 1653 * The total time we have accumulated since the start of the original 1654 * boot, to the last time something interesting happened in the 1655 * current run. 1656 */ 1657 protected long mTotalTime; 1658 1659 /** 1660 * The total time this timer has been running until the latest mark has been set. 1661 * Subtract this from mTotalTime to get the time spent running since the mark was set. 1662 */ 1663 protected long mTimeBeforeMark; 1664 1665 /** 1666 * Constructs from a parcel. 1667 * @param type 1668 * @param timeBase 1669 * @param in 1670 */ Timer(Clocks clocks, int type, TimeBase timeBase, Parcel in)1671 public Timer(Clocks clocks, int type, TimeBase timeBase, Parcel in) { 1672 mClocks = clocks; 1673 mType = type; 1674 mTimeBase = timeBase; 1675 1676 mCount = in.readInt(); 1677 mTotalTime = in.readLong(); 1678 mTimeBeforeMark = in.readLong(); 1679 timeBase.add(this); 1680 if (DEBUG) Log.i(TAG, "**** READ TIMER #" + mType + ": mTotalTime=" + mTotalTime); 1681 } 1682 Timer(Clocks clocks, int type, TimeBase timeBase)1683 public Timer(Clocks clocks, int type, TimeBase timeBase) { 1684 mClocks = clocks; 1685 mType = type; 1686 mTimeBase = timeBase; 1687 timeBase.add(this); 1688 } 1689 writeToParcel(Parcel out, long elapsedRealtimeUs)1690 public void writeToParcel(Parcel out, long elapsedRealtimeUs) { 1691 if (DEBUG) { 1692 Log.i(TAG, "**** WRITING TIMER #" + mType + ": mTotalTime=" 1693 + computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs))); 1694 } 1695 out.writeInt(computeCurrentCountLocked()); 1696 out.writeLong(computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs))); 1697 out.writeLong(mTimeBeforeMark); 1698 } 1699 computeRunTimeLocked(long curBatteryRealtime)1700 protected abstract long computeRunTimeLocked(long curBatteryRealtime); 1701 computeCurrentCountLocked()1702 protected abstract int computeCurrentCountLocked(); 1703 1704 /** 1705 * Clear state of this timer. Returns true if the timer is inactive 1706 * so can be completely dropped. 1707 */ 1708 @Override reset(boolean detachIfReset)1709 public boolean reset(boolean detachIfReset) { 1710 mTotalTime = mTimeBeforeMark = 0; 1711 mCount = 0; 1712 if (detachIfReset) { 1713 detach(); 1714 } 1715 return true; 1716 } 1717 1718 @Override detach()1719 public void detach() { 1720 mTimeBase.remove(this); 1721 } 1722 1723 @Override onTimeStarted(long elapsedRealtime, long timeBaseUptime, long baseRealtime)1724 public void onTimeStarted(long elapsedRealtime, long timeBaseUptime, long baseRealtime) { 1725 } 1726 1727 @Override onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime)1728 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) { 1729 if (DEBUG && mType < 0) { 1730 Log.v(TAG, "plug #" + mType + ": realtime=" + baseRealtime 1731 + " old mTotalTime=" + mTotalTime); 1732 } 1733 mTotalTime = computeRunTimeLocked(baseRealtime); 1734 mCount = computeCurrentCountLocked(); 1735 if (DEBUG && mType < 0) { 1736 Log.v(TAG, "plug #" + mType + ": new mTotalTime=" + mTotalTime); 1737 } 1738 } 1739 1740 /** 1741 * Writes a possibly null Timer to a Parcel. 1742 * 1743 * @param out the Parcel to be written to. 1744 * @param timer a Timer, or null. 1745 */ 1746 @UnsupportedAppUsage writeTimerToParcel(Parcel out, Timer timer, long elapsedRealtimeUs)1747 public static void writeTimerToParcel(Parcel out, Timer timer, long elapsedRealtimeUs) { 1748 if (timer == null) { 1749 out.writeInt(0); // indicates null 1750 return; 1751 } 1752 out.writeInt(1); // indicates non-null 1753 timer.writeToParcel(out, elapsedRealtimeUs); 1754 } 1755 1756 @Override 1757 @UnsupportedAppUsage getTotalTimeLocked(long elapsedRealtimeUs, int which)1758 public long getTotalTimeLocked(long elapsedRealtimeUs, int which) { 1759 return computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs)); 1760 } 1761 1762 @Override 1763 @UnsupportedAppUsage getCountLocked(int which)1764 public int getCountLocked(int which) { 1765 return computeCurrentCountLocked(); 1766 } 1767 1768 @Override getTimeSinceMarkLocked(long elapsedRealtimeUs)1769 public long getTimeSinceMarkLocked(long elapsedRealtimeUs) { 1770 long val = computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs)); 1771 return val - mTimeBeforeMark; 1772 } 1773 1774 @Override logState(Printer pw, String prefix)1775 public void logState(Printer pw, String prefix) { 1776 pw.println(prefix + "mCount=" + mCount); 1777 pw.println(prefix + "mTotalTime=" + mTotalTime); 1778 } 1779 1780 writeSummaryFromParcelLocked(Parcel out, long elapsedRealtimeUs)1781 public void writeSummaryFromParcelLocked(Parcel out, long elapsedRealtimeUs) { 1782 long runTime = computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs)); 1783 out.writeLong(runTime); 1784 out.writeInt(computeCurrentCountLocked()); 1785 } 1786 readSummaryFromParcelLocked(Parcel in)1787 public void readSummaryFromParcelLocked(Parcel in) { 1788 // Multiply by 1000 for backwards compatibility 1789 mTotalTime = in.readLong(); 1790 mCount = in.readInt(); 1791 // When reading the summary, we set the mark to be the latest information. 1792 mTimeBeforeMark = mTotalTime; 1793 } 1794 } 1795 1796 /** 1797 * A counter meant to accept monotonically increasing values to its {@link #update(long, int)} 1798 * method. The state of the timer according to its {@link TimeBase} will determine how much 1799 * of the value is recorded. 1800 * 1801 * If the value being recorded resets, {@link #endSample()} can be called in order to 1802 * account for the change. If the value passed in to {@link #update(long, int)} decreased 1803 * between calls, the {@link #endSample()} is automatically called and the new value is 1804 * expected to increase monotonically from that point on. 1805 */ 1806 public static class SamplingTimer extends Timer { 1807 1808 /** 1809 * The most recent reported count from /proc/wakelocks. 1810 */ 1811 int mCurrentReportedCount; 1812 1813 /** 1814 * The reported count from /proc/wakelocks when unplug() was last 1815 * called. 1816 */ 1817 int mUnpluggedReportedCount; 1818 1819 /** 1820 * The most recent reported total_time from /proc/wakelocks. 1821 */ 1822 long mCurrentReportedTotalTime; 1823 1824 1825 /** 1826 * The reported total_time from /proc/wakelocks when unplug() was last 1827 * called. 1828 */ 1829 long mUnpluggedReportedTotalTime; 1830 1831 /** 1832 * Whether we are currently in a discharge cycle. 1833 */ 1834 boolean mTimeBaseRunning; 1835 1836 /** 1837 * Whether we are currently recording reported values. 1838 */ 1839 boolean mTrackingReportedValues; 1840 1841 /* 1842 * A sequence counter, incremented once for each update of the stats. 1843 */ 1844 int mUpdateVersion; 1845 1846 @VisibleForTesting SamplingTimer(Clocks clocks, TimeBase timeBase, Parcel in)1847 public SamplingTimer(Clocks clocks, TimeBase timeBase, Parcel in) { 1848 super(clocks, 0, timeBase, in); 1849 mCurrentReportedCount = in.readInt(); 1850 mUnpluggedReportedCount = in.readInt(); 1851 mCurrentReportedTotalTime = in.readLong(); 1852 mUnpluggedReportedTotalTime = in.readLong(); 1853 mTrackingReportedValues = in.readInt() == 1; 1854 mTimeBaseRunning = timeBase.isRunning(); 1855 } 1856 1857 @VisibleForTesting SamplingTimer(Clocks clocks, TimeBase timeBase)1858 public SamplingTimer(Clocks clocks, TimeBase timeBase) { 1859 super(clocks, 0, timeBase); 1860 mTrackingReportedValues = false; 1861 mTimeBaseRunning = timeBase.isRunning(); 1862 } 1863 1864 /** 1865 * Ends the current sample, allowing subsequent values to {@link #update(long, int)} to 1866 * be less than the values used for a previous invocation. 1867 */ endSample()1868 public void endSample() { 1869 mTotalTime = computeRunTimeLocked(0 /* unused by us */); 1870 mCount = computeCurrentCountLocked(); 1871 mUnpluggedReportedTotalTime = mCurrentReportedTotalTime = 0; 1872 mUnpluggedReportedCount = mCurrentReportedCount = 0; 1873 } 1874 setUpdateVersion(int version)1875 public void setUpdateVersion(int version) { 1876 mUpdateVersion = version; 1877 } 1878 getUpdateVersion()1879 public int getUpdateVersion() { 1880 return mUpdateVersion; 1881 } 1882 1883 /** 1884 * Updates the current recorded values. These are meant to be monotonically increasing 1885 * and cumulative. If you are dealing with deltas, use {@link #add(long, int)}. 1886 * 1887 * If the values being recorded have been reset, the monotonically increasing requirement 1888 * will be broken. In this case, {@link #endSample()} is automatically called and 1889 * the total value of totalTime and count are recorded, starting a new monotonically 1890 * increasing sample. 1891 * 1892 * @param totalTime total time of sample in microseconds. 1893 * @param count total number of times the event being sampled occurred. 1894 */ update(long totalTime, int count)1895 public void update(long totalTime, int count) { 1896 if (mTimeBaseRunning && !mTrackingReportedValues) { 1897 // Updating the reported value for the first time. 1898 mUnpluggedReportedTotalTime = totalTime; 1899 mUnpluggedReportedCount = count; 1900 } 1901 1902 mTrackingReportedValues = true; 1903 1904 if (totalTime < mCurrentReportedTotalTime || count < mCurrentReportedCount) { 1905 endSample(); 1906 } 1907 1908 mCurrentReportedTotalTime = totalTime; 1909 mCurrentReportedCount = count; 1910 } 1911 1912 /** 1913 * Adds deltaTime and deltaCount to the current sample. 1914 * 1915 * @param deltaTime additional time recorded since the last sampled event, in microseconds. 1916 * @param deltaCount additional number of times the event being sampled occurred. 1917 */ add(long deltaTime, int deltaCount)1918 public void add(long deltaTime, int deltaCount) { 1919 update(mCurrentReportedTotalTime + deltaTime, mCurrentReportedCount + deltaCount); 1920 } 1921 1922 @Override onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime)1923 public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) { 1924 super.onTimeStarted(elapsedRealtime, baseUptime, baseRealtime); 1925 if (mTrackingReportedValues) { 1926 mUnpluggedReportedTotalTime = mCurrentReportedTotalTime; 1927 mUnpluggedReportedCount = mCurrentReportedCount; 1928 } 1929 mTimeBaseRunning = true; 1930 } 1931 1932 @Override onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime)1933 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) { 1934 super.onTimeStopped(elapsedRealtime, baseUptime, baseRealtime); 1935 mTimeBaseRunning = false; 1936 } 1937 1938 @Override logState(Printer pw, String prefix)1939 public void logState(Printer pw, String prefix) { 1940 super.logState(pw, prefix); 1941 pw.println(prefix + "mCurrentReportedCount=" + mCurrentReportedCount 1942 + " mUnpluggedReportedCount=" + mUnpluggedReportedCount 1943 + " mCurrentReportedTotalTime=" + mCurrentReportedTotalTime 1944 + " mUnpluggedReportedTotalTime=" + mUnpluggedReportedTotalTime); 1945 } 1946 1947 @Override computeRunTimeLocked(long curBatteryRealtime)1948 protected long computeRunTimeLocked(long curBatteryRealtime) { 1949 return mTotalTime + (mTimeBaseRunning && mTrackingReportedValues 1950 ? mCurrentReportedTotalTime - mUnpluggedReportedTotalTime : 0); 1951 } 1952 1953 @Override computeCurrentCountLocked()1954 protected int computeCurrentCountLocked() { 1955 return mCount + (mTimeBaseRunning && mTrackingReportedValues 1956 ? mCurrentReportedCount - mUnpluggedReportedCount : 0); 1957 } 1958 1959 @Override writeToParcel(Parcel out, long elapsedRealtimeUs)1960 public void writeToParcel(Parcel out, long elapsedRealtimeUs) { 1961 super.writeToParcel(out, elapsedRealtimeUs); 1962 out.writeInt(mCurrentReportedCount); 1963 out.writeInt(mUnpluggedReportedCount); 1964 out.writeLong(mCurrentReportedTotalTime); 1965 out.writeLong(mUnpluggedReportedTotalTime); 1966 out.writeInt(mTrackingReportedValues ? 1 : 0); 1967 } 1968 1969 @Override reset(boolean detachIfReset)1970 public boolean reset(boolean detachIfReset) { 1971 super.reset(detachIfReset); 1972 mTrackingReportedValues = false; 1973 mUnpluggedReportedTotalTime = 0; 1974 mUnpluggedReportedCount = 0; 1975 return true; 1976 } 1977 } 1978 1979 /** 1980 * A timer that increments in batches. It does not run for durations, but just jumps 1981 * for a pre-determined amount. 1982 */ 1983 public static class BatchTimer extends Timer { 1984 final Uid mUid; 1985 1986 /** 1987 * The last time at which we updated the timer. This is in elapsed realtime microseconds. 1988 */ 1989 long mLastAddedTime; 1990 1991 /** 1992 * The last duration that we added to the timer. This is in microseconds. 1993 */ 1994 long mLastAddedDuration; 1995 1996 /** 1997 * Whether we are currently in a discharge cycle. 1998 */ 1999 boolean mInDischarge; 2000 BatchTimer(Clocks clocks, Uid uid, int type, TimeBase timeBase, Parcel in)2001 BatchTimer(Clocks clocks, Uid uid, int type, TimeBase timeBase, Parcel in) { 2002 super(clocks, type, timeBase, in); 2003 mUid = uid; 2004 mLastAddedTime = in.readLong(); 2005 mLastAddedDuration = in.readLong(); 2006 mInDischarge = timeBase.isRunning(); 2007 } 2008 BatchTimer(Clocks clocks, Uid uid, int type, TimeBase timeBase)2009 BatchTimer(Clocks clocks, Uid uid, int type, TimeBase timeBase) { 2010 super(clocks, type, timeBase); 2011 mUid = uid; 2012 mInDischarge = timeBase.isRunning(); 2013 } 2014 2015 @Override writeToParcel(Parcel out, long elapsedRealtimeUs)2016 public void writeToParcel(Parcel out, long elapsedRealtimeUs) { 2017 super.writeToParcel(out, elapsedRealtimeUs); 2018 out.writeLong(mLastAddedTime); 2019 out.writeLong(mLastAddedDuration); 2020 } 2021 2022 @Override onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime)2023 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) { 2024 recomputeLastDuration(mClocks.elapsedRealtime() * 1000, false); 2025 mInDischarge = false; 2026 super.onTimeStopped(elapsedRealtime, baseUptime, baseRealtime); 2027 } 2028 2029 @Override onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime)2030 public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) { 2031 recomputeLastDuration(elapsedRealtime, false); 2032 mInDischarge = true; 2033 // If we are still within the last added duration, then re-added whatever remains. 2034 if (mLastAddedTime == elapsedRealtime) { 2035 mTotalTime += mLastAddedDuration; 2036 } 2037 super.onTimeStarted(elapsedRealtime, baseUptime, baseRealtime); 2038 } 2039 2040 @Override logState(Printer pw, String prefix)2041 public void logState(Printer pw, String prefix) { 2042 super.logState(pw, prefix); 2043 pw.println(prefix + "mLastAddedTime=" + mLastAddedTime 2044 + " mLastAddedDuration=" + mLastAddedDuration); 2045 } 2046 computeOverage(long curTime)2047 private long computeOverage(long curTime) { 2048 if (mLastAddedTime > 0) { 2049 return mLastAddedDuration - curTime; 2050 } 2051 return 0; 2052 } 2053 recomputeLastDuration(long curTime, boolean abort)2054 private void recomputeLastDuration(long curTime, boolean abort) { 2055 final long overage = computeOverage(curTime); 2056 if (overage > 0) { 2057 // Aborting before the duration ran out -- roll back the remaining 2058 // duration. Only do this if currently discharging; otherwise we didn't 2059 // actually add the time. 2060 if (mInDischarge) { 2061 mTotalTime -= overage; 2062 } 2063 if (abort) { 2064 mLastAddedTime = 0; 2065 } else { 2066 mLastAddedTime = curTime; 2067 mLastAddedDuration -= overage; 2068 } 2069 } 2070 } 2071 addDuration(BatteryStatsImpl stats, long durationMillis)2072 public void addDuration(BatteryStatsImpl stats, long durationMillis) { 2073 final long now = mClocks.elapsedRealtime() * 1000; 2074 recomputeLastDuration(now, true); 2075 mLastAddedTime = now; 2076 mLastAddedDuration = durationMillis * 1000; 2077 if (mInDischarge) { 2078 mTotalTime += mLastAddedDuration; 2079 mCount++; 2080 } 2081 } 2082 abortLastDuration(BatteryStatsImpl stats)2083 public void abortLastDuration(BatteryStatsImpl stats) { 2084 final long now = mClocks.elapsedRealtime() * 1000; 2085 recomputeLastDuration(now, true); 2086 } 2087 2088 @Override computeCurrentCountLocked()2089 protected int computeCurrentCountLocked() { 2090 return mCount; 2091 } 2092 2093 @Override computeRunTimeLocked(long curBatteryRealtime)2094 protected long computeRunTimeLocked(long curBatteryRealtime) { 2095 final long overage = computeOverage(mClocks.elapsedRealtime() * 1000); 2096 if (overage > 0) { 2097 return mTotalTime = overage; 2098 } 2099 return mTotalTime; 2100 } 2101 2102 @Override reset(boolean detachIfReset)2103 public boolean reset(boolean detachIfReset) { 2104 final long now = mClocks.elapsedRealtime() * 1000; 2105 recomputeLastDuration(now, true); 2106 boolean stillActive = mLastAddedTime == now; 2107 super.reset(!stillActive && detachIfReset); 2108 return !stillActive; 2109 } 2110 } 2111 2112 2113 /** 2114 * A StopwatchTimer that also tracks the total and max individual 2115 * time spent active according to the given timebase. Whereas 2116 * StopwatchTimer apportions the time amongst all in the pool, 2117 * the total and max durations are not apportioned. 2118 */ 2119 public static class DurationTimer extends StopwatchTimer { 2120 /** 2121 * The time (in ms) that the timer was last acquired or the time base 2122 * last (re-)started. Increasing the nesting depth does not reset this time. 2123 * 2124 * -1 if the timer is currently not running or the time base is not running. 2125 * 2126 * If written to a parcel, the start time is reset, as is mNesting in the base class 2127 * StopwatchTimer. 2128 */ 2129 long mStartTimeMs = -1; 2130 2131 /** 2132 * The longest time period (in ms) that the timer has been active. Not pooled. 2133 */ 2134 long mMaxDurationMs; 2135 2136 /** 2137 * The time (in ms) that that the timer has been active since most recent 2138 * stopRunningLocked() or reset(). Not pooled. 2139 */ 2140 long mCurrentDurationMs; 2141 2142 /** 2143 * The total time (in ms) that that the timer has been active since most recent reset() 2144 * prior to the current startRunningLocked. This is the sum of all past currentDurations 2145 * (but not including the present currentDuration) since reset. Not pooled. 2146 */ 2147 long mTotalDurationMs; 2148 DurationTimer(Clocks clocks, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, TimeBase timeBase, Parcel in)2149 public DurationTimer(Clocks clocks, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, 2150 TimeBase timeBase, Parcel in) { 2151 super(clocks, uid, type, timerPool, timeBase, in); 2152 mMaxDurationMs = in.readLong(); 2153 mTotalDurationMs = in.readLong(); 2154 mCurrentDurationMs = in.readLong(); 2155 } 2156 DurationTimer(Clocks clocks, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, TimeBase timeBase)2157 public DurationTimer(Clocks clocks, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, 2158 TimeBase timeBase) { 2159 super(clocks, uid, type, timerPool, timeBase); 2160 } 2161 2162 @Override writeToParcel(Parcel out, long elapsedRealtimeUs)2163 public void writeToParcel(Parcel out, long elapsedRealtimeUs) { 2164 super.writeToParcel(out, elapsedRealtimeUs); 2165 out.writeLong(getMaxDurationMsLocked(elapsedRealtimeUs / 1000)); 2166 out.writeLong(mTotalDurationMs); 2167 out.writeLong(getCurrentDurationMsLocked(elapsedRealtimeUs / 1000)); 2168 } 2169 2170 /** 2171 * Write the summary to the parcel. 2172 * 2173 * Since the time base is probably meaningless after we come back, reading 2174 * from this will have the effect of stopping the timer. So here all we write 2175 * is the max and total durations. 2176 */ 2177 @Override writeSummaryFromParcelLocked(Parcel out, long elapsedRealtimeUs)2178 public void writeSummaryFromParcelLocked(Parcel out, long elapsedRealtimeUs) { 2179 super.writeSummaryFromParcelLocked(out, elapsedRealtimeUs); 2180 out.writeLong(getMaxDurationMsLocked(elapsedRealtimeUs / 1000)); 2181 out.writeLong(getTotalDurationMsLocked(elapsedRealtimeUs / 1000)); 2182 } 2183 2184 /** 2185 * Read the summary parcel. 2186 * 2187 * Has the side effect of stopping the timer. 2188 */ 2189 @Override readSummaryFromParcelLocked(Parcel in)2190 public void readSummaryFromParcelLocked(Parcel in) { 2191 super.readSummaryFromParcelLocked(in); 2192 mMaxDurationMs = in.readLong(); 2193 mTotalDurationMs = in.readLong(); 2194 mStartTimeMs = -1; 2195 mCurrentDurationMs = 0; 2196 } 2197 2198 /** 2199 * The TimeBase time started (again). 2200 * 2201 * If the timer is also running, store the start time. 2202 */ onTimeStarted(long elapsedRealtimeUs, long baseUptime, long baseRealtime)2203 public void onTimeStarted(long elapsedRealtimeUs, long baseUptime, long baseRealtime) { 2204 super.onTimeStarted(elapsedRealtimeUs, baseUptime, baseRealtime); 2205 if (mNesting > 0) { 2206 mStartTimeMs = baseRealtime / 1000; 2207 } 2208 } 2209 2210 /** 2211 * The TimeBase stopped running. 2212 * 2213 * If the timer is running, add the duration into mCurrentDurationMs. 2214 */ 2215 @Override onTimeStopped(long elapsedRealtimeUs, long baseUptime, long baseRealtimeUs)2216 public void onTimeStopped(long elapsedRealtimeUs, long baseUptime, long baseRealtimeUs) { 2217 super.onTimeStopped(elapsedRealtimeUs, baseUptime, baseRealtimeUs); 2218 if (mNesting > 0) { 2219 // baseRealtimeUs has already been converted to the timebase's realtime. 2220 mCurrentDurationMs += (baseRealtimeUs / 1000) - mStartTimeMs; 2221 } 2222 mStartTimeMs = -1; 2223 } 2224 2225 @Override logState(Printer pw, String prefix)2226 public void logState(Printer pw, String prefix) { 2227 super.logState(pw, prefix); 2228 } 2229 2230 @Override startRunningLocked(long elapsedRealtimeMs)2231 public void startRunningLocked(long elapsedRealtimeMs) { 2232 super.startRunningLocked(elapsedRealtimeMs); 2233 if (mNesting == 1 && mTimeBase.isRunning()) { 2234 // Just started 2235 mStartTimeMs = mTimeBase.getRealtime(elapsedRealtimeMs * 1000) / 1000; 2236 } 2237 } 2238 2239 /** 2240 * Decrements the mNesting ref-count on this timer. 2241 * 2242 * If it actually stopped (mNesting went to 0), then possibly update 2243 * mMaxDuration if the current duration was the longest ever. 2244 */ 2245 @Override stopRunningLocked(long elapsedRealtimeMs)2246 public void stopRunningLocked(long elapsedRealtimeMs) { 2247 if (mNesting == 1) { 2248 final long durationMs = getCurrentDurationMsLocked(elapsedRealtimeMs); 2249 mTotalDurationMs += durationMs; 2250 if (durationMs > mMaxDurationMs) { 2251 mMaxDurationMs = durationMs; 2252 } 2253 mStartTimeMs = -1; 2254 mCurrentDurationMs = 0; 2255 } 2256 // super method decrements mNesting, which getCurrentDurationMsLocked relies on, 2257 // so call super.stopRunningLocked after calling getCurrentDurationMsLocked. 2258 super.stopRunningLocked(elapsedRealtimeMs); 2259 } 2260 2261 @Override reset(boolean detachIfReset)2262 public boolean reset(boolean detachIfReset) { 2263 boolean result = super.reset(detachIfReset); 2264 mMaxDurationMs = 0; 2265 mTotalDurationMs = 0; 2266 mCurrentDurationMs = 0; 2267 if (mNesting > 0) { 2268 mStartTimeMs = mTimeBase.getRealtime(mClocks.elapsedRealtime() * 1000) / 1000; 2269 } else { 2270 mStartTimeMs = -1; 2271 } 2272 return result; 2273 } 2274 2275 /** 2276 * Returns the max duration that this timer has ever seen. 2277 * 2278 * Note that this time is NOT split between the timers in the timer group that 2279 * this timer is attached to. It is the TOTAL time. 2280 */ 2281 @Override getMaxDurationMsLocked(long elapsedRealtimeMs)2282 public long getMaxDurationMsLocked(long elapsedRealtimeMs) { 2283 if (mNesting > 0) { 2284 final long durationMs = getCurrentDurationMsLocked(elapsedRealtimeMs); 2285 if (durationMs > mMaxDurationMs) { 2286 return durationMs; 2287 } 2288 } 2289 return mMaxDurationMs; 2290 } 2291 2292 /** 2293 * Returns the time since the timer was started. 2294 * Returns 0 if the timer is not currently running. 2295 * 2296 * Note that this time is NOT split between the timers in the timer group that 2297 * this timer is attached to. It is the TOTAL time. 2298 * 2299 * Note that if running timer is parceled and unparceled, this method will return 2300 * current duration value at the time of parceling even though timer may not be 2301 * currently running. 2302 */ 2303 @Override getCurrentDurationMsLocked(long elapsedRealtimeMs)2304 public long getCurrentDurationMsLocked(long elapsedRealtimeMs) { 2305 long durationMs = mCurrentDurationMs; 2306 if (mNesting > 0 && mTimeBase.isRunning()) { 2307 durationMs += (mTimeBase.getRealtime(elapsedRealtimeMs * 1000) / 1000) 2308 - mStartTimeMs; 2309 } 2310 return durationMs; 2311 } 2312 2313 /** 2314 * Returns the total cumulative duration that this timer has been on since reset(). 2315 * If mTimerPool == null, this should be the same 2316 * as getTotalTimeLocked(elapsedRealtimeMs*1000, STATS_SINCE_CHARGED)/1000. 2317 * 2318 * Note that this time is NOT split between the timers in the timer group that 2319 * this timer is attached to. It is the TOTAL time. For this reason, if mTimerPool != null, 2320 * the result will not be equivalent to getTotalTimeLocked. 2321 */ 2322 @Override getTotalDurationMsLocked(long elapsedRealtimeMs)2323 public long getTotalDurationMsLocked(long elapsedRealtimeMs) { 2324 return mTotalDurationMs + getCurrentDurationMsLocked(elapsedRealtimeMs); 2325 } 2326 } 2327 2328 /** 2329 * State for keeping track of timing information. 2330 */ 2331 public static class StopwatchTimer extends Timer { 2332 final Uid mUid; 2333 final ArrayList<StopwatchTimer> mTimerPool; 2334 2335 int mNesting; 2336 2337 /** 2338 * The last time at which we updated the timer. If mNesting is > 0, 2339 * subtract this from the current battery time to find the amount of 2340 * time we have been running since we last computed an update. 2341 */ 2342 long mUpdateTime; 2343 2344 /** 2345 * The total time at which the timer was acquired, to determine if it 2346 * was actually held for an interesting duration. If time base was not running when timer 2347 * was acquired, will be -1. 2348 */ 2349 long mAcquireTime = -1; 2350 2351 long mTimeout; 2352 2353 /** 2354 * For partial wake locks, keep track of whether we are in the list 2355 * to consume CPU cycles. 2356 */ 2357 @VisibleForTesting 2358 public boolean mInList; 2359 StopwatchTimer(Clocks clocks, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, TimeBase timeBase, Parcel in)2360 public StopwatchTimer(Clocks clocks, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, 2361 TimeBase timeBase, Parcel in) { 2362 super(clocks, type, timeBase, in); 2363 mUid = uid; 2364 mTimerPool = timerPool; 2365 mUpdateTime = in.readLong(); 2366 } 2367 StopwatchTimer(Clocks clocks, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, TimeBase timeBase)2368 public StopwatchTimer(Clocks clocks, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, 2369 TimeBase timeBase) { 2370 super(clocks, type, timeBase); 2371 mUid = uid; 2372 mTimerPool = timerPool; 2373 } 2374 setTimeout(long timeout)2375 public void setTimeout(long timeout) { 2376 mTimeout = timeout; 2377 } 2378 writeToParcel(Parcel out, long elapsedRealtimeUs)2379 public void writeToParcel(Parcel out, long elapsedRealtimeUs) { 2380 super.writeToParcel(out, elapsedRealtimeUs); 2381 out.writeLong(mUpdateTime); 2382 } 2383 onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime)2384 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) { 2385 if (mNesting > 0) { 2386 if (DEBUG && mType < 0) { 2387 Log.v(TAG, "old mUpdateTime=" + mUpdateTime); 2388 } 2389 super.onTimeStopped(elapsedRealtime, baseUptime, baseRealtime); 2390 mUpdateTime = baseRealtime; 2391 if (DEBUG && mType < 0) { 2392 Log.v(TAG, "new mUpdateTime=" + mUpdateTime); 2393 } 2394 } 2395 } 2396 logState(Printer pw, String prefix)2397 public void logState(Printer pw, String prefix) { 2398 super.logState(pw, prefix); 2399 pw.println(prefix + "mNesting=" + mNesting + " mUpdateTime=" + mUpdateTime 2400 + " mAcquireTime=" + mAcquireTime); 2401 } 2402 startRunningLocked(long elapsedRealtimeMs)2403 public void startRunningLocked(long elapsedRealtimeMs) { 2404 if (mNesting++ == 0) { 2405 final long batteryRealtime = mTimeBase.getRealtime(elapsedRealtimeMs * 1000); 2406 mUpdateTime = batteryRealtime; 2407 if (mTimerPool != null) { 2408 // Accumulate time to all currently active timers before adding 2409 // this new one to the pool. 2410 refreshTimersLocked(batteryRealtime, mTimerPool, null); 2411 // Add this timer to the active pool 2412 mTimerPool.add(this); 2413 } 2414 if (mTimeBase.isRunning()) { 2415 // Increment the count 2416 mCount++; 2417 mAcquireTime = mTotalTime; 2418 } else { 2419 mAcquireTime = -1; 2420 } 2421 if (DEBUG && mType < 0) { 2422 Log.v(TAG, "start #" + mType + ": mUpdateTime=" + mUpdateTime 2423 + " mTotalTime=" + mTotalTime + " mCount=" + mCount 2424 + " mAcquireTime=" + mAcquireTime); 2425 } 2426 } 2427 } 2428 isRunningLocked()2429 public boolean isRunningLocked() { 2430 return mNesting > 0; 2431 } 2432 stopRunningLocked(long elapsedRealtimeMs)2433 public void stopRunningLocked(long elapsedRealtimeMs) { 2434 // Ignore attempt to stop a timer that isn't running 2435 if (mNesting == 0) { 2436 return; 2437 } 2438 if (--mNesting == 0) { 2439 final long batteryRealtime = mTimeBase.getRealtime(elapsedRealtimeMs * 1000); 2440 if (mTimerPool != null) { 2441 // Accumulate time to all active counters, scaled by the total 2442 // active in the pool, before taking this one out of the pool. 2443 refreshTimersLocked(batteryRealtime, mTimerPool, null); 2444 // Remove this timer from the active pool 2445 mTimerPool.remove(this); 2446 } else { 2447 mNesting = 1; 2448 mTotalTime = computeRunTimeLocked(batteryRealtime); 2449 mNesting = 0; 2450 } 2451 2452 if (DEBUG && mType < 0) { 2453 Log.v(TAG, "stop #" + mType + ": mUpdateTime=" + mUpdateTime 2454 + " mTotalTime=" + mTotalTime + " mCount=" + mCount 2455 + " mAcquireTime=" + mAcquireTime); 2456 } 2457 2458 if (mAcquireTime >= 0 && mTotalTime == mAcquireTime) { 2459 // If there was no change in the time, then discard this 2460 // count. A somewhat cheezy strategy, but hey. 2461 mCount--; 2462 } 2463 } 2464 } 2465 stopAllRunningLocked(long elapsedRealtimeMs)2466 public void stopAllRunningLocked(long elapsedRealtimeMs) { 2467 if (mNesting > 0) { 2468 mNesting = 1; 2469 stopRunningLocked(elapsedRealtimeMs); 2470 } 2471 } 2472 2473 // Update the total time for all other running Timers with the same type as this Timer 2474 // due to a change in timer count refreshTimersLocked(long batteryRealtime, final ArrayList<StopwatchTimer> pool, StopwatchTimer self)2475 private static long refreshTimersLocked(long batteryRealtime, 2476 final ArrayList<StopwatchTimer> pool, StopwatchTimer self) { 2477 long selfTime = 0; 2478 final int N = pool.size(); 2479 for (int i=N-1; i>= 0; i--) { 2480 final StopwatchTimer t = pool.get(i); 2481 long heldTime = batteryRealtime - t.mUpdateTime; 2482 if (heldTime > 0) { 2483 final long myTime = heldTime / N; 2484 if (t == self) { 2485 selfTime = myTime; 2486 } 2487 t.mTotalTime += myTime; 2488 } 2489 t.mUpdateTime = batteryRealtime; 2490 } 2491 return selfTime; 2492 } 2493 2494 @Override computeRunTimeLocked(long curBatteryRealtime)2495 protected long computeRunTimeLocked(long curBatteryRealtime) { 2496 if (mTimeout > 0 && curBatteryRealtime > mUpdateTime + mTimeout) { 2497 curBatteryRealtime = mUpdateTime + mTimeout; 2498 } 2499 return mTotalTime + (mNesting > 0 2500 ? (curBatteryRealtime - mUpdateTime) 2501 / (mTimerPool != null ? mTimerPool.size() : 1) 2502 : 0); 2503 } 2504 2505 @Override computeCurrentCountLocked()2506 protected int computeCurrentCountLocked() { 2507 return mCount; 2508 } 2509 2510 @Override reset(boolean detachIfReset)2511 public boolean reset(boolean detachIfReset) { 2512 boolean canDetach = mNesting <= 0; 2513 super.reset(canDetach && detachIfReset); 2514 if (mNesting > 0) { 2515 mUpdateTime = mTimeBase.getRealtime(mClocks.elapsedRealtime() * 1000); 2516 } 2517 mAcquireTime = -1; // to ensure mCount isn't decreased to -1 if timer is stopped later. 2518 return canDetach; 2519 } 2520 2521 @Override 2522 @UnsupportedAppUsage detach()2523 public void detach() { 2524 super.detach(); 2525 if (mTimerPool != null) { 2526 mTimerPool.remove(this); 2527 } 2528 } 2529 2530 @Override readSummaryFromParcelLocked(Parcel in)2531 public void readSummaryFromParcelLocked(Parcel in) { 2532 super.readSummaryFromParcelLocked(in); 2533 mNesting = 0; 2534 } 2535 2536 /** 2537 * Set the mark so that we can query later for the total time the timer has 2538 * accumulated since this point. The timer can be running or not. 2539 * 2540 * @param elapsedRealtimeMs the current elapsed realtime in milliseconds. 2541 */ setMark(long elapsedRealtimeMs)2542 public void setMark(long elapsedRealtimeMs) { 2543 final long batteryRealtime = mTimeBase.getRealtime(elapsedRealtimeMs * 1000); 2544 if (mNesting > 0) { 2545 // We are running. 2546 if (mTimerPool != null) { 2547 refreshTimersLocked(batteryRealtime, mTimerPool, this); 2548 } else { 2549 mTotalTime += batteryRealtime - mUpdateTime; 2550 mUpdateTime = batteryRealtime; 2551 } 2552 } 2553 mTimeBeforeMark = mTotalTime; 2554 } 2555 } 2556 2557 /** 2558 * State for keeping track of two DurationTimers with different TimeBases, presumably where one 2559 * TimeBase is effectively a subset of the other. 2560 */ 2561 public static class DualTimer extends DurationTimer { 2562 // This class both is a DurationTimer and also holds a second DurationTimer. 2563 // The main timer (this) typically tracks the total time. It may be pooled (but since it's a 2564 // durationTimer, it also has the unpooled getTotalDurationMsLocked() for 2565 // STATS_SINCE_CHARGED). 2566 // mSubTimer typically tracks only part of the total time, such as background time, as 2567 // determined by a subTimeBase. It is NOT pooled. 2568 private final DurationTimer mSubTimer; 2569 2570 /** 2571 * Creates a DualTimer to hold a main timer (this) and a mSubTimer. 2572 * The main timer (this) is based on the given timeBase and timerPool. 2573 * The mSubTimer is based on the given subTimeBase. The mSubTimer is not pooled, even if 2574 * the main timer is. 2575 */ DualTimer(Clocks clocks, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, TimeBase timeBase, TimeBase subTimeBase, Parcel in)2576 public DualTimer(Clocks clocks, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, 2577 TimeBase timeBase, TimeBase subTimeBase, Parcel in) { 2578 super(clocks, uid, type, timerPool, timeBase, in); 2579 mSubTimer = new DurationTimer(clocks, uid, type, null, subTimeBase, in); 2580 } 2581 2582 /** 2583 * Creates a DualTimer to hold a main timer (this) and a mSubTimer. 2584 * The main timer (this) is based on the given timeBase and timerPool. 2585 * The mSubTimer is based on the given subTimeBase. The mSubTimer is not pooled, even if 2586 * the main timer is. 2587 */ DualTimer(Clocks clocks, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, TimeBase timeBase, TimeBase subTimeBase)2588 public DualTimer(Clocks clocks, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, 2589 TimeBase timeBase, TimeBase subTimeBase) { 2590 super(clocks, uid, type, timerPool, timeBase); 2591 mSubTimer = new DurationTimer(clocks, uid, type, null, subTimeBase); 2592 } 2593 2594 /** Get the secondary timer. */ 2595 @Override getSubTimer()2596 public DurationTimer getSubTimer() { 2597 return mSubTimer; 2598 } 2599 2600 @Override startRunningLocked(long elapsedRealtimeMs)2601 public void startRunningLocked(long elapsedRealtimeMs) { 2602 super.startRunningLocked(elapsedRealtimeMs); 2603 mSubTimer.startRunningLocked(elapsedRealtimeMs); 2604 } 2605 2606 @Override stopRunningLocked(long elapsedRealtimeMs)2607 public void stopRunningLocked(long elapsedRealtimeMs) { 2608 super.stopRunningLocked(elapsedRealtimeMs); 2609 mSubTimer.stopRunningLocked(elapsedRealtimeMs); 2610 } 2611 2612 @Override stopAllRunningLocked(long elapsedRealtimeMs)2613 public void stopAllRunningLocked(long elapsedRealtimeMs) { 2614 super.stopAllRunningLocked(elapsedRealtimeMs); 2615 mSubTimer.stopAllRunningLocked(elapsedRealtimeMs); 2616 } 2617 2618 @Override reset(boolean detachIfReset)2619 public boolean reset(boolean detachIfReset) { 2620 boolean active = false; 2621 // Do not detach the subTimer explicitly since that'll be done by DualTimer.detach(). 2622 active |= !mSubTimer.reset(false); 2623 active |= !super.reset(detachIfReset); 2624 return !active; 2625 } 2626 2627 @Override detach()2628 public void detach() { 2629 mSubTimer.detach(); 2630 super.detach(); 2631 } 2632 2633 @Override writeToParcel(Parcel out, long elapsedRealtimeUs)2634 public void writeToParcel(Parcel out, long elapsedRealtimeUs) { 2635 super.writeToParcel(out, elapsedRealtimeUs); 2636 mSubTimer.writeToParcel(out, elapsedRealtimeUs); 2637 } 2638 2639 @Override writeSummaryFromParcelLocked(Parcel out, long elapsedRealtimeUs)2640 public void writeSummaryFromParcelLocked(Parcel out, long elapsedRealtimeUs) { 2641 super.writeSummaryFromParcelLocked(out, elapsedRealtimeUs); 2642 mSubTimer.writeSummaryFromParcelLocked(out, elapsedRealtimeUs); 2643 } 2644 2645 @Override readSummaryFromParcelLocked(Parcel in)2646 public void readSummaryFromParcelLocked(Parcel in) { 2647 super.readSummaryFromParcelLocked(in); 2648 mSubTimer.readSummaryFromParcelLocked(in); 2649 } 2650 } 2651 2652 2653 public abstract class OverflowArrayMap<T> { 2654 private static final String OVERFLOW_NAME = "*overflow*"; 2655 2656 final int mUid; 2657 final ArrayMap<String, T> mMap = new ArrayMap<>(); 2658 T mCurOverflow; 2659 ArrayMap<String, MutableInt> mActiveOverflow; 2660 long mLastOverflowTime; 2661 long mLastOverflowFinishTime; 2662 long mLastClearTime; 2663 long mLastCleanupTime; 2664 OverflowArrayMap(int uid)2665 public OverflowArrayMap(int uid) { 2666 mUid = uid; 2667 } 2668 getMap()2669 public ArrayMap<String, T> getMap() { 2670 return mMap; 2671 } 2672 clear()2673 public void clear() { 2674 mLastClearTime = SystemClock.elapsedRealtime(); 2675 mMap.clear(); 2676 mCurOverflow = null; 2677 mActiveOverflow = null; 2678 } 2679 add(String name, T obj)2680 public void add(String name, T obj) { 2681 if (name == null) { 2682 name = ""; 2683 } 2684 mMap.put(name, obj); 2685 if (OVERFLOW_NAME.equals(name)) { 2686 mCurOverflow = obj; 2687 } 2688 } 2689 cleanup()2690 public void cleanup() { 2691 mLastCleanupTime = SystemClock.elapsedRealtime(); 2692 if (mActiveOverflow != null) { 2693 if (mActiveOverflow.size() == 0) { 2694 mActiveOverflow = null; 2695 } 2696 } 2697 if (mActiveOverflow == null) { 2698 // There is no currently active overflow, so we should no longer have 2699 // an overflow entry. 2700 if (mMap.containsKey(OVERFLOW_NAME)) { 2701 Slog.wtf(TAG, "Cleaning up with no active overflow, but have overflow entry " 2702 + mMap.get(OVERFLOW_NAME)); 2703 mMap.remove(OVERFLOW_NAME); 2704 } 2705 mCurOverflow = null; 2706 } else { 2707 // There is currently active overflow, so we should still have an overflow entry. 2708 if (mCurOverflow == null || !mMap.containsKey(OVERFLOW_NAME)) { 2709 Slog.wtf(TAG, "Cleaning up with active overflow, but no overflow entry: cur=" 2710 + mCurOverflow + " map=" + mMap.get(OVERFLOW_NAME)); 2711 } 2712 } 2713 } 2714 startObject(String name)2715 public T startObject(String name) { 2716 if (name == null) { 2717 name = ""; 2718 } 2719 T obj = mMap.get(name); 2720 if (obj != null) { 2721 return obj; 2722 } 2723 2724 // No object exists for the given name, but do we currently have it 2725 // running as part of the overflow? 2726 if (mActiveOverflow != null) { 2727 MutableInt over = mActiveOverflow.get(name); 2728 if (over != null) { 2729 // We are already actively counting this name in the overflow object. 2730 obj = mCurOverflow; 2731 if (obj == null) { 2732 // Shouldn't be here, but we'll try to recover. 2733 Slog.wtf(TAG, "Have active overflow " + name + " but null overflow"); 2734 obj = mCurOverflow = instantiateObject(); 2735 mMap.put(OVERFLOW_NAME, obj); 2736 } 2737 over.value++; 2738 return obj; 2739 } 2740 } 2741 2742 // No object exists for given name nor in the overflow; we need to make 2743 // a new one. 2744 final int N = mMap.size(); 2745 if (N >= MAX_WAKELOCKS_PER_UID) { 2746 // Went over the limit on number of objects to track; this one goes 2747 // in to the overflow. 2748 obj = mCurOverflow; 2749 if (obj == null) { 2750 // Need to start overflow now... 2751 obj = mCurOverflow = instantiateObject(); 2752 mMap.put(OVERFLOW_NAME, obj); 2753 } 2754 if (mActiveOverflow == null) { 2755 mActiveOverflow = new ArrayMap<>(); 2756 } 2757 mActiveOverflow.put(name, new MutableInt(1)); 2758 mLastOverflowTime = SystemClock.elapsedRealtime(); 2759 return obj; 2760 } 2761 2762 // Normal case where we just need to make a new object. 2763 obj = instantiateObject(); 2764 mMap.put(name, obj); 2765 return obj; 2766 } 2767 stopObject(String name)2768 public T stopObject(String name) { 2769 if (name == null) { 2770 name = ""; 2771 } 2772 T obj = mMap.get(name); 2773 if (obj != null) { 2774 return obj; 2775 } 2776 2777 // No object exists for the given name, but do we currently have it 2778 // running as part of the overflow? 2779 if (mActiveOverflow != null) { 2780 MutableInt over = mActiveOverflow.get(name); 2781 if (over != null) { 2782 // We are already actively counting this name in the overflow object. 2783 obj = mCurOverflow; 2784 if (obj != null) { 2785 over.value--; 2786 if (over.value <= 0) { 2787 mActiveOverflow.remove(name); 2788 mLastOverflowFinishTime = SystemClock.elapsedRealtime(); 2789 } 2790 return obj; 2791 } 2792 } 2793 } 2794 2795 // Huh, they are stopping an active operation but we can't find one! 2796 // That's not good. 2797 StringBuilder sb = new StringBuilder(); 2798 sb.append("Unable to find object for "); 2799 sb.append(name); 2800 sb.append(" in uid "); 2801 sb.append(mUid); 2802 sb.append(" mapsize="); 2803 sb.append(mMap.size()); 2804 sb.append(" activeoverflow="); 2805 sb.append(mActiveOverflow); 2806 sb.append(" curoverflow="); 2807 sb.append(mCurOverflow); 2808 long now = SystemClock.elapsedRealtime(); 2809 if (mLastOverflowTime != 0) { 2810 sb.append(" lastOverflowTime="); 2811 TimeUtils.formatDuration(mLastOverflowTime-now, sb); 2812 } 2813 if (mLastOverflowFinishTime != 0) { 2814 sb.append(" lastOverflowFinishTime="); 2815 TimeUtils.formatDuration(mLastOverflowFinishTime-now, sb); 2816 } 2817 if (mLastClearTime != 0) { 2818 sb.append(" lastClearTime="); 2819 TimeUtils.formatDuration(mLastClearTime-now, sb); 2820 } 2821 if (mLastCleanupTime != 0) { 2822 sb.append(" lastCleanupTime="); 2823 TimeUtils.formatDuration(mLastCleanupTime-now, sb); 2824 } 2825 Slog.wtf(TAG, sb.toString()); 2826 return null; 2827 } 2828 instantiateObject()2829 public abstract T instantiateObject(); 2830 } 2831 2832 public static class ControllerActivityCounterImpl extends ControllerActivityCounter 2833 implements Parcelable { 2834 private final LongSamplingCounter mIdleTimeMillis; 2835 private final LongSamplingCounter mScanTimeMillis; 2836 private final LongSamplingCounter mSleepTimeMillis; 2837 private final LongSamplingCounter mRxTimeMillis; 2838 private final LongSamplingCounter[] mTxTimeMillis; 2839 private final LongSamplingCounter mPowerDrainMaMs; 2840 private final LongSamplingCounter mMonitoredRailChargeConsumedMaMs; 2841 ControllerActivityCounterImpl(TimeBase timeBase, int numTxStates)2842 public ControllerActivityCounterImpl(TimeBase timeBase, int numTxStates) { 2843 mIdleTimeMillis = new LongSamplingCounter(timeBase); 2844 mScanTimeMillis = new LongSamplingCounter(timeBase); 2845 mSleepTimeMillis = new LongSamplingCounter(timeBase); 2846 mRxTimeMillis = new LongSamplingCounter(timeBase); 2847 mTxTimeMillis = new LongSamplingCounter[numTxStates]; 2848 for (int i = 0; i < numTxStates; i++) { 2849 mTxTimeMillis[i] = new LongSamplingCounter(timeBase); 2850 } 2851 mPowerDrainMaMs = new LongSamplingCounter(timeBase); 2852 mMonitoredRailChargeConsumedMaMs = new LongSamplingCounter(timeBase); 2853 } 2854 ControllerActivityCounterImpl(TimeBase timeBase, int numTxStates, Parcel in)2855 public ControllerActivityCounterImpl(TimeBase timeBase, int numTxStates, Parcel in) { 2856 mIdleTimeMillis = new LongSamplingCounter(timeBase, in); 2857 mScanTimeMillis = new LongSamplingCounter(timeBase, in); 2858 mSleepTimeMillis = new LongSamplingCounter(timeBase, in); 2859 mRxTimeMillis = new LongSamplingCounter(timeBase, in); 2860 final int recordedTxStates = in.readInt(); 2861 if (recordedTxStates != numTxStates) { 2862 throw new ParcelFormatException("inconsistent tx state lengths"); 2863 } 2864 2865 mTxTimeMillis = new LongSamplingCounter[numTxStates]; 2866 for (int i = 0; i < numTxStates; i++) { 2867 mTxTimeMillis[i] = new LongSamplingCounter(timeBase, in); 2868 } 2869 mPowerDrainMaMs = new LongSamplingCounter(timeBase, in); 2870 mMonitoredRailChargeConsumedMaMs = new LongSamplingCounter(timeBase, in); 2871 } 2872 readSummaryFromParcel(Parcel in)2873 public void readSummaryFromParcel(Parcel in) { 2874 mIdleTimeMillis.readSummaryFromParcelLocked(in); 2875 mScanTimeMillis.readSummaryFromParcelLocked(in); 2876 mSleepTimeMillis.readSummaryFromParcelLocked(in); 2877 mRxTimeMillis.readSummaryFromParcelLocked(in); 2878 final int recordedTxStates = in.readInt(); 2879 if (recordedTxStates != mTxTimeMillis.length) { 2880 throw new ParcelFormatException("inconsistent tx state lengths"); 2881 } 2882 for (LongSamplingCounter counter : mTxTimeMillis) { 2883 counter.readSummaryFromParcelLocked(in); 2884 } 2885 mPowerDrainMaMs.readSummaryFromParcelLocked(in); 2886 mMonitoredRailChargeConsumedMaMs.readSummaryFromParcelLocked(in); 2887 } 2888 2889 @Override describeContents()2890 public int describeContents() { 2891 return 0; 2892 } 2893 writeSummaryToParcel(Parcel dest)2894 public void writeSummaryToParcel(Parcel dest) { 2895 mIdleTimeMillis.writeSummaryFromParcelLocked(dest); 2896 mScanTimeMillis.writeSummaryFromParcelLocked(dest); 2897 mSleepTimeMillis.writeSummaryFromParcelLocked(dest); 2898 mRxTimeMillis.writeSummaryFromParcelLocked(dest); 2899 dest.writeInt(mTxTimeMillis.length); 2900 for (LongSamplingCounter counter : mTxTimeMillis) { 2901 counter.writeSummaryFromParcelLocked(dest); 2902 } 2903 mPowerDrainMaMs.writeSummaryFromParcelLocked(dest); 2904 mMonitoredRailChargeConsumedMaMs.writeSummaryFromParcelLocked(dest); 2905 } 2906 2907 @Override writeToParcel(Parcel dest, int flags)2908 public void writeToParcel(Parcel dest, int flags) { 2909 mIdleTimeMillis.writeToParcel(dest); 2910 mScanTimeMillis.writeToParcel(dest); 2911 mSleepTimeMillis.writeToParcel(dest); 2912 mRxTimeMillis.writeToParcel(dest); 2913 dest.writeInt(mTxTimeMillis.length); 2914 for (LongSamplingCounter counter : mTxTimeMillis) { 2915 counter.writeToParcel(dest); 2916 } 2917 mPowerDrainMaMs.writeToParcel(dest); 2918 mMonitoredRailChargeConsumedMaMs.writeToParcel(dest); 2919 } 2920 reset(boolean detachIfReset)2921 public void reset(boolean detachIfReset) { 2922 mIdleTimeMillis.reset(detachIfReset); 2923 mScanTimeMillis.reset(detachIfReset); 2924 mSleepTimeMillis.reset(detachIfReset); 2925 mRxTimeMillis.reset(detachIfReset); 2926 for (LongSamplingCounter counter : mTxTimeMillis) { 2927 counter.reset(detachIfReset); 2928 } 2929 mPowerDrainMaMs.reset(detachIfReset); 2930 mMonitoredRailChargeConsumedMaMs.reset(detachIfReset); 2931 } 2932 detach()2933 public void detach() { 2934 mIdleTimeMillis.detach(); 2935 mScanTimeMillis.detach(); 2936 mSleepTimeMillis.detach(); 2937 mRxTimeMillis.detach(); 2938 for (LongSamplingCounter counter : mTxTimeMillis) { 2939 counter.detach(); 2940 } 2941 mPowerDrainMaMs.detach(); 2942 mMonitoredRailChargeConsumedMaMs.detach(); 2943 } 2944 2945 /** 2946 * @return a LongSamplingCounter, measuring time spent in the idle state in 2947 * milliseconds. 2948 */ 2949 @Override getIdleTimeCounter()2950 public LongSamplingCounter getIdleTimeCounter() { 2951 return mIdleTimeMillis; 2952 } 2953 2954 /** 2955 * @return a LongSamplingCounter, measuring time spent in the scan state in 2956 * milliseconds. 2957 */ 2958 @Override getScanTimeCounter()2959 public LongSamplingCounter getScanTimeCounter() { 2960 return mScanTimeMillis; 2961 } 2962 2963 /** 2964 * @return a LongSamplingCounter, measuring time spent in the sleep state in 2965 * milliseconds. 2966 */ 2967 @Override getSleepTimeCounter()2968 public LongSamplingCounter getSleepTimeCounter() { 2969 return mSleepTimeMillis; 2970 } 2971 2972 /** 2973 * @return a LongSamplingCounter, measuring time spent in the receive state in 2974 * milliseconds. 2975 */ 2976 @Override getRxTimeCounter()2977 public LongSamplingCounter getRxTimeCounter() { 2978 return mRxTimeMillis; 2979 } 2980 2981 /** 2982 * @return a LongSamplingCounter[], measuring time spent in various transmit states in 2983 * milliseconds. 2984 */ 2985 @Override getTxTimeCounters()2986 public LongSamplingCounter[] getTxTimeCounters() { 2987 return mTxTimeMillis; 2988 } 2989 2990 /** 2991 * @return a LongSamplingCounter, measuring power use in milli-ampere milliseconds (mAmS). 2992 */ 2993 @Override getPowerCounter()2994 public LongSamplingCounter getPowerCounter() { 2995 return mPowerDrainMaMs; 2996 } 2997 2998 /** 2999 * @return a LongSamplingCounter, measuring actual monitored rail energy consumed 3000 * milli-ampere milli-seconds (mAmS). 3001 */ 3002 @Override getMonitoredRailChargeConsumedMaMs()3003 public LongSamplingCounter getMonitoredRailChargeConsumedMaMs() { 3004 return mMonitoredRailChargeConsumedMaMs; 3005 } 3006 } 3007 3008 /** Get Resource Power Manager stats. Create a new one if it doesn't already exist. */ getRpmTimerLocked(String name)3009 public SamplingTimer getRpmTimerLocked(String name) { 3010 SamplingTimer rpmt = mRpmStats.get(name); 3011 if (rpmt == null) { 3012 rpmt = new SamplingTimer(mClocks, mOnBatteryTimeBase); 3013 mRpmStats.put(name, rpmt); 3014 } 3015 return rpmt; 3016 } 3017 3018 /** Get Screen-off Resource Power Manager stats. Create new one if it doesn't already exist. */ getScreenOffRpmTimerLocked(String name)3019 public SamplingTimer getScreenOffRpmTimerLocked(String name) { 3020 SamplingTimer rpmt = mScreenOffRpmStats.get(name); 3021 if (rpmt == null) { 3022 rpmt = new SamplingTimer(mClocks, mOnBatteryScreenOffTimeBase); 3023 mScreenOffRpmStats.put(name, rpmt); 3024 } 3025 return rpmt; 3026 } 3027 3028 /* 3029 * Get the wakeup reason counter, and create a new one if one 3030 * doesn't already exist. 3031 */ getWakeupReasonTimerLocked(String name)3032 public SamplingTimer getWakeupReasonTimerLocked(String name) { 3033 SamplingTimer timer = mWakeupReasonStats.get(name); 3034 if (timer == null) { 3035 timer = new SamplingTimer(mClocks, mOnBatteryTimeBase); 3036 mWakeupReasonStats.put(name, timer); 3037 } 3038 return timer; 3039 } 3040 3041 /* 3042 * Get the KernelWakelockTimer associated with name, and create a new one if one 3043 * doesn't already exist. 3044 */ getKernelWakelockTimerLocked(String name)3045 public SamplingTimer getKernelWakelockTimerLocked(String name) { 3046 SamplingTimer kwlt = mKernelWakelockStats.get(name); 3047 if (kwlt == null) { 3048 kwlt = new SamplingTimer(mClocks, mOnBatteryScreenOffTimeBase); 3049 mKernelWakelockStats.put(name, kwlt); 3050 } 3051 return kwlt; 3052 } 3053 getKernelMemoryTimerLocked(long bucket)3054 public SamplingTimer getKernelMemoryTimerLocked(long bucket) { 3055 SamplingTimer kmt = mKernelMemoryStats.get(bucket); 3056 if (kmt == null) { 3057 kmt = new SamplingTimer(mClocks, mOnBatteryTimeBase); 3058 mKernelMemoryStats.put(bucket, kmt); 3059 } 3060 return kmt; 3061 } 3062 writeHistoryTag(HistoryTag tag)3063 private int writeHistoryTag(HistoryTag tag) { 3064 Integer idxObj = mHistoryTagPool.get(tag); 3065 int idx; 3066 if (idxObj != null) { 3067 idx = idxObj; 3068 } else { 3069 idx = mNextHistoryTagIdx; 3070 HistoryTag key = new HistoryTag(); 3071 key.setTo(tag); 3072 tag.poolIdx = idx; 3073 mHistoryTagPool.put(key, idx); 3074 mNextHistoryTagIdx++; 3075 mNumHistoryTagChars += key.string.length() + 1; 3076 } 3077 return idx; 3078 } 3079 readHistoryTag(int index, HistoryTag tag)3080 private void readHistoryTag(int index, HistoryTag tag) { 3081 if (index < mReadHistoryStrings.length) { 3082 tag.string = mReadHistoryStrings[index]; 3083 tag.uid = mReadHistoryUids[index]; 3084 } else { 3085 tag.string = null; 3086 tag.uid = 0; 3087 } 3088 tag.poolIdx = index; 3089 } 3090 3091 /* 3092 The history delta format uses flags to denote further data in subsequent ints in the parcel. 3093 3094 There is always the first token, which may contain the delta time, or an indicator of 3095 the length of the time (int or long) following this token. 3096 3097 First token: always present, 3098 31 23 15 7 0 3099 █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█ 3100 3101 T: the delta time if it is <= 0x7fffd. Otherwise 0x7fffe indicates an int immediately 3102 follows containing the time, and 0x7ffff indicates a long immediately follows with the 3103 delta time. 3104 A: battery level changed and an int follows with battery data. 3105 B: state changed and an int follows with state change data. 3106 C: state2 has changed and an int follows with state2 change data. 3107 D: wakelock/wakereason has changed and an wakelock/wakereason struct follows. 3108 E: event data has changed and an event struct follows. 3109 F: battery charge in coulombs has changed and an int with the charge follows. 3110 G: state flag denoting that the mobile radio was active. 3111 H: state flag denoting that the wifi radio was active. 3112 I: state flag denoting that a wifi scan occurred. 3113 J: state flag denoting that a wifi full lock was held. 3114 K: state flag denoting that the gps was on. 3115 L: state flag denoting that a wakelock was held. 3116 M: state flag denoting that the cpu was running. 3117 3118 Time int/long: if T in the first token is 0x7ffff or 0x7fffe, then an int or long follows 3119 with the time delta. 3120 3121 Battery level int: if A in the first token is set, 3122 31 23 15 7 0 3123 █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█ 3124 3125 D: indicates that extra history details follow. 3126 V: the battery voltage. 3127 T: the battery temperature. 3128 L: the battery level (out of 100). 3129 3130 State change int: if B in the first token is set, 3131 31 23 15 7 0 3132 █S|S|S|H|H|H|P|P█F|E|D|C|B| | |A█ | | | | | | | █ | | | | | | | █ 3133 3134 A: wifi multicast was on. 3135 B: battery was plugged in. 3136 C: screen was on. 3137 D: phone was scanning for signal. 3138 E: audio was on. 3139 F: a sensor was active. 3140 3141 State2 change int: if C in the first token is set, 3142 31 23 15 7 0 3143 █M|L|K|J|I|H|H|G█F|E|D|C| | | | █ | | | | | | | █ |B|B|B|A|A|A|A█ 3144 3145 A: 4 bits indicating the wifi supplicant state: {@link BatteryStats#WIFI_SUPPL_STATE_NAMES}. 3146 B: 3 bits indicating the wifi signal strength: 0, 1, 2, 3, 4. 3147 C: a bluetooth scan was active. 3148 D: the camera was active. 3149 E: bluetooth was on. 3150 F: a phone call was active. 3151 G: the device was charging. 3152 H: 2 bits indicating the device-idle (doze) state: off, light, full 3153 I: the flashlight was on. 3154 J: wifi was on. 3155 K: wifi was running. 3156 L: video was playing. 3157 M: power save mode was on. 3158 3159 Wakelock/wakereason struct: if D in the first token is set, 3160 TODO(adamlesinski): describe wakelock/wakereason struct. 3161 3162 Event struct: if E in the first token is set, 3163 TODO(adamlesinski): describe the event struct. 3164 3165 History step details struct: if D in the battery level int is set, 3166 TODO(adamlesinski): describe the history step details struct. 3167 3168 Battery charge int: if F in the first token is set, an int representing the battery charge 3169 in coulombs follows. 3170 */ 3171 3172 // Part of initial delta int that specifies the time delta. 3173 static final int DELTA_TIME_MASK = 0x7ffff; 3174 static final int DELTA_TIME_LONG = 0x7ffff; // The delta is a following long 3175 static final int DELTA_TIME_INT = 0x7fffe; // The delta is a following int 3176 static final int DELTA_TIME_ABS = 0x7fffd; // Following is an entire abs update. 3177 // Flag in delta int: a new battery level int follows. 3178 static final int DELTA_BATTERY_LEVEL_FLAG = 0x00080000; 3179 // Flag in delta int: a new full state and battery status int follows. 3180 static final int DELTA_STATE_FLAG = 0x00100000; 3181 // Flag in delta int: a new full state2 int follows. 3182 static final int DELTA_STATE2_FLAG = 0x00200000; 3183 // Flag in delta int: contains a wakelock or wakeReason tag. 3184 static final int DELTA_WAKELOCK_FLAG = 0x00400000; 3185 // Flag in delta int: contains an event description. 3186 static final int DELTA_EVENT_FLAG = 0x00800000; 3187 // Flag in delta int: contains the battery charge count in uAh. 3188 static final int DELTA_BATTERY_CHARGE_FLAG = 0x01000000; 3189 // These upper bits are the frequently changing state bits. 3190 static final int DELTA_STATE_MASK = 0xfe000000; 3191 3192 // These are the pieces of battery state that are packed in to the upper bits of 3193 // the state int that have been packed in to the first delta int. They must fit 3194 // in STATE_BATTERY_MASK. 3195 static final int STATE_BATTERY_MASK = 0xff000000; 3196 static final int STATE_BATTERY_STATUS_MASK = 0x00000007; 3197 static final int STATE_BATTERY_STATUS_SHIFT = 29; 3198 static final int STATE_BATTERY_HEALTH_MASK = 0x00000007; 3199 static final int STATE_BATTERY_HEALTH_SHIFT = 26; 3200 static final int STATE_BATTERY_PLUG_MASK = 0x00000003; 3201 static final int STATE_BATTERY_PLUG_SHIFT = 24; 3202 3203 // We use the low bit of the battery state int to indicate that we have full details 3204 // from a battery level change. 3205 static final int BATTERY_DELTA_LEVEL_FLAG = 0x00000001; 3206 writeHistoryDelta(Parcel dest, HistoryItem cur, HistoryItem last)3207 public void writeHistoryDelta(Parcel dest, HistoryItem cur, HistoryItem last) { 3208 if (last == null || cur.cmd != HistoryItem.CMD_UPDATE) { 3209 dest.writeInt(DELTA_TIME_ABS); 3210 cur.writeToParcel(dest, 0); 3211 return; 3212 } 3213 3214 final long deltaTime = cur.time - last.time; 3215 final int lastBatteryLevelInt = buildBatteryLevelInt(last); 3216 final int lastStateInt = buildStateInt(last); 3217 3218 int deltaTimeToken; 3219 if (deltaTime < 0 || deltaTime > Integer.MAX_VALUE) { 3220 deltaTimeToken = DELTA_TIME_LONG; 3221 } else if (deltaTime >= DELTA_TIME_ABS) { 3222 deltaTimeToken = DELTA_TIME_INT; 3223 } else { 3224 deltaTimeToken = (int)deltaTime; 3225 } 3226 int firstToken = deltaTimeToken | (cur.states&DELTA_STATE_MASK); 3227 final int includeStepDetails = mLastHistoryStepLevel > cur.batteryLevel 3228 ? BATTERY_DELTA_LEVEL_FLAG : 0; 3229 final boolean computeStepDetails = includeStepDetails != 0 3230 || mLastHistoryStepDetails == null; 3231 final int batteryLevelInt = buildBatteryLevelInt(cur) | includeStepDetails; 3232 final boolean batteryLevelIntChanged = batteryLevelInt != lastBatteryLevelInt; 3233 if (batteryLevelIntChanged) { 3234 firstToken |= DELTA_BATTERY_LEVEL_FLAG; 3235 } 3236 final int stateInt = buildStateInt(cur); 3237 final boolean stateIntChanged = stateInt != lastStateInt; 3238 if (stateIntChanged) { 3239 firstToken |= DELTA_STATE_FLAG; 3240 } 3241 final boolean state2IntChanged = cur.states2 != last.states2; 3242 if (state2IntChanged) { 3243 firstToken |= DELTA_STATE2_FLAG; 3244 } 3245 if (cur.wakelockTag != null || cur.wakeReasonTag != null) { 3246 firstToken |= DELTA_WAKELOCK_FLAG; 3247 } 3248 if (cur.eventCode != HistoryItem.EVENT_NONE) { 3249 firstToken |= DELTA_EVENT_FLAG; 3250 } 3251 3252 final boolean batteryChargeChanged = cur.batteryChargeUAh != last.batteryChargeUAh; 3253 if (batteryChargeChanged) { 3254 firstToken |= DELTA_BATTERY_CHARGE_FLAG; 3255 } 3256 dest.writeInt(firstToken); 3257 if (DEBUG) Slog.i(TAG, "WRITE DELTA: firstToken=0x" + Integer.toHexString(firstToken) 3258 + " deltaTime=" + deltaTime); 3259 3260 if (deltaTimeToken >= DELTA_TIME_INT) { 3261 if (deltaTimeToken == DELTA_TIME_INT) { 3262 if (DEBUG) Slog.i(TAG, "WRITE DELTA: int deltaTime=" + (int)deltaTime); 3263 dest.writeInt((int)deltaTime); 3264 } else { 3265 if (DEBUG) Slog.i(TAG, "WRITE DELTA: long deltaTime=" + deltaTime); 3266 dest.writeLong(deltaTime); 3267 } 3268 } 3269 if (batteryLevelIntChanged) { 3270 dest.writeInt(batteryLevelInt); 3271 if (DEBUG) Slog.i(TAG, "WRITE DELTA: batteryToken=0x" 3272 + Integer.toHexString(batteryLevelInt) 3273 + " batteryLevel=" + cur.batteryLevel 3274 + " batteryTemp=" + cur.batteryTemperature 3275 + " batteryVolt=" + (int)cur.batteryVoltage); 3276 } 3277 if (stateIntChanged) { 3278 dest.writeInt(stateInt); 3279 if (DEBUG) Slog.i(TAG, "WRITE DELTA: stateToken=0x" 3280 + Integer.toHexString(stateInt) 3281 + " batteryStatus=" + cur.batteryStatus 3282 + " batteryHealth=" + cur.batteryHealth 3283 + " batteryPlugType=" + cur.batteryPlugType 3284 + " states=0x" + Integer.toHexString(cur.states)); 3285 } 3286 if (state2IntChanged) { 3287 dest.writeInt(cur.states2); 3288 if (DEBUG) Slog.i(TAG, "WRITE DELTA: states2=0x" 3289 + Integer.toHexString(cur.states2)); 3290 } 3291 if (cur.wakelockTag != null || cur.wakeReasonTag != null) { 3292 int wakeLockIndex; 3293 int wakeReasonIndex; 3294 if (cur.wakelockTag != null) { 3295 wakeLockIndex = writeHistoryTag(cur.wakelockTag); 3296 if (DEBUG) Slog.i(TAG, "WRITE DELTA: wakelockTag=#" + cur.wakelockTag.poolIdx 3297 + " " + cur.wakelockTag.uid + ":" + cur.wakelockTag.string); 3298 } else { 3299 wakeLockIndex = 0xffff; 3300 } 3301 if (cur.wakeReasonTag != null) { 3302 wakeReasonIndex = writeHistoryTag(cur.wakeReasonTag); 3303 if (DEBUG) Slog.i(TAG, "WRITE DELTA: wakeReasonTag=#" + cur.wakeReasonTag.poolIdx 3304 + " " + cur.wakeReasonTag.uid + ":" + cur.wakeReasonTag.string); 3305 } else { 3306 wakeReasonIndex = 0xffff; 3307 } 3308 dest.writeInt((wakeReasonIndex<<16) | wakeLockIndex); 3309 } 3310 if (cur.eventCode != HistoryItem.EVENT_NONE) { 3311 int index = writeHistoryTag(cur.eventTag); 3312 int codeAndIndex = (cur.eventCode&0xffff) | (index<<16); 3313 dest.writeInt(codeAndIndex); 3314 if (DEBUG) Slog.i(TAG, "WRITE DELTA: event=" + cur.eventCode + " tag=#" 3315 + cur.eventTag.poolIdx + " " + cur.eventTag.uid + ":" 3316 + cur.eventTag.string); 3317 } 3318 if (computeStepDetails) { 3319 if (mPlatformIdleStateCallback != null) { 3320 mCurHistoryStepDetails.statPlatformIdleState = 3321 mPlatformIdleStateCallback.getPlatformLowPowerStats(); 3322 if (DEBUG) Slog.i(TAG, "WRITE PlatformIdleState:" + 3323 mCurHistoryStepDetails.statPlatformIdleState); 3324 3325 mCurHistoryStepDetails.statSubsystemPowerState = 3326 mPlatformIdleStateCallback.getSubsystemLowPowerStats(); 3327 if (DEBUG) Slog.i(TAG, "WRITE SubsystemPowerState:" + 3328 mCurHistoryStepDetails.statSubsystemPowerState); 3329 3330 } 3331 computeHistoryStepDetails(mCurHistoryStepDetails, mLastHistoryStepDetails); 3332 if (includeStepDetails != 0) { 3333 mCurHistoryStepDetails.writeToParcel(dest); 3334 } 3335 cur.stepDetails = mCurHistoryStepDetails; 3336 mLastHistoryStepDetails = mCurHistoryStepDetails; 3337 } else { 3338 cur.stepDetails = null; 3339 } 3340 if (mLastHistoryStepLevel < cur.batteryLevel) { 3341 mLastHistoryStepDetails = null; 3342 } 3343 mLastHistoryStepLevel = cur.batteryLevel; 3344 3345 if (batteryChargeChanged) { 3346 if (DEBUG) Slog.i(TAG, "WRITE DELTA: batteryChargeUAh=" + cur.batteryChargeUAh); 3347 dest.writeInt(cur.batteryChargeUAh); 3348 } 3349 dest.writeDouble(cur.modemRailChargeMah); 3350 dest.writeDouble(cur.wifiRailChargeMah); 3351 } 3352 buildBatteryLevelInt(HistoryItem h)3353 private int buildBatteryLevelInt(HistoryItem h) { 3354 return ((((int)h.batteryLevel)<<25)&0xfe000000) 3355 | ((((int)h.batteryTemperature)<<15)&0x01ff8000) 3356 | ((((int)h.batteryVoltage)<<1)&0x00007ffe); 3357 } 3358 readBatteryLevelInt(int batteryLevelInt, HistoryItem out)3359 private void readBatteryLevelInt(int batteryLevelInt, HistoryItem out) { 3360 out.batteryLevel = (byte)((batteryLevelInt & 0xfe000000) >>> 25); 3361 out.batteryTemperature = (short)((batteryLevelInt & 0x01ff8000) >>> 15); 3362 out.batteryVoltage = (char)((batteryLevelInt & 0x00007ffe) >>> 1); 3363 } 3364 buildStateInt(HistoryItem h)3365 private int buildStateInt(HistoryItem h) { 3366 int plugType = 0; 3367 if ((h.batteryPlugType&BatteryManager.BATTERY_PLUGGED_AC) != 0) { 3368 plugType = 1; 3369 } else if ((h.batteryPlugType&BatteryManager.BATTERY_PLUGGED_USB) != 0) { 3370 plugType = 2; 3371 } else if ((h.batteryPlugType&BatteryManager.BATTERY_PLUGGED_WIRELESS) != 0) { 3372 plugType = 3; 3373 } 3374 return ((h.batteryStatus&STATE_BATTERY_STATUS_MASK)<<STATE_BATTERY_STATUS_SHIFT) 3375 | ((h.batteryHealth&STATE_BATTERY_HEALTH_MASK)<<STATE_BATTERY_HEALTH_SHIFT) 3376 | ((plugType&STATE_BATTERY_PLUG_MASK)<<STATE_BATTERY_PLUG_SHIFT) 3377 | (h.states&(~STATE_BATTERY_MASK)); 3378 } 3379 computeHistoryStepDetails(final HistoryStepDetails out, final HistoryStepDetails last)3380 private void computeHistoryStepDetails(final HistoryStepDetails out, 3381 final HistoryStepDetails last) { 3382 final HistoryStepDetails tmp = last != null ? mTmpHistoryStepDetails : out; 3383 3384 // Perform a CPU update right after we do this collection, so we have started 3385 // collecting good data for the next step. 3386 requestImmediateCpuUpdate(); 3387 3388 if (last == null) { 3389 // We are not generating a delta, so all we need to do is reset the stats 3390 // we will later be doing a delta from. 3391 final int NU = mUidStats.size(); 3392 for (int i=0; i<NU; i++) { 3393 final BatteryStatsImpl.Uid uid = mUidStats.valueAt(i); 3394 uid.mLastStepUserTime = uid.mCurStepUserTime; 3395 uid.mLastStepSystemTime = uid.mCurStepSystemTime; 3396 } 3397 mLastStepCpuUserTime = mCurStepCpuUserTime; 3398 mLastStepCpuSystemTime = mCurStepCpuSystemTime; 3399 mLastStepStatUserTime = mCurStepStatUserTime; 3400 mLastStepStatSystemTime = mCurStepStatSystemTime; 3401 mLastStepStatIOWaitTime = mCurStepStatIOWaitTime; 3402 mLastStepStatIrqTime = mCurStepStatIrqTime; 3403 mLastStepStatSoftIrqTime = mCurStepStatSoftIrqTime; 3404 mLastStepStatIdleTime = mCurStepStatIdleTime; 3405 tmp.clear(); 3406 return; 3407 } 3408 if (DEBUG) { 3409 Slog.d(TAG, "Step stats last: user=" + mLastStepCpuUserTime + " sys=" 3410 + mLastStepStatSystemTime + " io=" + mLastStepStatIOWaitTime 3411 + " irq=" + mLastStepStatIrqTime + " sirq=" 3412 + mLastStepStatSoftIrqTime + " idle=" + mLastStepStatIdleTime); 3413 Slog.d(TAG, "Step stats cur: user=" + mCurStepCpuUserTime + " sys=" 3414 + mCurStepStatSystemTime + " io=" + mCurStepStatIOWaitTime 3415 + " irq=" + mCurStepStatIrqTime + " sirq=" 3416 + mCurStepStatSoftIrqTime + " idle=" + mCurStepStatIdleTime); 3417 } 3418 out.userTime = (int)(mCurStepCpuUserTime - mLastStepCpuUserTime); 3419 out.systemTime = (int)(mCurStepCpuSystemTime - mLastStepCpuSystemTime); 3420 out.statUserTime = (int)(mCurStepStatUserTime - mLastStepStatUserTime); 3421 out.statSystemTime = (int)(mCurStepStatSystemTime - mLastStepStatSystemTime); 3422 out.statIOWaitTime = (int)(mCurStepStatIOWaitTime - mLastStepStatIOWaitTime); 3423 out.statIrqTime = (int)(mCurStepStatIrqTime - mLastStepStatIrqTime); 3424 out.statSoftIrqTime = (int)(mCurStepStatSoftIrqTime - mLastStepStatSoftIrqTime); 3425 out.statIdlTime = (int)(mCurStepStatIdleTime - mLastStepStatIdleTime); 3426 out.appCpuUid1 = out.appCpuUid2 = out.appCpuUid3 = -1; 3427 out.appCpuUTime1 = out.appCpuUTime2 = out.appCpuUTime3 = 0; 3428 out.appCpuSTime1 = out.appCpuSTime2 = out.appCpuSTime3 = 0; 3429 final int NU = mUidStats.size(); 3430 for (int i=0; i<NU; i++) { 3431 final BatteryStatsImpl.Uid uid = mUidStats.valueAt(i); 3432 final int totalUTime = (int)(uid.mCurStepUserTime - uid.mLastStepUserTime); 3433 final int totalSTime = (int)(uid.mCurStepSystemTime - uid.mLastStepSystemTime); 3434 final int totalTime = totalUTime + totalSTime; 3435 uid.mLastStepUserTime = uid.mCurStepUserTime; 3436 uid.mLastStepSystemTime = uid.mCurStepSystemTime; 3437 if (totalTime <= (out.appCpuUTime3+out.appCpuSTime3)) { 3438 continue; 3439 } 3440 if (totalTime <= (out.appCpuUTime2+out.appCpuSTime2)) { 3441 out.appCpuUid3 = uid.mUid; 3442 out.appCpuUTime3 = totalUTime; 3443 out.appCpuSTime3 = totalSTime; 3444 } else { 3445 out.appCpuUid3 = out.appCpuUid2; 3446 out.appCpuUTime3 = out.appCpuUTime2; 3447 out.appCpuSTime3 = out.appCpuSTime2; 3448 if (totalTime <= (out.appCpuUTime1+out.appCpuSTime1)) { 3449 out.appCpuUid2 = uid.mUid; 3450 out.appCpuUTime2 = totalUTime; 3451 out.appCpuSTime2 = totalSTime; 3452 } else { 3453 out.appCpuUid2 = out.appCpuUid1; 3454 out.appCpuUTime2 = out.appCpuUTime1; 3455 out.appCpuSTime2 = out.appCpuSTime1; 3456 out.appCpuUid1 = uid.mUid; 3457 out.appCpuUTime1 = totalUTime; 3458 out.appCpuSTime1 = totalSTime; 3459 } 3460 } 3461 } 3462 mLastStepCpuUserTime = mCurStepCpuUserTime; 3463 mLastStepCpuSystemTime = mCurStepCpuSystemTime; 3464 mLastStepStatUserTime = mCurStepStatUserTime; 3465 mLastStepStatSystemTime = mCurStepStatSystemTime; 3466 mLastStepStatIOWaitTime = mCurStepStatIOWaitTime; 3467 mLastStepStatIrqTime = mCurStepStatIrqTime; 3468 mLastStepStatSoftIrqTime = mCurStepStatSoftIrqTime; 3469 mLastStepStatIdleTime = mCurStepStatIdleTime; 3470 } 3471 readHistoryDelta(Parcel src, HistoryItem cur)3472 public void readHistoryDelta(Parcel src, HistoryItem cur) { 3473 int firstToken = src.readInt(); 3474 int deltaTimeToken = firstToken&DELTA_TIME_MASK; 3475 cur.cmd = HistoryItem.CMD_UPDATE; 3476 cur.numReadInts = 1; 3477 if (DEBUG) Slog.i(TAG, "READ DELTA: firstToken=0x" + Integer.toHexString(firstToken) 3478 + " deltaTimeToken=" + deltaTimeToken); 3479 3480 if (deltaTimeToken < DELTA_TIME_ABS) { 3481 cur.time += deltaTimeToken; 3482 } else if (deltaTimeToken == DELTA_TIME_ABS) { 3483 cur.time = src.readLong(); 3484 cur.numReadInts += 2; 3485 if (DEBUG) Slog.i(TAG, "READ DELTA: ABS time=" + cur.time); 3486 cur.readFromParcel(src); 3487 return; 3488 } else if (deltaTimeToken == DELTA_TIME_INT) { 3489 int delta = src.readInt(); 3490 cur.time += delta; 3491 cur.numReadInts += 1; 3492 if (DEBUG) Slog.i(TAG, "READ DELTA: time delta=" + delta + " new time=" + cur.time); 3493 } else { 3494 long delta = src.readLong(); 3495 if (DEBUG) Slog.i(TAG, "READ DELTA: time delta=" + delta + " new time=" + cur.time); 3496 cur.time += delta; 3497 cur.numReadInts += 2; 3498 } 3499 3500 final int batteryLevelInt; 3501 if ((firstToken&DELTA_BATTERY_LEVEL_FLAG) != 0) { 3502 batteryLevelInt = src.readInt(); 3503 readBatteryLevelInt(batteryLevelInt, cur); 3504 cur.numReadInts += 1; 3505 if (DEBUG) Slog.i(TAG, "READ DELTA: batteryToken=0x" 3506 + Integer.toHexString(batteryLevelInt) 3507 + " batteryLevel=" + cur.batteryLevel 3508 + " batteryTemp=" + cur.batteryTemperature 3509 + " batteryVolt=" + (int)cur.batteryVoltage); 3510 } else { 3511 batteryLevelInt = 0; 3512 } 3513 3514 if ((firstToken&DELTA_STATE_FLAG) != 0) { 3515 int stateInt = src.readInt(); 3516 cur.states = (firstToken&DELTA_STATE_MASK) | (stateInt&(~STATE_BATTERY_MASK)); 3517 cur.batteryStatus = (byte)((stateInt>>STATE_BATTERY_STATUS_SHIFT) 3518 & STATE_BATTERY_STATUS_MASK); 3519 cur.batteryHealth = (byte)((stateInt>>STATE_BATTERY_HEALTH_SHIFT) 3520 & STATE_BATTERY_HEALTH_MASK); 3521 cur.batteryPlugType = (byte)((stateInt>>STATE_BATTERY_PLUG_SHIFT) 3522 & STATE_BATTERY_PLUG_MASK); 3523 switch (cur.batteryPlugType) { 3524 case 1: 3525 cur.batteryPlugType = BatteryManager.BATTERY_PLUGGED_AC; 3526 break; 3527 case 2: 3528 cur.batteryPlugType = BatteryManager.BATTERY_PLUGGED_USB; 3529 break; 3530 case 3: 3531 cur.batteryPlugType = BatteryManager.BATTERY_PLUGGED_WIRELESS; 3532 break; 3533 } 3534 cur.numReadInts += 1; 3535 if (DEBUG) Slog.i(TAG, "READ DELTA: stateToken=0x" 3536 + Integer.toHexString(stateInt) 3537 + " batteryStatus=" + cur.batteryStatus 3538 + " batteryHealth=" + cur.batteryHealth 3539 + " batteryPlugType=" + cur.batteryPlugType 3540 + " states=0x" + Integer.toHexString(cur.states)); 3541 } else { 3542 cur.states = (firstToken&DELTA_STATE_MASK) | (cur.states&(~STATE_BATTERY_MASK)); 3543 } 3544 3545 if ((firstToken&DELTA_STATE2_FLAG) != 0) { 3546 cur.states2 = src.readInt(); 3547 if (DEBUG) Slog.i(TAG, "READ DELTA: states2=0x" 3548 + Integer.toHexString(cur.states2)); 3549 } 3550 3551 if ((firstToken&DELTA_WAKELOCK_FLAG) != 0) { 3552 int indexes = src.readInt(); 3553 int wakeLockIndex = indexes&0xffff; 3554 int wakeReasonIndex = (indexes>>16)&0xffff; 3555 if (wakeLockIndex != 0xffff) { 3556 cur.wakelockTag = cur.localWakelockTag; 3557 readHistoryTag(wakeLockIndex, cur.wakelockTag); 3558 if (DEBUG) Slog.i(TAG, "READ DELTA: wakelockTag=#" + cur.wakelockTag.poolIdx 3559 + " " + cur.wakelockTag.uid + ":" + cur.wakelockTag.string); 3560 } else { 3561 cur.wakelockTag = null; 3562 } 3563 if (wakeReasonIndex != 0xffff) { 3564 cur.wakeReasonTag = cur.localWakeReasonTag; 3565 readHistoryTag(wakeReasonIndex, cur.wakeReasonTag); 3566 if (DEBUG) Slog.i(TAG, "READ DELTA: wakeReasonTag=#" + cur.wakeReasonTag.poolIdx 3567 + " " + cur.wakeReasonTag.uid + ":" + cur.wakeReasonTag.string); 3568 } else { 3569 cur.wakeReasonTag = null; 3570 } 3571 cur.numReadInts += 1; 3572 } else { 3573 cur.wakelockTag = null; 3574 cur.wakeReasonTag = null; 3575 } 3576 3577 if ((firstToken&DELTA_EVENT_FLAG) != 0) { 3578 cur.eventTag = cur.localEventTag; 3579 final int codeAndIndex = src.readInt(); 3580 cur.eventCode = (codeAndIndex&0xffff); 3581 final int index = ((codeAndIndex>>16)&0xffff); 3582 readHistoryTag(index, cur.eventTag); 3583 cur.numReadInts += 1; 3584 if (DEBUG) Slog.i(TAG, "READ DELTA: event=" + cur.eventCode + " tag=#" 3585 + cur.eventTag.poolIdx + " " + cur.eventTag.uid + ":" 3586 + cur.eventTag.string); 3587 } else { 3588 cur.eventCode = HistoryItem.EVENT_NONE; 3589 } 3590 3591 if ((batteryLevelInt&BATTERY_DELTA_LEVEL_FLAG) != 0) { 3592 cur.stepDetails = mReadHistoryStepDetails; 3593 cur.stepDetails.readFromParcel(src); 3594 } else { 3595 cur.stepDetails = null; 3596 } 3597 3598 if ((firstToken&DELTA_BATTERY_CHARGE_FLAG) != 0) { 3599 cur.batteryChargeUAh = src.readInt(); 3600 } 3601 cur.modemRailChargeMah = src.readDouble(); 3602 cur.wifiRailChargeMah = src.readDouble(); 3603 } 3604 3605 @Override commitCurrentHistoryBatchLocked()3606 public void commitCurrentHistoryBatchLocked() { 3607 mHistoryLastWritten.cmd = HistoryItem.CMD_NULL; 3608 } 3609 createFakeHistoryEvents(long numEvents)3610 public void createFakeHistoryEvents(long numEvents) { 3611 for(long i = 0; i < numEvents; i++) { 3612 noteLongPartialWakelockStart("name1", "historyName1", 1000); 3613 noteLongPartialWakelockFinish("name1", "historyName1", 1000); 3614 } 3615 } 3616 addHistoryBufferLocked(long elapsedRealtimeMs, HistoryItem cur)3617 void addHistoryBufferLocked(long elapsedRealtimeMs, HistoryItem cur) { 3618 if (!mHaveBatteryLevel || !mRecordingHistory) { 3619 return; 3620 } 3621 3622 final long timeDiff = (mHistoryBaseTime+elapsedRealtimeMs) - mHistoryLastWritten.time; 3623 final int diffStates = mHistoryLastWritten.states^(cur.states&mActiveHistoryStates); 3624 final int diffStates2 = mHistoryLastWritten.states2^(cur.states2&mActiveHistoryStates2); 3625 final int lastDiffStates = mHistoryLastWritten.states^mHistoryLastLastWritten.states; 3626 final int lastDiffStates2 = mHistoryLastWritten.states2^mHistoryLastLastWritten.states2; 3627 if (DEBUG) Slog.i(TAG, "ADD: tdelta=" + timeDiff + " diff=" 3628 + Integer.toHexString(diffStates) + " lastDiff=" 3629 + Integer.toHexString(lastDiffStates) + " diff2=" 3630 + Integer.toHexString(diffStates2) + " lastDiff2=" 3631 + Integer.toHexString(lastDiffStates2)); 3632 if (mHistoryBufferLastPos >= 0 && mHistoryLastWritten.cmd == HistoryItem.CMD_UPDATE 3633 && timeDiff < 1000 && (diffStates&lastDiffStates) == 0 3634 && (diffStates2&lastDiffStates2) == 0 3635 && (mHistoryLastWritten.wakelockTag == null || cur.wakelockTag == null) 3636 && (mHistoryLastWritten.wakeReasonTag == null || cur.wakeReasonTag == null) 3637 && mHistoryLastWritten.stepDetails == null 3638 && (mHistoryLastWritten.eventCode == HistoryItem.EVENT_NONE 3639 || cur.eventCode == HistoryItem.EVENT_NONE) 3640 && mHistoryLastWritten.batteryLevel == cur.batteryLevel 3641 && mHistoryLastWritten.batteryStatus == cur.batteryStatus 3642 && mHistoryLastWritten.batteryHealth == cur.batteryHealth 3643 && mHistoryLastWritten.batteryPlugType == cur.batteryPlugType 3644 && mHistoryLastWritten.batteryTemperature == cur.batteryTemperature 3645 && mHistoryLastWritten.batteryVoltage == cur.batteryVoltage) { 3646 // We can merge this new change in with the last one. Merging is 3647 // allowed as long as only the states have changed, and within those states 3648 // as long as no bit has changed both between now and the last entry, as 3649 // well as the last entry and the one before it (so we capture any toggles). 3650 if (DEBUG) Slog.i(TAG, "ADD: rewinding back to " + mHistoryBufferLastPos); 3651 mHistoryBuffer.setDataSize(mHistoryBufferLastPos); 3652 mHistoryBuffer.setDataPosition(mHistoryBufferLastPos); 3653 mHistoryBufferLastPos = -1; 3654 elapsedRealtimeMs = mHistoryLastWritten.time - mHistoryBaseTime; 3655 // If the last written history had a wakelock tag, we need to retain it. 3656 // Note that the condition above made sure that we aren't in a case where 3657 // both it and the current history item have a wakelock tag. 3658 if (mHistoryLastWritten.wakelockTag != null) { 3659 cur.wakelockTag = cur.localWakelockTag; 3660 cur.wakelockTag.setTo(mHistoryLastWritten.wakelockTag); 3661 } 3662 // If the last written history had a wake reason tag, we need to retain it. 3663 // Note that the condition above made sure that we aren't in a case where 3664 // both it and the current history item have a wakelock tag. 3665 if (mHistoryLastWritten.wakeReasonTag != null) { 3666 cur.wakeReasonTag = cur.localWakeReasonTag; 3667 cur.wakeReasonTag.setTo(mHistoryLastWritten.wakeReasonTag); 3668 } 3669 // If the last written history had an event, we need to retain it. 3670 // Note that the condition above made sure that we aren't in a case where 3671 // both it and the current history item have an event. 3672 if (mHistoryLastWritten.eventCode != HistoryItem.EVENT_NONE) { 3673 cur.eventCode = mHistoryLastWritten.eventCode; 3674 cur.eventTag = cur.localEventTag; 3675 cur.eventTag.setTo(mHistoryLastWritten.eventTag); 3676 } 3677 mHistoryLastWritten.setTo(mHistoryLastLastWritten); 3678 } 3679 final int dataSize = mHistoryBuffer.dataSize(); 3680 3681 if (dataSize >= mConstants.MAX_HISTORY_BUFFER) { 3682 //open a new history file. 3683 final long start = SystemClock.uptimeMillis(); 3684 writeHistoryLocked(true); 3685 if (DEBUG) { 3686 Slog.d(TAG, "addHistoryBufferLocked writeHistoryLocked takes ms:" 3687 + (SystemClock.uptimeMillis() - start)); 3688 } 3689 mBatteryStatsHistory.startNextFile(); 3690 mHistoryBuffer.setDataSize(0); 3691 mHistoryBuffer.setDataPosition(0); 3692 mHistoryBuffer.setDataCapacity(mConstants.MAX_HISTORY_BUFFER / 2); 3693 mHistoryBufferLastPos = -1; 3694 final long elapsedRealtime = mClocks.elapsedRealtime(); 3695 final long uptime = mClocks.uptimeMillis(); 3696 HistoryItem newItem = new HistoryItem(); 3697 newItem.setTo(cur); 3698 startRecordingHistory(elapsedRealtime, uptime, false); 3699 addHistoryBufferLocked(elapsedRealtimeMs, HistoryItem.CMD_UPDATE, newItem); 3700 return; 3701 } 3702 3703 if (dataSize == 0) { 3704 // The history is currently empty; we need it to start with a time stamp. 3705 cur.currentTime = System.currentTimeMillis(); 3706 addHistoryBufferLocked(elapsedRealtimeMs, HistoryItem.CMD_RESET, cur); 3707 } 3708 addHistoryBufferLocked(elapsedRealtimeMs, HistoryItem.CMD_UPDATE, cur); 3709 } 3710 addHistoryBufferLocked(long elapsedRealtimeMs, byte cmd, HistoryItem cur)3711 private void addHistoryBufferLocked(long elapsedRealtimeMs, byte cmd, HistoryItem cur) { 3712 if (mIteratingHistory) { 3713 throw new IllegalStateException("Can't do this while iterating history!"); 3714 } 3715 mHistoryBufferLastPos = mHistoryBuffer.dataPosition(); 3716 mHistoryLastLastWritten.setTo(mHistoryLastWritten); 3717 mHistoryLastWritten.setTo(mHistoryBaseTime + elapsedRealtimeMs, cmd, cur); 3718 mHistoryLastWritten.states &= mActiveHistoryStates; 3719 mHistoryLastWritten.states2 &= mActiveHistoryStates2; 3720 writeHistoryDelta(mHistoryBuffer, mHistoryLastWritten, mHistoryLastLastWritten); 3721 mLastHistoryElapsedRealtime = elapsedRealtimeMs; 3722 cur.wakelockTag = null; 3723 cur.wakeReasonTag = null; 3724 cur.eventCode = HistoryItem.EVENT_NONE; 3725 cur.eventTag = null; 3726 if (DEBUG_HISTORY) Slog.i(TAG, "Writing history buffer: was " + mHistoryBufferLastPos 3727 + " now " + mHistoryBuffer.dataPosition() 3728 + " size is now " + mHistoryBuffer.dataSize()); 3729 } 3730 3731 int mChangedStates = 0; 3732 int mChangedStates2 = 0; 3733 addHistoryRecordLocked(long elapsedRealtimeMs, long uptimeMs)3734 void addHistoryRecordLocked(long elapsedRealtimeMs, long uptimeMs) { 3735 if (mTrackRunningHistoryElapsedRealtime != 0) { 3736 final long diffElapsed = elapsedRealtimeMs - mTrackRunningHistoryElapsedRealtime; 3737 final long diffUptime = uptimeMs - mTrackRunningHistoryUptime; 3738 if (diffUptime < (diffElapsed-20)) { 3739 final long wakeElapsedTime = elapsedRealtimeMs - (diffElapsed - diffUptime); 3740 mHistoryAddTmp.setTo(mHistoryLastWritten); 3741 mHistoryAddTmp.wakelockTag = null; 3742 mHistoryAddTmp.wakeReasonTag = null; 3743 mHistoryAddTmp.eventCode = HistoryItem.EVENT_NONE; 3744 mHistoryAddTmp.states &= ~HistoryItem.STATE_CPU_RUNNING_FLAG; 3745 addHistoryRecordInnerLocked(wakeElapsedTime, mHistoryAddTmp); 3746 } 3747 } 3748 mHistoryCur.states |= HistoryItem.STATE_CPU_RUNNING_FLAG; 3749 mTrackRunningHistoryElapsedRealtime = elapsedRealtimeMs; 3750 mTrackRunningHistoryUptime = uptimeMs; 3751 addHistoryRecordInnerLocked(elapsedRealtimeMs, mHistoryCur); 3752 } 3753 addHistoryRecordInnerLocked(long elapsedRealtimeMs, HistoryItem cur)3754 void addHistoryRecordInnerLocked(long elapsedRealtimeMs, HistoryItem cur) { 3755 addHistoryBufferLocked(elapsedRealtimeMs, cur); 3756 3757 if (!USE_OLD_HISTORY) { 3758 return; 3759 } 3760 3761 if (!mHaveBatteryLevel || !mRecordingHistory) { 3762 return; 3763 } 3764 3765 // If the current time is basically the same as the last time, 3766 // and no states have since the last recorded entry changed and 3767 // are now resetting back to their original value, then just collapse 3768 // into one record. 3769 if (mHistoryEnd != null && mHistoryEnd.cmd == HistoryItem.CMD_UPDATE 3770 && (mHistoryBaseTime+elapsedRealtimeMs) < (mHistoryEnd.time+1000) 3771 && ((mHistoryEnd.states^cur.states)&mChangedStates&mActiveHistoryStates) == 0 3772 && ((mHistoryEnd.states2^cur.states2)&mChangedStates2&mActiveHistoryStates2) == 0) { 3773 // If the current is the same as the one before, then we no 3774 // longer need the entry. 3775 if (mHistoryLastEnd != null && mHistoryLastEnd.cmd == HistoryItem.CMD_UPDATE 3776 && (mHistoryBaseTime+elapsedRealtimeMs) < (mHistoryEnd.time+500) 3777 && mHistoryLastEnd.sameNonEvent(cur)) { 3778 mHistoryLastEnd.next = null; 3779 mHistoryEnd.next = mHistoryCache; 3780 mHistoryCache = mHistoryEnd; 3781 mHistoryEnd = mHistoryLastEnd; 3782 mHistoryLastEnd = null; 3783 } else { 3784 mChangedStates |= mHistoryEnd.states^(cur.states&mActiveHistoryStates); 3785 mChangedStates2 |= mHistoryEnd.states^(cur.states2&mActiveHistoryStates2); 3786 mHistoryEnd.setTo(mHistoryEnd.time, HistoryItem.CMD_UPDATE, cur); 3787 } 3788 return; 3789 } 3790 3791 mChangedStates = 0; 3792 mChangedStates2 = 0; 3793 addHistoryBufferLocked(elapsedRealtimeMs, HistoryItem.CMD_UPDATE, cur); 3794 } 3795 addHistoryEventLocked(long elapsedRealtimeMs, long uptimeMs, int code, String name, int uid)3796 public void addHistoryEventLocked(long elapsedRealtimeMs, long uptimeMs, int code, 3797 String name, int uid) { 3798 mHistoryCur.eventCode = code; 3799 mHistoryCur.eventTag = mHistoryCur.localEventTag; 3800 mHistoryCur.eventTag.string = name; 3801 mHistoryCur.eventTag.uid = uid; 3802 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 3803 } 3804 addHistoryRecordLocked(long elapsedRealtimeMs, long uptimeMs, byte cmd, HistoryItem cur)3805 void addHistoryRecordLocked(long elapsedRealtimeMs, long uptimeMs, byte cmd, HistoryItem cur) { 3806 HistoryItem rec = mHistoryCache; 3807 if (rec != null) { 3808 mHistoryCache = rec.next; 3809 } else { 3810 rec = new HistoryItem(); 3811 } 3812 rec.setTo(mHistoryBaseTime + elapsedRealtimeMs, cmd, cur); 3813 3814 addHistoryRecordLocked(rec); 3815 } 3816 addHistoryRecordLocked(HistoryItem rec)3817 void addHistoryRecordLocked(HistoryItem rec) { 3818 mNumHistoryItems++; 3819 rec.next = null; 3820 mHistoryLastEnd = mHistoryEnd; 3821 if (mHistoryEnd != null) { 3822 mHistoryEnd.next = rec; 3823 mHistoryEnd = rec; 3824 } else { 3825 mHistory = mHistoryEnd = rec; 3826 } 3827 } 3828 clearHistoryLocked()3829 void clearHistoryLocked() { 3830 if (DEBUG_HISTORY) Slog.i(TAG, "********** CLEARING HISTORY!"); 3831 if (USE_OLD_HISTORY) { 3832 if (mHistory != null) { 3833 mHistoryEnd.next = mHistoryCache; 3834 mHistoryCache = mHistory; 3835 mHistory = mHistoryLastEnd = mHistoryEnd = null; 3836 } 3837 mNumHistoryItems = 0; 3838 } 3839 3840 mHistoryBaseTime = 0; 3841 mLastHistoryElapsedRealtime = 0; 3842 mTrackRunningHistoryElapsedRealtime = 0; 3843 mTrackRunningHistoryUptime = 0; 3844 3845 mHistoryBuffer.setDataSize(0); 3846 mHistoryBuffer.setDataPosition(0); 3847 mHistoryBuffer.setDataCapacity(mConstants.MAX_HISTORY_BUFFER / 2); 3848 mHistoryLastLastWritten.clear(); 3849 mHistoryLastWritten.clear(); 3850 mHistoryTagPool.clear(); 3851 mNextHistoryTagIdx = 0; 3852 mNumHistoryTagChars = 0; 3853 mHistoryBufferLastPos = -1; 3854 mActiveHistoryStates = 0xffffffff; 3855 mActiveHistoryStates2 = 0xffffffff; 3856 } 3857 3858 @GuardedBy("this") updateTimeBasesLocked(boolean unplugged, int screenState, long uptime, long realtime)3859 public void updateTimeBasesLocked(boolean unplugged, int screenState, long uptime, 3860 long realtime) { 3861 final boolean screenOff = !isScreenOn(screenState); 3862 final boolean updateOnBatteryTimeBase = unplugged != mOnBatteryTimeBase.isRunning(); 3863 final boolean updateOnBatteryScreenOffTimeBase = 3864 (unplugged && screenOff) != mOnBatteryScreenOffTimeBase.isRunning(); 3865 3866 if (updateOnBatteryScreenOffTimeBase || updateOnBatteryTimeBase) { 3867 if (updateOnBatteryScreenOffTimeBase) { 3868 updateKernelWakelocksLocked(); 3869 updateBatteryPropertiesLocked(); 3870 } 3871 // This if{} is only necessary due to SCREEN_OFF_RPM_STATS_ENABLED, which exists because 3872 // updateRpmStatsLocked is too slow to run each screen change. When the speed is 3873 // improved, remove the surrounding if{}. 3874 if (SCREEN_OFF_RPM_STATS_ENABLED || updateOnBatteryTimeBase) { 3875 updateRpmStatsLocked(); // if either OnBattery or OnBatteryScreenOff timebase changes. 3876 } 3877 if (DEBUG_ENERGY_CPU) { 3878 Slog.d(TAG, "Updating cpu time because screen is now " 3879 + Display.stateToString(screenState) 3880 + " and battery is " + (unplugged ? "on" : "off")); 3881 } 3882 3883 mOnBatteryTimeBase.setRunning(unplugged, uptime, realtime); 3884 if (updateOnBatteryTimeBase) { 3885 for (int i = mUidStats.size() - 1; i >= 0; --i) { 3886 mUidStats.valueAt(i).updateOnBatteryBgTimeBase(uptime, realtime); 3887 } 3888 } 3889 if (updateOnBatteryScreenOffTimeBase) { 3890 mOnBatteryScreenOffTimeBase.setRunning(unplugged && screenOff, uptime, realtime); 3891 for (int i = mUidStats.size() - 1; i >= 0; --i) { 3892 mUidStats.valueAt(i).updateOnBatteryScreenOffBgTimeBase(uptime, realtime); 3893 } 3894 } 3895 } 3896 } 3897 updateBatteryPropertiesLocked()3898 private void updateBatteryPropertiesLocked() { 3899 try { 3900 IBatteryPropertiesRegistrar registrar = IBatteryPropertiesRegistrar.Stub.asInterface( 3901 ServiceManager.getService("batteryproperties")); 3902 if (registrar != null) { 3903 registrar.scheduleUpdate(); 3904 } 3905 } catch (RemoteException e) { 3906 // Ignore. 3907 } 3908 } 3909 addIsolatedUidLocked(int isolatedUid, int appUid)3910 public void addIsolatedUidLocked(int isolatedUid, int appUid) { 3911 mIsolatedUids.put(isolatedUid, appUid); 3912 final Uid u = getUidStatsLocked(appUid); 3913 u.addIsolatedUid(isolatedUid); 3914 } 3915 3916 /** 3917 * Schedules a read of the latest cpu times before removing the isolated UID. 3918 * @see #removeIsolatedUidLocked(int) 3919 */ scheduleRemoveIsolatedUidLocked(int isolatedUid, int appUid)3920 public void scheduleRemoveIsolatedUidLocked(int isolatedUid, int appUid) { 3921 int curUid = mIsolatedUids.get(isolatedUid, -1); 3922 if (curUid == appUid) { 3923 if (mExternalSync != null) { 3924 mExternalSync.scheduleCpuSyncDueToRemovedUid(isolatedUid); 3925 } 3926 } 3927 } 3928 3929 /** 3930 * This should only be called after the cpu times have been read. 3931 * @see #scheduleRemoveIsolatedUidLocked(int, int) 3932 */ 3933 @GuardedBy("this") removeIsolatedUidLocked(int isolatedUid)3934 public void removeIsolatedUidLocked(int isolatedUid) { 3935 final int idx = mIsolatedUids.indexOfKey(isolatedUid); 3936 if (idx >= 0) { 3937 final int ownerUid = mIsolatedUids.valueAt(idx); 3938 final Uid u = getUidStatsLocked(ownerUid); 3939 u.removeIsolatedUid(isolatedUid); 3940 mIsolatedUids.removeAt(idx); 3941 } 3942 mPendingRemovedUids.add(new UidToRemove(isolatedUid, mClocks.elapsedRealtime())); 3943 } 3944 mapUid(int uid)3945 public int mapUid(int uid) { 3946 int isolated = mIsolatedUids.get(uid, -1); 3947 return isolated > 0 ? isolated : uid; 3948 } 3949 noteEventLocked(int code, String name, int uid)3950 public void noteEventLocked(int code, String name, int uid) { 3951 uid = mapUid(uid); 3952 if (!mActiveEvents.updateState(code, name, uid, 0)) { 3953 return; 3954 } 3955 final long elapsedRealtime = mClocks.elapsedRealtime(); 3956 final long uptime = mClocks.uptimeMillis(); 3957 addHistoryEventLocked(elapsedRealtime, uptime, code, name, uid); 3958 } 3959 noteCurrentTimeChangedLocked()3960 public void noteCurrentTimeChangedLocked() { 3961 final long currentTime = System.currentTimeMillis(); 3962 final long elapsedRealtime = mClocks.elapsedRealtime(); 3963 final long uptime = mClocks.uptimeMillis(); 3964 recordCurrentTimeChangeLocked(currentTime, elapsedRealtime, uptime); 3965 } 3966 noteProcessStartLocked(String name, int uid)3967 public void noteProcessStartLocked(String name, int uid) { 3968 uid = mapUid(uid); 3969 if (isOnBattery()) { 3970 Uid u = getUidStatsLocked(uid); 3971 u.getProcessStatsLocked(name).incStartsLocked(); 3972 } 3973 if (!mActiveEvents.updateState(HistoryItem.EVENT_PROC_START, name, uid, 0)) { 3974 return; 3975 } 3976 if (!mRecordAllHistory) { 3977 return; 3978 } 3979 final long elapsedRealtime = mClocks.elapsedRealtime(); 3980 final long uptime = mClocks.uptimeMillis(); 3981 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_PROC_START, name, uid); 3982 } 3983 noteProcessCrashLocked(String name, int uid)3984 public void noteProcessCrashLocked(String name, int uid) { 3985 uid = mapUid(uid); 3986 if (isOnBattery()) { 3987 Uid u = getUidStatsLocked(uid); 3988 u.getProcessStatsLocked(name).incNumCrashesLocked(); 3989 } 3990 } 3991 noteProcessAnrLocked(String name, int uid)3992 public void noteProcessAnrLocked(String name, int uid) { 3993 uid = mapUid(uid); 3994 if (isOnBattery()) { 3995 Uid u = getUidStatsLocked(uid); 3996 u.getProcessStatsLocked(name).incNumAnrsLocked(); 3997 } 3998 } 3999 noteUidProcessStateLocked(int uid, int state)4000 public void noteUidProcessStateLocked(int uid, int state) { 4001 int parentUid = mapUid(uid); 4002 if (uid != parentUid) { 4003 // Isolated UIDs process state is already rolled up into parent, so no need to track 4004 // Otherwise the parent's process state will get downgraded incorrectly 4005 return; 4006 } 4007 getUidStatsLocked(uid).updateUidProcessStateLocked(state); 4008 } 4009 noteProcessFinishLocked(String name, int uid)4010 public void noteProcessFinishLocked(String name, int uid) { 4011 uid = mapUid(uid); 4012 if (!mActiveEvents.updateState(HistoryItem.EVENT_PROC_FINISH, name, uid, 0)) { 4013 return; 4014 } 4015 if (!mRecordAllHistory) { 4016 return; 4017 } 4018 final long elapsedRealtime = mClocks.elapsedRealtime(); 4019 final long uptime = mClocks.uptimeMillis(); 4020 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_PROC_FINISH, name, uid); 4021 } 4022 noteSyncStartLocked(String name, int uid)4023 public void noteSyncStartLocked(String name, int uid) { 4024 uid = mapUid(uid); 4025 final long elapsedRealtime = mClocks.elapsedRealtime(); 4026 final long uptime = mClocks.uptimeMillis(); 4027 getUidStatsLocked(uid).noteStartSyncLocked(name, elapsedRealtime); 4028 if (!mActiveEvents.updateState(HistoryItem.EVENT_SYNC_START, name, uid, 0)) { 4029 return; 4030 } 4031 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_SYNC_START, name, uid); 4032 } 4033 noteSyncFinishLocked(String name, int uid)4034 public void noteSyncFinishLocked(String name, int uid) { 4035 uid = mapUid(uid); 4036 final long elapsedRealtime = mClocks.elapsedRealtime(); 4037 final long uptime = mClocks.uptimeMillis(); 4038 getUidStatsLocked(uid).noteStopSyncLocked(name, elapsedRealtime); 4039 if (!mActiveEvents.updateState(HistoryItem.EVENT_SYNC_FINISH, name, uid, 0)) { 4040 return; 4041 } 4042 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_SYNC_FINISH, name, uid); 4043 } 4044 noteJobStartLocked(String name, int uid)4045 public void noteJobStartLocked(String name, int uid) { 4046 uid = mapUid(uid); 4047 final long elapsedRealtime = mClocks.elapsedRealtime(); 4048 final long uptime = mClocks.uptimeMillis(); 4049 getUidStatsLocked(uid).noteStartJobLocked(name, elapsedRealtime); 4050 if (!mActiveEvents.updateState(HistoryItem.EVENT_JOB_START, name, uid, 0)) { 4051 return; 4052 } 4053 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_JOB_START, name, uid); 4054 } 4055 noteJobFinishLocked(String name, int uid, int stopReason)4056 public void noteJobFinishLocked(String name, int uid, int stopReason) { 4057 uid = mapUid(uid); 4058 final long elapsedRealtime = mClocks.elapsedRealtime(); 4059 final long uptime = mClocks.uptimeMillis(); 4060 getUidStatsLocked(uid).noteStopJobLocked(name, elapsedRealtime, stopReason); 4061 if (!mActiveEvents.updateState(HistoryItem.EVENT_JOB_FINISH, name, uid, 0)) { 4062 return; 4063 } 4064 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_JOB_FINISH, name, uid); 4065 } 4066 noteJobsDeferredLocked(int uid, int numDeferred, long sinceLast)4067 public void noteJobsDeferredLocked(int uid, int numDeferred, long sinceLast) { 4068 uid = mapUid(uid); 4069 getUidStatsLocked(uid).noteJobsDeferredLocked(numDeferred, sinceLast); 4070 } 4071 noteAlarmStartLocked(String name, WorkSource workSource, int uid)4072 public void noteAlarmStartLocked(String name, WorkSource workSource, int uid) { 4073 noteAlarmStartOrFinishLocked(HistoryItem.EVENT_ALARM_START, name, workSource, uid); 4074 } 4075 noteAlarmFinishLocked(String name, WorkSource workSource, int uid)4076 public void noteAlarmFinishLocked(String name, WorkSource workSource, int uid) { 4077 noteAlarmStartOrFinishLocked(HistoryItem.EVENT_ALARM_FINISH, name, workSource, uid); 4078 } 4079 noteAlarmStartOrFinishLocked(int historyItem, String name, WorkSource workSource, int uid)4080 private void noteAlarmStartOrFinishLocked(int historyItem, String name, WorkSource workSource, 4081 int uid) { 4082 if (!mRecordAllHistory) { 4083 return; 4084 } 4085 4086 final long elapsedRealtime = mClocks.elapsedRealtime(); 4087 final long uptime = mClocks.uptimeMillis(); 4088 4089 if (workSource != null) { 4090 for (int i = 0; i < workSource.size(); ++i) { 4091 uid = mapUid(workSource.get(i)); 4092 if (mActiveEvents.updateState(historyItem, name, uid, 0)) { 4093 addHistoryEventLocked(elapsedRealtime, uptime, historyItem, name, uid); 4094 } 4095 } 4096 4097 List<WorkChain> workChains = workSource.getWorkChains(); 4098 if (workChains != null) { 4099 for (int i = 0; i < workChains.size(); ++i) { 4100 uid = mapUid(workChains.get(i).getAttributionUid()); 4101 if (mActiveEvents.updateState(historyItem, name, uid, 0)) { 4102 addHistoryEventLocked(elapsedRealtime, uptime, historyItem, name, uid); 4103 } 4104 } 4105 } 4106 } else { 4107 uid = mapUid(uid); 4108 4109 if (mActiveEvents.updateState(historyItem, name, uid, 0)) { 4110 addHistoryEventLocked(elapsedRealtime, uptime, historyItem, name, uid); 4111 } 4112 } 4113 } 4114 noteWakupAlarmLocked(String packageName, int uid, WorkSource workSource, String tag)4115 public void noteWakupAlarmLocked(String packageName, int uid, WorkSource workSource, 4116 String tag) { 4117 if (workSource != null) { 4118 for (int i = 0; i < workSource.size(); ++i) { 4119 uid = workSource.get(i); 4120 final String workSourceName = workSource.getName(i); 4121 4122 if (isOnBattery()) { 4123 BatteryStatsImpl.Uid.Pkg pkg = getPackageStatsLocked(uid, 4124 workSourceName != null ? workSourceName : packageName); 4125 pkg.noteWakeupAlarmLocked(tag); 4126 } 4127 } 4128 4129 ArrayList<WorkChain> workChains = workSource.getWorkChains(); 4130 if (workChains != null) { 4131 for (int i = 0; i < workChains.size(); ++i) { 4132 final WorkChain wc = workChains.get(i); 4133 uid = wc.getAttributionUid(); 4134 4135 if (isOnBattery()) { 4136 BatteryStatsImpl.Uid.Pkg pkg = getPackageStatsLocked(uid, packageName); 4137 pkg.noteWakeupAlarmLocked(tag); 4138 } 4139 } 4140 } 4141 } else { 4142 if (isOnBattery()) { 4143 BatteryStatsImpl.Uid.Pkg pkg = getPackageStatsLocked(uid, packageName); 4144 pkg.noteWakeupAlarmLocked(tag); 4145 } 4146 } 4147 } 4148 requestWakelockCpuUpdate()4149 private void requestWakelockCpuUpdate() { 4150 mExternalSync.scheduleCpuSyncDueToWakelockChange(DELAY_UPDATE_WAKELOCKS); 4151 } 4152 requestImmediateCpuUpdate()4153 private void requestImmediateCpuUpdate() { 4154 mExternalSync.scheduleCpuSyncDueToWakelockChange(0 /* delayMillis */); 4155 } 4156 setRecordAllHistoryLocked(boolean enabled)4157 public void setRecordAllHistoryLocked(boolean enabled) { 4158 mRecordAllHistory = enabled; 4159 if (!enabled) { 4160 // Clear out any existing state. 4161 mActiveEvents.removeEvents(HistoryItem.EVENT_WAKE_LOCK); 4162 mActiveEvents.removeEvents(HistoryItem.EVENT_ALARM); 4163 // Record the currently running processes as stopping, now that we are no 4164 // longer tracking them. 4165 HashMap<String, SparseIntArray> active = mActiveEvents.getStateForEvent( 4166 HistoryItem.EVENT_PROC); 4167 if (active != null) { 4168 long mSecRealtime = mClocks.elapsedRealtime(); 4169 final long mSecUptime = mClocks.uptimeMillis(); 4170 for (HashMap.Entry<String, SparseIntArray> ent : active.entrySet()) { 4171 SparseIntArray uids = ent.getValue(); 4172 for (int j=0; j<uids.size(); j++) { 4173 addHistoryEventLocked(mSecRealtime, mSecUptime, 4174 HistoryItem.EVENT_PROC_FINISH, ent.getKey(), uids.keyAt(j)); 4175 } 4176 } 4177 } 4178 } else { 4179 // Record the currently running processes as starting, now that we are tracking them. 4180 HashMap<String, SparseIntArray> active = mActiveEvents.getStateForEvent( 4181 HistoryItem.EVENT_PROC); 4182 if (active != null) { 4183 long mSecRealtime = mClocks.elapsedRealtime(); 4184 final long mSecUptime = mClocks.uptimeMillis(); 4185 for (HashMap.Entry<String, SparseIntArray> ent : active.entrySet()) { 4186 SparseIntArray uids = ent.getValue(); 4187 for (int j=0; j<uids.size(); j++) { 4188 addHistoryEventLocked(mSecRealtime, mSecUptime, 4189 HistoryItem.EVENT_PROC_START, ent.getKey(), uids.keyAt(j)); 4190 } 4191 } 4192 } 4193 } 4194 } 4195 setNoAutoReset(boolean enabled)4196 public void setNoAutoReset(boolean enabled) { 4197 mNoAutoReset = enabled; 4198 } 4199 setPretendScreenOff(boolean pretendScreenOff)4200 public void setPretendScreenOff(boolean pretendScreenOff) { 4201 if (mPretendScreenOff != pretendScreenOff) { 4202 mPretendScreenOff = pretendScreenOff; 4203 noteScreenStateLocked(pretendScreenOff ? Display.STATE_OFF : Display.STATE_ON); 4204 } 4205 } 4206 4207 private String mInitialAcquireWakeName; 4208 private int mInitialAcquireWakeUid = -1; 4209 noteStartWakeLocked(int uid, int pid, WorkChain wc, String name, String historyName, int type, boolean unimportantForLogging, long elapsedRealtime, long uptime)4210 public void noteStartWakeLocked(int uid, int pid, WorkChain wc, String name, String historyName, 4211 int type, boolean unimportantForLogging, long elapsedRealtime, long uptime) { 4212 uid = mapUid(uid); 4213 if (type == WAKE_TYPE_PARTIAL) { 4214 // Only care about partial wake locks, since full wake locks 4215 // will be canceled when the user puts the screen to sleep. 4216 aggregateLastWakeupUptimeLocked(uptime); 4217 if (historyName == null) { 4218 historyName = name; 4219 } 4220 if (mRecordAllHistory) { 4221 if (mActiveEvents.updateState(HistoryItem.EVENT_WAKE_LOCK_START, historyName, 4222 uid, 0)) { 4223 addHistoryEventLocked(elapsedRealtime, uptime, 4224 HistoryItem.EVENT_WAKE_LOCK_START, historyName, uid); 4225 } 4226 } 4227 if (mWakeLockNesting == 0) { 4228 mHistoryCur.states |= HistoryItem.STATE_WAKE_LOCK_FLAG; 4229 if (DEBUG_HISTORY) Slog.v(TAG, "Start wake lock to: " 4230 + Integer.toHexString(mHistoryCur.states)); 4231 mHistoryCur.wakelockTag = mHistoryCur.localWakelockTag; 4232 mHistoryCur.wakelockTag.string = mInitialAcquireWakeName = historyName; 4233 mHistoryCur.wakelockTag.uid = mInitialAcquireWakeUid = uid; 4234 mWakeLockImportant = !unimportantForLogging; 4235 addHistoryRecordLocked(elapsedRealtime, uptime); 4236 } else if (!mWakeLockImportant && !unimportantForLogging 4237 && mHistoryLastWritten.cmd == HistoryItem.CMD_UPDATE) { 4238 if (mHistoryLastWritten.wakelockTag != null) { 4239 // We'll try to update the last tag. 4240 mHistoryLastWritten.wakelockTag = null; 4241 mHistoryCur.wakelockTag = mHistoryCur.localWakelockTag; 4242 mHistoryCur.wakelockTag.string = mInitialAcquireWakeName = historyName; 4243 mHistoryCur.wakelockTag.uid = mInitialAcquireWakeUid = uid; 4244 addHistoryRecordLocked(elapsedRealtime, uptime); 4245 } 4246 mWakeLockImportant = true; 4247 } 4248 mWakeLockNesting++; 4249 } 4250 if (uid >= 0) { 4251 if (mOnBatteryScreenOffTimeBase.isRunning()) { 4252 // We only update the cpu time when a wake lock is acquired if the screen is off. 4253 // If the screen is on, we don't distribute the power amongst partial wakelocks. 4254 if (DEBUG_ENERGY_CPU) { 4255 Slog.d(TAG, "Updating cpu time because of +wake_lock"); 4256 } 4257 requestWakelockCpuUpdate(); 4258 } 4259 4260 getUidStatsLocked(uid).noteStartWakeLocked(pid, name, type, elapsedRealtime); 4261 4262 if (wc != null) { 4263 StatsLog.write(StatsLog.WAKELOCK_STATE_CHANGED, wc.getUids(), wc.getTags(), 4264 getPowerManagerWakeLockLevel(type), name, 4265 StatsLog.WAKELOCK_STATE_CHANGED__STATE__ACQUIRE); 4266 } else { 4267 StatsLog.write_non_chained(StatsLog.WAKELOCK_STATE_CHANGED, uid, null, 4268 getPowerManagerWakeLockLevel(type), name, 4269 StatsLog.WAKELOCK_STATE_CHANGED__STATE__ACQUIRE); 4270 } 4271 } 4272 } 4273 noteStopWakeLocked(int uid, int pid, WorkChain wc, String name, String historyName, int type, long elapsedRealtime, long uptime)4274 public void noteStopWakeLocked(int uid, int pid, WorkChain wc, String name, String historyName, 4275 int type, long elapsedRealtime, long uptime) { 4276 uid = mapUid(uid); 4277 if (type == WAKE_TYPE_PARTIAL) { 4278 mWakeLockNesting--; 4279 if (mRecordAllHistory) { 4280 if (historyName == null) { 4281 historyName = name; 4282 } 4283 if (mActiveEvents.updateState(HistoryItem.EVENT_WAKE_LOCK_FINISH, historyName, 4284 uid, 0)) { 4285 addHistoryEventLocked(elapsedRealtime, uptime, 4286 HistoryItem.EVENT_WAKE_LOCK_FINISH, historyName, uid); 4287 } 4288 } 4289 if (mWakeLockNesting == 0) { 4290 mHistoryCur.states &= ~HistoryItem.STATE_WAKE_LOCK_FLAG; 4291 if (DEBUG_HISTORY) Slog.v(TAG, "Stop wake lock to: " 4292 + Integer.toHexString(mHistoryCur.states)); 4293 mInitialAcquireWakeName = null; 4294 mInitialAcquireWakeUid = -1; 4295 addHistoryRecordLocked(elapsedRealtime, uptime); 4296 } 4297 } 4298 if (uid >= 0) { 4299 if (mOnBatteryScreenOffTimeBase.isRunning()) { 4300 if (DEBUG_ENERGY_CPU) { 4301 Slog.d(TAG, "Updating cpu time because of -wake_lock"); 4302 } 4303 requestWakelockCpuUpdate(); 4304 } 4305 4306 getUidStatsLocked(uid).noteStopWakeLocked(pid, name, type, elapsedRealtime); 4307 if (wc != null) { 4308 StatsLog.write(StatsLog.WAKELOCK_STATE_CHANGED, wc.getUids(), wc.getTags(), 4309 getPowerManagerWakeLockLevel(type), name, 4310 StatsLog.WAKELOCK_STATE_CHANGED__STATE__RELEASE); 4311 } else { 4312 StatsLog.write_non_chained(StatsLog.WAKELOCK_STATE_CHANGED, uid, null, 4313 getPowerManagerWakeLockLevel(type), name, 4314 StatsLog.WAKELOCK_STATE_CHANGED__STATE__RELEASE); 4315 } 4316 } 4317 } 4318 4319 /** 4320 * Converts BatteryStats wakelock types back into PowerManager wakelock levels. 4321 * This is the inverse map of Notifier.getBatteryStatsWakeLockMonitorType(). 4322 * These are estimations, since batterystats loses some of the original data. 4323 * TODO: Delete this. Instead, StatsLog.write should be called from PowerManager's Notifier. 4324 */ getPowerManagerWakeLockLevel(int battertStatsWakelockType)4325 private int getPowerManagerWakeLockLevel(int battertStatsWakelockType) { 4326 switch (battertStatsWakelockType) { 4327 // PowerManager.PARTIAL_WAKE_LOCK or PROXIMITY_SCREEN_OFF_WAKE_LOCK 4328 case BatteryStats.WAKE_TYPE_PARTIAL: 4329 return PowerManager.PARTIAL_WAKE_LOCK; 4330 4331 // PowerManager.SCREEN_DIM_WAKE_LOCK or SCREEN_BRIGHT_WAKE_LOCK 4332 case BatteryStats.WAKE_TYPE_FULL: 4333 return PowerManager.FULL_WAKE_LOCK; 4334 4335 case BatteryStats.WAKE_TYPE_DRAW: 4336 return PowerManager.DRAW_WAKE_LOCK; 4337 4338 // It appears that nothing can ever make a Window and PowerManager lacks an equivalent. 4339 case BatteryStats.WAKE_TYPE_WINDOW: 4340 Slog.e(TAG, "Illegal window wakelock type observed in batterystats."); 4341 return -1; 4342 4343 default: 4344 Slog.e(TAG, "Illegal wakelock type in batterystats: " + battertStatsWakelockType); 4345 return -1; 4346 } 4347 } 4348 noteStartWakeFromSourceLocked(WorkSource ws, int pid, String name, String historyName, int type, boolean unimportantForLogging)4349 public void noteStartWakeFromSourceLocked(WorkSource ws, int pid, String name, 4350 String historyName, int type, boolean unimportantForLogging) { 4351 final long elapsedRealtime = mClocks.elapsedRealtime(); 4352 final long uptime = mClocks.uptimeMillis(); 4353 final int N = ws.size(); 4354 for (int i=0; i<N; i++) { 4355 noteStartWakeLocked(ws.get(i), pid, null, name, historyName, type, 4356 unimportantForLogging, elapsedRealtime, uptime); 4357 } 4358 4359 List<WorkChain> wcs = ws.getWorkChains(); 4360 if (wcs != null) { 4361 for (int i = 0; i < wcs.size(); ++i) { 4362 final WorkChain wc = wcs.get(i); 4363 noteStartWakeLocked(wc.getAttributionUid(), pid, wc, name, historyName, type, 4364 unimportantForLogging, elapsedRealtime, uptime); 4365 } 4366 } 4367 } 4368 noteChangeWakelockFromSourceLocked(WorkSource ws, int pid, String name, String historyName, int type, WorkSource newWs, int newPid, String newName, String newHistoryName, int newType, boolean newUnimportantForLogging)4369 public void noteChangeWakelockFromSourceLocked(WorkSource ws, int pid, String name, 4370 String historyName, int type, WorkSource newWs, int newPid, String newName, 4371 String newHistoryName, int newType, boolean newUnimportantForLogging) { 4372 final long elapsedRealtime = mClocks.elapsedRealtime(); 4373 final long uptime = mClocks.uptimeMillis(); 4374 4375 List<WorkChain>[] wcs = WorkSource.diffChains(ws, newWs); 4376 4377 // For correct semantics, we start the need worksources first, so that we won't 4378 // make inappropriate history items as if all wake locks went away and new ones 4379 // appeared. This is okay because tracking of wake locks allows nesting. 4380 // 4381 // First the starts : 4382 final int NN = newWs.size(); 4383 for (int i=0; i<NN; i++) { 4384 noteStartWakeLocked(newWs.get(i), newPid, null, newName, newHistoryName, newType, 4385 newUnimportantForLogging, elapsedRealtime, uptime); 4386 } 4387 if (wcs != null) { 4388 List<WorkChain> newChains = wcs[0]; 4389 if (newChains != null) { 4390 for (int i = 0; i < newChains.size(); ++i) { 4391 final WorkChain newChain = newChains.get(i); 4392 noteStartWakeLocked(newChain.getAttributionUid(), newPid, newChain, newName, 4393 newHistoryName, newType, newUnimportantForLogging, elapsedRealtime, 4394 uptime); 4395 } 4396 } 4397 } 4398 4399 // Then the stops : 4400 final int NO = ws.size(); 4401 for (int i=0; i<NO; i++) { 4402 noteStopWakeLocked(ws.get(i), pid, null, name, historyName, type, elapsedRealtime, 4403 uptime); 4404 } 4405 if (wcs != null) { 4406 List<WorkChain> goneChains = wcs[1]; 4407 if (goneChains != null) { 4408 for (int i = 0; i < goneChains.size(); ++i) { 4409 final WorkChain goneChain = goneChains.get(i); 4410 noteStopWakeLocked(goneChain.getAttributionUid(), pid, goneChain, name, 4411 historyName, type, elapsedRealtime, uptime); 4412 } 4413 } 4414 } 4415 } 4416 noteStopWakeFromSourceLocked(WorkSource ws, int pid, String name, String historyName, int type)4417 public void noteStopWakeFromSourceLocked(WorkSource ws, int pid, String name, 4418 String historyName, int type) { 4419 final long elapsedRealtime = mClocks.elapsedRealtime(); 4420 final long uptime = mClocks.uptimeMillis(); 4421 final int N = ws.size(); 4422 for (int i=0; i<N; i++) { 4423 noteStopWakeLocked(ws.get(i), pid, null, name, historyName, type, elapsedRealtime, 4424 uptime); 4425 } 4426 4427 List<WorkChain> wcs = ws.getWorkChains(); 4428 if (wcs != null) { 4429 for (int i = 0; i < wcs.size(); ++i) { 4430 final WorkChain wc = wcs.get(i); 4431 noteStopWakeLocked(wc.getAttributionUid(), pid, wc, name, historyName, type, 4432 elapsedRealtime, uptime); 4433 } 4434 } 4435 } 4436 noteLongPartialWakelockStart(String name, String historyName, int uid)4437 public void noteLongPartialWakelockStart(String name, String historyName, int uid) { 4438 uid = mapUid(uid); 4439 noteLongPartialWakeLockStartInternal(name, historyName, uid); 4440 } 4441 noteLongPartialWakelockStartFromSource(String name, String historyName, WorkSource workSource)4442 public void noteLongPartialWakelockStartFromSource(String name, String historyName, 4443 WorkSource workSource) { 4444 final int N = workSource.size(); 4445 for (int i = 0; i < N; ++i) { 4446 final int uid = mapUid(workSource.get(i)); 4447 noteLongPartialWakeLockStartInternal(name, historyName, uid); 4448 } 4449 4450 final ArrayList<WorkChain> workChains = workSource.getWorkChains(); 4451 if (workChains != null) { 4452 for (int i = 0; i < workChains.size(); ++i) { 4453 final WorkChain workChain = workChains.get(i); 4454 final int uid = workChain.getAttributionUid(); 4455 noteLongPartialWakeLockStartInternal(name, historyName, uid); 4456 } 4457 } 4458 } 4459 noteLongPartialWakeLockStartInternal(String name, String historyName, int uid)4460 private void noteLongPartialWakeLockStartInternal(String name, String historyName, int uid) { 4461 final long elapsedRealtime = mClocks.elapsedRealtime(); 4462 final long uptime = mClocks.uptimeMillis(); 4463 if (historyName == null) { 4464 historyName = name; 4465 } 4466 if (!mActiveEvents.updateState(HistoryItem.EVENT_LONG_WAKE_LOCK_START, historyName, uid, 4467 0)) { 4468 return; 4469 } 4470 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_LONG_WAKE_LOCK_START, 4471 historyName, uid); 4472 } 4473 noteLongPartialWakelockFinish(String name, String historyName, int uid)4474 public void noteLongPartialWakelockFinish(String name, String historyName, int uid) { 4475 uid = mapUid(uid); 4476 noteLongPartialWakeLockFinishInternal(name, historyName, uid); 4477 } 4478 noteLongPartialWakelockFinishFromSource(String name, String historyName, WorkSource workSource)4479 public void noteLongPartialWakelockFinishFromSource(String name, String historyName, 4480 WorkSource workSource) { 4481 final int N = workSource.size(); 4482 for (int i = 0; i < N; ++i) { 4483 final int uid = mapUid(workSource.get(i)); 4484 noteLongPartialWakeLockFinishInternal(name, historyName, uid); 4485 } 4486 4487 final ArrayList<WorkChain> workChains = workSource.getWorkChains(); 4488 if (workChains != null) { 4489 for (int i = 0; i < workChains.size(); ++i) { 4490 final WorkChain workChain = workChains.get(i); 4491 final int uid = workChain.getAttributionUid(); 4492 noteLongPartialWakeLockFinishInternal(name, historyName, uid); 4493 } 4494 } 4495 } 4496 noteLongPartialWakeLockFinishInternal(String name, String historyName, int uid)4497 private void noteLongPartialWakeLockFinishInternal(String name, String historyName, int uid) { 4498 final long elapsedRealtime = mClocks.elapsedRealtime(); 4499 final long uptime = mClocks.uptimeMillis(); 4500 if (historyName == null) { 4501 historyName = name; 4502 } 4503 if (!mActiveEvents.updateState(HistoryItem.EVENT_LONG_WAKE_LOCK_FINISH, historyName, uid, 4504 0)) { 4505 return; 4506 } 4507 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_LONG_WAKE_LOCK_FINISH, 4508 historyName, uid); 4509 } 4510 aggregateLastWakeupUptimeLocked(long uptimeMs)4511 void aggregateLastWakeupUptimeLocked(long uptimeMs) { 4512 if (mLastWakeupReason != null) { 4513 long deltaUptime = uptimeMs - mLastWakeupUptimeMs; 4514 SamplingTimer timer = getWakeupReasonTimerLocked(mLastWakeupReason); 4515 timer.add(deltaUptime * 1000, 1); // time in in microseconds 4516 StatsLog.write(StatsLog.KERNEL_WAKEUP_REPORTED, mLastWakeupReason, 4517 /* duration_usec */ deltaUptime * 1000); 4518 mLastWakeupReason = null; 4519 } 4520 } 4521 noteWakeupReasonLocked(String reason)4522 public void noteWakeupReasonLocked(String reason) { 4523 final long elapsedRealtime = mClocks.elapsedRealtime(); 4524 final long uptime = mClocks.uptimeMillis(); 4525 if (DEBUG_HISTORY) Slog.v(TAG, "Wakeup reason \"" + reason +"\": " 4526 + Integer.toHexString(mHistoryCur.states)); 4527 aggregateLastWakeupUptimeLocked(uptime); 4528 mHistoryCur.wakeReasonTag = mHistoryCur.localWakeReasonTag; 4529 mHistoryCur.wakeReasonTag.string = reason; 4530 mHistoryCur.wakeReasonTag.uid = 0; 4531 mLastWakeupReason = reason; 4532 mLastWakeupUptimeMs = uptime; 4533 addHistoryRecordLocked(elapsedRealtime, uptime); 4534 } 4535 startAddingCpuLocked()4536 public boolean startAddingCpuLocked() { 4537 mExternalSync.cancelCpuSyncDueToWakelockChange(); 4538 return mOnBatteryInternal; 4539 } 4540 finishAddingCpuLocked(int totalUTime, int totalSTime, int statUserTime, int statSystemTime, int statIOWaitTime, int statIrqTime, int statSoftIrqTime, int statIdleTime)4541 public void finishAddingCpuLocked(int totalUTime, int totalSTime, int statUserTime, 4542 int statSystemTime, int statIOWaitTime, int statIrqTime, 4543 int statSoftIrqTime, int statIdleTime) { 4544 if (DEBUG) Slog.d(TAG, "Adding cpu: tuser=" + totalUTime + " tsys=" + totalSTime 4545 + " user=" + statUserTime + " sys=" + statSystemTime 4546 + " io=" + statIOWaitTime + " irq=" + statIrqTime 4547 + " sirq=" + statSoftIrqTime + " idle=" + statIdleTime); 4548 mCurStepCpuUserTime += totalUTime; 4549 mCurStepCpuSystemTime += totalSTime; 4550 mCurStepStatUserTime += statUserTime; 4551 mCurStepStatSystemTime += statSystemTime; 4552 mCurStepStatIOWaitTime += statIOWaitTime; 4553 mCurStepStatIrqTime += statIrqTime; 4554 mCurStepStatSoftIrqTime += statSoftIrqTime; 4555 mCurStepStatIdleTime += statIdleTime; 4556 } 4557 noteProcessDiedLocked(int uid, int pid)4558 public void noteProcessDiedLocked(int uid, int pid) { 4559 uid = mapUid(uid); 4560 Uid u = mUidStats.get(uid); 4561 if (u != null) { 4562 u.mPids.remove(pid); 4563 } 4564 } 4565 getProcessWakeTime(int uid, int pid, long realtime)4566 public long getProcessWakeTime(int uid, int pid, long realtime) { 4567 uid = mapUid(uid); 4568 Uid u = mUidStats.get(uid); 4569 if (u != null) { 4570 Uid.Pid p = u.mPids.get(pid); 4571 if (p != null) { 4572 return p.mWakeSumMs + (p.mWakeNesting > 0 ? (realtime - p.mWakeStartMs) : 0); 4573 } 4574 } 4575 return 0; 4576 } 4577 reportExcessiveCpuLocked(int uid, String proc, long overTime, long usedTime)4578 public void reportExcessiveCpuLocked(int uid, String proc, long overTime, long usedTime) { 4579 uid = mapUid(uid); 4580 Uid u = mUidStats.get(uid); 4581 if (u != null) { 4582 u.reportExcessiveCpuLocked(proc, overTime, usedTime); 4583 } 4584 } 4585 4586 int mSensorNesting; 4587 noteStartSensorLocked(int uid, int sensor)4588 public void noteStartSensorLocked(int uid, int sensor) { 4589 uid = mapUid(uid); 4590 final long elapsedRealtime = mClocks.elapsedRealtime(); 4591 final long uptime = mClocks.uptimeMillis(); 4592 if (mSensorNesting == 0) { 4593 mHistoryCur.states |= HistoryItem.STATE_SENSOR_ON_FLAG; 4594 if (DEBUG_HISTORY) Slog.v(TAG, "Start sensor to: " 4595 + Integer.toHexString(mHistoryCur.states)); 4596 addHistoryRecordLocked(elapsedRealtime, uptime); 4597 } 4598 mSensorNesting++; 4599 getUidStatsLocked(uid).noteStartSensor(sensor, elapsedRealtime); 4600 } 4601 noteStopSensorLocked(int uid, int sensor)4602 public void noteStopSensorLocked(int uid, int sensor) { 4603 uid = mapUid(uid); 4604 final long elapsedRealtime = mClocks.elapsedRealtime(); 4605 final long uptime = mClocks.uptimeMillis(); 4606 mSensorNesting--; 4607 if (mSensorNesting == 0) { 4608 mHistoryCur.states &= ~HistoryItem.STATE_SENSOR_ON_FLAG; 4609 if (DEBUG_HISTORY) Slog.v(TAG, "Stop sensor to: " 4610 + Integer.toHexString(mHistoryCur.states)); 4611 addHistoryRecordLocked(elapsedRealtime, uptime); 4612 } 4613 getUidStatsLocked(uid).noteStopSensor(sensor, elapsedRealtime); 4614 } 4615 4616 int mGpsNesting; 4617 noteGpsChangedLocked(WorkSource oldWs, WorkSource newWs)4618 public void noteGpsChangedLocked(WorkSource oldWs, WorkSource newWs) { 4619 for (int i = 0; i < newWs.size(); ++i) { 4620 noteStartGpsLocked(newWs.get(i), null); 4621 } 4622 4623 for (int i = 0; i < oldWs.size(); ++i) { 4624 noteStopGpsLocked((oldWs.get(i)), null); 4625 } 4626 4627 List<WorkChain>[] wcs = WorkSource.diffChains(oldWs, newWs); 4628 if (wcs != null) { 4629 if (wcs[0] != null) { 4630 final List<WorkChain> newChains = wcs[0]; 4631 for (int i = 0; i < newChains.size(); ++i) { 4632 noteStartGpsLocked(-1, newChains.get(i)); 4633 } 4634 } 4635 4636 if (wcs[1] != null) { 4637 final List<WorkChain> goneChains = wcs[1]; 4638 for (int i = 0; i < goneChains.size(); ++i) { 4639 noteStopGpsLocked(-1, goneChains.get(i)); 4640 } 4641 } 4642 } 4643 } 4644 noteStartGpsLocked(int uid, WorkChain workChain)4645 private void noteStartGpsLocked(int uid, WorkChain workChain) { 4646 uid = getAttributionUid(uid, workChain); 4647 final long elapsedRealtime = mClocks.elapsedRealtime(); 4648 final long uptime = mClocks.uptimeMillis(); 4649 if (mGpsNesting == 0) { 4650 mHistoryCur.states |= HistoryItem.STATE_GPS_ON_FLAG; 4651 if (DEBUG_HISTORY) Slog.v(TAG, "Start GPS to: " 4652 + Integer.toHexString(mHistoryCur.states)); 4653 addHistoryRecordLocked(elapsedRealtime, uptime); 4654 } 4655 mGpsNesting++; 4656 4657 if (workChain == null) { 4658 StatsLog.write_non_chained(StatsLog.GPS_SCAN_STATE_CHANGED, uid, null, 4659 StatsLog.GPS_SCAN_STATE_CHANGED__STATE__ON); 4660 } else { 4661 StatsLog.write(StatsLog.GPS_SCAN_STATE_CHANGED, 4662 workChain.getUids(), workChain.getTags(), 4663 StatsLog.GPS_SCAN_STATE_CHANGED__STATE__ON); 4664 } 4665 4666 getUidStatsLocked(uid).noteStartGps(elapsedRealtime); 4667 } 4668 noteStopGpsLocked(int uid, WorkChain workChain)4669 private void noteStopGpsLocked(int uid, WorkChain workChain) { 4670 uid = getAttributionUid(uid, workChain); 4671 final long elapsedRealtime = mClocks.elapsedRealtime(); 4672 final long uptime = mClocks.uptimeMillis(); 4673 mGpsNesting--; 4674 if (mGpsNesting == 0) { 4675 mHistoryCur.states &= ~HistoryItem.STATE_GPS_ON_FLAG; 4676 if (DEBUG_HISTORY) Slog.v(TAG, "Stop GPS to: " 4677 + Integer.toHexString(mHistoryCur.states)); 4678 addHistoryRecordLocked(elapsedRealtime, uptime); 4679 stopAllGpsSignalQualityTimersLocked(-1); 4680 mGpsSignalQualityBin = -1; 4681 } 4682 4683 if (workChain == null) { 4684 StatsLog.write_non_chained(StatsLog.GPS_SCAN_STATE_CHANGED, uid, null, 4685 StatsLog.GPS_SCAN_STATE_CHANGED__STATE__OFF); 4686 } else { 4687 StatsLog.write(StatsLog.GPS_SCAN_STATE_CHANGED, workChain.getUids(), 4688 workChain.getTags(), StatsLog.GPS_SCAN_STATE_CHANGED__STATE__OFF); 4689 } 4690 4691 getUidStatsLocked(uid).noteStopGps(elapsedRealtime); 4692 } 4693 noteGpsSignalQualityLocked(int signalLevel)4694 public void noteGpsSignalQualityLocked(int signalLevel) { 4695 if (mGpsNesting == 0) { 4696 return; 4697 } 4698 if (signalLevel < 0 || signalLevel >= GnssMetrics.NUM_GPS_SIGNAL_QUALITY_LEVELS) { 4699 stopAllGpsSignalQualityTimersLocked(-1); 4700 return; 4701 } 4702 final long elapsedRealtime = mClocks.elapsedRealtime(); 4703 final long uptime = mClocks.uptimeMillis(); 4704 if (mGpsSignalQualityBin != signalLevel) { 4705 if (mGpsSignalQualityBin >= 0) { 4706 mGpsSignalQualityTimer[mGpsSignalQualityBin].stopRunningLocked(elapsedRealtime); 4707 } 4708 if(!mGpsSignalQualityTimer[signalLevel].isRunningLocked()) { 4709 mGpsSignalQualityTimer[signalLevel].startRunningLocked(elapsedRealtime); 4710 } 4711 mHistoryCur.states2 = (mHistoryCur.states2&~HistoryItem.STATE2_GPS_SIGNAL_QUALITY_MASK) 4712 | (signalLevel << HistoryItem.STATE2_GPS_SIGNAL_QUALITY_SHIFT); 4713 addHistoryRecordLocked(elapsedRealtime, uptime); 4714 mGpsSignalQualityBin = signalLevel; 4715 } 4716 return; 4717 } 4718 4719 @GuardedBy("this") noteScreenStateLocked(int state)4720 public void noteScreenStateLocked(int state) { 4721 state = mPretendScreenOff ? Display.STATE_OFF : state; 4722 4723 // Battery stats relies on there being 4 states. To accommodate this, new states beyond the 4724 // original 4 are mapped to one of the originals. 4725 if (state > MAX_TRACKED_SCREEN_STATE) { 4726 switch (state) { 4727 case Display.STATE_VR: 4728 state = Display.STATE_ON; 4729 break; 4730 default: 4731 Slog.wtf(TAG, "Unknown screen state (not mapped): " + state); 4732 break; 4733 } 4734 } 4735 4736 if (mScreenState != state) { 4737 recordDailyStatsIfNeededLocked(true); 4738 final int oldState = mScreenState; 4739 mScreenState = state; 4740 if (DEBUG) Slog.v(TAG, "Screen state: oldState=" + Display.stateToString(oldState) 4741 + ", newState=" + Display.stateToString(state)); 4742 4743 if (state != Display.STATE_UNKNOWN) { 4744 int stepState = state-1; 4745 if ((stepState & STEP_LEVEL_MODE_SCREEN_STATE) == stepState) { 4746 mModStepMode |= (mCurStepMode & STEP_LEVEL_MODE_SCREEN_STATE) ^ stepState; 4747 mCurStepMode = (mCurStepMode & ~STEP_LEVEL_MODE_SCREEN_STATE) | stepState; 4748 } else { 4749 Slog.wtf(TAG, "Unexpected screen state: " + state); 4750 } 4751 } 4752 4753 final long elapsedRealtime = mClocks.elapsedRealtime(); 4754 final long uptime = mClocks.uptimeMillis(); 4755 4756 boolean updateHistory = false; 4757 if (isScreenDoze(state)) { 4758 mHistoryCur.states |= HistoryItem.STATE_SCREEN_DOZE_FLAG; 4759 mScreenDozeTimer.startRunningLocked(elapsedRealtime); 4760 updateHistory = true; 4761 } else if (isScreenDoze(oldState)) { 4762 mHistoryCur.states &= ~HistoryItem.STATE_SCREEN_DOZE_FLAG; 4763 mScreenDozeTimer.stopRunningLocked(elapsedRealtime); 4764 updateHistory = true; 4765 } 4766 if (isScreenOn(state)) { 4767 mHistoryCur.states |= HistoryItem.STATE_SCREEN_ON_FLAG; 4768 if (DEBUG_HISTORY) Slog.v(TAG, "Screen on to: " 4769 + Integer.toHexString(mHistoryCur.states)); 4770 mScreenOnTimer.startRunningLocked(elapsedRealtime); 4771 if (mScreenBrightnessBin >= 0) { 4772 mScreenBrightnessTimer[mScreenBrightnessBin].startRunningLocked(elapsedRealtime); 4773 } 4774 updateHistory = true; 4775 } else if (isScreenOn(oldState)) { 4776 mHistoryCur.states &= ~HistoryItem.STATE_SCREEN_ON_FLAG; 4777 if (DEBUG_HISTORY) Slog.v(TAG, "Screen off to: " 4778 + Integer.toHexString(mHistoryCur.states)); 4779 mScreenOnTimer.stopRunningLocked(elapsedRealtime); 4780 if (mScreenBrightnessBin >= 0) { 4781 mScreenBrightnessTimer[mScreenBrightnessBin].stopRunningLocked(elapsedRealtime); 4782 } 4783 updateHistory = true; 4784 } 4785 if (updateHistory) { 4786 if (DEBUG_HISTORY) Slog.v(TAG, "Screen state to: " 4787 + Display.stateToString(state)); 4788 addHistoryRecordLocked(elapsedRealtime, uptime); 4789 } 4790 mExternalSync.scheduleCpuSyncDueToScreenStateChange( 4791 mOnBatteryTimeBase.isRunning(), mOnBatteryScreenOffTimeBase.isRunning()); 4792 if (isScreenOn(state)) { 4793 updateTimeBasesLocked(mOnBatteryTimeBase.isRunning(), state, 4794 mClocks.uptimeMillis() * 1000, elapsedRealtime * 1000); 4795 // Fake a wake lock, so we consider the device waked as long as the screen is on. 4796 noteStartWakeLocked(-1, -1, null, "screen", null, WAKE_TYPE_PARTIAL, false, 4797 elapsedRealtime, uptime); 4798 } else if (isScreenOn(oldState)) { 4799 noteStopWakeLocked(-1, -1, null, "screen", "screen", WAKE_TYPE_PARTIAL, 4800 elapsedRealtime, uptime); 4801 updateTimeBasesLocked(mOnBatteryTimeBase.isRunning(), state, 4802 mClocks.uptimeMillis() * 1000, elapsedRealtime * 1000); 4803 } 4804 // Update discharge amounts. 4805 if (mOnBatteryInternal) { 4806 updateDischargeScreenLevelsLocked(oldState, state); 4807 } 4808 } 4809 } 4810 4811 @UnsupportedAppUsage noteScreenBrightnessLocked(int brightness)4812 public void noteScreenBrightnessLocked(int brightness) { 4813 // Bin the brightness. 4814 int bin = brightness / (256/NUM_SCREEN_BRIGHTNESS_BINS); 4815 if (bin < 0) bin = 0; 4816 else if (bin >= NUM_SCREEN_BRIGHTNESS_BINS) bin = NUM_SCREEN_BRIGHTNESS_BINS-1; 4817 if (mScreenBrightnessBin != bin) { 4818 final long elapsedRealtime = mClocks.elapsedRealtime(); 4819 final long uptime = mClocks.uptimeMillis(); 4820 mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_BRIGHTNESS_MASK) 4821 | (bin << HistoryItem.STATE_BRIGHTNESS_SHIFT); 4822 if (DEBUG_HISTORY) Slog.v(TAG, "Screen brightness " + bin + " to: " 4823 + Integer.toHexString(mHistoryCur.states)); 4824 addHistoryRecordLocked(elapsedRealtime, uptime); 4825 if (mScreenState == Display.STATE_ON) { 4826 if (mScreenBrightnessBin >= 0) { 4827 mScreenBrightnessTimer[mScreenBrightnessBin].stopRunningLocked(elapsedRealtime); 4828 } 4829 mScreenBrightnessTimer[bin].startRunningLocked(elapsedRealtime); 4830 } 4831 mScreenBrightnessBin = bin; 4832 } 4833 } 4834 4835 @UnsupportedAppUsage noteUserActivityLocked(int uid, int event)4836 public void noteUserActivityLocked(int uid, int event) { 4837 if (mOnBatteryInternal) { 4838 uid = mapUid(uid); 4839 getUidStatsLocked(uid).noteUserActivityLocked(event); 4840 } 4841 } 4842 noteWakeUpLocked(String reason, int reasonUid)4843 public void noteWakeUpLocked(String reason, int reasonUid) { 4844 final long elapsedRealtime = mClocks.elapsedRealtime(); 4845 final long uptime = mClocks.uptimeMillis(); 4846 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_SCREEN_WAKE_UP, 4847 reason, reasonUid); 4848 } 4849 noteInteractiveLocked(boolean interactive)4850 public void noteInteractiveLocked(boolean interactive) { 4851 if (mInteractive != interactive) { 4852 final long elapsedRealtime = mClocks.elapsedRealtime(); 4853 mInteractive = interactive; 4854 if (DEBUG) Slog.v(TAG, "Interactive: " + interactive); 4855 if (interactive) { 4856 mInteractiveTimer.startRunningLocked(elapsedRealtime); 4857 } else { 4858 mInteractiveTimer.stopRunningLocked(elapsedRealtime); 4859 } 4860 } 4861 } 4862 noteConnectivityChangedLocked(int type, String extra)4863 public void noteConnectivityChangedLocked(int type, String extra) { 4864 final long elapsedRealtime = mClocks.elapsedRealtime(); 4865 final long uptime = mClocks.uptimeMillis(); 4866 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_CONNECTIVITY_CHANGED, 4867 extra, type); 4868 mNumConnectivityChange++; 4869 } 4870 noteMobileRadioApWakeupLocked(final long elapsedRealtimeMillis, final long uptimeMillis, int uid)4871 private void noteMobileRadioApWakeupLocked(final long elapsedRealtimeMillis, 4872 final long uptimeMillis, int uid) { 4873 uid = mapUid(uid); 4874 addHistoryEventLocked(elapsedRealtimeMillis, uptimeMillis, HistoryItem.EVENT_WAKEUP_AP, "", 4875 uid); 4876 getUidStatsLocked(uid).noteMobileRadioApWakeupLocked(); 4877 } 4878 4879 /** 4880 * Updates the radio power state and returns true if an external stats collection should occur. 4881 */ noteMobileRadioPowerStateLocked(int powerState, long timestampNs, int uid)4882 public boolean noteMobileRadioPowerStateLocked(int powerState, long timestampNs, int uid) { 4883 final long elapsedRealtime = mClocks.elapsedRealtime(); 4884 final long uptime = mClocks.uptimeMillis(); 4885 if (mMobileRadioPowerState != powerState) { 4886 long realElapsedRealtimeMs; 4887 final boolean active = 4888 powerState == DataConnectionRealTimeInfo.DC_POWER_STATE_MEDIUM 4889 || powerState == DataConnectionRealTimeInfo.DC_POWER_STATE_HIGH; 4890 if (active) { 4891 if (uid > 0) { 4892 noteMobileRadioApWakeupLocked(elapsedRealtime, uptime, uid); 4893 } 4894 4895 mMobileRadioActiveStartTime = realElapsedRealtimeMs = timestampNs / (1000 * 1000); 4896 mHistoryCur.states |= HistoryItem.STATE_MOBILE_RADIO_ACTIVE_FLAG; 4897 } else { 4898 realElapsedRealtimeMs = timestampNs / (1000*1000); 4899 long lastUpdateTimeMs = mMobileRadioActiveStartTime; 4900 if (realElapsedRealtimeMs < lastUpdateTimeMs) { 4901 Slog.wtf(TAG, "Data connection inactive timestamp " + realElapsedRealtimeMs 4902 + " is before start time " + lastUpdateTimeMs); 4903 realElapsedRealtimeMs = elapsedRealtime; 4904 } else if (realElapsedRealtimeMs < elapsedRealtime) { 4905 mMobileRadioActiveAdjustedTime.addCountLocked(elapsedRealtime 4906 - realElapsedRealtimeMs); 4907 } 4908 mHistoryCur.states &= ~HistoryItem.STATE_MOBILE_RADIO_ACTIVE_FLAG; 4909 } 4910 if (DEBUG_HISTORY) Slog.v(TAG, "Mobile network active " + active + " to: " 4911 + Integer.toHexString(mHistoryCur.states)); 4912 addHistoryRecordLocked(elapsedRealtime, uptime); 4913 mMobileRadioPowerState = powerState; 4914 if (active) { 4915 mMobileRadioActiveTimer.startRunningLocked(elapsedRealtime); 4916 mMobileRadioActivePerAppTimer.startRunningLocked(elapsedRealtime); 4917 } else { 4918 mMobileRadioActiveTimer.stopRunningLocked(realElapsedRealtimeMs); 4919 mMobileRadioActivePerAppTimer.stopRunningLocked(realElapsedRealtimeMs); 4920 // Tell the caller to collect radio network/power stats. 4921 return true; 4922 } 4923 } 4924 return false; 4925 } 4926 notePowerSaveModeLocked(boolean enabled)4927 public void notePowerSaveModeLocked(boolean enabled) { 4928 if (mPowerSaveModeEnabled != enabled) { 4929 int stepState = enabled ? STEP_LEVEL_MODE_POWER_SAVE : 0; 4930 mModStepMode |= (mCurStepMode&STEP_LEVEL_MODE_POWER_SAVE) ^ stepState; 4931 mCurStepMode = (mCurStepMode&~STEP_LEVEL_MODE_POWER_SAVE) | stepState; 4932 final long elapsedRealtime = mClocks.elapsedRealtime(); 4933 final long uptime = mClocks.uptimeMillis(); 4934 mPowerSaveModeEnabled = enabled; 4935 if (enabled) { 4936 mHistoryCur.states2 |= HistoryItem.STATE2_POWER_SAVE_FLAG; 4937 if (DEBUG_HISTORY) Slog.v(TAG, "Power save mode enabled to: " 4938 + Integer.toHexString(mHistoryCur.states2)); 4939 mPowerSaveModeEnabledTimer.startRunningLocked(elapsedRealtime); 4940 } else { 4941 mHistoryCur.states2 &= ~HistoryItem.STATE2_POWER_SAVE_FLAG; 4942 if (DEBUG_HISTORY) Slog.v(TAG, "Power save mode disabled to: " 4943 + Integer.toHexString(mHistoryCur.states2)); 4944 mPowerSaveModeEnabledTimer.stopRunningLocked(elapsedRealtime); 4945 } 4946 addHistoryRecordLocked(elapsedRealtime, uptime); 4947 StatsLog.write(StatsLog.BATTERY_SAVER_MODE_STATE_CHANGED, enabled ? 4948 StatsLog.BATTERY_SAVER_MODE_STATE_CHANGED__STATE__ON : 4949 StatsLog.BATTERY_SAVER_MODE_STATE_CHANGED__STATE__OFF); 4950 } 4951 } 4952 noteDeviceIdleModeLocked(final int mode, String activeReason, int activeUid)4953 public void noteDeviceIdleModeLocked(final int mode, String activeReason, int activeUid) { 4954 final long elapsedRealtime = mClocks.elapsedRealtime(); 4955 final long uptime = mClocks.uptimeMillis(); 4956 boolean nowIdling = mode == DEVICE_IDLE_MODE_DEEP; 4957 if (mDeviceIdling && !nowIdling && activeReason == null) { 4958 // We don't go out of general idling mode until explicitly taken out of 4959 // device idle through going active or significant motion. 4960 nowIdling = true; 4961 } 4962 boolean nowLightIdling = mode == DEVICE_IDLE_MODE_LIGHT; 4963 if (mDeviceLightIdling && !nowLightIdling && !nowIdling && activeReason == null) { 4964 // We don't go out of general light idling mode until explicitly taken out of 4965 // device idle through going active or significant motion. 4966 nowLightIdling = true; 4967 } 4968 if (activeReason != null && (mDeviceIdling || mDeviceLightIdling)) { 4969 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_ACTIVE, 4970 activeReason, activeUid); 4971 } 4972 if (mDeviceIdling != nowIdling || mDeviceLightIdling != nowLightIdling) { 4973 int statsmode; 4974 if (nowIdling) statsmode = DEVICE_IDLE_MODE_DEEP; 4975 else if (nowLightIdling) statsmode = DEVICE_IDLE_MODE_LIGHT; 4976 else statsmode = DEVICE_IDLE_MODE_OFF; 4977 StatsLog.write(StatsLog.DEVICE_IDLING_MODE_STATE_CHANGED, statsmode); 4978 } 4979 if (mDeviceIdling != nowIdling) { 4980 mDeviceIdling = nowIdling; 4981 int stepState = nowIdling ? STEP_LEVEL_MODE_DEVICE_IDLE : 0; 4982 mModStepMode |= (mCurStepMode&STEP_LEVEL_MODE_DEVICE_IDLE) ^ stepState; 4983 mCurStepMode = (mCurStepMode&~STEP_LEVEL_MODE_DEVICE_IDLE) | stepState; 4984 if (nowIdling) { 4985 mDeviceIdlingTimer.startRunningLocked(elapsedRealtime); 4986 } else { 4987 mDeviceIdlingTimer.stopRunningLocked(elapsedRealtime); 4988 } 4989 } 4990 if (mDeviceLightIdling != nowLightIdling) { 4991 mDeviceLightIdling = nowLightIdling; 4992 if (nowLightIdling) { 4993 mDeviceLightIdlingTimer.startRunningLocked(elapsedRealtime); 4994 } else { 4995 mDeviceLightIdlingTimer.stopRunningLocked(elapsedRealtime); 4996 } 4997 } 4998 if (mDeviceIdleMode != mode) { 4999 mHistoryCur.states2 = (mHistoryCur.states2 & ~HistoryItem.STATE2_DEVICE_IDLE_MASK) 5000 | (mode << HistoryItem.STATE2_DEVICE_IDLE_SHIFT); 5001 if (DEBUG_HISTORY) Slog.v(TAG, "Device idle mode changed to: " 5002 + Integer.toHexString(mHistoryCur.states2)); 5003 addHistoryRecordLocked(elapsedRealtime, uptime); 5004 long lastDuration = elapsedRealtime - mLastIdleTimeStart; 5005 mLastIdleTimeStart = elapsedRealtime; 5006 if (mDeviceIdleMode == DEVICE_IDLE_MODE_LIGHT) { 5007 if (lastDuration > mLongestLightIdleTime) { 5008 mLongestLightIdleTime = lastDuration; 5009 } 5010 mDeviceIdleModeLightTimer.stopRunningLocked(elapsedRealtime); 5011 } else if (mDeviceIdleMode == DEVICE_IDLE_MODE_DEEP) { 5012 if (lastDuration > mLongestFullIdleTime) { 5013 mLongestFullIdleTime = lastDuration; 5014 } 5015 mDeviceIdleModeFullTimer.stopRunningLocked(elapsedRealtime); 5016 } 5017 if (mode == DEVICE_IDLE_MODE_LIGHT) { 5018 mDeviceIdleModeLightTimer.startRunningLocked(elapsedRealtime); 5019 } else if (mode == DEVICE_IDLE_MODE_DEEP) { 5020 mDeviceIdleModeFullTimer.startRunningLocked(elapsedRealtime); 5021 } 5022 mDeviceIdleMode = mode; 5023 StatsLog.write(StatsLog.DEVICE_IDLE_MODE_STATE_CHANGED, mode); 5024 } 5025 } 5026 notePackageInstalledLocked(String pkgName, long versionCode)5027 public void notePackageInstalledLocked(String pkgName, long versionCode) { 5028 final long elapsedRealtime = mClocks.elapsedRealtime(); 5029 final long uptime = mClocks.uptimeMillis(); 5030 // XXX need to figure out what to do with long version codes. 5031 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_PACKAGE_INSTALLED, 5032 pkgName, (int)versionCode); 5033 PackageChange pc = new PackageChange(); 5034 pc.mPackageName = pkgName; 5035 pc.mUpdate = true; 5036 pc.mVersionCode = versionCode; 5037 addPackageChange(pc); 5038 } 5039 notePackageUninstalledLocked(String pkgName)5040 public void notePackageUninstalledLocked(String pkgName) { 5041 final long elapsedRealtime = mClocks.elapsedRealtime(); 5042 final long uptime = mClocks.uptimeMillis(); 5043 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_PACKAGE_UNINSTALLED, 5044 pkgName, 0); 5045 PackageChange pc = new PackageChange(); 5046 pc.mPackageName = pkgName; 5047 pc.mUpdate = true; 5048 addPackageChange(pc); 5049 } 5050 addPackageChange(PackageChange pc)5051 private void addPackageChange(PackageChange pc) { 5052 if (mDailyPackageChanges == null) { 5053 mDailyPackageChanges = new ArrayList<>(); 5054 } 5055 mDailyPackageChanges.add(pc); 5056 } 5057 stopAllGpsSignalQualityTimersLocked(int except)5058 void stopAllGpsSignalQualityTimersLocked(int except) { 5059 final long elapsedRealtime = mClocks.elapsedRealtime(); 5060 for (int i = 0; i < GnssMetrics.NUM_GPS_SIGNAL_QUALITY_LEVELS; i++) { 5061 if (i == except) { 5062 continue; 5063 } 5064 while (mGpsSignalQualityTimer[i].isRunningLocked()) { 5065 mGpsSignalQualityTimer[i].stopRunningLocked(elapsedRealtime); 5066 } 5067 } 5068 } 5069 5070 @UnsupportedAppUsage notePhoneOnLocked()5071 public void notePhoneOnLocked() { 5072 if (!mPhoneOn) { 5073 final long elapsedRealtime = mClocks.elapsedRealtime(); 5074 final long uptime = mClocks.uptimeMillis(); 5075 mHistoryCur.states2 |= HistoryItem.STATE2_PHONE_IN_CALL_FLAG; 5076 if (DEBUG_HISTORY) Slog.v(TAG, "Phone on to: " 5077 + Integer.toHexString(mHistoryCur.states)); 5078 addHistoryRecordLocked(elapsedRealtime, uptime); 5079 mPhoneOn = true; 5080 mPhoneOnTimer.startRunningLocked(elapsedRealtime); 5081 } 5082 } 5083 5084 @UnsupportedAppUsage notePhoneOffLocked()5085 public void notePhoneOffLocked() { 5086 if (mPhoneOn) { 5087 final long elapsedRealtime = mClocks.elapsedRealtime(); 5088 final long uptime = mClocks.uptimeMillis(); 5089 mHistoryCur.states2 &= ~HistoryItem.STATE2_PHONE_IN_CALL_FLAG; 5090 if (DEBUG_HISTORY) Slog.v(TAG, "Phone off to: " 5091 + Integer.toHexString(mHistoryCur.states)); 5092 addHistoryRecordLocked(elapsedRealtime, uptime); 5093 mPhoneOn = false; 5094 mPhoneOnTimer.stopRunningLocked(elapsedRealtime); 5095 } 5096 } 5097 registerUsbStateReceiver(Context context)5098 private void registerUsbStateReceiver(Context context) { 5099 final IntentFilter usbStateFilter = new IntentFilter(); 5100 usbStateFilter.addAction(UsbManager.ACTION_USB_STATE); 5101 context.registerReceiver(new BroadcastReceiver() { 5102 @Override 5103 public void onReceive(Context context, Intent intent) { 5104 final boolean state = intent.getBooleanExtra(UsbManager.USB_CONNECTED, false); 5105 synchronized (BatteryStatsImpl.this) { 5106 noteUsbConnectionStateLocked(state); 5107 } 5108 } 5109 }, usbStateFilter); 5110 synchronized (this) { 5111 if (mUsbDataState == USB_DATA_UNKNOWN) { 5112 final Intent usbState = context.registerReceiver(null, usbStateFilter); 5113 final boolean initState = usbState != null && usbState.getBooleanExtra( 5114 UsbManager.USB_CONNECTED, false); 5115 noteUsbConnectionStateLocked(initState); 5116 } 5117 } 5118 } 5119 noteUsbConnectionStateLocked(boolean connected)5120 private void noteUsbConnectionStateLocked(boolean connected) { 5121 int newState = connected ? USB_DATA_CONNECTED : USB_DATA_DISCONNECTED; 5122 if (mUsbDataState != newState) { 5123 mUsbDataState = newState; 5124 if (connected) { 5125 mHistoryCur.states2 |= HistoryItem.STATE2_USB_DATA_LINK_FLAG; 5126 } else { 5127 mHistoryCur.states2 &= ~HistoryItem.STATE2_USB_DATA_LINK_FLAG; 5128 } 5129 addHistoryRecordLocked(mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 5130 } 5131 } 5132 stopAllPhoneSignalStrengthTimersLocked(int except)5133 void stopAllPhoneSignalStrengthTimersLocked(int except) { 5134 final long elapsedRealtime = mClocks.elapsedRealtime(); 5135 for (int i = 0; i < SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) { 5136 if (i == except) { 5137 continue; 5138 } 5139 while (mPhoneSignalStrengthsTimer[i].isRunningLocked()) { 5140 mPhoneSignalStrengthsTimer[i].stopRunningLocked(elapsedRealtime); 5141 } 5142 } 5143 } 5144 fixPhoneServiceState(int state, int signalBin)5145 private int fixPhoneServiceState(int state, int signalBin) { 5146 if (mPhoneSimStateRaw == TelephonyManager.SIM_STATE_ABSENT) { 5147 // In this case we will always be STATE_OUT_OF_SERVICE, so need 5148 // to infer that we are scanning from other data. 5149 if (state == ServiceState.STATE_OUT_OF_SERVICE 5150 && signalBin > SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN) { 5151 state = ServiceState.STATE_IN_SERVICE; 5152 } 5153 } 5154 5155 return state; 5156 } 5157 updateAllPhoneStateLocked(int state, int simState, int strengthBin)5158 private void updateAllPhoneStateLocked(int state, int simState, int strengthBin) { 5159 boolean scanning = false; 5160 boolean newHistory = false; 5161 5162 mPhoneServiceStateRaw = state; 5163 mPhoneSimStateRaw = simState; 5164 mPhoneSignalStrengthBinRaw = strengthBin; 5165 5166 final long elapsedRealtime = mClocks.elapsedRealtime(); 5167 final long uptime = mClocks.uptimeMillis(); 5168 5169 if (simState == TelephonyManager.SIM_STATE_ABSENT) { 5170 // In this case we will always be STATE_OUT_OF_SERVICE, so need 5171 // to infer that we are scanning from other data. 5172 if (state == ServiceState.STATE_OUT_OF_SERVICE 5173 && strengthBin > SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN) { 5174 state = ServiceState.STATE_IN_SERVICE; 5175 } 5176 } 5177 5178 // If the phone is powered off, stop all timers. 5179 if (state == ServiceState.STATE_POWER_OFF) { 5180 strengthBin = -1; 5181 5182 // If we are in service, make sure the correct signal string timer is running. 5183 } else if (state == ServiceState.STATE_IN_SERVICE) { 5184 // Bin will be changed below. 5185 5186 // If we're out of service, we are in the lowest signal strength 5187 // bin and have the scanning bit set. 5188 } else if (state == ServiceState.STATE_OUT_OF_SERVICE) { 5189 scanning = true; 5190 strengthBin = SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN; 5191 if (!mPhoneSignalScanningTimer.isRunningLocked()) { 5192 mHistoryCur.states |= HistoryItem.STATE_PHONE_SCANNING_FLAG; 5193 newHistory = true; 5194 if (DEBUG_HISTORY) Slog.v(TAG, "Phone started scanning to: " 5195 + Integer.toHexString(mHistoryCur.states)); 5196 mPhoneSignalScanningTimer.startRunningLocked(elapsedRealtime); 5197 StatsLog.write(StatsLog.PHONE_SERVICE_STATE_CHANGED, state, simState, strengthBin); 5198 } 5199 } 5200 5201 if (!scanning) { 5202 // If we are no longer scanning, then stop the scanning timer. 5203 if (mPhoneSignalScanningTimer.isRunningLocked()) { 5204 mHistoryCur.states &= ~HistoryItem.STATE_PHONE_SCANNING_FLAG; 5205 if (DEBUG_HISTORY) Slog.v(TAG, "Phone stopped scanning to: " 5206 + Integer.toHexString(mHistoryCur.states)); 5207 newHistory = true; 5208 mPhoneSignalScanningTimer.stopRunningLocked(elapsedRealtime); 5209 StatsLog.write(StatsLog.PHONE_SERVICE_STATE_CHANGED, state, simState, strengthBin); 5210 } 5211 } 5212 5213 if (mPhoneServiceState != state) { 5214 mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_PHONE_STATE_MASK) 5215 | (state << HistoryItem.STATE_PHONE_STATE_SHIFT); 5216 if (DEBUG_HISTORY) Slog.v(TAG, "Phone state " + state + " to: " 5217 + Integer.toHexString(mHistoryCur.states)); 5218 newHistory = true; 5219 mPhoneServiceState = state; 5220 } 5221 5222 if (mPhoneSignalStrengthBin != strengthBin) { 5223 if (mPhoneSignalStrengthBin >= 0) { 5224 mPhoneSignalStrengthsTimer[mPhoneSignalStrengthBin].stopRunningLocked( 5225 elapsedRealtime); 5226 } 5227 if (strengthBin >= 0) { 5228 if (!mPhoneSignalStrengthsTimer[strengthBin].isRunningLocked()) { 5229 mPhoneSignalStrengthsTimer[strengthBin].startRunningLocked(elapsedRealtime); 5230 } 5231 mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_PHONE_SIGNAL_STRENGTH_MASK) 5232 | (strengthBin << HistoryItem.STATE_PHONE_SIGNAL_STRENGTH_SHIFT); 5233 if (DEBUG_HISTORY) Slog.v(TAG, "Signal strength " + strengthBin + " to: " 5234 + Integer.toHexString(mHistoryCur.states)); 5235 newHistory = true; 5236 StatsLog.write(StatsLog.PHONE_SIGNAL_STRENGTH_CHANGED, strengthBin); 5237 } else { 5238 stopAllPhoneSignalStrengthTimersLocked(-1); 5239 } 5240 mPhoneSignalStrengthBin = strengthBin; 5241 } 5242 5243 if (newHistory) { 5244 addHistoryRecordLocked(elapsedRealtime, uptime); 5245 } 5246 } 5247 5248 /** 5249 * Telephony stack updates the phone state. 5250 * @param state phone state from ServiceState.getState() 5251 */ notePhoneStateLocked(int state, int simState)5252 public void notePhoneStateLocked(int state, int simState) { 5253 updateAllPhoneStateLocked(state, simState, mPhoneSignalStrengthBinRaw); 5254 } 5255 5256 @UnsupportedAppUsage notePhoneSignalStrengthLocked(SignalStrength signalStrength)5257 public void notePhoneSignalStrengthLocked(SignalStrength signalStrength) { 5258 // Bin the strength. 5259 int bin = signalStrength.getLevel(); 5260 updateAllPhoneStateLocked(mPhoneServiceStateRaw, mPhoneSimStateRaw, bin); 5261 } 5262 5263 @UnsupportedAppUsage notePhoneDataConnectionStateLocked(int dataType, boolean hasData)5264 public void notePhoneDataConnectionStateLocked(int dataType, boolean hasData) { 5265 // BatteryStats uses 0 to represent no network type. 5266 // Telephony does not have a concept of no network type, and uses 0 to represent unknown. 5267 // Unknown is included in DATA_CONNECTION_OTHER. 5268 int bin = DATA_CONNECTION_NONE; 5269 if (hasData) { 5270 if (dataType > 0 && dataType <= TelephonyManager.MAX_NETWORK_TYPE) { 5271 bin = dataType; 5272 } else { 5273 bin = DATA_CONNECTION_OTHER; 5274 } 5275 } 5276 if (DEBUG) Log.i(TAG, "Phone Data Connection -> " + dataType + " = " + hasData); 5277 if (mPhoneDataConnectionType != bin) { 5278 final long elapsedRealtime = mClocks.elapsedRealtime(); 5279 final long uptime = mClocks.uptimeMillis(); 5280 mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_DATA_CONNECTION_MASK) 5281 | (bin << HistoryItem.STATE_DATA_CONNECTION_SHIFT); 5282 if (DEBUG_HISTORY) Slog.v(TAG, "Data connection " + bin + " to: " 5283 + Integer.toHexString(mHistoryCur.states)); 5284 addHistoryRecordLocked(elapsedRealtime, uptime); 5285 if (mPhoneDataConnectionType >= 0) { 5286 mPhoneDataConnectionsTimer[mPhoneDataConnectionType].stopRunningLocked( 5287 elapsedRealtime); 5288 } 5289 mPhoneDataConnectionType = bin; 5290 mPhoneDataConnectionsTimer[bin].startRunningLocked(elapsedRealtime); 5291 } 5292 } 5293 noteWifiOnLocked()5294 public void noteWifiOnLocked() { 5295 if (!mWifiOn) { 5296 final long elapsedRealtime = mClocks.elapsedRealtime(); 5297 final long uptime = mClocks.uptimeMillis(); 5298 mHistoryCur.states2 |= HistoryItem.STATE2_WIFI_ON_FLAG; 5299 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI on to: " 5300 + Integer.toHexString(mHistoryCur.states)); 5301 addHistoryRecordLocked(elapsedRealtime, uptime); 5302 mWifiOn = true; 5303 mWifiOnTimer.startRunningLocked(elapsedRealtime); 5304 scheduleSyncExternalStatsLocked("wifi-off", ExternalStatsSync.UPDATE_WIFI); 5305 } 5306 } 5307 noteWifiOffLocked()5308 public void noteWifiOffLocked() { 5309 final long elapsedRealtime = mClocks.elapsedRealtime(); 5310 final long uptime = mClocks.uptimeMillis(); 5311 if (mWifiOn) { 5312 mHistoryCur.states2 &= ~HistoryItem.STATE2_WIFI_ON_FLAG; 5313 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI off to: " 5314 + Integer.toHexString(mHistoryCur.states)); 5315 addHistoryRecordLocked(elapsedRealtime, uptime); 5316 mWifiOn = false; 5317 mWifiOnTimer.stopRunningLocked(elapsedRealtime); 5318 scheduleSyncExternalStatsLocked("wifi-on", ExternalStatsSync.UPDATE_WIFI); 5319 } 5320 } 5321 5322 @UnsupportedAppUsage noteAudioOnLocked(int uid)5323 public void noteAudioOnLocked(int uid) { 5324 uid = mapUid(uid); 5325 final long elapsedRealtime = mClocks.elapsedRealtime(); 5326 final long uptime = mClocks.uptimeMillis(); 5327 if (mAudioOnNesting == 0) { 5328 mHistoryCur.states |= HistoryItem.STATE_AUDIO_ON_FLAG; 5329 if (DEBUG_HISTORY) Slog.v(TAG, "Audio on to: " 5330 + Integer.toHexString(mHistoryCur.states)); 5331 addHistoryRecordLocked(elapsedRealtime, uptime); 5332 mAudioOnTimer.startRunningLocked(elapsedRealtime); 5333 } 5334 mAudioOnNesting++; 5335 getUidStatsLocked(uid).noteAudioTurnedOnLocked(elapsedRealtime); 5336 } 5337 5338 @UnsupportedAppUsage noteAudioOffLocked(int uid)5339 public void noteAudioOffLocked(int uid) { 5340 if (mAudioOnNesting == 0) { 5341 return; 5342 } 5343 uid = mapUid(uid); 5344 final long elapsedRealtime = mClocks.elapsedRealtime(); 5345 final long uptime = mClocks.uptimeMillis(); 5346 if (--mAudioOnNesting == 0) { 5347 mHistoryCur.states &= ~HistoryItem.STATE_AUDIO_ON_FLAG; 5348 if (DEBUG_HISTORY) Slog.v(TAG, "Audio off to: " 5349 + Integer.toHexString(mHistoryCur.states)); 5350 addHistoryRecordLocked(elapsedRealtime, uptime); 5351 mAudioOnTimer.stopRunningLocked(elapsedRealtime); 5352 } 5353 getUidStatsLocked(uid).noteAudioTurnedOffLocked(elapsedRealtime); 5354 } 5355 5356 @UnsupportedAppUsage noteVideoOnLocked(int uid)5357 public void noteVideoOnLocked(int uid) { 5358 uid = mapUid(uid); 5359 final long elapsedRealtime = mClocks.elapsedRealtime(); 5360 final long uptime = mClocks.uptimeMillis(); 5361 if (mVideoOnNesting == 0) { 5362 mHistoryCur.states2 |= HistoryItem.STATE2_VIDEO_ON_FLAG; 5363 if (DEBUG_HISTORY) Slog.v(TAG, "Video on to: " 5364 + Integer.toHexString(mHistoryCur.states)); 5365 addHistoryRecordLocked(elapsedRealtime, uptime); 5366 mVideoOnTimer.startRunningLocked(elapsedRealtime); 5367 } 5368 mVideoOnNesting++; 5369 getUidStatsLocked(uid).noteVideoTurnedOnLocked(elapsedRealtime); 5370 } 5371 5372 @UnsupportedAppUsage noteVideoOffLocked(int uid)5373 public void noteVideoOffLocked(int uid) { 5374 if (mVideoOnNesting == 0) { 5375 return; 5376 } 5377 uid = mapUid(uid); 5378 final long elapsedRealtime = mClocks.elapsedRealtime(); 5379 final long uptime = mClocks.uptimeMillis(); 5380 if (--mVideoOnNesting == 0) { 5381 mHistoryCur.states2 &= ~HistoryItem.STATE2_VIDEO_ON_FLAG; 5382 if (DEBUG_HISTORY) Slog.v(TAG, "Video off to: " 5383 + Integer.toHexString(mHistoryCur.states)); 5384 addHistoryRecordLocked(elapsedRealtime, uptime); 5385 mVideoOnTimer.stopRunningLocked(elapsedRealtime); 5386 } 5387 getUidStatsLocked(uid).noteVideoTurnedOffLocked(elapsedRealtime); 5388 } 5389 noteResetAudioLocked()5390 public void noteResetAudioLocked() { 5391 if (mAudioOnNesting > 0) { 5392 final long elapsedRealtime = mClocks.elapsedRealtime(); 5393 final long uptime = mClocks.uptimeMillis(); 5394 mAudioOnNesting = 0; 5395 mHistoryCur.states &= ~HistoryItem.STATE_AUDIO_ON_FLAG; 5396 if (DEBUG_HISTORY) Slog.v(TAG, "Audio off to: " 5397 + Integer.toHexString(mHistoryCur.states)); 5398 addHistoryRecordLocked(elapsedRealtime, uptime); 5399 mAudioOnTimer.stopAllRunningLocked(elapsedRealtime); 5400 for (int i=0; i<mUidStats.size(); i++) { 5401 BatteryStatsImpl.Uid uid = mUidStats.valueAt(i); 5402 uid.noteResetAudioLocked(elapsedRealtime); 5403 } 5404 } 5405 } 5406 noteResetVideoLocked()5407 public void noteResetVideoLocked() { 5408 if (mVideoOnNesting > 0) { 5409 final long elapsedRealtime = mClocks.elapsedRealtime(); 5410 final long uptime = mClocks.uptimeMillis(); 5411 mAudioOnNesting = 0; 5412 mHistoryCur.states2 &= ~HistoryItem.STATE2_VIDEO_ON_FLAG; 5413 if (DEBUG_HISTORY) Slog.v(TAG, "Video off to: " 5414 + Integer.toHexString(mHistoryCur.states)); 5415 addHistoryRecordLocked(elapsedRealtime, uptime); 5416 mVideoOnTimer.stopAllRunningLocked(elapsedRealtime); 5417 for (int i=0; i<mUidStats.size(); i++) { 5418 BatteryStatsImpl.Uid uid = mUidStats.valueAt(i); 5419 uid.noteResetVideoLocked(elapsedRealtime); 5420 } 5421 } 5422 } 5423 noteActivityResumedLocked(int uid)5424 public void noteActivityResumedLocked(int uid) { 5425 uid = mapUid(uid); 5426 getUidStatsLocked(uid).noteActivityResumedLocked(mClocks.elapsedRealtime()); 5427 } 5428 noteActivityPausedLocked(int uid)5429 public void noteActivityPausedLocked(int uid) { 5430 uid = mapUid(uid); 5431 getUidStatsLocked(uid).noteActivityPausedLocked(mClocks.elapsedRealtime()); 5432 } 5433 noteVibratorOnLocked(int uid, long durationMillis)5434 public void noteVibratorOnLocked(int uid, long durationMillis) { 5435 uid = mapUid(uid); 5436 getUidStatsLocked(uid).noteVibratorOnLocked(durationMillis); 5437 } 5438 noteVibratorOffLocked(int uid)5439 public void noteVibratorOffLocked(int uid) { 5440 uid = mapUid(uid); 5441 getUidStatsLocked(uid).noteVibratorOffLocked(); 5442 } 5443 noteFlashlightOnLocked(int uid)5444 public void noteFlashlightOnLocked(int uid) { 5445 uid = mapUid(uid); 5446 final long elapsedRealtime = mClocks.elapsedRealtime(); 5447 final long uptime = mClocks.uptimeMillis(); 5448 if (mFlashlightOnNesting++ == 0) { 5449 mHistoryCur.states2 |= HistoryItem.STATE2_FLASHLIGHT_FLAG; 5450 if (DEBUG_HISTORY) Slog.v(TAG, "Flashlight on to: " 5451 + Integer.toHexString(mHistoryCur.states2)); 5452 addHistoryRecordLocked(elapsedRealtime, uptime); 5453 mFlashlightOnTimer.startRunningLocked(elapsedRealtime); 5454 } 5455 getUidStatsLocked(uid).noteFlashlightTurnedOnLocked(elapsedRealtime); 5456 } 5457 noteFlashlightOffLocked(int uid)5458 public void noteFlashlightOffLocked(int uid) { 5459 if (mFlashlightOnNesting == 0) { 5460 return; 5461 } 5462 uid = mapUid(uid); 5463 final long elapsedRealtime = mClocks.elapsedRealtime(); 5464 final long uptime = mClocks.uptimeMillis(); 5465 if (--mFlashlightOnNesting == 0) { 5466 mHistoryCur.states2 &= ~HistoryItem.STATE2_FLASHLIGHT_FLAG; 5467 if (DEBUG_HISTORY) Slog.v(TAG, "Flashlight off to: " 5468 + Integer.toHexString(mHistoryCur.states2)); 5469 addHistoryRecordLocked(elapsedRealtime, uptime); 5470 mFlashlightOnTimer.stopRunningLocked(elapsedRealtime); 5471 } 5472 getUidStatsLocked(uid).noteFlashlightTurnedOffLocked(elapsedRealtime); 5473 } 5474 noteCameraOnLocked(int uid)5475 public void noteCameraOnLocked(int uid) { 5476 uid = mapUid(uid); 5477 final long elapsedRealtime = mClocks.elapsedRealtime(); 5478 final long uptime = mClocks.uptimeMillis(); 5479 if (mCameraOnNesting++ == 0) { 5480 mHistoryCur.states2 |= HistoryItem.STATE2_CAMERA_FLAG; 5481 if (DEBUG_HISTORY) Slog.v(TAG, "Camera on to: " 5482 + Integer.toHexString(mHistoryCur.states2)); 5483 addHistoryRecordLocked(elapsedRealtime, uptime); 5484 mCameraOnTimer.startRunningLocked(elapsedRealtime); 5485 } 5486 getUidStatsLocked(uid).noteCameraTurnedOnLocked(elapsedRealtime); 5487 } 5488 noteCameraOffLocked(int uid)5489 public void noteCameraOffLocked(int uid) { 5490 if (mCameraOnNesting == 0) { 5491 return; 5492 } 5493 uid = mapUid(uid); 5494 final long elapsedRealtime = mClocks.elapsedRealtime(); 5495 final long uptime = mClocks.uptimeMillis(); 5496 if (--mCameraOnNesting == 0) { 5497 mHistoryCur.states2 &= ~HistoryItem.STATE2_CAMERA_FLAG; 5498 if (DEBUG_HISTORY) Slog.v(TAG, "Camera off to: " 5499 + Integer.toHexString(mHistoryCur.states2)); 5500 addHistoryRecordLocked(elapsedRealtime, uptime); 5501 mCameraOnTimer.stopRunningLocked(elapsedRealtime); 5502 } 5503 getUidStatsLocked(uid).noteCameraTurnedOffLocked(elapsedRealtime); 5504 } 5505 noteResetCameraLocked()5506 public void noteResetCameraLocked() { 5507 if (mCameraOnNesting > 0) { 5508 final long elapsedRealtime = mClocks.elapsedRealtime(); 5509 final long uptime = mClocks.uptimeMillis(); 5510 mCameraOnNesting = 0; 5511 mHistoryCur.states2 &= ~HistoryItem.STATE2_CAMERA_FLAG; 5512 if (DEBUG_HISTORY) Slog.v(TAG, "Camera off to: " 5513 + Integer.toHexString(mHistoryCur.states2)); 5514 addHistoryRecordLocked(elapsedRealtime, uptime); 5515 mCameraOnTimer.stopAllRunningLocked(elapsedRealtime); 5516 for (int i=0; i<mUidStats.size(); i++) { 5517 BatteryStatsImpl.Uid uid = mUidStats.valueAt(i); 5518 uid.noteResetCameraLocked(elapsedRealtime); 5519 } 5520 } 5521 } 5522 noteResetFlashlightLocked()5523 public void noteResetFlashlightLocked() { 5524 if (mFlashlightOnNesting > 0) { 5525 final long elapsedRealtime = mClocks.elapsedRealtime(); 5526 final long uptime = mClocks.uptimeMillis(); 5527 mFlashlightOnNesting = 0; 5528 mHistoryCur.states2 &= ~HistoryItem.STATE2_FLASHLIGHT_FLAG; 5529 if (DEBUG_HISTORY) Slog.v(TAG, "Flashlight off to: " 5530 + Integer.toHexString(mHistoryCur.states2)); 5531 addHistoryRecordLocked(elapsedRealtime, uptime); 5532 mFlashlightOnTimer.stopAllRunningLocked(elapsedRealtime); 5533 for (int i=0; i<mUidStats.size(); i++) { 5534 BatteryStatsImpl.Uid uid = mUidStats.valueAt(i); 5535 uid.noteResetFlashlightLocked(elapsedRealtime); 5536 } 5537 } 5538 } 5539 noteBluetoothScanStartedLocked(WorkChain workChain, int uid, boolean isUnoptimized)5540 private void noteBluetoothScanStartedLocked(WorkChain workChain, int uid, 5541 boolean isUnoptimized) { 5542 uid = getAttributionUid(uid, workChain); 5543 final long elapsedRealtime = mClocks.elapsedRealtime(); 5544 final long uptime = mClocks.uptimeMillis(); 5545 if (mBluetoothScanNesting == 0) { 5546 mHistoryCur.states2 |= HistoryItem.STATE2_BLUETOOTH_SCAN_FLAG; 5547 if (DEBUG_HISTORY) Slog.v(TAG, "BLE scan started for: " 5548 + Integer.toHexString(mHistoryCur.states2)); 5549 addHistoryRecordLocked(elapsedRealtime, uptime); 5550 mBluetoothScanTimer.startRunningLocked(elapsedRealtime); 5551 } 5552 mBluetoothScanNesting++; 5553 getUidStatsLocked(uid).noteBluetoothScanStartedLocked(elapsedRealtime, isUnoptimized); 5554 } 5555 noteBluetoothScanStartedFromSourceLocked(WorkSource ws, boolean isUnoptimized)5556 public void noteBluetoothScanStartedFromSourceLocked(WorkSource ws, boolean isUnoptimized) { 5557 final int N = ws.size(); 5558 for (int i = 0; i < N; i++) { 5559 noteBluetoothScanStartedLocked(null, ws.get(i), isUnoptimized); 5560 } 5561 5562 final List<WorkChain> workChains = ws.getWorkChains(); 5563 if (workChains != null) { 5564 for (int i = 0; i < workChains.size(); ++i) { 5565 noteBluetoothScanStartedLocked(workChains.get(i), -1, isUnoptimized); 5566 } 5567 } 5568 } 5569 noteBluetoothScanStoppedLocked(WorkChain workChain, int uid, boolean isUnoptimized)5570 private void noteBluetoothScanStoppedLocked(WorkChain workChain, int uid, 5571 boolean isUnoptimized) { 5572 uid = getAttributionUid(uid, workChain); 5573 final long elapsedRealtime = mClocks.elapsedRealtime(); 5574 final long uptime = mClocks.uptimeMillis(); 5575 mBluetoothScanNesting--; 5576 if (mBluetoothScanNesting == 0) { 5577 mHistoryCur.states2 &= ~HistoryItem.STATE2_BLUETOOTH_SCAN_FLAG; 5578 if (DEBUG_HISTORY) Slog.v(TAG, "BLE scan stopped for: " 5579 + Integer.toHexString(mHistoryCur.states2)); 5580 addHistoryRecordLocked(elapsedRealtime, uptime); 5581 mBluetoothScanTimer.stopRunningLocked(elapsedRealtime); 5582 } 5583 getUidStatsLocked(uid).noteBluetoothScanStoppedLocked(elapsedRealtime, isUnoptimized); 5584 } 5585 getAttributionUid(int uid, WorkChain workChain)5586 private int getAttributionUid(int uid, WorkChain workChain) { 5587 if (workChain != null) { 5588 return mapUid(workChain.getAttributionUid()); 5589 } 5590 5591 return mapUid(uid); 5592 } 5593 noteBluetoothScanStoppedFromSourceLocked(WorkSource ws, boolean isUnoptimized)5594 public void noteBluetoothScanStoppedFromSourceLocked(WorkSource ws, boolean isUnoptimized) { 5595 final int N = ws.size(); 5596 for (int i = 0; i < N; i++) { 5597 noteBluetoothScanStoppedLocked(null, ws.get(i), isUnoptimized); 5598 } 5599 5600 final List<WorkChain> workChains = ws.getWorkChains(); 5601 if (workChains != null) { 5602 for (int i = 0; i < workChains.size(); ++i) { 5603 noteBluetoothScanStoppedLocked(workChains.get(i), -1, isUnoptimized); 5604 } 5605 } 5606 } 5607 noteResetBluetoothScanLocked()5608 public void noteResetBluetoothScanLocked() { 5609 if (mBluetoothScanNesting > 0) { 5610 final long elapsedRealtime = mClocks.elapsedRealtime(); 5611 final long uptime = mClocks.uptimeMillis(); 5612 mBluetoothScanNesting = 0; 5613 mHistoryCur.states2 &= ~HistoryItem.STATE2_BLUETOOTH_SCAN_FLAG; 5614 if (DEBUG_HISTORY) Slog.v(TAG, "BLE can stopped for: " 5615 + Integer.toHexString(mHistoryCur.states2)); 5616 addHistoryRecordLocked(elapsedRealtime, uptime); 5617 mBluetoothScanTimer.stopAllRunningLocked(elapsedRealtime); 5618 for (int i=0; i<mUidStats.size(); i++) { 5619 BatteryStatsImpl.Uid uid = mUidStats.valueAt(i); 5620 uid.noteResetBluetoothScanLocked(elapsedRealtime); 5621 } 5622 } 5623 } 5624 noteBluetoothScanResultsFromSourceLocked(WorkSource ws, int numNewResults)5625 public void noteBluetoothScanResultsFromSourceLocked(WorkSource ws, int numNewResults) { 5626 final int N = ws.size(); 5627 for (int i = 0; i < N; i++) { 5628 int uid = mapUid(ws.get(i)); 5629 getUidStatsLocked(uid).noteBluetoothScanResultsLocked(numNewResults); 5630 } 5631 5632 final List<WorkChain> workChains = ws.getWorkChains(); 5633 if (workChains != null) { 5634 for (int i = 0; i < workChains.size(); ++i) { 5635 final WorkChain wc = workChains.get(i); 5636 int uid = mapUid(wc.getAttributionUid()); 5637 getUidStatsLocked(uid).noteBluetoothScanResultsLocked(numNewResults); 5638 } 5639 } 5640 } 5641 noteWifiRadioApWakeupLocked(final long elapsedRealtimeMillis, final long uptimeMillis, int uid)5642 private void noteWifiRadioApWakeupLocked(final long elapsedRealtimeMillis, 5643 final long uptimeMillis, int uid) { 5644 uid = mapUid(uid); 5645 addHistoryEventLocked(elapsedRealtimeMillis, uptimeMillis, HistoryItem.EVENT_WAKEUP_AP, "", 5646 uid); 5647 getUidStatsLocked(uid).noteWifiRadioApWakeupLocked(); 5648 } 5649 noteWifiRadioPowerState(int powerState, long timestampNs, int uid)5650 public void noteWifiRadioPowerState(int powerState, long timestampNs, int uid) { 5651 final long elapsedRealtime = mClocks.elapsedRealtime(); 5652 final long uptime = mClocks.uptimeMillis(); 5653 if (mWifiRadioPowerState != powerState) { 5654 final boolean active = 5655 powerState == DataConnectionRealTimeInfo.DC_POWER_STATE_MEDIUM 5656 || powerState == DataConnectionRealTimeInfo.DC_POWER_STATE_HIGH; 5657 if (active) { 5658 if (uid > 0) { 5659 noteWifiRadioApWakeupLocked(elapsedRealtime, uptime, uid); 5660 } 5661 mHistoryCur.states |= HistoryItem.STATE_WIFI_RADIO_ACTIVE_FLAG; 5662 mWifiActiveTimer.startRunningLocked(elapsedRealtime); 5663 } else { 5664 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_RADIO_ACTIVE_FLAG; 5665 mWifiActiveTimer.stopRunningLocked( 5666 timestampNs / (1000 * 1000)); 5667 } 5668 if (DEBUG_HISTORY) Slog.v(TAG, "Wifi network active " + active + " to: " 5669 + Integer.toHexString(mHistoryCur.states)); 5670 addHistoryRecordLocked(elapsedRealtime, uptime); 5671 mWifiRadioPowerState = powerState; 5672 } 5673 } 5674 noteWifiRunningLocked(WorkSource ws)5675 public void noteWifiRunningLocked(WorkSource ws) { 5676 if (!mGlobalWifiRunning) { 5677 final long elapsedRealtime = mClocks.elapsedRealtime(); 5678 final long uptime = mClocks.uptimeMillis(); 5679 mHistoryCur.states2 |= HistoryItem.STATE2_WIFI_RUNNING_FLAG; 5680 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI running to: " 5681 + Integer.toHexString(mHistoryCur.states)); 5682 addHistoryRecordLocked(elapsedRealtime, uptime); 5683 mGlobalWifiRunning = true; 5684 mGlobalWifiRunningTimer.startRunningLocked(elapsedRealtime); 5685 int N = ws.size(); 5686 for (int i=0; i<N; i++) { 5687 int uid = mapUid(ws.get(i)); 5688 getUidStatsLocked(uid).noteWifiRunningLocked(elapsedRealtime); 5689 } 5690 5691 List<WorkChain> workChains = ws.getWorkChains(); 5692 if (workChains != null) { 5693 for (int i = 0; i < workChains.size(); ++i) { 5694 int uid = mapUid(workChains.get(i).getAttributionUid()); 5695 getUidStatsLocked(uid).noteWifiRunningLocked(elapsedRealtime); 5696 } 5697 } 5698 5699 scheduleSyncExternalStatsLocked("wifi-running", ExternalStatsSync.UPDATE_WIFI); 5700 } else { 5701 Log.w(TAG, "noteWifiRunningLocked -- called while WIFI running"); 5702 } 5703 } 5704 noteWifiRunningChangedLocked(WorkSource oldWs, WorkSource newWs)5705 public void noteWifiRunningChangedLocked(WorkSource oldWs, WorkSource newWs) { 5706 if (mGlobalWifiRunning) { 5707 final long elapsedRealtime = mClocks.elapsedRealtime(); 5708 int N = oldWs.size(); 5709 for (int i=0; i<N; i++) { 5710 int uid = mapUid(oldWs.get(i)); 5711 getUidStatsLocked(uid).noteWifiStoppedLocked(elapsedRealtime); 5712 } 5713 5714 List<WorkChain> workChains = oldWs.getWorkChains(); 5715 if (workChains != null) { 5716 for (int i = 0; i < workChains.size(); ++i) { 5717 int uid = mapUid(workChains.get(i).getAttributionUid()); 5718 getUidStatsLocked(uid).noteWifiStoppedLocked(elapsedRealtime); 5719 } 5720 } 5721 5722 N = newWs.size(); 5723 for (int i=0; i<N; i++) { 5724 int uid = mapUid(newWs.get(i)); 5725 getUidStatsLocked(uid).noteWifiRunningLocked(elapsedRealtime); 5726 } 5727 5728 workChains = newWs.getWorkChains(); 5729 if (workChains != null) { 5730 for (int i = 0; i < workChains.size(); ++i) { 5731 int uid = mapUid(workChains.get(i).getAttributionUid()); 5732 getUidStatsLocked(uid).noteWifiRunningLocked(elapsedRealtime); 5733 } 5734 } 5735 } else { 5736 Log.w(TAG, "noteWifiRunningChangedLocked -- called while WIFI not running"); 5737 } 5738 } 5739 noteWifiStoppedLocked(WorkSource ws)5740 public void noteWifiStoppedLocked(WorkSource ws) { 5741 if (mGlobalWifiRunning) { 5742 final long elapsedRealtime = mClocks.elapsedRealtime(); 5743 final long uptime = mClocks.uptimeMillis(); 5744 mHistoryCur.states2 &= ~HistoryItem.STATE2_WIFI_RUNNING_FLAG; 5745 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI stopped to: " 5746 + Integer.toHexString(mHistoryCur.states)); 5747 addHistoryRecordLocked(elapsedRealtime, uptime); 5748 mGlobalWifiRunning = false; 5749 mGlobalWifiRunningTimer.stopRunningLocked(elapsedRealtime); 5750 int N = ws.size(); 5751 for (int i=0; i<N; i++) { 5752 int uid = mapUid(ws.get(i)); 5753 getUidStatsLocked(uid).noteWifiStoppedLocked(elapsedRealtime); 5754 } 5755 5756 List<WorkChain> workChains = ws.getWorkChains(); 5757 if (workChains != null) { 5758 for (int i = 0; i < workChains.size(); ++i) { 5759 int uid = mapUid(workChains.get(i).getAttributionUid()); 5760 getUidStatsLocked(uid).noteWifiStoppedLocked(elapsedRealtime); 5761 } 5762 } 5763 5764 scheduleSyncExternalStatsLocked("wifi-stopped", ExternalStatsSync.UPDATE_WIFI); 5765 } else { 5766 Log.w(TAG, "noteWifiStoppedLocked -- called while WIFI not running"); 5767 } 5768 } 5769 noteWifiStateLocked(int wifiState, String accessPoint)5770 public void noteWifiStateLocked(int wifiState, String accessPoint) { 5771 if (DEBUG) Log.i(TAG, "WiFi state -> " + wifiState); 5772 if (mWifiState != wifiState) { 5773 final long elapsedRealtime = mClocks.elapsedRealtime(); 5774 if (mWifiState >= 0) { 5775 mWifiStateTimer[mWifiState].stopRunningLocked(elapsedRealtime); 5776 } 5777 mWifiState = wifiState; 5778 mWifiStateTimer[wifiState].startRunningLocked(elapsedRealtime); 5779 scheduleSyncExternalStatsLocked("wifi-state", ExternalStatsSync.UPDATE_WIFI); 5780 } 5781 } 5782 noteWifiSupplicantStateChangedLocked(int supplState, boolean failedAuth)5783 public void noteWifiSupplicantStateChangedLocked(int supplState, boolean failedAuth) { 5784 if (DEBUG) Log.i(TAG, "WiFi suppl state -> " + supplState); 5785 if (mWifiSupplState != supplState) { 5786 final long elapsedRealtime = mClocks.elapsedRealtime(); 5787 final long uptime = mClocks.uptimeMillis(); 5788 if (mWifiSupplState >= 0) { 5789 mWifiSupplStateTimer[mWifiSupplState].stopRunningLocked(elapsedRealtime); 5790 } 5791 mWifiSupplState = supplState; 5792 mWifiSupplStateTimer[supplState].startRunningLocked(elapsedRealtime); 5793 mHistoryCur.states2 = 5794 (mHistoryCur.states2&~HistoryItem.STATE2_WIFI_SUPPL_STATE_MASK) 5795 | (supplState << HistoryItem.STATE2_WIFI_SUPPL_STATE_SHIFT); 5796 if (DEBUG_HISTORY) Slog.v(TAG, "Wifi suppl state " + supplState + " to: " 5797 + Integer.toHexString(mHistoryCur.states2)); 5798 addHistoryRecordLocked(elapsedRealtime, uptime); 5799 } 5800 } 5801 stopAllWifiSignalStrengthTimersLocked(int except)5802 void stopAllWifiSignalStrengthTimersLocked(int except) { 5803 final long elapsedRealtime = mClocks.elapsedRealtime(); 5804 for (int i = 0; i < NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { 5805 if (i == except) { 5806 continue; 5807 } 5808 while (mWifiSignalStrengthsTimer[i].isRunningLocked()) { 5809 mWifiSignalStrengthsTimer[i].stopRunningLocked(elapsedRealtime); 5810 } 5811 } 5812 } 5813 noteWifiRssiChangedLocked(int newRssi)5814 public void noteWifiRssiChangedLocked(int newRssi) { 5815 int strengthBin = WifiManager.calculateSignalLevel(newRssi, NUM_WIFI_SIGNAL_STRENGTH_BINS); 5816 if (DEBUG) Log.i(TAG, "WiFi rssi -> " + newRssi + " bin=" + strengthBin); 5817 if (mWifiSignalStrengthBin != strengthBin) { 5818 final long elapsedRealtime = mClocks.elapsedRealtime(); 5819 final long uptime = mClocks.uptimeMillis(); 5820 if (mWifiSignalStrengthBin >= 0) { 5821 mWifiSignalStrengthsTimer[mWifiSignalStrengthBin].stopRunningLocked( 5822 elapsedRealtime); 5823 } 5824 if (strengthBin >= 0) { 5825 if (!mWifiSignalStrengthsTimer[strengthBin].isRunningLocked()) { 5826 mWifiSignalStrengthsTimer[strengthBin].startRunningLocked(elapsedRealtime); 5827 } 5828 mHistoryCur.states2 = 5829 (mHistoryCur.states2&~HistoryItem.STATE2_WIFI_SIGNAL_STRENGTH_MASK) 5830 | (strengthBin << HistoryItem.STATE2_WIFI_SIGNAL_STRENGTH_SHIFT); 5831 if (DEBUG_HISTORY) Slog.v(TAG, "Wifi signal strength " + strengthBin + " to: " 5832 + Integer.toHexString(mHistoryCur.states2)); 5833 addHistoryRecordLocked(elapsedRealtime, uptime); 5834 } else { 5835 stopAllWifiSignalStrengthTimersLocked(-1); 5836 } 5837 mWifiSignalStrengthBin = strengthBin; 5838 } 5839 } 5840 5841 int mWifiFullLockNesting = 0; 5842 5843 @UnsupportedAppUsage noteFullWifiLockAcquiredLocked(int uid)5844 public void noteFullWifiLockAcquiredLocked(int uid) { 5845 final long elapsedRealtime = mClocks.elapsedRealtime(); 5846 final long uptime = mClocks.uptimeMillis(); 5847 if (mWifiFullLockNesting == 0) { 5848 mHistoryCur.states |= HistoryItem.STATE_WIFI_FULL_LOCK_FLAG; 5849 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI full lock on to: " 5850 + Integer.toHexString(mHistoryCur.states)); 5851 addHistoryRecordLocked(elapsedRealtime, uptime); 5852 } 5853 mWifiFullLockNesting++; 5854 getUidStatsLocked(uid).noteFullWifiLockAcquiredLocked(elapsedRealtime); 5855 } 5856 5857 @UnsupportedAppUsage noteFullWifiLockReleasedLocked(int uid)5858 public void noteFullWifiLockReleasedLocked(int uid) { 5859 final long elapsedRealtime = mClocks.elapsedRealtime(); 5860 final long uptime = mClocks.uptimeMillis(); 5861 mWifiFullLockNesting--; 5862 if (mWifiFullLockNesting == 0) { 5863 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_FULL_LOCK_FLAG; 5864 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI full lock off to: " 5865 + Integer.toHexString(mHistoryCur.states)); 5866 addHistoryRecordLocked(elapsedRealtime, uptime); 5867 } 5868 getUidStatsLocked(uid).noteFullWifiLockReleasedLocked(elapsedRealtime); 5869 } 5870 5871 int mWifiScanNesting = 0; 5872 noteWifiScanStartedLocked(int uid)5873 public void noteWifiScanStartedLocked(int uid) { 5874 final long elapsedRealtime = mClocks.elapsedRealtime(); 5875 final long uptime = mClocks.uptimeMillis(); 5876 if (mWifiScanNesting == 0) { 5877 mHistoryCur.states |= HistoryItem.STATE_WIFI_SCAN_FLAG; 5878 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI scan started for: " 5879 + Integer.toHexString(mHistoryCur.states)); 5880 addHistoryRecordLocked(elapsedRealtime, uptime); 5881 } 5882 mWifiScanNesting++; 5883 getUidStatsLocked(uid).noteWifiScanStartedLocked(elapsedRealtime); 5884 } 5885 noteWifiScanStoppedLocked(int uid)5886 public void noteWifiScanStoppedLocked(int uid) { 5887 final long elapsedRealtime = mClocks.elapsedRealtime(); 5888 final long uptime = mClocks.uptimeMillis(); 5889 mWifiScanNesting--; 5890 if (mWifiScanNesting == 0) { 5891 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_SCAN_FLAG; 5892 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI scan stopped for: " 5893 + Integer.toHexString(mHistoryCur.states)); 5894 addHistoryRecordLocked(elapsedRealtime, uptime); 5895 } 5896 getUidStatsLocked(uid).noteWifiScanStoppedLocked(elapsedRealtime); 5897 } 5898 noteWifiBatchedScanStartedLocked(int uid, int csph)5899 public void noteWifiBatchedScanStartedLocked(int uid, int csph) { 5900 uid = mapUid(uid); 5901 final long elapsedRealtime = mClocks.elapsedRealtime(); 5902 getUidStatsLocked(uid).noteWifiBatchedScanStartedLocked(csph, elapsedRealtime); 5903 } 5904 noteWifiBatchedScanStoppedLocked(int uid)5905 public void noteWifiBatchedScanStoppedLocked(int uid) { 5906 uid = mapUid(uid); 5907 final long elapsedRealtime = mClocks.elapsedRealtime(); 5908 getUidStatsLocked(uid).noteWifiBatchedScanStoppedLocked(elapsedRealtime); 5909 } 5910 5911 int mWifiMulticastNesting = 0; 5912 5913 @UnsupportedAppUsage noteWifiMulticastEnabledLocked(int uid)5914 public void noteWifiMulticastEnabledLocked(int uid) { 5915 uid = mapUid(uid); 5916 final long elapsedRealtime = mClocks.elapsedRealtime(); 5917 final long uptime = mClocks.uptimeMillis(); 5918 if (mWifiMulticastNesting == 0) { 5919 mHistoryCur.states |= HistoryItem.STATE_WIFI_MULTICAST_ON_FLAG; 5920 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI multicast on to: " 5921 + Integer.toHexString(mHistoryCur.states)); 5922 addHistoryRecordLocked(elapsedRealtime, uptime); 5923 5924 // Start Wifi Multicast overall timer 5925 if (!mWifiMulticastWakelockTimer.isRunningLocked()) { 5926 if (DEBUG_HISTORY) Slog.v(TAG, "WiFi Multicast Overall Timer Started"); 5927 mWifiMulticastWakelockTimer.startRunningLocked(elapsedRealtime); 5928 } 5929 } 5930 mWifiMulticastNesting++; 5931 getUidStatsLocked(uid).noteWifiMulticastEnabledLocked(elapsedRealtime); 5932 } 5933 5934 @UnsupportedAppUsage noteWifiMulticastDisabledLocked(int uid)5935 public void noteWifiMulticastDisabledLocked(int uid) { 5936 uid = mapUid(uid); 5937 final long elapsedRealtime = mClocks.elapsedRealtime(); 5938 final long uptime = mClocks.uptimeMillis(); 5939 mWifiMulticastNesting--; 5940 if (mWifiMulticastNesting == 0) { 5941 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_MULTICAST_ON_FLAG; 5942 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI multicast off to: " 5943 + Integer.toHexString(mHistoryCur.states)); 5944 addHistoryRecordLocked(elapsedRealtime, uptime); 5945 5946 // Stop Wifi Multicast overall timer 5947 if (mWifiMulticastWakelockTimer.isRunningLocked()) { 5948 if (DEBUG_HISTORY) Slog.v(TAG, "Multicast Overall Timer Stopped"); 5949 mWifiMulticastWakelockTimer.stopRunningLocked(elapsedRealtime); 5950 } 5951 } 5952 getUidStatsLocked(uid).noteWifiMulticastDisabledLocked(elapsedRealtime); 5953 } 5954 noteFullWifiLockAcquiredFromSourceLocked(WorkSource ws)5955 public void noteFullWifiLockAcquiredFromSourceLocked(WorkSource ws) { 5956 int N = ws.size(); 5957 for (int i=0; i<N; i++) { 5958 final int uid = mapUid(ws.get(i)); 5959 noteFullWifiLockAcquiredLocked(uid); 5960 } 5961 5962 final List<WorkChain> workChains = ws.getWorkChains(); 5963 if (workChains != null) { 5964 for (int i = 0; i < workChains.size(); ++i) { 5965 final WorkChain workChain = workChains.get(i); 5966 final int uid = mapUid(workChain.getAttributionUid()); 5967 noteFullWifiLockAcquiredLocked(uid); 5968 } 5969 } 5970 } 5971 noteFullWifiLockReleasedFromSourceLocked(WorkSource ws)5972 public void noteFullWifiLockReleasedFromSourceLocked(WorkSource ws) { 5973 int N = ws.size(); 5974 for (int i=0; i<N; i++) { 5975 final int uid = mapUid(ws.get(i)); 5976 noteFullWifiLockReleasedLocked(uid); 5977 } 5978 5979 final List<WorkChain> workChains = ws.getWorkChains(); 5980 if (workChains != null) { 5981 for (int i = 0; i < workChains.size(); ++i) { 5982 final WorkChain workChain = workChains.get(i); 5983 final int uid = mapUid(workChain.getAttributionUid()); 5984 noteFullWifiLockReleasedLocked(uid); 5985 } 5986 } 5987 } 5988 noteWifiScanStartedFromSourceLocked(WorkSource ws)5989 public void noteWifiScanStartedFromSourceLocked(WorkSource ws) { 5990 int N = ws.size(); 5991 for (int i=0; i<N; i++) { 5992 final int uid = mapUid(ws.get(i)); 5993 noteWifiScanStartedLocked(uid); 5994 } 5995 5996 final List<WorkChain> workChains = ws.getWorkChains(); 5997 if (workChains != null) { 5998 for (int i = 0; i < workChains.size(); ++i) { 5999 final WorkChain workChain = workChains.get(i); 6000 final int uid = mapUid(workChain.getAttributionUid()); 6001 noteWifiScanStartedLocked(uid); 6002 } 6003 } 6004 } 6005 noteWifiScanStoppedFromSourceLocked(WorkSource ws)6006 public void noteWifiScanStoppedFromSourceLocked(WorkSource ws) { 6007 int N = ws.size(); 6008 for (int i=0; i<N; i++) { 6009 final int uid = mapUid(ws.get(i)); 6010 noteWifiScanStoppedLocked(uid); 6011 } 6012 6013 final List<WorkChain> workChains = ws.getWorkChains(); 6014 if (workChains != null) { 6015 for (int i = 0; i < workChains.size(); ++i) { 6016 final WorkChain workChain = workChains.get(i); 6017 final int uid = mapUid(workChain.getAttributionUid()); 6018 noteWifiScanStoppedLocked(uid); 6019 } 6020 } 6021 } 6022 noteWifiBatchedScanStartedFromSourceLocked(WorkSource ws, int csph)6023 public void noteWifiBatchedScanStartedFromSourceLocked(WorkSource ws, int csph) { 6024 int N = ws.size(); 6025 for (int i=0; i<N; i++) { 6026 noteWifiBatchedScanStartedLocked(ws.get(i), csph); 6027 } 6028 6029 final List<WorkChain> workChains = ws.getWorkChains(); 6030 if (workChains != null) { 6031 for (int i = 0; i < workChains.size(); ++i) { 6032 noteWifiBatchedScanStartedLocked(workChains.get(i).getAttributionUid(), csph); 6033 } 6034 } 6035 } 6036 noteWifiBatchedScanStoppedFromSourceLocked(WorkSource ws)6037 public void noteWifiBatchedScanStoppedFromSourceLocked(WorkSource ws) { 6038 int N = ws.size(); 6039 for (int i=0; i<N; i++) { 6040 noteWifiBatchedScanStoppedLocked(ws.get(i)); 6041 } 6042 6043 final List<WorkChain> workChains = ws.getWorkChains(); 6044 if (workChains != null) { 6045 for (int i = 0; i < workChains.size(); ++i) { 6046 noteWifiBatchedScanStoppedLocked(workChains.get(i).getAttributionUid()); 6047 } 6048 } 6049 } 6050 includeInStringArray(String[] array, String str)6051 private static String[] includeInStringArray(String[] array, String str) { 6052 if (ArrayUtils.indexOf(array, str) >= 0) { 6053 return array; 6054 } 6055 String[] newArray = new String[array.length+1]; 6056 System.arraycopy(array, 0, newArray, 0, array.length); 6057 newArray[array.length] = str; 6058 return newArray; 6059 } 6060 excludeFromStringArray(String[] array, String str)6061 private static String[] excludeFromStringArray(String[] array, String str) { 6062 int index = ArrayUtils.indexOf(array, str); 6063 if (index >= 0) { 6064 String[] newArray = new String[array.length-1]; 6065 if (index > 0) { 6066 System.arraycopy(array, 0, newArray, 0, index); 6067 } 6068 if (index < array.length-1) { 6069 System.arraycopy(array, index+1, newArray, index, array.length-index-1); 6070 } 6071 return newArray; 6072 } 6073 return array; 6074 } 6075 noteNetworkInterfaceTypeLocked(String iface, int networkType)6076 public void noteNetworkInterfaceTypeLocked(String iface, int networkType) { 6077 if (TextUtils.isEmpty(iface)) return; 6078 6079 synchronized (mModemNetworkLock) { 6080 if (ConnectivityManager.isNetworkTypeMobile(networkType)) { 6081 mModemIfaces = includeInStringArray(mModemIfaces, iface); 6082 if (DEBUG) Slog.d(TAG, "Note mobile iface " + iface + ": " + mModemIfaces); 6083 } else { 6084 mModemIfaces = excludeFromStringArray(mModemIfaces, iface); 6085 if (DEBUG) Slog.d(TAG, "Note non-mobile iface " + iface + ": " + mModemIfaces); 6086 } 6087 } 6088 6089 synchronized (mWifiNetworkLock) { 6090 if (ConnectivityManager.isNetworkTypeWifi(networkType)) { 6091 mWifiIfaces = includeInStringArray(mWifiIfaces, iface); 6092 if (DEBUG) Slog.d(TAG, "Note wifi iface " + iface + ": " + mWifiIfaces); 6093 } else { 6094 mWifiIfaces = excludeFromStringArray(mWifiIfaces, iface); 6095 if (DEBUG) Slog.d(TAG, "Note non-wifi iface " + iface + ": " + mWifiIfaces); 6096 } 6097 } 6098 } 6099 getWifiIfaces()6100 public String[] getWifiIfaces() { 6101 synchronized (mWifiNetworkLock) { 6102 return mWifiIfaces; 6103 } 6104 } 6105 getMobileIfaces()6106 public String[] getMobileIfaces() { 6107 synchronized (mModemNetworkLock) { 6108 return mModemIfaces; 6109 } 6110 } 6111 6112 @UnsupportedAppUsage getScreenOnTime(long elapsedRealtimeUs, int which)6113 @Override public long getScreenOnTime(long elapsedRealtimeUs, int which) { 6114 return mScreenOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 6115 } 6116 getScreenOnCount(int which)6117 @Override public int getScreenOnCount(int which) { 6118 return mScreenOnTimer.getCountLocked(which); 6119 } 6120 getScreenDozeTime(long elapsedRealtimeUs, int which)6121 @Override public long getScreenDozeTime(long elapsedRealtimeUs, int which) { 6122 return mScreenDozeTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 6123 } 6124 getScreenDozeCount(int which)6125 @Override public int getScreenDozeCount(int which) { 6126 return mScreenDozeTimer.getCountLocked(which); 6127 } 6128 6129 @UnsupportedAppUsage getScreenBrightnessTime(int brightnessBin, long elapsedRealtimeUs, int which)6130 @Override public long getScreenBrightnessTime(int brightnessBin, 6131 long elapsedRealtimeUs, int which) { 6132 return mScreenBrightnessTimer[brightnessBin].getTotalTimeLocked( 6133 elapsedRealtimeUs, which); 6134 } 6135 getScreenBrightnessTimer(int brightnessBin)6136 @Override public Timer getScreenBrightnessTimer(int brightnessBin) { 6137 return mScreenBrightnessTimer[brightnessBin]; 6138 } 6139 getInteractiveTime(long elapsedRealtimeUs, int which)6140 @Override public long getInteractiveTime(long elapsedRealtimeUs, int which) { 6141 return mInteractiveTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 6142 } 6143 getPowerSaveModeEnabledTime(long elapsedRealtimeUs, int which)6144 @Override public long getPowerSaveModeEnabledTime(long elapsedRealtimeUs, int which) { 6145 return mPowerSaveModeEnabledTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 6146 } 6147 getPowerSaveModeEnabledCount(int which)6148 @Override public int getPowerSaveModeEnabledCount(int which) { 6149 return mPowerSaveModeEnabledTimer.getCountLocked(which); 6150 } 6151 getDeviceIdleModeTime(int mode, long elapsedRealtimeUs, int which)6152 @Override public long getDeviceIdleModeTime(int mode, long elapsedRealtimeUs, 6153 int which) { 6154 switch (mode) { 6155 case DEVICE_IDLE_MODE_LIGHT: 6156 return mDeviceIdleModeLightTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 6157 case DEVICE_IDLE_MODE_DEEP: 6158 return mDeviceIdleModeFullTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 6159 } 6160 return 0; 6161 } 6162 getDeviceIdleModeCount(int mode, int which)6163 @Override public int getDeviceIdleModeCount(int mode, int which) { 6164 switch (mode) { 6165 case DEVICE_IDLE_MODE_LIGHT: 6166 return mDeviceIdleModeLightTimer.getCountLocked(which); 6167 case DEVICE_IDLE_MODE_DEEP: 6168 return mDeviceIdleModeFullTimer.getCountLocked(which); 6169 } 6170 return 0; 6171 } 6172 getLongestDeviceIdleModeTime(int mode)6173 @Override public long getLongestDeviceIdleModeTime(int mode) { 6174 switch (mode) { 6175 case DEVICE_IDLE_MODE_LIGHT: 6176 return mLongestLightIdleTime; 6177 case DEVICE_IDLE_MODE_DEEP: 6178 return mLongestFullIdleTime; 6179 } 6180 return 0; 6181 } 6182 getDeviceIdlingTime(int mode, long elapsedRealtimeUs, int which)6183 @Override public long getDeviceIdlingTime(int mode, long elapsedRealtimeUs, int which) { 6184 switch (mode) { 6185 case DEVICE_IDLE_MODE_LIGHT: 6186 return mDeviceLightIdlingTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 6187 case DEVICE_IDLE_MODE_DEEP: 6188 return mDeviceIdlingTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 6189 } 6190 return 0; 6191 } 6192 getDeviceIdlingCount(int mode, int which)6193 @Override public int getDeviceIdlingCount(int mode, int which) { 6194 switch (mode) { 6195 case DEVICE_IDLE_MODE_LIGHT: 6196 return mDeviceLightIdlingTimer.getCountLocked(which); 6197 case DEVICE_IDLE_MODE_DEEP: 6198 return mDeviceIdlingTimer.getCountLocked(which); 6199 } 6200 return 0; 6201 } 6202 getNumConnectivityChange(int which)6203 @Override public int getNumConnectivityChange(int which) { 6204 return mNumConnectivityChange; 6205 } 6206 getGpsSignalQualityTime(int strengthBin, long elapsedRealtimeUs, int which)6207 @Override public long getGpsSignalQualityTime(int strengthBin, 6208 long elapsedRealtimeUs, int which) { 6209 if (strengthBin < 0 || strengthBin >= GnssMetrics.NUM_GPS_SIGNAL_QUALITY_LEVELS) { 6210 return 0; 6211 } 6212 return mGpsSignalQualityTimer[strengthBin].getTotalTimeLocked( 6213 elapsedRealtimeUs, which); 6214 } 6215 getGpsBatteryDrainMaMs()6216 @Override public long getGpsBatteryDrainMaMs() { 6217 final double opVolt = mPowerProfile.getAveragePower( 6218 PowerProfile.POWER_GPS_OPERATING_VOLTAGE) / 1000.0; 6219 if (opVolt == 0) { 6220 return 0; 6221 } 6222 double energyUsedMaMs = 0.0; 6223 final int which = STATS_SINCE_CHARGED; 6224 final long rawRealtime = SystemClock.elapsedRealtime() * 1000; 6225 for(int i=0; i < GnssMetrics.NUM_GPS_SIGNAL_QUALITY_LEVELS; i++) { 6226 energyUsedMaMs 6227 += mPowerProfile.getAveragePower(PowerProfile.POWER_GPS_SIGNAL_QUALITY_BASED, i) 6228 * (getGpsSignalQualityTime(i, rawRealtime, which) / 1000); 6229 } 6230 return (long) energyUsedMaMs; 6231 } 6232 6233 @UnsupportedAppUsage getPhoneOnTime(long elapsedRealtimeUs, int which)6234 @Override public long getPhoneOnTime(long elapsedRealtimeUs, int which) { 6235 return mPhoneOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 6236 } 6237 getPhoneOnCount(int which)6238 @Override public int getPhoneOnCount(int which) { 6239 return mPhoneOnTimer.getCountLocked(which); 6240 } 6241 6242 @UnsupportedAppUsage getPhoneSignalStrengthTime(int strengthBin, long elapsedRealtimeUs, int which)6243 @Override public long getPhoneSignalStrengthTime(int strengthBin, 6244 long elapsedRealtimeUs, int which) { 6245 return mPhoneSignalStrengthsTimer[strengthBin].getTotalTimeLocked( 6246 elapsedRealtimeUs, which); 6247 } 6248 6249 @UnsupportedAppUsage getPhoneSignalScanningTime( long elapsedRealtimeUs, int which)6250 @Override public long getPhoneSignalScanningTime( 6251 long elapsedRealtimeUs, int which) { 6252 return mPhoneSignalScanningTimer.getTotalTimeLocked( 6253 elapsedRealtimeUs, which); 6254 } 6255 getPhoneSignalScanningTimer()6256 @Override public Timer getPhoneSignalScanningTimer() { 6257 return mPhoneSignalScanningTimer; 6258 } 6259 6260 @UnsupportedAppUsage getPhoneSignalStrengthCount(int strengthBin, int which)6261 @Override public int getPhoneSignalStrengthCount(int strengthBin, int which) { 6262 return mPhoneSignalStrengthsTimer[strengthBin].getCountLocked(which); 6263 } 6264 getPhoneSignalStrengthTimer(int strengthBin)6265 @Override public Timer getPhoneSignalStrengthTimer(int strengthBin) { 6266 return mPhoneSignalStrengthsTimer[strengthBin]; 6267 } 6268 6269 @UnsupportedAppUsage getPhoneDataConnectionTime(int dataType, long elapsedRealtimeUs, int which)6270 @Override public long getPhoneDataConnectionTime(int dataType, 6271 long elapsedRealtimeUs, int which) { 6272 return mPhoneDataConnectionsTimer[dataType].getTotalTimeLocked( 6273 elapsedRealtimeUs, which); 6274 } 6275 6276 @UnsupportedAppUsage getPhoneDataConnectionCount(int dataType, int which)6277 @Override public int getPhoneDataConnectionCount(int dataType, int which) { 6278 return mPhoneDataConnectionsTimer[dataType].getCountLocked(which); 6279 } 6280 getPhoneDataConnectionTimer(int dataType)6281 @Override public Timer getPhoneDataConnectionTimer(int dataType) { 6282 return mPhoneDataConnectionsTimer[dataType]; 6283 } 6284 6285 @UnsupportedAppUsage getMobileRadioActiveTime(long elapsedRealtimeUs, int which)6286 @Override public long getMobileRadioActiveTime(long elapsedRealtimeUs, int which) { 6287 return mMobileRadioActiveTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 6288 } 6289 getMobileRadioActiveCount(int which)6290 @Override public int getMobileRadioActiveCount(int which) { 6291 return mMobileRadioActiveTimer.getCountLocked(which); 6292 } 6293 getMobileRadioActiveAdjustedTime(int which)6294 @Override public long getMobileRadioActiveAdjustedTime(int which) { 6295 return mMobileRadioActiveAdjustedTime.getCountLocked(which); 6296 } 6297 getMobileRadioActiveUnknownTime(int which)6298 @Override public long getMobileRadioActiveUnknownTime(int which) { 6299 return mMobileRadioActiveUnknownTime.getCountLocked(which); 6300 } 6301 getMobileRadioActiveUnknownCount(int which)6302 @Override public int getMobileRadioActiveUnknownCount(int which) { 6303 return (int)mMobileRadioActiveUnknownCount.getCountLocked(which); 6304 } 6305 getWifiMulticastWakelockTime( long elapsedRealtimeUs, int which)6306 @Override public long getWifiMulticastWakelockTime( 6307 long elapsedRealtimeUs, int which) { 6308 return mWifiMulticastWakelockTimer.getTotalTimeLocked( 6309 elapsedRealtimeUs, which); 6310 } 6311 getWifiMulticastWakelockCount(int which)6312 @Override public int getWifiMulticastWakelockCount(int which) { 6313 return mWifiMulticastWakelockTimer.getCountLocked(which); 6314 } 6315 6316 @UnsupportedAppUsage getWifiOnTime(long elapsedRealtimeUs, int which)6317 @Override public long getWifiOnTime(long elapsedRealtimeUs, int which) { 6318 return mWifiOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 6319 } 6320 getWifiActiveTime(long elapsedRealtimeUs, int which)6321 @Override public long getWifiActiveTime(long elapsedRealtimeUs, int which) { 6322 return mWifiActiveTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 6323 } 6324 6325 @UnsupportedAppUsage getGlobalWifiRunningTime(long elapsedRealtimeUs, int which)6326 @Override public long getGlobalWifiRunningTime(long elapsedRealtimeUs, int which) { 6327 return mGlobalWifiRunningTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 6328 } 6329 getWifiStateTime(int wifiState, long elapsedRealtimeUs, int which)6330 @Override public long getWifiStateTime(int wifiState, 6331 long elapsedRealtimeUs, int which) { 6332 return mWifiStateTimer[wifiState].getTotalTimeLocked( 6333 elapsedRealtimeUs, which); 6334 } 6335 getWifiStateCount(int wifiState, int which)6336 @Override public int getWifiStateCount(int wifiState, int which) { 6337 return mWifiStateTimer[wifiState].getCountLocked(which); 6338 } 6339 getWifiStateTimer(int wifiState)6340 @Override public Timer getWifiStateTimer(int wifiState) { 6341 return mWifiStateTimer[wifiState]; 6342 } 6343 getWifiSupplStateTime(int state, long elapsedRealtimeUs, int which)6344 @Override public long getWifiSupplStateTime(int state, 6345 long elapsedRealtimeUs, int which) { 6346 return mWifiSupplStateTimer[state].getTotalTimeLocked( 6347 elapsedRealtimeUs, which); 6348 } 6349 getWifiSupplStateCount(int state, int which)6350 @Override public int getWifiSupplStateCount(int state, int which) { 6351 return mWifiSupplStateTimer[state].getCountLocked(which); 6352 } 6353 getWifiSupplStateTimer(int state)6354 @Override public Timer getWifiSupplStateTimer(int state) { 6355 return mWifiSupplStateTimer[state]; 6356 } 6357 getWifiSignalStrengthTime(int strengthBin, long elapsedRealtimeUs, int which)6358 @Override public long getWifiSignalStrengthTime(int strengthBin, 6359 long elapsedRealtimeUs, int which) { 6360 return mWifiSignalStrengthsTimer[strengthBin].getTotalTimeLocked( 6361 elapsedRealtimeUs, which); 6362 } 6363 getWifiSignalStrengthCount(int strengthBin, int which)6364 @Override public int getWifiSignalStrengthCount(int strengthBin, int which) { 6365 return mWifiSignalStrengthsTimer[strengthBin].getCountLocked(which); 6366 } 6367 getWifiSignalStrengthTimer(int strengthBin)6368 @Override public Timer getWifiSignalStrengthTimer(int strengthBin) { 6369 return mWifiSignalStrengthsTimer[strengthBin]; 6370 } 6371 6372 @Override getBluetoothControllerActivity()6373 public ControllerActivityCounter getBluetoothControllerActivity() { 6374 return mBluetoothActivity; 6375 } 6376 6377 @Override getWifiControllerActivity()6378 public ControllerActivityCounter getWifiControllerActivity() { 6379 return mWifiActivity; 6380 } 6381 6382 @Override getModemControllerActivity()6383 public ControllerActivityCounter getModemControllerActivity() { 6384 return mModemActivity; 6385 } 6386 6387 @Override hasBluetoothActivityReporting()6388 public boolean hasBluetoothActivityReporting() { 6389 return mHasBluetoothReporting; 6390 } 6391 6392 @Override hasWifiActivityReporting()6393 public boolean hasWifiActivityReporting() { 6394 return mHasWifiReporting; 6395 } 6396 6397 @Override hasModemActivityReporting()6398 public boolean hasModemActivityReporting() { 6399 return mHasModemReporting; 6400 } 6401 6402 @Override getFlashlightOnTime(long elapsedRealtimeUs, int which)6403 public long getFlashlightOnTime(long elapsedRealtimeUs, int which) { 6404 return mFlashlightOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 6405 } 6406 6407 @Override getFlashlightOnCount(int which)6408 public long getFlashlightOnCount(int which) { 6409 return mFlashlightOnTimer.getCountLocked(which); 6410 } 6411 6412 @Override getCameraOnTime(long elapsedRealtimeUs, int which)6413 public long getCameraOnTime(long elapsedRealtimeUs, int which) { 6414 return mCameraOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 6415 } 6416 6417 @Override getBluetoothScanTime(long elapsedRealtimeUs, int which)6418 public long getBluetoothScanTime(long elapsedRealtimeUs, int which) { 6419 return mBluetoothScanTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 6420 } 6421 6422 @Override 6423 @UnsupportedAppUsage getNetworkActivityBytes(int type, int which)6424 public long getNetworkActivityBytes(int type, int which) { 6425 if (type >= 0 && type < mNetworkByteActivityCounters.length) { 6426 return mNetworkByteActivityCounters[type].getCountLocked(which); 6427 } else { 6428 return 0; 6429 } 6430 } 6431 6432 @Override getNetworkActivityPackets(int type, int which)6433 public long getNetworkActivityPackets(int type, int which) { 6434 if (type >= 0 && type < mNetworkPacketActivityCounters.length) { 6435 return mNetworkPacketActivityCounters[type].getCountLocked(which); 6436 } else { 6437 return 0; 6438 } 6439 } 6440 getStartClockTime()6441 @Override public long getStartClockTime() { 6442 final long currentTime = System.currentTimeMillis(); 6443 if ((currentTime > MILLISECONDS_IN_YEAR 6444 && mStartClockTime < (currentTime - MILLISECONDS_IN_YEAR)) 6445 || (mStartClockTime > currentTime)) { 6446 // If the start clock time has changed by more than a year, then presumably 6447 // the previous time was completely bogus. So we are going to figure out a 6448 // new time based on how much time has elapsed since we started counting. 6449 recordCurrentTimeChangeLocked(currentTime, mClocks.elapsedRealtime(), 6450 mClocks.uptimeMillis()); 6451 return currentTime - (mClocks.elapsedRealtime() - (mRealtimeStart / 1000)); 6452 } 6453 return mStartClockTime; 6454 } 6455 getStartPlatformVersion()6456 @Override public String getStartPlatformVersion() { 6457 return mStartPlatformVersion; 6458 } 6459 getEndPlatformVersion()6460 @Override public String getEndPlatformVersion() { 6461 return mEndPlatformVersion; 6462 } 6463 getParcelVersion()6464 @Override public int getParcelVersion() { 6465 return VERSION; 6466 } 6467 getIsOnBattery()6468 @Override public boolean getIsOnBattery() { 6469 return mOnBattery; 6470 } 6471 6472 @UnsupportedAppUsage getUidStats()6473 @Override public SparseArray<? extends BatteryStats.Uid> getUidStats() { 6474 return mUidStats; 6475 } 6476 resetIfNotNull(T t, boolean detachIfReset)6477 private static <T extends TimeBaseObs> boolean resetIfNotNull(T t, boolean detachIfReset) { 6478 if (t != null) { 6479 return t.reset(detachIfReset); 6480 } 6481 return true; 6482 } 6483 resetIfNotNull(T[] t, boolean detachIfReset)6484 private static <T extends TimeBaseObs> boolean resetIfNotNull(T[] t, boolean detachIfReset) { 6485 if (t != null) { 6486 boolean ret = true; 6487 for (int i = 0; i < t.length; i++) { 6488 ret &= resetIfNotNull(t[i], detachIfReset); 6489 } 6490 return ret; 6491 } 6492 return true; 6493 } 6494 resetIfNotNull(T[][] t, boolean detachIfReset)6495 private static <T extends TimeBaseObs> boolean resetIfNotNull(T[][] t, boolean detachIfReset) { 6496 if (t != null) { 6497 boolean ret = true; 6498 for (int i = 0; i < t.length; i++) { 6499 ret &= resetIfNotNull(t[i], detachIfReset); 6500 } 6501 return ret; 6502 } 6503 return true; 6504 } 6505 resetIfNotNull(ControllerActivityCounterImpl counter, boolean detachIfReset)6506 private static boolean resetIfNotNull(ControllerActivityCounterImpl counter, 6507 boolean detachIfReset) { 6508 if (counter != null) { 6509 counter.reset(detachIfReset); 6510 } 6511 return true; 6512 } 6513 detachIfNotNull(T t)6514 private static <T extends TimeBaseObs> void detachIfNotNull(T t) { 6515 if (t != null) { 6516 t.detach(); 6517 } 6518 } 6519 detachIfNotNull(T[] t)6520 private static <T extends TimeBaseObs> void detachIfNotNull(T[] t) { 6521 if (t != null) { 6522 for (int i = 0; i < t.length; i++) { 6523 detachIfNotNull(t[i]); 6524 } 6525 } 6526 } 6527 detachIfNotNull(T[][] t)6528 private static <T extends TimeBaseObs> void detachIfNotNull(T[][] t) { 6529 if (t != null) { 6530 for (int i = 0; i < t.length; i++) { 6531 detachIfNotNull(t[i]); 6532 } 6533 } 6534 } 6535 detachIfNotNull(ControllerActivityCounterImpl counter)6536 private static void detachIfNotNull(ControllerActivityCounterImpl counter) { 6537 if (counter != null) { 6538 counter.detach(); 6539 } 6540 } 6541 6542 /** 6543 * The statistics associated with a particular uid. 6544 */ 6545 public static class Uid extends BatteryStats.Uid { 6546 /** 6547 * BatteryStatsImpl that we are associated with. 6548 */ 6549 protected BatteryStatsImpl mBsi; 6550 6551 final int mUid; 6552 6553 /** TimeBase for when uid is in background and device is on battery. */ 6554 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) 6555 public final TimeBase mOnBatteryBackgroundTimeBase; 6556 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) 6557 public final TimeBase mOnBatteryScreenOffBackgroundTimeBase; 6558 6559 boolean mWifiRunning; 6560 StopwatchTimer mWifiRunningTimer; 6561 6562 boolean mFullWifiLockOut; 6563 StopwatchTimer mFullWifiLockTimer; 6564 6565 boolean mWifiScanStarted; 6566 DualTimer mWifiScanTimer; 6567 6568 static final int NO_BATCHED_SCAN_STARTED = -1; 6569 int mWifiBatchedScanBinStarted = NO_BATCHED_SCAN_STARTED; 6570 StopwatchTimer[] mWifiBatchedScanTimer; 6571 6572 int mWifiMulticastWakelockCount; 6573 StopwatchTimer mWifiMulticastTimer; 6574 6575 StopwatchTimer mAudioTurnedOnTimer; 6576 StopwatchTimer mVideoTurnedOnTimer; 6577 StopwatchTimer mFlashlightTurnedOnTimer; 6578 StopwatchTimer mCameraTurnedOnTimer; 6579 StopwatchTimer mForegroundActivityTimer; 6580 StopwatchTimer mForegroundServiceTimer; 6581 /** Total time spent by the uid holding any partial wakelocks. */ 6582 DualTimer mAggregatedPartialWakelockTimer; 6583 DualTimer mBluetoothScanTimer; 6584 DualTimer mBluetoothUnoptimizedScanTimer; 6585 Counter mBluetoothScanResultCounter; 6586 Counter mBluetoothScanResultBgCounter; 6587 6588 int mProcessState = ActivityManager.PROCESS_STATE_NONEXISTENT; 6589 StopwatchTimer[] mProcessStateTimer; 6590 6591 boolean mInForegroundService = false; 6592 6593 BatchTimer mVibratorOnTimer; 6594 6595 Counter[] mUserActivityCounters; 6596 6597 LongSamplingCounter[] mNetworkByteActivityCounters; 6598 LongSamplingCounter[] mNetworkPacketActivityCounters; 6599 LongSamplingCounter mMobileRadioActiveTime; 6600 LongSamplingCounter mMobileRadioActiveCount; 6601 6602 /** 6603 * How many times this UID woke up the Application Processor due to a Mobile radio packet. 6604 */ 6605 private LongSamplingCounter mMobileRadioApWakeupCount; 6606 6607 /** 6608 * How many times this UID woke up the Application Processor due to a Wifi packet. 6609 */ 6610 private LongSamplingCounter mWifiRadioApWakeupCount; 6611 6612 /** 6613 * The amount of time this uid has kept the WiFi controller in idle, tx, and rx mode. 6614 * Can be null if the UID has had no such activity. 6615 */ 6616 private ControllerActivityCounterImpl mWifiControllerActivity; 6617 6618 /** 6619 * The amount of time this uid has kept the Bluetooth controller in idle, tx, and rx mode. 6620 * Can be null if the UID has had no such activity. 6621 */ 6622 private ControllerActivityCounterImpl mBluetoothControllerActivity; 6623 6624 /** 6625 * The amount of time this uid has kept the Modem controller in idle, tx, and rx mode. 6626 * Can be null if the UID has had no such activity. 6627 */ 6628 private ControllerActivityCounterImpl mModemControllerActivity; 6629 6630 /** 6631 * The CPU times we had at the last history details update. 6632 */ 6633 long mLastStepUserTime; 6634 long mLastStepSystemTime; 6635 long mCurStepUserTime; 6636 long mCurStepSystemTime; 6637 6638 LongSamplingCounter mUserCpuTime; 6639 LongSamplingCounter mSystemCpuTime; 6640 LongSamplingCounter[][] mCpuClusterSpeedTimesUs; 6641 LongSamplingCounter mCpuActiveTimeMs; 6642 6643 LongSamplingCounterArray mCpuFreqTimeMs; 6644 LongSamplingCounterArray mScreenOffCpuFreqTimeMs; 6645 LongSamplingCounterArray mCpuClusterTimesMs; 6646 6647 LongSamplingCounterArray[] mProcStateTimeMs; 6648 LongSamplingCounterArray[] mProcStateScreenOffTimeMs; 6649 6650 IntArray mChildUids; 6651 6652 /** 6653 * The statistics we have collected for this uid's wake locks. 6654 */ 6655 final OverflowArrayMap<Wakelock> mWakelockStats; 6656 6657 /** 6658 * The statistics we have collected for this uid's syncs. 6659 */ 6660 final OverflowArrayMap<DualTimer> mSyncStats; 6661 6662 /** 6663 * The statistics we have collected for this uid's jobs. 6664 */ 6665 final OverflowArrayMap<DualTimer> mJobStats; 6666 6667 /** 6668 * Count of the jobs that have completed and the reasons why they completed. 6669 */ 6670 final ArrayMap<String, SparseIntArray> mJobCompletions = new ArrayMap<>(); 6671 6672 /** 6673 * Count of app launch events that had associated deferred job counts or info about 6674 * last time a job was run. 6675 */ 6676 Counter mJobsDeferredEventCount; 6677 6678 /** 6679 * Count of deferred jobs that were pending when the app was launched or brought to 6680 * the foreground through a user interaction. 6681 */ 6682 Counter mJobsDeferredCount; 6683 6684 /** 6685 * Sum of time since the last time a job was run for this app before it was launched. 6686 */ 6687 LongSamplingCounter mJobsFreshnessTimeMs; 6688 6689 /** 6690 * Array of counts of instances where the time since the last job was run for the app 6691 * fell within one of the thresholds in {@link #JOB_FRESHNESS_BUCKETS}. 6692 */ 6693 final Counter[] mJobsFreshnessBuckets; 6694 6695 /** 6696 * The statistics we have collected for this uid's sensor activations. 6697 */ 6698 final SparseArray<Sensor> mSensorStats = new SparseArray<>(); 6699 6700 /** 6701 * The statistics we have collected for this uid's processes. 6702 */ 6703 final ArrayMap<String, Proc> mProcessStats = new ArrayMap<>(); 6704 6705 /** 6706 * The statistics we have collected for this uid's processes. 6707 */ 6708 final ArrayMap<String, Pkg> mPackageStats = new ArrayMap<>(); 6709 6710 /** 6711 * The transient wake stats we have collected for this uid's pids. 6712 */ 6713 final SparseArray<Pid> mPids = new SparseArray<>(); 6714 Uid(BatteryStatsImpl bsi, int uid)6715 public Uid(BatteryStatsImpl bsi, int uid) { 6716 mBsi = bsi; 6717 mUid = uid; 6718 6719 /* Observer list of TimeBase object in Uid is short */ 6720 mOnBatteryBackgroundTimeBase = new TimeBase(false); 6721 mOnBatteryBackgroundTimeBase.init(mBsi.mClocks.uptimeMillis() * 1000, 6722 mBsi.mClocks.elapsedRealtime() * 1000); 6723 /* Observer list of TimeBase object in Uid is short */ 6724 mOnBatteryScreenOffBackgroundTimeBase = new TimeBase(false); 6725 mOnBatteryScreenOffBackgroundTimeBase.init(mBsi.mClocks.uptimeMillis() * 1000, 6726 mBsi.mClocks.elapsedRealtime() * 1000); 6727 6728 mUserCpuTime = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); 6729 mSystemCpuTime = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); 6730 mCpuActiveTimeMs = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); 6731 mCpuClusterTimesMs = new LongSamplingCounterArray(mBsi.mOnBatteryTimeBase); 6732 6733 mWakelockStats = mBsi.new OverflowArrayMap<Wakelock>(uid) { 6734 @Override public Wakelock instantiateObject() { 6735 return new Wakelock(mBsi, Uid.this); 6736 } 6737 }; 6738 mSyncStats = mBsi.new OverflowArrayMap<DualTimer>(uid) { 6739 @Override public DualTimer instantiateObject() { 6740 return new DualTimer(mBsi.mClocks, Uid.this, SYNC, null, 6741 mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase); 6742 } 6743 }; 6744 mJobStats = mBsi.new OverflowArrayMap<DualTimer>(uid) { 6745 @Override public DualTimer instantiateObject() { 6746 return new DualTimer(mBsi.mClocks, Uid.this, JOB, null, 6747 mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase); 6748 } 6749 }; 6750 6751 mWifiRunningTimer = new StopwatchTimer(mBsi.mClocks, this, WIFI_RUNNING, 6752 mBsi.mWifiRunningTimers, mBsi.mOnBatteryTimeBase); 6753 mFullWifiLockTimer = new StopwatchTimer(mBsi.mClocks, this, FULL_WIFI_LOCK, 6754 mBsi.mFullWifiLockTimers, mBsi.mOnBatteryTimeBase); 6755 mWifiScanTimer = new DualTimer(mBsi.mClocks, this, WIFI_SCAN, 6756 mBsi.mWifiScanTimers, mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase); 6757 mWifiBatchedScanTimer = new StopwatchTimer[NUM_WIFI_BATCHED_SCAN_BINS]; 6758 mWifiMulticastTimer = new StopwatchTimer(mBsi.mClocks, this, WIFI_MULTICAST_ENABLED, 6759 mBsi.mWifiMulticastTimers, mBsi.mOnBatteryTimeBase); 6760 mProcessStateTimer = new StopwatchTimer[NUM_PROCESS_STATE]; 6761 mJobsDeferredEventCount = new Counter(mBsi.mOnBatteryTimeBase); 6762 mJobsDeferredCount = new Counter(mBsi.mOnBatteryTimeBase); 6763 mJobsFreshnessTimeMs = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); 6764 mJobsFreshnessBuckets = new Counter[JOB_FRESHNESS_BUCKETS.length]; 6765 } 6766 6767 @VisibleForTesting setProcessStateForTest(int procState)6768 public void setProcessStateForTest(int procState) { 6769 mProcessState = procState; 6770 } 6771 6772 @Override getCpuFreqTimes(int which)6773 public long[] getCpuFreqTimes(int which) { 6774 return nullIfAllZeros(mCpuFreqTimeMs, which); 6775 } 6776 6777 @Override getScreenOffCpuFreqTimes(int which)6778 public long[] getScreenOffCpuFreqTimes(int which) { 6779 return nullIfAllZeros(mScreenOffCpuFreqTimeMs, which); 6780 } 6781 6782 @Override getCpuActiveTime()6783 public long getCpuActiveTime() { 6784 return mCpuActiveTimeMs.getCountLocked(STATS_SINCE_CHARGED); 6785 } 6786 6787 @Override getCpuClusterTimes()6788 public long[] getCpuClusterTimes() { 6789 return nullIfAllZeros(mCpuClusterTimesMs, STATS_SINCE_CHARGED); 6790 } 6791 6792 6793 @Override getCpuFreqTimes(int which, int procState)6794 public long[] getCpuFreqTimes(int which, int procState) { 6795 if (which < 0 || which >= NUM_PROCESS_STATE) { 6796 return null; 6797 } 6798 if (mProcStateTimeMs == null) { 6799 return null; 6800 } 6801 if (!mBsi.mPerProcStateCpuTimesAvailable) { 6802 mProcStateTimeMs = null; 6803 return null; 6804 } 6805 return nullIfAllZeros(mProcStateTimeMs[procState], which); 6806 } 6807 6808 @Override getScreenOffCpuFreqTimes(int which, int procState)6809 public long[] getScreenOffCpuFreqTimes(int which, int procState) { 6810 if (which < 0 || which >= NUM_PROCESS_STATE) { 6811 return null; 6812 } 6813 if (mProcStateScreenOffTimeMs == null) { 6814 return null; 6815 } 6816 if (!mBsi.mPerProcStateCpuTimesAvailable) { 6817 mProcStateScreenOffTimeMs = null; 6818 return null; 6819 } 6820 return nullIfAllZeros(mProcStateScreenOffTimeMs[procState], which); 6821 } 6822 addIsolatedUid(int isolatedUid)6823 public void addIsolatedUid(int isolatedUid) { 6824 if (mChildUids == null) { 6825 mChildUids = new IntArray(); 6826 } else if (mChildUids.indexOf(isolatedUid) >= 0) { 6827 return; 6828 } 6829 mChildUids.add(isolatedUid); 6830 } 6831 removeIsolatedUid(int isolatedUid)6832 public void removeIsolatedUid(int isolatedUid) { 6833 final int idx = mChildUids == null ? -1 : mChildUids.indexOf(isolatedUid); 6834 if (idx < 0) { 6835 return; 6836 } 6837 mChildUids.remove(idx); 6838 } 6839 nullIfAllZeros(LongSamplingCounterArray cpuTimesMs, int which)6840 private long[] nullIfAllZeros(LongSamplingCounterArray cpuTimesMs, int which) { 6841 if (cpuTimesMs == null) { 6842 return null; 6843 } 6844 final long[] counts = cpuTimesMs.getCountsLocked(which); 6845 if (counts == null) { 6846 return null; 6847 } 6848 // Return counts only if at least one of the elements is non-zero. 6849 for (int i = counts.length - 1; i >= 0; --i) { 6850 if (counts[i] != 0) { 6851 return counts; 6852 } 6853 } 6854 return null; 6855 } 6856 addProcStateTimesMs(int procState, long[] cpuTimesMs, boolean onBattery)6857 private void addProcStateTimesMs(int procState, long[] cpuTimesMs, boolean onBattery) { 6858 if (mProcStateTimeMs == null) { 6859 mProcStateTimeMs = new LongSamplingCounterArray[NUM_PROCESS_STATE]; 6860 } 6861 if (mProcStateTimeMs[procState] == null 6862 || mProcStateTimeMs[procState].getSize() != cpuTimesMs.length) { 6863 detachIfNotNull(mProcStateTimeMs[procState]); 6864 mProcStateTimeMs[procState] = new LongSamplingCounterArray( 6865 mBsi.mOnBatteryTimeBase); 6866 } 6867 mProcStateTimeMs[procState].addCountLocked(cpuTimesMs, onBattery); 6868 } 6869 addProcStateScreenOffTimesMs(int procState, long[] cpuTimesMs, boolean onBatteryScreenOff)6870 private void addProcStateScreenOffTimesMs(int procState, long[] cpuTimesMs, 6871 boolean onBatteryScreenOff) { 6872 if (mProcStateScreenOffTimeMs == null) { 6873 mProcStateScreenOffTimeMs = new LongSamplingCounterArray[NUM_PROCESS_STATE]; 6874 } 6875 if (mProcStateScreenOffTimeMs[procState] == null 6876 || mProcStateScreenOffTimeMs[procState].getSize() != cpuTimesMs.length) { 6877 detachIfNotNull(mProcStateScreenOffTimeMs[procState]); 6878 mProcStateScreenOffTimeMs[procState] = new LongSamplingCounterArray( 6879 mBsi.mOnBatteryScreenOffTimeBase); 6880 } 6881 mProcStateScreenOffTimeMs[procState].addCountLocked(cpuTimesMs, onBatteryScreenOff); 6882 } 6883 6884 @Override getAggregatedPartialWakelockTimer()6885 public Timer getAggregatedPartialWakelockTimer() { 6886 return mAggregatedPartialWakelockTimer; 6887 } 6888 6889 @Override 6890 @UnsupportedAppUsage getWakelockStats()6891 public ArrayMap<String, ? extends BatteryStats.Uid.Wakelock> getWakelockStats() { 6892 return mWakelockStats.getMap(); 6893 } 6894 6895 @Override getMulticastWakelockStats()6896 public Timer getMulticastWakelockStats() { 6897 return mWifiMulticastTimer; 6898 } 6899 6900 @Override getSyncStats()6901 public ArrayMap<String, ? extends BatteryStats.Timer> getSyncStats() { 6902 return mSyncStats.getMap(); 6903 } 6904 6905 @Override getJobStats()6906 public ArrayMap<String, ? extends BatteryStats.Timer> getJobStats() { 6907 return mJobStats.getMap(); 6908 } 6909 6910 @Override getJobCompletionStats()6911 public ArrayMap<String, SparseIntArray> getJobCompletionStats() { 6912 return mJobCompletions; 6913 } 6914 6915 @Override 6916 @UnsupportedAppUsage getSensorStats()6917 public SparseArray<? extends BatteryStats.Uid.Sensor> getSensorStats() { 6918 return mSensorStats; 6919 } 6920 6921 @Override 6922 @UnsupportedAppUsage getProcessStats()6923 public ArrayMap<String, ? extends BatteryStats.Uid.Proc> getProcessStats() { 6924 return mProcessStats; 6925 } 6926 6927 @Override getPackageStats()6928 public ArrayMap<String, ? extends BatteryStats.Uid.Pkg> getPackageStats() { 6929 return mPackageStats; 6930 } 6931 6932 @Override 6933 @UnsupportedAppUsage getUid()6934 public int getUid() { 6935 return mUid; 6936 } 6937 6938 @Override noteWifiRunningLocked(long elapsedRealtimeMs)6939 public void noteWifiRunningLocked(long elapsedRealtimeMs) { 6940 if (!mWifiRunning) { 6941 mWifiRunning = true; 6942 if (mWifiRunningTimer == null) { 6943 mWifiRunningTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, WIFI_RUNNING, 6944 mBsi.mWifiRunningTimers, mBsi.mOnBatteryTimeBase); 6945 } 6946 mWifiRunningTimer.startRunningLocked(elapsedRealtimeMs); 6947 } 6948 } 6949 6950 @Override noteWifiStoppedLocked(long elapsedRealtimeMs)6951 public void noteWifiStoppedLocked(long elapsedRealtimeMs) { 6952 if (mWifiRunning) { 6953 mWifiRunning = false; 6954 mWifiRunningTimer.stopRunningLocked(elapsedRealtimeMs); 6955 } 6956 } 6957 6958 @Override noteFullWifiLockAcquiredLocked(long elapsedRealtimeMs)6959 public void noteFullWifiLockAcquiredLocked(long elapsedRealtimeMs) { 6960 if (!mFullWifiLockOut) { 6961 mFullWifiLockOut = true; 6962 if (mFullWifiLockTimer == null) { 6963 mFullWifiLockTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, FULL_WIFI_LOCK, 6964 mBsi.mFullWifiLockTimers, mBsi.mOnBatteryTimeBase); 6965 } 6966 mFullWifiLockTimer.startRunningLocked(elapsedRealtimeMs); 6967 } 6968 } 6969 6970 @Override noteFullWifiLockReleasedLocked(long elapsedRealtimeMs)6971 public void noteFullWifiLockReleasedLocked(long elapsedRealtimeMs) { 6972 if (mFullWifiLockOut) { 6973 mFullWifiLockOut = false; 6974 mFullWifiLockTimer.stopRunningLocked(elapsedRealtimeMs); 6975 } 6976 } 6977 6978 @Override noteWifiScanStartedLocked(long elapsedRealtimeMs)6979 public void noteWifiScanStartedLocked(long elapsedRealtimeMs) { 6980 if (!mWifiScanStarted) { 6981 mWifiScanStarted = true; 6982 if (mWifiScanTimer == null) { 6983 mWifiScanTimer = new DualTimer(mBsi.mClocks, Uid.this, WIFI_SCAN, 6984 mBsi.mWifiScanTimers, mBsi.mOnBatteryTimeBase, 6985 mOnBatteryBackgroundTimeBase); 6986 } 6987 mWifiScanTimer.startRunningLocked(elapsedRealtimeMs); 6988 } 6989 } 6990 6991 @Override noteWifiScanStoppedLocked(long elapsedRealtimeMs)6992 public void noteWifiScanStoppedLocked(long elapsedRealtimeMs) { 6993 if (mWifiScanStarted) { 6994 mWifiScanStarted = false; 6995 mWifiScanTimer.stopRunningLocked(elapsedRealtimeMs); 6996 } 6997 } 6998 6999 @Override noteWifiBatchedScanStartedLocked(int csph, long elapsedRealtimeMs)7000 public void noteWifiBatchedScanStartedLocked(int csph, long elapsedRealtimeMs) { 7001 int bin = 0; 7002 while (csph > 8 && bin < NUM_WIFI_BATCHED_SCAN_BINS-1) { 7003 csph = csph >> 3; 7004 bin++; 7005 } 7006 7007 if (mWifiBatchedScanBinStarted == bin) return; 7008 7009 if (mWifiBatchedScanBinStarted != NO_BATCHED_SCAN_STARTED) { 7010 mWifiBatchedScanTimer[mWifiBatchedScanBinStarted]. 7011 stopRunningLocked(elapsedRealtimeMs); 7012 } 7013 mWifiBatchedScanBinStarted = bin; 7014 if (mWifiBatchedScanTimer[bin] == null) { 7015 makeWifiBatchedScanBin(bin, null); 7016 } 7017 mWifiBatchedScanTimer[bin].startRunningLocked(elapsedRealtimeMs); 7018 } 7019 7020 @Override noteWifiBatchedScanStoppedLocked(long elapsedRealtimeMs)7021 public void noteWifiBatchedScanStoppedLocked(long elapsedRealtimeMs) { 7022 if (mWifiBatchedScanBinStarted != NO_BATCHED_SCAN_STARTED) { 7023 mWifiBatchedScanTimer[mWifiBatchedScanBinStarted]. 7024 stopRunningLocked(elapsedRealtimeMs); 7025 mWifiBatchedScanBinStarted = NO_BATCHED_SCAN_STARTED; 7026 } 7027 } 7028 7029 @Override noteWifiMulticastEnabledLocked(long elapsedRealtimeMs)7030 public void noteWifiMulticastEnabledLocked(long elapsedRealtimeMs) { 7031 if (mWifiMulticastWakelockCount == 0) { 7032 if (mWifiMulticastTimer == null) { 7033 mWifiMulticastTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, 7034 WIFI_MULTICAST_ENABLED, mBsi.mWifiMulticastTimers, mBsi.mOnBatteryTimeBase); 7035 } 7036 mWifiMulticastTimer.startRunningLocked(elapsedRealtimeMs); 7037 } 7038 mWifiMulticastWakelockCount++; 7039 } 7040 7041 @Override noteWifiMulticastDisabledLocked(long elapsedRealtimeMs)7042 public void noteWifiMulticastDisabledLocked(long elapsedRealtimeMs) { 7043 if (mWifiMulticastWakelockCount == 0) { 7044 return; 7045 } 7046 7047 mWifiMulticastWakelockCount--; 7048 if (mWifiMulticastWakelockCount == 0) { 7049 mWifiMulticastTimer.stopRunningLocked(elapsedRealtimeMs); 7050 } 7051 } 7052 7053 @Override getWifiControllerActivity()7054 public ControllerActivityCounter getWifiControllerActivity() { 7055 return mWifiControllerActivity; 7056 } 7057 7058 @Override getBluetoothControllerActivity()7059 public ControllerActivityCounter getBluetoothControllerActivity() { 7060 return mBluetoothControllerActivity; 7061 } 7062 7063 @Override getModemControllerActivity()7064 public ControllerActivityCounter getModemControllerActivity() { 7065 return mModemControllerActivity; 7066 } 7067 getOrCreateWifiControllerActivityLocked()7068 public ControllerActivityCounterImpl getOrCreateWifiControllerActivityLocked() { 7069 if (mWifiControllerActivity == null) { 7070 mWifiControllerActivity = new ControllerActivityCounterImpl(mBsi.mOnBatteryTimeBase, 7071 NUM_BT_TX_LEVELS); 7072 } 7073 return mWifiControllerActivity; 7074 } 7075 getOrCreateBluetoothControllerActivityLocked()7076 public ControllerActivityCounterImpl getOrCreateBluetoothControllerActivityLocked() { 7077 if (mBluetoothControllerActivity == null) { 7078 mBluetoothControllerActivity = new ControllerActivityCounterImpl(mBsi.mOnBatteryTimeBase, 7079 NUM_BT_TX_LEVELS); 7080 } 7081 return mBluetoothControllerActivity; 7082 } 7083 getOrCreateModemControllerActivityLocked()7084 public ControllerActivityCounterImpl getOrCreateModemControllerActivityLocked() { 7085 if (mModemControllerActivity == null) { 7086 mModemControllerActivity = new ControllerActivityCounterImpl(mBsi.mOnBatteryTimeBase, 7087 ModemActivityInfo.TX_POWER_LEVELS); 7088 } 7089 return mModemControllerActivity; 7090 } 7091 createAudioTurnedOnTimerLocked()7092 public StopwatchTimer createAudioTurnedOnTimerLocked() { 7093 if (mAudioTurnedOnTimer == null) { 7094 mAudioTurnedOnTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, AUDIO_TURNED_ON, 7095 mBsi.mAudioTurnedOnTimers, mBsi.mOnBatteryTimeBase); 7096 } 7097 return mAudioTurnedOnTimer; 7098 } 7099 noteAudioTurnedOnLocked(long elapsedRealtimeMs)7100 public void noteAudioTurnedOnLocked(long elapsedRealtimeMs) { 7101 createAudioTurnedOnTimerLocked().startRunningLocked(elapsedRealtimeMs); 7102 } 7103 noteAudioTurnedOffLocked(long elapsedRealtimeMs)7104 public void noteAudioTurnedOffLocked(long elapsedRealtimeMs) { 7105 if (mAudioTurnedOnTimer != null) { 7106 mAudioTurnedOnTimer.stopRunningLocked(elapsedRealtimeMs); 7107 } 7108 } 7109 noteResetAudioLocked(long elapsedRealtimeMs)7110 public void noteResetAudioLocked(long elapsedRealtimeMs) { 7111 if (mAudioTurnedOnTimer != null) { 7112 mAudioTurnedOnTimer.stopAllRunningLocked(elapsedRealtimeMs); 7113 } 7114 } 7115 createVideoTurnedOnTimerLocked()7116 public StopwatchTimer createVideoTurnedOnTimerLocked() { 7117 if (mVideoTurnedOnTimer == null) { 7118 mVideoTurnedOnTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, VIDEO_TURNED_ON, 7119 mBsi.mVideoTurnedOnTimers, mBsi.mOnBatteryTimeBase); 7120 } 7121 return mVideoTurnedOnTimer; 7122 } 7123 noteVideoTurnedOnLocked(long elapsedRealtimeMs)7124 public void noteVideoTurnedOnLocked(long elapsedRealtimeMs) { 7125 createVideoTurnedOnTimerLocked().startRunningLocked(elapsedRealtimeMs); 7126 } 7127 noteVideoTurnedOffLocked(long elapsedRealtimeMs)7128 public void noteVideoTurnedOffLocked(long elapsedRealtimeMs) { 7129 if (mVideoTurnedOnTimer != null) { 7130 mVideoTurnedOnTimer.stopRunningLocked(elapsedRealtimeMs); 7131 } 7132 } 7133 noteResetVideoLocked(long elapsedRealtimeMs)7134 public void noteResetVideoLocked(long elapsedRealtimeMs) { 7135 if (mVideoTurnedOnTimer != null) { 7136 mVideoTurnedOnTimer.stopAllRunningLocked(elapsedRealtimeMs); 7137 } 7138 } 7139 createFlashlightTurnedOnTimerLocked()7140 public StopwatchTimer createFlashlightTurnedOnTimerLocked() { 7141 if (mFlashlightTurnedOnTimer == null) { 7142 mFlashlightTurnedOnTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, 7143 FLASHLIGHT_TURNED_ON, mBsi.mFlashlightTurnedOnTimers, mBsi.mOnBatteryTimeBase); 7144 } 7145 return mFlashlightTurnedOnTimer; 7146 } 7147 noteFlashlightTurnedOnLocked(long elapsedRealtimeMs)7148 public void noteFlashlightTurnedOnLocked(long elapsedRealtimeMs) { 7149 createFlashlightTurnedOnTimerLocked().startRunningLocked(elapsedRealtimeMs); 7150 } 7151 noteFlashlightTurnedOffLocked(long elapsedRealtimeMs)7152 public void noteFlashlightTurnedOffLocked(long elapsedRealtimeMs) { 7153 if (mFlashlightTurnedOnTimer != null) { 7154 mFlashlightTurnedOnTimer.stopRunningLocked(elapsedRealtimeMs); 7155 } 7156 } 7157 noteResetFlashlightLocked(long elapsedRealtimeMs)7158 public void noteResetFlashlightLocked(long elapsedRealtimeMs) { 7159 if (mFlashlightTurnedOnTimer != null) { 7160 mFlashlightTurnedOnTimer.stopAllRunningLocked(elapsedRealtimeMs); 7161 } 7162 } 7163 createCameraTurnedOnTimerLocked()7164 public StopwatchTimer createCameraTurnedOnTimerLocked() { 7165 if (mCameraTurnedOnTimer == null) { 7166 mCameraTurnedOnTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, CAMERA_TURNED_ON, 7167 mBsi.mCameraTurnedOnTimers, mBsi.mOnBatteryTimeBase); 7168 } 7169 return mCameraTurnedOnTimer; 7170 } 7171 noteCameraTurnedOnLocked(long elapsedRealtimeMs)7172 public void noteCameraTurnedOnLocked(long elapsedRealtimeMs) { 7173 createCameraTurnedOnTimerLocked().startRunningLocked(elapsedRealtimeMs); 7174 } 7175 noteCameraTurnedOffLocked(long elapsedRealtimeMs)7176 public void noteCameraTurnedOffLocked(long elapsedRealtimeMs) { 7177 if (mCameraTurnedOnTimer != null) { 7178 mCameraTurnedOnTimer.stopRunningLocked(elapsedRealtimeMs); 7179 } 7180 } 7181 noteResetCameraLocked(long elapsedRealtimeMs)7182 public void noteResetCameraLocked(long elapsedRealtimeMs) { 7183 if (mCameraTurnedOnTimer != null) { 7184 mCameraTurnedOnTimer.stopAllRunningLocked(elapsedRealtimeMs); 7185 } 7186 } 7187 createForegroundActivityTimerLocked()7188 public StopwatchTimer createForegroundActivityTimerLocked() { 7189 if (mForegroundActivityTimer == null) { 7190 mForegroundActivityTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, 7191 FOREGROUND_ACTIVITY, null, mBsi.mOnBatteryTimeBase); 7192 } 7193 return mForegroundActivityTimer; 7194 } 7195 createForegroundServiceTimerLocked()7196 public StopwatchTimer createForegroundServiceTimerLocked() { 7197 if (mForegroundServiceTimer == null) { 7198 mForegroundServiceTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, 7199 FOREGROUND_SERVICE, null, mBsi.mOnBatteryTimeBase); 7200 } 7201 return mForegroundServiceTimer; 7202 } 7203 createAggregatedPartialWakelockTimerLocked()7204 public DualTimer createAggregatedPartialWakelockTimerLocked() { 7205 if (mAggregatedPartialWakelockTimer == null) { 7206 mAggregatedPartialWakelockTimer = new DualTimer(mBsi.mClocks, this, 7207 AGGREGATED_WAKE_TYPE_PARTIAL, null, 7208 mBsi.mOnBatteryScreenOffTimeBase, mOnBatteryScreenOffBackgroundTimeBase); 7209 } 7210 return mAggregatedPartialWakelockTimer; 7211 } 7212 createBluetoothScanTimerLocked()7213 public DualTimer createBluetoothScanTimerLocked() { 7214 if (mBluetoothScanTimer == null) { 7215 mBluetoothScanTimer = new DualTimer(mBsi.mClocks, Uid.this, BLUETOOTH_SCAN_ON, 7216 mBsi.mBluetoothScanOnTimers, mBsi.mOnBatteryTimeBase, 7217 mOnBatteryBackgroundTimeBase); 7218 } 7219 return mBluetoothScanTimer; 7220 } 7221 createBluetoothUnoptimizedScanTimerLocked()7222 public DualTimer createBluetoothUnoptimizedScanTimerLocked() { 7223 if (mBluetoothUnoptimizedScanTimer == null) { 7224 mBluetoothUnoptimizedScanTimer = new DualTimer(mBsi.mClocks, Uid.this, 7225 BLUETOOTH_UNOPTIMIZED_SCAN_ON, null, 7226 mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase); 7227 } 7228 return mBluetoothUnoptimizedScanTimer; 7229 } 7230 noteBluetoothScanStartedLocked(long elapsedRealtimeMs, boolean isUnoptimized)7231 public void noteBluetoothScanStartedLocked(long elapsedRealtimeMs, 7232 boolean isUnoptimized) { 7233 createBluetoothScanTimerLocked().startRunningLocked(elapsedRealtimeMs); 7234 if (isUnoptimized) { 7235 createBluetoothUnoptimizedScanTimerLocked().startRunningLocked(elapsedRealtimeMs); 7236 } 7237 } 7238 noteBluetoothScanStoppedLocked(long elapsedRealtimeMs, boolean isUnoptimized)7239 public void noteBluetoothScanStoppedLocked(long elapsedRealtimeMs, boolean isUnoptimized) { 7240 if (mBluetoothScanTimer != null) { 7241 mBluetoothScanTimer.stopRunningLocked(elapsedRealtimeMs); 7242 } 7243 if (isUnoptimized && mBluetoothUnoptimizedScanTimer != null) { 7244 mBluetoothUnoptimizedScanTimer.stopRunningLocked(elapsedRealtimeMs); 7245 } 7246 } 7247 noteResetBluetoothScanLocked(long elapsedRealtimeMs)7248 public void noteResetBluetoothScanLocked(long elapsedRealtimeMs) { 7249 if (mBluetoothScanTimer != null) { 7250 mBluetoothScanTimer.stopAllRunningLocked(elapsedRealtimeMs); 7251 } 7252 if (mBluetoothUnoptimizedScanTimer != null) { 7253 mBluetoothUnoptimizedScanTimer.stopAllRunningLocked(elapsedRealtimeMs); 7254 } 7255 } 7256 createBluetoothScanResultCounterLocked()7257 public Counter createBluetoothScanResultCounterLocked() { 7258 if (mBluetoothScanResultCounter == null) { 7259 mBluetoothScanResultCounter = new Counter(mBsi.mOnBatteryTimeBase); 7260 } 7261 return mBluetoothScanResultCounter; 7262 } 7263 createBluetoothScanResultBgCounterLocked()7264 public Counter createBluetoothScanResultBgCounterLocked() { 7265 if (mBluetoothScanResultBgCounter == null) { 7266 mBluetoothScanResultBgCounter = new Counter(mOnBatteryBackgroundTimeBase); 7267 } 7268 return mBluetoothScanResultBgCounter; 7269 } 7270 noteBluetoothScanResultsLocked(int numNewResults)7271 public void noteBluetoothScanResultsLocked(int numNewResults) { 7272 createBluetoothScanResultCounterLocked().addAtomic(numNewResults); 7273 // Uses background timebase, so the count will only be incremented if uid in background. 7274 createBluetoothScanResultBgCounterLocked().addAtomic(numNewResults); 7275 } 7276 7277 @Override noteActivityResumedLocked(long elapsedRealtimeMs)7278 public void noteActivityResumedLocked(long elapsedRealtimeMs) { 7279 // We always start, since we want multiple foreground PIDs to nest 7280 createForegroundActivityTimerLocked().startRunningLocked(elapsedRealtimeMs); 7281 } 7282 7283 @Override noteActivityPausedLocked(long elapsedRealtimeMs)7284 public void noteActivityPausedLocked(long elapsedRealtimeMs) { 7285 if (mForegroundActivityTimer != null) { 7286 mForegroundActivityTimer.stopRunningLocked(elapsedRealtimeMs); 7287 } 7288 } 7289 noteForegroundServiceResumedLocked(long elapsedRealtimeMs)7290 public void noteForegroundServiceResumedLocked(long elapsedRealtimeMs) { 7291 createForegroundServiceTimerLocked().startRunningLocked(elapsedRealtimeMs); 7292 } 7293 noteForegroundServicePausedLocked(long elapsedRealtimeMs)7294 public void noteForegroundServicePausedLocked(long elapsedRealtimeMs) { 7295 if (mForegroundServiceTimer != null) { 7296 mForegroundServiceTimer.stopRunningLocked(elapsedRealtimeMs); 7297 } 7298 } 7299 createVibratorOnTimerLocked()7300 public BatchTimer createVibratorOnTimerLocked() { 7301 if (mVibratorOnTimer == null) { 7302 mVibratorOnTimer = new BatchTimer(mBsi.mClocks, Uid.this, VIBRATOR_ON, 7303 mBsi.mOnBatteryTimeBase); 7304 } 7305 return mVibratorOnTimer; 7306 } 7307 noteVibratorOnLocked(long durationMillis)7308 public void noteVibratorOnLocked(long durationMillis) { 7309 createVibratorOnTimerLocked().addDuration(mBsi, durationMillis); 7310 } 7311 noteVibratorOffLocked()7312 public void noteVibratorOffLocked() { 7313 if (mVibratorOnTimer != null) { 7314 mVibratorOnTimer.abortLastDuration(mBsi); 7315 } 7316 } 7317 7318 @Override 7319 @UnsupportedAppUsage getWifiRunningTime(long elapsedRealtimeUs, int which)7320 public long getWifiRunningTime(long elapsedRealtimeUs, int which) { 7321 if (mWifiRunningTimer == null) { 7322 return 0; 7323 } 7324 return mWifiRunningTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 7325 } 7326 7327 @Override getFullWifiLockTime(long elapsedRealtimeUs, int which)7328 public long getFullWifiLockTime(long elapsedRealtimeUs, int which) { 7329 if (mFullWifiLockTimer == null) { 7330 return 0; 7331 } 7332 return mFullWifiLockTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 7333 } 7334 7335 @Override 7336 @UnsupportedAppUsage getWifiScanTime(long elapsedRealtimeUs, int which)7337 public long getWifiScanTime(long elapsedRealtimeUs, int which) { 7338 if (mWifiScanTimer == null) { 7339 return 0; 7340 } 7341 return mWifiScanTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 7342 } 7343 7344 @Override getWifiScanCount(int which)7345 public int getWifiScanCount(int which) { 7346 if (mWifiScanTimer == null) { 7347 return 0; 7348 } 7349 return mWifiScanTimer.getCountLocked(which); 7350 } 7351 7352 @Override getWifiScanTimer()7353 public Timer getWifiScanTimer() { 7354 return mWifiScanTimer; 7355 } 7356 7357 @Override getWifiScanBackgroundCount(int which)7358 public int getWifiScanBackgroundCount(int which) { 7359 if (mWifiScanTimer == null || mWifiScanTimer.getSubTimer() == null) { 7360 return 0; 7361 } 7362 return mWifiScanTimer.getSubTimer().getCountLocked(which); 7363 } 7364 7365 @Override getWifiScanActualTime(final long elapsedRealtimeUs)7366 public long getWifiScanActualTime(final long elapsedRealtimeUs) { 7367 if (mWifiScanTimer == null) { 7368 return 0; 7369 } 7370 final long elapsedRealtimeMs = (elapsedRealtimeUs + 500) / 1000; 7371 return mWifiScanTimer.getTotalDurationMsLocked(elapsedRealtimeMs) * 1000; 7372 } 7373 7374 @Override getWifiScanBackgroundTime(final long elapsedRealtimeUs)7375 public long getWifiScanBackgroundTime(final long elapsedRealtimeUs) { 7376 if (mWifiScanTimer == null || mWifiScanTimer.getSubTimer() == null) { 7377 return 0; 7378 } 7379 final long elapsedRealtimeMs = (elapsedRealtimeUs + 500) / 1000; 7380 return mWifiScanTimer.getSubTimer().getTotalDurationMsLocked(elapsedRealtimeMs) * 1000; 7381 } 7382 7383 @Override getWifiScanBackgroundTimer()7384 public Timer getWifiScanBackgroundTimer() { 7385 if (mWifiScanTimer == null) { 7386 return null; 7387 } 7388 return mWifiScanTimer.getSubTimer(); 7389 } 7390 7391 @Override getWifiBatchedScanTime(int csphBin, long elapsedRealtimeUs, int which)7392 public long getWifiBatchedScanTime(int csphBin, long elapsedRealtimeUs, int which) { 7393 if (csphBin < 0 || csphBin >= NUM_WIFI_BATCHED_SCAN_BINS) return 0; 7394 if (mWifiBatchedScanTimer[csphBin] == null) { 7395 return 0; 7396 } 7397 return mWifiBatchedScanTimer[csphBin].getTotalTimeLocked(elapsedRealtimeUs, which); 7398 } 7399 7400 @Override getWifiBatchedScanCount(int csphBin, int which)7401 public int getWifiBatchedScanCount(int csphBin, int which) { 7402 if (csphBin < 0 || csphBin >= NUM_WIFI_BATCHED_SCAN_BINS) return 0; 7403 if (mWifiBatchedScanTimer[csphBin] == null) { 7404 return 0; 7405 } 7406 return mWifiBatchedScanTimer[csphBin].getCountLocked(which); 7407 } 7408 7409 @Override getWifiMulticastTime(long elapsedRealtimeUs, int which)7410 public long getWifiMulticastTime(long elapsedRealtimeUs, int which) { 7411 if (mWifiMulticastTimer == null) { 7412 return 0; 7413 } 7414 return mWifiMulticastTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 7415 } 7416 7417 @Override getAudioTurnedOnTimer()7418 public Timer getAudioTurnedOnTimer() { 7419 return mAudioTurnedOnTimer; 7420 } 7421 7422 @Override getVideoTurnedOnTimer()7423 public Timer getVideoTurnedOnTimer() { 7424 return mVideoTurnedOnTimer; 7425 } 7426 7427 @Override getFlashlightTurnedOnTimer()7428 public Timer getFlashlightTurnedOnTimer() { 7429 return mFlashlightTurnedOnTimer; 7430 } 7431 7432 @Override getCameraTurnedOnTimer()7433 public Timer getCameraTurnedOnTimer() { 7434 return mCameraTurnedOnTimer; 7435 } 7436 7437 @Override getForegroundActivityTimer()7438 public Timer getForegroundActivityTimer() { 7439 return mForegroundActivityTimer; 7440 } 7441 7442 @Override getForegroundServiceTimer()7443 public Timer getForegroundServiceTimer() { 7444 return mForegroundServiceTimer; 7445 } 7446 7447 @Override getBluetoothScanTimer()7448 public Timer getBluetoothScanTimer() { 7449 return mBluetoothScanTimer; 7450 } 7451 7452 @Override getBluetoothScanBackgroundTimer()7453 public Timer getBluetoothScanBackgroundTimer() { 7454 if (mBluetoothScanTimer == null) { 7455 return null; 7456 } 7457 return mBluetoothScanTimer.getSubTimer(); 7458 } 7459 7460 @Override getBluetoothUnoptimizedScanTimer()7461 public Timer getBluetoothUnoptimizedScanTimer() { 7462 return mBluetoothUnoptimizedScanTimer; 7463 } 7464 7465 @Override getBluetoothUnoptimizedScanBackgroundTimer()7466 public Timer getBluetoothUnoptimizedScanBackgroundTimer() { 7467 if (mBluetoothUnoptimizedScanTimer == null) { 7468 return null; 7469 } 7470 return mBluetoothUnoptimizedScanTimer.getSubTimer(); 7471 } 7472 7473 @Override getBluetoothScanResultCounter()7474 public Counter getBluetoothScanResultCounter() { 7475 return mBluetoothScanResultCounter; 7476 } 7477 7478 @Override getBluetoothScanResultBgCounter()7479 public Counter getBluetoothScanResultBgCounter() { 7480 return mBluetoothScanResultBgCounter; 7481 } 7482 makeProcessState(int i, Parcel in)7483 void makeProcessState(int i, Parcel in) { 7484 if (i < 0 || i >= NUM_PROCESS_STATE) return; 7485 7486 detachIfNotNull(mProcessStateTimer[i]); 7487 if (in == null) { 7488 mProcessStateTimer[i] = new StopwatchTimer(mBsi.mClocks, this, PROCESS_STATE, null, 7489 mBsi.mOnBatteryTimeBase); 7490 } else { 7491 mProcessStateTimer[i] = new StopwatchTimer(mBsi.mClocks, this, PROCESS_STATE, null, 7492 mBsi.mOnBatteryTimeBase, in); 7493 } 7494 } 7495 7496 @Override getProcessStateTime(int state, long elapsedRealtimeUs, int which)7497 public long getProcessStateTime(int state, long elapsedRealtimeUs, int which) { 7498 if (state < 0 || state >= NUM_PROCESS_STATE) return 0; 7499 if (mProcessStateTimer[state] == null) { 7500 return 0; 7501 } 7502 return mProcessStateTimer[state].getTotalTimeLocked(elapsedRealtimeUs, which); 7503 } 7504 7505 @Override getProcessStateTimer(int state)7506 public Timer getProcessStateTimer(int state) { 7507 if (state < 0 || state >= NUM_PROCESS_STATE) return null; 7508 return mProcessStateTimer[state]; 7509 } 7510 7511 @Override getVibratorOnTimer()7512 public Timer getVibratorOnTimer() { 7513 return mVibratorOnTimer; 7514 } 7515 7516 @Override noteUserActivityLocked(int type)7517 public void noteUserActivityLocked(int type) { 7518 if (mUserActivityCounters == null) { 7519 initUserActivityLocked(); 7520 } 7521 if (type >= 0 && type < NUM_USER_ACTIVITY_TYPES) { 7522 mUserActivityCounters[type].stepAtomic(); 7523 } else { 7524 Slog.w(TAG, "Unknown user activity type " + type + " was specified.", 7525 new Throwable()); 7526 } 7527 } 7528 7529 @Override hasUserActivity()7530 public boolean hasUserActivity() { 7531 return mUserActivityCounters != null; 7532 } 7533 7534 @Override getUserActivityCount(int type, int which)7535 public int getUserActivityCount(int type, int which) { 7536 if (mUserActivityCounters == null) { 7537 return 0; 7538 } 7539 return mUserActivityCounters[type].getCountLocked(which); 7540 } 7541 makeWifiBatchedScanBin(int i, Parcel in)7542 void makeWifiBatchedScanBin(int i, Parcel in) { 7543 if (i < 0 || i >= NUM_WIFI_BATCHED_SCAN_BINS) return; 7544 7545 ArrayList<StopwatchTimer> collected = mBsi.mWifiBatchedScanTimers.get(i); 7546 if (collected == null) { 7547 collected = new ArrayList<StopwatchTimer>(); 7548 mBsi.mWifiBatchedScanTimers.put(i, collected); 7549 } 7550 detachIfNotNull(mWifiBatchedScanTimer[i]); 7551 if (in == null) { 7552 mWifiBatchedScanTimer[i] = new StopwatchTimer(mBsi.mClocks, this, WIFI_BATCHED_SCAN, 7553 collected, mBsi.mOnBatteryTimeBase); 7554 } else { 7555 mWifiBatchedScanTimer[i] = new StopwatchTimer(mBsi.mClocks, this, WIFI_BATCHED_SCAN, 7556 collected, mBsi.mOnBatteryTimeBase, in); 7557 } 7558 } 7559 7560 initUserActivityLocked()7561 void initUserActivityLocked() { 7562 detachIfNotNull(mUserActivityCounters); 7563 mUserActivityCounters = new Counter[NUM_USER_ACTIVITY_TYPES]; 7564 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) { 7565 mUserActivityCounters[i] = new Counter(mBsi.mOnBatteryTimeBase); 7566 } 7567 } 7568 noteNetworkActivityLocked(int type, long deltaBytes, long deltaPackets)7569 void noteNetworkActivityLocked(int type, long deltaBytes, long deltaPackets) { 7570 if (mNetworkByteActivityCounters == null) { 7571 initNetworkActivityLocked(); 7572 } 7573 if (type >= 0 && type < NUM_NETWORK_ACTIVITY_TYPES) { 7574 mNetworkByteActivityCounters[type].addCountLocked(deltaBytes); 7575 mNetworkPacketActivityCounters[type].addCountLocked(deltaPackets); 7576 } else { 7577 Slog.w(TAG, "Unknown network activity type " + type + " was specified.", 7578 new Throwable()); 7579 } 7580 } 7581 noteMobileRadioActiveTimeLocked(long batteryUptime)7582 void noteMobileRadioActiveTimeLocked(long batteryUptime) { 7583 if (mNetworkByteActivityCounters == null) { 7584 initNetworkActivityLocked(); 7585 } 7586 mMobileRadioActiveTime.addCountLocked(batteryUptime); 7587 mMobileRadioActiveCount.addCountLocked(1); 7588 } 7589 7590 @Override hasNetworkActivity()7591 public boolean hasNetworkActivity() { 7592 return mNetworkByteActivityCounters != null; 7593 } 7594 7595 @Override getNetworkActivityBytes(int type, int which)7596 public long getNetworkActivityBytes(int type, int which) { 7597 if (mNetworkByteActivityCounters != null && type >= 0 7598 && type < mNetworkByteActivityCounters.length) { 7599 return mNetworkByteActivityCounters[type].getCountLocked(which); 7600 } else { 7601 return 0; 7602 } 7603 } 7604 7605 @Override getNetworkActivityPackets(int type, int which)7606 public long getNetworkActivityPackets(int type, int which) { 7607 if (mNetworkPacketActivityCounters != null && type >= 0 7608 && type < mNetworkPacketActivityCounters.length) { 7609 return mNetworkPacketActivityCounters[type].getCountLocked(which); 7610 } else { 7611 return 0; 7612 } 7613 } 7614 7615 @Override getMobileRadioActiveTime(int which)7616 public long getMobileRadioActiveTime(int which) { 7617 return mMobileRadioActiveTime != null 7618 ? mMobileRadioActiveTime.getCountLocked(which) : 0; 7619 } 7620 7621 @Override getMobileRadioActiveCount(int which)7622 public int getMobileRadioActiveCount(int which) { 7623 return mMobileRadioActiveCount != null 7624 ? (int)mMobileRadioActiveCount.getCountLocked(which) : 0; 7625 } 7626 7627 @Override getUserCpuTimeUs(int which)7628 public long getUserCpuTimeUs(int which) { 7629 return mUserCpuTime.getCountLocked(which); 7630 } 7631 7632 @Override getSystemCpuTimeUs(int which)7633 public long getSystemCpuTimeUs(int which) { 7634 return mSystemCpuTime.getCountLocked(which); 7635 } 7636 7637 @Override getTimeAtCpuSpeed(int cluster, int step, int which)7638 public long getTimeAtCpuSpeed(int cluster, int step, int which) { 7639 if (mCpuClusterSpeedTimesUs != null) { 7640 if (cluster >= 0 && cluster < mCpuClusterSpeedTimesUs.length) { 7641 final LongSamplingCounter[] cpuSpeedTimesUs = mCpuClusterSpeedTimesUs[cluster]; 7642 if (cpuSpeedTimesUs != null) { 7643 if (step >= 0 && step < cpuSpeedTimesUs.length) { 7644 final LongSamplingCounter c = cpuSpeedTimesUs[step]; 7645 if (c != null) { 7646 return c.getCountLocked(which); 7647 } 7648 } 7649 } 7650 } 7651 } 7652 return 0; 7653 } 7654 noteMobileRadioApWakeupLocked()7655 public void noteMobileRadioApWakeupLocked() { 7656 if (mMobileRadioApWakeupCount == null) { 7657 mMobileRadioApWakeupCount = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); 7658 } 7659 mMobileRadioApWakeupCount.addCountLocked(1); 7660 } 7661 7662 @Override getMobileRadioApWakeupCount(int which)7663 public long getMobileRadioApWakeupCount(int which) { 7664 if (mMobileRadioApWakeupCount != null) { 7665 return mMobileRadioApWakeupCount.getCountLocked(which); 7666 } 7667 return 0; 7668 } 7669 noteWifiRadioApWakeupLocked()7670 public void noteWifiRadioApWakeupLocked() { 7671 if (mWifiRadioApWakeupCount == null) { 7672 mWifiRadioApWakeupCount = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); 7673 } 7674 mWifiRadioApWakeupCount.addCountLocked(1); 7675 } 7676 7677 @Override getWifiRadioApWakeupCount(int which)7678 public long getWifiRadioApWakeupCount(int which) { 7679 if (mWifiRadioApWakeupCount != null) { 7680 return mWifiRadioApWakeupCount.getCountLocked(which); 7681 } 7682 return 0; 7683 } 7684 7685 @Override getDeferredJobsCheckinLineLocked(StringBuilder sb, int which)7686 public void getDeferredJobsCheckinLineLocked(StringBuilder sb, int which) { 7687 sb.setLength(0); 7688 final int deferredEventCount = mJobsDeferredEventCount.getCountLocked(which); 7689 if (deferredEventCount == 0) { 7690 return; 7691 } 7692 final int deferredCount = mJobsDeferredCount.getCountLocked(which); 7693 final long totalLatency = mJobsFreshnessTimeMs.getCountLocked(which); 7694 sb.append(deferredEventCount); sb.append(','); 7695 sb.append(deferredCount); sb.append(','); 7696 sb.append(totalLatency); 7697 for (int i = 0; i < JOB_FRESHNESS_BUCKETS.length; i++) { 7698 if (mJobsFreshnessBuckets[i] == null) { 7699 sb.append(",0"); 7700 } else { 7701 sb.append(","); 7702 sb.append(mJobsFreshnessBuckets[i].getCountLocked(which)); 7703 } 7704 } 7705 } 7706 7707 @Override getDeferredJobsLineLocked(StringBuilder sb, int which)7708 public void getDeferredJobsLineLocked(StringBuilder sb, int which) { 7709 sb.setLength(0); 7710 final int deferredEventCount = mJobsDeferredEventCount.getCountLocked(which); 7711 if (deferredEventCount == 0) { 7712 return; 7713 } 7714 final int deferredCount = mJobsDeferredCount.getCountLocked(which); 7715 final long totalLatency = mJobsFreshnessTimeMs.getCountLocked(which); 7716 sb.append("times="); sb.append(deferredEventCount); sb.append(", "); 7717 sb.append("count="); sb.append(deferredCount); sb.append(", "); 7718 sb.append("totalLatencyMs="); sb.append(totalLatency); sb.append(", "); 7719 for (int i = 0; i < JOB_FRESHNESS_BUCKETS.length; i++) { 7720 sb.append("<"); sb.append(JOB_FRESHNESS_BUCKETS[i]); sb.append("ms="); 7721 if (mJobsFreshnessBuckets[i] == null) { 7722 sb.append("0"); 7723 } else { 7724 sb.append(mJobsFreshnessBuckets[i].getCountLocked(which)); 7725 } 7726 sb.append(" "); 7727 } 7728 } 7729 initNetworkActivityLocked()7730 void initNetworkActivityLocked() { 7731 detachIfNotNull(mNetworkByteActivityCounters); 7732 mNetworkByteActivityCounters = new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES]; 7733 detachIfNotNull(mNetworkPacketActivityCounters); 7734 mNetworkPacketActivityCounters = new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES]; 7735 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 7736 mNetworkByteActivityCounters[i] = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); 7737 mNetworkPacketActivityCounters[i] = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); 7738 } 7739 detachIfNotNull(mMobileRadioActiveTime); 7740 mMobileRadioActiveTime = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); 7741 detachIfNotNull(mMobileRadioActiveCount); 7742 mMobileRadioActiveCount = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); 7743 } 7744 7745 /** 7746 * Clear all stats for this uid. Returns true if the uid is completely 7747 * inactive so can be dropped. 7748 */ 7749 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) reset(long uptime, long realtime)7750 public boolean reset(long uptime, long realtime) { 7751 boolean active = false; 7752 7753 mOnBatteryBackgroundTimeBase.init(uptime, realtime); 7754 mOnBatteryScreenOffBackgroundTimeBase.init(uptime, realtime); 7755 7756 if (mWifiRunningTimer != null) { 7757 active |= !mWifiRunningTimer.reset(false); 7758 active |= mWifiRunning; 7759 } 7760 if (mFullWifiLockTimer != null) { 7761 active |= !mFullWifiLockTimer.reset(false); 7762 active |= mFullWifiLockOut; 7763 } 7764 if (mWifiScanTimer != null) { 7765 active |= !mWifiScanTimer.reset(false); 7766 active |= mWifiScanStarted; 7767 } 7768 if (mWifiBatchedScanTimer != null) { 7769 for (int i = 0; i < NUM_WIFI_BATCHED_SCAN_BINS; i++) { 7770 if (mWifiBatchedScanTimer[i] != null) { 7771 active |= !mWifiBatchedScanTimer[i].reset(false); 7772 } 7773 } 7774 active |= (mWifiBatchedScanBinStarted != NO_BATCHED_SCAN_STARTED); 7775 } 7776 if (mWifiMulticastTimer != null) { 7777 active |= !mWifiMulticastTimer.reset(false); 7778 active |= (mWifiMulticastWakelockCount > 0); 7779 } 7780 7781 active |= !resetIfNotNull(mAudioTurnedOnTimer, false); 7782 active |= !resetIfNotNull(mVideoTurnedOnTimer, false); 7783 active |= !resetIfNotNull(mFlashlightTurnedOnTimer, false); 7784 active |= !resetIfNotNull(mCameraTurnedOnTimer, false); 7785 active |= !resetIfNotNull(mForegroundActivityTimer, false); 7786 active |= !resetIfNotNull(mForegroundServiceTimer, false); 7787 active |= !resetIfNotNull(mAggregatedPartialWakelockTimer, false); 7788 active |= !resetIfNotNull(mBluetoothScanTimer, false); 7789 active |= !resetIfNotNull(mBluetoothUnoptimizedScanTimer, false); 7790 7791 resetIfNotNull(mBluetoothScanResultCounter, false); 7792 resetIfNotNull(mBluetoothScanResultBgCounter, false); 7793 7794 if (mProcessStateTimer != null) { 7795 for (int i = 0; i < NUM_PROCESS_STATE; i++) { 7796 active |= !resetIfNotNull(mProcessStateTimer[i], false); 7797 } 7798 active |= (mProcessState != ActivityManager.PROCESS_STATE_NONEXISTENT); 7799 } 7800 if (mVibratorOnTimer != null) { 7801 if (mVibratorOnTimer.reset(false)) { 7802 mVibratorOnTimer.detach(); 7803 mVibratorOnTimer = null; 7804 } else { 7805 active = true; 7806 } 7807 } 7808 7809 resetIfNotNull(mUserActivityCounters, false); 7810 7811 resetIfNotNull(mNetworkByteActivityCounters, false); 7812 resetIfNotNull(mNetworkPacketActivityCounters, false); 7813 resetIfNotNull(mMobileRadioActiveTime, false); 7814 resetIfNotNull(mMobileRadioActiveCount, false); 7815 7816 resetIfNotNull(mWifiControllerActivity, false); 7817 resetIfNotNull(mBluetoothControllerActivity, false); 7818 resetIfNotNull(mModemControllerActivity, false); 7819 7820 resetIfNotNull(mUserCpuTime, false); 7821 resetIfNotNull(mSystemCpuTime, false); 7822 7823 resetIfNotNull(mCpuClusterSpeedTimesUs, false); 7824 7825 resetIfNotNull(mCpuFreqTimeMs, false); 7826 resetIfNotNull(mScreenOffCpuFreqTimeMs, false); 7827 7828 7829 resetIfNotNull(mCpuActiveTimeMs, false); 7830 resetIfNotNull(mCpuClusterTimesMs, false); 7831 7832 resetIfNotNull(mProcStateTimeMs, false); 7833 7834 resetIfNotNull(mProcStateScreenOffTimeMs, false); 7835 7836 resetIfNotNull(mMobileRadioApWakeupCount, false); 7837 7838 resetIfNotNull(mWifiRadioApWakeupCount, false); 7839 7840 7841 final ArrayMap<String, Wakelock> wakeStats = mWakelockStats.getMap(); 7842 for (int iw=wakeStats.size()-1; iw>=0; iw--) { 7843 Wakelock wl = wakeStats.valueAt(iw); 7844 if (wl.reset()) { 7845 wakeStats.removeAt(iw); 7846 } else { 7847 active = true; 7848 } 7849 } 7850 mWakelockStats.cleanup(); 7851 final ArrayMap<String, DualTimer> syncStats = mSyncStats.getMap(); 7852 for (int is=syncStats.size()-1; is>=0; is--) { 7853 DualTimer timer = syncStats.valueAt(is); 7854 if (timer.reset(false)) { 7855 syncStats.removeAt(is); 7856 timer.detach(); 7857 } else { 7858 active = true; 7859 } 7860 } 7861 mSyncStats.cleanup(); 7862 final ArrayMap<String, DualTimer> jobStats = mJobStats.getMap(); 7863 for (int ij=jobStats.size()-1; ij>=0; ij--) { 7864 DualTimer timer = jobStats.valueAt(ij); 7865 if (timer.reset(false)) { 7866 jobStats.removeAt(ij); 7867 timer.detach(); 7868 } else { 7869 active = true; 7870 } 7871 } 7872 mJobStats.cleanup(); 7873 mJobCompletions.clear(); 7874 7875 resetIfNotNull(mJobsDeferredEventCount, false); 7876 resetIfNotNull(mJobsDeferredCount, false); 7877 resetIfNotNull(mJobsFreshnessTimeMs, false); 7878 resetIfNotNull(mJobsFreshnessBuckets, false); 7879 7880 for (int ise = mSensorStats.size() - 1; ise >= 0; ise--) { 7881 Sensor s = mSensorStats.valueAt(ise); 7882 if (s.reset()) { 7883 mSensorStats.removeAt(ise); 7884 } else { 7885 active = true; 7886 } 7887 } 7888 7889 for (int ip = mProcessStats.size() - 1; ip >= 0; ip--) { 7890 Proc proc = mProcessStats.valueAt(ip); 7891 proc.detach(); 7892 } 7893 mProcessStats.clear(); 7894 7895 for (int i = mPids.size() - 1; i >= 0; i--) { 7896 Pid pid = mPids.valueAt(i); 7897 if (pid.mWakeNesting > 0) { 7898 active = true; 7899 } else { 7900 mPids.removeAt(i); 7901 } 7902 } 7903 7904 7905 for(int i = mPackageStats.size() - 1; i >= 0; i--) { 7906 Pkg p = mPackageStats.valueAt(i); 7907 p.detach(); 7908 } 7909 mPackageStats.clear(); 7910 7911 mLastStepUserTime = mLastStepSystemTime = 0; 7912 mCurStepUserTime = mCurStepSystemTime = 0; 7913 7914 return !active; 7915 } 7916 7917 /** 7918 * This method MUST be called whenever the Uid object is destructed, otherwise it is a 7919 * memory leak in {@link TimeBase#mObservers} list. 7920 * Typically the Uid object is destructed when it is removed from 7921 * {@link BatteryStatsImpl#mUidStats} 7922 */ detachFromTimeBase()7923 void detachFromTimeBase() { 7924 detachIfNotNull(mWifiRunningTimer); 7925 detachIfNotNull(mFullWifiLockTimer); 7926 detachIfNotNull(mWifiScanTimer); 7927 detachIfNotNull(mWifiBatchedScanTimer); 7928 detachIfNotNull(mWifiMulticastTimer); 7929 detachIfNotNull(mAudioTurnedOnTimer); 7930 detachIfNotNull(mVideoTurnedOnTimer); 7931 detachIfNotNull(mFlashlightTurnedOnTimer); 7932 7933 detachIfNotNull(mCameraTurnedOnTimer); 7934 detachIfNotNull(mForegroundActivityTimer); 7935 detachIfNotNull(mForegroundServiceTimer); 7936 7937 detachIfNotNull(mAggregatedPartialWakelockTimer); 7938 7939 detachIfNotNull(mBluetoothScanTimer); 7940 detachIfNotNull(mBluetoothUnoptimizedScanTimer); 7941 detachIfNotNull(mBluetoothScanResultCounter); 7942 detachIfNotNull(mBluetoothScanResultBgCounter); 7943 7944 detachIfNotNull(mProcessStateTimer); 7945 7946 detachIfNotNull(mVibratorOnTimer); 7947 7948 detachIfNotNull(mUserActivityCounters); 7949 7950 detachIfNotNull(mNetworkByteActivityCounters); 7951 detachIfNotNull(mNetworkPacketActivityCounters); 7952 7953 detachIfNotNull(mMobileRadioActiveTime); 7954 detachIfNotNull(mMobileRadioActiveCount); 7955 detachIfNotNull(mMobileRadioApWakeupCount); 7956 detachIfNotNull(mWifiRadioApWakeupCount); 7957 7958 detachIfNotNull(mWifiControllerActivity); 7959 detachIfNotNull(mBluetoothControllerActivity); 7960 detachIfNotNull(mModemControllerActivity); 7961 7962 mPids.clear(); 7963 7964 detachIfNotNull(mUserCpuTime); 7965 detachIfNotNull(mSystemCpuTime); 7966 7967 detachIfNotNull(mCpuClusterSpeedTimesUs); 7968 7969 detachIfNotNull(mCpuActiveTimeMs); 7970 detachIfNotNull(mCpuFreqTimeMs); 7971 7972 detachIfNotNull(mScreenOffCpuFreqTimeMs); 7973 7974 detachIfNotNull(mCpuClusterTimesMs); 7975 7976 detachIfNotNull(mProcStateTimeMs); 7977 7978 detachIfNotNull(mProcStateScreenOffTimeMs); 7979 7980 final ArrayMap<String, Wakelock> wakeStats = mWakelockStats.getMap(); 7981 for (int iw = wakeStats.size() - 1; iw >= 0; iw--) { 7982 Wakelock wl = wakeStats.valueAt(iw); 7983 wl.detachFromTimeBase(); 7984 } 7985 final ArrayMap<String, DualTimer> syncStats = mSyncStats.getMap(); 7986 for (int is = syncStats.size() - 1; is >= 0; is--) { 7987 DualTimer timer = syncStats.valueAt(is); 7988 detachIfNotNull(timer); 7989 } 7990 final ArrayMap<String, DualTimer> jobStats = mJobStats.getMap(); 7991 for (int ij = jobStats.size() - 1; ij >= 0; ij--) { 7992 DualTimer timer = jobStats.valueAt(ij); 7993 detachIfNotNull(timer); 7994 } 7995 7996 detachIfNotNull(mJobsDeferredEventCount); 7997 detachIfNotNull(mJobsDeferredCount); 7998 detachIfNotNull(mJobsFreshnessTimeMs); 7999 detachIfNotNull(mJobsFreshnessBuckets); 8000 8001 8002 for (int ise = mSensorStats.size() - 1; ise >= 0; ise--) { 8003 Sensor s = mSensorStats.valueAt(ise); 8004 s.detachFromTimeBase(); 8005 } 8006 8007 for (int ip= mProcessStats.size() - 1; ip >= 0; ip--) { 8008 Proc proc = mProcessStats.valueAt(ip); 8009 proc.detach(); 8010 } 8011 mProcessStats.clear(); 8012 8013 for(int i = mPackageStats.size() - 1; i >= 0; i--) { 8014 Pkg p = mPackageStats.valueAt(i); 8015 p.detach(); 8016 } 8017 mPackageStats.clear(); 8018 } 8019 writeJobCompletionsToParcelLocked(Parcel out)8020 void writeJobCompletionsToParcelLocked(Parcel out) { 8021 int NJC = mJobCompletions.size(); 8022 out.writeInt(NJC); 8023 for (int ijc=0; ijc<NJC; ijc++) { 8024 out.writeString(mJobCompletions.keyAt(ijc)); 8025 SparseIntArray types = mJobCompletions.valueAt(ijc); 8026 int NT = types.size(); 8027 out.writeInt(NT); 8028 for (int it=0; it<NT; it++) { 8029 out.writeInt(types.keyAt(it)); 8030 out.writeInt(types.valueAt(it)); 8031 } 8032 } 8033 } 8034 writeToParcelLocked(Parcel out, long uptimeUs, long elapsedRealtimeUs)8035 void writeToParcelLocked(Parcel out, long uptimeUs, long elapsedRealtimeUs) { 8036 mOnBatteryBackgroundTimeBase.writeToParcel(out, uptimeUs, elapsedRealtimeUs); 8037 mOnBatteryScreenOffBackgroundTimeBase.writeToParcel(out, uptimeUs, elapsedRealtimeUs); 8038 8039 final ArrayMap<String, Wakelock> wakeStats = mWakelockStats.getMap(); 8040 int NW = wakeStats.size(); 8041 out.writeInt(NW); 8042 for (int iw=0; iw<NW; iw++) { 8043 out.writeString(wakeStats.keyAt(iw)); 8044 Uid.Wakelock wakelock = wakeStats.valueAt(iw); 8045 wakelock.writeToParcelLocked(out, elapsedRealtimeUs); 8046 } 8047 8048 final ArrayMap<String, DualTimer> syncStats = mSyncStats.getMap(); 8049 int NS = syncStats.size(); 8050 out.writeInt(NS); 8051 for (int is=0; is<NS; is++) { 8052 out.writeString(syncStats.keyAt(is)); 8053 DualTimer timer = syncStats.valueAt(is); 8054 Timer.writeTimerToParcel(out, timer, elapsedRealtimeUs); 8055 } 8056 8057 final ArrayMap<String, DualTimer> jobStats = mJobStats.getMap(); 8058 int NJ = jobStats.size(); 8059 out.writeInt(NJ); 8060 for (int ij=0; ij<NJ; ij++) { 8061 out.writeString(jobStats.keyAt(ij)); 8062 DualTimer timer = jobStats.valueAt(ij); 8063 Timer.writeTimerToParcel(out, timer, elapsedRealtimeUs); 8064 } 8065 8066 writeJobCompletionsToParcelLocked(out); 8067 8068 mJobsDeferredEventCount.writeToParcel(out); 8069 mJobsDeferredCount.writeToParcel(out); 8070 mJobsFreshnessTimeMs.writeToParcel(out); 8071 for (int i = 0; i < JOB_FRESHNESS_BUCKETS.length; i++) { 8072 Counter.writeCounterToParcel(out, mJobsFreshnessBuckets[i]); 8073 } 8074 8075 int NSE = mSensorStats.size(); 8076 out.writeInt(NSE); 8077 for (int ise=0; ise<NSE; ise++) { 8078 out.writeInt(mSensorStats.keyAt(ise)); 8079 Uid.Sensor sensor = mSensorStats.valueAt(ise); 8080 sensor.writeToParcelLocked(out, elapsedRealtimeUs); 8081 } 8082 8083 int NP = mProcessStats.size(); 8084 out.writeInt(NP); 8085 for (int ip=0; ip<NP; ip++) { 8086 out.writeString(mProcessStats.keyAt(ip)); 8087 Uid.Proc proc = mProcessStats.valueAt(ip); 8088 proc.writeToParcelLocked(out); 8089 } 8090 8091 out.writeInt(mPackageStats.size()); 8092 for (Map.Entry<String, Uid.Pkg> pkgEntry : mPackageStats.entrySet()) { 8093 out.writeString(pkgEntry.getKey()); 8094 Uid.Pkg pkg = pkgEntry.getValue(); 8095 pkg.writeToParcelLocked(out); 8096 } 8097 8098 if (mWifiRunningTimer != null) { 8099 out.writeInt(1); 8100 mWifiRunningTimer.writeToParcel(out, elapsedRealtimeUs); 8101 } else { 8102 out.writeInt(0); 8103 } 8104 if (mFullWifiLockTimer != null) { 8105 out.writeInt(1); 8106 mFullWifiLockTimer.writeToParcel(out, elapsedRealtimeUs); 8107 } else { 8108 out.writeInt(0); 8109 } 8110 if (mWifiScanTimer != null) { 8111 out.writeInt(1); 8112 mWifiScanTimer.writeToParcel(out, elapsedRealtimeUs); 8113 } else { 8114 out.writeInt(0); 8115 } 8116 for (int i = 0; i < NUM_WIFI_BATCHED_SCAN_BINS; i++) { 8117 if (mWifiBatchedScanTimer[i] != null) { 8118 out.writeInt(1); 8119 mWifiBatchedScanTimer[i].writeToParcel(out, elapsedRealtimeUs); 8120 } else { 8121 out.writeInt(0); 8122 } 8123 } 8124 if (mWifiMulticastTimer != null) { 8125 out.writeInt(1); 8126 mWifiMulticastTimer.writeToParcel(out, elapsedRealtimeUs); 8127 } else { 8128 out.writeInt(0); 8129 } 8130 8131 if (mAudioTurnedOnTimer != null) { 8132 out.writeInt(1); 8133 mAudioTurnedOnTimer.writeToParcel(out, elapsedRealtimeUs); 8134 } else { 8135 out.writeInt(0); 8136 } 8137 if (mVideoTurnedOnTimer != null) { 8138 out.writeInt(1); 8139 mVideoTurnedOnTimer.writeToParcel(out, elapsedRealtimeUs); 8140 } else { 8141 out.writeInt(0); 8142 } 8143 if (mFlashlightTurnedOnTimer != null) { 8144 out.writeInt(1); 8145 mFlashlightTurnedOnTimer.writeToParcel(out, elapsedRealtimeUs); 8146 } else { 8147 out.writeInt(0); 8148 } 8149 if (mCameraTurnedOnTimer != null) { 8150 out.writeInt(1); 8151 mCameraTurnedOnTimer.writeToParcel(out, elapsedRealtimeUs); 8152 } else { 8153 out.writeInt(0); 8154 } 8155 if (mForegroundActivityTimer != null) { 8156 out.writeInt(1); 8157 mForegroundActivityTimer.writeToParcel(out, elapsedRealtimeUs); 8158 } else { 8159 out.writeInt(0); 8160 } 8161 if (mForegroundServiceTimer != null) { 8162 out.writeInt(1); 8163 mForegroundServiceTimer.writeToParcel(out, elapsedRealtimeUs); 8164 } else { 8165 out.writeInt(0); 8166 } 8167 if (mAggregatedPartialWakelockTimer != null) { 8168 out.writeInt(1); 8169 mAggregatedPartialWakelockTimer.writeToParcel(out, elapsedRealtimeUs); 8170 } else { 8171 out.writeInt(0); 8172 } 8173 if (mBluetoothScanTimer != null) { 8174 out.writeInt(1); 8175 mBluetoothScanTimer.writeToParcel(out, elapsedRealtimeUs); 8176 } else { 8177 out.writeInt(0); 8178 } 8179 if (mBluetoothUnoptimizedScanTimer != null) { 8180 out.writeInt(1); 8181 mBluetoothUnoptimizedScanTimer.writeToParcel(out, elapsedRealtimeUs); 8182 } else { 8183 out.writeInt(0); 8184 } 8185 if (mBluetoothScanResultCounter != null) { 8186 out.writeInt(1); 8187 mBluetoothScanResultCounter.writeToParcel(out); 8188 } else { 8189 out.writeInt(0); 8190 } 8191 if (mBluetoothScanResultBgCounter != null) { 8192 out.writeInt(1); 8193 mBluetoothScanResultBgCounter.writeToParcel(out); 8194 } else { 8195 out.writeInt(0); 8196 } 8197 for (int i = 0; i < NUM_PROCESS_STATE; i++) { 8198 if (mProcessStateTimer[i] != null) { 8199 out.writeInt(1); 8200 mProcessStateTimer[i].writeToParcel(out, elapsedRealtimeUs); 8201 } else { 8202 out.writeInt(0); 8203 } 8204 } 8205 if (mVibratorOnTimer != null) { 8206 out.writeInt(1); 8207 mVibratorOnTimer.writeToParcel(out, elapsedRealtimeUs); 8208 } else { 8209 out.writeInt(0); 8210 } 8211 if (mUserActivityCounters != null) { 8212 out.writeInt(1); 8213 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) { 8214 mUserActivityCounters[i].writeToParcel(out); 8215 } 8216 } else { 8217 out.writeInt(0); 8218 } 8219 if (mNetworkByteActivityCounters != null) { 8220 out.writeInt(1); 8221 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 8222 mNetworkByteActivityCounters[i].writeToParcel(out); 8223 mNetworkPacketActivityCounters[i].writeToParcel(out); 8224 } 8225 mMobileRadioActiveTime.writeToParcel(out); 8226 mMobileRadioActiveCount.writeToParcel(out); 8227 } else { 8228 out.writeInt(0); 8229 } 8230 8231 if (mWifiControllerActivity != null) { 8232 out.writeInt(1); 8233 mWifiControllerActivity.writeToParcel(out, 0); 8234 } else { 8235 out.writeInt(0); 8236 } 8237 8238 if (mBluetoothControllerActivity != null) { 8239 out.writeInt(1); 8240 mBluetoothControllerActivity.writeToParcel(out, 0); 8241 } else { 8242 out.writeInt(0); 8243 } 8244 8245 if (mModemControllerActivity != null) { 8246 out.writeInt(1); 8247 mModemControllerActivity.writeToParcel(out, 0); 8248 } else { 8249 out.writeInt(0); 8250 } 8251 8252 mUserCpuTime.writeToParcel(out); 8253 mSystemCpuTime.writeToParcel(out); 8254 8255 if (mCpuClusterSpeedTimesUs != null) { 8256 out.writeInt(1); 8257 out.writeInt(mCpuClusterSpeedTimesUs.length); 8258 for (LongSamplingCounter[] cpuSpeeds : mCpuClusterSpeedTimesUs) { 8259 if (cpuSpeeds != null) { 8260 out.writeInt(1); 8261 out.writeInt(cpuSpeeds.length); 8262 for (LongSamplingCounter c : cpuSpeeds) { 8263 if (c != null) { 8264 out.writeInt(1); 8265 c.writeToParcel(out); 8266 } else { 8267 out.writeInt(0); 8268 } 8269 } 8270 } else { 8271 out.writeInt(0); 8272 } 8273 } 8274 } else { 8275 out.writeInt(0); 8276 } 8277 8278 LongSamplingCounterArray.writeToParcel(out, mCpuFreqTimeMs); 8279 LongSamplingCounterArray.writeToParcel(out, mScreenOffCpuFreqTimeMs); 8280 8281 mCpuActiveTimeMs.writeToParcel(out); 8282 mCpuClusterTimesMs.writeToParcel(out); 8283 8284 if (mProcStateTimeMs != null) { 8285 out.writeInt(mProcStateTimeMs.length); 8286 for (LongSamplingCounterArray counters : mProcStateTimeMs) { 8287 LongSamplingCounterArray.writeToParcel(out, counters); 8288 } 8289 } else { 8290 out.writeInt(0); 8291 } 8292 if (mProcStateScreenOffTimeMs != null) { 8293 out.writeInt(mProcStateScreenOffTimeMs.length); 8294 for (LongSamplingCounterArray counters : mProcStateScreenOffTimeMs) { 8295 LongSamplingCounterArray.writeToParcel(out, counters); 8296 } 8297 } else { 8298 out.writeInt(0); 8299 } 8300 8301 if (mMobileRadioApWakeupCount != null) { 8302 out.writeInt(1); 8303 mMobileRadioApWakeupCount.writeToParcel(out); 8304 } else { 8305 out.writeInt(0); 8306 } 8307 8308 if (mWifiRadioApWakeupCount != null) { 8309 out.writeInt(1); 8310 mWifiRadioApWakeupCount.writeToParcel(out); 8311 } else { 8312 out.writeInt(0); 8313 } 8314 } 8315 readJobCompletionsFromParcelLocked(Parcel in)8316 void readJobCompletionsFromParcelLocked(Parcel in) { 8317 int numJobCompletions = in.readInt(); 8318 mJobCompletions.clear(); 8319 for (int j = 0; j < numJobCompletions; j++) { 8320 String jobName = in.readString(); 8321 int numTypes = in.readInt(); 8322 if (numTypes > 0) { 8323 SparseIntArray types = new SparseIntArray(); 8324 for (int k = 0; k < numTypes; k++) { 8325 int type = in.readInt(); 8326 int count = in.readInt(); 8327 types.put(type, count); 8328 } 8329 mJobCompletions.put(jobName, types); 8330 } 8331 } 8332 } 8333 readFromParcelLocked(TimeBase timeBase, TimeBase screenOffTimeBase, Parcel in)8334 void readFromParcelLocked(TimeBase timeBase, TimeBase screenOffTimeBase, Parcel in) { 8335 mOnBatteryBackgroundTimeBase.readFromParcel(in); 8336 mOnBatteryScreenOffBackgroundTimeBase.readFromParcel(in); 8337 8338 int numWakelocks = in.readInt(); 8339 mWakelockStats.clear(); 8340 for (int j = 0; j < numWakelocks; j++) { 8341 String wakelockName = in.readString(); 8342 Uid.Wakelock wakelock = new Wakelock(mBsi, this); 8343 wakelock.readFromParcelLocked( 8344 timeBase, screenOffTimeBase, mOnBatteryScreenOffBackgroundTimeBase, in); 8345 mWakelockStats.add(wakelockName, wakelock); 8346 } 8347 8348 int numSyncs = in.readInt(); 8349 mSyncStats.clear(); 8350 for (int j = 0; j < numSyncs; j++) { 8351 String syncName = in.readString(); 8352 if (in.readInt() != 0) { 8353 mSyncStats.add(syncName, new DualTimer(mBsi.mClocks, Uid.this, SYNC, null, 8354 mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase, in)); 8355 } 8356 } 8357 8358 int numJobs = in.readInt(); 8359 mJobStats.clear(); 8360 for (int j = 0; j < numJobs; j++) { 8361 String jobName = in.readString(); 8362 if (in.readInt() != 0) { 8363 mJobStats.add(jobName, new DualTimer(mBsi.mClocks, Uid.this, JOB, null, 8364 mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase, in)); 8365 } 8366 } 8367 8368 readJobCompletionsFromParcelLocked(in); 8369 8370 mJobsDeferredEventCount = new Counter(mBsi.mOnBatteryTimeBase, in); 8371 mJobsDeferredCount = new Counter(mBsi.mOnBatteryTimeBase, in); 8372 mJobsFreshnessTimeMs = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in); 8373 for (int i = 0; i < JOB_FRESHNESS_BUCKETS.length; i++) { 8374 mJobsFreshnessBuckets[i] = Counter.readCounterFromParcel(mBsi.mOnBatteryTimeBase, 8375 in); 8376 } 8377 8378 int numSensors = in.readInt(); 8379 mSensorStats.clear(); 8380 for (int k = 0; k < numSensors; k++) { 8381 int sensorNumber = in.readInt(); 8382 Uid.Sensor sensor = new Sensor(mBsi, this, sensorNumber); 8383 sensor.readFromParcelLocked(mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase, 8384 in); 8385 mSensorStats.put(sensorNumber, sensor); 8386 } 8387 8388 int numProcs = in.readInt(); 8389 mProcessStats.clear(); 8390 for (int k = 0; k < numProcs; k++) { 8391 String processName = in.readString(); 8392 Uid.Proc proc = new Proc(mBsi, processName); 8393 proc.readFromParcelLocked(in); 8394 mProcessStats.put(processName, proc); 8395 } 8396 8397 int numPkgs = in.readInt(); 8398 mPackageStats.clear(); 8399 for (int l = 0; l < numPkgs; l++) { 8400 String packageName = in.readString(); 8401 Uid.Pkg pkg = new Pkg(mBsi); 8402 pkg.readFromParcelLocked(in); 8403 mPackageStats.put(packageName, pkg); 8404 } 8405 8406 mWifiRunning = false; 8407 if (in.readInt() != 0) { 8408 mWifiRunningTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, WIFI_RUNNING, 8409 mBsi.mWifiRunningTimers, mBsi.mOnBatteryTimeBase, in); 8410 } else { 8411 mWifiRunningTimer = null; 8412 } 8413 mFullWifiLockOut = false; 8414 if (in.readInt() != 0) { 8415 mFullWifiLockTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, FULL_WIFI_LOCK, 8416 mBsi.mFullWifiLockTimers, mBsi.mOnBatteryTimeBase, in); 8417 } else { 8418 mFullWifiLockTimer = null; 8419 } 8420 mWifiScanStarted = false; 8421 if (in.readInt() != 0) { 8422 mWifiScanTimer = new DualTimer(mBsi.mClocks, Uid.this, WIFI_SCAN, 8423 mBsi.mWifiScanTimers, mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase, 8424 in); 8425 } else { 8426 mWifiScanTimer = null; 8427 } 8428 mWifiBatchedScanBinStarted = NO_BATCHED_SCAN_STARTED; 8429 for (int i = 0; i < NUM_WIFI_BATCHED_SCAN_BINS; i++) { 8430 if (in.readInt() != 0) { 8431 makeWifiBatchedScanBin(i, in); 8432 } else { 8433 mWifiBatchedScanTimer[i] = null; 8434 } 8435 } 8436 mWifiMulticastWakelockCount = 0; 8437 if (in.readInt() != 0) { 8438 mWifiMulticastTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, WIFI_MULTICAST_ENABLED, 8439 mBsi.mWifiMulticastTimers, mBsi.mOnBatteryTimeBase, in); 8440 } else { 8441 mWifiMulticastTimer = null; 8442 } 8443 if (in.readInt() != 0) { 8444 mAudioTurnedOnTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, AUDIO_TURNED_ON, 8445 mBsi.mAudioTurnedOnTimers, mBsi.mOnBatteryTimeBase, in); 8446 } else { 8447 mAudioTurnedOnTimer = null; 8448 } 8449 if (in.readInt() != 0) { 8450 mVideoTurnedOnTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, VIDEO_TURNED_ON, 8451 mBsi.mVideoTurnedOnTimers, mBsi.mOnBatteryTimeBase, in); 8452 } else { 8453 mVideoTurnedOnTimer = null; 8454 } 8455 if (in.readInt() != 0) { 8456 mFlashlightTurnedOnTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, 8457 FLASHLIGHT_TURNED_ON, mBsi.mFlashlightTurnedOnTimers, mBsi.mOnBatteryTimeBase, in); 8458 } else { 8459 mFlashlightTurnedOnTimer = null; 8460 } 8461 if (in.readInt() != 0) { 8462 mCameraTurnedOnTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, CAMERA_TURNED_ON, 8463 mBsi.mCameraTurnedOnTimers, mBsi.mOnBatteryTimeBase, in); 8464 } else { 8465 mCameraTurnedOnTimer = null; 8466 } 8467 if (in.readInt() != 0) { 8468 mForegroundActivityTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, 8469 FOREGROUND_ACTIVITY, null, mBsi.mOnBatteryTimeBase, in); 8470 } else { 8471 mForegroundActivityTimer = null; 8472 } 8473 if (in.readInt() != 0) { 8474 mForegroundServiceTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, 8475 FOREGROUND_SERVICE, null, mBsi.mOnBatteryTimeBase, in); 8476 } else { 8477 mForegroundServiceTimer = null; 8478 } 8479 if (in.readInt() != 0) { 8480 mAggregatedPartialWakelockTimer = new DualTimer(mBsi.mClocks, this, 8481 AGGREGATED_WAKE_TYPE_PARTIAL, null, 8482 mBsi.mOnBatteryScreenOffTimeBase, mOnBatteryScreenOffBackgroundTimeBase, 8483 in); 8484 } else { 8485 mAggregatedPartialWakelockTimer = null; 8486 } 8487 if (in.readInt() != 0) { 8488 mBluetoothScanTimer = new DualTimer(mBsi.mClocks, Uid.this, BLUETOOTH_SCAN_ON, 8489 mBsi.mBluetoothScanOnTimers, mBsi.mOnBatteryTimeBase, 8490 mOnBatteryBackgroundTimeBase, in); 8491 } else { 8492 mBluetoothScanTimer = null; 8493 } 8494 if (in.readInt() != 0) { 8495 mBluetoothUnoptimizedScanTimer = new DualTimer(mBsi.mClocks, Uid.this, 8496 BLUETOOTH_UNOPTIMIZED_SCAN_ON, null, 8497 mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase, in); 8498 } else { 8499 mBluetoothUnoptimizedScanTimer = null; 8500 } 8501 if (in.readInt() != 0) { 8502 mBluetoothScanResultCounter = new Counter(mBsi.mOnBatteryTimeBase, in); 8503 } else { 8504 mBluetoothScanResultCounter = null; 8505 } 8506 if (in.readInt() != 0) { 8507 mBluetoothScanResultBgCounter = new Counter(mOnBatteryBackgroundTimeBase, in); 8508 } else { 8509 mBluetoothScanResultBgCounter = null; 8510 } 8511 mProcessState = ActivityManager.PROCESS_STATE_NONEXISTENT; 8512 for (int i = 0; i < NUM_PROCESS_STATE; i++) { 8513 if (in.readInt() != 0) { 8514 makeProcessState(i, in); 8515 } else { 8516 mProcessStateTimer[i] = null; 8517 } 8518 } 8519 if (in.readInt() != 0) { 8520 mVibratorOnTimer = new BatchTimer(mBsi.mClocks, Uid.this, VIBRATOR_ON, 8521 mBsi.mOnBatteryTimeBase, in); 8522 } else { 8523 mVibratorOnTimer = null; 8524 } 8525 if (in.readInt() != 0) { 8526 mUserActivityCounters = new Counter[NUM_USER_ACTIVITY_TYPES]; 8527 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) { 8528 mUserActivityCounters[i] = new Counter(mBsi.mOnBatteryTimeBase, in); 8529 } 8530 } else { 8531 mUserActivityCounters = null; 8532 } 8533 if (in.readInt() != 0) { 8534 mNetworkByteActivityCounters = new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES]; 8535 mNetworkPacketActivityCounters 8536 = new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES]; 8537 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 8538 mNetworkByteActivityCounters[i] 8539 = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in); 8540 mNetworkPacketActivityCounters[i] 8541 = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in); 8542 } 8543 mMobileRadioActiveTime = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in); 8544 mMobileRadioActiveCount = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in); 8545 } else { 8546 mNetworkByteActivityCounters = null; 8547 mNetworkPacketActivityCounters = null; 8548 } 8549 8550 if (in.readInt() != 0) { 8551 mWifiControllerActivity = new ControllerActivityCounterImpl(mBsi.mOnBatteryTimeBase, 8552 NUM_WIFI_TX_LEVELS, in); 8553 } else { 8554 mWifiControllerActivity = null; 8555 } 8556 8557 if (in.readInt() != 0) { 8558 mBluetoothControllerActivity = new ControllerActivityCounterImpl(mBsi.mOnBatteryTimeBase, 8559 NUM_BT_TX_LEVELS, in); 8560 } else { 8561 mBluetoothControllerActivity = null; 8562 } 8563 8564 if (in.readInt() != 0) { 8565 mModemControllerActivity = new ControllerActivityCounterImpl(mBsi.mOnBatteryTimeBase, 8566 ModemActivityInfo.TX_POWER_LEVELS, in); 8567 } else { 8568 mModemControllerActivity = null; 8569 } 8570 8571 mUserCpuTime = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in); 8572 mSystemCpuTime = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in); 8573 8574 if (in.readInt() != 0) { 8575 int numCpuClusters = in.readInt(); 8576 if (mBsi.mPowerProfile != null && mBsi.mPowerProfile.getNumCpuClusters() != numCpuClusters) { 8577 throw new ParcelFormatException("Incompatible number of cpu clusters"); 8578 } 8579 8580 mCpuClusterSpeedTimesUs = new LongSamplingCounter[numCpuClusters][]; 8581 for (int cluster = 0; cluster < numCpuClusters; cluster++) { 8582 if (in.readInt() != 0) { 8583 int numSpeeds = in.readInt(); 8584 if (mBsi.mPowerProfile != null && 8585 mBsi.mPowerProfile.getNumSpeedStepsInCpuCluster(cluster) != numSpeeds) { 8586 throw new ParcelFormatException("Incompatible number of cpu speeds"); 8587 } 8588 8589 final LongSamplingCounter[] cpuSpeeds = new LongSamplingCounter[numSpeeds]; 8590 mCpuClusterSpeedTimesUs[cluster] = cpuSpeeds; 8591 for (int speed = 0; speed < numSpeeds; speed++) { 8592 if (in.readInt() != 0) { 8593 cpuSpeeds[speed] = new LongSamplingCounter( 8594 mBsi.mOnBatteryTimeBase, in); 8595 } 8596 } 8597 } else { 8598 mCpuClusterSpeedTimesUs[cluster] = null; 8599 } 8600 } 8601 } else { 8602 mCpuClusterSpeedTimesUs = null; 8603 } 8604 8605 mCpuFreqTimeMs = LongSamplingCounterArray.readFromParcel(in, mBsi.mOnBatteryTimeBase); 8606 mScreenOffCpuFreqTimeMs = LongSamplingCounterArray.readFromParcel( 8607 in, mBsi.mOnBatteryScreenOffTimeBase); 8608 8609 mCpuActiveTimeMs = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in); 8610 mCpuClusterTimesMs = new LongSamplingCounterArray(mBsi.mOnBatteryTimeBase, in); 8611 8612 int length = in.readInt(); 8613 if (length == NUM_PROCESS_STATE) { 8614 mProcStateTimeMs = new LongSamplingCounterArray[length]; 8615 for (int procState = 0; procState < length; ++procState) { 8616 mProcStateTimeMs[procState] = LongSamplingCounterArray.readFromParcel( 8617 in, mBsi.mOnBatteryTimeBase); 8618 } 8619 } else { 8620 mProcStateTimeMs = null; 8621 } 8622 length = in.readInt(); 8623 if (length == NUM_PROCESS_STATE) { 8624 mProcStateScreenOffTimeMs = new LongSamplingCounterArray[length]; 8625 for (int procState = 0; procState < length; ++procState) { 8626 mProcStateScreenOffTimeMs[procState] = LongSamplingCounterArray.readFromParcel( 8627 in, mBsi.mOnBatteryScreenOffTimeBase); 8628 } 8629 } else { 8630 mProcStateScreenOffTimeMs = null; 8631 } 8632 8633 if (in.readInt() != 0) { 8634 mMobileRadioApWakeupCount = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in); 8635 } else { 8636 mMobileRadioApWakeupCount = null; 8637 } 8638 8639 if (in.readInt() != 0) { 8640 mWifiRadioApWakeupCount = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in); 8641 } else { 8642 mWifiRadioApWakeupCount = null; 8643 } 8644 } 8645 noteJobsDeferredLocked(int numDeferred, long sinceLast)8646 public void noteJobsDeferredLocked(int numDeferred, long sinceLast) { 8647 mJobsDeferredEventCount.addAtomic(1); 8648 mJobsDeferredCount.addAtomic(numDeferred); 8649 if (sinceLast != 0) { 8650 // Add the total time, which can be divided by the event count to get an average 8651 mJobsFreshnessTimeMs.addCountLocked(sinceLast); 8652 // Also keep track of how many times there were in these different buckets. 8653 for (int i = 0; i < JOB_FRESHNESS_BUCKETS.length; i++) { 8654 if (sinceLast < JOB_FRESHNESS_BUCKETS[i]) { 8655 if (mJobsFreshnessBuckets[i] == null) { 8656 mJobsFreshnessBuckets[i] = new Counter( 8657 mBsi.mOnBatteryTimeBase); 8658 } 8659 mJobsFreshnessBuckets[i].addAtomic(1); 8660 break; 8661 } 8662 } 8663 } 8664 } 8665 8666 /** 8667 * The statistics associated with a particular wake lock. 8668 */ 8669 public static class Wakelock extends BatteryStats.Uid.Wakelock { 8670 /** 8671 * BatteryStatsImpl that we are associated with. 8672 */ 8673 protected BatteryStatsImpl mBsi; 8674 8675 /** 8676 * BatteryStatsImpl that we are associated with. 8677 */ 8678 protected Uid mUid; 8679 8680 /** 8681 * How long (in ms) this uid has been keeping the device partially awake. 8682 * Tracks both the total time and the time while the app was in the background. 8683 */ 8684 DualTimer mTimerPartial; 8685 8686 /** 8687 * How long (in ms) this uid has been keeping the device fully awake. 8688 */ 8689 StopwatchTimer mTimerFull; 8690 8691 /** 8692 * How long (in ms) this uid has had a window keeping the device awake. 8693 */ 8694 StopwatchTimer mTimerWindow; 8695 8696 /** 8697 * How long (in ms) this uid has had a draw wake lock. 8698 */ 8699 StopwatchTimer mTimerDraw; 8700 Wakelock(BatteryStatsImpl bsi, Uid uid)8701 public Wakelock(BatteryStatsImpl bsi, Uid uid) { 8702 mBsi = bsi; 8703 mUid = uid; 8704 } 8705 8706 /** 8707 * Reads a possibly null Timer from a Parcel. The timer is associated with the 8708 * proper timer pool from the given BatteryStatsImpl object. 8709 * 8710 * @param in the Parcel to be read from. 8711 * return a new Timer, or null. 8712 */ readStopwatchTimerFromParcel(int type, ArrayList<StopwatchTimer> pool, TimeBase timeBase, Parcel in)8713 private StopwatchTimer readStopwatchTimerFromParcel(int type, 8714 ArrayList<StopwatchTimer> pool, TimeBase timeBase, Parcel in) { 8715 if (in.readInt() == 0) { 8716 return null; 8717 } 8718 8719 return new StopwatchTimer(mBsi.mClocks, mUid, type, pool, timeBase, in); 8720 } 8721 8722 /** 8723 * Reads a possibly null Timer from a Parcel. The timer is associated with the 8724 * proper timer pool from the given BatteryStatsImpl object. 8725 * 8726 * @param in the Parcel to be read from. 8727 * return a new Timer, or null. 8728 */ readDualTimerFromParcel(int type, ArrayList<StopwatchTimer> pool, TimeBase timeBase, TimeBase bgTimeBase, Parcel in)8729 private DualTimer readDualTimerFromParcel(int type, ArrayList<StopwatchTimer> pool, 8730 TimeBase timeBase, TimeBase bgTimeBase, Parcel in) { 8731 if (in.readInt() == 0) { 8732 return null; 8733 } 8734 8735 return new DualTimer(mBsi.mClocks, mUid, type, pool, timeBase, bgTimeBase, in); 8736 } 8737 reset()8738 boolean reset() { 8739 boolean wlactive = false; 8740 8741 wlactive |= !resetIfNotNull(mTimerFull,false); 8742 wlactive |= !resetIfNotNull(mTimerPartial,false); 8743 wlactive |= !resetIfNotNull(mTimerWindow,false); 8744 wlactive |= !resetIfNotNull(mTimerDraw,false); 8745 8746 if (!wlactive) { 8747 detachIfNotNull(mTimerFull); 8748 mTimerFull = null; 8749 8750 detachIfNotNull(mTimerPartial); 8751 mTimerPartial = null; 8752 8753 detachIfNotNull(mTimerWindow); 8754 mTimerWindow = null; 8755 8756 detachIfNotNull(mTimerDraw); 8757 mTimerDraw = null; 8758 } 8759 return !wlactive; 8760 } 8761 readFromParcelLocked(TimeBase timeBase, TimeBase screenOffTimeBase, TimeBase screenOffBgTimeBase, Parcel in)8762 void readFromParcelLocked(TimeBase timeBase, TimeBase screenOffTimeBase, 8763 TimeBase screenOffBgTimeBase, Parcel in) { 8764 mTimerPartial = readDualTimerFromParcel(WAKE_TYPE_PARTIAL, 8765 mBsi.mPartialTimers, screenOffTimeBase, screenOffBgTimeBase, in); 8766 mTimerFull = readStopwatchTimerFromParcel(WAKE_TYPE_FULL, 8767 mBsi.mFullTimers, timeBase, in); 8768 mTimerWindow = readStopwatchTimerFromParcel(WAKE_TYPE_WINDOW, 8769 mBsi.mWindowTimers, timeBase, in); 8770 mTimerDraw = readStopwatchTimerFromParcel(WAKE_TYPE_DRAW, 8771 mBsi.mDrawTimers, timeBase, in); 8772 } 8773 writeToParcelLocked(Parcel out, long elapsedRealtimeUs)8774 void writeToParcelLocked(Parcel out, long elapsedRealtimeUs) { 8775 Timer.writeTimerToParcel(out, mTimerPartial, elapsedRealtimeUs); 8776 Timer.writeTimerToParcel(out, mTimerFull, elapsedRealtimeUs); 8777 Timer.writeTimerToParcel(out, mTimerWindow, elapsedRealtimeUs); 8778 Timer.writeTimerToParcel(out, mTimerDraw, elapsedRealtimeUs); 8779 } 8780 8781 @Override 8782 @UnsupportedAppUsage getWakeTime(int type)8783 public Timer getWakeTime(int type) { 8784 switch (type) { 8785 case WAKE_TYPE_FULL: return mTimerFull; 8786 case WAKE_TYPE_PARTIAL: return mTimerPartial; 8787 case WAKE_TYPE_WINDOW: return mTimerWindow; 8788 case WAKE_TYPE_DRAW: return mTimerDraw; 8789 default: throw new IllegalArgumentException("type = " + type); 8790 } 8791 } 8792 detachFromTimeBase()8793 public void detachFromTimeBase() { 8794 detachIfNotNull(mTimerPartial); 8795 detachIfNotNull(mTimerFull); 8796 detachIfNotNull(mTimerWindow); 8797 detachIfNotNull(mTimerDraw); 8798 } 8799 } 8800 8801 public static class Sensor extends BatteryStats.Uid.Sensor { 8802 /** 8803 * BatteryStatsImpl that we are associated with. 8804 */ 8805 protected BatteryStatsImpl mBsi; 8806 8807 /** 8808 * Uid that we are associated with. 8809 */ 8810 protected Uid mUid; 8811 8812 final int mHandle; 8813 DualTimer mTimer; 8814 Sensor(BatteryStatsImpl bsi, Uid uid, int handle)8815 public Sensor(BatteryStatsImpl bsi, Uid uid, int handle) { 8816 mBsi = bsi; 8817 mUid = uid; 8818 mHandle = handle; 8819 } 8820 readTimersFromParcel( TimeBase timeBase, TimeBase bgTimeBase, Parcel in)8821 private DualTimer readTimersFromParcel( 8822 TimeBase timeBase, TimeBase bgTimeBase, Parcel in) { 8823 if (in.readInt() == 0) { 8824 return null; 8825 } 8826 8827 ArrayList<StopwatchTimer> pool = mBsi.mSensorTimers.get(mHandle); 8828 if (pool == null) { 8829 pool = new ArrayList<StopwatchTimer>(); 8830 mBsi.mSensorTimers.put(mHandle, pool); 8831 } 8832 return new DualTimer(mBsi.mClocks, mUid, 0, pool, timeBase, bgTimeBase, in); 8833 } 8834 reset()8835 boolean reset() { 8836 if (mTimer.reset(true)) { 8837 mTimer = null; 8838 return true; 8839 } 8840 return false; 8841 } 8842 readFromParcelLocked(TimeBase timeBase, TimeBase bgTimeBase, Parcel in)8843 void readFromParcelLocked(TimeBase timeBase, TimeBase bgTimeBase, Parcel in) { 8844 mTimer = readTimersFromParcel(timeBase, bgTimeBase, in); 8845 } 8846 writeToParcelLocked(Parcel out, long elapsedRealtimeUs)8847 void writeToParcelLocked(Parcel out, long elapsedRealtimeUs) { 8848 Timer.writeTimerToParcel(out, mTimer, elapsedRealtimeUs); 8849 } 8850 8851 @Override 8852 @UnsupportedAppUsage getSensorTime()8853 public Timer getSensorTime() { 8854 return mTimer; 8855 } 8856 8857 @Override getSensorBackgroundTime()8858 public Timer getSensorBackgroundTime() { 8859 if (mTimer == null) { 8860 return null; 8861 } 8862 return mTimer.getSubTimer(); 8863 } 8864 8865 @Override 8866 @UnsupportedAppUsage getHandle()8867 public int getHandle() { 8868 return mHandle; 8869 } 8870 detachFromTimeBase()8871 public void detachFromTimeBase() { 8872 detachIfNotNull(mTimer); 8873 } 8874 } 8875 8876 /** 8877 * The statistics associated with a particular process. 8878 */ 8879 public static class Proc extends BatteryStats.Uid.Proc implements TimeBaseObs { 8880 /** 8881 * BatteryStatsImpl that we are associated with. 8882 */ 8883 protected BatteryStatsImpl mBsi; 8884 8885 /** 8886 * The name of this process. 8887 */ 8888 final String mName; 8889 8890 /** 8891 * Remains true until removed from the stats. 8892 */ 8893 boolean mActive = true; 8894 8895 /** 8896 * Total time (in ms) spent executing in user code. 8897 */ 8898 long mUserTime; 8899 8900 /** 8901 * Total time (in ms) spent executing in kernel code. 8902 */ 8903 long mSystemTime; 8904 8905 /** 8906 * Amount of time (in ms) the process was running in the foreground. 8907 */ 8908 long mForegroundTime; 8909 8910 /** 8911 * Number of times the process has been started. 8912 */ 8913 int mStarts; 8914 8915 /** 8916 * Number of times the process has crashed. 8917 */ 8918 int mNumCrashes; 8919 8920 /** 8921 * Number of times the process has had an ANR. 8922 */ 8923 int mNumAnrs; 8924 8925 ArrayList<ExcessivePower> mExcessivePower; 8926 Proc(BatteryStatsImpl bsi, String name)8927 public Proc(BatteryStatsImpl bsi, String name) { 8928 mBsi = bsi; 8929 mName = name; 8930 mBsi.mOnBatteryTimeBase.add(this); 8931 } 8932 onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime)8933 public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) { 8934 } 8935 onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime)8936 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) { 8937 } 8938 8939 @Override reset(boolean detachIfReset)8940 public boolean reset(boolean detachIfReset) { 8941 if (detachIfReset) { 8942 this.detach(); 8943 } 8944 return true; 8945 } 8946 8947 @Override detach()8948 public void detach() { 8949 mActive = false; 8950 mBsi.mOnBatteryTimeBase.remove(this); 8951 } 8952 countExcessivePowers()8953 public int countExcessivePowers() { 8954 return mExcessivePower != null ? mExcessivePower.size() : 0; 8955 } 8956 getExcessivePower(int i)8957 public ExcessivePower getExcessivePower(int i) { 8958 if (mExcessivePower != null) { 8959 return mExcessivePower.get(i); 8960 } 8961 return null; 8962 } 8963 addExcessiveCpu(long overTime, long usedTime)8964 public void addExcessiveCpu(long overTime, long usedTime) { 8965 if (mExcessivePower == null) { 8966 mExcessivePower = new ArrayList<ExcessivePower>(); 8967 } 8968 ExcessivePower ew = new ExcessivePower(); 8969 ew.type = ExcessivePower.TYPE_CPU; 8970 ew.overTime = overTime; 8971 ew.usedTime = usedTime; 8972 mExcessivePower.add(ew); 8973 } 8974 writeExcessivePowerToParcelLocked(Parcel out)8975 void writeExcessivePowerToParcelLocked(Parcel out) { 8976 if (mExcessivePower == null) { 8977 out.writeInt(0); 8978 return; 8979 } 8980 8981 final int N = mExcessivePower.size(); 8982 out.writeInt(N); 8983 for (int i=0; i<N; i++) { 8984 ExcessivePower ew = mExcessivePower.get(i); 8985 out.writeInt(ew.type); 8986 out.writeLong(ew.overTime); 8987 out.writeLong(ew.usedTime); 8988 } 8989 } 8990 readExcessivePowerFromParcelLocked(Parcel in)8991 void readExcessivePowerFromParcelLocked(Parcel in) { 8992 final int N = in.readInt(); 8993 if (N == 0) { 8994 mExcessivePower = null; 8995 return; 8996 } 8997 8998 if (N > 10000) { 8999 throw new ParcelFormatException( 9000 "File corrupt: too many excessive power entries " + N); 9001 } 9002 9003 mExcessivePower = new ArrayList<>(); 9004 for (int i=0; i<N; i++) { 9005 ExcessivePower ew = new ExcessivePower(); 9006 ew.type = in.readInt(); 9007 ew.overTime = in.readLong(); 9008 ew.usedTime = in.readLong(); 9009 mExcessivePower.add(ew); 9010 } 9011 } 9012 writeToParcelLocked(Parcel out)9013 void writeToParcelLocked(Parcel out) { 9014 out.writeLong(mUserTime); 9015 out.writeLong(mSystemTime); 9016 out.writeLong(mForegroundTime); 9017 out.writeInt(mStarts); 9018 out.writeInt(mNumCrashes); 9019 out.writeInt(mNumAnrs); 9020 writeExcessivePowerToParcelLocked(out); 9021 } 9022 readFromParcelLocked(Parcel in)9023 void readFromParcelLocked(Parcel in) { 9024 mUserTime = in.readLong(); 9025 mSystemTime = in.readLong(); 9026 mForegroundTime = in.readLong(); 9027 mStarts = in.readInt(); 9028 mNumCrashes = in.readInt(); 9029 mNumAnrs = in.readInt(); 9030 readExcessivePowerFromParcelLocked(in); 9031 } 9032 9033 @UnsupportedAppUsage addCpuTimeLocked(int utime, int stime)9034 public void addCpuTimeLocked(int utime, int stime) { 9035 addCpuTimeLocked(utime, stime, mBsi.mOnBatteryTimeBase.isRunning()); 9036 } 9037 addCpuTimeLocked(int utime, int stime, boolean isRunning)9038 public void addCpuTimeLocked(int utime, int stime, boolean isRunning) { 9039 if (isRunning) { 9040 mUserTime += utime; 9041 mSystemTime += stime; 9042 } 9043 } 9044 9045 @UnsupportedAppUsage addForegroundTimeLocked(long ttime)9046 public void addForegroundTimeLocked(long ttime) { 9047 mForegroundTime += ttime; 9048 } 9049 9050 @UnsupportedAppUsage incStartsLocked()9051 public void incStartsLocked() { 9052 mStarts++; 9053 } 9054 incNumCrashesLocked()9055 public void incNumCrashesLocked() { 9056 mNumCrashes++; 9057 } 9058 incNumAnrsLocked()9059 public void incNumAnrsLocked() { 9060 mNumAnrs++; 9061 } 9062 9063 @Override isActive()9064 public boolean isActive() { 9065 return mActive; 9066 } 9067 9068 @Override 9069 @UnsupportedAppUsage getUserTime(int which)9070 public long getUserTime(int which) { 9071 return mUserTime; 9072 } 9073 9074 @Override 9075 @UnsupportedAppUsage getSystemTime(int which)9076 public long getSystemTime(int which) { 9077 return mSystemTime; 9078 } 9079 9080 @Override 9081 @UnsupportedAppUsage getForegroundTime(int which)9082 public long getForegroundTime(int which) { 9083 return mForegroundTime; 9084 } 9085 9086 @Override 9087 @UnsupportedAppUsage getStarts(int which)9088 public int getStarts(int which) { 9089 return mStarts; 9090 } 9091 9092 @Override getNumCrashes(int which)9093 public int getNumCrashes(int which) { 9094 return mNumCrashes; 9095 } 9096 9097 @Override getNumAnrs(int which)9098 public int getNumAnrs(int which) { 9099 return mNumAnrs; 9100 } 9101 } 9102 9103 /** 9104 * The statistics associated with a particular package. 9105 */ 9106 public static class Pkg extends BatteryStats.Uid.Pkg implements TimeBaseObs { 9107 /** 9108 * BatteryStatsImpl that we are associated with. 9109 */ 9110 protected BatteryStatsImpl mBsi; 9111 9112 /** 9113 * Number of times wakeup alarms have occurred for this app. 9114 * On screen-off timebase starting in report v25. 9115 */ 9116 ArrayMap<String, Counter> mWakeupAlarms = new ArrayMap<>(); 9117 9118 /** 9119 * The statics we have collected for this package's services. 9120 */ 9121 final ArrayMap<String, Serv> mServiceStats = new ArrayMap<>(); 9122 Pkg(BatteryStatsImpl bsi)9123 public Pkg(BatteryStatsImpl bsi) { 9124 mBsi = bsi; 9125 mBsi.mOnBatteryScreenOffTimeBase.add(this); 9126 } 9127 onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime)9128 public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) { 9129 } 9130 onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime)9131 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) { 9132 } 9133 9134 @Override reset(boolean detachIfReset)9135 public boolean reset(boolean detachIfReset) { 9136 if (detachIfReset) { 9137 this.detach(); 9138 } 9139 return true; 9140 } 9141 9142 @Override detach()9143 public void detach() { 9144 mBsi.mOnBatteryScreenOffTimeBase.remove(this); 9145 for (int j = mWakeupAlarms.size() - 1; j >= 0; j--) { 9146 detachIfNotNull(mWakeupAlarms.valueAt(j)); 9147 } 9148 for (int j = mServiceStats.size() - 1; j >= 0; j--) { 9149 detachIfNotNull(mServiceStats.valueAt(j)); 9150 } 9151 } 9152 readFromParcelLocked(Parcel in)9153 void readFromParcelLocked(Parcel in) { 9154 int numWA = in.readInt(); 9155 mWakeupAlarms.clear(); 9156 for (int i=0; i<numWA; i++) { 9157 String tag = in.readString(); 9158 mWakeupAlarms.put(tag, new Counter(mBsi.mOnBatteryScreenOffTimeBase, in)); 9159 } 9160 9161 int numServs = in.readInt(); 9162 mServiceStats.clear(); 9163 for (int m = 0; m < numServs; m++) { 9164 String serviceName = in.readString(); 9165 Uid.Pkg.Serv serv = new Serv(mBsi); 9166 mServiceStats.put(serviceName, serv); 9167 9168 serv.readFromParcelLocked(in); 9169 } 9170 } 9171 writeToParcelLocked(Parcel out)9172 void writeToParcelLocked(Parcel out) { 9173 int numWA = mWakeupAlarms.size(); 9174 out.writeInt(numWA); 9175 for (int i=0; i<numWA; i++) { 9176 out.writeString(mWakeupAlarms.keyAt(i)); 9177 mWakeupAlarms.valueAt(i).writeToParcel(out); 9178 } 9179 9180 final int NS = mServiceStats.size(); 9181 out.writeInt(NS); 9182 for (int i=0; i<NS; i++) { 9183 out.writeString(mServiceStats.keyAt(i)); 9184 Uid.Pkg.Serv serv = mServiceStats.valueAt(i); 9185 serv.writeToParcelLocked(out); 9186 } 9187 } 9188 9189 @Override getWakeupAlarmStats()9190 public ArrayMap<String, ? extends BatteryStats.Counter> getWakeupAlarmStats() { 9191 return mWakeupAlarms; 9192 } 9193 noteWakeupAlarmLocked(String tag)9194 public void noteWakeupAlarmLocked(String tag) { 9195 Counter c = mWakeupAlarms.get(tag); 9196 if (c == null) { 9197 c = new Counter(mBsi.mOnBatteryScreenOffTimeBase); 9198 mWakeupAlarms.put(tag, c); 9199 } 9200 c.stepAtomic(); 9201 } 9202 9203 @Override getServiceStats()9204 public ArrayMap<String, ? extends BatteryStats.Uid.Pkg.Serv> getServiceStats() { 9205 return mServiceStats; 9206 } 9207 9208 /** 9209 * The statistics associated with a particular service. 9210 */ 9211 public static class Serv extends BatteryStats.Uid.Pkg.Serv implements TimeBaseObs { 9212 /** 9213 * BatteryStatsImpl that we are associated with. 9214 */ 9215 protected BatteryStatsImpl mBsi; 9216 9217 /** 9218 * The android package in which this service resides. 9219 */ 9220 protected Pkg mPkg; 9221 9222 /** 9223 * Total time (ms in battery uptime) the service has been left started. 9224 */ 9225 protected long mStartTime; 9226 9227 /** 9228 * If service has been started and not yet stopped, this is 9229 * when it was started. 9230 */ 9231 protected long mRunningSince; 9232 9233 /** 9234 * True if we are currently running. 9235 */ 9236 protected boolean mRunning; 9237 9238 /** 9239 * Total number of times startService() has been called. 9240 */ 9241 protected int mStarts; 9242 9243 /** 9244 * Total time (ms in battery uptime) the service has been left launched. 9245 */ 9246 protected long mLaunchedTime; 9247 9248 /** 9249 * If service has been launched and not yet exited, this is 9250 * when it was launched (ms in battery uptime). 9251 */ 9252 protected long mLaunchedSince; 9253 9254 /** 9255 * True if we are currently launched. 9256 */ 9257 protected boolean mLaunched; 9258 9259 /** 9260 * Total number times the service has been launched. 9261 */ 9262 protected int mLaunches; 9263 9264 /** 9265 * Construct a Serv. Also adds it to the on-battery time base as a listener. 9266 */ Serv(BatteryStatsImpl bsi)9267 public Serv(BatteryStatsImpl bsi) { 9268 mBsi = bsi; 9269 mBsi.mOnBatteryTimeBase.add(this); 9270 } 9271 onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime)9272 public void onTimeStarted(long elapsedRealtime, long baseUptime, 9273 long baseRealtime) { 9274 } 9275 onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime)9276 public void onTimeStopped(long elapsedRealtime, long baseUptime, 9277 long baseRealtime) { 9278 } 9279 9280 @Override reset(boolean detachIfReset)9281 public boolean reset(boolean detachIfReset) { 9282 if (detachIfReset) { 9283 this.detach(); 9284 } 9285 return true; 9286 } 9287 9288 /** 9289 * Remove this Serv as a listener from the time base. 9290 */ 9291 @Override detach()9292 public void detach() { 9293 mBsi.mOnBatteryTimeBase.remove(this); 9294 } 9295 readFromParcelLocked(Parcel in)9296 public void readFromParcelLocked(Parcel in) { 9297 mStartTime = in.readLong(); 9298 mRunningSince = in.readLong(); 9299 mRunning = in.readInt() != 0; 9300 mStarts = in.readInt(); 9301 mLaunchedTime = in.readLong(); 9302 mLaunchedSince = in.readLong(); 9303 mLaunched = in.readInt() != 0; 9304 mLaunches = in.readInt(); 9305 } 9306 writeToParcelLocked(Parcel out)9307 public void writeToParcelLocked(Parcel out) { 9308 out.writeLong(mStartTime); 9309 out.writeLong(mRunningSince); 9310 out.writeInt(mRunning ? 1 : 0); 9311 out.writeInt(mStarts); 9312 out.writeLong(mLaunchedTime); 9313 out.writeLong(mLaunchedSince); 9314 out.writeInt(mLaunched ? 1 : 0); 9315 out.writeInt(mLaunches); 9316 } 9317 getLaunchTimeToNowLocked(long batteryUptime)9318 public long getLaunchTimeToNowLocked(long batteryUptime) { 9319 if (!mLaunched) return mLaunchedTime; 9320 return mLaunchedTime + batteryUptime - mLaunchedSince; 9321 } 9322 getStartTimeToNowLocked(long batteryUptime)9323 public long getStartTimeToNowLocked(long batteryUptime) { 9324 if (!mRunning) return mStartTime; 9325 return mStartTime + batteryUptime - mRunningSince; 9326 } 9327 9328 @UnsupportedAppUsage startLaunchedLocked()9329 public void startLaunchedLocked() { 9330 if (!mLaunched) { 9331 mLaunches++; 9332 mLaunchedSince = mBsi.getBatteryUptimeLocked(); 9333 mLaunched = true; 9334 } 9335 } 9336 9337 @UnsupportedAppUsage stopLaunchedLocked()9338 public void stopLaunchedLocked() { 9339 if (mLaunched) { 9340 long time = mBsi.getBatteryUptimeLocked() - mLaunchedSince; 9341 if (time > 0) { 9342 mLaunchedTime += time; 9343 } else { 9344 mLaunches--; 9345 } 9346 mLaunched = false; 9347 } 9348 } 9349 9350 @UnsupportedAppUsage startRunningLocked()9351 public void startRunningLocked() { 9352 if (!mRunning) { 9353 mStarts++; 9354 mRunningSince = mBsi.getBatteryUptimeLocked(); 9355 mRunning = true; 9356 } 9357 } 9358 9359 @UnsupportedAppUsage stopRunningLocked()9360 public void stopRunningLocked() { 9361 if (mRunning) { 9362 long time = mBsi.getBatteryUptimeLocked() - mRunningSince; 9363 if (time > 0) { 9364 mStartTime += time; 9365 } else { 9366 mStarts--; 9367 } 9368 mRunning = false; 9369 } 9370 } 9371 9372 @UnsupportedAppUsage getBatteryStats()9373 public BatteryStatsImpl getBatteryStats() { 9374 return mBsi; 9375 } 9376 9377 @Override getLaunches(int which)9378 public int getLaunches(int which) { 9379 return mLaunches; 9380 } 9381 9382 @Override getStartTime(long now, int which)9383 public long getStartTime(long now, int which) { 9384 return getStartTimeToNowLocked(now); 9385 } 9386 9387 @Override getStarts(int which)9388 public int getStarts(int which) { 9389 return mStarts; 9390 } 9391 } 9392 newServiceStatsLocked()9393 final Serv newServiceStatsLocked() { 9394 return new Serv(mBsi); 9395 } 9396 } 9397 9398 /** 9399 * Retrieve the statistics object for a particular process, creating 9400 * if needed. 9401 */ getProcessStatsLocked(String name)9402 public Proc getProcessStatsLocked(String name) { 9403 Proc ps = mProcessStats.get(name); 9404 if (ps == null) { 9405 ps = new Proc(mBsi, name); 9406 mProcessStats.put(name, ps); 9407 } 9408 9409 return ps; 9410 } 9411 9412 @GuardedBy("mBsi") updateUidProcessStateLocked(int procState)9413 public void updateUidProcessStateLocked(int procState) { 9414 int uidRunningState; 9415 // Make special note of Foreground Services 9416 final boolean userAwareService = 9417 (ActivityManager.isForegroundService(procState)); 9418 uidRunningState = BatteryStats.mapToInternalProcessState(procState); 9419 9420 if (mProcessState == uidRunningState && userAwareService == mInForegroundService) { 9421 return; 9422 } 9423 9424 final long elapsedRealtimeMs = mBsi.mClocks.elapsedRealtime(); 9425 if (mProcessState != uidRunningState) { 9426 final long uptimeMs = mBsi.mClocks.uptimeMillis(); 9427 9428 if (mProcessState != ActivityManager.PROCESS_STATE_NONEXISTENT) { 9429 mProcessStateTimer[mProcessState].stopRunningLocked(elapsedRealtimeMs); 9430 9431 if (mBsi.trackPerProcStateCpuTimes()) { 9432 if (mBsi.mPendingUids.size() == 0) { 9433 mBsi.mExternalSync.scheduleReadProcStateCpuTimes( 9434 mBsi.mOnBatteryTimeBase.isRunning(), 9435 mBsi.mOnBatteryScreenOffTimeBase.isRunning(), 9436 mBsi.mConstants.PROC_STATE_CPU_TIMES_READ_DELAY_MS); 9437 mBsi.mNumSingleUidCpuTimeReads++; 9438 } else { 9439 mBsi.mNumBatchedSingleUidCpuTimeReads++; 9440 } 9441 if (mBsi.mPendingUids.indexOfKey(mUid) < 0 9442 || ArrayUtils.contains(CRITICAL_PROC_STATES, mProcessState)) { 9443 mBsi.mPendingUids.put(mUid, mProcessState); 9444 } 9445 } else { 9446 mBsi.mPendingUids.clear(); 9447 } 9448 } 9449 mProcessState = uidRunningState; 9450 if (uidRunningState != ActivityManager.PROCESS_STATE_NONEXISTENT) { 9451 if (mProcessStateTimer[uidRunningState] == null) { 9452 makeProcessState(uidRunningState, null); 9453 } 9454 mProcessStateTimer[uidRunningState].startRunningLocked(elapsedRealtimeMs); 9455 } 9456 9457 updateOnBatteryBgTimeBase(uptimeMs * 1000, elapsedRealtimeMs * 1000); 9458 updateOnBatteryScreenOffBgTimeBase(uptimeMs * 1000, elapsedRealtimeMs * 1000); 9459 } 9460 9461 if (userAwareService != mInForegroundService) { 9462 if (userAwareService) { 9463 noteForegroundServiceResumedLocked(elapsedRealtimeMs); 9464 } else { 9465 noteForegroundServicePausedLocked(elapsedRealtimeMs); 9466 } 9467 mInForegroundService = userAwareService; 9468 } 9469 } 9470 9471 /** Whether to consider Uid to be in the background for background timebase purposes. */ isInBackground()9472 public boolean isInBackground() { 9473 // Note that PROCESS_STATE_CACHED and ActivityManager.PROCESS_STATE_NONEXISTENT is 9474 // also considered to be 'background' for our purposes, because it's not foreground. 9475 return mProcessState >= PROCESS_STATE_BACKGROUND; 9476 } 9477 updateOnBatteryBgTimeBase(long uptimeUs, long realtimeUs)9478 public boolean updateOnBatteryBgTimeBase(long uptimeUs, long realtimeUs) { 9479 boolean on = mBsi.mOnBatteryTimeBase.isRunning() && isInBackground(); 9480 return mOnBatteryBackgroundTimeBase.setRunning(on, uptimeUs, realtimeUs); 9481 } 9482 updateOnBatteryScreenOffBgTimeBase(long uptimeUs, long realtimeUs)9483 public boolean updateOnBatteryScreenOffBgTimeBase(long uptimeUs, long realtimeUs) { 9484 boolean on = mBsi.mOnBatteryScreenOffTimeBase.isRunning() && isInBackground(); 9485 return mOnBatteryScreenOffBackgroundTimeBase.setRunning(on, uptimeUs, realtimeUs); 9486 } 9487 getPidStats()9488 public SparseArray<? extends Pid> getPidStats() { 9489 return mPids; 9490 } 9491 getPidStatsLocked(int pid)9492 public Pid getPidStatsLocked(int pid) { 9493 Pid p = mPids.get(pid); 9494 if (p == null) { 9495 p = new Pid(); 9496 mPids.put(pid, p); 9497 } 9498 return p; 9499 } 9500 9501 /** 9502 * Retrieve the statistics object for a particular service, creating 9503 * if needed. 9504 */ getPackageStatsLocked(String name)9505 public Pkg getPackageStatsLocked(String name) { 9506 Pkg ps = mPackageStats.get(name); 9507 if (ps == null) { 9508 ps = new Pkg(mBsi); 9509 mPackageStats.put(name, ps); 9510 } 9511 9512 return ps; 9513 } 9514 9515 /** 9516 * Retrieve the statistics object for a particular service, creating 9517 * if needed. 9518 */ getServiceStatsLocked(String pkg, String serv)9519 public Pkg.Serv getServiceStatsLocked(String pkg, String serv) { 9520 Pkg ps = getPackageStatsLocked(pkg); 9521 Pkg.Serv ss = ps.mServiceStats.get(serv); 9522 if (ss == null) { 9523 ss = ps.newServiceStatsLocked(); 9524 ps.mServiceStats.put(serv, ss); 9525 } 9526 9527 return ss; 9528 } 9529 readSyncSummaryFromParcelLocked(String name, Parcel in)9530 public void readSyncSummaryFromParcelLocked(String name, Parcel in) { 9531 DualTimer timer = mSyncStats.instantiateObject(); 9532 timer.readSummaryFromParcelLocked(in); 9533 mSyncStats.add(name, timer); 9534 } 9535 readJobSummaryFromParcelLocked(String name, Parcel in)9536 public void readJobSummaryFromParcelLocked(String name, Parcel in) { 9537 DualTimer timer = mJobStats.instantiateObject(); 9538 timer.readSummaryFromParcelLocked(in); 9539 mJobStats.add(name, timer); 9540 } 9541 readWakeSummaryFromParcelLocked(String wlName, Parcel in)9542 public void readWakeSummaryFromParcelLocked(String wlName, Parcel in) { 9543 Wakelock wl = new Wakelock(mBsi, this); 9544 mWakelockStats.add(wlName, wl); 9545 if (in.readInt() != 0) { 9546 getWakelockTimerLocked(wl, WAKE_TYPE_FULL).readSummaryFromParcelLocked(in); 9547 } 9548 if (in.readInt() != 0) { 9549 getWakelockTimerLocked(wl, WAKE_TYPE_PARTIAL).readSummaryFromParcelLocked(in); 9550 } 9551 if (in.readInt() != 0) { 9552 getWakelockTimerLocked(wl, WAKE_TYPE_WINDOW).readSummaryFromParcelLocked(in); 9553 } 9554 if (in.readInt() != 0) { 9555 getWakelockTimerLocked(wl, WAKE_TYPE_DRAW).readSummaryFromParcelLocked(in); 9556 } 9557 } 9558 getSensorTimerLocked(int sensor, boolean create)9559 public DualTimer getSensorTimerLocked(int sensor, boolean create) { 9560 Sensor se = mSensorStats.get(sensor); 9561 if (se == null) { 9562 if (!create) { 9563 return null; 9564 } 9565 se = new Sensor(mBsi, this, sensor); 9566 mSensorStats.put(sensor, se); 9567 } 9568 DualTimer t = se.mTimer; 9569 if (t != null) { 9570 return t; 9571 } 9572 ArrayList<StopwatchTimer> timers = mBsi.mSensorTimers.get(sensor); 9573 if (timers == null) { 9574 timers = new ArrayList<StopwatchTimer>(); 9575 mBsi.mSensorTimers.put(sensor, timers); 9576 } 9577 t = new DualTimer(mBsi.mClocks, this, BatteryStats.SENSOR, timers, 9578 mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase); 9579 se.mTimer = t; 9580 return t; 9581 } 9582 noteStartSyncLocked(String name, long elapsedRealtimeMs)9583 public void noteStartSyncLocked(String name, long elapsedRealtimeMs) { 9584 DualTimer t = mSyncStats.startObject(name); 9585 if (t != null) { 9586 t.startRunningLocked(elapsedRealtimeMs); 9587 } 9588 } 9589 noteStopSyncLocked(String name, long elapsedRealtimeMs)9590 public void noteStopSyncLocked(String name, long elapsedRealtimeMs) { 9591 DualTimer t = mSyncStats.stopObject(name); 9592 if (t != null) { 9593 t.stopRunningLocked(elapsedRealtimeMs); 9594 } 9595 } 9596 noteStartJobLocked(String name, long elapsedRealtimeMs)9597 public void noteStartJobLocked(String name, long elapsedRealtimeMs) { 9598 DualTimer t = mJobStats.startObject(name); 9599 if (t != null) { 9600 t.startRunningLocked(elapsedRealtimeMs); 9601 } 9602 } 9603 noteStopJobLocked(String name, long elapsedRealtimeMs, int stopReason)9604 public void noteStopJobLocked(String name, long elapsedRealtimeMs, int stopReason) { 9605 DualTimer t = mJobStats.stopObject(name); 9606 if (t != null) { 9607 t.stopRunningLocked(elapsedRealtimeMs); 9608 } 9609 if (mBsi.mOnBatteryTimeBase.isRunning()) { 9610 SparseIntArray types = mJobCompletions.get(name); 9611 if (types == null) { 9612 types = new SparseIntArray(); 9613 mJobCompletions.put(name, types); 9614 } 9615 int last = types.get(stopReason, 0); 9616 types.put(stopReason, last + 1); 9617 } 9618 } 9619 getWakelockTimerLocked(Wakelock wl, int type)9620 public StopwatchTimer getWakelockTimerLocked(Wakelock wl, int type) { 9621 if (wl == null) { 9622 return null; 9623 } 9624 switch (type) { 9625 case WAKE_TYPE_PARTIAL: { 9626 DualTimer t = wl.mTimerPartial; 9627 if (t == null) { 9628 t = new DualTimer(mBsi.mClocks, this, WAKE_TYPE_PARTIAL, 9629 mBsi.mPartialTimers, mBsi.mOnBatteryScreenOffTimeBase, 9630 mOnBatteryScreenOffBackgroundTimeBase); 9631 wl.mTimerPartial = t; 9632 } 9633 return t; 9634 } 9635 case WAKE_TYPE_FULL: { 9636 StopwatchTimer t = wl.mTimerFull; 9637 if (t == null) { 9638 t = new StopwatchTimer(mBsi.mClocks, this, WAKE_TYPE_FULL, 9639 mBsi.mFullTimers, mBsi.mOnBatteryTimeBase); 9640 wl.mTimerFull = t; 9641 } 9642 return t; 9643 } 9644 case WAKE_TYPE_WINDOW: { 9645 StopwatchTimer t = wl.mTimerWindow; 9646 if (t == null) { 9647 t = new StopwatchTimer(mBsi.mClocks, this, WAKE_TYPE_WINDOW, 9648 mBsi.mWindowTimers, mBsi.mOnBatteryTimeBase); 9649 wl.mTimerWindow = t; 9650 } 9651 return t; 9652 } 9653 case WAKE_TYPE_DRAW: { 9654 StopwatchTimer t = wl.mTimerDraw; 9655 if (t == null) { 9656 t = new StopwatchTimer(mBsi.mClocks, this, WAKE_TYPE_DRAW, 9657 mBsi.mDrawTimers, mBsi.mOnBatteryTimeBase); 9658 wl.mTimerDraw = t; 9659 } 9660 return t; 9661 } 9662 default: 9663 throw new IllegalArgumentException("type=" + type); 9664 } 9665 } 9666 noteStartWakeLocked(int pid, String name, int type, long elapsedRealtimeMs)9667 public void noteStartWakeLocked(int pid, String name, int type, long elapsedRealtimeMs) { 9668 Wakelock wl = mWakelockStats.startObject(name); 9669 if (wl != null) { 9670 getWakelockTimerLocked(wl, type).startRunningLocked(elapsedRealtimeMs); 9671 } 9672 if (type == WAKE_TYPE_PARTIAL) { 9673 createAggregatedPartialWakelockTimerLocked().startRunningLocked(elapsedRealtimeMs); 9674 if (pid >= 0) { 9675 Pid p = getPidStatsLocked(pid); 9676 if (p.mWakeNesting++ == 0) { 9677 p.mWakeStartMs = elapsedRealtimeMs; 9678 } 9679 } 9680 } 9681 } 9682 noteStopWakeLocked(int pid, String name, int type, long elapsedRealtimeMs)9683 public void noteStopWakeLocked(int pid, String name, int type, long elapsedRealtimeMs) { 9684 Wakelock wl = mWakelockStats.stopObject(name); 9685 if (wl != null) { 9686 StopwatchTimer wlt = getWakelockTimerLocked(wl, type); 9687 wlt.stopRunningLocked(elapsedRealtimeMs); 9688 } 9689 if (type == WAKE_TYPE_PARTIAL) { 9690 if (mAggregatedPartialWakelockTimer != null) { 9691 mAggregatedPartialWakelockTimer.stopRunningLocked(elapsedRealtimeMs); 9692 } 9693 if (pid >= 0) { 9694 Pid p = mPids.get(pid); 9695 if (p != null && p.mWakeNesting > 0) { 9696 if (p.mWakeNesting-- == 1) { 9697 p.mWakeSumMs += elapsedRealtimeMs - p.mWakeStartMs; 9698 p.mWakeStartMs = 0; 9699 } 9700 } 9701 } 9702 } 9703 } 9704 reportExcessiveCpuLocked(String proc, long overTime, long usedTime)9705 public void reportExcessiveCpuLocked(String proc, long overTime, long usedTime) { 9706 Proc p = getProcessStatsLocked(proc); 9707 if (p != null) { 9708 p.addExcessiveCpu(overTime, usedTime); 9709 } 9710 } 9711 noteStartSensor(int sensor, long elapsedRealtimeMs)9712 public void noteStartSensor(int sensor, long elapsedRealtimeMs) { 9713 DualTimer t = getSensorTimerLocked(sensor, /* create= */ true); 9714 t.startRunningLocked(elapsedRealtimeMs); 9715 } 9716 noteStopSensor(int sensor, long elapsedRealtimeMs)9717 public void noteStopSensor(int sensor, long elapsedRealtimeMs) { 9718 // Don't create a timer if one doesn't already exist 9719 DualTimer t = getSensorTimerLocked(sensor, false); 9720 if (t != null) { 9721 t.stopRunningLocked(elapsedRealtimeMs); 9722 } 9723 } 9724 noteStartGps(long elapsedRealtimeMs)9725 public void noteStartGps(long elapsedRealtimeMs) { 9726 noteStartSensor(Sensor.GPS, elapsedRealtimeMs); 9727 } 9728 noteStopGps(long elapsedRealtimeMs)9729 public void noteStopGps(long elapsedRealtimeMs) { 9730 noteStopSensor(Sensor.GPS, elapsedRealtimeMs); 9731 } 9732 getBatteryStats()9733 public BatteryStatsImpl getBatteryStats() { 9734 return mBsi; 9735 } 9736 } 9737 getCpuFreqs()9738 public long[] getCpuFreqs() { 9739 return mCpuFreqs; 9740 } 9741 BatteryStatsImpl(File systemDir, Handler handler, PlatformIdleStateCallback cb, RailEnergyDataCallback railStatsCb, UserInfoProvider userInfoProvider)9742 public BatteryStatsImpl(File systemDir, Handler handler, PlatformIdleStateCallback cb, 9743 RailEnergyDataCallback railStatsCb, UserInfoProvider userInfoProvider) { 9744 this(new SystemClocks(), systemDir, handler, cb, railStatsCb, userInfoProvider); 9745 } 9746 BatteryStatsImpl(Clocks clocks, File systemDir, Handler handler, PlatformIdleStateCallback cb, RailEnergyDataCallback railStatsCb, UserInfoProvider userInfoProvider)9747 private BatteryStatsImpl(Clocks clocks, File systemDir, Handler handler, 9748 PlatformIdleStateCallback cb, RailEnergyDataCallback railStatsCb, 9749 UserInfoProvider userInfoProvider) { 9750 init(clocks); 9751 9752 9753 if (systemDir == null) { 9754 mStatsFile = null; 9755 mBatteryStatsHistory = new BatteryStatsHistory(this, mHistoryBuffer); 9756 } else { 9757 mStatsFile = new AtomicFile(new File(systemDir, "batterystats.bin")); 9758 mBatteryStatsHistory = new BatteryStatsHistory(this, systemDir, mHistoryBuffer); 9759 } 9760 mCheckinFile = new AtomicFile(new File(systemDir, "batterystats-checkin.bin")); 9761 mDailyFile = new AtomicFile(new File(systemDir, "batterystats-daily.xml")); 9762 mHandler = new MyHandler(handler.getLooper()); 9763 mConstants = new Constants(mHandler); 9764 mStartCount++; 9765 mScreenOnTimer = new StopwatchTimer(mClocks, null, -1, null, mOnBatteryTimeBase); 9766 mScreenDozeTimer = new StopwatchTimer(mClocks, null, -1, null, mOnBatteryTimeBase); 9767 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 9768 mScreenBrightnessTimer[i] = new StopwatchTimer(mClocks, null, -100-i, null, 9769 mOnBatteryTimeBase); 9770 } 9771 mInteractiveTimer = new StopwatchTimer(mClocks, null, -10, null, mOnBatteryTimeBase); 9772 mPowerSaveModeEnabledTimer = new StopwatchTimer(mClocks, null, -2, null, 9773 mOnBatteryTimeBase); 9774 mDeviceIdleModeLightTimer = new StopwatchTimer(mClocks, null, -11, null, 9775 mOnBatteryTimeBase); 9776 mDeviceIdleModeFullTimer = new StopwatchTimer(mClocks, null, -14, null, mOnBatteryTimeBase); 9777 mDeviceLightIdlingTimer = new StopwatchTimer(mClocks, null, -15, null, mOnBatteryTimeBase); 9778 mDeviceIdlingTimer = new StopwatchTimer(mClocks, null, -12, null, mOnBatteryTimeBase); 9779 mPhoneOnTimer = new StopwatchTimer(mClocks, null, -3, null, mOnBatteryTimeBase); 9780 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) { 9781 mPhoneSignalStrengthsTimer[i] = new StopwatchTimer(mClocks, null, -200-i, null, 9782 mOnBatteryTimeBase); 9783 } 9784 mPhoneSignalScanningTimer = new StopwatchTimer(mClocks, null, -200+1, null, 9785 mOnBatteryTimeBase); 9786 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 9787 mPhoneDataConnectionsTimer[i] = new StopwatchTimer(mClocks, null, -300-i, null, 9788 mOnBatteryTimeBase); 9789 } 9790 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 9791 mNetworkByteActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase); 9792 mNetworkPacketActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase); 9793 } 9794 mWifiActivity = new ControllerActivityCounterImpl(mOnBatteryTimeBase, NUM_WIFI_TX_LEVELS); 9795 mBluetoothActivity = new ControllerActivityCounterImpl(mOnBatteryTimeBase, 9796 NUM_BT_TX_LEVELS); 9797 mModemActivity = new ControllerActivityCounterImpl(mOnBatteryTimeBase, 9798 ModemActivityInfo.TX_POWER_LEVELS); 9799 mMobileRadioActiveTimer = new StopwatchTimer(mClocks, null, -400, null, mOnBatteryTimeBase); 9800 mMobileRadioActivePerAppTimer = new StopwatchTimer(mClocks, null, -401, null, 9801 mOnBatteryTimeBase); 9802 mMobileRadioActiveAdjustedTime = new LongSamplingCounter(mOnBatteryTimeBase); 9803 mMobileRadioActiveUnknownTime = new LongSamplingCounter(mOnBatteryTimeBase); 9804 mMobileRadioActiveUnknownCount = new LongSamplingCounter(mOnBatteryTimeBase); 9805 mWifiMulticastWakelockTimer = new StopwatchTimer(mClocks, null, 9806 WIFI_AGGREGATE_MULTICAST_ENABLED, null, mOnBatteryTimeBase); 9807 mWifiOnTimer = new StopwatchTimer(mClocks, null, -4, null, mOnBatteryTimeBase); 9808 mGlobalWifiRunningTimer = new StopwatchTimer(mClocks, null, -5, null, mOnBatteryTimeBase); 9809 for (int i=0; i<NUM_WIFI_STATES; i++) { 9810 mWifiStateTimer[i] = new StopwatchTimer(mClocks, null, -600-i, null, 9811 mOnBatteryTimeBase); 9812 } 9813 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) { 9814 mWifiSupplStateTimer[i] = new StopwatchTimer(mClocks, null, -700-i, null, 9815 mOnBatteryTimeBase); 9816 } 9817 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { 9818 mWifiSignalStrengthsTimer[i] = new StopwatchTimer(mClocks, null, -800-i, null, 9819 mOnBatteryTimeBase); 9820 } 9821 mWifiActiveTimer = new StopwatchTimer(mClocks, null, -900, null, mOnBatteryTimeBase); 9822 for (int i=0; i< GnssMetrics.NUM_GPS_SIGNAL_QUALITY_LEVELS; i++) { 9823 mGpsSignalQualityTimer[i] = new StopwatchTimer(mClocks, null, -1000-i, null, 9824 mOnBatteryTimeBase); 9825 } 9826 mAudioOnTimer = new StopwatchTimer(mClocks, null, -7, null, mOnBatteryTimeBase); 9827 mVideoOnTimer = new StopwatchTimer(mClocks, null, -8, null, mOnBatteryTimeBase); 9828 mFlashlightOnTimer = new StopwatchTimer(mClocks, null, -9, null, mOnBatteryTimeBase); 9829 mCameraOnTimer = new StopwatchTimer(mClocks, null, -13, null, mOnBatteryTimeBase); 9830 mBluetoothScanTimer = new StopwatchTimer(mClocks, null, -14, null, mOnBatteryTimeBase); 9831 mDischargeScreenOffCounter = new LongSamplingCounter(mOnBatteryScreenOffTimeBase); 9832 mDischargeScreenDozeCounter = new LongSamplingCounter(mOnBatteryTimeBase); 9833 mDischargeLightDozeCounter = new LongSamplingCounter(mOnBatteryTimeBase); 9834 mDischargeDeepDozeCounter = new LongSamplingCounter(mOnBatteryTimeBase); 9835 mDischargeCounter = new LongSamplingCounter(mOnBatteryTimeBase); 9836 mOnBattery = mOnBatteryInternal = false; 9837 long uptime = mClocks.uptimeMillis() * 1000; 9838 long realtime = mClocks.elapsedRealtime() * 1000; 9839 initTimes(uptime, realtime); 9840 mStartPlatformVersion = mEndPlatformVersion = Build.ID; 9841 mDischargeStartLevel = 0; 9842 mDischargeUnplugLevel = 0; 9843 mDischargePlugLevel = -1; 9844 mDischargeCurrentLevel = 0; 9845 mCurrentBatteryLevel = 0; 9846 initDischarge(); 9847 clearHistoryLocked(); 9848 updateDailyDeadlineLocked(); 9849 mPlatformIdleStateCallback = cb; 9850 mRailEnergyDataCallback = railStatsCb; 9851 mUserInfoProvider = userInfoProvider; 9852 } 9853 9854 @UnsupportedAppUsage BatteryStatsImpl(Parcel p)9855 public BatteryStatsImpl(Parcel p) { 9856 this(new SystemClocks(), p); 9857 } 9858 BatteryStatsImpl(Clocks clocks, Parcel p)9859 public BatteryStatsImpl(Clocks clocks, Parcel p) { 9860 init(clocks); 9861 mStatsFile = null; 9862 mCheckinFile = null; 9863 mDailyFile = null; 9864 mHandler = null; 9865 mExternalSync = null; 9866 mConstants = new Constants(mHandler); 9867 clearHistoryLocked(); 9868 mBatteryStatsHistory = new BatteryStatsHistory(this, mHistoryBuffer); 9869 readFromParcel(p); 9870 mPlatformIdleStateCallback = null; 9871 mRailEnergyDataCallback = null; 9872 } 9873 setPowerProfileLocked(PowerProfile profile)9874 public void setPowerProfileLocked(PowerProfile profile) { 9875 mPowerProfile = profile; 9876 9877 // We need to initialize the KernelCpuSpeedReaders to read from 9878 // the first cpu of each core. Once we have the PowerProfile, we have access to this 9879 // information. 9880 final int numClusters = mPowerProfile.getNumCpuClusters(); 9881 mKernelCpuSpeedReaders = new KernelCpuSpeedReader[numClusters]; 9882 int firstCpuOfCluster = 0; 9883 for (int i = 0; i < numClusters; i++) { 9884 final int numSpeedSteps = mPowerProfile.getNumSpeedStepsInCpuCluster(i); 9885 mKernelCpuSpeedReaders[i] = new KernelCpuSpeedReader(firstCpuOfCluster, 9886 numSpeedSteps); 9887 firstCpuOfCluster += mPowerProfile.getNumCoresInCpuCluster(i); 9888 } 9889 9890 if (mEstimatedBatteryCapacity == -1) { 9891 // Initialize the estimated battery capacity to a known preset one. 9892 mEstimatedBatteryCapacity = (int) mPowerProfile.getBatteryCapacity(); 9893 } 9894 } 9895 setCallback(BatteryCallback cb)9896 public void setCallback(BatteryCallback cb) { 9897 mCallback = cb; 9898 } 9899 setRadioScanningTimeoutLocked(long timeout)9900 public void setRadioScanningTimeoutLocked(long timeout) { 9901 if (mPhoneSignalScanningTimer != null) { 9902 mPhoneSignalScanningTimer.setTimeout(timeout); 9903 } 9904 } 9905 setExternalStatsSyncLocked(ExternalStatsSync sync)9906 public void setExternalStatsSyncLocked(ExternalStatsSync sync) { 9907 mExternalSync = sync; 9908 } 9909 updateDailyDeadlineLocked()9910 public void updateDailyDeadlineLocked() { 9911 // Get the current time. 9912 long currentTime = mDailyStartTime = System.currentTimeMillis(); 9913 Calendar calDeadline = Calendar.getInstance(); 9914 calDeadline.setTimeInMillis(currentTime); 9915 9916 // Move time up to the next day, ranging from 1am to 3pm. 9917 calDeadline.set(Calendar.DAY_OF_YEAR, calDeadline.get(Calendar.DAY_OF_YEAR) + 1); 9918 calDeadline.set(Calendar.MILLISECOND, 0); 9919 calDeadline.set(Calendar.SECOND, 0); 9920 calDeadline.set(Calendar.MINUTE, 0); 9921 calDeadline.set(Calendar.HOUR_OF_DAY, 1); 9922 mNextMinDailyDeadline = calDeadline.getTimeInMillis(); 9923 calDeadline.set(Calendar.HOUR_OF_DAY, 3); 9924 mNextMaxDailyDeadline = calDeadline.getTimeInMillis(); 9925 } 9926 recordDailyStatsIfNeededLocked(boolean settled)9927 public void recordDailyStatsIfNeededLocked(boolean settled) { 9928 long currentTime = System.currentTimeMillis(); 9929 if (currentTime >= mNextMaxDailyDeadline) { 9930 recordDailyStatsLocked(); 9931 } else if (settled && currentTime >= mNextMinDailyDeadline) { 9932 recordDailyStatsLocked(); 9933 } else if (currentTime < (mDailyStartTime-(1000*60*60*24))) { 9934 recordDailyStatsLocked(); 9935 } 9936 } 9937 recordDailyStatsLocked()9938 public void recordDailyStatsLocked() { 9939 DailyItem item = new DailyItem(); 9940 item.mStartTime = mDailyStartTime; 9941 item.mEndTime = System.currentTimeMillis(); 9942 boolean hasData = false; 9943 if (mDailyDischargeStepTracker.mNumStepDurations > 0) { 9944 hasData = true; 9945 item.mDischargeSteps = new LevelStepTracker( 9946 mDailyDischargeStepTracker.mNumStepDurations, 9947 mDailyDischargeStepTracker.mStepDurations); 9948 } 9949 if (mDailyChargeStepTracker.mNumStepDurations > 0) { 9950 hasData = true; 9951 item.mChargeSteps = new LevelStepTracker( 9952 mDailyChargeStepTracker.mNumStepDurations, 9953 mDailyChargeStepTracker.mStepDurations); 9954 } 9955 if (mDailyPackageChanges != null) { 9956 hasData = true; 9957 item.mPackageChanges = mDailyPackageChanges; 9958 mDailyPackageChanges = null; 9959 } 9960 mDailyDischargeStepTracker.init(); 9961 mDailyChargeStepTracker.init(); 9962 updateDailyDeadlineLocked(); 9963 9964 if (hasData) { 9965 final long startTime = SystemClock.uptimeMillis(); 9966 mDailyItems.add(item); 9967 while (mDailyItems.size() > MAX_DAILY_ITEMS) { 9968 mDailyItems.remove(0); 9969 } 9970 final ByteArrayOutputStream memStream = new ByteArrayOutputStream(); 9971 try { 9972 XmlSerializer out = new FastXmlSerializer(); 9973 out.setOutput(memStream, StandardCharsets.UTF_8.name()); 9974 writeDailyItemsLocked(out); 9975 final long initialTime = SystemClock.uptimeMillis() - startTime; 9976 BackgroundThread.getHandler().post(new Runnable() { 9977 @Override 9978 public void run() { 9979 synchronized (mCheckinFile) { 9980 final long startTime2 = SystemClock.uptimeMillis(); 9981 FileOutputStream stream = null; 9982 try { 9983 stream = mDailyFile.startWrite(); 9984 memStream.writeTo(stream); 9985 stream.flush(); 9986 mDailyFile.finishWrite(stream); 9987 com.android.internal.logging.EventLogTags.writeCommitSysConfigFile( 9988 "batterystats-daily", 9989 initialTime + SystemClock.uptimeMillis() - startTime2); 9990 } catch (IOException e) { 9991 Slog.w("BatteryStats", 9992 "Error writing battery daily items", e); 9993 mDailyFile.failWrite(stream); 9994 } 9995 } 9996 } 9997 }); 9998 } catch (IOException e) { 9999 } 10000 } 10001 } 10002 writeDailyItemsLocked(XmlSerializer out)10003 private void writeDailyItemsLocked(XmlSerializer out) throws IOException { 10004 StringBuilder sb = new StringBuilder(64); 10005 out.startDocument(null, true); 10006 out.startTag(null, "daily-items"); 10007 for (int i=0; i<mDailyItems.size(); i++) { 10008 final DailyItem dit = mDailyItems.get(i); 10009 out.startTag(null, "item"); 10010 out.attribute(null, "start", Long.toString(dit.mStartTime)); 10011 out.attribute(null, "end", Long.toString(dit.mEndTime)); 10012 writeDailyLevelSteps(out, "dis", dit.mDischargeSteps, sb); 10013 writeDailyLevelSteps(out, "chg", dit.mChargeSteps, sb); 10014 if (dit.mPackageChanges != null) { 10015 for (int j=0; j<dit.mPackageChanges.size(); j++) { 10016 PackageChange pc = dit.mPackageChanges.get(j); 10017 if (pc.mUpdate) { 10018 out.startTag(null, "upd"); 10019 out.attribute(null, "pkg", pc.mPackageName); 10020 out.attribute(null, "ver", Long.toString(pc.mVersionCode)); 10021 out.endTag(null, "upd"); 10022 } else { 10023 out.startTag(null, "rem"); 10024 out.attribute(null, "pkg", pc.mPackageName); 10025 out.endTag(null, "rem"); 10026 } 10027 } 10028 } 10029 out.endTag(null, "item"); 10030 } 10031 out.endTag(null, "daily-items"); 10032 out.endDocument(); 10033 } 10034 writeDailyLevelSteps(XmlSerializer out, String tag, LevelStepTracker steps, StringBuilder tmpBuilder)10035 private void writeDailyLevelSteps(XmlSerializer out, String tag, LevelStepTracker steps, 10036 StringBuilder tmpBuilder) throws IOException { 10037 if (steps != null) { 10038 out.startTag(null, tag); 10039 out.attribute(null, "n", Integer.toString(steps.mNumStepDurations)); 10040 for (int i=0; i<steps.mNumStepDurations; i++) { 10041 out.startTag(null, "s"); 10042 tmpBuilder.setLength(0); 10043 steps.encodeEntryAt(i, tmpBuilder); 10044 out.attribute(null, "v", tmpBuilder.toString()); 10045 out.endTag(null, "s"); 10046 } 10047 out.endTag(null, tag); 10048 } 10049 } 10050 readDailyStatsLocked()10051 public void readDailyStatsLocked() { 10052 Slog.d(TAG, "Reading daily items from " + mDailyFile.getBaseFile()); 10053 mDailyItems.clear(); 10054 FileInputStream stream; 10055 try { 10056 stream = mDailyFile.openRead(); 10057 } catch (FileNotFoundException e) { 10058 return; 10059 } 10060 try { 10061 XmlPullParser parser = Xml.newPullParser(); 10062 parser.setInput(stream, StandardCharsets.UTF_8.name()); 10063 readDailyItemsLocked(parser); 10064 } catch (XmlPullParserException e) { 10065 } finally { 10066 try { 10067 stream.close(); 10068 } catch (IOException e) { 10069 } 10070 } 10071 } 10072 readDailyItemsLocked(XmlPullParser parser)10073 private void readDailyItemsLocked(XmlPullParser parser) { 10074 try { 10075 int type; 10076 while ((type = parser.next()) != XmlPullParser.START_TAG 10077 && type != XmlPullParser.END_DOCUMENT) { 10078 ; 10079 } 10080 10081 if (type != XmlPullParser.START_TAG) { 10082 throw new IllegalStateException("no start tag found"); 10083 } 10084 10085 int outerDepth = parser.getDepth(); 10086 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 10087 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 10088 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 10089 continue; 10090 } 10091 10092 String tagName = parser.getName(); 10093 if (tagName.equals("item")) { 10094 readDailyItemTagLocked(parser); 10095 } else { 10096 Slog.w(TAG, "Unknown element under <daily-items>: " 10097 + parser.getName()); 10098 XmlUtils.skipCurrentTag(parser); 10099 } 10100 } 10101 10102 } catch (IllegalStateException e) { 10103 Slog.w(TAG, "Failed parsing daily " + e); 10104 } catch (NullPointerException e) { 10105 Slog.w(TAG, "Failed parsing daily " + e); 10106 } catch (NumberFormatException e) { 10107 Slog.w(TAG, "Failed parsing daily " + e); 10108 } catch (XmlPullParserException e) { 10109 Slog.w(TAG, "Failed parsing daily " + e); 10110 } catch (IOException e) { 10111 Slog.w(TAG, "Failed parsing daily " + e); 10112 } catch (IndexOutOfBoundsException e) { 10113 Slog.w(TAG, "Failed parsing daily " + e); 10114 } 10115 } 10116 readDailyItemTagLocked(XmlPullParser parser)10117 void readDailyItemTagLocked(XmlPullParser parser) throws NumberFormatException, 10118 XmlPullParserException, IOException { 10119 DailyItem dit = new DailyItem(); 10120 String attr = parser.getAttributeValue(null, "start"); 10121 if (attr != null) { 10122 dit.mStartTime = Long.parseLong(attr); 10123 } 10124 attr = parser.getAttributeValue(null, "end"); 10125 if (attr != null) { 10126 dit.mEndTime = Long.parseLong(attr); 10127 } 10128 int outerDepth = parser.getDepth(); 10129 int type; 10130 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 10131 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 10132 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 10133 continue; 10134 } 10135 10136 String tagName = parser.getName(); 10137 if (tagName.equals("dis")) { 10138 readDailyItemTagDetailsLocked(parser, dit, false, "dis"); 10139 } else if (tagName.equals("chg")) { 10140 readDailyItemTagDetailsLocked(parser, dit, true, "chg"); 10141 } else if (tagName.equals("upd")) { 10142 if (dit.mPackageChanges == null) { 10143 dit.mPackageChanges = new ArrayList<>(); 10144 } 10145 PackageChange pc = new PackageChange(); 10146 pc.mUpdate = true; 10147 pc.mPackageName = parser.getAttributeValue(null, "pkg"); 10148 String verStr = parser.getAttributeValue(null, "ver"); 10149 pc.mVersionCode = verStr != null ? Long.parseLong(verStr) : 0; 10150 dit.mPackageChanges.add(pc); 10151 XmlUtils.skipCurrentTag(parser); 10152 } else if (tagName.equals("rem")) { 10153 if (dit.mPackageChanges == null) { 10154 dit.mPackageChanges = new ArrayList<>(); 10155 } 10156 PackageChange pc = new PackageChange(); 10157 pc.mUpdate = false; 10158 pc.mPackageName = parser.getAttributeValue(null, "pkg"); 10159 dit.mPackageChanges.add(pc); 10160 XmlUtils.skipCurrentTag(parser); 10161 } else { 10162 Slog.w(TAG, "Unknown element under <item>: " 10163 + parser.getName()); 10164 XmlUtils.skipCurrentTag(parser); 10165 } 10166 } 10167 mDailyItems.add(dit); 10168 } 10169 readDailyItemTagDetailsLocked(XmlPullParser parser, DailyItem dit, boolean isCharge, String tag)10170 void readDailyItemTagDetailsLocked(XmlPullParser parser, DailyItem dit, boolean isCharge, 10171 String tag) 10172 throws NumberFormatException, XmlPullParserException, IOException { 10173 final String numAttr = parser.getAttributeValue(null, "n"); 10174 if (numAttr == null) { 10175 Slog.w(TAG, "Missing 'n' attribute at " + parser.getPositionDescription()); 10176 XmlUtils.skipCurrentTag(parser); 10177 return; 10178 } 10179 final int num = Integer.parseInt(numAttr); 10180 LevelStepTracker steps = new LevelStepTracker(num); 10181 if (isCharge) { 10182 dit.mChargeSteps = steps; 10183 } else { 10184 dit.mDischargeSteps = steps; 10185 } 10186 int i = 0; 10187 int outerDepth = parser.getDepth(); 10188 int type; 10189 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 10190 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 10191 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 10192 continue; 10193 } 10194 10195 String tagName = parser.getName(); 10196 if ("s".equals(tagName)) { 10197 if (i < num) { 10198 String valueAttr = parser.getAttributeValue(null, "v"); 10199 if (valueAttr != null) { 10200 steps.decodeEntryAt(i, valueAttr); 10201 i++; 10202 } 10203 } 10204 } else { 10205 Slog.w(TAG, "Unknown element under <" + tag + ">: " 10206 + parser.getName()); 10207 XmlUtils.skipCurrentTag(parser); 10208 } 10209 } 10210 steps.mNumStepDurations = i; 10211 } 10212 10213 @Override getDailyItemLocked(int daysAgo)10214 public DailyItem getDailyItemLocked(int daysAgo) { 10215 int index = mDailyItems.size()-1-daysAgo; 10216 return index >= 0 ? mDailyItems.get(index) : null; 10217 } 10218 10219 @Override getCurrentDailyStartTime()10220 public long getCurrentDailyStartTime() { 10221 return mDailyStartTime; 10222 } 10223 10224 @Override getNextMinDailyDeadline()10225 public long getNextMinDailyDeadline() { 10226 return mNextMinDailyDeadline; 10227 } 10228 10229 @Override getNextMaxDailyDeadline()10230 public long getNextMaxDailyDeadline() { 10231 return mNextMaxDailyDeadline; 10232 } 10233 10234 @Override startIteratingOldHistoryLocked()10235 public boolean startIteratingOldHistoryLocked() { 10236 if (DEBUG_HISTORY) Slog.i(TAG, "ITERATING: buff size=" + mHistoryBuffer.dataSize() 10237 + " pos=" + mHistoryBuffer.dataPosition()); 10238 if ((mHistoryIterator = mHistory) == null) { 10239 return false; 10240 } 10241 mHistoryBuffer.setDataPosition(0); 10242 mHistoryReadTmp.clear(); 10243 mReadOverflow = false; 10244 mIteratingHistory = true; 10245 return true; 10246 } 10247 10248 @Override getNextOldHistoryLocked(HistoryItem out)10249 public boolean getNextOldHistoryLocked(HistoryItem out) { 10250 boolean end = mHistoryBuffer.dataPosition() >= mHistoryBuffer.dataSize(); 10251 if (!end) { 10252 readHistoryDelta(mHistoryBuffer, mHistoryReadTmp); 10253 mReadOverflow |= mHistoryReadTmp.cmd == HistoryItem.CMD_OVERFLOW; 10254 } 10255 HistoryItem cur = mHistoryIterator; 10256 if (cur == null) { 10257 if (!mReadOverflow && !end) { 10258 Slog.w(TAG, "Old history ends before new history!"); 10259 } 10260 return false; 10261 } 10262 out.setTo(cur); 10263 mHistoryIterator = cur.next; 10264 if (!mReadOverflow) { 10265 if (end) { 10266 Slog.w(TAG, "New history ends before old history!"); 10267 } else if (!out.same(mHistoryReadTmp)) { 10268 PrintWriter pw = new FastPrintWriter(new LogWriter(android.util.Log.WARN, TAG)); 10269 pw.println("Histories differ!"); 10270 pw.println("Old history:"); 10271 (new HistoryPrinter()).printNextItem(pw, out, 0, false, true); 10272 pw.println("New history:"); 10273 (new HistoryPrinter()).printNextItem(pw, mHistoryReadTmp, 0, false, 10274 true); 10275 pw.flush(); 10276 } 10277 } 10278 return true; 10279 } 10280 10281 @Override finishIteratingOldHistoryLocked()10282 public void finishIteratingOldHistoryLocked() { 10283 mIteratingHistory = false; 10284 mHistoryBuffer.setDataPosition(mHistoryBuffer.dataSize()); 10285 mHistoryIterator = null; 10286 } 10287 getHistoryTotalSize()10288 public int getHistoryTotalSize() { 10289 return mConstants.MAX_HISTORY_BUFFER * mConstants.MAX_HISTORY_FILES; 10290 } 10291 getHistoryUsedSize()10292 public int getHistoryUsedSize() { 10293 return mBatteryStatsHistory.getHistoryUsedSize(); 10294 } 10295 10296 @Override 10297 @UnsupportedAppUsage startIteratingHistoryLocked()10298 public boolean startIteratingHistoryLocked() { 10299 mBatteryStatsHistory.startIteratingHistory(); 10300 mReadOverflow = false; 10301 mIteratingHistory = true; 10302 mReadHistoryStrings = new String[mHistoryTagPool.size()]; 10303 mReadHistoryUids = new int[mHistoryTagPool.size()]; 10304 mReadHistoryChars = 0; 10305 for (HashMap.Entry<HistoryTag, Integer> ent : mHistoryTagPool.entrySet()) { 10306 final HistoryTag tag = ent.getKey(); 10307 final int idx = ent.getValue(); 10308 mReadHistoryStrings[idx] = tag.string; 10309 mReadHistoryUids[idx] = tag.uid; 10310 mReadHistoryChars += tag.string.length() + 1; 10311 } 10312 return true; 10313 } 10314 10315 @Override getHistoryStringPoolSize()10316 public int getHistoryStringPoolSize() { 10317 return mReadHistoryStrings.length; 10318 } 10319 10320 @Override getHistoryStringPoolBytes()10321 public int getHistoryStringPoolBytes() { 10322 // Each entry is a fixed 12 bytes: 4 for index, 4 for uid, 4 for string size 10323 // Each string character is 2 bytes. 10324 return (mReadHistoryStrings.length * 12) + (mReadHistoryChars * 2); 10325 } 10326 10327 @Override getHistoryTagPoolString(int index)10328 public String getHistoryTagPoolString(int index) { 10329 return mReadHistoryStrings[index]; 10330 } 10331 10332 @Override getHistoryTagPoolUid(int index)10333 public int getHistoryTagPoolUid(int index) { 10334 return mReadHistoryUids[index]; 10335 } 10336 10337 @Override 10338 @UnsupportedAppUsage getNextHistoryLocked(HistoryItem out)10339 public boolean getNextHistoryLocked(HistoryItem out) { 10340 Parcel p = mBatteryStatsHistory.getNextParcel(out); 10341 if (p == null) { 10342 return false; 10343 } 10344 final long lastRealtime = out.time; 10345 final long lastWalltime = out.currentTime; 10346 readHistoryDelta(p, out); 10347 if (out.cmd != HistoryItem.CMD_CURRENT_TIME 10348 && out.cmd != HistoryItem.CMD_RESET && lastWalltime != 0) { 10349 out.currentTime = lastWalltime + (out.time - lastRealtime); 10350 } 10351 return true; 10352 } 10353 10354 @Override finishIteratingHistoryLocked()10355 public void finishIteratingHistoryLocked() { 10356 mBatteryStatsHistory.finishIteratingHistory(); 10357 mIteratingHistory = false; 10358 mReadHistoryStrings = null; 10359 mReadHistoryUids = null; 10360 } 10361 10362 @Override getHistoryBaseTime()10363 public long getHistoryBaseTime() { 10364 return mHistoryBaseTime; 10365 } 10366 10367 @Override getStartCount()10368 public int getStartCount() { 10369 return mStartCount; 10370 } 10371 10372 @UnsupportedAppUsage isOnBattery()10373 public boolean isOnBattery() { 10374 return mOnBattery; 10375 } 10376 isCharging()10377 public boolean isCharging() { 10378 return mCharging; 10379 } 10380 isScreenOn(int state)10381 public boolean isScreenOn(int state) { 10382 return state == Display.STATE_ON || state == Display.STATE_VR 10383 || state == Display.STATE_ON_SUSPEND; 10384 } 10385 isScreenOff(int state)10386 public boolean isScreenOff(int state) { 10387 return state == Display.STATE_OFF; 10388 } 10389 isScreenDoze(int state)10390 public boolean isScreenDoze(int state) { 10391 return state == Display.STATE_DOZE || state == Display.STATE_DOZE_SUSPEND; 10392 } 10393 initTimes(long uptime, long realtime)10394 void initTimes(long uptime, long realtime) { 10395 mStartClockTime = System.currentTimeMillis(); 10396 mOnBatteryTimeBase.init(uptime, realtime); 10397 mOnBatteryScreenOffTimeBase.init(uptime, realtime); 10398 mRealtime = 0; 10399 mUptime = 0; 10400 mRealtimeStart = realtime; 10401 mUptimeStart = uptime; 10402 } 10403 initDischarge()10404 void initDischarge() { 10405 mLowDischargeAmountSinceCharge = 0; 10406 mHighDischargeAmountSinceCharge = 0; 10407 mDischargeAmountScreenOn = 0; 10408 mDischargeAmountScreenOnSinceCharge = 0; 10409 mDischargeAmountScreenOff = 0; 10410 mDischargeAmountScreenOffSinceCharge = 0; 10411 mDischargeAmountScreenDoze = 0; 10412 mDischargeAmountScreenDozeSinceCharge = 0; 10413 mDischargeStepTracker.init(); 10414 mChargeStepTracker.init(); 10415 mDischargeScreenOffCounter.reset(false); 10416 mDischargeScreenDozeCounter.reset(false); 10417 mDischargeLightDozeCounter.reset(false); 10418 mDischargeDeepDozeCounter.reset(false); 10419 mDischargeCounter.reset(false); 10420 } 10421 resetAllStatsCmdLocked()10422 public void resetAllStatsCmdLocked() { 10423 resetAllStatsLocked(); 10424 final long mSecUptime = mClocks.uptimeMillis(); 10425 long uptime = mSecUptime * 1000; 10426 long mSecRealtime = mClocks.elapsedRealtime(); 10427 long realtime = mSecRealtime * 1000; 10428 mDischargeStartLevel = mHistoryCur.batteryLevel; 10429 pullPendingStateUpdatesLocked(); 10430 addHistoryRecordLocked(mSecRealtime, mSecUptime); 10431 mDischargeCurrentLevel = mDischargeUnplugLevel = mDischargePlugLevel 10432 = mCurrentBatteryLevel = mHistoryCur.batteryLevel; 10433 mOnBatteryTimeBase.reset(uptime, realtime); 10434 mOnBatteryScreenOffTimeBase.reset(uptime, realtime); 10435 if ((mHistoryCur.states&HistoryItem.STATE_BATTERY_PLUGGED_FLAG) == 0) { 10436 if (isScreenOn(mScreenState)) { 10437 mDischargeScreenOnUnplugLevel = mHistoryCur.batteryLevel; 10438 mDischargeScreenDozeUnplugLevel = 0; 10439 mDischargeScreenOffUnplugLevel = 0; 10440 } else if (isScreenDoze(mScreenState)) { 10441 mDischargeScreenOnUnplugLevel = 0; 10442 mDischargeScreenDozeUnplugLevel = mHistoryCur.batteryLevel; 10443 mDischargeScreenOffUnplugLevel = 0; 10444 } else { 10445 mDischargeScreenOnUnplugLevel = 0; 10446 mDischargeScreenDozeUnplugLevel = 0; 10447 mDischargeScreenOffUnplugLevel = mHistoryCur.batteryLevel; 10448 } 10449 mDischargeAmountScreenOn = 0; 10450 mDischargeAmountScreenOff = 0; 10451 mDischargeAmountScreenDoze = 0; 10452 } 10453 initActiveHistoryEventsLocked(mSecRealtime, mSecUptime); 10454 } 10455 resetAllStatsLocked()10456 private void resetAllStatsLocked() { 10457 final long uptimeMillis = mClocks.uptimeMillis(); 10458 final long elapsedRealtimeMillis = mClocks.elapsedRealtime(); 10459 mStartCount = 0; 10460 initTimes(uptimeMillis * 1000, elapsedRealtimeMillis * 1000); 10461 mScreenOnTimer.reset(false); 10462 mScreenDozeTimer.reset(false); 10463 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 10464 mScreenBrightnessTimer[i].reset(false); 10465 } 10466 10467 if (mPowerProfile != null) { 10468 mEstimatedBatteryCapacity = (int) mPowerProfile.getBatteryCapacity(); 10469 } else { 10470 mEstimatedBatteryCapacity = -1; 10471 } 10472 mMinLearnedBatteryCapacity = -1; 10473 mMaxLearnedBatteryCapacity = -1; 10474 mInteractiveTimer.reset(false); 10475 mPowerSaveModeEnabledTimer.reset(false); 10476 mLastIdleTimeStart = elapsedRealtimeMillis; 10477 mLongestLightIdleTime = 0; 10478 mLongestFullIdleTime = 0; 10479 mDeviceIdleModeLightTimer.reset(false); 10480 mDeviceIdleModeFullTimer.reset(false); 10481 mDeviceLightIdlingTimer.reset(false); 10482 mDeviceIdlingTimer.reset(false); 10483 mPhoneOnTimer.reset(false); 10484 mAudioOnTimer.reset(false); 10485 mVideoOnTimer.reset(false); 10486 mFlashlightOnTimer.reset(false); 10487 mCameraOnTimer.reset(false); 10488 mBluetoothScanTimer.reset(false); 10489 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) { 10490 mPhoneSignalStrengthsTimer[i].reset(false); 10491 } 10492 mPhoneSignalScanningTimer.reset(false); 10493 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 10494 mPhoneDataConnectionsTimer[i].reset(false); 10495 } 10496 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 10497 mNetworkByteActivityCounters[i].reset(false); 10498 mNetworkPacketActivityCounters[i].reset(false); 10499 } 10500 mMobileRadioActiveTimer.reset(false); 10501 mMobileRadioActivePerAppTimer.reset(false); 10502 mMobileRadioActiveAdjustedTime.reset(false); 10503 mMobileRadioActiveUnknownTime.reset(false); 10504 mMobileRadioActiveUnknownCount.reset(false); 10505 mWifiOnTimer.reset(false); 10506 mGlobalWifiRunningTimer.reset(false); 10507 for (int i=0; i<NUM_WIFI_STATES; i++) { 10508 mWifiStateTimer[i].reset(false); 10509 } 10510 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) { 10511 mWifiSupplStateTimer[i].reset(false); 10512 } 10513 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { 10514 mWifiSignalStrengthsTimer[i].reset(false); 10515 } 10516 mWifiMulticastWakelockTimer.reset(false); 10517 mWifiActiveTimer.reset(false); 10518 mWifiActivity.reset(false); 10519 for (int i=0; i< GnssMetrics.NUM_GPS_SIGNAL_QUALITY_LEVELS; i++) { 10520 mGpsSignalQualityTimer[i].reset(false); 10521 } 10522 mBluetoothActivity.reset(false); 10523 mModemActivity.reset(false); 10524 mNumConnectivityChange = 0; 10525 10526 for (int i=0; i<mUidStats.size(); i++) { 10527 if (mUidStats.valueAt(i).reset(uptimeMillis * 1000, elapsedRealtimeMillis * 1000)) { 10528 mUidStats.valueAt(i).detachFromTimeBase(); 10529 mUidStats.remove(mUidStats.keyAt(i)); 10530 i--; 10531 } 10532 } 10533 10534 if (mRpmStats.size() > 0) { 10535 for (SamplingTimer timer : mRpmStats.values()) { 10536 mOnBatteryTimeBase.remove(timer); 10537 } 10538 mRpmStats.clear(); 10539 } 10540 if (mScreenOffRpmStats.size() > 0) { 10541 for (SamplingTimer timer : mScreenOffRpmStats.values()) { 10542 mOnBatteryScreenOffTimeBase.remove(timer); 10543 } 10544 mScreenOffRpmStats.clear(); 10545 } 10546 10547 if (mKernelWakelockStats.size() > 0) { 10548 for (SamplingTimer timer : mKernelWakelockStats.values()) { 10549 mOnBatteryScreenOffTimeBase.remove(timer); 10550 } 10551 mKernelWakelockStats.clear(); 10552 } 10553 10554 if (mKernelMemoryStats.size() > 0) { 10555 for (int i = 0; i < mKernelMemoryStats.size(); i++) { 10556 mOnBatteryTimeBase.remove(mKernelMemoryStats.valueAt(i)); 10557 } 10558 mKernelMemoryStats.clear(); 10559 } 10560 10561 if (mWakeupReasonStats.size() > 0) { 10562 for (SamplingTimer timer : mWakeupReasonStats.values()) { 10563 mOnBatteryTimeBase.remove(timer); 10564 } 10565 mWakeupReasonStats.clear(); 10566 } 10567 10568 mTmpRailStats.reset(); 10569 10570 mLastHistoryStepDetails = null; 10571 mLastStepCpuUserTime = mLastStepCpuSystemTime = 0; 10572 mCurStepCpuUserTime = mCurStepCpuSystemTime = 0; 10573 mLastStepCpuUserTime = mCurStepCpuUserTime = 0; 10574 mLastStepCpuSystemTime = mCurStepCpuSystemTime = 0; 10575 mLastStepStatUserTime = mCurStepStatUserTime = 0; 10576 mLastStepStatSystemTime = mCurStepStatSystemTime = 0; 10577 mLastStepStatIOWaitTime = mCurStepStatIOWaitTime = 0; 10578 mLastStepStatIrqTime = mCurStepStatIrqTime = 0; 10579 mLastStepStatSoftIrqTime = mCurStepStatSoftIrqTime = 0; 10580 mLastStepStatIdleTime = mCurStepStatIdleTime = 0; 10581 10582 mNumAllUidCpuTimeReads = 0; 10583 mNumUidsRemoved = 0; 10584 10585 initDischarge(); 10586 10587 clearHistoryLocked(); 10588 mBatteryStatsHistory.resetAllFiles(); 10589 10590 mHandler.sendEmptyMessage(MSG_REPORT_RESET_STATS); 10591 } 10592 initActiveHistoryEventsLocked(long elapsedRealtimeMs, long uptimeMs)10593 private void initActiveHistoryEventsLocked(long elapsedRealtimeMs, long uptimeMs) { 10594 for (int i=0; i<HistoryItem.EVENT_COUNT; i++) { 10595 if (!mRecordAllHistory && i == HistoryItem.EVENT_PROC) { 10596 // Not recording process starts/stops. 10597 continue; 10598 } 10599 HashMap<String, SparseIntArray> active = mActiveEvents.getStateForEvent(i); 10600 if (active == null) { 10601 continue; 10602 } 10603 for (HashMap.Entry<String, SparseIntArray> ent : active.entrySet()) { 10604 SparseIntArray uids = ent.getValue(); 10605 for (int j=0; j<uids.size(); j++) { 10606 addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, i, ent.getKey(), 10607 uids.keyAt(j)); 10608 } 10609 } 10610 } 10611 } 10612 updateDischargeScreenLevelsLocked(int oldState, int newState)10613 void updateDischargeScreenLevelsLocked(int oldState, int newState) { 10614 updateOldDischargeScreenLevelLocked(oldState); 10615 updateNewDischargeScreenLevelLocked(newState); 10616 } 10617 updateOldDischargeScreenLevelLocked(int state)10618 private void updateOldDischargeScreenLevelLocked(int state) { 10619 if (isScreenOn(state)) { 10620 int diff = mDischargeScreenOnUnplugLevel - mDischargeCurrentLevel; 10621 if (diff > 0) { 10622 mDischargeAmountScreenOn += diff; 10623 mDischargeAmountScreenOnSinceCharge += diff; 10624 } 10625 } else if (isScreenDoze(state)) { 10626 int diff = mDischargeScreenDozeUnplugLevel - mDischargeCurrentLevel; 10627 if (diff > 0) { 10628 mDischargeAmountScreenDoze += diff; 10629 mDischargeAmountScreenDozeSinceCharge += diff; 10630 } 10631 } else if (isScreenOff(state)){ 10632 int diff = mDischargeScreenOffUnplugLevel - mDischargeCurrentLevel; 10633 if (diff > 0) { 10634 mDischargeAmountScreenOff += diff; 10635 mDischargeAmountScreenOffSinceCharge += diff; 10636 } 10637 } 10638 } 10639 updateNewDischargeScreenLevelLocked(int state)10640 private void updateNewDischargeScreenLevelLocked(int state) { 10641 if (isScreenOn(state)) { 10642 mDischargeScreenOnUnplugLevel = mDischargeCurrentLevel; 10643 mDischargeScreenOffUnplugLevel = 0; 10644 mDischargeScreenDozeUnplugLevel = 0; 10645 } else if (isScreenDoze(state)){ 10646 mDischargeScreenOnUnplugLevel = 0; 10647 mDischargeScreenDozeUnplugLevel = mDischargeCurrentLevel; 10648 mDischargeScreenOffUnplugLevel = 0; 10649 } else if (isScreenOff(state)) { 10650 mDischargeScreenOnUnplugLevel = 0; 10651 mDischargeScreenDozeUnplugLevel = 0; 10652 mDischargeScreenOffUnplugLevel = mDischargeCurrentLevel; 10653 } 10654 } 10655 pullPendingStateUpdatesLocked()10656 public void pullPendingStateUpdatesLocked() { 10657 if (mOnBatteryInternal) { 10658 updateDischargeScreenLevelsLocked(mScreenState, mScreenState); 10659 } 10660 } 10661 10662 private final Pools.Pool<NetworkStats> mNetworkStatsPool = new Pools.SynchronizedPool<>(6); 10663 10664 private final Object mWifiNetworkLock = new Object(); 10665 10666 @GuardedBy("mWifiNetworkLock") 10667 private String[] mWifiIfaces = EmptyArray.STRING; 10668 10669 @GuardedBy("mWifiNetworkLock") 10670 private NetworkStats mLastWifiNetworkStats = new NetworkStats(0, -1); 10671 10672 private final Object mModemNetworkLock = new Object(); 10673 10674 @GuardedBy("mModemNetworkLock") 10675 private String[] mModemIfaces = EmptyArray.STRING; 10676 10677 @GuardedBy("mModemNetworkLock") 10678 private NetworkStats mLastModemNetworkStats = new NetworkStats(0, -1); 10679 readNetworkStatsLocked(String[] ifaces)10680 private NetworkStats readNetworkStatsLocked(String[] ifaces) { 10681 try { 10682 if (!ArrayUtils.isEmpty(ifaces)) { 10683 INetworkStatsService statsService = INetworkStatsService.Stub.asInterface( 10684 ServiceManager.getService(Context.NETWORK_STATS_SERVICE)); 10685 if (statsService != null) { 10686 return statsService.getDetailedUidStats(ifaces); 10687 } else { 10688 Slog.e(TAG, "Failed to get networkStatsService "); 10689 } 10690 } 10691 } catch (RemoteException e) { 10692 Slog.e(TAG, "failed to read network stats for ifaces: " + Arrays.toString(ifaces) + e); 10693 } 10694 return null; 10695 } 10696 10697 /** 10698 * Distribute WiFi energy info and network traffic to apps. 10699 * @param info The energy information from the WiFi controller. 10700 */ updateWifiState(@ullable final WifiActivityEnergyInfo info)10701 public void updateWifiState(@Nullable final WifiActivityEnergyInfo info) { 10702 if (DEBUG_ENERGY) { 10703 Slog.d(TAG, "Updating wifi stats: " + Arrays.toString(mWifiIfaces)); 10704 } 10705 10706 // Grab a separate lock to acquire the network stats, which may do I/O. 10707 NetworkStats delta = null; 10708 synchronized (mWifiNetworkLock) { 10709 final NetworkStats latestStats = readNetworkStatsLocked(mWifiIfaces); 10710 if (latestStats != null) { 10711 delta = NetworkStats.subtract(latestStats, mLastWifiNetworkStats, null, null, 10712 mNetworkStatsPool.acquire()); 10713 mNetworkStatsPool.release(mLastWifiNetworkStats); 10714 mLastWifiNetworkStats = latestStats; 10715 } 10716 } 10717 10718 synchronized (this) { 10719 if (!mOnBatteryInternal) { 10720 if (delta != null) { 10721 mNetworkStatsPool.release(delta); 10722 } 10723 return; 10724 } 10725 10726 final long elapsedRealtimeMs = mClocks.elapsedRealtime(); 10727 SparseLongArray rxPackets = new SparseLongArray(); 10728 SparseLongArray txPackets = new SparseLongArray(); 10729 long totalTxPackets = 0; 10730 long totalRxPackets = 0; 10731 if (delta != null) { 10732 NetworkStats.Entry entry = new NetworkStats.Entry(); 10733 final int size = delta.size(); 10734 for (int i = 0; i < size; i++) { 10735 entry = delta.getValues(i, entry); 10736 10737 if (DEBUG_ENERGY) { 10738 Slog.d(TAG, "Wifi uid " + entry.uid + ": delta rx=" + entry.rxBytes 10739 + " tx=" + entry.txBytes + " rxPackets=" + entry.rxPackets 10740 + " txPackets=" + entry.txPackets); 10741 } 10742 10743 if (entry.rxBytes == 0 && entry.txBytes == 0) { 10744 // Skip the lookup below since there is no work to do. 10745 continue; 10746 } 10747 10748 final Uid u = getUidStatsLocked(mapUid(entry.uid)); 10749 if (entry.rxBytes != 0) { 10750 u.noteNetworkActivityLocked(NETWORK_WIFI_RX_DATA, entry.rxBytes, 10751 entry.rxPackets); 10752 if (entry.set == NetworkStats.SET_DEFAULT) { // Background transfers 10753 u.noteNetworkActivityLocked(NETWORK_WIFI_BG_RX_DATA, entry.rxBytes, 10754 entry.rxPackets); 10755 } 10756 mNetworkByteActivityCounters[NETWORK_WIFI_RX_DATA].addCountLocked( 10757 entry.rxBytes); 10758 mNetworkPacketActivityCounters[NETWORK_WIFI_RX_DATA].addCountLocked( 10759 entry.rxPackets); 10760 10761 rxPackets.put(u.getUid(), entry.rxPackets); 10762 10763 // Sum the total number of packets so that the Rx Power can 10764 // be evenly distributed amongst the apps. 10765 totalRxPackets += entry.rxPackets; 10766 } 10767 10768 if (entry.txBytes != 0) { 10769 u.noteNetworkActivityLocked(NETWORK_WIFI_TX_DATA, entry.txBytes, 10770 entry.txPackets); 10771 if (entry.set == NetworkStats.SET_DEFAULT) { // Background transfers 10772 u.noteNetworkActivityLocked(NETWORK_WIFI_BG_TX_DATA, entry.txBytes, 10773 entry.txPackets); 10774 } 10775 mNetworkByteActivityCounters[NETWORK_WIFI_TX_DATA].addCountLocked( 10776 entry.txBytes); 10777 mNetworkPacketActivityCounters[NETWORK_WIFI_TX_DATA].addCountLocked( 10778 entry.txPackets); 10779 10780 txPackets.put(u.getUid(), entry.txPackets); 10781 10782 // Sum the total number of packets so that the Tx Power can 10783 // be evenly distributed amongst the apps. 10784 totalTxPackets += entry.txPackets; 10785 } 10786 } 10787 mNetworkStatsPool.release(delta); 10788 delta = null; 10789 } 10790 10791 if (info != null) { 10792 mHasWifiReporting = true; 10793 10794 // Measured in mAms 10795 final long txTimeMs = info.getControllerTxTimeMillis(); 10796 final long rxTimeMs = info.getControllerRxTimeMillis(); 10797 final long scanTimeMs = info.getControllerScanTimeMillis(); 10798 final long idleTimeMs = info.getControllerIdleTimeMillis(); 10799 final long totalTimeMs = txTimeMs + rxTimeMs + idleTimeMs; 10800 10801 long leftOverRxTimeMs = rxTimeMs; 10802 long leftOverTxTimeMs = txTimeMs; 10803 10804 if (DEBUG_ENERGY) { 10805 Slog.d(TAG, "------ BEGIN WiFi power blaming ------"); 10806 Slog.d(TAG, " Tx Time: " + txTimeMs + " ms"); 10807 Slog.d(TAG, " Rx Time: " + rxTimeMs + " ms"); 10808 Slog.d(TAG, " Idle Time: " + idleTimeMs + " ms"); 10809 Slog.d(TAG, " Total Time: " + totalTimeMs + " ms"); 10810 Slog.d(TAG, " Scan Time: " + scanTimeMs + " ms"); 10811 } 10812 10813 long totalWifiLockTimeMs = 0; 10814 long totalScanTimeMs = 0; 10815 10816 // On the first pass, collect some totals so that we can normalize power 10817 // calculations if we need to. 10818 final int uidStatsSize = mUidStats.size(); 10819 for (int i = 0; i < uidStatsSize; i++) { 10820 final Uid uid = mUidStats.valueAt(i); 10821 10822 // Sum the total scan power for all apps. 10823 totalScanTimeMs += uid.mWifiScanTimer.getTimeSinceMarkLocked( 10824 elapsedRealtimeMs * 1000) / 1000; 10825 10826 // Sum the total time holding wifi lock for all apps. 10827 totalWifiLockTimeMs += uid.mFullWifiLockTimer.getTimeSinceMarkLocked( 10828 elapsedRealtimeMs * 1000) / 1000; 10829 } 10830 10831 if (DEBUG_ENERGY && totalScanTimeMs > rxTimeMs) { 10832 Slog.d(TAG, 10833 " !Estimated scan time > Actual rx time (" + totalScanTimeMs + " ms > " 10834 + rxTimeMs + " ms). Normalizing scan time."); 10835 } 10836 if (DEBUG_ENERGY && totalScanTimeMs > txTimeMs) { 10837 Slog.d(TAG, 10838 " !Estimated scan time > Actual tx time (" + totalScanTimeMs + " ms > " 10839 + txTimeMs + " ms). Normalizing scan time."); 10840 } 10841 10842 // Actually assign and distribute power usage to apps. 10843 for (int i = 0; i < uidStatsSize; i++) { 10844 final Uid uid = mUidStats.valueAt(i); 10845 10846 long scanTimeSinceMarkMs = uid.mWifiScanTimer.getTimeSinceMarkLocked( 10847 elapsedRealtimeMs * 1000) / 1000; 10848 if (scanTimeSinceMarkMs > 0) { 10849 // Set the new mark so that next time we get new data since this point. 10850 uid.mWifiScanTimer.setMark(elapsedRealtimeMs); 10851 10852 long scanRxTimeSinceMarkMs = scanTimeSinceMarkMs; 10853 long scanTxTimeSinceMarkMs = scanTimeSinceMarkMs; 10854 10855 // Our total scan time is more than the reported Tx/Rx time. 10856 // This is possible because the cost of a scan is approximate. 10857 // Let's normalize the result so that we evenly blame each app 10858 // scanning. 10859 // 10860 // This means that we may have apps that transmitted/received packets not be 10861 // blamed for this, but this is fine as scans are relatively more expensive. 10862 if (totalScanTimeMs > rxTimeMs) { 10863 scanRxTimeSinceMarkMs = (rxTimeMs * scanRxTimeSinceMarkMs) / 10864 totalScanTimeMs; 10865 } 10866 if (totalScanTimeMs > txTimeMs) { 10867 scanTxTimeSinceMarkMs = (txTimeMs * scanTxTimeSinceMarkMs) / 10868 totalScanTimeMs; 10869 } 10870 10871 if (DEBUG_ENERGY) { 10872 Slog.d(TAG, " ScanTime for UID " + uid.getUid() + ": Rx:" 10873 + scanRxTimeSinceMarkMs + " ms Tx:" 10874 + scanTxTimeSinceMarkMs + " ms)"); 10875 } 10876 10877 ControllerActivityCounterImpl activityCounter = 10878 uid.getOrCreateWifiControllerActivityLocked(); 10879 activityCounter.getRxTimeCounter().addCountLocked(scanRxTimeSinceMarkMs); 10880 activityCounter.getTxTimeCounters()[0].addCountLocked( 10881 scanTxTimeSinceMarkMs); 10882 leftOverRxTimeMs -= scanRxTimeSinceMarkMs; 10883 leftOverTxTimeMs -= scanTxTimeSinceMarkMs; 10884 } 10885 10886 // Distribute evenly the power consumed while Idle to each app holding a WiFi 10887 // lock. 10888 final long wifiLockTimeSinceMarkMs = 10889 uid.mFullWifiLockTimer.getTimeSinceMarkLocked( 10890 elapsedRealtimeMs * 1000) / 1000; 10891 if (wifiLockTimeSinceMarkMs > 0) { 10892 // Set the new mark so that next time we get new data since this point. 10893 uid.mFullWifiLockTimer.setMark(elapsedRealtimeMs); 10894 10895 final long myIdleTimeMs = (wifiLockTimeSinceMarkMs * idleTimeMs) 10896 / totalWifiLockTimeMs; 10897 if (DEBUG_ENERGY) { 10898 Slog.d(TAG, " IdleTime for UID " + uid.getUid() + ": " 10899 + myIdleTimeMs + " ms"); 10900 } 10901 uid.getOrCreateWifiControllerActivityLocked().getIdleTimeCounter() 10902 .addCountLocked(myIdleTimeMs); 10903 } 10904 } 10905 10906 if (DEBUG_ENERGY) { 10907 Slog.d(TAG, " New RxPower: " + leftOverRxTimeMs + " ms"); 10908 Slog.d(TAG, " New TxPower: " + leftOverTxTimeMs + " ms"); 10909 } 10910 10911 // Distribute the remaining Tx power appropriately between all apps that transmitted 10912 // packets. 10913 for (int i = 0; i < txPackets.size(); i++) { 10914 final Uid uid = getUidStatsLocked(txPackets.keyAt(i)); 10915 final long myTxTimeMs = (txPackets.valueAt(i) * leftOverTxTimeMs) 10916 / totalTxPackets; 10917 if (DEBUG_ENERGY) { 10918 Slog.d(TAG, " TxTime for UID " + uid.getUid() + ": " + myTxTimeMs + " ms"); 10919 } 10920 uid.getOrCreateWifiControllerActivityLocked().getTxTimeCounters()[0] 10921 .addCountLocked(myTxTimeMs); 10922 } 10923 10924 // Distribute the remaining Rx power appropriately between all apps that received 10925 // packets. 10926 for (int i = 0; i < rxPackets.size(); i++) { 10927 final Uid uid = getUidStatsLocked(rxPackets.keyAt(i)); 10928 final long myRxTimeMs = (rxPackets.valueAt(i) * leftOverRxTimeMs) 10929 / totalRxPackets; 10930 if (DEBUG_ENERGY) { 10931 Slog.d(TAG, " RxTime for UID " + uid.getUid() + ": " + myRxTimeMs + " ms"); 10932 } 10933 uid.getOrCreateWifiControllerActivityLocked().getRxTimeCounter() 10934 .addCountLocked(myRxTimeMs); 10935 } 10936 10937 // Any left over power use will be picked up by the WiFi category in BatteryStatsHelper. 10938 10939 10940 // Update WiFi controller stats. 10941 mWifiActivity.getRxTimeCounter().addCountLocked(info.getControllerRxTimeMillis()); 10942 mWifiActivity.getTxTimeCounters()[0].addCountLocked( 10943 info.getControllerTxTimeMillis()); 10944 mWifiActivity.getScanTimeCounter().addCountLocked( 10945 info.getControllerScanTimeMillis()); 10946 mWifiActivity.getIdleTimeCounter().addCountLocked( 10947 info.getControllerIdleTimeMillis()); 10948 10949 // POWER_WIFI_CONTROLLER_OPERATING_VOLTAGE is measured in mV, so convert to V. 10950 final double opVolt = mPowerProfile.getAveragePower( 10951 PowerProfile.POWER_WIFI_CONTROLLER_OPERATING_VOLTAGE) / 1000.0; 10952 if (opVolt != 0) { 10953 // We store the power drain as mAms. 10954 mWifiActivity.getPowerCounter().addCountLocked( 10955 (long) (info.getControllerEnergyUsed() / opVolt)); 10956 } 10957 // Converting uWs to mAms. 10958 // Conversion: (uWs * (1000ms / 1s) * (1mW / 1000uW)) / mV = mAms 10959 long monitoredRailChargeConsumedMaMs = 10960 (long) (mTmpRailStats.getWifiTotalEnergyUseduWs() / opVolt); 10961 mWifiActivity.getMonitoredRailChargeConsumedMaMs().addCountLocked( 10962 monitoredRailChargeConsumedMaMs); 10963 mHistoryCur.wifiRailChargeMah += 10964 (monitoredRailChargeConsumedMaMs / MILLISECONDS_IN_HOUR); 10965 addHistoryRecordLocked(mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 10966 mTmpRailStats.resetWifiTotalEnergyUsed(); 10967 } 10968 } 10969 } 10970 10971 private ModemActivityInfo mLastModemActivityInfo = 10972 new ModemActivityInfo(0, 0, 0, new int[0], 0, 0); 10973 getDeltaModemActivityInfo(ModemActivityInfo activityInfo)10974 private ModemActivityInfo getDeltaModemActivityInfo(ModemActivityInfo activityInfo) { 10975 if (activityInfo == null) { 10976 return null; 10977 } 10978 int[] txTimeMs = new int[ModemActivityInfo.TX_POWER_LEVELS]; 10979 for (int i = 0; i < ModemActivityInfo.TX_POWER_LEVELS; i++) { 10980 txTimeMs[i] = activityInfo.getTxTimeMillis()[i] 10981 - mLastModemActivityInfo.getTxTimeMillis()[i]; 10982 } 10983 ModemActivityInfo deltaInfo = new ModemActivityInfo(activityInfo.getTimestamp(), 10984 activityInfo.getSleepTimeMillis() - mLastModemActivityInfo.getSleepTimeMillis(), 10985 activityInfo.getIdleTimeMillis() - mLastModemActivityInfo.getIdleTimeMillis(), 10986 txTimeMs, 10987 activityInfo.getRxTimeMillis() - mLastModemActivityInfo.getRxTimeMillis(), 10988 activityInfo.getEnergyUsed() - mLastModemActivityInfo.getEnergyUsed()); 10989 mLastModemActivityInfo = activityInfo; 10990 return deltaInfo; 10991 } 10992 10993 /** 10994 * Distribute Cell radio energy info and network traffic to apps. 10995 */ updateMobileRadioState(@ullable final ModemActivityInfo activityInfo)10996 public void updateMobileRadioState(@Nullable final ModemActivityInfo activityInfo) { 10997 if (DEBUG_ENERGY) { 10998 Slog.d(TAG, "Updating mobile radio stats with " + activityInfo); 10999 } 11000 ModemActivityInfo deltaInfo = getDeltaModemActivityInfo(activityInfo); 11001 11002 // Add modem tx power to history. 11003 addModemTxPowerToHistory(deltaInfo); 11004 11005 // Grab a separate lock to acquire the network stats, which may do I/O. 11006 NetworkStats delta = null; 11007 synchronized (mModemNetworkLock) { 11008 final NetworkStats latestStats = readNetworkStatsLocked(mModemIfaces); 11009 if (latestStats != null) { 11010 delta = NetworkStats.subtract(latestStats, mLastModemNetworkStats, null, null, 11011 mNetworkStatsPool.acquire()); 11012 mNetworkStatsPool.release(mLastModemNetworkStats); 11013 mLastModemNetworkStats = latestStats; 11014 } 11015 } 11016 11017 synchronized (this) { 11018 if (!mOnBatteryInternal) { 11019 if (delta != null) { 11020 mNetworkStatsPool.release(delta); 11021 } 11022 return; 11023 } 11024 11025 if (deltaInfo != null) { 11026 mHasModemReporting = true; 11027 mModemActivity.getIdleTimeCounter().addCountLocked( 11028 deltaInfo.getIdleTimeMillis()); 11029 mModemActivity.getSleepTimeCounter().addCountLocked( 11030 deltaInfo.getSleepTimeMillis()); 11031 mModemActivity.getRxTimeCounter().addCountLocked(deltaInfo.getRxTimeMillis()); 11032 for (int lvl = 0; lvl < ModemActivityInfo.TX_POWER_LEVELS; lvl++) { 11033 mModemActivity.getTxTimeCounters()[lvl] 11034 .addCountLocked(deltaInfo.getTxTimeMillis()[lvl]); 11035 } 11036 11037 // POWER_MODEM_CONTROLLER_OPERATING_VOLTAGE is measured in mV, so convert to V. 11038 final double opVolt = mPowerProfile.getAveragePower( 11039 PowerProfile.POWER_MODEM_CONTROLLER_OPERATING_VOLTAGE) / 1000.0; 11040 if (opVolt != 0) { 11041 double energyUsed = 11042 deltaInfo.getSleepTimeMillis() * 11043 mPowerProfile.getAveragePower(PowerProfile.POWER_MODEM_CONTROLLER_SLEEP) 11044 + deltaInfo.getIdleTimeMillis() * 11045 mPowerProfile.getAveragePower(PowerProfile.POWER_MODEM_CONTROLLER_IDLE) 11046 + deltaInfo.getRxTimeMillis() * 11047 mPowerProfile.getAveragePower(PowerProfile.POWER_MODEM_CONTROLLER_RX); 11048 int[] txTimeMs = deltaInfo.getTxTimeMillis(); 11049 for (int i = 0; i < Math.min(txTimeMs.length, 11050 SignalStrength.NUM_SIGNAL_STRENGTH_BINS); i++) { 11051 energyUsed += txTimeMs[i] * mPowerProfile.getAveragePower( 11052 PowerProfile.POWER_MODEM_CONTROLLER_TX, i); 11053 } 11054 11055 // We store the power drain as mAms. 11056 mModemActivity.getPowerCounter().addCountLocked((long) energyUsed); 11057 // Converting uWs to mAms. 11058 // Conversion: (uWs * (1000ms / 1s) * (1mW / 1000uW)) / mV = mAms 11059 long monitoredRailChargeConsumedMaMs = 11060 (long) (mTmpRailStats.getCellularTotalEnergyUseduWs() / opVolt); 11061 mModemActivity.getMonitoredRailChargeConsumedMaMs().addCountLocked( 11062 monitoredRailChargeConsumedMaMs); 11063 mHistoryCur.modemRailChargeMah += 11064 (monitoredRailChargeConsumedMaMs / MILLISECONDS_IN_HOUR); 11065 addHistoryRecordLocked(mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 11066 mTmpRailStats.resetCellularTotalEnergyUsed(); 11067 } 11068 } 11069 final long elapsedRealtimeMs = mClocks.elapsedRealtime(); 11070 long radioTime = mMobileRadioActivePerAppTimer.getTimeSinceMarkLocked( 11071 elapsedRealtimeMs * 1000); 11072 mMobileRadioActivePerAppTimer.setMark(elapsedRealtimeMs); 11073 11074 long totalRxPackets = 0; 11075 long totalTxPackets = 0; 11076 if (delta != null) { 11077 NetworkStats.Entry entry = new NetworkStats.Entry(); 11078 final int size = delta.size(); 11079 for (int i = 0; i < size; i++) { 11080 entry = delta.getValues(i, entry); 11081 if (entry.rxPackets == 0 && entry.txPackets == 0) { 11082 continue; 11083 } 11084 11085 if (DEBUG_ENERGY) { 11086 Slog.d(TAG, "Mobile uid " + entry.uid + ": delta rx=" + entry.rxBytes 11087 + " tx=" + entry.txBytes + " rxPackets=" + entry.rxPackets 11088 + " txPackets=" + entry.txPackets); 11089 } 11090 11091 totalRxPackets += entry.rxPackets; 11092 totalTxPackets += entry.txPackets; 11093 11094 final Uid u = getUidStatsLocked(mapUid(entry.uid)); 11095 u.noteNetworkActivityLocked(NETWORK_MOBILE_RX_DATA, entry.rxBytes, 11096 entry.rxPackets); 11097 u.noteNetworkActivityLocked(NETWORK_MOBILE_TX_DATA, entry.txBytes, 11098 entry.txPackets); 11099 if (entry.set == NetworkStats.SET_DEFAULT) { // Background transfers 11100 u.noteNetworkActivityLocked(NETWORK_MOBILE_BG_RX_DATA, 11101 entry.rxBytes, entry.rxPackets); 11102 u.noteNetworkActivityLocked(NETWORK_MOBILE_BG_TX_DATA, 11103 entry.txBytes, entry.txPackets); 11104 } 11105 11106 mNetworkByteActivityCounters[NETWORK_MOBILE_RX_DATA].addCountLocked( 11107 entry.rxBytes); 11108 mNetworkByteActivityCounters[NETWORK_MOBILE_TX_DATA].addCountLocked( 11109 entry.txBytes); 11110 mNetworkPacketActivityCounters[NETWORK_MOBILE_RX_DATA].addCountLocked( 11111 entry.rxPackets); 11112 mNetworkPacketActivityCounters[NETWORK_MOBILE_TX_DATA].addCountLocked( 11113 entry.txPackets); 11114 } 11115 11116 // Now distribute proportional blame to the apps that did networking. 11117 long totalPackets = totalRxPackets + totalTxPackets; 11118 if (totalPackets > 0) { 11119 for (int i = 0; i < size; i++) { 11120 entry = delta.getValues(i, entry); 11121 if (entry.rxPackets == 0 && entry.txPackets == 0) { 11122 continue; 11123 } 11124 11125 final Uid u = getUidStatsLocked(mapUid(entry.uid)); 11126 11127 // Distribute total radio active time in to this app. 11128 final long appPackets = entry.rxPackets + entry.txPackets; 11129 final long appRadioTime = (radioTime * appPackets) / totalPackets; 11130 u.noteMobileRadioActiveTimeLocked(appRadioTime); 11131 11132 // Remove this app from the totals, so that we don't lose any time 11133 // due to rounding. 11134 radioTime -= appRadioTime; 11135 totalPackets -= appPackets; 11136 11137 if (deltaInfo != null) { 11138 ControllerActivityCounterImpl activityCounter = 11139 u.getOrCreateModemControllerActivityLocked(); 11140 if (totalRxPackets > 0 && entry.rxPackets > 0) { 11141 final long rxMs = (entry.rxPackets * deltaInfo.getRxTimeMillis()) 11142 / totalRxPackets; 11143 activityCounter.getRxTimeCounter().addCountLocked(rxMs); 11144 } 11145 11146 if (totalTxPackets > 0 && entry.txPackets > 0) { 11147 for (int lvl = 0; lvl < ModemActivityInfo.TX_POWER_LEVELS; lvl++) { 11148 long txMs = 11149 entry.txPackets * deltaInfo.getTxTimeMillis()[lvl]; 11150 txMs /= totalTxPackets; 11151 activityCounter.getTxTimeCounters()[lvl].addCountLocked(txMs); 11152 } 11153 } 11154 } 11155 } 11156 } 11157 11158 if (radioTime > 0) { 11159 // Whoops, there is some radio time we can't blame on an app! 11160 mMobileRadioActiveUnknownTime.addCountLocked(radioTime); 11161 mMobileRadioActiveUnknownCount.addCountLocked(1); 11162 } 11163 11164 mNetworkStatsPool.release(delta); 11165 delta = null; 11166 } 11167 } 11168 } 11169 11170 /** 11171 * Add modem tx power to history 11172 * Device is said to be in high cellular transmit power when it has spent most of the transmit 11173 * time at the highest power level. 11174 * @param activityInfo 11175 */ addModemTxPowerToHistory(final ModemActivityInfo activityInfo)11176 private synchronized void addModemTxPowerToHistory(final ModemActivityInfo activityInfo) { 11177 if (activityInfo == null) { 11178 return; 11179 } 11180 int[] txTimeMs = activityInfo.getTxTimeMillis(); 11181 if (txTimeMs == null || txTimeMs.length != ModemActivityInfo.TX_POWER_LEVELS) { 11182 return; 11183 } 11184 final long elapsedRealtime = mClocks.elapsedRealtime(); 11185 final long uptime = mClocks.uptimeMillis(); 11186 int levelMaxTimeSpent = 0; 11187 for (int i = 1; i < txTimeMs.length; i++) { 11188 if (txTimeMs[i] > txTimeMs[levelMaxTimeSpent]) { 11189 levelMaxTimeSpent = i; 11190 } 11191 } 11192 if (levelMaxTimeSpent == ModemActivityInfo.TX_POWER_LEVELS - 1) { 11193 if (!mIsCellularTxPowerHigh) { 11194 mHistoryCur.states2 |= HistoryItem.STATE2_CELLULAR_HIGH_TX_POWER_FLAG; 11195 addHistoryRecordLocked(elapsedRealtime, uptime); 11196 mIsCellularTxPowerHigh = true; 11197 } 11198 return; 11199 } 11200 if (mIsCellularTxPowerHigh) { 11201 mHistoryCur.states2 &= ~HistoryItem.STATE2_CELLULAR_HIGH_TX_POWER_FLAG; 11202 addHistoryRecordLocked(elapsedRealtime, uptime); 11203 mIsCellularTxPowerHigh = false; 11204 } 11205 return; 11206 } 11207 11208 private final class BluetoothActivityInfoCache { 11209 long idleTimeMs; 11210 long rxTimeMs; 11211 long txTimeMs; 11212 long energy; 11213 11214 SparseLongArray uidRxBytes = new SparseLongArray(); 11215 SparseLongArray uidTxBytes = new SparseLongArray(); 11216 set(BluetoothActivityEnergyInfo info)11217 void set(BluetoothActivityEnergyInfo info) { 11218 idleTimeMs = info.getControllerIdleTimeMillis(); 11219 rxTimeMs = info.getControllerRxTimeMillis(); 11220 txTimeMs = info.getControllerTxTimeMillis(); 11221 energy = info.getControllerEnergyUsed(); 11222 if (info.getUidTraffic() != null) { 11223 for (UidTraffic traffic : info.getUidTraffic()) { 11224 uidRxBytes.put(traffic.getUid(), traffic.getRxBytes()); 11225 uidTxBytes.put(traffic.getUid(), traffic.getTxBytes()); 11226 } 11227 } 11228 } 11229 } 11230 11231 private final BluetoothActivityInfoCache mLastBluetoothActivityInfo 11232 = new BluetoothActivityInfoCache(); 11233 11234 /** 11235 * Distribute Bluetooth energy info and network traffic to apps. 11236 * 11237 * @param info The energy information from the bluetooth controller. 11238 */ updateBluetoothStateLocked(@ullable final BluetoothActivityEnergyInfo info)11239 public void updateBluetoothStateLocked(@Nullable final BluetoothActivityEnergyInfo info) { 11240 if (DEBUG_ENERGY) { 11241 Slog.d(TAG, "Updating bluetooth stats: " + info); 11242 } 11243 11244 if (info == null || !mOnBatteryInternal) { 11245 return; 11246 } 11247 11248 mHasBluetoothReporting = true; 11249 11250 final long elapsedRealtimeMs = mClocks.elapsedRealtime(); 11251 final long rxTimeMs = 11252 info.getControllerRxTimeMillis() - mLastBluetoothActivityInfo.rxTimeMs; 11253 final long txTimeMs = 11254 info.getControllerTxTimeMillis() - mLastBluetoothActivityInfo.txTimeMs; 11255 final long idleTimeMs = 11256 info.getControllerIdleTimeMillis() - mLastBluetoothActivityInfo.idleTimeMs; 11257 11258 if (DEBUG_ENERGY) { 11259 Slog.d(TAG, "------ BEGIN BLE power blaming ------"); 11260 Slog.d(TAG, " Tx Time: " + txTimeMs + " ms"); 11261 Slog.d(TAG, " Rx Time: " + rxTimeMs + " ms"); 11262 Slog.d(TAG, " Idle Time: " + idleTimeMs + " ms"); 11263 } 11264 11265 long totalScanTimeMs = 0; 11266 11267 final int uidCount = mUidStats.size(); 11268 for (int i = 0; i < uidCount; i++) { 11269 final Uid u = mUidStats.valueAt(i); 11270 if (u.mBluetoothScanTimer == null) { 11271 continue; 11272 } 11273 11274 totalScanTimeMs += u.mBluetoothScanTimer.getTimeSinceMarkLocked( 11275 elapsedRealtimeMs * 1000) / 1000; 11276 } 11277 11278 final boolean normalizeScanRxTime = (totalScanTimeMs > rxTimeMs); 11279 final boolean normalizeScanTxTime = (totalScanTimeMs > txTimeMs); 11280 11281 if (DEBUG_ENERGY) { 11282 Slog.d(TAG, "Normalizing scan power for RX=" + normalizeScanRxTime 11283 + " TX=" + normalizeScanTxTime); 11284 } 11285 11286 long leftOverRxTimeMs = rxTimeMs; 11287 long leftOverTxTimeMs = txTimeMs; 11288 11289 for (int i = 0; i < uidCount; i++) { 11290 final Uid u = mUidStats.valueAt(i); 11291 if (u.mBluetoothScanTimer == null) { 11292 continue; 11293 } 11294 11295 long scanTimeSinceMarkMs = u.mBluetoothScanTimer.getTimeSinceMarkLocked( 11296 elapsedRealtimeMs * 1000) / 1000; 11297 if (scanTimeSinceMarkMs > 0) { 11298 // Set the new mark so that next time we get new data since this point. 11299 u.mBluetoothScanTimer.setMark(elapsedRealtimeMs); 11300 11301 long scanTimeRxSinceMarkMs = scanTimeSinceMarkMs; 11302 long scanTimeTxSinceMarkMs = scanTimeSinceMarkMs; 11303 11304 if (normalizeScanRxTime) { 11305 // Scan time is longer than the total rx time in the controller, 11306 // so distribute the scan time proportionately. This means regular traffic 11307 // will not blamed, but scans are more expensive anyways. 11308 scanTimeRxSinceMarkMs = (rxTimeMs * scanTimeRxSinceMarkMs) / totalScanTimeMs; 11309 } 11310 11311 if (normalizeScanTxTime) { 11312 // Scan time is longer than the total tx time in the controller, 11313 // so distribute the scan time proportionately. This means regular traffic 11314 // will not blamed, but scans are more expensive anyways. 11315 scanTimeTxSinceMarkMs = (txTimeMs * scanTimeTxSinceMarkMs) / totalScanTimeMs; 11316 } 11317 11318 final ControllerActivityCounterImpl counter = 11319 u.getOrCreateBluetoothControllerActivityLocked(); 11320 counter.getRxTimeCounter().addCountLocked(scanTimeRxSinceMarkMs); 11321 counter.getTxTimeCounters()[0].addCountLocked(scanTimeTxSinceMarkMs); 11322 11323 leftOverRxTimeMs -= scanTimeRxSinceMarkMs; 11324 leftOverTxTimeMs -= scanTimeTxSinceMarkMs; 11325 } 11326 } 11327 11328 if (DEBUG_ENERGY) { 11329 Slog.d(TAG, "Left over time for traffic RX=" + leftOverRxTimeMs + " TX=" 11330 + leftOverTxTimeMs); 11331 } 11332 11333 // 11334 // Now distribute blame to apps that did bluetooth traffic. 11335 // 11336 11337 long totalTxBytes = 0; 11338 long totalRxBytes = 0; 11339 11340 final UidTraffic[] uidTraffic = info.getUidTraffic(); 11341 final int numUids = uidTraffic != null ? uidTraffic.length : 0; 11342 for (int i = 0; i < numUids; i++) { 11343 final UidTraffic traffic = uidTraffic[i]; 11344 final long rxBytes = traffic.getRxBytes() - mLastBluetoothActivityInfo.uidRxBytes.get( 11345 traffic.getUid()); 11346 final long txBytes = traffic.getTxBytes() - mLastBluetoothActivityInfo.uidTxBytes.get( 11347 traffic.getUid()); 11348 11349 // Add to the global counters. 11350 mNetworkByteActivityCounters[NETWORK_BT_RX_DATA].addCountLocked(rxBytes); 11351 mNetworkByteActivityCounters[NETWORK_BT_TX_DATA].addCountLocked(txBytes); 11352 11353 // Add to the UID counters. 11354 final Uid u = getUidStatsLocked(mapUid(traffic.getUid())); 11355 u.noteNetworkActivityLocked(NETWORK_BT_RX_DATA, rxBytes, 0); 11356 u.noteNetworkActivityLocked(NETWORK_BT_TX_DATA, txBytes, 0); 11357 11358 // Calculate the total traffic. 11359 totalRxBytes += rxBytes; 11360 totalTxBytes += txBytes; 11361 } 11362 11363 if ((totalTxBytes != 0 || totalRxBytes != 0) && (leftOverRxTimeMs != 0 11364 || leftOverTxTimeMs != 0)) { 11365 for (int i = 0; i < numUids; i++) { 11366 final UidTraffic traffic = uidTraffic[i]; 11367 final int uid = traffic.getUid(); 11368 final long rxBytes = 11369 traffic.getRxBytes() - mLastBluetoothActivityInfo.uidRxBytes.get(uid); 11370 final long txBytes = 11371 traffic.getTxBytes() - mLastBluetoothActivityInfo.uidTxBytes.get(uid); 11372 11373 final Uid u = getUidStatsLocked(mapUid(uid)); 11374 final ControllerActivityCounterImpl counter = 11375 u.getOrCreateBluetoothControllerActivityLocked(); 11376 11377 if (totalRxBytes > 0 && rxBytes > 0) { 11378 final long timeRxMs = (leftOverRxTimeMs * rxBytes) / totalRxBytes; 11379 if (DEBUG_ENERGY) { 11380 Slog.d(TAG, "UID=" + uid + " rx_bytes=" + rxBytes + " rx_time=" + timeRxMs); 11381 } 11382 counter.getRxTimeCounter().addCountLocked(timeRxMs); 11383 } 11384 11385 if (totalTxBytes > 0 && txBytes > 0) { 11386 final long timeTxMs = (leftOverTxTimeMs * txBytes) / totalTxBytes; 11387 if (DEBUG_ENERGY) { 11388 Slog.d(TAG, "UID=" + uid + " tx_bytes=" + txBytes + " tx_time=" + timeTxMs); 11389 } 11390 counter.getTxTimeCounters()[0].addCountLocked(timeTxMs); 11391 } 11392 } 11393 } 11394 11395 mBluetoothActivity.getRxTimeCounter().addCountLocked(rxTimeMs); 11396 mBluetoothActivity.getTxTimeCounters()[0].addCountLocked(txTimeMs); 11397 mBluetoothActivity.getIdleTimeCounter().addCountLocked(idleTimeMs); 11398 11399 // POWER_BLUETOOTH_CONTROLLER_OPERATING_VOLTAGE is measured in mV, so convert to V. 11400 final double opVolt = mPowerProfile.getAveragePower( 11401 PowerProfile.POWER_BLUETOOTH_CONTROLLER_OPERATING_VOLTAGE) / 1000.0; 11402 if (opVolt != 0) { 11403 // We store the power drain as mAms. 11404 mBluetoothActivity.getPowerCounter().addCountLocked( 11405 (long) ((info.getControllerEnergyUsed() - mLastBluetoothActivityInfo.energy) 11406 / opVolt)); 11407 } 11408 mLastBluetoothActivityInfo.set(info); 11409 } 11410 11411 /** 11412 * Read and record Resource Power Manager (RPM) state and voter times. 11413 * If RPM stats were fetched more recently than RPM_STATS_UPDATE_FREQ_MS ago, uses the old data 11414 * instead of fetching it anew. 11415 */ updateRpmStatsLocked()11416 public void updateRpmStatsLocked() { 11417 if (mPlatformIdleStateCallback == null) return; 11418 long now = SystemClock.elapsedRealtime(); 11419 if (now - mLastRpmStatsUpdateTimeMs >= RPM_STATS_UPDATE_FREQ_MS) { 11420 mPlatformIdleStateCallback.fillLowPowerStats(mTmpRpmStats); 11421 mLastRpmStatsUpdateTimeMs = now; 11422 } 11423 11424 for (Map.Entry<String, RpmStats.PowerStatePlatformSleepState> pstate 11425 : mTmpRpmStats.mPlatformLowPowerStats.entrySet()) { 11426 11427 // Update values for this platform state. 11428 final String pName = pstate.getKey(); 11429 final long pTimeUs = pstate.getValue().mTimeMs * 1000; 11430 final int pCount = pstate.getValue().mCount; 11431 getRpmTimerLocked(pName).update(pTimeUs, pCount); 11432 if (SCREEN_OFF_RPM_STATS_ENABLED) { 11433 getScreenOffRpmTimerLocked(pName).update(pTimeUs, pCount); 11434 } 11435 11436 // Update values for each voter of this platform state. 11437 for (Map.Entry<String, RpmStats.PowerStateElement> voter 11438 : pstate.getValue().mVoters.entrySet()) { 11439 final String vName = pName + "." + voter.getKey(); 11440 final long vTimeUs = voter.getValue().mTimeMs * 1000; 11441 final int vCount = voter.getValue().mCount; 11442 getRpmTimerLocked(vName).update(vTimeUs, vCount); 11443 if (SCREEN_OFF_RPM_STATS_ENABLED) { 11444 getScreenOffRpmTimerLocked(vName).update(vTimeUs, vCount); 11445 } 11446 } 11447 } 11448 11449 for (Map.Entry<String, RpmStats.PowerStateSubsystem> subsys 11450 : mTmpRpmStats.mSubsystemLowPowerStats.entrySet()) { 11451 11452 final String subsysName = subsys.getKey(); 11453 for (Map.Entry<String, RpmStats.PowerStateElement> sstate 11454 : subsys.getValue().mStates.entrySet()) { 11455 final String name = subsysName + "." + sstate.getKey(); 11456 final long timeUs = sstate.getValue().mTimeMs * 1000; 11457 final int count = sstate.getValue().mCount; 11458 getRpmTimerLocked(name).update(timeUs, count); 11459 if (SCREEN_OFF_RPM_STATS_ENABLED) { 11460 getScreenOffRpmTimerLocked(name).update(timeUs, count); 11461 } 11462 } 11463 } 11464 } 11465 11466 /** 11467 * Read and record Rail Energy data. 11468 */ updateRailStatsLocked()11469 public void updateRailStatsLocked() { 11470 if (mRailEnergyDataCallback == null || !mTmpRailStats.isRailStatsAvailable()) { 11471 return; 11472 } 11473 mRailEnergyDataCallback.fillRailDataStats(mTmpRailStats); 11474 } 11475 11476 /** 11477 * Read and distribute kernel wake lock use across apps. 11478 */ updateKernelWakelocksLocked()11479 public void updateKernelWakelocksLocked() { 11480 final KernelWakelockStats wakelockStats = mKernelWakelockReader.readKernelWakelockStats( 11481 mTmpWakelockStats); 11482 if (wakelockStats == null) { 11483 // Not crashing might make board bringup easier. 11484 Slog.w(TAG, "Couldn't get kernel wake lock stats"); 11485 return; 11486 } 11487 11488 for (Map.Entry<String, KernelWakelockStats.Entry> ent : wakelockStats.entrySet()) { 11489 String name = ent.getKey(); 11490 KernelWakelockStats.Entry kws = ent.getValue(); 11491 11492 SamplingTimer kwlt = mKernelWakelockStats.get(name); 11493 if (kwlt == null) { 11494 kwlt = new SamplingTimer(mClocks, mOnBatteryScreenOffTimeBase); 11495 mKernelWakelockStats.put(name, kwlt); 11496 } 11497 11498 kwlt.update(kws.mTotalTime, kws.mCount); 11499 kwlt.setUpdateVersion(kws.mVersion); 11500 } 11501 11502 int numWakelocksSetStale = 0; 11503 // Set timers to stale if they didn't appear in /d/wakeup_sources (or /proc/wakelocks) 11504 // this time. 11505 for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) { 11506 SamplingTimer st = ent.getValue(); 11507 if (st.getUpdateVersion() != wakelockStats.kernelWakelockVersion) { 11508 st.endSample(); 11509 numWakelocksSetStale++; 11510 } 11511 } 11512 11513 // Record whether we've seen a non-zero time (for debugging b/22716723). 11514 if (wakelockStats.isEmpty()) { 11515 Slog.wtf(TAG, "All kernel wakelocks had time of zero"); 11516 } 11517 11518 if (numWakelocksSetStale == mKernelWakelockStats.size()) { 11519 Slog.wtf(TAG, "All kernel wakelocks were set stale. new version=" + 11520 wakelockStats.kernelWakelockVersion); 11521 } 11522 } 11523 11524 // We use an anonymous class to access these variables, 11525 // so they can't live on the stack or they'd have to be 11526 // final MutableLong objects (more allocations). 11527 // Used in updateCpuTimeLocked(). 11528 long mTempTotalCpuUserTimeUs; 11529 long mTempTotalCpuSystemTimeUs; 11530 long[][] mWakeLockAllocationsUs; 11531 11532 /** 11533 * Reads the newest memory stats from the kernel. 11534 */ updateKernelMemoryBandwidthLocked()11535 public void updateKernelMemoryBandwidthLocked() { 11536 mKernelMemoryBandwidthStats.updateStats(); 11537 LongSparseLongArray bandwidthEntries = mKernelMemoryBandwidthStats.getBandwidthEntries(); 11538 final int bandwidthEntryCount = bandwidthEntries.size(); 11539 int index; 11540 for (int i = 0; i < bandwidthEntryCount; i++) { 11541 SamplingTimer timer; 11542 if ((index = mKernelMemoryStats.indexOfKey(bandwidthEntries.keyAt(i))) >= 0) { 11543 timer = mKernelMemoryStats.valueAt(index); 11544 } else { 11545 timer = new SamplingTimer(mClocks, mOnBatteryTimeBase); 11546 mKernelMemoryStats.put(bandwidthEntries.keyAt(i), timer); 11547 } 11548 timer.update(bandwidthEntries.valueAt(i), 1); 11549 if (DEBUG_MEMORY) { 11550 Slog.d(TAG, String.format("Added entry %d and updated timer to: " 11551 + "mUnpluggedReportedTotalTime %d size %d", bandwidthEntries.keyAt(i), 11552 mKernelMemoryStats.get( 11553 bandwidthEntries.keyAt(i)).mUnpluggedReportedTotalTime, 11554 mKernelMemoryStats.size())); 11555 } 11556 } 11557 } 11558 isOnBatteryLocked()11559 public boolean isOnBatteryLocked() { 11560 return mOnBatteryTimeBase.isRunning(); 11561 } 11562 isOnBatteryScreenOffLocked()11563 public boolean isOnBatteryScreenOffLocked() { 11564 return mOnBatteryScreenOffTimeBase.isRunning(); 11565 } 11566 11567 /** 11568 * Read and distribute CPU usage across apps. If their are partial wakelocks being held 11569 * and we are on battery with screen off, we give more of the cpu time to those apps holding 11570 * wakelocks. If the screen is on, we just assign the actual cpu time an app used. 11571 * It's possible this will be invoked after the internal battery/screen states are updated, so 11572 * passing the appropriate battery/screen states to try attribute the cpu times to correct 11573 * buckets. 11574 */ 11575 @GuardedBy("this") updateCpuTimeLocked(boolean onBattery, boolean onBatteryScreenOff)11576 public void updateCpuTimeLocked(boolean onBattery, boolean onBatteryScreenOff) { 11577 if (mPowerProfile == null) { 11578 return; 11579 } 11580 11581 if (DEBUG_ENERGY_CPU) { 11582 Slog.d(TAG, "!Cpu updating!"); 11583 } 11584 11585 if (mCpuFreqs == null) { 11586 mCpuFreqs = mCpuUidFreqTimeReader.readFreqs(mPowerProfile); 11587 } 11588 11589 // Calculate the wakelocks we have to distribute amongst. The system is excluded as it is 11590 // usually holding the wakelock on behalf of an app. 11591 // And Only distribute cpu power to wakelocks if the screen is off and we're on battery. 11592 ArrayList<StopwatchTimer> partialTimersToConsider = null; 11593 if (onBatteryScreenOff) { 11594 partialTimersToConsider = new ArrayList<>(); 11595 for (int i = mPartialTimers.size() - 1; i >= 0; --i) { 11596 final StopwatchTimer timer = mPartialTimers.get(i); 11597 // Since the collection and blaming of wakelocks can be scheduled to run after 11598 // some delay, the mPartialTimers list may have new entries. We can't blame 11599 // the newly added timer for past cpu time, so we only consider timers that 11600 // were present for one round of collection. Once a timer has gone through 11601 // a round of collection, its mInList field is set to true. 11602 if (timer.mInList && timer.mUid != null && timer.mUid.mUid != Process.SYSTEM_UID) { 11603 partialTimersToConsider.add(timer); 11604 } 11605 } 11606 } 11607 markPartialTimersAsEligible(); 11608 11609 // When the battery is not on, we don't attribute the cpu times to any timers but we still 11610 // need to take the snapshots. 11611 if (!onBattery) { 11612 mCpuUidUserSysTimeReader.readDelta(null); 11613 mCpuUidFreqTimeReader.readDelta(null); 11614 mNumAllUidCpuTimeReads += 2; 11615 if (mConstants.TRACK_CPU_ACTIVE_CLUSTER_TIME) { 11616 mCpuUidActiveTimeReader.readDelta(null); 11617 mCpuUidClusterTimeReader.readDelta(null); 11618 mNumAllUidCpuTimeReads += 2; 11619 } 11620 for (int cluster = mKernelCpuSpeedReaders.length - 1; cluster >= 0; --cluster) { 11621 mKernelCpuSpeedReaders[cluster].readDelta(); 11622 } 11623 return; 11624 } 11625 11626 mUserInfoProvider.refreshUserIds(); 11627 final SparseLongArray updatedUids = mCpuUidFreqTimeReader.perClusterTimesAvailable() 11628 ? null : new SparseLongArray(); 11629 readKernelUidCpuTimesLocked(partialTimersToConsider, updatedUids, onBattery); 11630 // updatedUids=null means /proc/uid_time_in_state provides snapshots of per-cluster cpu 11631 // freqs, so no need to approximate these values. 11632 if (updatedUids != null) { 11633 updateClusterSpeedTimes(updatedUids, onBattery); 11634 } 11635 readKernelUidCpuFreqTimesLocked(partialTimersToConsider, onBattery, onBatteryScreenOff); 11636 mNumAllUidCpuTimeReads += 2; 11637 if (mConstants.TRACK_CPU_ACTIVE_CLUSTER_TIME) { 11638 readKernelUidCpuActiveTimesLocked(onBattery); 11639 readKernelUidCpuClusterTimesLocked(onBattery); 11640 mNumAllUidCpuTimeReads += 2; 11641 } 11642 } 11643 11644 /** 11645 * Mark the current partial timers as gone through a collection so that they will be 11646 * considered in the next cpu times distribution to wakelock holders. 11647 */ 11648 @VisibleForTesting markPartialTimersAsEligible()11649 public void markPartialTimersAsEligible() { 11650 if (ArrayUtils.referenceEquals(mPartialTimers, mLastPartialTimers)) { 11651 // No difference, so each timer is now considered for the next collection. 11652 for (int i = mPartialTimers.size() - 1; i >= 0; --i) { 11653 mPartialTimers.get(i).mInList = true; 11654 } 11655 } else { 11656 // The lists are different, meaning we added (or removed a timer) since the last 11657 // collection. 11658 for (int i = mLastPartialTimers.size() - 1; i >= 0; --i) { 11659 mLastPartialTimers.get(i).mInList = false; 11660 } 11661 mLastPartialTimers.clear(); 11662 11663 // Mark the current timers as gone through a collection. 11664 final int numPartialTimers = mPartialTimers.size(); 11665 for (int i = 0; i < numPartialTimers; ++i) { 11666 final StopwatchTimer timer = mPartialTimers.get(i); 11667 timer.mInList = true; 11668 mLastPartialTimers.add(timer); 11669 } 11670 } 11671 } 11672 11673 /** 11674 * Take snapshot of cpu times (aggregated over all uids) at different frequencies and 11675 * calculate cpu times spent by each uid at different frequencies. 11676 * 11677 * @param updatedUids The uids for which times spent at different frequencies are calculated. 11678 */ 11679 @VisibleForTesting updateClusterSpeedTimes(@onNull SparseLongArray updatedUids, boolean onBattery)11680 public void updateClusterSpeedTimes(@NonNull SparseLongArray updatedUids, boolean onBattery) { 11681 long totalCpuClustersTimeMs = 0; 11682 // Read the time spent for each cluster at various cpu frequencies. 11683 final long[][] clusterSpeedTimesMs = new long[mKernelCpuSpeedReaders.length][]; 11684 for (int cluster = 0; cluster < mKernelCpuSpeedReaders.length; cluster++) { 11685 clusterSpeedTimesMs[cluster] = mKernelCpuSpeedReaders[cluster].readDelta(); 11686 if (clusterSpeedTimesMs[cluster] != null) { 11687 for (int speed = clusterSpeedTimesMs[cluster].length - 1; speed >= 0; --speed) { 11688 totalCpuClustersTimeMs += clusterSpeedTimesMs[cluster][speed]; 11689 } 11690 } 11691 } 11692 if (totalCpuClustersTimeMs != 0) { 11693 // We have cpu times per freq aggregated over all uids but we need the times per uid. 11694 // So, we distribute total time spent by an uid to different cpu freqs based on the 11695 // amount of time cpu was running at that freq. 11696 final int updatedUidsCount = updatedUids.size(); 11697 for (int i = 0; i < updatedUidsCount; ++i) { 11698 final Uid u = getUidStatsLocked(updatedUids.keyAt(i)); 11699 final long appCpuTimeUs = updatedUids.valueAt(i); 11700 // Add the cpu speeds to this UID. 11701 final int numClusters = mPowerProfile.getNumCpuClusters(); 11702 if (u.mCpuClusterSpeedTimesUs == null || 11703 u.mCpuClusterSpeedTimesUs.length != numClusters) { 11704 u.mCpuClusterSpeedTimesUs = new LongSamplingCounter[numClusters][]; 11705 } 11706 11707 for (int cluster = 0; cluster < clusterSpeedTimesMs.length; cluster++) { 11708 final int speedsInCluster = clusterSpeedTimesMs[cluster].length; 11709 if (u.mCpuClusterSpeedTimesUs[cluster] == null || speedsInCluster != 11710 u.mCpuClusterSpeedTimesUs[cluster].length) { 11711 u.mCpuClusterSpeedTimesUs[cluster] 11712 = new LongSamplingCounter[speedsInCluster]; 11713 } 11714 11715 final LongSamplingCounter[] cpuSpeeds = u.mCpuClusterSpeedTimesUs[cluster]; 11716 for (int speed = 0; speed < speedsInCluster; speed++) { 11717 if (cpuSpeeds[speed] == null) { 11718 cpuSpeeds[speed] = new LongSamplingCounter(mOnBatteryTimeBase); 11719 } 11720 cpuSpeeds[speed].addCountLocked(appCpuTimeUs 11721 * clusterSpeedTimesMs[cluster][speed] 11722 / totalCpuClustersTimeMs, onBattery); 11723 } 11724 } 11725 } 11726 } 11727 } 11728 11729 /** 11730 * Take a snapshot of the cpu times spent by each uid and update the corresponding counters. 11731 * If {@param partialTimers} is not null and empty, then we assign a portion of cpu times to 11732 * wakelock holders. 11733 * 11734 * @param partialTimers The wakelock holders among which the cpu times will be distributed. 11735 * @param updatedUids If not null, then the uids found in the snapshot will be added to this. 11736 */ 11737 @VisibleForTesting readKernelUidCpuTimesLocked(@ullable ArrayList<StopwatchTimer> partialTimers, @Nullable SparseLongArray updatedUids, boolean onBattery)11738 public void readKernelUidCpuTimesLocked(@Nullable ArrayList<StopwatchTimer> partialTimers, 11739 @Nullable SparseLongArray updatedUids, boolean onBattery) { 11740 mTempTotalCpuUserTimeUs = mTempTotalCpuSystemTimeUs = 0; 11741 final int numWakelocks = partialTimers == null ? 0 : partialTimers.size(); 11742 final long startTimeMs = mClocks.uptimeMillis(); 11743 11744 mCpuUidUserSysTimeReader.readDelta((uid, timesUs) -> { 11745 long userTimeUs = timesUs[0], systemTimeUs = timesUs[1]; 11746 11747 uid = mapUid(uid); 11748 if (Process.isIsolated(uid)) { 11749 // This could happen if the isolated uid mapping was removed before that process 11750 // was actually killed. 11751 mCpuUidUserSysTimeReader.removeUid(uid); 11752 Slog.d(TAG, "Got readings for an isolated uid with no mapping: " + uid); 11753 return; 11754 } 11755 if (!mUserInfoProvider.exists(UserHandle.getUserId(uid))) { 11756 Slog.d(TAG, "Got readings for an invalid user's uid " + uid); 11757 mCpuUidUserSysTimeReader.removeUid(uid); 11758 return; 11759 } 11760 final Uid u = getUidStatsLocked(uid); 11761 11762 // Accumulate the total system and user time. 11763 mTempTotalCpuUserTimeUs += userTimeUs; 11764 mTempTotalCpuSystemTimeUs += systemTimeUs; 11765 11766 StringBuilder sb = null; 11767 if (DEBUG_ENERGY_CPU) { 11768 sb = new StringBuilder(); 11769 sb.append(" got time for uid=").append(u.mUid).append(": u="); 11770 TimeUtils.formatDuration(userTimeUs / 1000, sb); 11771 sb.append(" s="); 11772 TimeUtils.formatDuration(systemTimeUs / 1000, sb); 11773 sb.append("\n"); 11774 } 11775 11776 if (numWakelocks > 0) { 11777 // We have wakelocks being held, so only give a portion of the 11778 // time to the process. The rest will be distributed among wakelock 11779 // holders. 11780 userTimeUs = (userTimeUs * WAKE_LOCK_WEIGHT) / 100; 11781 systemTimeUs = (systemTimeUs * WAKE_LOCK_WEIGHT) / 100; 11782 } 11783 11784 if (sb != null) { 11785 sb.append(" adding to uid=").append(u.mUid).append(": u="); 11786 TimeUtils.formatDuration(userTimeUs / 1000, sb); 11787 sb.append(" s="); 11788 TimeUtils.formatDuration(systemTimeUs / 1000, sb); 11789 Slog.d(TAG, sb.toString()); 11790 } 11791 11792 u.mUserCpuTime.addCountLocked(userTimeUs, onBattery); 11793 u.mSystemCpuTime.addCountLocked(systemTimeUs, onBattery); 11794 if (updatedUids != null) { 11795 updatedUids.put(u.getUid(), userTimeUs + systemTimeUs); 11796 } 11797 }); 11798 11799 final long elapsedTimeMs = mClocks.uptimeMillis() - startTimeMs; 11800 if (DEBUG_ENERGY_CPU || elapsedTimeMs >= 100) { 11801 Slog.d(TAG, "Reading cpu stats took " + elapsedTimeMs + "ms"); 11802 } 11803 11804 if (numWakelocks > 0) { 11805 // Distribute a portion of the total cpu time to wakelock holders. 11806 mTempTotalCpuUserTimeUs = (mTempTotalCpuUserTimeUs * (100 - WAKE_LOCK_WEIGHT)) / 100; 11807 mTempTotalCpuSystemTimeUs = 11808 (mTempTotalCpuSystemTimeUs * (100 - WAKE_LOCK_WEIGHT)) / 100; 11809 11810 for (int i = 0; i < numWakelocks; ++i) { 11811 final StopwatchTimer timer = partialTimers.get(i); 11812 final int userTimeUs = (int) (mTempTotalCpuUserTimeUs / (numWakelocks - i)); 11813 final int systemTimeUs = (int) (mTempTotalCpuSystemTimeUs / (numWakelocks - i)); 11814 11815 if (DEBUG_ENERGY_CPU) { 11816 final StringBuilder sb = new StringBuilder(); 11817 sb.append(" Distributing wakelock uid=").append(timer.mUid.mUid) 11818 .append(": u="); 11819 TimeUtils.formatDuration(userTimeUs / 1000, sb); 11820 sb.append(" s="); 11821 TimeUtils.formatDuration(systemTimeUs / 1000, sb); 11822 Slog.d(TAG, sb.toString()); 11823 } 11824 11825 timer.mUid.mUserCpuTime.addCountLocked(userTimeUs, onBattery); 11826 timer.mUid.mSystemCpuTime.addCountLocked(systemTimeUs, onBattery); 11827 if (updatedUids != null) { 11828 final int uid = timer.mUid.getUid(); 11829 updatedUids.put(uid, updatedUids.get(uid, 0) + userTimeUs + systemTimeUs); 11830 } 11831 11832 final Uid.Proc proc = timer.mUid.getProcessStatsLocked("*wakelock*"); 11833 proc.addCpuTimeLocked(userTimeUs / 1000, systemTimeUs / 1000, onBattery); 11834 11835 mTempTotalCpuUserTimeUs -= userTimeUs; 11836 mTempTotalCpuSystemTimeUs -= systemTimeUs; 11837 } 11838 } 11839 } 11840 11841 /** 11842 * Take a snapshot of the cpu times spent by each uid in each freq and update the 11843 * corresponding counters. 11844 * 11845 * @param partialTimers The wakelock holders among which the cpu freq times will be distributed. 11846 */ 11847 @VisibleForTesting readKernelUidCpuFreqTimesLocked(@ullable ArrayList<StopwatchTimer> partialTimers, boolean onBattery, boolean onBatteryScreenOff)11848 public void readKernelUidCpuFreqTimesLocked(@Nullable ArrayList<StopwatchTimer> partialTimers, 11849 boolean onBattery, boolean onBatteryScreenOff) { 11850 final boolean perClusterTimesAvailable = 11851 mCpuUidFreqTimeReader.perClusterTimesAvailable(); 11852 final int numWakelocks = partialTimers == null ? 0 : partialTimers.size(); 11853 final int numClusters = mPowerProfile.getNumCpuClusters(); 11854 mWakeLockAllocationsUs = null; 11855 final long startTimeMs = mClocks.uptimeMillis(); 11856 mCpuUidFreqTimeReader.readDelta((uid, cpuFreqTimeMs) -> { 11857 uid = mapUid(uid); 11858 if (Process.isIsolated(uid)) { 11859 mCpuUidFreqTimeReader.removeUid(uid); 11860 Slog.d(TAG, "Got freq readings for an isolated uid with no mapping: " + uid); 11861 return; 11862 } 11863 if (!mUserInfoProvider.exists(UserHandle.getUserId(uid))) { 11864 Slog.d(TAG, "Got freq readings for an invalid user's uid " + uid); 11865 mCpuUidFreqTimeReader.removeUid(uid); 11866 return; 11867 } 11868 final Uid u = getUidStatsLocked(uid); 11869 if (u.mCpuFreqTimeMs == null || u.mCpuFreqTimeMs.getSize() != cpuFreqTimeMs.length) { 11870 detachIfNotNull(u.mCpuFreqTimeMs); 11871 u.mCpuFreqTimeMs = new LongSamplingCounterArray(mOnBatteryTimeBase); 11872 } 11873 u.mCpuFreqTimeMs.addCountLocked(cpuFreqTimeMs, onBattery); 11874 if (u.mScreenOffCpuFreqTimeMs == null || 11875 u.mScreenOffCpuFreqTimeMs.getSize() != cpuFreqTimeMs.length) { 11876 detachIfNotNull(u.mScreenOffCpuFreqTimeMs); 11877 u.mScreenOffCpuFreqTimeMs = new LongSamplingCounterArray( 11878 mOnBatteryScreenOffTimeBase); 11879 } 11880 u.mScreenOffCpuFreqTimeMs.addCountLocked(cpuFreqTimeMs, onBatteryScreenOff); 11881 11882 if (perClusterTimesAvailable) { 11883 if (u.mCpuClusterSpeedTimesUs == null || 11884 u.mCpuClusterSpeedTimesUs.length != numClusters) { 11885 detachIfNotNull(u.mCpuClusterSpeedTimesUs); 11886 u.mCpuClusterSpeedTimesUs = new LongSamplingCounter[numClusters][]; 11887 } 11888 if (numWakelocks > 0 && mWakeLockAllocationsUs == null) { 11889 mWakeLockAllocationsUs = new long[numClusters][]; 11890 } 11891 11892 int freqIndex = 0; 11893 for (int cluster = 0; cluster < numClusters; ++cluster) { 11894 final int speedsInCluster = mPowerProfile.getNumSpeedStepsInCpuCluster(cluster); 11895 if (u.mCpuClusterSpeedTimesUs[cluster] == null || 11896 u.mCpuClusterSpeedTimesUs[cluster].length != speedsInCluster) { 11897 detachIfNotNull(u.mCpuClusterSpeedTimesUs[cluster]); 11898 u.mCpuClusterSpeedTimesUs[cluster] 11899 = new LongSamplingCounter[speedsInCluster]; 11900 } 11901 if (numWakelocks > 0 && mWakeLockAllocationsUs[cluster] == null) { 11902 mWakeLockAllocationsUs[cluster] = new long[speedsInCluster]; 11903 } 11904 final LongSamplingCounter[] cpuTimesUs = u.mCpuClusterSpeedTimesUs[cluster]; 11905 for (int speed = 0; speed < speedsInCluster; ++speed) { 11906 if (cpuTimesUs[speed] == null) { 11907 cpuTimesUs[speed] = new LongSamplingCounter(mOnBatteryTimeBase); 11908 } 11909 final long appAllocationUs; 11910 if (mWakeLockAllocationsUs != null) { 11911 appAllocationUs = 11912 (cpuFreqTimeMs[freqIndex] * 1000 * WAKE_LOCK_WEIGHT) / 100; 11913 mWakeLockAllocationsUs[cluster][speed] += 11914 (cpuFreqTimeMs[freqIndex] * 1000 - appAllocationUs); 11915 } else { 11916 appAllocationUs = cpuFreqTimeMs[freqIndex] * 1000; 11917 } 11918 cpuTimesUs[speed].addCountLocked(appAllocationUs, onBattery); 11919 freqIndex++; 11920 } 11921 } 11922 } 11923 }); 11924 11925 final long elapsedTimeMs = mClocks.uptimeMillis() - startTimeMs; 11926 if (DEBUG_ENERGY_CPU || elapsedTimeMs >= 100) { 11927 Slog.d(TAG, "Reading cpu freq times took " + elapsedTimeMs + "ms"); 11928 } 11929 11930 if (mWakeLockAllocationsUs != null) { 11931 for (int i = 0; i < numWakelocks; ++i) { 11932 final Uid u = partialTimers.get(i).mUid; 11933 if (u.mCpuClusterSpeedTimesUs == null || 11934 u.mCpuClusterSpeedTimesUs.length != numClusters) { 11935 detachIfNotNull(u.mCpuClusterSpeedTimesUs); 11936 u.mCpuClusterSpeedTimesUs = new LongSamplingCounter[numClusters][]; 11937 } 11938 11939 for (int cluster = 0; cluster < numClusters; ++cluster) { 11940 final int speedsInCluster = mPowerProfile.getNumSpeedStepsInCpuCluster(cluster); 11941 if (u.mCpuClusterSpeedTimesUs[cluster] == null || 11942 u.mCpuClusterSpeedTimesUs[cluster].length != speedsInCluster) { 11943 detachIfNotNull(u.mCpuClusterSpeedTimesUs[cluster]); 11944 u.mCpuClusterSpeedTimesUs[cluster] 11945 = new LongSamplingCounter[speedsInCluster]; 11946 } 11947 final LongSamplingCounter[] cpuTimeUs = u.mCpuClusterSpeedTimesUs[cluster]; 11948 for (int speed = 0; speed < speedsInCluster; ++speed) { 11949 if (cpuTimeUs[speed] == null) { 11950 cpuTimeUs[speed] = new LongSamplingCounter(mOnBatteryTimeBase); 11951 } 11952 final long allocationUs = 11953 mWakeLockAllocationsUs[cluster][speed] / (numWakelocks - i); 11954 cpuTimeUs[speed].addCountLocked(allocationUs, onBattery); 11955 mWakeLockAllocationsUs[cluster][speed] -= allocationUs; 11956 } 11957 } 11958 } 11959 } 11960 } 11961 11962 /** 11963 * Take a snapshot of the cpu active times spent by each uid and update the corresponding 11964 * counters. 11965 */ 11966 @VisibleForTesting readKernelUidCpuActiveTimesLocked(boolean onBattery)11967 public void readKernelUidCpuActiveTimesLocked(boolean onBattery) { 11968 final long startTimeMs = mClocks.uptimeMillis(); 11969 mCpuUidActiveTimeReader.readDelta((uid, cpuActiveTimesMs) -> { 11970 uid = mapUid(uid); 11971 if (Process.isIsolated(uid)) { 11972 mCpuUidActiveTimeReader.removeUid(uid); 11973 Slog.w(TAG, "Got active times for an isolated uid with no mapping: " + uid); 11974 return; 11975 } 11976 if (!mUserInfoProvider.exists(UserHandle.getUserId(uid))) { 11977 Slog.w(TAG, "Got active times for an invalid user's uid " + uid); 11978 mCpuUidActiveTimeReader.removeUid(uid); 11979 return; 11980 } 11981 final Uid u = getUidStatsLocked(uid); 11982 u.mCpuActiveTimeMs.addCountLocked(cpuActiveTimesMs, onBattery); 11983 }); 11984 11985 final long elapsedTimeMs = mClocks.uptimeMillis() - startTimeMs; 11986 if (DEBUG_ENERGY_CPU || elapsedTimeMs >= 100) { 11987 Slog.d(TAG, "Reading cpu active times took " + elapsedTimeMs + "ms"); 11988 } 11989 } 11990 11991 /** 11992 * Take a snapshot of the cpu cluster times spent by each uid and update the corresponding 11993 * counters. 11994 */ 11995 @VisibleForTesting readKernelUidCpuClusterTimesLocked(boolean onBattery)11996 public void readKernelUidCpuClusterTimesLocked(boolean onBattery) { 11997 final long startTimeMs = mClocks.uptimeMillis(); 11998 mCpuUidClusterTimeReader.readDelta((uid, cpuClusterTimesMs) -> { 11999 uid = mapUid(uid); 12000 if (Process.isIsolated(uid)) { 12001 mCpuUidClusterTimeReader.removeUid(uid); 12002 Slog.w(TAG, "Got cluster times for an isolated uid with no mapping: " + uid); 12003 return; 12004 } 12005 if (!mUserInfoProvider.exists(UserHandle.getUserId(uid))) { 12006 Slog.w(TAG, "Got cluster times for an invalid user's uid " + uid); 12007 mCpuUidClusterTimeReader.removeUid(uid); 12008 return; 12009 } 12010 final Uid u = getUidStatsLocked(uid); 12011 u.mCpuClusterTimesMs.addCountLocked(cpuClusterTimesMs, onBattery); 12012 }); 12013 12014 final long elapsedTimeMs = mClocks.uptimeMillis() - startTimeMs; 12015 if (DEBUG_ENERGY_CPU || elapsedTimeMs >= 100) { 12016 Slog.d(TAG, "Reading cpu cluster times took " + elapsedTimeMs + "ms"); 12017 } 12018 } 12019 setChargingLocked(boolean charging)12020 boolean setChargingLocked(boolean charging) { 12021 // if the device is no longer charging, remove the callback 12022 // if the device is now charging, it means that this is either called 12023 // 1. directly when level >= 90 12024 // 2. or from within the runnable that we deferred 12025 // For 1. if we have an existing callback, remove it, since we will immediately send a 12026 // ACTION_CHARGING 12027 // For 2. we remove existing callback so we don't send multiple ACTION_CHARGING 12028 mHandler.removeCallbacks(mDeferSetCharging); 12029 if (mCharging != charging) { 12030 mCharging = charging; 12031 if (charging) { 12032 mHistoryCur.states2 |= HistoryItem.STATE2_CHARGING_FLAG; 12033 } else { 12034 mHistoryCur.states2 &= ~HistoryItem.STATE2_CHARGING_FLAG; 12035 } 12036 mHandler.sendEmptyMessage(MSG_REPORT_CHARGING); 12037 return true; 12038 } 12039 return false; 12040 } 12041 12042 @GuardedBy("this") setOnBatteryLocked(final long mSecRealtime, final long mSecUptime, final boolean onBattery, final int oldStatus, final int level, final int chargeUAh)12043 protected void setOnBatteryLocked(final long mSecRealtime, final long mSecUptime, 12044 final boolean onBattery, final int oldStatus, final int level, final int chargeUAh) { 12045 boolean doWrite = false; 12046 Message m = mHandler.obtainMessage(MSG_REPORT_POWER_CHANGE); 12047 m.arg1 = onBattery ? 1 : 0; 12048 mHandler.sendMessage(m); 12049 12050 final long uptime = mSecUptime * 1000; 12051 final long realtime = mSecRealtime * 1000; 12052 final int screenState = mScreenState; 12053 if (onBattery) { 12054 // We will reset our status if we are unplugging after the 12055 // battery was last full, or the level is at 100, or 12056 // we have gone through a significant charge (from a very low 12057 // level to a now very high level). 12058 boolean reset = false; 12059 if (!mNoAutoReset && (oldStatus == BatteryManager.BATTERY_STATUS_FULL 12060 || level >= 90 12061 || (mDischargeCurrentLevel < 20 && level >= 80))) { 12062 Slog.i(TAG, "Resetting battery stats: level=" + level + " status=" + oldStatus 12063 + " dischargeLevel=" + mDischargeCurrentLevel 12064 + " lowAmount=" + getLowDischargeAmountSinceCharge() 12065 + " highAmount=" + getHighDischargeAmountSinceCharge()); 12066 // Before we write, collect a snapshot of the final aggregated 12067 // stats to be reported in the next checkin. Only do this if we have 12068 // a sufficient amount of data to make it interesting. 12069 if (getLowDischargeAmountSinceCharge() >= 20) { 12070 final long startTime = SystemClock.uptimeMillis(); 12071 final Parcel parcel = Parcel.obtain(); 12072 writeSummaryToParcel(parcel, true); 12073 final long initialTime = SystemClock.uptimeMillis() - startTime; 12074 BackgroundThread.getHandler().post(new Runnable() { 12075 @Override public void run() { 12076 synchronized (mCheckinFile) { 12077 final long startTime2 = SystemClock.uptimeMillis(); 12078 FileOutputStream stream = null; 12079 try { 12080 stream = mCheckinFile.startWrite(); 12081 stream.write(parcel.marshall()); 12082 stream.flush(); 12083 mCheckinFile.finishWrite(stream); 12084 com.android.internal.logging.EventLogTags.writeCommitSysConfigFile( 12085 "batterystats-checkin", 12086 initialTime + SystemClock.uptimeMillis() - startTime2); 12087 } catch (IOException e) { 12088 Slog.w("BatteryStats", 12089 "Error writing checkin battery statistics", e); 12090 mCheckinFile.failWrite(stream); 12091 } finally { 12092 parcel.recycle(); 12093 } 12094 } 12095 } 12096 }); 12097 } 12098 doWrite = true; 12099 resetAllStatsLocked(); 12100 if (chargeUAh > 0 && level > 0) { 12101 // Only use the reported coulomb charge value if it is supported and reported. 12102 mEstimatedBatteryCapacity = (int) ((chargeUAh / 1000) / (level / 100.0)); 12103 } 12104 mDischargeStartLevel = level; 12105 reset = true; 12106 mDischargeStepTracker.init(); 12107 } 12108 if (mCharging) { 12109 setChargingLocked(false); 12110 } 12111 mLastChargingStateLevel = level; 12112 mOnBattery = mOnBatteryInternal = true; 12113 mLastDischargeStepLevel = level; 12114 mMinDischargeStepLevel = level; 12115 mDischargeStepTracker.clearTime(); 12116 mDailyDischargeStepTracker.clearTime(); 12117 mInitStepMode = mCurStepMode; 12118 mModStepMode = 0; 12119 pullPendingStateUpdatesLocked(); 12120 mHistoryCur.batteryLevel = (byte)level; 12121 mHistoryCur.states &= ~HistoryItem.STATE_BATTERY_PLUGGED_FLAG; 12122 if (DEBUG_HISTORY) Slog.v(TAG, "Battery unplugged to: " 12123 + Integer.toHexString(mHistoryCur.states)); 12124 if (reset) { 12125 mRecordingHistory = true; 12126 startRecordingHistory(mSecRealtime, mSecUptime, reset); 12127 } 12128 addHistoryRecordLocked(mSecRealtime, mSecUptime); 12129 mDischargeCurrentLevel = mDischargeUnplugLevel = level; 12130 if (isScreenOn(screenState)) { 12131 mDischargeScreenOnUnplugLevel = level; 12132 mDischargeScreenDozeUnplugLevel = 0; 12133 mDischargeScreenOffUnplugLevel = 0; 12134 } else if (isScreenDoze(screenState)) { 12135 mDischargeScreenOnUnplugLevel = 0; 12136 mDischargeScreenDozeUnplugLevel = level; 12137 mDischargeScreenOffUnplugLevel = 0; 12138 } else { 12139 mDischargeScreenOnUnplugLevel = 0; 12140 mDischargeScreenDozeUnplugLevel = 0; 12141 mDischargeScreenOffUnplugLevel = level; 12142 } 12143 mDischargeAmountScreenOn = 0; 12144 mDischargeAmountScreenDoze = 0; 12145 mDischargeAmountScreenOff = 0; 12146 updateTimeBasesLocked(true, screenState, uptime, realtime); 12147 } else { 12148 mLastChargingStateLevel = level; 12149 mOnBattery = mOnBatteryInternal = false; 12150 pullPendingStateUpdatesLocked(); 12151 mHistoryCur.batteryLevel = (byte)level; 12152 mHistoryCur.states |= HistoryItem.STATE_BATTERY_PLUGGED_FLAG; 12153 if (DEBUG_HISTORY) Slog.v(TAG, "Battery plugged to: " 12154 + Integer.toHexString(mHistoryCur.states)); 12155 addHistoryRecordLocked(mSecRealtime, mSecUptime); 12156 mDischargeCurrentLevel = mDischargePlugLevel = level; 12157 if (level < mDischargeUnplugLevel) { 12158 mLowDischargeAmountSinceCharge += mDischargeUnplugLevel-level-1; 12159 mHighDischargeAmountSinceCharge += mDischargeUnplugLevel-level; 12160 } 12161 updateDischargeScreenLevelsLocked(screenState, screenState); 12162 updateTimeBasesLocked(false, screenState, uptime, realtime); 12163 mChargeStepTracker.init(); 12164 mLastChargeStepLevel = level; 12165 mMaxChargeStepLevel = level; 12166 mInitStepMode = mCurStepMode; 12167 mModStepMode = 0; 12168 } 12169 if (doWrite || (mLastWriteTime + (60 * 1000)) < mSecRealtime) { 12170 if (mStatsFile != null && mBatteryStatsHistory.getActiveFile() != null) { 12171 writeAsyncLocked(); 12172 } 12173 } 12174 } 12175 startRecordingHistory(final long elapsedRealtimeMs, final long uptimeMs, boolean reset)12176 private void startRecordingHistory(final long elapsedRealtimeMs, final long uptimeMs, 12177 boolean reset) { 12178 mRecordingHistory = true; 12179 mHistoryCur.currentTime = System.currentTimeMillis(); 12180 addHistoryBufferLocked(elapsedRealtimeMs, 12181 reset ? HistoryItem.CMD_RESET : HistoryItem.CMD_CURRENT_TIME, 12182 mHistoryCur); 12183 mHistoryCur.currentTime = 0; 12184 if (reset) { 12185 initActiveHistoryEventsLocked(elapsedRealtimeMs, uptimeMs); 12186 } 12187 } 12188 recordCurrentTimeChangeLocked(final long currentTime, final long elapsedRealtimeMs, final long uptimeMs)12189 private void recordCurrentTimeChangeLocked(final long currentTime, final long elapsedRealtimeMs, 12190 final long uptimeMs) { 12191 if (mRecordingHistory) { 12192 mHistoryCur.currentTime = currentTime; 12193 addHistoryBufferLocked(elapsedRealtimeMs, HistoryItem.CMD_CURRENT_TIME, mHistoryCur); 12194 mHistoryCur.currentTime = 0; 12195 } 12196 } 12197 recordShutdownLocked(final long elapsedRealtimeMs, final long uptimeMs)12198 private void recordShutdownLocked(final long elapsedRealtimeMs, final long uptimeMs) { 12199 if (mRecordingHistory) { 12200 mHistoryCur.currentTime = System.currentTimeMillis(); 12201 addHistoryBufferLocked(elapsedRealtimeMs, HistoryItem.CMD_SHUTDOWN, mHistoryCur); 12202 mHistoryCur.currentTime = 0; 12203 } 12204 } 12205 scheduleSyncExternalStatsLocked(String reason, int updateFlags)12206 private void scheduleSyncExternalStatsLocked(String reason, int updateFlags) { 12207 if (mExternalSync != null) { 12208 mExternalSync.scheduleSync(reason, updateFlags); 12209 } 12210 } 12211 12212 // This should probably be exposed in the API, though it's not critical 12213 public static final int BATTERY_PLUGGED_NONE = OsProtoEnums.BATTERY_PLUGGED_NONE; // = 0 12214 12215 @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)12216 public void setBatteryStateLocked(final int status, final int health, final int plugType, 12217 final int level, /* not final */ int temp, final int volt, final int chargeUAh, 12218 final int chargeFullUAh) { 12219 // Temperature is encoded without the signed bit, so clamp any negative temperatures to 0. 12220 temp = Math.max(0, temp); 12221 12222 reportChangesToStatsLog(mHaveBatteryLevel ? mHistoryCur : null, 12223 status, plugType, level); 12224 12225 final boolean onBattery = isOnBattery(plugType, status); 12226 final long uptime = mClocks.uptimeMillis(); 12227 final long elapsedRealtime = mClocks.elapsedRealtime(); 12228 if (!mHaveBatteryLevel) { 12229 mHaveBatteryLevel = true; 12230 // We start out assuming that the device is plugged in (not 12231 // on battery). If our first report is now that we are indeed 12232 // plugged in, then twiddle our state to correctly reflect that 12233 // since we won't be going through the full setOnBattery(). 12234 if (onBattery == mOnBattery) { 12235 if (onBattery) { 12236 mHistoryCur.states &= ~HistoryItem.STATE_BATTERY_PLUGGED_FLAG; 12237 } else { 12238 mHistoryCur.states |= HistoryItem.STATE_BATTERY_PLUGGED_FLAG; 12239 } 12240 } 12241 // Always start out assuming charging, that will be updated later. 12242 mHistoryCur.states2 |= HistoryItem.STATE2_CHARGING_FLAG; 12243 mHistoryCur.batteryStatus = (byte)status; 12244 mHistoryCur.batteryLevel = (byte)level; 12245 mHistoryCur.batteryChargeUAh = chargeUAh; 12246 mMaxChargeStepLevel = mMinDischargeStepLevel = 12247 mLastChargeStepLevel = mLastDischargeStepLevel = level; 12248 mLastChargingStateLevel = level; 12249 } else if (mCurrentBatteryLevel != level || mOnBattery != onBattery) { 12250 recordDailyStatsIfNeededLocked(level >= 100 && onBattery); 12251 } 12252 int oldStatus = mHistoryCur.batteryStatus; 12253 if (onBattery) { 12254 mDischargeCurrentLevel = level; 12255 if (!mRecordingHistory) { 12256 mRecordingHistory = true; 12257 startRecordingHistory(elapsedRealtime, uptime, true); 12258 } 12259 } else if (level < 96 && 12260 status != BatteryManager.BATTERY_STATUS_UNKNOWN) { 12261 if (!mRecordingHistory) { 12262 mRecordingHistory = true; 12263 startRecordingHistory(elapsedRealtime, uptime, true); 12264 } 12265 } 12266 mCurrentBatteryLevel = level; 12267 if (mDischargePlugLevel < 0) { 12268 mDischargePlugLevel = level; 12269 } 12270 12271 if (onBattery != mOnBattery) { 12272 mHistoryCur.batteryLevel = (byte)level; 12273 mHistoryCur.batteryStatus = (byte)status; 12274 mHistoryCur.batteryHealth = (byte)health; 12275 mHistoryCur.batteryPlugType = (byte)plugType; 12276 mHistoryCur.batteryTemperature = (short)temp; 12277 mHistoryCur.batteryVoltage = (char)volt; 12278 if (chargeUAh < mHistoryCur.batteryChargeUAh) { 12279 // Only record discharges 12280 final long chargeDiff = mHistoryCur.batteryChargeUAh - chargeUAh; 12281 mDischargeCounter.addCountLocked(chargeDiff); 12282 mDischargeScreenOffCounter.addCountLocked(chargeDiff); 12283 if (isScreenDoze(mScreenState)) { 12284 mDischargeScreenDozeCounter.addCountLocked(chargeDiff); 12285 } 12286 if (mDeviceIdleMode == DEVICE_IDLE_MODE_LIGHT) { 12287 mDischargeLightDozeCounter.addCountLocked(chargeDiff); 12288 } else if (mDeviceIdleMode == DEVICE_IDLE_MODE_DEEP) { 12289 mDischargeDeepDozeCounter.addCountLocked(chargeDiff); 12290 } 12291 } 12292 mHistoryCur.batteryChargeUAh = chargeUAh; 12293 setOnBatteryLocked(elapsedRealtime, uptime, onBattery, oldStatus, level, chargeUAh); 12294 } else { 12295 boolean changed = false; 12296 if (mHistoryCur.batteryLevel != level) { 12297 mHistoryCur.batteryLevel = (byte)level; 12298 changed = true; 12299 12300 // TODO(adamlesinski): Schedule the creation of a HistoryStepDetails record 12301 // which will pull external stats. 12302 mExternalSync.scheduleSyncDueToBatteryLevelChange( 12303 mConstants.BATTERY_LEVEL_COLLECTION_DELAY_MS); 12304 } 12305 if (mHistoryCur.batteryStatus != status) { 12306 mHistoryCur.batteryStatus = (byte)status; 12307 changed = true; 12308 } 12309 if (mHistoryCur.batteryHealth != health) { 12310 mHistoryCur.batteryHealth = (byte)health; 12311 changed = true; 12312 } 12313 if (mHistoryCur.batteryPlugType != plugType) { 12314 mHistoryCur.batteryPlugType = (byte)plugType; 12315 changed = true; 12316 } 12317 if (temp >= (mHistoryCur.batteryTemperature+10) 12318 || temp <= (mHistoryCur.batteryTemperature-10)) { 12319 mHistoryCur.batteryTemperature = (short)temp; 12320 changed = true; 12321 } 12322 if (volt > (mHistoryCur.batteryVoltage+20) 12323 || volt < (mHistoryCur.batteryVoltage-20)) { 12324 mHistoryCur.batteryVoltage = (char)volt; 12325 changed = true; 12326 } 12327 if (chargeUAh >= (mHistoryCur.batteryChargeUAh+10) 12328 || chargeUAh <= (mHistoryCur.batteryChargeUAh-10)) { 12329 if (chargeUAh < mHistoryCur.batteryChargeUAh) { 12330 // Only record discharges 12331 final long chargeDiff = mHistoryCur.batteryChargeUAh - chargeUAh; 12332 mDischargeCounter.addCountLocked(chargeDiff); 12333 mDischargeScreenOffCounter.addCountLocked(chargeDiff); 12334 if (isScreenDoze(mScreenState)) { 12335 mDischargeScreenDozeCounter.addCountLocked(chargeDiff); 12336 } 12337 if (mDeviceIdleMode == DEVICE_IDLE_MODE_LIGHT) { 12338 mDischargeLightDozeCounter.addCountLocked(chargeDiff); 12339 } else if (mDeviceIdleMode == DEVICE_IDLE_MODE_DEEP) { 12340 mDischargeDeepDozeCounter.addCountLocked(chargeDiff); 12341 } 12342 } 12343 mHistoryCur.batteryChargeUAh = chargeUAh; 12344 changed = true; 12345 } 12346 long modeBits = (((long)mInitStepMode) << STEP_LEVEL_INITIAL_MODE_SHIFT) 12347 | (((long)mModStepMode) << STEP_LEVEL_MODIFIED_MODE_SHIFT) 12348 | (((long)(level&0xff)) << STEP_LEVEL_LEVEL_SHIFT); 12349 if (onBattery) { 12350 changed |= setChargingLocked(false); 12351 if (mLastDischargeStepLevel != level && mMinDischargeStepLevel > level) { 12352 mDischargeStepTracker.addLevelSteps(mLastDischargeStepLevel - level, 12353 modeBits, elapsedRealtime); 12354 mDailyDischargeStepTracker.addLevelSteps(mLastDischargeStepLevel - level, 12355 modeBits, elapsedRealtime); 12356 mLastDischargeStepLevel = level; 12357 mMinDischargeStepLevel = level; 12358 mInitStepMode = mCurStepMode; 12359 mModStepMode = 0; 12360 } 12361 } else { 12362 if (level >= 90) { 12363 // If the battery level is at least 90%, always consider the device to be 12364 // charging even if it happens to go down a level. 12365 changed |= setChargingLocked(true); 12366 } else if (!mCharging) { 12367 if (mLastChargeStepLevel < level) { 12368 // We have not reported that we are charging, but the level has gone up, 12369 // but we would like to not have tons of activity from charging-constraint 12370 // jobs, so instead of reporting ACTION_CHARGING immediately, we defer it. 12371 if (!mHandler.hasCallbacks(mDeferSetCharging)) { 12372 mHandler.postDelayed( 12373 mDeferSetCharging, 12374 mConstants.BATTERY_CHARGED_DELAY_MS); 12375 } 12376 } else if (mLastChargeStepLevel > level) { 12377 // if we had deferred a runnable due to charge level increasing, but then 12378 // later the charge level drops (could be due to thermal issues), we don't 12379 // want to trigger the deferred runnable, so remove it here 12380 mHandler.removeCallbacks(mDeferSetCharging); 12381 } 12382 } else { 12383 if (mLastChargeStepLevel > level) { 12384 // We had reported that the device was charging, but here we are with 12385 // power connected and the level going down. Looks like the current 12386 // power supplied isn't enough, so consider the device to now be 12387 // discharging. 12388 changed |= setChargingLocked(false); 12389 } 12390 } 12391 if (mLastChargeStepLevel != level && mMaxChargeStepLevel < level) { 12392 mChargeStepTracker.addLevelSteps(level - mLastChargeStepLevel, 12393 modeBits, elapsedRealtime); 12394 mDailyChargeStepTracker.addLevelSteps(level - mLastChargeStepLevel, 12395 modeBits, elapsedRealtime); 12396 mMaxChargeStepLevel = level; 12397 mInitStepMode = mCurStepMode; 12398 mModStepMode = 0; 12399 } 12400 mLastChargeStepLevel = level; 12401 } 12402 if (changed) { 12403 addHistoryRecordLocked(elapsedRealtime, uptime); 12404 } 12405 } 12406 if (!onBattery && 12407 (status == BatteryManager.BATTERY_STATUS_FULL || 12408 status == BatteryManager.BATTERY_STATUS_UNKNOWN)) { 12409 // We don't record history while we are plugged in and fully charged 12410 // (or when battery is not present). The next time we are 12411 // unplugged, history will be cleared. 12412 mRecordingHistory = DEBUG; 12413 } 12414 12415 if (mMinLearnedBatteryCapacity == -1) { 12416 mMinLearnedBatteryCapacity = chargeFullUAh; 12417 } else { 12418 mMinLearnedBatteryCapacity = Math.min(mMinLearnedBatteryCapacity, chargeFullUAh); 12419 } 12420 mMaxLearnedBatteryCapacity = Math.max(mMaxLearnedBatteryCapacity, chargeFullUAh); 12421 } 12422 isOnBattery(int plugType, int status)12423 public static boolean isOnBattery(int plugType, int status) { 12424 return plugType == BATTERY_PLUGGED_NONE && status != BatteryManager.BATTERY_STATUS_UNKNOWN; 12425 } 12426 12427 // Inform StatsLog of setBatteryState changes. 12428 // If this is the first reporting, pass in recentPast == null. reportChangesToStatsLog(HistoryItem recentPast, final int status, final int plugType, final int level)12429 private void reportChangesToStatsLog(HistoryItem recentPast, 12430 final int status, final int plugType, final int level) { 12431 12432 if (recentPast == null || recentPast.batteryStatus != status) { 12433 StatsLog.write(StatsLog.CHARGING_STATE_CHANGED, status); 12434 } 12435 if (recentPast == null || recentPast.batteryPlugType != plugType) { 12436 StatsLog.write(StatsLog.PLUGGED_STATE_CHANGED, plugType); 12437 } 12438 if (recentPast == null || recentPast.batteryLevel != level) { 12439 StatsLog.write(StatsLog.BATTERY_LEVEL_CHANGED, level); 12440 } 12441 } 12442 12443 @UnsupportedAppUsage getAwakeTimeBattery()12444 public long getAwakeTimeBattery() { 12445 // This previously evaluated to mOnBatteryTimeBase.getUptime(getBatteryUptimeLocked()); 12446 // for over a decade, but surely that was a mistake. 12447 return getBatteryUptimeLocked(); 12448 } 12449 12450 @UnsupportedAppUsage getAwakeTimePlugged()12451 public long getAwakeTimePlugged() { 12452 return (mClocks.uptimeMillis() * 1000) - getAwakeTimeBattery(); 12453 } 12454 12455 @Override computeUptime(long curTime, int which)12456 public long computeUptime(long curTime, int which) { 12457 return mUptime + (curTime - mUptimeStart); 12458 } 12459 12460 @Override computeRealtime(long curTime, int which)12461 public long computeRealtime(long curTime, int which) { 12462 return mRealtime + (curTime - mRealtimeStart); 12463 } 12464 12465 @Override 12466 @UnsupportedAppUsage computeBatteryUptime(long curTime, int which)12467 public long computeBatteryUptime(long curTime, int which) { 12468 return mOnBatteryTimeBase.computeUptime(curTime, which); 12469 } 12470 12471 @Override 12472 @UnsupportedAppUsage computeBatteryRealtime(long curTime, int which)12473 public long computeBatteryRealtime(long curTime, int which) { 12474 return mOnBatteryTimeBase.computeRealtime(curTime, which); 12475 } 12476 12477 @Override computeBatteryScreenOffUptime(long curTime, int which)12478 public long computeBatteryScreenOffUptime(long curTime, int which) { 12479 return mOnBatteryScreenOffTimeBase.computeUptime(curTime, which); 12480 } 12481 12482 @Override computeBatteryScreenOffRealtime(long curTime, int which)12483 public long computeBatteryScreenOffRealtime(long curTime, int which) { 12484 return mOnBatteryScreenOffTimeBase.computeRealtime(curTime, which); 12485 } 12486 computeTimePerLevel(long[] steps, int numSteps)12487 private long computeTimePerLevel(long[] steps, int numSteps) { 12488 // For now we'll do a simple average across all steps. 12489 if (numSteps <= 0) { 12490 return -1; 12491 } 12492 long total = 0; 12493 for (int i=0; i<numSteps; i++) { 12494 total += steps[i] & STEP_LEVEL_TIME_MASK; 12495 } 12496 return total / numSteps; 12497 /* 12498 long[] buckets = new long[numSteps]; 12499 int numBuckets = 0; 12500 int numToAverage = 4; 12501 int i = 0; 12502 while (i < numSteps) { 12503 long totalTime = 0; 12504 int num = 0; 12505 for (int j=0; j<numToAverage && (i+j)<numSteps; j++) { 12506 totalTime += steps[i+j] & STEP_LEVEL_TIME_MASK; 12507 num++; 12508 } 12509 buckets[numBuckets] = totalTime / num; 12510 numBuckets++; 12511 numToAverage *= 2; 12512 i += num; 12513 } 12514 if (numBuckets < 1) { 12515 return -1; 12516 } 12517 long averageTime = buckets[numBuckets-1]; 12518 for (i=numBuckets-2; i>=0; i--) { 12519 averageTime = (averageTime + buckets[i]) / 2; 12520 } 12521 return averageTime; 12522 */ 12523 } 12524 12525 @Override 12526 @UnsupportedAppUsage computeBatteryTimeRemaining(long curTime)12527 public long computeBatteryTimeRemaining(long curTime) { 12528 if (!mOnBattery) { 12529 return -1; 12530 } 12531 /* Simple implementation just looks at the average discharge per level across the 12532 entire sample period. 12533 int discharge = (getLowDischargeAmountSinceCharge()+getHighDischargeAmountSinceCharge())/2; 12534 if (discharge < 2) { 12535 return -1; 12536 } 12537 long duration = computeBatteryRealtime(curTime, STATS_SINCE_CHARGED); 12538 if (duration < 1000*1000) { 12539 return -1; 12540 } 12541 long usPerLevel = duration/discharge; 12542 return usPerLevel * mCurrentBatteryLevel; 12543 */ 12544 if (mDischargeStepTracker.mNumStepDurations < 1) { 12545 return -1; 12546 } 12547 long msPerLevel = mDischargeStepTracker.computeTimePerLevel(); 12548 if (msPerLevel <= 0) { 12549 return -1; 12550 } 12551 return (msPerLevel * mCurrentBatteryLevel) * 1000; 12552 } 12553 12554 @Override getDischargeLevelStepTracker()12555 public LevelStepTracker getDischargeLevelStepTracker() { 12556 return mDischargeStepTracker; 12557 } 12558 12559 @Override getDailyDischargeLevelStepTracker()12560 public LevelStepTracker getDailyDischargeLevelStepTracker() { 12561 return mDailyDischargeStepTracker; 12562 } 12563 12564 @Override computeChargeTimeRemaining(long curTime)12565 public long computeChargeTimeRemaining(long curTime) { 12566 if (mOnBattery) { 12567 // Not yet working. 12568 return -1; 12569 } 12570 /* Broken 12571 int curLevel = mCurrentBatteryLevel; 12572 int plugLevel = mDischargePlugLevel; 12573 if (plugLevel < 0 || curLevel < (plugLevel+1)) { 12574 return -1; 12575 } 12576 long duration = computeBatteryRealtime(curTime, STATS_SINCE_UNPLUGGED); 12577 if (duration < 1000*1000) { 12578 return -1; 12579 } 12580 long usPerLevel = duration/(curLevel-plugLevel); 12581 return usPerLevel * (100-curLevel); 12582 */ 12583 if (mChargeStepTracker.mNumStepDurations < 1) { 12584 return -1; 12585 } 12586 long msPerLevel = mChargeStepTracker.computeTimePerLevel(); 12587 if (msPerLevel <= 0) { 12588 return -1; 12589 } 12590 return (msPerLevel * (100-mCurrentBatteryLevel)) * 1000; 12591 } 12592 12593 /*@hide */ getCellularBatteryStats()12594 public CellularBatteryStats getCellularBatteryStats() { 12595 CellularBatteryStats s = new CellularBatteryStats(); 12596 final int which = STATS_SINCE_CHARGED; 12597 final long rawRealTime = SystemClock.elapsedRealtime() * 1000; 12598 final ControllerActivityCounter counter = getModemControllerActivity(); 12599 final long sleepTimeMs = counter.getSleepTimeCounter().getCountLocked(which); 12600 final long idleTimeMs = counter.getIdleTimeCounter().getCountLocked(which); 12601 final long rxTimeMs = counter.getRxTimeCounter().getCountLocked(which); 12602 final long energyConsumedMaMs = counter.getPowerCounter().getCountLocked(which); 12603 final long monitoredRailChargeConsumedMaMs = 12604 counter.getMonitoredRailChargeConsumedMaMs().getCountLocked(which); 12605 long[] timeInRatMs = new long[BatteryStats.NUM_DATA_CONNECTION_TYPES]; 12606 for (int i = 0; i < timeInRatMs.length; i++) { 12607 timeInRatMs[i] = getPhoneDataConnectionTime(i, rawRealTime, which) / 1000; 12608 } 12609 long[] timeInRxSignalStrengthLevelMs = new long[SignalStrength.NUM_SIGNAL_STRENGTH_BINS]; 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<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; 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 mIsCellularTxPowerHigh = false; 13664 13665 int NRPMS = in.readInt(); 13666 if (NRPMS > 10000) { 13667 throw new ParcelFormatException("File corrupt: too many rpm stats " + NRPMS); 13668 } 13669 for (int irpm = 0; irpm < NRPMS; irpm++) { 13670 if (in.readInt() != 0) { 13671 String rpmName = in.readString(); 13672 getRpmTimerLocked(rpmName).readSummaryFromParcelLocked(in); 13673 } 13674 } 13675 int NSORPMS = in.readInt(); 13676 if (NSORPMS > 10000) { 13677 throw new ParcelFormatException("File corrupt: too many screen-off rpm stats " + NSORPMS); 13678 } 13679 for (int irpm = 0; irpm < NSORPMS; irpm++) { 13680 if (in.readInt() != 0) { 13681 String rpmName = in.readString(); 13682 getScreenOffRpmTimerLocked(rpmName).readSummaryFromParcelLocked(in); 13683 } 13684 } 13685 13686 int NKW = in.readInt(); 13687 if (NKW > 10000) { 13688 throw new ParcelFormatException("File corrupt: too many kernel wake locks " + NKW); 13689 } 13690 for (int ikw = 0; ikw < NKW; ikw++) { 13691 if (in.readInt() != 0) { 13692 String kwltName = in.readString(); 13693 getKernelWakelockTimerLocked(kwltName).readSummaryFromParcelLocked(in); 13694 } 13695 } 13696 13697 int NWR = in.readInt(); 13698 if (NWR > 10000) { 13699 throw new ParcelFormatException("File corrupt: too many wakeup reasons " + NWR); 13700 } 13701 for (int iwr = 0; iwr < NWR; iwr++) { 13702 if (in.readInt() != 0) { 13703 String reasonName = in.readString(); 13704 getWakeupReasonTimerLocked(reasonName).readSummaryFromParcelLocked(in); 13705 } 13706 } 13707 13708 int NMS = in.readInt(); 13709 for (int ims = 0; ims < NMS; ims++) { 13710 if (in.readInt() != 0) { 13711 long kmstName = in.readLong(); 13712 getKernelMemoryTimerLocked(kmstName).readSummaryFromParcelLocked(in); 13713 } 13714 } 13715 13716 final int NU = in.readInt(); 13717 if (NU > 10000) { 13718 throw new ParcelFormatException("File corrupt: too many uids " + NU); 13719 } 13720 for (int iu = 0; iu < NU; iu++) { 13721 int uid = in.readInt(); 13722 Uid u = new Uid(this, uid); 13723 mUidStats.put(uid, u); 13724 13725 u.mOnBatteryBackgroundTimeBase.readSummaryFromParcel(in); 13726 u.mOnBatteryScreenOffBackgroundTimeBase.readSummaryFromParcel(in); 13727 13728 u.mWifiRunning = false; 13729 if (in.readInt() != 0) { 13730 u.mWifiRunningTimer.readSummaryFromParcelLocked(in); 13731 } 13732 u.mFullWifiLockOut = false; 13733 if (in.readInt() != 0) { 13734 u.mFullWifiLockTimer.readSummaryFromParcelLocked(in); 13735 } 13736 u.mWifiScanStarted = false; 13737 if (in.readInt() != 0) { 13738 u.mWifiScanTimer.readSummaryFromParcelLocked(in); 13739 } 13740 u.mWifiBatchedScanBinStarted = Uid.NO_BATCHED_SCAN_STARTED; 13741 for (int i = 0; i < Uid.NUM_WIFI_BATCHED_SCAN_BINS; i++) { 13742 if (in.readInt() != 0) { 13743 u.makeWifiBatchedScanBin(i, null); 13744 u.mWifiBatchedScanTimer[i].readSummaryFromParcelLocked(in); 13745 } 13746 } 13747 u.mWifiMulticastWakelockCount = 0; 13748 if (in.readInt() != 0) { 13749 u.mWifiMulticastTimer.readSummaryFromParcelLocked(in); 13750 } 13751 if (in.readInt() != 0) { 13752 u.createAudioTurnedOnTimerLocked().readSummaryFromParcelLocked(in); 13753 } 13754 if (in.readInt() != 0) { 13755 u.createVideoTurnedOnTimerLocked().readSummaryFromParcelLocked(in); 13756 } 13757 if (in.readInt() != 0) { 13758 u.createFlashlightTurnedOnTimerLocked().readSummaryFromParcelLocked(in); 13759 } 13760 if (in.readInt() != 0) { 13761 u.createCameraTurnedOnTimerLocked().readSummaryFromParcelLocked(in); 13762 } 13763 if (in.readInt() != 0) { 13764 u.createForegroundActivityTimerLocked().readSummaryFromParcelLocked(in); 13765 } 13766 if (in.readInt() != 0) { 13767 u.createForegroundServiceTimerLocked().readSummaryFromParcelLocked(in); 13768 } 13769 if (in.readInt() != 0) { 13770 u.createAggregatedPartialWakelockTimerLocked().readSummaryFromParcelLocked(in); 13771 } 13772 if (in.readInt() != 0) { 13773 u.createBluetoothScanTimerLocked().readSummaryFromParcelLocked(in); 13774 } 13775 if (in.readInt() != 0) { 13776 u.createBluetoothUnoptimizedScanTimerLocked().readSummaryFromParcelLocked(in); 13777 } 13778 if (in.readInt() != 0) { 13779 u.createBluetoothScanResultCounterLocked().readSummaryFromParcelLocked(in); 13780 } 13781 if (in.readInt() != 0) { 13782 u.createBluetoothScanResultBgCounterLocked().readSummaryFromParcelLocked(in); 13783 } 13784 u.mProcessState = ActivityManager.PROCESS_STATE_NONEXISTENT; 13785 for (int i = 0; i < Uid.NUM_PROCESS_STATE; i++) { 13786 if (in.readInt() != 0) { 13787 u.makeProcessState(i, null); 13788 u.mProcessStateTimer[i].readSummaryFromParcelLocked(in); 13789 } 13790 } 13791 if (in.readInt() != 0) { 13792 u.createVibratorOnTimerLocked().readSummaryFromParcelLocked(in); 13793 } 13794 13795 if (in.readInt() != 0) { 13796 if (u.mUserActivityCounters == null) { 13797 u.initUserActivityLocked(); 13798 } 13799 for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) { 13800 u.mUserActivityCounters[i].readSummaryFromParcelLocked(in); 13801 } 13802 } 13803 13804 if (in.readInt() != 0) { 13805 if (u.mNetworkByteActivityCounters == null) { 13806 u.initNetworkActivityLocked(); 13807 } 13808 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 13809 u.mNetworkByteActivityCounters[i].readSummaryFromParcelLocked(in); 13810 u.mNetworkPacketActivityCounters[i].readSummaryFromParcelLocked(in); 13811 } 13812 u.mMobileRadioActiveTime.readSummaryFromParcelLocked(in); 13813 u.mMobileRadioActiveCount.readSummaryFromParcelLocked(in); 13814 } 13815 13816 u.mUserCpuTime.readSummaryFromParcelLocked(in); 13817 u.mSystemCpuTime.readSummaryFromParcelLocked(in); 13818 13819 if (in.readInt() != 0) { 13820 final int numClusters = in.readInt(); 13821 if (mPowerProfile != null && mPowerProfile.getNumCpuClusters() != numClusters) { 13822 throw new ParcelFormatException("Incompatible cpu cluster arrangement"); 13823 } 13824 detachIfNotNull(u.mCpuClusterSpeedTimesUs); 13825 u.mCpuClusterSpeedTimesUs = new LongSamplingCounter[numClusters][]; 13826 for (int cluster = 0; cluster < numClusters; cluster++) { 13827 if (in.readInt() != 0) { 13828 final int NSB = in.readInt(); 13829 if (mPowerProfile != null && 13830 mPowerProfile.getNumSpeedStepsInCpuCluster(cluster) != NSB) { 13831 throw new ParcelFormatException("File corrupt: too many speed bins " + 13832 NSB); 13833 } 13834 13835 u.mCpuClusterSpeedTimesUs[cluster] = new LongSamplingCounter[NSB]; 13836 for (int speed = 0; speed < NSB; speed++) { 13837 if (in.readInt() != 0) { 13838 u.mCpuClusterSpeedTimesUs[cluster][speed] = new LongSamplingCounter( 13839 mOnBatteryTimeBase); 13840 u.mCpuClusterSpeedTimesUs[cluster][speed].readSummaryFromParcelLocked(in); 13841 } 13842 } 13843 } else { 13844 u.mCpuClusterSpeedTimesUs[cluster] = null; 13845 } 13846 } 13847 } else { 13848 detachIfNotNull(u.mCpuClusterSpeedTimesUs); 13849 u.mCpuClusterSpeedTimesUs = null; 13850 } 13851 13852 detachIfNotNull(u.mCpuFreqTimeMs); 13853 u.mCpuFreqTimeMs = LongSamplingCounterArray.readSummaryFromParcelLocked( 13854 in, mOnBatteryTimeBase); 13855 detachIfNotNull(u.mScreenOffCpuFreqTimeMs); 13856 u.mScreenOffCpuFreqTimeMs = LongSamplingCounterArray.readSummaryFromParcelLocked( 13857 in, mOnBatteryScreenOffTimeBase); 13858 13859 u.mCpuActiveTimeMs.readSummaryFromParcelLocked(in); 13860 u.mCpuClusterTimesMs.readSummaryFromParcelLocked(in); 13861 13862 int length = in.readInt(); 13863 if (length == Uid.NUM_PROCESS_STATE) { 13864 detachIfNotNull(u.mProcStateTimeMs); 13865 u.mProcStateTimeMs = new LongSamplingCounterArray[length]; 13866 for (int procState = 0; procState < length; ++procState) { 13867 u.mProcStateTimeMs[procState] 13868 = LongSamplingCounterArray.readSummaryFromParcelLocked( 13869 in, mOnBatteryTimeBase); 13870 } 13871 } else { 13872 detachIfNotNull(u.mProcStateTimeMs); 13873 u.mProcStateTimeMs = null; 13874 } 13875 length = in.readInt(); 13876 if (length == Uid.NUM_PROCESS_STATE) { 13877 detachIfNotNull(u.mProcStateScreenOffTimeMs); 13878 u.mProcStateScreenOffTimeMs = new LongSamplingCounterArray[length]; 13879 for (int procState = 0; procState < length; ++procState) { 13880 u.mProcStateScreenOffTimeMs[procState] 13881 = LongSamplingCounterArray.readSummaryFromParcelLocked( 13882 in, mOnBatteryScreenOffTimeBase); 13883 } 13884 } else { 13885 detachIfNotNull(u.mProcStateScreenOffTimeMs); 13886 u.mProcStateScreenOffTimeMs = null; 13887 } 13888 13889 if (in.readInt() != 0) { 13890 detachIfNotNull(u.mMobileRadioApWakeupCount); 13891 u.mMobileRadioApWakeupCount = new LongSamplingCounter(mOnBatteryTimeBase); 13892 u.mMobileRadioApWakeupCount.readSummaryFromParcelLocked(in); 13893 } else { 13894 detachIfNotNull(u.mMobileRadioApWakeupCount); 13895 u.mMobileRadioApWakeupCount = null; 13896 } 13897 13898 if (in.readInt() != 0) { 13899 detachIfNotNull(u.mWifiRadioApWakeupCount); 13900 u.mWifiRadioApWakeupCount = new LongSamplingCounter(mOnBatteryTimeBase); 13901 u.mWifiRadioApWakeupCount.readSummaryFromParcelLocked(in); 13902 } else { 13903 detachIfNotNull(u.mWifiRadioApWakeupCount); 13904 u.mWifiRadioApWakeupCount = null; 13905 } 13906 13907 int NW = in.readInt(); 13908 if (NW > (MAX_WAKELOCKS_PER_UID+1)) { 13909 throw new ParcelFormatException("File corrupt: too many wake locks " + NW); 13910 } 13911 for (int iw = 0; iw < NW; iw++) { 13912 String wlName = in.readString(); 13913 u.readWakeSummaryFromParcelLocked(wlName, in); 13914 } 13915 13916 int NS = in.readInt(); 13917 if (NS > (MAX_WAKELOCKS_PER_UID+1)) { 13918 throw new ParcelFormatException("File corrupt: too many syncs " + NS); 13919 } 13920 for (int is = 0; is < NS; is++) { 13921 String name = in.readString(); 13922 u.readSyncSummaryFromParcelLocked(name, in); 13923 } 13924 13925 int NJ = in.readInt(); 13926 if (NJ > (MAX_WAKELOCKS_PER_UID+1)) { 13927 throw new ParcelFormatException("File corrupt: too many job timers " + NJ); 13928 } 13929 for (int ij = 0; ij < NJ; ij++) { 13930 String name = in.readString(); 13931 u.readJobSummaryFromParcelLocked(name, in); 13932 } 13933 13934 u.readJobCompletionsFromParcelLocked(in); 13935 13936 u.mJobsDeferredEventCount.readSummaryFromParcelLocked(in); 13937 u.mJobsDeferredCount.readSummaryFromParcelLocked(in); 13938 u.mJobsFreshnessTimeMs.readSummaryFromParcelLocked(in); 13939 detachIfNotNull(u.mJobsFreshnessBuckets); 13940 for (int i = 0; i < JOB_FRESHNESS_BUCKETS.length; i++) { 13941 if (in.readInt() != 0) { 13942 u.mJobsFreshnessBuckets[i] = new Counter(u.mBsi.mOnBatteryTimeBase); 13943 u.mJobsFreshnessBuckets[i].readSummaryFromParcelLocked(in); 13944 } 13945 } 13946 13947 int NP = in.readInt(); 13948 if (NP > 1000) { 13949 throw new ParcelFormatException("File corrupt: too many sensors " + NP); 13950 } 13951 for (int is = 0; is < NP; is++) { 13952 int seNumber = in.readInt(); 13953 if (in.readInt() != 0) { 13954 u.getSensorTimerLocked(seNumber, true).readSummaryFromParcelLocked(in); 13955 } 13956 } 13957 13958 NP = in.readInt(); 13959 if (NP > 1000) { 13960 throw new ParcelFormatException("File corrupt: too many processes " + NP); 13961 } 13962 for (int ip = 0; ip < NP; ip++) { 13963 String procName = in.readString(); 13964 Uid.Proc p = u.getProcessStatsLocked(procName); 13965 p.mUserTime = in.readLong(); 13966 p.mSystemTime = in.readLong(); 13967 p.mForegroundTime = in.readLong(); 13968 p.mStarts = in.readInt(); 13969 p.mNumCrashes = in.readInt(); 13970 p.mNumAnrs = in.readInt(); 13971 p.readExcessivePowerFromParcelLocked(in); 13972 } 13973 13974 NP = in.readInt(); 13975 if (NP > 10000) { 13976 throw new ParcelFormatException("File corrupt: too many packages " + NP); 13977 } 13978 for (int ip = 0; ip < NP; ip++) { 13979 String pkgName = in.readString(); 13980 detachIfNotNull(u.mPackageStats.get(pkgName)); 13981 Uid.Pkg p = u.getPackageStatsLocked(pkgName); 13982 final int NWA = in.readInt(); 13983 if (NWA > 10000) { 13984 throw new ParcelFormatException("File corrupt: too many wakeup alarms " + NWA); 13985 } 13986 p.mWakeupAlarms.clear(); 13987 for (int iwa = 0; iwa < NWA; iwa++) { 13988 String tag = in.readString(); 13989 Counter c = new Counter(mOnBatteryScreenOffTimeBase); 13990 c.readSummaryFromParcelLocked(in); 13991 p.mWakeupAlarms.put(tag, c); 13992 } 13993 NS = in.readInt(); 13994 if (NS > 10000) { 13995 throw new ParcelFormatException("File corrupt: too many services " + NS); 13996 } 13997 for (int is = 0; is < NS; is++) { 13998 String servName = in.readString(); 13999 Uid.Pkg.Serv s = u.getServiceStatsLocked(pkgName, servName); 14000 s.mStartTime = in.readLong(); 14001 s.mStarts = in.readInt(); 14002 s.mLaunches = in.readInt(); 14003 } 14004 } 14005 } 14006 } 14007 14008 /** 14009 * Writes a summary of the statistics to a Parcel, in a format suitable to be written to 14010 * disk. This format does not allow a lossless round-trip. 14011 * 14012 * @param out the Parcel to be written to. 14013 */ writeSummaryToParcel(Parcel out, boolean inclHistory)14014 public void writeSummaryToParcel(Parcel out, boolean inclHistory) { 14015 pullPendingStateUpdatesLocked(); 14016 14017 // Pull the clock time. This may update the time and make a new history entry 14018 // if we had originally pulled a time before the RTC was set. 14019 getStartClockTime(); 14020 14021 final long NOW_SYS = mClocks.uptimeMillis() * 1000; 14022 final long NOWREAL_SYS = mClocks.elapsedRealtime() * 1000; 14023 14024 out.writeInt(VERSION); 14025 14026 out.writeBoolean(inclHistory); 14027 if (inclHistory) { 14028 writeHistoryBuffer(out, true, true); 14029 mBatteryStatsHistory.writeToParcel(out); 14030 } 14031 14032 out.writeInt(mHistoryTagPool.size()); 14033 for (HashMap.Entry<HistoryTag, Integer> ent : mHistoryTagPool.entrySet()) { 14034 HistoryTag tag = ent.getKey(); 14035 out.writeInt(ent.getValue()); 14036 out.writeString(tag.string); 14037 out.writeInt(tag.uid); 14038 } 14039 14040 out.writeInt(mStartCount); 14041 out.writeLong(computeUptime(NOW_SYS, STATS_SINCE_CHARGED)); 14042 out.writeLong(computeRealtime(NOWREAL_SYS, STATS_SINCE_CHARGED)); 14043 out.writeLong(mStartClockTime); 14044 out.writeString(mStartPlatformVersion); 14045 out.writeString(mEndPlatformVersion); 14046 mOnBatteryTimeBase.writeSummaryToParcel(out, NOW_SYS, NOWREAL_SYS); 14047 mOnBatteryScreenOffTimeBase.writeSummaryToParcel(out, NOW_SYS, NOWREAL_SYS); 14048 out.writeInt(mDischargeUnplugLevel); 14049 out.writeInt(mDischargePlugLevel); 14050 out.writeInt(mDischargeCurrentLevel); 14051 out.writeInt(mCurrentBatteryLevel); 14052 out.writeInt(mEstimatedBatteryCapacity); 14053 out.writeInt(mMinLearnedBatteryCapacity); 14054 out.writeInt(mMaxLearnedBatteryCapacity); 14055 out.writeInt(getLowDischargeAmountSinceCharge()); 14056 out.writeInt(getHighDischargeAmountSinceCharge()); 14057 out.writeInt(getDischargeAmountScreenOnSinceCharge()); 14058 out.writeInt(getDischargeAmountScreenOffSinceCharge()); 14059 out.writeInt(getDischargeAmountScreenDozeSinceCharge()); 14060 mDischargeStepTracker.writeToParcel(out); 14061 mChargeStepTracker.writeToParcel(out); 14062 mDailyDischargeStepTracker.writeToParcel(out); 14063 mDailyChargeStepTracker.writeToParcel(out); 14064 mDischargeCounter.writeSummaryFromParcelLocked(out); 14065 mDischargeScreenOffCounter.writeSummaryFromParcelLocked(out); 14066 mDischargeScreenDozeCounter.writeSummaryFromParcelLocked(out); 14067 mDischargeLightDozeCounter.writeSummaryFromParcelLocked(out); 14068 mDischargeDeepDozeCounter.writeSummaryFromParcelLocked(out); 14069 if (mDailyPackageChanges != null) { 14070 final int NPKG = mDailyPackageChanges.size(); 14071 out.writeInt(NPKG); 14072 for (int i=0; i<NPKG; i++) { 14073 PackageChange pc = mDailyPackageChanges.get(i); 14074 out.writeString(pc.mPackageName); 14075 out.writeInt(pc.mUpdate ? 1 : 0); 14076 out.writeLong(pc.mVersionCode); 14077 } 14078 } else { 14079 out.writeInt(0); 14080 } 14081 out.writeLong(mDailyStartTime); 14082 out.writeLong(mNextMinDailyDeadline); 14083 out.writeLong(mNextMaxDailyDeadline); 14084 14085 mScreenOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14086 mScreenDozeTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14087 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 14088 mScreenBrightnessTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14089 } 14090 mInteractiveTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14091 mPowerSaveModeEnabledTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14092 out.writeLong(mLongestLightIdleTime); 14093 out.writeLong(mLongestFullIdleTime); 14094 mDeviceIdleModeLightTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14095 mDeviceIdleModeFullTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14096 mDeviceLightIdlingTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14097 mDeviceIdlingTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14098 mPhoneOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14099 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) { 14100 mPhoneSignalStrengthsTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14101 } 14102 mPhoneSignalScanningTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14103 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 14104 mPhoneDataConnectionsTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14105 } 14106 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 14107 mNetworkByteActivityCounters[i].writeSummaryFromParcelLocked(out); 14108 mNetworkPacketActivityCounters[i].writeSummaryFromParcelLocked(out); 14109 } 14110 mMobileRadioActiveTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14111 mMobileRadioActivePerAppTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14112 mMobileRadioActiveAdjustedTime.writeSummaryFromParcelLocked(out); 14113 mMobileRadioActiveUnknownTime.writeSummaryFromParcelLocked(out); 14114 mMobileRadioActiveUnknownCount.writeSummaryFromParcelLocked(out); 14115 mWifiMulticastWakelockTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14116 mWifiOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14117 mGlobalWifiRunningTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14118 for (int i=0; i<NUM_WIFI_STATES; i++) { 14119 mWifiStateTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14120 } 14121 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) { 14122 mWifiSupplStateTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14123 } 14124 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { 14125 mWifiSignalStrengthsTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14126 } 14127 mWifiActiveTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14128 mWifiActivity.writeSummaryToParcel(out); 14129 for (int i=0; i< GnssMetrics.NUM_GPS_SIGNAL_QUALITY_LEVELS; i++) { 14130 mGpsSignalQualityTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14131 } 14132 mBluetoothActivity.writeSummaryToParcel(out); 14133 mModemActivity.writeSummaryToParcel(out); 14134 out.writeInt(mHasWifiReporting ? 1 : 0); 14135 out.writeInt(mHasBluetoothReporting ? 1 : 0); 14136 out.writeInt(mHasModemReporting ? 1 : 0); 14137 14138 out.writeInt(mNumConnectivityChange); 14139 mFlashlightOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14140 mCameraOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14141 mBluetoothScanTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14142 14143 out.writeInt(mRpmStats.size()); 14144 for (Map.Entry<String, SamplingTimer> ent : mRpmStats.entrySet()) { 14145 Timer rpmt = ent.getValue(); 14146 if (rpmt != null) { 14147 out.writeInt(1); 14148 out.writeString(ent.getKey()); 14149 rpmt.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14150 } else { 14151 out.writeInt(0); 14152 } 14153 } 14154 out.writeInt(mScreenOffRpmStats.size()); 14155 for (Map.Entry<String, SamplingTimer> ent : mScreenOffRpmStats.entrySet()) { 14156 Timer rpmt = ent.getValue(); 14157 if (rpmt != null) { 14158 out.writeInt(1); 14159 out.writeString(ent.getKey()); 14160 rpmt.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14161 } else { 14162 out.writeInt(0); 14163 } 14164 } 14165 14166 out.writeInt(mKernelWakelockStats.size()); 14167 for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) { 14168 Timer kwlt = ent.getValue(); 14169 if (kwlt != null) { 14170 out.writeInt(1); 14171 out.writeString(ent.getKey()); 14172 kwlt.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14173 } else { 14174 out.writeInt(0); 14175 } 14176 } 14177 14178 out.writeInt(mWakeupReasonStats.size()); 14179 for (Map.Entry<String, SamplingTimer> ent : mWakeupReasonStats.entrySet()) { 14180 SamplingTimer timer = ent.getValue(); 14181 if (timer != null) { 14182 out.writeInt(1); 14183 out.writeString(ent.getKey()); 14184 timer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14185 } else { 14186 out.writeInt(0); 14187 } 14188 } 14189 14190 out.writeInt(mKernelMemoryStats.size()); 14191 for (int i = 0; i < mKernelMemoryStats.size(); i++) { 14192 Timer kmt = mKernelMemoryStats.valueAt(i); 14193 if (kmt != null) { 14194 out.writeInt(1); 14195 out.writeLong(mKernelMemoryStats.keyAt(i)); 14196 kmt.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14197 } else { 14198 out.writeInt(0); 14199 } 14200 } 14201 14202 final int NU = mUidStats.size(); 14203 out.writeInt(NU); 14204 for (int iu = 0; iu < NU; iu++) { 14205 out.writeInt(mUidStats.keyAt(iu)); 14206 Uid u = mUidStats.valueAt(iu); 14207 14208 u.mOnBatteryBackgroundTimeBase.writeSummaryToParcel(out, NOW_SYS, NOWREAL_SYS); 14209 u.mOnBatteryScreenOffBackgroundTimeBase.writeSummaryToParcel(out, NOW_SYS, NOWREAL_SYS); 14210 14211 if (u.mWifiRunningTimer != null) { 14212 out.writeInt(1); 14213 u.mWifiRunningTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14214 } else { 14215 out.writeInt(0); 14216 } 14217 if (u.mFullWifiLockTimer != null) { 14218 out.writeInt(1); 14219 u.mFullWifiLockTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14220 } else { 14221 out.writeInt(0); 14222 } 14223 if (u.mWifiScanTimer != null) { 14224 out.writeInt(1); 14225 u.mWifiScanTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14226 } else { 14227 out.writeInt(0); 14228 } 14229 for (int i = 0; i < Uid.NUM_WIFI_BATCHED_SCAN_BINS; i++) { 14230 if (u.mWifiBatchedScanTimer[i] != null) { 14231 out.writeInt(1); 14232 u.mWifiBatchedScanTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14233 } else { 14234 out.writeInt(0); 14235 } 14236 } 14237 if (u.mWifiMulticastTimer != null) { 14238 out.writeInt(1); 14239 u.mWifiMulticastTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14240 } else { 14241 out.writeInt(0); 14242 } 14243 if (u.mAudioTurnedOnTimer != null) { 14244 out.writeInt(1); 14245 u.mAudioTurnedOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14246 } else { 14247 out.writeInt(0); 14248 } 14249 if (u.mVideoTurnedOnTimer != null) { 14250 out.writeInt(1); 14251 u.mVideoTurnedOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14252 } else { 14253 out.writeInt(0); 14254 } 14255 if (u.mFlashlightTurnedOnTimer != null) { 14256 out.writeInt(1); 14257 u.mFlashlightTurnedOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14258 } else { 14259 out.writeInt(0); 14260 } 14261 if (u.mCameraTurnedOnTimer != null) { 14262 out.writeInt(1); 14263 u.mCameraTurnedOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14264 } else { 14265 out.writeInt(0); 14266 } 14267 if (u.mForegroundActivityTimer != null) { 14268 out.writeInt(1); 14269 u.mForegroundActivityTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14270 } else { 14271 out.writeInt(0); 14272 } 14273 if (u.mForegroundServiceTimer != null) { 14274 out.writeInt(1); 14275 u.mForegroundServiceTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14276 } else { 14277 out.writeInt(0); 14278 } 14279 if (u.mAggregatedPartialWakelockTimer != null) { 14280 out.writeInt(1); 14281 u.mAggregatedPartialWakelockTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14282 } else { 14283 out.writeInt(0); 14284 } 14285 if (u.mBluetoothScanTimer != null) { 14286 out.writeInt(1); 14287 u.mBluetoothScanTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14288 } else { 14289 out.writeInt(0); 14290 } 14291 if (u.mBluetoothUnoptimizedScanTimer != null) { 14292 out.writeInt(1); 14293 u.mBluetoothUnoptimizedScanTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14294 } else { 14295 out.writeInt(0); 14296 } 14297 if (u.mBluetoothScanResultCounter != null) { 14298 out.writeInt(1); 14299 u.mBluetoothScanResultCounter.writeSummaryFromParcelLocked(out); 14300 } else { 14301 out.writeInt(0); 14302 } 14303 if (u.mBluetoothScanResultBgCounter != null) { 14304 out.writeInt(1); 14305 u.mBluetoothScanResultBgCounter.writeSummaryFromParcelLocked(out); 14306 } else { 14307 out.writeInt(0); 14308 } 14309 for (int i = 0; i < Uid.NUM_PROCESS_STATE; i++) { 14310 if (u.mProcessStateTimer[i] != null) { 14311 out.writeInt(1); 14312 u.mProcessStateTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14313 } else { 14314 out.writeInt(0); 14315 } 14316 } 14317 if (u.mVibratorOnTimer != null) { 14318 out.writeInt(1); 14319 u.mVibratorOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14320 } else { 14321 out.writeInt(0); 14322 } 14323 14324 if (u.mUserActivityCounters == null) { 14325 out.writeInt(0); 14326 } else { 14327 out.writeInt(1); 14328 for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) { 14329 u.mUserActivityCounters[i].writeSummaryFromParcelLocked(out); 14330 } 14331 } 14332 14333 if (u.mNetworkByteActivityCounters == null) { 14334 out.writeInt(0); 14335 } else { 14336 out.writeInt(1); 14337 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 14338 u.mNetworkByteActivityCounters[i].writeSummaryFromParcelLocked(out); 14339 u.mNetworkPacketActivityCounters[i].writeSummaryFromParcelLocked(out); 14340 } 14341 u.mMobileRadioActiveTime.writeSummaryFromParcelLocked(out); 14342 u.mMobileRadioActiveCount.writeSummaryFromParcelLocked(out); 14343 } 14344 14345 u.mUserCpuTime.writeSummaryFromParcelLocked(out); 14346 u.mSystemCpuTime.writeSummaryFromParcelLocked(out); 14347 14348 if (u.mCpuClusterSpeedTimesUs != null) { 14349 out.writeInt(1); 14350 out.writeInt(u.mCpuClusterSpeedTimesUs.length); 14351 for (LongSamplingCounter[] cpuSpeeds : u.mCpuClusterSpeedTimesUs) { 14352 if (cpuSpeeds != null) { 14353 out.writeInt(1); 14354 out.writeInt(cpuSpeeds.length); 14355 for (LongSamplingCounter c : cpuSpeeds) { 14356 if (c != null) { 14357 out.writeInt(1); 14358 c.writeSummaryFromParcelLocked(out); 14359 } else { 14360 out.writeInt(0); 14361 } 14362 } 14363 } else { 14364 out.writeInt(0); 14365 } 14366 } 14367 } else { 14368 out.writeInt(0); 14369 } 14370 14371 LongSamplingCounterArray.writeSummaryToParcelLocked(out, u.mCpuFreqTimeMs); 14372 LongSamplingCounterArray.writeSummaryToParcelLocked(out, u.mScreenOffCpuFreqTimeMs); 14373 14374 u.mCpuActiveTimeMs.writeSummaryFromParcelLocked(out); 14375 u.mCpuClusterTimesMs.writeSummaryToParcelLocked(out); 14376 14377 if (u.mProcStateTimeMs != null) { 14378 out.writeInt(u.mProcStateTimeMs.length); 14379 for (LongSamplingCounterArray counters : u.mProcStateTimeMs) { 14380 LongSamplingCounterArray.writeSummaryToParcelLocked(out, counters); 14381 } 14382 } else { 14383 out.writeInt(0); 14384 } 14385 if (u.mProcStateScreenOffTimeMs != null) { 14386 out.writeInt(u.mProcStateScreenOffTimeMs.length); 14387 for (LongSamplingCounterArray counters : u.mProcStateScreenOffTimeMs) { 14388 LongSamplingCounterArray.writeSummaryToParcelLocked(out, counters); 14389 } 14390 } else { 14391 out.writeInt(0); 14392 } 14393 14394 if (u.mMobileRadioApWakeupCount != null) { 14395 out.writeInt(1); 14396 u.mMobileRadioApWakeupCount.writeSummaryFromParcelLocked(out); 14397 } else { 14398 out.writeInt(0); 14399 } 14400 14401 if (u.mWifiRadioApWakeupCount != null) { 14402 out.writeInt(1); 14403 u.mWifiRadioApWakeupCount.writeSummaryFromParcelLocked(out); 14404 } else { 14405 out.writeInt(0); 14406 } 14407 14408 final ArrayMap<String, Uid.Wakelock> wakeStats = u.mWakelockStats.getMap(); 14409 int NW = wakeStats.size(); 14410 out.writeInt(NW); 14411 for (int iw=0; iw<NW; iw++) { 14412 out.writeString(wakeStats.keyAt(iw)); 14413 Uid.Wakelock wl = wakeStats.valueAt(iw); 14414 if (wl.mTimerFull != null) { 14415 out.writeInt(1); 14416 wl.mTimerFull.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14417 } else { 14418 out.writeInt(0); 14419 } 14420 if (wl.mTimerPartial != null) { 14421 out.writeInt(1); 14422 wl.mTimerPartial.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14423 } else { 14424 out.writeInt(0); 14425 } 14426 if (wl.mTimerWindow != null) { 14427 out.writeInt(1); 14428 wl.mTimerWindow.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14429 } else { 14430 out.writeInt(0); 14431 } 14432 if (wl.mTimerDraw != null) { 14433 out.writeInt(1); 14434 wl.mTimerDraw.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14435 } else { 14436 out.writeInt(0); 14437 } 14438 } 14439 14440 final ArrayMap<String, DualTimer> syncStats = u.mSyncStats.getMap(); 14441 int NS = syncStats.size(); 14442 out.writeInt(NS); 14443 for (int is=0; is<NS; is++) { 14444 out.writeString(syncStats.keyAt(is)); 14445 syncStats.valueAt(is).writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14446 } 14447 14448 final ArrayMap<String, DualTimer> jobStats = u.mJobStats.getMap(); 14449 int NJ = jobStats.size(); 14450 out.writeInt(NJ); 14451 for (int ij=0; ij<NJ; ij++) { 14452 out.writeString(jobStats.keyAt(ij)); 14453 jobStats.valueAt(ij).writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14454 } 14455 14456 u.writeJobCompletionsToParcelLocked(out); 14457 14458 u.mJobsDeferredEventCount.writeSummaryFromParcelLocked(out); 14459 u.mJobsDeferredCount.writeSummaryFromParcelLocked(out); 14460 u.mJobsFreshnessTimeMs.writeSummaryFromParcelLocked(out); 14461 for (int i = 0; i < JOB_FRESHNESS_BUCKETS.length; i++) { 14462 if (u.mJobsFreshnessBuckets[i] != null) { 14463 out.writeInt(1); 14464 u.mJobsFreshnessBuckets[i].writeSummaryFromParcelLocked(out); 14465 } else { 14466 out.writeInt(0); 14467 } 14468 } 14469 14470 int NSE = u.mSensorStats.size(); 14471 out.writeInt(NSE); 14472 for (int ise=0; ise<NSE; ise++) { 14473 out.writeInt(u.mSensorStats.keyAt(ise)); 14474 Uid.Sensor se = u.mSensorStats.valueAt(ise); 14475 if (se.mTimer != null) { 14476 out.writeInt(1); 14477 se.mTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14478 } else { 14479 out.writeInt(0); 14480 } 14481 } 14482 14483 int NP = u.mProcessStats.size(); 14484 out.writeInt(NP); 14485 for (int ip=0; ip<NP; ip++) { 14486 out.writeString(u.mProcessStats.keyAt(ip)); 14487 Uid.Proc ps = u.mProcessStats.valueAt(ip); 14488 out.writeLong(ps.mUserTime); 14489 out.writeLong(ps.mSystemTime); 14490 out.writeLong(ps.mForegroundTime); 14491 out.writeInt(ps.mStarts); 14492 out.writeInt(ps.mNumCrashes); 14493 out.writeInt(ps.mNumAnrs); 14494 ps.writeExcessivePowerToParcelLocked(out); 14495 } 14496 14497 NP = u.mPackageStats.size(); 14498 out.writeInt(NP); 14499 if (NP > 0) { 14500 for (Map.Entry<String, BatteryStatsImpl.Uid.Pkg> ent 14501 : u.mPackageStats.entrySet()) { 14502 out.writeString(ent.getKey()); 14503 Uid.Pkg ps = ent.getValue(); 14504 final int NWA = ps.mWakeupAlarms.size(); 14505 out.writeInt(NWA); 14506 for (int iwa=0; iwa<NWA; iwa++) { 14507 out.writeString(ps.mWakeupAlarms.keyAt(iwa)); 14508 ps.mWakeupAlarms.valueAt(iwa).writeSummaryFromParcelLocked(out); 14509 } 14510 NS = ps.mServiceStats.size(); 14511 out.writeInt(NS); 14512 for (int is=0; is<NS; is++) { 14513 out.writeString(ps.mServiceStats.keyAt(is)); 14514 BatteryStatsImpl.Uid.Pkg.Serv ss = ps.mServiceStats.valueAt(is); 14515 long time = ss.getStartTimeToNowLocked( 14516 mOnBatteryTimeBase.getUptime(NOW_SYS)); 14517 out.writeLong(time); 14518 out.writeInt(ss.mStarts); 14519 out.writeInt(ss.mLaunches); 14520 } 14521 } 14522 } 14523 } 14524 } 14525 readFromParcel(Parcel in)14526 public void readFromParcel(Parcel in) { 14527 readFromParcelLocked(in); 14528 } 14529 readFromParcelLocked(Parcel in)14530 void readFromParcelLocked(Parcel in) { 14531 int magic = in.readInt(); 14532 if (magic != MAGIC) { 14533 throw new ParcelFormatException("Bad magic number: #" + Integer.toHexString(magic)); 14534 } 14535 14536 readHistoryBuffer(in, false); 14537 mBatteryStatsHistory.readFromParcel(in); 14538 14539 mStartCount = in.readInt(); 14540 mStartClockTime = in.readLong(); 14541 mStartPlatformVersion = in.readString(); 14542 mEndPlatformVersion = in.readString(); 14543 mUptime = in.readLong(); 14544 mUptimeStart = in.readLong(); 14545 mRealtime = in.readLong(); 14546 mRealtimeStart = in.readLong(); 14547 mOnBattery = in.readInt() != 0; 14548 mEstimatedBatteryCapacity = in.readInt(); 14549 mMinLearnedBatteryCapacity = in.readInt(); 14550 mMaxLearnedBatteryCapacity = in.readInt(); 14551 mOnBatteryInternal = false; // we are no longer really running. 14552 mOnBatteryTimeBase.readFromParcel(in); 14553 mOnBatteryScreenOffTimeBase.readFromParcel(in); 14554 14555 mScreenState = Display.STATE_UNKNOWN; 14556 mScreenOnTimer = new StopwatchTimer(mClocks, null, -1, null, mOnBatteryTimeBase, in); 14557 mScreenDozeTimer = new StopwatchTimer(mClocks, null, -1, null, mOnBatteryTimeBase, in); 14558 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 14559 mScreenBrightnessTimer[i] = new StopwatchTimer(mClocks, null, -100-i, null, 14560 mOnBatteryTimeBase, in); 14561 } 14562 mInteractive = false; 14563 mInteractiveTimer = new StopwatchTimer(mClocks, null, -10, null, mOnBatteryTimeBase, in); 14564 mPhoneOn = false; 14565 mPowerSaveModeEnabledTimer = new StopwatchTimer(mClocks, null, -2, null, 14566 mOnBatteryTimeBase, in); 14567 mLongestLightIdleTime = in.readLong(); 14568 mLongestFullIdleTime = in.readLong(); 14569 mDeviceIdleModeLightTimer = new StopwatchTimer(mClocks, null, -14, null, 14570 mOnBatteryTimeBase, in); 14571 mDeviceIdleModeFullTimer = new StopwatchTimer(mClocks, null, -11, null, 14572 mOnBatteryTimeBase, in); 14573 mDeviceLightIdlingTimer = new StopwatchTimer(mClocks, null, -15, null, 14574 mOnBatteryTimeBase, in); 14575 mDeviceIdlingTimer = new StopwatchTimer(mClocks, null, -12, null, mOnBatteryTimeBase, in); 14576 mPhoneOnTimer = new StopwatchTimer(mClocks, null, -3, null, mOnBatteryTimeBase, in); 14577 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) { 14578 mPhoneSignalStrengthsTimer[i] = new StopwatchTimer(mClocks, null, -200-i, 14579 null, mOnBatteryTimeBase, in); 14580 } 14581 mPhoneSignalScanningTimer = new StopwatchTimer(mClocks, null, -200+1, null, 14582 mOnBatteryTimeBase, in); 14583 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 14584 mPhoneDataConnectionsTimer[i] = new StopwatchTimer(mClocks, null, -300-i, 14585 null, mOnBatteryTimeBase, in); 14586 } 14587 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 14588 mNetworkByteActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase, in); 14589 mNetworkPacketActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase, in); 14590 } 14591 mMobileRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW; 14592 mMobileRadioActiveTimer = new StopwatchTimer(mClocks, null, -400, null, 14593 mOnBatteryTimeBase, in); 14594 mMobileRadioActivePerAppTimer = new StopwatchTimer(mClocks, null, -401, null, 14595 mOnBatteryTimeBase, in); 14596 mMobileRadioActiveAdjustedTime = new LongSamplingCounter(mOnBatteryTimeBase, in); 14597 mMobileRadioActiveUnknownTime = new LongSamplingCounter(mOnBatteryTimeBase, in); 14598 mMobileRadioActiveUnknownCount = new LongSamplingCounter(mOnBatteryTimeBase, in); 14599 mWifiMulticastWakelockTimer = new StopwatchTimer(mClocks, null, -4, null, 14600 mOnBatteryTimeBase, in); 14601 mWifiRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW; 14602 mWifiOn = false; 14603 mWifiOnTimer = new StopwatchTimer(mClocks, null, -4, null, mOnBatteryTimeBase, in); 14604 mGlobalWifiRunning = false; 14605 mGlobalWifiRunningTimer = new StopwatchTimer(mClocks, null, -5, null, 14606 mOnBatteryTimeBase, in); 14607 for (int i=0; i<NUM_WIFI_STATES; i++) { 14608 mWifiStateTimer[i] = new StopwatchTimer(mClocks, null, -600-i, 14609 null, mOnBatteryTimeBase, in); 14610 } 14611 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) { 14612 mWifiSupplStateTimer[i] = new StopwatchTimer(mClocks, null, -700-i, 14613 null, mOnBatteryTimeBase, in); 14614 } 14615 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { 14616 mWifiSignalStrengthsTimer[i] = new StopwatchTimer(mClocks, null, -800-i, 14617 null, mOnBatteryTimeBase, in); 14618 } 14619 mWifiActiveTimer = new StopwatchTimer(mClocks, null, -900, null, 14620 mOnBatteryTimeBase, in); 14621 mWifiActivity = new ControllerActivityCounterImpl(mOnBatteryTimeBase, 14622 NUM_WIFI_TX_LEVELS, in); 14623 for (int i=0; i<GnssMetrics.NUM_GPS_SIGNAL_QUALITY_LEVELS; i++) { 14624 mGpsSignalQualityTimer[i] = new StopwatchTimer(mClocks, null, -1000-i, 14625 null, mOnBatteryTimeBase, in); 14626 } 14627 mBluetoothActivity = new ControllerActivityCounterImpl(mOnBatteryTimeBase, 14628 NUM_BT_TX_LEVELS, in); 14629 mModemActivity = new ControllerActivityCounterImpl(mOnBatteryTimeBase, 14630 ModemActivityInfo.TX_POWER_LEVELS, in); 14631 mHasWifiReporting = in.readInt() != 0; 14632 mHasBluetoothReporting = in.readInt() != 0; 14633 mHasModemReporting = in.readInt() != 0; 14634 14635 mNumConnectivityChange = in.readInt(); 14636 mAudioOnNesting = 0; 14637 // TODO: It's likely a mistake that mAudioOnTimer/mVideoOnTimer don't write/read to parcel! 14638 mAudioOnTimer = new StopwatchTimer(mClocks, null, -7, null, mOnBatteryTimeBase); 14639 mVideoOnNesting = 0; 14640 mVideoOnTimer = new StopwatchTimer(mClocks, null, -8, null, mOnBatteryTimeBase); 14641 mFlashlightOnNesting = 0; 14642 mFlashlightOnTimer = new StopwatchTimer(mClocks, null, -9, null, mOnBatteryTimeBase, in); 14643 mCameraOnNesting = 0; 14644 mCameraOnTimer = new StopwatchTimer(mClocks, null, -13, null, mOnBatteryTimeBase, in); 14645 mBluetoothScanNesting = 0; 14646 mBluetoothScanTimer = new StopwatchTimer(mClocks, null, -14, null, mOnBatteryTimeBase, in); 14647 mIsCellularTxPowerHigh = false; 14648 mDischargeUnplugLevel = in.readInt(); 14649 mDischargePlugLevel = in.readInt(); 14650 mDischargeCurrentLevel = in.readInt(); 14651 mCurrentBatteryLevel = in.readInt(); 14652 mLowDischargeAmountSinceCharge = in.readInt(); 14653 mHighDischargeAmountSinceCharge = in.readInt(); 14654 mDischargeAmountScreenOn = in.readInt(); 14655 mDischargeAmountScreenOnSinceCharge = in.readInt(); 14656 mDischargeAmountScreenOff = in.readInt(); 14657 mDischargeAmountScreenOffSinceCharge = in.readInt(); 14658 mDischargeAmountScreenDoze = in.readInt(); 14659 mDischargeAmountScreenDozeSinceCharge = in.readInt(); 14660 mDischargeStepTracker.readFromParcel(in); 14661 mChargeStepTracker.readFromParcel(in); 14662 mDischargeCounter = new LongSamplingCounter(mOnBatteryTimeBase, in); 14663 mDischargeScreenOffCounter = new LongSamplingCounter(mOnBatteryScreenOffTimeBase, in); 14664 mDischargeScreenDozeCounter = new LongSamplingCounter(mOnBatteryTimeBase, in); 14665 mDischargeLightDozeCounter = new LongSamplingCounter(mOnBatteryTimeBase, in); 14666 mDischargeDeepDozeCounter = new LongSamplingCounter(mOnBatteryTimeBase, in); 14667 mLastWriteTime = in.readLong(); 14668 14669 mRpmStats.clear(); 14670 int NRPMS = in.readInt(); 14671 for (int irpm = 0; irpm < NRPMS; irpm++) { 14672 if (in.readInt() != 0) { 14673 String rpmName = in.readString(); 14674 SamplingTimer rpmt = new SamplingTimer(mClocks, mOnBatteryTimeBase, in); 14675 mRpmStats.put(rpmName, rpmt); 14676 } 14677 } 14678 mScreenOffRpmStats.clear(); 14679 int NSORPMS = in.readInt(); 14680 for (int irpm = 0; irpm < NSORPMS; irpm++) { 14681 if (in.readInt() != 0) { 14682 String rpmName = in.readString(); 14683 SamplingTimer rpmt = new SamplingTimer(mClocks, mOnBatteryScreenOffTimeBase, in); 14684 mScreenOffRpmStats.put(rpmName, rpmt); 14685 } 14686 } 14687 14688 mKernelWakelockStats.clear(); 14689 int NKW = in.readInt(); 14690 for (int ikw = 0; ikw < NKW; ikw++) { 14691 if (in.readInt() != 0) { 14692 String wakelockName = in.readString(); 14693 SamplingTimer kwlt = new SamplingTimer(mClocks, mOnBatteryScreenOffTimeBase, in); 14694 mKernelWakelockStats.put(wakelockName, kwlt); 14695 } 14696 } 14697 14698 mWakeupReasonStats.clear(); 14699 int NWR = in.readInt(); 14700 for (int iwr = 0; iwr < NWR; iwr++) { 14701 if (in.readInt() != 0) { 14702 String reasonName = in.readString(); 14703 SamplingTimer timer = new SamplingTimer(mClocks, mOnBatteryTimeBase, in); 14704 mWakeupReasonStats.put(reasonName, timer); 14705 } 14706 } 14707 14708 mKernelMemoryStats.clear(); 14709 int nmt = in.readInt(); 14710 for (int imt = 0; imt < nmt; imt++) { 14711 if (in.readInt() != 0) { 14712 Long bucket = in.readLong(); 14713 SamplingTimer kmt = new SamplingTimer(mClocks, mOnBatteryTimeBase, in); 14714 mKernelMemoryStats.put(bucket, kmt); 14715 } 14716 } 14717 14718 mPartialTimers.clear(); 14719 mFullTimers.clear(); 14720 mWindowTimers.clear(); 14721 mWifiRunningTimers.clear(); 14722 mFullWifiLockTimers.clear(); 14723 mWifiScanTimers.clear(); 14724 mWifiBatchedScanTimers.clear(); 14725 mWifiMulticastTimers.clear(); 14726 mAudioTurnedOnTimers.clear(); 14727 mVideoTurnedOnTimers.clear(); 14728 mFlashlightTurnedOnTimers.clear(); 14729 mCameraTurnedOnTimers.clear(); 14730 14731 int numUids = in.readInt(); 14732 mUidStats.clear(); 14733 for (int i = 0; i < numUids; i++) { 14734 int uid = in.readInt(); 14735 Uid u = new Uid(this, uid); 14736 u.readFromParcelLocked(mOnBatteryTimeBase, mOnBatteryScreenOffTimeBase, in); 14737 mUidStats.append(uid, u); 14738 } 14739 } 14740 writeToParcel(Parcel out, int flags)14741 public void writeToParcel(Parcel out, int flags) { 14742 writeToParcelLocked(out, true, flags); 14743 } 14744 writeToParcelWithoutUids(Parcel out, int flags)14745 public void writeToParcelWithoutUids(Parcel out, int flags) { 14746 writeToParcelLocked(out, false, flags); 14747 } 14748 14749 @SuppressWarnings("unused") writeToParcelLocked(Parcel out, boolean inclUids, int flags)14750 void writeToParcelLocked(Parcel out, boolean inclUids, int flags) { 14751 // Need to update with current kernel wake lock counts. 14752 pullPendingStateUpdatesLocked(); 14753 14754 // Pull the clock time. This may update the time and make a new history entry 14755 // if we had originally pulled a time before the RTC was set. 14756 getStartClockTime(); 14757 14758 final long uSecUptime = mClocks.uptimeMillis() * 1000; 14759 final long uSecRealtime = mClocks.elapsedRealtime() * 1000; 14760 final long batteryRealtime = mOnBatteryTimeBase.getRealtime(uSecRealtime); 14761 final long batteryScreenOffRealtime = mOnBatteryScreenOffTimeBase.getRealtime(uSecRealtime); 14762 14763 out.writeInt(MAGIC); 14764 14765 writeHistoryBuffer(out, true, false); 14766 mBatteryStatsHistory.writeToParcel(out); 14767 14768 out.writeInt(mStartCount); 14769 out.writeLong(mStartClockTime); 14770 out.writeString(mStartPlatformVersion); 14771 out.writeString(mEndPlatformVersion); 14772 out.writeLong(mUptime); 14773 out.writeLong(mUptimeStart); 14774 out.writeLong(mRealtime); 14775 out.writeLong(mRealtimeStart); 14776 out.writeInt(mOnBattery ? 1 : 0); 14777 out.writeInt(mEstimatedBatteryCapacity); 14778 out.writeInt(mMinLearnedBatteryCapacity); 14779 out.writeInt(mMaxLearnedBatteryCapacity); 14780 mOnBatteryTimeBase.writeToParcel(out, uSecUptime, uSecRealtime); 14781 mOnBatteryScreenOffTimeBase.writeToParcel(out, uSecUptime, uSecRealtime); 14782 14783 mScreenOnTimer.writeToParcel(out, uSecRealtime); 14784 mScreenDozeTimer.writeToParcel(out, uSecRealtime); 14785 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 14786 mScreenBrightnessTimer[i].writeToParcel(out, uSecRealtime); 14787 } 14788 mInteractiveTimer.writeToParcel(out, uSecRealtime); 14789 mPowerSaveModeEnabledTimer.writeToParcel(out, uSecRealtime); 14790 out.writeLong(mLongestLightIdleTime); 14791 out.writeLong(mLongestFullIdleTime); 14792 mDeviceIdleModeLightTimer.writeToParcel(out, uSecRealtime); 14793 mDeviceIdleModeFullTimer.writeToParcel(out, uSecRealtime); 14794 mDeviceLightIdlingTimer.writeToParcel(out, uSecRealtime); 14795 mDeviceIdlingTimer.writeToParcel(out, uSecRealtime); 14796 mPhoneOnTimer.writeToParcel(out, uSecRealtime); 14797 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) { 14798 mPhoneSignalStrengthsTimer[i].writeToParcel(out, uSecRealtime); 14799 } 14800 mPhoneSignalScanningTimer.writeToParcel(out, uSecRealtime); 14801 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 14802 mPhoneDataConnectionsTimer[i].writeToParcel(out, uSecRealtime); 14803 } 14804 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 14805 mNetworkByteActivityCounters[i].writeToParcel(out); 14806 mNetworkPacketActivityCounters[i].writeToParcel(out); 14807 } 14808 mMobileRadioActiveTimer.writeToParcel(out, uSecRealtime); 14809 mMobileRadioActivePerAppTimer.writeToParcel(out, uSecRealtime); 14810 mMobileRadioActiveAdjustedTime.writeToParcel(out); 14811 mMobileRadioActiveUnknownTime.writeToParcel(out); 14812 mMobileRadioActiveUnknownCount.writeToParcel(out); 14813 mWifiMulticastWakelockTimer.writeToParcel(out, uSecRealtime); 14814 mWifiOnTimer.writeToParcel(out, uSecRealtime); 14815 mGlobalWifiRunningTimer.writeToParcel(out, uSecRealtime); 14816 for (int i=0; i<NUM_WIFI_STATES; i++) { 14817 mWifiStateTimer[i].writeToParcel(out, uSecRealtime); 14818 } 14819 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) { 14820 mWifiSupplStateTimer[i].writeToParcel(out, uSecRealtime); 14821 } 14822 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { 14823 mWifiSignalStrengthsTimer[i].writeToParcel(out, uSecRealtime); 14824 } 14825 mWifiActiveTimer.writeToParcel(out, uSecRealtime); 14826 mWifiActivity.writeToParcel(out, 0); 14827 for (int i=0; i< GnssMetrics.NUM_GPS_SIGNAL_QUALITY_LEVELS; i++) { 14828 mGpsSignalQualityTimer[i].writeToParcel(out, uSecRealtime); 14829 } 14830 mBluetoothActivity.writeToParcel(out, 0); 14831 mModemActivity.writeToParcel(out, 0); 14832 out.writeInt(mHasWifiReporting ? 1 : 0); 14833 out.writeInt(mHasBluetoothReporting ? 1 : 0); 14834 out.writeInt(mHasModemReporting ? 1 : 0); 14835 14836 out.writeInt(mNumConnectivityChange); 14837 mFlashlightOnTimer.writeToParcel(out, uSecRealtime); 14838 mCameraOnTimer.writeToParcel(out, uSecRealtime); 14839 mBluetoothScanTimer.writeToParcel(out, uSecRealtime); 14840 out.writeInt(mDischargeUnplugLevel); 14841 out.writeInt(mDischargePlugLevel); 14842 out.writeInt(mDischargeCurrentLevel); 14843 out.writeInt(mCurrentBatteryLevel); 14844 out.writeInt(mLowDischargeAmountSinceCharge); 14845 out.writeInt(mHighDischargeAmountSinceCharge); 14846 out.writeInt(mDischargeAmountScreenOn); 14847 out.writeInt(mDischargeAmountScreenOnSinceCharge); 14848 out.writeInt(mDischargeAmountScreenOff); 14849 out.writeInt(mDischargeAmountScreenOffSinceCharge); 14850 out.writeInt(mDischargeAmountScreenDoze); 14851 out.writeInt(mDischargeAmountScreenDozeSinceCharge); 14852 mDischargeStepTracker.writeToParcel(out); 14853 mChargeStepTracker.writeToParcel(out); 14854 mDischargeCounter.writeToParcel(out); 14855 mDischargeScreenOffCounter.writeToParcel(out); 14856 mDischargeScreenDozeCounter.writeToParcel(out); 14857 mDischargeLightDozeCounter.writeToParcel(out); 14858 mDischargeDeepDozeCounter.writeToParcel(out); 14859 out.writeLong(mLastWriteTime); 14860 14861 out.writeInt(mRpmStats.size()); 14862 for (Map.Entry<String, SamplingTimer> ent : mRpmStats.entrySet()) { 14863 SamplingTimer rpmt = ent.getValue(); 14864 if (rpmt != null) { 14865 out.writeInt(1); 14866 out.writeString(ent.getKey()); 14867 rpmt.writeToParcel(out, uSecRealtime); 14868 } else { 14869 out.writeInt(0); 14870 } 14871 } 14872 out.writeInt(mScreenOffRpmStats.size()); 14873 for (Map.Entry<String, SamplingTimer> ent : mScreenOffRpmStats.entrySet()) { 14874 SamplingTimer rpmt = ent.getValue(); 14875 if (rpmt != null) { 14876 out.writeInt(1); 14877 out.writeString(ent.getKey()); 14878 rpmt.writeToParcel(out, uSecRealtime); 14879 } else { 14880 out.writeInt(0); 14881 } 14882 } 14883 14884 if (inclUids) { 14885 out.writeInt(mKernelWakelockStats.size()); 14886 for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) { 14887 SamplingTimer kwlt = ent.getValue(); 14888 if (kwlt != null) { 14889 out.writeInt(1); 14890 out.writeString(ent.getKey()); 14891 kwlt.writeToParcel(out, uSecRealtime); 14892 } else { 14893 out.writeInt(0); 14894 } 14895 } 14896 out.writeInt(mWakeupReasonStats.size()); 14897 for (Map.Entry<String, SamplingTimer> ent : mWakeupReasonStats.entrySet()) { 14898 SamplingTimer timer = ent.getValue(); 14899 if (timer != null) { 14900 out.writeInt(1); 14901 out.writeString(ent.getKey()); 14902 timer.writeToParcel(out, uSecRealtime); 14903 } else { 14904 out.writeInt(0); 14905 } 14906 } 14907 } else { 14908 out.writeInt(0); 14909 out.writeInt(0); 14910 } 14911 14912 out.writeInt(mKernelMemoryStats.size()); 14913 for (int i = 0; i < mKernelMemoryStats.size(); i++) { 14914 SamplingTimer kmt = mKernelMemoryStats.valueAt(i); 14915 if (kmt != null) { 14916 out.writeInt(1); 14917 out.writeLong(mKernelMemoryStats.keyAt(i)); 14918 kmt.writeToParcel(out, uSecRealtime); 14919 } else { 14920 out.writeInt(0); 14921 } 14922 } 14923 14924 if (inclUids) { 14925 int size = mUidStats.size(); 14926 out.writeInt(size); 14927 for (int i = 0; i < size; i++) { 14928 out.writeInt(mUidStats.keyAt(i)); 14929 Uid uid = mUidStats.valueAt(i); 14930 14931 uid.writeToParcelLocked(out, uSecUptime, uSecRealtime); 14932 } 14933 } else { 14934 out.writeInt(0); 14935 } 14936 } 14937 14938 @UnsupportedAppUsage 14939 public static final Parcelable.Creator<BatteryStatsImpl> CREATOR = 14940 new Parcelable.Creator<BatteryStatsImpl>() { 14941 public BatteryStatsImpl createFromParcel(Parcel in) { 14942 return new BatteryStatsImpl(in); 14943 } 14944 14945 public BatteryStatsImpl[] newArray(int size) { 14946 return new BatteryStatsImpl[size]; 14947 } 14948 }; 14949 prepareForDumpLocked()14950 public void prepareForDumpLocked() { 14951 // Need to retrieve current kernel wake lock stats before printing. 14952 pullPendingStateUpdatesLocked(); 14953 14954 // Pull the clock time. This may update the time and make a new history entry 14955 // if we had originally pulled a time before the RTC was set. 14956 getStartClockTime(); 14957 } 14958 dumpLocked(Context context, PrintWriter pw, int flags, int reqUid, long histStart)14959 public void dumpLocked(Context context, PrintWriter pw, int flags, int reqUid, long histStart) { 14960 if (DEBUG) { 14961 pw.println("mOnBatteryTimeBase:"); 14962 mOnBatteryTimeBase.dump(pw, " "); 14963 pw.println("mOnBatteryScreenOffTimeBase:"); 14964 mOnBatteryScreenOffTimeBase.dump(pw, " "); 14965 Printer pr = new PrintWriterPrinter(pw); 14966 pr.println("*** Screen on timer:"); 14967 mScreenOnTimer.logState(pr, " "); 14968 pr.println("*** Screen doze timer:"); 14969 mScreenDozeTimer.logState(pr, " "); 14970 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 14971 pr.println("*** Screen brightness #" + i + ":"); 14972 mScreenBrightnessTimer[i].logState(pr, " "); 14973 } 14974 pr.println("*** Interactive timer:"); 14975 mInteractiveTimer.logState(pr, " "); 14976 pr.println("*** Power save mode timer:"); 14977 mPowerSaveModeEnabledTimer.logState(pr, " "); 14978 pr.println("*** Device idle mode light timer:"); 14979 mDeviceIdleModeLightTimer.logState(pr, " "); 14980 pr.println("*** Device idle mode full timer:"); 14981 mDeviceIdleModeFullTimer.logState(pr, " "); 14982 pr.println("*** Device light idling timer:"); 14983 mDeviceLightIdlingTimer.logState(pr, " "); 14984 pr.println("*** Device idling timer:"); 14985 mDeviceIdlingTimer.logState(pr, " "); 14986 pr.println("*** Phone timer:"); 14987 mPhoneOnTimer.logState(pr, " "); 14988 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) { 14989 pr.println("*** Phone signal strength #" + i + ":"); 14990 mPhoneSignalStrengthsTimer[i].logState(pr, " "); 14991 } 14992 pr.println("*** Signal scanning :"); 14993 mPhoneSignalScanningTimer.logState(pr, " "); 14994 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 14995 pr.println("*** Data connection type #" + i + ":"); 14996 mPhoneDataConnectionsTimer[i].logState(pr, " "); 14997 } 14998 pr.println("*** mMobileRadioPowerState=" + mMobileRadioPowerState); 14999 pr.println("*** Mobile network active timer:"); 15000 mMobileRadioActiveTimer.logState(pr, " "); 15001 pr.println("*** Mobile network active adjusted timer:"); 15002 mMobileRadioActiveAdjustedTime.logState(pr, " "); 15003 pr.println("*** Wifi Multicast WakeLock Timer:"); 15004 mWifiMulticastWakelockTimer.logState(pr, " "); 15005 pr.println("*** mWifiRadioPowerState=" + mWifiRadioPowerState); 15006 pr.println("*** Wifi timer:"); 15007 mWifiOnTimer.logState(pr, " "); 15008 pr.println("*** WifiRunning timer:"); 15009 mGlobalWifiRunningTimer.logState(pr, " "); 15010 for (int i=0; i<NUM_WIFI_STATES; i++) { 15011 pr.println("*** Wifi state #" + i + ":"); 15012 mWifiStateTimer[i].logState(pr, " "); 15013 } 15014 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) { 15015 pr.println("*** Wifi suppl state #" + i + ":"); 15016 mWifiSupplStateTimer[i].logState(pr, " "); 15017 } 15018 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { 15019 pr.println("*** Wifi signal strength #" + i + ":"); 15020 mWifiSignalStrengthsTimer[i].logState(pr, " "); 15021 } 15022 for (int i=0; i<GnssMetrics.NUM_GPS_SIGNAL_QUALITY_LEVELS; i++) { 15023 pr.println("*** GPS signal quality #" + i + ":"); 15024 mGpsSignalQualityTimer[i].logState(pr, " "); 15025 } 15026 pr.println("*** Flashlight timer:"); 15027 mFlashlightOnTimer.logState(pr, " "); 15028 pr.println("*** Camera timer:"); 15029 mCameraOnTimer.logState(pr, " "); 15030 } 15031 super.dumpLocked(context, pw, flags, reqUid, histStart); 15032 pw.print("Total cpu time reads: "); 15033 pw.println(mNumSingleUidCpuTimeReads); 15034 pw.print("Batched cpu time reads: "); 15035 pw.println(mNumBatchedSingleUidCpuTimeReads); 15036 pw.print("Batching Duration (min): "); 15037 pw.println((mClocks.uptimeMillis() - mCpuTimeReadsTrackingStartTime) / (60 * 1000)); 15038 pw.print("All UID cpu time reads since the later of device start or stats reset: "); 15039 pw.println(mNumAllUidCpuTimeReads); 15040 pw.print("UIDs removed since the later of device start or stats reset: "); 15041 pw.println(mNumUidsRemoved); 15042 } 15043 } 15044