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