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