BatteryStatsImpl.java revision 61659e5daaea80104d4d0fd567e78b5f757b5df4
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 = 109 + (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 addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.CMD_UPDATE, cur); 2113 } 2114 2115 private void addHistoryBufferLocked(long elapsedRealtimeMs, long uptimeMs, byte cmd, 2116 HistoryItem cur) { 2117 if (mIteratingHistory) { 2118 throw new IllegalStateException("Can't do this while iterating history!"); 2119 } 2120 mHistoryBufferLastPos = mHistoryBuffer.dataPosition(); 2121 mHistoryLastLastWritten.setTo(mHistoryLastWritten); 2122 mHistoryLastWritten.setTo(mHistoryBaseTime + elapsedRealtimeMs, cmd, cur); 2123 writeHistoryDelta(mHistoryBuffer, mHistoryLastWritten, mHistoryLastLastWritten); 2124 mLastHistoryElapsedRealtime = elapsedRealtimeMs; 2125 cur.wakelockTag = null; 2126 cur.wakeReasonTag = null; 2127 cur.eventCode = HistoryItem.EVENT_NONE; 2128 cur.eventTag = null; 2129 if (DEBUG_HISTORY) Slog.i(TAG, "Writing history buffer: was " + mHistoryBufferLastPos 2130 + " now " + mHistoryBuffer.dataPosition() 2131 + " size is now " + mHistoryBuffer.dataSize()); 2132 } 2133 2134 int mChangedStates = 0; 2135 int mChangedStates2 = 0; 2136 2137 void addHistoryRecordLocked(long elapsedRealtimeMs, long uptimeMs) { 2138 if (mTrackRunningHistoryElapsedRealtime != 0) { 2139 final long diffElapsed = elapsedRealtimeMs - mTrackRunningHistoryElapsedRealtime; 2140 final long diffUptime = uptimeMs - mTrackRunningHistoryUptime; 2141 if (diffUptime < (diffElapsed-20)) { 2142 final long wakeElapsedTime = elapsedRealtimeMs - (diffElapsed - diffUptime); 2143 mHistoryAddTmp.setTo(mHistoryLastWritten); 2144 mHistoryAddTmp.wakelockTag = null; 2145 mHistoryAddTmp.wakeReasonTag = null; 2146 mHistoryAddTmp.eventCode = HistoryItem.EVENT_NONE; 2147 mHistoryAddTmp.states &= ~HistoryItem.STATE_CPU_RUNNING_FLAG; 2148 addHistoryRecordInnerLocked(wakeElapsedTime, uptimeMs, mHistoryAddTmp); 2149 } 2150 } 2151 mHistoryCur.states |= HistoryItem.STATE_CPU_RUNNING_FLAG; 2152 mTrackRunningHistoryElapsedRealtime = elapsedRealtimeMs; 2153 mTrackRunningHistoryUptime = uptimeMs; 2154 addHistoryRecordInnerLocked(elapsedRealtimeMs, uptimeMs, mHistoryCur); 2155 } 2156 2157 void addHistoryRecordInnerLocked(long elapsedRealtimeMs, long uptimeMs, HistoryItem cur) { 2158 addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, cur); 2159 2160 if (!USE_OLD_HISTORY) { 2161 return; 2162 } 2163 2164 if (!mHaveBatteryLevel || !mRecordingHistory) { 2165 return; 2166 } 2167 2168 // If the current time is basically the same as the last time, 2169 // and no states have since the last recorded entry changed and 2170 // are now resetting back to their original value, then just collapse 2171 // into one record. 2172 if (mHistoryEnd != null && mHistoryEnd.cmd == HistoryItem.CMD_UPDATE 2173 && (mHistoryBaseTime+elapsedRealtimeMs) < (mHistoryEnd.time+1000) 2174 && ((mHistoryEnd.states^cur.states)&mChangedStates) == 0 2175 && ((mHistoryEnd.states2^cur.states2)&mChangedStates2) == 0) { 2176 // If the current is the same as the one before, then we no 2177 // longer need the entry. 2178 if (mHistoryLastEnd != null && mHistoryLastEnd.cmd == HistoryItem.CMD_UPDATE 2179 && (mHistoryBaseTime+elapsedRealtimeMs) < (mHistoryEnd.time+500) 2180 && mHistoryLastEnd.sameNonEvent(cur)) { 2181 mHistoryLastEnd.next = null; 2182 mHistoryEnd.next = mHistoryCache; 2183 mHistoryCache = mHistoryEnd; 2184 mHistoryEnd = mHistoryLastEnd; 2185 mHistoryLastEnd = null; 2186 } else { 2187 mChangedStates |= mHistoryEnd.states^cur.states; 2188 mChangedStates2 |= mHistoryEnd.states^cur.states2; 2189 mHistoryEnd.setTo(mHistoryEnd.time, HistoryItem.CMD_UPDATE, cur); 2190 } 2191 return; 2192 } 2193 2194 mChangedStates = 0; 2195 mChangedStates2 = 0; 2196 2197 if (mNumHistoryItems == MAX_HISTORY_ITEMS 2198 || mNumHistoryItems == MAX_MAX_HISTORY_ITEMS) { 2199 addHistoryRecordLocked(elapsedRealtimeMs, HistoryItem.CMD_OVERFLOW); 2200 } 2201 2202 if (mNumHistoryItems >= MAX_HISTORY_ITEMS) { 2203 // Once we've reached the maximum number of items, we only 2204 // record changes to the battery level and the most interesting states. 2205 // Once we've reached the maximum maximum number of items, we only 2206 // record changes to the battery level. 2207 if (mHistoryEnd != null && mHistoryEnd.batteryLevel 2208 == cur.batteryLevel && 2209 (mNumHistoryItems >= MAX_MAX_HISTORY_ITEMS 2210 || ((mHistoryEnd.states^cur.states) 2211 & HistoryItem.MOST_INTERESTING_STATES) == 0)) { 2212 return; 2213 } 2214 } 2215 2216 addHistoryRecordLocked(elapsedRealtimeMs, HistoryItem.CMD_UPDATE); 2217 } 2218 2219 void addHistoryEventLocked(long elapsedRealtimeMs, long uptimeMs, int code, 2220 String name, int uid) { 2221 mHistoryCur.eventCode = code; 2222 mHistoryCur.eventTag = mHistoryCur.localEventTag; 2223 mHistoryCur.eventTag.string = name; 2224 mHistoryCur.eventTag.uid = uid; 2225 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); 2226 } 2227 2228 void addHistoryRecordLocked(long elapsedRealtimeMs, long uptimeMs, byte cmd, HistoryItem cur) { 2229 HistoryItem rec = mHistoryCache; 2230 if (rec != null) { 2231 mHistoryCache = rec.next; 2232 } else { 2233 rec = new HistoryItem(); 2234 } 2235 rec.setTo(mHistoryBaseTime + elapsedRealtimeMs, cmd, cur); 2236 2237 addHistoryRecordLocked(rec); 2238 } 2239 2240 void addHistoryRecordLocked(HistoryItem rec) { 2241 mNumHistoryItems++; 2242 rec.next = null; 2243 mHistoryLastEnd = mHistoryEnd; 2244 if (mHistoryEnd != null) { 2245 mHistoryEnd.next = rec; 2246 mHistoryEnd = rec; 2247 } else { 2248 mHistory = mHistoryEnd = rec; 2249 } 2250 } 2251 2252 void clearHistoryLocked() { 2253 if (DEBUG_HISTORY) Slog.i(TAG, "********** CLEARING HISTORY!"); 2254 if (USE_OLD_HISTORY) { 2255 if (mHistory != null) { 2256 mHistoryEnd.next = mHistoryCache; 2257 mHistoryCache = mHistory; 2258 mHistory = mHistoryLastEnd = mHistoryEnd = null; 2259 } 2260 mNumHistoryItems = 0; 2261 } 2262 2263 mHistoryBaseTime = 0; 2264 mLastHistoryElapsedRealtime = 0; 2265 mTrackRunningHistoryElapsedRealtime = 0; 2266 mTrackRunningHistoryUptime = 0; 2267 2268 mHistoryBuffer.setDataSize(0); 2269 mHistoryBuffer.setDataPosition(0); 2270 mHistoryBuffer.setDataCapacity(MAX_HISTORY_BUFFER / 2); 2271 mHistoryLastLastWritten.clear(); 2272 mHistoryLastWritten.clear(); 2273 mHistoryTagPool.clear(); 2274 mNextHistoryTagIdx = 0; 2275 mNumHistoryTagChars = 0; 2276 mHistoryBufferLastPos = -1; 2277 mHistoryOverflow = false; 2278 } 2279 2280 public void updateTimeBasesLocked(boolean unplugged, boolean screenOff, long uptime, 2281 long realtime) { 2282 if (mOnBatteryTimeBase.setRunning(unplugged, uptime, realtime)) { 2283 if (unplugged) { 2284 // Track bt headset ping count 2285 mBluetoothPingStart = getCurrentBluetoothPingCount(); 2286 mBluetoothPingCount = 0; 2287 } else { 2288 // Track bt headset ping count 2289 mBluetoothPingCount = getBluetoothPingCount(); 2290 mBluetoothPingStart = -1; 2291 } 2292 } 2293 2294 boolean unpluggedScreenOff = unplugged && screenOff; 2295 if (unpluggedScreenOff != mOnBatteryScreenOffTimeBase.isRunning()) { 2296 updateKernelWakelocksLocked(); 2297 requestWakelockCpuUpdate(); 2298 if (!unpluggedScreenOff) { 2299 // We are switching to no longer tracking wake locks, but we want 2300 // the next CPU update we receive to take them in to account. 2301 mDistributeWakelockCpu = true; 2302 } 2303 mOnBatteryScreenOffTimeBase.setRunning(unpluggedScreenOff, uptime, realtime); 2304 } 2305 } 2306 2307 public void addIsolatedUidLocked(int isolatedUid, int appUid) { 2308 mIsolatedUids.put(isolatedUid, appUid); 2309 } 2310 2311 public void removeIsolatedUidLocked(int isolatedUid, int appUid) { 2312 int curUid = mIsolatedUids.get(isolatedUid, -1); 2313 if (curUid == appUid) { 2314 mIsolatedUids.delete(isolatedUid); 2315 } 2316 } 2317 2318 public int mapUid(int uid) { 2319 int isolated = mIsolatedUids.get(uid, -1); 2320 return isolated > 0 ? isolated : uid; 2321 } 2322 2323 public void noteEventLocked(int code, String name, int uid) { 2324 uid = mapUid(uid); 2325 if (!mActiveEvents.updateState(code, name, uid, 0)) { 2326 return; 2327 } 2328 final long elapsedRealtime = SystemClock.elapsedRealtime(); 2329 final long uptime = SystemClock.uptimeMillis(); 2330 addHistoryEventLocked(elapsedRealtime, uptime, code, name, uid); 2331 } 2332 2333 public void noteProcessStartLocked(String name, int uid) { 2334 uid = mapUid(uid); 2335 if (isOnBattery()) { 2336 Uid u = getUidStatsLocked(uid); 2337 u.getProcessStatsLocked(name).incStartsLocked(); 2338 } 2339 if (!mActiveEvents.updateState(HistoryItem.EVENT_PROC_START, name, uid, 0)) { 2340 return; 2341 } 2342 final long elapsedRealtime = SystemClock.elapsedRealtime(); 2343 final long uptime = SystemClock.uptimeMillis(); 2344 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_PROC_START, name, uid); 2345 } 2346 2347 public void noteProcessStateLocked(String name, int uid, int state) { 2348 uid = mapUid(uid); 2349 final long elapsedRealtime = SystemClock.elapsedRealtime(); 2350 getUidStatsLocked(uid).updateProcessStateLocked(name, state, elapsedRealtime); 2351 } 2352 2353 public void noteProcessFinishLocked(String name, int uid) { 2354 uid = mapUid(uid); 2355 if (!mActiveEvents.updateState(HistoryItem.EVENT_PROC_FINISH, name, uid, 0)) { 2356 return; 2357 } 2358 final long elapsedRealtime = SystemClock.elapsedRealtime(); 2359 final long uptime = SystemClock.uptimeMillis(); 2360 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_PROC_FINISH, name, uid); 2361 getUidStatsLocked(uid).updateProcessStateLocked(name, Uid.PROCESS_STATE_NONE, 2362 elapsedRealtime); 2363 } 2364 2365 private void requestWakelockCpuUpdate() { 2366 if (!mHandler.hasMessages(MSG_UPDATE_WAKELOCKS)) { 2367 Message m = mHandler.obtainMessage(MSG_UPDATE_WAKELOCKS); 2368 mHandler.sendMessageDelayed(m, DELAY_UPDATE_WAKELOCKS); 2369 } 2370 } 2371 2372 public void setRecordAllWakeLocksLocked(boolean enabled) { 2373 mRecordAllWakeLocks = enabled; 2374 if (!enabled) { 2375 // Clear out any existing state. 2376 mActiveEvents.removeEvents(HistoryItem.EVENT_WAKE_LOCK); 2377 } 2378 } 2379 2380 public void setNoAutoReset(boolean enabled) { 2381 mNoAutoReset = enabled; 2382 } 2383 2384 private String mInitialAcquireWakeName; 2385 private int mInitialAcquireWakeUid = -1; 2386 2387 public void noteStartWakeLocked(int uid, int pid, String name, String historyName, int type, 2388 boolean unimportantForLogging, long elapsedRealtime, long uptime) { 2389 uid = mapUid(uid); 2390 if (type == WAKE_TYPE_PARTIAL) { 2391 // Only care about partial wake locks, since full wake locks 2392 // will be canceled when the user puts the screen to sleep. 2393 aggregateLastWakeupUptimeLocked(uptime); 2394 if (historyName == null) { 2395 historyName = name; 2396 } 2397 if (mRecordAllWakeLocks) { 2398 if (mActiveEvents.updateState(HistoryItem.EVENT_WAKE_LOCK_START, historyName, 2399 uid, 0)) { 2400 addHistoryEventLocked(elapsedRealtime, uptime, 2401 HistoryItem.EVENT_WAKE_LOCK_START, historyName, uid); 2402 } 2403 } 2404 if (mWakeLockNesting == 0) { 2405 mHistoryCur.states |= HistoryItem.STATE_WAKE_LOCK_FLAG; 2406 if (DEBUG_HISTORY) Slog.v(TAG, "Start wake lock to: " 2407 + Integer.toHexString(mHistoryCur.states)); 2408 mHistoryCur.wakelockTag = mHistoryCur.localWakelockTag; 2409 mHistoryCur.wakelockTag.string = mInitialAcquireWakeName = historyName; 2410 mHistoryCur.wakelockTag.uid = mInitialAcquireWakeUid = uid; 2411 mWakeLockImportant = !unimportantForLogging; 2412 addHistoryRecordLocked(elapsedRealtime, uptime); 2413 } else if (!mWakeLockImportant && !unimportantForLogging 2414 && mHistoryLastWritten.cmd == HistoryItem.CMD_UPDATE) { 2415 if (mHistoryLastWritten.wakelockTag != null) { 2416 // We'll try to update the last tag. 2417 mHistoryLastWritten.wakelockTag = null; 2418 mHistoryCur.wakelockTag = mHistoryCur.localWakelockTag; 2419 mHistoryCur.wakelockTag.string = mInitialAcquireWakeName = historyName; 2420 mHistoryCur.wakelockTag.uid = mInitialAcquireWakeUid = uid; 2421 addHistoryRecordLocked(elapsedRealtime, uptime); 2422 } 2423 mWakeLockImportant = true; 2424 } 2425 mWakeLockNesting++; 2426 } 2427 if (uid >= 0) { 2428 //if (uid == 0) { 2429 // Slog.wtf(TAG, "Acquiring wake lock from root: " + name); 2430 //} 2431 requestWakelockCpuUpdate(); 2432 getUidStatsLocked(uid).noteStartWakeLocked(pid, name, type, elapsedRealtime); 2433 } 2434 } 2435 2436 public void noteStopWakeLocked(int uid, int pid, String name, String historyName, int type, 2437 long elapsedRealtime, long uptime) { 2438 uid = mapUid(uid); 2439 if (type == WAKE_TYPE_PARTIAL) { 2440 mWakeLockNesting--; 2441 if (mRecordAllWakeLocks) { 2442 if (historyName == null) { 2443 historyName = name; 2444 } 2445 if (mActiveEvents.updateState(HistoryItem.EVENT_WAKE_LOCK_FINISH, historyName, 2446 uid, 0)) { 2447 addHistoryEventLocked(elapsedRealtime, uptime, 2448 HistoryItem.EVENT_WAKE_LOCK_FINISH, historyName, uid); 2449 } 2450 } 2451 if (mWakeLockNesting == 0) { 2452 mHistoryCur.states &= ~HistoryItem.STATE_WAKE_LOCK_FLAG; 2453 if (DEBUG_HISTORY) Slog.v(TAG, "Stop wake lock to: " 2454 + Integer.toHexString(mHistoryCur.states)); 2455 mInitialAcquireWakeName = null; 2456 mInitialAcquireWakeUid = -1; 2457 addHistoryRecordLocked(elapsedRealtime, uptime); 2458 } 2459 } 2460 if (uid >= 0) { 2461 requestWakelockCpuUpdate(); 2462 getUidStatsLocked(uid).noteStopWakeLocked(pid, name, type, elapsedRealtime); 2463 } 2464 } 2465 2466 public void noteStartWakeFromSourceLocked(WorkSource ws, int pid, String name, 2467 String historyName, int type, boolean unimportantForLogging) { 2468 final long elapsedRealtime = SystemClock.elapsedRealtime(); 2469 final long uptime = SystemClock.uptimeMillis(); 2470 final int N = ws.size(); 2471 for (int i=0; i<N; i++) { 2472 noteStartWakeLocked(ws.get(i), pid, name, historyName, type, unimportantForLogging, 2473 elapsedRealtime, uptime); 2474 } 2475 } 2476 2477 public void noteChangeWakelockFromSourceLocked(WorkSource ws, int pid, String name, 2478 String historyName, int type, WorkSource newWs, int newPid, String newName, 2479 String newHistoryName, int newType, boolean newUnimportantForLogging) { 2480 final long elapsedRealtime = SystemClock.elapsedRealtime(); 2481 final long uptime = SystemClock.uptimeMillis(); 2482 // For correct semantics, we start the need worksources first, so that we won't 2483 // make inappropriate history items as if all wake locks went away and new ones 2484 // appeared. This is okay because tracking of wake locks allows nesting. 2485 final int NN = newWs.size(); 2486 for (int i=0; i<NN; i++) { 2487 noteStartWakeLocked(newWs.get(i), newPid, newName, newHistoryName, newType, 2488 newUnimportantForLogging, elapsedRealtime, uptime); 2489 } 2490 final int NO = ws.size(); 2491 for (int i=0; i<NO; i++) { 2492 noteStopWakeLocked(ws.get(i), pid, name, historyName, type, elapsedRealtime, uptime); 2493 } 2494 } 2495 2496 public void noteStopWakeFromSourceLocked(WorkSource ws, int pid, String name, 2497 String historyName, int type) { 2498 final long elapsedRealtime = SystemClock.elapsedRealtime(); 2499 final long uptime = SystemClock.uptimeMillis(); 2500 final int N = ws.size(); 2501 for (int i=0; i<N; i++) { 2502 noteStopWakeLocked(ws.get(i), pid, name, historyName, type, elapsedRealtime, uptime); 2503 } 2504 } 2505 2506 void aggregateLastWakeupUptimeLocked(long uptimeMs) { 2507 if (mLastWakeupReason != null) { 2508 long deltaUptime = uptimeMs - mLastWakeupUptimeMs; 2509 LongSamplingCounter timer = getWakeupReasonCounterLocked(mLastWakeupReason); 2510 timer.addCountLocked(deltaUptime); 2511 mLastWakeupReason = null; 2512 } 2513 } 2514 2515 public void noteWakeupReasonLocked(String reason) { 2516 final long elapsedRealtime = SystemClock.elapsedRealtime(); 2517 final long uptime = SystemClock.uptimeMillis(); 2518 if (DEBUG_HISTORY) Slog.v(TAG, "Wakeup reason reason \"" + reason +"\": " 2519 + Integer.toHexString(mHistoryCur.states)); 2520 aggregateLastWakeupUptimeLocked(uptime); 2521 mHistoryCur.wakeReasonTag = mHistoryCur.localWakeReasonTag; 2522 mHistoryCur.wakeReasonTag.string = reason; 2523 mHistoryCur.wakeReasonTag.uid = 0; 2524 mLastWakeupReason = reason; 2525 mLastWakeupUptimeMs = uptime; 2526 addHistoryRecordLocked(elapsedRealtime, uptime); 2527 } 2528 2529 public int startAddingCpuLocked() { 2530 mHandler.removeMessages(MSG_UPDATE_WAKELOCKS); 2531 2532 final int N = mPartialTimers.size(); 2533 if (N == 0) { 2534 mLastPartialTimers.clear(); 2535 mDistributeWakelockCpu = false; 2536 return 0; 2537 } 2538 2539 if (!mOnBatteryScreenOffTimeBase.isRunning() && !mDistributeWakelockCpu) { 2540 return 0; 2541 } 2542 2543 mDistributeWakelockCpu = false; 2544 2545 // How many timers should consume CPU? Only want to include ones 2546 // that have already been in the list. 2547 for (int i=0; i<N; i++) { 2548 StopwatchTimer st = mPartialTimers.get(i); 2549 if (st.mInList) { 2550 Uid uid = st.mUid; 2551 // We don't include the system UID, because it so often 2552 // holds wake locks at one request or another of an app. 2553 if (uid != null && uid.mUid != Process.SYSTEM_UID) { 2554 return 50; 2555 } 2556 } 2557 } 2558 2559 return 0; 2560 } 2561 2562 public void finishAddingCpuLocked(int perc, int utime, int stime, long[] cpuSpeedTimes) { 2563 final int N = mPartialTimers.size(); 2564 if (perc != 0) { 2565 int num = 0; 2566 for (int i=0; i<N; i++) { 2567 StopwatchTimer st = mPartialTimers.get(i); 2568 if (st.mInList) { 2569 Uid uid = st.mUid; 2570 // We don't include the system UID, because it so often 2571 // holds wake locks at one request or another of an app. 2572 if (uid != null && uid.mUid != Process.SYSTEM_UID) { 2573 num++; 2574 } 2575 } 2576 } 2577 if (num != 0) { 2578 for (int i=0; i<N; i++) { 2579 StopwatchTimer st = mPartialTimers.get(i); 2580 if (st.mInList) { 2581 Uid uid = st.mUid; 2582 if (uid != null && uid.mUid != Process.SYSTEM_UID) { 2583 int myUTime = utime/num; 2584 int mySTime = stime/num; 2585 utime -= myUTime; 2586 stime -= mySTime; 2587 num--; 2588 Uid.Proc proc = uid.getProcessStatsLocked("*wakelock*"); 2589 proc.addCpuTimeLocked(myUTime, mySTime); 2590 proc.addSpeedStepTimes(cpuSpeedTimes); 2591 } 2592 } 2593 } 2594 } 2595 2596 // Just in case, collect any lost CPU time. 2597 if (utime != 0 || stime != 0) { 2598 Uid uid = getUidStatsLocked(Process.SYSTEM_UID); 2599 if (uid != null) { 2600 Uid.Proc proc = uid.getProcessStatsLocked("*lost*"); 2601 proc.addCpuTimeLocked(utime, stime); 2602 proc.addSpeedStepTimes(cpuSpeedTimes); 2603 } 2604 } 2605 } 2606 2607 final int NL = mLastPartialTimers.size(); 2608 boolean diff = N != NL; 2609 for (int i=0; i<NL && !diff; i++) { 2610 diff |= mPartialTimers.get(i) != mLastPartialTimers.get(i); 2611 } 2612 if (!diff) { 2613 for (int i=0; i<NL; i++) { 2614 mPartialTimers.get(i).mInList = true; 2615 } 2616 return; 2617 } 2618 2619 for (int i=0; i<NL; i++) { 2620 mLastPartialTimers.get(i).mInList = false; 2621 } 2622 mLastPartialTimers.clear(); 2623 for (int i=0; i<N; i++) { 2624 StopwatchTimer st = mPartialTimers.get(i); 2625 st.mInList = true; 2626 mLastPartialTimers.add(st); 2627 } 2628 } 2629 2630 public void noteProcessDiedLocked(int uid, int pid) { 2631 uid = mapUid(uid); 2632 Uid u = mUidStats.get(uid); 2633 if (u != null) { 2634 u.mPids.remove(pid); 2635 } 2636 } 2637 2638 public long getProcessWakeTime(int uid, int pid, long realtime) { 2639 uid = mapUid(uid); 2640 Uid u = mUidStats.get(uid); 2641 if (u != null) { 2642 Uid.Pid p = u.mPids.get(pid); 2643 if (p != null) { 2644 return p.mWakeSumMs + (p.mWakeNesting > 0 ? (realtime - p.mWakeStartMs) : 0); 2645 } 2646 } 2647 return 0; 2648 } 2649 2650 public void reportExcessiveWakeLocked(int uid, String proc, long overTime, long usedTime) { 2651 uid = mapUid(uid); 2652 Uid u = mUidStats.get(uid); 2653 if (u != null) { 2654 u.reportExcessiveWakeLocked(proc, overTime, usedTime); 2655 } 2656 } 2657 2658 public void reportExcessiveCpuLocked(int uid, String proc, long overTime, long usedTime) { 2659 uid = mapUid(uid); 2660 Uid u = mUidStats.get(uid); 2661 if (u != null) { 2662 u.reportExcessiveCpuLocked(proc, overTime, usedTime); 2663 } 2664 } 2665 2666 int mSensorNesting; 2667 2668 public void noteStartSensorLocked(int uid, int sensor) { 2669 uid = mapUid(uid); 2670 final long elapsedRealtime = SystemClock.elapsedRealtime(); 2671 final long uptime = SystemClock.uptimeMillis(); 2672 if (mSensorNesting == 0) { 2673 mHistoryCur.states |= HistoryItem.STATE_SENSOR_ON_FLAG; 2674 if (DEBUG_HISTORY) Slog.v(TAG, "Start sensor to: " 2675 + Integer.toHexString(mHistoryCur.states)); 2676 addHistoryRecordLocked(elapsedRealtime, uptime); 2677 } 2678 mSensorNesting++; 2679 getUidStatsLocked(uid).noteStartSensor(sensor, elapsedRealtime); 2680 } 2681 2682 public void noteStopSensorLocked(int uid, int sensor) { 2683 uid = mapUid(uid); 2684 final long elapsedRealtime = SystemClock.elapsedRealtime(); 2685 final long uptime = SystemClock.uptimeMillis(); 2686 mSensorNesting--; 2687 if (mSensorNesting == 0) { 2688 mHistoryCur.states &= ~HistoryItem.STATE_SENSOR_ON_FLAG; 2689 if (DEBUG_HISTORY) Slog.v(TAG, "Stop sensor to: " 2690 + Integer.toHexString(mHistoryCur.states)); 2691 addHistoryRecordLocked(elapsedRealtime, uptime); 2692 } 2693 getUidStatsLocked(uid).noteStopSensor(sensor, elapsedRealtime); 2694 } 2695 2696 int mGpsNesting; 2697 2698 public void noteStartGpsLocked(int uid) { 2699 uid = mapUid(uid); 2700 final long elapsedRealtime = SystemClock.elapsedRealtime(); 2701 final long uptime = SystemClock.uptimeMillis(); 2702 if (mGpsNesting == 0) { 2703 mHistoryCur.states |= HistoryItem.STATE_GPS_ON_FLAG; 2704 if (DEBUG_HISTORY) Slog.v(TAG, "Start GPS to: " 2705 + Integer.toHexString(mHistoryCur.states)); 2706 addHistoryRecordLocked(elapsedRealtime, uptime); 2707 } 2708 mGpsNesting++; 2709 getUidStatsLocked(uid).noteStartGps(elapsedRealtime); 2710 } 2711 2712 public void noteStopGpsLocked(int uid) { 2713 uid = mapUid(uid); 2714 final long elapsedRealtime = SystemClock.elapsedRealtime(); 2715 final long uptime = SystemClock.uptimeMillis(); 2716 mGpsNesting--; 2717 if (mGpsNesting == 0) { 2718 mHistoryCur.states &= ~HistoryItem.STATE_GPS_ON_FLAG; 2719 if (DEBUG_HISTORY) Slog.v(TAG, "Stop GPS to: " 2720 + Integer.toHexString(mHistoryCur.states)); 2721 addHistoryRecordLocked(elapsedRealtime, uptime); 2722 } 2723 getUidStatsLocked(uid).noteStopGps(elapsedRealtime); 2724 } 2725 2726 public void noteScreenStateLocked(int state) { 2727 if (mScreenState != state) { 2728 final int oldState = mScreenState; 2729 mScreenState = state; 2730 if (DEBUG) Slog.v(TAG, "Screen state: oldState=" + Display.stateToString(oldState) 2731 + ", newState=" + Display.stateToString(state)); 2732 2733 if (state == Display.STATE_ON) { 2734 // Screen turning on. 2735 final long elapsedRealtime = SystemClock.elapsedRealtime(); 2736 final long uptime = SystemClock.uptimeMillis(); 2737 mHistoryCur.states |= HistoryItem.STATE_SCREEN_ON_FLAG; 2738 if (DEBUG_HISTORY) Slog.v(TAG, "Screen on to: " 2739 + Integer.toHexString(mHistoryCur.states)); 2740 addHistoryRecordLocked(elapsedRealtime, uptime); 2741 mScreenOnTimer.startRunningLocked(elapsedRealtime); 2742 if (mScreenBrightnessBin >= 0) { 2743 mScreenBrightnessTimer[mScreenBrightnessBin].startRunningLocked(elapsedRealtime); 2744 } 2745 2746 updateTimeBasesLocked(mOnBatteryTimeBase.isRunning(), false, 2747 SystemClock.uptimeMillis() * 1000, elapsedRealtime * 1000); 2748 2749 // Fake a wake lock, so we consider the device waked as long 2750 // as the screen is on. 2751 noteStartWakeLocked(-1, -1, "screen", null, WAKE_TYPE_PARTIAL, false, 2752 elapsedRealtime, uptime); 2753 2754 // Update discharge amounts. 2755 if (mOnBatteryInternal) { 2756 updateDischargeScreenLevelsLocked(false, true); 2757 } 2758 } else if (oldState == Display.STATE_ON) { 2759 // Screen turning off or dozing. 2760 final long elapsedRealtime = SystemClock.elapsedRealtime(); 2761 final long uptime = SystemClock.uptimeMillis(); 2762 mHistoryCur.states &= ~HistoryItem.STATE_SCREEN_ON_FLAG; 2763 if (DEBUG_HISTORY) Slog.v(TAG, "Screen off to: " 2764 + Integer.toHexString(mHistoryCur.states)); 2765 addHistoryRecordLocked(elapsedRealtime, uptime); 2766 mScreenOnTimer.stopRunningLocked(elapsedRealtime); 2767 if (mScreenBrightnessBin >= 0) { 2768 mScreenBrightnessTimer[mScreenBrightnessBin].stopRunningLocked(elapsedRealtime); 2769 } 2770 2771 noteStopWakeLocked(-1, -1, "screen", "screen", WAKE_TYPE_PARTIAL, 2772 elapsedRealtime, uptime); 2773 2774 updateTimeBasesLocked(mOnBatteryTimeBase.isRunning(), true, 2775 SystemClock.uptimeMillis() * 1000, elapsedRealtime * 1000); 2776 2777 // Update discharge amounts. 2778 if (mOnBatteryInternal) { 2779 updateDischargeScreenLevelsLocked(true, false); 2780 } 2781 } 2782 } 2783 } 2784 2785 public void noteScreenBrightnessLocked(int brightness) { 2786 // Bin the brightness. 2787 int bin = brightness / (256/NUM_SCREEN_BRIGHTNESS_BINS); 2788 if (bin < 0) bin = 0; 2789 else if (bin >= NUM_SCREEN_BRIGHTNESS_BINS) bin = NUM_SCREEN_BRIGHTNESS_BINS-1; 2790 if (mScreenBrightnessBin != bin) { 2791 final long elapsedRealtime = SystemClock.elapsedRealtime(); 2792 final long uptime = SystemClock.uptimeMillis(); 2793 mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_BRIGHTNESS_MASK) 2794 | (bin << HistoryItem.STATE_BRIGHTNESS_SHIFT); 2795 if (DEBUG_HISTORY) Slog.v(TAG, "Screen brightness " + bin + " to: " 2796 + Integer.toHexString(mHistoryCur.states)); 2797 addHistoryRecordLocked(elapsedRealtime, uptime); 2798 if (mScreenState == Display.STATE_ON) { 2799 if (mScreenBrightnessBin >= 0) { 2800 mScreenBrightnessTimer[mScreenBrightnessBin].stopRunningLocked(elapsedRealtime); 2801 } 2802 mScreenBrightnessTimer[bin].startRunningLocked(elapsedRealtime); 2803 } 2804 mScreenBrightnessBin = bin; 2805 } 2806 } 2807 2808 public void noteUserActivityLocked(int uid, int event) { 2809 if (mOnBatteryInternal) { 2810 uid = mapUid(uid); 2811 getUidStatsLocked(uid).noteUserActivityLocked(event); 2812 } 2813 } 2814 2815 public void noteInteractiveLocked(boolean interactive) { 2816 if (mInteractive != interactive) { 2817 final long elapsedRealtime = SystemClock.elapsedRealtime(); 2818 mInteractive = interactive; 2819 if (DEBUG) Slog.v(TAG, "Interactive: " + interactive); 2820 if (interactive) { 2821 mInteractiveTimer.startRunningLocked(elapsedRealtime); 2822 } else { 2823 mInteractiveTimer.stopRunningLocked(elapsedRealtime); 2824 } 2825 } 2826 } 2827 2828 public void noteMobileRadioPowerState(int powerState, long timestampNs) { 2829 final long elapsedRealtime = SystemClock.elapsedRealtime(); 2830 final long uptime = SystemClock.uptimeMillis(); 2831 if (mMobileRadioPowerState != powerState) { 2832 long realElapsedRealtimeMs; 2833 final boolean active = 2834 powerState == DataConnectionRealTimeInfo.DC_POWER_STATE_MEDIUM 2835 || powerState == DataConnectionRealTimeInfo.DC_POWER_STATE_HIGH; 2836 if (active) { 2837 mMobileRadioActiveStartTime = realElapsedRealtimeMs = elapsedRealtime; 2838 mHistoryCur.states |= HistoryItem.STATE_MOBILE_RADIO_ACTIVE_FLAG; 2839 } else { 2840 realElapsedRealtimeMs = timestampNs / (1000*1000); 2841 long lastUpdateTimeMs = mMobileRadioActiveStartTime; 2842 if (realElapsedRealtimeMs < lastUpdateTimeMs) { 2843 Slog.wtf(TAG, "Data connection inactive timestamp " + realElapsedRealtimeMs 2844 + " is before start time " + lastUpdateTimeMs); 2845 realElapsedRealtimeMs = elapsedRealtime; 2846 } else if (realElapsedRealtimeMs < elapsedRealtime) { 2847 mMobileRadioActiveAdjustedTime.addCountLocked(elapsedRealtime 2848 - realElapsedRealtimeMs); 2849 } 2850 mHistoryCur.states &= ~HistoryItem.STATE_MOBILE_RADIO_ACTIVE_FLAG; 2851 } 2852 if (DEBUG_HISTORY) Slog.v(TAG, "Mobile network active " + active + " to: " 2853 + Integer.toHexString(mHistoryCur.states)); 2854 addHistoryRecordLocked(elapsedRealtime, uptime); 2855 mMobileRadioPowerState = powerState; 2856 if (active) { 2857 mMobileRadioActiveTimer.startRunningLocked(elapsedRealtime); 2858 mMobileRadioActivePerAppTimer.startRunningLocked(elapsedRealtime); 2859 } else { 2860 mMobileRadioActiveTimer.stopRunningLocked(realElapsedRealtimeMs); 2861 updateNetworkActivityLocked(NET_UPDATE_MOBILE, realElapsedRealtimeMs); 2862 mMobileRadioActivePerAppTimer.stopRunningLocked(realElapsedRealtimeMs); 2863 } 2864 } 2865 } 2866 2867 public void noteLowPowerMode(boolean enabled) { 2868 if (mLowPowerModeEnabled != enabled) { 2869 final long elapsedRealtime = SystemClock.elapsedRealtime(); 2870 final long uptime = SystemClock.uptimeMillis(); 2871 mLowPowerModeEnabled = enabled; 2872 if (enabled) { 2873 mHistoryCur.states2 |= HistoryItem.STATE2_LOW_POWER_FLAG; 2874 if (DEBUG_HISTORY) Slog.v(TAG, "Low power mode enabled to: " 2875 + Integer.toHexString(mHistoryCur.states2)); 2876 mLowPowerModeEnabledTimer.startRunningLocked(elapsedRealtime); 2877 } else { 2878 mHistoryCur.states2 &= ~HistoryItem.STATE2_LOW_POWER_FLAG; 2879 if (DEBUG_HISTORY) Slog.v(TAG, "Low power mode disabled to: " 2880 + Integer.toHexString(mHistoryCur.states2)); 2881 mLowPowerModeEnabledTimer.stopRunningLocked(elapsedRealtime); 2882 } 2883 addHistoryRecordLocked(elapsedRealtime, uptime); 2884 } 2885 } 2886 2887 public void notePhoneOnLocked() { 2888 if (!mPhoneOn) { 2889 final long elapsedRealtime = SystemClock.elapsedRealtime(); 2890 final long uptime = SystemClock.uptimeMillis(); 2891 mHistoryCur.states |= HistoryItem.STATE_PHONE_IN_CALL_FLAG; 2892 if (DEBUG_HISTORY) Slog.v(TAG, "Phone on to: " 2893 + Integer.toHexString(mHistoryCur.states)); 2894 addHistoryRecordLocked(elapsedRealtime, uptime); 2895 mPhoneOn = true; 2896 mPhoneOnTimer.startRunningLocked(elapsedRealtime); 2897 } 2898 } 2899 2900 public void notePhoneOffLocked() { 2901 if (mPhoneOn) { 2902 final long elapsedRealtime = SystemClock.elapsedRealtime(); 2903 final long uptime = SystemClock.uptimeMillis(); 2904 mHistoryCur.states &= ~HistoryItem.STATE_PHONE_IN_CALL_FLAG; 2905 if (DEBUG_HISTORY) Slog.v(TAG, "Phone off to: " 2906 + Integer.toHexString(mHistoryCur.states)); 2907 addHistoryRecordLocked(elapsedRealtime, uptime); 2908 mPhoneOn = false; 2909 mPhoneOnTimer.stopRunningLocked(elapsedRealtime); 2910 } 2911 } 2912 2913 void stopAllPhoneSignalStrengthTimersLocked(int except) { 2914 final long elapsedRealtime = SystemClock.elapsedRealtime(); 2915 for (int i = 0; i < SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) { 2916 if (i == except) { 2917 continue; 2918 } 2919 while (mPhoneSignalStrengthsTimer[i].isRunningLocked()) { 2920 mPhoneSignalStrengthsTimer[i].stopRunningLocked(elapsedRealtime); 2921 } 2922 } 2923 } 2924 2925 private int fixPhoneServiceState(int state, int signalBin) { 2926 if (mPhoneSimStateRaw == TelephonyManager.SIM_STATE_ABSENT) { 2927 // In this case we will always be STATE_OUT_OF_SERVICE, so need 2928 // to infer that we are scanning from other data. 2929 if (state == ServiceState.STATE_OUT_OF_SERVICE 2930 && signalBin > SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN) { 2931 state = ServiceState.STATE_IN_SERVICE; 2932 } 2933 } 2934 2935 return state; 2936 } 2937 2938 private void updateAllPhoneStateLocked(int state, int simState, int strengthBin) { 2939 boolean scanning = false; 2940 boolean newHistory = false; 2941 2942 mPhoneServiceStateRaw = state; 2943 mPhoneSimStateRaw = simState; 2944 mPhoneSignalStrengthBinRaw = strengthBin; 2945 2946 final long elapsedRealtime = SystemClock.elapsedRealtime(); 2947 final long uptime = SystemClock.uptimeMillis(); 2948 2949 if (simState == TelephonyManager.SIM_STATE_ABSENT) { 2950 // In this case we will always be STATE_OUT_OF_SERVICE, so need 2951 // to infer that we are scanning from other data. 2952 if (state == ServiceState.STATE_OUT_OF_SERVICE 2953 && strengthBin > SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN) { 2954 state = ServiceState.STATE_IN_SERVICE; 2955 } 2956 } 2957 2958 // If the phone is powered off, stop all timers. 2959 if (state == ServiceState.STATE_POWER_OFF) { 2960 strengthBin = -1; 2961 2962 // If we are in service, make sure the correct signal string timer is running. 2963 } else if (state == ServiceState.STATE_IN_SERVICE) { 2964 // Bin will be changed below. 2965 2966 // If we're out of service, we are in the lowest signal strength 2967 // bin and have the scanning bit set. 2968 } else if (state == ServiceState.STATE_OUT_OF_SERVICE) { 2969 scanning = true; 2970 strengthBin = SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN; 2971 if (!mPhoneSignalScanningTimer.isRunningLocked()) { 2972 mHistoryCur.states |= HistoryItem.STATE_PHONE_SCANNING_FLAG; 2973 newHistory = true; 2974 if (DEBUG_HISTORY) Slog.v(TAG, "Phone started scanning to: " 2975 + Integer.toHexString(mHistoryCur.states)); 2976 mPhoneSignalScanningTimer.startRunningLocked(elapsedRealtime); 2977 } 2978 } 2979 2980 if (!scanning) { 2981 // If we are no longer scanning, then stop the scanning timer. 2982 if (mPhoneSignalScanningTimer.isRunningLocked()) { 2983 mHistoryCur.states &= ~HistoryItem.STATE_PHONE_SCANNING_FLAG; 2984 if (DEBUG_HISTORY) Slog.v(TAG, "Phone stopped scanning to: " 2985 + Integer.toHexString(mHistoryCur.states)); 2986 newHistory = true; 2987 mPhoneSignalScanningTimer.stopRunningLocked(elapsedRealtime); 2988 } 2989 } 2990 2991 if (mPhoneServiceState != state) { 2992 mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_PHONE_STATE_MASK) 2993 | (state << HistoryItem.STATE_PHONE_STATE_SHIFT); 2994 if (DEBUG_HISTORY) Slog.v(TAG, "Phone state " + state + " to: " 2995 + Integer.toHexString(mHistoryCur.states)); 2996 newHistory = true; 2997 mPhoneServiceState = state; 2998 } 2999 3000 if (mPhoneSignalStrengthBin != strengthBin) { 3001 if (mPhoneSignalStrengthBin >= 0) { 3002 mPhoneSignalStrengthsTimer[mPhoneSignalStrengthBin].stopRunningLocked( 3003 elapsedRealtime); 3004 } 3005 if (strengthBin >= 0) { 3006 if (!mPhoneSignalStrengthsTimer[strengthBin].isRunningLocked()) { 3007 mPhoneSignalStrengthsTimer[strengthBin].startRunningLocked(elapsedRealtime); 3008 } 3009 mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_PHONE_SIGNAL_STRENGTH_MASK) 3010 | (strengthBin << HistoryItem.STATE_PHONE_SIGNAL_STRENGTH_SHIFT); 3011 if (DEBUG_HISTORY) Slog.v(TAG, "Signal strength " + strengthBin + " to: " 3012 + Integer.toHexString(mHistoryCur.states)); 3013 newHistory = true; 3014 } else { 3015 stopAllPhoneSignalStrengthTimersLocked(-1); 3016 } 3017 mPhoneSignalStrengthBin = strengthBin; 3018 } 3019 3020 if (newHistory) { 3021 addHistoryRecordLocked(elapsedRealtime, uptime); 3022 } 3023 } 3024 3025 /** 3026 * Telephony stack updates the phone state. 3027 * @param state phone state from ServiceState.getState() 3028 */ 3029 public void notePhoneStateLocked(int state, int simState) { 3030 updateAllPhoneStateLocked(state, simState, mPhoneSignalStrengthBinRaw); 3031 } 3032 3033 public void notePhoneSignalStrengthLocked(SignalStrength signalStrength) { 3034 // Bin the strength. 3035 int bin = signalStrength.getLevel(); 3036 updateAllPhoneStateLocked(mPhoneServiceStateRaw, mPhoneSimStateRaw, bin); 3037 } 3038 3039 public void notePhoneDataConnectionStateLocked(int dataType, boolean hasData) { 3040 int bin = DATA_CONNECTION_NONE; 3041 if (hasData) { 3042 switch (dataType) { 3043 case TelephonyManager.NETWORK_TYPE_EDGE: 3044 bin = DATA_CONNECTION_EDGE; 3045 break; 3046 case TelephonyManager.NETWORK_TYPE_GPRS: 3047 bin = DATA_CONNECTION_GPRS; 3048 break; 3049 case TelephonyManager.NETWORK_TYPE_UMTS: 3050 bin = DATA_CONNECTION_UMTS; 3051 break; 3052 case TelephonyManager.NETWORK_TYPE_CDMA: 3053 bin = DATA_CONNECTION_CDMA; 3054 break; 3055 case TelephonyManager.NETWORK_TYPE_EVDO_0: 3056 bin = DATA_CONNECTION_EVDO_0; 3057 break; 3058 case TelephonyManager.NETWORK_TYPE_EVDO_A: 3059 bin = DATA_CONNECTION_EVDO_A; 3060 break; 3061 case TelephonyManager.NETWORK_TYPE_1xRTT: 3062 bin = DATA_CONNECTION_1xRTT; 3063 break; 3064 case TelephonyManager.NETWORK_TYPE_HSDPA: 3065 bin = DATA_CONNECTION_HSDPA; 3066 break; 3067 case TelephonyManager.NETWORK_TYPE_HSUPA: 3068 bin = DATA_CONNECTION_HSUPA; 3069 break; 3070 case TelephonyManager.NETWORK_TYPE_HSPA: 3071 bin = DATA_CONNECTION_HSPA; 3072 break; 3073 case TelephonyManager.NETWORK_TYPE_IDEN: 3074 bin = DATA_CONNECTION_IDEN; 3075 break; 3076 case TelephonyManager.NETWORK_TYPE_EVDO_B: 3077 bin = DATA_CONNECTION_EVDO_B; 3078 break; 3079 case TelephonyManager.NETWORK_TYPE_LTE: 3080 bin = DATA_CONNECTION_LTE; 3081 break; 3082 case TelephonyManager.NETWORK_TYPE_EHRPD: 3083 bin = DATA_CONNECTION_EHRPD; 3084 break; 3085 case TelephonyManager.NETWORK_TYPE_HSPAP: 3086 bin = DATA_CONNECTION_HSPAP; 3087 break; 3088 default: 3089 bin = DATA_CONNECTION_OTHER; 3090 break; 3091 } 3092 } 3093 if (DEBUG) Log.i(TAG, "Phone Data Connection -> " + dataType + " = " + hasData); 3094 if (mPhoneDataConnectionType != bin) { 3095 final long elapsedRealtime = SystemClock.elapsedRealtime(); 3096 final long uptime = SystemClock.uptimeMillis(); 3097 mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_DATA_CONNECTION_MASK) 3098 | (bin << HistoryItem.STATE_DATA_CONNECTION_SHIFT); 3099 if (DEBUG_HISTORY) Slog.v(TAG, "Data connection " + bin + " to: " 3100 + Integer.toHexString(mHistoryCur.states)); 3101 addHistoryRecordLocked(elapsedRealtime, uptime); 3102 if (mPhoneDataConnectionType >= 0) { 3103 mPhoneDataConnectionsTimer[mPhoneDataConnectionType].stopRunningLocked( 3104 elapsedRealtime); 3105 } 3106 mPhoneDataConnectionType = bin; 3107 mPhoneDataConnectionsTimer[bin].startRunningLocked(elapsedRealtime); 3108 } 3109 } 3110 3111 public void noteWifiOnLocked() { 3112 if (!mWifiOn) { 3113 final long elapsedRealtime = SystemClock.elapsedRealtime(); 3114 final long uptime = SystemClock.uptimeMillis(); 3115 mHistoryCur.states2 |= HistoryItem.STATE2_WIFI_ON_FLAG; 3116 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI on to: " 3117 + Integer.toHexString(mHistoryCur.states)); 3118 addHistoryRecordLocked(elapsedRealtime, uptime); 3119 mWifiOn = true; 3120 mWifiOnTimer.startRunningLocked(elapsedRealtime); 3121 } 3122 } 3123 3124 public void noteWifiOffLocked() { 3125 final long elapsedRealtime = SystemClock.elapsedRealtime(); 3126 final long uptime = SystemClock.uptimeMillis(); 3127 if (mWifiOn) { 3128 mHistoryCur.states2 &= ~HistoryItem.STATE2_WIFI_ON_FLAG; 3129 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI off to: " 3130 + Integer.toHexString(mHistoryCur.states)); 3131 addHistoryRecordLocked(elapsedRealtime, uptime); 3132 mWifiOn = false; 3133 mWifiOnTimer.stopRunningLocked(elapsedRealtime); 3134 } 3135 } 3136 3137 public void noteAudioOnLocked(int uid) { 3138 uid = mapUid(uid); 3139 final long elapsedRealtime = SystemClock.elapsedRealtime(); 3140 final long uptime = SystemClock.uptimeMillis(); 3141 if (!mAudioOn) { 3142 mHistoryCur.states |= HistoryItem.STATE_AUDIO_ON_FLAG; 3143 if (DEBUG_HISTORY) Slog.v(TAG, "Audio on to: " 3144 + Integer.toHexString(mHistoryCur.states)); 3145 addHistoryRecordLocked(elapsedRealtime, uptime); 3146 mAudioOn = true; 3147 mAudioOnTimer.startRunningLocked(elapsedRealtime); 3148 } 3149 getUidStatsLocked(uid).noteAudioTurnedOnLocked(elapsedRealtime); 3150 } 3151 3152 public void noteAudioOffLocked(int uid) { 3153 uid = mapUid(uid); 3154 final long elapsedRealtime = SystemClock.elapsedRealtime(); 3155 final long uptime = SystemClock.uptimeMillis(); 3156 if (mAudioOn) { 3157 mHistoryCur.states &= ~HistoryItem.STATE_AUDIO_ON_FLAG; 3158 if (DEBUG_HISTORY) Slog.v(TAG, "Audio off to: " 3159 + Integer.toHexString(mHistoryCur.states)); 3160 addHistoryRecordLocked(elapsedRealtime, uptime); 3161 mAudioOn = false; 3162 mAudioOnTimer.stopRunningLocked(elapsedRealtime); 3163 } 3164 getUidStatsLocked(uid).noteAudioTurnedOffLocked(elapsedRealtime); 3165 } 3166 3167 public void noteVideoOnLocked(int uid) { 3168 uid = mapUid(uid); 3169 final long elapsedRealtime = SystemClock.elapsedRealtime(); 3170 final long uptime = SystemClock.uptimeMillis(); 3171 if (!mVideoOn) { 3172 mHistoryCur.states2 |= HistoryItem.STATE2_VIDEO_ON_FLAG; 3173 if (DEBUG_HISTORY) Slog.v(TAG, "Video on to: " 3174 + Integer.toHexString(mHistoryCur.states)); 3175 addHistoryRecordLocked(elapsedRealtime, uptime); 3176 mVideoOn = true; 3177 mVideoOnTimer.startRunningLocked(elapsedRealtime); 3178 } 3179 getUidStatsLocked(uid).noteVideoTurnedOnLocked(elapsedRealtime); 3180 } 3181 3182 public void noteVideoOffLocked(int uid) { 3183 uid = mapUid(uid); 3184 final long elapsedRealtime = SystemClock.elapsedRealtime(); 3185 final long uptime = SystemClock.uptimeMillis(); 3186 if (mVideoOn) { 3187 mHistoryCur.states2 &= ~HistoryItem.STATE2_VIDEO_ON_FLAG; 3188 if (DEBUG_HISTORY) Slog.v(TAG, "Video off to: " 3189 + Integer.toHexString(mHistoryCur.states)); 3190 addHistoryRecordLocked(elapsedRealtime, uptime); 3191 mVideoOn = false; 3192 mVideoOnTimer.stopRunningLocked(elapsedRealtime); 3193 } 3194 getUidStatsLocked(uid).noteVideoTurnedOffLocked(elapsedRealtime); 3195 } 3196 3197 public void noteActivityResumedLocked(int uid) { 3198 uid = mapUid(uid); 3199 getUidStatsLocked(uid).noteActivityResumedLocked(SystemClock.elapsedRealtime()); 3200 } 3201 3202 public void noteActivityPausedLocked(int uid) { 3203 uid = mapUid(uid); 3204 getUidStatsLocked(uid).noteActivityPausedLocked(SystemClock.elapsedRealtime()); 3205 } 3206 3207 public void noteVibratorOnLocked(int uid, long durationMillis) { 3208 uid = mapUid(uid); 3209 getUidStatsLocked(uid).noteVibratorOnLocked(durationMillis); 3210 } 3211 3212 public void noteVibratorOffLocked(int uid) { 3213 uid = mapUid(uid); 3214 getUidStatsLocked(uid).noteVibratorOffLocked(); 3215 } 3216 3217 public void noteFlashlightOnLocked() { 3218 if (!mFlashlightOn) { 3219 final long elapsedRealtime = SystemClock.elapsedRealtime(); 3220 final long uptime = SystemClock.uptimeMillis(); 3221 mHistoryCur.states2 |= HistoryItem.STATE2_FLASHLIGHT_FLAG; 3222 if (DEBUG_HISTORY) Slog.v(TAG, "Flashlight on to: " 3223 + Integer.toHexString(mHistoryCur.states)); 3224 addHistoryRecordLocked(elapsedRealtime, uptime); 3225 mFlashlightOn = true; 3226 mFlashlightOnTimer.startRunningLocked(elapsedRealtime); 3227 } 3228 } 3229 3230 public void noteFlashlightOffLocked() { 3231 final long elapsedRealtime = SystemClock.elapsedRealtime(); 3232 final long uptime = SystemClock.uptimeMillis(); 3233 if (mFlashlightOn) { 3234 mHistoryCur.states2 &= ~HistoryItem.STATE2_FLASHLIGHT_FLAG; 3235 if (DEBUG_HISTORY) Slog.v(TAG, "Flashlight off to: " 3236 + Integer.toHexString(mHistoryCur.states)); 3237 addHistoryRecordLocked(elapsedRealtime, uptime); 3238 mFlashlightOn = false; 3239 mFlashlightOnTimer.stopRunningLocked(elapsedRealtime); 3240 } 3241 } 3242 3243 public void noteWifiRunningLocked(WorkSource ws) { 3244 if (!mGlobalWifiRunning) { 3245 final long elapsedRealtime = SystemClock.elapsedRealtime(); 3246 final long uptime = SystemClock.uptimeMillis(); 3247 mHistoryCur.states2 |= HistoryItem.STATE2_WIFI_RUNNING_FLAG; 3248 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI running to: " 3249 + Integer.toHexString(mHistoryCur.states)); 3250 addHistoryRecordLocked(elapsedRealtime, uptime); 3251 mGlobalWifiRunning = true; 3252 mGlobalWifiRunningTimer.startRunningLocked(elapsedRealtime); 3253 int N = ws.size(); 3254 for (int i=0; i<N; i++) { 3255 int uid = mapUid(ws.get(i)); 3256 getUidStatsLocked(uid).noteWifiRunningLocked(elapsedRealtime); 3257 } 3258 } else { 3259 Log.w(TAG, "noteWifiRunningLocked -- called while WIFI running"); 3260 } 3261 } 3262 3263 public void noteWifiRunningChangedLocked(WorkSource oldWs, WorkSource newWs) { 3264 if (mGlobalWifiRunning) { 3265 final long elapsedRealtime = SystemClock.elapsedRealtime(); 3266 int N = oldWs.size(); 3267 for (int i=0; i<N; i++) { 3268 int uid = mapUid(oldWs.get(i)); 3269 getUidStatsLocked(uid).noteWifiStoppedLocked(elapsedRealtime); 3270 } 3271 N = newWs.size(); 3272 for (int i=0; i<N; i++) { 3273 int uid = mapUid(newWs.get(i)); 3274 getUidStatsLocked(uid).noteWifiRunningLocked(elapsedRealtime); 3275 } 3276 } else { 3277 Log.w(TAG, "noteWifiRunningChangedLocked -- called while WIFI not running"); 3278 } 3279 } 3280 3281 public void noteWifiStoppedLocked(WorkSource ws) { 3282 if (mGlobalWifiRunning) { 3283 final long elapsedRealtime = SystemClock.elapsedRealtime(); 3284 final long uptime = SystemClock.uptimeMillis(); 3285 mHistoryCur.states2 &= ~HistoryItem.STATE2_WIFI_RUNNING_FLAG; 3286 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI stopped to: " 3287 + Integer.toHexString(mHistoryCur.states)); 3288 addHistoryRecordLocked(elapsedRealtime, uptime); 3289 mGlobalWifiRunning = false; 3290 mGlobalWifiRunningTimer.stopRunningLocked(elapsedRealtime); 3291 int N = ws.size(); 3292 for (int i=0; i<N; i++) { 3293 int uid = mapUid(ws.get(i)); 3294 getUidStatsLocked(uid).noteWifiStoppedLocked(elapsedRealtime); 3295 } 3296 } else { 3297 Log.w(TAG, "noteWifiStoppedLocked -- called while WIFI not running"); 3298 } 3299 } 3300 3301 public void noteWifiStateLocked(int wifiState, String accessPoint) { 3302 if (DEBUG) Log.i(TAG, "WiFi state -> " + wifiState); 3303 if (mWifiState != wifiState) { 3304 final long elapsedRealtime = SystemClock.elapsedRealtime(); 3305 if (mWifiState >= 0) { 3306 mWifiStateTimer[mWifiState].stopRunningLocked(elapsedRealtime); 3307 } 3308 mWifiState = wifiState; 3309 mWifiStateTimer[wifiState].startRunningLocked(elapsedRealtime); 3310 } 3311 } 3312 3313 public void noteWifiSupplicantStateChangedLocked(int supplState, boolean failedAuth) { 3314 if (DEBUG) Log.i(TAG, "WiFi suppl state -> " + supplState); 3315 if (mWifiSupplState != supplState) { 3316 final long elapsedRealtime = SystemClock.elapsedRealtime(); 3317 final long uptime = SystemClock.uptimeMillis(); 3318 if (mWifiSupplState >= 0) { 3319 mWifiSupplStateTimer[mWifiSupplState].stopRunningLocked(elapsedRealtime); 3320 } 3321 mWifiSupplState = supplState; 3322 mWifiSupplStateTimer[supplState].startRunningLocked(elapsedRealtime); 3323 mHistoryCur.states2 = 3324 (mHistoryCur.states2&~HistoryItem.STATE2_WIFI_SUPPL_STATE_MASK) 3325 | (supplState << HistoryItem.STATE2_WIFI_SUPPL_STATE_SHIFT); 3326 if (DEBUG_HISTORY) Slog.v(TAG, "Wifi suppl state " + supplState + " to: " 3327 + Integer.toHexString(mHistoryCur.states2)); 3328 addHistoryRecordLocked(elapsedRealtime, uptime); 3329 } 3330 } 3331 3332 void stopAllWifiSignalStrengthTimersLocked(int except) { 3333 final long elapsedRealtime = SystemClock.elapsedRealtime(); 3334 for (int i = 0; i < NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { 3335 if (i == except) { 3336 continue; 3337 } 3338 while (mWifiSignalStrengthsTimer[i].isRunningLocked()) { 3339 mWifiSignalStrengthsTimer[i].stopRunningLocked(elapsedRealtime); 3340 } 3341 } 3342 } 3343 3344 public void noteWifiRssiChangedLocked(int newRssi) { 3345 int strengthBin = WifiManager.calculateSignalLevel(newRssi, NUM_WIFI_SIGNAL_STRENGTH_BINS); 3346 if (DEBUG) Log.i(TAG, "WiFi rssi -> " + newRssi + " bin=" + strengthBin); 3347 if (mWifiSignalStrengthBin != strengthBin) { 3348 final long elapsedRealtime = SystemClock.elapsedRealtime(); 3349 final long uptime = SystemClock.uptimeMillis(); 3350 if (mWifiSignalStrengthBin >= 0) { 3351 mWifiSignalStrengthsTimer[mWifiSignalStrengthBin].stopRunningLocked( 3352 elapsedRealtime); 3353 } 3354 if (strengthBin >= 0) { 3355 if (!mWifiSignalStrengthsTimer[strengthBin].isRunningLocked()) { 3356 mWifiSignalStrengthsTimer[strengthBin].startRunningLocked(elapsedRealtime); 3357 } 3358 mHistoryCur.states2 = 3359 (mHistoryCur.states2&~HistoryItem.STATE2_WIFI_SIGNAL_STRENGTH_MASK) 3360 | (strengthBin << HistoryItem.STATE2_WIFI_SIGNAL_STRENGTH_SHIFT); 3361 if (DEBUG_HISTORY) Slog.v(TAG, "Wifi signal strength " + strengthBin + " to: " 3362 + Integer.toHexString(mHistoryCur.states2)); 3363 addHistoryRecordLocked(elapsedRealtime, uptime); 3364 } else { 3365 stopAllWifiSignalStrengthTimersLocked(-1); 3366 } 3367 mWifiSignalStrengthBin = strengthBin; 3368 } 3369 } 3370 3371 public void noteBluetoothOnLocked() { 3372 if (!mBluetoothOn) { 3373 final long elapsedRealtime = SystemClock.elapsedRealtime(); 3374 final long uptime = SystemClock.uptimeMillis(); 3375 mHistoryCur.states |= HistoryItem.STATE_BLUETOOTH_ON_FLAG; 3376 if (DEBUG_HISTORY) Slog.v(TAG, "Bluetooth on to: " 3377 + Integer.toHexString(mHistoryCur.states)); 3378 addHistoryRecordLocked(elapsedRealtime, uptime); 3379 mBluetoothOn = true; 3380 mBluetoothOnTimer.startRunningLocked(elapsedRealtime); 3381 } 3382 } 3383 3384 public void noteBluetoothOffLocked() { 3385 if (mBluetoothOn) { 3386 final long elapsedRealtime = SystemClock.elapsedRealtime(); 3387 final long uptime = SystemClock.uptimeMillis(); 3388 mHistoryCur.states &= ~HistoryItem.STATE_BLUETOOTH_ON_FLAG; 3389 if (DEBUG_HISTORY) Slog.v(TAG, "Bluetooth off to: " 3390 + Integer.toHexString(mHistoryCur.states)); 3391 addHistoryRecordLocked(elapsedRealtime, uptime); 3392 mBluetoothOn = false; 3393 mBluetoothOnTimer.stopRunningLocked(elapsedRealtime); 3394 } 3395 } 3396 3397 public void noteBluetoothStateLocked(int bluetoothState) { 3398 if (DEBUG) Log.i(TAG, "Bluetooth state -> " + bluetoothState); 3399 if (mBluetoothState != bluetoothState) { 3400 final long elapsedRealtime = SystemClock.elapsedRealtime(); 3401 if (mBluetoothState >= 0) { 3402 mBluetoothStateTimer[mBluetoothState].stopRunningLocked(elapsedRealtime); 3403 } 3404 mBluetoothState = bluetoothState; 3405 mBluetoothStateTimer[bluetoothState].startRunningLocked(elapsedRealtime); 3406 } 3407 } 3408 3409 int mWifiFullLockNesting = 0; 3410 3411 public void noteFullWifiLockAcquiredLocked(int uid) { 3412 uid = mapUid(uid); 3413 final long elapsedRealtime = SystemClock.elapsedRealtime(); 3414 final long uptime = SystemClock.uptimeMillis(); 3415 if (mWifiFullLockNesting == 0) { 3416 mHistoryCur.states |= HistoryItem.STATE_WIFI_FULL_LOCK_FLAG; 3417 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI full lock on to: " 3418 + Integer.toHexString(mHistoryCur.states)); 3419 addHistoryRecordLocked(elapsedRealtime, uptime); 3420 } 3421 mWifiFullLockNesting++; 3422 getUidStatsLocked(uid).noteFullWifiLockAcquiredLocked(elapsedRealtime); 3423 } 3424 3425 public void noteFullWifiLockReleasedLocked(int uid) { 3426 uid = mapUid(uid); 3427 final long elapsedRealtime = SystemClock.elapsedRealtime(); 3428 final long uptime = SystemClock.uptimeMillis(); 3429 mWifiFullLockNesting--; 3430 if (mWifiFullLockNesting == 0) { 3431 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_FULL_LOCK_FLAG; 3432 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI full lock off to: " 3433 + Integer.toHexString(mHistoryCur.states)); 3434 addHistoryRecordLocked(elapsedRealtime, uptime); 3435 } 3436 getUidStatsLocked(uid).noteFullWifiLockReleasedLocked(elapsedRealtime); 3437 } 3438 3439 int mWifiScanNesting = 0; 3440 3441 public void noteWifiScanStartedLocked(int uid) { 3442 uid = mapUid(uid); 3443 final long elapsedRealtime = SystemClock.elapsedRealtime(); 3444 final long uptime = SystemClock.uptimeMillis(); 3445 if (mWifiScanNesting == 0) { 3446 mHistoryCur.states |= HistoryItem.STATE_WIFI_SCAN_FLAG; 3447 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI scan started for: " 3448 + Integer.toHexString(mHistoryCur.states)); 3449 addHistoryRecordLocked(elapsedRealtime, uptime); 3450 } 3451 mWifiScanNesting++; 3452 getUidStatsLocked(uid).noteWifiScanStartedLocked(elapsedRealtime); 3453 } 3454 3455 public void noteWifiScanStoppedLocked(int uid) { 3456 uid = mapUid(uid); 3457 final long elapsedRealtime = SystemClock.elapsedRealtime(); 3458 final long uptime = SystemClock.uptimeMillis(); 3459 mWifiScanNesting--; 3460 if (mWifiScanNesting == 0) { 3461 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_SCAN_FLAG; 3462 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI scan stopped for: " 3463 + Integer.toHexString(mHistoryCur.states)); 3464 addHistoryRecordLocked(elapsedRealtime, uptime); 3465 } 3466 getUidStatsLocked(uid).noteWifiScanStoppedLocked(elapsedRealtime); 3467 } 3468 3469 public void noteWifiBatchedScanStartedLocked(int uid, int csph) { 3470 uid = mapUid(uid); 3471 final long elapsedRealtime = SystemClock.elapsedRealtime(); 3472 getUidStatsLocked(uid).noteWifiBatchedScanStartedLocked(csph, elapsedRealtime); 3473 } 3474 3475 public void noteWifiBatchedScanStoppedLocked(int uid) { 3476 uid = mapUid(uid); 3477 final long elapsedRealtime = SystemClock.elapsedRealtime(); 3478 getUidStatsLocked(uid).noteWifiBatchedScanStoppedLocked(elapsedRealtime); 3479 } 3480 3481 int mWifiMulticastNesting = 0; 3482 3483 public void noteWifiMulticastEnabledLocked(int uid) { 3484 uid = mapUid(uid); 3485 final long elapsedRealtime = SystemClock.elapsedRealtime(); 3486 final long uptime = SystemClock.uptimeMillis(); 3487 if (mWifiMulticastNesting == 0) { 3488 mHistoryCur.states |= HistoryItem.STATE_WIFI_MULTICAST_ON_FLAG; 3489 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI multicast on to: " 3490 + Integer.toHexString(mHistoryCur.states)); 3491 addHistoryRecordLocked(elapsedRealtime, uptime); 3492 } 3493 mWifiMulticastNesting++; 3494 getUidStatsLocked(uid).noteWifiMulticastEnabledLocked(elapsedRealtime); 3495 } 3496 3497 public void noteWifiMulticastDisabledLocked(int uid) { 3498 uid = mapUid(uid); 3499 final long elapsedRealtime = SystemClock.elapsedRealtime(); 3500 final long uptime = SystemClock.uptimeMillis(); 3501 mWifiMulticastNesting--; 3502 if (mWifiMulticastNesting == 0) { 3503 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_MULTICAST_ON_FLAG; 3504 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI multicast off to: " 3505 + Integer.toHexString(mHistoryCur.states)); 3506 addHistoryRecordLocked(elapsedRealtime, uptime); 3507 } 3508 getUidStatsLocked(uid).noteWifiMulticastDisabledLocked(elapsedRealtime); 3509 } 3510 3511 public void noteFullWifiLockAcquiredFromSourceLocked(WorkSource ws) { 3512 int N = ws.size(); 3513 for (int i=0; i<N; i++) { 3514 noteFullWifiLockAcquiredLocked(ws.get(i)); 3515 } 3516 } 3517 3518 public void noteFullWifiLockReleasedFromSourceLocked(WorkSource ws) { 3519 int N = ws.size(); 3520 for (int i=0; i<N; i++) { 3521 noteFullWifiLockReleasedLocked(ws.get(i)); 3522 } 3523 } 3524 3525 public void noteWifiScanStartedFromSourceLocked(WorkSource ws) { 3526 int N = ws.size(); 3527 for (int i=0; i<N; i++) { 3528 noteWifiScanStartedLocked(ws.get(i)); 3529 } 3530 } 3531 3532 public void noteWifiScanStoppedFromSourceLocked(WorkSource ws) { 3533 int N = ws.size(); 3534 for (int i=0; i<N; i++) { 3535 noteWifiScanStoppedLocked(ws.get(i)); 3536 } 3537 } 3538 3539 public void noteWifiBatchedScanStartedFromSourceLocked(WorkSource ws, int csph) { 3540 int N = ws.size(); 3541 for (int i=0; i<N; i++) { 3542 noteWifiBatchedScanStartedLocked(ws.get(i), csph); 3543 } 3544 } 3545 3546 public void noteWifiBatchedScanStoppedFromSourceLocked(WorkSource ws) { 3547 int N = ws.size(); 3548 for (int i=0; i<N; i++) { 3549 noteWifiBatchedScanStoppedLocked(ws.get(i)); 3550 } 3551 } 3552 3553 public void noteWifiMulticastEnabledFromSourceLocked(WorkSource ws) { 3554 int N = ws.size(); 3555 for (int i=0; i<N; i++) { 3556 noteWifiMulticastEnabledLocked(ws.get(i)); 3557 } 3558 } 3559 3560 public void noteWifiMulticastDisabledFromSourceLocked(WorkSource ws) { 3561 int N = ws.size(); 3562 for (int i=0; i<N; i++) { 3563 noteWifiMulticastDisabledLocked(ws.get(i)); 3564 } 3565 } 3566 3567 private static String[] includeInStringArray(String[] array, String str) { 3568 if (ArrayUtils.indexOf(array, str) >= 0) { 3569 return array; 3570 } 3571 String[] newArray = new String[array.length+1]; 3572 System.arraycopy(array, 0, newArray, 0, array.length); 3573 newArray[array.length] = str; 3574 return newArray; 3575 } 3576 3577 private static String[] excludeFromStringArray(String[] array, String str) { 3578 int index = ArrayUtils.indexOf(array, str); 3579 if (index >= 0) { 3580 String[] newArray = new String[array.length-1]; 3581 if (index > 0) { 3582 System.arraycopy(array, 0, newArray, 0, index); 3583 } 3584 if (index < array.length-1) { 3585 System.arraycopy(array, index+1, newArray, index, array.length-index-1); 3586 } 3587 return newArray; 3588 } 3589 return array; 3590 } 3591 3592 public void noteNetworkInterfaceTypeLocked(String iface, int networkType) { 3593 if (ConnectivityManager.isNetworkTypeMobile(networkType)) { 3594 mMobileIfaces = includeInStringArray(mMobileIfaces, iface); 3595 if (DEBUG) Slog.d(TAG, "Note mobile iface " + iface + ": " + mMobileIfaces); 3596 } else { 3597 mMobileIfaces = excludeFromStringArray(mMobileIfaces, iface); 3598 if (DEBUG) Slog.d(TAG, "Note non-mobile iface " + iface + ": " + mMobileIfaces); 3599 } 3600 if (ConnectivityManager.isNetworkTypeWifi(networkType)) { 3601 mWifiIfaces = includeInStringArray(mWifiIfaces, iface); 3602 if (DEBUG) Slog.d(TAG, "Note wifi iface " + iface + ": " + mWifiIfaces); 3603 } else { 3604 mWifiIfaces = excludeFromStringArray(mWifiIfaces, iface); 3605 if (DEBUG) Slog.d(TAG, "Note non-wifi iface " + iface + ": " + mWifiIfaces); 3606 } 3607 } 3608 3609 public void noteNetworkStatsEnabledLocked() { 3610 // During device boot, qtaguid isn't enabled until after the inital 3611 // loading of battery stats. Now that they're enabled, take our initial 3612 // snapshot for future delta calculation. 3613 updateNetworkActivityLocked(NET_UPDATE_ALL, SystemClock.elapsedRealtime()); 3614 } 3615 3616 @Override public long getScreenOnTime(long elapsedRealtimeUs, int which) { 3617 return mScreenOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 3618 } 3619 3620 @Override public int getScreenOnCount(int which) { 3621 return mScreenOnTimer.getCountLocked(which); 3622 } 3623 3624 @Override public long getScreenBrightnessTime(int brightnessBin, 3625 long elapsedRealtimeUs, int which) { 3626 return mScreenBrightnessTimer[brightnessBin].getTotalTimeLocked( 3627 elapsedRealtimeUs, which); 3628 } 3629 3630 @Override public long getInteractiveTime(long elapsedRealtimeUs, int which) { 3631 return mInteractiveTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 3632 } 3633 3634 @Override public long getLowPowerModeEnabledTime(long elapsedRealtimeUs, int which) { 3635 return mLowPowerModeEnabledTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 3636 } 3637 3638 @Override public int getLowPowerModeEnabledCount(int which) { 3639 return mLowPowerModeEnabledTimer.getCountLocked(which); 3640 } 3641 3642 @Override public long getPhoneOnTime(long elapsedRealtimeUs, int which) { 3643 return mPhoneOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 3644 } 3645 3646 @Override public int getPhoneOnCount(int which) { 3647 return mPhoneOnTimer.getCountLocked(which); 3648 } 3649 3650 @Override public long getPhoneSignalStrengthTime(int strengthBin, 3651 long elapsedRealtimeUs, int which) { 3652 return mPhoneSignalStrengthsTimer[strengthBin].getTotalTimeLocked( 3653 elapsedRealtimeUs, which); 3654 } 3655 3656 @Override public long getPhoneSignalScanningTime( 3657 long elapsedRealtimeUs, int which) { 3658 return mPhoneSignalScanningTimer.getTotalTimeLocked( 3659 elapsedRealtimeUs, which); 3660 } 3661 3662 @Override public int getPhoneSignalStrengthCount(int strengthBin, int which) { 3663 return mPhoneSignalStrengthsTimer[strengthBin].getCountLocked(which); 3664 } 3665 3666 @Override public long getPhoneDataConnectionTime(int dataType, 3667 long elapsedRealtimeUs, int which) { 3668 return mPhoneDataConnectionsTimer[dataType].getTotalTimeLocked( 3669 elapsedRealtimeUs, which); 3670 } 3671 3672 @Override public int getPhoneDataConnectionCount(int dataType, int which) { 3673 return mPhoneDataConnectionsTimer[dataType].getCountLocked(which); 3674 } 3675 3676 @Override public long getMobileRadioActiveTime(long elapsedRealtimeUs, int which) { 3677 return mMobileRadioActiveTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 3678 } 3679 3680 @Override public int getMobileRadioActiveCount(int which) { 3681 return mMobileRadioActiveTimer.getCountLocked(which); 3682 } 3683 3684 @Override public long getMobileRadioActiveAdjustedTime(int which) { 3685 return mMobileRadioActiveAdjustedTime.getCountLocked(which); 3686 } 3687 3688 @Override public long getMobileRadioActiveUnknownTime(int which) { 3689 return mMobileRadioActiveUnknownTime.getCountLocked(which); 3690 } 3691 3692 @Override public int getMobileRadioActiveUnknownCount(int which) { 3693 return (int)mMobileRadioActiveUnknownCount.getCountLocked(which); 3694 } 3695 3696 @Override public long getWifiOnTime(long elapsedRealtimeUs, int which) { 3697 return mWifiOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 3698 } 3699 3700 @Override public long getGlobalWifiRunningTime(long elapsedRealtimeUs, int which) { 3701 return mGlobalWifiRunningTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 3702 } 3703 3704 @Override public long getWifiStateTime(int wifiState, 3705 long elapsedRealtimeUs, int which) { 3706 return mWifiStateTimer[wifiState].getTotalTimeLocked( 3707 elapsedRealtimeUs, which); 3708 } 3709 3710 @Override public int getWifiStateCount(int wifiState, int which) { 3711 return mWifiStateTimer[wifiState].getCountLocked(which); 3712 } 3713 3714 @Override public long getWifiSupplStateTime(int state, 3715 long elapsedRealtimeUs, int which) { 3716 return mWifiSupplStateTimer[state].getTotalTimeLocked( 3717 elapsedRealtimeUs, which); 3718 } 3719 3720 @Override public int getWifiSupplStateCount(int state, int which) { 3721 return mWifiSupplStateTimer[state].getCountLocked(which); 3722 } 3723 3724 @Override public long getWifiSignalStrengthTime(int strengthBin, 3725 long elapsedRealtimeUs, int which) { 3726 return mWifiSignalStrengthsTimer[strengthBin].getTotalTimeLocked( 3727 elapsedRealtimeUs, which); 3728 } 3729 3730 @Override public int getWifiSignalStrengthCount(int strengthBin, int which) { 3731 return mWifiSignalStrengthsTimer[strengthBin].getCountLocked(which); 3732 } 3733 3734 @Override public long getBluetoothOnTime(long elapsedRealtimeUs, int which) { 3735 return mBluetoothOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 3736 } 3737 3738 @Override public long getBluetoothStateTime(int bluetoothState, 3739 long elapsedRealtimeUs, int which) { 3740 return mBluetoothStateTimer[bluetoothState].getTotalTimeLocked( 3741 elapsedRealtimeUs, which); 3742 } 3743 3744 @Override public int getBluetoothStateCount(int bluetoothState, int which) { 3745 return mBluetoothStateTimer[bluetoothState].getCountLocked(which); 3746 } 3747 3748 @Override public long getFlashlightOnTime(long elapsedRealtimeUs, int which) { 3749 return mFlashlightOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 3750 } 3751 3752 @Override public long getFlashlightOnCount(int which) { 3753 return mFlashlightOnTimer.getCountLocked(which); 3754 } 3755 3756 @Override 3757 public long getNetworkActivityBytes(int type, int which) { 3758 if (type >= 0 && type < mNetworkByteActivityCounters.length) { 3759 return mNetworkByteActivityCounters[type].getCountLocked(which); 3760 } else { 3761 return 0; 3762 } 3763 } 3764 3765 @Override 3766 public long getNetworkActivityPackets(int type, int which) { 3767 if (type >= 0 && type < mNetworkPacketActivityCounters.length) { 3768 return mNetworkPacketActivityCounters[type].getCountLocked(which); 3769 } else { 3770 return 0; 3771 } 3772 } 3773 3774 @Override public long getStartClockTime() { 3775 return mStartClockTime; 3776 } 3777 3778 @Override public boolean getIsOnBattery() { 3779 return mOnBattery; 3780 } 3781 3782 @Override public SparseArray<? extends BatteryStats.Uid> getUidStats() { 3783 return mUidStats; 3784 } 3785 3786 /** 3787 * The statistics associated with a particular uid. 3788 */ 3789 public final class Uid extends BatteryStats.Uid { 3790 3791 final int mUid; 3792 3793 boolean mWifiRunning; 3794 StopwatchTimer mWifiRunningTimer; 3795 3796 boolean mFullWifiLockOut; 3797 StopwatchTimer mFullWifiLockTimer; 3798 3799 boolean mWifiScanStarted; 3800 StopwatchTimer mWifiScanTimer; 3801 3802 static final int NO_BATCHED_SCAN_STARTED = -1; 3803 int mWifiBatchedScanBinStarted = NO_BATCHED_SCAN_STARTED; 3804 StopwatchTimer[] mWifiBatchedScanTimer; 3805 3806 boolean mWifiMulticastEnabled; 3807 StopwatchTimer mWifiMulticastTimer; 3808 3809 boolean mAudioTurnedOn; 3810 StopwatchTimer mAudioTurnedOnTimer; 3811 3812 boolean mVideoTurnedOn; 3813 StopwatchTimer mVideoTurnedOnTimer; 3814 3815 StopwatchTimer mForegroundActivityTimer; 3816 3817 static final int PROCESS_STATE_NONE = NUM_PROCESS_STATE; 3818 int mProcessState = PROCESS_STATE_NONE; 3819 StopwatchTimer[] mProcessStateTimer; 3820 3821 BatchTimer mVibratorOnTimer; 3822 3823 Counter[] mUserActivityCounters; 3824 3825 LongSamplingCounter[] mNetworkByteActivityCounters; 3826 LongSamplingCounter[] mNetworkPacketActivityCounters; 3827 LongSamplingCounter mMobileRadioActiveTime; 3828 LongSamplingCounter mMobileRadioActiveCount; 3829 3830 /** 3831 * The statistics we have collected for this uid's wake locks. 3832 */ 3833 final ArrayMap<String, Wakelock> mWakelockStats = new ArrayMap<String, Wakelock>(); 3834 3835 /** 3836 * The statistics we have collected for this uid's sensor activations. 3837 */ 3838 final SparseArray<Sensor> mSensorStats = new SparseArray<Sensor>(); 3839 3840 /** 3841 * The statistics we have collected for this uid's processes. 3842 */ 3843 final ArrayMap<String, Proc> mProcessStats = new ArrayMap<String, Proc>(); 3844 3845 /** 3846 * The statistics we have collected for this uid's processes. 3847 */ 3848 final ArrayMap<String, Pkg> mPackageStats = new ArrayMap<String, Pkg>(); 3849 3850 /** 3851 * The transient wake stats we have collected for this uid's pids. 3852 */ 3853 final SparseArray<Pid> mPids = new SparseArray<Pid>(); 3854 3855 public Uid(int uid) { 3856 mUid = uid; 3857 mWifiRunningTimer = new StopwatchTimer(Uid.this, WIFI_RUNNING, 3858 mWifiRunningTimers, mOnBatteryTimeBase); 3859 mFullWifiLockTimer = new StopwatchTimer(Uid.this, FULL_WIFI_LOCK, 3860 mFullWifiLockTimers, mOnBatteryTimeBase); 3861 mWifiScanTimer = new StopwatchTimer(Uid.this, WIFI_SCAN, 3862 mWifiScanTimers, mOnBatteryTimeBase); 3863 mWifiBatchedScanTimer = new StopwatchTimer[NUM_WIFI_BATCHED_SCAN_BINS]; 3864 mWifiMulticastTimer = new StopwatchTimer(Uid.this, WIFI_MULTICAST_ENABLED, 3865 mWifiMulticastTimers, mOnBatteryTimeBase); 3866 mProcessStateTimer = new StopwatchTimer[NUM_PROCESS_STATE]; 3867 } 3868 3869 @Override 3870 public Map<String, ? extends BatteryStats.Uid.Wakelock> getWakelockStats() { 3871 return mWakelockStats; 3872 } 3873 3874 @Override 3875 public SparseArray<? extends BatteryStats.Uid.Sensor> getSensorStats() { 3876 return mSensorStats; 3877 } 3878 3879 @Override 3880 public Map<String, ? extends BatteryStats.Uid.Proc> getProcessStats() { 3881 return mProcessStats; 3882 } 3883 3884 @Override 3885 public Map<String, ? extends BatteryStats.Uid.Pkg> getPackageStats() { 3886 return mPackageStats; 3887 } 3888 3889 @Override 3890 public int getUid() { 3891 return mUid; 3892 } 3893 3894 @Override 3895 public void noteWifiRunningLocked(long elapsedRealtimeMs) { 3896 if (!mWifiRunning) { 3897 mWifiRunning = true; 3898 if (mWifiRunningTimer == null) { 3899 mWifiRunningTimer = new StopwatchTimer(Uid.this, WIFI_RUNNING, 3900 mWifiRunningTimers, mOnBatteryTimeBase); 3901 } 3902 mWifiRunningTimer.startRunningLocked(elapsedRealtimeMs); 3903 } 3904 } 3905 3906 @Override 3907 public void noteWifiStoppedLocked(long elapsedRealtimeMs) { 3908 if (mWifiRunning) { 3909 mWifiRunning = false; 3910 mWifiRunningTimer.stopRunningLocked(elapsedRealtimeMs); 3911 } 3912 } 3913 3914 @Override 3915 public void noteFullWifiLockAcquiredLocked(long elapsedRealtimeMs) { 3916 if (!mFullWifiLockOut) { 3917 mFullWifiLockOut = true; 3918 if (mFullWifiLockTimer == null) { 3919 mFullWifiLockTimer = new StopwatchTimer(Uid.this, FULL_WIFI_LOCK, 3920 mFullWifiLockTimers, mOnBatteryTimeBase); 3921 } 3922 mFullWifiLockTimer.startRunningLocked(elapsedRealtimeMs); 3923 } 3924 } 3925 3926 @Override 3927 public void noteFullWifiLockReleasedLocked(long elapsedRealtimeMs) { 3928 if (mFullWifiLockOut) { 3929 mFullWifiLockOut = false; 3930 mFullWifiLockTimer.stopRunningLocked(elapsedRealtimeMs); 3931 } 3932 } 3933 3934 @Override 3935 public void noteWifiScanStartedLocked(long elapsedRealtimeMs) { 3936 if (!mWifiScanStarted) { 3937 mWifiScanStarted = true; 3938 if (mWifiScanTimer == null) { 3939 mWifiScanTimer = new StopwatchTimer(Uid.this, WIFI_SCAN, 3940 mWifiScanTimers, mOnBatteryTimeBase); 3941 } 3942 mWifiScanTimer.startRunningLocked(elapsedRealtimeMs); 3943 } 3944 } 3945 3946 @Override 3947 public void noteWifiScanStoppedLocked(long elapsedRealtimeMs) { 3948 if (mWifiScanStarted) { 3949 mWifiScanStarted = false; 3950 mWifiScanTimer.stopRunningLocked(elapsedRealtimeMs); 3951 } 3952 } 3953 3954 @Override 3955 public void noteWifiBatchedScanStartedLocked(int csph, long elapsedRealtimeMs) { 3956 int bin = 0; 3957 while (csph > 8 && bin < NUM_WIFI_BATCHED_SCAN_BINS) { 3958 csph = csph >> 3; 3959 bin++; 3960 } 3961 3962 if (mWifiBatchedScanBinStarted == bin) return; 3963 3964 if (mWifiBatchedScanBinStarted != NO_BATCHED_SCAN_STARTED) { 3965 mWifiBatchedScanTimer[mWifiBatchedScanBinStarted]. 3966 stopRunningLocked(elapsedRealtimeMs); 3967 } 3968 mWifiBatchedScanBinStarted = bin; 3969 if (mWifiBatchedScanTimer[bin] == null) { 3970 makeWifiBatchedScanBin(bin, null); 3971 } 3972 mWifiBatchedScanTimer[bin].startRunningLocked(elapsedRealtimeMs); 3973 } 3974 3975 @Override 3976 public void noteWifiBatchedScanStoppedLocked(long elapsedRealtimeMs) { 3977 if (mWifiBatchedScanBinStarted != NO_BATCHED_SCAN_STARTED) { 3978 mWifiBatchedScanTimer[mWifiBatchedScanBinStarted]. 3979 stopRunningLocked(elapsedRealtimeMs); 3980 mWifiBatchedScanBinStarted = NO_BATCHED_SCAN_STARTED; 3981 } 3982 } 3983 3984 @Override 3985 public void noteWifiMulticastEnabledLocked(long elapsedRealtimeMs) { 3986 if (!mWifiMulticastEnabled) { 3987 mWifiMulticastEnabled = true; 3988 if (mWifiMulticastTimer == null) { 3989 mWifiMulticastTimer = new StopwatchTimer(Uid.this, WIFI_MULTICAST_ENABLED, 3990 mWifiMulticastTimers, mOnBatteryTimeBase); 3991 } 3992 mWifiMulticastTimer.startRunningLocked(elapsedRealtimeMs); 3993 } 3994 } 3995 3996 @Override 3997 public void noteWifiMulticastDisabledLocked(long elapsedRealtimeMs) { 3998 if (mWifiMulticastEnabled) { 3999 mWifiMulticastEnabled = false; 4000 mWifiMulticastTimer.stopRunningLocked(elapsedRealtimeMs); 4001 } 4002 } 4003 4004 public StopwatchTimer createAudioTurnedOnTimerLocked() { 4005 if (mAudioTurnedOnTimer == null) { 4006 mAudioTurnedOnTimer = new StopwatchTimer(Uid.this, AUDIO_TURNED_ON, 4007 null, mOnBatteryTimeBase); 4008 } 4009 return mAudioTurnedOnTimer; 4010 } 4011 4012 @Override 4013 public void noteAudioTurnedOnLocked(long elapsedRealtimeMs) { 4014 if (!mAudioTurnedOn) { 4015 mAudioTurnedOn = true; 4016 createAudioTurnedOnTimerLocked().startRunningLocked(elapsedRealtimeMs); 4017 } 4018 } 4019 4020 @Override 4021 public void noteAudioTurnedOffLocked(long elapsedRealtimeMs) { 4022 if (mAudioTurnedOn) { 4023 mAudioTurnedOn = false; 4024 if (mAudioTurnedOnTimer != null) { 4025 mAudioTurnedOnTimer.stopRunningLocked(elapsedRealtimeMs); 4026 } 4027 } 4028 } 4029 4030 public StopwatchTimer createVideoTurnedOnTimerLocked() { 4031 if (mVideoTurnedOnTimer == null) { 4032 mVideoTurnedOnTimer = new StopwatchTimer(Uid.this, VIDEO_TURNED_ON, 4033 null, mOnBatteryTimeBase); 4034 } 4035 return mVideoTurnedOnTimer; 4036 } 4037 4038 @Override 4039 public void noteVideoTurnedOnLocked(long elapsedRealtimeMs) { 4040 if (!mVideoTurnedOn) { 4041 mVideoTurnedOn = true; 4042 createVideoTurnedOnTimerLocked().startRunningLocked(elapsedRealtimeMs); 4043 } 4044 } 4045 4046 @Override 4047 public void noteVideoTurnedOffLocked(long elapsedRealtimeMs) { 4048 if (mVideoTurnedOn) { 4049 mVideoTurnedOn = false; 4050 if (mVideoTurnedOnTimer != null) { 4051 mVideoTurnedOnTimer.stopRunningLocked(elapsedRealtimeMs); 4052 } 4053 } 4054 } 4055 4056 public StopwatchTimer createForegroundActivityTimerLocked() { 4057 if (mForegroundActivityTimer == null) { 4058 mForegroundActivityTimer = new StopwatchTimer( 4059 Uid.this, FOREGROUND_ACTIVITY, null, mOnBatteryTimeBase); 4060 } 4061 return mForegroundActivityTimer; 4062 } 4063 4064 @Override 4065 public void noteActivityResumedLocked(long elapsedRealtimeMs) { 4066 // We always start, since we want multiple foreground PIDs to nest 4067 createForegroundActivityTimerLocked().startRunningLocked(elapsedRealtimeMs); 4068 } 4069 4070 @Override 4071 public void noteActivityPausedLocked(long elapsedRealtimeMs) { 4072 if (mForegroundActivityTimer != null) { 4073 mForegroundActivityTimer.stopRunningLocked(elapsedRealtimeMs); 4074 } 4075 } 4076 4077 void updateUidProcessStateLocked(int state, long elapsedRealtimeMs) { 4078 if (mProcessState == state) return; 4079 4080 if (mProcessState != PROCESS_STATE_NONE) { 4081 mProcessStateTimer[mProcessState].stopRunningLocked(elapsedRealtimeMs); 4082 } 4083 mProcessState = state; 4084 if (state != PROCESS_STATE_NONE) { 4085 if (mProcessStateTimer[state] == null) { 4086 makeProcessState(state, null); 4087 } 4088 mProcessStateTimer[state].startRunningLocked(elapsedRealtimeMs); 4089 } 4090 } 4091 4092 public BatchTimer createVibratorOnTimerLocked() { 4093 if (mVibratorOnTimer == null) { 4094 mVibratorOnTimer = new BatchTimer(Uid.this, VIBRATOR_ON, mOnBatteryTimeBase); 4095 } 4096 return mVibratorOnTimer; 4097 } 4098 4099 public void noteVibratorOnLocked(long durationMillis) { 4100 createVibratorOnTimerLocked().addDuration(BatteryStatsImpl.this, durationMillis); 4101 } 4102 4103 public void noteVibratorOffLocked() { 4104 if (mVibratorOnTimer != null) { 4105 mVibratorOnTimer.abortLastDuration(BatteryStatsImpl.this); 4106 } 4107 } 4108 4109 @Override 4110 public long getWifiRunningTime(long elapsedRealtimeUs, int which) { 4111 if (mWifiRunningTimer == null) { 4112 return 0; 4113 } 4114 return mWifiRunningTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 4115 } 4116 4117 @Override 4118 public long getFullWifiLockTime(long elapsedRealtimeUs, int which) { 4119 if (mFullWifiLockTimer == null) { 4120 return 0; 4121 } 4122 return mFullWifiLockTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 4123 } 4124 4125 @Override 4126 public long getWifiScanTime(long elapsedRealtimeUs, int which) { 4127 if (mWifiScanTimer == null) { 4128 return 0; 4129 } 4130 return mWifiScanTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 4131 } 4132 4133 @Override 4134 public long getWifiBatchedScanTime(int csphBin, long elapsedRealtimeUs, int which) { 4135 if (csphBin < 0 || csphBin >= NUM_WIFI_BATCHED_SCAN_BINS) return 0; 4136 if (mWifiBatchedScanTimer[csphBin] == null) { 4137 return 0; 4138 } 4139 return mWifiBatchedScanTimer[csphBin].getTotalTimeLocked(elapsedRealtimeUs, which); 4140 } 4141 4142 @Override 4143 public long getWifiMulticastTime(long elapsedRealtimeUs, int which) { 4144 if (mWifiMulticastTimer == null) { 4145 return 0; 4146 } 4147 return mWifiMulticastTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 4148 } 4149 4150 @Override 4151 public long getAudioTurnedOnTime(long elapsedRealtimeUs, int which) { 4152 if (mAudioTurnedOnTimer == null) { 4153 return 0; 4154 } 4155 return mAudioTurnedOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 4156 } 4157 4158 @Override 4159 public long getVideoTurnedOnTime(long elapsedRealtimeUs, int which) { 4160 if (mVideoTurnedOnTimer == null) { 4161 return 0; 4162 } 4163 return mVideoTurnedOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which); 4164 } 4165 4166 @Override 4167 public Timer getForegroundActivityTimer() { 4168 return mForegroundActivityTimer; 4169 } 4170 4171 void makeProcessState(int i, Parcel in) { 4172 if (i < 0 || i >= NUM_PROCESS_STATE) return; 4173 4174 if (in == null) { 4175 mProcessStateTimer[i] = new StopwatchTimer(this, PROCESS_STATE, null, 4176 mOnBatteryTimeBase); 4177 } else { 4178 mProcessStateTimer[i] = new StopwatchTimer(this, PROCESS_STATE, null, 4179 mOnBatteryTimeBase, in); 4180 } 4181 } 4182 4183 @Override 4184 public long getProcessStateTime(int state, long elapsedRealtimeUs, int which) { 4185 if (state < 0 || state >= NUM_PROCESS_STATE) return 0; 4186 if (mProcessStateTimer[state] == null) { 4187 return 0; 4188 } 4189 return mProcessStateTimer[state].getTotalTimeLocked(elapsedRealtimeUs, which); 4190 } 4191 4192 @Override 4193 public Timer getVibratorOnTimer() { 4194 return mVibratorOnTimer; 4195 } 4196 4197 @Override 4198 public void noteUserActivityLocked(int type) { 4199 if (mUserActivityCounters == null) { 4200 initUserActivityLocked(); 4201 } 4202 if (type >= 0 && type < NUM_USER_ACTIVITY_TYPES) { 4203 mUserActivityCounters[type].stepAtomic(); 4204 } else { 4205 Slog.w(TAG, "Unknown user activity type " + type + " was specified.", 4206 new Throwable()); 4207 } 4208 } 4209 4210 @Override 4211 public boolean hasUserActivity() { 4212 return mUserActivityCounters != null; 4213 } 4214 4215 @Override 4216 public int getUserActivityCount(int type, int which) { 4217 if (mUserActivityCounters == null) { 4218 return 0; 4219 } 4220 return mUserActivityCounters[type].getCountLocked(which); 4221 } 4222 4223 void makeWifiBatchedScanBin(int i, Parcel in) { 4224 if (i < 0 || i >= NUM_WIFI_BATCHED_SCAN_BINS) return; 4225 4226 ArrayList<StopwatchTimer> collected = mWifiBatchedScanTimers.get(i); 4227 if (collected == null) { 4228 collected = new ArrayList<StopwatchTimer>(); 4229 mWifiBatchedScanTimers.put(i, collected); 4230 } 4231 if (in == null) { 4232 mWifiBatchedScanTimer[i] = new StopwatchTimer(this, WIFI_BATCHED_SCAN, collected, 4233 mOnBatteryTimeBase); 4234 } else { 4235 mWifiBatchedScanTimer[i] = new StopwatchTimer(this, WIFI_BATCHED_SCAN, collected, 4236 mOnBatteryTimeBase, in); 4237 } 4238 } 4239 4240 4241 void initUserActivityLocked() { 4242 mUserActivityCounters = new Counter[NUM_USER_ACTIVITY_TYPES]; 4243 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) { 4244 mUserActivityCounters[i] = new Counter(mOnBatteryTimeBase); 4245 } 4246 } 4247 4248 void noteNetworkActivityLocked(int type, long deltaBytes, long deltaPackets) { 4249 if (mNetworkByteActivityCounters == null) { 4250 initNetworkActivityLocked(); 4251 } 4252 if (type >= 0 && type < NUM_NETWORK_ACTIVITY_TYPES) { 4253 mNetworkByteActivityCounters[type].addCountLocked(deltaBytes); 4254 mNetworkPacketActivityCounters[type].addCountLocked(deltaPackets); 4255 } else { 4256 Slog.w(TAG, "Unknown network activity type " + type + " was specified.", 4257 new Throwable()); 4258 } 4259 } 4260 4261 void noteMobileRadioActiveTimeLocked(long batteryUptime) { 4262 if (mNetworkByteActivityCounters == null) { 4263 initNetworkActivityLocked(); 4264 } 4265 mMobileRadioActiveTime.addCountLocked(batteryUptime); 4266 mMobileRadioActiveCount.addCountLocked(1); 4267 } 4268 4269 @Override 4270 public boolean hasNetworkActivity() { 4271 return mNetworkByteActivityCounters != null; 4272 } 4273 4274 @Override 4275 public long getNetworkActivityBytes(int type, int which) { 4276 if (mNetworkByteActivityCounters != null && type >= 0 4277 && type < mNetworkByteActivityCounters.length) { 4278 return mNetworkByteActivityCounters[type].getCountLocked(which); 4279 } else { 4280 return 0; 4281 } 4282 } 4283 4284 @Override 4285 public long getNetworkActivityPackets(int type, int which) { 4286 if (mNetworkPacketActivityCounters != null && type >= 0 4287 && type < mNetworkPacketActivityCounters.length) { 4288 return mNetworkPacketActivityCounters[type].getCountLocked(which); 4289 } else { 4290 return 0; 4291 } 4292 } 4293 4294 @Override 4295 public long getMobileRadioActiveTime(int which) { 4296 return mMobileRadioActiveTime != null 4297 ? mMobileRadioActiveTime.getCountLocked(which) : 0; 4298 } 4299 4300 @Override 4301 public int getMobileRadioActiveCount(int which) { 4302 return mMobileRadioActiveCount != null 4303 ? (int)mMobileRadioActiveCount.getCountLocked(which) : 0; 4304 } 4305 4306 void initNetworkActivityLocked() { 4307 mNetworkByteActivityCounters = new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES]; 4308 mNetworkPacketActivityCounters = new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES]; 4309 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 4310 mNetworkByteActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase); 4311 mNetworkPacketActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase); 4312 } 4313 mMobileRadioActiveTime = new LongSamplingCounter(mOnBatteryTimeBase); 4314 mMobileRadioActiveCount = new LongSamplingCounter(mOnBatteryTimeBase); 4315 } 4316 4317 /** 4318 * Clear all stats for this uid. Returns true if the uid is completely 4319 * inactive so can be dropped. 4320 */ 4321 boolean reset() { 4322 boolean active = false; 4323 4324 if (mWifiRunningTimer != null) { 4325 active |= !mWifiRunningTimer.reset(false); 4326 active |= mWifiRunning; 4327 } 4328 if (mFullWifiLockTimer != null) { 4329 active |= !mFullWifiLockTimer.reset(false); 4330 active |= mFullWifiLockOut; 4331 } 4332 if (mWifiScanTimer != null) { 4333 active |= !mWifiScanTimer.reset(false); 4334 active |= mWifiScanStarted; 4335 } 4336 if (mWifiBatchedScanTimer != null) { 4337 for (int i = 0; i < NUM_WIFI_BATCHED_SCAN_BINS; i++) { 4338 if (mWifiBatchedScanTimer[i] != null) { 4339 active |= !mWifiBatchedScanTimer[i].reset(false); 4340 } 4341 } 4342 active |= (mWifiBatchedScanBinStarted != NO_BATCHED_SCAN_STARTED); 4343 } 4344 if (mWifiMulticastTimer != null) { 4345 active |= !mWifiMulticastTimer.reset(false); 4346 active |= mWifiMulticastEnabled; 4347 } 4348 if (mAudioTurnedOnTimer != null) { 4349 active |= !mAudioTurnedOnTimer.reset(false); 4350 active |= mAudioTurnedOn; 4351 } 4352 if (mVideoTurnedOnTimer != null) { 4353 active |= !mVideoTurnedOnTimer.reset(false); 4354 active |= mVideoTurnedOn; 4355 } 4356 if (mForegroundActivityTimer != null) { 4357 active |= !mForegroundActivityTimer.reset(false); 4358 } 4359 if (mProcessStateTimer != null) { 4360 for (int i = 0; i < NUM_PROCESS_STATE; i++) { 4361 if (mProcessStateTimer[i] != null) { 4362 active |= !mProcessStateTimer[i].reset(false); 4363 } 4364 } 4365 active |= (mProcessState != PROCESS_STATE_NONE); 4366 } 4367 if (mVibratorOnTimer != null) { 4368 if (mVibratorOnTimer.reset(false)) { 4369 mVibratorOnTimer.detach(); 4370 mVibratorOnTimer = null; 4371 } else { 4372 active = true; 4373 } 4374 } 4375 4376 if (mUserActivityCounters != null) { 4377 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) { 4378 mUserActivityCounters[i].reset(false); 4379 } 4380 } 4381 4382 if (mNetworkByteActivityCounters != null) { 4383 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 4384 mNetworkByteActivityCounters[i].reset(false); 4385 mNetworkPacketActivityCounters[i].reset(false); 4386 } 4387 mMobileRadioActiveTime.reset(false); 4388 mMobileRadioActiveCount.reset(false); 4389 } 4390 4391 for (int iw=mWakelockStats.size()-1; iw>=0; iw--) { 4392 Wakelock wl = mWakelockStats.valueAt(iw); 4393 if (wl.reset()) { 4394 mWakelockStats.removeAt(iw); 4395 } else { 4396 active = true; 4397 } 4398 } 4399 for (int ise=mSensorStats.size()-1; ise>=0; ise--) { 4400 Sensor s = mSensorStats.valueAt(ise); 4401 if (s.reset()) { 4402 mSensorStats.removeAt(ise); 4403 } else { 4404 active = true; 4405 } 4406 } 4407 for (int ip=mProcessStats.size()-1; ip>=0; ip--) { 4408 Proc proc = mProcessStats.valueAt(ip); 4409 if (proc.mProcessState == PROCESS_STATE_NONE) { 4410 proc.detach(); 4411 mProcessStats.removeAt(ip); 4412 } else { 4413 active = true; 4414 } 4415 } 4416 if (mPids.size() > 0) { 4417 for (int i=mPids.size()-1; i>=0; i--) { 4418 Pid pid = mPids.valueAt(i); 4419 if (pid.mWakeNesting > 0) { 4420 active = true; 4421 } else { 4422 mPids.removeAt(i); 4423 } 4424 } 4425 } 4426 if (mPackageStats.size() > 0) { 4427 Iterator<Map.Entry<String, Pkg>> it = mPackageStats.entrySet().iterator(); 4428 while (it.hasNext()) { 4429 Map.Entry<String, Pkg> pkgEntry = it.next(); 4430 Pkg p = pkgEntry.getValue(); 4431 p.detach(); 4432 if (p.mServiceStats.size() > 0) { 4433 Iterator<Map.Entry<String, Pkg.Serv>> it2 4434 = p.mServiceStats.entrySet().iterator(); 4435 while (it2.hasNext()) { 4436 Map.Entry<String, Pkg.Serv> servEntry = it2.next(); 4437 servEntry.getValue().detach(); 4438 } 4439 } 4440 } 4441 mPackageStats.clear(); 4442 } 4443 4444 if (!active) { 4445 if (mWifiRunningTimer != null) { 4446 mWifiRunningTimer.detach(); 4447 } 4448 if (mFullWifiLockTimer != null) { 4449 mFullWifiLockTimer.detach(); 4450 } 4451 if (mWifiScanTimer != null) { 4452 mWifiScanTimer.detach(); 4453 } 4454 for (int i = 0; i < NUM_WIFI_BATCHED_SCAN_BINS; i++) { 4455 if (mWifiBatchedScanTimer[i] != null) { 4456 mWifiBatchedScanTimer[i].detach(); 4457 } 4458 } 4459 if (mWifiMulticastTimer != null) { 4460 mWifiMulticastTimer.detach(); 4461 } 4462 if (mAudioTurnedOnTimer != null) { 4463 mAudioTurnedOnTimer.detach(); 4464 mAudioTurnedOnTimer = null; 4465 } 4466 if (mVideoTurnedOnTimer != null) { 4467 mVideoTurnedOnTimer.detach(); 4468 mVideoTurnedOnTimer = null; 4469 } 4470 if (mForegroundActivityTimer != null) { 4471 mForegroundActivityTimer.detach(); 4472 mForegroundActivityTimer = null; 4473 } 4474 if (mUserActivityCounters != null) { 4475 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) { 4476 mUserActivityCounters[i].detach(); 4477 } 4478 } 4479 if (mNetworkByteActivityCounters != null) { 4480 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 4481 mNetworkByteActivityCounters[i].detach(); 4482 mNetworkPacketActivityCounters[i].detach(); 4483 } 4484 } 4485 mPids.clear(); 4486 } 4487 4488 return !active; 4489 } 4490 4491 void writeToParcelLocked(Parcel out, long elapsedRealtimeUs) { 4492 int NW = mWakelockStats.size(); 4493 out.writeInt(NW); 4494 for (int iw=0; iw<NW; iw++) { 4495 out.writeString(mWakelockStats.keyAt(iw)); 4496 Uid.Wakelock wakelock = mWakelockStats.valueAt(iw); 4497 wakelock.writeToParcelLocked(out, elapsedRealtimeUs); 4498 } 4499 4500 int NSE = mSensorStats.size(); 4501 out.writeInt(NSE); 4502 for (int ise=0; ise<NSE; ise++) { 4503 out.writeInt(mSensorStats.keyAt(ise)); 4504 Uid.Sensor sensor = mSensorStats.valueAt(ise); 4505 sensor.writeToParcelLocked(out, elapsedRealtimeUs); 4506 } 4507 4508 int NP = mProcessStats.size(); 4509 out.writeInt(NP); 4510 for (int ip=0; ip<NP; ip++) { 4511 out.writeString(mProcessStats.keyAt(ip)); 4512 Uid.Proc proc = mProcessStats.valueAt(ip); 4513 proc.writeToParcelLocked(out); 4514 } 4515 4516 out.writeInt(mPackageStats.size()); 4517 for (Map.Entry<String, Uid.Pkg> pkgEntry : mPackageStats.entrySet()) { 4518 out.writeString(pkgEntry.getKey()); 4519 Uid.Pkg pkg = pkgEntry.getValue(); 4520 pkg.writeToParcelLocked(out); 4521 } 4522 4523 if (mWifiRunningTimer != null) { 4524 out.writeInt(1); 4525 mWifiRunningTimer.writeToParcel(out, elapsedRealtimeUs); 4526 } else { 4527 out.writeInt(0); 4528 } 4529 if (mFullWifiLockTimer != null) { 4530 out.writeInt(1); 4531 mFullWifiLockTimer.writeToParcel(out, elapsedRealtimeUs); 4532 } else { 4533 out.writeInt(0); 4534 } 4535 if (mWifiScanTimer != null) { 4536 out.writeInt(1); 4537 mWifiScanTimer.writeToParcel(out, elapsedRealtimeUs); 4538 } else { 4539 out.writeInt(0); 4540 } 4541 for (int i = 0; i < NUM_WIFI_BATCHED_SCAN_BINS; i++) { 4542 if (mWifiBatchedScanTimer[i] != null) { 4543 out.writeInt(1); 4544 mWifiBatchedScanTimer[i].writeToParcel(out, elapsedRealtimeUs); 4545 } else { 4546 out.writeInt(0); 4547 } 4548 } 4549 if (mWifiMulticastTimer != null) { 4550 out.writeInt(1); 4551 mWifiMulticastTimer.writeToParcel(out, elapsedRealtimeUs); 4552 } else { 4553 out.writeInt(0); 4554 } 4555 if (mAudioTurnedOnTimer != null) { 4556 out.writeInt(1); 4557 mAudioTurnedOnTimer.writeToParcel(out, elapsedRealtimeUs); 4558 } else { 4559 out.writeInt(0); 4560 } 4561 if (mVideoTurnedOnTimer != null) { 4562 out.writeInt(1); 4563 mVideoTurnedOnTimer.writeToParcel(out, elapsedRealtimeUs); 4564 } else { 4565 out.writeInt(0); 4566 } 4567 if (mForegroundActivityTimer != null) { 4568 out.writeInt(1); 4569 mForegroundActivityTimer.writeToParcel(out, elapsedRealtimeUs); 4570 } else { 4571 out.writeInt(0); 4572 } 4573 for (int i = 0; i < NUM_PROCESS_STATE; i++) { 4574 if (mProcessStateTimer[i] != null) { 4575 out.writeInt(1); 4576 mProcessStateTimer[i].writeToParcel(out, elapsedRealtimeUs); 4577 } else { 4578 out.writeInt(0); 4579 } 4580 } 4581 if (mVibratorOnTimer != null) { 4582 out.writeInt(1); 4583 mVibratorOnTimer.writeToParcel(out, elapsedRealtimeUs); 4584 } else { 4585 out.writeInt(0); 4586 } 4587 if (mUserActivityCounters != null) { 4588 out.writeInt(1); 4589 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) { 4590 mUserActivityCounters[i].writeToParcel(out); 4591 } 4592 } else { 4593 out.writeInt(0); 4594 } 4595 if (mNetworkByteActivityCounters != null) { 4596 out.writeInt(1); 4597 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 4598 mNetworkByteActivityCounters[i].writeToParcel(out); 4599 mNetworkPacketActivityCounters[i].writeToParcel(out); 4600 } 4601 mMobileRadioActiveTime.writeToParcel(out); 4602 mMobileRadioActiveCount.writeToParcel(out); 4603 } else { 4604 out.writeInt(0); 4605 } 4606 } 4607 4608 void readFromParcelLocked(TimeBase timeBase, TimeBase screenOffTimeBase, Parcel in) { 4609 int numWakelocks = in.readInt(); 4610 mWakelockStats.clear(); 4611 for (int j = 0; j < numWakelocks; j++) { 4612 String wakelockName = in.readString(); 4613 Uid.Wakelock wakelock = new Wakelock(); 4614 wakelock.readFromParcelLocked(timeBase, screenOffTimeBase, in); 4615 // We will just drop some random set of wakelocks if 4616 // the previous run of the system was an older version 4617 // that didn't impose a limit. 4618 mWakelockStats.put(wakelockName, wakelock); 4619 } 4620 4621 int numSensors = in.readInt(); 4622 mSensorStats.clear(); 4623 for (int k = 0; k < numSensors; k++) { 4624 int sensorNumber = in.readInt(); 4625 Uid.Sensor sensor = new Sensor(sensorNumber); 4626 sensor.readFromParcelLocked(mOnBatteryTimeBase, in); 4627 mSensorStats.put(sensorNumber, sensor); 4628 } 4629 4630 int numProcs = in.readInt(); 4631 mProcessStats.clear(); 4632 for (int k = 0; k < numProcs; k++) { 4633 String processName = in.readString(); 4634 Uid.Proc proc = new Proc(); 4635 proc.readFromParcelLocked(in); 4636 mProcessStats.put(processName, proc); 4637 } 4638 4639 int numPkgs = in.readInt(); 4640 mPackageStats.clear(); 4641 for (int l = 0; l < numPkgs; l++) { 4642 String packageName = in.readString(); 4643 Uid.Pkg pkg = new Pkg(); 4644 pkg.readFromParcelLocked(in); 4645 mPackageStats.put(packageName, pkg); 4646 } 4647 4648 mWifiRunning = false; 4649 if (in.readInt() != 0) { 4650 mWifiRunningTimer = new StopwatchTimer(Uid.this, WIFI_RUNNING, 4651 mWifiRunningTimers, mOnBatteryTimeBase, in); 4652 } else { 4653 mWifiRunningTimer = null; 4654 } 4655 mFullWifiLockOut = false; 4656 if (in.readInt() != 0) { 4657 mFullWifiLockTimer = new StopwatchTimer(Uid.this, FULL_WIFI_LOCK, 4658 mFullWifiLockTimers, mOnBatteryTimeBase, in); 4659 } else { 4660 mFullWifiLockTimer = null; 4661 } 4662 mWifiScanStarted = false; 4663 if (in.readInt() != 0) { 4664 mWifiScanTimer = new StopwatchTimer(Uid.this, WIFI_SCAN, 4665 mWifiScanTimers, mOnBatteryTimeBase, in); 4666 } else { 4667 mWifiScanTimer = null; 4668 } 4669 mWifiBatchedScanBinStarted = NO_BATCHED_SCAN_STARTED; 4670 for (int i = 0; i < NUM_WIFI_BATCHED_SCAN_BINS; i++) { 4671 if (in.readInt() != 0) { 4672 makeWifiBatchedScanBin(i, in); 4673 } else { 4674 mWifiBatchedScanTimer[i] = null; 4675 } 4676 } 4677 mWifiMulticastEnabled = false; 4678 if (in.readInt() != 0) { 4679 mWifiMulticastTimer = new StopwatchTimer(Uid.this, WIFI_MULTICAST_ENABLED, 4680 mWifiMulticastTimers, mOnBatteryTimeBase, in); 4681 } else { 4682 mWifiMulticastTimer = null; 4683 } 4684 mAudioTurnedOn = false; 4685 if (in.readInt() != 0) { 4686 mAudioTurnedOnTimer = new StopwatchTimer(Uid.this, AUDIO_TURNED_ON, 4687 null, mOnBatteryTimeBase, in); 4688 } else { 4689 mAudioTurnedOnTimer = null; 4690 } 4691 mVideoTurnedOn = false; 4692 if (in.readInt() != 0) { 4693 mVideoTurnedOnTimer = new StopwatchTimer(Uid.this, VIDEO_TURNED_ON, 4694 null, mOnBatteryTimeBase, in); 4695 } else { 4696 mVideoTurnedOnTimer = null; 4697 } 4698 if (in.readInt() != 0) { 4699 mForegroundActivityTimer = new StopwatchTimer( 4700 Uid.this, FOREGROUND_ACTIVITY, null, mOnBatteryTimeBase, in); 4701 } else { 4702 mForegroundActivityTimer = null; 4703 } 4704 mProcessState = PROCESS_STATE_NONE; 4705 for (int i = 0; i < NUM_PROCESS_STATE; i++) { 4706 if (in.readInt() != 0) { 4707 makeProcessState(i, in); 4708 } else { 4709 mProcessStateTimer[i] = null; 4710 } 4711 } 4712 if (in.readInt() != 0) { 4713 mVibratorOnTimer = new BatchTimer(Uid.this, VIBRATOR_ON, mOnBatteryTimeBase, in); 4714 } else { 4715 mVibratorOnTimer = null; 4716 } 4717 if (in.readInt() != 0) { 4718 mUserActivityCounters = new Counter[NUM_USER_ACTIVITY_TYPES]; 4719 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) { 4720 mUserActivityCounters[i] = new Counter(mOnBatteryTimeBase, in); 4721 } 4722 } else { 4723 mUserActivityCounters = null; 4724 } 4725 if (in.readInt() != 0) { 4726 mNetworkByteActivityCounters = new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES]; 4727 mNetworkPacketActivityCounters 4728 = new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES]; 4729 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 4730 mNetworkByteActivityCounters[i] 4731 = new LongSamplingCounter(mOnBatteryTimeBase, in); 4732 mNetworkPacketActivityCounters[i] 4733 = new LongSamplingCounter(mOnBatteryTimeBase, in); 4734 } 4735 mMobileRadioActiveTime = new LongSamplingCounter(mOnBatteryTimeBase, in); 4736 mMobileRadioActiveCount = new LongSamplingCounter(mOnBatteryTimeBase, in); 4737 } else { 4738 mNetworkByteActivityCounters = null; 4739 mNetworkPacketActivityCounters = null; 4740 } 4741 } 4742 4743 /** 4744 * The statistics associated with a particular wake lock. 4745 */ 4746 public final class Wakelock extends BatteryStats.Uid.Wakelock { 4747 /** 4748 * How long (in ms) this uid has been keeping the device partially awake. 4749 */ 4750 StopwatchTimer mTimerPartial; 4751 4752 /** 4753 * How long (in ms) this uid has been keeping the device fully awake. 4754 */ 4755 StopwatchTimer mTimerFull; 4756 4757 /** 4758 * How long (in ms) this uid has had a window keeping the device awake. 4759 */ 4760 StopwatchTimer mTimerWindow; 4761 4762 /** 4763 * Reads a possibly null Timer from a Parcel. The timer is associated with the 4764 * proper timer pool from the given BatteryStatsImpl object. 4765 * 4766 * @param in the Parcel to be read from. 4767 * return a new Timer, or null. 4768 */ 4769 private StopwatchTimer readTimerFromParcel(int type, ArrayList<StopwatchTimer> pool, 4770 TimeBase timeBase, Parcel in) { 4771 if (in.readInt() == 0) { 4772 return null; 4773 } 4774 4775 return new StopwatchTimer(Uid.this, type, pool, timeBase, in); 4776 } 4777 4778 boolean reset() { 4779 boolean wlactive = false; 4780 if (mTimerFull != null) { 4781 wlactive |= !mTimerFull.reset(false); 4782 } 4783 if (mTimerPartial != null) { 4784 wlactive |= !mTimerPartial.reset(false); 4785 } 4786 if (mTimerWindow != null) { 4787 wlactive |= !mTimerWindow.reset(false); 4788 } 4789 if (!wlactive) { 4790 if (mTimerFull != null) { 4791 mTimerFull.detach(); 4792 mTimerFull = null; 4793 } 4794 if (mTimerPartial != null) { 4795 mTimerPartial.detach(); 4796 mTimerPartial = null; 4797 } 4798 if (mTimerWindow != null) { 4799 mTimerWindow.detach(); 4800 mTimerWindow = null; 4801 } 4802 } 4803 return !wlactive; 4804 } 4805 4806 void readFromParcelLocked(TimeBase timeBase, TimeBase screenOffTimeBase, Parcel in) { 4807 mTimerPartial = readTimerFromParcel(WAKE_TYPE_PARTIAL, 4808 mPartialTimers, screenOffTimeBase, in); 4809 mTimerFull = readTimerFromParcel(WAKE_TYPE_FULL, 4810 mFullTimers, timeBase, in); 4811 mTimerWindow = readTimerFromParcel(WAKE_TYPE_WINDOW, 4812 mWindowTimers, timeBase, in); 4813 } 4814 4815 void writeToParcelLocked(Parcel out, long elapsedRealtimeUs) { 4816 Timer.writeTimerToParcel(out, mTimerPartial, elapsedRealtimeUs); 4817 Timer.writeTimerToParcel(out, mTimerFull, elapsedRealtimeUs); 4818 Timer.writeTimerToParcel(out, mTimerWindow, elapsedRealtimeUs); 4819 } 4820 4821 @Override 4822 public Timer getWakeTime(int type) { 4823 switch (type) { 4824 case WAKE_TYPE_FULL: return mTimerFull; 4825 case WAKE_TYPE_PARTIAL: return mTimerPartial; 4826 case WAKE_TYPE_WINDOW: return mTimerWindow; 4827 default: throw new IllegalArgumentException("type = " + type); 4828 } 4829 } 4830 } 4831 4832 public final class Sensor extends BatteryStats.Uid.Sensor { 4833 final int mHandle; 4834 StopwatchTimer mTimer; 4835 4836 public Sensor(int handle) { 4837 mHandle = handle; 4838 } 4839 4840 private StopwatchTimer readTimerFromParcel(TimeBase timeBase, Parcel in) { 4841 if (in.readInt() == 0) { 4842 return null; 4843 } 4844 4845 ArrayList<StopwatchTimer> pool = mSensorTimers.get(mHandle); 4846 if (pool == null) { 4847 pool = new ArrayList<StopwatchTimer>(); 4848 mSensorTimers.put(mHandle, pool); 4849 } 4850 return new StopwatchTimer(Uid.this, 0, pool, timeBase, in); 4851 } 4852 4853 boolean reset() { 4854 if (mTimer.reset(true)) { 4855 mTimer = null; 4856 return true; 4857 } 4858 return false; 4859 } 4860 4861 void readFromParcelLocked(TimeBase timeBase, Parcel in) { 4862 mTimer = readTimerFromParcel(timeBase, in); 4863 } 4864 4865 void writeToParcelLocked(Parcel out, long elapsedRealtimeUs) { 4866 Timer.writeTimerToParcel(out, mTimer, elapsedRealtimeUs); 4867 } 4868 4869 @Override 4870 public Timer getSensorTime() { 4871 return mTimer; 4872 } 4873 4874 @Override 4875 public int getHandle() { 4876 return mHandle; 4877 } 4878 } 4879 4880 /** 4881 * The statistics associated with a particular process. 4882 */ 4883 public final class Proc extends BatteryStats.Uid.Proc implements TimeBaseObs { 4884 /** 4885 * Remains true until removed from the stats. 4886 */ 4887 boolean mActive = true; 4888 4889 /** 4890 * Total time (in 1/100 sec) spent executing in user code. 4891 */ 4892 long mUserTime; 4893 4894 /** 4895 * Total time (in 1/100 sec) spent executing in kernel code. 4896 */ 4897 long mSystemTime; 4898 4899 /** 4900 * Amount of time the process was running in the foreground. 4901 */ 4902 long mForegroundTime; 4903 4904 /** 4905 * Number of times the process has been started. 4906 */ 4907 int mStarts; 4908 4909 /** 4910 * The amount of user time loaded from a previous save. 4911 */ 4912 long mLoadedUserTime; 4913 4914 /** 4915 * The amount of system time loaded from a previous save. 4916 */ 4917 long mLoadedSystemTime; 4918 4919 /** 4920 * The amount of foreground time loaded from a previous save. 4921 */ 4922 long mLoadedForegroundTime; 4923 4924 /** 4925 * The number of times the process has started from a previous save. 4926 */ 4927 int mLoadedStarts; 4928 4929 /** 4930 * The amount of user time loaded from the previous run. 4931 */ 4932 long mLastUserTime; 4933 4934 /** 4935 * The amount of system time loaded from the previous run. 4936 */ 4937 long mLastSystemTime; 4938 4939 /** 4940 * The amount of foreground time loaded from the previous run 4941 */ 4942 long mLastForegroundTime; 4943 4944 /** 4945 * The number of times the process has started from the previous run. 4946 */ 4947 int mLastStarts; 4948 4949 /** 4950 * The amount of user time when last unplugged. 4951 */ 4952 long mUnpluggedUserTime; 4953 4954 /** 4955 * The amount of system time when last unplugged. 4956 */ 4957 long mUnpluggedSystemTime; 4958 4959 /** 4960 * The amount of foreground time since unplugged. 4961 */ 4962 long mUnpluggedForegroundTime; 4963 4964 /** 4965 * The number of times the process has started before unplugged. 4966 */ 4967 int mUnpluggedStarts; 4968 4969 /** 4970 * Current process state. 4971 */ 4972 int mProcessState = PROCESS_STATE_NONE; 4973 4974 SamplingCounter[] mSpeedBins; 4975 4976 ArrayList<ExcessivePower> mExcessivePower; 4977 4978 Proc() { 4979 mOnBatteryTimeBase.add(this); 4980 mSpeedBins = new SamplingCounter[getCpuSpeedSteps()]; 4981 } 4982 4983 public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) { 4984 mUnpluggedUserTime = mUserTime; 4985 mUnpluggedSystemTime = mSystemTime; 4986 mUnpluggedForegroundTime = mForegroundTime; 4987 mUnpluggedStarts = mStarts; 4988 } 4989 4990 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) { 4991 } 4992 4993 void detach() { 4994 mActive = false; 4995 mOnBatteryTimeBase.remove(this); 4996 for (int i = 0; i < mSpeedBins.length; i++) { 4997 SamplingCounter c = mSpeedBins[i]; 4998 if (c != null) { 4999 mOnBatteryTimeBase.remove(c); 5000 mSpeedBins[i] = null; 5001 } 5002 } 5003 } 5004 5005 public int countExcessivePowers() { 5006 return mExcessivePower != null ? mExcessivePower.size() : 0; 5007 } 5008 5009 public ExcessivePower getExcessivePower(int i) { 5010 if (mExcessivePower != null) { 5011 return mExcessivePower.get(i); 5012 } 5013 return null; 5014 } 5015 5016 public void addExcessiveWake(long overTime, long usedTime) { 5017 if (mExcessivePower == null) { 5018 mExcessivePower = new ArrayList<ExcessivePower>(); 5019 } 5020 ExcessivePower ew = new ExcessivePower(); 5021 ew.type = ExcessivePower.TYPE_WAKE; 5022 ew.overTime = overTime; 5023 ew.usedTime = usedTime; 5024 mExcessivePower.add(ew); 5025 } 5026 5027 public void addExcessiveCpu(long overTime, long usedTime) { 5028 if (mExcessivePower == null) { 5029 mExcessivePower = new ArrayList<ExcessivePower>(); 5030 } 5031 ExcessivePower ew = new ExcessivePower(); 5032 ew.type = ExcessivePower.TYPE_CPU; 5033 ew.overTime = overTime; 5034 ew.usedTime = usedTime; 5035 mExcessivePower.add(ew); 5036 } 5037 5038 void writeExcessivePowerToParcelLocked(Parcel out) { 5039 if (mExcessivePower == null) { 5040 out.writeInt(0); 5041 return; 5042 } 5043 5044 final int N = mExcessivePower.size(); 5045 out.writeInt(N); 5046 for (int i=0; i<N; i++) { 5047 ExcessivePower ew = mExcessivePower.get(i); 5048 out.writeInt(ew.type); 5049 out.writeLong(ew.overTime); 5050 out.writeLong(ew.usedTime); 5051 } 5052 } 5053 5054 boolean readExcessivePowerFromParcelLocked(Parcel in) { 5055 final int N = in.readInt(); 5056 if (N == 0) { 5057 mExcessivePower = null; 5058 return true; 5059 } 5060 5061 if (N > 10000) { 5062 Slog.w(TAG, "File corrupt: too many excessive power entries " + N); 5063 return false; 5064 } 5065 5066 mExcessivePower = new ArrayList<ExcessivePower>(); 5067 for (int i=0; i<N; i++) { 5068 ExcessivePower ew = new ExcessivePower(); 5069 ew.type = in.readInt(); 5070 ew.overTime = in.readLong(); 5071 ew.usedTime = in.readLong(); 5072 mExcessivePower.add(ew); 5073 } 5074 return true; 5075 } 5076 5077 void writeToParcelLocked(Parcel out) { 5078 out.writeLong(mUserTime); 5079 out.writeLong(mSystemTime); 5080 out.writeLong(mForegroundTime); 5081 out.writeInt(mStarts); 5082 out.writeLong(mLoadedUserTime); 5083 out.writeLong(mLoadedSystemTime); 5084 out.writeLong(mLoadedForegroundTime); 5085 out.writeInt(mLoadedStarts); 5086 out.writeLong(mUnpluggedUserTime); 5087 out.writeLong(mUnpluggedSystemTime); 5088 out.writeLong(mUnpluggedForegroundTime); 5089 out.writeInt(mUnpluggedStarts); 5090 5091 out.writeInt(mSpeedBins.length); 5092 for (int i = 0; i < mSpeedBins.length; i++) { 5093 SamplingCounter c = mSpeedBins[i]; 5094 if (c != null) { 5095 out.writeInt(1); 5096 c.writeToParcel(out); 5097 } else { 5098 out.writeInt(0); 5099 } 5100 } 5101 5102 writeExcessivePowerToParcelLocked(out); 5103 } 5104 5105 void readFromParcelLocked(Parcel in) { 5106 mUserTime = in.readLong(); 5107 mSystemTime = in.readLong(); 5108 mForegroundTime = in.readLong(); 5109 mStarts = in.readInt(); 5110 mLoadedUserTime = in.readLong(); 5111 mLoadedSystemTime = in.readLong(); 5112 mLoadedForegroundTime = in.readLong(); 5113 mLoadedStarts = in.readInt(); 5114 mLastUserTime = 0; 5115 mLastSystemTime = 0; 5116 mLastForegroundTime = 0; 5117 mLastStarts = 0; 5118 mUnpluggedUserTime = in.readLong(); 5119 mUnpluggedSystemTime = in.readLong(); 5120 mUnpluggedForegroundTime = in.readLong(); 5121 mUnpluggedStarts = in.readInt(); 5122 5123 int bins = in.readInt(); 5124 int steps = getCpuSpeedSteps(); 5125 mSpeedBins = new SamplingCounter[bins >= steps ? bins : steps]; 5126 for (int i = 0; i < bins; i++) { 5127 if (in.readInt() != 0) { 5128 mSpeedBins[i] = new SamplingCounter(mOnBatteryTimeBase, in); 5129 } 5130 } 5131 5132 readExcessivePowerFromParcelLocked(in); 5133 } 5134 5135 public BatteryStatsImpl getBatteryStats() { 5136 return BatteryStatsImpl.this; 5137 } 5138 5139 public void addCpuTimeLocked(int utime, int stime) { 5140 mUserTime += utime; 5141 mSystemTime += stime; 5142 } 5143 5144 public void addForegroundTimeLocked(long ttime) { 5145 mForegroundTime += ttime; 5146 } 5147 5148 public void incStartsLocked() { 5149 mStarts++; 5150 } 5151 5152 @Override 5153 public boolean isActive() { 5154 return mActive; 5155 } 5156 5157 @Override 5158 public long getUserTime(int which) { 5159 long val = mUserTime; 5160 if (which == STATS_CURRENT) { 5161 val -= mLoadedUserTime; 5162 } else if (which == STATS_SINCE_UNPLUGGED) { 5163 val -= mUnpluggedUserTime; 5164 } 5165 return val; 5166 } 5167 5168 @Override 5169 public long getSystemTime(int which) { 5170 long val = mSystemTime; 5171 if (which == STATS_CURRENT) { 5172 val -= mLoadedSystemTime; 5173 } else if (which == STATS_SINCE_UNPLUGGED) { 5174 val -= mUnpluggedSystemTime; 5175 } 5176 return val; 5177 } 5178 5179 @Override 5180 public long getForegroundTime(int which) { 5181 long val = mForegroundTime; 5182 if (which == STATS_CURRENT) { 5183 val -= mLoadedForegroundTime; 5184 } else if (which == STATS_SINCE_UNPLUGGED) { 5185 val -= mUnpluggedForegroundTime; 5186 } 5187 return val; 5188 } 5189 5190 @Override 5191 public int getStarts(int which) { 5192 int val = mStarts; 5193 if (which == STATS_CURRENT) { 5194 val -= mLoadedStarts; 5195 } else if (which == STATS_SINCE_UNPLUGGED) { 5196 val -= mUnpluggedStarts; 5197 } 5198 return val; 5199 } 5200 5201 /* Called by ActivityManagerService when CPU times are updated. */ 5202 public void addSpeedStepTimes(long[] values) { 5203 for (int i = 0; i < mSpeedBins.length && i < values.length; i++) { 5204 long amt = values[i]; 5205 if (amt != 0) { 5206 SamplingCounter c = mSpeedBins[i]; 5207 if (c == null) { 5208 mSpeedBins[i] = c = new SamplingCounter(mOnBatteryTimeBase); 5209 } 5210 c.addCountAtomic(values[i]); 5211 } 5212 } 5213 } 5214 5215 @Override 5216 public long getTimeAtCpuSpeedStep(int speedStep, int which) { 5217 if (speedStep < mSpeedBins.length) { 5218 SamplingCounter c = mSpeedBins[speedStep]; 5219 return c != null ? c.getCountLocked(which) : 0; 5220 } else { 5221 return 0; 5222 } 5223 } 5224 } 5225 5226 /** 5227 * The statistics associated with a particular package. 5228 */ 5229 public final class Pkg extends BatteryStats.Uid.Pkg implements TimeBaseObs { 5230 /** 5231 * Number of times this package has done something that could wake up the 5232 * device from sleep. 5233 */ 5234 int mWakeups; 5235 5236 /** 5237 * Number of things that could wake up the device loaded from a 5238 * previous save. 5239 */ 5240 int mLoadedWakeups; 5241 5242 /** 5243 * Number of things that could wake up the device as of the 5244 * last run. 5245 */ 5246 int mLastWakeups; 5247 5248 /** 5249 * Number of things that could wake up the device as of the 5250 * last run. 5251 */ 5252 int mUnpluggedWakeups; 5253 5254 /** 5255 * The statics we have collected for this package's services. 5256 */ 5257 final HashMap<String, Serv> mServiceStats = new HashMap<String, Serv>(); 5258 5259 Pkg() { 5260 mOnBatteryScreenOffTimeBase.add(this); 5261 } 5262 5263 public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) { 5264 mUnpluggedWakeups = mWakeups; 5265 } 5266 5267 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) { 5268 } 5269 5270 void detach() { 5271 mOnBatteryScreenOffTimeBase.remove(this); 5272 } 5273 5274 void readFromParcelLocked(Parcel in) { 5275 mWakeups = in.readInt(); 5276 mLoadedWakeups = in.readInt(); 5277 mLastWakeups = 0; 5278 mUnpluggedWakeups = in.readInt(); 5279 5280 int numServs = in.readInt(); 5281 mServiceStats.clear(); 5282 for (int m = 0; m < numServs; m++) { 5283 String serviceName = in.readString(); 5284 Uid.Pkg.Serv serv = new Serv(); 5285 mServiceStats.put(serviceName, serv); 5286 5287 serv.readFromParcelLocked(in); 5288 } 5289 } 5290 5291 void writeToParcelLocked(Parcel out) { 5292 out.writeInt(mWakeups); 5293 out.writeInt(mLoadedWakeups); 5294 out.writeInt(mUnpluggedWakeups); 5295 5296 out.writeInt(mServiceStats.size()); 5297 for (Map.Entry<String, Uid.Pkg.Serv> servEntry : mServiceStats.entrySet()) { 5298 out.writeString(servEntry.getKey()); 5299 Uid.Pkg.Serv serv = servEntry.getValue(); 5300 5301 serv.writeToParcelLocked(out); 5302 } 5303 } 5304 5305 @Override 5306 public Map<String, ? extends BatteryStats.Uid.Pkg.Serv> getServiceStats() { 5307 return mServiceStats; 5308 } 5309 5310 @Override 5311 public int getWakeups(int which) { 5312 int val = mWakeups; 5313 if (which == STATS_CURRENT) { 5314 val -= mLoadedWakeups; 5315 } else if (which == STATS_SINCE_UNPLUGGED) { 5316 val -= mUnpluggedWakeups; 5317 } 5318 5319 return val; 5320 } 5321 5322 /** 5323 * The statistics associated with a particular service. 5324 */ 5325 public final class Serv extends BatteryStats.Uid.Pkg.Serv implements TimeBaseObs { 5326 /** 5327 * Total time (ms in battery uptime) the service has been left started. 5328 */ 5329 long mStartTime; 5330 5331 /** 5332 * If service has been started and not yet stopped, this is 5333 * when it was started. 5334 */ 5335 long mRunningSince; 5336 5337 /** 5338 * True if we are currently running. 5339 */ 5340 boolean mRunning; 5341 5342 /** 5343 * Total number of times startService() has been called. 5344 */ 5345 int mStarts; 5346 5347 /** 5348 * Total time (ms in battery uptime) the service has been left launched. 5349 */ 5350 long mLaunchedTime; 5351 5352 /** 5353 * If service has been launched and not yet exited, this is 5354 * when it was launched (ms in battery uptime). 5355 */ 5356 long mLaunchedSince; 5357 5358 /** 5359 * True if we are currently launched. 5360 */ 5361 boolean mLaunched; 5362 5363 /** 5364 * Total number times the service has been launched. 5365 */ 5366 int mLaunches; 5367 5368 /** 5369 * The amount of time spent started loaded from a previous save 5370 * (ms in battery uptime). 5371 */ 5372 long mLoadedStartTime; 5373 5374 /** 5375 * The number of starts loaded from a previous save. 5376 */ 5377 int mLoadedStarts; 5378 5379 /** 5380 * The number of launches loaded from a previous save. 5381 */ 5382 int mLoadedLaunches; 5383 5384 /** 5385 * The amount of time spent started as of the last run (ms 5386 * in battery uptime). 5387 */ 5388 long mLastStartTime; 5389 5390 /** 5391 * The number of starts as of the last run. 5392 */ 5393 int mLastStarts; 5394 5395 /** 5396 * The number of launches as of the last run. 5397 */ 5398 int mLastLaunches; 5399 5400 /** 5401 * The amount of time spent started when last unplugged (ms 5402 * in battery uptime). 5403 */ 5404 long mUnpluggedStartTime; 5405 5406 /** 5407 * The number of starts when last unplugged. 5408 */ 5409 int mUnpluggedStarts; 5410 5411 /** 5412 * The number of launches when last unplugged. 5413 */ 5414 int mUnpluggedLaunches; 5415 5416 Serv() { 5417 mOnBatteryTimeBase.add(this); 5418 } 5419 5420 public void onTimeStarted(long elapsedRealtime, long baseUptime, 5421 long baseRealtime) { 5422 mUnpluggedStartTime = getStartTimeToNowLocked(baseUptime); 5423 mUnpluggedStarts = mStarts; 5424 mUnpluggedLaunches = mLaunches; 5425 } 5426 5427 public void onTimeStopped(long elapsedRealtime, long baseUptime, 5428 long baseRealtime) { 5429 } 5430 5431 void detach() { 5432 mOnBatteryTimeBase.remove(this); 5433 } 5434 5435 void readFromParcelLocked(Parcel in) { 5436 mStartTime = in.readLong(); 5437 mRunningSince = in.readLong(); 5438 mRunning = in.readInt() != 0; 5439 mStarts = in.readInt(); 5440 mLaunchedTime = in.readLong(); 5441 mLaunchedSince = in.readLong(); 5442 mLaunched = in.readInt() != 0; 5443 mLaunches = in.readInt(); 5444 mLoadedStartTime = in.readLong(); 5445 mLoadedStarts = in.readInt(); 5446 mLoadedLaunches = in.readInt(); 5447 mLastStartTime = 0; 5448 mLastStarts = 0; 5449 mLastLaunches = 0; 5450 mUnpluggedStartTime = in.readLong(); 5451 mUnpluggedStarts = in.readInt(); 5452 mUnpluggedLaunches = in.readInt(); 5453 } 5454 5455 void writeToParcelLocked(Parcel out) { 5456 out.writeLong(mStartTime); 5457 out.writeLong(mRunningSince); 5458 out.writeInt(mRunning ? 1 : 0); 5459 out.writeInt(mStarts); 5460 out.writeLong(mLaunchedTime); 5461 out.writeLong(mLaunchedSince); 5462 out.writeInt(mLaunched ? 1 : 0); 5463 out.writeInt(mLaunches); 5464 out.writeLong(mLoadedStartTime); 5465 out.writeInt(mLoadedStarts); 5466 out.writeInt(mLoadedLaunches); 5467 out.writeLong(mUnpluggedStartTime); 5468 out.writeInt(mUnpluggedStarts); 5469 out.writeInt(mUnpluggedLaunches); 5470 } 5471 5472 long getLaunchTimeToNowLocked(long batteryUptime) { 5473 if (!mLaunched) return mLaunchedTime; 5474 return mLaunchedTime + batteryUptime - mLaunchedSince; 5475 } 5476 5477 long getStartTimeToNowLocked(long batteryUptime) { 5478 if (!mRunning) return mStartTime; 5479 return mStartTime + batteryUptime - mRunningSince; 5480 } 5481 5482 public void startLaunchedLocked() { 5483 if (!mLaunched) { 5484 mLaunches++; 5485 mLaunchedSince = getBatteryUptimeLocked(); 5486 mLaunched = true; 5487 } 5488 } 5489 5490 public void stopLaunchedLocked() { 5491 if (mLaunched) { 5492 long time = getBatteryUptimeLocked() - mLaunchedSince; 5493 if (time > 0) { 5494 mLaunchedTime += time; 5495 } else { 5496 mLaunches--; 5497 } 5498 mLaunched = false; 5499 } 5500 } 5501 5502 public void startRunningLocked() { 5503 if (!mRunning) { 5504 mStarts++; 5505 mRunningSince = getBatteryUptimeLocked(); 5506 mRunning = true; 5507 } 5508 } 5509 5510 public void stopRunningLocked() { 5511 if (mRunning) { 5512 long time = getBatteryUptimeLocked() - mRunningSince; 5513 if (time > 0) { 5514 mStartTime += time; 5515 } else { 5516 mStarts--; 5517 } 5518 mRunning = false; 5519 } 5520 } 5521 5522 public BatteryStatsImpl getBatteryStats() { 5523 return BatteryStatsImpl.this; 5524 } 5525 5526 @Override 5527 public int getLaunches(int which) { 5528 int val = mLaunches; 5529 if (which == STATS_CURRENT) { 5530 val -= mLoadedLaunches; 5531 } else if (which == STATS_SINCE_UNPLUGGED) { 5532 val -= mUnpluggedLaunches; 5533 } 5534 return val; 5535 } 5536 5537 @Override 5538 public long getStartTime(long now, int which) { 5539 long val = getStartTimeToNowLocked(now); 5540 if (which == STATS_CURRENT) { 5541 val -= mLoadedStartTime; 5542 } else if (which == STATS_SINCE_UNPLUGGED) { 5543 val -= mUnpluggedStartTime; 5544 } 5545 return val; 5546 } 5547 5548 @Override 5549 public int getStarts(int which) { 5550 int val = mStarts; 5551 if (which == STATS_CURRENT) { 5552 val -= mLoadedStarts; 5553 } else if (which == STATS_SINCE_UNPLUGGED) { 5554 val -= mUnpluggedStarts; 5555 } 5556 5557 return val; 5558 } 5559 } 5560 5561 public BatteryStatsImpl getBatteryStats() { 5562 return BatteryStatsImpl.this; 5563 } 5564 5565 public void incWakeupsLocked() { 5566 mWakeups++; 5567 } 5568 5569 final Serv newServiceStatsLocked() { 5570 return new Serv(); 5571 } 5572 } 5573 5574 /** 5575 * Retrieve the statistics object for a particular process, creating 5576 * if needed. 5577 */ 5578 public Proc getProcessStatsLocked(String name) { 5579 Proc ps = mProcessStats.get(name); 5580 if (ps == null) { 5581 ps = new Proc(); 5582 mProcessStats.put(name, ps); 5583 } 5584 5585 return ps; 5586 } 5587 5588 public void updateProcessStateLocked(String procName, int state, long elapsedRealtimeMs) { 5589 int procState; 5590 if (state <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 5591 procState = PROCESS_STATE_FOREGROUND; 5592 } else if (state <= ActivityManager.PROCESS_STATE_RECEIVER) { 5593 procState = PROCESS_STATE_ACTIVE; 5594 } else { 5595 procState = PROCESS_STATE_RUNNING; 5596 } 5597 updateRealProcessStateLocked(procName, procState, elapsedRealtimeMs); 5598 } 5599 5600 public void updateRealProcessStateLocked(String procName, int procState, 5601 long elapsedRealtimeMs) { 5602 Proc proc = getProcessStatsLocked(procName); 5603 if (proc.mProcessState != procState) { 5604 boolean changed; 5605 if (procState < proc.mProcessState) { 5606 // Has this process become more important? If so, 5607 // we may need to change the uid if the currrent uid proc state 5608 // is not as important as what we are now setting. 5609 changed = mProcessState > procState; 5610 } else { 5611 // Has this process become less important? If so, 5612 // we may need to change the uid if the current uid proc state 5613 // is the same importance as the old setting. 5614 changed = mProcessState == proc.mProcessState; 5615 } 5616 proc.mProcessState = procState; 5617 if (changed) { 5618 // uid's state may have changed; compute what the new state should be. 5619 int uidProcState = PROCESS_STATE_NONE; 5620 for (int ip=mProcessStats.size()-1; ip>=0; ip--) { 5621 proc = mProcessStats.valueAt(ip); 5622 if (proc.mProcessState < uidProcState) { 5623 uidProcState = proc.mProcessState; 5624 } 5625 } 5626 updateUidProcessStateLocked(uidProcState, elapsedRealtimeMs); 5627 } 5628 } 5629 } 5630 5631 public SparseArray<? extends Pid> getPidStats() { 5632 return mPids; 5633 } 5634 5635 public Pid getPidStatsLocked(int pid) { 5636 Pid p = mPids.get(pid); 5637 if (p == null) { 5638 p = new Pid(); 5639 mPids.put(pid, p); 5640 } 5641 return p; 5642 } 5643 5644 /** 5645 * Retrieve the statistics object for a particular service, creating 5646 * if needed. 5647 */ 5648 public Pkg getPackageStatsLocked(String name) { 5649 Pkg ps = mPackageStats.get(name); 5650 if (ps == null) { 5651 ps = new Pkg(); 5652 mPackageStats.put(name, ps); 5653 } 5654 5655 return ps; 5656 } 5657 5658 /** 5659 * Retrieve the statistics object for a particular service, creating 5660 * if needed. 5661 */ 5662 public Pkg.Serv getServiceStatsLocked(String pkg, String serv) { 5663 Pkg ps = getPackageStatsLocked(pkg); 5664 Pkg.Serv ss = ps.mServiceStats.get(serv); 5665 if (ss == null) { 5666 ss = ps.newServiceStatsLocked(); 5667 ps.mServiceStats.put(serv, ss); 5668 } 5669 5670 return ss; 5671 } 5672 5673 public StopwatchTimer getWakeTimerLocked(String name, int type) { 5674 Wakelock wl = mWakelockStats.get(name); 5675 if (wl == null) { 5676 final int N = mWakelockStats.size(); 5677 if (N > MAX_WAKELOCKS_PER_UID) { 5678 name = BATCHED_WAKELOCK_NAME; 5679 wl = mWakelockStats.get(name); 5680 } 5681 if (wl == null) { 5682 wl = new Wakelock(); 5683 mWakelockStats.put(name, wl); 5684 } 5685 } 5686 StopwatchTimer t = null; 5687 switch (type) { 5688 case WAKE_TYPE_PARTIAL: 5689 t = wl.mTimerPartial; 5690 if (t == null) { 5691 t = new StopwatchTimer(Uid.this, WAKE_TYPE_PARTIAL, 5692 mPartialTimers, mOnBatteryScreenOffTimeBase); 5693 wl.mTimerPartial = t; 5694 } 5695 return t; 5696 case WAKE_TYPE_FULL: 5697 t = wl.mTimerFull; 5698 if (t == null) { 5699 t = new StopwatchTimer(Uid.this, WAKE_TYPE_FULL, 5700 mFullTimers, mOnBatteryTimeBase); 5701 wl.mTimerFull = t; 5702 } 5703 return t; 5704 case WAKE_TYPE_WINDOW: 5705 t = wl.mTimerWindow; 5706 if (t == null) { 5707 t = new StopwatchTimer(Uid.this, WAKE_TYPE_WINDOW, 5708 mWindowTimers, mOnBatteryTimeBase); 5709 wl.mTimerWindow = t; 5710 } 5711 return t; 5712 default: 5713 throw new IllegalArgumentException("type=" + type); 5714 } 5715 } 5716 5717 public StopwatchTimer getSensorTimerLocked(int sensor, boolean create) { 5718 Sensor se = mSensorStats.get(sensor); 5719 if (se == null) { 5720 if (!create) { 5721 return null; 5722 } 5723 se = new Sensor(sensor); 5724 mSensorStats.put(sensor, se); 5725 } 5726 StopwatchTimer t = se.mTimer; 5727 if (t != null) { 5728 return t; 5729 } 5730 ArrayList<StopwatchTimer> timers = mSensorTimers.get(sensor); 5731 if (timers == null) { 5732 timers = new ArrayList<StopwatchTimer>(); 5733 mSensorTimers.put(sensor, timers); 5734 } 5735 t = new StopwatchTimer(Uid.this, BatteryStats.SENSOR, timers, mOnBatteryTimeBase); 5736 se.mTimer = t; 5737 return t; 5738 } 5739 5740 public void noteStartWakeLocked(int pid, String name, int type, long elapsedRealtimeMs) { 5741 StopwatchTimer t = getWakeTimerLocked(name, type); 5742 if (t != null) { 5743 t.startRunningLocked(elapsedRealtimeMs); 5744 } 5745 if (pid >= 0 && type == WAKE_TYPE_PARTIAL) { 5746 Pid p = getPidStatsLocked(pid); 5747 if (p.mWakeNesting++ == 0) { 5748 p.mWakeStartMs = elapsedRealtimeMs; 5749 } 5750 } 5751 } 5752 5753 public void noteStopWakeLocked(int pid, String name, int type, long elapsedRealtimeMs) { 5754 StopwatchTimer t = getWakeTimerLocked(name, type); 5755 if (t != null) { 5756 t.stopRunningLocked(elapsedRealtimeMs); 5757 } 5758 if (pid >= 0 && type == WAKE_TYPE_PARTIAL) { 5759 Pid p = mPids.get(pid); 5760 if (p != null && p.mWakeNesting > 0) { 5761 if (p.mWakeNesting-- == 1) { 5762 p.mWakeSumMs += elapsedRealtimeMs - p.mWakeStartMs; 5763 p.mWakeStartMs = 0; 5764 } 5765 } 5766 } 5767 } 5768 5769 public void reportExcessiveWakeLocked(String proc, long overTime, long usedTime) { 5770 Proc p = getProcessStatsLocked(proc); 5771 if (p != null) { 5772 p.addExcessiveWake(overTime, usedTime); 5773 } 5774 } 5775 5776 public void reportExcessiveCpuLocked(String proc, long overTime, long usedTime) { 5777 Proc p = getProcessStatsLocked(proc); 5778 if (p != null) { 5779 p.addExcessiveCpu(overTime, usedTime); 5780 } 5781 } 5782 5783 public void noteStartSensor(int sensor, long elapsedRealtimeMs) { 5784 StopwatchTimer t = getSensorTimerLocked(sensor, true); 5785 if (t != null) { 5786 t.startRunningLocked(elapsedRealtimeMs); 5787 } 5788 } 5789 5790 public void noteStopSensor(int sensor, long elapsedRealtimeMs) { 5791 // Don't create a timer if one doesn't already exist 5792 StopwatchTimer t = getSensorTimerLocked(sensor, false); 5793 if (t != null) { 5794 t.stopRunningLocked(elapsedRealtimeMs); 5795 } 5796 } 5797 5798 public void noteStartGps(long elapsedRealtimeMs) { 5799 StopwatchTimer t = getSensorTimerLocked(Sensor.GPS, true); 5800 if (t != null) { 5801 t.startRunningLocked(elapsedRealtimeMs); 5802 } 5803 } 5804 5805 public void noteStopGps(long elapsedRealtimeMs) { 5806 StopwatchTimer t = getSensorTimerLocked(Sensor.GPS, false); 5807 if (t != null) { 5808 t.stopRunningLocked(elapsedRealtimeMs); 5809 } 5810 } 5811 5812 public BatteryStatsImpl getBatteryStats() { 5813 return BatteryStatsImpl.this; 5814 } 5815 } 5816 5817 public BatteryStatsImpl(String filename, Handler handler) { 5818 mFile = new JournaledFile(new File(filename), new File(filename + ".tmp")); 5819 mHandler = new MyHandler(handler.getLooper()); 5820 mStartCount++; 5821 mScreenOnTimer = new StopwatchTimer(null, -1, null, mOnBatteryTimeBase); 5822 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 5823 mScreenBrightnessTimer[i] = new StopwatchTimer(null, -100-i, null, mOnBatteryTimeBase); 5824 } 5825 mInteractiveTimer = new StopwatchTimer(null, -9, null, mOnBatteryTimeBase); 5826 mLowPowerModeEnabledTimer = new StopwatchTimer(null, -2, null, mOnBatteryTimeBase); 5827 mPhoneOnTimer = new StopwatchTimer(null, -3, null, mOnBatteryTimeBase); 5828 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) { 5829 mPhoneSignalStrengthsTimer[i] = new StopwatchTimer(null, -200-i, null, 5830 mOnBatteryTimeBase); 5831 } 5832 mPhoneSignalScanningTimer = new StopwatchTimer(null, -200+1, null, mOnBatteryTimeBase); 5833 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 5834 mPhoneDataConnectionsTimer[i] = new StopwatchTimer(null, -300-i, null, 5835 mOnBatteryTimeBase); 5836 } 5837 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 5838 mNetworkByteActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase); 5839 mNetworkPacketActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase); 5840 } 5841 mMobileRadioActiveTimer = new StopwatchTimer(null, -400, null, mOnBatteryTimeBase); 5842 mMobileRadioActivePerAppTimer = new StopwatchTimer(null, -401, null, mOnBatteryTimeBase); 5843 mMobileRadioActiveAdjustedTime = new LongSamplingCounter(mOnBatteryTimeBase); 5844 mMobileRadioActiveUnknownTime = new LongSamplingCounter(mOnBatteryTimeBase); 5845 mMobileRadioActiveUnknownCount = new LongSamplingCounter(mOnBatteryTimeBase); 5846 mWifiOnTimer = new StopwatchTimer(null, -4, null, mOnBatteryTimeBase); 5847 mGlobalWifiRunningTimer = new StopwatchTimer(null, -5, null, mOnBatteryTimeBase); 5848 for (int i=0; i<NUM_WIFI_STATES; i++) { 5849 mWifiStateTimer[i] = new StopwatchTimer(null, -600-i, null, mOnBatteryTimeBase); 5850 } 5851 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) { 5852 mWifiSupplStateTimer[i] = new StopwatchTimer(null, -700-i, null, mOnBatteryTimeBase); 5853 } 5854 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { 5855 mWifiSignalStrengthsTimer[i] = new StopwatchTimer(null, -800-i, null, 5856 mOnBatteryTimeBase); 5857 } 5858 mBluetoothOnTimer = new StopwatchTimer(null, -6, null, mOnBatteryTimeBase); 5859 for (int i=0; i< NUM_BLUETOOTH_STATES; i++) { 5860 mBluetoothStateTimer[i] = new StopwatchTimer(null, -500-i, null, mOnBatteryTimeBase); 5861 } 5862 mAudioOnTimer = new StopwatchTimer(null, -7, null, mOnBatteryTimeBase); 5863 mVideoOnTimer = new StopwatchTimer(null, -8, null, mOnBatteryTimeBase); 5864 mFlashlightOnTimer = new StopwatchTimer(null, -9, null, mOnBatteryTimeBase); 5865 mOnBattery = mOnBatteryInternal = false; 5866 long uptime = SystemClock.uptimeMillis() * 1000; 5867 long realtime = SystemClock.elapsedRealtime() * 1000; 5868 initTimes(uptime, realtime); 5869 mDischargeStartLevel = 0; 5870 mDischargeUnplugLevel = 0; 5871 mDischargePlugLevel = -1; 5872 mDischargeCurrentLevel = 0; 5873 mCurrentBatteryLevel = 0; 5874 initDischarge(); 5875 clearHistoryLocked(); 5876 } 5877 5878 public BatteryStatsImpl(Parcel p) { 5879 mFile = null; 5880 mHandler = null; 5881 clearHistoryLocked(); 5882 readFromParcel(p); 5883 } 5884 5885 public void setCallback(BatteryCallback cb) { 5886 mCallback = cb; 5887 } 5888 5889 public void setNumSpeedSteps(int steps) { 5890 if (sNumSpeedSteps == 0) sNumSpeedSteps = steps; 5891 } 5892 5893 public void setRadioScanningTimeout(long timeout) { 5894 if (mPhoneSignalScanningTimer != null) { 5895 mPhoneSignalScanningTimer.setTimeout(timeout); 5896 } 5897 } 5898 5899 @Override 5900 public boolean startIteratingOldHistoryLocked() { 5901 if (DEBUG_HISTORY) Slog.i(TAG, "ITERATING: buff size=" + mHistoryBuffer.dataSize() 5902 + " pos=" + mHistoryBuffer.dataPosition()); 5903 if ((mHistoryIterator = mHistory) == null) { 5904 return false; 5905 } 5906 mHistoryBuffer.setDataPosition(0); 5907 mHistoryReadTmp.clear(); 5908 mReadOverflow = false; 5909 mIteratingHistory = true; 5910 return true; 5911 } 5912 5913 @Override 5914 public boolean getNextOldHistoryLocked(HistoryItem out) { 5915 boolean end = mHistoryBuffer.dataPosition() >= mHistoryBuffer.dataSize(); 5916 if (!end) { 5917 readHistoryDelta(mHistoryBuffer, mHistoryReadTmp); 5918 mReadOverflow |= mHistoryReadTmp.cmd == HistoryItem.CMD_OVERFLOW; 5919 } 5920 HistoryItem cur = mHistoryIterator; 5921 if (cur == null) { 5922 if (!mReadOverflow && !end) { 5923 Slog.w(TAG, "Old history ends before new history!"); 5924 } 5925 return false; 5926 } 5927 out.setTo(cur); 5928 mHistoryIterator = cur.next; 5929 if (!mReadOverflow) { 5930 if (end) { 5931 Slog.w(TAG, "New history ends before old history!"); 5932 } else if (!out.same(mHistoryReadTmp)) { 5933 PrintWriter pw = new FastPrintWriter(new LogWriter(android.util.Log.WARN, TAG)); 5934 pw.println("Histories differ!"); 5935 pw.println("Old history:"); 5936 (new HistoryPrinter()).printNextItem(pw, out, 0, false, true); 5937 pw.println("New history:"); 5938 (new HistoryPrinter()).printNextItem(pw, mHistoryReadTmp, 0, false, 5939 true); 5940 pw.flush(); 5941 } 5942 } 5943 return true; 5944 } 5945 5946 @Override 5947 public void finishIteratingOldHistoryLocked() { 5948 mIteratingHistory = false; 5949 mHistoryBuffer.setDataPosition(mHistoryBuffer.dataSize()); 5950 mHistoryIterator = null; 5951 } 5952 5953 public int getHistoryTotalSize() { 5954 return MAX_HISTORY_BUFFER; 5955 } 5956 5957 public int getHistoryUsedSize() { 5958 return mHistoryBuffer.dataSize(); 5959 } 5960 5961 @Override 5962 public boolean startIteratingHistoryLocked() { 5963 if (DEBUG_HISTORY) Slog.i(TAG, "ITERATING: buff size=" + mHistoryBuffer.dataSize() 5964 + " pos=" + mHistoryBuffer.dataPosition()); 5965 if (mHistoryBuffer.dataSize() <= 0) { 5966 return false; 5967 } 5968 mHistoryBuffer.setDataPosition(0); 5969 mReadOverflow = false; 5970 mIteratingHistory = true; 5971 mReadHistoryStrings = new String[mHistoryTagPool.size()]; 5972 mReadHistoryUids = new int[mHistoryTagPool.size()]; 5973 mReadHistoryChars = 0; 5974 for (HashMap.Entry<HistoryTag, Integer> ent : mHistoryTagPool.entrySet()) { 5975 final HistoryTag tag = ent.getKey(); 5976 final int idx = ent.getValue(); 5977 mReadHistoryStrings[idx] = tag.string; 5978 mReadHistoryUids[idx] = tag.uid; 5979 mReadHistoryChars += tag.string.length() + 1; 5980 } 5981 return true; 5982 } 5983 5984 @Override 5985 public int getHistoryStringPoolSize() { 5986 return mReadHistoryStrings.length; 5987 } 5988 5989 @Override 5990 public int getHistoryStringPoolBytes() { 5991 // Each entry is a fixed 12 bytes: 4 for index, 4 for uid, 4 for string size 5992 // Each string character is 2 bytes. 5993 return (mReadHistoryStrings.length * 12) + (mReadHistoryChars * 2); 5994 } 5995 5996 @Override 5997 public String getHistoryTagPoolString(int index) { 5998 return mReadHistoryStrings[index]; 5999 } 6000 6001 @Override 6002 public int getHistoryTagPoolUid(int index) { 6003 return mReadHistoryUids[index]; 6004 } 6005 6006 @Override 6007 public boolean getNextHistoryLocked(HistoryItem out) { 6008 final int pos = mHistoryBuffer.dataPosition(); 6009 if (pos == 0) { 6010 out.clear(); 6011 } 6012 boolean end = pos >= mHistoryBuffer.dataSize(); 6013 if (end) { 6014 return false; 6015 } 6016 6017 final long lastRealtime = out.time; 6018 final long lastWalltime = out.currentTime; 6019 readHistoryDelta(mHistoryBuffer, out); 6020 if (out.cmd != HistoryItem.CMD_CURRENT_TIME 6021 && out.cmd != HistoryItem.CMD_RESET && lastWalltime != 0) { 6022 out.currentTime = lastWalltime + (out.time - lastRealtime); 6023 } 6024 return true; 6025 } 6026 6027 @Override 6028 public void finishIteratingHistoryLocked() { 6029 mIteratingHistory = false; 6030 mHistoryBuffer.setDataPosition(mHistoryBuffer.dataSize()); 6031 mReadHistoryStrings = null; 6032 } 6033 6034 @Override 6035 public long getHistoryBaseTime() { 6036 return mHistoryBaseTime; 6037 } 6038 6039 @Override 6040 public int getStartCount() { 6041 return mStartCount; 6042 } 6043 6044 public boolean isOnBattery() { 6045 return mOnBattery; 6046 } 6047 6048 public boolean isScreenOn() { 6049 return mScreenState == Display.STATE_ON; 6050 } 6051 6052 void initTimes(long uptime, long realtime) { 6053 mStartClockTime = System.currentTimeMillis(); 6054 mOnBatteryTimeBase.init(uptime, realtime); 6055 mOnBatteryScreenOffTimeBase.init(uptime, realtime); 6056 mRealtime = 0; 6057 mUptime = 0; 6058 mRealtimeStart = realtime; 6059 mUptimeStart = uptime; 6060 } 6061 6062 void initDischarge() { 6063 mLowDischargeAmountSinceCharge = 0; 6064 mHighDischargeAmountSinceCharge = 0; 6065 mDischargeAmountScreenOn = 0; 6066 mDischargeAmountScreenOnSinceCharge = 0; 6067 mDischargeAmountScreenOff = 0; 6068 mDischargeAmountScreenOffSinceCharge = 0; 6069 mLastDischargeStepTime = -1; 6070 mNumDischargeStepDurations = 0; 6071 mLastChargeStepTime = -1; 6072 mNumChargeStepDurations = 0; 6073 } 6074 6075 public void resetAllStatsCmdLocked() { 6076 resetAllStatsLocked(); 6077 final long mSecUptime = SystemClock.uptimeMillis(); 6078 long uptime = mSecUptime * 1000; 6079 long mSecRealtime = SystemClock.elapsedRealtime(); 6080 long realtime = mSecRealtime * 1000; 6081 mDischargeStartLevel = mHistoryCur.batteryLevel; 6082 pullPendingStateUpdatesLocked(); 6083 addHistoryRecordLocked(mSecRealtime, mSecUptime); 6084 mDischargeCurrentLevel = mDischargeUnplugLevel = mDischargePlugLevel 6085 = mCurrentBatteryLevel = mHistoryCur.batteryLevel; 6086 mOnBatteryTimeBase.reset(uptime, realtime); 6087 mOnBatteryScreenOffTimeBase.reset(uptime, realtime); 6088 if ((mHistoryCur.states&HistoryItem.STATE_BATTERY_PLUGGED_FLAG) == 0) { 6089 if (mScreenState == Display.STATE_ON) { 6090 mDischargeScreenOnUnplugLevel = mHistoryCur.batteryLevel; 6091 mDischargeScreenOffUnplugLevel = 0; 6092 } else { 6093 mDischargeScreenOnUnplugLevel = 0; 6094 mDischargeScreenOffUnplugLevel = mHistoryCur.batteryLevel; 6095 } 6096 mDischargeAmountScreenOn = 0; 6097 mDischargeAmountScreenOff = 0; 6098 } 6099 initActiveHistoryEventsLocked(mSecRealtime, mSecUptime); 6100 } 6101 6102 private void resetAllStatsLocked() { 6103 mStartCount = 0; 6104 initTimes(SystemClock.uptimeMillis() * 1000, SystemClock.elapsedRealtime() * 1000); 6105 mScreenOnTimer.reset(false); 6106 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 6107 mScreenBrightnessTimer[i].reset(false); 6108 } 6109 mInteractiveTimer.reset(false); 6110 mLowPowerModeEnabledTimer.reset(false); 6111 mPhoneOnTimer.reset(false); 6112 mAudioOnTimer.reset(false); 6113 mVideoOnTimer.reset(false); 6114 mFlashlightOnTimer.reset(false); 6115 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) { 6116 mPhoneSignalStrengthsTimer[i].reset(false); 6117 } 6118 mPhoneSignalScanningTimer.reset(false); 6119 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 6120 mPhoneDataConnectionsTimer[i].reset(false); 6121 } 6122 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 6123 mNetworkByteActivityCounters[i].reset(false); 6124 mNetworkPacketActivityCounters[i].reset(false); 6125 } 6126 mMobileRadioActiveTimer.reset(false); 6127 mMobileRadioActivePerAppTimer.reset(false); 6128 mMobileRadioActiveAdjustedTime.reset(false); 6129 mMobileRadioActiveUnknownTime.reset(false); 6130 mMobileRadioActiveUnknownCount.reset(false); 6131 mWifiOnTimer.reset(false); 6132 mGlobalWifiRunningTimer.reset(false); 6133 for (int i=0; i<NUM_WIFI_STATES; i++) { 6134 mWifiStateTimer[i].reset(false); 6135 } 6136 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) { 6137 mWifiSupplStateTimer[i].reset(false); 6138 } 6139 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { 6140 mWifiSignalStrengthsTimer[i].reset(false); 6141 } 6142 mBluetoothOnTimer.reset(false); 6143 for (int i=0; i< NUM_BLUETOOTH_STATES; i++) { 6144 mBluetoothStateTimer[i].reset(false); 6145 } 6146 6147 for (int i=0; i<mUidStats.size(); i++) { 6148 if (mUidStats.valueAt(i).reset()) { 6149 mUidStats.remove(mUidStats.keyAt(i)); 6150 i--; 6151 } 6152 } 6153 6154 if (mKernelWakelockStats.size() > 0) { 6155 for (SamplingTimer timer : mKernelWakelockStats.values()) { 6156 mOnBatteryScreenOffTimeBase.remove(timer); 6157 } 6158 mKernelWakelockStats.clear(); 6159 } 6160 6161 if (mWakeupReasonStats.size() > 0) { 6162 for (LongSamplingCounter timer : mWakeupReasonStats.values()) { 6163 mOnBatteryScreenOffTimeBase.remove(timer); 6164 } 6165 mWakeupReasonStats.clear(); 6166 } 6167 6168 initDischarge(); 6169 6170 clearHistoryLocked(); 6171 } 6172 6173 private void initActiveHistoryEventsLocked(long elapsedRealtimeMs, long uptimeMs) { 6174 for (int i=0; i<HistoryItem.EVENT_COUNT; i++) { 6175 HashMap<String, SparseIntArray> active = mActiveEvents.getStateForEvent(i); 6176 if (active == null) { 6177 continue; 6178 } 6179 for (HashMap.Entry<String, SparseIntArray> ent : active.entrySet()) { 6180 SparseIntArray uids = ent.getValue(); 6181 for (int j=0; j<uids.size(); j++) { 6182 addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, i, ent.getKey(), 6183 uids.keyAt(j)); 6184 } 6185 } 6186 } 6187 } 6188 6189 void updateDischargeScreenLevelsLocked(boolean oldScreenOn, boolean newScreenOn) { 6190 if (oldScreenOn) { 6191 int diff = mDischargeScreenOnUnplugLevel - mDischargeCurrentLevel; 6192 if (diff > 0) { 6193 mDischargeAmountScreenOn += diff; 6194 mDischargeAmountScreenOnSinceCharge += diff; 6195 } 6196 } else { 6197 int diff = mDischargeScreenOffUnplugLevel - mDischargeCurrentLevel; 6198 if (diff > 0) { 6199 mDischargeAmountScreenOff += diff; 6200 mDischargeAmountScreenOffSinceCharge += diff; 6201 } 6202 } 6203 if (newScreenOn) { 6204 mDischargeScreenOnUnplugLevel = mDischargeCurrentLevel; 6205 mDischargeScreenOffUnplugLevel = 0; 6206 } else { 6207 mDischargeScreenOnUnplugLevel = 0; 6208 mDischargeScreenOffUnplugLevel = mDischargeCurrentLevel; 6209 } 6210 } 6211 6212 public void pullPendingStateUpdatesLocked() { 6213 updateKernelWakelocksLocked(); 6214 updateNetworkActivityLocked(NET_UPDATE_ALL, SystemClock.elapsedRealtime()); 6215 if (mOnBatteryInternal) { 6216 final boolean screenOn = mScreenState == Display.STATE_ON; 6217 updateDischargeScreenLevelsLocked(screenOn, screenOn); 6218 } 6219 } 6220 6221 void setOnBatteryLocked(final long mSecRealtime, final long mSecUptime, final boolean onBattery, 6222 final int oldStatus, final int level) { 6223 boolean doWrite = false; 6224 Message m = mHandler.obtainMessage(MSG_REPORT_POWER_CHANGE); 6225 m.arg1 = onBattery ? 1 : 0; 6226 mHandler.sendMessage(m); 6227 mOnBattery = mOnBatteryInternal = onBattery; 6228 6229 final long uptime = mSecUptime * 1000; 6230 final long realtime = mSecRealtime * 1000; 6231 final boolean screenOn = mScreenState == Display.STATE_ON; 6232 if (onBattery) { 6233 // We will reset our status if we are unplugging after the 6234 // battery was last full, or the level is at 100, or 6235 // we have gone through a significant charge (from a very low 6236 // level to a now very high level). 6237 boolean reset = false; 6238 if (!mNoAutoReset && (oldStatus == BatteryManager.BATTERY_STATUS_FULL 6239 || level >= 90 6240 || (mDischargeCurrentLevel < 20 && level >= 80))) { 6241 doWrite = true; 6242 resetAllStatsLocked(); 6243 mDischargeStartLevel = level; 6244 reset = true; 6245 mNumDischargeStepDurations = 0; 6246 } 6247 mLastDischargeStepLevel = level; 6248 mMinDischargeStepLevel = level; 6249 mLastDischargeStepTime = -1; 6250 pullPendingStateUpdatesLocked(); 6251 mHistoryCur.batteryLevel = (byte)level; 6252 mHistoryCur.states &= ~HistoryItem.STATE_BATTERY_PLUGGED_FLAG; 6253 if (DEBUG_HISTORY) Slog.v(TAG, "Battery unplugged to: " 6254 + Integer.toHexString(mHistoryCur.states)); 6255 if (reset) { 6256 mRecordingHistory = true; 6257 startRecordingHistory(mSecRealtime, mSecUptime, reset); 6258 } 6259 addHistoryRecordLocked(mSecRealtime, mSecUptime); 6260 mDischargeCurrentLevel = mDischargeUnplugLevel = level; 6261 if (screenOn) { 6262 mDischargeScreenOnUnplugLevel = level; 6263 mDischargeScreenOffUnplugLevel = 0; 6264 } else { 6265 mDischargeScreenOnUnplugLevel = 0; 6266 mDischargeScreenOffUnplugLevel = level; 6267 } 6268 mDischargeAmountScreenOn = 0; 6269 mDischargeAmountScreenOff = 0; 6270 updateTimeBasesLocked(true, !screenOn, uptime, realtime); 6271 } else { 6272 pullPendingStateUpdatesLocked(); 6273 mHistoryCur.batteryLevel = (byte)level; 6274 mHistoryCur.states |= HistoryItem.STATE_BATTERY_PLUGGED_FLAG; 6275 if (DEBUG_HISTORY) Slog.v(TAG, "Battery plugged to: " 6276 + Integer.toHexString(mHistoryCur.states)); 6277 addHistoryRecordLocked(mSecRealtime, mSecUptime); 6278 mDischargeCurrentLevel = mDischargePlugLevel = level; 6279 if (level < mDischargeUnplugLevel) { 6280 mLowDischargeAmountSinceCharge += mDischargeUnplugLevel-level-1; 6281 mHighDischargeAmountSinceCharge += mDischargeUnplugLevel-level; 6282 } 6283 updateDischargeScreenLevelsLocked(screenOn, screenOn); 6284 updateTimeBasesLocked(false, !screenOn, uptime, realtime); 6285 mNumChargeStepDurations = 0; 6286 mLastChargeStepLevel = level; 6287 mMaxChargeStepLevel = level; 6288 mLastChargeStepTime = -1; 6289 } 6290 if (doWrite || (mLastWriteTime + (60 * 1000)) < mSecRealtime) { 6291 if (mFile != null) { 6292 writeAsyncLocked(); 6293 } 6294 } 6295 } 6296 6297 private void startRecordingHistory(final long elapsedRealtimeMs, final long uptimeMs, 6298 boolean reset) { 6299 mRecordingHistory = true; 6300 mHistoryCur.currentTime = System.currentTimeMillis(); 6301 addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, 6302 reset ? HistoryItem.CMD_RESET : HistoryItem.CMD_CURRENT_TIME, 6303 mHistoryCur); 6304 mHistoryCur.currentTime = 0; 6305 if (reset) { 6306 initActiveHistoryEventsLocked(elapsedRealtimeMs, uptimeMs); 6307 } 6308 } 6309 6310 // This should probably be exposed in the API, though it's not critical 6311 private static final int BATTERY_PLUGGED_NONE = 0; 6312 6313 private static int addLevelSteps(long[] steps, int stepCount, long lastStepTime, 6314 int numStepLevels, long elapsedRealtime) { 6315 if (lastStepTime >= 0 && numStepLevels > 0) { 6316 long duration = elapsedRealtime - lastStepTime; 6317 for (int i=0; i<numStepLevels; i++) { 6318 System.arraycopy(steps, 0, steps, 1, steps.length-1); 6319 long thisDuration = duration / (numStepLevels-i); 6320 duration -= thisDuration; 6321 steps[0] = thisDuration; 6322 } 6323 stepCount += numStepLevels; 6324 if (stepCount > steps.length) { 6325 stepCount = steps.length; 6326 } 6327 } 6328 return stepCount; 6329 } 6330 6331 public void setBatteryState(int status, int health, int plugType, int level, 6332 int temp, int volt) { 6333 synchronized(this) { 6334 final boolean onBattery = plugType == BATTERY_PLUGGED_NONE; 6335 final long uptime = SystemClock.uptimeMillis(); 6336 final long elapsedRealtime = SystemClock.elapsedRealtime(); 6337 int oldStatus = mHistoryCur.batteryStatus; 6338 if (!mHaveBatteryLevel) { 6339 mHaveBatteryLevel = true; 6340 // We start out assuming that the device is plugged in (not 6341 // on battery). If our first report is now that we are indeed 6342 // plugged in, then twiddle our state to correctly reflect that 6343 // since we won't be going through the full setOnBattery(). 6344 if (onBattery == mOnBattery) { 6345 if (onBattery) { 6346 mHistoryCur.states &= ~HistoryItem.STATE_BATTERY_PLUGGED_FLAG; 6347 } else { 6348 mHistoryCur.states |= HistoryItem.STATE_BATTERY_PLUGGED_FLAG; 6349 } 6350 } 6351 oldStatus = status; 6352 } 6353 if (onBattery) { 6354 mDischargeCurrentLevel = level; 6355 if (!mRecordingHistory) { 6356 mRecordingHistory = true; 6357 startRecordingHistory(elapsedRealtime, uptime, true); 6358 } 6359 } else if (level < 96) { 6360 if (!mRecordingHistory) { 6361 mRecordingHistory = true; 6362 startRecordingHistory(elapsedRealtime, uptime, true); 6363 } 6364 } 6365 mCurrentBatteryLevel = level; 6366 if (mDischargePlugLevel < 0) { 6367 mDischargePlugLevel = level; 6368 } 6369 if (onBattery != mOnBattery) { 6370 mHistoryCur.batteryLevel = (byte)level; 6371 mHistoryCur.batteryStatus = (byte)status; 6372 mHistoryCur.batteryHealth = (byte)health; 6373 mHistoryCur.batteryPlugType = (byte)plugType; 6374 mHistoryCur.batteryTemperature = (short)temp; 6375 mHistoryCur.batteryVoltage = (char)volt; 6376 setOnBatteryLocked(elapsedRealtime, uptime, onBattery, oldStatus, level); 6377 } else { 6378 boolean changed = false; 6379 if (mHistoryCur.batteryLevel != level) { 6380 mHistoryCur.batteryLevel = (byte)level; 6381 changed = true; 6382 } 6383 if (mHistoryCur.batteryStatus != status) { 6384 mHistoryCur.batteryStatus = (byte)status; 6385 changed = true; 6386 } 6387 if (mHistoryCur.batteryHealth != health) { 6388 mHistoryCur.batteryHealth = (byte)health; 6389 changed = true; 6390 } 6391 if (mHistoryCur.batteryPlugType != plugType) { 6392 mHistoryCur.batteryPlugType = (byte)plugType; 6393 changed = true; 6394 } 6395 if (temp >= (mHistoryCur.batteryTemperature+10) 6396 || temp <= (mHistoryCur.batteryTemperature-10)) { 6397 mHistoryCur.batteryTemperature = (short)temp; 6398 changed = true; 6399 } 6400 if (volt > (mHistoryCur.batteryVoltage+20) 6401 || volt < (mHistoryCur.batteryVoltage-20)) { 6402 mHistoryCur.batteryVoltage = (char)volt; 6403 changed = true; 6404 } 6405 if (changed) { 6406 addHistoryRecordLocked(elapsedRealtime, uptime); 6407 } 6408 if (onBattery) { 6409 if (mLastDischargeStepLevel != level && mMinDischargeStepLevel > level) { 6410 mNumDischargeStepDurations = addLevelSteps(mDischargeStepDurations, 6411 mNumDischargeStepDurations, mLastDischargeStepTime, 6412 mLastDischargeStepLevel - level, elapsedRealtime); 6413 mLastDischargeStepLevel = level; 6414 mMinDischargeStepLevel = level; 6415 mLastDischargeStepTime = elapsedRealtime; 6416 } 6417 } else { 6418 if (mLastChargeStepLevel != level && mMaxChargeStepLevel < level) { 6419 mNumChargeStepDurations = addLevelSteps(mChargeStepDurations, 6420 mNumChargeStepDurations, mLastChargeStepTime, 6421 level - mLastChargeStepLevel, elapsedRealtime); 6422 mLastChargeStepLevel = level; 6423 mMaxChargeStepLevel = level; 6424 mLastChargeStepTime = elapsedRealtime; 6425 } 6426 } 6427 } 6428 if (!onBattery && status == BatteryManager.BATTERY_STATUS_FULL) { 6429 // We don't record history while we are plugged in and fully charged. 6430 // The next time we are unplugged, history will be cleared. 6431 mRecordingHistory = DEBUG; 6432 } 6433 } 6434 } 6435 6436 public void updateKernelWakelocksLocked() { 6437 Map<String, KernelWakelockStats> m = readKernelWakelockStats(); 6438 6439 if (m == null) { 6440 // Not crashing might make board bringup easier. 6441 Slog.w(TAG, "Couldn't get kernel wake lock stats"); 6442 return; 6443 } 6444 6445 for (Map.Entry<String, KernelWakelockStats> ent : m.entrySet()) { 6446 String name = ent.getKey(); 6447 KernelWakelockStats kws = ent.getValue(); 6448 6449 SamplingTimer kwlt = mKernelWakelockStats.get(name); 6450 if (kwlt == null) { 6451 kwlt = new SamplingTimer(mOnBatteryScreenOffTimeBase, 6452 true /* track reported val */); 6453 mKernelWakelockStats.put(name, kwlt); 6454 } 6455 kwlt.updateCurrentReportedCount(kws.mCount); 6456 kwlt.updateCurrentReportedTotalTime(kws.mTotalTime); 6457 kwlt.setUpdateVersion(sKernelWakelockUpdateVersion); 6458 } 6459 6460 if (m.size() != mKernelWakelockStats.size()) { 6461 // Set timers to stale if they didn't appear in /proc/wakelocks this time. 6462 for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) { 6463 SamplingTimer st = ent.getValue(); 6464 if (st.getUpdateVersion() != sKernelWakelockUpdateVersion) { 6465 st.setStale(); 6466 } 6467 } 6468 } 6469 } 6470 6471 static final int NET_UPDATE_MOBILE = 1<<0; 6472 static final int NET_UPDATE_WIFI = 1<<1; 6473 static final int NET_UPDATE_ALL = 0xffff; 6474 6475 private void updateNetworkActivityLocked(int which, long elapsedRealtimeMs) { 6476 if (!SystemProperties.getBoolean(PROP_QTAGUID_ENABLED, false)) return; 6477 6478 if ((which&NET_UPDATE_MOBILE) != 0 && mMobileIfaces.length > 0) { 6479 final NetworkStats snapshot; 6480 final NetworkStats last = mCurMobileSnapshot; 6481 try { 6482 snapshot = mNetworkStatsFactory.readNetworkStatsDetail(UID_ALL, 6483 mMobileIfaces, NetworkStats.TAG_NONE, mLastMobileSnapshot); 6484 } catch (IOException e) { 6485 Log.wtf(TAG, "Failed to read mobile network stats", e); 6486 return; 6487 } 6488 6489 mCurMobileSnapshot = snapshot; 6490 mLastMobileSnapshot = last; 6491 6492 if (mOnBatteryInternal) { 6493 final NetworkStats delta = NetworkStats.subtract(snapshot, last, 6494 null, null, mTmpNetworkStats); 6495 mTmpNetworkStats = delta; 6496 6497 long radioTime = mMobileRadioActivePerAppTimer.checkpointRunningLocked( 6498 elapsedRealtimeMs); 6499 long totalPackets = delta.getTotalPackets(); 6500 6501 final int size = delta.size(); 6502 for (int i = 0; i < size; i++) { 6503 final NetworkStats.Entry entry = delta.getValues(i, mTmpNetworkStatsEntry); 6504 6505 if (entry.rxBytes == 0 || entry.txBytes == 0) continue; 6506 6507 final Uid u = getUidStatsLocked(mapUid(entry.uid)); 6508 u.noteNetworkActivityLocked(NETWORK_MOBILE_RX_DATA, entry.rxBytes, 6509 entry.rxPackets); 6510 u.noteNetworkActivityLocked(NETWORK_MOBILE_TX_DATA, entry.txBytes, 6511 entry.txPackets); 6512 6513 if (radioTime > 0) { 6514 // Distribute total radio active time in to this app. 6515 long appPackets = entry.rxPackets + entry.txPackets; 6516 long appRadioTime = (radioTime*appPackets)/totalPackets; 6517 u.noteMobileRadioActiveTimeLocked(appRadioTime); 6518 // Remove this app from the totals, so that we don't lose any time 6519 // due to rounding. 6520 radioTime -= appRadioTime; 6521 totalPackets -= appPackets; 6522 } 6523 6524 mNetworkByteActivityCounters[NETWORK_MOBILE_RX_DATA].addCountLocked( 6525 entry.rxBytes); 6526 mNetworkByteActivityCounters[NETWORK_MOBILE_TX_DATA].addCountLocked( 6527 entry.txBytes); 6528 mNetworkPacketActivityCounters[NETWORK_MOBILE_RX_DATA].addCountLocked( 6529 entry.rxPackets); 6530 mNetworkPacketActivityCounters[NETWORK_MOBILE_TX_DATA].addCountLocked( 6531 entry.txPackets); 6532 } 6533 6534 if (radioTime > 0) { 6535 // Whoops, there is some radio time we can't blame on an app! 6536 mMobileRadioActiveUnknownTime.addCountLocked(radioTime); 6537 mMobileRadioActiveUnknownCount.addCountLocked(1); 6538 } 6539 } 6540 } 6541 6542 if ((which&NET_UPDATE_WIFI) != 0 && mWifiIfaces.length > 0) { 6543 final NetworkStats snapshot; 6544 final NetworkStats last = mCurWifiSnapshot; 6545 try { 6546 snapshot = mNetworkStatsFactory.readNetworkStatsDetail(UID_ALL, 6547 mWifiIfaces, NetworkStats.TAG_NONE, mLastWifiSnapshot); 6548 } catch (IOException e) { 6549 Log.wtf(TAG, "Failed to read wifi network stats", e); 6550 return; 6551 } 6552 6553 mCurWifiSnapshot = snapshot; 6554 mLastWifiSnapshot = last; 6555 6556 if (mOnBatteryInternal) { 6557 final NetworkStats delta = NetworkStats.subtract(snapshot, last, 6558 null, null, mTmpNetworkStats); 6559 mTmpNetworkStats = delta; 6560 6561 final int size = delta.size(); 6562 for (int i = 0; i < size; i++) { 6563 final NetworkStats.Entry entry = delta.getValues(i, mTmpNetworkStatsEntry); 6564 6565 if (DEBUG) { 6566 final NetworkStats.Entry cur = snapshot.getValues(i, null); 6567 Slog.d(TAG, "Wifi uid " + entry.uid + ": delta rx=" + entry.rxBytes 6568 + " tx=" + entry.txBytes + ", cur rx=" + cur.rxBytes 6569 + " tx=" + cur.txBytes); 6570 } 6571 6572 if (entry.rxBytes == 0 || entry.txBytes == 0) continue; 6573 6574 final Uid u = getUidStatsLocked(mapUid(entry.uid)); 6575 u.noteNetworkActivityLocked(NETWORK_WIFI_RX_DATA, entry.rxBytes, 6576 entry.rxPackets); 6577 u.noteNetworkActivityLocked(NETWORK_WIFI_TX_DATA, entry.txBytes, 6578 entry.txPackets); 6579 6580 mNetworkByteActivityCounters[NETWORK_WIFI_RX_DATA].addCountLocked( 6581 entry.rxBytes); 6582 mNetworkByteActivityCounters[NETWORK_WIFI_TX_DATA].addCountLocked( 6583 entry.txBytes); 6584 mNetworkPacketActivityCounters[NETWORK_WIFI_RX_DATA].addCountLocked( 6585 entry.rxPackets); 6586 mNetworkPacketActivityCounters[NETWORK_WIFI_TX_DATA].addCountLocked( 6587 entry.txPackets); 6588 } 6589 } 6590 } 6591 } 6592 6593 public long getAwakeTimeBattery() { 6594 return computeBatteryUptime(getBatteryUptimeLocked(), STATS_CURRENT); 6595 } 6596 6597 public long getAwakeTimePlugged() { 6598 return (SystemClock.uptimeMillis() * 1000) - getAwakeTimeBattery(); 6599 } 6600 6601 @Override 6602 public long computeUptime(long curTime, int which) { 6603 switch (which) { 6604 case STATS_SINCE_CHARGED: return mUptime + (curTime-mUptimeStart); 6605 case STATS_CURRENT: return (curTime-mUptimeStart); 6606 case STATS_SINCE_UNPLUGGED: return (curTime-mOnBatteryTimeBase.getUptimeStart()); 6607 } 6608 return 0; 6609 } 6610 6611 @Override 6612 public long computeRealtime(long curTime, int which) { 6613 switch (which) { 6614 case STATS_SINCE_CHARGED: return mRealtime + (curTime-mRealtimeStart); 6615 case STATS_CURRENT: return (curTime-mRealtimeStart); 6616 case STATS_SINCE_UNPLUGGED: return (curTime-mOnBatteryTimeBase.getRealtimeStart()); 6617 } 6618 return 0; 6619 } 6620 6621 @Override 6622 public long computeBatteryUptime(long curTime, int which) { 6623 return mOnBatteryTimeBase.computeUptime(curTime, which); 6624 } 6625 6626 @Override 6627 public long computeBatteryRealtime(long curTime, int which) { 6628 return mOnBatteryTimeBase.computeRealtime(curTime, which); 6629 } 6630 6631 @Override 6632 public long computeBatteryScreenOffUptime(long curTime, int which) { 6633 return mOnBatteryScreenOffTimeBase.computeUptime(curTime, which); 6634 } 6635 6636 @Override 6637 public long computeBatteryScreenOffRealtime(long curTime, int which) { 6638 return mOnBatteryScreenOffTimeBase.computeRealtime(curTime, which); 6639 } 6640 6641 private long computeTimePerLevel(long[] steps, int numSteps) { 6642 // For now we'll do a simple average across all steps. 6643 if (numSteps <= 0) { 6644 return -1; 6645 } 6646 long total = 0; 6647 for (int i=0; i<numSteps; i++) { 6648 total += steps[i]; 6649 } 6650 return total / numSteps; 6651 /* 6652 long[] buckets = new long[numSteps]; 6653 int numBuckets = 0; 6654 int numToAverage = 4; 6655 int i = 0; 6656 while (i < numSteps) { 6657 long totalTime = 0; 6658 int num = 0; 6659 for (int j=0; j<numToAverage && (i+j)<numSteps; j++) { 6660 totalTime += steps[i+j]; 6661 num++; 6662 } 6663 buckets[numBuckets] = totalTime / num; 6664 numBuckets++; 6665 numToAverage *= 2; 6666 i += num; 6667 } 6668 if (numBuckets < 1) { 6669 return -1; 6670 } 6671 long averageTime = buckets[numBuckets-1]; 6672 for (i=numBuckets-2; i>=0; i--) { 6673 averageTime = (averageTime + buckets[i]) / 2; 6674 } 6675 return averageTime; 6676 */ 6677 } 6678 6679 @Override 6680 public long computeBatteryTimeRemaining(long curTime) { 6681 if (!mOnBattery) { 6682 return -1; 6683 } 6684 /* Simple implementation just looks at the average discharge per level across the 6685 entire sample period. 6686 int discharge = (getLowDischargeAmountSinceCharge()+getHighDischargeAmountSinceCharge())/2; 6687 if (discharge < 2) { 6688 return -1; 6689 } 6690 long duration = computeBatteryRealtime(curTime, STATS_SINCE_CHARGED); 6691 if (duration < 1000*1000) { 6692 return -1; 6693 } 6694 long usPerLevel = duration/discharge; 6695 return usPerLevel * mCurrentBatteryLevel; 6696 */ 6697 if (mNumDischargeStepDurations < 1) { 6698 return -1; 6699 } 6700 long msPerLevel = computeTimePerLevel(mDischargeStepDurations, mNumDischargeStepDurations); 6701 if (msPerLevel <= 0) { 6702 return -1; 6703 } 6704 return (msPerLevel * mCurrentBatteryLevel) * 1000; 6705 } 6706 6707 public int getNumDischargeStepDurations() { 6708 return mNumDischargeStepDurations; 6709 } 6710 6711 public long[] getDischargeStepDurationsArray() { 6712 return mDischargeStepDurations; 6713 } 6714 6715 @Override 6716 public long computeChargeTimeRemaining(long curTime) { 6717 if (mOnBattery) { 6718 // Not yet working. 6719 return -1; 6720 } 6721 /* Broken 6722 int curLevel = mCurrentBatteryLevel; 6723 int plugLevel = mDischargePlugLevel; 6724 if (plugLevel < 0 || curLevel < (plugLevel+1)) { 6725 return -1; 6726 } 6727 long duration = computeBatteryRealtime(curTime, STATS_SINCE_UNPLUGGED); 6728 if (duration < 1000*1000) { 6729 return -1; 6730 } 6731 long usPerLevel = duration/(curLevel-plugLevel); 6732 return usPerLevel * (100-curLevel); 6733 */ 6734 if (mNumChargeStepDurations < 1) { 6735 return -1; 6736 } 6737 long msPerLevel = computeTimePerLevel(mChargeStepDurations, mNumChargeStepDurations); 6738 if (msPerLevel <= 0) { 6739 return -1; 6740 } 6741 return (msPerLevel * (100-mCurrentBatteryLevel)) * 1000; 6742 } 6743 6744 public int getNumChargeStepDurations() { 6745 return mNumChargeStepDurations; 6746 } 6747 6748 public long[] getChargeStepDurationsArray() { 6749 return mChargeStepDurations; 6750 } 6751 6752 long getBatteryUptimeLocked() { 6753 return mOnBatteryTimeBase.getUptime(SystemClock.uptimeMillis() * 1000); 6754 } 6755 6756 @Override 6757 public long getBatteryUptime(long curTime) { 6758 return mOnBatteryTimeBase.getUptime(curTime); 6759 } 6760 6761 @Override 6762 public long getBatteryRealtime(long curTime) { 6763 return mOnBatteryTimeBase.getRealtime(curTime); 6764 } 6765 6766 @Override 6767 public int getDischargeStartLevel() { 6768 synchronized(this) { 6769 return getDischargeStartLevelLocked(); 6770 } 6771 } 6772 6773 public int getDischargeStartLevelLocked() { 6774 return mDischargeUnplugLevel; 6775 } 6776 6777 @Override 6778 public int getDischargeCurrentLevel() { 6779 synchronized(this) { 6780 return getDischargeCurrentLevelLocked(); 6781 } 6782 } 6783 6784 public int getDischargeCurrentLevelLocked() { 6785 return mDischargeCurrentLevel; 6786 } 6787 6788 @Override 6789 public int getLowDischargeAmountSinceCharge() { 6790 synchronized(this) { 6791 int val = mLowDischargeAmountSinceCharge; 6792 if (mOnBattery && mDischargeCurrentLevel < mDischargeUnplugLevel) { 6793 val += mDischargeUnplugLevel-mDischargeCurrentLevel-1; 6794 } 6795 return val; 6796 } 6797 } 6798 6799 @Override 6800 public int getHighDischargeAmountSinceCharge() { 6801 synchronized(this) { 6802 int val = mHighDischargeAmountSinceCharge; 6803 if (mOnBattery && mDischargeCurrentLevel < mDischargeUnplugLevel) { 6804 val += mDischargeUnplugLevel-mDischargeCurrentLevel; 6805 } 6806 return val; 6807 } 6808 } 6809 6810 @Override 6811 public int getDischargeAmount(int which) { 6812 int dischargeAmount = which == STATS_SINCE_CHARGED 6813 ? getHighDischargeAmountSinceCharge() 6814 : (getDischargeStartLevel() - getDischargeCurrentLevel()); 6815 if (dischargeAmount < 0) { 6816 dischargeAmount = 0; 6817 } 6818 return dischargeAmount; 6819 } 6820 6821 public int getDischargeAmountScreenOn() { 6822 synchronized(this) { 6823 int val = mDischargeAmountScreenOn; 6824 if (mOnBattery && mScreenState == Display.STATE_ON 6825 && mDischargeCurrentLevel < mDischargeScreenOnUnplugLevel) { 6826 val += mDischargeScreenOnUnplugLevel-mDischargeCurrentLevel; 6827 } 6828 return val; 6829 } 6830 } 6831 6832 public int getDischargeAmountScreenOnSinceCharge() { 6833 synchronized(this) { 6834 int val = mDischargeAmountScreenOnSinceCharge; 6835 if (mOnBattery && mScreenState == Display.STATE_ON 6836 && mDischargeCurrentLevel < mDischargeScreenOnUnplugLevel) { 6837 val += mDischargeScreenOnUnplugLevel-mDischargeCurrentLevel; 6838 } 6839 return val; 6840 } 6841 } 6842 6843 public int getDischargeAmountScreenOff() { 6844 synchronized(this) { 6845 int val = mDischargeAmountScreenOff; 6846 if (mOnBattery && mScreenState != Display.STATE_ON 6847 && mDischargeCurrentLevel < mDischargeScreenOffUnplugLevel) { 6848 val += mDischargeScreenOffUnplugLevel-mDischargeCurrentLevel; 6849 } 6850 return val; 6851 } 6852 } 6853 6854 public int getDischargeAmountScreenOffSinceCharge() { 6855 synchronized(this) { 6856 int val = mDischargeAmountScreenOffSinceCharge; 6857 if (mOnBattery && mScreenState != Display.STATE_ON 6858 && mDischargeCurrentLevel < mDischargeScreenOffUnplugLevel) { 6859 val += mDischargeScreenOffUnplugLevel-mDischargeCurrentLevel; 6860 } 6861 return val; 6862 } 6863 } 6864 6865 @Override 6866 public int getCpuSpeedSteps() { 6867 return sNumSpeedSteps; 6868 } 6869 6870 /** 6871 * Retrieve the statistics object for a particular uid, creating if needed. 6872 */ 6873 public Uid getUidStatsLocked(int uid) { 6874 Uid u = mUidStats.get(uid); 6875 if (u == null) { 6876 u = new Uid(uid); 6877 mUidStats.put(uid, u); 6878 } 6879 return u; 6880 } 6881 6882 /** 6883 * Remove the statistics object for a particular uid. 6884 */ 6885 public void removeUidStatsLocked(int uid) { 6886 mUidStats.remove(uid); 6887 } 6888 6889 /** 6890 * Retrieve the statistics object for a particular process, creating 6891 * if needed. 6892 */ 6893 public Uid.Proc getProcessStatsLocked(int uid, String name) { 6894 uid = mapUid(uid); 6895 Uid u = getUidStatsLocked(uid); 6896 return u.getProcessStatsLocked(name); 6897 } 6898 6899 /** 6900 * Retrieve the statistics object for a particular process, creating 6901 * if needed. 6902 */ 6903 public Uid.Pkg getPackageStatsLocked(int uid, String pkg) { 6904 uid = mapUid(uid); 6905 Uid u = getUidStatsLocked(uid); 6906 return u.getPackageStatsLocked(pkg); 6907 } 6908 6909 /** 6910 * Retrieve the statistics object for a particular service, creating 6911 * if needed. 6912 */ 6913 public Uid.Pkg.Serv getServiceStatsLocked(int uid, String pkg, String name) { 6914 uid = mapUid(uid); 6915 Uid u = getUidStatsLocked(uid); 6916 return u.getServiceStatsLocked(pkg, name); 6917 } 6918 6919 /** 6920 * Massage data to distribute any reasonable work down to more specific 6921 * owners. Must only be called on a dead BatteryStats object! 6922 */ 6923 public void distributeWorkLocked(int which) { 6924 // Aggregate all CPU time associated with WIFI. 6925 Uid wifiUid = mUidStats.get(Process.WIFI_UID); 6926 if (wifiUid != null) { 6927 long uSecTime = computeBatteryRealtime(SystemClock.elapsedRealtime() * 1000, which); 6928 for (int ip=wifiUid.mProcessStats.size()-1; ip>=0; ip--) { 6929 Uid.Proc proc = wifiUid.mProcessStats.valueAt(ip); 6930 long totalRunningTime = getGlobalWifiRunningTime(uSecTime, which); 6931 for (int i=0; i<mUidStats.size(); i++) { 6932 Uid uid = mUidStats.valueAt(i); 6933 if (uid.mUid != Process.WIFI_UID) { 6934 long uidRunningTime = uid.getWifiRunningTime(uSecTime, which); 6935 if (uidRunningTime > 0) { 6936 Uid.Proc uidProc = uid.getProcessStatsLocked("*wifi*"); 6937 long time = proc.getUserTime(which); 6938 time = (time*uidRunningTime)/totalRunningTime; 6939 uidProc.mUserTime += time; 6940 proc.mUserTime -= time; 6941 time = proc.getSystemTime(which); 6942 time = (time*uidRunningTime)/totalRunningTime; 6943 uidProc.mSystemTime += time; 6944 proc.mSystemTime -= time; 6945 time = proc.getForegroundTime(which); 6946 time = (time*uidRunningTime)/totalRunningTime; 6947 uidProc.mForegroundTime += time; 6948 proc.mForegroundTime -= time; 6949 for (int sb=0; sb<proc.mSpeedBins.length; sb++) { 6950 SamplingCounter sc = proc.mSpeedBins[sb]; 6951 if (sc != null) { 6952 time = sc.getCountLocked(which); 6953 time = (time*uidRunningTime)/totalRunningTime; 6954 SamplingCounter uidSc = uidProc.mSpeedBins[sb]; 6955 if (uidSc == null) { 6956 uidSc = new SamplingCounter(mOnBatteryTimeBase); 6957 uidProc.mSpeedBins[sb] = uidSc; 6958 } 6959 uidSc.mCount.addAndGet((int)time); 6960 sc.mCount.addAndGet((int)-time); 6961 } 6962 } 6963 totalRunningTime -= uidRunningTime; 6964 } 6965 } 6966 } 6967 } 6968 } 6969 } 6970 6971 public void shutdownLocked() { 6972 writeSyncLocked(); 6973 mShuttingDown = true; 6974 } 6975 6976 Parcel mPendingWrite = null; 6977 final ReentrantLock mWriteLock = new ReentrantLock(); 6978 6979 public void writeAsyncLocked() { 6980 writeLocked(false); 6981 } 6982 6983 public void writeSyncLocked() { 6984 writeLocked(true); 6985 } 6986 6987 void writeLocked(boolean sync) { 6988 if (mFile == null) { 6989 Slog.w("BatteryStats", "writeLocked: no file associated with this instance"); 6990 return; 6991 } 6992 6993 if (mShuttingDown) { 6994 return; 6995 } 6996 6997 Parcel out = Parcel.obtain(); 6998 writeSummaryToParcel(out); 6999 mLastWriteTime = SystemClock.elapsedRealtime(); 7000 7001 if (mPendingWrite != null) { 7002 mPendingWrite.recycle(); 7003 } 7004 mPendingWrite = out; 7005 7006 if (sync) { 7007 commitPendingDataToDisk(); 7008 } else { 7009 Thread thr = new Thread("BatteryStats-Write") { 7010 @Override 7011 public void run() { 7012 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 7013 commitPendingDataToDisk(); 7014 } 7015 }; 7016 thr.start(); 7017 } 7018 } 7019 7020 public void commitPendingDataToDisk() { 7021 final Parcel next; 7022 synchronized (this) { 7023 next = mPendingWrite; 7024 mPendingWrite = null; 7025 if (next == null) { 7026 return; 7027 } 7028 7029 mWriteLock.lock(); 7030 } 7031 7032 try { 7033 FileOutputStream stream = new FileOutputStream(mFile.chooseForWrite()); 7034 stream.write(next.marshall()); 7035 stream.flush(); 7036 FileUtils.sync(stream); 7037 stream.close(); 7038 mFile.commit(); 7039 } catch (IOException e) { 7040 Slog.w("BatteryStats", "Error writing battery statistics", e); 7041 mFile.rollback(); 7042 } finally { 7043 next.recycle(); 7044 mWriteLock.unlock(); 7045 } 7046 } 7047 7048 static byte[] readFully(FileInputStream stream) throws java.io.IOException { 7049 int pos = 0; 7050 int avail = stream.available(); 7051 byte[] data = new byte[avail]; 7052 while (true) { 7053 int amt = stream.read(data, pos, data.length-pos); 7054 //Log.i("foo", "Read " + amt + " bytes at " + pos 7055 // + " of avail " + data.length); 7056 if (amt <= 0) { 7057 //Log.i("foo", "**** FINISHED READING: pos=" + pos 7058 // + " len=" + data.length); 7059 return data; 7060 } 7061 pos += amt; 7062 avail = stream.available(); 7063 if (avail > data.length-pos) { 7064 byte[] newData = new byte[pos+avail]; 7065 System.arraycopy(data, 0, newData, 0, pos); 7066 data = newData; 7067 } 7068 } 7069 } 7070 7071 public void readLocked() { 7072 if (mFile == null) { 7073 Slog.w("BatteryStats", "readLocked: no file associated with this instance"); 7074 return; 7075 } 7076 7077 mUidStats.clear(); 7078 7079 try { 7080 File file = mFile.chooseForRead(); 7081 if (!file.exists()) { 7082 return; 7083 } 7084 FileInputStream stream = new FileInputStream(file); 7085 7086 byte[] raw = readFully(stream); 7087 Parcel in = Parcel.obtain(); 7088 in.unmarshall(raw, 0, raw.length); 7089 in.setDataPosition(0); 7090 stream.close(); 7091 7092 readSummaryFromParcel(in); 7093 } catch(Exception e) { 7094 Slog.e("BatteryStats", "Error reading battery statistics", e); 7095 } 7096 7097 if (mHistoryBuffer.dataPosition() > 0) { 7098 mRecordingHistory = true; 7099 final long elapsedRealtime = SystemClock.elapsedRealtime(); 7100 final long uptime = SystemClock.uptimeMillis(); 7101 if (USE_OLD_HISTORY) { 7102 addHistoryRecordLocked(elapsedRealtime, uptime, HistoryItem.CMD_START, mHistoryCur); 7103 } 7104 addHistoryBufferLocked(elapsedRealtime, uptime, HistoryItem.CMD_START, mHistoryCur); 7105 startRecordingHistory(elapsedRealtime, uptime, false); 7106 } 7107 } 7108 7109 public int describeContents() { 7110 return 0; 7111 } 7112 7113 void readHistory(Parcel in, boolean andOldHistory) { 7114 final long historyBaseTime = in.readLong(); 7115 7116 mHistoryBuffer.setDataSize(0); 7117 mHistoryBuffer.setDataPosition(0); 7118 mHistoryTagPool.clear(); 7119 mNextHistoryTagIdx = 0; 7120 mNumHistoryTagChars = 0; 7121 7122 int numTags = in.readInt(); 7123 for (int i=0; i<numTags; i++) { 7124 int idx = in.readInt(); 7125 String str = in.readString(); 7126 int uid = in.readInt(); 7127 HistoryTag tag = new HistoryTag(); 7128 tag.string = str; 7129 tag.uid = uid; 7130 tag.poolIdx = idx; 7131 mHistoryTagPool.put(tag, idx); 7132 if (idx >= mNextHistoryTagIdx) { 7133 mNextHistoryTagIdx = idx+1; 7134 } 7135 mNumHistoryTagChars += tag.string.length() + 1; 7136 } 7137 7138 int bufSize = in.readInt(); 7139 int curPos = in.dataPosition(); 7140 if (bufSize >= (MAX_MAX_HISTORY_BUFFER*3)) { 7141 Slog.w(TAG, "File corrupt: history data buffer too large " + bufSize); 7142 } else if ((bufSize&~3) != bufSize) { 7143 Slog.w(TAG, "File corrupt: history data buffer not aligned " + bufSize); 7144 } else { 7145 if (DEBUG_HISTORY) Slog.i(TAG, "***************** READING NEW HISTORY: " + bufSize 7146 + " bytes at " + curPos); 7147 mHistoryBuffer.appendFrom(in, curPos, bufSize); 7148 in.setDataPosition(curPos + bufSize); 7149 } 7150 7151 if (andOldHistory) { 7152 readOldHistory(in); 7153 } 7154 7155 if (DEBUG_HISTORY) { 7156 StringBuilder sb = new StringBuilder(128); 7157 sb.append("****************** OLD mHistoryBaseTime: "); 7158 TimeUtils.formatDuration(mHistoryBaseTime, sb); 7159 Slog.i(TAG, sb.toString()); 7160 } 7161 mHistoryBaseTime = historyBaseTime; 7162 if (DEBUG_HISTORY) { 7163 StringBuilder sb = new StringBuilder(128); 7164 sb.append("****************** NEW mHistoryBaseTime: "); 7165 TimeUtils.formatDuration(mHistoryBaseTime, sb); 7166 Slog.i(TAG, sb.toString()); 7167 } 7168 7169 // We are just arbitrarily going to insert 1 minute from the sample of 7170 // the last run until samples in this run. 7171 if (mHistoryBaseTime > 0) { 7172 long oldnow = SystemClock.elapsedRealtime(); 7173 mHistoryBaseTime = (mHistoryBaseTime - oldnow) + 60*1000; 7174 if (DEBUG_HISTORY) { 7175 StringBuilder sb = new StringBuilder(128); 7176 sb.append("****************** ADJUSTED mHistoryBaseTime: "); 7177 TimeUtils.formatDuration(mHistoryBaseTime, sb); 7178 Slog.i(TAG, sb.toString()); 7179 } 7180 } 7181 } 7182 7183 void readOldHistory(Parcel in) { 7184 if (!USE_OLD_HISTORY) { 7185 return; 7186 } 7187 mHistory = mHistoryEnd = mHistoryCache = null; 7188 long time; 7189 while (in.dataAvail() > 0 && (time=in.readLong()) >= 0) { 7190 HistoryItem rec = new HistoryItem(time, in); 7191 addHistoryRecordLocked(rec); 7192 } 7193 } 7194 7195 void writeHistory(Parcel out, boolean andOldHistory) { 7196 if (DEBUG_HISTORY) { 7197 StringBuilder sb = new StringBuilder(128); 7198 sb.append("****************** WRITING mHistoryBaseTime: "); 7199 TimeUtils.formatDuration(mHistoryBaseTime, sb); 7200 sb.append(" mLastHistoryElapsedRealtime: "); 7201 TimeUtils.formatDuration(mLastHistoryElapsedRealtime, sb); 7202 Slog.i(TAG, sb.toString()); 7203 } 7204 out.writeLong(mHistoryBaseTime + mLastHistoryElapsedRealtime); 7205 out.writeInt(mHistoryTagPool.size()); 7206 for (HashMap.Entry<HistoryTag, Integer> ent : mHistoryTagPool.entrySet()) { 7207 HistoryTag tag = ent.getKey(); 7208 out.writeInt(ent.getValue()); 7209 out.writeString(tag.string); 7210 out.writeInt(tag.uid); 7211 } 7212 out.writeInt(mHistoryBuffer.dataSize()); 7213 if (DEBUG_HISTORY) Slog.i(TAG, "***************** WRITING HISTORY: " 7214 + mHistoryBuffer.dataSize() + " bytes at " + out.dataPosition()); 7215 out.appendFrom(mHistoryBuffer, 0, mHistoryBuffer.dataSize()); 7216 7217 if (andOldHistory) { 7218 writeOldHistory(out); 7219 } 7220 } 7221 7222 void writeOldHistory(Parcel out) { 7223 if (!USE_OLD_HISTORY) { 7224 return; 7225 } 7226 HistoryItem rec = mHistory; 7227 while (rec != null) { 7228 if (rec.time >= 0) rec.writeToParcel(out, 0); 7229 rec = rec.next; 7230 } 7231 out.writeLong(-1); 7232 } 7233 7234 private void readSummaryFromParcel(Parcel in) { 7235 final int version = in.readInt(); 7236 if (version != VERSION) { 7237 Slog.w("BatteryStats", "readFromParcel: version got " + version 7238 + ", expected " + VERSION + "; erasing old stats"); 7239 return; 7240 } 7241 7242 readHistory(in, true); 7243 7244 mStartCount = in.readInt(); 7245 mUptime = in.readLong(); 7246 mRealtime = in.readLong(); 7247 mStartClockTime = in.readLong(); 7248 mOnBatteryTimeBase.readSummaryFromParcel(in); 7249 mOnBatteryScreenOffTimeBase.readSummaryFromParcel(in); 7250 mDischargeUnplugLevel = in.readInt(); 7251 mDischargePlugLevel = in.readInt(); 7252 mDischargeCurrentLevel = in.readInt(); 7253 mCurrentBatteryLevel = in.readInt(); 7254 mLowDischargeAmountSinceCharge = in.readInt(); 7255 mHighDischargeAmountSinceCharge = in.readInt(); 7256 mDischargeAmountScreenOnSinceCharge = in.readInt(); 7257 mDischargeAmountScreenOffSinceCharge = in.readInt(); 7258 mNumDischargeStepDurations = in.readInt(); 7259 in.readLongArray(mDischargeStepDurations); 7260 mNumChargeStepDurations = in.readInt(); 7261 in.readLongArray(mChargeStepDurations); 7262 7263 mStartCount++; 7264 7265 mScreenState = Display.STATE_UNKNOWN; 7266 mScreenOnTimer.readSummaryFromParcelLocked(in); 7267 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 7268 mScreenBrightnessTimer[i].readSummaryFromParcelLocked(in); 7269 } 7270 mInteractive = false; 7271 mInteractiveTimer.readSummaryFromParcelLocked(in); 7272 mPhoneOn = false; 7273 mLowPowerModeEnabledTimer.readSummaryFromParcelLocked(in); 7274 mPhoneOnTimer.readSummaryFromParcelLocked(in); 7275 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) { 7276 mPhoneSignalStrengthsTimer[i].readSummaryFromParcelLocked(in); 7277 } 7278 mPhoneSignalScanningTimer.readSummaryFromParcelLocked(in); 7279 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 7280 mPhoneDataConnectionsTimer[i].readSummaryFromParcelLocked(in); 7281 } 7282 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 7283 mNetworkByteActivityCounters[i].readSummaryFromParcelLocked(in); 7284 mNetworkPacketActivityCounters[i].readSummaryFromParcelLocked(in); 7285 } 7286 mMobileRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW; 7287 mMobileRadioActiveTimer.readSummaryFromParcelLocked(in); 7288 mMobileRadioActivePerAppTimer.readSummaryFromParcelLocked(in); 7289 mMobileRadioActiveAdjustedTime.readSummaryFromParcelLocked(in); 7290 mMobileRadioActiveUnknownTime.readSummaryFromParcelLocked(in); 7291 mMobileRadioActiveUnknownCount.readSummaryFromParcelLocked(in); 7292 mWifiOn = false; 7293 mWifiOnTimer.readSummaryFromParcelLocked(in); 7294 mGlobalWifiRunning = false; 7295 mGlobalWifiRunningTimer.readSummaryFromParcelLocked(in); 7296 for (int i=0; i<NUM_WIFI_STATES; i++) { 7297 mWifiStateTimer[i].readSummaryFromParcelLocked(in); 7298 } 7299 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) { 7300 mWifiSupplStateTimer[i].readSummaryFromParcelLocked(in); 7301 } 7302 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { 7303 mWifiSignalStrengthsTimer[i].readSummaryFromParcelLocked(in); 7304 } 7305 mBluetoothOn = false; 7306 mBluetoothOnTimer.readSummaryFromParcelLocked(in); 7307 for (int i=0; i< NUM_BLUETOOTH_STATES; i++) { 7308 mBluetoothStateTimer[i].readSummaryFromParcelLocked(in); 7309 } 7310 mFlashlightOn = false; 7311 mFlashlightOnTimer.readSummaryFromParcelLocked(in); 7312 7313 int NKW = in.readInt(); 7314 if (NKW > 10000) { 7315 Slog.w(TAG, "File corrupt: too many kernel wake locks " + NKW); 7316 return; 7317 } 7318 for (int ikw = 0; ikw < NKW; ikw++) { 7319 if (in.readInt() != 0) { 7320 String kwltName = in.readString(); 7321 getKernelWakelockTimerLocked(kwltName).readSummaryFromParcelLocked(in); 7322 } 7323 } 7324 7325 int NWR = in.readInt(); 7326 if (NWR > 10000) { 7327 Slog.w(TAG, "File corrupt: too many wakeup reasons " + NWR); 7328 return; 7329 } 7330 for (int iwr = 0; iwr < NWR; iwr++) { 7331 if (in.readInt() != 0) { 7332 String reasonName = in.readString(); 7333 getWakeupReasonCounterLocked(reasonName).readSummaryFromParcelLocked(in); 7334 } 7335 } 7336 7337 sNumSpeedSteps = in.readInt(); 7338 if (sNumSpeedSteps < 0 || sNumSpeedSteps > 100) { 7339 throw new BadParcelableException("Bad speed steps in data: " + sNumSpeedSteps); 7340 } 7341 7342 final int NU = in.readInt(); 7343 if (NU > 10000) { 7344 Slog.w(TAG, "File corrupt: too many uids " + NU); 7345 return; 7346 } 7347 for (int iu = 0; iu < NU; iu++) { 7348 int uid = in.readInt(); 7349 Uid u = new Uid(uid); 7350 mUidStats.put(uid, u); 7351 7352 u.mWifiRunning = false; 7353 if (in.readInt() != 0) { 7354 u.mWifiRunningTimer.readSummaryFromParcelLocked(in); 7355 } 7356 u.mFullWifiLockOut = false; 7357 if (in.readInt() != 0) { 7358 u.mFullWifiLockTimer.readSummaryFromParcelLocked(in); 7359 } 7360 u.mWifiScanStarted = false; 7361 if (in.readInt() != 0) { 7362 u.mWifiScanTimer.readSummaryFromParcelLocked(in); 7363 } 7364 u.mWifiBatchedScanBinStarted = Uid.NO_BATCHED_SCAN_STARTED; 7365 for (int i = 0; i < Uid.NUM_WIFI_BATCHED_SCAN_BINS; i++) { 7366 if (in.readInt() != 0) { 7367 u.makeWifiBatchedScanBin(i, null); 7368 u.mWifiBatchedScanTimer[i].readSummaryFromParcelLocked(in); 7369 } 7370 } 7371 u.mWifiMulticastEnabled = false; 7372 if (in.readInt() != 0) { 7373 u.mWifiMulticastTimer.readSummaryFromParcelLocked(in); 7374 } 7375 u.mAudioTurnedOn = false; 7376 if (in.readInt() != 0) { 7377 u.createAudioTurnedOnTimerLocked().readSummaryFromParcelLocked(in); 7378 } 7379 u.mVideoTurnedOn = false; 7380 if (in.readInt() != 0) { 7381 u.createVideoTurnedOnTimerLocked().readSummaryFromParcelLocked(in); 7382 } 7383 if (in.readInt() != 0) { 7384 u.createForegroundActivityTimerLocked().readSummaryFromParcelLocked(in); 7385 } 7386 u.mProcessState = Uid.PROCESS_STATE_NONE; 7387 for (int i = 0; i < Uid.NUM_PROCESS_STATE; i++) { 7388 if (in.readInt() != 0) { 7389 u.makeProcessState(i, null); 7390 u.mProcessStateTimer[i].readSummaryFromParcelLocked(in); 7391 } 7392 } 7393 if (in.readInt() != 0) { 7394 u.createVibratorOnTimerLocked().readSummaryFromParcelLocked(in); 7395 } 7396 7397 if (in.readInt() != 0) { 7398 if (u.mUserActivityCounters == null) { 7399 u.initUserActivityLocked(); 7400 } 7401 for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) { 7402 u.mUserActivityCounters[i].readSummaryFromParcelLocked(in); 7403 } 7404 } 7405 7406 if (in.readInt() != 0) { 7407 if (u.mNetworkByteActivityCounters == null) { 7408 u.initNetworkActivityLocked(); 7409 } 7410 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 7411 u.mNetworkByteActivityCounters[i].readSummaryFromParcelLocked(in); 7412 u.mNetworkPacketActivityCounters[i].readSummaryFromParcelLocked(in); 7413 } 7414 u.mMobileRadioActiveTime.readSummaryFromParcelLocked(in); 7415 u.mMobileRadioActiveCount.readSummaryFromParcelLocked(in); 7416 } 7417 7418 int NW = in.readInt(); 7419 if (NW > 100) { 7420 Slog.w(TAG, "File corrupt: too many wake locks " + NW); 7421 return; 7422 } 7423 for (int iw = 0; iw < NW; iw++) { 7424 String wlName = in.readString(); 7425 if (in.readInt() != 0) { 7426 u.getWakeTimerLocked(wlName, WAKE_TYPE_FULL).readSummaryFromParcelLocked(in); 7427 } 7428 if (in.readInt() != 0) { 7429 u.getWakeTimerLocked(wlName, WAKE_TYPE_PARTIAL).readSummaryFromParcelLocked(in); 7430 } 7431 if (in.readInt() != 0) { 7432 u.getWakeTimerLocked(wlName, WAKE_TYPE_WINDOW).readSummaryFromParcelLocked(in); 7433 } 7434 } 7435 7436 int NP = in.readInt(); 7437 if (NP > 1000) { 7438 Slog.w(TAG, "File corrupt: too many sensors " + NP); 7439 return; 7440 } 7441 for (int is = 0; is < NP; is++) { 7442 int seNumber = in.readInt(); 7443 if (in.readInt() != 0) { 7444 u.getSensorTimerLocked(seNumber, true) 7445 .readSummaryFromParcelLocked(in); 7446 } 7447 } 7448 7449 NP = in.readInt(); 7450 if (NP > 1000) { 7451 Slog.w(TAG, "File corrupt: too many processes " + NP); 7452 return; 7453 } 7454 for (int ip = 0; ip < NP; ip++) { 7455 String procName = in.readString(); 7456 Uid.Proc p = u.getProcessStatsLocked(procName); 7457 p.mUserTime = p.mLoadedUserTime = in.readLong(); 7458 p.mSystemTime = p.mLoadedSystemTime = in.readLong(); 7459 p.mForegroundTime = p.mLoadedForegroundTime = in.readLong(); 7460 p.mStarts = p.mLoadedStarts = in.readInt(); 7461 int NSB = in.readInt(); 7462 if (NSB > 100) { 7463 Slog.w(TAG, "File corrupt: too many speed bins " + NSB); 7464 return; 7465 } 7466 p.mSpeedBins = new SamplingCounter[NSB]; 7467 for (int i=0; i<NSB; i++) { 7468 if (in.readInt() != 0) { 7469 p.mSpeedBins[i] = new SamplingCounter(mOnBatteryTimeBase); 7470 p.mSpeedBins[i].readSummaryFromParcelLocked(in); 7471 } 7472 } 7473 if (!p.readExcessivePowerFromParcelLocked(in)) { 7474 return; 7475 } 7476 } 7477 7478 NP = in.readInt(); 7479 if (NP > 10000) { 7480 Slog.w(TAG, "File corrupt: too many packages " + NP); 7481 return; 7482 } 7483 for (int ip = 0; ip < NP; ip++) { 7484 String pkgName = in.readString(); 7485 Uid.Pkg p = u.getPackageStatsLocked(pkgName); 7486 p.mWakeups = p.mLoadedWakeups = in.readInt(); 7487 final int NS = in.readInt(); 7488 if (NS > 1000) { 7489 Slog.w(TAG, "File corrupt: too many services " + NS); 7490 return; 7491 } 7492 for (int is = 0; is < NS; is++) { 7493 String servName = in.readString(); 7494 Uid.Pkg.Serv s = u.getServiceStatsLocked(pkgName, servName); 7495 s.mStartTime = s.mLoadedStartTime = in.readLong(); 7496 s.mStarts = s.mLoadedStarts = in.readInt(); 7497 s.mLaunches = s.mLoadedLaunches = in.readInt(); 7498 } 7499 } 7500 } 7501 } 7502 7503 /** 7504 * Writes a summary of the statistics to a Parcel, in a format suitable to be written to 7505 * disk. This format does not allow a lossless round-trip. 7506 * 7507 * @param out the Parcel to be written to. 7508 */ 7509 public void writeSummaryToParcel(Parcel out) { 7510 pullPendingStateUpdatesLocked(); 7511 7512 final long NOW_SYS = SystemClock.uptimeMillis() * 1000; 7513 final long NOWREAL_SYS = SystemClock.elapsedRealtime() * 1000; 7514 7515 out.writeInt(VERSION); 7516 7517 writeHistory(out, true); 7518 7519 out.writeInt(mStartCount); 7520 out.writeLong(computeUptime(NOW_SYS, STATS_SINCE_CHARGED)); 7521 out.writeLong(computeRealtime(NOWREAL_SYS, STATS_SINCE_CHARGED)); 7522 out.writeLong(mStartClockTime); 7523 mOnBatteryTimeBase.writeSummaryToParcel(out, NOW_SYS, NOWREAL_SYS); 7524 mOnBatteryScreenOffTimeBase.writeSummaryToParcel(out, NOW_SYS, NOWREAL_SYS); 7525 out.writeInt(mDischargeUnplugLevel); 7526 out.writeInt(mDischargePlugLevel); 7527 out.writeInt(mDischargeCurrentLevel); 7528 out.writeInt(mCurrentBatteryLevel); 7529 out.writeInt(getLowDischargeAmountSinceCharge()); 7530 out.writeInt(getHighDischargeAmountSinceCharge()); 7531 out.writeInt(getDischargeAmountScreenOnSinceCharge()); 7532 out.writeInt(getDischargeAmountScreenOffSinceCharge()); 7533 out.writeInt(mNumDischargeStepDurations); 7534 out.writeLongArray(mDischargeStepDurations); 7535 out.writeInt(mNumChargeStepDurations); 7536 out.writeLongArray(mChargeStepDurations); 7537 7538 mScreenOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 7539 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 7540 mScreenBrightnessTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS); 7541 } 7542 mInteractiveTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 7543 mLowPowerModeEnabledTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 7544 mPhoneOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 7545 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) { 7546 mPhoneSignalStrengthsTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS); 7547 } 7548 mPhoneSignalScanningTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 7549 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 7550 mPhoneDataConnectionsTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS); 7551 } 7552 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 7553 mNetworkByteActivityCounters[i].writeSummaryFromParcelLocked(out); 7554 mNetworkPacketActivityCounters[i].writeSummaryFromParcelLocked(out); 7555 } 7556 mMobileRadioActiveTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 7557 mMobileRadioActivePerAppTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 7558 mMobileRadioActiveAdjustedTime.writeSummaryFromParcelLocked(out); 7559 mMobileRadioActiveUnknownTime.writeSummaryFromParcelLocked(out); 7560 mMobileRadioActiveUnknownCount.writeSummaryFromParcelLocked(out); 7561 mWifiOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 7562 mGlobalWifiRunningTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 7563 for (int i=0; i<NUM_WIFI_STATES; i++) { 7564 mWifiStateTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS); 7565 } 7566 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) { 7567 mWifiSupplStateTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS); 7568 } 7569 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { 7570 mWifiSignalStrengthsTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS); 7571 } 7572 mBluetoothOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 7573 for (int i=0; i< NUM_BLUETOOTH_STATES; i++) { 7574 mBluetoothStateTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS); 7575 } 7576 mFlashlightOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 7577 7578 out.writeInt(mKernelWakelockStats.size()); 7579 for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) { 7580 Timer kwlt = ent.getValue(); 7581 if (kwlt != null) { 7582 out.writeInt(1); 7583 out.writeString(ent.getKey()); 7584 kwlt.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 7585 } else { 7586 out.writeInt(0); 7587 } 7588 } 7589 7590 out.writeInt(mWakeupReasonStats.size()); 7591 for (Map.Entry<String, LongSamplingCounter> ent : mWakeupReasonStats.entrySet()) { 7592 LongSamplingCounter counter = ent.getValue(); 7593 if (counter != null) { 7594 out.writeInt(1); 7595 out.writeString(ent.getKey()); 7596 counter.writeSummaryFromParcelLocked(out); 7597 } else { 7598 out.writeInt(0); 7599 } 7600 } 7601 7602 out.writeInt(sNumSpeedSteps); 7603 final int NU = mUidStats.size(); 7604 out.writeInt(NU); 7605 for (int iu = 0; iu < NU; iu++) { 7606 out.writeInt(mUidStats.keyAt(iu)); 7607 Uid u = mUidStats.valueAt(iu); 7608 7609 if (u.mWifiRunningTimer != null) { 7610 out.writeInt(1); 7611 u.mWifiRunningTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 7612 } else { 7613 out.writeInt(0); 7614 } 7615 if (u.mFullWifiLockTimer != null) { 7616 out.writeInt(1); 7617 u.mFullWifiLockTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 7618 } else { 7619 out.writeInt(0); 7620 } 7621 if (u.mWifiScanTimer != null) { 7622 out.writeInt(1); 7623 u.mWifiScanTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 7624 } else { 7625 out.writeInt(0); 7626 } 7627 for (int i = 0; i < Uid.NUM_WIFI_BATCHED_SCAN_BINS; i++) { 7628 if (u.mWifiBatchedScanTimer[i] != null) { 7629 out.writeInt(1); 7630 u.mWifiBatchedScanTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS); 7631 } else { 7632 out.writeInt(0); 7633 } 7634 } 7635 if (u.mWifiMulticastTimer != null) { 7636 out.writeInt(1); 7637 u.mWifiMulticastTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 7638 } else { 7639 out.writeInt(0); 7640 } 7641 if (u.mAudioTurnedOnTimer != null) { 7642 out.writeInt(1); 7643 u.mAudioTurnedOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 7644 } else { 7645 out.writeInt(0); 7646 } 7647 if (u.mVideoTurnedOnTimer != null) { 7648 out.writeInt(1); 7649 u.mVideoTurnedOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 7650 } else { 7651 out.writeInt(0); 7652 } 7653 if (u.mForegroundActivityTimer != null) { 7654 out.writeInt(1); 7655 u.mForegroundActivityTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 7656 } else { 7657 out.writeInt(0); 7658 } 7659 for (int i = 0; i < Uid.NUM_PROCESS_STATE; i++) { 7660 if (u.mProcessStateTimer[i] != null) { 7661 out.writeInt(1); 7662 u.mProcessStateTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS); 7663 } else { 7664 out.writeInt(0); 7665 } 7666 } 7667 if (u.mVibratorOnTimer != null) { 7668 out.writeInt(1); 7669 u.mVibratorOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 7670 } else { 7671 out.writeInt(0); 7672 } 7673 7674 if (u.mUserActivityCounters == null) { 7675 out.writeInt(0); 7676 } else { 7677 out.writeInt(1); 7678 for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) { 7679 u.mUserActivityCounters[i].writeSummaryFromParcelLocked(out); 7680 } 7681 } 7682 7683 if (u.mNetworkByteActivityCounters == null) { 7684 out.writeInt(0); 7685 } else { 7686 out.writeInt(1); 7687 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 7688 u.mNetworkByteActivityCounters[i].writeSummaryFromParcelLocked(out); 7689 u.mNetworkPacketActivityCounters[i].writeSummaryFromParcelLocked(out); 7690 } 7691 u.mMobileRadioActiveTime.writeSummaryFromParcelLocked(out); 7692 u.mMobileRadioActiveCount.writeSummaryFromParcelLocked(out); 7693 } 7694 7695 int NW = u.mWakelockStats.size(); 7696 out.writeInt(NW); 7697 for (int iw=0; iw<NW; iw++) { 7698 out.writeString(u.mWakelockStats.keyAt(iw)); 7699 Uid.Wakelock wl = u.mWakelockStats.valueAt(iw); 7700 if (wl.mTimerFull != null) { 7701 out.writeInt(1); 7702 wl.mTimerFull.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 7703 } else { 7704 out.writeInt(0); 7705 } 7706 if (wl.mTimerPartial != null) { 7707 out.writeInt(1); 7708 wl.mTimerPartial.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 7709 } else { 7710 out.writeInt(0); 7711 } 7712 if (wl.mTimerWindow != null) { 7713 out.writeInt(1); 7714 wl.mTimerWindow.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 7715 } else { 7716 out.writeInt(0); 7717 } 7718 } 7719 7720 int NSE = u.mSensorStats.size(); 7721 out.writeInt(NSE); 7722 for (int ise=0; ise<NSE; ise++) { 7723 out.writeInt(u.mSensorStats.keyAt(ise)); 7724 Uid.Sensor se = u.mSensorStats.valueAt(ise); 7725 if (se.mTimer != null) { 7726 out.writeInt(1); 7727 se.mTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); 7728 } else { 7729 out.writeInt(0); 7730 } 7731 } 7732 7733 int NP = u.mProcessStats.size(); 7734 out.writeInt(NP); 7735 for (int ip=0; ip<NP; ip++) { 7736 out.writeString(u.mProcessStats.keyAt(ip)); 7737 Uid.Proc ps = u.mProcessStats.valueAt(ip); 7738 out.writeLong(ps.mUserTime); 7739 out.writeLong(ps.mSystemTime); 7740 out.writeLong(ps.mForegroundTime); 7741 out.writeInt(ps.mStarts); 7742 final int N = ps.mSpeedBins.length; 7743 out.writeInt(N); 7744 for (int i=0; i<N; i++) { 7745 if (ps.mSpeedBins[i] != null) { 7746 out.writeInt(1); 7747 ps.mSpeedBins[i].writeSummaryFromParcelLocked(out); 7748 } else { 7749 out.writeInt(0); 7750 } 7751 } 7752 ps.writeExcessivePowerToParcelLocked(out); 7753 } 7754 7755 NP = u.mPackageStats.size(); 7756 out.writeInt(NP); 7757 if (NP > 0) { 7758 for (Map.Entry<String, BatteryStatsImpl.Uid.Pkg> ent 7759 : u.mPackageStats.entrySet()) { 7760 out.writeString(ent.getKey()); 7761 Uid.Pkg ps = ent.getValue(); 7762 out.writeInt(ps.mWakeups); 7763 final int NS = ps.mServiceStats.size(); 7764 out.writeInt(NS); 7765 if (NS > 0) { 7766 for (Map.Entry<String, BatteryStatsImpl.Uid.Pkg.Serv> sent 7767 : ps.mServiceStats.entrySet()) { 7768 out.writeString(sent.getKey()); 7769 BatteryStatsImpl.Uid.Pkg.Serv ss = sent.getValue(); 7770 long time = ss.getStartTimeToNowLocked( 7771 mOnBatteryTimeBase.getUptime(NOW_SYS)); 7772 out.writeLong(time); 7773 out.writeInt(ss.mStarts); 7774 out.writeInt(ss.mLaunches); 7775 } 7776 } 7777 } 7778 } 7779 } 7780 } 7781 7782 public void readFromParcel(Parcel in) { 7783 readFromParcelLocked(in); 7784 } 7785 7786 void readFromParcelLocked(Parcel in) { 7787 int magic = in.readInt(); 7788 if (magic != MAGIC) { 7789 throw new ParcelFormatException("Bad magic number"); 7790 } 7791 7792 readHistory(in, false); 7793 7794 mStartCount = in.readInt(); 7795 mStartClockTime = in.readLong(); 7796 mUptime = in.readLong(); 7797 mUptimeStart = in.readLong(); 7798 mRealtime = in.readLong(); 7799 mRealtimeStart = in.readLong(); 7800 mOnBattery = in.readInt() != 0; 7801 mOnBatteryInternal = false; // we are no longer really running. 7802 mOnBatteryTimeBase.readFromParcel(in); 7803 mOnBatteryScreenOffTimeBase.readFromParcel(in); 7804 7805 mScreenState = Display.STATE_UNKNOWN; 7806 mScreenOnTimer = new StopwatchTimer(null, -1, null, mOnBatteryTimeBase, in); 7807 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 7808 mScreenBrightnessTimer[i] = new StopwatchTimer(null, -100-i, null, mOnBatteryTimeBase, 7809 in); 7810 } 7811 mInteractive = false; 7812 mInteractiveTimer = new StopwatchTimer(null, -9, null, mOnBatteryTimeBase, in); 7813 mPhoneOn = false; 7814 mLowPowerModeEnabledTimer = new StopwatchTimer(null, -2, null, mOnBatteryTimeBase, in); 7815 mPhoneOnTimer = new StopwatchTimer(null, -3, null, mOnBatteryTimeBase, in); 7816 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) { 7817 mPhoneSignalStrengthsTimer[i] = new StopwatchTimer(null, -200-i, 7818 null, mOnBatteryTimeBase, in); 7819 } 7820 mPhoneSignalScanningTimer = new StopwatchTimer(null, -200+1, null, mOnBatteryTimeBase, in); 7821 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 7822 mPhoneDataConnectionsTimer[i] = new StopwatchTimer(null, -300-i, 7823 null, mOnBatteryTimeBase, in); 7824 } 7825 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 7826 mNetworkByteActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase, in); 7827 mNetworkPacketActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase, in); 7828 } 7829 mMobileRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW; 7830 mMobileRadioActiveTimer = new StopwatchTimer(null, -400, null, mOnBatteryTimeBase, in); 7831 mMobileRadioActivePerAppTimer = new StopwatchTimer(null, -401, null, mOnBatteryTimeBase, 7832 in); 7833 mMobileRadioActiveAdjustedTime = new LongSamplingCounter(mOnBatteryTimeBase, in); 7834 mMobileRadioActiveUnknownTime = new LongSamplingCounter(mOnBatteryTimeBase, in); 7835 mMobileRadioActiveUnknownCount = new LongSamplingCounter(mOnBatteryTimeBase, in); 7836 mWifiOn = false; 7837 mWifiOnTimer = new StopwatchTimer(null, -4, null, mOnBatteryTimeBase, in); 7838 mGlobalWifiRunning = false; 7839 mGlobalWifiRunningTimer = new StopwatchTimer(null, -5, null, mOnBatteryTimeBase, in); 7840 for (int i=0; i<NUM_WIFI_STATES; i++) { 7841 mWifiStateTimer[i] = new StopwatchTimer(null, -600-i, 7842 null, mOnBatteryTimeBase, in); 7843 } 7844 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) { 7845 mWifiSupplStateTimer[i] = new StopwatchTimer(null, -700-i, 7846 null, mOnBatteryTimeBase, in); 7847 } 7848 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { 7849 mWifiSignalStrengthsTimer[i] = new StopwatchTimer(null, -800-i, 7850 null, mOnBatteryTimeBase, in); 7851 } 7852 mBluetoothOn = false; 7853 mBluetoothOnTimer = new StopwatchTimer(null, -6, null, mOnBatteryTimeBase, in); 7854 for (int i=0; i< NUM_BLUETOOTH_STATES; i++) { 7855 mBluetoothStateTimer[i] = new StopwatchTimer(null, -500-i, 7856 null, mOnBatteryTimeBase, in); 7857 } 7858 mAudioOn = false; 7859 mAudioOnTimer = new StopwatchTimer(null, -7, null, mOnBatteryTimeBase); 7860 mVideoOn = false; 7861 mVideoOnTimer = new StopwatchTimer(null, -8, null, mOnBatteryTimeBase); 7862 mFlashlightOn = false; 7863 mFlashlightOnTimer = new StopwatchTimer(null, -9, null, mOnBatteryTimeBase, in); 7864 mDischargeUnplugLevel = in.readInt(); 7865 mDischargePlugLevel = in.readInt(); 7866 mDischargeCurrentLevel = in.readInt(); 7867 mCurrentBatteryLevel = in.readInt(); 7868 mLowDischargeAmountSinceCharge = in.readInt(); 7869 mHighDischargeAmountSinceCharge = in.readInt(); 7870 mDischargeAmountScreenOn = in.readInt(); 7871 mDischargeAmountScreenOnSinceCharge = in.readInt(); 7872 mDischargeAmountScreenOff = in.readInt(); 7873 mDischargeAmountScreenOffSinceCharge = in.readInt(); 7874 mNumDischargeStepDurations = in.readInt(); 7875 in.readLongArray(mDischargeStepDurations); 7876 mNumChargeStepDurations = in.readInt(); 7877 in.readLongArray(mChargeStepDurations); 7878 mLastWriteTime = in.readLong(); 7879 7880 mBluetoothPingCount = in.readInt(); 7881 mBluetoothPingStart = -1; 7882 7883 mKernelWakelockStats.clear(); 7884 int NKW = in.readInt(); 7885 for (int ikw = 0; ikw < NKW; ikw++) { 7886 if (in.readInt() != 0) { 7887 String wakelockName = in.readString(); 7888 SamplingTimer kwlt = new SamplingTimer(mOnBatteryTimeBase, in); 7889 mKernelWakelockStats.put(wakelockName, kwlt); 7890 } 7891 } 7892 7893 mWakeupReasonStats.clear(); 7894 int NWR = in.readInt(); 7895 for (int iwr = 0; iwr < NWR; iwr++) { 7896 if (in.readInt() != 0) { 7897 String reasonName = in.readString(); 7898 LongSamplingCounter counter = new LongSamplingCounter(mOnBatteryScreenOffTimeBase, 7899 in); 7900 mWakeupReasonStats.put(reasonName, counter); 7901 } 7902 } 7903 7904 mPartialTimers.clear(); 7905 mFullTimers.clear(); 7906 mWindowTimers.clear(); 7907 mWifiRunningTimers.clear(); 7908 mFullWifiLockTimers.clear(); 7909 mWifiScanTimers.clear(); 7910 mWifiBatchedScanTimers.clear(); 7911 mWifiMulticastTimers.clear(); 7912 7913 sNumSpeedSteps = in.readInt(); 7914 7915 int numUids = in.readInt(); 7916 mUidStats.clear(); 7917 for (int i = 0; i < numUids; i++) { 7918 int uid = in.readInt(); 7919 Uid u = new Uid(uid); 7920 u.readFromParcelLocked(mOnBatteryTimeBase, mOnBatteryScreenOffTimeBase, in); 7921 mUidStats.append(uid, u); 7922 } 7923 } 7924 7925 public void writeToParcel(Parcel out, int flags) { 7926 writeToParcelLocked(out, true, flags); 7927 } 7928 7929 public void writeToParcelWithoutUids(Parcel out, int flags) { 7930 writeToParcelLocked(out, false, flags); 7931 } 7932 7933 @SuppressWarnings("unused") 7934 void writeToParcelLocked(Parcel out, boolean inclUids, int flags) { 7935 // Need to update with current kernel wake lock counts. 7936 pullPendingStateUpdatesLocked(); 7937 7938 final long uSecUptime = SystemClock.uptimeMillis() * 1000; 7939 final long uSecRealtime = SystemClock.elapsedRealtime() * 1000; 7940 final long batteryRealtime = mOnBatteryTimeBase.getRealtime(uSecRealtime); 7941 final long batteryScreenOffRealtime = mOnBatteryScreenOffTimeBase.getRealtime(uSecRealtime); 7942 7943 out.writeInt(MAGIC); 7944 7945 writeHistory(out, false); 7946 7947 out.writeInt(mStartCount); 7948 out.writeLong(mStartClockTime); 7949 out.writeLong(mUptime); 7950 out.writeLong(mUptimeStart); 7951 out.writeLong(mRealtime); 7952 out.writeLong(mRealtimeStart); 7953 out.writeInt(mOnBattery ? 1 : 0); 7954 mOnBatteryTimeBase.writeToParcel(out, uSecUptime, uSecRealtime); 7955 mOnBatteryScreenOffTimeBase.writeToParcel(out, uSecUptime, uSecRealtime); 7956 7957 mScreenOnTimer.writeToParcel(out, uSecRealtime); 7958 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 7959 mScreenBrightnessTimer[i].writeToParcel(out, uSecRealtime); 7960 } 7961 mInteractiveTimer.writeToParcel(out, uSecRealtime); 7962 mLowPowerModeEnabledTimer.writeToParcel(out, uSecRealtime); 7963 mPhoneOnTimer.writeToParcel(out, uSecRealtime); 7964 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) { 7965 mPhoneSignalStrengthsTimer[i].writeToParcel(out, uSecRealtime); 7966 } 7967 mPhoneSignalScanningTimer.writeToParcel(out, uSecRealtime); 7968 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 7969 mPhoneDataConnectionsTimer[i].writeToParcel(out, uSecRealtime); 7970 } 7971 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 7972 mNetworkByteActivityCounters[i].writeToParcel(out); 7973 mNetworkPacketActivityCounters[i].writeToParcel(out); 7974 } 7975 mMobileRadioActiveTimer.writeToParcel(out, uSecRealtime); 7976 mMobileRadioActivePerAppTimer.writeToParcel(out, uSecRealtime); 7977 mMobileRadioActiveAdjustedTime.writeToParcel(out); 7978 mMobileRadioActiveUnknownTime.writeToParcel(out); 7979 mMobileRadioActiveUnknownCount.writeToParcel(out); 7980 mWifiOnTimer.writeToParcel(out, uSecRealtime); 7981 mGlobalWifiRunningTimer.writeToParcel(out, uSecRealtime); 7982 for (int i=0; i<NUM_WIFI_STATES; i++) { 7983 mWifiStateTimer[i].writeToParcel(out, uSecRealtime); 7984 } 7985 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) { 7986 mWifiSupplStateTimer[i].writeToParcel(out, uSecRealtime); 7987 } 7988 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { 7989 mWifiSignalStrengthsTimer[i].writeToParcel(out, uSecRealtime); 7990 } 7991 mBluetoothOnTimer.writeToParcel(out, uSecRealtime); 7992 for (int i=0; i< NUM_BLUETOOTH_STATES; i++) { 7993 mBluetoothStateTimer[i].writeToParcel(out, uSecRealtime); 7994 } 7995 mFlashlightOnTimer.writeToParcel(out, uSecRealtime); 7996 out.writeInt(mDischargeUnplugLevel); 7997 out.writeInt(mDischargePlugLevel); 7998 out.writeInt(mDischargeCurrentLevel); 7999 out.writeInt(mCurrentBatteryLevel); 8000 out.writeInt(mLowDischargeAmountSinceCharge); 8001 out.writeInt(mHighDischargeAmountSinceCharge); 8002 out.writeInt(mDischargeAmountScreenOn); 8003 out.writeInt(mDischargeAmountScreenOnSinceCharge); 8004 out.writeInt(mDischargeAmountScreenOff); 8005 out.writeInt(mDischargeAmountScreenOffSinceCharge); 8006 out.writeInt(mNumDischargeStepDurations); 8007 out.writeLongArray(mDischargeStepDurations); 8008 out.writeInt(mNumChargeStepDurations); 8009 out.writeLongArray(mChargeStepDurations); 8010 out.writeLong(mLastWriteTime); 8011 8012 out.writeInt(getBluetoothPingCount()); 8013 8014 if (inclUids) { 8015 out.writeInt(mKernelWakelockStats.size()); 8016 for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) { 8017 SamplingTimer kwlt = ent.getValue(); 8018 if (kwlt != null) { 8019 out.writeInt(1); 8020 out.writeString(ent.getKey()); 8021 kwlt.writeToParcel(out, uSecRealtime); 8022 } else { 8023 out.writeInt(0); 8024 } 8025 } 8026 out.writeInt(mWakeupReasonStats.size()); 8027 for (Map.Entry<String, LongSamplingCounter> ent : mWakeupReasonStats.entrySet()) { 8028 LongSamplingCounter counter = ent.getValue(); 8029 if (counter != null) { 8030 out.writeInt(1); 8031 out.writeString(ent.getKey()); 8032 counter.writeToParcel(out); 8033 } else { 8034 out.writeInt(0); 8035 } 8036 } 8037 } else { 8038 out.writeInt(0); 8039 } 8040 8041 out.writeInt(sNumSpeedSteps); 8042 8043 if (inclUids) { 8044 int size = mUidStats.size(); 8045 out.writeInt(size); 8046 for (int i = 0; i < size; i++) { 8047 out.writeInt(mUidStats.keyAt(i)); 8048 Uid uid = mUidStats.valueAt(i); 8049 8050 uid.writeToParcelLocked(out, uSecRealtime); 8051 } 8052 } else { 8053 out.writeInt(0); 8054 } 8055 } 8056 8057 public static final Parcelable.Creator<BatteryStatsImpl> CREATOR = 8058 new Parcelable.Creator<BatteryStatsImpl>() { 8059 public BatteryStatsImpl createFromParcel(Parcel in) { 8060 return new BatteryStatsImpl(in); 8061 } 8062 8063 public BatteryStatsImpl[] newArray(int size) { 8064 return new BatteryStatsImpl[size]; 8065 } 8066 }; 8067 8068 public void prepareForDumpLocked() { 8069 // Need to retrieve current kernel wake lock stats before printing. 8070 pullPendingStateUpdatesLocked(); 8071 } 8072 8073 public void dumpLocked(Context context, PrintWriter pw, int flags, int reqUid, long histStart) { 8074 if (DEBUG) { 8075 pw.println("mOnBatteryTimeBase:"); 8076 mOnBatteryTimeBase.dump(pw, " "); 8077 pw.println("mOnBatteryScreenOffTimeBase:"); 8078 mOnBatteryScreenOffTimeBase.dump(pw, " "); 8079 Printer pr = new PrintWriterPrinter(pw); 8080 pr.println("*** Screen timer:"); 8081 mScreenOnTimer.logState(pr, " "); 8082 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 8083 pr.println("*** Screen brightness #" + i + ":"); 8084 mScreenBrightnessTimer[i].logState(pr, " "); 8085 } 8086 pr.println("*** Interactive timer:"); 8087 mInteractiveTimer.logState(pr, " "); 8088 pr.println("*** Low power mode timer:"); 8089 mLowPowerModeEnabledTimer.logState(pr, " "); 8090 pr.println("*** Phone timer:"); 8091 mPhoneOnTimer.logState(pr, " "); 8092 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) { 8093 pr.println("*** Phone signal strength #" + i + ":"); 8094 mPhoneSignalStrengthsTimer[i].logState(pr, " "); 8095 } 8096 pr.println("*** Signal scanning :"); 8097 mPhoneSignalScanningTimer.logState(pr, " "); 8098 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 8099 pr.println("*** Data connection type #" + i + ":"); 8100 mPhoneDataConnectionsTimer[i].logState(pr, " "); 8101 } 8102 pr.println("*** mMobileRadioPowerState=" + mMobileRadioPowerState); 8103 pr.println("*** Mobile network active timer:"); 8104 mMobileRadioActiveTimer.logState(pr, " "); 8105 pr.println("*** Mobile network active adjusted timer:"); 8106 mMobileRadioActiveAdjustedTime.logState(pr, " "); 8107 pr.println("*** Wifi timer:"); 8108 mWifiOnTimer.logState(pr, " "); 8109 pr.println("*** WifiRunning timer:"); 8110 mGlobalWifiRunningTimer.logState(pr, " "); 8111 for (int i=0; i<NUM_WIFI_STATES; i++) { 8112 pr.println("*** Wifi state #" + i + ":"); 8113 mWifiStateTimer[i].logState(pr, " "); 8114 } 8115 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) { 8116 pr.println("*** Wifi suppl state #" + i + ":"); 8117 mWifiSupplStateTimer[i].logState(pr, " "); 8118 } 8119 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { 8120 pr.println("*** Wifi signal strength #" + i + ":"); 8121 mWifiSignalStrengthsTimer[i].logState(pr, " "); 8122 } 8123 pr.println("*** Bluetooth timer:"); 8124 mBluetoothOnTimer.logState(pr, " "); 8125 for (int i=0; i< NUM_BLUETOOTH_STATES; i++) { 8126 pr.println("*** Bluetooth active type #" + i + ":"); 8127 mBluetoothStateTimer[i].logState(pr, " "); 8128 } 8129 pr.println("*** Flashlight timer:"); 8130 mFlashlightOnTimer.logState(pr, " "); 8131 } 8132 super.dumpLocked(context, pw, flags, reqUid, histStart); 8133 } 8134} 8135