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