BatteryStatsImpl.java revision 3d658bf20e2d56e36941e7407deebeec1276fbcf
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 static com.android.server.NetworkManagementSocketTagger.PROP_QTAGUID_ENABLED; 20 21import android.bluetooth.BluetoothDevice; 22import android.bluetooth.BluetoothHeadset; 23import android.content.Context; 24import android.net.ConnectivityManager; 25import android.net.NetworkStats; 26import android.os.BatteryManager; 27import android.os.BatteryStats; 28import android.os.FileUtils; 29import android.os.Handler; 30import android.os.Looper; 31import android.os.Message; 32import android.os.Parcel; 33import android.os.ParcelFormatException; 34import android.os.Parcelable; 35import android.os.Process; 36import android.os.SystemClock; 37import android.os.SystemProperties; 38import android.os.WorkSource; 39import android.telephony.ServiceState; 40import android.telephony.SignalStrength; 41import android.telephony.TelephonyManager; 42import android.util.Log; 43import android.util.LogWriter; 44import android.util.PrintWriterPrinter; 45import android.util.Printer; 46import android.util.Slog; 47import android.util.SparseArray; 48import android.util.SparseIntArray; 49import android.util.TimeUtils; 50 51import com.android.internal.annotations.GuardedBy; 52import com.android.internal.net.NetworkStatsFactory; 53import com.android.internal.util.FastPrintWriter; 54import com.android.internal.util.JournaledFile; 55import com.google.android.collect.Sets; 56 57import java.io.BufferedReader; 58import java.io.File; 59import java.io.FileInputStream; 60import java.io.FileOutputStream; 61import java.io.FileReader; 62import java.io.IOException; 63import java.io.PrintWriter; 64import java.util.ArrayList; 65import java.util.HashMap; 66import java.util.HashSet; 67import java.util.Iterator; 68import java.util.List; 69import java.util.Map; 70import java.util.concurrent.atomic.AtomicInteger; 71import java.util.concurrent.locks.ReentrantLock; 72 73/** 74 * All information we are collecting about things that can happen that impact 75 * battery life. All times are represented in microseconds except where indicated 76 * otherwise. 77 */ 78public final class BatteryStatsImpl extends BatteryStats { 79 private static final String TAG = "BatteryStatsImpl"; 80 private static final boolean DEBUG = true; 81 private static final boolean DEBUG_HISTORY = false; 82 private static final boolean USE_OLD_HISTORY = false; // for debugging. 83 84 // TODO: remove "tcp" from network methods, since we measure total stats. 85 86 // In-memory Parcel magic number, used to detect attempts to unmarshall bad data 87 private static final int MAGIC = 0xBA757475; // 'BATSTATS' 88 89 // Current on-disk Parcel version 90 private static final int VERSION = 77 + (USE_OLD_HISTORY ? 1000 : 0); 91 92 // Maximum number of items we will record in the history. 93 private static final int MAX_HISTORY_ITEMS = 2000; 94 95 // No, really, THIS is the maximum number of items we will record in the history. 96 private static final int MAX_MAX_HISTORY_ITEMS = 3000; 97 98 // The maximum number of names wakelocks we will keep track of 99 // per uid; once the limit is reached, we batch the remaining wakelocks 100 // in to one common name. 101 private static final int MAX_WAKELOCKS_PER_UID = 50; 102 103 private static final String BATCHED_WAKELOCK_NAME = "*overflow*"; 104 105 private static int sNumSpeedSteps; 106 107 private final JournaledFile mFile; 108 109 static final int MSG_UPDATE_WAKELOCKS = 1; 110 static final int MSG_REPORT_POWER_CHANGE = 2; 111 static final long DELAY_UPDATE_WAKELOCKS = 5*1000; 112 113 public interface BatteryCallback { 114 public void batteryNeedsCpuUpdate(); 115 public void batteryPowerChanged(boolean onBattery); 116 } 117 118 final class MyHandler extends Handler { 119 public MyHandler(Looper looper) { 120 super(looper, null, true); 121 } 122 123 @Override 124 public void handleMessage(Message msg) { 125 BatteryCallback cb = mCallback; 126 switch (msg.what) { 127 case MSG_UPDATE_WAKELOCKS: 128 if (cb != null) { 129 cb.batteryNeedsCpuUpdate(); 130 } 131 break; 132 case MSG_REPORT_POWER_CHANGE: 133 if (cb != null) { 134 cb.batteryPowerChanged(msg.arg1 != 0); 135 } 136 break; 137 } 138 } 139 } 140 141 private final MyHandler mHandler; 142 143 private BatteryCallback mCallback; 144 145 /** 146 * Mapping isolated uids to the actual owning app uid. 147 */ 148 final SparseIntArray mIsolatedUids = new SparseIntArray(); 149 150 /** 151 * The statistics we have collected organized by uids. 152 */ 153 final SparseArray<BatteryStatsImpl.Uid> mUidStats = 154 new SparseArray<BatteryStatsImpl.Uid>(); 155 156 // A set of pools of currently active timers. When a timer is queried, we will divide the 157 // elapsed time by the number of active timers to arrive at that timer's share of the time. 158 // In order to do this, we must refresh each timer whenever the number of active timers 159 // changes. 160 final ArrayList<StopwatchTimer> mPartialTimers = new ArrayList<StopwatchTimer>(); 161 final ArrayList<StopwatchTimer> mFullTimers = new ArrayList<StopwatchTimer>(); 162 final ArrayList<StopwatchTimer> mWindowTimers = new ArrayList<StopwatchTimer>(); 163 final SparseArray<ArrayList<StopwatchTimer>> mSensorTimers 164 = new SparseArray<ArrayList<StopwatchTimer>>(); 165 final ArrayList<StopwatchTimer> mWifiRunningTimers = new ArrayList<StopwatchTimer>(); 166 final ArrayList<StopwatchTimer> mFullWifiLockTimers = new ArrayList<StopwatchTimer>(); 167 final ArrayList<StopwatchTimer> mWifiMulticastTimers = new ArrayList<StopwatchTimer>(); 168 final ArrayList<StopwatchTimer> mWifiScanTimers = new ArrayList<StopwatchTimer>(); 169 final SparseArray<ArrayList<StopwatchTimer>> mWifiBatchedScanTimers = 170 new SparseArray<ArrayList<StopwatchTimer>>(); 171 172 // Last partial timers we use for distributing CPU usage. 173 final ArrayList<StopwatchTimer> mLastPartialTimers = new ArrayList<StopwatchTimer>(); 174 175 // These are the objects that will want to do something when the device 176 // is unplugged from power. 177 final ArrayList<Unpluggable> mUnpluggables = new ArrayList<Unpluggable>(); 178 179 boolean mShuttingDown; 180 181 long mHistoryBaseTime; 182 boolean mHaveBatteryLevel = false; 183 boolean mRecordingHistory = true; 184 int mNumHistoryItems; 185 186 static final int MAX_HISTORY_BUFFER = 128*1024; // 128KB 187 static final int MAX_MAX_HISTORY_BUFFER = 144*1024; // 144KB 188 final Parcel mHistoryBuffer = Parcel.obtain(); 189 final HistoryItem mHistoryLastWritten = new HistoryItem(); 190 final HistoryItem mHistoryLastLastWritten = new HistoryItem(); 191 final HistoryItem mHistoryReadTmp = new HistoryItem(); 192 final HashMap<HistoryTag, Integer> mHistoryTagPool = new HashMap<HistoryTag, Integer>(); 193 String[] mReadHistoryStrings; 194 int[] mReadHistoryUids; 195 int mReadHistoryChars; 196 int mNextHistoryTagIdx = 0; 197 int mNumHistoryTagChars = 0; 198 int mHistoryBufferLastPos = -1; 199 boolean mHistoryOverflow = false; 200 long mLastHistoryTime = 0; 201 202 final HistoryItem mHistoryCur = new HistoryItem(); 203 204 HistoryItem mHistory; 205 HistoryItem mHistoryEnd; 206 HistoryItem mHistoryLastEnd; 207 HistoryItem mHistoryCache; 208 209 private HistoryItem mHistoryIterator; 210 private boolean mReadOverflow; 211 private boolean mIteratingHistory; 212 213 int mStartCount; 214 215 long mStartClockTime; 216 217 long mBatteryUptime; 218 long mBatteryLastUptime; 219 long mBatteryRealtime; 220 long mBatteryLastRealtime; 221 222 long mUptime; 223 long mUptimeStart; 224 long mLastUptime; 225 long mRealtime; 226 long mRealtimeStart; 227 long mLastRealtime; 228 229 int mWakeLockNesting; 230 boolean mWakeLockImportant; 231 232 boolean mScreenOn; 233 StopwatchTimer mScreenOnTimer; 234 235 int mScreenBrightnessBin = -1; 236 final StopwatchTimer[] mScreenBrightnessTimer = new StopwatchTimer[NUM_SCREEN_BRIGHTNESS_BINS]; 237 238 Counter mInputEventCounter; 239 240 boolean mPhoneOn; 241 StopwatchTimer mPhoneOnTimer; 242 243 boolean mAudioOn; 244 StopwatchTimer mAudioOnTimer; 245 246 boolean mVideoOn; 247 StopwatchTimer mVideoOnTimer; 248 249 int mPhoneSignalStrengthBin = -1; 250 int mPhoneSignalStrengthBinRaw = -1; 251 final StopwatchTimer[] mPhoneSignalStrengthsTimer = 252 new StopwatchTimer[SignalStrength.NUM_SIGNAL_STRENGTH_BINS]; 253 254 StopwatchTimer mPhoneSignalScanningTimer; 255 256 int mPhoneDataConnectionType = -1; 257 final StopwatchTimer[] mPhoneDataConnectionsTimer = 258 new StopwatchTimer[NUM_DATA_CONNECTION_TYPES]; 259 260 final LongSamplingCounter[] mNetworkByteActivityCounters = 261 new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES]; 262 final LongSamplingCounter[] mNetworkPacketActivityCounters = 263 new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES]; 264 265 boolean mWifiOn; 266 StopwatchTimer mWifiOnTimer; 267 int mWifiOnUid = -1; 268 269 boolean mGlobalWifiRunning; 270 StopwatchTimer mGlobalWifiRunningTimer; 271 272 boolean mBluetoothOn; 273 StopwatchTimer mBluetoothOnTimer; 274 275 /** Bluetooth headset object */ 276 BluetoothHeadset mBtHeadset; 277 278 /** 279 * These provide time bases that discount the time the device is plugged 280 * in to power. 281 */ 282 boolean mOnBattery; 283 boolean mOnBatteryInternal; 284 long mTrackBatteryPastUptime; 285 long mTrackBatteryUptimeStart; 286 long mTrackBatteryPastRealtime; 287 long mTrackBatteryRealtimeStart; 288 289 long mUnpluggedBatteryUptime; 290 long mUnpluggedBatteryRealtime; 291 292 /* 293 * These keep track of battery levels (1-100) at the last plug event and the last unplug event. 294 */ 295 int mDischargeStartLevel; 296 int mDischargeUnplugLevel; 297 int mDischargeCurrentLevel; 298 int mLowDischargeAmountSinceCharge; 299 int mHighDischargeAmountSinceCharge; 300 int mDischargeScreenOnUnplugLevel; 301 int mDischargeScreenOffUnplugLevel; 302 int mDischargeAmountScreenOn; 303 int mDischargeAmountScreenOnSinceCharge; 304 int mDischargeAmountScreenOff; 305 int mDischargeAmountScreenOffSinceCharge; 306 307 long mLastWriteTime = 0; // Milliseconds 308 309 private long mRadioDataUptime; 310 private long mRadioDataStart; 311 312 private int mBluetoothPingCount; 313 private int mBluetoothPingStart = -1; 314 315 private int mPhoneServiceState = -1; 316 private int mPhoneServiceStateRaw = -1; 317 private int mPhoneSimStateRaw = -1; 318 319 /* 320 * Holds a SamplingTimer associated with each kernel wakelock name being tracked. 321 */ 322 private final HashMap<String, SamplingTimer> mKernelWakelockStats = 323 new HashMap<String, SamplingTimer>(); 324 325 public Map<String, ? extends SamplingTimer> getKernelWakelockStats() { 326 return mKernelWakelockStats; 327 } 328 329 private static int sKernelWakelockUpdateVersion = 0; 330 331 private static final int[] PROC_WAKELOCKS_FORMAT = new int[] { 332 Process.PROC_TAB_TERM|Process.PROC_OUT_STRING| // 0: name 333 Process.PROC_QUOTES, 334 Process.PROC_TAB_TERM|Process.PROC_OUT_LONG, // 1: count 335 Process.PROC_TAB_TERM, 336 Process.PROC_TAB_TERM, 337 Process.PROC_TAB_TERM, 338 Process.PROC_TAB_TERM|Process.PROC_OUT_LONG, // 5: totalTime 339 }; 340 341 private static final int[] WAKEUP_SOURCES_FORMAT = new int[] { 342 Process.PROC_TAB_TERM|Process.PROC_OUT_STRING, // 0: name 343 Process.PROC_TAB_TERM|Process.PROC_COMBINE| 344 Process.PROC_OUT_LONG, // 1: count 345 Process.PROC_TAB_TERM|Process.PROC_COMBINE, 346 Process.PROC_TAB_TERM|Process.PROC_COMBINE, 347 Process.PROC_TAB_TERM|Process.PROC_COMBINE, 348 Process.PROC_TAB_TERM|Process.PROC_COMBINE, 349 Process.PROC_TAB_TERM|Process.PROC_COMBINE 350 |Process.PROC_OUT_LONG, // 6: totalTime 351 }; 352 353 private final String[] mProcWakelocksName = new String[3]; 354 private final long[] mProcWakelocksData = new long[3]; 355 356 /* 357 * Used as a buffer for reading in data from /proc/wakelocks before it is processed and added 358 * to mKernelWakelockStats. 359 */ 360 private final Map<String, KernelWakelockStats> mProcWakelockFileStats = 361 new HashMap<String, KernelWakelockStats>(); 362 363 private final NetworkStatsFactory mNetworkStatsFactory = new NetworkStatsFactory(); 364 private NetworkStats mLastSnapshot; 365 366 @GuardedBy("this") 367 private HashSet<String> mMobileIfaces = Sets.newHashSet(); 368 @GuardedBy("this") 369 private HashSet<String> mWifiIfaces = Sets.newHashSet(); 370 371 // For debugging 372 public BatteryStatsImpl() { 373 mFile = null; 374 mHandler = null; 375 } 376 377 public static interface Unpluggable { 378 void unplug(long elapsedRealtime, long batteryUptime, long batteryRealtime); 379 void plug(long elapsedRealtime, long batteryUptime, long batteryRealtime); 380 } 381 382 /** 383 * State for keeping track of counting information. 384 */ 385 public static class Counter extends BatteryStats.Counter implements Unpluggable { 386 final AtomicInteger mCount = new AtomicInteger(); 387 final ArrayList<Unpluggable> mUnpluggables; 388 int mLoadedCount; 389 int mLastCount; 390 int mUnpluggedCount; 391 int mPluggedCount; 392 393 Counter(ArrayList<Unpluggable> unpluggables, Parcel in) { 394 mUnpluggables = unpluggables; 395 mPluggedCount = in.readInt(); 396 mCount.set(mPluggedCount); 397 mLoadedCount = in.readInt(); 398 mLastCount = 0; 399 mUnpluggedCount = in.readInt(); 400 unpluggables.add(this); 401 } 402 403 Counter(ArrayList<Unpluggable> unpluggables) { 404 mUnpluggables = unpluggables; 405 unpluggables.add(this); 406 } 407 408 public void writeToParcel(Parcel out) { 409 out.writeInt(mCount.get()); 410 out.writeInt(mLoadedCount); 411 out.writeInt(mUnpluggedCount); 412 } 413 414 public void unplug(long elapsedRealtime, long batteryUptime, long batteryRealtime) { 415 mUnpluggedCount = mPluggedCount; 416 mCount.set(mPluggedCount); 417 } 418 419 public void plug(long elapsedRealtime, long batteryUptime, long batteryRealtime) { 420 mPluggedCount = mCount.get(); 421 } 422 423 /** 424 * Writes a possibly null Counter to a Parcel. 425 * 426 * @param out the Parcel to be written to. 427 * @param counter a Counter, or null. 428 */ 429 public static void writeCounterToParcel(Parcel out, Counter counter) { 430 if (counter == null) { 431 out.writeInt(0); // indicates null 432 return; 433 } 434 out.writeInt(1); // indicates non-null 435 436 counter.writeToParcel(out); 437 } 438 439 @Override 440 public int getCountLocked(int which) { 441 int val; 442 if (which == STATS_LAST) { 443 val = mLastCount; 444 } else { 445 val = mCount.get(); 446 if (which == STATS_SINCE_UNPLUGGED) { 447 val -= mUnpluggedCount; 448 } else if (which != STATS_SINCE_CHARGED) { 449 val -= mLoadedCount; 450 } 451 } 452 453 return val; 454 } 455 456 public void logState(Printer pw, String prefix) { 457 pw.println(prefix + "mCount=" + mCount.get() 458 + " mLoadedCount=" + mLoadedCount + " mLastCount=" + mLastCount 459 + " mUnpluggedCount=" + mUnpluggedCount 460 + " mPluggedCount=" + mPluggedCount); 461 } 462 463 void stepAtomic() { 464 mCount.incrementAndGet(); 465 } 466 467 /** 468 * Clear state of this counter. 469 */ 470 void reset(boolean detachIfReset) { 471 mCount.set(0); 472 mLoadedCount = mLastCount = mPluggedCount = mUnpluggedCount = 0; 473 if (detachIfReset) { 474 detach(); 475 } 476 } 477 478 void detach() { 479 mUnpluggables.remove(this); 480 } 481 482 void writeSummaryFromParcelLocked(Parcel out) { 483 int count = mCount.get(); 484 out.writeInt(count); 485 } 486 487 void readSummaryFromParcelLocked(Parcel in) { 488 mLoadedCount = in.readInt(); 489 mCount.set(mLoadedCount); 490 mLastCount = 0; 491 mUnpluggedCount = mPluggedCount = mLoadedCount; 492 } 493 } 494 495 public static class SamplingCounter extends Counter { 496 SamplingCounter(ArrayList<Unpluggable> unpluggables, Parcel in) { 497 super(unpluggables, in); 498 } 499 500 SamplingCounter(ArrayList<Unpluggable> unpluggables) { 501 super(unpluggables); 502 } 503 504 public void addCountAtomic(long count) { 505 mCount.addAndGet((int)count); 506 } 507 } 508 509 public static class LongSamplingCounter implements Unpluggable { 510 final ArrayList<Unpluggable> mUnpluggables; 511 long mCount; 512 long mLoadedCount; 513 long mLastCount; 514 long mUnpluggedCount; 515 long mPluggedCount; 516 517 LongSamplingCounter(ArrayList<Unpluggable> unpluggables, Parcel in) { 518 mUnpluggables = unpluggables; 519 mPluggedCount = in.readLong(); 520 mCount = mPluggedCount; 521 mLoadedCount = in.readLong(); 522 mLastCount = 0; 523 mUnpluggedCount = in.readLong(); 524 unpluggables.add(this); 525 } 526 527 LongSamplingCounter(ArrayList<Unpluggable> unpluggables) { 528 mUnpluggables = unpluggables; 529 unpluggables.add(this); 530 } 531 532 public void writeToParcel(Parcel out) { 533 out.writeLong(mCount); 534 out.writeLong(mLoadedCount); 535 out.writeLong(mUnpluggedCount); 536 } 537 538 @Override 539 public void unplug(long elapsedRealtime, long batteryUptime, long batteryRealtime) { 540 mUnpluggedCount = mPluggedCount; 541 mCount = mPluggedCount; 542 } 543 544 @Override 545 public void plug(long elapsedRealtime, long batteryUptime, long batteryRealtime) { 546 mPluggedCount = mCount; 547 } 548 549 public long getCountLocked(int which) { 550 long val; 551 if (which == STATS_LAST) { 552 val = mLastCount; 553 } else { 554 val = mCount; 555 if (which == STATS_SINCE_UNPLUGGED) { 556 val -= mUnpluggedCount; 557 } else if (which != STATS_SINCE_CHARGED) { 558 val -= mLoadedCount; 559 } 560 } 561 562 return val; 563 } 564 565 void addCountLocked(long count) { 566 mCount += count; 567 } 568 569 /** 570 * Clear state of this counter. 571 */ 572 void reset(boolean detachIfReset) { 573 mCount = 0; 574 mLoadedCount = mLastCount = mPluggedCount = mUnpluggedCount = 0; 575 if (detachIfReset) { 576 detach(); 577 } 578 } 579 580 void detach() { 581 mUnpluggables.remove(this); 582 } 583 584 void writeSummaryFromParcelLocked(Parcel out) { 585 out.writeLong(mCount); 586 } 587 588 void readSummaryFromParcelLocked(Parcel in) { 589 mLoadedCount = in.readLong(); 590 mCount = mLoadedCount; 591 mLastCount = 0; 592 mUnpluggedCount = mPluggedCount = mLoadedCount; 593 } 594 } 595 596 /** 597 * State for keeping track of timing information. 598 */ 599 public static abstract class Timer extends BatteryStats.Timer implements Unpluggable { 600 final int mType; 601 final ArrayList<Unpluggable> mUnpluggables; 602 603 int mCount; 604 int mLoadedCount; 605 int mLastCount; 606 int mUnpluggedCount; 607 608 // Times are in microseconds for better accuracy when dividing by the 609 // lock count, and are in "battery realtime" units. 610 611 /** 612 * The total time we have accumulated since the start of the original 613 * boot, to the last time something interesting happened in the 614 * current run. 615 */ 616 long mTotalTime; 617 618 /** 619 * The total time we loaded for the previous runs. Subtract this from 620 * mTotalTime to find the time for the current run of the system. 621 */ 622 long mLoadedTime; 623 624 /** 625 * The run time of the last run of the system, as loaded from the 626 * saved data. 627 */ 628 long mLastTime; 629 630 /** 631 * The value of mTotalTime when unplug() was last called. Subtract 632 * this from mTotalTime to find the time since the last unplug from 633 * power. 634 */ 635 long mUnpluggedTime; 636 637 /** 638 * Constructs from a parcel. 639 * @param type 640 * @param unpluggables 641 * @param in 642 */ 643 Timer(int type, ArrayList<Unpluggable> unpluggables, Parcel in) { 644 mType = type; 645 mUnpluggables = unpluggables; 646 647 mCount = in.readInt(); 648 mLoadedCount = in.readInt(); 649 mLastCount = 0; 650 mUnpluggedCount = in.readInt(); 651 mTotalTime = in.readLong(); 652 mLoadedTime = in.readLong(); 653 mLastTime = 0; 654 mUnpluggedTime = in.readLong(); 655 unpluggables.add(this); 656 } 657 658 Timer(int type, ArrayList<Unpluggable> unpluggables) { 659 mType = type; 660 mUnpluggables = unpluggables; 661 unpluggables.add(this); 662 } 663 664 protected abstract long computeRunTimeLocked(long curBatteryRealtime); 665 666 protected abstract int computeCurrentCountLocked(); 667 668 /** 669 * Clear state of this timer. Returns true if the timer is inactive 670 * so can be completely dropped. 671 */ 672 boolean reset(BatteryStatsImpl stats, boolean detachIfReset) { 673 mTotalTime = mLoadedTime = mLastTime = 0; 674 mCount = mLoadedCount = mLastCount = 0; 675 if (detachIfReset) { 676 detach(); 677 } 678 return true; 679 } 680 681 void detach() { 682 mUnpluggables.remove(this); 683 } 684 685 public void writeToParcel(Parcel out, long batteryRealtime) { 686 out.writeInt(mCount); 687 out.writeInt(mLoadedCount); 688 out.writeInt(mUnpluggedCount); 689 out.writeLong(computeRunTimeLocked(batteryRealtime)); 690 out.writeLong(mLoadedTime); 691 out.writeLong(mUnpluggedTime); 692 } 693 694 public void unplug(long elapsedRealtime, long batteryUptime, long batteryRealtime) { 695 if (DEBUG && mType < 0) { 696 Log.v(TAG, "unplug #" + mType + ": realtime=" + batteryRealtime 697 + " old mUnpluggedTime=" + mUnpluggedTime 698 + " old mUnpluggedCount=" + mUnpluggedCount); 699 } 700 mUnpluggedTime = computeRunTimeLocked(batteryRealtime); 701 mUnpluggedCount = mCount; 702 if (DEBUG && mType < 0) { 703 Log.v(TAG, "unplug #" + mType 704 + ": new mUnpluggedTime=" + mUnpluggedTime 705 + " new mUnpluggedCount=" + mUnpluggedCount); 706 } 707 } 708 709 public void plug(long elapsedRealtime, long batteryUptime, long batteryRealtime) { 710 if (DEBUG && mType < 0) { 711 Log.v(TAG, "plug #" + mType + ": realtime=" + batteryRealtime 712 + " old mTotalTime=" + mTotalTime); 713 } 714 mTotalTime = computeRunTimeLocked(batteryRealtime); 715 mCount = computeCurrentCountLocked(); 716 if (DEBUG && mType < 0) { 717 Log.v(TAG, "plug #" + mType 718 + ": new mTotalTime=" + mTotalTime); 719 } 720 } 721 722 /** 723 * Writes a possibly null Timer to a Parcel. 724 * 725 * @param out the Parcel to be written to. 726 * @param timer a Timer, or null. 727 */ 728 public static void writeTimerToParcel(Parcel out, Timer timer, 729 long batteryRealtime) { 730 if (timer == null) { 731 out.writeInt(0); // indicates null 732 return; 733 } 734 out.writeInt(1); // indicates non-null 735 736 timer.writeToParcel(out, batteryRealtime); 737 } 738 739 @Override 740 public long getTotalTimeLocked(long batteryRealtime, int which) { 741 long val; 742 if (which == STATS_LAST) { 743 val = mLastTime; 744 } else { 745 val = computeRunTimeLocked(batteryRealtime); 746 if (which == STATS_SINCE_UNPLUGGED) { 747 val -= mUnpluggedTime; 748 } else if (which != STATS_SINCE_CHARGED) { 749 val -= mLoadedTime; 750 } 751 } 752 753 return val; 754 } 755 756 @Override 757 public int getCountLocked(int which) { 758 int val; 759 if (which == STATS_LAST) { 760 val = mLastCount; 761 } else { 762 val = computeCurrentCountLocked(); 763 if (which == STATS_SINCE_UNPLUGGED) { 764 val -= mUnpluggedCount; 765 } else if (which != STATS_SINCE_CHARGED) { 766 val -= mLoadedCount; 767 } 768 } 769 770 return val; 771 } 772 773 public void logState(Printer pw, String prefix) { 774 pw.println(prefix + "mCount=" + mCount 775 + " mLoadedCount=" + mLoadedCount + " mLastCount=" + mLastCount 776 + " mUnpluggedCount=" + mUnpluggedCount); 777 pw.println(prefix + "mTotalTime=" + mTotalTime 778 + " mLoadedTime=" + mLoadedTime); 779 pw.println(prefix + "mLastTime=" + mLastTime 780 + " mUnpluggedTime=" + mUnpluggedTime); 781 } 782 783 784 void writeSummaryFromParcelLocked(Parcel out, long batteryRealtime) { 785 long runTime = computeRunTimeLocked(batteryRealtime); 786 // Divide by 1000 for backwards compatibility 787 out.writeLong((runTime + 500) / 1000); 788 out.writeInt(mCount); 789 } 790 791 void readSummaryFromParcelLocked(Parcel in) { 792 // Multiply by 1000 for backwards compatibility 793 mTotalTime = mLoadedTime = in.readLong() * 1000; 794 mLastTime = 0; 795 mUnpluggedTime = mTotalTime; 796 mCount = mLoadedCount = in.readInt(); 797 mLastCount = 0; 798 mUnpluggedCount = mCount; 799 } 800 } 801 802 public static final class SamplingTimer extends Timer { 803 804 /** 805 * The most recent reported count from /proc/wakelocks. 806 */ 807 int mCurrentReportedCount; 808 809 /** 810 * The reported count from /proc/wakelocks when unplug() was last 811 * called. 812 */ 813 int mUnpluggedReportedCount; 814 815 /** 816 * The most recent reported total_time from /proc/wakelocks. 817 */ 818 long mCurrentReportedTotalTime; 819 820 821 /** 822 * The reported total_time from /proc/wakelocks when unplug() was last 823 * called. 824 */ 825 long mUnpluggedReportedTotalTime; 826 827 /** 828 * Whether we are currently in a discharge cycle. 829 */ 830 boolean mInDischarge; 831 832 /** 833 * Whether we are currently recording reported values. 834 */ 835 boolean mTrackingReportedValues; 836 837 /* 838 * A sequence counter, incremented once for each update of the stats. 839 */ 840 int mUpdateVersion; 841 842 SamplingTimer(ArrayList<Unpluggable> unpluggables, boolean inDischarge, Parcel in) { 843 super(0, unpluggables, in); 844 mCurrentReportedCount = in.readInt(); 845 mUnpluggedReportedCount = in.readInt(); 846 mCurrentReportedTotalTime = in.readLong(); 847 mUnpluggedReportedTotalTime = in.readLong(); 848 mTrackingReportedValues = in.readInt() == 1; 849 mInDischarge = inDischarge; 850 } 851 852 SamplingTimer(ArrayList<Unpluggable> unpluggables, boolean inDischarge, 853 boolean trackReportedValues) { 854 super(0, unpluggables); 855 mTrackingReportedValues = trackReportedValues; 856 mInDischarge = inDischarge; 857 } 858 859 public void setStale() { 860 mTrackingReportedValues = false; 861 mUnpluggedReportedTotalTime = 0; 862 mUnpluggedReportedCount = 0; 863 } 864 865 public void setUpdateVersion(int version) { 866 mUpdateVersion = version; 867 } 868 869 public int getUpdateVersion() { 870 return mUpdateVersion; 871 } 872 873 public void updateCurrentReportedCount(int count) { 874 if (mInDischarge && mUnpluggedReportedCount == 0) { 875 // Updating the reported value for the first time. 876 mUnpluggedReportedCount = count; 877 // If we are receiving an update update mTrackingReportedValues; 878 mTrackingReportedValues = true; 879 } 880 mCurrentReportedCount = count; 881 } 882 883 public void updateCurrentReportedTotalTime(long totalTime) { 884 if (mInDischarge && mUnpluggedReportedTotalTime == 0) { 885 // Updating the reported value for the first time. 886 mUnpluggedReportedTotalTime = totalTime; 887 // If we are receiving an update update mTrackingReportedValues; 888 mTrackingReportedValues = true; 889 } 890 mCurrentReportedTotalTime = totalTime; 891 } 892 893 public void unplug(long elapsedRealtime, long batteryUptime, long batteryRealtime) { 894 super.unplug(elapsedRealtime, batteryUptime, batteryRealtime); 895 if (mTrackingReportedValues) { 896 mUnpluggedReportedTotalTime = mCurrentReportedTotalTime; 897 mUnpluggedReportedCount = mCurrentReportedCount; 898 } 899 mInDischarge = true; 900 } 901 902 public void plug(long elapsedRealtime, long batteryUptime, long batteryRealtime) { 903 super.plug(elapsedRealtime, batteryUptime, batteryRealtime); 904 mInDischarge = false; 905 } 906 907 public void logState(Printer pw, String prefix) { 908 super.logState(pw, prefix); 909 pw.println(prefix + "mCurrentReportedCount=" + mCurrentReportedCount 910 + " mUnpluggedReportedCount=" + mUnpluggedReportedCount 911 + " mCurrentReportedTotalTime=" + mCurrentReportedTotalTime 912 + " mUnpluggedReportedTotalTime=" + mUnpluggedReportedTotalTime); 913 } 914 915 protected long computeRunTimeLocked(long curBatteryRealtime) { 916 return mTotalTime + (mInDischarge && mTrackingReportedValues 917 ? mCurrentReportedTotalTime - mUnpluggedReportedTotalTime : 0); 918 } 919 920 protected int computeCurrentCountLocked() { 921 return mCount + (mInDischarge && mTrackingReportedValues 922 ? mCurrentReportedCount - mUnpluggedReportedCount : 0); 923 } 924 925 public void writeToParcel(Parcel out, long batteryRealtime) { 926 super.writeToParcel(out, batteryRealtime); 927 out.writeInt(mCurrentReportedCount); 928 out.writeInt(mUnpluggedReportedCount); 929 out.writeLong(mCurrentReportedTotalTime); 930 out.writeLong(mUnpluggedReportedTotalTime); 931 out.writeInt(mTrackingReportedValues ? 1 : 0); 932 } 933 934 boolean reset(BatteryStatsImpl stats, boolean detachIfReset) { 935 super.reset(stats, detachIfReset); 936 setStale(); 937 return true; 938 } 939 940 void writeSummaryFromParcelLocked(Parcel out, long batteryRealtime) { 941 super.writeSummaryFromParcelLocked(out, batteryRealtime); 942 out.writeLong(mCurrentReportedTotalTime); 943 out.writeInt(mCurrentReportedCount); 944 out.writeInt(mTrackingReportedValues ? 1 : 0); 945 } 946 947 void readSummaryFromParcelLocked(Parcel in) { 948 super.readSummaryFromParcelLocked(in); 949 mUnpluggedReportedTotalTime = mCurrentReportedTotalTime = in.readLong(); 950 mUnpluggedReportedCount = mCurrentReportedCount = in.readInt(); 951 mTrackingReportedValues = in.readInt() == 1; 952 } 953 } 954 955 /** 956 * A timer that increments in batches. It does not run for durations, but just jumps 957 * for a pre-determined amount. 958 */ 959 public static final class BatchTimer extends Timer { 960 final Uid mUid; 961 962 /** 963 * The last time at which we updated the timer. This is in elapsed realtime microseconds. 964 */ 965 long mLastAddedTime; 966 967 /** 968 * The last duration that we added to the timer. This is in microseconds. 969 */ 970 long mLastAddedDuration; 971 972 /** 973 * Whether we are currently in a discharge cycle. 974 */ 975 boolean mInDischarge; 976 977 BatchTimer(Uid uid, int type, ArrayList<Unpluggable> unpluggables, 978 boolean inDischarge, Parcel in) { 979 super(type, unpluggables, in); 980 mUid = uid; 981 mLastAddedTime = in.readLong(); 982 mLastAddedDuration = in.readLong(); 983 mInDischarge = inDischarge; 984 } 985 986 BatchTimer(Uid uid, int type, ArrayList<Unpluggable> unpluggables, 987 boolean inDischarge) { 988 super(type, unpluggables); 989 mUid = uid; 990 mInDischarge = inDischarge; 991 } 992 993 @Override 994 public void writeToParcel(Parcel out, long batteryRealtime) { 995 super.writeToParcel(out, batteryRealtime); 996 out.writeLong(mLastAddedTime); 997 out.writeLong(mLastAddedDuration); 998 } 999 1000 @Override 1001 public void plug(long elapsedRealtime, long batteryUptime, long batteryRealtime) { 1002 recomputeLastDuration(SystemClock.elapsedRealtime() * 1000, false); 1003 mInDischarge = false; 1004 super.plug(elapsedRealtime, batteryUptime, batteryRealtime); 1005 } 1006 1007 @Override 1008 public void unplug(long elapsedRealtime, long batteryUptime, long batteryRealtime) { 1009 recomputeLastDuration(elapsedRealtime, false); 1010 mInDischarge = true; 1011 // If we are still within the last added duration, then re-added whatever remains. 1012 if (mLastAddedTime == elapsedRealtime) { 1013 mTotalTime += mLastAddedDuration; 1014 } 1015 super.unplug(elapsedRealtime, batteryUptime, batteryRealtime); 1016 } 1017 1018 @Override 1019 public void logState(Printer pw, String prefix) { 1020 super.logState(pw, prefix); 1021 pw.println(prefix + "mLastAddedTime=" + mLastAddedTime 1022 + " mLastAddedDuration=" + mLastAddedDuration); 1023 } 1024 1025 private long computeOverage(long curTime) { 1026 if (mLastAddedTime > 0) { 1027 return mLastTime + mLastAddedDuration - curTime; 1028 } 1029 return 0; 1030 } 1031 1032 private void recomputeLastDuration(long curTime, boolean abort) { 1033 final long overage = computeOverage(curTime); 1034 if (overage > 0) { 1035 // Aborting before the duration ran out -- roll back the remaining 1036 // duration. Only do this if currently discharging; otherwise we didn't 1037 // actually add the time. 1038 if (mInDischarge) { 1039 mTotalTime -= overage; 1040 } 1041 if (abort) { 1042 mLastAddedTime = 0; 1043 } else { 1044 mLastAddedTime = curTime; 1045 mLastAddedDuration -= overage; 1046 } 1047 } 1048 } 1049 1050 public void addDuration(BatteryStatsImpl stats, long durationMillis) { 1051 final long now = SystemClock.elapsedRealtime() * 1000; 1052 recomputeLastDuration(now, true); 1053 mLastAddedTime = now; 1054 mLastAddedDuration = durationMillis * 1000; 1055 if (mInDischarge) { 1056 mTotalTime += mLastAddedDuration; 1057 mCount++; 1058 } 1059 } 1060 1061 public void abortLastDuration(BatteryStatsImpl stats) { 1062 final long now = SystemClock.elapsedRealtime() * 1000; 1063 recomputeLastDuration(now, true); 1064 } 1065 1066 @Override 1067 protected int computeCurrentCountLocked() { 1068 return mCount; 1069 } 1070 1071 @Override 1072 protected long computeRunTimeLocked(long curBatteryRealtime) { 1073 final long overage = computeOverage(SystemClock.elapsedRealtime() * 1000); 1074 if (overage > 0) { 1075 return mTotalTime = overage; 1076 } 1077 return mTotalTime; 1078 } 1079 1080 @Override 1081 boolean reset(BatteryStatsImpl stats, boolean detachIfReset) { 1082 final long now = SystemClock.elapsedRealtime() * 1000; 1083 recomputeLastDuration(now, true); 1084 boolean stillActive = mLastAddedTime == now; 1085 super.reset(stats, !stillActive && detachIfReset); 1086 return !stillActive; 1087 } 1088 } 1089 1090 /** 1091 * State for keeping track of timing information. 1092 */ 1093 public static final class StopwatchTimer extends Timer { 1094 final Uid mUid; 1095 final ArrayList<StopwatchTimer> mTimerPool; 1096 1097 int mNesting; 1098 1099 /** 1100 * The last time at which we updated the timer. If mNesting is > 0, 1101 * subtract this from the current battery time to find the amount of 1102 * time we have been running since we last computed an update. 1103 */ 1104 long mUpdateTime; 1105 1106 /** 1107 * The total time at which the timer was acquired, to determine if it 1108 * was actually held for an interesting duration. 1109 */ 1110 long mAcquireTime; 1111 1112 long mTimeout; 1113 1114 /** 1115 * For partial wake locks, keep track of whether we are in the list 1116 * to consume CPU cycles. 1117 */ 1118 boolean mInList; 1119 1120 StopwatchTimer(Uid uid, int type, ArrayList<StopwatchTimer> timerPool, 1121 ArrayList<Unpluggable> unpluggables, Parcel in) { 1122 super(type, unpluggables, in); 1123 mUid = uid; 1124 mTimerPool = timerPool; 1125 mUpdateTime = in.readLong(); 1126 } 1127 1128 StopwatchTimer(Uid uid, int type, ArrayList<StopwatchTimer> timerPool, 1129 ArrayList<Unpluggable> unpluggables) { 1130 super(type, unpluggables); 1131 mUid = uid; 1132 mTimerPool = timerPool; 1133 } 1134 1135 void setTimeout(long timeout) { 1136 mTimeout = timeout; 1137 } 1138 1139 public void writeToParcel(Parcel out, long batteryRealtime) { 1140 super.writeToParcel(out, batteryRealtime); 1141 out.writeLong(mUpdateTime); 1142 } 1143 1144 public void plug(long elapsedRealtime, long batteryUptime, long batteryRealtime) { 1145 if (mNesting > 0) { 1146 if (DEBUG && mType < 0) { 1147 Log.v(TAG, "old mUpdateTime=" + mUpdateTime); 1148 } 1149 super.plug(elapsedRealtime, batteryUptime, batteryRealtime); 1150 mUpdateTime = batteryRealtime; 1151 if (DEBUG && mType < 0) { 1152 Log.v(TAG, "new mUpdateTime=" + mUpdateTime); 1153 } 1154 } 1155 } 1156 1157 public void logState(Printer pw, String prefix) { 1158 super.logState(pw, prefix); 1159 pw.println(prefix + "mNesting=" + mNesting + " mUpdateTime=" + mUpdateTime 1160 + " mAcquireTime=" + mAcquireTime); 1161 } 1162 1163 void startRunningLocked(BatteryStatsImpl stats) { 1164 if (mNesting++ == 0) { 1165 mUpdateTime = stats.getBatteryRealtimeLocked( 1166 SystemClock.elapsedRealtime() * 1000); 1167 if (mTimerPool != null) { 1168 // Accumulate time to all currently active timers before adding 1169 // this new one to the pool. 1170 refreshTimersLocked(stats, mTimerPool); 1171 // Add this timer to the active pool 1172 mTimerPool.add(this); 1173 } 1174 // Increment the count 1175 mCount++; 1176 mAcquireTime = mTotalTime; 1177 if (DEBUG && mType < 0) { 1178 Log.v(TAG, "start #" + mType + ": mUpdateTime=" + mUpdateTime 1179 + " mTotalTime=" + mTotalTime + " mCount=" + mCount 1180 + " mAcquireTime=" + mAcquireTime); 1181 } 1182 } 1183 } 1184 1185 boolean isRunningLocked() { 1186 return mNesting > 0; 1187 } 1188 1189 void stopRunningLocked(BatteryStatsImpl stats) { 1190 // Ignore attempt to stop a timer that isn't running 1191 if (mNesting == 0) { 1192 return; 1193 } 1194 if (--mNesting == 0) { 1195 if (mTimerPool != null) { 1196 // Accumulate time to all active counters, scaled by the total 1197 // active in the pool, before taking this one out of the pool. 1198 refreshTimersLocked(stats, mTimerPool); 1199 // Remove this timer from the active pool 1200 mTimerPool.remove(this); 1201 } else { 1202 final long realtime = SystemClock.elapsedRealtime() * 1000; 1203 final long batteryRealtime = stats.getBatteryRealtimeLocked(realtime); 1204 mNesting = 1; 1205 mTotalTime = computeRunTimeLocked(batteryRealtime); 1206 mNesting = 0; 1207 } 1208 1209 if (DEBUG && mType < 0) { 1210 Log.v(TAG, "stop #" + mType + ": mUpdateTime=" + mUpdateTime 1211 + " mTotalTime=" + mTotalTime + " mCount=" + mCount 1212 + " mAcquireTime=" + mAcquireTime); 1213 } 1214 1215 if (mTotalTime == mAcquireTime) { 1216 // If there was no change in the time, then discard this 1217 // count. A somewhat cheezy strategy, but hey. 1218 mCount--; 1219 } 1220 } 1221 } 1222 1223 // Update the total time for all other running Timers with the same type as this Timer 1224 // due to a change in timer count 1225 private static void refreshTimersLocked(final BatteryStatsImpl stats, 1226 final ArrayList<StopwatchTimer> pool) { 1227 final long realtime = SystemClock.elapsedRealtime() * 1000; 1228 final long batteryRealtime = stats.getBatteryRealtimeLocked(realtime); 1229 final int N = pool.size(); 1230 for (int i=N-1; i>= 0; i--) { 1231 final StopwatchTimer t = pool.get(i); 1232 long heldTime = batteryRealtime - t.mUpdateTime; 1233 if (heldTime > 0) { 1234 t.mTotalTime += heldTime / N; 1235 } 1236 t.mUpdateTime = batteryRealtime; 1237 } 1238 } 1239 1240 @Override 1241 protected long computeRunTimeLocked(long curBatteryRealtime) { 1242 if (mTimeout > 0 && curBatteryRealtime > mUpdateTime + mTimeout) { 1243 curBatteryRealtime = mUpdateTime + mTimeout; 1244 } 1245 return mTotalTime + (mNesting > 0 1246 ? (curBatteryRealtime - mUpdateTime) 1247 / (mTimerPool != null ? mTimerPool.size() : 1) 1248 : 0); 1249 } 1250 1251 @Override 1252 protected int computeCurrentCountLocked() { 1253 return mCount; 1254 } 1255 1256 boolean reset(BatteryStatsImpl stats, boolean detachIfReset) { 1257 boolean canDetach = mNesting <= 0; 1258 super.reset(stats, canDetach && detachIfReset); 1259 if (mNesting > 0) { 1260 mUpdateTime = stats.getBatteryRealtimeLocked( 1261 SystemClock.elapsedRealtime() * 1000); 1262 } 1263 mAcquireTime = mTotalTime; 1264 return canDetach; 1265 } 1266 1267 void detach() { 1268 super.detach(); 1269 if (mTimerPool != null) { 1270 mTimerPool.remove(this); 1271 } 1272 } 1273 1274 void readSummaryFromParcelLocked(Parcel in) { 1275 super.readSummaryFromParcelLocked(in); 1276 mNesting = 0; 1277 } 1278 } 1279 1280 private final Map<String, KernelWakelockStats> readKernelWakelockStats() { 1281 1282 FileInputStream is; 1283 byte[] buffer = new byte[8192]; 1284 int len; 1285 boolean wakeup_sources = false; 1286 1287 try { 1288 try { 1289 is = new FileInputStream("/proc/wakelocks"); 1290 } catch (java.io.FileNotFoundException e) { 1291 try { 1292 is = new FileInputStream("/d/wakeup_sources"); 1293 wakeup_sources = true; 1294 } catch (java.io.FileNotFoundException e2) { 1295 return null; 1296 } 1297 } 1298 1299 len = is.read(buffer); 1300 is.close(); 1301 } catch (java.io.IOException e) { 1302 return null; 1303 } 1304 1305 if (len > 0) { 1306 int i; 1307 for (i=0; i<len; i++) { 1308 if (buffer[i] == '\0') { 1309 len = i; 1310 break; 1311 } 1312 } 1313 } 1314 1315 return parseProcWakelocks(buffer, len, wakeup_sources); 1316 } 1317 1318 private final Map<String, KernelWakelockStats> parseProcWakelocks( 1319 byte[] wlBuffer, int len, boolean wakeup_sources) { 1320 String name; 1321 int count; 1322 long totalTime; 1323 int startIndex; 1324 int endIndex; 1325 int numUpdatedWlNames = 0; 1326 1327 // Advance past the first line. 1328 int i; 1329 for (i = 0; i < len && wlBuffer[i] != '\n' && wlBuffer[i] != '\0'; i++); 1330 startIndex = endIndex = i + 1; 1331 1332 synchronized(this) { 1333 Map<String, KernelWakelockStats> m = mProcWakelockFileStats; 1334 1335 sKernelWakelockUpdateVersion++; 1336 while (endIndex < len) { 1337 for (endIndex=startIndex; 1338 endIndex < len && wlBuffer[endIndex] != '\n' && wlBuffer[endIndex] != '\0'; 1339 endIndex++); 1340 endIndex++; // endIndex is an exclusive upper bound. 1341 // Don't go over the end of the buffer, Process.parseProcLine might 1342 // write to wlBuffer[endIndex] 1343 if (endIndex >= (len - 1) ) { 1344 return m; 1345 } 1346 1347 String[] nameStringArray = mProcWakelocksName; 1348 long[] wlData = mProcWakelocksData; 1349 // Stomp out any bad characters since this is from a circular buffer 1350 // A corruption is seen sometimes that results in the vm crashing 1351 // This should prevent crashes and the line will probably fail to parse 1352 for (int j = startIndex; j < endIndex; j++) { 1353 if ((wlBuffer[j] & 0x80) != 0) wlBuffer[j] = (byte) '?'; 1354 } 1355 boolean parsed = Process.parseProcLine(wlBuffer, startIndex, endIndex, 1356 wakeup_sources ? WAKEUP_SOURCES_FORMAT : 1357 PROC_WAKELOCKS_FORMAT, 1358 nameStringArray, wlData, null); 1359 1360 name = nameStringArray[0]; 1361 count = (int) wlData[1]; 1362 1363 if (wakeup_sources) { 1364 // convert milliseconds to microseconds 1365 totalTime = wlData[2] * 1000; 1366 } else { 1367 // convert nanoseconds to microseconds with rounding. 1368 totalTime = (wlData[2] + 500) / 1000; 1369 } 1370 1371 if (parsed && name.length() > 0) { 1372 if (!m.containsKey(name)) { 1373 m.put(name, new KernelWakelockStats(count, totalTime, 1374 sKernelWakelockUpdateVersion)); 1375 numUpdatedWlNames++; 1376 } else { 1377 KernelWakelockStats kwlStats = m.get(name); 1378 if (kwlStats.mVersion == sKernelWakelockUpdateVersion) { 1379 kwlStats.mCount += count; 1380 kwlStats.mTotalTime += totalTime; 1381 } else { 1382 kwlStats.mCount = count; 1383 kwlStats.mTotalTime = totalTime; 1384 kwlStats.mVersion = sKernelWakelockUpdateVersion; 1385 numUpdatedWlNames++; 1386 } 1387 } 1388 } 1389 startIndex = endIndex; 1390 } 1391 1392 if (m.size() != numUpdatedWlNames) { 1393 // Don't report old data. 1394 Iterator<KernelWakelockStats> itr = m.values().iterator(); 1395 while (itr.hasNext()) { 1396 if (itr.next().mVersion != sKernelWakelockUpdateVersion) { 1397 itr.remove(); 1398 } 1399 } 1400 } 1401 return m; 1402 } 1403 } 1404 1405 private class KernelWakelockStats { 1406 public int mCount; 1407 public long mTotalTime; 1408 public int mVersion; 1409 1410 KernelWakelockStats(int count, long totalTime, int version) { 1411 mCount = count; 1412 mTotalTime = totalTime; 1413 mVersion = version; 1414 } 1415 } 1416 1417 /* 1418 * Get the KernelWakelockTimer associated with name, and create a new one if one 1419 * doesn't already exist. 1420 */ 1421 public SamplingTimer getKernelWakelockTimerLocked(String name) { 1422 SamplingTimer kwlt = mKernelWakelockStats.get(name); 1423 if (kwlt == null) { 1424 kwlt = new SamplingTimer(mUnpluggables, mOnBatteryInternal, 1425 true /* track reported values */); 1426 mKernelWakelockStats.put(name, kwlt); 1427 } 1428 return kwlt; 1429 } 1430 1431 /** 1432 * Radio uptime in microseconds when transferring data. This value is very approximate. 1433 * @return 1434 */ 1435 private long getCurrentRadioDataUptime() { 1436 try { 1437 File awakeTimeFile = new File("/sys/devices/virtual/net/rmnet0/awake_time_ms"); 1438 if (!awakeTimeFile.exists()) return 0; 1439 BufferedReader br = new BufferedReader(new FileReader(awakeTimeFile)); 1440 String line = br.readLine(); 1441 br.close(); 1442 return Long.parseLong(line) * 1000; 1443 } catch (NumberFormatException nfe) { 1444 // Nothing 1445 } catch (IOException ioe) { 1446 // Nothing 1447 } 1448 return 0; 1449 } 1450 1451 /** 1452 * @deprecated use getRadioDataUptime 1453 */ 1454 public long getRadioDataUptimeMs() { 1455 return getRadioDataUptime() / 1000; 1456 } 1457 1458 /** 1459 * Returns the duration that the cell radio was up for data transfers. 1460 */ 1461 public long getRadioDataUptime() { 1462 if (mRadioDataStart == -1) { 1463 return mRadioDataUptime; 1464 } else { 1465 return getCurrentRadioDataUptime() - mRadioDataStart; 1466 } 1467 } 1468 1469 private int getCurrentBluetoothPingCount() { 1470 if (mBtHeadset != null) { 1471 List<BluetoothDevice> deviceList = mBtHeadset.getConnectedDevices(); 1472 if (deviceList.size() > 0) { 1473 return mBtHeadset.getBatteryUsageHint(deviceList.get(0)); 1474 } 1475 } 1476 return -1; 1477 } 1478 1479 public int getBluetoothPingCount() { 1480 if (mBluetoothPingStart == -1) { 1481 return mBluetoothPingCount; 1482 } else if (mBtHeadset != null) { 1483 return getCurrentBluetoothPingCount() - mBluetoothPingStart; 1484 } 1485 return 0; 1486 } 1487 1488 public void setBtHeadset(BluetoothHeadset headset) { 1489 if (headset != null && mBtHeadset == null && isOnBattery() && mBluetoothPingStart == -1) { 1490 mBluetoothPingStart = getCurrentBluetoothPingCount(); 1491 } 1492 mBtHeadset = headset; 1493 } 1494 1495 private int writeHistoryTag(HistoryTag tag) { 1496 Integer idxObj = mHistoryTagPool.get(tag); 1497 int idx; 1498 if (idxObj != null) { 1499 idx = idxObj; 1500 } else { 1501 idx = mNextHistoryTagIdx; 1502 HistoryTag key = new HistoryTag(); 1503 key.setTo(tag); 1504 tag.poolIdx = idx; 1505 mHistoryTagPool.put(key, idx); 1506 mNextHistoryTagIdx++; 1507 mNumHistoryTagChars += key.string.length() + 1; 1508 } 1509 return idx; 1510 } 1511 1512 private void readHistoryTag(int index, HistoryTag tag) { 1513 tag.string = mReadHistoryStrings[index]; 1514 tag.uid = mReadHistoryUids[index]; 1515 tag.poolIdx = index; 1516 } 1517 1518 // Part of initial delta int that specifies the time delta. 1519 static final int DELTA_TIME_MASK = 0xfffff; 1520 static final int DELTA_TIME_LONG = 0xfffff; // The delta is a following long 1521 static final int DELTA_TIME_INT = 0xffffe; // The delta is a following int 1522 static final int DELTA_TIME_ABS = 0xffffd; // Following is an entire abs update. 1523 // Flag in delta int: a new battery level int follows. 1524 static final int DELTA_BATTERY_LEVEL_FLAG = 0x00400000; 1525 // Flag in delta int: a new full state and battery status int follows. 1526 static final int DELTA_STATE_FLAG = 0x00800000; 1527 // Flag in delta int: contains a wakelock tag. 1528 static final int DELTA_WAKELOCK_FLAG = 0x01000000; 1529 // Flag in delta int: contains an event description. 1530 static final int DELTA_EVENT_FLAG = 0x02000000; 1531 // These upper bits are the frequently changing state bits. 1532 static final int DELTA_STATE_MASK = 0xfc000000; 1533 1534 public void writeHistoryDelta(Parcel dest, HistoryItem cur, HistoryItem last) { 1535 if (last == null || cur.cmd != HistoryItem.CMD_UPDATE) { 1536 dest.writeInt(DELTA_TIME_ABS); 1537 cur.writeToParcel(dest, 0); 1538 return; 1539 } 1540 1541 final long deltaTime = cur.time - last.time; 1542 final int lastBatteryLevelInt = buildBatteryLevelInt(last); 1543 final int lastStateInt = buildStateInt(last); 1544 1545 int deltaTimeToken; 1546 if (deltaTime < 0 || deltaTime > Integer.MAX_VALUE) { 1547 deltaTimeToken = DELTA_TIME_LONG; 1548 } else if (deltaTime >= DELTA_TIME_ABS) { 1549 deltaTimeToken = DELTA_TIME_INT; 1550 } else { 1551 deltaTimeToken = (int)deltaTime; 1552 } 1553 int firstToken = deltaTimeToken | (cur.states&DELTA_STATE_MASK); 1554 final int batteryLevelInt = buildBatteryLevelInt(cur); 1555 final boolean batteryLevelIntChanged = batteryLevelInt != lastBatteryLevelInt; 1556 if (batteryLevelIntChanged) { 1557 firstToken |= DELTA_BATTERY_LEVEL_FLAG; 1558 } 1559 final int stateInt = buildStateInt(cur); 1560 final boolean stateIntChanged = stateInt != lastStateInt; 1561 if (stateIntChanged) { 1562 firstToken |= DELTA_STATE_FLAG; 1563 } 1564 if (cur.wakelockTag != null) { 1565 firstToken |= DELTA_WAKELOCK_FLAG; 1566 } 1567 if (cur.eventCode != HistoryItem.EVENT_NONE) { 1568 firstToken |= DELTA_EVENT_FLAG; 1569 } 1570 dest.writeInt(firstToken); 1571 if (DEBUG) Slog.i(TAG, "WRITE DELTA: firstToken=0x" + Integer.toHexString(firstToken) 1572 + " deltaTime=" + deltaTime); 1573 1574 if (deltaTimeToken >= DELTA_TIME_INT) { 1575 if (deltaTimeToken == DELTA_TIME_INT) { 1576 if (DEBUG) Slog.i(TAG, "WRITE DELTA: int deltaTime=" + (int)deltaTime); 1577 dest.writeInt((int)deltaTime); 1578 } else { 1579 if (DEBUG) Slog.i(TAG, "WRITE DELTA: long deltaTime=" + deltaTime); 1580 dest.writeLong(deltaTime); 1581 } 1582 } 1583 if (batteryLevelIntChanged) { 1584 dest.writeInt(batteryLevelInt); 1585 if (DEBUG) Slog.i(TAG, "WRITE DELTA: batteryToken=0x" 1586 + Integer.toHexString(batteryLevelInt) 1587 + " batteryLevel=" + cur.batteryLevel 1588 + " batteryTemp=" + cur.batteryTemperature 1589 + " batteryVolt=" + (int)cur.batteryVoltage); 1590 } 1591 if (stateIntChanged) { 1592 dest.writeInt(stateInt); 1593 if (DEBUG) Slog.i(TAG, "WRITE DELTA: stateToken=0x" 1594 + Integer.toHexString(stateInt) 1595 + " batteryStatus=" + cur.batteryStatus 1596 + " batteryHealth=" + cur.batteryHealth 1597 + " batteryPlugType=" + cur.batteryPlugType 1598 + " states=0x" + Integer.toHexString(cur.states)); 1599 } 1600 if (cur.wakelockTag != null) { 1601 int index = writeHistoryTag(cur.wakelockTag); 1602 dest.writeInt(index); 1603 if (DEBUG) Slog.i(TAG, "WRITE DELTA: wakelockTag=#" + cur.wakelockTag.poolIdx 1604 + " " + cur.wakelockTag.uid + ":" + cur.wakelockTag.string); 1605 } 1606 if (cur.eventCode != HistoryItem.EVENT_NONE) { 1607 int index = writeHistoryTag(cur.eventTag); 1608 int codeAndIndex = (cur.eventCode&0xffff) | (index<<16); 1609 dest.writeInt(codeAndIndex); 1610 if (DEBUG) Slog.i(TAG, "WRITE DELTA: event=" + cur.eventCode + " tag=#" 1611 + cur.eventTag.poolIdx + " " + cur.eventTag.uid + ":" 1612 + cur.eventTag.string); 1613 } 1614 } 1615 1616 private int buildBatteryLevelInt(HistoryItem h) { 1617 return ((((int)h.batteryLevel)<<25)&0xfe000000) 1618 | ((((int)h.batteryTemperature)<<14)&0x01ffc000) 1619 | (((int)h.batteryVoltage)&0x00003fff); 1620 } 1621 1622 private int buildStateInt(HistoryItem h) { 1623 return ((((int)h.batteryStatus)<<28)&0xf0000000) 1624 | ((((int)h.batteryHealth)<<24)&0x0f000000) 1625 | ((((int)h.batteryPlugType)<<22)&0x00c00000) 1626 | (h.states&(~DELTA_STATE_MASK)); 1627 } 1628 1629 public void readHistoryDelta(Parcel src, HistoryItem cur) { 1630 int firstToken = src.readInt(); 1631 int deltaTimeToken = firstToken&DELTA_TIME_MASK; 1632 cur.cmd = HistoryItem.CMD_UPDATE; 1633 cur.numReadInts = 1; 1634 if (DEBUG) Slog.i(TAG, "READ DELTA: firstToken=0x" + Integer.toHexString(firstToken) 1635 + " deltaTimeToken=" + deltaTimeToken); 1636 1637 if (deltaTimeToken < DELTA_TIME_ABS) { 1638 cur.time += deltaTimeToken; 1639 } else if (deltaTimeToken == DELTA_TIME_ABS) { 1640 cur.time = src.readLong(); 1641 cur.numReadInts += 2; 1642 if (DEBUG) Slog.i(TAG, "READ DELTA: ABS time=" + cur.time); 1643 cur.readFromParcel(src); 1644 return; 1645 } else if (deltaTimeToken == DELTA_TIME_INT) { 1646 int delta = src.readInt(); 1647 cur.time += delta; 1648 cur.numReadInts += 1; 1649 if (DEBUG) Slog.i(TAG, "READ DELTA: time delta=" + delta + " new time=" + cur.time); 1650 } else { 1651 long delta = src.readLong(); 1652 if (DEBUG) Slog.i(TAG, "READ DELTA: time delta=" + delta + " new time=" + cur.time); 1653 cur.time += delta; 1654 cur.numReadInts += 2; 1655 } 1656 1657 if ((firstToken&DELTA_BATTERY_LEVEL_FLAG) != 0) { 1658 int batteryLevelInt = src.readInt(); 1659 cur.batteryLevel = (byte)((batteryLevelInt>>25)&0x7f); 1660 cur.batteryTemperature = (short)((batteryLevelInt<<7)>>21); 1661 cur.batteryVoltage = (char)(batteryLevelInt&0x3fff); 1662 cur.numReadInts += 1; 1663 if (DEBUG) Slog.i(TAG, "READ DELTA: batteryToken=0x" 1664 + Integer.toHexString(batteryLevelInt) 1665 + " batteryLevel=" + cur.batteryLevel 1666 + " batteryTemp=" + cur.batteryTemperature 1667 + " batteryVolt=" + (int)cur.batteryVoltage); 1668 } 1669 1670 if ((firstToken&DELTA_STATE_FLAG) != 0) { 1671 int stateInt = src.readInt(); 1672 cur.states = (firstToken&DELTA_STATE_MASK) | (stateInt&(~DELTA_STATE_MASK)); 1673 cur.batteryStatus = (byte)((stateInt>>28)&0xf); 1674 cur.batteryHealth = (byte)((stateInt>>24)&0xf); 1675 cur.batteryPlugType = (byte)((stateInt>>22)&0x3); 1676 cur.numReadInts += 1; 1677 if (DEBUG) Slog.i(TAG, "READ DELTA: stateToken=0x" 1678 + Integer.toHexString(stateInt) 1679 + " batteryStatus=" + cur.batteryStatus 1680 + " batteryHealth=" + cur.batteryHealth 1681 + " batteryPlugType=" + cur.batteryPlugType 1682 + " states=0x" + Integer.toHexString(cur.states)); 1683 } else { 1684 cur.states = (firstToken&DELTA_STATE_MASK) | (cur.states&(~DELTA_STATE_MASK)); 1685 } 1686 1687 if ((firstToken&DELTA_WAKELOCK_FLAG) != 0) { 1688 cur.wakelockTag = cur.localWakelockTag; 1689 int index = src.readInt(); 1690 readHistoryTag(index, cur.wakelockTag); 1691 cur.numReadInts += 1; 1692 if (DEBUG) Slog.i(TAG, "READ DELTA: wakelockTag=#" + cur.wakelockTag.poolIdx 1693 + " " + cur.wakelockTag.uid + ":" + cur.wakelockTag.string); 1694 } else { 1695 cur.wakelockTag = null; 1696 } 1697 1698 if ((firstToken&DELTA_EVENT_FLAG) != 0) { 1699 cur.eventTag = cur.localEventTag; 1700 final int codeAndIndex = src.readInt(); 1701 cur.eventCode = (codeAndIndex&0xffff); 1702 final int index = ((codeAndIndex>>16)&0xffff); 1703 readHistoryTag(index, cur.eventTag); 1704 cur.numReadInts += 1; 1705 if (DEBUG) Slog.i(TAG, "READ DELTA: event=" + cur.eventCode + " tag=#" 1706 + cur.eventTag.poolIdx + " " + cur.eventTag.uid + ":" 1707 + cur.eventTag.string); 1708 } else { 1709 cur.eventCode = HistoryItem.EVENT_NONE; 1710 } 1711 } 1712 1713 void addHistoryBufferLocked(long curTime) { 1714 if (!mHaveBatteryLevel || !mRecordingHistory) { 1715 return; 1716 } 1717 1718 final long timeDiff = (mHistoryBaseTime+curTime) - mHistoryLastWritten.time; 1719 final int diffStates = mHistoryLastWritten.states^mHistoryCur.states; 1720 final int lastDiffStates = mHistoryLastWritten.states^mHistoryLastLastWritten.states; 1721 if (DEBUG) Slog.i(TAG, "ADD: tdelta=" + timeDiff + " diff=" 1722 + Integer.toHexString(diffStates) + " lastDiff=" 1723 + Integer.toHexString(lastDiffStates)); 1724 if (mHistoryBufferLastPos >= 0 && mHistoryLastWritten.cmd == HistoryItem.CMD_UPDATE 1725 && timeDiff < 1000 && (diffStates&lastDiffStates) == 0 1726 && (mHistoryLastWritten.wakelockTag == null || mHistoryCur.wakelockTag == null) 1727 && (mHistoryLastWritten.eventCode == HistoryItem.EVENT_NONE 1728 || mHistoryCur.eventCode == HistoryItem.EVENT_NONE) 1729 && mHistoryLastWritten.batteryLevel == mHistoryCur.batteryLevel 1730 && mHistoryLastWritten.batteryStatus == mHistoryCur.batteryStatus 1731 && mHistoryLastWritten.batteryHealth == mHistoryCur.batteryHealth 1732 && mHistoryLastWritten.batteryPlugType == mHistoryCur.batteryPlugType 1733 && mHistoryLastWritten.batteryTemperature == mHistoryCur.batteryTemperature 1734 && mHistoryLastWritten.batteryVoltage == mHistoryCur.batteryVoltage) { 1735 // We can merge this new change in with the last one. Merging is 1736 // allows as long as only the states have changed, and within those states 1737 // as long as no bit has changed both between now and the last entry, as 1738 // well as the last entry and the one before it (so we capture any toggles). 1739 if (DEBUG) Slog.i(TAG, "ADD: rewinding back to " + mHistoryBufferLastPos); 1740 mHistoryBuffer.setDataSize(mHistoryBufferLastPos); 1741 mHistoryBuffer.setDataPosition(mHistoryBufferLastPos); 1742 mHistoryBufferLastPos = -1; 1743 curTime = mHistoryLastWritten.time - mHistoryBaseTime; 1744 // If the last written history had a wakelock tag, we need to retain it. 1745 // Note that the condition above made sure that we aren't in a case where 1746 // both it and the current history item have a wakelock tag. 1747 if (mHistoryLastWritten.wakelockTag != null) { 1748 mHistoryCur.wakelockTag = mHistoryCur.localWakelockTag; 1749 mHistoryCur.wakelockTag.setTo(mHistoryLastWritten.wakelockTag); 1750 } 1751 // If the last written history had an event, we need to retain it. 1752 // Note that the condition above made sure that we aren't in a case where 1753 // both it and the current history item have an event. 1754 if (mHistoryLastWritten.eventCode != HistoryItem.EVENT_NONE) { 1755 mHistoryCur.eventCode = mHistoryLastWritten.eventCode; 1756 mHistoryCur.eventTag = mHistoryCur.localEventTag; 1757 mHistoryCur.eventTag.setTo(mHistoryLastWritten.eventTag); 1758 } 1759 mHistoryLastWritten.setTo(mHistoryLastLastWritten); 1760 } 1761 1762 final int dataSize = mHistoryBuffer.dataSize(); 1763 if (dataSize >= MAX_HISTORY_BUFFER) { 1764 if (!mHistoryOverflow) { 1765 mHistoryOverflow = true; 1766 addHistoryBufferLocked(curTime, HistoryItem.CMD_UPDATE); 1767 addHistoryBufferLocked(curTime, HistoryItem.CMD_OVERFLOW); 1768 return; 1769 } 1770 1771 // Once we've reached the maximum number of items, we only 1772 // record changes to the battery level and the most interesting states. 1773 // Once we've reached the maximum maximum number of items, we only 1774 // record changes to the battery level. 1775 if (mHistoryLastWritten.batteryLevel == mHistoryCur.batteryLevel && 1776 (dataSize >= MAX_MAX_HISTORY_BUFFER 1777 || ((mHistoryLastWritten.states^mHistoryCur.states) 1778 & HistoryItem.MOST_INTERESTING_STATES) == 0)) { 1779 return; 1780 } 1781 1782 addHistoryBufferLocked(curTime, HistoryItem.CMD_UPDATE); 1783 return; 1784 } 1785 1786 addHistoryBufferLocked(curTime, HistoryItem.CMD_UPDATE); 1787 } 1788 1789 private void addHistoryBufferLocked(long curTime, byte cmd) { 1790 if (mIteratingHistory) { 1791 throw new IllegalStateException("Can't do this while iterating history!"); 1792 } 1793 mHistoryBufferLastPos = mHistoryBuffer.dataPosition(); 1794 mHistoryLastLastWritten.setTo(mHistoryLastWritten); 1795 mHistoryLastWritten.setTo(mHistoryBaseTime + curTime, cmd, mHistoryCur); 1796 writeHistoryDelta(mHistoryBuffer, mHistoryLastWritten, mHistoryLastLastWritten); 1797 mLastHistoryTime = curTime; 1798 mHistoryCur.wakelockTag = null; 1799 mHistoryCur.eventCode = HistoryItem.EVENT_NONE; 1800 mHistoryCur.eventTag = null; 1801 if (DEBUG_HISTORY) Slog.i(TAG, "Writing history buffer: was " + mHistoryBufferLastPos 1802 + " now " + mHistoryBuffer.dataPosition() 1803 + " size is now " + mHistoryBuffer.dataSize()); 1804 } 1805 1806 int mChangedStates = 0; 1807 1808 void addHistoryRecordLocked(long curTime) { 1809 addHistoryBufferLocked(curTime); 1810 1811 if (!USE_OLD_HISTORY) { 1812 return; 1813 } 1814 1815 if (!mHaveBatteryLevel || !mRecordingHistory) { 1816 return; 1817 } 1818 1819 // If the current time is basically the same as the last time, 1820 // and no states have since the last recorded entry changed and 1821 // are now resetting back to their original value, then just collapse 1822 // into one record. 1823 if (mHistoryEnd != null && mHistoryEnd.cmd == HistoryItem.CMD_UPDATE 1824 && (mHistoryBaseTime+curTime) < (mHistoryEnd.time+2000) 1825 && ((mHistoryEnd.states^mHistoryCur.states)&mChangedStates) == 0) { 1826 // If the current is the same as the one before, then we no 1827 // longer need the entry. 1828 if (mHistoryLastEnd != null && mHistoryLastEnd.cmd == HistoryItem.CMD_UPDATE 1829 && (mHistoryBaseTime+curTime) < (mHistoryEnd.time+500) 1830 && mHistoryLastEnd.sameNonEvent(mHistoryCur)) { 1831 mHistoryLastEnd.next = null; 1832 mHistoryEnd.next = mHistoryCache; 1833 mHistoryCache = mHistoryEnd; 1834 mHistoryEnd = mHistoryLastEnd; 1835 mHistoryLastEnd = null; 1836 } else { 1837 mChangedStates |= mHistoryEnd.states^mHistoryCur.states; 1838 mHistoryEnd.setTo(mHistoryEnd.time, HistoryItem.CMD_UPDATE, mHistoryCur); 1839 } 1840 return; 1841 } 1842 1843 mChangedStates = 0; 1844 1845 if (mNumHistoryItems == MAX_HISTORY_ITEMS 1846 || mNumHistoryItems == MAX_MAX_HISTORY_ITEMS) { 1847 addHistoryRecordLocked(curTime, HistoryItem.CMD_OVERFLOW); 1848 } 1849 1850 if (mNumHistoryItems >= MAX_HISTORY_ITEMS) { 1851 // Once we've reached the maximum number of items, we only 1852 // record changes to the battery level and the most interesting states. 1853 // Once we've reached the maximum maximum number of items, we only 1854 // record changes to the battery level. 1855 if (mHistoryEnd != null && mHistoryEnd.batteryLevel 1856 == mHistoryCur.batteryLevel && 1857 (mNumHistoryItems >= MAX_MAX_HISTORY_ITEMS 1858 || ((mHistoryEnd.states^mHistoryCur.states) 1859 & HistoryItem.MOST_INTERESTING_STATES) == 0)) { 1860 return; 1861 } 1862 } 1863 1864 addHistoryRecordLocked(curTime, HistoryItem.CMD_UPDATE); 1865 } 1866 1867 void addHistoryEventLocked(long curTime, int code, String name, int uid) { 1868 mHistoryCur.eventCode = code; 1869 mHistoryCur.eventTag = mHistoryCur.localEventTag; 1870 mHistoryCur.eventTag.string = name; 1871 mHistoryCur.eventTag.uid = uid; 1872 addHistoryBufferLocked(curTime); 1873 } 1874 1875 void addHistoryRecordLocked(long curTime, byte cmd) { 1876 HistoryItem rec = mHistoryCache; 1877 if (rec != null) { 1878 mHistoryCache = rec.next; 1879 } else { 1880 rec = new HistoryItem(); 1881 } 1882 rec.setTo(mHistoryBaseTime + curTime, cmd, mHistoryCur); 1883 1884 addHistoryRecordLocked(rec); 1885 } 1886 1887 void addHistoryRecordLocked(HistoryItem rec) { 1888 mNumHistoryItems++; 1889 rec.next = null; 1890 mHistoryLastEnd = mHistoryEnd; 1891 if (mHistoryEnd != null) { 1892 mHistoryEnd.next = rec; 1893 mHistoryEnd = rec; 1894 } else { 1895 mHistory = mHistoryEnd = rec; 1896 } 1897 } 1898 1899 void clearHistoryLocked() { 1900 if (DEBUG_HISTORY) Slog.i(TAG, "********** CLEARING HISTORY!"); 1901 if (USE_OLD_HISTORY) { 1902 if (mHistory != null) { 1903 mHistoryEnd.next = mHistoryCache; 1904 mHistoryCache = mHistory; 1905 mHistory = mHistoryLastEnd = mHistoryEnd = null; 1906 } 1907 mNumHistoryItems = 0; 1908 } 1909 1910 mHistoryBaseTime = 0; 1911 mLastHistoryTime = 0; 1912 1913 mHistoryBuffer.setDataSize(0); 1914 mHistoryBuffer.setDataPosition(0); 1915 mHistoryBuffer.setDataCapacity(MAX_HISTORY_BUFFER / 2); 1916 mHistoryLastLastWritten.clear(); 1917 mHistoryLastWritten.clear(); 1918 mHistoryTagPool.clear(); 1919 mNextHistoryTagIdx = 0; 1920 mNumHistoryTagChars = 0; 1921 mHistoryBufferLastPos = -1; 1922 mHistoryOverflow = false; 1923 } 1924 1925 public void doUnplugLocked(long elapsedRealtime, long batteryUptime, long batteryRealtime) { 1926 for (int i = mUnpluggables.size() - 1; i >= 0; i--) { 1927 mUnpluggables.get(i).unplug(elapsedRealtime, batteryUptime, batteryRealtime); 1928 } 1929 1930 // Track radio awake time 1931 mRadioDataStart = getCurrentRadioDataUptime(); 1932 mRadioDataUptime = 0; 1933 1934 // Track bt headset ping count 1935 mBluetoothPingStart = getCurrentBluetoothPingCount(); 1936 mBluetoothPingCount = 0; 1937 } 1938 1939 public void doPlugLocked(long elapsedRealtime, long batteryUptime, long batteryRealtime) { 1940 for (int i = mUnpluggables.size() - 1; i >= 0; i--) { 1941 mUnpluggables.get(i).plug(elapsedRealtime, batteryUptime, batteryRealtime); 1942 } 1943 1944 // Track radio awake time 1945 mRadioDataUptime = getRadioDataUptime(); 1946 mRadioDataStart = -1; 1947 1948 // Track bt headset ping count 1949 mBluetoothPingCount = getBluetoothPingCount(); 1950 mBluetoothPingStart = -1; 1951 } 1952 1953 public void addIsolatedUidLocked(int isolatedUid, int appUid) { 1954 mIsolatedUids.put(isolatedUid, appUid); 1955 } 1956 1957 public void removeIsolatedUidLocked(int isolatedUid, int appUid) { 1958 int curUid = mIsolatedUids.get(isolatedUid, -1); 1959 if (curUid == appUid) { 1960 mIsolatedUids.delete(isolatedUid); 1961 } 1962 } 1963 1964 public int mapUid(int uid) { 1965 int isolated = mIsolatedUids.get(uid, -1); 1966 return isolated > 0 ? isolated : uid; 1967 } 1968 1969 public void noteEventLocked(int code, String name, int uid) { 1970 uid = mapUid(uid); 1971 addHistoryEventLocked(SystemClock.elapsedRealtime(), code, name, uid); 1972 } 1973 1974 public void noteStartWakeLocked(int uid, int pid, String name, int type, 1975 boolean unimportantForLogging) { 1976 uid = mapUid(uid); 1977 if (type == WAKE_TYPE_PARTIAL) { 1978 // Only care about partial wake locks, since full wake locks 1979 // will be canceled when the user puts the screen to sleep. 1980 if (mWakeLockNesting == 0) { 1981 mHistoryCur.states |= HistoryItem.STATE_WAKE_LOCK_FLAG; 1982 if (DEBUG_HISTORY) Slog.v(TAG, "Start wake lock to: " 1983 + Integer.toHexString(mHistoryCur.states)); 1984 mHistoryCur.wakelockTag = mHistoryCur.localWakelockTag; 1985 mHistoryCur.wakelockTag.string = name; 1986 mHistoryCur.wakelockTag.uid = uid; 1987 mWakeLockImportant = !unimportantForLogging; 1988 addHistoryRecordLocked(SystemClock.elapsedRealtime()); 1989 } else if (!mWakeLockImportant && !unimportantForLogging) { 1990 if (mHistoryLastWritten.wakelockTag != null) { 1991 // We'll try to update the last tag. 1992 mHistoryLastWritten.wakelockTag = null; 1993 mHistoryCur.wakelockTag = mHistoryCur.localWakelockTag; 1994 mHistoryCur.wakelockTag.string = name; 1995 mHistoryCur.wakelockTag.uid = uid; 1996 addHistoryRecordLocked(SystemClock.elapsedRealtime()); 1997 } 1998 mWakeLockImportant = true; 1999 } 2000 mWakeLockNesting++; 2001 } 2002 if (uid >= 0) { 2003 if (!mHandler.hasMessages(MSG_UPDATE_WAKELOCKS)) { 2004 Message m = mHandler.obtainMessage(MSG_UPDATE_WAKELOCKS); 2005 mHandler.sendMessageDelayed(m, DELAY_UPDATE_WAKELOCKS); 2006 } 2007 getUidStatsLocked(uid).noteStartWakeLocked(pid, name, type); 2008 } 2009 } 2010 2011 public void noteStopWakeLocked(int uid, int pid, String name, int type) { 2012 uid = mapUid(uid); 2013 if (type == WAKE_TYPE_PARTIAL) { 2014 mWakeLockNesting--; 2015 if (mWakeLockNesting == 0) { 2016 mHistoryCur.states &= ~HistoryItem.STATE_WAKE_LOCK_FLAG; 2017 if (DEBUG_HISTORY) Slog.v(TAG, "Stop wake lock to: " 2018 + Integer.toHexString(mHistoryCur.states)); 2019 addHistoryRecordLocked(SystemClock.elapsedRealtime()); 2020 } 2021 } 2022 if (uid >= 0) { 2023 if (!mHandler.hasMessages(MSG_UPDATE_WAKELOCKS)) { 2024 Message m = mHandler.obtainMessage(MSG_UPDATE_WAKELOCKS); 2025 mHandler.sendMessageDelayed(m, DELAY_UPDATE_WAKELOCKS); 2026 } 2027 getUidStatsLocked(uid).noteStopWakeLocked(pid, name, type); 2028 } 2029 } 2030 2031 public void noteStartWakeFromSourceLocked(WorkSource ws, int pid, String name, int type, 2032 boolean unimportantForLogging) { 2033 int N = ws.size(); 2034 for (int i=0; i<N; i++) { 2035 noteStartWakeLocked(ws.get(i), pid, name, type, unimportantForLogging); 2036 } 2037 } 2038 2039 public void noteStopWakeFromSourceLocked(WorkSource ws, int pid, String name, int type) { 2040 int N = ws.size(); 2041 for (int i=0; i<N; i++) { 2042 noteStopWakeLocked(ws.get(i), pid, name, type); 2043 } 2044 } 2045 2046 public int startAddingCpuLocked() { 2047 mHandler.removeMessages(MSG_UPDATE_WAKELOCKS); 2048 2049 if (mScreenOn) { 2050 return 0; 2051 } 2052 2053 final int N = mPartialTimers.size(); 2054 if (N == 0) { 2055 mLastPartialTimers.clear(); 2056 return 0; 2057 } 2058 2059 // How many timers should consume CPU? Only want to include ones 2060 // that have already been in the list. 2061 for (int i=0; i<N; i++) { 2062 StopwatchTimer st = mPartialTimers.get(i); 2063 if (st.mInList) { 2064 Uid uid = st.mUid; 2065 // We don't include the system UID, because it so often 2066 // holds wake locks at one request or another of an app. 2067 if (uid != null && uid.mUid != Process.SYSTEM_UID) { 2068 return 50; 2069 } 2070 } 2071 } 2072 2073 return 0; 2074 } 2075 2076 public void finishAddingCpuLocked(int perc, int utime, int stime, long[] cpuSpeedTimes) { 2077 final int N = mPartialTimers.size(); 2078 if (perc != 0) { 2079 int num = 0; 2080 for (int i=0; i<N; i++) { 2081 StopwatchTimer st = mPartialTimers.get(i); 2082 if (st.mInList) { 2083 Uid uid = st.mUid; 2084 // We don't include the system UID, because it so often 2085 // holds wake locks at one request or another of an app. 2086 if (uid != null && uid.mUid != Process.SYSTEM_UID) { 2087 num++; 2088 } 2089 } 2090 } 2091 if (num != 0) { 2092 for (int i=0; i<N; i++) { 2093 StopwatchTimer st = mPartialTimers.get(i); 2094 if (st.mInList) { 2095 Uid uid = st.mUid; 2096 if (uid != null && uid.mUid != Process.SYSTEM_UID) { 2097 int myUTime = utime/num; 2098 int mySTime = stime/num; 2099 utime -= myUTime; 2100 stime -= mySTime; 2101 num--; 2102 Uid.Proc proc = uid.getProcessStatsLocked("*wakelock*"); 2103 proc.addCpuTimeLocked(myUTime, mySTime); 2104 proc.addSpeedStepTimes(cpuSpeedTimes); 2105 } 2106 } 2107 } 2108 } 2109 2110 // Just in case, collect any lost CPU time. 2111 if (utime != 0 || stime != 0) { 2112 Uid uid = getUidStatsLocked(Process.SYSTEM_UID); 2113 if (uid != null) { 2114 Uid.Proc proc = uid.getProcessStatsLocked("*lost*"); 2115 proc.addCpuTimeLocked(utime, stime); 2116 proc.addSpeedStepTimes(cpuSpeedTimes); 2117 } 2118 } 2119 } 2120 2121 final int NL = mLastPartialTimers.size(); 2122 boolean diff = N != NL; 2123 for (int i=0; i<NL && !diff; i++) { 2124 diff |= mPartialTimers.get(i) != mLastPartialTimers.get(i); 2125 } 2126 if (!diff) { 2127 for (int i=0; i<NL; i++) { 2128 mPartialTimers.get(i).mInList = true; 2129 } 2130 return; 2131 } 2132 2133 for (int i=0; i<NL; i++) { 2134 mLastPartialTimers.get(i).mInList = false; 2135 } 2136 mLastPartialTimers.clear(); 2137 for (int i=0; i<N; i++) { 2138 StopwatchTimer st = mPartialTimers.get(i); 2139 st.mInList = true; 2140 mLastPartialTimers.add(st); 2141 } 2142 } 2143 2144 public void noteProcessDiedLocked(int uid, int pid) { 2145 uid = mapUid(uid); 2146 Uid u = mUidStats.get(uid); 2147 if (u != null) { 2148 u.mPids.remove(pid); 2149 } 2150 } 2151 2152 public long getProcessWakeTime(int uid, int pid, long realtime) { 2153 uid = mapUid(uid); 2154 Uid u = mUidStats.get(uid); 2155 if (u != null) { 2156 Uid.Pid p = u.mPids.get(pid); 2157 if (p != null) { 2158 return p.mWakeSum + (p.mWakeStart != 0 ? (realtime - p.mWakeStart) : 0); 2159 } 2160 } 2161 return 0; 2162 } 2163 2164 public void reportExcessiveWakeLocked(int uid, String proc, long overTime, long usedTime) { 2165 uid = mapUid(uid); 2166 Uid u = mUidStats.get(uid); 2167 if (u != null) { 2168 u.reportExcessiveWakeLocked(proc, overTime, usedTime); 2169 } 2170 } 2171 2172 public void reportExcessiveCpuLocked(int uid, String proc, long overTime, long usedTime) { 2173 uid = mapUid(uid); 2174 Uid u = mUidStats.get(uid); 2175 if (u != null) { 2176 u.reportExcessiveCpuLocked(proc, overTime, usedTime); 2177 } 2178 } 2179 2180 int mSensorNesting; 2181 2182 public void noteStartSensorLocked(int uid, int sensor) { 2183 uid = mapUid(uid); 2184 if (mSensorNesting == 0) { 2185 mHistoryCur.states |= HistoryItem.STATE_SENSOR_ON_FLAG; 2186 if (DEBUG_HISTORY) Slog.v(TAG, "Start sensor to: " 2187 + Integer.toHexString(mHistoryCur.states)); 2188 addHistoryRecordLocked(SystemClock.elapsedRealtime()); 2189 } 2190 mSensorNesting++; 2191 getUidStatsLocked(uid).noteStartSensor(sensor); 2192 } 2193 2194 public void noteStopSensorLocked(int uid, int sensor) { 2195 uid = mapUid(uid); 2196 mSensorNesting--; 2197 if (mSensorNesting == 0) { 2198 mHistoryCur.states &= ~HistoryItem.STATE_SENSOR_ON_FLAG; 2199 if (DEBUG_HISTORY) Slog.v(TAG, "Stop sensor to: " 2200 + Integer.toHexString(mHistoryCur.states)); 2201 addHistoryRecordLocked(SystemClock.elapsedRealtime()); 2202 } 2203 getUidStatsLocked(uid).noteStopSensor(sensor); 2204 } 2205 2206 int mGpsNesting; 2207 2208 public void noteStartGpsLocked(int uid) { 2209 uid = mapUid(uid); 2210 if (mGpsNesting == 0) { 2211 mHistoryCur.states |= HistoryItem.STATE_GPS_ON_FLAG; 2212 if (DEBUG_HISTORY) Slog.v(TAG, "Start GPS to: " 2213 + Integer.toHexString(mHistoryCur.states)); 2214 addHistoryRecordLocked(SystemClock.elapsedRealtime()); 2215 } 2216 mGpsNesting++; 2217 getUidStatsLocked(uid).noteStartGps(); 2218 } 2219 2220 public void noteStopGpsLocked(int uid) { 2221 uid = mapUid(uid); 2222 mGpsNesting--; 2223 if (mGpsNesting == 0) { 2224 mHistoryCur.states &= ~HistoryItem.STATE_GPS_ON_FLAG; 2225 if (DEBUG_HISTORY) Slog.v(TAG, "Stop GPS to: " 2226 + Integer.toHexString(mHistoryCur.states)); 2227 addHistoryRecordLocked(SystemClock.elapsedRealtime()); 2228 } 2229 getUidStatsLocked(uid).noteStopGps(); 2230 } 2231 2232 public void noteScreenOnLocked() { 2233 if (!mScreenOn) { 2234 mHistoryCur.states |= HistoryItem.STATE_SCREEN_ON_FLAG; 2235 if (DEBUG_HISTORY) Slog.v(TAG, "Screen on to: " 2236 + Integer.toHexString(mHistoryCur.states)); 2237 addHistoryRecordLocked(SystemClock.elapsedRealtime()); 2238 mScreenOn = true; 2239 mScreenOnTimer.startRunningLocked(this); 2240 if (mScreenBrightnessBin >= 0) { 2241 mScreenBrightnessTimer[mScreenBrightnessBin].startRunningLocked(this); 2242 } 2243 2244 // Fake a wake lock, so we consider the device waked as long 2245 // as the screen is on. 2246 noteStartWakeLocked(-1, -1, "screen", WAKE_TYPE_PARTIAL, false); 2247 2248 // Update discharge amounts. 2249 if (mOnBatteryInternal) { 2250 updateDischargeScreenLevelsLocked(false, true); 2251 } 2252 } 2253 } 2254 2255 public void noteScreenOffLocked() { 2256 if (mScreenOn) { 2257 mHistoryCur.states &= ~HistoryItem.STATE_SCREEN_ON_FLAG; 2258 if (DEBUG_HISTORY) Slog.v(TAG, "Screen off to: " 2259 + Integer.toHexString(mHistoryCur.states)); 2260 addHistoryRecordLocked(SystemClock.elapsedRealtime()); 2261 mScreenOn = false; 2262 mScreenOnTimer.stopRunningLocked(this); 2263 if (mScreenBrightnessBin >= 0) { 2264 mScreenBrightnessTimer[mScreenBrightnessBin].stopRunningLocked(this); 2265 } 2266 2267 noteStopWakeLocked(-1, -1, "dummy", WAKE_TYPE_PARTIAL); 2268 2269 // Update discharge amounts. 2270 if (mOnBatteryInternal) { 2271 updateDischargeScreenLevelsLocked(true, false); 2272 } 2273 } 2274 } 2275 2276 public void noteScreenBrightnessLocked(int brightness) { 2277 // Bin the brightness. 2278 int bin = brightness / (256/NUM_SCREEN_BRIGHTNESS_BINS); 2279 if (bin < 0) bin = 0; 2280 else if (bin >= NUM_SCREEN_BRIGHTNESS_BINS) bin = NUM_SCREEN_BRIGHTNESS_BINS-1; 2281 if (mScreenBrightnessBin != bin) { 2282 mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_BRIGHTNESS_MASK) 2283 | (bin << HistoryItem.STATE_BRIGHTNESS_SHIFT); 2284 if (DEBUG_HISTORY) Slog.v(TAG, "Screen brightness " + bin + " to: " 2285 + Integer.toHexString(mHistoryCur.states)); 2286 addHistoryRecordLocked(SystemClock.elapsedRealtime()); 2287 if (mScreenOn) { 2288 if (mScreenBrightnessBin >= 0) { 2289 mScreenBrightnessTimer[mScreenBrightnessBin].stopRunningLocked(this); 2290 } 2291 mScreenBrightnessTimer[bin].startRunningLocked(this); 2292 } 2293 mScreenBrightnessBin = bin; 2294 } 2295 } 2296 2297 public void noteInputEventAtomic() { 2298 mInputEventCounter.stepAtomic(); 2299 } 2300 2301 public void noteUserActivityLocked(int uid, int event) { 2302 uid = mapUid(uid); 2303 getUidStatsLocked(uid).noteUserActivityLocked(event); 2304 } 2305 2306 public void notePhoneOnLocked() { 2307 if (!mPhoneOn) { 2308 mHistoryCur.states |= HistoryItem.STATE_PHONE_IN_CALL_FLAG; 2309 if (DEBUG_HISTORY) Slog.v(TAG, "Phone on to: " 2310 + Integer.toHexString(mHistoryCur.states)); 2311 addHistoryRecordLocked(SystemClock.elapsedRealtime()); 2312 mPhoneOn = true; 2313 mPhoneOnTimer.startRunningLocked(this); 2314 } 2315 } 2316 2317 public void notePhoneOffLocked() { 2318 if (mPhoneOn) { 2319 mHistoryCur.states &= ~HistoryItem.STATE_PHONE_IN_CALL_FLAG; 2320 if (DEBUG_HISTORY) Slog.v(TAG, "Phone off to: " 2321 + Integer.toHexString(mHistoryCur.states)); 2322 addHistoryRecordLocked(SystemClock.elapsedRealtime()); 2323 mPhoneOn = false; 2324 mPhoneOnTimer.stopRunningLocked(this); 2325 } 2326 } 2327 2328 void stopAllSignalStrengthTimersLocked(int except) { 2329 for (int i = 0; i < SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) { 2330 if (i == except) { 2331 continue; 2332 } 2333 while (mPhoneSignalStrengthsTimer[i].isRunningLocked()) { 2334 mPhoneSignalStrengthsTimer[i].stopRunningLocked(this); 2335 } 2336 } 2337 } 2338 2339 private int fixPhoneServiceState(int state, int signalBin) { 2340 if (mPhoneSimStateRaw == TelephonyManager.SIM_STATE_ABSENT) { 2341 // In this case we will always be STATE_OUT_OF_SERVICE, so need 2342 // to infer that we are scanning from other data. 2343 if (state == ServiceState.STATE_OUT_OF_SERVICE 2344 && signalBin > SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN) { 2345 state = ServiceState.STATE_IN_SERVICE; 2346 } 2347 } 2348 2349 return state; 2350 } 2351 2352 private void updateAllPhoneStateLocked(int state, int simState, int bin) { 2353 boolean scanning = false; 2354 boolean newHistory = false; 2355 2356 mPhoneServiceStateRaw = state; 2357 mPhoneSimStateRaw = simState; 2358 mPhoneSignalStrengthBinRaw = bin; 2359 2360 if (simState == TelephonyManager.SIM_STATE_ABSENT) { 2361 // In this case we will always be STATE_OUT_OF_SERVICE, so need 2362 // to infer that we are scanning from other data. 2363 if (state == ServiceState.STATE_OUT_OF_SERVICE 2364 && bin > SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN) { 2365 state = ServiceState.STATE_IN_SERVICE; 2366 } 2367 } 2368 2369 // If the phone is powered off, stop all timers. 2370 if (state == ServiceState.STATE_POWER_OFF) { 2371 bin = -1; 2372 2373 // If we are in service, make sure the correct signal string timer is running. 2374 } else if (state == ServiceState.STATE_IN_SERVICE) { 2375 // Bin will be changed below. 2376 2377 // If we're out of service, we are in the lowest signal strength 2378 // bin and have the scanning bit set. 2379 } else if (state == ServiceState.STATE_OUT_OF_SERVICE) { 2380 scanning = true; 2381 bin = SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN; 2382 if (!mPhoneSignalScanningTimer.isRunningLocked()) { 2383 mHistoryCur.states |= HistoryItem.STATE_PHONE_SCANNING_FLAG; 2384 newHistory = true; 2385 if (DEBUG_HISTORY) Slog.v(TAG, "Phone started scanning to: " 2386 + Integer.toHexString(mHistoryCur.states)); 2387 mPhoneSignalScanningTimer.startRunningLocked(this); 2388 } 2389 } 2390 2391 if (!scanning) { 2392 // If we are no longer scanning, then stop the scanning timer. 2393 if (mPhoneSignalScanningTimer.isRunningLocked()) { 2394 mHistoryCur.states &= ~HistoryItem.STATE_PHONE_SCANNING_FLAG; 2395 if (DEBUG_HISTORY) Slog.v(TAG, "Phone stopped scanning to: " 2396 + Integer.toHexString(mHistoryCur.states)); 2397 newHistory = true; 2398 mPhoneSignalScanningTimer.stopRunningLocked(this); 2399 } 2400 } 2401 2402 if (mPhoneServiceState != state) { 2403 mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_PHONE_STATE_MASK) 2404 | (state << HistoryItem.STATE_PHONE_STATE_SHIFT); 2405 if (DEBUG_HISTORY) Slog.v(TAG, "Phone state " + state + " to: " 2406 + Integer.toHexString(mHistoryCur.states)); 2407 newHistory = true; 2408 mPhoneServiceState = state; 2409 } 2410 2411 if (mPhoneSignalStrengthBin != bin) { 2412 if (mPhoneSignalStrengthBin >= 0) { 2413 mPhoneSignalStrengthsTimer[mPhoneSignalStrengthBin].stopRunningLocked(this); 2414 } 2415 if (bin >= 0) { 2416 if (!mPhoneSignalStrengthsTimer[bin].isRunningLocked()) { 2417 mPhoneSignalStrengthsTimer[bin].startRunningLocked(this); 2418 } 2419 mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_SIGNAL_STRENGTH_MASK) 2420 | (bin << HistoryItem.STATE_SIGNAL_STRENGTH_SHIFT); 2421 if (DEBUG_HISTORY) Slog.v(TAG, "Signal strength " + bin + " to: " 2422 + Integer.toHexString(mHistoryCur.states)); 2423 newHistory = true; 2424 } else { 2425 stopAllSignalStrengthTimersLocked(-1); 2426 } 2427 mPhoneSignalStrengthBin = bin; 2428 } 2429 2430 if (newHistory) { 2431 addHistoryRecordLocked(SystemClock.elapsedRealtime()); 2432 } 2433 } 2434 2435 /** 2436 * Telephony stack updates the phone state. 2437 * @param state phone state from ServiceState.getState() 2438 */ 2439 public void notePhoneStateLocked(int state, int simState) { 2440 updateAllPhoneStateLocked(state, simState, mPhoneSignalStrengthBinRaw); 2441 } 2442 2443 public void notePhoneSignalStrengthLocked(SignalStrength signalStrength) { 2444 // Bin the strength. 2445 int bin = signalStrength.getLevel(); 2446 updateAllPhoneStateLocked(mPhoneServiceStateRaw, mPhoneSimStateRaw, bin); 2447 } 2448 2449 public void notePhoneDataConnectionStateLocked(int dataType, boolean hasData) { 2450 int bin = DATA_CONNECTION_NONE; 2451 if (hasData) { 2452 switch (dataType) { 2453 case TelephonyManager.NETWORK_TYPE_EDGE: 2454 bin = DATA_CONNECTION_EDGE; 2455 break; 2456 case TelephonyManager.NETWORK_TYPE_GPRS: 2457 bin = DATA_CONNECTION_GPRS; 2458 break; 2459 case TelephonyManager.NETWORK_TYPE_UMTS: 2460 bin = DATA_CONNECTION_UMTS; 2461 break; 2462 case TelephonyManager.NETWORK_TYPE_CDMA: 2463 bin = DATA_CONNECTION_CDMA; 2464 break; 2465 case TelephonyManager.NETWORK_TYPE_EVDO_0: 2466 bin = DATA_CONNECTION_EVDO_0; 2467 break; 2468 case TelephonyManager.NETWORK_TYPE_EVDO_A: 2469 bin = DATA_CONNECTION_EVDO_A; 2470 break; 2471 case TelephonyManager.NETWORK_TYPE_1xRTT: 2472 bin = DATA_CONNECTION_1xRTT; 2473 break; 2474 case TelephonyManager.NETWORK_TYPE_HSDPA: 2475 bin = DATA_CONNECTION_HSDPA; 2476 break; 2477 case TelephonyManager.NETWORK_TYPE_HSUPA: 2478 bin = DATA_CONNECTION_HSUPA; 2479 break; 2480 case TelephonyManager.NETWORK_TYPE_HSPA: 2481 bin = DATA_CONNECTION_HSPA; 2482 break; 2483 case TelephonyManager.NETWORK_TYPE_IDEN: 2484 bin = DATA_CONNECTION_IDEN; 2485 break; 2486 case TelephonyManager.NETWORK_TYPE_EVDO_B: 2487 bin = DATA_CONNECTION_EVDO_B; 2488 break; 2489 case TelephonyManager.NETWORK_TYPE_LTE: 2490 bin = DATA_CONNECTION_LTE; 2491 break; 2492 case TelephonyManager.NETWORK_TYPE_EHRPD: 2493 bin = DATA_CONNECTION_EHRPD; 2494 break; 2495 case TelephonyManager.NETWORK_TYPE_HSPAP: 2496 bin = DATA_CONNECTION_HSPAP; 2497 break; 2498 default: 2499 bin = DATA_CONNECTION_OTHER; 2500 break; 2501 } 2502 } 2503 if (DEBUG) Log.i(TAG, "Phone Data Connection -> " + dataType + " = " + hasData); 2504 if (mPhoneDataConnectionType != bin) { 2505 mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_DATA_CONNECTION_MASK) 2506 | (bin << HistoryItem.STATE_DATA_CONNECTION_SHIFT); 2507 if (DEBUG_HISTORY) Slog.v(TAG, "Data connection " + bin + " to: " 2508 + Integer.toHexString(mHistoryCur.states)); 2509 addHistoryRecordLocked(SystemClock.elapsedRealtime()); 2510 if (mPhoneDataConnectionType >= 0) { 2511 mPhoneDataConnectionsTimer[mPhoneDataConnectionType].stopRunningLocked(this); 2512 } 2513 mPhoneDataConnectionType = bin; 2514 mPhoneDataConnectionsTimer[bin].startRunningLocked(this); 2515 } 2516 } 2517 2518 public void noteWifiOnLocked() { 2519 if (!mWifiOn) { 2520 mHistoryCur.states |= HistoryItem.STATE_WIFI_ON_FLAG; 2521 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI on to: " 2522 + Integer.toHexString(mHistoryCur.states)); 2523 addHistoryRecordLocked(SystemClock.elapsedRealtime()); 2524 mWifiOn = true; 2525 mWifiOnTimer.startRunningLocked(this); 2526 } 2527 } 2528 2529 public void noteWifiOffLocked() { 2530 if (mWifiOn) { 2531 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_ON_FLAG; 2532 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI off to: " 2533 + Integer.toHexString(mHistoryCur.states)); 2534 addHistoryRecordLocked(SystemClock.elapsedRealtime()); 2535 mWifiOn = false; 2536 mWifiOnTimer.stopRunningLocked(this); 2537 } 2538 if (mWifiOnUid >= 0) { 2539 getUidStatsLocked(mWifiOnUid).noteWifiStoppedLocked(); 2540 mWifiOnUid = -1; 2541 } 2542 } 2543 2544 public void noteAudioOnLocked(int uid) { 2545 uid = mapUid(uid); 2546 if (!mAudioOn) { 2547 mHistoryCur.states |= HistoryItem.STATE_AUDIO_ON_FLAG; 2548 if (DEBUG_HISTORY) Slog.v(TAG, "Audio on to: " 2549 + Integer.toHexString(mHistoryCur.states)); 2550 addHistoryRecordLocked(SystemClock.elapsedRealtime()); 2551 mAudioOn = true; 2552 mAudioOnTimer.startRunningLocked(this); 2553 } 2554 getUidStatsLocked(uid).noteAudioTurnedOnLocked(); 2555 } 2556 2557 public void noteAudioOffLocked(int uid) { 2558 uid = mapUid(uid); 2559 if (mAudioOn) { 2560 mHistoryCur.states &= ~HistoryItem.STATE_AUDIO_ON_FLAG; 2561 if (DEBUG_HISTORY) Slog.v(TAG, "Audio off to: " 2562 + Integer.toHexString(mHistoryCur.states)); 2563 addHistoryRecordLocked(SystemClock.elapsedRealtime()); 2564 mAudioOn = false; 2565 mAudioOnTimer.stopRunningLocked(this); 2566 } 2567 getUidStatsLocked(uid).noteAudioTurnedOffLocked(); 2568 } 2569 2570 public void noteVideoOnLocked(int uid) { 2571 uid = mapUid(uid); 2572 if (!mVideoOn) { 2573 mHistoryCur.states |= HistoryItem.STATE_VIDEO_ON_FLAG; 2574 if (DEBUG_HISTORY) Slog.v(TAG, "Video on to: " 2575 + Integer.toHexString(mHistoryCur.states)); 2576 addHistoryRecordLocked(SystemClock.elapsedRealtime()); 2577 mVideoOn = true; 2578 mVideoOnTimer.startRunningLocked(this); 2579 } 2580 getUidStatsLocked(uid).noteVideoTurnedOnLocked(); 2581 } 2582 2583 public void noteVideoOffLocked(int uid) { 2584 uid = mapUid(uid); 2585 if (mVideoOn) { 2586 mHistoryCur.states &= ~HistoryItem.STATE_VIDEO_ON_FLAG; 2587 if (DEBUG_HISTORY) Slog.v(TAG, "Video off to: " 2588 + Integer.toHexString(mHistoryCur.states)); 2589 addHistoryRecordLocked(SystemClock.elapsedRealtime()); 2590 mVideoOn = false; 2591 mVideoOnTimer.stopRunningLocked(this); 2592 } 2593 getUidStatsLocked(uid).noteVideoTurnedOffLocked(); 2594 } 2595 2596 public void noteActivityResumedLocked(int uid) { 2597 uid = mapUid(uid); 2598 getUidStatsLocked(uid).noteActivityResumedLocked(); 2599 } 2600 2601 public void noteActivityPausedLocked(int uid) { 2602 uid = mapUid(uid); 2603 getUidStatsLocked(uid).noteActivityPausedLocked(); 2604 } 2605 2606 public void noteVibratorOnLocked(int uid, long durationMillis) { 2607 uid = mapUid(uid); 2608 getUidStatsLocked(uid).noteVibratorOnLocked(durationMillis); 2609 } 2610 2611 public void noteVibratorOffLocked(int uid) { 2612 uid = mapUid(uid); 2613 getUidStatsLocked(uid).noteVibratorOffLocked(); 2614 } 2615 2616 public void noteWifiRunningLocked(WorkSource ws) { 2617 if (!mGlobalWifiRunning) { 2618 mHistoryCur.states |= HistoryItem.STATE_WIFI_RUNNING_FLAG; 2619 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI running to: " 2620 + Integer.toHexString(mHistoryCur.states)); 2621 addHistoryRecordLocked(SystemClock.elapsedRealtime()); 2622 mGlobalWifiRunning = true; 2623 mGlobalWifiRunningTimer.startRunningLocked(this); 2624 int N = ws.size(); 2625 for (int i=0; i<N; i++) { 2626 int uid = mapUid(ws.get(i)); 2627 getUidStatsLocked(uid).noteWifiRunningLocked(); 2628 } 2629 } else { 2630 Log.w(TAG, "noteWifiRunningLocked -- called while WIFI running"); 2631 } 2632 } 2633 2634 public void noteWifiRunningChangedLocked(WorkSource oldWs, WorkSource newWs) { 2635 if (mGlobalWifiRunning) { 2636 int N = oldWs.size(); 2637 for (int i=0; i<N; i++) { 2638 int uid = mapUid(oldWs.get(i)); 2639 getUidStatsLocked(uid).noteWifiStoppedLocked(); 2640 } 2641 N = newWs.size(); 2642 for (int i=0; i<N; i++) { 2643 int uid = mapUid(newWs.get(i)); 2644 getUidStatsLocked(uid).noteWifiRunningLocked(); 2645 } 2646 } else { 2647 Log.w(TAG, "noteWifiRunningChangedLocked -- called while WIFI not running"); 2648 } 2649 } 2650 2651 public void noteWifiStoppedLocked(WorkSource ws) { 2652 if (mGlobalWifiRunning) { 2653 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_RUNNING_FLAG; 2654 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI stopped to: " 2655 + Integer.toHexString(mHistoryCur.states)); 2656 addHistoryRecordLocked(SystemClock.elapsedRealtime()); 2657 mGlobalWifiRunning = false; 2658 mGlobalWifiRunningTimer.stopRunningLocked(this); 2659 int N = ws.size(); 2660 for (int i=0; i<N; i++) { 2661 int uid = mapUid(ws.get(i)); 2662 getUidStatsLocked(uid).noteWifiStoppedLocked(); 2663 } 2664 } else { 2665 Log.w(TAG, "noteWifiStoppedLocked -- called while WIFI not running"); 2666 } 2667 } 2668 2669 public void noteBluetoothOnLocked() { 2670 if (!mBluetoothOn) { 2671 mHistoryCur.states |= HistoryItem.STATE_BLUETOOTH_ON_FLAG; 2672 if (DEBUG_HISTORY) Slog.v(TAG, "Bluetooth on to: " 2673 + Integer.toHexString(mHistoryCur.states)); 2674 addHistoryRecordLocked(SystemClock.elapsedRealtime()); 2675 mBluetoothOn = true; 2676 mBluetoothOnTimer.startRunningLocked(this); 2677 } 2678 } 2679 2680 public void noteBluetoothOffLocked() { 2681 if (mBluetoothOn) { 2682 mHistoryCur.states &= ~HistoryItem.STATE_BLUETOOTH_ON_FLAG; 2683 if (DEBUG_HISTORY) Slog.v(TAG, "Bluetooth off to: " 2684 + Integer.toHexString(mHistoryCur.states)); 2685 addHistoryRecordLocked(SystemClock.elapsedRealtime()); 2686 mBluetoothOn = false; 2687 mBluetoothOnTimer.stopRunningLocked(this); 2688 } 2689 } 2690 2691 int mWifiFullLockNesting = 0; 2692 2693 public void noteFullWifiLockAcquiredLocked(int uid) { 2694 uid = mapUid(uid); 2695 if (mWifiFullLockNesting == 0) { 2696 mHistoryCur.states |= HistoryItem.STATE_WIFI_FULL_LOCK_FLAG; 2697 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI full lock on to: " 2698 + Integer.toHexString(mHistoryCur.states)); 2699 addHistoryRecordLocked(SystemClock.elapsedRealtime()); 2700 } 2701 mWifiFullLockNesting++; 2702 getUidStatsLocked(uid).noteFullWifiLockAcquiredLocked(); 2703 } 2704 2705 public void noteFullWifiLockReleasedLocked(int uid) { 2706 uid = mapUid(uid); 2707 mWifiFullLockNesting--; 2708 if (mWifiFullLockNesting == 0) { 2709 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_FULL_LOCK_FLAG; 2710 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI full lock off to: " 2711 + Integer.toHexString(mHistoryCur.states)); 2712 addHistoryRecordLocked(SystemClock.elapsedRealtime()); 2713 } 2714 getUidStatsLocked(uid).noteFullWifiLockReleasedLocked(); 2715 } 2716 2717 int mWifiScanNesting = 0; 2718 2719 public void noteWifiScanStartedLocked(int uid) { 2720 uid = mapUid(uid); 2721 if (mWifiScanNesting == 0) { 2722 mHistoryCur.states |= HistoryItem.STATE_WIFI_SCAN_FLAG; 2723 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI scan started for: " 2724 + Integer.toHexString(mHistoryCur.states)); 2725 addHistoryRecordLocked(SystemClock.elapsedRealtime()); 2726 } 2727 mWifiScanNesting++; 2728 getUidStatsLocked(uid).noteWifiScanStartedLocked(); 2729 } 2730 2731 public void noteWifiScanStoppedLocked(int uid) { 2732 uid = mapUid(uid); 2733 mWifiScanNesting--; 2734 if (mWifiScanNesting == 0) { 2735 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_SCAN_FLAG; 2736 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI scan stopped for: " 2737 + Integer.toHexString(mHistoryCur.states)); 2738 addHistoryRecordLocked(SystemClock.elapsedRealtime()); 2739 } 2740 getUidStatsLocked(uid).noteWifiScanStoppedLocked(); 2741 } 2742 2743 public void noteWifiBatchedScanStartedLocked(int uid, int csph) { 2744 uid = mapUid(uid); 2745 getUidStatsLocked(uid).noteWifiBatchedScanStartedLocked(csph); 2746 } 2747 2748 public void noteWifiBatchedScanStoppedLocked(int uid) { 2749 uid = mapUid(uid); 2750 getUidStatsLocked(uid).noteWifiBatchedScanStoppedLocked(); 2751 } 2752 2753 int mWifiMulticastNesting = 0; 2754 2755 public void noteWifiMulticastEnabledLocked(int uid) { 2756 uid = mapUid(uid); 2757 if (mWifiMulticastNesting == 0) { 2758 mHistoryCur.states |= HistoryItem.STATE_WIFI_MULTICAST_ON_FLAG; 2759 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI multicast on to: " 2760 + Integer.toHexString(mHistoryCur.states)); 2761 addHistoryRecordLocked(SystemClock.elapsedRealtime()); 2762 } 2763 mWifiMulticastNesting++; 2764 getUidStatsLocked(uid).noteWifiMulticastEnabledLocked(); 2765 } 2766 2767 public void noteWifiMulticastDisabledLocked(int uid) { 2768 uid = mapUid(uid); 2769 mWifiMulticastNesting--; 2770 if (mWifiMulticastNesting == 0) { 2771 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_MULTICAST_ON_FLAG; 2772 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI multicast off to: " 2773 + Integer.toHexString(mHistoryCur.states)); 2774 addHistoryRecordLocked(SystemClock.elapsedRealtime()); 2775 } 2776 getUidStatsLocked(uid).noteWifiMulticastDisabledLocked(); 2777 } 2778 2779 public void noteFullWifiLockAcquiredFromSourceLocked(WorkSource ws) { 2780 int N = ws.size(); 2781 for (int i=0; i<N; i++) { 2782 noteFullWifiLockAcquiredLocked(ws.get(i)); 2783 } 2784 } 2785 2786 public void noteFullWifiLockReleasedFromSourceLocked(WorkSource ws) { 2787 int N = ws.size(); 2788 for (int i=0; i<N; i++) { 2789 noteFullWifiLockReleasedLocked(ws.get(i)); 2790 } 2791 } 2792 2793 public void noteWifiScanStartedFromSourceLocked(WorkSource ws) { 2794 int N = ws.size(); 2795 for (int i=0; i<N; i++) { 2796 noteWifiScanStartedLocked(ws.get(i)); 2797 } 2798 } 2799 2800 public void noteWifiScanStoppedFromSourceLocked(WorkSource ws) { 2801 int N = ws.size(); 2802 for (int i=0; i<N; i++) { 2803 noteWifiScanStoppedLocked(ws.get(i)); 2804 } 2805 } 2806 2807 public void noteWifiBatchedScanStartedFromSourceLocked(WorkSource ws, int csph) { 2808 int N = ws.size(); 2809 for (int i=0; i<N; i++) { 2810 noteWifiBatchedScanStartedLocked(ws.get(i), csph); 2811 } 2812 } 2813 2814 public void noteWifiBatchedScanStoppedFromSourceLocked(WorkSource ws) { 2815 int N = ws.size(); 2816 for (int i=0; i<N; i++) { 2817 noteWifiBatchedScanStoppedLocked(ws.get(i)); 2818 } 2819 } 2820 2821 public void noteWifiMulticastEnabledFromSourceLocked(WorkSource ws) { 2822 int N = ws.size(); 2823 for (int i=0; i<N; i++) { 2824 noteWifiMulticastEnabledLocked(ws.get(i)); 2825 } 2826 } 2827 2828 public void noteWifiMulticastDisabledFromSourceLocked(WorkSource ws) { 2829 int N = ws.size(); 2830 for (int i=0; i<N; i++) { 2831 noteWifiMulticastDisabledLocked(ws.get(i)); 2832 } 2833 } 2834 2835 public void noteNetworkInterfaceTypeLocked(String iface, int networkType) { 2836 if (ConnectivityManager.isNetworkTypeMobile(networkType)) { 2837 mMobileIfaces.add(iface); 2838 } else { 2839 mMobileIfaces.remove(iface); 2840 } 2841 if (ConnectivityManager.isNetworkTypeWifi(networkType)) { 2842 mWifiIfaces.add(iface); 2843 } else { 2844 mWifiIfaces.remove(iface); 2845 } 2846 } 2847 2848 public void noteNetworkStatsEnabledLocked() { 2849 // During device boot, qtaguid isn't enabled until after the inital 2850 // loading of battery stats. Now that they're enabled, take our initial 2851 // snapshot for future delta calculation. 2852 updateNetworkActivityLocked(); 2853 } 2854 2855 @Override public long getScreenOnTime(long batteryRealtime, int which) { 2856 return mScreenOnTimer.getTotalTimeLocked(batteryRealtime, which); 2857 } 2858 2859 @Override public long getScreenBrightnessTime(int brightnessBin, 2860 long batteryRealtime, int which) { 2861 return mScreenBrightnessTimer[brightnessBin].getTotalTimeLocked( 2862 batteryRealtime, which); 2863 } 2864 2865 @Override public int getInputEventCount(int which) { 2866 return mInputEventCounter.getCountLocked(which); 2867 } 2868 2869 @Override public long getPhoneOnTime(long batteryRealtime, int which) { 2870 return mPhoneOnTimer.getTotalTimeLocked(batteryRealtime, which); 2871 } 2872 2873 @Override public long getPhoneSignalStrengthTime(int strengthBin, 2874 long batteryRealtime, int which) { 2875 return mPhoneSignalStrengthsTimer[strengthBin].getTotalTimeLocked( 2876 batteryRealtime, which); 2877 } 2878 2879 @Override public long getPhoneSignalScanningTime( 2880 long batteryRealtime, int which) { 2881 return mPhoneSignalScanningTimer.getTotalTimeLocked( 2882 batteryRealtime, which); 2883 } 2884 2885 @Override public int getPhoneSignalStrengthCount(int strengthBin, int which) { 2886 return mPhoneSignalStrengthsTimer[strengthBin].getCountLocked(which); 2887 } 2888 2889 @Override public long getPhoneDataConnectionTime(int dataType, 2890 long batteryRealtime, int which) { 2891 return mPhoneDataConnectionsTimer[dataType].getTotalTimeLocked( 2892 batteryRealtime, which); 2893 } 2894 2895 @Override public int getPhoneDataConnectionCount(int dataType, int which) { 2896 return mPhoneDataConnectionsTimer[dataType].getCountLocked(which); 2897 } 2898 2899 @Override public long getWifiOnTime(long batteryRealtime, int which) { 2900 return mWifiOnTimer.getTotalTimeLocked(batteryRealtime, which); 2901 } 2902 2903 @Override public long getGlobalWifiRunningTime(long batteryRealtime, int which) { 2904 return mGlobalWifiRunningTimer.getTotalTimeLocked(batteryRealtime, which); 2905 } 2906 2907 @Override public long getBluetoothOnTime(long batteryRealtime, int which) { 2908 return mBluetoothOnTimer.getTotalTimeLocked(batteryRealtime, which); 2909 } 2910 2911 @Override 2912 public long getNetworkActivityBytes(int type, int which) { 2913 if (type >= 0 && type < mNetworkByteActivityCounters.length) { 2914 return mNetworkByteActivityCounters[type].getCountLocked(which); 2915 } else { 2916 return 0; 2917 } 2918 } 2919 2920 @Override 2921 public long getNetworkActivityPackets(int type, int which) { 2922 if (type >= 0 && type < mNetworkPacketActivityCounters.length) { 2923 return mNetworkPacketActivityCounters[type].getCountLocked(which); 2924 } else { 2925 return 0; 2926 } 2927 } 2928 2929 @Override public long getStartClockTime() { 2930 return mStartClockTime; 2931 } 2932 2933 @Override public boolean getIsOnBattery() { 2934 return mOnBattery; 2935 } 2936 2937 @Override public SparseArray<? extends BatteryStats.Uid> getUidStats() { 2938 return mUidStats; 2939 } 2940 2941 /** 2942 * The statistics associated with a particular uid. 2943 */ 2944 public final class Uid extends BatteryStats.Uid { 2945 2946 final int mUid; 2947 2948 boolean mWifiRunning; 2949 StopwatchTimer mWifiRunningTimer; 2950 2951 boolean mFullWifiLockOut; 2952 StopwatchTimer mFullWifiLockTimer; 2953 2954 boolean mWifiScanStarted; 2955 StopwatchTimer mWifiScanTimer; 2956 2957 private static final int NO_BATCHED_SCAN_STARTED = -1; 2958 int mWifiBatchedScanBinStarted = NO_BATCHED_SCAN_STARTED; 2959 StopwatchTimer[] mWifiBatchedScanTimer; 2960 2961 boolean mWifiMulticastEnabled; 2962 StopwatchTimer mWifiMulticastTimer; 2963 2964 boolean mAudioTurnedOn; 2965 StopwatchTimer mAudioTurnedOnTimer; 2966 2967 boolean mVideoTurnedOn; 2968 StopwatchTimer mVideoTurnedOnTimer; 2969 2970 StopwatchTimer mForegroundActivityTimer; 2971 2972 BatchTimer mVibratorOnTimer; 2973 2974 Counter[] mUserActivityCounters; 2975 2976 LongSamplingCounter[] mNetworkByteActivityCounters; 2977 LongSamplingCounter[] mNetworkPacketActivityCounters; 2978 2979 /** 2980 * The statistics we have collected for this uid's wake locks. 2981 */ 2982 final HashMap<String, Wakelock> mWakelockStats = new HashMap<String, Wakelock>(); 2983 2984 /** 2985 * The statistics we have collected for this uid's sensor activations. 2986 */ 2987 final HashMap<Integer, Sensor> mSensorStats = new HashMap<Integer, Sensor>(); 2988 2989 /** 2990 * The statistics we have collected for this uid's processes. 2991 */ 2992 final HashMap<String, Proc> mProcessStats = new HashMap<String, Proc>(); 2993 2994 /** 2995 * The statistics we have collected for this uid's processes. 2996 */ 2997 final HashMap<String, Pkg> mPackageStats = new HashMap<String, Pkg>(); 2998 2999 /** 3000 * The transient wake stats we have collected for this uid's pids. 3001 */ 3002 final SparseArray<Pid> mPids = new SparseArray<Pid>(); 3003 3004 public Uid(int uid) { 3005 mUid = uid; 3006 mWifiRunningTimer = new StopwatchTimer(Uid.this, WIFI_RUNNING, 3007 mWifiRunningTimers, mUnpluggables); 3008 mFullWifiLockTimer = new StopwatchTimer(Uid.this, FULL_WIFI_LOCK, 3009 mFullWifiLockTimers, mUnpluggables); 3010 mWifiScanTimer = new StopwatchTimer(Uid.this, WIFI_SCAN, 3011 mWifiScanTimers, mUnpluggables); 3012 mWifiBatchedScanTimer = new StopwatchTimer[NUM_WIFI_BATCHED_SCAN_BINS]; 3013 mWifiMulticastTimer = new StopwatchTimer(Uid.this, WIFI_MULTICAST_ENABLED, 3014 mWifiMulticastTimers, mUnpluggables); 3015 } 3016 3017 @Override 3018 public Map<String, ? extends BatteryStats.Uid.Wakelock> getWakelockStats() { 3019 return mWakelockStats; 3020 } 3021 3022 @Override 3023 public Map<Integer, ? extends BatteryStats.Uid.Sensor> getSensorStats() { 3024 return mSensorStats; 3025 } 3026 3027 @Override 3028 public Map<String, ? extends BatteryStats.Uid.Proc> getProcessStats() { 3029 return mProcessStats; 3030 } 3031 3032 @Override 3033 public Map<String, ? extends BatteryStats.Uid.Pkg> getPackageStats() { 3034 return mPackageStats; 3035 } 3036 3037 @Override 3038 public int getUid() { 3039 return mUid; 3040 } 3041 3042 @Override 3043 public void noteWifiRunningLocked() { 3044 if (!mWifiRunning) { 3045 mWifiRunning = true; 3046 if (mWifiRunningTimer == null) { 3047 mWifiRunningTimer = new StopwatchTimer(Uid.this, WIFI_RUNNING, 3048 mWifiRunningTimers, mUnpluggables); 3049 } 3050 mWifiRunningTimer.startRunningLocked(BatteryStatsImpl.this); 3051 } 3052 } 3053 3054 @Override 3055 public void noteWifiStoppedLocked() { 3056 if (mWifiRunning) { 3057 mWifiRunning = false; 3058 mWifiRunningTimer.stopRunningLocked(BatteryStatsImpl.this); 3059 } 3060 } 3061 3062 @Override 3063 public void noteFullWifiLockAcquiredLocked() { 3064 if (!mFullWifiLockOut) { 3065 mFullWifiLockOut = true; 3066 if (mFullWifiLockTimer == null) { 3067 mFullWifiLockTimer = new StopwatchTimer(Uid.this, FULL_WIFI_LOCK, 3068 mFullWifiLockTimers, mUnpluggables); 3069 } 3070 mFullWifiLockTimer.startRunningLocked(BatteryStatsImpl.this); 3071 } 3072 } 3073 3074 @Override 3075 public void noteFullWifiLockReleasedLocked() { 3076 if (mFullWifiLockOut) { 3077 mFullWifiLockOut = false; 3078 mFullWifiLockTimer.stopRunningLocked(BatteryStatsImpl.this); 3079 } 3080 } 3081 3082 @Override 3083 public void noteWifiScanStartedLocked() { 3084 if (!mWifiScanStarted) { 3085 mWifiScanStarted = true; 3086 if (mWifiScanTimer == null) { 3087 mWifiScanTimer = new StopwatchTimer(Uid.this, WIFI_SCAN, 3088 mWifiScanTimers, mUnpluggables); 3089 } 3090 mWifiScanTimer.startRunningLocked(BatteryStatsImpl.this); 3091 } 3092 } 3093 3094 @Override 3095 public void noteWifiScanStoppedLocked() { 3096 if (mWifiScanStarted) { 3097 mWifiScanStarted = false; 3098 mWifiScanTimer.stopRunningLocked(BatteryStatsImpl.this); 3099 } 3100 } 3101 3102 @Override 3103 public void noteWifiBatchedScanStartedLocked(int csph) { 3104 int bin = 0; 3105 while (csph > 8 && bin < NUM_WIFI_BATCHED_SCAN_BINS) { 3106 csph = csph >> 3; 3107 bin++; 3108 } 3109 3110 if (mWifiBatchedScanBinStarted == bin) return; 3111 3112 if (mWifiBatchedScanBinStarted != NO_BATCHED_SCAN_STARTED) { 3113 mWifiBatchedScanTimer[mWifiBatchedScanBinStarted]. 3114 stopRunningLocked(BatteryStatsImpl.this); 3115 } 3116 mWifiBatchedScanBinStarted = bin; 3117 if (mWifiBatchedScanTimer[bin] == null) { 3118 makeWifiBatchedScanBin(bin, null); 3119 } 3120 mWifiBatchedScanTimer[bin].startRunningLocked(BatteryStatsImpl.this); 3121 } 3122 3123 @Override 3124 public void noteWifiBatchedScanStoppedLocked() { 3125 if (mWifiBatchedScanBinStarted != NO_BATCHED_SCAN_STARTED) { 3126 mWifiBatchedScanTimer[mWifiBatchedScanBinStarted]. 3127 stopRunningLocked(BatteryStatsImpl.this); 3128 mWifiBatchedScanBinStarted = NO_BATCHED_SCAN_STARTED; 3129 } 3130 } 3131 3132 @Override 3133 public void noteWifiMulticastEnabledLocked() { 3134 if (!mWifiMulticastEnabled) { 3135 mWifiMulticastEnabled = true; 3136 if (mWifiMulticastTimer == null) { 3137 mWifiMulticastTimer = new StopwatchTimer(Uid.this, WIFI_MULTICAST_ENABLED, 3138 mWifiMulticastTimers, mUnpluggables); 3139 } 3140 mWifiMulticastTimer.startRunningLocked(BatteryStatsImpl.this); 3141 } 3142 } 3143 3144 @Override 3145 public void noteWifiMulticastDisabledLocked() { 3146 if (mWifiMulticastEnabled) { 3147 mWifiMulticastEnabled = false; 3148 mWifiMulticastTimer.stopRunningLocked(BatteryStatsImpl.this); 3149 } 3150 } 3151 3152 public StopwatchTimer createAudioTurnedOnTimerLocked() { 3153 if (mAudioTurnedOnTimer == null) { 3154 mAudioTurnedOnTimer = new StopwatchTimer(Uid.this, AUDIO_TURNED_ON, 3155 null, mUnpluggables); 3156 } 3157 return mAudioTurnedOnTimer; 3158 } 3159 3160 @Override 3161 public void noteAudioTurnedOnLocked() { 3162 if (!mAudioTurnedOn) { 3163 mAudioTurnedOn = true; 3164 createAudioTurnedOnTimerLocked().startRunningLocked(BatteryStatsImpl.this); 3165 } 3166 } 3167 3168 @Override 3169 public void noteAudioTurnedOffLocked() { 3170 if (mAudioTurnedOn) { 3171 mAudioTurnedOn = false; 3172 if (mAudioTurnedOnTimer != null) { 3173 mAudioTurnedOnTimer.stopRunningLocked(BatteryStatsImpl.this); 3174 } 3175 } 3176 } 3177 3178 public StopwatchTimer createVideoTurnedOnTimerLocked() { 3179 if (mVideoTurnedOnTimer == null) { 3180 mVideoTurnedOnTimer = new StopwatchTimer(Uid.this, VIDEO_TURNED_ON, 3181 null, mUnpluggables); 3182 } 3183 return mVideoTurnedOnTimer; 3184 } 3185 3186 @Override 3187 public void noteVideoTurnedOnLocked() { 3188 if (!mVideoTurnedOn) { 3189 mVideoTurnedOn = true; 3190 createVideoTurnedOnTimerLocked().startRunningLocked(BatteryStatsImpl.this); 3191 } 3192 } 3193 3194 @Override 3195 public void noteVideoTurnedOffLocked() { 3196 if (mVideoTurnedOn) { 3197 mVideoTurnedOn = false; 3198 if (mVideoTurnedOnTimer != null) { 3199 mVideoTurnedOnTimer.stopRunningLocked(BatteryStatsImpl.this); 3200 } 3201 } 3202 } 3203 3204 public StopwatchTimer createForegroundActivityTimerLocked() { 3205 if (mForegroundActivityTimer == null) { 3206 mForegroundActivityTimer = new StopwatchTimer( 3207 Uid.this, FOREGROUND_ACTIVITY, null, mUnpluggables); 3208 } 3209 return mForegroundActivityTimer; 3210 } 3211 3212 @Override 3213 public void noteActivityResumedLocked() { 3214 // We always start, since we want multiple foreground PIDs to nest 3215 createForegroundActivityTimerLocked().startRunningLocked(BatteryStatsImpl.this); 3216 } 3217 3218 @Override 3219 public void noteActivityPausedLocked() { 3220 if (mForegroundActivityTimer != null) { 3221 mForegroundActivityTimer.stopRunningLocked(BatteryStatsImpl.this); 3222 } 3223 } 3224 3225 public BatchTimer createVibratorOnTimerLocked() { 3226 if (mVibratorOnTimer == null) { 3227 mVibratorOnTimer = new BatchTimer(Uid.this, VIBRATOR_ON, 3228 mUnpluggables, BatteryStatsImpl.this.mOnBatteryInternal); 3229 } 3230 return mVibratorOnTimer; 3231 } 3232 3233 public void noteVibratorOnLocked(long durationMillis) { 3234 createVibratorOnTimerLocked().addDuration(BatteryStatsImpl.this, durationMillis); 3235 } 3236 3237 public void noteVibratorOffLocked() { 3238 if (mVibratorOnTimer != null) { 3239 mVibratorOnTimer.abortLastDuration(BatteryStatsImpl.this); 3240 } 3241 } 3242 3243 @Override 3244 public long getWifiRunningTime(long batteryRealtime, int which) { 3245 if (mWifiRunningTimer == null) { 3246 return 0; 3247 } 3248 return mWifiRunningTimer.getTotalTimeLocked(batteryRealtime, which); 3249 } 3250 3251 @Override 3252 public long getFullWifiLockTime(long batteryRealtime, int which) { 3253 if (mFullWifiLockTimer == null) { 3254 return 0; 3255 } 3256 return mFullWifiLockTimer.getTotalTimeLocked(batteryRealtime, which); 3257 } 3258 3259 @Override 3260 public long getWifiScanTime(long batteryRealtime, int which) { 3261 if (mWifiScanTimer == null) { 3262 return 0; 3263 } 3264 return mWifiScanTimer.getTotalTimeLocked(batteryRealtime, which); 3265 } 3266 3267 @Override 3268 public long getWifiBatchedScanTime(int csphBin, long batteryRealtime, int which) { 3269 if (csphBin < 0 || csphBin >= NUM_WIFI_BATCHED_SCAN_BINS) return 0; 3270 if (mWifiBatchedScanTimer[csphBin] == null) { 3271 return 0; 3272 } 3273 return mWifiBatchedScanTimer[csphBin].getTotalTimeLocked(batteryRealtime, which); 3274 } 3275 3276 @Override 3277 public long getWifiMulticastTime(long batteryRealtime, int which) { 3278 if (mWifiMulticastTimer == null) { 3279 return 0; 3280 } 3281 return mWifiMulticastTimer.getTotalTimeLocked(batteryRealtime, 3282 which); 3283 } 3284 3285 @Override 3286 public long getAudioTurnedOnTime(long batteryRealtime, int which) { 3287 if (mAudioTurnedOnTimer == null) { 3288 return 0; 3289 } 3290 return mAudioTurnedOnTimer.getTotalTimeLocked(batteryRealtime, which); 3291 } 3292 3293 @Override 3294 public long getVideoTurnedOnTime(long batteryRealtime, int which) { 3295 if (mVideoTurnedOnTimer == null) { 3296 return 0; 3297 } 3298 return mVideoTurnedOnTimer.getTotalTimeLocked(batteryRealtime, which); 3299 } 3300 3301 @Override 3302 public Timer getForegroundActivityTimer() { 3303 return mForegroundActivityTimer; 3304 } 3305 3306 @Override 3307 public Timer getVibratorOnTimer() { 3308 return mVibratorOnTimer; 3309 } 3310 3311 @Override 3312 public void noteUserActivityLocked(int type) { 3313 if (mUserActivityCounters == null) { 3314 initUserActivityLocked(); 3315 } 3316 if (type >= 0 && type < NUM_USER_ACTIVITY_TYPES) { 3317 mUserActivityCounters[type].stepAtomic(); 3318 } else { 3319 Slog.w(TAG, "Unknown user activity type " + type + " was specified.", 3320 new Throwable()); 3321 } 3322 } 3323 3324 @Override 3325 public boolean hasUserActivity() { 3326 return mUserActivityCounters != null; 3327 } 3328 3329 @Override 3330 public int getUserActivityCount(int type, int which) { 3331 if (mUserActivityCounters == null) { 3332 return 0; 3333 } 3334 return mUserActivityCounters[type].getCountLocked(which); 3335 } 3336 3337 void makeWifiBatchedScanBin(int i, Parcel in) { 3338 if (i < 0 || i >= NUM_WIFI_BATCHED_SCAN_BINS) return; 3339 3340 ArrayList<StopwatchTimer> collected = mWifiBatchedScanTimers.get(i); 3341 if (collected == null) { 3342 collected = new ArrayList<StopwatchTimer>(); 3343 mWifiBatchedScanTimers.put(i, collected); 3344 } 3345 if (in == null) { 3346 mWifiBatchedScanTimer[i] = new StopwatchTimer(this, WIFI_BATCHED_SCAN, collected, 3347 mUnpluggables); 3348 } else { 3349 mWifiBatchedScanTimer[i] = new StopwatchTimer(this, WIFI_BATCHED_SCAN, collected, 3350 mUnpluggables, in); 3351 } 3352 } 3353 3354 3355 void initUserActivityLocked() { 3356 mUserActivityCounters = new Counter[NUM_USER_ACTIVITY_TYPES]; 3357 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) { 3358 mUserActivityCounters[i] = new Counter(mUnpluggables); 3359 } 3360 } 3361 3362 void noteNetworkActivityLocked(int type, long deltaBytes, long deltaPackets) { 3363 if (mNetworkByteActivityCounters == null) { 3364 initNetworkActivityLocked(); 3365 } 3366 if (type >= 0 && type < NUM_NETWORK_ACTIVITY_TYPES) { 3367 mNetworkByteActivityCounters[type].addCountLocked(deltaBytes); 3368 mNetworkPacketActivityCounters[type].addCountLocked(deltaPackets); 3369 } else { 3370 Slog.w(TAG, "Unknown network activity type " + type + " was specified.", 3371 new Throwable()); 3372 } 3373 } 3374 3375 @Override 3376 public boolean hasNetworkActivity() { 3377 return mNetworkByteActivityCounters != null; 3378 } 3379 3380 @Override 3381 public long getNetworkActivityBytes(int type, int which) { 3382 if (mNetworkByteActivityCounters != null && type >= 0 3383 && type < mNetworkByteActivityCounters.length) { 3384 return mNetworkByteActivityCounters[type].getCountLocked(which); 3385 } else { 3386 return 0; 3387 } 3388 } 3389 3390 @Override 3391 public long getNetworkActivityPackets(int type, int which) { 3392 if (mNetworkPacketActivityCounters != null && type >= 0 3393 && type < mNetworkPacketActivityCounters.length) { 3394 return mNetworkPacketActivityCounters[type].getCountLocked(which); 3395 } else { 3396 return 0; 3397 } 3398 } 3399 3400 void initNetworkActivityLocked() { 3401 mNetworkByteActivityCounters = new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES]; 3402 mNetworkPacketActivityCounters = new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES]; 3403 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 3404 mNetworkByteActivityCounters[i] = new LongSamplingCounter(mUnpluggables); 3405 mNetworkPacketActivityCounters[i] = new LongSamplingCounter(mUnpluggables); 3406 } 3407 } 3408 3409 /** 3410 * Clear all stats for this uid. Returns true if the uid is completely 3411 * inactive so can be dropped. 3412 */ 3413 boolean reset() { 3414 boolean active = false; 3415 3416 if (mWifiRunningTimer != null) { 3417 active |= !mWifiRunningTimer.reset(BatteryStatsImpl.this, false); 3418 active |= mWifiRunning; 3419 } 3420 if (mFullWifiLockTimer != null) { 3421 active |= !mFullWifiLockTimer.reset(BatteryStatsImpl.this, false); 3422 active |= mFullWifiLockOut; 3423 } 3424 if (mWifiScanTimer != null) { 3425 active |= !mWifiScanTimer.reset(BatteryStatsImpl.this, false); 3426 active |= mWifiScanStarted; 3427 } 3428 if (mWifiBatchedScanTimer != null) { 3429 for (int i = 0; i < NUM_WIFI_BATCHED_SCAN_BINS; i++) { 3430 if (mWifiBatchedScanTimer[i] != null) { 3431 active |= !mWifiBatchedScanTimer[i].reset(BatteryStatsImpl.this, false); 3432 } 3433 } 3434 active |= (mWifiBatchedScanBinStarted != NO_BATCHED_SCAN_STARTED); 3435 } 3436 if (mWifiMulticastTimer != null) { 3437 active |= !mWifiMulticastTimer.reset(BatteryStatsImpl.this, false); 3438 active |= mWifiMulticastEnabled; 3439 } 3440 if (mAudioTurnedOnTimer != null) { 3441 active |= !mAudioTurnedOnTimer.reset(BatteryStatsImpl.this, false); 3442 active |= mAudioTurnedOn; 3443 } 3444 if (mVideoTurnedOnTimer != null) { 3445 active |= !mVideoTurnedOnTimer.reset(BatteryStatsImpl.this, false); 3446 active |= mVideoTurnedOn; 3447 } 3448 if (mForegroundActivityTimer != null) { 3449 active |= !mForegroundActivityTimer.reset(BatteryStatsImpl.this, false); 3450 } 3451 if (mVibratorOnTimer != null) { 3452 if (mVibratorOnTimer.reset(BatteryStatsImpl.this, false)) { 3453 mVibratorOnTimer.detach(); 3454 mVibratorOnTimer = null; 3455 } else { 3456 active = true; 3457 } 3458 } 3459 3460 if (mUserActivityCounters != null) { 3461 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) { 3462 mUserActivityCounters[i].reset(false); 3463 } 3464 } 3465 3466 if (mNetworkByteActivityCounters != null) { 3467 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 3468 mNetworkByteActivityCounters[i].reset(false); 3469 mNetworkPacketActivityCounters[i].reset(false); 3470 } 3471 } 3472 3473 if (mWakelockStats.size() > 0) { 3474 Iterator<Map.Entry<String, Wakelock>> it = mWakelockStats.entrySet().iterator(); 3475 while (it.hasNext()) { 3476 Map.Entry<String, Wakelock> wakelockEntry = it.next(); 3477 Wakelock wl = wakelockEntry.getValue(); 3478 if (wl.reset()) { 3479 it.remove(); 3480 } else { 3481 active = true; 3482 } 3483 } 3484 } 3485 if (mSensorStats.size() > 0) { 3486 Iterator<Map.Entry<Integer, Sensor>> it = mSensorStats.entrySet().iterator(); 3487 while (it.hasNext()) { 3488 Map.Entry<Integer, Sensor> sensorEntry = it.next(); 3489 Sensor s = sensorEntry.getValue(); 3490 if (s.reset()) { 3491 it.remove(); 3492 } else { 3493 active = true; 3494 } 3495 } 3496 } 3497 if (mProcessStats.size() > 0) { 3498 Iterator<Map.Entry<String, Proc>> it = mProcessStats.entrySet().iterator(); 3499 while (it.hasNext()) { 3500 Map.Entry<String, Proc> procEntry = it.next(); 3501 procEntry.getValue().detach(); 3502 } 3503 mProcessStats.clear(); 3504 } 3505 if (mPids.size() > 0) { 3506 for (int i=0; !active && i<mPids.size(); i++) { 3507 Pid pid = mPids.valueAt(i); 3508 if (pid.mWakeStart != 0) { 3509 active = true; 3510 } 3511 } 3512 } 3513 if (mPackageStats.size() > 0) { 3514 Iterator<Map.Entry<String, Pkg>> it = mPackageStats.entrySet().iterator(); 3515 while (it.hasNext()) { 3516 Map.Entry<String, Pkg> pkgEntry = it.next(); 3517 Pkg p = pkgEntry.getValue(); 3518 p.detach(); 3519 if (p.mServiceStats.size() > 0) { 3520 Iterator<Map.Entry<String, Pkg.Serv>> it2 3521 = p.mServiceStats.entrySet().iterator(); 3522 while (it2.hasNext()) { 3523 Map.Entry<String, Pkg.Serv> servEntry = it2.next(); 3524 servEntry.getValue().detach(); 3525 } 3526 } 3527 } 3528 mPackageStats.clear(); 3529 } 3530 3531 mPids.clear(); 3532 3533 if (!active) { 3534 if (mWifiRunningTimer != null) { 3535 mWifiRunningTimer.detach(); 3536 } 3537 if (mFullWifiLockTimer != null) { 3538 mFullWifiLockTimer.detach(); 3539 } 3540 if (mWifiScanTimer != null) { 3541 mWifiScanTimer.detach(); 3542 } 3543 for (int i = 0; i < NUM_WIFI_BATCHED_SCAN_BINS; i++) { 3544 if (mWifiBatchedScanTimer[i] != null) { 3545 mWifiBatchedScanTimer[i].detach(); 3546 } 3547 } 3548 if (mWifiMulticastTimer != null) { 3549 mWifiMulticastTimer.detach(); 3550 } 3551 if (mAudioTurnedOnTimer != null) { 3552 mAudioTurnedOnTimer.detach(); 3553 mAudioTurnedOnTimer = null; 3554 } 3555 if (mVideoTurnedOnTimer != null) { 3556 mVideoTurnedOnTimer.detach(); 3557 mVideoTurnedOnTimer = null; 3558 } 3559 if (mForegroundActivityTimer != null) { 3560 mForegroundActivityTimer.detach(); 3561 mForegroundActivityTimer = null; 3562 } 3563 if (mUserActivityCounters != null) { 3564 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) { 3565 mUserActivityCounters[i].detach(); 3566 } 3567 } 3568 if (mNetworkByteActivityCounters != null) { 3569 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 3570 mNetworkByteActivityCounters[i].detach(); 3571 mNetworkPacketActivityCounters[i].detach(); 3572 } 3573 } 3574 } 3575 3576 return !active; 3577 } 3578 3579 void writeToParcelLocked(Parcel out, long batteryRealtime) { 3580 out.writeInt(mWakelockStats.size()); 3581 for (Map.Entry<String, Uid.Wakelock> wakelockEntry : mWakelockStats.entrySet()) { 3582 out.writeString(wakelockEntry.getKey()); 3583 Uid.Wakelock wakelock = wakelockEntry.getValue(); 3584 wakelock.writeToParcelLocked(out, batteryRealtime); 3585 } 3586 3587 out.writeInt(mSensorStats.size()); 3588 for (Map.Entry<Integer, Uid.Sensor> sensorEntry : mSensorStats.entrySet()) { 3589 out.writeInt(sensorEntry.getKey()); 3590 Uid.Sensor sensor = sensorEntry.getValue(); 3591 sensor.writeToParcelLocked(out, batteryRealtime); 3592 } 3593 3594 out.writeInt(mProcessStats.size()); 3595 for (Map.Entry<String, Uid.Proc> procEntry : mProcessStats.entrySet()) { 3596 out.writeString(procEntry.getKey()); 3597 Uid.Proc proc = procEntry.getValue(); 3598 proc.writeToParcelLocked(out); 3599 } 3600 3601 out.writeInt(mPackageStats.size()); 3602 for (Map.Entry<String, Uid.Pkg> pkgEntry : mPackageStats.entrySet()) { 3603 out.writeString(pkgEntry.getKey()); 3604 Uid.Pkg pkg = pkgEntry.getValue(); 3605 pkg.writeToParcelLocked(out); 3606 } 3607 3608 if (mWifiRunningTimer != null) { 3609 out.writeInt(1); 3610 mWifiRunningTimer.writeToParcel(out, batteryRealtime); 3611 } else { 3612 out.writeInt(0); 3613 } 3614 if (mFullWifiLockTimer != null) { 3615 out.writeInt(1); 3616 mFullWifiLockTimer.writeToParcel(out, batteryRealtime); 3617 } else { 3618 out.writeInt(0); 3619 } 3620 if (mWifiScanTimer != null) { 3621 out.writeInt(1); 3622 mWifiScanTimer.writeToParcel(out, batteryRealtime); 3623 } else { 3624 out.writeInt(0); 3625 } 3626 for (int i = 0; i < NUM_WIFI_BATCHED_SCAN_BINS; i++) { 3627 if (mWifiBatchedScanTimer[i] != null) { 3628 out.writeInt(1); 3629 mWifiBatchedScanTimer[i].writeToParcel(out, batteryRealtime); 3630 } else { 3631 out.writeInt(0); 3632 } 3633 } 3634 if (mWifiMulticastTimer != null) { 3635 out.writeInt(1); 3636 mWifiMulticastTimer.writeToParcel(out, batteryRealtime); 3637 } else { 3638 out.writeInt(0); 3639 } 3640 if (mAudioTurnedOnTimer != null) { 3641 out.writeInt(1); 3642 mAudioTurnedOnTimer.writeToParcel(out, batteryRealtime); 3643 } else { 3644 out.writeInt(0); 3645 } 3646 if (mVideoTurnedOnTimer != null) { 3647 out.writeInt(1); 3648 mVideoTurnedOnTimer.writeToParcel(out, batteryRealtime); 3649 } else { 3650 out.writeInt(0); 3651 } 3652 if (mForegroundActivityTimer != null) { 3653 out.writeInt(1); 3654 mForegroundActivityTimer.writeToParcel(out, batteryRealtime); 3655 } else { 3656 out.writeInt(0); 3657 } 3658 if (mVibratorOnTimer != null) { 3659 out.writeInt(1); 3660 mVibratorOnTimer.writeToParcel(out, batteryRealtime); 3661 } else { 3662 out.writeInt(0); 3663 } 3664 if (mUserActivityCounters != null) { 3665 out.writeInt(1); 3666 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) { 3667 mUserActivityCounters[i].writeToParcel(out); 3668 } 3669 } else { 3670 out.writeInt(0); 3671 } 3672 if (mNetworkByteActivityCounters != null) { 3673 out.writeInt(1); 3674 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 3675 mNetworkByteActivityCounters[i].writeToParcel(out); 3676 mNetworkPacketActivityCounters[i].writeToParcel(out); 3677 } 3678 } else { 3679 out.writeInt(0); 3680 } 3681 } 3682 3683 void readFromParcelLocked(ArrayList<Unpluggable> unpluggables, Parcel in) { 3684 int numWakelocks = in.readInt(); 3685 mWakelockStats.clear(); 3686 for (int j = 0; j < numWakelocks; j++) { 3687 String wakelockName = in.readString(); 3688 Uid.Wakelock wakelock = new Wakelock(); 3689 wakelock.readFromParcelLocked(unpluggables, in); 3690 // We will just drop some random set of wakelocks if 3691 // the previous run of the system was an older version 3692 // that didn't impose a limit. 3693 mWakelockStats.put(wakelockName, wakelock); 3694 } 3695 3696 int numSensors = in.readInt(); 3697 mSensorStats.clear(); 3698 for (int k = 0; k < numSensors; k++) { 3699 int sensorNumber = in.readInt(); 3700 Uid.Sensor sensor = new Sensor(sensorNumber); 3701 sensor.readFromParcelLocked(mUnpluggables, in); 3702 mSensorStats.put(sensorNumber, sensor); 3703 } 3704 3705 int numProcs = in.readInt(); 3706 mProcessStats.clear(); 3707 for (int k = 0; k < numProcs; k++) { 3708 String processName = in.readString(); 3709 Uid.Proc proc = new Proc(); 3710 proc.readFromParcelLocked(in); 3711 mProcessStats.put(processName, proc); 3712 } 3713 3714 int numPkgs = in.readInt(); 3715 mPackageStats.clear(); 3716 for (int l = 0; l < numPkgs; l++) { 3717 String packageName = in.readString(); 3718 Uid.Pkg pkg = new Pkg(); 3719 pkg.readFromParcelLocked(in); 3720 mPackageStats.put(packageName, pkg); 3721 } 3722 3723 mWifiRunning = false; 3724 if (in.readInt() != 0) { 3725 mWifiRunningTimer = new StopwatchTimer(Uid.this, WIFI_RUNNING, 3726 mWifiRunningTimers, mUnpluggables, in); 3727 } else { 3728 mWifiRunningTimer = null; 3729 } 3730 mFullWifiLockOut = false; 3731 if (in.readInt() != 0) { 3732 mFullWifiLockTimer = new StopwatchTimer(Uid.this, FULL_WIFI_LOCK, 3733 mFullWifiLockTimers, mUnpluggables, in); 3734 } else { 3735 mFullWifiLockTimer = null; 3736 } 3737 mWifiScanStarted = false; 3738 if (in.readInt() != 0) { 3739 mWifiScanTimer = new StopwatchTimer(Uid.this, WIFI_SCAN, 3740 mWifiScanTimers, mUnpluggables, in); 3741 } else { 3742 mWifiScanTimer = null; 3743 } 3744 mWifiBatchedScanBinStarted = NO_BATCHED_SCAN_STARTED; 3745 for (int i = 0; i < NUM_WIFI_BATCHED_SCAN_BINS; i++) { 3746 if (in.readInt() != 0) { 3747 makeWifiBatchedScanBin(i, in); 3748 } else { 3749 mWifiBatchedScanTimer[i] = null; 3750 } 3751 } 3752 mWifiMulticastEnabled = false; 3753 if (in.readInt() != 0) { 3754 mWifiMulticastTimer = new StopwatchTimer(Uid.this, WIFI_MULTICAST_ENABLED, 3755 mWifiMulticastTimers, mUnpluggables, in); 3756 } else { 3757 mWifiMulticastTimer = null; 3758 } 3759 mAudioTurnedOn = false; 3760 if (in.readInt() != 0) { 3761 mAudioTurnedOnTimer = new StopwatchTimer(Uid.this, AUDIO_TURNED_ON, 3762 null, mUnpluggables, in); 3763 } else { 3764 mAudioTurnedOnTimer = null; 3765 } 3766 mVideoTurnedOn = false; 3767 if (in.readInt() != 0) { 3768 mVideoTurnedOnTimer = new StopwatchTimer(Uid.this, VIDEO_TURNED_ON, 3769 null, mUnpluggables, in); 3770 } else { 3771 mVideoTurnedOnTimer = null; 3772 } 3773 if (in.readInt() != 0) { 3774 mForegroundActivityTimer = new StopwatchTimer( 3775 Uid.this, FOREGROUND_ACTIVITY, null, mUnpluggables, in); 3776 } else { 3777 mForegroundActivityTimer = null; 3778 } 3779 if (in.readInt() != 0) { 3780 mVibratorOnTimer = new BatchTimer(Uid.this, VIBRATOR_ON, 3781 mUnpluggables, BatteryStatsImpl.this.mOnBatteryInternal, in); 3782 } else { 3783 mVibratorOnTimer = null; 3784 } 3785 if (in.readInt() != 0) { 3786 mUserActivityCounters = new Counter[NUM_USER_ACTIVITY_TYPES]; 3787 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) { 3788 mUserActivityCounters[i] = new Counter(mUnpluggables, in); 3789 } 3790 } else { 3791 mUserActivityCounters = null; 3792 } 3793 if (in.readInt() != 0) { 3794 mNetworkByteActivityCounters = new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES]; 3795 mNetworkPacketActivityCounters 3796 = new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES]; 3797 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 3798 mNetworkByteActivityCounters[i] = new LongSamplingCounter(mUnpluggables, in); 3799 mNetworkPacketActivityCounters[i] = new LongSamplingCounter(mUnpluggables, in); 3800 } 3801 } else { 3802 mNetworkByteActivityCounters = null; 3803 mNetworkPacketActivityCounters = null; 3804 } 3805 } 3806 3807 /** 3808 * The statistics associated with a particular wake lock. 3809 */ 3810 public final class Wakelock extends BatteryStats.Uid.Wakelock { 3811 /** 3812 * How long (in ms) this uid has been keeping the device partially awake. 3813 */ 3814 StopwatchTimer mTimerPartial; 3815 3816 /** 3817 * How long (in ms) this uid has been keeping the device fully awake. 3818 */ 3819 StopwatchTimer mTimerFull; 3820 3821 /** 3822 * How long (in ms) this uid has had a window keeping the device awake. 3823 */ 3824 StopwatchTimer mTimerWindow; 3825 3826 /** 3827 * Reads a possibly null Timer from a Parcel. The timer is associated with the 3828 * proper timer pool from the given BatteryStatsImpl object. 3829 * 3830 * @param in the Parcel to be read from. 3831 * return a new Timer, or null. 3832 */ 3833 private StopwatchTimer readTimerFromParcel(int type, ArrayList<StopwatchTimer> pool, 3834 ArrayList<Unpluggable> unpluggables, Parcel in) { 3835 if (in.readInt() == 0) { 3836 return null; 3837 } 3838 3839 return new StopwatchTimer(Uid.this, type, pool, unpluggables, in); 3840 } 3841 3842 boolean reset() { 3843 boolean wlactive = false; 3844 if (mTimerFull != null) { 3845 wlactive |= !mTimerFull.reset(BatteryStatsImpl.this, false); 3846 } 3847 if (mTimerPartial != null) { 3848 wlactive |= !mTimerPartial.reset(BatteryStatsImpl.this, false); 3849 } 3850 if (mTimerWindow != null) { 3851 wlactive |= !mTimerWindow.reset(BatteryStatsImpl.this, false); 3852 } 3853 if (!wlactive) { 3854 if (mTimerFull != null) { 3855 mTimerFull.detach(); 3856 mTimerFull = null; 3857 } 3858 if (mTimerPartial != null) { 3859 mTimerPartial.detach(); 3860 mTimerPartial = null; 3861 } 3862 if (mTimerWindow != null) { 3863 mTimerWindow.detach(); 3864 mTimerWindow = null; 3865 } 3866 } 3867 return !wlactive; 3868 } 3869 3870 void readFromParcelLocked(ArrayList<Unpluggable> unpluggables, Parcel in) { 3871 mTimerPartial = readTimerFromParcel(WAKE_TYPE_PARTIAL, 3872 mPartialTimers, unpluggables, in); 3873 mTimerFull = readTimerFromParcel(WAKE_TYPE_FULL, 3874 mFullTimers, unpluggables, in); 3875 mTimerWindow = readTimerFromParcel(WAKE_TYPE_WINDOW, 3876 mWindowTimers, unpluggables, in); 3877 } 3878 3879 void writeToParcelLocked(Parcel out, long batteryRealtime) { 3880 Timer.writeTimerToParcel(out, mTimerPartial, batteryRealtime); 3881 Timer.writeTimerToParcel(out, mTimerFull, batteryRealtime); 3882 Timer.writeTimerToParcel(out, mTimerWindow, batteryRealtime); 3883 } 3884 3885 @Override 3886 public Timer getWakeTime(int type) { 3887 switch (type) { 3888 case WAKE_TYPE_FULL: return mTimerFull; 3889 case WAKE_TYPE_PARTIAL: return mTimerPartial; 3890 case WAKE_TYPE_WINDOW: return mTimerWindow; 3891 default: throw new IllegalArgumentException("type = " + type); 3892 } 3893 } 3894 } 3895 3896 public final class Sensor extends BatteryStats.Uid.Sensor { 3897 final int mHandle; 3898 StopwatchTimer mTimer; 3899 3900 public Sensor(int handle) { 3901 mHandle = handle; 3902 } 3903 3904 private StopwatchTimer readTimerFromParcel(ArrayList<Unpluggable> unpluggables, 3905 Parcel in) { 3906 if (in.readInt() == 0) { 3907 return null; 3908 } 3909 3910 ArrayList<StopwatchTimer> pool = mSensorTimers.get(mHandle); 3911 if (pool == null) { 3912 pool = new ArrayList<StopwatchTimer>(); 3913 mSensorTimers.put(mHandle, pool); 3914 } 3915 return new StopwatchTimer(Uid.this, 0, pool, unpluggables, in); 3916 } 3917 3918 boolean reset() { 3919 if (mTimer.reset(BatteryStatsImpl.this, true)) { 3920 mTimer = null; 3921 return true; 3922 } 3923 return false; 3924 } 3925 3926 void readFromParcelLocked(ArrayList<Unpluggable> unpluggables, Parcel in) { 3927 mTimer = readTimerFromParcel(unpluggables, in); 3928 } 3929 3930 void writeToParcelLocked(Parcel out, long batteryRealtime) { 3931 Timer.writeTimerToParcel(out, mTimer, batteryRealtime); 3932 } 3933 3934 @Override 3935 public Timer getSensorTime() { 3936 return mTimer; 3937 } 3938 3939 @Override 3940 public int getHandle() { 3941 return mHandle; 3942 } 3943 } 3944 3945 /** 3946 * The statistics associated with a particular process. 3947 */ 3948 public final class Proc extends BatteryStats.Uid.Proc implements Unpluggable { 3949 /** 3950 * Remains true until removed from the stats. 3951 */ 3952 boolean mActive = true; 3953 3954 /** 3955 * Total time (in 1/100 sec) spent executing in user code. 3956 */ 3957 long mUserTime; 3958 3959 /** 3960 * Total time (in 1/100 sec) spent executing in kernel code. 3961 */ 3962 long mSystemTime; 3963 3964 /** 3965 * Amount of time the process was running in the foreground. 3966 */ 3967 long mForegroundTime; 3968 3969 /** 3970 * Number of times the process has been started. 3971 */ 3972 int mStarts; 3973 3974 /** 3975 * The amount of user time loaded from a previous save. 3976 */ 3977 long mLoadedUserTime; 3978 3979 /** 3980 * The amount of system time loaded from a previous save. 3981 */ 3982 long mLoadedSystemTime; 3983 3984 /** 3985 * The amount of foreground time loaded from a previous save. 3986 */ 3987 long mLoadedForegroundTime; 3988 3989 /** 3990 * The number of times the process has started from a previous save. 3991 */ 3992 int mLoadedStarts; 3993 3994 /** 3995 * The amount of user time loaded from the previous run. 3996 */ 3997 long mLastUserTime; 3998 3999 /** 4000 * The amount of system time loaded from the previous run. 4001 */ 4002 long mLastSystemTime; 4003 4004 /** 4005 * The amount of foreground time loaded from the previous run 4006 */ 4007 long mLastForegroundTime; 4008 4009 /** 4010 * The number of times the process has started from the previous run. 4011 */ 4012 int mLastStarts; 4013 4014 /** 4015 * The amount of user time when last unplugged. 4016 */ 4017 long mUnpluggedUserTime; 4018 4019 /** 4020 * The amount of system time when last unplugged. 4021 */ 4022 long mUnpluggedSystemTime; 4023 4024 /** 4025 * The amount of foreground time since unplugged. 4026 */ 4027 long mUnpluggedForegroundTime; 4028 4029 /** 4030 * The number of times the process has started before unplugged. 4031 */ 4032 int mUnpluggedStarts; 4033 4034 SamplingCounter[] mSpeedBins; 4035 4036 ArrayList<ExcessivePower> mExcessivePower; 4037 4038 Proc() { 4039 mUnpluggables.add(this); 4040 mSpeedBins = new SamplingCounter[getCpuSpeedSteps()]; 4041 } 4042 4043 public void unplug(long elapsedRealtime, long batteryUptime, long batteryRealtime) { 4044 mUnpluggedUserTime = mUserTime; 4045 mUnpluggedSystemTime = mSystemTime; 4046 mUnpluggedForegroundTime = mForegroundTime; 4047 mUnpluggedStarts = mStarts; 4048 } 4049 4050 public void plug(long elapsedRealtime, long batteryUptime, long batteryRealtime) { 4051 } 4052 4053 void detach() { 4054 mActive = false; 4055 mUnpluggables.remove(this); 4056 for (int i = 0; i < mSpeedBins.length; i++) { 4057 SamplingCounter c = mSpeedBins[i]; 4058 if (c != null) { 4059 mUnpluggables.remove(c); 4060 mSpeedBins[i] = null; 4061 } 4062 } 4063 } 4064 4065 public int countExcessivePowers() { 4066 return mExcessivePower != null ? mExcessivePower.size() : 0; 4067 } 4068 4069 public ExcessivePower getExcessivePower(int i) { 4070 if (mExcessivePower != null) { 4071 return mExcessivePower.get(i); 4072 } 4073 return null; 4074 } 4075 4076 public void addExcessiveWake(long overTime, long usedTime) { 4077 if (mExcessivePower == null) { 4078 mExcessivePower = new ArrayList<ExcessivePower>(); 4079 } 4080 ExcessivePower ew = new ExcessivePower(); 4081 ew.type = ExcessivePower.TYPE_WAKE; 4082 ew.overTime = overTime; 4083 ew.usedTime = usedTime; 4084 mExcessivePower.add(ew); 4085 } 4086 4087 public void addExcessiveCpu(long overTime, long usedTime) { 4088 if (mExcessivePower == null) { 4089 mExcessivePower = new ArrayList<ExcessivePower>(); 4090 } 4091 ExcessivePower ew = new ExcessivePower(); 4092 ew.type = ExcessivePower.TYPE_CPU; 4093 ew.overTime = overTime; 4094 ew.usedTime = usedTime; 4095 mExcessivePower.add(ew); 4096 } 4097 4098 void writeExcessivePowerToParcelLocked(Parcel out) { 4099 if (mExcessivePower == null) { 4100 out.writeInt(0); 4101 return; 4102 } 4103 4104 final int N = mExcessivePower.size(); 4105 out.writeInt(N); 4106 for (int i=0; i<N; i++) { 4107 ExcessivePower ew = mExcessivePower.get(i); 4108 out.writeInt(ew.type); 4109 out.writeLong(ew.overTime); 4110 out.writeLong(ew.usedTime); 4111 } 4112 } 4113 4114 boolean readExcessivePowerFromParcelLocked(Parcel in) { 4115 final int N = in.readInt(); 4116 if (N == 0) { 4117 mExcessivePower = null; 4118 return true; 4119 } 4120 4121 if (N > 10000) { 4122 Slog.w(TAG, "File corrupt: too many excessive power entries " + N); 4123 return false; 4124 } 4125 4126 mExcessivePower = new ArrayList<ExcessivePower>(); 4127 for (int i=0; i<N; i++) { 4128 ExcessivePower ew = new ExcessivePower(); 4129 ew.type = in.readInt(); 4130 ew.overTime = in.readLong(); 4131 ew.usedTime = in.readLong(); 4132 mExcessivePower.add(ew); 4133 } 4134 return true; 4135 } 4136 4137 void writeToParcelLocked(Parcel out) { 4138 out.writeLong(mUserTime); 4139 out.writeLong(mSystemTime); 4140 out.writeLong(mForegroundTime); 4141 out.writeInt(mStarts); 4142 out.writeLong(mLoadedUserTime); 4143 out.writeLong(mLoadedSystemTime); 4144 out.writeLong(mLoadedForegroundTime); 4145 out.writeInt(mLoadedStarts); 4146 out.writeLong(mUnpluggedUserTime); 4147 out.writeLong(mUnpluggedSystemTime); 4148 out.writeLong(mUnpluggedForegroundTime); 4149 out.writeInt(mUnpluggedStarts); 4150 4151 out.writeInt(mSpeedBins.length); 4152 for (int i = 0; i < mSpeedBins.length; i++) { 4153 SamplingCounter c = mSpeedBins[i]; 4154 if (c != null) { 4155 out.writeInt(1); 4156 c.writeToParcel(out); 4157 } else { 4158 out.writeInt(0); 4159 } 4160 } 4161 4162 writeExcessivePowerToParcelLocked(out); 4163 } 4164 4165 void readFromParcelLocked(Parcel in) { 4166 mUserTime = in.readLong(); 4167 mSystemTime = in.readLong(); 4168 mForegroundTime = in.readLong(); 4169 mStarts = in.readInt(); 4170 mLoadedUserTime = in.readLong(); 4171 mLoadedSystemTime = in.readLong(); 4172 mLoadedForegroundTime = in.readLong(); 4173 mLoadedStarts = in.readInt(); 4174 mLastUserTime = 0; 4175 mLastSystemTime = 0; 4176 mLastForegroundTime = 0; 4177 mLastStarts = 0; 4178 mUnpluggedUserTime = in.readLong(); 4179 mUnpluggedSystemTime = in.readLong(); 4180 mUnpluggedForegroundTime = in.readLong(); 4181 mUnpluggedStarts = in.readInt(); 4182 4183 int bins = in.readInt(); 4184 int steps = getCpuSpeedSteps(); 4185 mSpeedBins = new SamplingCounter[bins >= steps ? bins : steps]; 4186 for (int i = 0; i < bins; i++) { 4187 if (in.readInt() != 0) { 4188 mSpeedBins[i] = new SamplingCounter(mUnpluggables, in); 4189 } 4190 } 4191 4192 readExcessivePowerFromParcelLocked(in); 4193 } 4194 4195 public BatteryStatsImpl getBatteryStats() { 4196 return BatteryStatsImpl.this; 4197 } 4198 4199 public void addCpuTimeLocked(int utime, int stime) { 4200 mUserTime += utime; 4201 mSystemTime += stime; 4202 } 4203 4204 public void addForegroundTimeLocked(long ttime) { 4205 mForegroundTime += ttime; 4206 } 4207 4208 public void incStartsLocked() { 4209 mStarts++; 4210 } 4211 4212 @Override 4213 public boolean isActive() { 4214 return mActive; 4215 } 4216 4217 @Override 4218 public long getUserTime(int which) { 4219 long val; 4220 if (which == STATS_LAST) { 4221 val = mLastUserTime; 4222 } else { 4223 val = mUserTime; 4224 if (which == STATS_CURRENT) { 4225 val -= mLoadedUserTime; 4226 } else if (which == STATS_SINCE_UNPLUGGED) { 4227 val -= mUnpluggedUserTime; 4228 } 4229 } 4230 return val; 4231 } 4232 4233 @Override 4234 public long getSystemTime(int which) { 4235 long val; 4236 if (which == STATS_LAST) { 4237 val = mLastSystemTime; 4238 } else { 4239 val = mSystemTime; 4240 if (which == STATS_CURRENT) { 4241 val -= mLoadedSystemTime; 4242 } else if (which == STATS_SINCE_UNPLUGGED) { 4243 val -= mUnpluggedSystemTime; 4244 } 4245 } 4246 return val; 4247 } 4248 4249 @Override 4250 public long getForegroundTime(int which) { 4251 long val; 4252 if (which == STATS_LAST) { 4253 val = mLastForegroundTime; 4254 } else { 4255 val = mForegroundTime; 4256 if (which == STATS_CURRENT) { 4257 val -= mLoadedForegroundTime; 4258 } else if (which == STATS_SINCE_UNPLUGGED) { 4259 val -= mUnpluggedForegroundTime; 4260 } 4261 } 4262 return val; 4263 } 4264 4265 @Override 4266 public int getStarts(int which) { 4267 int val; 4268 if (which == STATS_LAST) { 4269 val = mLastStarts; 4270 } else { 4271 val = mStarts; 4272 if (which == STATS_CURRENT) { 4273 val -= mLoadedStarts; 4274 } else if (which == STATS_SINCE_UNPLUGGED) { 4275 val -= mUnpluggedStarts; 4276 } 4277 } 4278 return val; 4279 } 4280 4281 /* Called by ActivityManagerService when CPU times are updated. */ 4282 public void addSpeedStepTimes(long[] values) { 4283 for (int i = 0; i < mSpeedBins.length && i < values.length; i++) { 4284 long amt = values[i]; 4285 if (amt != 0) { 4286 SamplingCounter c = mSpeedBins[i]; 4287 if (c == null) { 4288 mSpeedBins[i] = c = new SamplingCounter(mUnpluggables); 4289 } 4290 c.addCountAtomic(values[i]); 4291 } 4292 } 4293 } 4294 4295 @Override 4296 public long getTimeAtCpuSpeedStep(int speedStep, int which) { 4297 if (speedStep < mSpeedBins.length) { 4298 SamplingCounter c = mSpeedBins[speedStep]; 4299 return c != null ? c.getCountLocked(which) : 0; 4300 } else { 4301 return 0; 4302 } 4303 } 4304 } 4305 4306 /** 4307 * The statistics associated with a particular package. 4308 */ 4309 public final class Pkg extends BatteryStats.Uid.Pkg implements Unpluggable { 4310 /** 4311 * Number of times this package has done something that could wake up the 4312 * device from sleep. 4313 */ 4314 int mWakeups; 4315 4316 /** 4317 * Number of things that could wake up the device loaded from a 4318 * previous save. 4319 */ 4320 int mLoadedWakeups; 4321 4322 /** 4323 * Number of things that could wake up the device as of the 4324 * last run. 4325 */ 4326 int mLastWakeups; 4327 4328 /** 4329 * Number of things that could wake up the device as of the 4330 * last run. 4331 */ 4332 int mUnpluggedWakeups; 4333 4334 /** 4335 * The statics we have collected for this package's services. 4336 */ 4337 final HashMap<String, Serv> mServiceStats = new HashMap<String, Serv>(); 4338 4339 Pkg() { 4340 mUnpluggables.add(this); 4341 } 4342 4343 public void unplug(long elapsedRealtime, long batteryUptime, long batteryRealtime) { 4344 mUnpluggedWakeups = mWakeups; 4345 } 4346 4347 public void plug(long elapsedRealtime, long batteryUptime, long batteryRealtime) { 4348 } 4349 4350 void detach() { 4351 mUnpluggables.remove(this); 4352 } 4353 4354 void readFromParcelLocked(Parcel in) { 4355 mWakeups = in.readInt(); 4356 mLoadedWakeups = in.readInt(); 4357 mLastWakeups = 0; 4358 mUnpluggedWakeups = in.readInt(); 4359 4360 int numServs = in.readInt(); 4361 mServiceStats.clear(); 4362 for (int m = 0; m < numServs; m++) { 4363 String serviceName = in.readString(); 4364 Uid.Pkg.Serv serv = new Serv(); 4365 mServiceStats.put(serviceName, serv); 4366 4367 serv.readFromParcelLocked(in); 4368 } 4369 } 4370 4371 void writeToParcelLocked(Parcel out) { 4372 out.writeInt(mWakeups); 4373 out.writeInt(mLoadedWakeups); 4374 out.writeInt(mUnpluggedWakeups); 4375 4376 out.writeInt(mServiceStats.size()); 4377 for (Map.Entry<String, Uid.Pkg.Serv> servEntry : mServiceStats.entrySet()) { 4378 out.writeString(servEntry.getKey()); 4379 Uid.Pkg.Serv serv = servEntry.getValue(); 4380 4381 serv.writeToParcelLocked(out); 4382 } 4383 } 4384 4385 @Override 4386 public Map<String, ? extends BatteryStats.Uid.Pkg.Serv> getServiceStats() { 4387 return mServiceStats; 4388 } 4389 4390 @Override 4391 public int getWakeups(int which) { 4392 int val; 4393 if (which == STATS_LAST) { 4394 val = mLastWakeups; 4395 } else { 4396 val = mWakeups; 4397 if (which == STATS_CURRENT) { 4398 val -= mLoadedWakeups; 4399 } else if (which == STATS_SINCE_UNPLUGGED) { 4400 val -= mUnpluggedWakeups; 4401 } 4402 } 4403 4404 return val; 4405 } 4406 4407 /** 4408 * The statistics associated with a particular service. 4409 */ 4410 public final class Serv extends BatteryStats.Uid.Pkg.Serv implements Unpluggable { 4411 /** 4412 * Total time (ms in battery uptime) the service has been left started. 4413 */ 4414 long mStartTime; 4415 4416 /** 4417 * If service has been started and not yet stopped, this is 4418 * when it was started. 4419 */ 4420 long mRunningSince; 4421 4422 /** 4423 * True if we are currently running. 4424 */ 4425 boolean mRunning; 4426 4427 /** 4428 * Total number of times startService() has been called. 4429 */ 4430 int mStarts; 4431 4432 /** 4433 * Total time (ms in battery uptime) the service has been left launched. 4434 */ 4435 long mLaunchedTime; 4436 4437 /** 4438 * If service has been launched and not yet exited, this is 4439 * when it was launched (ms in battery uptime). 4440 */ 4441 long mLaunchedSince; 4442 4443 /** 4444 * True if we are currently launched. 4445 */ 4446 boolean mLaunched; 4447 4448 /** 4449 * Total number times the service has been launched. 4450 */ 4451 int mLaunches; 4452 4453 /** 4454 * The amount of time spent started loaded from a previous save 4455 * (ms in battery uptime). 4456 */ 4457 long mLoadedStartTime; 4458 4459 /** 4460 * The number of starts loaded from a previous save. 4461 */ 4462 int mLoadedStarts; 4463 4464 /** 4465 * The number of launches loaded from a previous save. 4466 */ 4467 int mLoadedLaunches; 4468 4469 /** 4470 * The amount of time spent started as of the last run (ms 4471 * in battery uptime). 4472 */ 4473 long mLastStartTime; 4474 4475 /** 4476 * The number of starts as of the last run. 4477 */ 4478 int mLastStarts; 4479 4480 /** 4481 * The number of launches as of the last run. 4482 */ 4483 int mLastLaunches; 4484 4485 /** 4486 * The amount of time spent started when last unplugged (ms 4487 * in battery uptime). 4488 */ 4489 long mUnpluggedStartTime; 4490 4491 /** 4492 * The number of starts when last unplugged. 4493 */ 4494 int mUnpluggedStarts; 4495 4496 /** 4497 * The number of launches when last unplugged. 4498 */ 4499 int mUnpluggedLaunches; 4500 4501 Serv() { 4502 mUnpluggables.add(this); 4503 } 4504 4505 public void unplug(long elapsedRealtime, long batteryUptime, long batteryRealtime) { 4506 mUnpluggedStartTime = getStartTimeToNowLocked(batteryUptime); 4507 mUnpluggedStarts = mStarts; 4508 mUnpluggedLaunches = mLaunches; 4509 } 4510 4511 public void plug(long elapsedRealtime, long batteryUptime, long batteryRealtime) { 4512 } 4513 4514 void detach() { 4515 mUnpluggables.remove(this); 4516 } 4517 4518 void readFromParcelLocked(Parcel in) { 4519 mStartTime = in.readLong(); 4520 mRunningSince = in.readLong(); 4521 mRunning = in.readInt() != 0; 4522 mStarts = in.readInt(); 4523 mLaunchedTime = in.readLong(); 4524 mLaunchedSince = in.readLong(); 4525 mLaunched = in.readInt() != 0; 4526 mLaunches = in.readInt(); 4527 mLoadedStartTime = in.readLong(); 4528 mLoadedStarts = in.readInt(); 4529 mLoadedLaunches = in.readInt(); 4530 mLastStartTime = 0; 4531 mLastStarts = 0; 4532 mLastLaunches = 0; 4533 mUnpluggedStartTime = in.readLong(); 4534 mUnpluggedStarts = in.readInt(); 4535 mUnpluggedLaunches = in.readInt(); 4536 } 4537 4538 void writeToParcelLocked(Parcel out) { 4539 out.writeLong(mStartTime); 4540 out.writeLong(mRunningSince); 4541 out.writeInt(mRunning ? 1 : 0); 4542 out.writeInt(mStarts); 4543 out.writeLong(mLaunchedTime); 4544 out.writeLong(mLaunchedSince); 4545 out.writeInt(mLaunched ? 1 : 0); 4546 out.writeInt(mLaunches); 4547 out.writeLong(mLoadedStartTime); 4548 out.writeInt(mLoadedStarts); 4549 out.writeInt(mLoadedLaunches); 4550 out.writeLong(mUnpluggedStartTime); 4551 out.writeInt(mUnpluggedStarts); 4552 out.writeInt(mUnpluggedLaunches); 4553 } 4554 4555 long getLaunchTimeToNowLocked(long batteryUptime) { 4556 if (!mLaunched) return mLaunchedTime; 4557 return mLaunchedTime + batteryUptime - mLaunchedSince; 4558 } 4559 4560 long getStartTimeToNowLocked(long batteryUptime) { 4561 if (!mRunning) return mStartTime; 4562 return mStartTime + batteryUptime - mRunningSince; 4563 } 4564 4565 public void startLaunchedLocked() { 4566 if (!mLaunched) { 4567 mLaunches++; 4568 mLaunchedSince = getBatteryUptimeLocked(); 4569 mLaunched = true; 4570 } 4571 } 4572 4573 public void stopLaunchedLocked() { 4574 if (mLaunched) { 4575 long time = getBatteryUptimeLocked() - mLaunchedSince; 4576 if (time > 0) { 4577 mLaunchedTime += time; 4578 } else { 4579 mLaunches--; 4580 } 4581 mLaunched = false; 4582 } 4583 } 4584 4585 public void startRunningLocked() { 4586 if (!mRunning) { 4587 mStarts++; 4588 mRunningSince = getBatteryUptimeLocked(); 4589 mRunning = true; 4590 } 4591 } 4592 4593 public void stopRunningLocked() { 4594 if (mRunning) { 4595 long time = getBatteryUptimeLocked() - mRunningSince; 4596 if (time > 0) { 4597 mStartTime += time; 4598 } else { 4599 mStarts--; 4600 } 4601 mRunning = false; 4602 } 4603 } 4604 4605 public BatteryStatsImpl getBatteryStats() { 4606 return BatteryStatsImpl.this; 4607 } 4608 4609 @Override 4610 public int getLaunches(int which) { 4611 int val; 4612 4613 if (which == STATS_LAST) { 4614 val = mLastLaunches; 4615 } else { 4616 val = mLaunches; 4617 if (which == STATS_CURRENT) { 4618 val -= mLoadedLaunches; 4619 } else if (which == STATS_SINCE_UNPLUGGED) { 4620 val -= mUnpluggedLaunches; 4621 } 4622 } 4623 4624 return val; 4625 } 4626 4627 @Override 4628 public long getStartTime(long now, int which) { 4629 long val; 4630 if (which == STATS_LAST) { 4631 val = mLastStartTime; 4632 } else { 4633 val = getStartTimeToNowLocked(now); 4634 if (which == STATS_CURRENT) { 4635 val -= mLoadedStartTime; 4636 } else if (which == STATS_SINCE_UNPLUGGED) { 4637 val -= mUnpluggedStartTime; 4638 } 4639 } 4640 4641 return val; 4642 } 4643 4644 @Override 4645 public int getStarts(int which) { 4646 int val; 4647 if (which == STATS_LAST) { 4648 val = mLastStarts; 4649 } else { 4650 val = mStarts; 4651 if (which == STATS_CURRENT) { 4652 val -= mLoadedStarts; 4653 } else if (which == STATS_SINCE_UNPLUGGED) { 4654 val -= mUnpluggedStarts; 4655 } 4656 } 4657 4658 return val; 4659 } 4660 } 4661 4662 public BatteryStatsImpl getBatteryStats() { 4663 return BatteryStatsImpl.this; 4664 } 4665 4666 public void incWakeupsLocked() { 4667 mWakeups++; 4668 } 4669 4670 final Serv newServiceStatsLocked() { 4671 return new Serv(); 4672 } 4673 } 4674 4675 /** 4676 * Retrieve the statistics object for a particular process, creating 4677 * if needed. 4678 */ 4679 public Proc getProcessStatsLocked(String name) { 4680 Proc ps = mProcessStats.get(name); 4681 if (ps == null) { 4682 ps = new Proc(); 4683 mProcessStats.put(name, ps); 4684 } 4685 4686 return ps; 4687 } 4688 4689 public SparseArray<? extends Pid> getPidStats() { 4690 return mPids; 4691 } 4692 4693 public Pid getPidStatsLocked(int pid) { 4694 Pid p = mPids.get(pid); 4695 if (p == null) { 4696 p = new Pid(); 4697 mPids.put(pid, p); 4698 } 4699 return p; 4700 } 4701 4702 /** 4703 * Retrieve the statistics object for a particular service, creating 4704 * if needed. 4705 */ 4706 public Pkg getPackageStatsLocked(String name) { 4707 Pkg ps = mPackageStats.get(name); 4708 if (ps == null) { 4709 ps = new Pkg(); 4710 mPackageStats.put(name, ps); 4711 } 4712 4713 return ps; 4714 } 4715 4716 /** 4717 * Retrieve the statistics object for a particular service, creating 4718 * if needed. 4719 */ 4720 public Pkg.Serv getServiceStatsLocked(String pkg, String serv) { 4721 Pkg ps = getPackageStatsLocked(pkg); 4722 Pkg.Serv ss = ps.mServiceStats.get(serv); 4723 if (ss == null) { 4724 ss = ps.newServiceStatsLocked(); 4725 ps.mServiceStats.put(serv, ss); 4726 } 4727 4728 return ss; 4729 } 4730 4731 public StopwatchTimer getWakeTimerLocked(String name, int type) { 4732 Wakelock wl = mWakelockStats.get(name); 4733 if (wl == null) { 4734 final int N = mWakelockStats.size(); 4735 if (N > MAX_WAKELOCKS_PER_UID) { 4736 name = BATCHED_WAKELOCK_NAME; 4737 wl = mWakelockStats.get(name); 4738 } 4739 if (wl == null) { 4740 wl = new Wakelock(); 4741 mWakelockStats.put(name, wl); 4742 } 4743 } 4744 StopwatchTimer t = null; 4745 switch (type) { 4746 case WAKE_TYPE_PARTIAL: 4747 t = wl.mTimerPartial; 4748 if (t == null) { 4749 t = new StopwatchTimer(Uid.this, WAKE_TYPE_PARTIAL, 4750 mPartialTimers, mUnpluggables); 4751 wl.mTimerPartial = t; 4752 } 4753 return t; 4754 case WAKE_TYPE_FULL: 4755 t = wl.mTimerFull; 4756 if (t == null) { 4757 t = new StopwatchTimer(Uid.this, WAKE_TYPE_FULL, 4758 mFullTimers, mUnpluggables); 4759 wl.mTimerFull = t; 4760 } 4761 return t; 4762 case WAKE_TYPE_WINDOW: 4763 t = wl.mTimerWindow; 4764 if (t == null) { 4765 t = new StopwatchTimer(Uid.this, WAKE_TYPE_WINDOW, 4766 mWindowTimers, mUnpluggables); 4767 wl.mTimerWindow = t; 4768 } 4769 return t; 4770 default: 4771 throw new IllegalArgumentException("type=" + type); 4772 } 4773 } 4774 4775 public StopwatchTimer getSensorTimerLocked(int sensor, boolean create) { 4776 Sensor se = mSensorStats.get(sensor); 4777 if (se == null) { 4778 if (!create) { 4779 return null; 4780 } 4781 se = new Sensor(sensor); 4782 mSensorStats.put(sensor, se); 4783 } 4784 StopwatchTimer t = se.mTimer; 4785 if (t != null) { 4786 return t; 4787 } 4788 ArrayList<StopwatchTimer> timers = mSensorTimers.get(sensor); 4789 if (timers == null) { 4790 timers = new ArrayList<StopwatchTimer>(); 4791 mSensorTimers.put(sensor, timers); 4792 } 4793 t = new StopwatchTimer(Uid.this, BatteryStats.SENSOR, timers, mUnpluggables); 4794 se.mTimer = t; 4795 return t; 4796 } 4797 4798 public void noteStartWakeLocked(int pid, String name, int type) { 4799 StopwatchTimer t = getWakeTimerLocked(name, type); 4800 if (t != null) { 4801 t.startRunningLocked(BatteryStatsImpl.this); 4802 } 4803 if (pid >= 0 && type == WAKE_TYPE_PARTIAL) { 4804 Pid p = getPidStatsLocked(pid); 4805 if (p.mWakeStart == 0) { 4806 p.mWakeStart = SystemClock.elapsedRealtime(); 4807 } 4808 } 4809 } 4810 4811 public void noteStopWakeLocked(int pid, String name, int type) { 4812 StopwatchTimer t = getWakeTimerLocked(name, type); 4813 if (t != null) { 4814 t.stopRunningLocked(BatteryStatsImpl.this); 4815 } 4816 if (pid >= 0 && type == WAKE_TYPE_PARTIAL) { 4817 Pid p = mPids.get(pid); 4818 if (p != null && p.mWakeStart != 0) { 4819 p.mWakeSum += SystemClock.elapsedRealtime() - p.mWakeStart; 4820 p.mWakeStart = 0; 4821 } 4822 } 4823 } 4824 4825 public void reportExcessiveWakeLocked(String proc, long overTime, long usedTime) { 4826 Proc p = getProcessStatsLocked(proc); 4827 if (p != null) { 4828 p.addExcessiveWake(overTime, usedTime); 4829 } 4830 } 4831 4832 public void reportExcessiveCpuLocked(String proc, long overTime, long usedTime) { 4833 Proc p = getProcessStatsLocked(proc); 4834 if (p != null) { 4835 p.addExcessiveCpu(overTime, usedTime); 4836 } 4837 } 4838 4839 public void noteStartSensor(int sensor) { 4840 StopwatchTimer t = getSensorTimerLocked(sensor, true); 4841 if (t != null) { 4842 t.startRunningLocked(BatteryStatsImpl.this); 4843 } 4844 } 4845 4846 public void noteStopSensor(int sensor) { 4847 // Don't create a timer if one doesn't already exist 4848 StopwatchTimer t = getSensorTimerLocked(sensor, false); 4849 if (t != null) { 4850 t.stopRunningLocked(BatteryStatsImpl.this); 4851 } 4852 } 4853 4854 public void noteStartGps() { 4855 StopwatchTimer t = getSensorTimerLocked(Sensor.GPS, true); 4856 if (t != null) { 4857 t.startRunningLocked(BatteryStatsImpl.this); 4858 } 4859 } 4860 4861 public void noteStopGps() { 4862 StopwatchTimer t = getSensorTimerLocked(Sensor.GPS, false); 4863 if (t != null) { 4864 t.stopRunningLocked(BatteryStatsImpl.this); 4865 } 4866 } 4867 4868 public BatteryStatsImpl getBatteryStats() { 4869 return BatteryStatsImpl.this; 4870 } 4871 } 4872 4873 public BatteryStatsImpl(String filename, Handler handler) { 4874 mFile = new JournaledFile(new File(filename), new File(filename + ".tmp")); 4875 mHandler = new MyHandler(handler.getLooper()); 4876 mStartCount++; 4877 mScreenOnTimer = new StopwatchTimer(null, -1, null, mUnpluggables); 4878 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 4879 mScreenBrightnessTimer[i] = new StopwatchTimer(null, -100-i, null, mUnpluggables); 4880 } 4881 mInputEventCounter = new Counter(mUnpluggables); 4882 mPhoneOnTimer = new StopwatchTimer(null, -2, null, mUnpluggables); 4883 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) { 4884 mPhoneSignalStrengthsTimer[i] = new StopwatchTimer(null, -200-i, null, mUnpluggables); 4885 } 4886 mPhoneSignalScanningTimer = new StopwatchTimer(null, -200+1, null, mUnpluggables); 4887 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 4888 mPhoneDataConnectionsTimer[i] = new StopwatchTimer(null, -300-i, null, mUnpluggables); 4889 } 4890 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 4891 mNetworkByteActivityCounters[i] = new LongSamplingCounter(mUnpluggables); 4892 mNetworkPacketActivityCounters[i] = new LongSamplingCounter(mUnpluggables); 4893 } 4894 mWifiOnTimer = new StopwatchTimer(null, -3, null, mUnpluggables); 4895 mGlobalWifiRunningTimer = new StopwatchTimer(null, -4, null, mUnpluggables); 4896 mBluetoothOnTimer = new StopwatchTimer(null, -5, null, mUnpluggables); 4897 mAudioOnTimer = new StopwatchTimer(null, -6, null, mUnpluggables); 4898 mVideoOnTimer = new StopwatchTimer(null, -7, null, mUnpluggables); 4899 mOnBattery = mOnBatteryInternal = false; 4900 initTimes(); 4901 mTrackBatteryPastUptime = 0; 4902 mTrackBatteryPastRealtime = 0; 4903 mUptimeStart = mTrackBatteryUptimeStart = SystemClock.uptimeMillis() * 1000; 4904 mRealtimeStart = mTrackBatteryRealtimeStart = SystemClock.elapsedRealtime() * 1000; 4905 mUnpluggedBatteryUptime = getBatteryUptimeLocked(mUptimeStart); 4906 mUnpluggedBatteryRealtime = getBatteryRealtimeLocked(mRealtimeStart); 4907 mDischargeStartLevel = 0; 4908 mDischargeUnplugLevel = 0; 4909 mDischargeCurrentLevel = 0; 4910 initDischarge(); 4911 clearHistoryLocked(); 4912 } 4913 4914 public BatteryStatsImpl(Parcel p) { 4915 mFile = null; 4916 mHandler = null; 4917 clearHistoryLocked(); 4918 readFromParcel(p); 4919 } 4920 4921 public void setCallback(BatteryCallback cb) { 4922 mCallback = cb; 4923 } 4924 4925 public void setNumSpeedSteps(int steps) { 4926 if (sNumSpeedSteps == 0) sNumSpeedSteps = steps; 4927 } 4928 4929 public void setRadioScanningTimeout(long timeout) { 4930 if (mPhoneSignalScanningTimer != null) { 4931 mPhoneSignalScanningTimer.setTimeout(timeout); 4932 } 4933 } 4934 4935 @Override 4936 public boolean startIteratingOldHistoryLocked() { 4937 if (DEBUG_HISTORY) Slog.i(TAG, "ITERATING: buff size=" + mHistoryBuffer.dataSize() 4938 + " pos=" + mHistoryBuffer.dataPosition()); 4939 if ((mHistoryIterator = mHistory) == null) { 4940 return false; 4941 } 4942 mHistoryBuffer.setDataPosition(0); 4943 mHistoryReadTmp.clear(); 4944 mReadOverflow = false; 4945 mIteratingHistory = true; 4946 return true; 4947 } 4948 4949 @Override 4950 public boolean getNextOldHistoryLocked(HistoryItem out) { 4951 boolean end = mHistoryBuffer.dataPosition() >= mHistoryBuffer.dataSize(); 4952 if (!end) { 4953 readHistoryDelta(mHistoryBuffer, mHistoryReadTmp); 4954 mReadOverflow |= mHistoryReadTmp.cmd == HistoryItem.CMD_OVERFLOW; 4955 } 4956 HistoryItem cur = mHistoryIterator; 4957 if (cur == null) { 4958 if (!mReadOverflow && !end) { 4959 Slog.w(TAG, "Old history ends before new history!"); 4960 } 4961 return false; 4962 } 4963 out.setTo(cur); 4964 mHistoryIterator = cur.next; 4965 if (!mReadOverflow) { 4966 if (end) { 4967 Slog.w(TAG, "New history ends before old history!"); 4968 } else if (!out.same(mHistoryReadTmp)) { 4969 long now = getHistoryBaseTime() + SystemClock.elapsedRealtime(); 4970 PrintWriter pw = new FastPrintWriter(new LogWriter(android.util.Log.WARN, TAG)); 4971 pw.println("Histories differ!"); 4972 pw.println("Old history:"); 4973 (new HistoryPrinter()).printNextItem(pw, out, now, false); 4974 pw.println("New history:"); 4975 (new HistoryPrinter()).printNextItem(pw, mHistoryReadTmp, now, false); 4976 pw.flush(); 4977 } 4978 } 4979 return true; 4980 } 4981 4982 @Override 4983 public void finishIteratingOldHistoryLocked() { 4984 mIteratingHistory = false; 4985 mHistoryBuffer.setDataPosition(mHistoryBuffer.dataSize()); 4986 mHistoryIterator = null; 4987 } 4988 4989 public int getHistoryTotalSize() { 4990 return MAX_HISTORY_BUFFER; 4991 } 4992 4993 public int getHistoryUsedSize() { 4994 return mHistoryBuffer.dataSize(); 4995 } 4996 4997 @Override 4998 public boolean startIteratingHistoryLocked() { 4999 if (DEBUG_HISTORY) Slog.i(TAG, "ITERATING: buff size=" + mHistoryBuffer.dataSize() 5000 + " pos=" + mHistoryBuffer.dataPosition()); 5001 if (mHistoryBuffer.dataSize() <= 0) { 5002 return false; 5003 } 5004 mHistoryBuffer.setDataPosition(0); 5005 mReadOverflow = false; 5006 mIteratingHistory = true; 5007 mReadHistoryStrings = new String[mHistoryTagPool.size()]; 5008 mReadHistoryUids = new int[mHistoryTagPool.size()]; 5009 mReadHistoryChars = 0; 5010 for (HashMap.Entry<HistoryTag, Integer> ent : mHistoryTagPool.entrySet()) { 5011 final HistoryTag tag = ent.getKey(); 5012 final int idx = ent.getValue(); 5013 mReadHistoryStrings[idx] = tag.string; 5014 mReadHistoryUids[idx] = tag.uid; 5015 mReadHistoryChars += tag.string.length() + 1; 5016 } 5017 return true; 5018 } 5019 5020 @Override 5021 public int getHistoryStringPoolSize() { 5022 return mReadHistoryStrings.length; 5023 } 5024 5025 @Override 5026 public int getHistoryStringPoolBytes() { 5027 // Each entry is a fixed 12 bytes: 4 for index, 4 for uid, 4 for string size 5028 // Each string character is 2 bytes. 5029 return (mReadHistoryStrings.length * 12) + (mReadHistoryChars * 2); 5030 } 5031 5032 @Override 5033 public String getHistoryTagPoolString(int index) { 5034 return mReadHistoryStrings[index]; 5035 } 5036 5037 @Override 5038 public int getHistoryTagPoolUid(int index) { 5039 return mReadHistoryUids[index]; 5040 } 5041 5042 @Override 5043 public boolean getNextHistoryLocked(HistoryItem out) { 5044 final int pos = mHistoryBuffer.dataPosition(); 5045 if (pos == 0) { 5046 out.clear(); 5047 } 5048 boolean end = pos >= mHistoryBuffer.dataSize(); 5049 if (end) { 5050 return false; 5051 } 5052 5053 readHistoryDelta(mHistoryBuffer, out); 5054 return true; 5055 } 5056 5057 @Override 5058 public void finishIteratingHistoryLocked() { 5059 mIteratingHistory = false; 5060 mHistoryBuffer.setDataPosition(mHistoryBuffer.dataSize()); 5061 mReadHistoryStrings = null; 5062 } 5063 5064 @Override 5065 public long getHistoryBaseTime() { 5066 return mHistoryBaseTime; 5067 } 5068 5069 @Override 5070 public int getStartCount() { 5071 return mStartCount; 5072 } 5073 5074 public boolean isOnBattery() { 5075 return mOnBattery; 5076 } 5077 5078 public boolean isScreenOn() { 5079 return mScreenOn; 5080 } 5081 5082 void initTimes() { 5083 mStartClockTime = System.currentTimeMillis(); 5084 mBatteryRealtime = mTrackBatteryPastUptime = 0; 5085 mBatteryUptime = mTrackBatteryPastRealtime = 0; 5086 mUptimeStart = mTrackBatteryUptimeStart = SystemClock.uptimeMillis() * 1000; 5087 mRealtimeStart = mTrackBatteryRealtimeStart = SystemClock.elapsedRealtime() * 1000; 5088 mUnpluggedBatteryUptime = getBatteryUptimeLocked(mUptimeStart); 5089 mUnpluggedBatteryRealtime = getBatteryRealtimeLocked(mRealtimeStart); 5090 } 5091 5092 void initDischarge() { 5093 mLowDischargeAmountSinceCharge = 0; 5094 mHighDischargeAmountSinceCharge = 0; 5095 mDischargeAmountScreenOn = 0; 5096 mDischargeAmountScreenOnSinceCharge = 0; 5097 mDischargeAmountScreenOff = 0; 5098 mDischargeAmountScreenOffSinceCharge = 0; 5099 } 5100 5101 public void resetAllStatsCmdLocked() { 5102 resetAllStatsLocked(); 5103 long uptime = SystemClock.uptimeMillis() * 1000; 5104 long mSecRealtime = SystemClock.elapsedRealtime(); 5105 long realtime = mSecRealtime * 1000; 5106 mDischargeStartLevel = mHistoryCur.batteryLevel; 5107 pullPendingStateUpdatesLocked(); 5108 addHistoryRecordLocked(mSecRealtime); 5109 mDischargeCurrentLevel = mDischargeUnplugLevel = mHistoryCur.batteryLevel; 5110 if ((mHistoryCur.states&HistoryItem.STATE_BATTERY_PLUGGED_FLAG) != 0) { 5111 mTrackBatteryPastUptime = 0; 5112 mTrackBatteryPastRealtime = 0; 5113 } else { 5114 mTrackBatteryUptimeStart = uptime; 5115 mTrackBatteryRealtimeStart = realtime; 5116 mUnpluggedBatteryUptime = getBatteryUptimeLocked(uptime); 5117 mUnpluggedBatteryRealtime = getBatteryRealtimeLocked(realtime); 5118 if (mScreenOn) { 5119 mDischargeScreenOnUnplugLevel = mHistoryCur.batteryLevel; 5120 mDischargeScreenOffUnplugLevel = 0; 5121 } else { 5122 mDischargeScreenOnUnplugLevel = 0; 5123 mDischargeScreenOffUnplugLevel = mHistoryCur.batteryLevel; 5124 } 5125 mDischargeAmountScreenOn = 0; 5126 mDischargeAmountScreenOff = 0; 5127 } 5128 } 5129 5130 private void resetAllStatsLocked() { 5131 mStartCount = 0; 5132 initTimes(); 5133 mScreenOnTimer.reset(this, false); 5134 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 5135 mScreenBrightnessTimer[i].reset(this, false); 5136 } 5137 mInputEventCounter.reset(false); 5138 mPhoneOnTimer.reset(this, false); 5139 mAudioOnTimer.reset(this, false); 5140 mVideoOnTimer.reset(this, false); 5141 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) { 5142 mPhoneSignalStrengthsTimer[i].reset(this, false); 5143 } 5144 mPhoneSignalScanningTimer.reset(this, false); 5145 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 5146 mPhoneDataConnectionsTimer[i].reset(this, false); 5147 } 5148 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 5149 mNetworkByteActivityCounters[i].reset(false); 5150 mNetworkPacketActivityCounters[i].reset(false); 5151 } 5152 mWifiOnTimer.reset(this, false); 5153 mGlobalWifiRunningTimer.reset(this, false); 5154 mBluetoothOnTimer.reset(this, false); 5155 5156 for (int i=0; i<mUidStats.size(); i++) { 5157 if (mUidStats.valueAt(i).reset()) { 5158 mUidStats.remove(mUidStats.keyAt(i)); 5159 i--; 5160 } 5161 } 5162 5163 if (mKernelWakelockStats.size() > 0) { 5164 for (SamplingTimer timer : mKernelWakelockStats.values()) { 5165 mUnpluggables.remove(timer); 5166 } 5167 mKernelWakelockStats.clear(); 5168 } 5169 5170 initDischarge(); 5171 5172 clearHistoryLocked(); 5173 } 5174 5175 void updateDischargeScreenLevelsLocked(boolean oldScreenOn, boolean newScreenOn) { 5176 if (oldScreenOn) { 5177 int diff = mDischargeScreenOnUnplugLevel - mDischargeCurrentLevel; 5178 if (diff > 0) { 5179 mDischargeAmountScreenOn += diff; 5180 mDischargeAmountScreenOnSinceCharge += diff; 5181 } 5182 } else { 5183 int diff = mDischargeScreenOffUnplugLevel - mDischargeCurrentLevel; 5184 if (diff > 0) { 5185 mDischargeAmountScreenOff += diff; 5186 mDischargeAmountScreenOffSinceCharge += diff; 5187 } 5188 } 5189 if (newScreenOn) { 5190 mDischargeScreenOnUnplugLevel = mDischargeCurrentLevel; 5191 mDischargeScreenOffUnplugLevel = 0; 5192 } else { 5193 mDischargeScreenOnUnplugLevel = 0; 5194 mDischargeScreenOffUnplugLevel = mDischargeCurrentLevel; 5195 } 5196 } 5197 5198 void setOnBattery(boolean onBattery, int oldStatus, int level) { 5199 synchronized(this) { 5200 setOnBatteryLocked(onBattery, oldStatus, level); 5201 } 5202 } 5203 5204 public void pullPendingStateUpdatesLocked() { 5205 updateKernelWakelocksLocked(); 5206 updateNetworkActivityLocked(); 5207 } 5208 5209 void setOnBatteryLocked(boolean onBattery, int oldStatus, int level) { 5210 boolean doWrite = false; 5211 Message m = mHandler.obtainMessage(MSG_REPORT_POWER_CHANGE); 5212 m.arg1 = onBattery ? 1 : 0; 5213 mHandler.sendMessage(m); 5214 mOnBattery = mOnBatteryInternal = onBattery; 5215 5216 long uptime = SystemClock.uptimeMillis() * 1000; 5217 long mSecRealtime = SystemClock.elapsedRealtime(); 5218 long realtime = mSecRealtime * 1000; 5219 if (onBattery) { 5220 // We will reset our status if we are unplugging after the 5221 // battery was last full, or the level is at 100, or 5222 // we have gone through a significant charge (from a very low 5223 // level to a now very high level). 5224 if (oldStatus == BatteryManager.BATTERY_STATUS_FULL 5225 || level >= 90 5226 || (mDischargeCurrentLevel < 20 && level >= 80)) { 5227 doWrite = true; 5228 resetAllStatsLocked(); 5229 mDischargeStartLevel = level; 5230 } 5231 pullPendingStateUpdatesLocked(); 5232 mHistoryCur.batteryLevel = (byte)level; 5233 mHistoryCur.states &= ~HistoryItem.STATE_BATTERY_PLUGGED_FLAG; 5234 if (DEBUG_HISTORY) Slog.v(TAG, "Battery unplugged to: " 5235 + Integer.toHexString(mHistoryCur.states)); 5236 addHistoryRecordLocked(mSecRealtime); 5237 mTrackBatteryUptimeStart = uptime; 5238 mTrackBatteryRealtimeStart = realtime; 5239 mUnpluggedBatteryUptime = getBatteryUptimeLocked(uptime); 5240 mUnpluggedBatteryRealtime = getBatteryRealtimeLocked(realtime); 5241 mDischargeCurrentLevel = mDischargeUnplugLevel = level; 5242 if (mScreenOn) { 5243 mDischargeScreenOnUnplugLevel = level; 5244 mDischargeScreenOffUnplugLevel = 0; 5245 } else { 5246 mDischargeScreenOnUnplugLevel = 0; 5247 mDischargeScreenOffUnplugLevel = level; 5248 } 5249 mDischargeAmountScreenOn = 0; 5250 mDischargeAmountScreenOff = 0; 5251 doUnplugLocked(realtime, mUnpluggedBatteryUptime, mUnpluggedBatteryRealtime); 5252 } else { 5253 pullPendingStateUpdatesLocked(); 5254 mHistoryCur.batteryLevel = (byte)level; 5255 mHistoryCur.states |= HistoryItem.STATE_BATTERY_PLUGGED_FLAG; 5256 if (DEBUG_HISTORY) Slog.v(TAG, "Battery plugged to: " 5257 + Integer.toHexString(mHistoryCur.states)); 5258 addHistoryRecordLocked(mSecRealtime); 5259 mTrackBatteryPastUptime += uptime - mTrackBatteryUptimeStart; 5260 mTrackBatteryPastRealtime += realtime - mTrackBatteryRealtimeStart; 5261 mDischargeCurrentLevel = level; 5262 if (level < mDischargeUnplugLevel) { 5263 mLowDischargeAmountSinceCharge += mDischargeUnplugLevel-level-1; 5264 mHighDischargeAmountSinceCharge += mDischargeUnplugLevel-level; 5265 } 5266 updateDischargeScreenLevelsLocked(mScreenOn, mScreenOn); 5267 doPlugLocked(realtime, getBatteryUptimeLocked(uptime), getBatteryRealtimeLocked(realtime)); 5268 } 5269 if (doWrite || (mLastWriteTime + (60 * 1000)) < mSecRealtime) { 5270 if (mFile != null) { 5271 writeAsyncLocked(); 5272 } 5273 } 5274 } 5275 5276 // This should probably be exposed in the API, though it's not critical 5277 private static final int BATTERY_PLUGGED_NONE = 0; 5278 5279 public void setBatteryState(int status, int health, int plugType, int level, 5280 int temp, int volt) { 5281 synchronized(this) { 5282 boolean onBattery = plugType == BATTERY_PLUGGED_NONE; 5283 int oldStatus = mHistoryCur.batteryStatus; 5284 if (!mHaveBatteryLevel) { 5285 mHaveBatteryLevel = true; 5286 // We start out assuming that the device is plugged in (not 5287 // on battery). If our first report is now that we are indeed 5288 // plugged in, then twiddle our state to correctly reflect that 5289 // since we won't be going through the full setOnBattery(). 5290 if (onBattery == mOnBattery) { 5291 if (onBattery) { 5292 mHistoryCur.states &= ~HistoryItem.STATE_BATTERY_PLUGGED_FLAG; 5293 } else { 5294 mHistoryCur.states |= HistoryItem.STATE_BATTERY_PLUGGED_FLAG; 5295 } 5296 } 5297 oldStatus = status; 5298 } 5299 if (onBattery) { 5300 mDischargeCurrentLevel = level; 5301 mRecordingHistory = true; 5302 } 5303 if (onBattery != mOnBattery) { 5304 mHistoryCur.batteryLevel = (byte)level; 5305 mHistoryCur.batteryStatus = (byte)status; 5306 mHistoryCur.batteryHealth = (byte)health; 5307 mHistoryCur.batteryPlugType = (byte)plugType; 5308 mHistoryCur.batteryTemperature = (short)temp; 5309 mHistoryCur.batteryVoltage = (char)volt; 5310 setOnBatteryLocked(onBattery, oldStatus, level); 5311 } else { 5312 boolean changed = false; 5313 if (mHistoryCur.batteryLevel != level) { 5314 mHistoryCur.batteryLevel = (byte)level; 5315 changed = true; 5316 } 5317 if (mHistoryCur.batteryStatus != status) { 5318 mHistoryCur.batteryStatus = (byte)status; 5319 changed = true; 5320 } 5321 if (mHistoryCur.batteryHealth != health) { 5322 mHistoryCur.batteryHealth = (byte)health; 5323 changed = true; 5324 } 5325 if (mHistoryCur.batteryPlugType != plugType) { 5326 mHistoryCur.batteryPlugType = (byte)plugType; 5327 changed = true; 5328 } 5329 if (temp >= (mHistoryCur.batteryTemperature+10) 5330 || temp <= (mHistoryCur.batteryTemperature-10)) { 5331 mHistoryCur.batteryTemperature = (short)temp; 5332 changed = true; 5333 } 5334 if (volt > (mHistoryCur.batteryVoltage+20) 5335 || volt < (mHistoryCur.batteryVoltage-20)) { 5336 mHistoryCur.batteryVoltage = (char)volt; 5337 changed = true; 5338 } 5339 if (changed) { 5340 addHistoryRecordLocked(SystemClock.elapsedRealtime()); 5341 } 5342 } 5343 if (!onBattery && status == BatteryManager.BATTERY_STATUS_FULL) { 5344 // We don't record history while we are plugged in and fully charged. 5345 // The next time we are unplugged, history will be cleared. 5346 mRecordingHistory = DEBUG; 5347 } 5348 } 5349 } 5350 5351 public void updateKernelWakelocksLocked() { 5352 Map<String, KernelWakelockStats> m = readKernelWakelockStats(); 5353 5354 if (m == null) { 5355 // Not crashing might make board bringup easier. 5356 Slog.w(TAG, "Couldn't get kernel wake lock stats"); 5357 return; 5358 } 5359 5360 for (Map.Entry<String, KernelWakelockStats> ent : m.entrySet()) { 5361 String name = ent.getKey(); 5362 KernelWakelockStats kws = ent.getValue(); 5363 5364 SamplingTimer kwlt = mKernelWakelockStats.get(name); 5365 if (kwlt == null) { 5366 kwlt = new SamplingTimer(mUnpluggables, mOnBatteryInternal, 5367 true /* track reported values */); 5368 mKernelWakelockStats.put(name, kwlt); 5369 } 5370 kwlt.updateCurrentReportedCount(kws.mCount); 5371 kwlt.updateCurrentReportedTotalTime(kws.mTotalTime); 5372 kwlt.setUpdateVersion(sKernelWakelockUpdateVersion); 5373 } 5374 5375 if (m.size() != mKernelWakelockStats.size()) { 5376 // Set timers to stale if they didn't appear in /proc/wakelocks this time. 5377 for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) { 5378 SamplingTimer st = ent.getValue(); 5379 if (st.getUpdateVersion() != sKernelWakelockUpdateVersion) { 5380 st.setStale(); 5381 } 5382 } 5383 } 5384 } 5385 5386 private void updateNetworkActivityLocked() { 5387 if (!SystemProperties.getBoolean(PROP_QTAGUID_ENABLED, false)) return; 5388 5389 final NetworkStats snapshot; 5390 try { 5391 snapshot = mNetworkStatsFactory.readNetworkStatsDetail(); 5392 } catch (IOException e) { 5393 Log.wtf(TAG, "Failed to read network stats", e); 5394 return; 5395 } 5396 5397 if (mLastSnapshot == null) { 5398 mLastSnapshot = snapshot; 5399 return; 5400 } 5401 5402 final NetworkStats delta = snapshot.subtract(mLastSnapshot); 5403 mLastSnapshot = snapshot; 5404 5405 NetworkStats.Entry entry = null; 5406 final int size = delta.size(); 5407 for (int i = 0; i < size; i++) { 5408 entry = delta.getValues(i, entry); 5409 5410 if (entry.rxBytes == 0 || entry.txBytes == 0) continue; 5411 if (entry.tag != NetworkStats.TAG_NONE) continue; 5412 5413 final Uid u = getUidStatsLocked(entry.uid); 5414 5415 if (mMobileIfaces.contains(entry.iface)) { 5416 u.noteNetworkActivityLocked(NETWORK_MOBILE_RX_DATA, entry.rxBytes, 5417 entry.rxPackets); 5418 u.noteNetworkActivityLocked(NETWORK_MOBILE_TX_DATA, entry.txBytes, 5419 entry.txPackets); 5420 5421 mNetworkByteActivityCounters[NETWORK_MOBILE_RX_DATA].addCountLocked(entry.rxBytes); 5422 mNetworkByteActivityCounters[NETWORK_MOBILE_TX_DATA].addCountLocked(entry.txBytes); 5423 mNetworkPacketActivityCounters[NETWORK_MOBILE_RX_DATA].addCountLocked( 5424 entry.rxPackets); 5425 mNetworkPacketActivityCounters[NETWORK_MOBILE_TX_DATA].addCountLocked( 5426 entry.txPackets); 5427 5428 } else if (mWifiIfaces.contains(entry.iface)) { 5429 u.noteNetworkActivityLocked(NETWORK_WIFI_RX_DATA, entry.rxBytes, entry.rxPackets); 5430 u.noteNetworkActivityLocked(NETWORK_WIFI_TX_DATA, entry.txBytes, entry.txPackets); 5431 5432 mNetworkByteActivityCounters[NETWORK_WIFI_RX_DATA].addCountLocked(entry.rxBytes); 5433 mNetworkByteActivityCounters[NETWORK_WIFI_TX_DATA].addCountLocked(entry.txBytes); 5434 mNetworkPacketActivityCounters[NETWORK_WIFI_RX_DATA].addCountLocked( 5435 entry.rxPackets); 5436 mNetworkPacketActivityCounters[NETWORK_WIFI_TX_DATA].addCountLocked( 5437 entry.txPackets); 5438 } 5439 } 5440 } 5441 5442 public long getAwakeTimeBattery() { 5443 return computeBatteryUptime(getBatteryUptimeLocked(), STATS_CURRENT); 5444 } 5445 5446 public long getAwakeTimePlugged() { 5447 return (SystemClock.uptimeMillis() * 1000) - getAwakeTimeBattery(); 5448 } 5449 5450 @Override 5451 public long computeUptime(long curTime, int which) { 5452 switch (which) { 5453 case STATS_SINCE_CHARGED: return mUptime + (curTime-mUptimeStart); 5454 case STATS_LAST: return mLastUptime; 5455 case STATS_CURRENT: return (curTime-mUptimeStart); 5456 case STATS_SINCE_UNPLUGGED: return (curTime-mTrackBatteryUptimeStart); 5457 } 5458 return 0; 5459 } 5460 5461 @Override 5462 public long computeRealtime(long curTime, int which) { 5463 switch (which) { 5464 case STATS_SINCE_CHARGED: return mRealtime + (curTime-mRealtimeStart); 5465 case STATS_LAST: return mLastRealtime; 5466 case STATS_CURRENT: return (curTime-mRealtimeStart); 5467 case STATS_SINCE_UNPLUGGED: return (curTime-mTrackBatteryRealtimeStart); 5468 } 5469 return 0; 5470 } 5471 5472 @Override 5473 public long computeBatteryUptime(long curTime, int which) { 5474 switch (which) { 5475 case STATS_SINCE_CHARGED: 5476 return mBatteryUptime + getBatteryUptime(curTime); 5477 case STATS_LAST: 5478 return mBatteryLastUptime; 5479 case STATS_CURRENT: 5480 return getBatteryUptime(curTime); 5481 case STATS_SINCE_UNPLUGGED: 5482 return getBatteryUptimeLocked(curTime) - mUnpluggedBatteryUptime; 5483 } 5484 return 0; 5485 } 5486 5487 @Override 5488 public long computeBatteryRealtime(long curTime, int which) { 5489 switch (which) { 5490 case STATS_SINCE_CHARGED: 5491 return mBatteryRealtime + getBatteryRealtimeLocked(curTime); 5492 case STATS_LAST: 5493 return mBatteryLastRealtime; 5494 case STATS_CURRENT: 5495 return getBatteryRealtimeLocked(curTime); 5496 case STATS_SINCE_UNPLUGGED: 5497 return getBatteryRealtimeLocked(curTime) - mUnpluggedBatteryRealtime; 5498 } 5499 return 0; 5500 } 5501 5502 long getBatteryUptimeLocked(long curTime) { 5503 long time = mTrackBatteryPastUptime; 5504 if (mOnBatteryInternal) { 5505 time += curTime - mTrackBatteryUptimeStart; 5506 } 5507 return time; 5508 } 5509 5510 long getBatteryUptimeLocked() { 5511 return getBatteryUptime(SystemClock.uptimeMillis() * 1000); 5512 } 5513 5514 @Override 5515 public long getBatteryUptime(long curTime) { 5516 return getBatteryUptimeLocked(curTime); 5517 } 5518 5519 long getBatteryRealtimeLocked(long curTime) { 5520 long time = mTrackBatteryPastRealtime; 5521 if (mOnBatteryInternal) { 5522 time += curTime - mTrackBatteryRealtimeStart; 5523 } 5524 return time; 5525 } 5526 5527 @Override 5528 public long getBatteryRealtime(long curTime) { 5529 return getBatteryRealtimeLocked(curTime); 5530 } 5531 5532 @Override 5533 public int getDischargeStartLevel() { 5534 synchronized(this) { 5535 return getDischargeStartLevelLocked(); 5536 } 5537 } 5538 5539 public int getDischargeStartLevelLocked() { 5540 return mDischargeUnplugLevel; 5541 } 5542 5543 @Override 5544 public int getDischargeCurrentLevel() { 5545 synchronized(this) { 5546 return getDischargeCurrentLevelLocked(); 5547 } 5548 } 5549 5550 public int getDischargeCurrentLevelLocked() { 5551 return mDischargeCurrentLevel; 5552 } 5553 5554 @Override 5555 public int getLowDischargeAmountSinceCharge() { 5556 synchronized(this) { 5557 int val = mLowDischargeAmountSinceCharge; 5558 if (mOnBattery && mDischargeCurrentLevel < mDischargeUnplugLevel) { 5559 val += mDischargeUnplugLevel-mDischargeCurrentLevel-1; 5560 } 5561 return val; 5562 } 5563 } 5564 5565 @Override 5566 public int getHighDischargeAmountSinceCharge() { 5567 synchronized(this) { 5568 int val = mHighDischargeAmountSinceCharge; 5569 if (mOnBattery && mDischargeCurrentLevel < mDischargeUnplugLevel) { 5570 val += mDischargeUnplugLevel-mDischargeCurrentLevel; 5571 } 5572 return val; 5573 } 5574 } 5575 5576 public int getDischargeAmountScreenOn() { 5577 synchronized(this) { 5578 int val = mDischargeAmountScreenOn; 5579 if (mOnBattery && mScreenOn 5580 && mDischargeCurrentLevel < mDischargeScreenOnUnplugLevel) { 5581 val += mDischargeScreenOnUnplugLevel-mDischargeCurrentLevel; 5582 } 5583 return val; 5584 } 5585 } 5586 5587 public int getDischargeAmountScreenOnSinceCharge() { 5588 synchronized(this) { 5589 int val = mDischargeAmountScreenOnSinceCharge; 5590 if (mOnBattery && mScreenOn 5591 && mDischargeCurrentLevel < mDischargeScreenOnUnplugLevel) { 5592 val += mDischargeScreenOnUnplugLevel-mDischargeCurrentLevel; 5593 } 5594 return val; 5595 } 5596 } 5597 5598 public int getDischargeAmountScreenOff() { 5599 synchronized(this) { 5600 int val = mDischargeAmountScreenOff; 5601 if (mOnBattery && !mScreenOn 5602 && mDischargeCurrentLevel < mDischargeScreenOffUnplugLevel) { 5603 val += mDischargeScreenOffUnplugLevel-mDischargeCurrentLevel; 5604 } 5605 return val; 5606 } 5607 } 5608 5609 public int getDischargeAmountScreenOffSinceCharge() { 5610 synchronized(this) { 5611 int val = mDischargeAmountScreenOffSinceCharge; 5612 if (mOnBattery && !mScreenOn 5613 && mDischargeCurrentLevel < mDischargeScreenOffUnplugLevel) { 5614 val += mDischargeScreenOffUnplugLevel-mDischargeCurrentLevel; 5615 } 5616 return val; 5617 } 5618 } 5619 5620 @Override 5621 public int getCpuSpeedSteps() { 5622 return sNumSpeedSteps; 5623 } 5624 5625 /** 5626 * Retrieve the statistics object for a particular uid, creating if needed. 5627 */ 5628 public Uid getUidStatsLocked(int uid) { 5629 Uid u = mUidStats.get(uid); 5630 if (u == null) { 5631 u = new Uid(uid); 5632 mUidStats.put(uid, u); 5633 } 5634 return u; 5635 } 5636 5637 /** 5638 * Remove the statistics object for a particular uid. 5639 */ 5640 public void removeUidStatsLocked(int uid) { 5641 mUidStats.remove(uid); 5642 } 5643 5644 /** 5645 * Retrieve the statistics object for a particular process, creating 5646 * if needed. 5647 */ 5648 public Uid.Proc getProcessStatsLocked(int uid, String name) { 5649 Uid u = getUidStatsLocked(uid); 5650 return u.getProcessStatsLocked(name); 5651 } 5652 5653 /** 5654 * Retrieve the statistics object for a particular process, creating 5655 * if needed. 5656 */ 5657 public Uid.Pkg getPackageStatsLocked(int uid, String pkg) { 5658 Uid u = getUidStatsLocked(uid); 5659 return u.getPackageStatsLocked(pkg); 5660 } 5661 5662 /** 5663 * Retrieve the statistics object for a particular service, creating 5664 * if needed. 5665 */ 5666 public Uid.Pkg.Serv getServiceStatsLocked(int uid, String pkg, String name) { 5667 Uid u = getUidStatsLocked(uid); 5668 return u.getServiceStatsLocked(pkg, name); 5669 } 5670 5671 /** 5672 * Massage data to distribute any reasonable work down to more specific 5673 * owners. Must only be called on a dead BatteryStats object! 5674 */ 5675 public void distributeWorkLocked(int which) { 5676 // Aggregate all CPU time associated with WIFI. 5677 Uid wifiUid = mUidStats.get(Process.WIFI_UID); 5678 if (wifiUid != null) { 5679 long uSecTime = computeBatteryRealtime(SystemClock.elapsedRealtime() * 1000, which); 5680 for (Uid.Proc proc : wifiUid.mProcessStats.values()) { 5681 long totalRunningTime = getGlobalWifiRunningTime(uSecTime, which); 5682 for (int i=0; i<mUidStats.size(); i++) { 5683 Uid uid = mUidStats.valueAt(i); 5684 if (uid.mUid != Process.WIFI_UID) { 5685 long uidRunningTime = uid.getWifiRunningTime(uSecTime, which); 5686 if (uidRunningTime > 0) { 5687 Uid.Proc uidProc = uid.getProcessStatsLocked("*wifi*"); 5688 long time = proc.getUserTime(which); 5689 time = (time*uidRunningTime)/totalRunningTime; 5690 uidProc.mUserTime += time; 5691 proc.mUserTime -= time; 5692 time = proc.getSystemTime(which); 5693 time = (time*uidRunningTime)/totalRunningTime; 5694 uidProc.mSystemTime += time; 5695 proc.mSystemTime -= time; 5696 time = proc.getForegroundTime(which); 5697 time = (time*uidRunningTime)/totalRunningTime; 5698 uidProc.mForegroundTime += time; 5699 proc.mForegroundTime -= time; 5700 for (int sb=0; sb<proc.mSpeedBins.length; sb++) { 5701 SamplingCounter sc = proc.mSpeedBins[sb]; 5702 if (sc != null) { 5703 time = sc.getCountLocked(which); 5704 time = (time*uidRunningTime)/totalRunningTime; 5705 SamplingCounter uidSc = uidProc.mSpeedBins[sb]; 5706 if (uidSc == null) { 5707 uidSc = new SamplingCounter(mUnpluggables); 5708 uidProc.mSpeedBins[sb] = uidSc; 5709 } 5710 uidSc.mCount.addAndGet((int)time); 5711 sc.mCount.addAndGet((int)-time); 5712 } 5713 } 5714 totalRunningTime -= uidRunningTime; 5715 } 5716 } 5717 } 5718 } 5719 } 5720 } 5721 5722 public void shutdownLocked() { 5723 writeSyncLocked(); 5724 mShuttingDown = true; 5725 } 5726 5727 Parcel mPendingWrite = null; 5728 final ReentrantLock mWriteLock = new ReentrantLock(); 5729 5730 public void writeAsyncLocked() { 5731 writeLocked(false); 5732 } 5733 5734 public void writeSyncLocked() { 5735 writeLocked(true); 5736 } 5737 5738 void writeLocked(boolean sync) { 5739 if (mFile == null) { 5740 Slog.w("BatteryStats", "writeLocked: no file associated with this instance"); 5741 return; 5742 } 5743 5744 if (mShuttingDown) { 5745 return; 5746 } 5747 5748 Parcel out = Parcel.obtain(); 5749 writeSummaryToParcel(out); 5750 mLastWriteTime = SystemClock.elapsedRealtime(); 5751 5752 if (mPendingWrite != null) { 5753 mPendingWrite.recycle(); 5754 } 5755 mPendingWrite = out; 5756 5757 if (sync) { 5758 commitPendingDataToDisk(); 5759 } else { 5760 Thread thr = new Thread("BatteryStats-Write") { 5761 @Override 5762 public void run() { 5763 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 5764 commitPendingDataToDisk(); 5765 } 5766 }; 5767 thr.start(); 5768 } 5769 } 5770 5771 public void commitPendingDataToDisk() { 5772 final Parcel next; 5773 synchronized (this) { 5774 next = mPendingWrite; 5775 mPendingWrite = null; 5776 if (next == null) { 5777 return; 5778 } 5779 5780 mWriteLock.lock(); 5781 } 5782 5783 try { 5784 FileOutputStream stream = new FileOutputStream(mFile.chooseForWrite()); 5785 stream.write(next.marshall()); 5786 stream.flush(); 5787 FileUtils.sync(stream); 5788 stream.close(); 5789 mFile.commit(); 5790 } catch (IOException e) { 5791 Slog.w("BatteryStats", "Error writing battery statistics", e); 5792 mFile.rollback(); 5793 } finally { 5794 next.recycle(); 5795 mWriteLock.unlock(); 5796 } 5797 } 5798 5799 static byte[] readFully(FileInputStream stream) throws java.io.IOException { 5800 int pos = 0; 5801 int avail = stream.available(); 5802 byte[] data = new byte[avail]; 5803 while (true) { 5804 int amt = stream.read(data, pos, data.length-pos); 5805 //Log.i("foo", "Read " + amt + " bytes at " + pos 5806 // + " of avail " + data.length); 5807 if (amt <= 0) { 5808 //Log.i("foo", "**** FINISHED READING: pos=" + pos 5809 // + " len=" + data.length); 5810 return data; 5811 } 5812 pos += amt; 5813 avail = stream.available(); 5814 if (avail > data.length-pos) { 5815 byte[] newData = new byte[pos+avail]; 5816 System.arraycopy(data, 0, newData, 0, pos); 5817 data = newData; 5818 } 5819 } 5820 } 5821 5822 public void readLocked() { 5823 if (mFile == null) { 5824 Slog.w("BatteryStats", "readLocked: no file associated with this instance"); 5825 return; 5826 } 5827 5828 mUidStats.clear(); 5829 5830 try { 5831 File file = mFile.chooseForRead(); 5832 if (!file.exists()) { 5833 return; 5834 } 5835 FileInputStream stream = new FileInputStream(file); 5836 5837 byte[] raw = readFully(stream); 5838 Parcel in = Parcel.obtain(); 5839 in.unmarshall(raw, 0, raw.length); 5840 in.setDataPosition(0); 5841 stream.close(); 5842 5843 readSummaryFromParcel(in); 5844 } catch(java.io.IOException e) { 5845 Slog.e("BatteryStats", "Error reading battery statistics", e); 5846 } 5847 5848 long now = SystemClock.elapsedRealtime(); 5849 if (USE_OLD_HISTORY) { 5850 addHistoryRecordLocked(now, HistoryItem.CMD_START); 5851 } 5852 addHistoryBufferLocked(now, HistoryItem.CMD_START); 5853 } 5854 5855 public int describeContents() { 5856 return 0; 5857 } 5858 5859 void readHistory(Parcel in, boolean andOldHistory) { 5860 final long historyBaseTime = in.readLong(); 5861 5862 mHistoryBuffer.setDataSize(0); 5863 mHistoryBuffer.setDataPosition(0); 5864 mHistoryTagPool.clear(); 5865 mNextHistoryTagIdx = 0; 5866 mNumHistoryTagChars = 0; 5867 5868 int numTags = in.readInt(); 5869 for (int i=0; i<numTags; i++) { 5870 int idx = in.readInt(); 5871 String str = in.readString(); 5872 int uid = in.readInt(); 5873 HistoryTag tag = new HistoryTag(); 5874 tag.string = str; 5875 tag.uid = uid; 5876 tag.poolIdx = idx; 5877 mHistoryTagPool.put(tag, idx); 5878 if (idx >= mNextHistoryTagIdx) { 5879 mNextHistoryTagIdx = idx+1; 5880 } 5881 mNumHistoryTagChars += tag.string.length() + 1; 5882 } 5883 5884 int bufSize = in.readInt(); 5885 int curPos = in.dataPosition(); 5886 if (bufSize >= (MAX_MAX_HISTORY_BUFFER*3)) { 5887 Slog.w(TAG, "File corrupt: history data buffer too large " + bufSize); 5888 } else if ((bufSize&~3) != bufSize) { 5889 Slog.w(TAG, "File corrupt: history data buffer not aligned " + bufSize); 5890 } else { 5891 if (DEBUG_HISTORY) Slog.i(TAG, "***************** READING NEW HISTORY: " + bufSize 5892 + " bytes at " + curPos); 5893 mHistoryBuffer.appendFrom(in, curPos, bufSize); 5894 in.setDataPosition(curPos + bufSize); 5895 } 5896 5897 if (andOldHistory) { 5898 readOldHistory(in); 5899 } 5900 5901 if (DEBUG_HISTORY) { 5902 StringBuilder sb = new StringBuilder(128); 5903 sb.append("****************** OLD mHistoryBaseTime: "); 5904 TimeUtils.formatDuration(mHistoryBaseTime, sb); 5905 Slog.i(TAG, sb.toString()); 5906 } 5907 mHistoryBaseTime = historyBaseTime; 5908 if (DEBUG_HISTORY) { 5909 StringBuilder sb = new StringBuilder(128); 5910 sb.append("****************** NEW mHistoryBaseTime: "); 5911 TimeUtils.formatDuration(mHistoryBaseTime, sb); 5912 Slog.i(TAG, sb.toString()); 5913 } 5914 5915 // We are just arbitrarily going to insert 1 minute from the sample of 5916 // the last run until samples in this run. 5917 if (mHistoryBaseTime > 0) { 5918 long oldnow = SystemClock.elapsedRealtime(); 5919 mHistoryBaseTime = (mHistoryBaseTime - oldnow) + 60*1000; 5920 if (DEBUG_HISTORY) { 5921 StringBuilder sb = new StringBuilder(128); 5922 sb.append("****************** ADJUSTED mHistoryBaseTime: "); 5923 TimeUtils.formatDuration(mHistoryBaseTime, sb); 5924 Slog.i(TAG, sb.toString()); 5925 } 5926 } 5927 } 5928 5929 void readOldHistory(Parcel in) { 5930 if (!USE_OLD_HISTORY) { 5931 return; 5932 } 5933 mHistory = mHistoryEnd = mHistoryCache = null; 5934 long time; 5935 while (in.dataAvail() > 0 && (time=in.readLong()) >= 0) { 5936 HistoryItem rec = new HistoryItem(time, in); 5937 addHistoryRecordLocked(rec); 5938 } 5939 } 5940 5941 void writeHistory(Parcel out, boolean andOldHistory) { 5942 if (DEBUG_HISTORY) { 5943 StringBuilder sb = new StringBuilder(128); 5944 sb.append("****************** WRITING mHistoryBaseTime: "); 5945 TimeUtils.formatDuration(mHistoryBaseTime, sb); 5946 sb.append(" mLastHistoryTime: "); 5947 TimeUtils.formatDuration(mLastHistoryTime, sb); 5948 Slog.i(TAG, sb.toString()); 5949 } 5950 out.writeLong(mHistoryBaseTime + mLastHistoryTime); 5951 out.writeInt(mHistoryTagPool.size()); 5952 for (HashMap.Entry<HistoryTag, Integer> ent : mHistoryTagPool.entrySet()) { 5953 HistoryTag tag = ent.getKey(); 5954 out.writeInt(ent.getValue()); 5955 out.writeString(tag.string); 5956 out.writeInt(tag.uid); 5957 } 5958 out.writeInt(mHistoryBuffer.dataSize()); 5959 if (DEBUG_HISTORY) Slog.i(TAG, "***************** WRITING HISTORY: " 5960 + mHistoryBuffer.dataSize() + " bytes at " + out.dataPosition()); 5961 out.appendFrom(mHistoryBuffer, 0, mHistoryBuffer.dataSize()); 5962 5963 if (andOldHistory) { 5964 writeOldHistory(out); 5965 } 5966 } 5967 5968 void writeOldHistory(Parcel out) { 5969 if (!USE_OLD_HISTORY) { 5970 return; 5971 } 5972 HistoryItem rec = mHistory; 5973 while (rec != null) { 5974 if (rec.time >= 0) rec.writeToParcel(out, 0); 5975 rec = rec.next; 5976 } 5977 out.writeLong(-1); 5978 } 5979 5980 private void readSummaryFromParcel(Parcel in) { 5981 final int version = in.readInt(); 5982 if (version != VERSION) { 5983 Slog.w("BatteryStats", "readFromParcel: version got " + version 5984 + ", expected " + VERSION + "; erasing old stats"); 5985 return; 5986 } 5987 5988 readHistory(in, true); 5989 5990 mStartCount = in.readInt(); 5991 mBatteryUptime = in.readLong(); 5992 mBatteryRealtime = in.readLong(); 5993 mUptime = in.readLong(); 5994 mRealtime = in.readLong(); 5995 mStartClockTime = in.readLong(); 5996 mDischargeUnplugLevel = in.readInt(); 5997 mDischargeCurrentLevel = in.readInt(); 5998 mLowDischargeAmountSinceCharge = in.readInt(); 5999 mHighDischargeAmountSinceCharge = in.readInt(); 6000 mDischargeAmountScreenOnSinceCharge = in.readInt(); 6001 mDischargeAmountScreenOffSinceCharge = in.readInt(); 6002 6003 mStartCount++; 6004 6005 mScreenOn = false; 6006 mScreenOnTimer.readSummaryFromParcelLocked(in); 6007 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 6008 mScreenBrightnessTimer[i].readSummaryFromParcelLocked(in); 6009 } 6010 mInputEventCounter.readSummaryFromParcelLocked(in); 6011 mPhoneOn = false; 6012 mPhoneOnTimer.readSummaryFromParcelLocked(in); 6013 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) { 6014 mPhoneSignalStrengthsTimer[i].readSummaryFromParcelLocked(in); 6015 } 6016 mPhoneSignalScanningTimer.readSummaryFromParcelLocked(in); 6017 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 6018 mPhoneDataConnectionsTimer[i].readSummaryFromParcelLocked(in); 6019 } 6020 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 6021 mNetworkByteActivityCounters[i].readSummaryFromParcelLocked(in); 6022 mNetworkPacketActivityCounters[i].readSummaryFromParcelLocked(in); 6023 } 6024 mWifiOn = false; 6025 mWifiOnTimer.readSummaryFromParcelLocked(in); 6026 mGlobalWifiRunning = false; 6027 mGlobalWifiRunningTimer.readSummaryFromParcelLocked(in); 6028 mBluetoothOn = false; 6029 mBluetoothOnTimer.readSummaryFromParcelLocked(in); 6030 6031 int NKW = in.readInt(); 6032 if (NKW > 10000) { 6033 Slog.w(TAG, "File corrupt: too many kernel wake locks " + NKW); 6034 return; 6035 } 6036 for (int ikw = 0; ikw < NKW; ikw++) { 6037 if (in.readInt() != 0) { 6038 String kwltName = in.readString(); 6039 getKernelWakelockTimerLocked(kwltName).readSummaryFromParcelLocked(in); 6040 } 6041 } 6042 6043 sNumSpeedSteps = in.readInt(); 6044 6045 final int NU = in.readInt(); 6046 if (NU > 10000) { 6047 Slog.w(TAG, "File corrupt: too many uids " + NU); 6048 return; 6049 } 6050 for (int iu = 0; iu < NU; iu++) { 6051 int uid = in.readInt(); 6052 Uid u = new Uid(uid); 6053 mUidStats.put(uid, u); 6054 6055 u.mWifiRunning = false; 6056 if (in.readInt() != 0) { 6057 u.mWifiRunningTimer.readSummaryFromParcelLocked(in); 6058 } 6059 u.mFullWifiLockOut = false; 6060 if (in.readInt() != 0) { 6061 u.mFullWifiLockTimer.readSummaryFromParcelLocked(in); 6062 } 6063 u.mWifiScanStarted = false; 6064 if (in.readInt() != 0) { 6065 u.mWifiScanTimer.readSummaryFromParcelLocked(in); 6066 } 6067 u.mWifiBatchedScanBinStarted = Uid.NO_BATCHED_SCAN_STARTED; 6068 for (int i = 0; i < Uid.NUM_WIFI_BATCHED_SCAN_BINS; i++) { 6069 if (in.readInt() != 0) { 6070 u.makeWifiBatchedScanBin(i, null); 6071 u.mWifiBatchedScanTimer[i].readSummaryFromParcelLocked(in); 6072 } 6073 } 6074 u.mWifiMulticastEnabled = false; 6075 if (in.readInt() != 0) { 6076 u.mWifiMulticastTimer.readSummaryFromParcelLocked(in); 6077 } 6078 u.mAudioTurnedOn = false; 6079 if (in.readInt() != 0) { 6080 u.createAudioTurnedOnTimerLocked().readSummaryFromParcelLocked(in); 6081 } 6082 u.mVideoTurnedOn = false; 6083 if (in.readInt() != 0) { 6084 u.createVideoTurnedOnTimerLocked().readSummaryFromParcelLocked(in); 6085 } 6086 if (in.readInt() != 0) { 6087 u.createForegroundActivityTimerLocked().readSummaryFromParcelLocked(in); 6088 } 6089 if (in.readInt() != 0) { 6090 u.createVibratorOnTimerLocked().readSummaryFromParcelLocked(in); 6091 } 6092 6093 if (in.readInt() != 0) { 6094 if (u.mUserActivityCounters == null) { 6095 u.initUserActivityLocked(); 6096 } 6097 for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) { 6098 u.mUserActivityCounters[i].readSummaryFromParcelLocked(in); 6099 } 6100 } 6101 6102 if (in.readInt() != 0) { 6103 if (u.mNetworkByteActivityCounters == null) { 6104 u.initNetworkActivityLocked(); 6105 } 6106 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 6107 u.mNetworkByteActivityCounters[i].readSummaryFromParcelLocked(in); 6108 u.mNetworkPacketActivityCounters[i].readSummaryFromParcelLocked(in); 6109 } 6110 } 6111 6112 int NW = in.readInt(); 6113 if (NW > 100) { 6114 Slog.w(TAG, "File corrupt: too many wake locks " + NW); 6115 return; 6116 } 6117 for (int iw = 0; iw < NW; iw++) { 6118 String wlName = in.readString(); 6119 if (in.readInt() != 0) { 6120 u.getWakeTimerLocked(wlName, WAKE_TYPE_FULL).readSummaryFromParcelLocked(in); 6121 } 6122 if (in.readInt() != 0) { 6123 u.getWakeTimerLocked(wlName, WAKE_TYPE_PARTIAL).readSummaryFromParcelLocked(in); 6124 } 6125 if (in.readInt() != 0) { 6126 u.getWakeTimerLocked(wlName, WAKE_TYPE_WINDOW).readSummaryFromParcelLocked(in); 6127 } 6128 } 6129 6130 int NP = in.readInt(); 6131 if (NP > 1000) { 6132 Slog.w(TAG, "File corrupt: too many sensors " + NP); 6133 return; 6134 } 6135 for (int is = 0; is < NP; is++) { 6136 int seNumber = in.readInt(); 6137 if (in.readInt() != 0) { 6138 u.getSensorTimerLocked(seNumber, true) 6139 .readSummaryFromParcelLocked(in); 6140 } 6141 } 6142 6143 NP = in.readInt(); 6144 if (NP > 1000) { 6145 Slog.w(TAG, "File corrupt: too many processes " + NP); 6146 return; 6147 } 6148 for (int ip = 0; ip < NP; ip++) { 6149 String procName = in.readString(); 6150 Uid.Proc p = u.getProcessStatsLocked(procName); 6151 p.mUserTime = p.mLoadedUserTime = in.readLong(); 6152 p.mSystemTime = p.mLoadedSystemTime = in.readLong(); 6153 p.mForegroundTime = p.mLoadedForegroundTime = in.readLong(); 6154 p.mStarts = p.mLoadedStarts = in.readInt(); 6155 int NSB = in.readInt(); 6156 if (NSB > 100) { 6157 Slog.w(TAG, "File corrupt: too many speed bins " + NSB); 6158 return; 6159 } 6160 p.mSpeedBins = new SamplingCounter[NSB]; 6161 for (int i=0; i<NSB; i++) { 6162 if (in.readInt() != 0) { 6163 p.mSpeedBins[i] = new SamplingCounter(mUnpluggables); 6164 p.mSpeedBins[i].readSummaryFromParcelLocked(in); 6165 } 6166 } 6167 if (!p.readExcessivePowerFromParcelLocked(in)) { 6168 return; 6169 } 6170 } 6171 6172 NP = in.readInt(); 6173 if (NP > 10000) { 6174 Slog.w(TAG, "File corrupt: too many packages " + NP); 6175 return; 6176 } 6177 for (int ip = 0; ip < NP; ip++) { 6178 String pkgName = in.readString(); 6179 Uid.Pkg p = u.getPackageStatsLocked(pkgName); 6180 p.mWakeups = p.mLoadedWakeups = in.readInt(); 6181 final int NS = in.readInt(); 6182 if (NS > 1000) { 6183 Slog.w(TAG, "File corrupt: too many services " + NS); 6184 return; 6185 } 6186 for (int is = 0; is < NS; is++) { 6187 String servName = in.readString(); 6188 Uid.Pkg.Serv s = u.getServiceStatsLocked(pkgName, servName); 6189 s.mStartTime = s.mLoadedStartTime = in.readLong(); 6190 s.mStarts = s.mLoadedStarts = in.readInt(); 6191 s.mLaunches = s.mLoadedLaunches = in.readInt(); 6192 } 6193 } 6194 } 6195 } 6196 6197 /** 6198 * Writes a summary of the statistics to a Parcel, in a format suitable to be written to 6199 * disk. This format does not allow a lossless round-trip. 6200 * 6201 * @param out the Parcel to be written to. 6202 */ 6203 public void writeSummaryToParcel(Parcel out) { 6204 pullPendingStateUpdatesLocked(); 6205 6206 final long NOW_SYS = SystemClock.uptimeMillis() * 1000; 6207 final long NOWREAL_SYS = SystemClock.elapsedRealtime() * 1000; 6208 final long NOW = getBatteryUptimeLocked(NOW_SYS); 6209 final long NOWREAL = getBatteryRealtimeLocked(NOWREAL_SYS); 6210 6211 out.writeInt(VERSION); 6212 6213 writeHistory(out, true); 6214 6215 out.writeInt(mStartCount); 6216 out.writeLong(computeBatteryUptime(NOW_SYS, STATS_SINCE_CHARGED)); 6217 out.writeLong(computeBatteryRealtime(NOWREAL_SYS, STATS_SINCE_CHARGED)); 6218 out.writeLong(computeUptime(NOW_SYS, STATS_SINCE_CHARGED)); 6219 out.writeLong(computeRealtime(NOWREAL_SYS, STATS_SINCE_CHARGED)); 6220 out.writeLong(mStartClockTime); 6221 out.writeInt(mDischargeUnplugLevel); 6222 out.writeInt(mDischargeCurrentLevel); 6223 out.writeInt(getLowDischargeAmountSinceCharge()); 6224 out.writeInt(getHighDischargeAmountSinceCharge()); 6225 out.writeInt(getDischargeAmountScreenOnSinceCharge()); 6226 out.writeInt(getDischargeAmountScreenOffSinceCharge()); 6227 6228 mScreenOnTimer.writeSummaryFromParcelLocked(out, NOWREAL); 6229 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 6230 mScreenBrightnessTimer[i].writeSummaryFromParcelLocked(out, NOWREAL); 6231 } 6232 mInputEventCounter.writeSummaryFromParcelLocked(out); 6233 mPhoneOnTimer.writeSummaryFromParcelLocked(out, NOWREAL); 6234 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) { 6235 mPhoneSignalStrengthsTimer[i].writeSummaryFromParcelLocked(out, NOWREAL); 6236 } 6237 mPhoneSignalScanningTimer.writeSummaryFromParcelLocked(out, NOWREAL); 6238 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 6239 mPhoneDataConnectionsTimer[i].writeSummaryFromParcelLocked(out, NOWREAL); 6240 } 6241 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 6242 mNetworkByteActivityCounters[i].writeSummaryFromParcelLocked(out); 6243 mNetworkPacketActivityCounters[i].writeSummaryFromParcelLocked(out); 6244 } 6245 mWifiOnTimer.writeSummaryFromParcelLocked(out, NOWREAL); 6246 mGlobalWifiRunningTimer.writeSummaryFromParcelLocked(out, NOWREAL); 6247 mBluetoothOnTimer.writeSummaryFromParcelLocked(out, NOWREAL); 6248 6249 out.writeInt(mKernelWakelockStats.size()); 6250 for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) { 6251 Timer kwlt = ent.getValue(); 6252 if (kwlt != null) { 6253 out.writeInt(1); 6254 out.writeString(ent.getKey()); 6255 ent.getValue().writeSummaryFromParcelLocked(out, NOWREAL); 6256 } else { 6257 out.writeInt(0); 6258 } 6259 } 6260 6261 out.writeInt(sNumSpeedSteps); 6262 final int NU = mUidStats.size(); 6263 out.writeInt(NU); 6264 for (int iu = 0; iu < NU; iu++) { 6265 out.writeInt(mUidStats.keyAt(iu)); 6266 Uid u = mUidStats.valueAt(iu); 6267 6268 if (u.mWifiRunningTimer != null) { 6269 out.writeInt(1); 6270 u.mWifiRunningTimer.writeSummaryFromParcelLocked(out, NOWREAL); 6271 } else { 6272 out.writeInt(0); 6273 } 6274 if (u.mFullWifiLockTimer != null) { 6275 out.writeInt(1); 6276 u.mFullWifiLockTimer.writeSummaryFromParcelLocked(out, NOWREAL); 6277 } else { 6278 out.writeInt(0); 6279 } 6280 if (u.mWifiScanTimer != null) { 6281 out.writeInt(1); 6282 u.mWifiScanTimer.writeSummaryFromParcelLocked(out, NOWREAL); 6283 } else { 6284 out.writeInt(0); 6285 } 6286 for (int i = 0; i < Uid.NUM_WIFI_BATCHED_SCAN_BINS; i++) { 6287 if (u.mWifiBatchedScanTimer[i] != null) { 6288 out.writeInt(1); 6289 u.mWifiBatchedScanTimer[i].writeSummaryFromParcelLocked(out, NOWREAL); 6290 } else { 6291 out.writeInt(0); 6292 } 6293 } 6294 if (u.mWifiMulticastTimer != null) { 6295 out.writeInt(1); 6296 u.mWifiMulticastTimer.writeSummaryFromParcelLocked(out, NOWREAL); 6297 } else { 6298 out.writeInt(0); 6299 } 6300 if (u.mAudioTurnedOnTimer != null) { 6301 out.writeInt(1); 6302 u.mAudioTurnedOnTimer.writeSummaryFromParcelLocked(out, NOWREAL); 6303 } else { 6304 out.writeInt(0); 6305 } 6306 if (u.mVideoTurnedOnTimer != null) { 6307 out.writeInt(1); 6308 u.mVideoTurnedOnTimer.writeSummaryFromParcelLocked(out, NOWREAL); 6309 } else { 6310 out.writeInt(0); 6311 } 6312 if (u.mForegroundActivityTimer != null) { 6313 out.writeInt(1); 6314 u.mForegroundActivityTimer.writeSummaryFromParcelLocked(out, NOWREAL); 6315 } else { 6316 out.writeInt(0); 6317 } 6318 if (u.mVibratorOnTimer != null) { 6319 out.writeInt(1); 6320 u.mVibratorOnTimer.writeSummaryFromParcelLocked(out, NOWREAL); 6321 } else { 6322 out.writeInt(0); 6323 } 6324 6325 if (u.mUserActivityCounters == null) { 6326 out.writeInt(0); 6327 } else { 6328 out.writeInt(1); 6329 for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) { 6330 u.mUserActivityCounters[i].writeSummaryFromParcelLocked(out); 6331 } 6332 } 6333 6334 if (u.mNetworkByteActivityCounters == null) { 6335 out.writeInt(0); 6336 } else { 6337 out.writeInt(1); 6338 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 6339 u.mNetworkByteActivityCounters[i].writeSummaryFromParcelLocked(out); 6340 u.mNetworkPacketActivityCounters[i].writeSummaryFromParcelLocked(out); 6341 } 6342 } 6343 6344 int NW = u.mWakelockStats.size(); 6345 out.writeInt(NW); 6346 if (NW > 0) { 6347 for (Map.Entry<String, BatteryStatsImpl.Uid.Wakelock> ent 6348 : u.mWakelockStats.entrySet()) { 6349 out.writeString(ent.getKey()); 6350 Uid.Wakelock wl = ent.getValue(); 6351 if (wl.mTimerFull != null) { 6352 out.writeInt(1); 6353 wl.mTimerFull.writeSummaryFromParcelLocked(out, NOWREAL); 6354 } else { 6355 out.writeInt(0); 6356 } 6357 if (wl.mTimerPartial != null) { 6358 out.writeInt(1); 6359 wl.mTimerPartial.writeSummaryFromParcelLocked(out, NOWREAL); 6360 } else { 6361 out.writeInt(0); 6362 } 6363 if (wl.mTimerWindow != null) { 6364 out.writeInt(1); 6365 wl.mTimerWindow.writeSummaryFromParcelLocked(out, NOWREAL); 6366 } else { 6367 out.writeInt(0); 6368 } 6369 } 6370 } 6371 6372 int NSE = u.mSensorStats.size(); 6373 out.writeInt(NSE); 6374 if (NSE > 0) { 6375 for (Map.Entry<Integer, BatteryStatsImpl.Uid.Sensor> ent 6376 : u.mSensorStats.entrySet()) { 6377 out.writeInt(ent.getKey()); 6378 Uid.Sensor se = ent.getValue(); 6379 if (se.mTimer != null) { 6380 out.writeInt(1); 6381 se.mTimer.writeSummaryFromParcelLocked(out, NOWREAL); 6382 } else { 6383 out.writeInt(0); 6384 } 6385 } 6386 } 6387 6388 int NP = u.mProcessStats.size(); 6389 out.writeInt(NP); 6390 if (NP > 0) { 6391 for (Map.Entry<String, BatteryStatsImpl.Uid.Proc> ent 6392 : u.mProcessStats.entrySet()) { 6393 out.writeString(ent.getKey()); 6394 Uid.Proc ps = ent.getValue(); 6395 out.writeLong(ps.mUserTime); 6396 out.writeLong(ps.mSystemTime); 6397 out.writeLong(ps.mForegroundTime); 6398 out.writeInt(ps.mStarts); 6399 final int N = ps.mSpeedBins.length; 6400 out.writeInt(N); 6401 for (int i=0; i<N; i++) { 6402 if (ps.mSpeedBins[i] != null) { 6403 out.writeInt(1); 6404 ps.mSpeedBins[i].writeSummaryFromParcelLocked(out); 6405 } else { 6406 out.writeInt(0); 6407 } 6408 } 6409 ps.writeExcessivePowerToParcelLocked(out); 6410 } 6411 } 6412 6413 NP = u.mPackageStats.size(); 6414 out.writeInt(NP); 6415 if (NP > 0) { 6416 for (Map.Entry<String, BatteryStatsImpl.Uid.Pkg> ent 6417 : u.mPackageStats.entrySet()) { 6418 out.writeString(ent.getKey()); 6419 Uid.Pkg ps = ent.getValue(); 6420 out.writeInt(ps.mWakeups); 6421 final int NS = ps.mServiceStats.size(); 6422 out.writeInt(NS); 6423 if (NS > 0) { 6424 for (Map.Entry<String, BatteryStatsImpl.Uid.Pkg.Serv> sent 6425 : ps.mServiceStats.entrySet()) { 6426 out.writeString(sent.getKey()); 6427 BatteryStatsImpl.Uid.Pkg.Serv ss = sent.getValue(); 6428 long time = ss.getStartTimeToNowLocked(NOW); 6429 out.writeLong(time); 6430 out.writeInt(ss.mStarts); 6431 out.writeInt(ss.mLaunches); 6432 } 6433 } 6434 } 6435 } 6436 } 6437 } 6438 6439 public void readFromParcel(Parcel in) { 6440 readFromParcelLocked(in); 6441 } 6442 6443 void readFromParcelLocked(Parcel in) { 6444 int magic = in.readInt(); 6445 if (magic != MAGIC) { 6446 throw new ParcelFormatException("Bad magic number"); 6447 } 6448 6449 readHistory(in, false); 6450 6451 mStartCount = in.readInt(); 6452 mBatteryUptime = in.readLong(); 6453 mBatteryLastUptime = 0; 6454 mBatteryRealtime = in.readLong(); 6455 mBatteryLastRealtime = 0; 6456 mStartClockTime = in.readLong(); 6457 mScreenOn = false; 6458 mScreenOnTimer = new StopwatchTimer(null, -1, null, mUnpluggables, in); 6459 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 6460 mScreenBrightnessTimer[i] = new StopwatchTimer(null, -100-i, 6461 null, mUnpluggables, in); 6462 } 6463 mInputEventCounter = new Counter(mUnpluggables, in); 6464 mPhoneOn = false; 6465 mPhoneOnTimer = new StopwatchTimer(null, -2, null, mUnpluggables, in); 6466 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) { 6467 mPhoneSignalStrengthsTimer[i] = new StopwatchTimer(null, -200-i, 6468 null, mUnpluggables, in); 6469 } 6470 mPhoneSignalScanningTimer = new StopwatchTimer(null, -200+1, null, mUnpluggables, in); 6471 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 6472 mPhoneDataConnectionsTimer[i] = new StopwatchTimer(null, -300-i, 6473 null, mUnpluggables, in); 6474 } 6475 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 6476 mNetworkByteActivityCounters[i] = new LongSamplingCounter(mUnpluggables, in); 6477 mNetworkPacketActivityCounters[i] = new LongSamplingCounter(mUnpluggables, in); 6478 } 6479 mWifiOn = false; 6480 mWifiOnTimer = new StopwatchTimer(null, -2, null, mUnpluggables, in); 6481 mGlobalWifiRunning = false; 6482 mGlobalWifiRunningTimer = new StopwatchTimer(null, -2, null, mUnpluggables, in); 6483 mBluetoothOn = false; 6484 mBluetoothOnTimer = new StopwatchTimer(null, -2, null, mUnpluggables, in); 6485 mUptime = in.readLong(); 6486 mUptimeStart = in.readLong(); 6487 mLastUptime = 0; 6488 mRealtime = in.readLong(); 6489 mRealtimeStart = in.readLong(); 6490 mLastRealtime = 0; 6491 mOnBattery = in.readInt() != 0; 6492 mOnBatteryInternal = false; // we are no longer really running. 6493 mTrackBatteryPastUptime = in.readLong(); 6494 mTrackBatteryUptimeStart = in.readLong(); 6495 mTrackBatteryPastRealtime = in.readLong(); 6496 mTrackBatteryRealtimeStart = in.readLong(); 6497 mUnpluggedBatteryUptime = in.readLong(); 6498 mUnpluggedBatteryRealtime = in.readLong(); 6499 mDischargeUnplugLevel = in.readInt(); 6500 mDischargeCurrentLevel = in.readInt(); 6501 mLowDischargeAmountSinceCharge = in.readInt(); 6502 mHighDischargeAmountSinceCharge = in.readInt(); 6503 mDischargeAmountScreenOn = in.readInt(); 6504 mDischargeAmountScreenOnSinceCharge = in.readInt(); 6505 mDischargeAmountScreenOff = in.readInt(); 6506 mDischargeAmountScreenOffSinceCharge = in.readInt(); 6507 mLastWriteTime = in.readLong(); 6508 6509 mRadioDataUptime = in.readLong(); 6510 mRadioDataStart = -1; 6511 6512 mBluetoothPingCount = in.readInt(); 6513 mBluetoothPingStart = -1; 6514 6515 mKernelWakelockStats.clear(); 6516 int NKW = in.readInt(); 6517 for (int ikw = 0; ikw < NKW; ikw++) { 6518 if (in.readInt() != 0) { 6519 String wakelockName = in.readString(); 6520 in.readInt(); // Extra 0/1 written by Timer.writeTimerToParcel 6521 SamplingTimer kwlt = new SamplingTimer(mUnpluggables, mOnBattery, in); 6522 mKernelWakelockStats.put(wakelockName, kwlt); 6523 } 6524 } 6525 6526 mPartialTimers.clear(); 6527 mFullTimers.clear(); 6528 mWindowTimers.clear(); 6529 mWifiRunningTimers.clear(); 6530 mFullWifiLockTimers.clear(); 6531 mWifiScanTimers.clear(); 6532 mWifiBatchedScanTimers.clear(); 6533 mWifiMulticastTimers.clear(); 6534 6535 sNumSpeedSteps = in.readInt(); 6536 6537 int numUids = in.readInt(); 6538 mUidStats.clear(); 6539 for (int i = 0; i < numUids; i++) { 6540 int uid = in.readInt(); 6541 Uid u = new Uid(uid); 6542 u.readFromParcelLocked(mUnpluggables, in); 6543 mUidStats.append(uid, u); 6544 } 6545 } 6546 6547 public void writeToParcel(Parcel out, int flags) { 6548 writeToParcelLocked(out, true, flags); 6549 } 6550 6551 public void writeToParcelWithoutUids(Parcel out, int flags) { 6552 writeToParcelLocked(out, false, flags); 6553 } 6554 6555 @SuppressWarnings("unused") 6556 void writeToParcelLocked(Parcel out, boolean inclUids, int flags) { 6557 // Need to update with current kernel wake lock counts. 6558 pullPendingStateUpdatesLocked(); 6559 6560 final long uSecUptime = SystemClock.uptimeMillis() * 1000; 6561 final long uSecRealtime = SystemClock.elapsedRealtime() * 1000; 6562 final long batteryUptime = getBatteryUptimeLocked(uSecUptime); 6563 final long batteryRealtime = getBatteryRealtimeLocked(uSecRealtime); 6564 6565 out.writeInt(MAGIC); 6566 6567 writeHistory(out, false); 6568 6569 out.writeInt(mStartCount); 6570 out.writeLong(mBatteryUptime); 6571 out.writeLong(mBatteryRealtime); 6572 out.writeLong(mStartClockTime); 6573 mScreenOnTimer.writeToParcel(out, batteryRealtime); 6574 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 6575 mScreenBrightnessTimer[i].writeToParcel(out, batteryRealtime); 6576 } 6577 mInputEventCounter.writeToParcel(out); 6578 mPhoneOnTimer.writeToParcel(out, batteryRealtime); 6579 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) { 6580 mPhoneSignalStrengthsTimer[i].writeToParcel(out, batteryRealtime); 6581 } 6582 mPhoneSignalScanningTimer.writeToParcel(out, batteryRealtime); 6583 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 6584 mPhoneDataConnectionsTimer[i].writeToParcel(out, batteryRealtime); 6585 } 6586 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { 6587 mNetworkByteActivityCounters[i].writeToParcel(out); 6588 mNetworkPacketActivityCounters[i].writeToParcel(out); 6589 } 6590 mWifiOnTimer.writeToParcel(out, batteryRealtime); 6591 mGlobalWifiRunningTimer.writeToParcel(out, batteryRealtime); 6592 mBluetoothOnTimer.writeToParcel(out, batteryRealtime); 6593 out.writeLong(mUptime); 6594 out.writeLong(mUptimeStart); 6595 out.writeLong(mRealtime); 6596 out.writeLong(mRealtimeStart); 6597 out.writeInt(mOnBattery ? 1 : 0); 6598 out.writeLong(batteryUptime); 6599 out.writeLong(mTrackBatteryUptimeStart); 6600 out.writeLong(batteryRealtime); 6601 out.writeLong(mTrackBatteryRealtimeStart); 6602 out.writeLong(mUnpluggedBatteryUptime); 6603 out.writeLong(mUnpluggedBatteryRealtime); 6604 out.writeInt(mDischargeUnplugLevel); 6605 out.writeInt(mDischargeCurrentLevel); 6606 out.writeInt(mLowDischargeAmountSinceCharge); 6607 out.writeInt(mHighDischargeAmountSinceCharge); 6608 out.writeInt(mDischargeAmountScreenOn); 6609 out.writeInt(mDischargeAmountScreenOnSinceCharge); 6610 out.writeInt(mDischargeAmountScreenOff); 6611 out.writeInt(mDischargeAmountScreenOffSinceCharge); 6612 out.writeLong(mLastWriteTime); 6613 6614 // Write radio uptime for data 6615 out.writeLong(getRadioDataUptime()); 6616 6617 out.writeInt(getBluetoothPingCount()); 6618 6619 if (inclUids) { 6620 out.writeInt(mKernelWakelockStats.size()); 6621 for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) { 6622 SamplingTimer kwlt = ent.getValue(); 6623 if (kwlt != null) { 6624 out.writeInt(1); 6625 out.writeString(ent.getKey()); 6626 Timer.writeTimerToParcel(out, kwlt, batteryRealtime); 6627 } else { 6628 out.writeInt(0); 6629 } 6630 } 6631 } else { 6632 out.writeInt(0); 6633 } 6634 6635 out.writeInt(sNumSpeedSteps); 6636 6637 if (inclUids) { 6638 int size = mUidStats.size(); 6639 out.writeInt(size); 6640 for (int i = 0; i < size; i++) { 6641 out.writeInt(mUidStats.keyAt(i)); 6642 Uid uid = mUidStats.valueAt(i); 6643 6644 uid.writeToParcelLocked(out, batteryRealtime); 6645 } 6646 } else { 6647 out.writeInt(0); 6648 } 6649 } 6650 6651 public static final Parcelable.Creator<BatteryStatsImpl> CREATOR = 6652 new Parcelable.Creator<BatteryStatsImpl>() { 6653 public BatteryStatsImpl createFromParcel(Parcel in) { 6654 return new BatteryStatsImpl(in); 6655 } 6656 6657 public BatteryStatsImpl[] newArray(int size) { 6658 return new BatteryStatsImpl[size]; 6659 } 6660 }; 6661 6662 public void prepareForDumpLocked() { 6663 // Need to retrieve current kernel wake lock stats before printing. 6664 pullPendingStateUpdatesLocked(); 6665 } 6666 6667 public void dumpLocked(Context context, PrintWriter pw, boolean isUnpluggedOnly, int reqUid, 6668 boolean historyOnly) { 6669 if (DEBUG) { 6670 Printer pr = new PrintWriterPrinter(pw); 6671 pr.println("*** Screen timer:"); 6672 mScreenOnTimer.logState(pr, " "); 6673 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { 6674 pr.println("*** Screen brightness #" + i + ":"); 6675 mScreenBrightnessTimer[i].logState(pr, " "); 6676 } 6677 pr.println("*** Input event counter:"); 6678 mInputEventCounter.logState(pr, " "); 6679 pr.println("*** Phone timer:"); 6680 mPhoneOnTimer.logState(pr, " "); 6681 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) { 6682 pr.println("*** Signal strength #" + i + ":"); 6683 mPhoneSignalStrengthsTimer[i].logState(pr, " "); 6684 } 6685 pr.println("*** Signal scanning :"); 6686 mPhoneSignalScanningTimer.logState(pr, " "); 6687 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { 6688 pr.println("*** Data connection type #" + i + ":"); 6689 mPhoneDataConnectionsTimer[i].logState(pr, " "); 6690 } 6691 pr.println("*** Wifi timer:"); 6692 mWifiOnTimer.logState(pr, " "); 6693 pr.println("*** WifiRunning timer:"); 6694 mGlobalWifiRunningTimer.logState(pr, " "); 6695 pr.println("*** Bluetooth timer:"); 6696 mBluetoothOnTimer.logState(pr, " "); 6697 } 6698 super.dumpLocked(context, pw, isUnpluggedOnly, reqUid, historyOnly); 6699 } 6700} 6701