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