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