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