BatteryStatsImpl.java revision 32907cfb38bda2d3c052cf5139c5b592678fedbb
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.BatteryStats; 24import android.os.Parcel; 25import android.os.ParcelFormatException; 26import android.os.Parcelable; 27import android.os.Process; 28import android.os.SystemClock; 29import android.telephony.ServiceState; 30import android.telephony.SignalStrength; 31import android.telephony.TelephonyManager; 32import android.util.Log; 33import android.util.PrintWriterPrinter; 34import android.util.Printer; 35import android.util.Slog; 36import android.util.SparseArray; 37 38import java.io.BufferedReader; 39import java.io.File; 40import java.io.FileInputStream; 41import java.io.FileOutputStream; 42import java.io.FileReader; 43import java.io.IOException; 44import java.io.PrintWriter; 45import java.util.ArrayList; 46import java.util.HashMap; 47import java.util.Iterator; 48import java.util.Map; 49import java.util.concurrent.atomic.AtomicInteger; 50 51/** 52 * All information we are collecting about things that can happen that impact 53 * battery life. All times are represented in microseconds except where indicated 54 * otherwise. 55 */ 56public final class BatteryStatsImpl extends BatteryStats { 57 private static final String TAG = "BatteryStatsImpl"; 58 private static final boolean DEBUG = false; 59 private static final boolean DEBUG_HISTORY = false; 60 61 // In-memory Parcel magic number, used to detect attempts to unmarshall bad data 62 private static final int MAGIC = 0xBA757475; // 'BATSTATS' 63 64 // Current on-disk Parcel version 65 private static final int VERSION = 44; 66 67 // The maximum number of names wakelocks we will keep track of 68 // per uid; once the limit is reached, we batch the remaining wakelocks 69 // in to one common name. 70 private static final int MAX_WAKELOCKS_PER_UID = 20; 71 72 private static final String BATCHED_WAKELOCK_NAME = "*overflow*"; 73 74 private static int sNumSpeedSteps; 75 76 private final JournaledFile mFile; 77 78 /** 79 * The statistics we have collected organized by uids. 80 */ 81 final SparseArray<BatteryStatsImpl.Uid> mUidStats = 82 new SparseArray<BatteryStatsImpl.Uid>(); 83 84 // A set of pools of currently active timers. When a timer is queried, we will divide the 85 // elapsed time by the number of active timers to arrive at that timer's share of the time. 86 // In order to do this, we must refresh each timer whenever the number of active timers 87 // changes. 88 final ArrayList<StopwatchTimer> mPartialTimers = new ArrayList<StopwatchTimer>(); 89 final ArrayList<StopwatchTimer> mFullTimers = new ArrayList<StopwatchTimer>(); 90 final ArrayList<StopwatchTimer> mWindowTimers = new ArrayList<StopwatchTimer>(); 91 final SparseArray<ArrayList<StopwatchTimer>> mSensorTimers 92 = new SparseArray<ArrayList<StopwatchTimer>>(); 93 94 // These are the objects that will want to do something when the device 95 // is unplugged from power. 96 final ArrayList<Unpluggable> mUnpluggables = new ArrayList<Unpluggable>(); 97 98 BatteryHistoryRecord mHistory; 99 BatteryHistoryRecord mHistoryEnd; 100 BatteryHistoryRecord mHistoryCache; 101 final BatteryHistoryRecord mHistoryCur = new BatteryHistoryRecord(); 102 103 int mStartCount; 104 105 long mBatteryUptime; 106 long mBatteryLastUptime; 107 long mBatteryRealtime; 108 long mBatteryLastRealtime; 109 110 long mUptime; 111 long mUptimeStart; 112 long mLastUptime; 113 long mRealtime; 114 long mRealtimeStart; 115 long mLastRealtime; 116 117 boolean mScreenOn; 118 StopwatchTimer mScreenOnTimer; 119 120 int mScreenBrightnessBin = -1; 121 final StopwatchTimer[] mScreenBrightnessTimer = new StopwatchTimer[NUM_SCREEN_BRIGHTNESS_BINS]; 122 123 Counter mInputEventCounter; 124 125 boolean mPhoneOn; 126 StopwatchTimer mPhoneOnTimer; 127 128 boolean mAudioOn; 129 StopwatchTimer mAudioOnTimer; 130 131 boolean mVideoOn; 132 StopwatchTimer mVideoOnTimer; 133 134 int mPhoneSignalStrengthBin = -1; 135 final StopwatchTimer[] mPhoneSignalStrengthsTimer = 136 new StopwatchTimer[NUM_SIGNAL_STRENGTH_BINS]; 137 138 StopwatchTimer mPhoneSignalScanningTimer; 139 140 int mPhoneDataConnectionType = -1; 141 final StopwatchTimer[] mPhoneDataConnectionsTimer = 142 new StopwatchTimer[NUM_DATA_CONNECTION_TYPES]; 143 144 boolean mWifiOn; 145 StopwatchTimer mWifiOnTimer; 146 int mWifiOnUid = -1; 147 148 boolean mWifiRunning; 149 StopwatchTimer mWifiRunningTimer; 150 151 boolean mBluetoothOn; 152 StopwatchTimer mBluetoothOnTimer; 153 154 /** Bluetooth headset object */ 155 BluetoothHeadset mBtHeadset; 156 157 /** 158 * These provide time bases that discount the time the device is plugged 159 * in to power. 160 */ 161 boolean mOnBattery; 162 boolean mOnBatteryInternal; 163 long mTrackBatteryPastUptime; 164 long mTrackBatteryUptimeStart; 165 long mTrackBatteryPastRealtime; 166 long mTrackBatteryRealtimeStart; 167 168 long mUnpluggedBatteryUptime; 169 long mUnpluggedBatteryRealtime; 170 171 /* 172 * These keep track of battery levels (1-100) at the last plug event and the last unplug event. 173 */ 174 int mDischargeStartLevel; 175 int mDischargeCurrentLevel; 176 177 long mLastWriteTime = 0; // Milliseconds 178 179 // Mobile data transferred while on battery 180 private long[] mMobileDataTx = new long[4]; 181 private long[] mMobileDataRx = new long[4]; 182 private long[] mTotalDataTx = new long[4]; 183 private long[] mTotalDataRx = new long[4]; 184 185 private long mRadioDataUptime; 186 private long mRadioDataStart; 187 188 private int mBluetoothPingCount; 189 private int mBluetoothPingStart = -1; 190 191 private int mPhoneServiceState = -1; 192 193 /* 194 * Holds a SamplingTimer associated with each kernel wakelock name being tracked. 195 */ 196 private final HashMap<String, SamplingTimer> mKernelWakelockStats = 197 new HashMap<String, SamplingTimer>(); 198 199 public Map<String, ? extends SamplingTimer> getKernelWakelockStats() { 200 return mKernelWakelockStats; 201 } 202 203 private static int sKernelWakelockUpdateVersion = 0; 204 205 private static final int[] PROC_WAKELOCKS_FORMAT = new int[] { 206 Process.PROC_TAB_TERM|Process.PROC_OUT_STRING, // 0: name 207 Process.PROC_TAB_TERM|Process.PROC_OUT_LONG, // 1: count 208 Process.PROC_TAB_TERM, 209 Process.PROC_TAB_TERM, 210 Process.PROC_TAB_TERM, 211 Process.PROC_TAB_TERM|Process.PROC_OUT_LONG, // 5: totalTime 212 }; 213 214 private final String[] mProcWakelocksName = new String[3]; 215 private final long[] mProcWakelocksData = new long[3]; 216 217 /* 218 * Used as a buffer for reading in data from /proc/wakelocks before it is processed and added 219 * to mKernelWakelockStats. 220 */ 221 private final Map<String, KernelWakelockStats> mProcWakelockFileStats = 222 new HashMap<String, KernelWakelockStats>(); 223 224 private HashMap<String, Integer> mUidCache = new HashMap<String, Integer>(); 225 226 // For debugging 227 public BatteryStatsImpl() { 228 mFile = null; 229 } 230 231 public static interface Unpluggable { 232 void unplug(long batteryUptime, long batteryRealtime); 233 void plug(long batteryUptime, long batteryRealtime); 234 } 235 236 /** 237 * State for keeping track of counting information. 238 */ 239 public static class Counter extends BatteryStats.Counter implements Unpluggable { 240 final AtomicInteger mCount = new AtomicInteger(); 241 int mLoadedCount; 242 int mLastCount; 243 int mUnpluggedCount; 244 int mPluggedCount; 245 246 Counter(ArrayList<Unpluggable> unpluggables, Parcel in) { 247 mPluggedCount = in.readInt(); 248 mCount.set(mPluggedCount); 249 mLoadedCount = in.readInt(); 250 mLastCount = in.readInt(); 251 mUnpluggedCount = in.readInt(); 252 unpluggables.add(this); 253 } 254 255 Counter(ArrayList<Unpluggable> unpluggables) { 256 unpluggables.add(this); 257 } 258 259 public void writeToParcel(Parcel out) { 260 out.writeInt(mCount.get()); 261 out.writeInt(mLoadedCount); 262 out.writeInt(mLastCount); 263 out.writeInt(mUnpluggedCount); 264 } 265 266 public void unplug(long batteryUptime, long batteryRealtime) { 267 mUnpluggedCount = mPluggedCount; 268 mCount.set(mPluggedCount); 269 } 270 271 public void plug(long batteryUptime, long batteryRealtime) { 272 mPluggedCount = mCount.get(); 273 } 274 275 /** 276 * Writes a possibly null Counter to a Parcel. 277 * 278 * @param out the Parcel to be written to. 279 * @param counter a Counter, or null. 280 */ 281 public static void writeCounterToParcel(Parcel out, Counter counter) { 282 if (counter == null) { 283 out.writeInt(0); // indicates null 284 return; 285 } 286 out.writeInt(1); // indicates non-null 287 288 counter.writeToParcel(out); 289 } 290 291 @Override 292 public int getCountLocked(int which) { 293 int val; 294 if (which == STATS_LAST) { 295 val = mLastCount; 296 } else { 297 val = mCount.get(); 298 if (which == STATS_UNPLUGGED) { 299 val -= mUnpluggedCount; 300 } else if (which != STATS_TOTAL) { 301 val -= mLoadedCount; 302 } 303 } 304 305 return val; 306 } 307 308 public void logState(Printer pw, String prefix) { 309 pw.println(prefix + "mCount=" + mCount.get() 310 + " mLoadedCount=" + mLoadedCount + " mLastCount=" + mLastCount 311 + " mUnpluggedCount=" + mUnpluggedCount 312 + " mPluggedCount=" + mPluggedCount); 313 } 314 315 void stepAtomic() { 316 mCount.incrementAndGet(); 317 } 318 319 void writeSummaryFromParcelLocked(Parcel out) { 320 int count = mCount.get(); 321 out.writeInt(count); 322 out.writeInt(count - mLoadedCount); 323 } 324 325 void readSummaryFromParcelLocked(Parcel in) { 326 mLoadedCount = in.readInt(); 327 mCount.set(mLoadedCount); 328 mLastCount = in.readInt(); 329 mUnpluggedCount = mPluggedCount = mLoadedCount; 330 } 331 } 332 333 public static class SamplingCounter extends Counter { 334 335 SamplingCounter(ArrayList<Unpluggable> unpluggables, Parcel in) { 336 super(unpluggables, in); 337 } 338 339 SamplingCounter(ArrayList<Unpluggable> unpluggables) { 340 super(unpluggables); 341 } 342 343 public void addCountAtomic(long count) { 344 mCount.addAndGet((int)count); 345 } 346 } 347 348 /** 349 * State for keeping track of timing information. 350 */ 351 public static abstract class Timer extends BatteryStats.Timer implements Unpluggable { 352 final int mType; 353 354 355 int mCount; 356 int mLoadedCount; 357 int mLastCount; 358 int mUnpluggedCount; 359 360 // Times are in microseconds for better accuracy when dividing by the 361 // lock count, and are in "battery realtime" units. 362 363 /** 364 * The total time we have accumulated since the start of the original 365 * boot, to the last time something interesting happened in the 366 * current run. 367 */ 368 long mTotalTime; 369 370 /** 371 * The total time we loaded for the previous runs. Subtract this from 372 * mTotalTime to find the time for the current run of the system. 373 */ 374 long mLoadedTime; 375 376 /** 377 * The run time of the last run of the system, as loaded from the 378 * saved data. 379 */ 380 long mLastTime; 381 382 /** 383 * The value of mTotalTime when unplug() was last called. Subtract 384 * this from mTotalTime to find the time since the last unplug from 385 * power. 386 */ 387 long mUnpluggedTime; 388 389 /** 390 * Constructs from a parcel. 391 * @param type 392 * @param unpluggables 393 * @param powerType 394 * @param in 395 */ 396 Timer(int type, ArrayList<Unpluggable> unpluggables, Parcel in) { 397 mType = type; 398 399 mCount = in.readInt(); 400 mLoadedCount = in.readInt(); 401 mLastCount = in.readInt(); 402 mUnpluggedCount = in.readInt(); 403 mTotalTime = in.readLong(); 404 mLoadedTime = in.readLong(); 405 mLastTime = in.readLong(); 406 mUnpluggedTime = in.readLong(); 407 unpluggables.add(this); 408 } 409 410 Timer(int type, ArrayList<Unpluggable> unpluggables) { 411 mType = type; 412 unpluggables.add(this); 413 } 414 415 protected abstract long computeRunTimeLocked(long curBatteryRealtime); 416 417 protected abstract int computeCurrentCountLocked(); 418 419 420 public void writeToParcel(Parcel out, long batteryRealtime) { 421 out.writeInt(mCount); 422 out.writeInt(mLoadedCount); 423 out.writeInt(mLastCount); 424 out.writeInt(mUnpluggedCount); 425 out.writeLong(computeRunTimeLocked(batteryRealtime)); 426 out.writeLong(mLoadedTime); 427 out.writeLong(mLastTime); 428 out.writeLong(mUnpluggedTime); 429 } 430 431 public void unplug(long batteryUptime, long batteryRealtime) { 432 if (DEBUG && mType < 0) { 433 Log.v(TAG, "unplug #" + mType + ": realtime=" + batteryRealtime 434 + " old mUnpluggedTime=" + mUnpluggedTime 435 + " old mUnpluggedCount=" + mUnpluggedCount); 436 } 437 mUnpluggedTime = computeRunTimeLocked(batteryRealtime); 438 mUnpluggedCount = mCount; 439 if (DEBUG && mType < 0) { 440 Log.v(TAG, "unplug #" + mType 441 + ": new mUnpluggedTime=" + mUnpluggedTime 442 + " new mUnpluggedCount=" + mUnpluggedCount); 443 } 444 } 445 446 public void plug(long batteryUptime, long batteryRealtime) { 447 if (DEBUG && mType < 0) { 448 Log.v(TAG, "plug #" + mType + ": realtime=" + batteryRealtime 449 + " old mTotalTime=" + mTotalTime); 450 } 451 mTotalTime = computeRunTimeLocked(batteryRealtime); 452 mCount = computeCurrentCountLocked(); 453 if (DEBUG && mType < 0) { 454 Log.v(TAG, "plug #" + mType 455 + ": new mTotalTime=" + mTotalTime); 456 } 457 } 458 459 /** 460 * Writes a possibly null Timer to a Parcel. 461 * 462 * @param out the Parcel to be written to. 463 * @param timer a Timer, or null. 464 */ 465 public static void writeTimerToParcel(Parcel out, Timer timer, 466 long batteryRealtime) { 467 if (timer == null) { 468 out.writeInt(0); // indicates null 469 return; 470 } 471 out.writeInt(1); // indicates non-null 472 473 timer.writeToParcel(out, batteryRealtime); 474 } 475 476 @Override 477 public long getTotalTimeLocked(long batteryRealtime, int which) { 478 long val; 479 if (which == STATS_LAST) { 480 val = mLastTime; 481 } else { 482 val = computeRunTimeLocked(batteryRealtime); 483 if (which == STATS_UNPLUGGED) { 484 val -= mUnpluggedTime; 485 } else if (which != STATS_TOTAL) { 486 val -= mLoadedTime; 487 } 488 } 489 490 return val; 491 } 492 493 @Override 494 public int getCountLocked(int which) { 495 int val; 496 if (which == STATS_LAST) { 497 val = mLastCount; 498 } else { 499 val = computeCurrentCountLocked(); 500 if (which == STATS_UNPLUGGED) { 501 val -= mUnpluggedCount; 502 } else if (which != STATS_TOTAL) { 503 val -= mLoadedCount; 504 } 505 } 506 507 return val; 508 } 509 510 public void logState(Printer pw, String prefix) { 511 pw.println(prefix + " mCount=" + mCount 512 + " mLoadedCount=" + mLoadedCount + " mLastCount=" + mLastCount 513 + " mUnpluggedCount=" + mUnpluggedCount); 514 pw.println(prefix + "mTotalTime=" + mTotalTime 515 + " mLoadedTime=" + mLoadedTime); 516 pw.println(prefix + "mLastTime=" + mLastTime 517 + " mUnpluggedTime=" + mUnpluggedTime); 518 } 519 520 521 void writeSummaryFromParcelLocked(Parcel out, long batteryRealtime) { 522 long runTime = computeRunTimeLocked(batteryRealtime); 523 // Divide by 1000 for backwards compatibility 524 out.writeLong((runTime + 500) / 1000); 525 out.writeLong(((runTime - mLoadedTime) + 500) / 1000); 526 out.writeInt(mCount); 527 out.writeInt(mCount - mLoadedCount); 528 } 529 530 void readSummaryFromParcelLocked(Parcel in) { 531 // Multiply by 1000 for backwards compatibility 532 mTotalTime = mLoadedTime = in.readLong() * 1000; 533 mLastTime = in.readLong() * 1000; 534 mUnpluggedTime = mTotalTime; 535 mCount = mLoadedCount = in.readInt(); 536 mLastCount = in.readInt(); 537 mUnpluggedCount = mCount; 538 } 539 } 540 541 public static final class SamplingTimer extends Timer { 542 543 /** 544 * The most recent reported count from /proc/wakelocks. 545 */ 546 int mCurrentReportedCount; 547 548 /** 549 * The reported count from /proc/wakelocks when unplug() was last 550 * called. 551 */ 552 int mUnpluggedReportedCount; 553 554 /** 555 * The most recent reported total_time from /proc/wakelocks. 556 */ 557 long mCurrentReportedTotalTime; 558 559 560 /** 561 * The reported total_time from /proc/wakelocks when unplug() was last 562 * called. 563 */ 564 long mUnpluggedReportedTotalTime; 565 566 /** 567 * Whether we are currently in a discharge cycle. 568 */ 569 boolean mInDischarge; 570 571 /** 572 * Whether we are currently recording reported values. 573 */ 574 boolean mTrackingReportedValues; 575 576 /* 577 * A sequnce counter, incremented once for each update of the stats. 578 */ 579 int mUpdateVersion; 580 581 SamplingTimer(ArrayList<Unpluggable> unpluggables, boolean inDischarge, Parcel in) { 582 super(0, unpluggables, in); 583 mCurrentReportedCount = in.readInt(); 584 mUnpluggedReportedCount = in.readInt(); 585 mCurrentReportedTotalTime = in.readLong(); 586 mUnpluggedReportedTotalTime = in.readLong(); 587 mTrackingReportedValues = in.readInt() == 1; 588 mInDischarge = inDischarge; 589 } 590 591 SamplingTimer(ArrayList<Unpluggable> unpluggables, boolean inDischarge, 592 boolean trackReportedValues) { 593 super(0, unpluggables); 594 mTrackingReportedValues = trackReportedValues; 595 mInDischarge = inDischarge; 596 } 597 598 public void setStale() { 599 mTrackingReportedValues = false; 600 mUnpluggedReportedTotalTime = 0; 601 mUnpluggedReportedCount = 0; 602 } 603 604 public void setUpdateVersion(int version) { 605 mUpdateVersion = version; 606 } 607 608 public int getUpdateVersion() { 609 return mUpdateVersion; 610 } 611 612 public void updateCurrentReportedCount(int count) { 613 if (mInDischarge && mUnpluggedReportedCount == 0) { 614 // Updating the reported value for the first time. 615 mUnpluggedReportedCount = count; 616 // If we are receiving an update update mTrackingReportedValues; 617 mTrackingReportedValues = true; 618 } 619 mCurrentReportedCount = count; 620 } 621 622 public void updateCurrentReportedTotalTime(long totalTime) { 623 if (mInDischarge && mUnpluggedReportedTotalTime == 0) { 624 // Updating the reported value for the first time. 625 mUnpluggedReportedTotalTime = totalTime; 626 // If we are receiving an update update mTrackingReportedValues; 627 mTrackingReportedValues = true; 628 } 629 mCurrentReportedTotalTime = totalTime; 630 } 631 632 public void unplug(long batteryUptime, long batteryRealtime) { 633 super.unplug(batteryUptime, batteryRealtime); 634 if (mTrackingReportedValues) { 635 mUnpluggedReportedTotalTime = mCurrentReportedTotalTime; 636 mUnpluggedReportedCount = mCurrentReportedCount; 637 } 638 mInDischarge = true; 639 } 640 641 public void plug(long batteryUptime, long batteryRealtime) { 642 super.plug(batteryUptime, batteryRealtime); 643 mInDischarge = false; 644 } 645 646 public void logState(Printer pw, String prefix) { 647 super.logState(pw, prefix); 648 pw.println(prefix + "mCurrentReportedCount=" + mCurrentReportedCount 649 + " mUnpluggedReportedCount=" + mUnpluggedReportedCount 650 + " mCurrentReportedTotalTime=" + mCurrentReportedTotalTime 651 + " mUnpluggedReportedTotalTime=" + mUnpluggedReportedTotalTime); 652 } 653 654 protected long computeRunTimeLocked(long curBatteryRealtime) { 655 return mTotalTime + (mInDischarge && mTrackingReportedValues 656 ? mCurrentReportedTotalTime - mUnpluggedReportedTotalTime : 0); 657 } 658 659 protected int computeCurrentCountLocked() { 660 return mCount + (mInDischarge && mTrackingReportedValues 661 ? mCurrentReportedCount - mUnpluggedReportedCount : 0); 662 } 663 664 public void writeToParcel(Parcel out, long batteryRealtime) { 665 super.writeToParcel(out, batteryRealtime); 666 out.writeInt(mCurrentReportedCount); 667 out.writeInt(mUnpluggedReportedCount); 668 out.writeLong(mCurrentReportedTotalTime); 669 out.writeLong(mUnpluggedReportedTotalTime); 670 out.writeInt(mTrackingReportedValues ? 1 : 0); 671 } 672 673 void writeSummaryFromParcelLocked(Parcel out, long batteryRealtime) { 674 super.writeSummaryFromParcelLocked(out, batteryRealtime); 675 out.writeLong(mCurrentReportedTotalTime); 676 out.writeInt(mCurrentReportedCount); 677 out.writeInt(mTrackingReportedValues ? 1 : 0); 678 } 679 680 void readSummaryFromParcelLocked(Parcel in) { 681 super.readSummaryFromParcelLocked(in); 682 mUnpluggedReportedTotalTime = mCurrentReportedTotalTime = in.readLong(); 683 mUnpluggedReportedCount = mCurrentReportedCount = in.readInt(); 684 mTrackingReportedValues = in.readInt() == 1; 685 } 686 } 687 688 /** 689 * State for keeping track of timing information. 690 */ 691 public static final class StopwatchTimer extends Timer { 692 final ArrayList<StopwatchTimer> mTimerPool; 693 int mNesting; 694 695 696 /** 697 * The last time at which we updated the timer. If mNesting is > 0, 698 * subtract this from the current battery time to find the amount of 699 * time we have been running since we last computed an update. 700 */ 701 long mUpdateTime; 702 703 /** 704 * The total time at which the timer was acquired, to determine if 705 * was actually held for an interesting duration. 706 */ 707 long mAcquireTime; 708 709 long mTimeout; 710 711 StopwatchTimer(int type, ArrayList<StopwatchTimer> timerPool, 712 ArrayList<Unpluggable> unpluggables, Parcel in) { 713 super(type, unpluggables, in); 714 mTimerPool = timerPool; 715 mUpdateTime = in.readLong(); 716 } 717 718 StopwatchTimer(int type, ArrayList<StopwatchTimer> timerPool, 719 ArrayList<Unpluggable> unpluggables) { 720 super(type, unpluggables); 721 mTimerPool = timerPool; 722 } 723 724 void setTimeout(long timeout) { 725 mTimeout = timeout; 726 } 727 728 public void writeToParcel(Parcel out, long batteryRealtime) { 729 super.writeToParcel(out, batteryRealtime); 730 out.writeLong(mUpdateTime); 731 } 732 733 public void plug(long batteryUptime, long batteryRealtime) { 734 if (mNesting > 0) { 735 if (DEBUG && mType < 0) { 736 Log.v(TAG, "old mUpdateTime=" + mUpdateTime); 737 } 738 super.plug(batteryUptime, batteryRealtime); 739 mUpdateTime = batteryRealtime; 740 if (DEBUG && mType < 0) { 741 Log.v(TAG, "new mUpdateTime=" + mUpdateTime); 742 } 743 } 744 } 745 746 public void logState(Printer pw, String prefix) { 747 super.logState(pw, prefix); 748 pw.println(prefix + "mNesting=" + mNesting + "mUpdateTime=" + mUpdateTime 749 + " mAcquireTime=" + mAcquireTime); 750 } 751 752 void startRunningLocked(BatteryStatsImpl stats) { 753 if (mNesting++ == 0) { 754 mUpdateTime = stats.getBatteryRealtimeLocked( 755 SystemClock.elapsedRealtime() * 1000); 756 if (mTimerPool != null) { 757 // Accumulate time to all currently active timers before adding 758 // this new one to the pool. 759 refreshTimersLocked(stats, mTimerPool); 760 // Add this timer to the active pool 761 mTimerPool.add(this); 762 } 763 // Increment the count 764 mCount++; 765 mAcquireTime = mTotalTime; 766 if (DEBUG && mType < 0) { 767 Log.v(TAG, "start #" + mType + ": mUpdateTime=" + mUpdateTime 768 + " mTotalTime=" + mTotalTime + " mCount=" + mCount 769 + " mAcquireTime=" + mAcquireTime); 770 } 771 } 772 } 773 774 boolean isRunningLocked() { 775 return mNesting > 0; 776 } 777 778 void stopRunningLocked(BatteryStatsImpl stats) { 779 // Ignore attempt to stop a timer that isn't running 780 if (mNesting == 0) { 781 return; 782 } 783 if (--mNesting == 0) { 784 if (mTimerPool != null) { 785 // Accumulate time to all active counters, scaled by the total 786 // active in the pool, before taking this one out of the pool. 787 refreshTimersLocked(stats, mTimerPool); 788 // Remove this timer from the active pool 789 mTimerPool.remove(this); 790 } else { 791 final long realtime = SystemClock.elapsedRealtime() * 1000; 792 final long batteryRealtime = stats.getBatteryRealtimeLocked(realtime); 793 mNesting = 1; 794 mTotalTime = computeRunTimeLocked(batteryRealtime); 795 mNesting = 0; 796 } 797 798 if (DEBUG && mType < 0) { 799 Log.v(TAG, "stop #" + mType + ": mUpdateTime=" + mUpdateTime 800 + " mTotalTime=" + mTotalTime + " mCount=" + mCount 801 + " mAcquireTime=" + mAcquireTime); 802 } 803 804 if (mTotalTime == mAcquireTime) { 805 // If there was no change in the time, then discard this 806 // count. A somewhat cheezy strategy, but hey. 807 mCount--; 808 } 809 } 810 } 811 812 // Update the total time for all other running Timers with the same type as this Timer 813 // due to a change in timer count 814 private static void refreshTimersLocked(final BatteryStatsImpl stats, 815 final ArrayList<StopwatchTimer> pool) { 816 final long realtime = SystemClock.elapsedRealtime() * 1000; 817 final long batteryRealtime = stats.getBatteryRealtimeLocked(realtime); 818 final int N = pool.size(); 819 for (int i=N-1; i>= 0; i--) { 820 final StopwatchTimer t = pool.get(i); 821 long heldTime = batteryRealtime - t.mUpdateTime; 822 if (heldTime > 0) { 823 t.mTotalTime += heldTime / N; 824 } 825 t.mUpdateTime = batteryRealtime; 826 } 827 } 828 829 @Override 830 protected long computeRunTimeLocked(long curBatteryRealtime) { 831 if (mTimeout > 0 && curBatteryRealtime > mUpdateTime + mTimeout) { 832 curBatteryRealtime = mUpdateTime + mTimeout; 833 } 834 return mTotalTime + (mNesting > 0 835 ? (curBatteryRealtime - mUpdateTime) 836 / (mTimerPool != null ? mTimerPool.size() : 1) 837 : 0); 838 } 839 840 @Override 841 protected int computeCurrentCountLocked() { 842 return mCount; 843 } 844 845 void readSummaryFromParcelLocked(Parcel in) { 846 super.readSummaryFromParcelLocked(in); 847 mNesting = 0; 848 } 849 } 850 851 private final Map<String, KernelWakelockStats> readKernelWakelockStats() { 852 853 byte[] buffer = new byte[4096]; 854 int len; 855 856 try { 857 FileInputStream is = new FileInputStream("/proc/wakelocks"); 858 len = is.read(buffer); 859 is.close(); 860 861 if (len > 0) { 862 int i; 863 for (i=0; i<len; i++) { 864 if (buffer[i] == '\0') { 865 len = i; 866 break; 867 } 868 } 869 } 870 } catch (java.io.FileNotFoundException e) { 871 return null; 872 } catch (java.io.IOException e) { 873 return null; 874 } 875 876 return parseProcWakelocks(buffer, len); 877 } 878 879 private final Map<String, KernelWakelockStats> parseProcWakelocks( 880 byte[] wlBuffer, int len) { 881 String name; 882 int count; 883 long totalTime; 884 int startIndex, endIndex; 885 int numUpdatedWlNames = 0; 886 887 // Advance past the first line. 888 int i; 889 for (i = 0; i < len && wlBuffer[i] != '\n' && wlBuffer[i] != '\0'; i++); 890 startIndex = endIndex = i + 1; 891 892 synchronized(this) { 893 Map<String, KernelWakelockStats> m = mProcWakelockFileStats; 894 895 sKernelWakelockUpdateVersion++; 896 while (endIndex < len) { 897 for (endIndex=startIndex; 898 endIndex < len && wlBuffer[endIndex] != '\n' && wlBuffer[endIndex] != '\0'; 899 endIndex++); 900 // Don't go over the end of the buffer 901 if (endIndex < len) { 902 endIndex++; // endIndex is an exclusive upper bound. 903 } 904 905 String[] nameStringArray = mProcWakelocksName; 906 long[] wlData = mProcWakelocksData; 907 // Stomp out any bad characters since this is from a circular buffer 908 // A corruption is seen sometimes that results in the vm crashing 909 // This should prevent crashes and the line will probably fail to parse 910 for (int j = startIndex; j < endIndex; j++) { 911 if ((wlBuffer[j] & 0x80) != 0) wlBuffer[j] = (byte) '?'; 912 } 913 boolean parsed = Process.parseProcLine(wlBuffer, startIndex, endIndex, 914 PROC_WAKELOCKS_FORMAT, nameStringArray, wlData, null); 915 916 name = nameStringArray[0]; 917 count = (int) wlData[1]; 918 // convert nanoseconds to microseconds with rounding. 919 totalTime = (wlData[2] + 500) / 1000; 920 921 if (parsed && name.length() > 0) { 922 if (!m.containsKey(name)) { 923 m.put(name, new KernelWakelockStats(count, totalTime, 924 sKernelWakelockUpdateVersion)); 925 numUpdatedWlNames++; 926 } else { 927 KernelWakelockStats kwlStats = m.get(name); 928 if (kwlStats.mVersion == sKernelWakelockUpdateVersion) { 929 kwlStats.mCount += count; 930 kwlStats.mTotalTime += totalTime; 931 } else { 932 kwlStats.mCount = count; 933 kwlStats.mTotalTime = totalTime; 934 kwlStats.mVersion = sKernelWakelockUpdateVersion; 935 numUpdatedWlNames++; 936 } 937 } 938 } 939 startIndex = endIndex; 940 } 941 942 if (m.size() != numUpdatedWlNames) { 943 // Don't report old data. 944 Iterator<KernelWakelockStats> itr = m.values().iterator(); 945 while (itr.hasNext()) { 946 if (itr.next().mVersion != sKernelWakelockUpdateVersion) { 947 itr.remove(); 948 } 949 } 950 } 951 return m; 952 } 953 } 954 955 private class KernelWakelockStats { 956 public int mCount; 957 public long mTotalTime; 958 public int mVersion; 959 960 KernelWakelockStats(int count, long totalTime, int version) { 961 mCount = count; 962 mTotalTime = totalTime; 963 mVersion = version; 964 } 965 } 966 967 /* 968 * Get the KernelWakelockTimer associated with name, and create a new one if one 969 * doesn't already exist. 970 */ 971 public SamplingTimer getKernelWakelockTimerLocked(String name) { 972 SamplingTimer kwlt = mKernelWakelockStats.get(name); 973 if (kwlt == null) { 974 kwlt = new SamplingTimer(mUnpluggables, mOnBatteryInternal, 975 true /* track reported values */); 976 mKernelWakelockStats.put(name, kwlt); 977 } 978 return kwlt; 979 } 980 981 private void doDataPlug(long[] dataTransfer, long currentBytes) { 982 dataTransfer[STATS_LAST] = dataTransfer[STATS_UNPLUGGED]; 983 dataTransfer[STATS_UNPLUGGED] = -1; 984 } 985 986 private void doDataUnplug(long[] dataTransfer, long currentBytes) { 987 dataTransfer[STATS_UNPLUGGED] = currentBytes; 988 } 989 990 /** 991 * Radio uptime in microseconds when transferring data. This value is very approximate. 992 * @return 993 */ 994 private long getCurrentRadioDataUptime() { 995 try { 996 File awakeTimeFile = new File("/sys/devices/virtual/net/rmnet0/awake_time_ms"); 997 if (!awakeTimeFile.exists()) return 0; 998 BufferedReader br = new BufferedReader(new FileReader(awakeTimeFile)); 999 String line = br.readLine(); 1000 br.close(); 1001 return Long.parseLong(line) * 1000; 1002 } catch (NumberFormatException nfe) { 1003 // Nothing 1004 } catch (IOException ioe) { 1005 // Nothing 1006 } 1007 return 0; 1008 } 1009 1010 /** 1011 * @deprecated use getRadioDataUptime 1012 */ 1013 public long getRadioDataUptimeMs() { 1014 return getRadioDataUptime() / 1000; 1015 } 1016 1017 /** 1018 * Returns the duration that the cell radio was up for data transfers. 1019 */ 1020 public long getRadioDataUptime() { 1021 if (mRadioDataStart == -1) { 1022 return mRadioDataUptime; 1023 } else { 1024 return getCurrentRadioDataUptime() - mRadioDataStart; 1025 } 1026 } 1027 1028 private int getCurrentBluetoothPingCount() { 1029 if (mBtHeadset != null) { 1030 return mBtHeadset.getBatteryUsageHint(); 1031 } 1032 return -1; 1033 } 1034 1035 public int getBluetoothPingCount() { 1036 if (mBluetoothPingStart == -1) { 1037 return mBluetoothPingCount; 1038 } else if (mBtHeadset != null) { 1039 return getCurrentBluetoothPingCount() - mBluetoothPingStart; 1040 } 1041 return 0; 1042 } 1043 1044 public void setBtHeadset(BluetoothHeadset headset) { 1045 if (headset != null && mBtHeadset == null && isOnBattery() && mBluetoothPingStart == -1) { 1046 mBluetoothPingStart = getCurrentBluetoothPingCount(); 1047 } 1048 mBtHeadset = headset; 1049 } 1050 1051 void addHistoryRecord(long curTime) { 1052 BatteryHistoryRecord rec = mHistoryCache; 1053 if (rec != null) { 1054 mHistoryCache = rec.next; 1055 } else { 1056 rec = new BatteryHistoryRecord(); 1057 } 1058 rec.time = curTime; 1059 rec.batteryLevel = mHistoryCur.batteryLevel; 1060 rec.states = mHistoryCur.states; 1061 addHistoryRecord(rec); 1062 } 1063 1064 void addHistoryRecord(BatteryHistoryRecord rec) { 1065 rec.next = null; 1066 if (mHistoryEnd != null) { 1067 mHistoryEnd.next = rec; 1068 mHistoryEnd = rec; 1069 } else { 1070 mHistory = mHistoryEnd = rec; 1071 } 1072 } 1073 1074 void clearHistory() { 1075 if (mHistory != null) { 1076 mHistoryEnd.next = mHistoryCache; 1077 mHistoryCache = mHistory; 1078 mHistory = mHistoryEnd = null; 1079 } 1080 } 1081 1082 public void doUnplug(long batteryUptime, long batteryRealtime) { 1083 for (int iu = mUidStats.size() - 1; iu >= 0; iu--) { 1084 Uid u = mUidStats.valueAt(iu); 1085 u.mStartedTcpBytesReceived = TrafficStats.getUidRxBytes(u.mUid); 1086 u.mStartedTcpBytesSent = TrafficStats.getUidTxBytes(u.mUid); 1087 u.mTcpBytesReceivedAtLastUnplug = u.mCurrentTcpBytesReceived; 1088 u.mTcpBytesSentAtLastUnplug = u.mCurrentTcpBytesSent; 1089 } 1090 for (int i = mUnpluggables.size() - 1; i >= 0; i--) { 1091 mUnpluggables.get(i).unplug(batteryUptime, batteryRealtime); 1092 } 1093 // Track total mobile data 1094 doDataUnplug(mMobileDataRx, TrafficStats.getMobileRxBytes()); 1095 doDataUnplug(mMobileDataTx, TrafficStats.getMobileTxBytes()); 1096 doDataUnplug(mTotalDataRx, TrafficStats.getTotalRxBytes()); 1097 doDataUnplug(mTotalDataTx, TrafficStats.getTotalTxBytes()); 1098 // Track radio awake time 1099 mRadioDataStart = getCurrentRadioDataUptime(); 1100 mRadioDataUptime = 0; 1101 // Track bt headset ping count 1102 mBluetoothPingStart = getCurrentBluetoothPingCount(); 1103 mBluetoothPingCount = 0; 1104 } 1105 1106 public void doPlug(long batteryUptime, long batteryRealtime) { 1107 for (int iu = mUidStats.size() - 1; iu >= 0; iu--) { 1108 Uid u = mUidStats.valueAt(iu); 1109 if (u.mStartedTcpBytesReceived >= 0) { 1110 u.mCurrentTcpBytesReceived = u.computeCurrentTcpBytesReceived(); 1111 u.mStartedTcpBytesReceived = -1; 1112 } 1113 if (u.mStartedTcpBytesSent >= 0) { 1114 u.mCurrentTcpBytesSent = u.computeCurrentTcpBytesSent(); 1115 u.mStartedTcpBytesSent = -1; 1116 } 1117 } 1118 for (int i = mUnpluggables.size() - 1; i >= 0; i--) { 1119 mUnpluggables.get(i).plug(batteryUptime, batteryRealtime); 1120 } 1121 doDataPlug(mMobileDataRx, TrafficStats.getMobileRxBytes()); 1122 doDataPlug(mMobileDataTx, TrafficStats.getMobileTxBytes()); 1123 doDataPlug(mTotalDataRx, TrafficStats.getTotalRxBytes()); 1124 doDataPlug(mTotalDataTx, TrafficStats.getTotalTxBytes()); 1125 // Track radio awake time 1126 mRadioDataUptime = getRadioDataUptime(); 1127 mRadioDataStart = -1; 1128 1129 // Track bt headset ping count 1130 mBluetoothPingCount = getBluetoothPingCount(); 1131 mBluetoothPingStart = -1; 1132 } 1133 1134 int mGpsNesting; 1135 1136 public void noteStartGps(int uid) { 1137 if (mGpsNesting == 0) { 1138 mHistoryCur.states |= BatteryHistoryRecord.STATE_GPS_ON_FLAG; 1139 if (DEBUG_HISTORY) Slog.v(TAG, "Start GPS to: " 1140 + Integer.toHexString(mHistoryCur.states)); 1141 addHistoryRecord(SystemClock.elapsedRealtime()); 1142 } 1143 mGpsNesting++; 1144 getUidStatsLocked(uid).noteStartGps(); 1145 } 1146 1147 public void noteStopGps(int uid) { 1148 mGpsNesting--; 1149 if (mGpsNesting == 0) { 1150 mHistoryCur.states &= ~BatteryHistoryRecord.STATE_GPS_ON_FLAG; 1151 if (DEBUG_HISTORY) Slog.v(TAG, "Stop GPS to: " 1152 + Integer.toHexString(mHistoryCur.states)); 1153 addHistoryRecord(SystemClock.elapsedRealtime()); 1154 } 1155 getUidStatsLocked(uid).noteStopGps(); 1156 } 1157 1158 public void noteScreenOnLocked() { 1159 if (!mScreenOn) { 1160 mHistoryCur.states |= BatteryHistoryRecord.STATE_SCREEN_ON_FLAG; 1161 if (DEBUG_HISTORY) Slog.v(TAG, "Screen on to: " 1162 + Integer.toHexString(mHistoryCur.states)); 1163 addHistoryRecord(SystemClock.elapsedRealtime()); 1164 mGpsNesting++; 1165 mScreenOn = true; 1166 mScreenOnTimer.startRunningLocked(this); 1167 if (mScreenBrightnessBin >= 0) { 1168 mScreenBrightnessTimer[mScreenBrightnessBin].startRunningLocked(this); 1169 } 1170 } 1171 } 1172 1173 public void noteScreenOffLocked() { 1174 if (mScreenOn) { 1175 mHistoryCur.states &= ~BatteryHistoryRecord.STATE_SCREEN_ON_FLAG; 1176 if (DEBUG_HISTORY) Slog.v(TAG, "Screen off to: " 1177 + Integer.toHexString(mHistoryCur.states)); 1178 addHistoryRecord(SystemClock.elapsedRealtime()); 1179 mScreenOn = false; 1180 mScreenOnTimer.stopRunningLocked(this); 1181 if (mScreenBrightnessBin >= 0) { 1182 mScreenBrightnessTimer[mScreenBrightnessBin].stopRunningLocked(this); 1183 } 1184 } 1185 } 1186 1187 public void noteScreenBrightnessLocked(int brightness) { 1188 // Bin the brightness. 1189 int bin = brightness / (256/NUM_SCREEN_BRIGHTNESS_BINS); 1190 if (bin < 0) bin = 0; 1191 else if (bin >= NUM_SCREEN_BRIGHTNESS_BINS) bin = NUM_SCREEN_BRIGHTNESS_BINS-1; 1192 if (mScreenBrightnessBin != bin) { 1193 mHistoryCur.states = (mHistoryCur.states&~BatteryHistoryRecord.STATE_SCREEN_MASK) 1194 | (bin << BatteryHistoryRecord.STATE_SCREEN_SHIFT); 1195 if (DEBUG_HISTORY) Slog.v(TAG, "Screen brightness " + bin + " to: " 1196 + Integer.toHexString(mHistoryCur.states)); 1197 addHistoryRecord(SystemClock.elapsedRealtime()); 1198 if (mScreenOn) { 1199 if (mScreenBrightnessBin >= 0) { 1200 mScreenBrightnessTimer[mScreenBrightnessBin].stopRunningLocked(this); 1201 } 1202 mScreenBrightnessTimer[bin].startRunningLocked(this); 1203 } 1204 mScreenBrightnessBin = bin; 1205 } 1206 } 1207 1208 public void noteInputEventAtomic() { 1209 mInputEventCounter.stepAtomic(); 1210 } 1211 1212 public void noteUserActivityLocked(int uid, int event) { 1213 getUidStatsLocked(uid).noteUserActivityLocked(event); 1214 } 1215 1216 public void notePhoneOnLocked() { 1217 if (!mPhoneOn) { 1218 mHistoryCur.states |= BatteryHistoryRecord.STATE_PHONE_ON_FLAG; 1219 if (DEBUG_HISTORY) Slog.v(TAG, "Phone on to: " 1220 + Integer.toHexString(mHistoryCur.states)); 1221 addHistoryRecord(SystemClock.elapsedRealtime()); 1222 mPhoneOn = true; 1223 mPhoneOnTimer.startRunningLocked(this); 1224 } 1225 } 1226 1227 public void notePhoneOffLocked() { 1228 if (mPhoneOn) { 1229 mHistoryCur.states &= ~BatteryHistoryRecord.STATE_PHONE_ON_FLAG; 1230 if (DEBUG_HISTORY) Slog.v(TAG, "Phone off to: " 1231 + Integer.toHexString(mHistoryCur.states)); 1232 addHistoryRecord(SystemClock.elapsedRealtime()); 1233 mPhoneOn = false; 1234 mPhoneOnTimer.stopRunningLocked(this); 1235 } 1236 } 1237 1238 /** 1239 * Telephony stack updates the phone state. 1240 * @param state phone state from ServiceState.getState() 1241 */ 1242 public void notePhoneStateLocked(int state) { 1243 int bin = mPhoneSignalStrengthBin; 1244 boolean isAirplaneMode = state == ServiceState.STATE_POWER_OFF; 1245 // Stop all timers 1246 if (isAirplaneMode || state == ServiceState.STATE_OUT_OF_SERVICE) { 1247 for (int i = 0; i < NUM_SIGNAL_STRENGTH_BINS; i++) { 1248 while (mPhoneSignalStrengthsTimer[i].isRunningLocked()) { 1249 mPhoneSignalStrengthsTimer[i].stopRunningLocked(this); 1250 } 1251 } 1252 } 1253 // Stop Signal Scanning timer, in case we're going into service 1254 while (mPhoneSignalScanningTimer.isRunningLocked()) { 1255 mPhoneSignalScanningTimer.stopRunningLocked(this); 1256 } 1257 1258 // If we're back in service or continuing in service, restart the old timer. 1259 if (state == ServiceState.STATE_IN_SERVICE) { 1260 if (bin == -1) bin = SIGNAL_STRENGTH_NONE_OR_UNKNOWN; 1261 if (!mPhoneSignalStrengthsTimer[bin].isRunningLocked()) { 1262 mPhoneSignalStrengthsTimer[bin].startRunningLocked(this); 1263 } 1264 } else if (state == ServiceState.STATE_OUT_OF_SERVICE) { 1265 mPhoneSignalStrengthBin = SIGNAL_STRENGTH_NONE_OR_UNKNOWN; 1266 if (!mPhoneSignalStrengthsTimer[mPhoneSignalStrengthBin].isRunningLocked()) { 1267 mPhoneSignalStrengthsTimer[mPhoneSignalStrengthBin].startRunningLocked(this); 1268 } 1269 if (!mPhoneSignalScanningTimer.isRunningLocked()) { 1270 mPhoneSignalScanningTimer.startRunningLocked(this); 1271 } 1272 } 1273 1274 if (mPhoneServiceState != state) { 1275 mHistoryCur.states = (mHistoryCur.states&~BatteryHistoryRecord.STATE_PHONE_STATE_MASK) 1276 | (state << BatteryHistoryRecord.STATE_PHONE_STATE_SHIFT); 1277 if (DEBUG_HISTORY) Slog.v(TAG, "Phone state " + bin + " to: " 1278 + Integer.toHexString(mHistoryCur.states)); 1279 addHistoryRecord(SystemClock.elapsedRealtime()); 1280 mPhoneServiceState = state; 1281 } 1282 } 1283 1284 public void notePhoneSignalStrengthLocked(SignalStrength signalStrength) { 1285 // Bin the strength. 1286 int bin; 1287 if (mPhoneServiceState == ServiceState.STATE_POWER_OFF 1288 || mPhoneServiceState == ServiceState.STATE_OUT_OF_SERVICE) { 1289 // Ignore any signal strength changes when radio was turned off or out of service. 1290 return; 1291 } 1292 if (!signalStrength.isGsm()) { 1293 int dBm = signalStrength.getCdmaDbm(); 1294 if (dBm >= -75) bin = SIGNAL_STRENGTH_GREAT; 1295 else if (dBm >= -85) bin = SIGNAL_STRENGTH_GOOD; 1296 else if (dBm >= -95) bin = SIGNAL_STRENGTH_MODERATE; 1297 else if (dBm >= -100) bin = SIGNAL_STRENGTH_POOR; 1298 else bin = SIGNAL_STRENGTH_NONE_OR_UNKNOWN; 1299 } else { 1300 int asu = signalStrength.getGsmSignalStrength(); 1301 if (asu < 0 || asu >= 99) bin = SIGNAL_STRENGTH_NONE_OR_UNKNOWN; 1302 else if (asu >= 16) bin = SIGNAL_STRENGTH_GREAT; 1303 else if (asu >= 8) bin = SIGNAL_STRENGTH_GOOD; 1304 else if (asu >= 4) bin = SIGNAL_STRENGTH_MODERATE; 1305 else bin = SIGNAL_STRENGTH_POOR; 1306 } 1307 if (mPhoneSignalStrengthBin != bin) { 1308 mHistoryCur.states = (mHistoryCur.states&~BatteryHistoryRecord.STATE_SIGNAL_STRENGTH_MASK) 1309 | (bin << BatteryHistoryRecord.STATE_SIGNAL_STRENGTH_SHIFT); 1310 if (DEBUG_HISTORY) Slog.v(TAG, "Signal strength " + bin + " to: " 1311 + Integer.toHexString(mHistoryCur.states)); 1312 addHistoryRecord(SystemClock.elapsedRealtime()); 1313 if (mPhoneSignalStrengthBin >= 0) { 1314 mPhoneSignalStrengthsTimer[mPhoneSignalStrengthBin].stopRunningLocked(this); 1315 } 1316 mPhoneSignalStrengthBin = bin; 1317 mPhoneSignalStrengthsTimer[bin].startRunningLocked(this); 1318 } 1319 } 1320 1321 public void notePhoneDataConnectionStateLocked(int dataType, boolean hasData) { 1322 int bin = DATA_CONNECTION_NONE; 1323 if (hasData) { 1324 switch (dataType) { 1325 case TelephonyManager.NETWORK_TYPE_EDGE: 1326 bin = DATA_CONNECTION_EDGE; 1327 break; 1328 case TelephonyManager.NETWORK_TYPE_GPRS: 1329 bin = DATA_CONNECTION_GPRS; 1330 break; 1331 case TelephonyManager.NETWORK_TYPE_UMTS: 1332 bin = DATA_CONNECTION_UMTS; 1333 break; 1334 default: 1335 bin = DATA_CONNECTION_OTHER; 1336 break; 1337 } 1338 } 1339 if (DEBUG) Log.i(TAG, "Phone Data Connection -> " + dataType + " = " + hasData); 1340 if (mPhoneDataConnectionType != bin) { 1341 mHistoryCur.states = (mHistoryCur.states&~BatteryHistoryRecord.STATE_DATA_CONNECTION_MASK) 1342 | (bin << BatteryHistoryRecord.STATE_DATA_CONNECTION_SHIFT); 1343 if (DEBUG_HISTORY) Slog.v(TAG, "Data connection " + bin + " to: " 1344 + Integer.toHexString(mHistoryCur.states)); 1345 addHistoryRecord(SystemClock.elapsedRealtime()); 1346 if (mPhoneDataConnectionType >= 0) { 1347 mPhoneDataConnectionsTimer[mPhoneDataConnectionType].stopRunningLocked(this); 1348 } 1349 mPhoneDataConnectionType = bin; 1350 mPhoneDataConnectionsTimer[bin].startRunningLocked(this); 1351 } 1352 } 1353 1354 public void noteWifiOnLocked(int uid) { 1355 if (!mWifiOn) { 1356 mHistoryCur.states |= BatteryHistoryRecord.STATE_WIFI_ON_FLAG; 1357 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI on to: " 1358 + Integer.toHexString(mHistoryCur.states)); 1359 addHistoryRecord(SystemClock.elapsedRealtime()); 1360 mWifiOn = true; 1361 mWifiOnTimer.startRunningLocked(this); 1362 } 1363 if (mWifiOnUid != uid) { 1364 if (mWifiOnUid >= 0) { 1365 getUidStatsLocked(mWifiOnUid).noteWifiTurnedOffLocked(); 1366 } 1367 mWifiOnUid = uid; 1368 getUidStatsLocked(uid).noteWifiTurnedOnLocked(); 1369 } 1370 } 1371 1372 public void noteWifiOffLocked(int uid) { 1373 if (mWifiOn) { 1374 mHistoryCur.states &= ~BatteryHistoryRecord.STATE_WIFI_ON_FLAG; 1375 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI off to: " 1376 + Integer.toHexString(mHistoryCur.states)); 1377 addHistoryRecord(SystemClock.elapsedRealtime()); 1378 mWifiOn = false; 1379 mWifiOnTimer.stopRunningLocked(this); 1380 } 1381 if (mWifiOnUid >= 0) { 1382 getUidStatsLocked(mWifiOnUid).noteWifiTurnedOffLocked(); 1383 mWifiOnUid = -1; 1384 } 1385 } 1386 1387 public void noteAudioOnLocked(int uid) { 1388 if (!mAudioOn) { 1389 mHistoryCur.states |= BatteryHistoryRecord.STATE_AUDIO_ON_FLAG; 1390 if (DEBUG_HISTORY) Slog.v(TAG, "Audio on to: " 1391 + Integer.toHexString(mHistoryCur.states)); 1392 addHistoryRecord(SystemClock.elapsedRealtime()); 1393 mAudioOn = true; 1394 mAudioOnTimer.startRunningLocked(this); 1395 } 1396 getUidStatsLocked(uid).noteAudioTurnedOnLocked(); 1397 } 1398 1399 public void noteAudioOffLocked(int uid) { 1400 if (mAudioOn) { 1401 mHistoryCur.states &= ~BatteryHistoryRecord.STATE_AUDIO_ON_FLAG; 1402 if (DEBUG_HISTORY) Slog.v(TAG, "Audio off to: " 1403 + Integer.toHexString(mHistoryCur.states)); 1404 addHistoryRecord(SystemClock.elapsedRealtime()); 1405 mAudioOn = false; 1406 mAudioOnTimer.stopRunningLocked(this); 1407 } 1408 getUidStatsLocked(uid).noteAudioTurnedOffLocked(); 1409 } 1410 1411 public void noteVideoOnLocked(int uid) { 1412 if (!mVideoOn) { 1413 mHistoryCur.states |= BatteryHistoryRecord.STATE_VIDEO_ON_FLAG; 1414 if (DEBUG_HISTORY) Slog.v(TAG, "Video on to: " 1415 + Integer.toHexString(mHistoryCur.states)); 1416 addHistoryRecord(SystemClock.elapsedRealtime()); 1417 mVideoOn = true; 1418 mVideoOnTimer.startRunningLocked(this); 1419 } 1420 getUidStatsLocked(uid).noteVideoTurnedOnLocked(); 1421 } 1422 1423 public void noteVideoOffLocked(int uid) { 1424 if (mVideoOn) { 1425 mHistoryCur.states &= ~BatteryHistoryRecord.STATE_VIDEO_ON_FLAG; 1426 if (DEBUG_HISTORY) Slog.v(TAG, "Video off to: " 1427 + Integer.toHexString(mHistoryCur.states)); 1428 addHistoryRecord(SystemClock.elapsedRealtime()); 1429 mVideoOn = false; 1430 mVideoOnTimer.stopRunningLocked(this); 1431 } 1432 getUidStatsLocked(uid).noteVideoTurnedOffLocked(); 1433 } 1434 1435 public void noteWifiRunningLocked() { 1436 if (!mWifiRunning) { 1437 mHistoryCur.states |= BatteryHistoryRecord.STATE_WIFI_RUNNING_FLAG; 1438 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI running to: " 1439 + Integer.toHexString(mHistoryCur.states)); 1440 addHistoryRecord(SystemClock.elapsedRealtime()); 1441 mWifiRunning = true; 1442 mWifiRunningTimer.startRunningLocked(this); 1443 } 1444 } 1445 1446 public void noteWifiStoppedLocked() { 1447 if (mWifiRunning) { 1448 mHistoryCur.states &= ~BatteryHistoryRecord.STATE_WIFI_RUNNING_FLAG; 1449 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI stopped to: " 1450 + Integer.toHexString(mHistoryCur.states)); 1451 addHistoryRecord(SystemClock.elapsedRealtime()); 1452 mWifiRunning = false; 1453 mWifiRunningTimer.stopRunningLocked(this); 1454 } 1455 } 1456 1457 public void noteBluetoothOnLocked() { 1458 if (!mBluetoothOn) { 1459 mHistoryCur.states |= BatteryHistoryRecord.STATE_BLUETOOTH_ON_FLAG; 1460 if (DEBUG_HISTORY) Slog.v(TAG, "Bluetooth on to: " 1461 + Integer.toHexString(mHistoryCur.states)); 1462 addHistoryRecord(SystemClock.elapsedRealtime()); 1463 mBluetoothOn = true; 1464 mBluetoothOnTimer.startRunningLocked(this); 1465 } 1466 } 1467 1468 public void noteBluetoothOffLocked() { 1469 if (mBluetoothOn) { 1470 mHistoryCur.states &= ~BatteryHistoryRecord.STATE_BLUETOOTH_ON_FLAG; 1471 if (DEBUG_HISTORY) Slog.v(TAG, "Bluetooth off to: " 1472 + Integer.toHexString(mHistoryCur.states)); 1473 addHistoryRecord(SystemClock.elapsedRealtime()); 1474 mBluetoothOn = false; 1475 mBluetoothOnTimer.stopRunningLocked(this); 1476 } 1477 } 1478 1479 int mWifiFullLockNesting = 0; 1480 1481 public void noteFullWifiLockAcquiredLocked(int uid) { 1482 if (mWifiFullLockNesting == 0) { 1483 mHistoryCur.states |= BatteryHistoryRecord.STATE_WIFI_FULL_LOCK_FLAG; 1484 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI full lock on to: " 1485 + Integer.toHexString(mHistoryCur.states)); 1486 addHistoryRecord(SystemClock.elapsedRealtime()); 1487 } 1488 mWifiFullLockNesting++; 1489 getUidStatsLocked(uid).noteFullWifiLockAcquiredLocked(); 1490 } 1491 1492 public void noteFullWifiLockReleasedLocked(int uid) { 1493 mWifiFullLockNesting--; 1494 if (mWifiFullLockNesting == 0) { 1495 mHistoryCur.states &= ~BatteryHistoryRecord.STATE_WIFI_FULL_LOCK_FLAG; 1496 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI full lock off to: " 1497 + Integer.toHexString(mHistoryCur.states)); 1498 addHistoryRecord(SystemClock.elapsedRealtime()); 1499 } 1500 getUidStatsLocked(uid).noteFullWifiLockReleasedLocked(); 1501 } 1502 1503 int mWifiScanLockNesting = 0; 1504 1505 public void noteScanWifiLockAcquiredLocked(int uid) { 1506 if (mWifiScanLockNesting == 0) { 1507 mHistoryCur.states |= BatteryHistoryRecord.STATE_WIFI_SCAN_LOCK_FLAG; 1508 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI scan lock on to: " 1509 + Integer.toHexString(mHistoryCur.states)); 1510 addHistoryRecord(SystemClock.elapsedRealtime()); 1511 } 1512 mWifiScanLockNesting++; 1513 getUidStatsLocked(uid).noteScanWifiLockAcquiredLocked(); 1514 } 1515 1516 public void noteScanWifiLockReleasedLocked(int uid) { 1517 mWifiScanLockNesting--; 1518 if (mWifiScanLockNesting == 0) { 1519 mHistoryCur.states &= ~BatteryHistoryRecord.STATE_WIFI_SCAN_LOCK_FLAG; 1520 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI scan lock off to: " 1521 + Integer.toHexString(mHistoryCur.states)); 1522 addHistoryRecord(SystemClock.elapsedRealtime()); 1523 } 1524 getUidStatsLocked(uid).noteScanWifiLockReleasedLocked(); 1525 } 1526 1527 int mWifiMulticastNesting = 0; 1528 1529 public void noteWifiMulticastEnabledLocked(int uid) { 1530 if (mWifiMulticastNesting == 0) { 1531 mHistoryCur.states |= BatteryHistoryRecord.STATE_WIFI_MULTICAST_ON_FLAG; 1532 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI multicast on to: " 1533 + Integer.toHexString(mHistoryCur.states)); 1534 addHistoryRecord(SystemClock.elapsedRealtime()); 1535 } 1536 mWifiMulticastNesting++; 1537 getUidStatsLocked(uid).noteWifiMulticastEnabledLocked(); 1538 } 1539 1540 public void noteWifiMulticastDisabledLocked(int uid) { 1541 mWifiMulticastNesting--; 1542 if (mWifiMulticastNesting == 0) { 1543 mHistoryCur.states &= ~BatteryHistoryRecord.STATE_WIFI_MULTICAST_ON_FLAG; 1544 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI multicast off to: " 1545 + Integer.toHexString(mHistoryCur.states)); 1546 addHistoryRecord(SystemClock.elapsedRealtime()); 1547 } 1548 getUidStatsLocked(uid).noteWifiMulticastDisabledLocked(); 1549 } 1550 1551 @Override public long getScreenOnTime(long batteryRealtime, int which) { 1552 return mScreenOnTimer.getTotalTimeLocked(batteryRealtime, which); 1553 } 1554 1555 @Override public long getScreenBrightnessTime(int brightnessBin, 1556 long batteryRealtime, int which) { 1557 return mScreenBrightnessTimer[brightnessBin].getTotalTimeLocked( 1558 batteryRealtime, which); 1559 } 1560 1561 @Override public int getInputEventCount(int which) { 1562 return mInputEventCounter.getCountLocked(which); 1563 } 1564 1565 @Override public long getPhoneOnTime(long batteryRealtime, int which) { 1566 return mPhoneOnTimer.getTotalTimeLocked(batteryRealtime, which); 1567 } 1568 1569 @Override public long getPhoneSignalStrengthTime(int strengthBin, 1570 long batteryRealtime, int which) { 1571 return mPhoneSignalStrengthsTimer[strengthBin].getTotalTimeLocked( 1572 batteryRealtime, which); 1573 } 1574 1575 @Override public long getPhoneSignalScanningTime( 1576 long batteryRealtime, int which) { 1577 return mPhoneSignalScanningTimer.getTotalTimeLocked( 1578 batteryRealtime, which); 1579 } 1580 1581 @Override public int getPhoneSignalStrengthCount(int dataType, int which) { 1582 return mPhoneDataConnectionsTimer[dataType].getCountLocked(which); 1583 } 1584 1585 @Override public long getPhoneDataConnectionTime(int dataType, 1586 long batteryRealtime, int which) { 1587 return mPhoneDataConnectionsTimer[dataType].getTotalTimeLocked( 1588 batteryRealtime, which); 1589 } 1590 1591 @Override public int getPhoneDataConnectionCount(int dataType, int which) { 1592 return mPhoneDataConnectionsTimer[dataType].getCountLocked(which); 1593 } 1594 1595 @Override public long getWifiOnTime(long batteryRealtime, int which) { 1596 return mWifiOnTimer.getTotalTimeLocked(batteryRealtime, which); 1597 } 1598 1599 @Override public long getWifiRunningTime(long batteryRealtime, int which) { 1600 return mWifiRunningTimer.getTotalTimeLocked(batteryRealtime, which); 1601 } 1602 1603 @Override public long getBluetoothOnTime(long batteryRealtime, int which) { 1604 return mBluetoothOnTimer.getTotalTimeLocked(batteryRealtime, which); 1605 } 1606 1607 @Override public boolean getIsOnBattery() { 1608 return mOnBattery; 1609 } 1610 1611 @Override public SparseArray<? extends BatteryStats.Uid> getUidStats() { 1612 return mUidStats; 1613 } 1614 1615 /** 1616 * The statistics associated with a particular uid. 1617 */ 1618 public final class Uid extends BatteryStats.Uid { 1619 1620 final int mUid; 1621 long mLoadedTcpBytesReceived; 1622 long mLoadedTcpBytesSent; 1623 long mCurrentTcpBytesReceived; 1624 long mCurrentTcpBytesSent; 1625 long mTcpBytesReceivedAtLastUnplug; 1626 long mTcpBytesSentAtLastUnplug; 1627 1628 // These are not saved/restored when parcelling, since we want 1629 // to return from the parcel with a snapshot of the state. 1630 long mStartedTcpBytesReceived = -1; 1631 long mStartedTcpBytesSent = -1; 1632 1633 boolean mWifiTurnedOn; 1634 StopwatchTimer mWifiTurnedOnTimer; 1635 1636 boolean mFullWifiLockOut; 1637 StopwatchTimer mFullWifiLockTimer; 1638 1639 boolean mScanWifiLockOut; 1640 StopwatchTimer mScanWifiLockTimer; 1641 1642 boolean mWifiMulticastEnabled; 1643 StopwatchTimer mWifiMulticastTimer; 1644 1645 boolean mAudioTurnedOn; 1646 StopwatchTimer mAudioTurnedOnTimer; 1647 1648 boolean mVideoTurnedOn; 1649 StopwatchTimer mVideoTurnedOnTimer; 1650 1651 Counter[] mUserActivityCounters; 1652 1653 /** 1654 * The statistics we have collected for this uid's wake locks. 1655 */ 1656 final HashMap<String, Wakelock> mWakelockStats = new HashMap<String, Wakelock>(); 1657 1658 /** 1659 * The statistics we have collected for this uid's sensor activations. 1660 */ 1661 final HashMap<Integer, Sensor> mSensorStats = new HashMap<Integer, Sensor>(); 1662 1663 /** 1664 * The statistics we have collected for this uid's processes. 1665 */ 1666 final HashMap<String, Proc> mProcessStats = new HashMap<String, Proc>(); 1667 1668 /** 1669 * The statistics we have collected for this uid's processes. 1670 */ 1671 final HashMap<String, Pkg> mPackageStats = new HashMap<String, Pkg>(); 1672 1673 public Uid(int uid) { 1674 mUid = uid; 1675 mWifiTurnedOnTimer = new StopwatchTimer(WIFI_TURNED_ON, null, mUnpluggables); 1676 mFullWifiLockTimer = new StopwatchTimer(FULL_WIFI_LOCK, null, mUnpluggables); 1677 mScanWifiLockTimer = new StopwatchTimer(SCAN_WIFI_LOCK, null, mUnpluggables); 1678 mWifiMulticastTimer = new StopwatchTimer(WIFI_MULTICAST_ENABLED, 1679 null, mUnpluggables); 1680 mAudioTurnedOnTimer = new StopwatchTimer(AUDIO_TURNED_ON, null, mUnpluggables); 1681 mVideoTurnedOnTimer = new StopwatchTimer(VIDEO_TURNED_ON, null, mUnpluggables); 1682 } 1683 1684 @Override 1685 public Map<String, ? extends BatteryStats.Uid.Wakelock> getWakelockStats() { 1686 return mWakelockStats; 1687 } 1688 1689 @Override 1690 public Map<Integer, ? extends BatteryStats.Uid.Sensor> getSensorStats() { 1691 return mSensorStats; 1692 } 1693 1694 @Override 1695 public Map<String, ? extends BatteryStats.Uid.Proc> getProcessStats() { 1696 return mProcessStats; 1697 } 1698 1699 @Override 1700 public Map<String, ? extends BatteryStats.Uid.Pkg> getPackageStats() { 1701 return mPackageStats; 1702 } 1703 1704 @Override 1705 public int getUid() { 1706 return mUid; 1707 } 1708 1709 @Override 1710 public long getTcpBytesReceived(int which) { 1711 if (which == STATS_LAST) { 1712 return mLoadedTcpBytesReceived; 1713 } else { 1714 long current = computeCurrentTcpBytesReceived(); 1715 if (which == STATS_UNPLUGGED) { 1716 current -= mTcpBytesReceivedAtLastUnplug; 1717 } else if (which == STATS_TOTAL) { 1718 current += mLoadedTcpBytesReceived; 1719 } 1720 return current; 1721 } 1722 } 1723 1724 public long computeCurrentTcpBytesReceived() { 1725 return mCurrentTcpBytesReceived + (mStartedTcpBytesReceived >= 0 1726 ? (TrafficStats.getUidRxBytes(mUid) - mStartedTcpBytesReceived) : 0); 1727 } 1728 1729 @Override 1730 public long getTcpBytesSent(int which) { 1731 if (which == STATS_LAST) { 1732 return mLoadedTcpBytesSent; 1733 } else { 1734 long current = computeCurrentTcpBytesSent(); 1735 if (which == STATS_UNPLUGGED) { 1736 current -= mTcpBytesSentAtLastUnplug; 1737 } else if (which == STATS_TOTAL) { 1738 current += mLoadedTcpBytesSent; 1739 } 1740 return current; 1741 } 1742 } 1743 1744 @Override 1745 public void noteWifiTurnedOnLocked() { 1746 if (!mWifiTurnedOn) { 1747 mWifiTurnedOn = true; 1748 mWifiTurnedOnTimer.startRunningLocked(BatteryStatsImpl.this); 1749 } 1750 } 1751 1752 @Override 1753 public void noteWifiTurnedOffLocked() { 1754 if (mWifiTurnedOn) { 1755 mWifiTurnedOn = false; 1756 mWifiTurnedOnTimer.stopRunningLocked(BatteryStatsImpl.this); 1757 } 1758 } 1759 1760 @Override 1761 public void noteFullWifiLockAcquiredLocked() { 1762 if (!mFullWifiLockOut) { 1763 mFullWifiLockOut = true; 1764 mFullWifiLockTimer.startRunningLocked(BatteryStatsImpl.this); 1765 } 1766 } 1767 1768 @Override 1769 public void noteVideoTurnedOnLocked() { 1770 if (!mVideoTurnedOn) { 1771 mVideoTurnedOn = true; 1772 mVideoTurnedOnTimer.startRunningLocked(BatteryStatsImpl.this); 1773 } 1774 } 1775 1776 @Override 1777 public void noteVideoTurnedOffLocked() { 1778 if (mVideoTurnedOn) { 1779 mVideoTurnedOn = false; 1780 mVideoTurnedOnTimer.stopRunningLocked(BatteryStatsImpl.this); 1781 } 1782 } 1783 1784 @Override 1785 public void noteAudioTurnedOnLocked() { 1786 if (!mAudioTurnedOn) { 1787 mAudioTurnedOn = true; 1788 mAudioTurnedOnTimer.startRunningLocked(BatteryStatsImpl.this); 1789 } 1790 } 1791 1792 @Override 1793 public void noteAudioTurnedOffLocked() { 1794 if (mAudioTurnedOn) { 1795 mAudioTurnedOn = false; 1796 mAudioTurnedOnTimer.stopRunningLocked(BatteryStatsImpl.this); 1797 } 1798 } 1799 1800 @Override 1801 public void noteFullWifiLockReleasedLocked() { 1802 if (mFullWifiLockOut) { 1803 mFullWifiLockOut = false; 1804 mFullWifiLockTimer.stopRunningLocked(BatteryStatsImpl.this); 1805 } 1806 } 1807 1808 @Override 1809 public void noteScanWifiLockAcquiredLocked() { 1810 if (!mScanWifiLockOut) { 1811 mScanWifiLockOut = true; 1812 mScanWifiLockTimer.startRunningLocked(BatteryStatsImpl.this); 1813 } 1814 } 1815 1816 @Override 1817 public void noteScanWifiLockReleasedLocked() { 1818 if (mScanWifiLockOut) { 1819 mScanWifiLockOut = false; 1820 mScanWifiLockTimer.stopRunningLocked(BatteryStatsImpl.this); 1821 } 1822 } 1823 1824 @Override 1825 public void noteWifiMulticastEnabledLocked() { 1826 if (!mWifiMulticastEnabled) { 1827 mWifiMulticastEnabled = true; 1828 mWifiMulticastTimer.startRunningLocked(BatteryStatsImpl.this); 1829 } 1830 } 1831 1832 @Override 1833 public void noteWifiMulticastDisabledLocked() { 1834 if (mWifiMulticastEnabled) { 1835 mWifiMulticastEnabled = false; 1836 mWifiMulticastTimer.stopRunningLocked(BatteryStatsImpl.this); 1837 } 1838 } 1839 1840 @Override 1841 public long getWifiTurnedOnTime(long batteryRealtime, int which) { 1842 return mWifiTurnedOnTimer.getTotalTimeLocked(batteryRealtime, which); 1843 } 1844 1845 @Override 1846 public long getAudioTurnedOnTime(long batteryRealtime, int which) { 1847 return mAudioTurnedOnTimer.getTotalTimeLocked(batteryRealtime, which); 1848 } 1849 1850 @Override 1851 public long getVideoTurnedOnTime(long batteryRealtime, int which) { 1852 return mVideoTurnedOnTimer.getTotalTimeLocked(batteryRealtime, which); 1853 } 1854 1855 @Override 1856 public long getFullWifiLockTime(long batteryRealtime, int which) { 1857 return mFullWifiLockTimer.getTotalTimeLocked(batteryRealtime, which); 1858 } 1859 1860 @Override 1861 public long getScanWifiLockTime(long batteryRealtime, int which) { 1862 return mScanWifiLockTimer.getTotalTimeLocked(batteryRealtime, which); 1863 } 1864 1865 @Override 1866 public long getWifiMulticastTime(long batteryRealtime, int which) { 1867 return mWifiMulticastTimer.getTotalTimeLocked(batteryRealtime, 1868 which); 1869 } 1870 1871 @Override 1872 public void noteUserActivityLocked(int type) { 1873 if (mUserActivityCounters == null) { 1874 initUserActivityLocked(); 1875 } 1876 if (type < 0) type = 0; 1877 else if (type >= NUM_USER_ACTIVITY_TYPES) type = NUM_USER_ACTIVITY_TYPES-1; 1878 mUserActivityCounters[type].stepAtomic(); 1879 } 1880 1881 @Override 1882 public boolean hasUserActivity() { 1883 return mUserActivityCounters != null; 1884 } 1885 1886 @Override 1887 public int getUserActivityCount(int type, int which) { 1888 if (mUserActivityCounters == null) { 1889 return 0; 1890 } 1891 return mUserActivityCounters[type].getCountLocked(which); 1892 } 1893 1894 void initUserActivityLocked() { 1895 mUserActivityCounters = new Counter[NUM_USER_ACTIVITY_TYPES]; 1896 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) { 1897 mUserActivityCounters[i] = new Counter(mUnpluggables); 1898 } 1899 } 1900 1901 public long computeCurrentTcpBytesSent() { 1902 return mCurrentTcpBytesSent + (mStartedTcpBytesSent >= 0 1903 ? (TrafficStats.getUidTxBytes(mUid) - mStartedTcpBytesSent) : 0); 1904 } 1905 1906 void writeToParcelLocked(Parcel out, long batteryRealtime) { 1907 out.writeInt(mWakelockStats.size()); 1908 for (Map.Entry<String, Uid.Wakelock> wakelockEntry : mWakelockStats.entrySet()) { 1909 out.writeString(wakelockEntry.getKey()); 1910 Uid.Wakelock wakelock = wakelockEntry.getValue(); 1911 wakelock.writeToParcelLocked(out, batteryRealtime); 1912 } 1913 1914 out.writeInt(mSensorStats.size()); 1915 for (Map.Entry<Integer, Uid.Sensor> sensorEntry : mSensorStats.entrySet()) { 1916 out.writeInt(sensorEntry.getKey()); 1917 Uid.Sensor sensor = sensorEntry.getValue(); 1918 sensor.writeToParcelLocked(out, batteryRealtime); 1919 } 1920 1921 out.writeInt(mProcessStats.size()); 1922 for (Map.Entry<String, Uid.Proc> procEntry : mProcessStats.entrySet()) { 1923 out.writeString(procEntry.getKey()); 1924 Uid.Proc proc = procEntry.getValue(); 1925 proc.writeToParcelLocked(out); 1926 } 1927 1928 out.writeInt(mPackageStats.size()); 1929 for (Map.Entry<String, Uid.Pkg> pkgEntry : mPackageStats.entrySet()) { 1930 out.writeString(pkgEntry.getKey()); 1931 Uid.Pkg pkg = pkgEntry.getValue(); 1932 pkg.writeToParcelLocked(out); 1933 } 1934 1935 out.writeLong(mLoadedTcpBytesReceived); 1936 out.writeLong(mLoadedTcpBytesSent); 1937 out.writeLong(computeCurrentTcpBytesReceived()); 1938 out.writeLong(computeCurrentTcpBytesSent()); 1939 out.writeLong(mTcpBytesReceivedAtLastUnplug); 1940 out.writeLong(mTcpBytesSentAtLastUnplug); 1941 mWifiTurnedOnTimer.writeToParcel(out, batteryRealtime); 1942 mFullWifiLockTimer.writeToParcel(out, batteryRealtime); 1943 mAudioTurnedOnTimer.writeToParcel(out, batteryRealtime); 1944 mVideoTurnedOnTimer.writeToParcel(out, batteryRealtime); 1945 mScanWifiLockTimer.writeToParcel(out, batteryRealtime); 1946 mWifiMulticastTimer.writeToParcel(out, batteryRealtime); 1947 if (mUserActivityCounters == null) { 1948 out.writeInt(0); 1949 } else { 1950 out.writeInt(1); 1951 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) { 1952 mUserActivityCounters[i].writeToParcel(out); 1953 } 1954 } 1955 } 1956 1957 void readFromParcelLocked(ArrayList<Unpluggable> unpluggables, Parcel in) { 1958 int numWakelocks = in.readInt(); 1959 mWakelockStats.clear(); 1960 for (int j = 0; j < numWakelocks; j++) { 1961 String wakelockName = in.readString(); 1962 Uid.Wakelock wakelock = new Wakelock(); 1963 wakelock.readFromParcelLocked(unpluggables, in); 1964 if (mWakelockStats.size() < MAX_WAKELOCKS_PER_UID) { 1965 // We will just drop some random set of wakelocks if 1966 // the previous run of the system was an older version 1967 // that didn't impose a limit. 1968 mWakelockStats.put(wakelockName, wakelock); 1969 } 1970 } 1971 1972 int numSensors = in.readInt(); 1973 mSensorStats.clear(); 1974 for (int k = 0; k < numSensors; k++) { 1975 int sensorNumber = in.readInt(); 1976 Uid.Sensor sensor = new Sensor(sensorNumber); 1977 sensor.readFromParcelLocked(mUnpluggables, in); 1978 mSensorStats.put(sensorNumber, sensor); 1979 } 1980 1981 int numProcs = in.readInt(); 1982 mProcessStats.clear(); 1983 for (int k = 0; k < numProcs; k++) { 1984 String processName = in.readString(); 1985 Uid.Proc proc = new Proc(); 1986 proc.readFromParcelLocked(in); 1987 mProcessStats.put(processName, proc); 1988 } 1989 1990 int numPkgs = in.readInt(); 1991 mPackageStats.clear(); 1992 for (int l = 0; l < numPkgs; l++) { 1993 String packageName = in.readString(); 1994 Uid.Pkg pkg = new Pkg(); 1995 pkg.readFromParcelLocked(in); 1996 mPackageStats.put(packageName, pkg); 1997 } 1998 1999 mLoadedTcpBytesReceived = in.readLong(); 2000 mLoadedTcpBytesSent = in.readLong(); 2001 mCurrentTcpBytesReceived = in.readLong(); 2002 mCurrentTcpBytesSent = in.readLong(); 2003 mTcpBytesReceivedAtLastUnplug = in.readLong(); 2004 mTcpBytesSentAtLastUnplug = in.readLong(); 2005 mWifiTurnedOn = false; 2006 mWifiTurnedOnTimer = new StopwatchTimer(WIFI_TURNED_ON, null, mUnpluggables, in); 2007 mFullWifiLockOut = false; 2008 mFullWifiLockTimer = new StopwatchTimer(FULL_WIFI_LOCK, null, mUnpluggables, in); 2009 mAudioTurnedOn = false; 2010 mAudioTurnedOnTimer = new StopwatchTimer(AUDIO_TURNED_ON, null, mUnpluggables, in); 2011 mVideoTurnedOn = false; 2012 mVideoTurnedOnTimer = new StopwatchTimer(VIDEO_TURNED_ON, null, mUnpluggables, in); 2013 mScanWifiLockOut = false; 2014 mScanWifiLockTimer = new StopwatchTimer(SCAN_WIFI_LOCK, null, mUnpluggables, in); 2015 mWifiMulticastEnabled = false; 2016 mWifiMulticastTimer = new StopwatchTimer(WIFI_MULTICAST_ENABLED, 2017 null, mUnpluggables, in); 2018 if (in.readInt() == 0) { 2019 mUserActivityCounters = null; 2020 } else { 2021 mUserActivityCounters = new Counter[NUM_USER_ACTIVITY_TYPES]; 2022 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) { 2023 mUserActivityCounters[i] = new Counter(mUnpluggables, in); 2024 } 2025 } 2026 } 2027 2028 /** 2029 * The statistics associated with a particular wake lock. 2030 */ 2031 public final class Wakelock extends BatteryStats.Uid.Wakelock { 2032 /** 2033 * How long (in ms) this uid has been keeping the device partially awake. 2034 */ 2035 StopwatchTimer mTimerPartial; 2036 2037 /** 2038 * How long (in ms) this uid has been keeping the device fully awake. 2039 */ 2040 StopwatchTimer mTimerFull; 2041 2042 /** 2043 * How long (in ms) this uid has had a window keeping the device awake. 2044 */ 2045 StopwatchTimer mTimerWindow; 2046 2047 /** 2048 * Reads a possibly null Timer from a Parcel. The timer is associated with the 2049 * proper timer pool from the given BatteryStatsImpl object. 2050 * 2051 * @param in the Parcel to be read from. 2052 * return a new Timer, or null. 2053 */ 2054 private StopwatchTimer readTimerFromParcel(int type, ArrayList<StopwatchTimer> pool, 2055 ArrayList<Unpluggable> unpluggables, Parcel in) { 2056 if (in.readInt() == 0) { 2057 return null; 2058 } 2059 2060 return new StopwatchTimer(type, pool, unpluggables, in); 2061 } 2062 2063 void readFromParcelLocked(ArrayList<Unpluggable> unpluggables, Parcel in) { 2064 mTimerPartial = readTimerFromParcel(WAKE_TYPE_PARTIAL, 2065 mPartialTimers, unpluggables, in); 2066 mTimerFull = readTimerFromParcel(WAKE_TYPE_FULL, 2067 mFullTimers, unpluggables, in); 2068 mTimerWindow = readTimerFromParcel(WAKE_TYPE_WINDOW, 2069 mWindowTimers, unpluggables, in); 2070 } 2071 2072 void writeToParcelLocked(Parcel out, long batteryRealtime) { 2073 Timer.writeTimerToParcel(out, mTimerPartial, batteryRealtime); 2074 Timer.writeTimerToParcel(out, mTimerFull, batteryRealtime); 2075 Timer.writeTimerToParcel(out, mTimerWindow, batteryRealtime); 2076 } 2077 2078 @Override 2079 public Timer getWakeTime(int type) { 2080 switch (type) { 2081 case WAKE_TYPE_FULL: return mTimerFull; 2082 case WAKE_TYPE_PARTIAL: return mTimerPartial; 2083 case WAKE_TYPE_WINDOW: return mTimerWindow; 2084 default: throw new IllegalArgumentException("type = " + type); 2085 } 2086 } 2087 } 2088 2089 public final class Sensor extends BatteryStats.Uid.Sensor { 2090 final int mHandle; 2091 StopwatchTimer mTimer; 2092 2093 public Sensor(int handle) { 2094 mHandle = handle; 2095 } 2096 2097 private StopwatchTimer readTimerFromParcel(ArrayList<Unpluggable> unpluggables, 2098 Parcel in) { 2099 if (in.readInt() == 0) { 2100 return null; 2101 } 2102 2103 ArrayList<StopwatchTimer> pool = mSensorTimers.get(mHandle); 2104 if (pool == null) { 2105 pool = new ArrayList<StopwatchTimer>(); 2106 mSensorTimers.put(mHandle, pool); 2107 } 2108 return new StopwatchTimer(0, pool, unpluggables, in); 2109 } 2110 2111 void readFromParcelLocked(ArrayList<Unpluggable> unpluggables, Parcel in) { 2112 mTimer = readTimerFromParcel(unpluggables, in); 2113 } 2114 2115 void writeToParcelLocked(Parcel out, long batteryRealtime) { 2116 Timer.writeTimerToParcel(out, mTimer, batteryRealtime); 2117 } 2118 2119 @Override 2120 public Timer getSensorTime() { 2121 return mTimer; 2122 } 2123 2124 @Override 2125 public int getHandle() { 2126 return mHandle; 2127 } 2128 } 2129 2130 /** 2131 * The statistics associated with a particular process. 2132 */ 2133 public final class Proc extends BatteryStats.Uid.Proc implements Unpluggable { 2134 /** 2135 * Total time (in 1/100 sec) spent executing in user code. 2136 */ 2137 long mUserTime; 2138 2139 /** 2140 * Total time (in 1/100 sec) spent executing in kernel code. 2141 */ 2142 long mSystemTime; 2143 2144 /** 2145 * Number of times the process has been started. 2146 */ 2147 int mStarts; 2148 2149 /** 2150 * Amount of time the process was running in the foreground. 2151 */ 2152 long mForegroundTime; 2153 2154 /** 2155 * The amount of user time loaded from a previous save. 2156 */ 2157 long mLoadedUserTime; 2158 2159 /** 2160 * The amount of system time loaded from a previous save. 2161 */ 2162 long mLoadedSystemTime; 2163 2164 /** 2165 * The number of times the process has started from a previous save. 2166 */ 2167 int mLoadedStarts; 2168 2169 /** 2170 * The amount of foreground time loaded from a previous save. 2171 */ 2172 long mLoadedForegroundTime; 2173 2174 /** 2175 * The amount of user time loaded from the previous run. 2176 */ 2177 long mLastUserTime; 2178 2179 /** 2180 * The amount of system time loaded from the previous run. 2181 */ 2182 long mLastSystemTime; 2183 2184 /** 2185 * The number of times the process has started from the previous run. 2186 */ 2187 int mLastStarts; 2188 2189 /** 2190 * The amount of foreground time loaded from the previous run 2191 */ 2192 long mLastForegroundTime; 2193 2194 /** 2195 * The amount of user time when last unplugged. 2196 */ 2197 long mUnpluggedUserTime; 2198 2199 /** 2200 * The amount of system time when last unplugged. 2201 */ 2202 long mUnpluggedSystemTime; 2203 2204 /** 2205 * The number of times the process has started before unplugged. 2206 */ 2207 int mUnpluggedStarts; 2208 2209 /** 2210 * The amount of foreground time since unplugged. 2211 */ 2212 long mUnpluggedForegroundTime; 2213 2214 SamplingCounter[] mSpeedBins; 2215 2216 Proc() { 2217 mUnpluggables.add(this); 2218 mSpeedBins = new SamplingCounter[getCpuSpeedSteps()]; 2219 for (int i = 0; i < mSpeedBins.length; i++) { 2220 mSpeedBins[i] = new SamplingCounter(mUnpluggables); 2221 } 2222 } 2223 2224 public void unplug(long batteryUptime, long batteryRealtime) { 2225 mUnpluggedUserTime = mUserTime; 2226 mUnpluggedSystemTime = mSystemTime; 2227 mUnpluggedStarts = mStarts; 2228 mUnpluggedForegroundTime = mForegroundTime; 2229 } 2230 2231 public void plug(long batteryUptime, long batteryRealtime) { 2232 } 2233 2234 void writeToParcelLocked(Parcel out) { 2235 final long uSecRealtime = SystemClock.elapsedRealtime() * 1000; 2236 final long batteryRealtime = getBatteryRealtimeLocked(uSecRealtime); 2237 2238 out.writeLong(mUserTime); 2239 out.writeLong(mSystemTime); 2240 out.writeLong(mForegroundTime); 2241 out.writeInt(mStarts); 2242 out.writeLong(mLoadedUserTime); 2243 out.writeLong(mLoadedSystemTime); 2244 out.writeLong(mLoadedForegroundTime); 2245 out.writeInt(mLoadedStarts); 2246 out.writeLong(mLastUserTime); 2247 out.writeLong(mLastSystemTime); 2248 out.writeLong(mLastForegroundTime); 2249 out.writeInt(mLastStarts); 2250 out.writeLong(mUnpluggedUserTime); 2251 out.writeLong(mUnpluggedSystemTime); 2252 out.writeLong(mUnpluggedForegroundTime); 2253 out.writeInt(mUnpluggedStarts); 2254 2255 out.writeInt(mSpeedBins.length); 2256 for (int i = 0; i < mSpeedBins.length; i++) { 2257 mSpeedBins[i].writeToParcel(out); 2258 } 2259 } 2260 2261 void readFromParcelLocked(Parcel in) { 2262 mUserTime = in.readLong(); 2263 mSystemTime = in.readLong(); 2264 mForegroundTime = in.readLong(); 2265 mStarts = in.readInt(); 2266 mLoadedUserTime = in.readLong(); 2267 mLoadedSystemTime = in.readLong(); 2268 mLoadedForegroundTime = in.readLong(); 2269 mLoadedStarts = in.readInt(); 2270 mLastUserTime = in.readLong(); 2271 mLastSystemTime = in.readLong(); 2272 mLastForegroundTime = in.readLong(); 2273 mLastStarts = in.readInt(); 2274 mUnpluggedUserTime = in.readLong(); 2275 mUnpluggedSystemTime = in.readLong(); 2276 mUnpluggedForegroundTime = in.readLong(); 2277 mUnpluggedStarts = in.readInt(); 2278 2279 int bins = in.readInt(); 2280 mSpeedBins = new SamplingCounter[bins]; 2281 for (int i = 0; i < bins; i++) { 2282 mSpeedBins[i] = new SamplingCounter(mUnpluggables, in); 2283 } 2284 } 2285 2286 public BatteryStatsImpl getBatteryStats() { 2287 return BatteryStatsImpl.this; 2288 } 2289 2290 public void addCpuTimeLocked(int utime, int stime) { 2291 mUserTime += utime; 2292 mSystemTime += stime; 2293 } 2294 2295 public void addForegroundTimeLocked(long ttime) { 2296 mForegroundTime += ttime; 2297 } 2298 2299 public void incStartsLocked() { 2300 mStarts++; 2301 } 2302 2303 @Override 2304 public long getUserTime(int which) { 2305 long val; 2306 if (which == STATS_LAST) { 2307 val = mLastUserTime; 2308 } else { 2309 val = mUserTime; 2310 if (which == STATS_CURRENT) { 2311 val -= mLoadedUserTime; 2312 } else if (which == STATS_UNPLUGGED) { 2313 val -= mUnpluggedUserTime; 2314 } 2315 } 2316 return val; 2317 } 2318 2319 @Override 2320 public long getSystemTime(int which) { 2321 long val; 2322 if (which == STATS_LAST) { 2323 val = mLastSystemTime; 2324 } else { 2325 val = mSystemTime; 2326 if (which == STATS_CURRENT) { 2327 val -= mLoadedSystemTime; 2328 } else if (which == STATS_UNPLUGGED) { 2329 val -= mUnpluggedSystemTime; 2330 } 2331 } 2332 return val; 2333 } 2334 2335 @Override 2336 public long getForegroundTime(int which) { 2337 long val; 2338 if (which == STATS_LAST) { 2339 val = mLastForegroundTime; 2340 } else { 2341 val = mForegroundTime; 2342 if (which == STATS_CURRENT) { 2343 val -= mLoadedForegroundTime; 2344 } else if (which == STATS_UNPLUGGED) { 2345 val -= mUnpluggedForegroundTime; 2346 } 2347 } 2348 return val; 2349 } 2350 2351 @Override 2352 public int getStarts(int which) { 2353 int val; 2354 if (which == STATS_LAST) { 2355 val = mLastStarts; 2356 } else { 2357 val = mStarts; 2358 if (which == STATS_CURRENT) { 2359 val -= mLoadedStarts; 2360 } else if (which == STATS_UNPLUGGED) { 2361 val -= mUnpluggedStarts; 2362 } 2363 } 2364 return val; 2365 } 2366 2367 /* Called by ActivityManagerService when CPU times are updated. */ 2368 public void addSpeedStepTimes(long[] values) { 2369 for (int i = 0; i < mSpeedBins.length && i < values.length; i++) { 2370 mSpeedBins[i].addCountAtomic(values[i]); 2371 } 2372 } 2373 2374 @Override 2375 public long getTimeAtCpuSpeedStep(int speedStep, int which) { 2376 if (speedStep < mSpeedBins.length) { 2377 return mSpeedBins[speedStep].getCountLocked(which); 2378 } else { 2379 return 0; 2380 } 2381 } 2382 } 2383 2384 /** 2385 * The statistics associated with a particular package. 2386 */ 2387 public final class Pkg extends BatteryStats.Uid.Pkg implements Unpluggable { 2388 /** 2389 * Number of times this package has done something that could wake up the 2390 * device from sleep. 2391 */ 2392 int mWakeups; 2393 2394 /** 2395 * Number of things that could wake up the device loaded from a 2396 * previous save. 2397 */ 2398 int mLoadedWakeups; 2399 2400 /** 2401 * Number of things that could wake up the device as of the 2402 * last run. 2403 */ 2404 int mLastWakeups; 2405 2406 /** 2407 * Number of things that could wake up the device as of the 2408 * last run. 2409 */ 2410 int mUnpluggedWakeups; 2411 2412 /** 2413 * The statics we have collected for this package's services. 2414 */ 2415 final HashMap<String, Serv> mServiceStats = new HashMap<String, Serv>(); 2416 2417 Pkg() { 2418 mUnpluggables.add(this); 2419 } 2420 2421 public void unplug(long batteryUptime, long batteryRealtime) { 2422 mUnpluggedWakeups = mWakeups; 2423 } 2424 2425 public void plug(long batteryUptime, long batteryRealtime) { 2426 } 2427 2428 void readFromParcelLocked(Parcel in) { 2429 mWakeups = in.readInt(); 2430 mLoadedWakeups = in.readInt(); 2431 mLastWakeups = in.readInt(); 2432 mUnpluggedWakeups = in.readInt(); 2433 2434 int numServs = in.readInt(); 2435 mServiceStats.clear(); 2436 for (int m = 0; m < numServs; m++) { 2437 String serviceName = in.readString(); 2438 Uid.Pkg.Serv serv = new Serv(); 2439 mServiceStats.put(serviceName, serv); 2440 2441 serv.readFromParcelLocked(in); 2442 } 2443 } 2444 2445 void writeToParcelLocked(Parcel out) { 2446 out.writeInt(mWakeups); 2447 out.writeInt(mLoadedWakeups); 2448 out.writeInt(mLastWakeups); 2449 out.writeInt(mUnpluggedWakeups); 2450 2451 out.writeInt(mServiceStats.size()); 2452 for (Map.Entry<String, Uid.Pkg.Serv> servEntry : mServiceStats.entrySet()) { 2453 out.writeString(servEntry.getKey()); 2454 Uid.Pkg.Serv serv = servEntry.getValue(); 2455 2456 serv.writeToParcelLocked(out); 2457 } 2458 } 2459 2460 @Override 2461 public Map<String, ? extends BatteryStats.Uid.Pkg.Serv> getServiceStats() { 2462 return mServiceStats; 2463 } 2464 2465 @Override 2466 public int getWakeups(int which) { 2467 int val; 2468 if (which == STATS_LAST) { 2469 val = mLastWakeups; 2470 } else { 2471 val = mWakeups; 2472 if (which == STATS_CURRENT) { 2473 val -= mLoadedWakeups; 2474 } else if (which == STATS_UNPLUGGED) { 2475 val -= mUnpluggedWakeups; 2476 } 2477 } 2478 2479 return val; 2480 } 2481 2482 /** 2483 * The statistics associated with a particular service. 2484 */ 2485 public final class Serv extends BatteryStats.Uid.Pkg.Serv implements Unpluggable { 2486 /** 2487 * Total time (ms in battery uptime) the service has been left started. 2488 */ 2489 long mStartTime; 2490 2491 /** 2492 * If service has been started and not yet stopped, this is 2493 * when it was started. 2494 */ 2495 long mRunningSince; 2496 2497 /** 2498 * True if we are currently running. 2499 */ 2500 boolean mRunning; 2501 2502 /** 2503 * Total number of times startService() has been called. 2504 */ 2505 int mStarts; 2506 2507 /** 2508 * Total time (ms in battery uptime) the service has been left launched. 2509 */ 2510 long mLaunchedTime; 2511 2512 /** 2513 * If service has been launched and not yet exited, this is 2514 * when it was launched (ms in battery uptime). 2515 */ 2516 long mLaunchedSince; 2517 2518 /** 2519 * True if we are currently launched. 2520 */ 2521 boolean mLaunched; 2522 2523 /** 2524 * Total number times the service has been launched. 2525 */ 2526 int mLaunches; 2527 2528 /** 2529 * The amount of time spent started loaded from a previous save 2530 * (ms in battery uptime). 2531 */ 2532 long mLoadedStartTime; 2533 2534 /** 2535 * The number of starts loaded from a previous save. 2536 */ 2537 int mLoadedStarts; 2538 2539 /** 2540 * The number of launches loaded from a previous save. 2541 */ 2542 int mLoadedLaunches; 2543 2544 /** 2545 * The amount of time spent started as of the last run (ms 2546 * in battery uptime). 2547 */ 2548 long mLastStartTime; 2549 2550 /** 2551 * The number of starts as of the last run. 2552 */ 2553 int mLastStarts; 2554 2555 /** 2556 * The number of launches as of the last run. 2557 */ 2558 int mLastLaunches; 2559 2560 /** 2561 * The amount of time spent started when last unplugged (ms 2562 * in battery uptime). 2563 */ 2564 long mUnpluggedStartTime; 2565 2566 /** 2567 * The number of starts when last unplugged. 2568 */ 2569 int mUnpluggedStarts; 2570 2571 /** 2572 * The number of launches when last unplugged. 2573 */ 2574 int mUnpluggedLaunches; 2575 2576 Serv() { 2577 mUnpluggables.add(this); 2578 } 2579 2580 public void unplug(long batteryUptime, long batteryRealtime) { 2581 mUnpluggedStartTime = getStartTimeToNowLocked(batteryUptime); 2582 mUnpluggedStarts = mStarts; 2583 mUnpluggedLaunches = mLaunches; 2584 } 2585 2586 public void plug(long batteryUptime, long batteryRealtime) { 2587 } 2588 2589 void readFromParcelLocked(Parcel in) { 2590 mStartTime = in.readLong(); 2591 mRunningSince = in.readLong(); 2592 mRunning = in.readInt() != 0; 2593 mStarts = in.readInt(); 2594 mLaunchedTime = in.readLong(); 2595 mLaunchedSince = in.readLong(); 2596 mLaunched = in.readInt() != 0; 2597 mLaunches = in.readInt(); 2598 mLoadedStartTime = in.readLong(); 2599 mLoadedStarts = in.readInt(); 2600 mLoadedLaunches = in.readInt(); 2601 mLastStartTime = in.readLong(); 2602 mLastStarts = in.readInt(); 2603 mLastLaunches = in.readInt(); 2604 mUnpluggedStartTime = in.readLong(); 2605 mUnpluggedStarts = in.readInt(); 2606 mUnpluggedLaunches = in.readInt(); 2607 } 2608 2609 void writeToParcelLocked(Parcel out) { 2610 out.writeLong(mStartTime); 2611 out.writeLong(mRunningSince); 2612 out.writeInt(mRunning ? 1 : 0); 2613 out.writeInt(mStarts); 2614 out.writeLong(mLaunchedTime); 2615 out.writeLong(mLaunchedSince); 2616 out.writeInt(mLaunched ? 1 : 0); 2617 out.writeInt(mLaunches); 2618 out.writeLong(mLoadedStartTime); 2619 out.writeInt(mLoadedStarts); 2620 out.writeInt(mLoadedLaunches); 2621 out.writeLong(mLastStartTime); 2622 out.writeInt(mLastStarts); 2623 out.writeInt(mLastLaunches); 2624 out.writeLong(mUnpluggedStartTime); 2625 out.writeInt(mUnpluggedStarts); 2626 out.writeInt(mUnpluggedLaunches); 2627 } 2628 2629 long getLaunchTimeToNowLocked(long batteryUptime) { 2630 if (!mLaunched) return mLaunchedTime; 2631 return mLaunchedTime + batteryUptime - mLaunchedSince; 2632 } 2633 2634 long getStartTimeToNowLocked(long batteryUptime) { 2635 if (!mRunning) return mStartTime; 2636 return mStartTime + batteryUptime - mRunningSince; 2637 } 2638 2639 public void startLaunchedLocked() { 2640 if (!mLaunched) { 2641 mLaunches++; 2642 mLaunchedSince = getBatteryUptimeLocked(); 2643 mLaunched = true; 2644 } 2645 } 2646 2647 public void stopLaunchedLocked() { 2648 if (mLaunched) { 2649 long time = getBatteryUptimeLocked() - mLaunchedSince; 2650 if (time > 0) { 2651 mLaunchedTime += time; 2652 } else { 2653 mLaunches--; 2654 } 2655 mLaunched = false; 2656 } 2657 } 2658 2659 public void startRunningLocked() { 2660 if (!mRunning) { 2661 mStarts++; 2662 mRunningSince = getBatteryUptimeLocked(); 2663 mRunning = true; 2664 } 2665 } 2666 2667 public void stopRunningLocked() { 2668 if (mRunning) { 2669 long time = getBatteryUptimeLocked() - mRunningSince; 2670 if (time > 0) { 2671 mStartTime += time; 2672 } else { 2673 mStarts--; 2674 } 2675 mRunning = false; 2676 } 2677 } 2678 2679 public BatteryStatsImpl getBatteryStats() { 2680 return BatteryStatsImpl.this; 2681 } 2682 2683 @Override 2684 public int getLaunches(int which) { 2685 int val; 2686 2687 if (which == STATS_LAST) { 2688 val = mLastLaunches; 2689 } else { 2690 val = mLaunches; 2691 if (which == STATS_CURRENT) { 2692 val -= mLoadedLaunches; 2693 } else if (which == STATS_UNPLUGGED) { 2694 val -= mUnpluggedLaunches; 2695 } 2696 } 2697 2698 return val; 2699 } 2700 2701 @Override 2702 public long getStartTime(long now, int which) { 2703 long val; 2704 if (which == STATS_LAST) { 2705 val = mLastStartTime; 2706 } else { 2707 val = getStartTimeToNowLocked(now); 2708 if (which == STATS_CURRENT) { 2709 val -= mLoadedStartTime; 2710 } else if (which == STATS_UNPLUGGED) { 2711 val -= mUnpluggedStartTime; 2712 } 2713 } 2714 2715 return val; 2716 } 2717 2718 @Override 2719 public int getStarts(int which) { 2720 int val; 2721 if (which == STATS_LAST) { 2722 val = mLastStarts; 2723 } else { 2724 val = mStarts; 2725 if (which == STATS_CURRENT) { 2726 val -= mLoadedStarts; 2727 } else if (which == STATS_UNPLUGGED) { 2728 val -= mUnpluggedStarts; 2729 } 2730 } 2731 2732 return val; 2733 } 2734 } 2735 2736 public BatteryStatsImpl getBatteryStats() { 2737 return BatteryStatsImpl.this; 2738 } 2739 2740 public void incWakeupsLocked() { 2741 mWakeups++; 2742 } 2743 2744 final Serv newServiceStatsLocked() { 2745 return new Serv(); 2746 } 2747 } 2748 2749 /** 2750 * Retrieve the statistics object for a particular process, creating 2751 * if needed. 2752 */ 2753 public Proc getProcessStatsLocked(String name) { 2754 Proc ps = mProcessStats.get(name); 2755 if (ps == null) { 2756 ps = new Proc(); 2757 mProcessStats.put(name, ps); 2758 } 2759 2760 return ps; 2761 } 2762 2763 /** 2764 * Retrieve the statistics object for a particular service, creating 2765 * if needed. 2766 */ 2767 public Pkg getPackageStatsLocked(String name) { 2768 Pkg ps = mPackageStats.get(name); 2769 if (ps == null) { 2770 ps = new Pkg(); 2771 mPackageStats.put(name, ps); 2772 } 2773 2774 return ps; 2775 } 2776 2777 /** 2778 * Retrieve the statistics object for a particular service, creating 2779 * if needed. 2780 */ 2781 public Pkg.Serv getServiceStatsLocked(String pkg, String serv) { 2782 Pkg ps = getPackageStatsLocked(pkg); 2783 Pkg.Serv ss = ps.mServiceStats.get(serv); 2784 if (ss == null) { 2785 ss = ps.newServiceStatsLocked(); 2786 ps.mServiceStats.put(serv, ss); 2787 } 2788 2789 return ss; 2790 } 2791 2792 public StopwatchTimer getWakeTimerLocked(String name, int type) { 2793 Wakelock wl = mWakelockStats.get(name); 2794 if (wl == null) { 2795 if (mWakelockStats.size() > MAX_WAKELOCKS_PER_UID) { 2796 name = BATCHED_WAKELOCK_NAME; 2797 wl = mWakelockStats.get(name); 2798 } 2799 if (wl == null) { 2800 wl = new Wakelock(); 2801 mWakelockStats.put(name, wl); 2802 } 2803 } 2804 StopwatchTimer t = null; 2805 switch (type) { 2806 case WAKE_TYPE_PARTIAL: 2807 t = wl.mTimerPartial; 2808 if (t == null) { 2809 t = new StopwatchTimer(WAKE_TYPE_PARTIAL, mPartialTimers, mUnpluggables); 2810 wl.mTimerPartial = t; 2811 } 2812 return t; 2813 case WAKE_TYPE_FULL: 2814 t = wl.mTimerFull; 2815 if (t == null) { 2816 t = new StopwatchTimer(WAKE_TYPE_FULL, mFullTimers, mUnpluggables); 2817 wl.mTimerFull = t; 2818 } 2819 return t; 2820 case WAKE_TYPE_WINDOW: 2821 t = wl.mTimerWindow; 2822 if (t == null) { 2823 t = new StopwatchTimer(WAKE_TYPE_WINDOW, mWindowTimers, mUnpluggables); 2824 wl.mTimerWindow = t; 2825 } 2826 return t; 2827 default: 2828 throw new IllegalArgumentException("type=" + type); 2829 } 2830 } 2831 2832 public StopwatchTimer getSensorTimerLocked(int sensor, boolean create) { 2833 Sensor se = mSensorStats.get(sensor); 2834 if (se == null) { 2835 if (!create) { 2836 return null; 2837 } 2838 se = new Sensor(sensor); 2839 mSensorStats.put(sensor, se); 2840 } 2841 StopwatchTimer t = se.mTimer; 2842 if (t != null) { 2843 return t; 2844 } 2845 ArrayList<StopwatchTimer> timers = mSensorTimers.get(sensor); 2846 if (timers == null) { 2847 timers = new ArrayList<StopwatchTimer>(); 2848 mSensorTimers.put(sensor, timers); 2849 } 2850 t = new StopwatchTimer(BatteryStats.SENSOR, timers, mUnpluggables); 2851 se.mTimer = t; 2852 return t; 2853 } 2854 2855 public void noteStartWakeLocked(String name, int type) { 2856 StopwatchTimer t = getWakeTimerLocked(name, type); 2857 if (t != null) { 2858 t.startRunningLocked(BatteryStatsImpl.this); 2859 } 2860 } 2861 2862 public void noteStopWakeLocked(String name, int type) { 2863 StopwatchTimer t = getWakeTimerLocked(name, type); 2864 if (t != null) { 2865 t.stopRunningLocked(BatteryStatsImpl.this); 2866 } 2867 } 2868 2869 public void noteStartSensor(int sensor) { 2870 StopwatchTimer t = getSensorTimerLocked(sensor, true); 2871 if (t != null) { 2872 t.startRunningLocked(BatteryStatsImpl.this); 2873 } 2874 } 2875 2876 public void noteStopSensor(int sensor) { 2877 // Don't create a timer if one doesn't already exist 2878 StopwatchTimer t = getSensorTimerLocked(sensor, false); 2879 if (t != null) { 2880 t.stopRunningLocked(BatteryStatsImpl.this); 2881 } 2882 } 2883 2884 public void noteStartGps() { 2885 StopwatchTimer t = getSensorTimerLocked(Sensor.GPS, true); 2886 if (t != null) { 2887 t.startRunningLocked(BatteryStatsImpl.this); 2888 } 2889 } 2890 2891 public void noteStopGps() { 2892 StopwatchTimer t = getSensorTimerLocked(Sensor.GPS, false); 2893 if (t != null) { 2894 t.stopRunningLocked(BatteryStatsImpl.this); 2895 } 2896 } 2897 2898 public BatteryStatsImpl getBatteryStats() { 2899 return BatteryStatsImpl.this; 2900 } 2901 } 2902 2903 public BatteryStatsImpl(String filename) { 2904 mFile = new JournaledFile(new File(filename), new File(filename + ".tmp")); 2905 mStartCount++; 2906 mScreenOnTimer = new StopwatchTimer(-1, null, mUnpluggables); 2907 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 2908 mScreenBrightnessTimer[i] = new StopwatchTimer(-100-i, null, mUnpluggables); 2909 } 2910 mInputEventCounter = new Counter(mUnpluggables); 2911 mPhoneOnTimer = new StopwatchTimer(-2, null, mUnpluggables); 2912 for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) { 2913 mPhoneSignalStrengthsTimer[i] = new StopwatchTimer(-200-i, null, mUnpluggables); 2914 } 2915 mPhoneSignalScanningTimer = new StopwatchTimer(-200+1, null, mUnpluggables); 2916 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 2917 mPhoneDataConnectionsTimer[i] = new StopwatchTimer(-300-i, null, mUnpluggables); 2918 } 2919 mWifiOnTimer = new StopwatchTimer(-3, null, mUnpluggables); 2920 mWifiRunningTimer = new StopwatchTimer(-4, null, mUnpluggables); 2921 mBluetoothOnTimer = new StopwatchTimer(-5, null, mUnpluggables); 2922 mAudioOnTimer = new StopwatchTimer(-6, null, mUnpluggables); 2923 mOnBattery = mOnBatteryInternal = false; 2924 mTrackBatteryPastUptime = 0; 2925 mTrackBatteryPastRealtime = 0; 2926 mUptimeStart = mTrackBatteryUptimeStart = SystemClock.uptimeMillis() * 1000; 2927 mRealtimeStart = mTrackBatteryRealtimeStart = SystemClock.elapsedRealtime() * 1000; 2928 mUnpluggedBatteryUptime = getBatteryUptimeLocked(mUptimeStart); 2929 mUnpluggedBatteryRealtime = getBatteryRealtimeLocked(mRealtimeStart); 2930 mDischargeStartLevel = 0; 2931 mDischargeCurrentLevel = 0; 2932 } 2933 2934 public BatteryStatsImpl(Parcel p) { 2935 mFile = null; 2936 readFromParcel(p); 2937 } 2938 2939 public void setNumSpeedSteps(int steps) { 2940 if (sNumSpeedSteps == 0) sNumSpeedSteps = steps; 2941 } 2942 2943 public void setRadioScanningTimeout(long timeout) { 2944 if (mPhoneSignalScanningTimer != null) { 2945 mPhoneSignalScanningTimer.setTimeout(timeout); 2946 } 2947 } 2948 2949 @Override 2950 public BatteryHistoryRecord getHistory() { 2951 return mHistory; 2952 } 2953 2954 @Override 2955 public int getStartCount() { 2956 return mStartCount; 2957 } 2958 2959 public boolean isOnBattery() { 2960 return mOnBattery; 2961 } 2962 2963 public void setOnBattery(boolean onBattery, int level) { 2964 synchronized(this) { 2965 updateKernelWakelocksLocked(); 2966 if (mOnBattery != onBattery) { 2967 mOnBattery = mOnBatteryInternal = onBattery; 2968 2969 long uptime = SystemClock.uptimeMillis() * 1000; 2970 long mSecRealtime = SystemClock.elapsedRealtime(); 2971 long realtime = mSecRealtime * 1000; 2972 if (onBattery) { 2973 clearHistory(); 2974 mHistoryCur.batteryLevel = (byte)level; 2975 mHistoryCur.states &= ~BatteryHistoryRecord.STATE_BATTERY_PLUGGED_FLAG; 2976 if (DEBUG_HISTORY) Slog.v(TAG, "Battery unplugged to: " 2977 + Integer.toHexString(mHistoryCur.states)); 2978 addHistoryRecord(mSecRealtime); 2979 mTrackBatteryUptimeStart = uptime; 2980 mTrackBatteryRealtimeStart = realtime; 2981 mUnpluggedBatteryUptime = getBatteryUptimeLocked(uptime); 2982 mUnpluggedBatteryRealtime = getBatteryRealtimeLocked(realtime); 2983 mDischargeCurrentLevel = mDischargeStartLevel = level; 2984 doUnplug(mUnpluggedBatteryUptime, mUnpluggedBatteryRealtime); 2985 } else { 2986 mHistoryCur.batteryLevel = (byte)level; 2987 mHistoryCur.states |= BatteryHistoryRecord.STATE_BATTERY_PLUGGED_FLAG; 2988 if (DEBUG_HISTORY) Slog.v(TAG, "Battery plugged to: " 2989 + Integer.toHexString(mHistoryCur.states)); 2990 addHistoryRecord(mSecRealtime); 2991 mTrackBatteryPastUptime += uptime - mTrackBatteryUptimeStart; 2992 mTrackBatteryPastRealtime += realtime - mTrackBatteryRealtimeStart; 2993 mDischargeCurrentLevel = level; 2994 doPlug(getBatteryUptimeLocked(uptime), getBatteryRealtimeLocked(realtime)); 2995 } 2996 if ((mLastWriteTime + (60 * 1000)) < mSecRealtime) { 2997 if (mFile != null) { 2998 writeLocked(); 2999 } 3000 } 3001 } 3002 } 3003 } 3004 3005 public void recordCurrentLevel(int level) { 3006 if (mDischargeCurrentLevel != level) { 3007 mDischargeCurrentLevel = level; 3008 mHistoryCur.batteryLevel = (byte)level; 3009 addHistoryRecord(SystemClock.elapsedRealtime()); 3010 } 3011 } 3012 3013 public void updateKernelWakelocksLocked() { 3014 Map<String, KernelWakelockStats> m = readKernelWakelockStats(); 3015 3016 if (m == null) { 3017 // Not crashing might make board bringup easier. 3018 Slog.w(TAG, "Couldn't get kernel wake lock stats"); 3019 return; 3020 } 3021 3022 for (Map.Entry<String, KernelWakelockStats> ent : m.entrySet()) { 3023 String name = ent.getKey(); 3024 KernelWakelockStats kws = ent.getValue(); 3025 3026 SamplingTimer kwlt = mKernelWakelockStats.get(name); 3027 if (kwlt == null) { 3028 kwlt = new SamplingTimer(mUnpluggables, mOnBatteryInternal, 3029 true /* track reported values */); 3030 mKernelWakelockStats.put(name, kwlt); 3031 } 3032 kwlt.updateCurrentReportedCount(kws.mCount); 3033 kwlt.updateCurrentReportedTotalTime(kws.mTotalTime); 3034 kwlt.setUpdateVersion(sKernelWakelockUpdateVersion); 3035 } 3036 3037 if (m.size() != mKernelWakelockStats.size()) { 3038 // Set timers to stale if they didn't appear in /proc/wakelocks this time. 3039 for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) { 3040 SamplingTimer st = ent.getValue(); 3041 if (st.getUpdateVersion() != sKernelWakelockUpdateVersion) { 3042 st.setStale(); 3043 } 3044 } 3045 } 3046 } 3047 3048 public long getAwakeTimeBattery() { 3049 return computeBatteryUptime(getBatteryUptimeLocked(), STATS_CURRENT); 3050 } 3051 3052 public long getAwakeTimePlugged() { 3053 return (SystemClock.uptimeMillis() * 1000) - getAwakeTimeBattery(); 3054 } 3055 3056 @Override 3057 public long computeUptime(long curTime, int which) { 3058 switch (which) { 3059 case STATS_TOTAL: return mUptime + (curTime-mUptimeStart); 3060 case STATS_LAST: return mLastUptime; 3061 case STATS_CURRENT: return (curTime-mUptimeStart); 3062 case STATS_UNPLUGGED: return (curTime-mTrackBatteryUptimeStart); 3063 } 3064 return 0; 3065 } 3066 3067 @Override 3068 public long computeRealtime(long curTime, int which) { 3069 switch (which) { 3070 case STATS_TOTAL: return mRealtime + (curTime-mRealtimeStart); 3071 case STATS_LAST: return mLastRealtime; 3072 case STATS_CURRENT: return (curTime-mRealtimeStart); 3073 case STATS_UNPLUGGED: return (curTime-mTrackBatteryRealtimeStart); 3074 } 3075 return 0; 3076 } 3077 3078 @Override 3079 public long computeBatteryUptime(long curTime, int which) { 3080 switch (which) { 3081 case STATS_TOTAL: 3082 return mBatteryUptime + getBatteryUptime(curTime); 3083 case STATS_LAST: 3084 return mBatteryLastUptime; 3085 case STATS_CURRENT: 3086 return getBatteryUptime(curTime); 3087 case STATS_UNPLUGGED: 3088 return getBatteryUptimeLocked(curTime) - mUnpluggedBatteryUptime; 3089 } 3090 return 0; 3091 } 3092 3093 @Override 3094 public long computeBatteryRealtime(long curTime, int which) { 3095 switch (which) { 3096 case STATS_TOTAL: 3097 return mBatteryRealtime + getBatteryRealtimeLocked(curTime); 3098 case STATS_LAST: 3099 return mBatteryLastRealtime; 3100 case STATS_CURRENT: 3101 return getBatteryRealtimeLocked(curTime); 3102 case STATS_UNPLUGGED: 3103 return getBatteryRealtimeLocked(curTime) - mUnpluggedBatteryRealtime; 3104 } 3105 return 0; 3106 } 3107 3108 long getBatteryUptimeLocked(long curTime) { 3109 long time = mTrackBatteryPastUptime; 3110 if (mOnBatteryInternal) { 3111 time += curTime - mTrackBatteryUptimeStart; 3112 } 3113 return time; 3114 } 3115 3116 long getBatteryUptimeLocked() { 3117 return getBatteryUptime(SystemClock.uptimeMillis() * 1000); 3118 } 3119 3120 @Override 3121 public long getBatteryUptime(long curTime) { 3122 return getBatteryUptimeLocked(curTime); 3123 } 3124 3125 long getBatteryRealtimeLocked(long curTime) { 3126 long time = mTrackBatteryPastRealtime; 3127 if (mOnBatteryInternal) { 3128 time += curTime - mTrackBatteryRealtimeStart; 3129 } 3130 return time; 3131 } 3132 3133 @Override 3134 public long getBatteryRealtime(long curTime) { 3135 return getBatteryRealtimeLocked(curTime); 3136 } 3137 3138 private long getTcpBytes(long current, long[] dataBytes, int which) { 3139 if (which == STATS_LAST) { 3140 return dataBytes[STATS_LAST]; 3141 } else { 3142 if (which == STATS_UNPLUGGED) { 3143 if (dataBytes[STATS_UNPLUGGED] < 0) { 3144 return dataBytes[STATS_LAST]; 3145 } else { 3146 return current - dataBytes[STATS_UNPLUGGED]; 3147 } 3148 } else if (which == STATS_TOTAL) { 3149 return (current - dataBytes[STATS_CURRENT]) + dataBytes[STATS_TOTAL]; 3150 } 3151 return current - dataBytes[STATS_CURRENT]; 3152 } 3153 } 3154 3155 /** Only STATS_UNPLUGGED works properly */ 3156 public long getMobileTcpBytesSent(int which) { 3157 return getTcpBytes(TrafficStats.getMobileTxBytes(), mMobileDataTx, which); 3158 } 3159 3160 /** Only STATS_UNPLUGGED works properly */ 3161 public long getMobileTcpBytesReceived(int which) { 3162 return getTcpBytes(TrafficStats.getMobileRxBytes(), mMobileDataRx, which); 3163 } 3164 3165 /** Only STATS_UNPLUGGED works properly */ 3166 public long getTotalTcpBytesSent(int which) { 3167 return getTcpBytes(TrafficStats.getTotalTxBytes(), mTotalDataTx, which); 3168 } 3169 3170 /** Only STATS_UNPLUGGED works properly */ 3171 public long getTotalTcpBytesReceived(int which) { 3172 return getTcpBytes(TrafficStats.getTotalRxBytes(), mTotalDataRx, which); 3173 } 3174 3175 @Override 3176 public int getDischargeStartLevel() { 3177 synchronized(this) { 3178 return getDischargeStartLevelLocked(); 3179 } 3180 } 3181 3182 public int getDischargeStartLevelLocked() { 3183 return mDischargeStartLevel; 3184 } 3185 3186 @Override 3187 public int getDischargeCurrentLevel() { 3188 synchronized(this) { 3189 return getDischargeCurrentLevelLocked(); 3190 } 3191 } 3192 3193 public int getDischargeCurrentLevelLocked() { 3194 return mDischargeCurrentLevel; 3195 } 3196 3197 @Override 3198 public int getCpuSpeedSteps() { 3199 return sNumSpeedSteps; 3200 } 3201 3202 /** 3203 * Retrieve the statistics object for a particular uid, creating if needed. 3204 */ 3205 public Uid getUidStatsLocked(int uid) { 3206 Uid u = mUidStats.get(uid); 3207 if (u == null) { 3208 u = new Uid(uid); 3209 mUidStats.put(uid, u); 3210 } 3211 return u; 3212 } 3213 3214 /** 3215 * Remove the statistics object for a particular uid. 3216 */ 3217 public void removeUidStatsLocked(int uid) { 3218 mUidStats.remove(uid); 3219 } 3220 3221 /** 3222 * Retrieve the statistics object for a particular process, creating 3223 * if needed. 3224 */ 3225 public Uid.Proc getProcessStatsLocked(int uid, String name) { 3226 Uid u = getUidStatsLocked(uid); 3227 return u.getProcessStatsLocked(name); 3228 } 3229 3230 /** 3231 * Retrieve the statistics object for a particular process, given 3232 * the name of the process. 3233 * @param name process name 3234 * @return the statistics object for the process 3235 */ 3236 public Uid.Proc getProcessStatsLocked(String name, int pid) { 3237 int uid; 3238 if (mUidCache.containsKey(name)) { 3239 uid = mUidCache.get(name); 3240 } else { 3241 uid = Process.getUidForPid(pid); 3242 mUidCache.put(name, uid); 3243 } 3244 Uid u = getUidStatsLocked(uid); 3245 return u.getProcessStatsLocked(name); 3246 } 3247 3248 /** 3249 * Retrieve the statistics object for a particular process, creating 3250 * if needed. 3251 */ 3252 public Uid.Pkg getPackageStatsLocked(int uid, String pkg) { 3253 Uid u = getUidStatsLocked(uid); 3254 return u.getPackageStatsLocked(pkg); 3255 } 3256 3257 /** 3258 * Retrieve the statistics object for a particular service, creating 3259 * if needed. 3260 */ 3261 public Uid.Pkg.Serv getServiceStatsLocked(int uid, String pkg, String name) { 3262 Uid u = getUidStatsLocked(uid); 3263 return u.getServiceStatsLocked(pkg, name); 3264 } 3265 3266 private static JournaledFile makeJournaledFile() { 3267 final String base = "/data/system/device_policies.xml"; 3268 return new JournaledFile(new File(base), new File(base + ".tmp")); 3269 } 3270 3271 public void writeLocked() { 3272 if (mFile == null) { 3273 Slog.w("BatteryStats", "writeLocked: no file associated with this instance"); 3274 return; 3275 } 3276 3277 try { 3278 FileOutputStream stream = new FileOutputStream(mFile.chooseForWrite()); 3279 Parcel out = Parcel.obtain(); 3280 writeSummaryToParcel(out); 3281 stream.write(out.marshall()); 3282 out.recycle(); 3283 3284 stream.flush(); 3285 stream.close(); 3286 mFile.commit(); 3287 3288 mLastWriteTime = SystemClock.elapsedRealtime(); 3289 return; 3290 } catch (IOException e) { 3291 Slog.w("BatteryStats", "Error writing battery statistics", e); 3292 } 3293 mFile.rollback(); 3294 } 3295 3296 static byte[] readFully(FileInputStream stream) throws java.io.IOException { 3297 int pos = 0; 3298 int avail = stream.available(); 3299 byte[] data = new byte[avail]; 3300 while (true) { 3301 int amt = stream.read(data, pos, data.length-pos); 3302 //Log.i("foo", "Read " + amt + " bytes at " + pos 3303 // + " of avail " + data.length); 3304 if (amt <= 0) { 3305 //Log.i("foo", "**** FINISHED READING: pos=" + pos 3306 // + " len=" + data.length); 3307 return data; 3308 } 3309 pos += amt; 3310 avail = stream.available(); 3311 if (avail > data.length-pos) { 3312 byte[] newData = new byte[pos+avail]; 3313 System.arraycopy(data, 0, newData, 0, pos); 3314 data = newData; 3315 } 3316 } 3317 } 3318 3319 public void readLocked() { 3320 if (mFile == null) { 3321 Slog.w("BatteryStats", "readLocked: no file associated with this instance"); 3322 return; 3323 } 3324 3325 mUidStats.clear(); 3326 3327 try { 3328 File file = mFile.chooseForRead(); 3329 if (!file.exists()) { 3330 return; 3331 } 3332 FileInputStream stream = new FileInputStream(file); 3333 3334 byte[] raw = readFully(stream); 3335 Parcel in = Parcel.obtain(); 3336 in.unmarshall(raw, 0, raw.length); 3337 in.setDataPosition(0); 3338 stream.close(); 3339 3340 readSummaryFromParcel(in); 3341 } catch(java.io.IOException e) { 3342 Slog.e("BatteryStats", "Error reading battery statistics", e); 3343 } 3344 } 3345 3346 public int describeContents() { 3347 return 0; 3348 } 3349 3350 void readHistory(Parcel in) { 3351 mHistory = mHistoryEnd = mHistoryCache = null; 3352 long time; 3353 while ((time=in.readLong()) >= 0) { 3354 BatteryHistoryRecord rec = new BatteryHistoryRecord(time, in); 3355 addHistoryRecord(rec); 3356 } 3357 } 3358 3359 void writeHistory(Parcel out) { 3360 BatteryHistoryRecord rec = mHistory; 3361 while (rec != null) { 3362 if (rec.time >= 0) rec.writeToParcel(out, 0); 3363 rec = rec.next; 3364 } 3365 out.writeLong(-1); 3366 } 3367 3368 private void readSummaryFromParcel(Parcel in) { 3369 final int version = in.readInt(); 3370 if (version != VERSION) { 3371 Slog.w("BatteryStats", "readFromParcel: version got " + version 3372 + ", expected " + VERSION + "; erasing old stats"); 3373 return; 3374 } 3375 3376 readHistory(in); 3377 3378 mStartCount = in.readInt(); 3379 mBatteryUptime = in.readLong(); 3380 mBatteryLastUptime = in.readLong(); 3381 mBatteryRealtime = in.readLong(); 3382 mBatteryLastRealtime = in.readLong(); 3383 mUptime = in.readLong(); 3384 mLastUptime = in.readLong(); 3385 mRealtime = in.readLong(); 3386 mLastRealtime = in.readLong(); 3387 mDischargeStartLevel = in.readInt(); 3388 mDischargeCurrentLevel = in.readInt(); 3389 3390 mStartCount++; 3391 3392 mScreenOn = false; 3393 mScreenOnTimer.readSummaryFromParcelLocked(in); 3394 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 3395 mScreenBrightnessTimer[i].readSummaryFromParcelLocked(in); 3396 } 3397 mInputEventCounter.readSummaryFromParcelLocked(in); 3398 mPhoneOn = false; 3399 mPhoneOnTimer.readSummaryFromParcelLocked(in); 3400 for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) { 3401 mPhoneSignalStrengthsTimer[i].readSummaryFromParcelLocked(in); 3402 } 3403 mPhoneSignalScanningTimer.readSummaryFromParcelLocked(in); 3404 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 3405 mPhoneDataConnectionsTimer[i].readSummaryFromParcelLocked(in); 3406 } 3407 mWifiOn = false; 3408 mWifiOnTimer.readSummaryFromParcelLocked(in); 3409 mWifiRunning = false; 3410 mWifiRunningTimer.readSummaryFromParcelLocked(in); 3411 mBluetoothOn = false; 3412 mBluetoothOnTimer.readSummaryFromParcelLocked(in); 3413 3414 int NKW = in.readInt(); 3415 if (NKW > 10000) { 3416 Slog.w(TAG, "File corrupt: too many kernel wake locks " + NKW); 3417 return; 3418 } 3419 for (int ikw = 0; ikw < NKW; ikw++) { 3420 if (in.readInt() != 0) { 3421 String kwltName = in.readString(); 3422 getKernelWakelockTimerLocked(kwltName).readSummaryFromParcelLocked(in); 3423 } 3424 } 3425 3426 sNumSpeedSteps = in.readInt(); 3427 3428 final int NU = in.readInt(); 3429 if (NU > 10000) { 3430 Slog.w(TAG, "File corrupt: too many uids " + NU); 3431 return; 3432 } 3433 for (int iu = 0; iu < NU; iu++) { 3434 int uid = in.readInt(); 3435 Uid u = new Uid(uid); 3436 mUidStats.put(uid, u); 3437 3438 u.mWifiTurnedOn = false; 3439 u.mWifiTurnedOnTimer.readSummaryFromParcelLocked(in); 3440 u.mFullWifiLockOut = false; 3441 u.mFullWifiLockTimer.readSummaryFromParcelLocked(in); 3442 u.mAudioTurnedOn = false; 3443 u.mAudioTurnedOnTimer.readSummaryFromParcelLocked(in); 3444 u.mVideoTurnedOn = false; 3445 u.mVideoTurnedOnTimer.readSummaryFromParcelLocked(in); 3446 u.mScanWifiLockOut = false; 3447 u.mScanWifiLockTimer.readSummaryFromParcelLocked(in); 3448 u.mWifiMulticastEnabled = false; 3449 u.mWifiMulticastTimer.readSummaryFromParcelLocked(in); 3450 3451 if (in.readInt() != 0) { 3452 if (u.mUserActivityCounters == null) { 3453 u.initUserActivityLocked(); 3454 } 3455 for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) { 3456 u.mUserActivityCounters[i].readSummaryFromParcelLocked(in); 3457 } 3458 } 3459 3460 int NW = in.readInt(); 3461 if (NW > 10000) { 3462 Slog.w(TAG, "File corrupt: too many wake locks " + NW); 3463 return; 3464 } 3465 for (int iw = 0; iw < NW; iw++) { 3466 String wlName = in.readString(); 3467 if (in.readInt() != 0) { 3468 u.getWakeTimerLocked(wlName, WAKE_TYPE_FULL).readSummaryFromParcelLocked(in); 3469 } 3470 if (in.readInt() != 0) { 3471 u.getWakeTimerLocked(wlName, WAKE_TYPE_PARTIAL).readSummaryFromParcelLocked(in); 3472 } 3473 if (in.readInt() != 0) { 3474 u.getWakeTimerLocked(wlName, WAKE_TYPE_WINDOW).readSummaryFromParcelLocked(in); 3475 } 3476 } 3477 3478 int NP = in.readInt(); 3479 if (NP > 10000) { 3480 Slog.w(TAG, "File corrupt: too many sensors " + NP); 3481 return; 3482 } 3483 for (int is = 0; is < NP; is++) { 3484 int seNumber = in.readInt(); 3485 if (in.readInt() != 0) { 3486 u.getSensorTimerLocked(seNumber, true) 3487 .readSummaryFromParcelLocked(in); 3488 } 3489 } 3490 3491 NP = in.readInt(); 3492 if (NP > 10000) { 3493 Slog.w(TAG, "File corrupt: too many processes " + NP); 3494 return; 3495 } 3496 for (int ip = 0; ip < NP; ip++) { 3497 String procName = in.readString(); 3498 Uid.Proc p = u.getProcessStatsLocked(procName); 3499 p.mUserTime = p.mLoadedUserTime = in.readLong(); 3500 p.mLastUserTime = in.readLong(); 3501 p.mSystemTime = p.mLoadedSystemTime = in.readLong(); 3502 p.mLastSystemTime = in.readLong(); 3503 p.mStarts = p.mLoadedStarts = in.readInt(); 3504 p.mLastStarts = in.readInt(); 3505 } 3506 3507 NP = in.readInt(); 3508 if (NP > 10000) { 3509 Slog.w(TAG, "File corrupt: too many packages " + NP); 3510 return; 3511 } 3512 for (int ip = 0; ip < NP; ip++) { 3513 String pkgName = in.readString(); 3514 Uid.Pkg p = u.getPackageStatsLocked(pkgName); 3515 p.mWakeups = p.mLoadedWakeups = in.readInt(); 3516 p.mLastWakeups = in.readInt(); 3517 final int NS = in.readInt(); 3518 for (int is = 0; is < NS; is++) { 3519 String servName = in.readString(); 3520 Uid.Pkg.Serv s = u.getServiceStatsLocked(pkgName, servName); 3521 s.mStartTime = s.mLoadedStartTime = in.readLong(); 3522 s.mLastStartTime = in.readLong(); 3523 s.mStarts = s.mLoadedStarts = in.readInt(); 3524 s.mLastStarts = in.readInt(); 3525 s.mLaunches = s.mLoadedLaunches = in.readInt(); 3526 s.mLastLaunches = in.readInt(); 3527 } 3528 } 3529 3530 u.mLoadedTcpBytesReceived = in.readLong(); 3531 u.mLoadedTcpBytesSent = in.readLong(); 3532 } 3533 } 3534 3535 /** 3536 * Writes a summary of the statistics to a Parcel, in a format suitable to be written to 3537 * disk. This format does not allow a lossless round-trip. 3538 * 3539 * @param out the Parcel to be written to. 3540 */ 3541 public void writeSummaryToParcel(Parcel out) { 3542 final long NOW_SYS = SystemClock.uptimeMillis() * 1000; 3543 final long NOWREAL_SYS = SystemClock.elapsedRealtime() * 1000; 3544 final long NOW = getBatteryUptimeLocked(NOW_SYS); 3545 final long NOWREAL = getBatteryRealtimeLocked(NOWREAL_SYS); 3546 3547 out.writeInt(VERSION); 3548 3549 writeHistory(out); 3550 3551 out.writeInt(mStartCount); 3552 out.writeLong(computeBatteryUptime(NOW_SYS, STATS_TOTAL)); 3553 out.writeLong(computeBatteryUptime(NOW_SYS, STATS_CURRENT)); 3554 out.writeLong(computeBatteryRealtime(NOWREAL_SYS, STATS_TOTAL)); 3555 out.writeLong(computeBatteryRealtime(NOWREAL_SYS, STATS_CURRENT)); 3556 out.writeLong(computeUptime(NOW_SYS, STATS_TOTAL)); 3557 out.writeLong(computeUptime(NOW_SYS, STATS_CURRENT)); 3558 out.writeLong(computeRealtime(NOWREAL_SYS, STATS_TOTAL)); 3559 out.writeLong(computeRealtime(NOWREAL_SYS, STATS_CURRENT)); 3560 out.writeInt(mDischargeStartLevel); 3561 out.writeInt(mDischargeCurrentLevel); 3562 3563 3564 mScreenOnTimer.writeSummaryFromParcelLocked(out, NOWREAL); 3565 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 3566 mScreenBrightnessTimer[i].writeSummaryFromParcelLocked(out, NOWREAL); 3567 } 3568 mInputEventCounter.writeSummaryFromParcelLocked(out); 3569 mPhoneOnTimer.writeSummaryFromParcelLocked(out, NOWREAL); 3570 for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) { 3571 mPhoneSignalStrengthsTimer[i].writeSummaryFromParcelLocked(out, NOWREAL); 3572 } 3573 mPhoneSignalScanningTimer.writeSummaryFromParcelLocked(out, NOWREAL); 3574 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 3575 mPhoneDataConnectionsTimer[i].writeSummaryFromParcelLocked(out, NOWREAL); 3576 } 3577 mWifiOnTimer.writeSummaryFromParcelLocked(out, NOWREAL); 3578 mWifiRunningTimer.writeSummaryFromParcelLocked(out, NOWREAL); 3579 mBluetoothOnTimer.writeSummaryFromParcelLocked(out, NOWREAL); 3580 3581 out.writeInt(mKernelWakelockStats.size()); 3582 for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) { 3583 Timer kwlt = ent.getValue(); 3584 if (kwlt != null) { 3585 out.writeInt(1); 3586 out.writeString(ent.getKey()); 3587 ent.getValue().writeSummaryFromParcelLocked(out, NOWREAL); 3588 } else { 3589 out.writeInt(0); 3590 } 3591 } 3592 3593 out.writeInt(sNumSpeedSteps); 3594 final int NU = mUidStats.size(); 3595 out.writeInt(NU); 3596 for (int iu = 0; iu < NU; iu++) { 3597 out.writeInt(mUidStats.keyAt(iu)); 3598 Uid u = mUidStats.valueAt(iu); 3599 3600 u.mWifiTurnedOnTimer.writeSummaryFromParcelLocked(out, NOWREAL); 3601 u.mFullWifiLockTimer.writeSummaryFromParcelLocked(out, NOWREAL); 3602 u.mAudioTurnedOnTimer.writeSummaryFromParcelLocked(out, NOWREAL); 3603 u.mVideoTurnedOnTimer.writeSummaryFromParcelLocked(out, NOWREAL); 3604 u.mScanWifiLockTimer.writeSummaryFromParcelLocked(out, NOWREAL); 3605 u.mWifiMulticastTimer.writeSummaryFromParcelLocked(out, NOWREAL); 3606 3607 if (u.mUserActivityCounters == null) { 3608 out.writeInt(0); 3609 } else { 3610 out.writeInt(1); 3611 for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) { 3612 u.mUserActivityCounters[i].writeSummaryFromParcelLocked(out); 3613 } 3614 } 3615 3616 int NW = u.mWakelockStats.size(); 3617 out.writeInt(NW); 3618 if (NW > 0) { 3619 for (Map.Entry<String, BatteryStatsImpl.Uid.Wakelock> ent 3620 : u.mWakelockStats.entrySet()) { 3621 out.writeString(ent.getKey()); 3622 Uid.Wakelock wl = ent.getValue(); 3623 if (wl.mTimerFull != null) { 3624 out.writeInt(1); 3625 wl.mTimerFull.writeSummaryFromParcelLocked(out, NOWREAL); 3626 } else { 3627 out.writeInt(0); 3628 } 3629 if (wl.mTimerPartial != null) { 3630 out.writeInt(1); 3631 wl.mTimerPartial.writeSummaryFromParcelLocked(out, NOWREAL); 3632 } else { 3633 out.writeInt(0); 3634 } 3635 if (wl.mTimerWindow != null) { 3636 out.writeInt(1); 3637 wl.mTimerWindow.writeSummaryFromParcelLocked(out, NOWREAL); 3638 } else { 3639 out.writeInt(0); 3640 } 3641 } 3642 } 3643 3644 int NSE = u.mSensorStats.size(); 3645 out.writeInt(NSE); 3646 if (NSE > 0) { 3647 for (Map.Entry<Integer, BatteryStatsImpl.Uid.Sensor> ent 3648 : u.mSensorStats.entrySet()) { 3649 out.writeInt(ent.getKey()); 3650 Uid.Sensor se = ent.getValue(); 3651 if (se.mTimer != null) { 3652 out.writeInt(1); 3653 se.mTimer.writeSummaryFromParcelLocked(out, NOWREAL); 3654 } else { 3655 out.writeInt(0); 3656 } 3657 } 3658 } 3659 3660 int NP = u.mProcessStats.size(); 3661 out.writeInt(NP); 3662 if (NP > 0) { 3663 for (Map.Entry<String, BatteryStatsImpl.Uid.Proc> ent 3664 : u.mProcessStats.entrySet()) { 3665 out.writeString(ent.getKey()); 3666 Uid.Proc ps = ent.getValue(); 3667 out.writeLong(ps.mUserTime); 3668 out.writeLong(ps.mUserTime - ps.mLoadedUserTime); 3669 out.writeLong(ps.mSystemTime); 3670 out.writeLong(ps.mSystemTime - ps.mLoadedSystemTime); 3671 out.writeInt(ps.mStarts); 3672 out.writeInt(ps.mStarts - ps.mLoadedStarts); 3673 } 3674 } 3675 3676 NP = u.mPackageStats.size(); 3677 out.writeInt(NP); 3678 if (NP > 0) { 3679 for (Map.Entry<String, BatteryStatsImpl.Uid.Pkg> ent 3680 : u.mPackageStats.entrySet()) { 3681 out.writeString(ent.getKey()); 3682 Uid.Pkg ps = ent.getValue(); 3683 out.writeInt(ps.mWakeups); 3684 out.writeInt(ps.mWakeups - ps.mLoadedWakeups); 3685 final int NS = ps.mServiceStats.size(); 3686 out.writeInt(NS); 3687 if (NS > 0) { 3688 for (Map.Entry<String, BatteryStatsImpl.Uid.Pkg.Serv> sent 3689 : ps.mServiceStats.entrySet()) { 3690 out.writeString(sent.getKey()); 3691 BatteryStatsImpl.Uid.Pkg.Serv ss = sent.getValue(); 3692 long time = ss.getStartTimeToNowLocked(NOW); 3693 out.writeLong(time); 3694 out.writeLong(time - ss.mLoadedStartTime); 3695 out.writeInt(ss.mStarts); 3696 out.writeInt(ss.mStarts - ss.mLoadedStarts); 3697 out.writeInt(ss.mLaunches); 3698 out.writeInt(ss.mLaunches - ss.mLoadedLaunches); 3699 } 3700 } 3701 } 3702 } 3703 3704 out.writeLong(u.getTcpBytesReceived(STATS_TOTAL)); 3705 out.writeLong(u.getTcpBytesSent(STATS_TOTAL)); 3706 } 3707 } 3708 3709 public void readFromParcel(Parcel in) { 3710 readFromParcelLocked(in); 3711 } 3712 3713 void readFromParcelLocked(Parcel in) { 3714 int magic = in.readInt(); 3715 if (magic != MAGIC) { 3716 throw new ParcelFormatException("Bad magic number"); 3717 } 3718 3719 readHistory(in); 3720 3721 mStartCount = in.readInt(); 3722 mBatteryUptime = in.readLong(); 3723 mBatteryLastUptime = in.readLong(); 3724 mBatteryRealtime = in.readLong(); 3725 mBatteryLastRealtime = in.readLong(); 3726 mScreenOn = false; 3727 mScreenOnTimer = new StopwatchTimer(-1, null, mUnpluggables, in); 3728 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 3729 mScreenBrightnessTimer[i] = new StopwatchTimer(-100-i, null, mUnpluggables, in); 3730 } 3731 mInputEventCounter = new Counter(mUnpluggables, in); 3732 mPhoneOn = false; 3733 mPhoneOnTimer = new StopwatchTimer(-2, null, mUnpluggables, in); 3734 for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) { 3735 mPhoneSignalStrengthsTimer[i] = new StopwatchTimer(-200-i, null, mUnpluggables, in); 3736 } 3737 mPhoneSignalScanningTimer = new StopwatchTimer(-200+1, null, mUnpluggables, in); 3738 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 3739 mPhoneDataConnectionsTimer[i] = new StopwatchTimer(-300-i, null, mUnpluggables, in); 3740 } 3741 mWifiOn = false; 3742 mWifiOnTimer = new StopwatchTimer(-2, null, mUnpluggables, in); 3743 mWifiRunning = false; 3744 mWifiRunningTimer = new StopwatchTimer(-2, null, mUnpluggables, in); 3745 mBluetoothOn = false; 3746 mBluetoothOnTimer = new StopwatchTimer(-2, null, mUnpluggables, in); 3747 mUptime = in.readLong(); 3748 mUptimeStart = in.readLong(); 3749 mLastUptime = in.readLong(); 3750 mRealtime = in.readLong(); 3751 mRealtimeStart = in.readLong(); 3752 mLastRealtime = in.readLong(); 3753 mOnBattery = in.readInt() != 0; 3754 mOnBatteryInternal = false; // we are no longer really running. 3755 mTrackBatteryPastUptime = in.readLong(); 3756 mTrackBatteryUptimeStart = in.readLong(); 3757 mTrackBatteryPastRealtime = in.readLong(); 3758 mTrackBatteryRealtimeStart = in.readLong(); 3759 mUnpluggedBatteryUptime = in.readLong(); 3760 mUnpluggedBatteryRealtime = in.readLong(); 3761 mDischargeStartLevel = in.readInt(); 3762 mDischargeCurrentLevel = in.readInt(); 3763 mLastWriteTime = in.readLong(); 3764 3765 mMobileDataRx[STATS_LAST] = in.readLong(); 3766 mMobileDataRx[STATS_UNPLUGGED] = -1; 3767 mMobileDataTx[STATS_LAST] = in.readLong(); 3768 mMobileDataTx[STATS_UNPLUGGED] = -1; 3769 mTotalDataRx[STATS_LAST] = in.readLong(); 3770 mTotalDataRx[STATS_UNPLUGGED] = -1; 3771 mTotalDataTx[STATS_LAST] = in.readLong(); 3772 mTotalDataTx[STATS_UNPLUGGED] = -1; 3773 3774 mRadioDataUptime = in.readLong(); 3775 mRadioDataStart = -1; 3776 3777 mBluetoothPingCount = in.readInt(); 3778 mBluetoothPingStart = -1; 3779 3780 mKernelWakelockStats.clear(); 3781 int NKW = in.readInt(); 3782 for (int ikw = 0; ikw < NKW; ikw++) { 3783 if (in.readInt() != 0) { 3784 String wakelockName = in.readString(); 3785 in.readInt(); // Extra 0/1 written by Timer.writeTimerToParcel 3786 SamplingTimer kwlt = new SamplingTimer(mUnpluggables, mOnBattery, in); 3787 mKernelWakelockStats.put(wakelockName, kwlt); 3788 } 3789 } 3790 3791 mPartialTimers.clear(); 3792 mFullTimers.clear(); 3793 mWindowTimers.clear(); 3794 3795 sNumSpeedSteps = in.readInt(); 3796 3797 int numUids = in.readInt(); 3798 mUidStats.clear(); 3799 for (int i = 0; i < numUids; i++) { 3800 int uid = in.readInt(); 3801 Uid u = new Uid(uid); 3802 u.readFromParcelLocked(mUnpluggables, in); 3803 mUidStats.append(uid, u); 3804 } 3805 } 3806 3807 public void writeToParcel(Parcel out, int flags) { 3808 writeToParcelLocked(out, flags); 3809 } 3810 3811 @SuppressWarnings("unused") 3812 void writeToParcelLocked(Parcel out, int flags) { 3813 final long uSecUptime = SystemClock.uptimeMillis() * 1000; 3814 final long uSecRealtime = SystemClock.elapsedRealtime() * 1000; 3815 final long batteryUptime = getBatteryUptimeLocked(uSecUptime); 3816 final long batteryRealtime = getBatteryRealtimeLocked(uSecRealtime); 3817 3818 out.writeInt(MAGIC); 3819 3820 writeHistory(out); 3821 3822 out.writeInt(mStartCount); 3823 out.writeLong(mBatteryUptime); 3824 out.writeLong(mBatteryLastUptime); 3825 out.writeLong(mBatteryRealtime); 3826 out.writeLong(mBatteryLastRealtime); 3827 mScreenOnTimer.writeToParcel(out, batteryRealtime); 3828 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 3829 mScreenBrightnessTimer[i].writeToParcel(out, batteryRealtime); 3830 } 3831 mInputEventCounter.writeToParcel(out); 3832 mPhoneOnTimer.writeToParcel(out, batteryRealtime); 3833 for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) { 3834 mPhoneSignalStrengthsTimer[i].writeToParcel(out, batteryRealtime); 3835 } 3836 mPhoneSignalScanningTimer.writeToParcel(out, batteryRealtime); 3837 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 3838 mPhoneDataConnectionsTimer[i].writeToParcel(out, batteryRealtime); 3839 } 3840 mWifiOnTimer.writeToParcel(out, batteryRealtime); 3841 mWifiRunningTimer.writeToParcel(out, batteryRealtime); 3842 mBluetoothOnTimer.writeToParcel(out, batteryRealtime); 3843 out.writeLong(mUptime); 3844 out.writeLong(mUptimeStart); 3845 out.writeLong(mLastUptime); 3846 out.writeLong(mRealtime); 3847 out.writeLong(mRealtimeStart); 3848 out.writeLong(mLastRealtime); 3849 out.writeInt(mOnBattery ? 1 : 0); 3850 out.writeLong(batteryUptime); 3851 out.writeLong(mTrackBatteryUptimeStart); 3852 out.writeLong(batteryRealtime); 3853 out.writeLong(mTrackBatteryRealtimeStart); 3854 out.writeLong(mUnpluggedBatteryUptime); 3855 out.writeLong(mUnpluggedBatteryRealtime); 3856 out.writeInt(mDischargeStartLevel); 3857 out.writeInt(mDischargeCurrentLevel); 3858 out.writeLong(mLastWriteTime); 3859 3860 out.writeLong(getMobileTcpBytesReceived(STATS_UNPLUGGED)); 3861 out.writeLong(getMobileTcpBytesSent(STATS_UNPLUGGED)); 3862 out.writeLong(getTotalTcpBytesReceived(STATS_UNPLUGGED)); 3863 out.writeLong(getTotalTcpBytesSent(STATS_UNPLUGGED)); 3864 3865 // Write radio uptime for data 3866 out.writeLong(getRadioDataUptime()); 3867 3868 out.writeInt(getBluetoothPingCount()); 3869 3870 out.writeInt(mKernelWakelockStats.size()); 3871 for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) { 3872 SamplingTimer kwlt = ent.getValue(); 3873 if (kwlt != null) { 3874 out.writeInt(1); 3875 out.writeString(ent.getKey()); 3876 Timer.writeTimerToParcel(out, kwlt, batteryRealtime); 3877 } else { 3878 out.writeInt(0); 3879 } 3880 } 3881 3882 out.writeInt(sNumSpeedSteps); 3883 3884 int size = mUidStats.size(); 3885 out.writeInt(size); 3886 for (int i = 0; i < size; i++) { 3887 out.writeInt(mUidStats.keyAt(i)); 3888 Uid uid = mUidStats.valueAt(i); 3889 3890 uid.writeToParcelLocked(out, batteryRealtime); 3891 } 3892 } 3893 3894 public static final Parcelable.Creator<BatteryStatsImpl> CREATOR = 3895 new Parcelable.Creator<BatteryStatsImpl>() { 3896 public BatteryStatsImpl createFromParcel(Parcel in) { 3897 return new BatteryStatsImpl(in); 3898 } 3899 3900 public BatteryStatsImpl[] newArray(int size) { 3901 return new BatteryStatsImpl[size]; 3902 } 3903 }; 3904 3905 public void dumpLocked(PrintWriter pw) { 3906 if (DEBUG) { 3907 Printer pr = new PrintWriterPrinter(pw); 3908 pr.println("*** Screen timer:"); 3909 mScreenOnTimer.logState(pr, " "); 3910 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 3911 pr.println("*** Screen brightness #" + i + ":"); 3912 mScreenBrightnessTimer[i].logState(pr, " "); 3913 } 3914 pr.println("*** Input event counter:"); 3915 mInputEventCounter.logState(pr, " "); 3916 pr.println("*** Phone timer:"); 3917 mPhoneOnTimer.logState(pr, " "); 3918 for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) { 3919 pr.println("*** Signal strength #" + i + ":"); 3920 mPhoneSignalStrengthsTimer[i].logState(pr, " "); 3921 } 3922 pr.println("*** Signal scanning :"); 3923 mPhoneSignalScanningTimer.logState(pr, " "); 3924 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 3925 pr.println("*** Data connection type #" + i + ":"); 3926 mPhoneDataConnectionsTimer[i].logState(pr, " "); 3927 } 3928 pr.println("*** Wifi timer:"); 3929 mWifiOnTimer.logState(pr, " "); 3930 pr.println("*** WifiRunning timer:"); 3931 mWifiRunningTimer.logState(pr, " "); 3932 pr.println("*** Bluetooth timer:"); 3933 mBluetoothOnTimer.logState(pr, " "); 3934 } 3935 super.dumpLocked(pw); 3936 } 3937} 3938