BatteryStatsImpl.java revision ae3844527a305cef8bbd1c895b79be45a6c51dbc
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 com.android.internal.util.JournaledFile; 20 21import android.bluetooth.BluetoothDevice; 22import android.bluetooth.BluetoothHeadset; 23import android.net.TrafficStats; 24import android.os.BatteryManager; 25import android.os.BatteryStats; 26import android.os.FileUtils; 27import android.os.Handler; 28import android.os.Message; 29import android.os.Parcel; 30import android.os.ParcelFormatException; 31import android.os.Parcelable; 32import android.os.Process; 33import android.os.SystemClock; 34import android.os.WorkSource; 35import android.telephony.ServiceState; 36import android.telephony.SignalStrength; 37import android.telephony.TelephonyManager; 38import android.util.Log; 39import android.util.LogWriter; 40import android.util.PrintWriterPrinter; 41import android.util.Printer; 42import android.util.Slog; 43import android.util.SparseArray; 44import android.util.TimeUtils; 45 46import java.io.BufferedReader; 47import java.io.File; 48import java.io.FileInputStream; 49import java.io.FileOutputStream; 50import java.io.FileReader; 51import java.io.IOException; 52import java.io.PrintWriter; 53import java.util.ArrayList; 54import java.util.HashMap; 55import java.util.Iterator; 56import java.util.List; 57import java.util.Map; 58import java.util.concurrent.atomic.AtomicInteger; 59import java.util.concurrent.locks.ReentrantLock; 60 61/** 62 * All information we are collecting about things that can happen that impact 63 * battery life. All times are represented in microseconds except where indicated 64 * otherwise. 65 */ 66public final class BatteryStatsImpl extends BatteryStats { 67 private static final String TAG = "BatteryStatsImpl"; 68 private static final boolean DEBUG = false; 69 private static final boolean DEBUG_HISTORY = false; 70 71 // In-memory Parcel magic number, used to detect attempts to unmarshall bad data 72 private static final int MAGIC = 0xBA757475; // 'BATSTATS' 73 74 // Current on-disk Parcel version 75 private static final int VERSION = 60; 76 77 // Maximum number of items we will record in the history. 78 private static final int MAX_HISTORY_ITEMS = 2000; 79 80 // No, really, THIS is the maximum number of items we will record in the history. 81 private static final int MAX_MAX_HISTORY_ITEMS = 3000; 82 83 // The maximum number of names wakelocks we will keep track of 84 // per uid; once the limit is reached, we batch the remaining wakelocks 85 // in to one common name. 86 private static final int MAX_WAKELOCKS_PER_UID = 30; 87 88 private static final String BATCHED_WAKELOCK_NAME = "*overflow*"; 89 90 private static int sNumSpeedSteps; 91 92 private final JournaledFile mFile; 93 94 static final int MSG_UPDATE_WAKELOCKS = 1; 95 static final int MSG_REPORT_POWER_CHANGE = 2; 96 static final long DELAY_UPDATE_WAKELOCKS = 5*1000; 97 98 public interface BatteryCallback { 99 public void batteryNeedsCpuUpdate(); 100 public void batteryPowerChanged(boolean onBattery); 101 } 102 103 final class MyHandler extends Handler { 104 @Override 105 public void handleMessage(Message msg) { 106 BatteryCallback cb = mCallback; 107 switch (msg.what) { 108 case MSG_UPDATE_WAKELOCKS: 109 if (cb != null) { 110 cb.batteryNeedsCpuUpdate(); 111 } 112 break; 113 case MSG_REPORT_POWER_CHANGE: 114 if (cb != null) { 115 cb.batteryPowerChanged(msg.arg1 != 0); 116 } 117 break; 118 } 119 } 120 } 121 122 private final MyHandler mHandler; 123 124 private BatteryCallback mCallback; 125 126 /** 127 * The statistics we have collected organized by uids. 128 */ 129 final SparseArray<BatteryStatsImpl.Uid> mUidStats = 130 new SparseArray<BatteryStatsImpl.Uid>(); 131 132 // A set of pools of currently active timers. When a timer is queried, we will divide the 133 // elapsed time by the number of active timers to arrive at that timer's share of the time. 134 // In order to do this, we must refresh each timer whenever the number of active timers 135 // changes. 136 final ArrayList<StopwatchTimer> mPartialTimers = new ArrayList<StopwatchTimer>(); 137 final ArrayList<StopwatchTimer> mFullTimers = new ArrayList<StopwatchTimer>(); 138 final ArrayList<StopwatchTimer> mWindowTimers = new ArrayList<StopwatchTimer>(); 139 final SparseArray<ArrayList<StopwatchTimer>> mSensorTimers 140 = new SparseArray<ArrayList<StopwatchTimer>>(); 141 final ArrayList<StopwatchTimer> mWifiRunningTimers = new ArrayList<StopwatchTimer>(); 142 final ArrayList<StopwatchTimer> mFullWifiLockTimers = new ArrayList<StopwatchTimer>(); 143 final ArrayList<StopwatchTimer> mScanWifiLockTimers = new ArrayList<StopwatchTimer>(); 144 final ArrayList<StopwatchTimer> mWifiMulticastTimers = new ArrayList<StopwatchTimer>(); 145 146 // Last partial timers we use for distributing CPU usage. 147 final ArrayList<StopwatchTimer> mLastPartialTimers = new ArrayList<StopwatchTimer>(); 148 149 // These are the objects that will want to do something when the device 150 // is unplugged from power. 151 final ArrayList<Unpluggable> mUnpluggables = new ArrayList<Unpluggable>(); 152 153 boolean mShuttingDown; 154 155 long mHistoryBaseTime; 156 boolean mHaveBatteryLevel = false; 157 boolean mRecordingHistory = true; 158 int mNumHistoryItems; 159 160 static final int MAX_HISTORY_BUFFER = 128*1024; // 128KB 161 static final int MAX_MAX_HISTORY_BUFFER = 144*1024; // 144KB 162 final Parcel mHistoryBuffer = Parcel.obtain(); 163 final HistoryItem mHistoryLastWritten = new HistoryItem(); 164 final HistoryItem mHistoryLastLastWritten = new HistoryItem(); 165 final HistoryItem mHistoryReadTmp = new HistoryItem(); 166 int mHistoryBufferLastPos = -1; 167 boolean mHistoryOverflow = false; 168 long mLastHistoryTime = 0; 169 170 final HistoryItem mHistoryCur = new HistoryItem(); 171 172 HistoryItem mHistory; 173 HistoryItem mHistoryEnd; 174 HistoryItem mHistoryLastEnd; 175 HistoryItem mHistoryCache; 176 177 private HistoryItem mHistoryIterator; 178 private boolean mReadOverflow; 179 private boolean mIteratingHistory; 180 181 int mStartCount; 182 183 long mBatteryUptime; 184 long mBatteryLastUptime; 185 long mBatteryRealtime; 186 long mBatteryLastRealtime; 187 188 long mUptime; 189 long mUptimeStart; 190 long mLastUptime; 191 long mRealtime; 192 long mRealtimeStart; 193 long mLastRealtime; 194 195 boolean mScreenOn; 196 StopwatchTimer mScreenOnTimer; 197 198 int mScreenBrightnessBin = -1; 199 final StopwatchTimer[] mScreenBrightnessTimer = new StopwatchTimer[NUM_SCREEN_BRIGHTNESS_BINS]; 200 201 Counter mInputEventCounter; 202 203 boolean mPhoneOn; 204 StopwatchTimer mPhoneOnTimer; 205 206 boolean mAudioOn; 207 StopwatchTimer mAudioOnTimer; 208 209 boolean mVideoOn; 210 StopwatchTimer mVideoOnTimer; 211 212 int mPhoneSignalStrengthBin = -1; 213 int mPhoneSignalStrengthBinRaw = -1; 214 final StopwatchTimer[] mPhoneSignalStrengthsTimer = 215 new StopwatchTimer[SignalStrength.NUM_SIGNAL_STRENGTH_BINS]; 216 217 StopwatchTimer mPhoneSignalScanningTimer; 218 219 int mPhoneDataConnectionType = -1; 220 final StopwatchTimer[] mPhoneDataConnectionsTimer = 221 new StopwatchTimer[NUM_DATA_CONNECTION_TYPES]; 222 223 boolean mWifiOn; 224 StopwatchTimer mWifiOnTimer; 225 int mWifiOnUid = -1; 226 227 boolean mGlobalWifiRunning; 228 StopwatchTimer mGlobalWifiRunningTimer; 229 230 boolean mBluetoothOn; 231 StopwatchTimer mBluetoothOnTimer; 232 233 /** Bluetooth headset object */ 234 BluetoothHeadset mBtHeadset; 235 236 /** 237 * These provide time bases that discount the time the device is plugged 238 * in to power. 239 */ 240 boolean mOnBattery; 241 boolean mOnBatteryInternal; 242 long mTrackBatteryPastUptime; 243 long mTrackBatteryUptimeStart; 244 long mTrackBatteryPastRealtime; 245 long mTrackBatteryRealtimeStart; 246 247 long mUnpluggedBatteryUptime; 248 long mUnpluggedBatteryRealtime; 249 250 /* 251 * These keep track of battery levels (1-100) at the last plug event and the last unplug event. 252 */ 253 int mDischargeStartLevel; 254 int mDischargeUnplugLevel; 255 int mDischargeCurrentLevel; 256 int mLowDischargeAmountSinceCharge; 257 int mHighDischargeAmountSinceCharge; 258 int mDischargeScreenOnUnplugLevel; 259 int mDischargeScreenOffUnplugLevel; 260 int mDischargeAmountScreenOn; 261 int mDischargeAmountScreenOnSinceCharge; 262 int mDischargeAmountScreenOff; 263 int mDischargeAmountScreenOffSinceCharge; 264 265 long mLastWriteTime = 0; // Milliseconds 266 267 // Mobile data transferred while on battery 268 private long[] mMobileDataTx = new long[4]; 269 private long[] mMobileDataRx = new long[4]; 270 private long[] mTotalDataTx = new long[4]; 271 private long[] mTotalDataRx = new long[4]; 272 273 private long mRadioDataUptime; 274 private long mRadioDataStart; 275 276 private int mBluetoothPingCount; 277 private int mBluetoothPingStart = -1; 278 279 private int mPhoneServiceState = -1; 280 private int mPhoneServiceStateRaw = -1; 281 private int mPhoneSimStateRaw = -1; 282 283 /* 284 * Holds a SamplingTimer associated with each kernel wakelock name being tracked. 285 */ 286 private final HashMap<String, SamplingTimer> mKernelWakelockStats = 287 new HashMap<String, SamplingTimer>(); 288 289 public Map<String, ? extends SamplingTimer> getKernelWakelockStats() { 290 return mKernelWakelockStats; 291 } 292 293 private static int sKernelWakelockUpdateVersion = 0; 294 295 private static final int[] PROC_WAKELOCKS_FORMAT = new int[] { 296 Process.PROC_TAB_TERM|Process.PROC_OUT_STRING, // 0: name 297 Process.PROC_TAB_TERM|Process.PROC_OUT_LONG, // 1: count 298 Process.PROC_TAB_TERM, 299 Process.PROC_TAB_TERM, 300 Process.PROC_TAB_TERM, 301 Process.PROC_TAB_TERM|Process.PROC_OUT_LONG, // 5: totalTime 302 }; 303 304 private final String[] mProcWakelocksName = new String[3]; 305 private final long[] mProcWakelocksData = new long[3]; 306 307 /* 308 * Used as a buffer for reading in data from /proc/wakelocks before it is processed and added 309 * to mKernelWakelockStats. 310 */ 311 private final Map<String, KernelWakelockStats> mProcWakelockFileStats = 312 new HashMap<String, KernelWakelockStats>(); 313 314 private HashMap<String, Integer> mUidCache = new HashMap<String, Integer>(); 315 316 // For debugging 317 public BatteryStatsImpl() { 318 mFile = null; 319 mHandler = null; 320 } 321 322 public static interface Unpluggable { 323 void unplug(long batteryUptime, long batteryRealtime); 324 void plug(long batteryUptime, long batteryRealtime); 325 } 326 327 /** 328 * State for keeping track of counting information. 329 */ 330 public static class Counter extends BatteryStats.Counter implements Unpluggable { 331 final AtomicInteger mCount = new AtomicInteger(); 332 final ArrayList<Unpluggable> mUnpluggables; 333 int mLoadedCount; 334 int mLastCount; 335 int mUnpluggedCount; 336 int mPluggedCount; 337 338 Counter(ArrayList<Unpluggable> unpluggables, Parcel in) { 339 mUnpluggables = unpluggables; 340 mPluggedCount = in.readInt(); 341 mCount.set(mPluggedCount); 342 mLoadedCount = in.readInt(); 343 mLastCount = 0; 344 mUnpluggedCount = in.readInt(); 345 unpluggables.add(this); 346 } 347 348 Counter(ArrayList<Unpluggable> unpluggables) { 349 mUnpluggables = unpluggables; 350 unpluggables.add(this); 351 } 352 353 public void writeToParcel(Parcel out) { 354 out.writeInt(mCount.get()); 355 out.writeInt(mLoadedCount); 356 out.writeInt(mUnpluggedCount); 357 } 358 359 public void unplug(long batteryUptime, long batteryRealtime) { 360 mUnpluggedCount = mPluggedCount; 361 mCount.set(mPluggedCount); 362 } 363 364 public void plug(long batteryUptime, long batteryRealtime) { 365 mPluggedCount = mCount.get(); 366 } 367 368 /** 369 * Writes a possibly null Counter to a Parcel. 370 * 371 * @param out the Parcel to be written to. 372 * @param counter a Counter, or null. 373 */ 374 public static void writeCounterToParcel(Parcel out, Counter counter) { 375 if (counter == null) { 376 out.writeInt(0); // indicates null 377 return; 378 } 379 out.writeInt(1); // indicates non-null 380 381 counter.writeToParcel(out); 382 } 383 384 @Override 385 public int getCountLocked(int which) { 386 int val; 387 if (which == STATS_LAST) { 388 val = mLastCount; 389 } else { 390 val = mCount.get(); 391 if (which == STATS_SINCE_UNPLUGGED) { 392 val -= mUnpluggedCount; 393 } else if (which != STATS_SINCE_CHARGED) { 394 val -= mLoadedCount; 395 } 396 } 397 398 return val; 399 } 400 401 public void logState(Printer pw, String prefix) { 402 pw.println(prefix + "mCount=" + mCount.get() 403 + " mLoadedCount=" + mLoadedCount + " mLastCount=" + mLastCount 404 + " mUnpluggedCount=" + mUnpluggedCount 405 + " mPluggedCount=" + mPluggedCount); 406 } 407 408 void stepAtomic() { 409 mCount.incrementAndGet(); 410 } 411 412 /** 413 * Clear state of this counter. 414 */ 415 void reset(boolean detachIfReset) { 416 mCount.set(0); 417 mLoadedCount = mLastCount = mPluggedCount = mUnpluggedCount = 0; 418 if (detachIfReset) { 419 detach(); 420 } 421 } 422 423 void detach() { 424 mUnpluggables.remove(this); 425 } 426 427 void writeSummaryFromParcelLocked(Parcel out) { 428 int count = mCount.get(); 429 out.writeInt(count); 430 } 431 432 void readSummaryFromParcelLocked(Parcel in) { 433 mLoadedCount = in.readInt(); 434 mCount.set(mLoadedCount); 435 mLastCount = 0; 436 mUnpluggedCount = mPluggedCount = mLoadedCount; 437 } 438 } 439 440 public static class SamplingCounter extends Counter { 441 442 SamplingCounter(ArrayList<Unpluggable> unpluggables, Parcel in) { 443 super(unpluggables, in); 444 } 445 446 SamplingCounter(ArrayList<Unpluggable> unpluggables) { 447 super(unpluggables); 448 } 449 450 public void addCountAtomic(long count) { 451 mCount.addAndGet((int)count); 452 } 453 } 454 455 /** 456 * State for keeping track of timing information. 457 */ 458 public static abstract class Timer extends BatteryStats.Timer implements Unpluggable { 459 final int mType; 460 final ArrayList<Unpluggable> mUnpluggables; 461 462 int mCount; 463 int mLoadedCount; 464 int mLastCount; 465 int mUnpluggedCount; 466 467 // Times are in microseconds for better accuracy when dividing by the 468 // lock count, and are in "battery realtime" units. 469 470 /** 471 * The total time we have accumulated since the start of the original 472 * boot, to the last time something interesting happened in the 473 * current run. 474 */ 475 long mTotalTime; 476 477 /** 478 * The total time we loaded for the previous runs. Subtract this from 479 * mTotalTime to find the time for the current run of the system. 480 */ 481 long mLoadedTime; 482 483 /** 484 * The run time of the last run of the system, as loaded from the 485 * saved data. 486 */ 487 long mLastTime; 488 489 /** 490 * The value of mTotalTime when unplug() was last called. Subtract 491 * this from mTotalTime to find the time since the last unplug from 492 * power. 493 */ 494 long mUnpluggedTime; 495 496 /** 497 * Constructs from a parcel. 498 * @param type 499 * @param unpluggables 500 * @param powerType 501 * @param in 502 */ 503 Timer(int type, ArrayList<Unpluggable> unpluggables, Parcel in) { 504 mType = type; 505 mUnpluggables = unpluggables; 506 507 mCount = in.readInt(); 508 mLoadedCount = in.readInt(); 509 mLastCount = 0; 510 mUnpluggedCount = in.readInt(); 511 mTotalTime = in.readLong(); 512 mLoadedTime = in.readLong(); 513 mLastTime = 0; 514 mUnpluggedTime = in.readLong(); 515 unpluggables.add(this); 516 } 517 518 Timer(int type, ArrayList<Unpluggable> unpluggables) { 519 mType = type; 520 mUnpluggables = unpluggables; 521 unpluggables.add(this); 522 } 523 524 protected abstract long computeRunTimeLocked(long curBatteryRealtime); 525 526 protected abstract int computeCurrentCountLocked(); 527 528 /** 529 * Clear state of this timer. Returns true if the timer is inactive 530 * so can be completely dropped. 531 */ 532 boolean reset(BatteryStatsImpl stats, boolean detachIfReset) { 533 mTotalTime = mLoadedTime = mLastTime = 0; 534 mCount = mLoadedCount = mLastCount = 0; 535 if (detachIfReset) { 536 detach(); 537 } 538 return true; 539 } 540 541 void detach() { 542 mUnpluggables.remove(this); 543 } 544 545 public void writeToParcel(Parcel out, long batteryRealtime) { 546 out.writeInt(mCount); 547 out.writeInt(mLoadedCount); 548 out.writeInt(mUnpluggedCount); 549 out.writeLong(computeRunTimeLocked(batteryRealtime)); 550 out.writeLong(mLoadedTime); 551 out.writeLong(mUnpluggedTime); 552 } 553 554 public void unplug(long batteryUptime, long batteryRealtime) { 555 if (DEBUG && mType < 0) { 556 Log.v(TAG, "unplug #" + mType + ": realtime=" + batteryRealtime 557 + " old mUnpluggedTime=" + mUnpluggedTime 558 + " old mUnpluggedCount=" + mUnpluggedCount); 559 } 560 mUnpluggedTime = computeRunTimeLocked(batteryRealtime); 561 mUnpluggedCount = mCount; 562 if (DEBUG && mType < 0) { 563 Log.v(TAG, "unplug #" + mType 564 + ": new mUnpluggedTime=" + mUnpluggedTime 565 + " new mUnpluggedCount=" + mUnpluggedCount); 566 } 567 } 568 569 public void plug(long batteryUptime, long batteryRealtime) { 570 if (DEBUG && mType < 0) { 571 Log.v(TAG, "plug #" + mType + ": realtime=" + batteryRealtime 572 + " old mTotalTime=" + mTotalTime); 573 } 574 mTotalTime = computeRunTimeLocked(batteryRealtime); 575 mCount = computeCurrentCountLocked(); 576 if (DEBUG && mType < 0) { 577 Log.v(TAG, "plug #" + mType 578 + ": new mTotalTime=" + mTotalTime); 579 } 580 } 581 582 /** 583 * Writes a possibly null Timer to a Parcel. 584 * 585 * @param out the Parcel to be written to. 586 * @param timer a Timer, or null. 587 */ 588 public static void writeTimerToParcel(Parcel out, Timer timer, 589 long batteryRealtime) { 590 if (timer == null) { 591 out.writeInt(0); // indicates null 592 return; 593 } 594 out.writeInt(1); // indicates non-null 595 596 timer.writeToParcel(out, batteryRealtime); 597 } 598 599 @Override 600 public long getTotalTimeLocked(long batteryRealtime, int which) { 601 long val; 602 if (which == STATS_LAST) { 603 val = mLastTime; 604 } else { 605 val = computeRunTimeLocked(batteryRealtime); 606 if (which == STATS_SINCE_UNPLUGGED) { 607 val -= mUnpluggedTime; 608 } else if (which != STATS_SINCE_CHARGED) { 609 val -= mLoadedTime; 610 } 611 } 612 613 return val; 614 } 615 616 @Override 617 public int getCountLocked(int which) { 618 int val; 619 if (which == STATS_LAST) { 620 val = mLastCount; 621 } else { 622 val = computeCurrentCountLocked(); 623 if (which == STATS_SINCE_UNPLUGGED) { 624 val -= mUnpluggedCount; 625 } else if (which != STATS_SINCE_CHARGED) { 626 val -= mLoadedCount; 627 } 628 } 629 630 return val; 631 } 632 633 public void logState(Printer pw, String prefix) { 634 pw.println(prefix + " mCount=" + mCount 635 + " mLoadedCount=" + mLoadedCount + " mLastCount=" + mLastCount 636 + " mUnpluggedCount=" + mUnpluggedCount); 637 pw.println(prefix + "mTotalTime=" + mTotalTime 638 + " mLoadedTime=" + mLoadedTime); 639 pw.println(prefix + "mLastTime=" + mLastTime 640 + " mUnpluggedTime=" + mUnpluggedTime); 641 } 642 643 644 void writeSummaryFromParcelLocked(Parcel out, long batteryRealtime) { 645 long runTime = computeRunTimeLocked(batteryRealtime); 646 // Divide by 1000 for backwards compatibility 647 out.writeLong((runTime + 500) / 1000); 648 out.writeInt(mCount); 649 } 650 651 void readSummaryFromParcelLocked(Parcel in) { 652 // Multiply by 1000 for backwards compatibility 653 mTotalTime = mLoadedTime = in.readLong() * 1000; 654 mLastTime = 0; 655 mUnpluggedTime = mTotalTime; 656 mCount = mLoadedCount = in.readInt(); 657 mLastCount = 0; 658 mUnpluggedCount = mCount; 659 } 660 } 661 662 public static final class SamplingTimer extends Timer { 663 664 /** 665 * The most recent reported count from /proc/wakelocks. 666 */ 667 int mCurrentReportedCount; 668 669 /** 670 * The reported count from /proc/wakelocks when unplug() was last 671 * called. 672 */ 673 int mUnpluggedReportedCount; 674 675 /** 676 * The most recent reported total_time from /proc/wakelocks. 677 */ 678 long mCurrentReportedTotalTime; 679 680 681 /** 682 * The reported total_time from /proc/wakelocks when unplug() was last 683 * called. 684 */ 685 long mUnpluggedReportedTotalTime; 686 687 /** 688 * Whether we are currently in a discharge cycle. 689 */ 690 boolean mInDischarge; 691 692 /** 693 * Whether we are currently recording reported values. 694 */ 695 boolean mTrackingReportedValues; 696 697 /* 698 * A sequnce counter, incremented once for each update of the stats. 699 */ 700 int mUpdateVersion; 701 702 SamplingTimer(ArrayList<Unpluggable> unpluggables, boolean inDischarge, Parcel in) { 703 super(0, unpluggables, in); 704 mCurrentReportedCount = in.readInt(); 705 mUnpluggedReportedCount = in.readInt(); 706 mCurrentReportedTotalTime = in.readLong(); 707 mUnpluggedReportedTotalTime = in.readLong(); 708 mTrackingReportedValues = in.readInt() == 1; 709 mInDischarge = inDischarge; 710 } 711 712 SamplingTimer(ArrayList<Unpluggable> unpluggables, boolean inDischarge, 713 boolean trackReportedValues) { 714 super(0, unpluggables); 715 mTrackingReportedValues = trackReportedValues; 716 mInDischarge = inDischarge; 717 } 718 719 public void setStale() { 720 mTrackingReportedValues = false; 721 mUnpluggedReportedTotalTime = 0; 722 mUnpluggedReportedCount = 0; 723 } 724 725 public void setUpdateVersion(int version) { 726 mUpdateVersion = version; 727 } 728 729 public int getUpdateVersion() { 730 return mUpdateVersion; 731 } 732 733 public void updateCurrentReportedCount(int count) { 734 if (mInDischarge && mUnpluggedReportedCount == 0) { 735 // Updating the reported value for the first time. 736 mUnpluggedReportedCount = count; 737 // If we are receiving an update update mTrackingReportedValues; 738 mTrackingReportedValues = true; 739 } 740 mCurrentReportedCount = count; 741 } 742 743 public void updateCurrentReportedTotalTime(long totalTime) { 744 if (mInDischarge && mUnpluggedReportedTotalTime == 0) { 745 // Updating the reported value for the first time. 746 mUnpluggedReportedTotalTime = totalTime; 747 // If we are receiving an update update mTrackingReportedValues; 748 mTrackingReportedValues = true; 749 } 750 mCurrentReportedTotalTime = totalTime; 751 } 752 753 public void unplug(long batteryUptime, long batteryRealtime) { 754 super.unplug(batteryUptime, batteryRealtime); 755 if (mTrackingReportedValues) { 756 mUnpluggedReportedTotalTime = mCurrentReportedTotalTime; 757 mUnpluggedReportedCount = mCurrentReportedCount; 758 } 759 mInDischarge = true; 760 } 761 762 public void plug(long batteryUptime, long batteryRealtime) { 763 super.plug(batteryUptime, batteryRealtime); 764 mInDischarge = false; 765 } 766 767 public void logState(Printer pw, String prefix) { 768 super.logState(pw, prefix); 769 pw.println(prefix + "mCurrentReportedCount=" + mCurrentReportedCount 770 + " mUnpluggedReportedCount=" + mUnpluggedReportedCount 771 + " mCurrentReportedTotalTime=" + mCurrentReportedTotalTime 772 + " mUnpluggedReportedTotalTime=" + mUnpluggedReportedTotalTime); 773 } 774 775 protected long computeRunTimeLocked(long curBatteryRealtime) { 776 return mTotalTime + (mInDischarge && mTrackingReportedValues 777 ? mCurrentReportedTotalTime - mUnpluggedReportedTotalTime : 0); 778 } 779 780 protected int computeCurrentCountLocked() { 781 return mCount + (mInDischarge && mTrackingReportedValues 782 ? mCurrentReportedCount - mUnpluggedReportedCount : 0); 783 } 784 785 public void writeToParcel(Parcel out, long batteryRealtime) { 786 super.writeToParcel(out, batteryRealtime); 787 out.writeInt(mCurrentReportedCount); 788 out.writeInt(mUnpluggedReportedCount); 789 out.writeLong(mCurrentReportedTotalTime); 790 out.writeLong(mUnpluggedReportedTotalTime); 791 out.writeInt(mTrackingReportedValues ? 1 : 0); 792 } 793 794 boolean reset(BatteryStatsImpl stats, boolean detachIfReset) { 795 super.reset(stats, detachIfReset); 796 setStale(); 797 return true; 798 } 799 800 void writeSummaryFromParcelLocked(Parcel out, long batteryRealtime) { 801 super.writeSummaryFromParcelLocked(out, batteryRealtime); 802 out.writeLong(mCurrentReportedTotalTime); 803 out.writeInt(mCurrentReportedCount); 804 out.writeInt(mTrackingReportedValues ? 1 : 0); 805 } 806 807 void readSummaryFromParcelLocked(Parcel in) { 808 super.readSummaryFromParcelLocked(in); 809 mUnpluggedReportedTotalTime = mCurrentReportedTotalTime = in.readLong(); 810 mUnpluggedReportedCount = mCurrentReportedCount = in.readInt(); 811 mTrackingReportedValues = in.readInt() == 1; 812 } 813 } 814 815 /** 816 * State for keeping track of timing information. 817 */ 818 public static final class StopwatchTimer extends Timer { 819 final Uid mUid; 820 final ArrayList<StopwatchTimer> mTimerPool; 821 822 int mNesting; 823 824 /** 825 * The last time at which we updated the timer. If mNesting is > 0, 826 * subtract this from the current battery time to find the amount of 827 * time we have been running since we last computed an update. 828 */ 829 long mUpdateTime; 830 831 /** 832 * The total time at which the timer was acquired, to determine if it 833 * was actually held for an interesting duration. 834 */ 835 long mAcquireTime; 836 837 long mTimeout; 838 839 /** 840 * For partial wake locks, keep track of whether we are in the list 841 * to consume CPU cycles. 842 */ 843 boolean mInList; 844 845 StopwatchTimer(Uid uid, int type, ArrayList<StopwatchTimer> timerPool, 846 ArrayList<Unpluggable> unpluggables, Parcel in) { 847 super(type, unpluggables, in); 848 mUid = uid; 849 mTimerPool = timerPool; 850 mUpdateTime = in.readLong(); 851 } 852 853 StopwatchTimer(Uid uid, int type, ArrayList<StopwatchTimer> timerPool, 854 ArrayList<Unpluggable> unpluggables) { 855 super(type, unpluggables); 856 mUid = uid; 857 mTimerPool = timerPool; 858 } 859 860 void setTimeout(long timeout) { 861 mTimeout = timeout; 862 } 863 864 public void writeToParcel(Parcel out, long batteryRealtime) { 865 super.writeToParcel(out, batteryRealtime); 866 out.writeLong(mUpdateTime); 867 } 868 869 public void plug(long batteryUptime, long batteryRealtime) { 870 if (mNesting > 0) { 871 if (DEBUG && mType < 0) { 872 Log.v(TAG, "old mUpdateTime=" + mUpdateTime); 873 } 874 super.plug(batteryUptime, batteryRealtime); 875 mUpdateTime = batteryRealtime; 876 if (DEBUG && mType < 0) { 877 Log.v(TAG, "new mUpdateTime=" + mUpdateTime); 878 } 879 } 880 } 881 882 public void logState(Printer pw, String prefix) { 883 super.logState(pw, prefix); 884 pw.println(prefix + "mNesting=" + mNesting + "mUpdateTime=" + mUpdateTime 885 + " mAcquireTime=" + mAcquireTime); 886 } 887 888 void startRunningLocked(BatteryStatsImpl stats) { 889 if (mNesting++ == 0) { 890 mUpdateTime = stats.getBatteryRealtimeLocked( 891 SystemClock.elapsedRealtime() * 1000); 892 if (mTimerPool != null) { 893 // Accumulate time to all currently active timers before adding 894 // this new one to the pool. 895 refreshTimersLocked(stats, mTimerPool); 896 // Add this timer to the active pool 897 mTimerPool.add(this); 898 } 899 // Increment the count 900 mCount++; 901 mAcquireTime = mTotalTime; 902 if (DEBUG && mType < 0) { 903 Log.v(TAG, "start #" + mType + ": mUpdateTime=" + mUpdateTime 904 + " mTotalTime=" + mTotalTime + " mCount=" + mCount 905 + " mAcquireTime=" + mAcquireTime); 906 } 907 } 908 } 909 910 boolean isRunningLocked() { 911 return mNesting > 0; 912 } 913 914 void stopRunningLocked(BatteryStatsImpl stats) { 915 // Ignore attempt to stop a timer that isn't running 916 if (mNesting == 0) { 917 return; 918 } 919 if (--mNesting == 0) { 920 if (mTimerPool != null) { 921 // Accumulate time to all active counters, scaled by the total 922 // active in the pool, before taking this one out of the pool. 923 refreshTimersLocked(stats, mTimerPool); 924 // Remove this timer from the active pool 925 mTimerPool.remove(this); 926 } else { 927 final long realtime = SystemClock.elapsedRealtime() * 1000; 928 final long batteryRealtime = stats.getBatteryRealtimeLocked(realtime); 929 mNesting = 1; 930 mTotalTime = computeRunTimeLocked(batteryRealtime); 931 mNesting = 0; 932 } 933 934 if (DEBUG && mType < 0) { 935 Log.v(TAG, "stop #" + mType + ": mUpdateTime=" + mUpdateTime 936 + " mTotalTime=" + mTotalTime + " mCount=" + mCount 937 + " mAcquireTime=" + mAcquireTime); 938 } 939 940 if (mTotalTime == mAcquireTime) { 941 // If there was no change in the time, then discard this 942 // count. A somewhat cheezy strategy, but hey. 943 mCount--; 944 } 945 } 946 } 947 948 // Update the total time for all other running Timers with the same type as this Timer 949 // due to a change in timer count 950 private static void refreshTimersLocked(final BatteryStatsImpl stats, 951 final ArrayList<StopwatchTimer> pool) { 952 final long realtime = SystemClock.elapsedRealtime() * 1000; 953 final long batteryRealtime = stats.getBatteryRealtimeLocked(realtime); 954 final int N = pool.size(); 955 for (int i=N-1; i>= 0; i--) { 956 final StopwatchTimer t = pool.get(i); 957 long heldTime = batteryRealtime - t.mUpdateTime; 958 if (heldTime > 0) { 959 t.mTotalTime += heldTime / N; 960 } 961 t.mUpdateTime = batteryRealtime; 962 } 963 } 964 965 @Override 966 protected long computeRunTimeLocked(long curBatteryRealtime) { 967 if (mTimeout > 0 && curBatteryRealtime > mUpdateTime + mTimeout) { 968 curBatteryRealtime = mUpdateTime + mTimeout; 969 } 970 return mTotalTime + (mNesting > 0 971 ? (curBatteryRealtime - mUpdateTime) 972 / (mTimerPool != null ? mTimerPool.size() : 1) 973 : 0); 974 } 975 976 @Override 977 protected int computeCurrentCountLocked() { 978 return mCount; 979 } 980 981 boolean reset(BatteryStatsImpl stats, boolean detachIfReset) { 982 boolean canDetach = mNesting <= 0; 983 super.reset(stats, canDetach && detachIfReset); 984 if (mNesting > 0) { 985 mUpdateTime = stats.getBatteryRealtimeLocked( 986 SystemClock.elapsedRealtime() * 1000); 987 } 988 mAcquireTime = mTotalTime; 989 return canDetach; 990 } 991 992 void detach() { 993 super.detach(); 994 if (mTimerPool != null) { 995 mTimerPool.remove(this); 996 } 997 } 998 999 void readSummaryFromParcelLocked(Parcel in) { 1000 super.readSummaryFromParcelLocked(in); 1001 mNesting = 0; 1002 } 1003 } 1004 1005 private final Map<String, KernelWakelockStats> readKernelWakelockStats() { 1006 1007 byte[] buffer = new byte[8192]; 1008 int len; 1009 1010 try { 1011 FileInputStream is = new FileInputStream("/proc/wakelocks"); 1012 len = is.read(buffer); 1013 is.close(); 1014 1015 if (len > 0) { 1016 int i; 1017 for (i=0; i<len; i++) { 1018 if (buffer[i] == '\0') { 1019 len = i; 1020 break; 1021 } 1022 } 1023 } 1024 } catch (java.io.FileNotFoundException e) { 1025 return null; 1026 } catch (java.io.IOException e) { 1027 return null; 1028 } 1029 1030 return parseProcWakelocks(buffer, len); 1031 } 1032 1033 private final Map<String, KernelWakelockStats> parseProcWakelocks( 1034 byte[] wlBuffer, int len) { 1035 String name; 1036 int count; 1037 long totalTime; 1038 int startIndex, endIndex; 1039 int numUpdatedWlNames = 0; 1040 1041 // Advance past the first line. 1042 int i; 1043 for (i = 0; i < len && wlBuffer[i] != '\n' && wlBuffer[i] != '\0'; i++); 1044 startIndex = endIndex = i + 1; 1045 1046 synchronized(this) { 1047 Map<String, KernelWakelockStats> m = mProcWakelockFileStats; 1048 1049 sKernelWakelockUpdateVersion++; 1050 while (endIndex < len) { 1051 for (endIndex=startIndex; 1052 endIndex < len && wlBuffer[endIndex] != '\n' && wlBuffer[endIndex] != '\0'; 1053 endIndex++); 1054 endIndex++; // endIndex is an exclusive upper bound. 1055 // Don't go over the end of the buffer, Process.parseProcLine might 1056 // write to wlBuffer[endIndex] 1057 if (endIndex >= (len - 1) ) { 1058 return m; 1059 } 1060 1061 String[] nameStringArray = mProcWakelocksName; 1062 long[] wlData = mProcWakelocksData; 1063 // Stomp out any bad characters since this is from a circular buffer 1064 // A corruption is seen sometimes that results in the vm crashing 1065 // This should prevent crashes and the line will probably fail to parse 1066 for (int j = startIndex; j < endIndex; j++) { 1067 if ((wlBuffer[j] & 0x80) != 0) wlBuffer[j] = (byte) '?'; 1068 } 1069 boolean parsed = Process.parseProcLine(wlBuffer, startIndex, endIndex, 1070 PROC_WAKELOCKS_FORMAT, nameStringArray, wlData, null); 1071 1072 name = nameStringArray[0]; 1073 count = (int) wlData[1]; 1074 // convert nanoseconds to microseconds with rounding. 1075 totalTime = (wlData[2] + 500) / 1000; 1076 1077 if (parsed && name.length() > 0) { 1078 if (!m.containsKey(name)) { 1079 m.put(name, new KernelWakelockStats(count, totalTime, 1080 sKernelWakelockUpdateVersion)); 1081 numUpdatedWlNames++; 1082 } else { 1083 KernelWakelockStats kwlStats = m.get(name); 1084 if (kwlStats.mVersion == sKernelWakelockUpdateVersion) { 1085 kwlStats.mCount += count; 1086 kwlStats.mTotalTime += totalTime; 1087 } else { 1088 kwlStats.mCount = count; 1089 kwlStats.mTotalTime = totalTime; 1090 kwlStats.mVersion = sKernelWakelockUpdateVersion; 1091 numUpdatedWlNames++; 1092 } 1093 } 1094 } 1095 startIndex = endIndex; 1096 } 1097 1098 if (m.size() != numUpdatedWlNames) { 1099 // Don't report old data. 1100 Iterator<KernelWakelockStats> itr = m.values().iterator(); 1101 while (itr.hasNext()) { 1102 if (itr.next().mVersion != sKernelWakelockUpdateVersion) { 1103 itr.remove(); 1104 } 1105 } 1106 } 1107 return m; 1108 } 1109 } 1110 1111 private class KernelWakelockStats { 1112 public int mCount; 1113 public long mTotalTime; 1114 public int mVersion; 1115 1116 KernelWakelockStats(int count, long totalTime, int version) { 1117 mCount = count; 1118 mTotalTime = totalTime; 1119 mVersion = version; 1120 } 1121 } 1122 1123 /* 1124 * Get the KernelWakelockTimer associated with name, and create a new one if one 1125 * doesn't already exist. 1126 */ 1127 public SamplingTimer getKernelWakelockTimerLocked(String name) { 1128 SamplingTimer kwlt = mKernelWakelockStats.get(name); 1129 if (kwlt == null) { 1130 kwlt = new SamplingTimer(mUnpluggables, mOnBatteryInternal, 1131 true /* track reported values */); 1132 mKernelWakelockStats.put(name, kwlt); 1133 } 1134 return kwlt; 1135 } 1136 1137 private void doDataPlug(long[] dataTransfer, long currentBytes) { 1138 dataTransfer[STATS_LAST] = dataTransfer[STATS_SINCE_UNPLUGGED]; 1139 dataTransfer[STATS_SINCE_UNPLUGGED] = -1; 1140 } 1141 1142 private void doDataUnplug(long[] dataTransfer, long currentBytes) { 1143 dataTransfer[STATS_SINCE_UNPLUGGED] = currentBytes; 1144 } 1145 1146 /** 1147 * Radio uptime in microseconds when transferring data. This value is very approximate. 1148 * @return 1149 */ 1150 private long getCurrentRadioDataUptime() { 1151 try { 1152 File awakeTimeFile = new File("/sys/devices/virtual/net/rmnet0/awake_time_ms"); 1153 if (!awakeTimeFile.exists()) return 0; 1154 BufferedReader br = new BufferedReader(new FileReader(awakeTimeFile)); 1155 String line = br.readLine(); 1156 br.close(); 1157 return Long.parseLong(line) * 1000; 1158 } catch (NumberFormatException nfe) { 1159 // Nothing 1160 } catch (IOException ioe) { 1161 // Nothing 1162 } 1163 return 0; 1164 } 1165 1166 /** 1167 * @deprecated use getRadioDataUptime 1168 */ 1169 public long getRadioDataUptimeMs() { 1170 return getRadioDataUptime() / 1000; 1171 } 1172 1173 /** 1174 * Returns the duration that the cell radio was up for data transfers. 1175 */ 1176 public long getRadioDataUptime() { 1177 if (mRadioDataStart == -1) { 1178 return mRadioDataUptime; 1179 } else { 1180 return getCurrentRadioDataUptime() - mRadioDataStart; 1181 } 1182 } 1183 1184 private int getCurrentBluetoothPingCount() { 1185 if (mBtHeadset != null) { 1186 List<BluetoothDevice> deviceList = mBtHeadset.getConnectedDevices(); 1187 if (deviceList.size() > 0) { 1188 return mBtHeadset.getBatteryUsageHint(deviceList.get(0)); 1189 } 1190 } 1191 return -1; 1192 } 1193 1194 public int getBluetoothPingCount() { 1195 if (mBluetoothPingStart == -1) { 1196 return mBluetoothPingCount; 1197 } else if (mBtHeadset != null) { 1198 return getCurrentBluetoothPingCount() - mBluetoothPingStart; 1199 } 1200 return 0; 1201 } 1202 1203 public void setBtHeadset(BluetoothHeadset headset) { 1204 if (headset != null && mBtHeadset == null && isOnBattery() && mBluetoothPingStart == -1) { 1205 mBluetoothPingStart = getCurrentBluetoothPingCount(); 1206 } 1207 mBtHeadset = headset; 1208 } 1209 1210 int mChangedBufferStates = 0; 1211 1212 void addHistoryBufferLocked(long curTime) { 1213 if (!mHaveBatteryLevel || !mRecordingHistory) { 1214 return; 1215 } 1216 1217 final long timeDiff = (mHistoryBaseTime+curTime) - mHistoryLastWritten.time; 1218 if (mHistoryBufferLastPos >= 0 && mHistoryLastWritten.cmd == HistoryItem.CMD_UPDATE 1219 && timeDiff < 2000 1220 && ((mHistoryLastWritten.states^mHistoryCur.states)&mChangedBufferStates) == 0) { 1221 // If the current is the same as the one before, then we no 1222 // longer need the entry. 1223 mHistoryBuffer.setDataSize(mHistoryBufferLastPos); 1224 mHistoryBuffer.setDataPosition(mHistoryBufferLastPos); 1225 mHistoryBufferLastPos = -1; 1226 if (mHistoryLastLastWritten.cmd == HistoryItem.CMD_UPDATE 1227 && timeDiff < 500 && mHistoryLastLastWritten.same(mHistoryCur)) { 1228 // If this results in us returning to the state written 1229 // prior to the last one, then we can just delete the last 1230 // written one and drop the new one. Nothing more to do. 1231 mHistoryLastWritten.setTo(mHistoryLastLastWritten); 1232 mHistoryLastLastWritten.cmd = HistoryItem.CMD_NULL; 1233 return; 1234 } 1235 mChangedBufferStates |= mHistoryLastWritten.states^mHistoryCur.states; 1236 curTime = mHistoryLastWritten.time - mHistoryBaseTime; 1237 mHistoryLastWritten.setTo(mHistoryLastLastWritten); 1238 } else { 1239 mChangedBufferStates = 0; 1240 } 1241 1242 final int dataSize = mHistoryBuffer.dataSize(); 1243 if (dataSize >= MAX_HISTORY_BUFFER) { 1244 if (!mHistoryOverflow) { 1245 mHistoryOverflow = true; 1246 addHistoryBufferLocked(curTime, HistoryItem.CMD_OVERFLOW); 1247 } 1248 1249 // Once we've reached the maximum number of items, we only 1250 // record changes to the battery level and the most interesting states. 1251 // Once we've reached the maximum maximum number of items, we only 1252 // record changes to the battery level. 1253 if (mHistoryLastWritten.batteryLevel == mHistoryCur.batteryLevel && 1254 (dataSize >= MAX_MAX_HISTORY_BUFFER 1255 || ((mHistoryEnd.states^mHistoryCur.states) 1256 & HistoryItem.MOST_INTERESTING_STATES) == 0)) { 1257 return; 1258 } 1259 } 1260 1261 addHistoryBufferLocked(curTime, HistoryItem.CMD_UPDATE); 1262 } 1263 1264 void addHistoryBufferLocked(long curTime, byte cmd) { 1265 int origPos = 0; 1266 if (mIteratingHistory) { 1267 origPos = mHistoryBuffer.dataPosition(); 1268 mHistoryBuffer.setDataPosition(mHistoryBuffer.dataSize()); 1269 } 1270 mHistoryBufferLastPos = mHistoryBuffer.dataPosition(); 1271 mHistoryLastLastWritten.setTo(mHistoryLastWritten); 1272 mHistoryLastWritten.setTo(mHistoryBaseTime + curTime, cmd, mHistoryCur); 1273 mHistoryLastWritten.writeDelta(mHistoryBuffer, mHistoryLastLastWritten); 1274 mLastHistoryTime = curTime; 1275 if (DEBUG_HISTORY) Slog.i(TAG, "Writing history buffer: was " + mHistoryBufferLastPos 1276 + " now " + mHistoryBuffer.dataPosition() 1277 + " size is now " + mHistoryBuffer.dataSize()); 1278 if (mIteratingHistory) { 1279 mHistoryBuffer.setDataPosition(origPos); 1280 } 1281 } 1282 1283 int mChangedStates = 0; 1284 1285 void addHistoryRecordLocked(long curTime) { 1286 addHistoryBufferLocked(curTime); 1287 1288 if (!mHaveBatteryLevel || !mRecordingHistory) { 1289 return; 1290 } 1291 1292 // If the current time is basically the same as the last time, 1293 // and no states have since the last recorded entry changed and 1294 // are now resetting back to their original value, then just collapse 1295 // into one record. 1296 if (mHistoryEnd != null && mHistoryEnd.cmd == HistoryItem.CMD_UPDATE 1297 && (mHistoryBaseTime+curTime) < (mHistoryEnd.time+2000) 1298 && ((mHistoryEnd.states^mHistoryCur.states)&mChangedStates) == 0) { 1299 // If the current is the same as the one before, then we no 1300 // longer need the entry. 1301 if (mHistoryLastEnd != null && mHistoryLastEnd.cmd == HistoryItem.CMD_UPDATE 1302 && (mHistoryBaseTime+curTime) < (mHistoryEnd.time+500) 1303 && mHistoryLastEnd.same(mHistoryCur)) { 1304 mHistoryLastEnd.next = null; 1305 mHistoryEnd.next = mHistoryCache; 1306 mHistoryCache = mHistoryEnd; 1307 mHistoryEnd = mHistoryLastEnd; 1308 mHistoryLastEnd = null; 1309 } else { 1310 mChangedStates |= mHistoryEnd.states^mHistoryCur.states; 1311 mHistoryEnd.setTo(mHistoryEnd.time, HistoryItem.CMD_UPDATE, mHistoryCur); 1312 } 1313 return; 1314 } 1315 1316 mChangedStates = 0; 1317 1318 if (mNumHistoryItems == MAX_HISTORY_ITEMS 1319 || mNumHistoryItems == MAX_MAX_HISTORY_ITEMS) { 1320 addHistoryRecordLocked(curTime, HistoryItem.CMD_OVERFLOW); 1321 } 1322 1323 if (mNumHistoryItems >= MAX_HISTORY_ITEMS) { 1324 // Once we've reached the maximum number of items, we only 1325 // record changes to the battery level and the most interesting states. 1326 // Once we've reached the maximum maximum number of items, we only 1327 // record changes to the battery level. 1328 if (mHistoryEnd != null && mHistoryEnd.batteryLevel 1329 == mHistoryCur.batteryLevel && 1330 (mNumHistoryItems >= MAX_MAX_HISTORY_ITEMS 1331 || ((mHistoryEnd.states^mHistoryCur.states) 1332 & HistoryItem.MOST_INTERESTING_STATES) == 0)) { 1333 return; 1334 } 1335 } 1336 1337 addHistoryRecordLocked(curTime, HistoryItem.CMD_UPDATE); 1338 } 1339 1340 void addHistoryRecordLocked(long curTime, byte cmd) { 1341 HistoryItem rec = mHistoryCache; 1342 if (rec != null) { 1343 mHistoryCache = rec.next; 1344 } else { 1345 rec = new HistoryItem(); 1346 } 1347 rec.setTo(mHistoryBaseTime + curTime, cmd, mHistoryCur); 1348 1349 addHistoryRecordLocked(rec); 1350 } 1351 1352 void addHistoryRecordLocked(HistoryItem rec) { 1353 mNumHistoryItems++; 1354 rec.next = null; 1355 mHistoryLastEnd = mHistoryEnd; 1356 if (mHistoryEnd != null) { 1357 mHistoryEnd.next = rec; 1358 mHistoryEnd = rec; 1359 } else { 1360 mHistory = mHistoryEnd = rec; 1361 } 1362 } 1363 1364 void clearHistoryLocked() { 1365 if (DEBUG_HISTORY) Slog.i(TAG, "********** CLEARING HISTORY!"); 1366 if (mHistory != null) { 1367 mHistoryEnd.next = mHistoryCache; 1368 mHistoryCache = mHistory; 1369 mHistory = mHistoryLastEnd = mHistoryEnd = null; 1370 } 1371 mNumHistoryItems = 0; 1372 mHistoryBaseTime = 0; 1373 mLastHistoryTime = 0; 1374 1375 mHistoryBuffer.setDataSize(0); 1376 mHistoryBuffer.setDataPosition(0); 1377 mHistoryBuffer.setDataCapacity(MAX_HISTORY_BUFFER/2); 1378 mHistoryLastLastWritten.cmd = HistoryItem.CMD_NULL; 1379 mHistoryLastWritten.cmd = HistoryItem.CMD_NULL; 1380 mHistoryBufferLastPos = -1; 1381 mHistoryOverflow = false; 1382 } 1383 1384 public void doUnplugLocked(long batteryUptime, long batteryRealtime) { 1385 for (int iu = mUidStats.size() - 1; iu >= 0; iu--) { 1386 Uid u = mUidStats.valueAt(iu); 1387 u.mStartedTcpBytesReceived = TrafficStats.getUidRxBytes(u.mUid); 1388 u.mStartedTcpBytesSent = TrafficStats.getUidTxBytes(u.mUid); 1389 u.mTcpBytesReceivedAtLastUnplug = u.mCurrentTcpBytesReceived; 1390 u.mTcpBytesSentAtLastUnplug = u.mCurrentTcpBytesSent; 1391 } 1392 for (int i = mUnpluggables.size() - 1; i >= 0; i--) { 1393 mUnpluggables.get(i).unplug(batteryUptime, batteryRealtime); 1394 } 1395 // Track total mobile data 1396 doDataUnplug(mMobileDataRx, TrafficStats.getMobileRxBytes()); 1397 doDataUnplug(mMobileDataTx, TrafficStats.getMobileTxBytes()); 1398 doDataUnplug(mTotalDataRx, TrafficStats.getTotalRxBytes()); 1399 doDataUnplug(mTotalDataTx, TrafficStats.getTotalTxBytes()); 1400 // Track radio awake time 1401 mRadioDataStart = getCurrentRadioDataUptime(); 1402 mRadioDataUptime = 0; 1403 // Track bt headset ping count 1404 mBluetoothPingStart = getCurrentBluetoothPingCount(); 1405 mBluetoothPingCount = 0; 1406 } 1407 1408 public void doPlugLocked(long batteryUptime, long batteryRealtime) { 1409 for (int iu = mUidStats.size() - 1; iu >= 0; iu--) { 1410 Uid u = mUidStats.valueAt(iu); 1411 if (u.mStartedTcpBytesReceived >= 0) { 1412 u.mCurrentTcpBytesReceived = u.computeCurrentTcpBytesReceived(); 1413 u.mStartedTcpBytesReceived = -1; 1414 } 1415 if (u.mStartedTcpBytesSent >= 0) { 1416 u.mCurrentTcpBytesSent = u.computeCurrentTcpBytesSent(); 1417 u.mStartedTcpBytesSent = -1; 1418 } 1419 } 1420 for (int i = mUnpluggables.size() - 1; i >= 0; i--) { 1421 mUnpluggables.get(i).plug(batteryUptime, batteryRealtime); 1422 } 1423 doDataPlug(mMobileDataRx, TrafficStats.getMobileRxBytes()); 1424 doDataPlug(mMobileDataTx, TrafficStats.getMobileTxBytes()); 1425 doDataPlug(mTotalDataRx, TrafficStats.getTotalRxBytes()); 1426 doDataPlug(mTotalDataTx, TrafficStats.getTotalTxBytes()); 1427 // Track radio awake time 1428 mRadioDataUptime = getRadioDataUptime(); 1429 mRadioDataStart = -1; 1430 1431 // Track bt headset ping count 1432 mBluetoothPingCount = getBluetoothPingCount(); 1433 mBluetoothPingStart = -1; 1434 } 1435 1436 int mWakeLockNesting; 1437 1438 public void noteStartWakeLocked(int uid, int pid, String name, int type) { 1439 if (type == WAKE_TYPE_PARTIAL) { 1440 // Only care about partial wake locks, since full wake locks 1441 // will be canceled when the user puts the screen to sleep. 1442 if (mWakeLockNesting == 0) { 1443 mHistoryCur.states |= HistoryItem.STATE_WAKE_LOCK_FLAG; 1444 if (DEBUG_HISTORY) Slog.v(TAG, "Start wake lock to: " 1445 + Integer.toHexString(mHistoryCur.states)); 1446 addHistoryRecordLocked(SystemClock.elapsedRealtime()); 1447 } 1448 mWakeLockNesting++; 1449 } 1450 if (uid >= 0) { 1451 if (!mHandler.hasMessages(MSG_UPDATE_WAKELOCKS)) { 1452 Message m = mHandler.obtainMessage(MSG_UPDATE_WAKELOCKS); 1453 mHandler.sendMessageDelayed(m, DELAY_UPDATE_WAKELOCKS); 1454 } 1455 getUidStatsLocked(uid).noteStartWakeLocked(pid, name, type); 1456 } 1457 } 1458 1459 public void noteStopWakeLocked(int uid, int pid, String name, int type) { 1460 if (type == WAKE_TYPE_PARTIAL) { 1461 mWakeLockNesting--; 1462 if (mWakeLockNesting == 0) { 1463 mHistoryCur.states &= ~HistoryItem.STATE_WAKE_LOCK_FLAG; 1464 if (DEBUG_HISTORY) Slog.v(TAG, "Stop wake lock to: " 1465 + Integer.toHexString(mHistoryCur.states)); 1466 addHistoryRecordLocked(SystemClock.elapsedRealtime()); 1467 } 1468 } 1469 if (uid >= 0) { 1470 if (!mHandler.hasMessages(MSG_UPDATE_WAKELOCKS)) { 1471 Message m = mHandler.obtainMessage(MSG_UPDATE_WAKELOCKS); 1472 mHandler.sendMessageDelayed(m, DELAY_UPDATE_WAKELOCKS); 1473 } 1474 getUidStatsLocked(uid).noteStopWakeLocked(pid, name, type); 1475 } 1476 } 1477 1478 public void noteStartWakeFromSourceLocked(WorkSource ws, int pid, String name, int type) { 1479 int N = ws.size(); 1480 for (int i=0; i<N; i++) { 1481 noteStartWakeLocked(ws.get(i), pid, name, type); 1482 } 1483 } 1484 1485 public void noteStopWakeFromSourceLocked(WorkSource ws, int pid, String name, int type) { 1486 int N = ws.size(); 1487 for (int i=0; i<N; i++) { 1488 noteStopWakeLocked(ws.get(i), pid, name, type); 1489 } 1490 } 1491 1492 public int startAddingCpuLocked() { 1493 mHandler.removeMessages(MSG_UPDATE_WAKELOCKS); 1494 1495 if (mScreenOn) { 1496 return 0; 1497 } 1498 1499 final int N = mPartialTimers.size(); 1500 if (N == 0) { 1501 mLastPartialTimers.clear(); 1502 return 0; 1503 } 1504 1505 // How many timers should consume CPU? Only want to include ones 1506 // that have already been in the list. 1507 for (int i=0; i<N; i++) { 1508 StopwatchTimer st = mPartialTimers.get(i); 1509 if (st.mInList) { 1510 Uid uid = st.mUid; 1511 // We don't include the system UID, because it so often 1512 // holds wake locks at one request or another of an app. 1513 if (uid != null && uid.mUid != Process.SYSTEM_UID) { 1514 return 50; 1515 } 1516 } 1517 } 1518 1519 return 0; 1520 } 1521 1522 public void finishAddingCpuLocked(int perc, int utime, int stime, long[] cpuSpeedTimes) { 1523 final int N = mPartialTimers.size(); 1524 if (perc != 0) { 1525 int num = 0; 1526 for (int i=0; i<N; i++) { 1527 StopwatchTimer st = mPartialTimers.get(i); 1528 if (st.mInList) { 1529 Uid uid = st.mUid; 1530 // We don't include the system UID, because it so often 1531 // holds wake locks at one request or another of an app. 1532 if (uid != null && uid.mUid != Process.SYSTEM_UID) { 1533 num++; 1534 } 1535 } 1536 } 1537 if (num != 0) { 1538 for (int i=0; i<N; i++) { 1539 StopwatchTimer st = mPartialTimers.get(i); 1540 if (st.mInList) { 1541 Uid uid = st.mUid; 1542 if (uid != null && uid.mUid != Process.SYSTEM_UID) { 1543 int myUTime = utime/num; 1544 int mySTime = stime/num; 1545 utime -= myUTime; 1546 stime -= mySTime; 1547 num--; 1548 Uid.Proc proc = uid.getProcessStatsLocked("*wakelock*"); 1549 proc.addCpuTimeLocked(myUTime, mySTime); 1550 proc.addSpeedStepTimes(cpuSpeedTimes); 1551 } 1552 } 1553 } 1554 } 1555 1556 // Just in case, collect any lost CPU time. 1557 if (utime != 0 || stime != 0) { 1558 Uid uid = getUidStatsLocked(Process.SYSTEM_UID); 1559 if (uid != null) { 1560 Uid.Proc proc = uid.getProcessStatsLocked("*lost*"); 1561 proc.addCpuTimeLocked(utime, stime); 1562 proc.addSpeedStepTimes(cpuSpeedTimes); 1563 } 1564 } 1565 } 1566 1567 final int NL = mLastPartialTimers.size(); 1568 boolean diff = N != NL; 1569 for (int i=0; i<NL && !diff; i++) { 1570 diff |= mPartialTimers.get(i) != mLastPartialTimers.get(i); 1571 } 1572 if (!diff) { 1573 for (int i=0; i<NL; i++) { 1574 mPartialTimers.get(i).mInList = true; 1575 } 1576 return; 1577 } 1578 1579 for (int i=0; i<NL; i++) { 1580 mLastPartialTimers.get(i).mInList = false; 1581 } 1582 mLastPartialTimers.clear(); 1583 for (int i=0; i<N; i++) { 1584 StopwatchTimer st = mPartialTimers.get(i); 1585 st.mInList = true; 1586 mLastPartialTimers.add(st); 1587 } 1588 } 1589 1590 public void noteProcessDiedLocked(int uid, int pid) { 1591 Uid u = mUidStats.get(uid); 1592 if (u != null) { 1593 u.mPids.remove(pid); 1594 } 1595 } 1596 1597 public long getProcessWakeTime(int uid, int pid, long realtime) { 1598 Uid u = mUidStats.get(uid); 1599 if (u != null) { 1600 Uid.Pid p = u.mPids.get(pid); 1601 if (p != null) { 1602 return p.mWakeSum + (p.mWakeStart != 0 ? (realtime - p.mWakeStart) : 0); 1603 } 1604 } 1605 return 0; 1606 } 1607 1608 public void reportExcessiveWakeLocked(int uid, String proc, long overTime, long usedTime) { 1609 Uid u = mUidStats.get(uid); 1610 if (u != null) { 1611 u.reportExcessiveWakeLocked(proc, overTime, usedTime); 1612 } 1613 } 1614 1615 public void reportExcessiveCpuLocked(int uid, String proc, long overTime, long usedTime) { 1616 Uid u = mUidStats.get(uid); 1617 if (u != null) { 1618 u.reportExcessiveCpuLocked(proc, overTime, usedTime); 1619 } 1620 } 1621 1622 int mSensorNesting; 1623 1624 public void noteStartSensorLocked(int uid, int sensor) { 1625 if (mSensorNesting == 0) { 1626 mHistoryCur.states |= HistoryItem.STATE_SENSOR_ON_FLAG; 1627 if (DEBUG_HISTORY) Slog.v(TAG, "Start sensor to: " 1628 + Integer.toHexString(mHistoryCur.states)); 1629 addHistoryRecordLocked(SystemClock.elapsedRealtime()); 1630 } 1631 mSensorNesting++; 1632 getUidStatsLocked(uid).noteStartSensor(sensor); 1633 } 1634 1635 public void noteStopSensorLocked(int uid, int sensor) { 1636 mSensorNesting--; 1637 if (mSensorNesting == 0) { 1638 mHistoryCur.states &= ~HistoryItem.STATE_SENSOR_ON_FLAG; 1639 if (DEBUG_HISTORY) Slog.v(TAG, "Stop sensor to: " 1640 + Integer.toHexString(mHistoryCur.states)); 1641 addHistoryRecordLocked(SystemClock.elapsedRealtime()); 1642 } 1643 getUidStatsLocked(uid).noteStopSensor(sensor); 1644 } 1645 1646 int mGpsNesting; 1647 1648 public void noteStartGpsLocked(int uid) { 1649 if (mGpsNesting == 0) { 1650 mHistoryCur.states |= HistoryItem.STATE_GPS_ON_FLAG; 1651 if (DEBUG_HISTORY) Slog.v(TAG, "Start GPS to: " 1652 + Integer.toHexString(mHistoryCur.states)); 1653 addHistoryRecordLocked(SystemClock.elapsedRealtime()); 1654 } 1655 mGpsNesting++; 1656 getUidStatsLocked(uid).noteStartGps(); 1657 } 1658 1659 public void noteStopGpsLocked(int uid) { 1660 mGpsNesting--; 1661 if (mGpsNesting == 0) { 1662 mHistoryCur.states &= ~HistoryItem.STATE_GPS_ON_FLAG; 1663 if (DEBUG_HISTORY) Slog.v(TAG, "Stop GPS to: " 1664 + Integer.toHexString(mHistoryCur.states)); 1665 addHistoryRecordLocked(SystemClock.elapsedRealtime()); 1666 } 1667 getUidStatsLocked(uid).noteStopGps(); 1668 } 1669 1670 public void noteScreenOnLocked() { 1671 if (!mScreenOn) { 1672 mHistoryCur.states |= HistoryItem.STATE_SCREEN_ON_FLAG; 1673 if (DEBUG_HISTORY) Slog.v(TAG, "Screen on to: " 1674 + Integer.toHexString(mHistoryCur.states)); 1675 addHistoryRecordLocked(SystemClock.elapsedRealtime()); 1676 mScreenOn = true; 1677 mScreenOnTimer.startRunningLocked(this); 1678 if (mScreenBrightnessBin >= 0) { 1679 mScreenBrightnessTimer[mScreenBrightnessBin].startRunningLocked(this); 1680 } 1681 1682 // Fake a wake lock, so we consider the device waked as long 1683 // as the screen is on. 1684 noteStartWakeLocked(-1, -1, "dummy", WAKE_TYPE_PARTIAL); 1685 1686 // Update discharge amounts. 1687 if (mOnBatteryInternal) { 1688 updateDischargeScreenLevelsLocked(false, true); 1689 } 1690 } 1691 } 1692 1693 public void noteScreenOffLocked() { 1694 if (mScreenOn) { 1695 mHistoryCur.states &= ~HistoryItem.STATE_SCREEN_ON_FLAG; 1696 if (DEBUG_HISTORY) Slog.v(TAG, "Screen off to: " 1697 + Integer.toHexString(mHistoryCur.states)); 1698 addHistoryRecordLocked(SystemClock.elapsedRealtime()); 1699 mScreenOn = false; 1700 mScreenOnTimer.stopRunningLocked(this); 1701 if (mScreenBrightnessBin >= 0) { 1702 mScreenBrightnessTimer[mScreenBrightnessBin].stopRunningLocked(this); 1703 } 1704 1705 noteStopWakeLocked(-1, -1, "dummy", WAKE_TYPE_PARTIAL); 1706 1707 // Update discharge amounts. 1708 if (mOnBatteryInternal) { 1709 updateDischargeScreenLevelsLocked(true, false); 1710 } 1711 } 1712 } 1713 1714 public void noteScreenBrightnessLocked(int brightness) { 1715 // Bin the brightness. 1716 int bin = brightness / (256/NUM_SCREEN_BRIGHTNESS_BINS); 1717 if (bin < 0) bin = 0; 1718 else if (bin >= NUM_SCREEN_BRIGHTNESS_BINS) bin = NUM_SCREEN_BRIGHTNESS_BINS-1; 1719 if (mScreenBrightnessBin != bin) { 1720 mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_BRIGHTNESS_MASK) 1721 | (bin << HistoryItem.STATE_BRIGHTNESS_SHIFT); 1722 if (DEBUG_HISTORY) Slog.v(TAG, "Screen brightness " + bin + " to: " 1723 + Integer.toHexString(mHistoryCur.states)); 1724 addHistoryRecordLocked(SystemClock.elapsedRealtime()); 1725 if (mScreenOn) { 1726 if (mScreenBrightnessBin >= 0) { 1727 mScreenBrightnessTimer[mScreenBrightnessBin].stopRunningLocked(this); 1728 } 1729 mScreenBrightnessTimer[bin].startRunningLocked(this); 1730 } 1731 mScreenBrightnessBin = bin; 1732 } 1733 } 1734 1735 public void noteInputEventAtomic() { 1736 mInputEventCounter.stepAtomic(); 1737 } 1738 1739 public void noteUserActivityLocked(int uid, int event) { 1740 getUidStatsLocked(uid).noteUserActivityLocked(event); 1741 } 1742 1743 public void notePhoneOnLocked() { 1744 if (!mPhoneOn) { 1745 mHistoryCur.states |= HistoryItem.STATE_PHONE_IN_CALL_FLAG; 1746 if (DEBUG_HISTORY) Slog.v(TAG, "Phone on to: " 1747 + Integer.toHexString(mHistoryCur.states)); 1748 addHistoryRecordLocked(SystemClock.elapsedRealtime()); 1749 mPhoneOn = true; 1750 mPhoneOnTimer.startRunningLocked(this); 1751 } 1752 } 1753 1754 public void notePhoneOffLocked() { 1755 if (mPhoneOn) { 1756 mHistoryCur.states &= ~HistoryItem.STATE_PHONE_IN_CALL_FLAG; 1757 if (DEBUG_HISTORY) Slog.v(TAG, "Phone off to: " 1758 + Integer.toHexString(mHistoryCur.states)); 1759 addHistoryRecordLocked(SystemClock.elapsedRealtime()); 1760 mPhoneOn = false; 1761 mPhoneOnTimer.stopRunningLocked(this); 1762 } 1763 } 1764 1765 void stopAllSignalStrengthTimersLocked(int except) { 1766 for (int i = 0; i < SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) { 1767 if (i == except) { 1768 continue; 1769 } 1770 while (mPhoneSignalStrengthsTimer[i].isRunningLocked()) { 1771 mPhoneSignalStrengthsTimer[i].stopRunningLocked(this); 1772 } 1773 } 1774 } 1775 1776 private int fixPhoneServiceState(int state, int signalBin) { 1777 if (mPhoneSimStateRaw == TelephonyManager.SIM_STATE_ABSENT) { 1778 // In this case we will always be STATE_OUT_OF_SERVICE, so need 1779 // to infer that we are scanning from other data. 1780 if (state == ServiceState.STATE_OUT_OF_SERVICE 1781 && signalBin > SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN) { 1782 state = ServiceState.STATE_IN_SERVICE; 1783 } 1784 } 1785 1786 return state; 1787 } 1788 1789 private void updateAllPhoneStateLocked(int state, int simState, int bin) { 1790 boolean scanning = false; 1791 boolean newHistory = false; 1792 1793 mPhoneServiceStateRaw = state; 1794 mPhoneSimStateRaw = simState; 1795 mPhoneSignalStrengthBinRaw = bin; 1796 1797 if (simState == TelephonyManager.SIM_STATE_ABSENT) { 1798 // In this case we will always be STATE_OUT_OF_SERVICE, so need 1799 // to infer that we are scanning from other data. 1800 if (state == ServiceState.STATE_OUT_OF_SERVICE 1801 && bin > SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN) { 1802 state = ServiceState.STATE_IN_SERVICE; 1803 } 1804 } 1805 1806 // If the phone is powered off, stop all timers. 1807 if (state == ServiceState.STATE_POWER_OFF) { 1808 bin = -1; 1809 1810 // If we are in service, make sure the correct signal string timer is running. 1811 } else if (state == ServiceState.STATE_IN_SERVICE) { 1812 // Bin will be changed below. 1813 1814 // If we're out of service, we are in the lowest signal strength 1815 // bin and have the scanning bit set. 1816 } else if (state == ServiceState.STATE_OUT_OF_SERVICE) { 1817 scanning = true; 1818 bin = SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN; 1819 if (!mPhoneSignalScanningTimer.isRunningLocked()) { 1820 mHistoryCur.states |= HistoryItem.STATE_PHONE_SCANNING_FLAG; 1821 newHistory = true; 1822 if (DEBUG_HISTORY) Slog.v(TAG, "Phone started scanning to: " 1823 + Integer.toHexString(mHistoryCur.states)); 1824 mPhoneSignalScanningTimer.startRunningLocked(this); 1825 } 1826 } 1827 1828 if (!scanning) { 1829 // If we are no longer scanning, then stop the scanning timer. 1830 if (mPhoneSignalScanningTimer.isRunningLocked()) { 1831 mHistoryCur.states &= ~HistoryItem.STATE_PHONE_SCANNING_FLAG; 1832 if (DEBUG_HISTORY) Slog.v(TAG, "Phone stopped scanning to: " 1833 + Integer.toHexString(mHistoryCur.states)); 1834 newHistory = true; 1835 mPhoneSignalScanningTimer.stopRunningLocked(this); 1836 } 1837 } 1838 1839 if (mPhoneServiceState != state) { 1840 mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_PHONE_STATE_MASK) 1841 | (state << HistoryItem.STATE_PHONE_STATE_SHIFT); 1842 if (DEBUG_HISTORY) Slog.v(TAG, "Phone state " + state + " to: " 1843 + Integer.toHexString(mHistoryCur.states)); 1844 newHistory = true; 1845 mPhoneServiceState = state; 1846 } 1847 1848 if (mPhoneSignalStrengthBin != bin) { 1849 if (mPhoneSignalStrengthBin >= 0) { 1850 mPhoneSignalStrengthsTimer[mPhoneSignalStrengthBin].stopRunningLocked(this); 1851 } 1852 if (bin >= 0) { 1853 if (!mPhoneSignalStrengthsTimer[bin].isRunningLocked()) { 1854 mPhoneSignalStrengthsTimer[bin].startRunningLocked(this); 1855 } 1856 mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_SIGNAL_STRENGTH_MASK) 1857 | (bin << HistoryItem.STATE_SIGNAL_STRENGTH_SHIFT); 1858 if (DEBUG_HISTORY) Slog.v(TAG, "Signal strength " + bin + " to: " 1859 + Integer.toHexString(mHistoryCur.states)); 1860 newHistory = true; 1861 } else { 1862 stopAllSignalStrengthTimersLocked(-1); 1863 } 1864 mPhoneSignalStrengthBin = bin; 1865 } 1866 1867 if (newHistory) { 1868 addHistoryRecordLocked(SystemClock.elapsedRealtime()); 1869 } 1870 } 1871 1872 /** 1873 * Telephony stack updates the phone state. 1874 * @param state phone state from ServiceState.getState() 1875 */ 1876 public void notePhoneStateLocked(int state, int simState) { 1877 updateAllPhoneStateLocked(state, simState, mPhoneSignalStrengthBinRaw); 1878 } 1879 1880 public void notePhoneSignalStrengthLocked(SignalStrength signalStrength) { 1881 // Bin the strength. 1882 int bin = signalStrength.getLevel(); 1883 updateAllPhoneStateLocked(mPhoneServiceStateRaw, mPhoneSimStateRaw, bin); 1884 } 1885 1886 public void notePhoneDataConnectionStateLocked(int dataType, boolean hasData) { 1887 int bin = DATA_CONNECTION_NONE; 1888 if (hasData) { 1889 switch (dataType) { 1890 case TelephonyManager.NETWORK_TYPE_EDGE: 1891 bin = DATA_CONNECTION_EDGE; 1892 break; 1893 case TelephonyManager.NETWORK_TYPE_GPRS: 1894 bin = DATA_CONNECTION_GPRS; 1895 break; 1896 case TelephonyManager.NETWORK_TYPE_UMTS: 1897 bin = DATA_CONNECTION_UMTS; 1898 break; 1899 case TelephonyManager.NETWORK_TYPE_CDMA: 1900 bin = DATA_CONNECTION_CDMA; 1901 break; 1902 case TelephonyManager.NETWORK_TYPE_EVDO_0: 1903 bin = DATA_CONNECTION_EVDO_0; 1904 break; 1905 case TelephonyManager.NETWORK_TYPE_EVDO_A: 1906 bin = DATA_CONNECTION_EVDO_A; 1907 break; 1908 case TelephonyManager.NETWORK_TYPE_1xRTT: 1909 bin = DATA_CONNECTION_1xRTT; 1910 break; 1911 case TelephonyManager.NETWORK_TYPE_HSDPA: 1912 bin = DATA_CONNECTION_HSDPA; 1913 break; 1914 case TelephonyManager.NETWORK_TYPE_HSUPA: 1915 bin = DATA_CONNECTION_HSUPA; 1916 break; 1917 case TelephonyManager.NETWORK_TYPE_HSPA: 1918 bin = DATA_CONNECTION_HSPA; 1919 break; 1920 case TelephonyManager.NETWORK_TYPE_IDEN: 1921 bin = DATA_CONNECTION_IDEN; 1922 break; 1923 case TelephonyManager.NETWORK_TYPE_EVDO_B: 1924 bin = DATA_CONNECTION_EVDO_B; 1925 break; 1926 case TelephonyManager.NETWORK_TYPE_LTE: 1927 bin = DATA_CONNECTION_LTE; 1928 break; 1929 case TelephonyManager.NETWORK_TYPE_EHRPD: 1930 bin = DATA_CONNECTION_EHRPD; 1931 break; 1932 default: 1933 bin = DATA_CONNECTION_OTHER; 1934 break; 1935 } 1936 } 1937 if (DEBUG) Log.i(TAG, "Phone Data Connection -> " + dataType + " = " + hasData); 1938 if (mPhoneDataConnectionType != bin) { 1939 mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_DATA_CONNECTION_MASK) 1940 | (bin << HistoryItem.STATE_DATA_CONNECTION_SHIFT); 1941 if (DEBUG_HISTORY) Slog.v(TAG, "Data connection " + bin + " to: " 1942 + Integer.toHexString(mHistoryCur.states)); 1943 addHistoryRecordLocked(SystemClock.elapsedRealtime()); 1944 if (mPhoneDataConnectionType >= 0) { 1945 mPhoneDataConnectionsTimer[mPhoneDataConnectionType].stopRunningLocked(this); 1946 } 1947 mPhoneDataConnectionType = bin; 1948 mPhoneDataConnectionsTimer[bin].startRunningLocked(this); 1949 } 1950 } 1951 1952 public void noteWifiOnLocked() { 1953 if (!mWifiOn) { 1954 mHistoryCur.states |= HistoryItem.STATE_WIFI_ON_FLAG; 1955 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI on to: " 1956 + Integer.toHexString(mHistoryCur.states)); 1957 addHistoryRecordLocked(SystemClock.elapsedRealtime()); 1958 mWifiOn = true; 1959 mWifiOnTimer.startRunningLocked(this); 1960 } 1961 } 1962 1963 public void noteWifiOffLocked() { 1964 if (mWifiOn) { 1965 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_ON_FLAG; 1966 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI off to: " 1967 + Integer.toHexString(mHistoryCur.states)); 1968 addHistoryRecordLocked(SystemClock.elapsedRealtime()); 1969 mWifiOn = false; 1970 mWifiOnTimer.stopRunningLocked(this); 1971 } 1972 if (mWifiOnUid >= 0) { 1973 getUidStatsLocked(mWifiOnUid).noteWifiStoppedLocked(); 1974 mWifiOnUid = -1; 1975 } 1976 } 1977 1978 public void noteAudioOnLocked(int uid) { 1979 if (!mAudioOn) { 1980 mHistoryCur.states |= HistoryItem.STATE_AUDIO_ON_FLAG; 1981 if (DEBUG_HISTORY) Slog.v(TAG, "Audio on to: " 1982 + Integer.toHexString(mHistoryCur.states)); 1983 addHistoryRecordLocked(SystemClock.elapsedRealtime()); 1984 mAudioOn = true; 1985 mAudioOnTimer.startRunningLocked(this); 1986 } 1987 getUidStatsLocked(uid).noteAudioTurnedOnLocked(); 1988 } 1989 1990 public void noteAudioOffLocked(int uid) { 1991 if (mAudioOn) { 1992 mHistoryCur.states &= ~HistoryItem.STATE_AUDIO_ON_FLAG; 1993 if (DEBUG_HISTORY) Slog.v(TAG, "Audio off to: " 1994 + Integer.toHexString(mHistoryCur.states)); 1995 addHistoryRecordLocked(SystemClock.elapsedRealtime()); 1996 mAudioOn = false; 1997 mAudioOnTimer.stopRunningLocked(this); 1998 } 1999 getUidStatsLocked(uid).noteAudioTurnedOffLocked(); 2000 } 2001 2002 public void noteVideoOnLocked(int uid) { 2003 if (!mVideoOn) { 2004 mHistoryCur.states |= HistoryItem.STATE_VIDEO_ON_FLAG; 2005 if (DEBUG_HISTORY) Slog.v(TAG, "Video on to: " 2006 + Integer.toHexString(mHistoryCur.states)); 2007 addHistoryRecordLocked(SystemClock.elapsedRealtime()); 2008 mVideoOn = true; 2009 mVideoOnTimer.startRunningLocked(this); 2010 } 2011 getUidStatsLocked(uid).noteVideoTurnedOnLocked(); 2012 } 2013 2014 public void noteVideoOffLocked(int uid) { 2015 if (mVideoOn) { 2016 mHistoryCur.states &= ~HistoryItem.STATE_VIDEO_ON_FLAG; 2017 if (DEBUG_HISTORY) Slog.v(TAG, "Video off to: " 2018 + Integer.toHexString(mHistoryCur.states)); 2019 addHistoryRecordLocked(SystemClock.elapsedRealtime()); 2020 mVideoOn = false; 2021 mVideoOnTimer.stopRunningLocked(this); 2022 } 2023 getUidStatsLocked(uid).noteVideoTurnedOffLocked(); 2024 } 2025 2026 public void noteWifiRunningLocked(WorkSource ws) { 2027 if (!mGlobalWifiRunning) { 2028 mHistoryCur.states |= HistoryItem.STATE_WIFI_RUNNING_FLAG; 2029 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI running to: " 2030 + Integer.toHexString(mHistoryCur.states)); 2031 addHistoryRecordLocked(SystemClock.elapsedRealtime()); 2032 mGlobalWifiRunning = true; 2033 mGlobalWifiRunningTimer.startRunningLocked(this); 2034 int N = ws.size(); 2035 for (int i=0; i<N; i++) { 2036 getUidStatsLocked(ws.get(i)).noteWifiRunningLocked(); 2037 } 2038 } else { 2039 Log.w(TAG, "noteWifiRunningLocked -- called while WIFI running"); 2040 } 2041 } 2042 2043 public void noteWifiRunningChangedLocked(WorkSource oldWs, WorkSource newWs) { 2044 if (mGlobalWifiRunning) { 2045 int N = oldWs.size(); 2046 for (int i=0; i<N; i++) { 2047 getUidStatsLocked(oldWs.get(i)).noteWifiStoppedLocked(); 2048 } 2049 N = newWs.size(); 2050 for (int i=0; i<N; i++) { 2051 getUidStatsLocked(newWs.get(i)).noteWifiRunningLocked(); 2052 } 2053 } else { 2054 Log.w(TAG, "noteWifiRunningChangedLocked -- called while WIFI not running"); 2055 } 2056 } 2057 2058 public void noteWifiStoppedLocked(WorkSource ws) { 2059 if (mGlobalWifiRunning) { 2060 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_RUNNING_FLAG; 2061 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI stopped to: " 2062 + Integer.toHexString(mHistoryCur.states)); 2063 addHistoryRecordLocked(SystemClock.elapsedRealtime()); 2064 mGlobalWifiRunning = false; 2065 mGlobalWifiRunningTimer.stopRunningLocked(this); 2066 int N = ws.size(); 2067 for (int i=0; i<N; i++) { 2068 getUidStatsLocked(ws.get(i)).noteWifiStoppedLocked(); 2069 } 2070 } else { 2071 Log.w(TAG, "noteWifiStoppedLocked -- called while WIFI not running"); 2072 } 2073 } 2074 2075 public void noteBluetoothOnLocked() { 2076 if (!mBluetoothOn) { 2077 mHistoryCur.states |= HistoryItem.STATE_BLUETOOTH_ON_FLAG; 2078 if (DEBUG_HISTORY) Slog.v(TAG, "Bluetooth on to: " 2079 + Integer.toHexString(mHistoryCur.states)); 2080 addHistoryRecordLocked(SystemClock.elapsedRealtime()); 2081 mBluetoothOn = true; 2082 mBluetoothOnTimer.startRunningLocked(this); 2083 } 2084 } 2085 2086 public void noteBluetoothOffLocked() { 2087 if (mBluetoothOn) { 2088 mHistoryCur.states &= ~HistoryItem.STATE_BLUETOOTH_ON_FLAG; 2089 if (DEBUG_HISTORY) Slog.v(TAG, "Bluetooth off to: " 2090 + Integer.toHexString(mHistoryCur.states)); 2091 addHistoryRecordLocked(SystemClock.elapsedRealtime()); 2092 mBluetoothOn = false; 2093 mBluetoothOnTimer.stopRunningLocked(this); 2094 } 2095 } 2096 2097 int mWifiFullLockNesting = 0; 2098 2099 public void noteFullWifiLockAcquiredLocked(int uid) { 2100 if (mWifiFullLockNesting == 0) { 2101 mHistoryCur.states |= HistoryItem.STATE_WIFI_FULL_LOCK_FLAG; 2102 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI full lock on to: " 2103 + Integer.toHexString(mHistoryCur.states)); 2104 addHistoryRecordLocked(SystemClock.elapsedRealtime()); 2105 } 2106 mWifiFullLockNesting++; 2107 getUidStatsLocked(uid).noteFullWifiLockAcquiredLocked(); 2108 } 2109 2110 public void noteFullWifiLockReleasedLocked(int uid) { 2111 mWifiFullLockNesting--; 2112 if (mWifiFullLockNesting == 0) { 2113 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_FULL_LOCK_FLAG; 2114 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI full lock off to: " 2115 + Integer.toHexString(mHistoryCur.states)); 2116 addHistoryRecordLocked(SystemClock.elapsedRealtime()); 2117 } 2118 getUidStatsLocked(uid).noteFullWifiLockReleasedLocked(); 2119 } 2120 2121 int mWifiScanLockNesting = 0; 2122 2123 public void noteScanWifiLockAcquiredLocked(int uid) { 2124 if (mWifiScanLockNesting == 0) { 2125 mHistoryCur.states |= HistoryItem.STATE_WIFI_SCAN_LOCK_FLAG; 2126 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI scan lock on to: " 2127 + Integer.toHexString(mHistoryCur.states)); 2128 addHistoryRecordLocked(SystemClock.elapsedRealtime()); 2129 } 2130 mWifiScanLockNesting++; 2131 getUidStatsLocked(uid).noteScanWifiLockAcquiredLocked(); 2132 } 2133 2134 public void noteScanWifiLockReleasedLocked(int uid) { 2135 mWifiScanLockNesting--; 2136 if (mWifiScanLockNesting == 0) { 2137 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_SCAN_LOCK_FLAG; 2138 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI scan lock off to: " 2139 + Integer.toHexString(mHistoryCur.states)); 2140 addHistoryRecordLocked(SystemClock.elapsedRealtime()); 2141 } 2142 getUidStatsLocked(uid).noteScanWifiLockReleasedLocked(); 2143 } 2144 2145 int mWifiMulticastNesting = 0; 2146 2147 public void noteWifiMulticastEnabledLocked(int uid) { 2148 if (mWifiMulticastNesting == 0) { 2149 mHistoryCur.states |= HistoryItem.STATE_WIFI_MULTICAST_ON_FLAG; 2150 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI multicast on to: " 2151 + Integer.toHexString(mHistoryCur.states)); 2152 addHistoryRecordLocked(SystemClock.elapsedRealtime()); 2153 } 2154 mWifiMulticastNesting++; 2155 getUidStatsLocked(uid).noteWifiMulticastEnabledLocked(); 2156 } 2157 2158 public void noteWifiMulticastDisabledLocked(int uid) { 2159 mWifiMulticastNesting--; 2160 if (mWifiMulticastNesting == 0) { 2161 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_MULTICAST_ON_FLAG; 2162 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI multicast off to: " 2163 + Integer.toHexString(mHistoryCur.states)); 2164 addHistoryRecordLocked(SystemClock.elapsedRealtime()); 2165 } 2166 getUidStatsLocked(uid).noteWifiMulticastDisabledLocked(); 2167 } 2168 2169 public void noteFullWifiLockAcquiredFromSourceLocked(WorkSource ws) { 2170 int N = ws.size(); 2171 for (int i=0; i<N; i++) { 2172 noteFullWifiLockAcquiredLocked(ws.get(i)); 2173 } 2174 } 2175 2176 public void noteFullWifiLockReleasedFromSourceLocked(WorkSource ws) { 2177 int N = ws.size(); 2178 for (int i=0; i<N; i++) { 2179 noteFullWifiLockReleasedLocked(ws.get(i)); 2180 } 2181 } 2182 2183 public void noteScanWifiLockAcquiredFromSourceLocked(WorkSource ws) { 2184 int N = ws.size(); 2185 for (int i=0; i<N; i++) { 2186 noteScanWifiLockAcquiredLocked(ws.get(i)); 2187 } 2188 } 2189 2190 public void noteScanWifiLockReleasedFromSourceLocked(WorkSource ws) { 2191 int N = ws.size(); 2192 for (int i=0; i<N; i++) { 2193 noteScanWifiLockReleasedLocked(ws.get(i)); 2194 } 2195 } 2196 2197 public void noteWifiMulticastEnabledFromSourceLocked(WorkSource ws) { 2198 int N = ws.size(); 2199 for (int i=0; i<N; i++) { 2200 noteWifiMulticastEnabledLocked(ws.get(i)); 2201 } 2202 } 2203 2204 public void noteWifiMulticastDisabledFromSourceLocked(WorkSource ws) { 2205 int N = ws.size(); 2206 for (int i=0; i<N; i++) { 2207 noteWifiMulticastDisabledLocked(ws.get(i)); 2208 } 2209 } 2210 2211 @Override public long getScreenOnTime(long batteryRealtime, int which) { 2212 return mScreenOnTimer.getTotalTimeLocked(batteryRealtime, which); 2213 } 2214 2215 @Override public long getScreenBrightnessTime(int brightnessBin, 2216 long batteryRealtime, int which) { 2217 return mScreenBrightnessTimer[brightnessBin].getTotalTimeLocked( 2218 batteryRealtime, which); 2219 } 2220 2221 @Override public int getInputEventCount(int which) { 2222 return mInputEventCounter.getCountLocked(which); 2223 } 2224 2225 @Override public long getPhoneOnTime(long batteryRealtime, int which) { 2226 return mPhoneOnTimer.getTotalTimeLocked(batteryRealtime, which); 2227 } 2228 2229 @Override public long getPhoneSignalStrengthTime(int strengthBin, 2230 long batteryRealtime, int which) { 2231 return mPhoneSignalStrengthsTimer[strengthBin].getTotalTimeLocked( 2232 batteryRealtime, which); 2233 } 2234 2235 @Override public long getPhoneSignalScanningTime( 2236 long batteryRealtime, int which) { 2237 return mPhoneSignalScanningTimer.getTotalTimeLocked( 2238 batteryRealtime, which); 2239 } 2240 2241 @Override public int getPhoneSignalStrengthCount(int dataType, int which) { 2242 return mPhoneDataConnectionsTimer[dataType].getCountLocked(which); 2243 } 2244 2245 @Override public long getPhoneDataConnectionTime(int dataType, 2246 long batteryRealtime, int which) { 2247 return mPhoneDataConnectionsTimer[dataType].getTotalTimeLocked( 2248 batteryRealtime, which); 2249 } 2250 2251 @Override public int getPhoneDataConnectionCount(int dataType, int which) { 2252 return mPhoneDataConnectionsTimer[dataType].getCountLocked(which); 2253 } 2254 2255 @Override public long getWifiOnTime(long batteryRealtime, int which) { 2256 return mWifiOnTimer.getTotalTimeLocked(batteryRealtime, which); 2257 } 2258 2259 @Override public long getGlobalWifiRunningTime(long batteryRealtime, int which) { 2260 return mGlobalWifiRunningTimer.getTotalTimeLocked(batteryRealtime, which); 2261 } 2262 2263 @Override public long getBluetoothOnTime(long batteryRealtime, int which) { 2264 return mBluetoothOnTimer.getTotalTimeLocked(batteryRealtime, which); 2265 } 2266 2267 @Override public boolean getIsOnBattery() { 2268 return mOnBattery; 2269 } 2270 2271 @Override public SparseArray<? extends BatteryStats.Uid> getUidStats() { 2272 return mUidStats; 2273 } 2274 2275 /** 2276 * The statistics associated with a particular uid. 2277 */ 2278 public final class Uid extends BatteryStats.Uid { 2279 2280 final int mUid; 2281 long mLoadedTcpBytesReceived; 2282 long mLoadedTcpBytesSent; 2283 long mCurrentTcpBytesReceived; 2284 long mCurrentTcpBytesSent; 2285 long mTcpBytesReceivedAtLastUnplug; 2286 long mTcpBytesSentAtLastUnplug; 2287 2288 // These are not saved/restored when parcelling, since we want 2289 // to return from the parcel with a snapshot of the state. 2290 long mStartedTcpBytesReceived = -1; 2291 long mStartedTcpBytesSent = -1; 2292 2293 boolean mWifiRunning; 2294 StopwatchTimer mWifiRunningTimer; 2295 2296 boolean mFullWifiLockOut; 2297 StopwatchTimer mFullWifiLockTimer; 2298 2299 boolean mScanWifiLockOut; 2300 StopwatchTimer mScanWifiLockTimer; 2301 2302 boolean mWifiMulticastEnabled; 2303 StopwatchTimer mWifiMulticastTimer; 2304 2305 boolean mAudioTurnedOn; 2306 StopwatchTimer mAudioTurnedOnTimer; 2307 2308 boolean mVideoTurnedOn; 2309 StopwatchTimer mVideoTurnedOnTimer; 2310 2311 Counter[] mUserActivityCounters; 2312 2313 /** 2314 * The statistics we have collected for this uid's wake locks. 2315 */ 2316 final HashMap<String, Wakelock> mWakelockStats = new HashMap<String, Wakelock>(); 2317 2318 /** 2319 * The statistics we have collected for this uid's sensor activations. 2320 */ 2321 final HashMap<Integer, Sensor> mSensorStats = new HashMap<Integer, Sensor>(); 2322 2323 /** 2324 * The statistics we have collected for this uid's processes. 2325 */ 2326 final HashMap<String, Proc> mProcessStats = new HashMap<String, Proc>(); 2327 2328 /** 2329 * The statistics we have collected for this uid's processes. 2330 */ 2331 final HashMap<String, Pkg> mPackageStats = new HashMap<String, Pkg>(); 2332 2333 /** 2334 * The transient wake stats we have collected for this uid's pids. 2335 */ 2336 final SparseArray<Pid> mPids = new SparseArray<Pid>(); 2337 2338 public Uid(int uid) { 2339 mUid = uid; 2340 mWifiRunningTimer = new StopwatchTimer(Uid.this, WIFI_RUNNING, 2341 mWifiRunningTimers, mUnpluggables); 2342 mFullWifiLockTimer = new StopwatchTimer(Uid.this, FULL_WIFI_LOCK, 2343 mFullWifiLockTimers, mUnpluggables); 2344 mScanWifiLockTimer = new StopwatchTimer(Uid.this, SCAN_WIFI_LOCK, 2345 mScanWifiLockTimers, mUnpluggables); 2346 mWifiMulticastTimer = new StopwatchTimer(Uid.this, WIFI_MULTICAST_ENABLED, 2347 mWifiMulticastTimers, mUnpluggables); 2348 mAudioTurnedOnTimer = new StopwatchTimer(Uid.this, AUDIO_TURNED_ON, 2349 null, mUnpluggables); 2350 mVideoTurnedOnTimer = new StopwatchTimer(Uid.this, VIDEO_TURNED_ON, 2351 null, mUnpluggables); 2352 } 2353 2354 @Override 2355 public Map<String, ? extends BatteryStats.Uid.Wakelock> getWakelockStats() { 2356 return mWakelockStats; 2357 } 2358 2359 @Override 2360 public Map<Integer, ? extends BatteryStats.Uid.Sensor> getSensorStats() { 2361 return mSensorStats; 2362 } 2363 2364 @Override 2365 public Map<String, ? extends BatteryStats.Uid.Proc> getProcessStats() { 2366 return mProcessStats; 2367 } 2368 2369 @Override 2370 public Map<String, ? extends BatteryStats.Uid.Pkg> getPackageStats() { 2371 return mPackageStats; 2372 } 2373 2374 @Override 2375 public int getUid() { 2376 return mUid; 2377 } 2378 2379 @Override 2380 public long getTcpBytesReceived(int which) { 2381 if (which == STATS_LAST) { 2382 return mLoadedTcpBytesReceived; 2383 } else { 2384 long current = computeCurrentTcpBytesReceived(); 2385 if (which == STATS_SINCE_UNPLUGGED) { 2386 current -= mTcpBytesReceivedAtLastUnplug; 2387 } else if (which == STATS_SINCE_CHARGED) { 2388 current += mLoadedTcpBytesReceived; 2389 } 2390 return current; 2391 } 2392 } 2393 2394 public long computeCurrentTcpBytesReceived() { 2395 return mCurrentTcpBytesReceived + (mStartedTcpBytesReceived >= 0 2396 ? (TrafficStats.getUidRxBytes(mUid) - mStartedTcpBytesReceived) : 0); 2397 } 2398 2399 @Override 2400 public long getTcpBytesSent(int which) { 2401 if (which == STATS_LAST) { 2402 return mLoadedTcpBytesSent; 2403 } else { 2404 long current = computeCurrentTcpBytesSent(); 2405 if (which == STATS_SINCE_UNPLUGGED) { 2406 current -= mTcpBytesSentAtLastUnplug; 2407 } else if (which == STATS_SINCE_CHARGED) { 2408 current += mLoadedTcpBytesSent; 2409 } 2410 return current; 2411 } 2412 } 2413 2414 @Override 2415 public void noteWifiRunningLocked() { 2416 if (!mWifiRunning) { 2417 mWifiRunning = true; 2418 if (mWifiRunningTimer == null) { 2419 mWifiRunningTimer = new StopwatchTimer(Uid.this, WIFI_RUNNING, 2420 mWifiRunningTimers, mUnpluggables); 2421 } 2422 mWifiRunningTimer.startRunningLocked(BatteryStatsImpl.this); 2423 } 2424 } 2425 2426 @Override 2427 public void noteWifiStoppedLocked() { 2428 if (mWifiRunning) { 2429 mWifiRunning = false; 2430 mWifiRunningTimer.stopRunningLocked(BatteryStatsImpl.this); 2431 } 2432 } 2433 2434 @Override 2435 public void noteFullWifiLockAcquiredLocked() { 2436 if (!mFullWifiLockOut) { 2437 mFullWifiLockOut = true; 2438 if (mFullWifiLockTimer == null) { 2439 mFullWifiLockTimer = new StopwatchTimer(Uid.this, FULL_WIFI_LOCK, 2440 mFullWifiLockTimers, mUnpluggables); 2441 } 2442 mFullWifiLockTimer.startRunningLocked(BatteryStatsImpl.this); 2443 } 2444 } 2445 2446 @Override 2447 public void noteFullWifiLockReleasedLocked() { 2448 if (mFullWifiLockOut) { 2449 mFullWifiLockOut = false; 2450 mFullWifiLockTimer.stopRunningLocked(BatteryStatsImpl.this); 2451 } 2452 } 2453 2454 @Override 2455 public void noteScanWifiLockAcquiredLocked() { 2456 if (!mScanWifiLockOut) { 2457 mScanWifiLockOut = true; 2458 if (mScanWifiLockTimer == null) { 2459 mScanWifiLockTimer = new StopwatchTimer(Uid.this, SCAN_WIFI_LOCK, 2460 mScanWifiLockTimers, mUnpluggables); 2461 } 2462 mScanWifiLockTimer.startRunningLocked(BatteryStatsImpl.this); 2463 } 2464 } 2465 2466 @Override 2467 public void noteScanWifiLockReleasedLocked() { 2468 if (mScanWifiLockOut) { 2469 mScanWifiLockOut = false; 2470 mScanWifiLockTimer.stopRunningLocked(BatteryStatsImpl.this); 2471 } 2472 } 2473 2474 @Override 2475 public void noteWifiMulticastEnabledLocked() { 2476 if (!mWifiMulticastEnabled) { 2477 mWifiMulticastEnabled = true; 2478 if (mWifiMulticastTimer == null) { 2479 mWifiMulticastTimer = new StopwatchTimer(Uid.this, WIFI_MULTICAST_ENABLED, 2480 mWifiMulticastTimers, mUnpluggables); 2481 } 2482 mWifiMulticastTimer.startRunningLocked(BatteryStatsImpl.this); 2483 } 2484 } 2485 2486 @Override 2487 public void noteWifiMulticastDisabledLocked() { 2488 if (mWifiMulticastEnabled) { 2489 mWifiMulticastEnabled = false; 2490 mWifiMulticastTimer.stopRunningLocked(BatteryStatsImpl.this); 2491 } 2492 } 2493 2494 @Override 2495 public void noteAudioTurnedOnLocked() { 2496 if (!mAudioTurnedOn) { 2497 mAudioTurnedOn = true; 2498 if (mAudioTurnedOnTimer == null) { 2499 mAudioTurnedOnTimer = new StopwatchTimer(Uid.this, AUDIO_TURNED_ON, 2500 null, mUnpluggables); 2501 } 2502 mAudioTurnedOnTimer.startRunningLocked(BatteryStatsImpl.this); 2503 } 2504 } 2505 2506 @Override 2507 public void noteAudioTurnedOffLocked() { 2508 if (mAudioTurnedOn) { 2509 mAudioTurnedOn = false; 2510 mAudioTurnedOnTimer.stopRunningLocked(BatteryStatsImpl.this); 2511 } 2512 } 2513 2514 @Override 2515 public void noteVideoTurnedOnLocked() { 2516 if (!mVideoTurnedOn) { 2517 mVideoTurnedOn = true; 2518 if (mVideoTurnedOnTimer == null) { 2519 mVideoTurnedOnTimer = new StopwatchTimer(Uid.this, VIDEO_TURNED_ON, 2520 null, mUnpluggables); 2521 } 2522 mVideoTurnedOnTimer.startRunningLocked(BatteryStatsImpl.this); 2523 } 2524 } 2525 2526 @Override 2527 public void noteVideoTurnedOffLocked() { 2528 if (mVideoTurnedOn) { 2529 mVideoTurnedOn = false; 2530 mVideoTurnedOnTimer.stopRunningLocked(BatteryStatsImpl.this); 2531 } 2532 } 2533 2534 @Override 2535 public long getWifiRunningTime(long batteryRealtime, int which) { 2536 if (mWifiRunningTimer == null) { 2537 return 0; 2538 } 2539 return mWifiRunningTimer.getTotalTimeLocked(batteryRealtime, which); 2540 } 2541 2542 @Override 2543 public long getFullWifiLockTime(long batteryRealtime, int which) { 2544 if (mFullWifiLockTimer == null) { 2545 return 0; 2546 } 2547 return mFullWifiLockTimer.getTotalTimeLocked(batteryRealtime, which); 2548 } 2549 2550 @Override 2551 public long getScanWifiLockTime(long batteryRealtime, int which) { 2552 if (mScanWifiLockTimer == null) { 2553 return 0; 2554 } 2555 return mScanWifiLockTimer.getTotalTimeLocked(batteryRealtime, which); 2556 } 2557 2558 @Override 2559 public long getWifiMulticastTime(long batteryRealtime, int which) { 2560 if (mWifiMulticastTimer == null) { 2561 return 0; 2562 } 2563 return mWifiMulticastTimer.getTotalTimeLocked(batteryRealtime, 2564 which); 2565 } 2566 2567 @Override 2568 public long getAudioTurnedOnTime(long batteryRealtime, int which) { 2569 if (mAudioTurnedOnTimer == null) { 2570 return 0; 2571 } 2572 return mAudioTurnedOnTimer.getTotalTimeLocked(batteryRealtime, which); 2573 } 2574 2575 @Override 2576 public long getVideoTurnedOnTime(long batteryRealtime, int which) { 2577 if (mVideoTurnedOnTimer == null) { 2578 return 0; 2579 } 2580 return mVideoTurnedOnTimer.getTotalTimeLocked(batteryRealtime, which); 2581 } 2582 2583 @Override 2584 public void noteUserActivityLocked(int type) { 2585 if (mUserActivityCounters == null) { 2586 initUserActivityLocked(); 2587 } 2588 if (type < 0) type = 0; 2589 else if (type >= NUM_USER_ACTIVITY_TYPES) type = NUM_USER_ACTIVITY_TYPES-1; 2590 mUserActivityCounters[type].stepAtomic(); 2591 } 2592 2593 @Override 2594 public boolean hasUserActivity() { 2595 return mUserActivityCounters != null; 2596 } 2597 2598 @Override 2599 public int getUserActivityCount(int type, int which) { 2600 if (mUserActivityCounters == null) { 2601 return 0; 2602 } 2603 return mUserActivityCounters[type].getCountLocked(which); 2604 } 2605 2606 void initUserActivityLocked() { 2607 mUserActivityCounters = new Counter[NUM_USER_ACTIVITY_TYPES]; 2608 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) { 2609 mUserActivityCounters[i] = new Counter(mUnpluggables); 2610 } 2611 } 2612 2613 public long computeCurrentTcpBytesSent() { 2614 return mCurrentTcpBytesSent + (mStartedTcpBytesSent >= 0 2615 ? (TrafficStats.getUidTxBytes(mUid) - mStartedTcpBytesSent) : 0); 2616 } 2617 2618 /** 2619 * Clear all stats for this uid. Returns true if the uid is completely 2620 * inactive so can be dropped. 2621 */ 2622 boolean reset() { 2623 boolean active = false; 2624 2625 if (mWifiRunningTimer != null) { 2626 active |= !mWifiRunningTimer.reset(BatteryStatsImpl.this, false); 2627 active |= mWifiRunning; 2628 } 2629 if (mFullWifiLockTimer != null) { 2630 active |= !mFullWifiLockTimer.reset(BatteryStatsImpl.this, false); 2631 active |= mFullWifiLockOut; 2632 } 2633 if (mScanWifiLockTimer != null) { 2634 active |= !mScanWifiLockTimer.reset(BatteryStatsImpl.this, false); 2635 active |= mScanWifiLockOut; 2636 } 2637 if (mWifiMulticastTimer != null) { 2638 active |= !mWifiMulticastTimer.reset(BatteryStatsImpl.this, false); 2639 active |= mWifiMulticastEnabled; 2640 } 2641 if (mAudioTurnedOnTimer != null) { 2642 active |= !mAudioTurnedOnTimer.reset(BatteryStatsImpl.this, false); 2643 active |= mAudioTurnedOn; 2644 } 2645 if (mVideoTurnedOnTimer != null) { 2646 active |= !mVideoTurnedOnTimer.reset(BatteryStatsImpl.this, false); 2647 active |= mVideoTurnedOn; 2648 } 2649 2650 mLoadedTcpBytesReceived = mLoadedTcpBytesSent = 0; 2651 mCurrentTcpBytesReceived = mCurrentTcpBytesSent = 0; 2652 2653 if (mUserActivityCounters != null) { 2654 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) { 2655 mUserActivityCounters[i].reset(false); 2656 } 2657 } 2658 2659 if (mWakelockStats.size() > 0) { 2660 Iterator<Map.Entry<String, Wakelock>> it = mWakelockStats.entrySet().iterator(); 2661 while (it.hasNext()) { 2662 Map.Entry<String, Wakelock> wakelockEntry = it.next(); 2663 Wakelock wl = wakelockEntry.getValue(); 2664 if (wl.reset()) { 2665 it.remove(); 2666 } else { 2667 active = true; 2668 } 2669 } 2670 } 2671 if (mSensorStats.size() > 0) { 2672 Iterator<Map.Entry<Integer, Sensor>> it = mSensorStats.entrySet().iterator(); 2673 while (it.hasNext()) { 2674 Map.Entry<Integer, Sensor> sensorEntry = it.next(); 2675 Sensor s = sensorEntry.getValue(); 2676 if (s.reset()) { 2677 it.remove(); 2678 } else { 2679 active = true; 2680 } 2681 } 2682 } 2683 if (mProcessStats.size() > 0) { 2684 Iterator<Map.Entry<String, Proc>> it = mProcessStats.entrySet().iterator(); 2685 while (it.hasNext()) { 2686 Map.Entry<String, Proc> procEntry = it.next(); 2687 procEntry.getValue().detach(); 2688 } 2689 mProcessStats.clear(); 2690 } 2691 if (mPids.size() > 0) { 2692 for (int i=0; !active && i<mPids.size(); i++) { 2693 Pid pid = mPids.valueAt(i); 2694 if (pid.mWakeStart != 0) { 2695 active = true; 2696 } 2697 } 2698 } 2699 if (mPackageStats.size() > 0) { 2700 Iterator<Map.Entry<String, Pkg>> it = mPackageStats.entrySet().iterator(); 2701 while (it.hasNext()) { 2702 Map.Entry<String, Pkg> pkgEntry = it.next(); 2703 Pkg p = pkgEntry.getValue(); 2704 p.detach(); 2705 if (p.mServiceStats.size() > 0) { 2706 Iterator<Map.Entry<String, Pkg.Serv>> it2 2707 = p.mServiceStats.entrySet().iterator(); 2708 while (it2.hasNext()) { 2709 Map.Entry<String, Pkg.Serv> servEntry = it2.next(); 2710 servEntry.getValue().detach(); 2711 } 2712 } 2713 } 2714 mPackageStats.clear(); 2715 } 2716 2717 mPids.clear(); 2718 2719 if (!active) { 2720 if (mWifiRunningTimer != null) { 2721 mWifiRunningTimer.detach(); 2722 } 2723 if (mFullWifiLockTimer != null) { 2724 mFullWifiLockTimer.detach(); 2725 } 2726 if (mScanWifiLockTimer != null) { 2727 mScanWifiLockTimer.detach(); 2728 } 2729 if (mWifiMulticastTimer != null) { 2730 mWifiMulticastTimer.detach(); 2731 } 2732 if (mAudioTurnedOnTimer != null) { 2733 mAudioTurnedOnTimer.detach(); 2734 } 2735 if (mVideoTurnedOnTimer != null) { 2736 mVideoTurnedOnTimer.detach(); 2737 } 2738 if (mUserActivityCounters != null) { 2739 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) { 2740 mUserActivityCounters[i].detach(); 2741 } 2742 } 2743 } 2744 2745 return !active; 2746 } 2747 2748 void writeToParcelLocked(Parcel out, long batteryRealtime) { 2749 out.writeInt(mWakelockStats.size()); 2750 for (Map.Entry<String, Uid.Wakelock> wakelockEntry : mWakelockStats.entrySet()) { 2751 out.writeString(wakelockEntry.getKey()); 2752 Uid.Wakelock wakelock = wakelockEntry.getValue(); 2753 wakelock.writeToParcelLocked(out, batteryRealtime); 2754 } 2755 2756 out.writeInt(mSensorStats.size()); 2757 for (Map.Entry<Integer, Uid.Sensor> sensorEntry : mSensorStats.entrySet()) { 2758 out.writeInt(sensorEntry.getKey()); 2759 Uid.Sensor sensor = sensorEntry.getValue(); 2760 sensor.writeToParcelLocked(out, batteryRealtime); 2761 } 2762 2763 out.writeInt(mProcessStats.size()); 2764 for (Map.Entry<String, Uid.Proc> procEntry : mProcessStats.entrySet()) { 2765 out.writeString(procEntry.getKey()); 2766 Uid.Proc proc = procEntry.getValue(); 2767 proc.writeToParcelLocked(out); 2768 } 2769 2770 out.writeInt(mPackageStats.size()); 2771 for (Map.Entry<String, Uid.Pkg> pkgEntry : mPackageStats.entrySet()) { 2772 out.writeString(pkgEntry.getKey()); 2773 Uid.Pkg pkg = pkgEntry.getValue(); 2774 pkg.writeToParcelLocked(out); 2775 } 2776 2777 out.writeLong(mLoadedTcpBytesReceived); 2778 out.writeLong(mLoadedTcpBytesSent); 2779 out.writeLong(computeCurrentTcpBytesReceived()); 2780 out.writeLong(computeCurrentTcpBytesSent()); 2781 out.writeLong(mTcpBytesReceivedAtLastUnplug); 2782 out.writeLong(mTcpBytesSentAtLastUnplug); 2783 if (mWifiRunningTimer != null) { 2784 out.writeInt(1); 2785 mWifiRunningTimer.writeToParcel(out, batteryRealtime); 2786 } else { 2787 out.writeInt(0); 2788 } 2789 if (mFullWifiLockTimer != null) { 2790 out.writeInt(1); 2791 mFullWifiLockTimer.writeToParcel(out, batteryRealtime); 2792 } else { 2793 out.writeInt(0); 2794 } 2795 if (mScanWifiLockTimer != null) { 2796 out.writeInt(1); 2797 mScanWifiLockTimer.writeToParcel(out, batteryRealtime); 2798 } else { 2799 out.writeInt(0); 2800 } 2801 if (mWifiMulticastTimer != null) { 2802 out.writeInt(1); 2803 mWifiMulticastTimer.writeToParcel(out, batteryRealtime); 2804 } else { 2805 out.writeInt(0); 2806 } 2807 if (mAudioTurnedOnTimer != null) { 2808 out.writeInt(1); 2809 mAudioTurnedOnTimer.writeToParcel(out, batteryRealtime); 2810 } else { 2811 out.writeInt(0); 2812 } 2813 if (mVideoTurnedOnTimer != null) { 2814 out.writeInt(1); 2815 mVideoTurnedOnTimer.writeToParcel(out, batteryRealtime); 2816 } else { 2817 out.writeInt(0); 2818 } 2819 if (mUserActivityCounters != null) { 2820 out.writeInt(1); 2821 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) { 2822 mUserActivityCounters[i].writeToParcel(out); 2823 } 2824 } else { 2825 out.writeInt(0); 2826 } 2827 } 2828 2829 void readFromParcelLocked(ArrayList<Unpluggable> unpluggables, Parcel in) { 2830 int numWakelocks = in.readInt(); 2831 mWakelockStats.clear(); 2832 for (int j = 0; j < numWakelocks; j++) { 2833 String wakelockName = in.readString(); 2834 Uid.Wakelock wakelock = new Wakelock(); 2835 wakelock.readFromParcelLocked(unpluggables, in); 2836 if (mWakelockStats.size() < MAX_WAKELOCKS_PER_UID) { 2837 // We will just drop some random set of wakelocks if 2838 // the previous run of the system was an older version 2839 // that didn't impose a limit. 2840 mWakelockStats.put(wakelockName, wakelock); 2841 } 2842 } 2843 2844 int numSensors = in.readInt(); 2845 mSensorStats.clear(); 2846 for (int k = 0; k < numSensors; k++) { 2847 int sensorNumber = in.readInt(); 2848 Uid.Sensor sensor = new Sensor(sensorNumber); 2849 sensor.readFromParcelLocked(mUnpluggables, in); 2850 mSensorStats.put(sensorNumber, sensor); 2851 } 2852 2853 int numProcs = in.readInt(); 2854 mProcessStats.clear(); 2855 for (int k = 0; k < numProcs; k++) { 2856 String processName = in.readString(); 2857 Uid.Proc proc = new Proc(); 2858 proc.readFromParcelLocked(in); 2859 mProcessStats.put(processName, proc); 2860 } 2861 2862 int numPkgs = in.readInt(); 2863 mPackageStats.clear(); 2864 for (int l = 0; l < numPkgs; l++) { 2865 String packageName = in.readString(); 2866 Uid.Pkg pkg = new Pkg(); 2867 pkg.readFromParcelLocked(in); 2868 mPackageStats.put(packageName, pkg); 2869 } 2870 2871 mLoadedTcpBytesReceived = in.readLong(); 2872 mLoadedTcpBytesSent = in.readLong(); 2873 mCurrentTcpBytesReceived = in.readLong(); 2874 mCurrentTcpBytesSent = in.readLong(); 2875 mTcpBytesReceivedAtLastUnplug = in.readLong(); 2876 mTcpBytesSentAtLastUnplug = in.readLong(); 2877 mWifiRunning = false; 2878 if (in.readInt() != 0) { 2879 mWifiRunningTimer = new StopwatchTimer(Uid.this, WIFI_RUNNING, 2880 mWifiRunningTimers, mUnpluggables, in); 2881 } else { 2882 mWifiRunningTimer = null; 2883 } 2884 mFullWifiLockOut = false; 2885 if (in.readInt() != 0) { 2886 mFullWifiLockTimer = new StopwatchTimer(Uid.this, FULL_WIFI_LOCK, 2887 mFullWifiLockTimers, mUnpluggables, in); 2888 } else { 2889 mFullWifiLockTimer = null; 2890 } 2891 mScanWifiLockOut = false; 2892 if (in.readInt() != 0) { 2893 mScanWifiLockTimer = new StopwatchTimer(Uid.this, SCAN_WIFI_LOCK, 2894 mScanWifiLockTimers, mUnpluggables, in); 2895 } else { 2896 mScanWifiLockTimer = null; 2897 } 2898 mWifiMulticastEnabled = false; 2899 if (in.readInt() != 0) { 2900 mWifiMulticastTimer = new StopwatchTimer(Uid.this, WIFI_MULTICAST_ENABLED, 2901 mWifiMulticastTimers, mUnpluggables, in); 2902 } else { 2903 mWifiMulticastTimer = null; 2904 } 2905 mAudioTurnedOn = false; 2906 if (in.readInt() != 0) { 2907 mAudioTurnedOnTimer = new StopwatchTimer(Uid.this, AUDIO_TURNED_ON, 2908 null, mUnpluggables, in); 2909 } else { 2910 mAudioTurnedOnTimer = null; 2911 } 2912 mVideoTurnedOn = false; 2913 if (in.readInt() != 0) { 2914 mVideoTurnedOnTimer = new StopwatchTimer(Uid.this, VIDEO_TURNED_ON, 2915 null, mUnpluggables, in); 2916 } else { 2917 mVideoTurnedOnTimer = null; 2918 } 2919 if (in.readInt() != 0) { 2920 mUserActivityCounters = new Counter[NUM_USER_ACTIVITY_TYPES]; 2921 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) { 2922 mUserActivityCounters[i] = new Counter(mUnpluggables, in); 2923 } 2924 } else { 2925 mUserActivityCounters = null; 2926 } 2927 } 2928 2929 /** 2930 * The statistics associated with a particular wake lock. 2931 */ 2932 public final class Wakelock extends BatteryStats.Uid.Wakelock { 2933 /** 2934 * How long (in ms) this uid has been keeping the device partially awake. 2935 */ 2936 StopwatchTimer mTimerPartial; 2937 2938 /** 2939 * How long (in ms) this uid has been keeping the device fully awake. 2940 */ 2941 StopwatchTimer mTimerFull; 2942 2943 /** 2944 * How long (in ms) this uid has had a window keeping the device awake. 2945 */ 2946 StopwatchTimer mTimerWindow; 2947 2948 /** 2949 * Reads a possibly null Timer from a Parcel. The timer is associated with the 2950 * proper timer pool from the given BatteryStatsImpl object. 2951 * 2952 * @param in the Parcel to be read from. 2953 * return a new Timer, or null. 2954 */ 2955 private StopwatchTimer readTimerFromParcel(int type, ArrayList<StopwatchTimer> pool, 2956 ArrayList<Unpluggable> unpluggables, Parcel in) { 2957 if (in.readInt() == 0) { 2958 return null; 2959 } 2960 2961 return new StopwatchTimer(Uid.this, type, pool, unpluggables, in); 2962 } 2963 2964 boolean reset() { 2965 boolean wlactive = false; 2966 if (mTimerFull != null) { 2967 wlactive |= !mTimerFull.reset(BatteryStatsImpl.this, false); 2968 } 2969 if (mTimerPartial != null) { 2970 wlactive |= !mTimerPartial.reset(BatteryStatsImpl.this, false); 2971 } 2972 if (mTimerWindow != null) { 2973 wlactive |= !mTimerWindow.reset(BatteryStatsImpl.this, false); 2974 } 2975 if (!wlactive) { 2976 if (mTimerFull != null) { 2977 mTimerFull.detach(); 2978 mTimerFull = null; 2979 } 2980 if (mTimerPartial != null) { 2981 mTimerPartial.detach(); 2982 mTimerPartial = null; 2983 } 2984 if (mTimerWindow != null) { 2985 mTimerWindow.detach(); 2986 mTimerWindow = null; 2987 } 2988 } 2989 return !wlactive; 2990 } 2991 2992 void readFromParcelLocked(ArrayList<Unpluggable> unpluggables, Parcel in) { 2993 mTimerPartial = readTimerFromParcel(WAKE_TYPE_PARTIAL, 2994 mPartialTimers, unpluggables, in); 2995 mTimerFull = readTimerFromParcel(WAKE_TYPE_FULL, 2996 mFullTimers, unpluggables, in); 2997 mTimerWindow = readTimerFromParcel(WAKE_TYPE_WINDOW, 2998 mWindowTimers, unpluggables, in); 2999 } 3000 3001 void writeToParcelLocked(Parcel out, long batteryRealtime) { 3002 Timer.writeTimerToParcel(out, mTimerPartial, batteryRealtime); 3003 Timer.writeTimerToParcel(out, mTimerFull, batteryRealtime); 3004 Timer.writeTimerToParcel(out, mTimerWindow, batteryRealtime); 3005 } 3006 3007 @Override 3008 public Timer getWakeTime(int type) { 3009 switch (type) { 3010 case WAKE_TYPE_FULL: return mTimerFull; 3011 case WAKE_TYPE_PARTIAL: return mTimerPartial; 3012 case WAKE_TYPE_WINDOW: return mTimerWindow; 3013 default: throw new IllegalArgumentException("type = " + type); 3014 } 3015 } 3016 } 3017 3018 public final class Sensor extends BatteryStats.Uid.Sensor { 3019 final int mHandle; 3020 StopwatchTimer mTimer; 3021 3022 public Sensor(int handle) { 3023 mHandle = handle; 3024 } 3025 3026 private StopwatchTimer readTimerFromParcel(ArrayList<Unpluggable> unpluggables, 3027 Parcel in) { 3028 if (in.readInt() == 0) { 3029 return null; 3030 } 3031 3032 ArrayList<StopwatchTimer> pool = mSensorTimers.get(mHandle); 3033 if (pool == null) { 3034 pool = new ArrayList<StopwatchTimer>(); 3035 mSensorTimers.put(mHandle, pool); 3036 } 3037 return new StopwatchTimer(Uid.this, 0, pool, unpluggables, in); 3038 } 3039 3040 boolean reset() { 3041 if (mTimer.reset(BatteryStatsImpl.this, true)) { 3042 mTimer = null; 3043 return true; 3044 } 3045 return false; 3046 } 3047 3048 void readFromParcelLocked(ArrayList<Unpluggable> unpluggables, Parcel in) { 3049 mTimer = readTimerFromParcel(unpluggables, in); 3050 } 3051 3052 void writeToParcelLocked(Parcel out, long batteryRealtime) { 3053 Timer.writeTimerToParcel(out, mTimer, batteryRealtime); 3054 } 3055 3056 @Override 3057 public Timer getSensorTime() { 3058 return mTimer; 3059 } 3060 3061 @Override 3062 public int getHandle() { 3063 return mHandle; 3064 } 3065 } 3066 3067 /** 3068 * The statistics associated with a particular process. 3069 */ 3070 public final class Proc extends BatteryStats.Uid.Proc implements Unpluggable { 3071 /** 3072 * Total time (in 1/100 sec) spent executing in user code. 3073 */ 3074 long mUserTime; 3075 3076 /** 3077 * Total time (in 1/100 sec) spent executing in kernel code. 3078 */ 3079 long mSystemTime; 3080 3081 /** 3082 * Number of times the process has been started. 3083 */ 3084 int mStarts; 3085 3086 /** 3087 * Amount of time the process was running in the foreground. 3088 */ 3089 long mForegroundTime; 3090 3091 /** 3092 * The amount of user time loaded from a previous save. 3093 */ 3094 long mLoadedUserTime; 3095 3096 /** 3097 * The amount of system time loaded from a previous save. 3098 */ 3099 long mLoadedSystemTime; 3100 3101 /** 3102 * The number of times the process has started from a previous save. 3103 */ 3104 int mLoadedStarts; 3105 3106 /** 3107 * The amount of foreground time loaded from a previous save. 3108 */ 3109 long mLoadedForegroundTime; 3110 3111 /** 3112 * The amount of user time loaded from the previous run. 3113 */ 3114 long mLastUserTime; 3115 3116 /** 3117 * The amount of system time loaded from the previous run. 3118 */ 3119 long mLastSystemTime; 3120 3121 /** 3122 * The number of times the process has started from the previous run. 3123 */ 3124 int mLastStarts; 3125 3126 /** 3127 * The amount of foreground time loaded from the previous run 3128 */ 3129 long mLastForegroundTime; 3130 3131 /** 3132 * The amount of user time when last unplugged. 3133 */ 3134 long mUnpluggedUserTime; 3135 3136 /** 3137 * The amount of system time when last unplugged. 3138 */ 3139 long mUnpluggedSystemTime; 3140 3141 /** 3142 * The number of times the process has started before unplugged. 3143 */ 3144 int mUnpluggedStarts; 3145 3146 /** 3147 * The amount of foreground time since unplugged. 3148 */ 3149 long mUnpluggedForegroundTime; 3150 3151 SamplingCounter[] mSpeedBins; 3152 3153 ArrayList<ExcessivePower> mExcessivePower; 3154 3155 Proc() { 3156 mUnpluggables.add(this); 3157 mSpeedBins = new SamplingCounter[getCpuSpeedSteps()]; 3158 } 3159 3160 public void unplug(long batteryUptime, long batteryRealtime) { 3161 mUnpluggedUserTime = mUserTime; 3162 mUnpluggedSystemTime = mSystemTime; 3163 mUnpluggedStarts = mStarts; 3164 mUnpluggedForegroundTime = mForegroundTime; 3165 } 3166 3167 public void plug(long batteryUptime, long batteryRealtime) { 3168 } 3169 3170 void detach() { 3171 mUnpluggables.remove(this); 3172 for (int i = 0; i < mSpeedBins.length; i++) { 3173 SamplingCounter c = mSpeedBins[i]; 3174 if (c != null) { 3175 mUnpluggables.remove(c); 3176 mSpeedBins[i] = null; 3177 } 3178 } 3179 } 3180 3181 public int countExcessivePowers() { 3182 return mExcessivePower != null ? mExcessivePower.size() : 0; 3183 } 3184 3185 public ExcessivePower getExcessivePower(int i) { 3186 if (mExcessivePower != null) { 3187 return mExcessivePower.get(i); 3188 } 3189 return null; 3190 } 3191 3192 public void addExcessiveWake(long overTime, long usedTime) { 3193 if (mExcessivePower == null) { 3194 mExcessivePower = new ArrayList<ExcessivePower>(); 3195 } 3196 ExcessivePower ew = new ExcessivePower(); 3197 ew.type = ExcessivePower.TYPE_WAKE; 3198 ew.overTime = overTime; 3199 ew.usedTime = usedTime; 3200 mExcessivePower.add(ew); 3201 } 3202 3203 public void addExcessiveCpu(long overTime, long usedTime) { 3204 if (mExcessivePower == null) { 3205 mExcessivePower = new ArrayList<ExcessivePower>(); 3206 } 3207 ExcessivePower ew = new ExcessivePower(); 3208 ew.type = ExcessivePower.TYPE_CPU; 3209 ew.overTime = overTime; 3210 ew.usedTime = usedTime; 3211 mExcessivePower.add(ew); 3212 } 3213 3214 void writeExcessivePowerToParcelLocked(Parcel out) { 3215 if (mExcessivePower == null) { 3216 out.writeInt(0); 3217 return; 3218 } 3219 3220 final int N = mExcessivePower.size(); 3221 out.writeInt(N); 3222 for (int i=0; i<N; i++) { 3223 ExcessivePower ew = mExcessivePower.get(i); 3224 out.writeInt(ew.type); 3225 out.writeLong(ew.overTime); 3226 out.writeLong(ew.usedTime); 3227 } 3228 } 3229 3230 boolean readExcessivePowerFromParcelLocked(Parcel in) { 3231 final int N = in.readInt(); 3232 if (N == 0) { 3233 mExcessivePower = null; 3234 return true; 3235 } 3236 3237 if (N > 10000) { 3238 Slog.w(TAG, "File corrupt: too many excessive power entries " + N); 3239 return false; 3240 } 3241 3242 mExcessivePower = new ArrayList<ExcessivePower>(); 3243 for (int i=0; i<N; i++) { 3244 ExcessivePower ew = new ExcessivePower(); 3245 ew.type = in.readInt(); 3246 ew.overTime = in.readLong(); 3247 ew.usedTime = in.readLong(); 3248 mExcessivePower.add(ew); 3249 } 3250 return true; 3251 } 3252 3253 void writeToParcelLocked(Parcel out) { 3254 out.writeLong(mUserTime); 3255 out.writeLong(mSystemTime); 3256 out.writeLong(mForegroundTime); 3257 out.writeInt(mStarts); 3258 out.writeLong(mLoadedUserTime); 3259 out.writeLong(mLoadedSystemTime); 3260 out.writeLong(mLoadedForegroundTime); 3261 out.writeInt(mLoadedStarts); 3262 out.writeLong(mUnpluggedUserTime); 3263 out.writeLong(mUnpluggedSystemTime); 3264 out.writeLong(mUnpluggedForegroundTime); 3265 out.writeInt(mUnpluggedStarts); 3266 3267 out.writeInt(mSpeedBins.length); 3268 for (int i = 0; i < mSpeedBins.length; i++) { 3269 SamplingCounter c = mSpeedBins[i]; 3270 if (c != null) { 3271 out.writeInt(1); 3272 c.writeToParcel(out); 3273 } else { 3274 out.writeInt(0); 3275 } 3276 } 3277 3278 writeExcessivePowerToParcelLocked(out); 3279 } 3280 3281 void readFromParcelLocked(Parcel in) { 3282 mUserTime = in.readLong(); 3283 mSystemTime = in.readLong(); 3284 mForegroundTime = in.readLong(); 3285 mStarts = in.readInt(); 3286 mLoadedUserTime = in.readLong(); 3287 mLoadedSystemTime = in.readLong(); 3288 mLoadedForegroundTime = in.readLong(); 3289 mLoadedStarts = in.readInt(); 3290 mLastUserTime = 0; 3291 mLastSystemTime = 0; 3292 mLastForegroundTime = 0; 3293 mLastStarts = 0; 3294 mUnpluggedUserTime = in.readLong(); 3295 mUnpluggedSystemTime = in.readLong(); 3296 mUnpluggedForegroundTime = in.readLong(); 3297 mUnpluggedStarts = in.readInt(); 3298 3299 int bins = in.readInt(); 3300 int steps = getCpuSpeedSteps(); 3301 mSpeedBins = new SamplingCounter[bins >= steps ? bins : steps]; 3302 for (int i = 0; i < bins; i++) { 3303 if (in.readInt() != 0) { 3304 mSpeedBins[i] = new SamplingCounter(mUnpluggables, in); 3305 } 3306 } 3307 3308 readExcessivePowerFromParcelLocked(in); 3309 } 3310 3311 public BatteryStatsImpl getBatteryStats() { 3312 return BatteryStatsImpl.this; 3313 } 3314 3315 public void addCpuTimeLocked(int utime, int stime) { 3316 mUserTime += utime; 3317 mSystemTime += stime; 3318 } 3319 3320 public void addForegroundTimeLocked(long ttime) { 3321 mForegroundTime += ttime; 3322 } 3323 3324 public void incStartsLocked() { 3325 mStarts++; 3326 } 3327 3328 @Override 3329 public long getUserTime(int which) { 3330 long val; 3331 if (which == STATS_LAST) { 3332 val = mLastUserTime; 3333 } else { 3334 val = mUserTime; 3335 if (which == STATS_CURRENT) { 3336 val -= mLoadedUserTime; 3337 } else if (which == STATS_SINCE_UNPLUGGED) { 3338 val -= mUnpluggedUserTime; 3339 } 3340 } 3341 return val; 3342 } 3343 3344 @Override 3345 public long getSystemTime(int which) { 3346 long val; 3347 if (which == STATS_LAST) { 3348 val = mLastSystemTime; 3349 } else { 3350 val = mSystemTime; 3351 if (which == STATS_CURRENT) { 3352 val -= mLoadedSystemTime; 3353 } else if (which == STATS_SINCE_UNPLUGGED) { 3354 val -= mUnpluggedSystemTime; 3355 } 3356 } 3357 return val; 3358 } 3359 3360 @Override 3361 public long getForegroundTime(int which) { 3362 long val; 3363 if (which == STATS_LAST) { 3364 val = mLastForegroundTime; 3365 } else { 3366 val = mForegroundTime; 3367 if (which == STATS_CURRENT) { 3368 val -= mLoadedForegroundTime; 3369 } else if (which == STATS_SINCE_UNPLUGGED) { 3370 val -= mUnpluggedForegroundTime; 3371 } 3372 } 3373 return val; 3374 } 3375 3376 @Override 3377 public int getStarts(int which) { 3378 int val; 3379 if (which == STATS_LAST) { 3380 val = mLastStarts; 3381 } else { 3382 val = mStarts; 3383 if (which == STATS_CURRENT) { 3384 val -= mLoadedStarts; 3385 } else if (which == STATS_SINCE_UNPLUGGED) { 3386 val -= mUnpluggedStarts; 3387 } 3388 } 3389 return val; 3390 } 3391 3392 /* Called by ActivityManagerService when CPU times are updated. */ 3393 public void addSpeedStepTimes(long[] values) { 3394 for (int i = 0; i < mSpeedBins.length && i < values.length; i++) { 3395 long amt = values[i]; 3396 if (amt != 0) { 3397 SamplingCounter c = mSpeedBins[i]; 3398 if (c == null) { 3399 mSpeedBins[i] = c = new SamplingCounter(mUnpluggables); 3400 } 3401 c.addCountAtomic(values[i]); 3402 } 3403 } 3404 } 3405 3406 @Override 3407 public long getTimeAtCpuSpeedStep(int speedStep, int which) { 3408 if (speedStep < mSpeedBins.length) { 3409 SamplingCounter c = mSpeedBins[speedStep]; 3410 return c != null ? c.getCountLocked(which) : 0; 3411 } else { 3412 return 0; 3413 } 3414 } 3415 } 3416 3417 /** 3418 * The statistics associated with a particular package. 3419 */ 3420 public final class Pkg extends BatteryStats.Uid.Pkg implements Unpluggable { 3421 /** 3422 * Number of times this package has done something that could wake up the 3423 * device from sleep. 3424 */ 3425 int mWakeups; 3426 3427 /** 3428 * Number of things that could wake up the device loaded from a 3429 * previous save. 3430 */ 3431 int mLoadedWakeups; 3432 3433 /** 3434 * Number of things that could wake up the device as of the 3435 * last run. 3436 */ 3437 int mLastWakeups; 3438 3439 /** 3440 * Number of things that could wake up the device as of the 3441 * last run. 3442 */ 3443 int mUnpluggedWakeups; 3444 3445 /** 3446 * The statics we have collected for this package's services. 3447 */ 3448 final HashMap<String, Serv> mServiceStats = new HashMap<String, Serv>(); 3449 3450 Pkg() { 3451 mUnpluggables.add(this); 3452 } 3453 3454 public void unplug(long batteryUptime, long batteryRealtime) { 3455 mUnpluggedWakeups = mWakeups; 3456 } 3457 3458 public void plug(long batteryUptime, long batteryRealtime) { 3459 } 3460 3461 void detach() { 3462 mUnpluggables.remove(this); 3463 } 3464 3465 void readFromParcelLocked(Parcel in) { 3466 mWakeups = in.readInt(); 3467 mLoadedWakeups = in.readInt(); 3468 mLastWakeups = 0; 3469 mUnpluggedWakeups = in.readInt(); 3470 3471 int numServs = in.readInt(); 3472 mServiceStats.clear(); 3473 for (int m = 0; m < numServs; m++) { 3474 String serviceName = in.readString(); 3475 Uid.Pkg.Serv serv = new Serv(); 3476 mServiceStats.put(serviceName, serv); 3477 3478 serv.readFromParcelLocked(in); 3479 } 3480 } 3481 3482 void writeToParcelLocked(Parcel out) { 3483 out.writeInt(mWakeups); 3484 out.writeInt(mLoadedWakeups); 3485 out.writeInt(mUnpluggedWakeups); 3486 3487 out.writeInt(mServiceStats.size()); 3488 for (Map.Entry<String, Uid.Pkg.Serv> servEntry : mServiceStats.entrySet()) { 3489 out.writeString(servEntry.getKey()); 3490 Uid.Pkg.Serv serv = servEntry.getValue(); 3491 3492 serv.writeToParcelLocked(out); 3493 } 3494 } 3495 3496 @Override 3497 public Map<String, ? extends BatteryStats.Uid.Pkg.Serv> getServiceStats() { 3498 return mServiceStats; 3499 } 3500 3501 @Override 3502 public int getWakeups(int which) { 3503 int val; 3504 if (which == STATS_LAST) { 3505 val = mLastWakeups; 3506 } else { 3507 val = mWakeups; 3508 if (which == STATS_CURRENT) { 3509 val -= mLoadedWakeups; 3510 } else if (which == STATS_SINCE_UNPLUGGED) { 3511 val -= mUnpluggedWakeups; 3512 } 3513 } 3514 3515 return val; 3516 } 3517 3518 /** 3519 * The statistics associated with a particular service. 3520 */ 3521 public final class Serv extends BatteryStats.Uid.Pkg.Serv implements Unpluggable { 3522 /** 3523 * Total time (ms in battery uptime) the service has been left started. 3524 */ 3525 long mStartTime; 3526 3527 /** 3528 * If service has been started and not yet stopped, this is 3529 * when it was started. 3530 */ 3531 long mRunningSince; 3532 3533 /** 3534 * True if we are currently running. 3535 */ 3536 boolean mRunning; 3537 3538 /** 3539 * Total number of times startService() has been called. 3540 */ 3541 int mStarts; 3542 3543 /** 3544 * Total time (ms in battery uptime) the service has been left launched. 3545 */ 3546 long mLaunchedTime; 3547 3548 /** 3549 * If service has been launched and not yet exited, this is 3550 * when it was launched (ms in battery uptime). 3551 */ 3552 long mLaunchedSince; 3553 3554 /** 3555 * True if we are currently launched. 3556 */ 3557 boolean mLaunched; 3558 3559 /** 3560 * Total number times the service has been launched. 3561 */ 3562 int mLaunches; 3563 3564 /** 3565 * The amount of time spent started loaded from a previous save 3566 * (ms in battery uptime). 3567 */ 3568 long mLoadedStartTime; 3569 3570 /** 3571 * The number of starts loaded from a previous save. 3572 */ 3573 int mLoadedStarts; 3574 3575 /** 3576 * The number of launches loaded from a previous save. 3577 */ 3578 int mLoadedLaunches; 3579 3580 /** 3581 * The amount of time spent started as of the last run (ms 3582 * in battery uptime). 3583 */ 3584 long mLastStartTime; 3585 3586 /** 3587 * The number of starts as of the last run. 3588 */ 3589 int mLastStarts; 3590 3591 /** 3592 * The number of launches as of the last run. 3593 */ 3594 int mLastLaunches; 3595 3596 /** 3597 * The amount of time spent started when last unplugged (ms 3598 * in battery uptime). 3599 */ 3600 long mUnpluggedStartTime; 3601 3602 /** 3603 * The number of starts when last unplugged. 3604 */ 3605 int mUnpluggedStarts; 3606 3607 /** 3608 * The number of launches when last unplugged. 3609 */ 3610 int mUnpluggedLaunches; 3611 3612 Serv() { 3613 mUnpluggables.add(this); 3614 } 3615 3616 public void unplug(long batteryUptime, long batteryRealtime) { 3617 mUnpluggedStartTime = getStartTimeToNowLocked(batteryUptime); 3618 mUnpluggedStarts = mStarts; 3619 mUnpluggedLaunches = mLaunches; 3620 } 3621 3622 public void plug(long batteryUptime, long batteryRealtime) { 3623 } 3624 3625 void detach() { 3626 mUnpluggables.remove(this); 3627 } 3628 3629 void readFromParcelLocked(Parcel in) { 3630 mStartTime = in.readLong(); 3631 mRunningSince = in.readLong(); 3632 mRunning = in.readInt() != 0; 3633 mStarts = in.readInt(); 3634 mLaunchedTime = in.readLong(); 3635 mLaunchedSince = in.readLong(); 3636 mLaunched = in.readInt() != 0; 3637 mLaunches = in.readInt(); 3638 mLoadedStartTime = in.readLong(); 3639 mLoadedStarts = in.readInt(); 3640 mLoadedLaunches = in.readInt(); 3641 mLastStartTime = 0; 3642 mLastStarts = 0; 3643 mLastLaunches = 0; 3644 mUnpluggedStartTime = in.readLong(); 3645 mUnpluggedStarts = in.readInt(); 3646 mUnpluggedLaunches = in.readInt(); 3647 } 3648 3649 void writeToParcelLocked(Parcel out) { 3650 out.writeLong(mStartTime); 3651 out.writeLong(mRunningSince); 3652 out.writeInt(mRunning ? 1 : 0); 3653 out.writeInt(mStarts); 3654 out.writeLong(mLaunchedTime); 3655 out.writeLong(mLaunchedSince); 3656 out.writeInt(mLaunched ? 1 : 0); 3657 out.writeInt(mLaunches); 3658 out.writeLong(mLoadedStartTime); 3659 out.writeInt(mLoadedStarts); 3660 out.writeInt(mLoadedLaunches); 3661 out.writeLong(mUnpluggedStartTime); 3662 out.writeInt(mUnpluggedStarts); 3663 out.writeInt(mUnpluggedLaunches); 3664 } 3665 3666 long getLaunchTimeToNowLocked(long batteryUptime) { 3667 if (!mLaunched) return mLaunchedTime; 3668 return mLaunchedTime + batteryUptime - mLaunchedSince; 3669 } 3670 3671 long getStartTimeToNowLocked(long batteryUptime) { 3672 if (!mRunning) return mStartTime; 3673 return mStartTime + batteryUptime - mRunningSince; 3674 } 3675 3676 public void startLaunchedLocked() { 3677 if (!mLaunched) { 3678 mLaunches++; 3679 mLaunchedSince = getBatteryUptimeLocked(); 3680 mLaunched = true; 3681 } 3682 } 3683 3684 public void stopLaunchedLocked() { 3685 if (mLaunched) { 3686 long time = getBatteryUptimeLocked() - mLaunchedSince; 3687 if (time > 0) { 3688 mLaunchedTime += time; 3689 } else { 3690 mLaunches--; 3691 } 3692 mLaunched = false; 3693 } 3694 } 3695 3696 public void startRunningLocked() { 3697 if (!mRunning) { 3698 mStarts++; 3699 mRunningSince = getBatteryUptimeLocked(); 3700 mRunning = true; 3701 } 3702 } 3703 3704 public void stopRunningLocked() { 3705 if (mRunning) { 3706 long time = getBatteryUptimeLocked() - mRunningSince; 3707 if (time > 0) { 3708 mStartTime += time; 3709 } else { 3710 mStarts--; 3711 } 3712 mRunning = false; 3713 } 3714 } 3715 3716 public BatteryStatsImpl getBatteryStats() { 3717 return BatteryStatsImpl.this; 3718 } 3719 3720 @Override 3721 public int getLaunches(int which) { 3722 int val; 3723 3724 if (which == STATS_LAST) { 3725 val = mLastLaunches; 3726 } else { 3727 val = mLaunches; 3728 if (which == STATS_CURRENT) { 3729 val -= mLoadedLaunches; 3730 } else if (which == STATS_SINCE_UNPLUGGED) { 3731 val -= mUnpluggedLaunches; 3732 } 3733 } 3734 3735 return val; 3736 } 3737 3738 @Override 3739 public long getStartTime(long now, int which) { 3740 long val; 3741 if (which == STATS_LAST) { 3742 val = mLastStartTime; 3743 } else { 3744 val = getStartTimeToNowLocked(now); 3745 if (which == STATS_CURRENT) { 3746 val -= mLoadedStartTime; 3747 } else if (which == STATS_SINCE_UNPLUGGED) { 3748 val -= mUnpluggedStartTime; 3749 } 3750 } 3751 3752 return val; 3753 } 3754 3755 @Override 3756 public int getStarts(int which) { 3757 int val; 3758 if (which == STATS_LAST) { 3759 val = mLastStarts; 3760 } else { 3761 val = mStarts; 3762 if (which == STATS_CURRENT) { 3763 val -= mLoadedStarts; 3764 } else if (which == STATS_SINCE_UNPLUGGED) { 3765 val -= mUnpluggedStarts; 3766 } 3767 } 3768 3769 return val; 3770 } 3771 } 3772 3773 public BatteryStatsImpl getBatteryStats() { 3774 return BatteryStatsImpl.this; 3775 } 3776 3777 public void incWakeupsLocked() { 3778 mWakeups++; 3779 } 3780 3781 final Serv newServiceStatsLocked() { 3782 return new Serv(); 3783 } 3784 } 3785 3786 /** 3787 * Retrieve the statistics object for a particular process, creating 3788 * if needed. 3789 */ 3790 public Proc getProcessStatsLocked(String name) { 3791 Proc ps = mProcessStats.get(name); 3792 if (ps == null) { 3793 ps = new Proc(); 3794 mProcessStats.put(name, ps); 3795 } 3796 3797 return ps; 3798 } 3799 3800 public SparseArray<? extends Pid> getPidStats() { 3801 return mPids; 3802 } 3803 3804 public Pid getPidStatsLocked(int pid) { 3805 Pid p = mPids.get(pid); 3806 if (p == null) { 3807 p = new Pid(); 3808 mPids.put(pid, p); 3809 } 3810 return p; 3811 } 3812 3813 /** 3814 * Retrieve the statistics object for a particular service, creating 3815 * if needed. 3816 */ 3817 public Pkg getPackageStatsLocked(String name) { 3818 Pkg ps = mPackageStats.get(name); 3819 if (ps == null) { 3820 ps = new Pkg(); 3821 mPackageStats.put(name, ps); 3822 } 3823 3824 return ps; 3825 } 3826 3827 /** 3828 * Retrieve the statistics object for a particular service, creating 3829 * if needed. 3830 */ 3831 public Pkg.Serv getServiceStatsLocked(String pkg, String serv) { 3832 Pkg ps = getPackageStatsLocked(pkg); 3833 Pkg.Serv ss = ps.mServiceStats.get(serv); 3834 if (ss == null) { 3835 ss = ps.newServiceStatsLocked(); 3836 ps.mServiceStats.put(serv, ss); 3837 } 3838 3839 return ss; 3840 } 3841 3842 public StopwatchTimer getWakeTimerLocked(String name, int type) { 3843 Wakelock wl = mWakelockStats.get(name); 3844 if (wl == null) { 3845 if (mWakelockStats.size() > MAX_WAKELOCKS_PER_UID) { 3846 name = BATCHED_WAKELOCK_NAME; 3847 wl = mWakelockStats.get(name); 3848 } 3849 if (wl == null) { 3850 wl = new Wakelock(); 3851 mWakelockStats.put(name, wl); 3852 } 3853 } 3854 StopwatchTimer t = null; 3855 switch (type) { 3856 case WAKE_TYPE_PARTIAL: 3857 t = wl.mTimerPartial; 3858 if (t == null) { 3859 t = new StopwatchTimer(Uid.this, WAKE_TYPE_PARTIAL, 3860 mPartialTimers, mUnpluggables); 3861 wl.mTimerPartial = t; 3862 } 3863 return t; 3864 case WAKE_TYPE_FULL: 3865 t = wl.mTimerFull; 3866 if (t == null) { 3867 t = new StopwatchTimer(Uid.this, WAKE_TYPE_FULL, 3868 mFullTimers, mUnpluggables); 3869 wl.mTimerFull = t; 3870 } 3871 return t; 3872 case WAKE_TYPE_WINDOW: 3873 t = wl.mTimerWindow; 3874 if (t == null) { 3875 t = new StopwatchTimer(Uid.this, WAKE_TYPE_WINDOW, 3876 mWindowTimers, mUnpluggables); 3877 wl.mTimerWindow = t; 3878 } 3879 return t; 3880 default: 3881 throw new IllegalArgumentException("type=" + type); 3882 } 3883 } 3884 3885 public StopwatchTimer getSensorTimerLocked(int sensor, boolean create) { 3886 Sensor se = mSensorStats.get(sensor); 3887 if (se == null) { 3888 if (!create) { 3889 return null; 3890 } 3891 se = new Sensor(sensor); 3892 mSensorStats.put(sensor, se); 3893 } 3894 StopwatchTimer t = se.mTimer; 3895 if (t != null) { 3896 return t; 3897 } 3898 ArrayList<StopwatchTimer> timers = mSensorTimers.get(sensor); 3899 if (timers == null) { 3900 timers = new ArrayList<StopwatchTimer>(); 3901 mSensorTimers.put(sensor, timers); 3902 } 3903 t = new StopwatchTimer(Uid.this, BatteryStats.SENSOR, timers, mUnpluggables); 3904 se.mTimer = t; 3905 return t; 3906 } 3907 3908 public void noteStartWakeLocked(int pid, String name, int type) { 3909 StopwatchTimer t = getWakeTimerLocked(name, type); 3910 if (t != null) { 3911 t.startRunningLocked(BatteryStatsImpl.this); 3912 } 3913 if (pid >= 0 && type == WAKE_TYPE_PARTIAL) { 3914 Pid p = getPidStatsLocked(pid); 3915 if (p.mWakeStart == 0) { 3916 p.mWakeStart = SystemClock.elapsedRealtime(); 3917 } 3918 } 3919 } 3920 3921 public void noteStopWakeLocked(int pid, String name, int type) { 3922 StopwatchTimer t = getWakeTimerLocked(name, type); 3923 if (t != null) { 3924 t.stopRunningLocked(BatteryStatsImpl.this); 3925 } 3926 if (pid >= 0 && type == WAKE_TYPE_PARTIAL) { 3927 Pid p = mPids.get(pid); 3928 if (p != null && p.mWakeStart != 0) { 3929 p.mWakeSum += SystemClock.elapsedRealtime() - p.mWakeStart; 3930 p.mWakeStart = 0; 3931 } 3932 } 3933 } 3934 3935 public void reportExcessiveWakeLocked(String proc, long overTime, long usedTime) { 3936 Proc p = getProcessStatsLocked(proc); 3937 if (p != null) { 3938 p.addExcessiveWake(overTime, usedTime); 3939 } 3940 } 3941 3942 public void reportExcessiveCpuLocked(String proc, long overTime, long usedTime) { 3943 Proc p = getProcessStatsLocked(proc); 3944 if (p != null) { 3945 p.addExcessiveCpu(overTime, usedTime); 3946 } 3947 } 3948 3949 public void noteStartSensor(int sensor) { 3950 StopwatchTimer t = getSensorTimerLocked(sensor, true); 3951 if (t != null) { 3952 t.startRunningLocked(BatteryStatsImpl.this); 3953 } 3954 } 3955 3956 public void noteStopSensor(int sensor) { 3957 // Don't create a timer if one doesn't already exist 3958 StopwatchTimer t = getSensorTimerLocked(sensor, false); 3959 if (t != null) { 3960 t.stopRunningLocked(BatteryStatsImpl.this); 3961 } 3962 } 3963 3964 public void noteStartGps() { 3965 StopwatchTimer t = getSensorTimerLocked(Sensor.GPS, true); 3966 if (t != null) { 3967 t.startRunningLocked(BatteryStatsImpl.this); 3968 } 3969 } 3970 3971 public void noteStopGps() { 3972 StopwatchTimer t = getSensorTimerLocked(Sensor.GPS, false); 3973 if (t != null) { 3974 t.stopRunningLocked(BatteryStatsImpl.this); 3975 } 3976 } 3977 3978 public BatteryStatsImpl getBatteryStats() { 3979 return BatteryStatsImpl.this; 3980 } 3981 } 3982 3983 public BatteryStatsImpl(String filename) { 3984 mFile = new JournaledFile(new File(filename), new File(filename + ".tmp")); 3985 mHandler = new MyHandler(); 3986 mStartCount++; 3987 mScreenOnTimer = new StopwatchTimer(null, -1, null, mUnpluggables); 3988 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 3989 mScreenBrightnessTimer[i] = new StopwatchTimer(null, -100-i, null, mUnpluggables); 3990 } 3991 mInputEventCounter = new Counter(mUnpluggables); 3992 mPhoneOnTimer = new StopwatchTimer(null, -2, null, mUnpluggables); 3993 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) { 3994 mPhoneSignalStrengthsTimer[i] = new StopwatchTimer(null, -200-i, null, mUnpluggables); 3995 } 3996 mPhoneSignalScanningTimer = new StopwatchTimer(null, -200+1, null, mUnpluggables); 3997 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 3998 mPhoneDataConnectionsTimer[i] = new StopwatchTimer(null, -300-i, null, mUnpluggables); 3999 } 4000 mWifiOnTimer = new StopwatchTimer(null, -3, null, mUnpluggables); 4001 mGlobalWifiRunningTimer = new StopwatchTimer(null, -4, null, mUnpluggables); 4002 mBluetoothOnTimer = new StopwatchTimer(null, -5, null, mUnpluggables); 4003 mAudioOnTimer = new StopwatchTimer(null, -6, null, mUnpluggables); 4004 mVideoOnTimer = new StopwatchTimer(null, -7, null, mUnpluggables); 4005 mOnBattery = mOnBatteryInternal = false; 4006 initTimes(); 4007 mTrackBatteryPastUptime = 0; 4008 mTrackBatteryPastRealtime = 0; 4009 mUptimeStart = mTrackBatteryUptimeStart = SystemClock.uptimeMillis() * 1000; 4010 mRealtimeStart = mTrackBatteryRealtimeStart = SystemClock.elapsedRealtime() * 1000; 4011 mUnpluggedBatteryUptime = getBatteryUptimeLocked(mUptimeStart); 4012 mUnpluggedBatteryRealtime = getBatteryRealtimeLocked(mRealtimeStart); 4013 mDischargeStartLevel = 0; 4014 mDischargeUnplugLevel = 0; 4015 mDischargeCurrentLevel = 0; 4016 initDischarge(); 4017 clearHistoryLocked(); 4018 } 4019 4020 public BatteryStatsImpl(Parcel p) { 4021 mFile = null; 4022 mHandler = null; 4023 clearHistoryLocked(); 4024 readFromParcel(p); 4025 } 4026 4027 public void setCallback(BatteryCallback cb) { 4028 mCallback = cb; 4029 } 4030 4031 public void setNumSpeedSteps(int steps) { 4032 if (sNumSpeedSteps == 0) sNumSpeedSteps = steps; 4033 } 4034 4035 public void setRadioScanningTimeout(long timeout) { 4036 if (mPhoneSignalScanningTimer != null) { 4037 mPhoneSignalScanningTimer.setTimeout(timeout); 4038 } 4039 } 4040 4041 @Override 4042 public boolean startIteratingOldHistoryLocked() { 4043 if (DEBUG_HISTORY) Slog.i(TAG, "ITERATING: buff size=" + mHistoryBuffer.dataSize() 4044 + " pos=" + mHistoryBuffer.dataPosition()); 4045 mHistoryBuffer.setDataPosition(0); 4046 mHistoryReadTmp.clear(); 4047 mReadOverflow = false; 4048 mIteratingHistory = true; 4049 return (mHistoryIterator = mHistory) != null; 4050 } 4051 4052 @Override 4053 public boolean getNextOldHistoryLocked(HistoryItem out) { 4054 boolean end = mHistoryBuffer.dataPosition() >= mHistoryBuffer.dataSize(); 4055 if (!end) { 4056 mHistoryReadTmp.readDelta(mHistoryBuffer); 4057 mReadOverflow |= mHistoryReadTmp.cmd == HistoryItem.CMD_OVERFLOW; 4058 } 4059 HistoryItem cur = mHistoryIterator; 4060 if (cur == null) { 4061 if (!mReadOverflow && !end) { 4062 Slog.w(TAG, "Old history ends before new history!"); 4063 } 4064 return false; 4065 } 4066 out.setTo(cur); 4067 mHistoryIterator = cur.next; 4068 if (!mReadOverflow) { 4069 if (end) { 4070 Slog.w(TAG, "New history ends before old history!"); 4071 } else if (!out.same(mHistoryReadTmp)) { 4072 long now = getHistoryBaseTime() + SystemClock.elapsedRealtime(); 4073 PrintWriter pw = new PrintWriter(new LogWriter(android.util.Log.WARN, TAG)); 4074 pw.println("Histories differ!"); 4075 pw.println("Old history:"); 4076 (new HistoryPrinter()).printNextItem(pw, out, now); 4077 pw.println("New history:"); 4078 (new HistoryPrinter()).printNextItem(pw, mHistoryReadTmp, now); 4079 } 4080 } 4081 return true; 4082 } 4083 4084 @Override 4085 public void finishIteratingOldHistoryLocked() { 4086 mIteratingHistory = false; 4087 mHistoryBuffer.setDataPosition(mHistoryBuffer.dataSize()); 4088 } 4089 4090 @Override 4091 public boolean startIteratingHistoryLocked() { 4092 if (DEBUG_HISTORY) Slog.i(TAG, "ITERATING: buff size=" + mHistoryBuffer.dataSize() 4093 + " pos=" + mHistoryBuffer.dataPosition()); 4094 mHistoryBuffer.setDataPosition(0); 4095 mReadOverflow = false; 4096 mIteratingHistory = true; 4097 return mHistoryBuffer.dataSize() > 0; 4098 } 4099 4100 @Override 4101 public boolean getNextHistoryLocked(HistoryItem out) { 4102 final int pos = mHistoryBuffer.dataPosition(); 4103 if (pos == 0) { 4104 out.clear(); 4105 } 4106 boolean end = pos >= mHistoryBuffer.dataSize(); 4107 if (end) { 4108 return false; 4109 } 4110 4111 out.readDelta(mHistoryBuffer); 4112 return true; 4113 } 4114 4115 @Override 4116 public void finishIteratingHistoryLocked() { 4117 mIteratingHistory = false; 4118 mHistoryBuffer.setDataPosition(mHistoryBuffer.dataSize()); 4119 } 4120 4121 @Override 4122 public long getHistoryBaseTime() { 4123 return mHistoryBaseTime; 4124 } 4125 4126 @Override 4127 public int getStartCount() { 4128 return mStartCount; 4129 } 4130 4131 public boolean isOnBattery() { 4132 return mOnBattery; 4133 } 4134 4135 public boolean isScreenOn() { 4136 return mScreenOn; 4137 } 4138 4139 void initTimes() { 4140 mBatteryRealtime = mTrackBatteryPastUptime = 0; 4141 mBatteryUptime = mTrackBatteryPastRealtime = 0; 4142 mUptimeStart = mTrackBatteryUptimeStart = SystemClock.uptimeMillis() * 1000; 4143 mRealtimeStart = mTrackBatteryRealtimeStart = SystemClock.elapsedRealtime() * 1000; 4144 mUnpluggedBatteryUptime = getBatteryUptimeLocked(mUptimeStart); 4145 mUnpluggedBatteryRealtime = getBatteryRealtimeLocked(mRealtimeStart); 4146 } 4147 4148 void initDischarge() { 4149 mLowDischargeAmountSinceCharge = 0; 4150 mHighDischargeAmountSinceCharge = 0; 4151 mDischargeAmountScreenOn = 0; 4152 mDischargeAmountScreenOnSinceCharge = 0; 4153 mDischargeAmountScreenOff = 0; 4154 mDischargeAmountScreenOffSinceCharge = 0; 4155 } 4156 4157 public void resetAllStatsLocked() { 4158 mStartCount = 0; 4159 initTimes(); 4160 mScreenOnTimer.reset(this, false); 4161 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 4162 mScreenBrightnessTimer[i].reset(this, false); 4163 } 4164 mInputEventCounter.reset(false); 4165 mPhoneOnTimer.reset(this, false); 4166 mAudioOnTimer.reset(this, false); 4167 mVideoOnTimer.reset(this, false); 4168 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) { 4169 mPhoneSignalStrengthsTimer[i].reset(this, false); 4170 } 4171 mPhoneSignalScanningTimer.reset(this, false); 4172 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 4173 mPhoneDataConnectionsTimer[i].reset(this, false); 4174 } 4175 mWifiOnTimer.reset(this, false); 4176 mGlobalWifiRunningTimer.reset(this, false); 4177 mBluetoothOnTimer.reset(this, false); 4178 4179 for (int i=0; i<mUidStats.size(); i++) { 4180 if (mUidStats.valueAt(i).reset()) { 4181 mUidStats.remove(mUidStats.keyAt(i)); 4182 i--; 4183 } 4184 } 4185 4186 if (mKernelWakelockStats.size() > 0) { 4187 for (SamplingTimer timer : mKernelWakelockStats.values()) { 4188 mUnpluggables.remove(timer); 4189 } 4190 mKernelWakelockStats.clear(); 4191 } 4192 4193 initDischarge(); 4194 4195 clearHistoryLocked(); 4196 } 4197 4198 void updateDischargeScreenLevelsLocked(boolean oldScreenOn, boolean newScreenOn) { 4199 if (oldScreenOn) { 4200 int diff = mDischargeScreenOnUnplugLevel - mDischargeCurrentLevel; 4201 if (diff > 0) { 4202 mDischargeAmountScreenOn += diff; 4203 mDischargeAmountScreenOnSinceCharge += diff; 4204 } 4205 } else { 4206 int diff = mDischargeScreenOffUnplugLevel - mDischargeCurrentLevel; 4207 if (diff > 0) { 4208 mDischargeAmountScreenOff += diff; 4209 mDischargeAmountScreenOffSinceCharge += diff; 4210 } 4211 } 4212 if (newScreenOn) { 4213 mDischargeScreenOnUnplugLevel = mDischargeCurrentLevel; 4214 mDischargeScreenOffUnplugLevel = 0; 4215 } else { 4216 mDischargeScreenOnUnplugLevel = 0; 4217 mDischargeScreenOffUnplugLevel = mDischargeCurrentLevel; 4218 } 4219 } 4220 4221 void setOnBattery(boolean onBattery, int oldStatus, int level) { 4222 synchronized(this) { 4223 setOnBatteryLocked(onBattery, oldStatus, level); 4224 } 4225 } 4226 4227 void setOnBatteryLocked(boolean onBattery, int oldStatus, int level) { 4228 boolean doWrite = false; 4229 Message m = mHandler.obtainMessage(MSG_REPORT_POWER_CHANGE); 4230 m.arg1 = onBattery ? 1 : 0; 4231 mHandler.sendMessage(m); 4232 mOnBattery = mOnBatteryInternal = onBattery; 4233 4234 long uptime = SystemClock.uptimeMillis() * 1000; 4235 long mSecRealtime = SystemClock.elapsedRealtime(); 4236 long realtime = mSecRealtime * 1000; 4237 if (onBattery) { 4238 // We will reset our status if we are unplugging after the 4239 // battery was last full, or the level is at 100, or 4240 // we have gone through a significant charge (from a very low 4241 // level to a now very high level). 4242 if (oldStatus == BatteryManager.BATTERY_STATUS_FULL 4243 || level >= 90 4244 || (mDischargeCurrentLevel < 20 && level >= 80)) { 4245 doWrite = true; 4246 resetAllStatsLocked(); 4247 mDischargeStartLevel = level; 4248 } 4249 updateKernelWakelocksLocked(); 4250 mHistoryCur.batteryLevel = (byte)level; 4251 mHistoryCur.states &= ~HistoryItem.STATE_BATTERY_PLUGGED_FLAG; 4252 if (DEBUG_HISTORY) Slog.v(TAG, "Battery unplugged to: " 4253 + Integer.toHexString(mHistoryCur.states)); 4254 addHistoryRecordLocked(mSecRealtime); 4255 mTrackBatteryUptimeStart = uptime; 4256 mTrackBatteryRealtimeStart = realtime; 4257 mUnpluggedBatteryUptime = getBatteryUptimeLocked(uptime); 4258 mUnpluggedBatteryRealtime = getBatteryRealtimeLocked(realtime); 4259 mDischargeCurrentLevel = mDischargeUnplugLevel = level; 4260 if (mScreenOn) { 4261 mDischargeScreenOnUnplugLevel = level; 4262 mDischargeScreenOffUnplugLevel = 0; 4263 } else { 4264 mDischargeScreenOnUnplugLevel = 0; 4265 mDischargeScreenOffUnplugLevel = level; 4266 } 4267 mDischargeAmountScreenOn = 0; 4268 mDischargeAmountScreenOff = 0; 4269 doUnplugLocked(mUnpluggedBatteryUptime, mUnpluggedBatteryRealtime); 4270 } else { 4271 updateKernelWakelocksLocked(); 4272 mHistoryCur.batteryLevel = (byte)level; 4273 mHistoryCur.states |= HistoryItem.STATE_BATTERY_PLUGGED_FLAG; 4274 if (DEBUG_HISTORY) Slog.v(TAG, "Battery plugged to: " 4275 + Integer.toHexString(mHistoryCur.states)); 4276 addHistoryRecordLocked(mSecRealtime); 4277 mTrackBatteryPastUptime += uptime - mTrackBatteryUptimeStart; 4278 mTrackBatteryPastRealtime += realtime - mTrackBatteryRealtimeStart; 4279 mDischargeCurrentLevel = level; 4280 if (level < mDischargeUnplugLevel) { 4281 mLowDischargeAmountSinceCharge += mDischargeUnplugLevel-level-1; 4282 mHighDischargeAmountSinceCharge += mDischargeUnplugLevel-level; 4283 } 4284 updateDischargeScreenLevelsLocked(mScreenOn, mScreenOn); 4285 doPlugLocked(getBatteryUptimeLocked(uptime), getBatteryRealtimeLocked(realtime)); 4286 } 4287 if (doWrite || (mLastWriteTime + (60 * 1000)) < mSecRealtime) { 4288 if (mFile != null) { 4289 writeAsyncLocked(); 4290 } 4291 } 4292 } 4293 4294 // This should probably be exposed in the API, though it's not critical 4295 private static final int BATTERY_PLUGGED_NONE = 0; 4296 4297 public void setBatteryState(int status, int health, int plugType, int level, 4298 int temp, int volt) { 4299 synchronized(this) { 4300 boolean onBattery = plugType == BATTERY_PLUGGED_NONE; 4301 int oldStatus = mHistoryCur.batteryStatus; 4302 if (!mHaveBatteryLevel) { 4303 mHaveBatteryLevel = true; 4304 // We start out assuming that the device is plugged in (not 4305 // on battery). If our first report is now that we are indeed 4306 // plugged in, then twiddle our state to correctly reflect that 4307 // since we won't be going through the full setOnBattery(). 4308 if (onBattery == mOnBattery) { 4309 if (onBattery) { 4310 mHistoryCur.states &= ~HistoryItem.STATE_BATTERY_PLUGGED_FLAG; 4311 } else { 4312 mHistoryCur.states |= HistoryItem.STATE_BATTERY_PLUGGED_FLAG; 4313 } 4314 } 4315 oldStatus = status; 4316 } 4317 if (onBattery) { 4318 mDischargeCurrentLevel = level; 4319 mRecordingHistory = true; 4320 } 4321 if (onBattery != mOnBattery) { 4322 mHistoryCur.batteryLevel = (byte)level; 4323 mHistoryCur.batteryStatus = (byte)status; 4324 mHistoryCur.batteryHealth = (byte)health; 4325 mHistoryCur.batteryPlugType = (byte)plugType; 4326 mHistoryCur.batteryTemperature = (char)temp; 4327 mHistoryCur.batteryVoltage = (char)volt; 4328 setOnBatteryLocked(onBattery, oldStatus, level); 4329 } else { 4330 boolean changed = false; 4331 if (mHistoryCur.batteryLevel != level) { 4332 mHistoryCur.batteryLevel = (byte)level; 4333 changed = true; 4334 } 4335 if (mHistoryCur.batteryStatus != status) { 4336 mHistoryCur.batteryStatus = (byte)status; 4337 changed = true; 4338 } 4339 if (mHistoryCur.batteryHealth != health) { 4340 mHistoryCur.batteryHealth = (byte)health; 4341 changed = true; 4342 } 4343 if (mHistoryCur.batteryPlugType != plugType) { 4344 mHistoryCur.batteryPlugType = (byte)plugType; 4345 changed = true; 4346 } 4347 if (temp >= (mHistoryCur.batteryTemperature+10) 4348 || temp <= (mHistoryCur.batteryTemperature-10)) { 4349 mHistoryCur.batteryTemperature = (char)temp; 4350 changed = true; 4351 } 4352 if (volt > (mHistoryCur.batteryVoltage+20) 4353 || volt < (mHistoryCur.batteryVoltage-20)) { 4354 mHistoryCur.batteryVoltage = (char)volt; 4355 changed = true; 4356 } 4357 if (changed) { 4358 addHistoryRecordLocked(SystemClock.elapsedRealtime()); 4359 } 4360 } 4361 if (!onBattery && status == BatteryManager.BATTERY_STATUS_FULL) { 4362 // We don't record history while we are plugged in and fully charged. 4363 // The next time we are unplugged, history will be cleared. 4364 mRecordingHistory = false; 4365 } 4366 } 4367 } 4368 4369 public void updateKernelWakelocksLocked() { 4370 Map<String, KernelWakelockStats> m = readKernelWakelockStats(); 4371 4372 if (m == null) { 4373 // Not crashing might make board bringup easier. 4374 Slog.w(TAG, "Couldn't get kernel wake lock stats"); 4375 return; 4376 } 4377 4378 for (Map.Entry<String, KernelWakelockStats> ent : m.entrySet()) { 4379 String name = ent.getKey(); 4380 KernelWakelockStats kws = ent.getValue(); 4381 4382 SamplingTimer kwlt = mKernelWakelockStats.get(name); 4383 if (kwlt == null) { 4384 kwlt = new SamplingTimer(mUnpluggables, mOnBatteryInternal, 4385 true /* track reported values */); 4386 mKernelWakelockStats.put(name, kwlt); 4387 } 4388 kwlt.updateCurrentReportedCount(kws.mCount); 4389 kwlt.updateCurrentReportedTotalTime(kws.mTotalTime); 4390 kwlt.setUpdateVersion(sKernelWakelockUpdateVersion); 4391 } 4392 4393 if (m.size() != mKernelWakelockStats.size()) { 4394 // Set timers to stale if they didn't appear in /proc/wakelocks this time. 4395 for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) { 4396 SamplingTimer st = ent.getValue(); 4397 if (st.getUpdateVersion() != sKernelWakelockUpdateVersion) { 4398 st.setStale(); 4399 } 4400 } 4401 } 4402 } 4403 4404 public long getAwakeTimeBattery() { 4405 return computeBatteryUptime(getBatteryUptimeLocked(), STATS_CURRENT); 4406 } 4407 4408 public long getAwakeTimePlugged() { 4409 return (SystemClock.uptimeMillis() * 1000) - getAwakeTimeBattery(); 4410 } 4411 4412 @Override 4413 public long computeUptime(long curTime, int which) { 4414 switch (which) { 4415 case STATS_SINCE_CHARGED: return mUptime + (curTime-mUptimeStart); 4416 case STATS_LAST: return mLastUptime; 4417 case STATS_CURRENT: return (curTime-mUptimeStart); 4418 case STATS_SINCE_UNPLUGGED: return (curTime-mTrackBatteryUptimeStart); 4419 } 4420 return 0; 4421 } 4422 4423 @Override 4424 public long computeRealtime(long curTime, int which) { 4425 switch (which) { 4426 case STATS_SINCE_CHARGED: return mRealtime + (curTime-mRealtimeStart); 4427 case STATS_LAST: return mLastRealtime; 4428 case STATS_CURRENT: return (curTime-mRealtimeStart); 4429 case STATS_SINCE_UNPLUGGED: return (curTime-mTrackBatteryRealtimeStart); 4430 } 4431 return 0; 4432 } 4433 4434 @Override 4435 public long computeBatteryUptime(long curTime, int which) { 4436 switch (which) { 4437 case STATS_SINCE_CHARGED: 4438 return mBatteryUptime + getBatteryUptime(curTime); 4439 case STATS_LAST: 4440 return mBatteryLastUptime; 4441 case STATS_CURRENT: 4442 return getBatteryUptime(curTime); 4443 case STATS_SINCE_UNPLUGGED: 4444 return getBatteryUptimeLocked(curTime) - mUnpluggedBatteryUptime; 4445 } 4446 return 0; 4447 } 4448 4449 @Override 4450 public long computeBatteryRealtime(long curTime, int which) { 4451 switch (which) { 4452 case STATS_SINCE_CHARGED: 4453 return mBatteryRealtime + getBatteryRealtimeLocked(curTime); 4454 case STATS_LAST: 4455 return mBatteryLastRealtime; 4456 case STATS_CURRENT: 4457 return getBatteryRealtimeLocked(curTime); 4458 case STATS_SINCE_UNPLUGGED: 4459 return getBatteryRealtimeLocked(curTime) - mUnpluggedBatteryRealtime; 4460 } 4461 return 0; 4462 } 4463 4464 long getBatteryUptimeLocked(long curTime) { 4465 long time = mTrackBatteryPastUptime; 4466 if (mOnBatteryInternal) { 4467 time += curTime - mTrackBatteryUptimeStart; 4468 } 4469 return time; 4470 } 4471 4472 long getBatteryUptimeLocked() { 4473 return getBatteryUptime(SystemClock.uptimeMillis() * 1000); 4474 } 4475 4476 @Override 4477 public long getBatteryUptime(long curTime) { 4478 return getBatteryUptimeLocked(curTime); 4479 } 4480 4481 long getBatteryRealtimeLocked(long curTime) { 4482 long time = mTrackBatteryPastRealtime; 4483 if (mOnBatteryInternal) { 4484 time += curTime - mTrackBatteryRealtimeStart; 4485 } 4486 return time; 4487 } 4488 4489 @Override 4490 public long getBatteryRealtime(long curTime) { 4491 return getBatteryRealtimeLocked(curTime); 4492 } 4493 4494 private long getTcpBytes(long current, long[] dataBytes, int which) { 4495 if (which == STATS_LAST) { 4496 return dataBytes[STATS_LAST]; 4497 } else { 4498 if (which == STATS_SINCE_UNPLUGGED) { 4499 if (dataBytes[STATS_SINCE_UNPLUGGED] < 0) { 4500 return dataBytes[STATS_LAST]; 4501 } else { 4502 return current - dataBytes[STATS_SINCE_UNPLUGGED]; 4503 } 4504 } else if (which == STATS_SINCE_CHARGED) { 4505 return (current - dataBytes[STATS_CURRENT]) + dataBytes[STATS_SINCE_CHARGED]; 4506 } 4507 return current - dataBytes[STATS_CURRENT]; 4508 } 4509 } 4510 4511 /** Only STATS_UNPLUGGED works properly */ 4512 public long getMobileTcpBytesSent(int which) { 4513 return getTcpBytes(TrafficStats.getMobileTxBytes(), mMobileDataTx, which); 4514 } 4515 4516 /** Only STATS_UNPLUGGED works properly */ 4517 public long getMobileTcpBytesReceived(int which) { 4518 return getTcpBytes(TrafficStats.getMobileRxBytes(), mMobileDataRx, which); 4519 } 4520 4521 /** Only STATS_UNPLUGGED works properly */ 4522 public long getTotalTcpBytesSent(int which) { 4523 return getTcpBytes(TrafficStats.getTotalTxBytes(), mTotalDataTx, which); 4524 } 4525 4526 /** Only STATS_UNPLUGGED works properly */ 4527 public long getTotalTcpBytesReceived(int which) { 4528 return getTcpBytes(TrafficStats.getTotalRxBytes(), mTotalDataRx, which); 4529 } 4530 4531 @Override 4532 public int getDischargeStartLevel() { 4533 synchronized(this) { 4534 return getDischargeStartLevelLocked(); 4535 } 4536 } 4537 4538 public int getDischargeStartLevelLocked() { 4539 return mDischargeUnplugLevel; 4540 } 4541 4542 @Override 4543 public int getDischargeCurrentLevel() { 4544 synchronized(this) { 4545 return getDischargeCurrentLevelLocked(); 4546 } 4547 } 4548 4549 public int getDischargeCurrentLevelLocked() { 4550 return mDischargeCurrentLevel; 4551 } 4552 4553 @Override 4554 public int getLowDischargeAmountSinceCharge() { 4555 synchronized(this) { 4556 int val = mLowDischargeAmountSinceCharge; 4557 if (mOnBattery && mDischargeCurrentLevel < mDischargeUnplugLevel) { 4558 val += mDischargeUnplugLevel-mDischargeCurrentLevel-1; 4559 } 4560 return val; 4561 } 4562 } 4563 4564 @Override 4565 public int getHighDischargeAmountSinceCharge() { 4566 synchronized(this) { 4567 int val = mHighDischargeAmountSinceCharge; 4568 if (mOnBattery && mDischargeCurrentLevel < mDischargeUnplugLevel) { 4569 val += mDischargeUnplugLevel-mDischargeCurrentLevel; 4570 } 4571 return val; 4572 } 4573 } 4574 4575 public int getDischargeAmountScreenOn() { 4576 synchronized(this) { 4577 int val = mDischargeAmountScreenOn; 4578 if (mOnBattery && mScreenOn 4579 && mDischargeCurrentLevel < mDischargeScreenOnUnplugLevel) { 4580 val += mDischargeScreenOnUnplugLevel-mDischargeCurrentLevel; 4581 } 4582 return val; 4583 } 4584 } 4585 4586 public int getDischargeAmountScreenOnSinceCharge() { 4587 synchronized(this) { 4588 int val = mDischargeAmountScreenOnSinceCharge; 4589 if (mOnBattery && mScreenOn 4590 && mDischargeCurrentLevel < mDischargeScreenOnUnplugLevel) { 4591 val += mDischargeScreenOnUnplugLevel-mDischargeCurrentLevel; 4592 } 4593 return val; 4594 } 4595 } 4596 4597 public int getDischargeAmountScreenOff() { 4598 synchronized(this) { 4599 int val = mDischargeAmountScreenOff; 4600 if (mOnBattery && !mScreenOn 4601 && mDischargeCurrentLevel < mDischargeScreenOffUnplugLevel) { 4602 val += mDischargeScreenOffUnplugLevel-mDischargeCurrentLevel; 4603 } 4604 return val; 4605 } 4606 } 4607 4608 public int getDischargeAmountScreenOffSinceCharge() { 4609 synchronized(this) { 4610 int val = mDischargeAmountScreenOffSinceCharge; 4611 if (mOnBattery && !mScreenOn 4612 && mDischargeCurrentLevel < mDischargeScreenOffUnplugLevel) { 4613 val += mDischargeScreenOffUnplugLevel-mDischargeCurrentLevel; 4614 } 4615 return val; 4616 } 4617 } 4618 4619 @Override 4620 public int getCpuSpeedSteps() { 4621 return sNumSpeedSteps; 4622 } 4623 4624 /** 4625 * Retrieve the statistics object for a particular uid, creating if needed. 4626 */ 4627 public Uid getUidStatsLocked(int uid) { 4628 Uid u = mUidStats.get(uid); 4629 if (u == null) { 4630 u = new Uid(uid); 4631 mUidStats.put(uid, u); 4632 } 4633 return u; 4634 } 4635 4636 /** 4637 * Remove the statistics object for a particular uid. 4638 */ 4639 public void removeUidStatsLocked(int uid) { 4640 mUidStats.remove(uid); 4641 } 4642 4643 /** 4644 * Retrieve the statistics object for a particular process, creating 4645 * if needed. 4646 */ 4647 public Uid.Proc getProcessStatsLocked(int uid, String name) { 4648 Uid u = getUidStatsLocked(uid); 4649 return u.getProcessStatsLocked(name); 4650 } 4651 4652 /** 4653 * Retrieve the statistics object for a particular process, given 4654 * the name of the process. 4655 * @param name process name 4656 * @return the statistics object for the process 4657 */ 4658 public Uid.Proc getProcessStatsLocked(String name, int pid) { 4659 int uid; 4660 if (mUidCache.containsKey(name)) { 4661 uid = mUidCache.get(name); 4662 } else { 4663 uid = Process.getUidForPid(pid); 4664 mUidCache.put(name, uid); 4665 } 4666 Uid u = getUidStatsLocked(uid); 4667 return u.getProcessStatsLocked(name); 4668 } 4669 4670 /** 4671 * Retrieve the statistics object for a particular process, creating 4672 * if needed. 4673 */ 4674 public Uid.Pkg getPackageStatsLocked(int uid, String pkg) { 4675 Uid u = getUidStatsLocked(uid); 4676 return u.getPackageStatsLocked(pkg); 4677 } 4678 4679 /** 4680 * Retrieve the statistics object for a particular service, creating 4681 * if needed. 4682 */ 4683 public Uid.Pkg.Serv getServiceStatsLocked(int uid, String pkg, String name) { 4684 Uid u = getUidStatsLocked(uid); 4685 return u.getServiceStatsLocked(pkg, name); 4686 } 4687 4688 /** 4689 * Massage data to distribute any reasonable work down to more specific 4690 * owners. Must only be called on a dead BatteryStats object! 4691 */ 4692 public void distributeWorkLocked(int which) { 4693 // Aggregate all CPU time associated with WIFI. 4694 Uid wifiUid = mUidStats.get(Process.WIFI_UID); 4695 if (wifiUid != null) { 4696 long uSecTime = computeBatteryRealtime(SystemClock.elapsedRealtime() * 1000, which); 4697 for (Uid.Proc proc : wifiUid.mProcessStats.values()) { 4698 long totalRunningTime = getGlobalWifiRunningTime(uSecTime, which); 4699 for (int i=0; i<mUidStats.size(); i++) { 4700 Uid uid = mUidStats.valueAt(i); 4701 if (uid.mUid != Process.WIFI_UID) { 4702 long uidRunningTime = uid.getWifiRunningTime(uSecTime, which); 4703 if (uidRunningTime > 0) { 4704 Uid.Proc uidProc = uid.getProcessStatsLocked("*wifi*"); 4705 long time = proc.getUserTime(which); 4706 time = (time*uidRunningTime)/totalRunningTime; 4707 uidProc.mUserTime += time; 4708 proc.mUserTime -= time; 4709 time = proc.getSystemTime(which); 4710 time = (time*uidRunningTime)/totalRunningTime; 4711 uidProc.mSystemTime += time; 4712 proc.mSystemTime -= time; 4713 time = proc.getForegroundTime(which); 4714 time = (time*uidRunningTime)/totalRunningTime; 4715 uidProc.mForegroundTime += time; 4716 proc.mForegroundTime -= time; 4717 for (int sb=0; sb<proc.mSpeedBins.length; sb++) { 4718 SamplingCounter sc = proc.mSpeedBins[sb]; 4719 if (sc != null) { 4720 time = sc.getCountLocked(which); 4721 time = (time*uidRunningTime)/totalRunningTime; 4722 SamplingCounter uidSc = uidProc.mSpeedBins[sb]; 4723 if (uidSc == null) { 4724 uidSc = new SamplingCounter(mUnpluggables); 4725 uidProc.mSpeedBins[sb] = uidSc; 4726 } 4727 uidSc.mCount.addAndGet((int)time); 4728 sc.mCount.addAndGet((int)-time); 4729 } 4730 } 4731 totalRunningTime -= uidRunningTime; 4732 } 4733 } 4734 } 4735 } 4736 } 4737 } 4738 4739 public void shutdownLocked() { 4740 writeSyncLocked(); 4741 mShuttingDown = true; 4742 } 4743 4744 Parcel mPendingWrite = null; 4745 final ReentrantLock mWriteLock = new ReentrantLock(); 4746 4747 public void writeAsyncLocked() { 4748 writeLocked(false); 4749 } 4750 4751 public void writeSyncLocked() { 4752 writeLocked(true); 4753 } 4754 4755 void writeLocked(boolean sync) { 4756 if (mFile == null) { 4757 Slog.w("BatteryStats", "writeLocked: no file associated with this instance"); 4758 return; 4759 } 4760 4761 if (mShuttingDown) { 4762 return; 4763 } 4764 4765 Parcel out = Parcel.obtain(); 4766 writeSummaryToParcel(out); 4767 mLastWriteTime = SystemClock.elapsedRealtime(); 4768 4769 if (mPendingWrite != null) { 4770 mPendingWrite.recycle(); 4771 } 4772 mPendingWrite = out; 4773 4774 if (sync) { 4775 commitPendingDataToDisk(); 4776 } else { 4777 Thread thr = new Thread("BatteryStats-Write") { 4778 @Override 4779 public void run() { 4780 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 4781 commitPendingDataToDisk(); 4782 } 4783 }; 4784 thr.start(); 4785 } 4786 } 4787 4788 public void commitPendingDataToDisk() { 4789 final Parcel next; 4790 synchronized (this) { 4791 next = mPendingWrite; 4792 mPendingWrite = null; 4793 if (next == null) { 4794 return; 4795 } 4796 4797 mWriteLock.lock(); 4798 } 4799 4800 try { 4801 FileOutputStream stream = new FileOutputStream(mFile.chooseForWrite()); 4802 stream.write(next.marshall()); 4803 stream.flush(); 4804 FileUtils.sync(stream); 4805 stream.close(); 4806 mFile.commit(); 4807 } catch (IOException e) { 4808 Slog.w("BatteryStats", "Error writing battery statistics", e); 4809 mFile.rollback(); 4810 } finally { 4811 next.recycle(); 4812 mWriteLock.unlock(); 4813 } 4814 } 4815 4816 static byte[] readFully(FileInputStream stream) throws java.io.IOException { 4817 int pos = 0; 4818 int avail = stream.available(); 4819 byte[] data = new byte[avail]; 4820 while (true) { 4821 int amt = stream.read(data, pos, data.length-pos); 4822 //Log.i("foo", "Read " + amt + " bytes at " + pos 4823 // + " of avail " + data.length); 4824 if (amt <= 0) { 4825 //Log.i("foo", "**** FINISHED READING: pos=" + pos 4826 // + " len=" + data.length); 4827 return data; 4828 } 4829 pos += amt; 4830 avail = stream.available(); 4831 if (avail > data.length-pos) { 4832 byte[] newData = new byte[pos+avail]; 4833 System.arraycopy(data, 0, newData, 0, pos); 4834 data = newData; 4835 } 4836 } 4837 } 4838 4839 public void readLocked() { 4840 if (mFile == null) { 4841 Slog.w("BatteryStats", "readLocked: no file associated with this instance"); 4842 return; 4843 } 4844 4845 mUidStats.clear(); 4846 4847 try { 4848 File file = mFile.chooseForRead(); 4849 if (!file.exists()) { 4850 return; 4851 } 4852 FileInputStream stream = new FileInputStream(file); 4853 4854 byte[] raw = readFully(stream); 4855 Parcel in = Parcel.obtain(); 4856 in.unmarshall(raw, 0, raw.length); 4857 in.setDataPosition(0); 4858 stream.close(); 4859 4860 readSummaryFromParcel(in); 4861 } catch(java.io.IOException e) { 4862 Slog.e("BatteryStats", "Error reading battery statistics", e); 4863 } 4864 4865 long now = SystemClock.elapsedRealtime(); 4866 addHistoryRecordLocked(now, HistoryItem.CMD_START); 4867 addHistoryBufferLocked(now, HistoryItem.CMD_START); 4868 } 4869 4870 public int describeContents() { 4871 return 0; 4872 } 4873 4874 void readHistory(Parcel in, boolean andOldHistory) { 4875 final long historyBaseTime = in.readLong(); 4876 4877 mHistoryBuffer.setDataSize(0); 4878 mHistoryBuffer.setDataPosition(0); 4879 4880 int bufSize = in.readInt(); 4881 int curPos = in.dataPosition(); 4882 if (bufSize >= (MAX_MAX_HISTORY_BUFFER*3)) { 4883 Slog.w(TAG, "File corrupt: history data buffer too large " + bufSize); 4884 } else if ((bufSize&~3) != bufSize) { 4885 Slog.w(TAG, "File corrupt: history data buffer not aligned " + bufSize); 4886 } else { 4887 if (DEBUG_HISTORY) Slog.i(TAG, "***************** READING NEW HISTORY: " + bufSize 4888 + " bytes at " + curPos); 4889 mHistoryBuffer.appendFrom(in, curPos, bufSize); 4890 in.setDataPosition(curPos + bufSize); 4891 } 4892 4893 if (andOldHistory) { 4894 readOldHistory(in); 4895 } 4896 4897 if (DEBUG_HISTORY) { 4898 StringBuilder sb = new StringBuilder(128); 4899 sb.append("****************** OLD mHistoryBaseTime: "); 4900 TimeUtils.formatDuration(mHistoryBaseTime, sb); 4901 Slog.i(TAG, sb.toString()); 4902 } 4903 mHistoryBaseTime = historyBaseTime; 4904 if (DEBUG_HISTORY) { 4905 StringBuilder sb = new StringBuilder(128); 4906 sb.append("****************** NEW mHistoryBaseTime: "); 4907 TimeUtils.formatDuration(mHistoryBaseTime, sb); 4908 Slog.i(TAG, sb.toString()); 4909 } 4910 4911 // We are just arbitrarily going to insert 1 minute from the sample of 4912 // the last run until samples in this run. 4913 if (mHistoryBaseTime > 0) { 4914 long oldnow = SystemClock.elapsedRealtime(); 4915 mHistoryBaseTime = (mHistoryBaseTime - oldnow) + 60*1000; 4916 if (DEBUG_HISTORY) { 4917 StringBuilder sb = new StringBuilder(128); 4918 sb.append("****************** ADJUSTED mHistoryBaseTime: "); 4919 TimeUtils.formatDuration(mHistoryBaseTime, sb); 4920 Slog.i(TAG, sb.toString()); 4921 } 4922 } 4923 } 4924 4925 void readOldHistory(Parcel in) { 4926 mHistory = mHistoryEnd = mHistoryCache = null; 4927 long time; 4928 while (in.dataAvail() > 0 && (time=in.readLong()) >= 0) { 4929 HistoryItem rec = new HistoryItem(time, in); 4930 addHistoryRecordLocked(rec); 4931 } 4932 } 4933 4934 void writeHistory(Parcel out, boolean andOldHistory) { 4935 if (DEBUG_HISTORY) { 4936 StringBuilder sb = new StringBuilder(128); 4937 sb.append("****************** WRITING mHistoryBaseTime: "); 4938 TimeUtils.formatDuration(mHistoryBaseTime, sb); 4939 sb.append(" mLastHistoryTime: "); 4940 TimeUtils.formatDuration(mLastHistoryTime, sb); 4941 Slog.i(TAG, sb.toString()); 4942 } 4943 out.writeLong(mHistoryBaseTime + mLastHistoryTime); 4944 out.writeInt(mHistoryBuffer.dataSize()); 4945 if (DEBUG_HISTORY) Slog.i(TAG, "***************** WRITING HISTORY: " 4946 + mHistoryBuffer.dataSize() + " bytes at " + out.dataPosition()); 4947 out.appendFrom(mHistoryBuffer, 0, mHistoryBuffer.dataSize()); 4948 4949 if (andOldHistory) { 4950 writeOldHistory(out); 4951 } 4952 } 4953 4954 void writeOldHistory(Parcel out) { 4955 HistoryItem rec = mHistory; 4956 while (rec != null) { 4957 if (rec.time >= 0) rec.writeToParcel(out, 0); 4958 rec = rec.next; 4959 } 4960 out.writeLong(-1); 4961 } 4962 4963 private void readSummaryFromParcel(Parcel in) { 4964 final int version = in.readInt(); 4965 if (version != VERSION) { 4966 Slog.w("BatteryStats", "readFromParcel: version got " + version 4967 + ", expected " + VERSION + "; erasing old stats"); 4968 return; 4969 } 4970 4971 readHistory(in, true); 4972 4973 mStartCount = in.readInt(); 4974 mBatteryUptime = in.readLong(); 4975 mBatteryRealtime = in.readLong(); 4976 mUptime = in.readLong(); 4977 mRealtime = in.readLong(); 4978 mDischargeUnplugLevel = in.readInt(); 4979 mDischargeCurrentLevel = in.readInt(); 4980 mLowDischargeAmountSinceCharge = in.readInt(); 4981 mHighDischargeAmountSinceCharge = in.readInt(); 4982 mDischargeAmountScreenOnSinceCharge = in.readInt(); 4983 mDischargeAmountScreenOffSinceCharge = in.readInt(); 4984 4985 mStartCount++; 4986 4987 mScreenOn = false; 4988 mScreenOnTimer.readSummaryFromParcelLocked(in); 4989 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 4990 mScreenBrightnessTimer[i].readSummaryFromParcelLocked(in); 4991 } 4992 mInputEventCounter.readSummaryFromParcelLocked(in); 4993 mPhoneOn = false; 4994 mPhoneOnTimer.readSummaryFromParcelLocked(in); 4995 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) { 4996 mPhoneSignalStrengthsTimer[i].readSummaryFromParcelLocked(in); 4997 } 4998 mPhoneSignalScanningTimer.readSummaryFromParcelLocked(in); 4999 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 5000 mPhoneDataConnectionsTimer[i].readSummaryFromParcelLocked(in); 5001 } 5002 mWifiOn = false; 5003 mWifiOnTimer.readSummaryFromParcelLocked(in); 5004 mGlobalWifiRunning = false; 5005 mGlobalWifiRunningTimer.readSummaryFromParcelLocked(in); 5006 mBluetoothOn = false; 5007 mBluetoothOnTimer.readSummaryFromParcelLocked(in); 5008 5009 int NKW = in.readInt(); 5010 if (NKW > 10000) { 5011 Slog.w(TAG, "File corrupt: too many kernel wake locks " + NKW); 5012 return; 5013 } 5014 for (int ikw = 0; ikw < NKW; ikw++) { 5015 if (in.readInt() != 0) { 5016 String kwltName = in.readString(); 5017 getKernelWakelockTimerLocked(kwltName).readSummaryFromParcelLocked(in); 5018 } 5019 } 5020 5021 sNumSpeedSteps = in.readInt(); 5022 5023 final int NU = in.readInt(); 5024 if (NU > 10000) { 5025 Slog.w(TAG, "File corrupt: too many uids " + NU); 5026 return; 5027 } 5028 for (int iu = 0; iu < NU; iu++) { 5029 int uid = in.readInt(); 5030 Uid u = new Uid(uid); 5031 mUidStats.put(uid, u); 5032 5033 u.mWifiRunning = false; 5034 if (in.readInt() != 0) { 5035 u.mWifiRunningTimer.readSummaryFromParcelLocked(in); 5036 } 5037 u.mFullWifiLockOut = false; 5038 if (in.readInt() != 0) { 5039 u.mFullWifiLockTimer.readSummaryFromParcelLocked(in); 5040 } 5041 u.mScanWifiLockOut = false; 5042 if (in.readInt() != 0) { 5043 u.mScanWifiLockTimer.readSummaryFromParcelLocked(in); 5044 } 5045 u.mWifiMulticastEnabled = false; 5046 if (in.readInt() != 0) { 5047 u.mWifiMulticastTimer.readSummaryFromParcelLocked(in); 5048 } 5049 u.mAudioTurnedOn = false; 5050 if (in.readInt() != 0) { 5051 u.mAudioTurnedOnTimer.readSummaryFromParcelLocked(in); 5052 } 5053 u.mVideoTurnedOn = false; 5054 if (in.readInt() != 0) { 5055 u.mVideoTurnedOnTimer.readSummaryFromParcelLocked(in); 5056 } 5057 5058 if (in.readInt() != 0) { 5059 if (u.mUserActivityCounters == null) { 5060 u.initUserActivityLocked(); 5061 } 5062 for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) { 5063 u.mUserActivityCounters[i].readSummaryFromParcelLocked(in); 5064 } 5065 } 5066 5067 int NW = in.readInt(); 5068 if (NW > 100) { 5069 Slog.w(TAG, "File corrupt: too many wake locks " + NW); 5070 return; 5071 } 5072 for (int iw = 0; iw < NW; iw++) { 5073 String wlName = in.readString(); 5074 if (in.readInt() != 0) { 5075 u.getWakeTimerLocked(wlName, WAKE_TYPE_FULL).readSummaryFromParcelLocked(in); 5076 } 5077 if (in.readInt() != 0) { 5078 u.getWakeTimerLocked(wlName, WAKE_TYPE_PARTIAL).readSummaryFromParcelLocked(in); 5079 } 5080 if (in.readInt() != 0) { 5081 u.getWakeTimerLocked(wlName, WAKE_TYPE_WINDOW).readSummaryFromParcelLocked(in); 5082 } 5083 } 5084 5085 int NP = in.readInt(); 5086 if (NP > 1000) { 5087 Slog.w(TAG, "File corrupt: too many sensors " + NP); 5088 return; 5089 } 5090 for (int is = 0; is < NP; is++) { 5091 int seNumber = in.readInt(); 5092 if (in.readInt() != 0) { 5093 u.getSensorTimerLocked(seNumber, true) 5094 .readSummaryFromParcelLocked(in); 5095 } 5096 } 5097 5098 NP = in.readInt(); 5099 if (NP > 1000) { 5100 Slog.w(TAG, "File corrupt: too many processes " + NP); 5101 return; 5102 } 5103 for (int ip = 0; ip < NP; ip++) { 5104 String procName = in.readString(); 5105 Uid.Proc p = u.getProcessStatsLocked(procName); 5106 p.mUserTime = p.mLoadedUserTime = in.readLong(); 5107 p.mSystemTime = p.mLoadedSystemTime = in.readLong(); 5108 p.mStarts = p.mLoadedStarts = in.readInt(); 5109 int NSB = in.readInt(); 5110 if (NSB > 100) { 5111 Slog.w(TAG, "File corrupt: too many speed bins " + NSB); 5112 return; 5113 } 5114 p.mSpeedBins = new SamplingCounter[NSB]; 5115 for (int i=0; i<NSB; i++) { 5116 if (in.readInt() != 0) { 5117 p.mSpeedBins[i] = new SamplingCounter(mUnpluggables); 5118 p.mSpeedBins[i].readSummaryFromParcelLocked(in); 5119 } 5120 } 5121 if (!p.readExcessivePowerFromParcelLocked(in)) { 5122 return; 5123 } 5124 } 5125 5126 NP = in.readInt(); 5127 if (NP > 10000) { 5128 Slog.w(TAG, "File corrupt: too many packages " + NP); 5129 return; 5130 } 5131 for (int ip = 0; ip < NP; ip++) { 5132 String pkgName = in.readString(); 5133 Uid.Pkg p = u.getPackageStatsLocked(pkgName); 5134 p.mWakeups = p.mLoadedWakeups = in.readInt(); 5135 final int NS = in.readInt(); 5136 if (NS > 1000) { 5137 Slog.w(TAG, "File corrupt: too many services " + NS); 5138 return; 5139 } 5140 for (int is = 0; is < NS; is++) { 5141 String servName = in.readString(); 5142 Uid.Pkg.Serv s = u.getServiceStatsLocked(pkgName, servName); 5143 s.mStartTime = s.mLoadedStartTime = in.readLong(); 5144 s.mStarts = s.mLoadedStarts = in.readInt(); 5145 s.mLaunches = s.mLoadedLaunches = in.readInt(); 5146 } 5147 } 5148 5149 u.mLoadedTcpBytesReceived = in.readLong(); 5150 u.mLoadedTcpBytesSent = in.readLong(); 5151 } 5152 } 5153 5154 /** 5155 * Writes a summary of the statistics to a Parcel, in a format suitable to be written to 5156 * disk. This format does not allow a lossless round-trip. 5157 * 5158 * @param out the Parcel to be written to. 5159 */ 5160 public void writeSummaryToParcel(Parcel out) { 5161 // Need to update with current kernel wake lock counts. 5162 updateKernelWakelocksLocked(); 5163 5164 final long NOW_SYS = SystemClock.uptimeMillis() * 1000; 5165 final long NOWREAL_SYS = SystemClock.elapsedRealtime() * 1000; 5166 final long NOW = getBatteryUptimeLocked(NOW_SYS); 5167 final long NOWREAL = getBatteryRealtimeLocked(NOWREAL_SYS); 5168 5169 out.writeInt(VERSION); 5170 5171 writeHistory(out, true); 5172 5173 out.writeInt(mStartCount); 5174 out.writeLong(computeBatteryUptime(NOW_SYS, STATS_SINCE_CHARGED)); 5175 out.writeLong(computeBatteryRealtime(NOWREAL_SYS, STATS_SINCE_CHARGED)); 5176 out.writeLong(computeUptime(NOW_SYS, STATS_SINCE_CHARGED)); 5177 out.writeLong(computeRealtime(NOWREAL_SYS, STATS_SINCE_CHARGED)); 5178 out.writeInt(mDischargeUnplugLevel); 5179 out.writeInt(mDischargeCurrentLevel); 5180 out.writeInt(getLowDischargeAmountSinceCharge()); 5181 out.writeInt(getHighDischargeAmountSinceCharge()); 5182 out.writeInt(getDischargeAmountScreenOnSinceCharge()); 5183 out.writeInt(getDischargeAmountScreenOffSinceCharge()); 5184 5185 mScreenOnTimer.writeSummaryFromParcelLocked(out, NOWREAL); 5186 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 5187 mScreenBrightnessTimer[i].writeSummaryFromParcelLocked(out, NOWREAL); 5188 } 5189 mInputEventCounter.writeSummaryFromParcelLocked(out); 5190 mPhoneOnTimer.writeSummaryFromParcelLocked(out, NOWREAL); 5191 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) { 5192 mPhoneSignalStrengthsTimer[i].writeSummaryFromParcelLocked(out, NOWREAL); 5193 } 5194 mPhoneSignalScanningTimer.writeSummaryFromParcelLocked(out, NOWREAL); 5195 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 5196 mPhoneDataConnectionsTimer[i].writeSummaryFromParcelLocked(out, NOWREAL); 5197 } 5198 mWifiOnTimer.writeSummaryFromParcelLocked(out, NOWREAL); 5199 mGlobalWifiRunningTimer.writeSummaryFromParcelLocked(out, NOWREAL); 5200 mBluetoothOnTimer.writeSummaryFromParcelLocked(out, NOWREAL); 5201 5202 out.writeInt(mKernelWakelockStats.size()); 5203 for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) { 5204 Timer kwlt = ent.getValue(); 5205 if (kwlt != null) { 5206 out.writeInt(1); 5207 out.writeString(ent.getKey()); 5208 ent.getValue().writeSummaryFromParcelLocked(out, NOWREAL); 5209 } else { 5210 out.writeInt(0); 5211 } 5212 } 5213 5214 out.writeInt(sNumSpeedSteps); 5215 final int NU = mUidStats.size(); 5216 out.writeInt(NU); 5217 for (int iu = 0; iu < NU; iu++) { 5218 out.writeInt(mUidStats.keyAt(iu)); 5219 Uid u = mUidStats.valueAt(iu); 5220 5221 if (u.mWifiRunningTimer != null) { 5222 out.writeInt(1); 5223 u.mWifiRunningTimer.writeSummaryFromParcelLocked(out, NOWREAL); 5224 } else { 5225 out.writeInt(0); 5226 } 5227 if (u.mFullWifiLockTimer != null) { 5228 out.writeInt(1); 5229 u.mFullWifiLockTimer.writeSummaryFromParcelLocked(out, NOWREAL); 5230 } else { 5231 out.writeInt(0); 5232 } 5233 if (u.mScanWifiLockTimer != null) { 5234 out.writeInt(1); 5235 u.mScanWifiLockTimer.writeSummaryFromParcelLocked(out, NOWREAL); 5236 } else { 5237 out.writeInt(0); 5238 } 5239 if (u.mWifiMulticastTimer != null) { 5240 out.writeInt(1); 5241 u.mWifiMulticastTimer.writeSummaryFromParcelLocked(out, NOWREAL); 5242 } else { 5243 out.writeInt(0); 5244 } 5245 if (u.mAudioTurnedOnTimer != null) { 5246 out.writeInt(1); 5247 u.mAudioTurnedOnTimer.writeSummaryFromParcelLocked(out, NOWREAL); 5248 } else { 5249 out.writeInt(0); 5250 } 5251 if (u.mVideoTurnedOnTimer != null) { 5252 out.writeInt(1); 5253 u.mVideoTurnedOnTimer.writeSummaryFromParcelLocked(out, NOWREAL); 5254 } else { 5255 out.writeInt(0); 5256 } 5257 5258 if (u.mUserActivityCounters == null) { 5259 out.writeInt(0); 5260 } else { 5261 out.writeInt(1); 5262 for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) { 5263 u.mUserActivityCounters[i].writeSummaryFromParcelLocked(out); 5264 } 5265 } 5266 5267 int NW = u.mWakelockStats.size(); 5268 out.writeInt(NW); 5269 if (NW > 0) { 5270 for (Map.Entry<String, BatteryStatsImpl.Uid.Wakelock> ent 5271 : u.mWakelockStats.entrySet()) { 5272 out.writeString(ent.getKey()); 5273 Uid.Wakelock wl = ent.getValue(); 5274 if (wl.mTimerFull != null) { 5275 out.writeInt(1); 5276 wl.mTimerFull.writeSummaryFromParcelLocked(out, NOWREAL); 5277 } else { 5278 out.writeInt(0); 5279 } 5280 if (wl.mTimerPartial != null) { 5281 out.writeInt(1); 5282 wl.mTimerPartial.writeSummaryFromParcelLocked(out, NOWREAL); 5283 } else { 5284 out.writeInt(0); 5285 } 5286 if (wl.mTimerWindow != null) { 5287 out.writeInt(1); 5288 wl.mTimerWindow.writeSummaryFromParcelLocked(out, NOWREAL); 5289 } else { 5290 out.writeInt(0); 5291 } 5292 } 5293 } 5294 5295 int NSE = u.mSensorStats.size(); 5296 out.writeInt(NSE); 5297 if (NSE > 0) { 5298 for (Map.Entry<Integer, BatteryStatsImpl.Uid.Sensor> ent 5299 : u.mSensorStats.entrySet()) { 5300 out.writeInt(ent.getKey()); 5301 Uid.Sensor se = ent.getValue(); 5302 if (se.mTimer != null) { 5303 out.writeInt(1); 5304 se.mTimer.writeSummaryFromParcelLocked(out, NOWREAL); 5305 } else { 5306 out.writeInt(0); 5307 } 5308 } 5309 } 5310 5311 int NP = u.mProcessStats.size(); 5312 out.writeInt(NP); 5313 if (NP > 0) { 5314 for (Map.Entry<String, BatteryStatsImpl.Uid.Proc> ent 5315 : u.mProcessStats.entrySet()) { 5316 out.writeString(ent.getKey()); 5317 Uid.Proc ps = ent.getValue(); 5318 out.writeLong(ps.mUserTime); 5319 out.writeLong(ps.mSystemTime); 5320 out.writeInt(ps.mStarts); 5321 final int N = ps.mSpeedBins.length; 5322 out.writeInt(N); 5323 for (int i=0; i<N; i++) { 5324 if (ps.mSpeedBins[i] != null) { 5325 out.writeInt(1); 5326 ps.mSpeedBins[i].writeSummaryFromParcelLocked(out); 5327 } else { 5328 out.writeInt(0); 5329 } 5330 } 5331 ps.writeExcessivePowerToParcelLocked(out); 5332 } 5333 } 5334 5335 NP = u.mPackageStats.size(); 5336 out.writeInt(NP); 5337 if (NP > 0) { 5338 for (Map.Entry<String, BatteryStatsImpl.Uid.Pkg> ent 5339 : u.mPackageStats.entrySet()) { 5340 out.writeString(ent.getKey()); 5341 Uid.Pkg ps = ent.getValue(); 5342 out.writeInt(ps.mWakeups); 5343 final int NS = ps.mServiceStats.size(); 5344 out.writeInt(NS); 5345 if (NS > 0) { 5346 for (Map.Entry<String, BatteryStatsImpl.Uid.Pkg.Serv> sent 5347 : ps.mServiceStats.entrySet()) { 5348 out.writeString(sent.getKey()); 5349 BatteryStatsImpl.Uid.Pkg.Serv ss = sent.getValue(); 5350 long time = ss.getStartTimeToNowLocked(NOW); 5351 out.writeLong(time); 5352 out.writeInt(ss.mStarts); 5353 out.writeInt(ss.mLaunches); 5354 } 5355 } 5356 } 5357 } 5358 5359 out.writeLong(u.getTcpBytesReceived(STATS_SINCE_CHARGED)); 5360 out.writeLong(u.getTcpBytesSent(STATS_SINCE_CHARGED)); 5361 } 5362 } 5363 5364 public void readFromParcel(Parcel in) { 5365 readFromParcelLocked(in); 5366 } 5367 5368 void readFromParcelLocked(Parcel in) { 5369 int magic = in.readInt(); 5370 if (magic != MAGIC) { 5371 throw new ParcelFormatException("Bad magic number"); 5372 } 5373 5374 readHistory(in, false); 5375 5376 mStartCount = in.readInt(); 5377 mBatteryUptime = in.readLong(); 5378 mBatteryLastUptime = 0; 5379 mBatteryRealtime = in.readLong(); 5380 mBatteryLastRealtime = 0; 5381 mScreenOn = false; 5382 mScreenOnTimer = new StopwatchTimer(null, -1, null, mUnpluggables, in); 5383 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 5384 mScreenBrightnessTimer[i] = new StopwatchTimer(null, -100-i, 5385 null, mUnpluggables, in); 5386 } 5387 mInputEventCounter = new Counter(mUnpluggables, in); 5388 mPhoneOn = false; 5389 mPhoneOnTimer = new StopwatchTimer(null, -2, null, mUnpluggables, in); 5390 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) { 5391 mPhoneSignalStrengthsTimer[i] = new StopwatchTimer(null, -200-i, 5392 null, mUnpluggables, in); 5393 } 5394 mPhoneSignalScanningTimer = new StopwatchTimer(null, -200+1, null, mUnpluggables, in); 5395 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 5396 mPhoneDataConnectionsTimer[i] = new StopwatchTimer(null, -300-i, 5397 null, mUnpluggables, in); 5398 } 5399 mWifiOn = false; 5400 mWifiOnTimer = new StopwatchTimer(null, -2, null, mUnpluggables, in); 5401 mGlobalWifiRunning = false; 5402 mGlobalWifiRunningTimer = new StopwatchTimer(null, -2, null, mUnpluggables, in); 5403 mBluetoothOn = false; 5404 mBluetoothOnTimer = new StopwatchTimer(null, -2, null, mUnpluggables, in); 5405 mUptime = in.readLong(); 5406 mUptimeStart = in.readLong(); 5407 mLastUptime = 0; 5408 mRealtime = in.readLong(); 5409 mRealtimeStart = in.readLong(); 5410 mLastRealtime = 0; 5411 mOnBattery = in.readInt() != 0; 5412 mOnBatteryInternal = false; // we are no longer really running. 5413 mTrackBatteryPastUptime = in.readLong(); 5414 mTrackBatteryUptimeStart = in.readLong(); 5415 mTrackBatteryPastRealtime = in.readLong(); 5416 mTrackBatteryRealtimeStart = in.readLong(); 5417 mUnpluggedBatteryUptime = in.readLong(); 5418 mUnpluggedBatteryRealtime = in.readLong(); 5419 mDischargeUnplugLevel = in.readInt(); 5420 mDischargeCurrentLevel = in.readInt(); 5421 mLowDischargeAmountSinceCharge = in.readInt(); 5422 mHighDischargeAmountSinceCharge = in.readInt(); 5423 mDischargeAmountScreenOn = in.readInt(); 5424 mDischargeAmountScreenOnSinceCharge = in.readInt(); 5425 mDischargeAmountScreenOff = in.readInt(); 5426 mDischargeAmountScreenOffSinceCharge = in.readInt(); 5427 mLastWriteTime = in.readLong(); 5428 5429 mMobileDataRx[STATS_LAST] = in.readLong(); 5430 mMobileDataRx[STATS_SINCE_UNPLUGGED] = -1; 5431 mMobileDataTx[STATS_LAST] = in.readLong(); 5432 mMobileDataTx[STATS_SINCE_UNPLUGGED] = -1; 5433 mTotalDataRx[STATS_LAST] = in.readLong(); 5434 mTotalDataRx[STATS_SINCE_UNPLUGGED] = -1; 5435 mTotalDataTx[STATS_LAST] = in.readLong(); 5436 mTotalDataTx[STATS_SINCE_UNPLUGGED] = -1; 5437 5438 mRadioDataUptime = in.readLong(); 5439 mRadioDataStart = -1; 5440 5441 mBluetoothPingCount = in.readInt(); 5442 mBluetoothPingStart = -1; 5443 5444 mKernelWakelockStats.clear(); 5445 int NKW = in.readInt(); 5446 for (int ikw = 0; ikw < NKW; ikw++) { 5447 if (in.readInt() != 0) { 5448 String wakelockName = in.readString(); 5449 in.readInt(); // Extra 0/1 written by Timer.writeTimerToParcel 5450 SamplingTimer kwlt = new SamplingTimer(mUnpluggables, mOnBattery, in); 5451 mKernelWakelockStats.put(wakelockName, kwlt); 5452 } 5453 } 5454 5455 mPartialTimers.clear(); 5456 mFullTimers.clear(); 5457 mWindowTimers.clear(); 5458 mWifiRunningTimers.clear(); 5459 mFullWifiLockTimers.clear(); 5460 mScanWifiLockTimers.clear(); 5461 mWifiMulticastTimers.clear(); 5462 5463 sNumSpeedSteps = in.readInt(); 5464 5465 int numUids = in.readInt(); 5466 mUidStats.clear(); 5467 for (int i = 0; i < numUids; i++) { 5468 int uid = in.readInt(); 5469 Uid u = new Uid(uid); 5470 u.readFromParcelLocked(mUnpluggables, in); 5471 mUidStats.append(uid, u); 5472 } 5473 } 5474 5475 public void writeToParcel(Parcel out, int flags) { 5476 writeToParcelLocked(out, true, flags); 5477 } 5478 5479 public void writeToParcelWithoutUids(Parcel out, int flags) { 5480 writeToParcelLocked(out, false, flags); 5481 } 5482 5483 @SuppressWarnings("unused") 5484 void writeToParcelLocked(Parcel out, boolean inclUids, int flags) { 5485 // Need to update with current kernel wake lock counts. 5486 updateKernelWakelocksLocked(); 5487 5488 final long uSecUptime = SystemClock.uptimeMillis() * 1000; 5489 final long uSecRealtime = SystemClock.elapsedRealtime() * 1000; 5490 final long batteryUptime = getBatteryUptimeLocked(uSecUptime); 5491 final long batteryRealtime = getBatteryRealtimeLocked(uSecRealtime); 5492 5493 out.writeInt(MAGIC); 5494 5495 writeHistory(out, false); 5496 5497 out.writeInt(mStartCount); 5498 out.writeLong(mBatteryUptime); 5499 out.writeLong(mBatteryRealtime); 5500 mScreenOnTimer.writeToParcel(out, batteryRealtime); 5501 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 5502 mScreenBrightnessTimer[i].writeToParcel(out, batteryRealtime); 5503 } 5504 mInputEventCounter.writeToParcel(out); 5505 mPhoneOnTimer.writeToParcel(out, batteryRealtime); 5506 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) { 5507 mPhoneSignalStrengthsTimer[i].writeToParcel(out, batteryRealtime); 5508 } 5509 mPhoneSignalScanningTimer.writeToParcel(out, batteryRealtime); 5510 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 5511 mPhoneDataConnectionsTimer[i].writeToParcel(out, batteryRealtime); 5512 } 5513 mWifiOnTimer.writeToParcel(out, batteryRealtime); 5514 mGlobalWifiRunningTimer.writeToParcel(out, batteryRealtime); 5515 mBluetoothOnTimer.writeToParcel(out, batteryRealtime); 5516 out.writeLong(mUptime); 5517 out.writeLong(mUptimeStart); 5518 out.writeLong(mRealtime); 5519 out.writeLong(mRealtimeStart); 5520 out.writeInt(mOnBattery ? 1 : 0); 5521 out.writeLong(batteryUptime); 5522 out.writeLong(mTrackBatteryUptimeStart); 5523 out.writeLong(batteryRealtime); 5524 out.writeLong(mTrackBatteryRealtimeStart); 5525 out.writeLong(mUnpluggedBatteryUptime); 5526 out.writeLong(mUnpluggedBatteryRealtime); 5527 out.writeInt(mDischargeUnplugLevel); 5528 out.writeInt(mDischargeCurrentLevel); 5529 out.writeInt(mLowDischargeAmountSinceCharge); 5530 out.writeInt(mHighDischargeAmountSinceCharge); 5531 out.writeInt(mDischargeAmountScreenOn); 5532 out.writeInt(mDischargeAmountScreenOnSinceCharge); 5533 out.writeInt(mDischargeAmountScreenOff); 5534 out.writeInt(mDischargeAmountScreenOffSinceCharge); 5535 out.writeLong(mLastWriteTime); 5536 5537 out.writeLong(getMobileTcpBytesReceived(STATS_SINCE_UNPLUGGED)); 5538 out.writeLong(getMobileTcpBytesSent(STATS_SINCE_UNPLUGGED)); 5539 out.writeLong(getTotalTcpBytesReceived(STATS_SINCE_UNPLUGGED)); 5540 out.writeLong(getTotalTcpBytesSent(STATS_SINCE_UNPLUGGED)); 5541 5542 // Write radio uptime for data 5543 out.writeLong(getRadioDataUptime()); 5544 5545 out.writeInt(getBluetoothPingCount()); 5546 5547 if (inclUids) { 5548 out.writeInt(mKernelWakelockStats.size()); 5549 for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) { 5550 SamplingTimer kwlt = ent.getValue(); 5551 if (kwlt != null) { 5552 out.writeInt(1); 5553 out.writeString(ent.getKey()); 5554 Timer.writeTimerToParcel(out, kwlt, batteryRealtime); 5555 } else { 5556 out.writeInt(0); 5557 } 5558 } 5559 } else { 5560 out.writeInt(0); 5561 } 5562 5563 out.writeInt(sNumSpeedSteps); 5564 5565 if (inclUids) { 5566 int size = mUidStats.size(); 5567 out.writeInt(size); 5568 for (int i = 0; i < size; i++) { 5569 out.writeInt(mUidStats.keyAt(i)); 5570 Uid uid = mUidStats.valueAt(i); 5571 5572 uid.writeToParcelLocked(out, batteryRealtime); 5573 } 5574 } else { 5575 out.writeInt(0); 5576 } 5577 } 5578 5579 public static final Parcelable.Creator<BatteryStatsImpl> CREATOR = 5580 new Parcelable.Creator<BatteryStatsImpl>() { 5581 public BatteryStatsImpl createFromParcel(Parcel in) { 5582 return new BatteryStatsImpl(in); 5583 } 5584 5585 public BatteryStatsImpl[] newArray(int size) { 5586 return new BatteryStatsImpl[size]; 5587 } 5588 }; 5589 5590 public void prepareForDumpLocked() { 5591 // Need to retrieve current kernel wake lock stats before printing. 5592 updateKernelWakelocksLocked(); 5593 } 5594 5595 public void dumpLocked(PrintWriter pw) { 5596 if (DEBUG) { 5597 Printer pr = new PrintWriterPrinter(pw); 5598 pr.println("*** Screen timer:"); 5599 mScreenOnTimer.logState(pr, " "); 5600 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 5601 pr.println("*** Screen brightness #" + i + ":"); 5602 mScreenBrightnessTimer[i].logState(pr, " "); 5603 } 5604 pr.println("*** Input event counter:"); 5605 mInputEventCounter.logState(pr, " "); 5606 pr.println("*** Phone timer:"); 5607 mPhoneOnTimer.logState(pr, " "); 5608 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) { 5609 pr.println("*** Signal strength #" + i + ":"); 5610 mPhoneSignalStrengthsTimer[i].logState(pr, " "); 5611 } 5612 pr.println("*** Signal scanning :"); 5613 mPhoneSignalScanningTimer.logState(pr, " "); 5614 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 5615 pr.println("*** Data connection type #" + i + ":"); 5616 mPhoneDataConnectionsTimer[i].logState(pr, " "); 5617 } 5618 pr.println("*** Wifi timer:"); 5619 mWifiOnTimer.logState(pr, " "); 5620 pr.println("*** WifiRunning timer:"); 5621 mGlobalWifiRunningTimer.logState(pr, " "); 5622 pr.println("*** Bluetooth timer:"); 5623 mBluetoothOnTimer.logState(pr, " "); 5624 } 5625 super.dumpLocked(pw); 5626 } 5627} 5628