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