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