BatteryStatsImpl.java revision d4abd1eeb01187fa2ef78b64ae4f493a7bb3563f
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 17package com.android.internal.os; 18 19import android.annotation.Nullable; 20import android.app.ActivityManager; 21import android.bluetooth.BluetoothActivityEnergyInfo; 22import android.bluetooth.UidTraffic; 23import android.content.Context; 24import android.content.Intent; 25import android.net.ConnectivityManager; 26import android.net.NetworkStats; 27import android.net.wifi.WifiActivityEnergyInfo; 28import android.net.wifi.WifiManager; 29import android.os.BatteryManager; 30import android.os.BatteryStats; 31import android.os.Build; 32import android.os.FileUtils; 33import android.os.Handler; 34import android.os.IBatteryPropertiesRegistrar; 35import android.os.Looper; 36import android.os.Message; 37import android.os.Parcel; 38import android.os.ParcelFormatException; 39import android.os.Parcelable; 40import android.os.Process; 41import android.os.RemoteException; 42import android.os.ServiceManager; 43import android.os.SystemClock; 44import android.os.SystemProperties; 45import android.os.WorkSource; 46import android.telephony.DataConnectionRealTimeInfo; 47import android.telephony.ModemActivityInfo; 48import android.telephony.ServiceState; 49import android.telephony.SignalStrength; 50import android.telephony.TelephonyManager; 51import android.text.TextUtils; 52import android.util.ArrayMap; 53import android.util.Log; 54import android.util.LogWriter; 55import android.util.LongSparseArray; 56import android.util.LongSparseLongArray; 57import android.util.MutableInt; 58import android.util.PrintWriterPrinter; 59import android.util.Printer; 60import android.util.Slog; 61import android.util.SparseArray; 62import android.util.SparseIntArray; 63import android.util.SparseLongArray; 64import android.util.TimeUtils; 65import android.util.Xml; 66import android.view.Display; 67 68import com.android.internal.annotations.VisibleForTesting; 69import com.android.internal.net.NetworkStatsFactory; 70import com.android.internal.util.ArrayUtils; 71import com.android.internal.util.FastPrintWriter; 72import com.android.internal.util.FastXmlSerializer; 73import com.android.internal.util.JournaledFile; 74import com.android.internal.util.XmlUtils; 75import com.android.server.NetworkManagementSocketTagger; 76import libcore.util.EmptyArray; 77import org.xmlpull.v1.XmlPullParser; 78import org.xmlpull.v1.XmlPullParserException; 79import org.xmlpull.v1.XmlSerializer; 80 81import java.io.ByteArrayOutputStream; 82import java.io.File; 83import java.io.FileInputStream; 84import java.io.FileNotFoundException; 85import java.io.FileOutputStream; 86import java.io.IOException; 87import java.io.PrintWriter; 88import java.nio.charset.StandardCharsets; 89import java.util.ArrayList; 90import java.util.Calendar; 91import java.util.HashMap; 92import java.util.Iterator; 93import java.util.Map; 94import java.util.concurrent.atomic.AtomicInteger; 95import java.util.concurrent.locks.ReentrantLock; 96 97/** 98 * All information we are collecting about things that can happen that impact 99 * battery life. All times are represented in microseconds except where indicated 100 * otherwise. 101 */ 102public class BatteryStatsImpl extends BatteryStats { 103 private static final String TAG = "BatteryStatsImpl"; 104 private static final boolean DEBUG = false; 105 public static final boolean DEBUG_ENERGY = false; 106 private static final boolean DEBUG_ENERGY_CPU = DEBUG_ENERGY; 107 private static final boolean DEBUG_MEMORY = false; 108 private static final boolean DEBUG_HISTORY = false; 109 private static final boolean USE_OLD_HISTORY = false; // for debugging. 110 111 // TODO: remove "tcp" from network methods, since we measure total stats. 112 113 // In-memory Parcel magic number, used to detect attempts to unmarshall bad data 114 private static final int MAGIC = 0xBA757475; // 'BATSTATS' 115 116 // Current on-disk Parcel version 117 private static final int VERSION = 154 + (USE_OLD_HISTORY ? 1000 : 0); 118 119 // Maximum number of items we will record in the history. 120 private static final int MAX_HISTORY_ITEMS = 2000; 121 122 // No, really, THIS is the maximum number of items we will record in the history. 123 private static final int MAX_MAX_HISTORY_ITEMS = 3000; 124 125 // The maximum number of names wakelocks we will keep track of 126 // per uid; once the limit is reached, we batch the remaining wakelocks 127 // in to one common name. 128 private static final int MAX_WAKELOCKS_PER_UID = 100; 129 130 // Number of transmit power states the Wifi controller can be in. 131 private static final int NUM_WIFI_TX_LEVELS = 1; 132 133 // Number of transmit power states the Bluetooth controller can be in. 134 private static final int NUM_BT_TX_LEVELS = 1; 135 136 protected Clocks mClocks; 137 138 private final JournaledFile mFile; 139 public final AtomicFile mCheckinFile; 140 public final AtomicFile mDailyFile; 141 142 static final int MSG_UPDATE_WAKELOCKS = 1; 143 static final int MSG_REPORT_POWER_CHANGE = 2; 144 static final int MSG_REPORT_CHARGING = 3; 145 static final long DELAY_UPDATE_WAKELOCKS = 5*1000; 146 147 private final KernelWakelockReader mKernelWakelockReader = new KernelWakelockReader(); 148 private final KernelWakelockStats mTmpWakelockStats = new KernelWakelockStats(); 149 150 private final KernelUidCpuTimeReader mKernelUidCpuTimeReader = new KernelUidCpuTimeReader(); 151 private KernelCpuSpeedReader[] mKernelCpuSpeedReaders; 152 153 private final KernelMemoryBandwidthStats mKernelMemoryBandwidthStats 154 = new KernelMemoryBandwidthStats(); 155 private final LongSparseArray<SamplingTimer> mKernelMemoryStats = new LongSparseArray<>(); 156 public LongSparseArray<SamplingTimer> getKernelMemoryStats() { 157 return mKernelMemoryStats; 158 } 159 160 public interface BatteryCallback { 161 public void batteryNeedsCpuUpdate(); 162 public void batteryPowerChanged(boolean onBattery); 163 public void batterySendBroadcast(Intent intent); 164 } 165 166 public interface PlatformIdleStateCallback { 167 public String getPlatformLowPowerStats(); 168 } 169 170 private final PlatformIdleStateCallback mPlatformIdleStateCallback; 171 172 173 final class MyHandler extends Handler { 174 public MyHandler(Looper looper) { 175 super(looper, null, true); 176 } 177 178 @Override 179 public void handleMessage(Message msg) { 180 BatteryCallback cb = mCallback; 181 switch (msg.what) { 182 case MSG_UPDATE_WAKELOCKS: 183 synchronized (BatteryStatsImpl.this) { 184 updateCpuTimeLocked(); 185 } 186 if (cb != null) { 187 cb.batteryNeedsCpuUpdate(); 188 } 189 break; 190 case MSG_REPORT_POWER_CHANGE: 191 if (cb != null) { 192 cb.batteryPowerChanged(msg.arg1 != 0); 193 } 194 break; 195 case MSG_REPORT_CHARGING: 196 if (cb != null) { 197 final String action; 198 synchronized (BatteryStatsImpl.this) { 199 action = mCharging ? BatteryManager.ACTION_CHARGING 200 : BatteryManager.ACTION_DISCHARGING; 201 } 202 Intent intent = new Intent(action); 203 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); 204 cb.batterySendBroadcast(intent); 205 } 206 break; 207 } 208 } 209 } 210 211 public interface Clocks { 212 public long elapsedRealtime(); 213 public long uptimeMillis(); 214 } 215 216 public static class SystemClocks implements Clocks { 217 public long elapsedRealtime() { 218 return SystemClock.elapsedRealtime(); 219 } 220 221 public long uptimeMillis() { 222 return SystemClock.uptimeMillis(); 223 } 224 } 225 226 public interface ExternalStatsSync { 227 public static final int UPDATE_CPU = 0x01; 228 public static final int UPDATE_WIFI = 0x02; 229 public static final int UPDATE_RADIO = 0x04; 230 public static final int UPDATE_BT = 0x08; 231 public static final int UPDATE_ALL = UPDATE_CPU | UPDATE_WIFI | UPDATE_RADIO | UPDATE_BT; 232 233 void scheduleSync(String reason, int flags); 234 void scheduleCpuSyncDueToRemovedUid(int uid); 235 } 236 237 public final MyHandler mHandler; 238 private final ExternalStatsSync mExternalSync; 239 240 private BatteryCallback mCallback; 241 242 /** 243 * Mapping isolated uids to the actual owning app uid. 244 */ 245 final SparseIntArray mIsolatedUids = new SparseIntArray(); 246 247 /** 248 * The statistics we have collected organized by uids. 249 */ 250 final SparseArray<BatteryStatsImpl.Uid> mUidStats = new SparseArray<>(); 251 252 // A set of pools of currently active timers. When a timer is queried, we will divide the 253 // elapsed time by the number of active timers to arrive at that timer's share of the time. 254 // In order to do this, we must refresh each timer whenever the number of active timers 255 // changes. 256 final ArrayList<StopwatchTimer> mPartialTimers = new ArrayList<>(); 257 final ArrayList<StopwatchTimer> mFullTimers = new ArrayList<>(); 258 final ArrayList<StopwatchTimer> mWindowTimers = new ArrayList<>(); 259 final ArrayList<StopwatchTimer> mDrawTimers = new ArrayList<>(); 260 final SparseArray<ArrayList<StopwatchTimer>> mSensorTimers = new SparseArray<>(); 261 final ArrayList<StopwatchTimer> mWifiRunningTimers = new ArrayList<>(); 262 final ArrayList<StopwatchTimer> mFullWifiLockTimers = new ArrayList<>(); 263 final ArrayList<StopwatchTimer> mWifiMulticastTimers = new ArrayList<>(); 264 final ArrayList<StopwatchTimer> mWifiScanTimers = new ArrayList<>(); 265 final SparseArray<ArrayList<StopwatchTimer>> mWifiBatchedScanTimers = new SparseArray<>(); 266 final ArrayList<StopwatchTimer> mAudioTurnedOnTimers = new ArrayList<>(); 267 final ArrayList<StopwatchTimer> mVideoTurnedOnTimers = new ArrayList<>(); 268 final ArrayList<StopwatchTimer> mFlashlightTurnedOnTimers = new ArrayList<>(); 269 final ArrayList<StopwatchTimer> mCameraTurnedOnTimers = new ArrayList<>(); 270 final ArrayList<StopwatchTimer> mBluetoothScanOnTimers = new ArrayList<>(); 271 272 // Last partial timers we use for distributing CPU usage. 273 final ArrayList<StopwatchTimer> mLastPartialTimers = new ArrayList<>(); 274 275 // These are the objects that will want to do something when the device 276 // is unplugged from power. 277 protected final TimeBase mOnBatteryTimeBase = new TimeBase(); 278 279 // These are the objects that will want to do something when the device 280 // is unplugged from power *and* the screen is off. 281 final TimeBase mOnBatteryScreenOffTimeBase = new TimeBase(); 282 283 // Set to true when we want to distribute CPU across wakelocks for the next 284 // CPU update, even if we aren't currently running wake locks. 285 boolean mDistributeWakelockCpu; 286 287 boolean mShuttingDown; 288 289 final HistoryEventTracker mActiveEvents = new HistoryEventTracker(); 290 291 long mHistoryBaseTime; 292 boolean mHaveBatteryLevel = false; 293 boolean mRecordingHistory = false; 294 int mNumHistoryItems; 295 296 static final int MAX_HISTORY_BUFFER = 256*1024; // 256KB 297 static final int MAX_MAX_HISTORY_BUFFER = 320*1024; // 320KB 298 final Parcel mHistoryBuffer = Parcel.obtain(); 299 final HistoryItem mHistoryLastWritten = new HistoryItem(); 300 final HistoryItem mHistoryLastLastWritten = new HistoryItem(); 301 final HistoryItem mHistoryReadTmp = new HistoryItem(); 302 final HistoryItem mHistoryAddTmp = new HistoryItem(); 303 final HashMap<HistoryTag, Integer> mHistoryTagPool = new HashMap<>(); 304 String[] mReadHistoryStrings; 305 int[] mReadHistoryUids; 306 int mReadHistoryChars; 307 int mNextHistoryTagIdx = 0; 308 int mNumHistoryTagChars = 0; 309 int mHistoryBufferLastPos = -1; 310 boolean mHistoryOverflow = false; 311 int mActiveHistoryStates = 0xffffffff; 312 int mActiveHistoryStates2 = 0xffffffff; 313 long mLastHistoryElapsedRealtime = 0; 314 long mTrackRunningHistoryElapsedRealtime = 0; 315 long mTrackRunningHistoryUptime = 0; 316 317 final HistoryItem mHistoryCur = new HistoryItem(); 318 319 HistoryItem mHistory; 320 HistoryItem mHistoryEnd; 321 HistoryItem mHistoryLastEnd; 322 HistoryItem mHistoryCache; 323 324 // Used by computeHistoryStepDetails 325 HistoryStepDetails mLastHistoryStepDetails = null; 326 byte mLastHistoryStepLevel = 0; 327 final HistoryStepDetails mCurHistoryStepDetails = new HistoryStepDetails(); 328 final HistoryStepDetails mReadHistoryStepDetails = new HistoryStepDetails(); 329 final HistoryStepDetails mTmpHistoryStepDetails = new HistoryStepDetails(); 330 331 /** 332 * Total time (in milliseconds) spent executing in user code. 333 */ 334 long mLastStepCpuUserTime; 335 long mCurStepCpuUserTime; 336 /** 337 * Total time (in milliseconds) spent executing in kernel code. 338 */ 339 long mLastStepCpuSystemTime; 340 long mCurStepCpuSystemTime; 341 /** 342 * Times from /proc/stat (but measured in milliseconds). 343 */ 344 long mLastStepStatUserTime; 345 long mLastStepStatSystemTime; 346 long mLastStepStatIOWaitTime; 347 long mLastStepStatIrqTime; 348 long mLastStepStatSoftIrqTime; 349 long mLastStepStatIdleTime; 350 long mCurStepStatUserTime; 351 long mCurStepStatSystemTime; 352 long mCurStepStatIOWaitTime; 353 long mCurStepStatIrqTime; 354 long mCurStepStatSoftIrqTime; 355 long mCurStepStatIdleTime; 356 357 private HistoryItem mHistoryIterator; 358 private boolean mReadOverflow; 359 private boolean mIteratingHistory; 360 361 int mStartCount; 362 363 long mStartClockTime; 364 String mStartPlatformVersion; 365 String mEndPlatformVersion; 366 367 long mUptime; 368 long mUptimeStart; 369 long mRealtime; 370 long mRealtimeStart; 371 372 int mWakeLockNesting; 373 boolean mWakeLockImportant; 374 public boolean mRecordAllHistory; 375 boolean mNoAutoReset; 376 377 int mScreenState = Display.STATE_UNKNOWN; 378 StopwatchTimer mScreenOnTimer; 379 380 int mScreenBrightnessBin = -1; 381 final StopwatchTimer[] mScreenBrightnessTimer = new StopwatchTimer[NUM_SCREEN_BRIGHTNESS_BINS]; 382 383 boolean mPretendScreenOff; 384 385 boolean mInteractive; 386 StopwatchTimer mInteractiveTimer; 387 388 boolean mPowerSaveModeEnabled; 389 StopwatchTimer mPowerSaveModeEnabledTimer; 390 391 boolean mDeviceIdling; 392 StopwatchTimer mDeviceIdlingTimer; 393 394 boolean mDeviceLightIdling; 395 StopwatchTimer mDeviceLightIdlingTimer; 396 397 int mDeviceIdleMode; 398 long mLastIdleTimeStart; 399 long mLongestLightIdleTime; 400 long mLongestFullIdleTime; 401 StopwatchTimer mDeviceIdleModeLightTimer; 402 StopwatchTimer mDeviceIdleModeFullTimer; 403 404 boolean mPhoneOn; 405 StopwatchTimer mPhoneOnTimer; 406 407 int mAudioOnNesting; 408 StopwatchTimer mAudioOnTimer; 409 410 int mVideoOnNesting; 411 StopwatchTimer mVideoOnTimer; 412 413 int mFlashlightOnNesting; 414 StopwatchTimer mFlashlightOnTimer; 415 416 int mCameraOnNesting; 417 StopwatchTimer mCameraOnTimer; 418 419 int mPhoneSignalStrengthBin = -1; 420 int mPhoneSignalStrengthBinRaw = -1; 421 final StopwatchTimer[] mPhoneSignalStrengthsTimer = 422 new StopwatchTimer[SignalStrength.NUM_SIGNAL_STRENGTH_BINS]; 423 424 StopwatchTimer mPhoneSignalScanningTimer; 425 426 int mPhoneDataConnectionType = -1; 427 final StopwatchTimer[] mPhoneDataConnectionsTimer = 428 new StopwatchTimer[NUM_DATA_CONNECTION_TYPES]; 429 430 final LongSamplingCounter[] mNetworkByteActivityCounters = 431 new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES]; 432 final LongSamplingCounter[] mNetworkPacketActivityCounters = 433 new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES]; 434 435 /** 436 * The WiFi controller activity (time in tx, rx, idle, and power consumed) for the device. 437 */ 438 ControllerActivityCounterImpl mWifiActivity; 439 440 /** 441 * The Bluetooth controller activity (time in tx, rx, idle, and power consumed) for the device. 442 */ 443 ControllerActivityCounterImpl mBluetoothActivity; 444 445 /** 446 * The Modem controller activity (time in tx, rx, idle, and power consumed) for the device. 447 */ 448 ControllerActivityCounterImpl mModemActivity; 449 450 /** 451 * Whether the device supports WiFi controller energy reporting. This is set to true on 452 * the first WiFi energy report. See {@link #mWifiActivity}. 453 */ 454 boolean mHasWifiReporting = false; 455 456 /** 457 * Whether the device supports Bluetooth controller energy reporting. This is set to true on 458 * the first Bluetooth energy report. See {@link #mBluetoothActivity}. 459 */ 460 boolean mHasBluetoothReporting = false; 461 462 /** 463 * Whether the device supports Modem controller energy reporting. This is set to true on 464 * the first Modem energy report. See {@link #mModemActivity}. 465 */ 466 boolean mHasModemReporting = false; 467 468 boolean mWifiOn; 469 StopwatchTimer mWifiOnTimer; 470 471 boolean mGlobalWifiRunning; 472 StopwatchTimer mGlobalWifiRunningTimer; 473 474 int mWifiState = -1; 475 final StopwatchTimer[] mWifiStateTimer = new StopwatchTimer[NUM_WIFI_STATES]; 476 477 int mWifiSupplState = -1; 478 final StopwatchTimer[] mWifiSupplStateTimer = new StopwatchTimer[NUM_WIFI_SUPPL_STATES]; 479 480 int mWifiSignalStrengthBin = -1; 481 final StopwatchTimer[] mWifiSignalStrengthsTimer = 482 new StopwatchTimer[NUM_WIFI_SIGNAL_STRENGTH_BINS]; 483 484 int mBluetoothScanNesting; 485 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) 486 protected StopwatchTimer mBluetoothScanTimer; 487 488 int mMobileRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW; 489 long mMobileRadioActiveStartTime; 490 StopwatchTimer mMobileRadioActiveTimer; 491 StopwatchTimer mMobileRadioActivePerAppTimer; 492 LongSamplingCounter mMobileRadioActiveAdjustedTime; 493 LongSamplingCounter mMobileRadioActiveUnknownTime; 494 LongSamplingCounter mMobileRadioActiveUnknownCount; 495 496 int mWifiRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW; 497 498 /** 499 * These provide time bases that discount the time the device is plugged 500 * in to power. 501 */ 502 boolean mOnBattery; 503 boolean mOnBatteryInternal; 504 505 /** 506 * External reporting of whether the device is actually charging. 507 */ 508 boolean mCharging = true; 509 int mLastChargingStateLevel; 510 511 /* 512 * These keep track of battery levels (1-100) at the last plug event and the last unplug event. 513 */ 514 int mDischargeStartLevel; 515 int mDischargeUnplugLevel; 516 int mDischargePlugLevel; 517 int mDischargeCurrentLevel; 518 int mCurrentBatteryLevel; 519 int mLowDischargeAmountSinceCharge; 520 int mHighDischargeAmountSinceCharge; 521 int mDischargeScreenOnUnplugLevel; 522 int mDischargeScreenOffUnplugLevel; 523 int mDischargeAmountScreenOn; 524 int mDischargeAmountScreenOnSinceCharge; 525 int mDischargeAmountScreenOff; 526 int mDischargeAmountScreenOffSinceCharge; 527 528 private LongSamplingCounter mDischargeScreenOffCounter; 529 private LongSamplingCounter mDischargeCounter; 530 531 static final int MAX_LEVEL_STEPS = 200; 532 533 int mInitStepMode = 0; 534 int mCurStepMode = 0; 535 int mModStepMode = 0; 536 537 int mLastDischargeStepLevel; 538 int mMinDischargeStepLevel; 539 final LevelStepTracker mDischargeStepTracker = new LevelStepTracker(MAX_LEVEL_STEPS); 540 final LevelStepTracker mDailyDischargeStepTracker = new LevelStepTracker(MAX_LEVEL_STEPS*2); 541 ArrayList<PackageChange> mDailyPackageChanges; 542 543 int mLastChargeStepLevel; 544 int mMaxChargeStepLevel; 545 final LevelStepTracker mChargeStepTracker = new LevelStepTracker(MAX_LEVEL_STEPS); 546 final LevelStepTracker mDailyChargeStepTracker = new LevelStepTracker(MAX_LEVEL_STEPS*2); 547 548 static final int MAX_DAILY_ITEMS = 10; 549 550 long mDailyStartTime = 0; 551 long mNextMinDailyDeadline = 0; 552 long mNextMaxDailyDeadline = 0; 553 554 final ArrayList<DailyItem> mDailyItems = new ArrayList<>(); 555 556 long mLastWriteTime = 0; // Milliseconds 557 558 private int mPhoneServiceState = -1; 559 private int mPhoneServiceStateRaw = -1; 560 private int mPhoneSimStateRaw = -1; 561 562 private int mNumConnectivityChange; 563 private int mLoadedNumConnectivityChange; 564 private int mUnpluggedNumConnectivityChange; 565 566 private int mEstimatedBatteryCapacity = -1; 567 568 // Last learned capacity reported by BatteryService in 569 // setBatteryState(). 570 private int mLastChargeFullUAh = 0; 571 572 private final NetworkStats.Entry mTmpNetworkStatsEntry = new NetworkStats.Entry(); 573 574 private PowerProfile mPowerProfile; 575 576 /* 577 * Holds a SamplingTimer associated with each kernel wakelock name being tracked. 578 */ 579 private final HashMap<String, SamplingTimer> mKernelWakelockStats = new HashMap<>(); 580 581 public Map<String, ? extends Timer> getKernelWakelockStats() { 582 return mKernelWakelockStats; 583 } 584 585 String mLastWakeupReason = null; 586 long mLastWakeupUptimeMs = 0; 587 private final HashMap<String, SamplingTimer> mWakeupReasonStats = new HashMap<>(); 588 589 public Map<String, ? extends Timer> getWakeupReasonStats() { 590 return mWakeupReasonStats; 591 } 592 593 @Override 594 public LongCounter getDischargeScreenOffCoulombCounter() { 595 return mDischargeScreenOffCounter; 596 } 597 598 @Override 599 public LongCounter getDischargeCoulombCounter() { 600 return mDischargeCounter; 601 } 602 603 @Override 604 public int getEstimatedBatteryCapacity() { 605 return mEstimatedBatteryCapacity; 606 } 607 608 public BatteryStatsImpl() { 609 this(new SystemClocks()); 610 } 611 612 public BatteryStatsImpl(Clocks clocks) { 613 init(clocks); 614 mFile = null; 615 mCheckinFile = null; 616 mDailyFile = null; 617 mHandler = null; 618 mExternalSync = null; 619 mPlatformIdleStateCallback = null; 620 clearHistoryLocked(); 621 } 622 623 private void init(Clocks clocks) { 624 mClocks = clocks; 625 mMobileNetworkStats = new NetworkStats[] { 626 new NetworkStats(mClocks.elapsedRealtime(), 50), 627 new NetworkStats(mClocks.elapsedRealtime(), 50), 628 new NetworkStats(mClocks.elapsedRealtime(), 50) 629 }; 630 mWifiNetworkStats = new NetworkStats[] { 631 new NetworkStats(mClocks.elapsedRealtime(), 50), 632 new NetworkStats(mClocks.elapsedRealtime(), 50), 633 new NetworkStats(mClocks.elapsedRealtime(), 50) 634 }; 635 } 636 637 public static interface TimeBaseObs { 638 void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime); 639 void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime); 640 } 641 642 // methods are protected not private to be VisibleForTesting 643 public static class TimeBase { 644 protected final ArrayList<TimeBaseObs> mObservers = new ArrayList<>(); 645 646 protected long mUptime; 647 protected long mRealtime; 648 649 protected boolean mRunning; 650 651 protected long mPastUptime; 652 protected long mUptimeStart; 653 protected long mPastRealtime; 654 protected long mRealtimeStart; 655 protected long mUnpluggedUptime; 656 protected long mUnpluggedRealtime; 657 658 public void dump(PrintWriter pw, String prefix) { 659 StringBuilder sb = new StringBuilder(128); 660 pw.print(prefix); pw.print("mRunning="); pw.println(mRunning); 661 sb.setLength(0); 662 sb.append(prefix); 663 sb.append("mUptime="); 664 formatTimeMs(sb, mUptime / 1000); 665 pw.println(sb.toString()); 666 sb.setLength(0); 667 sb.append(prefix); 668 sb.append("mRealtime="); 669 formatTimeMs(sb, mRealtime / 1000); 670 pw.println(sb.toString()); 671 sb.setLength(0); 672 sb.append(prefix); 673 sb.append("mPastUptime="); 674 formatTimeMs(sb, mPastUptime / 1000); sb.append("mUptimeStart="); 675 formatTimeMs(sb, mUptimeStart / 1000); 676 sb.append("mUnpluggedUptime="); formatTimeMs(sb, mUnpluggedUptime / 1000); 677 pw.println(sb.toString()); 678 sb.setLength(0); 679 sb.append(prefix); 680 sb.append("mPastRealtime="); 681 formatTimeMs(sb, mPastRealtime / 1000); sb.append("mRealtimeStart="); 682 formatTimeMs(sb, mRealtimeStart / 1000); 683 sb.append("mUnpluggedRealtime="); formatTimeMs(sb, mUnpluggedRealtime / 1000); 684 pw.println(sb.toString()); 685 } 686 687 public void add(TimeBaseObs observer) { 688 mObservers.add(observer); 689 } 690 691 public void remove(TimeBaseObs observer) { 692 if (!mObservers.remove(observer)) { 693 Slog.wtf(TAG, "Removed unknown observer: " + observer); 694 } 695 } 696 697 public boolean hasObserver(TimeBaseObs observer) { 698 return mObservers.contains(observer); 699 } 700 701 public void init(long uptime, long realtime) { 702 mRealtime = 0; 703 mUptime = 0; 704 mPastUptime = 0; 705 mPastRealtime = 0; 706 mUptimeStart = uptime; 707 mRealtimeStart = realtime; 708 mUnpluggedUptime = getUptime(mUptimeStart); 709 mUnpluggedRealtime = getRealtime(mRealtimeStart); 710 } 711 712 public void reset(long uptime, long realtime) { 713 if (!mRunning) { 714 mPastUptime = 0; 715 mPastRealtime = 0; 716 } else { 717 mUptimeStart = uptime; 718 mRealtimeStart = realtime; 719 // TODO: Since mUptimeStart was just reset and we are running, getUptime will 720 // just return mPastUptime. Also, are we sure we don't want to reset that? 721 mUnpluggedUptime = getUptime(uptime); 722 // TODO: likewise. 723 mUnpluggedRealtime = getRealtime(realtime); 724 } 725 } 726 727 public long computeUptime(long curTime, int which) { 728 switch (which) { 729 case STATS_SINCE_CHARGED: 730 return mUptime + getUptime(curTime); 731 case STATS_CURRENT: 732 return getUptime(curTime); 733 case STATS_SINCE_UNPLUGGED: 734 return getUptime(curTime) - mUnpluggedUptime; 735 } 736 return 0; 737 } 738 739 public long computeRealtime(long curTime, int which) { 740 switch (which) { 741 case STATS_SINCE_CHARGED: 742 return mRealtime + getRealtime(curTime); 743 case STATS_CURRENT: 744 return getRealtime(curTime); 745 case STATS_SINCE_UNPLUGGED: 746 return getRealtime(curTime) - mUnpluggedRealtime; 747 } 748 return 0; 749 } 750 751 public long getUptime(long curTime) { 752 long time = mPastUptime; 753 if (mRunning) { 754 time += curTime - mUptimeStart; 755 } 756 return time; 757 } 758 759 public long getRealtime(long curTime) { 760 long time = mPastRealtime; 761 if (mRunning) { 762 time += curTime - mRealtimeStart; 763 } 764 return time; 765 } 766 767 public long getUptimeStart() { 768 return mUptimeStart; 769 } 770 771 public long getRealtimeStart() { 772 return mRealtimeStart; 773 } 774 775 public boolean isRunning() { 776 return mRunning; 777 } 778 779 public boolean setRunning(boolean running, long uptime, long realtime) { 780 if (mRunning != running) { 781 mRunning = running; 782 if (running) { 783 mUptimeStart = uptime; 784 mRealtimeStart = realtime; 785 long batteryUptime = mUnpluggedUptime = getUptime(uptime); 786 long batteryRealtime = mUnpluggedRealtime = getRealtime(realtime); 787 788 for (int i = mObservers.size() - 1; i >= 0; i--) { 789 mObservers.get(i).onTimeStarted(realtime, batteryUptime, batteryRealtime); 790 } 791 } else { 792 mPastUptime += uptime - mUptimeStart; 793 mPastRealtime += realtime - mRealtimeStart; 794 795 long batteryUptime = getUptime(uptime); 796 long batteryRealtime = getRealtime(realtime); 797 798 for (int i = mObservers.size() - 1; i >= 0; i--) { 799 mObservers.get(i).onTimeStopped(realtime, batteryUptime, batteryRealtime); 800 } 801 } 802 return true; 803 } 804 return false; 805 } 806 807 public void readSummaryFromParcel(Parcel in) { 808 mUptime = in.readLong(); 809 mRealtime = in.readLong(); 810 } 811 812 public void writeSummaryToParcel(Parcel out, long uptime, long realtime) { 813 out.writeLong(computeUptime(uptime, STATS_SINCE_CHARGED)); 814 out.writeLong(computeRealtime(realtime, STATS_SINCE_CHARGED)); 815 } 816 817 public void readFromParcel(Parcel in) { 818 mRunning = false; 819 mUptime = in.readLong(); 820 mPastUptime = in.readLong(); 821 mUptimeStart = in.readLong(); 822 mRealtime = in.readLong(); 823 mPastRealtime = in.readLong(); 824 mRealtimeStart = in.readLong(); 825 mUnpluggedUptime = in.readLong(); 826 mUnpluggedRealtime = in.readLong(); 827 } 828 829 public void writeToParcel(Parcel out, long uptime, long realtime) { 830 final long runningUptime = getUptime(uptime); 831 final long runningRealtime = getRealtime(realtime); 832 out.writeLong(mUptime); 833 out.writeLong(runningUptime); 834 out.writeLong(mUptimeStart); 835 out.writeLong(mRealtime); 836 out.writeLong(runningRealtime); 837 out.writeLong(mRealtimeStart); 838 out.writeLong(mUnpluggedUptime); 839 out.writeLong(mUnpluggedRealtime); 840 } 841 } 842 843 /** 844 * State for keeping track of counting information. 845 */ 846 public static class Counter extends BatteryStats.Counter implements TimeBaseObs { 847 final AtomicInteger mCount = new AtomicInteger(); 848 final TimeBase mTimeBase; 849 int mLoadedCount; 850 int mLastCount; 851 int mUnpluggedCount; 852 int mPluggedCount; 853 854 Counter(TimeBase timeBase, Parcel in) { 855 mTimeBase = timeBase; 856 mPluggedCount = in.readInt(); 857 mCount.set(mPluggedCount); 858 mLoadedCount = in.readInt(); 859 mLastCount = 0; 860 mUnpluggedCount = in.readInt(); 861 timeBase.add(this); 862 } 863 864 Counter(TimeBase timeBase) { 865 mTimeBase = timeBase; 866 timeBase.add(this); 867 } 868 869 public void writeToParcel(Parcel out) { 870 out.writeInt(mCount.get()); 871 out.writeInt(mLoadedCount); 872 out.writeInt(mUnpluggedCount); 873 } 874 875 public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) { 876 mUnpluggedCount = mPluggedCount; 877 mCount.set(mPluggedCount); 878 } 879 880 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) { 881 mPluggedCount = mCount.get(); 882 } 883 884 /** 885 * Writes a possibly null Counter to a Parcel. 886 * 887 * @param out the Parcel to be written to. 888 * @param counter a Counter, or null. 889 */ 890 public static void writeCounterToParcel(Parcel out, Counter counter) { 891 if (counter == null) { 892 out.writeInt(0); // indicates null 893 return; 894 } 895 out.writeInt(1); // indicates non-null 896 897 counter.writeToParcel(out); 898 } 899 900 @Override 901 public int getCountLocked(int which) { 902 int val = mCount.get(); 903 if (which == STATS_SINCE_UNPLUGGED) { 904 val -= mUnpluggedCount; 905 } else if (which != STATS_SINCE_CHARGED) { 906 val -= mLoadedCount; 907 } 908 909 return val; 910 } 911 912 public void logState(Printer pw, String prefix) { 913 pw.println(prefix + "mCount=" + mCount.get() 914 + " mLoadedCount=" + mLoadedCount + " mLastCount=" + mLastCount 915 + " mUnpluggedCount=" + mUnpluggedCount 916 + " mPluggedCount=" + mPluggedCount); 917 } 918 919 void stepAtomic() { 920 mCount.incrementAndGet(); 921 } 922 923 /** 924 * Clear state of this counter. 925 */ 926 void reset(boolean detachIfReset) { 927 mCount.set(0); 928 mLoadedCount = mLastCount = mPluggedCount = mUnpluggedCount = 0; 929 if (detachIfReset) { 930 detach(); 931 } 932 } 933 934 void detach() { 935 mTimeBase.remove(this); 936 } 937 938 void writeSummaryFromParcelLocked(Parcel out) { 939 int count = mCount.get(); 940 out.writeInt(count); 941 } 942 943 void readSummaryFromParcelLocked(Parcel in) { 944 mLoadedCount = in.readInt(); 945 mCount.set(mLoadedCount); 946 mLastCount = 0; 947 mUnpluggedCount = mPluggedCount = mLoadedCount; 948 } 949 } 950 951 public static class LongSamplingCounter extends LongCounter implements TimeBaseObs { 952 final TimeBase mTimeBase; 953 long mCount; 954 long mLoadedCount; 955 long mUnpluggedCount; 956 long mPluggedCount; 957 958 LongSamplingCounter(TimeBase timeBase, Parcel in) { 959 mTimeBase = timeBase; 960 mPluggedCount = in.readLong(); 961 mCount = mPluggedCount; 962 mLoadedCount = in.readLong(); 963 mUnpluggedCount = in.readLong(); 964 timeBase.add(this); 965 } 966 967 LongSamplingCounter(TimeBase timeBase) { 968 mTimeBase = timeBase; 969 timeBase.add(this); 970 } 971 972 public void writeToParcel(Parcel out) { 973 out.writeLong(mCount); 974 out.writeLong(mLoadedCount); 975 out.writeLong(mUnpluggedCount); 976 } 977 978 @Override 979 public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) { 980 mUnpluggedCount = mPluggedCount; 981 mCount = mPluggedCount; 982 } 983 984 @Override 985 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) { 986 mPluggedCount = mCount; 987 } 988 989 public long getCountLocked(int which) { 990 long val = mTimeBase.isRunning() ? mCount : mPluggedCount; 991 if (which == STATS_SINCE_UNPLUGGED) { 992 val -= mUnpluggedCount; 993 } else if (which != STATS_SINCE_CHARGED) { 994 val -= mLoadedCount; 995 } 996 return val; 997 } 998 999 @Override 1000 public void logState(Printer pw, String prefix) { 1001 pw.println(prefix + "mCount=" + mCount 1002 + " mLoadedCount=" + mLoadedCount 1003 + " mUnpluggedCount=" + mUnpluggedCount 1004 + " mPluggedCount=" + mPluggedCount); 1005 } 1006 1007 void addCountLocked(long count) { 1008 mCount += count; 1009 } 1010 1011 /** 1012 * Clear state of this counter. 1013 */ 1014 void reset(boolean detachIfReset) { 1015 mCount = 0; 1016 mLoadedCount = mPluggedCount = mUnpluggedCount = 0; 1017 if (detachIfReset) { 1018 detach(); 1019 } 1020 } 1021 1022 void detach() { 1023 mTimeBase.remove(this); 1024 } 1025 1026 void writeSummaryFromParcelLocked(Parcel out) { 1027 out.writeLong(mCount); 1028 } 1029 1030 void readSummaryFromParcelLocked(Parcel in) { 1031 mLoadedCount = in.readLong(); 1032 mCount = mLoadedCount; 1033 mUnpluggedCount = mPluggedCount = mLoadedCount; 1034 } 1035 } 1036 1037 /** 1038 * State for keeping track of timing information. 1039 */ 1040 public static abstract class Timer extends BatteryStats.Timer implements TimeBaseObs { 1041 protected final Clocks mClocks; 1042 protected final int mType; 1043 protected final TimeBase mTimeBase; 1044 1045 protected int mCount; 1046 protected int mLoadedCount; 1047 protected int mLastCount; 1048 protected int mUnpluggedCount; 1049 1050 // Times are in microseconds for better accuracy when dividing by the 1051 // lock count, and are in "battery realtime" units. 1052 1053 /** 1054 * The total time we have accumulated since the start of the original 1055 * boot, to the last time something interesting happened in the 1056 * current run. 1057 */ 1058 protected long mTotalTime; 1059 1060 /** 1061 * The total time we loaded for the previous runs. Subtract this from 1062 * mTotalTime to find the time for the current run of the system. 1063 */ 1064 protected long mLoadedTime; 1065 1066 /** 1067 * The run time of the last run of the system, as loaded from the 1068 * saved data. 1069 */ 1070 protected long mLastTime; 1071 1072 /** 1073 * The value of mTotalTime when unplug() was last called. Subtract 1074 * this from mTotalTime to find the time since the last unplug from 1075 * power. 1076 */ 1077 protected long mUnpluggedTime; 1078 1079 /** 1080 * The total time this timer has been running until the latest mark has been set. 1081 * Subtract this from mTotalTime to get the time spent running since the mark was set. 1082 */ 1083 protected long mTimeBeforeMark; 1084 1085 /** 1086 * Constructs from a parcel. 1087 * @param type 1088 * @param timeBase 1089 * @param in 1090 */ 1091 public Timer(Clocks clocks, int type, TimeBase timeBase, Parcel in) { 1092 mClocks = clocks; 1093 mType = type; 1094 mTimeBase = timeBase; 1095 1096 mCount = in.readInt(); 1097 mLoadedCount = in.readInt(); 1098 mLastCount = 0; 1099 mUnpluggedCount = in.readInt(); 1100 mTotalTime = in.readLong(); 1101 mLoadedTime = in.readLong(); 1102 mLastTime = 0; 1103 mUnpluggedTime = in.readLong(); 1104 mTimeBeforeMark = in.readLong(); 1105 timeBase.add(this); 1106 if (DEBUG) Log.i(TAG, "**** READ TIMER #" + mType + ": mTotalTime=" + mTotalTime); 1107 } 1108 1109 public Timer(Clocks clocks, int type, TimeBase timeBase) { 1110 mClocks = clocks; 1111 mType = type; 1112 mTimeBase = timeBase; 1113 timeBase.add(this); 1114 } 1115 1116 protected abstract long computeRunTimeLocked(long curBatteryRealtime); 1117 1118 protected abstract int computeCurrentCountLocked(); 1119 1120 /** 1121 * Clear state of this timer. Returns true if the timer is inactive 1122 * so can be completely dropped. 1123 */ 1124 public boolean reset(boolean detachIfReset) { 1125 mTotalTime = mLoadedTime = mLastTime = mTimeBeforeMark = 0; 1126 mCount = mLoadedCount = mLastCount = 0; 1127 if (detachIfReset) { 1128 detach(); 1129 } 1130 return true; 1131 } 1132 1133 public void detach() { 1134 mTimeBase.remove(this); 1135 } 1136 1137 public void writeToParcel(Parcel out, long elapsedRealtimeUs) { 1138 if (DEBUG) Log.i(TAG, "**** WRITING TIMER #" + mType + ": mTotalTime=" 1139 + computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs))); 1140 out.writeInt(computeCurrentCountLocked()); 1141 out.writeInt(mLoadedCount); 1142 out.writeInt(mUnpluggedCount); 1143 out.writeLong(computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs))); 1144 out.writeLong(mLoadedTime); 1145 out.writeLong(mUnpluggedTime); 1146 out.writeLong(mTimeBeforeMark); 1147 } 1148 1149 @Override 1150 public void onTimeStarted(long elapsedRealtime, long timeBaseUptime, long baseRealtime) { 1151 if (DEBUG && mType < 0) { 1152 Log.v(TAG, "unplug #" + mType + ": realtime=" + baseRealtime 1153 + " old mUnpluggedTime=" + mUnpluggedTime 1154 + " old mUnpluggedCount=" + mUnpluggedCount); 1155 } 1156 mUnpluggedTime = computeRunTimeLocked(baseRealtime); 1157 mUnpluggedCount = computeCurrentCountLocked(); 1158 if (DEBUG && mType < 0) { 1159 Log.v(TAG, "unplug #" + mType 1160 + ": new mUnpluggedTime=" + mUnpluggedTime 1161 + " new mUnpluggedCount=" + mUnpluggedCount); 1162 } 1163 } 1164 1165 @Override 1166 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) { 1167 if (DEBUG && mType < 0) { 1168 Log.v(TAG, "plug #" + mType + ": realtime=" + baseRealtime 1169 + " old mTotalTime=" + mTotalTime); 1170 } 1171 mTotalTime = computeRunTimeLocked(baseRealtime); 1172 mCount = computeCurrentCountLocked(); 1173 if (DEBUG && mType < 0) { 1174 Log.v(TAG, "plug #" + mType 1175 + ": new mTotalTime=" + mTotalTime); 1176 } 1177 } 1178 1179 /** 1180 * Writes a possibly null Timer to a Parcel. 1181 * 1182 * @param out the Parcel to be written to. 1183 * @param timer a Timer, or null. 1184 */ 1185 public static void writeTimerToParcel(Parcel out, Timer timer, long elapsedRealtimeUs) { 1186 if (timer == null) { 1187 out.writeInt(0); // indicates null 1188 return; 1189 } 1190 out.writeInt(1); // indicates non-null 1191 1192 timer.writeToParcel(out, elapsedRealtimeUs); 1193 } 1194 1195 @Override 1196 public long getTotalTimeLocked(long elapsedRealtimeUs, int which) { 1197 long val = computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs)); 1198 if (which == STATS_SINCE_UNPLUGGED) { 1199 val -= mUnpluggedTime; 1200 } else if (which != STATS_SINCE_CHARGED) { 1201 val -= mLoadedTime; 1202 } 1203 1204 return val; 1205 } 1206 1207 @Override 1208 public int getCountLocked(int which) { 1209 int val = computeCurrentCountLocked(); 1210 if (which == STATS_SINCE_UNPLUGGED) { 1211 val -= mUnpluggedCount; 1212 } else if (which != STATS_SINCE_CHARGED) { 1213 val -= mLoadedCount; 1214 } 1215 1216 return val; 1217 } 1218 1219 @Override 1220 public long getTimeSinceMarkLocked(long elapsedRealtimeUs) { 1221 long val = computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs)); 1222 return val - mTimeBeforeMark; 1223 } 1224 1225 @Override 1226 public void logState(Printer pw, String prefix) { 1227 pw.println(prefix + "mCount=" + mCount 1228 + " mLoadedCount=" + mLoadedCount + " mLastCount=" + mLastCount 1229 + " mUnpluggedCount=" + mUnpluggedCount); 1230 pw.println(prefix + "mTotalTime=" + mTotalTime 1231 + " mLoadedTime=" + mLoadedTime); 1232 pw.println(prefix + "mLastTime=" + mLastTime 1233 + " mUnpluggedTime=" + mUnpluggedTime); 1234 } 1235 1236 1237 public void writeSummaryFromParcelLocked(Parcel out, long elapsedRealtimeUs) { 1238 long runTime = computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs)); 1239 out.writeLong(runTime); 1240 out.writeInt(computeCurrentCountLocked()); 1241 } 1242 1243 public void readSummaryFromParcelLocked(Parcel in) { 1244 // Multiply by 1000 for backwards compatibility 1245 mTotalTime = mLoadedTime = in.readLong(); 1246 mLastTime = 0; 1247 mUnpluggedTime = mTotalTime; 1248 mCount = mLoadedCount = in.readInt(); 1249 mLastCount = 0; 1250 mUnpluggedCount = mCount; 1251 1252 // When reading the summary, we set the mark to be the latest information. 1253 mTimeBeforeMark = mTotalTime; 1254 } 1255 } 1256 1257 /** 1258 * A counter meant to accept monotonically increasing values to its {@link #update(long, int)} 1259 * method. The state of the timer according to its {@link TimeBase} will determine how much 1260 * of the value is recorded. 1261 * 1262 * If the value being recorded resets, {@link #endSample()} can be called in order to 1263 * account for the change. If the value passed in to {@link #update(long, int)} decreased 1264 * between calls, the {@link #endSample()} is automatically called and the new value is 1265 * expected to increase monotonically from that point on. 1266 */ 1267 public static class SamplingTimer extends Timer { 1268 1269 /** 1270 * The most recent reported count from /proc/wakelocks. 1271 */ 1272 int mCurrentReportedCount; 1273 1274 /** 1275 * The reported count from /proc/wakelocks when unplug() was last 1276 * called. 1277 */ 1278 int mUnpluggedReportedCount; 1279 1280 /** 1281 * The most recent reported total_time from /proc/wakelocks. 1282 */ 1283 long mCurrentReportedTotalTime; 1284 1285 1286 /** 1287 * The reported total_time from /proc/wakelocks when unplug() was last 1288 * called. 1289 */ 1290 long mUnpluggedReportedTotalTime; 1291 1292 /** 1293 * Whether we are currently in a discharge cycle. 1294 */ 1295 boolean mTimeBaseRunning; 1296 1297 /** 1298 * Whether we are currently recording reported values. 1299 */ 1300 boolean mTrackingReportedValues; 1301 1302 /* 1303 * A sequence counter, incremented once for each update of the stats. 1304 */ 1305 int mUpdateVersion; 1306 1307 @VisibleForTesting 1308 public SamplingTimer(Clocks clocks, TimeBase timeBase, Parcel in) { 1309 super(clocks, 0, timeBase, in); 1310 mCurrentReportedCount = in.readInt(); 1311 mUnpluggedReportedCount = in.readInt(); 1312 mCurrentReportedTotalTime = in.readLong(); 1313 mUnpluggedReportedTotalTime = in.readLong(); 1314 mTrackingReportedValues = in.readInt() == 1; 1315 mTimeBaseRunning = timeBase.isRunning(); 1316 } 1317 1318 @VisibleForTesting 1319 public SamplingTimer(Clocks clocks, TimeBase timeBase) { 1320 super(clocks, 0, timeBase); 1321 mTrackingReportedValues = false; 1322 mTimeBaseRunning = timeBase.isRunning(); 1323 } 1324 1325 /** 1326 * Ends the current sample, allowing subsequent values to {@link #update(long, int)} to 1327 * be less than the values used for a previous invocation. 1328 */ 1329 public void endSample() { 1330 mTotalTime = computeRunTimeLocked(0 /* unused by us */); 1331 mCount = computeCurrentCountLocked(); 1332 mUnpluggedReportedTotalTime = mCurrentReportedTotalTime = 0; 1333 mUnpluggedReportedCount = mCurrentReportedCount = 0; 1334 } 1335 1336 public void setUpdateVersion(int version) { 1337 mUpdateVersion = version; 1338 } 1339 1340 public int getUpdateVersion() { 1341 return mUpdateVersion; 1342 } 1343 1344 /** 1345 * Updates the current recorded values. These are meant to be monotonically increasing 1346 * and cumulative. If you are dealing with deltas, use {@link #add(long, int)}. 1347 * 1348 * If the values being recorded have been reset, the monotonically increasing requirement 1349 * will be broken. In this case, {@link #endSample()} is automatically called and 1350 * the total value of totalTime and count are recorded, starting a new monotonically 1351 * increasing sample. 1352 * 1353 * @param totalTime total time of sample in microseconds. 1354 * @param count total number of times the event being sampled occurred. 1355 */ 1356 public void update(long totalTime, int count) { 1357 if (mTimeBaseRunning && !mTrackingReportedValues) { 1358 // Updating the reported value for the first time. 1359 mUnpluggedReportedTotalTime = totalTime; 1360 mUnpluggedReportedCount = count; 1361 } 1362 1363 mTrackingReportedValues = true; 1364 1365 if (totalTime < mCurrentReportedTotalTime || count < mCurrentReportedCount) { 1366 endSample(); 1367 } 1368 1369 mCurrentReportedTotalTime = totalTime; 1370 mCurrentReportedCount = count; 1371 } 1372 1373 /** 1374 * Adds deltaTime and deltaCount to the current sample. 1375 * 1376 * @param deltaTime additional time recorded since the last sampled event, in microseconds. 1377 * @param deltaCount additional number of times the event being sampled occurred. 1378 */ 1379 public void add(long deltaTime, int deltaCount) { 1380 update(mCurrentReportedTotalTime + deltaTime, mCurrentReportedCount + deltaCount); 1381 } 1382 1383 @Override 1384 public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) { 1385 super.onTimeStarted(elapsedRealtime, baseUptime, baseRealtime); 1386 if (mTrackingReportedValues) { 1387 mUnpluggedReportedTotalTime = mCurrentReportedTotalTime; 1388 mUnpluggedReportedCount = mCurrentReportedCount; 1389 } 1390 mTimeBaseRunning = true; 1391 } 1392 1393 @Override 1394 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) { 1395 super.onTimeStopped(elapsedRealtime, baseUptime, baseRealtime); 1396 mTimeBaseRunning = false; 1397 } 1398 1399 @Override 1400 public void logState(Printer pw, String prefix) { 1401 super.logState(pw, prefix); 1402 pw.println(prefix + "mCurrentReportedCount=" + mCurrentReportedCount 1403 + " mUnpluggedReportedCount=" + mUnpluggedReportedCount 1404 + " mCurrentReportedTotalTime=" + mCurrentReportedTotalTime 1405 + " mUnpluggedReportedTotalTime=" + mUnpluggedReportedTotalTime); 1406 } 1407 1408 @Override 1409 protected long computeRunTimeLocked(long curBatteryRealtime) { 1410 return mTotalTime + (mTimeBaseRunning && mTrackingReportedValues 1411 ? mCurrentReportedTotalTime - mUnpluggedReportedTotalTime : 0); 1412 } 1413 1414 @Override 1415 protected int computeCurrentCountLocked() { 1416 return mCount + (mTimeBaseRunning && mTrackingReportedValues 1417 ? mCurrentReportedCount - mUnpluggedReportedCount : 0); 1418 } 1419 1420 @Override 1421 public void writeToParcel(Parcel out, long elapsedRealtimeUs) { 1422 super.writeToParcel(out, elapsedRealtimeUs); 1423 out.writeInt(mCurrentReportedCount); 1424 out.writeInt(mUnpluggedReportedCount); 1425 out.writeLong(mCurrentReportedTotalTime); 1426 out.writeLong(mUnpluggedReportedTotalTime); 1427 out.writeInt(mTrackingReportedValues ? 1 : 0); 1428 } 1429 1430 @Override 1431 public boolean reset(boolean detachIfReset) { 1432 super.reset(detachIfReset); 1433 mTrackingReportedValues = false; 1434 mUnpluggedReportedTotalTime = 0; 1435 mUnpluggedReportedCount = 0; 1436 return true; 1437 } 1438 } 1439 1440 /** 1441 * A timer that increments in batches. It does not run for durations, but just jumps 1442 * for a pre-determined amount. 1443 */ 1444 public static class BatchTimer extends Timer { 1445 final Uid mUid; 1446 1447 /** 1448 * The last time at which we updated the timer. This is in elapsed realtime microseconds. 1449 */ 1450 long mLastAddedTime; 1451 1452 /** 1453 * The last duration that we added to the timer. This is in microseconds. 1454 */ 1455 long mLastAddedDuration; 1456 1457 /** 1458 * Whether we are currently in a discharge cycle. 1459 */ 1460 boolean mInDischarge; 1461 1462 BatchTimer(Clocks clocks, Uid uid, int type, TimeBase timeBase, Parcel in) { 1463 super(clocks, type, timeBase, in); 1464 mUid = uid; 1465 mLastAddedTime = in.readLong(); 1466 mLastAddedDuration = in.readLong(); 1467 mInDischarge = timeBase.isRunning(); 1468 } 1469 1470 BatchTimer(Clocks clocks, Uid uid, int type, TimeBase timeBase) { 1471 super(clocks, type, timeBase); 1472 mUid = uid; 1473 mInDischarge = timeBase.isRunning(); 1474 } 1475 1476 @Override 1477 public void writeToParcel(Parcel out, long elapsedRealtimeUs) { 1478 super.writeToParcel(out, elapsedRealtimeUs); 1479 out.writeLong(mLastAddedTime); 1480 out.writeLong(mLastAddedDuration); 1481 } 1482 1483 @Override 1484 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) { 1485 recomputeLastDuration(mClocks.elapsedRealtime() * 1000, false); 1486 mInDischarge = false; 1487 super.onTimeStopped(elapsedRealtime, baseUptime, baseRealtime); 1488 } 1489 1490 @Override 1491 public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) { 1492 recomputeLastDuration(elapsedRealtime, false); 1493 mInDischarge = true; 1494 // If we are still within the last added duration, then re-added whatever remains. 1495 if (mLastAddedTime == elapsedRealtime) { 1496 mTotalTime += mLastAddedDuration; 1497 } 1498 super.onTimeStarted(elapsedRealtime, baseUptime, baseRealtime); 1499 } 1500 1501 @Override 1502 public void logState(Printer pw, String prefix) { 1503 super.logState(pw, prefix); 1504 pw.println(prefix + "mLastAddedTime=" + mLastAddedTime 1505 + " mLastAddedDuration=" + mLastAddedDuration); 1506 } 1507 1508 private long computeOverage(long curTime) { 1509 if (mLastAddedTime > 0) { 1510 return mLastTime + mLastAddedDuration - curTime; 1511 } 1512 return 0; 1513 } 1514 1515 private void recomputeLastDuration(long curTime, boolean abort) { 1516 final long overage = computeOverage(curTime); 1517 if (overage > 0) { 1518 // Aborting before the duration ran out -- roll back the remaining 1519 // duration. Only do this if currently discharging; otherwise we didn't 1520 // actually add the time. 1521 if (mInDischarge) { 1522 mTotalTime -= overage; 1523 } 1524 if (abort) { 1525 mLastAddedTime = 0; 1526 } else { 1527 mLastAddedTime = curTime; 1528 mLastAddedDuration -= overage; 1529 } 1530 } 1531 } 1532 1533 public void addDuration(BatteryStatsImpl stats, long durationMillis) { 1534 final long now = mClocks.elapsedRealtime() * 1000; 1535 recomputeLastDuration(now, true); 1536 mLastAddedTime = now; 1537 mLastAddedDuration = durationMillis * 1000; 1538 if (mInDischarge) { 1539 mTotalTime += mLastAddedDuration; 1540 mCount++; 1541 } 1542 } 1543 1544 public void abortLastDuration(BatteryStatsImpl stats) { 1545 final long now = mClocks.elapsedRealtime() * 1000; 1546 recomputeLastDuration(now, true); 1547 } 1548 1549 @Override 1550 protected int computeCurrentCountLocked() { 1551 return mCount; 1552 } 1553 1554 @Override 1555 protected long computeRunTimeLocked(long curBatteryRealtime) { 1556 final long overage = computeOverage(mClocks.elapsedRealtime() * 1000); 1557 if (overage > 0) { 1558 return mTotalTime = overage; 1559 } 1560 return mTotalTime; 1561 } 1562 1563 @Override 1564 public boolean reset(boolean detachIfReset) { 1565 final long now = mClocks.elapsedRealtime() * 1000; 1566 recomputeLastDuration(now, true); 1567 boolean stillActive = mLastAddedTime == now; 1568 super.reset(!stillActive && detachIfReset); 1569 return !stillActive; 1570 } 1571 } 1572 1573 1574 /** 1575 * A StopwatchTimer that also tracks the total and max individual 1576 * time spent active according to the given timebase. Whereas 1577 * StopwatchTimer apportions the time amongst all in the pool, 1578 * the total and max durations are not apportioned. 1579 */ 1580 public static class DurationTimer extends StopwatchTimer { 1581 /** 1582 * The time (in ms) that the timer was last acquired or the time base 1583 * last (re-)started. Increasing the nesting depth does not reset this time. 1584 * 1585 * -1 if the timer is currently not running or the time base is not running. 1586 * 1587 * If written to a parcel, the start time is reset, as is mNesting in the base class 1588 * StopwatchTimer. 1589 */ 1590 long mStartTimeMs = -1; 1591 1592 /** 1593 * The longest time period (in ms) that the timer has been active. Not pooled. 1594 */ 1595 long mMaxDurationMs; 1596 1597 /** 1598 * The time (in ms) that that the timer has been active since most recent 1599 * stopRunningLocked() or reset(). Not pooled. 1600 */ 1601 long mCurrentDurationMs; 1602 1603 /** 1604 * The total time (in ms) that that the timer has been active since most recent reset() 1605 * prior to the current startRunningLocked. This is the sum of all past currentDurations 1606 * (but not including the present currentDuration) since reset. Not pooled. 1607 */ 1608 long mTotalDurationMs; 1609 1610 public DurationTimer(Clocks clocks, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, 1611 TimeBase timeBase, Parcel in) { 1612 super(clocks, uid, type, timerPool, timeBase, in); 1613 mMaxDurationMs = in.readLong(); 1614 mTotalDurationMs = in.readLong(); 1615 } 1616 1617 public DurationTimer(Clocks clocks, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, 1618 TimeBase timeBase) { 1619 super(clocks, uid, type, timerPool, timeBase); 1620 } 1621 1622 @Override 1623 public void writeToParcel(Parcel out, long elapsedRealtimeUs) { 1624 super.writeToParcel(out, elapsedRealtimeUs); 1625 out.writeLong(getMaxDurationMsLocked(elapsedRealtimeUs / 1000)); 1626 out.writeLong(getTotalDurationMsLocked(elapsedRealtimeUs / 1000)); 1627 } 1628 1629 /** 1630 * Write the summary to the parcel. 1631 * 1632 * Since the time base is probably meaningless after we come back, reading 1633 * from this will have the effect of stopping the timer. So here all we write 1634 * is the max and total durations. 1635 */ 1636 @Override 1637 public void writeSummaryFromParcelLocked(Parcel out, long elapsedRealtimeUs) { 1638 super.writeSummaryFromParcelLocked(out, elapsedRealtimeUs); 1639 out.writeLong(getMaxDurationMsLocked(elapsedRealtimeUs / 1000)); 1640 out.writeLong(getTotalDurationMsLocked(elapsedRealtimeUs / 1000)); 1641 } 1642 1643 /** 1644 * Read the summary parcel. 1645 * 1646 * Has the side effect of stopping the timer. 1647 */ 1648 @Override 1649 public void readSummaryFromParcelLocked(Parcel in) { 1650 super.readSummaryFromParcelLocked(in); 1651 mMaxDurationMs = in.readLong(); 1652 mTotalDurationMs = in.readLong(); 1653 mStartTimeMs = -1; 1654 mCurrentDurationMs = 0; 1655 } 1656 1657 /** 1658 * The TimeBase time started (again). 1659 * 1660 * If the timer is also running, store the start time. 1661 */ 1662 public void onTimeStarted(long elapsedRealtimeUs, long baseUptime, long baseRealtime) { 1663 super.onTimeStarted(elapsedRealtimeUs, baseUptime, baseRealtime); 1664 if (mNesting > 0) { 1665 mStartTimeMs = baseRealtime / 1000; 1666 } 1667 } 1668 1669 /** 1670 * The TimeBase stopped running. 1671 * 1672 * If the timer is running, add the duration into mCurrentDurationMs. 1673 */ 1674 @Override 1675 public void onTimeStopped(long elapsedRealtimeUs, long baseUptime, long baseRealtimeUs) { 1676 super.onTimeStopped(elapsedRealtimeUs, baseUptime, baseRealtimeUs); 1677 if (mNesting > 0) { 1678 // baseRealtimeUs has already been converted to the timebase's realtime. 1679 mCurrentDurationMs += (baseRealtimeUs / 1000) - mStartTimeMs; 1680 } 1681 mStartTimeMs = -1; 1682 } 1683 1684 @Override 1685 public void logState(Printer pw, String prefix) { 1686 super.logState(pw, prefix); 1687 } 1688 1689 @Override 1690 public void startRunningLocked(long elapsedRealtimeMs) { 1691 super.startRunningLocked(elapsedRealtimeMs); 1692 if (mNesting == 1 && mTimeBase.isRunning()) { 1693 // Just started 1694 mStartTimeMs = mTimeBase.getRealtime(elapsedRealtimeMs * 1000) / 1000; 1695 } 1696 } 1697 1698 /** 1699 * Decrements the mNesting ref-count on this timer. 1700 * 1701 * If it actually stopped (mNesting went to 0), then possibly update 1702 * mMaxDuration if the current duration was the longest ever. 1703 */ 1704 @Override 1705 public void stopRunningLocked(long elapsedRealtimeMs) { 1706 if (mNesting == 1) { 1707 final long durationMs = getCurrentDurationMsLocked(elapsedRealtimeMs); 1708 mTotalDurationMs += durationMs; 1709 if (durationMs > mMaxDurationMs) { 1710 mMaxDurationMs = durationMs; 1711 } 1712 mStartTimeMs = -1; 1713 mCurrentDurationMs = 0; 1714 } 1715 // super method decrements mNesting, which getCurrentDurationMsLocked relies on, 1716 // so call super.stopRunningLocked after calling getCurrentDurationMsLocked. 1717 super.stopRunningLocked(elapsedRealtimeMs); 1718 } 1719 1720 @Override 1721 public boolean reset(boolean detachIfReset) { 1722 boolean result = super.reset(detachIfReset); 1723 mMaxDurationMs = 0; 1724 mTotalDurationMs = 0; 1725 mCurrentDurationMs = 0; 1726 if (mNesting > 0) { 1727 mStartTimeMs = mTimeBase.getRealtime(mClocks.elapsedRealtime()*1000) / 1000; 1728 } else { 1729 mStartTimeMs = -1; 1730 } 1731 return result; 1732 } 1733 1734 /** 1735 * Returns the max duration that this timer has ever seen. 1736 * 1737 * Note that this time is NOT split between the timers in the timer group that 1738 * this timer is attached to. It is the TOTAL time. 1739 */ 1740 @Override 1741 public long getMaxDurationMsLocked(long elapsedRealtimeMs) { 1742 if (mNesting > 0) { 1743 final long durationMs = getCurrentDurationMsLocked(elapsedRealtimeMs); 1744 if (durationMs > mMaxDurationMs) { 1745 return durationMs; 1746 } 1747 } 1748 return mMaxDurationMs; 1749 } 1750 1751 /** 1752 * Returns the time since the timer was started. 1753 * Returns 0 if the timer is not currently running. 1754 * 1755 * Note that this time is NOT split between the timers in the timer group that 1756 * this timer is attached to. It is the TOTAL time. 1757 */ 1758 @Override 1759 public long getCurrentDurationMsLocked(long elapsedRealtimeMs) { 1760 long durationMs = mCurrentDurationMs; 1761 if (mNesting > 0 && mTimeBase.isRunning()) { 1762 durationMs += (mTimeBase.getRealtime(elapsedRealtimeMs*1000)/1000) 1763 - mStartTimeMs; 1764 } 1765 return durationMs; 1766 } 1767 1768 /** 1769 * Returns the total cumulative duration that this timer has been on since reset(). 1770 * If mTimerPool == null, this should be the same 1771 * as getTotalTimeLocked(elapsedRealtimeMs*1000, STATS_SINCE_CHARGED)/1000. 1772 * 1773 * Note that this time is NOT split between the timers in the timer group that 1774 * this timer is attached to. It is the TOTAL time. For this reason, if mTimerPool != null, 1775 * the result will not be equivalent to getTotalTimeLocked. 1776 */ 1777 @Override 1778 public long getTotalDurationMsLocked(long elapsedRealtimeMs) { 1779 return mTotalDurationMs + getCurrentDurationMsLocked(elapsedRealtimeMs); 1780 } 1781 } 1782 1783 /** 1784 * State for keeping track of timing information. 1785 */ 1786 public static class StopwatchTimer extends Timer { 1787 final Uid mUid; 1788 final ArrayList<StopwatchTimer> mTimerPool; 1789 1790 int mNesting; 1791 1792 /** 1793 * The last time at which we updated the timer. If mNesting is > 0, 1794 * subtract this from the current battery time to find the amount of 1795 * time we have been running since we last computed an update. 1796 */ 1797 long mUpdateTime; 1798 1799 /** 1800 * The total time at which the timer was acquired, to determine if it 1801 * was actually held for an interesting duration. If time base was not running when timer 1802 * was acquired, will be -1. 1803 */ 1804 long mAcquireTime = -1; 1805 1806 long mTimeout; 1807 1808 /** 1809 * For partial wake locks, keep track of whether we are in the list 1810 * to consume CPU cycles. 1811 */ 1812 boolean mInList; 1813 1814 public StopwatchTimer(Clocks clocks, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, 1815 TimeBase timeBase, Parcel in) { 1816 super(clocks, type, timeBase, in); 1817 mUid = uid; 1818 mTimerPool = timerPool; 1819 mUpdateTime = in.readLong(); 1820 } 1821 1822 public StopwatchTimer(Clocks clocks, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, 1823 TimeBase timeBase) { 1824 super(clocks, type, timeBase); 1825 mUid = uid; 1826 mTimerPool = timerPool; 1827 } 1828 1829 public void setTimeout(long timeout) { 1830 mTimeout = timeout; 1831 } 1832 1833 public void writeToParcel(Parcel out, long elapsedRealtimeUs) { 1834 super.writeToParcel(out, elapsedRealtimeUs); 1835 out.writeLong(mUpdateTime); 1836 } 1837 1838 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) { 1839 if (mNesting > 0) { 1840 if (DEBUG && mType < 0) { 1841 Log.v(TAG, "old mUpdateTime=" + mUpdateTime); 1842 } 1843 super.onTimeStopped(elapsedRealtime, baseUptime, baseRealtime); 1844 mUpdateTime = baseRealtime; 1845 if (DEBUG && mType < 0) { 1846 Log.v(TAG, "new mUpdateTime=" + mUpdateTime); 1847 } 1848 } 1849 } 1850 1851 public void logState(Printer pw, String prefix) { 1852 super.logState(pw, prefix); 1853 pw.println(prefix + "mNesting=" + mNesting + " mUpdateTime=" + mUpdateTime 1854 + " mAcquireTime=" + mAcquireTime); 1855 } 1856 1857 public void startRunningLocked(long elapsedRealtimeMs) { 1858 if (mNesting++ == 0) { 1859 final long batteryRealtime = mTimeBase.getRealtime(elapsedRealtimeMs * 1000); 1860 mUpdateTime = batteryRealtime; 1861 if (mTimerPool != null) { 1862 // Accumulate time to all currently active timers before adding 1863 // this new one to the pool. 1864 refreshTimersLocked(batteryRealtime, mTimerPool, null); 1865 // Add this timer to the active pool 1866 mTimerPool.add(this); 1867 } 1868 if (mTimeBase.isRunning()) { 1869 // Increment the count 1870 mCount++; 1871 mAcquireTime = mTotalTime; 1872 } else { 1873 mAcquireTime = -1; 1874 } 1875 if (DEBUG && mType < 0) { 1876 Log.v(TAG, "start #" + mType + ": mUpdateTime=" + mUpdateTime 1877 + " mTotalTime=" + mTotalTime + " mCount=" + mCount 1878 + " mAcquireTime=" + mAcquireTime); 1879 } 1880 } 1881 } 1882 1883 public boolean isRunningLocked() { 1884 return mNesting > 0; 1885 } 1886 1887 public void stopRunningLocked(long elapsedRealtimeMs) { 1888 // Ignore attempt to stop a timer that isn't running 1889 if (mNesting == 0) { 1890 return; 1891 } 1892 if (--mNesting == 0) { 1893 final long batteryRealtime = mTimeBase.getRealtime(elapsedRealtimeMs * 1000); 1894 if (mTimerPool != null) { 1895 // Accumulate time to all active counters, scaled by the total 1896 // active in the pool, before taking this one out of the pool. 1897 refreshTimersLocked(batteryRealtime, mTimerPool, null); 1898 // Remove this timer from the active pool 1899 mTimerPool.remove(this); 1900 } else { 1901 mNesting = 1; 1902 mTotalTime = computeRunTimeLocked(batteryRealtime); 1903 mNesting = 0; 1904 } 1905 1906 if (DEBUG && mType < 0) { 1907 Log.v(TAG, "stop #" + mType + ": mUpdateTime=" + mUpdateTime 1908 + " mTotalTime=" + mTotalTime + " mCount=" + mCount 1909 + " mAcquireTime=" + mAcquireTime); 1910 } 1911 1912 if (mAcquireTime >= 0 && mTotalTime == mAcquireTime) { 1913 // If there was no change in the time, then discard this 1914 // count. A somewhat cheezy strategy, but hey. 1915 mCount--; 1916 } 1917 } 1918 } 1919 1920 public void stopAllRunningLocked(long elapsedRealtimeMs) { 1921 if (mNesting > 0) { 1922 mNesting = 1; 1923 stopRunningLocked(elapsedRealtimeMs); 1924 } 1925 } 1926 1927 // Update the total time for all other running Timers with the same type as this Timer 1928 // due to a change in timer count 1929 private static long refreshTimersLocked(long batteryRealtime, 1930 final ArrayList<StopwatchTimer> pool, StopwatchTimer self) { 1931 long selfTime = 0; 1932 final int N = pool.size(); 1933 for (int i=N-1; i>= 0; i--) { 1934 final StopwatchTimer t = pool.get(i); 1935 long heldTime = batteryRealtime - t.mUpdateTime; 1936 if (heldTime > 0) { 1937 final long myTime = heldTime / N; 1938 if (t == self) { 1939 selfTime = myTime; 1940 } 1941 t.mTotalTime += myTime; 1942 } 1943 t.mUpdateTime = batteryRealtime; 1944 } 1945 return selfTime; 1946 } 1947 1948 @Override 1949 protected long computeRunTimeLocked(long curBatteryRealtime) { 1950 if (mTimeout > 0 && curBatteryRealtime > mUpdateTime + mTimeout) { 1951 curBatteryRealtime = mUpdateTime + mTimeout; 1952 } 1953 return mTotalTime + (mNesting > 0 1954 ? (curBatteryRealtime - mUpdateTime) 1955 / (mTimerPool != null ? mTimerPool.size() : 1) 1956 : 0); 1957 } 1958 1959 @Override 1960 protected int computeCurrentCountLocked() { 1961 return mCount; 1962 } 1963 1964 @Override 1965 public boolean reset(boolean detachIfReset) { 1966 boolean canDetach = mNesting <= 0; 1967 super.reset(canDetach && detachIfReset); 1968 if (mNesting > 0) { 1969 mUpdateTime = mTimeBase.getRealtime(mClocks.elapsedRealtime() * 1000); 1970 } 1971 mAcquireTime = -1; // to ensure mCount isn't decreased to -1 if timer is stopped later. 1972 return canDetach; 1973 } 1974 1975 @Override 1976 public void detach() { 1977 super.detach(); 1978 if (mTimerPool != null) { 1979 mTimerPool.remove(this); 1980 } 1981 } 1982 1983 @Override 1984 public void readSummaryFromParcelLocked(Parcel in) { 1985 super.readSummaryFromParcelLocked(in); 1986 mNesting = 0; 1987 } 1988 1989 /** 1990 * Set the mark so that we can query later for the total time the timer has 1991 * accumulated since this point. The timer can be running or not. 1992 * 1993 * @param elapsedRealtimeMs the current elapsed realtime in milliseconds. 1994 */ 1995 public void setMark(long elapsedRealtimeMs) { 1996 final long batteryRealtime = mTimeBase.getRealtime(elapsedRealtimeMs * 1000); 1997 if (mNesting > 0) { 1998 // We are running. 1999 if (mTimerPool != null) { 2000 refreshTimersLocked(batteryRealtime, mTimerPool, this); 2001 } else { 2002 mTotalTime += batteryRealtime - mUpdateTime; 2003 mUpdateTime = batteryRealtime; 2004 } 2005 } 2006 mTimeBeforeMark = mTotalTime; 2007 } 2008 } 2009 2010 /** 2011 * State for keeping track of two DurationTimers with different TimeBases, presumably where one 2012 * TimeBase is effectively a subset of the other. 2013 */ 2014 public static class DualTimer extends DurationTimer { 2015 // This class both is a DurationTimer and also holds a second DurationTimer. 2016 // The main timer (this) typically tracks the total time. It may be pooled (but since it's a 2017 // durationTimer, it also has the unpooled getTotalDurationMsLocked() for 2018 // STATS_SINCE_CHARGED). 2019 // mSubTimer typically tracks only part of the total time, such as background time, as 2020 // determined by a subTimeBase. It is NOT pooled. 2021 private final DurationTimer mSubTimer; 2022 2023 /** 2024 * Creates a DualTimer to hold a main timer (this) and a mSubTimer. 2025 * The main timer (this) is based on the given timeBase and timerPool. 2026 * The mSubTimer is based on the given subTimeBase. The mSubTimer is not pooled, even if 2027 * the main timer is. 2028 */ 2029 public DualTimer(Clocks clocks, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, 2030 TimeBase timeBase, TimeBase subTimeBase, Parcel in) { 2031 super(clocks, uid, type, timerPool, timeBase, in); 2032 mSubTimer = new DurationTimer(clocks, uid, type, null, subTimeBase, in); 2033 } 2034 2035 /** 2036 * Creates a DualTimer to hold a main timer (this) and a mSubTimer. 2037 * The main timer (this) is based on the given timeBase and timerPool. 2038 * The mSubTimer is based on the given subTimeBase. The mSubTimer is not pooled, even if 2039 * the main timer is. 2040 */ 2041 public DualTimer(Clocks clocks, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, 2042 TimeBase timeBase, TimeBase subTimeBase) { 2043 super(clocks, uid, type, timerPool, timeBase); 2044 mSubTimer = new DurationTimer(clocks, uid, type, null, subTimeBase); 2045 } 2046 2047 /** Get the secondary timer. */ 2048 @Override 2049 public DurationTimer getSubTimer() { 2050 return mSubTimer; 2051 } 2052 2053 @Override 2054 public void startRunningLocked(long elapsedRealtimeMs) { 2055 super.startRunningLocked(elapsedRealtimeMs); 2056 mSubTimer.startRunningLocked(elapsedRealtimeMs); 2057 } 2058 2059 @Override 2060 public void stopRunningLocked(long elapsedRealtimeMs) { 2061 super.stopRunningLocked(elapsedRealtimeMs); 2062 mSubTimer.stopRunningLocked(elapsedRealtimeMs); 2063 } 2064 2065 @Override 2066 public void stopAllRunningLocked(long elapsedRealtimeMs) { 2067 super.stopAllRunningLocked(elapsedRealtimeMs); 2068 mSubTimer.stopAllRunningLocked(elapsedRealtimeMs); 2069 } 2070 2071 @Override 2072 public boolean reset(boolean detachIfReset) { 2073 boolean active = false; 2074 // Do not detach the subTimer explicitly since that'll be done by DualTimer.detach(). 2075 active |= !mSubTimer.reset(false); 2076 active |= !super.reset(detachIfReset); 2077 return !active; 2078 } 2079 2080 @Override 2081 public void detach() { 2082 mSubTimer.detach(); 2083 super.detach(); 2084 } 2085 2086 @Override 2087 public void writeToParcel(Parcel out, long elapsedRealtimeUs) { 2088 super.writeToParcel(out, elapsedRealtimeUs); 2089 mSubTimer.writeToParcel(out, elapsedRealtimeUs); 2090 } 2091 2092 @Override 2093 public void writeSummaryFromParcelLocked(Parcel out, long elapsedRealtimeUs) { 2094 super.writeSummaryFromParcelLocked(out, elapsedRealtimeUs); 2095 mSubTimer.writeSummaryFromParcelLocked(out, elapsedRealtimeUs); 2096 } 2097 2098 @Override 2099 public void readSummaryFromParcelLocked(Parcel in) { 2100 super.readSummaryFromParcelLocked(in); 2101 mSubTimer.readSummaryFromParcelLocked(in); 2102 } 2103 } 2104 2105 2106 public abstract class OverflowArrayMap<T> { 2107 private static final String OVERFLOW_NAME = "*overflow*"; 2108 2109 final int mUid; 2110 final ArrayMap<String, T> mMap = new ArrayMap<>(); 2111 T mCurOverflow; 2112 ArrayMap<String, MutableInt> mActiveOverflow; 2113 long mLastOverflowTime; 2114 long mLastOverflowFinishTime; 2115 long mLastClearTime; 2116 long mLastCleanupTime; 2117 2118 public OverflowArrayMap(int uid) { 2119 mUid = uid; 2120 } 2121 2122 public ArrayMap<String, T> getMap() { 2123 return mMap; 2124 } 2125 2126 public void clear() { 2127 mLastClearTime = SystemClock.elapsedRealtime(); 2128 mMap.clear(); 2129 mCurOverflow = null; 2130 mActiveOverflow = null; 2131 } 2132 2133 public void add(String name, T obj) { 2134 if (name == null) { 2135 name = ""; 2136 } 2137 mMap.put(name, obj); 2138 if (OVERFLOW_NAME.equals(name)) { 2139 mCurOverflow = obj; 2140 } 2141 } 2142 2143 public void cleanup() { 2144 mLastCleanupTime = SystemClock.elapsedRealtime(); 2145 if (mActiveOverflow != null) { 2146 if (mActiveOverflow.size() == 0) { 2147 mActiveOverflow = null; 2148 } 2149 } 2150 if (mActiveOverflow == null) { 2151 // There is no currently active overflow, so we should no longer have 2152 // an overflow entry. 2153 if (mMap.containsKey(OVERFLOW_NAME)) { 2154 Slog.wtf(TAG, "Cleaning up with no active overflow, but have overflow entry " 2155 + mMap.get(OVERFLOW_NAME)); 2156 mMap.remove(OVERFLOW_NAME); 2157 } 2158 mCurOverflow = null; 2159 } else { 2160 // There is currently active overflow, so we should still have an overflow entry. 2161 if (mCurOverflow == null || !mMap.containsKey(OVERFLOW_NAME)) { 2162 Slog.wtf(TAG, "Cleaning up with active overflow, but no overflow entry: cur=" 2163 + mCurOverflow + " map=" + mMap.get(OVERFLOW_NAME)); 2164 } 2165 } 2166 } 2167 2168 public T startObject(String name) { 2169 if (name == null) { 2170 name = ""; 2171 } 2172 T obj = mMap.get(name); 2173 if (obj != null) { 2174 return obj; 2175 } 2176 2177 // No object exists for the given name, but do we currently have it 2178 // running as part of the overflow? 2179 if (mActiveOverflow != null) { 2180 MutableInt over = mActiveOverflow.get(name); 2181 if (over != null) { 2182 // We are already actively counting this name in the overflow object. 2183 obj = mCurOverflow; 2184 if (obj == null) { 2185 // Shouldn't be here, but we'll try to recover. 2186 Slog.wtf(TAG, "Have active overflow " + name + " but null overflow"); 2187 obj = mCurOverflow = instantiateObject(); 2188 mMap.put(OVERFLOW_NAME, obj); 2189 } 2190 over.value++; 2191 return obj; 2192 } 2193 } 2194 2195 // No object exists for given name nor in the overflow; we need to make 2196 // a new one. 2197 final int N = mMap.size(); 2198 if (N >= MAX_WAKELOCKS_PER_UID) { 2199 // Went over the limit on number of objects to track; this one goes 2200 // in to the overflow. 2201 obj = mCurOverflow; 2202 if (obj == null) { 2203 // Need to start overflow now... 2204 obj = mCurOverflow = instantiateObject(); 2205 mMap.put(OVERFLOW_NAME, obj); 2206 } 2207 if (mActiveOverflow == null) { 2208 mActiveOverflow = new ArrayMap<>(); 2209 } 2210 mActiveOverflow.put(name, new MutableInt(1)); 2211 mLastOverflowTime = SystemClock.elapsedRealtime(); 2212 return obj; 2213 } 2214 2215 // Normal case where we just need to make a new object. 2216 obj = instantiateObject(); 2217 mMap.put(name, obj); 2218 return obj; 2219 } 2220 2221 public T stopObject(String name) { 2222 if (name == null) { 2223 name = ""; 2224 } 2225 T obj = mMap.get(name); 2226 if (obj != null) { 2227 return obj; 2228 } 2229 2230 // No object exists for the given name, but do we currently have it 2231 // running as part of the overflow? 2232 if (mActiveOverflow != null) { 2233 MutableInt over = mActiveOverflow.get(name); 2234 if (over != null) { 2235 // We are already actively counting this name in the overflow object. 2236 obj = mCurOverflow; 2237 if (obj != null) { 2238 over.value--; 2239 if (over.value <= 0) { 2240 mActiveOverflow.remove(name); 2241 mLastOverflowFinishTime = SystemClock.elapsedRealtime(); 2242 } 2243 return obj; 2244 } 2245 } 2246 } 2247 2248 // Huh, they are stopping an active operation but we can't find one! 2249 // That's not good. 2250 StringBuilder sb = new StringBuilder(); 2251 sb.append("Unable to find object for "); 2252 sb.append(name); 2253 sb.append(" in uid "); 2254 sb.append(mUid); 2255 sb.append(" mapsize="); 2256 sb.append(mMap.size()); 2257 sb.append(" activeoverflow="); 2258 sb.append(mActiveOverflow); 2259 sb.append(" curoverflow="); 2260 sb.append(mCurOverflow); 2261 long now = SystemClock.elapsedRealtime(); 2262 if (mLastOverflowTime != 0) { 2263 sb.append(" lastOverflowTime="); 2264 TimeUtils.formatDuration(mLastOverflowTime-now, sb); 2265 } 2266 if (mLastOverflowFinishTime != 0) { 2267 sb.append(" lastOverflowFinishTime="); 2268 TimeUtils.formatDuration(mLastOverflowFinishTime-now, sb); 2269 } 2270 if (mLastClearTime != 0) { 2271 sb.append(" lastClearTime="); 2272 TimeUtils.formatDuration(mLastClearTime-now, sb); 2273 } 2274 if (mLastCleanupTime != 0) { 2275 sb.append(" lastCleanupTime="); 2276 TimeUtils.formatDuration(mLastCleanupTime-now, sb); 2277 } 2278 Slog.wtf(TAG, sb.toString()); 2279 return null; 2280 } 2281 2282 public abstract T instantiateObject(); 2283 } 2284 2285 public static class ControllerActivityCounterImpl extends ControllerActivityCounter 2286 implements Parcelable { 2287 private final LongSamplingCounter mIdleTimeMillis; 2288 private final LongSamplingCounter mRxTimeMillis; 2289 private final LongSamplingCounter[] mTxTimeMillis; 2290 private final LongSamplingCounter mPowerDrainMaMs; 2291 2292 public ControllerActivityCounterImpl(TimeBase timeBase, int numTxStates) { 2293 mIdleTimeMillis = new LongSamplingCounter(timeBase); 2294 mRxTimeMillis = new LongSamplingCounter(timeBase); 2295 mTxTimeMillis = new LongSamplingCounter[numTxStates]; 2296 for (int i = 0; i < numTxStates; i++) { 2297 mTxTimeMillis[i] = new LongSamplingCounter(timeBase); 2298 } 2299 mPowerDrainMaMs = new LongSamplingCounter(timeBase); 2300 } 2301 2302 public ControllerActivityCounterImpl(TimeBase timeBase, int numTxStates, Parcel in) { 2303 mIdleTimeMillis = new LongSamplingCounter(timeBase, in); 2304 mRxTimeMillis = new LongSamplingCounter(timeBase, in); 2305 final int recordedTxStates = in.readInt(); 2306 if (recordedTxStates != numTxStates) { 2307 throw new ParcelFormatException("inconsistent tx state lengths"); 2308 } 2309 2310 mTxTimeMillis = new LongSamplingCounter[numTxStates]; 2311 for (int i = 0; i < numTxStates; i++) { 2312 mTxTimeMillis[i] = new LongSamplingCounter(timeBase, in); 2313 } 2314 mPowerDrainMaMs = new LongSamplingCounter(timeBase, in); 2315 } 2316 2317 public void readSummaryFromParcel(Parcel in) { 2318 mIdleTimeMillis.readSummaryFromParcelLocked(in); 2319 mRxTimeMillis.readSummaryFromParcelLocked(in); 2320 final int recordedTxStates = in.readInt(); 2321 if (recordedTxStates != mTxTimeMillis.length) { 2322 throw new ParcelFormatException("inconsistent tx state lengths"); 2323 } 2324 for (LongSamplingCounter counter : mTxTimeMillis) { 2325 counter.readSummaryFromParcelLocked(in); 2326 } 2327 mPowerDrainMaMs.readSummaryFromParcelLocked(in); 2328 } 2329 2330 @Override 2331 public int describeContents() { 2332 return 0; 2333 } 2334 2335 public void writeSummaryToParcel(Parcel dest) { 2336 mIdleTimeMillis.writeSummaryFromParcelLocked(dest); 2337 mRxTimeMillis.writeSummaryFromParcelLocked(dest); 2338 dest.writeInt(mTxTimeMillis.length); 2339 for (LongSamplingCounter counter : mTxTimeMillis) { 2340 counter.writeSummaryFromParcelLocked(dest); 2341 } 2342 mPowerDrainMaMs.writeSummaryFromParcelLocked(dest); 2343 } 2344 2345 @Override 2346 public void writeToParcel(Parcel dest, int flags) { 2347 mIdleTimeMillis.writeToParcel(dest); 2348 mRxTimeMillis.writeToParcel(dest); 2349 dest.writeInt(mTxTimeMillis.length); 2350 for (LongSamplingCounter counter : mTxTimeMillis) { 2351 counter.writeToParcel(dest); 2352 } 2353 mPowerDrainMaMs.writeToParcel(dest); 2354 } 2355 2356 public void reset(boolean detachIfReset) { 2357 mIdleTimeMillis.reset(detachIfReset); 2358 mRxTimeMillis.reset(detachIfReset); 2359 for (LongSamplingCounter counter : mTxTimeMillis) { 2360 counter.reset(detachIfReset); 2361 } 2362 mPowerDrainMaMs.reset(detachIfReset); 2363 } 2364 2365 public void detach() { 2366 mIdleTimeMillis.detach(); 2367 mRxTimeMillis.detach(); 2368 for (LongSamplingCounter counter : mTxTimeMillis) { 2369 counter.detach(); 2370 } 2371 mPowerDrainMaMs.detach(); 2372 } 2373 2374 /** 2375 * @return a LongSamplingCounter, measuring time spent in the idle state in 2376 * milliseconds. 2377 */ 2378 @Override 2379 public LongSamplingCounter getIdleTimeCounter() { 2380 return mIdleTimeMillis; 2381 } 2382 2383 /** 2384 * @return a LongSamplingCounter, measuring time spent in the receive state in 2385 * milliseconds. 2386 */ 2387 @Override 2388 public LongSamplingCounter getRxTimeCounter() { 2389 return mRxTimeMillis; 2390 } 2391 2392 /** 2393 * @return a LongSamplingCounter[], measuring time spent in various transmit states in 2394 * milliseconds. 2395 */ 2396 @Override 2397 public LongSamplingCounter[] getTxTimeCounters() { 2398 return mTxTimeMillis; 2399 } 2400 2401 /** 2402 * @return a LongSamplingCounter, measuring power use in milli-ampere milliseconds (mAmS). 2403 */ 2404 @Override 2405 public LongSamplingCounter getPowerCounter() { 2406 return mPowerDrainMaMs; 2407 } 2408 } 2409 2410 /* 2411 * Get the wakeup reason counter, and create a new one if one 2412 * doesn't already exist. 2413 */ 2414 public SamplingTimer getWakeupReasonTimerLocked(String name) { 2415 SamplingTimer timer = mWakeupReasonStats.get(name); 2416 if (timer == null) { 2417 timer = new SamplingTimer(mClocks, mOnBatteryTimeBase); 2418 mWakeupReasonStats.put(name, timer); 2419 } 2420 return timer; 2421 } 2422 2423 /* 2424 * Get the KernelWakelockTimer associated with name, and create a new one if one 2425 * doesn't already exist. 2426 */ 2427 public SamplingTimer getKernelWakelockTimerLocked(String name) { 2428 SamplingTimer kwlt = mKernelWakelockStats.get(name); 2429 if (kwlt == null) { 2430 kwlt = new SamplingTimer(mClocks, mOnBatteryScreenOffTimeBase); 2431 mKernelWakelockStats.put(name, kwlt); 2432 } 2433 return kwlt; 2434 } 2435 2436 public SamplingTimer getKernelMemoryTimerLocked(long bucket) { 2437 SamplingTimer kmt = mKernelMemoryStats.get(bucket); 2438 if (kmt == null) { 2439 kmt = new SamplingTimer(mClocks, mOnBatteryTimeBase); 2440 mKernelMemoryStats.put(bucket, kmt); 2441 } 2442 return kmt; 2443 } 2444 2445 private int writeHistoryTag(HistoryTag tag) { 2446 Integer idxObj = mHistoryTagPool.get(tag); 2447 int idx; 2448 if (idxObj != null) { 2449 idx = idxObj; 2450 } else { 2451 idx = mNextHistoryTagIdx; 2452 HistoryTag key = new HistoryTag(); 2453 key.setTo(tag); 2454 tag.poolIdx = idx; 2455 mHistoryTagPool.put(key, idx); 2456 mNextHistoryTagIdx++; 2457 mNumHistoryTagChars += key.string.length() + 1; 2458 } 2459 return idx; 2460 } 2461 2462 private void readHistoryTag(int index, HistoryTag tag) { 2463 tag.string = mReadHistoryStrings[index]; 2464 tag.uid = mReadHistoryUids[index]; 2465 tag.poolIdx = index; 2466 } 2467 2468 /* 2469 The history delta format uses flags to denote further data in subsequent ints in the parcel. 2470 2471 There is always the first token, which may contain the delta time, or an indicator of 2472 the length of the time (int or long) following this token. 2473 2474 First token: always present, 2475 31 23 15 7 0 2476 █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█ 2477 2478 T: the delta time if it is <= 0x7fffd. Otherwise 0x7fffe indicates an int immediately 2479 follows containing the time, and 0x7ffff indicates a long immediately follows with the 2480 delta time. 2481 A: battery level changed and an int follows with battery data. 2482 B: state changed and an int follows with state change data. 2483 C: state2 has changed and an int follows with state2 change data. 2484 D: wakelock/wakereason has changed and an wakelock/wakereason struct follows. 2485 E: event data has changed and an event struct follows. 2486 F: battery charge in coulombs has changed and an int with the charge follows. 2487 G: state flag denoting that the mobile radio was active. 2488 H: state flag denoting that the wifi radio was active. 2489 I: state flag denoting that a wifi scan occurred. 2490 J: state flag denoting that a wifi full lock was held. 2491 K: state flag denoting that the gps was on. 2492 L: state flag denoting that a wakelock was held. 2493 M: state flag denoting that the cpu was running. 2494 2495 Time int/long: if T in the first token is 0x7ffff or 0x7fffe, then an int or long follows 2496 with the time delta. 2497 2498 Battery level int: if A in the first token is set, 2499 31 23 15 7 0 2500 █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█ 2501 2502 D: indicates that extra history details follow. 2503 V: the battery voltage. 2504 T: the battery temperature. 2505 L: the battery level (out of 100). 2506 2507 State change int: if B in the first token is set, 2508 31 23 15 7 0 2509 █S|S|S|H|H|H|P|P█F|E|D|C|B| | |A█ | | | | | | | █ | | | | | | | █ 2510 2511 A: wifi multicast was on. 2512 B: battery was plugged in. 2513 C: screen was on. 2514 D: phone was scanning for signal. 2515 E: audio was on. 2516 F: a sensor was active. 2517 2518 State2 change int: if C in the first token is set, 2519 31 23 15 7 0 2520 █M|L|K|J|I|H|H|G█F|E|D|C| | | | █ | | | | | | | █ |B|B|B|A|A|A|A█ 2521 2522 A: 4 bits indicating the wifi supplicant state: {@link BatteryStats#WIFI_SUPPL_STATE_NAMES}. 2523 B: 3 bits indicating the wifi signal strength: 0, 1, 2, 3, 4. 2524 C: a bluetooth scan was active. 2525 D: the camera was active. 2526 E: bluetooth was on. 2527 F: a phone call was active. 2528 G: the device was charging. 2529 H: 2 bits indicating the device-idle (doze) state: off, light, full 2530 I: the flashlight was on. 2531 J: wifi was on. 2532 K: wifi was running. 2533 L: video was playing. 2534 M: power save mode was on. 2535 2536 Wakelock/wakereason struct: if D in the first token is set, 2537 TODO(adamlesinski): describe wakelock/wakereason struct. 2538 2539 Event struct: if E in the first token is set, 2540 TODO(adamlesinski): describe the event struct. 2541 2542 History step details struct: if D in the battery level int is set, 2543 TODO(adamlesinski): describe the history step details struct. 2544 2545 Battery charge int: if F in the first token is set, an int representing the battery charge 2546 in coulombs follows. 2547 */ 2548 2549 // Part of initial delta int that specifies the time delta. 2550 static final int DELTA_TIME_MASK = 0x7ffff; 2551 static final int DELTA_TIME_LONG = 0x7ffff; // The delta is a following long 2552 static final int DELTA_TIME_INT = 0x7fffe; // The delta is a following int 2553 static final int DELTA_TIME_ABS = 0x7fffd; // Following is an entire abs update. 2554 // Flag in delta int: a new battery level int follows. 2555 static final int DELTA_BATTERY_LEVEL_FLAG = 0x00080000; 2556 // Flag in delta int: a new full state and battery status int follows. 2557 static final int DELTA_STATE_FLAG = 0x00100000; 2558 // Flag in delta int: a new full state2 int follows. 2559 static final int DELTA_STATE2_FLAG = 0x00200000; 2560 // Flag in delta int: contains a wakelock or wakeReason tag. 2561 static final int DELTA_WAKELOCK_FLAG = 0x00400000; 2562 // Flag in delta int: contains an event description. 2563 static final int DELTA_EVENT_FLAG = 0x00800000; 2564 // Flag in delta int: contains the battery charge count in uAh. 2565 static final int DELTA_BATTERY_CHARGE_FLAG = 0x01000000; 2566 // These upper bits are the frequently changing state bits. 2567 static final int DELTA_STATE_MASK = 0xfe000000; 2568 2569 // These are the pieces of battery state that are packed in to the upper bits of 2570 // the state int that have been packed in to the first delta int. They must fit 2571 // in STATE_BATTERY_MASK. 2572 static final int STATE_BATTERY_MASK = 0xff000000; 2573 static final int STATE_BATTERY_STATUS_MASK = 0x00000007; 2574 static final int STATE_BATTERY_STATUS_SHIFT = 29; 2575 static final int STATE_BATTERY_HEALTH_MASK = 0x00000007; 2576 static final int STATE_BATTERY_HEALTH_SHIFT = 26; 2577 static final int STATE_BATTERY_PLUG_MASK = 0x00000003; 2578 static final int STATE_BATTERY_PLUG_SHIFT = 24; 2579 2580 // We use the low bit of the battery state int to indicate that we have full details 2581 // from a battery level change. 2582 static final int BATTERY_DELTA_LEVEL_FLAG = 0x00000001; 2583 2584 public void writeHistoryDelta(Parcel dest, HistoryItem cur, HistoryItem last) { 2585 if (last == null || cur.cmd != HistoryItem.CMD_UPDATE) { 2586 dest.writeInt(DELTA_TIME_ABS); 2587 cur.writeToParcel(dest, 0); 2588 return; 2589 } 2590 2591 final long deltaTime = cur.time - last.time; 2592 final int lastBatteryLevelInt = buildBatteryLevelInt(last); 2593 final int lastStateInt = buildStateInt(last); 2594 2595 int deltaTimeToken; 2596 if (deltaTime < 0 || deltaTime > Integer.MAX_VALUE) { 2597 deltaTimeToken = DELTA_TIME_LONG; 2598 } else if (deltaTime >= DELTA_TIME_ABS) { 2599 deltaTimeToken = DELTA_TIME_INT; 2600 } else { 2601 deltaTimeToken = (int)deltaTime; 2602 } 2603 int firstToken = deltaTimeToken | (cur.states&DELTA_STATE_MASK); 2604 final int includeStepDetails = mLastHistoryStepLevel > cur.batteryLevel 2605 ? BATTERY_DELTA_LEVEL_FLAG : 0; 2606 final boolean computeStepDetails = includeStepDetails != 0 2607 || mLastHistoryStepDetails == null; 2608 final int batteryLevelInt = buildBatteryLevelInt(cur) | includeStepDetails; 2609 final boolean batteryLevelIntChanged = batteryLevelInt != lastBatteryLevelInt; 2610 if (batteryLevelIntChanged) { 2611 firstToken |= DELTA_BATTERY_LEVEL_FLAG; 2612 } 2613 final int stateInt = buildStateInt(cur); 2614 final boolean stateIntChanged = stateInt != lastStateInt; 2615 if (stateIntChanged) { 2616 firstToken |= DELTA_STATE_FLAG; 2617 } 2618 final boolean state2IntChanged = cur.states2 != last.states2; 2619 if (state2IntChanged) { 2620 firstToken |= DELTA_STATE2_FLAG; 2621 } 2622 if (cur.wakelockTag != null || cur.wakeReasonTag != null) { 2623 firstToken |= DELTA_WAKELOCK_FLAG; 2624 } 2625 if (cur.eventCode != HistoryItem.EVENT_NONE) { 2626 firstToken |= DELTA_EVENT_FLAG; 2627 } 2628 2629 final boolean batteryChargeChanged = cur.batteryChargeUAh != last.batteryChargeUAh; 2630 if (batteryChargeChanged) { 2631 firstToken |= DELTA_BATTERY_CHARGE_FLAG; 2632 } 2633 dest.writeInt(firstToken); 2634 if (DEBUG) Slog.i(TAG, "WRITE DELTA: firstToken=0x" + Integer.toHexString(firstToken) 2635 + " deltaTime=" + deltaTime); 2636 2637 if (deltaTimeToken >= DELTA_TIME_INT) { 2638 if (deltaTimeToken == DELTA_TIME_INT) { 2639 if (DEBUG) Slog.i(TAG, "WRITE DELTA: int deltaTime=" + (int)deltaTime); 2640 dest.writeInt((int)deltaTime); 2641 } else { 2642 if (DEBUG) Slog.i(TAG, "WRITE DELTA: long deltaTime=" + deltaTime); 2643 dest.writeLong(deltaTime); 2644 } 2645 } 2646 if (batteryLevelIntChanged) { 2647 dest.writeInt(batteryLevelInt); 2648 if (DEBUG) Slog.i(TAG, "WRITE DELTA: batteryToken=0x" 2649 + Integer.toHexString(batteryLevelInt) 2650 + " batteryLevel=" + cur.batteryLevel 2651 + " batteryTemp=" + cur.batteryTemperature 2652 + " batteryVolt=" + (int)cur.batteryVoltage); 2653 } 2654 if (stateIntChanged) { 2655 dest.writeInt(stateInt); 2656 if (DEBUG) Slog.i(TAG, "WRITE DELTA: stateToken=0x" 2657 + Integer.toHexString(stateInt) 2658 + " batteryStatus=" + cur.batteryStatus 2659 + " batteryHealth=" + cur.batteryHealth 2660 + " batteryPlugType=" + cur.batteryPlugType 2661 + " states=0x" + Integer.toHexString(cur.states)); 2662 } 2663 if (state2IntChanged) { 2664 dest.writeInt(cur.states2); 2665 if (DEBUG) Slog.i(TAG, "WRITE DELTA: states2=0x" 2666 + Integer.toHexString(cur.states2)); 2667 } 2668 if (cur.wakelockTag != null || cur.wakeReasonTag != null) { 2669 int wakeLockIndex; 2670 int wakeReasonIndex; 2671 if (cur.wakelockTag != null) { 2672 wakeLockIndex = writeHistoryTag(cur.wakelockTag); 2673 if (DEBUG) Slog.i(TAG, "WRITE DELTA: wakelockTag=#" + cur.wakelockTag.poolIdx 2674 + " " + cur.wakelockTag.uid + ":" + cur.wakelockTag.string); 2675 } else { 2676 wakeLockIndex = 0xffff; 2677 } 2678 if (cur.wakeReasonTag != null) { 2679 wakeReasonIndex = writeHistoryTag(cur.wakeReasonTag); 2680 if (DEBUG) Slog.i(TAG, "WRITE DELTA: wakeReasonTag=#" + cur.wakeReasonTag.poolIdx 2681 + " " + cur.wakeReasonTag.uid + ":" + cur.wakeReasonTag.string); 2682 } else { 2683 wakeReasonIndex = 0xffff; 2684 } 2685 dest.writeInt((wakeReasonIndex<<16) | wakeLockIndex); 2686 } 2687 if (cur.eventCode != HistoryItem.EVENT_NONE) { 2688 int index = writeHistoryTag(cur.eventTag); 2689 int codeAndIndex = (cur.eventCode&0xffff) | (index<<16); 2690 dest.writeInt(codeAndIndex); 2691 if (DEBUG) Slog.i(TAG, "WRITE DELTA: event=" + cur.eventCode + " tag=#" 2692 + cur.eventTag.poolIdx + " " + cur.eventTag.uid + ":" 2693 + cur.eventTag.string); 2694 } 2695 if (computeStepDetails) { 2696 if (mPlatformIdleStateCallback != null) { 2697 mCurHistoryStepDetails.statPlatformIdleState = 2698 mPlatformIdleStateCallback.getPlatformLowPowerStats(); 2699 if (DEBUG) Slog.i(TAG, "WRITE PlatformIdleState:" + 2700 mCurHistoryStepDetails.statPlatformIdleState); 2701 } 2702 computeHistoryStepDetails(mCurHistoryStepDetails, mLastHistoryStepDetails); 2703 if (includeStepDetails != 0) { 2704 mCurHistoryStepDetails.writeToParcel(dest); 2705 } 2706 cur.stepDetails = mCurHistoryStepDetails; 2707 mLastHistoryStepDetails = mCurHistoryStepDetails; 2708 } else { 2709 cur.stepDetails = null; 2710 } 2711 if (mLastHistoryStepLevel < cur.batteryLevel) { 2712 mLastHistoryStepDetails = null; 2713 } 2714 mLastHistoryStepLevel = cur.batteryLevel; 2715 2716 if (batteryChargeChanged) { 2717 if (DEBUG) Slog.i(TAG, "WRITE DELTA: batteryChargeUAh=" + cur.batteryChargeUAh); 2718 dest.writeInt(cur.batteryChargeUAh); 2719 } 2720 } 2721 2722 private int buildBatteryLevelInt(HistoryItem h) { 2723 return ((((int)h.batteryLevel)<<25)&0xfe000000) 2724 | ((((int)h.batteryTemperature)<<15)&0x01ff8000) 2725 | ((((int)h.batteryVoltage)<<1)&0x00007ffe); 2726 } 2727 2728 private void readBatteryLevelInt(int batteryLevelInt, HistoryItem out) { 2729 out.batteryLevel = (byte)((batteryLevelInt & 0xfe000000) >>> 25); 2730 out.batteryTemperature = (short)((batteryLevelInt & 0x01ff8000) >>> 15); 2731 out.batteryVoltage = (char)((batteryLevelInt & 0x00007ffe) >>> 1); 2732 } 2733 2734 private int buildStateInt(HistoryItem h) { 2735 int plugType = 0; 2736 if ((h.batteryPlugType&BatteryManager.BATTERY_PLUGGED_AC) != 0) { 2737 plugType = 1; 2738 } else if ((h.batteryPlugType&BatteryManager.BATTERY_PLUGGED_USB) != 0) { 2739 plugType = 2; 2740 } else if ((h.batteryPlugType&BatteryManager.BATTERY_PLUGGED_WIRELESS) != 0) { 2741 plugType = 3; 2742 } 2743 return ((h.batteryStatus&STATE_BATTERY_STATUS_MASK)<<STATE_BATTERY_STATUS_SHIFT) 2744 | ((h.batteryHealth&STATE_BATTERY_HEALTH_MASK)<<STATE_BATTERY_HEALTH_SHIFT) 2745 | ((plugType&STATE_BATTERY_PLUG_MASK)<<STATE_BATTERY_PLUG_SHIFT) 2746 | (h.states&(~STATE_BATTERY_MASK)); 2747 } 2748 2749 private void computeHistoryStepDetails(final HistoryStepDetails out, 2750 final HistoryStepDetails last) { 2751 final HistoryStepDetails tmp = last != null ? mTmpHistoryStepDetails : out; 2752 2753 // Perform a CPU update right after we do this collection, so we have started 2754 // collecting good data for the next step. 2755 requestImmediateCpuUpdate(); 2756 2757 if (last == null) { 2758 // We are not generating a delta, so all we need to do is reset the stats 2759 // we will later be doing a delta from. 2760 final int NU = mUidStats.size(); 2761 for (int i=0; i<NU; i++) { 2762 final BatteryStatsImpl.Uid uid = mUidStats.valueAt(i); 2763 uid.mLastStepUserTime = uid.mCurStepUserTime; 2764 uid.mLastStepSystemTime = uid.mCurStepSystemTime; 2765 } 2766 mLastStepCpuUserTime = mCurStepCpuUserTime; 2767 mLastStepCpuSystemTime = mCurStepCpuSystemTime; 2768 mLastStepStatUserTime = mCurStepStatUserTime; 2769 mLastStepStatSystemTime = mCurStepStatSystemTime; 2770 mLastStepStatIOWaitTime = mCurStepStatIOWaitTime; 2771 mLastStepStatIrqTime = mCurStepStatIrqTime; 2772 mLastStepStatSoftIrqTime = mCurStepStatSoftIrqTime; 2773 mLastStepStatIdleTime = mCurStepStatIdleTime; 2774 tmp.clear(); 2775 return; 2776 } 2777 if (DEBUG) { 2778 Slog.d(TAG, "Step stats last: user=" + mLastStepCpuUserTime + " sys=" 2779 + mLastStepStatSystemTime + " io=" + mLastStepStatIOWaitTime 2780 + " irq=" + mLastStepStatIrqTime + " sirq=" 2781 + mLastStepStatSoftIrqTime + " idle=" + mLastStepStatIdleTime); 2782 Slog.d(TAG, "Step stats cur: user=" + mCurStepCpuUserTime + " sys=" 2783 + mCurStepStatSystemTime + " io=" + mCurStepStatIOWaitTime 2784 + " irq=" + mCurStepStatIrqTime + " sirq=" 2785 + mCurStepStatSoftIrqTime + " idle=" + mCurStepStatIdleTime); 2786 } 2787 out.userTime = (int)(mCurStepCpuUserTime - mLastStepCpuUserTime); 2788 out.systemTime = (int)(mCurStepCpuSystemTime - mLastStepCpuSystemTime); 2789 out.statUserTime = (int)(mCurStepStatUserTime - mLastStepStatUserTime); 2790 out.statSystemTime = (int)(mCurStepStatSystemTime - mLastStepStatSystemTime); 2791 out.statIOWaitTime = (int)(mCurStepStatIOWaitTime - mLastStepStatIOWaitTime); 2792 out.statIrqTime = (int)(mCurStepStatIrqTime - mLastStepStatIrqTime); 2793 out.statSoftIrqTime = (int)(mCurStepStatSoftIrqTime - mLastStepStatSoftIrqTime); 2794 out.statIdlTime = (int)(mCurStepStatIdleTime - mLastStepStatIdleTime); 2795 out.appCpuUid1 = out.appCpuUid2 = out.appCpuUid3 = -1; 2796 out.appCpuUTime1 = out.appCpuUTime2 = out.appCpuUTime3 = 0; 2797 out.appCpuSTime1 = out.appCpuSTime2 = out.appCpuSTime3 = 0; 2798 final int NU = mUidStats.size(); 2799 for (int i=0; i<NU; i++) { 2800 final BatteryStatsImpl.Uid uid = mUidStats.valueAt(i); 2801 final int totalUTime = (int)(uid.mCurStepUserTime - uid.mLastStepUserTime); 2802 final int totalSTime = (int)(uid.mCurStepSystemTime - uid.mLastStepSystemTime); 2803 final int totalTime = totalUTime + totalSTime; 2804 uid.mLastStepUserTime = uid.mCurStepUserTime; 2805 uid.mLastStepSystemTime = uid.mCurStepSystemTime; 2806 if (totalTime <= (out.appCpuUTime3+out.appCpuSTime3)) { 2807 continue; 2808 } 2809 if (totalTime <= (out.appCpuUTime2+out.appCpuSTime2)) { 2810 out.appCpuUid3 = uid.mUid; 2811 out.appCpuUTime3 = totalUTime; 2812 out.appCpuSTime3 = totalSTime; 2813 } else { 2814 out.appCpuUid3 = out.appCpuUid2; 2815 out.appCpuUTime3 = out.appCpuUTime2; 2816 out.appCpuSTime3 = out.appCpuSTime2; 2817 if (totalTime <= (out.appCpuUTime1+out.appCpuSTime1)) { 2818 out.appCpuUid2 = uid.mUid; 2819 out.appCpuUTime2 = totalUTime; 2820 out.appCpuSTime2 = totalSTime; 2821 } else { 2822 out.appCpuUid2 = out.appCpuUid1; 2823 out.appCpuUTime2 = out.appCpuUTime1; 2824 out.appCpuSTime2 = out.appCpuSTime1; 2825 out.appCpuUid1 = uid.mUid; 2826 out.appCpuUTime1 = totalUTime; 2827 out.appCpuSTime1 = totalSTime; 2828 } 2829 } 2830 } 2831 mLastStepCpuUserTime = mCurStepCpuUserTime; 2832 mLastStepCpuSystemTime = mCurStepCpuSystemTime; 2833 mLastStepStatUserTime = mCurStepStatUserTime; 2834 mLastStepStatSystemTime = mCurStepStatSystemTime; 2835 mLastStepStatIOWaitTime = mCurStepStatIOWaitTime; 2836 mLastStepStatIrqTime = mCurStepStatIrqTime; 2837 mLastStepStatSoftIrqTime = mCurStepStatSoftIrqTime; 2838 mLastStepStatIdleTime = mCurStepStatIdleTime; 2839 } 2840 2841 public void readHistoryDelta(Parcel src, HistoryItem cur) { 2842 int firstToken = src.readInt(); 2843 int deltaTimeToken = firstToken&DELTA_TIME_MASK; 2844 cur.cmd = HistoryItem.CMD_UPDATE; 2845 cur.numReadInts = 1; 2846 if (DEBUG) Slog.i(TAG, "READ DELTA: firstToken=0x" + Integer.toHexString(firstToken) 2847 + " deltaTimeToken=" + deltaTimeToken); 2848 2849 if (deltaTimeToken < DELTA_TIME_ABS) { 2850 cur.time += deltaTimeToken; 2851 } else if (deltaTimeToken == DELTA_TIME_ABS) { 2852 cur.time = src.readLong(); 2853 cur.numReadInts += 2; 2854 if (DEBUG) Slog.i(TAG, "READ DELTA: ABS time=" + cur.time); 2855 cur.readFromParcel(src); 2856 return; 2857 } else if (deltaTimeToken == DELTA_TIME_INT) { 2858 int delta = src.readInt(); 2859 cur.time += delta; 2860 cur.numReadInts += 1; 2861 if (DEBUG) Slog.i(TAG, "READ DELTA: time delta=" + delta + " new time=" + cur.time); 2862 } else { 2863 long delta = src.readLong(); 2864 if (DEBUG) Slog.i(TAG, "READ DELTA: time delta=" + delta + " new time=" + cur.time); 2865 cur.time += delta; 2866 cur.numReadInts += 2; 2867 } 2868 2869 final int batteryLevelInt; 2870 if ((firstToken&DELTA_BATTERY_LEVEL_FLAG) != 0) { 2871 batteryLevelInt = src.readInt(); 2872 readBatteryLevelInt(batteryLevelInt, cur); 2873 cur.numReadInts += 1; 2874 if (DEBUG) Slog.i(TAG, "READ DELTA: batteryToken=0x" 2875 + Integer.toHexString(batteryLevelInt) 2876 + " batteryLevel=" + cur.batteryLevel 2877 + " batteryTemp=" + cur.batteryTemperature 2878 + " batteryVolt=" + (int)cur.batteryVoltage); 2879 } else { 2880 batteryLevelInt = 0; 2881 } 2882 2883 if ((firstToken&DELTA_STATE_FLAG) != 0) { 2884 int stateInt = src.readInt(); 2885 cur.states = (firstToken&DELTA_STATE_MASK) | (stateInt&(~STATE_BATTERY_MASK)); 2886 cur.batteryStatus = (byte)((stateInt>>STATE_BATTERY_STATUS_SHIFT) 2887 & STATE_BATTERY_STATUS_MASK); 2888 cur.batteryHealth = (byte)((stateInt>>STATE_BATTERY_HEALTH_SHIFT) 2889 & STATE_BATTERY_HEALTH_MASK); 2890 cur.batteryPlugType = (byte)((stateInt>>STATE_BATTERY_PLUG_SHIFT) 2891 & STATE_BATTERY_PLUG_MASK); 2892 switch (cur.batteryPlugType) { 2893 case 1: 2894 cur.batteryPlugType = BatteryManager.BATTERY_PLUGGED_AC; 2895 break; 2896 case 2: 2897 cur.batteryPlugType = BatteryManager.BATTERY_PLUGGED_USB; 2898 break; 2899 case 3: 2900 cur.batteryPlugType = BatteryManager.BATTERY_PLUGGED_WIRELESS; 2901 break; 2902 } 2903 cur.numReadInts += 1; 2904 if (DEBUG) Slog.i(TAG, "READ DELTA: stateToken=0x" 2905 + Integer.toHexString(stateInt) 2906 + " batteryStatus=" + cur.batteryStatus 2907 + " batteryHealth=" + cur.batteryHealth 2908 + " batteryPlugType=" + cur.batteryPlugType 2909 + " states=0x" + Integer.toHexString(cur.states)); 2910 } else { 2911 cur.states = (firstToken&DELTA_STATE_MASK) | (cur.states&(~STATE_BATTERY_MASK)); 2912 } 2913 2914 if ((firstToken&DELTA_STATE2_FLAG) != 0) { 2915 cur.states2 = src.readInt(); 2916 if (DEBUG) Slog.i(TAG, "READ DELTA: states2=0x" 2917 + Integer.toHexString(cur.states2)); 2918 } 2919 2920 if ((firstToken&DELTA_WAKELOCK_FLAG) != 0) { 2921 int indexes = src.readInt(); 2922 int wakeLockIndex = indexes&0xffff; 2923 int wakeReasonIndex = (indexes>>16)&0xffff; 2924 if (wakeLockIndex != 0xffff) { 2925 cur.wakelockTag = cur.localWakelockTag; 2926 readHistoryTag(wakeLockIndex, cur.wakelockTag); 2927 if (DEBUG) Slog.i(TAG, "READ DELTA: wakelockTag=#" + cur.wakelockTag.poolIdx 2928 + " " + cur.wakelockTag.uid + ":" + cur.wakelockTag.string); 2929 } else { 2930 cur.wakelockTag = null; 2931 } 2932 if (wakeReasonIndex != 0xffff) { 2933 cur.wakeReasonTag = cur.localWakeReasonTag; 2934 readHistoryTag(wakeReasonIndex, cur.wakeReasonTag); 2935 if (DEBUG) Slog.i(TAG, "READ DELTA: wakeReasonTag=#" + cur.wakeReasonTag.poolIdx 2936 + " " + cur.wakeReasonTag.uid + ":" + cur.wakeReasonTag.string); 2937 } else { 2938 cur.wakeReasonTag = null; 2939 } 2940 cur.numReadInts += 1; 2941 } else { 2942 cur.wakelockTag = null; 2943 cur.wakeReasonTag = null; 2944 } 2945 2946 if ((firstToken&DELTA_EVENT_FLAG) != 0) { 2947 cur.eventTag = cur.localEventTag; 2948 final int codeAndIndex = src.readInt(); 2949 cur.eventCode = (codeAndIndex&0xffff); 2950 final int index = ((codeAndIndex>>16)&0xffff); 2951 readHistoryTag(index, cur.eventTag); 2952 cur.numReadInts += 1; 2953 if (DEBUG) Slog.i(TAG, "READ DELTA: event=" + cur.eventCode + " tag=#" 2954 + cur.eventTag.poolIdx + " " + cur.eventTag.uid + ":" 2955 + cur.eventTag.string); 2956 } else { 2957 cur.eventCode = HistoryItem.EVENT_NONE; 2958 } 2959 2960 if ((batteryLevelInt&BATTERY_DELTA_LEVEL_FLAG) != 0) { 2961 cur.stepDetails = mReadHistoryStepDetails; 2962 cur.stepDetails.readFromParcel(src); 2963 } else { 2964 cur.stepDetails = null; 2965 } 2966 2967 if ((firstToken&DELTA_BATTERY_CHARGE_FLAG) != 0) { 2968 cur.batteryChargeUAh = src.readInt(); 2969 } 2970 } 2971 2972 @Override 2973 public void commitCurrentHistoryBatchLocked() { 2974 mHistoryLastWritten.cmd = HistoryItem.CMD_NULL; 2975 } 2976 2977 void addHistoryBufferLocked(long elapsedRealtimeMs, long uptimeMs, HistoryItem cur) { 2978 if (!mHaveBatteryLevel || !mRecordingHistory) { 2979 return; 2980 } 2981 2982 final long timeDiff = (mHistoryBaseTime+elapsedRealtimeMs) - mHistoryLastWritten.time; 2983 final int diffStates = mHistoryLastWritten.states^(cur.states&mActiveHistoryStates); 2984 final int diffStates2 = mHistoryLastWritten.states2^(cur.states2&mActiveHistoryStates2); 2985 final int lastDiffStates = mHistoryLastWritten.states^mHistoryLastLastWritten.states; 2986 final int lastDiffStates2 = mHistoryLastWritten.states2^mHistoryLastLastWritten.states2; 2987 if (DEBUG) Slog.i(TAG, "ADD: tdelta=" + timeDiff + " diff=" 2988 + Integer.toHexString(diffStates) + " lastDiff=" 2989 + Integer.toHexString(lastDiffStates) + " diff2=" 2990 + Integer.toHexString(diffStates2) + " lastDiff2=" 2991 + Integer.toHexString(lastDiffStates2)); 2992 if (mHistoryBufferLastPos >= 0 && mHistoryLastWritten.cmd == HistoryItem.CMD_UPDATE 2993 && timeDiff < 1000 && (diffStates&lastDiffStates) == 0 2994 && (diffStates2&lastDiffStates2) == 0 2995 && (mHistoryLastWritten.wakelockTag == null || cur.wakelockTag == null) 2996 && (mHistoryLastWritten.wakeReasonTag == null || cur.wakeReasonTag == null) 2997 && mHistoryLastWritten.stepDetails == null 2998 && (mHistoryLastWritten.eventCode == HistoryItem.EVENT_NONE 2999 || cur.eventCode == HistoryItem.EVENT_NONE) 3000 && mHistoryLastWritten.batteryLevel == cur.batteryLevel 3001 && mHistoryLastWritten.batteryStatus == cur.batteryStatus 3002 && mHistoryLastWritten.batteryHealth == cur.batteryHealth 3003 && mHistoryLastWritten.batteryPlugType == cur.batteryPlugType 3004 && mHistoryLastWritten.batteryTemperature == cur.batteryTemperature 3005 && mHistoryLastWritten.batteryVoltage == cur.batteryVoltage) { 3006 // We can merge this new change in with the last one. Merging is 3007 // allowed as long as only the states have changed, and within those states 3008 // as long as no bit has changed both between now and the last entry, as 3009 // well as the last entry and the one before it (so we capture any toggles). 3010 if (DEBUG) Slog.i(TAG, "ADD: rewinding back to " + mHistoryBufferLastPos); 3011 mHistoryBuffer.setDataSize(mHistoryBufferLastPos); 3012 mHistoryBuffer.setDataPosition(mHistoryBufferLastPos); 3013 mHistoryBufferLastPos = -1; 3014 elapsedRealtimeMs = mHistoryLastWritten.time - mHistoryBaseTime; 3015 // If the last written history had a wakelock tag, we need to retain it. 3016 // Note that the condition above made sure that we aren't in a case where 3017 // both it and the current history item have a wakelock tag. 3018 if (mHistoryLastWritten.wakelockTag != null) { 3019 cur.wakelockTag = cur.localWakelockTag; 3020 cur.wakelockTag.setTo(mHistoryLastWritten.wakelockTag); 3021 } 3022 // If the last written history had a wake reason tag, we need to retain it. 3023 // Note that the condition above made sure that we aren't in a case where 3024 // both it and the current history item have a wakelock tag. 3025 if (mHistoryLastWritten.wakeReasonTag != null) { 3026 cur.wakeReasonTag = cur.localWakeReasonTag; 3027 cur.wakeReasonTag.setTo(mHistoryLastWritten.wakeReasonTag); 3028 } 3029 // If the last written history had an event, we need to retain it. 3030 // Note that the condition above made sure that we aren't in a case where 3031 // both it and the current history item have an event. 3032 if (mHistoryLastWritten.eventCode != HistoryItem.EVENT_NONE) { 3033 cur.eventCode = mHistoryLastWritten.eventCode; 3034 cur.eventTag = cur.localEventTag; 3035 cur.eventTag.setTo(mHistoryLastWritten.eventTag); 3036 } 3037 mHistoryLastWritten.setTo(mHistoryLastLastWritten); 3038 } 3039 3040 boolean recordResetDueToOverflow = false; 3041 final int dataSize = mHistoryBuffer.dataSize(); 3042 if (dataSize >= MAX_MAX_HISTORY_BUFFER*3) { 3043 // Clients can't deal with history buffers this large. This only 3044 // really happens when the device is on charger and interacted with 3045 // for long periods of time, like in retail mode. Since the device is 3046 // most likely charged, when unplugged, stats would have reset anyways. 3047 // Reset the stats and mark that we overflowed. 3048 // b/32540341 3049 resetAllStatsLocked(); 3050 3051 // Mark that we want to set *OVERFLOW* event and the RESET:START 3052 // events. 3053 recordResetDueToOverflow = true; 3054 3055 } else if (dataSize >= MAX_HISTORY_BUFFER) { 3056 if (!mHistoryOverflow) { 3057 mHistoryOverflow = true; 3058 addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.CMD_UPDATE, cur); 3059 addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.CMD_OVERFLOW, cur); 3060 return; 3061 } 3062 3063 // After overflow, we allow various bit-wise states to settle to 0. 3064 boolean writeAnyway = false; 3065 final int curStates = cur.states & HistoryItem.SETTLE_TO_ZERO_STATES 3066 & mActiveHistoryStates; 3067 if (mHistoryLastWritten.states != curStates) { 3068 // mActiveHistoryStates keeps track of which bits in .states are now being 3069 // forced to 0. 3070 int old = mActiveHistoryStates; 3071 mActiveHistoryStates &= curStates | ~HistoryItem.SETTLE_TO_ZERO_STATES; 3072 writeAnyway |= old != mActiveHistoryStates; 3073 } 3074 final int curStates2 = cur.states2 & HistoryItem.SETTLE_TO_ZERO_STATES2 3075 & mActiveHistoryStates2; 3076 if (mHistoryLastWritten.states2 != curStates2) { 3077 // mActiveHistoryStates2 keeps track of which bits in .states2 are now being 3078 // forced to 0. 3079 int old = mActiveHistoryStates2; 3080 mActiveHistoryStates2 &= curStates2 | ~HistoryItem.SETTLE_TO_ZERO_STATES2; 3081 writeAnyway |= old != mActiveHistoryStates2; 3082 } 3083 3084 // Once we've reached the maximum number of items, we only 3085 // record changes to the battery level and the most interesting states. 3086 // Once we've reached the maximum maximum number of items, we only 3087 // record changes to the battery level. 3088 if (!writeAnyway && mHistoryLastWritten.batteryLevel == cur.batteryLevel && 3089 (dataSize >= MAX_MAX_HISTORY_BUFFER 3090 || ((mHistoryLastWritten.states^cur.states) 3091 & HistoryItem.MOST_INTERESTING_STATES) == 0 3092 || ((mHistoryLastWritten.states2^cur.states2) 3093 & HistoryItem.MOST_INTERESTING_STATES2) == 0)) { 3094 return; 3095 } 3096 3097 addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.CMD_UPDATE, cur); 3098 return; 3099 } 3100 3101 if (dataSize == 0 || recordResetDueToOverflow) { 3102 // The history is currently empty; we need it to start with a time stamp. 3103 cur.currentTime = System.currentTimeMillis(); 3104 if (recordResetDueToOverflow) { 3105 addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.CMD_OVERFLOW, cur); 3106 } 3107 addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.CMD_RESET, cur); 3108 } 3109 addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.CMD_UPDATE, cur); 3110 } 3111 3112 private void addHistoryBufferLocked(long elapsedRealtimeMs, long uptimeMs, byte cmd, 3113 HistoryItem cur) { 3114 if (mIteratingHistory) { 3115 throw new IllegalStateException("Can't do this while iterating history!"); 3116 } 3117 mHistoryBufferLastPos = mHistoryBuffer.dataPosition(); 3118 mHistoryLastLastWritten.setTo(mHistoryLastWritten); 3119 mHistoryLastWritten.setTo(mHistoryBaseTime + elapsedRealtimeMs, cmd, cur); 3120 mHistoryLastWritten.states &= mActiveHistoryStates; 3121 mHistoryLastWritten.states2 &= mActiveHistoryStates2; 3122 writeHistoryDelta(mHistoryBuffer, mHistoryLastWritten, mHistoryLastLastWritten); 3123 mLastHistoryElapsedRealtime = elapsedRealtimeMs; 3124 cur.wakelockTag = null; 3125 cur.wakeReasonTag = null; 3126 cur.eventCode = HistoryItem.EVENT_NONE; 3127 cur.eventTag = null; 3128 if (DEBUG_HISTORY) Slog.i(TAG, "Writing history buffer: was " + mHistoryBufferLastPos 3129 + " now " + mHistoryBuffer.dataPosition() 3130 + " size is now " + mHistoryBuffer.dataSize()); 3131 } 3132 3133 int mChangedStates = 0; 3134 int mChangedStates2 = 0; 3135 3136 void addHistoryRecordLocked(long elapsedRealtimeMs, long uptimeMs) { 3137 if (mTrackRunningHistoryElapsedRealtime != 0) { 3138 final long diffElapsed = elapsedRealtimeMs - mTrackRunningHistoryElapsedRealtime; 3139 final long diffUptime = uptimeMs - mTrackRunningHistoryUptime; 3140 if (diffUptime < (diffElapsed-20)) { 3141 final long wakeElapsedTime = elapsedRealtimeMs - (diffElapsed - diffUptime); 3142 mHistoryAddTmp.setTo(mHistoryLastWritten); 3143 mHistoryAddTmp.wakelockTag = null; 3144 mHistoryAddTmp.wakeReasonTag = null; 3145 mHistoryAddTmp.eventCode = HistoryItem.EVENT_NONE; 3146 mHistoryAddTmp.states &= ~HistoryItem.STATE_CPU_RUNNING_FLAG; 3147 addHistoryRecordInnerLocked(wakeElapsedTime, uptimeMs, mHistoryAddTmp); 3148 } 3149 } 3150 mHistoryCur.states |= HistoryItem.STATE_CPU_RUNNING_FLAG; 3151 mTrackRunningHistoryElapsedRealtime = elapsedRealtimeMs; 3152 mTrackRunningHistoryUptime = uptimeMs; 3153 addHistoryRecordInnerLocked(elapsedRealtimeMs, uptimeMs, mHistoryCur); 3154 } 3155 3156 void addHistoryRecordInnerLocked(long elapsedRealtimeMs, long uptimeMs, HistoryItem cur) { 3157 addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, cur); 3158 3159 if (!USE_OLD_HISTORY) { 3160 return; 3161 } 3162 3163 if (!mHaveBatteryLevel || !mRecordingHistory) { 3164 return; 3165 } 3166 3167 // If the current time is basically the same as the last time, 3168 // and no states have since the last recorded entry changed and 3169 // are now resetting back to their original value, then just collapse 3170 // into one record. 3171 if (mHistoryEnd != null && mHistoryEnd.cmd == HistoryItem.CMD_UPDATE 3172 && (mHistoryBaseTime+elapsedRealtimeMs) < (mHistoryEnd.time+1000) 3173 && ((mHistoryEnd.states^cur.states)&mChangedStates&mActiveHistoryStates) == 0 3174 && ((mHistoryEnd.states2^cur.states2)&mChangedStates2&mActiveHistoryStates2) == 0) { 3175 // If the current is the same as the one before, then we no 3176 // longer need the entry. 3177 if (mHistoryLastEnd != null && mHistoryLastEnd.cmd == HistoryItem.CMD_UPDATE 3178 && (mHistoryBaseTime+elapsedRealtimeMs) < (mHistoryEnd.time+500) 3179 && mHistoryLastEnd.sameNonEvent(cur)) { 3180 mHistoryLastEnd.next = null; 3181 mHistoryEnd.next = mHistoryCache; 3182 mHistoryCache = mHistoryEnd; 3183 mHistoryEnd = mHistoryLastEnd; 3184 mHistoryLastEnd = null; 3185 } else { 3186 mChangedStates |= mHistoryEnd.states^(cur.states&mActiveHistoryStates); 3187 mChangedStates2 |= mHistoryEnd.states^(cur.states2&mActiveHistoryStates2); 3188 mHistoryEnd.setTo(mHistoryEnd.time, HistoryItem.CMD_UPDATE, cur); 3189 } 3190 return; 3191 } 3192 3193 mChangedStates = 0; 3194 mChangedStates2 = 0; 3195 3196 if (mNumHistoryItems == MAX_HISTORY_ITEMS 3197 || mNumHistoryItems == MAX_MAX_HISTORY_ITEMS) { 3198 addHistoryRecordLocked(elapsedRealtimeMs, HistoryItem.CMD_OVERFLOW); 3199 } 3200 3201 if (mNumHistoryItems >= MAX_HISTORY_ITEMS) { 3202 // Once we've reached the maximum number of items, we only 3203 // record changes to the battery level and the most interesting states. 3204 // Once we've reached the maximum maximum number of items, we only 3205 // record changes to the battery level. 3206 if (mHistoryEnd != null && mHistoryEnd.batteryLevel 3207 == cur.batteryLevel && 3208 (mNumHistoryItems >= MAX_MAX_HISTORY_ITEMS 3209 || ((mHistoryEnd.states^(cur.states&mActiveHistoryStates)) 3210 & HistoryItem.MOST_INTERESTING_STATES) == 0)) { 3211 return; 3212 } 3213 } 3214 3215 addHistoryRecordLocked(elapsedRealtimeMs, HistoryItem.CMD_UPDATE); 3216 } 3217 3218 public void addHistoryEventLocked(long elapsedRealtimeMs, long uptimeMs, int code, 3219 String name, int uid) { 3220 mHistoryCur.eventCode = code; 3221 mHistoryCur.eventTag = mHistoryCur.localEventTag; 3222 mHistoryCur.eventTag.string = name; 3223 mHistoryCur.eventTag.uid = uid; 3224 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 3225 } 3226 3227 void addHistoryRecordLocked(long elapsedRealtimeMs, long uptimeMs, byte cmd, HistoryItem cur) { 3228 HistoryItem rec = mHistoryCache; 3229 if (rec != null) { 3230 mHistoryCache = rec.next; 3231 } else { 3232 rec = new HistoryItem(); 3233 } 3234 rec.setTo(mHistoryBaseTime + elapsedRealtimeMs, cmd, cur); 3235 3236 addHistoryRecordLocked(rec); 3237 } 3238 3239 void addHistoryRecordLocked(HistoryItem rec) { 3240 mNumHistoryItems++; 3241 rec.next = null; 3242 mHistoryLastEnd = mHistoryEnd; 3243 if (mHistoryEnd != null) { 3244 mHistoryEnd.next = rec; 3245 mHistoryEnd = rec; 3246 } else { 3247 mHistory = mHistoryEnd = rec; 3248 } 3249 } 3250 3251 void clearHistoryLocked() { 3252 if (DEBUG_HISTORY) Slog.i(TAG, "********** CLEARING HISTORY!"); 3253 if (USE_OLD_HISTORY) { 3254 if (mHistory != null) { 3255 mHistoryEnd.next = mHistoryCache; 3256 mHistoryCache = mHistory; 3257 mHistory = mHistoryLastEnd = mHistoryEnd = null; 3258 } 3259 mNumHistoryItems = 0; 3260 } 3261 3262 mHistoryBaseTime = 0; 3263 mLastHistoryElapsedRealtime = 0; 3264 mTrackRunningHistoryElapsedRealtime = 0; 3265 mTrackRunningHistoryUptime = 0; 3266 3267 mHistoryBuffer.setDataSize(0); 3268 mHistoryBuffer.setDataPosition(0); 3269 mHistoryBuffer.setDataCapacity(MAX_HISTORY_BUFFER / 2); 3270 mHistoryLastLastWritten.clear(); 3271 mHistoryLastWritten.clear(); 3272 mHistoryTagPool.clear(); 3273 mNextHistoryTagIdx = 0; 3274 mNumHistoryTagChars = 0; 3275 mHistoryBufferLastPos = -1; 3276 mHistoryOverflow = false; 3277 mActiveHistoryStates = 0xffffffff; 3278 mActiveHistoryStates2 = 0xffffffff; 3279 } 3280 3281 public void updateTimeBasesLocked(boolean unplugged, boolean screenOff, long uptime, 3282 long realtime) { 3283 boolean batteryStatusChanged = mOnBatteryTimeBase.setRunning(unplugged, uptime, realtime); 3284 3285 if (batteryStatusChanged) { 3286 for (int i=0; i<mUidStats.size(); i++) { 3287 mUidStats.valueAt(i).updateBgTimeBase(uptime, realtime); 3288 } 3289 } 3290 3291 boolean unpluggedScreenOff = unplugged && screenOff; 3292 if (unpluggedScreenOff != mOnBatteryScreenOffTimeBase.isRunning()) { 3293 updateKernelWakelocksLocked(); 3294 updateBatteryPropertiesLocked(); 3295 if (DEBUG_ENERGY_CPU) { 3296 Slog.d(TAG, "Updating cpu time because screen is now " + 3297 (unpluggedScreenOff ? "off" : "on")); 3298 } 3299 updateCpuTimeLocked(); 3300 mOnBatteryScreenOffTimeBase.setRunning(unpluggedScreenOff, uptime, realtime); 3301 } 3302 } 3303 3304 private void updateBatteryPropertiesLocked() { 3305 try { 3306 IBatteryPropertiesRegistrar registrar = IBatteryPropertiesRegistrar.Stub.asInterface( 3307 ServiceManager.getService("batteryproperties")); 3308 registrar.scheduleUpdate(); 3309 } catch (RemoteException e) { 3310 // Ignore. 3311 } 3312 } 3313 3314 public void addIsolatedUidLocked(int isolatedUid, int appUid) { 3315 mIsolatedUids.put(isolatedUid, appUid); 3316 } 3317 3318 /** 3319 * Schedules a read of the latest cpu times before removing the isolated UID. 3320 * @see #removeIsolatedUidLocked(int) 3321 */ 3322 public void scheduleRemoveIsolatedUidLocked(int isolatedUid, int appUid) { 3323 int curUid = mIsolatedUids.get(isolatedUid, -1); 3324 if (curUid == appUid) { 3325 if (mExternalSync != null) { 3326 mExternalSync.scheduleCpuSyncDueToRemovedUid(isolatedUid); 3327 } 3328 } 3329 } 3330 3331 /** 3332 * This should only be called after the cpu times have been read. 3333 * @see #scheduleRemoveIsolatedUidLocked(int, int) 3334 */ 3335 public void removeIsolatedUidLocked(int isolatedUid) { 3336 mIsolatedUids.delete(isolatedUid); 3337 mKernelUidCpuTimeReader.removeUid(isolatedUid); 3338 } 3339 3340 public int mapUid(int uid) { 3341 int isolated = mIsolatedUids.get(uid, -1); 3342 return isolated > 0 ? isolated : uid; 3343 } 3344 3345 public void noteEventLocked(int code, String name, int uid) { 3346 uid = mapUid(uid); 3347 if (!mActiveEvents.updateState(code, name, uid, 0)) { 3348 return; 3349 } 3350 final long elapsedRealtime = mClocks.elapsedRealtime(); 3351 final long uptime = mClocks.uptimeMillis(); 3352 addHistoryEventLocked(elapsedRealtime, uptime, code, name, uid); 3353 } 3354 3355 boolean ensureStartClockTime(final long currentTime) { 3356 final long ABOUT_ONE_YEAR = 365*24*60*60*1000L; 3357 if (currentTime > ABOUT_ONE_YEAR && mStartClockTime < (currentTime-ABOUT_ONE_YEAR)) { 3358 // If the start clock time has changed by more than a year, then presumably 3359 // the previous time was completely bogus. So we are going to figure out a 3360 // new time based on how much time has elapsed since we started counting. 3361 mStartClockTime = currentTime - (mClocks.elapsedRealtime()-(mRealtimeStart/1000)); 3362 return true; 3363 } 3364 return false; 3365 } 3366 3367 public void noteCurrentTimeChangedLocked() { 3368 final long currentTime = System.currentTimeMillis(); 3369 final long elapsedRealtime = mClocks.elapsedRealtime(); 3370 final long uptime = mClocks.uptimeMillis(); 3371 recordCurrentTimeChangeLocked(currentTime, elapsedRealtime, uptime); 3372 ensureStartClockTime(currentTime); 3373 } 3374 3375 public void noteProcessStartLocked(String name, int uid) { 3376 uid = mapUid(uid); 3377 if (isOnBattery()) { 3378 Uid u = getUidStatsLocked(uid); 3379 u.getProcessStatsLocked(name).incStartsLocked(); 3380 } 3381 if (!mActiveEvents.updateState(HistoryItem.EVENT_PROC_START, name, uid, 0)) { 3382 return; 3383 } 3384 if (!mRecordAllHistory) { 3385 return; 3386 } 3387 final long elapsedRealtime = mClocks.elapsedRealtime(); 3388 final long uptime = mClocks.uptimeMillis(); 3389 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_PROC_START, name, uid); 3390 } 3391 3392 public void noteProcessCrashLocked(String name, int uid) { 3393 uid = mapUid(uid); 3394 if (isOnBattery()) { 3395 Uid u = getUidStatsLocked(uid); 3396 u.getProcessStatsLocked(name).incNumCrashesLocked(); 3397 } 3398 } 3399 3400 public void noteProcessAnrLocked(String name, int uid) { 3401 uid = mapUid(uid); 3402 if (isOnBattery()) { 3403 Uid u = getUidStatsLocked(uid); 3404 u.getProcessStatsLocked(name).incNumAnrsLocked(); 3405 } 3406 } 3407 3408 public void noteUidProcessStateLocked(int uid, int state) { 3409 uid = mapUid(uid); 3410 getUidStatsLocked(uid).updateUidProcessStateLocked(state); 3411 } 3412 3413 public void noteProcessFinishLocked(String name, int uid) { 3414 uid = mapUid(uid); 3415 if (!mActiveEvents.updateState(HistoryItem.EVENT_PROC_FINISH, name, uid, 0)) { 3416 return; 3417 } 3418 if (!mRecordAllHistory) { 3419 return; 3420 } 3421 final long elapsedRealtime = mClocks.elapsedRealtime(); 3422 final long uptime = mClocks.uptimeMillis(); 3423 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_PROC_FINISH, name, uid); 3424 } 3425 3426 public void noteSyncStartLocked(String name, int uid) { 3427 uid = mapUid(uid); 3428 final long elapsedRealtime = mClocks.elapsedRealtime(); 3429 final long uptime = mClocks.uptimeMillis(); 3430 getUidStatsLocked(uid).noteStartSyncLocked(name, elapsedRealtime); 3431 if (!mActiveEvents.updateState(HistoryItem.EVENT_SYNC_START, name, uid, 0)) { 3432 return; 3433 } 3434 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_SYNC_START, name, uid); 3435 } 3436 3437 public void noteSyncFinishLocked(String name, int uid) { 3438 uid = mapUid(uid); 3439 final long elapsedRealtime = mClocks.elapsedRealtime(); 3440 final long uptime = mClocks.uptimeMillis(); 3441 getUidStatsLocked(uid).noteStopSyncLocked(name, elapsedRealtime); 3442 if (!mActiveEvents.updateState(HistoryItem.EVENT_SYNC_FINISH, name, uid, 0)) { 3443 return; 3444 } 3445 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_SYNC_FINISH, name, uid); 3446 } 3447 3448 public void noteJobStartLocked(String name, int uid) { 3449 uid = mapUid(uid); 3450 final long elapsedRealtime = mClocks.elapsedRealtime(); 3451 final long uptime = mClocks.uptimeMillis(); 3452 getUidStatsLocked(uid).noteStartJobLocked(name, elapsedRealtime); 3453 if (!mActiveEvents.updateState(HistoryItem.EVENT_JOB_START, name, uid, 0)) { 3454 return; 3455 } 3456 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_JOB_START, name, uid); 3457 } 3458 3459 public void noteJobFinishLocked(String name, int uid) { 3460 uid = mapUid(uid); 3461 final long elapsedRealtime = mClocks.elapsedRealtime(); 3462 final long uptime = mClocks.uptimeMillis(); 3463 getUidStatsLocked(uid).noteStopJobLocked(name, elapsedRealtime); 3464 if (!mActiveEvents.updateState(HistoryItem.EVENT_JOB_FINISH, name, uid, 0)) { 3465 return; 3466 } 3467 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_JOB_FINISH, name, uid); 3468 } 3469 3470 public void noteAlarmStartLocked(String name, int uid) { 3471 if (!mRecordAllHistory) { 3472 return; 3473 } 3474 uid = mapUid(uid); 3475 final long elapsedRealtime = mClocks.elapsedRealtime(); 3476 final long uptime = mClocks.uptimeMillis(); 3477 if (!mActiveEvents.updateState(HistoryItem.EVENT_ALARM_START, name, uid, 0)) { 3478 return; 3479 } 3480 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_ALARM_START, name, uid); 3481 } 3482 3483 public void noteAlarmFinishLocked(String name, int uid) { 3484 if (!mRecordAllHistory) { 3485 return; 3486 } 3487 uid = mapUid(uid); 3488 final long elapsedRealtime = mClocks.elapsedRealtime(); 3489 final long uptime = mClocks.uptimeMillis(); 3490 if (!mActiveEvents.updateState(HistoryItem.EVENT_ALARM_FINISH, name, uid, 0)) { 3491 return; 3492 } 3493 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_ALARM_FINISH, name, uid); 3494 } 3495 3496 private void requestWakelockCpuUpdate() { 3497 if (!mHandler.hasMessages(MSG_UPDATE_WAKELOCKS)) { 3498 Message m = mHandler.obtainMessage(MSG_UPDATE_WAKELOCKS); 3499 mHandler.sendMessageDelayed(m, DELAY_UPDATE_WAKELOCKS); 3500 } 3501 } 3502 3503 private void requestImmediateCpuUpdate() { 3504 mHandler.removeMessages(MSG_UPDATE_WAKELOCKS); 3505 mHandler.sendEmptyMessage(MSG_UPDATE_WAKELOCKS); 3506 } 3507 3508 public void setRecordAllHistoryLocked(boolean enabled) { 3509 mRecordAllHistory = enabled; 3510 if (!enabled) { 3511 // Clear out any existing state. 3512 mActiveEvents.removeEvents(HistoryItem.EVENT_WAKE_LOCK); 3513 mActiveEvents.removeEvents(HistoryItem.EVENT_ALARM); 3514 // Record the currently running processes as stopping, now that we are no 3515 // longer tracking them. 3516 HashMap<String, SparseIntArray> active = mActiveEvents.getStateForEvent( 3517 HistoryItem.EVENT_PROC); 3518 if (active != null) { 3519 long mSecRealtime = mClocks.elapsedRealtime(); 3520 final long mSecUptime = mClocks.uptimeMillis(); 3521 for (HashMap.Entry<String, SparseIntArray> ent : active.entrySet()) { 3522 SparseIntArray uids = ent.getValue(); 3523 for (int j=0; j<uids.size(); j++) { 3524 addHistoryEventLocked(mSecRealtime, mSecUptime, 3525 HistoryItem.EVENT_PROC_FINISH, ent.getKey(), uids.keyAt(j)); 3526 } 3527 } 3528 } 3529 } else { 3530 // Record the currently running processes as starting, now that we are tracking them. 3531 HashMap<String, SparseIntArray> active = mActiveEvents.getStateForEvent( 3532 HistoryItem.EVENT_PROC); 3533 if (active != null) { 3534 long mSecRealtime = mClocks.elapsedRealtime(); 3535 final long mSecUptime = mClocks.uptimeMillis(); 3536 for (HashMap.Entry<String, SparseIntArray> ent : active.entrySet()) { 3537 SparseIntArray uids = ent.getValue(); 3538 for (int j=0; j<uids.size(); j++) { 3539 addHistoryEventLocked(mSecRealtime, mSecUptime, 3540 HistoryItem.EVENT_PROC_START, ent.getKey(), uids.keyAt(j)); 3541 } 3542 } 3543 } 3544 } 3545 } 3546 3547 public void setNoAutoReset(boolean enabled) { 3548 mNoAutoReset = enabled; 3549 } 3550 3551 public void setPretendScreenOff(boolean pretendScreenOff) { 3552 mPretendScreenOff = pretendScreenOff; 3553 noteScreenStateLocked(pretendScreenOff ? Display.STATE_OFF : Display.STATE_ON); 3554 } 3555 3556 private String mInitialAcquireWakeName; 3557 private int mInitialAcquireWakeUid = -1; 3558 3559 public void noteStartWakeLocked(int uid, int pid, String name, String historyName, int type, 3560 boolean unimportantForLogging, long elapsedRealtime, long uptime) { 3561 uid = mapUid(uid); 3562 if (type == WAKE_TYPE_PARTIAL) { 3563 // Only care about partial wake locks, since full wake locks 3564 // will be canceled when the user puts the screen to sleep. 3565 aggregateLastWakeupUptimeLocked(uptime); 3566 if (historyName == null) { 3567 historyName = name; 3568 } 3569 if (mRecordAllHistory) { 3570 if (mActiveEvents.updateState(HistoryItem.EVENT_WAKE_LOCK_START, historyName, 3571 uid, 0)) { 3572 addHistoryEventLocked(elapsedRealtime, uptime, 3573 HistoryItem.EVENT_WAKE_LOCK_START, historyName, uid); 3574 } 3575 } 3576 if (mWakeLockNesting == 0) { 3577 mHistoryCur.states |= HistoryItem.STATE_WAKE_LOCK_FLAG; 3578 if (DEBUG_HISTORY) Slog.v(TAG, "Start wake lock to: " 3579 + Integer.toHexString(mHistoryCur.states)); 3580 mHistoryCur.wakelockTag = mHistoryCur.localWakelockTag; 3581 mHistoryCur.wakelockTag.string = mInitialAcquireWakeName = historyName; 3582 mHistoryCur.wakelockTag.uid = mInitialAcquireWakeUid = uid; 3583 mWakeLockImportant = !unimportantForLogging; 3584 addHistoryRecordLocked(elapsedRealtime, uptime); 3585 } else if (!mWakeLockImportant && !unimportantForLogging 3586 && mHistoryLastWritten.cmd == HistoryItem.CMD_UPDATE) { 3587 if (mHistoryLastWritten.wakelockTag != null) { 3588 // We'll try to update the last tag. 3589 mHistoryLastWritten.wakelockTag = null; 3590 mHistoryCur.wakelockTag = mHistoryCur.localWakelockTag; 3591 mHistoryCur.wakelockTag.string = mInitialAcquireWakeName = historyName; 3592 mHistoryCur.wakelockTag.uid = mInitialAcquireWakeUid = uid; 3593 addHistoryRecordLocked(elapsedRealtime, uptime); 3594 } 3595 mWakeLockImportant = true; 3596 } 3597 mWakeLockNesting++; 3598 } 3599 if (uid >= 0) { 3600 if (mOnBatteryScreenOffTimeBase.isRunning()) { 3601 // We only update the cpu time when a wake lock is acquired if the screen is off. 3602 // If the screen is on, we don't distribute the power amongst partial wakelocks. 3603 if (DEBUG_ENERGY_CPU) { 3604 Slog.d(TAG, "Updating cpu time because of +wake_lock"); 3605 } 3606 requestWakelockCpuUpdate(); 3607 } 3608 getUidStatsLocked(uid).noteStartWakeLocked(pid, name, type, elapsedRealtime); 3609 } 3610 } 3611 3612 public void noteStopWakeLocked(int uid, int pid, String name, String historyName, int type, 3613 long elapsedRealtime, long uptime) { 3614 uid = mapUid(uid); 3615 if (type == WAKE_TYPE_PARTIAL) { 3616 mWakeLockNesting--; 3617 if (mRecordAllHistory) { 3618 if (historyName == null) { 3619 historyName = name; 3620 } 3621 if (mActiveEvents.updateState(HistoryItem.EVENT_WAKE_LOCK_FINISH, historyName, 3622 uid, 0)) { 3623 addHistoryEventLocked(elapsedRealtime, uptime, 3624 HistoryItem.EVENT_WAKE_LOCK_FINISH, historyName, uid); 3625 } 3626 } 3627 if (mWakeLockNesting == 0) { 3628 mHistoryCur.states &= ~HistoryItem.STATE_WAKE_LOCK_FLAG; 3629 if (DEBUG_HISTORY) Slog.v(TAG, "Stop wake lock to: " 3630 + Integer.toHexString(mHistoryCur.states)); 3631 mInitialAcquireWakeName = null; 3632 mInitialAcquireWakeUid = -1; 3633 addHistoryRecordLocked(elapsedRealtime, uptime); 3634 } 3635 } 3636 if (uid >= 0) { 3637 if (mOnBatteryScreenOffTimeBase.isRunning()) { 3638 if (DEBUG_ENERGY_CPU) { 3639 Slog.d(TAG, "Updating cpu time because of -wake_lock"); 3640 } 3641 requestWakelockCpuUpdate(); 3642 } 3643 getUidStatsLocked(uid).noteStopWakeLocked(pid, name, type, elapsedRealtime); 3644 } 3645 } 3646 3647 public void noteStartWakeFromSourceLocked(WorkSource ws, int pid, String name, 3648 String historyName, int type, boolean unimportantForLogging) { 3649 final long elapsedRealtime = mClocks.elapsedRealtime(); 3650 final long uptime = mClocks.uptimeMillis(); 3651 final int N = ws.size(); 3652 for (int i=0; i<N; i++) { 3653 noteStartWakeLocked(ws.get(i), pid, name, historyName, type, unimportantForLogging, 3654 elapsedRealtime, uptime); 3655 } 3656 } 3657 3658 public void noteChangeWakelockFromSourceLocked(WorkSource ws, int pid, String name, 3659 String historyName, int type, WorkSource newWs, int newPid, String newName, 3660 String newHistoryName, int newType, boolean newUnimportantForLogging) { 3661 final long elapsedRealtime = mClocks.elapsedRealtime(); 3662 final long uptime = mClocks.uptimeMillis(); 3663 // For correct semantics, we start the need worksources first, so that we won't 3664 // make inappropriate history items as if all wake locks went away and new ones 3665 // appeared. This is okay because tracking of wake locks allows nesting. 3666 final int NN = newWs.size(); 3667 for (int i=0; i<NN; i++) { 3668 noteStartWakeLocked(newWs.get(i), newPid, newName, newHistoryName, newType, 3669 newUnimportantForLogging, elapsedRealtime, uptime); 3670 } 3671 final int NO = ws.size(); 3672 for (int i=0; i<NO; i++) { 3673 noteStopWakeLocked(ws.get(i), pid, name, historyName, type, elapsedRealtime, uptime); 3674 } 3675 } 3676 3677 public void noteStopWakeFromSourceLocked(WorkSource ws, int pid, String name, 3678 String historyName, int type) { 3679 final long elapsedRealtime = mClocks.elapsedRealtime(); 3680 final long uptime = mClocks.uptimeMillis(); 3681 final int N = ws.size(); 3682 for (int i=0; i<N; i++) { 3683 noteStopWakeLocked(ws.get(i), pid, name, historyName, type, elapsedRealtime, uptime); 3684 } 3685 } 3686 3687 public void noteLongPartialWakelockStart(String name, String historyName, int uid) { 3688 uid = mapUid(uid); 3689 final long elapsedRealtime = mClocks.elapsedRealtime(); 3690 final long uptime = mClocks.uptimeMillis(); 3691 if (historyName == null) { 3692 historyName = name; 3693 } 3694 if (!mActiveEvents.updateState(HistoryItem.EVENT_LONG_WAKE_LOCK_START, historyName, uid, 3695 0)) { 3696 return; 3697 } 3698 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_LONG_WAKE_LOCK_START, 3699 historyName, uid); 3700 } 3701 3702 public void noteLongPartialWakelockFinish(String name, String historyName, int uid) { 3703 uid = mapUid(uid); 3704 final long elapsedRealtime = mClocks.elapsedRealtime(); 3705 final long uptime = mClocks.uptimeMillis(); 3706 if (historyName == null) { 3707 historyName = name; 3708 } 3709 if (!mActiveEvents.updateState(HistoryItem.EVENT_LONG_WAKE_LOCK_FINISH, historyName, uid, 3710 0)) { 3711 return; 3712 } 3713 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_LONG_WAKE_LOCK_FINISH, 3714 historyName, uid); 3715 } 3716 3717 void aggregateLastWakeupUptimeLocked(long uptimeMs) { 3718 if (mLastWakeupReason != null) { 3719 long deltaUptime = uptimeMs - mLastWakeupUptimeMs; 3720 SamplingTimer timer = getWakeupReasonTimerLocked(mLastWakeupReason); 3721 timer.add(deltaUptime * 1000, 1); // time in in microseconds 3722 mLastWakeupReason = null; 3723 } 3724 } 3725 3726 public void noteWakeupReasonLocked(String reason) { 3727 final long elapsedRealtime = mClocks.elapsedRealtime(); 3728 final long uptime = mClocks.uptimeMillis(); 3729 if (DEBUG_HISTORY) Slog.v(TAG, "Wakeup reason \"" + reason +"\": " 3730 + Integer.toHexString(mHistoryCur.states)); 3731 aggregateLastWakeupUptimeLocked(uptime); 3732 mHistoryCur.wakeReasonTag = mHistoryCur.localWakeReasonTag; 3733 mHistoryCur.wakeReasonTag.string = reason; 3734 mHistoryCur.wakeReasonTag.uid = 0; 3735 mLastWakeupReason = reason; 3736 mLastWakeupUptimeMs = uptime; 3737 addHistoryRecordLocked(elapsedRealtime, uptime); 3738 } 3739 3740 public boolean startAddingCpuLocked() { 3741 mHandler.removeMessages(MSG_UPDATE_WAKELOCKS); 3742 return mOnBatteryInternal; 3743 } 3744 3745 public void finishAddingCpuLocked(int totalUTime, int totalSTime, int statUserTime, 3746 int statSystemTime, int statIOWaitTime, int statIrqTime, 3747 int statSoftIrqTime, int statIdleTime) { 3748 if (DEBUG) Slog.d(TAG, "Adding cpu: tuser=" + totalUTime + " tsys=" + totalSTime 3749 + " user=" + statUserTime + " sys=" + statSystemTime 3750 + " io=" + statIOWaitTime + " irq=" + statIrqTime 3751 + " sirq=" + statSoftIrqTime + " idle=" + statIdleTime); 3752 mCurStepCpuUserTime += totalUTime; 3753 mCurStepCpuSystemTime += totalSTime; 3754 mCurStepStatUserTime += statUserTime; 3755 mCurStepStatSystemTime += statSystemTime; 3756 mCurStepStatIOWaitTime += statIOWaitTime; 3757 mCurStepStatIrqTime += statIrqTime; 3758 mCurStepStatSoftIrqTime += statSoftIrqTime; 3759 mCurStepStatIdleTime += statIdleTime; 3760 } 3761 3762 public void noteProcessDiedLocked(int uid, int pid) { 3763 uid = mapUid(uid); 3764 Uid u = mUidStats.get(uid); 3765 if (u != null) { 3766 u.mPids.remove(pid); 3767 } 3768 } 3769 3770 public long getProcessWakeTime(int uid, int pid, long realtime) { 3771 uid = mapUid(uid); 3772 Uid u = mUidStats.get(uid); 3773 if (u != null) { 3774 Uid.Pid p = u.mPids.get(pid); 3775 if (p != null) { 3776 return p.mWakeSumMs + (p.mWakeNesting > 0 ? (realtime - p.mWakeStartMs) : 0); 3777 } 3778 } 3779 return 0; 3780 } 3781 3782 public void reportExcessiveWakeLocked(int uid, String proc, long overTime, long usedTime) { 3783 uid = mapUid(uid); 3784 Uid u = mUidStats.get(uid); 3785 if (u != null) { 3786 u.reportExcessiveWakeLocked(proc, overTime, usedTime); 3787 } 3788 } 3789 3790 public void reportExcessiveCpuLocked(int uid, String proc, long overTime, long usedTime) { 3791 uid = mapUid(uid); 3792 Uid u = mUidStats.get(uid); 3793 if (u != null) { 3794 u.reportExcessiveCpuLocked(proc, overTime, usedTime); 3795 } 3796 } 3797 3798 int mSensorNesting; 3799 3800 public void noteStartSensorLocked(int uid, int sensor) { 3801 uid = mapUid(uid); 3802 final long elapsedRealtime = mClocks.elapsedRealtime(); 3803 final long uptime = mClocks.uptimeMillis(); 3804 if (mSensorNesting == 0) { 3805 mHistoryCur.states |= HistoryItem.STATE_SENSOR_ON_FLAG; 3806 if (DEBUG_HISTORY) Slog.v(TAG, "Start sensor to: " 3807 + Integer.toHexString(mHistoryCur.states)); 3808 addHistoryRecordLocked(elapsedRealtime, uptime); 3809 } 3810 mSensorNesting++; 3811 getUidStatsLocked(uid).noteStartSensor(sensor, elapsedRealtime); 3812 } 3813 3814 public void noteStopSensorLocked(int uid, int sensor) { 3815 uid = mapUid(uid); 3816 final long elapsedRealtime = mClocks.elapsedRealtime(); 3817 final long uptime = mClocks.uptimeMillis(); 3818 mSensorNesting--; 3819 if (mSensorNesting == 0) { 3820 mHistoryCur.states &= ~HistoryItem.STATE_SENSOR_ON_FLAG; 3821 if (DEBUG_HISTORY) Slog.v(TAG, "Stop sensor to: " 3822 + Integer.toHexString(mHistoryCur.states)); 3823 addHistoryRecordLocked(elapsedRealtime, uptime); 3824 } 3825 getUidStatsLocked(uid).noteStopSensor(sensor, elapsedRealtime); 3826 } 3827 3828 int mGpsNesting; 3829 3830 public void noteStartGpsLocked(int uid) { 3831 uid = mapUid(uid); 3832 final long elapsedRealtime = mClocks.elapsedRealtime(); 3833 final long uptime = mClocks.uptimeMillis(); 3834 if (mGpsNesting == 0) { 3835 mHistoryCur.states |= HistoryItem.STATE_GPS_ON_FLAG; 3836 if (DEBUG_HISTORY) Slog.v(TAG, "Start GPS to: " 3837 + Integer.toHexString(mHistoryCur.states)); 3838 addHistoryRecordLocked(elapsedRealtime, uptime); 3839 } 3840 mGpsNesting++; 3841 getUidStatsLocked(uid).noteStartGps(elapsedRealtime); 3842 } 3843 3844 public void noteStopGpsLocked(int uid) { 3845 uid = mapUid(uid); 3846 final long elapsedRealtime = mClocks.elapsedRealtime(); 3847 final long uptime = mClocks.uptimeMillis(); 3848 mGpsNesting--; 3849 if (mGpsNesting == 0) { 3850 mHistoryCur.states &= ~HistoryItem.STATE_GPS_ON_FLAG; 3851 if (DEBUG_HISTORY) Slog.v(TAG, "Stop GPS to: " 3852 + Integer.toHexString(mHistoryCur.states)); 3853 addHistoryRecordLocked(elapsedRealtime, uptime); 3854 } 3855 getUidStatsLocked(uid).noteStopGps(elapsedRealtime); 3856 } 3857 3858 public void noteScreenStateLocked(int state) { 3859 state = mPretendScreenOff ? Display.STATE_OFF : state; 3860 3861 // Battery stats relies on there being 4 states. To accommodate this, new states beyond the 3862 // original 4 are mapped to one of the originals. 3863 if (state > MAX_TRACKED_SCREEN_STATE) { 3864 switch (state) { 3865 case Display.STATE_VR: 3866 state = Display.STATE_ON; 3867 break; 3868 default: 3869 Slog.wtf(TAG, "Unknown screen state (not mapped): " + state); 3870 break; 3871 } 3872 } 3873 3874 if (mScreenState != state) { 3875 recordDailyStatsIfNeededLocked(true); 3876 final int oldState = mScreenState; 3877 mScreenState = state; 3878 if (DEBUG) Slog.v(TAG, "Screen state: oldState=" + Display.stateToString(oldState) 3879 + ", newState=" + Display.stateToString(state)); 3880 3881 if (state != Display.STATE_UNKNOWN) { 3882 int stepState = state-1; 3883 if ((stepState & STEP_LEVEL_MODE_SCREEN_STATE) == stepState) { 3884 mModStepMode |= (mCurStepMode & STEP_LEVEL_MODE_SCREEN_STATE) ^ stepState; 3885 mCurStepMode = (mCurStepMode & ~STEP_LEVEL_MODE_SCREEN_STATE) | stepState; 3886 } else { 3887 Slog.wtf(TAG, "Unexpected screen state: " + state); 3888 } 3889 } 3890 3891 if (state == Display.STATE_ON) { 3892 // Screen turning on. 3893 final long elapsedRealtime = mClocks.elapsedRealtime(); 3894 final long uptime = mClocks.uptimeMillis(); 3895 mHistoryCur.states |= HistoryItem.STATE_SCREEN_ON_FLAG; 3896 if (DEBUG_HISTORY) Slog.v(TAG, "Screen on to: " 3897 + Integer.toHexString(mHistoryCur.states)); 3898 addHistoryRecordLocked(elapsedRealtime, uptime); 3899 mScreenOnTimer.startRunningLocked(elapsedRealtime); 3900 if (mScreenBrightnessBin >= 0) { 3901 mScreenBrightnessTimer[mScreenBrightnessBin].startRunningLocked(elapsedRealtime); 3902 } 3903 3904 updateTimeBasesLocked(mOnBatteryTimeBase.isRunning(), false, 3905 mClocks.uptimeMillis() * 1000, elapsedRealtime * 1000); 3906 3907 // Fake a wake lock, so we consider the device waked as long 3908 // as the screen is on. 3909 noteStartWakeLocked(-1, -1, "screen", null, WAKE_TYPE_PARTIAL, false, 3910 elapsedRealtime, uptime); 3911 3912 // Update discharge amounts. 3913 if (mOnBatteryInternal) { 3914 updateDischargeScreenLevelsLocked(false, true); 3915 } 3916 } else if (oldState == Display.STATE_ON) { 3917 // Screen turning off or dozing. 3918 final long elapsedRealtime = mClocks.elapsedRealtime(); 3919 final long uptime = mClocks.uptimeMillis(); 3920 mHistoryCur.states &= ~HistoryItem.STATE_SCREEN_ON_FLAG; 3921 if (DEBUG_HISTORY) Slog.v(TAG, "Screen off to: " 3922 + Integer.toHexString(mHistoryCur.states)); 3923 addHistoryRecordLocked(elapsedRealtime, uptime); 3924 mScreenOnTimer.stopRunningLocked(elapsedRealtime); 3925 if (mScreenBrightnessBin >= 0) { 3926 mScreenBrightnessTimer[mScreenBrightnessBin].stopRunningLocked(elapsedRealtime); 3927 } 3928 3929 noteStopWakeLocked(-1, -1, "screen", "screen", WAKE_TYPE_PARTIAL, 3930 elapsedRealtime, uptime); 3931 3932 updateTimeBasesLocked(mOnBatteryTimeBase.isRunning(), true, 3933 mClocks.uptimeMillis() * 1000, elapsedRealtime * 1000); 3934 3935 // Update discharge amounts. 3936 if (mOnBatteryInternal) { 3937 updateDischargeScreenLevelsLocked(true, false); 3938 } 3939 } 3940 } 3941 } 3942 3943 public void noteScreenBrightnessLocked(int brightness) { 3944 // Bin the brightness. 3945 int bin = brightness / (256/NUM_SCREEN_BRIGHTNESS_BINS); 3946 if (bin < 0) bin = 0; 3947 else if (bin >= NUM_SCREEN_BRIGHTNESS_BINS) bin = NUM_SCREEN_BRIGHTNESS_BINS-1; 3948 if (mScreenBrightnessBin != bin) { 3949 final long elapsedRealtime = mClocks.elapsedRealtime(); 3950 final long uptime = mClocks.uptimeMillis(); 3951 mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_BRIGHTNESS_MASK) 3952 | (bin << HistoryItem.STATE_BRIGHTNESS_SHIFT); 3953 if (DEBUG_HISTORY) Slog.v(TAG, "Screen brightness " + bin + " to: " 3954 + Integer.toHexString(mHistoryCur.states)); 3955 addHistoryRecordLocked(elapsedRealtime, uptime); 3956 if (mScreenState == Display.STATE_ON) { 3957 if (mScreenBrightnessBin >= 0) { 3958 mScreenBrightnessTimer[mScreenBrightnessBin].stopRunningLocked(elapsedRealtime); 3959 } 3960 mScreenBrightnessTimer[bin].startRunningLocked(elapsedRealtime); 3961 } 3962 mScreenBrightnessBin = bin; 3963 } 3964 } 3965 3966 public void noteUserActivityLocked(int uid, int event) { 3967 if (mOnBatteryInternal) { 3968 uid = mapUid(uid); 3969 getUidStatsLocked(uid).noteUserActivityLocked(event); 3970 } 3971 } 3972 3973 public void noteWakeUpLocked(String reason, int reasonUid) { 3974 final long elapsedRealtime = mClocks.elapsedRealtime(); 3975 final long uptime = mClocks.uptimeMillis(); 3976 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_SCREEN_WAKE_UP, 3977 reason, reasonUid); 3978 } 3979 3980 public void noteInteractiveLocked(boolean interactive) { 3981 if (mInteractive != interactive) { 3982 final long elapsedRealtime = mClocks.elapsedRealtime(); 3983 mInteractive = interactive; 3984 if (DEBUG) Slog.v(TAG, "Interactive: " + interactive); 3985 if (interactive) { 3986 mInteractiveTimer.startRunningLocked(elapsedRealtime); 3987 } else { 3988 mInteractiveTimer.stopRunningLocked(elapsedRealtime); 3989 } 3990 } 3991 } 3992 3993 public void noteConnectivityChangedLocked(int type, String extra) { 3994 final long elapsedRealtime = mClocks.elapsedRealtime(); 3995 final long uptime = mClocks.uptimeMillis(); 3996 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_CONNECTIVITY_CHANGED, 3997 extra, type); 3998 mNumConnectivityChange++; 3999 } 4000 4001 private void noteMobileRadioApWakeupLocked(final long elapsedRealtimeMillis, 4002 final long uptimeMillis, int uid) { 4003 uid = mapUid(uid); 4004 addHistoryEventLocked(elapsedRealtimeMillis, uptimeMillis, HistoryItem.EVENT_WAKEUP_AP, "", 4005 uid); 4006 getUidStatsLocked(uid).noteMobileRadioApWakeupLocked(); 4007 } 4008 4009 public void noteMobileRadioPowerState(int powerState, long timestampNs, int uid) { 4010 final long elapsedRealtime = mClocks.elapsedRealtime(); 4011 final long uptime = mClocks.uptimeMillis(); 4012 if (mMobileRadioPowerState != powerState) { 4013 long realElapsedRealtimeMs; 4014 final boolean active = 4015 powerState == DataConnectionRealTimeInfo.DC_POWER_STATE_MEDIUM 4016 || powerState == DataConnectionRealTimeInfo.DC_POWER_STATE_HIGH; 4017 if (active) { 4018 if (uid > 0) { 4019 noteMobileRadioApWakeupLocked(elapsedRealtime, uptime, uid); 4020 } 4021 4022 mMobileRadioActiveStartTime = realElapsedRealtimeMs = timestampNs / (1000 * 1000); 4023 mHistoryCur.states |= HistoryItem.STATE_MOBILE_RADIO_ACTIVE_FLAG; 4024 } else { 4025 realElapsedRealtimeMs = timestampNs / (1000*1000); 4026 long lastUpdateTimeMs = mMobileRadioActiveStartTime; 4027 if (realElapsedRealtimeMs < lastUpdateTimeMs) { 4028 Slog.wtf(TAG, "Data connection inactive timestamp " + realElapsedRealtimeMs 4029 + " is before start time " + lastUpdateTimeMs); 4030 realElapsedRealtimeMs = elapsedRealtime; 4031 } else if (realElapsedRealtimeMs < elapsedRealtime) { 4032 mMobileRadioActiveAdjustedTime.addCountLocked(elapsedRealtime 4033 - realElapsedRealtimeMs); 4034 } 4035 mHistoryCur.states &= ~HistoryItem.STATE_MOBILE_RADIO_ACTIVE_FLAG; 4036 } 4037 if (DEBUG_HISTORY) Slog.v(TAG, "Mobile network active " + active + " to: " 4038 + Integer.toHexString(mHistoryCur.states)); 4039 addHistoryRecordLocked(elapsedRealtime, uptime); 4040 mMobileRadioPowerState = powerState; 4041 if (active) { 4042 mMobileRadioActiveTimer.startRunningLocked(elapsedRealtime); 4043 mMobileRadioActivePerAppTimer.startRunningLocked(elapsedRealtime); 4044 } else { 4045 mMobileRadioActiveTimer.stopRunningLocked(realElapsedRealtimeMs); 4046 updateMobileRadioStateLocked(realElapsedRealtimeMs, null); 4047 mMobileRadioActivePerAppTimer.stopRunningLocked(realElapsedRealtimeMs); 4048 } 4049 } 4050 } 4051 4052 public void notePowerSaveMode(boolean enabled) { 4053 if (mPowerSaveModeEnabled != enabled) { 4054 int stepState = enabled ? STEP_LEVEL_MODE_POWER_SAVE : 0; 4055 mModStepMode |= (mCurStepMode&STEP_LEVEL_MODE_POWER_SAVE) ^ stepState; 4056 mCurStepMode = (mCurStepMode&~STEP_LEVEL_MODE_POWER_SAVE) | stepState; 4057 final long elapsedRealtime = mClocks.elapsedRealtime(); 4058 final long uptime = mClocks.uptimeMillis(); 4059 mPowerSaveModeEnabled = enabled; 4060 if (enabled) { 4061 mHistoryCur.states2 |= HistoryItem.STATE2_POWER_SAVE_FLAG; 4062 if (DEBUG_HISTORY) Slog.v(TAG, "Power save mode enabled to: " 4063 + Integer.toHexString(mHistoryCur.states2)); 4064 mPowerSaveModeEnabledTimer.startRunningLocked(elapsedRealtime); 4065 } else { 4066 mHistoryCur.states2 &= ~HistoryItem.STATE2_POWER_SAVE_FLAG; 4067 if (DEBUG_HISTORY) Slog.v(TAG, "Power save mode disabled to: " 4068 + Integer.toHexString(mHistoryCur.states2)); 4069 mPowerSaveModeEnabledTimer.stopRunningLocked(elapsedRealtime); 4070 } 4071 addHistoryRecordLocked(elapsedRealtime, uptime); 4072 } 4073 } 4074 4075 public void noteDeviceIdleModeLocked(int mode, String activeReason, int activeUid) { 4076 final long elapsedRealtime = mClocks.elapsedRealtime(); 4077 final long uptime = mClocks.uptimeMillis(); 4078 boolean nowIdling = mode == DEVICE_IDLE_MODE_DEEP; 4079 if (mDeviceIdling && !nowIdling && activeReason == null) { 4080 // We don't go out of general idling mode until explicitly taken out of 4081 // device idle through going active or significant motion. 4082 nowIdling = true; 4083 } 4084 boolean nowLightIdling = mode == DEVICE_IDLE_MODE_LIGHT; 4085 if (mDeviceLightIdling && !nowLightIdling && !nowIdling && activeReason == null) { 4086 // We don't go out of general light idling mode until explicitly taken out of 4087 // device idle through going active or significant motion. 4088 nowLightIdling = true; 4089 } 4090 if (activeReason != null && (mDeviceIdling || mDeviceLightIdling)) { 4091 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_ACTIVE, 4092 activeReason, activeUid); 4093 } 4094 if (mDeviceIdling != nowIdling) { 4095 mDeviceIdling = nowIdling; 4096 int stepState = nowIdling ? STEP_LEVEL_MODE_DEVICE_IDLE : 0; 4097 mModStepMode |= (mCurStepMode&STEP_LEVEL_MODE_DEVICE_IDLE) ^ stepState; 4098 mCurStepMode = (mCurStepMode&~STEP_LEVEL_MODE_DEVICE_IDLE) | stepState; 4099 if (nowIdling) { 4100 mDeviceIdlingTimer.startRunningLocked(elapsedRealtime); 4101 } else { 4102 mDeviceIdlingTimer.stopRunningLocked(elapsedRealtime); 4103 } 4104 } 4105 if (mDeviceLightIdling != nowLightIdling) { 4106 mDeviceLightIdling = nowLightIdling; 4107 if (nowLightIdling) { 4108 mDeviceLightIdlingTimer.startRunningLocked(elapsedRealtime); 4109 } else { 4110 mDeviceLightIdlingTimer.stopRunningLocked(elapsedRealtime); 4111 } 4112 } 4113 if (mDeviceIdleMode != mode) { 4114 mHistoryCur.states2 = (mHistoryCur.states2 & ~HistoryItem.STATE2_DEVICE_IDLE_MASK) 4115 | (mode << HistoryItem.STATE2_DEVICE_IDLE_SHIFT); 4116 if (DEBUG_HISTORY) Slog.v(TAG, "Device idle mode changed to: " 4117 + Integer.toHexString(mHistoryCur.states2)); 4118 addHistoryRecordLocked(elapsedRealtime, uptime); 4119 long lastDuration = elapsedRealtime - mLastIdleTimeStart; 4120 mLastIdleTimeStart = elapsedRealtime; 4121 if (mDeviceIdleMode == DEVICE_IDLE_MODE_LIGHT) { 4122 if (lastDuration > mLongestLightIdleTime) { 4123 mLongestLightIdleTime = lastDuration; 4124 } 4125 mDeviceIdleModeLightTimer.stopRunningLocked(elapsedRealtime); 4126 } else if (mDeviceIdleMode == DEVICE_IDLE_MODE_DEEP) { 4127 if (lastDuration > mLongestFullIdleTime) { 4128 mLongestFullIdleTime = lastDuration; 4129 } 4130 mDeviceIdleModeFullTimer.stopRunningLocked(elapsedRealtime); 4131 } 4132 if (mode == DEVICE_IDLE_MODE_LIGHT) { 4133 mDeviceIdleModeLightTimer.startRunningLocked(elapsedRealtime); 4134 } else if (mode == DEVICE_IDLE_MODE_DEEP) { 4135 mDeviceIdleModeFullTimer.startRunningLocked(elapsedRealtime); 4136 } 4137 mDeviceIdleMode = mode; 4138 } 4139 } 4140 4141 public void notePackageInstalledLocked(String pkgName, int versionCode) { 4142 final long elapsedRealtime = mClocks.elapsedRealtime(); 4143 final long uptime = mClocks.uptimeMillis(); 4144 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_PACKAGE_INSTALLED, 4145 pkgName, versionCode); 4146 PackageChange pc = new PackageChange(); 4147 pc.mPackageName = pkgName; 4148 pc.mUpdate = true; 4149 pc.mVersionCode = versionCode; 4150 addPackageChange(pc); 4151 } 4152 4153 public void notePackageUninstalledLocked(String pkgName) { 4154 final long elapsedRealtime = mClocks.elapsedRealtime(); 4155 final long uptime = mClocks.uptimeMillis(); 4156 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_PACKAGE_UNINSTALLED, 4157 pkgName, 0); 4158 PackageChange pc = new PackageChange(); 4159 pc.mPackageName = pkgName; 4160 pc.mUpdate = true; 4161 addPackageChange(pc); 4162 } 4163 4164 private void addPackageChange(PackageChange pc) { 4165 if (mDailyPackageChanges == null) { 4166 mDailyPackageChanges = new ArrayList<>(); 4167 } 4168 mDailyPackageChanges.add(pc); 4169 } 4170 4171 public void notePhoneOnLocked() { 4172 if (!mPhoneOn) { 4173 final long elapsedRealtime = mClocks.elapsedRealtime(); 4174 final long uptime = mClocks.uptimeMillis(); 4175 mHistoryCur.states2 |= HistoryItem.STATE2_PHONE_IN_CALL_FLAG; 4176 if (DEBUG_HISTORY) Slog.v(TAG, "Phone on to: " 4177 + Integer.toHexString(mHistoryCur.states)); 4178 addHistoryRecordLocked(elapsedRealtime, uptime); 4179 mPhoneOn = true; 4180 mPhoneOnTimer.startRunningLocked(elapsedRealtime); 4181 } 4182 } 4183 4184 public void notePhoneOffLocked() { 4185 if (mPhoneOn) { 4186 final long elapsedRealtime = mClocks.elapsedRealtime(); 4187 final long uptime = mClocks.uptimeMillis(); 4188 mHistoryCur.states2 &= ~HistoryItem.STATE2_PHONE_IN_CALL_FLAG; 4189 if (DEBUG_HISTORY) Slog.v(TAG, "Phone off to: " 4190 + Integer.toHexString(mHistoryCur.states)); 4191 addHistoryRecordLocked(elapsedRealtime, uptime); 4192 mPhoneOn = false; 4193 mPhoneOnTimer.stopRunningLocked(elapsedRealtime); 4194 } 4195 } 4196 4197 void stopAllPhoneSignalStrengthTimersLocked(int except) { 4198 final long elapsedRealtime = mClocks.elapsedRealtime(); 4199 for (int i = 0; i < SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) { 4200 if (i == except) { 4201 continue; 4202 } 4203 while (mPhoneSignalStrengthsTimer[i].isRunningLocked()) { 4204 mPhoneSignalStrengthsTimer[i].stopRunningLocked(elapsedRealtime); 4205 } 4206 } 4207 } 4208 4209 private int fixPhoneServiceState(int state, int signalBin) { 4210 if (mPhoneSimStateRaw == TelephonyManager.SIM_STATE_ABSENT) { 4211 // In this case we will always be STATE_OUT_OF_SERVICE, so need 4212 // to infer that we are scanning from other data. 4213 if (state == ServiceState.STATE_OUT_OF_SERVICE 4214 && signalBin > SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN) { 4215 state = ServiceState.STATE_IN_SERVICE; 4216 } 4217 } 4218 4219 return state; 4220 } 4221 4222 private void updateAllPhoneStateLocked(int state, int simState, int strengthBin) { 4223 boolean scanning = false; 4224 boolean newHistory = false; 4225 4226 mPhoneServiceStateRaw = state; 4227 mPhoneSimStateRaw = simState; 4228 mPhoneSignalStrengthBinRaw = strengthBin; 4229 4230 final long elapsedRealtime = mClocks.elapsedRealtime(); 4231 final long uptime = mClocks.uptimeMillis(); 4232 4233 if (simState == TelephonyManager.SIM_STATE_ABSENT) { 4234 // In this case we will always be STATE_OUT_OF_SERVICE, so need 4235 // to infer that we are scanning from other data. 4236 if (state == ServiceState.STATE_OUT_OF_SERVICE 4237 && strengthBin > SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN) { 4238 state = ServiceState.STATE_IN_SERVICE; 4239 } 4240 } 4241 4242 // If the phone is powered off, stop all timers. 4243 if (state == ServiceState.STATE_POWER_OFF) { 4244 strengthBin = -1; 4245 4246 // If we are in service, make sure the correct signal string timer is running. 4247 } else if (state == ServiceState.STATE_IN_SERVICE) { 4248 // Bin will be changed below. 4249 4250 // If we're out of service, we are in the lowest signal strength 4251 // bin and have the scanning bit set. 4252 } else if (state == ServiceState.STATE_OUT_OF_SERVICE) { 4253 scanning = true; 4254 strengthBin = SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN; 4255 if (!mPhoneSignalScanningTimer.isRunningLocked()) { 4256 mHistoryCur.states |= HistoryItem.STATE_PHONE_SCANNING_FLAG; 4257 newHistory = true; 4258 if (DEBUG_HISTORY) Slog.v(TAG, "Phone started scanning to: " 4259 + Integer.toHexString(mHistoryCur.states)); 4260 mPhoneSignalScanningTimer.startRunningLocked(elapsedRealtime); 4261 } 4262 } 4263 4264 if (!scanning) { 4265 // If we are no longer scanning, then stop the scanning timer. 4266 if (mPhoneSignalScanningTimer.isRunningLocked()) { 4267 mHistoryCur.states &= ~HistoryItem.STATE_PHONE_SCANNING_FLAG; 4268 if (DEBUG_HISTORY) Slog.v(TAG, "Phone stopped scanning to: " 4269 + Integer.toHexString(mHistoryCur.states)); 4270 newHistory = true; 4271 mPhoneSignalScanningTimer.stopRunningLocked(elapsedRealtime); 4272 } 4273 } 4274 4275 if (mPhoneServiceState != state) { 4276 mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_PHONE_STATE_MASK) 4277 | (state << HistoryItem.STATE_PHONE_STATE_SHIFT); 4278 if (DEBUG_HISTORY) Slog.v(TAG, "Phone state " + state + " to: " 4279 + Integer.toHexString(mHistoryCur.states)); 4280 newHistory = true; 4281 mPhoneServiceState = state; 4282 } 4283 4284 if (mPhoneSignalStrengthBin != strengthBin) { 4285 if (mPhoneSignalStrengthBin >= 0) { 4286 mPhoneSignalStrengthsTimer[mPhoneSignalStrengthBin].stopRunningLocked( 4287 elapsedRealtime); 4288 } 4289 if (strengthBin >= 0) { 4290 if (!mPhoneSignalStrengthsTimer[strengthBin].isRunningLocked()) { 4291 mPhoneSignalStrengthsTimer[strengthBin].startRunningLocked(elapsedRealtime); 4292 } 4293 mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_PHONE_SIGNAL_STRENGTH_MASK) 4294 | (strengthBin << HistoryItem.STATE_PHONE_SIGNAL_STRENGTH_SHIFT); 4295 if (DEBUG_HISTORY) Slog.v(TAG, "Signal strength " + strengthBin + " to: " 4296 + Integer.toHexString(mHistoryCur.states)); 4297 newHistory = true; 4298 } else { 4299 stopAllPhoneSignalStrengthTimersLocked(-1); 4300 } 4301 mPhoneSignalStrengthBin = strengthBin; 4302 } 4303 4304 if (newHistory) { 4305 addHistoryRecordLocked(elapsedRealtime, uptime); 4306 } 4307 } 4308 4309 /** 4310 * Telephony stack updates the phone state. 4311 * @param state phone state from ServiceState.getState() 4312 */ 4313 public void notePhoneStateLocked(int state, int simState) { 4314 updateAllPhoneStateLocked(state, simState, mPhoneSignalStrengthBinRaw); 4315 } 4316 4317 public void notePhoneSignalStrengthLocked(SignalStrength signalStrength) { 4318 // Bin the strength. 4319 int bin = signalStrength.getLevel(); 4320 updateAllPhoneStateLocked(mPhoneServiceStateRaw, mPhoneSimStateRaw, bin); 4321 } 4322 4323 public void notePhoneDataConnectionStateLocked(int dataType, boolean hasData) { 4324 int bin = DATA_CONNECTION_NONE; 4325 if (hasData) { 4326 switch (dataType) { 4327 case TelephonyManager.NETWORK_TYPE_EDGE: 4328 bin = DATA_CONNECTION_EDGE; 4329 break; 4330 case TelephonyManager.NETWORK_TYPE_GPRS: 4331 bin = DATA_CONNECTION_GPRS; 4332 break; 4333 case TelephonyManager.NETWORK_TYPE_UMTS: 4334 bin = DATA_CONNECTION_UMTS; 4335 break; 4336 case TelephonyManager.NETWORK_TYPE_CDMA: 4337 bin = DATA_CONNECTION_CDMA; 4338 break; 4339 case TelephonyManager.NETWORK_TYPE_EVDO_0: 4340 bin = DATA_CONNECTION_EVDO_0; 4341 break; 4342 case TelephonyManager.NETWORK_TYPE_EVDO_A: 4343 bin = DATA_CONNECTION_EVDO_A; 4344 break; 4345 case TelephonyManager.NETWORK_TYPE_1xRTT: 4346 bin = DATA_CONNECTION_1xRTT; 4347 break; 4348 case TelephonyManager.NETWORK_TYPE_HSDPA: 4349 bin = DATA_CONNECTION_HSDPA; 4350 break; 4351 case TelephonyManager.NETWORK_TYPE_HSUPA: 4352 bin = DATA_CONNECTION_HSUPA; 4353 break; 4354 case TelephonyManager.NETWORK_TYPE_HSPA: 4355 bin = DATA_CONNECTION_HSPA; 4356 break; 4357 case TelephonyManager.NETWORK_TYPE_IDEN: 4358 bin = DATA_CONNECTION_IDEN; 4359 break; 4360 case TelephonyManager.NETWORK_TYPE_EVDO_B: 4361 bin = DATA_CONNECTION_EVDO_B; 4362 break; 4363 case TelephonyManager.NETWORK_TYPE_LTE: 4364 bin = DATA_CONNECTION_LTE; 4365 break; 4366 case TelephonyManager.NETWORK_TYPE_EHRPD: 4367 bin = DATA_CONNECTION_EHRPD; 4368 break; 4369 case TelephonyManager.NETWORK_TYPE_HSPAP: 4370 bin = DATA_CONNECTION_HSPAP; 4371 break; 4372 default: 4373 bin = DATA_CONNECTION_OTHER; 4374 break; 4375 } 4376 } 4377 if (DEBUG) Log.i(TAG, "Phone Data Connection -> " + dataType + " = " + hasData); 4378 if (mPhoneDataConnectionType != bin) { 4379 final long elapsedRealtime = mClocks.elapsedRealtime(); 4380 final long uptime = mClocks.uptimeMillis(); 4381 mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_DATA_CONNECTION_MASK) 4382 | (bin << HistoryItem.STATE_DATA_CONNECTION_SHIFT); 4383 if (DEBUG_HISTORY) Slog.v(TAG, "Data connection " + bin + " to: " 4384 + Integer.toHexString(mHistoryCur.states)); 4385 addHistoryRecordLocked(elapsedRealtime, uptime); 4386 if (mPhoneDataConnectionType >= 0) { 4387 mPhoneDataConnectionsTimer[mPhoneDataConnectionType].stopRunningLocked( 4388 elapsedRealtime); 4389 } 4390 mPhoneDataConnectionType = bin; 4391 mPhoneDataConnectionsTimer[bin].startRunningLocked(elapsedRealtime); 4392 } 4393 } 4394 4395 public void noteWifiOnLocked() { 4396 if (!mWifiOn) { 4397 final long elapsedRealtime = mClocks.elapsedRealtime(); 4398 final long uptime = mClocks.uptimeMillis(); 4399 mHistoryCur.states2 |= HistoryItem.STATE2_WIFI_ON_FLAG; 4400 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI on to: " 4401 + Integer.toHexString(mHistoryCur.states)); 4402 addHistoryRecordLocked(elapsedRealtime, uptime); 4403 mWifiOn = true; 4404 mWifiOnTimer.startRunningLocked(elapsedRealtime); 4405 scheduleSyncExternalStatsLocked("wifi-off", ExternalStatsSync.UPDATE_WIFI); 4406 } 4407 } 4408 4409 public void noteWifiOffLocked() { 4410 final long elapsedRealtime = mClocks.elapsedRealtime(); 4411 final long uptime = mClocks.uptimeMillis(); 4412 if (mWifiOn) { 4413 mHistoryCur.states2 &= ~HistoryItem.STATE2_WIFI_ON_FLAG; 4414 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI off to: " 4415 + Integer.toHexString(mHistoryCur.states)); 4416 addHistoryRecordLocked(elapsedRealtime, uptime); 4417 mWifiOn = false; 4418 mWifiOnTimer.stopRunningLocked(elapsedRealtime); 4419 scheduleSyncExternalStatsLocked("wifi-on", ExternalStatsSync.UPDATE_WIFI); 4420 } 4421 } 4422 4423 public void noteAudioOnLocked(int uid) { 4424 uid = mapUid(uid); 4425 final long elapsedRealtime = mClocks.elapsedRealtime(); 4426 final long uptime = mClocks.uptimeMillis(); 4427 if (mAudioOnNesting == 0) { 4428 mHistoryCur.states |= HistoryItem.STATE_AUDIO_ON_FLAG; 4429 if (DEBUG_HISTORY) Slog.v(TAG, "Audio on to: " 4430 + Integer.toHexString(mHistoryCur.states)); 4431 addHistoryRecordLocked(elapsedRealtime, uptime); 4432 mAudioOnTimer.startRunningLocked(elapsedRealtime); 4433 } 4434 mAudioOnNesting++; 4435 getUidStatsLocked(uid).noteAudioTurnedOnLocked(elapsedRealtime); 4436 } 4437 4438 public void noteAudioOffLocked(int uid) { 4439 if (mAudioOnNesting == 0) { 4440 return; 4441 } 4442 uid = mapUid(uid); 4443 final long elapsedRealtime = mClocks.elapsedRealtime(); 4444 final long uptime = mClocks.uptimeMillis(); 4445 if (--mAudioOnNesting == 0) { 4446 mHistoryCur.states &= ~HistoryItem.STATE_AUDIO_ON_FLAG; 4447 if (DEBUG_HISTORY) Slog.v(TAG, "Audio off to: " 4448 + Integer.toHexString(mHistoryCur.states)); 4449 addHistoryRecordLocked(elapsedRealtime, uptime); 4450 mAudioOnTimer.stopRunningLocked(elapsedRealtime); 4451 } 4452 getUidStatsLocked(uid).noteAudioTurnedOffLocked(elapsedRealtime); 4453 } 4454 4455 public void noteVideoOnLocked(int uid) { 4456 uid = mapUid(uid); 4457 final long elapsedRealtime = mClocks.elapsedRealtime(); 4458 final long uptime = mClocks.uptimeMillis(); 4459 if (mVideoOnNesting == 0) { 4460 mHistoryCur.states2 |= HistoryItem.STATE2_VIDEO_ON_FLAG; 4461 if (DEBUG_HISTORY) Slog.v(TAG, "Video on to: " 4462 + Integer.toHexString(mHistoryCur.states)); 4463 addHistoryRecordLocked(elapsedRealtime, uptime); 4464 mVideoOnTimer.startRunningLocked(elapsedRealtime); 4465 } 4466 mVideoOnNesting++; 4467 getUidStatsLocked(uid).noteVideoTurnedOnLocked(elapsedRealtime); 4468 } 4469 4470 public void noteVideoOffLocked(int uid) { 4471 if (mVideoOnNesting == 0) { 4472 return; 4473 } 4474 uid = mapUid(uid); 4475 final long elapsedRealtime = mClocks.elapsedRealtime(); 4476 final long uptime = mClocks.uptimeMillis(); 4477 if (--mVideoOnNesting == 0) { 4478 mHistoryCur.states2 &= ~HistoryItem.STATE2_VIDEO_ON_FLAG; 4479 if (DEBUG_HISTORY) Slog.v(TAG, "Video off to: " 4480 + Integer.toHexString(mHistoryCur.states)); 4481 addHistoryRecordLocked(elapsedRealtime, uptime); 4482 mVideoOnTimer.stopRunningLocked(elapsedRealtime); 4483 } 4484 getUidStatsLocked(uid).noteVideoTurnedOffLocked(elapsedRealtime); 4485 } 4486 4487 public void noteResetAudioLocked() { 4488 if (mAudioOnNesting > 0) { 4489 final long elapsedRealtime = mClocks.elapsedRealtime(); 4490 final long uptime = mClocks.uptimeMillis(); 4491 mAudioOnNesting = 0; 4492 mHistoryCur.states &= ~HistoryItem.STATE_AUDIO_ON_FLAG; 4493 if (DEBUG_HISTORY) Slog.v(TAG, "Audio off to: " 4494 + Integer.toHexString(mHistoryCur.states)); 4495 addHistoryRecordLocked(elapsedRealtime, uptime); 4496 mAudioOnTimer.stopAllRunningLocked(elapsedRealtime); 4497 for (int i=0; i<mUidStats.size(); i++) { 4498 BatteryStatsImpl.Uid uid = mUidStats.valueAt(i); 4499 uid.noteResetAudioLocked(elapsedRealtime); 4500 } 4501 } 4502 } 4503 4504 public void noteResetVideoLocked() { 4505 if (mVideoOnNesting > 0) { 4506 final long elapsedRealtime = mClocks.elapsedRealtime(); 4507 final long uptime = mClocks.uptimeMillis(); 4508 mAudioOnNesting = 0; 4509 mHistoryCur.states2 &= ~HistoryItem.STATE2_VIDEO_ON_FLAG; 4510 if (DEBUG_HISTORY) Slog.v(TAG, "Video off to: " 4511 + Integer.toHexString(mHistoryCur.states)); 4512 addHistoryRecordLocked(elapsedRealtime, uptime); 4513 mVideoOnTimer.stopAllRunningLocked(elapsedRealtime); 4514 for (int i=0; i<mUidStats.size(); i++) { 4515 BatteryStatsImpl.Uid uid = mUidStats.valueAt(i); 4516 uid.noteResetVideoLocked(elapsedRealtime); 4517 } 4518 } 4519 } 4520 4521 public void noteActivityResumedLocked(int uid) { 4522 uid = mapUid(uid); 4523 getUidStatsLocked(uid).noteActivityResumedLocked(mClocks.elapsedRealtime()); 4524 } 4525 4526 public void noteActivityPausedLocked(int uid) { 4527 uid = mapUid(uid); 4528 getUidStatsLocked(uid).noteActivityPausedLocked(mClocks.elapsedRealtime()); 4529 } 4530 4531 public void noteVibratorOnLocked(int uid, long durationMillis) { 4532 uid = mapUid(uid); 4533 getUidStatsLocked(uid).noteVibratorOnLocked(durationMillis); 4534 } 4535 4536 public void noteVibratorOffLocked(int uid) { 4537 uid = mapUid(uid); 4538 getUidStatsLocked(uid).noteVibratorOffLocked(); 4539 } 4540 4541 public void noteFlashlightOnLocked(int uid) { 4542 uid = mapUid(uid); 4543 final long elapsedRealtime = mClocks.elapsedRealtime(); 4544 final long uptime = mClocks.uptimeMillis(); 4545 if (mFlashlightOnNesting++ == 0) { 4546 mHistoryCur.states2 |= HistoryItem.STATE2_FLASHLIGHT_FLAG; 4547 if (DEBUG_HISTORY) Slog.v(TAG, "Flashlight on to: " 4548 + Integer.toHexString(mHistoryCur.states2)); 4549 addHistoryRecordLocked(elapsedRealtime, uptime); 4550 mFlashlightOnTimer.startRunningLocked(elapsedRealtime); 4551 } 4552 getUidStatsLocked(uid).noteFlashlightTurnedOnLocked(elapsedRealtime); 4553 } 4554 4555 public void noteFlashlightOffLocked(int uid) { 4556 if (mFlashlightOnNesting == 0) { 4557 return; 4558 } 4559 uid = mapUid(uid); 4560 final long elapsedRealtime = mClocks.elapsedRealtime(); 4561 final long uptime = mClocks.uptimeMillis(); 4562 if (--mFlashlightOnNesting == 0) { 4563 mHistoryCur.states2 &= ~HistoryItem.STATE2_FLASHLIGHT_FLAG; 4564 if (DEBUG_HISTORY) Slog.v(TAG, "Flashlight off to: " 4565 + Integer.toHexString(mHistoryCur.states2)); 4566 addHistoryRecordLocked(elapsedRealtime, uptime); 4567 mFlashlightOnTimer.stopRunningLocked(elapsedRealtime); 4568 } 4569 getUidStatsLocked(uid).noteFlashlightTurnedOffLocked(elapsedRealtime); 4570 } 4571 4572 public void noteCameraOnLocked(int uid) { 4573 uid = mapUid(uid); 4574 final long elapsedRealtime = mClocks.elapsedRealtime(); 4575 final long uptime = mClocks.uptimeMillis(); 4576 if (mCameraOnNesting++ == 0) { 4577 mHistoryCur.states2 |= HistoryItem.STATE2_CAMERA_FLAG; 4578 if (DEBUG_HISTORY) Slog.v(TAG, "Camera on to: " 4579 + Integer.toHexString(mHistoryCur.states2)); 4580 addHistoryRecordLocked(elapsedRealtime, uptime); 4581 mCameraOnTimer.startRunningLocked(elapsedRealtime); 4582 } 4583 getUidStatsLocked(uid).noteCameraTurnedOnLocked(elapsedRealtime); 4584 } 4585 4586 public void noteCameraOffLocked(int uid) { 4587 if (mCameraOnNesting == 0) { 4588 return; 4589 } 4590 uid = mapUid(uid); 4591 final long elapsedRealtime = mClocks.elapsedRealtime(); 4592 final long uptime = mClocks.uptimeMillis(); 4593 if (--mCameraOnNesting == 0) { 4594 mHistoryCur.states2 &= ~HistoryItem.STATE2_CAMERA_FLAG; 4595 if (DEBUG_HISTORY) Slog.v(TAG, "Camera off to: " 4596 + Integer.toHexString(mHistoryCur.states2)); 4597 addHistoryRecordLocked(elapsedRealtime, uptime); 4598 mCameraOnTimer.stopRunningLocked(elapsedRealtime); 4599 } 4600 getUidStatsLocked(uid).noteCameraTurnedOffLocked(elapsedRealtime); 4601 } 4602 4603 public void noteResetCameraLocked() { 4604 if (mCameraOnNesting > 0) { 4605 final long elapsedRealtime = mClocks.elapsedRealtime(); 4606 final long uptime = mClocks.uptimeMillis(); 4607 mCameraOnNesting = 0; 4608 mHistoryCur.states2 &= ~HistoryItem.STATE2_CAMERA_FLAG; 4609 if (DEBUG_HISTORY) Slog.v(TAG, "Camera off to: " 4610 + Integer.toHexString(mHistoryCur.states2)); 4611 addHistoryRecordLocked(elapsedRealtime, uptime); 4612 mCameraOnTimer.stopAllRunningLocked(elapsedRealtime); 4613 for (int i=0; i<mUidStats.size(); i++) { 4614 BatteryStatsImpl.Uid uid = mUidStats.valueAt(i); 4615 uid.noteResetCameraLocked(elapsedRealtime); 4616 } 4617 } 4618 } 4619 4620 public void noteResetFlashlightLocked() { 4621 if (mFlashlightOnNesting > 0) { 4622 final long elapsedRealtime = mClocks.elapsedRealtime(); 4623 final long uptime = mClocks.uptimeMillis(); 4624 mFlashlightOnNesting = 0; 4625 mHistoryCur.states2 &= ~HistoryItem.STATE2_FLASHLIGHT_FLAG; 4626 if (DEBUG_HISTORY) Slog.v(TAG, "Flashlight off to: " 4627 + Integer.toHexString(mHistoryCur.states2)); 4628 addHistoryRecordLocked(elapsedRealtime, uptime); 4629 mFlashlightOnTimer.stopAllRunningLocked(elapsedRealtime); 4630 for (int i=0; i<mUidStats.size(); i++) { 4631 BatteryStatsImpl.Uid uid = mUidStats.valueAt(i); 4632 uid.noteResetFlashlightLocked(elapsedRealtime); 4633 } 4634 } 4635 } 4636 4637 private void noteBluetoothScanStartedLocked(int uid) { 4638 uid = mapUid(uid); 4639 final long elapsedRealtime = mClocks.elapsedRealtime(); 4640 final long uptime = mClocks.uptimeMillis(); 4641 if (mBluetoothScanNesting == 0) { 4642 mHistoryCur.states2 |= HistoryItem.STATE2_BLUETOOTH_SCAN_FLAG; 4643 if (DEBUG_HISTORY) Slog.v(TAG, "BLE scan started for: " 4644 + Integer.toHexString(mHistoryCur.states2)); 4645 addHistoryRecordLocked(elapsedRealtime, uptime); 4646 mBluetoothScanTimer.startRunningLocked(elapsedRealtime); 4647 } 4648 mBluetoothScanNesting++; 4649 getUidStatsLocked(uid).noteBluetoothScanStartedLocked(elapsedRealtime); 4650 } 4651 4652 public void noteBluetoothScanStartedFromSourceLocked(WorkSource ws) { 4653 final int N = ws.size(); 4654 for (int i = 0; i < N; i++) { 4655 noteBluetoothScanStartedLocked(ws.get(i)); 4656 } 4657 } 4658 4659 private void noteBluetoothScanStoppedLocked(int uid) { 4660 uid = mapUid(uid); 4661 final long elapsedRealtime = mClocks.elapsedRealtime(); 4662 final long uptime = mClocks.uptimeMillis(); 4663 mBluetoothScanNesting--; 4664 if (mBluetoothScanNesting == 0) { 4665 mHistoryCur.states2 &= ~HistoryItem.STATE2_BLUETOOTH_SCAN_FLAG; 4666 if (DEBUG_HISTORY) Slog.v(TAG, "BLE scan stopped for: " 4667 + Integer.toHexString(mHistoryCur.states2)); 4668 addHistoryRecordLocked(elapsedRealtime, uptime); 4669 mBluetoothScanTimer.stopRunningLocked(elapsedRealtime); 4670 } 4671 getUidStatsLocked(uid).noteBluetoothScanStoppedLocked(elapsedRealtime); 4672 } 4673 4674 public void noteBluetoothScanStoppedFromSourceLocked(WorkSource ws) { 4675 final int N = ws.size(); 4676 for (int i = 0; i < N; i++) { 4677 noteBluetoothScanStoppedLocked(ws.get(i)); 4678 } 4679 } 4680 4681 public void noteResetBluetoothScanLocked() { 4682 if (mBluetoothScanNesting > 0) { 4683 final long elapsedRealtime = mClocks.elapsedRealtime(); 4684 final long uptime = mClocks.uptimeMillis(); 4685 mBluetoothScanNesting = 0; 4686 mHistoryCur.states2 &= ~HistoryItem.STATE2_BLUETOOTH_SCAN_FLAG; 4687 if (DEBUG_HISTORY) Slog.v(TAG, "BLE can stopped for: " 4688 + Integer.toHexString(mHistoryCur.states2)); 4689 addHistoryRecordLocked(elapsedRealtime, uptime); 4690 mBluetoothScanTimer.stopAllRunningLocked(elapsedRealtime); 4691 for (int i=0; i<mUidStats.size(); i++) { 4692 BatteryStatsImpl.Uid uid = mUidStats.valueAt(i); 4693 uid.noteResetBluetoothScanLocked(elapsedRealtime); 4694 } 4695 } 4696 } 4697 4698 private void noteWifiRadioApWakeupLocked(final long elapsedRealtimeMillis, 4699 final long uptimeMillis, int uid) { 4700 uid = mapUid(uid); 4701 addHistoryEventLocked(elapsedRealtimeMillis, uptimeMillis, HistoryItem.EVENT_WAKEUP_AP, "", 4702 uid); 4703 getUidStatsLocked(uid).noteWifiRadioApWakeupLocked(); 4704 } 4705 4706 public void noteWifiRadioPowerState(int powerState, long timestampNs, int uid) { 4707 final long elapsedRealtime = mClocks.elapsedRealtime(); 4708 final long uptime = mClocks.uptimeMillis(); 4709 if (mWifiRadioPowerState != powerState) { 4710 final boolean active = 4711 powerState == DataConnectionRealTimeInfo.DC_POWER_STATE_MEDIUM 4712 || powerState == DataConnectionRealTimeInfo.DC_POWER_STATE_HIGH; 4713 if (active) { 4714 if (uid > 0) { 4715 noteWifiRadioApWakeupLocked(elapsedRealtime, uptime, uid); 4716 } 4717 mHistoryCur.states |= HistoryItem.STATE_WIFI_RADIO_ACTIVE_FLAG; 4718 } else { 4719 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_RADIO_ACTIVE_FLAG; 4720 } 4721 if (DEBUG_HISTORY) Slog.v(TAG, "Wifi network active " + active + " to: " 4722 + Integer.toHexString(mHistoryCur.states)); 4723 addHistoryRecordLocked(elapsedRealtime, uptime); 4724 mWifiRadioPowerState = powerState; 4725 } 4726 } 4727 4728 public void noteWifiRunningLocked(WorkSource ws) { 4729 if (!mGlobalWifiRunning) { 4730 final long elapsedRealtime = mClocks.elapsedRealtime(); 4731 final long uptime = mClocks.uptimeMillis(); 4732 mHistoryCur.states2 |= HistoryItem.STATE2_WIFI_RUNNING_FLAG; 4733 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI running to: " 4734 + Integer.toHexString(mHistoryCur.states)); 4735 addHistoryRecordLocked(elapsedRealtime, uptime); 4736 mGlobalWifiRunning = true; 4737 mGlobalWifiRunningTimer.startRunningLocked(elapsedRealtime); 4738 int N = ws.size(); 4739 for (int i=0; i<N; i++) { 4740 int uid = mapUid(ws.get(i)); 4741 getUidStatsLocked(uid).noteWifiRunningLocked(elapsedRealtime); 4742 } 4743 scheduleSyncExternalStatsLocked("wifi-running", ExternalStatsSync.UPDATE_WIFI); 4744 } else { 4745 Log.w(TAG, "noteWifiRunningLocked -- called while WIFI running"); 4746 } 4747 } 4748 4749 public void noteWifiRunningChangedLocked(WorkSource oldWs, WorkSource newWs) { 4750 if (mGlobalWifiRunning) { 4751 final long elapsedRealtime = mClocks.elapsedRealtime(); 4752 int N = oldWs.size(); 4753 for (int i=0; i<N; i++) { 4754 int uid = mapUid(oldWs.get(i)); 4755 getUidStatsLocked(uid).noteWifiStoppedLocked(elapsedRealtime); 4756 } 4757 N = newWs.size(); 4758 for (int i=0; i<N; i++) { 4759 int uid = mapUid(newWs.get(i)); 4760 getUidStatsLocked(uid).noteWifiRunningLocked(elapsedRealtime); 4761 } 4762 } else { 4763 Log.w(TAG, "noteWifiRunningChangedLocked -- called while WIFI not running"); 4764 } 4765 } 4766 4767 public void noteWifiStoppedLocked(WorkSource ws) { 4768 if (mGlobalWifiRunning) { 4769 final long elapsedRealtime = mClocks.elapsedRealtime(); 4770 final long uptime = mClocks.uptimeMillis(); 4771 mHistoryCur.states2 &= ~HistoryItem.STATE2_WIFI_RUNNING_FLAG; 4772 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI stopped to: " 4773 + Integer.toHexString(mHistoryCur.states)); 4774 addHistoryRecordLocked(elapsedRealtime, uptime); 4775 mGlobalWifiRunning = false; 4776 mGlobalWifiRunningTimer.stopRunningLocked(elapsedRealtime); 4777 int N = ws.size(); 4778 for (int i=0; i<N; i++) { 4779 int uid = mapUid(ws.get(i)); 4780 getUidStatsLocked(uid).noteWifiStoppedLocked(elapsedRealtime); 4781 } 4782 scheduleSyncExternalStatsLocked("wifi-stopped", ExternalStatsSync.UPDATE_WIFI); 4783 } else { 4784 Log.w(TAG, "noteWifiStoppedLocked -- called while WIFI not running"); 4785 } 4786 } 4787 4788 public void noteWifiStateLocked(int wifiState, String accessPoint) { 4789 if (DEBUG) Log.i(TAG, "WiFi state -> " + wifiState); 4790 if (mWifiState != wifiState) { 4791 final long elapsedRealtime = mClocks.elapsedRealtime(); 4792 if (mWifiState >= 0) { 4793 mWifiStateTimer[mWifiState].stopRunningLocked(elapsedRealtime); 4794 } 4795 mWifiState = wifiState; 4796 mWifiStateTimer[wifiState].startRunningLocked(elapsedRealtime); 4797 scheduleSyncExternalStatsLocked("wifi-state", ExternalStatsSync.UPDATE_WIFI); 4798 } 4799 } 4800 4801 public void noteWifiSupplicantStateChangedLocked(int supplState, boolean failedAuth) { 4802 if (DEBUG) Log.i(TAG, "WiFi suppl state -> " + supplState); 4803 if (mWifiSupplState != supplState) { 4804 final long elapsedRealtime = mClocks.elapsedRealtime(); 4805 final long uptime = mClocks.uptimeMillis(); 4806 if (mWifiSupplState >= 0) { 4807 mWifiSupplStateTimer[mWifiSupplState].stopRunningLocked(elapsedRealtime); 4808 } 4809 mWifiSupplState = supplState; 4810 mWifiSupplStateTimer[supplState].startRunningLocked(elapsedRealtime); 4811 mHistoryCur.states2 = 4812 (mHistoryCur.states2&~HistoryItem.STATE2_WIFI_SUPPL_STATE_MASK) 4813 | (supplState << HistoryItem.STATE2_WIFI_SUPPL_STATE_SHIFT); 4814 if (DEBUG_HISTORY) Slog.v(TAG, "Wifi suppl state " + supplState + " to: " 4815 + Integer.toHexString(mHistoryCur.states2)); 4816 addHistoryRecordLocked(elapsedRealtime, uptime); 4817 } 4818 } 4819 4820 void stopAllWifiSignalStrengthTimersLocked(int except) { 4821 final long elapsedRealtime = mClocks.elapsedRealtime(); 4822 for (int i = 0; i < NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { 4823 if (i == except) { 4824 continue; 4825 } 4826 while (mWifiSignalStrengthsTimer[i].isRunningLocked()) { 4827 mWifiSignalStrengthsTimer[i].stopRunningLocked(elapsedRealtime); 4828 } 4829 } 4830 } 4831 4832 public void noteWifiRssiChangedLocked(int newRssi) { 4833 int strengthBin = WifiManager.calculateSignalLevel(newRssi, NUM_WIFI_SIGNAL_STRENGTH_BINS); 4834 if (DEBUG) Log.i(TAG, "WiFi rssi -> " + newRssi + " bin=" + strengthBin); 4835 if (mWifiSignalStrengthBin != strengthBin) { 4836 final long elapsedRealtime = mClocks.elapsedRealtime(); 4837 final long uptime = mClocks.uptimeMillis(); 4838 if (mWifiSignalStrengthBin >= 0) { 4839 mWifiSignalStrengthsTimer[mWifiSignalStrengthBin].stopRunningLocked( 4840 elapsedRealtime); 4841 } 4842 if (strengthBin >= 0) { 4843 if (!mWifiSignalStrengthsTimer[strengthBin].isRunningLocked()) { 4844 mWifiSignalStrengthsTimer[strengthBin].startRunningLocked(elapsedRealtime); 4845 } 4846 mHistoryCur.states2 = 4847 (mHistoryCur.states2&~HistoryItem.STATE2_WIFI_SIGNAL_STRENGTH_MASK) 4848 | (strengthBin << HistoryItem.STATE2_WIFI_SIGNAL_STRENGTH_SHIFT); 4849 if (DEBUG_HISTORY) Slog.v(TAG, "Wifi signal strength " + strengthBin + " to: " 4850 + Integer.toHexString(mHistoryCur.states2)); 4851 addHistoryRecordLocked(elapsedRealtime, uptime); 4852 } else { 4853 stopAllWifiSignalStrengthTimersLocked(-1); 4854 } 4855 mWifiSignalStrengthBin = strengthBin; 4856 } 4857 } 4858 4859 int mWifiFullLockNesting = 0; 4860 4861 public void noteFullWifiLockAcquiredLocked(int uid) { 4862 uid = mapUid(uid); 4863 final long elapsedRealtime = mClocks.elapsedRealtime(); 4864 final long uptime = mClocks.uptimeMillis(); 4865 if (mWifiFullLockNesting == 0) { 4866 mHistoryCur.states |= HistoryItem.STATE_WIFI_FULL_LOCK_FLAG; 4867 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI full lock on to: " 4868 + Integer.toHexString(mHistoryCur.states)); 4869 addHistoryRecordLocked(elapsedRealtime, uptime); 4870 } 4871 mWifiFullLockNesting++; 4872 getUidStatsLocked(uid).noteFullWifiLockAcquiredLocked(elapsedRealtime); 4873 } 4874 4875 public void noteFullWifiLockReleasedLocked(int uid) { 4876 uid = mapUid(uid); 4877 final long elapsedRealtime = mClocks.elapsedRealtime(); 4878 final long uptime = mClocks.uptimeMillis(); 4879 mWifiFullLockNesting--; 4880 if (mWifiFullLockNesting == 0) { 4881 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_FULL_LOCK_FLAG; 4882 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI full lock off to: " 4883 + Integer.toHexString(mHistoryCur.states)); 4884 addHistoryRecordLocked(elapsedRealtime, uptime); 4885 } 4886 getUidStatsLocked(uid).noteFullWifiLockReleasedLocked(elapsedRealtime); 4887 } 4888 4889 int mWifiScanNesting = 0; 4890 4891 public void noteWifiScanStartedLocked(int uid) { 4892 uid = mapUid(uid); 4893 final long elapsedRealtime = mClocks.elapsedRealtime(); 4894 final long uptime = mClocks.uptimeMillis(); 4895 if (mWifiScanNesting == 0) { 4896 mHistoryCur.states |= HistoryItem.STATE_WIFI_SCAN_FLAG; 4897 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI scan started for: " 4898 + Integer.toHexString(mHistoryCur.states)); 4899 addHistoryRecordLocked(elapsedRealtime, uptime); 4900 } 4901 mWifiScanNesting++; 4902 getUidStatsLocked(uid).noteWifiScanStartedLocked(elapsedRealtime); 4903 } 4904 4905 public void noteWifiScanStoppedLocked(int uid) { 4906 uid = mapUid(uid); 4907 final long elapsedRealtime = mClocks.elapsedRealtime(); 4908 final long uptime = mClocks.uptimeMillis(); 4909 mWifiScanNesting--; 4910 if (mWifiScanNesting == 0) { 4911 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_SCAN_FLAG; 4912 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI scan stopped for: " 4913 + Integer.toHexString(mHistoryCur.states)); 4914 addHistoryRecordLocked(elapsedRealtime, uptime); 4915 } 4916 getUidStatsLocked(uid).noteWifiScanStoppedLocked(elapsedRealtime); 4917 } 4918 4919 public void noteWifiBatchedScanStartedLocked(int uid, int csph) { 4920 uid = mapUid(uid); 4921 final long elapsedRealtime = mClocks.elapsedRealtime(); 4922 getUidStatsLocked(uid).noteWifiBatchedScanStartedLocked(csph, elapsedRealtime); 4923 } 4924 4925 public void noteWifiBatchedScanStoppedLocked(int uid) { 4926 uid = mapUid(uid); 4927 final long elapsedRealtime = mClocks.elapsedRealtime(); 4928 getUidStatsLocked(uid).noteWifiBatchedScanStoppedLocked(elapsedRealtime); 4929 } 4930 4931 int mWifiMulticastNesting = 0; 4932 4933 public void noteWifiMulticastEnabledLocked(int uid) { 4934 uid = mapUid(uid); 4935 final long elapsedRealtime = mClocks.elapsedRealtime(); 4936 final long uptime = mClocks.uptimeMillis(); 4937 if (mWifiMulticastNesting == 0) { 4938 mHistoryCur.states |= HistoryItem.STATE_WIFI_MULTICAST_ON_FLAG; 4939 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI multicast on to: " 4940 + Integer.toHexString(mHistoryCur.states)); 4941 addHistoryRecordLocked(elapsedRealtime, uptime); 4942 } 4943 mWifiMulticastNesting++; 4944 getUidStatsLocked(uid).noteWifiMulticastEnabledLocked(elapsedRealtime); 4945 } 4946 4947 public void noteWifiMulticastDisabledLocked(int uid) { 4948 uid = mapUid(uid); 4949 final long elapsedRealtime = mClocks.elapsedRealtime(); 4950 final long uptime = mClocks.uptimeMillis(); 4951 mWifiMulticastNesting--; 4952 if (mWifiMulticastNesting == 0) { 4953 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_MULTICAST_ON_FLAG; 4954 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI multicast off to: " 4955 + Integer.toHexString(mHistoryCur.states)); 4956 addHistoryRecordLocked(elapsedRealtime, uptime); 4957 } 4958 getUidStatsLocked(uid).noteWifiMulticastDisabledLocked(elapsedRealtime); 4959 } 4960 4961 public void noteFullWifiLockAcquiredFromSourceLocked(WorkSource ws) { 4962 int N = ws.size(); 4963 for (int i=0; i<N; i++) { 4964 noteFullWifiLockAcquiredLocked(ws.get(i)); 4965 } 4966 } 4967 4968 public void noteFullWifiLockReleasedFromSourceLocked(WorkSource ws) { 4969 int N = ws.size(); 4970 for (int i=0; i<N; i++) { 4971 noteFullWifiLockReleasedLocked(ws.get(i)); 4972 } 4973 } 4974 4975 public void noteWifiScanStartedFromSourceLocked(WorkSource ws) { 4976 int N = ws.size(); 4977 for (int i=0; i<N; i++) { 4978 noteWifiScanStartedLocked(ws.get(i)); 4979 } 4980 } 4981 4982 public void noteWifiScanStoppedFromSourceLocked(WorkSource ws) { 4983 int N = ws.size(); 4984 for (int i=0; i<N; i++) { 4985 noteWifiScanStoppedLocked(ws.get(i)); 4986 } 4987 } 4988 4989 public void noteWifiBatchedScanStartedFromSourceLocked(WorkSource ws, int csph) { 4990 int N = ws.size(); 4991 for (int i=0; i<N; i++) { 4992 noteWifiBatchedScanStartedLocked(ws.get(i), csph); 4993 } 4994 } 4995 4996 public void noteWifiBatchedScanStoppedFromSourceLocked(WorkSource ws) { 4997 int N = ws.size(); 4998 for (int i=0; i<N; i++) { 4999 noteWifiBatchedScanStoppedLocked(ws.get(i)); 5000 } 5001 } 5002 5003 public void noteWifiMulticastEnabledFromSourceLocked(WorkSource ws) { 5004 int N = ws.size(); 5005 for (int i=0; i<N; i++) { 5006 noteWifiMulticastEnabledLocked(ws.get(i)); 5007 } 5008 } 5009 5010 public void noteWifiMulticastDisabledFromSourceLocked(WorkSource ws) { 5011 int N = ws.size(); 5012 for (int i=0; i<N; i++) { 5013 noteWifiMulticastDisabledLocked(ws.get(i)); 5014 } 5015 } 5016 5017 private static String[] includeInStringArray(String[] array, String str) { 5018 if (ArrayUtils.indexOf(array, str) >= 0) { 5019 return array; 5020 } 5021 String[] newArray = new String[array.length+1]; 5022 System.arraycopy(array, 0, newArray, 0, array.length); 5023 newArray[array.length] = str; 5024 return newArray; 5025 } 5026 5027 private static String[] excludeFromStringArray(String[] array, String str) { 5028 int index = ArrayUtils.indexOf(array, str); 5029 if (index >= 0) { 5030 String[] newArray = new String[array.length-1]; 5031 if (index > 0) { 5032 System.arraycopy(array, 0, newArray, 0, index); 5033 } 5034 if (index < array.length-1) { 5035 System.arraycopy(array, index+1, newArray, index, array.length-index-1); 5036 } 5037 return newArray; 5038 } 5039 return array; 5040 } 5041 5042 public void noteNetworkInterfaceTypeLocked(String iface, int networkType) { 5043 if (TextUtils.isEmpty(iface)) return; 5044 if (ConnectivityManager.isNetworkTypeMobile(networkType)) { 5045 mMobileIfaces = includeInStringArray(mMobileIfaces, iface); 5046 if (DEBUG) Slog.d(TAG, "Note mobile iface " + iface + ": " + mMobileIfaces); 5047 } else { 5048 mMobileIfaces = excludeFromStringArray(mMobileIfaces, iface); 5049 if (DEBUG) Slog.d(TAG, "Note non-mobile iface " + iface + ": " + mMobileIfaces); 5050 } 5051 if (ConnectivityManager.isNetworkTypeWifi(networkType)) { 5052 mWifiIfaces = includeInStringArray(mWifiIfaces, iface); 5053 if (DEBUG) Slog.d(TAG, "Note wifi iface " + iface + ": " + mWifiIfaces); 5054 } else { 5055 mWifiIfaces = excludeFromStringArray(mWifiIfaces, iface); 5056 if (DEBUG) Slog.d(TAG, "Note non-wifi iface " + iface + ": " + mWifiIfaces); 5057 } 5058 } 5059 5060 public void noteNetworkStatsEnabledLocked() { 5061 // During device boot, qtaguid isn't enabled until after the inital 5062 // loading of battery stats. Now that they're enabled, take our initial 5063 // snapshot for future delta calculation. 5064 updateMobileRadioStateLocked(mClocks.elapsedRealtime(), null); 5065 updateWifiStateLocked(null); 5066 } 5067 5068 @Override public long getScreenOnTime(long elapsedRealtimeUs, int which) { 5069 return mScreenOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 5070 } 5071 5072 @Override public int getScreenOnCount(int which) { 5073 return mScreenOnTimer.getCountLocked(which); 5074 } 5075 5076 @Override public long getScreenBrightnessTime(int brightnessBin, 5077 long elapsedRealtimeUs, int which) { 5078 return mScreenBrightnessTimer[brightnessBin].getTotalTimeLocked( 5079 elapsedRealtimeUs, which); 5080 } 5081 5082 @Override public long getInteractiveTime(long elapsedRealtimeUs, int which) { 5083 return mInteractiveTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 5084 } 5085 5086 @Override public long getPowerSaveModeEnabledTime(long elapsedRealtimeUs, int which) { 5087 return mPowerSaveModeEnabledTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 5088 } 5089 5090 @Override public int getPowerSaveModeEnabledCount(int which) { 5091 return mPowerSaveModeEnabledTimer.getCountLocked(which); 5092 } 5093 5094 @Override public long getDeviceIdleModeTime(int mode, long elapsedRealtimeUs, 5095 int which) { 5096 switch (mode) { 5097 case DEVICE_IDLE_MODE_LIGHT: 5098 return mDeviceIdleModeLightTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 5099 case DEVICE_IDLE_MODE_DEEP: 5100 return mDeviceIdleModeFullTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 5101 } 5102 return 0; 5103 } 5104 5105 @Override public int getDeviceIdleModeCount(int mode, int which) { 5106 switch (mode) { 5107 case DEVICE_IDLE_MODE_LIGHT: 5108 return mDeviceIdleModeLightTimer.getCountLocked(which); 5109 case DEVICE_IDLE_MODE_DEEP: 5110 return mDeviceIdleModeFullTimer.getCountLocked(which); 5111 } 5112 return 0; 5113 } 5114 5115 @Override public long getLongestDeviceIdleModeTime(int mode) { 5116 switch (mode) { 5117 case DEVICE_IDLE_MODE_LIGHT: 5118 return mLongestLightIdleTime; 5119 case DEVICE_IDLE_MODE_DEEP: 5120 return mLongestFullIdleTime; 5121 } 5122 return 0; 5123 } 5124 5125 @Override public long getDeviceIdlingTime(int mode, long elapsedRealtimeUs, int which) { 5126 switch (mode) { 5127 case DEVICE_IDLE_MODE_LIGHT: 5128 return mDeviceLightIdlingTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 5129 case DEVICE_IDLE_MODE_DEEP: 5130 return mDeviceIdlingTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 5131 } 5132 return 0; 5133 } 5134 5135 @Override public int getDeviceIdlingCount(int mode, int which) { 5136 switch (mode) { 5137 case DEVICE_IDLE_MODE_LIGHT: 5138 return mDeviceLightIdlingTimer.getCountLocked(which); 5139 case DEVICE_IDLE_MODE_DEEP: 5140 return mDeviceIdlingTimer.getCountLocked(which); 5141 } 5142 return 0; 5143 } 5144 5145 @Override public int getNumConnectivityChange(int which) { 5146 int val = mNumConnectivityChange; 5147 if (which == STATS_CURRENT) { 5148 val -= mLoadedNumConnectivityChange; 5149 } else if (which == STATS_SINCE_UNPLUGGED) { 5150 val -= mUnpluggedNumConnectivityChange; 5151 } 5152 return val; 5153 } 5154 5155 @Override public long getPhoneOnTime(long elapsedRealtimeUs, int which) { 5156 return mPhoneOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 5157 } 5158 5159 @Override public int getPhoneOnCount(int which) { 5160 return mPhoneOnTimer.getCountLocked(which); 5161 } 5162 5163 @Override public long getPhoneSignalStrengthTime(int strengthBin, 5164 long elapsedRealtimeUs, int which) { 5165 return mPhoneSignalStrengthsTimer[strengthBin].getTotalTimeLocked( 5166 elapsedRealtimeUs, which); 5167 } 5168 5169 @Override public long getPhoneSignalScanningTime( 5170 long elapsedRealtimeUs, int which) { 5171 return mPhoneSignalScanningTimer.getTotalTimeLocked( 5172 elapsedRealtimeUs, which); 5173 } 5174 5175 @Override public int getPhoneSignalStrengthCount(int strengthBin, int which) { 5176 return mPhoneSignalStrengthsTimer[strengthBin].getCountLocked(which); 5177 } 5178 5179 @Override public long getPhoneDataConnectionTime(int dataType, 5180 long elapsedRealtimeUs, int which) { 5181 return mPhoneDataConnectionsTimer[dataType].getTotalTimeLocked( 5182 elapsedRealtimeUs, which); 5183 } 5184 5185 @Override public int getPhoneDataConnectionCount(int dataType, int which) { 5186 return mPhoneDataConnectionsTimer[dataType].getCountLocked(which); 5187 } 5188 5189 @Override public long getMobileRadioActiveTime(long elapsedRealtimeUs, int which) { 5190 return mMobileRadioActiveTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 5191 } 5192 5193 @Override public int getMobileRadioActiveCount(int which) { 5194 return mMobileRadioActiveTimer.getCountLocked(which); 5195 } 5196 5197 @Override public long getMobileRadioActiveAdjustedTime(int which) { 5198 return mMobileRadioActiveAdjustedTime.getCountLocked(which); 5199 } 5200 5201 @Override public long getMobileRadioActiveUnknownTime(int which) { 5202 return mMobileRadioActiveUnknownTime.getCountLocked(which); 5203 } 5204 5205 @Override public int getMobileRadioActiveUnknownCount(int which) { 5206 return (int)mMobileRadioActiveUnknownCount.getCountLocked(which); 5207 } 5208 5209 @Override public long getWifiOnTime(long elapsedRealtimeUs, int which) { 5210 return mWifiOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 5211 } 5212 5213 @Override public long getGlobalWifiRunningTime(long elapsedRealtimeUs, int which) { 5214 return mGlobalWifiRunningTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 5215 } 5216 5217 @Override public long getWifiStateTime(int wifiState, 5218 long elapsedRealtimeUs, int which) { 5219 return mWifiStateTimer[wifiState].getTotalTimeLocked( 5220 elapsedRealtimeUs, which); 5221 } 5222 5223 @Override public int getWifiStateCount(int wifiState, int which) { 5224 return mWifiStateTimer[wifiState].getCountLocked(which); 5225 } 5226 5227 @Override public long getWifiSupplStateTime(int state, 5228 long elapsedRealtimeUs, int which) { 5229 return mWifiSupplStateTimer[state].getTotalTimeLocked( 5230 elapsedRealtimeUs, which); 5231 } 5232 5233 @Override public int getWifiSupplStateCount(int state, int which) { 5234 return mWifiSupplStateTimer[state].getCountLocked(which); 5235 } 5236 5237 @Override public long getWifiSignalStrengthTime(int strengthBin, 5238 long elapsedRealtimeUs, int which) { 5239 return mWifiSignalStrengthsTimer[strengthBin].getTotalTimeLocked( 5240 elapsedRealtimeUs, which); 5241 } 5242 5243 @Override public int getWifiSignalStrengthCount(int strengthBin, int which) { 5244 return mWifiSignalStrengthsTimer[strengthBin].getCountLocked(which); 5245 } 5246 5247 @Override 5248 public ControllerActivityCounter getBluetoothControllerActivity() { 5249 return mBluetoothActivity; 5250 } 5251 5252 @Override 5253 public ControllerActivityCounter getWifiControllerActivity() { 5254 return mWifiActivity; 5255 } 5256 5257 @Override 5258 public ControllerActivityCounter getModemControllerActivity() { 5259 return mModemActivity; 5260 } 5261 5262 @Override 5263 public boolean hasBluetoothActivityReporting() { 5264 return mHasBluetoothReporting; 5265 } 5266 5267 @Override 5268 public boolean hasWifiActivityReporting() { 5269 return mHasWifiReporting; 5270 } 5271 5272 @Override 5273 public boolean hasModemActivityReporting() { 5274 return mHasModemReporting; 5275 } 5276 5277 @Override 5278 public long getFlashlightOnTime(long elapsedRealtimeUs, int which) { 5279 return mFlashlightOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 5280 } 5281 5282 @Override 5283 public long getFlashlightOnCount(int which) { 5284 return mFlashlightOnTimer.getCountLocked(which); 5285 } 5286 5287 @Override 5288 public long getCameraOnTime(long elapsedRealtimeUs, int which) { 5289 return mCameraOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 5290 } 5291 5292 @Override 5293 public long getBluetoothScanTime(long elapsedRealtimeUs, int which) { 5294 return mBluetoothScanTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 5295 } 5296 5297 @Override 5298 public long getNetworkActivityBytes(int type, int which) { 5299 if (type >= 0 && type < mNetworkByteActivityCounters.length) { 5300 return mNetworkByteActivityCounters[type].getCountLocked(which); 5301 } else { 5302 return 0; 5303 } 5304 } 5305 5306 @Override 5307 public long getNetworkActivityPackets(int type, int which) { 5308 if (type >= 0 && type < mNetworkPacketActivityCounters.length) { 5309 return mNetworkPacketActivityCounters[type].getCountLocked(which); 5310 } else { 5311 return 0; 5312 } 5313 } 5314 5315 @Override public long getStartClockTime() { 5316 final long currentTime = System.currentTimeMillis(); 5317 if (ensureStartClockTime(currentTime)) { 5318 recordCurrentTimeChangeLocked(currentTime, mClocks.elapsedRealtime(), 5319 mClocks.uptimeMillis()); 5320 } 5321 return mStartClockTime; 5322 } 5323 5324 @Override public String getStartPlatformVersion() { 5325 return mStartPlatformVersion; 5326 } 5327 5328 @Override public String getEndPlatformVersion() { 5329 return mEndPlatformVersion; 5330 } 5331 5332 @Override public int getParcelVersion() { 5333 return VERSION; 5334 } 5335 5336 @Override public boolean getIsOnBattery() { 5337 return mOnBattery; 5338 } 5339 5340 @Override public SparseArray<? extends BatteryStats.Uid> getUidStats() { 5341 return mUidStats; 5342 } 5343 5344 private static void detachTimerIfNotNull(BatteryStatsImpl.Timer timer) { 5345 if (timer != null) { 5346 timer.detach(); 5347 } 5348 } 5349 5350 private static boolean resetTimerIfNotNull(BatteryStatsImpl.Timer timer, 5351 boolean detachIfReset) { 5352 if (timer != null) { 5353 return timer.reset(detachIfReset); 5354 } 5355 return true; 5356 } 5357 5358 private static boolean resetTimerIfNotNull(DualTimer timer, boolean detachIfReset) { 5359 if (timer != null) { 5360 return timer.reset(detachIfReset); 5361 } 5362 return true; 5363 } 5364 5365 private static void detachLongCounterIfNotNull(LongSamplingCounter counter) { 5366 if (counter != null) { 5367 counter.detach(); 5368 } 5369 } 5370 5371 private static void resetLongCounterIfNotNull(LongSamplingCounter counter, 5372 boolean detachIfReset) { 5373 if (counter != null) { 5374 counter.reset(detachIfReset); 5375 } 5376 } 5377 5378 /** 5379 * The statistics associated with a particular uid. 5380 */ 5381 public static class Uid extends BatteryStats.Uid { 5382 /** 5383 * BatteryStatsImpl that we are associated with. 5384 */ 5385 protected BatteryStatsImpl mBsi; 5386 5387 final int mUid; 5388 5389 /** TimeBase for when uid is in background and device is on battery. */ 5390 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) 5391 public final TimeBase mOnBatteryBackgroundTimeBase; 5392 5393 boolean mWifiRunning; 5394 StopwatchTimer mWifiRunningTimer; 5395 5396 boolean mFullWifiLockOut; 5397 StopwatchTimer mFullWifiLockTimer; 5398 5399 boolean mWifiScanStarted; 5400 DualTimer mWifiScanTimer; 5401 5402 static final int NO_BATCHED_SCAN_STARTED = -1; 5403 int mWifiBatchedScanBinStarted = NO_BATCHED_SCAN_STARTED; 5404 StopwatchTimer[] mWifiBatchedScanTimer; 5405 5406 boolean mWifiMulticastEnabled; 5407 StopwatchTimer mWifiMulticastTimer; 5408 5409 StopwatchTimer mAudioTurnedOnTimer; 5410 StopwatchTimer mVideoTurnedOnTimer; 5411 StopwatchTimer mFlashlightTurnedOnTimer; 5412 StopwatchTimer mCameraTurnedOnTimer; 5413 StopwatchTimer mForegroundActivityTimer; 5414 DualTimer mBluetoothScanTimer; 5415 5416 int mProcessState = ActivityManager.PROCESS_STATE_NONEXISTENT; 5417 StopwatchTimer[] mProcessStateTimer; 5418 5419 BatchTimer mVibratorOnTimer; 5420 5421 Counter[] mUserActivityCounters; 5422 5423 LongSamplingCounter[] mNetworkByteActivityCounters; 5424 LongSamplingCounter[] mNetworkPacketActivityCounters; 5425 LongSamplingCounter mMobileRadioActiveTime; 5426 LongSamplingCounter mMobileRadioActiveCount; 5427 5428 /** 5429 * How many times this UID woke up the Application Processor due to a Mobile radio packet. 5430 */ 5431 private LongSamplingCounter mMobileRadioApWakeupCount; 5432 5433 /** 5434 * How many times this UID woke up the Application Processor due to a Wifi packet. 5435 */ 5436 private LongSamplingCounter mWifiRadioApWakeupCount; 5437 5438 /** 5439 * The amount of time this uid has kept the WiFi controller in idle, tx, and rx mode. 5440 * Can be null if the UID has had no such activity. 5441 */ 5442 private ControllerActivityCounterImpl mWifiControllerActivity; 5443 5444 /** 5445 * The amount of time this uid has kept the Bluetooth controller in idle, tx, and rx mode. 5446 * Can be null if the UID has had no such activity. 5447 */ 5448 private ControllerActivityCounterImpl mBluetoothControllerActivity; 5449 5450 /** 5451 * The amount of time this uid has kept the Modem controller in idle, tx, and rx mode. 5452 * Can be null if the UID has had no such activity. 5453 */ 5454 private ControllerActivityCounterImpl mModemControllerActivity; 5455 5456 /** 5457 * The CPU times we had at the last history details update. 5458 */ 5459 long mLastStepUserTime; 5460 long mLastStepSystemTime; 5461 long mCurStepUserTime; 5462 long mCurStepSystemTime; 5463 5464 LongSamplingCounter mUserCpuTime; 5465 LongSamplingCounter mSystemCpuTime; 5466 LongSamplingCounter[][] mCpuClusterSpeed; 5467 5468 /** 5469 * The statistics we have collected for this uid's wake locks. 5470 */ 5471 final OverflowArrayMap<Wakelock> mWakelockStats; 5472 5473 /** 5474 * The statistics we have collected for this uid's syncs. 5475 */ 5476 final OverflowArrayMap<StopwatchTimer> mSyncStats; 5477 5478 /** 5479 * The statistics we have collected for this uid's jobs. 5480 */ 5481 final OverflowArrayMap<DualTimer> mJobStats; 5482 5483 /** 5484 * The statistics we have collected for this uid's sensor activations. 5485 */ 5486 final SparseArray<Sensor> mSensorStats = new SparseArray<>(); 5487 5488 /** 5489 * The statistics we have collected for this uid's processes. 5490 */ 5491 final ArrayMap<String, Proc> mProcessStats = new ArrayMap<>(); 5492 5493 /** 5494 * The statistics we have collected for this uid's processes. 5495 */ 5496 final ArrayMap<String, Pkg> mPackageStats = new ArrayMap<>(); 5497 5498 /** 5499 * The transient wake stats we have collected for this uid's pids. 5500 */ 5501 final SparseArray<Pid> mPids = new SparseArray<>(); 5502 5503 public Uid(BatteryStatsImpl bsi, int uid) { 5504 mBsi = bsi; 5505 mUid = uid; 5506 5507 mOnBatteryBackgroundTimeBase = new TimeBase(); 5508 mOnBatteryBackgroundTimeBase.init(mBsi.mClocks.uptimeMillis() * 1000, 5509 mBsi.mClocks.elapsedRealtime() * 1000); 5510 5511 mUserCpuTime = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); 5512 mSystemCpuTime = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); 5513 5514 mWakelockStats = mBsi.new OverflowArrayMap<Wakelock>(uid) { 5515 @Override public Wakelock instantiateObject() { 5516 return new Wakelock(mBsi, Uid.this); 5517 } 5518 }; 5519 mSyncStats = mBsi.new OverflowArrayMap<StopwatchTimer>(uid) { 5520 @Override public StopwatchTimer instantiateObject() { 5521 return new StopwatchTimer(mBsi.mClocks, Uid.this, SYNC, null, 5522 mBsi.mOnBatteryTimeBase); 5523 } 5524 }; 5525 mJobStats = mBsi.new OverflowArrayMap<DualTimer>(uid) { 5526 @Override public DualTimer instantiateObject() { 5527 return new DualTimer(mBsi.mClocks, Uid.this, JOB, null, 5528 mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase); 5529 } 5530 }; 5531 5532 mWifiRunningTimer = new StopwatchTimer(mBsi.mClocks, this, WIFI_RUNNING, 5533 mBsi.mWifiRunningTimers, mBsi.mOnBatteryTimeBase); 5534 mFullWifiLockTimer = new StopwatchTimer(mBsi.mClocks, this, FULL_WIFI_LOCK, 5535 mBsi.mFullWifiLockTimers, mBsi.mOnBatteryTimeBase); 5536 mWifiScanTimer = new DualTimer(mBsi.mClocks, this, WIFI_SCAN, 5537 mBsi.mWifiScanTimers, mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase); 5538 mWifiBatchedScanTimer = new StopwatchTimer[NUM_WIFI_BATCHED_SCAN_BINS]; 5539 mWifiMulticastTimer = new StopwatchTimer(mBsi.mClocks, this, WIFI_MULTICAST_ENABLED, 5540 mBsi.mWifiMulticastTimers, mBsi.mOnBatteryTimeBase); 5541 mProcessStateTimer = new StopwatchTimer[NUM_PROCESS_STATE]; 5542 } 5543 5544 @Override 5545 public ArrayMap<String, ? extends BatteryStats.Uid.Wakelock> getWakelockStats() { 5546 return mWakelockStats.getMap(); 5547 } 5548 5549 @Override 5550 public ArrayMap<String, ? extends BatteryStats.Timer> getSyncStats() { 5551 return mSyncStats.getMap(); 5552 } 5553 5554 @Override 5555 public ArrayMap<String, ? extends BatteryStats.Timer> getJobStats() { 5556 return mJobStats.getMap(); 5557 } 5558 5559 @Override 5560 public SparseArray<? extends BatteryStats.Uid.Sensor> getSensorStats() { 5561 return mSensorStats; 5562 } 5563 5564 @Override 5565 public ArrayMap<String, ? extends BatteryStats.Uid.Proc> getProcessStats() { 5566 return mProcessStats; 5567 } 5568 5569 @Override 5570 public ArrayMap<String, ? extends BatteryStats.Uid.Pkg> getPackageStats() { 5571 return mPackageStats; 5572 } 5573 5574 @Override 5575 public int getUid() { 5576 return mUid; 5577 } 5578 5579 @Override 5580 public void noteWifiRunningLocked(long elapsedRealtimeMs) { 5581 if (!mWifiRunning) { 5582 mWifiRunning = true; 5583 if (mWifiRunningTimer == null) { 5584 mWifiRunningTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, WIFI_RUNNING, 5585 mBsi.mWifiRunningTimers, mBsi.mOnBatteryTimeBase); 5586 } 5587 mWifiRunningTimer.startRunningLocked(elapsedRealtimeMs); 5588 } 5589 } 5590 5591 @Override 5592 public void noteWifiStoppedLocked(long elapsedRealtimeMs) { 5593 if (mWifiRunning) { 5594 mWifiRunning = false; 5595 mWifiRunningTimer.stopRunningLocked(elapsedRealtimeMs); 5596 } 5597 } 5598 5599 @Override 5600 public void noteFullWifiLockAcquiredLocked(long elapsedRealtimeMs) { 5601 if (!mFullWifiLockOut) { 5602 mFullWifiLockOut = true; 5603 if (mFullWifiLockTimer == null) { 5604 mFullWifiLockTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, FULL_WIFI_LOCK, 5605 mBsi.mFullWifiLockTimers, mBsi.mOnBatteryTimeBase); 5606 } 5607 mFullWifiLockTimer.startRunningLocked(elapsedRealtimeMs); 5608 } 5609 } 5610 5611 @Override 5612 public void noteFullWifiLockReleasedLocked(long elapsedRealtimeMs) { 5613 if (mFullWifiLockOut) { 5614 mFullWifiLockOut = false; 5615 mFullWifiLockTimer.stopRunningLocked(elapsedRealtimeMs); 5616 } 5617 } 5618 5619 @Override 5620 public void noteWifiScanStartedLocked(long elapsedRealtimeMs) { 5621 if (!mWifiScanStarted) { 5622 mWifiScanStarted = true; 5623 if (mWifiScanTimer == null) { 5624 mWifiScanTimer = new DualTimer(mBsi.mClocks, Uid.this, WIFI_SCAN, 5625 mBsi.mWifiScanTimers, mBsi.mOnBatteryTimeBase, 5626 mOnBatteryBackgroundTimeBase); 5627 } 5628 mWifiScanTimer.startRunningLocked(elapsedRealtimeMs); 5629 } 5630 } 5631 5632 @Override 5633 public void noteWifiScanStoppedLocked(long elapsedRealtimeMs) { 5634 if (mWifiScanStarted) { 5635 mWifiScanStarted = false; 5636 mWifiScanTimer.stopRunningLocked(elapsedRealtimeMs); 5637 } 5638 } 5639 5640 @Override 5641 public void noteWifiBatchedScanStartedLocked(int csph, long elapsedRealtimeMs) { 5642 int bin = 0; 5643 while (csph > 8 && bin < NUM_WIFI_BATCHED_SCAN_BINS-1) { 5644 csph = csph >> 3; 5645 bin++; 5646 } 5647 5648 if (mWifiBatchedScanBinStarted == bin) return; 5649 5650 if (mWifiBatchedScanBinStarted != NO_BATCHED_SCAN_STARTED) { 5651 mWifiBatchedScanTimer[mWifiBatchedScanBinStarted]. 5652 stopRunningLocked(elapsedRealtimeMs); 5653 } 5654 mWifiBatchedScanBinStarted = bin; 5655 if (mWifiBatchedScanTimer[bin] == null) { 5656 makeWifiBatchedScanBin(bin, null); 5657 } 5658 mWifiBatchedScanTimer[bin].startRunningLocked(elapsedRealtimeMs); 5659 } 5660 5661 @Override 5662 public void noteWifiBatchedScanStoppedLocked(long elapsedRealtimeMs) { 5663 if (mWifiBatchedScanBinStarted != NO_BATCHED_SCAN_STARTED) { 5664 mWifiBatchedScanTimer[mWifiBatchedScanBinStarted]. 5665 stopRunningLocked(elapsedRealtimeMs); 5666 mWifiBatchedScanBinStarted = NO_BATCHED_SCAN_STARTED; 5667 } 5668 } 5669 5670 @Override 5671 public void noteWifiMulticastEnabledLocked(long elapsedRealtimeMs) { 5672 if (!mWifiMulticastEnabled) { 5673 mWifiMulticastEnabled = true; 5674 if (mWifiMulticastTimer == null) { 5675 mWifiMulticastTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, 5676 WIFI_MULTICAST_ENABLED, mBsi.mWifiMulticastTimers, mBsi.mOnBatteryTimeBase); 5677 } 5678 mWifiMulticastTimer.startRunningLocked(elapsedRealtimeMs); 5679 } 5680 } 5681 5682 @Override 5683 public void noteWifiMulticastDisabledLocked(long elapsedRealtimeMs) { 5684 if (mWifiMulticastEnabled) { 5685 mWifiMulticastEnabled = false; 5686 mWifiMulticastTimer.stopRunningLocked(elapsedRealtimeMs); 5687 } 5688 } 5689 5690 @Override 5691 public ControllerActivityCounter getWifiControllerActivity() { 5692 return mWifiControllerActivity; 5693 } 5694 5695 @Override 5696 public ControllerActivityCounter getBluetoothControllerActivity() { 5697 return mBluetoothControllerActivity; 5698 } 5699 5700 @Override 5701 public ControllerActivityCounter getModemControllerActivity() { 5702 return mModemControllerActivity; 5703 } 5704 5705 public ControllerActivityCounterImpl getOrCreateWifiControllerActivityLocked() { 5706 if (mWifiControllerActivity == null) { 5707 mWifiControllerActivity = new ControllerActivityCounterImpl(mBsi.mOnBatteryTimeBase, 5708 NUM_BT_TX_LEVELS); 5709 } 5710 return mWifiControllerActivity; 5711 } 5712 5713 public ControllerActivityCounterImpl getOrCreateBluetoothControllerActivityLocked() { 5714 if (mBluetoothControllerActivity == null) { 5715 mBluetoothControllerActivity = new ControllerActivityCounterImpl(mBsi.mOnBatteryTimeBase, 5716 NUM_BT_TX_LEVELS); 5717 } 5718 return mBluetoothControllerActivity; 5719 } 5720 5721 public ControllerActivityCounterImpl getOrCreateModemControllerActivityLocked() { 5722 if (mModemControllerActivity == null) { 5723 mModemControllerActivity = new ControllerActivityCounterImpl(mBsi.mOnBatteryTimeBase, 5724 ModemActivityInfo.TX_POWER_LEVELS); 5725 } 5726 return mModemControllerActivity; 5727 } 5728 5729 public StopwatchTimer createAudioTurnedOnTimerLocked() { 5730 if (mAudioTurnedOnTimer == null) { 5731 mAudioTurnedOnTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, AUDIO_TURNED_ON, 5732 mBsi.mAudioTurnedOnTimers, mBsi.mOnBatteryTimeBase); 5733 } 5734 return mAudioTurnedOnTimer; 5735 } 5736 5737 public void noteAudioTurnedOnLocked(long elapsedRealtimeMs) { 5738 createAudioTurnedOnTimerLocked().startRunningLocked(elapsedRealtimeMs); 5739 } 5740 5741 public void noteAudioTurnedOffLocked(long elapsedRealtimeMs) { 5742 if (mAudioTurnedOnTimer != null) { 5743 mAudioTurnedOnTimer.stopRunningLocked(elapsedRealtimeMs); 5744 } 5745 } 5746 5747 public void noteResetAudioLocked(long elapsedRealtimeMs) { 5748 if (mAudioTurnedOnTimer != null) { 5749 mAudioTurnedOnTimer.stopAllRunningLocked(elapsedRealtimeMs); 5750 } 5751 } 5752 5753 public StopwatchTimer createVideoTurnedOnTimerLocked() { 5754 if (mVideoTurnedOnTimer == null) { 5755 mVideoTurnedOnTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, VIDEO_TURNED_ON, 5756 mBsi.mVideoTurnedOnTimers, mBsi.mOnBatteryTimeBase); 5757 } 5758 return mVideoTurnedOnTimer; 5759 } 5760 5761 public void noteVideoTurnedOnLocked(long elapsedRealtimeMs) { 5762 createVideoTurnedOnTimerLocked().startRunningLocked(elapsedRealtimeMs); 5763 } 5764 5765 public void noteVideoTurnedOffLocked(long elapsedRealtimeMs) { 5766 if (mVideoTurnedOnTimer != null) { 5767 mVideoTurnedOnTimer.stopRunningLocked(elapsedRealtimeMs); 5768 } 5769 } 5770 5771 public void noteResetVideoLocked(long elapsedRealtimeMs) { 5772 if (mVideoTurnedOnTimer != null) { 5773 mVideoTurnedOnTimer.stopAllRunningLocked(elapsedRealtimeMs); 5774 } 5775 } 5776 5777 public StopwatchTimer createFlashlightTurnedOnTimerLocked() { 5778 if (mFlashlightTurnedOnTimer == null) { 5779 mFlashlightTurnedOnTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, 5780 FLASHLIGHT_TURNED_ON, mBsi.mFlashlightTurnedOnTimers, mBsi.mOnBatteryTimeBase); 5781 } 5782 return mFlashlightTurnedOnTimer; 5783 } 5784 5785 public void noteFlashlightTurnedOnLocked(long elapsedRealtimeMs) { 5786 createFlashlightTurnedOnTimerLocked().startRunningLocked(elapsedRealtimeMs); 5787 } 5788 5789 public void noteFlashlightTurnedOffLocked(long elapsedRealtimeMs) { 5790 if (mFlashlightTurnedOnTimer != null) { 5791 mFlashlightTurnedOnTimer.stopRunningLocked(elapsedRealtimeMs); 5792 } 5793 } 5794 5795 public void noteResetFlashlightLocked(long elapsedRealtimeMs) { 5796 if (mFlashlightTurnedOnTimer != null) { 5797 mFlashlightTurnedOnTimer.stopAllRunningLocked(elapsedRealtimeMs); 5798 } 5799 } 5800 5801 public StopwatchTimer createCameraTurnedOnTimerLocked() { 5802 if (mCameraTurnedOnTimer == null) { 5803 mCameraTurnedOnTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, CAMERA_TURNED_ON, 5804 mBsi.mCameraTurnedOnTimers, mBsi.mOnBatteryTimeBase); 5805 } 5806 return mCameraTurnedOnTimer; 5807 } 5808 5809 public void noteCameraTurnedOnLocked(long elapsedRealtimeMs) { 5810 createCameraTurnedOnTimerLocked().startRunningLocked(elapsedRealtimeMs); 5811 } 5812 5813 public void noteCameraTurnedOffLocked(long elapsedRealtimeMs) { 5814 if (mCameraTurnedOnTimer != null) { 5815 mCameraTurnedOnTimer.stopRunningLocked(elapsedRealtimeMs); 5816 } 5817 } 5818 5819 public void noteResetCameraLocked(long elapsedRealtimeMs) { 5820 if (mCameraTurnedOnTimer != null) { 5821 mCameraTurnedOnTimer.stopAllRunningLocked(elapsedRealtimeMs); 5822 } 5823 } 5824 5825 public StopwatchTimer createForegroundActivityTimerLocked() { 5826 if (mForegroundActivityTimer == null) { 5827 mForegroundActivityTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, 5828 FOREGROUND_ACTIVITY, null, mBsi.mOnBatteryTimeBase); 5829 } 5830 return mForegroundActivityTimer; 5831 } 5832 5833 public DualTimer createBluetoothScanTimerLocked() { 5834 if (mBluetoothScanTimer == null) { 5835 mBluetoothScanTimer = new DualTimer(mBsi.mClocks, Uid.this, BLUETOOTH_SCAN_ON, 5836 mBsi.mBluetoothScanOnTimers, mBsi.mOnBatteryTimeBase, 5837 mOnBatteryBackgroundTimeBase); 5838 } 5839 return mBluetoothScanTimer; 5840 } 5841 5842 public void noteBluetoothScanStartedLocked(long elapsedRealtimeMs) { 5843 createBluetoothScanTimerLocked().startRunningLocked(elapsedRealtimeMs); 5844 } 5845 5846 public void noteBluetoothScanStoppedLocked(long elapsedRealtimeMs) { 5847 if (mBluetoothScanTimer != null) { 5848 mBluetoothScanTimer.stopRunningLocked(elapsedRealtimeMs); 5849 } 5850 } 5851 5852 public void noteResetBluetoothScanLocked(long elapsedRealtimeMs) { 5853 if (mBluetoothScanTimer != null) { 5854 mBluetoothScanTimer.stopAllRunningLocked(elapsedRealtimeMs); 5855 } 5856 } 5857 5858 @Override 5859 public void noteActivityResumedLocked(long elapsedRealtimeMs) { 5860 // We always start, since we want multiple foreground PIDs to nest 5861 createForegroundActivityTimerLocked().startRunningLocked(elapsedRealtimeMs); 5862 } 5863 5864 @Override 5865 public void noteActivityPausedLocked(long elapsedRealtimeMs) { 5866 if (mForegroundActivityTimer != null) { 5867 mForegroundActivityTimer.stopRunningLocked(elapsedRealtimeMs); 5868 } 5869 } 5870 5871 public BatchTimer createVibratorOnTimerLocked() { 5872 if (mVibratorOnTimer == null) { 5873 mVibratorOnTimer = new BatchTimer(mBsi.mClocks, Uid.this, VIBRATOR_ON, 5874 mBsi.mOnBatteryTimeBase); 5875 } 5876 return mVibratorOnTimer; 5877 } 5878 5879 public void noteVibratorOnLocked(long durationMillis) { 5880 createVibratorOnTimerLocked().addDuration(mBsi, durationMillis); 5881 } 5882 5883 public void noteVibratorOffLocked() { 5884 if (mVibratorOnTimer != null) { 5885 mVibratorOnTimer.abortLastDuration(mBsi); 5886 } 5887 } 5888 5889 @Override 5890 public long getWifiRunningTime(long elapsedRealtimeUs, int which) { 5891 if (mWifiRunningTimer == null) { 5892 return 0; 5893 } 5894 return mWifiRunningTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 5895 } 5896 5897 @Override 5898 public long getFullWifiLockTime(long elapsedRealtimeUs, int which) { 5899 if (mFullWifiLockTimer == null) { 5900 return 0; 5901 } 5902 return mFullWifiLockTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 5903 } 5904 5905 @Override 5906 public long getWifiScanTime(long elapsedRealtimeUs, int which) { 5907 if (mWifiScanTimer == null) { 5908 return 0; 5909 } 5910 return mWifiScanTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 5911 } 5912 5913 @Override 5914 public int getWifiScanCount(int which) { 5915 if (mWifiScanTimer == null) { 5916 return 0; 5917 } 5918 return mWifiScanTimer.getCountLocked(which); 5919 } 5920 5921 @Override 5922 public int getWifiScanBackgroundCount(int which) { 5923 if (mWifiScanTimer == null || mWifiScanTimer.getSubTimer() == null) { 5924 return 0; 5925 } 5926 return mWifiScanTimer.getSubTimer().getCountLocked(which); 5927 } 5928 5929 @Override 5930 public long getWifiScanActualTime(final long elapsedRealtimeUs) { 5931 if (mWifiScanTimer == null) { 5932 return 0; 5933 } 5934 final long elapsedRealtimeMs = (elapsedRealtimeUs + 500) / 1000; 5935 return mWifiScanTimer.getTotalDurationMsLocked(elapsedRealtimeMs) * 1000; 5936 } 5937 5938 @Override 5939 public long getWifiScanBackgroundTime(final long elapsedRealtimeUs) { 5940 if (mWifiScanTimer == null || mWifiScanTimer.getSubTimer() == null) { 5941 return 0; 5942 } 5943 final long elapsedRealtimeMs = (elapsedRealtimeUs + 500) / 1000; 5944 return mWifiScanTimer.getSubTimer().getTotalDurationMsLocked(elapsedRealtimeMs) * 1000; 5945 } 5946 5947 @Override 5948 public long getWifiBatchedScanTime(int csphBin, long elapsedRealtimeUs, int which) { 5949 if (csphBin < 0 || csphBin >= NUM_WIFI_BATCHED_SCAN_BINS) return 0; 5950 if (mWifiBatchedScanTimer[csphBin] == null) { 5951 return 0; 5952 } 5953 return mWifiBatchedScanTimer[csphBin].getTotalTimeLocked(elapsedRealtimeUs, which); 5954 } 5955 5956 @Override 5957 public int getWifiBatchedScanCount(int csphBin, int which) { 5958 if (csphBin < 0 || csphBin >= NUM_WIFI_BATCHED_SCAN_BINS) return 0; 5959 if (mWifiBatchedScanTimer[csphBin] == null) { 5960 return 0; 5961 } 5962 return mWifiBatchedScanTimer[csphBin].getCountLocked(which); 5963 } 5964 5965 @Override 5966 public long getWifiMulticastTime(long elapsedRealtimeUs, int which) { 5967 if (mWifiMulticastTimer == null) { 5968 return 0; 5969 } 5970 return mWifiMulticastTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 5971 } 5972 5973 @Override 5974 public Timer getAudioTurnedOnTimer() { 5975 return mAudioTurnedOnTimer; 5976 } 5977 5978 @Override 5979 public Timer getVideoTurnedOnTimer() { 5980 return mVideoTurnedOnTimer; 5981 } 5982 5983 @Override 5984 public Timer getFlashlightTurnedOnTimer() { 5985 return mFlashlightTurnedOnTimer; 5986 } 5987 5988 @Override 5989 public Timer getCameraTurnedOnTimer() { 5990 return mCameraTurnedOnTimer; 5991 } 5992 5993 @Override 5994 public Timer getForegroundActivityTimer() { 5995 return mForegroundActivityTimer; 5996 } 5997 5998 @Override 5999 public Timer getBluetoothScanTimer() { 6000 return mBluetoothScanTimer; 6001 } 6002 6003 @Override 6004 public Timer getBluetoothScanBackgroundTimer() { 6005 if (mBluetoothScanTimer == null) { 6006 return null; 6007 } 6008 return mBluetoothScanTimer.getSubTimer(); 6009 } 6010 6011 void makeProcessState(int i, Parcel in) { 6012 if (i < 0 || i >= NUM_PROCESS_STATE) return; 6013 6014 if (in == null) { 6015 mProcessStateTimer[i] = new StopwatchTimer(mBsi.mClocks, this, PROCESS_STATE, null, 6016 mBsi.mOnBatteryTimeBase); 6017 } else { 6018 mProcessStateTimer[i] = new StopwatchTimer(mBsi.mClocks, this, PROCESS_STATE, null, 6019 mBsi.mOnBatteryTimeBase, in); 6020 } 6021 } 6022 6023 @Override 6024 public long getProcessStateTime(int state, long elapsedRealtimeUs, int which) { 6025 if (state < 0 || state >= NUM_PROCESS_STATE) return 0; 6026 if (mProcessStateTimer[state] == null) { 6027 return 0; 6028 } 6029 return mProcessStateTimer[state].getTotalTimeLocked(elapsedRealtimeUs, which); 6030 } 6031 6032 @Override 6033 public Timer getProcessStateTimer(int state) { 6034 if (state < 0 || state >= NUM_PROCESS_STATE) return null; 6035 return mProcessStateTimer[state]; 6036 } 6037 6038 @Override 6039 public Timer getVibratorOnTimer() { 6040 return mVibratorOnTimer; 6041 } 6042 6043 @Override 6044 public void noteUserActivityLocked(int type) { 6045 if (mUserActivityCounters == null) { 6046 initUserActivityLocked(); 6047 } 6048 if (type >= 0 && type < NUM_USER_ACTIVITY_TYPES) { 6049 mUserActivityCounters[type].stepAtomic(); 6050 } else { 6051 Slog.w(TAG, "Unknown user activity type " + type + " was specified.", 6052 new Throwable()); 6053 } 6054 } 6055 6056 @Override 6057 public boolean hasUserActivity() { 6058 return mUserActivityCounters != null; 6059 } 6060 6061 @Override 6062 public int getUserActivityCount(int type, int which) { 6063 if (mUserActivityCounters == null) { 6064 return 0; 6065 } 6066 return mUserActivityCounters[type].getCountLocked(which); 6067 } 6068 6069 void makeWifiBatchedScanBin(int i, Parcel in) { 6070 if (i < 0 || i >= NUM_WIFI_BATCHED_SCAN_BINS) return; 6071 6072 ArrayList<StopwatchTimer> collected = mBsi.mWifiBatchedScanTimers.get(i); 6073 if (collected == null) { 6074 collected = new ArrayList<StopwatchTimer>(); 6075 mBsi.mWifiBatchedScanTimers.put(i, collected); 6076 } 6077 if (in == null) { 6078 mWifiBatchedScanTimer[i] = new StopwatchTimer(mBsi.mClocks, this, WIFI_BATCHED_SCAN, 6079 collected, mBsi.mOnBatteryTimeBase); 6080 } else { 6081 mWifiBatchedScanTimer[i] = new StopwatchTimer(mBsi.mClocks, this, WIFI_BATCHED_SCAN, 6082 collected, mBsi.mOnBatteryTimeBase, in); 6083 } 6084 } 6085 6086 6087 void initUserActivityLocked() { 6088 mUserActivityCounters = new Counter[NUM_USER_ACTIVITY_TYPES]; 6089 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) { 6090 mUserActivityCounters[i] = new Counter(mBsi.mOnBatteryTimeBase); 6091 } 6092 } 6093 6094 void noteNetworkActivityLocked(int type, long deltaBytes, long deltaPackets) { 6095 if (mNetworkByteActivityCounters == null) { 6096 initNetworkActivityLocked(); 6097 } 6098 if (type >= 0 && type < NUM_NETWORK_ACTIVITY_TYPES) { 6099 mNetworkByteActivityCounters[type].addCountLocked(deltaBytes); 6100 mNetworkPacketActivityCounters[type].addCountLocked(deltaPackets); 6101 } else { 6102 Slog.w(TAG, "Unknown network activity type " + type + " was specified.", 6103 new Throwable()); 6104 } 6105 } 6106 6107 void noteMobileRadioActiveTimeLocked(long batteryUptime) { 6108 if (mNetworkByteActivityCounters == null) { 6109 initNetworkActivityLocked(); 6110 } 6111 mMobileRadioActiveTime.addCountLocked(batteryUptime); 6112 mMobileRadioActiveCount.addCountLocked(1); 6113 } 6114 6115 @Override 6116 public boolean hasNetworkActivity() { 6117 return mNetworkByteActivityCounters != null; 6118 } 6119 6120 @Override 6121 public long getNetworkActivityBytes(int type, int which) { 6122 if (mNetworkByteActivityCounters != null && type >= 0 6123 && type < mNetworkByteActivityCounters.length) { 6124 return mNetworkByteActivityCounters[type].getCountLocked(which); 6125 } else { 6126 return 0; 6127 } 6128 } 6129 6130 @Override 6131 public long getNetworkActivityPackets(int type, int which) { 6132 if (mNetworkPacketActivityCounters != null && type >= 0 6133 && type < mNetworkPacketActivityCounters.length) { 6134 return mNetworkPacketActivityCounters[type].getCountLocked(which); 6135 } else { 6136 return 0; 6137 } 6138 } 6139 6140 @Override 6141 public long getMobileRadioActiveTime(int which) { 6142 return mMobileRadioActiveTime != null 6143 ? mMobileRadioActiveTime.getCountLocked(which) : 0; 6144 } 6145 6146 @Override 6147 public int getMobileRadioActiveCount(int which) { 6148 return mMobileRadioActiveCount != null 6149 ? (int)mMobileRadioActiveCount.getCountLocked(which) : 0; 6150 } 6151 6152 @Override 6153 public long getUserCpuTimeUs(int which) { 6154 return mUserCpuTime.getCountLocked(which); 6155 } 6156 6157 @Override 6158 public long getSystemCpuTimeUs(int which) { 6159 return mSystemCpuTime.getCountLocked(which); 6160 } 6161 6162 @Override 6163 public long getTimeAtCpuSpeed(int cluster, int step, int which) { 6164 if (mCpuClusterSpeed != null) { 6165 if (cluster >= 0 && cluster < mCpuClusterSpeed.length) { 6166 final LongSamplingCounter[] cpuSpeeds = mCpuClusterSpeed[cluster]; 6167 if (cpuSpeeds != null) { 6168 if (step >= 0 && step < cpuSpeeds.length) { 6169 final LongSamplingCounter c = cpuSpeeds[step]; 6170 if (c != null) { 6171 return c.getCountLocked(which); 6172 } 6173 } 6174 } 6175 } 6176 } 6177 return 0; 6178 } 6179 6180 public void noteMobileRadioApWakeupLocked() { 6181 if (mMobileRadioApWakeupCount == null) { 6182 mMobileRadioApWakeupCount = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); 6183 } 6184 mMobileRadioApWakeupCount.addCountLocked(1); 6185 } 6186 6187 @Override 6188 public long getMobileRadioApWakeupCount(int which) { 6189 if (mMobileRadioApWakeupCount != null) { 6190 return mMobileRadioApWakeupCount.getCountLocked(which); 6191 } 6192 return 0; 6193 } 6194 6195 public void noteWifiRadioApWakeupLocked() { 6196 if (mWifiRadioApWakeupCount == null) { 6197 mWifiRadioApWakeupCount = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); 6198 } 6199 mWifiRadioApWakeupCount.addCountLocked(1); 6200 } 6201 6202 @Override 6203 public long getWifiRadioApWakeupCount(int which) { 6204 if (mWifiRadioApWakeupCount != null) { 6205 return mWifiRadioApWakeupCount.getCountLocked(which); 6206 } 6207 return 0; 6208 } 6209 6210 void initNetworkActivityLocked() { 6211 mNetworkByteActivityCounters = new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES]; 6212 mNetworkPacketActivityCounters = new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES]; 6213 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 6214 mNetworkByteActivityCounters[i] = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); 6215 mNetworkPacketActivityCounters[i] = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); 6216 } 6217 mMobileRadioActiveTime = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); 6218 mMobileRadioActiveCount = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); 6219 } 6220 6221 /** 6222 * Clear all stats for this uid. Returns true if the uid is completely 6223 * inactive so can be dropped. 6224 */ 6225 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) 6226 public boolean reset() { 6227 boolean active = false; 6228 6229 if (mWifiRunningTimer != null) { 6230 active |= !mWifiRunningTimer.reset(false); 6231 active |= mWifiRunning; 6232 } 6233 if (mFullWifiLockTimer != null) { 6234 active |= !mFullWifiLockTimer.reset(false); 6235 active |= mFullWifiLockOut; 6236 } 6237 if (mWifiScanTimer != null) { 6238 active |= !mWifiScanTimer.reset(false); 6239 active |= mWifiScanStarted; 6240 } 6241 if (mWifiBatchedScanTimer != null) { 6242 for (int i = 0; i < NUM_WIFI_BATCHED_SCAN_BINS; i++) { 6243 if (mWifiBatchedScanTimer[i] != null) { 6244 active |= !mWifiBatchedScanTimer[i].reset(false); 6245 } 6246 } 6247 active |= (mWifiBatchedScanBinStarted != NO_BATCHED_SCAN_STARTED); 6248 } 6249 if (mWifiMulticastTimer != null) { 6250 active |= !mWifiMulticastTimer.reset(false); 6251 active |= mWifiMulticastEnabled; 6252 } 6253 6254 active |= !resetTimerIfNotNull(mAudioTurnedOnTimer, false); 6255 active |= !resetTimerIfNotNull(mVideoTurnedOnTimer, false); 6256 active |= !resetTimerIfNotNull(mFlashlightTurnedOnTimer, false); 6257 active |= !resetTimerIfNotNull(mCameraTurnedOnTimer, false); 6258 active |= !resetTimerIfNotNull(mForegroundActivityTimer, false); 6259 active |= !resetTimerIfNotNull(mBluetoothScanTimer, false); 6260 6261 if (mProcessStateTimer != null) { 6262 for (int i = 0; i < NUM_PROCESS_STATE; i++) { 6263 if (mProcessStateTimer[i] != null) { 6264 active |= !mProcessStateTimer[i].reset(false); 6265 } 6266 } 6267 active |= (mProcessState != ActivityManager.PROCESS_STATE_NONEXISTENT); 6268 } 6269 if (mVibratorOnTimer != null) { 6270 if (mVibratorOnTimer.reset(false)) { 6271 mVibratorOnTimer.detach(); 6272 mVibratorOnTimer = null; 6273 } else { 6274 active = true; 6275 } 6276 } 6277 6278 if (mUserActivityCounters != null) { 6279 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) { 6280 mUserActivityCounters[i].reset(false); 6281 } 6282 } 6283 6284 if (mNetworkByteActivityCounters != null) { 6285 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 6286 mNetworkByteActivityCounters[i].reset(false); 6287 mNetworkPacketActivityCounters[i].reset(false); 6288 } 6289 mMobileRadioActiveTime.reset(false); 6290 mMobileRadioActiveCount.reset(false); 6291 } 6292 6293 if (mWifiControllerActivity != null) { 6294 mWifiControllerActivity.reset(false); 6295 } 6296 6297 if (mBluetoothControllerActivity != null) { 6298 mBluetoothControllerActivity.reset(false); 6299 } 6300 6301 if (mModemControllerActivity != null) { 6302 mModemControllerActivity.reset(false); 6303 } 6304 6305 mUserCpuTime.reset(false); 6306 mSystemCpuTime.reset(false); 6307 6308 if (mCpuClusterSpeed != null) { 6309 for (LongSamplingCounter[] speeds : mCpuClusterSpeed) { 6310 if (speeds != null) { 6311 for (LongSamplingCounter speed : speeds) { 6312 if (speed != null) { 6313 speed.reset(false); 6314 } 6315 } 6316 } 6317 } 6318 } 6319 6320 resetLongCounterIfNotNull(mMobileRadioApWakeupCount, false); 6321 resetLongCounterIfNotNull(mWifiRadioApWakeupCount, false); 6322 6323 final ArrayMap<String, Wakelock> wakeStats = mWakelockStats.getMap(); 6324 for (int iw=wakeStats.size()-1; iw>=0; iw--) { 6325 Wakelock wl = wakeStats.valueAt(iw); 6326 if (wl.reset()) { 6327 wakeStats.removeAt(iw); 6328 } else { 6329 active = true; 6330 } 6331 } 6332 mWakelockStats.cleanup(); 6333 final ArrayMap<String, StopwatchTimer> syncStats = mSyncStats.getMap(); 6334 for (int is=syncStats.size()-1; is>=0; is--) { 6335 StopwatchTimer timer = syncStats.valueAt(is); 6336 if (timer.reset(false)) { 6337 syncStats.removeAt(is); 6338 timer.detach(); 6339 } else { 6340 active = true; 6341 } 6342 } 6343 mSyncStats.cleanup(); 6344 final ArrayMap<String, DualTimer> jobStats = mJobStats.getMap(); 6345 for (int ij=jobStats.size()-1; ij>=0; ij--) { 6346 DualTimer timer = jobStats.valueAt(ij); 6347 if (timer.reset(false)) { 6348 jobStats.removeAt(ij); 6349 timer.detach(); 6350 } else { 6351 active = true; 6352 } 6353 } 6354 mJobStats.cleanup(); 6355 for (int ise=mSensorStats.size()-1; ise>=0; ise--) { 6356 Sensor s = mSensorStats.valueAt(ise); 6357 if (s.reset()) { 6358 mSensorStats.removeAt(ise); 6359 } else { 6360 active = true; 6361 } 6362 } 6363 for (int ip=mProcessStats.size()-1; ip>=0; ip--) { 6364 Proc proc = mProcessStats.valueAt(ip); 6365 proc.detach(); 6366 } 6367 mProcessStats.clear(); 6368 if (mPids.size() > 0) { 6369 for (int i=mPids.size()-1; i>=0; i--) { 6370 Pid pid = mPids.valueAt(i); 6371 if (pid.mWakeNesting > 0) { 6372 active = true; 6373 } else { 6374 mPids.removeAt(i); 6375 } 6376 } 6377 } 6378 if (mPackageStats.size() > 0) { 6379 Iterator<Map.Entry<String, Pkg>> it = mPackageStats.entrySet().iterator(); 6380 while (it.hasNext()) { 6381 Map.Entry<String, Pkg> pkgEntry = it.next(); 6382 Pkg p = pkgEntry.getValue(); 6383 p.detach(); 6384 if (p.mServiceStats.size() > 0) { 6385 Iterator<Map.Entry<String, Pkg.Serv>> it2 6386 = p.mServiceStats.entrySet().iterator(); 6387 while (it2.hasNext()) { 6388 Map.Entry<String, Pkg.Serv> servEntry = it2.next(); 6389 servEntry.getValue().detach(); 6390 } 6391 } 6392 } 6393 mPackageStats.clear(); 6394 } 6395 6396 mLastStepUserTime = mLastStepSystemTime = 0; 6397 mCurStepUserTime = mCurStepSystemTime = 0; 6398 6399 mOnBatteryBackgroundTimeBase.reset(mBsi.mClocks.elapsedRealtime() * 1000, 6400 mBsi.mClocks.uptimeMillis() * 1000); 6401 6402 if (!active) { 6403 if (mWifiRunningTimer != null) { 6404 mWifiRunningTimer.detach(); 6405 } 6406 if (mFullWifiLockTimer != null) { 6407 mFullWifiLockTimer.detach(); 6408 } 6409 if (mWifiScanTimer != null) { 6410 mWifiScanTimer.detach(); 6411 } 6412 for (int i = 0; i < NUM_WIFI_BATCHED_SCAN_BINS; i++) { 6413 if (mWifiBatchedScanTimer[i] != null) { 6414 mWifiBatchedScanTimer[i].detach(); 6415 } 6416 } 6417 if (mWifiMulticastTimer != null) { 6418 mWifiMulticastTimer.detach(); 6419 } 6420 if (mAudioTurnedOnTimer != null) { 6421 mAudioTurnedOnTimer.detach(); 6422 mAudioTurnedOnTimer = null; 6423 } 6424 if (mVideoTurnedOnTimer != null) { 6425 mVideoTurnedOnTimer.detach(); 6426 mVideoTurnedOnTimer = null; 6427 } 6428 if (mFlashlightTurnedOnTimer != null) { 6429 mFlashlightTurnedOnTimer.detach(); 6430 mFlashlightTurnedOnTimer = null; 6431 } 6432 if (mCameraTurnedOnTimer != null) { 6433 mCameraTurnedOnTimer.detach(); 6434 mCameraTurnedOnTimer = null; 6435 } 6436 if (mForegroundActivityTimer != null) { 6437 mForegroundActivityTimer.detach(); 6438 mForegroundActivityTimer = null; 6439 } 6440 if (mBluetoothScanTimer != null) { 6441 mBluetoothScanTimer.detach(); 6442 mBluetoothScanTimer = null; 6443 } 6444 if (mUserActivityCounters != null) { 6445 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) { 6446 mUserActivityCounters[i].detach(); 6447 } 6448 } 6449 if (mNetworkByteActivityCounters != null) { 6450 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 6451 mNetworkByteActivityCounters[i].detach(); 6452 mNetworkPacketActivityCounters[i].detach(); 6453 } 6454 } 6455 6456 if (mWifiControllerActivity != null) { 6457 mWifiControllerActivity.detach(); 6458 } 6459 6460 if (mBluetoothControllerActivity != null) { 6461 mBluetoothControllerActivity.detach(); 6462 } 6463 6464 if (mModemControllerActivity != null) { 6465 mModemControllerActivity.detach(); 6466 } 6467 6468 mPids.clear(); 6469 6470 mUserCpuTime.detach(); 6471 mSystemCpuTime.detach(); 6472 6473 if (mCpuClusterSpeed != null) { 6474 for (LongSamplingCounter[] cpuSpeeds : mCpuClusterSpeed) { 6475 if (cpuSpeeds != null) { 6476 for (LongSamplingCounter c : cpuSpeeds) { 6477 if (c != null) { 6478 c.detach(); 6479 } 6480 } 6481 } 6482 } 6483 } 6484 6485 detachLongCounterIfNotNull(mMobileRadioApWakeupCount); 6486 detachLongCounterIfNotNull(mWifiRadioApWakeupCount); 6487 } 6488 6489 return !active; 6490 } 6491 6492 void writeToParcelLocked(Parcel out, long uptimeUs, long elapsedRealtimeUs) { 6493 mOnBatteryBackgroundTimeBase.writeToParcel(out, uptimeUs, elapsedRealtimeUs); 6494 6495 final ArrayMap<String, Wakelock> wakeStats = mWakelockStats.getMap(); 6496 int NW = wakeStats.size(); 6497 out.writeInt(NW); 6498 for (int iw=0; iw<NW; iw++) { 6499 out.writeString(wakeStats.keyAt(iw)); 6500 Uid.Wakelock wakelock = wakeStats.valueAt(iw); 6501 wakelock.writeToParcelLocked(out, elapsedRealtimeUs); 6502 } 6503 6504 final ArrayMap<String, StopwatchTimer> syncStats = mSyncStats.getMap(); 6505 int NS = syncStats.size(); 6506 out.writeInt(NS); 6507 for (int is=0; is<NS; is++) { 6508 out.writeString(syncStats.keyAt(is)); 6509 StopwatchTimer timer = syncStats.valueAt(is); 6510 Timer.writeTimerToParcel(out, timer, elapsedRealtimeUs); 6511 } 6512 6513 final ArrayMap<String, DualTimer> jobStats = mJobStats.getMap(); 6514 int NJ = jobStats.size(); 6515 out.writeInt(NJ); 6516 for (int ij=0; ij<NJ; ij++) { 6517 out.writeString(jobStats.keyAt(ij)); 6518 DualTimer timer = jobStats.valueAt(ij); 6519 Timer.writeTimerToParcel(out, timer, elapsedRealtimeUs); 6520 } 6521 6522 int NSE = mSensorStats.size(); 6523 out.writeInt(NSE); 6524 for (int ise=0; ise<NSE; ise++) { 6525 out.writeInt(mSensorStats.keyAt(ise)); 6526 Uid.Sensor sensor = mSensorStats.valueAt(ise); 6527 sensor.writeToParcelLocked(out, elapsedRealtimeUs); 6528 } 6529 6530 int NP = mProcessStats.size(); 6531 out.writeInt(NP); 6532 for (int ip=0; ip<NP; ip++) { 6533 out.writeString(mProcessStats.keyAt(ip)); 6534 Uid.Proc proc = mProcessStats.valueAt(ip); 6535 proc.writeToParcelLocked(out); 6536 } 6537 6538 out.writeInt(mPackageStats.size()); 6539 for (Map.Entry<String, Uid.Pkg> pkgEntry : mPackageStats.entrySet()) { 6540 out.writeString(pkgEntry.getKey()); 6541 Uid.Pkg pkg = pkgEntry.getValue(); 6542 pkg.writeToParcelLocked(out); 6543 } 6544 6545 if (mWifiRunningTimer != null) { 6546 out.writeInt(1); 6547 mWifiRunningTimer.writeToParcel(out, elapsedRealtimeUs); 6548 } else { 6549 out.writeInt(0); 6550 } 6551 if (mFullWifiLockTimer != null) { 6552 out.writeInt(1); 6553 mFullWifiLockTimer.writeToParcel(out, elapsedRealtimeUs); 6554 } else { 6555 out.writeInt(0); 6556 } 6557 if (mWifiScanTimer != null) { 6558 out.writeInt(1); 6559 mWifiScanTimer.writeToParcel(out, elapsedRealtimeUs); 6560 } else { 6561 out.writeInt(0); 6562 } 6563 for (int i = 0; i < NUM_WIFI_BATCHED_SCAN_BINS; i++) { 6564 if (mWifiBatchedScanTimer[i] != null) { 6565 out.writeInt(1); 6566 mWifiBatchedScanTimer[i].writeToParcel(out, elapsedRealtimeUs); 6567 } else { 6568 out.writeInt(0); 6569 } 6570 } 6571 if (mWifiMulticastTimer != null) { 6572 out.writeInt(1); 6573 mWifiMulticastTimer.writeToParcel(out, elapsedRealtimeUs); 6574 } else { 6575 out.writeInt(0); 6576 } 6577 6578 if (mAudioTurnedOnTimer != null) { 6579 out.writeInt(1); 6580 mAudioTurnedOnTimer.writeToParcel(out, elapsedRealtimeUs); 6581 } else { 6582 out.writeInt(0); 6583 } 6584 if (mVideoTurnedOnTimer != null) { 6585 out.writeInt(1); 6586 mVideoTurnedOnTimer.writeToParcel(out, elapsedRealtimeUs); 6587 } else { 6588 out.writeInt(0); 6589 } 6590 if (mFlashlightTurnedOnTimer != null) { 6591 out.writeInt(1); 6592 mFlashlightTurnedOnTimer.writeToParcel(out, elapsedRealtimeUs); 6593 } else { 6594 out.writeInt(0); 6595 } 6596 if (mCameraTurnedOnTimer != null) { 6597 out.writeInt(1); 6598 mCameraTurnedOnTimer.writeToParcel(out, elapsedRealtimeUs); 6599 } else { 6600 out.writeInt(0); 6601 } 6602 if (mForegroundActivityTimer != null) { 6603 out.writeInt(1); 6604 mForegroundActivityTimer.writeToParcel(out, elapsedRealtimeUs); 6605 } else { 6606 out.writeInt(0); 6607 } 6608 if (mBluetoothScanTimer != null) { 6609 out.writeInt(1); 6610 mBluetoothScanTimer.writeToParcel(out, elapsedRealtimeUs); 6611 } else { 6612 out.writeInt(0); 6613 } 6614 for (int i = 0; i < NUM_PROCESS_STATE; i++) { 6615 if (mProcessStateTimer[i] != null) { 6616 out.writeInt(1); 6617 mProcessStateTimer[i].writeToParcel(out, elapsedRealtimeUs); 6618 } else { 6619 out.writeInt(0); 6620 } 6621 } 6622 if (mVibratorOnTimer != null) { 6623 out.writeInt(1); 6624 mVibratorOnTimer.writeToParcel(out, elapsedRealtimeUs); 6625 } else { 6626 out.writeInt(0); 6627 } 6628 if (mUserActivityCounters != null) { 6629 out.writeInt(1); 6630 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) { 6631 mUserActivityCounters[i].writeToParcel(out); 6632 } 6633 } else { 6634 out.writeInt(0); 6635 } 6636 if (mNetworkByteActivityCounters != null) { 6637 out.writeInt(1); 6638 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 6639 mNetworkByteActivityCounters[i].writeToParcel(out); 6640 mNetworkPacketActivityCounters[i].writeToParcel(out); 6641 } 6642 mMobileRadioActiveTime.writeToParcel(out); 6643 mMobileRadioActiveCount.writeToParcel(out); 6644 } else { 6645 out.writeInt(0); 6646 } 6647 6648 if (mWifiControllerActivity != null) { 6649 out.writeInt(1); 6650 mWifiControllerActivity.writeToParcel(out, 0); 6651 } else { 6652 out.writeInt(0); 6653 } 6654 6655 if (mBluetoothControllerActivity != null) { 6656 out.writeInt(1); 6657 mBluetoothControllerActivity.writeToParcel(out, 0); 6658 } else { 6659 out.writeInt(0); 6660 } 6661 6662 if (mModemControllerActivity != null) { 6663 out.writeInt(1); 6664 mModemControllerActivity.writeToParcel(out, 0); 6665 } else { 6666 out.writeInt(0); 6667 } 6668 6669 mUserCpuTime.writeToParcel(out); 6670 mSystemCpuTime.writeToParcel(out); 6671 6672 if (mCpuClusterSpeed != null) { 6673 out.writeInt(1); 6674 out.writeInt(mCpuClusterSpeed.length); 6675 for (LongSamplingCounter[] cpuSpeeds : mCpuClusterSpeed) { 6676 if (cpuSpeeds != null) { 6677 out.writeInt(1); 6678 out.writeInt(cpuSpeeds.length); 6679 for (LongSamplingCounter c : cpuSpeeds) { 6680 if (c != null) { 6681 out.writeInt(1); 6682 c.writeToParcel(out); 6683 } else { 6684 out.writeInt(0); 6685 } 6686 } 6687 } else { 6688 out.writeInt(0); 6689 } 6690 } 6691 } else { 6692 out.writeInt(0); 6693 } 6694 6695 if (mMobileRadioApWakeupCount != null) { 6696 out.writeInt(1); 6697 mMobileRadioApWakeupCount.writeToParcel(out); 6698 } else { 6699 out.writeInt(0); 6700 } 6701 6702 if (mWifiRadioApWakeupCount != null) { 6703 out.writeInt(1); 6704 mWifiRadioApWakeupCount.writeToParcel(out); 6705 } else { 6706 out.writeInt(0); 6707 } 6708 } 6709 6710 void readFromParcelLocked(TimeBase timeBase, TimeBase screenOffTimeBase, Parcel in) { 6711 mOnBatteryBackgroundTimeBase.readFromParcel(in); 6712 6713 int numWakelocks = in.readInt(); 6714 mWakelockStats.clear(); 6715 for (int j = 0; j < numWakelocks; j++) { 6716 String wakelockName = in.readString(); 6717 Uid.Wakelock wakelock = new Wakelock(mBsi, this); 6718 wakelock.readFromParcelLocked(timeBase, screenOffTimeBase, in); 6719 mWakelockStats.add(wakelockName, wakelock); 6720 } 6721 6722 int numSyncs = in.readInt(); 6723 mSyncStats.clear(); 6724 for (int j = 0; j < numSyncs; j++) { 6725 String syncName = in.readString(); 6726 if (in.readInt() != 0) { 6727 mSyncStats.add(syncName, 6728 new StopwatchTimer(mBsi.mClocks, Uid.this, SYNC, null, timeBase, in)); 6729 } 6730 } 6731 6732 int numJobs = in.readInt(); 6733 mJobStats.clear(); 6734 for (int j = 0; j < numJobs; j++) { 6735 String jobName = in.readString(); 6736 if (in.readInt() != 0) { 6737 mJobStats.add(jobName, new DualTimer(mBsi.mClocks, Uid.this, JOB, null, 6738 mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase, in)); 6739 } 6740 } 6741 6742 int numSensors = in.readInt(); 6743 mSensorStats.clear(); 6744 for (int k = 0; k < numSensors; k++) { 6745 int sensorNumber = in.readInt(); 6746 Uid.Sensor sensor = new Sensor(mBsi, this, sensorNumber); 6747 sensor.readFromParcelLocked(mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase, 6748 in); 6749 mSensorStats.put(sensorNumber, sensor); 6750 } 6751 6752 int numProcs = in.readInt(); 6753 mProcessStats.clear(); 6754 for (int k = 0; k < numProcs; k++) { 6755 String processName = in.readString(); 6756 Uid.Proc proc = new Proc(mBsi, processName); 6757 proc.readFromParcelLocked(in); 6758 mProcessStats.put(processName, proc); 6759 } 6760 6761 int numPkgs = in.readInt(); 6762 mPackageStats.clear(); 6763 for (int l = 0; l < numPkgs; l++) { 6764 String packageName = in.readString(); 6765 Uid.Pkg pkg = new Pkg(mBsi); 6766 pkg.readFromParcelLocked(in); 6767 mPackageStats.put(packageName, pkg); 6768 } 6769 6770 mWifiRunning = false; 6771 if (in.readInt() != 0) { 6772 mWifiRunningTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, WIFI_RUNNING, 6773 mBsi.mWifiRunningTimers, mBsi.mOnBatteryTimeBase, in); 6774 } else { 6775 mWifiRunningTimer = null; 6776 } 6777 mFullWifiLockOut = false; 6778 if (in.readInt() != 0) { 6779 mFullWifiLockTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, FULL_WIFI_LOCK, 6780 mBsi.mFullWifiLockTimers, mBsi.mOnBatteryTimeBase, in); 6781 } else { 6782 mFullWifiLockTimer = null; 6783 } 6784 mWifiScanStarted = false; 6785 if (in.readInt() != 0) { 6786 mWifiScanTimer = new DualTimer(mBsi.mClocks, Uid.this, WIFI_SCAN, 6787 mBsi.mWifiScanTimers, mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase, 6788 in); 6789 } else { 6790 mWifiScanTimer = null; 6791 } 6792 mWifiBatchedScanBinStarted = NO_BATCHED_SCAN_STARTED; 6793 for (int i = 0; i < NUM_WIFI_BATCHED_SCAN_BINS; i++) { 6794 if (in.readInt() != 0) { 6795 makeWifiBatchedScanBin(i, in); 6796 } else { 6797 mWifiBatchedScanTimer[i] = null; 6798 } 6799 } 6800 mWifiMulticastEnabled = false; 6801 if (in.readInt() != 0) { 6802 mWifiMulticastTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, WIFI_MULTICAST_ENABLED, 6803 mBsi.mWifiMulticastTimers, mBsi.mOnBatteryTimeBase, in); 6804 } else { 6805 mWifiMulticastTimer = null; 6806 } 6807 if (in.readInt() != 0) { 6808 mAudioTurnedOnTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, AUDIO_TURNED_ON, 6809 mBsi.mAudioTurnedOnTimers, mBsi.mOnBatteryTimeBase, in); 6810 } else { 6811 mAudioTurnedOnTimer = null; 6812 } 6813 if (in.readInt() != 0) { 6814 mVideoTurnedOnTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, VIDEO_TURNED_ON, 6815 mBsi.mVideoTurnedOnTimers, mBsi.mOnBatteryTimeBase, in); 6816 } else { 6817 mVideoTurnedOnTimer = null; 6818 } 6819 if (in.readInt() != 0) { 6820 mFlashlightTurnedOnTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, 6821 FLASHLIGHT_TURNED_ON, mBsi.mFlashlightTurnedOnTimers, mBsi.mOnBatteryTimeBase, in); 6822 } else { 6823 mFlashlightTurnedOnTimer = null; 6824 } 6825 if (in.readInt() != 0) { 6826 mCameraTurnedOnTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, CAMERA_TURNED_ON, 6827 mBsi.mCameraTurnedOnTimers, mBsi.mOnBatteryTimeBase, in); 6828 } else { 6829 mCameraTurnedOnTimer = null; 6830 } 6831 if (in.readInt() != 0) { 6832 mForegroundActivityTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, 6833 FOREGROUND_ACTIVITY, null, mBsi.mOnBatteryTimeBase, in); 6834 } else { 6835 mForegroundActivityTimer = null; 6836 } 6837 if (in.readInt() != 0) { 6838 mBluetoothScanTimer = new DualTimer(mBsi.mClocks, Uid.this, BLUETOOTH_SCAN_ON, 6839 mBsi.mBluetoothScanOnTimers, mBsi.mOnBatteryTimeBase, 6840 mOnBatteryBackgroundTimeBase, in); 6841 } else { 6842 mBluetoothScanTimer = null; 6843 } 6844 mProcessState = ActivityManager.PROCESS_STATE_NONEXISTENT; 6845 for (int i = 0; i < NUM_PROCESS_STATE; i++) { 6846 if (in.readInt() != 0) { 6847 makeProcessState(i, in); 6848 } else { 6849 mProcessStateTimer[i] = null; 6850 } 6851 } 6852 if (in.readInt() != 0) { 6853 mVibratorOnTimer = new BatchTimer(mBsi.mClocks, Uid.this, VIBRATOR_ON, 6854 mBsi.mOnBatteryTimeBase, in); 6855 } else { 6856 mVibratorOnTimer = null; 6857 } 6858 if (in.readInt() != 0) { 6859 mUserActivityCounters = new Counter[NUM_USER_ACTIVITY_TYPES]; 6860 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) { 6861 mUserActivityCounters[i] = new Counter(mBsi.mOnBatteryTimeBase, in); 6862 } 6863 } else { 6864 mUserActivityCounters = null; 6865 } 6866 if (in.readInt() != 0) { 6867 mNetworkByteActivityCounters = new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES]; 6868 mNetworkPacketActivityCounters 6869 = new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES]; 6870 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 6871 mNetworkByteActivityCounters[i] 6872 = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in); 6873 mNetworkPacketActivityCounters[i] 6874 = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in); 6875 } 6876 mMobileRadioActiveTime = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in); 6877 mMobileRadioActiveCount = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in); 6878 } else { 6879 mNetworkByteActivityCounters = null; 6880 mNetworkPacketActivityCounters = null; 6881 } 6882 6883 if (in.readInt() != 0) { 6884 mWifiControllerActivity = new ControllerActivityCounterImpl(mBsi.mOnBatteryTimeBase, 6885 NUM_WIFI_TX_LEVELS, in); 6886 } else { 6887 mWifiControllerActivity = null; 6888 } 6889 6890 if (in.readInt() != 0) { 6891 mBluetoothControllerActivity = new ControllerActivityCounterImpl(mBsi.mOnBatteryTimeBase, 6892 NUM_BT_TX_LEVELS, in); 6893 } else { 6894 mBluetoothControllerActivity = null; 6895 } 6896 6897 if (in.readInt() != 0) { 6898 mModemControllerActivity = new ControllerActivityCounterImpl(mBsi.mOnBatteryTimeBase, 6899 ModemActivityInfo.TX_POWER_LEVELS, in); 6900 } else { 6901 mModemControllerActivity = null; 6902 } 6903 6904 mUserCpuTime = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in); 6905 mSystemCpuTime = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in); 6906 6907 if (in.readInt() != 0) { 6908 int numCpuClusters = in.readInt(); 6909 if (mBsi.mPowerProfile != null && mBsi.mPowerProfile.getNumCpuClusters() != numCpuClusters) { 6910 throw new ParcelFormatException("Incompatible number of cpu clusters"); 6911 } 6912 6913 mCpuClusterSpeed = new LongSamplingCounter[numCpuClusters][]; 6914 for (int cluster = 0; cluster < numCpuClusters; cluster++) { 6915 if (in.readInt() != 0) { 6916 int numSpeeds = in.readInt(); 6917 if (mBsi.mPowerProfile != null && 6918 mBsi.mPowerProfile.getNumSpeedStepsInCpuCluster(cluster) != numSpeeds) { 6919 throw new ParcelFormatException("Incompatible number of cpu speeds"); 6920 } 6921 6922 final LongSamplingCounter[] cpuSpeeds = new LongSamplingCounter[numSpeeds]; 6923 mCpuClusterSpeed[cluster] = cpuSpeeds; 6924 for (int speed = 0; speed < numSpeeds; speed++) { 6925 if (in.readInt() != 0) { 6926 cpuSpeeds[speed] = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in); 6927 } 6928 } 6929 } else { 6930 mCpuClusterSpeed[cluster] = null; 6931 } 6932 } 6933 } else { 6934 mCpuClusterSpeed = null; 6935 } 6936 6937 if (in.readInt() != 0) { 6938 mMobileRadioApWakeupCount = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in); 6939 } else { 6940 mMobileRadioApWakeupCount = null; 6941 } 6942 6943 if (in.readInt() != 0) { 6944 mWifiRadioApWakeupCount = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in); 6945 } else { 6946 mWifiRadioApWakeupCount = null; 6947 } 6948 } 6949 6950 /** 6951 * The statistics associated with a particular wake lock. 6952 */ 6953 public static class Wakelock extends BatteryStats.Uid.Wakelock { 6954 /** 6955 * BatteryStatsImpl that we are associated with. 6956 */ 6957 protected BatteryStatsImpl mBsi; 6958 6959 /** 6960 * BatteryStatsImpl that we are associated with. 6961 */ 6962 protected Uid mUid; 6963 6964 /** 6965 * How long (in ms) this uid has been keeping the device partially awake. 6966 */ 6967 DurationTimer mTimerPartial; 6968 6969 /** 6970 * How long (in ms) this uid has been keeping the device fully awake. 6971 */ 6972 StopwatchTimer mTimerFull; 6973 6974 /** 6975 * How long (in ms) this uid has had a window keeping the device awake. 6976 */ 6977 StopwatchTimer mTimerWindow; 6978 6979 /** 6980 * How long (in ms) this uid has had a draw wake lock. 6981 */ 6982 StopwatchTimer mTimerDraw; 6983 6984 public Wakelock(BatteryStatsImpl bsi, Uid uid) { 6985 mBsi = bsi; 6986 mUid = uid; 6987 } 6988 6989 /** 6990 * Reads a possibly null Timer from a Parcel. The timer is associated with the 6991 * proper timer pool from the given BatteryStatsImpl object. 6992 * 6993 * @param in the Parcel to be read from. 6994 * return a new Timer, or null. 6995 */ 6996 private StopwatchTimer readStopwatchTimerFromParcel(int type, 6997 ArrayList<StopwatchTimer> pool, TimeBase timeBase, Parcel in) { 6998 if (in.readInt() == 0) { 6999 return null; 7000 } 7001 7002 return new StopwatchTimer(mBsi.mClocks, mUid, type, pool, timeBase, in); 7003 } 7004 7005 /** 7006 * Reads a possibly null Timer from a Parcel. The timer is associated with the 7007 * proper timer pool from the given BatteryStatsImpl object. 7008 * 7009 * @param in the Parcel to be read from. 7010 * return a new Timer, or null. 7011 */ 7012 private DurationTimer readDurationTimerFromParcel(int type, 7013 ArrayList<StopwatchTimer> pool, TimeBase timeBase, Parcel in) { 7014 if (in.readInt() == 0) { 7015 return null; 7016 } 7017 7018 return new DurationTimer(mBsi.mClocks, mUid, type, pool, timeBase, in); 7019 } 7020 7021 boolean reset() { 7022 boolean wlactive = false; 7023 if (mTimerFull != null) { 7024 wlactive |= !mTimerFull.reset(false); 7025 } 7026 if (mTimerPartial != null) { 7027 wlactive |= !mTimerPartial.reset(false); 7028 } 7029 if (mTimerWindow != null) { 7030 wlactive |= !mTimerWindow.reset(false); 7031 } 7032 if (mTimerDraw != null) { 7033 wlactive |= !mTimerDraw.reset(false); 7034 } 7035 if (!wlactive) { 7036 if (mTimerFull != null) { 7037 mTimerFull.detach(); 7038 mTimerFull = null; 7039 } 7040 if (mTimerPartial != null) { 7041 mTimerPartial.detach(); 7042 mTimerPartial = null; 7043 } 7044 if (mTimerWindow != null) { 7045 mTimerWindow.detach(); 7046 mTimerWindow = null; 7047 } 7048 if (mTimerDraw != null) { 7049 mTimerDraw.detach(); 7050 mTimerDraw = null; 7051 } 7052 } 7053 return !wlactive; 7054 } 7055 7056 void readFromParcelLocked(TimeBase timeBase, TimeBase screenOffTimeBase, Parcel in) { 7057 mTimerPartial = readDurationTimerFromParcel(WAKE_TYPE_PARTIAL, 7058 mBsi.mPartialTimers, screenOffTimeBase, in); 7059 mTimerFull = readStopwatchTimerFromParcel(WAKE_TYPE_FULL, 7060 mBsi.mFullTimers, timeBase, in); 7061 mTimerWindow = readStopwatchTimerFromParcel(WAKE_TYPE_WINDOW, 7062 mBsi.mWindowTimers, timeBase, in); 7063 mTimerDraw = readStopwatchTimerFromParcel(WAKE_TYPE_DRAW, 7064 mBsi.mDrawTimers, timeBase, in); 7065 } 7066 7067 void writeToParcelLocked(Parcel out, long elapsedRealtimeUs) { 7068 Timer.writeTimerToParcel(out, mTimerPartial, elapsedRealtimeUs); 7069 Timer.writeTimerToParcel(out, mTimerFull, elapsedRealtimeUs); 7070 Timer.writeTimerToParcel(out, mTimerWindow, elapsedRealtimeUs); 7071 Timer.writeTimerToParcel(out, mTimerDraw, elapsedRealtimeUs); 7072 } 7073 7074 @Override 7075 public Timer getWakeTime(int type) { 7076 switch (type) { 7077 case WAKE_TYPE_FULL: return mTimerFull; 7078 case WAKE_TYPE_PARTIAL: return mTimerPartial; 7079 case WAKE_TYPE_WINDOW: return mTimerWindow; 7080 case WAKE_TYPE_DRAW: return mTimerDraw; 7081 default: throw new IllegalArgumentException("type = " + type); 7082 } 7083 } 7084 7085 public StopwatchTimer getStopwatchTimer(int type) { 7086 switch (type) { 7087 case WAKE_TYPE_PARTIAL: { 7088 DurationTimer t = mTimerPartial; 7089 if (t == null) { 7090 t = new DurationTimer(mBsi.mClocks, mUid, WAKE_TYPE_PARTIAL, 7091 mBsi.mPartialTimers, mBsi.mOnBatteryScreenOffTimeBase); 7092 mTimerPartial = t; 7093 } 7094 return t; 7095 } 7096 case WAKE_TYPE_FULL: { 7097 StopwatchTimer t = mTimerFull; 7098 if (t == null) { 7099 t = new StopwatchTimer(mBsi.mClocks, mUid, WAKE_TYPE_FULL, 7100 mBsi.mFullTimers, mBsi.mOnBatteryTimeBase); 7101 mTimerFull = t; 7102 } 7103 return t; 7104 } 7105 case WAKE_TYPE_WINDOW: { 7106 StopwatchTimer t = mTimerWindow; 7107 if (t == null) { 7108 t = new StopwatchTimer(mBsi.mClocks, mUid, WAKE_TYPE_WINDOW, 7109 mBsi.mWindowTimers, mBsi.mOnBatteryTimeBase); 7110 mTimerWindow = t; 7111 } 7112 return t; 7113 } 7114 case WAKE_TYPE_DRAW: { 7115 StopwatchTimer t = mTimerDraw; 7116 if (t == null) { 7117 t = new StopwatchTimer(mBsi.mClocks, mUid, WAKE_TYPE_DRAW, 7118 mBsi.mDrawTimers, mBsi.mOnBatteryTimeBase); 7119 mTimerDraw = t; 7120 } 7121 return t; 7122 } 7123 default: 7124 throw new IllegalArgumentException("type=" + type); 7125 } 7126 } 7127 } 7128 7129 public static class Sensor extends BatteryStats.Uid.Sensor { 7130 /** 7131 * BatteryStatsImpl that we are associated with. 7132 */ 7133 protected BatteryStatsImpl mBsi; 7134 7135 /** 7136 * Uid that we are associated with. 7137 */ 7138 protected Uid mUid; 7139 7140 final int mHandle; 7141 DualTimer mTimer; 7142 7143 public Sensor(BatteryStatsImpl bsi, Uid uid, int handle) { 7144 mBsi = bsi; 7145 mUid = uid; 7146 mHandle = handle; 7147 } 7148 7149 private DualTimer readTimersFromParcel( 7150 TimeBase timeBase, TimeBase bgTimeBase, Parcel in) { 7151 if (in.readInt() == 0) { 7152 return null; 7153 } 7154 7155 ArrayList<StopwatchTimer> pool = mBsi.mSensorTimers.get(mHandle); 7156 if (pool == null) { 7157 pool = new ArrayList<StopwatchTimer>(); 7158 mBsi.mSensorTimers.put(mHandle, pool); 7159 } 7160 return new DualTimer(mBsi.mClocks, mUid, 0, pool, timeBase, bgTimeBase, in); 7161 } 7162 7163 boolean reset() { 7164 if (mTimer.reset(true)) { 7165 mTimer = null; 7166 return true; 7167 } 7168 return false; 7169 } 7170 7171 void readFromParcelLocked(TimeBase timeBase, TimeBase bgTimeBase, Parcel in) { 7172 mTimer = readTimersFromParcel(timeBase, bgTimeBase, in); 7173 } 7174 7175 void writeToParcelLocked(Parcel out, long elapsedRealtimeUs) { 7176 Timer.writeTimerToParcel(out, mTimer, elapsedRealtimeUs); 7177 } 7178 7179 @Override 7180 public Timer getSensorTime() { 7181 return mTimer; 7182 } 7183 7184 @Override 7185 public Timer getSensorBackgroundTime() { 7186 if (mTimer == null) { 7187 return null; 7188 } 7189 return mTimer.getSubTimer(); 7190 } 7191 7192 @Override 7193 public int getHandle() { 7194 return mHandle; 7195 } 7196 } 7197 7198 /** 7199 * The statistics associated with a particular process. 7200 */ 7201 public static class Proc extends BatteryStats.Uid.Proc implements TimeBaseObs { 7202 /** 7203 * BatteryStatsImpl that we are associated with. 7204 */ 7205 protected BatteryStatsImpl mBsi; 7206 7207 /** 7208 * The name of this process. 7209 */ 7210 final String mName; 7211 7212 /** 7213 * Remains true until removed from the stats. 7214 */ 7215 boolean mActive = true; 7216 7217 /** 7218 * Total time (in ms) spent executing in user code. 7219 */ 7220 long mUserTime; 7221 7222 /** 7223 * Total time (in ms) spent executing in kernel code. 7224 */ 7225 long mSystemTime; 7226 7227 /** 7228 * Amount of time (in ms) the process was running in the foreground. 7229 */ 7230 long mForegroundTime; 7231 7232 /** 7233 * Number of times the process has been started. 7234 */ 7235 int mStarts; 7236 7237 /** 7238 * Number of times the process has crashed. 7239 */ 7240 int mNumCrashes; 7241 7242 /** 7243 * Number of times the process has had an ANR. 7244 */ 7245 int mNumAnrs; 7246 7247 /** 7248 * The amount of user time loaded from a previous save. 7249 */ 7250 long mLoadedUserTime; 7251 7252 /** 7253 * The amount of system time loaded from a previous save. 7254 */ 7255 long mLoadedSystemTime; 7256 7257 /** 7258 * The amount of foreground time loaded from a previous save. 7259 */ 7260 long mLoadedForegroundTime; 7261 7262 /** 7263 * The number of times the process has started from a previous save. 7264 */ 7265 int mLoadedStarts; 7266 7267 /** 7268 * Number of times the process has crashed from a previous save. 7269 */ 7270 int mLoadedNumCrashes; 7271 7272 /** 7273 * Number of times the process has had an ANR from a previous save. 7274 */ 7275 int mLoadedNumAnrs; 7276 7277 /** 7278 * The amount of user time when last unplugged. 7279 */ 7280 long mUnpluggedUserTime; 7281 7282 /** 7283 * The amount of system time when last unplugged. 7284 */ 7285 long mUnpluggedSystemTime; 7286 7287 /** 7288 * The amount of foreground time since unplugged. 7289 */ 7290 long mUnpluggedForegroundTime; 7291 7292 /** 7293 * The number of times the process has started before unplugged. 7294 */ 7295 int mUnpluggedStarts; 7296 7297 /** 7298 * Number of times the process has crashed before unplugged. 7299 */ 7300 int mUnpluggedNumCrashes; 7301 7302 /** 7303 * Number of times the process has had an ANR before unplugged. 7304 */ 7305 int mUnpluggedNumAnrs; 7306 7307 ArrayList<ExcessivePower> mExcessivePower; 7308 7309 public Proc(BatteryStatsImpl bsi, String name) { 7310 mBsi = bsi; 7311 mName = name; 7312 mBsi.mOnBatteryTimeBase.add(this); 7313 } 7314 7315 public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) { 7316 mUnpluggedUserTime = mUserTime; 7317 mUnpluggedSystemTime = mSystemTime; 7318 mUnpluggedForegroundTime = mForegroundTime; 7319 mUnpluggedStarts = mStarts; 7320 mUnpluggedNumCrashes = mNumCrashes; 7321 mUnpluggedNumAnrs = mNumAnrs; 7322 } 7323 7324 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) { 7325 } 7326 7327 void detach() { 7328 mActive = false; 7329 mBsi.mOnBatteryTimeBase.remove(this); 7330 } 7331 7332 public int countExcessivePowers() { 7333 return mExcessivePower != null ? mExcessivePower.size() : 0; 7334 } 7335 7336 public ExcessivePower getExcessivePower(int i) { 7337 if (mExcessivePower != null) { 7338 return mExcessivePower.get(i); 7339 } 7340 return null; 7341 } 7342 7343 public void addExcessiveWake(long overTime, long usedTime) { 7344 if (mExcessivePower == null) { 7345 mExcessivePower = new ArrayList<ExcessivePower>(); 7346 } 7347 ExcessivePower ew = new ExcessivePower(); 7348 ew.type = ExcessivePower.TYPE_WAKE; 7349 ew.overTime = overTime; 7350 ew.usedTime = usedTime; 7351 mExcessivePower.add(ew); 7352 } 7353 7354 public void addExcessiveCpu(long overTime, long usedTime) { 7355 if (mExcessivePower == null) { 7356 mExcessivePower = new ArrayList<ExcessivePower>(); 7357 } 7358 ExcessivePower ew = new ExcessivePower(); 7359 ew.type = ExcessivePower.TYPE_CPU; 7360 ew.overTime = overTime; 7361 ew.usedTime = usedTime; 7362 mExcessivePower.add(ew); 7363 } 7364 7365 void writeExcessivePowerToParcelLocked(Parcel out) { 7366 if (mExcessivePower == null) { 7367 out.writeInt(0); 7368 return; 7369 } 7370 7371 final int N = mExcessivePower.size(); 7372 out.writeInt(N); 7373 for (int i=0; i<N; i++) { 7374 ExcessivePower ew = mExcessivePower.get(i); 7375 out.writeInt(ew.type); 7376 out.writeLong(ew.overTime); 7377 out.writeLong(ew.usedTime); 7378 } 7379 } 7380 7381 void readExcessivePowerFromParcelLocked(Parcel in) { 7382 final int N = in.readInt(); 7383 if (N == 0) { 7384 mExcessivePower = null; 7385 return; 7386 } 7387 7388 if (N > 10000) { 7389 throw new ParcelFormatException( 7390 "File corrupt: too many excessive power entries " + N); 7391 } 7392 7393 mExcessivePower = new ArrayList<>(); 7394 for (int i=0; i<N; i++) { 7395 ExcessivePower ew = new ExcessivePower(); 7396 ew.type = in.readInt(); 7397 ew.overTime = in.readLong(); 7398 ew.usedTime = in.readLong(); 7399 mExcessivePower.add(ew); 7400 } 7401 } 7402 7403 void writeToParcelLocked(Parcel out) { 7404 out.writeLong(mUserTime); 7405 out.writeLong(mSystemTime); 7406 out.writeLong(mForegroundTime); 7407 out.writeInt(mStarts); 7408 out.writeInt(mNumCrashes); 7409 out.writeInt(mNumAnrs); 7410 out.writeLong(mLoadedUserTime); 7411 out.writeLong(mLoadedSystemTime); 7412 out.writeLong(mLoadedForegroundTime); 7413 out.writeInt(mLoadedStarts); 7414 out.writeInt(mLoadedNumCrashes); 7415 out.writeInt(mLoadedNumAnrs); 7416 out.writeLong(mUnpluggedUserTime); 7417 out.writeLong(mUnpluggedSystemTime); 7418 out.writeLong(mUnpluggedForegroundTime); 7419 out.writeInt(mUnpluggedStarts); 7420 out.writeInt(mUnpluggedNumCrashes); 7421 out.writeInt(mUnpluggedNumAnrs); 7422 writeExcessivePowerToParcelLocked(out); 7423 } 7424 7425 void readFromParcelLocked(Parcel in) { 7426 mUserTime = in.readLong(); 7427 mSystemTime = in.readLong(); 7428 mForegroundTime = in.readLong(); 7429 mStarts = in.readInt(); 7430 mNumCrashes = in.readInt(); 7431 mNumAnrs = in.readInt(); 7432 mLoadedUserTime = in.readLong(); 7433 mLoadedSystemTime = in.readLong(); 7434 mLoadedForegroundTime = in.readLong(); 7435 mLoadedStarts = in.readInt(); 7436 mLoadedNumCrashes = in.readInt(); 7437 mLoadedNumAnrs = in.readInt(); 7438 mUnpluggedUserTime = in.readLong(); 7439 mUnpluggedSystemTime = in.readLong(); 7440 mUnpluggedForegroundTime = in.readLong(); 7441 mUnpluggedStarts = in.readInt(); 7442 mUnpluggedNumCrashes = in.readInt(); 7443 mUnpluggedNumAnrs = in.readInt(); 7444 readExcessivePowerFromParcelLocked(in); 7445 } 7446 7447 public void addCpuTimeLocked(int utime, int stime) { 7448 mUserTime += utime; 7449 mSystemTime += stime; 7450 } 7451 7452 public void addForegroundTimeLocked(long ttime) { 7453 mForegroundTime += ttime; 7454 } 7455 7456 public void incStartsLocked() { 7457 mStarts++; 7458 } 7459 7460 public void incNumCrashesLocked() { 7461 mNumCrashes++; 7462 } 7463 7464 public void incNumAnrsLocked() { 7465 mNumAnrs++; 7466 } 7467 7468 @Override 7469 public boolean isActive() { 7470 return mActive; 7471 } 7472 7473 @Override 7474 public long getUserTime(int which) { 7475 long val = mUserTime; 7476 if (which == STATS_CURRENT) { 7477 val -= mLoadedUserTime; 7478 } else if (which == STATS_SINCE_UNPLUGGED) { 7479 val -= mUnpluggedUserTime; 7480 } 7481 return val; 7482 } 7483 7484 @Override 7485 public long getSystemTime(int which) { 7486 long val = mSystemTime; 7487 if (which == STATS_CURRENT) { 7488 val -= mLoadedSystemTime; 7489 } else if (which == STATS_SINCE_UNPLUGGED) { 7490 val -= mUnpluggedSystemTime; 7491 } 7492 return val; 7493 } 7494 7495 @Override 7496 public long getForegroundTime(int which) { 7497 long val = mForegroundTime; 7498 if (which == STATS_CURRENT) { 7499 val -= mLoadedForegroundTime; 7500 } else if (which == STATS_SINCE_UNPLUGGED) { 7501 val -= mUnpluggedForegroundTime; 7502 } 7503 return val; 7504 } 7505 7506 @Override 7507 public int getStarts(int which) { 7508 int val = mStarts; 7509 if (which == STATS_CURRENT) { 7510 val -= mLoadedStarts; 7511 } else if (which == STATS_SINCE_UNPLUGGED) { 7512 val -= mUnpluggedStarts; 7513 } 7514 return val; 7515 } 7516 7517 @Override 7518 public int getNumCrashes(int which) { 7519 int val = mNumCrashes; 7520 if (which == STATS_CURRENT) { 7521 val -= mLoadedNumCrashes; 7522 } else if (which == STATS_SINCE_UNPLUGGED) { 7523 val -= mUnpluggedNumCrashes; 7524 } 7525 return val; 7526 } 7527 7528 @Override 7529 public int getNumAnrs(int which) { 7530 int val = mNumAnrs; 7531 if (which == STATS_CURRENT) { 7532 val -= mLoadedNumAnrs; 7533 } else if (which == STATS_SINCE_UNPLUGGED) { 7534 val -= mUnpluggedNumAnrs; 7535 } 7536 return val; 7537 } 7538 } 7539 7540 /** 7541 * The statistics associated with a particular package. 7542 */ 7543 public static class Pkg extends BatteryStats.Uid.Pkg implements TimeBaseObs { 7544 /** 7545 * BatteryStatsImpl that we are associated with. 7546 */ 7547 protected BatteryStatsImpl mBsi; 7548 7549 /** 7550 * Number of times wakeup alarms have occurred for this app. 7551 */ 7552 ArrayMap<String, Counter> mWakeupAlarms = new ArrayMap<>(); 7553 7554 /** 7555 * The statics we have collected for this package's services. 7556 */ 7557 final ArrayMap<String, Serv> mServiceStats = new ArrayMap<>(); 7558 7559 public Pkg(BatteryStatsImpl bsi) { 7560 mBsi = bsi; 7561 mBsi.mOnBatteryScreenOffTimeBase.add(this); 7562 } 7563 7564 public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) { 7565 } 7566 7567 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) { 7568 } 7569 7570 void detach() { 7571 mBsi.mOnBatteryScreenOffTimeBase.remove(this); 7572 } 7573 7574 void readFromParcelLocked(Parcel in) { 7575 int numWA = in.readInt(); 7576 mWakeupAlarms.clear(); 7577 for (int i=0; i<numWA; i++) { 7578 String tag = in.readString(); 7579 mWakeupAlarms.put(tag, new Counter(mBsi.mOnBatteryTimeBase, in)); 7580 } 7581 7582 int numServs = in.readInt(); 7583 mServiceStats.clear(); 7584 for (int m = 0; m < numServs; m++) { 7585 String serviceName = in.readString(); 7586 Uid.Pkg.Serv serv = new Serv(mBsi); 7587 mServiceStats.put(serviceName, serv); 7588 7589 serv.readFromParcelLocked(in); 7590 } 7591 } 7592 7593 void writeToParcelLocked(Parcel out) { 7594 int numWA = mWakeupAlarms.size(); 7595 out.writeInt(numWA); 7596 for (int i=0; i<numWA; i++) { 7597 out.writeString(mWakeupAlarms.keyAt(i)); 7598 mWakeupAlarms.valueAt(i).writeToParcel(out); 7599 } 7600 7601 final int NS = mServiceStats.size(); 7602 out.writeInt(NS); 7603 for (int i=0; i<NS; i++) { 7604 out.writeString(mServiceStats.keyAt(i)); 7605 Uid.Pkg.Serv serv = mServiceStats.valueAt(i); 7606 serv.writeToParcelLocked(out); 7607 } 7608 } 7609 7610 @Override 7611 public ArrayMap<String, ? extends BatteryStats.Counter> getWakeupAlarmStats() { 7612 return mWakeupAlarms; 7613 } 7614 7615 public void noteWakeupAlarmLocked(String tag) { 7616 Counter c = mWakeupAlarms.get(tag); 7617 if (c == null) { 7618 c = new Counter(mBsi.mOnBatteryTimeBase); 7619 mWakeupAlarms.put(tag, c); 7620 } 7621 c.stepAtomic(); 7622 } 7623 7624 @Override 7625 public ArrayMap<String, ? extends BatteryStats.Uid.Pkg.Serv> getServiceStats() { 7626 return mServiceStats; 7627 } 7628 7629 /** 7630 * The statistics associated with a particular service. 7631 */ 7632 public static class Serv extends BatteryStats.Uid.Pkg.Serv implements TimeBaseObs { 7633 /** 7634 * BatteryStatsImpl that we are associated with. 7635 */ 7636 protected BatteryStatsImpl mBsi; 7637 7638 /** 7639 * The android package in which this service resides. 7640 */ 7641 protected Pkg mPkg; 7642 7643 /** 7644 * Total time (ms in battery uptime) the service has been left started. 7645 */ 7646 protected long mStartTime; 7647 7648 /** 7649 * If service has been started and not yet stopped, this is 7650 * when it was started. 7651 */ 7652 protected long mRunningSince; 7653 7654 /** 7655 * True if we are currently running. 7656 */ 7657 protected boolean mRunning; 7658 7659 /** 7660 * Total number of times startService() has been called. 7661 */ 7662 protected int mStarts; 7663 7664 /** 7665 * Total time (ms in battery uptime) the service has been left launched. 7666 */ 7667 protected long mLaunchedTime; 7668 7669 /** 7670 * If service has been launched and not yet exited, this is 7671 * when it was launched (ms in battery uptime). 7672 */ 7673 protected long mLaunchedSince; 7674 7675 /** 7676 * True if we are currently launched. 7677 */ 7678 protected boolean mLaunched; 7679 7680 /** 7681 * Total number times the service has been launched. 7682 */ 7683 protected int mLaunches; 7684 7685 /** 7686 * The amount of time spent started loaded from a previous save 7687 * (ms in battery uptime). 7688 */ 7689 protected long mLoadedStartTime; 7690 7691 /** 7692 * The number of starts loaded from a previous save. 7693 */ 7694 protected int mLoadedStarts; 7695 7696 /** 7697 * The number of launches loaded from a previous save. 7698 */ 7699 protected int mLoadedLaunches; 7700 7701 /** 7702 * The amount of time spent started as of the last run (ms 7703 * in battery uptime). 7704 */ 7705 protected long mLastStartTime; 7706 7707 /** 7708 * The number of starts as of the last run. 7709 */ 7710 protected int mLastStarts; 7711 7712 /** 7713 * The number of launches as of the last run. 7714 */ 7715 protected int mLastLaunches; 7716 7717 /** 7718 * The amount of time spent started when last unplugged (ms 7719 * in battery uptime). 7720 */ 7721 protected long mUnpluggedStartTime; 7722 7723 /** 7724 * The number of starts when last unplugged. 7725 */ 7726 protected int mUnpluggedStarts; 7727 7728 /** 7729 * The number of launches when last unplugged. 7730 */ 7731 protected int mUnpluggedLaunches; 7732 7733 /** 7734 * Construct a Serv. Also adds it to the on-battery time base as a listener. 7735 */ 7736 public Serv(BatteryStatsImpl bsi) { 7737 mBsi = bsi; 7738 mBsi.mOnBatteryTimeBase.add(this); 7739 } 7740 7741 public void onTimeStarted(long elapsedRealtime, long baseUptime, 7742 long baseRealtime) { 7743 mUnpluggedStartTime = getStartTimeToNowLocked(baseUptime); 7744 mUnpluggedStarts = mStarts; 7745 mUnpluggedLaunches = mLaunches; 7746 } 7747 7748 public void onTimeStopped(long elapsedRealtime, long baseUptime, 7749 long baseRealtime) { 7750 } 7751 7752 /** 7753 * Remove this Serv as a listener from the time base. 7754 */ 7755 public void detach() { 7756 mBsi.mOnBatteryTimeBase.remove(this); 7757 } 7758 7759 public void readFromParcelLocked(Parcel in) { 7760 mStartTime = in.readLong(); 7761 mRunningSince = in.readLong(); 7762 mRunning = in.readInt() != 0; 7763 mStarts = in.readInt(); 7764 mLaunchedTime = in.readLong(); 7765 mLaunchedSince = in.readLong(); 7766 mLaunched = in.readInt() != 0; 7767 mLaunches = in.readInt(); 7768 mLoadedStartTime = in.readLong(); 7769 mLoadedStarts = in.readInt(); 7770 mLoadedLaunches = in.readInt(); 7771 mLastStartTime = 0; 7772 mLastStarts = 0; 7773 mLastLaunches = 0; 7774 mUnpluggedStartTime = in.readLong(); 7775 mUnpluggedStarts = in.readInt(); 7776 mUnpluggedLaunches = in.readInt(); 7777 } 7778 7779 public void writeToParcelLocked(Parcel out) { 7780 out.writeLong(mStartTime); 7781 out.writeLong(mRunningSince); 7782 out.writeInt(mRunning ? 1 : 0); 7783 out.writeInt(mStarts); 7784 out.writeLong(mLaunchedTime); 7785 out.writeLong(mLaunchedSince); 7786 out.writeInt(mLaunched ? 1 : 0); 7787 out.writeInt(mLaunches); 7788 out.writeLong(mLoadedStartTime); 7789 out.writeInt(mLoadedStarts); 7790 out.writeInt(mLoadedLaunches); 7791 out.writeLong(mUnpluggedStartTime); 7792 out.writeInt(mUnpluggedStarts); 7793 out.writeInt(mUnpluggedLaunches); 7794 } 7795 7796 public long getLaunchTimeToNowLocked(long batteryUptime) { 7797 if (!mLaunched) return mLaunchedTime; 7798 return mLaunchedTime + batteryUptime - mLaunchedSince; 7799 } 7800 7801 public long getStartTimeToNowLocked(long batteryUptime) { 7802 if (!mRunning) return mStartTime; 7803 return mStartTime + batteryUptime - mRunningSince; 7804 } 7805 7806 public void startLaunchedLocked() { 7807 if (!mLaunched) { 7808 mLaunches++; 7809 mLaunchedSince = mBsi.getBatteryUptimeLocked(); 7810 mLaunched = true; 7811 } 7812 } 7813 7814 public void stopLaunchedLocked() { 7815 if (mLaunched) { 7816 long time = mBsi.getBatteryUptimeLocked() - mLaunchedSince; 7817 if (time > 0) { 7818 mLaunchedTime += time; 7819 } else { 7820 mLaunches--; 7821 } 7822 mLaunched = false; 7823 } 7824 } 7825 7826 public void startRunningLocked() { 7827 if (!mRunning) { 7828 mStarts++; 7829 mRunningSince = mBsi.getBatteryUptimeLocked(); 7830 mRunning = true; 7831 } 7832 } 7833 7834 public void stopRunningLocked() { 7835 if (mRunning) { 7836 long time = mBsi.getBatteryUptimeLocked() - mRunningSince; 7837 if (time > 0) { 7838 mStartTime += time; 7839 } else { 7840 mStarts--; 7841 } 7842 mRunning = false; 7843 } 7844 } 7845 7846 public BatteryStatsImpl getBatteryStats() { 7847 return mBsi; 7848 } 7849 7850 @Override 7851 public int getLaunches(int which) { 7852 int val = mLaunches; 7853 if (which == STATS_CURRENT) { 7854 val -= mLoadedLaunches; 7855 } else if (which == STATS_SINCE_UNPLUGGED) { 7856 val -= mUnpluggedLaunches; 7857 } 7858 return val; 7859 } 7860 7861 @Override 7862 public long getStartTime(long now, int which) { 7863 long val = getStartTimeToNowLocked(now); 7864 if (which == STATS_CURRENT) { 7865 val -= mLoadedStartTime; 7866 } else if (which == STATS_SINCE_UNPLUGGED) { 7867 val -= mUnpluggedStartTime; 7868 } 7869 return val; 7870 } 7871 7872 @Override 7873 public int getStarts(int which) { 7874 int val = mStarts; 7875 if (which == STATS_CURRENT) { 7876 val -= mLoadedStarts; 7877 } else if (which == STATS_SINCE_UNPLUGGED) { 7878 val -= mUnpluggedStarts; 7879 } 7880 7881 return val; 7882 } 7883 } 7884 7885 final Serv newServiceStatsLocked() { 7886 return new Serv(mBsi); 7887 } 7888 } 7889 7890 /** 7891 * Retrieve the statistics object for a particular process, creating 7892 * if needed. 7893 */ 7894 public Proc getProcessStatsLocked(String name) { 7895 Proc ps = mProcessStats.get(name); 7896 if (ps == null) { 7897 ps = new Proc(mBsi, name); 7898 mProcessStats.put(name, ps); 7899 } 7900 7901 return ps; 7902 } 7903 7904 public void updateUidProcessStateLocked(int procState) { 7905 int uidRunningState; 7906 if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT) { 7907 uidRunningState = ActivityManager.PROCESS_STATE_NONEXISTENT; 7908 } else if (procState == ActivityManager.PROCESS_STATE_TOP) { 7909 uidRunningState = PROCESS_STATE_TOP; 7910 } else if (procState <= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) { 7911 // Persistent and other foreground states go here. 7912 uidRunningState = PROCESS_STATE_FOREGROUND_SERVICE; 7913 } else if (procState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) { 7914 uidRunningState = PROCESS_STATE_TOP_SLEEPING; 7915 } else if (procState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 7916 // Persistent and other foreground states go here. 7917 uidRunningState = PROCESS_STATE_FOREGROUND; 7918 } else if (procState <= ActivityManager.PROCESS_STATE_RECEIVER) { 7919 uidRunningState = PROCESS_STATE_BACKGROUND; 7920 } else { 7921 uidRunningState = PROCESS_STATE_CACHED; 7922 } 7923 7924 if (mProcessState == uidRunningState) return; 7925 7926 final long elapsedRealtimeMs = mBsi.mClocks.elapsedRealtime(); 7927 final long uptimeMs = mBsi.mClocks.uptimeMillis(); 7928 7929 if (mProcessState != ActivityManager.PROCESS_STATE_NONEXISTENT) { 7930 mProcessStateTimer[mProcessState].stopRunningLocked(elapsedRealtimeMs); 7931 } 7932 mProcessState = uidRunningState; 7933 if (uidRunningState != ActivityManager.PROCESS_STATE_NONEXISTENT) { 7934 if (mProcessStateTimer[uidRunningState] == null) { 7935 makeProcessState(uidRunningState, null); 7936 } 7937 mProcessStateTimer[uidRunningState].startRunningLocked(elapsedRealtimeMs); 7938 } 7939 7940 updateBgTimeBase(uptimeMs * 1000, elapsedRealtimeMs * 1000); 7941 } 7942 7943 public boolean updateBgTimeBase(long uptimeUs, long realtimeUs) { 7944 // Note that PROCESS_STATE_CACHED and ActivityManager.PROCESS_STATE_NONEXISTENT is 7945 // also considered to be 'background' for our purposes, because it's not foreground. 7946 boolean isBgAndUnplugged = mBsi.mOnBatteryTimeBase.isRunning() 7947 && mProcessState >= PROCESS_STATE_BACKGROUND; 7948 return mOnBatteryBackgroundTimeBase.setRunning(isBgAndUnplugged, uptimeUs, realtimeUs); 7949 } 7950 7951 public SparseArray<? extends Pid> getPidStats() { 7952 return mPids; 7953 } 7954 7955 public Pid getPidStatsLocked(int pid) { 7956 Pid p = mPids.get(pid); 7957 if (p == null) { 7958 p = new Pid(); 7959 mPids.put(pid, p); 7960 } 7961 return p; 7962 } 7963 7964 /** 7965 * Retrieve the statistics object for a particular service, creating 7966 * if needed. 7967 */ 7968 public Pkg getPackageStatsLocked(String name) { 7969 Pkg ps = mPackageStats.get(name); 7970 if (ps == null) { 7971 ps = new Pkg(mBsi); 7972 mPackageStats.put(name, ps); 7973 } 7974 7975 return ps; 7976 } 7977 7978 /** 7979 * Retrieve the statistics object for a particular service, creating 7980 * if needed. 7981 */ 7982 public Pkg.Serv getServiceStatsLocked(String pkg, String serv) { 7983 Pkg ps = getPackageStatsLocked(pkg); 7984 Pkg.Serv ss = ps.mServiceStats.get(serv); 7985 if (ss == null) { 7986 ss = ps.newServiceStatsLocked(); 7987 ps.mServiceStats.put(serv, ss); 7988 } 7989 7990 return ss; 7991 } 7992 7993 public void readSyncSummaryFromParcelLocked(String name, Parcel in) { 7994 StopwatchTimer timer = mSyncStats.instantiateObject(); 7995 timer.readSummaryFromParcelLocked(in); 7996 mSyncStats.add(name, timer); 7997 } 7998 7999 public void readJobSummaryFromParcelLocked(String name, Parcel in) { 8000 DualTimer timer = mJobStats.instantiateObject(); 8001 timer.readSummaryFromParcelLocked(in); 8002 mJobStats.add(name, timer); 8003 } 8004 8005 public void readWakeSummaryFromParcelLocked(String wlName, Parcel in) { 8006 Wakelock wl = new Wakelock(mBsi, this); 8007 mWakelockStats.add(wlName, wl); 8008 if (in.readInt() != 0) { 8009 wl.getStopwatchTimer(WAKE_TYPE_FULL).readSummaryFromParcelLocked(in); 8010 } 8011 if (in.readInt() != 0) { 8012 wl.getStopwatchTimer(WAKE_TYPE_PARTIAL).readSummaryFromParcelLocked(in); 8013 } 8014 if (in.readInt() != 0) { 8015 wl.getStopwatchTimer(WAKE_TYPE_WINDOW).readSummaryFromParcelLocked(in); 8016 } 8017 if (in.readInt() != 0) { 8018 wl.getStopwatchTimer(WAKE_TYPE_DRAW).readSummaryFromParcelLocked(in); 8019 } 8020 } 8021 8022 public DualTimer getSensorTimerLocked(int sensor, boolean create) { 8023 Sensor se = mSensorStats.get(sensor); 8024 if (se == null) { 8025 if (!create) { 8026 return null; 8027 } 8028 se = new Sensor(mBsi, this, sensor); 8029 mSensorStats.put(sensor, se); 8030 } 8031 DualTimer t = se.mTimer; 8032 if (t != null) { 8033 return t; 8034 } 8035 ArrayList<StopwatchTimer> timers = mBsi.mSensorTimers.get(sensor); 8036 if (timers == null) { 8037 timers = new ArrayList<StopwatchTimer>(); 8038 mBsi.mSensorTimers.put(sensor, timers); 8039 } 8040 t = new DualTimer(mBsi.mClocks, this, BatteryStats.SENSOR, timers, 8041 mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase); 8042 se.mTimer = t; 8043 return t; 8044 } 8045 8046 public void noteStartSyncLocked(String name, long elapsedRealtimeMs) { 8047 StopwatchTimer t = mSyncStats.startObject(name); 8048 if (t != null) { 8049 t.startRunningLocked(elapsedRealtimeMs); 8050 } 8051 } 8052 8053 public void noteStopSyncLocked(String name, long elapsedRealtimeMs) { 8054 StopwatchTimer t = mSyncStats.stopObject(name); 8055 if (t != null) { 8056 t.stopRunningLocked(elapsedRealtimeMs); 8057 } 8058 } 8059 8060 public void noteStartJobLocked(String name, long elapsedRealtimeMs) { 8061 DualTimer t = mJobStats.startObject(name); 8062 if (t != null) { 8063 t.startRunningLocked(elapsedRealtimeMs); 8064 } 8065 } 8066 8067 public void noteStopJobLocked(String name, long elapsedRealtimeMs) { 8068 DualTimer t = mJobStats.stopObject(name); 8069 if (t != null) { 8070 t.stopRunningLocked(elapsedRealtimeMs); 8071 } 8072 } 8073 8074 public void noteStartWakeLocked(int pid, String name, int type, long elapsedRealtimeMs) { 8075 Wakelock wl = mWakelockStats.startObject(name); 8076 if (wl != null) { 8077 wl.getStopwatchTimer(type).startRunningLocked(elapsedRealtimeMs); 8078 } 8079 if (pid >= 0 && type == WAKE_TYPE_PARTIAL) { 8080 Pid p = getPidStatsLocked(pid); 8081 if (p.mWakeNesting++ == 0) { 8082 p.mWakeStartMs = elapsedRealtimeMs; 8083 } 8084 } 8085 } 8086 8087 public void noteStopWakeLocked(int pid, String name, int type, long elapsedRealtimeMs) { 8088 Wakelock wl = mWakelockStats.stopObject(name); 8089 if (wl != null) { 8090 wl.getStopwatchTimer(type).stopRunningLocked(elapsedRealtimeMs); 8091 } 8092 if (pid >= 0 && type == WAKE_TYPE_PARTIAL) { 8093 Pid p = mPids.get(pid); 8094 if (p != null && p.mWakeNesting > 0) { 8095 if (p.mWakeNesting-- == 1) { 8096 p.mWakeSumMs += elapsedRealtimeMs - p.mWakeStartMs; 8097 p.mWakeStartMs = 0; 8098 } 8099 } 8100 } 8101 } 8102 8103 public void reportExcessiveWakeLocked(String proc, long overTime, long usedTime) { 8104 Proc p = getProcessStatsLocked(proc); 8105 if (p != null) { 8106 p.addExcessiveWake(overTime, usedTime); 8107 } 8108 } 8109 8110 public void reportExcessiveCpuLocked(String proc, long overTime, long usedTime) { 8111 Proc p = getProcessStatsLocked(proc); 8112 if (p != null) { 8113 p.addExcessiveCpu(overTime, usedTime); 8114 } 8115 } 8116 8117 public void noteStartSensor(int sensor, long elapsedRealtimeMs) { 8118 DualTimer t = getSensorTimerLocked(sensor, /* create= */ true); 8119 t.startRunningLocked(elapsedRealtimeMs); 8120 } 8121 8122 public void noteStopSensor(int sensor, long elapsedRealtimeMs) { 8123 // Don't create a timer if one doesn't already exist 8124 DualTimer t = getSensorTimerLocked(sensor, false); 8125 if (t != null) { 8126 t.stopRunningLocked(elapsedRealtimeMs); 8127 } 8128 } 8129 8130 public void noteStartGps(long elapsedRealtimeMs) { 8131 noteStartSensor(Sensor.GPS, elapsedRealtimeMs); 8132 } 8133 8134 public void noteStopGps(long elapsedRealtimeMs) { 8135 noteStopSensor(Sensor.GPS, elapsedRealtimeMs); 8136 } 8137 8138 public BatteryStatsImpl getBatteryStats() { 8139 return mBsi; 8140 } 8141 } 8142 8143 public BatteryStatsImpl(File systemDir, Handler handler, ExternalStatsSync externalSync) { 8144 this(new SystemClocks(), systemDir, handler, externalSync, null); 8145 } 8146 8147 public BatteryStatsImpl(File systemDir, Handler handler, ExternalStatsSync externalSync, 8148 PlatformIdleStateCallback cb) { 8149 this(new SystemClocks(), systemDir, handler, externalSync, cb); 8150 } 8151 8152 public BatteryStatsImpl(Clocks clocks, File systemDir, Handler handler, 8153 ExternalStatsSync externalSync, PlatformIdleStateCallback cb) { 8154 init(clocks); 8155 8156 if (systemDir != null) { 8157 mFile = new JournaledFile(new File(systemDir, "batterystats.bin"), 8158 new File(systemDir, "batterystats.bin.tmp")); 8159 } else { 8160 mFile = null; 8161 } 8162 mCheckinFile = new AtomicFile(new File(systemDir, "batterystats-checkin.bin")); 8163 mDailyFile = new AtomicFile(new File(systemDir, "batterystats-daily.xml")); 8164 mExternalSync = externalSync; 8165 mHandler = new MyHandler(handler.getLooper()); 8166 mStartCount++; 8167 mScreenOnTimer = new StopwatchTimer(mClocks, null, -1, null, mOnBatteryTimeBase); 8168 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 8169 mScreenBrightnessTimer[i] = new StopwatchTimer(mClocks, null, -100-i, null, 8170 mOnBatteryTimeBase); 8171 } 8172 mInteractiveTimer = new StopwatchTimer(mClocks, null, -10, null, mOnBatteryTimeBase); 8173 mPowerSaveModeEnabledTimer = new StopwatchTimer(mClocks, null, -2, null, 8174 mOnBatteryTimeBase); 8175 mDeviceIdleModeLightTimer = new StopwatchTimer(mClocks, null, -11, null, 8176 mOnBatteryTimeBase); 8177 mDeviceIdleModeFullTimer = new StopwatchTimer(mClocks, null, -14, null, mOnBatteryTimeBase); 8178 mDeviceLightIdlingTimer = new StopwatchTimer(mClocks, null, -15, null, mOnBatteryTimeBase); 8179 mDeviceIdlingTimer = new StopwatchTimer(mClocks, null, -12, null, mOnBatteryTimeBase); 8180 mPhoneOnTimer = new StopwatchTimer(mClocks, null, -3, null, mOnBatteryTimeBase); 8181 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) { 8182 mPhoneSignalStrengthsTimer[i] = new StopwatchTimer(mClocks, null, -200-i, null, 8183 mOnBatteryTimeBase); 8184 } 8185 mPhoneSignalScanningTimer = new StopwatchTimer(mClocks, null, -200+1, null, 8186 mOnBatteryTimeBase); 8187 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 8188 mPhoneDataConnectionsTimer[i] = new StopwatchTimer(mClocks, null, -300-i, null, 8189 mOnBatteryTimeBase); 8190 } 8191 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 8192 mNetworkByteActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase); 8193 mNetworkPacketActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase); 8194 } 8195 mWifiActivity = new ControllerActivityCounterImpl(mOnBatteryTimeBase, NUM_WIFI_TX_LEVELS); 8196 mBluetoothActivity = new ControllerActivityCounterImpl(mOnBatteryTimeBase, 8197 NUM_BT_TX_LEVELS); 8198 mModemActivity = new ControllerActivityCounterImpl(mOnBatteryTimeBase, 8199 ModemActivityInfo.TX_POWER_LEVELS); 8200 mMobileRadioActiveTimer = new StopwatchTimer(mClocks, null, -400, null, mOnBatteryTimeBase); 8201 mMobileRadioActivePerAppTimer = new StopwatchTimer(mClocks, null, -401, null, 8202 mOnBatteryTimeBase); 8203 mMobileRadioActiveAdjustedTime = new LongSamplingCounter(mOnBatteryTimeBase); 8204 mMobileRadioActiveUnknownTime = new LongSamplingCounter(mOnBatteryTimeBase); 8205 mMobileRadioActiveUnknownCount = new LongSamplingCounter(mOnBatteryTimeBase); 8206 mWifiOnTimer = new StopwatchTimer(mClocks, null, -4, null, mOnBatteryTimeBase); 8207 mGlobalWifiRunningTimer = new StopwatchTimer(mClocks, null, -5, null, mOnBatteryTimeBase); 8208 for (int i=0; i<NUM_WIFI_STATES; i++) { 8209 mWifiStateTimer[i] = new StopwatchTimer(mClocks, null, -600-i, null, 8210 mOnBatteryTimeBase); 8211 } 8212 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) { 8213 mWifiSupplStateTimer[i] = new StopwatchTimer(mClocks, null, -700-i, null, 8214 mOnBatteryTimeBase); 8215 } 8216 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { 8217 mWifiSignalStrengthsTimer[i] = new StopwatchTimer(mClocks, null, -800-i, null, 8218 mOnBatteryTimeBase); 8219 } 8220 mAudioOnTimer = new StopwatchTimer(mClocks, null, -7, null, mOnBatteryTimeBase); 8221 mVideoOnTimer = new StopwatchTimer(mClocks, null, -8, null, mOnBatteryTimeBase); 8222 mFlashlightOnTimer = new StopwatchTimer(mClocks, null, -9, null, mOnBatteryTimeBase); 8223 mCameraOnTimer = new StopwatchTimer(mClocks, null, -13, null, mOnBatteryTimeBase); 8224 mBluetoothScanTimer = new StopwatchTimer(mClocks, null, -14, null, mOnBatteryTimeBase); 8225 mDischargeScreenOffCounter = new LongSamplingCounter(mOnBatteryScreenOffTimeBase); 8226 mDischargeCounter = new LongSamplingCounter(mOnBatteryTimeBase); 8227 mOnBattery = mOnBatteryInternal = false; 8228 long uptime = mClocks.uptimeMillis() * 1000; 8229 long realtime = mClocks.elapsedRealtime() * 1000; 8230 initTimes(uptime, realtime); 8231 mStartPlatformVersion = mEndPlatformVersion = Build.ID; 8232 mDischargeStartLevel = 0; 8233 mDischargeUnplugLevel = 0; 8234 mDischargePlugLevel = -1; 8235 mDischargeCurrentLevel = 0; 8236 mCurrentBatteryLevel = 0; 8237 initDischarge(); 8238 clearHistoryLocked(); 8239 updateDailyDeadlineLocked(); 8240 mPlatformIdleStateCallback = cb; 8241 } 8242 8243 public BatteryStatsImpl(Parcel p) { 8244 this(new SystemClocks(), p); 8245 } 8246 8247 public BatteryStatsImpl(Clocks clocks, Parcel p) { 8248 init(clocks); 8249 mFile = null; 8250 mCheckinFile = null; 8251 mDailyFile = null; 8252 mHandler = null; 8253 mExternalSync = null; 8254 clearHistoryLocked(); 8255 readFromParcel(p); 8256 mPlatformIdleStateCallback = null; 8257 } 8258 8259 public void setPowerProfile(PowerProfile profile) { 8260 synchronized (this) { 8261 mPowerProfile = profile; 8262 8263 // We need to initialize the KernelCpuSpeedReaders to read from 8264 // the first cpu of each core. Once we have the PowerProfile, we have access to this 8265 // information. 8266 final int numClusters = mPowerProfile.getNumCpuClusters(); 8267 mKernelCpuSpeedReaders = new KernelCpuSpeedReader[numClusters]; 8268 int firstCpuOfCluster = 0; 8269 for (int i = 0; i < numClusters; i++) { 8270 final int numSpeedSteps = mPowerProfile.getNumSpeedStepsInCpuCluster(i); 8271 mKernelCpuSpeedReaders[i] = new KernelCpuSpeedReader(firstCpuOfCluster, 8272 numSpeedSteps); 8273 firstCpuOfCluster += mPowerProfile.getNumCoresInCpuCluster(i); 8274 } 8275 8276 if (mEstimatedBatteryCapacity == -1) { 8277 // Initialize the estimated battery capacity to a known preset one. 8278 mEstimatedBatteryCapacity = (int) mPowerProfile.getBatteryCapacity(); 8279 } 8280 } 8281 } 8282 8283 public void setCallback(BatteryCallback cb) { 8284 mCallback = cb; 8285 } 8286 8287 public void setRadioScanningTimeout(long timeout) { 8288 if (mPhoneSignalScanningTimer != null) { 8289 mPhoneSignalScanningTimer.setTimeout(timeout); 8290 } 8291 } 8292 8293 public void updateDailyDeadlineLocked() { 8294 // Get the current time. 8295 long currentTime = mDailyStartTime = System.currentTimeMillis(); 8296 Calendar calDeadline = Calendar.getInstance(); 8297 calDeadline.setTimeInMillis(currentTime); 8298 8299 // Move time up to the next day, ranging from 1am to 3pm. 8300 calDeadline.set(Calendar.DAY_OF_YEAR, calDeadline.get(Calendar.DAY_OF_YEAR) + 1); 8301 calDeadline.set(Calendar.MILLISECOND, 0); 8302 calDeadline.set(Calendar.SECOND, 0); 8303 calDeadline.set(Calendar.MINUTE, 0); 8304 calDeadline.set(Calendar.HOUR_OF_DAY, 1); 8305 mNextMinDailyDeadline = calDeadline.getTimeInMillis(); 8306 calDeadline.set(Calendar.HOUR_OF_DAY, 3); 8307 mNextMaxDailyDeadline = calDeadline.getTimeInMillis(); 8308 } 8309 8310 public void recordDailyStatsIfNeededLocked(boolean settled) { 8311 long currentTime = System.currentTimeMillis(); 8312 if (currentTime >= mNextMaxDailyDeadline) { 8313 recordDailyStatsLocked(); 8314 } else if (settled && currentTime >= mNextMinDailyDeadline) { 8315 recordDailyStatsLocked(); 8316 } else if (currentTime < (mDailyStartTime-(1000*60*60*24))) { 8317 recordDailyStatsLocked(); 8318 } 8319 } 8320 8321 public void recordDailyStatsLocked() { 8322 DailyItem item = new DailyItem(); 8323 item.mStartTime = mDailyStartTime; 8324 item.mEndTime = System.currentTimeMillis(); 8325 boolean hasData = false; 8326 if (mDailyDischargeStepTracker.mNumStepDurations > 0) { 8327 hasData = true; 8328 item.mDischargeSteps = new LevelStepTracker( 8329 mDailyDischargeStepTracker.mNumStepDurations, 8330 mDailyDischargeStepTracker.mStepDurations); 8331 } 8332 if (mDailyChargeStepTracker.mNumStepDurations > 0) { 8333 hasData = true; 8334 item.mChargeSteps = new LevelStepTracker( 8335 mDailyChargeStepTracker.mNumStepDurations, 8336 mDailyChargeStepTracker.mStepDurations); 8337 } 8338 if (mDailyPackageChanges != null) { 8339 hasData = true; 8340 item.mPackageChanges = mDailyPackageChanges; 8341 mDailyPackageChanges = null; 8342 } 8343 mDailyDischargeStepTracker.init(); 8344 mDailyChargeStepTracker.init(); 8345 updateDailyDeadlineLocked(); 8346 8347 if (hasData) { 8348 mDailyItems.add(item); 8349 while (mDailyItems.size() > MAX_DAILY_ITEMS) { 8350 mDailyItems.remove(0); 8351 } 8352 final ByteArrayOutputStream memStream = new ByteArrayOutputStream(); 8353 try { 8354 XmlSerializer out = new FastXmlSerializer(); 8355 out.setOutput(memStream, StandardCharsets.UTF_8.name()); 8356 writeDailyItemsLocked(out); 8357 BackgroundThread.getHandler().post(new Runnable() { 8358 @Override 8359 public void run() { 8360 synchronized (mCheckinFile) { 8361 FileOutputStream stream = null; 8362 try { 8363 stream = mDailyFile.startWrite(); 8364 memStream.writeTo(stream); 8365 stream.flush(); 8366 FileUtils.sync(stream); 8367 stream.close(); 8368 mDailyFile.finishWrite(stream); 8369 } catch (IOException e) { 8370 Slog.w("BatteryStats", 8371 "Error writing battery daily items", e); 8372 mDailyFile.failWrite(stream); 8373 } 8374 } 8375 } 8376 }); 8377 } catch (IOException e) { 8378 } 8379 } 8380 } 8381 8382 private void writeDailyItemsLocked(XmlSerializer out) throws IOException { 8383 StringBuilder sb = new StringBuilder(64); 8384 out.startDocument(null, true); 8385 out.startTag(null, "daily-items"); 8386 for (int i=0; i<mDailyItems.size(); i++) { 8387 final DailyItem dit = mDailyItems.get(i); 8388 out.startTag(null, "item"); 8389 out.attribute(null, "start", Long.toString(dit.mStartTime)); 8390 out.attribute(null, "end", Long.toString(dit.mEndTime)); 8391 writeDailyLevelSteps(out, "dis", dit.mDischargeSteps, sb); 8392 writeDailyLevelSteps(out, "chg", dit.mChargeSteps, sb); 8393 if (dit.mPackageChanges != null) { 8394 for (int j=0; j<dit.mPackageChanges.size(); j++) { 8395 PackageChange pc = dit.mPackageChanges.get(j); 8396 if (pc.mUpdate) { 8397 out.startTag(null, "upd"); 8398 out.attribute(null, "pkg", pc.mPackageName); 8399 out.attribute(null, "ver", Integer.toString(pc.mVersionCode)); 8400 out.endTag(null, "upd"); 8401 } else { 8402 out.startTag(null, "rem"); 8403 out.attribute(null, "pkg", pc.mPackageName); 8404 out.endTag(null, "rem"); 8405 } 8406 } 8407 } 8408 out.endTag(null, "item"); 8409 } 8410 out.endTag(null, "daily-items"); 8411 out.endDocument(); 8412 } 8413 8414 private void writeDailyLevelSteps(XmlSerializer out, String tag, LevelStepTracker steps, 8415 StringBuilder tmpBuilder) throws IOException { 8416 if (steps != null) { 8417 out.startTag(null, tag); 8418 out.attribute(null, "n", Integer.toString(steps.mNumStepDurations)); 8419 for (int i=0; i<steps.mNumStepDurations; i++) { 8420 out.startTag(null, "s"); 8421 tmpBuilder.setLength(0); 8422 steps.encodeEntryAt(i, tmpBuilder); 8423 out.attribute(null, "v", tmpBuilder.toString()); 8424 out.endTag(null, "s"); 8425 } 8426 out.endTag(null, tag); 8427 } 8428 } 8429 8430 public void readDailyStatsLocked() { 8431 Slog.d(TAG, "Reading daily items from " + mDailyFile.getBaseFile()); 8432 mDailyItems.clear(); 8433 FileInputStream stream; 8434 try { 8435 stream = mDailyFile.openRead(); 8436 } catch (FileNotFoundException e) { 8437 return; 8438 } 8439 try { 8440 XmlPullParser parser = Xml.newPullParser(); 8441 parser.setInput(stream, StandardCharsets.UTF_8.name()); 8442 readDailyItemsLocked(parser); 8443 } catch (XmlPullParserException e) { 8444 } finally { 8445 try { 8446 stream.close(); 8447 } catch (IOException e) { 8448 } 8449 } 8450 } 8451 8452 private void readDailyItemsLocked(XmlPullParser parser) { 8453 try { 8454 int type; 8455 while ((type = parser.next()) != XmlPullParser.START_TAG 8456 && type != XmlPullParser.END_DOCUMENT) { 8457 ; 8458 } 8459 8460 if (type != XmlPullParser.START_TAG) { 8461 throw new IllegalStateException("no start tag found"); 8462 } 8463 8464 int outerDepth = parser.getDepth(); 8465 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 8466 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 8467 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 8468 continue; 8469 } 8470 8471 String tagName = parser.getName(); 8472 if (tagName.equals("item")) { 8473 readDailyItemTagLocked(parser); 8474 } else { 8475 Slog.w(TAG, "Unknown element under <daily-items>: " 8476 + parser.getName()); 8477 XmlUtils.skipCurrentTag(parser); 8478 } 8479 } 8480 8481 } catch (IllegalStateException e) { 8482 Slog.w(TAG, "Failed parsing daily " + e); 8483 } catch (NullPointerException e) { 8484 Slog.w(TAG, "Failed parsing daily " + e); 8485 } catch (NumberFormatException e) { 8486 Slog.w(TAG, "Failed parsing daily " + e); 8487 } catch (XmlPullParserException e) { 8488 Slog.w(TAG, "Failed parsing daily " + e); 8489 } catch (IOException e) { 8490 Slog.w(TAG, "Failed parsing daily " + e); 8491 } catch (IndexOutOfBoundsException e) { 8492 Slog.w(TAG, "Failed parsing daily " + e); 8493 } 8494 } 8495 8496 void readDailyItemTagLocked(XmlPullParser parser) throws NumberFormatException, 8497 XmlPullParserException, IOException { 8498 DailyItem dit = new DailyItem(); 8499 String attr = parser.getAttributeValue(null, "start"); 8500 if (attr != null) { 8501 dit.mStartTime = Long.parseLong(attr); 8502 } 8503 attr = parser.getAttributeValue(null, "end"); 8504 if (attr != null) { 8505 dit.mEndTime = Long.parseLong(attr); 8506 } 8507 int outerDepth = parser.getDepth(); 8508 int type; 8509 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 8510 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 8511 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 8512 continue; 8513 } 8514 8515 String tagName = parser.getName(); 8516 if (tagName.equals("dis")) { 8517 readDailyItemTagDetailsLocked(parser, dit, false, "dis"); 8518 } else if (tagName.equals("chg")) { 8519 readDailyItemTagDetailsLocked(parser, dit, true, "chg"); 8520 } else if (tagName.equals("upd")) { 8521 if (dit.mPackageChanges == null) { 8522 dit.mPackageChanges = new ArrayList<>(); 8523 } 8524 PackageChange pc = new PackageChange(); 8525 pc.mUpdate = true; 8526 pc.mPackageName = parser.getAttributeValue(null, "pkg"); 8527 String verStr = parser.getAttributeValue(null, "ver"); 8528 pc.mVersionCode = verStr != null ? Integer.parseInt(verStr) : 0; 8529 dit.mPackageChanges.add(pc); 8530 XmlUtils.skipCurrentTag(parser); 8531 } else if (tagName.equals("rem")) { 8532 if (dit.mPackageChanges == null) { 8533 dit.mPackageChanges = new ArrayList<>(); 8534 } 8535 PackageChange pc = new PackageChange(); 8536 pc.mUpdate = false; 8537 pc.mPackageName = parser.getAttributeValue(null, "pkg"); 8538 dit.mPackageChanges.add(pc); 8539 XmlUtils.skipCurrentTag(parser); 8540 } else { 8541 Slog.w(TAG, "Unknown element under <item>: " 8542 + parser.getName()); 8543 XmlUtils.skipCurrentTag(parser); 8544 } 8545 } 8546 mDailyItems.add(dit); 8547 } 8548 8549 void readDailyItemTagDetailsLocked(XmlPullParser parser, DailyItem dit, boolean isCharge, 8550 String tag) 8551 throws NumberFormatException, XmlPullParserException, IOException { 8552 final String numAttr = parser.getAttributeValue(null, "n"); 8553 if (numAttr == null) { 8554 Slog.w(TAG, "Missing 'n' attribute at " + parser.getPositionDescription()); 8555 XmlUtils.skipCurrentTag(parser); 8556 return; 8557 } 8558 final int num = Integer.parseInt(numAttr); 8559 LevelStepTracker steps = new LevelStepTracker(num); 8560 if (isCharge) { 8561 dit.mChargeSteps = steps; 8562 } else { 8563 dit.mDischargeSteps = steps; 8564 } 8565 int i = 0; 8566 int outerDepth = parser.getDepth(); 8567 int type; 8568 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 8569 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 8570 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 8571 continue; 8572 } 8573 8574 String tagName = parser.getName(); 8575 if ("s".equals(tagName)) { 8576 if (i < num) { 8577 String valueAttr = parser.getAttributeValue(null, "v"); 8578 if (valueAttr != null) { 8579 steps.decodeEntryAt(i, valueAttr); 8580 i++; 8581 } 8582 } 8583 } else { 8584 Slog.w(TAG, "Unknown element under <" + tag + ">: " 8585 + parser.getName()); 8586 XmlUtils.skipCurrentTag(parser); 8587 } 8588 } 8589 steps.mNumStepDurations = i; 8590 } 8591 8592 @Override 8593 public DailyItem getDailyItemLocked(int daysAgo) { 8594 int index = mDailyItems.size()-1-daysAgo; 8595 return index >= 0 ? mDailyItems.get(index) : null; 8596 } 8597 8598 @Override 8599 public long getCurrentDailyStartTime() { 8600 return mDailyStartTime; 8601 } 8602 8603 @Override 8604 public long getNextMinDailyDeadline() { 8605 return mNextMinDailyDeadline; 8606 } 8607 8608 @Override 8609 public long getNextMaxDailyDeadline() { 8610 return mNextMaxDailyDeadline; 8611 } 8612 8613 @Override 8614 public boolean startIteratingOldHistoryLocked() { 8615 if (DEBUG_HISTORY) Slog.i(TAG, "ITERATING: buff size=" + mHistoryBuffer.dataSize() 8616 + " pos=" + mHistoryBuffer.dataPosition()); 8617 if ((mHistoryIterator = mHistory) == null) { 8618 return false; 8619 } 8620 mHistoryBuffer.setDataPosition(0); 8621 mHistoryReadTmp.clear(); 8622 mReadOverflow = false; 8623 mIteratingHistory = true; 8624 return true; 8625 } 8626 8627 @Override 8628 public boolean getNextOldHistoryLocked(HistoryItem out) { 8629 boolean end = mHistoryBuffer.dataPosition() >= mHistoryBuffer.dataSize(); 8630 if (!end) { 8631 readHistoryDelta(mHistoryBuffer, mHistoryReadTmp); 8632 mReadOverflow |= mHistoryReadTmp.cmd == HistoryItem.CMD_OVERFLOW; 8633 } 8634 HistoryItem cur = mHistoryIterator; 8635 if (cur == null) { 8636 if (!mReadOverflow && !end) { 8637 Slog.w(TAG, "Old history ends before new history!"); 8638 } 8639 return false; 8640 } 8641 out.setTo(cur); 8642 mHistoryIterator = cur.next; 8643 if (!mReadOverflow) { 8644 if (end) { 8645 Slog.w(TAG, "New history ends before old history!"); 8646 } else if (!out.same(mHistoryReadTmp)) { 8647 PrintWriter pw = new FastPrintWriter(new LogWriter(android.util.Log.WARN, TAG)); 8648 pw.println("Histories differ!"); 8649 pw.println("Old history:"); 8650 (new HistoryPrinter()).printNextItem(pw, out, 0, false, true); 8651 pw.println("New history:"); 8652 (new HistoryPrinter()).printNextItem(pw, mHistoryReadTmp, 0, false, 8653 true); 8654 pw.flush(); 8655 } 8656 } 8657 return true; 8658 } 8659 8660 @Override 8661 public void finishIteratingOldHistoryLocked() { 8662 mIteratingHistory = false; 8663 mHistoryBuffer.setDataPosition(mHistoryBuffer.dataSize()); 8664 mHistoryIterator = null; 8665 } 8666 8667 public int getHistoryTotalSize() { 8668 return MAX_HISTORY_BUFFER; 8669 } 8670 8671 public int getHistoryUsedSize() { 8672 return mHistoryBuffer.dataSize(); 8673 } 8674 8675 @Override 8676 public boolean startIteratingHistoryLocked() { 8677 if (DEBUG_HISTORY) Slog.i(TAG, "ITERATING: buff size=" + mHistoryBuffer.dataSize() 8678 + " pos=" + mHistoryBuffer.dataPosition()); 8679 if (mHistoryBuffer.dataSize() <= 0) { 8680 return false; 8681 } 8682 mHistoryBuffer.setDataPosition(0); 8683 mReadOverflow = false; 8684 mIteratingHistory = true; 8685 mReadHistoryStrings = new String[mHistoryTagPool.size()]; 8686 mReadHistoryUids = new int[mHistoryTagPool.size()]; 8687 mReadHistoryChars = 0; 8688 for (HashMap.Entry<HistoryTag, Integer> ent : mHistoryTagPool.entrySet()) { 8689 final HistoryTag tag = ent.getKey(); 8690 final int idx = ent.getValue(); 8691 mReadHistoryStrings[idx] = tag.string; 8692 mReadHistoryUids[idx] = tag.uid; 8693 mReadHistoryChars += tag.string.length() + 1; 8694 } 8695 return true; 8696 } 8697 8698 @Override 8699 public int getHistoryStringPoolSize() { 8700 return mReadHistoryStrings.length; 8701 } 8702 8703 @Override 8704 public int getHistoryStringPoolBytes() { 8705 // Each entry is a fixed 12 bytes: 4 for index, 4 for uid, 4 for string size 8706 // Each string character is 2 bytes. 8707 return (mReadHistoryStrings.length * 12) + (mReadHistoryChars * 2); 8708 } 8709 8710 @Override 8711 public String getHistoryTagPoolString(int index) { 8712 return mReadHistoryStrings[index]; 8713 } 8714 8715 @Override 8716 public int getHistoryTagPoolUid(int index) { 8717 return mReadHistoryUids[index]; 8718 } 8719 8720 @Override 8721 public boolean getNextHistoryLocked(HistoryItem out) { 8722 final int pos = mHistoryBuffer.dataPosition(); 8723 if (pos == 0) { 8724 out.clear(); 8725 } 8726 boolean end = pos >= mHistoryBuffer.dataSize(); 8727 if (end) { 8728 return false; 8729 } 8730 8731 final long lastRealtime = out.time; 8732 final long lastWalltime = out.currentTime; 8733 readHistoryDelta(mHistoryBuffer, out); 8734 if (out.cmd != HistoryItem.CMD_CURRENT_TIME 8735 && out.cmd != HistoryItem.CMD_RESET && lastWalltime != 0) { 8736 out.currentTime = lastWalltime + (out.time - lastRealtime); 8737 } 8738 return true; 8739 } 8740 8741 @Override 8742 public void finishIteratingHistoryLocked() { 8743 mIteratingHistory = false; 8744 mHistoryBuffer.setDataPosition(mHistoryBuffer.dataSize()); 8745 mReadHistoryStrings = null; 8746 } 8747 8748 @Override 8749 public long getHistoryBaseTime() { 8750 return mHistoryBaseTime; 8751 } 8752 8753 @Override 8754 public int getStartCount() { 8755 return mStartCount; 8756 } 8757 8758 public boolean isOnBattery() { 8759 return mOnBattery; 8760 } 8761 8762 public boolean isCharging() { 8763 return mCharging; 8764 } 8765 8766 public boolean isScreenOn() { 8767 return mScreenState == Display.STATE_ON; 8768 } 8769 8770 void initTimes(long uptime, long realtime) { 8771 mStartClockTime = System.currentTimeMillis(); 8772 mOnBatteryTimeBase.init(uptime, realtime); 8773 mOnBatteryScreenOffTimeBase.init(uptime, realtime); 8774 mRealtime = 0; 8775 mUptime = 0; 8776 mRealtimeStart = realtime; 8777 mUptimeStart = uptime; 8778 } 8779 8780 void initDischarge() { 8781 mLowDischargeAmountSinceCharge = 0; 8782 mHighDischargeAmountSinceCharge = 0; 8783 mDischargeAmountScreenOn = 0; 8784 mDischargeAmountScreenOnSinceCharge = 0; 8785 mDischargeAmountScreenOff = 0; 8786 mDischargeAmountScreenOffSinceCharge = 0; 8787 mDischargeStepTracker.init(); 8788 mChargeStepTracker.init(); 8789 mDischargeScreenOffCounter.reset(false); 8790 mDischargeCounter.reset(false); 8791 } 8792 8793 public void resetAllStatsCmdLocked() { 8794 resetAllStatsLocked(); 8795 final long mSecUptime = mClocks.uptimeMillis(); 8796 long uptime = mSecUptime * 1000; 8797 long mSecRealtime = mClocks.elapsedRealtime(); 8798 long realtime = mSecRealtime * 1000; 8799 mDischargeStartLevel = mHistoryCur.batteryLevel; 8800 pullPendingStateUpdatesLocked(); 8801 addHistoryRecordLocked(mSecRealtime, mSecUptime); 8802 mDischargeCurrentLevel = mDischargeUnplugLevel = mDischargePlugLevel 8803 = mCurrentBatteryLevel = mHistoryCur.batteryLevel; 8804 mOnBatteryTimeBase.reset(uptime, realtime); 8805 mOnBatteryScreenOffTimeBase.reset(uptime, realtime); 8806 if ((mHistoryCur.states&HistoryItem.STATE_BATTERY_PLUGGED_FLAG) == 0) { 8807 if (mScreenState == Display.STATE_ON) { 8808 mDischargeScreenOnUnplugLevel = mHistoryCur.batteryLevel; 8809 mDischargeScreenOffUnplugLevel = 0; 8810 } else { 8811 mDischargeScreenOnUnplugLevel = 0; 8812 mDischargeScreenOffUnplugLevel = mHistoryCur.batteryLevel; 8813 } 8814 mDischargeAmountScreenOn = 0; 8815 mDischargeAmountScreenOff = 0; 8816 } 8817 initActiveHistoryEventsLocked(mSecRealtime, mSecUptime); 8818 } 8819 8820 private void resetAllStatsLocked() { 8821 final long uptimeMillis = mClocks.uptimeMillis(); 8822 final long elapsedRealtimeMillis = mClocks.elapsedRealtime(); 8823 mStartCount = 0; 8824 initTimes(uptimeMillis * 1000, elapsedRealtimeMillis * 1000); 8825 mScreenOnTimer.reset(false); 8826 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 8827 mScreenBrightnessTimer[i].reset(false); 8828 } 8829 8830 if (mPowerProfile != null) { 8831 mEstimatedBatteryCapacity = (int) mPowerProfile.getBatteryCapacity(); 8832 } else { 8833 mEstimatedBatteryCapacity = -1; 8834 } 8835 mInteractiveTimer.reset(false); 8836 mPowerSaveModeEnabledTimer.reset(false); 8837 mLastIdleTimeStart = elapsedRealtimeMillis; 8838 mLongestLightIdleTime = 0; 8839 mLongestFullIdleTime = 0; 8840 mDeviceIdleModeLightTimer.reset(false); 8841 mDeviceIdleModeFullTimer.reset(false); 8842 mDeviceLightIdlingTimer.reset(false); 8843 mDeviceIdlingTimer.reset(false); 8844 mPhoneOnTimer.reset(false); 8845 mAudioOnTimer.reset(false); 8846 mVideoOnTimer.reset(false); 8847 mFlashlightOnTimer.reset(false); 8848 mCameraOnTimer.reset(false); 8849 mBluetoothScanTimer.reset(false); 8850 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) { 8851 mPhoneSignalStrengthsTimer[i].reset(false); 8852 } 8853 mPhoneSignalScanningTimer.reset(false); 8854 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 8855 mPhoneDataConnectionsTimer[i].reset(false); 8856 } 8857 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 8858 mNetworkByteActivityCounters[i].reset(false); 8859 mNetworkPacketActivityCounters[i].reset(false); 8860 } 8861 mMobileRadioActiveTimer.reset(false); 8862 mMobileRadioActivePerAppTimer.reset(false); 8863 mMobileRadioActiveAdjustedTime.reset(false); 8864 mMobileRadioActiveUnknownTime.reset(false); 8865 mMobileRadioActiveUnknownCount.reset(false); 8866 mWifiOnTimer.reset(false); 8867 mGlobalWifiRunningTimer.reset(false); 8868 for (int i=0; i<NUM_WIFI_STATES; i++) { 8869 mWifiStateTimer[i].reset(false); 8870 } 8871 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) { 8872 mWifiSupplStateTimer[i].reset(false); 8873 } 8874 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { 8875 mWifiSignalStrengthsTimer[i].reset(false); 8876 } 8877 mWifiActivity.reset(false); 8878 mBluetoothActivity.reset(false); 8879 mModemActivity.reset(false); 8880 mNumConnectivityChange = mLoadedNumConnectivityChange = mUnpluggedNumConnectivityChange = 0; 8881 8882 for (int i=0; i<mUidStats.size(); i++) { 8883 if (mUidStats.valueAt(i).reset()) { 8884 mUidStats.remove(mUidStats.keyAt(i)); 8885 i--; 8886 } 8887 } 8888 8889 if (mKernelWakelockStats.size() > 0) { 8890 for (SamplingTimer timer : mKernelWakelockStats.values()) { 8891 mOnBatteryScreenOffTimeBase.remove(timer); 8892 } 8893 mKernelWakelockStats.clear(); 8894 } 8895 8896 if (mKernelMemoryStats.size() > 0) { 8897 for (int i = 0; i < mKernelMemoryStats.size(); i++) { 8898 mOnBatteryTimeBase.remove(mKernelMemoryStats.valueAt(i)); 8899 } 8900 mKernelMemoryStats.clear(); 8901 } 8902 8903 if (mWakeupReasonStats.size() > 0) { 8904 for (SamplingTimer timer : mWakeupReasonStats.values()) { 8905 mOnBatteryTimeBase.remove(timer); 8906 } 8907 mWakeupReasonStats.clear(); 8908 } 8909 8910 mLastHistoryStepDetails = null; 8911 mLastStepCpuUserTime = mLastStepCpuSystemTime = 0; 8912 mCurStepCpuUserTime = mCurStepCpuSystemTime = 0; 8913 mLastStepCpuUserTime = mCurStepCpuUserTime = 0; 8914 mLastStepCpuSystemTime = mCurStepCpuSystemTime = 0; 8915 mLastStepStatUserTime = mCurStepStatUserTime = 0; 8916 mLastStepStatSystemTime = mCurStepStatSystemTime = 0; 8917 mLastStepStatIOWaitTime = mCurStepStatIOWaitTime = 0; 8918 mLastStepStatIrqTime = mCurStepStatIrqTime = 0; 8919 mLastStepStatSoftIrqTime = mCurStepStatSoftIrqTime = 0; 8920 mLastStepStatIdleTime = mCurStepStatIdleTime = 0; 8921 8922 initDischarge(); 8923 8924 clearHistoryLocked(); 8925 } 8926 8927 private void initActiveHistoryEventsLocked(long elapsedRealtimeMs, long uptimeMs) { 8928 for (int i=0; i<HistoryItem.EVENT_COUNT; i++) { 8929 if (!mRecordAllHistory && i == HistoryItem.EVENT_PROC) { 8930 // Not recording process starts/stops. 8931 continue; 8932 } 8933 HashMap<String, SparseIntArray> active = mActiveEvents.getStateForEvent(i); 8934 if (active == null) { 8935 continue; 8936 } 8937 for (HashMap.Entry<String, SparseIntArray> ent : active.entrySet()) { 8938 SparseIntArray uids = ent.getValue(); 8939 for (int j=0; j<uids.size(); j++) { 8940 addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, i, ent.getKey(), 8941 uids.keyAt(j)); 8942 } 8943 } 8944 } 8945 } 8946 8947 void updateDischargeScreenLevelsLocked(boolean oldScreenOn, boolean newScreenOn) { 8948 if (oldScreenOn) { 8949 int diff = mDischargeScreenOnUnplugLevel - mDischargeCurrentLevel; 8950 if (diff > 0) { 8951 mDischargeAmountScreenOn += diff; 8952 mDischargeAmountScreenOnSinceCharge += diff; 8953 } 8954 } else { 8955 int diff = mDischargeScreenOffUnplugLevel - mDischargeCurrentLevel; 8956 if (diff > 0) { 8957 mDischargeAmountScreenOff += diff; 8958 mDischargeAmountScreenOffSinceCharge += diff; 8959 } 8960 } 8961 if (newScreenOn) { 8962 mDischargeScreenOnUnplugLevel = mDischargeCurrentLevel; 8963 mDischargeScreenOffUnplugLevel = 0; 8964 } else { 8965 mDischargeScreenOnUnplugLevel = 0; 8966 mDischargeScreenOffUnplugLevel = mDischargeCurrentLevel; 8967 } 8968 } 8969 8970 public void pullPendingStateUpdatesLocked() { 8971 if (mOnBatteryInternal) { 8972 final boolean screenOn = mScreenState == Display.STATE_ON; 8973 updateDischargeScreenLevelsLocked(screenOn, screenOn); 8974 } 8975 } 8976 8977 private String[] mMobileIfaces = EmptyArray.STRING; 8978 private String[] mWifiIfaces = EmptyArray.STRING; 8979 8980 private final NetworkStatsFactory mNetworkStatsFactory = new NetworkStatsFactory(); 8981 8982 private static final int NETWORK_STATS_LAST = 0; 8983 private static final int NETWORK_STATS_NEXT = 1; 8984 private static final int NETWORK_STATS_DELTA = 2; 8985 8986 private NetworkStats[] mMobileNetworkStats; 8987 private NetworkStats[] mWifiNetworkStats; 8988 8989 /** 8990 * Retrieves the delta of network stats for the given network ifaces. Uses networkStatsBuffer 8991 * as a buffer of NetworkStats objects to cycle through when computing deltas. 8992 */ 8993 private NetworkStats getNetworkStatsDeltaLocked(String[] ifaces, 8994 NetworkStats[] networkStatsBuffer) 8995 throws IOException { 8996 if (!SystemProperties.getBoolean(NetworkManagementSocketTagger.PROP_QTAGUID_ENABLED, 8997 false)) { 8998 return null; 8999 } 9000 9001 final NetworkStats stats = mNetworkStatsFactory.readNetworkStatsDetail(NetworkStats.UID_ALL, 9002 ifaces, NetworkStats.TAG_NONE, networkStatsBuffer[NETWORK_STATS_NEXT]); 9003 networkStatsBuffer[NETWORK_STATS_DELTA] = NetworkStats.subtract(stats, 9004 networkStatsBuffer[NETWORK_STATS_LAST], null, null, 9005 networkStatsBuffer[NETWORK_STATS_DELTA]); 9006 networkStatsBuffer[NETWORK_STATS_NEXT] = networkStatsBuffer[NETWORK_STATS_LAST]; 9007 networkStatsBuffer[NETWORK_STATS_LAST] = stats; 9008 return networkStatsBuffer[NETWORK_STATS_DELTA]; 9009 } 9010 9011 /** 9012 * Distribute WiFi energy info and network traffic to apps. 9013 * @param info The energy information from the WiFi controller. 9014 */ 9015 public void updateWifiStateLocked(@Nullable final WifiActivityEnergyInfo info) { 9016 if (DEBUG_ENERGY) { 9017 Slog.d(TAG, "Updating wifi stats"); 9018 } 9019 9020 final long elapsedRealtimeMs = mClocks.elapsedRealtime(); 9021 NetworkStats delta = null; 9022 try { 9023 if (!ArrayUtils.isEmpty(mWifiIfaces)) { 9024 delta = getNetworkStatsDeltaLocked(mWifiIfaces, mWifiNetworkStats); 9025 } 9026 } catch (IOException e) { 9027 Slog.wtf(TAG, "Failed to get wifi network stats", e); 9028 return; 9029 } 9030 9031 if (!mOnBatteryInternal) { 9032 return; 9033 } 9034 9035 SparseLongArray rxPackets = new SparseLongArray(); 9036 SparseLongArray txPackets = new SparseLongArray(); 9037 long totalTxPackets = 0; 9038 long totalRxPackets = 0; 9039 if (delta != null) { 9040 final int size = delta.size(); 9041 for (int i = 0; i < size; i++) { 9042 final NetworkStats.Entry entry = delta.getValues(i, mTmpNetworkStatsEntry); 9043 9044 if (DEBUG_ENERGY) { 9045 Slog.d(TAG, "Wifi uid " + entry.uid + ": delta rx=" + entry.rxBytes 9046 + " tx=" + entry.txBytes + " rxPackets=" + entry.rxPackets 9047 + " txPackets=" + entry.txPackets); 9048 } 9049 9050 if (entry.rxBytes == 0 && entry.txBytes == 0) { 9051 // Skip the lookup below since there is no work to do. 9052 continue; 9053 } 9054 9055 final Uid u = getUidStatsLocked(mapUid(entry.uid)); 9056 if (entry.rxBytes != 0) { 9057 u.noteNetworkActivityLocked(NETWORK_WIFI_RX_DATA, entry.rxBytes, 9058 entry.rxPackets); 9059 if (entry.set == NetworkStats.SET_DEFAULT) { // Background transfers 9060 u.noteNetworkActivityLocked(NETWORK_WIFI_BG_RX_DATA, entry.rxBytes, 9061 entry.rxPackets); 9062 } 9063 mNetworkByteActivityCounters[NETWORK_WIFI_RX_DATA].addCountLocked( 9064 entry.rxBytes); 9065 mNetworkPacketActivityCounters[NETWORK_WIFI_RX_DATA].addCountLocked( 9066 entry.rxPackets); 9067 9068 rxPackets.put(u.getUid(), entry.rxPackets); 9069 9070 // Sum the total number of packets so that the Rx Power can 9071 // be evenly distributed amongst the apps. 9072 totalRxPackets += entry.rxPackets; 9073 } 9074 9075 if (entry.txBytes != 0) { 9076 u.noteNetworkActivityLocked(NETWORK_WIFI_TX_DATA, entry.txBytes, 9077 entry.txPackets); 9078 if (entry.set == NetworkStats.SET_DEFAULT) { // Background transfers 9079 u.noteNetworkActivityLocked(NETWORK_WIFI_BG_TX_DATA, entry.txBytes, 9080 entry.txPackets); 9081 } 9082 mNetworkByteActivityCounters[NETWORK_WIFI_TX_DATA].addCountLocked( 9083 entry.txBytes); 9084 mNetworkPacketActivityCounters[NETWORK_WIFI_TX_DATA].addCountLocked( 9085 entry.txPackets); 9086 9087 txPackets.put(u.getUid(), entry.txPackets); 9088 9089 // Sum the total number of packets so that the Tx Power can 9090 // be evenly distributed amongst the apps. 9091 totalTxPackets += entry.txPackets; 9092 } 9093 } 9094 } 9095 9096 if (info != null) { 9097 mHasWifiReporting = true; 9098 9099 // Measured in mAms 9100 final long txTimeMs = info.getControllerTxTimeMillis(); 9101 final long rxTimeMs = info.getControllerRxTimeMillis(); 9102 final long idleTimeMs = info.getControllerIdleTimeMillis(); 9103 final long totalTimeMs = txTimeMs + rxTimeMs + idleTimeMs; 9104 9105 long leftOverRxTimeMs = rxTimeMs; 9106 long leftOverTxTimeMs = txTimeMs; 9107 9108 if (DEBUG_ENERGY) { 9109 Slog.d(TAG, "------ BEGIN WiFi power blaming ------"); 9110 Slog.d(TAG, " Tx Time: " + txTimeMs + " ms"); 9111 Slog.d(TAG, " Rx Time: " + rxTimeMs + " ms"); 9112 Slog.d(TAG, " Idle Time: " + idleTimeMs + " ms"); 9113 Slog.d(TAG, " Total Time: " + totalTimeMs + " ms"); 9114 } 9115 9116 long totalWifiLockTimeMs = 0; 9117 long totalScanTimeMs = 0; 9118 9119 // On the first pass, collect some totals so that we can normalize power 9120 // calculations if we need to. 9121 final int uidStatsSize = mUidStats.size(); 9122 for (int i = 0; i < uidStatsSize; i++) { 9123 final Uid uid = mUidStats.valueAt(i); 9124 9125 // Sum the total scan power for all apps. 9126 totalScanTimeMs += uid.mWifiScanTimer.getTimeSinceMarkLocked( 9127 elapsedRealtimeMs * 1000) / 1000; 9128 9129 // Sum the total time holding wifi lock for all apps. 9130 totalWifiLockTimeMs += uid.mFullWifiLockTimer.getTimeSinceMarkLocked( 9131 elapsedRealtimeMs * 1000) / 1000; 9132 } 9133 9134 if (DEBUG_ENERGY && totalScanTimeMs > rxTimeMs) { 9135 Slog.d(TAG, " !Estimated scan time > Actual rx time (" + totalScanTimeMs + " ms > " 9136 + rxTimeMs + " ms). Normalizing scan time."); 9137 } 9138 if (DEBUG_ENERGY && totalScanTimeMs > txTimeMs) { 9139 Slog.d(TAG, " !Estimated scan time > Actual tx time (" + totalScanTimeMs + " ms > " 9140 + txTimeMs + " ms). Normalizing scan time."); 9141 } 9142 9143 // Actually assign and distribute power usage to apps. 9144 for (int i = 0; i < uidStatsSize; i++) { 9145 final Uid uid = mUidStats.valueAt(i); 9146 9147 long scanTimeSinceMarkMs = uid.mWifiScanTimer.getTimeSinceMarkLocked( 9148 elapsedRealtimeMs * 1000) / 1000; 9149 if (scanTimeSinceMarkMs > 0) { 9150 // Set the new mark so that next time we get new data since this point. 9151 uid.mWifiScanTimer.setMark(elapsedRealtimeMs); 9152 9153 long scanRxTimeSinceMarkMs = scanTimeSinceMarkMs; 9154 long scanTxTimeSinceMarkMs = scanTimeSinceMarkMs; 9155 9156 // Our total scan time is more than the reported Tx/Rx time. 9157 // This is possible because the cost of a scan is approximate. 9158 // Let's normalize the result so that we evenly blame each app 9159 // scanning. 9160 // 9161 // This means that we may have apps that transmitted/received packets not be 9162 // blamed for this, but this is fine as scans are relatively more expensive. 9163 if (totalScanTimeMs > rxTimeMs) { 9164 scanRxTimeSinceMarkMs = (rxTimeMs * scanRxTimeSinceMarkMs) / 9165 totalScanTimeMs; 9166 } 9167 if (totalScanTimeMs > txTimeMs) { 9168 scanTxTimeSinceMarkMs = (txTimeMs * scanTxTimeSinceMarkMs) / 9169 totalScanTimeMs; 9170 } 9171 9172 if (DEBUG_ENERGY) { 9173 Slog.d(TAG, " ScanTime for UID " + uid.getUid() + ": Rx:" 9174 + scanRxTimeSinceMarkMs + " ms Tx:" 9175 + scanTxTimeSinceMarkMs + " ms)"); 9176 } 9177 9178 ControllerActivityCounterImpl activityCounter = 9179 uid.getOrCreateWifiControllerActivityLocked(); 9180 activityCounter.getRxTimeCounter().addCountLocked(scanRxTimeSinceMarkMs); 9181 activityCounter.getTxTimeCounters()[0].addCountLocked(scanTxTimeSinceMarkMs); 9182 leftOverRxTimeMs -= scanRxTimeSinceMarkMs; 9183 leftOverTxTimeMs -= scanTxTimeSinceMarkMs; 9184 } 9185 9186 // Distribute evenly the power consumed while Idle to each app holding a WiFi 9187 // lock. 9188 final long wifiLockTimeSinceMarkMs = uid.mFullWifiLockTimer.getTimeSinceMarkLocked( 9189 elapsedRealtimeMs * 1000) / 1000; 9190 if (wifiLockTimeSinceMarkMs > 0) { 9191 // Set the new mark so that next time we get new data since this point. 9192 uid.mFullWifiLockTimer.setMark(elapsedRealtimeMs); 9193 9194 final long myIdleTimeMs = (wifiLockTimeSinceMarkMs * idleTimeMs) 9195 / totalWifiLockTimeMs; 9196 if (DEBUG_ENERGY) { 9197 Slog.d(TAG, " IdleTime for UID " + uid.getUid() + ": " 9198 + myIdleTimeMs + " ms"); 9199 } 9200 uid.getOrCreateWifiControllerActivityLocked().getIdleTimeCounter() 9201 .addCountLocked(myIdleTimeMs); 9202 } 9203 } 9204 9205 if (DEBUG_ENERGY) { 9206 Slog.d(TAG, " New RxPower: " + leftOverRxTimeMs + " ms"); 9207 Slog.d(TAG, " New TxPower: " + leftOverTxTimeMs + " ms"); 9208 } 9209 9210 // Distribute the remaining Tx power appropriately between all apps that transmitted 9211 // packets. 9212 for (int i = 0; i < txPackets.size(); i++) { 9213 final Uid uid = getUidStatsLocked(txPackets.keyAt(i)); 9214 final long myTxTimeMs = (txPackets.valueAt(i) * leftOverTxTimeMs) / totalTxPackets; 9215 if (DEBUG_ENERGY) { 9216 Slog.d(TAG, " TxTime for UID " + uid.getUid() + ": " + myTxTimeMs + " ms"); 9217 } 9218 uid.getOrCreateWifiControllerActivityLocked().getTxTimeCounters()[0] 9219 .addCountLocked(myTxTimeMs); 9220 } 9221 9222 // Distribute the remaining Rx power appropriately between all apps that received 9223 // packets. 9224 for (int i = 0; i < rxPackets.size(); i++) { 9225 final Uid uid = getUidStatsLocked(rxPackets.keyAt(i)); 9226 final long myRxTimeMs = (rxPackets.valueAt(i) * leftOverRxTimeMs) / totalRxPackets; 9227 if (DEBUG_ENERGY) { 9228 Slog.d(TAG, " RxTime for UID " + uid.getUid() + ": " + myRxTimeMs + " ms"); 9229 } 9230 uid.getOrCreateWifiControllerActivityLocked().getRxTimeCounter() 9231 .addCountLocked(myRxTimeMs); 9232 } 9233 9234 // Any left over power use will be picked up by the WiFi category in BatteryStatsHelper. 9235 9236 // Update WiFi controller stats. 9237 mWifiActivity.getRxTimeCounter().addCountLocked(info.getControllerRxTimeMillis()); 9238 mWifiActivity.getTxTimeCounters()[0].addCountLocked(info.getControllerTxTimeMillis()); 9239 mWifiActivity.getIdleTimeCounter().addCountLocked(info.getControllerIdleTimeMillis()); 9240 9241 // POWER_WIFI_CONTROLLER_OPERATING_VOLTAGE is measured in mV, so convert to V. 9242 final double opVolt = mPowerProfile.getAveragePower( 9243 PowerProfile.POWER_WIFI_CONTROLLER_OPERATING_VOLTAGE) / 1000.0; 9244 if (opVolt != 0) { 9245 // We store the power drain as mAms. 9246 mWifiActivity.getPowerCounter().addCountLocked( 9247 (long)(info.getControllerEnergyUsed() / opVolt)); 9248 } 9249 } 9250 } 9251 9252 /** 9253 * Distribute Cell radio energy info and network traffic to apps. 9254 */ 9255 public void updateMobileRadioStateLocked(final long elapsedRealtimeMs, 9256 final ModemActivityInfo activityInfo) { 9257 if (DEBUG_ENERGY) { 9258 Slog.d(TAG, "Updating mobile radio stats with " + activityInfo); 9259 } 9260 9261 NetworkStats delta = null; 9262 try { 9263 if (!ArrayUtils.isEmpty(mMobileIfaces)) { 9264 delta = getNetworkStatsDeltaLocked(mMobileIfaces, mMobileNetworkStats); 9265 } 9266 } catch (IOException e) { 9267 Slog.wtf(TAG, "Failed to get mobile network stats", e); 9268 return; 9269 } 9270 9271 if (!mOnBatteryInternal) { 9272 return; 9273 } 9274 9275 long radioTime = mMobileRadioActivePerAppTimer.getTimeSinceMarkLocked( 9276 elapsedRealtimeMs * 1000); 9277 mMobileRadioActivePerAppTimer.setMark(elapsedRealtimeMs); 9278 9279 long totalRxPackets = 0; 9280 long totalTxPackets = 0; 9281 if (delta != null) { 9282 final int size = delta.size(); 9283 for (int i = 0; i < size; i++) { 9284 final NetworkStats.Entry entry = delta.getValues(i, mTmpNetworkStatsEntry); 9285 if (entry.rxPackets == 0 && entry.txPackets == 0) { 9286 continue; 9287 } 9288 9289 if (DEBUG_ENERGY) { 9290 Slog.d(TAG, "Mobile uid " + entry.uid + ": delta rx=" + entry.rxBytes 9291 + " tx=" + entry.txBytes + " rxPackets=" + entry.rxPackets 9292 + " txPackets=" + entry.txPackets); 9293 } 9294 9295 totalRxPackets += entry.rxPackets; 9296 totalTxPackets += entry.txPackets; 9297 9298 final Uid u = getUidStatsLocked(mapUid(entry.uid)); 9299 u.noteNetworkActivityLocked(NETWORK_MOBILE_RX_DATA, entry.rxBytes, entry.rxPackets); 9300 u.noteNetworkActivityLocked(NETWORK_MOBILE_TX_DATA, entry.txBytes, entry.txPackets); 9301 if (entry.set == NetworkStats.SET_DEFAULT) { // Background transfers 9302 u.noteNetworkActivityLocked(NETWORK_MOBILE_BG_RX_DATA, 9303 entry.rxBytes, entry.rxPackets); 9304 u.noteNetworkActivityLocked(NETWORK_MOBILE_BG_TX_DATA, 9305 entry.txBytes, entry.txPackets); 9306 } 9307 9308 mNetworkByteActivityCounters[NETWORK_MOBILE_RX_DATA].addCountLocked( 9309 entry.rxBytes); 9310 mNetworkByteActivityCounters[NETWORK_MOBILE_TX_DATA].addCountLocked( 9311 entry.txBytes); 9312 mNetworkPacketActivityCounters[NETWORK_MOBILE_RX_DATA].addCountLocked( 9313 entry.rxPackets); 9314 mNetworkPacketActivityCounters[NETWORK_MOBILE_TX_DATA].addCountLocked( 9315 entry.txPackets); 9316 } 9317 9318 // Now distribute proportional blame to the apps that did networking. 9319 long totalPackets = totalRxPackets + totalTxPackets; 9320 if (totalPackets > 0) { 9321 for (int i = 0; i < size; i++) { 9322 final NetworkStats.Entry entry = delta.getValues(i, mTmpNetworkStatsEntry); 9323 if (entry.rxPackets == 0 && entry.txPackets == 0) { 9324 continue; 9325 } 9326 9327 final Uid u = getUidStatsLocked(mapUid(entry.uid)); 9328 9329 // Distribute total radio active time in to this app. 9330 final long appPackets = entry.rxPackets + entry.txPackets; 9331 final long appRadioTime = (radioTime * appPackets) / totalPackets; 9332 u.noteMobileRadioActiveTimeLocked(appRadioTime); 9333 9334 // Remove this app from the totals, so that we don't lose any time 9335 // due to rounding. 9336 radioTime -= appRadioTime; 9337 totalPackets -= appPackets; 9338 9339 if (activityInfo != null) { 9340 ControllerActivityCounterImpl activityCounter = 9341 u.getOrCreateModemControllerActivityLocked(); 9342 if (totalRxPackets > 0 && entry.rxPackets > 0) { 9343 final long rxMs = (entry.rxPackets * activityInfo.getRxTimeMillis()) 9344 / totalRxPackets; 9345 activityCounter.getRxTimeCounter().addCountLocked(rxMs); 9346 } 9347 9348 if (totalTxPackets > 0 && entry.txPackets > 0) { 9349 for (int lvl = 0; lvl < ModemActivityInfo.TX_POWER_LEVELS; lvl++) { 9350 long txMs = entry.txPackets * activityInfo.getTxTimeMillis()[lvl]; 9351 txMs /= totalTxPackets; 9352 activityCounter.getTxTimeCounters()[lvl].addCountLocked(txMs); 9353 } 9354 } 9355 } 9356 } 9357 } 9358 9359 if (radioTime > 0) { 9360 // Whoops, there is some radio time we can't blame on an app! 9361 mMobileRadioActiveUnknownTime.addCountLocked(radioTime); 9362 mMobileRadioActiveUnknownCount.addCountLocked(1); 9363 } 9364 } 9365 9366 if (activityInfo != null) { 9367 mHasModemReporting = true; 9368 mModemActivity.getIdleTimeCounter().addCountLocked(activityInfo.getIdleTimeMillis()); 9369 mModemActivity.getRxTimeCounter().addCountLocked(activityInfo.getRxTimeMillis()); 9370 for (int lvl = 0; lvl < ModemActivityInfo.TX_POWER_LEVELS; lvl++) { 9371 mModemActivity.getTxTimeCounters()[lvl] 9372 .addCountLocked(activityInfo.getTxTimeMillis()[lvl]); 9373 } 9374 9375 // POWER_MODEM_CONTROLLER_OPERATING_VOLTAGE is measured in mV, so convert to V. 9376 final double opVolt = mPowerProfile.getAveragePower( 9377 PowerProfile.POWER_MODEM_CONTROLLER_OPERATING_VOLTAGE) / 1000.0; 9378 if (opVolt != 0) { 9379 // We store the power drain as mAms. 9380 mModemActivity.getPowerCounter().addCountLocked( 9381 (long) (activityInfo.getEnergyUsed() / opVolt)); 9382 } 9383 } 9384 } 9385 9386 /** 9387 * Distribute Bluetooth energy info and network traffic to apps. 9388 * @param info The energy information from the bluetooth controller. 9389 */ 9390 public void updateBluetoothStateLocked(@Nullable final BluetoothActivityEnergyInfo info) { 9391 if (DEBUG_ENERGY) { 9392 Slog.d(TAG, "Updating bluetooth stats: " + info); 9393 } 9394 9395 if (info == null || !mOnBatteryInternal) { 9396 return; 9397 } 9398 9399 mHasBluetoothReporting = true; 9400 9401 final long elapsedRealtimeMs = mClocks.elapsedRealtime(); 9402 final long rxTimeMs = info.getControllerRxTimeMillis(); 9403 final long txTimeMs = info.getControllerTxTimeMillis(); 9404 9405 if (DEBUG_ENERGY) { 9406 Slog.d(TAG, "------ BEGIN BLE power blaming ------"); 9407 Slog.d(TAG, " Tx Time: " + txTimeMs + " ms"); 9408 Slog.d(TAG, " Rx Time: " + rxTimeMs + " ms"); 9409 Slog.d(TAG, " Idle Time: " + info.getControllerIdleTimeMillis() + " ms"); 9410 } 9411 9412 long totalScanTimeMs = 0; 9413 9414 final int uidCount = mUidStats.size(); 9415 for (int i = 0; i < uidCount; i++) { 9416 final Uid u = mUidStats.valueAt(i); 9417 if (u.mBluetoothScanTimer == null) { 9418 continue; 9419 } 9420 9421 totalScanTimeMs += u.mBluetoothScanTimer.getTimeSinceMarkLocked( 9422 elapsedRealtimeMs * 1000) / 1000; 9423 } 9424 9425 final boolean normalizeScanRxTime = (totalScanTimeMs > rxTimeMs); 9426 final boolean normalizeScanTxTime = (totalScanTimeMs > txTimeMs); 9427 9428 if (DEBUG_ENERGY) { 9429 Slog.d(TAG, "Normalizing scan power for RX=" + normalizeScanRxTime 9430 + " TX=" + normalizeScanTxTime); 9431 } 9432 9433 long leftOverRxTimeMs = rxTimeMs; 9434 long leftOverTxTimeMs = txTimeMs; 9435 9436 for (int i = 0; i < uidCount; i++) { 9437 final Uid u = mUidStats.valueAt(i); 9438 if (u.mBluetoothScanTimer == null) { 9439 continue; 9440 } 9441 9442 long scanTimeSinceMarkMs = u.mBluetoothScanTimer.getTimeSinceMarkLocked( 9443 elapsedRealtimeMs * 1000) / 1000; 9444 if (scanTimeSinceMarkMs > 0) { 9445 // Set the new mark so that next time we get new data since this point. 9446 u.mBluetoothScanTimer.setMark(elapsedRealtimeMs); 9447 9448 long scanTimeRxSinceMarkMs = scanTimeSinceMarkMs; 9449 long scanTimeTxSinceMarkMs = scanTimeSinceMarkMs; 9450 9451 if (normalizeScanRxTime) { 9452 // Scan time is longer than the total rx time in the controller, 9453 // so distribute the scan time proportionately. This means regular traffic 9454 // will not blamed, but scans are more expensive anyways. 9455 scanTimeRxSinceMarkMs = (rxTimeMs * scanTimeRxSinceMarkMs) / totalScanTimeMs; 9456 } 9457 9458 if (normalizeScanTxTime) { 9459 // Scan time is longer than the total tx time in the controller, 9460 // so distribute the scan time proportionately. This means regular traffic 9461 // will not blamed, but scans are more expensive anyways. 9462 scanTimeTxSinceMarkMs = (txTimeMs * scanTimeTxSinceMarkMs) / totalScanTimeMs; 9463 } 9464 9465 final ControllerActivityCounterImpl counter = 9466 u.getOrCreateBluetoothControllerActivityLocked(); 9467 counter.getRxTimeCounter().addCountLocked(scanTimeRxSinceMarkMs); 9468 counter.getTxTimeCounters()[0].addCountLocked(scanTimeTxSinceMarkMs); 9469 9470 leftOverRxTimeMs -= scanTimeRxSinceMarkMs; 9471 leftOverTxTimeMs -= scanTimeTxSinceMarkMs; 9472 } 9473 } 9474 9475 if (DEBUG_ENERGY) { 9476 Slog.d(TAG, "Left over time for traffic RX=" + leftOverRxTimeMs 9477 + " TX=" + leftOverTxTimeMs); 9478 } 9479 9480 // 9481 // Now distribute blame to apps that did bluetooth traffic. 9482 // 9483 9484 long totalTxBytes = 0; 9485 long totalRxBytes = 0; 9486 9487 final UidTraffic[] uidTraffic = info.getUidTraffic(); 9488 final int numUids = uidTraffic != null ? uidTraffic.length : 0; 9489 for (int i = 0; i < numUids; i++) { 9490 final UidTraffic traffic = uidTraffic[i]; 9491 9492 // Add to the global counters. 9493 mNetworkByteActivityCounters[NETWORK_BT_RX_DATA].addCountLocked( 9494 traffic.getRxBytes()); 9495 mNetworkByteActivityCounters[NETWORK_BT_TX_DATA].addCountLocked( 9496 traffic.getTxBytes()); 9497 9498 // Add to the UID counters. 9499 final Uid u = getUidStatsLocked(mapUid(traffic.getUid())); 9500 u.noteNetworkActivityLocked(NETWORK_BT_RX_DATA, traffic.getRxBytes(), 0); 9501 u.noteNetworkActivityLocked(NETWORK_BT_TX_DATA, traffic.getTxBytes(), 0); 9502 9503 // Calculate the total traffic. 9504 totalTxBytes += traffic.getTxBytes(); 9505 totalRxBytes += traffic.getRxBytes(); 9506 } 9507 9508 if ((totalTxBytes != 0 || totalRxBytes != 0) && 9509 (leftOverRxTimeMs != 0 || leftOverTxTimeMs != 0)) { 9510 for (int i = 0; i < numUids; i++) { 9511 final UidTraffic traffic = uidTraffic[i]; 9512 9513 final Uid u = getUidStatsLocked(mapUid(traffic.getUid())); 9514 final ControllerActivityCounterImpl counter = 9515 u.getOrCreateBluetoothControllerActivityLocked(); 9516 9517 if (totalRxBytes > 0 && traffic.getRxBytes() > 0) { 9518 final long timeRxMs = (leftOverRxTimeMs * traffic.getRxBytes()) / totalRxBytes; 9519 9520 if (DEBUG_ENERGY) { 9521 Slog.d(TAG, "UID=" + traffic.getUid() + " rx_bytes=" + traffic.getRxBytes() 9522 + " rx_time=" + timeRxMs); 9523 } 9524 counter.getRxTimeCounter().addCountLocked(timeRxMs); 9525 leftOverRxTimeMs -= timeRxMs; 9526 } 9527 9528 if (totalTxBytes > 0 && traffic.getTxBytes() > 0) { 9529 final long timeTxMs = (leftOverTxTimeMs * traffic.getTxBytes()) / totalTxBytes; 9530 9531 if (DEBUG_ENERGY) { 9532 Slog.d(TAG, "UID=" + traffic.getUid() + " tx_bytes=" + traffic.getTxBytes() 9533 + " tx_time=" + timeTxMs); 9534 } 9535 9536 counter.getTxTimeCounters()[0].addCountLocked(timeTxMs); 9537 leftOverTxTimeMs -= timeTxMs; 9538 } 9539 } 9540 } 9541 9542 mBluetoothActivity.getRxTimeCounter().addCountLocked( 9543 info.getControllerRxTimeMillis()); 9544 mBluetoothActivity.getTxTimeCounters()[0].addCountLocked( 9545 info.getControllerTxTimeMillis()); 9546 mBluetoothActivity.getIdleTimeCounter().addCountLocked( 9547 info.getControllerIdleTimeMillis()); 9548 9549 // POWER_BLUETOOTH_CONTROLLER_OPERATING_VOLTAGE is measured in mV, so convert to V. 9550 final double opVolt = mPowerProfile.getAveragePower( 9551 PowerProfile.POWER_BLUETOOTH_CONTROLLER_OPERATING_VOLTAGE) / 1000.0; 9552 if (opVolt != 0) { 9553 // We store the power drain as mAms. 9554 mBluetoothActivity.getPowerCounter().addCountLocked( 9555 (long) (info.getControllerEnergyUsed() / opVolt)); 9556 } 9557 } 9558 9559 /** 9560 * Read and distribute kernel wake lock use across apps. 9561 */ 9562 public void updateKernelWakelocksLocked() { 9563 final KernelWakelockStats wakelockStats = mKernelWakelockReader.readKernelWakelockStats( 9564 mTmpWakelockStats); 9565 if (wakelockStats == null) { 9566 // Not crashing might make board bringup easier. 9567 Slog.w(TAG, "Couldn't get kernel wake lock stats"); 9568 return; 9569 } 9570 9571 for (Map.Entry<String, KernelWakelockStats.Entry> ent : wakelockStats.entrySet()) { 9572 String name = ent.getKey(); 9573 KernelWakelockStats.Entry kws = ent.getValue(); 9574 9575 SamplingTimer kwlt = mKernelWakelockStats.get(name); 9576 if (kwlt == null) { 9577 kwlt = new SamplingTimer(mClocks, mOnBatteryScreenOffTimeBase); 9578 mKernelWakelockStats.put(name, kwlt); 9579 } 9580 9581 kwlt.update(kws.mTotalTime, kws.mCount); 9582 kwlt.setUpdateVersion(kws.mVersion); 9583 } 9584 9585 int numWakelocksSetStale = 0; 9586 // Set timers to stale if they didn't appear in /d/wakeup_sources (or /proc/wakelocks) 9587 // this time. 9588 for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) { 9589 SamplingTimer st = ent.getValue(); 9590 if (st.getUpdateVersion() != wakelockStats.kernelWakelockVersion) { 9591 st.endSample(); 9592 numWakelocksSetStale++; 9593 } 9594 } 9595 9596 // Record whether we've seen a non-zero time (for debugging b/22716723). 9597 if (wakelockStats.isEmpty()) { 9598 Slog.wtf(TAG, "All kernel wakelocks had time of zero"); 9599 } 9600 9601 if (numWakelocksSetStale == mKernelWakelockStats.size()) { 9602 Slog.wtf(TAG, "All kernel wakelocks were set stale. new version=" + 9603 wakelockStats.kernelWakelockVersion); 9604 } 9605 } 9606 9607 // We use an anonymous class to access these variables, 9608 // so they can't live on the stack or they'd have to be 9609 // final MutableLong objects (more allocations). 9610 // Used in updateCpuTimeLocked(). 9611 long mTempTotalCpuUserTimeUs; 9612 long mTempTotalCpuSystemTimeUs; 9613 9614 /** 9615 * Reads the newest memory stats from the kernel. 9616 */ 9617 public void updateKernelMemoryBandwidthLocked() { 9618 mKernelMemoryBandwidthStats.updateStats(); 9619 LongSparseLongArray bandwidthEntries = mKernelMemoryBandwidthStats.getBandwidthEntries(); 9620 final int bandwidthEntryCount = bandwidthEntries.size(); 9621 int index; 9622 for (int i = 0; i < bandwidthEntryCount; i++) { 9623 SamplingTimer timer; 9624 if ((index = mKernelMemoryStats.indexOfKey(bandwidthEntries.keyAt(i))) >= 0) { 9625 timer = mKernelMemoryStats.valueAt(index); 9626 } else { 9627 timer = new SamplingTimer(mClocks, mOnBatteryTimeBase); 9628 mKernelMemoryStats.put(bandwidthEntries.keyAt(i), timer); 9629 } 9630 timer.update(bandwidthEntries.valueAt(i), 1); 9631 if (DEBUG_MEMORY) { 9632 Slog.d(TAG, String.format("Added entry %d and updated timer to: " 9633 + "mUnpluggedReportedTotalTime %d size %d", bandwidthEntries.keyAt(i), 9634 mKernelMemoryStats.get( 9635 bandwidthEntries.keyAt(i)).mUnpluggedReportedTotalTime, 9636 mKernelMemoryStats.size())); 9637 } 9638 } 9639 } 9640 9641 /** 9642 * Read and distribute CPU usage across apps. If their are partial wakelocks being held 9643 * and we are on battery with screen off, we give more of the cpu time to those apps holding 9644 * wakelocks. If the screen is on, we just assign the actual cpu time an app used. 9645 */ 9646 public void updateCpuTimeLocked() { 9647 if (mPowerProfile == null) { 9648 return; 9649 } 9650 9651 if (DEBUG_ENERGY_CPU) { 9652 Slog.d(TAG, "!Cpu updating!"); 9653 } 9654 9655 // Holding a wakelock costs more than just using the cpu. 9656 // Currently, we assign only half the cpu time to an app that is running but 9657 // not holding a wakelock. The apps holding wakelocks get the rest of the blame. 9658 // If no app is holding a wakelock, then the distribution is normal. 9659 final int wakelockWeight = 50; 9660 9661 // Read the time spent for each cluster at various cpu frequencies. 9662 final long[][] clusterSpeeds = new long[mKernelCpuSpeedReaders.length][]; 9663 for (int cluster = 0; cluster < mKernelCpuSpeedReaders.length; cluster++) { 9664 clusterSpeeds[cluster] = mKernelCpuSpeedReaders[cluster].readDelta(); 9665 } 9666 9667 int numWakelocks = 0; 9668 9669 // Calculate how many wakelocks we have to distribute amongst. The system is excluded. 9670 // Only distribute cpu power to wakelocks if the screen is off and we're on battery. 9671 final int numPartialTimers = mPartialTimers.size(); 9672 if (mOnBatteryScreenOffTimeBase.isRunning()) { 9673 for (int i = 0; i < numPartialTimers; i++) { 9674 final StopwatchTimer timer = mPartialTimers.get(i); 9675 if (timer.mInList && timer.mUid != null && timer.mUid.mUid != Process.SYSTEM_UID) { 9676 // Since the collection and blaming of wakelocks can be scheduled to run after 9677 // some delay, the mPartialTimers list may have new entries. We can't blame 9678 // the newly added timer for past cpu time, so we only consider timers that 9679 // were present for one round of collection. Once a timer has gone through 9680 // a round of collection, its mInList field is set to true. 9681 numWakelocks++; 9682 } 9683 } 9684 } 9685 9686 final int numWakelocksF = numWakelocks; 9687 mTempTotalCpuUserTimeUs = 0; 9688 mTempTotalCpuSystemTimeUs = 0; 9689 9690 // Read the CPU data for each UID. This will internally generate a snapshot so next time 9691 // we read, we get a delta. If we are to distribute the cpu time, then do so. Otherwise 9692 // we just ignore the data. 9693 final long startTimeMs = mClocks.elapsedRealtime(); 9694 mKernelUidCpuTimeReader.readDelta(!mOnBatteryInternal ? null : 9695 new KernelUidCpuTimeReader.Callback() { 9696 @Override 9697 public void onUidCpuTime(int uid, long userTimeUs, long systemTimeUs) { 9698 final Uid u = getUidStatsLocked(mapUid(uid)); 9699 9700 // Accumulate the total system and user time. 9701 mTempTotalCpuUserTimeUs += userTimeUs; 9702 mTempTotalCpuSystemTimeUs += systemTimeUs; 9703 9704 StringBuilder sb = null; 9705 if (DEBUG_ENERGY_CPU) { 9706 sb = new StringBuilder(); 9707 sb.append(" got time for uid=").append(u.mUid).append(": u="); 9708 TimeUtils.formatDuration(userTimeUs / 1000, sb); 9709 sb.append(" s="); 9710 TimeUtils.formatDuration(systemTimeUs / 1000, sb); 9711 sb.append("\n"); 9712 } 9713 9714 if (numWakelocksF > 0) { 9715 // We have wakelocks being held, so only give a portion of the 9716 // time to the process. The rest will be distributed among wakelock 9717 // holders. 9718 userTimeUs = (userTimeUs * wakelockWeight) / 100; 9719 systemTimeUs = (systemTimeUs * wakelockWeight) / 100; 9720 } 9721 9722 if (sb != null) { 9723 sb.append(" adding to uid=").append(u.mUid).append(": u="); 9724 TimeUtils.formatDuration(userTimeUs / 1000, sb); 9725 sb.append(" s="); 9726 TimeUtils.formatDuration(systemTimeUs / 1000, sb); 9727 Slog.d(TAG, sb.toString()); 9728 } 9729 9730 u.mUserCpuTime.addCountLocked(userTimeUs); 9731 u.mSystemCpuTime.addCountLocked(systemTimeUs); 9732 9733 // Add the cpu speeds to this UID. These are used as a ratio 9734 // for computing the power this UID used. 9735 final int numClusters = mPowerProfile.getNumCpuClusters(); 9736 if (u.mCpuClusterSpeed == null || u.mCpuClusterSpeed.length != 9737 numClusters) { 9738 u.mCpuClusterSpeed = new LongSamplingCounter[numClusters][]; 9739 } 9740 9741 for (int cluster = 0; cluster < clusterSpeeds.length; cluster++) { 9742 final int speedsInCluster = mPowerProfile.getNumSpeedStepsInCpuCluster( 9743 cluster); 9744 if (u.mCpuClusterSpeed[cluster] == null || speedsInCluster != 9745 u.mCpuClusterSpeed[cluster].length) { 9746 u.mCpuClusterSpeed[cluster] = 9747 new LongSamplingCounter[speedsInCluster]; 9748 } 9749 9750 final LongSamplingCounter[] cpuSpeeds = u.mCpuClusterSpeed[cluster]; 9751 for (int speed = 0; speed < clusterSpeeds[cluster].length; speed++) { 9752 if (cpuSpeeds[speed] == null) { 9753 cpuSpeeds[speed] = new LongSamplingCounter(mOnBatteryTimeBase); 9754 } 9755 cpuSpeeds[speed].addCountLocked(clusterSpeeds[cluster][speed]); 9756 } 9757 } 9758 } 9759 }); 9760 9761 // TODO: STOPSHIP, remove the "true" below after b/34961340 is fixed 9762 if (DEBUG_ENERGY_CPU || true) { 9763 Slog.d(TAG, "Reading cpu stats took " + (mClocks.elapsedRealtime() - startTimeMs) + 9764 " ms"); 9765 } 9766 9767 if (mOnBatteryInternal && numWakelocks > 0) { 9768 // Distribute a portion of the total cpu time to wakelock holders. 9769 mTempTotalCpuUserTimeUs = (mTempTotalCpuUserTimeUs * (100 - wakelockWeight)) / 100; 9770 mTempTotalCpuSystemTimeUs = 9771 (mTempTotalCpuSystemTimeUs * (100 - wakelockWeight)) / 100; 9772 9773 for (int i = 0; i < numPartialTimers; i++) { 9774 final StopwatchTimer timer = mPartialTimers.get(i); 9775 9776 // The system does not share any blame, as it is usually holding the wakelock 9777 // on behalf of an app. 9778 if (timer.mInList && timer.mUid != null && timer.mUid.mUid != Process.SYSTEM_UID) { 9779 int userTimeUs = (int) (mTempTotalCpuUserTimeUs / numWakelocks); 9780 int systemTimeUs = (int) (mTempTotalCpuSystemTimeUs / numWakelocks); 9781 9782 if (DEBUG_ENERGY_CPU) { 9783 StringBuilder sb = new StringBuilder(); 9784 sb.append(" Distributing wakelock uid=").append(timer.mUid.mUid) 9785 .append(": u="); 9786 TimeUtils.formatDuration(userTimeUs / 1000, sb); 9787 sb.append(" s="); 9788 TimeUtils.formatDuration(systemTimeUs / 1000, sb); 9789 Slog.d(TAG, sb.toString()); 9790 } 9791 9792 timer.mUid.mUserCpuTime.addCountLocked(userTimeUs); 9793 timer.mUid.mSystemCpuTime.addCountLocked(systemTimeUs); 9794 9795 final Uid.Proc proc = timer.mUid.getProcessStatsLocked("*wakelock*"); 9796 proc.addCpuTimeLocked(userTimeUs / 1000, systemTimeUs / 1000); 9797 9798 mTempTotalCpuUserTimeUs -= userTimeUs; 9799 mTempTotalCpuSystemTimeUs -= systemTimeUs; 9800 numWakelocks--; 9801 } 9802 } 9803 9804 if (mTempTotalCpuUserTimeUs > 0 || mTempTotalCpuSystemTimeUs > 0) { 9805 // Anything left over is given to the system. 9806 if (DEBUG_ENERGY_CPU) { 9807 StringBuilder sb = new StringBuilder(); 9808 sb.append(" Distributing lost time to system: u="); 9809 TimeUtils.formatDuration(mTempTotalCpuUserTimeUs / 1000, sb); 9810 sb.append(" s="); 9811 TimeUtils.formatDuration(mTempTotalCpuSystemTimeUs / 1000, sb); 9812 Slog.d(TAG, sb.toString()); 9813 } 9814 9815 final Uid u = getUidStatsLocked(Process.SYSTEM_UID); 9816 u.mUserCpuTime.addCountLocked(mTempTotalCpuUserTimeUs); 9817 u.mSystemCpuTime.addCountLocked(mTempTotalCpuSystemTimeUs); 9818 9819 final Uid.Proc proc = u.getProcessStatsLocked("*lost*"); 9820 proc.addCpuTimeLocked((int) mTempTotalCpuUserTimeUs / 1000, 9821 (int) mTempTotalCpuSystemTimeUs / 1000); 9822 } 9823 } 9824 9825 // See if there is a difference in wakelocks between this collection and the last 9826 // collection. 9827 if (ArrayUtils.referenceEquals(mPartialTimers, mLastPartialTimers)) { 9828 // No difference, so each timer is now considered for the next collection. 9829 for (int i = 0; i < numPartialTimers; i++) { 9830 mPartialTimers.get(i).mInList = true; 9831 } 9832 } else { 9833 // The lists are different, meaning we added (or removed a timer) since the last 9834 // collection. 9835 final int numLastPartialTimers = mLastPartialTimers.size(); 9836 for (int i = 0; i < numLastPartialTimers; i++) { 9837 mLastPartialTimers.get(i).mInList = false; 9838 } 9839 mLastPartialTimers.clear(); 9840 9841 // Mark the current timers as gone through a collection. 9842 for (int i = 0; i < numPartialTimers; i++) { 9843 final StopwatchTimer timer = mPartialTimers.get(i); 9844 timer.mInList = true; 9845 mLastPartialTimers.add(timer); 9846 } 9847 } 9848 } 9849 9850 boolean setChargingLocked(boolean charging) { 9851 if (mCharging != charging) { 9852 mCharging = charging; 9853 if (charging) { 9854 mHistoryCur.states2 |= HistoryItem.STATE2_CHARGING_FLAG; 9855 } else { 9856 mHistoryCur.states2 &= ~HistoryItem.STATE2_CHARGING_FLAG; 9857 } 9858 mHandler.sendEmptyMessage(MSG_REPORT_CHARGING); 9859 return true; 9860 } 9861 return false; 9862 } 9863 9864 void setOnBatteryLocked(final long mSecRealtime, final long mSecUptime, final boolean onBattery, 9865 final int oldStatus, final int level, final int chargeUAh) { 9866 boolean doWrite = false; 9867 Message m = mHandler.obtainMessage(MSG_REPORT_POWER_CHANGE); 9868 m.arg1 = onBattery ? 1 : 0; 9869 mHandler.sendMessage(m); 9870 9871 final long uptime = mSecUptime * 1000; 9872 final long realtime = mSecRealtime * 1000; 9873 final boolean screenOn = mScreenState == Display.STATE_ON; 9874 if (onBattery) { 9875 // We will reset our status if we are unplugging after the 9876 // battery was last full, or the level is at 100, or 9877 // we have gone through a significant charge (from a very low 9878 // level to a now very high level). 9879 boolean reset = false; 9880 if (!mNoAutoReset && (oldStatus == BatteryManager.BATTERY_STATUS_FULL 9881 || level >= 90 9882 || (mDischargeCurrentLevel < 20 && level >= 80) 9883 || (getHighDischargeAmountSinceCharge() >= 200 9884 && mHistoryBuffer.dataSize() >= MAX_HISTORY_BUFFER))) { 9885 Slog.i(TAG, "Resetting battery stats: level=" + level + " status=" + oldStatus 9886 + " dischargeLevel=" + mDischargeCurrentLevel 9887 + " lowAmount=" + getLowDischargeAmountSinceCharge() 9888 + " highAmount=" + getHighDischargeAmountSinceCharge()); 9889 // Before we write, collect a snapshot of the final aggregated 9890 // stats to be reported in the next checkin. Only do this if we have 9891 // a sufficient amount of data to make it interesting. 9892 if (getLowDischargeAmountSinceCharge() >= 20) { 9893 final Parcel parcel = Parcel.obtain(); 9894 writeSummaryToParcel(parcel, true); 9895 BackgroundThread.getHandler().post(new Runnable() { 9896 @Override public void run() { 9897 synchronized (mCheckinFile) { 9898 FileOutputStream stream = null; 9899 try { 9900 stream = mCheckinFile.startWrite(); 9901 stream.write(parcel.marshall()); 9902 stream.flush(); 9903 FileUtils.sync(stream); 9904 stream.close(); 9905 mCheckinFile.finishWrite(stream); 9906 } catch (IOException e) { 9907 Slog.w("BatteryStats", 9908 "Error writing checkin battery statistics", e); 9909 mCheckinFile.failWrite(stream); 9910 } finally { 9911 parcel.recycle(); 9912 } 9913 } 9914 } 9915 }); 9916 } 9917 doWrite = true; 9918 resetAllStatsLocked(); 9919 if (chargeUAh > 0 && level > 0) { 9920 // Only use the reported coulomb charge value if it is supported and reported. 9921 mEstimatedBatteryCapacity = (int) ((chargeUAh / 1000) / (level / 100.0)); 9922 } 9923 mDischargeStartLevel = level; 9924 reset = true; 9925 mDischargeStepTracker.init(); 9926 } 9927 if (mCharging) { 9928 setChargingLocked(false); 9929 } 9930 mLastChargingStateLevel = level; 9931 mOnBattery = mOnBatteryInternal = true; 9932 mLastDischargeStepLevel = level; 9933 mMinDischargeStepLevel = level; 9934 mDischargeStepTracker.clearTime(); 9935 mDailyDischargeStepTracker.clearTime(); 9936 mInitStepMode = mCurStepMode; 9937 mModStepMode = 0; 9938 pullPendingStateUpdatesLocked(); 9939 mHistoryCur.batteryLevel = (byte)level; 9940 mHistoryCur.states &= ~HistoryItem.STATE_BATTERY_PLUGGED_FLAG; 9941 if (DEBUG_HISTORY) Slog.v(TAG, "Battery unplugged to: " 9942 + Integer.toHexString(mHistoryCur.states)); 9943 if (reset) { 9944 mRecordingHistory = true; 9945 startRecordingHistory(mSecRealtime, mSecUptime, reset); 9946 } 9947 addHistoryRecordLocked(mSecRealtime, mSecUptime); 9948 mDischargeCurrentLevel = mDischargeUnplugLevel = level; 9949 if (screenOn) { 9950 mDischargeScreenOnUnplugLevel = level; 9951 mDischargeScreenOffUnplugLevel = 0; 9952 } else { 9953 mDischargeScreenOnUnplugLevel = 0; 9954 mDischargeScreenOffUnplugLevel = level; 9955 } 9956 mDischargeAmountScreenOn = 0; 9957 mDischargeAmountScreenOff = 0; 9958 updateTimeBasesLocked(true, !screenOn, uptime, realtime); 9959 } else { 9960 mLastChargingStateLevel = level; 9961 mOnBattery = mOnBatteryInternal = false; 9962 pullPendingStateUpdatesLocked(); 9963 mHistoryCur.batteryLevel = (byte)level; 9964 mHistoryCur.states |= HistoryItem.STATE_BATTERY_PLUGGED_FLAG; 9965 if (DEBUG_HISTORY) Slog.v(TAG, "Battery plugged to: " 9966 + Integer.toHexString(mHistoryCur.states)); 9967 addHistoryRecordLocked(mSecRealtime, mSecUptime); 9968 mDischargeCurrentLevel = mDischargePlugLevel = level; 9969 if (level < mDischargeUnplugLevel) { 9970 mLowDischargeAmountSinceCharge += mDischargeUnplugLevel-level-1; 9971 mHighDischargeAmountSinceCharge += mDischargeUnplugLevel-level; 9972 } 9973 updateDischargeScreenLevelsLocked(screenOn, screenOn); 9974 updateTimeBasesLocked(false, !screenOn, uptime, realtime); 9975 mChargeStepTracker.init(); 9976 mLastChargeStepLevel = level; 9977 mMaxChargeStepLevel = level; 9978 mInitStepMode = mCurStepMode; 9979 mModStepMode = 0; 9980 } 9981 if (doWrite || (mLastWriteTime + (60 * 1000)) < mSecRealtime) { 9982 if (mFile != null) { 9983 writeAsyncLocked(); 9984 } 9985 } 9986 } 9987 9988 private void startRecordingHistory(final long elapsedRealtimeMs, final long uptimeMs, 9989 boolean reset) { 9990 mRecordingHistory = true; 9991 mHistoryCur.currentTime = System.currentTimeMillis(); 9992 addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, 9993 reset ? HistoryItem.CMD_RESET : HistoryItem.CMD_CURRENT_TIME, 9994 mHistoryCur); 9995 mHistoryCur.currentTime = 0; 9996 if (reset) { 9997 initActiveHistoryEventsLocked(elapsedRealtimeMs, uptimeMs); 9998 } 9999 } 10000 10001 private void recordCurrentTimeChangeLocked(final long currentTime, final long elapsedRealtimeMs, 10002 final long uptimeMs) { 10003 if (mRecordingHistory) { 10004 mHistoryCur.currentTime = currentTime; 10005 addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.CMD_CURRENT_TIME, 10006 mHistoryCur); 10007 mHistoryCur.currentTime = 0; 10008 } 10009 } 10010 10011 private void recordShutdownLocked(final long elapsedRealtimeMs, final long uptimeMs) { 10012 if (mRecordingHistory) { 10013 mHistoryCur.currentTime = System.currentTimeMillis(); 10014 addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.CMD_SHUTDOWN, 10015 mHistoryCur); 10016 mHistoryCur.currentTime = 0; 10017 } 10018 } 10019 10020 private void scheduleSyncExternalStatsLocked(String reason, int updateFlags) { 10021 if (mExternalSync != null) { 10022 mExternalSync.scheduleSync(reason, updateFlags); 10023 } 10024 } 10025 10026 // This should probably be exposed in the API, though it's not critical 10027 public static final int BATTERY_PLUGGED_NONE = 0; 10028 10029 public void setBatteryStateLocked(int status, int health, int plugType, int level, 10030 int temp, int volt, int chargeUAh, int chargeFullUAh) { 10031 // Temperature is encoded without the signed bit, so clamp any negative temperatures to 0. 10032 temp = Math.max(0, temp); 10033 10034 final boolean onBattery = plugType == BATTERY_PLUGGED_NONE; 10035 final long uptime = mClocks.uptimeMillis(); 10036 final long elapsedRealtime = mClocks.elapsedRealtime(); 10037 if (!mHaveBatteryLevel) { 10038 mHaveBatteryLevel = true; 10039 // We start out assuming that the device is plugged in (not 10040 // on battery). If our first report is now that we are indeed 10041 // plugged in, then twiddle our state to correctly reflect that 10042 // since we won't be going through the full setOnBattery(). 10043 if (onBattery == mOnBattery) { 10044 if (onBattery) { 10045 mHistoryCur.states &= ~HistoryItem.STATE_BATTERY_PLUGGED_FLAG; 10046 } else { 10047 mHistoryCur.states |= HistoryItem.STATE_BATTERY_PLUGGED_FLAG; 10048 } 10049 } 10050 // Always start out assuming charging, that will be updated later. 10051 mHistoryCur.states2 |= HistoryItem.STATE2_CHARGING_FLAG; 10052 mHistoryCur.batteryStatus = (byte)status; 10053 mHistoryCur.batteryLevel = (byte)level; 10054 mHistoryCur.batteryChargeUAh = chargeUAh; 10055 mMaxChargeStepLevel = mMinDischargeStepLevel = 10056 mLastChargeStepLevel = mLastDischargeStepLevel = level; 10057 mLastChargingStateLevel = level; 10058 } else if (mCurrentBatteryLevel != level || mOnBattery != onBattery) { 10059 recordDailyStatsIfNeededLocked(level >= 100 && onBattery); 10060 } 10061 int oldStatus = mHistoryCur.batteryStatus; 10062 if (onBattery) { 10063 mDischargeCurrentLevel = level; 10064 if (!mRecordingHistory) { 10065 mRecordingHistory = true; 10066 startRecordingHistory(elapsedRealtime, uptime, true); 10067 } 10068 } else if (level < 96) { 10069 if (!mRecordingHistory) { 10070 mRecordingHistory = true; 10071 startRecordingHistory(elapsedRealtime, uptime, true); 10072 } 10073 } 10074 mCurrentBatteryLevel = level; 10075 if (mDischargePlugLevel < 0) { 10076 mDischargePlugLevel = level; 10077 } 10078 10079 if (onBattery != mOnBattery) { 10080 mHistoryCur.batteryLevel = (byte)level; 10081 mHistoryCur.batteryStatus = (byte)status; 10082 mHistoryCur.batteryHealth = (byte)health; 10083 mHistoryCur.batteryPlugType = (byte)plugType; 10084 mHistoryCur.batteryTemperature = (short)temp; 10085 mHistoryCur.batteryVoltage = (char)volt; 10086 if (chargeUAh < mHistoryCur.batteryChargeUAh) { 10087 // Only record discharges 10088 final long chargeDiff = mHistoryCur.batteryChargeUAh - chargeUAh; 10089 mDischargeCounter.addCountLocked(chargeDiff); 10090 mDischargeScreenOffCounter.addCountLocked(chargeDiff); 10091 } 10092 mHistoryCur.batteryChargeUAh = chargeUAh; 10093 setOnBatteryLocked(elapsedRealtime, uptime, onBattery, oldStatus, level, chargeUAh); 10094 } else { 10095 boolean changed = false; 10096 if (mHistoryCur.batteryLevel != level) { 10097 mHistoryCur.batteryLevel = (byte)level; 10098 changed = true; 10099 10100 // TODO(adamlesinski): Schedule the creation of a HistoryStepDetails record 10101 // which will pull external stats. 10102 scheduleSyncExternalStatsLocked("battery-level", ExternalStatsSync.UPDATE_ALL); 10103 } 10104 if (mHistoryCur.batteryStatus != status) { 10105 mHistoryCur.batteryStatus = (byte)status; 10106 changed = true; 10107 } 10108 if (mHistoryCur.batteryHealth != health) { 10109 mHistoryCur.batteryHealth = (byte)health; 10110 changed = true; 10111 } 10112 if (mHistoryCur.batteryPlugType != plugType) { 10113 mHistoryCur.batteryPlugType = (byte)plugType; 10114 changed = true; 10115 } 10116 if (temp >= (mHistoryCur.batteryTemperature+10) 10117 || temp <= (mHistoryCur.batteryTemperature-10)) { 10118 mHistoryCur.batteryTemperature = (short)temp; 10119 changed = true; 10120 } 10121 if (volt > (mHistoryCur.batteryVoltage+20) 10122 || volt < (mHistoryCur.batteryVoltage-20)) { 10123 mHistoryCur.batteryVoltage = (char)volt; 10124 changed = true; 10125 } 10126 if (chargeUAh >= (mHistoryCur.batteryChargeUAh+10) 10127 || chargeUAh <= (mHistoryCur.batteryChargeUAh-10)) { 10128 if (chargeUAh < mHistoryCur.batteryChargeUAh) { 10129 // Only record discharges 10130 final long chargeDiff = mHistoryCur.batteryChargeUAh - chargeUAh; 10131 mDischargeCounter.addCountLocked(chargeDiff); 10132 mDischargeScreenOffCounter.addCountLocked(chargeDiff); 10133 } 10134 mHistoryCur.batteryChargeUAh = chargeUAh; 10135 changed = true; 10136 } 10137 long modeBits = (((long)mInitStepMode) << STEP_LEVEL_INITIAL_MODE_SHIFT) 10138 | (((long)mModStepMode) << STEP_LEVEL_MODIFIED_MODE_SHIFT) 10139 | (((long)(level&0xff)) << STEP_LEVEL_LEVEL_SHIFT); 10140 if (onBattery) { 10141 changed |= setChargingLocked(false); 10142 if (mLastDischargeStepLevel != level && mMinDischargeStepLevel > level) { 10143 mDischargeStepTracker.addLevelSteps(mLastDischargeStepLevel - level, 10144 modeBits, elapsedRealtime); 10145 mDailyDischargeStepTracker.addLevelSteps(mLastDischargeStepLevel - level, 10146 modeBits, elapsedRealtime); 10147 mLastDischargeStepLevel = level; 10148 mMinDischargeStepLevel = level; 10149 mInitStepMode = mCurStepMode; 10150 mModStepMode = 0; 10151 } 10152 } else { 10153 if (level >= 90) { 10154 // If the battery level is at least 90%, always consider the device to be 10155 // charging even if it happens to go down a level. 10156 changed |= setChargingLocked(true); 10157 mLastChargeStepLevel = level; 10158 } if (!mCharging) { 10159 if (mLastChargeStepLevel < level) { 10160 // We have not reporting that we are charging, but the level has now 10161 // gone up, so consider the state to be charging. 10162 changed |= setChargingLocked(true); 10163 mLastChargeStepLevel = level; 10164 } 10165 } else { 10166 if (mLastChargeStepLevel > level) { 10167 // We had reported that the device was charging, but here we are with 10168 // power connected and the level going down. Looks like the current 10169 // power supplied isn't enough, so consider the device to now be 10170 // discharging. 10171 changed |= setChargingLocked(false); 10172 mLastChargeStepLevel = level; 10173 } 10174 } 10175 if (mLastChargeStepLevel != level && mMaxChargeStepLevel < level) { 10176 mChargeStepTracker.addLevelSteps(level - mLastChargeStepLevel, 10177 modeBits, elapsedRealtime); 10178 mDailyChargeStepTracker.addLevelSteps(level - mLastChargeStepLevel, 10179 modeBits, elapsedRealtime); 10180 mLastChargeStepLevel = level; 10181 mMaxChargeStepLevel = level; 10182 mInitStepMode = mCurStepMode; 10183 mModStepMode = 0; 10184 } 10185 } 10186 if (changed) { 10187 addHistoryRecordLocked(elapsedRealtime, uptime); 10188 } 10189 } 10190 if (!onBattery && status == BatteryManager.BATTERY_STATUS_FULL) { 10191 // We don't record history while we are plugged in and fully charged. 10192 // The next time we are unplugged, history will be cleared. 10193 mRecordingHistory = DEBUG; 10194 } 10195 10196 if (differsByMoreThan(chargeFullUAh, mLastChargeFullUAh, 100)) { 10197 mLastChargeFullUAh = chargeFullUAh; 10198 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_ESTIMATED_BATTERY_CAP, 10199 "", chargeFullUAh / 1000); 10200 } 10201 } 10202 10203 private static boolean differsByMoreThan(int left, int right, int diff) { 10204 return Math.abs(left - right) > diff; 10205 } 10206 10207 public long getAwakeTimeBattery() { 10208 return computeBatteryUptime(getBatteryUptimeLocked(), STATS_CURRENT); 10209 } 10210 10211 public long getAwakeTimePlugged() { 10212 return (mClocks.uptimeMillis() * 1000) - getAwakeTimeBattery(); 10213 } 10214 10215 @Override 10216 public long computeUptime(long curTime, int which) { 10217 switch (which) { 10218 case STATS_SINCE_CHARGED: return mUptime + (curTime-mUptimeStart); 10219 case STATS_CURRENT: return (curTime-mUptimeStart); 10220 case STATS_SINCE_UNPLUGGED: return (curTime-mOnBatteryTimeBase.getUptimeStart()); 10221 } 10222 return 0; 10223 } 10224 10225 @Override 10226 public long computeRealtime(long curTime, int which) { 10227 switch (which) { 10228 case STATS_SINCE_CHARGED: return mRealtime + (curTime-mRealtimeStart); 10229 case STATS_CURRENT: return (curTime-mRealtimeStart); 10230 case STATS_SINCE_UNPLUGGED: return (curTime-mOnBatteryTimeBase.getRealtimeStart()); 10231 } 10232 return 0; 10233 } 10234 10235 @Override 10236 public long computeBatteryUptime(long curTime, int which) { 10237 return mOnBatteryTimeBase.computeUptime(curTime, which); 10238 } 10239 10240 @Override 10241 public long computeBatteryRealtime(long curTime, int which) { 10242 return mOnBatteryTimeBase.computeRealtime(curTime, which); 10243 } 10244 10245 @Override 10246 public long computeBatteryScreenOffUptime(long curTime, int which) { 10247 return mOnBatteryScreenOffTimeBase.computeUptime(curTime, which); 10248 } 10249 10250 @Override 10251 public long computeBatteryScreenOffRealtime(long curTime, int which) { 10252 return mOnBatteryScreenOffTimeBase.computeRealtime(curTime, which); 10253 } 10254 10255 private long computeTimePerLevel(long[] steps, int numSteps) { 10256 // For now we'll do a simple average across all steps. 10257 if (numSteps <= 0) { 10258 return -1; 10259 } 10260 long total = 0; 10261 for (int i=0; i<numSteps; i++) { 10262 total += steps[i] & STEP_LEVEL_TIME_MASK; 10263 } 10264 return total / numSteps; 10265 /* 10266 long[] buckets = new long[numSteps]; 10267 int numBuckets = 0; 10268 int numToAverage = 4; 10269 int i = 0; 10270 while (i < numSteps) { 10271 long totalTime = 0; 10272 int num = 0; 10273 for (int j=0; j<numToAverage && (i+j)<numSteps; j++) { 10274 totalTime += steps[i+j] & STEP_LEVEL_TIME_MASK; 10275 num++; 10276 } 10277 buckets[numBuckets] = totalTime / num; 10278 numBuckets++; 10279 numToAverage *= 2; 10280 i += num; 10281 } 10282 if (numBuckets < 1) { 10283 return -1; 10284 } 10285 long averageTime = buckets[numBuckets-1]; 10286 for (i=numBuckets-2; i>=0; i--) { 10287 averageTime = (averageTime + buckets[i]) / 2; 10288 } 10289 return averageTime; 10290 */ 10291 } 10292 10293 @Override 10294 public long computeBatteryTimeRemaining(long curTime) { 10295 if (!mOnBattery) { 10296 return -1; 10297 } 10298 /* Simple implementation just looks at the average discharge per level across the 10299 entire sample period. 10300 int discharge = (getLowDischargeAmountSinceCharge()+getHighDischargeAmountSinceCharge())/2; 10301 if (discharge < 2) { 10302 return -1; 10303 } 10304 long duration = computeBatteryRealtime(curTime, STATS_SINCE_CHARGED); 10305 if (duration < 1000*1000) { 10306 return -1; 10307 } 10308 long usPerLevel = duration/discharge; 10309 return usPerLevel * mCurrentBatteryLevel; 10310 */ 10311 if (mDischargeStepTracker.mNumStepDurations < 1) { 10312 return -1; 10313 } 10314 long msPerLevel = mDischargeStepTracker.computeTimePerLevel(); 10315 if (msPerLevel <= 0) { 10316 return -1; 10317 } 10318 return (msPerLevel * mCurrentBatteryLevel) * 1000; 10319 } 10320 10321 @Override 10322 public LevelStepTracker getDischargeLevelStepTracker() { 10323 return mDischargeStepTracker; 10324 } 10325 10326 @Override 10327 public LevelStepTracker getDailyDischargeLevelStepTracker() { 10328 return mDailyDischargeStepTracker; 10329 } 10330 10331 @Override 10332 public long computeChargeTimeRemaining(long curTime) { 10333 if (mOnBattery) { 10334 // Not yet working. 10335 return -1; 10336 } 10337 /* Broken 10338 int curLevel = mCurrentBatteryLevel; 10339 int plugLevel = mDischargePlugLevel; 10340 if (plugLevel < 0 || curLevel < (plugLevel+1)) { 10341 return -1; 10342 } 10343 long duration = computeBatteryRealtime(curTime, STATS_SINCE_UNPLUGGED); 10344 if (duration < 1000*1000) { 10345 return -1; 10346 } 10347 long usPerLevel = duration/(curLevel-plugLevel); 10348 return usPerLevel * (100-curLevel); 10349 */ 10350 if (mChargeStepTracker.mNumStepDurations < 1) { 10351 return -1; 10352 } 10353 long msPerLevel = mChargeStepTracker.computeTimePerLevel(); 10354 if (msPerLevel <= 0) { 10355 return -1; 10356 } 10357 return (msPerLevel * (100-mCurrentBatteryLevel)) * 1000; 10358 } 10359 10360 @Override 10361 public LevelStepTracker getChargeLevelStepTracker() { 10362 return mChargeStepTracker; 10363 } 10364 10365 @Override 10366 public LevelStepTracker getDailyChargeLevelStepTracker() { 10367 return mDailyChargeStepTracker; 10368 } 10369 10370 @Override 10371 public ArrayList<PackageChange> getDailyPackageChanges() { 10372 return mDailyPackageChanges; 10373 } 10374 10375 protected long getBatteryUptimeLocked() { 10376 return mOnBatteryTimeBase.getUptime(mClocks.uptimeMillis() * 1000); 10377 } 10378 10379 @Override 10380 public long getBatteryUptime(long curTime) { 10381 return mOnBatteryTimeBase.getUptime(curTime); 10382 } 10383 10384 @Override 10385 public long getBatteryRealtime(long curTime) { 10386 return mOnBatteryTimeBase.getRealtime(curTime); 10387 } 10388 10389 @Override 10390 public int getDischargeStartLevel() { 10391 synchronized(this) { 10392 return getDischargeStartLevelLocked(); 10393 } 10394 } 10395 10396 public int getDischargeStartLevelLocked() { 10397 return mDischargeUnplugLevel; 10398 } 10399 10400 @Override 10401 public int getDischargeCurrentLevel() { 10402 synchronized(this) { 10403 return getDischargeCurrentLevelLocked(); 10404 } 10405 } 10406 10407 public int getDischargeCurrentLevelLocked() { 10408 return mDischargeCurrentLevel; 10409 } 10410 10411 @Override 10412 public int getLowDischargeAmountSinceCharge() { 10413 synchronized(this) { 10414 int val = mLowDischargeAmountSinceCharge; 10415 if (mOnBattery && mDischargeCurrentLevel < mDischargeUnplugLevel) { 10416 val += mDischargeUnplugLevel-mDischargeCurrentLevel-1; 10417 } 10418 return val; 10419 } 10420 } 10421 10422 @Override 10423 public int getHighDischargeAmountSinceCharge() { 10424 synchronized(this) { 10425 int val = mHighDischargeAmountSinceCharge; 10426 if (mOnBattery && mDischargeCurrentLevel < mDischargeUnplugLevel) { 10427 val += mDischargeUnplugLevel-mDischargeCurrentLevel; 10428 } 10429 return val; 10430 } 10431 } 10432 10433 @Override 10434 public int getDischargeAmount(int which) { 10435 int dischargeAmount = which == STATS_SINCE_CHARGED 10436 ? getHighDischargeAmountSinceCharge() 10437 : (getDischargeStartLevel() - getDischargeCurrentLevel()); 10438 if (dischargeAmount < 0) { 10439 dischargeAmount = 0; 10440 } 10441 return dischargeAmount; 10442 } 10443 10444 public int getDischargeAmountScreenOn() { 10445 synchronized(this) { 10446 int val = mDischargeAmountScreenOn; 10447 if (mOnBattery && mScreenState == Display.STATE_ON 10448 && mDischargeCurrentLevel < mDischargeScreenOnUnplugLevel) { 10449 val += mDischargeScreenOnUnplugLevel-mDischargeCurrentLevel; 10450 } 10451 return val; 10452 } 10453 } 10454 10455 public int getDischargeAmountScreenOnSinceCharge() { 10456 synchronized(this) { 10457 int val = mDischargeAmountScreenOnSinceCharge; 10458 if (mOnBattery && mScreenState == Display.STATE_ON 10459 && mDischargeCurrentLevel < mDischargeScreenOnUnplugLevel) { 10460 val += mDischargeScreenOnUnplugLevel-mDischargeCurrentLevel; 10461 } 10462 return val; 10463 } 10464 } 10465 10466 public int getDischargeAmountScreenOff() { 10467 synchronized(this) { 10468 int val = mDischargeAmountScreenOff; 10469 if (mOnBattery && mScreenState != Display.STATE_ON 10470 && mDischargeCurrentLevel < mDischargeScreenOffUnplugLevel) { 10471 val += mDischargeScreenOffUnplugLevel-mDischargeCurrentLevel; 10472 } 10473 return val; 10474 } 10475 } 10476 10477 public int getDischargeAmountScreenOffSinceCharge() { 10478 synchronized(this) { 10479 int val = mDischargeAmountScreenOffSinceCharge; 10480 if (mOnBattery && mScreenState != Display.STATE_ON 10481 && mDischargeCurrentLevel < mDischargeScreenOffUnplugLevel) { 10482 val += mDischargeScreenOffUnplugLevel-mDischargeCurrentLevel; 10483 } 10484 return val; 10485 } 10486 } 10487 10488 /** 10489 * Retrieve the statistics object for a particular uid, creating if needed. 10490 */ 10491 public Uid getUidStatsLocked(int uid) { 10492 Uid u = mUidStats.get(uid); 10493 if (u == null) { 10494 u = new Uid(this, uid); 10495 mUidStats.put(uid, u); 10496 } 10497 return u; 10498 } 10499 10500 /** 10501 * Remove the statistics object for a particular uid. 10502 */ 10503 public void removeUidStatsLocked(int uid) { 10504 mKernelUidCpuTimeReader.removeUid(uid); 10505 mUidStats.remove(uid); 10506 } 10507 10508 /** 10509 * Retrieve the statistics object for a particular process, creating 10510 * if needed. 10511 */ 10512 public Uid.Proc getProcessStatsLocked(int uid, String name) { 10513 uid = mapUid(uid); 10514 Uid u = getUidStatsLocked(uid); 10515 return u.getProcessStatsLocked(name); 10516 } 10517 10518 /** 10519 * Retrieve the statistics object for a particular process, creating 10520 * if needed. 10521 */ 10522 public Uid.Pkg getPackageStatsLocked(int uid, String pkg) { 10523 uid = mapUid(uid); 10524 Uid u = getUidStatsLocked(uid); 10525 return u.getPackageStatsLocked(pkg); 10526 } 10527 10528 /** 10529 * Retrieve the statistics object for a particular service, creating 10530 * if needed. 10531 */ 10532 public Uid.Pkg.Serv getServiceStatsLocked(int uid, String pkg, String name) { 10533 uid = mapUid(uid); 10534 Uid u = getUidStatsLocked(uid); 10535 return u.getServiceStatsLocked(pkg, name); 10536 } 10537 10538 public void shutdownLocked() { 10539 recordShutdownLocked(mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 10540 writeSyncLocked(); 10541 mShuttingDown = true; 10542 } 10543 10544 Parcel mPendingWrite = null; 10545 final ReentrantLock mWriteLock = new ReentrantLock(); 10546 10547 public void writeAsyncLocked() { 10548 writeLocked(false); 10549 } 10550 10551 public void writeSyncLocked() { 10552 writeLocked(true); 10553 } 10554 10555 void writeLocked(boolean sync) { 10556 if (mFile == null) { 10557 Slog.w("BatteryStats", "writeLocked: no file associated with this instance"); 10558 return; 10559 } 10560 10561 if (mShuttingDown) { 10562 return; 10563 } 10564 10565 Parcel out = Parcel.obtain(); 10566 writeSummaryToParcel(out, true); 10567 mLastWriteTime = mClocks.elapsedRealtime(); 10568 10569 if (mPendingWrite != null) { 10570 mPendingWrite.recycle(); 10571 } 10572 mPendingWrite = out; 10573 10574 if (sync) { 10575 commitPendingDataToDisk(); 10576 } else { 10577 BackgroundThread.getHandler().post(new Runnable() { 10578 @Override public void run() { 10579 commitPendingDataToDisk(); 10580 } 10581 }); 10582 } 10583 } 10584 10585 public void commitPendingDataToDisk() { 10586 final Parcel next; 10587 synchronized (this) { 10588 next = mPendingWrite; 10589 mPendingWrite = null; 10590 if (next == null) { 10591 return; 10592 } 10593 } 10594 10595 mWriteLock.lock(); 10596 try { 10597 FileOutputStream stream = new FileOutputStream(mFile.chooseForWrite()); 10598 stream.write(next.marshall()); 10599 stream.flush(); 10600 FileUtils.sync(stream); 10601 stream.close(); 10602 mFile.commit(); 10603 } catch (IOException e) { 10604 Slog.w("BatteryStats", "Error writing battery statistics", e); 10605 mFile.rollback(); 10606 } finally { 10607 next.recycle(); 10608 mWriteLock.unlock(); 10609 } 10610 } 10611 10612 public void readLocked() { 10613 if (mDailyFile != null) { 10614 readDailyStatsLocked(); 10615 } 10616 10617 if (mFile == null) { 10618 Slog.w("BatteryStats", "readLocked: no file associated with this instance"); 10619 return; 10620 } 10621 10622 mUidStats.clear(); 10623 10624 try { 10625 File file = mFile.chooseForRead(); 10626 if (!file.exists()) { 10627 return; 10628 } 10629 FileInputStream stream = new FileInputStream(file); 10630 10631 byte[] raw = BatteryStatsHelper.readFully(stream); 10632 Parcel in = Parcel.obtain(); 10633 in.unmarshall(raw, 0, raw.length); 10634 in.setDataPosition(0); 10635 stream.close(); 10636 10637 readSummaryFromParcel(in); 10638 } catch(Exception e) { 10639 Slog.e("BatteryStats", "Error reading battery statistics", e); 10640 resetAllStatsLocked(); 10641 } 10642 10643 mEndPlatformVersion = Build.ID; 10644 10645 if (mHistoryBuffer.dataPosition() > 0) { 10646 mRecordingHistory = true; 10647 final long elapsedRealtime = mClocks.elapsedRealtime(); 10648 final long uptime = mClocks.uptimeMillis(); 10649 if (USE_OLD_HISTORY) { 10650 addHistoryRecordLocked(elapsedRealtime, uptime, HistoryItem.CMD_START, mHistoryCur); 10651 } 10652 addHistoryBufferLocked(elapsedRealtime, uptime, HistoryItem.CMD_START, mHistoryCur); 10653 startRecordingHistory(elapsedRealtime, uptime, false); 10654 } 10655 10656 recordDailyStatsIfNeededLocked(false); 10657 } 10658 10659 public int describeContents() { 10660 return 0; 10661 } 10662 10663 void readHistory(Parcel in, boolean andOldHistory) throws ParcelFormatException { 10664 final long historyBaseTime = in.readLong(); 10665 10666 mHistoryBuffer.setDataSize(0); 10667 mHistoryBuffer.setDataPosition(0); 10668 mHistoryTagPool.clear(); 10669 mNextHistoryTagIdx = 0; 10670 mNumHistoryTagChars = 0; 10671 10672 int numTags = in.readInt(); 10673 for (int i=0; i<numTags; i++) { 10674 int idx = in.readInt(); 10675 String str = in.readString(); 10676 if (str == null) { 10677 throw new ParcelFormatException("null history tag string"); 10678 } 10679 int uid = in.readInt(); 10680 HistoryTag tag = new HistoryTag(); 10681 tag.string = str; 10682 tag.uid = uid; 10683 tag.poolIdx = idx; 10684 mHistoryTagPool.put(tag, idx); 10685 if (idx >= mNextHistoryTagIdx) { 10686 mNextHistoryTagIdx = idx+1; 10687 } 10688 mNumHistoryTagChars += tag.string.length() + 1; 10689 } 10690 10691 int bufSize = in.readInt(); 10692 int curPos = in.dataPosition(); 10693 if (bufSize >= (MAX_MAX_HISTORY_BUFFER*3)) { 10694 throw new ParcelFormatException("File corrupt: history data buffer too large " + 10695 bufSize); 10696 } else if ((bufSize&~3) != bufSize) { 10697 throw new ParcelFormatException("File corrupt: history data buffer not aligned " + 10698 bufSize); 10699 } else { 10700 if (DEBUG_HISTORY) Slog.i(TAG, "***************** READING NEW HISTORY: " + bufSize 10701 + " bytes at " + curPos); 10702 mHistoryBuffer.appendFrom(in, curPos, bufSize); 10703 in.setDataPosition(curPos + bufSize); 10704 } 10705 10706 if (andOldHistory) { 10707 readOldHistory(in); 10708 } 10709 10710 if (DEBUG_HISTORY) { 10711 StringBuilder sb = new StringBuilder(128); 10712 sb.append("****************** OLD mHistoryBaseTime: "); 10713 TimeUtils.formatDuration(mHistoryBaseTime, sb); 10714 Slog.i(TAG, sb.toString()); 10715 } 10716 mHistoryBaseTime = historyBaseTime; 10717 if (DEBUG_HISTORY) { 10718 StringBuilder sb = new StringBuilder(128); 10719 sb.append("****************** NEW mHistoryBaseTime: "); 10720 TimeUtils.formatDuration(mHistoryBaseTime, sb); 10721 Slog.i(TAG, sb.toString()); 10722 } 10723 10724 // We are just arbitrarily going to insert 1 minute from the sample of 10725 // the last run until samples in this run. 10726 if (mHistoryBaseTime > 0) { 10727 long oldnow = mClocks.elapsedRealtime(); 10728 mHistoryBaseTime = mHistoryBaseTime - oldnow + 1; 10729 if (DEBUG_HISTORY) { 10730 StringBuilder sb = new StringBuilder(128); 10731 sb.append("****************** ADJUSTED mHistoryBaseTime: "); 10732 TimeUtils.formatDuration(mHistoryBaseTime, sb); 10733 Slog.i(TAG, sb.toString()); 10734 } 10735 } 10736 } 10737 10738 void readOldHistory(Parcel in) { 10739 if (!USE_OLD_HISTORY) { 10740 return; 10741 } 10742 mHistory = mHistoryEnd = mHistoryCache = null; 10743 long time; 10744 while (in.dataAvail() > 0 && (time=in.readLong()) >= 0) { 10745 HistoryItem rec = new HistoryItem(time, in); 10746 addHistoryRecordLocked(rec); 10747 } 10748 } 10749 10750 void writeHistory(Parcel out, boolean inclData, boolean andOldHistory) { 10751 if (DEBUG_HISTORY) { 10752 StringBuilder sb = new StringBuilder(128); 10753 sb.append("****************** WRITING mHistoryBaseTime: "); 10754 TimeUtils.formatDuration(mHistoryBaseTime, sb); 10755 sb.append(" mLastHistoryElapsedRealtime: "); 10756 TimeUtils.formatDuration(mLastHistoryElapsedRealtime, sb); 10757 Slog.i(TAG, sb.toString()); 10758 } 10759 out.writeLong(mHistoryBaseTime + mLastHistoryElapsedRealtime); 10760 if (!inclData) { 10761 out.writeInt(0); 10762 out.writeInt(0); 10763 return; 10764 } 10765 out.writeInt(mHistoryTagPool.size()); 10766 for (HashMap.Entry<HistoryTag, Integer> ent : mHistoryTagPool.entrySet()) { 10767 HistoryTag tag = ent.getKey(); 10768 out.writeInt(ent.getValue()); 10769 out.writeString(tag.string); 10770 out.writeInt(tag.uid); 10771 } 10772 out.writeInt(mHistoryBuffer.dataSize()); 10773 if (DEBUG_HISTORY) Slog.i(TAG, "***************** WRITING HISTORY: " 10774 + mHistoryBuffer.dataSize() + " bytes at " + out.dataPosition()); 10775 out.appendFrom(mHistoryBuffer, 0, mHistoryBuffer.dataSize()); 10776 10777 if (andOldHistory) { 10778 writeOldHistory(out); 10779 } 10780 } 10781 10782 void writeOldHistory(Parcel out) { 10783 if (!USE_OLD_HISTORY) { 10784 return; 10785 } 10786 HistoryItem rec = mHistory; 10787 while (rec != null) { 10788 if (rec.time >= 0) rec.writeToParcel(out, 0); 10789 rec = rec.next; 10790 } 10791 out.writeLong(-1); 10792 } 10793 10794 public void readSummaryFromParcel(Parcel in) throws ParcelFormatException { 10795 final int version = in.readInt(); 10796 if (version != VERSION) { 10797 Slog.w("BatteryStats", "readFromParcel: version got " + version 10798 + ", expected " + VERSION + "; erasing old stats"); 10799 return; 10800 } 10801 10802 readHistory(in, true); 10803 10804 mStartCount = in.readInt(); 10805 mUptime = in.readLong(); 10806 mRealtime = in.readLong(); 10807 mStartClockTime = in.readLong(); 10808 mStartPlatformVersion = in.readString(); 10809 mEndPlatformVersion = in.readString(); 10810 mOnBatteryTimeBase.readSummaryFromParcel(in); 10811 mOnBatteryScreenOffTimeBase.readSummaryFromParcel(in); 10812 mDischargeUnplugLevel = in.readInt(); 10813 mDischargePlugLevel = in.readInt(); 10814 mDischargeCurrentLevel = in.readInt(); 10815 mCurrentBatteryLevel = in.readInt(); 10816 mEstimatedBatteryCapacity = in.readInt(); 10817 mLowDischargeAmountSinceCharge = in.readInt(); 10818 mHighDischargeAmountSinceCharge = in.readInt(); 10819 mDischargeAmountScreenOnSinceCharge = in.readInt(); 10820 mDischargeAmountScreenOffSinceCharge = in.readInt(); 10821 mDischargeStepTracker.readFromParcel(in); 10822 mChargeStepTracker.readFromParcel(in); 10823 mDailyDischargeStepTracker.readFromParcel(in); 10824 mDailyChargeStepTracker.readFromParcel(in); 10825 mDischargeCounter.readSummaryFromParcelLocked(in); 10826 mDischargeScreenOffCounter.readSummaryFromParcelLocked(in); 10827 int NPKG = in.readInt(); 10828 if (NPKG > 0) { 10829 mDailyPackageChanges = new ArrayList<>(NPKG); 10830 while (NPKG > 0) { 10831 NPKG--; 10832 PackageChange pc = new PackageChange(); 10833 pc.mPackageName = in.readString(); 10834 pc.mUpdate = in.readInt() != 0; 10835 pc.mVersionCode = in.readInt(); 10836 mDailyPackageChanges.add(pc); 10837 } 10838 } else { 10839 mDailyPackageChanges = null; 10840 } 10841 mDailyStartTime = in.readLong(); 10842 mNextMinDailyDeadline = in.readLong(); 10843 mNextMaxDailyDeadline = in.readLong(); 10844 10845 mStartCount++; 10846 10847 mScreenState = Display.STATE_UNKNOWN; 10848 mScreenOnTimer.readSummaryFromParcelLocked(in); 10849 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 10850 mScreenBrightnessTimer[i].readSummaryFromParcelLocked(in); 10851 } 10852 mInteractive = false; 10853 mInteractiveTimer.readSummaryFromParcelLocked(in); 10854 mPhoneOn = false; 10855 mPowerSaveModeEnabledTimer.readSummaryFromParcelLocked(in); 10856 mLongestLightIdleTime = in.readLong(); 10857 mLongestFullIdleTime = in.readLong(); 10858 mDeviceIdleModeLightTimer.readSummaryFromParcelLocked(in); 10859 mDeviceIdleModeFullTimer.readSummaryFromParcelLocked(in); 10860 mDeviceLightIdlingTimer.readSummaryFromParcelLocked(in); 10861 mDeviceIdlingTimer.readSummaryFromParcelLocked(in); 10862 mPhoneOnTimer.readSummaryFromParcelLocked(in); 10863 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) { 10864 mPhoneSignalStrengthsTimer[i].readSummaryFromParcelLocked(in); 10865 } 10866 mPhoneSignalScanningTimer.readSummaryFromParcelLocked(in); 10867 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 10868 mPhoneDataConnectionsTimer[i].readSummaryFromParcelLocked(in); 10869 } 10870 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 10871 mNetworkByteActivityCounters[i].readSummaryFromParcelLocked(in); 10872 mNetworkPacketActivityCounters[i].readSummaryFromParcelLocked(in); 10873 } 10874 mMobileRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW; 10875 mMobileRadioActiveTimer.readSummaryFromParcelLocked(in); 10876 mMobileRadioActivePerAppTimer.readSummaryFromParcelLocked(in); 10877 mMobileRadioActiveAdjustedTime.readSummaryFromParcelLocked(in); 10878 mMobileRadioActiveUnknownTime.readSummaryFromParcelLocked(in); 10879 mMobileRadioActiveUnknownCount.readSummaryFromParcelLocked(in); 10880 mWifiRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW; 10881 mWifiOn = false; 10882 mWifiOnTimer.readSummaryFromParcelLocked(in); 10883 mGlobalWifiRunning = false; 10884 mGlobalWifiRunningTimer.readSummaryFromParcelLocked(in); 10885 for (int i=0; i<NUM_WIFI_STATES; i++) { 10886 mWifiStateTimer[i].readSummaryFromParcelLocked(in); 10887 } 10888 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) { 10889 mWifiSupplStateTimer[i].readSummaryFromParcelLocked(in); 10890 } 10891 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { 10892 mWifiSignalStrengthsTimer[i].readSummaryFromParcelLocked(in); 10893 } 10894 mWifiActivity.readSummaryFromParcel(in); 10895 mBluetoothActivity.readSummaryFromParcel(in); 10896 mModemActivity.readSummaryFromParcel(in); 10897 mHasWifiReporting = in.readInt() != 0; 10898 mHasBluetoothReporting = in.readInt() != 0; 10899 mHasModemReporting = in.readInt() != 0; 10900 10901 mNumConnectivityChange = mLoadedNumConnectivityChange = in.readInt(); 10902 mFlashlightOnNesting = 0; 10903 mFlashlightOnTimer.readSummaryFromParcelLocked(in); 10904 mCameraOnNesting = 0; 10905 mCameraOnTimer.readSummaryFromParcelLocked(in); 10906 mBluetoothScanNesting = 0; 10907 mBluetoothScanTimer.readSummaryFromParcelLocked(in); 10908 10909 int NKW = in.readInt(); 10910 if (NKW > 10000) { 10911 throw new ParcelFormatException("File corrupt: too many kernel wake locks " + NKW); 10912 } 10913 for (int ikw = 0; ikw < NKW; ikw++) { 10914 if (in.readInt() != 0) { 10915 String kwltName = in.readString(); 10916 getKernelWakelockTimerLocked(kwltName).readSummaryFromParcelLocked(in); 10917 } 10918 } 10919 10920 int NWR = in.readInt(); 10921 if (NWR > 10000) { 10922 throw new ParcelFormatException("File corrupt: too many wakeup reasons " + NWR); 10923 } 10924 for (int iwr = 0; iwr < NWR; iwr++) { 10925 if (in.readInt() != 0) { 10926 String reasonName = in.readString(); 10927 getWakeupReasonTimerLocked(reasonName).readSummaryFromParcelLocked(in); 10928 } 10929 } 10930 10931 int NMS = in.readInt(); 10932 for (int ims = 0; ims < NMS; ims++) { 10933 if (in.readInt() != 0) { 10934 long kmstName = in.readLong(); 10935 getKernelMemoryTimerLocked(kmstName).readSummaryFromParcelLocked(in); 10936 } 10937 } 10938 10939 final int NU = in.readInt(); 10940 if (NU > 10000) { 10941 throw new ParcelFormatException("File corrupt: too many uids " + NU); 10942 } 10943 for (int iu = 0; iu < NU; iu++) { 10944 int uid = in.readInt(); 10945 Uid u = new Uid(this, uid); 10946 mUidStats.put(uid, u); 10947 10948 u.mOnBatteryBackgroundTimeBase.readSummaryFromParcel(in); 10949 10950 u.mWifiRunning = false; 10951 if (in.readInt() != 0) { 10952 u.mWifiRunningTimer.readSummaryFromParcelLocked(in); 10953 } 10954 u.mFullWifiLockOut = false; 10955 if (in.readInt() != 0) { 10956 u.mFullWifiLockTimer.readSummaryFromParcelLocked(in); 10957 } 10958 u.mWifiScanStarted = false; 10959 if (in.readInt() != 0) { 10960 u.mWifiScanTimer.readSummaryFromParcelLocked(in); 10961 } 10962 u.mWifiBatchedScanBinStarted = Uid.NO_BATCHED_SCAN_STARTED; 10963 for (int i = 0; i < Uid.NUM_WIFI_BATCHED_SCAN_BINS; i++) { 10964 if (in.readInt() != 0) { 10965 u.makeWifiBatchedScanBin(i, null); 10966 u.mWifiBatchedScanTimer[i].readSummaryFromParcelLocked(in); 10967 } 10968 } 10969 u.mWifiMulticastEnabled = false; 10970 if (in.readInt() != 0) { 10971 u.mWifiMulticastTimer.readSummaryFromParcelLocked(in); 10972 } 10973 if (in.readInt() != 0) { 10974 u.createAudioTurnedOnTimerLocked().readSummaryFromParcelLocked(in); 10975 } 10976 if (in.readInt() != 0) { 10977 u.createVideoTurnedOnTimerLocked().readSummaryFromParcelLocked(in); 10978 } 10979 if (in.readInt() != 0) { 10980 u.createFlashlightTurnedOnTimerLocked().readSummaryFromParcelLocked(in); 10981 } 10982 if (in.readInt() != 0) { 10983 u.createCameraTurnedOnTimerLocked().readSummaryFromParcelLocked(in); 10984 } 10985 if (in.readInt() != 0) { 10986 u.createForegroundActivityTimerLocked().readSummaryFromParcelLocked(in); 10987 } 10988 if (in.readInt() != 0) { 10989 u.createBluetoothScanTimerLocked().readSummaryFromParcelLocked(in); 10990 } 10991 u.mProcessState = ActivityManager.PROCESS_STATE_NONEXISTENT; 10992 for (int i = 0; i < Uid.NUM_PROCESS_STATE; i++) { 10993 if (in.readInt() != 0) { 10994 u.makeProcessState(i, null); 10995 u.mProcessStateTimer[i].readSummaryFromParcelLocked(in); 10996 } 10997 } 10998 if (in.readInt() != 0) { 10999 u.createVibratorOnTimerLocked().readSummaryFromParcelLocked(in); 11000 } 11001 11002 if (in.readInt() != 0) { 11003 if (u.mUserActivityCounters == null) { 11004 u.initUserActivityLocked(); 11005 } 11006 for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) { 11007 u.mUserActivityCounters[i].readSummaryFromParcelLocked(in); 11008 } 11009 } 11010 11011 if (in.readInt() != 0) { 11012 if (u.mNetworkByteActivityCounters == null) { 11013 u.initNetworkActivityLocked(); 11014 } 11015 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 11016 u.mNetworkByteActivityCounters[i].readSummaryFromParcelLocked(in); 11017 u.mNetworkPacketActivityCounters[i].readSummaryFromParcelLocked(in); 11018 } 11019 u.mMobileRadioActiveTime.readSummaryFromParcelLocked(in); 11020 u.mMobileRadioActiveCount.readSummaryFromParcelLocked(in); 11021 } 11022 11023 u.mUserCpuTime.readSummaryFromParcelLocked(in); 11024 u.mSystemCpuTime.readSummaryFromParcelLocked(in); 11025 11026 if (in.readInt() != 0) { 11027 final int numClusters = in.readInt(); 11028 if (mPowerProfile != null && mPowerProfile.getNumCpuClusters() != numClusters) { 11029 throw new ParcelFormatException("Incompatible cpu cluster arrangement"); 11030 } 11031 11032 u.mCpuClusterSpeed = new LongSamplingCounter[numClusters][]; 11033 for (int cluster = 0; cluster < numClusters; cluster++) { 11034 if (in.readInt() != 0) { 11035 final int NSB = in.readInt(); 11036 if (mPowerProfile != null && 11037 mPowerProfile.getNumSpeedStepsInCpuCluster(cluster) != NSB) { 11038 throw new ParcelFormatException("File corrupt: too many speed bins " + 11039 NSB); 11040 } 11041 11042 u.mCpuClusterSpeed[cluster] = new LongSamplingCounter[NSB]; 11043 for (int speed = 0; speed < NSB; speed++) { 11044 if (in.readInt() != 0) { 11045 u.mCpuClusterSpeed[cluster][speed] = new LongSamplingCounter( 11046 mOnBatteryTimeBase); 11047 u.mCpuClusterSpeed[cluster][speed].readSummaryFromParcelLocked(in); 11048 } 11049 } 11050 } else { 11051 u.mCpuClusterSpeed[cluster] = null; 11052 } 11053 } 11054 } else { 11055 u.mCpuClusterSpeed = null; 11056 } 11057 11058 if (in.readInt() != 0) { 11059 u.mMobileRadioApWakeupCount = new LongSamplingCounter(mOnBatteryTimeBase); 11060 u.mMobileRadioApWakeupCount.readSummaryFromParcelLocked(in); 11061 } else { 11062 u.mMobileRadioApWakeupCount = null; 11063 } 11064 11065 if (in.readInt() != 0) { 11066 u.mWifiRadioApWakeupCount = new LongSamplingCounter(mOnBatteryTimeBase); 11067 u.mWifiRadioApWakeupCount.readSummaryFromParcelLocked(in); 11068 } else { 11069 u.mWifiRadioApWakeupCount = null; 11070 } 11071 11072 int NW = in.readInt(); 11073 if (NW > (MAX_WAKELOCKS_PER_UID+1)) { 11074 throw new ParcelFormatException("File corrupt: too many wake locks " + NW); 11075 } 11076 for (int iw = 0; iw < NW; iw++) { 11077 String wlName = in.readString(); 11078 u.readWakeSummaryFromParcelLocked(wlName, in); 11079 } 11080 11081 int NS = in.readInt(); 11082 if (NS > (MAX_WAKELOCKS_PER_UID+1)) { 11083 throw new ParcelFormatException("File corrupt: too many syncs " + NS); 11084 } 11085 for (int is = 0; is < NS; is++) { 11086 String name = in.readString(); 11087 u.readSyncSummaryFromParcelLocked(name, in); 11088 } 11089 11090 int NJ = in.readInt(); 11091 if (NJ > (MAX_WAKELOCKS_PER_UID+1)) { 11092 throw new ParcelFormatException("File corrupt: too many job timers " + NJ); 11093 } 11094 for (int ij = 0; ij < NJ; ij++) { 11095 String name = in.readString(); 11096 u.readJobSummaryFromParcelLocked(name, in); 11097 } 11098 11099 int NP = in.readInt(); 11100 if (NP > 1000) { 11101 throw new ParcelFormatException("File corrupt: too many sensors " + NP); 11102 } 11103 for (int is = 0; is < NP; is++) { 11104 int seNumber = in.readInt(); 11105 if (in.readInt() != 0) { 11106 u.getSensorTimerLocked(seNumber, true).readSummaryFromParcelLocked(in); 11107 } 11108 } 11109 11110 NP = in.readInt(); 11111 if (NP > 1000) { 11112 throw new ParcelFormatException("File corrupt: too many processes " + NP); 11113 } 11114 for (int ip = 0; ip < NP; ip++) { 11115 String procName = in.readString(); 11116 Uid.Proc p = u.getProcessStatsLocked(procName); 11117 p.mUserTime = p.mLoadedUserTime = in.readLong(); 11118 p.mSystemTime = p.mLoadedSystemTime = in.readLong(); 11119 p.mForegroundTime = p.mLoadedForegroundTime = in.readLong(); 11120 p.mStarts = p.mLoadedStarts = in.readInt(); 11121 p.mNumCrashes = p.mLoadedNumCrashes = in.readInt(); 11122 p.mNumAnrs = p.mLoadedNumAnrs = in.readInt(); 11123 p.readExcessivePowerFromParcelLocked(in); 11124 } 11125 11126 NP = in.readInt(); 11127 if (NP > 10000) { 11128 throw new ParcelFormatException("File corrupt: too many packages " + NP); 11129 } 11130 for (int ip = 0; ip < NP; ip++) { 11131 String pkgName = in.readString(); 11132 Uid.Pkg p = u.getPackageStatsLocked(pkgName); 11133 final int NWA = in.readInt(); 11134 if (NWA > 1000) { 11135 throw new ParcelFormatException("File corrupt: too many wakeup alarms " + NWA); 11136 } 11137 p.mWakeupAlarms.clear(); 11138 for (int iwa=0; iwa<NWA; iwa++) { 11139 String tag = in.readString(); 11140 Counter c = new Counter(mOnBatteryTimeBase); 11141 c.readSummaryFromParcelLocked(in); 11142 p.mWakeupAlarms.put(tag, c); 11143 } 11144 NS = in.readInt(); 11145 if (NS > 1000) { 11146 throw new ParcelFormatException("File corrupt: too many services " + NS); 11147 } 11148 for (int is = 0; is < NS; is++) { 11149 String servName = in.readString(); 11150 Uid.Pkg.Serv s = u.getServiceStatsLocked(pkgName, servName); 11151 s.mStartTime = s.mLoadedStartTime = in.readLong(); 11152 s.mStarts = s.mLoadedStarts = in.readInt(); 11153 s.mLaunches = s.mLoadedLaunches = in.readInt(); 11154 } 11155 } 11156 } 11157 } 11158 11159 /** 11160 * Writes a summary of the statistics to a Parcel, in a format suitable to be written to 11161 * disk. This format does not allow a lossless round-trip. 11162 * 11163 * @param out the Parcel to be written to. 11164 */ 11165 public void writeSummaryToParcel(Parcel out, boolean inclHistory) { 11166 pullPendingStateUpdatesLocked(); 11167 11168 // Pull the clock time. This may update the time and make a new history entry 11169 // if we had originally pulled a time before the RTC was set. 11170 long startClockTime = getStartClockTime(); 11171 11172 final long NOW_SYS = mClocks.uptimeMillis() * 1000; 11173 final long NOWREAL_SYS = mClocks.elapsedRealtime() * 1000; 11174 11175 out.writeInt(VERSION); 11176 11177 writeHistory(out, inclHistory, true); 11178 11179 out.writeInt(mStartCount); 11180 out.writeLong(computeUptime(NOW_SYS, STATS_SINCE_CHARGED)); 11181 out.writeLong(computeRealtime(NOWREAL_SYS, STATS_SINCE_CHARGED)); 11182 out.writeLong(startClockTime); 11183 out.writeString(mStartPlatformVersion); 11184 out.writeString(mEndPlatformVersion); 11185 mOnBatteryTimeBase.writeSummaryToParcel(out, NOW_SYS, NOWREAL_SYS); 11186 mOnBatteryScreenOffTimeBase.writeSummaryToParcel(out, NOW_SYS, NOWREAL_SYS); 11187 out.writeInt(mDischargeUnplugLevel); 11188 out.writeInt(mDischargePlugLevel); 11189 out.writeInt(mDischargeCurrentLevel); 11190 out.writeInt(mCurrentBatteryLevel); 11191 out.writeInt(mEstimatedBatteryCapacity); 11192 out.writeInt(getLowDischargeAmountSinceCharge()); 11193 out.writeInt(getHighDischargeAmountSinceCharge()); 11194 out.writeInt(getDischargeAmountScreenOnSinceCharge()); 11195 out.writeInt(getDischargeAmountScreenOffSinceCharge()); 11196 mDischargeStepTracker.writeToParcel(out); 11197 mChargeStepTracker.writeToParcel(out); 11198 mDailyDischargeStepTracker.writeToParcel(out); 11199 mDailyChargeStepTracker.writeToParcel(out); 11200 mDischargeCounter.writeSummaryFromParcelLocked(out); 11201 mDischargeScreenOffCounter.writeSummaryFromParcelLocked(out); 11202 if (mDailyPackageChanges != null) { 11203 final int NPKG = mDailyPackageChanges.size(); 11204 out.writeInt(NPKG); 11205 for (int i=0; i<NPKG; i++) { 11206 PackageChange pc = mDailyPackageChanges.get(i); 11207 out.writeString(pc.mPackageName); 11208 out.writeInt(pc.mUpdate ? 1 : 0); 11209 out.writeInt(pc.mVersionCode); 11210 } 11211 } else { 11212 out.writeInt(0); 11213 } 11214 out.writeLong(mDailyStartTime); 11215 out.writeLong(mNextMinDailyDeadline); 11216 out.writeLong(mNextMaxDailyDeadline); 11217 11218 mScreenOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 11219 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 11220 mScreenBrightnessTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS); 11221 } 11222 mInteractiveTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 11223 mPowerSaveModeEnabledTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 11224 out.writeLong(mLongestLightIdleTime); 11225 out.writeLong(mLongestFullIdleTime); 11226 mDeviceIdleModeLightTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 11227 mDeviceIdleModeFullTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 11228 mDeviceLightIdlingTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 11229 mDeviceIdlingTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 11230 mPhoneOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 11231 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) { 11232 mPhoneSignalStrengthsTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS); 11233 } 11234 mPhoneSignalScanningTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 11235 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 11236 mPhoneDataConnectionsTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS); 11237 } 11238 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 11239 mNetworkByteActivityCounters[i].writeSummaryFromParcelLocked(out); 11240 mNetworkPacketActivityCounters[i].writeSummaryFromParcelLocked(out); 11241 } 11242 mMobileRadioActiveTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 11243 mMobileRadioActivePerAppTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 11244 mMobileRadioActiveAdjustedTime.writeSummaryFromParcelLocked(out); 11245 mMobileRadioActiveUnknownTime.writeSummaryFromParcelLocked(out); 11246 mMobileRadioActiveUnknownCount.writeSummaryFromParcelLocked(out); 11247 mWifiOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 11248 mGlobalWifiRunningTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 11249 for (int i=0; i<NUM_WIFI_STATES; i++) { 11250 mWifiStateTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS); 11251 } 11252 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) { 11253 mWifiSupplStateTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS); 11254 } 11255 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { 11256 mWifiSignalStrengthsTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS); 11257 } 11258 mWifiActivity.writeSummaryToParcel(out); 11259 mBluetoothActivity.writeSummaryToParcel(out); 11260 mModemActivity.writeSummaryToParcel(out); 11261 out.writeInt(mHasWifiReporting ? 1 : 0); 11262 out.writeInt(mHasBluetoothReporting ? 1 : 0); 11263 out.writeInt(mHasModemReporting ? 1 : 0); 11264 11265 out.writeInt(mNumConnectivityChange); 11266 mFlashlightOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 11267 mCameraOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 11268 mBluetoothScanTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 11269 11270 out.writeInt(mKernelWakelockStats.size()); 11271 for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) { 11272 Timer kwlt = ent.getValue(); 11273 if (kwlt != null) { 11274 out.writeInt(1); 11275 out.writeString(ent.getKey()); 11276 kwlt.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 11277 } else { 11278 out.writeInt(0); 11279 } 11280 } 11281 11282 out.writeInt(mWakeupReasonStats.size()); 11283 for (Map.Entry<String, SamplingTimer> ent : mWakeupReasonStats.entrySet()) { 11284 SamplingTimer timer = ent.getValue(); 11285 if (timer != null) { 11286 out.writeInt(1); 11287 out.writeString(ent.getKey()); 11288 timer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 11289 } else { 11290 out.writeInt(0); 11291 } 11292 } 11293 11294 out.writeInt(mKernelMemoryStats.size()); 11295 for (int i = 0; i < mKernelMemoryStats.size(); i++) { 11296 Timer kmt = mKernelMemoryStats.valueAt(i); 11297 if (kmt != null) { 11298 out.writeInt(1); 11299 out.writeLong(mKernelMemoryStats.keyAt(i)); 11300 kmt.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 11301 } else { 11302 out.writeInt(0); 11303 } 11304 } 11305 11306 final int NU = mUidStats.size(); 11307 out.writeInt(NU); 11308 for (int iu = 0; iu < NU; iu++) { 11309 out.writeInt(mUidStats.keyAt(iu)); 11310 Uid u = mUidStats.valueAt(iu); 11311 11312 u.mOnBatteryBackgroundTimeBase.writeSummaryToParcel(out, NOW_SYS, NOWREAL_SYS); 11313 11314 if (u.mWifiRunningTimer != null) { 11315 out.writeInt(1); 11316 u.mWifiRunningTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 11317 } else { 11318 out.writeInt(0); 11319 } 11320 if (u.mFullWifiLockTimer != null) { 11321 out.writeInt(1); 11322 u.mFullWifiLockTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 11323 } else { 11324 out.writeInt(0); 11325 } 11326 if (u.mWifiScanTimer != null) { 11327 out.writeInt(1); 11328 u.mWifiScanTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 11329 } else { 11330 out.writeInt(0); 11331 } 11332 for (int i = 0; i < Uid.NUM_WIFI_BATCHED_SCAN_BINS; i++) { 11333 if (u.mWifiBatchedScanTimer[i] != null) { 11334 out.writeInt(1); 11335 u.mWifiBatchedScanTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS); 11336 } else { 11337 out.writeInt(0); 11338 } 11339 } 11340 if (u.mWifiMulticastTimer != null) { 11341 out.writeInt(1); 11342 u.mWifiMulticastTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 11343 } else { 11344 out.writeInt(0); 11345 } 11346 if (u.mAudioTurnedOnTimer != null) { 11347 out.writeInt(1); 11348 u.mAudioTurnedOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 11349 } else { 11350 out.writeInt(0); 11351 } 11352 if (u.mVideoTurnedOnTimer != null) { 11353 out.writeInt(1); 11354 u.mVideoTurnedOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 11355 } else { 11356 out.writeInt(0); 11357 } 11358 if (u.mFlashlightTurnedOnTimer != null) { 11359 out.writeInt(1); 11360 u.mFlashlightTurnedOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 11361 } else { 11362 out.writeInt(0); 11363 } 11364 if (u.mCameraTurnedOnTimer != null) { 11365 out.writeInt(1); 11366 u.mCameraTurnedOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 11367 } else { 11368 out.writeInt(0); 11369 } 11370 if (u.mForegroundActivityTimer != null) { 11371 out.writeInt(1); 11372 u.mForegroundActivityTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 11373 } else { 11374 out.writeInt(0); 11375 } 11376 if (u.mBluetoothScanTimer != null) { 11377 out.writeInt(1); 11378 u.mBluetoothScanTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 11379 } else { 11380 out.writeInt(0); 11381 } 11382 for (int i = 0; i < Uid.NUM_PROCESS_STATE; i++) { 11383 if (u.mProcessStateTimer[i] != null) { 11384 out.writeInt(1); 11385 u.mProcessStateTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS); 11386 } else { 11387 out.writeInt(0); 11388 } 11389 } 11390 if (u.mVibratorOnTimer != null) { 11391 out.writeInt(1); 11392 u.mVibratorOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 11393 } else { 11394 out.writeInt(0); 11395 } 11396 11397 if (u.mUserActivityCounters == null) { 11398 out.writeInt(0); 11399 } else { 11400 out.writeInt(1); 11401 for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) { 11402 u.mUserActivityCounters[i].writeSummaryFromParcelLocked(out); 11403 } 11404 } 11405 11406 if (u.mNetworkByteActivityCounters == null) { 11407 out.writeInt(0); 11408 } else { 11409 out.writeInt(1); 11410 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 11411 u.mNetworkByteActivityCounters[i].writeSummaryFromParcelLocked(out); 11412 u.mNetworkPacketActivityCounters[i].writeSummaryFromParcelLocked(out); 11413 } 11414 u.mMobileRadioActiveTime.writeSummaryFromParcelLocked(out); 11415 u.mMobileRadioActiveCount.writeSummaryFromParcelLocked(out); 11416 } 11417 11418 u.mUserCpuTime.writeSummaryFromParcelLocked(out); 11419 u.mSystemCpuTime.writeSummaryFromParcelLocked(out); 11420 11421 if (u.mCpuClusterSpeed != null) { 11422 out.writeInt(1); 11423 out.writeInt(u.mCpuClusterSpeed.length); 11424 for (LongSamplingCounter[] cpuSpeeds : u.mCpuClusterSpeed) { 11425 if (cpuSpeeds != null) { 11426 out.writeInt(1); 11427 out.writeInt(cpuSpeeds.length); 11428 for (LongSamplingCounter c : cpuSpeeds) { 11429 if (c != null) { 11430 out.writeInt(1); 11431 c.writeSummaryFromParcelLocked(out); 11432 } else { 11433 out.writeInt(0); 11434 } 11435 } 11436 } else { 11437 out.writeInt(0); 11438 } 11439 } 11440 } else { 11441 out.writeInt(0); 11442 } 11443 11444 if (u.mMobileRadioApWakeupCount != null) { 11445 out.writeInt(1); 11446 u.mMobileRadioApWakeupCount.writeSummaryFromParcelLocked(out); 11447 } else { 11448 out.writeInt(0); 11449 } 11450 11451 if (u.mWifiRadioApWakeupCount != null) { 11452 out.writeInt(1); 11453 u.mWifiRadioApWakeupCount.writeSummaryFromParcelLocked(out); 11454 } else { 11455 out.writeInt(0); 11456 } 11457 11458 final ArrayMap<String, Uid.Wakelock> wakeStats = u.mWakelockStats.getMap(); 11459 int NW = wakeStats.size(); 11460 out.writeInt(NW); 11461 for (int iw=0; iw<NW; iw++) { 11462 out.writeString(wakeStats.keyAt(iw)); 11463 Uid.Wakelock wl = wakeStats.valueAt(iw); 11464 if (wl.mTimerFull != null) { 11465 out.writeInt(1); 11466 wl.mTimerFull.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 11467 } else { 11468 out.writeInt(0); 11469 } 11470 if (wl.mTimerPartial != null) { 11471 out.writeInt(1); 11472 wl.mTimerPartial.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 11473 } else { 11474 out.writeInt(0); 11475 } 11476 if (wl.mTimerWindow != null) { 11477 out.writeInt(1); 11478 wl.mTimerWindow.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 11479 } else { 11480 out.writeInt(0); 11481 } 11482 if (wl.mTimerDraw != null) { 11483 out.writeInt(1); 11484 wl.mTimerDraw.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 11485 } else { 11486 out.writeInt(0); 11487 } 11488 } 11489 11490 final ArrayMap<String, StopwatchTimer> syncStats = u.mSyncStats.getMap(); 11491 int NS = syncStats.size(); 11492 out.writeInt(NS); 11493 for (int is=0; is<NS; is++) { 11494 out.writeString(syncStats.keyAt(is)); 11495 syncStats.valueAt(is).writeSummaryFromParcelLocked(out, NOWREAL_SYS); 11496 } 11497 11498 final ArrayMap<String, DualTimer> jobStats = u.mJobStats.getMap(); 11499 int NJ = jobStats.size(); 11500 out.writeInt(NJ); 11501 for (int ij=0; ij<NJ; ij++) { 11502 out.writeString(jobStats.keyAt(ij)); 11503 jobStats.valueAt(ij).writeSummaryFromParcelLocked(out, NOWREAL_SYS); 11504 } 11505 11506 int NSE = u.mSensorStats.size(); 11507 out.writeInt(NSE); 11508 for (int ise=0; ise<NSE; ise++) { 11509 out.writeInt(u.mSensorStats.keyAt(ise)); 11510 Uid.Sensor se = u.mSensorStats.valueAt(ise); 11511 if (se.mTimer != null) { 11512 out.writeInt(1); 11513 se.mTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 11514 } else { 11515 out.writeInt(0); 11516 } 11517 } 11518 11519 int NP = u.mProcessStats.size(); 11520 out.writeInt(NP); 11521 for (int ip=0; ip<NP; ip++) { 11522 out.writeString(u.mProcessStats.keyAt(ip)); 11523 Uid.Proc ps = u.mProcessStats.valueAt(ip); 11524 out.writeLong(ps.mUserTime); 11525 out.writeLong(ps.mSystemTime); 11526 out.writeLong(ps.mForegroundTime); 11527 out.writeInt(ps.mStarts); 11528 out.writeInt(ps.mNumCrashes); 11529 out.writeInt(ps.mNumAnrs); 11530 ps.writeExcessivePowerToParcelLocked(out); 11531 } 11532 11533 NP = u.mPackageStats.size(); 11534 out.writeInt(NP); 11535 if (NP > 0) { 11536 for (Map.Entry<String, BatteryStatsImpl.Uid.Pkg> ent 11537 : u.mPackageStats.entrySet()) { 11538 out.writeString(ent.getKey()); 11539 Uid.Pkg ps = ent.getValue(); 11540 final int NWA = ps.mWakeupAlarms.size(); 11541 out.writeInt(NWA); 11542 for (int iwa=0; iwa<NWA; iwa++) { 11543 out.writeString(ps.mWakeupAlarms.keyAt(iwa)); 11544 ps.mWakeupAlarms.valueAt(iwa).writeSummaryFromParcelLocked(out); 11545 } 11546 NS = ps.mServiceStats.size(); 11547 out.writeInt(NS); 11548 for (int is=0; is<NS; is++) { 11549 out.writeString(ps.mServiceStats.keyAt(is)); 11550 BatteryStatsImpl.Uid.Pkg.Serv ss = ps.mServiceStats.valueAt(is); 11551 long time = ss.getStartTimeToNowLocked( 11552 mOnBatteryTimeBase.getUptime(NOW_SYS)); 11553 out.writeLong(time); 11554 out.writeInt(ss.mStarts); 11555 out.writeInt(ss.mLaunches); 11556 } 11557 } 11558 } 11559 } 11560 } 11561 11562 public void readFromParcel(Parcel in) { 11563 readFromParcelLocked(in); 11564 } 11565 11566 void readFromParcelLocked(Parcel in) { 11567 int magic = in.readInt(); 11568 if (magic != MAGIC) { 11569 throw new ParcelFormatException("Bad magic number: #" + Integer.toHexString(magic)); 11570 } 11571 11572 readHistory(in, false); 11573 11574 mStartCount = in.readInt(); 11575 mStartClockTime = in.readLong(); 11576 mStartPlatformVersion = in.readString(); 11577 mEndPlatformVersion = in.readString(); 11578 mUptime = in.readLong(); 11579 mUptimeStart = in.readLong(); 11580 mRealtime = in.readLong(); 11581 mRealtimeStart = in.readLong(); 11582 mOnBattery = in.readInt() != 0; 11583 mEstimatedBatteryCapacity = in.readInt(); 11584 mOnBatteryInternal = false; // we are no longer really running. 11585 mOnBatteryTimeBase.readFromParcel(in); 11586 mOnBatteryScreenOffTimeBase.readFromParcel(in); 11587 11588 mScreenState = Display.STATE_UNKNOWN; 11589 mScreenOnTimer = new StopwatchTimer(mClocks, null, -1, null, mOnBatteryTimeBase, in); 11590 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 11591 mScreenBrightnessTimer[i] = new StopwatchTimer(mClocks, null, -100-i, null, 11592 mOnBatteryTimeBase, in); 11593 } 11594 mInteractive = false; 11595 mInteractiveTimer = new StopwatchTimer(mClocks, null, -10, null, mOnBatteryTimeBase, in); 11596 mPhoneOn = false; 11597 mPowerSaveModeEnabledTimer = new StopwatchTimer(mClocks, null, -2, null, 11598 mOnBatteryTimeBase, in); 11599 mLongestLightIdleTime = in.readLong(); 11600 mLongestFullIdleTime = in.readLong(); 11601 mDeviceIdleModeLightTimer = new StopwatchTimer(mClocks, null, -14, null, 11602 mOnBatteryTimeBase, in); 11603 mDeviceIdleModeFullTimer = new StopwatchTimer(mClocks, null, -11, null, 11604 mOnBatteryTimeBase, in); 11605 mDeviceLightIdlingTimer = new StopwatchTimer(mClocks, null, -15, null, 11606 mOnBatteryTimeBase, in); 11607 mDeviceIdlingTimer = new StopwatchTimer(mClocks, null, -12, null, mOnBatteryTimeBase, in); 11608 mPhoneOnTimer = new StopwatchTimer(mClocks, null, -3, null, mOnBatteryTimeBase, in); 11609 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) { 11610 mPhoneSignalStrengthsTimer[i] = new StopwatchTimer(mClocks, null, -200-i, 11611 null, mOnBatteryTimeBase, in); 11612 } 11613 mPhoneSignalScanningTimer = new StopwatchTimer(mClocks, null, -200+1, null, 11614 mOnBatteryTimeBase, in); 11615 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 11616 mPhoneDataConnectionsTimer[i] = new StopwatchTimer(mClocks, null, -300-i, 11617 null, mOnBatteryTimeBase, in); 11618 } 11619 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 11620 mNetworkByteActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase, in); 11621 mNetworkPacketActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase, in); 11622 } 11623 mMobileRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW; 11624 mMobileRadioActiveTimer = new StopwatchTimer(mClocks, null, -400, null, 11625 mOnBatteryTimeBase, in); 11626 mMobileRadioActivePerAppTimer = new StopwatchTimer(mClocks, null, -401, null, 11627 mOnBatteryTimeBase, in); 11628 mMobileRadioActiveAdjustedTime = new LongSamplingCounter(mOnBatteryTimeBase, in); 11629 mMobileRadioActiveUnknownTime = new LongSamplingCounter(mOnBatteryTimeBase, in); 11630 mMobileRadioActiveUnknownCount = new LongSamplingCounter(mOnBatteryTimeBase, in); 11631 mWifiRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW; 11632 mWifiOn = false; 11633 mWifiOnTimer = new StopwatchTimer(mClocks, null, -4, null, mOnBatteryTimeBase, in); 11634 mGlobalWifiRunning = false; 11635 mGlobalWifiRunningTimer = new StopwatchTimer(mClocks, null, -5, null, 11636 mOnBatteryTimeBase, in); 11637 for (int i=0; i<NUM_WIFI_STATES; i++) { 11638 mWifiStateTimer[i] = new StopwatchTimer(mClocks, null, -600-i, 11639 null, mOnBatteryTimeBase, in); 11640 } 11641 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) { 11642 mWifiSupplStateTimer[i] = new StopwatchTimer(mClocks, null, -700-i, 11643 null, mOnBatteryTimeBase, in); 11644 } 11645 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { 11646 mWifiSignalStrengthsTimer[i] = new StopwatchTimer(mClocks, null, -800-i, 11647 null, mOnBatteryTimeBase, in); 11648 } 11649 11650 mWifiActivity = new ControllerActivityCounterImpl(mOnBatteryTimeBase, 11651 NUM_WIFI_TX_LEVELS, in); 11652 mBluetoothActivity = new ControllerActivityCounterImpl(mOnBatteryTimeBase, 11653 NUM_BT_TX_LEVELS, in); 11654 mModemActivity = new ControllerActivityCounterImpl(mOnBatteryTimeBase, 11655 ModemActivityInfo.TX_POWER_LEVELS, in); 11656 mHasWifiReporting = in.readInt() != 0; 11657 mHasBluetoothReporting = in.readInt() != 0; 11658 mHasModemReporting = in.readInt() != 0; 11659 11660 mNumConnectivityChange = in.readInt(); 11661 mLoadedNumConnectivityChange = in.readInt(); 11662 mUnpluggedNumConnectivityChange = in.readInt(); 11663 mAudioOnNesting = 0; 11664 mAudioOnTimer = new StopwatchTimer(mClocks, null, -7, null, mOnBatteryTimeBase); 11665 mVideoOnNesting = 0; 11666 mVideoOnTimer = new StopwatchTimer(mClocks, null, -8, null, mOnBatteryTimeBase); 11667 mFlashlightOnNesting = 0; 11668 mFlashlightOnTimer = new StopwatchTimer(mClocks, null, -9, null, mOnBatteryTimeBase, in); 11669 mCameraOnNesting = 0; 11670 mCameraOnTimer = new StopwatchTimer(mClocks, null, -13, null, mOnBatteryTimeBase, in); 11671 mBluetoothScanNesting = 0; 11672 mBluetoothScanTimer = new StopwatchTimer(mClocks, null, -14, null, mOnBatteryTimeBase, in); 11673 mDischargeUnplugLevel = in.readInt(); 11674 mDischargePlugLevel = in.readInt(); 11675 mDischargeCurrentLevel = in.readInt(); 11676 mCurrentBatteryLevel = in.readInt(); 11677 mLowDischargeAmountSinceCharge = in.readInt(); 11678 mHighDischargeAmountSinceCharge = in.readInt(); 11679 mDischargeAmountScreenOn = in.readInt(); 11680 mDischargeAmountScreenOnSinceCharge = in.readInt(); 11681 mDischargeAmountScreenOff = in.readInt(); 11682 mDischargeAmountScreenOffSinceCharge = in.readInt(); 11683 mDischargeStepTracker.readFromParcel(in); 11684 mChargeStepTracker.readFromParcel(in); 11685 mDischargeCounter = new LongSamplingCounter(mOnBatteryTimeBase, in); 11686 mDischargeScreenOffCounter = new LongSamplingCounter(mOnBatteryTimeBase, in); 11687 mLastWriteTime = in.readLong(); 11688 11689 mKernelWakelockStats.clear(); 11690 int NKW = in.readInt(); 11691 for (int ikw = 0; ikw < NKW; ikw++) { 11692 if (in.readInt() != 0) { 11693 String wakelockName = in.readString(); 11694 SamplingTimer kwlt = new SamplingTimer(mClocks, mOnBatteryScreenOffTimeBase, in); 11695 mKernelWakelockStats.put(wakelockName, kwlt); 11696 } 11697 } 11698 11699 mWakeupReasonStats.clear(); 11700 int NWR = in.readInt(); 11701 for (int iwr = 0; iwr < NWR; iwr++) { 11702 if (in.readInt() != 0) { 11703 String reasonName = in.readString(); 11704 SamplingTimer timer = new SamplingTimer(mClocks, mOnBatteryTimeBase, in); 11705 mWakeupReasonStats.put(reasonName, timer); 11706 } 11707 } 11708 11709 mKernelMemoryStats.clear(); 11710 int nmt = in.readInt(); 11711 for (int imt = 0; imt < nmt; imt++) { 11712 if (in.readInt() != 0) { 11713 Long bucket = in.readLong(); 11714 SamplingTimer kmt = new SamplingTimer(mClocks, mOnBatteryTimeBase, in); 11715 mKernelMemoryStats.put(bucket, kmt); 11716 } 11717 } 11718 11719 mPartialTimers.clear(); 11720 mFullTimers.clear(); 11721 mWindowTimers.clear(); 11722 mWifiRunningTimers.clear(); 11723 mFullWifiLockTimers.clear(); 11724 mWifiScanTimers.clear(); 11725 mWifiBatchedScanTimers.clear(); 11726 mWifiMulticastTimers.clear(); 11727 mAudioTurnedOnTimers.clear(); 11728 mVideoTurnedOnTimers.clear(); 11729 mFlashlightTurnedOnTimers.clear(); 11730 mCameraTurnedOnTimers.clear(); 11731 11732 int numUids = in.readInt(); 11733 mUidStats.clear(); 11734 for (int i = 0; i < numUids; i++) { 11735 int uid = in.readInt(); 11736 Uid u = new Uid(this, uid); 11737 u.readFromParcelLocked(mOnBatteryTimeBase, mOnBatteryScreenOffTimeBase, in); 11738 mUidStats.append(uid, u); 11739 } 11740 } 11741 11742 public void writeToParcel(Parcel out, int flags) { 11743 writeToParcelLocked(out, true, flags); 11744 } 11745 11746 public void writeToParcelWithoutUids(Parcel out, int flags) { 11747 writeToParcelLocked(out, false, flags); 11748 } 11749 11750 @SuppressWarnings("unused") 11751 void writeToParcelLocked(Parcel out, boolean inclUids, int flags) { 11752 // Need to update with current kernel wake lock counts. 11753 pullPendingStateUpdatesLocked(); 11754 11755 // Pull the clock time. This may update the time and make a new history entry 11756 // if we had originally pulled a time before the RTC was set. 11757 long startClockTime = getStartClockTime(); 11758 11759 final long uSecUptime = mClocks.uptimeMillis() * 1000; 11760 final long uSecRealtime = mClocks.elapsedRealtime() * 1000; 11761 final long batteryRealtime = mOnBatteryTimeBase.getRealtime(uSecRealtime); 11762 final long batteryScreenOffRealtime = mOnBatteryScreenOffTimeBase.getRealtime(uSecRealtime); 11763 11764 out.writeInt(MAGIC); 11765 11766 writeHistory(out, true, false); 11767 11768 out.writeInt(mStartCount); 11769 out.writeLong(startClockTime); 11770 out.writeString(mStartPlatformVersion); 11771 out.writeString(mEndPlatformVersion); 11772 out.writeLong(mUptime); 11773 out.writeLong(mUptimeStart); 11774 out.writeLong(mRealtime); 11775 out.writeLong(mRealtimeStart); 11776 out.writeInt(mOnBattery ? 1 : 0); 11777 out.writeInt(mEstimatedBatteryCapacity); 11778 mOnBatteryTimeBase.writeToParcel(out, uSecUptime, uSecRealtime); 11779 mOnBatteryScreenOffTimeBase.writeToParcel(out, uSecUptime, uSecRealtime); 11780 11781 mScreenOnTimer.writeToParcel(out, uSecRealtime); 11782 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 11783 mScreenBrightnessTimer[i].writeToParcel(out, uSecRealtime); 11784 } 11785 mInteractiveTimer.writeToParcel(out, uSecRealtime); 11786 mPowerSaveModeEnabledTimer.writeToParcel(out, uSecRealtime); 11787 out.writeLong(mLongestLightIdleTime); 11788 out.writeLong(mLongestFullIdleTime); 11789 mDeviceIdleModeLightTimer.writeToParcel(out, uSecRealtime); 11790 mDeviceIdleModeFullTimer.writeToParcel(out, uSecRealtime); 11791 mDeviceLightIdlingTimer.writeToParcel(out, uSecRealtime); 11792 mDeviceIdlingTimer.writeToParcel(out, uSecRealtime); 11793 mPhoneOnTimer.writeToParcel(out, uSecRealtime); 11794 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) { 11795 mPhoneSignalStrengthsTimer[i].writeToParcel(out, uSecRealtime); 11796 } 11797 mPhoneSignalScanningTimer.writeToParcel(out, uSecRealtime); 11798 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 11799 mPhoneDataConnectionsTimer[i].writeToParcel(out, uSecRealtime); 11800 } 11801 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 11802 mNetworkByteActivityCounters[i].writeToParcel(out); 11803 mNetworkPacketActivityCounters[i].writeToParcel(out); 11804 } 11805 mMobileRadioActiveTimer.writeToParcel(out, uSecRealtime); 11806 mMobileRadioActivePerAppTimer.writeToParcel(out, uSecRealtime); 11807 mMobileRadioActiveAdjustedTime.writeToParcel(out); 11808 mMobileRadioActiveUnknownTime.writeToParcel(out); 11809 mMobileRadioActiveUnknownCount.writeToParcel(out); 11810 mWifiOnTimer.writeToParcel(out, uSecRealtime); 11811 mGlobalWifiRunningTimer.writeToParcel(out, uSecRealtime); 11812 for (int i=0; i<NUM_WIFI_STATES; i++) { 11813 mWifiStateTimer[i].writeToParcel(out, uSecRealtime); 11814 } 11815 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) { 11816 mWifiSupplStateTimer[i].writeToParcel(out, uSecRealtime); 11817 } 11818 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { 11819 mWifiSignalStrengthsTimer[i].writeToParcel(out, uSecRealtime); 11820 } 11821 mWifiActivity.writeToParcel(out, 0); 11822 mBluetoothActivity.writeToParcel(out, 0); 11823 mModemActivity.writeToParcel(out, 0); 11824 out.writeInt(mHasWifiReporting ? 1 : 0); 11825 out.writeInt(mHasBluetoothReporting ? 1 : 0); 11826 out.writeInt(mHasModemReporting ? 1 : 0); 11827 11828 out.writeInt(mNumConnectivityChange); 11829 out.writeInt(mLoadedNumConnectivityChange); 11830 out.writeInt(mUnpluggedNumConnectivityChange); 11831 mFlashlightOnTimer.writeToParcel(out, uSecRealtime); 11832 mCameraOnTimer.writeToParcel(out, uSecRealtime); 11833 mBluetoothScanTimer.writeToParcel(out, uSecRealtime); 11834 out.writeInt(mDischargeUnplugLevel); 11835 out.writeInt(mDischargePlugLevel); 11836 out.writeInt(mDischargeCurrentLevel); 11837 out.writeInt(mCurrentBatteryLevel); 11838 out.writeInt(mLowDischargeAmountSinceCharge); 11839 out.writeInt(mHighDischargeAmountSinceCharge); 11840 out.writeInt(mDischargeAmountScreenOn); 11841 out.writeInt(mDischargeAmountScreenOnSinceCharge); 11842 out.writeInt(mDischargeAmountScreenOff); 11843 out.writeInt(mDischargeAmountScreenOffSinceCharge); 11844 mDischargeStepTracker.writeToParcel(out); 11845 mChargeStepTracker.writeToParcel(out); 11846 mDischargeCounter.writeToParcel(out); 11847 mDischargeScreenOffCounter.writeToParcel(out); 11848 out.writeLong(mLastWriteTime); 11849 11850 if (inclUids) { 11851 out.writeInt(mKernelWakelockStats.size()); 11852 for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) { 11853 SamplingTimer kwlt = ent.getValue(); 11854 if (kwlt != null) { 11855 out.writeInt(1); 11856 out.writeString(ent.getKey()); 11857 kwlt.writeToParcel(out, uSecRealtime); 11858 } else { 11859 out.writeInt(0); 11860 } 11861 } 11862 out.writeInt(mWakeupReasonStats.size()); 11863 for (Map.Entry<String, SamplingTimer> ent : mWakeupReasonStats.entrySet()) { 11864 SamplingTimer timer = ent.getValue(); 11865 if (timer != null) { 11866 out.writeInt(1); 11867 out.writeString(ent.getKey()); 11868 timer.writeToParcel(out, uSecRealtime); 11869 } else { 11870 out.writeInt(0); 11871 } 11872 } 11873 } else { 11874 out.writeInt(0); 11875 } 11876 11877 out.writeInt(mKernelMemoryStats.size()); 11878 for (int i = 0; i < mKernelMemoryStats.size(); i++) { 11879 SamplingTimer kmt = mKernelMemoryStats.valueAt(i); 11880 if (kmt != null) { 11881 out.writeInt(1); 11882 out.writeLong(mKernelMemoryStats.keyAt(i)); 11883 kmt.writeToParcel(out, uSecRealtime); 11884 } else { 11885 out.writeInt(0); 11886 } 11887 } 11888 11889 if (inclUids) { 11890 int size = mUidStats.size(); 11891 out.writeInt(size); 11892 for (int i = 0; i < size; i++) { 11893 out.writeInt(mUidStats.keyAt(i)); 11894 Uid uid = mUidStats.valueAt(i); 11895 11896 uid.writeToParcelLocked(out, uSecUptime, uSecRealtime); 11897 } 11898 } else { 11899 out.writeInt(0); 11900 } 11901 } 11902 11903 public static final Parcelable.Creator<BatteryStatsImpl> CREATOR = 11904 new Parcelable.Creator<BatteryStatsImpl>() { 11905 public BatteryStatsImpl createFromParcel(Parcel in) { 11906 return new BatteryStatsImpl(in); 11907 } 11908 11909 public BatteryStatsImpl[] newArray(int size) { 11910 return new BatteryStatsImpl[size]; 11911 } 11912 }; 11913 11914 public void prepareForDumpLocked() { 11915 // Need to retrieve current kernel wake lock stats before printing. 11916 pullPendingStateUpdatesLocked(); 11917 11918 // Pull the clock time. This may update the time and make a new history entry 11919 // if we had originally pulled a time before the RTC was set. 11920 getStartClockTime(); 11921 } 11922 11923 public void dumpLocked(Context context, PrintWriter pw, int flags, int reqUid, long histStart) { 11924 if (DEBUG) { 11925 pw.println("mOnBatteryTimeBase:"); 11926 mOnBatteryTimeBase.dump(pw, " "); 11927 pw.println("mOnBatteryScreenOffTimeBase:"); 11928 mOnBatteryScreenOffTimeBase.dump(pw, " "); 11929 Printer pr = new PrintWriterPrinter(pw); 11930 pr.println("*** Screen timer:"); 11931 mScreenOnTimer.logState(pr, " "); 11932 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 11933 pr.println("*** Screen brightness #" + i + ":"); 11934 mScreenBrightnessTimer[i].logState(pr, " "); 11935 } 11936 pr.println("*** Interactive timer:"); 11937 mInteractiveTimer.logState(pr, " "); 11938 pr.println("*** Power save mode timer:"); 11939 mPowerSaveModeEnabledTimer.logState(pr, " "); 11940 pr.println("*** Device idle mode light timer:"); 11941 mDeviceIdleModeLightTimer.logState(pr, " "); 11942 pr.println("*** Device idle mode full timer:"); 11943 mDeviceIdleModeFullTimer.logState(pr, " "); 11944 pr.println("*** Device light idling timer:"); 11945 mDeviceLightIdlingTimer.logState(pr, " "); 11946 pr.println("*** Device idling timer:"); 11947 mDeviceIdlingTimer.logState(pr, " "); 11948 pr.println("*** Phone timer:"); 11949 mPhoneOnTimer.logState(pr, " "); 11950 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) { 11951 pr.println("*** Phone signal strength #" + i + ":"); 11952 mPhoneSignalStrengthsTimer[i].logState(pr, " "); 11953 } 11954 pr.println("*** Signal scanning :"); 11955 mPhoneSignalScanningTimer.logState(pr, " "); 11956 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 11957 pr.println("*** Data connection type #" + i + ":"); 11958 mPhoneDataConnectionsTimer[i].logState(pr, " "); 11959 } 11960 pr.println("*** mMobileRadioPowerState=" + mMobileRadioPowerState); 11961 pr.println("*** Mobile network active timer:"); 11962 mMobileRadioActiveTimer.logState(pr, " "); 11963 pr.println("*** Mobile network active adjusted timer:"); 11964 mMobileRadioActiveAdjustedTime.logState(pr, " "); 11965 pr.println("*** mWifiRadioPowerState=" + mWifiRadioPowerState); 11966 pr.println("*** Wifi timer:"); 11967 mWifiOnTimer.logState(pr, " "); 11968 pr.println("*** WifiRunning timer:"); 11969 mGlobalWifiRunningTimer.logState(pr, " "); 11970 for (int i=0; i<NUM_WIFI_STATES; i++) { 11971 pr.println("*** Wifi state #" + i + ":"); 11972 mWifiStateTimer[i].logState(pr, " "); 11973 } 11974 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) { 11975 pr.println("*** Wifi suppl state #" + i + ":"); 11976 mWifiSupplStateTimer[i].logState(pr, " "); 11977 } 11978 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { 11979 pr.println("*** Wifi signal strength #" + i + ":"); 11980 mWifiSignalStrengthsTimer[i].logState(pr, " "); 11981 } 11982 pr.println("*** Flashlight timer:"); 11983 mFlashlightOnTimer.logState(pr, " "); 11984 pr.println("*** Camera timer:"); 11985 mCameraOnTimer.logState(pr, " "); 11986 } 11987 super.dumpLocked(context, pw, flags, reqUid, histStart); 11988 } 11989} 11990