diff options
| author | 2015-11-19 17:55:19 -0800 | |
|---|---|---|
| committer | 2015-12-01 16:53:28 -0800 | |
| commit | a8d10945a608ac6f85a6ab85b69b9a118d7853d8 (patch) | |
| tree | 538080712b9f65099b9a5158c6d6fb2ecf7756c1 | |
| parent | 96b2da271ffa18f1ecc7da57e6469ac01e0c2041 (diff) | |
Fix reporting of uid state in battery stats.
Now that the activity manager keeps track of per-uid process states,
we can push that already rolled-up data into battery stats to directly
track the times in those states.
The problem with the reporting was actually that we weren't dealing
correctly with negative process states, which is now fixed. (It was
interpreting them as FOREGROUND rather than not running.)
Also split out a number of new states -- TOP, FOREGROUND_SERVICE,
TOP_SLEEPING -- from FOREGROUND. This should allow us to get a much
better idea of how much an app has been actively in use: TOP is when
it is directly visible to the user or in use by such, FOREGROUND_SERVICE
is when it is running in the background in a way the user is aware of.
Also when reporting these numbers, they are no longer added together as
reported but kept as separate times.
Change-Id: I6d307503a4b4ad5c0d5d49305ef63f8eb858e2c9
4 files changed, 73 insertions, 105 deletions
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java index 1aa5c66202f2..bce38f40682a 100644 --- a/core/java/android/os/BatteryStats.java +++ b/core/java/android/os/BatteryStats.java @@ -169,7 +169,7 @@ public abstract class BatteryStats implements Parcelable { /** * Current version of checkin data format. */ - static final String CHECKIN_VERSION = "16"; + static final String CHECKIN_VERSION = "17"; /** * Old version, we hit 9 and ran out of room, need to remove. @@ -407,17 +407,23 @@ public abstract class BatteryStats implements Parcelable { public abstract Timer getCameraTurnedOnTimer(); public abstract Timer getForegroundActivityTimer(); - // Time this uid has any processes in foreground state. - public static final int PROCESS_STATE_FOREGROUND = 0; - // Time this uid has any process in active state (not cached). - public static final int PROCESS_STATE_ACTIVE = 1; + // Time this uid has any processes in the top state. + public static final int PROCESS_STATE_TOP = 0; + // Time this uid has any process with a started out bound foreground service. + public static final int PROCESS_STATE_FOREGROUND_SERVICE = 1; + // Time this uid has any process that is top while the device is sleeping. + public static final int PROCESS_STATE_TOP_SLEEPING = 2; + // Time this uid has any process in an active foreground state. + public static final int PROCESS_STATE_FOREGROUND = 3; + // Time this uid has any process in an active background state. + public static final int PROCESS_STATE_BACKGROUND = 4; // Time this uid has any processes running at all. - public static final int PROCESS_STATE_RUNNING = 2; + public static final int PROCESS_STATE_CACHED = 5; // Total number of process states we track. - public static final int NUM_PROCESS_STATE = 3; + public static final int NUM_PROCESS_STATE = 6; static final String[] PROCESS_STATE_NAMES = { - "Foreground", "Active", "Running" + "Top", "Fg Service", "Top Sleeping", "Foreground", "Background", "Cached" }; public abstract long getProcessStateTime(int state, long elapsedRealtimeUs, int which); @@ -2954,8 +2960,9 @@ public abstract class BatteryStats implements Parcelable { final Object[] stateTimes = new Object[Uid.NUM_PROCESS_STATE]; long totalStateTime = 0; for (int ips=0; ips<Uid.NUM_PROCESS_STATE; ips++) { - totalStateTime += u.getProcessStateTime(ips, rawRealtime, which); - stateTimes[ips] = (totalStateTime + 500) / 1000; + final long time = u.getProcessStateTime(ips, rawRealtime, which); + totalStateTime += time; + stateTimes[ips] = (time + 500) / 1000; } if (totalStateTime > 0) { dumpLine(pw, uid, category, STATE_TIME_DATA, stateTimes); @@ -4122,11 +4129,18 @@ public abstract class BatteryStats implements Parcelable { sb.append(" "); sb.append(Uid.PROCESS_STATE_NAMES[ips]); sb.append(" for: "); - formatTimeMs(sb, (totalStateTime + 500) / 1000); + formatTimeMs(sb, (time + 500) / 1000); pw.println(sb.toString()); uidActivity = true; } } + if (totalStateTime > 0) { + sb.setLength(0); + sb.append(prefix); + sb.append(" Total running: "); + formatTimeMs(sb, (totalStateTime + 500) / 1000); + pw.println(sb.toString()); + } final long userCpuTimeUs = u.getUserCpuTimeUs(which); final long systemCpuTimeUs = u.getSystemCpuTimeUs(which); diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java index 9391c6038fbc..4a969b28e784 100644 --- a/core/java/com/android/internal/os/BatteryStatsImpl.java +++ b/core/java/com/android/internal/os/BatteryStatsImpl.java @@ -105,7 +105,7 @@ public final class BatteryStatsImpl extends BatteryStats { private static final int MAGIC = 0xBA757475; // 'BATSTATS' // Current on-disk Parcel version - private static final int VERSION = 136 + (USE_OLD_HISTORY ? 1000 : 0); + private static final int VERSION = 138 + (USE_OLD_HISTORY ? 1000 : 0); // Maximum number of items we will record in the history. private static final int MAX_HISTORY_ITEMS = 2000; @@ -2621,10 +2621,9 @@ public final class BatteryStatsImpl extends BatteryStats { } } - public void noteProcessStateLocked(String name, int uid, int state) { + public void noteUidProcessStateLocked(int uid, int state) { uid = mapUid(uid); - final long elapsedRealtime = SystemClock.elapsedRealtime(); - getUidStatsLocked(uid).updateProcessStateLocked(name, state, elapsedRealtime); + getUidStatsLocked(uid).updateUidProcessStateLocked(state); } public void noteProcessFinishLocked(String name, int uid) { @@ -2632,13 +2631,11 @@ public final class BatteryStatsImpl extends BatteryStats { if (!mActiveEvents.updateState(HistoryItem.EVENT_PROC_FINISH, name, uid, 0)) { return; } - final long elapsedRealtime = SystemClock.elapsedRealtime(); - final long uptime = SystemClock.uptimeMillis(); - getUidStatsLocked(uid).updateProcessStateLocked(name, Uid.PROCESS_STATE_NONE, - elapsedRealtime); if (!mRecordAllHistory) { return; } + final long elapsedRealtime = SystemClock.elapsedRealtime(); + final long uptime = SystemClock.uptimeMillis(); addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_PROC_FINISH, name, uid); } @@ -4446,8 +4443,7 @@ public final class BatteryStatsImpl extends BatteryStats { StopwatchTimer mForegroundActivityTimer; - static final int PROCESS_STATE_NONE = NUM_PROCESS_STATE; - int mProcessState = PROCESS_STATE_NONE; + int mProcessState = ActivityManager.PROCESS_STATE_NONEXISTENT; StopwatchTimer[] mProcessStateTimer; BatchTimer mVibratorOnTimer; @@ -4812,21 +4808,6 @@ public final class BatteryStatsImpl extends BatteryStats { } } - void updateUidProcessStateLocked(int state, long elapsedRealtimeMs) { - if (mProcessState == state) return; - - if (mProcessState != PROCESS_STATE_NONE) { - mProcessStateTimer[mProcessState].stopRunningLocked(elapsedRealtimeMs); - } - mProcessState = state; - if (state != PROCESS_STATE_NONE) { - if (mProcessStateTimer[state] == null) { - makeProcessState(state, null); - } - mProcessStateTimer[state].startRunningLocked(elapsedRealtimeMs); - } - } - public BatchTimer createVibratorOnTimerLocked() { if (mVibratorOnTimer == null) { mVibratorOnTimer = new BatchTimer(Uid.this, VIBRATOR_ON, mOnBatteryTimeBase); @@ -5167,7 +5148,7 @@ public final class BatteryStatsImpl extends BatteryStats { active |= !mProcessStateTimer[i].reset(false); } } - active |= (mProcessState != PROCESS_STATE_NONE); + active |= (mProcessState != ActivityManager.PROCESS_STATE_NONEXISTENT); } if (mVibratorOnTimer != null) { if (mVibratorOnTimer.reset(false)) { @@ -5261,14 +5242,9 @@ public final class BatteryStatsImpl extends BatteryStats { } for (int ip=mProcessStats.size()-1; ip>=0; ip--) { Proc proc = mProcessStats.valueAt(ip); - if (proc.mProcessState == PROCESS_STATE_NONE) { - proc.detach(); - mProcessStats.removeAt(ip); - } else { - proc.reset(); - active = true; - } + proc.detach(); } + mProcessStats.clear(); if (mPids.size() > 0) { for (int i=mPids.size()-1; i>=0; i--) { Pid pid = mPids.valueAt(i); @@ -5697,7 +5673,7 @@ public final class BatteryStatsImpl extends BatteryStats { } else { mForegroundActivityTimer = null; } - mProcessState = PROCESS_STATE_NONE; + mProcessState = ActivityManager.PROCESS_STATE_NONEXISTENT; for (int i = 0; i < NUM_PROCESS_STATE; i++) { if (in.readInt() != 0) { makeProcessState(i, in); @@ -6080,11 +6056,6 @@ public final class BatteryStatsImpl extends BatteryStats { */ int mUnpluggedNumAnrs; - /** - * Current process state. - */ - int mProcessState = PROCESS_STATE_NONE; - ArrayList<ExcessivePower> mExcessivePower; Proc(String name) { @@ -6104,16 +6075,6 @@ public final class BatteryStatsImpl extends BatteryStats { public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) { } - void reset() { - mUserTime = mSystemTime = mForegroundTime = 0; - mStarts = mNumCrashes = mNumAnrs = 0; - mLoadedUserTime = mLoadedSystemTime = mLoadedForegroundTime = 0; - mLoadedStarts = mLoadedNumCrashes = mLoadedNumAnrs = 0; - mUnpluggedUserTime = mUnpluggedSystemTime = mUnpluggedForegroundTime = 0; - mUnpluggedStarts = mUnpluggedNumCrashes = mUnpluggedNumAnrs = 0; - mExcessivePower = null; - } - void detach() { mActive = false; mOnBatteryTimeBase.remove(this); @@ -6668,46 +6629,39 @@ public final class BatteryStatsImpl extends BatteryStats { return ps; } - public void updateProcessStateLocked(String procName, int state, long elapsedRealtimeMs) { - int procState; - if (state <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { - procState = PROCESS_STATE_FOREGROUND; - } else if (state <= ActivityManager.PROCESS_STATE_RECEIVER) { - procState = PROCESS_STATE_ACTIVE; + public void updateUidProcessStateLocked(int procState) { + int uidRunningState; + if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT) { + uidRunningState = ActivityManager.PROCESS_STATE_NONEXISTENT; + } else if (procState == ActivityManager.PROCESS_STATE_TOP) { + uidRunningState = PROCESS_STATE_TOP; + } else if (procState <= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) { + // Persistent and other foreground states go here. + uidRunningState = PROCESS_STATE_FOREGROUND_SERVICE; + } else if (procState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) { + uidRunningState = PROCESS_STATE_TOP_SLEEPING; + } else if (procState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { + // Persistent and other foreground states go here. + uidRunningState = PROCESS_STATE_FOREGROUND; + } else if (procState <= ActivityManager.PROCESS_STATE_RECEIVER) { + uidRunningState = PROCESS_STATE_BACKGROUND; } else { - procState = PROCESS_STATE_RUNNING; + uidRunningState = PROCESS_STATE_CACHED; } - updateRealProcessStateLocked(procName, procState, elapsedRealtimeMs); - } - public void updateRealProcessStateLocked(String procName, int procState, - long elapsedRealtimeMs) { - Proc proc = getProcessStatsLocked(procName); - if (proc.mProcessState != procState) { - boolean changed; - if (procState < proc.mProcessState) { - // Has this process become more important? If so, - // we may need to change the uid if the currrent uid proc state - // is not as important as what we are now setting. - changed = mProcessState > procState; - } else { - // Has this process become less important? If so, - // we may need to change the uid if the current uid proc state - // is the same importance as the old setting. - changed = mProcessState == proc.mProcessState; - } - proc.mProcessState = procState; - if (changed) { - // uid's state may have changed; compute what the new state should be. - int uidProcState = PROCESS_STATE_NONE; - for (int ip=mProcessStats.size()-1; ip>=0; ip--) { - proc = mProcessStats.valueAt(ip); - if (proc.mProcessState < uidProcState) { - uidProcState = proc.mProcessState; - } - } - updateUidProcessStateLocked(uidProcState, elapsedRealtimeMs); + if (mProcessState == uidRunningState) return; + + final long elapsedRealtime = SystemClock.elapsedRealtime(); + + if (mProcessState != ActivityManager.PROCESS_STATE_NONEXISTENT) { + mProcessStateTimer[mProcessState].stopRunningLocked(elapsedRealtime); + } + mProcessState = uidRunningState; + if (uidRunningState != ActivityManager.PROCESS_STATE_NONEXISTENT) { + if (mProcessStateTimer[uidRunningState] == null) { + makeProcessState(uidRunningState, null); } + mProcessStateTimer[uidRunningState].startRunningLocked(elapsedRealtime); } } @@ -9423,7 +9377,7 @@ public final class BatteryStatsImpl extends BatteryStats { if (in.readInt() != 0) { u.createForegroundActivityTimerLocked().readSummaryFromParcelLocked(in); } - u.mProcessState = Uid.PROCESS_STATE_NONE; + u.mProcessState = ActivityManager.PROCESS_STATE_NONEXISTENT; for (int i = 0; i < Uid.NUM_PROCESS_STATE; i++) { if (in.readInt() != 0) { u.makeProcessState(i, null); diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 99470c808b8f..80d00cca7730 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -6009,6 +6009,8 @@ public final class ActivityManagerService extends ActivityManagerNative "No more processes in " + old.uidRecord); enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE); mActiveUids.remove(uid); + mBatteryStatsService.noteUidProcessState(uid, + ActivityManager.PROCESS_STATE_NONEXISTENT); } old.uidRecord = null; } @@ -6033,6 +6035,7 @@ public final class ActivityManagerService extends ActivityManagerNative if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS, "Creating new process uid: " + uidRec); mActiveUids.put(proc.uid, uidRec); + mBatteryStatsService.noteUidProcessState(uidRec.uid, uidRec.curProcState); enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE); } proc.uidRecord = uidRec; @@ -19370,10 +19373,6 @@ public final class ActivityManagerService extends ActivityManagerNative if (proc.baseProcessTracker != null) { proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); } - if (proc.repProcState >= 0) { - mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid, - proc.repProcState); - } } } @@ -19873,6 +19872,7 @@ public final class ActivityManagerService extends ActivityManagerNative } uidRec.setProcState = uidRec.curProcState; enqueueUidChangeLocked(uidRec, -1, uidChange); + mBatteryStatsService.noteUidProcessState(uidRec.uid, uidRec.curProcState); } } diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java index c7228ce47683..f64b80323b91 100644 --- a/services/core/java/com/android/server/am/BatteryStatsService.java +++ b/services/core/java/com/android/server/am/BatteryStatsService.java @@ -272,15 +272,15 @@ public final class BatteryStatsService extends IBatteryStats.Stub } } - void noteProcessState(String name, int uid, int state) { + void noteProcessFinish(String name, int uid) { synchronized (mStats) { - mStats.noteProcessStateLocked(name, uid, state); + mStats.noteProcessFinishLocked(name, uid); } } - void noteProcessFinish(String name, int uid) { + void noteUidProcessState(int uid, int state) { synchronized (mStats) { - mStats.noteProcessFinishLocked(name, uid); + mStats.noteUidProcessStateLocked(uid, state); } } |