Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9ce2976c authored by Amith Yamasani's avatar Amith Yamasani Committed by Android (Google) Code Review
Browse files

Merge "Fix issue in proc state ranking in a cycle"

parents 16729c7c 08888c02
Loading
Loading
Loading
Loading
+86 −43
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@ import static android.Manifest.permission.REMOVE_TASKS;
import static android.app.ActivityManager.INSTR_FLAG_DISABLE_HIDDEN_API_CHECKS;
import static android.app.ActivityManager.INSTR_FLAG_MOUNT_EXTERNAL_STORAGE_FULL;
import static android.app.ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
import static android.app.ActivityManager.PROCESS_STATE_CACHED_EMPTY;
import static android.app.ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
import static android.app.ActivityManager.PROCESS_STATE_NONEXISTENT;
import static android.app.ActivityManagerInternal.ALLOW_FULL_ONLY;
@@ -15711,7 +15712,7 @@ public class ActivityManagerService extends IActivityManager.Stub
    }
    private final boolean computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
            boolean doingAll, long now) {
            boolean doingAll, long now, boolean cycleReEval) {
        if (mAdjSeq == app.adjSeq) {
            if (app.adjSeq == app.completedAdjSeq) {
                // This adjustment has already been computed successfully.
@@ -15787,10 +15788,11 @@ public class ActivityManagerService extends IActivityManager.Stub
                    app.setCurrentSchedulingGroup(ProcessList.SCHED_GROUP_RESTRICTED);
                }
            }
            app.setCurRawProcState(app.getCurProcState());
            app.curAdj = app.maxAdj;
            app.completedAdjSeq = app.adjSeq;
            // if curAdj is less than prevAppAdj, then this process was promoted
            return app.curAdj < prevAppAdj;
            return app.curAdj < prevAppAdj || app.getCurProcState() < prevProcState;
        }
        app.systemNoUi = false;
@@ -16032,8 +16034,13 @@ public class ActivityManagerService extends IActivityManager.Stub
        // By default, we use the computed adjustment.  It may be changed if
        // there are applications dependent on our services or providers, but
        // this gives us a baseline and makes sure we don't get into an
        // infinite recursion.
        app.setCurRawAdj(adj);
        // infinite recursion. If we're re-evaluating due to cycles, use the previously computed
        // values.
        app.setCurRawAdj(!cycleReEval ? adj : Math.min(adj, app.getCurRawAdj()));
        app.setCurRawProcState(!cycleReEval
                ? procState
                : Math.min(procState, app.getCurRawProcState()));
        app.hasStartedServices = false;
        app.adjSeq = mAdjSeq;
@@ -16135,21 +16142,15 @@ public class ActivityManagerService extends IActivityManager.Stub
                    boolean trackedProcState = false;
                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
                        ProcessRecord client = cr.binding.client;
                        computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
                        if (client.containsCycle) {
                            // We've detected a cycle. We should retry computeOomAdjLocked later in
                            // case a later-checked connection from a client  would raise its
                            // priority legitimately.
                            app.containsCycle = true;
                            // If the client has not been completely evaluated, skip using its
                            // priority. Else use the conservative value for now and look for a
                            // better state in the next iteration.
                            if (client.completedAdjSeq < mAdjSeq) {
                        computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now, cycleReEval);
                        if (shouldSkipDueToCycle(app, client, procState, adj, cycleReEval)) {
                            continue;
                        }
                        }
                        int clientAdj = client.getCurRawAdj();
                        int clientProcState = client.getCurProcState();
                        int clientProcState = client.getCurRawProcState();
                        if (clientProcState >= PROCESS_STATE_CACHED_ACTIVITY) {
                            // If the other app is cached for any reason, for purposes here
                            // we are going to consider it empty.  The specific cached state
@@ -16234,6 +16235,7 @@ public class ActivityManagerService extends IActivityManager.Stub
                                }
                                if (adj >  newAdj) {
                                    adj = newAdj;
                                    app.setCurRawAdj(adj);
                                    adjType = "service";
                                }
                            }
