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