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