BatteryStatsImpl.java revision 633a1740ce5951ccb5d478ba2795f6f4fada1646
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 mDischargeStartLevel; 135 int mDischargeCurrentLevel; 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 mDischargeStartLevel = 0; 1951 mDischargeCurrentLevel = 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 mDischargeCurrentLevel = mDischargeStartLevel = level; 1982 doUnplug(mUnpluggedBatteryUptime, mUnpluggedBatteryRealtime); 1983 } else { 1984 mTrackBatteryPastUptime += uptime - mTrackBatteryUptimeStart; 1985 mTrackBatteryPastRealtime += realtime - mTrackBatteryRealtimeStart; 1986 mDischargeCurrentLevel = 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 void recordCurrentLevel(int level) { 1999 mDischargeCurrentLevel = level; 2000 } 2001 2002 public long getAwakeTimeBattery() { 2003 return computeBatteryUptime(getBatteryUptimeLocked(), STATS_CURRENT); 2004 } 2005 2006 public long getAwakeTimePlugged() { 2007 return (SystemClock.uptimeMillis() * 1000) - getAwakeTimeBattery(); 2008 } 2009 2010 @Override 2011 public long computeUptime(long curTime, int which) { 2012 switch (which) { 2013 case STATS_TOTAL: return mUptime + (curTime-mUptimeStart); 2014 case STATS_LAST: return mLastUptime; 2015 case STATS_CURRENT: return (curTime-mUptimeStart); 2016 case STATS_UNPLUGGED: return (curTime-mTrackBatteryUptimeStart); 2017 } 2018 return 0; 2019 } 2020 2021 @Override 2022 public long computeRealtime(long curTime, int which) { 2023 switch (which) { 2024 case STATS_TOTAL: return mRealtime + (curTime-mRealtimeStart); 2025 case STATS_LAST: return mLastRealtime; 2026 case STATS_CURRENT: return (curTime-mRealtimeStart); 2027 case STATS_UNPLUGGED: return (curTime-mTrackBatteryRealtimeStart); 2028 } 2029 return 0; 2030 } 2031 2032 @Override 2033 public long computeBatteryUptime(long curTime, int which) { 2034 switch (which) { 2035 case STATS_TOTAL: 2036 return mBatteryUptime + getBatteryUptime(curTime); 2037 case STATS_LAST: 2038 return mBatteryLastUptime; 2039 case STATS_CURRENT: 2040 return getBatteryUptime(curTime); 2041 case STATS_UNPLUGGED: 2042 return getBatteryUptimeLocked(curTime) - mUnpluggedBatteryUptime; 2043 } 2044 return 0; 2045 } 2046 2047 @Override 2048 public long computeBatteryRealtime(long curTime, int which) { 2049 switch (which) { 2050 case STATS_TOTAL: 2051 return mBatteryRealtime + getBatteryRealtimeLocked(curTime); 2052 case STATS_LAST: 2053 return mBatteryLastRealtime; 2054 case STATS_CURRENT: 2055 return getBatteryRealtimeLocked(curTime); 2056 case STATS_UNPLUGGED: 2057 return getBatteryRealtimeLocked(curTime) - mUnpluggedBatteryRealtime; 2058 } 2059 return 0; 2060 } 2061 2062 long getBatteryUptimeLocked(long curTime) { 2063 long time = mTrackBatteryPastUptime; 2064 if (mOnBatteryInternal) { 2065 time += curTime - mTrackBatteryUptimeStart; 2066 } 2067 return time; 2068 } 2069 2070 long getBatteryUptimeLocked() { 2071 return getBatteryUptime(SystemClock.uptimeMillis() * 1000); 2072 } 2073 2074 @Override 2075 public long getBatteryUptime(long curTime) { 2076 return getBatteryUptimeLocked(curTime); 2077 } 2078 2079 long getBatteryRealtimeLocked(long curTime) { 2080 long time = mTrackBatteryPastRealtime; 2081 if (mOnBatteryInternal) { 2082 time += curTime - mTrackBatteryRealtimeStart; 2083 } 2084 return time; 2085 } 2086 2087 @Override 2088 public long getBatteryRealtime(long curTime) { 2089 return getBatteryRealtimeLocked(curTime); 2090 } 2091 2092 @Override 2093 public int getDischargeStartLevel() { 2094 synchronized(this) { 2095 return getDischargeStartLevelLocked(); 2096 } 2097 } 2098 2099 public int getDischargeStartLevelLocked() { 2100 return mDischargeStartLevel; 2101 } 2102 2103 @Override 2104 public int getDischargeCurrentLevel() { 2105 synchronized(this) { 2106 return getDischargeCurrentLevelLocked(); 2107 } 2108 } 2109 2110 public int getDischargeCurrentLevelLocked() { 2111 return mDischargeCurrentLevel; 2112 } 2113 2114 /** 2115 * Retrieve the statistics object for a particular uid, creating if needed. 2116 */ 2117 public Uid getUidStatsLocked(int uid) { 2118 Uid u = mUidStats.get(uid); 2119 if (u == null) { 2120 u = new Uid(uid); 2121 mUidStats.put(uid, u); 2122 } 2123 return u; 2124 } 2125 2126 /** 2127 * Remove the statistics object for a particular uid. 2128 */ 2129 public void removeUidStatsLocked(int uid) { 2130 mUidStats.remove(uid); 2131 } 2132 2133 /** 2134 * Retrieve the statistics object for a particular process, creating 2135 * if needed. 2136 */ 2137 public Uid.Proc getProcessStatsLocked(int uid, String name) { 2138 Uid u = getUidStatsLocked(uid); 2139 return u.getProcessStatsLocked(name); 2140 } 2141 2142 /** 2143 * Retrieve the statistics object for a particular process, creating 2144 * if needed. 2145 */ 2146 public Uid.Pkg getPackageStatsLocked(int uid, String pkg) { 2147 Uid u = getUidStatsLocked(uid); 2148 return u.getPackageStatsLocked(pkg); 2149 } 2150 2151 /** 2152 * Retrieve the statistics object for a particular service, creating 2153 * if needed. 2154 */ 2155 public Uid.Pkg.Serv getServiceStatsLocked(int uid, String pkg, String name) { 2156 Uid u = getUidStatsLocked(uid); 2157 return u.getServiceStatsLocked(pkg, name); 2158 } 2159 2160 public void writeLocked() { 2161 if ((mFile == null) || (mBackupFile == null)) { 2162 Log.w("BatteryStats", "writeLocked: no file associated with this instance"); 2163 return; 2164 } 2165 2166 // Keep the old file around until we know the new one has 2167 // been successfully written. 2168 if (mFile.exists()) { 2169 if (mBackupFile.exists()) { 2170 mBackupFile.delete(); 2171 } 2172 mFile.renameTo(mBackupFile); 2173 } 2174 2175 try { 2176 FileOutputStream stream = new FileOutputStream(mFile); 2177 Parcel out = Parcel.obtain(); 2178 writeSummaryToParcel(out); 2179 stream.write(out.marshall()); 2180 out.recycle(); 2181 2182 stream.flush(); 2183 stream.close(); 2184 mBackupFile.delete(); 2185 2186 mLastWriteTime = SystemClock.elapsedRealtime(); 2187 } catch (IOException e) { 2188 Log.e("BatteryStats", "Error writing battery statistics", e); 2189 } 2190 } 2191 2192 static byte[] readFully(FileInputStream stream) throws java.io.IOException { 2193 int pos = 0; 2194 int avail = stream.available(); 2195 byte[] data = new byte[avail]; 2196 while (true) { 2197 int amt = stream.read(data, pos, data.length-pos); 2198 //Log.i("foo", "Read " + amt + " bytes at " + pos 2199 // + " of avail " + data.length); 2200 if (amt <= 0) { 2201 //Log.i("foo", "**** FINISHED READING: pos=" + pos 2202 // + " len=" + data.length); 2203 return data; 2204 } 2205 pos += amt; 2206 avail = stream.available(); 2207 if (avail > data.length-pos) { 2208 byte[] newData = new byte[pos+avail]; 2209 System.arraycopy(data, 0, newData, 0, pos); 2210 data = newData; 2211 } 2212 } 2213 } 2214 2215 public void readLocked() { 2216 if ((mFile == null) || (mBackupFile == null)) { 2217 Log.w("BatteryStats", "readLocked: no file associated with this instance"); 2218 return; 2219 } 2220 2221 mUidStats.clear(); 2222 2223 FileInputStream stream = null; 2224 if (mBackupFile.exists()) { 2225 try { 2226 stream = new FileInputStream(mBackupFile); 2227 } catch (java.io.IOException e) { 2228 // We'll try for the normal settings file. 2229 } 2230 } 2231 2232 try { 2233 if (stream == null) { 2234 if (!mFile.exists()) { 2235 return; 2236 } 2237 stream = new FileInputStream(mFile); 2238 } 2239 2240 byte[] raw = readFully(stream); 2241 Parcel in = Parcel.obtain(); 2242 in.unmarshall(raw, 0, raw.length); 2243 in.setDataPosition(0); 2244 stream.close(); 2245 2246 readSummaryFromParcel(in); 2247 } catch(java.io.IOException e) { 2248 Log.e("BatteryStats", "Error reading battery statistics", e); 2249 } 2250 } 2251 2252 public int describeContents() { 2253 return 0; 2254 } 2255 2256 private void readSummaryFromParcel(Parcel in) { 2257 final int version = in.readInt(); 2258 if (version != VERSION) { 2259 Log.w("BatteryStats", "readFromParcel: version got " + version 2260 + ", expected " + VERSION + "; erasing old stats"); 2261 return; 2262 } 2263 2264 mStartCount = in.readInt(); 2265 mBatteryUptime = in.readLong(); 2266 mBatteryLastUptime = in.readLong(); 2267 mBatteryRealtime = in.readLong(); 2268 mBatteryLastRealtime = in.readLong(); 2269 mUptime = in.readLong(); 2270 mLastUptime = in.readLong(); 2271 mRealtime = in.readLong(); 2272 mLastRealtime = in.readLong(); 2273 mDischargeStartLevel = in.readInt(); 2274 mDischargeCurrentLevel = in.readInt(); 2275 2276 mStartCount++; 2277 2278 mScreenOn = false; 2279 mScreenOnTimer.readSummaryFromParcelLocked(in); 2280 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 2281 mScreenBrightnessTimer[i].readSummaryFromParcelLocked(in); 2282 } 2283 mInputEventCounter.readSummaryFromParcelLocked(in); 2284 mPhoneOn = false; 2285 mPhoneOnTimer.readSummaryFromParcelLocked(in); 2286 for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) { 2287 mPhoneSignalStrengthsTimer[i].readSummaryFromParcelLocked(in); 2288 } 2289 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 2290 mPhoneDataConnectionsTimer[i].readSummaryFromParcelLocked(in); 2291 } 2292 mWifiOn = false; 2293 mWifiOnTimer.readSummaryFromParcelLocked(in); 2294 mWifiRunning = false; 2295 mWifiRunningTimer.readSummaryFromParcelLocked(in); 2296 mBluetoothOn = false; 2297 mBluetoothOnTimer.readSummaryFromParcelLocked(in); 2298 2299 final int NU = in.readInt(); 2300 for (int iu = 0; iu < NU; iu++) { 2301 int uid = in.readInt(); 2302 Uid u = new Uid(uid); 2303 mUidStats.put(uid, u); 2304 2305 u.mWifiTurnedOn = false; 2306 u.mWifiTurnedOnTimer.readSummaryFromParcelLocked(in); 2307 u.mFullWifiLockOut = false; 2308 u.mFullWifiLockTimer.readSummaryFromParcelLocked(in); 2309 u.mScanWifiLockOut = false; 2310 u.mScanWifiLockTimer.readSummaryFromParcelLocked(in); 2311 2312 if (in.readInt() != 0) { 2313 if (u.mUserActivityCounters == null) { 2314 u.initUserActivityLocked(); 2315 } 2316 for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) { 2317 u.mUserActivityCounters[i].readSummaryFromParcelLocked(in); 2318 } 2319 } 2320 2321 int NW = in.readInt(); 2322 for (int iw = 0; iw < NW; iw++) { 2323 String wlName = in.readString(); 2324 if (in.readInt() != 0) { 2325 u.getWakeTimerLocked(wlName, WAKE_TYPE_FULL).readSummaryFromParcelLocked(in); 2326 } 2327 if (in.readInt() != 0) { 2328 u.getWakeTimerLocked(wlName, WAKE_TYPE_PARTIAL).readSummaryFromParcelLocked(in); 2329 } 2330 if (in.readInt() != 0) { 2331 u.getWakeTimerLocked(wlName, WAKE_TYPE_WINDOW).readSummaryFromParcelLocked(in); 2332 } 2333 } 2334 2335 int NP = in.readInt(); 2336 for (int is = 0; is < NP; is++) { 2337 int seNumber = in.readInt(); 2338 if (in.readInt() != 0) { 2339 u.getSensorTimerLocked(seNumber, true) 2340 .readSummaryFromParcelLocked(in); 2341 } 2342 } 2343 2344 NP = in.readInt(); 2345 for (int ip = 0; ip < NP; ip++) { 2346 String procName = in.readString(); 2347 Uid.Proc p = u.getProcessStatsLocked(procName); 2348 p.mUserTime = p.mLoadedUserTime = in.readLong(); 2349 p.mLastUserTime = in.readLong(); 2350 p.mSystemTime = p.mLoadedSystemTime = in.readLong(); 2351 p.mLastSystemTime = in.readLong(); 2352 p.mStarts = p.mLoadedStarts = in.readInt(); 2353 p.mLastStarts = in.readInt(); 2354 } 2355 2356 NP = in.readInt(); 2357 for (int ip = 0; ip < NP; ip++) { 2358 String pkgName = in.readString(); 2359 Uid.Pkg p = u.getPackageStatsLocked(pkgName); 2360 p.mWakeups = p.mLoadedWakeups = in.readInt(); 2361 p.mLastWakeups = in.readInt(); 2362 final int NS = in.readInt(); 2363 for (int is = 0; is < NS; is++) { 2364 String servName = in.readString(); 2365 Uid.Pkg.Serv s = u.getServiceStatsLocked(pkgName, servName); 2366 s.mStartTime = s.mLoadedStartTime = in.readLong(); 2367 s.mLastStartTime = in.readLong(); 2368 s.mStarts = s.mLoadedStarts = in.readInt(); 2369 s.mLastStarts = in.readInt(); 2370 s.mLaunches = s.mLoadedLaunches = in.readInt(); 2371 s.mLastLaunches = in.readInt(); 2372 } 2373 } 2374 2375 u.mLoadedTcpBytesReceived = in.readLong(); 2376 u.mLoadedTcpBytesSent = in.readLong(); 2377 } 2378 } 2379 2380 /** 2381 * Writes a summary of the statistics to a Parcel, in a format suitable to be written to 2382 * disk. This format does not allow a lossless round-trip. 2383 * 2384 * @param out the Parcel to be written to. 2385 */ 2386 public void writeSummaryToParcel(Parcel out) { 2387 final long NOW_SYS = SystemClock.uptimeMillis() * 1000; 2388 final long NOWREAL_SYS = SystemClock.elapsedRealtime() * 1000; 2389 final long NOW = getBatteryUptimeLocked(NOW_SYS); 2390 final long NOWREAL = getBatteryRealtimeLocked(NOWREAL_SYS); 2391 2392 out.writeInt(VERSION); 2393 2394 out.writeInt(mStartCount); 2395 out.writeLong(computeBatteryUptime(NOW_SYS, STATS_TOTAL)); 2396 out.writeLong(computeBatteryUptime(NOW_SYS, STATS_CURRENT)); 2397 out.writeLong(computeBatteryRealtime(NOWREAL_SYS, STATS_TOTAL)); 2398 out.writeLong(computeBatteryRealtime(NOWREAL_SYS, STATS_CURRENT)); 2399 out.writeLong(computeUptime(NOW_SYS, STATS_TOTAL)); 2400 out.writeLong(computeUptime(NOW_SYS, STATS_CURRENT)); 2401 out.writeLong(computeRealtime(NOWREAL_SYS, STATS_TOTAL)); 2402 out.writeLong(computeRealtime(NOWREAL_SYS, STATS_CURRENT)); 2403 out.writeInt(mDischargeStartLevel); 2404 out.writeInt(mDischargeCurrentLevel); 2405 2406 2407 mScreenOnTimer.writeSummaryFromParcelLocked(out, NOWREAL); 2408 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 2409 mScreenBrightnessTimer[i].writeSummaryFromParcelLocked(out, NOWREAL); 2410 } 2411 mInputEventCounter.writeSummaryFromParcelLocked(out); 2412 mPhoneOnTimer.writeSummaryFromParcelLocked(out, NOWREAL); 2413 for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) { 2414 mPhoneSignalStrengthsTimer[i].writeSummaryFromParcelLocked(out, NOWREAL); 2415 } 2416 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 2417 mPhoneDataConnectionsTimer[i].writeSummaryFromParcelLocked(out, NOWREAL); 2418 } 2419 mWifiOnTimer.writeSummaryFromParcelLocked(out, NOWREAL); 2420 mWifiRunningTimer.writeSummaryFromParcelLocked(out, NOWREAL); 2421 mBluetoothOnTimer.writeSummaryFromParcelLocked(out, NOWREAL); 2422 2423 final int NU = mUidStats.size(); 2424 out.writeInt(NU); 2425 for (int iu = 0; iu < NU; iu++) { 2426 out.writeInt(mUidStats.keyAt(iu)); 2427 Uid u = mUidStats.valueAt(iu); 2428 2429 u.mWifiTurnedOnTimer.writeSummaryFromParcelLocked(out, NOWREAL); 2430 u.mFullWifiLockTimer.writeSummaryFromParcelLocked(out, NOWREAL); 2431 u.mScanWifiLockTimer.writeSummaryFromParcelLocked(out, NOWREAL); 2432 2433 if (u.mUserActivityCounters == null) { 2434 out.writeInt(0); 2435 } else { 2436 out.writeInt(1); 2437 for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) { 2438 u.mUserActivityCounters[i].writeSummaryFromParcelLocked(out); 2439 } 2440 } 2441 2442 int NW = u.mWakelockStats.size(); 2443 out.writeInt(NW); 2444 if (NW > 0) { 2445 for (Map.Entry<String, BatteryStatsImpl.Uid.Wakelock> ent 2446 : u.mWakelockStats.entrySet()) { 2447 out.writeString(ent.getKey()); 2448 Uid.Wakelock wl = ent.getValue(); 2449 if (wl.mTimerFull != null) { 2450 out.writeInt(1); 2451 wl.mTimerFull.writeSummaryFromParcelLocked(out, NOWREAL); 2452 } else { 2453 out.writeInt(0); 2454 } 2455 if (wl.mTimerPartial != null) { 2456 out.writeInt(1); 2457 wl.mTimerPartial.writeSummaryFromParcelLocked(out, NOWREAL); 2458 } else { 2459 out.writeInt(0); 2460 } 2461 if (wl.mTimerWindow != null) { 2462 out.writeInt(1); 2463 wl.mTimerWindow.writeSummaryFromParcelLocked(out, NOWREAL); 2464 } else { 2465 out.writeInt(0); 2466 } 2467 } 2468 } 2469 2470 int NSE = u.mSensorStats.size(); 2471 out.writeInt(NSE); 2472 if (NSE > 0) { 2473 for (Map.Entry<Integer, BatteryStatsImpl.Uid.Sensor> ent 2474 : u.mSensorStats.entrySet()) { 2475 out.writeInt(ent.getKey()); 2476 Uid.Sensor se = ent.getValue(); 2477 if (se.mTimer != null) { 2478 out.writeInt(1); 2479 se.mTimer.writeSummaryFromParcelLocked(out, NOWREAL); 2480 } else { 2481 out.writeInt(0); 2482 } 2483 } 2484 } 2485 2486 int NP = u.mProcessStats.size(); 2487 out.writeInt(NP); 2488 if (NP > 0) { 2489 for (Map.Entry<String, BatteryStatsImpl.Uid.Proc> ent 2490 : u.mProcessStats.entrySet()) { 2491 out.writeString(ent.getKey()); 2492 Uid.Proc ps = ent.getValue(); 2493 out.writeLong(ps.mUserTime); 2494 out.writeLong(ps.mUserTime - ps.mLoadedUserTime); 2495 out.writeLong(ps.mSystemTime); 2496 out.writeLong(ps.mSystemTime - ps.mLoadedSystemTime); 2497 out.writeInt(ps.mStarts); 2498 out.writeInt(ps.mStarts - ps.mLoadedStarts); 2499 } 2500 } 2501 2502 NP = u.mPackageStats.size(); 2503 out.writeInt(NP); 2504 if (NP > 0) { 2505 for (Map.Entry<String, BatteryStatsImpl.Uid.Pkg> ent 2506 : u.mPackageStats.entrySet()) { 2507 out.writeString(ent.getKey()); 2508 Uid.Pkg ps = ent.getValue(); 2509 out.writeInt(ps.mWakeups); 2510 out.writeInt(ps.mWakeups - ps.mLoadedWakeups); 2511 final int NS = ps.mServiceStats.size(); 2512 out.writeInt(NS); 2513 if (NS > 0) { 2514 for (Map.Entry<String, BatteryStatsImpl.Uid.Pkg.Serv> sent 2515 : ps.mServiceStats.entrySet()) { 2516 out.writeString(sent.getKey()); 2517 BatteryStatsImpl.Uid.Pkg.Serv ss = sent.getValue(); 2518 long time = ss.getStartTimeToNowLocked(NOW); 2519 out.writeLong(time); 2520 out.writeLong(time - ss.mLoadedStartTime); 2521 out.writeInt(ss.mStarts); 2522 out.writeInt(ss.mStarts - ss.mLoadedStarts); 2523 out.writeInt(ss.mLaunches); 2524 out.writeInt(ss.mLaunches - ss.mLoadedLaunches); 2525 } 2526 } 2527 } 2528 } 2529 2530 out.writeLong(u.getTcpBytesReceived(STATS_TOTAL)); 2531 out.writeLong(u.getTcpBytesSent(STATS_TOTAL)); 2532 } 2533 } 2534 2535 public void readFromParcel(Parcel in) { 2536 readFromParcelLocked(in); 2537 } 2538 2539 void readFromParcelLocked(Parcel in) { 2540 int magic = in.readInt(); 2541 if (magic != MAGIC) { 2542 throw new ParcelFormatException("Bad magic number"); 2543 } 2544 2545 mStartCount = in.readInt(); 2546 mBatteryUptime = in.readLong(); 2547 mBatteryLastUptime = in.readLong(); 2548 mBatteryRealtime = in.readLong(); 2549 mBatteryLastRealtime = in.readLong(); 2550 mScreenOn = false; 2551 mScreenOnTimer = new Timer(-1, null, mUnpluggables, in); 2552 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 2553 mScreenBrightnessTimer[i] = new Timer(-100-i, null, mUnpluggables, in); 2554 } 2555 mInputEventCounter = new Counter(mUnpluggables, in); 2556 mPhoneOn = false; 2557 mPhoneOnTimer = new Timer(-2, null, mUnpluggables, in); 2558 for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) { 2559 mPhoneSignalStrengthsTimer[i] = new Timer(-200-i, null, mUnpluggables, in); 2560 } 2561 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 2562 mPhoneDataConnectionsTimer[i] = new Timer(-300-i, null, mUnpluggables, in); 2563 } 2564 mWifiOn = false; 2565 mWifiOnTimer = new Timer(-2, null, mUnpluggables, in); 2566 mWifiRunning = false; 2567 mWifiRunningTimer = new Timer(-2, null, mUnpluggables, in); 2568 mBluetoothOn = false; 2569 mBluetoothOnTimer = new Timer(-2, null, mUnpluggables, in); 2570 mUptime = in.readLong(); 2571 mUptimeStart = in.readLong(); 2572 mLastUptime = in.readLong(); 2573 mRealtime = in.readLong(); 2574 mRealtimeStart = in.readLong(); 2575 mLastRealtime = in.readLong(); 2576 mOnBattery = in.readInt() != 0; 2577 mOnBatteryInternal = false; // we are no longer really running. 2578 mTrackBatteryPastUptime = in.readLong(); 2579 mTrackBatteryUptimeStart = in.readLong(); 2580 mTrackBatteryPastRealtime = in.readLong(); 2581 mTrackBatteryRealtimeStart = in.readLong(); 2582 mUnpluggedBatteryUptime = in.readLong(); 2583 mUnpluggedBatteryRealtime = in.readLong(); 2584 mDischargeStartLevel = in.readInt(); 2585 mDischargeCurrentLevel = in.readInt(); 2586 mLastWriteTime = in.readLong(); 2587 2588 mPartialTimers.clear(); 2589 mFullTimers.clear(); 2590 mWindowTimers.clear(); 2591 2592 int numUids = in.readInt(); 2593 mUidStats.clear(); 2594 for (int i = 0; i < numUids; i++) { 2595 int uid = in.readInt(); 2596 Uid u = new Uid(uid); 2597 u.readFromParcelLocked(mUnpluggables, in); 2598 mUidStats.append(uid, u); 2599 } 2600 } 2601 2602 public void writeToParcel(Parcel out, int flags) { 2603 writeToParcelLocked(out, flags); 2604 } 2605 2606 @SuppressWarnings("unused") 2607 void writeToParcelLocked(Parcel out, int flags) { 2608 final long uSecUptime = SystemClock.uptimeMillis() * 1000; 2609 final long uSecRealtime = SystemClock.elapsedRealtime() * 1000; 2610 final long batteryUptime = getBatteryUptimeLocked(uSecUptime); 2611 final long batteryRealtime = getBatteryRealtimeLocked(uSecRealtime); 2612 2613 out.writeInt(MAGIC); 2614 out.writeInt(mStartCount); 2615 out.writeLong(mBatteryUptime); 2616 out.writeLong(mBatteryLastUptime); 2617 out.writeLong(mBatteryRealtime); 2618 out.writeLong(mBatteryLastRealtime); 2619 mScreenOnTimer.writeToParcel(out, batteryRealtime); 2620 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 2621 mScreenBrightnessTimer[i].writeToParcel(out, batteryRealtime); 2622 } 2623 mInputEventCounter.writeToParcel(out); 2624 mPhoneOnTimer.writeToParcel(out, batteryRealtime); 2625 for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) { 2626 mPhoneSignalStrengthsTimer[i].writeToParcel(out, batteryRealtime); 2627 } 2628 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 2629 mPhoneDataConnectionsTimer[i].writeToParcel(out, batteryRealtime); 2630 } 2631 mWifiOnTimer.writeToParcel(out, batteryRealtime); 2632 mWifiRunningTimer.writeToParcel(out, batteryRealtime); 2633 mBluetoothOnTimer.writeToParcel(out, batteryRealtime); 2634 out.writeLong(mUptime); 2635 out.writeLong(mUptimeStart); 2636 out.writeLong(mLastUptime); 2637 out.writeLong(mRealtime); 2638 out.writeLong(mRealtimeStart); 2639 out.writeLong(mLastRealtime); 2640 out.writeInt(mOnBattery ? 1 : 0); 2641 out.writeLong(batteryUptime); 2642 out.writeLong(mTrackBatteryUptimeStart); 2643 out.writeLong(batteryRealtime); 2644 out.writeLong(mTrackBatteryRealtimeStart); 2645 out.writeLong(mUnpluggedBatteryUptime); 2646 out.writeLong(mUnpluggedBatteryRealtime); 2647 out.writeInt(mDischargeStartLevel); 2648 out.writeInt(mDischargeCurrentLevel); 2649 out.writeLong(mLastWriteTime); 2650 2651 int size = mUidStats.size(); 2652 out.writeInt(size); 2653 for (int i = 0; i < size; i++) { 2654 out.writeInt(mUidStats.keyAt(i)); 2655 Uid uid = mUidStats.valueAt(i); 2656 2657 uid.writeToParcelLocked(out, batteryRealtime); 2658 } 2659 } 2660 2661 public static final Parcelable.Creator<BatteryStatsImpl> CREATOR = 2662 new Parcelable.Creator<BatteryStatsImpl>() { 2663 public BatteryStatsImpl createFromParcel(Parcel in) { 2664 return new BatteryStatsImpl(in); 2665 } 2666 2667 public BatteryStatsImpl[] newArray(int size) { 2668 return new BatteryStatsImpl[size]; 2669 } 2670 }; 2671 2672 public void dumpLocked(Printer pw) { 2673 if (DEBUG) { 2674 pw.println("*** Screen timer:"); 2675 mScreenOnTimer.logState(pw, " "); 2676 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 2677 pw.println("*** Screen brightness #" + i + ":"); 2678 mScreenBrightnessTimer[i].logState(pw, " "); 2679 } 2680 pw.println("*** Input event counter:"); 2681 mInputEventCounter.logState(pw, " "); 2682 pw.println("*** Phone timer:"); 2683 mPhoneOnTimer.logState(pw, " "); 2684 for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) { 2685 pw.println("*** Signal strength #" + i + ":"); 2686 mPhoneSignalStrengthsTimer[i].logState(pw, " "); 2687 } 2688 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 2689 pw.println("*** Data connection type #" + i + ":"); 2690 mPhoneDataConnectionsTimer[i].logState(pw, " "); 2691 } 2692 pw.println("*** Wifi timer:"); 2693 mWifiOnTimer.logState(pw, " "); 2694 pw.println("*** WifiRunning timer:"); 2695 mWifiRunningTimer.logState(pw, " "); 2696 pw.println("*** Bluetooth timer:"); 2697 mBluetoothOnTimer.logState(pw, " "); 2698 } 2699 super.dumpLocked(pw); 2700 } 2701} 2702