1 /* 2 * Copyright (C) 2006-2007 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.internal.os; 18 19 import android.annotation.NonNull; 20 import android.annotation.Nullable; 21 import android.app.ActivityManager; 22 import android.bluetooth.BluetoothActivityEnergyInfo; 23 import android.bluetooth.UidTraffic; 24 import android.content.BroadcastReceiver; 25 import android.content.ContentResolver; 26 import android.content.Context; 27 import android.content.Intent; 28 import android.content.IntentFilter; 29 import android.database.ContentObserver; 30 import android.hardware.usb.UsbManager; 31 import android.net.ConnectivityManager; 32 import android.net.NetworkStats; 33 import android.net.Uri; 34 import android.net.wifi.WifiActivityEnergyInfo; 35 import android.net.wifi.WifiManager; 36 import android.os.BatteryManager; 37 import android.os.BatteryStats; 38 import android.os.Build; 39 import android.os.FileUtils; 40 import android.os.Handler; 41 import android.os.IBatteryPropertiesRegistrar; 42 import android.os.Looper; 43 import android.os.Message; 44 import android.os.OsProtoEnums; 45 import android.os.Parcel; 46 import android.os.ParcelFormatException; 47 import android.os.Parcelable; 48 import android.os.PowerManager; 49 import android.os.Process; 50 import android.os.RemoteException; 51 import android.os.ServiceManager; 52 import android.os.SystemClock; 53 import android.os.UserHandle; 54 import android.os.WorkSource; 55 import android.os.WorkSource.WorkChain; 56 import android.os.connectivity.CellularBatteryStats; 57 import android.os.connectivity.GpsBatteryStats; 58 import android.os.connectivity.WifiBatteryStats; 59 import android.provider.Settings; 60 import android.telephony.DataConnectionRealTimeInfo; 61 import android.telephony.ModemActivityInfo; 62 import android.telephony.ServiceState; 63 import android.telephony.SignalStrength; 64 import android.telephony.TelephonyManager; 65 import android.text.TextUtils; 66 import android.util.ArrayMap; 67 import android.util.IntArray; 68 import android.util.KeyValueListParser; 69 import android.util.Log; 70 import android.util.LogWriter; 71 import android.util.LongSparseArray; 72 import android.util.LongSparseLongArray; 73 import android.util.MutableInt; 74 import android.util.Pools; 75 import android.util.PrintWriterPrinter; 76 import android.util.Printer; 77 import android.util.Slog; 78 import android.util.SparseArray; 79 import android.util.SparseIntArray; 80 import android.util.SparseLongArray; 81 import android.util.StatsLog; 82 import android.util.TimeUtils; 83 import android.util.Xml; 84 import android.view.Display; 85 86 import com.android.internal.annotations.GuardedBy; 87 import com.android.internal.annotations.VisibleForTesting; 88 import com.android.internal.location.gnssmetrics.GnssMetrics; 89 import com.android.internal.net.NetworkStatsFactory; 90 import com.android.internal.util.ArrayUtils; 91 import com.android.internal.util.FastPrintWriter; 92 import com.android.internal.util.FastXmlSerializer; 93 import com.android.internal.util.JournaledFile; 94 import com.android.internal.util.XmlUtils; 95 96 import libcore.util.EmptyArray; 97 98 import org.xmlpull.v1.XmlPullParser; 99 import org.xmlpull.v1.XmlPullParserException; 100 import org.xmlpull.v1.XmlSerializer; 101 102 import java.io.ByteArrayOutputStream; 103 import java.io.File; 104 import java.io.FileInputStream; 105 import java.io.FileNotFoundException; 106 import java.io.FileOutputStream; 107 import java.io.IOException; 108 import java.io.PrintWriter; 109 import java.nio.charset.StandardCharsets; 110 import java.util.ArrayList; 111 import java.util.Arrays; 112 import java.util.Calendar; 113 import java.util.HashMap; 114 import java.util.Iterator; 115 import java.util.LinkedList; 116 import java.util.List; 117 import java.util.Map; 118 import java.util.Queue; 119 import java.util.concurrent.Future; 120 import java.util.concurrent.atomic.AtomicInteger; 121 import java.util.concurrent.locks.ReentrantLock; 122 123 /** 124 * All information we are collecting about things that can happen that impact 125 * battery life. All times are represented in microseconds except where indicated 126 * otherwise. 127 */ 128 public class BatteryStatsImpl extends BatteryStats { 129 private static final String TAG = "BatteryStatsImpl"; 130 private static final boolean DEBUG = false; 131 public static final boolean DEBUG_ENERGY = false; 132 private static final boolean DEBUG_ENERGY_CPU = DEBUG_ENERGY; 133 private static final boolean DEBUG_MEMORY = false; 134 private static final boolean DEBUG_HISTORY = false; 135 private static final boolean USE_OLD_HISTORY = false; // for debugging. 136 137 // TODO: remove "tcp" from network methods, since we measure total stats. 138 139 // In-memory Parcel magic number, used to detect attempts to unmarshall bad data 140 private static final int MAGIC = 0xBA757475; // 'BATSTATS' 141 142 // Current on-disk Parcel version 143 private static final int VERSION = 177 + (USE_OLD_HISTORY ? 1000 : 0); 144 145 // Maximum number of items we will record in the history. 146 private static final int MAX_HISTORY_ITEMS; 147 148 // No, really, THIS is the maximum number of items we will record in the history. 149 private static final int MAX_MAX_HISTORY_ITEMS; 150 151 // The maximum number of names wakelocks we will keep track of 152 // per uid; once the limit is reached, we batch the remaining wakelocks 153 // in to one common name. 154 private static final int MAX_WAKELOCKS_PER_UID; 155 156 static final int MAX_HISTORY_BUFFER; // 256KB 157 static final int MAX_MAX_HISTORY_BUFFER; // 320KB 158 159 static { 160 if (ActivityManager.isLowRamDeviceStatic()) { 161 MAX_HISTORY_ITEMS = 800; 162 MAX_MAX_HISTORY_ITEMS = 1200; 163 MAX_WAKELOCKS_PER_UID = 40; 164 MAX_HISTORY_BUFFER = 96*1024; // 96KB 165 MAX_MAX_HISTORY_BUFFER = 128*1024; // 128KB 166 } else { 167 MAX_HISTORY_ITEMS = 4000; 168 MAX_MAX_HISTORY_ITEMS = 6000; 169 MAX_WAKELOCKS_PER_UID = 200; 170 MAX_HISTORY_BUFFER = 512*1024; // 512KB 171 MAX_MAX_HISTORY_BUFFER = 640*1024; // 640KB 172 } 173 } 174 175 // Number of transmit power states the Wifi controller can be in. 176 private static final int NUM_WIFI_TX_LEVELS = 1; 177 178 // Number of transmit power states the Bluetooth controller can be in. 179 private static final int NUM_BT_TX_LEVELS = 1; 180 181 /** 182 * Holding a wakelock costs more than just using the cpu. 183 * Currently, we assign only half the cpu time to an app that is running but 184 * not holding a wakelock. The apps holding wakelocks get the rest of the blame. 185 * If no app is holding a wakelock, then the distribution is normal. 186 */ 187 @VisibleForTesting 188 public static final int WAKE_LOCK_WEIGHT = 50; 189 190 protected Clocks mClocks; 191 192 private final JournaledFile mFile; 193 public final AtomicFile mCheckinFile; 194 public final AtomicFile mDailyFile; 195 196 static final int MSG_REPORT_CPU_UPDATE_NEEDED = 1; 197 static final int MSG_REPORT_POWER_CHANGE = 2; 198 static final int MSG_REPORT_CHARGING = 3; 199 static final int MSG_REPORT_RESET_STATS = 4; 200 static final long DELAY_UPDATE_WAKELOCKS = 5*1000; 201 202 private final KernelWakelockReader mKernelWakelockReader = new KernelWakelockReader(); 203 private final KernelWakelockStats mTmpWakelockStats = new KernelWakelockStats(); 204 205 @VisibleForTesting 206 protected KernelUidCpuTimeReader mKernelUidCpuTimeReader = new KernelUidCpuTimeReader(); 207 @VisibleForTesting 208 protected KernelCpuSpeedReader[] mKernelCpuSpeedReaders; 209 @VisibleForTesting 210 protected KernelUidCpuFreqTimeReader mKernelUidCpuFreqTimeReader = 211 new KernelUidCpuFreqTimeReader(); 212 @VisibleForTesting 213 protected KernelUidCpuActiveTimeReader mKernelUidCpuActiveTimeReader = 214 new KernelUidCpuActiveTimeReader(); 215 @VisibleForTesting 216 protected KernelUidCpuClusterTimeReader mKernelUidCpuClusterTimeReader = 217 new KernelUidCpuClusterTimeReader(); 218 @VisibleForTesting 219 protected KernelSingleUidTimeReader mKernelSingleUidTimeReader; 220 221 private final KernelMemoryBandwidthStats mKernelMemoryBandwidthStats 222 = new KernelMemoryBandwidthStats(); 223 private final LongSparseArray<SamplingTimer> mKernelMemoryStats = new LongSparseArray<>(); getKernelMemoryStats()224 public LongSparseArray<SamplingTimer> getKernelMemoryStats() { 225 return mKernelMemoryStats; 226 } 227 228 @GuardedBy("this") 229 public boolean mPerProcStateCpuTimesAvailable = true; 230 231 /** 232 * Uids for which per-procstate cpu times need to be updated. 233 * 234 * Contains uid -> procState mappings. 235 */ 236 @GuardedBy("this") 237 @VisibleForTesting 238 protected final SparseIntArray mPendingUids = new SparseIntArray(); 239 240 @GuardedBy("this") 241 private long mNumSingleUidCpuTimeReads; 242 @GuardedBy("this") 243 private long mNumBatchedSingleUidCpuTimeReads; 244 @GuardedBy("this") 245 private long mCpuTimeReadsTrackingStartTime = SystemClock.uptimeMillis(); 246 @GuardedBy("this") 247 private int mNumUidsRemoved; 248 @GuardedBy("this") 249 private int mNumAllUidCpuTimeReads; 250 251 /** Container for Resource Power Manager stats. Updated by updateRpmStatsLocked. */ 252 private final RpmStats mTmpRpmStats = new RpmStats(); 253 /** The soonest the RPM stats can be updated after it was last updated. */ 254 private static final long RPM_STATS_UPDATE_FREQ_MS = 1000; 255 /** Last time that RPM stats were updated by updateRpmStatsLocked. */ 256 private long mLastRpmStatsUpdateTimeMs = -RPM_STATS_UPDATE_FREQ_MS; 257 /** 258 * Use a queue to delay removing UIDs from {@link KernelUidCpuTimeReader}, 259 * {@link KernelUidCpuActiveTimeReader}, {@link KernelUidCpuClusterTimeReader}, 260 * {@link KernelUidCpuFreqTimeReader} and from the Kernel. 261 * 262 * Isolated and invalid UID info must be removed to conserve memory. However, STATSD and 263 * Batterystats both need to access UID cpu time. To resolve this race condition, only 264 * Batterystats shall remove UIDs, and a delay {@link Constants#UID_REMOVE_DELAY_MS} is 265 * implemented so that STATSD can capture those UID times before they are deleted. 266 */ 267 @GuardedBy("this") 268 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) 269 protected Queue<UidToRemove> mPendingRemovedUids = new LinkedList<>(); 270 271 @VisibleForTesting 272 public final class UidToRemove { 273 int startUid; 274 int endUid; 275 long timeAddedInQueue; 276 277 /** Remove just one UID */ UidToRemove(int uid, long timestamp)278 public UidToRemove(int uid, long timestamp) { 279 this(uid, uid, timestamp); 280 } 281 282 /** Remove a range of UIDs, startUid must be smaller than endUid. */ UidToRemove(int startUid, int endUid, long timestamp)283 public UidToRemove(int startUid, int endUid, long timestamp) { 284 this.startUid = startUid; 285 this.endUid = endUid; 286 timeAddedInQueue = timestamp; 287 } 288 remove()289 void remove() { 290 if (startUid == endUid) { 291 mKernelUidCpuTimeReader.removeUid(startUid); 292 mKernelUidCpuFreqTimeReader.removeUid(startUid); 293 if (mConstants.TRACK_CPU_ACTIVE_CLUSTER_TIME) { 294 mKernelUidCpuActiveTimeReader.removeUid(startUid); 295 mKernelUidCpuClusterTimeReader.removeUid(startUid); 296 } 297 if (mKernelSingleUidTimeReader != null) { 298 mKernelSingleUidTimeReader.removeUid(startUid); 299 } 300 mNumUidsRemoved++; 301 } else if (startUid < endUid) { 302 mKernelUidCpuFreqTimeReader.removeUidsInRange(startUid, endUid); 303 mKernelUidCpuTimeReader.removeUidsInRange(startUid, endUid); 304 if (mConstants.TRACK_CPU_ACTIVE_CLUSTER_TIME) { 305 mKernelUidCpuActiveTimeReader.removeUidsInRange(startUid, endUid); 306 mKernelUidCpuClusterTimeReader.removeUidsInRange(startUid, endUid); 307 } 308 if (mKernelSingleUidTimeReader != null) { 309 mKernelSingleUidTimeReader.removeUidsInRange(startUid, endUid); 310 } 311 // Treat as one. We don't know how many uids there are in between. 312 mNumUidsRemoved++; 313 } else { 314 Slog.w(TAG, "End UID " + endUid + " is smaller than start UID " + startUid); 315 } 316 } 317 } 318 319 public interface BatteryCallback { batteryNeedsCpuUpdate()320 public void batteryNeedsCpuUpdate(); batteryPowerChanged(boolean onBattery)321 public void batteryPowerChanged(boolean onBattery); batterySendBroadcast(Intent intent)322 public void batterySendBroadcast(Intent intent); batteryStatsReset()323 public void batteryStatsReset(); 324 } 325 326 public interface PlatformIdleStateCallback { fillLowPowerStats(RpmStats rpmStats)327 public void fillLowPowerStats(RpmStats rpmStats); getPlatformLowPowerStats()328 public String getPlatformLowPowerStats(); getSubsystemLowPowerStats()329 public String getSubsystemLowPowerStats(); 330 } 331 332 public static abstract class UserInfoProvider { 333 private int[] userIds; getUserIds()334 protected abstract @Nullable int[] getUserIds(); 335 @VisibleForTesting refreshUserIds()336 public final void refreshUserIds() { 337 userIds = getUserIds(); 338 } 339 @VisibleForTesting exists(int userId)340 public boolean exists(int userId) { 341 return userIds != null ? ArrayUtils.contains(userIds, userId) : true; 342 } 343 } 344 345 private final PlatformIdleStateCallback mPlatformIdleStateCallback; 346 347 final class MyHandler extends Handler { MyHandler(Looper looper)348 public MyHandler(Looper looper) { 349 super(looper, null, true); 350 } 351 352 @Override handleMessage(Message msg)353 public void handleMessage(Message msg) { 354 BatteryCallback cb = mCallback; 355 switch (msg.what) { 356 case MSG_REPORT_CPU_UPDATE_NEEDED: 357 if (cb != null) { 358 cb.batteryNeedsCpuUpdate(); 359 } 360 break; 361 case MSG_REPORT_POWER_CHANGE: 362 if (cb != null) { 363 cb.batteryPowerChanged(msg.arg1 != 0); 364 } 365 break; 366 case MSG_REPORT_CHARGING: 367 if (cb != null) { 368 final String action; 369 synchronized (BatteryStatsImpl.this) { 370 action = mCharging ? BatteryManager.ACTION_CHARGING 371 : BatteryManager.ACTION_DISCHARGING; 372 } 373 Intent intent = new Intent(action); 374 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); 375 cb.batterySendBroadcast(intent); 376 } 377 break; 378 case MSG_REPORT_RESET_STATS: 379 if (cb != null) { 380 cb.batteryStatsReset(); 381 } 382 } 383 } 384 } 385 postBatteryNeedsCpuUpdateMsg()386 public void postBatteryNeedsCpuUpdateMsg() { 387 mHandler.sendEmptyMessage(MSG_REPORT_CPU_UPDATE_NEEDED); 388 } 389 390 /** 391 * Update per-freq cpu times for all the uids in {@link #mPendingUids}. 392 */ updateProcStateCpuTimes(boolean onBattery, boolean onBatteryScreenOff)393 public void updateProcStateCpuTimes(boolean onBattery, boolean onBatteryScreenOff) { 394 final SparseIntArray uidStates; 395 synchronized (BatteryStatsImpl.this) { 396 if (!mConstants.TRACK_CPU_TIMES_BY_PROC_STATE) { 397 return; 398 } 399 if(!initKernelSingleUidTimeReaderLocked()) { 400 return; 401 } 402 // If the KernelSingleUidTimeReader has stale cpu times, then we shouldn't try to 403 // compute deltas since it might result in mis-attributing cpu times to wrong states. 404 if (mKernelSingleUidTimeReader.hasStaleData()) { 405 mPendingUids.clear(); 406 return; 407 } 408 409 if (mPendingUids.size() == 0) { 410 return; 411 } 412 uidStates = mPendingUids.clone(); 413 mPendingUids.clear(); 414 } 415 for (int i = uidStates.size() - 1; i >= 0; --i) { 416 final int uid = uidStates.keyAt(i); 417 final int procState = uidStates.valueAt(i); 418 final int[] isolatedUids; 419 final Uid u; 420 synchronized (BatteryStatsImpl.this) { 421 // It's possible that uid no longer exists and any internal references have 422 // already been deleted, so using {@link #getAvailableUidStatsLocked} to avoid 423 // creating an UidStats object if it doesn't already exist. 424 u = getAvailableUidStatsLocked(uid); 425 if (u == null) { 426 continue; 427 } 428 if (u.mChildUids == null) { 429 isolatedUids = null; 430 } else { 431 isolatedUids = u.mChildUids.toArray(); 432 for (int j = isolatedUids.length - 1; j >= 0; --j) { 433 isolatedUids[j] = u.mChildUids.get(j); 434 } 435 } 436 } 437 long[] cpuTimesMs = mKernelSingleUidTimeReader.readDeltaMs(uid); 438 if (isolatedUids != null) { 439 for (int j = isolatedUids.length - 1; j >= 0; --j) { 440 cpuTimesMs = addCpuTimes(cpuTimesMs, 441 mKernelSingleUidTimeReader.readDeltaMs(isolatedUids[j])); 442 } 443 } 444 if (onBattery && cpuTimesMs != null) { 445 synchronized (BatteryStatsImpl.this) { 446 u.addProcStateTimesMs(procState, cpuTimesMs, onBattery); 447 u.addProcStateScreenOffTimesMs(procState, cpuTimesMs, onBatteryScreenOff); 448 } 449 } 450 } 451 } 452 clearPendingRemovedUids()453 public void clearPendingRemovedUids() { 454 long cutOffTime = mClocks.elapsedRealtime() - mConstants.UID_REMOVE_DELAY_MS; 455 while (!mPendingRemovedUids.isEmpty() 456 && mPendingRemovedUids.peek().timeAddedInQueue < cutOffTime) { 457 mPendingRemovedUids.poll().remove(); 458 } 459 } 460 copyFromAllUidsCpuTimes()461 public void copyFromAllUidsCpuTimes() { 462 synchronized (BatteryStatsImpl.this) { 463 copyFromAllUidsCpuTimes( 464 mOnBatteryTimeBase.isRunning(), mOnBatteryScreenOffTimeBase.isRunning()); 465 } 466 } 467 468 /** 469 * When the battery/screen state changes, we don't attribute the cpu times to any process 470 * but we still need to snapshots of all uids to get correct deltas later on. Since we 471 * already read this data for updating per-freq cpu times, we can use the same data for 472 * per-procstate cpu times. 473 */ copyFromAllUidsCpuTimes(boolean onBattery, boolean onBatteryScreenOff)474 public void copyFromAllUidsCpuTimes(boolean onBattery, boolean onBatteryScreenOff) { 475 synchronized (BatteryStatsImpl.this) { 476 if (!mConstants.TRACK_CPU_TIMES_BY_PROC_STATE) { 477 return; 478 } 479 if(!initKernelSingleUidTimeReaderLocked()) { 480 return; 481 } 482 483 final SparseArray<long[]> allUidCpuFreqTimesMs = 484 mKernelUidCpuFreqTimeReader.getAllUidCpuFreqTimeMs(); 485 // If the KernelSingleUidTimeReader has stale cpu times, then we shouldn't try to 486 // compute deltas since it might result in mis-attributing cpu times to wrong states. 487 if (mKernelSingleUidTimeReader.hasStaleData()) { 488 mKernelSingleUidTimeReader.setAllUidsCpuTimesMs(allUidCpuFreqTimesMs); 489 mKernelSingleUidTimeReader.markDataAsStale(false); 490 mPendingUids.clear(); 491 return; 492 } 493 for (int i = allUidCpuFreqTimesMs.size() - 1; i >= 0; --i) { 494 final int uid = allUidCpuFreqTimesMs.keyAt(i); 495 final Uid u = getAvailableUidStatsLocked(mapUid(uid)); 496 if (u == null) { 497 continue; 498 } 499 final long[] cpuTimesMs = allUidCpuFreqTimesMs.valueAt(i); 500 if (cpuTimesMs == null) { 501 continue; 502 } 503 final long[] deltaTimesMs = mKernelSingleUidTimeReader.computeDelta( 504 uid, cpuTimesMs.clone()); 505 if (onBattery && deltaTimesMs != null) { 506 final int procState; 507 final int idx = mPendingUids.indexOfKey(uid); 508 if (idx >= 0) { 509 procState = mPendingUids.valueAt(idx); 510 mPendingUids.removeAt(idx); 511 } else { 512 procState = u.mProcessState; 513 } 514 if (procState >= 0 && procState < Uid.NUM_PROCESS_STATE) { 515 u.addProcStateTimesMs(procState, deltaTimesMs, onBattery); 516 u.addProcStateScreenOffTimesMs(procState, deltaTimesMs, onBatteryScreenOff); 517 } 518 } 519 } 520 } 521 } 522 523 @VisibleForTesting addCpuTimes(long[] timesA, long[] timesB)524 public long[] addCpuTimes(long[] timesA, long[] timesB) { 525 if (timesA != null && timesB != null) { 526 for (int i = timesA.length - 1; i >= 0; --i) { 527 timesA[i] += timesB[i]; 528 } 529 return timesA; 530 } 531 return timesA == null ? (timesB == null ? null : timesB) : timesA; 532 } 533 534 @GuardedBy("this") initKernelSingleUidTimeReaderLocked()535 private boolean initKernelSingleUidTimeReaderLocked() { 536 if (mKernelSingleUidTimeReader == null) { 537 if (mPowerProfile == null) { 538 return false; 539 } 540 if (mCpuFreqs == null) { 541 mCpuFreqs = mKernelUidCpuFreqTimeReader.readFreqs(mPowerProfile); 542 } 543 if (mCpuFreqs != null) { 544 mKernelSingleUidTimeReader = new KernelSingleUidTimeReader(mCpuFreqs.length); 545 } else { 546 mPerProcStateCpuTimesAvailable = mKernelUidCpuFreqTimeReader.allUidTimesAvailable(); 547 return false; 548 } 549 } 550 mPerProcStateCpuTimesAvailable = mKernelUidCpuFreqTimeReader.allUidTimesAvailable() 551 && mKernelSingleUidTimeReader.singleUidCpuTimesAvailable(); 552 return true; 553 } 554 555 public interface Clocks { elapsedRealtime()556 public long elapsedRealtime(); uptimeMillis()557 public long uptimeMillis(); 558 } 559 560 public static class SystemClocks implements Clocks { elapsedRealtime()561 public long elapsedRealtime() { 562 return SystemClock.elapsedRealtime(); 563 } 564 uptimeMillis()565 public long uptimeMillis() { 566 return SystemClock.uptimeMillis(); 567 } 568 } 569 570 public interface ExternalStatsSync { 571 int UPDATE_CPU = 0x01; 572 int UPDATE_WIFI = 0x02; 573 int UPDATE_RADIO = 0x04; 574 int UPDATE_BT = 0x08; 575 int UPDATE_RPM = 0x10; // 16 576 int UPDATE_ALL = UPDATE_CPU | UPDATE_WIFI | UPDATE_RADIO | UPDATE_BT | UPDATE_RPM; 577 scheduleSync(String reason, int flags)578 Future<?> scheduleSync(String reason, int flags); scheduleCpuSyncDueToRemovedUid(int uid)579 Future<?> scheduleCpuSyncDueToRemovedUid(int uid); scheduleReadProcStateCpuTimes(boolean onBattery, boolean onBatteryScreenOff, long delayMillis)580 Future<?> scheduleReadProcStateCpuTimes(boolean onBattery, boolean onBatteryScreenOff, 581 long delayMillis); scheduleCopyFromAllUidsCpuTimes(boolean onBattery, boolean onBatteryScreenOff)582 Future<?> scheduleCopyFromAllUidsCpuTimes(boolean onBattery, boolean onBatteryScreenOff); scheduleCpuSyncDueToSettingChange()583 Future<?> scheduleCpuSyncDueToSettingChange(); scheduleCpuSyncDueToScreenStateChange(boolean onBattery, boolean onBatteryScreenOff)584 Future<?> scheduleCpuSyncDueToScreenStateChange(boolean onBattery, 585 boolean onBatteryScreenOff); scheduleCpuSyncDueToWakelockChange(long delayMillis)586 Future<?> scheduleCpuSyncDueToWakelockChange(long delayMillis); cancelCpuSyncDueToWakelockChange()587 void cancelCpuSyncDueToWakelockChange(); scheduleSyncDueToBatteryLevelChange(long delayMillis)588 Future<?> scheduleSyncDueToBatteryLevelChange(long delayMillis); 589 } 590 591 public Handler mHandler; 592 private ExternalStatsSync mExternalSync = null; 593 @VisibleForTesting 594 protected UserInfoProvider mUserInfoProvider = null; 595 596 private BatteryCallback mCallback; 597 598 /** 599 * Mapping isolated uids to the actual owning app uid. 600 */ 601 final SparseIntArray mIsolatedUids = new SparseIntArray(); 602 603 /** 604 * The statistics we have collected organized by uids. 605 */ 606 final SparseArray<BatteryStatsImpl.Uid> mUidStats = new SparseArray<>(); 607 608 // A set of pools of currently active timers. When a timer is queried, we will divide the 609 // elapsed time by the number of active timers to arrive at that timer's share of the time. 610 // In order to do this, we must refresh each timer whenever the number of active timers 611 // changes. 612 @VisibleForTesting 613 protected ArrayList<StopwatchTimer> mPartialTimers = new ArrayList<>(); 614 final ArrayList<StopwatchTimer> mFullTimers = new ArrayList<>(); 615 final ArrayList<StopwatchTimer> mWindowTimers = new ArrayList<>(); 616 final ArrayList<StopwatchTimer> mDrawTimers = new ArrayList<>(); 617 final SparseArray<ArrayList<StopwatchTimer>> mSensorTimers = new SparseArray<>(); 618 final ArrayList<StopwatchTimer> mWifiRunningTimers = new ArrayList<>(); 619 final ArrayList<StopwatchTimer> mFullWifiLockTimers = new ArrayList<>(); 620 final ArrayList<StopwatchTimer> mWifiMulticastTimers = new ArrayList<>(); 621 final ArrayList<StopwatchTimer> mWifiScanTimers = new ArrayList<>(); 622 final SparseArray<ArrayList<StopwatchTimer>> mWifiBatchedScanTimers = new SparseArray<>(); 623 final ArrayList<StopwatchTimer> mAudioTurnedOnTimers = new ArrayList<>(); 624 final ArrayList<StopwatchTimer> mVideoTurnedOnTimers = new ArrayList<>(); 625 final ArrayList<StopwatchTimer> mFlashlightTurnedOnTimers = new ArrayList<>(); 626 final ArrayList<StopwatchTimer> mCameraTurnedOnTimers = new ArrayList<>(); 627 final ArrayList<StopwatchTimer> mBluetoothScanOnTimers = new ArrayList<>(); 628 629 // Last partial timers we use for distributing CPU usage. 630 @VisibleForTesting 631 protected ArrayList<StopwatchTimer> mLastPartialTimers = new ArrayList<>(); 632 633 // These are the objects that will want to do something when the device 634 // is unplugged from power. 635 protected final TimeBase mOnBatteryTimeBase = new TimeBase(); 636 637 // These are the objects that will want to do something when the device 638 // is unplugged from power *and* the screen is off or doze. 639 protected final TimeBase mOnBatteryScreenOffTimeBase = new TimeBase(); 640 641 // Set to true when we want to distribute CPU across wakelocks for the next 642 // CPU update, even if we aren't currently running wake locks. 643 boolean mDistributeWakelockCpu; 644 645 boolean mShuttingDown; 646 647 final HistoryEventTracker mActiveEvents = new HistoryEventTracker(); 648 649 long mHistoryBaseTime; 650 protected boolean mHaveBatteryLevel = false; 651 protected boolean mRecordingHistory = false; 652 int mNumHistoryItems; 653 654 final Parcel mHistoryBuffer = Parcel.obtain(); 655 final HistoryItem mHistoryLastWritten = new HistoryItem(); 656 final HistoryItem mHistoryLastLastWritten = new HistoryItem(); 657 final HistoryItem mHistoryReadTmp = new HistoryItem(); 658 final HistoryItem mHistoryAddTmp = new HistoryItem(); 659 final HashMap<HistoryTag, Integer> mHistoryTagPool = new HashMap<>(); 660 String[] mReadHistoryStrings; 661 int[] mReadHistoryUids; 662 int mReadHistoryChars; 663 int mNextHistoryTagIdx = 0; 664 int mNumHistoryTagChars = 0; 665 int mHistoryBufferLastPos = -1; 666 boolean mHistoryOverflow = false; 667 int mActiveHistoryStates = 0xffffffff; 668 int mActiveHistoryStates2 = 0xffffffff; 669 long mLastHistoryElapsedRealtime = 0; 670 long mTrackRunningHistoryElapsedRealtime = 0; 671 long mTrackRunningHistoryUptime = 0; 672 673 final HistoryItem mHistoryCur = new HistoryItem(); 674 675 HistoryItem mHistory; 676 HistoryItem mHistoryEnd; 677 HistoryItem mHistoryLastEnd; 678 HistoryItem mHistoryCache; 679 680 // Used by computeHistoryStepDetails 681 HistoryStepDetails mLastHistoryStepDetails = null; 682 byte mLastHistoryStepLevel = 0; 683 final HistoryStepDetails mCurHistoryStepDetails = new HistoryStepDetails(); 684 final HistoryStepDetails mReadHistoryStepDetails = new HistoryStepDetails(); 685 final HistoryStepDetails mTmpHistoryStepDetails = new HistoryStepDetails(); 686 687 /** 688 * Total time (in milliseconds) spent executing in user code. 689 */ 690 long mLastStepCpuUserTime; 691 long mCurStepCpuUserTime; 692 /** 693 * Total time (in milliseconds) spent executing in kernel code. 694 */ 695 long mLastStepCpuSystemTime; 696 long mCurStepCpuSystemTime; 697 /** 698 * Times from /proc/stat (but measured in milliseconds). 699 */ 700 long mLastStepStatUserTime; 701 long mLastStepStatSystemTime; 702 long mLastStepStatIOWaitTime; 703 long mLastStepStatIrqTime; 704 long mLastStepStatSoftIrqTime; 705 long mLastStepStatIdleTime; 706 long mCurStepStatUserTime; 707 long mCurStepStatSystemTime; 708 long mCurStepStatIOWaitTime; 709 long mCurStepStatIrqTime; 710 long mCurStepStatSoftIrqTime; 711 long mCurStepStatIdleTime; 712 713 private HistoryItem mHistoryIterator; 714 private boolean mReadOverflow; 715 private boolean mIteratingHistory; 716 717 int mStartCount; 718 719 long mStartClockTime; 720 String mStartPlatformVersion; 721 String mEndPlatformVersion; 722 723 long mUptime; 724 long mUptimeStart; 725 long mRealtime; 726 long mRealtimeStart; 727 728 int mWakeLockNesting; 729 boolean mWakeLockImportant; 730 public boolean mRecordAllHistory; 731 boolean mNoAutoReset; 732 733 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) 734 protected int mScreenState = Display.STATE_UNKNOWN; 735 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) 736 protected StopwatchTimer mScreenOnTimer; 737 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) 738 protected StopwatchTimer mScreenDozeTimer; 739 740 int mScreenBrightnessBin = -1; 741 final StopwatchTimer[] mScreenBrightnessTimer = new StopwatchTimer[NUM_SCREEN_BRIGHTNESS_BINS]; 742 743 boolean mPretendScreenOff; 744 745 boolean mInteractive; 746 StopwatchTimer mInteractiveTimer; 747 748 boolean mPowerSaveModeEnabled; 749 StopwatchTimer mPowerSaveModeEnabledTimer; 750 751 boolean mDeviceIdling; 752 StopwatchTimer mDeviceIdlingTimer; 753 754 boolean mDeviceLightIdling; 755 StopwatchTimer mDeviceLightIdlingTimer; 756 757 int mDeviceIdleMode; 758 long mLastIdleTimeStart; 759 long mLongestLightIdleTime; 760 long mLongestFullIdleTime; 761 StopwatchTimer mDeviceIdleModeLightTimer; 762 StopwatchTimer mDeviceIdleModeFullTimer; 763 764 boolean mPhoneOn; 765 StopwatchTimer mPhoneOnTimer; 766 767 int mAudioOnNesting; 768 StopwatchTimer mAudioOnTimer; 769 770 int mVideoOnNesting; 771 StopwatchTimer mVideoOnTimer; 772 773 int mFlashlightOnNesting; 774 StopwatchTimer mFlashlightOnTimer; 775 776 int mCameraOnNesting; 777 StopwatchTimer mCameraOnTimer; 778 779 private static final int USB_DATA_UNKNOWN = 0; 780 private static final int USB_DATA_DISCONNECTED = 1; 781 private static final int USB_DATA_CONNECTED = 2; 782 int mUsbDataState = USB_DATA_UNKNOWN; 783 784 int mGpsSignalQualityBin = -1; 785 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) 786 protected final StopwatchTimer[] mGpsSignalQualityTimer = 787 new StopwatchTimer[GnssMetrics.NUM_GPS_SIGNAL_QUALITY_LEVELS]; 788 789 int mPhoneSignalStrengthBin = -1; 790 int mPhoneSignalStrengthBinRaw = -1; 791 final StopwatchTimer[] mPhoneSignalStrengthsTimer = 792 new StopwatchTimer[SignalStrength.NUM_SIGNAL_STRENGTH_BINS]; 793 794 StopwatchTimer mPhoneSignalScanningTimer; 795 796 int mPhoneDataConnectionType = -1; 797 final StopwatchTimer[] mPhoneDataConnectionsTimer = 798 new StopwatchTimer[NUM_DATA_CONNECTION_TYPES]; 799 800 final LongSamplingCounter[] mNetworkByteActivityCounters = 801 new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES]; 802 final LongSamplingCounter[] mNetworkPacketActivityCounters = 803 new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES]; 804 805 /** 806 * The WiFi Overall wakelock timer 807 * This timer tracks the actual aggregate time for which MC wakelocks are enabled 808 * since addition of per UID timers would not result in an accurate value due to overlapp of 809 * per uid wakelock timers 810 */ 811 StopwatchTimer mWifiMulticastWakelockTimer; 812 813 /** 814 * The WiFi controller activity (time in tx, rx, idle, and power consumed) for the device. 815 */ 816 ControllerActivityCounterImpl mWifiActivity; 817 818 /** 819 * The Bluetooth controller activity (time in tx, rx, idle, and power consumed) for the device. 820 */ 821 ControllerActivityCounterImpl mBluetoothActivity; 822 823 /** 824 * The Modem controller activity (time in tx, rx, idle, and power consumed) for the device. 825 */ 826 ControllerActivityCounterImpl mModemActivity; 827 828 /** 829 * Whether the device supports WiFi controller energy reporting. This is set to true on 830 * the first WiFi energy report. See {@link #mWifiActivity}. 831 */ 832 boolean mHasWifiReporting = false; 833 834 /** 835 * Whether the device supports Bluetooth controller energy reporting. This is set to true on 836 * the first Bluetooth energy report. See {@link #mBluetoothActivity}. 837 */ 838 boolean mHasBluetoothReporting = false; 839 840 /** 841 * Whether the device supports Modem controller energy reporting. This is set to true on 842 * the first Modem energy report. See {@link #mModemActivity}. 843 */ 844 boolean mHasModemReporting = false; 845 846 boolean mWifiOn; 847 StopwatchTimer mWifiOnTimer; 848 849 boolean mGlobalWifiRunning; 850 StopwatchTimer mGlobalWifiRunningTimer; 851 852 int mWifiState = -1; 853 final StopwatchTimer[] mWifiStateTimer = new StopwatchTimer[NUM_WIFI_STATES]; 854 855 int mWifiSupplState = -1; 856 final StopwatchTimer[] mWifiSupplStateTimer = new StopwatchTimer[NUM_WIFI_SUPPL_STATES]; 857 858 int mWifiSignalStrengthBin = -1; 859 final StopwatchTimer[] mWifiSignalStrengthsTimer = 860 new StopwatchTimer[NUM_WIFI_SIGNAL_STRENGTH_BINS]; 861 862 StopwatchTimer mWifiActiveTimer; 863 864 int mBluetoothScanNesting; 865 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) 866 protected StopwatchTimer mBluetoothScanTimer; 867 868 boolean mIsCellularTxPowerHigh = false; 869 870 int mMobileRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW; 871 long mMobileRadioActiveStartTime; 872 StopwatchTimer mMobileRadioActiveTimer; 873 StopwatchTimer mMobileRadioActivePerAppTimer; 874 LongSamplingCounter mMobileRadioActiveAdjustedTime; 875 LongSamplingCounter mMobileRadioActiveUnknownTime; 876 LongSamplingCounter mMobileRadioActiveUnknownCount; 877 878 int mWifiRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW; 879 880 /** 881 * These provide time bases that discount the time the device is plugged 882 * in to power. 883 */ 884 boolean mOnBattery; 885 @VisibleForTesting 886 protected boolean mOnBatteryInternal; 887 888 /** 889 * External reporting of whether the device is actually charging. 890 */ 891 boolean mCharging = true; 892 int mLastChargingStateLevel; 893 894 /* 895 * These keep track of battery levels (1-100) at the last plug event and the last unplug event. 896 */ 897 int mDischargeStartLevel; 898 int mDischargeUnplugLevel; 899 int mDischargePlugLevel; 900 int mDischargeCurrentLevel; 901 int mCurrentBatteryLevel; 902 int mLowDischargeAmountSinceCharge; 903 int mHighDischargeAmountSinceCharge; 904 int mDischargeScreenOnUnplugLevel; 905 int mDischargeScreenOffUnplugLevel; 906 int mDischargeScreenDozeUnplugLevel; 907 int mDischargeAmountScreenOn; 908 int mDischargeAmountScreenOnSinceCharge; 909 int mDischargeAmountScreenOff; 910 int mDischargeAmountScreenOffSinceCharge; 911 int mDischargeAmountScreenDoze; 912 int mDischargeAmountScreenDozeSinceCharge; 913 914 private LongSamplingCounter mDischargeScreenOffCounter; 915 private LongSamplingCounter mDischargeScreenDozeCounter; 916 private LongSamplingCounter mDischargeCounter; 917 private LongSamplingCounter mDischargeLightDozeCounter; 918 private LongSamplingCounter mDischargeDeepDozeCounter; 919 920 static final int MAX_LEVEL_STEPS = 200; 921 922 int mInitStepMode = 0; 923 int mCurStepMode = 0; 924 int mModStepMode = 0; 925 926 int mLastDischargeStepLevel; 927 int mMinDischargeStepLevel; 928 final LevelStepTracker mDischargeStepTracker = new LevelStepTracker(MAX_LEVEL_STEPS); 929 final LevelStepTracker mDailyDischargeStepTracker = new LevelStepTracker(MAX_LEVEL_STEPS*2); 930 ArrayList<PackageChange> mDailyPackageChanges; 931 932 int mLastChargeStepLevel; 933 int mMaxChargeStepLevel; 934 final LevelStepTracker mChargeStepTracker = new LevelStepTracker(MAX_LEVEL_STEPS); 935 final LevelStepTracker mDailyChargeStepTracker = new LevelStepTracker(MAX_LEVEL_STEPS*2); 936 937 static final int MAX_DAILY_ITEMS = 10; 938 939 long mDailyStartTime = 0; 940 long mNextMinDailyDeadline = 0; 941 long mNextMaxDailyDeadline = 0; 942 943 final ArrayList<DailyItem> mDailyItems = new ArrayList<>(); 944 945 long mLastWriteTime = 0; // Milliseconds 946 947 private int mPhoneServiceState = -1; 948 private int mPhoneServiceStateRaw = -1; 949 private int mPhoneSimStateRaw = -1; 950 951 private int mNumConnectivityChange; 952 private int mLoadedNumConnectivityChange; 953 private int mUnpluggedNumConnectivityChange; 954 955 private int mEstimatedBatteryCapacity = -1; 956 957 private int mMinLearnedBatteryCapacity = -1; 958 private int mMaxLearnedBatteryCapacity = -1; 959 960 private long[] mCpuFreqs; 961 962 @VisibleForTesting 963 protected PowerProfile mPowerProfile; 964 965 @GuardedBy("this") 966 private final Constants mConstants; 967 968 /* 969 * Holds a SamplingTimer associated with each Resource Power Manager state and voter, 970 * recording their times when on-battery (regardless of screen state). 971 */ 972 private final HashMap<String, SamplingTimer> mRpmStats = new HashMap<>(); 973 /** Times for each Resource Power Manager state and voter when screen-off and on-battery. */ 974 private final HashMap<String, SamplingTimer> mScreenOffRpmStats = new HashMap<>(); 975 976 @Override getRpmStats()977 public Map<String, ? extends Timer> getRpmStats() { 978 return mRpmStats; 979 } 980 981 // TODO: Note: screenOffRpmStats has been disabled via SCREEN_OFF_RPM_STATS_ENABLED. 982 @Override getScreenOffRpmStats()983 public Map<String, ? extends Timer> getScreenOffRpmStats() { 984 return mScreenOffRpmStats; 985 } 986 987 /* 988 * Holds a SamplingTimer associated with each kernel wakelock name being tracked. 989 */ 990 private final HashMap<String, SamplingTimer> mKernelWakelockStats = new HashMap<>(); 991 getKernelWakelockStats()992 public Map<String, ? extends Timer> getKernelWakelockStats() { 993 return mKernelWakelockStats; 994 } 995 996 String mLastWakeupReason = null; 997 long mLastWakeupUptimeMs = 0; 998 private final HashMap<String, SamplingTimer> mWakeupReasonStats = new HashMap<>(); 999 getWakeupReasonStats()1000 public Map<String, ? extends Timer> getWakeupReasonStats() { 1001 return mWakeupReasonStats; 1002 } 1003 1004 @Override getUahDischarge(int which)1005 public long getUahDischarge(int which) { 1006 return mDischargeCounter.getCountLocked(which); 1007 } 1008 1009 @Override getUahDischargeScreenOff(int which)1010 public long getUahDischargeScreenOff(int which) { 1011 return mDischargeScreenOffCounter.getCountLocked(which); 1012 } 1013 1014 @Override getUahDischargeScreenDoze(int which)1015 public long getUahDischargeScreenDoze(int which) { 1016 return mDischargeScreenDozeCounter.getCountLocked(which); 1017 } 1018 1019 @Override getUahDischargeLightDoze(int which)1020 public long getUahDischargeLightDoze(int which) { 1021 return mDischargeLightDozeCounter.getCountLocked(which); 1022 } 1023 1024 @Override getUahDischargeDeepDoze(int which)1025 public long getUahDischargeDeepDoze(int which) { 1026 return mDischargeDeepDozeCounter.getCountLocked(which); 1027 } 1028 1029 @Override getEstimatedBatteryCapacity()1030 public int getEstimatedBatteryCapacity() { 1031 return mEstimatedBatteryCapacity; 1032 } 1033 1034 @Override getMinLearnedBatteryCapacity()1035 public int getMinLearnedBatteryCapacity() { 1036 return mMinLearnedBatteryCapacity; 1037 } 1038 1039 @Override getMaxLearnedBatteryCapacity()1040 public int getMaxLearnedBatteryCapacity() { 1041 return mMaxLearnedBatteryCapacity; 1042 } 1043 BatteryStatsImpl()1044 public BatteryStatsImpl() { 1045 this(new SystemClocks()); 1046 } 1047 BatteryStatsImpl(Clocks clocks)1048 public BatteryStatsImpl(Clocks clocks) { 1049 init(clocks); 1050 mFile = null; 1051 mCheckinFile = null; 1052 mDailyFile = null; 1053 mHandler = null; 1054 mPlatformIdleStateCallback = null; 1055 mUserInfoProvider = null; 1056 mConstants = new Constants(mHandler); 1057 clearHistoryLocked(); 1058 } 1059 init(Clocks clocks)1060 private void init(Clocks clocks) { 1061 mClocks = clocks; 1062 } 1063 1064 public interface TimeBaseObs { onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime)1065 void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime); onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime)1066 void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime); 1067 } 1068 1069 // methods are protected not private to be VisibleForTesting 1070 public static class TimeBase { 1071 protected final ArrayList<TimeBaseObs> mObservers = new ArrayList<>(); 1072 1073 protected long mUptime; 1074 protected long mRealtime; 1075 1076 protected boolean mRunning; 1077 1078 protected long mPastUptime; 1079 protected long mUptimeStart; 1080 protected long mPastRealtime; 1081 protected long mRealtimeStart; 1082 protected long mUnpluggedUptime; 1083 protected long mUnpluggedRealtime; 1084 dump(PrintWriter pw, String prefix)1085 public void dump(PrintWriter pw, String prefix) { 1086 StringBuilder sb = new StringBuilder(128); 1087 pw.print(prefix); pw.print("mRunning="); pw.println(mRunning); 1088 sb.setLength(0); 1089 sb.append(prefix); 1090 sb.append("mUptime="); 1091 formatTimeMs(sb, mUptime / 1000); 1092 pw.println(sb.toString()); 1093 sb.setLength(0); 1094 sb.append(prefix); 1095 sb.append("mRealtime="); 1096 formatTimeMs(sb, mRealtime / 1000); 1097 pw.println(sb.toString()); 1098 sb.setLength(0); 1099 sb.append(prefix); 1100 sb.append("mPastUptime="); 1101 formatTimeMs(sb, mPastUptime / 1000); sb.append("mUptimeStart="); 1102 formatTimeMs(sb, mUptimeStart / 1000); 1103 sb.append("mUnpluggedUptime="); formatTimeMs(sb, mUnpluggedUptime / 1000); 1104 pw.println(sb.toString()); 1105 sb.setLength(0); 1106 sb.append(prefix); 1107 sb.append("mPastRealtime="); 1108 formatTimeMs(sb, mPastRealtime / 1000); sb.append("mRealtimeStart="); 1109 formatTimeMs(sb, mRealtimeStart / 1000); 1110 sb.append("mUnpluggedRealtime="); formatTimeMs(sb, mUnpluggedRealtime / 1000); 1111 pw.println(sb.toString()); 1112 } 1113 add(TimeBaseObs observer)1114 public void add(TimeBaseObs observer) { 1115 mObservers.add(observer); 1116 } 1117 remove(TimeBaseObs observer)1118 public void remove(TimeBaseObs observer) { 1119 if (!mObservers.remove(observer)) { 1120 Slog.wtf(TAG, "Removed unknown observer: " + observer); 1121 } 1122 } 1123 hasObserver(TimeBaseObs observer)1124 public boolean hasObserver(TimeBaseObs observer) { 1125 return mObservers.contains(observer); 1126 } 1127 init(long uptime, long realtime)1128 public void init(long uptime, long realtime) { 1129 mRealtime = 0; 1130 mUptime = 0; 1131 mPastUptime = 0; 1132 mPastRealtime = 0; 1133 mUptimeStart = uptime; 1134 mRealtimeStart = realtime; 1135 mUnpluggedUptime = getUptime(mUptimeStart); 1136 mUnpluggedRealtime = getRealtime(mRealtimeStart); 1137 } 1138 reset(long uptime, long realtime)1139 public void reset(long uptime, long realtime) { 1140 if (!mRunning) { 1141 mPastUptime = 0; 1142 mPastRealtime = 0; 1143 } else { 1144 mUptimeStart = uptime; 1145 mRealtimeStart = realtime; 1146 // TODO: Since mUptimeStart was just reset and we are running, getUptime will 1147 // just return mPastUptime. Also, are we sure we don't want to reset that? 1148 mUnpluggedUptime = getUptime(uptime); 1149 // TODO: likewise. 1150 mUnpluggedRealtime = getRealtime(realtime); 1151 } 1152 } 1153 computeUptime(long curTime, int which)1154 public long computeUptime(long curTime, int which) { 1155 switch (which) { 1156 case STATS_SINCE_CHARGED: 1157 return mUptime + getUptime(curTime); 1158 case STATS_CURRENT: 1159 return getUptime(curTime); 1160 case STATS_SINCE_UNPLUGGED: 1161 return getUptime(curTime) - mUnpluggedUptime; 1162 } 1163 return 0; 1164 } 1165 computeRealtime(long curTime, int which)1166 public long computeRealtime(long curTime, int which) { 1167 switch (which) { 1168 case STATS_SINCE_CHARGED: 1169 return mRealtime + getRealtime(curTime); 1170 case STATS_CURRENT: 1171 return getRealtime(curTime); 1172 case STATS_SINCE_UNPLUGGED: 1173 return getRealtime(curTime) - mUnpluggedRealtime; 1174 } 1175 return 0; 1176 } 1177 getUptime(long curTime)1178 public long getUptime(long curTime) { 1179 long time = mPastUptime; 1180 if (mRunning) { 1181 time += curTime - mUptimeStart; 1182 } 1183 return time; 1184 } 1185 getRealtime(long curTime)1186 public long getRealtime(long curTime) { 1187 long time = mPastRealtime; 1188 if (mRunning) { 1189 time += curTime - mRealtimeStart; 1190 } 1191 return time; 1192 } 1193 getUptimeStart()1194 public long getUptimeStart() { 1195 return mUptimeStart; 1196 } 1197 getRealtimeStart()1198 public long getRealtimeStart() { 1199 return mRealtimeStart; 1200 } 1201 isRunning()1202 public boolean isRunning() { 1203 return mRunning; 1204 } 1205 setRunning(boolean running, long uptime, long realtime)1206 public boolean setRunning(boolean running, long uptime, long realtime) { 1207 if (mRunning != running) { 1208 mRunning = running; 1209 if (running) { 1210 mUptimeStart = uptime; 1211 mRealtimeStart = realtime; 1212 long batteryUptime = mUnpluggedUptime = getUptime(uptime); 1213 long batteryRealtime = mUnpluggedRealtime = getRealtime(realtime); 1214 1215 for (int i = mObservers.size() - 1; i >= 0; i--) { 1216 mObservers.get(i).onTimeStarted(realtime, batteryUptime, batteryRealtime); 1217 } 1218 } else { 1219 mPastUptime += uptime - mUptimeStart; 1220 mPastRealtime += realtime - mRealtimeStart; 1221 1222 long batteryUptime = getUptime(uptime); 1223 long batteryRealtime = getRealtime(realtime); 1224 1225 for (int i = mObservers.size() - 1; i >= 0; i--) { 1226 mObservers.get(i).onTimeStopped(realtime, batteryUptime, batteryRealtime); 1227 } 1228 } 1229 return true; 1230 } 1231 return false; 1232 } 1233 readSummaryFromParcel(Parcel in)1234 public void readSummaryFromParcel(Parcel in) { 1235 mUptime = in.readLong(); 1236 mRealtime = in.readLong(); 1237 } 1238 writeSummaryToParcel(Parcel out, long uptime, long realtime)1239 public void writeSummaryToParcel(Parcel out, long uptime, long realtime) { 1240 out.writeLong(computeUptime(uptime, STATS_SINCE_CHARGED)); 1241 out.writeLong(computeRealtime(realtime, STATS_SINCE_CHARGED)); 1242 } 1243 readFromParcel(Parcel in)1244 public void readFromParcel(Parcel in) { 1245 mRunning = false; 1246 mUptime = in.readLong(); 1247 mPastUptime = in.readLong(); 1248 mUptimeStart = in.readLong(); 1249 mRealtime = in.readLong(); 1250 mPastRealtime = in.readLong(); 1251 mRealtimeStart = in.readLong(); 1252 mUnpluggedUptime = in.readLong(); 1253 mUnpluggedRealtime = in.readLong(); 1254 } 1255 writeToParcel(Parcel out, long uptime, long realtime)1256 public void writeToParcel(Parcel out, long uptime, long realtime) { 1257 final long runningUptime = getUptime(uptime); 1258 final long runningRealtime = getRealtime(realtime); 1259 out.writeLong(mUptime); 1260 out.writeLong(runningUptime); 1261 out.writeLong(mUptimeStart); 1262 out.writeLong(mRealtime); 1263 out.writeLong(runningRealtime); 1264 out.writeLong(mRealtimeStart); 1265 out.writeLong(mUnpluggedUptime); 1266 out.writeLong(mUnpluggedRealtime); 1267 } 1268 } 1269 1270 /** 1271 * State for keeping track of counting information. 1272 */ 1273 public static class Counter extends BatteryStats.Counter implements TimeBaseObs { 1274 final AtomicInteger mCount = new AtomicInteger(); 1275 final TimeBase mTimeBase; 1276 int mLoadedCount; 1277 int mUnpluggedCount; 1278 int mPluggedCount; 1279 Counter(TimeBase timeBase, Parcel in)1280 public Counter(TimeBase timeBase, Parcel in) { 1281 mTimeBase = timeBase; 1282 mPluggedCount = in.readInt(); 1283 mCount.set(mPluggedCount); 1284 mLoadedCount = in.readInt(); 1285 mUnpluggedCount = in.readInt(); 1286 timeBase.add(this); 1287 } 1288 Counter(TimeBase timeBase)1289 public Counter(TimeBase timeBase) { 1290 mTimeBase = timeBase; 1291 timeBase.add(this); 1292 } 1293 writeToParcel(Parcel out)1294 public void writeToParcel(Parcel out) { 1295 out.writeInt(mCount.get()); 1296 out.writeInt(mLoadedCount); 1297 out.writeInt(mUnpluggedCount); 1298 } 1299 1300 @Override onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime)1301 public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) { 1302 mUnpluggedCount = mPluggedCount; 1303 } 1304 1305 @Override onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime)1306 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) { 1307 mPluggedCount = mCount.get(); 1308 } 1309 1310 /** 1311 * Writes a possibly null Counter to a Parcel. 1312 * 1313 * @param out the Parcel to be written to. 1314 * @param counter a Counter, or null. 1315 */ writeCounterToParcel(Parcel out, @Nullable Counter counter)1316 public static void writeCounterToParcel(Parcel out, @Nullable Counter counter) { 1317 if (counter == null) { 1318 out.writeInt(0); // indicates null 1319 return; 1320 } 1321 out.writeInt(1); // indicates non-null 1322 1323 counter.writeToParcel(out); 1324 } 1325 1326 /** 1327 * Reads a Counter that was written using {@link #writeCounterToParcel(Parcel, Counter)}. 1328 * @param timeBase the timebase to assign to the Counter 1329 * @param in the parcel to read from 1330 * @return the Counter or null. 1331 */ readCounterFromParcel(TimeBase timeBase, Parcel in)1332 public static @Nullable Counter readCounterFromParcel(TimeBase timeBase, Parcel in) { 1333 if (in.readInt() == 0) { 1334 return null; 1335 } 1336 return new Counter(timeBase, in); 1337 } 1338 1339 @Override getCountLocked(int which)1340 public int getCountLocked(int which) { 1341 int val = mCount.get(); 1342 if (which == STATS_SINCE_UNPLUGGED) { 1343 val -= mUnpluggedCount; 1344 } else if (which != STATS_SINCE_CHARGED) { 1345 val -= mLoadedCount; 1346 } 1347 1348 return val; 1349 } 1350 logState(Printer pw, String prefix)1351 public void logState(Printer pw, String prefix) { 1352 pw.println(prefix + "mCount=" + mCount.get() 1353 + " mLoadedCount=" + mLoadedCount 1354 + " mUnpluggedCount=" + mUnpluggedCount 1355 + " mPluggedCount=" + mPluggedCount); 1356 } 1357 1358 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) stepAtomic()1359 public void stepAtomic() { 1360 if (mTimeBase.isRunning()) { 1361 mCount.incrementAndGet(); 1362 } 1363 } 1364 addAtomic(int delta)1365 void addAtomic(int delta) { 1366 if (mTimeBase.isRunning()) { 1367 mCount.addAndGet(delta); 1368 } 1369 } 1370 1371 /** 1372 * Clear state of this counter. 1373 */ reset(boolean detachIfReset)1374 void reset(boolean detachIfReset) { 1375 mCount.set(0); 1376 mLoadedCount = mPluggedCount = mUnpluggedCount = 0; 1377 if (detachIfReset) { 1378 detach(); 1379 } 1380 } 1381 detach()1382 void detach() { 1383 mTimeBase.remove(this); 1384 } 1385 1386 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) writeSummaryFromParcelLocked(Parcel out)1387 public void writeSummaryFromParcelLocked(Parcel out) { 1388 int count = mCount.get(); 1389 out.writeInt(count); 1390 } 1391 1392 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) readSummaryFromParcelLocked(Parcel in)1393 public void readSummaryFromParcelLocked(Parcel in) { 1394 mLoadedCount = in.readInt(); 1395 mCount.set(mLoadedCount); 1396 mUnpluggedCount = mPluggedCount = mLoadedCount; 1397 } 1398 } 1399 1400 @VisibleForTesting 1401 public static class LongSamplingCounterArray extends LongCounterArray implements TimeBaseObs { 1402 final TimeBase mTimeBase; 1403 public long[] mCounts; 1404 public long[] mLoadedCounts; 1405 public long[] mUnpluggedCounts; 1406 LongSamplingCounterArray(TimeBase timeBase, Parcel in)1407 private LongSamplingCounterArray(TimeBase timeBase, Parcel in) { 1408 mTimeBase = timeBase; 1409 mCounts = in.createLongArray(); 1410 mLoadedCounts = in.createLongArray(); 1411 mUnpluggedCounts = in.createLongArray(); 1412 timeBase.add(this); 1413 } 1414 LongSamplingCounterArray(TimeBase timeBase)1415 public LongSamplingCounterArray(TimeBase timeBase) { 1416 mTimeBase = timeBase; 1417 timeBase.add(this); 1418 } 1419 writeToParcel(Parcel out)1420 private void writeToParcel(Parcel out) { 1421 out.writeLongArray(mCounts); 1422 out.writeLongArray(mLoadedCounts); 1423 out.writeLongArray(mUnpluggedCounts); 1424 } 1425 1426 @Override onTimeStarted(long elapsedRealTime, long baseUptime, long baseRealtime)1427 public void onTimeStarted(long elapsedRealTime, long baseUptime, long baseRealtime) { 1428 mUnpluggedCounts = copyArray(mCounts, mUnpluggedCounts); 1429 } 1430 1431 @Override onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime)1432 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) { 1433 } 1434 1435 @Override getCountsLocked(int which)1436 public long[] getCountsLocked(int which) { 1437 long[] val = copyArray(mCounts, null); 1438 if (which == STATS_SINCE_UNPLUGGED) { 1439 subtract(val, mUnpluggedCounts); 1440 } else if (which != STATS_SINCE_CHARGED) { 1441 subtract(val, mLoadedCounts); 1442 } 1443 return val; 1444 } 1445 1446 @Override logState(Printer pw, String prefix)1447 public void logState(Printer pw, String prefix) { 1448 pw.println(prefix + "mCounts=" + Arrays.toString(mCounts) 1449 + " mLoadedCounts=" + Arrays.toString(mLoadedCounts) 1450 + " mUnpluggedCounts=" + Arrays.toString(mUnpluggedCounts)); 1451 } 1452 addCountLocked(long[] counts)1453 public void addCountLocked(long[] counts) { 1454 addCountLocked(counts, mTimeBase.isRunning()); 1455 } 1456 addCountLocked(long[] counts, boolean isRunning)1457 public void addCountLocked(long[] counts, boolean isRunning) { 1458 if (counts == null) { 1459 return; 1460 } 1461 if (isRunning) { 1462 if (mCounts == null) { 1463 mCounts = new long[counts.length]; 1464 } 1465 for (int i = 0; i < counts.length; ++i) { 1466 mCounts[i] += counts[i]; 1467 } 1468 } 1469 } 1470 getSize()1471 public int getSize() { 1472 return mCounts == null ? 0 : mCounts.length; 1473 } 1474 1475 /** 1476 * Clear state of this counter. 1477 */ reset(boolean detachIfReset)1478 public void reset(boolean detachIfReset) { 1479 fillArray(mCounts, 0); 1480 fillArray(mLoadedCounts, 0); 1481 fillArray(mUnpluggedCounts, 0); 1482 if (detachIfReset) { 1483 detach(); 1484 } 1485 } 1486 detach()1487 public void detach() { 1488 mTimeBase.remove(this); 1489 } 1490 writeSummaryToParcelLocked(Parcel out)1491 private void writeSummaryToParcelLocked(Parcel out) { 1492 out.writeLongArray(mCounts); 1493 } 1494 readSummaryFromParcelLocked(Parcel in)1495 private void readSummaryFromParcelLocked(Parcel in) { 1496 mCounts = in.createLongArray(); 1497 mLoadedCounts = copyArray(mCounts, mLoadedCounts); 1498 mUnpluggedCounts = copyArray(mCounts, mUnpluggedCounts); 1499 } 1500 writeToParcel(Parcel out, LongSamplingCounterArray counterArray)1501 public static void writeToParcel(Parcel out, LongSamplingCounterArray counterArray) { 1502 if (counterArray != null) { 1503 out.writeInt(1); 1504 counterArray.writeToParcel(out); 1505 } else { 1506 out.writeInt(0); 1507 } 1508 } 1509 readFromParcel(Parcel in, TimeBase timeBase)1510 public static LongSamplingCounterArray readFromParcel(Parcel in, TimeBase timeBase) { 1511 if (in.readInt() != 0) { 1512 return new LongSamplingCounterArray(timeBase, in); 1513 } else { 1514 return null; 1515 } 1516 } 1517 writeSummaryToParcelLocked(Parcel out, LongSamplingCounterArray counterArray)1518 public static void writeSummaryToParcelLocked(Parcel out, 1519 LongSamplingCounterArray counterArray) { 1520 if (counterArray != null) { 1521 out.writeInt(1); 1522 counterArray.writeSummaryToParcelLocked(out); 1523 } else { 1524 out.writeInt(0); 1525 } 1526 } 1527 readSummaryFromParcelLocked(Parcel in, TimeBase timeBase)1528 public static LongSamplingCounterArray readSummaryFromParcelLocked(Parcel in, 1529 TimeBase timeBase) { 1530 if (in.readInt() != 0) { 1531 final LongSamplingCounterArray counterArray 1532 = new LongSamplingCounterArray(timeBase); 1533 counterArray.readSummaryFromParcelLocked(in); 1534 return counterArray; 1535 } else { 1536 return null; 1537 } 1538 } 1539 fillArray(long[] a, long val)1540 private static void fillArray(long[] a, long val) { 1541 if (a != null) { 1542 Arrays.fill(a, val); 1543 } 1544 } 1545 subtract(@onNull long[] val, long[] toSubtract)1546 private static void subtract(@NonNull long[] val, long[] toSubtract) { 1547 if (toSubtract == null) { 1548 return; 1549 } 1550 for (int i = 0; i < val.length; i++) { 1551 val[i] -= toSubtract[i]; 1552 } 1553 } 1554 copyArray(long[] src, long[] dest)1555 private static long[] copyArray(long[] src, long[] dest) { 1556 if (src == null) { 1557 return null; 1558 } else { 1559 if (dest == null) { 1560 dest = new long[src.length]; 1561 } 1562 System.arraycopy(src, 0, dest, 0, src.length); 1563 return dest; 1564 } 1565 } 1566 } 1567 1568 @VisibleForTesting 1569 public static class LongSamplingCounter extends LongCounter implements TimeBaseObs { 1570 final TimeBase mTimeBase; 1571 public long mCount; 1572 public long mCurrentCount; 1573 public long mLoadedCount; 1574 public long mUnpluggedCount; 1575 LongSamplingCounter(TimeBase timeBase, Parcel in)1576 public LongSamplingCounter(TimeBase timeBase, Parcel in) { 1577 mTimeBase = timeBase; 1578 mCount = in.readLong(); 1579 mCurrentCount = in.readLong(); 1580 mLoadedCount = in.readLong(); 1581 mUnpluggedCount = in.readLong(); 1582 timeBase.add(this); 1583 } 1584 LongSamplingCounter(TimeBase timeBase)1585 public LongSamplingCounter(TimeBase timeBase) { 1586 mTimeBase = timeBase; 1587 timeBase.add(this); 1588 } 1589 writeToParcel(Parcel out)1590 public void writeToParcel(Parcel out) { 1591 out.writeLong(mCount); 1592 out.writeLong(mCurrentCount); 1593 out.writeLong(mLoadedCount); 1594 out.writeLong(mUnpluggedCount); 1595 } 1596 1597 @Override onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime)1598 public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) { 1599 mUnpluggedCount = mCount; 1600 } 1601 1602 @Override onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime)1603 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) { 1604 } 1605 getCountLocked(int which)1606 public long getCountLocked(int which) { 1607 long val = mCount; 1608 if (which == STATS_SINCE_UNPLUGGED) { 1609 val -= mUnpluggedCount; 1610 } else if (which != STATS_SINCE_CHARGED) { 1611 val -= mLoadedCount; 1612 } 1613 return val; 1614 } 1615 1616 @Override logState(Printer pw, String prefix)1617 public void logState(Printer pw, String prefix) { 1618 pw.println(prefix + "mCount=" + mCount 1619 + " mCurrentCount=" + mCurrentCount 1620 + " mLoadedCount=" + mLoadedCount 1621 + " mUnpluggedCount=" + mUnpluggedCount); 1622 } 1623 addCountLocked(long count)1624 public void addCountLocked(long count) { 1625 update(mCurrentCount + count, mTimeBase.isRunning()); 1626 } 1627 addCountLocked(long count, boolean isRunning)1628 public void addCountLocked(long count, boolean isRunning) { 1629 update(mCurrentCount + count, isRunning); 1630 } 1631 update(long count)1632 public void update(long count) { 1633 update(count, mTimeBase.isRunning()); 1634 } 1635 update(long count, boolean isRunning)1636 public void update(long count, boolean isRunning) { 1637 if (count < mCurrentCount) { 1638 mCurrentCount = 0; 1639 } 1640 if (isRunning) { 1641 mCount += count - mCurrentCount; 1642 } 1643 mCurrentCount = count; 1644 } 1645 1646 /** 1647 * Clear state of this counter. 1648 */ reset(boolean detachIfReset)1649 public void reset(boolean detachIfReset) { 1650 mCount = 0; 1651 mLoadedCount = mUnpluggedCount = 0; 1652 if (detachIfReset) { 1653 detach(); 1654 } 1655 } 1656 detach()1657 public void detach() { 1658 mTimeBase.remove(this); 1659 } 1660 writeSummaryFromParcelLocked(Parcel out)1661 public void writeSummaryFromParcelLocked(Parcel out) { 1662 out.writeLong(mCount); 1663 } 1664 readSummaryFromParcelLocked(Parcel in)1665 public void readSummaryFromParcelLocked(Parcel in) { 1666 mCount = mUnpluggedCount= mLoadedCount = in.readLong(); 1667 } 1668 } 1669 1670 /** 1671 * State for keeping track of timing information. 1672 */ 1673 public static abstract class Timer extends BatteryStats.Timer implements TimeBaseObs { 1674 protected final Clocks mClocks; 1675 protected final int mType; 1676 protected final TimeBase mTimeBase; 1677 1678 protected int mCount; 1679 protected int mLoadedCount; 1680 protected int mLastCount; 1681 protected int mUnpluggedCount; 1682 1683 // Times are in microseconds for better accuracy when dividing by the 1684 // lock count, and are in "battery realtime" units. 1685 1686 /** 1687 * The total time we have accumulated since the start of the original 1688 * boot, to the last time something interesting happened in the 1689 * current run. 1690 */ 1691 protected long mTotalTime; 1692 1693 /** 1694 * The total time we loaded for the previous runs. Subtract this from 1695 * mTotalTime to find the time for the current run of the system. 1696 */ 1697 protected long mLoadedTime; 1698 1699 /** 1700 * The run time of the last run of the system, as loaded from the 1701 * saved data. 1702 */ 1703 protected long mLastTime; 1704 1705 /** 1706 * The value of mTotalTime when unplug() was last called. Subtract 1707 * this from mTotalTime to find the time since the last unplug from 1708 * power. 1709 */ 1710 protected long mUnpluggedTime; 1711 1712 /** 1713 * The total time this timer has been running until the latest mark has been set. 1714 * Subtract this from mTotalTime to get the time spent running since the mark was set. 1715 */ 1716 protected long mTimeBeforeMark; 1717 1718 /** 1719 * Constructs from a parcel. 1720 * @param type 1721 * @param timeBase 1722 * @param in 1723 */ Timer(Clocks clocks, int type, TimeBase timeBase, Parcel in)1724 public Timer(Clocks clocks, int type, TimeBase timeBase, Parcel in) { 1725 mClocks = clocks; 1726 mType = type; 1727 mTimeBase = timeBase; 1728 1729 mCount = in.readInt(); 1730 mLoadedCount = in.readInt(); 1731 mLastCount = 0; 1732 mUnpluggedCount = in.readInt(); 1733 mTotalTime = in.readLong(); 1734 mLoadedTime = in.readLong(); 1735 mLastTime = 0; 1736 mUnpluggedTime = in.readLong(); 1737 mTimeBeforeMark = in.readLong(); 1738 timeBase.add(this); 1739 if (DEBUG) Log.i(TAG, "**** READ TIMER #" + mType + ": mTotalTime=" + mTotalTime); 1740 } 1741 Timer(Clocks clocks, int type, TimeBase timeBase)1742 public Timer(Clocks clocks, int type, TimeBase timeBase) { 1743 mClocks = clocks; 1744 mType = type; 1745 mTimeBase = timeBase; 1746 timeBase.add(this); 1747 } 1748 computeRunTimeLocked(long curBatteryRealtime)1749 protected abstract long computeRunTimeLocked(long curBatteryRealtime); 1750 computeCurrentCountLocked()1751 protected abstract int computeCurrentCountLocked(); 1752 1753 /** 1754 * Clear state of this timer. Returns true if the timer is inactive 1755 * so can be completely dropped. 1756 */ reset(boolean detachIfReset)1757 public boolean reset(boolean detachIfReset) { 1758 mTotalTime = mLoadedTime = mLastTime = mTimeBeforeMark = 0; 1759 mCount = mLoadedCount = mLastCount = 0; 1760 if (detachIfReset) { 1761 detach(); 1762 } 1763 return true; 1764 } 1765 detach()1766 public void detach() { 1767 mTimeBase.remove(this); 1768 } 1769 writeToParcel(Parcel out, long elapsedRealtimeUs)1770 public void writeToParcel(Parcel out, long elapsedRealtimeUs) { 1771 if (DEBUG) Log.i(TAG, "**** WRITING TIMER #" + mType + ": mTotalTime=" 1772 + computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs))); 1773 out.writeInt(computeCurrentCountLocked()); 1774 out.writeInt(mLoadedCount); 1775 out.writeInt(mUnpluggedCount); 1776 out.writeLong(computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs))); 1777 out.writeLong(mLoadedTime); 1778 out.writeLong(mUnpluggedTime); 1779 out.writeLong(mTimeBeforeMark); 1780 } 1781 1782 @Override onTimeStarted(long elapsedRealtime, long timeBaseUptime, long baseRealtime)1783 public void onTimeStarted(long elapsedRealtime, long timeBaseUptime, long baseRealtime) { 1784 if (DEBUG && mType < 0) { 1785 Log.v(TAG, "unplug #" + mType + ": realtime=" + baseRealtime 1786 + " old mUnpluggedTime=" + mUnpluggedTime 1787 + " old mUnpluggedCount=" + mUnpluggedCount); 1788 } 1789 mUnpluggedTime = computeRunTimeLocked(baseRealtime); 1790 mUnpluggedCount = computeCurrentCountLocked(); 1791 if (DEBUG && mType < 0) { 1792 Log.v(TAG, "unplug #" + mType 1793 + ": new mUnpluggedTime=" + mUnpluggedTime 1794 + " new mUnpluggedCount=" + mUnpluggedCount); 1795 } 1796 } 1797 1798 @Override onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime)1799 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) { 1800 if (DEBUG && mType < 0) { 1801 Log.v(TAG, "plug #" + mType + ": realtime=" + baseRealtime 1802 + " old mTotalTime=" + mTotalTime); 1803 } 1804 mTotalTime = computeRunTimeLocked(baseRealtime); 1805 mCount = computeCurrentCountLocked(); 1806 if (DEBUG && mType < 0) { 1807 Log.v(TAG, "plug #" + mType 1808 + ": new mTotalTime=" + mTotalTime); 1809 } 1810 } 1811 1812 /** 1813 * Writes a possibly null Timer to a Parcel. 1814 * 1815 * @param out the Parcel to be written to. 1816 * @param timer a Timer, or null. 1817 */ writeTimerToParcel(Parcel out, Timer timer, long elapsedRealtimeUs)1818 public static void writeTimerToParcel(Parcel out, Timer timer, long elapsedRealtimeUs) { 1819 if (timer == null) { 1820 out.writeInt(0); // indicates null 1821 return; 1822 } 1823 out.writeInt(1); // indicates non-null 1824 1825 timer.writeToParcel(out, elapsedRealtimeUs); 1826 } 1827 1828 @Override getTotalTimeLocked(long elapsedRealtimeUs, int which)1829 public long getTotalTimeLocked(long elapsedRealtimeUs, int which) { 1830 long val = computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs)); 1831 if (which == STATS_SINCE_UNPLUGGED) { 1832 val -= mUnpluggedTime; 1833 } else if (which != STATS_SINCE_CHARGED) { 1834 val -= mLoadedTime; 1835 } 1836 1837 return val; 1838 } 1839 1840 @Override getCountLocked(int which)1841 public int getCountLocked(int which) { 1842 int val = computeCurrentCountLocked(); 1843 if (which == STATS_SINCE_UNPLUGGED) { 1844 val -= mUnpluggedCount; 1845 } else if (which != STATS_SINCE_CHARGED) { 1846 val -= mLoadedCount; 1847 } 1848 1849 return val; 1850 } 1851 1852 @Override getTimeSinceMarkLocked(long elapsedRealtimeUs)1853 public long getTimeSinceMarkLocked(long elapsedRealtimeUs) { 1854 long val = computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs)); 1855 return val - mTimeBeforeMark; 1856 } 1857 1858 @Override logState(Printer pw, String prefix)1859 public void logState(Printer pw, String prefix) { 1860 pw.println(prefix + "mCount=" + mCount 1861 + " mLoadedCount=" + mLoadedCount + " mLastCount=" + mLastCount 1862 + " mUnpluggedCount=" + mUnpluggedCount); 1863 pw.println(prefix + "mTotalTime=" + mTotalTime 1864 + " mLoadedTime=" + mLoadedTime); 1865 pw.println(prefix + "mLastTime=" + mLastTime 1866 + " mUnpluggedTime=" + mUnpluggedTime); 1867 } 1868 1869 writeSummaryFromParcelLocked(Parcel out, long elapsedRealtimeUs)1870 public void writeSummaryFromParcelLocked(Parcel out, long elapsedRealtimeUs) { 1871 long runTime = computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs)); 1872 out.writeLong(runTime); 1873 out.writeInt(computeCurrentCountLocked()); 1874 } 1875 readSummaryFromParcelLocked(Parcel in)1876 public void readSummaryFromParcelLocked(Parcel in) { 1877 // Multiply by 1000 for backwards compatibility 1878 mTotalTime = mLoadedTime = in.readLong(); 1879 mLastTime = 0; 1880 mUnpluggedTime = mTotalTime; 1881 mCount = mLoadedCount = in.readInt(); 1882 mLastCount = 0; 1883 mUnpluggedCount = mCount; 1884 1885 // When reading the summary, we set the mark to be the latest information. 1886 mTimeBeforeMark = mTotalTime; 1887 } 1888 } 1889 1890 /** 1891 * A counter meant to accept monotonically increasing values to its {@link #update(long, int)} 1892 * method. The state of the timer according to its {@link TimeBase} will determine how much 1893 * of the value is recorded. 1894 * 1895 * If the value being recorded resets, {@link #endSample()} can be called in order to 1896 * account for the change. If the value passed in to {@link #update(long, int)} decreased 1897 * between calls, the {@link #endSample()} is automatically called and the new value is 1898 * expected to increase monotonically from that point on. 1899 */ 1900 public static class SamplingTimer extends Timer { 1901 1902 /** 1903 * The most recent reported count from /proc/wakelocks. 1904 */ 1905 int mCurrentReportedCount; 1906 1907 /** 1908 * The reported count from /proc/wakelocks when unplug() was last 1909 * called. 1910 */ 1911 int mUnpluggedReportedCount; 1912 1913 /** 1914 * The most recent reported total_time from /proc/wakelocks. 1915 */ 1916 long mCurrentReportedTotalTime; 1917 1918 1919 /** 1920 * The reported total_time from /proc/wakelocks when unplug() was last 1921 * called. 1922 */ 1923 long mUnpluggedReportedTotalTime; 1924 1925 /** 1926 * Whether we are currently in a discharge cycle. 1927 */ 1928 boolean mTimeBaseRunning; 1929 1930 /** 1931 * Whether we are currently recording reported values. 1932 */ 1933 boolean mTrackingReportedValues; 1934 1935 /* 1936 * A sequence counter, incremented once for each update of the stats. 1937 */ 1938 int mUpdateVersion; 1939 1940 @VisibleForTesting SamplingTimer(Clocks clocks, TimeBase timeBase, Parcel in)1941 public SamplingTimer(Clocks clocks, TimeBase timeBase, Parcel in) { 1942 super(clocks, 0, timeBase, in); 1943 mCurrentReportedCount = in.readInt(); 1944 mUnpluggedReportedCount = in.readInt(); 1945 mCurrentReportedTotalTime = in.readLong(); 1946 mUnpluggedReportedTotalTime = in.readLong(); 1947 mTrackingReportedValues = in.readInt() == 1; 1948 mTimeBaseRunning = timeBase.isRunning(); 1949 } 1950 1951 @VisibleForTesting SamplingTimer(Clocks clocks, TimeBase timeBase)1952 public SamplingTimer(Clocks clocks, TimeBase timeBase) { 1953 super(clocks, 0, timeBase); 1954 mTrackingReportedValues = false; 1955 mTimeBaseRunning = timeBase.isRunning(); 1956 } 1957 1958 /** 1959 * Ends the current sample, allowing subsequent values to {@link #update(long, int)} to 1960 * be less than the values used for a previous invocation. 1961 */ endSample()1962 public void endSample() { 1963 mTotalTime = computeRunTimeLocked(0 /* unused by us */); 1964 mCount = computeCurrentCountLocked(); 1965 mUnpluggedReportedTotalTime = mCurrentReportedTotalTime = 0; 1966 mUnpluggedReportedCount = mCurrentReportedCount = 0; 1967 } 1968 setUpdateVersion(int version)1969 public void setUpdateVersion(int version) { 1970 mUpdateVersion = version; 1971 } 1972 getUpdateVersion()1973 public int getUpdateVersion() { 1974 return mUpdateVersion; 1975 } 1976 1977 /** 1978 * Updates the current recorded values. These are meant to be monotonically increasing 1979 * and cumulative. If you are dealing with deltas, use {@link #add(long, int)}. 1980 * 1981 * If the values being recorded have been reset, the monotonically increasing requirement 1982 * will be broken. In this case, {@link #endSample()} is automatically called and 1983 * the total value of totalTime and count are recorded, starting a new monotonically 1984 * increasing sample. 1985 * 1986 * @param totalTime total time of sample in microseconds. 1987 * @param count total number of times the event being sampled occurred. 1988 */ update(long totalTime, int count)1989 public void update(long totalTime, int count) { 1990 if (mTimeBaseRunning && !mTrackingReportedValues) { 1991 // Updating the reported value for the first time. 1992 mUnpluggedReportedTotalTime = totalTime; 1993 mUnpluggedReportedCount = count; 1994 } 1995 1996 mTrackingReportedValues = true; 1997 1998 if (totalTime < mCurrentReportedTotalTime || count < mCurrentReportedCount) { 1999 endSample(); 2000 } 2001 2002 mCurrentReportedTotalTime = totalTime; 2003 mCurrentReportedCount = count; 2004 } 2005 2006 /** 2007 * Adds deltaTime and deltaCount to the current sample. 2008 * 2009 * @param deltaTime additional time recorded since the last sampled event, in microseconds. 2010 * @param deltaCount additional number of times the event being sampled occurred. 2011 */ add(long deltaTime, int deltaCount)2012 public void add(long deltaTime, int deltaCount) { 2013 update(mCurrentReportedTotalTime + deltaTime, mCurrentReportedCount + deltaCount); 2014 } 2015 2016 @Override onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime)2017 public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) { 2018 super.onTimeStarted(elapsedRealtime, baseUptime, baseRealtime); 2019 if (mTrackingReportedValues) { 2020 mUnpluggedReportedTotalTime = mCurrentReportedTotalTime; 2021 mUnpluggedReportedCount = mCurrentReportedCount; 2022 } 2023 mTimeBaseRunning = true; 2024 } 2025 2026 @Override onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime)2027 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) { 2028 super.onTimeStopped(elapsedRealtime, baseUptime, baseRealtime); 2029 mTimeBaseRunning = false; 2030 } 2031 2032 @Override logState(Printer pw, String prefix)2033 public void logState(Printer pw, String prefix) { 2034 super.logState(pw, prefix); 2035 pw.println(prefix + "mCurrentReportedCount=" + mCurrentReportedCount 2036 + " mUnpluggedReportedCount=" + mUnpluggedReportedCount 2037 + " mCurrentReportedTotalTime=" + mCurrentReportedTotalTime 2038 + " mUnpluggedReportedTotalTime=" + mUnpluggedReportedTotalTime); 2039 } 2040 2041 @Override computeRunTimeLocked(long curBatteryRealtime)2042 protected long computeRunTimeLocked(long curBatteryRealtime) { 2043 return mTotalTime + (mTimeBaseRunning && mTrackingReportedValues 2044 ? mCurrentReportedTotalTime - mUnpluggedReportedTotalTime : 0); 2045 } 2046 2047 @Override computeCurrentCountLocked()2048 protected int computeCurrentCountLocked() { 2049 return mCount + (mTimeBaseRunning && mTrackingReportedValues 2050 ? mCurrentReportedCount - mUnpluggedReportedCount : 0); 2051 } 2052 2053 @Override writeToParcel(Parcel out, long elapsedRealtimeUs)2054 public void writeToParcel(Parcel out, long elapsedRealtimeUs) { 2055 super.writeToParcel(out, elapsedRealtimeUs); 2056 out.writeInt(mCurrentReportedCount); 2057 out.writeInt(mUnpluggedReportedCount); 2058 out.writeLong(mCurrentReportedTotalTime); 2059 out.writeLong(mUnpluggedReportedTotalTime); 2060 out.writeInt(mTrackingReportedValues ? 1 : 0); 2061 } 2062 2063 @Override reset(boolean detachIfReset)2064 public boolean reset(boolean detachIfReset) { 2065 super.reset(detachIfReset); 2066 mTrackingReportedValues = false; 2067 mUnpluggedReportedTotalTime = 0; 2068 mUnpluggedReportedCount = 0; 2069 return true; 2070 } 2071 } 2072 2073 /** 2074 * A timer that increments in batches. It does not run for durations, but just jumps 2075 * for a pre-determined amount. 2076 */ 2077 public static class BatchTimer extends Timer { 2078 final Uid mUid; 2079 2080 /** 2081 * The last time at which we updated the timer. This is in elapsed realtime microseconds. 2082 */ 2083 long mLastAddedTime; 2084 2085 /** 2086 * The last duration that we added to the timer. This is in microseconds. 2087 */ 2088 long mLastAddedDuration; 2089 2090 /** 2091 * Whether we are currently in a discharge cycle. 2092 */ 2093 boolean mInDischarge; 2094 BatchTimer(Clocks clocks, Uid uid, int type, TimeBase timeBase, Parcel in)2095 BatchTimer(Clocks clocks, Uid uid, int type, TimeBase timeBase, Parcel in) { 2096 super(clocks, type, timeBase, in); 2097 mUid = uid; 2098 mLastAddedTime = in.readLong(); 2099 mLastAddedDuration = in.readLong(); 2100 mInDischarge = timeBase.isRunning(); 2101 } 2102 BatchTimer(Clocks clocks, Uid uid, int type, TimeBase timeBase)2103 BatchTimer(Clocks clocks, Uid uid, int type, TimeBase timeBase) { 2104 super(clocks, type, timeBase); 2105 mUid = uid; 2106 mInDischarge = timeBase.isRunning(); 2107 } 2108 2109 @Override writeToParcel(Parcel out, long elapsedRealtimeUs)2110 public void writeToParcel(Parcel out, long elapsedRealtimeUs) { 2111 super.writeToParcel(out, elapsedRealtimeUs); 2112 out.writeLong(mLastAddedTime); 2113 out.writeLong(mLastAddedDuration); 2114 } 2115 2116 @Override onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime)2117 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) { 2118 recomputeLastDuration(mClocks.elapsedRealtime() * 1000, false); 2119 mInDischarge = false; 2120 super.onTimeStopped(elapsedRealtime, baseUptime, baseRealtime); 2121 } 2122 2123 @Override onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime)2124 public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) { 2125 recomputeLastDuration(elapsedRealtime, false); 2126 mInDischarge = true; 2127 // If we are still within the last added duration, then re-added whatever remains. 2128 if (mLastAddedTime == elapsedRealtime) { 2129 mTotalTime += mLastAddedDuration; 2130 } 2131 super.onTimeStarted(elapsedRealtime, baseUptime, baseRealtime); 2132 } 2133 2134 @Override logState(Printer pw, String prefix)2135 public void logState(Printer pw, String prefix) { 2136 super.logState(pw, prefix); 2137 pw.println(prefix + "mLastAddedTime=" + mLastAddedTime 2138 + " mLastAddedDuration=" + mLastAddedDuration); 2139 } 2140 computeOverage(long curTime)2141 private long computeOverage(long curTime) { 2142 if (mLastAddedTime > 0) { 2143 return mLastTime + mLastAddedDuration - curTime; 2144 } 2145 return 0; 2146 } 2147 recomputeLastDuration(long curTime, boolean abort)2148 private void recomputeLastDuration(long curTime, boolean abort) { 2149 final long overage = computeOverage(curTime); 2150 if (overage > 0) { 2151 // Aborting before the duration ran out -- roll back the remaining 2152 // duration. Only do this if currently discharging; otherwise we didn't 2153 // actually add the time. 2154 if (mInDischarge) { 2155 mTotalTime -= overage; 2156 } 2157 if (abort) { 2158 mLastAddedTime = 0; 2159 } else { 2160 mLastAddedTime = curTime; 2161 mLastAddedDuration -= overage; 2162 } 2163 } 2164 } 2165 addDuration(BatteryStatsImpl stats, long durationMillis)2166 public void addDuration(BatteryStatsImpl stats, long durationMillis) { 2167 final long now = mClocks.elapsedRealtime() * 1000; 2168 recomputeLastDuration(now, true); 2169 mLastAddedTime = now; 2170 mLastAddedDuration = durationMillis * 1000; 2171 if (mInDischarge) { 2172 mTotalTime += mLastAddedDuration; 2173 mCount++; 2174 } 2175 } 2176 abortLastDuration(BatteryStatsImpl stats)2177 public void abortLastDuration(BatteryStatsImpl stats) { 2178 final long now = mClocks.elapsedRealtime() * 1000; 2179 recomputeLastDuration(now, true); 2180 } 2181 2182 @Override computeCurrentCountLocked()2183 protected int computeCurrentCountLocked() { 2184 return mCount; 2185 } 2186 2187 @Override computeRunTimeLocked(long curBatteryRealtime)2188 protected long computeRunTimeLocked(long curBatteryRealtime) { 2189 final long overage = computeOverage(mClocks.elapsedRealtime() * 1000); 2190 if (overage > 0) { 2191 return mTotalTime = overage; 2192 } 2193 return mTotalTime; 2194 } 2195 2196 @Override reset(boolean detachIfReset)2197 public boolean reset(boolean detachIfReset) { 2198 final long now = mClocks.elapsedRealtime() * 1000; 2199 recomputeLastDuration(now, true); 2200 boolean stillActive = mLastAddedTime == now; 2201 super.reset(!stillActive && detachIfReset); 2202 return !stillActive; 2203 } 2204 } 2205 2206 2207 /** 2208 * A StopwatchTimer that also tracks the total and max individual 2209 * time spent active according to the given timebase. Whereas 2210 * StopwatchTimer apportions the time amongst all in the pool, 2211 * the total and max durations are not apportioned. 2212 */ 2213 public static class DurationTimer extends StopwatchTimer { 2214 /** 2215 * The time (in ms) that the timer was last acquired or the time base 2216 * last (re-)started. Increasing the nesting depth does not reset this time. 2217 * 2218 * -1 if the timer is currently not running or the time base is not running. 2219 * 2220 * If written to a parcel, the start time is reset, as is mNesting in the base class 2221 * StopwatchTimer. 2222 */ 2223 long mStartTimeMs = -1; 2224 2225 /** 2226 * The longest time period (in ms) that the timer has been active. Not pooled. 2227 */ 2228 long mMaxDurationMs; 2229 2230 /** 2231 * The time (in ms) that that the timer has been active since most recent 2232 * stopRunningLocked() or reset(). Not pooled. 2233 */ 2234 long mCurrentDurationMs; 2235 2236 /** 2237 * The total time (in ms) that that the timer has been active since most recent reset() 2238 * prior to the current startRunningLocked. This is the sum of all past currentDurations 2239 * (but not including the present currentDuration) since reset. Not pooled. 2240 */ 2241 long mTotalDurationMs; 2242 DurationTimer(Clocks clocks, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, TimeBase timeBase, Parcel in)2243 public DurationTimer(Clocks clocks, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, 2244 TimeBase timeBase, Parcel in) { 2245 super(clocks, uid, type, timerPool, timeBase, in); 2246 mMaxDurationMs = in.readLong(); 2247 mTotalDurationMs = in.readLong(); 2248 mCurrentDurationMs = in.readLong(); 2249 } 2250 DurationTimer(Clocks clocks, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, TimeBase timeBase)2251 public DurationTimer(Clocks clocks, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, 2252 TimeBase timeBase) { 2253 super(clocks, uid, type, timerPool, timeBase); 2254 } 2255 2256 @Override writeToParcel(Parcel out, long elapsedRealtimeUs)2257 public void writeToParcel(Parcel out, long elapsedRealtimeUs) { 2258 super.writeToParcel(out, elapsedRealtimeUs); 2259 out.writeLong(getMaxDurationMsLocked(elapsedRealtimeUs / 1000)); 2260 out.writeLong(mTotalDurationMs); 2261 out.writeLong(getCurrentDurationMsLocked(elapsedRealtimeUs / 1000)); 2262 } 2263 2264 /** 2265 * Write the summary to the parcel. 2266 * 2267 * Since the time base is probably meaningless after we come back, reading 2268 * from this will have the effect of stopping the timer. So here all we write 2269 * is the max and total durations. 2270 */ 2271 @Override writeSummaryFromParcelLocked(Parcel out, long elapsedRealtimeUs)2272 public void writeSummaryFromParcelLocked(Parcel out, long elapsedRealtimeUs) { 2273 super.writeSummaryFromParcelLocked(out, elapsedRealtimeUs); 2274 out.writeLong(getMaxDurationMsLocked(elapsedRealtimeUs / 1000)); 2275 out.writeLong(getTotalDurationMsLocked(elapsedRealtimeUs / 1000)); 2276 } 2277 2278 /** 2279 * Read the summary parcel. 2280 * 2281 * Has the side effect of stopping the timer. 2282 */ 2283 @Override readSummaryFromParcelLocked(Parcel in)2284 public void readSummaryFromParcelLocked(Parcel in) { 2285 super.readSummaryFromParcelLocked(in); 2286 mMaxDurationMs = in.readLong(); 2287 mTotalDurationMs = in.readLong(); 2288 mStartTimeMs = -1; 2289 mCurrentDurationMs = 0; 2290 } 2291 2292 /** 2293 * The TimeBase time started (again). 2294 * 2295 * If the timer is also running, store the start time. 2296 */ onTimeStarted(long elapsedRealtimeUs, long baseUptime, long baseRealtime)2297 public void onTimeStarted(long elapsedRealtimeUs, long baseUptime, long baseRealtime) { 2298 super.onTimeStarted(elapsedRealtimeUs, baseUptime, baseRealtime); 2299 if (mNesting > 0) { 2300 mStartTimeMs = baseRealtime / 1000; 2301 } 2302 } 2303 2304 /** 2305 * The TimeBase stopped running. 2306 * 2307 * If the timer is running, add the duration into mCurrentDurationMs. 2308 */ 2309 @Override onTimeStopped(long elapsedRealtimeUs, long baseUptime, long baseRealtimeUs)2310 public void onTimeStopped(long elapsedRealtimeUs, long baseUptime, long baseRealtimeUs) { 2311 super.onTimeStopped(elapsedRealtimeUs, baseUptime, baseRealtimeUs); 2312 if (mNesting > 0) { 2313 // baseRealtimeUs has already been converted to the timebase's realtime. 2314 mCurrentDurationMs += (baseRealtimeUs / 1000) - mStartTimeMs; 2315 } 2316 mStartTimeMs = -1; 2317 } 2318 2319 @Override logState(Printer pw, String prefix)2320 public void logState(Printer pw, String prefix) { 2321 super.logState(pw, prefix); 2322 } 2323 2324 @Override startRunningLocked(long elapsedRealtimeMs)2325 public void startRunningLocked(long elapsedRealtimeMs) { 2326 super.startRunningLocked(elapsedRealtimeMs); 2327 if (mNesting == 1 && mTimeBase.isRunning()) { 2328 // Just started 2329 mStartTimeMs = mTimeBase.getRealtime(elapsedRealtimeMs * 1000) / 1000; 2330 } 2331 } 2332 2333 /** 2334 * Decrements the mNesting ref-count on this timer. 2335 * 2336 * If it actually stopped (mNesting went to 0), then possibly update 2337 * mMaxDuration if the current duration was the longest ever. 2338 */ 2339 @Override stopRunningLocked(long elapsedRealtimeMs)2340 public void stopRunningLocked(long elapsedRealtimeMs) { 2341 if (mNesting == 1) { 2342 final long durationMs = getCurrentDurationMsLocked(elapsedRealtimeMs); 2343 mTotalDurationMs += durationMs; 2344 if (durationMs > mMaxDurationMs) { 2345 mMaxDurationMs = durationMs; 2346 } 2347 mStartTimeMs = -1; 2348 mCurrentDurationMs = 0; 2349 } 2350 // super method decrements mNesting, which getCurrentDurationMsLocked relies on, 2351 // so call super.stopRunningLocked after calling getCurrentDurationMsLocked. 2352 super.stopRunningLocked(elapsedRealtimeMs); 2353 } 2354 2355 @Override reset(boolean detachIfReset)2356 public boolean reset(boolean detachIfReset) { 2357 boolean result = super.reset(detachIfReset); 2358 mMaxDurationMs = 0; 2359 mTotalDurationMs = 0; 2360 mCurrentDurationMs = 0; 2361 if (mNesting > 0) { 2362 mStartTimeMs = mTimeBase.getRealtime(mClocks.elapsedRealtime()*1000) / 1000; 2363 } else { 2364 mStartTimeMs = -1; 2365 } 2366 return result; 2367 } 2368 2369 /** 2370 * Returns the max duration that this timer has ever seen. 2371 * 2372 * Note that this time is NOT split between the timers in the timer group that 2373 * this timer is attached to. It is the TOTAL time. 2374 */ 2375 @Override getMaxDurationMsLocked(long elapsedRealtimeMs)2376 public long getMaxDurationMsLocked(long elapsedRealtimeMs) { 2377 if (mNesting > 0) { 2378 final long durationMs = getCurrentDurationMsLocked(elapsedRealtimeMs); 2379 if (durationMs > mMaxDurationMs) { 2380 return durationMs; 2381 } 2382 } 2383 return mMaxDurationMs; 2384 } 2385 2386 /** 2387 * Returns the time since the timer was started. 2388 * Returns 0 if the timer is not currently running. 2389 * 2390 * Note that this time is NOT split between the timers in the timer group that 2391 * this timer is attached to. It is the TOTAL time. 2392 * 2393 * Note that if running timer is parceled and unparceled, this method will return 2394 * current duration value at the time of parceling even though timer may not be 2395 * currently running. 2396 */ 2397 @Override getCurrentDurationMsLocked(long elapsedRealtimeMs)2398 public long getCurrentDurationMsLocked(long elapsedRealtimeMs) { 2399 long durationMs = mCurrentDurationMs; 2400 if (mNesting > 0 && mTimeBase.isRunning()) { 2401 durationMs += (mTimeBase.getRealtime(elapsedRealtimeMs*1000)/1000) 2402 - mStartTimeMs; 2403 } 2404 return durationMs; 2405 } 2406 2407 /** 2408 * Returns the total cumulative duration that this timer has been on since reset(). 2409 * If mTimerPool == null, this should be the same 2410 * as getTotalTimeLocked(elapsedRealtimeMs*1000, STATS_SINCE_CHARGED)/1000. 2411 * 2412 * Note that this time is NOT split between the timers in the timer group that 2413 * this timer is attached to. It is the TOTAL time. For this reason, if mTimerPool != null, 2414 * the result will not be equivalent to getTotalTimeLocked. 2415 */ 2416 @Override getTotalDurationMsLocked(long elapsedRealtimeMs)2417 public long getTotalDurationMsLocked(long elapsedRealtimeMs) { 2418 return mTotalDurationMs + getCurrentDurationMsLocked(elapsedRealtimeMs); 2419 } 2420 } 2421 2422 /** 2423 * State for keeping track of timing information. 2424 */ 2425 public static class StopwatchTimer extends Timer { 2426 final Uid mUid; 2427 final ArrayList<StopwatchTimer> mTimerPool; 2428 2429 int mNesting; 2430 2431 /** 2432 * The last time at which we updated the timer. If mNesting is > 0, 2433 * subtract this from the current battery time to find the amount of 2434 * time we have been running since we last computed an update. 2435 */ 2436 long mUpdateTime; 2437 2438 /** 2439 * The total time at which the timer was acquired, to determine if it 2440 * was actually held for an interesting duration. If time base was not running when timer 2441 * was acquired, will be -1. 2442 */ 2443 long mAcquireTime = -1; 2444 2445 long mTimeout; 2446 2447 /** 2448 * For partial wake locks, keep track of whether we are in the list 2449 * to consume CPU cycles. 2450 */ 2451 @VisibleForTesting 2452 public boolean mInList; 2453 StopwatchTimer(Clocks clocks, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, TimeBase timeBase, Parcel in)2454 public StopwatchTimer(Clocks clocks, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, 2455 TimeBase timeBase, Parcel in) { 2456 super(clocks, type, timeBase, in); 2457 mUid = uid; 2458 mTimerPool = timerPool; 2459 mUpdateTime = in.readLong(); 2460 } 2461 StopwatchTimer(Clocks clocks, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, TimeBase timeBase)2462 public StopwatchTimer(Clocks clocks, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, 2463 TimeBase timeBase) { 2464 super(clocks, type, timeBase); 2465 mUid = uid; 2466 mTimerPool = timerPool; 2467 } 2468 setTimeout(long timeout)2469 public void setTimeout(long timeout) { 2470 mTimeout = timeout; 2471 } 2472 writeToParcel(Parcel out, long elapsedRealtimeUs)2473 public void writeToParcel(Parcel out, long elapsedRealtimeUs) { 2474 super.writeToParcel(out, elapsedRealtimeUs); 2475 out.writeLong(mUpdateTime); 2476 } 2477 onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime)2478 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) { 2479 if (mNesting > 0) { 2480 if (DEBUG && mType < 0) { 2481 Log.v(TAG, "old mUpdateTime=" + mUpdateTime); 2482 } 2483 super.onTimeStopped(elapsedRealtime, baseUptime, baseRealtime); 2484 mUpdateTime = baseRealtime; 2485 if (DEBUG && mType < 0) { 2486 Log.v(TAG, "new mUpdateTime=" + mUpdateTime); 2487 } 2488 } 2489 } 2490 logState(Printer pw, String prefix)2491 public void logState(Printer pw, String prefix) { 2492 super.logState(pw, prefix); 2493 pw.println(prefix + "mNesting=" + mNesting + " mUpdateTime=" + mUpdateTime 2494 + " mAcquireTime=" + mAcquireTime); 2495 } 2496 startRunningLocked(long elapsedRealtimeMs)2497 public void startRunningLocked(long elapsedRealtimeMs) { 2498 if (mNesting++ == 0) { 2499 final long batteryRealtime = mTimeBase.getRealtime(elapsedRealtimeMs * 1000); 2500 mUpdateTime = batteryRealtime; 2501 if (mTimerPool != null) { 2502 // Accumulate time to all currently active timers before adding 2503 // this new one to the pool. 2504 refreshTimersLocked(batteryRealtime, mTimerPool, null); 2505 // Add this timer to the active pool 2506 mTimerPool.add(this); 2507 } 2508 if (mTimeBase.isRunning()) { 2509 // Increment the count 2510 mCount++; 2511 mAcquireTime = mTotalTime; 2512 } else { 2513 mAcquireTime = -1; 2514 } 2515 if (DEBUG && mType < 0) { 2516 Log.v(TAG, "start #" + mType + ": mUpdateTime=" + mUpdateTime 2517 + " mTotalTime=" + mTotalTime + " mCount=" + mCount 2518 + " mAcquireTime=" + mAcquireTime); 2519 } 2520 } 2521 } 2522 isRunningLocked()2523 public boolean isRunningLocked() { 2524 return mNesting > 0; 2525 } 2526 stopRunningLocked(long elapsedRealtimeMs)2527 public void stopRunningLocked(long elapsedRealtimeMs) { 2528 // Ignore attempt to stop a timer that isn't running 2529 if (mNesting == 0) { 2530 return; 2531 } 2532 if (--mNesting == 0) { 2533 final long batteryRealtime = mTimeBase.getRealtime(elapsedRealtimeMs * 1000); 2534 if (mTimerPool != null) { 2535 // Accumulate time to all active counters, scaled by the total 2536 // active in the pool, before taking this one out of the pool. 2537 refreshTimersLocked(batteryRealtime, mTimerPool, null); 2538 // Remove this timer from the active pool 2539 mTimerPool.remove(this); 2540 } else { 2541 mNesting = 1; 2542 mTotalTime = computeRunTimeLocked(batteryRealtime); 2543 mNesting = 0; 2544 } 2545 2546 if (DEBUG && mType < 0) { 2547 Log.v(TAG, "stop #" + mType + ": mUpdateTime=" + mUpdateTime 2548 + " mTotalTime=" + mTotalTime + " mCount=" + mCount 2549 + " mAcquireTime=" + mAcquireTime); 2550 } 2551 2552 if (mAcquireTime >= 0 && mTotalTime == mAcquireTime) { 2553 // If there was no change in the time, then discard this 2554 // count. A somewhat cheezy strategy, but hey. 2555 mCount--; 2556 } 2557 } 2558 } 2559 stopAllRunningLocked(long elapsedRealtimeMs)2560 public void stopAllRunningLocked(long elapsedRealtimeMs) { 2561 if (mNesting > 0) { 2562 mNesting = 1; 2563 stopRunningLocked(elapsedRealtimeMs); 2564 } 2565 } 2566 2567 // Update the total time for all other running Timers with the same type as this Timer 2568 // due to a change in timer count refreshTimersLocked(long batteryRealtime, final ArrayList<StopwatchTimer> pool, StopwatchTimer self)2569 private static long refreshTimersLocked(long batteryRealtime, 2570 final ArrayList<StopwatchTimer> pool, StopwatchTimer self) { 2571 long selfTime = 0; 2572 final int N = pool.size(); 2573 for (int i=N-1; i>= 0; i--) { 2574 final StopwatchTimer t = pool.get(i); 2575 long heldTime = batteryRealtime - t.mUpdateTime; 2576 if (heldTime > 0) { 2577 final long myTime = heldTime / N; 2578 if (t == self) { 2579 selfTime = myTime; 2580 } 2581 t.mTotalTime += myTime; 2582 } 2583 t.mUpdateTime = batteryRealtime; 2584 } 2585 return selfTime; 2586 } 2587 2588 @Override computeRunTimeLocked(long curBatteryRealtime)2589 protected long computeRunTimeLocked(long curBatteryRealtime) { 2590 if (mTimeout > 0 && curBatteryRealtime > mUpdateTime + mTimeout) { 2591 curBatteryRealtime = mUpdateTime + mTimeout; 2592 } 2593 return mTotalTime + (mNesting > 0 2594 ? (curBatteryRealtime - mUpdateTime) 2595 / (mTimerPool != null ? mTimerPool.size() : 1) 2596 : 0); 2597 } 2598 2599 @Override computeCurrentCountLocked()2600 protected int computeCurrentCountLocked() { 2601 return mCount; 2602 } 2603 2604 @Override reset(boolean detachIfReset)2605 public boolean reset(boolean detachIfReset) { 2606 boolean canDetach = mNesting <= 0; 2607 super.reset(canDetach && detachIfReset); 2608 if (mNesting > 0) { 2609 mUpdateTime = mTimeBase.getRealtime(mClocks.elapsedRealtime() * 1000); 2610 } 2611 mAcquireTime = -1; // to ensure mCount isn't decreased to -1 if timer is stopped later. 2612 return canDetach; 2613 } 2614 2615 @Override detach()2616 public void detach() { 2617 super.detach(); 2618 if (mTimerPool != null) { 2619 mTimerPool.remove(this); 2620 } 2621 } 2622 2623 @Override readSummaryFromParcelLocked(Parcel in)2624 public void readSummaryFromParcelLocked(Parcel in) { 2625 super.readSummaryFromParcelLocked(in); 2626 mNesting = 0; 2627 } 2628 2629 /** 2630 * Set the mark so that we can query later for the total time the timer has 2631 * accumulated since this point. The timer can be running or not. 2632 * 2633 * @param elapsedRealtimeMs the current elapsed realtime in milliseconds. 2634 */ setMark(long elapsedRealtimeMs)2635 public void setMark(long elapsedRealtimeMs) { 2636 final long batteryRealtime = mTimeBase.getRealtime(elapsedRealtimeMs * 1000); 2637 if (mNesting > 0) { 2638 // We are running. 2639 if (mTimerPool != null) { 2640 refreshTimersLocked(batteryRealtime, mTimerPool, this); 2641 } else { 2642 mTotalTime += batteryRealtime - mUpdateTime; 2643 mUpdateTime = batteryRealtime; 2644 } 2645 } 2646 mTimeBeforeMark = mTotalTime; 2647 } 2648 } 2649 2650 /** 2651 * State for keeping track of two DurationTimers with different TimeBases, presumably where one 2652 * TimeBase is effectively a subset of the other. 2653 */ 2654 public static class DualTimer extends DurationTimer { 2655 // This class both is a DurationTimer and also holds a second DurationTimer. 2656 // The main timer (this) typically tracks the total time. It may be pooled (but since it's a 2657 // durationTimer, it also has the unpooled getTotalDurationMsLocked() for 2658 // STATS_SINCE_CHARGED). 2659 // mSubTimer typically tracks only part of the total time, such as background time, as 2660 // determined by a subTimeBase. It is NOT pooled. 2661 private final DurationTimer mSubTimer; 2662 2663 /** 2664 * Creates a DualTimer to hold a main timer (this) and a mSubTimer. 2665 * The main timer (this) is based on the given timeBase and timerPool. 2666 * The mSubTimer is based on the given subTimeBase. The mSubTimer is not pooled, even if 2667 * the main timer is. 2668 */ DualTimer(Clocks clocks, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, TimeBase timeBase, TimeBase subTimeBase, Parcel in)2669 public DualTimer(Clocks clocks, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, 2670 TimeBase timeBase, TimeBase subTimeBase, Parcel in) { 2671 super(clocks, uid, type, timerPool, timeBase, in); 2672 mSubTimer = new DurationTimer(clocks, uid, type, null, subTimeBase, in); 2673 } 2674 2675 /** 2676 * Creates a DualTimer to hold a main timer (this) and a mSubTimer. 2677 * The main timer (this) is based on the given timeBase and timerPool. 2678 * The mSubTimer is based on the given subTimeBase. The mSubTimer is not pooled, even if 2679 * the main timer is. 2680 */ DualTimer(Clocks clocks, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, TimeBase timeBase, TimeBase subTimeBase)2681 public DualTimer(Clocks clocks, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, 2682 TimeBase timeBase, TimeBase subTimeBase) { 2683 super(clocks, uid, type, timerPool, timeBase); 2684 mSubTimer = new DurationTimer(clocks, uid, type, null, subTimeBase); 2685 } 2686 2687 /** Get the secondary timer. */ 2688 @Override getSubTimer()2689 public DurationTimer getSubTimer() { 2690 return mSubTimer; 2691 } 2692 2693 @Override startRunningLocked(long elapsedRealtimeMs)2694 public void startRunningLocked(long elapsedRealtimeMs) { 2695 super.startRunningLocked(elapsedRealtimeMs); 2696 mSubTimer.startRunningLocked(elapsedRealtimeMs); 2697 } 2698 2699 @Override stopRunningLocked(long elapsedRealtimeMs)2700 public void stopRunningLocked(long elapsedRealtimeMs) { 2701 super.stopRunningLocked(elapsedRealtimeMs); 2702 mSubTimer.stopRunningLocked(elapsedRealtimeMs); 2703 } 2704 2705 @Override stopAllRunningLocked(long elapsedRealtimeMs)2706 public void stopAllRunningLocked(long elapsedRealtimeMs) { 2707 super.stopAllRunningLocked(elapsedRealtimeMs); 2708 mSubTimer.stopAllRunningLocked(elapsedRealtimeMs); 2709 } 2710 2711 @Override reset(boolean detachIfReset)2712 public boolean reset(boolean detachIfReset) { 2713 boolean active = false; 2714 // Do not detach the subTimer explicitly since that'll be done by DualTimer.detach(). 2715 active |= !mSubTimer.reset(false); 2716 active |= !super.reset(detachIfReset); 2717 return !active; 2718 } 2719 2720 @Override detach()2721 public void detach() { 2722 mSubTimer.detach(); 2723 super.detach(); 2724 } 2725 2726 @Override writeToParcel(Parcel out, long elapsedRealtimeUs)2727 public void writeToParcel(Parcel out, long elapsedRealtimeUs) { 2728 super.writeToParcel(out, elapsedRealtimeUs); 2729 mSubTimer.writeToParcel(out, elapsedRealtimeUs); 2730 } 2731 2732 @Override writeSummaryFromParcelLocked(Parcel out, long elapsedRealtimeUs)2733 public void writeSummaryFromParcelLocked(Parcel out, long elapsedRealtimeUs) { 2734 super.writeSummaryFromParcelLocked(out, elapsedRealtimeUs); 2735 mSubTimer.writeSummaryFromParcelLocked(out, elapsedRealtimeUs); 2736 } 2737 2738 @Override readSummaryFromParcelLocked(Parcel in)2739 public void readSummaryFromParcelLocked(Parcel in) { 2740 super.readSummaryFromParcelLocked(in); 2741 mSubTimer.readSummaryFromParcelLocked(in); 2742 } 2743 } 2744 2745 2746 public abstract class OverflowArrayMap<T> { 2747 private static final String OVERFLOW_NAME = "*overflow*"; 2748 2749 final int mUid; 2750 final ArrayMap<String, T> mMap = new ArrayMap<>(); 2751 T mCurOverflow; 2752 ArrayMap<String, MutableInt> mActiveOverflow; 2753 long mLastOverflowTime; 2754 long mLastOverflowFinishTime; 2755 long mLastClearTime; 2756 long mLastCleanupTime; 2757 OverflowArrayMap(int uid)2758 public OverflowArrayMap(int uid) { 2759 mUid = uid; 2760 } 2761 getMap()2762 public ArrayMap<String, T> getMap() { 2763 return mMap; 2764 } 2765 clear()2766 public void clear() { 2767 mLastClearTime = SystemClock.elapsedRealtime(); 2768 mMap.clear(); 2769 mCurOverflow = null; 2770 mActiveOverflow = null; 2771 } 2772 add(String name, T obj)2773 public void add(String name, T obj) { 2774 if (name == null) { 2775 name = ""; 2776 } 2777 mMap.put(name, obj); 2778 if (OVERFLOW_NAME.equals(name)) { 2779 mCurOverflow = obj; 2780 } 2781 } 2782 cleanup()2783 public void cleanup() { 2784 mLastCleanupTime = SystemClock.elapsedRealtime(); 2785 if (mActiveOverflow != null) { 2786 if (mActiveOverflow.size() == 0) { 2787 mActiveOverflow = null; 2788 } 2789 } 2790 if (mActiveOverflow == null) { 2791 // There is no currently active overflow, so we should no longer have 2792 // an overflow entry. 2793 if (mMap.containsKey(OVERFLOW_NAME)) { 2794 Slog.wtf(TAG, "Cleaning up with no active overflow, but have overflow entry " 2795 + mMap.get(OVERFLOW_NAME)); 2796 mMap.remove(OVERFLOW_NAME); 2797 } 2798 mCurOverflow = null; 2799 } else { 2800 // There is currently active overflow, so we should still have an overflow entry. 2801 if (mCurOverflow == null || !mMap.containsKey(OVERFLOW_NAME)) { 2802 Slog.wtf(TAG, "Cleaning up with active overflow, but no overflow entry: cur=" 2803 + mCurOverflow + " map=" + mMap.get(OVERFLOW_NAME)); 2804 } 2805 } 2806 } 2807 startObject(String name)2808 public T startObject(String name) { 2809 if (name == null) { 2810 name = ""; 2811 } 2812 T obj = mMap.get(name); 2813 if (obj != null) { 2814 return obj; 2815 } 2816 2817 // No object exists for the given name, but do we currently have it 2818 // running as part of the overflow? 2819 if (mActiveOverflow != null) { 2820 MutableInt over = mActiveOverflow.get(name); 2821 if (over != null) { 2822 // We are already actively counting this name in the overflow object. 2823 obj = mCurOverflow; 2824 if (obj == null) { 2825 // Shouldn't be here, but we'll try to recover. 2826 Slog.wtf(TAG, "Have active overflow " + name + " but null overflow"); 2827 obj = mCurOverflow = instantiateObject(); 2828 mMap.put(OVERFLOW_NAME, obj); 2829 } 2830 over.value++; 2831 return obj; 2832 } 2833 } 2834 2835 // No object exists for given name nor in the overflow; we need to make 2836 // a new one. 2837 final int N = mMap.size(); 2838 if (N >= MAX_WAKELOCKS_PER_UID) { 2839 // Went over the limit on number of objects to track; this one goes 2840 // in to the overflow. 2841 obj = mCurOverflow; 2842 if (obj == null) { 2843 // Need to start overflow now... 2844 obj = mCurOverflow = instantiateObject(); 2845 mMap.put(OVERFLOW_NAME, obj); 2846 } 2847 if (mActiveOverflow == null) { 2848 mActiveOverflow = new ArrayMap<>(); 2849 } 2850 mActiveOverflow.put(name, new MutableInt(1)); 2851 mLastOverflowTime = SystemClock.elapsedRealtime(); 2852 return obj; 2853 } 2854 2855 // Normal case where we just need to make a new object. 2856 obj = instantiateObject(); 2857 mMap.put(name, obj); 2858 return obj; 2859 } 2860 stopObject(String name)2861 public T stopObject(String name) { 2862 if (name == null) { 2863 name = ""; 2864 } 2865 T obj = mMap.get(name); 2866 if (obj != null) { 2867 return obj; 2868 } 2869 2870 // No object exists for the given name, but do we currently have it 2871 // running as part of the overflow? 2872 if (mActiveOverflow != null) { 2873 MutableInt over = mActiveOverflow.get(name); 2874 if (over != null) { 2875 // We are already actively counting this name in the overflow object. 2876 obj = mCurOverflow; 2877 if (obj != null) { 2878 over.value--; 2879 if (over.value <= 0) { 2880 mActiveOverflow.remove(name); 2881 mLastOverflowFinishTime = SystemClock.elapsedRealtime(); 2882 } 2883 return obj; 2884 } 2885 } 2886 } 2887 2888 // Huh, they are stopping an active operation but we can't find one! 2889 // That's not good. 2890 StringBuilder sb = new StringBuilder(); 2891 sb.append("Unable to find object for "); 2892 sb.append(name); 2893 sb.append(" in uid "); 2894 sb.append(mUid); 2895 sb.append(" mapsize="); 2896 sb.append(mMap.size()); 2897 sb.append(" activeoverflow="); 2898 sb.append(mActiveOverflow); 2899 sb.append(" curoverflow="); 2900 sb.append(mCurOverflow); 2901 long now = SystemClock.elapsedRealtime(); 2902 if (mLastOverflowTime != 0) { 2903 sb.append(" lastOverflowTime="); 2904 TimeUtils.formatDuration(mLastOverflowTime-now, sb); 2905 } 2906 if (mLastOverflowFinishTime != 0) { 2907 sb.append(" lastOverflowFinishTime="); 2908 TimeUtils.formatDuration(mLastOverflowFinishTime-now, sb); 2909 } 2910 if (mLastClearTime != 0) { 2911 sb.append(" lastClearTime="); 2912 TimeUtils.formatDuration(mLastClearTime-now, sb); 2913 } 2914 if (mLastCleanupTime != 0) { 2915 sb.append(" lastCleanupTime="); 2916 TimeUtils.formatDuration(mLastCleanupTime-now, sb); 2917 } 2918 Slog.wtf(TAG, sb.toString()); 2919 return null; 2920 } 2921 instantiateObject()2922 public abstract T instantiateObject(); 2923 } 2924 2925 public static class ControllerActivityCounterImpl extends ControllerActivityCounter 2926 implements Parcelable { 2927 private final LongSamplingCounter mIdleTimeMillis; 2928 private final LongSamplingCounter mScanTimeMillis; 2929 private final LongSamplingCounter mSleepTimeMillis; 2930 private final LongSamplingCounter mRxTimeMillis; 2931 private final LongSamplingCounter[] mTxTimeMillis; 2932 private final LongSamplingCounter mPowerDrainMaMs; 2933 ControllerActivityCounterImpl(TimeBase timeBase, int numTxStates)2934 public ControllerActivityCounterImpl(TimeBase timeBase, int numTxStates) { 2935 mIdleTimeMillis = new LongSamplingCounter(timeBase); 2936 mScanTimeMillis = new LongSamplingCounter(timeBase); 2937 mSleepTimeMillis = new LongSamplingCounter(timeBase); 2938 mRxTimeMillis = new LongSamplingCounter(timeBase); 2939 mTxTimeMillis = new LongSamplingCounter[numTxStates]; 2940 for (int i = 0; i < numTxStates; i++) { 2941 mTxTimeMillis[i] = new LongSamplingCounter(timeBase); 2942 } 2943 mPowerDrainMaMs = new LongSamplingCounter(timeBase); 2944 } 2945 ControllerActivityCounterImpl(TimeBase timeBase, int numTxStates, Parcel in)2946 public ControllerActivityCounterImpl(TimeBase timeBase, int numTxStates, Parcel in) { 2947 mIdleTimeMillis = new LongSamplingCounter(timeBase, in); 2948 mScanTimeMillis = new LongSamplingCounter(timeBase, in); 2949 mSleepTimeMillis = new LongSamplingCounter(timeBase, in); 2950 mRxTimeMillis = new LongSamplingCounter(timeBase, in); 2951 final int recordedTxStates = in.readInt(); 2952 if (recordedTxStates != numTxStates) { 2953 throw new ParcelFormatException("inconsistent tx state lengths"); 2954 } 2955 2956 mTxTimeMillis = new LongSamplingCounter[numTxStates]; 2957 for (int i = 0; i < numTxStates; i++) { 2958 mTxTimeMillis[i] = new LongSamplingCounter(timeBase, in); 2959 } 2960 mPowerDrainMaMs = new LongSamplingCounter(timeBase, in); 2961 } 2962 readSummaryFromParcel(Parcel in)2963 public void readSummaryFromParcel(Parcel in) { 2964 mIdleTimeMillis.readSummaryFromParcelLocked(in); 2965 mScanTimeMillis.readSummaryFromParcelLocked(in); 2966 mSleepTimeMillis.readSummaryFromParcelLocked(in); 2967 mRxTimeMillis.readSummaryFromParcelLocked(in); 2968 final int recordedTxStates = in.readInt(); 2969 if (recordedTxStates != mTxTimeMillis.length) { 2970 throw new ParcelFormatException("inconsistent tx state lengths"); 2971 } 2972 for (LongSamplingCounter counter : mTxTimeMillis) { 2973 counter.readSummaryFromParcelLocked(in); 2974 } 2975 mPowerDrainMaMs.readSummaryFromParcelLocked(in); 2976 } 2977 2978 @Override describeContents()2979 public int describeContents() { 2980 return 0; 2981 } 2982 writeSummaryToParcel(Parcel dest)2983 public void writeSummaryToParcel(Parcel dest) { 2984 mIdleTimeMillis.writeSummaryFromParcelLocked(dest); 2985 mScanTimeMillis.writeSummaryFromParcelLocked(dest); 2986 mSleepTimeMillis.writeSummaryFromParcelLocked(dest); 2987 mRxTimeMillis.writeSummaryFromParcelLocked(dest); 2988 dest.writeInt(mTxTimeMillis.length); 2989 for (LongSamplingCounter counter : mTxTimeMillis) { 2990 counter.writeSummaryFromParcelLocked(dest); 2991 } 2992 mPowerDrainMaMs.writeSummaryFromParcelLocked(dest); 2993 } 2994 2995 @Override writeToParcel(Parcel dest, int flags)2996 public void writeToParcel(Parcel dest, int flags) { 2997 mIdleTimeMillis.writeToParcel(dest); 2998 mScanTimeMillis.writeToParcel(dest); 2999 mSleepTimeMillis.writeToParcel(dest); 3000 mRxTimeMillis.writeToParcel(dest); 3001 dest.writeInt(mTxTimeMillis.length); 3002 for (LongSamplingCounter counter : mTxTimeMillis) { 3003 counter.writeToParcel(dest); 3004 } 3005 mPowerDrainMaMs.writeToParcel(dest); 3006 } 3007 reset(boolean detachIfReset)3008 public void reset(boolean detachIfReset) { 3009 mIdleTimeMillis.reset(detachIfReset); 3010 mScanTimeMillis.reset(detachIfReset); 3011 mSleepTimeMillis.reset(detachIfReset); 3012 mRxTimeMillis.reset(detachIfReset); 3013 for (LongSamplingCounter counter : mTxTimeMillis) { 3014 counter.reset(detachIfReset); 3015 } 3016 mPowerDrainMaMs.reset(detachIfReset); 3017 } 3018 detach()3019 public void detach() { 3020 mIdleTimeMillis.detach(); 3021 mScanTimeMillis.detach(); 3022 mSleepTimeMillis.detach(); 3023 mRxTimeMillis.detach(); 3024 for (LongSamplingCounter counter : mTxTimeMillis) { 3025 counter.detach(); 3026 } 3027 mPowerDrainMaMs.detach(); 3028 } 3029 3030 /** 3031 * @return a LongSamplingCounter, measuring time spent in the idle state in 3032 * milliseconds. 3033 */ 3034 @Override getIdleTimeCounter()3035 public LongSamplingCounter getIdleTimeCounter() { 3036 return mIdleTimeMillis; 3037 } 3038 3039 /** 3040 * @return a LongSamplingCounter, measuring time spent in the scan state in 3041 * milliseconds. 3042 */ 3043 @Override getScanTimeCounter()3044 public LongSamplingCounter getScanTimeCounter() { 3045 return mScanTimeMillis; 3046 } 3047 3048 /** 3049 * @return a LongSamplingCounter, measuring time spent in the sleep state in 3050 * milliseconds. 3051 */ 3052 @Override getSleepTimeCounter()3053 public LongSamplingCounter getSleepTimeCounter() { 3054 return mSleepTimeMillis; 3055 } 3056 3057 /** 3058 * @return a LongSamplingCounter, measuring time spent in the receive state in 3059 * milliseconds. 3060 */ 3061 @Override getRxTimeCounter()3062 public LongSamplingCounter getRxTimeCounter() { 3063 return mRxTimeMillis; 3064 } 3065 3066 /** 3067 * @return a LongSamplingCounter[], measuring time spent in various transmit states in 3068 * milliseconds. 3069 */ 3070 @Override getTxTimeCounters()3071 public LongSamplingCounter[] getTxTimeCounters() { 3072 return mTxTimeMillis; 3073 } 3074 3075 /** 3076 * @return a LongSamplingCounter, measuring power use in milli-ampere milliseconds (mAmS). 3077 */ 3078 @Override getPowerCounter()3079 public LongSamplingCounter getPowerCounter() { 3080 return mPowerDrainMaMs; 3081 } 3082 } 3083 3084 /** Get Resource Power Manager stats. Create a new one if it doesn't already exist. */ getRpmTimerLocked(String name)3085 public SamplingTimer getRpmTimerLocked(String name) { 3086 SamplingTimer rpmt = mRpmStats.get(name); 3087 if (rpmt == null) { 3088 rpmt = new SamplingTimer(mClocks, mOnBatteryTimeBase); 3089 mRpmStats.put(name, rpmt); 3090 } 3091 return rpmt; 3092 } 3093 3094 /** Get Screen-off Resource Power Manager stats. Create new one if it doesn't already exist. */ getScreenOffRpmTimerLocked(String name)3095 public SamplingTimer getScreenOffRpmTimerLocked(String name) { 3096 SamplingTimer rpmt = mScreenOffRpmStats.get(name); 3097 if (rpmt == null) { 3098 rpmt = new SamplingTimer(mClocks, mOnBatteryScreenOffTimeBase); 3099 mScreenOffRpmStats.put(name, rpmt); 3100 } 3101 return rpmt; 3102 } 3103 3104 /* 3105 * Get the wakeup reason counter, and create a new one if one 3106 * doesn't already exist. 3107 */ getWakeupReasonTimerLocked(String name)3108 public SamplingTimer getWakeupReasonTimerLocked(String name) { 3109 SamplingTimer timer = mWakeupReasonStats.get(name); 3110 if (timer == null) { 3111 timer = new SamplingTimer(mClocks, mOnBatteryTimeBase); 3112 mWakeupReasonStats.put(name, timer); 3113 } 3114 return timer; 3115 } 3116 3117 /* 3118 * Get the KernelWakelockTimer associated with name, and create a new one if one 3119 * doesn't already exist. 3120 */ getKernelWakelockTimerLocked(String name)3121 public SamplingTimer getKernelWakelockTimerLocked(String name) { 3122 SamplingTimer kwlt = mKernelWakelockStats.get(name); 3123 if (kwlt == null) { 3124 kwlt = new SamplingTimer(mClocks, mOnBatteryScreenOffTimeBase); 3125 mKernelWakelockStats.put(name, kwlt); 3126 } 3127 return kwlt; 3128 } 3129 getKernelMemoryTimerLocked(long bucket)3130 public SamplingTimer getKernelMemoryTimerLocked(long bucket) { 3131 SamplingTimer kmt = mKernelMemoryStats.get(bucket); 3132 if (kmt == null) { 3133 kmt = new SamplingTimer(mClocks, mOnBatteryTimeBase); 3134 mKernelMemoryStats.put(bucket, kmt); 3135 } 3136 return kmt; 3137 } 3138 writeHistoryTag(HistoryTag tag)3139 private int writeHistoryTag(HistoryTag tag) { 3140 Integer idxObj = mHistoryTagPool.get(tag); 3141 int idx; 3142 if (idxObj != null) { 3143 idx = idxObj; 3144 } else { 3145 idx = mNextHistoryTagIdx; 3146 HistoryTag key = new HistoryTag(); 3147 key.setTo(tag); 3148 tag.poolIdx = idx; 3149 mHistoryTagPool.put(key, idx); 3150 mNextHistoryTagIdx++; 3151 mNumHistoryTagChars += key.string.length() + 1; 3152 } 3153 return idx; 3154 } 3155 readHistoryTag(int index, HistoryTag tag)3156 private void readHistoryTag(int index, HistoryTag tag) { 3157 tag.string = mReadHistoryStrings[index]; 3158 tag.uid = mReadHistoryUids[index]; 3159 tag.poolIdx = index; 3160 } 3161 3162 /* 3163 The history delta format uses flags to denote further data in subsequent ints in the parcel. 3164 3165 There is always the first token, which may contain the delta time, or an indicator of 3166 the length of the time (int or long) following this token. 3167 3168 First token: always present, 3169 31 23 15 7 0 3170 █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█ 3171 3172 T: the delta time if it is <= 0x7fffd. Otherwise 0x7fffe indicates an int immediately 3173 follows containing the time, and 0x7ffff indicates a long immediately follows with the 3174 delta time. 3175 A: battery level changed and an int follows with battery data. 3176 B: state changed and an int follows with state change data. 3177 C: state2 has changed and an int follows with state2 change data. 3178 D: wakelock/wakereason has changed and an wakelock/wakereason struct follows. 3179 E: event data has changed and an event struct follows. 3180 F: battery charge in coulombs has changed and an int with the charge follows. 3181 G: state flag denoting that the mobile radio was active. 3182 H: state flag denoting that the wifi radio was active. 3183 I: state flag denoting that a wifi scan occurred. 3184 J: state flag denoting that a wifi full lock was held. 3185 K: state flag denoting that the gps was on. 3186 L: state flag denoting that a wakelock was held. 3187 M: state flag denoting that the cpu was running. 3188 3189 Time int/long: if T in the first token is 0x7ffff or 0x7fffe, then an int or long follows 3190 with the time delta. 3191 3192 Battery level int: if A in the first token is set, 3193 31 23 15 7 0 3194 █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█ 3195 3196 D: indicates that extra history details follow. 3197 V: the battery voltage. 3198 T: the battery temperature. 3199 L: the battery level (out of 100). 3200 3201 State change int: if B in the first token is set, 3202 31 23 15 7 0 3203 █S|S|S|H|H|H|P|P█F|E|D|C|B| | |A█ | | | | | | | █ | | | | | | | █ 3204 3205 A: wifi multicast was on. 3206 B: battery was plugged in. 3207 C: screen was on. 3208 D: phone was scanning for signal. 3209 E: audio was on. 3210 F: a sensor was active. 3211 3212 State2 change int: if C in the first token is set, 3213 31 23 15 7 0 3214 █M|L|K|J|I|H|H|G█F|E|D|C| | | | █ | | | | | | | █ |B|B|B|A|A|A|A█ 3215 3216 A: 4 bits indicating the wifi supplicant state: {@link BatteryStats#WIFI_SUPPL_STATE_NAMES}. 3217 B: 3 bits indicating the wifi signal strength: 0, 1, 2, 3, 4. 3218 C: a bluetooth scan was active. 3219 D: the camera was active. 3220 E: bluetooth was on. 3221 F: a phone call was active. 3222 G: the device was charging. 3223 H: 2 bits indicating the device-idle (doze) state: off, light, full 3224 I: the flashlight was on. 3225 J: wifi was on. 3226 K: wifi was running. 3227 L: video was playing. 3228 M: power save mode was on. 3229 3230 Wakelock/wakereason struct: if D in the first token is set, 3231 TODO(adamlesinski): describe wakelock/wakereason struct. 3232 3233 Event struct: if E in the first token is set, 3234 TODO(adamlesinski): describe the event struct. 3235 3236 History step details struct: if D in the battery level int is set, 3237 TODO(adamlesinski): describe the history step details struct. 3238 3239 Battery charge int: if F in the first token is set, an int representing the battery charge 3240 in coulombs follows. 3241 */ 3242 3243 // Part of initial delta int that specifies the time delta. 3244 static final int DELTA_TIME_MASK = 0x7ffff; 3245 static final int DELTA_TIME_LONG = 0x7ffff; // The delta is a following long 3246 static final int DELTA_TIME_INT = 0x7fffe; // The delta is a following int 3247 static final int DELTA_TIME_ABS = 0x7fffd; // Following is an entire abs update. 3248 // Flag in delta int: a new battery level int follows. 3249 static final int DELTA_BATTERY_LEVEL_FLAG = 0x00080000; 3250 // Flag in delta int: a new full state and battery status int follows. 3251 static final int DELTA_STATE_FLAG = 0x00100000; 3252 // Flag in delta int: a new full state2 int follows. 3253 static final int DELTA_STATE2_FLAG = 0x00200000; 3254 // Flag in delta int: contains a wakelock or wakeReason tag. 3255 static final int DELTA_WAKELOCK_FLAG = 0x00400000; 3256 // Flag in delta int: contains an event description. 3257 static final int DELTA_EVENT_FLAG = 0x00800000; 3258 // Flag in delta int: contains the battery charge count in uAh. 3259 static final int DELTA_BATTERY_CHARGE_FLAG = 0x01000000; 3260 // These upper bits are the frequently changing state bits. 3261 static final int DELTA_STATE_MASK = 0xfe000000; 3262 3263 // These are the pieces of battery state that are packed in to the upper bits of 3264 // the state int that have been packed in to the first delta int. They must fit 3265 // in STATE_BATTERY_MASK. 3266 static final int STATE_BATTERY_MASK = 0xff000000; 3267 static final int STATE_BATTERY_STATUS_MASK = 0x00000007; 3268 static final int STATE_BATTERY_STATUS_SHIFT = 29; 3269 static final int STATE_BATTERY_HEALTH_MASK = 0x00000007; 3270 static final int STATE_BATTERY_HEALTH_SHIFT = 26; 3271 static final int STATE_BATTERY_PLUG_MASK = 0x00000003; 3272 static final int STATE_BATTERY_PLUG_SHIFT = 24; 3273 3274 // We use the low bit of the battery state int to indicate that we have full details 3275 // from a battery level change. 3276 static final int BATTERY_DELTA_LEVEL_FLAG = 0x00000001; 3277 writeHistoryDelta(Parcel dest, HistoryItem cur, HistoryItem last)3278 public void writeHistoryDelta(Parcel dest, HistoryItem cur, HistoryItem last) { 3279 if (last == null || cur.cmd != HistoryItem.CMD_UPDATE) { 3280 dest.writeInt(DELTA_TIME_ABS); 3281 cur.writeToParcel(dest, 0); 3282 return; 3283 } 3284 3285 final long deltaTime = cur.time - last.time; 3286 final int lastBatteryLevelInt = buildBatteryLevelInt(last); 3287 final int lastStateInt = buildStateInt(last); 3288 3289 int deltaTimeToken; 3290 if (deltaTime < 0 || deltaTime > Integer.MAX_VALUE) { 3291 deltaTimeToken = DELTA_TIME_LONG; 3292 } else if (deltaTime >= DELTA_TIME_ABS) { 3293 deltaTimeToken = DELTA_TIME_INT; 3294 } else { 3295 deltaTimeToken = (int)deltaTime; 3296 } 3297 int firstToken = deltaTimeToken | (cur.states&DELTA_STATE_MASK); 3298 final int includeStepDetails = mLastHistoryStepLevel > cur.batteryLevel 3299 ? BATTERY_DELTA_LEVEL_FLAG : 0; 3300 final boolean computeStepDetails = includeStepDetails != 0 3301 || mLastHistoryStepDetails == null; 3302 final int batteryLevelInt = buildBatteryLevelInt(cur) | includeStepDetails; 3303 final boolean batteryLevelIntChanged = batteryLevelInt != lastBatteryLevelInt; 3304 if (batteryLevelIntChanged) { 3305 firstToken |= DELTA_BATTERY_LEVEL_FLAG; 3306 } 3307 final int stateInt = buildStateInt(cur); 3308 final boolean stateIntChanged = stateInt != lastStateInt; 3309 if (stateIntChanged) { 3310 firstToken |= DELTA_STATE_FLAG; 3311 } 3312 final boolean state2IntChanged = cur.states2 != last.states2; 3313 if (state2IntChanged) { 3314 firstToken |= DELTA_STATE2_FLAG; 3315 } 3316 if (cur.wakelockTag != null || cur.wakeReasonTag != null) { 3317 firstToken |= DELTA_WAKELOCK_FLAG; 3318 } 3319 if (cur.eventCode != HistoryItem.EVENT_NONE) { 3320 firstToken |= DELTA_EVENT_FLAG; 3321 } 3322 3323 final boolean batteryChargeChanged = cur.batteryChargeUAh != last.batteryChargeUAh; 3324 if (batteryChargeChanged) { 3325 firstToken |= DELTA_BATTERY_CHARGE_FLAG; 3326 } 3327 dest.writeInt(firstToken); 3328 if (DEBUG) Slog.i(TAG, "WRITE DELTA: firstToken=0x" + Integer.toHexString(firstToken) 3329 + " deltaTime=" + deltaTime); 3330 3331 if (deltaTimeToken >= DELTA_TIME_INT) { 3332 if (deltaTimeToken == DELTA_TIME_INT) { 3333 if (DEBUG) Slog.i(TAG, "WRITE DELTA: int deltaTime=" + (int)deltaTime); 3334 dest.writeInt((int)deltaTime); 3335 } else { 3336 if (DEBUG) Slog.i(TAG, "WRITE DELTA: long deltaTime=" + deltaTime); 3337 dest.writeLong(deltaTime); 3338 } 3339 } 3340 if (batteryLevelIntChanged) { 3341 dest.writeInt(batteryLevelInt); 3342 if (DEBUG) Slog.i(TAG, "WRITE DELTA: batteryToken=0x" 3343 + Integer.toHexString(batteryLevelInt) 3344 + " batteryLevel=" + cur.batteryLevel 3345 + " batteryTemp=" + cur.batteryTemperature 3346 + " batteryVolt=" + (int)cur.batteryVoltage); 3347 } 3348 if (stateIntChanged) { 3349 dest.writeInt(stateInt); 3350 if (DEBUG) Slog.i(TAG, "WRITE DELTA: stateToken=0x" 3351 + Integer.toHexString(stateInt) 3352 + " batteryStatus=" + cur.batteryStatus 3353 + " batteryHealth=" + cur.batteryHealth 3354 + " batteryPlugType=" + cur.batteryPlugType 3355 + " states=0x" + Integer.toHexString(cur.states)); 3356 } 3357 if (state2IntChanged) { 3358 dest.writeInt(cur.states2); 3359 if (DEBUG) Slog.i(TAG, "WRITE DELTA: states2=0x" 3360 + Integer.toHexString(cur.states2)); 3361 } 3362 if (cur.wakelockTag != null || cur.wakeReasonTag != null) { 3363 int wakeLockIndex; 3364 int wakeReasonIndex; 3365 if (cur.wakelockTag != null) { 3366 wakeLockIndex = writeHistoryTag(cur.wakelockTag); 3367 if (DEBUG) Slog.i(TAG, "WRITE DELTA: wakelockTag=#" + cur.wakelockTag.poolIdx 3368 + " " + cur.wakelockTag.uid + ":" + cur.wakelockTag.string); 3369 } else { 3370 wakeLockIndex = 0xffff; 3371 } 3372 if (cur.wakeReasonTag != null) { 3373 wakeReasonIndex = writeHistoryTag(cur.wakeReasonTag); 3374 if (DEBUG) Slog.i(TAG, "WRITE DELTA: wakeReasonTag=#" + cur.wakeReasonTag.poolIdx 3375 + " " + cur.wakeReasonTag.uid + ":" + cur.wakeReasonTag.string); 3376 } else { 3377 wakeReasonIndex = 0xffff; 3378 } 3379 dest.writeInt((wakeReasonIndex<<16) | wakeLockIndex); 3380 } 3381 if (cur.eventCode != HistoryItem.EVENT_NONE) { 3382 int index = writeHistoryTag(cur.eventTag); 3383 int codeAndIndex = (cur.eventCode&0xffff) | (index<<16); 3384 dest.writeInt(codeAndIndex); 3385 if (DEBUG) Slog.i(TAG, "WRITE DELTA: event=" + cur.eventCode + " tag=#" 3386 + cur.eventTag.poolIdx + " " + cur.eventTag.uid + ":" 3387 + cur.eventTag.string); 3388 } 3389 if (computeStepDetails) { 3390 if (mPlatformIdleStateCallback != null) { 3391 mCurHistoryStepDetails.statPlatformIdleState = 3392 mPlatformIdleStateCallback.getPlatformLowPowerStats(); 3393 if (DEBUG) Slog.i(TAG, "WRITE PlatformIdleState:" + 3394 mCurHistoryStepDetails.statPlatformIdleState); 3395 3396 mCurHistoryStepDetails.statSubsystemPowerState = 3397 mPlatformIdleStateCallback.getSubsystemLowPowerStats(); 3398 if (DEBUG) Slog.i(TAG, "WRITE SubsystemPowerState:" + 3399 mCurHistoryStepDetails.statSubsystemPowerState); 3400 3401 } 3402 computeHistoryStepDetails(mCurHistoryStepDetails, mLastHistoryStepDetails); 3403 if (includeStepDetails != 0) { 3404 mCurHistoryStepDetails.writeToParcel(dest); 3405 } 3406 cur.stepDetails = mCurHistoryStepDetails; 3407 mLastHistoryStepDetails = mCurHistoryStepDetails; 3408 } else { 3409 cur.stepDetails = null; 3410 } 3411 if (mLastHistoryStepLevel < cur.batteryLevel) { 3412 mLastHistoryStepDetails = null; 3413 } 3414 mLastHistoryStepLevel = cur.batteryLevel; 3415 3416 if (batteryChargeChanged) { 3417 if (DEBUG) Slog.i(TAG, "WRITE DELTA: batteryChargeUAh=" + cur.batteryChargeUAh); 3418 dest.writeInt(cur.batteryChargeUAh); 3419 } 3420 } 3421 buildBatteryLevelInt(HistoryItem h)3422 private int buildBatteryLevelInt(HistoryItem h) { 3423 return ((((int)h.batteryLevel)<<25)&0xfe000000) 3424 | ((((int)h.batteryTemperature)<<15)&0x01ff8000) 3425 | ((((int)h.batteryVoltage)<<1)&0x00007ffe); 3426 } 3427 readBatteryLevelInt(int batteryLevelInt, HistoryItem out)3428 private void readBatteryLevelInt(int batteryLevelInt, HistoryItem out) { 3429 out.batteryLevel = (byte)((batteryLevelInt & 0xfe000000) >>> 25); 3430 out.batteryTemperature = (short)((batteryLevelInt & 0x01ff8000) >>> 15); 3431 out.batteryVoltage = (char)((batteryLevelInt & 0x00007ffe) >>> 1); 3432 } 3433 buildStateInt(HistoryItem h)3434 private int buildStateInt(HistoryItem h) { 3435 int plugType = 0; 3436 if ((h.batteryPlugType&BatteryManager.BATTERY_PLUGGED_AC) != 0) { 3437 plugType = 1; 3438 } else if ((h.batteryPlugType&BatteryManager.BATTERY_PLUGGED_USB) != 0) { 3439 plugType = 2; 3440 } else if ((h.batteryPlugType&BatteryManager.BATTERY_PLUGGED_WIRELESS) != 0) { 3441 plugType = 3; 3442 } 3443 return ((h.batteryStatus&STATE_BATTERY_STATUS_MASK)<<STATE_BATTERY_STATUS_SHIFT) 3444 | ((h.batteryHealth&STATE_BATTERY_HEALTH_MASK)<<STATE_BATTERY_HEALTH_SHIFT) 3445 | ((plugType&STATE_BATTERY_PLUG_MASK)<<STATE_BATTERY_PLUG_SHIFT) 3446 | (h.states&(~STATE_BATTERY_MASK)); 3447 } 3448 computeHistoryStepDetails(final HistoryStepDetails out, final HistoryStepDetails last)3449 private void computeHistoryStepDetails(final HistoryStepDetails out, 3450 final HistoryStepDetails last) { 3451 final HistoryStepDetails tmp = last != null ? mTmpHistoryStepDetails : out; 3452 3453 // Perform a CPU update right after we do this collection, so we have started 3454 // collecting good data for the next step. 3455 requestImmediateCpuUpdate(); 3456 3457 if (last == null) { 3458 // We are not generating a delta, so all we need to do is reset the stats 3459 // we will later be doing a delta from. 3460 final int NU = mUidStats.size(); 3461 for (int i=0; i<NU; i++) { 3462 final BatteryStatsImpl.Uid uid = mUidStats.valueAt(i); 3463 uid.mLastStepUserTime = uid.mCurStepUserTime; 3464 uid.mLastStepSystemTime = uid.mCurStepSystemTime; 3465 } 3466 mLastStepCpuUserTime = mCurStepCpuUserTime; 3467 mLastStepCpuSystemTime = mCurStepCpuSystemTime; 3468 mLastStepStatUserTime = mCurStepStatUserTime; 3469 mLastStepStatSystemTime = mCurStepStatSystemTime; 3470 mLastStepStatIOWaitTime = mCurStepStatIOWaitTime; 3471 mLastStepStatIrqTime = mCurStepStatIrqTime; 3472 mLastStepStatSoftIrqTime = mCurStepStatSoftIrqTime; 3473 mLastStepStatIdleTime = mCurStepStatIdleTime; 3474 tmp.clear(); 3475 return; 3476 } 3477 if (DEBUG) { 3478 Slog.d(TAG, "Step stats last: user=" + mLastStepCpuUserTime + " sys=" 3479 + mLastStepStatSystemTime + " io=" + mLastStepStatIOWaitTime 3480 + " irq=" + mLastStepStatIrqTime + " sirq=" 3481 + mLastStepStatSoftIrqTime + " idle=" + mLastStepStatIdleTime); 3482 Slog.d(TAG, "Step stats cur: user=" + mCurStepCpuUserTime + " sys=" 3483 + mCurStepStatSystemTime + " io=" + mCurStepStatIOWaitTime 3484 + " irq=" + mCurStepStatIrqTime + " sirq=" 3485 + mCurStepStatSoftIrqTime + " idle=" + mCurStepStatIdleTime); 3486 } 3487 out.userTime = (int)(mCurStepCpuUserTime - mLastStepCpuUserTime); 3488 out.systemTime = (int)(mCurStepCpuSystemTime - mLastStepCpuSystemTime); 3489 out.statUserTime = (int)(mCurStepStatUserTime - mLastStepStatUserTime); 3490 out.statSystemTime = (int)(mCurStepStatSystemTime - mLastStepStatSystemTime); 3491 out.statIOWaitTime = (int)(mCurStepStatIOWaitTime - mLastStepStatIOWaitTime); 3492 out.statIrqTime = (int)(mCurStepStatIrqTime - mLastStepStatIrqTime); 3493 out.statSoftIrqTime = (int)(mCurStepStatSoftIrqTime - mLastStepStatSoftIrqTime); 3494 out.statIdlTime = (int)(mCurStepStatIdleTime - mLastStepStatIdleTime); 3495 out.appCpuUid1 = out.appCpuUid2 = out.appCpuUid3 = -1; 3496 out.appCpuUTime1 = out.appCpuUTime2 = out.appCpuUTime3 = 0; 3497 out.appCpuSTime1 = out.appCpuSTime2 = out.appCpuSTime3 = 0; 3498 final int NU = mUidStats.size(); 3499 for (int i=0; i<NU; i++) { 3500 final BatteryStatsImpl.Uid uid = mUidStats.valueAt(i); 3501 final int totalUTime = (int)(uid.mCurStepUserTime - uid.mLastStepUserTime); 3502 final int totalSTime = (int)(uid.mCurStepSystemTime - uid.mLastStepSystemTime); 3503 final int totalTime = totalUTime + totalSTime; 3504 uid.mLastStepUserTime = uid.mCurStepUserTime; 3505 uid.mLastStepSystemTime = uid.mCurStepSystemTime; 3506 if (totalTime <= (out.appCpuUTime3+out.appCpuSTime3)) { 3507 continue; 3508 } 3509 if (totalTime <= (out.appCpuUTime2+out.appCpuSTime2)) { 3510 out.appCpuUid3 = uid.mUid; 3511 out.appCpuUTime3 = totalUTime; 3512 out.appCpuSTime3 = totalSTime; 3513 } else { 3514 out.appCpuUid3 = out.appCpuUid2; 3515 out.appCpuUTime3 = out.appCpuUTime2; 3516 out.appCpuSTime3 = out.appCpuSTime2; 3517 if (totalTime <= (out.appCpuUTime1+out.appCpuSTime1)) { 3518 out.appCpuUid2 = uid.mUid; 3519 out.appCpuUTime2 = totalUTime; 3520 out.appCpuSTime2 = totalSTime; 3521 } else { 3522 out.appCpuUid2 = out.appCpuUid1; 3523 out.appCpuUTime2 = out.appCpuUTime1; 3524 out.appCpuSTime2 = out.appCpuSTime1; 3525 out.appCpuUid1 = uid.mUid; 3526 out.appCpuUTime1 = totalUTime; 3527 out.appCpuSTime1 = totalSTime; 3528 } 3529 } 3530 } 3531 mLastStepCpuUserTime = mCurStepCpuUserTime; 3532 mLastStepCpuSystemTime = mCurStepCpuSystemTime; 3533 mLastStepStatUserTime = mCurStepStatUserTime; 3534 mLastStepStatSystemTime = mCurStepStatSystemTime; 3535 mLastStepStatIOWaitTime = mCurStepStatIOWaitTime; 3536 mLastStepStatIrqTime = mCurStepStatIrqTime; 3537 mLastStepStatSoftIrqTime = mCurStepStatSoftIrqTime; 3538 mLastStepStatIdleTime = mCurStepStatIdleTime; 3539 } 3540 readHistoryDelta(Parcel src, HistoryItem cur)3541 public void readHistoryDelta(Parcel src, HistoryItem cur) { 3542 int firstToken = src.readInt(); 3543 int deltaTimeToken = firstToken&DELTA_TIME_MASK; 3544 cur.cmd = HistoryItem.CMD_UPDATE; 3545 cur.numReadInts = 1; 3546 if (DEBUG) Slog.i(TAG, "READ DELTA: firstToken=0x" + Integer.toHexString(firstToken) 3547 + " deltaTimeToken=" + deltaTimeToken); 3548 3549 if (deltaTimeToken < DELTA_TIME_ABS) { 3550 cur.time += deltaTimeToken; 3551 } else if (deltaTimeToken == DELTA_TIME_ABS) { 3552 cur.time = src.readLong(); 3553 cur.numReadInts += 2; 3554 if (DEBUG) Slog.i(TAG, "READ DELTA: ABS time=" + cur.time); 3555 cur.readFromParcel(src); 3556 return; 3557 } else if (deltaTimeToken == DELTA_TIME_INT) { 3558 int delta = src.readInt(); 3559 cur.time += delta; 3560 cur.numReadInts += 1; 3561 if (DEBUG) Slog.i(TAG, "READ DELTA: time delta=" + delta + " new time=" + cur.time); 3562 } else { 3563 long delta = src.readLong(); 3564 if (DEBUG) Slog.i(TAG, "READ DELTA: time delta=" + delta + " new time=" + cur.time); 3565 cur.time += delta; 3566 cur.numReadInts += 2; 3567 } 3568 3569 final int batteryLevelInt; 3570 if ((firstToken&DELTA_BATTERY_LEVEL_FLAG) != 0) { 3571 batteryLevelInt = src.readInt(); 3572 readBatteryLevelInt(batteryLevelInt, cur); 3573 cur.numReadInts += 1; 3574 if (DEBUG) Slog.i(TAG, "READ DELTA: batteryToken=0x" 3575 + Integer.toHexString(batteryLevelInt) 3576 + " batteryLevel=" + cur.batteryLevel 3577 + " batteryTemp=" + cur.batteryTemperature 3578 + " batteryVolt=" + (int)cur.batteryVoltage); 3579 } else { 3580 batteryLevelInt = 0; 3581 } 3582 3583 if ((firstToken&DELTA_STATE_FLAG) != 0) { 3584 int stateInt = src.readInt(); 3585 cur.states = (firstToken&DELTA_STATE_MASK) | (stateInt&(~STATE_BATTERY_MASK)); 3586 cur.batteryStatus = (byte)((stateInt>>STATE_BATTERY_STATUS_SHIFT) 3587 & STATE_BATTERY_STATUS_MASK); 3588 cur.batteryHealth = (byte)((stateInt>>STATE_BATTERY_HEALTH_SHIFT) 3589 & STATE_BATTERY_HEALTH_MASK); 3590 cur.batteryPlugType = (byte)((stateInt>>STATE_BATTERY_PLUG_SHIFT) 3591 & STATE_BATTERY_PLUG_MASK); 3592 switch (cur.batteryPlugType) { 3593 case 1: 3594 cur.batteryPlugType = BatteryManager.BATTERY_PLUGGED_AC; 3595 break; 3596 case 2: 3597 cur.batteryPlugType = BatteryManager.BATTERY_PLUGGED_USB; 3598 break; 3599 case 3: 3600 cur.batteryPlugType = BatteryManager.BATTERY_PLUGGED_WIRELESS; 3601 break; 3602 } 3603 cur.numReadInts += 1; 3604 if (DEBUG) Slog.i(TAG, "READ DELTA: stateToken=0x" 3605 + Integer.toHexString(stateInt) 3606 + " batteryStatus=" + cur.batteryStatus 3607 + " batteryHealth=" + cur.batteryHealth 3608 + " batteryPlugType=" + cur.batteryPlugType 3609 + " states=0x" + Integer.toHexString(cur.states)); 3610 } else { 3611 cur.states = (firstToken&DELTA_STATE_MASK) | (cur.states&(~STATE_BATTERY_MASK)); 3612 } 3613 3614 if ((firstToken&DELTA_STATE2_FLAG) != 0) { 3615 cur.states2 = src.readInt(); 3616 if (DEBUG) Slog.i(TAG, "READ DELTA: states2=0x" 3617 + Integer.toHexString(cur.states2)); 3618 } 3619 3620 if ((firstToken&DELTA_WAKELOCK_FLAG) != 0) { 3621 int indexes = src.readInt(); 3622 int wakeLockIndex = indexes&0xffff; 3623 int wakeReasonIndex = (indexes>>16)&0xffff; 3624 if (wakeLockIndex != 0xffff) { 3625 cur.wakelockTag = cur.localWakelockTag; 3626 readHistoryTag(wakeLockIndex, cur.wakelockTag); 3627 if (DEBUG) Slog.i(TAG, "READ DELTA: wakelockTag=#" + cur.wakelockTag.poolIdx 3628 + " " + cur.wakelockTag.uid + ":" + cur.wakelockTag.string); 3629 } else { 3630 cur.wakelockTag = null; 3631 } 3632 if (wakeReasonIndex != 0xffff) { 3633 cur.wakeReasonTag = cur.localWakeReasonTag; 3634 readHistoryTag(wakeReasonIndex, cur.wakeReasonTag); 3635 if (DEBUG) Slog.i(TAG, "READ DELTA: wakeReasonTag=#" + cur.wakeReasonTag.poolIdx 3636 + " " + cur.wakeReasonTag.uid + ":" + cur.wakeReasonTag.string); 3637 } else { 3638 cur.wakeReasonTag = null; 3639 } 3640 cur.numReadInts += 1; 3641 } else { 3642 cur.wakelockTag = null; 3643 cur.wakeReasonTag = null; 3644 } 3645 3646 if ((firstToken&DELTA_EVENT_FLAG) != 0) { 3647 cur.eventTag = cur.localEventTag; 3648 final int codeAndIndex = src.readInt(); 3649 cur.eventCode = (codeAndIndex&0xffff); 3650 final int index = ((codeAndIndex>>16)&0xffff); 3651 readHistoryTag(index, cur.eventTag); 3652 cur.numReadInts += 1; 3653 if (DEBUG) Slog.i(TAG, "READ DELTA: event=" + cur.eventCode + " tag=#" 3654 + cur.eventTag.poolIdx + " " + cur.eventTag.uid + ":" 3655 + cur.eventTag.string); 3656 } else { 3657 cur.eventCode = HistoryItem.EVENT_NONE; 3658 } 3659 3660 if ((batteryLevelInt&BATTERY_DELTA_LEVEL_FLAG) != 0) { 3661 cur.stepDetails = mReadHistoryStepDetails; 3662 cur.stepDetails.readFromParcel(src); 3663 } else { 3664 cur.stepDetails = null; 3665 } 3666 3667 if ((firstToken&DELTA_BATTERY_CHARGE_FLAG) != 0) { 3668 cur.batteryChargeUAh = src.readInt(); 3669 } 3670 } 3671 3672 @Override commitCurrentHistoryBatchLocked()3673 public void commitCurrentHistoryBatchLocked() { 3674 mHistoryLastWritten.cmd = HistoryItem.CMD_NULL; 3675 } 3676 addHistoryBufferLocked(long elapsedRealtimeMs, HistoryItem cur)3677 void addHistoryBufferLocked(long elapsedRealtimeMs, HistoryItem cur) { 3678 if (!mHaveBatteryLevel || !mRecordingHistory) { 3679 return; 3680 } 3681 3682 final long timeDiff = (mHistoryBaseTime+elapsedRealtimeMs) - mHistoryLastWritten.time; 3683 final int diffStates = mHistoryLastWritten.states^(cur.states&mActiveHistoryStates); 3684 final int diffStates2 = mHistoryLastWritten.states2^(cur.states2&mActiveHistoryStates2); 3685 final int lastDiffStates = mHistoryLastWritten.states^mHistoryLastLastWritten.states; 3686 final int lastDiffStates2 = mHistoryLastWritten.states2^mHistoryLastLastWritten.states2; 3687 if (DEBUG) Slog.i(TAG, "ADD: tdelta=" + timeDiff + " diff=" 3688 + Integer.toHexString(diffStates) + " lastDiff=" 3689 + Integer.toHexString(lastDiffStates) + " diff2=" 3690 + Integer.toHexString(diffStates2) + " lastDiff2=" 3691 + Integer.toHexString(lastDiffStates2)); 3692 if (mHistoryBufferLastPos >= 0 && mHistoryLastWritten.cmd == HistoryItem.CMD_UPDATE 3693 && timeDiff < 1000 && (diffStates&lastDiffStates) == 0 3694 && (diffStates2&lastDiffStates2) == 0 3695 && (mHistoryLastWritten.wakelockTag == null || cur.wakelockTag == null) 3696 && (mHistoryLastWritten.wakeReasonTag == null || cur.wakeReasonTag == null) 3697 && mHistoryLastWritten.stepDetails == null 3698 && (mHistoryLastWritten.eventCode == HistoryItem.EVENT_NONE 3699 || cur.eventCode == HistoryItem.EVENT_NONE) 3700 && mHistoryLastWritten.batteryLevel == cur.batteryLevel 3701 && mHistoryLastWritten.batteryStatus == cur.batteryStatus 3702 && mHistoryLastWritten.batteryHealth == cur.batteryHealth 3703 && mHistoryLastWritten.batteryPlugType == cur.batteryPlugType 3704 && mHistoryLastWritten.batteryTemperature == cur.batteryTemperature 3705 && mHistoryLastWritten.batteryVoltage == cur.batteryVoltage) { 3706 // We can merge this new change in with the last one. Merging is 3707 // allowed as long as only the states have changed, and within those states 3708 // as long as no bit has changed both between now and the last entry, as 3709 // well as the last entry and the one before it (so we capture any toggles). 3710 if (DEBUG) Slog.i(TAG, "ADD: rewinding back to " + mHistoryBufferLastPos); 3711 mHistoryBuffer.setDataSize(mHistoryBufferLastPos); 3712 mHistoryBuffer.setDataPosition(mHistoryBufferLastPos); 3713 mHistoryBufferLastPos = -1; 3714 elapsedRealtimeMs = mHistoryLastWritten.time - mHistoryBaseTime; 3715 // If the last written history had a wakelock tag, we need to retain it. 3716 // Note that the condition above made sure that we aren't in a case where 3717 // both it and the current history item have a wakelock tag. 3718 if (mHistoryLastWritten.wakelockTag != null) { 3719 cur.wakelockTag = cur.localWakelockTag; 3720 cur.wakelockTag.setTo(mHistoryLastWritten.wakelockTag); 3721 } 3722 // If the last written history had a wake reason tag, we need to retain it. 3723 // Note that the condition above made sure that we aren't in a case where 3724 // both it and the current history item have a wakelock tag. 3725 if (mHistoryLastWritten.wakeReasonTag != null) { 3726 cur.wakeReasonTag = cur.localWakeReasonTag; 3727 cur.wakeReasonTag.setTo(mHistoryLastWritten.wakeReasonTag); 3728 } 3729 // If the last written history had an event, we need to retain it. 3730 // Note that the condition above made sure that we aren't in a case where 3731 // both it and the current history item have an event. 3732 if (mHistoryLastWritten.eventCode != HistoryItem.EVENT_NONE) { 3733 cur.eventCode = mHistoryLastWritten.eventCode; 3734 cur.eventTag = cur.localEventTag; 3735 cur.eventTag.setTo(mHistoryLastWritten.eventTag); 3736 } 3737 mHistoryLastWritten.setTo(mHistoryLastLastWritten); 3738 } 3739 3740 boolean recordResetDueToOverflow = false; 3741 final int dataSize = mHistoryBuffer.dataSize(); 3742 if (dataSize >= MAX_MAX_HISTORY_BUFFER*3) { 3743 // Clients can't deal with history buffers this large. This only 3744 // really happens when the device is on charger and interacted with 3745 // for long periods of time, like in retail mode. Since the device is 3746 // most likely charged, when unplugged, stats would have reset anyways. 3747 // Reset the stats and mark that we overflowed. 3748 // b/32540341 3749 resetAllStatsLocked(); 3750 3751 // Mark that we want to set *OVERFLOW* event and the RESET:START 3752 // events. 3753 recordResetDueToOverflow = true; 3754 3755 } else if (dataSize >= MAX_HISTORY_BUFFER) { 3756 if (!mHistoryOverflow) { 3757 mHistoryOverflow = true; 3758 addHistoryBufferLocked(elapsedRealtimeMs, HistoryItem.CMD_UPDATE, cur); 3759 addHistoryBufferLocked(elapsedRealtimeMs, HistoryItem.CMD_OVERFLOW, cur); 3760 return; 3761 } 3762 3763 // After overflow, we allow various bit-wise states to settle to 0. 3764 boolean writeAnyway = false; 3765 final int curStates = cur.states & HistoryItem.SETTLE_TO_ZERO_STATES 3766 & mActiveHistoryStates; 3767 if (mHistoryLastWritten.states != curStates) { 3768 // mActiveHistoryStates keeps track of which bits in .states are now being 3769 // forced to 0. 3770 int old = mActiveHistoryStates; 3771 mActiveHistoryStates &= curStates | ~HistoryItem.SETTLE_TO_ZERO_STATES; 3772 writeAnyway |= old != mActiveHistoryStates; 3773 } 3774 final int curStates2 = cur.states2 & HistoryItem.SETTLE_TO_ZERO_STATES2 3775 & mActiveHistoryStates2; 3776 if (mHistoryLastWritten.states2 != curStates2) { 3777 // mActiveHistoryStates2 keeps track of which bits in .states2 are now being 3778 // forced to 0. 3779 int old = mActiveHistoryStates2; 3780 mActiveHistoryStates2 &= curStates2 | ~HistoryItem.SETTLE_TO_ZERO_STATES2; 3781 writeAnyway |= old != mActiveHistoryStates2; 3782 } 3783 3784 // Once we've reached the maximum number of items, we only 3785 // record changes to the battery level and the most interesting states. 3786 // Once we've reached the maximum maximum number of items, we only 3787 // record changes to the battery level. 3788 if (!writeAnyway && mHistoryLastWritten.batteryLevel == cur.batteryLevel && 3789 (dataSize >= MAX_MAX_HISTORY_BUFFER 3790 || ((mHistoryLastWritten.states^cur.states) 3791 & HistoryItem.MOST_INTERESTING_STATES) == 0 3792 || ((mHistoryLastWritten.states2^cur.states2) 3793 & HistoryItem.MOST_INTERESTING_STATES2) == 0)) { 3794 return; 3795 } 3796 3797 addHistoryBufferLocked(elapsedRealtimeMs, HistoryItem.CMD_UPDATE, cur); 3798 return; 3799 } 3800 3801 if (dataSize == 0 || recordResetDueToOverflow) { 3802 // The history is currently empty; we need it to start with a time stamp. 3803 cur.currentTime = System.currentTimeMillis(); 3804 if (recordResetDueToOverflow) { 3805 addHistoryBufferLocked(elapsedRealtimeMs, HistoryItem.CMD_OVERFLOW, cur); 3806 } 3807 addHistoryBufferLocked(elapsedRealtimeMs, HistoryItem.CMD_RESET, cur); 3808 } 3809 addHistoryBufferLocked(elapsedRealtimeMs, HistoryItem.CMD_UPDATE, cur); 3810 } 3811 addHistoryBufferLocked(long elapsedRealtimeMs, byte cmd, HistoryItem cur)3812 private void addHistoryBufferLocked(long elapsedRealtimeMs, byte cmd, HistoryItem cur) { 3813 if (mIteratingHistory) { 3814 throw new IllegalStateException("Can't do this while iterating history!"); 3815 } 3816 mHistoryBufferLastPos = mHistoryBuffer.dataPosition(); 3817 mHistoryLastLastWritten.setTo(mHistoryLastWritten); 3818 mHistoryLastWritten.setTo(mHistoryBaseTime + elapsedRealtimeMs, cmd, cur); 3819 mHistoryLastWritten.states &= mActiveHistoryStates; 3820 mHistoryLastWritten.states2 &= mActiveHistoryStates2; 3821 writeHistoryDelta(mHistoryBuffer, mHistoryLastWritten, mHistoryLastLastWritten); 3822 mLastHistoryElapsedRealtime = elapsedRealtimeMs; 3823 cur.wakelockTag = null; 3824 cur.wakeReasonTag = null; 3825 cur.eventCode = HistoryItem.EVENT_NONE; 3826 cur.eventTag = null; 3827 if (DEBUG_HISTORY) Slog.i(TAG, "Writing history buffer: was " + mHistoryBufferLastPos 3828 + " now " + mHistoryBuffer.dataPosition() 3829 + " size is now " + mHistoryBuffer.dataSize()); 3830 } 3831 3832 int mChangedStates = 0; 3833 int mChangedStates2 = 0; 3834 addHistoryRecordLocked(long elapsedRealtimeMs, long uptimeMs)3835 void addHistoryRecordLocked(long elapsedRealtimeMs, long uptimeMs) { 3836 if (mTrackRunningHistoryElapsedRealtime != 0) { 3837 final long diffElapsed = elapsedRealtimeMs - mTrackRunningHistoryElapsedRealtime; 3838 final long diffUptime = uptimeMs - mTrackRunningHistoryUptime; 3839 if (diffUptime < (diffElapsed-20)) { 3840 final long wakeElapsedTime = elapsedRealtimeMs - (diffElapsed - diffUptime); 3841 mHistoryAddTmp.setTo(mHistoryLastWritten); 3842 mHistoryAddTmp.wakelockTag = null; 3843 mHistoryAddTmp.wakeReasonTag = null; 3844 mHistoryAddTmp.eventCode = HistoryItem.EVENT_NONE; 3845 mHistoryAddTmp.states &= ~HistoryItem.STATE_CPU_RUNNING_FLAG; 3846 addHistoryRecordInnerLocked(wakeElapsedTime, mHistoryAddTmp); 3847 } 3848 } 3849 mHistoryCur.states |= HistoryItem.STATE_CPU_RUNNING_FLAG; 3850 mTrackRunningHistoryElapsedRealtime = elapsedRealtimeMs; 3851 mTrackRunningHistoryUptime = uptimeMs; 3852 addHistoryRecordInnerLocked(elapsedRealtimeMs, mHistoryCur); 3853 } 3854 addHistoryRecordInnerLocked(long elapsedRealtimeMs, HistoryItem cur)3855 void addHistoryRecordInnerLocked(long elapsedRealtimeMs, HistoryItem cur) { 3856 addHistoryBufferLocked(elapsedRealtimeMs, cur); 3857 3858 if (!USE_OLD_HISTORY) { 3859 return; 3860 } 3861 3862 if (!mHaveBatteryLevel || !mRecordingHistory) { 3863 return; 3864 } 3865 3866 // If the current time is basically the same as the last time, 3867 // and no states have since the last recorded entry changed and 3868 // are now resetting back to their original value, then just collapse 3869 // into one record. 3870 if (mHistoryEnd != null && mHistoryEnd.cmd == HistoryItem.CMD_UPDATE 3871 && (mHistoryBaseTime+elapsedRealtimeMs) < (mHistoryEnd.time+1000) 3872 && ((mHistoryEnd.states^cur.states)&mChangedStates&mActiveHistoryStates) == 0 3873 && ((mHistoryEnd.states2^cur.states2)&mChangedStates2&mActiveHistoryStates2) == 0) { 3874 // If the current is the same as the one before, then we no 3875 // longer need the entry. 3876 if (mHistoryLastEnd != null && mHistoryLastEnd.cmd == HistoryItem.CMD_UPDATE 3877 && (mHistoryBaseTime+elapsedRealtimeMs) < (mHistoryEnd.time+500) 3878 && mHistoryLastEnd.sameNonEvent(cur)) { 3879 mHistoryLastEnd.next = null; 3880 mHistoryEnd.next = mHistoryCache; 3881 mHistoryCache = mHistoryEnd; 3882 mHistoryEnd = mHistoryLastEnd; 3883 mHistoryLastEnd = null; 3884 } else { 3885 mChangedStates |= mHistoryEnd.states^(cur.states&mActiveHistoryStates); 3886 mChangedStates2 |= mHistoryEnd.states^(cur.states2&mActiveHistoryStates2); 3887 mHistoryEnd.setTo(mHistoryEnd.time, HistoryItem.CMD_UPDATE, cur); 3888 } 3889 return; 3890 } 3891 3892 mChangedStates = 0; 3893 mChangedStates2 = 0; 3894 3895 if (mNumHistoryItems == MAX_HISTORY_ITEMS 3896 || mNumHistoryItems == MAX_MAX_HISTORY_ITEMS) { 3897 addHistoryBufferLocked(elapsedRealtimeMs, HistoryItem.CMD_OVERFLOW, cur); 3898 } 3899 3900 if (mNumHistoryItems >= MAX_HISTORY_ITEMS) { 3901 // Once we've reached the maximum number of items, we only 3902 // record changes to the battery level and the most interesting states. 3903 // Once we've reached the maximum maximum number of items, we only 3904 // record changes to the battery level. 3905 if (mHistoryEnd != null && mHistoryEnd.batteryLevel 3906 == cur.batteryLevel && 3907 (mNumHistoryItems >= MAX_MAX_HISTORY_ITEMS 3908 || ((mHistoryEnd.states^(cur.states&mActiveHistoryStates)) 3909 & HistoryItem.MOST_INTERESTING_STATES) == 0)) { 3910 return; 3911 } 3912 } 3913 3914 addHistoryBufferLocked(elapsedRealtimeMs, HistoryItem.CMD_UPDATE, cur); 3915 } 3916 addHistoryEventLocked(long elapsedRealtimeMs, long uptimeMs, int code, String name, int uid)3917 public void addHistoryEventLocked(long elapsedRealtimeMs, long uptimeMs, int code, 3918 String name, int uid) { 3919 mHistoryCur.eventCode = code; 3920 mHistoryCur.eventTag = mHistoryCur.localEventTag; 3921 mHistoryCur.eventTag.string = name; 3922 mHistoryCur.eventTag.uid = uid; 3923 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 3924 } 3925 addHistoryRecordLocked(long elapsedRealtimeMs, long uptimeMs, byte cmd, HistoryItem cur)3926 void addHistoryRecordLocked(long elapsedRealtimeMs, long uptimeMs, byte cmd, HistoryItem cur) { 3927 HistoryItem rec = mHistoryCache; 3928 if (rec != null) { 3929 mHistoryCache = rec.next; 3930 } else { 3931 rec = new HistoryItem(); 3932 } 3933 rec.setTo(mHistoryBaseTime + elapsedRealtimeMs, cmd, cur); 3934 3935 addHistoryRecordLocked(rec); 3936 } 3937 addHistoryRecordLocked(HistoryItem rec)3938 void addHistoryRecordLocked(HistoryItem rec) { 3939 mNumHistoryItems++; 3940 rec.next = null; 3941 mHistoryLastEnd = mHistoryEnd; 3942 if (mHistoryEnd != null) { 3943 mHistoryEnd.next = rec; 3944 mHistoryEnd = rec; 3945 } else { 3946 mHistory = mHistoryEnd = rec; 3947 } 3948 } 3949 clearHistoryLocked()3950 void clearHistoryLocked() { 3951 if (DEBUG_HISTORY) Slog.i(TAG, "********** CLEARING HISTORY!"); 3952 if (USE_OLD_HISTORY) { 3953 if (mHistory != null) { 3954 mHistoryEnd.next = mHistoryCache; 3955 mHistoryCache = mHistory; 3956 mHistory = mHistoryLastEnd = mHistoryEnd = null; 3957 } 3958 mNumHistoryItems = 0; 3959 } 3960 3961 mHistoryBaseTime = 0; 3962 mLastHistoryElapsedRealtime = 0; 3963 mTrackRunningHistoryElapsedRealtime = 0; 3964 mTrackRunningHistoryUptime = 0; 3965 3966 mHistoryBuffer.setDataSize(0); 3967 mHistoryBuffer.setDataPosition(0); 3968 mHistoryBuffer.setDataCapacity(MAX_HISTORY_BUFFER / 2); 3969 mHistoryLastLastWritten.clear(); 3970 mHistoryLastWritten.clear(); 3971 mHistoryTagPool.clear(); 3972 mNextHistoryTagIdx = 0; 3973 mNumHistoryTagChars = 0; 3974 mHistoryBufferLastPos = -1; 3975 mHistoryOverflow = false; 3976 mActiveHistoryStates = 0xffffffff; 3977 mActiveHistoryStates2 = 0xffffffff; 3978 } 3979 3980 @GuardedBy("this") updateTimeBasesLocked(boolean unplugged, int screenState, long uptime, long realtime)3981 public void updateTimeBasesLocked(boolean unplugged, int screenState, long uptime, 3982 long realtime) { 3983 final boolean screenOff = !isScreenOn(screenState); 3984 final boolean updateOnBatteryTimeBase = unplugged != mOnBatteryTimeBase.isRunning(); 3985 final boolean updateOnBatteryScreenOffTimeBase = 3986 (unplugged && screenOff) != mOnBatteryScreenOffTimeBase.isRunning(); 3987 3988 if (updateOnBatteryScreenOffTimeBase || updateOnBatteryTimeBase) { 3989 if (updateOnBatteryScreenOffTimeBase) { 3990 updateKernelWakelocksLocked(); 3991 updateBatteryPropertiesLocked(); 3992 } 3993 // This if{} is only necessary due to SCREEN_OFF_RPM_STATS_ENABLED, which exists because 3994 // updateRpmStatsLocked is too slow to run each screen change. When the speed is 3995 // improved, remove the surrounding if{}. 3996 if (SCREEN_OFF_RPM_STATS_ENABLED || updateOnBatteryTimeBase) { 3997 updateRpmStatsLocked(); // if either OnBattery or OnBatteryScreenOff timebase changes. 3998 } 3999 if (DEBUG_ENERGY_CPU) { 4000 Slog.d(TAG, "Updating cpu time because screen is now " 4001 + Display.stateToString(screenState) 4002 + " and battery is " + (unplugged ? "on" : "off")); 4003 } 4004 4005 mOnBatteryTimeBase.setRunning(unplugged, uptime, realtime); 4006 if (updateOnBatteryTimeBase) { 4007 for (int i = mUidStats.size() - 1; i >= 0; --i) { 4008 mUidStats.valueAt(i).updateOnBatteryBgTimeBase(uptime, realtime); 4009 } 4010 } 4011 if (updateOnBatteryScreenOffTimeBase) { 4012 mOnBatteryScreenOffTimeBase.setRunning(unplugged && screenOff, uptime, realtime); 4013 for (int i = mUidStats.size() - 1; i >= 0; --i) { 4014 mUidStats.valueAt(i).updateOnBatteryScreenOffBgTimeBase(uptime, realtime); 4015 } 4016 } 4017 } 4018 } 4019 updateBatteryPropertiesLocked()4020 private void updateBatteryPropertiesLocked() { 4021 try { 4022 IBatteryPropertiesRegistrar registrar = IBatteryPropertiesRegistrar.Stub.asInterface( 4023 ServiceManager.getService("batteryproperties")); 4024 registrar.scheduleUpdate(); 4025 } catch (RemoteException e) { 4026 // Ignore. 4027 } 4028 } 4029 addIsolatedUidLocked(int isolatedUid, int appUid)4030 public void addIsolatedUidLocked(int isolatedUid, int appUid) { 4031 mIsolatedUids.put(isolatedUid, appUid); 4032 StatsLog.write(StatsLog.ISOLATED_UID_CHANGED, appUid, isolatedUid, 4033 StatsLog.ISOLATED_UID_CHANGED__EVENT__CREATED); 4034 final Uid u = getUidStatsLocked(appUid); 4035 u.addIsolatedUid(isolatedUid); 4036 } 4037 4038 /** 4039 * Schedules a read of the latest cpu times before removing the isolated UID. 4040 * @see #removeIsolatedUidLocked(int) 4041 */ scheduleRemoveIsolatedUidLocked(int isolatedUid, int appUid)4042 public void scheduleRemoveIsolatedUidLocked(int isolatedUid, int appUid) { 4043 int curUid = mIsolatedUids.get(isolatedUid, -1); 4044 if (curUid == appUid) { 4045 if (mExternalSync != null) { 4046 mExternalSync.scheduleCpuSyncDueToRemovedUid(isolatedUid); 4047 } 4048 } 4049 } 4050 4051 /** 4052 * This should only be called after the cpu times have been read. 4053 * @see #scheduleRemoveIsolatedUidLocked(int, int) 4054 */ 4055 @GuardedBy("this") removeIsolatedUidLocked(int isolatedUid)4056 public void removeIsolatedUidLocked(int isolatedUid) { 4057 StatsLog.write( 4058 StatsLog.ISOLATED_UID_CHANGED, mIsolatedUids.get(isolatedUid, -1), 4059 isolatedUid, StatsLog.ISOLATED_UID_CHANGED__EVENT__REMOVED); 4060 final int idx = mIsolatedUids.indexOfKey(isolatedUid); 4061 if (idx >= 0) { 4062 final int ownerUid = mIsolatedUids.valueAt(idx); 4063 final Uid u = getUidStatsLocked(ownerUid); 4064 u.removeIsolatedUid(isolatedUid); 4065 mIsolatedUids.removeAt(idx); 4066 } 4067 mPendingRemovedUids.add(new UidToRemove(isolatedUid, mClocks.elapsedRealtime())); 4068 } 4069 mapUid(int uid)4070 public int mapUid(int uid) { 4071 int isolated = mIsolatedUids.get(uid, -1); 4072 return isolated > 0 ? isolated : uid; 4073 } 4074 noteEventLocked(int code, String name, int uid)4075 public void noteEventLocked(int code, String name, int uid) { 4076 uid = mapUid(uid); 4077 if (!mActiveEvents.updateState(code, name, uid, 0)) { 4078 return; 4079 } 4080 final long elapsedRealtime = mClocks.elapsedRealtime(); 4081 final long uptime = mClocks.uptimeMillis(); 4082 addHistoryEventLocked(elapsedRealtime, uptime, code, name, uid); 4083 } 4084 ensureStartClockTime(final long currentTime)4085 boolean ensureStartClockTime(final long currentTime) { 4086 final long ABOUT_ONE_YEAR = 365*24*60*60*1000L; 4087 if ((currentTime > ABOUT_ONE_YEAR && mStartClockTime < (currentTime-ABOUT_ONE_YEAR)) 4088 || (mStartClockTime > currentTime)) { 4089 // If the start clock time has changed by more than a year, then presumably 4090 // the previous time was completely bogus. So we are going to figure out a 4091 // new time based on how much time has elapsed since we started counting. 4092 mStartClockTime = currentTime - (mClocks.elapsedRealtime()-(mRealtimeStart/1000)); 4093 return true; 4094 } 4095 return false; 4096 } 4097 noteCurrentTimeChangedLocked()4098 public void noteCurrentTimeChangedLocked() { 4099 final long currentTime = System.currentTimeMillis(); 4100 final long elapsedRealtime = mClocks.elapsedRealtime(); 4101 final long uptime = mClocks.uptimeMillis(); 4102 recordCurrentTimeChangeLocked(currentTime, elapsedRealtime, uptime); 4103 ensureStartClockTime(currentTime); 4104 } 4105 noteProcessStartLocked(String name, int uid)4106 public void noteProcessStartLocked(String name, int uid) { 4107 uid = mapUid(uid); 4108 if (isOnBattery()) { 4109 Uid u = getUidStatsLocked(uid); 4110 u.getProcessStatsLocked(name).incStartsLocked(); 4111 } 4112 if (!mActiveEvents.updateState(HistoryItem.EVENT_PROC_START, name, uid, 0)) { 4113 return; 4114 } 4115 if (!mRecordAllHistory) { 4116 return; 4117 } 4118 final long elapsedRealtime = mClocks.elapsedRealtime(); 4119 final long uptime = mClocks.uptimeMillis(); 4120 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_PROC_START, name, uid); 4121 } 4122 noteProcessCrashLocked(String name, int uid)4123 public void noteProcessCrashLocked(String name, int uid) { 4124 uid = mapUid(uid); 4125 if (isOnBattery()) { 4126 Uid u = getUidStatsLocked(uid); 4127 u.getProcessStatsLocked(name).incNumCrashesLocked(); 4128 } 4129 } 4130 noteProcessAnrLocked(String name, int uid)4131 public void noteProcessAnrLocked(String name, int uid) { 4132 uid = mapUid(uid); 4133 if (isOnBattery()) { 4134 Uid u = getUidStatsLocked(uid); 4135 u.getProcessStatsLocked(name).incNumAnrsLocked(); 4136 } 4137 } 4138 noteUidProcessStateLocked(int uid, int state)4139 public void noteUidProcessStateLocked(int uid, int state) { 4140 int parentUid = mapUid(uid); 4141 if (uid != parentUid) { 4142 // Isolated UIDs process state is already rolled up into parent, so no need to track 4143 // Otherwise the parent's process state will get downgraded incorrectly 4144 return; 4145 } 4146 getUidStatsLocked(uid).updateUidProcessStateLocked(state); 4147 } 4148 noteProcessFinishLocked(String name, int uid)4149 public void noteProcessFinishLocked(String name, int uid) { 4150 uid = mapUid(uid); 4151 if (!mActiveEvents.updateState(HistoryItem.EVENT_PROC_FINISH, name, uid, 0)) { 4152 return; 4153 } 4154 if (!mRecordAllHistory) { 4155 return; 4156 } 4157 final long elapsedRealtime = mClocks.elapsedRealtime(); 4158 final long uptime = mClocks.uptimeMillis(); 4159 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_PROC_FINISH, name, uid); 4160 } 4161 noteSyncStartLocked(String name, int uid)4162 public void noteSyncStartLocked(String name, int uid) { 4163 uid = mapUid(uid); 4164 final long elapsedRealtime = mClocks.elapsedRealtime(); 4165 final long uptime = mClocks.uptimeMillis(); 4166 getUidStatsLocked(uid).noteStartSyncLocked(name, elapsedRealtime); 4167 if (!mActiveEvents.updateState(HistoryItem.EVENT_SYNC_START, name, uid, 0)) { 4168 return; 4169 } 4170 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_SYNC_START, name, uid); 4171 } 4172 noteSyncFinishLocked(String name, int uid)4173 public void noteSyncFinishLocked(String name, int uid) { 4174 uid = mapUid(uid); 4175 final long elapsedRealtime = mClocks.elapsedRealtime(); 4176 final long uptime = mClocks.uptimeMillis(); 4177 getUidStatsLocked(uid).noteStopSyncLocked(name, elapsedRealtime); 4178 if (!mActiveEvents.updateState(HistoryItem.EVENT_SYNC_FINISH, name, uid, 0)) { 4179 return; 4180 } 4181 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_SYNC_FINISH, name, uid); 4182 } 4183 noteJobStartLocked(String name, int uid)4184 public void noteJobStartLocked(String name, int uid) { 4185 uid = mapUid(uid); 4186 final long elapsedRealtime = mClocks.elapsedRealtime(); 4187 final long uptime = mClocks.uptimeMillis(); 4188 getUidStatsLocked(uid).noteStartJobLocked(name, elapsedRealtime); 4189 if (!mActiveEvents.updateState(HistoryItem.EVENT_JOB_START, name, uid, 0)) { 4190 return; 4191 } 4192 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_JOB_START, name, uid); 4193 } 4194 noteJobFinishLocked(String name, int uid, int stopReason)4195 public void noteJobFinishLocked(String name, int uid, int stopReason) { 4196 uid = mapUid(uid); 4197 final long elapsedRealtime = mClocks.elapsedRealtime(); 4198 final long uptime = mClocks.uptimeMillis(); 4199 getUidStatsLocked(uid).noteStopJobLocked(name, elapsedRealtime, stopReason); 4200 if (!mActiveEvents.updateState(HistoryItem.EVENT_JOB_FINISH, name, uid, 0)) { 4201 return; 4202 } 4203 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_JOB_FINISH, name, uid); 4204 } 4205 noteJobsDeferredLocked(int uid, int numDeferred, long sinceLast)4206 public void noteJobsDeferredLocked(int uid, int numDeferred, long sinceLast) { 4207 uid = mapUid(uid); 4208 getUidStatsLocked(uid).noteJobsDeferredLocked(numDeferred, sinceLast); 4209 } 4210 noteAlarmStartLocked(String name, WorkSource workSource, int uid)4211 public void noteAlarmStartLocked(String name, WorkSource workSource, int uid) { 4212 noteAlarmStartOrFinishLocked(HistoryItem.EVENT_ALARM_START, name, workSource, uid); 4213 } 4214 noteAlarmFinishLocked(String name, WorkSource workSource, int uid)4215 public void noteAlarmFinishLocked(String name, WorkSource workSource, int uid) { 4216 noteAlarmStartOrFinishLocked(HistoryItem.EVENT_ALARM_FINISH, name, workSource, uid); 4217 } 4218 noteAlarmStartOrFinishLocked(int historyItem, String name, WorkSource workSource, int uid)4219 private void noteAlarmStartOrFinishLocked(int historyItem, String name, WorkSource workSource, 4220 int uid) { 4221 if (!mRecordAllHistory) { 4222 return; 4223 } 4224 4225 final long elapsedRealtime = mClocks.elapsedRealtime(); 4226 final long uptime = mClocks.uptimeMillis(); 4227 4228 if (workSource != null) { 4229 for (int i = 0; i < workSource.size(); ++i) { 4230 uid = mapUid(workSource.get(i)); 4231 if (mActiveEvents.updateState(historyItem, name, uid, 0)) { 4232 addHistoryEventLocked(elapsedRealtime, uptime, historyItem, name, uid); 4233 } 4234 } 4235 4236 List<WorkChain> workChains = workSource.getWorkChains(); 4237 if (workChains != null) { 4238 for (int i = 0; i < workChains.size(); ++i) { 4239 uid = mapUid(workChains.get(i).getAttributionUid()); 4240 if (mActiveEvents.updateState(historyItem, name, uid, 0)) { 4241 addHistoryEventLocked(elapsedRealtime, uptime, historyItem, name, uid); 4242 } 4243 } 4244 } 4245 } else { 4246 uid = mapUid(uid); 4247 4248 if (mActiveEvents.updateState(historyItem, name, uid, 0)) { 4249 addHistoryEventLocked(elapsedRealtime, uptime, historyItem, name, uid); 4250 } 4251 } 4252 } 4253 noteWakupAlarmLocked(String packageName, int uid, WorkSource workSource, String tag)4254 public void noteWakupAlarmLocked(String packageName, int uid, WorkSource workSource, 4255 String tag) { 4256 if (workSource != null) { 4257 for (int i = 0; i < workSource.size(); ++i) { 4258 uid = workSource.get(i); 4259 final String workSourceName = workSource.getName(i); 4260 4261 if (isOnBattery()) { 4262 BatteryStatsImpl.Uid.Pkg pkg = getPackageStatsLocked(uid, 4263 workSourceName != null ? workSourceName : packageName); 4264 pkg.noteWakeupAlarmLocked(tag); 4265 } 4266 StatsLog.write_non_chained(StatsLog.WAKEUP_ALARM_OCCURRED, workSource.get(i), 4267 workSource.getName(i), tag); 4268 } 4269 4270 ArrayList<WorkChain> workChains = workSource.getWorkChains(); 4271 if (workChains != null) { 4272 for (int i = 0; i < workChains.size(); ++i) { 4273 final WorkChain wc = workChains.get(i); 4274 uid = wc.getAttributionUid(); 4275 4276 if (isOnBattery()) { 4277 BatteryStatsImpl.Uid.Pkg pkg = getPackageStatsLocked(uid, packageName); 4278 pkg.noteWakeupAlarmLocked(tag); 4279 } 4280 StatsLog.write(StatsLog.WAKEUP_ALARM_OCCURRED, wc.getUids(), wc.getTags(), tag); 4281 } 4282 } 4283 } else { 4284 if (isOnBattery()) { 4285 BatteryStatsImpl.Uid.Pkg pkg = getPackageStatsLocked(uid, packageName); 4286 pkg.noteWakeupAlarmLocked(tag); 4287 } 4288 StatsLog.write_non_chained(StatsLog.WAKEUP_ALARM_OCCURRED, uid, null, tag); 4289 } 4290 } 4291 requestWakelockCpuUpdate()4292 private void requestWakelockCpuUpdate() { 4293 mExternalSync.scheduleCpuSyncDueToWakelockChange(DELAY_UPDATE_WAKELOCKS); 4294 } 4295 requestImmediateCpuUpdate()4296 private void requestImmediateCpuUpdate() { 4297 mExternalSync.scheduleCpuSyncDueToWakelockChange(0 /* delayMillis */); 4298 } 4299 setRecordAllHistoryLocked(boolean enabled)4300 public void setRecordAllHistoryLocked(boolean enabled) { 4301 mRecordAllHistory = enabled; 4302 if (!enabled) { 4303 // Clear out any existing state. 4304 mActiveEvents.removeEvents(HistoryItem.EVENT_WAKE_LOCK); 4305 mActiveEvents.removeEvents(HistoryItem.EVENT_ALARM); 4306 // Record the currently running processes as stopping, now that we are no 4307 // longer tracking them. 4308 HashMap<String, SparseIntArray> active = mActiveEvents.getStateForEvent( 4309 HistoryItem.EVENT_PROC); 4310 if (active != null) { 4311 long mSecRealtime = mClocks.elapsedRealtime(); 4312 final long mSecUptime = mClocks.uptimeMillis(); 4313 for (HashMap.Entry<String, SparseIntArray> ent : active.entrySet()) { 4314 SparseIntArray uids = ent.getValue(); 4315 for (int j=0; j<uids.size(); j++) { 4316 addHistoryEventLocked(mSecRealtime, mSecUptime, 4317 HistoryItem.EVENT_PROC_FINISH, ent.getKey(), uids.keyAt(j)); 4318 } 4319 } 4320 } 4321 } else { 4322 // Record the currently running processes as starting, now that we are tracking them. 4323 HashMap<String, SparseIntArray> active = mActiveEvents.getStateForEvent( 4324 HistoryItem.EVENT_PROC); 4325 if (active != null) { 4326 long mSecRealtime = mClocks.elapsedRealtime(); 4327 final long mSecUptime = mClocks.uptimeMillis(); 4328 for (HashMap.Entry<String, SparseIntArray> ent : active.entrySet()) { 4329 SparseIntArray uids = ent.getValue(); 4330 for (int j=0; j<uids.size(); j++) { 4331 addHistoryEventLocked(mSecRealtime, mSecUptime, 4332 HistoryItem.EVENT_PROC_START, ent.getKey(), uids.keyAt(j)); 4333 } 4334 } 4335 } 4336 } 4337 } 4338 setNoAutoReset(boolean enabled)4339 public void setNoAutoReset(boolean enabled) { 4340 mNoAutoReset = enabled; 4341 } 4342 setPretendScreenOff(boolean pretendScreenOff)4343 public void setPretendScreenOff(boolean pretendScreenOff) { 4344 if (mPretendScreenOff != pretendScreenOff) { 4345 mPretendScreenOff = pretendScreenOff; 4346 noteScreenStateLocked(pretendScreenOff ? Display.STATE_OFF : Display.STATE_ON); 4347 } 4348 } 4349 4350 private String mInitialAcquireWakeName; 4351 private int mInitialAcquireWakeUid = -1; 4352 noteStartWakeLocked(int uid, int pid, WorkChain wc, String name, String historyName, int type, boolean unimportantForLogging, long elapsedRealtime, long uptime)4353 public void noteStartWakeLocked(int uid, int pid, WorkChain wc, String name, String historyName, 4354 int type, boolean unimportantForLogging, long elapsedRealtime, long uptime) { 4355 uid = mapUid(uid); 4356 if (type == WAKE_TYPE_PARTIAL) { 4357 // Only care about partial wake locks, since full wake locks 4358 // will be canceled when the user puts the screen to sleep. 4359 aggregateLastWakeupUptimeLocked(uptime); 4360 if (historyName == null) { 4361 historyName = name; 4362 } 4363 if (mRecordAllHistory) { 4364 if (mActiveEvents.updateState(HistoryItem.EVENT_WAKE_LOCK_START, historyName, 4365 uid, 0)) { 4366 addHistoryEventLocked(elapsedRealtime, uptime, 4367 HistoryItem.EVENT_WAKE_LOCK_START, historyName, uid); 4368 } 4369 } 4370 if (mWakeLockNesting == 0) { 4371 mHistoryCur.states |= HistoryItem.STATE_WAKE_LOCK_FLAG; 4372 if (DEBUG_HISTORY) Slog.v(TAG, "Start wake lock to: " 4373 + Integer.toHexString(mHistoryCur.states)); 4374 mHistoryCur.wakelockTag = mHistoryCur.localWakelockTag; 4375 mHistoryCur.wakelockTag.string = mInitialAcquireWakeName = historyName; 4376 mHistoryCur.wakelockTag.uid = mInitialAcquireWakeUid = uid; 4377 mWakeLockImportant = !unimportantForLogging; 4378 addHistoryRecordLocked(elapsedRealtime, uptime); 4379 } else if (!mWakeLockImportant && !unimportantForLogging 4380 && mHistoryLastWritten.cmd == HistoryItem.CMD_UPDATE) { 4381 if (mHistoryLastWritten.wakelockTag != null) { 4382 // We'll try to update the last tag. 4383 mHistoryLastWritten.wakelockTag = null; 4384 mHistoryCur.wakelockTag = mHistoryCur.localWakelockTag; 4385 mHistoryCur.wakelockTag.string = mInitialAcquireWakeName = historyName; 4386 mHistoryCur.wakelockTag.uid = mInitialAcquireWakeUid = uid; 4387 addHistoryRecordLocked(elapsedRealtime, uptime); 4388 } 4389 mWakeLockImportant = true; 4390 } 4391 mWakeLockNesting++; 4392 } 4393 if (uid >= 0) { 4394 if (mOnBatteryScreenOffTimeBase.isRunning()) { 4395 // We only update the cpu time when a wake lock is acquired if the screen is off. 4396 // If the screen is on, we don't distribute the power amongst partial wakelocks. 4397 if (DEBUG_ENERGY_CPU) { 4398 Slog.d(TAG, "Updating cpu time because of +wake_lock"); 4399 } 4400 requestWakelockCpuUpdate(); 4401 } 4402 4403 getUidStatsLocked(uid).noteStartWakeLocked(pid, name, type, elapsedRealtime); 4404 4405 if (wc != null) { 4406 StatsLog.write(StatsLog.WAKELOCK_STATE_CHANGED, wc.getUids(), wc.getTags(), 4407 getPowerManagerWakeLockLevel(type), name, 4408 StatsLog.WAKELOCK_STATE_CHANGED__STATE__ACQUIRE); 4409 } else { 4410 StatsLog.write_non_chained(StatsLog.WAKELOCK_STATE_CHANGED, uid, null, 4411 getPowerManagerWakeLockLevel(type), name, 4412 StatsLog.WAKELOCK_STATE_CHANGED__STATE__ACQUIRE); 4413 } 4414 } 4415 } 4416 noteStopWakeLocked(int uid, int pid, WorkChain wc, String name, String historyName, int type, long elapsedRealtime, long uptime)4417 public void noteStopWakeLocked(int uid, int pid, WorkChain wc, String name, String historyName, 4418 int type, long elapsedRealtime, long uptime) { 4419 uid = mapUid(uid); 4420 if (type == WAKE_TYPE_PARTIAL) { 4421 mWakeLockNesting--; 4422 if (mRecordAllHistory) { 4423 if (historyName == null) { 4424 historyName = name; 4425 } 4426 if (mActiveEvents.updateState(HistoryItem.EVENT_WAKE_LOCK_FINISH, historyName, 4427 uid, 0)) { 4428 addHistoryEventLocked(elapsedRealtime, uptime, 4429 HistoryItem.EVENT_WAKE_LOCK_FINISH, historyName, uid); 4430 } 4431 } 4432 if (mWakeLockNesting == 0) { 4433 mHistoryCur.states &= ~HistoryItem.STATE_WAKE_LOCK_FLAG; 4434 if (DEBUG_HISTORY) Slog.v(TAG, "Stop wake lock to: " 4435 + Integer.toHexString(mHistoryCur.states)); 4436 mInitialAcquireWakeName = null; 4437 mInitialAcquireWakeUid = -1; 4438 addHistoryRecordLocked(elapsedRealtime, uptime); 4439 } 4440 } 4441 if (uid >= 0) { 4442 if (mOnBatteryScreenOffTimeBase.isRunning()) { 4443 if (DEBUG_ENERGY_CPU) { 4444 Slog.d(TAG, "Updating cpu time because of -wake_lock"); 4445 } 4446 requestWakelockCpuUpdate(); 4447 } 4448 4449 getUidStatsLocked(uid).noteStopWakeLocked(pid, name, type, elapsedRealtime); 4450 if (wc != null) { 4451 StatsLog.write(StatsLog.WAKELOCK_STATE_CHANGED, wc.getUids(), wc.getTags(), 4452 getPowerManagerWakeLockLevel(type), name, 4453 StatsLog.WAKELOCK_STATE_CHANGED__STATE__RELEASE); 4454 } else { 4455 StatsLog.write_non_chained(StatsLog.WAKELOCK_STATE_CHANGED, uid, null, 4456 getPowerManagerWakeLockLevel(type), name, 4457 StatsLog.WAKELOCK_STATE_CHANGED__STATE__RELEASE); 4458 } 4459 } 4460 } 4461 4462 /** 4463 * Converts BatteryStats wakelock types back into PowerManager wakelock levels. 4464 * This is the inverse map of Notifier.getBatteryStatsWakeLockMonitorType(). 4465 * These are estimations, since batterystats loses some of the original data. 4466 * TODO: Delete this. Instead, StatsLog.write should be called from PowerManager's Notifier. 4467 */ getPowerManagerWakeLockLevel(int battertStatsWakelockType)4468 private int getPowerManagerWakeLockLevel(int battertStatsWakelockType) { 4469 switch (battertStatsWakelockType) { 4470 // PowerManager.PARTIAL_WAKE_LOCK or PROXIMITY_SCREEN_OFF_WAKE_LOCK 4471 case BatteryStats.WAKE_TYPE_PARTIAL: 4472 return PowerManager.PARTIAL_WAKE_LOCK; 4473 4474 // PowerManager.SCREEN_DIM_WAKE_LOCK or SCREEN_BRIGHT_WAKE_LOCK 4475 case BatteryStats.WAKE_TYPE_FULL: 4476 return PowerManager.FULL_WAKE_LOCK; 4477 4478 case BatteryStats.WAKE_TYPE_DRAW: 4479 return PowerManager.DRAW_WAKE_LOCK; 4480 4481 // It appears that nothing can ever make a Window and PowerManager lacks an equivalent. 4482 case BatteryStats.WAKE_TYPE_WINDOW: 4483 Slog.e(TAG, "Illegal window wakelock type observed in batterystats."); 4484 return -1; 4485 4486 default: 4487 Slog.e(TAG, "Illegal wakelock type in batterystats: " + battertStatsWakelockType); 4488 return -1; 4489 } 4490 } 4491 noteStartWakeFromSourceLocked(WorkSource ws, int pid, String name, String historyName, int type, boolean unimportantForLogging)4492 public void noteStartWakeFromSourceLocked(WorkSource ws, int pid, String name, 4493 String historyName, int type, boolean unimportantForLogging) { 4494 final long elapsedRealtime = mClocks.elapsedRealtime(); 4495 final long uptime = mClocks.uptimeMillis(); 4496 final int N = ws.size(); 4497 for (int i=0; i<N; i++) { 4498 noteStartWakeLocked(ws.get(i), pid, null, name, historyName, type, 4499 unimportantForLogging, elapsedRealtime, uptime); 4500 } 4501 4502 List<WorkChain> wcs = ws.getWorkChains(); 4503 if (wcs != null) { 4504 for (int i = 0; i < wcs.size(); ++i) { 4505 final WorkChain wc = wcs.get(i); 4506 noteStartWakeLocked(wc.getAttributionUid(), pid, wc, name, historyName, type, 4507 unimportantForLogging, elapsedRealtime, uptime); 4508 } 4509 } 4510 } 4511 noteChangeWakelockFromSourceLocked(WorkSource ws, int pid, String name, String historyName, int type, WorkSource newWs, int newPid, String newName, String newHistoryName, int newType, boolean newUnimportantForLogging)4512 public void noteChangeWakelockFromSourceLocked(WorkSource ws, int pid, String name, 4513 String historyName, int type, WorkSource newWs, int newPid, String newName, 4514 String newHistoryName, int newType, boolean newUnimportantForLogging) { 4515 final long elapsedRealtime = mClocks.elapsedRealtime(); 4516 final long uptime = mClocks.uptimeMillis(); 4517 4518 List<WorkChain>[] wcs = WorkSource.diffChains(ws, newWs); 4519 4520 // For correct semantics, we start the need worksources first, so that we won't 4521 // make inappropriate history items as if all wake locks went away and new ones 4522 // appeared. This is okay because tracking of wake locks allows nesting. 4523 // 4524 // First the starts : 4525 final int NN = newWs.size(); 4526 for (int i=0; i<NN; i++) { 4527 noteStartWakeLocked(newWs.get(i), newPid, null, newName, newHistoryName, newType, 4528 newUnimportantForLogging, elapsedRealtime, uptime); 4529 } 4530 if (wcs != null) { 4531 List<WorkChain> newChains = wcs[0]; 4532 if (newChains != null) { 4533 for (int i = 0; i < newChains.size(); ++i) { 4534 final WorkChain newChain = newChains.get(i); 4535 noteStartWakeLocked(newChain.getAttributionUid(), newPid, newChain, newName, 4536 newHistoryName, newType, newUnimportantForLogging, elapsedRealtime, 4537 uptime); 4538 } 4539 } 4540 } 4541 4542 // Then the stops : 4543 final int NO = ws.size(); 4544 for (int i=0; i<NO; i++) { 4545 noteStopWakeLocked(ws.get(i), pid, null, name, historyName, type, elapsedRealtime, 4546 uptime); 4547 } 4548 if (wcs != null) { 4549 List<WorkChain> goneChains = wcs[1]; 4550 if (goneChains != null) { 4551 for (int i = 0; i < goneChains.size(); ++i) { 4552 final WorkChain goneChain = goneChains.get(i); 4553 noteStopWakeLocked(goneChain.getAttributionUid(), pid, goneChain, name, 4554 historyName, type, elapsedRealtime, uptime); 4555 } 4556 } 4557 } 4558 } 4559 noteStopWakeFromSourceLocked(WorkSource ws, int pid, String name, String historyName, int type)4560 public void noteStopWakeFromSourceLocked(WorkSource ws, int pid, String name, 4561 String historyName, int type) { 4562 final long elapsedRealtime = mClocks.elapsedRealtime(); 4563 final long uptime = mClocks.uptimeMillis(); 4564 final int N = ws.size(); 4565 for (int i=0; i<N; i++) { 4566 noteStopWakeLocked(ws.get(i), pid, null, name, historyName, type, elapsedRealtime, 4567 uptime); 4568 } 4569 4570 List<WorkChain> wcs = ws.getWorkChains(); 4571 if (wcs != null) { 4572 for (int i = 0; i < wcs.size(); ++i) { 4573 final WorkChain wc = wcs.get(i); 4574 noteStopWakeLocked(wc.getAttributionUid(), pid, wc, name, historyName, type, 4575 elapsedRealtime, uptime); 4576 } 4577 } 4578 } 4579 noteLongPartialWakelockStart(String name, String historyName, int uid)4580 public void noteLongPartialWakelockStart(String name, String historyName, int uid) { 4581 StatsLog.write_non_chained(StatsLog.LONG_PARTIAL_WAKELOCK_STATE_CHANGED, 4582 uid, null, name, historyName, 4583 StatsLog.LONG_PARTIAL_WAKELOCK_STATE_CHANGED__STATE__ON); 4584 4585 uid = mapUid(uid); 4586 noteLongPartialWakeLockStartInternal(name, historyName, uid); 4587 } 4588 noteLongPartialWakelockStartFromSource(String name, String historyName, WorkSource workSource)4589 public void noteLongPartialWakelockStartFromSource(String name, String historyName, 4590 WorkSource workSource) { 4591 final int N = workSource.size(); 4592 for (int i = 0; i < N; ++i) { 4593 final int uid = mapUid(workSource.get(i)); 4594 noteLongPartialWakeLockStartInternal(name, historyName, uid); 4595 StatsLog.write_non_chained(StatsLog.LONG_PARTIAL_WAKELOCK_STATE_CHANGED, 4596 workSource.get(i), workSource.getName(i), name, historyName, 4597 StatsLog.LONG_PARTIAL_WAKELOCK_STATE_CHANGED__STATE__ON); 4598 } 4599 4600 final ArrayList<WorkChain> workChains = workSource.getWorkChains(); 4601 if (workChains != null) { 4602 for (int i = 0; i < workChains.size(); ++i) { 4603 final WorkChain workChain = workChains.get(i); 4604 final int uid = workChain.getAttributionUid(); 4605 noteLongPartialWakeLockStartInternal(name, historyName, uid); 4606 4607 StatsLog.write(StatsLog.LONG_PARTIAL_WAKELOCK_STATE_CHANGED, 4608 workChain.getUids(), workChain.getTags(), name, historyName, 4609 StatsLog.LONG_PARTIAL_WAKELOCK_STATE_CHANGED__STATE__ON); 4610 } 4611 } 4612 } 4613 noteLongPartialWakeLockStartInternal(String name, String historyName, int uid)4614 private void noteLongPartialWakeLockStartInternal(String name, String historyName, int uid) { 4615 final long elapsedRealtime = mClocks.elapsedRealtime(); 4616 final long uptime = mClocks.uptimeMillis(); 4617 if (historyName == null) { 4618 historyName = name; 4619 } 4620 if (!mActiveEvents.updateState(HistoryItem.EVENT_LONG_WAKE_LOCK_START, historyName, uid, 4621 0)) { 4622 return; 4623 } 4624 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_LONG_WAKE_LOCK_START, 4625 historyName, uid); 4626 } 4627 noteLongPartialWakelockFinish(String name, String historyName, int uid)4628 public void noteLongPartialWakelockFinish(String name, String historyName, int uid) { 4629 StatsLog.write_non_chained(StatsLog.LONG_PARTIAL_WAKELOCK_STATE_CHANGED, uid, null, 4630 name, historyName, StatsLog.LONG_PARTIAL_WAKELOCK_STATE_CHANGED__STATE__OFF); 4631 4632 uid = mapUid(uid); 4633 noteLongPartialWakeLockFinishInternal(name, historyName, uid); 4634 } 4635 noteLongPartialWakelockFinishFromSource(String name, String historyName, WorkSource workSource)4636 public void noteLongPartialWakelockFinishFromSource(String name, String historyName, 4637 WorkSource workSource) { 4638 final int N = workSource.size(); 4639 for (int i = 0; i < N; ++i) { 4640 final int uid = mapUid(workSource.get(i)); 4641 noteLongPartialWakeLockFinishInternal(name, historyName, uid); 4642 StatsLog.write_non_chained(StatsLog.LONG_PARTIAL_WAKELOCK_STATE_CHANGED, 4643 workSource.get(i), workSource.getName(i), name, historyName, 4644 StatsLog.LONG_PARTIAL_WAKELOCK_STATE_CHANGED__STATE__OFF); 4645 } 4646 4647 final ArrayList<WorkChain> workChains = workSource.getWorkChains(); 4648 if (workChains != null) { 4649 for (int i = 0; i < workChains.size(); ++i) { 4650 final WorkChain workChain = workChains.get(i); 4651 final int uid = workChain.getAttributionUid(); 4652 noteLongPartialWakeLockFinishInternal(name, historyName, uid); 4653 StatsLog.write(StatsLog.LONG_PARTIAL_WAKELOCK_STATE_CHANGED, 4654 workChain.getUids(), workChain.getTags(), name, historyName, 4655 StatsLog.LONG_PARTIAL_WAKELOCK_STATE_CHANGED__STATE__OFF); 4656 } 4657 } 4658 } 4659 noteLongPartialWakeLockFinishInternal(String name, String historyName, int uid)4660 private void noteLongPartialWakeLockFinishInternal(String name, String historyName, int uid) { 4661 final long elapsedRealtime = mClocks.elapsedRealtime(); 4662 final long uptime = mClocks.uptimeMillis(); 4663 if (historyName == null) { 4664 historyName = name; 4665 } 4666 if (!mActiveEvents.updateState(HistoryItem.EVENT_LONG_WAKE_LOCK_FINISH, historyName, uid, 4667 0)) { 4668 return; 4669 } 4670 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_LONG_WAKE_LOCK_FINISH, 4671 historyName, uid); 4672 } 4673 aggregateLastWakeupUptimeLocked(long uptimeMs)4674 void aggregateLastWakeupUptimeLocked(long uptimeMs) { 4675 if (mLastWakeupReason != null) { 4676 long deltaUptime = uptimeMs - mLastWakeupUptimeMs; 4677 SamplingTimer timer = getWakeupReasonTimerLocked(mLastWakeupReason); 4678 timer.add(deltaUptime * 1000, 1); // time in in microseconds 4679 StatsLog.write(StatsLog.KERNEL_WAKEUP_REPORTED, mLastWakeupReason, 4680 /* duration_usec */ deltaUptime * 1000); 4681 mLastWakeupReason = null; 4682 } 4683 } 4684 noteWakeupReasonLocked(String reason)4685 public void noteWakeupReasonLocked(String reason) { 4686 final long elapsedRealtime = mClocks.elapsedRealtime(); 4687 final long uptime = mClocks.uptimeMillis(); 4688 if (DEBUG_HISTORY) Slog.v(TAG, "Wakeup reason \"" + reason +"\": " 4689 + Integer.toHexString(mHistoryCur.states)); 4690 aggregateLastWakeupUptimeLocked(uptime); 4691 mHistoryCur.wakeReasonTag = mHistoryCur.localWakeReasonTag; 4692 mHistoryCur.wakeReasonTag.string = reason; 4693 mHistoryCur.wakeReasonTag.uid = 0; 4694 mLastWakeupReason = reason; 4695 mLastWakeupUptimeMs = uptime; 4696 addHistoryRecordLocked(elapsedRealtime, uptime); 4697 } 4698 startAddingCpuLocked()4699 public boolean startAddingCpuLocked() { 4700 mExternalSync.cancelCpuSyncDueToWakelockChange(); 4701 return mOnBatteryInternal; 4702 } 4703 finishAddingCpuLocked(int totalUTime, int totalSTime, int statUserTime, int statSystemTime, int statIOWaitTime, int statIrqTime, int statSoftIrqTime, int statIdleTime)4704 public void finishAddingCpuLocked(int totalUTime, int totalSTime, int statUserTime, 4705 int statSystemTime, int statIOWaitTime, int statIrqTime, 4706 int statSoftIrqTime, int statIdleTime) { 4707 if (DEBUG) Slog.d(TAG, "Adding cpu: tuser=" + totalUTime + " tsys=" + totalSTime 4708 + " user=" + statUserTime + " sys=" + statSystemTime 4709 + " io=" + statIOWaitTime + " irq=" + statIrqTime 4710 + " sirq=" + statSoftIrqTime + " idle=" + statIdleTime); 4711 mCurStepCpuUserTime += totalUTime; 4712 mCurStepCpuSystemTime += totalSTime; 4713 mCurStepStatUserTime += statUserTime; 4714 mCurStepStatSystemTime += statSystemTime; 4715 mCurStepStatIOWaitTime += statIOWaitTime; 4716 mCurStepStatIrqTime += statIrqTime; 4717 mCurStepStatSoftIrqTime += statSoftIrqTime; 4718 mCurStepStatIdleTime += statIdleTime; 4719 } 4720 noteProcessDiedLocked(int uid, int pid)4721 public void noteProcessDiedLocked(int uid, int pid) { 4722 uid = mapUid(uid); 4723 Uid u = mUidStats.get(uid); 4724 if (u != null) { 4725 u.mPids.remove(pid); 4726 } 4727 } 4728 getProcessWakeTime(int uid, int pid, long realtime)4729 public long getProcessWakeTime(int uid, int pid, long realtime) { 4730 uid = mapUid(uid); 4731 Uid u = mUidStats.get(uid); 4732 if (u != null) { 4733 Uid.Pid p = u.mPids.get(pid); 4734 if (p != null) { 4735 return p.mWakeSumMs + (p.mWakeNesting > 0 ? (realtime - p.mWakeStartMs) : 0); 4736 } 4737 } 4738 return 0; 4739 } 4740 reportExcessiveCpuLocked(int uid, String proc, long overTime, long usedTime)4741 public void reportExcessiveCpuLocked(int uid, String proc, long overTime, long usedTime) { 4742 uid = mapUid(uid); 4743 Uid u = mUidStats.get(uid); 4744 if (u != null) { 4745 u.reportExcessiveCpuLocked(proc, overTime, usedTime); 4746 } 4747 } 4748 4749 int mSensorNesting; 4750 noteStartSensorLocked(int uid, int sensor)4751 public void noteStartSensorLocked(int uid, int sensor) { 4752 uid = mapUid(uid); 4753 final long elapsedRealtime = mClocks.elapsedRealtime(); 4754 final long uptime = mClocks.uptimeMillis(); 4755 if (mSensorNesting == 0) { 4756 mHistoryCur.states |= HistoryItem.STATE_SENSOR_ON_FLAG; 4757 if (DEBUG_HISTORY) Slog.v(TAG, "Start sensor to: " 4758 + Integer.toHexString(mHistoryCur.states)); 4759 addHistoryRecordLocked(elapsedRealtime, uptime); 4760 } 4761 mSensorNesting++; 4762 getUidStatsLocked(uid).noteStartSensor(sensor, elapsedRealtime); 4763 } 4764 noteStopSensorLocked(int uid, int sensor)4765 public void noteStopSensorLocked(int uid, int sensor) { 4766 uid = mapUid(uid); 4767 final long elapsedRealtime = mClocks.elapsedRealtime(); 4768 final long uptime = mClocks.uptimeMillis(); 4769 mSensorNesting--; 4770 if (mSensorNesting == 0) { 4771 mHistoryCur.states &= ~HistoryItem.STATE_SENSOR_ON_FLAG; 4772 if (DEBUG_HISTORY) Slog.v(TAG, "Stop sensor to: " 4773 + Integer.toHexString(mHistoryCur.states)); 4774 addHistoryRecordLocked(elapsedRealtime, uptime); 4775 } 4776 getUidStatsLocked(uid).noteStopSensor(sensor, elapsedRealtime); 4777 } 4778 4779 int mGpsNesting; 4780 noteGpsChangedLocked(WorkSource oldWs, WorkSource newWs)4781 public void noteGpsChangedLocked(WorkSource oldWs, WorkSource newWs) { 4782 for (int i = 0; i < newWs.size(); ++i) { 4783 noteStartGpsLocked(newWs.get(i), null); 4784 } 4785 4786 for (int i = 0; i < oldWs.size(); ++i) { 4787 noteStopGpsLocked((oldWs.get(i)), null); 4788 } 4789 4790 List<WorkChain>[] wcs = WorkSource.diffChains(oldWs, newWs); 4791 if (wcs != null) { 4792 if (wcs[0] != null) { 4793 final List<WorkChain> newChains = wcs[0]; 4794 for (int i = 0; i < newChains.size(); ++i) { 4795 noteStartGpsLocked(-1, newChains.get(i)); 4796 } 4797 } 4798 4799 if (wcs[1] != null) { 4800 final List<WorkChain> goneChains = wcs[1]; 4801 for (int i = 0; i < goneChains.size(); ++i) { 4802 noteStopGpsLocked(-1, goneChains.get(i)); 4803 } 4804 } 4805 } 4806 } 4807 noteStartGpsLocked(int uid, WorkChain workChain)4808 private void noteStartGpsLocked(int uid, WorkChain workChain) { 4809 uid = getAttributionUid(uid, workChain); 4810 final long elapsedRealtime = mClocks.elapsedRealtime(); 4811 final long uptime = mClocks.uptimeMillis(); 4812 if (mGpsNesting == 0) { 4813 mHistoryCur.states |= HistoryItem.STATE_GPS_ON_FLAG; 4814 if (DEBUG_HISTORY) Slog.v(TAG, "Start GPS to: " 4815 + Integer.toHexString(mHistoryCur.states)); 4816 addHistoryRecordLocked(elapsedRealtime, uptime); 4817 } 4818 mGpsNesting++; 4819 4820 if (workChain == null) { 4821 StatsLog.write_non_chained(StatsLog.GPS_SCAN_STATE_CHANGED, uid, null, 4822 StatsLog.GPS_SCAN_STATE_CHANGED__STATE__ON); 4823 } else { 4824 StatsLog.write(StatsLog.GPS_SCAN_STATE_CHANGED, 4825 workChain.getUids(), workChain.getTags(), 4826 StatsLog.GPS_SCAN_STATE_CHANGED__STATE__ON); 4827 } 4828 4829 getUidStatsLocked(uid).noteStartGps(elapsedRealtime); 4830 } 4831 noteStopGpsLocked(int uid, WorkChain workChain)4832 private void noteStopGpsLocked(int uid, WorkChain workChain) { 4833 uid = getAttributionUid(uid, workChain); 4834 final long elapsedRealtime = mClocks.elapsedRealtime(); 4835 final long uptime = mClocks.uptimeMillis(); 4836 mGpsNesting--; 4837 if (mGpsNesting == 0) { 4838 mHistoryCur.states &= ~HistoryItem.STATE_GPS_ON_FLAG; 4839 if (DEBUG_HISTORY) Slog.v(TAG, "Stop GPS to: " 4840 + Integer.toHexString(mHistoryCur.states)); 4841 addHistoryRecordLocked(elapsedRealtime, uptime); 4842 stopAllGpsSignalQualityTimersLocked(-1); 4843 mGpsSignalQualityBin = -1; 4844 } 4845 4846 if (workChain == null) { 4847 StatsLog.write_non_chained(StatsLog.GPS_SCAN_STATE_CHANGED, uid, null, 4848 StatsLog.GPS_SCAN_STATE_CHANGED__STATE__OFF); 4849 } else { 4850 StatsLog.write(StatsLog.GPS_SCAN_STATE_CHANGED, workChain.getUids(), 4851 workChain.getTags(), StatsLog.GPS_SCAN_STATE_CHANGED__STATE__OFF); 4852 } 4853 4854 getUidStatsLocked(uid).noteStopGps(elapsedRealtime); 4855 } 4856 noteGpsSignalQualityLocked(int signalLevel)4857 public void noteGpsSignalQualityLocked(int signalLevel) { 4858 if (mGpsNesting == 0) { 4859 return; 4860 } 4861 if (signalLevel < 0 || signalLevel >= GnssMetrics.NUM_GPS_SIGNAL_QUALITY_LEVELS) { 4862 stopAllGpsSignalQualityTimersLocked(-1); 4863 return; 4864 } 4865 final long elapsedRealtime = mClocks.elapsedRealtime(); 4866 final long uptime = mClocks.uptimeMillis(); 4867 if (mGpsSignalQualityBin != signalLevel) { 4868 if (mGpsSignalQualityBin >= 0) { 4869 mGpsSignalQualityTimer[mGpsSignalQualityBin].stopRunningLocked(elapsedRealtime); 4870 } 4871 if(!mGpsSignalQualityTimer[signalLevel].isRunningLocked()) { 4872 mGpsSignalQualityTimer[signalLevel].startRunningLocked(elapsedRealtime); 4873 } 4874 mHistoryCur.states2 = (mHistoryCur.states2&~HistoryItem.STATE2_GPS_SIGNAL_QUALITY_MASK) 4875 | (signalLevel << HistoryItem.STATE2_GPS_SIGNAL_QUALITY_SHIFT); 4876 addHistoryRecordLocked(elapsedRealtime, uptime); 4877 mGpsSignalQualityBin = signalLevel; 4878 } 4879 return; 4880 } 4881 4882 @GuardedBy("this") noteScreenStateLocked(int state)4883 public void noteScreenStateLocked(int state) { 4884 state = mPretendScreenOff ? Display.STATE_OFF : state; 4885 4886 // Battery stats relies on there being 4 states. To accommodate this, new states beyond the 4887 // original 4 are mapped to one of the originals. 4888 if (state > MAX_TRACKED_SCREEN_STATE) { 4889 switch (state) { 4890 case Display.STATE_VR: 4891 state = Display.STATE_ON; 4892 break; 4893 default: 4894 Slog.wtf(TAG, "Unknown screen state (not mapped): " + state); 4895 break; 4896 } 4897 } 4898 4899 if (mScreenState != state) { 4900 recordDailyStatsIfNeededLocked(true); 4901 final int oldState = mScreenState; 4902 mScreenState = state; 4903 if (DEBUG) Slog.v(TAG, "Screen state: oldState=" + Display.stateToString(oldState) 4904 + ", newState=" + Display.stateToString(state)); 4905 4906 if (state != Display.STATE_UNKNOWN) { 4907 int stepState = state-1; 4908 if ((stepState & STEP_LEVEL_MODE_SCREEN_STATE) == stepState) { 4909 mModStepMode |= (mCurStepMode & STEP_LEVEL_MODE_SCREEN_STATE) ^ stepState; 4910 mCurStepMode = (mCurStepMode & ~STEP_LEVEL_MODE_SCREEN_STATE) | stepState; 4911 } else { 4912 Slog.wtf(TAG, "Unexpected screen state: " + state); 4913 } 4914 } 4915 4916 final long elapsedRealtime = mClocks.elapsedRealtime(); 4917 final long uptime = mClocks.uptimeMillis(); 4918 4919 boolean updateHistory = false; 4920 if (isScreenDoze(state)) { 4921 mHistoryCur.states |= HistoryItem.STATE_SCREEN_DOZE_FLAG; 4922 mScreenDozeTimer.startRunningLocked(elapsedRealtime); 4923 updateHistory = true; 4924 } else if (isScreenDoze(oldState)) { 4925 mHistoryCur.states &= ~HistoryItem.STATE_SCREEN_DOZE_FLAG; 4926 mScreenDozeTimer.stopRunningLocked(elapsedRealtime); 4927 updateHistory = true; 4928 } 4929 if (isScreenOn(state)) { 4930 mHistoryCur.states |= HistoryItem.STATE_SCREEN_ON_FLAG; 4931 if (DEBUG_HISTORY) Slog.v(TAG, "Screen on to: " 4932 + Integer.toHexString(mHistoryCur.states)); 4933 mScreenOnTimer.startRunningLocked(elapsedRealtime); 4934 if (mScreenBrightnessBin >= 0) { 4935 mScreenBrightnessTimer[mScreenBrightnessBin].startRunningLocked(elapsedRealtime); 4936 } 4937 updateHistory = true; 4938 } else if (isScreenOn(oldState)) { 4939 mHistoryCur.states &= ~HistoryItem.STATE_SCREEN_ON_FLAG; 4940 if (DEBUG_HISTORY) Slog.v(TAG, "Screen off to: " 4941 + Integer.toHexString(mHistoryCur.states)); 4942 mScreenOnTimer.stopRunningLocked(elapsedRealtime); 4943 if (mScreenBrightnessBin >= 0) { 4944 mScreenBrightnessTimer[mScreenBrightnessBin].stopRunningLocked(elapsedRealtime); 4945 } 4946 updateHistory = true; 4947 } 4948 if (updateHistory) { 4949 if (DEBUG_HISTORY) Slog.v(TAG, "Screen state to: " 4950 + Display.stateToString(state)); 4951 addHistoryRecordLocked(elapsedRealtime, uptime); 4952 } 4953 mExternalSync.scheduleCpuSyncDueToScreenStateChange( 4954 mOnBatteryTimeBase.isRunning(), mOnBatteryScreenOffTimeBase.isRunning()); 4955 if (isScreenOn(state)) { 4956 updateTimeBasesLocked(mOnBatteryTimeBase.isRunning(), state, 4957 mClocks.uptimeMillis() * 1000, elapsedRealtime * 1000); 4958 // Fake a wake lock, so we consider the device waked as long as the screen is on. 4959 noteStartWakeLocked(-1, -1, null, "screen", null, WAKE_TYPE_PARTIAL, false, 4960 elapsedRealtime, uptime); 4961 } else if (isScreenOn(oldState)) { 4962 noteStopWakeLocked(-1, -1, null, "screen", "screen", WAKE_TYPE_PARTIAL, 4963 elapsedRealtime, uptime); 4964 updateTimeBasesLocked(mOnBatteryTimeBase.isRunning(), state, 4965 mClocks.uptimeMillis() * 1000, elapsedRealtime * 1000); 4966 } 4967 // Update discharge amounts. 4968 if (mOnBatteryInternal) { 4969 updateDischargeScreenLevelsLocked(oldState, state); 4970 } 4971 } 4972 } 4973 noteScreenBrightnessLocked(int brightness)4974 public void noteScreenBrightnessLocked(int brightness) { 4975 // Bin the brightness. 4976 int bin = brightness / (256/NUM_SCREEN_BRIGHTNESS_BINS); 4977 if (bin < 0) bin = 0; 4978 else if (bin >= NUM_SCREEN_BRIGHTNESS_BINS) bin = NUM_SCREEN_BRIGHTNESS_BINS-1; 4979 if (mScreenBrightnessBin != bin) { 4980 final long elapsedRealtime = mClocks.elapsedRealtime(); 4981 final long uptime = mClocks.uptimeMillis(); 4982 mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_BRIGHTNESS_MASK) 4983 | (bin << HistoryItem.STATE_BRIGHTNESS_SHIFT); 4984 if (DEBUG_HISTORY) Slog.v(TAG, "Screen brightness " + bin + " to: " 4985 + Integer.toHexString(mHistoryCur.states)); 4986 addHistoryRecordLocked(elapsedRealtime, uptime); 4987 if (mScreenState == Display.STATE_ON) { 4988 if (mScreenBrightnessBin >= 0) { 4989 mScreenBrightnessTimer[mScreenBrightnessBin].stopRunningLocked(elapsedRealtime); 4990 } 4991 mScreenBrightnessTimer[bin].startRunningLocked(elapsedRealtime); 4992 } 4993 mScreenBrightnessBin = bin; 4994 } 4995 } 4996 noteUserActivityLocked(int uid, int event)4997 public void noteUserActivityLocked(int uid, int event) { 4998 if (mOnBatteryInternal) { 4999 uid = mapUid(uid); 5000 getUidStatsLocked(uid).noteUserActivityLocked(event); 5001 } 5002 } 5003 noteWakeUpLocked(String reason, int reasonUid)5004 public void noteWakeUpLocked(String reason, int reasonUid) { 5005 final long elapsedRealtime = mClocks.elapsedRealtime(); 5006 final long uptime = mClocks.uptimeMillis(); 5007 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_SCREEN_WAKE_UP, 5008 reason, reasonUid); 5009 } 5010 noteInteractiveLocked(boolean interactive)5011 public void noteInteractiveLocked(boolean interactive) { 5012 if (mInteractive != interactive) { 5013 final long elapsedRealtime = mClocks.elapsedRealtime(); 5014 mInteractive = interactive; 5015 if (DEBUG) Slog.v(TAG, "Interactive: " + interactive); 5016 if (interactive) { 5017 mInteractiveTimer.startRunningLocked(elapsedRealtime); 5018 } else { 5019 mInteractiveTimer.stopRunningLocked(elapsedRealtime); 5020 } 5021 } 5022 } 5023 noteConnectivityChangedLocked(int type, String extra)5024 public void noteConnectivityChangedLocked(int type, String extra) { 5025 final long elapsedRealtime = mClocks.elapsedRealtime(); 5026 final long uptime = mClocks.uptimeMillis(); 5027 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_CONNECTIVITY_CHANGED, 5028 extra, type); 5029 mNumConnectivityChange++; 5030 } 5031 noteMobileRadioApWakeupLocked(final long elapsedRealtimeMillis, final long uptimeMillis, int uid)5032 private void noteMobileRadioApWakeupLocked(final long elapsedRealtimeMillis, 5033 final long uptimeMillis, int uid) { 5034 uid = mapUid(uid); 5035 addHistoryEventLocked(elapsedRealtimeMillis, uptimeMillis, HistoryItem.EVENT_WAKEUP_AP, "", 5036 uid); 5037 getUidStatsLocked(uid).noteMobileRadioApWakeupLocked(); 5038 } 5039 5040 /** 5041 * Updates the radio power state and returns true if an external stats collection should occur. 5042 */ noteMobileRadioPowerStateLocked(int powerState, long timestampNs, int uid)5043 public boolean noteMobileRadioPowerStateLocked(int powerState, long timestampNs, int uid) { 5044 final long elapsedRealtime = mClocks.elapsedRealtime(); 5045 final long uptime = mClocks.uptimeMillis(); 5046 if (mMobileRadioPowerState != powerState) { 5047 long realElapsedRealtimeMs; 5048 final boolean active = 5049 powerState == DataConnectionRealTimeInfo.DC_POWER_STATE_MEDIUM 5050 || powerState == DataConnectionRealTimeInfo.DC_POWER_STATE_HIGH; 5051 if (active) { 5052 if (uid > 0) { 5053 noteMobileRadioApWakeupLocked(elapsedRealtime, uptime, uid); 5054 } 5055 5056 mMobileRadioActiveStartTime = realElapsedRealtimeMs = timestampNs / (1000 * 1000); 5057 mHistoryCur.states |= HistoryItem.STATE_MOBILE_RADIO_ACTIVE_FLAG; 5058 } else { 5059 realElapsedRealtimeMs = timestampNs / (1000*1000); 5060 long lastUpdateTimeMs = mMobileRadioActiveStartTime; 5061 if (realElapsedRealtimeMs < lastUpdateTimeMs) { 5062 Slog.wtf(TAG, "Data connection inactive timestamp " + realElapsedRealtimeMs 5063 + " is before start time " + lastUpdateTimeMs); 5064 realElapsedRealtimeMs = elapsedRealtime; 5065 } else if (realElapsedRealtimeMs < elapsedRealtime) { 5066 mMobileRadioActiveAdjustedTime.addCountLocked(elapsedRealtime 5067 - realElapsedRealtimeMs); 5068 } 5069 mHistoryCur.states &= ~HistoryItem.STATE_MOBILE_RADIO_ACTIVE_FLAG; 5070 } 5071 if (DEBUG_HISTORY) Slog.v(TAG, "Mobile network active " + active + " to: " 5072 + Integer.toHexString(mHistoryCur.states)); 5073 addHistoryRecordLocked(elapsedRealtime, uptime); 5074 mMobileRadioPowerState = powerState; 5075 StatsLog.write_non_chained(StatsLog.MOBILE_RADIO_POWER_STATE_CHANGED, uid, null, 5076 powerState); 5077 if (active) { 5078 mMobileRadioActiveTimer.startRunningLocked(elapsedRealtime); 5079 mMobileRadioActivePerAppTimer.startRunningLocked(elapsedRealtime); 5080 } else { 5081 mMobileRadioActiveTimer.stopRunningLocked(realElapsedRealtimeMs); 5082 mMobileRadioActivePerAppTimer.stopRunningLocked(realElapsedRealtimeMs); 5083 // Tell the caller to collect radio network/power stats. 5084 return true; 5085 } 5086 } 5087 return false; 5088 } 5089 notePowerSaveModeLocked(boolean enabled)5090 public void notePowerSaveModeLocked(boolean enabled) { 5091 if (mPowerSaveModeEnabled != enabled) { 5092 int stepState = enabled ? STEP_LEVEL_MODE_POWER_SAVE : 0; 5093 mModStepMode |= (mCurStepMode&STEP_LEVEL_MODE_POWER_SAVE) ^ stepState; 5094 mCurStepMode = (mCurStepMode&~STEP_LEVEL_MODE_POWER_SAVE) | stepState; 5095 final long elapsedRealtime = mClocks.elapsedRealtime(); 5096 final long uptime = mClocks.uptimeMillis(); 5097 mPowerSaveModeEnabled = enabled; 5098 if (enabled) { 5099 mHistoryCur.states2 |= HistoryItem.STATE2_POWER_SAVE_FLAG; 5100 if (DEBUG_HISTORY) Slog.v(TAG, "Power save mode enabled to: " 5101 + Integer.toHexString(mHistoryCur.states2)); 5102 mPowerSaveModeEnabledTimer.startRunningLocked(elapsedRealtime); 5103 } else { 5104 mHistoryCur.states2 &= ~HistoryItem.STATE2_POWER_SAVE_FLAG; 5105 if (DEBUG_HISTORY) Slog.v(TAG, "Power save mode disabled to: " 5106 + Integer.toHexString(mHistoryCur.states2)); 5107 mPowerSaveModeEnabledTimer.stopRunningLocked(elapsedRealtime); 5108 } 5109 addHistoryRecordLocked(elapsedRealtime, uptime); 5110 StatsLog.write(StatsLog.BATTERY_SAVER_MODE_STATE_CHANGED, enabled ? 5111 StatsLog.BATTERY_SAVER_MODE_STATE_CHANGED__STATE__ON : 5112 StatsLog.BATTERY_SAVER_MODE_STATE_CHANGED__STATE__OFF); 5113 } 5114 } 5115 noteDeviceIdleModeLocked(final int mode, String activeReason, int activeUid)5116 public void noteDeviceIdleModeLocked(final int mode, String activeReason, int activeUid) { 5117 final long elapsedRealtime = mClocks.elapsedRealtime(); 5118 final long uptime = mClocks.uptimeMillis(); 5119 boolean nowIdling = mode == DEVICE_IDLE_MODE_DEEP; 5120 if (mDeviceIdling && !nowIdling && activeReason == null) { 5121 // We don't go out of general idling mode until explicitly taken out of 5122 // device idle through going active or significant motion. 5123 nowIdling = true; 5124 } 5125 boolean nowLightIdling = mode == DEVICE_IDLE_MODE_LIGHT; 5126 if (mDeviceLightIdling && !nowLightIdling && !nowIdling && activeReason == null) { 5127 // We don't go out of general light idling mode until explicitly taken out of 5128 // device idle through going active or significant motion. 5129 nowLightIdling = true; 5130 } 5131 if (activeReason != null && (mDeviceIdling || mDeviceLightIdling)) { 5132 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_ACTIVE, 5133 activeReason, activeUid); 5134 } 5135 if (mDeviceIdling != nowIdling || mDeviceLightIdling != nowLightIdling) { 5136 int statsmode; 5137 if (nowIdling) statsmode = DEVICE_IDLE_MODE_DEEP; 5138 else if (nowLightIdling) statsmode = DEVICE_IDLE_MODE_LIGHT; 5139 else statsmode = DEVICE_IDLE_MODE_OFF; 5140 StatsLog.write(StatsLog.DEVICE_IDLING_MODE_STATE_CHANGED, statsmode); 5141 } 5142 if (mDeviceIdling != nowIdling) { 5143 mDeviceIdling = nowIdling; 5144 int stepState = nowIdling ? STEP_LEVEL_MODE_DEVICE_IDLE : 0; 5145 mModStepMode |= (mCurStepMode&STEP_LEVEL_MODE_DEVICE_IDLE) ^ stepState; 5146 mCurStepMode = (mCurStepMode&~STEP_LEVEL_MODE_DEVICE_IDLE) | stepState; 5147 if (nowIdling) { 5148 mDeviceIdlingTimer.startRunningLocked(elapsedRealtime); 5149 } else { 5150 mDeviceIdlingTimer.stopRunningLocked(elapsedRealtime); 5151 } 5152 } 5153 if (mDeviceLightIdling != nowLightIdling) { 5154 mDeviceLightIdling = nowLightIdling; 5155 if (nowLightIdling) { 5156 mDeviceLightIdlingTimer.startRunningLocked(elapsedRealtime); 5157 } else { 5158 mDeviceLightIdlingTimer.stopRunningLocked(elapsedRealtime); 5159 } 5160 } 5161 if (mDeviceIdleMode != mode) { 5162 mHistoryCur.states2 = (mHistoryCur.states2 & ~HistoryItem.STATE2_DEVICE_IDLE_MASK) 5163 | (mode << HistoryItem.STATE2_DEVICE_IDLE_SHIFT); 5164 if (DEBUG_HISTORY) Slog.v(TAG, "Device idle mode changed to: " 5165 + Integer.toHexString(mHistoryCur.states2)); 5166 addHistoryRecordLocked(elapsedRealtime, uptime); 5167 long lastDuration = elapsedRealtime - mLastIdleTimeStart; 5168 mLastIdleTimeStart = elapsedRealtime; 5169 if (mDeviceIdleMode == DEVICE_IDLE_MODE_LIGHT) { 5170 if (lastDuration > mLongestLightIdleTime) { 5171 mLongestLightIdleTime = lastDuration; 5172 } 5173 mDeviceIdleModeLightTimer.stopRunningLocked(elapsedRealtime); 5174 } else if (mDeviceIdleMode == DEVICE_IDLE_MODE_DEEP) { 5175 if (lastDuration > mLongestFullIdleTime) { 5176 mLongestFullIdleTime = lastDuration; 5177 } 5178 mDeviceIdleModeFullTimer.stopRunningLocked(elapsedRealtime); 5179 } 5180 if (mode == DEVICE_IDLE_MODE_LIGHT) { 5181 mDeviceIdleModeLightTimer.startRunningLocked(elapsedRealtime); 5182 } else if (mode == DEVICE_IDLE_MODE_DEEP) { 5183 mDeviceIdleModeFullTimer.startRunningLocked(elapsedRealtime); 5184 } 5185 mDeviceIdleMode = mode; 5186 StatsLog.write(StatsLog.DEVICE_IDLE_MODE_STATE_CHANGED, mode); 5187 } 5188 } 5189 notePackageInstalledLocked(String pkgName, long versionCode)5190 public void notePackageInstalledLocked(String pkgName, long versionCode) { 5191 final long elapsedRealtime = mClocks.elapsedRealtime(); 5192 final long uptime = mClocks.uptimeMillis(); 5193 // XXX need to figure out what to do with long version codes. 5194 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_PACKAGE_INSTALLED, 5195 pkgName, (int)versionCode); 5196 PackageChange pc = new PackageChange(); 5197 pc.mPackageName = pkgName; 5198 pc.mUpdate = true; 5199 pc.mVersionCode = versionCode; 5200 addPackageChange(pc); 5201 } 5202 notePackageUninstalledLocked(String pkgName)5203 public void notePackageUninstalledLocked(String pkgName) { 5204 final long elapsedRealtime = mClocks.elapsedRealtime(); 5205 final long uptime = mClocks.uptimeMillis(); 5206 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_PACKAGE_UNINSTALLED, 5207 pkgName, 0); 5208 PackageChange pc = new PackageChange(); 5209 pc.mPackageName = pkgName; 5210 pc.mUpdate = true; 5211 addPackageChange(pc); 5212 } 5213 addPackageChange(PackageChange pc)5214 private void addPackageChange(PackageChange pc) { 5215 if (mDailyPackageChanges == null) { 5216 mDailyPackageChanges = new ArrayList<>(); 5217 } 5218 mDailyPackageChanges.add(pc); 5219 } 5220 stopAllGpsSignalQualityTimersLocked(int except)5221 void stopAllGpsSignalQualityTimersLocked(int except) { 5222 final long elapsedRealtime = mClocks.elapsedRealtime(); 5223 for (int i = 0; i < GnssMetrics.NUM_GPS_SIGNAL_QUALITY_LEVELS; i++) { 5224 if (i == except) { 5225 continue; 5226 } 5227 while (mGpsSignalQualityTimer[i].isRunningLocked()) { 5228 mGpsSignalQualityTimer[i].stopRunningLocked(elapsedRealtime); 5229 } 5230 } 5231 } 5232 notePhoneOnLocked()5233 public void notePhoneOnLocked() { 5234 if (!mPhoneOn) { 5235 final long elapsedRealtime = mClocks.elapsedRealtime(); 5236 final long uptime = mClocks.uptimeMillis(); 5237 mHistoryCur.states2 |= HistoryItem.STATE2_PHONE_IN_CALL_FLAG; 5238 if (DEBUG_HISTORY) Slog.v(TAG, "Phone on to: " 5239 + Integer.toHexString(mHistoryCur.states)); 5240 addHistoryRecordLocked(elapsedRealtime, uptime); 5241 mPhoneOn = true; 5242 mPhoneOnTimer.startRunningLocked(elapsedRealtime); 5243 } 5244 } 5245 notePhoneOffLocked()5246 public void notePhoneOffLocked() { 5247 if (mPhoneOn) { 5248 final long elapsedRealtime = mClocks.elapsedRealtime(); 5249 final long uptime = mClocks.uptimeMillis(); 5250 mHistoryCur.states2 &= ~HistoryItem.STATE2_PHONE_IN_CALL_FLAG; 5251 if (DEBUG_HISTORY) Slog.v(TAG, "Phone off to: " 5252 + Integer.toHexString(mHistoryCur.states)); 5253 addHistoryRecordLocked(elapsedRealtime, uptime); 5254 mPhoneOn = false; 5255 mPhoneOnTimer.stopRunningLocked(elapsedRealtime); 5256 } 5257 } 5258 registerUsbStateReceiver(Context context)5259 private void registerUsbStateReceiver(Context context) { 5260 final IntentFilter usbStateFilter = new IntentFilter(); 5261 usbStateFilter.addAction(UsbManager.ACTION_USB_STATE); 5262 context.registerReceiver(new BroadcastReceiver() { 5263 @Override 5264 public void onReceive(Context context, Intent intent) { 5265 final boolean state = intent.getBooleanExtra(UsbManager.USB_CONNECTED, false); 5266 synchronized (BatteryStatsImpl.this) { 5267 noteUsbConnectionStateLocked(state); 5268 } 5269 } 5270 }, usbStateFilter); 5271 synchronized (this) { 5272 if (mUsbDataState == USB_DATA_UNKNOWN) { 5273 final Intent usbState = context.registerReceiver(null, usbStateFilter); 5274 final boolean initState = usbState != null && usbState.getBooleanExtra( 5275 UsbManager.USB_CONNECTED, false); 5276 noteUsbConnectionStateLocked(initState); 5277 } 5278 } 5279 } 5280 noteUsbConnectionStateLocked(boolean connected)5281 private void noteUsbConnectionStateLocked(boolean connected) { 5282 int newState = connected ? USB_DATA_CONNECTED : USB_DATA_DISCONNECTED; 5283 if (mUsbDataState != newState) { 5284 mUsbDataState = newState; 5285 if (connected) { 5286 mHistoryCur.states2 |= HistoryItem.STATE2_USB_DATA_LINK_FLAG; 5287 } else { 5288 mHistoryCur.states2 &= ~HistoryItem.STATE2_USB_DATA_LINK_FLAG; 5289 } 5290 addHistoryRecordLocked(mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 5291 } 5292 } 5293 stopAllPhoneSignalStrengthTimersLocked(int except)5294 void stopAllPhoneSignalStrengthTimersLocked(int except) { 5295 final long elapsedRealtime = mClocks.elapsedRealtime(); 5296 for (int i = 0; i < SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) { 5297 if (i == except) { 5298 continue; 5299 } 5300 while (mPhoneSignalStrengthsTimer[i].isRunningLocked()) { 5301 mPhoneSignalStrengthsTimer[i].stopRunningLocked(elapsedRealtime); 5302 } 5303 } 5304 } 5305 fixPhoneServiceState(int state, int signalBin)5306 private int fixPhoneServiceState(int state, int signalBin) { 5307 if (mPhoneSimStateRaw == TelephonyManager.SIM_STATE_ABSENT) { 5308 // In this case we will always be STATE_OUT_OF_SERVICE, so need 5309 // to infer that we are scanning from other data. 5310 if (state == ServiceState.STATE_OUT_OF_SERVICE 5311 && signalBin > SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN) { 5312 state = ServiceState.STATE_IN_SERVICE; 5313 } 5314 } 5315 5316 return state; 5317 } 5318 updateAllPhoneStateLocked(int state, int simState, int strengthBin)5319 private void updateAllPhoneStateLocked(int state, int simState, int strengthBin) { 5320 boolean scanning = false; 5321 boolean newHistory = false; 5322 5323 mPhoneServiceStateRaw = state; 5324 mPhoneSimStateRaw = simState; 5325 mPhoneSignalStrengthBinRaw = strengthBin; 5326 5327 final long elapsedRealtime = mClocks.elapsedRealtime(); 5328 final long uptime = mClocks.uptimeMillis(); 5329 5330 if (simState == TelephonyManager.SIM_STATE_ABSENT) { 5331 // In this case we will always be STATE_OUT_OF_SERVICE, so need 5332 // to infer that we are scanning from other data. 5333 if (state == ServiceState.STATE_OUT_OF_SERVICE 5334 && strengthBin > SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN) { 5335 state = ServiceState.STATE_IN_SERVICE; 5336 } 5337 } 5338 5339 // If the phone is powered off, stop all timers. 5340 if (state == ServiceState.STATE_POWER_OFF) { 5341 strengthBin = -1; 5342 5343 // If we are in service, make sure the correct signal string timer is running. 5344 } else if (state == ServiceState.STATE_IN_SERVICE) { 5345 // Bin will be changed below. 5346 5347 // If we're out of service, we are in the lowest signal strength 5348 // bin and have the scanning bit set. 5349 } else if (state == ServiceState.STATE_OUT_OF_SERVICE) { 5350 scanning = true; 5351 strengthBin = SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN; 5352 if (!mPhoneSignalScanningTimer.isRunningLocked()) { 5353 mHistoryCur.states |= HistoryItem.STATE_PHONE_SCANNING_FLAG; 5354 newHistory = true; 5355 if (DEBUG_HISTORY) Slog.v(TAG, "Phone started scanning to: " 5356 + Integer.toHexString(mHistoryCur.states)); 5357 mPhoneSignalScanningTimer.startRunningLocked(elapsedRealtime); 5358 } 5359 } 5360 5361 if (!scanning) { 5362 // If we are no longer scanning, then stop the scanning timer. 5363 if (mPhoneSignalScanningTimer.isRunningLocked()) { 5364 mHistoryCur.states &= ~HistoryItem.STATE_PHONE_SCANNING_FLAG; 5365 if (DEBUG_HISTORY) Slog.v(TAG, "Phone stopped scanning to: " 5366 + Integer.toHexString(mHistoryCur.states)); 5367 newHistory = true; 5368 mPhoneSignalScanningTimer.stopRunningLocked(elapsedRealtime); 5369 } 5370 } 5371 5372 if (mPhoneServiceState != state) { 5373 mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_PHONE_STATE_MASK) 5374 | (state << HistoryItem.STATE_PHONE_STATE_SHIFT); 5375 if (DEBUG_HISTORY) Slog.v(TAG, "Phone state " + state + " to: " 5376 + Integer.toHexString(mHistoryCur.states)); 5377 newHistory = true; 5378 mPhoneServiceState = state; 5379 } 5380 5381 if (mPhoneSignalStrengthBin != strengthBin) { 5382 if (mPhoneSignalStrengthBin >= 0) { 5383 mPhoneSignalStrengthsTimer[mPhoneSignalStrengthBin].stopRunningLocked( 5384 elapsedRealtime); 5385 } 5386 if (strengthBin >= 0) { 5387 if (!mPhoneSignalStrengthsTimer[strengthBin].isRunningLocked()) { 5388 mPhoneSignalStrengthsTimer[strengthBin].startRunningLocked(elapsedRealtime); 5389 } 5390 mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_PHONE_SIGNAL_STRENGTH_MASK) 5391 | (strengthBin << HistoryItem.STATE_PHONE_SIGNAL_STRENGTH_SHIFT); 5392 if (DEBUG_HISTORY) Slog.v(TAG, "Signal strength " + strengthBin + " to: " 5393 + Integer.toHexString(mHistoryCur.states)); 5394 newHistory = true; 5395 StatsLog.write(StatsLog.PHONE_SIGNAL_STRENGTH_CHANGED, strengthBin); 5396 } else { 5397 stopAllPhoneSignalStrengthTimersLocked(-1); 5398 } 5399 mPhoneSignalStrengthBin = strengthBin; 5400 } 5401 5402 if (newHistory) { 5403 addHistoryRecordLocked(elapsedRealtime, uptime); 5404 } 5405 } 5406 5407 /** 5408 * Telephony stack updates the phone state. 5409 * @param state phone state from ServiceState.getState() 5410 */ notePhoneStateLocked(int state, int simState)5411 public void notePhoneStateLocked(int state, int simState) { 5412 updateAllPhoneStateLocked(state, simState, mPhoneSignalStrengthBinRaw); 5413 } 5414 notePhoneSignalStrengthLocked(SignalStrength signalStrength)5415 public void notePhoneSignalStrengthLocked(SignalStrength signalStrength) { 5416 // Bin the strength. 5417 int bin = signalStrength.getLevel(); 5418 updateAllPhoneStateLocked(mPhoneServiceStateRaw, mPhoneSimStateRaw, bin); 5419 } 5420 notePhoneDataConnectionStateLocked(int dataType, boolean hasData)5421 public void notePhoneDataConnectionStateLocked(int dataType, boolean hasData) { 5422 // BatteryStats uses 0 to represent no network type. 5423 // Telephony does not have a concept of no network type, and uses 0 to represent unknown. 5424 // Unknown is included in DATA_CONNECTION_OTHER. 5425 int bin = DATA_CONNECTION_NONE; 5426 if (hasData) { 5427 if (dataType > 0 && dataType <= TelephonyManager.MAX_NETWORK_TYPE) { 5428 bin = dataType; 5429 } else { 5430 bin = DATA_CONNECTION_OTHER; 5431 } 5432 } 5433 if (DEBUG) Log.i(TAG, "Phone Data Connection -> " + dataType + " = " + hasData); 5434 if (mPhoneDataConnectionType != bin) { 5435 final long elapsedRealtime = mClocks.elapsedRealtime(); 5436 final long uptime = mClocks.uptimeMillis(); 5437 mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_DATA_CONNECTION_MASK) 5438 | (bin << HistoryItem.STATE_DATA_CONNECTION_SHIFT); 5439 if (DEBUG_HISTORY) Slog.v(TAG, "Data connection " + bin + " to: " 5440 + Integer.toHexString(mHistoryCur.states)); 5441 addHistoryRecordLocked(elapsedRealtime, uptime); 5442 if (mPhoneDataConnectionType >= 0) { 5443 mPhoneDataConnectionsTimer[mPhoneDataConnectionType].stopRunningLocked( 5444 elapsedRealtime); 5445 } 5446 mPhoneDataConnectionType = bin; 5447 mPhoneDataConnectionsTimer[bin].startRunningLocked(elapsedRealtime); 5448 } 5449 } 5450 noteWifiOnLocked()5451 public void noteWifiOnLocked() { 5452 if (!mWifiOn) { 5453 final long elapsedRealtime = mClocks.elapsedRealtime(); 5454 final long uptime = mClocks.uptimeMillis(); 5455 mHistoryCur.states2 |= HistoryItem.STATE2_WIFI_ON_FLAG; 5456 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI on to: " 5457 + Integer.toHexString(mHistoryCur.states)); 5458 addHistoryRecordLocked(elapsedRealtime, uptime); 5459 mWifiOn = true; 5460 mWifiOnTimer.startRunningLocked(elapsedRealtime); 5461 scheduleSyncExternalStatsLocked("wifi-off", ExternalStatsSync.UPDATE_WIFI); 5462 } 5463 } 5464 noteWifiOffLocked()5465 public void noteWifiOffLocked() { 5466 final long elapsedRealtime = mClocks.elapsedRealtime(); 5467 final long uptime = mClocks.uptimeMillis(); 5468 if (mWifiOn) { 5469 mHistoryCur.states2 &= ~HistoryItem.STATE2_WIFI_ON_FLAG; 5470 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI off to: " 5471 + Integer.toHexString(mHistoryCur.states)); 5472 addHistoryRecordLocked(elapsedRealtime, uptime); 5473 mWifiOn = false; 5474 mWifiOnTimer.stopRunningLocked(elapsedRealtime); 5475 scheduleSyncExternalStatsLocked("wifi-on", ExternalStatsSync.UPDATE_WIFI); 5476 } 5477 } 5478 noteAudioOnLocked(int uid)5479 public void noteAudioOnLocked(int uid) { 5480 uid = mapUid(uid); 5481 final long elapsedRealtime = mClocks.elapsedRealtime(); 5482 final long uptime = mClocks.uptimeMillis(); 5483 if (mAudioOnNesting == 0) { 5484 mHistoryCur.states |= HistoryItem.STATE_AUDIO_ON_FLAG; 5485 if (DEBUG_HISTORY) Slog.v(TAG, "Audio on to: " 5486 + Integer.toHexString(mHistoryCur.states)); 5487 addHistoryRecordLocked(elapsedRealtime, uptime); 5488 mAudioOnTimer.startRunningLocked(elapsedRealtime); 5489 } 5490 mAudioOnNesting++; 5491 getUidStatsLocked(uid).noteAudioTurnedOnLocked(elapsedRealtime); 5492 } 5493 noteAudioOffLocked(int uid)5494 public void noteAudioOffLocked(int uid) { 5495 if (mAudioOnNesting == 0) { 5496 return; 5497 } 5498 uid = mapUid(uid); 5499 final long elapsedRealtime = mClocks.elapsedRealtime(); 5500 final long uptime = mClocks.uptimeMillis(); 5501 if (--mAudioOnNesting == 0) { 5502 mHistoryCur.states &= ~HistoryItem.STATE_AUDIO_ON_FLAG; 5503 if (DEBUG_HISTORY) Slog.v(TAG, "Audio off to: " 5504 + Integer.toHexString(mHistoryCur.states)); 5505 addHistoryRecordLocked(elapsedRealtime, uptime); 5506 mAudioOnTimer.stopRunningLocked(elapsedRealtime); 5507 } 5508 getUidStatsLocked(uid).noteAudioTurnedOffLocked(elapsedRealtime); 5509 } 5510 noteVideoOnLocked(int uid)5511 public void noteVideoOnLocked(int uid) { 5512 uid = mapUid(uid); 5513 final long elapsedRealtime = mClocks.elapsedRealtime(); 5514 final long uptime = mClocks.uptimeMillis(); 5515 if (mVideoOnNesting == 0) { 5516 mHistoryCur.states2 |= HistoryItem.STATE2_VIDEO_ON_FLAG; 5517 if (DEBUG_HISTORY) Slog.v(TAG, "Video on to: " 5518 + Integer.toHexString(mHistoryCur.states)); 5519 addHistoryRecordLocked(elapsedRealtime, uptime); 5520 mVideoOnTimer.startRunningLocked(elapsedRealtime); 5521 } 5522 mVideoOnNesting++; 5523 getUidStatsLocked(uid).noteVideoTurnedOnLocked(elapsedRealtime); 5524 } 5525 noteVideoOffLocked(int uid)5526 public void noteVideoOffLocked(int uid) { 5527 if (mVideoOnNesting == 0) { 5528 return; 5529 } 5530 uid = mapUid(uid); 5531 final long elapsedRealtime = mClocks.elapsedRealtime(); 5532 final long uptime = mClocks.uptimeMillis(); 5533 if (--mVideoOnNesting == 0) { 5534 mHistoryCur.states2 &= ~HistoryItem.STATE2_VIDEO_ON_FLAG; 5535 if (DEBUG_HISTORY) Slog.v(TAG, "Video off to: " 5536 + Integer.toHexString(mHistoryCur.states)); 5537 addHistoryRecordLocked(elapsedRealtime, uptime); 5538 mVideoOnTimer.stopRunningLocked(elapsedRealtime); 5539 } 5540 getUidStatsLocked(uid).noteVideoTurnedOffLocked(elapsedRealtime); 5541 } 5542 noteResetAudioLocked()5543 public void noteResetAudioLocked() { 5544 if (mAudioOnNesting > 0) { 5545 final long elapsedRealtime = mClocks.elapsedRealtime(); 5546 final long uptime = mClocks.uptimeMillis(); 5547 mAudioOnNesting = 0; 5548 mHistoryCur.states &= ~HistoryItem.STATE_AUDIO_ON_FLAG; 5549 if (DEBUG_HISTORY) Slog.v(TAG, "Audio off to: " 5550 + Integer.toHexString(mHistoryCur.states)); 5551 addHistoryRecordLocked(elapsedRealtime, uptime); 5552 mAudioOnTimer.stopAllRunningLocked(elapsedRealtime); 5553 for (int i=0; i<mUidStats.size(); i++) { 5554 BatteryStatsImpl.Uid uid = mUidStats.valueAt(i); 5555 uid.noteResetAudioLocked(elapsedRealtime); 5556 } 5557 } 5558 } 5559 noteResetVideoLocked()5560 public void noteResetVideoLocked() { 5561 if (mVideoOnNesting > 0) { 5562 final long elapsedRealtime = mClocks.elapsedRealtime(); 5563 final long uptime = mClocks.uptimeMillis(); 5564 mAudioOnNesting = 0; 5565 mHistoryCur.states2 &= ~HistoryItem.STATE2_VIDEO_ON_FLAG; 5566 if (DEBUG_HISTORY) Slog.v(TAG, "Video off to: " 5567 + Integer.toHexString(mHistoryCur.states)); 5568 addHistoryRecordLocked(elapsedRealtime, uptime); 5569 mVideoOnTimer.stopAllRunningLocked(elapsedRealtime); 5570 for (int i=0; i<mUidStats.size(); i++) { 5571 BatteryStatsImpl.Uid uid = mUidStats.valueAt(i); 5572 uid.noteResetVideoLocked(elapsedRealtime); 5573 } 5574 } 5575 } 5576 noteActivityResumedLocked(int uid)5577 public void noteActivityResumedLocked(int uid) { 5578 uid = mapUid(uid); 5579 getUidStatsLocked(uid).noteActivityResumedLocked(mClocks.elapsedRealtime()); 5580 } 5581 noteActivityPausedLocked(int uid)5582 public void noteActivityPausedLocked(int uid) { 5583 uid = mapUid(uid); 5584 getUidStatsLocked(uid).noteActivityPausedLocked(mClocks.elapsedRealtime()); 5585 } 5586 noteVibratorOnLocked(int uid, long durationMillis)5587 public void noteVibratorOnLocked(int uid, long durationMillis) { 5588 uid = mapUid(uid); 5589 getUidStatsLocked(uid).noteVibratorOnLocked(durationMillis); 5590 } 5591 noteVibratorOffLocked(int uid)5592 public void noteVibratorOffLocked(int uid) { 5593 uid = mapUid(uid); 5594 getUidStatsLocked(uid).noteVibratorOffLocked(); 5595 } 5596 noteFlashlightOnLocked(int uid)5597 public void noteFlashlightOnLocked(int uid) { 5598 uid = mapUid(uid); 5599 final long elapsedRealtime = mClocks.elapsedRealtime(); 5600 final long uptime = mClocks.uptimeMillis(); 5601 if (mFlashlightOnNesting++ == 0) { 5602 mHistoryCur.states2 |= HistoryItem.STATE2_FLASHLIGHT_FLAG; 5603 if (DEBUG_HISTORY) Slog.v(TAG, "Flashlight on to: " 5604 + Integer.toHexString(mHistoryCur.states2)); 5605 addHistoryRecordLocked(elapsedRealtime, uptime); 5606 mFlashlightOnTimer.startRunningLocked(elapsedRealtime); 5607 } 5608 getUidStatsLocked(uid).noteFlashlightTurnedOnLocked(elapsedRealtime); 5609 } 5610 noteFlashlightOffLocked(int uid)5611 public void noteFlashlightOffLocked(int uid) { 5612 if (mFlashlightOnNesting == 0) { 5613 return; 5614 } 5615 uid = mapUid(uid); 5616 final long elapsedRealtime = mClocks.elapsedRealtime(); 5617 final long uptime = mClocks.uptimeMillis(); 5618 if (--mFlashlightOnNesting == 0) { 5619 mHistoryCur.states2 &= ~HistoryItem.STATE2_FLASHLIGHT_FLAG; 5620 if (DEBUG_HISTORY) Slog.v(TAG, "Flashlight off to: " 5621 + Integer.toHexString(mHistoryCur.states2)); 5622 addHistoryRecordLocked(elapsedRealtime, uptime); 5623 mFlashlightOnTimer.stopRunningLocked(elapsedRealtime); 5624 } 5625 getUidStatsLocked(uid).noteFlashlightTurnedOffLocked(elapsedRealtime); 5626 } 5627 noteCameraOnLocked(int uid)5628 public void noteCameraOnLocked(int uid) { 5629 uid = mapUid(uid); 5630 final long elapsedRealtime = mClocks.elapsedRealtime(); 5631 final long uptime = mClocks.uptimeMillis(); 5632 if (mCameraOnNesting++ == 0) { 5633 mHistoryCur.states2 |= HistoryItem.STATE2_CAMERA_FLAG; 5634 if (DEBUG_HISTORY) Slog.v(TAG, "Camera on to: " 5635 + Integer.toHexString(mHistoryCur.states2)); 5636 addHistoryRecordLocked(elapsedRealtime, uptime); 5637 mCameraOnTimer.startRunningLocked(elapsedRealtime); 5638 } 5639 getUidStatsLocked(uid).noteCameraTurnedOnLocked(elapsedRealtime); 5640 } 5641 noteCameraOffLocked(int uid)5642 public void noteCameraOffLocked(int uid) { 5643 if (mCameraOnNesting == 0) { 5644 return; 5645 } 5646 uid = mapUid(uid); 5647 final long elapsedRealtime = mClocks.elapsedRealtime(); 5648 final long uptime = mClocks.uptimeMillis(); 5649 if (--mCameraOnNesting == 0) { 5650 mHistoryCur.states2 &= ~HistoryItem.STATE2_CAMERA_FLAG; 5651 if (DEBUG_HISTORY) Slog.v(TAG, "Camera off to: " 5652 + Integer.toHexString(mHistoryCur.states2)); 5653 addHistoryRecordLocked(elapsedRealtime, uptime); 5654 mCameraOnTimer.stopRunningLocked(elapsedRealtime); 5655 } 5656 getUidStatsLocked(uid).noteCameraTurnedOffLocked(elapsedRealtime); 5657 } 5658 noteResetCameraLocked()5659 public void noteResetCameraLocked() { 5660 if (mCameraOnNesting > 0) { 5661 final long elapsedRealtime = mClocks.elapsedRealtime(); 5662 final long uptime = mClocks.uptimeMillis(); 5663 mCameraOnNesting = 0; 5664 mHistoryCur.states2 &= ~HistoryItem.STATE2_CAMERA_FLAG; 5665 if (DEBUG_HISTORY) Slog.v(TAG, "Camera off to: " 5666 + Integer.toHexString(mHistoryCur.states2)); 5667 addHistoryRecordLocked(elapsedRealtime, uptime); 5668 mCameraOnTimer.stopAllRunningLocked(elapsedRealtime); 5669 for (int i=0; i<mUidStats.size(); i++) { 5670 BatteryStatsImpl.Uid uid = mUidStats.valueAt(i); 5671 uid.noteResetCameraLocked(elapsedRealtime); 5672 } 5673 } 5674 } 5675 noteResetFlashlightLocked()5676 public void noteResetFlashlightLocked() { 5677 if (mFlashlightOnNesting > 0) { 5678 final long elapsedRealtime = mClocks.elapsedRealtime(); 5679 final long uptime = mClocks.uptimeMillis(); 5680 mFlashlightOnNesting = 0; 5681 mHistoryCur.states2 &= ~HistoryItem.STATE2_FLASHLIGHT_FLAG; 5682 if (DEBUG_HISTORY) Slog.v(TAG, "Flashlight off to: " 5683 + Integer.toHexString(mHistoryCur.states2)); 5684 addHistoryRecordLocked(elapsedRealtime, uptime); 5685 mFlashlightOnTimer.stopAllRunningLocked(elapsedRealtime); 5686 for (int i=0; i<mUidStats.size(); i++) { 5687 BatteryStatsImpl.Uid uid = mUidStats.valueAt(i); 5688 uid.noteResetFlashlightLocked(elapsedRealtime); 5689 } 5690 } 5691 } 5692 noteBluetoothScanStartedLocked(WorkChain workChain, int uid, boolean isUnoptimized)5693 private void noteBluetoothScanStartedLocked(WorkChain workChain, int uid, 5694 boolean isUnoptimized) { 5695 uid = getAttributionUid(uid, workChain); 5696 final long elapsedRealtime = mClocks.elapsedRealtime(); 5697 final long uptime = mClocks.uptimeMillis(); 5698 if (mBluetoothScanNesting == 0) { 5699 mHistoryCur.states2 |= HistoryItem.STATE2_BLUETOOTH_SCAN_FLAG; 5700 if (DEBUG_HISTORY) Slog.v(TAG, "BLE scan started for: " 5701 + Integer.toHexString(mHistoryCur.states2)); 5702 addHistoryRecordLocked(elapsedRealtime, uptime); 5703 mBluetoothScanTimer.startRunningLocked(elapsedRealtime); 5704 } 5705 mBluetoothScanNesting++; 5706 getUidStatsLocked(uid).noteBluetoothScanStartedLocked(elapsedRealtime, isUnoptimized); 5707 } 5708 noteBluetoothScanStartedFromSourceLocked(WorkSource ws, boolean isUnoptimized)5709 public void noteBluetoothScanStartedFromSourceLocked(WorkSource ws, boolean isUnoptimized) { 5710 final int N = ws.size(); 5711 for (int i = 0; i < N; i++) { 5712 noteBluetoothScanStartedLocked(null, ws.get(i), isUnoptimized); 5713 } 5714 5715 final List<WorkChain> workChains = ws.getWorkChains(); 5716 if (workChains != null) { 5717 for (int i = 0; i < workChains.size(); ++i) { 5718 noteBluetoothScanStartedLocked(workChains.get(i), -1, isUnoptimized); 5719 } 5720 } 5721 } 5722 noteBluetoothScanStoppedLocked(WorkChain workChain, int uid, boolean isUnoptimized)5723 private void noteBluetoothScanStoppedLocked(WorkChain workChain, int uid, 5724 boolean isUnoptimized) { 5725 uid = getAttributionUid(uid, workChain); 5726 final long elapsedRealtime = mClocks.elapsedRealtime(); 5727 final long uptime = mClocks.uptimeMillis(); 5728 mBluetoothScanNesting--; 5729 if (mBluetoothScanNesting == 0) { 5730 mHistoryCur.states2 &= ~HistoryItem.STATE2_BLUETOOTH_SCAN_FLAG; 5731 if (DEBUG_HISTORY) Slog.v(TAG, "BLE scan stopped for: " 5732 + Integer.toHexString(mHistoryCur.states2)); 5733 addHistoryRecordLocked(elapsedRealtime, uptime); 5734 mBluetoothScanTimer.stopRunningLocked(elapsedRealtime); 5735 } 5736 getUidStatsLocked(uid).noteBluetoothScanStoppedLocked(elapsedRealtime, isUnoptimized); 5737 } 5738 getAttributionUid(int uid, WorkChain workChain)5739 private int getAttributionUid(int uid, WorkChain workChain) { 5740 if (workChain != null) { 5741 return mapUid(workChain.getAttributionUid()); 5742 } 5743 5744 return mapUid(uid); 5745 } 5746 noteBluetoothScanStoppedFromSourceLocked(WorkSource ws, boolean isUnoptimized)5747 public void noteBluetoothScanStoppedFromSourceLocked(WorkSource ws, boolean isUnoptimized) { 5748 final int N = ws.size(); 5749 for (int i = 0; i < N; i++) { 5750 noteBluetoothScanStoppedLocked(null, ws.get(i), isUnoptimized); 5751 } 5752 5753 final List<WorkChain> workChains = ws.getWorkChains(); 5754 if (workChains != null) { 5755 for (int i = 0; i < workChains.size(); ++i) { 5756 noteBluetoothScanStoppedLocked(workChains.get(i), -1, isUnoptimized); 5757 } 5758 } 5759 } 5760 noteResetBluetoothScanLocked()5761 public void noteResetBluetoothScanLocked() { 5762 if (mBluetoothScanNesting > 0) { 5763 final long elapsedRealtime = mClocks.elapsedRealtime(); 5764 final long uptime = mClocks.uptimeMillis(); 5765 mBluetoothScanNesting = 0; 5766 mHistoryCur.states2 &= ~HistoryItem.STATE2_BLUETOOTH_SCAN_FLAG; 5767 if (DEBUG_HISTORY) Slog.v(TAG, "BLE can stopped for: " 5768 + Integer.toHexString(mHistoryCur.states2)); 5769 addHistoryRecordLocked(elapsedRealtime, uptime); 5770 mBluetoothScanTimer.stopAllRunningLocked(elapsedRealtime); 5771 for (int i=0; i<mUidStats.size(); i++) { 5772 BatteryStatsImpl.Uid uid = mUidStats.valueAt(i); 5773 uid.noteResetBluetoothScanLocked(elapsedRealtime); 5774 } 5775 } 5776 } 5777 noteBluetoothScanResultsFromSourceLocked(WorkSource ws, int numNewResults)5778 public void noteBluetoothScanResultsFromSourceLocked(WorkSource ws, int numNewResults) { 5779 final int N = ws.size(); 5780 for (int i = 0; i < N; i++) { 5781 int uid = mapUid(ws.get(i)); 5782 getUidStatsLocked(uid).noteBluetoothScanResultsLocked(numNewResults); 5783 StatsLog.write_non_chained(StatsLog.BLE_SCAN_RESULT_RECEIVED, ws.get(i), ws.getName(i), 5784 numNewResults); 5785 } 5786 5787 final List<WorkChain> workChains = ws.getWorkChains(); 5788 if (workChains != null) { 5789 for (int i = 0; i < workChains.size(); ++i) { 5790 final WorkChain wc = workChains.get(i); 5791 int uid = mapUid(wc.getAttributionUid()); 5792 getUidStatsLocked(uid).noteBluetoothScanResultsLocked(numNewResults); 5793 StatsLog.write(StatsLog.BLE_SCAN_RESULT_RECEIVED, 5794 wc.getUids(), wc.getTags(), numNewResults); 5795 } 5796 } 5797 } 5798 noteWifiRadioApWakeupLocked(final long elapsedRealtimeMillis, final long uptimeMillis, int uid)5799 private void noteWifiRadioApWakeupLocked(final long elapsedRealtimeMillis, 5800 final long uptimeMillis, int uid) { 5801 uid = mapUid(uid); 5802 addHistoryEventLocked(elapsedRealtimeMillis, uptimeMillis, HistoryItem.EVENT_WAKEUP_AP, "", 5803 uid); 5804 getUidStatsLocked(uid).noteWifiRadioApWakeupLocked(); 5805 } 5806 noteWifiRadioPowerState(int powerState, long timestampNs, int uid)5807 public void noteWifiRadioPowerState(int powerState, long timestampNs, int uid) { 5808 final long elapsedRealtime = mClocks.elapsedRealtime(); 5809 final long uptime = mClocks.uptimeMillis(); 5810 if (mWifiRadioPowerState != powerState) { 5811 final boolean active = 5812 powerState == DataConnectionRealTimeInfo.DC_POWER_STATE_MEDIUM 5813 || powerState == DataConnectionRealTimeInfo.DC_POWER_STATE_HIGH; 5814 if (active) { 5815 if (uid > 0) { 5816 noteWifiRadioApWakeupLocked(elapsedRealtime, uptime, uid); 5817 } 5818 mHistoryCur.states |= HistoryItem.STATE_WIFI_RADIO_ACTIVE_FLAG; 5819 mWifiActiveTimer.startRunningLocked(elapsedRealtime); 5820 } else { 5821 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_RADIO_ACTIVE_FLAG; 5822 mWifiActiveTimer.stopRunningLocked( 5823 timestampNs / (1000 * 1000)); 5824 } 5825 if (DEBUG_HISTORY) Slog.v(TAG, "Wifi network active " + active + " to: " 5826 + Integer.toHexString(mHistoryCur.states)); 5827 addHistoryRecordLocked(elapsedRealtime, uptime); 5828 mWifiRadioPowerState = powerState; 5829 StatsLog.write_non_chained(StatsLog.WIFI_RADIO_POWER_STATE_CHANGED, uid, null, 5830 powerState); 5831 } 5832 } 5833 noteWifiRunningLocked(WorkSource ws)5834 public void noteWifiRunningLocked(WorkSource ws) { 5835 if (!mGlobalWifiRunning) { 5836 final long elapsedRealtime = mClocks.elapsedRealtime(); 5837 final long uptime = mClocks.uptimeMillis(); 5838 mHistoryCur.states2 |= HistoryItem.STATE2_WIFI_RUNNING_FLAG; 5839 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI running to: " 5840 + Integer.toHexString(mHistoryCur.states)); 5841 addHistoryRecordLocked(elapsedRealtime, uptime); 5842 mGlobalWifiRunning = true; 5843 mGlobalWifiRunningTimer.startRunningLocked(elapsedRealtime); 5844 int N = ws.size(); 5845 for (int i=0; i<N; i++) { 5846 int uid = mapUid(ws.get(i)); 5847 getUidStatsLocked(uid).noteWifiRunningLocked(elapsedRealtime); 5848 } 5849 5850 List<WorkChain> workChains = ws.getWorkChains(); 5851 if (workChains != null) { 5852 for (int i = 0; i < workChains.size(); ++i) { 5853 int uid = mapUid(workChains.get(i).getAttributionUid()); 5854 getUidStatsLocked(uid).noteWifiRunningLocked(elapsedRealtime); 5855 } 5856 } 5857 5858 scheduleSyncExternalStatsLocked("wifi-running", ExternalStatsSync.UPDATE_WIFI); 5859 } else { 5860 Log.w(TAG, "noteWifiRunningLocked -- called while WIFI running"); 5861 } 5862 } 5863 noteWifiRunningChangedLocked(WorkSource oldWs, WorkSource newWs)5864 public void noteWifiRunningChangedLocked(WorkSource oldWs, WorkSource newWs) { 5865 if (mGlobalWifiRunning) { 5866 final long elapsedRealtime = mClocks.elapsedRealtime(); 5867 int N = oldWs.size(); 5868 for (int i=0; i<N; i++) { 5869 int uid = mapUid(oldWs.get(i)); 5870 getUidStatsLocked(uid).noteWifiStoppedLocked(elapsedRealtime); 5871 } 5872 5873 List<WorkChain> workChains = oldWs.getWorkChains(); 5874 if (workChains != null) { 5875 for (int i = 0; i < workChains.size(); ++i) { 5876 int uid = mapUid(workChains.get(i).getAttributionUid()); 5877 getUidStatsLocked(uid).noteWifiStoppedLocked(elapsedRealtime); 5878 } 5879 } 5880 5881 N = newWs.size(); 5882 for (int i=0; i<N; i++) { 5883 int uid = mapUid(newWs.get(i)); 5884 getUidStatsLocked(uid).noteWifiRunningLocked(elapsedRealtime); 5885 } 5886 5887 workChains = newWs.getWorkChains(); 5888 if (workChains != null) { 5889 for (int i = 0; i < workChains.size(); ++i) { 5890 int uid = mapUid(workChains.get(i).getAttributionUid()); 5891 getUidStatsLocked(uid).noteWifiRunningLocked(elapsedRealtime); 5892 } 5893 } 5894 } else { 5895 Log.w(TAG, "noteWifiRunningChangedLocked -- called while WIFI not running"); 5896 } 5897 } 5898 noteWifiStoppedLocked(WorkSource ws)5899 public void noteWifiStoppedLocked(WorkSource ws) { 5900 if (mGlobalWifiRunning) { 5901 final long elapsedRealtime = mClocks.elapsedRealtime(); 5902 final long uptime = mClocks.uptimeMillis(); 5903 mHistoryCur.states2 &= ~HistoryItem.STATE2_WIFI_RUNNING_FLAG; 5904 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI stopped to: " 5905 + Integer.toHexString(mHistoryCur.states)); 5906 addHistoryRecordLocked(elapsedRealtime, uptime); 5907 mGlobalWifiRunning = false; 5908 mGlobalWifiRunningTimer.stopRunningLocked(elapsedRealtime); 5909 int N = ws.size(); 5910 for (int i=0; i<N; i++) { 5911 int uid = mapUid(ws.get(i)); 5912 getUidStatsLocked(uid).noteWifiStoppedLocked(elapsedRealtime); 5913 } 5914 5915 List<WorkChain> workChains = ws.getWorkChains(); 5916 if (workChains != null) { 5917 for (int i = 0; i < workChains.size(); ++i) { 5918 int uid = mapUid(workChains.get(i).getAttributionUid()); 5919 getUidStatsLocked(uid).noteWifiStoppedLocked(elapsedRealtime); 5920 } 5921 } 5922 5923 scheduleSyncExternalStatsLocked("wifi-stopped", ExternalStatsSync.UPDATE_WIFI); 5924 } else { 5925 Log.w(TAG, "noteWifiStoppedLocked -- called while WIFI not running"); 5926 } 5927 } 5928 noteWifiStateLocked(int wifiState, String accessPoint)5929 public void noteWifiStateLocked(int wifiState, String accessPoint) { 5930 if (DEBUG) Log.i(TAG, "WiFi state -> " + wifiState); 5931 if (mWifiState != wifiState) { 5932 final long elapsedRealtime = mClocks.elapsedRealtime(); 5933 if (mWifiState >= 0) { 5934 mWifiStateTimer[mWifiState].stopRunningLocked(elapsedRealtime); 5935 } 5936 mWifiState = wifiState; 5937 mWifiStateTimer[wifiState].startRunningLocked(elapsedRealtime); 5938 scheduleSyncExternalStatsLocked("wifi-state", ExternalStatsSync.UPDATE_WIFI); 5939 } 5940 } 5941 noteWifiSupplicantStateChangedLocked(int supplState, boolean failedAuth)5942 public void noteWifiSupplicantStateChangedLocked(int supplState, boolean failedAuth) { 5943 if (DEBUG) Log.i(TAG, "WiFi suppl state -> " + supplState); 5944 if (mWifiSupplState != supplState) { 5945 final long elapsedRealtime = mClocks.elapsedRealtime(); 5946 final long uptime = mClocks.uptimeMillis(); 5947 if (mWifiSupplState >= 0) { 5948 mWifiSupplStateTimer[mWifiSupplState].stopRunningLocked(elapsedRealtime); 5949 } 5950 mWifiSupplState = supplState; 5951 mWifiSupplStateTimer[supplState].startRunningLocked(elapsedRealtime); 5952 mHistoryCur.states2 = 5953 (mHistoryCur.states2&~HistoryItem.STATE2_WIFI_SUPPL_STATE_MASK) 5954 | (supplState << HistoryItem.STATE2_WIFI_SUPPL_STATE_SHIFT); 5955 if (DEBUG_HISTORY) Slog.v(TAG, "Wifi suppl state " + supplState + " to: " 5956 + Integer.toHexString(mHistoryCur.states2)); 5957 addHistoryRecordLocked(elapsedRealtime, uptime); 5958 } 5959 } 5960 stopAllWifiSignalStrengthTimersLocked(int except)5961 void stopAllWifiSignalStrengthTimersLocked(int except) { 5962 final long elapsedRealtime = mClocks.elapsedRealtime(); 5963 for (int i = 0; i < NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { 5964 if (i == except) { 5965 continue; 5966 } 5967 while (mWifiSignalStrengthsTimer[i].isRunningLocked()) { 5968 mWifiSignalStrengthsTimer[i].stopRunningLocked(elapsedRealtime); 5969 } 5970 } 5971 } 5972 noteWifiRssiChangedLocked(int newRssi)5973 public void noteWifiRssiChangedLocked(int newRssi) { 5974 int strengthBin = WifiManager.calculateSignalLevel(newRssi, NUM_WIFI_SIGNAL_STRENGTH_BINS); 5975 if (DEBUG) Log.i(TAG, "WiFi rssi -> " + newRssi + " bin=" + strengthBin); 5976 if (mWifiSignalStrengthBin != strengthBin) { 5977 final long elapsedRealtime = mClocks.elapsedRealtime(); 5978 final long uptime = mClocks.uptimeMillis(); 5979 if (mWifiSignalStrengthBin >= 0) { 5980 mWifiSignalStrengthsTimer[mWifiSignalStrengthBin].stopRunningLocked( 5981 elapsedRealtime); 5982 } 5983 if (strengthBin >= 0) { 5984 if (!mWifiSignalStrengthsTimer[strengthBin].isRunningLocked()) { 5985 mWifiSignalStrengthsTimer[strengthBin].startRunningLocked(elapsedRealtime); 5986 } 5987 mHistoryCur.states2 = 5988 (mHistoryCur.states2&~HistoryItem.STATE2_WIFI_SIGNAL_STRENGTH_MASK) 5989 | (strengthBin << HistoryItem.STATE2_WIFI_SIGNAL_STRENGTH_SHIFT); 5990 if (DEBUG_HISTORY) Slog.v(TAG, "Wifi signal strength " + strengthBin + " to: " 5991 + Integer.toHexString(mHistoryCur.states2)); 5992 addHistoryRecordLocked(elapsedRealtime, uptime); 5993 } else { 5994 stopAllWifiSignalStrengthTimersLocked(-1); 5995 } 5996 StatsLog.write(StatsLog.WIFI_SIGNAL_STRENGTH_CHANGED, strengthBin); 5997 mWifiSignalStrengthBin = strengthBin; 5998 } 5999 } 6000 6001 int mWifiFullLockNesting = 0; 6002 noteFullWifiLockAcquiredLocked(int uid)6003 public void noteFullWifiLockAcquiredLocked(int uid) { 6004 final long elapsedRealtime = mClocks.elapsedRealtime(); 6005 final long uptime = mClocks.uptimeMillis(); 6006 if (mWifiFullLockNesting == 0) { 6007 mHistoryCur.states |= HistoryItem.STATE_WIFI_FULL_LOCK_FLAG; 6008 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI full lock on to: " 6009 + Integer.toHexString(mHistoryCur.states)); 6010 addHistoryRecordLocked(elapsedRealtime, uptime); 6011 } 6012 mWifiFullLockNesting++; 6013 getUidStatsLocked(uid).noteFullWifiLockAcquiredLocked(elapsedRealtime); 6014 } 6015 noteFullWifiLockReleasedLocked(int uid)6016 public void noteFullWifiLockReleasedLocked(int uid) { 6017 final long elapsedRealtime = mClocks.elapsedRealtime(); 6018 final long uptime = mClocks.uptimeMillis(); 6019 mWifiFullLockNesting--; 6020 if (mWifiFullLockNesting == 0) { 6021 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_FULL_LOCK_FLAG; 6022 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI full lock off to: " 6023 + Integer.toHexString(mHistoryCur.states)); 6024 addHistoryRecordLocked(elapsedRealtime, uptime); 6025 } 6026 getUidStatsLocked(uid).noteFullWifiLockReleasedLocked(elapsedRealtime); 6027 } 6028 6029 int mWifiScanNesting = 0; 6030 noteWifiScanStartedLocked(int uid)6031 public void noteWifiScanStartedLocked(int uid) { 6032 final long elapsedRealtime = mClocks.elapsedRealtime(); 6033 final long uptime = mClocks.uptimeMillis(); 6034 if (mWifiScanNesting == 0) { 6035 mHistoryCur.states |= HistoryItem.STATE_WIFI_SCAN_FLAG; 6036 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI scan started for: " 6037 + Integer.toHexString(mHistoryCur.states)); 6038 addHistoryRecordLocked(elapsedRealtime, uptime); 6039 } 6040 mWifiScanNesting++; 6041 getUidStatsLocked(uid).noteWifiScanStartedLocked(elapsedRealtime); 6042 } 6043 noteWifiScanStoppedLocked(int uid)6044 public void noteWifiScanStoppedLocked(int uid) { 6045 final long elapsedRealtime = mClocks.elapsedRealtime(); 6046 final long uptime = mClocks.uptimeMillis(); 6047 mWifiScanNesting--; 6048 if (mWifiScanNesting == 0) { 6049 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_SCAN_FLAG; 6050 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI scan stopped for: " 6051 + Integer.toHexString(mHistoryCur.states)); 6052 addHistoryRecordLocked(elapsedRealtime, uptime); 6053 } 6054 getUidStatsLocked(uid).noteWifiScanStoppedLocked(elapsedRealtime); 6055 } 6056 noteWifiBatchedScanStartedLocked(int uid, int csph)6057 public void noteWifiBatchedScanStartedLocked(int uid, int csph) { 6058 uid = mapUid(uid); 6059 final long elapsedRealtime = mClocks.elapsedRealtime(); 6060 getUidStatsLocked(uid).noteWifiBatchedScanStartedLocked(csph, elapsedRealtime); 6061 } 6062 noteWifiBatchedScanStoppedLocked(int uid)6063 public void noteWifiBatchedScanStoppedLocked(int uid) { 6064 uid = mapUid(uid); 6065 final long elapsedRealtime = mClocks.elapsedRealtime(); 6066 getUidStatsLocked(uid).noteWifiBatchedScanStoppedLocked(elapsedRealtime); 6067 } 6068 6069 int mWifiMulticastNesting = 0; 6070 noteWifiMulticastEnabledLocked(int uid)6071 public void noteWifiMulticastEnabledLocked(int uid) { 6072 uid = mapUid(uid); 6073 final long elapsedRealtime = mClocks.elapsedRealtime(); 6074 final long uptime = mClocks.uptimeMillis(); 6075 if (mWifiMulticastNesting == 0) { 6076 mHistoryCur.states |= HistoryItem.STATE_WIFI_MULTICAST_ON_FLAG; 6077 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI multicast on to: " 6078 + Integer.toHexString(mHistoryCur.states)); 6079 addHistoryRecordLocked(elapsedRealtime, uptime); 6080 6081 // Start Wifi Multicast overall timer 6082 if (!mWifiMulticastWakelockTimer.isRunningLocked()) { 6083 if (DEBUG_HISTORY) Slog.v(TAG, "WiFi Multicast Overall Timer Started"); 6084 mWifiMulticastWakelockTimer.startRunningLocked(elapsedRealtime); 6085 } 6086 } 6087 mWifiMulticastNesting++; 6088 getUidStatsLocked(uid).noteWifiMulticastEnabledLocked(elapsedRealtime); 6089 } 6090 noteWifiMulticastDisabledLocked(int uid)6091 public void noteWifiMulticastDisabledLocked(int uid) { 6092 uid = mapUid(uid); 6093 final long elapsedRealtime = mClocks.elapsedRealtime(); 6094 final long uptime = mClocks.uptimeMillis(); 6095 mWifiMulticastNesting--; 6096 if (mWifiMulticastNesting == 0) { 6097 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_MULTICAST_ON_FLAG; 6098 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI multicast off to: " 6099 + Integer.toHexString(mHistoryCur.states)); 6100 addHistoryRecordLocked(elapsedRealtime, uptime); 6101 6102 // Stop Wifi Multicast overall timer 6103 if (mWifiMulticastWakelockTimer.isRunningLocked()) { 6104 if (DEBUG_HISTORY) Slog.v(TAG, "Multicast Overall Timer Stopped"); 6105 mWifiMulticastWakelockTimer.stopRunningLocked(elapsedRealtime); 6106 } 6107 } 6108 getUidStatsLocked(uid).noteWifiMulticastDisabledLocked(elapsedRealtime); 6109 } 6110 noteFullWifiLockAcquiredFromSourceLocked(WorkSource ws)6111 public void noteFullWifiLockAcquiredFromSourceLocked(WorkSource ws) { 6112 int N = ws.size(); 6113 for (int i=0; i<N; i++) { 6114 final int uid = mapUid(ws.get(i)); 6115 noteFullWifiLockAcquiredLocked(uid); 6116 StatsLog.write_non_chained(StatsLog.WIFI_LOCK_STATE_CHANGED, ws.get(i), ws.getName(i), 6117 StatsLog.WIFI_LOCK_STATE_CHANGED__STATE__ON); 6118 } 6119 6120 final List<WorkChain> workChains = ws.getWorkChains(); 6121 if (workChains != null) { 6122 for (int i = 0; i < workChains.size(); ++i) { 6123 final WorkChain workChain = workChains.get(i); 6124 final int uid = mapUid(workChain.getAttributionUid()); 6125 noteFullWifiLockAcquiredLocked(uid); 6126 StatsLog.write(StatsLog.WIFI_LOCK_STATE_CHANGED, 6127 workChain.getUids(), workChain.getTags(), 6128 StatsLog.WIFI_LOCK_STATE_CHANGED__STATE__ON); 6129 } 6130 } 6131 } 6132 noteFullWifiLockReleasedFromSourceLocked(WorkSource ws)6133 public void noteFullWifiLockReleasedFromSourceLocked(WorkSource ws) { 6134 int N = ws.size(); 6135 for (int i=0; i<N; i++) { 6136 final int uid = mapUid(ws.get(i)); 6137 noteFullWifiLockReleasedLocked(uid); 6138 StatsLog.write_non_chained(StatsLog.WIFI_LOCK_STATE_CHANGED, ws.get(i), ws.getName(i), 6139 StatsLog.WIFI_LOCK_STATE_CHANGED__STATE__OFF); 6140 } 6141 6142 final List<WorkChain> workChains = ws.getWorkChains(); 6143 if (workChains != null) { 6144 for (int i = 0; i < workChains.size(); ++i) { 6145 final WorkChain workChain = workChains.get(i); 6146 final int uid = mapUid(workChain.getAttributionUid()); 6147 noteFullWifiLockReleasedLocked(uid); 6148 StatsLog.write(StatsLog.WIFI_LOCK_STATE_CHANGED, 6149 workChain.getUids(), workChain.getTags(), 6150 StatsLog.WIFI_LOCK_STATE_CHANGED__STATE__OFF); 6151 } 6152 } 6153 } 6154 noteWifiScanStartedFromSourceLocked(WorkSource ws)6155 public void noteWifiScanStartedFromSourceLocked(WorkSource ws) { 6156 int N = ws.size(); 6157 for (int i=0; i<N; i++) { 6158 final int uid = mapUid(ws.get(i)); 6159 noteWifiScanStartedLocked(uid); 6160 StatsLog.write_non_chained(StatsLog.WIFI_SCAN_STATE_CHANGED, ws.get(i), ws.getName(i), 6161 StatsLog.WIFI_SCAN_STATE_CHANGED__STATE__ON); 6162 } 6163 6164 final List<WorkChain> workChains = ws.getWorkChains(); 6165 if (workChains != null) { 6166 for (int i = 0; i < workChains.size(); ++i) { 6167 final WorkChain workChain = workChains.get(i); 6168 final int uid = mapUid(workChain.getAttributionUid()); 6169 noteWifiScanStartedLocked(uid); 6170 StatsLog.write(StatsLog.WIFI_SCAN_STATE_CHANGED, workChain.getUids(), 6171 workChain.getTags(), StatsLog.WIFI_SCAN_STATE_CHANGED__STATE__ON); 6172 } 6173 } 6174 } 6175 noteWifiScanStoppedFromSourceLocked(WorkSource ws)6176 public void noteWifiScanStoppedFromSourceLocked(WorkSource ws) { 6177 int N = ws.size(); 6178 for (int i=0; i<N; i++) { 6179 final int uid = mapUid(ws.get(i)); 6180 noteWifiScanStoppedLocked(uid); 6181 StatsLog.write_non_chained(StatsLog.WIFI_SCAN_STATE_CHANGED, ws.get(i), ws.getName(i), 6182 StatsLog.WIFI_SCAN_STATE_CHANGED__STATE__OFF); 6183 } 6184 6185 final List<WorkChain> workChains = ws.getWorkChains(); 6186 if (workChains != null) { 6187 for (int i = 0; i < workChains.size(); ++i) { 6188 final WorkChain workChain = workChains.get(i); 6189 final int uid = mapUid(workChain.getAttributionUid()); 6190 noteWifiScanStoppedLocked(uid); 6191 StatsLog.write(StatsLog.WIFI_SCAN_STATE_CHANGED, 6192 workChain.getUids(), workChain.getTags(), 6193 StatsLog.WIFI_SCAN_STATE_CHANGED__STATE__OFF); 6194 } 6195 } 6196 } 6197 noteWifiBatchedScanStartedFromSourceLocked(WorkSource ws, int csph)6198 public void noteWifiBatchedScanStartedFromSourceLocked(WorkSource ws, int csph) { 6199 int N = ws.size(); 6200 for (int i=0; i<N; i++) { 6201 noteWifiBatchedScanStartedLocked(ws.get(i), csph); 6202 } 6203 6204 final List<WorkChain> workChains = ws.getWorkChains(); 6205 if (workChains != null) { 6206 for (int i = 0; i < workChains.size(); ++i) { 6207 noteWifiBatchedScanStartedLocked(workChains.get(i).getAttributionUid(), csph); 6208 } 6209 } 6210 } 6211 noteWifiBatchedScanStoppedFromSourceLocked(WorkSource ws)6212 public void noteWifiBatchedScanStoppedFromSourceLocked(WorkSource ws) { 6213 int N = ws.size(); 6214 for (int i=0; i<N; i++) { 6215 noteWifiBatchedScanStoppedLocked(ws.get(i)); 6216 } 6217 6218 final List<WorkChain> workChains = ws.getWorkChains(); 6219 if (workChains != null) { 6220 for (int i = 0; i < workChains.size(); ++i) { 6221 noteWifiBatchedScanStoppedLocked(workChains.get(i).getAttributionUid()); 6222 } 6223 } 6224 } 6225 includeInStringArray(String[] array, String str)6226 private static String[] includeInStringArray(String[] array, String str) { 6227 if (ArrayUtils.indexOf(array, str) >= 0) { 6228 return array; 6229 } 6230 String[] newArray = new String[array.length+1]; 6231 System.arraycopy(array, 0, newArray, 0, array.length); 6232 newArray[array.length] = str; 6233 return newArray; 6234 } 6235 excludeFromStringArray(String[] array, String str)6236 private static String[] excludeFromStringArray(String[] array, String str) { 6237 int index = ArrayUtils.indexOf(array, str); 6238 if (index >= 0) { 6239 String[] newArray = new String[array.length-1]; 6240 if (index > 0) { 6241 System.arraycopy(array, 0, newArray, 0, index); 6242 } 6243 if (index < array.length-1) { 6244 System.arraycopy(array, index+1, newArray, index, array.length-index-1); 6245 } 6246 return newArray; 6247 } 6248 return array; 6249 } 6250 noteNetworkInterfaceTypeLocked(String iface, int networkType)6251 public void noteNetworkInterfaceTypeLocked(String iface, int networkType) { 6252 if (TextUtils.isEmpty(iface)) return; 6253 6254 synchronized (mModemNetworkLock) { 6255 if (ConnectivityManager.isNetworkTypeMobile(networkType)) { 6256 mModemIfaces = includeInStringArray(mModemIfaces, iface); 6257 if (DEBUG) Slog.d(TAG, "Note mobile iface " + iface + ": " + mModemIfaces); 6258 } else { 6259 mModemIfaces = excludeFromStringArray(mModemIfaces, iface); 6260 if (DEBUG) Slog.d(TAG, "Note non-mobile iface " + iface + ": " + mModemIfaces); 6261 } 6262 } 6263 6264 synchronized (mWifiNetworkLock) { 6265 if (ConnectivityManager.isNetworkTypeWifi(networkType)) { 6266 mWifiIfaces = includeInStringArray(mWifiIfaces, iface); 6267 if (DEBUG) Slog.d(TAG, "Note wifi iface " + iface + ": " + mWifiIfaces); 6268 } else { 6269 mWifiIfaces = excludeFromStringArray(mWifiIfaces, iface); 6270 if (DEBUG) Slog.d(TAG, "Note non-wifi iface " + iface + ": " + mWifiIfaces); 6271 } 6272 } 6273 } 6274 getWifiIfaces()6275 public String[] getWifiIfaces() { 6276 synchronized (mWifiNetworkLock) { 6277 return mWifiIfaces; 6278 } 6279 } 6280 getMobileIfaces()6281 public String[] getMobileIfaces() { 6282 synchronized (mModemNetworkLock) { 6283 return mModemIfaces; 6284 } 6285 } 6286 getScreenOnTime(long elapsedRealtimeUs, int which)6287 @Override public long getScreenOnTime(long elapsedRealtimeUs, int which) { 6288 return mScreenOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 6289 } 6290 getScreenOnCount(int which)6291 @Override public int getScreenOnCount(int which) { 6292 return mScreenOnTimer.getCountLocked(which); 6293 } 6294 getScreenDozeTime(long elapsedRealtimeUs, int which)6295 @Override public long getScreenDozeTime(long elapsedRealtimeUs, int which) { 6296 return mScreenDozeTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 6297 } 6298 getScreenDozeCount(int which)6299 @Override public int getScreenDozeCount(int which) { 6300 return mScreenDozeTimer.getCountLocked(which); 6301 } 6302 getScreenBrightnessTime(int brightnessBin, long elapsedRealtimeUs, int which)6303 @Override public long getScreenBrightnessTime(int brightnessBin, 6304 long elapsedRealtimeUs, int which) { 6305 return mScreenBrightnessTimer[brightnessBin].getTotalTimeLocked( 6306 elapsedRealtimeUs, which); 6307 } 6308 getScreenBrightnessTimer(int brightnessBin)6309 @Override public Timer getScreenBrightnessTimer(int brightnessBin) { 6310 return mScreenBrightnessTimer[brightnessBin]; 6311 } 6312 getInteractiveTime(long elapsedRealtimeUs, int which)6313 @Override public long getInteractiveTime(long elapsedRealtimeUs, int which) { 6314 return mInteractiveTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 6315 } 6316 getPowerSaveModeEnabledTime(long elapsedRealtimeUs, int which)6317 @Override public long getPowerSaveModeEnabledTime(long elapsedRealtimeUs, int which) { 6318 return mPowerSaveModeEnabledTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 6319 } 6320 getPowerSaveModeEnabledCount(int which)6321 @Override public int getPowerSaveModeEnabledCount(int which) { 6322 return mPowerSaveModeEnabledTimer.getCountLocked(which); 6323 } 6324 getDeviceIdleModeTime(int mode, long elapsedRealtimeUs, int which)6325 @Override public long getDeviceIdleModeTime(int mode, long elapsedRealtimeUs, 6326 int which) { 6327 switch (mode) { 6328 case DEVICE_IDLE_MODE_LIGHT: 6329 return mDeviceIdleModeLightTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 6330 case DEVICE_IDLE_MODE_DEEP: 6331 return mDeviceIdleModeFullTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 6332 } 6333 return 0; 6334 } 6335 getDeviceIdleModeCount(int mode, int which)6336 @Override public int getDeviceIdleModeCount(int mode, int which) { 6337 switch (mode) { 6338 case DEVICE_IDLE_MODE_LIGHT: 6339 return mDeviceIdleModeLightTimer.getCountLocked(which); 6340 case DEVICE_IDLE_MODE_DEEP: 6341 return mDeviceIdleModeFullTimer.getCountLocked(which); 6342 } 6343 return 0; 6344 } 6345 getLongestDeviceIdleModeTime(int mode)6346 @Override public long getLongestDeviceIdleModeTime(int mode) { 6347 switch (mode) { 6348 case DEVICE_IDLE_MODE_LIGHT: 6349 return mLongestLightIdleTime; 6350 case DEVICE_IDLE_MODE_DEEP: 6351 return mLongestFullIdleTime; 6352 } 6353 return 0; 6354 } 6355 getDeviceIdlingTime(int mode, long elapsedRealtimeUs, int which)6356 @Override public long getDeviceIdlingTime(int mode, long elapsedRealtimeUs, int which) { 6357 switch (mode) { 6358 case DEVICE_IDLE_MODE_LIGHT: 6359 return mDeviceLightIdlingTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 6360 case DEVICE_IDLE_MODE_DEEP: 6361 return mDeviceIdlingTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 6362 } 6363 return 0; 6364 } 6365 getDeviceIdlingCount(int mode, int which)6366 @Override public int getDeviceIdlingCount(int mode, int which) { 6367 switch (mode) { 6368 case DEVICE_IDLE_MODE_LIGHT: 6369 return mDeviceLightIdlingTimer.getCountLocked(which); 6370 case DEVICE_IDLE_MODE_DEEP: 6371 return mDeviceIdlingTimer.getCountLocked(which); 6372 } 6373 return 0; 6374 } 6375 getNumConnectivityChange(int which)6376 @Override public int getNumConnectivityChange(int which) { 6377 int val = mNumConnectivityChange; 6378 if (which == STATS_CURRENT) { 6379 val -= mLoadedNumConnectivityChange; 6380 } else if (which == STATS_SINCE_UNPLUGGED) { 6381 val -= mUnpluggedNumConnectivityChange; 6382 } 6383 return val; 6384 } 6385 getGpsSignalQualityTime(int strengthBin, long elapsedRealtimeUs, int which)6386 @Override public long getGpsSignalQualityTime(int strengthBin, 6387 long elapsedRealtimeUs, int which) { 6388 if (strengthBin < 0 || strengthBin >= GnssMetrics.NUM_GPS_SIGNAL_QUALITY_LEVELS) { 6389 return 0; 6390 } 6391 return mGpsSignalQualityTimer[strengthBin].getTotalTimeLocked( 6392 elapsedRealtimeUs, which); 6393 } 6394 getGpsBatteryDrainMaMs()6395 @Override public long getGpsBatteryDrainMaMs() { 6396 final double opVolt = mPowerProfile.getAveragePower( 6397 PowerProfile.POWER_GPS_OPERATING_VOLTAGE) / 1000.0; 6398 if (opVolt == 0) { 6399 return 0; 6400 } 6401 double energyUsedMaMs = 0.0; 6402 final int which = STATS_SINCE_CHARGED; 6403 final long rawRealtime = SystemClock.elapsedRealtime() * 1000; 6404 for(int i=0; i < GnssMetrics.NUM_GPS_SIGNAL_QUALITY_LEVELS; i++) { 6405 energyUsedMaMs 6406 += mPowerProfile.getAveragePower(PowerProfile.POWER_GPS_SIGNAL_QUALITY_BASED, i) 6407 * (getGpsSignalQualityTime(i, rawRealtime, which) / 1000); 6408 } 6409 return (long) energyUsedMaMs; 6410 } 6411 getPhoneOnTime(long elapsedRealtimeUs, int which)6412 @Override public long getPhoneOnTime(long elapsedRealtimeUs, int which) { 6413 return mPhoneOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 6414 } 6415 getPhoneOnCount(int which)6416 @Override public int getPhoneOnCount(int which) { 6417 return mPhoneOnTimer.getCountLocked(which); 6418 } 6419 getPhoneSignalStrengthTime(int strengthBin, long elapsedRealtimeUs, int which)6420 @Override public long getPhoneSignalStrengthTime(int strengthBin, 6421 long elapsedRealtimeUs, int which) { 6422 return mPhoneSignalStrengthsTimer[strengthBin].getTotalTimeLocked( 6423 elapsedRealtimeUs, which); 6424 } 6425 getPhoneSignalScanningTime( long elapsedRealtimeUs, int which)6426 @Override public long getPhoneSignalScanningTime( 6427 long elapsedRealtimeUs, int which) { 6428 return mPhoneSignalScanningTimer.getTotalTimeLocked( 6429 elapsedRealtimeUs, which); 6430 } 6431 getPhoneSignalScanningTimer()6432 @Override public Timer getPhoneSignalScanningTimer() { 6433 return mPhoneSignalScanningTimer; 6434 } 6435 getPhoneSignalStrengthCount(int strengthBin, int which)6436 @Override public int getPhoneSignalStrengthCount(int strengthBin, int which) { 6437 return mPhoneSignalStrengthsTimer[strengthBin].getCountLocked(which); 6438 } 6439 getPhoneSignalStrengthTimer(int strengthBin)6440 @Override public Timer getPhoneSignalStrengthTimer(int strengthBin) { 6441 return mPhoneSignalStrengthsTimer[strengthBin]; 6442 } 6443 getPhoneDataConnectionTime(int dataType, long elapsedRealtimeUs, int which)6444 @Override public long getPhoneDataConnectionTime(int dataType, 6445 long elapsedRealtimeUs, int which) { 6446 return mPhoneDataConnectionsTimer[dataType].getTotalTimeLocked( 6447 elapsedRealtimeUs, which); 6448 } 6449 getPhoneDataConnectionCount(int dataType, int which)6450 @Override public int getPhoneDataConnectionCount(int dataType, int which) { 6451 return mPhoneDataConnectionsTimer[dataType].getCountLocked(which); 6452 } 6453 getPhoneDataConnectionTimer(int dataType)6454 @Override public Timer getPhoneDataConnectionTimer(int dataType) { 6455 return mPhoneDataConnectionsTimer[dataType]; 6456 } 6457 getMobileRadioActiveTime(long elapsedRealtimeUs, int which)6458 @Override public long getMobileRadioActiveTime(long elapsedRealtimeUs, int which) { 6459 return mMobileRadioActiveTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 6460 } 6461 getMobileRadioActiveCount(int which)6462 @Override public int getMobileRadioActiveCount(int which) { 6463 return mMobileRadioActiveTimer.getCountLocked(which); 6464 } 6465 getMobileRadioActiveAdjustedTime(int which)6466 @Override public long getMobileRadioActiveAdjustedTime(int which) { 6467 return mMobileRadioActiveAdjustedTime.getCountLocked(which); 6468 } 6469 getMobileRadioActiveUnknownTime(int which)6470 @Override public long getMobileRadioActiveUnknownTime(int which) { 6471 return mMobileRadioActiveUnknownTime.getCountLocked(which); 6472 } 6473 getMobileRadioActiveUnknownCount(int which)6474 @Override public int getMobileRadioActiveUnknownCount(int which) { 6475 return (int)mMobileRadioActiveUnknownCount.getCountLocked(which); 6476 } 6477 getWifiMulticastWakelockTime( long elapsedRealtimeUs, int which)6478 @Override public long getWifiMulticastWakelockTime( 6479 long elapsedRealtimeUs, int which) { 6480 return mWifiMulticastWakelockTimer.getTotalTimeLocked( 6481 elapsedRealtimeUs, which); 6482 } 6483 getWifiMulticastWakelockCount(int which)6484 @Override public int getWifiMulticastWakelockCount(int which) { 6485 return mWifiMulticastWakelockTimer.getCountLocked(which); 6486 } 6487 getWifiOnTime(long elapsedRealtimeUs, int which)6488 @Override public long getWifiOnTime(long elapsedRealtimeUs, int which) { 6489 return mWifiOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 6490 } 6491 getWifiActiveTime(long elapsedRealtimeUs, int which)6492 @Override public long getWifiActiveTime(long elapsedRealtimeUs, int which) { 6493 return mWifiActiveTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 6494 } 6495 getGlobalWifiRunningTime(long elapsedRealtimeUs, int which)6496 @Override public long getGlobalWifiRunningTime(long elapsedRealtimeUs, int which) { 6497 return mGlobalWifiRunningTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 6498 } 6499 getWifiStateTime(int wifiState, long elapsedRealtimeUs, int which)6500 @Override public long getWifiStateTime(int wifiState, 6501 long elapsedRealtimeUs, int which) { 6502 return mWifiStateTimer[wifiState].getTotalTimeLocked( 6503 elapsedRealtimeUs, which); 6504 } 6505 getWifiStateCount(int wifiState, int which)6506 @Override public int getWifiStateCount(int wifiState, int which) { 6507 return mWifiStateTimer[wifiState].getCountLocked(which); 6508 } 6509 getWifiStateTimer(int wifiState)6510 @Override public Timer getWifiStateTimer(int wifiState) { 6511 return mWifiStateTimer[wifiState]; 6512 } 6513 getWifiSupplStateTime(int state, long elapsedRealtimeUs, int which)6514 @Override public long getWifiSupplStateTime(int state, 6515 long elapsedRealtimeUs, int which) { 6516 return mWifiSupplStateTimer[state].getTotalTimeLocked( 6517 elapsedRealtimeUs, which); 6518 } 6519 getWifiSupplStateCount(int state, int which)6520 @Override public int getWifiSupplStateCount(int state, int which) { 6521 return mWifiSupplStateTimer[state].getCountLocked(which); 6522 } 6523 getWifiSupplStateTimer(int state)6524 @Override public Timer getWifiSupplStateTimer(int state) { 6525 return mWifiSupplStateTimer[state]; 6526 } 6527 getWifiSignalStrengthTime(int strengthBin, long elapsedRealtimeUs, int which)6528 @Override public long getWifiSignalStrengthTime(int strengthBin, 6529 long elapsedRealtimeUs, int which) { 6530 return mWifiSignalStrengthsTimer[strengthBin].getTotalTimeLocked( 6531 elapsedRealtimeUs, which); 6532 } 6533 getWifiSignalStrengthCount(int strengthBin, int which)6534 @Override public int getWifiSignalStrengthCount(int strengthBin, int which) { 6535 return mWifiSignalStrengthsTimer[strengthBin].getCountLocked(which); 6536 } 6537 getWifiSignalStrengthTimer(int strengthBin)6538 @Override public Timer getWifiSignalStrengthTimer(int strengthBin) { 6539 return mWifiSignalStrengthsTimer[strengthBin]; 6540 } 6541 6542 @Override getBluetoothControllerActivity()6543 public ControllerActivityCounter getBluetoothControllerActivity() { 6544 return mBluetoothActivity; 6545 } 6546 6547 @Override getWifiControllerActivity()6548 public ControllerActivityCounter getWifiControllerActivity() { 6549 return mWifiActivity; 6550 } 6551 6552 @Override getModemControllerActivity()6553 public ControllerActivityCounter getModemControllerActivity() { 6554 return mModemActivity; 6555 } 6556 6557 @Override hasBluetoothActivityReporting()6558 public boolean hasBluetoothActivityReporting() { 6559 return mHasBluetoothReporting; 6560 } 6561 6562 @Override hasWifiActivityReporting()6563 public boolean hasWifiActivityReporting() { 6564 return mHasWifiReporting; 6565 } 6566 6567 @Override hasModemActivityReporting()6568 public boolean hasModemActivityReporting() { 6569 return mHasModemReporting; 6570 } 6571 6572 @Override getFlashlightOnTime(long elapsedRealtimeUs, int which)6573 public long getFlashlightOnTime(long elapsedRealtimeUs, int which) { 6574 return mFlashlightOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 6575 } 6576 6577 @Override getFlashlightOnCount(int which)6578 public long getFlashlightOnCount(int which) { 6579 return mFlashlightOnTimer.getCountLocked(which); 6580 } 6581 6582 @Override getCameraOnTime(long elapsedRealtimeUs, int which)6583 public long getCameraOnTime(long elapsedRealtimeUs, int which) { 6584 return mCameraOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 6585 } 6586 6587 @Override getBluetoothScanTime(long elapsedRealtimeUs, int which)6588 public long getBluetoothScanTime(long elapsedRealtimeUs, int which) { 6589 return mBluetoothScanTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 6590 } 6591 6592 @Override getNetworkActivityBytes(int type, int which)6593 public long getNetworkActivityBytes(int type, int which) { 6594 if (type >= 0 && type < mNetworkByteActivityCounters.length) { 6595 return mNetworkByteActivityCounters[type].getCountLocked(which); 6596 } else { 6597 return 0; 6598 } 6599 } 6600 6601 @Override getNetworkActivityPackets(int type, int which)6602 public long getNetworkActivityPackets(int type, int which) { 6603 if (type >= 0 && type < mNetworkPacketActivityCounters.length) { 6604 return mNetworkPacketActivityCounters[type].getCountLocked(which); 6605 } else { 6606 return 0; 6607 } 6608 } 6609 getStartClockTime()6610 @Override public long getStartClockTime() { 6611 final long currentTime = System.currentTimeMillis(); 6612 if (ensureStartClockTime(currentTime)) { 6613 recordCurrentTimeChangeLocked(currentTime, mClocks.elapsedRealtime(), 6614 mClocks.uptimeMillis()); 6615 } 6616 return mStartClockTime; 6617 } 6618 getStartPlatformVersion()6619 @Override public String getStartPlatformVersion() { 6620 return mStartPlatformVersion; 6621 } 6622 getEndPlatformVersion()6623 @Override public String getEndPlatformVersion() { 6624 return mEndPlatformVersion; 6625 } 6626 getParcelVersion()6627 @Override public int getParcelVersion() { 6628 return VERSION; 6629 } 6630 getIsOnBattery()6631 @Override public boolean getIsOnBattery() { 6632 return mOnBattery; 6633 } 6634 getUidStats()6635 @Override public SparseArray<? extends BatteryStats.Uid> getUidStats() { 6636 return mUidStats; 6637 } 6638 detachTimerIfNotNull(BatteryStatsImpl.Timer timer)6639 private static void detachTimerIfNotNull(BatteryStatsImpl.Timer timer) { 6640 if (timer != null) { 6641 timer.detach(); 6642 } 6643 } 6644 resetTimerIfNotNull(BatteryStatsImpl.Timer timer, boolean detachIfReset)6645 private static boolean resetTimerIfNotNull(BatteryStatsImpl.Timer timer, 6646 boolean detachIfReset) { 6647 if (timer != null) { 6648 return timer.reset(detachIfReset); 6649 } 6650 return true; 6651 } 6652 resetTimerIfNotNull(DualTimer timer, boolean detachIfReset)6653 private static boolean resetTimerIfNotNull(DualTimer timer, boolean detachIfReset) { 6654 if (timer != null) { 6655 return timer.reset(detachIfReset); 6656 } 6657 return true; 6658 } 6659 detachLongCounterIfNotNull(LongSamplingCounter counter)6660 private static void detachLongCounterIfNotNull(LongSamplingCounter counter) { 6661 if (counter != null) { 6662 counter.detach(); 6663 } 6664 } 6665 resetLongCounterIfNotNull(LongSamplingCounter counter, boolean detachIfReset)6666 private static void resetLongCounterIfNotNull(LongSamplingCounter counter, 6667 boolean detachIfReset) { 6668 if (counter != null) { 6669 counter.reset(detachIfReset); 6670 } 6671 } 6672 6673 /** 6674 * The statistics associated with a particular uid. 6675 */ 6676 public static class Uid extends BatteryStats.Uid { 6677 /** 6678 * BatteryStatsImpl that we are associated with. 6679 */ 6680 protected BatteryStatsImpl mBsi; 6681 6682 final int mUid; 6683 6684 /** TimeBase for when uid is in background and device is on battery. */ 6685 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) 6686 public final TimeBase mOnBatteryBackgroundTimeBase; 6687 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) 6688 public final TimeBase mOnBatteryScreenOffBackgroundTimeBase; 6689 6690 boolean mWifiRunning; 6691 StopwatchTimer mWifiRunningTimer; 6692 6693 boolean mFullWifiLockOut; 6694 StopwatchTimer mFullWifiLockTimer; 6695 6696 boolean mWifiScanStarted; 6697 DualTimer mWifiScanTimer; 6698 6699 static final int NO_BATCHED_SCAN_STARTED = -1; 6700 int mWifiBatchedScanBinStarted = NO_BATCHED_SCAN_STARTED; 6701 StopwatchTimer[] mWifiBatchedScanTimer; 6702 6703 boolean mWifiMulticastEnabled; 6704 StopwatchTimer mWifiMulticastTimer; 6705 6706 StopwatchTimer mAudioTurnedOnTimer; 6707 StopwatchTimer mVideoTurnedOnTimer; 6708 StopwatchTimer mFlashlightTurnedOnTimer; 6709 StopwatchTimer mCameraTurnedOnTimer; 6710 StopwatchTimer mForegroundActivityTimer; 6711 StopwatchTimer mForegroundServiceTimer; 6712 /** Total time spent by the uid holding any partial wakelocks. */ 6713 DualTimer mAggregatedPartialWakelockTimer; 6714 DualTimer mBluetoothScanTimer; 6715 DualTimer mBluetoothUnoptimizedScanTimer; 6716 Counter mBluetoothScanResultCounter; 6717 Counter mBluetoothScanResultBgCounter; 6718 6719 int mProcessState = ActivityManager.PROCESS_STATE_NONEXISTENT; 6720 StopwatchTimer[] mProcessStateTimer; 6721 6722 boolean mInForegroundService = false; 6723 6724 BatchTimer mVibratorOnTimer; 6725 6726 Counter[] mUserActivityCounters; 6727 6728 LongSamplingCounter[] mNetworkByteActivityCounters; 6729 LongSamplingCounter[] mNetworkPacketActivityCounters; 6730 LongSamplingCounter mMobileRadioActiveTime; 6731 LongSamplingCounter mMobileRadioActiveCount; 6732 6733 /** 6734 * How many times this UID woke up the Application Processor due to a Mobile radio packet. 6735 */ 6736 private LongSamplingCounter mMobileRadioApWakeupCount; 6737 6738 /** 6739 * How many times this UID woke up the Application Processor due to a Wifi packet. 6740 */ 6741 private LongSamplingCounter mWifiRadioApWakeupCount; 6742 6743 /** 6744 * The amount of time this uid has kept the WiFi controller in idle, tx, and rx mode. 6745 * Can be null if the UID has had no such activity. 6746 */ 6747 private ControllerActivityCounterImpl mWifiControllerActivity; 6748 6749 /** 6750 * The amount of time this uid has kept the Bluetooth controller in idle, tx, and rx mode. 6751 * Can be null if the UID has had no such activity. 6752 */ 6753 private ControllerActivityCounterImpl mBluetoothControllerActivity; 6754 6755 /** 6756 * The amount of time this uid has kept the Modem controller in idle, tx, and rx mode. 6757 * Can be null if the UID has had no such activity. 6758 */ 6759 private ControllerActivityCounterImpl mModemControllerActivity; 6760 6761 /** 6762 * The CPU times we had at the last history details update. 6763 */ 6764 long mLastStepUserTime; 6765 long mLastStepSystemTime; 6766 long mCurStepUserTime; 6767 long mCurStepSystemTime; 6768 6769 LongSamplingCounter mUserCpuTime; 6770 LongSamplingCounter mSystemCpuTime; 6771 LongSamplingCounter[][] mCpuClusterSpeedTimesUs; 6772 LongSamplingCounter mCpuActiveTimeMs; 6773 6774 LongSamplingCounterArray mCpuFreqTimeMs; 6775 LongSamplingCounterArray mScreenOffCpuFreqTimeMs; 6776 LongSamplingCounterArray mCpuClusterTimesMs; 6777 6778 LongSamplingCounterArray[] mProcStateTimeMs; 6779 LongSamplingCounterArray[] mProcStateScreenOffTimeMs; 6780 6781 IntArray mChildUids; 6782 6783 /** 6784 * The statistics we have collected for this uid's wake locks. 6785 */ 6786 final OverflowArrayMap<Wakelock> mWakelockStats; 6787 6788 /** 6789 * The statistics we have collected for this uid's syncs. 6790 */ 6791 final OverflowArrayMap<DualTimer> mSyncStats; 6792 6793 /** 6794 * The statistics we have collected for this uid's jobs. 6795 */ 6796 final OverflowArrayMap<DualTimer> mJobStats; 6797 6798 /** 6799 * Count of the jobs that have completed and the reasons why they completed. 6800 */ 6801 final ArrayMap<String, SparseIntArray> mJobCompletions = new ArrayMap<>(); 6802 6803 /** 6804 * Count of app launch events that had associated deferred job counts or info about 6805 * last time a job was run. 6806 */ 6807 Counter mJobsDeferredEventCount; 6808 6809 /** 6810 * Count of deferred jobs that were pending when the app was launched or brought to 6811 * the foreground through a user interaction. 6812 */ 6813 Counter mJobsDeferredCount; 6814 6815 /** 6816 * Sum of time since the last time a job was run for this app before it was launched. 6817 */ 6818 LongSamplingCounter mJobsFreshnessTimeMs; 6819 6820 /** 6821 * Array of counts of instances where the time since the last job was run for the app 6822 * fell within one of the thresholds in {@link #JOB_FRESHNESS_BUCKETS}. 6823 */ 6824 final Counter[] mJobsFreshnessBuckets; 6825 6826 /** 6827 * The statistics we have collected for this uid's sensor activations. 6828 */ 6829 final SparseArray<Sensor> mSensorStats = new SparseArray<>(); 6830 6831 /** 6832 * The statistics we have collected for this uid's processes. 6833 */ 6834 final ArrayMap<String, Proc> mProcessStats = new ArrayMap<>(); 6835 6836 /** 6837 * The statistics we have collected for this uid's processes. 6838 */ 6839 final ArrayMap<String, Pkg> mPackageStats = new ArrayMap<>(); 6840 6841 /** 6842 * The transient wake stats we have collected for this uid's pids. 6843 */ 6844 final SparseArray<Pid> mPids = new SparseArray<>(); 6845 Uid(BatteryStatsImpl bsi, int uid)6846 public Uid(BatteryStatsImpl bsi, int uid) { 6847 mBsi = bsi; 6848 mUid = uid; 6849 6850 mOnBatteryBackgroundTimeBase = new TimeBase(); 6851 mOnBatteryBackgroundTimeBase.init(mBsi.mClocks.uptimeMillis() * 1000, 6852 mBsi.mClocks.elapsedRealtime() * 1000); 6853 6854 mOnBatteryScreenOffBackgroundTimeBase = new TimeBase(); 6855 mOnBatteryScreenOffBackgroundTimeBase.init(mBsi.mClocks.uptimeMillis() * 1000, 6856 mBsi.mClocks.elapsedRealtime() * 1000); 6857 6858 mUserCpuTime = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); 6859 mSystemCpuTime = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); 6860 mCpuActiveTimeMs = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); 6861 mCpuClusterTimesMs = new LongSamplingCounterArray(mBsi.mOnBatteryTimeBase); 6862 6863 mWakelockStats = mBsi.new OverflowArrayMap<Wakelock>(uid) { 6864 @Override public Wakelock instantiateObject() { 6865 return new Wakelock(mBsi, Uid.this); 6866 } 6867 }; 6868 mSyncStats = mBsi.new OverflowArrayMap<DualTimer>(uid) { 6869 @Override public DualTimer instantiateObject() { 6870 return new DualTimer(mBsi.mClocks, Uid.this, SYNC, null, 6871 mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase); 6872 } 6873 }; 6874 mJobStats = mBsi.new OverflowArrayMap<DualTimer>(uid) { 6875 @Override public DualTimer instantiateObject() { 6876 return new DualTimer(mBsi.mClocks, Uid.this, JOB, null, 6877 mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase); 6878 } 6879 }; 6880 6881 mWifiRunningTimer = new StopwatchTimer(mBsi.mClocks, this, WIFI_RUNNING, 6882 mBsi.mWifiRunningTimers, mBsi.mOnBatteryTimeBase); 6883 mFullWifiLockTimer = new StopwatchTimer(mBsi.mClocks, this, FULL_WIFI_LOCK, 6884 mBsi.mFullWifiLockTimers, mBsi.mOnBatteryTimeBase); 6885 mWifiScanTimer = new DualTimer(mBsi.mClocks, this, WIFI_SCAN, 6886 mBsi.mWifiScanTimers, mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase); 6887 mWifiBatchedScanTimer = new StopwatchTimer[NUM_WIFI_BATCHED_SCAN_BINS]; 6888 mWifiMulticastTimer = new StopwatchTimer(mBsi.mClocks, this, WIFI_MULTICAST_ENABLED, 6889 mBsi.mWifiMulticastTimers, mBsi.mOnBatteryTimeBase); 6890 mProcessStateTimer = new StopwatchTimer[NUM_PROCESS_STATE]; 6891 mJobsDeferredEventCount = new Counter(mBsi.mOnBatteryTimeBase); 6892 mJobsDeferredCount = new Counter(mBsi.mOnBatteryTimeBase); 6893 mJobsFreshnessTimeMs = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); 6894 mJobsFreshnessBuckets = new Counter[JOB_FRESHNESS_BUCKETS.length]; 6895 } 6896 6897 @VisibleForTesting setProcessStateForTest(int procState)6898 public void setProcessStateForTest(int procState) { 6899 mProcessState = procState; 6900 } 6901 6902 @Override getCpuFreqTimes(int which)6903 public long[] getCpuFreqTimes(int which) { 6904 return nullIfAllZeros(mCpuFreqTimeMs, which); 6905 } 6906 6907 @Override getScreenOffCpuFreqTimes(int which)6908 public long[] getScreenOffCpuFreqTimes(int which) { 6909 return nullIfAllZeros(mScreenOffCpuFreqTimeMs, which); 6910 } 6911 6912 @Override getCpuActiveTime()6913 public long getCpuActiveTime() { 6914 return mCpuActiveTimeMs.getCountLocked(STATS_SINCE_CHARGED); 6915 } 6916 6917 @Override getCpuClusterTimes()6918 public long[] getCpuClusterTimes() { 6919 return nullIfAllZeros(mCpuClusterTimesMs, STATS_SINCE_CHARGED); 6920 } 6921 6922 6923 @Override getCpuFreqTimes(int which, int procState)6924 public long[] getCpuFreqTimes(int which, int procState) { 6925 if (which < 0 || which >= NUM_PROCESS_STATE) { 6926 return null; 6927 } 6928 if (mProcStateTimeMs == null) { 6929 return null; 6930 } 6931 if (!mBsi.mPerProcStateCpuTimesAvailable) { 6932 mProcStateTimeMs = null; 6933 return null; 6934 } 6935 return nullIfAllZeros(mProcStateTimeMs[procState], which); 6936 } 6937 6938 @Override getScreenOffCpuFreqTimes(int which, int procState)6939 public long[] getScreenOffCpuFreqTimes(int which, int procState) { 6940 if (which < 0 || which >= NUM_PROCESS_STATE) { 6941 return null; 6942 } 6943 if (mProcStateScreenOffTimeMs == null) { 6944 return null; 6945 } 6946 if (!mBsi.mPerProcStateCpuTimesAvailable) { 6947 mProcStateScreenOffTimeMs = null; 6948 return null; 6949 } 6950 return nullIfAllZeros(mProcStateScreenOffTimeMs[procState], which); 6951 } 6952 addIsolatedUid(int isolatedUid)6953 public void addIsolatedUid(int isolatedUid) { 6954 if (mChildUids == null) { 6955 mChildUids = new IntArray(); 6956 } else if (mChildUids.indexOf(isolatedUid) >= 0) { 6957 return; 6958 } 6959 mChildUids.add(isolatedUid); 6960 } 6961 removeIsolatedUid(int isolatedUid)6962 public void removeIsolatedUid(int isolatedUid) { 6963 final int idx = mChildUids == null ? -1 : mChildUids.indexOf(isolatedUid); 6964 if (idx < 0) { 6965 return; 6966 } 6967 mChildUids.remove(idx); 6968 } 6969 nullIfAllZeros(LongSamplingCounterArray cpuTimesMs, int which)6970 private long[] nullIfAllZeros(LongSamplingCounterArray cpuTimesMs, int which) { 6971 if (cpuTimesMs == null) { 6972 return null; 6973 } 6974 final long[] counts = cpuTimesMs.getCountsLocked(which); 6975 if (counts == null) { 6976 return null; 6977 } 6978 // Return counts only if at least one of the elements is non-zero. 6979 for (int i = counts.length - 1; i >= 0; --i) { 6980 if (counts[i] != 0) { 6981 return counts; 6982 } 6983 } 6984 return null; 6985 } 6986 addProcStateTimesMs(int procState, long[] cpuTimesMs, boolean onBattery)6987 private void addProcStateTimesMs(int procState, long[] cpuTimesMs, boolean onBattery) { 6988 if (mProcStateTimeMs == null) { 6989 mProcStateTimeMs = new LongSamplingCounterArray[NUM_PROCESS_STATE]; 6990 } 6991 if (mProcStateTimeMs[procState] == null 6992 || mProcStateTimeMs[procState].getSize() != cpuTimesMs.length) { 6993 mProcStateTimeMs[procState] = new LongSamplingCounterArray( 6994 mBsi.mOnBatteryTimeBase); 6995 } 6996 mProcStateTimeMs[procState].addCountLocked(cpuTimesMs, onBattery); 6997 } 6998 addProcStateScreenOffTimesMs(int procState, long[] cpuTimesMs, boolean onBatteryScreenOff)6999 private void addProcStateScreenOffTimesMs(int procState, long[] cpuTimesMs, 7000 boolean onBatteryScreenOff) { 7001 if (mProcStateScreenOffTimeMs == null) { 7002 mProcStateScreenOffTimeMs = new LongSamplingCounterArray[NUM_PROCESS_STATE]; 7003 } 7004 if (mProcStateScreenOffTimeMs[procState] == null 7005 || mProcStateScreenOffTimeMs[procState].getSize() != cpuTimesMs.length) { 7006 mProcStateScreenOffTimeMs[procState] = new LongSamplingCounterArray( 7007 mBsi.mOnBatteryScreenOffTimeBase); 7008 } 7009 mProcStateScreenOffTimeMs[procState].addCountLocked(cpuTimesMs, onBatteryScreenOff); 7010 } 7011 7012 @Override getAggregatedPartialWakelockTimer()7013 public Timer getAggregatedPartialWakelockTimer() { 7014 return mAggregatedPartialWakelockTimer; 7015 } 7016 7017 @Override getWakelockStats()7018 public ArrayMap<String, ? extends BatteryStats.Uid.Wakelock> getWakelockStats() { 7019 return mWakelockStats.getMap(); 7020 } 7021 7022 @Override getMulticastWakelockStats()7023 public Timer getMulticastWakelockStats() { 7024 return mWifiMulticastTimer; 7025 } 7026 7027 @Override getSyncStats()7028 public ArrayMap<String, ? extends BatteryStats.Timer> getSyncStats() { 7029 return mSyncStats.getMap(); 7030 } 7031 7032 @Override getJobStats()7033 public ArrayMap<String, ? extends BatteryStats.Timer> getJobStats() { 7034 return mJobStats.getMap(); 7035 } 7036 7037 @Override getJobCompletionStats()7038 public ArrayMap<String, SparseIntArray> getJobCompletionStats() { 7039 return mJobCompletions; 7040 } 7041 7042 @Override getSensorStats()7043 public SparseArray<? extends BatteryStats.Uid.Sensor> getSensorStats() { 7044 return mSensorStats; 7045 } 7046 7047 @Override getProcessStats()7048 public ArrayMap<String, ? extends BatteryStats.Uid.Proc> getProcessStats() { 7049 return mProcessStats; 7050 } 7051 7052 @Override getPackageStats()7053 public ArrayMap<String, ? extends BatteryStats.Uid.Pkg> getPackageStats() { 7054 return mPackageStats; 7055 } 7056 7057 @Override getUid()7058 public int getUid() { 7059 return mUid; 7060 } 7061 7062 @Override noteWifiRunningLocked(long elapsedRealtimeMs)7063 public void noteWifiRunningLocked(long elapsedRealtimeMs) { 7064 if (!mWifiRunning) { 7065 mWifiRunning = true; 7066 if (mWifiRunningTimer == null) { 7067 mWifiRunningTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, WIFI_RUNNING, 7068 mBsi.mWifiRunningTimers, mBsi.mOnBatteryTimeBase); 7069 } 7070 mWifiRunningTimer.startRunningLocked(elapsedRealtimeMs); 7071 } 7072 } 7073 7074 @Override noteWifiStoppedLocked(long elapsedRealtimeMs)7075 public void noteWifiStoppedLocked(long elapsedRealtimeMs) { 7076 if (mWifiRunning) { 7077 mWifiRunning = false; 7078 mWifiRunningTimer.stopRunningLocked(elapsedRealtimeMs); 7079 } 7080 } 7081 7082 @Override noteFullWifiLockAcquiredLocked(long elapsedRealtimeMs)7083 public void noteFullWifiLockAcquiredLocked(long elapsedRealtimeMs) { 7084 if (!mFullWifiLockOut) { 7085 mFullWifiLockOut = true; 7086 if (mFullWifiLockTimer == null) { 7087 mFullWifiLockTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, FULL_WIFI_LOCK, 7088 mBsi.mFullWifiLockTimers, mBsi.mOnBatteryTimeBase); 7089 } 7090 mFullWifiLockTimer.startRunningLocked(elapsedRealtimeMs); 7091 } 7092 } 7093 7094 @Override noteFullWifiLockReleasedLocked(long elapsedRealtimeMs)7095 public void noteFullWifiLockReleasedLocked(long elapsedRealtimeMs) { 7096 if (mFullWifiLockOut) { 7097 mFullWifiLockOut = false; 7098 mFullWifiLockTimer.stopRunningLocked(elapsedRealtimeMs); 7099 } 7100 } 7101 7102 @Override noteWifiScanStartedLocked(long elapsedRealtimeMs)7103 public void noteWifiScanStartedLocked(long elapsedRealtimeMs) { 7104 if (!mWifiScanStarted) { 7105 mWifiScanStarted = true; 7106 if (mWifiScanTimer == null) { 7107 mWifiScanTimer = new DualTimer(mBsi.mClocks, Uid.this, WIFI_SCAN, 7108 mBsi.mWifiScanTimers, mBsi.mOnBatteryTimeBase, 7109 mOnBatteryBackgroundTimeBase); 7110 } 7111 mWifiScanTimer.startRunningLocked(elapsedRealtimeMs); 7112 } 7113 } 7114 7115 @Override noteWifiScanStoppedLocked(long elapsedRealtimeMs)7116 public void noteWifiScanStoppedLocked(long elapsedRealtimeMs) { 7117 if (mWifiScanStarted) { 7118 mWifiScanStarted = false; 7119 mWifiScanTimer.stopRunningLocked(elapsedRealtimeMs); 7120 } 7121 } 7122 7123 @Override noteWifiBatchedScanStartedLocked(int csph, long elapsedRealtimeMs)7124 public void noteWifiBatchedScanStartedLocked(int csph, long elapsedRealtimeMs) { 7125 int bin = 0; 7126 while (csph > 8 && bin < NUM_WIFI_BATCHED_SCAN_BINS-1) { 7127 csph = csph >> 3; 7128 bin++; 7129 } 7130 7131 if (mWifiBatchedScanBinStarted == bin) return; 7132 7133 if (mWifiBatchedScanBinStarted != NO_BATCHED_SCAN_STARTED) { 7134 mWifiBatchedScanTimer[mWifiBatchedScanBinStarted]. 7135 stopRunningLocked(elapsedRealtimeMs); 7136 } 7137 mWifiBatchedScanBinStarted = bin; 7138 if (mWifiBatchedScanTimer[bin] == null) { 7139 makeWifiBatchedScanBin(bin, null); 7140 } 7141 mWifiBatchedScanTimer[bin].startRunningLocked(elapsedRealtimeMs); 7142 } 7143 7144 @Override noteWifiBatchedScanStoppedLocked(long elapsedRealtimeMs)7145 public void noteWifiBatchedScanStoppedLocked(long elapsedRealtimeMs) { 7146 if (mWifiBatchedScanBinStarted != NO_BATCHED_SCAN_STARTED) { 7147 mWifiBatchedScanTimer[mWifiBatchedScanBinStarted]. 7148 stopRunningLocked(elapsedRealtimeMs); 7149 mWifiBatchedScanBinStarted = NO_BATCHED_SCAN_STARTED; 7150 } 7151 } 7152 7153 @Override noteWifiMulticastEnabledLocked(long elapsedRealtimeMs)7154 public void noteWifiMulticastEnabledLocked(long elapsedRealtimeMs) { 7155 if (!mWifiMulticastEnabled) { 7156 mWifiMulticastEnabled = true; 7157 if (mWifiMulticastTimer == null) { 7158 mWifiMulticastTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, 7159 WIFI_MULTICAST_ENABLED, mBsi.mWifiMulticastTimers, mBsi.mOnBatteryTimeBase); 7160 } 7161 mWifiMulticastTimer.startRunningLocked(elapsedRealtimeMs); 7162 StatsLog.write_non_chained( 7163 StatsLog.WIFI_MULTICAST_LOCK_STATE_CHANGED, getUid(), null, 7164 StatsLog.WIFI_MULTICAST_LOCK_STATE_CHANGED__STATE__ON); 7165 } 7166 } 7167 7168 @Override noteWifiMulticastDisabledLocked(long elapsedRealtimeMs)7169 public void noteWifiMulticastDisabledLocked(long elapsedRealtimeMs) { 7170 if (mWifiMulticastEnabled) { 7171 mWifiMulticastEnabled = false; 7172 mWifiMulticastTimer.stopRunningLocked(elapsedRealtimeMs); 7173 StatsLog.write_non_chained( 7174 StatsLog.WIFI_MULTICAST_LOCK_STATE_CHANGED, getUid(), null, 7175 StatsLog.WIFI_MULTICAST_LOCK_STATE_CHANGED__STATE__OFF); 7176 } 7177 } 7178 7179 @Override getWifiControllerActivity()7180 public ControllerActivityCounter getWifiControllerActivity() { 7181 return mWifiControllerActivity; 7182 } 7183 7184 @Override getBluetoothControllerActivity()7185 public ControllerActivityCounter getBluetoothControllerActivity() { 7186 return mBluetoothControllerActivity; 7187 } 7188 7189 @Override getModemControllerActivity()7190 public ControllerActivityCounter getModemControllerActivity() { 7191 return mModemControllerActivity; 7192 } 7193 getOrCreateWifiControllerActivityLocked()7194 public ControllerActivityCounterImpl getOrCreateWifiControllerActivityLocked() { 7195 if (mWifiControllerActivity == null) { 7196 mWifiControllerActivity = new ControllerActivityCounterImpl(mBsi.mOnBatteryTimeBase, 7197 NUM_BT_TX_LEVELS); 7198 } 7199 return mWifiControllerActivity; 7200 } 7201 getOrCreateBluetoothControllerActivityLocked()7202 public ControllerActivityCounterImpl getOrCreateBluetoothControllerActivityLocked() { 7203 if (mBluetoothControllerActivity == null) { 7204 mBluetoothControllerActivity = new ControllerActivityCounterImpl(mBsi.mOnBatteryTimeBase, 7205 NUM_BT_TX_LEVELS); 7206 } 7207 return mBluetoothControllerActivity; 7208 } 7209 getOrCreateModemControllerActivityLocked()7210 public ControllerActivityCounterImpl getOrCreateModemControllerActivityLocked() { 7211 if (mModemControllerActivity == null) { 7212 mModemControllerActivity = new ControllerActivityCounterImpl(mBsi.mOnBatteryTimeBase, 7213 ModemActivityInfo.TX_POWER_LEVELS); 7214 } 7215 return mModemControllerActivity; 7216 } 7217 createAudioTurnedOnTimerLocked()7218 public StopwatchTimer createAudioTurnedOnTimerLocked() { 7219 if (mAudioTurnedOnTimer == null) { 7220 mAudioTurnedOnTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, AUDIO_TURNED_ON, 7221 mBsi.mAudioTurnedOnTimers, mBsi.mOnBatteryTimeBase); 7222 } 7223 return mAudioTurnedOnTimer; 7224 } 7225 noteAudioTurnedOnLocked(long elapsedRealtimeMs)7226 public void noteAudioTurnedOnLocked(long elapsedRealtimeMs) { 7227 createAudioTurnedOnTimerLocked().startRunningLocked(elapsedRealtimeMs); 7228 } 7229 noteAudioTurnedOffLocked(long elapsedRealtimeMs)7230 public void noteAudioTurnedOffLocked(long elapsedRealtimeMs) { 7231 if (mAudioTurnedOnTimer != null) { 7232 mAudioTurnedOnTimer.stopRunningLocked(elapsedRealtimeMs); 7233 } 7234 } 7235 noteResetAudioLocked(long elapsedRealtimeMs)7236 public void noteResetAudioLocked(long elapsedRealtimeMs) { 7237 if (mAudioTurnedOnTimer != null) { 7238 mAudioTurnedOnTimer.stopAllRunningLocked(elapsedRealtimeMs); 7239 } 7240 } 7241 createVideoTurnedOnTimerLocked()7242 public StopwatchTimer createVideoTurnedOnTimerLocked() { 7243 if (mVideoTurnedOnTimer == null) { 7244 mVideoTurnedOnTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, VIDEO_TURNED_ON, 7245 mBsi.mVideoTurnedOnTimers, mBsi.mOnBatteryTimeBase); 7246 } 7247 return mVideoTurnedOnTimer; 7248 } 7249 noteVideoTurnedOnLocked(long elapsedRealtimeMs)7250 public void noteVideoTurnedOnLocked(long elapsedRealtimeMs) { 7251 createVideoTurnedOnTimerLocked().startRunningLocked(elapsedRealtimeMs); 7252 } 7253 noteVideoTurnedOffLocked(long elapsedRealtimeMs)7254 public void noteVideoTurnedOffLocked(long elapsedRealtimeMs) { 7255 if (mVideoTurnedOnTimer != null) { 7256 mVideoTurnedOnTimer.stopRunningLocked(elapsedRealtimeMs); 7257 } 7258 } 7259 noteResetVideoLocked(long elapsedRealtimeMs)7260 public void noteResetVideoLocked(long elapsedRealtimeMs) { 7261 if (mVideoTurnedOnTimer != null) { 7262 mVideoTurnedOnTimer.stopAllRunningLocked(elapsedRealtimeMs); 7263 } 7264 } 7265 createFlashlightTurnedOnTimerLocked()7266 public StopwatchTimer createFlashlightTurnedOnTimerLocked() { 7267 if (mFlashlightTurnedOnTimer == null) { 7268 mFlashlightTurnedOnTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, 7269 FLASHLIGHT_TURNED_ON, mBsi.mFlashlightTurnedOnTimers, mBsi.mOnBatteryTimeBase); 7270 } 7271 return mFlashlightTurnedOnTimer; 7272 } 7273 noteFlashlightTurnedOnLocked(long elapsedRealtimeMs)7274 public void noteFlashlightTurnedOnLocked(long elapsedRealtimeMs) { 7275 createFlashlightTurnedOnTimerLocked().startRunningLocked(elapsedRealtimeMs); 7276 } 7277 noteFlashlightTurnedOffLocked(long elapsedRealtimeMs)7278 public void noteFlashlightTurnedOffLocked(long elapsedRealtimeMs) { 7279 if (mFlashlightTurnedOnTimer != null) { 7280 mFlashlightTurnedOnTimer.stopRunningLocked(elapsedRealtimeMs); 7281 } 7282 } 7283 noteResetFlashlightLocked(long elapsedRealtimeMs)7284 public void noteResetFlashlightLocked(long elapsedRealtimeMs) { 7285 if (mFlashlightTurnedOnTimer != null) { 7286 mFlashlightTurnedOnTimer.stopAllRunningLocked(elapsedRealtimeMs); 7287 } 7288 } 7289 createCameraTurnedOnTimerLocked()7290 public StopwatchTimer createCameraTurnedOnTimerLocked() { 7291 if (mCameraTurnedOnTimer == null) { 7292 mCameraTurnedOnTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, CAMERA_TURNED_ON, 7293 mBsi.mCameraTurnedOnTimers, mBsi.mOnBatteryTimeBase); 7294 } 7295 return mCameraTurnedOnTimer; 7296 } 7297 noteCameraTurnedOnLocked(long elapsedRealtimeMs)7298 public void noteCameraTurnedOnLocked(long elapsedRealtimeMs) { 7299 createCameraTurnedOnTimerLocked().startRunningLocked(elapsedRealtimeMs); 7300 } 7301 noteCameraTurnedOffLocked(long elapsedRealtimeMs)7302 public void noteCameraTurnedOffLocked(long elapsedRealtimeMs) { 7303 if (mCameraTurnedOnTimer != null) { 7304 mCameraTurnedOnTimer.stopRunningLocked(elapsedRealtimeMs); 7305 } 7306 } 7307 noteResetCameraLocked(long elapsedRealtimeMs)7308 public void noteResetCameraLocked(long elapsedRealtimeMs) { 7309 if (mCameraTurnedOnTimer != null) { 7310 mCameraTurnedOnTimer.stopAllRunningLocked(elapsedRealtimeMs); 7311 } 7312 } 7313 createForegroundActivityTimerLocked()7314 public StopwatchTimer createForegroundActivityTimerLocked() { 7315 if (mForegroundActivityTimer == null) { 7316 mForegroundActivityTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, 7317 FOREGROUND_ACTIVITY, null, mBsi.mOnBatteryTimeBase); 7318 } 7319 return mForegroundActivityTimer; 7320 } 7321 createForegroundServiceTimerLocked()7322 public StopwatchTimer createForegroundServiceTimerLocked() { 7323 if (mForegroundServiceTimer == null) { 7324 mForegroundServiceTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, 7325 FOREGROUND_SERVICE, null, mBsi.mOnBatteryTimeBase); 7326 } 7327 return mForegroundServiceTimer; 7328 } 7329 createAggregatedPartialWakelockTimerLocked()7330 public DualTimer createAggregatedPartialWakelockTimerLocked() { 7331 if (mAggregatedPartialWakelockTimer == null) { 7332 mAggregatedPartialWakelockTimer = new DualTimer(mBsi.mClocks, this, 7333 AGGREGATED_WAKE_TYPE_PARTIAL, null, 7334 mBsi.mOnBatteryScreenOffTimeBase, mOnBatteryScreenOffBackgroundTimeBase); 7335 } 7336 return mAggregatedPartialWakelockTimer; 7337 } 7338 createBluetoothScanTimerLocked()7339 public DualTimer createBluetoothScanTimerLocked() { 7340 if (mBluetoothScanTimer == null) { 7341 mBluetoothScanTimer = new DualTimer(mBsi.mClocks, Uid.this, BLUETOOTH_SCAN_ON, 7342 mBsi.mBluetoothScanOnTimers, mBsi.mOnBatteryTimeBase, 7343 mOnBatteryBackgroundTimeBase); 7344 } 7345 return mBluetoothScanTimer; 7346 } 7347 createBluetoothUnoptimizedScanTimerLocked()7348 public DualTimer createBluetoothUnoptimizedScanTimerLocked() { 7349 if (mBluetoothUnoptimizedScanTimer == null) { 7350 mBluetoothUnoptimizedScanTimer = new DualTimer(mBsi.mClocks, Uid.this, 7351 BLUETOOTH_UNOPTIMIZED_SCAN_ON, null, 7352 mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase); 7353 } 7354 return mBluetoothUnoptimizedScanTimer; 7355 } 7356 noteBluetoothScanStartedLocked(long elapsedRealtimeMs, boolean isUnoptimized)7357 public void noteBluetoothScanStartedLocked(long elapsedRealtimeMs, 7358 boolean isUnoptimized) { 7359 createBluetoothScanTimerLocked().startRunningLocked(elapsedRealtimeMs); 7360 if (isUnoptimized) { 7361 createBluetoothUnoptimizedScanTimerLocked().startRunningLocked(elapsedRealtimeMs); 7362 } 7363 } 7364 noteBluetoothScanStoppedLocked(long elapsedRealtimeMs, boolean isUnoptimized)7365 public void noteBluetoothScanStoppedLocked(long elapsedRealtimeMs, boolean isUnoptimized) { 7366 if (mBluetoothScanTimer != null) { 7367 mBluetoothScanTimer.stopRunningLocked(elapsedRealtimeMs); 7368 } 7369 if (isUnoptimized && mBluetoothUnoptimizedScanTimer != null) { 7370 mBluetoothUnoptimizedScanTimer.stopRunningLocked(elapsedRealtimeMs); 7371 } 7372 } 7373 noteResetBluetoothScanLocked(long elapsedRealtimeMs)7374 public void noteResetBluetoothScanLocked(long elapsedRealtimeMs) { 7375 if (mBluetoothScanTimer != null) { 7376 mBluetoothScanTimer.stopAllRunningLocked(elapsedRealtimeMs); 7377 } 7378 if (mBluetoothUnoptimizedScanTimer != null) { 7379 mBluetoothUnoptimizedScanTimer.stopAllRunningLocked(elapsedRealtimeMs); 7380 } 7381 } 7382 createBluetoothScanResultCounterLocked()7383 public Counter createBluetoothScanResultCounterLocked() { 7384 if (mBluetoothScanResultCounter == null) { 7385 mBluetoothScanResultCounter = new Counter(mBsi.mOnBatteryTimeBase); 7386 } 7387 return mBluetoothScanResultCounter; 7388 } 7389 createBluetoothScanResultBgCounterLocked()7390 public Counter createBluetoothScanResultBgCounterLocked() { 7391 if (mBluetoothScanResultBgCounter == null) { 7392 mBluetoothScanResultBgCounter = new Counter(mOnBatteryBackgroundTimeBase); 7393 } 7394 return mBluetoothScanResultBgCounter; 7395 } 7396 noteBluetoothScanResultsLocked(int numNewResults)7397 public void noteBluetoothScanResultsLocked(int numNewResults) { 7398 createBluetoothScanResultCounterLocked().addAtomic(numNewResults); 7399 // Uses background timebase, so the count will only be incremented if uid in background. 7400 createBluetoothScanResultBgCounterLocked().addAtomic(numNewResults); 7401 } 7402 7403 @Override noteActivityResumedLocked(long elapsedRealtimeMs)7404 public void noteActivityResumedLocked(long elapsedRealtimeMs) { 7405 // We always start, since we want multiple foreground PIDs to nest 7406 createForegroundActivityTimerLocked().startRunningLocked(elapsedRealtimeMs); 7407 } 7408 7409 @Override noteActivityPausedLocked(long elapsedRealtimeMs)7410 public void noteActivityPausedLocked(long elapsedRealtimeMs) { 7411 if (mForegroundActivityTimer != null) { 7412 mForegroundActivityTimer.stopRunningLocked(elapsedRealtimeMs); 7413 } 7414 } 7415 noteForegroundServiceResumedLocked(long elapsedRealtimeMs)7416 public void noteForegroundServiceResumedLocked(long elapsedRealtimeMs) { 7417 createForegroundServiceTimerLocked().startRunningLocked(elapsedRealtimeMs); 7418 } 7419 noteForegroundServicePausedLocked(long elapsedRealtimeMs)7420 public void noteForegroundServicePausedLocked(long elapsedRealtimeMs) { 7421 if (mForegroundServiceTimer != null) { 7422 mForegroundServiceTimer.stopRunningLocked(elapsedRealtimeMs); 7423 } 7424 } 7425 createVibratorOnTimerLocked()7426 public BatchTimer createVibratorOnTimerLocked() { 7427 if (mVibratorOnTimer == null) { 7428 mVibratorOnTimer = new BatchTimer(mBsi.mClocks, Uid.this, VIBRATOR_ON, 7429 mBsi.mOnBatteryTimeBase); 7430 } 7431 return mVibratorOnTimer; 7432 } 7433 noteVibratorOnLocked(long durationMillis)7434 public void noteVibratorOnLocked(long durationMillis) { 7435 createVibratorOnTimerLocked().addDuration(mBsi, durationMillis); 7436 } 7437 noteVibratorOffLocked()7438 public void noteVibratorOffLocked() { 7439 if (mVibratorOnTimer != null) { 7440 mVibratorOnTimer.abortLastDuration(mBsi); 7441 } 7442 } 7443 7444 @Override getWifiRunningTime(long elapsedRealtimeUs, int which)7445 public long getWifiRunningTime(long elapsedRealtimeUs, int which) { 7446 if (mWifiRunningTimer == null) { 7447 return 0; 7448 } 7449 return mWifiRunningTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 7450 } 7451 7452 @Override getFullWifiLockTime(long elapsedRealtimeUs, int which)7453 public long getFullWifiLockTime(long elapsedRealtimeUs, int which) { 7454 if (mFullWifiLockTimer == null) { 7455 return 0; 7456 } 7457 return mFullWifiLockTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 7458 } 7459 7460 @Override getWifiScanTime(long elapsedRealtimeUs, int which)7461 public long getWifiScanTime(long elapsedRealtimeUs, int which) { 7462 if (mWifiScanTimer == null) { 7463 return 0; 7464 } 7465 return mWifiScanTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 7466 } 7467 7468 @Override getWifiScanCount(int which)7469 public int getWifiScanCount(int which) { 7470 if (mWifiScanTimer == null) { 7471 return 0; 7472 } 7473 return mWifiScanTimer.getCountLocked(which); 7474 } 7475 7476 @Override getWifiScanTimer()7477 public Timer getWifiScanTimer() { 7478 return mWifiScanTimer; 7479 } 7480 7481 @Override getWifiScanBackgroundCount(int which)7482 public int getWifiScanBackgroundCount(int which) { 7483 if (mWifiScanTimer == null || mWifiScanTimer.getSubTimer() == null) { 7484 return 0; 7485 } 7486 return mWifiScanTimer.getSubTimer().getCountLocked(which); 7487 } 7488 7489 @Override getWifiScanActualTime(final long elapsedRealtimeUs)7490 public long getWifiScanActualTime(final long elapsedRealtimeUs) { 7491 if (mWifiScanTimer == null) { 7492 return 0; 7493 } 7494 final long elapsedRealtimeMs = (elapsedRealtimeUs + 500) / 1000; 7495 return mWifiScanTimer.getTotalDurationMsLocked(elapsedRealtimeMs) * 1000; 7496 } 7497 7498 @Override getWifiScanBackgroundTime(final long elapsedRealtimeUs)7499 public long getWifiScanBackgroundTime(final long elapsedRealtimeUs) { 7500 if (mWifiScanTimer == null || mWifiScanTimer.getSubTimer() == null) { 7501 return 0; 7502 } 7503 final long elapsedRealtimeMs = (elapsedRealtimeUs + 500) / 1000; 7504 return mWifiScanTimer.getSubTimer().getTotalDurationMsLocked(elapsedRealtimeMs) * 1000; 7505 } 7506 7507 @Override getWifiScanBackgroundTimer()7508 public Timer getWifiScanBackgroundTimer() { 7509 if (mWifiScanTimer == null) { 7510 return null; 7511 } 7512 return mWifiScanTimer.getSubTimer(); 7513 } 7514 7515 @Override getWifiBatchedScanTime(int csphBin, long elapsedRealtimeUs, int which)7516 public long getWifiBatchedScanTime(int csphBin, long elapsedRealtimeUs, int which) { 7517 if (csphBin < 0 || csphBin >= NUM_WIFI_BATCHED_SCAN_BINS) return 0; 7518 if (mWifiBatchedScanTimer[csphBin] == null) { 7519 return 0; 7520 } 7521 return mWifiBatchedScanTimer[csphBin].getTotalTimeLocked(elapsedRealtimeUs, which); 7522 } 7523 7524 @Override getWifiBatchedScanCount(int csphBin, int which)7525 public int getWifiBatchedScanCount(int csphBin, int which) { 7526 if (csphBin < 0 || csphBin >= NUM_WIFI_BATCHED_SCAN_BINS) return 0; 7527 if (mWifiBatchedScanTimer[csphBin] == null) { 7528 return 0; 7529 } 7530 return mWifiBatchedScanTimer[csphBin].getCountLocked(which); 7531 } 7532 7533 @Override getWifiMulticastTime(long elapsedRealtimeUs, int which)7534 public long getWifiMulticastTime(long elapsedRealtimeUs, int which) { 7535 if (mWifiMulticastTimer == null) { 7536 return 0; 7537 } 7538 return mWifiMulticastTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 7539 } 7540 7541 @Override getAudioTurnedOnTimer()7542 public Timer getAudioTurnedOnTimer() { 7543 return mAudioTurnedOnTimer; 7544 } 7545 7546 @Override getVideoTurnedOnTimer()7547 public Timer getVideoTurnedOnTimer() { 7548 return mVideoTurnedOnTimer; 7549 } 7550 7551 @Override getFlashlightTurnedOnTimer()7552 public Timer getFlashlightTurnedOnTimer() { 7553 return mFlashlightTurnedOnTimer; 7554 } 7555 7556 @Override getCameraTurnedOnTimer()7557 public Timer getCameraTurnedOnTimer() { 7558 return mCameraTurnedOnTimer; 7559 } 7560 7561 @Override getForegroundActivityTimer()7562 public Timer getForegroundActivityTimer() { 7563 return mForegroundActivityTimer; 7564 } 7565 7566 @Override getForegroundServiceTimer()7567 public Timer getForegroundServiceTimer() { 7568 return mForegroundServiceTimer; 7569 } 7570 7571 @Override getBluetoothScanTimer()7572 public Timer getBluetoothScanTimer() { 7573 return mBluetoothScanTimer; 7574 } 7575 7576 @Override getBluetoothScanBackgroundTimer()7577 public Timer getBluetoothScanBackgroundTimer() { 7578 if (mBluetoothScanTimer == null) { 7579 return null; 7580 } 7581 return mBluetoothScanTimer.getSubTimer(); 7582 } 7583 7584 @Override getBluetoothUnoptimizedScanTimer()7585 public Timer getBluetoothUnoptimizedScanTimer() { 7586 return mBluetoothUnoptimizedScanTimer; 7587 } 7588 7589 @Override getBluetoothUnoptimizedScanBackgroundTimer()7590 public Timer getBluetoothUnoptimizedScanBackgroundTimer() { 7591 if (mBluetoothUnoptimizedScanTimer == null) { 7592 return null; 7593 } 7594 return mBluetoothUnoptimizedScanTimer.getSubTimer(); 7595 } 7596 7597 @Override getBluetoothScanResultCounter()7598 public Counter getBluetoothScanResultCounter() { 7599 return mBluetoothScanResultCounter; 7600 } 7601 7602 @Override getBluetoothScanResultBgCounter()7603 public Counter getBluetoothScanResultBgCounter() { 7604 return mBluetoothScanResultBgCounter; 7605 } 7606 makeProcessState(int i, Parcel in)7607 void makeProcessState(int i, Parcel in) { 7608 if (i < 0 || i >= NUM_PROCESS_STATE) return; 7609 7610 if (in == null) { 7611 mProcessStateTimer[i] = new StopwatchTimer(mBsi.mClocks, this, PROCESS_STATE, null, 7612 mBsi.mOnBatteryTimeBase); 7613 } else { 7614 mProcessStateTimer[i] = new StopwatchTimer(mBsi.mClocks, this, PROCESS_STATE, null, 7615 mBsi.mOnBatteryTimeBase, in); 7616 } 7617 } 7618 7619 @Override getProcessStateTime(int state, long elapsedRealtimeUs, int which)7620 public long getProcessStateTime(int state, long elapsedRealtimeUs, int which) { 7621 if (state < 0 || state >= NUM_PROCESS_STATE) return 0; 7622 if (mProcessStateTimer[state] == null) { 7623 return 0; 7624 } 7625 return mProcessStateTimer[state].getTotalTimeLocked(elapsedRealtimeUs, which); 7626 } 7627 7628 @Override getProcessStateTimer(int state)7629 public Timer getProcessStateTimer(int state) { 7630 if (state < 0 || state >= NUM_PROCESS_STATE) return null; 7631 return mProcessStateTimer[state]; 7632 } 7633 7634 @Override getVibratorOnTimer()7635 public Timer getVibratorOnTimer() { 7636 return mVibratorOnTimer; 7637 } 7638 7639 @Override noteUserActivityLocked(int type)7640 public void noteUserActivityLocked(int type) { 7641 if (mUserActivityCounters == null) { 7642 initUserActivityLocked(); 7643 } 7644 if (type >= 0 && type < NUM_USER_ACTIVITY_TYPES) { 7645 mUserActivityCounters[type].stepAtomic(); 7646 } else { 7647 Slog.w(TAG, "Unknown user activity type " + type + " was specified.", 7648 new Throwable()); 7649 } 7650 } 7651 7652 @Override hasUserActivity()7653 public boolean hasUserActivity() { 7654 return mUserActivityCounters != null; 7655 } 7656 7657 @Override getUserActivityCount(int type, int which)7658 public int getUserActivityCount(int type, int which) { 7659 if (mUserActivityCounters == null) { 7660 return 0; 7661 } 7662 return mUserActivityCounters[type].getCountLocked(which); 7663 } 7664 makeWifiBatchedScanBin(int i, Parcel in)7665 void makeWifiBatchedScanBin(int i, Parcel in) { 7666 if (i < 0 || i >= NUM_WIFI_BATCHED_SCAN_BINS) return; 7667 7668 ArrayList<StopwatchTimer> collected = mBsi.mWifiBatchedScanTimers.get(i); 7669 if (collected == null) { 7670 collected = new ArrayList<StopwatchTimer>(); 7671 mBsi.mWifiBatchedScanTimers.put(i, collected); 7672 } 7673 if (in == null) { 7674 mWifiBatchedScanTimer[i] = new StopwatchTimer(mBsi.mClocks, this, WIFI_BATCHED_SCAN, 7675 collected, mBsi.mOnBatteryTimeBase); 7676 } else { 7677 mWifiBatchedScanTimer[i] = new StopwatchTimer(mBsi.mClocks, this, WIFI_BATCHED_SCAN, 7678 collected, mBsi.mOnBatteryTimeBase, in); 7679 } 7680 } 7681 7682 initUserActivityLocked()7683 void initUserActivityLocked() { 7684 mUserActivityCounters = new Counter[NUM_USER_ACTIVITY_TYPES]; 7685 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) { 7686 mUserActivityCounters[i] = new Counter(mBsi.mOnBatteryTimeBase); 7687 } 7688 } 7689 noteNetworkActivityLocked(int type, long deltaBytes, long deltaPackets)7690 void noteNetworkActivityLocked(int type, long deltaBytes, long deltaPackets) { 7691 if (mNetworkByteActivityCounters == null) { 7692 initNetworkActivityLocked(); 7693 } 7694 if (type >= 0 && type < NUM_NETWORK_ACTIVITY_TYPES) { 7695 mNetworkByteActivityCounters[type].addCountLocked(deltaBytes); 7696 mNetworkPacketActivityCounters[type].addCountLocked(deltaPackets); 7697 } else { 7698 Slog.w(TAG, "Unknown network activity type " + type + " was specified.", 7699 new Throwable()); 7700 } 7701 } 7702 noteMobileRadioActiveTimeLocked(long batteryUptime)7703 void noteMobileRadioActiveTimeLocked(long batteryUptime) { 7704 if (mNetworkByteActivityCounters == null) { 7705 initNetworkActivityLocked(); 7706 } 7707 mMobileRadioActiveTime.addCountLocked(batteryUptime); 7708 mMobileRadioActiveCount.addCountLocked(1); 7709 } 7710 7711 @Override hasNetworkActivity()7712 public boolean hasNetworkActivity() { 7713 return mNetworkByteActivityCounters != null; 7714 } 7715 7716 @Override getNetworkActivityBytes(int type, int which)7717 public long getNetworkActivityBytes(int type, int which) { 7718 if (mNetworkByteActivityCounters != null && type >= 0 7719 && type < mNetworkByteActivityCounters.length) { 7720 return mNetworkByteActivityCounters[type].getCountLocked(which); 7721 } else { 7722 return 0; 7723 } 7724 } 7725 7726 @Override getNetworkActivityPackets(int type, int which)7727 public long getNetworkActivityPackets(int type, int which) { 7728 if (mNetworkPacketActivityCounters != null && type >= 0 7729 && type < mNetworkPacketActivityCounters.length) { 7730 return mNetworkPacketActivityCounters[type].getCountLocked(which); 7731 } else { 7732 return 0; 7733 } 7734 } 7735 7736 @Override getMobileRadioActiveTime(int which)7737 public long getMobileRadioActiveTime(int which) { 7738 return mMobileRadioActiveTime != null 7739 ? mMobileRadioActiveTime.getCountLocked(which) : 0; 7740 } 7741 7742 @Override getMobileRadioActiveCount(int which)7743 public int getMobileRadioActiveCount(int which) { 7744 return mMobileRadioActiveCount != null 7745 ? (int)mMobileRadioActiveCount.getCountLocked(which) : 0; 7746 } 7747 7748 @Override getUserCpuTimeUs(int which)7749 public long getUserCpuTimeUs(int which) { 7750 return mUserCpuTime.getCountLocked(which); 7751 } 7752 7753 @Override getSystemCpuTimeUs(int which)7754 public long getSystemCpuTimeUs(int which) { 7755 return mSystemCpuTime.getCountLocked(which); 7756 } 7757 7758 @Override getTimeAtCpuSpeed(int cluster, int step, int which)7759 public long getTimeAtCpuSpeed(int cluster, int step, int which) { 7760 if (mCpuClusterSpeedTimesUs != null) { 7761 if (cluster >= 0 && cluster < mCpuClusterSpeedTimesUs.length) { 7762 final LongSamplingCounter[] cpuSpeedTimesUs = mCpuClusterSpeedTimesUs[cluster]; 7763 if (cpuSpeedTimesUs != null) { 7764 if (step >= 0 && step < cpuSpeedTimesUs.length) { 7765 final LongSamplingCounter c = cpuSpeedTimesUs[step]; 7766 if (c != null) { 7767 return c.getCountLocked(which); 7768 } 7769 } 7770 } 7771 } 7772 } 7773 return 0; 7774 } 7775 noteMobileRadioApWakeupLocked()7776 public void noteMobileRadioApWakeupLocked() { 7777 if (mMobileRadioApWakeupCount == null) { 7778 mMobileRadioApWakeupCount = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); 7779 } 7780 mMobileRadioApWakeupCount.addCountLocked(1); 7781 } 7782 7783 @Override getMobileRadioApWakeupCount(int which)7784 public long getMobileRadioApWakeupCount(int which) { 7785 if (mMobileRadioApWakeupCount != null) { 7786 return mMobileRadioApWakeupCount.getCountLocked(which); 7787 } 7788 return 0; 7789 } 7790 noteWifiRadioApWakeupLocked()7791 public void noteWifiRadioApWakeupLocked() { 7792 if (mWifiRadioApWakeupCount == null) { 7793 mWifiRadioApWakeupCount = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); 7794 } 7795 mWifiRadioApWakeupCount.addCountLocked(1); 7796 } 7797 7798 @Override getWifiRadioApWakeupCount(int which)7799 public long getWifiRadioApWakeupCount(int which) { 7800 if (mWifiRadioApWakeupCount != null) { 7801 return mWifiRadioApWakeupCount.getCountLocked(which); 7802 } 7803 return 0; 7804 } 7805 7806 @Override getDeferredJobsCheckinLineLocked(StringBuilder sb, int which)7807 public void getDeferredJobsCheckinLineLocked(StringBuilder sb, int which) { 7808 sb.setLength(0); 7809 final int deferredEventCount = mJobsDeferredEventCount.getCountLocked(which); 7810 if (deferredEventCount == 0) { 7811 return; 7812 } 7813 final int deferredCount = mJobsDeferredCount.getCountLocked(which); 7814 final long totalLatency = mJobsFreshnessTimeMs.getCountLocked(which); 7815 sb.append(deferredEventCount); sb.append(','); 7816 sb.append(deferredCount); sb.append(','); 7817 sb.append(totalLatency); 7818 for (int i = 0; i < JOB_FRESHNESS_BUCKETS.length; i++) { 7819 if (mJobsFreshnessBuckets[i] == null) { 7820 sb.append(",0"); 7821 } else { 7822 sb.append(","); 7823 sb.append(mJobsFreshnessBuckets[i].getCountLocked(which)); 7824 } 7825 } 7826 } 7827 7828 @Override getDeferredJobsLineLocked(StringBuilder sb, int which)7829 public void getDeferredJobsLineLocked(StringBuilder sb, int which) { 7830 sb.setLength(0); 7831 final int deferredEventCount = mJobsDeferredEventCount.getCountLocked(which); 7832 if (deferredEventCount == 0) { 7833 return; 7834 } 7835 final int deferredCount = mJobsDeferredCount.getCountLocked(which); 7836 final long totalLatency = mJobsFreshnessTimeMs.getCountLocked(which); 7837 sb.append("times="); sb.append(deferredEventCount); sb.append(", "); 7838 sb.append("count="); sb.append(deferredCount); sb.append(", "); 7839 sb.append("totalLatencyMs="); sb.append(totalLatency); sb.append(", "); 7840 for (int i = 0; i < JOB_FRESHNESS_BUCKETS.length; i++) { 7841 sb.append("<"); sb.append(JOB_FRESHNESS_BUCKETS[i]); sb.append("ms="); 7842 if (mJobsFreshnessBuckets[i] == null) { 7843 sb.append("0"); 7844 } else { 7845 sb.append(mJobsFreshnessBuckets[i].getCountLocked(which)); 7846 } 7847 sb.append(" "); 7848 } 7849 } 7850 initNetworkActivityLocked()7851 void initNetworkActivityLocked() { 7852 mNetworkByteActivityCounters = new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES]; 7853 mNetworkPacketActivityCounters = new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES]; 7854 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 7855 mNetworkByteActivityCounters[i] = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); 7856 mNetworkPacketActivityCounters[i] = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); 7857 } 7858 mMobileRadioActiveTime = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); 7859 mMobileRadioActiveCount = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); 7860 } 7861 7862 /** 7863 * Clear all stats for this uid. Returns true if the uid is completely 7864 * inactive so can be dropped. 7865 */ 7866 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) reset(long uptime, long realtime)7867 public boolean reset(long uptime, long realtime) { 7868 boolean active = false; 7869 7870 mOnBatteryBackgroundTimeBase.init(uptime, realtime); 7871 mOnBatteryScreenOffBackgroundTimeBase.init(uptime, realtime); 7872 7873 if (mWifiRunningTimer != null) { 7874 active |= !mWifiRunningTimer.reset(false); 7875 active |= mWifiRunning; 7876 } 7877 if (mFullWifiLockTimer != null) { 7878 active |= !mFullWifiLockTimer.reset(false); 7879 active |= mFullWifiLockOut; 7880 } 7881 if (mWifiScanTimer != null) { 7882 active |= !mWifiScanTimer.reset(false); 7883 active |= mWifiScanStarted; 7884 } 7885 if (mWifiBatchedScanTimer != null) { 7886 for (int i = 0; i < NUM_WIFI_BATCHED_SCAN_BINS; i++) { 7887 if (mWifiBatchedScanTimer[i] != null) { 7888 active |= !mWifiBatchedScanTimer[i].reset(false); 7889 } 7890 } 7891 active |= (mWifiBatchedScanBinStarted != NO_BATCHED_SCAN_STARTED); 7892 } 7893 if (mWifiMulticastTimer != null) { 7894 active |= !mWifiMulticastTimer.reset(false); 7895 active |= mWifiMulticastEnabled; 7896 } 7897 7898 active |= !resetTimerIfNotNull(mAudioTurnedOnTimer, false); 7899 active |= !resetTimerIfNotNull(mVideoTurnedOnTimer, false); 7900 active |= !resetTimerIfNotNull(mFlashlightTurnedOnTimer, false); 7901 active |= !resetTimerIfNotNull(mCameraTurnedOnTimer, false); 7902 active |= !resetTimerIfNotNull(mForegroundActivityTimer, false); 7903 active |= !resetTimerIfNotNull(mForegroundServiceTimer, false); 7904 active |= !resetTimerIfNotNull(mAggregatedPartialWakelockTimer, false); 7905 active |= !resetTimerIfNotNull(mBluetoothScanTimer, false); 7906 active |= !resetTimerIfNotNull(mBluetoothUnoptimizedScanTimer, false); 7907 if (mBluetoothScanResultCounter != null) { 7908 mBluetoothScanResultCounter.reset(false); 7909 } 7910 if (mBluetoothScanResultBgCounter != null) { 7911 mBluetoothScanResultBgCounter.reset(false); 7912 } 7913 7914 if (mProcessStateTimer != null) { 7915 for (int i = 0; i < NUM_PROCESS_STATE; i++) { 7916 if (mProcessStateTimer[i] != null) { 7917 active |= !mProcessStateTimer[i].reset(false); 7918 } 7919 } 7920 active |= (mProcessState != ActivityManager.PROCESS_STATE_NONEXISTENT); 7921 } 7922 if (mVibratorOnTimer != null) { 7923 if (mVibratorOnTimer.reset(false)) { 7924 mVibratorOnTimer.detach(); 7925 mVibratorOnTimer = null; 7926 } else { 7927 active = true; 7928 } 7929 } 7930 7931 if (mUserActivityCounters != null) { 7932 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) { 7933 mUserActivityCounters[i].reset(false); 7934 } 7935 } 7936 7937 if (mNetworkByteActivityCounters != null) { 7938 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 7939 mNetworkByteActivityCounters[i].reset(false); 7940 mNetworkPacketActivityCounters[i].reset(false); 7941 } 7942 mMobileRadioActiveTime.reset(false); 7943 mMobileRadioActiveCount.reset(false); 7944 } 7945 7946 if (mWifiControllerActivity != null) { 7947 mWifiControllerActivity.reset(false); 7948 } 7949 7950 if (mBluetoothControllerActivity != null) { 7951 mBluetoothControllerActivity.reset(false); 7952 } 7953 7954 if (mModemControllerActivity != null) { 7955 mModemControllerActivity.reset(false); 7956 } 7957 7958 mUserCpuTime.reset(false); 7959 mSystemCpuTime.reset(false); 7960 7961 if (mCpuClusterSpeedTimesUs != null) { 7962 for (LongSamplingCounter[] speeds : mCpuClusterSpeedTimesUs) { 7963 if (speeds != null) { 7964 for (LongSamplingCounter speed : speeds) { 7965 if (speed != null) { 7966 speed.reset(false); 7967 } 7968 } 7969 } 7970 } 7971 } 7972 7973 if (mCpuFreqTimeMs != null) { 7974 mCpuFreqTimeMs.reset(false); 7975 } 7976 if (mScreenOffCpuFreqTimeMs != null) { 7977 mScreenOffCpuFreqTimeMs.reset(false); 7978 } 7979 7980 mCpuActiveTimeMs.reset(false); 7981 mCpuClusterTimesMs.reset(false); 7982 7983 if (mProcStateTimeMs != null) { 7984 for (LongSamplingCounterArray counters : mProcStateTimeMs) { 7985 if (counters != null) { 7986 counters.reset(false); 7987 } 7988 } 7989 } 7990 if (mProcStateScreenOffTimeMs != null) { 7991 for (LongSamplingCounterArray counters : mProcStateScreenOffTimeMs) { 7992 if (counters != null) { 7993 counters.reset(false); 7994 } 7995 } 7996 } 7997 7998 resetLongCounterIfNotNull(mMobileRadioApWakeupCount, false); 7999 resetLongCounterIfNotNull(mWifiRadioApWakeupCount, false); 8000 8001 final ArrayMap<String, Wakelock> wakeStats = mWakelockStats.getMap(); 8002 for (int iw=wakeStats.size()-1; iw>=0; iw--) { 8003 Wakelock wl = wakeStats.valueAt(iw); 8004 if (wl.reset()) { 8005 wakeStats.removeAt(iw); 8006 } else { 8007 active = true; 8008 } 8009 } 8010 mWakelockStats.cleanup(); 8011 final ArrayMap<String, DualTimer> syncStats = mSyncStats.getMap(); 8012 for (int is=syncStats.size()-1; is>=0; is--) { 8013 DualTimer timer = syncStats.valueAt(is); 8014 if (timer.reset(false)) { 8015 syncStats.removeAt(is); 8016 timer.detach(); 8017 } else { 8018 active = true; 8019 } 8020 } 8021 mSyncStats.cleanup(); 8022 final ArrayMap<String, DualTimer> jobStats = mJobStats.getMap(); 8023 for (int ij=jobStats.size()-1; ij>=0; ij--) { 8024 DualTimer timer = jobStats.valueAt(ij); 8025 if (timer.reset(false)) { 8026 jobStats.removeAt(ij); 8027 timer.detach(); 8028 } else { 8029 active = true; 8030 } 8031 } 8032 mJobStats.cleanup(); 8033 mJobCompletions.clear(); 8034 8035 mJobsDeferredEventCount.reset(false); 8036 mJobsDeferredCount.reset(false); 8037 mJobsFreshnessTimeMs.reset(false); 8038 for (int ij = 0; ij < JOB_FRESHNESS_BUCKETS.length; ij++) { 8039 if (mJobsFreshnessBuckets[ij] != null) { 8040 mJobsFreshnessBuckets[ij].reset(false); 8041 } 8042 } 8043 8044 for (int ise=mSensorStats.size()-1; ise>=0; ise--) { 8045 Sensor s = mSensorStats.valueAt(ise); 8046 if (s.reset()) { 8047 mSensorStats.removeAt(ise); 8048 } else { 8049 active = true; 8050 } 8051 } 8052 8053 for (int ip=mProcessStats.size()-1; ip>=0; ip--) { 8054 Proc proc = mProcessStats.valueAt(ip); 8055 proc.detach(); 8056 } 8057 mProcessStats.clear(); 8058 if (mPids.size() > 0) { 8059 for (int i=mPids.size()-1; i>=0; i--) { 8060 Pid pid = mPids.valueAt(i); 8061 if (pid.mWakeNesting > 0) { 8062 active = true; 8063 } else { 8064 mPids.removeAt(i); 8065 } 8066 } 8067 } 8068 if (mPackageStats.size() > 0) { 8069 Iterator<Map.Entry<String, Pkg>> it = mPackageStats.entrySet().iterator(); 8070 while (it.hasNext()) { 8071 Map.Entry<String, Pkg> pkgEntry = it.next(); 8072 Pkg p = pkgEntry.getValue(); 8073 p.detach(); 8074 if (p.mServiceStats.size() > 0) { 8075 Iterator<Map.Entry<String, Pkg.Serv>> it2 8076 = p.mServiceStats.entrySet().iterator(); 8077 while (it2.hasNext()) { 8078 Map.Entry<String, Pkg.Serv> servEntry = it2.next(); 8079 servEntry.getValue().detach(); 8080 } 8081 } 8082 } 8083 mPackageStats.clear(); 8084 } 8085 8086 mLastStepUserTime = mLastStepSystemTime = 0; 8087 mCurStepUserTime = mCurStepSystemTime = 0; 8088 8089 if (!active) { 8090 if (mWifiRunningTimer != null) { 8091 mWifiRunningTimer.detach(); 8092 } 8093 if (mFullWifiLockTimer != null) { 8094 mFullWifiLockTimer.detach(); 8095 } 8096 if (mWifiScanTimer != null) { 8097 mWifiScanTimer.detach(); 8098 } 8099 for (int i = 0; i < NUM_WIFI_BATCHED_SCAN_BINS; i++) { 8100 if (mWifiBatchedScanTimer[i] != null) { 8101 mWifiBatchedScanTimer[i].detach(); 8102 } 8103 } 8104 if (mWifiMulticastTimer != null) { 8105 mWifiMulticastTimer.detach(); 8106 } 8107 if (mAudioTurnedOnTimer != null) { 8108 mAudioTurnedOnTimer.detach(); 8109 mAudioTurnedOnTimer = null; 8110 } 8111 if (mVideoTurnedOnTimer != null) { 8112 mVideoTurnedOnTimer.detach(); 8113 mVideoTurnedOnTimer = null; 8114 } 8115 if (mFlashlightTurnedOnTimer != null) { 8116 mFlashlightTurnedOnTimer.detach(); 8117 mFlashlightTurnedOnTimer = null; 8118 } 8119 if (mCameraTurnedOnTimer != null) { 8120 mCameraTurnedOnTimer.detach(); 8121 mCameraTurnedOnTimer = null; 8122 } 8123 if (mForegroundActivityTimer != null) { 8124 mForegroundActivityTimer.detach(); 8125 mForegroundActivityTimer = null; 8126 } 8127 if (mForegroundServiceTimer != null) { 8128 mForegroundServiceTimer.detach(); 8129 mForegroundServiceTimer = null; 8130 } 8131 if (mAggregatedPartialWakelockTimer != null) { 8132 mAggregatedPartialWakelockTimer.detach(); 8133 mAggregatedPartialWakelockTimer = null; 8134 } 8135 if (mBluetoothScanTimer != null) { 8136 mBluetoothScanTimer.detach(); 8137 mBluetoothScanTimer = null; 8138 } 8139 if (mBluetoothUnoptimizedScanTimer != null) { 8140 mBluetoothUnoptimizedScanTimer.detach(); 8141 mBluetoothUnoptimizedScanTimer = null; 8142 } 8143 if (mBluetoothScanResultCounter != null) { 8144 mBluetoothScanResultCounter.detach(); 8145 mBluetoothScanResultCounter = null; 8146 } 8147 if (mBluetoothScanResultBgCounter != null) { 8148 mBluetoothScanResultBgCounter.detach(); 8149 mBluetoothScanResultBgCounter = null; 8150 } 8151 if (mUserActivityCounters != null) { 8152 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) { 8153 mUserActivityCounters[i].detach(); 8154 } 8155 } 8156 if (mNetworkByteActivityCounters != null) { 8157 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 8158 mNetworkByteActivityCounters[i].detach(); 8159 mNetworkPacketActivityCounters[i].detach(); 8160 } 8161 } 8162 8163 if (mWifiControllerActivity != null) { 8164 mWifiControllerActivity.detach(); 8165 } 8166 8167 if (mBluetoothControllerActivity != null) { 8168 mBluetoothControllerActivity.detach(); 8169 } 8170 8171 if (mModemControllerActivity != null) { 8172 mModemControllerActivity.detach(); 8173 } 8174 8175 mPids.clear(); 8176 8177 mUserCpuTime.detach(); 8178 mSystemCpuTime.detach(); 8179 8180 if (mCpuClusterSpeedTimesUs != null) { 8181 for (LongSamplingCounter[] cpuSpeeds : mCpuClusterSpeedTimesUs) { 8182 if (cpuSpeeds != null) { 8183 for (LongSamplingCounter c : cpuSpeeds) { 8184 if (c != null) { 8185 c.detach(); 8186 } 8187 } 8188 } 8189 } 8190 } 8191 8192 if (mCpuFreqTimeMs != null) { 8193 mCpuFreqTimeMs.detach(); 8194 } 8195 if (mScreenOffCpuFreqTimeMs != null) { 8196 mScreenOffCpuFreqTimeMs.detach(); 8197 } 8198 mCpuActiveTimeMs.detach(); 8199 mCpuClusterTimesMs.detach(); 8200 8201 if (mProcStateTimeMs != null) { 8202 for (LongSamplingCounterArray counters : mProcStateTimeMs) { 8203 if (counters != null) { 8204 counters.detach(); 8205 } 8206 } 8207 } 8208 if (mProcStateScreenOffTimeMs != null) { 8209 for (LongSamplingCounterArray counters : mProcStateScreenOffTimeMs) { 8210 if (counters != null) { 8211 counters.detach(); 8212 } 8213 } 8214 } 8215 detachLongCounterIfNotNull(mMobileRadioApWakeupCount); 8216 detachLongCounterIfNotNull(mWifiRadioApWakeupCount); 8217 } 8218 8219 return !active; 8220 } 8221 writeJobCompletionsToParcelLocked(Parcel out)8222 void writeJobCompletionsToParcelLocked(Parcel out) { 8223 int NJC = mJobCompletions.size(); 8224 out.writeInt(NJC); 8225 for (int ijc=0; ijc<NJC; ijc++) { 8226 out.writeString(mJobCompletions.keyAt(ijc)); 8227 SparseIntArray types = mJobCompletions.valueAt(ijc); 8228 int NT = types.size(); 8229 out.writeInt(NT); 8230 for (int it=0; it<NT; it++) { 8231 out.writeInt(types.keyAt(it)); 8232 out.writeInt(types.valueAt(it)); 8233 } 8234 } 8235 } 8236 writeToParcelLocked(Parcel out, long uptimeUs, long elapsedRealtimeUs)8237 void writeToParcelLocked(Parcel out, long uptimeUs, long elapsedRealtimeUs) { 8238 mOnBatteryBackgroundTimeBase.writeToParcel(out, uptimeUs, elapsedRealtimeUs); 8239 mOnBatteryScreenOffBackgroundTimeBase.writeToParcel(out, uptimeUs, elapsedRealtimeUs); 8240 8241 final ArrayMap<String, Wakelock> wakeStats = mWakelockStats.getMap(); 8242 int NW = wakeStats.size(); 8243 out.writeInt(NW); 8244 for (int iw=0; iw<NW; iw++) { 8245 out.writeString(wakeStats.keyAt(iw)); 8246 Uid.Wakelock wakelock = wakeStats.valueAt(iw); 8247 wakelock.writeToParcelLocked(out, elapsedRealtimeUs); 8248 } 8249 8250 final ArrayMap<String, DualTimer> syncStats = mSyncStats.getMap(); 8251 int NS = syncStats.size(); 8252 out.writeInt(NS); 8253 for (int is=0; is<NS; is++) { 8254 out.writeString(syncStats.keyAt(is)); 8255 DualTimer timer = syncStats.valueAt(is); 8256 Timer.writeTimerToParcel(out, timer, elapsedRealtimeUs); 8257 } 8258 8259 final ArrayMap<String, DualTimer> jobStats = mJobStats.getMap(); 8260 int NJ = jobStats.size(); 8261 out.writeInt(NJ); 8262 for (int ij=0; ij<NJ; ij++) { 8263 out.writeString(jobStats.keyAt(ij)); 8264 DualTimer timer = jobStats.valueAt(ij); 8265 Timer.writeTimerToParcel(out, timer, elapsedRealtimeUs); 8266 } 8267 8268 writeJobCompletionsToParcelLocked(out); 8269 8270 mJobsDeferredEventCount.writeToParcel(out); 8271 mJobsDeferredCount.writeToParcel(out); 8272 mJobsFreshnessTimeMs.writeToParcel(out); 8273 for (int i = 0; i < JOB_FRESHNESS_BUCKETS.length; i++) { 8274 Counter.writeCounterToParcel(out, mJobsFreshnessBuckets[i]); 8275 } 8276 8277 int NSE = mSensorStats.size(); 8278 out.writeInt(NSE); 8279 for (int ise=0; ise<NSE; ise++) { 8280 out.writeInt(mSensorStats.keyAt(ise)); 8281 Uid.Sensor sensor = mSensorStats.valueAt(ise); 8282 sensor.writeToParcelLocked(out, elapsedRealtimeUs); 8283 } 8284 8285 int NP = mProcessStats.size(); 8286 out.writeInt(NP); 8287 for (int ip=0; ip<NP; ip++) { 8288 out.writeString(mProcessStats.keyAt(ip)); 8289 Uid.Proc proc = mProcessStats.valueAt(ip); 8290 proc.writeToParcelLocked(out); 8291 } 8292 8293 out.writeInt(mPackageStats.size()); 8294 for (Map.Entry<String, Uid.Pkg> pkgEntry : mPackageStats.entrySet()) { 8295 out.writeString(pkgEntry.getKey()); 8296 Uid.Pkg pkg = pkgEntry.getValue(); 8297 pkg.writeToParcelLocked(out); 8298 } 8299 8300 if (mWifiRunningTimer != null) { 8301 out.writeInt(1); 8302 mWifiRunningTimer.writeToParcel(out, elapsedRealtimeUs); 8303 } else { 8304 out.writeInt(0); 8305 } 8306 if (mFullWifiLockTimer != null) { 8307 out.writeInt(1); 8308 mFullWifiLockTimer.writeToParcel(out, elapsedRealtimeUs); 8309 } else { 8310 out.writeInt(0); 8311 } 8312 if (mWifiScanTimer != null) { 8313 out.writeInt(1); 8314 mWifiScanTimer.writeToParcel(out, elapsedRealtimeUs); 8315 } else { 8316 out.writeInt(0); 8317 } 8318 for (int i = 0; i < NUM_WIFI_BATCHED_SCAN_BINS; i++) { 8319 if (mWifiBatchedScanTimer[i] != null) { 8320 out.writeInt(1); 8321 mWifiBatchedScanTimer[i].writeToParcel(out, elapsedRealtimeUs); 8322 } else { 8323 out.writeInt(0); 8324 } 8325 } 8326 if (mWifiMulticastTimer != null) { 8327 out.writeInt(1); 8328 mWifiMulticastTimer.writeToParcel(out, elapsedRealtimeUs); 8329 } else { 8330 out.writeInt(0); 8331 } 8332 8333 if (mAudioTurnedOnTimer != null) { 8334 out.writeInt(1); 8335 mAudioTurnedOnTimer.writeToParcel(out, elapsedRealtimeUs); 8336 } else { 8337 out.writeInt(0); 8338 } 8339 if (mVideoTurnedOnTimer != null) { 8340 out.writeInt(1); 8341 mVideoTurnedOnTimer.writeToParcel(out, elapsedRealtimeUs); 8342 } else { 8343 out.writeInt(0); 8344 } 8345 if (mFlashlightTurnedOnTimer != null) { 8346 out.writeInt(1); 8347 mFlashlightTurnedOnTimer.writeToParcel(out, elapsedRealtimeUs); 8348 } else { 8349 out.writeInt(0); 8350 } 8351 if (mCameraTurnedOnTimer != null) { 8352 out.writeInt(1); 8353 mCameraTurnedOnTimer.writeToParcel(out, elapsedRealtimeUs); 8354 } else { 8355 out.writeInt(0); 8356 } 8357 if (mForegroundActivityTimer != null) { 8358 out.writeInt(1); 8359 mForegroundActivityTimer.writeToParcel(out, elapsedRealtimeUs); 8360 } else { 8361 out.writeInt(0); 8362 } 8363 if (mForegroundServiceTimer != null) { 8364 out.writeInt(1); 8365 mForegroundServiceTimer.writeToParcel(out, elapsedRealtimeUs); 8366 } else { 8367 out.writeInt(0); 8368 } 8369 if (mAggregatedPartialWakelockTimer != null) { 8370 out.writeInt(1); 8371 mAggregatedPartialWakelockTimer.writeToParcel(out, elapsedRealtimeUs); 8372 } else { 8373 out.writeInt(0); 8374 } 8375 if (mBluetoothScanTimer != null) { 8376 out.writeInt(1); 8377 mBluetoothScanTimer.writeToParcel(out, elapsedRealtimeUs); 8378 } else { 8379 out.writeInt(0); 8380 } 8381 if (mBluetoothUnoptimizedScanTimer != null) { 8382 out.writeInt(1); 8383 mBluetoothUnoptimizedScanTimer.writeToParcel(out, elapsedRealtimeUs); 8384 } else { 8385 out.writeInt(0); 8386 } 8387 if (mBluetoothScanResultCounter != null) { 8388 out.writeInt(1); 8389 mBluetoothScanResultCounter.writeToParcel(out); 8390 } else { 8391 out.writeInt(0); 8392 } 8393 if (mBluetoothScanResultBgCounter != null) { 8394 out.writeInt(1); 8395 mBluetoothScanResultBgCounter.writeToParcel(out); 8396 } else { 8397 out.writeInt(0); 8398 } 8399 for (int i = 0; i < NUM_PROCESS_STATE; i++) { 8400 if (mProcessStateTimer[i] != null) { 8401 out.writeInt(1); 8402 mProcessStateTimer[i].writeToParcel(out, elapsedRealtimeUs); 8403 } else { 8404 out.writeInt(0); 8405 } 8406 } 8407 if (mVibratorOnTimer != null) { 8408 out.writeInt(1); 8409 mVibratorOnTimer.writeToParcel(out, elapsedRealtimeUs); 8410 } else { 8411 out.writeInt(0); 8412 } 8413 if (mUserActivityCounters != null) { 8414 out.writeInt(1); 8415 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) { 8416 mUserActivityCounters[i].writeToParcel(out); 8417 } 8418 } else { 8419 out.writeInt(0); 8420 } 8421 if (mNetworkByteActivityCounters != null) { 8422 out.writeInt(1); 8423 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 8424 mNetworkByteActivityCounters[i].writeToParcel(out); 8425 mNetworkPacketActivityCounters[i].writeToParcel(out); 8426 } 8427 mMobileRadioActiveTime.writeToParcel(out); 8428 mMobileRadioActiveCount.writeToParcel(out); 8429 } else { 8430 out.writeInt(0); 8431 } 8432 8433 if (mWifiControllerActivity != null) { 8434 out.writeInt(1); 8435 mWifiControllerActivity.writeToParcel(out, 0); 8436 } else { 8437 out.writeInt(0); 8438 } 8439 8440 if (mBluetoothControllerActivity != null) { 8441 out.writeInt(1); 8442 mBluetoothControllerActivity.writeToParcel(out, 0); 8443 } else { 8444 out.writeInt(0); 8445 } 8446 8447 if (mModemControllerActivity != null) { 8448 out.writeInt(1); 8449 mModemControllerActivity.writeToParcel(out, 0); 8450 } else { 8451 out.writeInt(0); 8452 } 8453 8454 mUserCpuTime.writeToParcel(out); 8455 mSystemCpuTime.writeToParcel(out); 8456 8457 if (mCpuClusterSpeedTimesUs != null) { 8458 out.writeInt(1); 8459 out.writeInt(mCpuClusterSpeedTimesUs.length); 8460 for (LongSamplingCounter[] cpuSpeeds : mCpuClusterSpeedTimesUs) { 8461 if (cpuSpeeds != null) { 8462 out.writeInt(1); 8463 out.writeInt(cpuSpeeds.length); 8464 for (LongSamplingCounter c : cpuSpeeds) { 8465 if (c != null) { 8466 out.writeInt(1); 8467 c.writeToParcel(out); 8468 } else { 8469 out.writeInt(0); 8470 } 8471 } 8472 } else { 8473 out.writeInt(0); 8474 } 8475 } 8476 } else { 8477 out.writeInt(0); 8478 } 8479 8480 LongSamplingCounterArray.writeToParcel(out, mCpuFreqTimeMs); 8481 LongSamplingCounterArray.writeToParcel(out, mScreenOffCpuFreqTimeMs); 8482 8483 mCpuActiveTimeMs.writeToParcel(out); 8484 mCpuClusterTimesMs.writeToParcel(out); 8485 8486 if (mProcStateTimeMs != null) { 8487 out.writeInt(mProcStateTimeMs.length); 8488 for (LongSamplingCounterArray counters : mProcStateTimeMs) { 8489 LongSamplingCounterArray.writeToParcel(out, counters); 8490 } 8491 } else { 8492 out.writeInt(0); 8493 } 8494 if (mProcStateScreenOffTimeMs != null) { 8495 out.writeInt(mProcStateScreenOffTimeMs.length); 8496 for (LongSamplingCounterArray counters : mProcStateScreenOffTimeMs) { 8497 LongSamplingCounterArray.writeToParcel(out, counters); 8498 } 8499 } else { 8500 out.writeInt(0); 8501 } 8502 8503 if (mMobileRadioApWakeupCount != null) { 8504 out.writeInt(1); 8505 mMobileRadioApWakeupCount.writeToParcel(out); 8506 } else { 8507 out.writeInt(0); 8508 } 8509 8510 if (mWifiRadioApWakeupCount != null) { 8511 out.writeInt(1); 8512 mWifiRadioApWakeupCount.writeToParcel(out); 8513 } else { 8514 out.writeInt(0); 8515 } 8516 } 8517 readJobCompletionsFromParcelLocked(Parcel in)8518 void readJobCompletionsFromParcelLocked(Parcel in) { 8519 int numJobCompletions = in.readInt(); 8520 mJobCompletions.clear(); 8521 for (int j = 0; j < numJobCompletions; j++) { 8522 String jobName = in.readString(); 8523 int numTypes = in.readInt(); 8524 if (numTypes > 0) { 8525 SparseIntArray types = new SparseIntArray(); 8526 for (int k = 0; k < numTypes; k++) { 8527 int type = in.readInt(); 8528 int count = in.readInt(); 8529 types.put(type, count); 8530 } 8531 mJobCompletions.put(jobName, types); 8532 } 8533 } 8534 } 8535 readFromParcelLocked(TimeBase timeBase, TimeBase screenOffTimeBase, Parcel in)8536 void readFromParcelLocked(TimeBase timeBase, TimeBase screenOffTimeBase, Parcel in) { 8537 mOnBatteryBackgroundTimeBase.readFromParcel(in); 8538 mOnBatteryScreenOffBackgroundTimeBase.readFromParcel(in); 8539 8540 int numWakelocks = in.readInt(); 8541 mWakelockStats.clear(); 8542 for (int j = 0; j < numWakelocks; j++) { 8543 String wakelockName = in.readString(); 8544 Uid.Wakelock wakelock = new Wakelock(mBsi, this); 8545 wakelock.readFromParcelLocked( 8546 timeBase, screenOffTimeBase, mOnBatteryScreenOffBackgroundTimeBase, in); 8547 mWakelockStats.add(wakelockName, wakelock); 8548 } 8549 8550 int numSyncs = in.readInt(); 8551 mSyncStats.clear(); 8552 for (int j = 0; j < numSyncs; j++) { 8553 String syncName = in.readString(); 8554 if (in.readInt() != 0) { 8555 mSyncStats.add(syncName, new DualTimer(mBsi.mClocks, Uid.this, SYNC, null, 8556 mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase, in)); 8557 } 8558 } 8559 8560 int numJobs = in.readInt(); 8561 mJobStats.clear(); 8562 for (int j = 0; j < numJobs; j++) { 8563 String jobName = in.readString(); 8564 if (in.readInt() != 0) { 8565 mJobStats.add(jobName, new DualTimer(mBsi.mClocks, Uid.this, JOB, null, 8566 mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase, in)); 8567 } 8568 } 8569 8570 readJobCompletionsFromParcelLocked(in); 8571 8572 mJobsDeferredEventCount = new Counter(mBsi.mOnBatteryTimeBase, in); 8573 mJobsDeferredCount = new Counter(mBsi.mOnBatteryTimeBase, in); 8574 mJobsFreshnessTimeMs = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in); 8575 for (int i = 0; i < JOB_FRESHNESS_BUCKETS.length; i++) { 8576 mJobsFreshnessBuckets[i] = Counter.readCounterFromParcel(mBsi.mOnBatteryTimeBase, 8577 in); 8578 } 8579 8580 int numSensors = in.readInt(); 8581 mSensorStats.clear(); 8582 for (int k = 0; k < numSensors; k++) { 8583 int sensorNumber = in.readInt(); 8584 Uid.Sensor sensor = new Sensor(mBsi, this, sensorNumber); 8585 sensor.readFromParcelLocked(mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase, 8586 in); 8587 mSensorStats.put(sensorNumber, sensor); 8588 } 8589 8590 int numProcs = in.readInt(); 8591 mProcessStats.clear(); 8592 for (int k = 0; k < numProcs; k++) { 8593 String processName = in.readString(); 8594 Uid.Proc proc = new Proc(mBsi, processName); 8595 proc.readFromParcelLocked(in); 8596 mProcessStats.put(processName, proc); 8597 } 8598 8599 int numPkgs = in.readInt(); 8600 mPackageStats.clear(); 8601 for (int l = 0; l < numPkgs; l++) { 8602 String packageName = in.readString(); 8603 Uid.Pkg pkg = new Pkg(mBsi); 8604 pkg.readFromParcelLocked(in); 8605 mPackageStats.put(packageName, pkg); 8606 } 8607 8608 mWifiRunning = false; 8609 if (in.readInt() != 0) { 8610 mWifiRunningTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, WIFI_RUNNING, 8611 mBsi.mWifiRunningTimers, mBsi.mOnBatteryTimeBase, in); 8612 } else { 8613 mWifiRunningTimer = null; 8614 } 8615 mFullWifiLockOut = false; 8616 if (in.readInt() != 0) { 8617 mFullWifiLockTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, FULL_WIFI_LOCK, 8618 mBsi.mFullWifiLockTimers, mBsi.mOnBatteryTimeBase, in); 8619 } else { 8620 mFullWifiLockTimer = null; 8621 } 8622 mWifiScanStarted = false; 8623 if (in.readInt() != 0) { 8624 mWifiScanTimer = new DualTimer(mBsi.mClocks, Uid.this, WIFI_SCAN, 8625 mBsi.mWifiScanTimers, mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase, 8626 in); 8627 } else { 8628 mWifiScanTimer = null; 8629 } 8630 mWifiBatchedScanBinStarted = NO_BATCHED_SCAN_STARTED; 8631 for (int i = 0; i < NUM_WIFI_BATCHED_SCAN_BINS; i++) { 8632 if (in.readInt() != 0) { 8633 makeWifiBatchedScanBin(i, in); 8634 } else { 8635 mWifiBatchedScanTimer[i] = null; 8636 } 8637 } 8638 mWifiMulticastEnabled = false; 8639 if (in.readInt() != 0) { 8640 mWifiMulticastTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, WIFI_MULTICAST_ENABLED, 8641 mBsi.mWifiMulticastTimers, mBsi.mOnBatteryTimeBase, in); 8642 } else { 8643 mWifiMulticastTimer = null; 8644 } 8645 if (in.readInt() != 0) { 8646 mAudioTurnedOnTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, AUDIO_TURNED_ON, 8647 mBsi.mAudioTurnedOnTimers, mBsi.mOnBatteryTimeBase, in); 8648 } else { 8649 mAudioTurnedOnTimer = null; 8650 } 8651 if (in.readInt() != 0) { 8652 mVideoTurnedOnTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, VIDEO_TURNED_ON, 8653 mBsi.mVideoTurnedOnTimers, mBsi.mOnBatteryTimeBase, in); 8654 } else { 8655 mVideoTurnedOnTimer = null; 8656 } 8657 if (in.readInt() != 0) { 8658 mFlashlightTurnedOnTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, 8659 FLASHLIGHT_TURNED_ON, mBsi.mFlashlightTurnedOnTimers, mBsi.mOnBatteryTimeBase, in); 8660 } else { 8661 mFlashlightTurnedOnTimer = null; 8662 } 8663 if (in.readInt() != 0) { 8664 mCameraTurnedOnTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, CAMERA_TURNED_ON, 8665 mBsi.mCameraTurnedOnTimers, mBsi.mOnBatteryTimeBase, in); 8666 } else { 8667 mCameraTurnedOnTimer = null; 8668 } 8669 if (in.readInt() != 0) { 8670 mForegroundActivityTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, 8671 FOREGROUND_ACTIVITY, null, mBsi.mOnBatteryTimeBase, in); 8672 } else { 8673 mForegroundActivityTimer = null; 8674 } 8675 if (in.readInt() != 0) { 8676 mForegroundServiceTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, 8677 FOREGROUND_SERVICE, null, mBsi.mOnBatteryTimeBase, in); 8678 } else { 8679 mForegroundServiceTimer = null; 8680 } 8681 if (in.readInt() != 0) { 8682 mAggregatedPartialWakelockTimer = new DualTimer(mBsi.mClocks, this, 8683 AGGREGATED_WAKE_TYPE_PARTIAL, null, 8684 mBsi.mOnBatteryScreenOffTimeBase, mOnBatteryScreenOffBackgroundTimeBase, 8685 in); 8686 } else { 8687 mAggregatedPartialWakelockTimer = null; 8688 } 8689 if (in.readInt() != 0) { 8690 mBluetoothScanTimer = new DualTimer(mBsi.mClocks, Uid.this, BLUETOOTH_SCAN_ON, 8691 mBsi.mBluetoothScanOnTimers, mBsi.mOnBatteryTimeBase, 8692 mOnBatteryBackgroundTimeBase, in); 8693 } else { 8694 mBluetoothScanTimer = null; 8695 } 8696 if (in.readInt() != 0) { 8697 mBluetoothUnoptimizedScanTimer = new DualTimer(mBsi.mClocks, Uid.this, 8698 BLUETOOTH_UNOPTIMIZED_SCAN_ON, null, 8699 mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase, in); 8700 } else { 8701 mBluetoothUnoptimizedScanTimer = null; 8702 } 8703 if (in.readInt() != 0) { 8704 mBluetoothScanResultCounter = new Counter(mBsi.mOnBatteryTimeBase, in); 8705 } else { 8706 mBluetoothScanResultCounter = null; 8707 } 8708 if (in.readInt() != 0) { 8709 mBluetoothScanResultBgCounter = new Counter(mOnBatteryBackgroundTimeBase, in); 8710 } else { 8711 mBluetoothScanResultBgCounter = null; 8712 } 8713 mProcessState = ActivityManager.PROCESS_STATE_NONEXISTENT; 8714 for (int i = 0; i < NUM_PROCESS_STATE; i++) { 8715 if (in.readInt() != 0) { 8716 makeProcessState(i, in); 8717 } else { 8718 mProcessStateTimer[i] = null; 8719 } 8720 } 8721 if (in.readInt() != 0) { 8722 mVibratorOnTimer = new BatchTimer(mBsi.mClocks, Uid.this, VIBRATOR_ON, 8723 mBsi.mOnBatteryTimeBase, in); 8724 } else { 8725 mVibratorOnTimer = null; 8726 } 8727 if (in.readInt() != 0) { 8728 mUserActivityCounters = new Counter[NUM_USER_ACTIVITY_TYPES]; 8729 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) { 8730 mUserActivityCounters[i] = new Counter(mBsi.mOnBatteryTimeBase, in); 8731 } 8732 } else { 8733 mUserActivityCounters = null; 8734 } 8735 if (in.readInt() != 0) { 8736 mNetworkByteActivityCounters = new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES]; 8737 mNetworkPacketActivityCounters 8738 = new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES]; 8739 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 8740 mNetworkByteActivityCounters[i] 8741 = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in); 8742 mNetworkPacketActivityCounters[i] 8743 = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in); 8744 } 8745 mMobileRadioActiveTime = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in); 8746 mMobileRadioActiveCount = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in); 8747 } else { 8748 mNetworkByteActivityCounters = null; 8749 mNetworkPacketActivityCounters = null; 8750 } 8751 8752 if (in.readInt() != 0) { 8753 mWifiControllerActivity = new ControllerActivityCounterImpl(mBsi.mOnBatteryTimeBase, 8754 NUM_WIFI_TX_LEVELS, in); 8755 } else { 8756 mWifiControllerActivity = null; 8757 } 8758 8759 if (in.readInt() != 0) { 8760 mBluetoothControllerActivity = new ControllerActivityCounterImpl(mBsi.mOnBatteryTimeBase, 8761 NUM_BT_TX_LEVELS, in); 8762 } else { 8763 mBluetoothControllerActivity = null; 8764 } 8765 8766 if (in.readInt() != 0) { 8767 mModemControllerActivity = new ControllerActivityCounterImpl(mBsi.mOnBatteryTimeBase, 8768 ModemActivityInfo.TX_POWER_LEVELS, in); 8769 } else { 8770 mModemControllerActivity = null; 8771 } 8772 8773 mUserCpuTime = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in); 8774 mSystemCpuTime = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in); 8775 8776 if (in.readInt() != 0) { 8777 int numCpuClusters = in.readInt(); 8778 if (mBsi.mPowerProfile != null && mBsi.mPowerProfile.getNumCpuClusters() != numCpuClusters) { 8779 throw new ParcelFormatException("Incompatible number of cpu clusters"); 8780 } 8781 8782 mCpuClusterSpeedTimesUs = new LongSamplingCounter[numCpuClusters][]; 8783 for (int cluster = 0; cluster < numCpuClusters; cluster++) { 8784 if (in.readInt() != 0) { 8785 int numSpeeds = in.readInt(); 8786 if (mBsi.mPowerProfile != null && 8787 mBsi.mPowerProfile.getNumSpeedStepsInCpuCluster(cluster) != numSpeeds) { 8788 throw new ParcelFormatException("Incompatible number of cpu speeds"); 8789 } 8790 8791 final LongSamplingCounter[] cpuSpeeds = new LongSamplingCounter[numSpeeds]; 8792 mCpuClusterSpeedTimesUs[cluster] = cpuSpeeds; 8793 for (int speed = 0; speed < numSpeeds; speed++) { 8794 if (in.readInt() != 0) { 8795 cpuSpeeds[speed] = new LongSamplingCounter( 8796 mBsi.mOnBatteryTimeBase, in); 8797 } 8798 } 8799 } else { 8800 mCpuClusterSpeedTimesUs[cluster] = null; 8801 } 8802 } 8803 } else { 8804 mCpuClusterSpeedTimesUs = null; 8805 } 8806 8807 mCpuFreqTimeMs = LongSamplingCounterArray.readFromParcel(in, mBsi.mOnBatteryTimeBase); 8808 mScreenOffCpuFreqTimeMs = LongSamplingCounterArray.readFromParcel( 8809 in, mBsi.mOnBatteryScreenOffTimeBase); 8810 8811 mCpuActiveTimeMs = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in); 8812 mCpuClusterTimesMs = new LongSamplingCounterArray(mBsi.mOnBatteryTimeBase, in); 8813 8814 int length = in.readInt(); 8815 if (length == NUM_PROCESS_STATE) { 8816 mProcStateTimeMs = new LongSamplingCounterArray[length]; 8817 for (int procState = 0; procState < length; ++procState) { 8818 mProcStateTimeMs[procState] = LongSamplingCounterArray.readFromParcel( 8819 in, mBsi.mOnBatteryTimeBase); 8820 } 8821 } else { 8822 mProcStateTimeMs = null; 8823 } 8824 length = in.readInt(); 8825 if (length == NUM_PROCESS_STATE) { 8826 mProcStateScreenOffTimeMs = new LongSamplingCounterArray[length]; 8827 for (int procState = 0; procState < length; ++procState) { 8828 mProcStateScreenOffTimeMs[procState] = LongSamplingCounterArray.readFromParcel( 8829 in, mBsi.mOnBatteryScreenOffTimeBase); 8830 } 8831 } else { 8832 mProcStateScreenOffTimeMs = null; 8833 } 8834 8835 if (in.readInt() != 0) { 8836 mMobileRadioApWakeupCount = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in); 8837 } else { 8838 mMobileRadioApWakeupCount = null; 8839 } 8840 8841 if (in.readInt() != 0) { 8842 mWifiRadioApWakeupCount = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in); 8843 } else { 8844 mWifiRadioApWakeupCount = null; 8845 } 8846 } 8847 noteJobsDeferredLocked(int numDeferred, long sinceLast)8848 public void noteJobsDeferredLocked(int numDeferred, long sinceLast) { 8849 mJobsDeferredEventCount.addAtomic(1); 8850 mJobsDeferredCount.addAtomic(numDeferred); 8851 if (sinceLast != 0) { 8852 // Add the total time, which can be divided by the event count to get an average 8853 mJobsFreshnessTimeMs.addCountLocked(sinceLast); 8854 // Also keep track of how many times there were in these different buckets. 8855 for (int i = 0; i < JOB_FRESHNESS_BUCKETS.length; i++) { 8856 if (sinceLast < JOB_FRESHNESS_BUCKETS[i]) { 8857 if (mJobsFreshnessBuckets[i] == null) { 8858 mJobsFreshnessBuckets[i] = new Counter( 8859 mBsi.mOnBatteryTimeBase); 8860 } 8861 mJobsFreshnessBuckets[i].addAtomic(1); 8862 break; 8863 } 8864 } 8865 } 8866 } 8867 8868 /** 8869 * The statistics associated with a particular wake lock. 8870 */ 8871 public static class Wakelock extends BatteryStats.Uid.Wakelock { 8872 /** 8873 * BatteryStatsImpl that we are associated with. 8874 */ 8875 protected BatteryStatsImpl mBsi; 8876 8877 /** 8878 * BatteryStatsImpl that we are associated with. 8879 */ 8880 protected Uid mUid; 8881 8882 /** 8883 * How long (in ms) this uid has been keeping the device partially awake. 8884 * Tracks both the total time and the time while the app was in the background. 8885 */ 8886 DualTimer mTimerPartial; 8887 8888 /** 8889 * How long (in ms) this uid has been keeping the device fully awake. 8890 */ 8891 StopwatchTimer mTimerFull; 8892 8893 /** 8894 * How long (in ms) this uid has had a window keeping the device awake. 8895 */ 8896 StopwatchTimer mTimerWindow; 8897 8898 /** 8899 * How long (in ms) this uid has had a draw wake lock. 8900 */ 8901 StopwatchTimer mTimerDraw; 8902 Wakelock(BatteryStatsImpl bsi, Uid uid)8903 public Wakelock(BatteryStatsImpl bsi, Uid uid) { 8904 mBsi = bsi; 8905 mUid = uid; 8906 } 8907 8908 /** 8909 * Reads a possibly null Timer from a Parcel. The timer is associated with the 8910 * proper timer pool from the given BatteryStatsImpl object. 8911 * 8912 * @param in the Parcel to be read from. 8913 * return a new Timer, or null. 8914 */ readStopwatchTimerFromParcel(int type, ArrayList<StopwatchTimer> pool, TimeBase timeBase, Parcel in)8915 private StopwatchTimer readStopwatchTimerFromParcel(int type, 8916 ArrayList<StopwatchTimer> pool, TimeBase timeBase, Parcel in) { 8917 if (in.readInt() == 0) { 8918 return null; 8919 } 8920 8921 return new StopwatchTimer(mBsi.mClocks, mUid, type, pool, timeBase, in); 8922 } 8923 8924 /** 8925 * Reads a possibly null Timer from a Parcel. The timer is associated with the 8926 * proper timer pool from the given BatteryStatsImpl object. 8927 * 8928 * @param in the Parcel to be read from. 8929 * return a new Timer, or null. 8930 */ readDualTimerFromParcel(int type, ArrayList<StopwatchTimer> pool, TimeBase timeBase, TimeBase bgTimeBase, Parcel in)8931 private DualTimer readDualTimerFromParcel(int type, ArrayList<StopwatchTimer> pool, 8932 TimeBase timeBase, TimeBase bgTimeBase, Parcel in) { 8933 if (in.readInt() == 0) { 8934 return null; 8935 } 8936 8937 return new DualTimer(mBsi.mClocks, mUid, type, pool, timeBase, bgTimeBase, in); 8938 } 8939 reset()8940 boolean reset() { 8941 boolean wlactive = false; 8942 if (mTimerFull != null) { 8943 wlactive |= !mTimerFull.reset(false); 8944 } 8945 if (mTimerPartial != null) { 8946 wlactive |= !mTimerPartial.reset(false); 8947 } 8948 if (mTimerWindow != null) { 8949 wlactive |= !mTimerWindow.reset(false); 8950 } 8951 if (mTimerDraw != null) { 8952 wlactive |= !mTimerDraw.reset(false); 8953 } 8954 if (!wlactive) { 8955 if (mTimerFull != null) { 8956 mTimerFull.detach(); 8957 mTimerFull = null; 8958 } 8959 if (mTimerPartial != null) { 8960 mTimerPartial.detach(); 8961 mTimerPartial = null; 8962 } 8963 if (mTimerWindow != null) { 8964 mTimerWindow.detach(); 8965 mTimerWindow = null; 8966 } 8967 if (mTimerDraw != null) { 8968 mTimerDraw.detach(); 8969 mTimerDraw = null; 8970 } 8971 } 8972 return !wlactive; 8973 } 8974 readFromParcelLocked(TimeBase timeBase, TimeBase screenOffTimeBase, TimeBase screenOffBgTimeBase, Parcel in)8975 void readFromParcelLocked(TimeBase timeBase, TimeBase screenOffTimeBase, 8976 TimeBase screenOffBgTimeBase, Parcel in) { 8977 mTimerPartial = readDualTimerFromParcel(WAKE_TYPE_PARTIAL, 8978 mBsi.mPartialTimers, screenOffTimeBase, screenOffBgTimeBase, in); 8979 mTimerFull = readStopwatchTimerFromParcel(WAKE_TYPE_FULL, 8980 mBsi.mFullTimers, timeBase, in); 8981 mTimerWindow = readStopwatchTimerFromParcel(WAKE_TYPE_WINDOW, 8982 mBsi.mWindowTimers, timeBase, in); 8983 mTimerDraw = readStopwatchTimerFromParcel(WAKE_TYPE_DRAW, 8984 mBsi.mDrawTimers, timeBase, in); 8985 } 8986 writeToParcelLocked(Parcel out, long elapsedRealtimeUs)8987 void writeToParcelLocked(Parcel out, long elapsedRealtimeUs) { 8988 Timer.writeTimerToParcel(out, mTimerPartial, elapsedRealtimeUs); 8989 Timer.writeTimerToParcel(out, mTimerFull, elapsedRealtimeUs); 8990 Timer.writeTimerToParcel(out, mTimerWindow, elapsedRealtimeUs); 8991 Timer.writeTimerToParcel(out, mTimerDraw, elapsedRealtimeUs); 8992 } 8993 8994 @Override getWakeTime(int type)8995 public Timer getWakeTime(int type) { 8996 switch (type) { 8997 case WAKE_TYPE_FULL: return mTimerFull; 8998 case WAKE_TYPE_PARTIAL: return mTimerPartial; 8999 case WAKE_TYPE_WINDOW: return mTimerWindow; 9000 case WAKE_TYPE_DRAW: return mTimerDraw; 9001 default: throw new IllegalArgumentException("type = " + type); 9002 } 9003 } 9004 } 9005 9006 public static class Sensor extends BatteryStats.Uid.Sensor { 9007 /** 9008 * BatteryStatsImpl that we are associated with. 9009 */ 9010 protected BatteryStatsImpl mBsi; 9011 9012 /** 9013 * Uid that we are associated with. 9014 */ 9015 protected Uid mUid; 9016 9017 final int mHandle; 9018 DualTimer mTimer; 9019 Sensor(BatteryStatsImpl bsi, Uid uid, int handle)9020 public Sensor(BatteryStatsImpl bsi, Uid uid, int handle) { 9021 mBsi = bsi; 9022 mUid = uid; 9023 mHandle = handle; 9024 } 9025 readTimersFromParcel( TimeBase timeBase, TimeBase bgTimeBase, Parcel in)9026 private DualTimer readTimersFromParcel( 9027 TimeBase timeBase, TimeBase bgTimeBase, Parcel in) { 9028 if (in.readInt() == 0) { 9029 return null; 9030 } 9031 9032 ArrayList<StopwatchTimer> pool = mBsi.mSensorTimers.get(mHandle); 9033 if (pool == null) { 9034 pool = new ArrayList<StopwatchTimer>(); 9035 mBsi.mSensorTimers.put(mHandle, pool); 9036 } 9037 return new DualTimer(mBsi.mClocks, mUid, 0, pool, timeBase, bgTimeBase, in); 9038 } 9039 reset()9040 boolean reset() { 9041 if (mTimer.reset(true)) { 9042 mTimer = null; 9043 return true; 9044 } 9045 return false; 9046 } 9047 readFromParcelLocked(TimeBase timeBase, TimeBase bgTimeBase, Parcel in)9048 void readFromParcelLocked(TimeBase timeBase, TimeBase bgTimeBase, Parcel in) { 9049 mTimer = readTimersFromParcel(timeBase, bgTimeBase, in); 9050 } 9051 writeToParcelLocked(Parcel out, long elapsedRealtimeUs)9052 void writeToParcelLocked(Parcel out, long elapsedRealtimeUs) { 9053 Timer.writeTimerToParcel(out, mTimer, elapsedRealtimeUs); 9054 } 9055 9056 @Override getSensorTime()9057 public Timer getSensorTime() { 9058 return mTimer; 9059 } 9060 9061 @Override getSensorBackgroundTime()9062 public Timer getSensorBackgroundTime() { 9063 if (mTimer == null) { 9064 return null; 9065 } 9066 return mTimer.getSubTimer(); 9067 } 9068 9069 @Override getHandle()9070 public int getHandle() { 9071 return mHandle; 9072 } 9073 } 9074 9075 /** 9076 * The statistics associated with a particular process. 9077 */ 9078 public static class Proc extends BatteryStats.Uid.Proc implements TimeBaseObs { 9079 /** 9080 * BatteryStatsImpl that we are associated with. 9081 */ 9082 protected BatteryStatsImpl mBsi; 9083 9084 /** 9085 * The name of this process. 9086 */ 9087 final String mName; 9088 9089 /** 9090 * Remains true until removed from the stats. 9091 */ 9092 boolean mActive = true; 9093 9094 /** 9095 * Total time (in ms) spent executing in user code. 9096 */ 9097 long mUserTime; 9098 9099 /** 9100 * Total time (in ms) spent executing in kernel code. 9101 */ 9102 long mSystemTime; 9103 9104 /** 9105 * Amount of time (in ms) the process was running in the foreground. 9106 */ 9107 long mForegroundTime; 9108 9109 /** 9110 * Number of times the process has been started. 9111 */ 9112 int mStarts; 9113 9114 /** 9115 * Number of times the process has crashed. 9116 */ 9117 int mNumCrashes; 9118 9119 /** 9120 * Number of times the process has had an ANR. 9121 */ 9122 int mNumAnrs; 9123 9124 /** 9125 * The amount of user time loaded from a previous save. 9126 */ 9127 long mLoadedUserTime; 9128 9129 /** 9130 * The amount of system time loaded from a previous save. 9131 */ 9132 long mLoadedSystemTime; 9133 9134 /** 9135 * The amount of foreground time loaded from a previous save. 9136 */ 9137 long mLoadedForegroundTime; 9138 9139 /** 9140 * The number of times the process has started from a previous save. 9141 */ 9142 int mLoadedStarts; 9143 9144 /** 9145 * Number of times the process has crashed from a previous save. 9146 */ 9147 int mLoadedNumCrashes; 9148 9149 /** 9150 * Number of times the process has had an ANR from a previous save. 9151 */ 9152 int mLoadedNumAnrs; 9153 9154 /** 9155 * The amount of user time when last unplugged. 9156 */ 9157 long mUnpluggedUserTime; 9158 9159 /** 9160 * The amount of system time when last unplugged. 9161 */ 9162 long mUnpluggedSystemTime; 9163 9164 /** 9165 * The amount of foreground time since unplugged. 9166 */ 9167 long mUnpluggedForegroundTime; 9168 9169 /** 9170 * The number of times the process has started before unplugged. 9171 */ 9172 int mUnpluggedStarts; 9173 9174 /** 9175 * Number of times the process has crashed before unplugged. 9176 */ 9177 int mUnpluggedNumCrashes; 9178 9179 /** 9180 * Number of times the process has had an ANR before unplugged. 9181 */ 9182 int mUnpluggedNumAnrs; 9183 9184 ArrayList<ExcessivePower> mExcessivePower; 9185 Proc(BatteryStatsImpl bsi, String name)9186 public Proc(BatteryStatsImpl bsi, String name) { 9187 mBsi = bsi; 9188 mName = name; 9189 mBsi.mOnBatteryTimeBase.add(this); 9190 } 9191 onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime)9192 public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) { 9193 mUnpluggedUserTime = mUserTime; 9194 mUnpluggedSystemTime = mSystemTime; 9195 mUnpluggedForegroundTime = mForegroundTime; 9196 mUnpluggedStarts = mStarts; 9197 mUnpluggedNumCrashes = mNumCrashes; 9198 mUnpluggedNumAnrs = mNumAnrs; 9199 } 9200 onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime)9201 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) { 9202 } 9203 detach()9204 void detach() { 9205 mActive = false; 9206 mBsi.mOnBatteryTimeBase.remove(this); 9207 } 9208 countExcessivePowers()9209 public int countExcessivePowers() { 9210 return mExcessivePower != null ? mExcessivePower.size() : 0; 9211 } 9212 getExcessivePower(int i)9213 public ExcessivePower getExcessivePower(int i) { 9214 if (mExcessivePower != null) { 9215 return mExcessivePower.get(i); 9216 } 9217 return null; 9218 } 9219 addExcessiveCpu(long overTime, long usedTime)9220 public void addExcessiveCpu(long overTime, long usedTime) { 9221 if (mExcessivePower == null) { 9222 mExcessivePower = new ArrayList<ExcessivePower>(); 9223 } 9224 ExcessivePower ew = new ExcessivePower(); 9225 ew.type = ExcessivePower.TYPE_CPU; 9226 ew.overTime = overTime; 9227 ew.usedTime = usedTime; 9228 mExcessivePower.add(ew); 9229 } 9230 writeExcessivePowerToParcelLocked(Parcel out)9231 void writeExcessivePowerToParcelLocked(Parcel out) { 9232 if (mExcessivePower == null) { 9233 out.writeInt(0); 9234 return; 9235 } 9236 9237 final int N = mExcessivePower.size(); 9238 out.writeInt(N); 9239 for (int i=0; i<N; i++) { 9240 ExcessivePower ew = mExcessivePower.get(i); 9241 out.writeInt(ew.type); 9242 out.writeLong(ew.overTime); 9243 out.writeLong(ew.usedTime); 9244 } 9245 } 9246 readExcessivePowerFromParcelLocked(Parcel in)9247 void readExcessivePowerFromParcelLocked(Parcel in) { 9248 final int N = in.readInt(); 9249 if (N == 0) { 9250 mExcessivePower = null; 9251 return; 9252 } 9253 9254 if (N > 10000) { 9255 throw new ParcelFormatException( 9256 "File corrupt: too many excessive power entries " + N); 9257 } 9258 9259 mExcessivePower = new ArrayList<>(); 9260 for (int i=0; i<N; i++) { 9261 ExcessivePower ew = new ExcessivePower(); 9262 ew.type = in.readInt(); 9263 ew.overTime = in.readLong(); 9264 ew.usedTime = in.readLong(); 9265 mExcessivePower.add(ew); 9266 } 9267 } 9268 writeToParcelLocked(Parcel out)9269 void writeToParcelLocked(Parcel out) { 9270 out.writeLong(mUserTime); 9271 out.writeLong(mSystemTime); 9272 out.writeLong(mForegroundTime); 9273 out.writeInt(mStarts); 9274 out.writeInt(mNumCrashes); 9275 out.writeInt(mNumAnrs); 9276 out.writeLong(mLoadedUserTime); 9277 out.writeLong(mLoadedSystemTime); 9278 out.writeLong(mLoadedForegroundTime); 9279 out.writeInt(mLoadedStarts); 9280 out.writeInt(mLoadedNumCrashes); 9281 out.writeInt(mLoadedNumAnrs); 9282 out.writeLong(mUnpluggedUserTime); 9283 out.writeLong(mUnpluggedSystemTime); 9284 out.writeLong(mUnpluggedForegroundTime); 9285 out.writeInt(mUnpluggedStarts); 9286 out.writeInt(mUnpluggedNumCrashes); 9287 out.writeInt(mUnpluggedNumAnrs); 9288 writeExcessivePowerToParcelLocked(out); 9289 } 9290 readFromParcelLocked(Parcel in)9291 void readFromParcelLocked(Parcel in) { 9292 mUserTime = in.readLong(); 9293 mSystemTime = in.readLong(); 9294 mForegroundTime = in.readLong(); 9295 mStarts = in.readInt(); 9296 mNumCrashes = in.readInt(); 9297 mNumAnrs = in.readInt(); 9298 mLoadedUserTime = in.readLong(); 9299 mLoadedSystemTime = in.readLong(); 9300 mLoadedForegroundTime = in.readLong(); 9301 mLoadedStarts = in.readInt(); 9302 mLoadedNumCrashes = in.readInt(); 9303 mLoadedNumAnrs = in.readInt(); 9304 mUnpluggedUserTime = in.readLong(); 9305 mUnpluggedSystemTime = in.readLong(); 9306 mUnpluggedForegroundTime = in.readLong(); 9307 mUnpluggedStarts = in.readInt(); 9308 mUnpluggedNumCrashes = in.readInt(); 9309 mUnpluggedNumAnrs = in.readInt(); 9310 readExcessivePowerFromParcelLocked(in); 9311 } 9312 addCpuTimeLocked(int utime, int stime)9313 public void addCpuTimeLocked(int utime, int stime) { 9314 addCpuTimeLocked(utime, stime, mBsi.mOnBatteryTimeBase.isRunning()); 9315 } 9316 addCpuTimeLocked(int utime, int stime, boolean isRunning)9317 public void addCpuTimeLocked(int utime, int stime, boolean isRunning) { 9318 if (isRunning) { 9319 mUserTime += utime; 9320 mSystemTime += stime; 9321 } 9322 } 9323 addForegroundTimeLocked(long ttime)9324 public void addForegroundTimeLocked(long ttime) { 9325 mForegroundTime += ttime; 9326 } 9327 incStartsLocked()9328 public void incStartsLocked() { 9329 mStarts++; 9330 } 9331 incNumCrashesLocked()9332 public void incNumCrashesLocked() { 9333 mNumCrashes++; 9334 } 9335 incNumAnrsLocked()9336 public void incNumAnrsLocked() { 9337 mNumAnrs++; 9338 } 9339 9340 @Override isActive()9341 public boolean isActive() { 9342 return mActive; 9343 } 9344 9345 @Override getUserTime(int which)9346 public long getUserTime(int which) { 9347 long val = mUserTime; 9348 if (which == STATS_CURRENT) { 9349 val -= mLoadedUserTime; 9350 } else if (which == STATS_SINCE_UNPLUGGED) { 9351 val -= mUnpluggedUserTime; 9352 } 9353 return val; 9354 } 9355 9356 @Override getSystemTime(int which)9357 public long getSystemTime(int which) { 9358 long val = mSystemTime; 9359 if (which == STATS_CURRENT) { 9360 val -= mLoadedSystemTime; 9361 } else if (which == STATS_SINCE_UNPLUGGED) { 9362 val -= mUnpluggedSystemTime; 9363 } 9364 return val; 9365 } 9366 9367 @Override getForegroundTime(int which)9368 public long getForegroundTime(int which) { 9369 long val = mForegroundTime; 9370 if (which == STATS_CURRENT) { 9371 val -= mLoadedForegroundTime; 9372 } else if (which == STATS_SINCE_UNPLUGGED) { 9373 val -= mUnpluggedForegroundTime; 9374 } 9375 return val; 9376 } 9377 9378 @Override getStarts(int which)9379 public int getStarts(int which) { 9380 int val = mStarts; 9381 if (which == STATS_CURRENT) { 9382 val -= mLoadedStarts; 9383 } else if (which == STATS_SINCE_UNPLUGGED) { 9384 val -= mUnpluggedStarts; 9385 } 9386 return val; 9387 } 9388 9389 @Override getNumCrashes(int which)9390 public int getNumCrashes(int which) { 9391 int val = mNumCrashes; 9392 if (which == STATS_CURRENT) { 9393 val -= mLoadedNumCrashes; 9394 } else if (which == STATS_SINCE_UNPLUGGED) { 9395 val -= mUnpluggedNumCrashes; 9396 } 9397 return val; 9398 } 9399 9400 @Override getNumAnrs(int which)9401 public int getNumAnrs(int which) { 9402 int val = mNumAnrs; 9403 if (which == STATS_CURRENT) { 9404 val -= mLoadedNumAnrs; 9405 } else if (which == STATS_SINCE_UNPLUGGED) { 9406 val -= mUnpluggedNumAnrs; 9407 } 9408 return val; 9409 } 9410 } 9411 9412 /** 9413 * The statistics associated with a particular package. 9414 */ 9415 public static class Pkg extends BatteryStats.Uid.Pkg implements TimeBaseObs { 9416 /** 9417 * BatteryStatsImpl that we are associated with. 9418 */ 9419 protected BatteryStatsImpl mBsi; 9420 9421 /** 9422 * Number of times wakeup alarms have occurred for this app. 9423 * On screen-off timebase starting in report v25. 9424 */ 9425 ArrayMap<String, Counter> mWakeupAlarms = new ArrayMap<>(); 9426 9427 /** 9428 * The statics we have collected for this package's services. 9429 */ 9430 final ArrayMap<String, Serv> mServiceStats = new ArrayMap<>(); 9431 Pkg(BatteryStatsImpl bsi)9432 public Pkg(BatteryStatsImpl bsi) { 9433 mBsi = bsi; 9434 mBsi.mOnBatteryScreenOffTimeBase.add(this); 9435 } 9436 onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime)9437 public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) { 9438 } 9439 onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime)9440 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) { 9441 } 9442 detach()9443 void detach() { 9444 mBsi.mOnBatteryScreenOffTimeBase.remove(this); 9445 } 9446 readFromParcelLocked(Parcel in)9447 void readFromParcelLocked(Parcel in) { 9448 int numWA = in.readInt(); 9449 mWakeupAlarms.clear(); 9450 for (int i=0; i<numWA; i++) { 9451 String tag = in.readString(); 9452 mWakeupAlarms.put(tag, new Counter(mBsi.mOnBatteryScreenOffTimeBase, in)); 9453 } 9454 9455 int numServs = in.readInt(); 9456 mServiceStats.clear(); 9457 for (int m = 0; m < numServs; m++) { 9458 String serviceName = in.readString(); 9459 Uid.Pkg.Serv serv = new Serv(mBsi); 9460 mServiceStats.put(serviceName, serv); 9461 9462 serv.readFromParcelLocked(in); 9463 } 9464 } 9465 writeToParcelLocked(Parcel out)9466 void writeToParcelLocked(Parcel out) { 9467 int numWA = mWakeupAlarms.size(); 9468 out.writeInt(numWA); 9469 for (int i=0; i<numWA; i++) { 9470 out.writeString(mWakeupAlarms.keyAt(i)); 9471 mWakeupAlarms.valueAt(i).writeToParcel(out); 9472 } 9473 9474 final int NS = mServiceStats.size(); 9475 out.writeInt(NS); 9476 for (int i=0; i<NS; i++) { 9477 out.writeString(mServiceStats.keyAt(i)); 9478 Uid.Pkg.Serv serv = mServiceStats.valueAt(i); 9479 serv.writeToParcelLocked(out); 9480 } 9481 } 9482 9483 @Override getWakeupAlarmStats()9484 public ArrayMap<String, ? extends BatteryStats.Counter> getWakeupAlarmStats() { 9485 return mWakeupAlarms; 9486 } 9487 noteWakeupAlarmLocked(String tag)9488 public void noteWakeupAlarmLocked(String tag) { 9489 Counter c = mWakeupAlarms.get(tag); 9490 if (c == null) { 9491 c = new Counter(mBsi.mOnBatteryScreenOffTimeBase); 9492 mWakeupAlarms.put(tag, c); 9493 } 9494 c.stepAtomic(); 9495 } 9496 9497 @Override getServiceStats()9498 public ArrayMap<String, ? extends BatteryStats.Uid.Pkg.Serv> getServiceStats() { 9499 return mServiceStats; 9500 } 9501 9502 /** 9503 * The statistics associated with a particular service. 9504 */ 9505 public static class Serv extends BatteryStats.Uid.Pkg.Serv implements TimeBaseObs { 9506 /** 9507 * BatteryStatsImpl that we are associated with. 9508 */ 9509 protected BatteryStatsImpl mBsi; 9510 9511 /** 9512 * The android package in which this service resides. 9513 */ 9514 protected Pkg mPkg; 9515 9516 /** 9517 * Total time (ms in battery uptime) the service has been left started. 9518 */ 9519 protected long mStartTime; 9520 9521 /** 9522 * If service has been started and not yet stopped, this is 9523 * when it was started. 9524 */ 9525 protected long mRunningSince; 9526 9527 /** 9528 * True if we are currently running. 9529 */ 9530 protected boolean mRunning; 9531 9532 /** 9533 * Total number of times startService() has been called. 9534 */ 9535 protected int mStarts; 9536 9537 /** 9538 * Total time (ms in battery uptime) the service has been left launched. 9539 */ 9540 protected long mLaunchedTime; 9541 9542 /** 9543 * If service has been launched and not yet exited, this is 9544 * when it was launched (ms in battery uptime). 9545 */ 9546 protected long mLaunchedSince; 9547 9548 /** 9549 * True if we are currently launched. 9550 */ 9551 protected boolean mLaunched; 9552 9553 /** 9554 * Total number times the service has been launched. 9555 */ 9556 protected int mLaunches; 9557 9558 /** 9559 * The amount of time spent started loaded from a previous save 9560 * (ms in battery uptime). 9561 */ 9562 protected long mLoadedStartTime; 9563 9564 /** 9565 * The number of starts loaded from a previous save. 9566 */ 9567 protected int mLoadedStarts; 9568 9569 /** 9570 * The number of launches loaded from a previous save. 9571 */ 9572 protected int mLoadedLaunches; 9573 9574 /** 9575 * The amount of time spent started as of the last run (ms 9576 * in battery uptime). 9577 */ 9578 protected long mLastStartTime; 9579 9580 /** 9581 * The number of starts as of the last run. 9582 */ 9583 protected int mLastStarts; 9584 9585 /** 9586 * The number of launches as of the last run. 9587 */ 9588 protected int mLastLaunches; 9589 9590 /** 9591 * The amount of time spent started when last unplugged (ms 9592 * in battery uptime). 9593 */ 9594 protected long mUnpluggedStartTime; 9595 9596 /** 9597 * The number of starts when last unplugged. 9598 */ 9599 protected int mUnpluggedStarts; 9600 9601 /** 9602 * The number of launches when last unplugged. 9603 */ 9604 protected int mUnpluggedLaunches; 9605 9606 /** 9607 * Construct a Serv. Also adds it to the on-battery time base as a listener. 9608 */ Serv(BatteryStatsImpl bsi)9609 public Serv(BatteryStatsImpl bsi) { 9610 mBsi = bsi; 9611 mBsi.mOnBatteryTimeBase.add(this); 9612 } 9613 onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime)9614 public void onTimeStarted(long elapsedRealtime, long baseUptime, 9615 long baseRealtime) { 9616 mUnpluggedStartTime = getStartTimeToNowLocked(baseUptime); 9617 mUnpluggedStarts = mStarts; 9618 mUnpluggedLaunches = mLaunches; 9619 } 9620 onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime)9621 public void onTimeStopped(long elapsedRealtime, long baseUptime, 9622 long baseRealtime) { 9623 } 9624 9625 /** 9626 * Remove this Serv as a listener from the time base. 9627 */ detach()9628 public void detach() { 9629 mBsi.mOnBatteryTimeBase.remove(this); 9630 } 9631 readFromParcelLocked(Parcel in)9632 public void readFromParcelLocked(Parcel in) { 9633 mStartTime = in.readLong(); 9634 mRunningSince = in.readLong(); 9635 mRunning = in.readInt() != 0; 9636 mStarts = in.readInt(); 9637 mLaunchedTime = in.readLong(); 9638 mLaunchedSince = in.readLong(); 9639 mLaunched = in.readInt() != 0; 9640 mLaunches = in.readInt(); 9641 mLoadedStartTime = in.readLong(); 9642 mLoadedStarts = in.readInt(); 9643 mLoadedLaunches = in.readInt(); 9644 mLastStartTime = 0; 9645 mLastStarts = 0; 9646 mLastLaunches = 0; 9647 mUnpluggedStartTime = in.readLong(); 9648 mUnpluggedStarts = in.readInt(); 9649 mUnpluggedLaunches = in.readInt(); 9650 } 9651 writeToParcelLocked(Parcel out)9652 public void writeToParcelLocked(Parcel out) { 9653 out.writeLong(mStartTime); 9654 out.writeLong(mRunningSince); 9655 out.writeInt(mRunning ? 1 : 0); 9656 out.writeInt(mStarts); 9657 out.writeLong(mLaunchedTime); 9658 out.writeLong(mLaunchedSince); 9659 out.writeInt(mLaunched ? 1 : 0); 9660 out.writeInt(mLaunches); 9661 out.writeLong(mLoadedStartTime); 9662 out.writeInt(mLoadedStarts); 9663 out.writeInt(mLoadedLaunches); 9664 out.writeLong(mUnpluggedStartTime); 9665 out.writeInt(mUnpluggedStarts); 9666 out.writeInt(mUnpluggedLaunches); 9667 } 9668 getLaunchTimeToNowLocked(long batteryUptime)9669 public long getLaunchTimeToNowLocked(long batteryUptime) { 9670 if (!mLaunched) return mLaunchedTime; 9671 return mLaunchedTime + batteryUptime - mLaunchedSince; 9672 } 9673 getStartTimeToNowLocked(long batteryUptime)9674 public long getStartTimeToNowLocked(long batteryUptime) { 9675 if (!mRunning) return mStartTime; 9676 return mStartTime + batteryUptime - mRunningSince; 9677 } 9678 startLaunchedLocked()9679 public void startLaunchedLocked() { 9680 if (!mLaunched) { 9681 mLaunches++; 9682 mLaunchedSince = mBsi.getBatteryUptimeLocked(); 9683 mLaunched = true; 9684 } 9685 } 9686 stopLaunchedLocked()9687 public void stopLaunchedLocked() { 9688 if (mLaunched) { 9689 long time = mBsi.getBatteryUptimeLocked() - mLaunchedSince; 9690 if (time > 0) { 9691 mLaunchedTime += time; 9692 } else { 9693 mLaunches--; 9694 } 9695 mLaunched = false; 9696 } 9697 } 9698 startRunningLocked()9699 public void startRunningLocked() { 9700 if (!mRunning) { 9701 mStarts++; 9702 mRunningSince = mBsi.getBatteryUptimeLocked(); 9703 mRunning = true; 9704 } 9705 } 9706 stopRunningLocked()9707 public void stopRunningLocked() { 9708 if (mRunning) { 9709 long time = mBsi.getBatteryUptimeLocked() - mRunningSince; 9710 if (time > 0) { 9711 mStartTime += time; 9712 } else { 9713 mStarts--; 9714 } 9715 mRunning = false; 9716 } 9717 } 9718 getBatteryStats()9719 public BatteryStatsImpl getBatteryStats() { 9720 return mBsi; 9721 } 9722 9723 @Override getLaunches(int which)9724 public int getLaunches(int which) { 9725 int val = mLaunches; 9726 if (which == STATS_CURRENT) { 9727 val -= mLoadedLaunches; 9728 } else if (which == STATS_SINCE_UNPLUGGED) { 9729 val -= mUnpluggedLaunches; 9730 } 9731 return val; 9732 } 9733 9734 @Override getStartTime(long now, int which)9735 public long getStartTime(long now, int which) { 9736 long val = getStartTimeToNowLocked(now); 9737 if (which == STATS_CURRENT) { 9738 val -= mLoadedStartTime; 9739 } else if (which == STATS_SINCE_UNPLUGGED) { 9740 val -= mUnpluggedStartTime; 9741 } 9742 return val; 9743 } 9744 9745 @Override getStarts(int which)9746 public int getStarts(int which) { 9747 int val = mStarts; 9748 if (which == STATS_CURRENT) { 9749 val -= mLoadedStarts; 9750 } else if (which == STATS_SINCE_UNPLUGGED) { 9751 val -= mUnpluggedStarts; 9752 } 9753 9754 return val; 9755 } 9756 } 9757 newServiceStatsLocked()9758 final Serv newServiceStatsLocked() { 9759 return new Serv(mBsi); 9760 } 9761 } 9762 9763 /** 9764 * Retrieve the statistics object for a particular process, creating 9765 * if needed. 9766 */ getProcessStatsLocked(String name)9767 public Proc getProcessStatsLocked(String name) { 9768 Proc ps = mProcessStats.get(name); 9769 if (ps == null) { 9770 ps = new Proc(mBsi, name); 9771 mProcessStats.put(name, ps); 9772 } 9773 9774 return ps; 9775 } 9776 9777 @GuardedBy("mBsi") updateUidProcessStateLocked(int procState)9778 public void updateUidProcessStateLocked(int procState) { 9779 int uidRunningState; 9780 // Make special note of Foreground Services 9781 final boolean userAwareService = 9782 (procState == ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE); 9783 uidRunningState = BatteryStats.mapToInternalProcessState(procState); 9784 9785 if (mProcessState == uidRunningState && userAwareService == mInForegroundService) { 9786 return; 9787 } 9788 9789 final long elapsedRealtimeMs = mBsi.mClocks.elapsedRealtime(); 9790 if (mProcessState != uidRunningState) { 9791 final long uptimeMs = mBsi.mClocks.uptimeMillis(); 9792 9793 if (mProcessState != ActivityManager.PROCESS_STATE_NONEXISTENT) { 9794 mProcessStateTimer[mProcessState].stopRunningLocked(elapsedRealtimeMs); 9795 9796 if (mBsi.trackPerProcStateCpuTimes()) { 9797 if (mBsi.mPendingUids.size() == 0) { 9798 mBsi.mExternalSync.scheduleReadProcStateCpuTimes( 9799 mBsi.mOnBatteryTimeBase.isRunning(), 9800 mBsi.mOnBatteryScreenOffTimeBase.isRunning(), 9801 mBsi.mConstants.PROC_STATE_CPU_TIMES_READ_DELAY_MS); 9802 mBsi.mNumSingleUidCpuTimeReads++; 9803 } else { 9804 mBsi.mNumBatchedSingleUidCpuTimeReads++; 9805 } 9806 if (mBsi.mPendingUids.indexOfKey(mUid) < 0 9807 || ArrayUtils.contains(CRITICAL_PROC_STATES, mProcessState)) { 9808 mBsi.mPendingUids.put(mUid, mProcessState); 9809 } 9810 } else { 9811 mBsi.mPendingUids.clear(); 9812 } 9813 } 9814 mProcessState = uidRunningState; 9815 if (uidRunningState != ActivityManager.PROCESS_STATE_NONEXISTENT) { 9816 if (mProcessStateTimer[uidRunningState] == null) { 9817 makeProcessState(uidRunningState, null); 9818 } 9819 mProcessStateTimer[uidRunningState].startRunningLocked(elapsedRealtimeMs); 9820 } 9821 9822 updateOnBatteryBgTimeBase(uptimeMs * 1000, elapsedRealtimeMs * 1000); 9823 updateOnBatteryScreenOffBgTimeBase(uptimeMs * 1000, elapsedRealtimeMs * 1000); 9824 } 9825 9826 if (userAwareService != mInForegroundService) { 9827 if (userAwareService) { 9828 noteForegroundServiceResumedLocked(elapsedRealtimeMs); 9829 } else { 9830 noteForegroundServicePausedLocked(elapsedRealtimeMs); 9831 } 9832 mInForegroundService = userAwareService; 9833 } 9834 } 9835 9836 /** Whether to consider Uid to be in the background for background timebase purposes. */ isInBackground()9837 public boolean isInBackground() { 9838 // Note that PROCESS_STATE_CACHED and ActivityManager.PROCESS_STATE_NONEXISTENT is 9839 // also considered to be 'background' for our purposes, because it's not foreground. 9840 return mProcessState >= PROCESS_STATE_BACKGROUND; 9841 } 9842 updateOnBatteryBgTimeBase(long uptimeUs, long realtimeUs)9843 public boolean updateOnBatteryBgTimeBase(long uptimeUs, long realtimeUs) { 9844 boolean on = mBsi.mOnBatteryTimeBase.isRunning() && isInBackground(); 9845 return mOnBatteryBackgroundTimeBase.setRunning(on, uptimeUs, realtimeUs); 9846 } 9847 updateOnBatteryScreenOffBgTimeBase(long uptimeUs, long realtimeUs)9848 public boolean updateOnBatteryScreenOffBgTimeBase(long uptimeUs, long realtimeUs) { 9849 boolean on = mBsi.mOnBatteryScreenOffTimeBase.isRunning() && isInBackground(); 9850 return mOnBatteryScreenOffBackgroundTimeBase.setRunning(on, uptimeUs, realtimeUs); 9851 } 9852 getPidStats()9853 public SparseArray<? extends Pid> getPidStats() { 9854 return mPids; 9855 } 9856 getPidStatsLocked(int pid)9857 public Pid getPidStatsLocked(int pid) { 9858 Pid p = mPids.get(pid); 9859 if (p == null) { 9860 p = new Pid(); 9861 mPids.put(pid, p); 9862 } 9863 return p; 9864 } 9865 9866 /** 9867 * Retrieve the statistics object for a particular service, creating 9868 * if needed. 9869 */ getPackageStatsLocked(String name)9870 public Pkg getPackageStatsLocked(String name) { 9871 Pkg ps = mPackageStats.get(name); 9872 if (ps == null) { 9873 ps = new Pkg(mBsi); 9874 mPackageStats.put(name, ps); 9875 } 9876 9877 return ps; 9878 } 9879 9880 /** 9881 * Retrieve the statistics object for a particular service, creating 9882 * if needed. 9883 */ getServiceStatsLocked(String pkg, String serv)9884 public Pkg.Serv getServiceStatsLocked(String pkg, String serv) { 9885 Pkg ps = getPackageStatsLocked(pkg); 9886 Pkg.Serv ss = ps.mServiceStats.get(serv); 9887 if (ss == null) { 9888 ss = ps.newServiceStatsLocked(); 9889 ps.mServiceStats.put(serv, ss); 9890 } 9891 9892 return ss; 9893 } 9894 readSyncSummaryFromParcelLocked(String name, Parcel in)9895 public void readSyncSummaryFromParcelLocked(String name, Parcel in) { 9896 DualTimer timer = mSyncStats.instantiateObject(); 9897 timer.readSummaryFromParcelLocked(in); 9898 mSyncStats.add(name, timer); 9899 } 9900 readJobSummaryFromParcelLocked(String name, Parcel in)9901 public void readJobSummaryFromParcelLocked(String name, Parcel in) { 9902 DualTimer timer = mJobStats.instantiateObject(); 9903 timer.readSummaryFromParcelLocked(in); 9904 mJobStats.add(name, timer); 9905 } 9906 readWakeSummaryFromParcelLocked(String wlName, Parcel in)9907 public void readWakeSummaryFromParcelLocked(String wlName, Parcel in) { 9908 Wakelock wl = new Wakelock(mBsi, this); 9909 mWakelockStats.add(wlName, wl); 9910 if (in.readInt() != 0) { 9911 getWakelockTimerLocked(wl, WAKE_TYPE_FULL).readSummaryFromParcelLocked(in); 9912 } 9913 if (in.readInt() != 0) { 9914 getWakelockTimerLocked(wl, WAKE_TYPE_PARTIAL).readSummaryFromParcelLocked(in); 9915 } 9916 if (in.readInt() != 0) { 9917 getWakelockTimerLocked(wl, WAKE_TYPE_WINDOW).readSummaryFromParcelLocked(in); 9918 } 9919 if (in.readInt() != 0) { 9920 getWakelockTimerLocked(wl, WAKE_TYPE_DRAW).readSummaryFromParcelLocked(in); 9921 } 9922 } 9923 getSensorTimerLocked(int sensor, boolean create)9924 public DualTimer getSensorTimerLocked(int sensor, boolean create) { 9925 Sensor se = mSensorStats.get(sensor); 9926 if (se == null) { 9927 if (!create) { 9928 return null; 9929 } 9930 se = new Sensor(mBsi, this, sensor); 9931 mSensorStats.put(sensor, se); 9932 } 9933 DualTimer t = se.mTimer; 9934 if (t != null) { 9935 return t; 9936 } 9937 ArrayList<StopwatchTimer> timers = mBsi.mSensorTimers.get(sensor); 9938 if (timers == null) { 9939 timers = new ArrayList<StopwatchTimer>(); 9940 mBsi.mSensorTimers.put(sensor, timers); 9941 } 9942 t = new DualTimer(mBsi.mClocks, this, BatteryStats.SENSOR, timers, 9943 mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase); 9944 se.mTimer = t; 9945 return t; 9946 } 9947 noteStartSyncLocked(String name, long elapsedRealtimeMs)9948 public void noteStartSyncLocked(String name, long elapsedRealtimeMs) { 9949 DualTimer t = mSyncStats.startObject(name); 9950 if (t != null) { 9951 t.startRunningLocked(elapsedRealtimeMs); 9952 } 9953 } 9954 noteStopSyncLocked(String name, long elapsedRealtimeMs)9955 public void noteStopSyncLocked(String name, long elapsedRealtimeMs) { 9956 DualTimer t = mSyncStats.stopObject(name); 9957 if (t != null) { 9958 t.stopRunningLocked(elapsedRealtimeMs); 9959 } 9960 } 9961 noteStartJobLocked(String name, long elapsedRealtimeMs)9962 public void noteStartJobLocked(String name, long elapsedRealtimeMs) { 9963 DualTimer t = mJobStats.startObject(name); 9964 if (t != null) { 9965 t.startRunningLocked(elapsedRealtimeMs); 9966 } 9967 } 9968 noteStopJobLocked(String name, long elapsedRealtimeMs, int stopReason)9969 public void noteStopJobLocked(String name, long elapsedRealtimeMs, int stopReason) { 9970 DualTimer t = mJobStats.stopObject(name); 9971 if (t != null) { 9972 t.stopRunningLocked(elapsedRealtimeMs); 9973 } 9974 if (mBsi.mOnBatteryTimeBase.isRunning()) { 9975 SparseIntArray types = mJobCompletions.get(name); 9976 if (types == null) { 9977 types = new SparseIntArray(); 9978 mJobCompletions.put(name, types); 9979 } 9980 int last = types.get(stopReason, 0); 9981 types.put(stopReason, last + 1); 9982 } 9983 } 9984 getWakelockTimerLocked(Wakelock wl, int type)9985 public StopwatchTimer getWakelockTimerLocked(Wakelock wl, int type) { 9986 if (wl == null) { 9987 return null; 9988 } 9989 switch (type) { 9990 case WAKE_TYPE_PARTIAL: { 9991 DualTimer t = wl.mTimerPartial; 9992 if (t == null) { 9993 t = new DualTimer(mBsi.mClocks, this, WAKE_TYPE_PARTIAL, 9994 mBsi.mPartialTimers, mBsi.mOnBatteryScreenOffTimeBase, 9995 mOnBatteryScreenOffBackgroundTimeBase); 9996 wl.mTimerPartial = t; 9997 } 9998 return t; 9999 } 10000 case WAKE_TYPE_FULL: { 10001 StopwatchTimer t = wl.mTimerFull; 10002 if (t == null) { 10003 t = new StopwatchTimer(mBsi.mClocks, this, WAKE_TYPE_FULL, 10004 mBsi.mFullTimers, mBsi.mOnBatteryTimeBase); 10005 wl.mTimerFull = t; 10006 } 10007 return t; 10008 } 10009 case WAKE_TYPE_WINDOW: { 10010 StopwatchTimer t = wl.mTimerWindow; 10011 if (t == null) { 10012 t = new StopwatchTimer(mBsi.mClocks, this, WAKE_TYPE_WINDOW, 10013 mBsi.mWindowTimers, mBsi.mOnBatteryTimeBase); 10014 wl.mTimerWindow = t; 10015 } 10016 return t; 10017 } 10018 case WAKE_TYPE_DRAW: { 10019 StopwatchTimer t = wl.mTimerDraw; 10020 if (t == null) { 10021 t = new StopwatchTimer(mBsi.mClocks, this, WAKE_TYPE_DRAW, 10022 mBsi.mDrawTimers, mBsi.mOnBatteryTimeBase); 10023 wl.mTimerDraw = t; 10024 } 10025 return t; 10026 } 10027 default: 10028 throw new IllegalArgumentException("type=" + type); 10029 } 10030 } 10031 noteStartWakeLocked(int pid, String name, int type, long elapsedRealtimeMs)10032 public void noteStartWakeLocked(int pid, String name, int type, long elapsedRealtimeMs) { 10033 Wakelock wl = mWakelockStats.startObject(name); 10034 if (wl != null) { 10035 getWakelockTimerLocked(wl, type).startRunningLocked(elapsedRealtimeMs); 10036 } 10037 if (type == WAKE_TYPE_PARTIAL) { 10038 createAggregatedPartialWakelockTimerLocked().startRunningLocked(elapsedRealtimeMs); 10039 if (pid >= 0) { 10040 Pid p = getPidStatsLocked(pid); 10041 if (p.mWakeNesting++ == 0) { 10042 p.mWakeStartMs = elapsedRealtimeMs; 10043 } 10044 } 10045 } 10046 } 10047 noteStopWakeLocked(int pid, String name, int type, long elapsedRealtimeMs)10048 public void noteStopWakeLocked(int pid, String name, int type, long elapsedRealtimeMs) { 10049 Wakelock wl = mWakelockStats.stopObject(name); 10050 if (wl != null) { 10051 StopwatchTimer wlt = getWakelockTimerLocked(wl, type); 10052 wlt.stopRunningLocked(elapsedRealtimeMs); 10053 } 10054 if (type == WAKE_TYPE_PARTIAL) { 10055 if (mAggregatedPartialWakelockTimer != null) { 10056 mAggregatedPartialWakelockTimer.stopRunningLocked(elapsedRealtimeMs); 10057 } 10058 if (pid >= 0) { 10059 Pid p = mPids.get(pid); 10060 if (p != null && p.mWakeNesting > 0) { 10061 if (p.mWakeNesting-- == 1) { 10062 p.mWakeSumMs += elapsedRealtimeMs - p.mWakeStartMs; 10063 p.mWakeStartMs = 0; 10064 } 10065 } 10066 } 10067 } 10068 } 10069 reportExcessiveCpuLocked(String proc, long overTime, long usedTime)10070 public void reportExcessiveCpuLocked(String proc, long overTime, long usedTime) { 10071 Proc p = getProcessStatsLocked(proc); 10072 if (p != null) { 10073 p.addExcessiveCpu(overTime, usedTime); 10074 } 10075 } 10076 noteStartSensor(int sensor, long elapsedRealtimeMs)10077 public void noteStartSensor(int sensor, long elapsedRealtimeMs) { 10078 DualTimer t = getSensorTimerLocked(sensor, /* create= */ true); 10079 t.startRunningLocked(elapsedRealtimeMs); 10080 } 10081 noteStopSensor(int sensor, long elapsedRealtimeMs)10082 public void noteStopSensor(int sensor, long elapsedRealtimeMs) { 10083 // Don't create a timer if one doesn't already exist 10084 DualTimer t = getSensorTimerLocked(sensor, false); 10085 if (t != null) { 10086 t.stopRunningLocked(elapsedRealtimeMs); 10087 } 10088 } 10089 noteStartGps(long elapsedRealtimeMs)10090 public void noteStartGps(long elapsedRealtimeMs) { 10091 noteStartSensor(Sensor.GPS, elapsedRealtimeMs); 10092 } 10093 noteStopGps(long elapsedRealtimeMs)10094 public void noteStopGps(long elapsedRealtimeMs) { 10095 noteStopSensor(Sensor.GPS, elapsedRealtimeMs); 10096 } 10097 getBatteryStats()10098 public BatteryStatsImpl getBatteryStats() { 10099 return mBsi; 10100 } 10101 } 10102 getCpuFreqs()10103 public long[] getCpuFreqs() { 10104 return mCpuFreqs; 10105 } 10106 BatteryStatsImpl(File systemDir, Handler handler, PlatformIdleStateCallback cb, UserInfoProvider userInfoProvider)10107 public BatteryStatsImpl(File systemDir, Handler handler, PlatformIdleStateCallback cb, 10108 UserInfoProvider userInfoProvider) { 10109 this(new SystemClocks(), systemDir, handler, cb, userInfoProvider); 10110 } 10111 BatteryStatsImpl(Clocks clocks, File systemDir, Handler handler, PlatformIdleStateCallback cb, UserInfoProvider userInfoProvider)10112 private BatteryStatsImpl(Clocks clocks, File systemDir, Handler handler, 10113 PlatformIdleStateCallback cb, 10114 UserInfoProvider userInfoProvider) { 10115 init(clocks); 10116 10117 if (systemDir != null) { 10118 mFile = new JournaledFile(new File(systemDir, "batterystats.bin"), 10119 new File(systemDir, "batterystats.bin.tmp")); 10120 } else { 10121 mFile = null; 10122 } 10123 mCheckinFile = new AtomicFile(new File(systemDir, "batterystats-checkin.bin")); 10124 mDailyFile = new AtomicFile(new File(systemDir, "batterystats-daily.xml")); 10125 mHandler = new MyHandler(handler.getLooper()); 10126 mConstants = new Constants(mHandler); 10127 mStartCount++; 10128 mScreenOnTimer = new StopwatchTimer(mClocks, null, -1, null, mOnBatteryTimeBase); 10129 mScreenDozeTimer = new StopwatchTimer(mClocks, null, -1, null, mOnBatteryTimeBase); 10130 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 10131 mScreenBrightnessTimer[i] = new StopwatchTimer(mClocks, null, -100-i, null, 10132 mOnBatteryTimeBase); 10133 } 10134 mInteractiveTimer = new StopwatchTimer(mClocks, null, -10, null, mOnBatteryTimeBase); 10135 mPowerSaveModeEnabledTimer = new StopwatchTimer(mClocks, null, -2, null, 10136 mOnBatteryTimeBase); 10137 mDeviceIdleModeLightTimer = new StopwatchTimer(mClocks, null, -11, null, 10138 mOnBatteryTimeBase); 10139 mDeviceIdleModeFullTimer = new StopwatchTimer(mClocks, null, -14, null, mOnBatteryTimeBase); 10140 mDeviceLightIdlingTimer = new StopwatchTimer(mClocks, null, -15, null, mOnBatteryTimeBase); 10141 mDeviceIdlingTimer = new StopwatchTimer(mClocks, null, -12, null, mOnBatteryTimeBase); 10142 mPhoneOnTimer = new StopwatchTimer(mClocks, null, -3, null, mOnBatteryTimeBase); 10143 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) { 10144 mPhoneSignalStrengthsTimer[i] = new StopwatchTimer(mClocks, null, -200-i, null, 10145 mOnBatteryTimeBase); 10146 } 10147 mPhoneSignalScanningTimer = new StopwatchTimer(mClocks, null, -200+1, null, 10148 mOnBatteryTimeBase); 10149 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 10150 mPhoneDataConnectionsTimer[i] = new StopwatchTimer(mClocks, null, -300-i, null, 10151 mOnBatteryTimeBase); 10152 } 10153 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 10154 mNetworkByteActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase); 10155 mNetworkPacketActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase); 10156 } 10157 mWifiActivity = new ControllerActivityCounterImpl(mOnBatteryTimeBase, NUM_WIFI_TX_LEVELS); 10158 mBluetoothActivity = new ControllerActivityCounterImpl(mOnBatteryTimeBase, 10159 NUM_BT_TX_LEVELS); 10160 mModemActivity = new ControllerActivityCounterImpl(mOnBatteryTimeBase, 10161 ModemActivityInfo.TX_POWER_LEVELS); 10162 mMobileRadioActiveTimer = new StopwatchTimer(mClocks, null, -400, null, mOnBatteryTimeBase); 10163 mMobileRadioActivePerAppTimer = new StopwatchTimer(mClocks, null, -401, null, 10164 mOnBatteryTimeBase); 10165 mMobileRadioActiveAdjustedTime = new LongSamplingCounter(mOnBatteryTimeBase); 10166 mMobileRadioActiveUnknownTime = new LongSamplingCounter(mOnBatteryTimeBase); 10167 mMobileRadioActiveUnknownCount = new LongSamplingCounter(mOnBatteryTimeBase); 10168 mWifiMulticastWakelockTimer = new StopwatchTimer(mClocks, null, 10169 WIFI_AGGREGATE_MULTICAST_ENABLED, null, mOnBatteryTimeBase); 10170 mWifiOnTimer = new StopwatchTimer(mClocks, null, -4, null, mOnBatteryTimeBase); 10171 mGlobalWifiRunningTimer = new StopwatchTimer(mClocks, null, -5, null, mOnBatteryTimeBase); 10172 for (int i=0; i<NUM_WIFI_STATES; i++) { 10173 mWifiStateTimer[i] = new StopwatchTimer(mClocks, null, -600-i, null, 10174 mOnBatteryTimeBase); 10175 } 10176 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) { 10177 mWifiSupplStateTimer[i] = new StopwatchTimer(mClocks, null, -700-i, null, 10178 mOnBatteryTimeBase); 10179 } 10180 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { 10181 mWifiSignalStrengthsTimer[i] = new StopwatchTimer(mClocks, null, -800-i, null, 10182 mOnBatteryTimeBase); 10183 } 10184 mWifiActiveTimer = new StopwatchTimer(mClocks, null, -900, null, mOnBatteryTimeBase); 10185 for (int i=0; i< GnssMetrics.NUM_GPS_SIGNAL_QUALITY_LEVELS; i++) { 10186 mGpsSignalQualityTimer[i] = new StopwatchTimer(mClocks, null, -1000-i, null, 10187 mOnBatteryTimeBase); 10188 } 10189 mAudioOnTimer = new StopwatchTimer(mClocks, null, -7, null, mOnBatteryTimeBase); 10190 mVideoOnTimer = new StopwatchTimer(mClocks, null, -8, null, mOnBatteryTimeBase); 10191 mFlashlightOnTimer = new StopwatchTimer(mClocks, null, -9, null, mOnBatteryTimeBase); 10192 mCameraOnTimer = new StopwatchTimer(mClocks, null, -13, null, mOnBatteryTimeBase); 10193 mBluetoothScanTimer = new StopwatchTimer(mClocks, null, -14, null, mOnBatteryTimeBase); 10194 mDischargeScreenOffCounter = new LongSamplingCounter(mOnBatteryScreenOffTimeBase); 10195 mDischargeScreenDozeCounter = new LongSamplingCounter(mOnBatteryTimeBase); 10196 mDischargeLightDozeCounter = new LongSamplingCounter(mOnBatteryTimeBase); 10197 mDischargeDeepDozeCounter = new LongSamplingCounter(mOnBatteryTimeBase); 10198 mDischargeCounter = new LongSamplingCounter(mOnBatteryTimeBase); 10199 mOnBattery = mOnBatteryInternal = false; 10200 long uptime = mClocks.uptimeMillis() * 1000; 10201 long realtime = mClocks.elapsedRealtime() * 1000; 10202 initTimes(uptime, realtime); 10203 mStartPlatformVersion = mEndPlatformVersion = Build.ID; 10204 mDischargeStartLevel = 0; 10205 mDischargeUnplugLevel = 0; 10206 mDischargePlugLevel = -1; 10207 mDischargeCurrentLevel = 0; 10208 mCurrentBatteryLevel = 0; 10209 initDischarge(); 10210 clearHistoryLocked(); 10211 updateDailyDeadlineLocked(); 10212 mPlatformIdleStateCallback = cb; 10213 mUserInfoProvider = userInfoProvider; 10214 } 10215 BatteryStatsImpl(Parcel p)10216 public BatteryStatsImpl(Parcel p) { 10217 this(new SystemClocks(), p); 10218 } 10219 BatteryStatsImpl(Clocks clocks, Parcel p)10220 public BatteryStatsImpl(Clocks clocks, Parcel p) { 10221 init(clocks); 10222 mFile = null; 10223 mCheckinFile = null; 10224 mDailyFile = null; 10225 mHandler = null; 10226 mExternalSync = null; 10227 mConstants = new Constants(mHandler); 10228 clearHistoryLocked(); 10229 readFromParcel(p); 10230 mPlatformIdleStateCallback = null; 10231 } 10232 setPowerProfileLocked(PowerProfile profile)10233 public void setPowerProfileLocked(PowerProfile profile) { 10234 mPowerProfile = profile; 10235 10236 // We need to initialize the KernelCpuSpeedReaders to read from 10237 // the first cpu of each core. Once we have the PowerProfile, we have access to this 10238 // information. 10239 final int numClusters = mPowerProfile.getNumCpuClusters(); 10240 mKernelCpuSpeedReaders = new KernelCpuSpeedReader[numClusters]; 10241 int firstCpuOfCluster = 0; 10242 for (int i = 0; i < numClusters; i++) { 10243 final int numSpeedSteps = mPowerProfile.getNumSpeedStepsInCpuCluster(i); 10244 mKernelCpuSpeedReaders[i] = new KernelCpuSpeedReader(firstCpuOfCluster, 10245 numSpeedSteps); 10246 firstCpuOfCluster += mPowerProfile.getNumCoresInCpuCluster(i); 10247 } 10248 10249 if (mEstimatedBatteryCapacity == -1) { 10250 // Initialize the estimated battery capacity to a known preset one. 10251 mEstimatedBatteryCapacity = (int) mPowerProfile.getBatteryCapacity(); 10252 } 10253 } 10254 setCallback(BatteryCallback cb)10255 public void setCallback(BatteryCallback cb) { 10256 mCallback = cb; 10257 } 10258 setRadioScanningTimeoutLocked(long timeout)10259 public void setRadioScanningTimeoutLocked(long timeout) { 10260 if (mPhoneSignalScanningTimer != null) { 10261 mPhoneSignalScanningTimer.setTimeout(timeout); 10262 } 10263 } 10264 setExternalStatsSyncLocked(ExternalStatsSync sync)10265 public void setExternalStatsSyncLocked(ExternalStatsSync sync) { 10266 mExternalSync = sync; 10267 } 10268 updateDailyDeadlineLocked()10269 public void updateDailyDeadlineLocked() { 10270 // Get the current time. 10271 long currentTime = mDailyStartTime = System.currentTimeMillis(); 10272 Calendar calDeadline = Calendar.getInstance(); 10273 calDeadline.setTimeInMillis(currentTime); 10274 10275 // Move time up to the next day, ranging from 1am to 3pm. 10276 calDeadline.set(Calendar.DAY_OF_YEAR, calDeadline.get(Calendar.DAY_OF_YEAR) + 1); 10277 calDeadline.set(Calendar.MILLISECOND, 0); 10278 calDeadline.set(Calendar.SECOND, 0); 10279 calDeadline.set(Calendar.MINUTE, 0); 10280 calDeadline.set(Calendar.HOUR_OF_DAY, 1); 10281 mNextMinDailyDeadline = calDeadline.getTimeInMillis(); 10282 calDeadline.set(Calendar.HOUR_OF_DAY, 3); 10283 mNextMaxDailyDeadline = calDeadline.getTimeInMillis(); 10284 } 10285 recordDailyStatsIfNeededLocked(boolean settled)10286 public void recordDailyStatsIfNeededLocked(boolean settled) { 10287 long currentTime = System.currentTimeMillis(); 10288 if (currentTime >= mNextMaxDailyDeadline) { 10289 recordDailyStatsLocked(); 10290 } else if (settled && currentTime >= mNextMinDailyDeadline) { 10291 recordDailyStatsLocked(); 10292 } else if (currentTime < (mDailyStartTime-(1000*60*60*24))) { 10293 recordDailyStatsLocked(); 10294 } 10295 } 10296 recordDailyStatsLocked()10297 public void recordDailyStatsLocked() { 10298 DailyItem item = new DailyItem(); 10299 item.mStartTime = mDailyStartTime; 10300 item.mEndTime = System.currentTimeMillis(); 10301 boolean hasData = false; 10302 if (mDailyDischargeStepTracker.mNumStepDurations > 0) { 10303 hasData = true; 10304 item.mDischargeSteps = new LevelStepTracker( 10305 mDailyDischargeStepTracker.mNumStepDurations, 10306 mDailyDischargeStepTracker.mStepDurations); 10307 } 10308 if (mDailyChargeStepTracker.mNumStepDurations > 0) { 10309 hasData = true; 10310 item.mChargeSteps = new LevelStepTracker( 10311 mDailyChargeStepTracker.mNumStepDurations, 10312 mDailyChargeStepTracker.mStepDurations); 10313 } 10314 if (mDailyPackageChanges != null) { 10315 hasData = true; 10316 item.mPackageChanges = mDailyPackageChanges; 10317 mDailyPackageChanges = null; 10318 } 10319 mDailyDischargeStepTracker.init(); 10320 mDailyChargeStepTracker.init(); 10321 updateDailyDeadlineLocked(); 10322 10323 if (hasData) { 10324 final long startTime = SystemClock.uptimeMillis(); 10325 mDailyItems.add(item); 10326 while (mDailyItems.size() > MAX_DAILY_ITEMS) { 10327 mDailyItems.remove(0); 10328 } 10329 final ByteArrayOutputStream memStream = new ByteArrayOutputStream(); 10330 try { 10331 XmlSerializer out = new FastXmlSerializer(); 10332 out.setOutput(memStream, StandardCharsets.UTF_8.name()); 10333 writeDailyItemsLocked(out); 10334 final long initialTime = SystemClock.uptimeMillis() - startTime; 10335 BackgroundThread.getHandler().post(new Runnable() { 10336 @Override 10337 public void run() { 10338 synchronized (mCheckinFile) { 10339 final long startTime2 = SystemClock.uptimeMillis(); 10340 FileOutputStream stream = null; 10341 try { 10342 stream = mDailyFile.startWrite(); 10343 memStream.writeTo(stream); 10344 stream.flush(); 10345 FileUtils.sync(stream); 10346 stream.close(); 10347 mDailyFile.finishWrite(stream); 10348 com.android.internal.logging.EventLogTags.writeCommitSysConfigFile( 10349 "batterystats-daily", 10350 initialTime + SystemClock.uptimeMillis() - startTime2); 10351 } catch (IOException e) { 10352 Slog.w("BatteryStats", 10353 "Error writing battery daily items", e); 10354 mDailyFile.failWrite(stream); 10355 } 10356 } 10357 } 10358 }); 10359 } catch (IOException e) { 10360 } 10361 } 10362 } 10363 writeDailyItemsLocked(XmlSerializer out)10364 private void writeDailyItemsLocked(XmlSerializer out) throws IOException { 10365 StringBuilder sb = new StringBuilder(64); 10366 out.startDocument(null, true); 10367 out.startTag(null, "daily-items"); 10368 for (int i=0; i<mDailyItems.size(); i++) { 10369 final DailyItem dit = mDailyItems.get(i); 10370 out.startTag(null, "item"); 10371 out.attribute(null, "start", Long.toString(dit.mStartTime)); 10372 out.attribute(null, "end", Long.toString(dit.mEndTime)); 10373 writeDailyLevelSteps(out, "dis", dit.mDischargeSteps, sb); 10374 writeDailyLevelSteps(out, "chg", dit.mChargeSteps, sb); 10375 if (dit.mPackageChanges != null) { 10376 for (int j=0; j<dit.mPackageChanges.size(); j++) { 10377 PackageChange pc = dit.mPackageChanges.get(j); 10378 if (pc.mUpdate) { 10379 out.startTag(null, "upd"); 10380 out.attribute(null, "pkg", pc.mPackageName); 10381 out.attribute(null, "ver", Long.toString(pc.mVersionCode)); 10382 out.endTag(null, "upd"); 10383 } else { 10384 out.startTag(null, "rem"); 10385 out.attribute(null, "pkg", pc.mPackageName); 10386 out.endTag(null, "rem"); 10387 } 10388 } 10389 } 10390 out.endTag(null, "item"); 10391 } 10392 out.endTag(null, "daily-items"); 10393 out.endDocument(); 10394 } 10395 writeDailyLevelSteps(XmlSerializer out, String tag, LevelStepTracker steps, StringBuilder tmpBuilder)10396 private void writeDailyLevelSteps(XmlSerializer out, String tag, LevelStepTracker steps, 10397 StringBuilder tmpBuilder) throws IOException { 10398 if (steps != null) { 10399 out.startTag(null, tag); 10400 out.attribute(null, "n", Integer.toString(steps.mNumStepDurations)); 10401 for (int i=0; i<steps.mNumStepDurations; i++) { 10402 out.startTag(null, "s"); 10403 tmpBuilder.setLength(0); 10404 steps.encodeEntryAt(i, tmpBuilder); 10405 out.attribute(null, "v", tmpBuilder.toString()); 10406 out.endTag(null, "s"); 10407 } 10408 out.endTag(null, tag); 10409 } 10410 } 10411 readDailyStatsLocked()10412 public void readDailyStatsLocked() { 10413 Slog.d(TAG, "Reading daily items from " + mDailyFile.getBaseFile()); 10414 mDailyItems.clear(); 10415 FileInputStream stream; 10416 try { 10417 stream = mDailyFile.openRead(); 10418 } catch (FileNotFoundException e) { 10419 return; 10420 } 10421 try { 10422 XmlPullParser parser = Xml.newPullParser(); 10423 parser.setInput(stream, StandardCharsets.UTF_8.name()); 10424 readDailyItemsLocked(parser); 10425 } catch (XmlPullParserException e) { 10426 } finally { 10427 try { 10428 stream.close(); 10429 } catch (IOException e) { 10430 } 10431 } 10432 } 10433 readDailyItemsLocked(XmlPullParser parser)10434 private void readDailyItemsLocked(XmlPullParser parser) { 10435 try { 10436 int type; 10437 while ((type = parser.next()) != XmlPullParser.START_TAG 10438 && type != XmlPullParser.END_DOCUMENT) { 10439 ; 10440 } 10441 10442 if (type != XmlPullParser.START_TAG) { 10443 throw new IllegalStateException("no start tag found"); 10444 } 10445 10446 int outerDepth = parser.getDepth(); 10447 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 10448 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 10449 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 10450 continue; 10451 } 10452 10453 String tagName = parser.getName(); 10454 if (tagName.equals("item")) { 10455 readDailyItemTagLocked(parser); 10456 } else { 10457 Slog.w(TAG, "Unknown element under <daily-items>: " 10458 + parser.getName()); 10459 XmlUtils.skipCurrentTag(parser); 10460 } 10461 } 10462 10463 } catch (IllegalStateException e) { 10464 Slog.w(TAG, "Failed parsing daily " + e); 10465 } catch (NullPointerException e) { 10466 Slog.w(TAG, "Failed parsing daily " + e); 10467 } catch (NumberFormatException e) { 10468 Slog.w(TAG, "Failed parsing daily " + e); 10469 } catch (XmlPullParserException e) { 10470 Slog.w(TAG, "Failed parsing daily " + e); 10471 } catch (IOException e) { 10472 Slog.w(TAG, "Failed parsing daily " + e); 10473 } catch (IndexOutOfBoundsException e) { 10474 Slog.w(TAG, "Failed parsing daily " + e); 10475 } 10476 } 10477 readDailyItemTagLocked(XmlPullParser parser)10478 void readDailyItemTagLocked(XmlPullParser parser) throws NumberFormatException, 10479 XmlPullParserException, IOException { 10480 DailyItem dit = new DailyItem(); 10481 String attr = parser.getAttributeValue(null, "start"); 10482 if (attr != null) { 10483 dit.mStartTime = Long.parseLong(attr); 10484 } 10485 attr = parser.getAttributeValue(null, "end"); 10486 if (attr != null) { 10487 dit.mEndTime = Long.parseLong(attr); 10488 } 10489 int outerDepth = parser.getDepth(); 10490 int type; 10491 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 10492 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 10493 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 10494 continue; 10495 } 10496 10497 String tagName = parser.getName(); 10498 if (tagName.equals("dis")) { 10499 readDailyItemTagDetailsLocked(parser, dit, false, "dis"); 10500 } else if (tagName.equals("chg")) { 10501 readDailyItemTagDetailsLocked(parser, dit, true, "chg"); 10502 } else if (tagName.equals("upd")) { 10503 if (dit.mPackageChanges == null) { 10504 dit.mPackageChanges = new ArrayList<>(); 10505 } 10506 PackageChange pc = new PackageChange(); 10507 pc.mUpdate = true; 10508 pc.mPackageName = parser.getAttributeValue(null, "pkg"); 10509 String verStr = parser.getAttributeValue(null, "ver"); 10510 pc.mVersionCode = verStr != null ? Long.parseLong(verStr) : 0; 10511 dit.mPackageChanges.add(pc); 10512 XmlUtils.skipCurrentTag(parser); 10513 } else if (tagName.equals("rem")) { 10514 if (dit.mPackageChanges == null) { 10515 dit.mPackageChanges = new ArrayList<>(); 10516 } 10517 PackageChange pc = new PackageChange(); 10518 pc.mUpdate = false; 10519 pc.mPackageName = parser.getAttributeValue(null, "pkg"); 10520 dit.mPackageChanges.add(pc); 10521 XmlUtils.skipCurrentTag(parser); 10522 } else { 10523 Slog.w(TAG, "Unknown element under <item>: " 10524 + parser.getName()); 10525 XmlUtils.skipCurrentTag(parser); 10526 } 10527 } 10528 mDailyItems.add(dit); 10529 } 10530 readDailyItemTagDetailsLocked(XmlPullParser parser, DailyItem dit, boolean isCharge, String tag)10531 void readDailyItemTagDetailsLocked(XmlPullParser parser, DailyItem dit, boolean isCharge, 10532 String tag) 10533 throws NumberFormatException, XmlPullParserException, IOException { 10534 final String numAttr = parser.getAttributeValue(null, "n"); 10535 if (numAttr == null) { 10536 Slog.w(TAG, "Missing 'n' attribute at " + parser.getPositionDescription()); 10537 XmlUtils.skipCurrentTag(parser); 10538 return; 10539 } 10540 final int num = Integer.parseInt(numAttr); 10541 LevelStepTracker steps = new LevelStepTracker(num); 10542 if (isCharge) { 10543 dit.mChargeSteps = steps; 10544 } else { 10545 dit.mDischargeSteps = steps; 10546 } 10547 int i = 0; 10548 int outerDepth = parser.getDepth(); 10549 int type; 10550 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 10551 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 10552 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 10553 continue; 10554 } 10555 10556 String tagName = parser.getName(); 10557 if ("s".equals(tagName)) { 10558 if (i < num) { 10559 String valueAttr = parser.getAttributeValue(null, "v"); 10560 if (valueAttr != null) { 10561 steps.decodeEntryAt(i, valueAttr); 10562 i++; 10563 } 10564 } 10565 } else { 10566 Slog.w(TAG, "Unknown element under <" + tag + ">: " 10567 + parser.getName()); 10568 XmlUtils.skipCurrentTag(parser); 10569 } 10570 } 10571 steps.mNumStepDurations = i; 10572 } 10573 10574 @Override getDailyItemLocked(int daysAgo)10575 public DailyItem getDailyItemLocked(int daysAgo) { 10576 int index = mDailyItems.size()-1-daysAgo; 10577 return index >= 0 ? mDailyItems.get(index) : null; 10578 } 10579 10580 @Override getCurrentDailyStartTime()10581 public long getCurrentDailyStartTime() { 10582 return mDailyStartTime; 10583 } 10584 10585 @Override getNextMinDailyDeadline()10586 public long getNextMinDailyDeadline() { 10587 return mNextMinDailyDeadline; 10588 } 10589 10590 @Override getNextMaxDailyDeadline()10591 public long getNextMaxDailyDeadline() { 10592 return mNextMaxDailyDeadline; 10593 } 10594 10595 @Override startIteratingOldHistoryLocked()10596 public boolean startIteratingOldHistoryLocked() { 10597 if (DEBUG_HISTORY) Slog.i(TAG, "ITERATING: buff size=" + mHistoryBuffer.dataSize() 10598 + " pos=" + mHistoryBuffer.dataPosition()); 10599 if ((mHistoryIterator = mHistory) == null) { 10600 return false; 10601 } 10602 mHistoryBuffer.setDataPosition(0); 10603 mHistoryReadTmp.clear(); 10604 mReadOverflow = false; 10605 mIteratingHistory = true; 10606 return true; 10607 } 10608 10609 @Override getNextOldHistoryLocked(HistoryItem out)10610 public boolean getNextOldHistoryLocked(HistoryItem out) { 10611 boolean end = mHistoryBuffer.dataPosition() >= mHistoryBuffer.dataSize(); 10612 if (!end) { 10613 readHistoryDelta(mHistoryBuffer, mHistoryReadTmp); 10614 mReadOverflow |= mHistoryReadTmp.cmd == HistoryItem.CMD_OVERFLOW; 10615 } 10616 HistoryItem cur = mHistoryIterator; 10617 if (cur == null) { 10618 if (!mReadOverflow && !end) { 10619 Slog.w(TAG, "Old history ends before new history!"); 10620 } 10621 return false; 10622 } 10623 out.setTo(cur); 10624 mHistoryIterator = cur.next; 10625 if (!mReadOverflow) { 10626 if (end) { 10627 Slog.w(TAG, "New history ends before old history!"); 10628 } else if (!out.same(mHistoryReadTmp)) { 10629 PrintWriter pw = new FastPrintWriter(new LogWriter(android.util.Log.WARN, TAG)); 10630 pw.println("Histories differ!"); 10631 pw.println("Old history:"); 10632 (new HistoryPrinter()).printNextItem(pw, out, 0, false, true); 10633 pw.println("New history:"); 10634 (new HistoryPrinter()).printNextItem(pw, mHistoryReadTmp, 0, false, 10635 true); 10636 pw.flush(); 10637 } 10638 } 10639 return true; 10640 } 10641 10642 @Override finishIteratingOldHistoryLocked()10643 public void finishIteratingOldHistoryLocked() { 10644 mIteratingHistory = false; 10645 mHistoryBuffer.setDataPosition(mHistoryBuffer.dataSize()); 10646 mHistoryIterator = null; 10647 } 10648 getHistoryTotalSize()10649 public int getHistoryTotalSize() { 10650 return MAX_HISTORY_BUFFER; 10651 } 10652 getHistoryUsedSize()10653 public int getHistoryUsedSize() { 10654 return mHistoryBuffer.dataSize(); 10655 } 10656 10657 @Override startIteratingHistoryLocked()10658 public boolean startIteratingHistoryLocked() { 10659 if (DEBUG_HISTORY) Slog.i(TAG, "ITERATING: buff size=" + mHistoryBuffer.dataSize() 10660 + " pos=" + mHistoryBuffer.dataPosition()); 10661 if (mHistoryBuffer.dataSize() <= 0) { 10662 return false; 10663 } 10664 mHistoryBuffer.setDataPosition(0); 10665 mReadOverflow = false; 10666 mIteratingHistory = true; 10667 mReadHistoryStrings = new String[mHistoryTagPool.size()]; 10668 mReadHistoryUids = new int[mHistoryTagPool.size()]; 10669 mReadHistoryChars = 0; 10670 for (HashMap.Entry<HistoryTag, Integer> ent : mHistoryTagPool.entrySet()) { 10671 final HistoryTag tag = ent.getKey(); 10672 final int idx = ent.getValue(); 10673 mReadHistoryStrings[idx] = tag.string; 10674 mReadHistoryUids[idx] = tag.uid; 10675 mReadHistoryChars += tag.string.length() + 1; 10676 } 10677 return true; 10678 } 10679 10680 @Override getHistoryStringPoolSize()10681 public int getHistoryStringPoolSize() { 10682 return mReadHistoryStrings.length; 10683 } 10684 10685 @Override getHistoryStringPoolBytes()10686 public int getHistoryStringPoolBytes() { 10687 // Each entry is a fixed 12 bytes: 4 for index, 4 for uid, 4 for string size 10688 // Each string character is 2 bytes. 10689 return (mReadHistoryStrings.length * 12) + (mReadHistoryChars * 2); 10690 } 10691 10692 @Override getHistoryTagPoolString(int index)10693 public String getHistoryTagPoolString(int index) { 10694 return mReadHistoryStrings[index]; 10695 } 10696 10697 @Override getHistoryTagPoolUid(int index)10698 public int getHistoryTagPoolUid(int index) { 10699 return mReadHistoryUids[index]; 10700 } 10701 10702 @Override getNextHistoryLocked(HistoryItem out)10703 public boolean getNextHistoryLocked(HistoryItem out) { 10704 final int pos = mHistoryBuffer.dataPosition(); 10705 if (pos == 0) { 10706 out.clear(); 10707 } 10708 boolean end = pos >= mHistoryBuffer.dataSize(); 10709 if (end) { 10710 return false; 10711 } 10712 10713 final long lastRealtime = out.time; 10714 final long lastWalltime = out.currentTime; 10715 readHistoryDelta(mHistoryBuffer, out); 10716 if (out.cmd != HistoryItem.CMD_CURRENT_TIME 10717 && out.cmd != HistoryItem.CMD_RESET && lastWalltime != 0) { 10718 out.currentTime = lastWalltime + (out.time - lastRealtime); 10719 } 10720 return true; 10721 } 10722 10723 @Override finishIteratingHistoryLocked()10724 public void finishIteratingHistoryLocked() { 10725 mIteratingHistory = false; 10726 mHistoryBuffer.setDataPosition(mHistoryBuffer.dataSize()); 10727 mReadHistoryStrings = null; 10728 } 10729 10730 @Override getHistoryBaseTime()10731 public long getHistoryBaseTime() { 10732 return mHistoryBaseTime; 10733 } 10734 10735 @Override getStartCount()10736 public int getStartCount() { 10737 return mStartCount; 10738 } 10739 isOnBattery()10740 public boolean isOnBattery() { 10741 return mOnBattery; 10742 } 10743 isCharging()10744 public boolean isCharging() { 10745 return mCharging; 10746 } 10747 isScreenOn(int state)10748 public boolean isScreenOn(int state) { 10749 return state == Display.STATE_ON || state == Display.STATE_VR 10750 || state == Display.STATE_ON_SUSPEND; 10751 } 10752 isScreenOff(int state)10753 public boolean isScreenOff(int state) { 10754 return state == Display.STATE_OFF; 10755 } 10756 isScreenDoze(int state)10757 public boolean isScreenDoze(int state) { 10758 return state == Display.STATE_DOZE || state == Display.STATE_DOZE_SUSPEND; 10759 } 10760 initTimes(long uptime, long realtime)10761 void initTimes(long uptime, long realtime) { 10762 mStartClockTime = System.currentTimeMillis(); 10763 mOnBatteryTimeBase.init(uptime, realtime); 10764 mOnBatteryScreenOffTimeBase.init(uptime, realtime); 10765 mRealtime = 0; 10766 mUptime = 0; 10767 mRealtimeStart = realtime; 10768 mUptimeStart = uptime; 10769 } 10770 initDischarge()10771 void initDischarge() { 10772 mLowDischargeAmountSinceCharge = 0; 10773 mHighDischargeAmountSinceCharge = 0; 10774 mDischargeAmountScreenOn = 0; 10775 mDischargeAmountScreenOnSinceCharge = 0; 10776 mDischargeAmountScreenOff = 0; 10777 mDischargeAmountScreenOffSinceCharge = 0; 10778 mDischargeAmountScreenDoze = 0; 10779 mDischargeAmountScreenDozeSinceCharge = 0; 10780 mDischargeStepTracker.init(); 10781 mChargeStepTracker.init(); 10782 mDischargeScreenOffCounter.reset(false); 10783 mDischargeScreenDozeCounter.reset(false); 10784 mDischargeLightDozeCounter.reset(false); 10785 mDischargeDeepDozeCounter.reset(false); 10786 mDischargeCounter.reset(false); 10787 } 10788 resetAllStatsCmdLocked()10789 public void resetAllStatsCmdLocked() { 10790 resetAllStatsLocked(); 10791 final long mSecUptime = mClocks.uptimeMillis(); 10792 long uptime = mSecUptime * 1000; 10793 long mSecRealtime = mClocks.elapsedRealtime(); 10794 long realtime = mSecRealtime * 1000; 10795 mDischargeStartLevel = mHistoryCur.batteryLevel; 10796 pullPendingStateUpdatesLocked(); 10797 addHistoryRecordLocked(mSecRealtime, mSecUptime); 10798 mDischargeCurrentLevel = mDischargeUnplugLevel = mDischargePlugLevel 10799 = mCurrentBatteryLevel = mHistoryCur.batteryLevel; 10800 mOnBatteryTimeBase.reset(uptime, realtime); 10801 mOnBatteryScreenOffTimeBase.reset(uptime, realtime); 10802 if ((mHistoryCur.states&HistoryItem.STATE_BATTERY_PLUGGED_FLAG) == 0) { 10803 if (isScreenOn(mScreenState)) { 10804 mDischargeScreenOnUnplugLevel = mHistoryCur.batteryLevel; 10805 mDischargeScreenDozeUnplugLevel = 0; 10806 mDischargeScreenOffUnplugLevel = 0; 10807 } else if (isScreenDoze(mScreenState)) { 10808 mDischargeScreenOnUnplugLevel = 0; 10809 mDischargeScreenDozeUnplugLevel = mHistoryCur.batteryLevel; 10810 mDischargeScreenOffUnplugLevel = 0; 10811 } else { 10812 mDischargeScreenOnUnplugLevel = 0; 10813 mDischargeScreenDozeUnplugLevel = 0; 10814 mDischargeScreenOffUnplugLevel = mHistoryCur.batteryLevel; 10815 } 10816 mDischargeAmountScreenOn = 0; 10817 mDischargeAmountScreenOff = 0; 10818 mDischargeAmountScreenDoze = 0; 10819 } 10820 initActiveHistoryEventsLocked(mSecRealtime, mSecUptime); 10821 } 10822 resetAllStatsLocked()10823 private void resetAllStatsLocked() { 10824 final long uptimeMillis = mClocks.uptimeMillis(); 10825 final long elapsedRealtimeMillis = mClocks.elapsedRealtime(); 10826 mStartCount = 0; 10827 initTimes(uptimeMillis * 1000, elapsedRealtimeMillis * 1000); 10828 mScreenOnTimer.reset(false); 10829 mScreenDozeTimer.reset(false); 10830 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 10831 mScreenBrightnessTimer[i].reset(false); 10832 } 10833 10834 if (mPowerProfile != null) { 10835 mEstimatedBatteryCapacity = (int) mPowerProfile.getBatteryCapacity(); 10836 } else { 10837 mEstimatedBatteryCapacity = -1; 10838 } 10839 mMinLearnedBatteryCapacity = -1; 10840 mMaxLearnedBatteryCapacity = -1; 10841 mInteractiveTimer.reset(false); 10842 mPowerSaveModeEnabledTimer.reset(false); 10843 mLastIdleTimeStart = elapsedRealtimeMillis; 10844 mLongestLightIdleTime = 0; 10845 mLongestFullIdleTime = 0; 10846 mDeviceIdleModeLightTimer.reset(false); 10847 mDeviceIdleModeFullTimer.reset(false); 10848 mDeviceLightIdlingTimer.reset(false); 10849 mDeviceIdlingTimer.reset(false); 10850 mPhoneOnTimer.reset(false); 10851 mAudioOnTimer.reset(false); 10852 mVideoOnTimer.reset(false); 10853 mFlashlightOnTimer.reset(false); 10854 mCameraOnTimer.reset(false); 10855 mBluetoothScanTimer.reset(false); 10856 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) { 10857 mPhoneSignalStrengthsTimer[i].reset(false); 10858 } 10859 mPhoneSignalScanningTimer.reset(false); 10860 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 10861 mPhoneDataConnectionsTimer[i].reset(false); 10862 } 10863 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 10864 mNetworkByteActivityCounters[i].reset(false); 10865 mNetworkPacketActivityCounters[i].reset(false); 10866 } 10867 mMobileRadioActiveTimer.reset(false); 10868 mMobileRadioActivePerAppTimer.reset(false); 10869 mMobileRadioActiveAdjustedTime.reset(false); 10870 mMobileRadioActiveUnknownTime.reset(false); 10871 mMobileRadioActiveUnknownCount.reset(false); 10872 mWifiOnTimer.reset(false); 10873 mGlobalWifiRunningTimer.reset(false); 10874 for (int i=0; i<NUM_WIFI_STATES; i++) { 10875 mWifiStateTimer[i].reset(false); 10876 } 10877 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) { 10878 mWifiSupplStateTimer[i].reset(false); 10879 } 10880 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { 10881 mWifiSignalStrengthsTimer[i].reset(false); 10882 } 10883 mWifiMulticastWakelockTimer.reset(false); 10884 mWifiActiveTimer.reset(false); 10885 mWifiActivity.reset(false); 10886 for (int i=0; i< GnssMetrics.NUM_GPS_SIGNAL_QUALITY_LEVELS; i++) { 10887 mGpsSignalQualityTimer[i].reset(false); 10888 } 10889 mBluetoothActivity.reset(false); 10890 mModemActivity.reset(false); 10891 mNumConnectivityChange = mLoadedNumConnectivityChange = mUnpluggedNumConnectivityChange = 0; 10892 10893 for (int i=0; i<mUidStats.size(); i++) { 10894 if (mUidStats.valueAt(i).reset(uptimeMillis * 1000, elapsedRealtimeMillis * 1000)) { 10895 mUidStats.remove(mUidStats.keyAt(i)); 10896 i--; 10897 } 10898 } 10899 10900 if (mRpmStats.size() > 0) { 10901 for (SamplingTimer timer : mRpmStats.values()) { 10902 mOnBatteryTimeBase.remove(timer); 10903 } 10904 mRpmStats.clear(); 10905 } 10906 if (mScreenOffRpmStats.size() > 0) { 10907 for (SamplingTimer timer : mScreenOffRpmStats.values()) { 10908 mOnBatteryScreenOffTimeBase.remove(timer); 10909 } 10910 mScreenOffRpmStats.clear(); 10911 } 10912 10913 if (mKernelWakelockStats.size() > 0) { 10914 for (SamplingTimer timer : mKernelWakelockStats.values()) { 10915 mOnBatteryScreenOffTimeBase.remove(timer); 10916 } 10917 mKernelWakelockStats.clear(); 10918 } 10919 10920 if (mKernelMemoryStats.size() > 0) { 10921 for (int i = 0; i < mKernelMemoryStats.size(); i++) { 10922 mOnBatteryTimeBase.remove(mKernelMemoryStats.valueAt(i)); 10923 } 10924 mKernelMemoryStats.clear(); 10925 } 10926 10927 if (mWakeupReasonStats.size() > 0) { 10928 for (SamplingTimer timer : mWakeupReasonStats.values()) { 10929 mOnBatteryTimeBase.remove(timer); 10930 } 10931 mWakeupReasonStats.clear(); 10932 } 10933 10934 mLastHistoryStepDetails = null; 10935 mLastStepCpuUserTime = mLastStepCpuSystemTime = 0; 10936 mCurStepCpuUserTime = mCurStepCpuSystemTime = 0; 10937 mLastStepCpuUserTime = mCurStepCpuUserTime = 0; 10938 mLastStepCpuSystemTime = mCurStepCpuSystemTime = 0; 10939 mLastStepStatUserTime = mCurStepStatUserTime = 0; 10940 mLastStepStatSystemTime = mCurStepStatSystemTime = 0; 10941 mLastStepStatIOWaitTime = mCurStepStatIOWaitTime = 0; 10942 mLastStepStatIrqTime = mCurStepStatIrqTime = 0; 10943 mLastStepStatSoftIrqTime = mCurStepStatSoftIrqTime = 0; 10944 mLastStepStatIdleTime = mCurStepStatIdleTime = 0; 10945 10946 mNumAllUidCpuTimeReads = 0; 10947 mNumUidsRemoved = 0; 10948 10949 initDischarge(); 10950 10951 clearHistoryLocked(); 10952 mHandler.sendEmptyMessage(MSG_REPORT_RESET_STATS); 10953 } 10954 initActiveHistoryEventsLocked(long elapsedRealtimeMs, long uptimeMs)10955 private void initActiveHistoryEventsLocked(long elapsedRealtimeMs, long uptimeMs) { 10956 for (int i=0; i<HistoryItem.EVENT_COUNT; i++) { 10957 if (!mRecordAllHistory && i == HistoryItem.EVENT_PROC) { 10958 // Not recording process starts/stops. 10959 continue; 10960 } 10961 HashMap<String, SparseIntArray> active = mActiveEvents.getStateForEvent(i); 10962 if (active == null) { 10963 continue; 10964 } 10965 for (HashMap.Entry<String, SparseIntArray> ent : active.entrySet()) { 10966 SparseIntArray uids = ent.getValue(); 10967 for (int j=0; j<uids.size(); j++) { 10968 addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, i, ent.getKey(), 10969 uids.keyAt(j)); 10970 } 10971 } 10972 } 10973 } 10974 updateDischargeScreenLevelsLocked(int oldState, int newState)10975 void updateDischargeScreenLevelsLocked(int oldState, int newState) { 10976 updateOldDischargeScreenLevelLocked(oldState); 10977 updateNewDischargeScreenLevelLocked(newState); 10978 } 10979 updateOldDischargeScreenLevelLocked(int state)10980 private void updateOldDischargeScreenLevelLocked(int state) { 10981 if (isScreenOn(state)) { 10982 int diff = mDischargeScreenOnUnplugLevel - mDischargeCurrentLevel; 10983 if (diff > 0) { 10984 mDischargeAmountScreenOn += diff; 10985 mDischargeAmountScreenOnSinceCharge += diff; 10986 } 10987 } else if (isScreenDoze(state)) { 10988 int diff = mDischargeScreenDozeUnplugLevel - mDischargeCurrentLevel; 10989 if (diff > 0) { 10990 mDischargeAmountScreenDoze += diff; 10991 mDischargeAmountScreenDozeSinceCharge += diff; 10992 } 10993 } else if (isScreenOff(state)){ 10994 int diff = mDischargeScreenOffUnplugLevel - mDischargeCurrentLevel; 10995 if (diff > 0) { 10996 mDischargeAmountScreenOff += diff; 10997 mDischargeAmountScreenOffSinceCharge += diff; 10998 } 10999 } 11000 } 11001 updateNewDischargeScreenLevelLocked(int state)11002 private void updateNewDischargeScreenLevelLocked(int state) { 11003 if (isScreenOn(state)) { 11004 mDischargeScreenOnUnplugLevel = mDischargeCurrentLevel; 11005 mDischargeScreenOffUnplugLevel = 0; 11006 mDischargeScreenDozeUnplugLevel = 0; 11007 } else if (isScreenDoze(state)){ 11008 mDischargeScreenOnUnplugLevel = 0; 11009 mDischargeScreenDozeUnplugLevel = mDischargeCurrentLevel; 11010 mDischargeScreenOffUnplugLevel = 0; 11011 } else if (isScreenOff(state)) { 11012 mDischargeScreenOnUnplugLevel = 0; 11013 mDischargeScreenDozeUnplugLevel = 0; 11014 mDischargeScreenOffUnplugLevel = mDischargeCurrentLevel; 11015 } 11016 } 11017 pullPendingStateUpdatesLocked()11018 public void pullPendingStateUpdatesLocked() { 11019 if (mOnBatteryInternal) { 11020 updateDischargeScreenLevelsLocked(mScreenState, mScreenState); 11021 } 11022 } 11023 11024 private final NetworkStatsFactory mNetworkStatsFactory = new NetworkStatsFactory(); 11025 private final Pools.Pool<NetworkStats> mNetworkStatsPool = new Pools.SynchronizedPool<>(6); 11026 11027 private final Object mWifiNetworkLock = new Object(); 11028 11029 @GuardedBy("mWifiNetworkLock") 11030 private String[] mWifiIfaces = EmptyArray.STRING; 11031 11032 @GuardedBy("mWifiNetworkLock") 11033 private NetworkStats mLastWifiNetworkStats = new NetworkStats(0, -1); 11034 11035 private final Object mModemNetworkLock = new Object(); 11036 11037 @GuardedBy("mModemNetworkLock") 11038 private String[] mModemIfaces = EmptyArray.STRING; 11039 11040 @GuardedBy("mModemNetworkLock") 11041 private NetworkStats mLastModemNetworkStats = new NetworkStats(0, -1); 11042 readNetworkStatsLocked(String[] ifaces)11043 private NetworkStats readNetworkStatsLocked(String[] ifaces) { 11044 try { 11045 if (!ArrayUtils.isEmpty(ifaces)) { 11046 return mNetworkStatsFactory.readNetworkStatsDetail(NetworkStats.UID_ALL, ifaces, 11047 NetworkStats.TAG_NONE, mNetworkStatsPool.acquire()); 11048 } 11049 } catch (IOException e) { 11050 Slog.e(TAG, "failed to read network stats for ifaces: " + Arrays.toString(ifaces)); 11051 } 11052 return null; 11053 } 11054 11055 /** 11056 * Distribute WiFi energy info and network traffic to apps. 11057 * @param info The energy information from the WiFi controller. 11058 */ updateWifiState(@ullable final WifiActivityEnergyInfo info)11059 public void updateWifiState(@Nullable final WifiActivityEnergyInfo info) { 11060 if (DEBUG_ENERGY) { 11061 Slog.d(TAG, "Updating wifi stats: " + Arrays.toString(mWifiIfaces)); 11062 } 11063 11064 // Grab a separate lock to acquire the network stats, which may do I/O. 11065 NetworkStats delta = null; 11066 synchronized (mWifiNetworkLock) { 11067 final NetworkStats latestStats = readNetworkStatsLocked(mWifiIfaces); 11068 if (latestStats != null) { 11069 delta = NetworkStats.subtract(latestStats, mLastWifiNetworkStats, null, null, 11070 mNetworkStatsPool.acquire()); 11071 mNetworkStatsPool.release(mLastWifiNetworkStats); 11072 mLastWifiNetworkStats = latestStats; 11073 } 11074 } 11075 11076 synchronized (this) { 11077 if (!mOnBatteryInternal) { 11078 if (delta != null) { 11079 mNetworkStatsPool.release(delta); 11080 } 11081 return; 11082 } 11083 11084 final long elapsedRealtimeMs = mClocks.elapsedRealtime(); 11085 SparseLongArray rxPackets = new SparseLongArray(); 11086 SparseLongArray txPackets = new SparseLongArray(); 11087 long totalTxPackets = 0; 11088 long totalRxPackets = 0; 11089 if (delta != null) { 11090 NetworkStats.Entry entry = new NetworkStats.Entry(); 11091 final int size = delta.size(); 11092 for (int i = 0; i < size; i++) { 11093 entry = delta.getValues(i, entry); 11094 11095 if (DEBUG_ENERGY) { 11096 Slog.d(TAG, "Wifi uid " + entry.uid + ": delta rx=" + entry.rxBytes 11097 + " tx=" + entry.txBytes + " rxPackets=" + entry.rxPackets 11098 + " txPackets=" + entry.txPackets); 11099 } 11100 11101 if (entry.rxBytes == 0 && entry.txBytes == 0) { 11102 // Skip the lookup below since there is no work to do. 11103 continue; 11104 } 11105 11106 final Uid u = getUidStatsLocked(mapUid(entry.uid)); 11107 if (entry.rxBytes != 0) { 11108 u.noteNetworkActivityLocked(NETWORK_WIFI_RX_DATA, entry.rxBytes, 11109 entry.rxPackets); 11110 if (entry.set == NetworkStats.SET_DEFAULT) { // Background transfers 11111 u.noteNetworkActivityLocked(NETWORK_WIFI_BG_RX_DATA, entry.rxBytes, 11112 entry.rxPackets); 11113 } 11114 mNetworkByteActivityCounters[NETWORK_WIFI_RX_DATA].addCountLocked( 11115 entry.rxBytes); 11116 mNetworkPacketActivityCounters[NETWORK_WIFI_RX_DATA].addCountLocked( 11117 entry.rxPackets); 11118 11119 rxPackets.put(u.getUid(), entry.rxPackets); 11120 11121 // Sum the total number of packets so that the Rx Power can 11122 // be evenly distributed amongst the apps. 11123 totalRxPackets += entry.rxPackets; 11124 } 11125 11126 if (entry.txBytes != 0) { 11127 u.noteNetworkActivityLocked(NETWORK_WIFI_TX_DATA, entry.txBytes, 11128 entry.txPackets); 11129 if (entry.set == NetworkStats.SET_DEFAULT) { // Background transfers 11130 u.noteNetworkActivityLocked(NETWORK_WIFI_BG_TX_DATA, entry.txBytes, 11131 entry.txPackets); 11132 } 11133 mNetworkByteActivityCounters[NETWORK_WIFI_TX_DATA].addCountLocked( 11134 entry.txBytes); 11135 mNetworkPacketActivityCounters[NETWORK_WIFI_TX_DATA].addCountLocked( 11136 entry.txPackets); 11137 11138 txPackets.put(u.getUid(), entry.txPackets); 11139 11140 // Sum the total number of packets so that the Tx Power can 11141 // be evenly distributed amongst the apps. 11142 totalTxPackets += entry.txPackets; 11143 } 11144 } 11145 mNetworkStatsPool.release(delta); 11146 delta = null; 11147 } 11148 11149 if (info != null) { 11150 mHasWifiReporting = true; 11151 11152 // Measured in mAms 11153 final long txTimeMs = info.getControllerTxTimeMillis(); 11154 final long rxTimeMs = info.getControllerRxTimeMillis(); 11155 final long scanTimeMs = info.getControllerScanTimeMillis(); 11156 final long idleTimeMs = info.getControllerIdleTimeMillis(); 11157 final long totalTimeMs = txTimeMs + rxTimeMs + idleTimeMs; 11158 11159 long leftOverRxTimeMs = rxTimeMs; 11160 long leftOverTxTimeMs = txTimeMs; 11161 11162 if (DEBUG_ENERGY) { 11163 Slog.d(TAG, "------ BEGIN WiFi power blaming ------"); 11164 Slog.d(TAG, " Tx Time: " + txTimeMs + " ms"); 11165 Slog.d(TAG, " Rx Time: " + rxTimeMs + " ms"); 11166 Slog.d(TAG, " Idle Time: " + idleTimeMs + " ms"); 11167 Slog.d(TAG, " Total Time: " + totalTimeMs + " ms"); 11168 Slog.d(TAG, " Scan Time: " + scanTimeMs + " ms"); 11169 } 11170 11171 long totalWifiLockTimeMs = 0; 11172 long totalScanTimeMs = 0; 11173 11174 // On the first pass, collect some totals so that we can normalize power 11175 // calculations if we need to. 11176 final int uidStatsSize = mUidStats.size(); 11177 for (int i = 0; i < uidStatsSize; i++) { 11178 final Uid uid = mUidStats.valueAt(i); 11179 11180 // Sum the total scan power for all apps. 11181 totalScanTimeMs += uid.mWifiScanTimer.getTimeSinceMarkLocked( 11182 elapsedRealtimeMs * 1000) / 1000; 11183 11184 // Sum the total time holding wifi lock for all apps. 11185 totalWifiLockTimeMs += uid.mFullWifiLockTimer.getTimeSinceMarkLocked( 11186 elapsedRealtimeMs * 1000) / 1000; 11187 } 11188 11189 if (DEBUG_ENERGY && totalScanTimeMs > rxTimeMs) { 11190 Slog.d(TAG, 11191 " !Estimated scan time > Actual rx time (" + totalScanTimeMs + " ms > " 11192 + rxTimeMs + " ms). Normalizing scan time."); 11193 } 11194 if (DEBUG_ENERGY && totalScanTimeMs > txTimeMs) { 11195 Slog.d(TAG, 11196 " !Estimated scan time > Actual tx time (" + totalScanTimeMs + " ms > " 11197 + txTimeMs + " ms). Normalizing scan time."); 11198 } 11199 11200 // Actually assign and distribute power usage to apps. 11201 for (int i = 0; i < uidStatsSize; i++) { 11202 final Uid uid = mUidStats.valueAt(i); 11203 11204 long scanTimeSinceMarkMs = uid.mWifiScanTimer.getTimeSinceMarkLocked( 11205 elapsedRealtimeMs * 1000) / 1000; 11206 if (scanTimeSinceMarkMs > 0) { 11207 // Set the new mark so that next time we get new data since this point. 11208 uid.mWifiScanTimer.setMark(elapsedRealtimeMs); 11209 11210 long scanRxTimeSinceMarkMs = scanTimeSinceMarkMs; 11211 long scanTxTimeSinceMarkMs = scanTimeSinceMarkMs; 11212 11213 // Our total scan time is more than the reported Tx/Rx time. 11214 // This is possible because the cost of a scan is approximate. 11215 // Let's normalize the result so that we evenly blame each app 11216 // scanning. 11217 // 11218 // This means that we may have apps that transmitted/received packets not be 11219 // blamed for this, but this is fine as scans are relatively more expensive. 11220 if (totalScanTimeMs > rxTimeMs) { 11221 scanRxTimeSinceMarkMs = (rxTimeMs * scanRxTimeSinceMarkMs) / 11222 totalScanTimeMs; 11223 } 11224 if (totalScanTimeMs > txTimeMs) { 11225 scanTxTimeSinceMarkMs = (txTimeMs * scanTxTimeSinceMarkMs) / 11226 totalScanTimeMs; 11227 } 11228 11229 if (DEBUG_ENERGY) { 11230 Slog.d(TAG, " ScanTime for UID " + uid.getUid() + ": Rx:" 11231 + scanRxTimeSinceMarkMs + " ms Tx:" 11232 + scanTxTimeSinceMarkMs + " ms)"); 11233 } 11234 11235 ControllerActivityCounterImpl activityCounter = 11236 uid.getOrCreateWifiControllerActivityLocked(); 11237 activityCounter.getRxTimeCounter().addCountLocked(scanRxTimeSinceMarkMs); 11238 activityCounter.getTxTimeCounters()[0].addCountLocked( 11239 scanTxTimeSinceMarkMs); 11240 leftOverRxTimeMs -= scanRxTimeSinceMarkMs; 11241 leftOverTxTimeMs -= scanTxTimeSinceMarkMs; 11242 } 11243 11244 // Distribute evenly the power consumed while Idle to each app holding a WiFi 11245 // lock. 11246 final long wifiLockTimeSinceMarkMs = 11247 uid.mFullWifiLockTimer.getTimeSinceMarkLocked( 11248 elapsedRealtimeMs * 1000) / 1000; 11249 if (wifiLockTimeSinceMarkMs > 0) { 11250 // Set the new mark so that next time we get new data since this point. 11251 uid.mFullWifiLockTimer.setMark(elapsedRealtimeMs); 11252 11253 final long myIdleTimeMs = (wifiLockTimeSinceMarkMs * idleTimeMs) 11254 / totalWifiLockTimeMs; 11255 if (DEBUG_ENERGY) { 11256 Slog.d(TAG, " IdleTime for UID " + uid.getUid() + ": " 11257 + myIdleTimeMs + " ms"); 11258 } 11259 uid.getOrCreateWifiControllerActivityLocked().getIdleTimeCounter() 11260 .addCountLocked(myIdleTimeMs); 11261 } 11262 } 11263 11264 if (DEBUG_ENERGY) { 11265 Slog.d(TAG, " New RxPower: " + leftOverRxTimeMs + " ms"); 11266 Slog.d(TAG, " New TxPower: " + leftOverTxTimeMs + " ms"); 11267 } 11268 11269 // Distribute the remaining Tx power appropriately between all apps that transmitted 11270 // packets. 11271 for (int i = 0; i < txPackets.size(); i++) { 11272 final Uid uid = getUidStatsLocked(txPackets.keyAt(i)); 11273 final long myTxTimeMs = (txPackets.valueAt(i) * leftOverTxTimeMs) 11274 / totalTxPackets; 11275 if (DEBUG_ENERGY) { 11276 Slog.d(TAG, " TxTime for UID " + uid.getUid() + ": " + myTxTimeMs + " ms"); 11277 } 11278 uid.getOrCreateWifiControllerActivityLocked().getTxTimeCounters()[0] 11279 .addCountLocked(myTxTimeMs); 11280 } 11281 11282 // Distribute the remaining Rx power appropriately between all apps that received 11283 // packets. 11284 for (int i = 0; i < rxPackets.size(); i++) { 11285 final Uid uid = getUidStatsLocked(rxPackets.keyAt(i)); 11286 final long myRxTimeMs = (rxPackets.valueAt(i) * leftOverRxTimeMs) 11287 / totalRxPackets; 11288 if (DEBUG_ENERGY) { 11289 Slog.d(TAG, " RxTime for UID " + uid.getUid() + ": " + myRxTimeMs + " ms"); 11290 } 11291 uid.getOrCreateWifiControllerActivityLocked().getRxTimeCounter() 11292 .addCountLocked(myRxTimeMs); 11293 } 11294 11295 // Any left over power use will be picked up by the WiFi category in BatteryStatsHelper. 11296 11297 11298 // Update WiFi controller stats. 11299 mWifiActivity.getRxTimeCounter().addCountLocked(info.getControllerRxTimeMillis()); 11300 mWifiActivity.getTxTimeCounters()[0].addCountLocked( 11301 info.getControllerTxTimeMillis()); 11302 mWifiActivity.getScanTimeCounter().addCountLocked( 11303 info.getControllerScanTimeMillis()); 11304 mWifiActivity.getIdleTimeCounter().addCountLocked( 11305 info.getControllerIdleTimeMillis()); 11306 11307 // POWER_WIFI_CONTROLLER_OPERATING_VOLTAGE is measured in mV, so convert to V. 11308 final double opVolt = mPowerProfile.getAveragePower( 11309 PowerProfile.POWER_WIFI_CONTROLLER_OPERATING_VOLTAGE) / 1000.0; 11310 if (opVolt != 0) { 11311 // We store the power drain as mAms. 11312 mWifiActivity.getPowerCounter().addCountLocked( 11313 (long) (info.getControllerEnergyUsed() / opVolt)); 11314 } 11315 } 11316 } 11317 } 11318 11319 private ModemActivityInfo mLastModemActivityInfo = 11320 new ModemActivityInfo(0, 0, 0, new int[0], 0, 0); 11321 getDeltaModemActivityInfo(ModemActivityInfo activityInfo)11322 private ModemActivityInfo getDeltaModemActivityInfo(ModemActivityInfo activityInfo) { 11323 if (activityInfo == null) { 11324 return null; 11325 } 11326 int[] txTimeMs = new int[ModemActivityInfo.TX_POWER_LEVELS]; 11327 for (int i = 0; i < ModemActivityInfo.TX_POWER_LEVELS; i++) { 11328 txTimeMs[i] = activityInfo.getTxTimeMillis()[i] 11329 - mLastModemActivityInfo.getTxTimeMillis()[i]; 11330 } 11331 ModemActivityInfo deltaInfo = new ModemActivityInfo(activityInfo.getTimestamp(), 11332 activityInfo.getSleepTimeMillis() - mLastModemActivityInfo.getSleepTimeMillis(), 11333 activityInfo.getIdleTimeMillis() - mLastModemActivityInfo.getIdleTimeMillis(), 11334 txTimeMs, 11335 activityInfo.getRxTimeMillis() - mLastModemActivityInfo.getRxTimeMillis(), 11336 activityInfo.getEnergyUsed() - mLastModemActivityInfo.getEnergyUsed()); 11337 mLastModemActivityInfo = activityInfo; 11338 return deltaInfo; 11339 } 11340 11341 /** 11342 * Distribute Cell radio energy info and network traffic to apps. 11343 */ updateMobileRadioState(@ullable final ModemActivityInfo activityInfo)11344 public void updateMobileRadioState(@Nullable final ModemActivityInfo activityInfo) { 11345 if (DEBUG_ENERGY) { 11346 Slog.d(TAG, "Updating mobile radio stats with " + activityInfo); 11347 } 11348 ModemActivityInfo deltaInfo = getDeltaModemActivityInfo(activityInfo); 11349 11350 // Add modem tx power to history. 11351 addModemTxPowerToHistory(deltaInfo); 11352 11353 // Grab a separate lock to acquire the network stats, which may do I/O. 11354 NetworkStats delta = null; 11355 synchronized (mModemNetworkLock) { 11356 final NetworkStats latestStats = readNetworkStatsLocked(mModemIfaces); 11357 if (latestStats != null) { 11358 delta = NetworkStats.subtract(latestStats, mLastModemNetworkStats, null, null, 11359 mNetworkStatsPool.acquire()); 11360 mNetworkStatsPool.release(mLastModemNetworkStats); 11361 mLastModemNetworkStats = latestStats; 11362 } 11363 } 11364 11365 synchronized (this) { 11366 if (!mOnBatteryInternal) { 11367 if (delta != null) { 11368 mNetworkStatsPool.release(delta); 11369 } 11370 return; 11371 } 11372 11373 if (deltaInfo != null) { 11374 mHasModemReporting = true; 11375 mModemActivity.getIdleTimeCounter().addCountLocked( 11376 deltaInfo.getIdleTimeMillis()); 11377 mModemActivity.getSleepTimeCounter().addCountLocked( 11378 deltaInfo.getSleepTimeMillis()); 11379 mModemActivity.getRxTimeCounter().addCountLocked(deltaInfo.getRxTimeMillis()); 11380 for (int lvl = 0; lvl < ModemActivityInfo.TX_POWER_LEVELS; lvl++) { 11381 mModemActivity.getTxTimeCounters()[lvl] 11382 .addCountLocked(deltaInfo.getTxTimeMillis()[lvl]); 11383 } 11384 11385 // POWER_MODEM_CONTROLLER_OPERATING_VOLTAGE is measured in mV, so convert to V. 11386 final double opVolt = mPowerProfile.getAveragePower( 11387 PowerProfile.POWER_MODEM_CONTROLLER_OPERATING_VOLTAGE) / 1000.0; 11388 if (opVolt != 0) { 11389 double energyUsed = 11390 deltaInfo.getSleepTimeMillis() * 11391 mPowerProfile.getAveragePower(PowerProfile.POWER_MODEM_CONTROLLER_SLEEP) 11392 + deltaInfo.getIdleTimeMillis() * 11393 mPowerProfile.getAveragePower(PowerProfile.POWER_MODEM_CONTROLLER_IDLE) 11394 + deltaInfo.getRxTimeMillis() * 11395 mPowerProfile.getAveragePower(PowerProfile.POWER_MODEM_CONTROLLER_RX); 11396 int[] txTimeMs = deltaInfo.getTxTimeMillis(); 11397 for (int i = 0; i < Math.min(txTimeMs.length, 11398 SignalStrength.NUM_SIGNAL_STRENGTH_BINS); i++) { 11399 energyUsed += txTimeMs[i] * mPowerProfile.getAveragePower( 11400 PowerProfile.POWER_MODEM_CONTROLLER_TX, i); 11401 } 11402 11403 // We store the power drain as mAms. 11404 mModemActivity.getPowerCounter().addCountLocked((long) energyUsed); 11405 } 11406 } 11407 11408 final long elapsedRealtimeMs = mClocks.elapsedRealtime(); 11409 long radioTime = mMobileRadioActivePerAppTimer.getTimeSinceMarkLocked( 11410 elapsedRealtimeMs * 1000); 11411 mMobileRadioActivePerAppTimer.setMark(elapsedRealtimeMs); 11412 11413 long totalRxPackets = 0; 11414 long totalTxPackets = 0; 11415 if (delta != null) { 11416 NetworkStats.Entry entry = new NetworkStats.Entry(); 11417 final int size = delta.size(); 11418 for (int i = 0; i < size; i++) { 11419 entry = delta.getValues(i, entry); 11420 if (entry.rxPackets == 0 && entry.txPackets == 0) { 11421 continue; 11422 } 11423 11424 if (DEBUG_ENERGY) { 11425 Slog.d(TAG, "Mobile uid " + entry.uid + ": delta rx=" + entry.rxBytes 11426 + " tx=" + entry.txBytes + " rxPackets=" + entry.rxPackets 11427 + " txPackets=" + entry.txPackets); 11428 } 11429 11430 totalRxPackets += entry.rxPackets; 11431 totalTxPackets += entry.txPackets; 11432 11433 final Uid u = getUidStatsLocked(mapUid(entry.uid)); 11434 u.noteNetworkActivityLocked(NETWORK_MOBILE_RX_DATA, entry.rxBytes, 11435 entry.rxPackets); 11436 u.noteNetworkActivityLocked(NETWORK_MOBILE_TX_DATA, entry.txBytes, 11437 entry.txPackets); 11438 if (entry.set == NetworkStats.SET_DEFAULT) { // Background transfers 11439 u.noteNetworkActivityLocked(NETWORK_MOBILE_BG_RX_DATA, 11440 entry.rxBytes, entry.rxPackets); 11441 u.noteNetworkActivityLocked(NETWORK_MOBILE_BG_TX_DATA, 11442 entry.txBytes, entry.txPackets); 11443 } 11444 11445 mNetworkByteActivityCounters[NETWORK_MOBILE_RX_DATA].addCountLocked( 11446 entry.rxBytes); 11447 mNetworkByteActivityCounters[NETWORK_MOBILE_TX_DATA].addCountLocked( 11448 entry.txBytes); 11449 mNetworkPacketActivityCounters[NETWORK_MOBILE_RX_DATA].addCountLocked( 11450 entry.rxPackets); 11451 mNetworkPacketActivityCounters[NETWORK_MOBILE_TX_DATA].addCountLocked( 11452 entry.txPackets); 11453 } 11454 11455 // Now distribute proportional blame to the apps that did networking. 11456 long totalPackets = totalRxPackets + totalTxPackets; 11457 if (totalPackets > 0) { 11458 for (int i = 0; i < size; i++) { 11459 entry = delta.getValues(i, entry); 11460 if (entry.rxPackets == 0 && entry.txPackets == 0) { 11461 continue; 11462 } 11463 11464 final Uid u = getUidStatsLocked(mapUid(entry.uid)); 11465 11466 // Distribute total radio active time in to this app. 11467 final long appPackets = entry.rxPackets + entry.txPackets; 11468 final long appRadioTime = (radioTime * appPackets) / totalPackets; 11469 u.noteMobileRadioActiveTimeLocked(appRadioTime); 11470 11471 // Remove this app from the totals, so that we don't lose any time 11472 // due to rounding. 11473 radioTime -= appRadioTime; 11474 totalPackets -= appPackets; 11475 11476 if (deltaInfo != null) { 11477 ControllerActivityCounterImpl activityCounter = 11478 u.getOrCreateModemControllerActivityLocked(); 11479 if (totalRxPackets > 0 && entry.rxPackets > 0) { 11480 final long rxMs = (entry.rxPackets * deltaInfo.getRxTimeMillis()) 11481 / totalRxPackets; 11482 activityCounter.getRxTimeCounter().addCountLocked(rxMs); 11483 } 11484 11485 if (totalTxPackets > 0 && entry.txPackets > 0) { 11486 for (int lvl = 0; lvl < ModemActivityInfo.TX_POWER_LEVELS; lvl++) { 11487 long txMs = 11488 entry.txPackets * deltaInfo.getTxTimeMillis()[lvl]; 11489 txMs /= totalTxPackets; 11490 activityCounter.getTxTimeCounters()[lvl].addCountLocked(txMs); 11491 } 11492 } 11493 } 11494 } 11495 } 11496 11497 if (radioTime > 0) { 11498 // Whoops, there is some radio time we can't blame on an app! 11499 mMobileRadioActiveUnknownTime.addCountLocked(radioTime); 11500 mMobileRadioActiveUnknownCount.addCountLocked(1); 11501 } 11502 11503 mNetworkStatsPool.release(delta); 11504 delta = null; 11505 } 11506 } 11507 } 11508 11509 /** 11510 * Add modem tx power to history 11511 * Device is said to be in high cellular transmit power when it has spent most of the transmit 11512 * time at the highest power level. 11513 * @param activityInfo 11514 */ addModemTxPowerToHistory(final ModemActivityInfo activityInfo)11515 private synchronized void addModemTxPowerToHistory(final ModemActivityInfo activityInfo) { 11516 if (activityInfo == null) { 11517 return; 11518 } 11519 int[] txTimeMs = activityInfo.getTxTimeMillis(); 11520 if (txTimeMs == null || txTimeMs.length != ModemActivityInfo.TX_POWER_LEVELS) { 11521 return; 11522 } 11523 final long elapsedRealtime = mClocks.elapsedRealtime(); 11524 final long uptime = mClocks.uptimeMillis(); 11525 int levelMaxTimeSpent = 0; 11526 for (int i = 1; i < txTimeMs.length; i++) { 11527 if (txTimeMs[i] > txTimeMs[levelMaxTimeSpent]) { 11528 levelMaxTimeSpent = i; 11529 } 11530 } 11531 if (levelMaxTimeSpent == ModemActivityInfo.TX_POWER_LEVELS - 1) { 11532 if (!mIsCellularTxPowerHigh) { 11533 mHistoryCur.states2 |= HistoryItem.STATE2_CELLULAR_HIGH_TX_POWER_FLAG; 11534 addHistoryRecordLocked(elapsedRealtime, uptime); 11535 mIsCellularTxPowerHigh = true; 11536 } 11537 return; 11538 } 11539 if (mIsCellularTxPowerHigh) { 11540 mHistoryCur.states2 &= ~HistoryItem.STATE2_CELLULAR_HIGH_TX_POWER_FLAG; 11541 addHistoryRecordLocked(elapsedRealtime, uptime); 11542 mIsCellularTxPowerHigh = false; 11543 } 11544 return; 11545 } 11546 11547 private final class BluetoothActivityInfoCache { 11548 long idleTimeMs; 11549 long rxTimeMs; 11550 long txTimeMs; 11551 long energy; 11552 11553 SparseLongArray uidRxBytes = new SparseLongArray(); 11554 SparseLongArray uidTxBytes = new SparseLongArray(); 11555 set(BluetoothActivityEnergyInfo info)11556 void set(BluetoothActivityEnergyInfo info) { 11557 idleTimeMs = info.getControllerIdleTimeMillis(); 11558 rxTimeMs = info.getControllerRxTimeMillis(); 11559 txTimeMs = info.getControllerTxTimeMillis(); 11560 energy = info.getControllerEnergyUsed(); 11561 if (info.getUidTraffic() != null) { 11562 for (UidTraffic traffic : info.getUidTraffic()) { 11563 uidRxBytes.put(traffic.getUid(), traffic.getRxBytes()); 11564 uidTxBytes.put(traffic.getUid(), traffic.getTxBytes()); 11565 } 11566 } 11567 } 11568 } 11569 11570 private final BluetoothActivityInfoCache mLastBluetoothActivityInfo 11571 = new BluetoothActivityInfoCache(); 11572 11573 /** 11574 * Distribute Bluetooth energy info and network traffic to apps. 11575 * 11576 * @param info The energy information from the bluetooth controller. 11577 */ updateBluetoothStateLocked(@ullable final BluetoothActivityEnergyInfo info)11578 public void updateBluetoothStateLocked(@Nullable final BluetoothActivityEnergyInfo info) { 11579 if (DEBUG_ENERGY) { 11580 Slog.d(TAG, "Updating bluetooth stats: " + info); 11581 } 11582 11583 if (info == null || !mOnBatteryInternal) { 11584 return; 11585 } 11586 11587 mHasBluetoothReporting = true; 11588 11589 final long elapsedRealtimeMs = mClocks.elapsedRealtime(); 11590 final long rxTimeMs = 11591 info.getControllerRxTimeMillis() - mLastBluetoothActivityInfo.rxTimeMs; 11592 final long txTimeMs = 11593 info.getControllerTxTimeMillis() - mLastBluetoothActivityInfo.txTimeMs; 11594 final long idleTimeMs = 11595 info.getControllerIdleTimeMillis() - mLastBluetoothActivityInfo.idleTimeMs; 11596 11597 if (DEBUG_ENERGY) { 11598 Slog.d(TAG, "------ BEGIN BLE power blaming ------"); 11599 Slog.d(TAG, " Tx Time: " + txTimeMs + " ms"); 11600 Slog.d(TAG, " Rx Time: " + rxTimeMs + " ms"); 11601 Slog.d(TAG, " Idle Time: " + idleTimeMs + " ms"); 11602 } 11603 11604 long totalScanTimeMs = 0; 11605 11606 final int uidCount = mUidStats.size(); 11607 for (int i = 0; i < uidCount; i++) { 11608 final Uid u = mUidStats.valueAt(i); 11609 if (u.mBluetoothScanTimer == null) { 11610 continue; 11611 } 11612 11613 totalScanTimeMs += u.mBluetoothScanTimer.getTimeSinceMarkLocked( 11614 elapsedRealtimeMs * 1000) / 1000; 11615 } 11616 11617 final boolean normalizeScanRxTime = (totalScanTimeMs > rxTimeMs); 11618 final boolean normalizeScanTxTime = (totalScanTimeMs > txTimeMs); 11619 11620 if (DEBUG_ENERGY) { 11621 Slog.d(TAG, "Normalizing scan power for RX=" + normalizeScanRxTime 11622 + " TX=" + normalizeScanTxTime); 11623 } 11624 11625 long leftOverRxTimeMs = rxTimeMs; 11626 long leftOverTxTimeMs = txTimeMs; 11627 11628 for (int i = 0; i < uidCount; i++) { 11629 final Uid u = mUidStats.valueAt(i); 11630 if (u.mBluetoothScanTimer == null) { 11631 continue; 11632 } 11633 11634 long scanTimeSinceMarkMs = u.mBluetoothScanTimer.getTimeSinceMarkLocked( 11635 elapsedRealtimeMs * 1000) / 1000; 11636 if (scanTimeSinceMarkMs > 0) { 11637 // Set the new mark so that next time we get new data since this point. 11638 u.mBluetoothScanTimer.setMark(elapsedRealtimeMs); 11639 11640 long scanTimeRxSinceMarkMs = scanTimeSinceMarkMs; 11641 long scanTimeTxSinceMarkMs = scanTimeSinceMarkMs; 11642 11643 if (normalizeScanRxTime) { 11644 // Scan time is longer than the total rx time in the controller, 11645 // so distribute the scan time proportionately. This means regular traffic 11646 // will not blamed, but scans are more expensive anyways. 11647 scanTimeRxSinceMarkMs = (rxTimeMs * scanTimeRxSinceMarkMs) / totalScanTimeMs; 11648 } 11649 11650 if (normalizeScanTxTime) { 11651 // Scan time is longer than the total tx time in the controller, 11652 // so distribute the scan time proportionately. This means regular traffic 11653 // will not blamed, but scans are more expensive anyways. 11654 scanTimeTxSinceMarkMs = (txTimeMs * scanTimeTxSinceMarkMs) / totalScanTimeMs; 11655 } 11656 11657 final ControllerActivityCounterImpl counter = 11658 u.getOrCreateBluetoothControllerActivityLocked(); 11659 counter.getRxTimeCounter().addCountLocked(scanTimeRxSinceMarkMs); 11660 counter.getTxTimeCounters()[0].addCountLocked(scanTimeTxSinceMarkMs); 11661 11662 leftOverRxTimeMs -= scanTimeRxSinceMarkMs; 11663 leftOverTxTimeMs -= scanTimeTxSinceMarkMs; 11664 } 11665 } 11666 11667 if (DEBUG_ENERGY) { 11668 Slog.d(TAG, "Left over time for traffic RX=" + leftOverRxTimeMs + " TX=" 11669 + leftOverTxTimeMs); 11670 } 11671 11672 // 11673 // Now distribute blame to apps that did bluetooth traffic. 11674 // 11675 11676 long totalTxBytes = 0; 11677 long totalRxBytes = 0; 11678 11679 final UidTraffic[] uidTraffic = info.getUidTraffic(); 11680 final int numUids = uidTraffic != null ? uidTraffic.length : 0; 11681 for (int i = 0; i < numUids; i++) { 11682 final UidTraffic traffic = uidTraffic[i]; 11683 final long rxBytes = traffic.getRxBytes() - mLastBluetoothActivityInfo.uidRxBytes.get( 11684 traffic.getUid()); 11685 final long txBytes = traffic.getTxBytes() - mLastBluetoothActivityInfo.uidTxBytes.get( 11686 traffic.getUid()); 11687 11688 // Add to the global counters. 11689 mNetworkByteActivityCounters[NETWORK_BT_RX_DATA].addCountLocked(rxBytes); 11690 mNetworkByteActivityCounters[NETWORK_BT_TX_DATA].addCountLocked(txBytes); 11691 11692 // Add to the UID counters. 11693 final Uid u = getUidStatsLocked(mapUid(traffic.getUid())); 11694 u.noteNetworkActivityLocked(NETWORK_BT_RX_DATA, rxBytes, 0); 11695 u.noteNetworkActivityLocked(NETWORK_BT_TX_DATA, txBytes, 0); 11696 11697 // Calculate the total traffic. 11698 totalRxBytes += rxBytes; 11699 totalTxBytes += txBytes; 11700 } 11701 11702 if ((totalTxBytes != 0 || totalRxBytes != 0) && (leftOverRxTimeMs != 0 11703 || leftOverTxTimeMs != 0)) { 11704 for (int i = 0; i < numUids; i++) { 11705 final UidTraffic traffic = uidTraffic[i]; 11706 final int uid = traffic.getUid(); 11707 final long rxBytes = 11708 traffic.getRxBytes() - mLastBluetoothActivityInfo.uidRxBytes.get(uid); 11709 final long txBytes = 11710 traffic.getTxBytes() - mLastBluetoothActivityInfo.uidTxBytes.get(uid); 11711 11712 final Uid u = getUidStatsLocked(mapUid(uid)); 11713 final ControllerActivityCounterImpl counter = 11714 u.getOrCreateBluetoothControllerActivityLocked(); 11715 11716 if (totalRxBytes > 0 && rxBytes > 0) { 11717 final long timeRxMs = (leftOverRxTimeMs * rxBytes) / totalRxBytes; 11718 if (DEBUG_ENERGY) { 11719 Slog.d(TAG, "UID=" + uid + " rx_bytes=" + rxBytes + " rx_time=" + timeRxMs); 11720 } 11721 counter.getRxTimeCounter().addCountLocked(timeRxMs); 11722 leftOverRxTimeMs -= timeRxMs; 11723 } 11724 11725 if (totalTxBytes > 0 && txBytes > 0) { 11726 final long timeTxMs = (leftOverTxTimeMs * txBytes) / totalTxBytes; 11727 if (DEBUG_ENERGY) { 11728 Slog.d(TAG, "UID=" + uid + " tx_bytes=" + txBytes + " tx_time=" + timeTxMs); 11729 } 11730 counter.getTxTimeCounters()[0].addCountLocked(timeTxMs); 11731 leftOverTxTimeMs -= timeTxMs; 11732 } 11733 } 11734 } 11735 11736 mBluetoothActivity.getRxTimeCounter().addCountLocked(rxTimeMs); 11737 mBluetoothActivity.getTxTimeCounters()[0].addCountLocked(txTimeMs); 11738 mBluetoothActivity.getIdleTimeCounter().addCountLocked(idleTimeMs); 11739 11740 // POWER_BLUETOOTH_CONTROLLER_OPERATING_VOLTAGE is measured in mV, so convert to V. 11741 final double opVolt = mPowerProfile.getAveragePower( 11742 PowerProfile.POWER_BLUETOOTH_CONTROLLER_OPERATING_VOLTAGE) / 1000.0; 11743 if (opVolt != 0) { 11744 // We store the power drain as mAms. 11745 mBluetoothActivity.getPowerCounter().addCountLocked( 11746 (long) ((info.getControllerEnergyUsed() - mLastBluetoothActivityInfo.energy) 11747 / opVolt)); 11748 } 11749 mLastBluetoothActivityInfo.set(info); 11750 } 11751 11752 /** 11753 * Read and record Resource Power Manager (RPM) state and voter times. 11754 * If RPM stats were fetched more recently than RPM_STATS_UPDATE_FREQ_MS ago, uses the old data 11755 * instead of fetching it anew. 11756 */ updateRpmStatsLocked()11757 public void updateRpmStatsLocked() { 11758 if (mPlatformIdleStateCallback == null) return; 11759 long now = SystemClock.elapsedRealtime(); 11760 if (now - mLastRpmStatsUpdateTimeMs >= RPM_STATS_UPDATE_FREQ_MS) { 11761 mPlatformIdleStateCallback.fillLowPowerStats(mTmpRpmStats); 11762 mLastRpmStatsUpdateTimeMs = now; 11763 } 11764 11765 for (Map.Entry<String, RpmStats.PowerStatePlatformSleepState> pstate 11766 : mTmpRpmStats.mPlatformLowPowerStats.entrySet()) { 11767 11768 // Update values for this platform state. 11769 final String pName = pstate.getKey(); 11770 final long pTimeUs = pstate.getValue().mTimeMs * 1000; 11771 final int pCount = pstate.getValue().mCount; 11772 getRpmTimerLocked(pName).update(pTimeUs, pCount); 11773 if (SCREEN_OFF_RPM_STATS_ENABLED) { 11774 getScreenOffRpmTimerLocked(pName).update(pTimeUs, pCount); 11775 } 11776 11777 // Update values for each voter of this platform state. 11778 for (Map.Entry<String, RpmStats.PowerStateElement> voter 11779 : pstate.getValue().mVoters.entrySet()) { 11780 final String vName = pName + "." + voter.getKey(); 11781 final long vTimeUs = voter.getValue().mTimeMs * 1000; 11782 final int vCount = voter.getValue().mCount; 11783 getRpmTimerLocked(vName).update(vTimeUs, vCount); 11784 if (SCREEN_OFF_RPM_STATS_ENABLED) { 11785 getScreenOffRpmTimerLocked(vName).update(vTimeUs, vCount); 11786 } 11787 } 11788 } 11789 11790 for (Map.Entry<String, RpmStats.PowerStateSubsystem> subsys 11791 : mTmpRpmStats.mSubsystemLowPowerStats.entrySet()) { 11792 11793 final String subsysName = subsys.getKey(); 11794 for (Map.Entry<String, RpmStats.PowerStateElement> sstate 11795 : subsys.getValue().mStates.entrySet()) { 11796 final String name = subsysName + "." + sstate.getKey(); 11797 final long timeUs = sstate.getValue().mTimeMs * 1000; 11798 final int count = sstate.getValue().mCount; 11799 getRpmTimerLocked(name).update(timeUs, count); 11800 if (SCREEN_OFF_RPM_STATS_ENABLED) { 11801 getScreenOffRpmTimerLocked(name).update(timeUs, count); 11802 } 11803 } 11804 } 11805 } 11806 11807 /** 11808 * Read and distribute kernel wake lock use across apps. 11809 */ updateKernelWakelocksLocked()11810 public void updateKernelWakelocksLocked() { 11811 final KernelWakelockStats wakelockStats = mKernelWakelockReader.readKernelWakelockStats( 11812 mTmpWakelockStats); 11813 if (wakelockStats == null) { 11814 // Not crashing might make board bringup easier. 11815 Slog.w(TAG, "Couldn't get kernel wake lock stats"); 11816 return; 11817 } 11818 11819 for (Map.Entry<String, KernelWakelockStats.Entry> ent : wakelockStats.entrySet()) { 11820 String name = ent.getKey(); 11821 KernelWakelockStats.Entry kws = ent.getValue(); 11822 11823 SamplingTimer kwlt = mKernelWakelockStats.get(name); 11824 if (kwlt == null) { 11825 kwlt = new SamplingTimer(mClocks, mOnBatteryScreenOffTimeBase); 11826 mKernelWakelockStats.put(name, kwlt); 11827 } 11828 11829 kwlt.update(kws.mTotalTime, kws.mCount); 11830 kwlt.setUpdateVersion(kws.mVersion); 11831 } 11832 11833 int numWakelocksSetStale = 0; 11834 // Set timers to stale if they didn't appear in /d/wakeup_sources (or /proc/wakelocks) 11835 // this time. 11836 for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) { 11837 SamplingTimer st = ent.getValue(); 11838 if (st.getUpdateVersion() != wakelockStats.kernelWakelockVersion) { 11839 st.endSample(); 11840 numWakelocksSetStale++; 11841 } 11842 } 11843 11844 // Record whether we've seen a non-zero time (for debugging b/22716723). 11845 if (wakelockStats.isEmpty()) { 11846 Slog.wtf(TAG, "All kernel wakelocks had time of zero"); 11847 } 11848 11849 if (numWakelocksSetStale == mKernelWakelockStats.size()) { 11850 Slog.wtf(TAG, "All kernel wakelocks were set stale. new version=" + 11851 wakelockStats.kernelWakelockVersion); 11852 } 11853 } 11854 11855 // We use an anonymous class to access these variables, 11856 // so they can't live on the stack or they'd have to be 11857 // final MutableLong objects (more allocations). 11858 // Used in updateCpuTimeLocked(). 11859 long mTempTotalCpuUserTimeUs; 11860 long mTempTotalCpuSystemTimeUs; 11861 long[][] mWakeLockAllocationsUs; 11862 11863 /** 11864 * Reads the newest memory stats from the kernel. 11865 */ updateKernelMemoryBandwidthLocked()11866 public void updateKernelMemoryBandwidthLocked() { 11867 mKernelMemoryBandwidthStats.updateStats(); 11868 LongSparseLongArray bandwidthEntries = mKernelMemoryBandwidthStats.getBandwidthEntries(); 11869 final int bandwidthEntryCount = bandwidthEntries.size(); 11870 int index; 11871 for (int i = 0; i < bandwidthEntryCount; i++) { 11872 SamplingTimer timer; 11873 if ((index = mKernelMemoryStats.indexOfKey(bandwidthEntries.keyAt(i))) >= 0) { 11874 timer = mKernelMemoryStats.valueAt(index); 11875 } else { 11876 timer = new SamplingTimer(mClocks, mOnBatteryTimeBase); 11877 mKernelMemoryStats.put(bandwidthEntries.keyAt(i), timer); 11878 } 11879 timer.update(bandwidthEntries.valueAt(i), 1); 11880 if (DEBUG_MEMORY) { 11881 Slog.d(TAG, String.format("Added entry %d and updated timer to: " 11882 + "mUnpluggedReportedTotalTime %d size %d", bandwidthEntries.keyAt(i), 11883 mKernelMemoryStats.get( 11884 bandwidthEntries.keyAt(i)).mUnpluggedReportedTotalTime, 11885 mKernelMemoryStats.size())); 11886 } 11887 } 11888 } 11889 isOnBatteryLocked()11890 public boolean isOnBatteryLocked() { 11891 return mOnBatteryTimeBase.isRunning(); 11892 } 11893 isOnBatteryScreenOffLocked()11894 public boolean isOnBatteryScreenOffLocked() { 11895 return mOnBatteryScreenOffTimeBase.isRunning(); 11896 } 11897 11898 /** 11899 * Read and distribute CPU usage across apps. If their are partial wakelocks being held 11900 * and we are on battery with screen off, we give more of the cpu time to those apps holding 11901 * wakelocks. If the screen is on, we just assign the actual cpu time an app used. 11902 * It's possible this will be invoked after the internal battery/screen states are updated, so 11903 * passing the appropriate battery/screen states to try attribute the cpu times to correct 11904 * buckets. 11905 */ 11906 @GuardedBy("this") updateCpuTimeLocked(boolean onBattery, boolean onBatteryScreenOff)11907 public void updateCpuTimeLocked(boolean onBattery, boolean onBatteryScreenOff) { 11908 if (mPowerProfile == null) { 11909 return; 11910 } 11911 11912 if (DEBUG_ENERGY_CPU) { 11913 Slog.d(TAG, "!Cpu updating!"); 11914 } 11915 11916 if (mCpuFreqs == null) { 11917 mCpuFreqs = mKernelUidCpuFreqTimeReader.readFreqs(mPowerProfile); 11918 } 11919 11920 // Calculate the wakelocks we have to distribute amongst. The system is excluded as it is 11921 // usually holding the wakelock on behalf of an app. 11922 // And Only distribute cpu power to wakelocks if the screen is off and we're on battery. 11923 ArrayList<StopwatchTimer> partialTimersToConsider = null; 11924 if (onBatteryScreenOff) { 11925 partialTimersToConsider = new ArrayList<>(); 11926 for (int i = mPartialTimers.size() - 1; i >= 0; --i) { 11927 final StopwatchTimer timer = mPartialTimers.get(i); 11928 // Since the collection and blaming of wakelocks can be scheduled to run after 11929 // some delay, the mPartialTimers list may have new entries. We can't blame 11930 // the newly added timer for past cpu time, so we only consider timers that 11931 // were present for one round of collection. Once a timer has gone through 11932 // a round of collection, its mInList field is set to true. 11933 if (timer.mInList && timer.mUid != null && timer.mUid.mUid != Process.SYSTEM_UID) { 11934 partialTimersToConsider.add(timer); 11935 } 11936 } 11937 } 11938 markPartialTimersAsEligible(); 11939 11940 // When the battery is not on, we don't attribute the cpu times to any timers but we still 11941 // need to take the snapshots. 11942 if (!onBattery) { 11943 mKernelUidCpuTimeReader.readDelta(null); 11944 mKernelUidCpuFreqTimeReader.readDelta(null); 11945 mNumAllUidCpuTimeReads += 2; 11946 if (mConstants.TRACK_CPU_ACTIVE_CLUSTER_TIME) { 11947 mKernelUidCpuActiveTimeReader.readDelta(null); 11948 mKernelUidCpuClusterTimeReader.readDelta(null); 11949 mNumAllUidCpuTimeReads += 2; 11950 } 11951 for (int cluster = mKernelCpuSpeedReaders.length - 1; cluster >= 0; --cluster) { 11952 mKernelCpuSpeedReaders[cluster].readDelta(); 11953 } 11954 return; 11955 } 11956 11957 mUserInfoProvider.refreshUserIds(); 11958 final SparseLongArray updatedUids = mKernelUidCpuFreqTimeReader.perClusterTimesAvailable() 11959 ? null : new SparseLongArray(); 11960 readKernelUidCpuTimesLocked(partialTimersToConsider, updatedUids, onBattery); 11961 // updatedUids=null means /proc/uid_time_in_state provides snapshots of per-cluster cpu 11962 // freqs, so no need to approximate these values. 11963 if (updatedUids != null) { 11964 updateClusterSpeedTimes(updatedUids, onBattery); 11965 } 11966 readKernelUidCpuFreqTimesLocked(partialTimersToConsider, onBattery, onBatteryScreenOff); 11967 mNumAllUidCpuTimeReads += 2; 11968 if (mConstants.TRACK_CPU_ACTIVE_CLUSTER_TIME) { 11969 readKernelUidCpuActiveTimesLocked(onBattery); 11970 readKernelUidCpuClusterTimesLocked(onBattery); 11971 mNumAllUidCpuTimeReads += 2; 11972 } 11973 } 11974 11975 /** 11976 * Mark the current partial timers as gone through a collection so that they will be 11977 * considered in the next cpu times distribution to wakelock holders. 11978 */ 11979 @VisibleForTesting markPartialTimersAsEligible()11980 public void markPartialTimersAsEligible() { 11981 if (ArrayUtils.referenceEquals(mPartialTimers, mLastPartialTimers)) { 11982 // No difference, so each timer is now considered for the next collection. 11983 for (int i = mPartialTimers.size() - 1; i >= 0; --i) { 11984 mPartialTimers.get(i).mInList = true; 11985 } 11986 } else { 11987 // The lists are different, meaning we added (or removed a timer) since the last 11988 // collection. 11989 for (int i = mLastPartialTimers.size() - 1; i >= 0; --i) { 11990 mLastPartialTimers.get(i).mInList = false; 11991 } 11992 mLastPartialTimers.clear(); 11993 11994 // Mark the current timers as gone through a collection. 11995 final int numPartialTimers = mPartialTimers.size(); 11996 for (int i = 0; i < numPartialTimers; ++i) { 11997 final StopwatchTimer timer = mPartialTimers.get(i); 11998 timer.mInList = true; 11999 mLastPartialTimers.add(timer); 12000 } 12001 } 12002 } 12003 12004 /** 12005 * Take snapshot of cpu times (aggregated over all uids) at different frequencies and 12006 * calculate cpu times spent by each uid at different frequencies. 12007 * 12008 * @param updatedUids The uids for which times spent at different frequencies are calculated. 12009 */ 12010 @VisibleForTesting updateClusterSpeedTimes(@onNull SparseLongArray updatedUids, boolean onBattery)12011 public void updateClusterSpeedTimes(@NonNull SparseLongArray updatedUids, boolean onBattery) { 12012 long totalCpuClustersTimeMs = 0; 12013 // Read the time spent for each cluster at various cpu frequencies. 12014 final long[][] clusterSpeedTimesMs = new long[mKernelCpuSpeedReaders.length][]; 12015 for (int cluster = 0; cluster < mKernelCpuSpeedReaders.length; cluster++) { 12016 clusterSpeedTimesMs[cluster] = mKernelCpuSpeedReaders[cluster].readDelta(); 12017 if (clusterSpeedTimesMs[cluster] != null) { 12018 for (int speed = clusterSpeedTimesMs[cluster].length - 1; speed >= 0; --speed) { 12019 totalCpuClustersTimeMs += clusterSpeedTimesMs[cluster][speed]; 12020 } 12021 } 12022 } 12023 if (totalCpuClustersTimeMs != 0) { 12024 // We have cpu times per freq aggregated over all uids but we need the times per uid. 12025 // So, we distribute total time spent by an uid to different cpu freqs based on the 12026 // amount of time cpu was running at that freq. 12027 final int updatedUidsCount = updatedUids.size(); 12028 for (int i = 0; i < updatedUidsCount; ++i) { 12029 final Uid u = getUidStatsLocked(updatedUids.keyAt(i)); 12030 final long appCpuTimeUs = updatedUids.valueAt(i); 12031 // Add the cpu speeds to this UID. 12032 final int numClusters = mPowerProfile.getNumCpuClusters(); 12033 if (u.mCpuClusterSpeedTimesUs == null || 12034 u.mCpuClusterSpeedTimesUs.length != numClusters) { 12035 u.mCpuClusterSpeedTimesUs = new LongSamplingCounter[numClusters][]; 12036 } 12037 12038 for (int cluster = 0; cluster < clusterSpeedTimesMs.length; cluster++) { 12039 final int speedsInCluster = clusterSpeedTimesMs[cluster].length; 12040 if (u.mCpuClusterSpeedTimesUs[cluster] == null || speedsInCluster != 12041 u.mCpuClusterSpeedTimesUs[cluster].length) { 12042 u.mCpuClusterSpeedTimesUs[cluster] 12043 = new LongSamplingCounter[speedsInCluster]; 12044 } 12045 12046 final LongSamplingCounter[] cpuSpeeds = u.mCpuClusterSpeedTimesUs[cluster]; 12047 for (int speed = 0; speed < speedsInCluster; speed++) { 12048 if (cpuSpeeds[speed] == null) { 12049 cpuSpeeds[speed] = new LongSamplingCounter(mOnBatteryTimeBase); 12050 } 12051 cpuSpeeds[speed].addCountLocked(appCpuTimeUs 12052 * clusterSpeedTimesMs[cluster][speed] 12053 / totalCpuClustersTimeMs, onBattery); 12054 } 12055 } 12056 } 12057 } 12058 } 12059 12060 /** 12061 * Take a snapshot of the cpu times spent by each uid and update the corresponding counters. 12062 * If {@param partialTimers} is not null and empty, then we assign a portion of cpu times to 12063 * wakelock holders. 12064 * 12065 * @param partialTimers The wakelock holders among which the cpu times will be distributed. 12066 * @param updatedUids If not null, then the uids found in the snapshot will be added to this. 12067 */ 12068 @VisibleForTesting readKernelUidCpuTimesLocked(@ullable ArrayList<StopwatchTimer> partialTimers, @Nullable SparseLongArray updatedUids, boolean onBattery)12069 public void readKernelUidCpuTimesLocked(@Nullable ArrayList<StopwatchTimer> partialTimers, 12070 @Nullable SparseLongArray updatedUids, boolean onBattery) { 12071 mTempTotalCpuUserTimeUs = mTempTotalCpuSystemTimeUs = 0; 12072 final int numWakelocks = partialTimers == null ? 0 : partialTimers.size(); 12073 final long startTimeMs = mClocks.uptimeMillis(); 12074 12075 mKernelUidCpuTimeReader.readDelta((uid, userTimeUs, systemTimeUs) -> { 12076 uid = mapUid(uid); 12077 if (Process.isIsolated(uid)) { 12078 // This could happen if the isolated uid mapping was removed before that process 12079 // was actually killed. 12080 mKernelUidCpuTimeReader.removeUid(uid); 12081 Slog.d(TAG, "Got readings for an isolated uid with no mapping: " + uid); 12082 return; 12083 } 12084 if (!mUserInfoProvider.exists(UserHandle.getUserId(uid))) { 12085 Slog.d(TAG, "Got readings for an invalid user's uid " + uid); 12086 mKernelUidCpuTimeReader.removeUid(uid); 12087 return; 12088 } 12089 final Uid u = getUidStatsLocked(uid); 12090 12091 // Accumulate the total system and user time. 12092 mTempTotalCpuUserTimeUs += userTimeUs; 12093 mTempTotalCpuSystemTimeUs += systemTimeUs; 12094 12095 StringBuilder sb = null; 12096 if (DEBUG_ENERGY_CPU) { 12097 sb = new StringBuilder(); 12098 sb.append(" got time for uid=").append(u.mUid).append(": u="); 12099 TimeUtils.formatDuration(userTimeUs / 1000, sb); 12100 sb.append(" s="); 12101 TimeUtils.formatDuration(systemTimeUs / 1000, sb); 12102 sb.append("\n"); 12103 } 12104 12105 if (numWakelocks > 0) { 12106 // We have wakelocks being held, so only give a portion of the 12107 // time to the process. The rest will be distributed among wakelock 12108 // holders. 12109 userTimeUs = (userTimeUs * WAKE_LOCK_WEIGHT) / 100; 12110 systemTimeUs = (systemTimeUs * WAKE_LOCK_WEIGHT) / 100; 12111 } 12112 12113 if (sb != null) { 12114 sb.append(" adding to uid=").append(u.mUid).append(": u="); 12115 TimeUtils.formatDuration(userTimeUs / 1000, sb); 12116 sb.append(" s="); 12117 TimeUtils.formatDuration(systemTimeUs / 1000, sb); 12118 Slog.d(TAG, sb.toString()); 12119 } 12120 12121 u.mUserCpuTime.addCountLocked(userTimeUs, onBattery); 12122 u.mSystemCpuTime.addCountLocked(systemTimeUs, onBattery); 12123 if (updatedUids != null) { 12124 updatedUids.put(u.getUid(), userTimeUs + systemTimeUs); 12125 } 12126 }); 12127 12128 final long elapsedTimeMs = mClocks.uptimeMillis() - startTimeMs; 12129 if (DEBUG_ENERGY_CPU || elapsedTimeMs >= 100) { 12130 Slog.d(TAG, "Reading cpu stats took " + elapsedTimeMs + "ms"); 12131 } 12132 12133 if (numWakelocks > 0) { 12134 // Distribute a portion of the total cpu time to wakelock holders. 12135 mTempTotalCpuUserTimeUs = (mTempTotalCpuUserTimeUs * (100 - WAKE_LOCK_WEIGHT)) / 100; 12136 mTempTotalCpuSystemTimeUs = 12137 (mTempTotalCpuSystemTimeUs * (100 - WAKE_LOCK_WEIGHT)) / 100; 12138 12139 for (int i = 0; i < numWakelocks; ++i) { 12140 final StopwatchTimer timer = partialTimers.get(i); 12141 final int userTimeUs = (int) (mTempTotalCpuUserTimeUs / (numWakelocks - i)); 12142 final int systemTimeUs = (int) (mTempTotalCpuSystemTimeUs / (numWakelocks - i)); 12143 12144 if (DEBUG_ENERGY_CPU) { 12145 final StringBuilder sb = new StringBuilder(); 12146 sb.append(" Distributing wakelock uid=").append(timer.mUid.mUid) 12147 .append(": u="); 12148 TimeUtils.formatDuration(userTimeUs / 1000, sb); 12149 sb.append(" s="); 12150 TimeUtils.formatDuration(systemTimeUs / 1000, sb); 12151 Slog.d(TAG, sb.toString()); 12152 } 12153 12154 timer.mUid.mUserCpuTime.addCountLocked(userTimeUs, onBattery); 12155 timer.mUid.mSystemCpuTime.addCountLocked(systemTimeUs, onBattery); 12156 if (updatedUids != null) { 12157 final int uid = timer.mUid.getUid(); 12158 updatedUids.put(uid, updatedUids.get(uid, 0) + userTimeUs + systemTimeUs); 12159 } 12160 12161 final Uid.Proc proc = timer.mUid.getProcessStatsLocked("*wakelock*"); 12162 proc.addCpuTimeLocked(userTimeUs / 1000, systemTimeUs / 1000, onBattery); 12163 12164 mTempTotalCpuUserTimeUs -= userTimeUs; 12165 mTempTotalCpuSystemTimeUs -= systemTimeUs; 12166 } 12167 } 12168 } 12169 12170 /** 12171 * Take a snapshot of the cpu times spent by each uid in each freq and update the 12172 * corresponding counters. 12173 * 12174 * @param partialTimers The wakelock holders among which the cpu freq times will be distributed. 12175 */ 12176 @VisibleForTesting readKernelUidCpuFreqTimesLocked(@ullable ArrayList<StopwatchTimer> partialTimers, boolean onBattery, boolean onBatteryScreenOff)12177 public void readKernelUidCpuFreqTimesLocked(@Nullable ArrayList<StopwatchTimer> partialTimers, 12178 boolean onBattery, boolean onBatteryScreenOff) { 12179 final boolean perClusterTimesAvailable = 12180 mKernelUidCpuFreqTimeReader.perClusterTimesAvailable(); 12181 final int numWakelocks = partialTimers == null ? 0 : partialTimers.size(); 12182 final int numClusters = mPowerProfile.getNumCpuClusters(); 12183 mWakeLockAllocationsUs = null; 12184 final long startTimeMs = mClocks.uptimeMillis(); 12185 mKernelUidCpuFreqTimeReader.readDelta((uid, cpuFreqTimeMs) -> { 12186 uid = mapUid(uid); 12187 if (Process.isIsolated(uid)) { 12188 mKernelUidCpuFreqTimeReader.removeUid(uid); 12189 Slog.d(TAG, "Got freq readings for an isolated uid with no mapping: " + uid); 12190 return; 12191 } 12192 if (!mUserInfoProvider.exists(UserHandle.getUserId(uid))) { 12193 Slog.d(TAG, "Got freq readings for an invalid user's uid " + uid); 12194 mKernelUidCpuFreqTimeReader.removeUid(uid); 12195 return; 12196 } 12197 final Uid u = getUidStatsLocked(uid); 12198 if (u.mCpuFreqTimeMs == null || u.mCpuFreqTimeMs.getSize() != cpuFreqTimeMs.length) { 12199 u.mCpuFreqTimeMs = new LongSamplingCounterArray(mOnBatteryTimeBase); 12200 } 12201 u.mCpuFreqTimeMs.addCountLocked(cpuFreqTimeMs, onBattery); 12202 if (u.mScreenOffCpuFreqTimeMs == null || 12203 u.mScreenOffCpuFreqTimeMs.getSize() != cpuFreqTimeMs.length) { 12204 u.mScreenOffCpuFreqTimeMs = new LongSamplingCounterArray( 12205 mOnBatteryScreenOffTimeBase); 12206 } 12207 u.mScreenOffCpuFreqTimeMs.addCountLocked(cpuFreqTimeMs, onBatteryScreenOff); 12208 12209 if (perClusterTimesAvailable) { 12210 if (u.mCpuClusterSpeedTimesUs == null || 12211 u.mCpuClusterSpeedTimesUs.length != numClusters) { 12212 u.mCpuClusterSpeedTimesUs = new LongSamplingCounter[numClusters][]; 12213 } 12214 if (numWakelocks > 0 && mWakeLockAllocationsUs == null) { 12215 mWakeLockAllocationsUs = new long[numClusters][]; 12216 } 12217 12218 int freqIndex = 0; 12219 for (int cluster = 0; cluster < numClusters; ++cluster) { 12220 final int speedsInCluster = mPowerProfile.getNumSpeedStepsInCpuCluster(cluster); 12221 if (u.mCpuClusterSpeedTimesUs[cluster] == null || 12222 u.mCpuClusterSpeedTimesUs[cluster].length != speedsInCluster) { 12223 u.mCpuClusterSpeedTimesUs[cluster] 12224 = new LongSamplingCounter[speedsInCluster]; 12225 } 12226 if (numWakelocks > 0 && mWakeLockAllocationsUs[cluster] == null) { 12227 mWakeLockAllocationsUs[cluster] = new long[speedsInCluster]; 12228 } 12229 final LongSamplingCounter[] cpuTimesUs = u.mCpuClusterSpeedTimesUs[cluster]; 12230 for (int speed = 0; speed < speedsInCluster; ++speed) { 12231 if (cpuTimesUs[speed] == null) { 12232 cpuTimesUs[speed] = new LongSamplingCounter(mOnBatteryTimeBase); 12233 } 12234 final long appAllocationUs; 12235 if (mWakeLockAllocationsUs != null) { 12236 appAllocationUs = 12237 (cpuFreqTimeMs[freqIndex] * 1000 * WAKE_LOCK_WEIGHT) / 100; 12238 mWakeLockAllocationsUs[cluster][speed] += 12239 (cpuFreqTimeMs[freqIndex] * 1000 - appAllocationUs); 12240 } else { 12241 appAllocationUs = cpuFreqTimeMs[freqIndex] * 1000; 12242 } 12243 cpuTimesUs[speed].addCountLocked(appAllocationUs, onBattery); 12244 freqIndex++; 12245 } 12246 } 12247 } 12248 }); 12249 12250 final long elapsedTimeMs = mClocks.uptimeMillis() - startTimeMs; 12251 if (DEBUG_ENERGY_CPU || elapsedTimeMs >= 100) { 12252 Slog.d(TAG, "Reading cpu freq times took " + elapsedTimeMs + "ms"); 12253 } 12254 12255 if (mWakeLockAllocationsUs != null) { 12256 for (int i = 0; i < numWakelocks; ++i) { 12257 final Uid u = partialTimers.get(i).mUid; 12258 if (u.mCpuClusterSpeedTimesUs == null || 12259 u.mCpuClusterSpeedTimesUs.length != numClusters) { 12260 u.mCpuClusterSpeedTimesUs = new LongSamplingCounter[numClusters][]; 12261 } 12262 12263 for (int cluster = 0; cluster < numClusters; ++cluster) { 12264 final int speedsInCluster = mPowerProfile.getNumSpeedStepsInCpuCluster(cluster); 12265 if (u.mCpuClusterSpeedTimesUs[cluster] == null || 12266 u.mCpuClusterSpeedTimesUs[cluster].length != speedsInCluster) { 12267 u.mCpuClusterSpeedTimesUs[cluster] 12268 = new LongSamplingCounter[speedsInCluster]; 12269 } 12270 final LongSamplingCounter[] cpuTimeUs = u.mCpuClusterSpeedTimesUs[cluster]; 12271 for (int speed = 0; speed < speedsInCluster; ++speed) { 12272 if (cpuTimeUs[speed] == null) { 12273 cpuTimeUs[speed] = new LongSamplingCounter(mOnBatteryTimeBase); 12274 } 12275 final long allocationUs = 12276 mWakeLockAllocationsUs[cluster][speed] / (numWakelocks - i); 12277 cpuTimeUs[speed].addCountLocked(allocationUs, onBattery); 12278 mWakeLockAllocationsUs[cluster][speed] -= allocationUs; 12279 } 12280 } 12281 } 12282 } 12283 } 12284 12285 /** 12286 * Take a snapshot of the cpu active times spent by each uid and update the corresponding 12287 * counters. 12288 */ 12289 @VisibleForTesting readKernelUidCpuActiveTimesLocked(boolean onBattery)12290 public void readKernelUidCpuActiveTimesLocked(boolean onBattery) { 12291 final long startTimeMs = mClocks.uptimeMillis(); 12292 mKernelUidCpuActiveTimeReader.readDelta((uid, cpuActiveTimesMs) -> { 12293 uid = mapUid(uid); 12294 if (Process.isIsolated(uid)) { 12295 mKernelUidCpuActiveTimeReader.removeUid(uid); 12296 Slog.w(TAG, "Got active times for an isolated uid with no mapping: " + uid); 12297 return; 12298 } 12299 if (!mUserInfoProvider.exists(UserHandle.getUserId(uid))) { 12300 Slog.w(TAG, "Got active times for an invalid user's uid " + uid); 12301 mKernelUidCpuActiveTimeReader.removeUid(uid); 12302 return; 12303 } 12304 final Uid u = getUidStatsLocked(uid); 12305 u.mCpuActiveTimeMs.addCountLocked(cpuActiveTimesMs, onBattery); 12306 }); 12307 12308 final long elapsedTimeMs = mClocks.uptimeMillis() - startTimeMs; 12309 if (DEBUG_ENERGY_CPU || elapsedTimeMs >= 100) { 12310 Slog.d(TAG, "Reading cpu active times took " + elapsedTimeMs + "ms"); 12311 } 12312 } 12313 12314 /** 12315 * Take a snapshot of the cpu cluster times spent by each uid and update the corresponding 12316 * counters. 12317 */ 12318 @VisibleForTesting readKernelUidCpuClusterTimesLocked(boolean onBattery)12319 public void readKernelUidCpuClusterTimesLocked(boolean onBattery) { 12320 final long startTimeMs = mClocks.uptimeMillis(); 12321 mKernelUidCpuClusterTimeReader.readDelta((uid, cpuClusterTimesMs) -> { 12322 uid = mapUid(uid); 12323 if (Process.isIsolated(uid)) { 12324 mKernelUidCpuClusterTimeReader.removeUid(uid); 12325 Slog.w(TAG, "Got cluster times for an isolated uid with no mapping: " + uid); 12326 return; 12327 } 12328 if (!mUserInfoProvider.exists(UserHandle.getUserId(uid))) { 12329 Slog.w(TAG, "Got cluster times for an invalid user's uid " + uid); 12330 mKernelUidCpuClusterTimeReader.removeUid(uid); 12331 return; 12332 } 12333 final Uid u = getUidStatsLocked(uid); 12334 u.mCpuClusterTimesMs.addCountLocked(cpuClusterTimesMs, onBattery); 12335 }); 12336 12337 final long elapsedTimeMs = mClocks.uptimeMillis() - startTimeMs; 12338 if (DEBUG_ENERGY_CPU || elapsedTimeMs >= 100) { 12339 Slog.d(TAG, "Reading cpu cluster times took " + elapsedTimeMs + "ms"); 12340 } 12341 } 12342 setChargingLocked(boolean charging)12343 boolean setChargingLocked(boolean charging) { 12344 if (mCharging != charging) { 12345 mCharging = charging; 12346 if (charging) { 12347 mHistoryCur.states2 |= HistoryItem.STATE2_CHARGING_FLAG; 12348 } else { 12349 mHistoryCur.states2 &= ~HistoryItem.STATE2_CHARGING_FLAG; 12350 } 12351 mHandler.sendEmptyMessage(MSG_REPORT_CHARGING); 12352 return true; 12353 } 12354 return false; 12355 } 12356 12357 @GuardedBy("this") setOnBatteryLocked(final long mSecRealtime, final long mSecUptime, final boolean onBattery, final int oldStatus, final int level, final int chargeUAh)12358 protected void setOnBatteryLocked(final long mSecRealtime, final long mSecUptime, 12359 final boolean onBattery, final int oldStatus, final int level, final int chargeUAh) { 12360 boolean doWrite = false; 12361 Message m = mHandler.obtainMessage(MSG_REPORT_POWER_CHANGE); 12362 m.arg1 = onBattery ? 1 : 0; 12363 mHandler.sendMessage(m); 12364 12365 final long uptime = mSecUptime * 1000; 12366 final long realtime = mSecRealtime * 1000; 12367 final int screenState = mScreenState; 12368 if (onBattery) { 12369 // We will reset our status if we are unplugging after the 12370 // battery was last full, or the level is at 100, or 12371 // we have gone through a significant charge (from a very low 12372 // level to a now very high level). 12373 boolean reset = false; 12374 if (!mNoAutoReset && (oldStatus == BatteryManager.BATTERY_STATUS_FULL 12375 || level >= 90 12376 || (mDischargeCurrentLevel < 20 && level >= 80) 12377 || (getHighDischargeAmountSinceCharge() >= 200 12378 && mHistoryBuffer.dataSize() >= MAX_HISTORY_BUFFER))) { 12379 Slog.i(TAG, "Resetting battery stats: level=" + level + " status=" + oldStatus 12380 + " dischargeLevel=" + mDischargeCurrentLevel 12381 + " lowAmount=" + getLowDischargeAmountSinceCharge() 12382 + " highAmount=" + getHighDischargeAmountSinceCharge()); 12383 // Before we write, collect a snapshot of the final aggregated 12384 // stats to be reported in the next checkin. Only do this if we have 12385 // a sufficient amount of data to make it interesting. 12386 if (getLowDischargeAmountSinceCharge() >= 20) { 12387 final long startTime = SystemClock.uptimeMillis(); 12388 final Parcel parcel = Parcel.obtain(); 12389 writeSummaryToParcel(parcel, true); 12390 final long initialTime = SystemClock.uptimeMillis() - startTime; 12391 BackgroundThread.getHandler().post(new Runnable() { 12392 @Override public void run() { 12393 synchronized (mCheckinFile) { 12394 final long startTime2 = SystemClock.uptimeMillis(); 12395 FileOutputStream stream = null; 12396 try { 12397 stream = mCheckinFile.startWrite(); 12398 stream.write(parcel.marshall()); 12399 stream.flush(); 12400 FileUtils.sync(stream); 12401 stream.close(); 12402 mCheckinFile.finishWrite(stream); 12403 com.android.internal.logging.EventLogTags.writeCommitSysConfigFile( 12404 "batterystats-checkin", 12405 initialTime + SystemClock.uptimeMillis() - startTime2); 12406 } catch (IOException e) { 12407 Slog.w("BatteryStats", 12408 "Error writing checkin battery statistics", e); 12409 mCheckinFile.failWrite(stream); 12410 } finally { 12411 parcel.recycle(); 12412 } 12413 } 12414 } 12415 }); 12416 } 12417 doWrite = true; 12418 resetAllStatsLocked(); 12419 if (chargeUAh > 0 && level > 0) { 12420 // Only use the reported coulomb charge value if it is supported and reported. 12421 mEstimatedBatteryCapacity = (int) ((chargeUAh / 1000) / (level / 100.0)); 12422 } 12423 mDischargeStartLevel = level; 12424 reset = true; 12425 mDischargeStepTracker.init(); 12426 } 12427 if (mCharging) { 12428 setChargingLocked(false); 12429 } 12430 mLastChargingStateLevel = level; 12431 mOnBattery = mOnBatteryInternal = true; 12432 mLastDischargeStepLevel = level; 12433 mMinDischargeStepLevel = level; 12434 mDischargeStepTracker.clearTime(); 12435 mDailyDischargeStepTracker.clearTime(); 12436 mInitStepMode = mCurStepMode; 12437 mModStepMode = 0; 12438 pullPendingStateUpdatesLocked(); 12439 mHistoryCur.batteryLevel = (byte)level; 12440 mHistoryCur.states &= ~HistoryItem.STATE_BATTERY_PLUGGED_FLAG; 12441 if (DEBUG_HISTORY) Slog.v(TAG, "Battery unplugged to: " 12442 + Integer.toHexString(mHistoryCur.states)); 12443 if (reset) { 12444 mRecordingHistory = true; 12445 startRecordingHistory(mSecRealtime, mSecUptime, reset); 12446 } 12447 addHistoryRecordLocked(mSecRealtime, mSecUptime); 12448 mDischargeCurrentLevel = mDischargeUnplugLevel = level; 12449 if (isScreenOn(screenState)) { 12450 mDischargeScreenOnUnplugLevel = level; 12451 mDischargeScreenDozeUnplugLevel = 0; 12452 mDischargeScreenOffUnplugLevel = 0; 12453 } else if (isScreenDoze(screenState)) { 12454 mDischargeScreenOnUnplugLevel = 0; 12455 mDischargeScreenDozeUnplugLevel = level; 12456 mDischargeScreenOffUnplugLevel = 0; 12457 } else { 12458 mDischargeScreenOnUnplugLevel = 0; 12459 mDischargeScreenDozeUnplugLevel = 0; 12460 mDischargeScreenOffUnplugLevel = level; 12461 } 12462 mDischargeAmountScreenOn = 0; 12463 mDischargeAmountScreenDoze = 0; 12464 mDischargeAmountScreenOff = 0; 12465 updateTimeBasesLocked(true, screenState, uptime, realtime); 12466 } else { 12467 mLastChargingStateLevel = level; 12468 mOnBattery = mOnBatteryInternal = false; 12469 pullPendingStateUpdatesLocked(); 12470 mHistoryCur.batteryLevel = (byte)level; 12471 mHistoryCur.states |= HistoryItem.STATE_BATTERY_PLUGGED_FLAG; 12472 if (DEBUG_HISTORY) Slog.v(TAG, "Battery plugged to: " 12473 + Integer.toHexString(mHistoryCur.states)); 12474 addHistoryRecordLocked(mSecRealtime, mSecUptime); 12475 mDischargeCurrentLevel = mDischargePlugLevel = level; 12476 if (level < mDischargeUnplugLevel) { 12477 mLowDischargeAmountSinceCharge += mDischargeUnplugLevel-level-1; 12478 mHighDischargeAmountSinceCharge += mDischargeUnplugLevel-level; 12479 } 12480 updateDischargeScreenLevelsLocked(screenState, screenState); 12481 updateTimeBasesLocked(false, screenState, uptime, realtime); 12482 mChargeStepTracker.init(); 12483 mLastChargeStepLevel = level; 12484 mMaxChargeStepLevel = level; 12485 mInitStepMode = mCurStepMode; 12486 mModStepMode = 0; 12487 } 12488 if (doWrite || (mLastWriteTime + (60 * 1000)) < mSecRealtime) { 12489 if (mFile != null) { 12490 writeAsyncLocked(); 12491 } 12492 } 12493 } 12494 startRecordingHistory(final long elapsedRealtimeMs, final long uptimeMs, boolean reset)12495 private void startRecordingHistory(final long elapsedRealtimeMs, final long uptimeMs, 12496 boolean reset) { 12497 mRecordingHistory = true; 12498 mHistoryCur.currentTime = System.currentTimeMillis(); 12499 addHistoryBufferLocked(elapsedRealtimeMs, 12500 reset ? HistoryItem.CMD_RESET : HistoryItem.CMD_CURRENT_TIME, 12501 mHistoryCur); 12502 mHistoryCur.currentTime = 0; 12503 if (reset) { 12504 initActiveHistoryEventsLocked(elapsedRealtimeMs, uptimeMs); 12505 } 12506 } 12507 recordCurrentTimeChangeLocked(final long currentTime, final long elapsedRealtimeMs, final long uptimeMs)12508 private void recordCurrentTimeChangeLocked(final long currentTime, final long elapsedRealtimeMs, 12509 final long uptimeMs) { 12510 if (mRecordingHistory) { 12511 mHistoryCur.currentTime = currentTime; 12512 addHistoryBufferLocked(elapsedRealtimeMs, HistoryItem.CMD_CURRENT_TIME, mHistoryCur); 12513 mHistoryCur.currentTime = 0; 12514 } 12515 } 12516 recordShutdownLocked(final long elapsedRealtimeMs, final long uptimeMs)12517 private void recordShutdownLocked(final long elapsedRealtimeMs, final long uptimeMs) { 12518 if (mRecordingHistory) { 12519 mHistoryCur.currentTime = System.currentTimeMillis(); 12520 addHistoryBufferLocked(elapsedRealtimeMs, HistoryItem.CMD_SHUTDOWN, mHistoryCur); 12521 mHistoryCur.currentTime = 0; 12522 } 12523 } 12524 scheduleSyncExternalStatsLocked(String reason, int updateFlags)12525 private void scheduleSyncExternalStatsLocked(String reason, int updateFlags) { 12526 if (mExternalSync != null) { 12527 mExternalSync.scheduleSync(reason, updateFlags); 12528 } 12529 } 12530 12531 // This should probably be exposed in the API, though it's not critical 12532 public static final int BATTERY_PLUGGED_NONE = OsProtoEnums.BATTERY_PLUGGED_NONE; // = 0 12533 12534 @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)12535 public void setBatteryStateLocked(final int status, final int health, final int plugType, 12536 final int level, /* not final */ int temp, final int volt, final int chargeUAh, 12537 final int chargeFullUAh) { 12538 // Temperature is encoded without the signed bit, so clamp any negative temperatures to 0. 12539 temp = Math.max(0, temp); 12540 12541 reportChangesToStatsLog(mHaveBatteryLevel ? mHistoryCur : null, 12542 status, plugType, level); 12543 12544 final boolean onBattery = isOnBattery(plugType, status); 12545 final long uptime = mClocks.uptimeMillis(); 12546 final long elapsedRealtime = mClocks.elapsedRealtime(); 12547 if (!mHaveBatteryLevel) { 12548 mHaveBatteryLevel = true; 12549 // We start out assuming that the device is plugged in (not 12550 // on battery). If our first report is now that we are indeed 12551 // plugged in, then twiddle our state to correctly reflect that 12552 // since we won't be going through the full setOnBattery(). 12553 if (onBattery == mOnBattery) { 12554 if (onBattery) { 12555 mHistoryCur.states &= ~HistoryItem.STATE_BATTERY_PLUGGED_FLAG; 12556 } else { 12557 mHistoryCur.states |= HistoryItem.STATE_BATTERY_PLUGGED_FLAG; 12558 } 12559 } 12560 // Always start out assuming charging, that will be updated later. 12561 mHistoryCur.states2 |= HistoryItem.STATE2_CHARGING_FLAG; 12562 mHistoryCur.batteryStatus = (byte)status; 12563 mHistoryCur.batteryLevel = (byte)level; 12564 mHistoryCur.batteryChargeUAh = chargeUAh; 12565 mMaxChargeStepLevel = mMinDischargeStepLevel = 12566 mLastChargeStepLevel = mLastDischargeStepLevel = level; 12567 mLastChargingStateLevel = level; 12568 } else if (mCurrentBatteryLevel != level || mOnBattery != onBattery) { 12569 recordDailyStatsIfNeededLocked(level >= 100 && onBattery); 12570 } 12571 int oldStatus = mHistoryCur.batteryStatus; 12572 if (onBattery) { 12573 mDischargeCurrentLevel = level; 12574 if (!mRecordingHistory) { 12575 mRecordingHistory = true; 12576 startRecordingHistory(elapsedRealtime, uptime, true); 12577 } 12578 } else if (level < 96 && 12579 status != BatteryManager.BATTERY_STATUS_UNKNOWN) { 12580 if (!mRecordingHistory) { 12581 mRecordingHistory = true; 12582 startRecordingHistory(elapsedRealtime, uptime, true); 12583 } 12584 } 12585 mCurrentBatteryLevel = level; 12586 if (mDischargePlugLevel < 0) { 12587 mDischargePlugLevel = level; 12588 } 12589 12590 if (onBattery != mOnBattery) { 12591 mHistoryCur.batteryLevel = (byte)level; 12592 mHistoryCur.batteryStatus = (byte)status; 12593 mHistoryCur.batteryHealth = (byte)health; 12594 mHistoryCur.batteryPlugType = (byte)plugType; 12595 mHistoryCur.batteryTemperature = (short)temp; 12596 mHistoryCur.batteryVoltage = (char)volt; 12597 if (chargeUAh < mHistoryCur.batteryChargeUAh) { 12598 // Only record discharges 12599 final long chargeDiff = mHistoryCur.batteryChargeUAh - chargeUAh; 12600 mDischargeCounter.addCountLocked(chargeDiff); 12601 mDischargeScreenOffCounter.addCountLocked(chargeDiff); 12602 if (isScreenDoze(mScreenState)) { 12603 mDischargeScreenDozeCounter.addCountLocked(chargeDiff); 12604 } 12605 if (mDeviceIdleMode == DEVICE_IDLE_MODE_LIGHT) { 12606 mDischargeLightDozeCounter.addCountLocked(chargeDiff); 12607 } else if (mDeviceIdleMode == DEVICE_IDLE_MODE_DEEP) { 12608 mDischargeDeepDozeCounter.addCountLocked(chargeDiff); 12609 } 12610 } 12611 mHistoryCur.batteryChargeUAh = chargeUAh; 12612 setOnBatteryLocked(elapsedRealtime, uptime, onBattery, oldStatus, level, chargeUAh); 12613 } else { 12614 boolean changed = false; 12615 if (mHistoryCur.batteryLevel != level) { 12616 mHistoryCur.batteryLevel = (byte)level; 12617 changed = true; 12618 12619 // TODO(adamlesinski): Schedule the creation of a HistoryStepDetails record 12620 // which will pull external stats. 12621 mExternalSync.scheduleSyncDueToBatteryLevelChange( 12622 mConstants.BATTERY_LEVEL_COLLECTION_DELAY_MS); 12623 } 12624 if (mHistoryCur.batteryStatus != status) { 12625 mHistoryCur.batteryStatus = (byte)status; 12626 changed = true; 12627 } 12628 if (mHistoryCur.batteryHealth != health) { 12629 mHistoryCur.batteryHealth = (byte)health; 12630 changed = true; 12631 } 12632 if (mHistoryCur.batteryPlugType != plugType) { 12633 mHistoryCur.batteryPlugType = (byte)plugType; 12634 changed = true; 12635 } 12636 if (temp >= (mHistoryCur.batteryTemperature+10) 12637 || temp <= (mHistoryCur.batteryTemperature-10)) { 12638 mHistoryCur.batteryTemperature = (short)temp; 12639 changed = true; 12640 } 12641 if (volt > (mHistoryCur.batteryVoltage+20) 12642 || volt < (mHistoryCur.batteryVoltage-20)) { 12643 mHistoryCur.batteryVoltage = (char)volt; 12644 changed = true; 12645 } 12646 if (chargeUAh >= (mHistoryCur.batteryChargeUAh+10) 12647 || chargeUAh <= (mHistoryCur.batteryChargeUAh-10)) { 12648 if (chargeUAh < mHistoryCur.batteryChargeUAh) { 12649 // Only record discharges 12650 final long chargeDiff = mHistoryCur.batteryChargeUAh - chargeUAh; 12651 mDischargeCounter.addCountLocked(chargeDiff); 12652 mDischargeScreenOffCounter.addCountLocked(chargeDiff); 12653 if (isScreenDoze(mScreenState)) { 12654 mDischargeScreenDozeCounter.addCountLocked(chargeDiff); 12655 } 12656 if (mDeviceIdleMode == DEVICE_IDLE_MODE_LIGHT) { 12657 mDischargeLightDozeCounter.addCountLocked(chargeDiff); 12658 } else if (mDeviceIdleMode == DEVICE_IDLE_MODE_DEEP) { 12659 mDischargeDeepDozeCounter.addCountLocked(chargeDiff); 12660 } 12661 } 12662 mHistoryCur.batteryChargeUAh = chargeUAh; 12663 changed = true; 12664 } 12665 long modeBits = (((long)mInitStepMode) << STEP_LEVEL_INITIAL_MODE_SHIFT) 12666 | (((long)mModStepMode) << STEP_LEVEL_MODIFIED_MODE_SHIFT) 12667 | (((long)(level&0xff)) << STEP_LEVEL_LEVEL_SHIFT); 12668 if (onBattery) { 12669 changed |= setChargingLocked(false); 12670 if (mLastDischargeStepLevel != level && mMinDischargeStepLevel > level) { 12671 mDischargeStepTracker.addLevelSteps(mLastDischargeStepLevel - level, 12672 modeBits, elapsedRealtime); 12673 mDailyDischargeStepTracker.addLevelSteps(mLastDischargeStepLevel - level, 12674 modeBits, elapsedRealtime); 12675 mLastDischargeStepLevel = level; 12676 mMinDischargeStepLevel = level; 12677 mInitStepMode = mCurStepMode; 12678 mModStepMode = 0; 12679 } 12680 } else { 12681 if (level >= 90) { 12682 // If the battery level is at least 90%, always consider the device to be 12683 // charging even if it happens to go down a level. 12684 changed |= setChargingLocked(true); 12685 mLastChargeStepLevel = level; 12686 } if (!mCharging) { 12687 if (mLastChargeStepLevel < level) { 12688 // We have not reporting that we are charging, but the level has now 12689 // gone up, so consider the state to be charging. 12690 changed |= setChargingLocked(true); 12691 mLastChargeStepLevel = level; 12692 } 12693 } else { 12694 if (mLastChargeStepLevel > level) { 12695 // We had reported that the device was charging, but here we are with 12696 // power connected and the level going down. Looks like the current 12697 // power supplied isn't enough, so consider the device to now be 12698 // discharging. 12699 changed |= setChargingLocked(false); 12700 mLastChargeStepLevel = level; 12701 } 12702 } 12703 if (mLastChargeStepLevel != level && mMaxChargeStepLevel < level) { 12704 mChargeStepTracker.addLevelSteps(level - mLastChargeStepLevel, 12705 modeBits, elapsedRealtime); 12706 mDailyChargeStepTracker.addLevelSteps(level - mLastChargeStepLevel, 12707 modeBits, elapsedRealtime); 12708 mLastChargeStepLevel = level; 12709 mMaxChargeStepLevel = level; 12710 mInitStepMode = mCurStepMode; 12711 mModStepMode = 0; 12712 } 12713 } 12714 if (changed) { 12715 addHistoryRecordLocked(elapsedRealtime, uptime); 12716 } 12717 } 12718 if (!onBattery && 12719 (status == BatteryManager.BATTERY_STATUS_FULL || 12720 status == BatteryManager.BATTERY_STATUS_UNKNOWN)) { 12721 // We don't record history while we are plugged in and fully charged 12722 // (or when battery is not present). The next time we are 12723 // unplugged, history will be cleared. 12724 mRecordingHistory = DEBUG; 12725 } 12726 12727 if (mMinLearnedBatteryCapacity == -1) { 12728 mMinLearnedBatteryCapacity = chargeFullUAh; 12729 } else { 12730 Math.min(mMinLearnedBatteryCapacity, chargeFullUAh); 12731 } 12732 mMaxLearnedBatteryCapacity = Math.max(mMaxLearnedBatteryCapacity, chargeFullUAh); 12733 } 12734 isOnBattery(int plugType, int status)12735 public static boolean isOnBattery(int plugType, int status) { 12736 return plugType == BATTERY_PLUGGED_NONE && status != BatteryManager.BATTERY_STATUS_UNKNOWN; 12737 } 12738 12739 // Inform StatsLog of setBatteryState changes. 12740 // If this is the first reporting, pass in recentPast == null. reportChangesToStatsLog(HistoryItem recentPast, final int status, final int plugType, final int level)12741 private void reportChangesToStatsLog(HistoryItem recentPast, 12742 final int status, final int plugType, final int level) { 12743 12744 if (recentPast == null || recentPast.batteryStatus != status) { 12745 StatsLog.write(StatsLog.CHARGING_STATE_CHANGED, status); 12746 } 12747 if (recentPast == null || recentPast.batteryPlugType != plugType) { 12748 StatsLog.write(StatsLog.PLUGGED_STATE_CHANGED, plugType); 12749 } 12750 if (recentPast == null || recentPast.batteryLevel != level) { 12751 StatsLog.write(StatsLog.BATTERY_LEVEL_CHANGED, level); 12752 } 12753 } 12754 getAwakeTimeBattery()12755 public long getAwakeTimeBattery() { 12756 return computeBatteryUptime(getBatteryUptimeLocked(), STATS_CURRENT); 12757 } 12758 getAwakeTimePlugged()12759 public long getAwakeTimePlugged() { 12760 return (mClocks.uptimeMillis() * 1000) - getAwakeTimeBattery(); 12761 } 12762 12763 @Override computeUptime(long curTime, int which)12764 public long computeUptime(long curTime, int which) { 12765 switch (which) { 12766 case STATS_SINCE_CHARGED: return mUptime + (curTime-mUptimeStart); 12767 case STATS_CURRENT: return (curTime-mUptimeStart); 12768 case STATS_SINCE_UNPLUGGED: return (curTime-mOnBatteryTimeBase.getUptimeStart()); 12769 } 12770 return 0; 12771 } 12772 12773 @Override computeRealtime(long curTime, int which)12774 public long computeRealtime(long curTime, int which) { 12775 switch (which) { 12776 case STATS_SINCE_CHARGED: return mRealtime + (curTime-mRealtimeStart); 12777 case STATS_CURRENT: return (curTime-mRealtimeStart); 12778 case STATS_SINCE_UNPLUGGED: return (curTime-mOnBatteryTimeBase.getRealtimeStart()); 12779 } 12780 return 0; 12781 } 12782 12783 @Override computeBatteryUptime(long curTime, int which)12784 public long computeBatteryUptime(long curTime, int which) { 12785 return mOnBatteryTimeBase.computeUptime(curTime, which); 12786 } 12787 12788 @Override computeBatteryRealtime(long curTime, int which)12789 public long computeBatteryRealtime(long curTime, int which) { 12790 return mOnBatteryTimeBase.computeRealtime(curTime, which); 12791 } 12792 12793 @Override computeBatteryScreenOffUptime(long curTime, int which)12794 public long computeBatteryScreenOffUptime(long curTime, int which) { 12795 return mOnBatteryScreenOffTimeBase.computeUptime(curTime, which); 12796 } 12797 12798 @Override computeBatteryScreenOffRealtime(long curTime, int which)12799 public long computeBatteryScreenOffRealtime(long curTime, int which) { 12800 return mOnBatteryScreenOffTimeBase.computeRealtime(curTime, which); 12801 } 12802 computeTimePerLevel(long[] steps, int numSteps)12803 private long computeTimePerLevel(long[] steps, int numSteps) { 12804 // For now we'll do a simple average across all steps. 12805 if (numSteps <= 0) { 12806 return -1; 12807 } 12808 long total = 0; 12809 for (int i=0; i<numSteps; i++) { 12810 total += steps[i] & STEP_LEVEL_TIME_MASK; 12811 } 12812 return total / numSteps; 12813 /* 12814 long[] buckets = new long[numSteps]; 12815 int numBuckets = 0; 12816 int numToAverage = 4; 12817 int i = 0; 12818 while (i < numSteps) { 12819 long totalTime = 0; 12820 int num = 0; 12821 for (int j=0; j<numToAverage && (i+j)<numSteps; j++) { 12822 totalTime += steps[i+j] & STEP_LEVEL_TIME_MASK; 12823 num++; 12824 } 12825 buckets[numBuckets] = totalTime / num; 12826 numBuckets++; 12827 numToAverage *= 2; 12828 i += num; 12829 } 12830 if (numBuckets < 1) { 12831 return -1; 12832 } 12833 long averageTime = buckets[numBuckets-1]; 12834 for (i=numBuckets-2; i>=0; i--) { 12835 averageTime = (averageTime + buckets[i]) / 2; 12836 } 12837 return averageTime; 12838 */ 12839 } 12840 12841 @Override computeBatteryTimeRemaining(long curTime)12842 public long computeBatteryTimeRemaining(long curTime) { 12843 if (!mOnBattery) { 12844 return -1; 12845 } 12846 /* Simple implementation just looks at the average discharge per level across the 12847 entire sample period. 12848 int discharge = (getLowDischargeAmountSinceCharge()+getHighDischargeAmountSinceCharge())/2; 12849 if (discharge < 2) { 12850 return -1; 12851 } 12852 long duration = computeBatteryRealtime(curTime, STATS_SINCE_CHARGED); 12853 if (duration < 1000*1000) { 12854 return -1; 12855 } 12856 long usPerLevel = duration/discharge; 12857 return usPerLevel * mCurrentBatteryLevel; 12858 */ 12859 if (mDischargeStepTracker.mNumStepDurations < 1) { 12860 return -1; 12861 } 12862 long msPerLevel = mDischargeStepTracker.computeTimePerLevel(); 12863 if (msPerLevel <= 0) { 12864 return -1; 12865 } 12866 return (msPerLevel * mCurrentBatteryLevel) * 1000; 12867 } 12868 12869 @Override getDischargeLevelStepTracker()12870 public LevelStepTracker getDischargeLevelStepTracker() { 12871 return mDischargeStepTracker; 12872 } 12873 12874 @Override getDailyDischargeLevelStepTracker()12875 public LevelStepTracker getDailyDischargeLevelStepTracker() { 12876 return mDailyDischargeStepTracker; 12877 } 12878 12879 @Override computeChargeTimeRemaining(long curTime)12880 public long computeChargeTimeRemaining(long curTime) { 12881 if (mOnBattery) { 12882 // Not yet working. 12883 return -1; 12884 } 12885 /* Broken 12886 int curLevel = mCurrentBatteryLevel; 12887 int plugLevel = mDischargePlugLevel; 12888 if (plugLevel < 0 || curLevel < (plugLevel+1)) { 12889 return -1; 12890 } 12891 long duration = computeBatteryRealtime(curTime, STATS_SINCE_UNPLUGGED); 12892 if (duration < 1000*1000) { 12893 return -1; 12894 } 12895 long usPerLevel = duration/(curLevel-plugLevel); 12896 return usPerLevel * (100-curLevel); 12897 */ 12898 if (mChargeStepTracker.mNumStepDurations < 1) { 12899 return -1; 12900 } 12901 long msPerLevel = mChargeStepTracker.computeTimePerLevel(); 12902 if (msPerLevel <= 0) { 12903 return -1; 12904 } 12905 return (msPerLevel * (100-mCurrentBatteryLevel)) * 1000; 12906 } 12907 12908 /*@hide */ getCellularBatteryStats()12909 public CellularBatteryStats getCellularBatteryStats() { 12910 CellularBatteryStats s = new CellularBatteryStats(); 12911 final int which = STATS_SINCE_CHARGED; 12912 final long rawRealTime = SystemClock.elapsedRealtime() * 1000; 12913 final ControllerActivityCounter counter = getModemControllerActivity(); 12914 final long sleepTimeMs = counter.getSleepTimeCounter().getCountLocked(which); 12915 final long idleTimeMs = counter.getIdleTimeCounter().getCountLocked(which); 12916 final long rxTimeMs = counter.getRxTimeCounter().getCountLocked(which); 12917 final long energyConsumedMaMs = counter.getPowerCounter().getCountLocked(which); 12918 long[] timeInRatMs = new long[BatteryStats.NUM_DATA_CONNECTION_TYPES]; 12919 for (int i = 0; i < timeInRatMs.length; i++) { 12920 timeInRatMs[i] = getPhoneDataConnectionTime(i, rawRealTime, which) / 1000; 12921 } 12922 long[] timeInRxSignalStrengthLevelMs = new long[SignalStrength.NUM_SIGNAL_STRENGTH_BINS]; 12923 for (int i = 0; i < timeInRxSignalStrengthLevelMs.length; i++) { 12924 timeInRxSignalStrengthLevelMs[i] 12925 = getPhoneSignalStrengthTime(i, rawRealTime, which) / 1000; 12926 } 12927 long[] txTimeMs = new long[Math.min(ModemActivityInfo.TX_POWER_LEVELS, 12928 counter.getTxTimeCounters().length)]; 12929 long totalTxTimeMs = 0; 12930 for (int i = 0; i < txTimeMs.length; i++) { 12931 txTimeMs[i] = counter.getTxTimeCounters()[i].getCountLocked(which); 12932 totalTxTimeMs += txTimeMs[i]; 12933 } 12934 s.setLoggingDurationMs(computeBatteryRealtime(rawRealTime, which) / 1000); 12935 s.setKernelActiveTimeMs(getMobileRadioActiveTime(rawRealTime, which) / 1000); 12936 s.setNumPacketsTx(getNetworkActivityPackets(NETWORK_MOBILE_TX_DATA, which)); 12937 s.setNumBytesTx(getNetworkActivityBytes(NETWORK_MOBILE_TX_DATA, which)); 12938 s.setNumPacketsRx(getNetworkActivityPackets(NETWORK_MOBILE_RX_DATA, which)); 12939 s.setNumBytesRx(getNetworkActivityBytes(NETWORK_MOBILE_RX_DATA, which)); 12940 s.setSleepTimeMs(sleepTimeMs); 12941 s.setIdleTimeMs(idleTimeMs); 12942 s.setRxTimeMs(rxTimeMs); 12943 s.setEnergyConsumedMaMs(energyConsumedMaMs); 12944 s.setTimeInRatMs(timeInRatMs); 12945 s.setTimeInRxSignalStrengthLevelMs(timeInRxSignalStrengthLevelMs); 12946 s.setTxTimeMs(txTimeMs); 12947 return s; 12948 } 12949 12950 /*@hide */ getWifiBatteryStats()12951 public WifiBatteryStats getWifiBatteryStats() { 12952 WifiBatteryStats s = new WifiBatteryStats(); 12953 final int which = STATS_SINCE_CHARGED; 12954 final long rawRealTime = SystemClock.elapsedRealtime() * 1000; 12955 final ControllerActivityCounter counter = getWifiControllerActivity(); 12956 final long idleTimeMs = counter.getIdleTimeCounter().getCountLocked(which); 12957 final long scanTimeMs = counter.getScanTimeCounter().getCountLocked(which); 12958 final long rxTimeMs = counter.getRxTimeCounter().getCountLocked(which); 12959 final long txTimeMs = counter.getTxTimeCounters()[0].getCountLocked(which); 12960 final long totalControllerActivityTimeMs 12961 = computeBatteryRealtime(SystemClock.elapsedRealtime() * 1000, which) / 1000; 12962 final long sleepTimeMs 12963 = totalControllerActivityTimeMs - (idleTimeMs + rxTimeMs + txTimeMs); 12964 final long energyConsumedMaMs = counter.getPowerCounter().getCountLocked(which); 12965 long numAppScanRequest = 0; 12966 for (int i = 0; i < mUidStats.size(); i++) { 12967 numAppScanRequest += mUidStats.valueAt(i).mWifiScanTimer.getCountLocked(which); 12968 } 12969 long[] timeInStateMs = new long[NUM_WIFI_STATES]; 12970 for (int i=0; i<NUM_WIFI_STATES; i++) { 12971 timeInStateMs[i] = getWifiStateTime(i, rawRealTime, which) / 1000; 12972 } 12973 long[] timeInSupplStateMs = new long[NUM_WIFI_SUPPL_STATES]; 12974 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) { 12975 timeInSupplStateMs[i] = getWifiSupplStateTime(i, rawRealTime, which) / 1000; 12976 } 12977 long[] timeSignalStrengthTimeMs = new long[NUM_WIFI_SIGNAL_STRENGTH_BINS]; 12978 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { 12979 timeSignalStrengthTimeMs[i] = getWifiSignalStrengthTime(i, rawRealTime, which) / 1000; 12980 } 12981 s.setLoggingDurationMs(computeBatteryRealtime(rawRealTime, which) / 1000); 12982 s.setKernelActiveTimeMs(getWifiActiveTime(rawRealTime, which) / 1000); 12983 s.setNumPacketsTx(getNetworkActivityPackets(NETWORK_WIFI_TX_DATA, which)); 12984 s.setNumBytesTx(getNetworkActivityBytes(NETWORK_WIFI_TX_DATA, which)); 12985 s.setNumPacketsRx(getNetworkActivityPackets(NETWORK_WIFI_RX_DATA, which)); 12986 s.setNumBytesRx(getNetworkActivityBytes(NETWORK_WIFI_RX_DATA, which)); 12987 s.setSleepTimeMs(sleepTimeMs); 12988 s.setIdleTimeMs(idleTimeMs); 12989 s.setRxTimeMs(rxTimeMs); 12990 s.setTxTimeMs(txTimeMs); 12991 s.setScanTimeMs(scanTimeMs); 12992 s.setEnergyConsumedMaMs(energyConsumedMaMs); 12993 s.setNumAppScanRequest(numAppScanRequest); 12994 s.setTimeInStateMs(timeInStateMs); 12995 s.setTimeInSupplicantStateMs(timeInSupplStateMs); 12996 s.setTimeInRxSignalStrengthLevelMs(timeSignalStrengthTimeMs); 12997 return s; 12998 } 12999 13000 /*@hide */ getGpsBatteryStats()13001 public GpsBatteryStats getGpsBatteryStats() { 13002 GpsBatteryStats s = new GpsBatteryStats(); 13003 final int which = STATS_SINCE_CHARGED; 13004 final long rawRealTime = SystemClock.elapsedRealtime() * 1000; 13005 s.setLoggingDurationMs(computeBatteryRealtime(rawRealTime, which) / 1000); 13006 s.setEnergyConsumedMaMs(getGpsBatteryDrainMaMs()); 13007 long[] time = new long[GnssMetrics.NUM_GPS_SIGNAL_QUALITY_LEVELS]; 13008 for (int i=0; i<time.length; i++) { 13009 time[i] = getGpsSignalQualityTime(i, rawRealTime, which) / 1000; 13010 } 13011 s.setTimeInGpsSignalQualityLevel(time); 13012 return s; 13013 } 13014 13015 @Override getChargeLevelStepTracker()13016 public LevelStepTracker getChargeLevelStepTracker() { 13017 return mChargeStepTracker; 13018 } 13019 13020 @Override getDailyChargeLevelStepTracker()13021 public LevelStepTracker getDailyChargeLevelStepTracker() { 13022 return mDailyChargeStepTracker; 13023 } 13024 13025 @Override getDailyPackageChanges()13026 public ArrayList<PackageChange> getDailyPackageChanges() { 13027 return mDailyPackageChanges; 13028 } 13029 getBatteryUptimeLocked()13030 protected long getBatteryUptimeLocked() { 13031 return mOnBatteryTimeBase.getUptime(mClocks.uptimeMillis() * 1000); 13032 } 13033 13034 @Override getBatteryUptime(long curTime)13035 public long getBatteryUptime(long curTime) { 13036 return mOnBatteryTimeBase.getUptime(curTime); 13037 } 13038 13039 @Override getBatteryRealtime(long curTime)13040 public long getBatteryRealtime(long curTime) { 13041 return mOnBatteryTimeBase.getRealtime(curTime); 13042 } 13043 13044 @Override getDischargeStartLevel()13045 public int getDischargeStartLevel() { 13046 synchronized(this) { 13047 return getDischargeStartLevelLocked(); 13048 } 13049 } 13050 getDischargeStartLevelLocked()13051 public int getDischargeStartLevelLocked() { 13052 return mDischargeUnplugLevel; 13053 } 13054 13055 @Override getDischargeCurrentLevel()13056 public int getDischargeCurrentLevel() { 13057 synchronized(this) { 13058 return getDischargeCurrentLevelLocked(); 13059 } 13060 } 13061 getDischargeCurrentLevelLocked()13062 public int getDischargeCurrentLevelLocked() { 13063 return mDischargeCurrentLevel; 13064 } 13065 13066 @Override getLowDischargeAmountSinceCharge()13067 public int getLowDischargeAmountSinceCharge() { 13068 synchronized(this) { 13069 int val = mLowDischargeAmountSinceCharge; 13070 if (mOnBattery && mDischargeCurrentLevel < mDischargeUnplugLevel) { 13071 val += mDischargeUnplugLevel-mDischargeCurrentLevel-1; 13072 } 13073 return val; 13074 } 13075 } 13076 13077 @Override getHighDischargeAmountSinceCharge()13078 public int getHighDischargeAmountSinceCharge() { 13079 synchronized(this) { 13080 int val = mHighDischargeAmountSinceCharge; 13081 if (mOnBattery && mDischargeCurrentLevel < mDischargeUnplugLevel) { 13082 val += mDischargeUnplugLevel-mDischargeCurrentLevel; 13083 } 13084 return val; 13085 } 13086 } 13087 13088 @Override getDischargeAmount(int which)13089 public int getDischargeAmount(int which) { 13090 int dischargeAmount = which == STATS_SINCE_CHARGED 13091 ? getHighDischargeAmountSinceCharge() 13092 : (getDischargeStartLevel() - getDischargeCurrentLevel()); 13093 if (dischargeAmount < 0) { 13094 dischargeAmount = 0; 13095 } 13096 return dischargeAmount; 13097 } 13098 13099 @Override getDischargeAmountScreenOn()13100 public int getDischargeAmountScreenOn() { 13101 synchronized(this) { 13102 int val = mDischargeAmountScreenOn; 13103 if (mOnBattery && isScreenOn(mScreenState) 13104 && mDischargeCurrentLevel < mDischargeScreenOnUnplugLevel) { 13105 val += mDischargeScreenOnUnplugLevel-mDischargeCurrentLevel; 13106 } 13107 return val; 13108 } 13109 } 13110 13111 @Override getDischargeAmountScreenOnSinceCharge()13112 public int getDischargeAmountScreenOnSinceCharge() { 13113 synchronized(this) { 13114 int val = mDischargeAmountScreenOnSinceCharge; 13115 if (mOnBattery && isScreenOn(mScreenState) 13116 && mDischargeCurrentLevel < mDischargeScreenOnUnplugLevel) { 13117 val += mDischargeScreenOnUnplugLevel-mDischargeCurrentLevel; 13118 } 13119 return val; 13120 } 13121 } 13122 13123 @Override getDischargeAmountScreenOff()13124 public int getDischargeAmountScreenOff() { 13125 synchronized(this) { 13126 int val = mDischargeAmountScreenOff; 13127 if (mOnBattery && isScreenOff(mScreenState) 13128 && mDischargeCurrentLevel < mDischargeScreenOffUnplugLevel) { 13129 val += mDischargeScreenOffUnplugLevel-mDischargeCurrentLevel; 13130 } 13131 // For backward compatibility, doze discharge is counted into screen off. 13132 return val + getDischargeAmountScreenDoze(); 13133 } 13134 } 13135 13136 @Override getDischargeAmountScreenOffSinceCharge()13137 public int getDischargeAmountScreenOffSinceCharge() { 13138 synchronized(this) { 13139 int val = mDischargeAmountScreenOffSinceCharge; 13140 if (mOnBattery && isScreenOff(mScreenState) 13141 && mDischargeCurrentLevel < mDischargeScreenOffUnplugLevel) { 13142 val += mDischargeScreenOffUnplugLevel-mDischargeCurrentLevel; 13143 } 13144 // For backward compatibility, doze discharge is counted into screen off. 13145 return val + getDischargeAmountScreenDozeSinceCharge(); 13146 } 13147 } 13148 13149 @Override getDischargeAmountScreenDoze()13150 public int getDischargeAmountScreenDoze() { 13151 synchronized(this) { 13152 int val = mDischargeAmountScreenDoze; 13153 if (mOnBattery && isScreenDoze(mScreenState) 13154 && mDischargeCurrentLevel < mDischargeScreenDozeUnplugLevel) { 13155 val += mDischargeScreenDozeUnplugLevel-mDischargeCurrentLevel; 13156 } 13157 return val; 13158 } 13159 } 13160 13161 @Override getDischargeAmountScreenDozeSinceCharge()13162 public int getDischargeAmountScreenDozeSinceCharge() { 13163 synchronized(this) { 13164 int val = mDischargeAmountScreenDozeSinceCharge; 13165 if (mOnBattery && isScreenDoze(mScreenState) 13166 && mDischargeCurrentLevel < mDischargeScreenDozeUnplugLevel) { 13167 val += mDischargeScreenDozeUnplugLevel-mDischargeCurrentLevel; 13168 } 13169 return val; 13170 } 13171 } 13172 13173 /** 13174 * Retrieve the statistics object for a particular uid, creating if needed. 13175 */ getUidStatsLocked(int uid)13176 public Uid getUidStatsLocked(int uid) { 13177 Uid u = mUidStats.get(uid); 13178 if (u == null) { 13179 u = new Uid(this, uid); 13180 mUidStats.put(uid, u); 13181 } 13182 return u; 13183 } 13184 13185 /** 13186 * Retrieve the statistics object for a particular uid. Returns null if the object is not 13187 * available. 13188 */ getAvailableUidStatsLocked(int uid)13189 public Uid getAvailableUidStatsLocked(int uid) { 13190 Uid u = mUidStats.get(uid); 13191 return u; 13192 } 13193 onCleanupUserLocked(int userId)13194 public void onCleanupUserLocked(int userId) { 13195 final int firstUidForUser = UserHandle.getUid(userId, 0); 13196 final int lastUidForUser = UserHandle.getUid(userId, UserHandle.PER_USER_RANGE - 1); 13197 mPendingRemovedUids.add( 13198 new UidToRemove(firstUidForUser, lastUidForUser, mClocks.elapsedRealtime())); 13199 } 13200 onUserRemovedLocked(int userId)13201 public void onUserRemovedLocked(int userId) { 13202 final int firstUidForUser = UserHandle.getUid(userId, 0); 13203 final int lastUidForUser = UserHandle.getUid(userId, UserHandle.PER_USER_RANGE - 1); 13204 mUidStats.put(firstUidForUser, null); 13205 mUidStats.put(lastUidForUser, null); 13206 final int firstIndex = mUidStats.indexOfKey(firstUidForUser); 13207 final int lastIndex = mUidStats.indexOfKey(lastUidForUser); 13208 mUidStats.removeAtRange(firstIndex, lastIndex - firstIndex + 1); 13209 } 13210 13211 /** 13212 * Remove the statistics object for a particular uid. 13213 */ removeUidStatsLocked(int uid)13214 public void removeUidStatsLocked(int uid) { 13215 mUidStats.remove(uid); 13216 mPendingRemovedUids.add(new UidToRemove(uid, mClocks.elapsedRealtime())); 13217 } 13218 13219 /** 13220 * Retrieve the statistics object for a particular process, creating 13221 * if needed. 13222 */ getProcessStatsLocked(int uid, String name)13223 public Uid.Proc getProcessStatsLocked(int uid, String name) { 13224 uid = mapUid(uid); 13225 Uid u = getUidStatsLocked(uid); 13226 return u.getProcessStatsLocked(name); 13227 } 13228 13229 /** 13230 * Retrieve the statistics object for a particular process, creating 13231 * if needed. 13232 */ getPackageStatsLocked(int uid, String pkg)13233 public Uid.Pkg getPackageStatsLocked(int uid, String pkg) { 13234 uid = mapUid(uid); 13235 Uid u = getUidStatsLocked(uid); 13236 return u.getPackageStatsLocked(pkg); 13237 } 13238 13239 /** 13240 * Retrieve the statistics object for a particular service, creating 13241 * if needed. 13242 */ getServiceStatsLocked(int uid, String pkg, String name)13243 public Uid.Pkg.Serv getServiceStatsLocked(int uid, String pkg, String name) { 13244 uid = mapUid(uid); 13245 Uid u = getUidStatsLocked(uid); 13246 return u.getServiceStatsLocked(pkg, name); 13247 } 13248 shutdownLocked()13249 public void shutdownLocked() { 13250 recordShutdownLocked(mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 13251 writeSyncLocked(); 13252 mShuttingDown = true; 13253 } 13254 trackPerProcStateCpuTimes()13255 public boolean trackPerProcStateCpuTimes() { 13256 return mConstants.TRACK_CPU_TIMES_BY_PROC_STATE && mPerProcStateCpuTimesAvailable; 13257 } 13258 systemServicesReady(Context context)13259 public void systemServicesReady(Context context) { 13260 mConstants.startObserving(context.getContentResolver()); 13261 registerUsbStateReceiver(context); 13262 } 13263 13264 @VisibleForTesting 13265 public final class Constants extends ContentObserver { 13266 public static final String KEY_TRACK_CPU_TIMES_BY_PROC_STATE 13267 = "track_cpu_times_by_proc_state"; 13268 public static final String KEY_TRACK_CPU_ACTIVE_CLUSTER_TIME 13269 = "track_cpu_active_cluster_time"; 13270 public static final String KEY_PROC_STATE_CPU_TIMES_READ_DELAY_MS 13271 = "proc_state_cpu_times_read_delay_ms"; 13272 public static final String KEY_KERNEL_UID_READERS_THROTTLE_TIME 13273 = "kernel_uid_readers_throttle_time"; 13274 public static final String KEY_UID_REMOVE_DELAY_MS 13275 = "uid_remove_delay_ms"; 13276 public static final String KEY_EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS 13277 = "external_stats_collection_rate_limit_ms"; 13278 public static final String KEY_BATTERY_LEVEL_COLLECTION_DELAY_MS 13279 = "battery_level_collection_delay_ms"; 13280 13281 private static final boolean DEFAULT_TRACK_CPU_TIMES_BY_PROC_STATE = true; 13282 private static final boolean DEFAULT_TRACK_CPU_ACTIVE_CLUSTER_TIME = true; 13283 private static final long DEFAULT_PROC_STATE_CPU_TIMES_READ_DELAY_MS = 5_000; 13284 private static final long DEFAULT_KERNEL_UID_READERS_THROTTLE_TIME = 10_000; 13285 private static final long DEFAULT_UID_REMOVE_DELAY_MS = 5L * 60L * 1000L; 13286 private static final long DEFAULT_EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS = 600_000; 13287 private static final long DEFAULT_BATTERY_LEVEL_COLLECTION_DELAY_MS = 300_000; 13288 13289 public boolean TRACK_CPU_TIMES_BY_PROC_STATE = DEFAULT_TRACK_CPU_TIMES_BY_PROC_STATE; 13290 public boolean TRACK_CPU_ACTIVE_CLUSTER_TIME = DEFAULT_TRACK_CPU_ACTIVE_CLUSTER_TIME; 13291 public long PROC_STATE_CPU_TIMES_READ_DELAY_MS = DEFAULT_PROC_STATE_CPU_TIMES_READ_DELAY_MS; 13292 public long KERNEL_UID_READERS_THROTTLE_TIME = DEFAULT_KERNEL_UID_READERS_THROTTLE_TIME; 13293 public long UID_REMOVE_DELAY_MS = DEFAULT_UID_REMOVE_DELAY_MS; 13294 public long EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS 13295 = DEFAULT_EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS; 13296 public long BATTERY_LEVEL_COLLECTION_DELAY_MS 13297 = DEFAULT_BATTERY_LEVEL_COLLECTION_DELAY_MS; 13298 13299 private ContentResolver mResolver; 13300 private final KeyValueListParser mParser = new KeyValueListParser(','); 13301 Constants(Handler handler)13302 public Constants(Handler handler) { 13303 super(handler); 13304 } 13305 startObserving(ContentResolver resolver)13306 public void startObserving(ContentResolver resolver) { 13307 mResolver = resolver; 13308 mResolver.registerContentObserver( 13309 Settings.Global.getUriFor(Settings.Global.BATTERY_STATS_CONSTANTS), 13310 false /* notifyForDescendants */, this); 13311 updateConstants(); 13312 } 13313 13314 @Override onChange(boolean selfChange, Uri uri)13315 public void onChange(boolean selfChange, Uri uri) { 13316 updateConstants(); 13317 } 13318 updateConstants()13319 private void updateConstants() { 13320 synchronized (BatteryStatsImpl.this) { 13321 try { 13322 mParser.setString(Settings.Global.getString(mResolver, 13323 Settings.Global.BATTERY_STATS_CONSTANTS)); 13324 } catch (IllegalArgumentException e) { 13325 // Failed to parse the settings string, log this and move on 13326 // with defaults. 13327 Slog.e(TAG, "Bad batterystats settings", e); 13328 } 13329 13330 updateTrackCpuTimesByProcStateLocked(TRACK_CPU_TIMES_BY_PROC_STATE, 13331 mParser.getBoolean(KEY_TRACK_CPU_TIMES_BY_PROC_STATE, 13332 DEFAULT_TRACK_CPU_TIMES_BY_PROC_STATE)); 13333 TRACK_CPU_ACTIVE_CLUSTER_TIME = mParser.getBoolean( 13334 KEY_TRACK_CPU_ACTIVE_CLUSTER_TIME, DEFAULT_TRACK_CPU_ACTIVE_CLUSTER_TIME); 13335 updateProcStateCpuTimesReadDelayMs(PROC_STATE_CPU_TIMES_READ_DELAY_MS, 13336 mParser.getLong(KEY_PROC_STATE_CPU_TIMES_READ_DELAY_MS, 13337 DEFAULT_PROC_STATE_CPU_TIMES_READ_DELAY_MS)); 13338 updateKernelUidReadersThrottleTime(KERNEL_UID_READERS_THROTTLE_TIME, 13339 mParser.getLong(KEY_KERNEL_UID_READERS_THROTTLE_TIME, 13340 DEFAULT_KERNEL_UID_READERS_THROTTLE_TIME)); 13341 updateUidRemoveDelay( 13342 mParser.getLong(KEY_UID_REMOVE_DELAY_MS, DEFAULT_UID_REMOVE_DELAY_MS)); 13343 EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS = mParser.getLong( 13344 KEY_EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS, 13345 DEFAULT_EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS); 13346 BATTERY_LEVEL_COLLECTION_DELAY_MS = mParser.getLong( 13347 KEY_BATTERY_LEVEL_COLLECTION_DELAY_MS, 13348 DEFAULT_BATTERY_LEVEL_COLLECTION_DELAY_MS); 13349 } 13350 } 13351 updateTrackCpuTimesByProcStateLocked(boolean wasEnabled, boolean isEnabled)13352 private void updateTrackCpuTimesByProcStateLocked(boolean wasEnabled, boolean isEnabled) { 13353 TRACK_CPU_TIMES_BY_PROC_STATE = isEnabled; 13354 if (isEnabled && !wasEnabled) { 13355 mKernelSingleUidTimeReader.markDataAsStale(true); 13356 mExternalSync.scheduleCpuSyncDueToSettingChange(); 13357 13358 mNumSingleUidCpuTimeReads = 0; 13359 mNumBatchedSingleUidCpuTimeReads = 0; 13360 mCpuTimeReadsTrackingStartTime = mClocks.uptimeMillis(); 13361 } 13362 } 13363 updateProcStateCpuTimesReadDelayMs(long oldDelayMillis, long newDelayMillis)13364 private void updateProcStateCpuTimesReadDelayMs(long oldDelayMillis, long newDelayMillis) { 13365 PROC_STATE_CPU_TIMES_READ_DELAY_MS = newDelayMillis; 13366 if (oldDelayMillis != newDelayMillis) { 13367 mNumSingleUidCpuTimeReads = 0; 13368 mNumBatchedSingleUidCpuTimeReads = 0; 13369 mCpuTimeReadsTrackingStartTime = mClocks.uptimeMillis(); 13370 } 13371 } 13372 updateKernelUidReadersThrottleTime(long oldTimeMs, long newTimeMs)13373 private void updateKernelUidReadersThrottleTime(long oldTimeMs, long newTimeMs) { 13374 KERNEL_UID_READERS_THROTTLE_TIME = newTimeMs; 13375 if (oldTimeMs != newTimeMs) { 13376 mKernelUidCpuTimeReader.setThrottleInterval(KERNEL_UID_READERS_THROTTLE_TIME); 13377 mKernelUidCpuFreqTimeReader.setThrottleInterval(KERNEL_UID_READERS_THROTTLE_TIME); 13378 mKernelUidCpuActiveTimeReader.setThrottleInterval(KERNEL_UID_READERS_THROTTLE_TIME); 13379 mKernelUidCpuClusterTimeReader 13380 .setThrottleInterval(KERNEL_UID_READERS_THROTTLE_TIME); 13381 } 13382 } 13383 updateUidRemoveDelay(long newTimeMs)13384 private void updateUidRemoveDelay(long newTimeMs) { 13385 UID_REMOVE_DELAY_MS = newTimeMs; 13386 clearPendingRemovedUids(); 13387 } 13388 dumpLocked(PrintWriter pw)13389 public void dumpLocked(PrintWriter pw) { 13390 pw.print(KEY_TRACK_CPU_TIMES_BY_PROC_STATE); pw.print("="); 13391 pw.println(TRACK_CPU_TIMES_BY_PROC_STATE); 13392 pw.print(KEY_TRACK_CPU_ACTIVE_CLUSTER_TIME); pw.print("="); 13393 pw.println(TRACK_CPU_ACTIVE_CLUSTER_TIME); 13394 pw.print(KEY_PROC_STATE_CPU_TIMES_READ_DELAY_MS); pw.print("="); 13395 pw.println(PROC_STATE_CPU_TIMES_READ_DELAY_MS); 13396 pw.print(KEY_KERNEL_UID_READERS_THROTTLE_TIME); pw.print("="); 13397 pw.println(KERNEL_UID_READERS_THROTTLE_TIME); 13398 pw.print(KEY_EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS); pw.print("="); 13399 pw.println(EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS); 13400 pw.print(KEY_BATTERY_LEVEL_COLLECTION_DELAY_MS); pw.print("="); 13401 pw.println(BATTERY_LEVEL_COLLECTION_DELAY_MS); 13402 } 13403 } 13404 getExternalStatsCollectionRateLimitMs()13405 public long getExternalStatsCollectionRateLimitMs() { 13406 synchronized (this) { 13407 return mConstants.EXTERNAL_STATS_COLLECTION_RATE_LIMIT_MS; 13408 } 13409 } 13410 13411 @GuardedBy("this") dumpConstantsLocked(PrintWriter pw)13412 public void dumpConstantsLocked(PrintWriter pw) { 13413 mConstants.dumpLocked(pw); 13414 } 13415 13416 @GuardedBy("this") dumpCpuStatsLocked(PrintWriter pw)13417 public void dumpCpuStatsLocked(PrintWriter pw) { 13418 int size = mUidStats.size(); 13419 pw.println("Per UID CPU user & system time in ms:"); 13420 for (int i = 0; i < size; i++) { 13421 int u = mUidStats.keyAt(i); 13422 Uid uid = mUidStats.get(u); 13423 pw.print(" "); pw.print(u); pw.print(": "); 13424 pw.print(uid.getUserCpuTimeUs(STATS_SINCE_CHARGED) / 1000); pw.print(" "); 13425 pw.println(uid.getSystemCpuTimeUs(STATS_SINCE_CHARGED) / 1000); 13426 } 13427 pw.println("Per UID CPU active time in ms:"); 13428 for (int i = 0; i < size; i++) { 13429 int u = mUidStats.keyAt(i); 13430 Uid uid = mUidStats.get(u); 13431 if (uid.getCpuActiveTime() > 0) { 13432 pw.print(" "); pw.print(u); pw.print(": "); pw.println(uid.getCpuActiveTime()); 13433 } 13434 } 13435 pw.println("Per UID CPU cluster time in ms:"); 13436 for (int i = 0; i < size; i++) { 13437 int u = mUidStats.keyAt(i); 13438 long[] times = mUidStats.get(u).getCpuClusterTimes(); 13439 if (times != null) { 13440 pw.print(" "); pw.print(u); pw.print(": "); pw.println(Arrays.toString(times)); 13441 } 13442 } 13443 pw.println("Per UID CPU frequency time in ms:"); 13444 for (int i = 0; i < size; i++) { 13445 int u = mUidStats.keyAt(i); 13446 long[] times = mUidStats.get(u).getCpuFreqTimes(STATS_SINCE_CHARGED); 13447 if (times != null) { 13448 pw.print(" "); pw.print(u); pw.print(": "); pw.println(Arrays.toString(times)); 13449 } 13450 } 13451 } 13452 13453 Parcel mPendingWrite = null; 13454 final ReentrantLock mWriteLock = new ReentrantLock(); 13455 writeAsyncLocked()13456 public void writeAsyncLocked() { 13457 writeLocked(false); 13458 } 13459 writeSyncLocked()13460 public void writeSyncLocked() { 13461 writeLocked(true); 13462 } 13463 writeLocked(boolean sync)13464 void writeLocked(boolean sync) { 13465 if (mFile == null) { 13466 Slog.w("BatteryStats", "writeLocked: no file associated with this instance"); 13467 return; 13468 } 13469 13470 if (mShuttingDown) { 13471 return; 13472 } 13473 13474 Parcel out = Parcel.obtain(); 13475 writeSummaryToParcel(out, true); 13476 mLastWriteTime = mClocks.elapsedRealtime(); 13477 13478 if (mPendingWrite != null) { 13479 mPendingWrite.recycle(); 13480 } 13481 mPendingWrite = out; 13482 13483 if (sync) { 13484 commitPendingDataToDisk(); 13485 } else { 13486 BackgroundThread.getHandler().post(new Runnable() { 13487 @Override public void run() { 13488 commitPendingDataToDisk(); 13489 } 13490 }); 13491 } 13492 } 13493 commitPendingDataToDisk()13494 public void commitPendingDataToDisk() { 13495 final Parcel next; 13496 synchronized (this) { 13497 next = mPendingWrite; 13498 mPendingWrite = null; 13499 if (next == null) { 13500 return; 13501 } 13502 } 13503 13504 mWriteLock.lock(); 13505 try { 13506 final long startTime = SystemClock.uptimeMillis(); 13507 FileOutputStream stream = new FileOutputStream(mFile.chooseForWrite()); 13508 stream.write(next.marshall()); 13509 stream.flush(); 13510 FileUtils.sync(stream); 13511 stream.close(); 13512 mFile.commit(); 13513 com.android.internal.logging.EventLogTags.writeCommitSysConfigFile( 13514 "batterystats", SystemClock.uptimeMillis() - startTime); 13515 } catch (IOException e) { 13516 Slog.w("BatteryStats", "Error writing battery statistics", e); 13517 mFile.rollback(); 13518 } finally { 13519 next.recycle(); 13520 mWriteLock.unlock(); 13521 } 13522 } 13523 readLocked()13524 public void readLocked() { 13525 if (mDailyFile != null) { 13526 readDailyStatsLocked(); 13527 } 13528 13529 if (mFile == null) { 13530 Slog.w("BatteryStats", "readLocked: no file associated with this instance"); 13531 return; 13532 } 13533 13534 mUidStats.clear(); 13535 13536 try { 13537 File file = mFile.chooseForRead(); 13538 if (!file.exists()) { 13539 return; 13540 } 13541 FileInputStream stream = new FileInputStream(file); 13542 13543 byte[] raw = BatteryStatsHelper.readFully(stream); 13544 Parcel in = Parcel.obtain(); 13545 in.unmarshall(raw, 0, raw.length); 13546 in.setDataPosition(0); 13547 stream.close(); 13548 13549 readSummaryFromParcel(in); 13550 } catch(Exception e) { 13551 Slog.e("BatteryStats", "Error reading battery statistics", e); 13552 resetAllStatsLocked(); 13553 } 13554 13555 mEndPlatformVersion = Build.ID; 13556 13557 if (mHistoryBuffer.dataPosition() > 0) { 13558 mRecordingHistory = true; 13559 final long elapsedRealtime = mClocks.elapsedRealtime(); 13560 final long uptime = mClocks.uptimeMillis(); 13561 if (USE_OLD_HISTORY) { 13562 addHistoryRecordLocked(elapsedRealtime, uptime, HistoryItem.CMD_START, mHistoryCur); 13563 } 13564 addHistoryBufferLocked(elapsedRealtime, HistoryItem.CMD_START, mHistoryCur); 13565 startRecordingHistory(elapsedRealtime, uptime, false); 13566 } 13567 13568 recordDailyStatsIfNeededLocked(false); 13569 } 13570 describeContents()13571 public int describeContents() { 13572 return 0; 13573 } 13574 readHistory(Parcel in, boolean andOldHistory)13575 void readHistory(Parcel in, boolean andOldHistory) throws ParcelFormatException { 13576 final long historyBaseTime = in.readLong(); 13577 13578 mHistoryBuffer.setDataSize(0); 13579 mHistoryBuffer.setDataPosition(0); 13580 mHistoryTagPool.clear(); 13581 mNextHistoryTagIdx = 0; 13582 mNumHistoryTagChars = 0; 13583 13584 int numTags = in.readInt(); 13585 for (int i=0; i<numTags; i++) { 13586 int idx = in.readInt(); 13587 String str = in.readString(); 13588 if (str == null) { 13589 throw new ParcelFormatException("null history tag string"); 13590 } 13591 int uid = in.readInt(); 13592 HistoryTag tag = new HistoryTag(); 13593 tag.string = str; 13594 tag.uid = uid; 13595 tag.poolIdx = idx; 13596 mHistoryTagPool.put(tag, idx); 13597 if (idx >= mNextHistoryTagIdx) { 13598 mNextHistoryTagIdx = idx+1; 13599 } 13600 mNumHistoryTagChars += tag.string.length() + 1; 13601 } 13602 13603 int bufSize = in.readInt(); 13604 int curPos = in.dataPosition(); 13605 if (bufSize >= (MAX_MAX_HISTORY_BUFFER*3)) { 13606 throw new ParcelFormatException("File corrupt: history data buffer too large " + 13607 bufSize); 13608 } else if ((bufSize&~3) != bufSize) { 13609 throw new ParcelFormatException("File corrupt: history data buffer not aligned " + 13610 bufSize); 13611 } else { 13612 if (DEBUG_HISTORY) Slog.i(TAG, "***************** READING NEW HISTORY: " + bufSize 13613 + " bytes at " + curPos); 13614 mHistoryBuffer.appendFrom(in, curPos, bufSize); 13615 in.setDataPosition(curPos + bufSize); 13616 } 13617 13618 if (andOldHistory) { 13619 readOldHistory(in); 13620 } 13621 13622 if (DEBUG_HISTORY) { 13623 StringBuilder sb = new StringBuilder(128); 13624 sb.append("****************** OLD mHistoryBaseTime: "); 13625 TimeUtils.formatDuration(mHistoryBaseTime, sb); 13626 Slog.i(TAG, sb.toString()); 13627 } 13628 mHistoryBaseTime = historyBaseTime; 13629 if (DEBUG_HISTORY) { 13630 StringBuilder sb = new StringBuilder(128); 13631 sb.append("****************** NEW mHistoryBaseTime: "); 13632 TimeUtils.formatDuration(mHistoryBaseTime, sb); 13633 Slog.i(TAG, sb.toString()); 13634 } 13635 13636 // We are just arbitrarily going to insert 1 minute from the sample of 13637 // the last run until samples in this run. 13638 if (mHistoryBaseTime > 0) { 13639 long oldnow = mClocks.elapsedRealtime(); 13640 mHistoryBaseTime = mHistoryBaseTime - oldnow + 1; 13641 if (DEBUG_HISTORY) { 13642 StringBuilder sb = new StringBuilder(128); 13643 sb.append("****************** ADJUSTED mHistoryBaseTime: "); 13644 TimeUtils.formatDuration(mHistoryBaseTime, sb); 13645 Slog.i(TAG, sb.toString()); 13646 } 13647 } 13648 } 13649 readOldHistory(Parcel in)13650 void readOldHistory(Parcel in) { 13651 if (!USE_OLD_HISTORY) { 13652 return; 13653 } 13654 mHistory = mHistoryEnd = mHistoryCache = null; 13655 long time; 13656 while (in.dataAvail() > 0 && (time=in.readLong()) >= 0) { 13657 HistoryItem rec = new HistoryItem(time, in); 13658 addHistoryRecordLocked(rec); 13659 } 13660 } 13661 writeHistory(Parcel out, boolean inclData, boolean andOldHistory)13662 void writeHistory(Parcel out, boolean inclData, boolean andOldHistory) { 13663 if (DEBUG_HISTORY) { 13664 StringBuilder sb = new StringBuilder(128); 13665 sb.append("****************** WRITING mHistoryBaseTime: "); 13666 TimeUtils.formatDuration(mHistoryBaseTime, sb); 13667 sb.append(" mLastHistoryElapsedRealtime: "); 13668 TimeUtils.formatDuration(mLastHistoryElapsedRealtime, sb); 13669 Slog.i(TAG, sb.toString()); 13670 } 13671 out.writeLong(mHistoryBaseTime + mLastHistoryElapsedRealtime); 13672 if (!inclData) { 13673 out.writeInt(0); 13674 out.writeInt(0); 13675 return; 13676 } 13677 out.writeInt(mHistoryTagPool.size()); 13678 for (HashMap.Entry<HistoryTag, Integer> ent : mHistoryTagPool.entrySet()) { 13679 HistoryTag tag = ent.getKey(); 13680 out.writeInt(ent.getValue()); 13681 out.writeString(tag.string); 13682 out.writeInt(tag.uid); 13683 } 13684 out.writeInt(mHistoryBuffer.dataSize()); 13685 if (DEBUG_HISTORY) Slog.i(TAG, "***************** WRITING HISTORY: " 13686 + mHistoryBuffer.dataSize() + " bytes at " + out.dataPosition()); 13687 out.appendFrom(mHistoryBuffer, 0, mHistoryBuffer.dataSize()); 13688 13689 if (andOldHistory) { 13690 writeOldHistory(out); 13691 } 13692 } 13693 writeOldHistory(Parcel out)13694 void writeOldHistory(Parcel out) { 13695 if (!USE_OLD_HISTORY) { 13696 return; 13697 } 13698 HistoryItem rec = mHistory; 13699 while (rec != null) { 13700 if (rec.time >= 0) rec.writeToParcel(out, 0); 13701 rec = rec.next; 13702 } 13703 out.writeLong(-1); 13704 } 13705 readSummaryFromParcel(Parcel in)13706 public void readSummaryFromParcel(Parcel in) throws ParcelFormatException { 13707 final int version = in.readInt(); 13708 if (version != VERSION) { 13709 Slog.w("BatteryStats", "readFromParcel: version got " + version 13710 + ", expected " + VERSION + "; erasing old stats"); 13711 return; 13712 } 13713 13714 readHistory(in, true); 13715 13716 mStartCount = in.readInt(); 13717 mUptime = in.readLong(); 13718 mRealtime = in.readLong(); 13719 mStartClockTime = in.readLong(); 13720 mStartPlatformVersion = in.readString(); 13721 mEndPlatformVersion = in.readString(); 13722 mOnBatteryTimeBase.readSummaryFromParcel(in); 13723 mOnBatteryScreenOffTimeBase.readSummaryFromParcel(in); 13724 mDischargeUnplugLevel = in.readInt(); 13725 mDischargePlugLevel = in.readInt(); 13726 mDischargeCurrentLevel = in.readInt(); 13727 mCurrentBatteryLevel = in.readInt(); 13728 mEstimatedBatteryCapacity = in.readInt(); 13729 mMinLearnedBatteryCapacity = in.readInt(); 13730 mMaxLearnedBatteryCapacity = in.readInt(); 13731 mLowDischargeAmountSinceCharge = in.readInt(); 13732 mHighDischargeAmountSinceCharge = in.readInt(); 13733 mDischargeAmountScreenOnSinceCharge = in.readInt(); 13734 mDischargeAmountScreenOffSinceCharge = in.readInt(); 13735 mDischargeAmountScreenDozeSinceCharge = in.readInt(); 13736 mDischargeStepTracker.readFromParcel(in); 13737 mChargeStepTracker.readFromParcel(in); 13738 mDailyDischargeStepTracker.readFromParcel(in); 13739 mDailyChargeStepTracker.readFromParcel(in); 13740 mDischargeCounter.readSummaryFromParcelLocked(in); 13741 mDischargeScreenOffCounter.readSummaryFromParcelLocked(in); 13742 mDischargeScreenDozeCounter.readSummaryFromParcelLocked(in); 13743 mDischargeLightDozeCounter.readSummaryFromParcelLocked(in); 13744 mDischargeDeepDozeCounter.readSummaryFromParcelLocked(in); 13745 int NPKG = in.readInt(); 13746 if (NPKG > 0) { 13747 mDailyPackageChanges = new ArrayList<>(NPKG); 13748 while (NPKG > 0) { 13749 NPKG--; 13750 PackageChange pc = new PackageChange(); 13751 pc.mPackageName = in.readString(); 13752 pc.mUpdate = in.readInt() != 0; 13753 pc.mVersionCode = in.readLong(); 13754 mDailyPackageChanges.add(pc); 13755 } 13756 } else { 13757 mDailyPackageChanges = null; 13758 } 13759 mDailyStartTime = in.readLong(); 13760 mNextMinDailyDeadline = in.readLong(); 13761 mNextMaxDailyDeadline = in.readLong(); 13762 13763 mStartCount++; 13764 13765 mScreenState = Display.STATE_UNKNOWN; 13766 mScreenOnTimer.readSummaryFromParcelLocked(in); 13767 mScreenDozeTimer.readSummaryFromParcelLocked(in); 13768 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 13769 mScreenBrightnessTimer[i].readSummaryFromParcelLocked(in); 13770 } 13771 mInteractive = false; 13772 mInteractiveTimer.readSummaryFromParcelLocked(in); 13773 mPhoneOn = false; 13774 mPowerSaveModeEnabledTimer.readSummaryFromParcelLocked(in); 13775 mLongestLightIdleTime = in.readLong(); 13776 mLongestFullIdleTime = in.readLong(); 13777 mDeviceIdleModeLightTimer.readSummaryFromParcelLocked(in); 13778 mDeviceIdleModeFullTimer.readSummaryFromParcelLocked(in); 13779 mDeviceLightIdlingTimer.readSummaryFromParcelLocked(in); 13780 mDeviceIdlingTimer.readSummaryFromParcelLocked(in); 13781 mPhoneOnTimer.readSummaryFromParcelLocked(in); 13782 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) { 13783 mPhoneSignalStrengthsTimer[i].readSummaryFromParcelLocked(in); 13784 } 13785 mPhoneSignalScanningTimer.readSummaryFromParcelLocked(in); 13786 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 13787 mPhoneDataConnectionsTimer[i].readSummaryFromParcelLocked(in); 13788 } 13789 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 13790 mNetworkByteActivityCounters[i].readSummaryFromParcelLocked(in); 13791 mNetworkPacketActivityCounters[i].readSummaryFromParcelLocked(in); 13792 } 13793 mMobileRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW; 13794 mMobileRadioActiveTimer.readSummaryFromParcelLocked(in); 13795 mMobileRadioActivePerAppTimer.readSummaryFromParcelLocked(in); 13796 mMobileRadioActiveAdjustedTime.readSummaryFromParcelLocked(in); 13797 mMobileRadioActiveUnknownTime.readSummaryFromParcelLocked(in); 13798 mMobileRadioActiveUnknownCount.readSummaryFromParcelLocked(in); 13799 mWifiMulticastWakelockTimer.readSummaryFromParcelLocked(in); 13800 mWifiRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW; 13801 mWifiOn = false; 13802 mWifiOnTimer.readSummaryFromParcelLocked(in); 13803 mGlobalWifiRunning = false; 13804 mGlobalWifiRunningTimer.readSummaryFromParcelLocked(in); 13805 for (int i=0; i<NUM_WIFI_STATES; i++) { 13806 mWifiStateTimer[i].readSummaryFromParcelLocked(in); 13807 } 13808 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) { 13809 mWifiSupplStateTimer[i].readSummaryFromParcelLocked(in); 13810 } 13811 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { 13812 mWifiSignalStrengthsTimer[i].readSummaryFromParcelLocked(in); 13813 } 13814 mWifiActiveTimer.readSummaryFromParcelLocked(in); 13815 mWifiActivity.readSummaryFromParcel(in); 13816 for (int i=0; i<GnssMetrics.NUM_GPS_SIGNAL_QUALITY_LEVELS; i++) { 13817 mGpsSignalQualityTimer[i].readSummaryFromParcelLocked(in); 13818 } 13819 mBluetoothActivity.readSummaryFromParcel(in); 13820 mModemActivity.readSummaryFromParcel(in); 13821 mHasWifiReporting = in.readInt() != 0; 13822 mHasBluetoothReporting = in.readInt() != 0; 13823 mHasModemReporting = in.readInt() != 0; 13824 13825 mNumConnectivityChange = mLoadedNumConnectivityChange = in.readInt(); 13826 mFlashlightOnNesting = 0; 13827 mFlashlightOnTimer.readSummaryFromParcelLocked(in); 13828 mCameraOnNesting = 0; 13829 mCameraOnTimer.readSummaryFromParcelLocked(in); 13830 mBluetoothScanNesting = 0; 13831 mBluetoothScanTimer.readSummaryFromParcelLocked(in); 13832 mIsCellularTxPowerHigh = false; 13833 13834 int NRPMS = in.readInt(); 13835 if (NRPMS > 10000) { 13836 throw new ParcelFormatException("File corrupt: too many rpm stats " + NRPMS); 13837 } 13838 for (int irpm = 0; irpm < NRPMS; irpm++) { 13839 if (in.readInt() != 0) { 13840 String rpmName = in.readString(); 13841 getRpmTimerLocked(rpmName).readSummaryFromParcelLocked(in); 13842 } 13843 } 13844 int NSORPMS = in.readInt(); 13845 if (NSORPMS > 10000) { 13846 throw new ParcelFormatException("File corrupt: too many screen-off rpm stats " + NSORPMS); 13847 } 13848 for (int irpm = 0; irpm < NSORPMS; irpm++) { 13849 if (in.readInt() != 0) { 13850 String rpmName = in.readString(); 13851 getScreenOffRpmTimerLocked(rpmName).readSummaryFromParcelLocked(in); 13852 } 13853 } 13854 13855 int NKW = in.readInt(); 13856 if (NKW > 10000) { 13857 throw new ParcelFormatException("File corrupt: too many kernel wake locks " + NKW); 13858 } 13859 for (int ikw = 0; ikw < NKW; ikw++) { 13860 if (in.readInt() != 0) { 13861 String kwltName = in.readString(); 13862 getKernelWakelockTimerLocked(kwltName).readSummaryFromParcelLocked(in); 13863 } 13864 } 13865 13866 int NWR = in.readInt(); 13867 if (NWR > 10000) { 13868 throw new ParcelFormatException("File corrupt: too many wakeup reasons " + NWR); 13869 } 13870 for (int iwr = 0; iwr < NWR; iwr++) { 13871 if (in.readInt() != 0) { 13872 String reasonName = in.readString(); 13873 getWakeupReasonTimerLocked(reasonName).readSummaryFromParcelLocked(in); 13874 } 13875 } 13876 13877 int NMS = in.readInt(); 13878 for (int ims = 0; ims < NMS; ims++) { 13879 if (in.readInt() != 0) { 13880 long kmstName = in.readLong(); 13881 getKernelMemoryTimerLocked(kmstName).readSummaryFromParcelLocked(in); 13882 } 13883 } 13884 13885 final int NU = in.readInt(); 13886 if (NU > 10000) { 13887 throw new ParcelFormatException("File corrupt: too many uids " + NU); 13888 } 13889 for (int iu = 0; iu < NU; iu++) { 13890 int uid = in.readInt(); 13891 Uid u = new Uid(this, uid); 13892 mUidStats.put(uid, u); 13893 13894 u.mOnBatteryBackgroundTimeBase.readSummaryFromParcel(in); 13895 u.mOnBatteryScreenOffBackgroundTimeBase.readSummaryFromParcel(in); 13896 13897 u.mWifiRunning = false; 13898 if (in.readInt() != 0) { 13899 u.mWifiRunningTimer.readSummaryFromParcelLocked(in); 13900 } 13901 u.mFullWifiLockOut = false; 13902 if (in.readInt() != 0) { 13903 u.mFullWifiLockTimer.readSummaryFromParcelLocked(in); 13904 } 13905 u.mWifiScanStarted = false; 13906 if (in.readInt() != 0) { 13907 u.mWifiScanTimer.readSummaryFromParcelLocked(in); 13908 } 13909 u.mWifiBatchedScanBinStarted = Uid.NO_BATCHED_SCAN_STARTED; 13910 for (int i = 0; i < Uid.NUM_WIFI_BATCHED_SCAN_BINS; i++) { 13911 if (in.readInt() != 0) { 13912 u.makeWifiBatchedScanBin(i, null); 13913 u.mWifiBatchedScanTimer[i].readSummaryFromParcelLocked(in); 13914 } 13915 } 13916 u.mWifiMulticastEnabled = false; 13917 if (in.readInt() != 0) { 13918 u.mWifiMulticastTimer.readSummaryFromParcelLocked(in); 13919 } 13920 if (in.readInt() != 0) { 13921 u.createAudioTurnedOnTimerLocked().readSummaryFromParcelLocked(in); 13922 } 13923 if (in.readInt() != 0) { 13924 u.createVideoTurnedOnTimerLocked().readSummaryFromParcelLocked(in); 13925 } 13926 if (in.readInt() != 0) { 13927 u.createFlashlightTurnedOnTimerLocked().readSummaryFromParcelLocked(in); 13928 } 13929 if (in.readInt() != 0) { 13930 u.createCameraTurnedOnTimerLocked().readSummaryFromParcelLocked(in); 13931 } 13932 if (in.readInt() != 0) { 13933 u.createForegroundActivityTimerLocked().readSummaryFromParcelLocked(in); 13934 } 13935 if (in.readInt() != 0) { 13936 u.createForegroundServiceTimerLocked().readSummaryFromParcelLocked(in); 13937 } 13938 if (in.readInt() != 0) { 13939 u.createAggregatedPartialWakelockTimerLocked().readSummaryFromParcelLocked(in); 13940 } 13941 if (in.readInt() != 0) { 13942 u.createBluetoothScanTimerLocked().readSummaryFromParcelLocked(in); 13943 } 13944 if (in.readInt() != 0) { 13945 u.createBluetoothUnoptimizedScanTimerLocked().readSummaryFromParcelLocked(in); 13946 } 13947 if (in.readInt() != 0) { 13948 u.createBluetoothScanResultCounterLocked().readSummaryFromParcelLocked(in); 13949 } 13950 if (in.readInt() != 0) { 13951 u.createBluetoothScanResultBgCounterLocked().readSummaryFromParcelLocked(in); 13952 } 13953 u.mProcessState = ActivityManager.PROCESS_STATE_NONEXISTENT; 13954 for (int i = 0; i < Uid.NUM_PROCESS_STATE; i++) { 13955 if (in.readInt() != 0) { 13956 u.makeProcessState(i, null); 13957 u.mProcessStateTimer[i].readSummaryFromParcelLocked(in); 13958 } 13959 } 13960 if (in.readInt() != 0) { 13961 u.createVibratorOnTimerLocked().readSummaryFromParcelLocked(in); 13962 } 13963 13964 if (in.readInt() != 0) { 13965 if (u.mUserActivityCounters == null) { 13966 u.initUserActivityLocked(); 13967 } 13968 for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) { 13969 u.mUserActivityCounters[i].readSummaryFromParcelLocked(in); 13970 } 13971 } 13972 13973 if (in.readInt() != 0) { 13974 if (u.mNetworkByteActivityCounters == null) { 13975 u.initNetworkActivityLocked(); 13976 } 13977 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 13978 u.mNetworkByteActivityCounters[i].readSummaryFromParcelLocked(in); 13979 u.mNetworkPacketActivityCounters[i].readSummaryFromParcelLocked(in); 13980 } 13981 u.mMobileRadioActiveTime.readSummaryFromParcelLocked(in); 13982 u.mMobileRadioActiveCount.readSummaryFromParcelLocked(in); 13983 } 13984 13985 u.mUserCpuTime.readSummaryFromParcelLocked(in); 13986 u.mSystemCpuTime.readSummaryFromParcelLocked(in); 13987 13988 if (in.readInt() != 0) { 13989 final int numClusters = in.readInt(); 13990 if (mPowerProfile != null && mPowerProfile.getNumCpuClusters() != numClusters) { 13991 throw new ParcelFormatException("Incompatible cpu cluster arrangement"); 13992 } 13993 13994 u.mCpuClusterSpeedTimesUs = new LongSamplingCounter[numClusters][]; 13995 for (int cluster = 0; cluster < numClusters; cluster++) { 13996 if (in.readInt() != 0) { 13997 final int NSB = in.readInt(); 13998 if (mPowerProfile != null && 13999 mPowerProfile.getNumSpeedStepsInCpuCluster(cluster) != NSB) { 14000 throw new ParcelFormatException("File corrupt: too many speed bins " + 14001 NSB); 14002 } 14003 14004 u.mCpuClusterSpeedTimesUs[cluster] = new LongSamplingCounter[NSB]; 14005 for (int speed = 0; speed < NSB; speed++) { 14006 if (in.readInt() != 0) { 14007 u.mCpuClusterSpeedTimesUs[cluster][speed] = new LongSamplingCounter( 14008 mOnBatteryTimeBase); 14009 u.mCpuClusterSpeedTimesUs[cluster][speed].readSummaryFromParcelLocked(in); 14010 } 14011 } 14012 } else { 14013 u.mCpuClusterSpeedTimesUs[cluster] = null; 14014 } 14015 } 14016 } else { 14017 u.mCpuClusterSpeedTimesUs = null; 14018 } 14019 14020 u.mCpuFreqTimeMs = LongSamplingCounterArray.readSummaryFromParcelLocked( 14021 in, mOnBatteryTimeBase); 14022 u.mScreenOffCpuFreqTimeMs = LongSamplingCounterArray.readSummaryFromParcelLocked( 14023 in, mOnBatteryScreenOffTimeBase); 14024 14025 u.mCpuActiveTimeMs.readSummaryFromParcelLocked(in); 14026 u.mCpuClusterTimesMs.readSummaryFromParcelLocked(in); 14027 14028 int length = in.readInt(); 14029 if (length == Uid.NUM_PROCESS_STATE) { 14030 u.mProcStateTimeMs = new LongSamplingCounterArray[length]; 14031 for (int procState = 0; procState < length; ++procState) { 14032 u.mProcStateTimeMs[procState] 14033 = LongSamplingCounterArray.readSummaryFromParcelLocked( 14034 in, mOnBatteryTimeBase); 14035 } 14036 } else { 14037 u.mProcStateTimeMs = null; 14038 } 14039 length = in.readInt(); 14040 if (length == Uid.NUM_PROCESS_STATE) { 14041 u.mProcStateScreenOffTimeMs = new LongSamplingCounterArray[length]; 14042 for (int procState = 0; procState < length; ++procState) { 14043 u.mProcStateScreenOffTimeMs[procState] 14044 = LongSamplingCounterArray.readSummaryFromParcelLocked( 14045 in, mOnBatteryScreenOffTimeBase); 14046 } 14047 } else { 14048 u.mProcStateScreenOffTimeMs = null; 14049 } 14050 14051 if (in.readInt() != 0) { 14052 u.mMobileRadioApWakeupCount = new LongSamplingCounter(mOnBatteryTimeBase); 14053 u.mMobileRadioApWakeupCount.readSummaryFromParcelLocked(in); 14054 } else { 14055 u.mMobileRadioApWakeupCount = null; 14056 } 14057 14058 if (in.readInt() != 0) { 14059 u.mWifiRadioApWakeupCount = new LongSamplingCounter(mOnBatteryTimeBase); 14060 u.mWifiRadioApWakeupCount.readSummaryFromParcelLocked(in); 14061 } else { 14062 u.mWifiRadioApWakeupCount = null; 14063 } 14064 14065 int NW = in.readInt(); 14066 if (NW > (MAX_WAKELOCKS_PER_UID+1)) { 14067 throw new ParcelFormatException("File corrupt: too many wake locks " + NW); 14068 } 14069 for (int iw = 0; iw < NW; iw++) { 14070 String wlName = in.readString(); 14071 u.readWakeSummaryFromParcelLocked(wlName, in); 14072 } 14073 14074 int NS = in.readInt(); 14075 if (NS > (MAX_WAKELOCKS_PER_UID+1)) { 14076 throw new ParcelFormatException("File corrupt: too many syncs " + NS); 14077 } 14078 for (int is = 0; is < NS; is++) { 14079 String name = in.readString(); 14080 u.readSyncSummaryFromParcelLocked(name, in); 14081 } 14082 14083 int NJ = in.readInt(); 14084 if (NJ > (MAX_WAKELOCKS_PER_UID+1)) { 14085 throw new ParcelFormatException("File corrupt: too many job timers " + NJ); 14086 } 14087 for (int ij = 0; ij < NJ; ij++) { 14088 String name = in.readString(); 14089 u.readJobSummaryFromParcelLocked(name, in); 14090 } 14091 14092 u.readJobCompletionsFromParcelLocked(in); 14093 14094 u.mJobsDeferredEventCount.readSummaryFromParcelLocked(in); 14095 u.mJobsDeferredCount.readSummaryFromParcelLocked(in); 14096 u.mJobsFreshnessTimeMs.readSummaryFromParcelLocked(in); 14097 for (int i = 0; i < JOB_FRESHNESS_BUCKETS.length; i++) { 14098 if (in.readInt() != 0) { 14099 u.mJobsFreshnessBuckets[i] = new Counter(u.mBsi.mOnBatteryTimeBase); 14100 u.mJobsFreshnessBuckets[i].readSummaryFromParcelLocked(in); 14101 } 14102 } 14103 14104 int NP = in.readInt(); 14105 if (NP > 1000) { 14106 throw new ParcelFormatException("File corrupt: too many sensors " + NP); 14107 } 14108 for (int is = 0; is < NP; is++) { 14109 int seNumber = in.readInt(); 14110 if (in.readInt() != 0) { 14111 u.getSensorTimerLocked(seNumber, true).readSummaryFromParcelLocked(in); 14112 } 14113 } 14114 14115 NP = in.readInt(); 14116 if (NP > 1000) { 14117 throw new ParcelFormatException("File corrupt: too many processes " + NP); 14118 } 14119 for (int ip = 0; ip < NP; ip++) { 14120 String procName = in.readString(); 14121 Uid.Proc p = u.getProcessStatsLocked(procName); 14122 p.mUserTime = p.mLoadedUserTime = in.readLong(); 14123 p.mSystemTime = p.mLoadedSystemTime = in.readLong(); 14124 p.mForegroundTime = p.mLoadedForegroundTime = in.readLong(); 14125 p.mStarts = p.mLoadedStarts = in.readInt(); 14126 p.mNumCrashes = p.mLoadedNumCrashes = in.readInt(); 14127 p.mNumAnrs = p.mLoadedNumAnrs = in.readInt(); 14128 p.readExcessivePowerFromParcelLocked(in); 14129 } 14130 14131 NP = in.readInt(); 14132 if (NP > 10000) { 14133 throw new ParcelFormatException("File corrupt: too many packages " + NP); 14134 } 14135 for (int ip = 0; ip < NP; ip++) { 14136 String pkgName = in.readString(); 14137 Uid.Pkg p = u.getPackageStatsLocked(pkgName); 14138 final int NWA = in.readInt(); 14139 if (NWA > 1000) { 14140 throw new ParcelFormatException("File corrupt: too many wakeup alarms " + NWA); 14141 } 14142 p.mWakeupAlarms.clear(); 14143 for (int iwa=0; iwa<NWA; iwa++) { 14144 String tag = in.readString(); 14145 Counter c = new Counter(mOnBatteryScreenOffTimeBase); 14146 c.readSummaryFromParcelLocked(in); 14147 p.mWakeupAlarms.put(tag, c); 14148 } 14149 NS = in.readInt(); 14150 if (NS > 1000) { 14151 throw new ParcelFormatException("File corrupt: too many services " + NS); 14152 } 14153 for (int is = 0; is < NS; is++) { 14154 String servName = in.readString(); 14155 Uid.Pkg.Serv s = u.getServiceStatsLocked(pkgName, servName); 14156 s.mStartTime = s.mLoadedStartTime = in.readLong(); 14157 s.mStarts = s.mLoadedStarts = in.readInt(); 14158 s.mLaunches = s.mLoadedLaunches = in.readInt(); 14159 } 14160 } 14161 } 14162 } 14163 14164 /** 14165 * Writes a summary of the statistics to a Parcel, in a format suitable to be written to 14166 * disk. This format does not allow a lossless round-trip. 14167 * 14168 * @param out the Parcel to be written to. 14169 */ writeSummaryToParcel(Parcel out, boolean inclHistory)14170 public void writeSummaryToParcel(Parcel out, boolean inclHistory) { 14171 pullPendingStateUpdatesLocked(); 14172 14173 // Pull the clock time. This may update the time and make a new history entry 14174 // if we had originally pulled a time before the RTC was set. 14175 long startClockTime = getStartClockTime(); 14176 14177 final long NOW_SYS = mClocks.uptimeMillis() * 1000; 14178 final long NOWREAL_SYS = mClocks.elapsedRealtime() * 1000; 14179 14180 out.writeInt(VERSION); 14181 14182 writeHistory(out, inclHistory, true); 14183 14184 out.writeInt(mStartCount); 14185 out.writeLong(computeUptime(NOW_SYS, STATS_SINCE_CHARGED)); 14186 out.writeLong(computeRealtime(NOWREAL_SYS, STATS_SINCE_CHARGED)); 14187 out.writeLong(startClockTime); 14188 out.writeString(mStartPlatformVersion); 14189 out.writeString(mEndPlatformVersion); 14190 mOnBatteryTimeBase.writeSummaryToParcel(out, NOW_SYS, NOWREAL_SYS); 14191 mOnBatteryScreenOffTimeBase.writeSummaryToParcel(out, NOW_SYS, NOWREAL_SYS); 14192 out.writeInt(mDischargeUnplugLevel); 14193 out.writeInt(mDischargePlugLevel); 14194 out.writeInt(mDischargeCurrentLevel); 14195 out.writeInt(mCurrentBatteryLevel); 14196 out.writeInt(mEstimatedBatteryCapacity); 14197 out.writeInt(mMinLearnedBatteryCapacity); 14198 out.writeInt(mMaxLearnedBatteryCapacity); 14199 out.writeInt(getLowDischargeAmountSinceCharge()); 14200 out.writeInt(getHighDischargeAmountSinceCharge()); 14201 out.writeInt(getDischargeAmountScreenOnSinceCharge()); 14202 out.writeInt(getDischargeAmountScreenOffSinceCharge()); 14203 out.writeInt(getDischargeAmountScreenDozeSinceCharge()); 14204 mDischargeStepTracker.writeToParcel(out); 14205 mChargeStepTracker.writeToParcel(out); 14206 mDailyDischargeStepTracker.writeToParcel(out); 14207 mDailyChargeStepTracker.writeToParcel(out); 14208 mDischargeCounter.writeSummaryFromParcelLocked(out); 14209 mDischargeScreenOffCounter.writeSummaryFromParcelLocked(out); 14210 mDischargeScreenDozeCounter.writeSummaryFromParcelLocked(out); 14211 mDischargeLightDozeCounter.writeSummaryFromParcelLocked(out); 14212 mDischargeDeepDozeCounter.writeSummaryFromParcelLocked(out); 14213 if (mDailyPackageChanges != null) { 14214 final int NPKG = mDailyPackageChanges.size(); 14215 out.writeInt(NPKG); 14216 for (int i=0; i<NPKG; i++) { 14217 PackageChange pc = mDailyPackageChanges.get(i); 14218 out.writeString(pc.mPackageName); 14219 out.writeInt(pc.mUpdate ? 1 : 0); 14220 out.writeLong(pc.mVersionCode); 14221 } 14222 } else { 14223 out.writeInt(0); 14224 } 14225 out.writeLong(mDailyStartTime); 14226 out.writeLong(mNextMinDailyDeadline); 14227 out.writeLong(mNextMaxDailyDeadline); 14228 14229 mScreenOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14230 mScreenDozeTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14231 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 14232 mScreenBrightnessTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14233 } 14234 mInteractiveTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14235 mPowerSaveModeEnabledTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14236 out.writeLong(mLongestLightIdleTime); 14237 out.writeLong(mLongestFullIdleTime); 14238 mDeviceIdleModeLightTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14239 mDeviceIdleModeFullTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14240 mDeviceLightIdlingTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14241 mDeviceIdlingTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14242 mPhoneOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14243 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) { 14244 mPhoneSignalStrengthsTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14245 } 14246 mPhoneSignalScanningTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14247 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 14248 mPhoneDataConnectionsTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14249 } 14250 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 14251 mNetworkByteActivityCounters[i].writeSummaryFromParcelLocked(out); 14252 mNetworkPacketActivityCounters[i].writeSummaryFromParcelLocked(out); 14253 } 14254 mMobileRadioActiveTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14255 mMobileRadioActivePerAppTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14256 mMobileRadioActiveAdjustedTime.writeSummaryFromParcelLocked(out); 14257 mMobileRadioActiveUnknownTime.writeSummaryFromParcelLocked(out); 14258 mMobileRadioActiveUnknownCount.writeSummaryFromParcelLocked(out); 14259 mWifiMulticastWakelockTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14260 mWifiOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14261 mGlobalWifiRunningTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14262 for (int i=0; i<NUM_WIFI_STATES; i++) { 14263 mWifiStateTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14264 } 14265 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) { 14266 mWifiSupplStateTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14267 } 14268 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { 14269 mWifiSignalStrengthsTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14270 } 14271 mWifiActiveTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14272 mWifiActivity.writeSummaryToParcel(out); 14273 for (int i=0; i< GnssMetrics.NUM_GPS_SIGNAL_QUALITY_LEVELS; i++) { 14274 mGpsSignalQualityTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14275 } 14276 mBluetoothActivity.writeSummaryToParcel(out); 14277 mModemActivity.writeSummaryToParcel(out); 14278 out.writeInt(mHasWifiReporting ? 1 : 0); 14279 out.writeInt(mHasBluetoothReporting ? 1 : 0); 14280 out.writeInt(mHasModemReporting ? 1 : 0); 14281 14282 out.writeInt(mNumConnectivityChange); 14283 mFlashlightOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14284 mCameraOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14285 mBluetoothScanTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14286 14287 out.writeInt(mRpmStats.size()); 14288 for (Map.Entry<String, SamplingTimer> ent : mRpmStats.entrySet()) { 14289 Timer rpmt = ent.getValue(); 14290 if (rpmt != null) { 14291 out.writeInt(1); 14292 out.writeString(ent.getKey()); 14293 rpmt.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14294 } else { 14295 out.writeInt(0); 14296 } 14297 } 14298 out.writeInt(mScreenOffRpmStats.size()); 14299 for (Map.Entry<String, SamplingTimer> ent : mScreenOffRpmStats.entrySet()) { 14300 Timer rpmt = ent.getValue(); 14301 if (rpmt != null) { 14302 out.writeInt(1); 14303 out.writeString(ent.getKey()); 14304 rpmt.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14305 } else { 14306 out.writeInt(0); 14307 } 14308 } 14309 14310 out.writeInt(mKernelWakelockStats.size()); 14311 for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) { 14312 Timer kwlt = ent.getValue(); 14313 if (kwlt != null) { 14314 out.writeInt(1); 14315 out.writeString(ent.getKey()); 14316 kwlt.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14317 } else { 14318 out.writeInt(0); 14319 } 14320 } 14321 14322 out.writeInt(mWakeupReasonStats.size()); 14323 for (Map.Entry<String, SamplingTimer> ent : mWakeupReasonStats.entrySet()) { 14324 SamplingTimer timer = ent.getValue(); 14325 if (timer != null) { 14326 out.writeInt(1); 14327 out.writeString(ent.getKey()); 14328 timer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14329 } else { 14330 out.writeInt(0); 14331 } 14332 } 14333 14334 out.writeInt(mKernelMemoryStats.size()); 14335 for (int i = 0; i < mKernelMemoryStats.size(); i++) { 14336 Timer kmt = mKernelMemoryStats.valueAt(i); 14337 if (kmt != null) { 14338 out.writeInt(1); 14339 out.writeLong(mKernelMemoryStats.keyAt(i)); 14340 kmt.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14341 } else { 14342 out.writeInt(0); 14343 } 14344 } 14345 14346 final int NU = mUidStats.size(); 14347 out.writeInt(NU); 14348 for (int iu = 0; iu < NU; iu++) { 14349 out.writeInt(mUidStats.keyAt(iu)); 14350 Uid u = mUidStats.valueAt(iu); 14351 14352 u.mOnBatteryBackgroundTimeBase.writeSummaryToParcel(out, NOW_SYS, NOWREAL_SYS); 14353 u.mOnBatteryScreenOffBackgroundTimeBase.writeSummaryToParcel(out, NOW_SYS, NOWREAL_SYS); 14354 14355 if (u.mWifiRunningTimer != null) { 14356 out.writeInt(1); 14357 u.mWifiRunningTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14358 } else { 14359 out.writeInt(0); 14360 } 14361 if (u.mFullWifiLockTimer != null) { 14362 out.writeInt(1); 14363 u.mFullWifiLockTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14364 } else { 14365 out.writeInt(0); 14366 } 14367 if (u.mWifiScanTimer != null) { 14368 out.writeInt(1); 14369 u.mWifiScanTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14370 } else { 14371 out.writeInt(0); 14372 } 14373 for (int i = 0; i < Uid.NUM_WIFI_BATCHED_SCAN_BINS; i++) { 14374 if (u.mWifiBatchedScanTimer[i] != null) { 14375 out.writeInt(1); 14376 u.mWifiBatchedScanTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14377 } else { 14378 out.writeInt(0); 14379 } 14380 } 14381 if (u.mWifiMulticastTimer != null) { 14382 out.writeInt(1); 14383 u.mWifiMulticastTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14384 } else { 14385 out.writeInt(0); 14386 } 14387 if (u.mAudioTurnedOnTimer != null) { 14388 out.writeInt(1); 14389 u.mAudioTurnedOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14390 } else { 14391 out.writeInt(0); 14392 } 14393 if (u.mVideoTurnedOnTimer != null) { 14394 out.writeInt(1); 14395 u.mVideoTurnedOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14396 } else { 14397 out.writeInt(0); 14398 } 14399 if (u.mFlashlightTurnedOnTimer != null) { 14400 out.writeInt(1); 14401 u.mFlashlightTurnedOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14402 } else { 14403 out.writeInt(0); 14404 } 14405 if (u.mCameraTurnedOnTimer != null) { 14406 out.writeInt(1); 14407 u.mCameraTurnedOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14408 } else { 14409 out.writeInt(0); 14410 } 14411 if (u.mForegroundActivityTimer != null) { 14412 out.writeInt(1); 14413 u.mForegroundActivityTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14414 } else { 14415 out.writeInt(0); 14416 } 14417 if (u.mForegroundServiceTimer != null) { 14418 out.writeInt(1); 14419 u.mForegroundServiceTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14420 } else { 14421 out.writeInt(0); 14422 } 14423 if (u.mAggregatedPartialWakelockTimer != null) { 14424 out.writeInt(1); 14425 u.mAggregatedPartialWakelockTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14426 } else { 14427 out.writeInt(0); 14428 } 14429 if (u.mBluetoothScanTimer != null) { 14430 out.writeInt(1); 14431 u.mBluetoothScanTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14432 } else { 14433 out.writeInt(0); 14434 } 14435 if (u.mBluetoothUnoptimizedScanTimer != null) { 14436 out.writeInt(1); 14437 u.mBluetoothUnoptimizedScanTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14438 } else { 14439 out.writeInt(0); 14440 } 14441 if (u.mBluetoothScanResultCounter != null) { 14442 out.writeInt(1); 14443 u.mBluetoothScanResultCounter.writeSummaryFromParcelLocked(out); 14444 } else { 14445 out.writeInt(0); 14446 } 14447 if (u.mBluetoothScanResultBgCounter != null) { 14448 out.writeInt(1); 14449 u.mBluetoothScanResultBgCounter.writeSummaryFromParcelLocked(out); 14450 } else { 14451 out.writeInt(0); 14452 } 14453 for (int i = 0; i < Uid.NUM_PROCESS_STATE; i++) { 14454 if (u.mProcessStateTimer[i] != null) { 14455 out.writeInt(1); 14456 u.mProcessStateTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14457 } else { 14458 out.writeInt(0); 14459 } 14460 } 14461 if (u.mVibratorOnTimer != null) { 14462 out.writeInt(1); 14463 u.mVibratorOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14464 } else { 14465 out.writeInt(0); 14466 } 14467 14468 if (u.mUserActivityCounters == null) { 14469 out.writeInt(0); 14470 } else { 14471 out.writeInt(1); 14472 for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) { 14473 u.mUserActivityCounters[i].writeSummaryFromParcelLocked(out); 14474 } 14475 } 14476 14477 if (u.mNetworkByteActivityCounters == null) { 14478 out.writeInt(0); 14479 } else { 14480 out.writeInt(1); 14481 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 14482 u.mNetworkByteActivityCounters[i].writeSummaryFromParcelLocked(out); 14483 u.mNetworkPacketActivityCounters[i].writeSummaryFromParcelLocked(out); 14484 } 14485 u.mMobileRadioActiveTime.writeSummaryFromParcelLocked(out); 14486 u.mMobileRadioActiveCount.writeSummaryFromParcelLocked(out); 14487 } 14488 14489 u.mUserCpuTime.writeSummaryFromParcelLocked(out); 14490 u.mSystemCpuTime.writeSummaryFromParcelLocked(out); 14491 14492 if (u.mCpuClusterSpeedTimesUs != null) { 14493 out.writeInt(1); 14494 out.writeInt(u.mCpuClusterSpeedTimesUs.length); 14495 for (LongSamplingCounter[] cpuSpeeds : u.mCpuClusterSpeedTimesUs) { 14496 if (cpuSpeeds != null) { 14497 out.writeInt(1); 14498 out.writeInt(cpuSpeeds.length); 14499 for (LongSamplingCounter c : cpuSpeeds) { 14500 if (c != null) { 14501 out.writeInt(1); 14502 c.writeSummaryFromParcelLocked(out); 14503 } else { 14504 out.writeInt(0); 14505 } 14506 } 14507 } else { 14508 out.writeInt(0); 14509 } 14510 } 14511 } else { 14512 out.writeInt(0); 14513 } 14514 14515 LongSamplingCounterArray.writeSummaryToParcelLocked(out, u.mCpuFreqTimeMs); 14516 LongSamplingCounterArray.writeSummaryToParcelLocked(out, u.mScreenOffCpuFreqTimeMs); 14517 14518 u.mCpuActiveTimeMs.writeSummaryFromParcelLocked(out); 14519 u.mCpuClusterTimesMs.writeSummaryToParcelLocked(out); 14520 14521 if (u.mProcStateTimeMs != null) { 14522 out.writeInt(u.mProcStateTimeMs.length); 14523 for (LongSamplingCounterArray counters : u.mProcStateTimeMs) { 14524 LongSamplingCounterArray.writeSummaryToParcelLocked(out, counters); 14525 } 14526 } else { 14527 out.writeInt(0); 14528 } 14529 if (u.mProcStateScreenOffTimeMs != null) { 14530 out.writeInt(u.mProcStateScreenOffTimeMs.length); 14531 for (LongSamplingCounterArray counters : u.mProcStateScreenOffTimeMs) { 14532 LongSamplingCounterArray.writeSummaryToParcelLocked(out, counters); 14533 } 14534 } else { 14535 out.writeInt(0); 14536 } 14537 14538 if (u.mMobileRadioApWakeupCount != null) { 14539 out.writeInt(1); 14540 u.mMobileRadioApWakeupCount.writeSummaryFromParcelLocked(out); 14541 } else { 14542 out.writeInt(0); 14543 } 14544 14545 if (u.mWifiRadioApWakeupCount != null) { 14546 out.writeInt(1); 14547 u.mWifiRadioApWakeupCount.writeSummaryFromParcelLocked(out); 14548 } else { 14549 out.writeInt(0); 14550 } 14551 14552 final ArrayMap<String, Uid.Wakelock> wakeStats = u.mWakelockStats.getMap(); 14553 int NW = wakeStats.size(); 14554 out.writeInt(NW); 14555 for (int iw=0; iw<NW; iw++) { 14556 out.writeString(wakeStats.keyAt(iw)); 14557 Uid.Wakelock wl = wakeStats.valueAt(iw); 14558 if (wl.mTimerFull != null) { 14559 out.writeInt(1); 14560 wl.mTimerFull.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14561 } else { 14562 out.writeInt(0); 14563 } 14564 if (wl.mTimerPartial != null) { 14565 out.writeInt(1); 14566 wl.mTimerPartial.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14567 } else { 14568 out.writeInt(0); 14569 } 14570 if (wl.mTimerWindow != null) { 14571 out.writeInt(1); 14572 wl.mTimerWindow.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14573 } else { 14574 out.writeInt(0); 14575 } 14576 if (wl.mTimerDraw != null) { 14577 out.writeInt(1); 14578 wl.mTimerDraw.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14579 } else { 14580 out.writeInt(0); 14581 } 14582 } 14583 14584 final ArrayMap<String, DualTimer> syncStats = u.mSyncStats.getMap(); 14585 int NS = syncStats.size(); 14586 out.writeInt(NS); 14587 for (int is=0; is<NS; is++) { 14588 out.writeString(syncStats.keyAt(is)); 14589 syncStats.valueAt(is).writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14590 } 14591 14592 final ArrayMap<String, DualTimer> jobStats = u.mJobStats.getMap(); 14593 int NJ = jobStats.size(); 14594 out.writeInt(NJ); 14595 for (int ij=0; ij<NJ; ij++) { 14596 out.writeString(jobStats.keyAt(ij)); 14597 jobStats.valueAt(ij).writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14598 } 14599 14600 u.writeJobCompletionsToParcelLocked(out); 14601 14602 u.mJobsDeferredEventCount.writeSummaryFromParcelLocked(out); 14603 u.mJobsDeferredCount.writeSummaryFromParcelLocked(out); 14604 u.mJobsFreshnessTimeMs.writeSummaryFromParcelLocked(out); 14605 for (int i = 0; i < JOB_FRESHNESS_BUCKETS.length; i++) { 14606 if (u.mJobsFreshnessBuckets[i] != null) { 14607 out.writeInt(1); 14608 u.mJobsFreshnessBuckets[i].writeSummaryFromParcelLocked(out); 14609 } else { 14610 out.writeInt(0); 14611 } 14612 } 14613 14614 int NSE = u.mSensorStats.size(); 14615 out.writeInt(NSE); 14616 for (int ise=0; ise<NSE; ise++) { 14617 out.writeInt(u.mSensorStats.keyAt(ise)); 14618 Uid.Sensor se = u.mSensorStats.valueAt(ise); 14619 if (se.mTimer != null) { 14620 out.writeInt(1); 14621 se.mTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 14622 } else { 14623 out.writeInt(0); 14624 } 14625 } 14626 14627 int NP = u.mProcessStats.size(); 14628 out.writeInt(NP); 14629 for (int ip=0; ip<NP; ip++) { 14630 out.writeString(u.mProcessStats.keyAt(ip)); 14631 Uid.Proc ps = u.mProcessStats.valueAt(ip); 14632 out.writeLong(ps.mUserTime); 14633 out.writeLong(ps.mSystemTime); 14634 out.writeLong(ps.mForegroundTime); 14635 out.writeInt(ps.mStarts); 14636 out.writeInt(ps.mNumCrashes); 14637 out.writeInt(ps.mNumAnrs); 14638 ps.writeExcessivePowerToParcelLocked(out); 14639 } 14640 14641 NP = u.mPackageStats.size(); 14642 out.writeInt(NP); 14643 if (NP > 0) { 14644 for (Map.Entry<String, BatteryStatsImpl.Uid.Pkg> ent 14645 : u.mPackageStats.entrySet()) { 14646 out.writeString(ent.getKey()); 14647 Uid.Pkg ps = ent.getValue(); 14648 final int NWA = ps.mWakeupAlarms.size(); 14649 out.writeInt(NWA); 14650 for (int iwa=0; iwa<NWA; iwa++) { 14651 out.writeString(ps.mWakeupAlarms.keyAt(iwa)); 14652 ps.mWakeupAlarms.valueAt(iwa).writeSummaryFromParcelLocked(out); 14653 } 14654 NS = ps.mServiceStats.size(); 14655 out.writeInt(NS); 14656 for (int is=0; is<NS; is++) { 14657 out.writeString(ps.mServiceStats.keyAt(is)); 14658 BatteryStatsImpl.Uid.Pkg.Serv ss = ps.mServiceStats.valueAt(is); 14659 long time = ss.getStartTimeToNowLocked( 14660 mOnBatteryTimeBase.getUptime(NOW_SYS)); 14661 out.writeLong(time); 14662 out.writeInt(ss.mStarts); 14663 out.writeInt(ss.mLaunches); 14664 } 14665 } 14666 } 14667 } 14668 } 14669 readFromParcel(Parcel in)14670 public void readFromParcel(Parcel in) { 14671 readFromParcelLocked(in); 14672 } 14673 readFromParcelLocked(Parcel in)14674 void readFromParcelLocked(Parcel in) { 14675 int magic = in.readInt(); 14676 if (magic != MAGIC) { 14677 throw new ParcelFormatException("Bad magic number: #" + Integer.toHexString(magic)); 14678 } 14679 14680 readHistory(in, false); 14681 14682 mStartCount = in.readInt(); 14683 mStartClockTime = in.readLong(); 14684 mStartPlatformVersion = in.readString(); 14685 mEndPlatformVersion = in.readString(); 14686 mUptime = in.readLong(); 14687 mUptimeStart = in.readLong(); 14688 mRealtime = in.readLong(); 14689 mRealtimeStart = in.readLong(); 14690 mOnBattery = in.readInt() != 0; 14691 mEstimatedBatteryCapacity = in.readInt(); 14692 mMinLearnedBatteryCapacity = in.readInt(); 14693 mMaxLearnedBatteryCapacity = in.readInt(); 14694 mOnBatteryInternal = false; // we are no longer really running. 14695 mOnBatteryTimeBase.readFromParcel(in); 14696 mOnBatteryScreenOffTimeBase.readFromParcel(in); 14697 14698 mScreenState = Display.STATE_UNKNOWN; 14699 mScreenOnTimer = new StopwatchTimer(mClocks, null, -1, null, mOnBatteryTimeBase, in); 14700 mScreenDozeTimer = new StopwatchTimer(mClocks, null, -1, null, mOnBatteryTimeBase, in); 14701 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 14702 mScreenBrightnessTimer[i] = new StopwatchTimer(mClocks, null, -100-i, null, 14703 mOnBatteryTimeBase, in); 14704 } 14705 mInteractive = false; 14706 mInteractiveTimer = new StopwatchTimer(mClocks, null, -10, null, mOnBatteryTimeBase, in); 14707 mPhoneOn = false; 14708 mPowerSaveModeEnabledTimer = new StopwatchTimer(mClocks, null, -2, null, 14709 mOnBatteryTimeBase, in); 14710 mLongestLightIdleTime = in.readLong(); 14711 mLongestFullIdleTime = in.readLong(); 14712 mDeviceIdleModeLightTimer = new StopwatchTimer(mClocks, null, -14, null, 14713 mOnBatteryTimeBase, in); 14714 mDeviceIdleModeFullTimer = new StopwatchTimer(mClocks, null, -11, null, 14715 mOnBatteryTimeBase, in); 14716 mDeviceLightIdlingTimer = new StopwatchTimer(mClocks, null, -15, null, 14717 mOnBatteryTimeBase, in); 14718 mDeviceIdlingTimer = new StopwatchTimer(mClocks, null, -12, null, mOnBatteryTimeBase, in); 14719 mPhoneOnTimer = new StopwatchTimer(mClocks, null, -3, null, mOnBatteryTimeBase, in); 14720 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) { 14721 mPhoneSignalStrengthsTimer[i] = new StopwatchTimer(mClocks, null, -200-i, 14722 null, mOnBatteryTimeBase, in); 14723 } 14724 mPhoneSignalScanningTimer = new StopwatchTimer(mClocks, null, -200+1, null, 14725 mOnBatteryTimeBase, in); 14726 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 14727 mPhoneDataConnectionsTimer[i] = new StopwatchTimer(mClocks, null, -300-i, 14728 null, mOnBatteryTimeBase, in); 14729 } 14730 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 14731 mNetworkByteActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase, in); 14732 mNetworkPacketActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase, in); 14733 } 14734 mMobileRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW; 14735 mMobileRadioActiveTimer = new StopwatchTimer(mClocks, null, -400, null, 14736 mOnBatteryTimeBase, in); 14737 mMobileRadioActivePerAppTimer = new StopwatchTimer(mClocks, null, -401, null, 14738 mOnBatteryTimeBase, in); 14739 mMobileRadioActiveAdjustedTime = new LongSamplingCounter(mOnBatteryTimeBase, in); 14740 mMobileRadioActiveUnknownTime = new LongSamplingCounter(mOnBatteryTimeBase, in); 14741 mMobileRadioActiveUnknownCount = new LongSamplingCounter(mOnBatteryTimeBase, in); 14742 mWifiMulticastWakelockTimer = new StopwatchTimer(mClocks, null, -4, null, 14743 mOnBatteryTimeBase, in); 14744 mWifiRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW; 14745 mWifiOn = false; 14746 mWifiOnTimer = new StopwatchTimer(mClocks, null, -4, null, mOnBatteryTimeBase, in); 14747 mGlobalWifiRunning = false; 14748 mGlobalWifiRunningTimer = new StopwatchTimer(mClocks, null, -5, null, 14749 mOnBatteryTimeBase, in); 14750 for (int i=0; i<NUM_WIFI_STATES; i++) { 14751 mWifiStateTimer[i] = new StopwatchTimer(mClocks, null, -600-i, 14752 null, mOnBatteryTimeBase, in); 14753 } 14754 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) { 14755 mWifiSupplStateTimer[i] = new StopwatchTimer(mClocks, null, -700-i, 14756 null, mOnBatteryTimeBase, in); 14757 } 14758 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { 14759 mWifiSignalStrengthsTimer[i] = new StopwatchTimer(mClocks, null, -800-i, 14760 null, mOnBatteryTimeBase, in); 14761 } 14762 mWifiActiveTimer = new StopwatchTimer(mClocks, null, -900, null, 14763 mOnBatteryTimeBase, in); 14764 mWifiActivity = new ControllerActivityCounterImpl(mOnBatteryTimeBase, 14765 NUM_WIFI_TX_LEVELS, in); 14766 for (int i=0; i<GnssMetrics.NUM_GPS_SIGNAL_QUALITY_LEVELS; i++) { 14767 mGpsSignalQualityTimer[i] = new StopwatchTimer(mClocks, null, -1000-i, 14768 null, mOnBatteryTimeBase, in); 14769 } 14770 mBluetoothActivity = new ControllerActivityCounterImpl(mOnBatteryTimeBase, 14771 NUM_BT_TX_LEVELS, in); 14772 mModemActivity = new ControllerActivityCounterImpl(mOnBatteryTimeBase, 14773 ModemActivityInfo.TX_POWER_LEVELS, in); 14774 mHasWifiReporting = in.readInt() != 0; 14775 mHasBluetoothReporting = in.readInt() != 0; 14776 mHasModemReporting = in.readInt() != 0; 14777 14778 mNumConnectivityChange = in.readInt(); 14779 mLoadedNumConnectivityChange = in.readInt(); 14780 mUnpluggedNumConnectivityChange = in.readInt(); 14781 mAudioOnNesting = 0; 14782 mAudioOnTimer = new StopwatchTimer(mClocks, null, -7, null, mOnBatteryTimeBase); 14783 mVideoOnNesting = 0; 14784 mVideoOnTimer = new StopwatchTimer(mClocks, null, -8, null, mOnBatteryTimeBase); 14785 mFlashlightOnNesting = 0; 14786 mFlashlightOnTimer = new StopwatchTimer(mClocks, null, -9, null, mOnBatteryTimeBase, in); 14787 mCameraOnNesting = 0; 14788 mCameraOnTimer = new StopwatchTimer(mClocks, null, -13, null, mOnBatteryTimeBase, in); 14789 mBluetoothScanNesting = 0; 14790 mBluetoothScanTimer = new StopwatchTimer(mClocks, null, -14, null, mOnBatteryTimeBase, in); 14791 mIsCellularTxPowerHigh = false; 14792 mDischargeUnplugLevel = in.readInt(); 14793 mDischargePlugLevel = in.readInt(); 14794 mDischargeCurrentLevel = in.readInt(); 14795 mCurrentBatteryLevel = in.readInt(); 14796 mLowDischargeAmountSinceCharge = in.readInt(); 14797 mHighDischargeAmountSinceCharge = in.readInt(); 14798 mDischargeAmountScreenOn = in.readInt(); 14799 mDischargeAmountScreenOnSinceCharge = in.readInt(); 14800 mDischargeAmountScreenOff = in.readInt(); 14801 mDischargeAmountScreenOffSinceCharge = in.readInt(); 14802 mDischargeAmountScreenDoze = in.readInt(); 14803 mDischargeAmountScreenDozeSinceCharge = in.readInt(); 14804 mDischargeStepTracker.readFromParcel(in); 14805 mChargeStepTracker.readFromParcel(in); 14806 mDischargeCounter = new LongSamplingCounter(mOnBatteryTimeBase, in); 14807 mDischargeScreenOffCounter = new LongSamplingCounter(mOnBatteryScreenOffTimeBase, in); 14808 mDischargeScreenDozeCounter = new LongSamplingCounter(mOnBatteryTimeBase, in); 14809 mDischargeLightDozeCounter = new LongSamplingCounter(mOnBatteryTimeBase, in); 14810 mDischargeDeepDozeCounter = new LongSamplingCounter(mOnBatteryTimeBase, in); 14811 mLastWriteTime = in.readLong(); 14812 14813 mRpmStats.clear(); 14814 int NRPMS = in.readInt(); 14815 for (int irpm = 0; irpm < NRPMS; irpm++) { 14816 if (in.readInt() != 0) { 14817 String rpmName = in.readString(); 14818 SamplingTimer rpmt = new SamplingTimer(mClocks, mOnBatteryTimeBase, in); 14819 mRpmStats.put(rpmName, rpmt); 14820 } 14821 } 14822 mScreenOffRpmStats.clear(); 14823 int NSORPMS = in.readInt(); 14824 for (int irpm = 0; irpm < NSORPMS; irpm++) { 14825 if (in.readInt() != 0) { 14826 String rpmName = in.readString(); 14827 SamplingTimer rpmt = new SamplingTimer(mClocks, mOnBatteryScreenOffTimeBase, in); 14828 mScreenOffRpmStats.put(rpmName, rpmt); 14829 } 14830 } 14831 14832 mKernelWakelockStats.clear(); 14833 int NKW = in.readInt(); 14834 for (int ikw = 0; ikw < NKW; ikw++) { 14835 if (in.readInt() != 0) { 14836 String wakelockName = in.readString(); 14837 SamplingTimer kwlt = new SamplingTimer(mClocks, mOnBatteryScreenOffTimeBase, in); 14838 mKernelWakelockStats.put(wakelockName, kwlt); 14839 } 14840 } 14841 14842 mWakeupReasonStats.clear(); 14843 int NWR = in.readInt(); 14844 for (int iwr = 0; iwr < NWR; iwr++) { 14845 if (in.readInt() != 0) { 14846 String reasonName = in.readString(); 14847 SamplingTimer timer = new SamplingTimer(mClocks, mOnBatteryTimeBase, in); 14848 mWakeupReasonStats.put(reasonName, timer); 14849 } 14850 } 14851 14852 mKernelMemoryStats.clear(); 14853 int nmt = in.readInt(); 14854 for (int imt = 0; imt < nmt; imt++) { 14855 if (in.readInt() != 0) { 14856 Long bucket = in.readLong(); 14857 SamplingTimer kmt = new SamplingTimer(mClocks, mOnBatteryTimeBase, in); 14858 mKernelMemoryStats.put(bucket, kmt); 14859 } 14860 } 14861 14862 mPartialTimers.clear(); 14863 mFullTimers.clear(); 14864 mWindowTimers.clear(); 14865 mWifiRunningTimers.clear(); 14866 mFullWifiLockTimers.clear(); 14867 mWifiScanTimers.clear(); 14868 mWifiBatchedScanTimers.clear(); 14869 mWifiMulticastTimers.clear(); 14870 mAudioTurnedOnTimers.clear(); 14871 mVideoTurnedOnTimers.clear(); 14872 mFlashlightTurnedOnTimers.clear(); 14873 mCameraTurnedOnTimers.clear(); 14874 14875 int numUids = in.readInt(); 14876 mUidStats.clear(); 14877 for (int i = 0; i < numUids; i++) { 14878 int uid = in.readInt(); 14879 Uid u = new Uid(this, uid); 14880 u.readFromParcelLocked(mOnBatteryTimeBase, mOnBatteryScreenOffTimeBase, in); 14881 mUidStats.append(uid, u); 14882 } 14883 } 14884 writeToParcel(Parcel out, int flags)14885 public void writeToParcel(Parcel out, int flags) { 14886 writeToParcelLocked(out, true, flags); 14887 } 14888 writeToParcelWithoutUids(Parcel out, int flags)14889 public void writeToParcelWithoutUids(Parcel out, int flags) { 14890 writeToParcelLocked(out, false, flags); 14891 } 14892 14893 @SuppressWarnings("unused") writeToParcelLocked(Parcel out, boolean inclUids, int flags)14894 void writeToParcelLocked(Parcel out, boolean inclUids, int flags) { 14895 // Need to update with current kernel wake lock counts. 14896 pullPendingStateUpdatesLocked(); 14897 14898 // Pull the clock time. This may update the time and make a new history entry 14899 // if we had originally pulled a time before the RTC was set. 14900 long startClockTime = getStartClockTime(); 14901 14902 final long uSecUptime = mClocks.uptimeMillis() * 1000; 14903 final long uSecRealtime = mClocks.elapsedRealtime() * 1000; 14904 final long batteryRealtime = mOnBatteryTimeBase.getRealtime(uSecRealtime); 14905 final long batteryScreenOffRealtime = mOnBatteryScreenOffTimeBase.getRealtime(uSecRealtime); 14906 14907 out.writeInt(MAGIC); 14908 14909 writeHistory(out, true, false); 14910 14911 out.writeInt(mStartCount); 14912 out.writeLong(startClockTime); 14913 out.writeString(mStartPlatformVersion); 14914 out.writeString(mEndPlatformVersion); 14915 out.writeLong(mUptime); 14916 out.writeLong(mUptimeStart); 14917 out.writeLong(mRealtime); 14918 out.writeLong(mRealtimeStart); 14919 out.writeInt(mOnBattery ? 1 : 0); 14920 out.writeInt(mEstimatedBatteryCapacity); 14921 out.writeInt(mMinLearnedBatteryCapacity); 14922 out.writeInt(mMaxLearnedBatteryCapacity); 14923 mOnBatteryTimeBase.writeToParcel(out, uSecUptime, uSecRealtime); 14924 mOnBatteryScreenOffTimeBase.writeToParcel(out, uSecUptime, uSecRealtime); 14925 14926 mScreenOnTimer.writeToParcel(out, uSecRealtime); 14927 mScreenDozeTimer.writeToParcel(out, uSecRealtime); 14928 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 14929 mScreenBrightnessTimer[i].writeToParcel(out, uSecRealtime); 14930 } 14931 mInteractiveTimer.writeToParcel(out, uSecRealtime); 14932 mPowerSaveModeEnabledTimer.writeToParcel(out, uSecRealtime); 14933 out.writeLong(mLongestLightIdleTime); 14934 out.writeLong(mLongestFullIdleTime); 14935 mDeviceIdleModeLightTimer.writeToParcel(out, uSecRealtime); 14936 mDeviceIdleModeFullTimer.writeToParcel(out, uSecRealtime); 14937 mDeviceLightIdlingTimer.writeToParcel(out, uSecRealtime); 14938 mDeviceIdlingTimer.writeToParcel(out, uSecRealtime); 14939 mPhoneOnTimer.writeToParcel(out, uSecRealtime); 14940 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) { 14941 mPhoneSignalStrengthsTimer[i].writeToParcel(out, uSecRealtime); 14942 } 14943 mPhoneSignalScanningTimer.writeToParcel(out, uSecRealtime); 14944 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 14945 mPhoneDataConnectionsTimer[i].writeToParcel(out, uSecRealtime); 14946 } 14947 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 14948 mNetworkByteActivityCounters[i].writeToParcel(out); 14949 mNetworkPacketActivityCounters[i].writeToParcel(out); 14950 } 14951 mMobileRadioActiveTimer.writeToParcel(out, uSecRealtime); 14952 mMobileRadioActivePerAppTimer.writeToParcel(out, uSecRealtime); 14953 mMobileRadioActiveAdjustedTime.writeToParcel(out); 14954 mMobileRadioActiveUnknownTime.writeToParcel(out); 14955 mMobileRadioActiveUnknownCount.writeToParcel(out); 14956 mWifiMulticastWakelockTimer.writeToParcel(out, uSecRealtime); 14957 mWifiOnTimer.writeToParcel(out, uSecRealtime); 14958 mGlobalWifiRunningTimer.writeToParcel(out, uSecRealtime); 14959 for (int i=0; i<NUM_WIFI_STATES; i++) { 14960 mWifiStateTimer[i].writeToParcel(out, uSecRealtime); 14961 } 14962 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) { 14963 mWifiSupplStateTimer[i].writeToParcel(out, uSecRealtime); 14964 } 14965 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { 14966 mWifiSignalStrengthsTimer[i].writeToParcel(out, uSecRealtime); 14967 } 14968 mWifiActiveTimer.writeToParcel(out, uSecRealtime); 14969 mWifiActivity.writeToParcel(out, 0); 14970 for (int i=0; i< GnssMetrics.NUM_GPS_SIGNAL_QUALITY_LEVELS; i++) { 14971 mGpsSignalQualityTimer[i].writeToParcel(out, uSecRealtime); 14972 } 14973 mBluetoothActivity.writeToParcel(out, 0); 14974 mModemActivity.writeToParcel(out, 0); 14975 out.writeInt(mHasWifiReporting ? 1 : 0); 14976 out.writeInt(mHasBluetoothReporting ? 1 : 0); 14977 out.writeInt(mHasModemReporting ? 1 : 0); 14978 14979 out.writeInt(mNumConnectivityChange); 14980 out.writeInt(mLoadedNumConnectivityChange); 14981 out.writeInt(mUnpluggedNumConnectivityChange); 14982 mFlashlightOnTimer.writeToParcel(out, uSecRealtime); 14983 mCameraOnTimer.writeToParcel(out, uSecRealtime); 14984 mBluetoothScanTimer.writeToParcel(out, uSecRealtime); 14985 out.writeInt(mDischargeUnplugLevel); 14986 out.writeInt(mDischargePlugLevel); 14987 out.writeInt(mDischargeCurrentLevel); 14988 out.writeInt(mCurrentBatteryLevel); 14989 out.writeInt(mLowDischargeAmountSinceCharge); 14990 out.writeInt(mHighDischargeAmountSinceCharge); 14991 out.writeInt(mDischargeAmountScreenOn); 14992 out.writeInt(mDischargeAmountScreenOnSinceCharge); 14993 out.writeInt(mDischargeAmountScreenOff); 14994 out.writeInt(mDischargeAmountScreenOffSinceCharge); 14995 out.writeInt(mDischargeAmountScreenDoze); 14996 out.writeInt(mDischargeAmountScreenDozeSinceCharge); 14997 mDischargeStepTracker.writeToParcel(out); 14998 mChargeStepTracker.writeToParcel(out); 14999 mDischargeCounter.writeToParcel(out); 15000 mDischargeScreenOffCounter.writeToParcel(out); 15001 mDischargeScreenDozeCounter.writeToParcel(out); 15002 mDischargeLightDozeCounter.writeToParcel(out); 15003 mDischargeDeepDozeCounter.writeToParcel(out); 15004 out.writeLong(mLastWriteTime); 15005 15006 out.writeInt(mRpmStats.size()); 15007 for (Map.Entry<String, SamplingTimer> ent : mRpmStats.entrySet()) { 15008 SamplingTimer rpmt = ent.getValue(); 15009 if (rpmt != null) { 15010 out.writeInt(1); 15011 out.writeString(ent.getKey()); 15012 rpmt.writeToParcel(out, uSecRealtime); 15013 } else { 15014 out.writeInt(0); 15015 } 15016 } 15017 out.writeInt(mScreenOffRpmStats.size()); 15018 for (Map.Entry<String, SamplingTimer> ent : mScreenOffRpmStats.entrySet()) { 15019 SamplingTimer rpmt = ent.getValue(); 15020 if (rpmt != null) { 15021 out.writeInt(1); 15022 out.writeString(ent.getKey()); 15023 rpmt.writeToParcel(out, uSecRealtime); 15024 } else { 15025 out.writeInt(0); 15026 } 15027 } 15028 15029 if (inclUids) { 15030 out.writeInt(mKernelWakelockStats.size()); 15031 for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) { 15032 SamplingTimer kwlt = ent.getValue(); 15033 if (kwlt != null) { 15034 out.writeInt(1); 15035 out.writeString(ent.getKey()); 15036 kwlt.writeToParcel(out, uSecRealtime); 15037 } else { 15038 out.writeInt(0); 15039 } 15040 } 15041 out.writeInt(mWakeupReasonStats.size()); 15042 for (Map.Entry<String, SamplingTimer> ent : mWakeupReasonStats.entrySet()) { 15043 SamplingTimer timer = ent.getValue(); 15044 if (timer != null) { 15045 out.writeInt(1); 15046 out.writeString(ent.getKey()); 15047 timer.writeToParcel(out, uSecRealtime); 15048 } else { 15049 out.writeInt(0); 15050 } 15051 } 15052 } else { 15053 out.writeInt(0); 15054 out.writeInt(0); 15055 } 15056 15057 out.writeInt(mKernelMemoryStats.size()); 15058 for (int i = 0; i < mKernelMemoryStats.size(); i++) { 15059 SamplingTimer kmt = mKernelMemoryStats.valueAt(i); 15060 if (kmt != null) { 15061 out.writeInt(1); 15062 out.writeLong(mKernelMemoryStats.keyAt(i)); 15063 kmt.writeToParcel(out, uSecRealtime); 15064 } else { 15065 out.writeInt(0); 15066 } 15067 } 15068 15069 if (inclUids) { 15070 int size = mUidStats.size(); 15071 out.writeInt(size); 15072 for (int i = 0; i < size; i++) { 15073 out.writeInt(mUidStats.keyAt(i)); 15074 Uid uid = mUidStats.valueAt(i); 15075 15076 uid.writeToParcelLocked(out, uSecUptime, uSecRealtime); 15077 } 15078 } else { 15079 out.writeInt(0); 15080 } 15081 } 15082 15083 public static final Parcelable.Creator<BatteryStatsImpl> CREATOR = 15084 new Parcelable.Creator<BatteryStatsImpl>() { 15085 public BatteryStatsImpl createFromParcel(Parcel in) { 15086 return new BatteryStatsImpl(in); 15087 } 15088 15089 public BatteryStatsImpl[] newArray(int size) { 15090 return new BatteryStatsImpl[size]; 15091 } 15092 }; 15093 prepareForDumpLocked()15094 public void prepareForDumpLocked() { 15095 // Need to retrieve current kernel wake lock stats before printing. 15096 pullPendingStateUpdatesLocked(); 15097 15098 // Pull the clock time. This may update the time and make a new history entry 15099 // if we had originally pulled a time before the RTC was set. 15100 getStartClockTime(); 15101 } 15102 dumpLocked(Context context, PrintWriter pw, int flags, int reqUid, long histStart)15103 public void dumpLocked(Context context, PrintWriter pw, int flags, int reqUid, long histStart) { 15104 if (DEBUG) { 15105 pw.println("mOnBatteryTimeBase:"); 15106 mOnBatteryTimeBase.dump(pw, " "); 15107 pw.println("mOnBatteryScreenOffTimeBase:"); 15108 mOnBatteryScreenOffTimeBase.dump(pw, " "); 15109 Printer pr = new PrintWriterPrinter(pw); 15110 pr.println("*** Screen on timer:"); 15111 mScreenOnTimer.logState(pr, " "); 15112 pr.println("*** Screen doze timer:"); 15113 mScreenDozeTimer.logState(pr, " "); 15114 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 15115 pr.println("*** Screen brightness #" + i + ":"); 15116 mScreenBrightnessTimer[i].logState(pr, " "); 15117 } 15118 pr.println("*** Interactive timer:"); 15119 mInteractiveTimer.logState(pr, " "); 15120 pr.println("*** Power save mode timer:"); 15121 mPowerSaveModeEnabledTimer.logState(pr, " "); 15122 pr.println("*** Device idle mode light timer:"); 15123 mDeviceIdleModeLightTimer.logState(pr, " "); 15124 pr.println("*** Device idle mode full timer:"); 15125 mDeviceIdleModeFullTimer.logState(pr, " "); 15126 pr.println("*** Device light idling timer:"); 15127 mDeviceLightIdlingTimer.logState(pr, " "); 15128 pr.println("*** Device idling timer:"); 15129 mDeviceIdlingTimer.logState(pr, " "); 15130 pr.println("*** Phone timer:"); 15131 mPhoneOnTimer.logState(pr, " "); 15132 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) { 15133 pr.println("*** Phone signal strength #" + i + ":"); 15134 mPhoneSignalStrengthsTimer[i].logState(pr, " "); 15135 } 15136 pr.println("*** Signal scanning :"); 15137 mPhoneSignalScanningTimer.logState(pr, " "); 15138 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 15139 pr.println("*** Data connection type #" + i + ":"); 15140 mPhoneDataConnectionsTimer[i].logState(pr, " "); 15141 } 15142 pr.println("*** mMobileRadioPowerState=" + mMobileRadioPowerState); 15143 pr.println("*** Mobile network active timer:"); 15144 mMobileRadioActiveTimer.logState(pr, " "); 15145 pr.println("*** Mobile network active adjusted timer:"); 15146 mMobileRadioActiveAdjustedTime.logState(pr, " "); 15147 pr.println("*** Wifi Multicast WakeLock Timer:"); 15148 mWifiMulticastWakelockTimer.logState(pr, " "); 15149 pr.println("*** mWifiRadioPowerState=" + mWifiRadioPowerState); 15150 pr.println("*** Wifi timer:"); 15151 mWifiOnTimer.logState(pr, " "); 15152 pr.println("*** WifiRunning timer:"); 15153 mGlobalWifiRunningTimer.logState(pr, " "); 15154 for (int i=0; i<NUM_WIFI_STATES; i++) { 15155 pr.println("*** Wifi state #" + i + ":"); 15156 mWifiStateTimer[i].logState(pr, " "); 15157 } 15158 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) { 15159 pr.println("*** Wifi suppl state #" + i + ":"); 15160 mWifiSupplStateTimer[i].logState(pr, " "); 15161 } 15162 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { 15163 pr.println("*** Wifi signal strength #" + i + ":"); 15164 mWifiSignalStrengthsTimer[i].logState(pr, " "); 15165 } 15166 for (int i=0; i<GnssMetrics.NUM_GPS_SIGNAL_QUALITY_LEVELS; i++) { 15167 pr.println("*** GPS signal quality #" + i + ":"); 15168 mGpsSignalQualityTimer[i].logState(pr, " "); 15169 } 15170 pr.println("*** Flashlight timer:"); 15171 mFlashlightOnTimer.logState(pr, " "); 15172 pr.println("*** Camera timer:"); 15173 mCameraOnTimer.logState(pr, " "); 15174 } 15175 super.dumpLocked(context, pw, flags, reqUid, histStart); 15176 pw.print("Total cpu time reads: "); 15177 pw.println(mNumSingleUidCpuTimeReads); 15178 pw.print("Batched cpu time reads: "); 15179 pw.println(mNumBatchedSingleUidCpuTimeReads); 15180 pw.print("Batching Duration (min): "); 15181 pw.println((mClocks.uptimeMillis() - mCpuTimeReadsTrackingStartTime) / (60 * 1000)); 15182 pw.print("All UID cpu time reads since the later of device start or stats reset: "); 15183 pw.println(mNumAllUidCpuTimeReads); 15184 pw.print("UIDs removed since the later of device start or stats reset: "); 15185 pw.println(mNumUidsRemoved); 15186 } 15187 } 15188