diff options
4 files changed, 271 insertions, 54 deletions
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java index a857e582beaf..32fb108c593c 100644 --- a/core/java/android/os/BatteryStats.java +++ b/core/java/android/os/BatteryStats.java @@ -1586,8 +1586,10 @@ public abstract class BatteryStats implements Parcelable { sb.append(prefix); sb.append(" CPU: "); formatTime(sb, userTime); sb.append("usr + "); formatTime(sb, systemTime); sb.append("krn\n"); - sb.append(prefix); sb.append(" "); sb.append(starts); - sb.append(" proc starts"); + if (starts != 0) { + sb.append(prefix); sb.append(" "); sb.append(starts); + sb.append(" proc starts"); + } pw.println(sb.toString()); for (int e=0; e<numExcessive; e++) { Uid.Proc.ExcessiveWake ew = ps.getExcessiveWake(e); diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java index 566ed29d15c7..b73b78ba8960 100644 --- a/core/java/com/android/internal/os/BatteryStatsImpl.java +++ b/core/java/com/android/internal/os/BatteryStatsImpl.java @@ -22,6 +22,8 @@ import android.bluetooth.BluetoothHeadset; import android.net.TrafficStats; import android.os.BatteryManager; import android.os.BatteryStats; +import android.os.Handler; +import android.os.Message; import android.os.Parcel; import android.os.ParcelFormatException; import android.os.Parcelable; @@ -79,6 +81,38 @@ public final class BatteryStatsImpl extends BatteryStats { private final JournaledFile mFile; + static final int MSG_UPDATE_WAKELOCKS = 1; + static final int MSG_REPORT_POWER_CHANGE = 2; + static final long DELAY_UPDATE_WAKELOCKS = 15*1000; + + public interface BatteryCallback { + public void batteryNeedsCpuUpdate(); + public void batteryPowerChanged(boolean onBattery); + } + + final class MyHandler extends Handler { + @Override + public void handleMessage(Message msg) { + BatteryCallback cb = mCallback; + switch (msg.what) { + case MSG_UPDATE_WAKELOCKS: + if (cb != null) { + cb.batteryNeedsCpuUpdate(); + } + break; + case MSG_REPORT_POWER_CHANGE: + if (cb != null) { + cb.batteryPowerChanged(msg.arg1 != 0); + } + break; + } + } + } + + private final MyHandler mHandler; + + private BatteryCallback mCallback; + /** * The statistics we have collected organized by uids. */ @@ -95,6 +129,9 @@ public final class BatteryStatsImpl extends BatteryStats { final SparseArray<ArrayList<StopwatchTimer>> mSensorTimers = new SparseArray<ArrayList<StopwatchTimer>>(); + // Last partial timers we use for distributing CPU usage. + final ArrayList<StopwatchTimer> mLastPartialTimers = new ArrayList<StopwatchTimer>(); + // These are the objects that will want to do something when the device // is unplugged from power. final ArrayList<Unpluggable> mUnpluggables = new ArrayList<Unpluggable>(); @@ -240,6 +277,7 @@ public final class BatteryStatsImpl extends BatteryStats { // For debugging public BatteryStatsImpl() { mFile = null; + mHandler = null; } public static interface Unpluggable { @@ -739,7 +777,9 @@ public final class BatteryStatsImpl extends BatteryStats { * State for keeping track of timing information. */ public static final class StopwatchTimer extends Timer { + final Uid mUid; final ArrayList<StopwatchTimer> mTimerPool; + int mNesting; /** @@ -757,16 +797,24 @@ public final class BatteryStatsImpl extends BatteryStats { long mTimeout; - StopwatchTimer(int type, ArrayList<StopwatchTimer> timerPool, + /** + * For partial wake locks, keep track of whether we are in the list + * to consume CPU cycles. + */ + boolean mInList; + + StopwatchTimer(Uid uid, int type, ArrayList<StopwatchTimer> timerPool, ArrayList<Unpluggable> unpluggables, Parcel in) { super(type, unpluggables, in); + mUid = uid; mTimerPool = timerPool; mUpdateTime = in.readLong(); } - StopwatchTimer(int type, ArrayList<StopwatchTimer> timerPool, + StopwatchTimer(Uid uid, int type, ArrayList<StopwatchTimer> timerPool, ArrayList<Unpluggable> unpluggables) { super(type, unpluggables); + mUid = uid; mTimerPool = timerPool; } @@ -1252,6 +1300,10 @@ public final class BatteryStatsImpl extends BatteryStats { mWakeLockNesting++; } if (uid >= 0) { + if (!mHandler.hasMessages(MSG_UPDATE_WAKELOCKS)) { + Message m = mHandler.obtainMessage(MSG_UPDATE_WAKELOCKS); + mHandler.sendMessageDelayed(m, DELAY_UPDATE_WAKELOCKS); + } getUidStatsLocked(uid).noteStartWakeLocked(pid, name, type); } } @@ -1267,10 +1319,112 @@ public final class BatteryStatsImpl extends BatteryStats { } } if (uid >= 0) { + if (!mHandler.hasMessages(MSG_UPDATE_WAKELOCKS)) { + Message m = mHandler.obtainMessage(MSG_UPDATE_WAKELOCKS); + mHandler.sendMessageDelayed(m, DELAY_UPDATE_WAKELOCKS); + } getUidStatsLocked(uid).noteStopWakeLocked(pid, name, type); } } + public int startAddingCpuLocked() { + mHandler.removeMessages(MSG_UPDATE_WAKELOCKS); + + if (mScreenOn) { + return 0; + } + + final int N = mPartialTimers.size(); + if (N == 0) { + mLastPartialTimers.clear(); + return 0; + } + + // How many timers should consume CPU? Only want to include ones + // that have already been in the list. + for (int i=0; i<N; i++) { + StopwatchTimer st = mPartialTimers.get(i); + if (st.mInList) { + Uid uid = st.mUid; + // We don't include the system UID, because it so often + // holds wake locks at one request or another of an app. + if (uid != null && uid.mUid != Process.SYSTEM_UID) { + return 50; + } + } + } + + return 0; + } + + public void finishAddingCpuLocked(int perc, int utime, int stime, long[] cpuSpeedTimes) { + final int N = mPartialTimers.size(); + if (perc != 0) { + int num = 0; + for (int i=0; i<N; i++) { + StopwatchTimer st = mPartialTimers.get(i); + if (st.mInList) { + Uid uid = st.mUid; + // We don't include the system UID, because it so often + // holds wake locks at one request or another of an app. + if (uid != null && uid.mUid != Process.SYSTEM_UID) { + num++; + } + } + } + if (num != 0) { + for (int i=0; i<N; i++) { + StopwatchTimer st = mPartialTimers.get(i); + if (st.mInList) { + int myUTime = utime/num; + int mySTime = stime/num; + utime -= myUTime; + stime -= mySTime; + num--; + Uid uid = st.mUid; + if (uid != null && uid.mUid != Process.SYSTEM_UID) { + Uid.Proc proc = uid.getProcessStatsLocked("*wakelock*"); + proc.addCpuTimeLocked(myUTime, mySTime); + proc.addSpeedStepTimes(cpuSpeedTimes); + } + } + } + } + + // Just in case, collect any lost CPU time. + if (utime != 0 || stime != 0) { + Uid uid = getUidStatsLocked(Process.SYSTEM_UID); + if (uid != null) { + Uid.Proc proc = uid.getProcessStatsLocked("*lost*"); + proc.addCpuTimeLocked(utime, stime); + proc.addSpeedStepTimes(cpuSpeedTimes); + } + } + } + + final int NL = mLastPartialTimers.size(); + boolean diff = N != NL; + for (int i=0; i<NL && !diff; i++) { + diff |= mPartialTimers.get(i) != mLastPartialTimers.get(i); + } + if (!diff) { + for (int i=0; i<NL; i++) { + mPartialTimers.get(i).mInList = true; + } + return; + } + + for (int i=0; i<NL; i++) { + mLastPartialTimers.get(i).mInList = false; + } + mLastPartialTimers.clear(); + for (int i=0; i<N; i++) { + StopwatchTimer st = mPartialTimers.get(i); + st.mInList = true; + mLastPartialTimers.add(st); + } + } + public void noteProcessDiedLocked(int uid, int pid) { Uid u = mUidStats.get(uid); if (u != null) { @@ -1922,13 +2076,18 @@ public final class BatteryStatsImpl extends BatteryStats { public Uid(int uid) { mUid = uid; - mWifiTurnedOnTimer = new StopwatchTimer(WIFI_TURNED_ON, null, mUnpluggables); - mFullWifiLockTimer = new StopwatchTimer(FULL_WIFI_LOCK, null, mUnpluggables); - mScanWifiLockTimer = new StopwatchTimer(SCAN_WIFI_LOCK, null, mUnpluggables); - mWifiMulticastTimer = new StopwatchTimer(WIFI_MULTICAST_ENABLED, + mWifiTurnedOnTimer = new StopwatchTimer(Uid.this, WIFI_TURNED_ON, + null, mUnpluggables); + mFullWifiLockTimer = new StopwatchTimer(Uid.this, FULL_WIFI_LOCK, + null, mUnpluggables); + mScanWifiLockTimer = new StopwatchTimer(Uid.this, SCAN_WIFI_LOCK, + null, mUnpluggables); + mWifiMulticastTimer = new StopwatchTimer(Uid.this, WIFI_MULTICAST_ENABLED, + null, mUnpluggables); + mAudioTurnedOnTimer = new StopwatchTimer(Uid.this, AUDIO_TURNED_ON, + null, mUnpluggables); + mVideoTurnedOnTimer = new StopwatchTimer(Uid.this, VIDEO_TURNED_ON, null, mUnpluggables); - mAudioTurnedOnTimer = new StopwatchTimer(AUDIO_TURNED_ON, null, mUnpluggables); - mVideoTurnedOnTimer = new StopwatchTimer(VIDEO_TURNED_ON, null, mUnpluggables); } @Override @@ -1996,7 +2155,7 @@ public final class BatteryStatsImpl extends BatteryStats { if (!mWifiTurnedOn) { mWifiTurnedOn = true; if (mWifiTurnedOnTimer == null) { - mWifiTurnedOnTimer = new StopwatchTimer(WIFI_TURNED_ON, + mWifiTurnedOnTimer = new StopwatchTimer(Uid.this, WIFI_TURNED_ON, null, mUnpluggables); } mWifiTurnedOnTimer.startRunningLocked(BatteryStatsImpl.this); @@ -2016,7 +2175,7 @@ public final class BatteryStatsImpl extends BatteryStats { if (!mFullWifiLockOut) { mFullWifiLockOut = true; if (mFullWifiLockTimer == null) { - mFullWifiLockTimer = new StopwatchTimer(FULL_WIFI_LOCK, + mFullWifiLockTimer = new StopwatchTimer(Uid.this, FULL_WIFI_LOCK, null, mUnpluggables); } mFullWifiLockTimer.startRunningLocked(BatteryStatsImpl.this); @@ -2036,7 +2195,7 @@ public final class BatteryStatsImpl extends BatteryStats { if (!mScanWifiLockOut) { mScanWifiLockOut = true; if (mScanWifiLockTimer == null) { - mScanWifiLockTimer = new StopwatchTimer(SCAN_WIFI_LOCK, + mScanWifiLockTimer = new StopwatchTimer(Uid.this, SCAN_WIFI_LOCK, null, mUnpluggables); } mScanWifiLockTimer.startRunningLocked(BatteryStatsImpl.this); @@ -2056,7 +2215,7 @@ public final class BatteryStatsImpl extends BatteryStats { if (!mWifiMulticastEnabled) { mWifiMulticastEnabled = true; if (mWifiMulticastTimer == null) { - mWifiMulticastTimer = new StopwatchTimer(WIFI_MULTICAST_ENABLED, + mWifiMulticastTimer = new StopwatchTimer(Uid.this, WIFI_MULTICAST_ENABLED, null, mUnpluggables); } mWifiMulticastTimer.startRunningLocked(BatteryStatsImpl.this); @@ -2076,7 +2235,7 @@ public final class BatteryStatsImpl extends BatteryStats { if (!mAudioTurnedOn) { mAudioTurnedOn = true; if (mAudioTurnedOnTimer == null) { - mAudioTurnedOnTimer = new StopwatchTimer(AUDIO_TURNED_ON, + mAudioTurnedOnTimer = new StopwatchTimer(Uid.this, AUDIO_TURNED_ON, null, mUnpluggables); } mAudioTurnedOnTimer.startRunningLocked(BatteryStatsImpl.this); @@ -2096,7 +2255,7 @@ public final class BatteryStatsImpl extends BatteryStats { if (!mVideoTurnedOn) { mVideoTurnedOn = true; if (mVideoTurnedOnTimer == null) { - mVideoTurnedOnTimer = new StopwatchTimer(VIDEO_TURNED_ON, + mVideoTurnedOnTimer = new StopwatchTimer(Uid.this, VIDEO_TURNED_ON, null, mUnpluggables); } mVideoTurnedOnTimer.startRunningLocked(BatteryStatsImpl.this); @@ -2456,42 +2615,42 @@ public final class BatteryStatsImpl extends BatteryStats { mTcpBytesSentAtLastUnplug = in.readLong(); mWifiTurnedOn = false; if (in.readInt() != 0) { - mWifiTurnedOnTimer = new StopwatchTimer(WIFI_TURNED_ON, + mWifiTurnedOnTimer = new StopwatchTimer(Uid.this, WIFI_TURNED_ON, null, mUnpluggables, in); } else { mWifiTurnedOnTimer = null; } mFullWifiLockOut = false; if (in.readInt() != 0) { - mFullWifiLockTimer = new StopwatchTimer(FULL_WIFI_LOCK, + mFullWifiLockTimer = new StopwatchTimer(Uid.this, FULL_WIFI_LOCK, null, mUnpluggables, in); } else { mFullWifiLockTimer = null; } mScanWifiLockOut = false; if (in.readInt() != 0) { - mScanWifiLockTimer = new StopwatchTimer(SCAN_WIFI_LOCK, + mScanWifiLockTimer = new StopwatchTimer(Uid.this, SCAN_WIFI_LOCK, null, mUnpluggables, in); } else { mScanWifiLockTimer = null; } mWifiMulticastEnabled = false; if (in.readInt() != 0) { - mWifiMulticastTimer = new StopwatchTimer(WIFI_MULTICAST_ENABLED, + mWifiMulticastTimer = new StopwatchTimer(Uid.this, WIFI_MULTICAST_ENABLED, null, mUnpluggables, in); } else { mWifiMulticastTimer = null; } mAudioTurnedOn = false; if (in.readInt() != 0) { - mAudioTurnedOnTimer = new StopwatchTimer(AUDIO_TURNED_ON, + mAudioTurnedOnTimer = new StopwatchTimer(Uid.this, AUDIO_TURNED_ON, null, mUnpluggables, in); } else { mAudioTurnedOnTimer = null; } mVideoTurnedOn = false; if (in.readInt() != 0) { - mVideoTurnedOnTimer = new StopwatchTimer(VIDEO_TURNED_ON, + mVideoTurnedOnTimer = new StopwatchTimer(Uid.this, VIDEO_TURNED_ON, null, mUnpluggables, in); } else { mVideoTurnedOnTimer = null; @@ -2538,7 +2697,7 @@ public final class BatteryStatsImpl extends BatteryStats { return null; } - return new StopwatchTimer(type, pool, unpluggables, in); + return new StopwatchTimer(Uid.this, type, pool, unpluggables, in); } boolean reset() { @@ -2614,7 +2773,7 @@ public final class BatteryStatsImpl extends BatteryStats { pool = new ArrayList<StopwatchTimer>(); mSensorTimers.put(mHandle, pool); } - return new StopwatchTimer(0, pool, unpluggables, in); + return new StopwatchTimer(Uid.this, 0, pool, unpluggables, in); } boolean reset() { @@ -3416,21 +3575,24 @@ public final class BatteryStatsImpl extends BatteryStats { case WAKE_TYPE_PARTIAL: t = wl.mTimerPartial; if (t == null) { - t = new StopwatchTimer(WAKE_TYPE_PARTIAL, mPartialTimers, mUnpluggables); + t = new StopwatchTimer(Uid.this, WAKE_TYPE_PARTIAL, + mPartialTimers, mUnpluggables); wl.mTimerPartial = t; } return t; case WAKE_TYPE_FULL: t = wl.mTimerFull; if (t == null) { - t = new StopwatchTimer(WAKE_TYPE_FULL, mFullTimers, mUnpluggables); + t = new StopwatchTimer(Uid.this, WAKE_TYPE_FULL, + mFullTimers, mUnpluggables); wl.mTimerFull = t; } return t; case WAKE_TYPE_WINDOW: t = wl.mTimerWindow; if (t == null) { - t = new StopwatchTimer(WAKE_TYPE_WINDOW, mWindowTimers, mUnpluggables); + t = new StopwatchTimer(Uid.this, WAKE_TYPE_WINDOW, + mWindowTimers, mUnpluggables); wl.mTimerWindow = t; } return t; @@ -3457,7 +3619,7 @@ public final class BatteryStatsImpl extends BatteryStats { timers = new ArrayList<StopwatchTimer>(); mSensorTimers.put(sensor, timers); } - t = new StopwatchTimer(BatteryStats.SENSOR, timers, mUnpluggables); + t = new StopwatchTimer(Uid.this, BatteryStats.SENSOR, timers, mUnpluggables); se.mTimer = t; return t; } @@ -3530,25 +3692,26 @@ public final class BatteryStatsImpl extends BatteryStats { public BatteryStatsImpl(String filename) { mFile = new JournaledFile(new File(filename), new File(filename + ".tmp")); + mHandler = new MyHandler(); mStartCount++; - mScreenOnTimer = new StopwatchTimer(-1, null, mUnpluggables); + mScreenOnTimer = new StopwatchTimer(null, -1, null, mUnpluggables); for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { - mScreenBrightnessTimer[i] = new StopwatchTimer(-100-i, null, mUnpluggables); + mScreenBrightnessTimer[i] = new StopwatchTimer(null, -100-i, null, mUnpluggables); } mInputEventCounter = new Counter(mUnpluggables); - mPhoneOnTimer = new StopwatchTimer(-2, null, mUnpluggables); + mPhoneOnTimer = new StopwatchTimer(null, -2, null, mUnpluggables); for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) { - mPhoneSignalStrengthsTimer[i] = new StopwatchTimer(-200-i, null, mUnpluggables); + mPhoneSignalStrengthsTimer[i] = new StopwatchTimer(null, -200-i, null, mUnpluggables); } - mPhoneSignalScanningTimer = new StopwatchTimer(-200+1, null, mUnpluggables); + mPhoneSignalScanningTimer = new StopwatchTimer(null, -200+1, null, mUnpluggables); for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { - mPhoneDataConnectionsTimer[i] = new StopwatchTimer(-300-i, null, mUnpluggables); + mPhoneDataConnectionsTimer[i] = new StopwatchTimer(null, -300-i, null, mUnpluggables); } - mWifiOnTimer = new StopwatchTimer(-3, null, mUnpluggables); - mWifiRunningTimer = new StopwatchTimer(-4, null, mUnpluggables); - mBluetoothOnTimer = new StopwatchTimer(-5, null, mUnpluggables); - mAudioOnTimer = new StopwatchTimer(-6, null, mUnpluggables); - mVideoOnTimer = new StopwatchTimer(-7, null, mUnpluggables); + mWifiOnTimer = new StopwatchTimer(null, -3, null, mUnpluggables); + mWifiRunningTimer = new StopwatchTimer(null, -4, null, mUnpluggables); + mBluetoothOnTimer = new StopwatchTimer(null, -5, null, mUnpluggables); + mAudioOnTimer = new StopwatchTimer(null, -6, null, mUnpluggables); + mVideoOnTimer = new StopwatchTimer(null, -7, null, mUnpluggables); mOnBattery = mOnBatteryInternal = false; initTimes(); mTrackBatteryPastUptime = 0; @@ -3566,9 +3729,14 @@ public final class BatteryStatsImpl extends BatteryStats { public BatteryStatsImpl(Parcel p) { mFile = null; + mHandler = null; readFromParcel(p); } + public void setCallback(BatteryCallback cb) { + mCallback = cb; + } + public void setNumSpeedSteps(int steps) { if (sNumSpeedSteps == 0) sNumSpeedSteps = steps; } @@ -3653,6 +3821,9 @@ public final class BatteryStatsImpl extends BatteryStats { void setOnBattery(boolean onBattery, int oldStatus, int level) { synchronized(this) { boolean doWrite = false; + Message m = mHandler.obtainMessage(MSG_REPORT_POWER_CHANGE); + m.arg1 = onBattery ? 1 : 0; + mHandler.sendMessage(m); mOnBattery = mOnBatteryInternal = onBattery; long uptime = SystemClock.uptimeMillis() * 1000; @@ -4553,26 +4724,29 @@ public final class BatteryStatsImpl extends BatteryStats { mBatteryRealtime = in.readLong(); mBatteryLastRealtime = 0; mScreenOn = false; - mScreenOnTimer = new StopwatchTimer(-1, null, mUnpluggables, in); + mScreenOnTimer = new StopwatchTimer(null, -1, null, mUnpluggables, in); for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { - mScreenBrightnessTimer[i] = new StopwatchTimer(-100-i, null, mUnpluggables, in); + mScreenBrightnessTimer[i] = new StopwatchTimer(null, -100-i, + null, mUnpluggables, in); } mInputEventCounter = new Counter(mUnpluggables, in); mPhoneOn = false; - mPhoneOnTimer = new StopwatchTimer(-2, null, mUnpluggables, in); + mPhoneOnTimer = new StopwatchTimer(null, -2, null, mUnpluggables, in); for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) { - mPhoneSignalStrengthsTimer[i] = new StopwatchTimer(-200-i, null, mUnpluggables, in); + mPhoneSignalStrengthsTimer[i] = new StopwatchTimer(null, -200-i, + null, mUnpluggables, in); } - mPhoneSignalScanningTimer = new StopwatchTimer(-200+1, null, mUnpluggables, in); + mPhoneSignalScanningTimer = new StopwatchTimer(null, -200+1, null, mUnpluggables, in); for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { - mPhoneDataConnectionsTimer[i] = new StopwatchTimer(-300-i, null, mUnpluggables, in); + mPhoneDataConnectionsTimer[i] = new StopwatchTimer(null, -300-i, + null, mUnpluggables, in); } mWifiOn = false; - mWifiOnTimer = new StopwatchTimer(-2, null, mUnpluggables, in); + mWifiOnTimer = new StopwatchTimer(null, -2, null, mUnpluggables, in); mWifiRunning = false; - mWifiRunningTimer = new StopwatchTimer(-2, null, mUnpluggables, in); + mWifiRunningTimer = new StopwatchTimer(null, -2, null, mUnpluggables, in); mBluetoothOn = false; - mBluetoothOnTimer = new StopwatchTimer(-2, null, mUnpluggables, in); + mBluetoothOnTimer = new StopwatchTimer(null, -2, null, mUnpluggables, in); mUptime = in.readLong(); mUptimeStart = in.readLong(); mLastUptime = 0; diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java index 89a162764b15..3142ee454870 100644 --- a/services/java/com/android/server/am/ActivityManagerService.java +++ b/services/java/com/android/server/am/ActivityManagerService.java @@ -131,7 +131,8 @@ import java.util.Set; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicLong; -public final class ActivityManagerService extends ActivityManagerNative implements Watchdog.Monitor { +public final class ActivityManagerService extends ActivityManagerNative + implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { static final String TAG = "ActivityManager"; static final boolean DEBUG = false; static final boolean localLOGV = DEBUG ? Config.LOGD : Config.LOGV; @@ -750,6 +751,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen boolean mBooting = false; boolean mWaitingUpdate = false; boolean mDidUpdate = false; + boolean mOnBattery = false; Context mContext; @@ -1381,8 +1383,10 @@ public final class ActivityManagerService extends ActivityManagerNative implemen systemDir, "batterystats.bin").toString()); mBatteryStatsService.getActiveStatistics().readLocked(); mBatteryStatsService.getActiveStatistics().writeLocked(); + mOnBattery = mBatteryStatsService.getActiveStatistics().getIsOnBattery(); + mBatteryStatsService.getActiveStatistics().setCallback(this); - mUsageStatsService = new UsageStatsService( new File( + mUsageStatsService = new UsageStatsService(new File( systemDir, "usagestats").toString()); GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", @@ -1495,25 +1499,36 @@ public final class ActivityManagerService extends ActivityManagerNative implemen synchronized(bstats) { synchronized(mPidsSelfLocked) { if (haveNewCpuStats) { - if (mBatteryStatsService.isOnBattery()) { + if (mOnBattery) { + int perc = bstats.startAddingCpuLocked(); + int totalUTime = 0; + int totalSTime = 0; final int N = mProcessStats.countWorkingStats(); for (int i=0; i<N; i++) { ProcessStats.Stats st = mProcessStats.getWorkingStats(i); ProcessRecord pr = mPidsSelfLocked.get(st.pid); + int otherUTime = (st.rel_utime*perc)/100; + int otherSTime = (st.rel_stime*perc)/100; + totalUTime += otherUTime; + totalSTime += otherSTime; if (pr != null) { BatteryStatsImpl.Uid.Proc ps = pr.batteryStats; - ps.addCpuTimeLocked(st.rel_utime, st.rel_stime); + ps.addCpuTimeLocked(st.rel_utime-otherUTime, + st.rel_stime-otherSTime); ps.addSpeedStepTimes(cpuSpeedTimes); } else { BatteryStatsImpl.Uid.Proc ps = bstats.getProcessStatsLocked(st.name, st.pid); if (ps != null) { - ps.addCpuTimeLocked(st.rel_utime, st.rel_stime); + ps.addCpuTimeLocked(st.rel_utime-otherUTime, + st.rel_stime-otherSTime); ps.addSpeedStepTimes(cpuSpeedTimes); } } } + bstats.finishAddingCpuLocked(perc, totalUTime, + totalSTime, cpuSpeedTimes); } } } @@ -1526,6 +1541,23 @@ public final class ActivityManagerService extends ActivityManagerNative implemen } } + @Override + public void batteryNeedsCpuUpdate() { + updateCpuStatsNow(); + } + + @Override + public void batteryPowerChanged(boolean onBattery) { + // When plugging in, update the CPU stats first before changing + // the plug state. + updateCpuStatsNow(); + synchronized (this) { + synchronized(mPidsSelfLocked) { + mOnBattery = onBattery; + } + } + } + /** * Initialize the application bind args. These are passed to each * process when the bindApplication() IPC is sent to the process. They're diff --git a/services/java/com/android/server/am/ProcessRecord.java b/services/java/com/android/server/am/ProcessRecord.java index 6d1fbabc73ed..67df707341ed 100644 --- a/services/java/com/android/server/am/ProcessRecord.java +++ b/services/java/com/android/server/am/ProcessRecord.java @@ -131,6 +131,13 @@ class ProcessRecord { void dump(PrintWriter pw, String prefix) { final long now = SystemClock.uptimeMillis(); + long wtime; + synchronized (batteryStats.getBatteryStats()) { + wtime = batteryStats.getBatteryStats().getProcessWakeTime(info.uid, + pid, SystemClock.elapsedRealtime()); + } + long timeUsed = wtime - lastWakeTime; + if (info.className != null) { pw.print(prefix); pw.print("class="); pw.println(info.className); } @@ -182,7 +189,9 @@ class ProcessRecord { pw.print(prefix); pw.print("adjSeq="); pw.print(adjSeq); pw.print(" lruSeq="); pw.println(lruSeq); pw.print(prefix); pw.print("lastWakeTime="); pw.print(lastWakeTime); - pw.print(" lastRequestedGc="); + pw.print(" time used="); + TimeUtils.formatDuration(timeUsed, pw); pw.println(""); + pw.print(prefix); pw.print("lastRequestedGc="); TimeUtils.formatDuration(lastRequestedGc, now, pw); pw.print(" lastLowMemory="); TimeUtils.formatDuration(lastLowMemory, now, pw); |