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