BatteryStatsImpl.java revision 4a3eda992b70601e26a76d9492b2f9381cf0fe51
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 = 153 + (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 mCpuPower; 5467 LongSamplingCounter[][] mCpuClusterSpeed; 5468 5469 /** 5470 * The statistics we have collected for this uid's wake locks. 5471 */ 5472 final OverflowArrayMap<Wakelock> mWakelockStats; 5473 5474 /** 5475 * The statistics we have collected for this uid's syncs. 5476 */ 5477 final OverflowArrayMap<StopwatchTimer> mSyncStats; 5478 5479 /** 5480 * The statistics we have collected for this uid's jobs. 5481 */ 5482 final OverflowArrayMap<DualTimer> mJobStats; 5483 5484 /** 5485 * The statistics we have collected for this uid's sensor activations. 5486 */ 5487 final SparseArray<Sensor> mSensorStats = new SparseArray<>(); 5488 5489 /** 5490 * The statistics we have collected for this uid's processes. 5491 */ 5492 final ArrayMap<String, Proc> mProcessStats = new ArrayMap<>(); 5493 5494 /** 5495 * The statistics we have collected for this uid's processes. 5496 */ 5497 final ArrayMap<String, Pkg> mPackageStats = new ArrayMap<>(); 5498 5499 /** 5500 * The transient wake stats we have collected for this uid's pids. 5501 */ 5502 final SparseArray<Pid> mPids = new SparseArray<>(); 5503 5504 public Uid(BatteryStatsImpl bsi, int uid) { 5505 mBsi = bsi; 5506 mUid = uid; 5507 5508 mOnBatteryBackgroundTimeBase = new TimeBase(); 5509 mOnBatteryBackgroundTimeBase.init(mBsi.mClocks.uptimeMillis() * 1000, 5510 mBsi.mClocks.elapsedRealtime() * 1000); 5511 5512 mUserCpuTime = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); 5513 mSystemCpuTime = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); 5514 mCpuPower = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); 5515 5516 mWakelockStats = mBsi.new OverflowArrayMap<Wakelock>(uid) { 5517 @Override public Wakelock instantiateObject() { 5518 return new Wakelock(mBsi, Uid.this); 5519 } 5520 }; 5521 mSyncStats = mBsi.new OverflowArrayMap<StopwatchTimer>(uid) { 5522 @Override public StopwatchTimer instantiateObject() { 5523 return new StopwatchTimer(mBsi.mClocks, Uid.this, SYNC, null, 5524 mBsi.mOnBatteryTimeBase); 5525 } 5526 }; 5527 mJobStats = mBsi.new OverflowArrayMap<DualTimer>(uid) { 5528 @Override public DualTimer instantiateObject() { 5529 return new DualTimer(mBsi.mClocks, Uid.this, JOB, null, 5530 mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase); 5531 } 5532 }; 5533 5534 mWifiRunningTimer = new StopwatchTimer(mBsi.mClocks, this, WIFI_RUNNING, 5535 mBsi.mWifiRunningTimers, mBsi.mOnBatteryTimeBase); 5536 mFullWifiLockTimer = new StopwatchTimer(mBsi.mClocks, this, FULL_WIFI_LOCK, 5537 mBsi.mFullWifiLockTimers, mBsi.mOnBatteryTimeBase); 5538 mWifiScanTimer = new DualTimer(mBsi.mClocks, this, WIFI_SCAN, 5539 mBsi.mWifiScanTimers, mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase); 5540 mWifiBatchedScanTimer = new StopwatchTimer[NUM_WIFI_BATCHED_SCAN_BINS]; 5541 mWifiMulticastTimer = new StopwatchTimer(mBsi.mClocks, this, WIFI_MULTICAST_ENABLED, 5542 mBsi.mWifiMulticastTimers, mBsi.mOnBatteryTimeBase); 5543 mProcessStateTimer = new StopwatchTimer[NUM_PROCESS_STATE]; 5544 } 5545 5546 @Override 5547 public ArrayMap<String, ? extends BatteryStats.Uid.Wakelock> getWakelockStats() { 5548 return mWakelockStats.getMap(); 5549 } 5550 5551 @Override 5552 public ArrayMap<String, ? extends BatteryStats.Timer> getSyncStats() { 5553 return mSyncStats.getMap(); 5554 } 5555 5556 @Override 5557 public ArrayMap<String, ? extends BatteryStats.Timer> getJobStats() { 5558 return mJobStats.getMap(); 5559 } 5560 5561 @Override 5562 public SparseArray<? extends BatteryStats.Uid.Sensor> getSensorStats() { 5563 return mSensorStats; 5564 } 5565 5566 @Override 5567 public ArrayMap<String, ? extends BatteryStats.Uid.Proc> getProcessStats() { 5568 return mProcessStats; 5569 } 5570 5571 @Override 5572 public ArrayMap<String, ? extends BatteryStats.Uid.Pkg> getPackageStats() { 5573 return mPackageStats; 5574 } 5575 5576 @Override 5577 public int getUid() { 5578 return mUid; 5579 } 5580 5581 @Override 5582 public void noteWifiRunningLocked(long elapsedRealtimeMs) { 5583 if (!mWifiRunning) { 5584 mWifiRunning = true; 5585 if (mWifiRunningTimer == null) { 5586 mWifiRunningTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, WIFI_RUNNING, 5587 mBsi.mWifiRunningTimers, mBsi.mOnBatteryTimeBase); 5588 } 5589 mWifiRunningTimer.startRunningLocked(elapsedRealtimeMs); 5590 } 5591 } 5592 5593 @Override 5594 public void noteWifiStoppedLocked(long elapsedRealtimeMs) { 5595 if (mWifiRunning) { 5596 mWifiRunning = false; 5597 mWifiRunningTimer.stopRunningLocked(elapsedRealtimeMs); 5598 } 5599 } 5600 5601 @Override 5602 public void noteFullWifiLockAcquiredLocked(long elapsedRealtimeMs) { 5603 if (!mFullWifiLockOut) { 5604 mFullWifiLockOut = true; 5605 if (mFullWifiLockTimer == null) { 5606 mFullWifiLockTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, FULL_WIFI_LOCK, 5607 mBsi.mFullWifiLockTimers, mBsi.mOnBatteryTimeBase); 5608 } 5609 mFullWifiLockTimer.startRunningLocked(elapsedRealtimeMs); 5610 } 5611 } 5612 5613 @Override 5614 public void noteFullWifiLockReleasedLocked(long elapsedRealtimeMs) { 5615 if (mFullWifiLockOut) { 5616 mFullWifiLockOut = false; 5617 mFullWifiLockTimer.stopRunningLocked(elapsedRealtimeMs); 5618 } 5619 } 5620 5621 @Override 5622 public void noteWifiScanStartedLocked(long elapsedRealtimeMs) { 5623 if (!mWifiScanStarted) { 5624 mWifiScanStarted = true; 5625 if (mWifiScanTimer == null) { 5626 mWifiScanTimer = new DualTimer(mBsi.mClocks, Uid.this, WIFI_SCAN, 5627 mBsi.mWifiScanTimers, mBsi.mOnBatteryTimeBase, 5628 mOnBatteryBackgroundTimeBase); 5629 } 5630 mWifiScanTimer.startRunningLocked(elapsedRealtimeMs); 5631 } 5632 } 5633 5634 @Override 5635 public void noteWifiScanStoppedLocked(long elapsedRealtimeMs) { 5636 if (mWifiScanStarted) { 5637 mWifiScanStarted = false; 5638 mWifiScanTimer.stopRunningLocked(elapsedRealtimeMs); 5639 } 5640 } 5641 5642 @Override 5643 public void noteWifiBatchedScanStartedLocked(int csph, long elapsedRealtimeMs) { 5644 int bin = 0; 5645 while (csph > 8 && bin < NUM_WIFI_BATCHED_SCAN_BINS-1) { 5646 csph = csph >> 3; 5647 bin++; 5648 } 5649 5650 if (mWifiBatchedScanBinStarted == bin) return; 5651 5652 if (mWifiBatchedScanBinStarted != NO_BATCHED_SCAN_STARTED) { 5653 mWifiBatchedScanTimer[mWifiBatchedScanBinStarted]. 5654 stopRunningLocked(elapsedRealtimeMs); 5655 } 5656 mWifiBatchedScanBinStarted = bin; 5657 if (mWifiBatchedScanTimer[bin] == null) { 5658 makeWifiBatchedScanBin(bin, null); 5659 } 5660 mWifiBatchedScanTimer[bin].startRunningLocked(elapsedRealtimeMs); 5661 } 5662 5663 @Override 5664 public void noteWifiBatchedScanStoppedLocked(long elapsedRealtimeMs) { 5665 if (mWifiBatchedScanBinStarted != NO_BATCHED_SCAN_STARTED) { 5666 mWifiBatchedScanTimer[mWifiBatchedScanBinStarted]. 5667 stopRunningLocked(elapsedRealtimeMs); 5668 mWifiBatchedScanBinStarted = NO_BATCHED_SCAN_STARTED; 5669 } 5670 } 5671 5672 @Override 5673 public void noteWifiMulticastEnabledLocked(long elapsedRealtimeMs) { 5674 if (!mWifiMulticastEnabled) { 5675 mWifiMulticastEnabled = true; 5676 if (mWifiMulticastTimer == null) { 5677 mWifiMulticastTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, 5678 WIFI_MULTICAST_ENABLED, mBsi.mWifiMulticastTimers, mBsi.mOnBatteryTimeBase); 5679 } 5680 mWifiMulticastTimer.startRunningLocked(elapsedRealtimeMs); 5681 } 5682 } 5683 5684 @Override 5685 public void noteWifiMulticastDisabledLocked(long elapsedRealtimeMs) { 5686 if (mWifiMulticastEnabled) { 5687 mWifiMulticastEnabled = false; 5688 mWifiMulticastTimer.stopRunningLocked(elapsedRealtimeMs); 5689 } 5690 } 5691 5692 @Override 5693 public ControllerActivityCounter getWifiControllerActivity() { 5694 return mWifiControllerActivity; 5695 } 5696 5697 @Override 5698 public ControllerActivityCounter getBluetoothControllerActivity() { 5699 return mBluetoothControllerActivity; 5700 } 5701 5702 @Override 5703 public ControllerActivityCounter getModemControllerActivity() { 5704 return mModemControllerActivity; 5705 } 5706 5707 public ControllerActivityCounterImpl getOrCreateWifiControllerActivityLocked() { 5708 if (mWifiControllerActivity == null) { 5709 mWifiControllerActivity = new ControllerActivityCounterImpl(mBsi.mOnBatteryTimeBase, 5710 NUM_BT_TX_LEVELS); 5711 } 5712 return mWifiControllerActivity; 5713 } 5714 5715 public ControllerActivityCounterImpl getOrCreateBluetoothControllerActivityLocked() { 5716 if (mBluetoothControllerActivity == null) { 5717 mBluetoothControllerActivity = new ControllerActivityCounterImpl(mBsi.mOnBatteryTimeBase, 5718 NUM_BT_TX_LEVELS); 5719 } 5720 return mBluetoothControllerActivity; 5721 } 5722 5723 public ControllerActivityCounterImpl getOrCreateModemControllerActivityLocked() { 5724 if (mModemControllerActivity == null) { 5725 mModemControllerActivity = new ControllerActivityCounterImpl(mBsi.mOnBatteryTimeBase, 5726 ModemActivityInfo.TX_POWER_LEVELS); 5727 } 5728 return mModemControllerActivity; 5729 } 5730 5731 public StopwatchTimer createAudioTurnedOnTimerLocked() { 5732 if (mAudioTurnedOnTimer == null) { 5733 mAudioTurnedOnTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, AUDIO_TURNED_ON, 5734 mBsi.mAudioTurnedOnTimers, mBsi.mOnBatteryTimeBase); 5735 } 5736 return mAudioTurnedOnTimer; 5737 } 5738 5739 public void noteAudioTurnedOnLocked(long elapsedRealtimeMs) { 5740 createAudioTurnedOnTimerLocked().startRunningLocked(elapsedRealtimeMs); 5741 } 5742 5743 public void noteAudioTurnedOffLocked(long elapsedRealtimeMs) { 5744 if (mAudioTurnedOnTimer != null) { 5745 mAudioTurnedOnTimer.stopRunningLocked(elapsedRealtimeMs); 5746 } 5747 } 5748 5749 public void noteResetAudioLocked(long elapsedRealtimeMs) { 5750 if (mAudioTurnedOnTimer != null) { 5751 mAudioTurnedOnTimer.stopAllRunningLocked(elapsedRealtimeMs); 5752 } 5753 } 5754 5755 public StopwatchTimer createVideoTurnedOnTimerLocked() { 5756 if (mVideoTurnedOnTimer == null) { 5757 mVideoTurnedOnTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, VIDEO_TURNED_ON, 5758 mBsi.mVideoTurnedOnTimers, mBsi.mOnBatteryTimeBase); 5759 } 5760 return mVideoTurnedOnTimer; 5761 } 5762 5763 public void noteVideoTurnedOnLocked(long elapsedRealtimeMs) { 5764 createVideoTurnedOnTimerLocked().startRunningLocked(elapsedRealtimeMs); 5765 } 5766 5767 public void noteVideoTurnedOffLocked(long elapsedRealtimeMs) { 5768 if (mVideoTurnedOnTimer != null) { 5769 mVideoTurnedOnTimer.stopRunningLocked(elapsedRealtimeMs); 5770 } 5771 } 5772 5773 public void noteResetVideoLocked(long elapsedRealtimeMs) { 5774 if (mVideoTurnedOnTimer != null) { 5775 mVideoTurnedOnTimer.stopAllRunningLocked(elapsedRealtimeMs); 5776 } 5777 } 5778 5779 public StopwatchTimer createFlashlightTurnedOnTimerLocked() { 5780 if (mFlashlightTurnedOnTimer == null) { 5781 mFlashlightTurnedOnTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, 5782 FLASHLIGHT_TURNED_ON, mBsi.mFlashlightTurnedOnTimers, mBsi.mOnBatteryTimeBase); 5783 } 5784 return mFlashlightTurnedOnTimer; 5785 } 5786 5787 public void noteFlashlightTurnedOnLocked(long elapsedRealtimeMs) { 5788 createFlashlightTurnedOnTimerLocked().startRunningLocked(elapsedRealtimeMs); 5789 } 5790 5791 public void noteFlashlightTurnedOffLocked(long elapsedRealtimeMs) { 5792 if (mFlashlightTurnedOnTimer != null) { 5793 mFlashlightTurnedOnTimer.stopRunningLocked(elapsedRealtimeMs); 5794 } 5795 } 5796 5797 public void noteResetFlashlightLocked(long elapsedRealtimeMs) { 5798 if (mFlashlightTurnedOnTimer != null) { 5799 mFlashlightTurnedOnTimer.stopAllRunningLocked(elapsedRealtimeMs); 5800 } 5801 } 5802 5803 public StopwatchTimer createCameraTurnedOnTimerLocked() { 5804 if (mCameraTurnedOnTimer == null) { 5805 mCameraTurnedOnTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, CAMERA_TURNED_ON, 5806 mBsi.mCameraTurnedOnTimers, mBsi.mOnBatteryTimeBase); 5807 } 5808 return mCameraTurnedOnTimer; 5809 } 5810 5811 public void noteCameraTurnedOnLocked(long elapsedRealtimeMs) { 5812 createCameraTurnedOnTimerLocked().startRunningLocked(elapsedRealtimeMs); 5813 } 5814 5815 public void noteCameraTurnedOffLocked(long elapsedRealtimeMs) { 5816 if (mCameraTurnedOnTimer != null) { 5817 mCameraTurnedOnTimer.stopRunningLocked(elapsedRealtimeMs); 5818 } 5819 } 5820 5821 public void noteResetCameraLocked(long elapsedRealtimeMs) { 5822 if (mCameraTurnedOnTimer != null) { 5823 mCameraTurnedOnTimer.stopAllRunningLocked(elapsedRealtimeMs); 5824 } 5825 } 5826 5827 public StopwatchTimer createForegroundActivityTimerLocked() { 5828 if (mForegroundActivityTimer == null) { 5829 mForegroundActivityTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, 5830 FOREGROUND_ACTIVITY, null, mBsi.mOnBatteryTimeBase); 5831 } 5832 return mForegroundActivityTimer; 5833 } 5834 5835 public DualTimer createBluetoothScanTimerLocked() { 5836 if (mBluetoothScanTimer == null) { 5837 mBluetoothScanTimer = new DualTimer(mBsi.mClocks, Uid.this, BLUETOOTH_SCAN_ON, 5838 mBsi.mBluetoothScanOnTimers, mBsi.mOnBatteryTimeBase, 5839 mOnBatteryBackgroundTimeBase); 5840 } 5841 return mBluetoothScanTimer; 5842 } 5843 5844 public void noteBluetoothScanStartedLocked(long elapsedRealtimeMs) { 5845 createBluetoothScanTimerLocked().startRunningLocked(elapsedRealtimeMs); 5846 } 5847 5848 public void noteBluetoothScanStoppedLocked(long elapsedRealtimeMs) { 5849 if (mBluetoothScanTimer != null) { 5850 mBluetoothScanTimer.stopRunningLocked(elapsedRealtimeMs); 5851 } 5852 } 5853 5854 public void noteResetBluetoothScanLocked(long elapsedRealtimeMs) { 5855 if (mBluetoothScanTimer != null) { 5856 mBluetoothScanTimer.stopAllRunningLocked(elapsedRealtimeMs); 5857 } 5858 } 5859 5860 @Override 5861 public void noteActivityResumedLocked(long elapsedRealtimeMs) { 5862 // We always start, since we want multiple foreground PIDs to nest 5863 createForegroundActivityTimerLocked().startRunningLocked(elapsedRealtimeMs); 5864 } 5865 5866 @Override 5867 public void noteActivityPausedLocked(long elapsedRealtimeMs) { 5868 if (mForegroundActivityTimer != null) { 5869 mForegroundActivityTimer.stopRunningLocked(elapsedRealtimeMs); 5870 } 5871 } 5872 5873 public BatchTimer createVibratorOnTimerLocked() { 5874 if (mVibratorOnTimer == null) { 5875 mVibratorOnTimer = new BatchTimer(mBsi.mClocks, Uid.this, VIBRATOR_ON, 5876 mBsi.mOnBatteryTimeBase); 5877 } 5878 return mVibratorOnTimer; 5879 } 5880 5881 public void noteVibratorOnLocked(long durationMillis) { 5882 createVibratorOnTimerLocked().addDuration(mBsi, durationMillis); 5883 } 5884 5885 public void noteVibratorOffLocked() { 5886 if (mVibratorOnTimer != null) { 5887 mVibratorOnTimer.abortLastDuration(mBsi); 5888 } 5889 } 5890 5891 @Override 5892 public long getWifiRunningTime(long elapsedRealtimeUs, int which) { 5893 if (mWifiRunningTimer == null) { 5894 return 0; 5895 } 5896 return mWifiRunningTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 5897 } 5898 5899 @Override 5900 public long getFullWifiLockTime(long elapsedRealtimeUs, int which) { 5901 if (mFullWifiLockTimer == null) { 5902 return 0; 5903 } 5904 return mFullWifiLockTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 5905 } 5906 5907 @Override 5908 public long getWifiScanTime(long elapsedRealtimeUs, int which) { 5909 if (mWifiScanTimer == null) { 5910 return 0; 5911 } 5912 return mWifiScanTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 5913 } 5914 5915 @Override 5916 public int getWifiScanCount(int which) { 5917 if (mWifiScanTimer == null) { 5918 return 0; 5919 } 5920 return mWifiScanTimer.getCountLocked(which); 5921 } 5922 5923 @Override 5924 public int getWifiScanBackgroundCount(int which) { 5925 if (mWifiScanTimer == null || mWifiScanTimer.getSubTimer() == null) { 5926 return 0; 5927 } 5928 return mWifiScanTimer.getSubTimer().getCountLocked(which); 5929 } 5930 5931 @Override 5932 public long getWifiScanActualTime(final long elapsedRealtimeUs) { 5933 if (mWifiScanTimer == null) { 5934 return 0; 5935 } 5936 final long elapsedRealtimeMs = (elapsedRealtimeUs + 500) / 1000; 5937 return mWifiScanTimer.getTotalDurationMsLocked(elapsedRealtimeMs) * 1000; 5938 } 5939 5940 @Override 5941 public long getWifiScanBackgroundTime(final long elapsedRealtimeUs) { 5942 if (mWifiScanTimer == null || mWifiScanTimer.getSubTimer() == null) { 5943 return 0; 5944 } 5945 final long elapsedRealtimeMs = (elapsedRealtimeUs + 500) / 1000; 5946 return mWifiScanTimer.getSubTimer().getTotalDurationMsLocked(elapsedRealtimeMs) * 1000; 5947 } 5948 5949 @Override 5950 public long getWifiBatchedScanTime(int csphBin, long elapsedRealtimeUs, int which) { 5951 if (csphBin < 0 || csphBin >= NUM_WIFI_BATCHED_SCAN_BINS) return 0; 5952 if (mWifiBatchedScanTimer[csphBin] == null) { 5953 return 0; 5954 } 5955 return mWifiBatchedScanTimer[csphBin].getTotalTimeLocked(elapsedRealtimeUs, which); 5956 } 5957 5958 @Override 5959 public int getWifiBatchedScanCount(int csphBin, int which) { 5960 if (csphBin < 0 || csphBin >= NUM_WIFI_BATCHED_SCAN_BINS) return 0; 5961 if (mWifiBatchedScanTimer[csphBin] == null) { 5962 return 0; 5963 } 5964 return mWifiBatchedScanTimer[csphBin].getCountLocked(which); 5965 } 5966 5967 @Override 5968 public long getWifiMulticastTime(long elapsedRealtimeUs, int which) { 5969 if (mWifiMulticastTimer == null) { 5970 return 0; 5971 } 5972 return mWifiMulticastTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 5973 } 5974 5975 @Override 5976 public Timer getAudioTurnedOnTimer() { 5977 return mAudioTurnedOnTimer; 5978 } 5979 5980 @Override 5981 public Timer getVideoTurnedOnTimer() { 5982 return mVideoTurnedOnTimer; 5983 } 5984 5985 @Override 5986 public Timer getFlashlightTurnedOnTimer() { 5987 return mFlashlightTurnedOnTimer; 5988 } 5989 5990 @Override 5991 public Timer getCameraTurnedOnTimer() { 5992 return mCameraTurnedOnTimer; 5993 } 5994 5995 @Override 5996 public Timer getForegroundActivityTimer() { 5997 return mForegroundActivityTimer; 5998 } 5999 6000 @Override 6001 public Timer getBluetoothScanTimer() { 6002 return mBluetoothScanTimer; 6003 } 6004 6005 @Override 6006 public Timer getBluetoothScanBackgroundTimer() { 6007 if (mBluetoothScanTimer == null) { 6008 return null; 6009 } 6010 return mBluetoothScanTimer.getSubTimer(); 6011 } 6012 6013 void makeProcessState(int i, Parcel in) { 6014 if (i < 0 || i >= NUM_PROCESS_STATE) return; 6015 6016 if (in == null) { 6017 mProcessStateTimer[i] = new StopwatchTimer(mBsi.mClocks, this, PROCESS_STATE, null, 6018 mBsi.mOnBatteryTimeBase); 6019 } else { 6020 mProcessStateTimer[i] = new StopwatchTimer(mBsi.mClocks, this, PROCESS_STATE, null, 6021 mBsi.mOnBatteryTimeBase, in); 6022 } 6023 } 6024 6025 @Override 6026 public long getProcessStateTime(int state, long elapsedRealtimeUs, int which) { 6027 if (state < 0 || state >= NUM_PROCESS_STATE) return 0; 6028 if (mProcessStateTimer[state] == null) { 6029 return 0; 6030 } 6031 return mProcessStateTimer[state].getTotalTimeLocked(elapsedRealtimeUs, which); 6032 } 6033 6034 @Override 6035 public Timer getProcessStateTimer(int state) { 6036 if (state < 0 || state >= NUM_PROCESS_STATE) return null; 6037 return mProcessStateTimer[state]; 6038 } 6039 6040 @Override 6041 public Timer getVibratorOnTimer() { 6042 return mVibratorOnTimer; 6043 } 6044 6045 @Override 6046 public void noteUserActivityLocked(int type) { 6047 if (mUserActivityCounters == null) { 6048 initUserActivityLocked(); 6049 } 6050 if (type >= 0 && type < NUM_USER_ACTIVITY_TYPES) { 6051 mUserActivityCounters[type].stepAtomic(); 6052 } else { 6053 Slog.w(TAG, "Unknown user activity type " + type + " was specified.", 6054 new Throwable()); 6055 } 6056 } 6057 6058 @Override 6059 public boolean hasUserActivity() { 6060 return mUserActivityCounters != null; 6061 } 6062 6063 @Override 6064 public int getUserActivityCount(int type, int which) { 6065 if (mUserActivityCounters == null) { 6066 return 0; 6067 } 6068 return mUserActivityCounters[type].getCountLocked(which); 6069 } 6070 6071 void makeWifiBatchedScanBin(int i, Parcel in) { 6072 if (i < 0 || i >= NUM_WIFI_BATCHED_SCAN_BINS) return; 6073 6074 ArrayList<StopwatchTimer> collected = mBsi.mWifiBatchedScanTimers.get(i); 6075 if (collected == null) { 6076 collected = new ArrayList<StopwatchTimer>(); 6077 mBsi.mWifiBatchedScanTimers.put(i, collected); 6078 } 6079 if (in == null) { 6080 mWifiBatchedScanTimer[i] = new StopwatchTimer(mBsi.mClocks, this, WIFI_BATCHED_SCAN, 6081 collected, mBsi.mOnBatteryTimeBase); 6082 } else { 6083 mWifiBatchedScanTimer[i] = new StopwatchTimer(mBsi.mClocks, this, WIFI_BATCHED_SCAN, 6084 collected, mBsi.mOnBatteryTimeBase, in); 6085 } 6086 } 6087 6088 6089 void initUserActivityLocked() { 6090 mUserActivityCounters = new Counter[NUM_USER_ACTIVITY_TYPES]; 6091 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) { 6092 mUserActivityCounters[i] = new Counter(mBsi.mOnBatteryTimeBase); 6093 } 6094 } 6095 6096 void noteNetworkActivityLocked(int type, long deltaBytes, long deltaPackets) { 6097 if (mNetworkByteActivityCounters == null) { 6098 initNetworkActivityLocked(); 6099 } 6100 if (type >= 0 && type < NUM_NETWORK_ACTIVITY_TYPES) { 6101 mNetworkByteActivityCounters[type].addCountLocked(deltaBytes); 6102 mNetworkPacketActivityCounters[type].addCountLocked(deltaPackets); 6103 } else { 6104 Slog.w(TAG, "Unknown network activity type " + type + " was specified.", 6105 new Throwable()); 6106 } 6107 } 6108 6109 void noteMobileRadioActiveTimeLocked(long batteryUptime) { 6110 if (mNetworkByteActivityCounters == null) { 6111 initNetworkActivityLocked(); 6112 } 6113 mMobileRadioActiveTime.addCountLocked(batteryUptime); 6114 mMobileRadioActiveCount.addCountLocked(1); 6115 } 6116 6117 @Override 6118 public boolean hasNetworkActivity() { 6119 return mNetworkByteActivityCounters != null; 6120 } 6121 6122 @Override 6123 public long getNetworkActivityBytes(int type, int which) { 6124 if (mNetworkByteActivityCounters != null && type >= 0 6125 && type < mNetworkByteActivityCounters.length) { 6126 return mNetworkByteActivityCounters[type].getCountLocked(which); 6127 } else { 6128 return 0; 6129 } 6130 } 6131 6132 @Override 6133 public long getNetworkActivityPackets(int type, int which) { 6134 if (mNetworkPacketActivityCounters != null && type >= 0 6135 && type < mNetworkPacketActivityCounters.length) { 6136 return mNetworkPacketActivityCounters[type].getCountLocked(which); 6137 } else { 6138 return 0; 6139 } 6140 } 6141 6142 @Override 6143 public long getMobileRadioActiveTime(int which) { 6144 return mMobileRadioActiveTime != null 6145 ? mMobileRadioActiveTime.getCountLocked(which) : 0; 6146 } 6147 6148 @Override 6149 public int getMobileRadioActiveCount(int which) { 6150 return mMobileRadioActiveCount != null 6151 ? (int)mMobileRadioActiveCount.getCountLocked(which) : 0; 6152 } 6153 6154 @Override 6155 public long getUserCpuTimeUs(int which) { 6156 return mUserCpuTime.getCountLocked(which); 6157 } 6158 6159 @Override 6160 public long getSystemCpuTimeUs(int which) { 6161 return mSystemCpuTime.getCountLocked(which); 6162 } 6163 6164 @Override 6165 public long getCpuPowerMaUs(int which) { 6166 return mCpuPower.getCountLocked(which); 6167 } 6168 6169 @Override 6170 public long getTimeAtCpuSpeed(int cluster, int step, int which) { 6171 if (mCpuClusterSpeed != null) { 6172 if (cluster >= 0 && cluster < mCpuClusterSpeed.length) { 6173 final LongSamplingCounter[] cpuSpeeds = mCpuClusterSpeed[cluster]; 6174 if (cpuSpeeds != null) { 6175 if (step >= 0 && step < cpuSpeeds.length) { 6176 final LongSamplingCounter c = cpuSpeeds[step]; 6177 if (c != null) { 6178 return c.getCountLocked(which); 6179 } 6180 } 6181 } 6182 } 6183 } 6184 return 0; 6185 } 6186 6187 public void noteMobileRadioApWakeupLocked() { 6188 if (mMobileRadioApWakeupCount == null) { 6189 mMobileRadioApWakeupCount = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); 6190 } 6191 mMobileRadioApWakeupCount.addCountLocked(1); 6192 } 6193 6194 @Override 6195 public long getMobileRadioApWakeupCount(int which) { 6196 if (mMobileRadioApWakeupCount != null) { 6197 return mMobileRadioApWakeupCount.getCountLocked(which); 6198 } 6199 return 0; 6200 } 6201 6202 public void noteWifiRadioApWakeupLocked() { 6203 if (mWifiRadioApWakeupCount == null) { 6204 mWifiRadioApWakeupCount = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); 6205 } 6206 mWifiRadioApWakeupCount.addCountLocked(1); 6207 } 6208 6209 @Override 6210 public long getWifiRadioApWakeupCount(int which) { 6211 if (mWifiRadioApWakeupCount != null) { 6212 return mWifiRadioApWakeupCount.getCountLocked(which); 6213 } 6214 return 0; 6215 } 6216 6217 void initNetworkActivityLocked() { 6218 mNetworkByteActivityCounters = new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES]; 6219 mNetworkPacketActivityCounters = new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES]; 6220 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 6221 mNetworkByteActivityCounters[i] = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); 6222 mNetworkPacketActivityCounters[i] = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); 6223 } 6224 mMobileRadioActiveTime = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); 6225 mMobileRadioActiveCount = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); 6226 } 6227 6228 /** 6229 * Clear all stats for this uid. Returns true if the uid is completely 6230 * inactive so can be dropped. 6231 */ 6232 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) 6233 public boolean reset() { 6234 boolean active = false; 6235 6236 if (mWifiRunningTimer != null) { 6237 active |= !mWifiRunningTimer.reset(false); 6238 active |= mWifiRunning; 6239 } 6240 if (mFullWifiLockTimer != null) { 6241 active |= !mFullWifiLockTimer.reset(false); 6242 active |= mFullWifiLockOut; 6243 } 6244 if (mWifiScanTimer != null) { 6245 active |= !mWifiScanTimer.reset(false); 6246 active |= mWifiScanStarted; 6247 } 6248 if (mWifiBatchedScanTimer != null) { 6249 for (int i = 0; i < NUM_WIFI_BATCHED_SCAN_BINS; i++) { 6250 if (mWifiBatchedScanTimer[i] != null) { 6251 active |= !mWifiBatchedScanTimer[i].reset(false); 6252 } 6253 } 6254 active |= (mWifiBatchedScanBinStarted != NO_BATCHED_SCAN_STARTED); 6255 } 6256 if (mWifiMulticastTimer != null) { 6257 active |= !mWifiMulticastTimer.reset(false); 6258 active |= mWifiMulticastEnabled; 6259 } 6260 6261 active |= !resetTimerIfNotNull(mAudioTurnedOnTimer, false); 6262 active |= !resetTimerIfNotNull(mVideoTurnedOnTimer, false); 6263 active |= !resetTimerIfNotNull(mFlashlightTurnedOnTimer, false); 6264 active |= !resetTimerIfNotNull(mCameraTurnedOnTimer, false); 6265 active |= !resetTimerIfNotNull(mForegroundActivityTimer, false); 6266 active |= !resetTimerIfNotNull(mBluetoothScanTimer, false); 6267 6268 if (mProcessStateTimer != null) { 6269 for (int i = 0; i < NUM_PROCESS_STATE; i++) { 6270 if (mProcessStateTimer[i] != null) { 6271 active |= !mProcessStateTimer[i].reset(false); 6272 } 6273 } 6274 active |= (mProcessState != ActivityManager.PROCESS_STATE_NONEXISTENT); 6275 } 6276 if (mVibratorOnTimer != null) { 6277 if (mVibratorOnTimer.reset(false)) { 6278 mVibratorOnTimer.detach(); 6279 mVibratorOnTimer = null; 6280 } else { 6281 active = true; 6282 } 6283 } 6284 6285 if (mUserActivityCounters != null) { 6286 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) { 6287 mUserActivityCounters[i].reset(false); 6288 } 6289 } 6290 6291 if (mNetworkByteActivityCounters != null) { 6292 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 6293 mNetworkByteActivityCounters[i].reset(false); 6294 mNetworkPacketActivityCounters[i].reset(false); 6295 } 6296 mMobileRadioActiveTime.reset(false); 6297 mMobileRadioActiveCount.reset(false); 6298 } 6299 6300 if (mWifiControllerActivity != null) { 6301 mWifiControllerActivity.reset(false); 6302 } 6303 6304 if (mBluetoothControllerActivity != null) { 6305 mBluetoothControllerActivity.reset(false); 6306 } 6307 6308 if (mModemControllerActivity != null) { 6309 mModemControllerActivity.reset(false); 6310 } 6311 6312 mUserCpuTime.reset(false); 6313 mSystemCpuTime.reset(false); 6314 mCpuPower.reset(false); 6315 6316 if (mCpuClusterSpeed != null) { 6317 for (LongSamplingCounter[] speeds : mCpuClusterSpeed) { 6318 if (speeds != null) { 6319 for (LongSamplingCounter speed : speeds) { 6320 if (speed != null) { 6321 speed.reset(false); 6322 } 6323 } 6324 } 6325 } 6326 } 6327 6328 resetLongCounterIfNotNull(mMobileRadioApWakeupCount, false); 6329 resetLongCounterIfNotNull(mWifiRadioApWakeupCount, false); 6330 6331 final ArrayMap<String, Wakelock> wakeStats = mWakelockStats.getMap(); 6332 for (int iw=wakeStats.size()-1; iw>=0; iw--) { 6333 Wakelock wl = wakeStats.valueAt(iw); 6334 if (wl.reset()) { 6335 wakeStats.removeAt(iw); 6336 } else { 6337 active = true; 6338 } 6339 } 6340 mWakelockStats.cleanup(); 6341 final ArrayMap<String, StopwatchTimer> syncStats = mSyncStats.getMap(); 6342 for (int is=syncStats.size()-1; is>=0; is--) { 6343 StopwatchTimer timer = syncStats.valueAt(is); 6344 if (timer.reset(false)) { 6345 syncStats.removeAt(is); 6346 timer.detach(); 6347 } else { 6348 active = true; 6349 } 6350 } 6351 mSyncStats.cleanup(); 6352 final ArrayMap<String, DualTimer> jobStats = mJobStats.getMap(); 6353 for (int ij=jobStats.size()-1; ij>=0; ij--) { 6354 DualTimer timer = jobStats.valueAt(ij); 6355 if (timer.reset(false)) { 6356 jobStats.removeAt(ij); 6357 timer.detach(); 6358 } else { 6359 active = true; 6360 } 6361 } 6362 mJobStats.cleanup(); 6363 for (int ise=mSensorStats.size()-1; ise>=0; ise--) { 6364 Sensor s = mSensorStats.valueAt(ise); 6365 if (s.reset()) { 6366 mSensorStats.removeAt(ise); 6367 } else { 6368 active = true; 6369 } 6370 } 6371 for (int ip=mProcessStats.size()-1; ip>=0; ip--) { 6372 Proc proc = mProcessStats.valueAt(ip); 6373 proc.detach(); 6374 } 6375 mProcessStats.clear(); 6376 if (mPids.size() > 0) { 6377 for (int i=mPids.size()-1; i>=0; i--) { 6378 Pid pid = mPids.valueAt(i); 6379 if (pid.mWakeNesting > 0) { 6380 active = true; 6381 } else { 6382 mPids.removeAt(i); 6383 } 6384 } 6385 } 6386 if (mPackageStats.size() > 0) { 6387 Iterator<Map.Entry<String, Pkg>> it = mPackageStats.entrySet().iterator(); 6388 while (it.hasNext()) { 6389 Map.Entry<String, Pkg> pkgEntry = it.next(); 6390 Pkg p = pkgEntry.getValue(); 6391 p.detach(); 6392 if (p.mServiceStats.size() > 0) { 6393 Iterator<Map.Entry<String, Pkg.Serv>> it2 6394 = p.mServiceStats.entrySet().iterator(); 6395 while (it2.hasNext()) { 6396 Map.Entry<String, Pkg.Serv> servEntry = it2.next(); 6397 servEntry.getValue().detach(); 6398 } 6399 } 6400 } 6401 mPackageStats.clear(); 6402 } 6403 6404 mLastStepUserTime = mLastStepSystemTime = 0; 6405 mCurStepUserTime = mCurStepSystemTime = 0; 6406 6407 mOnBatteryBackgroundTimeBase.reset(mBsi.mClocks.elapsedRealtime() * 1000, 6408 mBsi.mClocks.uptimeMillis() * 1000); 6409 6410 if (!active) { 6411 if (mWifiRunningTimer != null) { 6412 mWifiRunningTimer.detach(); 6413 } 6414 if (mFullWifiLockTimer != null) { 6415 mFullWifiLockTimer.detach(); 6416 } 6417 if (mWifiScanTimer != null) { 6418 mWifiScanTimer.detach(); 6419 } 6420 for (int i = 0; i < NUM_WIFI_BATCHED_SCAN_BINS; i++) { 6421 if (mWifiBatchedScanTimer[i] != null) { 6422 mWifiBatchedScanTimer[i].detach(); 6423 } 6424 } 6425 if (mWifiMulticastTimer != null) { 6426 mWifiMulticastTimer.detach(); 6427 } 6428 if (mAudioTurnedOnTimer != null) { 6429 mAudioTurnedOnTimer.detach(); 6430 mAudioTurnedOnTimer = null; 6431 } 6432 if (mVideoTurnedOnTimer != null) { 6433 mVideoTurnedOnTimer.detach(); 6434 mVideoTurnedOnTimer = null; 6435 } 6436 if (mFlashlightTurnedOnTimer != null) { 6437 mFlashlightTurnedOnTimer.detach(); 6438 mFlashlightTurnedOnTimer = null; 6439 } 6440 if (mCameraTurnedOnTimer != null) { 6441 mCameraTurnedOnTimer.detach(); 6442 mCameraTurnedOnTimer = null; 6443 } 6444 if (mForegroundActivityTimer != null) { 6445 mForegroundActivityTimer.detach(); 6446 mForegroundActivityTimer = null; 6447 } 6448 if (mBluetoothScanTimer != null) { 6449 mBluetoothScanTimer.detach(); 6450 mBluetoothScanTimer = null; 6451 } 6452 if (mUserActivityCounters != null) { 6453 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) { 6454 mUserActivityCounters[i].detach(); 6455 } 6456 } 6457 if (mNetworkByteActivityCounters != null) { 6458 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 6459 mNetworkByteActivityCounters[i].detach(); 6460 mNetworkPacketActivityCounters[i].detach(); 6461 } 6462 } 6463 6464 if (mWifiControllerActivity != null) { 6465 mWifiControllerActivity.detach(); 6466 } 6467 6468 if (mBluetoothControllerActivity != null) { 6469 mBluetoothControllerActivity.detach(); 6470 } 6471 6472 if (mModemControllerActivity != null) { 6473 mModemControllerActivity.detach(); 6474 } 6475 6476 mPids.clear(); 6477 6478 mUserCpuTime.detach(); 6479 mSystemCpuTime.detach(); 6480 mCpuPower.detach(); 6481 6482 if (mCpuClusterSpeed != null) { 6483 for (LongSamplingCounter[] cpuSpeeds : mCpuClusterSpeed) { 6484 if (cpuSpeeds != null) { 6485 for (LongSamplingCounter c : cpuSpeeds) { 6486 if (c != null) { 6487 c.detach(); 6488 } 6489 } 6490 } 6491 } 6492 } 6493 6494 detachLongCounterIfNotNull(mMobileRadioApWakeupCount); 6495 detachLongCounterIfNotNull(mWifiRadioApWakeupCount); 6496 } 6497 6498 return !active; 6499 } 6500 6501 void writeToParcelLocked(Parcel out, long uptimeUs, long elapsedRealtimeUs) { 6502 mOnBatteryBackgroundTimeBase.writeToParcel(out, uptimeUs, elapsedRealtimeUs); 6503 6504 final ArrayMap<String, Wakelock> wakeStats = mWakelockStats.getMap(); 6505 int NW = wakeStats.size(); 6506 out.writeInt(NW); 6507 for (int iw=0; iw<NW; iw++) { 6508 out.writeString(wakeStats.keyAt(iw)); 6509 Uid.Wakelock wakelock = wakeStats.valueAt(iw); 6510 wakelock.writeToParcelLocked(out, elapsedRealtimeUs); 6511 } 6512 6513 final ArrayMap<String, StopwatchTimer> syncStats = mSyncStats.getMap(); 6514 int NS = syncStats.size(); 6515 out.writeInt(NS); 6516 for (int is=0; is<NS; is++) { 6517 out.writeString(syncStats.keyAt(is)); 6518 StopwatchTimer timer = syncStats.valueAt(is); 6519 Timer.writeTimerToParcel(out, timer, elapsedRealtimeUs); 6520 } 6521 6522 final ArrayMap<String, DualTimer> jobStats = mJobStats.getMap(); 6523 int NJ = jobStats.size(); 6524 out.writeInt(NJ); 6525 for (int ij=0; ij<NJ; ij++) { 6526 out.writeString(jobStats.keyAt(ij)); 6527 DualTimer timer = jobStats.valueAt(ij); 6528 Timer.writeTimerToParcel(out, timer, elapsedRealtimeUs); 6529 } 6530 6531 int NSE = mSensorStats.size(); 6532 out.writeInt(NSE); 6533 for (int ise=0; ise<NSE; ise++) { 6534 out.writeInt(mSensorStats.keyAt(ise)); 6535 Uid.Sensor sensor = mSensorStats.valueAt(ise); 6536 sensor.writeToParcelLocked(out, elapsedRealtimeUs); 6537 } 6538 6539 int NP = mProcessStats.size(); 6540 out.writeInt(NP); 6541 for (int ip=0; ip<NP; ip++) { 6542 out.writeString(mProcessStats.keyAt(ip)); 6543 Uid.Proc proc = mProcessStats.valueAt(ip); 6544 proc.writeToParcelLocked(out); 6545 } 6546 6547 out.writeInt(mPackageStats.size()); 6548 for (Map.Entry<String, Uid.Pkg> pkgEntry : mPackageStats.entrySet()) { 6549 out.writeString(pkgEntry.getKey()); 6550 Uid.Pkg pkg = pkgEntry.getValue(); 6551 pkg.writeToParcelLocked(out); 6552 } 6553 6554 if (mWifiRunningTimer != null) { 6555 out.writeInt(1); 6556 mWifiRunningTimer.writeToParcel(out, elapsedRealtimeUs); 6557 } else { 6558 out.writeInt(0); 6559 } 6560 if (mFullWifiLockTimer != null) { 6561 out.writeInt(1); 6562 mFullWifiLockTimer.writeToParcel(out, elapsedRealtimeUs); 6563 } else { 6564 out.writeInt(0); 6565 } 6566 if (mWifiScanTimer != null) { 6567 out.writeInt(1); 6568 mWifiScanTimer.writeToParcel(out, elapsedRealtimeUs); 6569 } else { 6570 out.writeInt(0); 6571 } 6572 for (int i = 0; i < NUM_WIFI_BATCHED_SCAN_BINS; i++) { 6573 if (mWifiBatchedScanTimer[i] != null) { 6574 out.writeInt(1); 6575 mWifiBatchedScanTimer[i].writeToParcel(out, elapsedRealtimeUs); 6576 } else { 6577 out.writeInt(0); 6578 } 6579 } 6580 if (mWifiMulticastTimer != null) { 6581 out.writeInt(1); 6582 mWifiMulticastTimer.writeToParcel(out, elapsedRealtimeUs); 6583 } else { 6584 out.writeInt(0); 6585 } 6586 6587 if (mAudioTurnedOnTimer != null) { 6588 out.writeInt(1); 6589 mAudioTurnedOnTimer.writeToParcel(out, elapsedRealtimeUs); 6590 } else { 6591 out.writeInt(0); 6592 } 6593 if (mVideoTurnedOnTimer != null) { 6594 out.writeInt(1); 6595 mVideoTurnedOnTimer.writeToParcel(out, elapsedRealtimeUs); 6596 } else { 6597 out.writeInt(0); 6598 } 6599 if (mFlashlightTurnedOnTimer != null) { 6600 out.writeInt(1); 6601 mFlashlightTurnedOnTimer.writeToParcel(out, elapsedRealtimeUs); 6602 } else { 6603 out.writeInt(0); 6604 } 6605 if (mCameraTurnedOnTimer != null) { 6606 out.writeInt(1); 6607 mCameraTurnedOnTimer.writeToParcel(out, elapsedRealtimeUs); 6608 } else { 6609 out.writeInt(0); 6610 } 6611 if (mForegroundActivityTimer != null) { 6612 out.writeInt(1); 6613 mForegroundActivityTimer.writeToParcel(out, elapsedRealtimeUs); 6614 } else { 6615 out.writeInt(0); 6616 } 6617 if (mBluetoothScanTimer != null) { 6618 out.writeInt(1); 6619 mBluetoothScanTimer.writeToParcel(out, elapsedRealtimeUs); 6620 } else { 6621 out.writeInt(0); 6622 } 6623 for (int i = 0; i < NUM_PROCESS_STATE; i++) { 6624 if (mProcessStateTimer[i] != null) { 6625 out.writeInt(1); 6626 mProcessStateTimer[i].writeToParcel(out, elapsedRealtimeUs); 6627 } else { 6628 out.writeInt(0); 6629 } 6630 } 6631 if (mVibratorOnTimer != null) { 6632 out.writeInt(1); 6633 mVibratorOnTimer.writeToParcel(out, elapsedRealtimeUs); 6634 } else { 6635 out.writeInt(0); 6636 } 6637 if (mUserActivityCounters != null) { 6638 out.writeInt(1); 6639 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) { 6640 mUserActivityCounters[i].writeToParcel(out); 6641 } 6642 } else { 6643 out.writeInt(0); 6644 } 6645 if (mNetworkByteActivityCounters != null) { 6646 out.writeInt(1); 6647 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 6648 mNetworkByteActivityCounters[i].writeToParcel(out); 6649 mNetworkPacketActivityCounters[i].writeToParcel(out); 6650 } 6651 mMobileRadioActiveTime.writeToParcel(out); 6652 mMobileRadioActiveCount.writeToParcel(out); 6653 } else { 6654 out.writeInt(0); 6655 } 6656 6657 if (mWifiControllerActivity != null) { 6658 out.writeInt(1); 6659 mWifiControllerActivity.writeToParcel(out, 0); 6660 } else { 6661 out.writeInt(0); 6662 } 6663 6664 if (mBluetoothControllerActivity != null) { 6665 out.writeInt(1); 6666 mBluetoothControllerActivity.writeToParcel(out, 0); 6667 } else { 6668 out.writeInt(0); 6669 } 6670 6671 if (mModemControllerActivity != null) { 6672 out.writeInt(1); 6673 mModemControllerActivity.writeToParcel(out, 0); 6674 } else { 6675 out.writeInt(0); 6676 } 6677 6678 mUserCpuTime.writeToParcel(out); 6679 mSystemCpuTime.writeToParcel(out); 6680 mCpuPower.writeToParcel(out); 6681 6682 if (mCpuClusterSpeed != null) { 6683 out.writeInt(1); 6684 out.writeInt(mCpuClusterSpeed.length); 6685 for (LongSamplingCounter[] cpuSpeeds : mCpuClusterSpeed) { 6686 if (cpuSpeeds != null) { 6687 out.writeInt(1); 6688 out.writeInt(cpuSpeeds.length); 6689 for (LongSamplingCounter c : cpuSpeeds) { 6690 if (c != null) { 6691 out.writeInt(1); 6692 c.writeToParcel(out); 6693 } else { 6694 out.writeInt(0); 6695 } 6696 } 6697 } else { 6698 out.writeInt(0); 6699 } 6700 } 6701 } else { 6702 out.writeInt(0); 6703 } 6704 6705 if (mMobileRadioApWakeupCount != null) { 6706 out.writeInt(1); 6707 mMobileRadioApWakeupCount.writeToParcel(out); 6708 } else { 6709 out.writeInt(0); 6710 } 6711 6712 if (mWifiRadioApWakeupCount != null) { 6713 out.writeInt(1); 6714 mWifiRadioApWakeupCount.writeToParcel(out); 6715 } else { 6716 out.writeInt(0); 6717 } 6718 } 6719 6720 void readFromParcelLocked(TimeBase timeBase, TimeBase screenOffTimeBase, Parcel in) { 6721 mOnBatteryBackgroundTimeBase.readFromParcel(in); 6722 6723 int numWakelocks = in.readInt(); 6724 mWakelockStats.clear(); 6725 for (int j = 0; j < numWakelocks; j++) { 6726 String wakelockName = in.readString(); 6727 Uid.Wakelock wakelock = new Wakelock(mBsi, this); 6728 wakelock.readFromParcelLocked(timeBase, screenOffTimeBase, in); 6729 mWakelockStats.add(wakelockName, wakelock); 6730 } 6731 6732 int numSyncs = in.readInt(); 6733 mSyncStats.clear(); 6734 for (int j = 0; j < numSyncs; j++) { 6735 String syncName = in.readString(); 6736 if (in.readInt() != 0) { 6737 mSyncStats.add(syncName, 6738 new StopwatchTimer(mBsi.mClocks, Uid.this, SYNC, null, timeBase, in)); 6739 } 6740 } 6741 6742 int numJobs = in.readInt(); 6743 mJobStats.clear(); 6744 for (int j = 0; j < numJobs; j++) { 6745 String jobName = in.readString(); 6746 if (in.readInt() != 0) { 6747 mJobStats.add(jobName, new DualTimer(mBsi.mClocks, Uid.this, JOB, null, 6748 mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase, in)); 6749 } 6750 } 6751 6752 int numSensors = in.readInt(); 6753 mSensorStats.clear(); 6754 for (int k = 0; k < numSensors; k++) { 6755 int sensorNumber = in.readInt(); 6756 Uid.Sensor sensor = new Sensor(mBsi, this, sensorNumber); 6757 sensor.readFromParcelLocked(mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase, 6758 in); 6759 mSensorStats.put(sensorNumber, sensor); 6760 } 6761 6762 int numProcs = in.readInt(); 6763 mProcessStats.clear(); 6764 for (int k = 0; k < numProcs; k++) { 6765 String processName = in.readString(); 6766 Uid.Proc proc = new Proc(mBsi, processName); 6767 proc.readFromParcelLocked(in); 6768 mProcessStats.put(processName, proc); 6769 } 6770 6771 int numPkgs = in.readInt(); 6772 mPackageStats.clear(); 6773 for (int l = 0; l < numPkgs; l++) { 6774 String packageName = in.readString(); 6775 Uid.Pkg pkg = new Pkg(mBsi); 6776 pkg.readFromParcelLocked(in); 6777 mPackageStats.put(packageName, pkg); 6778 } 6779 6780 mWifiRunning = false; 6781 if (in.readInt() != 0) { 6782 mWifiRunningTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, WIFI_RUNNING, 6783 mBsi.mWifiRunningTimers, mBsi.mOnBatteryTimeBase, in); 6784 } else { 6785 mWifiRunningTimer = null; 6786 } 6787 mFullWifiLockOut = false; 6788 if (in.readInt() != 0) { 6789 mFullWifiLockTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, FULL_WIFI_LOCK, 6790 mBsi.mFullWifiLockTimers, mBsi.mOnBatteryTimeBase, in); 6791 } else { 6792 mFullWifiLockTimer = null; 6793 } 6794 mWifiScanStarted = false; 6795 if (in.readInt() != 0) { 6796 mWifiScanTimer = new DualTimer(mBsi.mClocks, Uid.this, WIFI_SCAN, 6797 mBsi.mWifiScanTimers, mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase, 6798 in); 6799 } else { 6800 mWifiScanTimer = null; 6801 } 6802 mWifiBatchedScanBinStarted = NO_BATCHED_SCAN_STARTED; 6803 for (int i = 0; i < NUM_WIFI_BATCHED_SCAN_BINS; i++) { 6804 if (in.readInt() != 0) { 6805 makeWifiBatchedScanBin(i, in); 6806 } else { 6807 mWifiBatchedScanTimer[i] = null; 6808 } 6809 } 6810 mWifiMulticastEnabled = false; 6811 if (in.readInt() != 0) { 6812 mWifiMulticastTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, WIFI_MULTICAST_ENABLED, 6813 mBsi.mWifiMulticastTimers, mBsi.mOnBatteryTimeBase, in); 6814 } else { 6815 mWifiMulticastTimer = null; 6816 } 6817 if (in.readInt() != 0) { 6818 mAudioTurnedOnTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, AUDIO_TURNED_ON, 6819 mBsi.mAudioTurnedOnTimers, mBsi.mOnBatteryTimeBase, in); 6820 } else { 6821 mAudioTurnedOnTimer = null; 6822 } 6823 if (in.readInt() != 0) { 6824 mVideoTurnedOnTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, VIDEO_TURNED_ON, 6825 mBsi.mVideoTurnedOnTimers, mBsi.mOnBatteryTimeBase, in); 6826 } else { 6827 mVideoTurnedOnTimer = null; 6828 } 6829 if (in.readInt() != 0) { 6830 mFlashlightTurnedOnTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, 6831 FLASHLIGHT_TURNED_ON, mBsi.mFlashlightTurnedOnTimers, mBsi.mOnBatteryTimeBase, in); 6832 } else { 6833 mFlashlightTurnedOnTimer = null; 6834 } 6835 if (in.readInt() != 0) { 6836 mCameraTurnedOnTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, CAMERA_TURNED_ON, 6837 mBsi.mCameraTurnedOnTimers, mBsi.mOnBatteryTimeBase, in); 6838 } else { 6839 mCameraTurnedOnTimer = null; 6840 } 6841 if (in.readInt() != 0) { 6842 mForegroundActivityTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, 6843 FOREGROUND_ACTIVITY, null, mBsi.mOnBatteryTimeBase, in); 6844 } else { 6845 mForegroundActivityTimer = null; 6846 } 6847 if (in.readInt() != 0) { 6848 mBluetoothScanTimer = new DualTimer(mBsi.mClocks, Uid.this, BLUETOOTH_SCAN_ON, 6849 mBsi.mBluetoothScanOnTimers, mBsi.mOnBatteryTimeBase, 6850 mOnBatteryBackgroundTimeBase, in); 6851 } else { 6852 mBluetoothScanTimer = null; 6853 } 6854 mProcessState = ActivityManager.PROCESS_STATE_NONEXISTENT; 6855 for (int i = 0; i < NUM_PROCESS_STATE; i++) { 6856 if (in.readInt() != 0) { 6857 makeProcessState(i, in); 6858 } else { 6859 mProcessStateTimer[i] = null; 6860 } 6861 } 6862 if (in.readInt() != 0) { 6863 mVibratorOnTimer = new BatchTimer(mBsi.mClocks, Uid.this, VIBRATOR_ON, 6864 mBsi.mOnBatteryTimeBase, in); 6865 } else { 6866 mVibratorOnTimer = null; 6867 } 6868 if (in.readInt() != 0) { 6869 mUserActivityCounters = new Counter[NUM_USER_ACTIVITY_TYPES]; 6870 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) { 6871 mUserActivityCounters[i] = new Counter(mBsi.mOnBatteryTimeBase, in); 6872 } 6873 } else { 6874 mUserActivityCounters = null; 6875 } 6876 if (in.readInt() != 0) { 6877 mNetworkByteActivityCounters = new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES]; 6878 mNetworkPacketActivityCounters 6879 = new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES]; 6880 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 6881 mNetworkByteActivityCounters[i] 6882 = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in); 6883 mNetworkPacketActivityCounters[i] 6884 = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in); 6885 } 6886 mMobileRadioActiveTime = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in); 6887 mMobileRadioActiveCount = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in); 6888 } else { 6889 mNetworkByteActivityCounters = null; 6890 mNetworkPacketActivityCounters = null; 6891 } 6892 6893 if (in.readInt() != 0) { 6894 mWifiControllerActivity = new ControllerActivityCounterImpl(mBsi.mOnBatteryTimeBase, 6895 NUM_WIFI_TX_LEVELS, in); 6896 } else { 6897 mWifiControllerActivity = null; 6898 } 6899 6900 if (in.readInt() != 0) { 6901 mBluetoothControllerActivity = new ControllerActivityCounterImpl(mBsi.mOnBatteryTimeBase, 6902 NUM_BT_TX_LEVELS, in); 6903 } else { 6904 mBluetoothControllerActivity = null; 6905 } 6906 6907 if (in.readInt() != 0) { 6908 mModemControllerActivity = new ControllerActivityCounterImpl(mBsi.mOnBatteryTimeBase, 6909 ModemActivityInfo.TX_POWER_LEVELS, in); 6910 } else { 6911 mModemControllerActivity = null; 6912 } 6913 6914 mUserCpuTime = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in); 6915 mSystemCpuTime = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in); 6916 mCpuPower = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in); 6917 6918 if (in.readInt() != 0) { 6919 int numCpuClusters = in.readInt(); 6920 if (mBsi.mPowerProfile != null && mBsi.mPowerProfile.getNumCpuClusters() != numCpuClusters) { 6921 throw new ParcelFormatException("Incompatible number of cpu clusters"); 6922 } 6923 6924 mCpuClusterSpeed = new LongSamplingCounter[numCpuClusters][]; 6925 for (int cluster = 0; cluster < numCpuClusters; cluster++) { 6926 if (in.readInt() != 0) { 6927 int numSpeeds = in.readInt(); 6928 if (mBsi.mPowerProfile != null && 6929 mBsi.mPowerProfile.getNumSpeedStepsInCpuCluster(cluster) != numSpeeds) { 6930 throw new ParcelFormatException("Incompatible number of cpu speeds"); 6931 } 6932 6933 final LongSamplingCounter[] cpuSpeeds = new LongSamplingCounter[numSpeeds]; 6934 mCpuClusterSpeed[cluster] = cpuSpeeds; 6935 for (int speed = 0; speed < numSpeeds; speed++) { 6936 if (in.readInt() != 0) { 6937 cpuSpeeds[speed] = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in); 6938 } 6939 } 6940 } else { 6941 mCpuClusterSpeed[cluster] = null; 6942 } 6943 } 6944 } else { 6945 mCpuClusterSpeed = null; 6946 } 6947 6948 if (in.readInt() != 0) { 6949 mMobileRadioApWakeupCount = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in); 6950 } else { 6951 mMobileRadioApWakeupCount = null; 6952 } 6953 6954 if (in.readInt() != 0) { 6955 mWifiRadioApWakeupCount = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in); 6956 } else { 6957 mWifiRadioApWakeupCount = null; 6958 } 6959 } 6960 6961 /** 6962 * The statistics associated with a particular wake lock. 6963 */ 6964 public static class Wakelock extends BatteryStats.Uid.Wakelock { 6965 /** 6966 * BatteryStatsImpl that we are associated with. 6967 */ 6968 protected BatteryStatsImpl mBsi; 6969 6970 /** 6971 * BatteryStatsImpl that we are associated with. 6972 */ 6973 protected Uid mUid; 6974 6975 /** 6976 * How long (in ms) this uid has been keeping the device partially awake. 6977 */ 6978 DurationTimer mTimerPartial; 6979 6980 /** 6981 * How long (in ms) this uid has been keeping the device fully awake. 6982 */ 6983 StopwatchTimer mTimerFull; 6984 6985 /** 6986 * How long (in ms) this uid has had a window keeping the device awake. 6987 */ 6988 StopwatchTimer mTimerWindow; 6989 6990 /** 6991 * How long (in ms) this uid has had a draw wake lock. 6992 */ 6993 StopwatchTimer mTimerDraw; 6994 6995 public Wakelock(BatteryStatsImpl bsi, Uid uid) { 6996 mBsi = bsi; 6997 mUid = uid; 6998 } 6999 7000 /** 7001 * Reads a possibly null Timer from a Parcel. The timer is associated with the 7002 * proper timer pool from the given BatteryStatsImpl object. 7003 * 7004 * @param in the Parcel to be read from. 7005 * return a new Timer, or null. 7006 */ 7007 private StopwatchTimer readStopwatchTimerFromParcel(int type, 7008 ArrayList<StopwatchTimer> pool, TimeBase timeBase, Parcel in) { 7009 if (in.readInt() == 0) { 7010 return null; 7011 } 7012 7013 return new StopwatchTimer(mBsi.mClocks, mUid, type, pool, timeBase, in); 7014 } 7015 7016 /** 7017 * Reads a possibly null Timer from a Parcel. The timer is associated with the 7018 * proper timer pool from the given BatteryStatsImpl object. 7019 * 7020 * @param in the Parcel to be read from. 7021 * return a new Timer, or null. 7022 */ 7023 private DurationTimer readDurationTimerFromParcel(int type, 7024 ArrayList<StopwatchTimer> pool, TimeBase timeBase, Parcel in) { 7025 if (in.readInt() == 0) { 7026 return null; 7027 } 7028 7029 return new DurationTimer(mBsi.mClocks, mUid, type, pool, timeBase, in); 7030 } 7031 7032 boolean reset() { 7033 boolean wlactive = false; 7034 if (mTimerFull != null) { 7035 wlactive |= !mTimerFull.reset(false); 7036 } 7037 if (mTimerPartial != null) { 7038 wlactive |= !mTimerPartial.reset(false); 7039 } 7040 if (mTimerWindow != null) { 7041 wlactive |= !mTimerWindow.reset(false); 7042 } 7043 if (mTimerDraw != null) { 7044 wlactive |= !mTimerDraw.reset(false); 7045 } 7046 if (!wlactive) { 7047 if (mTimerFull != null) { 7048 mTimerFull.detach(); 7049 mTimerFull = null; 7050 } 7051 if (mTimerPartial != null) { 7052 mTimerPartial.detach(); 7053 mTimerPartial = null; 7054 } 7055 if (mTimerWindow != null) { 7056 mTimerWindow.detach(); 7057 mTimerWindow = null; 7058 } 7059 if (mTimerDraw != null) { 7060 mTimerDraw.detach(); 7061 mTimerDraw = null; 7062 } 7063 } 7064 return !wlactive; 7065 } 7066 7067 void readFromParcelLocked(TimeBase timeBase, TimeBase screenOffTimeBase, Parcel in) { 7068 mTimerPartial = readDurationTimerFromParcel(WAKE_TYPE_PARTIAL, 7069 mBsi.mPartialTimers, screenOffTimeBase, in); 7070 mTimerFull = readStopwatchTimerFromParcel(WAKE_TYPE_FULL, 7071 mBsi.mFullTimers, timeBase, in); 7072 mTimerWindow = readStopwatchTimerFromParcel(WAKE_TYPE_WINDOW, 7073 mBsi.mWindowTimers, timeBase, in); 7074 mTimerDraw = readStopwatchTimerFromParcel(WAKE_TYPE_DRAW, 7075 mBsi.mDrawTimers, timeBase, in); 7076 } 7077 7078 void writeToParcelLocked(Parcel out, long elapsedRealtimeUs) { 7079 Timer.writeTimerToParcel(out, mTimerPartial, elapsedRealtimeUs); 7080 Timer.writeTimerToParcel(out, mTimerFull, elapsedRealtimeUs); 7081 Timer.writeTimerToParcel(out, mTimerWindow, elapsedRealtimeUs); 7082 Timer.writeTimerToParcel(out, mTimerDraw, elapsedRealtimeUs); 7083 } 7084 7085 @Override 7086 public Timer getWakeTime(int type) { 7087 switch (type) { 7088 case WAKE_TYPE_FULL: return mTimerFull; 7089 case WAKE_TYPE_PARTIAL: return mTimerPartial; 7090 case WAKE_TYPE_WINDOW: return mTimerWindow; 7091 case WAKE_TYPE_DRAW: return mTimerDraw; 7092 default: throw new IllegalArgumentException("type = " + type); 7093 } 7094 } 7095 7096 public StopwatchTimer getStopwatchTimer(int type) { 7097 switch (type) { 7098 case WAKE_TYPE_PARTIAL: { 7099 DurationTimer t = mTimerPartial; 7100 if (t == null) { 7101 t = new DurationTimer(mBsi.mClocks, mUid, WAKE_TYPE_PARTIAL, 7102 mBsi.mPartialTimers, mBsi.mOnBatteryScreenOffTimeBase); 7103 mTimerPartial = t; 7104 } 7105 return t; 7106 } 7107 case WAKE_TYPE_FULL: { 7108 StopwatchTimer t = mTimerFull; 7109 if (t == null) { 7110 t = new StopwatchTimer(mBsi.mClocks, mUid, WAKE_TYPE_FULL, 7111 mBsi.mFullTimers, mBsi.mOnBatteryTimeBase); 7112 mTimerFull = t; 7113 } 7114 return t; 7115 } 7116 case WAKE_TYPE_WINDOW: { 7117 StopwatchTimer t = mTimerWindow; 7118 if (t == null) { 7119 t = new StopwatchTimer(mBsi.mClocks, mUid, WAKE_TYPE_WINDOW, 7120 mBsi.mWindowTimers, mBsi.mOnBatteryTimeBase); 7121 mTimerWindow = t; 7122 } 7123 return t; 7124 } 7125 case WAKE_TYPE_DRAW: { 7126 StopwatchTimer t = mTimerDraw; 7127 if (t == null) { 7128 t = new StopwatchTimer(mBsi.mClocks, mUid, WAKE_TYPE_DRAW, 7129 mBsi.mDrawTimers, mBsi.mOnBatteryTimeBase); 7130 mTimerDraw = t; 7131 } 7132 return t; 7133 } 7134 default: 7135 throw new IllegalArgumentException("type=" + type); 7136 } 7137 } 7138 } 7139 7140 public static class Sensor extends BatteryStats.Uid.Sensor { 7141 /** 7142 * BatteryStatsImpl that we are associated with. 7143 */ 7144 protected BatteryStatsImpl mBsi; 7145 7146 /** 7147 * Uid that we are associated with. 7148 */ 7149 protected Uid mUid; 7150 7151 final int mHandle; 7152 DualTimer mTimer; 7153 7154 public Sensor(BatteryStatsImpl bsi, Uid uid, int handle) { 7155 mBsi = bsi; 7156 mUid = uid; 7157 mHandle = handle; 7158 } 7159 7160 private DualTimer readTimersFromParcel( 7161 TimeBase timeBase, TimeBase bgTimeBase, Parcel in) { 7162 if (in.readInt() == 0) { 7163 return null; 7164 } 7165 7166 ArrayList<StopwatchTimer> pool = mBsi.mSensorTimers.get(mHandle); 7167 if (pool == null) { 7168 pool = new ArrayList<StopwatchTimer>(); 7169 mBsi.mSensorTimers.put(mHandle, pool); 7170 } 7171 return new DualTimer(mBsi.mClocks, mUid, 0, pool, timeBase, bgTimeBase, in); 7172 } 7173 7174 boolean reset() { 7175 if (mTimer.reset(true)) { 7176 mTimer = null; 7177 return true; 7178 } 7179 return false; 7180 } 7181 7182 void readFromParcelLocked(TimeBase timeBase, TimeBase bgTimeBase, Parcel in) { 7183 mTimer = readTimersFromParcel(timeBase, bgTimeBase, in); 7184 } 7185 7186 void writeToParcelLocked(Parcel out, long elapsedRealtimeUs) { 7187 Timer.writeTimerToParcel(out, mTimer, elapsedRealtimeUs); 7188 } 7189 7190 @Override 7191 public Timer getSensorTime() { 7192 return mTimer; 7193 } 7194 7195 @Override 7196 public Timer getSensorBackgroundTime() { 7197 if (mTimer == null) { 7198 return null; 7199 } 7200 return mTimer.getSubTimer(); 7201 } 7202 7203 @Override 7204 public int getHandle() { 7205 return mHandle; 7206 } 7207 } 7208 7209 /** 7210 * The statistics associated with a particular process. 7211 */ 7212 public static class Proc extends BatteryStats.Uid.Proc implements TimeBaseObs { 7213 /** 7214 * BatteryStatsImpl that we are associated with. 7215 */ 7216 protected BatteryStatsImpl mBsi; 7217 7218 /** 7219 * The name of this process. 7220 */ 7221 final String mName; 7222 7223 /** 7224 * Remains true until removed from the stats. 7225 */ 7226 boolean mActive = true; 7227 7228 /** 7229 * Total time (in ms) spent executing in user code. 7230 */ 7231 long mUserTime; 7232 7233 /** 7234 * Total time (in ms) spent executing in kernel code. 7235 */ 7236 long mSystemTime; 7237 7238 /** 7239 * Amount of time (in ms) the process was running in the foreground. 7240 */ 7241 long mForegroundTime; 7242 7243 /** 7244 * Number of times the process has been started. 7245 */ 7246 int mStarts; 7247 7248 /** 7249 * Number of times the process has crashed. 7250 */ 7251 int mNumCrashes; 7252 7253 /** 7254 * Number of times the process has had an ANR. 7255 */ 7256 int mNumAnrs; 7257 7258 /** 7259 * The amount of user time loaded from a previous save. 7260 */ 7261 long mLoadedUserTime; 7262 7263 /** 7264 * The amount of system time loaded from a previous save. 7265 */ 7266 long mLoadedSystemTime; 7267 7268 /** 7269 * The amount of foreground time loaded from a previous save. 7270 */ 7271 long mLoadedForegroundTime; 7272 7273 /** 7274 * The number of times the process has started from a previous save. 7275 */ 7276 int mLoadedStarts; 7277 7278 /** 7279 * Number of times the process has crashed from a previous save. 7280 */ 7281 int mLoadedNumCrashes; 7282 7283 /** 7284 * Number of times the process has had an ANR from a previous save. 7285 */ 7286 int mLoadedNumAnrs; 7287 7288 /** 7289 * The amount of user time when last unplugged. 7290 */ 7291 long mUnpluggedUserTime; 7292 7293 /** 7294 * The amount of system time when last unplugged. 7295 */ 7296 long mUnpluggedSystemTime; 7297 7298 /** 7299 * The amount of foreground time since unplugged. 7300 */ 7301 long mUnpluggedForegroundTime; 7302 7303 /** 7304 * The number of times the process has started before unplugged. 7305 */ 7306 int mUnpluggedStarts; 7307 7308 /** 7309 * Number of times the process has crashed before unplugged. 7310 */ 7311 int mUnpluggedNumCrashes; 7312 7313 /** 7314 * Number of times the process has had an ANR before unplugged. 7315 */ 7316 int mUnpluggedNumAnrs; 7317 7318 ArrayList<ExcessivePower> mExcessivePower; 7319 7320 public Proc(BatteryStatsImpl bsi, String name) { 7321 mBsi = bsi; 7322 mName = name; 7323 mBsi.mOnBatteryTimeBase.add(this); 7324 } 7325 7326 public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) { 7327 mUnpluggedUserTime = mUserTime; 7328 mUnpluggedSystemTime = mSystemTime; 7329 mUnpluggedForegroundTime = mForegroundTime; 7330 mUnpluggedStarts = mStarts; 7331 mUnpluggedNumCrashes = mNumCrashes; 7332 mUnpluggedNumAnrs = mNumAnrs; 7333 } 7334 7335 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) { 7336 } 7337 7338 void detach() { 7339 mActive = false; 7340 mBsi.mOnBatteryTimeBase.remove(this); 7341 } 7342 7343 public int countExcessivePowers() { 7344 return mExcessivePower != null ? mExcessivePower.size() : 0; 7345 } 7346 7347 public ExcessivePower getExcessivePower(int i) { 7348 if (mExcessivePower != null) { 7349 return mExcessivePower.get(i); 7350 } 7351 return null; 7352 } 7353 7354 public void addExcessiveWake(long overTime, long usedTime) { 7355 if (mExcessivePower == null) { 7356 mExcessivePower = new ArrayList<ExcessivePower>(); 7357 } 7358 ExcessivePower ew = new ExcessivePower(); 7359 ew.type = ExcessivePower.TYPE_WAKE; 7360 ew.overTime = overTime; 7361 ew.usedTime = usedTime; 7362 mExcessivePower.add(ew); 7363 } 7364 7365 public void addExcessiveCpu(long overTime, long usedTime) { 7366 if (mExcessivePower == null) { 7367 mExcessivePower = new ArrayList<ExcessivePower>(); 7368 } 7369 ExcessivePower ew = new ExcessivePower(); 7370 ew.type = ExcessivePower.TYPE_CPU; 7371 ew.overTime = overTime; 7372 ew.usedTime = usedTime; 7373 mExcessivePower.add(ew); 7374 } 7375 7376 void writeExcessivePowerToParcelLocked(Parcel out) { 7377 if (mExcessivePower == null) { 7378 out.writeInt(0); 7379 return; 7380 } 7381 7382 final int N = mExcessivePower.size(); 7383 out.writeInt(N); 7384 for (int i=0; i<N; i++) { 7385 ExcessivePower ew = mExcessivePower.get(i); 7386 out.writeInt(ew.type); 7387 out.writeLong(ew.overTime); 7388 out.writeLong(ew.usedTime); 7389 } 7390 } 7391 7392 void readExcessivePowerFromParcelLocked(Parcel in) { 7393 final int N = in.readInt(); 7394 if (N == 0) { 7395 mExcessivePower = null; 7396 return; 7397 } 7398 7399 if (N > 10000) { 7400 throw new ParcelFormatException( 7401 "File corrupt: too many excessive power entries " + N); 7402 } 7403 7404 mExcessivePower = new ArrayList<>(); 7405 for (int i=0; i<N; i++) { 7406 ExcessivePower ew = new ExcessivePower(); 7407 ew.type = in.readInt(); 7408 ew.overTime = in.readLong(); 7409 ew.usedTime = in.readLong(); 7410 mExcessivePower.add(ew); 7411 } 7412 } 7413 7414 void writeToParcelLocked(Parcel out) { 7415 out.writeLong(mUserTime); 7416 out.writeLong(mSystemTime); 7417 out.writeLong(mForegroundTime); 7418 out.writeInt(mStarts); 7419 out.writeInt(mNumCrashes); 7420 out.writeInt(mNumAnrs); 7421 out.writeLong(mLoadedUserTime); 7422 out.writeLong(mLoadedSystemTime); 7423 out.writeLong(mLoadedForegroundTime); 7424 out.writeInt(mLoadedStarts); 7425 out.writeInt(mLoadedNumCrashes); 7426 out.writeInt(mLoadedNumAnrs); 7427 out.writeLong(mUnpluggedUserTime); 7428 out.writeLong(mUnpluggedSystemTime); 7429 out.writeLong(mUnpluggedForegroundTime); 7430 out.writeInt(mUnpluggedStarts); 7431 out.writeInt(mUnpluggedNumCrashes); 7432 out.writeInt(mUnpluggedNumAnrs); 7433 writeExcessivePowerToParcelLocked(out); 7434 } 7435 7436 void readFromParcelLocked(Parcel in) { 7437 mUserTime = in.readLong(); 7438 mSystemTime = in.readLong(); 7439 mForegroundTime = in.readLong(); 7440 mStarts = in.readInt(); 7441 mNumCrashes = in.readInt(); 7442 mNumAnrs = in.readInt(); 7443 mLoadedUserTime = in.readLong(); 7444 mLoadedSystemTime = in.readLong(); 7445 mLoadedForegroundTime = in.readLong(); 7446 mLoadedStarts = in.readInt(); 7447 mLoadedNumCrashes = in.readInt(); 7448 mLoadedNumAnrs = in.readInt(); 7449 mUnpluggedUserTime = in.readLong(); 7450 mUnpluggedSystemTime = in.readLong(); 7451 mUnpluggedForegroundTime = in.readLong(); 7452 mUnpluggedStarts = in.readInt(); 7453 mUnpluggedNumCrashes = in.readInt(); 7454 mUnpluggedNumAnrs = in.readInt(); 7455 readExcessivePowerFromParcelLocked(in); 7456 } 7457 7458 public void addCpuTimeLocked(int utime, int stime) { 7459 mUserTime += utime; 7460 mSystemTime += stime; 7461 } 7462 7463 public void addForegroundTimeLocked(long ttime) { 7464 mForegroundTime += ttime; 7465 } 7466 7467 public void incStartsLocked() { 7468 mStarts++; 7469 } 7470 7471 public void incNumCrashesLocked() { 7472 mNumCrashes++; 7473 } 7474 7475 public void incNumAnrsLocked() { 7476 mNumAnrs++; 7477 } 7478 7479 @Override 7480 public boolean isActive() { 7481 return mActive; 7482 } 7483 7484 @Override 7485 public long getUserTime(int which) { 7486 long val = mUserTime; 7487 if (which == STATS_CURRENT) { 7488 val -= mLoadedUserTime; 7489 } else if (which == STATS_SINCE_UNPLUGGED) { 7490 val -= mUnpluggedUserTime; 7491 } 7492 return val; 7493 } 7494 7495 @Override 7496 public long getSystemTime(int which) { 7497 long val = mSystemTime; 7498 if (which == STATS_CURRENT) { 7499 val -= mLoadedSystemTime; 7500 } else if (which == STATS_SINCE_UNPLUGGED) { 7501 val -= mUnpluggedSystemTime; 7502 } 7503 return val; 7504 } 7505 7506 @Override 7507 public long getForegroundTime(int which) { 7508 long val = mForegroundTime; 7509 if (which == STATS_CURRENT) { 7510 val -= mLoadedForegroundTime; 7511 } else if (which == STATS_SINCE_UNPLUGGED) { 7512 val -= mUnpluggedForegroundTime; 7513 } 7514 return val; 7515 } 7516 7517 @Override 7518 public int getStarts(int which) { 7519 int val = mStarts; 7520 if (which == STATS_CURRENT) { 7521 val -= mLoadedStarts; 7522 } else if (which == STATS_SINCE_UNPLUGGED) { 7523 val -= mUnpluggedStarts; 7524 } 7525 return val; 7526 } 7527 7528 @Override 7529 public int getNumCrashes(int which) { 7530 int val = mNumCrashes; 7531 if (which == STATS_CURRENT) { 7532 val -= mLoadedNumCrashes; 7533 } else if (which == STATS_SINCE_UNPLUGGED) { 7534 val -= mUnpluggedNumCrashes; 7535 } 7536 return val; 7537 } 7538 7539 @Override 7540 public int getNumAnrs(int which) { 7541 int val = mNumAnrs; 7542 if (which == STATS_CURRENT) { 7543 val -= mLoadedNumAnrs; 7544 } else if (which == STATS_SINCE_UNPLUGGED) { 7545 val -= mUnpluggedNumAnrs; 7546 } 7547 return val; 7548 } 7549 } 7550 7551 /** 7552 * The statistics associated with a particular package. 7553 */ 7554 public static class Pkg extends BatteryStats.Uid.Pkg implements TimeBaseObs { 7555 /** 7556 * BatteryStatsImpl that we are associated with. 7557 */ 7558 protected BatteryStatsImpl mBsi; 7559 7560 /** 7561 * Number of times wakeup alarms have occurred for this app. 7562 */ 7563 ArrayMap<String, Counter> mWakeupAlarms = new ArrayMap<>(); 7564 7565 /** 7566 * The statics we have collected for this package's services. 7567 */ 7568 final ArrayMap<String, Serv> mServiceStats = new ArrayMap<>(); 7569 7570 public Pkg(BatteryStatsImpl bsi) { 7571 mBsi = bsi; 7572 mBsi.mOnBatteryScreenOffTimeBase.add(this); 7573 } 7574 7575 public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) { 7576 } 7577 7578 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) { 7579 } 7580 7581 void detach() { 7582 mBsi.mOnBatteryScreenOffTimeBase.remove(this); 7583 } 7584 7585 void readFromParcelLocked(Parcel in) { 7586 int numWA = in.readInt(); 7587 mWakeupAlarms.clear(); 7588 for (int i=0; i<numWA; i++) { 7589 String tag = in.readString(); 7590 mWakeupAlarms.put(tag, new Counter(mBsi.mOnBatteryTimeBase, in)); 7591 } 7592 7593 int numServs = in.readInt(); 7594 mServiceStats.clear(); 7595 for (int m = 0; m < numServs; m++) { 7596 String serviceName = in.readString(); 7597 Uid.Pkg.Serv serv = new Serv(mBsi); 7598 mServiceStats.put(serviceName, serv); 7599 7600 serv.readFromParcelLocked(in); 7601 } 7602 } 7603 7604 void writeToParcelLocked(Parcel out) { 7605 int numWA = mWakeupAlarms.size(); 7606 out.writeInt(numWA); 7607 for (int i=0; i<numWA; i++) { 7608 out.writeString(mWakeupAlarms.keyAt(i)); 7609 mWakeupAlarms.valueAt(i).writeToParcel(out); 7610 } 7611 7612 final int NS = mServiceStats.size(); 7613 out.writeInt(NS); 7614 for (int i=0; i<NS; i++) { 7615 out.writeString(mServiceStats.keyAt(i)); 7616 Uid.Pkg.Serv serv = mServiceStats.valueAt(i); 7617 serv.writeToParcelLocked(out); 7618 } 7619 } 7620 7621 @Override 7622 public ArrayMap<String, ? extends BatteryStats.Counter> getWakeupAlarmStats() { 7623 return mWakeupAlarms; 7624 } 7625 7626 public void noteWakeupAlarmLocked(String tag) { 7627 Counter c = mWakeupAlarms.get(tag); 7628 if (c == null) { 7629 c = new Counter(mBsi.mOnBatteryTimeBase); 7630 mWakeupAlarms.put(tag, c); 7631 } 7632 c.stepAtomic(); 7633 } 7634 7635 @Override 7636 public ArrayMap<String, ? extends BatteryStats.Uid.Pkg.Serv> getServiceStats() { 7637 return mServiceStats; 7638 } 7639 7640 /** 7641 * The statistics associated with a particular service. 7642 */ 7643 public static class Serv extends BatteryStats.Uid.Pkg.Serv implements TimeBaseObs { 7644 /** 7645 * BatteryStatsImpl that we are associated with. 7646 */ 7647 protected BatteryStatsImpl mBsi; 7648 7649 /** 7650 * The android package in which this service resides. 7651 */ 7652 protected Pkg mPkg; 7653 7654 /** 7655 * Total time (ms in battery uptime) the service has been left started. 7656 */ 7657 protected long mStartTime; 7658 7659 /** 7660 * If service has been started and not yet stopped, this is 7661 * when it was started. 7662 */ 7663 protected long mRunningSince; 7664 7665 /** 7666 * True if we are currently running. 7667 */ 7668 protected boolean mRunning; 7669 7670 /** 7671 * Total number of times startService() has been called. 7672 */ 7673 protected int mStarts; 7674 7675 /** 7676 * Total time (ms in battery uptime) the service has been left launched. 7677 */ 7678 protected long mLaunchedTime; 7679 7680 /** 7681 * If service has been launched and not yet exited, this is 7682 * when it was launched (ms in battery uptime). 7683 */ 7684 protected long mLaunchedSince; 7685 7686 /** 7687 * True if we are currently launched. 7688 */ 7689 protected boolean mLaunched; 7690 7691 /** 7692 * Total number times the service has been launched. 7693 */ 7694 protected int mLaunches; 7695 7696 /** 7697 * The amount of time spent started loaded from a previous save 7698 * (ms in battery uptime). 7699 */ 7700 protected long mLoadedStartTime; 7701 7702 /** 7703 * The number of starts loaded from a previous save. 7704 */ 7705 protected int mLoadedStarts; 7706 7707 /** 7708 * The number of launches loaded from a previous save. 7709 */ 7710 protected int mLoadedLaunches; 7711 7712 /** 7713 * The amount of time spent started as of the last run (ms 7714 * in battery uptime). 7715 */ 7716 protected long mLastStartTime; 7717 7718 /** 7719 * The number of starts as of the last run. 7720 */ 7721 protected int mLastStarts; 7722 7723 /** 7724 * The number of launches as of the last run. 7725 */ 7726 protected int mLastLaunches; 7727 7728 /** 7729 * The amount of time spent started when last unplugged (ms 7730 * in battery uptime). 7731 */ 7732 protected long mUnpluggedStartTime; 7733 7734 /** 7735 * The number of starts when last unplugged. 7736 */ 7737 protected int mUnpluggedStarts; 7738 7739 /** 7740 * The number of launches when last unplugged. 7741 */ 7742 protected int mUnpluggedLaunches; 7743 7744 /** 7745 * Construct a Serv. Also adds it to the on-battery time base as a listener. 7746 */ 7747 public Serv(BatteryStatsImpl bsi) { 7748 mBsi = bsi; 7749 mBsi.mOnBatteryTimeBase.add(this); 7750 } 7751 7752 public void onTimeStarted(long elapsedRealtime, long baseUptime, 7753 long baseRealtime) { 7754 mUnpluggedStartTime = getStartTimeToNowLocked(baseUptime); 7755 mUnpluggedStarts = mStarts; 7756 mUnpluggedLaunches = mLaunches; 7757 } 7758 7759 public void onTimeStopped(long elapsedRealtime, long baseUptime, 7760 long baseRealtime) { 7761 } 7762 7763 /** 7764 * Remove this Serv as a listener from the time base. 7765 */ 7766 public void detach() { 7767 mBsi.mOnBatteryTimeBase.remove(this); 7768 } 7769 7770 public void readFromParcelLocked(Parcel in) { 7771 mStartTime = in.readLong(); 7772 mRunningSince = in.readLong(); 7773 mRunning = in.readInt() != 0; 7774 mStarts = in.readInt(); 7775 mLaunchedTime = in.readLong(); 7776 mLaunchedSince = in.readLong(); 7777 mLaunched = in.readInt() != 0; 7778 mLaunches = in.readInt(); 7779 mLoadedStartTime = in.readLong(); 7780 mLoadedStarts = in.readInt(); 7781 mLoadedLaunches = in.readInt(); 7782 mLastStartTime = 0; 7783 mLastStarts = 0; 7784 mLastLaunches = 0; 7785 mUnpluggedStartTime = in.readLong(); 7786 mUnpluggedStarts = in.readInt(); 7787 mUnpluggedLaunches = in.readInt(); 7788 } 7789 7790 public void writeToParcelLocked(Parcel out) { 7791 out.writeLong(mStartTime); 7792 out.writeLong(mRunningSince); 7793 out.writeInt(mRunning ? 1 : 0); 7794 out.writeInt(mStarts); 7795 out.writeLong(mLaunchedTime); 7796 out.writeLong(mLaunchedSince); 7797 out.writeInt(mLaunched ? 1 : 0); 7798 out.writeInt(mLaunches); 7799 out.writeLong(mLoadedStartTime); 7800 out.writeInt(mLoadedStarts); 7801 out.writeInt(mLoadedLaunches); 7802 out.writeLong(mUnpluggedStartTime); 7803 out.writeInt(mUnpluggedStarts); 7804 out.writeInt(mUnpluggedLaunches); 7805 } 7806 7807 public long getLaunchTimeToNowLocked(long batteryUptime) { 7808 if (!mLaunched) return mLaunchedTime; 7809 return mLaunchedTime + batteryUptime - mLaunchedSince; 7810 } 7811 7812 public long getStartTimeToNowLocked(long batteryUptime) { 7813 if (!mRunning) return mStartTime; 7814 return mStartTime + batteryUptime - mRunningSince; 7815 } 7816 7817 public void startLaunchedLocked() { 7818 if (!mLaunched) { 7819 mLaunches++; 7820 mLaunchedSince = mBsi.getBatteryUptimeLocked(); 7821 mLaunched = true; 7822 } 7823 } 7824 7825 public void stopLaunchedLocked() { 7826 if (mLaunched) { 7827 long time = mBsi.getBatteryUptimeLocked() - mLaunchedSince; 7828 if (time > 0) { 7829 mLaunchedTime += time; 7830 } else { 7831 mLaunches--; 7832 } 7833 mLaunched = false; 7834 } 7835 } 7836 7837 public void startRunningLocked() { 7838 if (!mRunning) { 7839 mStarts++; 7840 mRunningSince = mBsi.getBatteryUptimeLocked(); 7841 mRunning = true; 7842 } 7843 } 7844 7845 public void stopRunningLocked() { 7846 if (mRunning) { 7847 long time = mBsi.getBatteryUptimeLocked() - mRunningSince; 7848 if (time > 0) { 7849 mStartTime += time; 7850 } else { 7851 mStarts--; 7852 } 7853 mRunning = false; 7854 } 7855 } 7856 7857 public BatteryStatsImpl getBatteryStats() { 7858 return mBsi; 7859 } 7860 7861 @Override 7862 public int getLaunches(int which) { 7863 int val = mLaunches; 7864 if (which == STATS_CURRENT) { 7865 val -= mLoadedLaunches; 7866 } else if (which == STATS_SINCE_UNPLUGGED) { 7867 val -= mUnpluggedLaunches; 7868 } 7869 return val; 7870 } 7871 7872 @Override 7873 public long getStartTime(long now, int which) { 7874 long val = getStartTimeToNowLocked(now); 7875 if (which == STATS_CURRENT) { 7876 val -= mLoadedStartTime; 7877 } else if (which == STATS_SINCE_UNPLUGGED) { 7878 val -= mUnpluggedStartTime; 7879 } 7880 return val; 7881 } 7882 7883 @Override 7884 public int getStarts(int which) { 7885 int val = mStarts; 7886 if (which == STATS_CURRENT) { 7887 val -= mLoadedStarts; 7888 } else if (which == STATS_SINCE_UNPLUGGED) { 7889 val -= mUnpluggedStarts; 7890 } 7891 7892 return val; 7893 } 7894 } 7895 7896 final Serv newServiceStatsLocked() { 7897 return new Serv(mBsi); 7898 } 7899 } 7900 7901 /** 7902 * Retrieve the statistics object for a particular process, creating 7903 * if needed. 7904 */ 7905 public Proc getProcessStatsLocked(String name) { 7906 Proc ps = mProcessStats.get(name); 7907 if (ps == null) { 7908 ps = new Proc(mBsi, name); 7909 mProcessStats.put(name, ps); 7910 } 7911 7912 return ps; 7913 } 7914 7915 public void updateUidProcessStateLocked(int procState) { 7916 int uidRunningState; 7917 if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT) { 7918 uidRunningState = ActivityManager.PROCESS_STATE_NONEXISTENT; 7919 } else if (procState == ActivityManager.PROCESS_STATE_TOP) { 7920 uidRunningState = PROCESS_STATE_TOP; 7921 } else if (procState <= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) { 7922 // Persistent and other foreground states go here. 7923 uidRunningState = PROCESS_STATE_FOREGROUND_SERVICE; 7924 } else if (procState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) { 7925 uidRunningState = PROCESS_STATE_TOP_SLEEPING; 7926 } else if (procState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 7927 // Persistent and other foreground states go here. 7928 uidRunningState = PROCESS_STATE_FOREGROUND; 7929 } else if (procState <= ActivityManager.PROCESS_STATE_RECEIVER) { 7930 uidRunningState = PROCESS_STATE_BACKGROUND; 7931 } else { 7932 uidRunningState = PROCESS_STATE_CACHED; 7933 } 7934 7935 if (mProcessState == uidRunningState) return; 7936 7937 final long elapsedRealtimeMs = mBsi.mClocks.elapsedRealtime(); 7938 final long uptimeMs = mBsi.mClocks.uptimeMillis(); 7939 7940 if (mProcessState != ActivityManager.PROCESS_STATE_NONEXISTENT) { 7941 mProcessStateTimer[mProcessState].stopRunningLocked(elapsedRealtimeMs); 7942 } 7943 mProcessState = uidRunningState; 7944 if (uidRunningState != ActivityManager.PROCESS_STATE_NONEXISTENT) { 7945 if (mProcessStateTimer[uidRunningState] == null) { 7946 makeProcessState(uidRunningState, null); 7947 } 7948 mProcessStateTimer[uidRunningState].startRunningLocked(elapsedRealtimeMs); 7949 } 7950 7951 updateBgTimeBase(uptimeMs * 1000, elapsedRealtimeMs * 1000); 7952 } 7953 7954 public boolean updateBgTimeBase(long uptimeUs, long realtimeUs) { 7955 // Note that PROCESS_STATE_CACHED and ActivityManager.PROCESS_STATE_NONEXISTENT is 7956 // also considered to be 'background' for our purposes, because it's not foreground. 7957 boolean isBgAndUnplugged = mBsi.mOnBatteryTimeBase.isRunning() 7958 && mProcessState >= PROCESS_STATE_BACKGROUND; 7959 return mOnBatteryBackgroundTimeBase.setRunning(isBgAndUnplugged, uptimeUs, realtimeUs); 7960 } 7961 7962 public SparseArray<? extends Pid> getPidStats() { 7963 return mPids; 7964 } 7965 7966 public Pid getPidStatsLocked(int pid) { 7967 Pid p = mPids.get(pid); 7968 if (p == null) { 7969 p = new Pid(); 7970 mPids.put(pid, p); 7971 } 7972 return p; 7973 } 7974 7975 /** 7976 * Retrieve the statistics object for a particular service, creating 7977 * if needed. 7978 */ 7979 public Pkg getPackageStatsLocked(String name) { 7980 Pkg ps = mPackageStats.get(name); 7981 if (ps == null) { 7982 ps = new Pkg(mBsi); 7983 mPackageStats.put(name, ps); 7984 } 7985 7986 return ps; 7987 } 7988 7989 /** 7990 * Retrieve the statistics object for a particular service, creating 7991 * if needed. 7992 */ 7993 public Pkg.Serv getServiceStatsLocked(String pkg, String serv) { 7994 Pkg ps = getPackageStatsLocked(pkg); 7995 Pkg.Serv ss = ps.mServiceStats.get(serv); 7996 if (ss == null) { 7997 ss = ps.newServiceStatsLocked(); 7998 ps.mServiceStats.put(serv, ss); 7999 } 8000 8001 return ss; 8002 } 8003 8004 public void readSyncSummaryFromParcelLocked(String name, Parcel in) { 8005 StopwatchTimer timer = mSyncStats.instantiateObject(); 8006 timer.readSummaryFromParcelLocked(in); 8007 mSyncStats.add(name, timer); 8008 } 8009 8010 public void readJobSummaryFromParcelLocked(String name, Parcel in) { 8011 DualTimer timer = mJobStats.instantiateObject(); 8012 timer.readSummaryFromParcelLocked(in); 8013 mJobStats.add(name, timer); 8014 } 8015 8016 public void readWakeSummaryFromParcelLocked(String wlName, Parcel in) { 8017 Wakelock wl = new Wakelock(mBsi, this); 8018 mWakelockStats.add(wlName, wl); 8019 if (in.readInt() != 0) { 8020 wl.getStopwatchTimer(WAKE_TYPE_FULL).readSummaryFromParcelLocked(in); 8021 } 8022 if (in.readInt() != 0) { 8023 wl.getStopwatchTimer(WAKE_TYPE_PARTIAL).readSummaryFromParcelLocked(in); 8024 } 8025 if (in.readInt() != 0) { 8026 wl.getStopwatchTimer(WAKE_TYPE_WINDOW).readSummaryFromParcelLocked(in); 8027 } 8028 if (in.readInt() != 0) { 8029 wl.getStopwatchTimer(WAKE_TYPE_DRAW).readSummaryFromParcelLocked(in); 8030 } 8031 } 8032 8033 public DualTimer getSensorTimerLocked(int sensor, boolean create) { 8034 Sensor se = mSensorStats.get(sensor); 8035 if (se == null) { 8036 if (!create) { 8037 return null; 8038 } 8039 se = new Sensor(mBsi, this, sensor); 8040 mSensorStats.put(sensor, se); 8041 } 8042 DualTimer t = se.mTimer; 8043 if (t != null) { 8044 return t; 8045 } 8046 ArrayList<StopwatchTimer> timers = mBsi.mSensorTimers.get(sensor); 8047 if (timers == null) { 8048 timers = new ArrayList<StopwatchTimer>(); 8049 mBsi.mSensorTimers.put(sensor, timers); 8050 } 8051 t = new DualTimer(mBsi.mClocks, this, BatteryStats.SENSOR, timers, 8052 mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase); 8053 se.mTimer = t; 8054 return t; 8055 } 8056 8057 public void noteStartSyncLocked(String name, long elapsedRealtimeMs) { 8058 StopwatchTimer t = mSyncStats.startObject(name); 8059 if (t != null) { 8060 t.startRunningLocked(elapsedRealtimeMs); 8061 } 8062 } 8063 8064 public void noteStopSyncLocked(String name, long elapsedRealtimeMs) { 8065 StopwatchTimer t = mSyncStats.stopObject(name); 8066 if (t != null) { 8067 t.stopRunningLocked(elapsedRealtimeMs); 8068 } 8069 } 8070 8071 public void noteStartJobLocked(String name, long elapsedRealtimeMs) { 8072 DualTimer t = mJobStats.startObject(name); 8073 if (t != null) { 8074 t.startRunningLocked(elapsedRealtimeMs); 8075 } 8076 } 8077 8078 public void noteStopJobLocked(String name, long elapsedRealtimeMs) { 8079 DualTimer t = mJobStats.stopObject(name); 8080 if (t != null) { 8081 t.stopRunningLocked(elapsedRealtimeMs); 8082 } 8083 } 8084 8085 public void noteStartWakeLocked(int pid, String name, int type, long elapsedRealtimeMs) { 8086 Wakelock wl = mWakelockStats.startObject(name); 8087 if (wl != null) { 8088 wl.getStopwatchTimer(type).startRunningLocked(elapsedRealtimeMs); 8089 } 8090 if (pid >= 0 && type == WAKE_TYPE_PARTIAL) { 8091 Pid p = getPidStatsLocked(pid); 8092 if (p.mWakeNesting++ == 0) { 8093 p.mWakeStartMs = elapsedRealtimeMs; 8094 } 8095 } 8096 } 8097 8098 public void noteStopWakeLocked(int pid, String name, int type, long elapsedRealtimeMs) { 8099 Wakelock wl = mWakelockStats.stopObject(name); 8100 if (wl != null) { 8101 wl.getStopwatchTimer(type).stopRunningLocked(elapsedRealtimeMs); 8102 } 8103 if (pid >= 0 && type == WAKE_TYPE_PARTIAL) { 8104 Pid p = mPids.get(pid); 8105 if (p != null && p.mWakeNesting > 0) { 8106 if (p.mWakeNesting-- == 1) { 8107 p.mWakeSumMs += elapsedRealtimeMs - p.mWakeStartMs; 8108 p.mWakeStartMs = 0; 8109 } 8110 } 8111 } 8112 } 8113 8114 public void reportExcessiveWakeLocked(String proc, long overTime, long usedTime) { 8115 Proc p = getProcessStatsLocked(proc); 8116 if (p != null) { 8117 p.addExcessiveWake(overTime, usedTime); 8118 } 8119 } 8120 8121 public void reportExcessiveCpuLocked(String proc, long overTime, long usedTime) { 8122 Proc p = getProcessStatsLocked(proc); 8123 if (p != null) { 8124 p.addExcessiveCpu(overTime, usedTime); 8125 } 8126 } 8127 8128 public void noteStartSensor(int sensor, long elapsedRealtimeMs) { 8129 DualTimer t = getSensorTimerLocked(sensor, /* create= */ true); 8130 t.startRunningLocked(elapsedRealtimeMs); 8131 } 8132 8133 public void noteStopSensor(int sensor, long elapsedRealtimeMs) { 8134 // Don't create a timer if one doesn't already exist 8135 DualTimer t = getSensorTimerLocked(sensor, false); 8136 if (t != null) { 8137 t.stopRunningLocked(elapsedRealtimeMs); 8138 } 8139 } 8140 8141 public void noteStartGps(long elapsedRealtimeMs) { 8142 noteStartSensor(Sensor.GPS, elapsedRealtimeMs); 8143 } 8144 8145 public void noteStopGps(long elapsedRealtimeMs) { 8146 noteStopSensor(Sensor.GPS, elapsedRealtimeMs); 8147 } 8148 8149 public BatteryStatsImpl getBatteryStats() { 8150 return mBsi; 8151 } 8152 } 8153 8154 public BatteryStatsImpl(File systemDir, Handler handler, ExternalStatsSync externalSync) { 8155 this(new SystemClocks(), systemDir, handler, externalSync, null); 8156 } 8157 8158 public BatteryStatsImpl(File systemDir, Handler handler, ExternalStatsSync externalSync, 8159 PlatformIdleStateCallback cb) { 8160 this(new SystemClocks(), systemDir, handler, externalSync, cb); 8161 } 8162 8163 public BatteryStatsImpl(Clocks clocks, File systemDir, Handler handler, 8164 ExternalStatsSync externalSync, PlatformIdleStateCallback cb) { 8165 init(clocks); 8166 8167 if (systemDir != null) { 8168 mFile = new JournaledFile(new File(systemDir, "batterystats.bin"), 8169 new File(systemDir, "batterystats.bin.tmp")); 8170 } else { 8171 mFile = null; 8172 } 8173 mCheckinFile = new AtomicFile(new File(systemDir, "batterystats-checkin.bin")); 8174 mDailyFile = new AtomicFile(new File(systemDir, "batterystats-daily.xml")); 8175 mExternalSync = externalSync; 8176 mHandler = new MyHandler(handler.getLooper()); 8177 mStartCount++; 8178 mScreenOnTimer = new StopwatchTimer(mClocks, null, -1, null, mOnBatteryTimeBase); 8179 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 8180 mScreenBrightnessTimer[i] = new StopwatchTimer(mClocks, null, -100-i, null, 8181 mOnBatteryTimeBase); 8182 } 8183 mInteractiveTimer = new StopwatchTimer(mClocks, null, -10, null, mOnBatteryTimeBase); 8184 mPowerSaveModeEnabledTimer = new StopwatchTimer(mClocks, null, -2, null, 8185 mOnBatteryTimeBase); 8186 mDeviceIdleModeLightTimer = new StopwatchTimer(mClocks, null, -11, null, 8187 mOnBatteryTimeBase); 8188 mDeviceIdleModeFullTimer = new StopwatchTimer(mClocks, null, -14, null, mOnBatteryTimeBase); 8189 mDeviceLightIdlingTimer = new StopwatchTimer(mClocks, null, -15, null, mOnBatteryTimeBase); 8190 mDeviceIdlingTimer = new StopwatchTimer(mClocks, null, -12, null, mOnBatteryTimeBase); 8191 mPhoneOnTimer = new StopwatchTimer(mClocks, null, -3, null, mOnBatteryTimeBase); 8192 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) { 8193 mPhoneSignalStrengthsTimer[i] = new StopwatchTimer(mClocks, null, -200-i, null, 8194 mOnBatteryTimeBase); 8195 } 8196 mPhoneSignalScanningTimer = new StopwatchTimer(mClocks, null, -200+1, null, 8197 mOnBatteryTimeBase); 8198 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 8199 mPhoneDataConnectionsTimer[i] = new StopwatchTimer(mClocks, null, -300-i, null, 8200 mOnBatteryTimeBase); 8201 } 8202 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 8203 mNetworkByteActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase); 8204 mNetworkPacketActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase); 8205 } 8206 mWifiActivity = new ControllerActivityCounterImpl(mOnBatteryTimeBase, NUM_WIFI_TX_LEVELS); 8207 mBluetoothActivity = new ControllerActivityCounterImpl(mOnBatteryTimeBase, 8208 NUM_BT_TX_LEVELS); 8209 mModemActivity = new ControllerActivityCounterImpl(mOnBatteryTimeBase, 8210 ModemActivityInfo.TX_POWER_LEVELS); 8211 mMobileRadioActiveTimer = new StopwatchTimer(mClocks, null, -400, null, mOnBatteryTimeBase); 8212 mMobileRadioActivePerAppTimer = new StopwatchTimer(mClocks, null, -401, null, 8213 mOnBatteryTimeBase); 8214 mMobileRadioActiveAdjustedTime = new LongSamplingCounter(mOnBatteryTimeBase); 8215 mMobileRadioActiveUnknownTime = new LongSamplingCounter(mOnBatteryTimeBase); 8216 mMobileRadioActiveUnknownCount = new LongSamplingCounter(mOnBatteryTimeBase); 8217 mWifiOnTimer = new StopwatchTimer(mClocks, null, -4, null, mOnBatteryTimeBase); 8218 mGlobalWifiRunningTimer = new StopwatchTimer(mClocks, null, -5, null, mOnBatteryTimeBase); 8219 for (int i=0; i<NUM_WIFI_STATES; i++) { 8220 mWifiStateTimer[i] = new StopwatchTimer(mClocks, null, -600-i, null, 8221 mOnBatteryTimeBase); 8222 } 8223 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) { 8224 mWifiSupplStateTimer[i] = new StopwatchTimer(mClocks, null, -700-i, null, 8225 mOnBatteryTimeBase); 8226 } 8227 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { 8228 mWifiSignalStrengthsTimer[i] = new StopwatchTimer(mClocks, null, -800-i, null, 8229 mOnBatteryTimeBase); 8230 } 8231 mAudioOnTimer = new StopwatchTimer(mClocks, null, -7, null, mOnBatteryTimeBase); 8232 mVideoOnTimer = new StopwatchTimer(mClocks, null, -8, null, mOnBatteryTimeBase); 8233 mFlashlightOnTimer = new StopwatchTimer(mClocks, null, -9, null, mOnBatteryTimeBase); 8234 mCameraOnTimer = new StopwatchTimer(mClocks, null, -13, null, mOnBatteryTimeBase); 8235 mBluetoothScanTimer = new StopwatchTimer(mClocks, null, -14, null, mOnBatteryTimeBase); 8236 mDischargeScreenOffCounter = new LongSamplingCounter(mOnBatteryScreenOffTimeBase); 8237 mDischargeCounter = new LongSamplingCounter(mOnBatteryTimeBase); 8238 mOnBattery = mOnBatteryInternal = false; 8239 long uptime = mClocks.uptimeMillis() * 1000; 8240 long realtime = mClocks.elapsedRealtime() * 1000; 8241 initTimes(uptime, realtime); 8242 mStartPlatformVersion = mEndPlatformVersion = Build.ID; 8243 mDischargeStartLevel = 0; 8244 mDischargeUnplugLevel = 0; 8245 mDischargePlugLevel = -1; 8246 mDischargeCurrentLevel = 0; 8247 mCurrentBatteryLevel = 0; 8248 initDischarge(); 8249 clearHistoryLocked(); 8250 updateDailyDeadlineLocked(); 8251 mPlatformIdleStateCallback = cb; 8252 } 8253 8254 public BatteryStatsImpl(Parcel p) { 8255 this(new SystemClocks(), p); 8256 } 8257 8258 public BatteryStatsImpl(Clocks clocks, Parcel p) { 8259 init(clocks); 8260 mFile = null; 8261 mCheckinFile = null; 8262 mDailyFile = null; 8263 mHandler = null; 8264 mExternalSync = null; 8265 clearHistoryLocked(); 8266 readFromParcel(p); 8267 mPlatformIdleStateCallback = null; 8268 } 8269 8270 public void setPowerProfile(PowerProfile profile) { 8271 synchronized (this) { 8272 mPowerProfile = profile; 8273 8274 // We need to initialize the KernelCpuSpeedReaders to read from 8275 // the first cpu of each core. Once we have the PowerProfile, we have access to this 8276 // information. 8277 final int numClusters = mPowerProfile.getNumCpuClusters(); 8278 mKernelCpuSpeedReaders = new KernelCpuSpeedReader[numClusters]; 8279 int firstCpuOfCluster = 0; 8280 for (int i = 0; i < numClusters; i++) { 8281 final int numSpeedSteps = mPowerProfile.getNumSpeedStepsInCpuCluster(i); 8282 mKernelCpuSpeedReaders[i] = new KernelCpuSpeedReader(firstCpuOfCluster, 8283 numSpeedSteps); 8284 firstCpuOfCluster += mPowerProfile.getNumCoresInCpuCluster(i); 8285 } 8286 8287 if (mEstimatedBatteryCapacity == -1) { 8288 // Initialize the estimated battery capacity to a known preset one. 8289 mEstimatedBatteryCapacity = (int) mPowerProfile.getBatteryCapacity(); 8290 } 8291 } 8292 } 8293 8294 public void setCallback(BatteryCallback cb) { 8295 mCallback = cb; 8296 } 8297 8298 public void setRadioScanningTimeout(long timeout) { 8299 if (mPhoneSignalScanningTimer != null) { 8300 mPhoneSignalScanningTimer.setTimeout(timeout); 8301 } 8302 } 8303 8304 public void updateDailyDeadlineLocked() { 8305 // Get the current time. 8306 long currentTime = mDailyStartTime = System.currentTimeMillis(); 8307 Calendar calDeadline = Calendar.getInstance(); 8308 calDeadline.setTimeInMillis(currentTime); 8309 8310 // Move time up to the next day, ranging from 1am to 3pm. 8311 calDeadline.set(Calendar.DAY_OF_YEAR, calDeadline.get(Calendar.DAY_OF_YEAR) + 1); 8312 calDeadline.set(Calendar.MILLISECOND, 0); 8313 calDeadline.set(Calendar.SECOND, 0); 8314 calDeadline.set(Calendar.MINUTE, 0); 8315 calDeadline.set(Calendar.HOUR_OF_DAY, 1); 8316 mNextMinDailyDeadline = calDeadline.getTimeInMillis(); 8317 calDeadline.set(Calendar.HOUR_OF_DAY, 3); 8318 mNextMaxDailyDeadline = calDeadline.getTimeInMillis(); 8319 } 8320 8321 public void recordDailyStatsIfNeededLocked(boolean settled) { 8322 long currentTime = System.currentTimeMillis(); 8323 if (currentTime >= mNextMaxDailyDeadline) { 8324 recordDailyStatsLocked(); 8325 } else if (settled && currentTime >= mNextMinDailyDeadline) { 8326 recordDailyStatsLocked(); 8327 } else if (currentTime < (mDailyStartTime-(1000*60*60*24))) { 8328 recordDailyStatsLocked(); 8329 } 8330 } 8331 8332 public void recordDailyStatsLocked() { 8333 DailyItem item = new DailyItem(); 8334 item.mStartTime = mDailyStartTime; 8335 item.mEndTime = System.currentTimeMillis(); 8336 boolean hasData = false; 8337 if (mDailyDischargeStepTracker.mNumStepDurations > 0) { 8338 hasData = true; 8339 item.mDischargeSteps = new LevelStepTracker( 8340 mDailyDischargeStepTracker.mNumStepDurations, 8341 mDailyDischargeStepTracker.mStepDurations); 8342 } 8343 if (mDailyChargeStepTracker.mNumStepDurations > 0) { 8344 hasData = true; 8345 item.mChargeSteps = new LevelStepTracker( 8346 mDailyChargeStepTracker.mNumStepDurations, 8347 mDailyChargeStepTracker.mStepDurations); 8348 } 8349 if (mDailyPackageChanges != null) { 8350 hasData = true; 8351 item.mPackageChanges = mDailyPackageChanges; 8352 mDailyPackageChanges = null; 8353 } 8354 mDailyDischargeStepTracker.init(); 8355 mDailyChargeStepTracker.init(); 8356 updateDailyDeadlineLocked(); 8357 8358 if (hasData) { 8359 mDailyItems.add(item); 8360 while (mDailyItems.size() > MAX_DAILY_ITEMS) { 8361 mDailyItems.remove(0); 8362 } 8363 final ByteArrayOutputStream memStream = new ByteArrayOutputStream(); 8364 try { 8365 XmlSerializer out = new FastXmlSerializer(); 8366 out.setOutput(memStream, StandardCharsets.UTF_8.name()); 8367 writeDailyItemsLocked(out); 8368 BackgroundThread.getHandler().post(new Runnable() { 8369 @Override 8370 public void run() { 8371 synchronized (mCheckinFile) { 8372 FileOutputStream stream = null; 8373 try { 8374 stream = mDailyFile.startWrite(); 8375 memStream.writeTo(stream); 8376 stream.flush(); 8377 FileUtils.sync(stream); 8378 stream.close(); 8379 mDailyFile.finishWrite(stream); 8380 } catch (IOException e) { 8381 Slog.w("BatteryStats", 8382 "Error writing battery daily items", e); 8383 mDailyFile.failWrite(stream); 8384 } 8385 } 8386 } 8387 }); 8388 } catch (IOException e) { 8389 } 8390 } 8391 } 8392 8393 private void writeDailyItemsLocked(XmlSerializer out) throws IOException { 8394 StringBuilder sb = new StringBuilder(64); 8395 out.startDocument(null, true); 8396 out.startTag(null, "daily-items"); 8397 for (int i=0; i<mDailyItems.size(); i++) { 8398 final DailyItem dit = mDailyItems.get(i); 8399 out.startTag(null, "item"); 8400 out.attribute(null, "start", Long.toString(dit.mStartTime)); 8401 out.attribute(null, "end", Long.toString(dit.mEndTime)); 8402 writeDailyLevelSteps(out, "dis", dit.mDischargeSteps, sb); 8403 writeDailyLevelSteps(out, "chg", dit.mChargeSteps, sb); 8404 if (dit.mPackageChanges != null) { 8405 for (int j=0; j<dit.mPackageChanges.size(); j++) { 8406 PackageChange pc = dit.mPackageChanges.get(j); 8407 if (pc.mUpdate) { 8408 out.startTag(null, "upd"); 8409 out.attribute(null, "pkg", pc.mPackageName); 8410 out.attribute(null, "ver", Integer.toString(pc.mVersionCode)); 8411 out.endTag(null, "upd"); 8412 } else { 8413 out.startTag(null, "rem"); 8414 out.attribute(null, "pkg", pc.mPackageName); 8415 out.endTag(null, "rem"); 8416 } 8417 } 8418 } 8419 out.endTag(null, "item"); 8420 } 8421 out.endTag(null, "daily-items"); 8422 out.endDocument(); 8423 } 8424 8425 private void writeDailyLevelSteps(XmlSerializer out, String tag, LevelStepTracker steps, 8426 StringBuilder tmpBuilder) throws IOException { 8427 if (steps != null) { 8428 out.startTag(null, tag); 8429 out.attribute(null, "n", Integer.toString(steps.mNumStepDurations)); 8430 for (int i=0; i<steps.mNumStepDurations; i++) { 8431 out.startTag(null, "s"); 8432 tmpBuilder.setLength(0); 8433 steps.encodeEntryAt(i, tmpBuilder); 8434 out.attribute(null, "v", tmpBuilder.toString()); 8435 out.endTag(null, "s"); 8436 } 8437 out.endTag(null, tag); 8438 } 8439 } 8440 8441 public void readDailyStatsLocked() { 8442 Slog.d(TAG, "Reading daily items from " + mDailyFile.getBaseFile()); 8443 mDailyItems.clear(); 8444 FileInputStream stream; 8445 try { 8446 stream = mDailyFile.openRead(); 8447 } catch (FileNotFoundException e) { 8448 return; 8449 } 8450 try { 8451 XmlPullParser parser = Xml.newPullParser(); 8452 parser.setInput(stream, StandardCharsets.UTF_8.name()); 8453 readDailyItemsLocked(parser); 8454 } catch (XmlPullParserException e) { 8455 } finally { 8456 try { 8457 stream.close(); 8458 } catch (IOException e) { 8459 } 8460 } 8461 } 8462 8463 private void readDailyItemsLocked(XmlPullParser parser) { 8464 try { 8465 int type; 8466 while ((type = parser.next()) != XmlPullParser.START_TAG 8467 && type != XmlPullParser.END_DOCUMENT) { 8468 ; 8469 } 8470 8471 if (type != XmlPullParser.START_TAG) { 8472 throw new IllegalStateException("no start tag found"); 8473 } 8474 8475 int outerDepth = parser.getDepth(); 8476 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 8477 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 8478 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 8479 continue; 8480 } 8481 8482 String tagName = parser.getName(); 8483 if (tagName.equals("item")) { 8484 readDailyItemTagLocked(parser); 8485 } else { 8486 Slog.w(TAG, "Unknown element under <daily-items>: " 8487 + parser.getName()); 8488 XmlUtils.skipCurrentTag(parser); 8489 } 8490 } 8491 8492 } catch (IllegalStateException e) { 8493 Slog.w(TAG, "Failed parsing daily " + e); 8494 } catch (NullPointerException e) { 8495 Slog.w(TAG, "Failed parsing daily " + e); 8496 } catch (NumberFormatException e) { 8497 Slog.w(TAG, "Failed parsing daily " + e); 8498 } catch (XmlPullParserException e) { 8499 Slog.w(TAG, "Failed parsing daily " + e); 8500 } catch (IOException e) { 8501 Slog.w(TAG, "Failed parsing daily " + e); 8502 } catch (IndexOutOfBoundsException e) { 8503 Slog.w(TAG, "Failed parsing daily " + e); 8504 } 8505 } 8506 8507 void readDailyItemTagLocked(XmlPullParser parser) throws NumberFormatException, 8508 XmlPullParserException, IOException { 8509 DailyItem dit = new DailyItem(); 8510 String attr = parser.getAttributeValue(null, "start"); 8511 if (attr != null) { 8512 dit.mStartTime = Long.parseLong(attr); 8513 } 8514 attr = parser.getAttributeValue(null, "end"); 8515 if (attr != null) { 8516 dit.mEndTime = Long.parseLong(attr); 8517 } 8518 int outerDepth = parser.getDepth(); 8519 int type; 8520 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 8521 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 8522 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 8523 continue; 8524 } 8525 8526 String tagName = parser.getName(); 8527 if (tagName.equals("dis")) { 8528 readDailyItemTagDetailsLocked(parser, dit, false, "dis"); 8529 } else if (tagName.equals("chg")) { 8530 readDailyItemTagDetailsLocked(parser, dit, true, "chg"); 8531 } else if (tagName.equals("upd")) { 8532 if (dit.mPackageChanges == null) { 8533 dit.mPackageChanges = new ArrayList<>(); 8534 } 8535 PackageChange pc = new PackageChange(); 8536 pc.mUpdate = true; 8537 pc.mPackageName = parser.getAttributeValue(null, "pkg"); 8538 String verStr = parser.getAttributeValue(null, "ver"); 8539 pc.mVersionCode = verStr != null ? Integer.parseInt(verStr) : 0; 8540 dit.mPackageChanges.add(pc); 8541 XmlUtils.skipCurrentTag(parser); 8542 } else if (tagName.equals("rem")) { 8543 if (dit.mPackageChanges == null) { 8544 dit.mPackageChanges = new ArrayList<>(); 8545 } 8546 PackageChange pc = new PackageChange(); 8547 pc.mUpdate = false; 8548 pc.mPackageName = parser.getAttributeValue(null, "pkg"); 8549 dit.mPackageChanges.add(pc); 8550 XmlUtils.skipCurrentTag(parser); 8551 } else { 8552 Slog.w(TAG, "Unknown element under <item>: " 8553 + parser.getName()); 8554 XmlUtils.skipCurrentTag(parser); 8555 } 8556 } 8557 mDailyItems.add(dit); 8558 } 8559 8560 void readDailyItemTagDetailsLocked(XmlPullParser parser, DailyItem dit, boolean isCharge, 8561 String tag) 8562 throws NumberFormatException, XmlPullParserException, IOException { 8563 final String numAttr = parser.getAttributeValue(null, "n"); 8564 if (numAttr == null) { 8565 Slog.w(TAG, "Missing 'n' attribute at " + parser.getPositionDescription()); 8566 XmlUtils.skipCurrentTag(parser); 8567 return; 8568 } 8569 final int num = Integer.parseInt(numAttr); 8570 LevelStepTracker steps = new LevelStepTracker(num); 8571 if (isCharge) { 8572 dit.mChargeSteps = steps; 8573 } else { 8574 dit.mDischargeSteps = steps; 8575 } 8576 int i = 0; 8577 int outerDepth = parser.getDepth(); 8578 int type; 8579 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 8580 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 8581 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 8582 continue; 8583 } 8584 8585 String tagName = parser.getName(); 8586 if ("s".equals(tagName)) { 8587 if (i < num) { 8588 String valueAttr = parser.getAttributeValue(null, "v"); 8589 if (valueAttr != null) { 8590 steps.decodeEntryAt(i, valueAttr); 8591 i++; 8592 } 8593 } 8594 } else { 8595 Slog.w(TAG, "Unknown element under <" + tag + ">: " 8596 + parser.getName()); 8597 XmlUtils.skipCurrentTag(parser); 8598 } 8599 } 8600 steps.mNumStepDurations = i; 8601 } 8602 8603 @Override 8604 public DailyItem getDailyItemLocked(int daysAgo) { 8605 int index = mDailyItems.size()-1-daysAgo; 8606 return index >= 0 ? mDailyItems.get(index) : null; 8607 } 8608 8609 @Override 8610 public long getCurrentDailyStartTime() { 8611 return mDailyStartTime; 8612 } 8613 8614 @Override 8615 public long getNextMinDailyDeadline() { 8616 return mNextMinDailyDeadline; 8617 } 8618 8619 @Override 8620 public long getNextMaxDailyDeadline() { 8621 return mNextMaxDailyDeadline; 8622 } 8623 8624 @Override 8625 public boolean startIteratingOldHistoryLocked() { 8626 if (DEBUG_HISTORY) Slog.i(TAG, "ITERATING: buff size=" + mHistoryBuffer.dataSize() 8627 + " pos=" + mHistoryBuffer.dataPosition()); 8628 if ((mHistoryIterator = mHistory) == null) { 8629 return false; 8630 } 8631 mHistoryBuffer.setDataPosition(0); 8632 mHistoryReadTmp.clear(); 8633 mReadOverflow = false; 8634 mIteratingHistory = true; 8635 return true; 8636 } 8637 8638 @Override 8639 public boolean getNextOldHistoryLocked(HistoryItem out) { 8640 boolean end = mHistoryBuffer.dataPosition() >= mHistoryBuffer.dataSize(); 8641 if (!end) { 8642 readHistoryDelta(mHistoryBuffer, mHistoryReadTmp); 8643 mReadOverflow |= mHistoryReadTmp.cmd == HistoryItem.CMD_OVERFLOW; 8644 } 8645 HistoryItem cur = mHistoryIterator; 8646 if (cur == null) { 8647 if (!mReadOverflow && !end) { 8648 Slog.w(TAG, "Old history ends before new history!"); 8649 } 8650 return false; 8651 } 8652 out.setTo(cur); 8653 mHistoryIterator = cur.next; 8654 if (!mReadOverflow) { 8655 if (end) { 8656 Slog.w(TAG, "New history ends before old history!"); 8657 } else if (!out.same(mHistoryReadTmp)) { 8658 PrintWriter pw = new FastPrintWriter(new LogWriter(android.util.Log.WARN, TAG)); 8659 pw.println("Histories differ!"); 8660 pw.println("Old history:"); 8661 (new HistoryPrinter()).printNextItem(pw, out, 0, false, true); 8662 pw.println("New history:"); 8663 (new HistoryPrinter()).printNextItem(pw, mHistoryReadTmp, 0, false, 8664 true); 8665 pw.flush(); 8666 } 8667 } 8668 return true; 8669 } 8670 8671 @Override 8672 public void finishIteratingOldHistoryLocked() { 8673 mIteratingHistory = false; 8674 mHistoryBuffer.setDataPosition(mHistoryBuffer.dataSize()); 8675 mHistoryIterator = null; 8676 } 8677 8678 public int getHistoryTotalSize() { 8679 return MAX_HISTORY_BUFFER; 8680 } 8681 8682 public int getHistoryUsedSize() { 8683 return mHistoryBuffer.dataSize(); 8684 } 8685 8686 @Override 8687 public boolean startIteratingHistoryLocked() { 8688 if (DEBUG_HISTORY) Slog.i(TAG, "ITERATING: buff size=" + mHistoryBuffer.dataSize() 8689 + " pos=" + mHistoryBuffer.dataPosition()); 8690 if (mHistoryBuffer.dataSize() <= 0) { 8691 return false; 8692 } 8693 mHistoryBuffer.setDataPosition(0); 8694 mReadOverflow = false; 8695 mIteratingHistory = true; 8696 mReadHistoryStrings = new String[mHistoryTagPool.size()]; 8697 mReadHistoryUids = new int[mHistoryTagPool.size()]; 8698 mReadHistoryChars = 0; 8699 for (HashMap.Entry<HistoryTag, Integer> ent : mHistoryTagPool.entrySet()) { 8700 final HistoryTag tag = ent.getKey(); 8701 final int idx = ent.getValue(); 8702 mReadHistoryStrings[idx] = tag.string; 8703 mReadHistoryUids[idx] = tag.uid; 8704 mReadHistoryChars += tag.string.length() + 1; 8705 } 8706 return true; 8707 } 8708 8709 @Override 8710 public int getHistoryStringPoolSize() { 8711 return mReadHistoryStrings.length; 8712 } 8713 8714 @Override 8715 public int getHistoryStringPoolBytes() { 8716 // Each entry is a fixed 12 bytes: 4 for index, 4 for uid, 4 for string size 8717 // Each string character is 2 bytes. 8718 return (mReadHistoryStrings.length * 12) + (mReadHistoryChars * 2); 8719 } 8720 8721 @Override 8722 public String getHistoryTagPoolString(int index) { 8723 return mReadHistoryStrings[index]; 8724 } 8725 8726 @Override 8727 public int getHistoryTagPoolUid(int index) { 8728 return mReadHistoryUids[index]; 8729 } 8730 8731 @Override 8732 public boolean getNextHistoryLocked(HistoryItem out) { 8733 final int pos = mHistoryBuffer.dataPosition(); 8734 if (pos == 0) { 8735 out.clear(); 8736 } 8737 boolean end = pos >= mHistoryBuffer.dataSize(); 8738 if (end) { 8739 return false; 8740 } 8741 8742 final long lastRealtime = out.time; 8743 final long lastWalltime = out.currentTime; 8744 readHistoryDelta(mHistoryBuffer, out); 8745 if (out.cmd != HistoryItem.CMD_CURRENT_TIME 8746 && out.cmd != HistoryItem.CMD_RESET && lastWalltime != 0) { 8747 out.currentTime = lastWalltime + (out.time - lastRealtime); 8748 } 8749 return true; 8750 } 8751 8752 @Override 8753 public void finishIteratingHistoryLocked() { 8754 mIteratingHistory = false; 8755 mHistoryBuffer.setDataPosition(mHistoryBuffer.dataSize()); 8756 mReadHistoryStrings = null; 8757 } 8758 8759 @Override 8760 public long getHistoryBaseTime() { 8761 return mHistoryBaseTime; 8762 } 8763 8764 @Override 8765 public int getStartCount() { 8766 return mStartCount; 8767 } 8768 8769 public boolean isOnBattery() { 8770 return mOnBattery; 8771 } 8772 8773 public boolean isCharging() { 8774 return mCharging; 8775 } 8776 8777 public boolean isScreenOn() { 8778 return mScreenState == Display.STATE_ON; 8779 } 8780 8781 void initTimes(long uptime, long realtime) { 8782 mStartClockTime = System.currentTimeMillis(); 8783 mOnBatteryTimeBase.init(uptime, realtime); 8784 mOnBatteryScreenOffTimeBase.init(uptime, realtime); 8785 mRealtime = 0; 8786 mUptime = 0; 8787 mRealtimeStart = realtime; 8788 mUptimeStart = uptime; 8789 } 8790 8791 void initDischarge() { 8792 mLowDischargeAmountSinceCharge = 0; 8793 mHighDischargeAmountSinceCharge = 0; 8794 mDischargeAmountScreenOn = 0; 8795 mDischargeAmountScreenOnSinceCharge = 0; 8796 mDischargeAmountScreenOff = 0; 8797 mDischargeAmountScreenOffSinceCharge = 0; 8798 mDischargeStepTracker.init(); 8799 mChargeStepTracker.init(); 8800 mDischargeScreenOffCounter.reset(false); 8801 mDischargeCounter.reset(false); 8802 } 8803 8804 public void resetAllStatsCmdLocked() { 8805 resetAllStatsLocked(); 8806 final long mSecUptime = mClocks.uptimeMillis(); 8807 long uptime = mSecUptime * 1000; 8808 long mSecRealtime = mClocks.elapsedRealtime(); 8809 long realtime = mSecRealtime * 1000; 8810 mDischargeStartLevel = mHistoryCur.batteryLevel; 8811 pullPendingStateUpdatesLocked(); 8812 addHistoryRecordLocked(mSecRealtime, mSecUptime); 8813 mDischargeCurrentLevel = mDischargeUnplugLevel = mDischargePlugLevel 8814 = mCurrentBatteryLevel = mHistoryCur.batteryLevel; 8815 mOnBatteryTimeBase.reset(uptime, realtime); 8816 mOnBatteryScreenOffTimeBase.reset(uptime, realtime); 8817 if ((mHistoryCur.states&HistoryItem.STATE_BATTERY_PLUGGED_FLAG) == 0) { 8818 if (mScreenState == Display.STATE_ON) { 8819 mDischargeScreenOnUnplugLevel = mHistoryCur.batteryLevel; 8820 mDischargeScreenOffUnplugLevel = 0; 8821 } else { 8822 mDischargeScreenOnUnplugLevel = 0; 8823 mDischargeScreenOffUnplugLevel = mHistoryCur.batteryLevel; 8824 } 8825 mDischargeAmountScreenOn = 0; 8826 mDischargeAmountScreenOff = 0; 8827 } 8828 initActiveHistoryEventsLocked(mSecRealtime, mSecUptime); 8829 } 8830 8831 private void resetAllStatsLocked() { 8832 final long uptimeMillis = mClocks.uptimeMillis(); 8833 final long elapsedRealtimeMillis = mClocks.elapsedRealtime(); 8834 mStartCount = 0; 8835 initTimes(uptimeMillis * 1000, elapsedRealtimeMillis * 1000); 8836 mScreenOnTimer.reset(false); 8837 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 8838 mScreenBrightnessTimer[i].reset(false); 8839 } 8840 8841 if (mPowerProfile != null) { 8842 mEstimatedBatteryCapacity = (int) mPowerProfile.getBatteryCapacity(); 8843 } else { 8844 mEstimatedBatteryCapacity = -1; 8845 } 8846 mInteractiveTimer.reset(false); 8847 mPowerSaveModeEnabledTimer.reset(false); 8848 mLastIdleTimeStart = elapsedRealtimeMillis; 8849 mLongestLightIdleTime = 0; 8850 mLongestFullIdleTime = 0; 8851 mDeviceIdleModeLightTimer.reset(false); 8852 mDeviceIdleModeFullTimer.reset(false); 8853 mDeviceLightIdlingTimer.reset(false); 8854 mDeviceIdlingTimer.reset(false); 8855 mPhoneOnTimer.reset(false); 8856 mAudioOnTimer.reset(false); 8857 mVideoOnTimer.reset(false); 8858 mFlashlightOnTimer.reset(false); 8859 mCameraOnTimer.reset(false); 8860 mBluetoothScanTimer.reset(false); 8861 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) { 8862 mPhoneSignalStrengthsTimer[i].reset(false); 8863 } 8864 mPhoneSignalScanningTimer.reset(false); 8865 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 8866 mPhoneDataConnectionsTimer[i].reset(false); 8867 } 8868 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 8869 mNetworkByteActivityCounters[i].reset(false); 8870 mNetworkPacketActivityCounters[i].reset(false); 8871 } 8872 mMobileRadioActiveTimer.reset(false); 8873 mMobileRadioActivePerAppTimer.reset(false); 8874 mMobileRadioActiveAdjustedTime.reset(false); 8875 mMobileRadioActiveUnknownTime.reset(false); 8876 mMobileRadioActiveUnknownCount.reset(false); 8877 mWifiOnTimer.reset(false); 8878 mGlobalWifiRunningTimer.reset(false); 8879 for (int i=0; i<NUM_WIFI_STATES; i++) { 8880 mWifiStateTimer[i].reset(false); 8881 } 8882 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) { 8883 mWifiSupplStateTimer[i].reset(false); 8884 } 8885 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { 8886 mWifiSignalStrengthsTimer[i].reset(false); 8887 } 8888 mWifiActivity.reset(false); 8889 mBluetoothActivity.reset(false); 8890 mModemActivity.reset(false); 8891 mNumConnectivityChange = mLoadedNumConnectivityChange = mUnpluggedNumConnectivityChange = 0; 8892 8893 for (int i=0; i<mUidStats.size(); i++) { 8894 if (mUidStats.valueAt(i).reset()) { 8895 mUidStats.remove(mUidStats.keyAt(i)); 8896 i--; 8897 } 8898 } 8899 8900 if (mKernelWakelockStats.size() > 0) { 8901 for (SamplingTimer timer : mKernelWakelockStats.values()) { 8902 mOnBatteryScreenOffTimeBase.remove(timer); 8903 } 8904 mKernelWakelockStats.clear(); 8905 } 8906 8907 if (mKernelMemoryStats.size() > 0) { 8908 for (int i = 0; i < mKernelMemoryStats.size(); i++) { 8909 mOnBatteryTimeBase.remove(mKernelMemoryStats.valueAt(i)); 8910 } 8911 mKernelMemoryStats.clear(); 8912 } 8913 8914 if (mWakeupReasonStats.size() > 0) { 8915 for (SamplingTimer timer : mWakeupReasonStats.values()) { 8916 mOnBatteryTimeBase.remove(timer); 8917 } 8918 mWakeupReasonStats.clear(); 8919 } 8920 8921 mLastHistoryStepDetails = null; 8922 mLastStepCpuUserTime = mLastStepCpuSystemTime = 0; 8923 mCurStepCpuUserTime = mCurStepCpuSystemTime = 0; 8924 mLastStepCpuUserTime = mCurStepCpuUserTime = 0; 8925 mLastStepCpuSystemTime = mCurStepCpuSystemTime = 0; 8926 mLastStepStatUserTime = mCurStepStatUserTime = 0; 8927 mLastStepStatSystemTime = mCurStepStatSystemTime = 0; 8928 mLastStepStatIOWaitTime = mCurStepStatIOWaitTime = 0; 8929 mLastStepStatIrqTime = mCurStepStatIrqTime = 0; 8930 mLastStepStatSoftIrqTime = mCurStepStatSoftIrqTime = 0; 8931 mLastStepStatIdleTime = mCurStepStatIdleTime = 0; 8932 8933 initDischarge(); 8934 8935 clearHistoryLocked(); 8936 } 8937 8938 private void initActiveHistoryEventsLocked(long elapsedRealtimeMs, long uptimeMs) { 8939 for (int i=0; i<HistoryItem.EVENT_COUNT; i++) { 8940 if (!mRecordAllHistory && i == HistoryItem.EVENT_PROC) { 8941 // Not recording process starts/stops. 8942 continue; 8943 } 8944 HashMap<String, SparseIntArray> active = mActiveEvents.getStateForEvent(i); 8945 if (active == null) { 8946 continue; 8947 } 8948 for (HashMap.Entry<String, SparseIntArray> ent : active.entrySet()) { 8949 SparseIntArray uids = ent.getValue(); 8950 for (int j=0; j<uids.size(); j++) { 8951 addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, i, ent.getKey(), 8952 uids.keyAt(j)); 8953 } 8954 } 8955 } 8956 } 8957 8958 void updateDischargeScreenLevelsLocked(boolean oldScreenOn, boolean newScreenOn) { 8959 if (oldScreenOn) { 8960 int diff = mDischargeScreenOnUnplugLevel - mDischargeCurrentLevel; 8961 if (diff > 0) { 8962 mDischargeAmountScreenOn += diff; 8963 mDischargeAmountScreenOnSinceCharge += diff; 8964 } 8965 } else { 8966 int diff = mDischargeScreenOffUnplugLevel - mDischargeCurrentLevel; 8967 if (diff > 0) { 8968 mDischargeAmountScreenOff += diff; 8969 mDischargeAmountScreenOffSinceCharge += diff; 8970 } 8971 } 8972 if (newScreenOn) { 8973 mDischargeScreenOnUnplugLevel = mDischargeCurrentLevel; 8974 mDischargeScreenOffUnplugLevel = 0; 8975 } else { 8976 mDischargeScreenOnUnplugLevel = 0; 8977 mDischargeScreenOffUnplugLevel = mDischargeCurrentLevel; 8978 } 8979 } 8980 8981 public void pullPendingStateUpdatesLocked() { 8982 if (mOnBatteryInternal) { 8983 final boolean screenOn = mScreenState == Display.STATE_ON; 8984 updateDischargeScreenLevelsLocked(screenOn, screenOn); 8985 } 8986 } 8987 8988 private String[] mMobileIfaces = EmptyArray.STRING; 8989 private String[] mWifiIfaces = EmptyArray.STRING; 8990 8991 private final NetworkStatsFactory mNetworkStatsFactory = new NetworkStatsFactory(); 8992 8993 private static final int NETWORK_STATS_LAST = 0; 8994 private static final int NETWORK_STATS_NEXT = 1; 8995 private static final int NETWORK_STATS_DELTA = 2; 8996 8997 private NetworkStats[] mMobileNetworkStats; 8998 private NetworkStats[] mWifiNetworkStats; 8999 9000 /** 9001 * Retrieves the delta of network stats for the given network ifaces. Uses networkStatsBuffer 9002 * as a buffer of NetworkStats objects to cycle through when computing deltas. 9003 */ 9004 private NetworkStats getNetworkStatsDeltaLocked(String[] ifaces, 9005 NetworkStats[] networkStatsBuffer) 9006 throws IOException { 9007 if (!SystemProperties.getBoolean(NetworkManagementSocketTagger.PROP_QTAGUID_ENABLED, 9008 false)) { 9009 return null; 9010 } 9011 9012 final NetworkStats stats = mNetworkStatsFactory.readNetworkStatsDetail(NetworkStats.UID_ALL, 9013 ifaces, NetworkStats.TAG_NONE, networkStatsBuffer[NETWORK_STATS_NEXT]); 9014 networkStatsBuffer[NETWORK_STATS_DELTA] = NetworkStats.subtract(stats, 9015 networkStatsBuffer[NETWORK_STATS_LAST], null, null, 9016 networkStatsBuffer[NETWORK_STATS_DELTA]); 9017 networkStatsBuffer[NETWORK_STATS_NEXT] = networkStatsBuffer[NETWORK_STATS_LAST]; 9018 networkStatsBuffer[NETWORK_STATS_LAST] = stats; 9019 return networkStatsBuffer[NETWORK_STATS_DELTA]; 9020 } 9021 9022 /** 9023 * Distribute WiFi energy info and network traffic to apps. 9024 * @param info The energy information from the WiFi controller. 9025 */ 9026 public void updateWifiStateLocked(@Nullable final WifiActivityEnergyInfo info) { 9027 if (DEBUG_ENERGY) { 9028 Slog.d(TAG, "Updating wifi stats"); 9029 } 9030 9031 final long elapsedRealtimeMs = mClocks.elapsedRealtime(); 9032 NetworkStats delta = null; 9033 try { 9034 if (!ArrayUtils.isEmpty(mWifiIfaces)) { 9035 delta = getNetworkStatsDeltaLocked(mWifiIfaces, mWifiNetworkStats); 9036 } 9037 } catch (IOException e) { 9038 Slog.wtf(TAG, "Failed to get wifi network stats", e); 9039 return; 9040 } 9041 9042 if (!mOnBatteryInternal) { 9043 return; 9044 } 9045 9046 SparseLongArray rxPackets = new SparseLongArray(); 9047 SparseLongArray txPackets = new SparseLongArray(); 9048 long totalTxPackets = 0; 9049 long totalRxPackets = 0; 9050 if (delta != null) { 9051 final int size = delta.size(); 9052 for (int i = 0; i < size; i++) { 9053 final NetworkStats.Entry entry = delta.getValues(i, mTmpNetworkStatsEntry); 9054 9055 if (DEBUG_ENERGY) { 9056 Slog.d(TAG, "Wifi uid " + entry.uid + ": delta rx=" + entry.rxBytes 9057 + " tx=" + entry.txBytes + " rxPackets=" + entry.rxPackets 9058 + " txPackets=" + entry.txPackets); 9059 } 9060 9061 if (entry.rxBytes == 0 && entry.txBytes == 0) { 9062 // Skip the lookup below since there is no work to do. 9063 continue; 9064 } 9065 9066 final Uid u = getUidStatsLocked(mapUid(entry.uid)); 9067 if (entry.rxBytes != 0) { 9068 u.noteNetworkActivityLocked(NETWORK_WIFI_RX_DATA, entry.rxBytes, 9069 entry.rxPackets); 9070 if (entry.set == NetworkStats.SET_DEFAULT) { // Background transfers 9071 u.noteNetworkActivityLocked(NETWORK_WIFI_BG_RX_DATA, entry.rxBytes, 9072 entry.rxPackets); 9073 } 9074 mNetworkByteActivityCounters[NETWORK_WIFI_RX_DATA].addCountLocked( 9075 entry.rxBytes); 9076 mNetworkPacketActivityCounters[NETWORK_WIFI_RX_DATA].addCountLocked( 9077 entry.rxPackets); 9078 9079 rxPackets.put(u.getUid(), entry.rxPackets); 9080 9081 // Sum the total number of packets so that the Rx Power can 9082 // be evenly distributed amongst the apps. 9083 totalRxPackets += entry.rxPackets; 9084 } 9085 9086 if (entry.txBytes != 0) { 9087 u.noteNetworkActivityLocked(NETWORK_WIFI_TX_DATA, entry.txBytes, 9088 entry.txPackets); 9089 if (entry.set == NetworkStats.SET_DEFAULT) { // Background transfers 9090 u.noteNetworkActivityLocked(NETWORK_WIFI_BG_TX_DATA, entry.txBytes, 9091 entry.txPackets); 9092 } 9093 mNetworkByteActivityCounters[NETWORK_WIFI_TX_DATA].addCountLocked( 9094 entry.txBytes); 9095 mNetworkPacketActivityCounters[NETWORK_WIFI_TX_DATA].addCountLocked( 9096 entry.txPackets); 9097 9098 txPackets.put(u.getUid(), entry.txPackets); 9099 9100 // Sum the total number of packets so that the Tx Power can 9101 // be evenly distributed amongst the apps. 9102 totalTxPackets += entry.txPackets; 9103 } 9104 } 9105 } 9106 9107 if (info != null) { 9108 mHasWifiReporting = true; 9109 9110 // Measured in mAms 9111 final long txTimeMs = info.getControllerTxTimeMillis(); 9112 final long rxTimeMs = info.getControllerRxTimeMillis(); 9113 final long idleTimeMs = info.getControllerIdleTimeMillis(); 9114 final long totalTimeMs = txTimeMs + rxTimeMs + idleTimeMs; 9115 9116 long leftOverRxTimeMs = rxTimeMs; 9117 long leftOverTxTimeMs = txTimeMs; 9118 9119 if (DEBUG_ENERGY) { 9120 Slog.d(TAG, "------ BEGIN WiFi power blaming ------"); 9121 Slog.d(TAG, " Tx Time: " + txTimeMs + " ms"); 9122 Slog.d(TAG, " Rx Time: " + rxTimeMs + " ms"); 9123 Slog.d(TAG, " Idle Time: " + idleTimeMs + " ms"); 9124 Slog.d(TAG, " Total Time: " + totalTimeMs + " ms"); 9125 } 9126 9127 long totalWifiLockTimeMs = 0; 9128 long totalScanTimeMs = 0; 9129 9130 // On the first pass, collect some totals so that we can normalize power 9131 // calculations if we need to. 9132 final int uidStatsSize = mUidStats.size(); 9133 for (int i = 0; i < uidStatsSize; i++) { 9134 final Uid uid = mUidStats.valueAt(i); 9135 9136 // Sum the total scan power for all apps. 9137 totalScanTimeMs += uid.mWifiScanTimer.getTimeSinceMarkLocked( 9138 elapsedRealtimeMs * 1000) / 1000; 9139 9140 // Sum the total time holding wifi lock for all apps. 9141 totalWifiLockTimeMs += uid.mFullWifiLockTimer.getTimeSinceMarkLocked( 9142 elapsedRealtimeMs * 1000) / 1000; 9143 } 9144 9145 if (DEBUG_ENERGY && totalScanTimeMs > rxTimeMs) { 9146 Slog.d(TAG, " !Estimated scan time > Actual rx time (" + totalScanTimeMs + " ms > " 9147 + rxTimeMs + " ms). Normalizing scan time."); 9148 } 9149 if (DEBUG_ENERGY && totalScanTimeMs > txTimeMs) { 9150 Slog.d(TAG, " !Estimated scan time > Actual tx time (" + totalScanTimeMs + " ms > " 9151 + txTimeMs + " ms). Normalizing scan time."); 9152 } 9153 9154 // Actually assign and distribute power usage to apps. 9155 for (int i = 0; i < uidStatsSize; i++) { 9156 final Uid uid = mUidStats.valueAt(i); 9157 9158 long scanTimeSinceMarkMs = uid.mWifiScanTimer.getTimeSinceMarkLocked( 9159 elapsedRealtimeMs * 1000) / 1000; 9160 if (scanTimeSinceMarkMs > 0) { 9161 // Set the new mark so that next time we get new data since this point. 9162 uid.mWifiScanTimer.setMark(elapsedRealtimeMs); 9163 9164 long scanRxTimeSinceMarkMs = scanTimeSinceMarkMs; 9165 long scanTxTimeSinceMarkMs = scanTimeSinceMarkMs; 9166 9167 // Our total scan time is more than the reported Tx/Rx time. 9168 // This is possible because the cost of a scan is approximate. 9169 // Let's normalize the result so that we evenly blame each app 9170 // scanning. 9171 // 9172 // This means that we may have apps that transmitted/received packets not be 9173 // blamed for this, but this is fine as scans are relatively more expensive. 9174 if (totalScanTimeMs > rxTimeMs) { 9175 scanRxTimeSinceMarkMs = (rxTimeMs * scanRxTimeSinceMarkMs) / 9176 totalScanTimeMs; 9177 } 9178 if (totalScanTimeMs > txTimeMs) { 9179 scanTxTimeSinceMarkMs = (txTimeMs * scanTxTimeSinceMarkMs) / 9180 totalScanTimeMs; 9181 } 9182 9183 if (DEBUG_ENERGY) { 9184 Slog.d(TAG, " ScanTime for UID " + uid.getUid() + ": Rx:" 9185 + scanRxTimeSinceMarkMs + " ms Tx:" 9186 + scanTxTimeSinceMarkMs + " ms)"); 9187 } 9188 9189 ControllerActivityCounterImpl activityCounter = 9190 uid.getOrCreateWifiControllerActivityLocked(); 9191 activityCounter.getRxTimeCounter().addCountLocked(scanRxTimeSinceMarkMs); 9192 activityCounter.getTxTimeCounters()[0].addCountLocked(scanTxTimeSinceMarkMs); 9193 leftOverRxTimeMs -= scanRxTimeSinceMarkMs; 9194 leftOverTxTimeMs -= scanTxTimeSinceMarkMs; 9195 } 9196 9197 // Distribute evenly the power consumed while Idle to each app holding a WiFi 9198 // lock. 9199 final long wifiLockTimeSinceMarkMs = uid.mFullWifiLockTimer.getTimeSinceMarkLocked( 9200 elapsedRealtimeMs * 1000) / 1000; 9201 if (wifiLockTimeSinceMarkMs > 0) { 9202 // Set the new mark so that next time we get new data since this point. 9203 uid.mFullWifiLockTimer.setMark(elapsedRealtimeMs); 9204 9205 final long myIdleTimeMs = (wifiLockTimeSinceMarkMs * idleTimeMs) 9206 / totalWifiLockTimeMs; 9207 if (DEBUG_ENERGY) { 9208 Slog.d(TAG, " IdleTime for UID " + uid.getUid() + ": " 9209 + myIdleTimeMs + " ms"); 9210 } 9211 uid.getOrCreateWifiControllerActivityLocked().getIdleTimeCounter() 9212 .addCountLocked(myIdleTimeMs); 9213 } 9214 } 9215 9216 if (DEBUG_ENERGY) { 9217 Slog.d(TAG, " New RxPower: " + leftOverRxTimeMs + " ms"); 9218 Slog.d(TAG, " New TxPower: " + leftOverTxTimeMs + " ms"); 9219 } 9220 9221 // Distribute the remaining Tx power appropriately between all apps that transmitted 9222 // packets. 9223 for (int i = 0; i < txPackets.size(); i++) { 9224 final Uid uid = getUidStatsLocked(txPackets.keyAt(i)); 9225 final long myTxTimeMs = (txPackets.valueAt(i) * leftOverTxTimeMs) / totalTxPackets; 9226 if (DEBUG_ENERGY) { 9227 Slog.d(TAG, " TxTime for UID " + uid.getUid() + ": " + myTxTimeMs + " ms"); 9228 } 9229 uid.getOrCreateWifiControllerActivityLocked().getTxTimeCounters()[0] 9230 .addCountLocked(myTxTimeMs); 9231 } 9232 9233 // Distribute the remaining Rx power appropriately between all apps that received 9234 // packets. 9235 for (int i = 0; i < rxPackets.size(); i++) { 9236 final Uid uid = getUidStatsLocked(rxPackets.keyAt(i)); 9237 final long myRxTimeMs = (rxPackets.valueAt(i) * leftOverRxTimeMs) / totalRxPackets; 9238 if (DEBUG_ENERGY) { 9239 Slog.d(TAG, " RxTime for UID " + uid.getUid() + ": " + myRxTimeMs + " ms"); 9240 } 9241 uid.getOrCreateWifiControllerActivityLocked().getRxTimeCounter() 9242 .addCountLocked(myRxTimeMs); 9243 } 9244 9245 // Any left over power use will be picked up by the WiFi category in BatteryStatsHelper. 9246 9247 // Update WiFi controller stats. 9248 mWifiActivity.getRxTimeCounter().addCountLocked(info.getControllerRxTimeMillis()); 9249 mWifiActivity.getTxTimeCounters()[0].addCountLocked(info.getControllerTxTimeMillis()); 9250 mWifiActivity.getIdleTimeCounter().addCountLocked(info.getControllerIdleTimeMillis()); 9251 9252 // POWER_WIFI_CONTROLLER_OPERATING_VOLTAGE is measured in mV, so convert to V. 9253 final double opVolt = mPowerProfile.getAveragePower( 9254 PowerProfile.POWER_WIFI_CONTROLLER_OPERATING_VOLTAGE) / 1000.0; 9255 if (opVolt != 0) { 9256 // We store the power drain as mAms. 9257 mWifiActivity.getPowerCounter().addCountLocked( 9258 (long)(info.getControllerEnergyUsed() / opVolt)); 9259 } 9260 } 9261 } 9262 9263 /** 9264 * Distribute Cell radio energy info and network traffic to apps. 9265 */ 9266 public void updateMobileRadioStateLocked(final long elapsedRealtimeMs, 9267 final ModemActivityInfo activityInfo) { 9268 if (DEBUG_ENERGY) { 9269 Slog.d(TAG, "Updating mobile radio stats with " + activityInfo); 9270 } 9271 9272 NetworkStats delta = null; 9273 try { 9274 if (!ArrayUtils.isEmpty(mMobileIfaces)) { 9275 delta = getNetworkStatsDeltaLocked(mMobileIfaces, mMobileNetworkStats); 9276 } 9277 } catch (IOException e) { 9278 Slog.wtf(TAG, "Failed to get mobile network stats", e); 9279 return; 9280 } 9281 9282 if (!mOnBatteryInternal) { 9283 return; 9284 } 9285 9286 long radioTime = mMobileRadioActivePerAppTimer.getTimeSinceMarkLocked( 9287 elapsedRealtimeMs * 1000); 9288 mMobileRadioActivePerAppTimer.setMark(elapsedRealtimeMs); 9289 9290 long totalRxPackets = 0; 9291 long totalTxPackets = 0; 9292 if (delta != null) { 9293 final int size = delta.size(); 9294 for (int i = 0; i < size; i++) { 9295 final NetworkStats.Entry entry = delta.getValues(i, mTmpNetworkStatsEntry); 9296 if (entry.rxPackets == 0 && entry.txPackets == 0) { 9297 continue; 9298 } 9299 9300 if (DEBUG_ENERGY) { 9301 Slog.d(TAG, "Mobile uid " + entry.uid + ": delta rx=" + entry.rxBytes 9302 + " tx=" + entry.txBytes + " rxPackets=" + entry.rxPackets 9303 + " txPackets=" + entry.txPackets); 9304 } 9305 9306 totalRxPackets += entry.rxPackets; 9307 totalTxPackets += entry.txPackets; 9308 9309 final Uid u = getUidStatsLocked(mapUid(entry.uid)); 9310 u.noteNetworkActivityLocked(NETWORK_MOBILE_RX_DATA, entry.rxBytes, entry.rxPackets); 9311 u.noteNetworkActivityLocked(NETWORK_MOBILE_TX_DATA, entry.txBytes, entry.txPackets); 9312 if (entry.set == NetworkStats.SET_DEFAULT) { // Background transfers 9313 u.noteNetworkActivityLocked(NETWORK_MOBILE_BG_RX_DATA, 9314 entry.rxBytes, entry.rxPackets); 9315 u.noteNetworkActivityLocked(NETWORK_MOBILE_BG_TX_DATA, 9316 entry.txBytes, entry.txPackets); 9317 } 9318 9319 mNetworkByteActivityCounters[NETWORK_MOBILE_RX_DATA].addCountLocked( 9320 entry.rxBytes); 9321 mNetworkByteActivityCounters[NETWORK_MOBILE_TX_DATA].addCountLocked( 9322 entry.txBytes); 9323 mNetworkPacketActivityCounters[NETWORK_MOBILE_RX_DATA].addCountLocked( 9324 entry.rxPackets); 9325 mNetworkPacketActivityCounters[NETWORK_MOBILE_TX_DATA].addCountLocked( 9326 entry.txPackets); 9327 } 9328 9329 // Now distribute proportional blame to the apps that did networking. 9330 long totalPackets = totalRxPackets + totalTxPackets; 9331 if (totalPackets > 0) { 9332 for (int i = 0; i < size; i++) { 9333 final NetworkStats.Entry entry = delta.getValues(i, mTmpNetworkStatsEntry); 9334 if (entry.rxPackets == 0 && entry.txPackets == 0) { 9335 continue; 9336 } 9337 9338 final Uid u = getUidStatsLocked(mapUid(entry.uid)); 9339 9340 // Distribute total radio active time in to this app. 9341 final long appPackets = entry.rxPackets + entry.txPackets; 9342 final long appRadioTime = (radioTime * appPackets) / totalPackets; 9343 u.noteMobileRadioActiveTimeLocked(appRadioTime); 9344 9345 // Remove this app from the totals, so that we don't lose any time 9346 // due to rounding. 9347 radioTime -= appRadioTime; 9348 totalPackets -= appPackets; 9349 9350 if (activityInfo != null) { 9351 ControllerActivityCounterImpl activityCounter = 9352 u.getOrCreateModemControllerActivityLocked(); 9353 if (totalRxPackets > 0 && entry.rxPackets > 0) { 9354 final long rxMs = (entry.rxPackets * activityInfo.getRxTimeMillis()) 9355 / totalRxPackets; 9356 activityCounter.getRxTimeCounter().addCountLocked(rxMs); 9357 } 9358 9359 if (totalTxPackets > 0 && entry.txPackets > 0) { 9360 for (int lvl = 0; lvl < ModemActivityInfo.TX_POWER_LEVELS; lvl++) { 9361 long txMs = entry.txPackets * activityInfo.getTxTimeMillis()[lvl]; 9362 txMs /= totalTxPackets; 9363 activityCounter.getTxTimeCounters()[lvl].addCountLocked(txMs); 9364 } 9365 } 9366 } 9367 } 9368 } 9369 9370 if (radioTime > 0) { 9371 // Whoops, there is some radio time we can't blame on an app! 9372 mMobileRadioActiveUnknownTime.addCountLocked(radioTime); 9373 mMobileRadioActiveUnknownCount.addCountLocked(1); 9374 } 9375 } 9376 9377 if (activityInfo != null) { 9378 mHasModemReporting = true; 9379 mModemActivity.getIdleTimeCounter().addCountLocked(activityInfo.getIdleTimeMillis()); 9380 mModemActivity.getRxTimeCounter().addCountLocked(activityInfo.getRxTimeMillis()); 9381 for (int lvl = 0; lvl < ModemActivityInfo.TX_POWER_LEVELS; lvl++) { 9382 mModemActivity.getTxTimeCounters()[lvl] 9383 .addCountLocked(activityInfo.getTxTimeMillis()[lvl]); 9384 } 9385 9386 // POWER_MODEM_CONTROLLER_OPERATING_VOLTAGE is measured in mV, so convert to V. 9387 final double opVolt = mPowerProfile.getAveragePower( 9388 PowerProfile.POWER_MODEM_CONTROLLER_OPERATING_VOLTAGE) / 1000.0; 9389 if (opVolt != 0) { 9390 // We store the power drain as mAms. 9391 mModemActivity.getPowerCounter().addCountLocked( 9392 (long) (activityInfo.getEnergyUsed() / opVolt)); 9393 } 9394 } 9395 } 9396 9397 /** 9398 * Distribute Bluetooth energy info and network traffic to apps. 9399 * @param info The energy information from the bluetooth controller. 9400 */ 9401 public void updateBluetoothStateLocked(@Nullable final BluetoothActivityEnergyInfo info) { 9402 if (DEBUG_ENERGY) { 9403 Slog.d(TAG, "Updating bluetooth stats: " + info); 9404 } 9405 9406 if (info == null || !mOnBatteryInternal) { 9407 return; 9408 } 9409 9410 mHasBluetoothReporting = true; 9411 9412 final long elapsedRealtimeMs = mClocks.elapsedRealtime(); 9413 final long rxTimeMs = info.getControllerRxTimeMillis(); 9414 final long txTimeMs = info.getControllerTxTimeMillis(); 9415 9416 if (DEBUG_ENERGY) { 9417 Slog.d(TAG, "------ BEGIN BLE power blaming ------"); 9418 Slog.d(TAG, " Tx Time: " + txTimeMs + " ms"); 9419 Slog.d(TAG, " Rx Time: " + rxTimeMs + " ms"); 9420 Slog.d(TAG, " Idle Time: " + info.getControllerIdleTimeMillis() + " ms"); 9421 } 9422 9423 long totalScanTimeMs = 0; 9424 9425 final int uidCount = mUidStats.size(); 9426 for (int i = 0; i < uidCount; i++) { 9427 final Uid u = mUidStats.valueAt(i); 9428 if (u.mBluetoothScanTimer == null) { 9429 continue; 9430 } 9431 9432 totalScanTimeMs += u.mBluetoothScanTimer.getTimeSinceMarkLocked( 9433 elapsedRealtimeMs * 1000) / 1000; 9434 } 9435 9436 final boolean normalizeScanRxTime = (totalScanTimeMs > rxTimeMs); 9437 final boolean normalizeScanTxTime = (totalScanTimeMs > txTimeMs); 9438 9439 if (DEBUG_ENERGY) { 9440 Slog.d(TAG, "Normalizing scan power for RX=" + normalizeScanRxTime 9441 + " TX=" + normalizeScanTxTime); 9442 } 9443 9444 long leftOverRxTimeMs = rxTimeMs; 9445 long leftOverTxTimeMs = txTimeMs; 9446 9447 for (int i = 0; i < uidCount; i++) { 9448 final Uid u = mUidStats.valueAt(i); 9449 if (u.mBluetoothScanTimer == null) { 9450 continue; 9451 } 9452 9453 long scanTimeSinceMarkMs = u.mBluetoothScanTimer.getTimeSinceMarkLocked( 9454 elapsedRealtimeMs * 1000) / 1000; 9455 if (scanTimeSinceMarkMs > 0) { 9456 // Set the new mark so that next time we get new data since this point. 9457 u.mBluetoothScanTimer.setMark(elapsedRealtimeMs); 9458 9459 long scanTimeRxSinceMarkMs = scanTimeSinceMarkMs; 9460 long scanTimeTxSinceMarkMs = scanTimeSinceMarkMs; 9461 9462 if (normalizeScanRxTime) { 9463 // Scan time is longer than the total rx time in the controller, 9464 // so distribute the scan time proportionately. This means regular traffic 9465 // will not blamed, but scans are more expensive anyways. 9466 scanTimeRxSinceMarkMs = (rxTimeMs * scanTimeRxSinceMarkMs) / totalScanTimeMs; 9467 } 9468 9469 if (normalizeScanTxTime) { 9470 // Scan time is longer than the total tx time in the controller, 9471 // so distribute the scan time proportionately. This means regular traffic 9472 // will not blamed, but scans are more expensive anyways. 9473 scanTimeTxSinceMarkMs = (txTimeMs * scanTimeTxSinceMarkMs) / totalScanTimeMs; 9474 } 9475 9476 final ControllerActivityCounterImpl counter = 9477 u.getOrCreateBluetoothControllerActivityLocked(); 9478 counter.getRxTimeCounter().addCountLocked(scanTimeRxSinceMarkMs); 9479 counter.getTxTimeCounters()[0].addCountLocked(scanTimeTxSinceMarkMs); 9480 9481 leftOverRxTimeMs -= scanTimeRxSinceMarkMs; 9482 leftOverTxTimeMs -= scanTimeTxSinceMarkMs; 9483 } 9484 } 9485 9486 if (DEBUG_ENERGY) { 9487 Slog.d(TAG, "Left over time for traffic RX=" + leftOverRxTimeMs 9488 + " TX=" + leftOverTxTimeMs); 9489 } 9490 9491 // 9492 // Now distribute blame to apps that did bluetooth traffic. 9493 // 9494 9495 long totalTxBytes = 0; 9496 long totalRxBytes = 0; 9497 9498 final UidTraffic[] uidTraffic = info.getUidTraffic(); 9499 final int numUids = uidTraffic != null ? uidTraffic.length : 0; 9500 for (int i = 0; i < numUids; i++) { 9501 final UidTraffic traffic = uidTraffic[i]; 9502 9503 // Add to the global counters. 9504 mNetworkByteActivityCounters[NETWORK_BT_RX_DATA].addCountLocked( 9505 traffic.getRxBytes()); 9506 mNetworkByteActivityCounters[NETWORK_BT_TX_DATA].addCountLocked( 9507 traffic.getTxBytes()); 9508 9509 // Add to the UID counters. 9510 final Uid u = getUidStatsLocked(mapUid(traffic.getUid())); 9511 u.noteNetworkActivityLocked(NETWORK_BT_RX_DATA, traffic.getRxBytes(), 0); 9512 u.noteNetworkActivityLocked(NETWORK_BT_TX_DATA, traffic.getTxBytes(), 0); 9513 9514 // Calculate the total traffic. 9515 totalTxBytes += traffic.getTxBytes(); 9516 totalRxBytes += traffic.getRxBytes(); 9517 } 9518 9519 if ((totalTxBytes != 0 || totalRxBytes != 0) && 9520 (leftOverRxTimeMs != 0 || leftOverTxTimeMs != 0)) { 9521 for (int i = 0; i < numUids; i++) { 9522 final UidTraffic traffic = uidTraffic[i]; 9523 9524 final Uid u = getUidStatsLocked(mapUid(traffic.getUid())); 9525 final ControllerActivityCounterImpl counter = 9526 u.getOrCreateBluetoothControllerActivityLocked(); 9527 9528 if (totalRxBytes > 0 && traffic.getRxBytes() > 0) { 9529 final long timeRxMs = (leftOverRxTimeMs * traffic.getRxBytes()) / totalRxBytes; 9530 9531 if (DEBUG_ENERGY) { 9532 Slog.d(TAG, "UID=" + traffic.getUid() + " rx_bytes=" + traffic.getRxBytes() 9533 + " rx_time=" + timeRxMs); 9534 } 9535 counter.getRxTimeCounter().addCountLocked(timeRxMs); 9536 leftOverRxTimeMs -= timeRxMs; 9537 } 9538 9539 if (totalTxBytes > 0 && traffic.getTxBytes() > 0) { 9540 final long timeTxMs = (leftOverTxTimeMs * traffic.getTxBytes()) / totalTxBytes; 9541 9542 if (DEBUG_ENERGY) { 9543 Slog.d(TAG, "UID=" + traffic.getUid() + " tx_bytes=" + traffic.getTxBytes() 9544 + " tx_time=" + timeTxMs); 9545 } 9546 9547 counter.getTxTimeCounters()[0].addCountLocked(timeTxMs); 9548 leftOverTxTimeMs -= timeTxMs; 9549 } 9550 } 9551 } 9552 9553 mBluetoothActivity.getRxTimeCounter().addCountLocked( 9554 info.getControllerRxTimeMillis()); 9555 mBluetoothActivity.getTxTimeCounters()[0].addCountLocked( 9556 info.getControllerTxTimeMillis()); 9557 mBluetoothActivity.getIdleTimeCounter().addCountLocked( 9558 info.getControllerIdleTimeMillis()); 9559 9560 // POWER_BLUETOOTH_CONTROLLER_OPERATING_VOLTAGE is measured in mV, so convert to V. 9561 final double opVolt = mPowerProfile.getAveragePower( 9562 PowerProfile.POWER_BLUETOOTH_CONTROLLER_OPERATING_VOLTAGE) / 1000.0; 9563 if (opVolt != 0) { 9564 // We store the power drain as mAms. 9565 mBluetoothActivity.getPowerCounter().addCountLocked( 9566 (long) (info.getControllerEnergyUsed() / opVolt)); 9567 } 9568 } 9569 9570 /** 9571 * Read and distribute kernel wake lock use across apps. 9572 */ 9573 public void updateKernelWakelocksLocked() { 9574 final KernelWakelockStats wakelockStats = mKernelWakelockReader.readKernelWakelockStats( 9575 mTmpWakelockStats); 9576 if (wakelockStats == null) { 9577 // Not crashing might make board bringup easier. 9578 Slog.w(TAG, "Couldn't get kernel wake lock stats"); 9579 return; 9580 } 9581 9582 for (Map.Entry<String, KernelWakelockStats.Entry> ent : wakelockStats.entrySet()) { 9583 String name = ent.getKey(); 9584 KernelWakelockStats.Entry kws = ent.getValue(); 9585 9586 SamplingTimer kwlt = mKernelWakelockStats.get(name); 9587 if (kwlt == null) { 9588 kwlt = new SamplingTimer(mClocks, mOnBatteryScreenOffTimeBase); 9589 mKernelWakelockStats.put(name, kwlt); 9590 } 9591 9592 kwlt.update(kws.mTotalTime, kws.mCount); 9593 kwlt.setUpdateVersion(kws.mVersion); 9594 } 9595 9596 int numWakelocksSetStale = 0; 9597 // Set timers to stale if they didn't appear in /d/wakeup_sources (or /proc/wakelocks) 9598 // this time. 9599 for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) { 9600 SamplingTimer st = ent.getValue(); 9601 if (st.getUpdateVersion() != wakelockStats.kernelWakelockVersion) { 9602 st.endSample(); 9603 numWakelocksSetStale++; 9604 } 9605 } 9606 9607 // Record whether we've seen a non-zero time (for debugging b/22716723). 9608 if (wakelockStats.isEmpty()) { 9609 Slog.wtf(TAG, "All kernel wakelocks had time of zero"); 9610 } 9611 9612 if (numWakelocksSetStale == mKernelWakelockStats.size()) { 9613 Slog.wtf(TAG, "All kernel wakelocks were set stale. new version=" + 9614 wakelockStats.kernelWakelockVersion); 9615 } 9616 } 9617 9618 // We use an anonymous class to access these variables, 9619 // so they can't live on the stack or they'd have to be 9620 // final MutableLong objects (more allocations). 9621 // Used in updateCpuTimeLocked(). 9622 long mTempTotalCpuUserTimeUs; 9623 long mTempTotalCpuSystemTimeUs; 9624 9625 /** 9626 * Reads the newest memory stats from the kernel. 9627 */ 9628 public void updateKernelMemoryBandwidthLocked() { 9629 mKernelMemoryBandwidthStats.updateStats(); 9630 LongSparseLongArray bandwidthEntries = mKernelMemoryBandwidthStats.getBandwidthEntries(); 9631 final int bandwidthEntryCount = bandwidthEntries.size(); 9632 int index; 9633 for (int i = 0; i < bandwidthEntryCount; i++) { 9634 SamplingTimer timer; 9635 if ((index = mKernelMemoryStats.indexOfKey(bandwidthEntries.keyAt(i))) >= 0) { 9636 timer = mKernelMemoryStats.valueAt(index); 9637 } else { 9638 timer = new SamplingTimer(mClocks, mOnBatteryTimeBase); 9639 mKernelMemoryStats.put(bandwidthEntries.keyAt(i), timer); 9640 } 9641 timer.update(bandwidthEntries.valueAt(i), 1); 9642 if (DEBUG_MEMORY) { 9643 Slog.d(TAG, String.format("Added entry %d and updated timer to: " 9644 + "mUnpluggedReportedTotalTime %d size %d", bandwidthEntries.keyAt(i), 9645 mKernelMemoryStats.get( 9646 bandwidthEntries.keyAt(i)).mUnpluggedReportedTotalTime, 9647 mKernelMemoryStats.size())); 9648 } 9649 } 9650 } 9651 9652 /** 9653 * Read and distribute CPU usage across apps. If their are partial wakelocks being held 9654 * and we are on battery with screen off, we give more of the cpu time to those apps holding 9655 * wakelocks. If the screen is on, we just assign the actual cpu time an app used. 9656 */ 9657 public void updateCpuTimeLocked() { 9658 if (mPowerProfile == null) { 9659 return; 9660 } 9661 9662 if (DEBUG_ENERGY_CPU) { 9663 Slog.d(TAG, "!Cpu updating!"); 9664 } 9665 9666 // Holding a wakelock costs more than just using the cpu. 9667 // Currently, we assign only half the cpu time to an app that is running but 9668 // not holding a wakelock. The apps holding wakelocks get the rest of the blame. 9669 // If no app is holding a wakelock, then the distribution is normal. 9670 final int wakelockWeight = 50; 9671 9672 // Read the time spent for each cluster at various cpu frequencies. 9673 final long[][] clusterSpeeds = new long[mKernelCpuSpeedReaders.length][]; 9674 for (int cluster = 0; cluster < mKernelCpuSpeedReaders.length; cluster++) { 9675 clusterSpeeds[cluster] = mKernelCpuSpeedReaders[cluster].readDelta(); 9676 } 9677 9678 int numWakelocks = 0; 9679 9680 // Calculate how many wakelocks we have to distribute amongst. The system is excluded. 9681 // Only distribute cpu power to wakelocks if the screen is off and we're on battery. 9682 final int numPartialTimers = mPartialTimers.size(); 9683 if (mOnBatteryScreenOffTimeBase.isRunning()) { 9684 for (int i = 0; i < numPartialTimers; i++) { 9685 final StopwatchTimer timer = mPartialTimers.get(i); 9686 if (timer.mInList && timer.mUid != null && timer.mUid.mUid != Process.SYSTEM_UID) { 9687 // Since the collection and blaming of wakelocks can be scheduled to run after 9688 // some delay, the mPartialTimers list may have new entries. We can't blame 9689 // the newly added timer for past cpu time, so we only consider timers that 9690 // were present for one round of collection. Once a timer has gone through 9691 // a round of collection, its mInList field is set to true. 9692 numWakelocks++; 9693 } 9694 } 9695 } 9696 9697 final int numWakelocksF = numWakelocks; 9698 mTempTotalCpuUserTimeUs = 0; 9699 mTempTotalCpuSystemTimeUs = 0; 9700 9701 // Read the CPU data for each UID. This will internally generate a snapshot so next time 9702 // we read, we get a delta. If we are to distribute the cpu time, then do so. Otherwise 9703 // we just ignore the data. 9704 final long startTimeMs = mClocks.elapsedRealtime(); 9705 mKernelUidCpuTimeReader.readDelta(!mOnBatteryInternal ? null : 9706 new KernelUidCpuTimeReader.Callback() { 9707 @Override 9708 public void onUidCpuTime(int uid, long userTimeUs, long systemTimeUs, 9709 long powerMaUs) { 9710 final Uid u = getUidStatsLocked(mapUid(uid)); 9711 9712 // Accumulate the total system and user time. 9713 mTempTotalCpuUserTimeUs += userTimeUs; 9714 mTempTotalCpuSystemTimeUs += systemTimeUs; 9715 9716 StringBuilder sb = null; 9717 if (DEBUG_ENERGY_CPU) { 9718 sb = new StringBuilder(); 9719 sb.append(" got time for uid=").append(u.mUid).append(": u="); 9720 TimeUtils.formatDuration(userTimeUs / 1000, sb); 9721 sb.append(" s="); 9722 TimeUtils.formatDuration(systemTimeUs / 1000, sb); 9723 sb.append(" p=").append(powerMaUs / 1000).append("mAms\n"); 9724 } 9725 9726 if (numWakelocksF > 0) { 9727 // We have wakelocks being held, so only give a portion of the 9728 // time to the process. The rest will be distributed among wakelock 9729 // holders. 9730 userTimeUs = (userTimeUs * wakelockWeight) / 100; 9731 systemTimeUs = (systemTimeUs * wakelockWeight) / 100; 9732 } 9733 9734 if (sb != null) { 9735 sb.append(" adding to uid=").append(u.mUid).append(": u="); 9736 TimeUtils.formatDuration(userTimeUs / 1000, sb); 9737 sb.append(" s="); 9738 TimeUtils.formatDuration(systemTimeUs / 1000, sb); 9739 sb.append(" p=").append(powerMaUs / 1000).append("mAms"); 9740 Slog.d(TAG, sb.toString()); 9741 } 9742 9743 u.mUserCpuTime.addCountLocked(userTimeUs); 9744 u.mSystemCpuTime.addCountLocked(systemTimeUs); 9745 u.mCpuPower.addCountLocked(powerMaUs); 9746 9747 // Add the cpu speeds to this UID. These are used as a ratio 9748 // for computing the power this UID used. 9749 final int numClusters = mPowerProfile.getNumCpuClusters(); 9750 if (u.mCpuClusterSpeed == null || u.mCpuClusterSpeed.length != 9751 numClusters) { 9752 u.mCpuClusterSpeed = new LongSamplingCounter[numClusters][]; 9753 } 9754 9755 for (int cluster = 0; cluster < clusterSpeeds.length; cluster++) { 9756 final int speedsInCluster = mPowerProfile.getNumSpeedStepsInCpuCluster( 9757 cluster); 9758 if (u.mCpuClusterSpeed[cluster] == null || speedsInCluster != 9759 u.mCpuClusterSpeed[cluster].length) { 9760 u.mCpuClusterSpeed[cluster] = 9761 new LongSamplingCounter[speedsInCluster]; 9762 } 9763 9764 final LongSamplingCounter[] cpuSpeeds = u.mCpuClusterSpeed[cluster]; 9765 for (int speed = 0; speed < clusterSpeeds[cluster].length; speed++) { 9766 if (cpuSpeeds[speed] == null) { 9767 cpuSpeeds[speed] = new LongSamplingCounter(mOnBatteryTimeBase); 9768 } 9769 cpuSpeeds[speed].addCountLocked(clusterSpeeds[cluster][speed]); 9770 } 9771 } 9772 } 9773 }); 9774 9775 // TODO: STOPSHIP, remove the "true" below after b/34961340 is fixed 9776 if (DEBUG_ENERGY_CPU || true) { 9777 Slog.d(TAG, "Reading cpu stats took " + (mClocks.elapsedRealtime() - startTimeMs) + 9778 " ms"); 9779 } 9780 9781 if (mOnBatteryInternal && numWakelocks > 0) { 9782 // Distribute a portion of the total cpu time to wakelock holders. 9783 mTempTotalCpuUserTimeUs = (mTempTotalCpuUserTimeUs * (100 - wakelockWeight)) / 100; 9784 mTempTotalCpuSystemTimeUs = 9785 (mTempTotalCpuSystemTimeUs * (100 - wakelockWeight)) / 100; 9786 9787 for (int i = 0; i < numPartialTimers; i++) { 9788 final StopwatchTimer timer = mPartialTimers.get(i); 9789 9790 // The system does not share any blame, as it is usually holding the wakelock 9791 // on behalf of an app. 9792 if (timer.mInList && timer.mUid != null && timer.mUid.mUid != Process.SYSTEM_UID) { 9793 int userTimeUs = (int) (mTempTotalCpuUserTimeUs / numWakelocks); 9794 int systemTimeUs = (int) (mTempTotalCpuSystemTimeUs / numWakelocks); 9795 9796 if (DEBUG_ENERGY_CPU) { 9797 StringBuilder sb = new StringBuilder(); 9798 sb.append(" Distributing wakelock uid=").append(timer.mUid.mUid) 9799 .append(": u="); 9800 TimeUtils.formatDuration(userTimeUs / 1000, sb); 9801 sb.append(" s="); 9802 TimeUtils.formatDuration(systemTimeUs / 1000, sb); 9803 Slog.d(TAG, sb.toString()); 9804 } 9805 9806 timer.mUid.mUserCpuTime.addCountLocked(userTimeUs); 9807 timer.mUid.mSystemCpuTime.addCountLocked(systemTimeUs); 9808 9809 final Uid.Proc proc = timer.mUid.getProcessStatsLocked("*wakelock*"); 9810 proc.addCpuTimeLocked(userTimeUs / 1000, systemTimeUs / 1000); 9811 9812 mTempTotalCpuUserTimeUs -= userTimeUs; 9813 mTempTotalCpuSystemTimeUs -= systemTimeUs; 9814 numWakelocks--; 9815 } 9816 } 9817 9818 if (mTempTotalCpuUserTimeUs > 0 || mTempTotalCpuSystemTimeUs > 0) { 9819 // Anything left over is given to the system. 9820 if (DEBUG_ENERGY_CPU) { 9821 StringBuilder sb = new StringBuilder(); 9822 sb.append(" Distributing lost time to system: u="); 9823 TimeUtils.formatDuration(mTempTotalCpuUserTimeUs / 1000, sb); 9824 sb.append(" s="); 9825 TimeUtils.formatDuration(mTempTotalCpuSystemTimeUs / 1000, sb); 9826 Slog.d(TAG, sb.toString()); 9827 } 9828 9829 final Uid u = getUidStatsLocked(Process.SYSTEM_UID); 9830 u.mUserCpuTime.addCountLocked(mTempTotalCpuUserTimeUs); 9831 u.mSystemCpuTime.addCountLocked(mTempTotalCpuSystemTimeUs); 9832 9833 final Uid.Proc proc = u.getProcessStatsLocked("*lost*"); 9834 proc.addCpuTimeLocked((int) mTempTotalCpuUserTimeUs / 1000, 9835 (int) mTempTotalCpuSystemTimeUs / 1000); 9836 } 9837 } 9838 9839 // See if there is a difference in wakelocks between this collection and the last 9840 // collection. 9841 if (ArrayUtils.referenceEquals(mPartialTimers, mLastPartialTimers)) { 9842 // No difference, so each timer is now considered for the next collection. 9843 for (int i = 0; i < numPartialTimers; i++) { 9844 mPartialTimers.get(i).mInList = true; 9845 } 9846 } else { 9847 // The lists are different, meaning we added (or removed a timer) since the last 9848 // collection. 9849 final int numLastPartialTimers = mLastPartialTimers.size(); 9850 for (int i = 0; i < numLastPartialTimers; i++) { 9851 mLastPartialTimers.get(i).mInList = false; 9852 } 9853 mLastPartialTimers.clear(); 9854 9855 // Mark the current timers as gone through a collection. 9856 for (int i = 0; i < numPartialTimers; i++) { 9857 final StopwatchTimer timer = mPartialTimers.get(i); 9858 timer.mInList = true; 9859 mLastPartialTimers.add(timer); 9860 } 9861 } 9862 } 9863 9864 boolean setChargingLocked(boolean charging) { 9865 if (mCharging != charging) { 9866 mCharging = charging; 9867 if (charging) { 9868 mHistoryCur.states2 |= HistoryItem.STATE2_CHARGING_FLAG; 9869 } else { 9870 mHistoryCur.states2 &= ~HistoryItem.STATE2_CHARGING_FLAG; 9871 } 9872 mHandler.sendEmptyMessage(MSG_REPORT_CHARGING); 9873 return true; 9874 } 9875 return false; 9876 } 9877 9878 void setOnBatteryLocked(final long mSecRealtime, final long mSecUptime, final boolean onBattery, 9879 final int oldStatus, final int level, final int chargeUAh) { 9880 boolean doWrite = false; 9881 Message m = mHandler.obtainMessage(MSG_REPORT_POWER_CHANGE); 9882 m.arg1 = onBattery ? 1 : 0; 9883 mHandler.sendMessage(m); 9884 9885 final long uptime = mSecUptime * 1000; 9886 final long realtime = mSecRealtime * 1000; 9887 final boolean screenOn = mScreenState == Display.STATE_ON; 9888 if (onBattery) { 9889 // We will reset our status if we are unplugging after the 9890 // battery was last full, or the level is at 100, or 9891 // we have gone through a significant charge (from a very low 9892 // level to a now very high level). 9893 boolean reset = false; 9894 if (!mNoAutoReset && (oldStatus == BatteryManager.BATTERY_STATUS_FULL 9895 || level >= 90 9896 || (mDischargeCurrentLevel < 20 && level >= 80) 9897 || (getHighDischargeAmountSinceCharge() >= 200 9898 && mHistoryBuffer.dataSize() >= MAX_HISTORY_BUFFER))) { 9899 Slog.i(TAG, "Resetting battery stats: level=" + level + " status=" + oldStatus 9900 + " dischargeLevel=" + mDischargeCurrentLevel 9901 + " lowAmount=" + getLowDischargeAmountSinceCharge() 9902 + " highAmount=" + getHighDischargeAmountSinceCharge()); 9903 // Before we write, collect a snapshot of the final aggregated 9904 // stats to be reported in the next checkin. Only do this if we have 9905 // a sufficient amount of data to make it interesting. 9906 if (getLowDischargeAmountSinceCharge() >= 20) { 9907 final Parcel parcel = Parcel.obtain(); 9908 writeSummaryToParcel(parcel, true); 9909 BackgroundThread.getHandler().post(new Runnable() { 9910 @Override public void run() { 9911 synchronized (mCheckinFile) { 9912 FileOutputStream stream = null; 9913 try { 9914 stream = mCheckinFile.startWrite(); 9915 stream.write(parcel.marshall()); 9916 stream.flush(); 9917 FileUtils.sync(stream); 9918 stream.close(); 9919 mCheckinFile.finishWrite(stream); 9920 } catch (IOException e) { 9921 Slog.w("BatteryStats", 9922 "Error writing checkin battery statistics", e); 9923 mCheckinFile.failWrite(stream); 9924 } finally { 9925 parcel.recycle(); 9926 } 9927 } 9928 } 9929 }); 9930 } 9931 doWrite = true; 9932 resetAllStatsLocked(); 9933 if (chargeUAh > 0 && level > 0) { 9934 // Only use the reported coulomb charge value if it is supported and reported. 9935 mEstimatedBatteryCapacity = (int) ((chargeUAh / 1000) / (level / 100.0)); 9936 } 9937 mDischargeStartLevel = level; 9938 reset = true; 9939 mDischargeStepTracker.init(); 9940 } 9941 if (mCharging) { 9942 setChargingLocked(false); 9943 } 9944 mLastChargingStateLevel = level; 9945 mOnBattery = mOnBatteryInternal = true; 9946 mLastDischargeStepLevel = level; 9947 mMinDischargeStepLevel = level; 9948 mDischargeStepTracker.clearTime(); 9949 mDailyDischargeStepTracker.clearTime(); 9950 mInitStepMode = mCurStepMode; 9951 mModStepMode = 0; 9952 pullPendingStateUpdatesLocked(); 9953 mHistoryCur.batteryLevel = (byte)level; 9954 mHistoryCur.states &= ~HistoryItem.STATE_BATTERY_PLUGGED_FLAG; 9955 if (DEBUG_HISTORY) Slog.v(TAG, "Battery unplugged to: " 9956 + Integer.toHexString(mHistoryCur.states)); 9957 if (reset) { 9958 mRecordingHistory = true; 9959 startRecordingHistory(mSecRealtime, mSecUptime, reset); 9960 } 9961 addHistoryRecordLocked(mSecRealtime, mSecUptime); 9962 mDischargeCurrentLevel = mDischargeUnplugLevel = level; 9963 if (screenOn) { 9964 mDischargeScreenOnUnplugLevel = level; 9965 mDischargeScreenOffUnplugLevel = 0; 9966 } else { 9967 mDischargeScreenOnUnplugLevel = 0; 9968 mDischargeScreenOffUnplugLevel = level; 9969 } 9970 mDischargeAmountScreenOn = 0; 9971 mDischargeAmountScreenOff = 0; 9972 updateTimeBasesLocked(true, !screenOn, uptime, realtime); 9973 } else { 9974 mLastChargingStateLevel = level; 9975 mOnBattery = mOnBatteryInternal = false; 9976 pullPendingStateUpdatesLocked(); 9977 mHistoryCur.batteryLevel = (byte)level; 9978 mHistoryCur.states |= HistoryItem.STATE_BATTERY_PLUGGED_FLAG; 9979 if (DEBUG_HISTORY) Slog.v(TAG, "Battery plugged to: " 9980 + Integer.toHexString(mHistoryCur.states)); 9981 addHistoryRecordLocked(mSecRealtime, mSecUptime); 9982 mDischargeCurrentLevel = mDischargePlugLevel = level; 9983 if (level < mDischargeUnplugLevel) { 9984 mLowDischargeAmountSinceCharge += mDischargeUnplugLevel-level-1; 9985 mHighDischargeAmountSinceCharge += mDischargeUnplugLevel-level; 9986 } 9987 updateDischargeScreenLevelsLocked(screenOn, screenOn); 9988 updateTimeBasesLocked(false, !screenOn, uptime, realtime); 9989 mChargeStepTracker.init(); 9990 mLastChargeStepLevel = level; 9991 mMaxChargeStepLevel = level; 9992 mInitStepMode = mCurStepMode; 9993 mModStepMode = 0; 9994 } 9995 if (doWrite || (mLastWriteTime + (60 * 1000)) < mSecRealtime) { 9996 if (mFile != null) { 9997 writeAsyncLocked(); 9998 } 9999 } 10000 } 10001 10002 private void startRecordingHistory(final long elapsedRealtimeMs, final long uptimeMs, 10003 boolean reset) { 10004 mRecordingHistory = true; 10005 mHistoryCur.currentTime = System.currentTimeMillis(); 10006 addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, 10007 reset ? HistoryItem.CMD_RESET : HistoryItem.CMD_CURRENT_TIME, 10008 mHistoryCur); 10009 mHistoryCur.currentTime = 0; 10010 if (reset) { 10011 initActiveHistoryEventsLocked(elapsedRealtimeMs, uptimeMs); 10012 } 10013 } 10014 10015 private void recordCurrentTimeChangeLocked(final long currentTime, final long elapsedRealtimeMs, 10016 final long uptimeMs) { 10017 if (mRecordingHistory) { 10018 mHistoryCur.currentTime = currentTime; 10019 addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.CMD_CURRENT_TIME, 10020 mHistoryCur); 10021 mHistoryCur.currentTime = 0; 10022 } 10023 } 10024 10025 private void recordShutdownLocked(final long elapsedRealtimeMs, final long uptimeMs) { 10026 if (mRecordingHistory) { 10027 mHistoryCur.currentTime = System.currentTimeMillis(); 10028 addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.CMD_SHUTDOWN, 10029 mHistoryCur); 10030 mHistoryCur.currentTime = 0; 10031 } 10032 } 10033 10034 private void scheduleSyncExternalStatsLocked(String reason, int updateFlags) { 10035 if (mExternalSync != null) { 10036 mExternalSync.scheduleSync(reason, updateFlags); 10037 } 10038 } 10039 10040 // This should probably be exposed in the API, though it's not critical 10041 public static final int BATTERY_PLUGGED_NONE = 0; 10042 10043 public void setBatteryStateLocked(int status, int health, int plugType, int level, 10044 int temp, int volt, int chargeUAh, int chargeFullUAh) { 10045 // Temperature is encoded without the signed bit, so clamp any negative temperatures to 0. 10046 temp = Math.max(0, temp); 10047 10048 final boolean onBattery = plugType == BATTERY_PLUGGED_NONE; 10049 final long uptime = mClocks.uptimeMillis(); 10050 final long elapsedRealtime = mClocks.elapsedRealtime(); 10051 if (!mHaveBatteryLevel) { 10052 mHaveBatteryLevel = true; 10053 // We start out assuming that the device is plugged in (not 10054 // on battery). If our first report is now that we are indeed 10055 // plugged in, then twiddle our state to correctly reflect that 10056 // since we won't be going through the full setOnBattery(). 10057 if (onBattery == mOnBattery) { 10058 if (onBattery) { 10059 mHistoryCur.states &= ~HistoryItem.STATE_BATTERY_PLUGGED_FLAG; 10060 } else { 10061 mHistoryCur.states |= HistoryItem.STATE_BATTERY_PLUGGED_FLAG; 10062 } 10063 } 10064 // Always start out assuming charging, that will be updated later. 10065 mHistoryCur.states2 |= HistoryItem.STATE2_CHARGING_FLAG; 10066 mHistoryCur.batteryStatus = (byte)status; 10067 mHistoryCur.batteryLevel = (byte)level; 10068 mHistoryCur.batteryChargeUAh = chargeUAh; 10069 mMaxChargeStepLevel = mMinDischargeStepLevel = 10070 mLastChargeStepLevel = mLastDischargeStepLevel = level; 10071 mLastChargingStateLevel = level; 10072 } else if (mCurrentBatteryLevel != level || mOnBattery != onBattery) { 10073 recordDailyStatsIfNeededLocked(level >= 100 && onBattery); 10074 } 10075 int oldStatus = mHistoryCur.batteryStatus; 10076 if (onBattery) { 10077 mDischargeCurrentLevel = level; 10078 if (!mRecordingHistory) { 10079 mRecordingHistory = true; 10080 startRecordingHistory(elapsedRealtime, uptime, true); 10081 } 10082 } else if (level < 96) { 10083 if (!mRecordingHistory) { 10084 mRecordingHistory = true; 10085 startRecordingHistory(elapsedRealtime, uptime, true); 10086 } 10087 } 10088 mCurrentBatteryLevel = level; 10089 if (mDischargePlugLevel < 0) { 10090 mDischargePlugLevel = level; 10091 } 10092 10093 if (onBattery != mOnBattery) { 10094 mHistoryCur.batteryLevel = (byte)level; 10095 mHistoryCur.batteryStatus = (byte)status; 10096 mHistoryCur.batteryHealth = (byte)health; 10097 mHistoryCur.batteryPlugType = (byte)plugType; 10098 mHistoryCur.batteryTemperature = (short)temp; 10099 mHistoryCur.batteryVoltage = (char)volt; 10100 if (chargeUAh < mHistoryCur.batteryChargeUAh) { 10101 // Only record discharges 10102 final long chargeDiff = mHistoryCur.batteryChargeUAh - chargeUAh; 10103 mDischargeCounter.addCountLocked(chargeDiff); 10104 mDischargeScreenOffCounter.addCountLocked(chargeDiff); 10105 } 10106 mHistoryCur.batteryChargeUAh = chargeUAh; 10107 setOnBatteryLocked(elapsedRealtime, uptime, onBattery, oldStatus, level, chargeUAh); 10108 } else { 10109 boolean changed = false; 10110 if (mHistoryCur.batteryLevel != level) { 10111 mHistoryCur.batteryLevel = (byte)level; 10112 changed = true; 10113 10114 // TODO(adamlesinski): Schedule the creation of a HistoryStepDetails record 10115 // which will pull external stats. 10116 scheduleSyncExternalStatsLocked("battery-level", ExternalStatsSync.UPDATE_ALL); 10117 } 10118 if (mHistoryCur.batteryStatus != status) { 10119 mHistoryCur.batteryStatus = (byte)status; 10120 changed = true; 10121 } 10122 if (mHistoryCur.batteryHealth != health) { 10123 mHistoryCur.batteryHealth = (byte)health; 10124 changed = true; 10125 } 10126 if (mHistoryCur.batteryPlugType != plugType) { 10127 mHistoryCur.batteryPlugType = (byte)plugType; 10128 changed = true; 10129 } 10130 if (temp >= (mHistoryCur.batteryTemperature+10) 10131 || temp <= (mHistoryCur.batteryTemperature-10)) { 10132 mHistoryCur.batteryTemperature = (short)temp; 10133 changed = true; 10134 } 10135 if (volt > (mHistoryCur.batteryVoltage+20) 10136 || volt < (mHistoryCur.batteryVoltage-20)) { 10137 mHistoryCur.batteryVoltage = (char)volt; 10138 changed = true; 10139 } 10140 if (chargeUAh >= (mHistoryCur.batteryChargeUAh+10) 10141 || chargeUAh <= (mHistoryCur.batteryChargeUAh-10)) { 10142 if (chargeUAh < mHistoryCur.batteryChargeUAh) { 10143 // Only record discharges 10144 final long chargeDiff = mHistoryCur.batteryChargeUAh - chargeUAh; 10145 mDischargeCounter.addCountLocked(chargeDiff); 10146 mDischargeScreenOffCounter.addCountLocked(chargeDiff); 10147 } 10148 mHistoryCur.batteryChargeUAh = chargeUAh; 10149 changed = true; 10150 } 10151 long modeBits = (((long)mInitStepMode) << STEP_LEVEL_INITIAL_MODE_SHIFT) 10152 | (((long)mModStepMode) << STEP_LEVEL_MODIFIED_MODE_SHIFT) 10153 | (((long)(level&0xff)) << STEP_LEVEL_LEVEL_SHIFT); 10154 if (onBattery) { 10155 changed |= setChargingLocked(false); 10156 if (mLastDischargeStepLevel != level && mMinDischargeStepLevel > level) { 10157 mDischargeStepTracker.addLevelSteps(mLastDischargeStepLevel - level, 10158 modeBits, elapsedRealtime); 10159 mDailyDischargeStepTracker.addLevelSteps(mLastDischargeStepLevel - level, 10160 modeBits, elapsedRealtime); 10161 mLastDischargeStepLevel = level; 10162 mMinDischargeStepLevel = level; 10163 mInitStepMode = mCurStepMode; 10164 mModStepMode = 0; 10165 } 10166 } else { 10167 if (level >= 90) { 10168 // If the battery level is at least 90%, always consider the device to be 10169 // charging even if it happens to go down a level. 10170 changed |= setChargingLocked(true); 10171 mLastChargeStepLevel = level; 10172 } if (!mCharging) { 10173 if (mLastChargeStepLevel < level) { 10174 // We have not reporting that we are charging, but the level has now 10175 // gone up, so consider the state to be charging. 10176 changed |= setChargingLocked(true); 10177 mLastChargeStepLevel = level; 10178 } 10179 } else { 10180 if (mLastChargeStepLevel > level) { 10181 // We had reported that the device was charging, but here we are with 10182 // power connected and the level going down. Looks like the current 10183 // power supplied isn't enough, so consider the device to now be 10184 // discharging. 10185 changed |= setChargingLocked(false); 10186 mLastChargeStepLevel = level; 10187 } 10188 } 10189 if (mLastChargeStepLevel != level && mMaxChargeStepLevel < level) { 10190 mChargeStepTracker.addLevelSteps(level - mLastChargeStepLevel, 10191 modeBits, elapsedRealtime); 10192 mDailyChargeStepTracker.addLevelSteps(level - mLastChargeStepLevel, 10193 modeBits, elapsedRealtime); 10194 mLastChargeStepLevel = level; 10195 mMaxChargeStepLevel = level; 10196 mInitStepMode = mCurStepMode; 10197 mModStepMode = 0; 10198 } 10199 } 10200 if (changed) { 10201 addHistoryRecordLocked(elapsedRealtime, uptime); 10202 } 10203 } 10204 if (!onBattery && status == BatteryManager.BATTERY_STATUS_FULL) { 10205 // We don't record history while we are plugged in and fully charged. 10206 // The next time we are unplugged, history will be cleared. 10207 mRecordingHistory = DEBUG; 10208 } 10209 10210 if (differsByMoreThan(chargeFullUAh, mLastChargeFullUAh, 100)) { 10211 mLastChargeFullUAh = chargeFullUAh; 10212 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_ESTIMATED_BATTERY_CAP, 10213 "", chargeFullUAh / 1000); 10214 } 10215 } 10216 10217 private static boolean differsByMoreThan(int left, int right, int diff) { 10218 return Math.abs(left - right) > diff; 10219 } 10220 10221 public long getAwakeTimeBattery() { 10222 return computeBatteryUptime(getBatteryUptimeLocked(), STATS_CURRENT); 10223 } 10224 10225 public long getAwakeTimePlugged() { 10226 return (mClocks.uptimeMillis() * 1000) - getAwakeTimeBattery(); 10227 } 10228 10229 @Override 10230 public long computeUptime(long curTime, int which) { 10231 switch (which) { 10232 case STATS_SINCE_CHARGED: return mUptime + (curTime-mUptimeStart); 10233 case STATS_CURRENT: return (curTime-mUptimeStart); 10234 case STATS_SINCE_UNPLUGGED: return (curTime-mOnBatteryTimeBase.getUptimeStart()); 10235 } 10236 return 0; 10237 } 10238 10239 @Override 10240 public long computeRealtime(long curTime, int which) { 10241 switch (which) { 10242 case STATS_SINCE_CHARGED: return mRealtime + (curTime-mRealtimeStart); 10243 case STATS_CURRENT: return (curTime-mRealtimeStart); 10244 case STATS_SINCE_UNPLUGGED: return (curTime-mOnBatteryTimeBase.getRealtimeStart()); 10245 } 10246 return 0; 10247 } 10248 10249 @Override 10250 public long computeBatteryUptime(long curTime, int which) { 10251 return mOnBatteryTimeBase.computeUptime(curTime, which); 10252 } 10253 10254 @Override 10255 public long computeBatteryRealtime(long curTime, int which) { 10256 return mOnBatteryTimeBase.computeRealtime(curTime, which); 10257 } 10258 10259 @Override 10260 public long computeBatteryScreenOffUptime(long curTime, int which) { 10261 return mOnBatteryScreenOffTimeBase.computeUptime(curTime, which); 10262 } 10263 10264 @Override 10265 public long computeBatteryScreenOffRealtime(long curTime, int which) { 10266 return mOnBatteryScreenOffTimeBase.computeRealtime(curTime, which); 10267 } 10268 10269 private long computeTimePerLevel(long[] steps, int numSteps) { 10270 // For now we'll do a simple average across all steps. 10271 if (numSteps <= 0) { 10272 return -1; 10273 } 10274 long total = 0; 10275 for (int i=0; i<numSteps; i++) { 10276 total += steps[i] & STEP_LEVEL_TIME_MASK; 10277 } 10278 return total / numSteps; 10279 /* 10280 long[] buckets = new long[numSteps]; 10281 int numBuckets = 0; 10282 int numToAverage = 4; 10283 int i = 0; 10284 while (i < numSteps) { 10285 long totalTime = 0; 10286 int num = 0; 10287 for (int j=0; j<numToAverage && (i+j)<numSteps; j++) { 10288 totalTime += steps[i+j] & STEP_LEVEL_TIME_MASK; 10289 num++; 10290 } 10291 buckets[numBuckets] = totalTime / num; 10292 numBuckets++; 10293 numToAverage *= 2; 10294 i += num; 10295 } 10296 if (numBuckets < 1) { 10297 return -1; 10298 } 10299 long averageTime = buckets[numBuckets-1]; 10300 for (i=numBuckets-2; i>=0; i--) { 10301 averageTime = (averageTime + buckets[i]) / 2; 10302 } 10303 return averageTime; 10304 */ 10305 } 10306 10307 @Override 10308 public long computeBatteryTimeRemaining(long curTime) { 10309 if (!mOnBattery) { 10310 return -1; 10311 } 10312 /* Simple implementation just looks at the average discharge per level across the 10313 entire sample period. 10314 int discharge = (getLowDischargeAmountSinceCharge()+getHighDischargeAmountSinceCharge())/2; 10315 if (discharge < 2) { 10316 return -1; 10317 } 10318 long duration = computeBatteryRealtime(curTime, STATS_SINCE_CHARGED); 10319 if (duration < 1000*1000) { 10320 return -1; 10321 } 10322 long usPerLevel = duration/discharge; 10323 return usPerLevel * mCurrentBatteryLevel; 10324 */ 10325 if (mDischargeStepTracker.mNumStepDurations < 1) { 10326 return -1; 10327 } 10328 long msPerLevel = mDischargeStepTracker.computeTimePerLevel(); 10329 if (msPerLevel <= 0) { 10330 return -1; 10331 } 10332 return (msPerLevel * mCurrentBatteryLevel) * 1000; 10333 } 10334 10335 @Override 10336 public LevelStepTracker getDischargeLevelStepTracker() { 10337 return mDischargeStepTracker; 10338 } 10339 10340 @Override 10341 public LevelStepTracker getDailyDischargeLevelStepTracker() { 10342 return mDailyDischargeStepTracker; 10343 } 10344 10345 @Override 10346 public long computeChargeTimeRemaining(long curTime) { 10347 if (mOnBattery) { 10348 // Not yet working. 10349 return -1; 10350 } 10351 /* Broken 10352 int curLevel = mCurrentBatteryLevel; 10353 int plugLevel = mDischargePlugLevel; 10354 if (plugLevel < 0 || curLevel < (plugLevel+1)) { 10355 return -1; 10356 } 10357 long duration = computeBatteryRealtime(curTime, STATS_SINCE_UNPLUGGED); 10358 if (duration < 1000*1000) { 10359 return -1; 10360 } 10361 long usPerLevel = duration/(curLevel-plugLevel); 10362 return usPerLevel * (100-curLevel); 10363 */ 10364 if (mChargeStepTracker.mNumStepDurations < 1) { 10365 return -1; 10366 } 10367 long msPerLevel = mChargeStepTracker.computeTimePerLevel(); 10368 if (msPerLevel <= 0) { 10369 return -1; 10370 } 10371 return (msPerLevel * (100-mCurrentBatteryLevel)) * 1000; 10372 } 10373 10374 @Override 10375 public LevelStepTracker getChargeLevelStepTracker() { 10376 return mChargeStepTracker; 10377 } 10378 10379 @Override 10380 public LevelStepTracker getDailyChargeLevelStepTracker() { 10381 return mDailyChargeStepTracker; 10382 } 10383 10384 @Override 10385 public ArrayList<PackageChange> getDailyPackageChanges() { 10386 return mDailyPackageChanges; 10387 } 10388 10389 protected long getBatteryUptimeLocked() { 10390 return mOnBatteryTimeBase.getUptime(mClocks.uptimeMillis() * 1000); 10391 } 10392 10393 @Override 10394 public long getBatteryUptime(long curTime) { 10395 return mOnBatteryTimeBase.getUptime(curTime); 10396 } 10397 10398 @Override 10399 public long getBatteryRealtime(long curTime) { 10400 return mOnBatteryTimeBase.getRealtime(curTime); 10401 } 10402 10403 @Override 10404 public int getDischargeStartLevel() { 10405 synchronized(this) { 10406 return getDischargeStartLevelLocked(); 10407 } 10408 } 10409 10410 public int getDischargeStartLevelLocked() { 10411 return mDischargeUnplugLevel; 10412 } 10413 10414 @Override 10415 public int getDischargeCurrentLevel() { 10416 synchronized(this) { 10417 return getDischargeCurrentLevelLocked(); 10418 } 10419 } 10420 10421 public int getDischargeCurrentLevelLocked() { 10422 return mDischargeCurrentLevel; 10423 } 10424 10425 @Override 10426 public int getLowDischargeAmountSinceCharge() { 10427 synchronized(this) { 10428 int val = mLowDischargeAmountSinceCharge; 10429 if (mOnBattery && mDischargeCurrentLevel < mDischargeUnplugLevel) { 10430 val += mDischargeUnplugLevel-mDischargeCurrentLevel-1; 10431 } 10432 return val; 10433 } 10434 } 10435 10436 @Override 10437 public int getHighDischargeAmountSinceCharge() { 10438 synchronized(this) { 10439 int val = mHighDischargeAmountSinceCharge; 10440 if (mOnBattery && mDischargeCurrentLevel < mDischargeUnplugLevel) { 10441 val += mDischargeUnplugLevel-mDischargeCurrentLevel; 10442 } 10443 return val; 10444 } 10445 } 10446 10447 @Override 10448 public int getDischargeAmount(int which) { 10449 int dischargeAmount = which == STATS_SINCE_CHARGED 10450 ? getHighDischargeAmountSinceCharge() 10451 : (getDischargeStartLevel() - getDischargeCurrentLevel()); 10452 if (dischargeAmount < 0) { 10453 dischargeAmount = 0; 10454 } 10455 return dischargeAmount; 10456 } 10457 10458 public int getDischargeAmountScreenOn() { 10459 synchronized(this) { 10460 int val = mDischargeAmountScreenOn; 10461 if (mOnBattery && mScreenState == Display.STATE_ON 10462 && mDischargeCurrentLevel < mDischargeScreenOnUnplugLevel) { 10463 val += mDischargeScreenOnUnplugLevel-mDischargeCurrentLevel; 10464 } 10465 return val; 10466 } 10467 } 10468 10469 public int getDischargeAmountScreenOnSinceCharge() { 10470 synchronized(this) { 10471 int val = mDischargeAmountScreenOnSinceCharge; 10472 if (mOnBattery && mScreenState == Display.STATE_ON 10473 && mDischargeCurrentLevel < mDischargeScreenOnUnplugLevel) { 10474 val += mDischargeScreenOnUnplugLevel-mDischargeCurrentLevel; 10475 } 10476 return val; 10477 } 10478 } 10479 10480 public int getDischargeAmountScreenOff() { 10481 synchronized(this) { 10482 int val = mDischargeAmountScreenOff; 10483 if (mOnBattery && mScreenState != Display.STATE_ON 10484 && mDischargeCurrentLevel < mDischargeScreenOffUnplugLevel) { 10485 val += mDischargeScreenOffUnplugLevel-mDischargeCurrentLevel; 10486 } 10487 return val; 10488 } 10489 } 10490 10491 public int getDischargeAmountScreenOffSinceCharge() { 10492 synchronized(this) { 10493 int val = mDischargeAmountScreenOffSinceCharge; 10494 if (mOnBattery && mScreenState != Display.STATE_ON 10495 && mDischargeCurrentLevel < mDischargeScreenOffUnplugLevel) { 10496 val += mDischargeScreenOffUnplugLevel-mDischargeCurrentLevel; 10497 } 10498 return val; 10499 } 10500 } 10501 10502 /** 10503 * Retrieve the statistics object for a particular uid, creating if needed. 10504 */ 10505 public Uid getUidStatsLocked(int uid) { 10506 Uid u = mUidStats.get(uid); 10507 if (u == null) { 10508 u = new Uid(this, uid); 10509 mUidStats.put(uid, u); 10510 } 10511 return u; 10512 } 10513 10514 /** 10515 * Remove the statistics object for a particular uid. 10516 */ 10517 public void removeUidStatsLocked(int uid) { 10518 mKernelUidCpuTimeReader.removeUid(uid); 10519 mUidStats.remove(uid); 10520 } 10521 10522 /** 10523 * Retrieve the statistics object for a particular process, creating 10524 * if needed. 10525 */ 10526 public Uid.Proc getProcessStatsLocked(int uid, String name) { 10527 uid = mapUid(uid); 10528 Uid u = getUidStatsLocked(uid); 10529 return u.getProcessStatsLocked(name); 10530 } 10531 10532 /** 10533 * Retrieve the statistics object for a particular process, creating 10534 * if needed. 10535 */ 10536 public Uid.Pkg getPackageStatsLocked(int uid, String pkg) { 10537 uid = mapUid(uid); 10538 Uid u = getUidStatsLocked(uid); 10539 return u.getPackageStatsLocked(pkg); 10540 } 10541 10542 /** 10543 * Retrieve the statistics object for a particular service, creating 10544 * if needed. 10545 */ 10546 public Uid.Pkg.Serv getServiceStatsLocked(int uid, String pkg, String name) { 10547 uid = mapUid(uid); 10548 Uid u = getUidStatsLocked(uid); 10549 return u.getServiceStatsLocked(pkg, name); 10550 } 10551 10552 public void shutdownLocked() { 10553 recordShutdownLocked(mClocks.elapsedRealtime(), mClocks.uptimeMillis()); 10554 writeSyncLocked(); 10555 mShuttingDown = true; 10556 } 10557 10558 Parcel mPendingWrite = null; 10559 final ReentrantLock mWriteLock = new ReentrantLock(); 10560 10561 public void writeAsyncLocked() { 10562 writeLocked(false); 10563 } 10564 10565 public void writeSyncLocked() { 10566 writeLocked(true); 10567 } 10568 10569 void writeLocked(boolean sync) { 10570 if (mFile == null) { 10571 Slog.w("BatteryStats", "writeLocked: no file associated with this instance"); 10572 return; 10573 } 10574 10575 if (mShuttingDown) { 10576 return; 10577 } 10578 10579 Parcel out = Parcel.obtain(); 10580 writeSummaryToParcel(out, true); 10581 mLastWriteTime = mClocks.elapsedRealtime(); 10582 10583 if (mPendingWrite != null) { 10584 mPendingWrite.recycle(); 10585 } 10586 mPendingWrite = out; 10587 10588 if (sync) { 10589 commitPendingDataToDisk(); 10590 } else { 10591 BackgroundThread.getHandler().post(new Runnable() { 10592 @Override public void run() { 10593 commitPendingDataToDisk(); 10594 } 10595 }); 10596 } 10597 } 10598 10599 public void commitPendingDataToDisk() { 10600 final Parcel next; 10601 synchronized (this) { 10602 next = mPendingWrite; 10603 mPendingWrite = null; 10604 if (next == null) { 10605 return; 10606 } 10607 } 10608 10609 mWriteLock.lock(); 10610 try { 10611 FileOutputStream stream = new FileOutputStream(mFile.chooseForWrite()); 10612 stream.write(next.marshall()); 10613 stream.flush(); 10614 FileUtils.sync(stream); 10615 stream.close(); 10616 mFile.commit(); 10617 } catch (IOException e) { 10618 Slog.w("BatteryStats", "Error writing battery statistics", e); 10619 mFile.rollback(); 10620 } finally { 10621 next.recycle(); 10622 mWriteLock.unlock(); 10623 } 10624 } 10625 10626 public void readLocked() { 10627 if (mDailyFile != null) { 10628 readDailyStatsLocked(); 10629 } 10630 10631 if (mFile == null) { 10632 Slog.w("BatteryStats", "readLocked: no file associated with this instance"); 10633 return; 10634 } 10635 10636 mUidStats.clear(); 10637 10638 try { 10639 File file = mFile.chooseForRead(); 10640 if (!file.exists()) { 10641 return; 10642 } 10643 FileInputStream stream = new FileInputStream(file); 10644 10645 byte[] raw = BatteryStatsHelper.readFully(stream); 10646 Parcel in = Parcel.obtain(); 10647 in.unmarshall(raw, 0, raw.length); 10648 in.setDataPosition(0); 10649 stream.close(); 10650 10651 readSummaryFromParcel(in); 10652 } catch(Exception e) { 10653 Slog.e("BatteryStats", "Error reading battery statistics", e); 10654 resetAllStatsLocked(); 10655 } 10656 10657 mEndPlatformVersion = Build.ID; 10658 10659 if (mHistoryBuffer.dataPosition() > 0) { 10660 mRecordingHistory = true; 10661 final long elapsedRealtime = mClocks.elapsedRealtime(); 10662 final long uptime = mClocks.uptimeMillis(); 10663 if (USE_OLD_HISTORY) { 10664 addHistoryRecordLocked(elapsedRealtime, uptime, HistoryItem.CMD_START, mHistoryCur); 10665 } 10666 addHistoryBufferLocked(elapsedRealtime, uptime, HistoryItem.CMD_START, mHistoryCur); 10667 startRecordingHistory(elapsedRealtime, uptime, false); 10668 } 10669 10670 recordDailyStatsIfNeededLocked(false); 10671 } 10672 10673 public int describeContents() { 10674 return 0; 10675 } 10676 10677 void readHistory(Parcel in, boolean andOldHistory) throws ParcelFormatException { 10678 final long historyBaseTime = in.readLong(); 10679 10680 mHistoryBuffer.setDataSize(0); 10681 mHistoryBuffer.setDataPosition(0); 10682 mHistoryTagPool.clear(); 10683 mNextHistoryTagIdx = 0; 10684 mNumHistoryTagChars = 0; 10685 10686 int numTags = in.readInt(); 10687 for (int i=0; i<numTags; i++) { 10688 int idx = in.readInt(); 10689 String str = in.readString(); 10690 if (str == null) { 10691 throw new ParcelFormatException("null history tag string"); 10692 } 10693 int uid = in.readInt(); 10694 HistoryTag tag = new HistoryTag(); 10695 tag.string = str; 10696 tag.uid = uid; 10697 tag.poolIdx = idx; 10698 mHistoryTagPool.put(tag, idx); 10699 if (idx >= mNextHistoryTagIdx) { 10700 mNextHistoryTagIdx = idx+1; 10701 } 10702 mNumHistoryTagChars += tag.string.length() + 1; 10703 } 10704 10705 int bufSize = in.readInt(); 10706 int curPos = in.dataPosition(); 10707 if (bufSize >= (MAX_MAX_HISTORY_BUFFER*3)) { 10708 throw new ParcelFormatException("File corrupt: history data buffer too large " + 10709 bufSize); 10710 } else if ((bufSize&~3) != bufSize) { 10711 throw new ParcelFormatException("File corrupt: history data buffer not aligned " + 10712 bufSize); 10713 } else { 10714 if (DEBUG_HISTORY) Slog.i(TAG, "***************** READING NEW HISTORY: " + bufSize 10715 + " bytes at " + curPos); 10716 mHistoryBuffer.appendFrom(in, curPos, bufSize); 10717 in.setDataPosition(curPos + bufSize); 10718 } 10719 10720 if (andOldHistory) { 10721 readOldHistory(in); 10722 } 10723 10724 if (DEBUG_HISTORY) { 10725 StringBuilder sb = new StringBuilder(128); 10726 sb.append("****************** OLD mHistoryBaseTime: "); 10727 TimeUtils.formatDuration(mHistoryBaseTime, sb); 10728 Slog.i(TAG, sb.toString()); 10729 } 10730 mHistoryBaseTime = historyBaseTime; 10731 if (DEBUG_HISTORY) { 10732 StringBuilder sb = new StringBuilder(128); 10733 sb.append("****************** NEW mHistoryBaseTime: "); 10734 TimeUtils.formatDuration(mHistoryBaseTime, sb); 10735 Slog.i(TAG, sb.toString()); 10736 } 10737 10738 // We are just arbitrarily going to insert 1 minute from the sample of 10739 // the last run until samples in this run. 10740 if (mHistoryBaseTime > 0) { 10741 long oldnow = mClocks.elapsedRealtime(); 10742 mHistoryBaseTime = mHistoryBaseTime - oldnow + 1; 10743 if (DEBUG_HISTORY) { 10744 StringBuilder sb = new StringBuilder(128); 10745 sb.append("****************** ADJUSTED mHistoryBaseTime: "); 10746 TimeUtils.formatDuration(mHistoryBaseTime, sb); 10747 Slog.i(TAG, sb.toString()); 10748 } 10749 } 10750 } 10751 10752 void readOldHistory(Parcel in) { 10753 if (!USE_OLD_HISTORY) { 10754 return; 10755 } 10756 mHistory = mHistoryEnd = mHistoryCache = null; 10757 long time; 10758 while (in.dataAvail() > 0 && (time=in.readLong()) >= 0) { 10759 HistoryItem rec = new HistoryItem(time, in); 10760 addHistoryRecordLocked(rec); 10761 } 10762 } 10763 10764 void writeHistory(Parcel out, boolean inclData, boolean andOldHistory) { 10765 if (DEBUG_HISTORY) { 10766 StringBuilder sb = new StringBuilder(128); 10767 sb.append("****************** WRITING mHistoryBaseTime: "); 10768 TimeUtils.formatDuration(mHistoryBaseTime, sb); 10769 sb.append(" mLastHistoryElapsedRealtime: "); 10770 TimeUtils.formatDuration(mLastHistoryElapsedRealtime, sb); 10771 Slog.i(TAG, sb.toString()); 10772 } 10773 out.writeLong(mHistoryBaseTime + mLastHistoryElapsedRealtime); 10774 if (!inclData) { 10775 out.writeInt(0); 10776 out.writeInt(0); 10777 return; 10778 } 10779 out.writeInt(mHistoryTagPool.size()); 10780 for (HashMap.Entry<HistoryTag, Integer> ent : mHistoryTagPool.entrySet()) { 10781 HistoryTag tag = ent.getKey(); 10782 out.writeInt(ent.getValue()); 10783 out.writeString(tag.string); 10784 out.writeInt(tag.uid); 10785 } 10786 out.writeInt(mHistoryBuffer.dataSize()); 10787 if (DEBUG_HISTORY) Slog.i(TAG, "***************** WRITING HISTORY: " 10788 + mHistoryBuffer.dataSize() + " bytes at " + out.dataPosition()); 10789 out.appendFrom(mHistoryBuffer, 0, mHistoryBuffer.dataSize()); 10790 10791 if (andOldHistory) { 10792 writeOldHistory(out); 10793 } 10794 } 10795 10796 void writeOldHistory(Parcel out) { 10797 if (!USE_OLD_HISTORY) { 10798 return; 10799 } 10800 HistoryItem rec = mHistory; 10801 while (rec != null) { 10802 if (rec.time >= 0) rec.writeToParcel(out, 0); 10803 rec = rec.next; 10804 } 10805 out.writeLong(-1); 10806 } 10807 10808 public void readSummaryFromParcel(Parcel in) throws ParcelFormatException { 10809 final int version = in.readInt(); 10810 if (version != VERSION) { 10811 Slog.w("BatteryStats", "readFromParcel: version got " + version 10812 + ", expected " + VERSION + "; erasing old stats"); 10813 return; 10814 } 10815 10816 readHistory(in, true); 10817 10818 mStartCount = in.readInt(); 10819 mUptime = in.readLong(); 10820 mRealtime = in.readLong(); 10821 mStartClockTime = in.readLong(); 10822 mStartPlatformVersion = in.readString(); 10823 mEndPlatformVersion = in.readString(); 10824 mOnBatteryTimeBase.readSummaryFromParcel(in); 10825 mOnBatteryScreenOffTimeBase.readSummaryFromParcel(in); 10826 mDischargeUnplugLevel = in.readInt(); 10827 mDischargePlugLevel = in.readInt(); 10828 mDischargeCurrentLevel = in.readInt(); 10829 mCurrentBatteryLevel = in.readInt(); 10830 mEstimatedBatteryCapacity = in.readInt(); 10831 mLowDischargeAmountSinceCharge = in.readInt(); 10832 mHighDischargeAmountSinceCharge = in.readInt(); 10833 mDischargeAmountScreenOnSinceCharge = in.readInt(); 10834 mDischargeAmountScreenOffSinceCharge = in.readInt(); 10835 mDischargeStepTracker.readFromParcel(in); 10836 mChargeStepTracker.readFromParcel(in); 10837 mDailyDischargeStepTracker.readFromParcel(in); 10838 mDailyChargeStepTracker.readFromParcel(in); 10839 mDischargeCounter.readSummaryFromParcelLocked(in); 10840 mDischargeScreenOffCounter.readSummaryFromParcelLocked(in); 10841 int NPKG = in.readInt(); 10842 if (NPKG > 0) { 10843 mDailyPackageChanges = new ArrayList<>(NPKG); 10844 while (NPKG > 0) { 10845 NPKG--; 10846 PackageChange pc = new PackageChange(); 10847 pc.mPackageName = in.readString(); 10848 pc.mUpdate = in.readInt() != 0; 10849 pc.mVersionCode = in.readInt(); 10850 mDailyPackageChanges.add(pc); 10851 } 10852 } else { 10853 mDailyPackageChanges = null; 10854 } 10855 mDailyStartTime = in.readLong(); 10856 mNextMinDailyDeadline = in.readLong(); 10857 mNextMaxDailyDeadline = in.readLong(); 10858 10859 mStartCount++; 10860 10861 mScreenState = Display.STATE_UNKNOWN; 10862 mScreenOnTimer.readSummaryFromParcelLocked(in); 10863 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 10864 mScreenBrightnessTimer[i].readSummaryFromParcelLocked(in); 10865 } 10866 mInteractive = false; 10867 mInteractiveTimer.readSummaryFromParcelLocked(in); 10868 mPhoneOn = false; 10869 mPowerSaveModeEnabledTimer.readSummaryFromParcelLocked(in); 10870 mLongestLightIdleTime = in.readLong(); 10871 mLongestFullIdleTime = in.readLong(); 10872 mDeviceIdleModeLightTimer.readSummaryFromParcelLocked(in); 10873 mDeviceIdleModeFullTimer.readSummaryFromParcelLocked(in); 10874 mDeviceLightIdlingTimer.readSummaryFromParcelLocked(in); 10875 mDeviceIdlingTimer.readSummaryFromParcelLocked(in); 10876 mPhoneOnTimer.readSummaryFromParcelLocked(in); 10877 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) { 10878 mPhoneSignalStrengthsTimer[i].readSummaryFromParcelLocked(in); 10879 } 10880 mPhoneSignalScanningTimer.readSummaryFromParcelLocked(in); 10881 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 10882 mPhoneDataConnectionsTimer[i].readSummaryFromParcelLocked(in); 10883 } 10884 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 10885 mNetworkByteActivityCounters[i].readSummaryFromParcelLocked(in); 10886 mNetworkPacketActivityCounters[i].readSummaryFromParcelLocked(in); 10887 } 10888 mMobileRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW; 10889 mMobileRadioActiveTimer.readSummaryFromParcelLocked(in); 10890 mMobileRadioActivePerAppTimer.readSummaryFromParcelLocked(in); 10891 mMobileRadioActiveAdjustedTime.readSummaryFromParcelLocked(in); 10892 mMobileRadioActiveUnknownTime.readSummaryFromParcelLocked(in); 10893 mMobileRadioActiveUnknownCount.readSummaryFromParcelLocked(in); 10894 mWifiRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW; 10895 mWifiOn = false; 10896 mWifiOnTimer.readSummaryFromParcelLocked(in); 10897 mGlobalWifiRunning = false; 10898 mGlobalWifiRunningTimer.readSummaryFromParcelLocked(in); 10899 for (int i=0; i<NUM_WIFI_STATES; i++) { 10900 mWifiStateTimer[i].readSummaryFromParcelLocked(in); 10901 } 10902 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) { 10903 mWifiSupplStateTimer[i].readSummaryFromParcelLocked(in); 10904 } 10905 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { 10906 mWifiSignalStrengthsTimer[i].readSummaryFromParcelLocked(in); 10907 } 10908 mWifiActivity.readSummaryFromParcel(in); 10909 mBluetoothActivity.readSummaryFromParcel(in); 10910 mModemActivity.readSummaryFromParcel(in); 10911 mHasWifiReporting = in.readInt() != 0; 10912 mHasBluetoothReporting = in.readInt() != 0; 10913 mHasModemReporting = in.readInt() != 0; 10914 10915 mNumConnectivityChange = mLoadedNumConnectivityChange = in.readInt(); 10916 mFlashlightOnNesting = 0; 10917 mFlashlightOnTimer.readSummaryFromParcelLocked(in); 10918 mCameraOnNesting = 0; 10919 mCameraOnTimer.readSummaryFromParcelLocked(in); 10920 mBluetoothScanNesting = 0; 10921 mBluetoothScanTimer.readSummaryFromParcelLocked(in); 10922 10923 int NKW = in.readInt(); 10924 if (NKW > 10000) { 10925 throw new ParcelFormatException("File corrupt: too many kernel wake locks " + NKW); 10926 } 10927 for (int ikw = 0; ikw < NKW; ikw++) { 10928 if (in.readInt() != 0) { 10929 String kwltName = in.readString(); 10930 getKernelWakelockTimerLocked(kwltName).readSummaryFromParcelLocked(in); 10931 } 10932 } 10933 10934 int NWR = in.readInt(); 10935 if (NWR > 10000) { 10936 throw new ParcelFormatException("File corrupt: too many wakeup reasons " + NWR); 10937 } 10938 for (int iwr = 0; iwr < NWR; iwr++) { 10939 if (in.readInt() != 0) { 10940 String reasonName = in.readString(); 10941 getWakeupReasonTimerLocked(reasonName).readSummaryFromParcelLocked(in); 10942 } 10943 } 10944 10945 int NMS = in.readInt(); 10946 for (int ims = 0; ims < NMS; ims++) { 10947 if (in.readInt() != 0) { 10948 long kmstName = in.readLong(); 10949 getKernelMemoryTimerLocked(kmstName).readSummaryFromParcelLocked(in); 10950 } 10951 } 10952 10953 final int NU = in.readInt(); 10954 if (NU > 10000) { 10955 throw new ParcelFormatException("File corrupt: too many uids " + NU); 10956 } 10957 for (int iu = 0; iu < NU; iu++) { 10958 int uid = in.readInt(); 10959 Uid u = new Uid(this, uid); 10960 mUidStats.put(uid, u); 10961 10962 u.mOnBatteryBackgroundTimeBase.readSummaryFromParcel(in); 10963 10964 u.mWifiRunning = false; 10965 if (in.readInt() != 0) { 10966 u.mWifiRunningTimer.readSummaryFromParcelLocked(in); 10967 } 10968 u.mFullWifiLockOut = false; 10969 if (in.readInt() != 0) { 10970 u.mFullWifiLockTimer.readSummaryFromParcelLocked(in); 10971 } 10972 u.mWifiScanStarted = false; 10973 if (in.readInt() != 0) { 10974 u.mWifiScanTimer.readSummaryFromParcelLocked(in); 10975 } 10976 u.mWifiBatchedScanBinStarted = Uid.NO_BATCHED_SCAN_STARTED; 10977 for (int i = 0; i < Uid.NUM_WIFI_BATCHED_SCAN_BINS; i++) { 10978 if (in.readInt() != 0) { 10979 u.makeWifiBatchedScanBin(i, null); 10980 u.mWifiBatchedScanTimer[i].readSummaryFromParcelLocked(in); 10981 } 10982 } 10983 u.mWifiMulticastEnabled = false; 10984 if (in.readInt() != 0) { 10985 u.mWifiMulticastTimer.readSummaryFromParcelLocked(in); 10986 } 10987 if (in.readInt() != 0) { 10988 u.createAudioTurnedOnTimerLocked().readSummaryFromParcelLocked(in); 10989 } 10990 if (in.readInt() != 0) { 10991 u.createVideoTurnedOnTimerLocked().readSummaryFromParcelLocked(in); 10992 } 10993 if (in.readInt() != 0) { 10994 u.createFlashlightTurnedOnTimerLocked().readSummaryFromParcelLocked(in); 10995 } 10996 if (in.readInt() != 0) { 10997 u.createCameraTurnedOnTimerLocked().readSummaryFromParcelLocked(in); 10998 } 10999 if (in.readInt() != 0) { 11000 u.createForegroundActivityTimerLocked().readSummaryFromParcelLocked(in); 11001 } 11002 if (in.readInt() != 0) { 11003 u.createBluetoothScanTimerLocked().readSummaryFromParcelLocked(in); 11004 } 11005 u.mProcessState = ActivityManager.PROCESS_STATE_NONEXISTENT; 11006 for (int i = 0; i < Uid.NUM_PROCESS_STATE; i++) { 11007 if (in.readInt() != 0) { 11008 u.makeProcessState(i, null); 11009 u.mProcessStateTimer[i].readSummaryFromParcelLocked(in); 11010 } 11011 } 11012 if (in.readInt() != 0) { 11013 u.createVibratorOnTimerLocked().readSummaryFromParcelLocked(in); 11014 } 11015 11016 if (in.readInt() != 0) { 11017 if (u.mUserActivityCounters == null) { 11018 u.initUserActivityLocked(); 11019 } 11020 for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) { 11021 u.mUserActivityCounters[i].readSummaryFromParcelLocked(in); 11022 } 11023 } 11024 11025 if (in.readInt() != 0) { 11026 if (u.mNetworkByteActivityCounters == null) { 11027 u.initNetworkActivityLocked(); 11028 } 11029 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 11030 u.mNetworkByteActivityCounters[i].readSummaryFromParcelLocked(in); 11031 u.mNetworkPacketActivityCounters[i].readSummaryFromParcelLocked(in); 11032 } 11033 u.mMobileRadioActiveTime.readSummaryFromParcelLocked(in); 11034 u.mMobileRadioActiveCount.readSummaryFromParcelLocked(in); 11035 } 11036 11037 u.mUserCpuTime.readSummaryFromParcelLocked(in); 11038 u.mSystemCpuTime.readSummaryFromParcelLocked(in); 11039 u.mCpuPower.readSummaryFromParcelLocked(in); 11040 11041 if (in.readInt() != 0) { 11042 final int numClusters = in.readInt(); 11043 if (mPowerProfile != null && mPowerProfile.getNumCpuClusters() != numClusters) { 11044 throw new ParcelFormatException("Incompatible cpu cluster arrangement"); 11045 } 11046 11047 u.mCpuClusterSpeed = new LongSamplingCounter[numClusters][]; 11048 for (int cluster = 0; cluster < numClusters; cluster++) { 11049 if (in.readInt() != 0) { 11050 final int NSB = in.readInt(); 11051 if (mPowerProfile != null && 11052 mPowerProfile.getNumSpeedStepsInCpuCluster(cluster) != NSB) { 11053 throw new ParcelFormatException("File corrupt: too many speed bins " + 11054 NSB); 11055 } 11056 11057 u.mCpuClusterSpeed[cluster] = new LongSamplingCounter[NSB]; 11058 for (int speed = 0; speed < NSB; speed++) { 11059 if (in.readInt() != 0) { 11060 u.mCpuClusterSpeed[cluster][speed] = new LongSamplingCounter( 11061 mOnBatteryTimeBase); 11062 u.mCpuClusterSpeed[cluster][speed].readSummaryFromParcelLocked(in); 11063 } 11064 } 11065 } else { 11066 u.mCpuClusterSpeed[cluster] = null; 11067 } 11068 } 11069 } else { 11070 u.mCpuClusterSpeed = null; 11071 } 11072 11073 if (in.readInt() != 0) { 11074 u.mMobileRadioApWakeupCount = new LongSamplingCounter(mOnBatteryTimeBase); 11075 u.mMobileRadioApWakeupCount.readSummaryFromParcelLocked(in); 11076 } else { 11077 u.mMobileRadioApWakeupCount = null; 11078 } 11079 11080 if (in.readInt() != 0) { 11081 u.mWifiRadioApWakeupCount = new LongSamplingCounter(mOnBatteryTimeBase); 11082 u.mWifiRadioApWakeupCount.readSummaryFromParcelLocked(in); 11083 } else { 11084 u.mWifiRadioApWakeupCount = null; 11085 } 11086 11087 int NW = in.readInt(); 11088 if (NW > (MAX_WAKELOCKS_PER_UID+1)) { 11089 throw new ParcelFormatException("File corrupt: too many wake locks " + NW); 11090 } 11091 for (int iw = 0; iw < NW; iw++) { 11092 String wlName = in.readString(); 11093 u.readWakeSummaryFromParcelLocked(wlName, in); 11094 } 11095 11096 int NS = in.readInt(); 11097 if (NS > (MAX_WAKELOCKS_PER_UID+1)) { 11098 throw new ParcelFormatException("File corrupt: too many syncs " + NS); 11099 } 11100 for (int is = 0; is < NS; is++) { 11101 String name = in.readString(); 11102 u.readSyncSummaryFromParcelLocked(name, in); 11103 } 11104 11105 int NJ = in.readInt(); 11106 if (NJ > (MAX_WAKELOCKS_PER_UID+1)) { 11107 throw new ParcelFormatException("File corrupt: too many job timers " + NJ); 11108 } 11109 for (int ij = 0; ij < NJ; ij++) { 11110 String name = in.readString(); 11111 u.readJobSummaryFromParcelLocked(name, in); 11112 } 11113 11114 int NP = in.readInt(); 11115 if (NP > 1000) { 11116 throw new ParcelFormatException("File corrupt: too many sensors " + NP); 11117 } 11118 for (int is = 0; is < NP; is++) { 11119 int seNumber = in.readInt(); 11120 if (in.readInt() != 0) { 11121 u.getSensorTimerLocked(seNumber, true).readSummaryFromParcelLocked(in); 11122 } 11123 } 11124 11125 NP = in.readInt(); 11126 if (NP > 1000) { 11127 throw new ParcelFormatException("File corrupt: too many processes " + NP); 11128 } 11129 for (int ip = 0; ip < NP; ip++) { 11130 String procName = in.readString(); 11131 Uid.Proc p = u.getProcessStatsLocked(procName); 11132 p.mUserTime = p.mLoadedUserTime = in.readLong(); 11133 p.mSystemTime = p.mLoadedSystemTime = in.readLong(); 11134 p.mForegroundTime = p.mLoadedForegroundTime = in.readLong(); 11135 p.mStarts = p.mLoadedStarts = in.readInt(); 11136 p.mNumCrashes = p.mLoadedNumCrashes = in.readInt(); 11137 p.mNumAnrs = p.mLoadedNumAnrs = in.readInt(); 11138 p.readExcessivePowerFromParcelLocked(in); 11139 } 11140 11141 NP = in.readInt(); 11142 if (NP > 10000) { 11143 throw new ParcelFormatException("File corrupt: too many packages " + NP); 11144 } 11145 for (int ip = 0; ip < NP; ip++) { 11146 String pkgName = in.readString(); 11147 Uid.Pkg p = u.getPackageStatsLocked(pkgName); 11148 final int NWA = in.readInt(); 11149 if (NWA > 1000) { 11150 throw new ParcelFormatException("File corrupt: too many wakeup alarms " + NWA); 11151 } 11152 p.mWakeupAlarms.clear(); 11153 for (int iwa=0; iwa<NWA; iwa++) { 11154 String tag = in.readString(); 11155 Counter c = new Counter(mOnBatteryTimeBase); 11156 c.readSummaryFromParcelLocked(in); 11157 p.mWakeupAlarms.put(tag, c); 11158 } 11159 NS = in.readInt(); 11160 if (NS > 1000) { 11161 throw new ParcelFormatException("File corrupt: too many services " + NS); 11162 } 11163 for (int is = 0; is < NS; is++) { 11164 String servName = in.readString(); 11165 Uid.Pkg.Serv s = u.getServiceStatsLocked(pkgName, servName); 11166 s.mStartTime = s.mLoadedStartTime = in.readLong(); 11167 s.mStarts = s.mLoadedStarts = in.readInt(); 11168 s.mLaunches = s.mLoadedLaunches = in.readInt(); 11169 } 11170 } 11171 } 11172 } 11173 11174 /** 11175 * Writes a summary of the statistics to a Parcel, in a format suitable to be written to 11176 * disk. This format does not allow a lossless round-trip. 11177 * 11178 * @param out the Parcel to be written to. 11179 */ 11180 public void writeSummaryToParcel(Parcel out, boolean inclHistory) { 11181 pullPendingStateUpdatesLocked(); 11182 11183 // Pull the clock time. This may update the time and make a new history entry 11184 // if we had originally pulled a time before the RTC was set. 11185 long startClockTime = getStartClockTime(); 11186 11187 final long NOW_SYS = mClocks.uptimeMillis() * 1000; 11188 final long NOWREAL_SYS = mClocks.elapsedRealtime() * 1000; 11189 11190 out.writeInt(VERSION); 11191 11192 writeHistory(out, inclHistory, true); 11193 11194 out.writeInt(mStartCount); 11195 out.writeLong(computeUptime(NOW_SYS, STATS_SINCE_CHARGED)); 11196 out.writeLong(computeRealtime(NOWREAL_SYS, STATS_SINCE_CHARGED)); 11197 out.writeLong(startClockTime); 11198 out.writeString(mStartPlatformVersion); 11199 out.writeString(mEndPlatformVersion); 11200 mOnBatteryTimeBase.writeSummaryToParcel(out, NOW_SYS, NOWREAL_SYS); 11201 mOnBatteryScreenOffTimeBase.writeSummaryToParcel(out, NOW_SYS, NOWREAL_SYS); 11202 out.writeInt(mDischargeUnplugLevel); 11203 out.writeInt(mDischargePlugLevel); 11204 out.writeInt(mDischargeCurrentLevel); 11205 out.writeInt(mCurrentBatteryLevel); 11206 out.writeInt(mEstimatedBatteryCapacity); 11207 out.writeInt(getLowDischargeAmountSinceCharge()); 11208 out.writeInt(getHighDischargeAmountSinceCharge()); 11209 out.writeInt(getDischargeAmountScreenOnSinceCharge()); 11210 out.writeInt(getDischargeAmountScreenOffSinceCharge()); 11211 mDischargeStepTracker.writeToParcel(out); 11212 mChargeStepTracker.writeToParcel(out); 11213 mDailyDischargeStepTracker.writeToParcel(out); 11214 mDailyChargeStepTracker.writeToParcel(out); 11215 mDischargeCounter.writeSummaryFromParcelLocked(out); 11216 mDischargeScreenOffCounter.writeSummaryFromParcelLocked(out); 11217 if (mDailyPackageChanges != null) { 11218 final int NPKG = mDailyPackageChanges.size(); 11219 out.writeInt(NPKG); 11220 for (int i=0; i<NPKG; i++) { 11221 PackageChange pc = mDailyPackageChanges.get(i); 11222 out.writeString(pc.mPackageName); 11223 out.writeInt(pc.mUpdate ? 1 : 0); 11224 out.writeInt(pc.mVersionCode); 11225 } 11226 } else { 11227 out.writeInt(0); 11228 } 11229 out.writeLong(mDailyStartTime); 11230 out.writeLong(mNextMinDailyDeadline); 11231 out.writeLong(mNextMaxDailyDeadline); 11232 11233 mScreenOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 11234 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 11235 mScreenBrightnessTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS); 11236 } 11237 mInteractiveTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 11238 mPowerSaveModeEnabledTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 11239 out.writeLong(mLongestLightIdleTime); 11240 out.writeLong(mLongestFullIdleTime); 11241 mDeviceIdleModeLightTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 11242 mDeviceIdleModeFullTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 11243 mDeviceLightIdlingTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 11244 mDeviceIdlingTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 11245 mPhoneOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 11246 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) { 11247 mPhoneSignalStrengthsTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS); 11248 } 11249 mPhoneSignalScanningTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 11250 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 11251 mPhoneDataConnectionsTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS); 11252 } 11253 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 11254 mNetworkByteActivityCounters[i].writeSummaryFromParcelLocked(out); 11255 mNetworkPacketActivityCounters[i].writeSummaryFromParcelLocked(out); 11256 } 11257 mMobileRadioActiveTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 11258 mMobileRadioActivePerAppTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 11259 mMobileRadioActiveAdjustedTime.writeSummaryFromParcelLocked(out); 11260 mMobileRadioActiveUnknownTime.writeSummaryFromParcelLocked(out); 11261 mMobileRadioActiveUnknownCount.writeSummaryFromParcelLocked(out); 11262 mWifiOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 11263 mGlobalWifiRunningTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 11264 for (int i=0; i<NUM_WIFI_STATES; i++) { 11265 mWifiStateTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS); 11266 } 11267 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) { 11268 mWifiSupplStateTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS); 11269 } 11270 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { 11271 mWifiSignalStrengthsTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS); 11272 } 11273 mWifiActivity.writeSummaryToParcel(out); 11274 mBluetoothActivity.writeSummaryToParcel(out); 11275 mModemActivity.writeSummaryToParcel(out); 11276 out.writeInt(mHasWifiReporting ? 1 : 0); 11277 out.writeInt(mHasBluetoothReporting ? 1 : 0); 11278 out.writeInt(mHasModemReporting ? 1 : 0); 11279 11280 out.writeInt(mNumConnectivityChange); 11281 mFlashlightOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 11282 mCameraOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 11283 mBluetoothScanTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 11284 11285 out.writeInt(mKernelWakelockStats.size()); 11286 for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) { 11287 Timer kwlt = ent.getValue(); 11288 if (kwlt != null) { 11289 out.writeInt(1); 11290 out.writeString(ent.getKey()); 11291 kwlt.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 11292 } else { 11293 out.writeInt(0); 11294 } 11295 } 11296 11297 out.writeInt(mWakeupReasonStats.size()); 11298 for (Map.Entry<String, SamplingTimer> ent : mWakeupReasonStats.entrySet()) { 11299 SamplingTimer timer = ent.getValue(); 11300 if (timer != null) { 11301 out.writeInt(1); 11302 out.writeString(ent.getKey()); 11303 timer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 11304 } else { 11305 out.writeInt(0); 11306 } 11307 } 11308 11309 out.writeInt(mKernelMemoryStats.size()); 11310 for (int i = 0; i < mKernelMemoryStats.size(); i++) { 11311 Timer kmt = mKernelMemoryStats.valueAt(i); 11312 if (kmt != null) { 11313 out.writeInt(1); 11314 out.writeLong(mKernelMemoryStats.keyAt(i)); 11315 kmt.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 11316 } else { 11317 out.writeInt(0); 11318 } 11319 } 11320 11321 final int NU = mUidStats.size(); 11322 out.writeInt(NU); 11323 for (int iu = 0; iu < NU; iu++) { 11324 out.writeInt(mUidStats.keyAt(iu)); 11325 Uid u = mUidStats.valueAt(iu); 11326 11327 u.mOnBatteryBackgroundTimeBase.writeSummaryToParcel(out, NOW_SYS, NOWREAL_SYS); 11328 11329 if (u.mWifiRunningTimer != null) { 11330 out.writeInt(1); 11331 u.mWifiRunningTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 11332 } else { 11333 out.writeInt(0); 11334 } 11335 if (u.mFullWifiLockTimer != null) { 11336 out.writeInt(1); 11337 u.mFullWifiLockTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 11338 } else { 11339 out.writeInt(0); 11340 } 11341 if (u.mWifiScanTimer != null) { 11342 out.writeInt(1); 11343 u.mWifiScanTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 11344 } else { 11345 out.writeInt(0); 11346 } 11347 for (int i = 0; i < Uid.NUM_WIFI_BATCHED_SCAN_BINS; i++) { 11348 if (u.mWifiBatchedScanTimer[i] != null) { 11349 out.writeInt(1); 11350 u.mWifiBatchedScanTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS); 11351 } else { 11352 out.writeInt(0); 11353 } 11354 } 11355 if (u.mWifiMulticastTimer != null) { 11356 out.writeInt(1); 11357 u.mWifiMulticastTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 11358 } else { 11359 out.writeInt(0); 11360 } 11361 if (u.mAudioTurnedOnTimer != null) { 11362 out.writeInt(1); 11363 u.mAudioTurnedOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 11364 } else { 11365 out.writeInt(0); 11366 } 11367 if (u.mVideoTurnedOnTimer != null) { 11368 out.writeInt(1); 11369 u.mVideoTurnedOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 11370 } else { 11371 out.writeInt(0); 11372 } 11373 if (u.mFlashlightTurnedOnTimer != null) { 11374 out.writeInt(1); 11375 u.mFlashlightTurnedOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 11376 } else { 11377 out.writeInt(0); 11378 } 11379 if (u.mCameraTurnedOnTimer != null) { 11380 out.writeInt(1); 11381 u.mCameraTurnedOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 11382 } else { 11383 out.writeInt(0); 11384 } 11385 if (u.mForegroundActivityTimer != null) { 11386 out.writeInt(1); 11387 u.mForegroundActivityTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 11388 } else { 11389 out.writeInt(0); 11390 } 11391 if (u.mBluetoothScanTimer != null) { 11392 out.writeInt(1); 11393 u.mBluetoothScanTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 11394 } else { 11395 out.writeInt(0); 11396 } 11397 for (int i = 0; i < Uid.NUM_PROCESS_STATE; i++) { 11398 if (u.mProcessStateTimer[i] != null) { 11399 out.writeInt(1); 11400 u.mProcessStateTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS); 11401 } else { 11402 out.writeInt(0); 11403 } 11404 } 11405 if (u.mVibratorOnTimer != null) { 11406 out.writeInt(1); 11407 u.mVibratorOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 11408 } else { 11409 out.writeInt(0); 11410 } 11411 11412 if (u.mUserActivityCounters == null) { 11413 out.writeInt(0); 11414 } else { 11415 out.writeInt(1); 11416 for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) { 11417 u.mUserActivityCounters[i].writeSummaryFromParcelLocked(out); 11418 } 11419 } 11420 11421 if (u.mNetworkByteActivityCounters == null) { 11422 out.writeInt(0); 11423 } else { 11424 out.writeInt(1); 11425 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 11426 u.mNetworkByteActivityCounters[i].writeSummaryFromParcelLocked(out); 11427 u.mNetworkPacketActivityCounters[i].writeSummaryFromParcelLocked(out); 11428 } 11429 u.mMobileRadioActiveTime.writeSummaryFromParcelLocked(out); 11430 u.mMobileRadioActiveCount.writeSummaryFromParcelLocked(out); 11431 } 11432 11433 u.mUserCpuTime.writeSummaryFromParcelLocked(out); 11434 u.mSystemCpuTime.writeSummaryFromParcelLocked(out); 11435 u.mCpuPower.writeSummaryFromParcelLocked(out); 11436 11437 if (u.mCpuClusterSpeed != null) { 11438 out.writeInt(1); 11439 out.writeInt(u.mCpuClusterSpeed.length); 11440 for (LongSamplingCounter[] cpuSpeeds : u.mCpuClusterSpeed) { 11441 if (cpuSpeeds != null) { 11442 out.writeInt(1); 11443 out.writeInt(cpuSpeeds.length); 11444 for (LongSamplingCounter c : cpuSpeeds) { 11445 if (c != null) { 11446 out.writeInt(1); 11447 c.writeSummaryFromParcelLocked(out); 11448 } else { 11449 out.writeInt(0); 11450 } 11451 } 11452 } else { 11453 out.writeInt(0); 11454 } 11455 } 11456 } else { 11457 out.writeInt(0); 11458 } 11459 11460 if (u.mMobileRadioApWakeupCount != null) { 11461 out.writeInt(1); 11462 u.mMobileRadioApWakeupCount.writeSummaryFromParcelLocked(out); 11463 } else { 11464 out.writeInt(0); 11465 } 11466 11467 if (u.mWifiRadioApWakeupCount != null) { 11468 out.writeInt(1); 11469 u.mWifiRadioApWakeupCount.writeSummaryFromParcelLocked(out); 11470 } else { 11471 out.writeInt(0); 11472 } 11473 11474 final ArrayMap<String, Uid.Wakelock> wakeStats = u.mWakelockStats.getMap(); 11475 int NW = wakeStats.size(); 11476 out.writeInt(NW); 11477 for (int iw=0; iw<NW; iw++) { 11478 out.writeString(wakeStats.keyAt(iw)); 11479 Uid.Wakelock wl = wakeStats.valueAt(iw); 11480 if (wl.mTimerFull != null) { 11481 out.writeInt(1); 11482 wl.mTimerFull.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 11483 } else { 11484 out.writeInt(0); 11485 } 11486 if (wl.mTimerPartial != null) { 11487 out.writeInt(1); 11488 wl.mTimerPartial.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 11489 } else { 11490 out.writeInt(0); 11491 } 11492 if (wl.mTimerWindow != null) { 11493 out.writeInt(1); 11494 wl.mTimerWindow.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 11495 } else { 11496 out.writeInt(0); 11497 } 11498 if (wl.mTimerDraw != null) { 11499 out.writeInt(1); 11500 wl.mTimerDraw.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 11501 } else { 11502 out.writeInt(0); 11503 } 11504 } 11505 11506 final ArrayMap<String, StopwatchTimer> syncStats = u.mSyncStats.getMap(); 11507 int NS = syncStats.size(); 11508 out.writeInt(NS); 11509 for (int is=0; is<NS; is++) { 11510 out.writeString(syncStats.keyAt(is)); 11511 syncStats.valueAt(is).writeSummaryFromParcelLocked(out, NOWREAL_SYS); 11512 } 11513 11514 final ArrayMap<String, DualTimer> jobStats = u.mJobStats.getMap(); 11515 int NJ = jobStats.size(); 11516 out.writeInt(NJ); 11517 for (int ij=0; ij<NJ; ij++) { 11518 out.writeString(jobStats.keyAt(ij)); 11519 jobStats.valueAt(ij).writeSummaryFromParcelLocked(out, NOWREAL_SYS); 11520 } 11521 11522 int NSE = u.mSensorStats.size(); 11523 out.writeInt(NSE); 11524 for (int ise=0; ise<NSE; ise++) { 11525 out.writeInt(u.mSensorStats.keyAt(ise)); 11526 Uid.Sensor se = u.mSensorStats.valueAt(ise); 11527 if (se.mTimer != null) { 11528 out.writeInt(1); 11529 se.mTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 11530 } else { 11531 out.writeInt(0); 11532 } 11533 } 11534 11535 int NP = u.mProcessStats.size(); 11536 out.writeInt(NP); 11537 for (int ip=0; ip<NP; ip++) { 11538 out.writeString(u.mProcessStats.keyAt(ip)); 11539 Uid.Proc ps = u.mProcessStats.valueAt(ip); 11540 out.writeLong(ps.mUserTime); 11541 out.writeLong(ps.mSystemTime); 11542 out.writeLong(ps.mForegroundTime); 11543 out.writeInt(ps.mStarts); 11544 out.writeInt(ps.mNumCrashes); 11545 out.writeInt(ps.mNumAnrs); 11546 ps.writeExcessivePowerToParcelLocked(out); 11547 } 11548 11549 NP = u.mPackageStats.size(); 11550 out.writeInt(NP); 11551 if (NP > 0) { 11552 for (Map.Entry<String, BatteryStatsImpl.Uid.Pkg> ent 11553 : u.mPackageStats.entrySet()) { 11554 out.writeString(ent.getKey()); 11555 Uid.Pkg ps = ent.getValue(); 11556 final int NWA = ps.mWakeupAlarms.size(); 11557 out.writeInt(NWA); 11558 for (int iwa=0; iwa<NWA; iwa++) { 11559 out.writeString(ps.mWakeupAlarms.keyAt(iwa)); 11560 ps.mWakeupAlarms.valueAt(iwa).writeSummaryFromParcelLocked(out); 11561 } 11562 NS = ps.mServiceStats.size(); 11563 out.writeInt(NS); 11564 for (int is=0; is<NS; is++) { 11565 out.writeString(ps.mServiceStats.keyAt(is)); 11566 BatteryStatsImpl.Uid.Pkg.Serv ss = ps.mServiceStats.valueAt(is); 11567 long time = ss.getStartTimeToNowLocked( 11568 mOnBatteryTimeBase.getUptime(NOW_SYS)); 11569 out.writeLong(time); 11570 out.writeInt(ss.mStarts); 11571 out.writeInt(ss.mLaunches); 11572 } 11573 } 11574 } 11575 } 11576 } 11577 11578 public void readFromParcel(Parcel in) { 11579 readFromParcelLocked(in); 11580 } 11581 11582 void readFromParcelLocked(Parcel in) { 11583 int magic = in.readInt(); 11584 if (magic != MAGIC) { 11585 throw new ParcelFormatException("Bad magic number: #" + Integer.toHexString(magic)); 11586 } 11587 11588 readHistory(in, false); 11589 11590 mStartCount = in.readInt(); 11591 mStartClockTime = in.readLong(); 11592 mStartPlatformVersion = in.readString(); 11593 mEndPlatformVersion = in.readString(); 11594 mUptime = in.readLong(); 11595 mUptimeStart = in.readLong(); 11596 mRealtime = in.readLong(); 11597 mRealtimeStart = in.readLong(); 11598 mOnBattery = in.readInt() != 0; 11599 mEstimatedBatteryCapacity = in.readInt(); 11600 mOnBatteryInternal = false; // we are no longer really running. 11601 mOnBatteryTimeBase.readFromParcel(in); 11602 mOnBatteryScreenOffTimeBase.readFromParcel(in); 11603 11604 mScreenState = Display.STATE_UNKNOWN; 11605 mScreenOnTimer = new StopwatchTimer(mClocks, null, -1, null, mOnBatteryTimeBase, in); 11606 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 11607 mScreenBrightnessTimer[i] = new StopwatchTimer(mClocks, null, -100-i, null, 11608 mOnBatteryTimeBase, in); 11609 } 11610 mInteractive = false; 11611 mInteractiveTimer = new StopwatchTimer(mClocks, null, -10, null, mOnBatteryTimeBase, in); 11612 mPhoneOn = false; 11613 mPowerSaveModeEnabledTimer = new StopwatchTimer(mClocks, null, -2, null, 11614 mOnBatteryTimeBase, in); 11615 mLongestLightIdleTime = in.readLong(); 11616 mLongestFullIdleTime = in.readLong(); 11617 mDeviceIdleModeLightTimer = new StopwatchTimer(mClocks, null, -14, null, 11618 mOnBatteryTimeBase, in); 11619 mDeviceIdleModeFullTimer = new StopwatchTimer(mClocks, null, -11, null, 11620 mOnBatteryTimeBase, in); 11621 mDeviceLightIdlingTimer = new StopwatchTimer(mClocks, null, -15, null, 11622 mOnBatteryTimeBase, in); 11623 mDeviceIdlingTimer = new StopwatchTimer(mClocks, null, -12, null, mOnBatteryTimeBase, in); 11624 mPhoneOnTimer = new StopwatchTimer(mClocks, null, -3, null, mOnBatteryTimeBase, in); 11625 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) { 11626 mPhoneSignalStrengthsTimer[i] = new StopwatchTimer(mClocks, null, -200-i, 11627 null, mOnBatteryTimeBase, in); 11628 } 11629 mPhoneSignalScanningTimer = new StopwatchTimer(mClocks, null, -200+1, null, 11630 mOnBatteryTimeBase, in); 11631 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 11632 mPhoneDataConnectionsTimer[i] = new StopwatchTimer(mClocks, null, -300-i, 11633 null, mOnBatteryTimeBase, in); 11634 } 11635 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 11636 mNetworkByteActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase, in); 11637 mNetworkPacketActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase, in); 11638 } 11639 mMobileRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW; 11640 mMobileRadioActiveTimer = new StopwatchTimer(mClocks, null, -400, null, 11641 mOnBatteryTimeBase, in); 11642 mMobileRadioActivePerAppTimer = new StopwatchTimer(mClocks, null, -401, null, 11643 mOnBatteryTimeBase, in); 11644 mMobileRadioActiveAdjustedTime = new LongSamplingCounter(mOnBatteryTimeBase, in); 11645 mMobileRadioActiveUnknownTime = new LongSamplingCounter(mOnBatteryTimeBase, in); 11646 mMobileRadioActiveUnknownCount = new LongSamplingCounter(mOnBatteryTimeBase, in); 11647 mWifiRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW; 11648 mWifiOn = false; 11649 mWifiOnTimer = new StopwatchTimer(mClocks, null, -4, null, mOnBatteryTimeBase, in); 11650 mGlobalWifiRunning = false; 11651 mGlobalWifiRunningTimer = new StopwatchTimer(mClocks, null, -5, null, 11652 mOnBatteryTimeBase, in); 11653 for (int i=0; i<NUM_WIFI_STATES; i++) { 11654 mWifiStateTimer[i] = new StopwatchTimer(mClocks, null, -600-i, 11655 null, mOnBatteryTimeBase, in); 11656 } 11657 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) { 11658 mWifiSupplStateTimer[i] = new StopwatchTimer(mClocks, null, -700-i, 11659 null, mOnBatteryTimeBase, in); 11660 } 11661 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { 11662 mWifiSignalStrengthsTimer[i] = new StopwatchTimer(mClocks, null, -800-i, 11663 null, mOnBatteryTimeBase, in); 11664 } 11665 11666 mWifiActivity = new ControllerActivityCounterImpl(mOnBatteryTimeBase, 11667 NUM_WIFI_TX_LEVELS, in); 11668 mBluetoothActivity = new ControllerActivityCounterImpl(mOnBatteryTimeBase, 11669 NUM_BT_TX_LEVELS, in); 11670 mModemActivity = new ControllerActivityCounterImpl(mOnBatteryTimeBase, 11671 ModemActivityInfo.TX_POWER_LEVELS, in); 11672 mHasWifiReporting = in.readInt() != 0; 11673 mHasBluetoothReporting = in.readInt() != 0; 11674 mHasModemReporting = in.readInt() != 0; 11675 11676 mNumConnectivityChange = in.readInt(); 11677 mLoadedNumConnectivityChange = in.readInt(); 11678 mUnpluggedNumConnectivityChange = in.readInt(); 11679 mAudioOnNesting = 0; 11680 mAudioOnTimer = new StopwatchTimer(mClocks, null, -7, null, mOnBatteryTimeBase); 11681 mVideoOnNesting = 0; 11682 mVideoOnTimer = new StopwatchTimer(mClocks, null, -8, null, mOnBatteryTimeBase); 11683 mFlashlightOnNesting = 0; 11684 mFlashlightOnTimer = new StopwatchTimer(mClocks, null, -9, null, mOnBatteryTimeBase, in); 11685 mCameraOnNesting = 0; 11686 mCameraOnTimer = new StopwatchTimer(mClocks, null, -13, null, mOnBatteryTimeBase, in); 11687 mBluetoothScanNesting = 0; 11688 mBluetoothScanTimer = new StopwatchTimer(mClocks, null, -14, null, mOnBatteryTimeBase, in); 11689 mDischargeUnplugLevel = in.readInt(); 11690 mDischargePlugLevel = in.readInt(); 11691 mDischargeCurrentLevel = in.readInt(); 11692 mCurrentBatteryLevel = in.readInt(); 11693 mLowDischargeAmountSinceCharge = in.readInt(); 11694 mHighDischargeAmountSinceCharge = in.readInt(); 11695 mDischargeAmountScreenOn = in.readInt(); 11696 mDischargeAmountScreenOnSinceCharge = in.readInt(); 11697 mDischargeAmountScreenOff = in.readInt(); 11698 mDischargeAmountScreenOffSinceCharge = in.readInt(); 11699 mDischargeStepTracker.readFromParcel(in); 11700 mChargeStepTracker.readFromParcel(in); 11701 mDischargeCounter = new LongSamplingCounter(mOnBatteryTimeBase, in); 11702 mDischargeScreenOffCounter = new LongSamplingCounter(mOnBatteryTimeBase, in); 11703 mLastWriteTime = in.readLong(); 11704 11705 mKernelWakelockStats.clear(); 11706 int NKW = in.readInt(); 11707 for (int ikw = 0; ikw < NKW; ikw++) { 11708 if (in.readInt() != 0) { 11709 String wakelockName = in.readString(); 11710 SamplingTimer kwlt = new SamplingTimer(mClocks, mOnBatteryScreenOffTimeBase, in); 11711 mKernelWakelockStats.put(wakelockName, kwlt); 11712 } 11713 } 11714 11715 mWakeupReasonStats.clear(); 11716 int NWR = in.readInt(); 11717 for (int iwr = 0; iwr < NWR; iwr++) { 11718 if (in.readInt() != 0) { 11719 String reasonName = in.readString(); 11720 SamplingTimer timer = new SamplingTimer(mClocks, mOnBatteryTimeBase, in); 11721 mWakeupReasonStats.put(reasonName, timer); 11722 } 11723 } 11724 11725 mKernelMemoryStats.clear(); 11726 int nmt = in.readInt(); 11727 for (int imt = 0; imt < nmt; imt++) { 11728 if (in.readInt() != 0) { 11729 Long bucket = in.readLong(); 11730 SamplingTimer kmt = new SamplingTimer(mClocks, mOnBatteryTimeBase, in); 11731 mKernelMemoryStats.put(bucket, kmt); 11732 } 11733 } 11734 11735 mPartialTimers.clear(); 11736 mFullTimers.clear(); 11737 mWindowTimers.clear(); 11738 mWifiRunningTimers.clear(); 11739 mFullWifiLockTimers.clear(); 11740 mWifiScanTimers.clear(); 11741 mWifiBatchedScanTimers.clear(); 11742 mWifiMulticastTimers.clear(); 11743 mAudioTurnedOnTimers.clear(); 11744 mVideoTurnedOnTimers.clear(); 11745 mFlashlightTurnedOnTimers.clear(); 11746 mCameraTurnedOnTimers.clear(); 11747 11748 int numUids = in.readInt(); 11749 mUidStats.clear(); 11750 for (int i = 0; i < numUids; i++) { 11751 int uid = in.readInt(); 11752 Uid u = new Uid(this, uid); 11753 u.readFromParcelLocked(mOnBatteryTimeBase, mOnBatteryScreenOffTimeBase, in); 11754 mUidStats.append(uid, u); 11755 } 11756 } 11757 11758 public void writeToParcel(Parcel out, int flags) { 11759 writeToParcelLocked(out, true, flags); 11760 } 11761 11762 public void writeToParcelWithoutUids(Parcel out, int flags) { 11763 writeToParcelLocked(out, false, flags); 11764 } 11765 11766 @SuppressWarnings("unused") 11767 void writeToParcelLocked(Parcel out, boolean inclUids, int flags) { 11768 // Need to update with current kernel wake lock counts. 11769 pullPendingStateUpdatesLocked(); 11770 11771 // Pull the clock time. This may update the time and make a new history entry 11772 // if we had originally pulled a time before the RTC was set. 11773 long startClockTime = getStartClockTime(); 11774 11775 final long uSecUptime = mClocks.uptimeMillis() * 1000; 11776 final long uSecRealtime = mClocks.elapsedRealtime() * 1000; 11777 final long batteryRealtime = mOnBatteryTimeBase.getRealtime(uSecRealtime); 11778 final long batteryScreenOffRealtime = mOnBatteryScreenOffTimeBase.getRealtime(uSecRealtime); 11779 11780 out.writeInt(MAGIC); 11781 11782 writeHistory(out, true, false); 11783 11784 out.writeInt(mStartCount); 11785 out.writeLong(startClockTime); 11786 out.writeString(mStartPlatformVersion); 11787 out.writeString(mEndPlatformVersion); 11788 out.writeLong(mUptime); 11789 out.writeLong(mUptimeStart); 11790 out.writeLong(mRealtime); 11791 out.writeLong(mRealtimeStart); 11792 out.writeInt(mOnBattery ? 1 : 0); 11793 out.writeInt(mEstimatedBatteryCapacity); 11794 mOnBatteryTimeBase.writeToParcel(out, uSecUptime, uSecRealtime); 11795 mOnBatteryScreenOffTimeBase.writeToParcel(out, uSecUptime, uSecRealtime); 11796 11797 mScreenOnTimer.writeToParcel(out, uSecRealtime); 11798 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 11799 mScreenBrightnessTimer[i].writeToParcel(out, uSecRealtime); 11800 } 11801 mInteractiveTimer.writeToParcel(out, uSecRealtime); 11802 mPowerSaveModeEnabledTimer.writeToParcel(out, uSecRealtime); 11803 out.writeLong(mLongestLightIdleTime); 11804 out.writeLong(mLongestFullIdleTime); 11805 mDeviceIdleModeLightTimer.writeToParcel(out, uSecRealtime); 11806 mDeviceIdleModeFullTimer.writeToParcel(out, uSecRealtime); 11807 mDeviceLightIdlingTimer.writeToParcel(out, uSecRealtime); 11808 mDeviceIdlingTimer.writeToParcel(out, uSecRealtime); 11809 mPhoneOnTimer.writeToParcel(out, uSecRealtime); 11810 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) { 11811 mPhoneSignalStrengthsTimer[i].writeToParcel(out, uSecRealtime); 11812 } 11813 mPhoneSignalScanningTimer.writeToParcel(out, uSecRealtime); 11814 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 11815 mPhoneDataConnectionsTimer[i].writeToParcel(out, uSecRealtime); 11816 } 11817 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 11818 mNetworkByteActivityCounters[i].writeToParcel(out); 11819 mNetworkPacketActivityCounters[i].writeToParcel(out); 11820 } 11821 mMobileRadioActiveTimer.writeToParcel(out, uSecRealtime); 11822 mMobileRadioActivePerAppTimer.writeToParcel(out, uSecRealtime); 11823 mMobileRadioActiveAdjustedTime.writeToParcel(out); 11824 mMobileRadioActiveUnknownTime.writeToParcel(out); 11825 mMobileRadioActiveUnknownCount.writeToParcel(out); 11826 mWifiOnTimer.writeToParcel(out, uSecRealtime); 11827 mGlobalWifiRunningTimer.writeToParcel(out, uSecRealtime); 11828 for (int i=0; i<NUM_WIFI_STATES; i++) { 11829 mWifiStateTimer[i].writeToParcel(out, uSecRealtime); 11830 } 11831 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) { 11832 mWifiSupplStateTimer[i].writeToParcel(out, uSecRealtime); 11833 } 11834 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { 11835 mWifiSignalStrengthsTimer[i].writeToParcel(out, uSecRealtime); 11836 } 11837 mWifiActivity.writeToParcel(out, 0); 11838 mBluetoothActivity.writeToParcel(out, 0); 11839 mModemActivity.writeToParcel(out, 0); 11840 out.writeInt(mHasWifiReporting ? 1 : 0); 11841 out.writeInt(mHasBluetoothReporting ? 1 : 0); 11842 out.writeInt(mHasModemReporting ? 1 : 0); 11843 11844 out.writeInt(mNumConnectivityChange); 11845 out.writeInt(mLoadedNumConnectivityChange); 11846 out.writeInt(mUnpluggedNumConnectivityChange); 11847 mFlashlightOnTimer.writeToParcel(out, uSecRealtime); 11848 mCameraOnTimer.writeToParcel(out, uSecRealtime); 11849 mBluetoothScanTimer.writeToParcel(out, uSecRealtime); 11850 out.writeInt(mDischargeUnplugLevel); 11851 out.writeInt(mDischargePlugLevel); 11852 out.writeInt(mDischargeCurrentLevel); 11853 out.writeInt(mCurrentBatteryLevel); 11854 out.writeInt(mLowDischargeAmountSinceCharge); 11855 out.writeInt(mHighDischargeAmountSinceCharge); 11856 out.writeInt(mDischargeAmountScreenOn); 11857 out.writeInt(mDischargeAmountScreenOnSinceCharge); 11858 out.writeInt(mDischargeAmountScreenOff); 11859 out.writeInt(mDischargeAmountScreenOffSinceCharge); 11860 mDischargeStepTracker.writeToParcel(out); 11861 mChargeStepTracker.writeToParcel(out); 11862 mDischargeCounter.writeToParcel(out); 11863 mDischargeScreenOffCounter.writeToParcel(out); 11864 out.writeLong(mLastWriteTime); 11865 11866 if (inclUids) { 11867 out.writeInt(mKernelWakelockStats.size()); 11868 for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) { 11869 SamplingTimer kwlt = ent.getValue(); 11870 if (kwlt != null) { 11871 out.writeInt(1); 11872 out.writeString(ent.getKey()); 11873 kwlt.writeToParcel(out, uSecRealtime); 11874 } else { 11875 out.writeInt(0); 11876 } 11877 } 11878 out.writeInt(mWakeupReasonStats.size()); 11879 for (Map.Entry<String, SamplingTimer> ent : mWakeupReasonStats.entrySet()) { 11880 SamplingTimer timer = ent.getValue(); 11881 if (timer != null) { 11882 out.writeInt(1); 11883 out.writeString(ent.getKey()); 11884 timer.writeToParcel(out, uSecRealtime); 11885 } else { 11886 out.writeInt(0); 11887 } 11888 } 11889 } else { 11890 out.writeInt(0); 11891 } 11892 11893 out.writeInt(mKernelMemoryStats.size()); 11894 for (int i = 0; i < mKernelMemoryStats.size(); i++) { 11895 SamplingTimer kmt = mKernelMemoryStats.valueAt(i); 11896 if (kmt != null) { 11897 out.writeInt(1); 11898 out.writeLong(mKernelMemoryStats.keyAt(i)); 11899 kmt.writeToParcel(out, uSecRealtime); 11900 } else { 11901 out.writeInt(0); 11902 } 11903 } 11904 11905 if (inclUids) { 11906 int size = mUidStats.size(); 11907 out.writeInt(size); 11908 for (int i = 0; i < size; i++) { 11909 out.writeInt(mUidStats.keyAt(i)); 11910 Uid uid = mUidStats.valueAt(i); 11911 11912 uid.writeToParcelLocked(out, uSecUptime, uSecRealtime); 11913 } 11914 } else { 11915 out.writeInt(0); 11916 } 11917 } 11918 11919 public static final Parcelable.Creator<BatteryStatsImpl> CREATOR = 11920 new Parcelable.Creator<BatteryStatsImpl>() { 11921 public BatteryStatsImpl createFromParcel(Parcel in) { 11922 return new BatteryStatsImpl(in); 11923 } 11924 11925 public BatteryStatsImpl[] newArray(int size) { 11926 return new BatteryStatsImpl[size]; 11927 } 11928 }; 11929 11930 public void prepareForDumpLocked() { 11931 // Need to retrieve current kernel wake lock stats before printing. 11932 pullPendingStateUpdatesLocked(); 11933 11934 // Pull the clock time. This may update the time and make a new history entry 11935 // if we had originally pulled a time before the RTC was set. 11936 getStartClockTime(); 11937 } 11938 11939 public void dumpLocked(Context context, PrintWriter pw, int flags, int reqUid, long histStart) { 11940 if (DEBUG) { 11941 pw.println("mOnBatteryTimeBase:"); 11942 mOnBatteryTimeBase.dump(pw, " "); 11943 pw.println("mOnBatteryScreenOffTimeBase:"); 11944 mOnBatteryScreenOffTimeBase.dump(pw, " "); 11945 Printer pr = new PrintWriterPrinter(pw); 11946 pr.println("*** Screen timer:"); 11947 mScreenOnTimer.logState(pr, " "); 11948 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 11949 pr.println("*** Screen brightness #" + i + ":"); 11950 mScreenBrightnessTimer[i].logState(pr, " "); 11951 } 11952 pr.println("*** Interactive timer:"); 11953 mInteractiveTimer.logState(pr, " "); 11954 pr.println("*** Power save mode timer:"); 11955 mPowerSaveModeEnabledTimer.logState(pr, " "); 11956 pr.println("*** Device idle mode light timer:"); 11957 mDeviceIdleModeLightTimer.logState(pr, " "); 11958 pr.println("*** Device idle mode full timer:"); 11959 mDeviceIdleModeFullTimer.logState(pr, " "); 11960 pr.println("*** Device light idling timer:"); 11961 mDeviceLightIdlingTimer.logState(pr, " "); 11962 pr.println("*** Device idling timer:"); 11963 mDeviceIdlingTimer.logState(pr, " "); 11964 pr.println("*** Phone timer:"); 11965 mPhoneOnTimer.logState(pr, " "); 11966 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) { 11967 pr.println("*** Phone signal strength #" + i + ":"); 11968 mPhoneSignalStrengthsTimer[i].logState(pr, " "); 11969 } 11970 pr.println("*** Signal scanning :"); 11971 mPhoneSignalScanningTimer.logState(pr, " "); 11972 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 11973 pr.println("*** Data connection type #" + i + ":"); 11974 mPhoneDataConnectionsTimer[i].logState(pr, " "); 11975 } 11976 pr.println("*** mMobileRadioPowerState=" + mMobileRadioPowerState); 11977 pr.println("*** Mobile network active timer:"); 11978 mMobileRadioActiveTimer.logState(pr, " "); 11979 pr.println("*** Mobile network active adjusted timer:"); 11980 mMobileRadioActiveAdjustedTime.logState(pr, " "); 11981 pr.println("*** mWifiRadioPowerState=" + mWifiRadioPowerState); 11982 pr.println("*** Wifi timer:"); 11983 mWifiOnTimer.logState(pr, " "); 11984 pr.println("*** WifiRunning timer:"); 11985 mGlobalWifiRunningTimer.logState(pr, " "); 11986 for (int i=0; i<NUM_WIFI_STATES; i++) { 11987 pr.println("*** Wifi state #" + i + ":"); 11988 mWifiStateTimer[i].logState(pr, " "); 11989 } 11990 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) { 11991 pr.println("*** Wifi suppl state #" + i + ":"); 11992 mWifiSupplStateTimer[i].logState(pr, " "); 11993 } 11994 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { 11995 pr.println("*** Wifi signal strength #" + i + ":"); 11996 mWifiSignalStrengthsTimer[i].logState(pr, " "); 11997 } 11998 pr.println("*** Flashlight timer:"); 11999 mFlashlightOnTimer.logState(pr, " "); 12000 pr.println("*** Camera timer:"); 12001 mCameraOnTimer.logState(pr, " "); 12002 } 12003 super.dumpLocked(context, pw, flags, reqUid, histStart); 12004 } 12005} 12006