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