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