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