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