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

Commit c4ce739e authored by Yasin Kilicdere's avatar Yasin Kilicdere
Browse files

Fix prev expire flow in OomAdjuster.

When an app is sent to background, it gets prev oom score with all its
bindings (except the ones bound with the BIND_WAIVE_PRIORITY flag).
Then there are three ways the app loses this prev score.

1. Another app comes top, and then goes background,
   taking away the prev status.
2. After 60 seconds, prev status expires.
3. App comes foreground again. (This one is not relevant to the topic)

Flow 1 and 2 have different results. When 1 happens, all the processes
get chh+X with respect to their position in the process LRU list. But
when 2 happens, the processes with prev score all get cch. And this
causes a random killing order in LMKD.

This CL makes "prev expire" flow similar to "another app grabbing prev"
flow.

Bug: 357844136
Change-Id: I9efa3b3855d8d9ddb29d9b3358cb648d38099204
Test: atest MockingOomAdjusterTests#testUpdateOomAdj_DoAll_PreviousApp
Flag: EXEMPT bugfix
parent cecce414
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -1201,6 +1201,7 @@ public class OomAdjuster {
                    >= UNKNOWN_ADJ) {
                    final ProcessServiceRecord psr = app.mServices;
                    switch (state.getCurProcState()) {
                        case PROCESS_STATE_LAST_ACTIVITY:
                        case PROCESS_STATE_CACHED_ACTIVITY:
                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
                        case ActivityManager.PROCESS_STATE_CACHED_RECENT:
@@ -2180,7 +2181,6 @@ public class OomAdjuster {
                procState = PROCESS_STATE_LAST_ACTIVITY;
                schedGroup = SCHED_GROUP_BACKGROUND;
                state.setAdjType("previous-expired");
                adj = CACHED_APP_MIN_ADJ;
                if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
                    reportOomAdjMessageLocked(TAG_OOM_ADJ, "Expire prev adj: " + app);
                }
+44 −0
Original line number Diff line number Diff line
@@ -46,6 +46,7 @@ import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentat

import static com.android.server.am.ActivityManagerService.FOLLOW_UP_OOMADJUSTER_UPDATE_MSG;
import static com.android.server.am.ProcessList.BACKUP_APP_ADJ;
import static com.android.server.am.ProcessList.CACHED_APP_IMPORTANCE_LEVELS;
import static com.android.server.am.ProcessList.CACHED_APP_MAX_ADJ;
import static com.android.server.am.ProcessList.CACHED_APP_MIN_ADJ;
import static com.android.server.am.ProcessList.FOREGROUND_APP_ADJ;
@@ -842,6 +843,49 @@ public class MockingOomAdjusterTests {
                followUpTimeCaptor.capture());
    }

    @SuppressWarnings("GuardedBy")
    @Test
    public void testUpdateOomAdj_DoAll_PreviousApp() {
        final int numberOfApps = 15;
        final ProcessRecord[] apps = new ProcessRecord[numberOfApps];
        for (int i = 0; i < numberOfApps; i++) {
            apps[i] = spy(makeDefaultProcessRecord(MOCKAPP_PID + i, MOCKAPP_UID + i,
                    MOCKAPP_PROCESSNAME + i, MOCKAPP_PACKAGENAME + i, true));
            final WindowProcessController wpc = apps[i].getWindowProcessController();
            doReturn(true).when(wpc).isPreviousProcess();
            doReturn(true).when(wpc).hasActivities();
        }
        mService.mWakefulness.set(PowerManagerInternal.WAKEFULNESS_AWAKE);
        setProcessesToLru(apps);
        mService.mOomAdjuster.updateOomAdjLocked(OOM_ADJ_REASON_NONE);

        for (int i = 0; i < numberOfApps; i++) {
            assertProcStates(apps[i], PROCESS_STATE_LAST_ACTIVITY, PREVIOUS_APP_ADJ,
                    SCHED_GROUP_BACKGROUND, "previous");
        }

        if (!Flags.followUpOomadjUpdates()) return;

        for (int i = 0; i < numberOfApps; i++) {
            final ArgumentCaptor<Long> followUpTimeCaptor = ArgumentCaptor.forClass(Long.class);
            verify(mService.mHandler).sendEmptyMessageAtTime(eq(FOLLOW_UP_OOMADJUSTER_UPDATE_MSG),
                    followUpTimeCaptor.capture());
            mInjector.jumpUptimeAheadTo(followUpTimeCaptor.getValue());
        }

        mService.mOomAdjuster.updateOomAdjFollowUpTargetsLocked();

        for (int i = 0; i < numberOfApps; i++) {
            final int mruIndex = numberOfApps - i - 1;
            int expectedAdj = CACHED_APP_MIN_ADJ + (mruIndex * 2 * CACHED_APP_IMPORTANCE_LEVELS);
            if (expectedAdj > CACHED_APP_MAX_ADJ) {
                expectedAdj = CACHED_APP_MAX_ADJ;
            }
            assertProcStates(apps[i], PROCESS_STATE_LAST_ACTIVITY, expectedAdj,
                    SCHED_GROUP_BACKGROUND, "previous-expired");
        }
    }

    @SuppressWarnings("GuardedBy")
    @Test
    public void testUpdateOomAdj_DoOne_Backup() {