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