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