@@ -16305,6 +16307,7 @@ public class ActivityManagerService extends IActivityManager.Stub
                        }
                        if (procState > clientProcState) {
                            procState = clientProcState;
                            app.setCurRawProcState(procState);
                            if (adjType == null) {
                                adjType = "service";
                            }
@@ -16336,6 +16339,7 @@ public class ActivityManagerService extends IActivityManager.Stub
                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ
                                && a.isActivityVisible()) {
                            adj = ProcessList.FOREGROUND_APP_ADJ;
                            app.setCurRawAdj(adj);
                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
                                    schedGroup = ProcessList.SCHED_GROUP_TOP_APP_BOUND;
@@ -16377,21 +16381,15 @@ public class ActivityManagerService extends IActivityManager.Stub
                    // Being our own client is not interesting.
                    continue;
                }
                computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
                if (client.containsCycle) {
                    // We've detected a cycle. We should retry computeOomAdjLocked later in
                    // case a later-checked connection from a client  would raise its
                    // priority legitimately.
                    app.containsCycle = true;
                    // If the client has not been completely evaluated, skip using its
                    // priority. Else use the conservative value for now and look for a
                    // better state in the next iteration.
                    if (client.completedAdjSeq < mAdjSeq) {
                computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now, cycleReEval);
                if (shouldSkipDueToCycle(app, client, procState, adj, cycleReEval)) {
                    continue;
                }
                }
                int clientAdj = client.getCurRawAdj();
                int clientProcState = client.getCurProcState();
                int clientProcState = client.getCurRawProcState();
                if (clientProcState >= PROCESS_STATE_CACHED_ACTIVITY) {
                    // If the other app is cached for any reason, for purposes here
                    // we are going to consider it empty.
@@ -16405,6 +16403,7 @@ public class ActivityManagerService extends IActivityManager.Stub
                    } else {
                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
                        app.setCurRawAdj(adj);
                        adjType = "provider";
                    }
                    app.cached &= client.cached;
@@ -16440,6 +16439,7 @@ public class ActivityManagerService extends IActivityManager.Stub
                conn.trackProcState(clientProcState, mAdjSeq, now);
                if (procState > clientProcState) {
                    procState = clientProcState;
                    app.setCurRawProcState(procState);
                }
                if (client.getCurrentSchedulingGroup() > schedGroup) {
                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
@@ -16465,6 +16465,7 @@ public class ActivityManagerService extends IActivityManager.Stub
            if (cpr.hasExternalProcessHandles()) {
                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
                    adj = ProcessList.FOREGROUND_APP_ADJ;
                    app.setCurRawAdj(adj);
                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
                    app.cached = false;
                    app.adjType = "ext-provider";
@@ -16476,6 +16477,7 @@ public class ActivityManagerService extends IActivityManager.Stub
                }
                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
                    app.setCurRawProcState(procState);
                    if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
                        reportOomAdjMessageLocked(TAG_OOM_ADJ,
                                "Raise procstate to external provider: " + app);
@@ -16620,6 +16622,7 @@ public class ActivityManagerService extends IActivityManager.Stub
        app.curAdj = app.modifyRawOomAdj(adj);
        app.setCurrentSchedulingGroup(schedGroup);
        app.setCurProcState(procState);
        app.setCurRawProcState(procState);
        app.setHasForegroundActivities(foregroundActivities);
        app.completedAdjSeq = mAdjSeq;
@@ -16627,6 +16630,44 @@ public class ActivityManagerService extends IActivityManager.Stub
        return app.curAdj < prevAppAdj || app.getCurProcState() < prevProcState;
    }
    /**
     * Checks if for the given app and client, there's a cycle that should skip over the client
     * for now or use partial values to evaluate the effect of the client binding.
     * @param app
     * @param client
     * @param procState procstate evaluated so far for this app
     * @param adj oom_adj evaluated so far for this app
     * @param cycleReEval whether we're currently re-evaluating due to a cycle, and not the first
     *                    evaluation.
     * @return whether to skip using the client connection at this time
     */
    private boolean shouldSkipDueToCycle(ProcessRecord app, ProcessRecord client,
            int procState, int adj, boolean cycleReEval) {
        if (client.containsCycle) {
            // We've detected a cycle. We should retry computeOomAdjLocked later in
            // case a later-checked connection from a client  would raise its
            // priority legitimately.
            app.containsCycle = true;
            // If the client has not been completely evaluated, check if it's worth
            // using the partial values.
            if (client.completedAdjSeq < mAdjSeq) {
                if (cycleReEval) {
                    // If the partial values are no better, skip until the next
                    // attempt
                    if (client.getCurRawProcState() >= procState
                            && client.getCurRawAdj() >= adj) {
                        return true;
                    }
                    // Else use the client's partial procstate and adj to adjust the
                    // effect of the binding
                } else {
                    return true;
                }
            }
        }
        return false;
    }
    private static final class RecordPssRunnable implements Runnable {
        private final ActivityManagerService mService;
        private final ProcessRecord mProc;
@@ -17493,7 +17534,7 @@ public class ActivityManagerService extends IActivityManager.Stub
            return false;
        }
        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now, false);
        return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
    }
