diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 2371101d7c9fd..9e78af82709dc 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -5614,15 +5614,29 @@ public class ActivityManagerService extends IActivityManager.Stub synchronized (mProcLock) { synchronized (mPidsSelfLocked) { + int newestTimeIndex = -1; + long newestTime = Long.MIN_VALUE; for (int i = 0; i < pids.length; i++) { ProcessRecord pr = mPidsSelfLocked.get(pids[i]); if (pr != null) { - final boolean isPendingTop = - mPendingStartActivityUids.isPendingTopPid(pr.uid, pids[i]); - states[i] = isPendingTop ? PROCESS_STATE_TOP : pr.mState.getCurProcState(); - if (scores != null) { - scores[i] = isPendingTop - ? (ProcessList.FOREGROUND_APP_ADJ - 1) : pr.mState.getCurAdj(); + final long pendingTopTime = + mPendingStartActivityUids.getPendingTopPidTime(pr.uid, pids[i]); + if (pendingTopTime != PendingStartActivityUids.INVALID_TIME) { + // The uid in mPendingStartActivityUids gets the TOP process state. + states[i] = PROCESS_STATE_TOP; + if (scores != null) { + // The uid in mPendingStartActivityUids gets a better score. + scores[i] = ProcessList.FOREGROUND_APP_ADJ - 1; + } + if (pendingTopTime > newestTime) { + newestTimeIndex = i; + newestTime = pendingTopTime; + } + } else { + states[i] = pr.mState.getCurProcState(); + if (scores != null) { + scores[i] = pr.mState.getCurAdj(); + } } } else { states[i] = PROCESS_STATE_NONEXISTENT; @@ -5631,6 +5645,13 @@ public class ActivityManagerService extends IActivityManager.Stub } } } + // The uid with the newest timestamp in mPendingStartActivityUids gets the best + // score. + if (newestTimeIndex != -1) { + if (scores != null) { + scores[newestTimeIndex] = ProcessList.FOREGROUND_APP_ADJ - 2; + } + } } } } diff --git a/services/core/java/com/android/server/am/PendingStartActivityUids.java b/services/core/java/com/android/server/am/PendingStartActivityUids.java index 6bf9d4e5c3f0f..802ea001e28c3 100644 --- a/services/core/java/com/android/server/am/PendingStartActivityUids.java +++ b/services/core/java/com/android/server/am/PendingStartActivityUids.java @@ -35,6 +35,8 @@ import android.util.SparseArray; final class PendingStartActivityUids { static final String TAG = ActivityManagerService.TAG; + public static final long INVALID_TIME = 0; + // Key is uid, value is Pair of pid and SystemClock.elapsedRealtime() when the // uid is added. private final SparseArray> mPendingUids = new SparseArray(); @@ -63,13 +65,20 @@ final class PendingStartActivityUids { } } - synchronized boolean isPendingTopPid(int uid, int pid) { + /** + * Return the elapsedRealtime when the uid is added to the mPendingUids map. + * @param uid + * @param pid + * @return elapsedRealtime if the uid is in the mPendingUids map; + * INVALID_TIME if the uid is not in the mPendingUids map. + */ + synchronized long getPendingTopPidTime(int uid, int pid) { + long ret = INVALID_TIME; final Pair pendingPid = mPendingUids.get(uid); - if (pendingPid != null) { - return pendingPid.first == pid; - } else { - return false; + if (pendingPid != null && pendingPid.first == pid) { + ret = pendingPid.second; } + return ret; } synchronized boolean isPendingTopUid(int uid) {