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