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