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