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