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