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

Commit f0c110a1 authored by Michael Wachenschwanz's avatar Michael Wachenschwanz Committed by Android (Google) Code Review
Browse files

Merge changes I5fba8c48,I4c29b852 into main

* changes:
  Reattach OomAdjuster rewrite flag (attempt 2)
  Run postUpdate on pending oom adjust updates for new OomAdjuster
parents 540fe889 6857ad9b
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -243,7 +243,7 @@ final class ActivityManagerConstants extends ContentObserver {
    /**
     * The default value to {@link #KEY_ENABLE_NEW_OOMADJ}.
     */
    private static final boolean DEFAULT_ENABLE_NEW_OOM_ADJ = false;
    private static final boolean DEFAULT_ENABLE_NEW_OOM_ADJ = Flags.oomadjusterCorrectnessRewrite();

    /**
     * Same as {@link TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_NOT_ALLOWED}
+2 −0
Original line number Diff line number Diff line
@@ -1385,6 +1385,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();