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