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