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