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