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