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

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

Run postUpdate on pending oom adjust updates for new OomAdjuster

Isolated process trimming happens as a part of the postUpdate step.
Service stops usual trigger a pending omm adjust update, so the isolated
process trim needs to happen on pending updates (which matches legacy
behavior)

Test: atest MockingOomAdjusterTests
Test: atest CtsStatsdAtomHostTestCases:AppExitHostTest
Fixes: 318574235
Change-Id: I4c29b852037526097d4b4994bc6575fe6925bb81
parent 342c33d3
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -1386,6 +1386,8 @@ public class OomAdjuster {
                        break;
                }

                // TODO: b/319163103 - limit isolated/sandbox trimming to just the processes
                //  evaluated in the current update.
                if (app.isolated && psr.numberOfRunningServices() <= 0
                        && app.getIsolatedEntryPoint() == null) {
                    // If this is an isolated process, there are no services
+1 −12
Original line number Diff line number Diff line
@@ -724,24 +724,13 @@ public class OomAdjusterModernImpl extends OomAdjuster {

        if (fullUpdate) {
            assignCachedAdjIfNecessary(mProcessList.getLruProcessesLOSP());
            postUpdateOomAdjInnerLSP(oomAdjReason, activeUids, now, nowElapsed, oldTime);
        } else {
            activeProcesses.clear();
            activeProcesses.addAll(targetProcesses);
            assignCachedAdjIfNecessary(activeProcesses);

            for (int  i = activeUids.size() - 1; i >= 0; i--) {
                final UidRecord uidRec = activeUids.valueAt(i);
                uidRec.forEachProcess(this::updateAppUidRecIfNecessaryLSP);
            }
            updateUidsLSP(activeUids, nowElapsed);

            for (int i = 0, size = targetProcesses.size(); i < size; i++) {
                applyOomAdjLSP(targetProcesses.valueAt(i), false, now, nowElapsed, oomAdjReason);
            }

            activeProcesses.clear();
        }
        postUpdateOomAdjInnerLSP(oomAdjReason, activeUids, now, nowElapsed, oldTime);
        targetProcesses.clear();

        if (startProfiling) {
+105 −0
Original line number Diff line number Diff line
@@ -80,10 +80,13 @@ import static org.mockito.Mockito.doCallRealMethod;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;

import android.app.ActivityManager;
import android.app.AppOpsManager;
import android.app.ApplicationExitInfo;
import android.app.IApplicationThread;
import android.app.IServiceConnection;
import android.content.ComponentName;
@@ -94,6 +97,7 @@ import android.content.pm.ServiceInfo;
import android.os.Build;
import android.os.IBinder;
import android.os.PowerManagerInternal;
import android.os.Process;
import android.os.SystemClock;
import android.os.UserHandle;
import android.platform.test.annotations.Presubmit;
@@ -148,6 +152,9 @@ public class MockingOomAdjusterTests {
    private static final String MOCKAPP5_PROCESSNAME = "test #5";
    private static final String MOCKAPP5_PACKAGENAME = "com.android.test.test5";
    private static final int MOCKAPP2_UID_OTHER = MOCKAPP2_UID + UserHandle.PER_USER_RANGE;
    private static final int MOCKAPP_ISOLATED_UID = Process.FIRST_ISOLATED_UID + 321;
    private static final String MOCKAPP_ISOLATED_PROCESSNAME = "isolated test #1";

    private static int sFirstCachedAdj = ProcessList.CACHED_APP_MIN_ADJ
                                          + ProcessList.CACHED_APP_IMPORTANCE_LEVELS;
    private static Context sContext;
@@ -285,6 +292,20 @@ public class MockingOomAdjusterTests {
        }
    }

    /**
     * Run updateOomAdjPendingTargetsLocked().
     * - enqueues all provided processes to the pending list and lru before running
     */
    @SuppressWarnings("GuardedBy")
    private void updateOomAdjPending(ProcessRecord... apps) {
        setProcessesToLru(apps);
        for (ProcessRecord app : apps) {
            sService.mOomAdjuster.enqueueOomAdjTargetLocked(app);
        }
        sService.mOomAdjuster.updateOomAdjPendingTargetsLocked(OOM_ADJ_REASON_NONE);
        sService.mProcessList.getLruProcessesLOSP().clear();
    }

    /**
     * Fix up the pointers in the {@link ProcessRecordNode#mApp}:
     * because we used the mokito spy objects all over the tests here, but the internal
@@ -2651,6 +2672,90 @@ public class MockingOomAdjusterTests {
        assertNotEquals(FOREGROUND_APP_ADJ, app.mState.getSetAdj());
    }

    @SuppressWarnings("GuardedBy")
    @Test
    public void testUpdateOomAdj_DoAll_Isolated_stopService() {
        ProcessRecord app = spy(makeDefaultProcessRecord(MOCKAPP_PID, MOCKAPP_ISOLATED_UID,
                MOCKAPP_ISOLATED_PROCESSNAME, MOCKAPP_PACKAGENAME, false));

        setProcessesToLru(app);
        ServiceRecord s = makeServiceRecord(app);
        s.startRequested = true;
        s.lastActivity = SystemClock.uptimeMillis();
        sService.mWakefulness.set(PowerManagerInternal.WAKEFULNESS_AWAKE);
        updateOomAdj();
        assertProcStates(app, PROCESS_STATE_SERVICE, SERVICE_ADJ, SCHED_GROUP_BACKGROUND);

        app.mServices.stopService(s);
        updateOomAdj();
        // isolated process should be killed immediately after service stop.
        verify(app).killLocked("isolated not needed", ApplicationExitInfo.REASON_OTHER,
                ApplicationExitInfo.SUBREASON_ISOLATED_NOT_NEEDED, true);
    }

    @SuppressWarnings("GuardedBy")
    @Test
    public void testUpdateOomAdj_DoPending_Isolated_stopService() {
        ProcessRecord app = spy(makeDefaultProcessRecord(MOCKAPP_PID, MOCKAPP_ISOLATED_UID,
                MOCKAPP_ISOLATED_PROCESSNAME, MOCKAPP_PACKAGENAME, false));

        ServiceRecord s = makeServiceRecord(app);
        s.startRequested = true;
        s.lastActivity = SystemClock.uptimeMillis();
        sService.mWakefulness.set(PowerManagerInternal.WAKEFULNESS_AWAKE);
        updateOomAdjPending(app);
        assertProcStates(app, PROCESS_STATE_SERVICE, SERVICE_ADJ, SCHED_GROUP_BACKGROUND);

        app.mServices.stopService(s);
        updateOomAdjPending(app);
        // isolated process should be killed immediately after service stop.
        verify(app).killLocked("isolated not needed", ApplicationExitInfo.REASON_OTHER,
                ApplicationExitInfo.SUBREASON_ISOLATED_NOT_NEEDED, true);
    }

    @SuppressWarnings("GuardedBy")
    @Test
    public void testUpdateOomAdj_DoAll_Isolated_stopServiceWithEntryPoint() {
        ProcessRecord app = spy(makeDefaultProcessRecord(MOCKAPP_PID, MOCKAPP_ISOLATED_UID,
                MOCKAPP_ISOLATED_PROCESSNAME, MOCKAPP_PACKAGENAME, false));
        app.setIsolatedEntryPoint("test");

        setProcessesToLru(app);
        ServiceRecord s = makeServiceRecord(app);
        s.startRequested = true;
        s.lastActivity = SystemClock.uptimeMillis();
        sService.mWakefulness.set(PowerManagerInternal.WAKEFULNESS_AWAKE);
        updateOomAdj();
        assertProcStates(app, PROCESS_STATE_SERVICE, SERVICE_ADJ, SCHED_GROUP_BACKGROUND);

        app.mServices.stopService(s);
        updateOomAdj();
        // isolated process with entry point should not be killed
        verify(app, never()).killLocked("isolated not needed", ApplicationExitInfo.REASON_OTHER,
                ApplicationExitInfo.SUBREASON_ISOLATED_NOT_NEEDED, true);
    }

    @SuppressWarnings("GuardedBy")
    @Test
    public void testUpdateOomAdj_DoPending_Isolated_stopServiceWithEntryPoint() {
        ProcessRecord app = spy(makeDefaultProcessRecord(MOCKAPP_PID, MOCKAPP_ISOLATED_UID,
                MOCKAPP_ISOLATED_PROCESSNAME, MOCKAPP_PACKAGENAME, false));
        app.setIsolatedEntryPoint("test");

        ServiceRecord s = makeServiceRecord(app);
        s.startRequested = true;
        s.lastActivity = SystemClock.uptimeMillis();
        sService.mWakefulness.set(PowerManagerInternal.WAKEFULNESS_AWAKE);
        updateOomAdjPending(app);
        assertProcStates(app, PROCESS_STATE_SERVICE, SERVICE_ADJ, SCHED_GROUP_BACKGROUND);

        app.mServices.stopService(s);
        updateOomAdjPending(app);
        // isolated process with entry point should not be killed
        verify(app, never()).killLocked("isolated not needed", ApplicationExitInfo.REASON_OTHER,
                ApplicationExitInfo.SUBREASON_ISOLATED_NOT_NEEDED, true);
    }

    private ProcessRecord makeDefaultProcessRecord(int pid, int uid, String processName,
            String packageName, boolean hasShownUi) {
        long now = SystemClock.uptimeMillis();