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