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