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

Commit d6041cb9 authored by Michael Wachenschwanz's avatar Michael Wachenschwanz
Browse files

Remove mCached and mEmpty from PSR and calculate on query

The mCached and mEmpty are effectively descriptions of oomAdj and
ProcState. Calculating cached and empty states from oomAdj and procState
guarantees there will be no desync from those respective states.

Also cache adjType for Activity-based policies, so it does not get wiped
out by subsequent computes in an update.

Fixes: 302754011
Test: atest MockingOomAdjusterTests
Test: atest ServiceBindingOomAdjPolicyTest
Change-Id: Icc1f5a772a0739d28718f4e1255f1c33204b77a9
parent b7d18815
Loading
Loading
Loading
Loading
+19 −33
Original line number Diff line number Diff line
@@ -1624,6 +1624,7 @@ public class OomAdjuster {
        int appUid;
        int logUid;
        int processStateCurTop;
        String mAdjType;
        ProcessStateRecord mState;

        void initialize(ProcessRecord app, int adj, boolean foregroundActivities,
@@ -1638,6 +1639,7 @@ public class OomAdjuster {
            this.appUid = appUid;
            this.logUid = logUid;
            this.processStateCurTop = processStateCurTop;
            mAdjType = app.mState.getAdjType();
            this.mState = app.mState;
        }

@@ -1646,14 +1648,14 @@ public class OomAdjuster {
            // App has a visible activity; only upgrade adjustment.
            if (adj > VISIBLE_APP_ADJ) {
                adj = VISIBLE_APP_ADJ;
                mState.setAdjType("vis-activity");
                mAdjType = "vis-activity";
                if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
                    reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise adj to vis-activity: " + app);
                }
            }
            if (procState > processStateCurTop) {
                procState = processStateCurTop;
                mState.setAdjType("vis-activity");
                mAdjType = "vis-activity";
                if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
                    reportOomAdjMessageLocked(TAG_OOM_ADJ,
                            "Raise procstate to vis-activity (top): " + app);
@@ -1662,8 +1664,6 @@ public class OomAdjuster {
            if (schedGroup < SCHED_GROUP_DEFAULT) {
                schedGroup = SCHED_GROUP_DEFAULT;
            }
            mState.setCached(false);
            mState.setEmpty(false);
            foregroundActivities = true;
            mHasVisibleActivities = true;
        }
@@ -1672,14 +1672,14 @@ public class OomAdjuster {
        public void onPausedActivity() {
            if (adj > PERCEPTIBLE_APP_ADJ) {
                adj = PERCEPTIBLE_APP_ADJ;
                mState.setAdjType("pause-activity");
                mAdjType = "pause-activity";
                if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
                    reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise adj to pause-activity: "  + app);
                }
            }
            if (procState > processStateCurTop) {
                procState = processStateCurTop;
                mState.setAdjType("pause-activity");
                mAdjType = "pause-activity";
                if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
                    reportOomAdjMessageLocked(TAG_OOM_ADJ,
                            "Raise procstate to pause-activity (top): "  + app);
@@ -1688,8 +1688,6 @@ public class OomAdjuster {
            if (schedGroup < SCHED_GROUP_DEFAULT) {
                schedGroup = SCHED_GROUP_DEFAULT;
            }
            mState.setCached(false);
            mState.setEmpty(false);
            foregroundActivities = true;
            mHasVisibleActivities = false;
        }
@@ -1698,7 +1696,7 @@ public class OomAdjuster {
        public void onStoppingActivity(boolean finishing) {
            if (adj > PERCEPTIBLE_APP_ADJ) {
                adj = PERCEPTIBLE_APP_ADJ;
                mState.setAdjType("stop-activity");
                mAdjType = "stop-activity";
                if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
                    reportOomAdjMessageLocked(TAG_OOM_ADJ,
                            "Raise adj to stop-activity: "  + app);
@@ -1714,15 +1712,13 @@ public class OomAdjuster {
            if (!finishing) {
                if (procState > PROCESS_STATE_LAST_ACTIVITY) {
                    procState = PROCESS_STATE_LAST_ACTIVITY;
                    mState.setAdjType("stop-activity");
                    mAdjType = "stop-activity";
                    if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
                        reportOomAdjMessageLocked(TAG_OOM_ADJ,
                                "Raise procstate to stop-activity: " + app);
                    }
                }
            }
            mState.setCached(false);
            mState.setEmpty(false);
            foregroundActivities = true;
            mHasVisibleActivities = false;
        }
@@ -1731,7 +1727,7 @@ public class OomAdjuster {
        public void onOtherActivity() {
            if (procState > PROCESS_STATE_CACHED_ACTIVITY) {
                procState = PROCESS_STATE_CACHED_ACTIVITY;
                mState.setAdjType("cch-act");
                mAdjType = "cch-act";
                if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
                    reportOomAdjMessageLocked(TAG_OOM_ADJ,
                            "Raise procstate to cached activity: " + app);
@@ -1787,8 +1783,6 @@ public class OomAdjuster {
        state.setAdjTypeCode(ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN);
        state.setAdjSource(null);
        state.setAdjTarget(null);
        state.setEmpty(false);
        state.setCached(false);
        if (!couldRecurse || !cycleReEval) {
            // Don't reset this flag when doing cycles re-evaluation.
            state.setNoKillOnBgRestrictedAndIdle(false);
@@ -1940,8 +1934,6 @@ public class OomAdjuster {
            adj = cachedAdj;
            procState = PROCESS_STATE_CACHED_EMPTY;
            if (!couldRecurse || !state.containsCycle()) {
                state.setCached(true);
                state.setEmpty(true);
                state.setAdjType("cch-empty");
            }
            if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
@@ -1960,6 +1952,7 @@ public class OomAdjuster {
            hasVisibleActivities = state.getCachedHasVisibleActivities();
            procState = state.getCachedProcState();
            schedGroup = state.getCachedSchedGroup();
            state.setAdjType(state.getCachedAdjType());
        }

        if (procState > PROCESS_STATE_CACHED_RECENT && state.getCachedHasRecentTasks()) {
@@ -2017,7 +2010,6 @@ public class OomAdjuster {
                adj = newAdj;
                procState = newProcState;
                state.setAdjType(adjType);
                state.setCached(false);
                schedGroup = SCHED_GROUP_DEFAULT;

                if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
@@ -2075,7 +2067,6 @@ public class OomAdjuster {
                // thus out of background check), so we yes the best background level we can.
                adj = PERCEPTIBLE_APP_ADJ;
                procState = PROCESS_STATE_TRANSIENT_BACKGROUND;
                state.setCached(false);
                state.setAdjType("force-imp");
                state.setAdjSource(state.getForcingToImportant());
                schedGroup = SCHED_GROUP_DEFAULT;
@@ -2090,7 +2081,6 @@ public class OomAdjuster {
                // We don't want to kill the current heavy-weight process.
                adj = HEAVY_WEIGHT_APP_ADJ;
                schedGroup = SCHED_GROUP_BACKGROUND;
                state.setCached(false);
                state.setAdjType("heavy");
                if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
                    reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise adj to heavy: " + app);
@@ -2111,7 +2101,6 @@ public class OomAdjuster {
                // home app, so we don't want to let it go into the background.
                adj = HOME_APP_ADJ;
                schedGroup = SCHED_GROUP_BACKGROUND;
                state.setCached(false);
                state.setAdjType("home");
                if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
                    reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise adj to home: " + app);
@@ -2145,7 +2134,6 @@ public class OomAdjuster {
                if (adj > PREVIOUS_APP_ADJ) {
                    adj = PREVIOUS_APP_ADJ;
                    schedGroup = SCHED_GROUP_BACKGROUND;
                    state.setCached(false);
                    state.setAdjType("previous");
                    if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
                        reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise adj to prev: " + app);
@@ -2193,7 +2181,6 @@ public class OomAdjuster {
                if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
                    reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise adj to backup: " + app);
                }
                state.setCached(false);
            }
            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
                procState = ActivityManager.PROCESS_STATE_BACKUP;
@@ -2247,7 +2234,6 @@ public class OomAdjuster {
                                reportOomAdjMessageLocked(TAG_OOM_ADJ,
                                        "Raise adj to started service: " + app);
                            }
                            state.setCached(false);
                        }
                    }
                    // If we have let the service slide into the background
@@ -2363,7 +2349,6 @@ public class OomAdjuster {
                    adj = FOREGROUND_APP_ADJ;
                    state.setCurRawAdj(adj);
                    schedGroup = SCHED_GROUP_DEFAULT;
                    state.setCached(false);
                    state.setAdjType("ext-provider");
                    state.setAdjTarget(cpr.name);
                    if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
@@ -2386,7 +2371,6 @@ public class OomAdjuster {
            if (adj > PREVIOUS_APP_ADJ) {
                adj = PREVIOUS_APP_ADJ;
                schedGroup = SCHED_GROUP_BACKGROUND;
                state.setCached(false);
                state.setAdjType("recent-provider");
                if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
                    reportOomAdjMessageLocked(TAG_OOM_ADJ,
@@ -2694,10 +2678,12 @@ public class OomAdjuster {
                    if (adj > clientAdj) {
                        adjType = "cch-bound-ui-services";
                    }
                    if (state.setCached(false, dryRun)) {

                    if (state.isCached() && dryRun) {
                        // Bail out early, as we only care about the return value for a dryrun.
                        return true;
                    }

                    clientAdj = adj;
                    clientProcState = procState;
                } else {
@@ -2782,12 +2768,14 @@ public class OomAdjuster {
                            newAdj = adj;
                        }
                    }

                    if (!cstate.isCached()) {
                        if (state.setCached(false, dryRun)) {
                        if (state.isCached() && dryRun) {
                            // Bail out early, as we only care about the return value for a dryrun.
                            return true;
                        }
                    }

                    if (adj >  newAdj) {
                        adj = newAdj;
                        if (state.setCurRawAdj(adj, dryRun)) {
@@ -2945,8 +2933,8 @@ public class OomAdjuster {
                        schedGroup = SCHED_GROUP_DEFAULT;
                    }
                }

                if (!dryRun) {
                    state.setCached(false);
                    state.setAdjType("service");
                    state.setAdjTypeCode(ActivityManager.RunningAppProcessInfo
                            .REASON_SERVICE_IN_USE);
@@ -2987,7 +2975,6 @@ public class OomAdjuster {
        }
        state.setCurCapability(capability);

        state.setEmpty(false);
        return updated;
    }

@@ -3077,7 +3064,8 @@ public class OomAdjuster {
                }
                adjType = "provider";
            }
            if (state.setCached(state.isCached() & cstate.isCached(), dryRun)) {

            if (state.isCached() && !cstate.isCached() && dryRun) {
                // Bail out early, as we only care about the return value for a dryrun.
                return true;
            }
@@ -3144,7 +3132,6 @@ public class OomAdjuster {
        }
        state.setCurCapability(capability);

        state.setEmpty(false);
        return false;
    }

@@ -3601,7 +3588,6 @@ public class OomAdjuster {
        state.setCurProcState(initialProcState);
        state.setCurRawProcState(initialProcState);
        state.setCurCapability(initialCapability);
        state.setCached(initialCached);

        state.setCurAdj(ProcessList.FOREGROUND_APP_ADJ);
        state.setCurRawAdj(ProcessList.FOREGROUND_APP_ADJ);
+0 −5
Original line number Diff line number Diff line
@@ -1122,11 +1122,6 @@ class ProcessRecord implements WindowProcessListener {
        mInFullBackup = inFullBackup;
    }

    @GuardedBy("mService")
    public void setCached(boolean cached) {
        mState.setCached(cached);
    }

    @Override
    @GuardedBy("mService")
    public boolean isCached() {
+18 −42
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package com.android.server.am;

import static android.app.ActivityManager.PROCESS_CAPABILITY_NONE;
import static android.app.ActivityManager.PROCESS_STATE_CACHED_EMPTY;
import static android.app.ActivityManager.PROCESS_STATE_NONEXISTENT;
import static android.app.ActivityManagerInternal.OOM_ADJ_REASON_UI_VISIBILITY;
import static android.app.ProcessMemoryState.HOSTING_COMPONENT_TYPE_ACTIVITY;
@@ -24,6 +25,7 @@ import static android.app.ProcessMemoryState.HOSTING_COMPONENT_TYPE_BROADCAST_RE
import static android.app.ProcessMemoryState.HOSTING_COMPONENT_TYPE_STARTED_SERVICE;

import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
import static com.android.server.am.ProcessList.CACHED_APP_MIN_ADJ;
import static com.android.server.am.ProcessRecord.TAG;

import android.annotation.ElapsedRealtimeLong;
@@ -282,18 +284,6 @@ final class ProcessStateRecord {
    @GuardedBy("mService")
    private long mLastTopTime = Long.MIN_VALUE;

    /**
     * Is this an empty background process?
     */
    @GuardedBy("mService")
    private boolean mEmpty;

    /**
     * Is this a cached process?
     */
    @GuardedBy("mService")
    private boolean mCached;

    /**
     * This is a system process, but not currently showing UI.
     */
@@ -395,7 +385,7 @@ final class ProcessStateRecord {
    private boolean mNoKillOnBgRestrictedAndIdle;

    /**
     * Last set value of {@link #mCached}.
     * Last set value of {@link #isCached()}.
     */
    @GuardedBy("mService")
    private boolean mSetCached;
@@ -408,7 +398,7 @@ final class ProcessStateRecord {

    /**
     * The last time when the {@link #mNoKillOnBgRestrictedAndIdle} is false and the
     * {@link #mCached} is true, and either the former state is flipping from true to false
     * {@link #isCached()} is true, and either the former state is flipping from true to false
     * when latter state is true, or the latter state is flipping from false to true when the
     * former state is false.
     */
@@ -445,6 +435,8 @@ final class ProcessStateRecord {
        VALUE_INVALID, // CACHED_COMPAT_CHANGE_USE_SHORT_FGS_USAGE_INTERACTION_TIME
    };

    @GuardedBy("mService")
    private String mCachedAdjType = null;
    @GuardedBy("mService")
    private int mCachedAdj = ProcessList.INVALID_ADJ;
    @GuardedBy("mService")
@@ -535,7 +527,7 @@ final class ProcessStateRecord {

    @GuardedBy(anyOf = {"mService", "mProcLock"})
    int getSetAdjWithServices() {
        if (mSetAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
        if (mSetAdj >= CACHED_APP_MIN_ADJ) {
            if (mHasStartedServices) {
                return ProcessList.SERVICE_B_ADJ;
            }
@@ -914,37 +906,14 @@ final class ProcessStateRecord {
        return mLastTopTime;
    }

    @GuardedBy("mService")
    void setEmpty(boolean empty) {
        mEmpty = empty;
    }

    @GuardedBy("mService")
    boolean isEmpty() {
        return mEmpty;
    }

    @GuardedBy("mService")
    void setCached(boolean cached) {
        setCached(cached, false);
    }

    /**
     * @return {@code true} if it's a dry run and it's going to uncache the process
     * if it was a real run.
     */
    @GuardedBy("mService")
    boolean setCached(boolean cached, boolean dryRun) {
        if (dryRun) {
            return mCached && !cached;
        }
        mCached = cached;
        return false;
        return mCurProcState >= PROCESS_STATE_CACHED_EMPTY;
    }

    @GuardedBy("mService")
    boolean isCached() {
        return mCached;
        return mCurAdj >= CACHED_APP_MIN_ADJ;
    }

    @GuardedBy("mService")
@@ -1041,6 +1010,7 @@ final class ProcessStateRecord {
        mCachedForegroundActivities = false;
        mCachedProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
        mCachedSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
        mCachedAdjType = null;
    }

    @GuardedBy("mService")
@@ -1152,6 +1122,7 @@ final class ProcessStateRecord {
        mCachedHasVisibleActivities = callback.mHasVisibleActivities ? VALUE_TRUE : VALUE_FALSE;
        mCachedProcState = callback.procState;
        mCachedSchedGroup = callback.schedGroup;
        mCachedAdjType = callback.mAdjType;

        if (mCachedAdj == ProcessList.VISIBLE_APP_ADJ) {
            mCachedAdj += minLayer;
@@ -1178,6 +1149,11 @@ final class ProcessStateRecord {
        return mCachedSchedGroup;
    }

    @GuardedBy("mService")
    String getCachedAdjType() {
        return mCachedAdjType;
    }

    @GuardedBy("mService")
    boolean shouldScheduleLikeTopApp() {
        return mScheduleLikeTopApp;
@@ -1381,8 +1357,8 @@ final class ProcessStateRecord {
            pw.print(prefix); pw.print("hasShownUi="); pw.print(mHasShownUi);
            pw.print(" pendingUiClean="); pw.println(mApp.mProfile.hasPendingUiClean());
        }
        pw.print(prefix); pw.print("cached="); pw.print(mCached);
        pw.print(" empty="); pw.println(mEmpty);
        pw.print(prefix); pw.print("cached="); pw.print(isCached());
        pw.print(" empty="); pw.println(isEmpty());
        if (mServiceB) {
            pw.print(prefix); pw.print("serviceb="); pw.print(mServiceB);
            pw.print(" serviceHighRam="); pw.println(mServiceHighRam);
+0 −1
Original line number Diff line number Diff line
@@ -751,7 +751,6 @@ public class CacheOomRankerTest {
        app.mState.setCurAdj(setAdj);
        app.setLastActivityTime(lastActivityTime);
        mPidToRss.put(app.getPid(), lastRss);
        app.mState.setCached(false);
        for (int i = 0; i < wentToForegroundCount; ++i) {
            app.mState.setSetProcState(ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
            app.mState.setSetProcState(ActivityManager.PROCESS_STATE_CACHED_RECENT);
+7 −6
Original line number Diff line number Diff line
@@ -470,6 +470,7 @@ public class MockingOomAdjusterTests {
        ProcessRecord app = spy(makeDefaultProcessRecord(MOCKAPP_PID, MOCKAPP_UID,
                MOCKAPP_PROCESSNAME, MOCKAPP_PACKAGENAME, true));
        app.mState.setCurRawAdj(CACHED_APP_MIN_ADJ);
        app.mState.setCurAdj(CACHED_APP_MIN_ADJ);
        doReturn(null).when(sService).getTopApp();
        sService.mWakefulness.set(PowerManagerInternal.WAKEFULNESS_AWAKE);
        updateOomAdj(app);
@@ -494,6 +495,8 @@ public class MockingOomAdjusterTests {
            field.set(callback, PROCESS_STATE_TOP);
            field = callback.getClass().getDeclaredField("schedGroup");
            field.set(callback, SCHED_GROUP_TOP_APP);
            field = callback.getClass().getDeclaredField("mAdjType");
            field.set(callback, "vis-activity");
            return 0;
        })).when(wpc).computeOomAdjFromActivities(
                any(WindowProcessController.ComputeOomAdjCallback.class));
@@ -501,6 +504,9 @@ public class MockingOomAdjusterTests {
        updateOomAdj(app);

        assertProcStates(app, PROCESS_STATE_TOP, VISIBLE_APP_ADJ, SCHED_GROUP_TOP_APP);
        assertFalse(app.mState.isCached());
        assertFalse(app.mState.isEmpty());
        assertEquals("vis-activity", app.mState.getAdjType());
    }

    @SuppressWarnings("GuardedBy")
@@ -871,8 +877,8 @@ public class MockingOomAdjusterTests {
    public void testUpdateOomAdj_DoOne_NonCachedToCached() {
        ProcessRecord app = spy(makeDefaultProcessRecord(MOCKAPP_PID, MOCKAPP_UID,
                MOCKAPP_PROCESSNAME, MOCKAPP_PACKAGENAME, false));
        app.mState.setCached(false);
        app.mState.setCurRawAdj(SERVICE_ADJ);
        app.mState.setCurAdj(SERVICE_ADJ);
        doReturn(null).when(sService).getTopApp();
        sService.mWakefulness.set(PowerManagerInternal.WAKEFULNESS_AWAKE);
        updateOomAdj(app);
@@ -2546,7 +2552,6 @@ public class MockingOomAdjusterTests {
        s.startRequested = true;
        s.lastActivity = now;

        app.mState.setCached(false);
        app.mServices.startService(s);
        app.mState.setHasShownUi(true);

@@ -2559,7 +2564,6 @@ public class MockingOomAdjusterTests {
        s2.startRequested = true;
        s2.lastActivity = now - sService.mConstants.MAX_SERVICE_INACTIVITY - 1;

        app2.mState.setCached(false);
        app2.mServices.startService(s2);
        app2.mState.setHasShownUi(false);

@@ -2577,7 +2581,6 @@ public class MockingOomAdjusterTests {

        assertProcStates(app, false, PROCESS_STATE_SERVICE, SERVICE_ADJ, "started-services");

        app.mState.setCached(false);
        app.mState.setSetProcState(PROCESS_STATE_NONEXISTENT);
        app.mState.setAdjType(null);
        app.mState.setSetAdj(UNKNOWN_ADJ);
@@ -2605,7 +2608,6 @@ public class MockingOomAdjusterTests {
        assertProcStates(app, false, PROCESS_STATE_SERVICE, SERVICE_ADJ, "started-services");
        assertProcStates(app2, true, PROCESS_STATE_SERVICE, cachedAdj1, "cch-started-services");

        app.mState.setCached(true);
        app.mState.setSetProcState(PROCESS_STATE_NONEXISTENT);
        app.mState.setAdjType(null);
        app.mState.setSetAdj(UNKNOWN_ADJ);
@@ -3035,7 +3037,6 @@ public class MockingOomAdjusterTests {
            state.setHasTopUi(mHasTopUi);
            state.setRunningRemoteAnimation(mRunningRemoteAnimation);
            state.setHasOverlayUi(mHasOverlayUi);
            state.setCached(mCached);
            state.setLastTopTime(mLastTopTime);
            state.setForcingToImportant(mForcingToImportant);
            services.setConnectionGroup(mConnectionGroup);
Loading