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