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