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