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