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