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