@@ -17868,12 +17909,14 @@ public class ActivityManagerService extends IActivityManager.Stub
        for (int i=N-1; i>=0; i--) {
            ProcessRecord app = mProcessList.mLruProcesses.get(i);
            app.containsCycle = false;
            app.setCurRawProcState(PROCESS_STATE_CACHED_EMPTY);
            app.setCurRawAdj(ProcessList.UNKNOWN_ADJ);
        }
        for (int i=N-1; i>=0; i--) {
            ProcessRecord app = mProcessList.mLruProcesses.get(i);
            if (!app.killedByAm && app.thread != null) {
                app.procStateChanged = false;
                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now, false);
                // if any app encountered a cycle, we need to perform an additional loop later
                retryCycles |= app.containsCycle;
@@ -17976,8 +18019,8 @@ public class ActivityManagerService extends IActivityManager.Stub
            for (int i=0; i<N; i++) {
                ProcessRecord app = mProcessList.mLruProcesses.get(i);
                if (!app.killedByAm && app.thread != null && app.containsCycle == true) {
                    if (computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now)) {
                    if (computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now,
                            true)) {
                        retryCycles = true;
                    }
                }
+10 −0
Original line number Diff line number Diff line
@@ -153,6 +153,7 @@ final class ProcessRecord implements WindowProcessListener {
    int trimMemoryLevel;        // Last selected memory trimming level
    private int mCurProcState = PROCESS_STATE_NONEXISTENT; // Currently computed process state
    private int mRepProcState = PROCESS_STATE_NONEXISTENT; // Last reported process state
    private int mCurRawProcState = PROCESS_STATE_NONEXISTENT; // Temp state during computation
    int setProcState = PROCESS_STATE_NONEXISTENT; // Last set process state in process tracker
    int pssProcState = PROCESS_STATE_NONEXISTENT; // Currently requesting pss for
    int pssStatType;            // The type of stat collection that we are currently requesting
@@ -902,6 +903,7 @@ final class ProcessRecord implements WindowProcessListener {
        if (mRepProcState > newState) {
            mRepProcState = newState;
            setCurProcState(newState);
            setCurRawProcState(newState);
            for (int ipkg = pkgList.size() - 1; ipkg >= 0; ipkg--) {
                StatsLog.write(StatsLog.PROCESS_STATE_CHANGED,
                        uid, processName, pkgList.keyAt(ipkg),
@@ -984,6 +986,14 @@ final class ProcessRecord implements WindowProcessListener {
        return mCurProcState;
    }

    void setCurRawProcState(int curRawProcState) {
        mCurRawProcState = curRawProcState;
    }

    int getCurRawProcState() {
        return mCurRawProcState;
    }

    void setReportedProcState(int repProcState) {
        mRepProcState = repProcState;
        for (int ipkg = pkgList.size() - 1; ipkg >= 0; ipkg--) {