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

Commit 15038d0b authored by Michael Wachenschwanz's avatar Michael Wachenschwanz
Browse files

Make sure shouldNotFreeze state change correctly triggers updates.

The shouldNotFreeze state is propagated across bindings, so anything
that can grant a process the shouldNotFreeze state should not be skipped
by ServiceBindingOomAdjPolicy.

Flag: com.android.server.am.unfreeze_bind_policy_fix
Fixes: 375691778
Test: atest ServiceBindingOomAdjPolicyTest
Change-Id: I3eec63893ca0cc14ade1b46fecabbadf45eb2cd7
parent eec846d9
Loading
Loading
Loading
Loading
+85 −37
Original line number Diff line number Diff line
@@ -4068,8 +4068,9 @@ public class OomAdjuster {
    }

    /**
     * Evaluate the service connection, return {@code true} if the client will change the state
     * of the service host process by the given connection.
     * Evaluate the service connection, return {@code true} if the client will change any state
     * (ie. ProcessState, oomAdj, capability, etc) of the service host process by the given
     * connection.
     */
    @GuardedBy("mService")
    boolean evaluateServiceConnectionAdd(ProcessRecord client, ProcessRecord app,
@@ -4077,21 +4078,41 @@ public class OomAdjuster {
        if (evaluateConnectionPrelude(client, app)) {
            return true;
        }
        if (app.getSetAdj() <= client.getSetAdj()
                && app.getSetProcState() <= client.getSetProcState()
                && ((app.getSetCapability() & client.getSetCapability())
                        == client.getSetCapability()
                        || cr.notHasFlag(Context.BIND_INCLUDE_CAPABILITIES
                                | Context.BIND_BYPASS_USER_NETWORK_RESTRICTIONS))) {
            // The service host process has better states than the client, so no change.
            return false;
        }

        boolean needDryRun = false;
        if (app.getSetAdj() > client.getSetAdj()) {
            // The connection might elevate the importance of the service's oom adj score.
            needDryRun = true;
        } else if (app.getSetProcState() > client.getSetProcState()) {
            // The connection might elevate the importance of the service's process state.
            needDryRun = true;
        } else if (cr.hasFlag(Context.BIND_INCLUDE_CAPABILITIES
                            | Context.BIND_BYPASS_USER_NETWORK_RESTRICTIONS)
                && (app.getSetCapability() & client.getSetCapability())
                        != client.getSetCapability()) {
            // The connection might elevate the importance of the service's capabilities.
            needDryRun = true;
        } else if (Flags.unfreezeBindPolicyFix()
                && cr.hasFlag(Context.BIND_WAIVE_PRIORITY
                            | Context.BIND_ALLOW_OOM_MANAGEMENT)) {
            // These bind flags can grant the shouldNotFreeze state to the service.
            needDryRun = true;
        } else if (Flags.unfreezeBindPolicyFix()
                && client.mOptRecord.shouldNotFreeze()
                && !app.mOptRecord.shouldNotFreeze()) {
            // The shouldNotFreeze state can be propagated and needs to be checked.
            needDryRun = true;
        }

        if (needDryRun) {
            // Take a dry run of the computeServiceHostOomAdjLSP, this would't be expensive
            // since it's only evaluating one service connection.
            return computeServiceHostOomAdjLSP(cr, app, client, mInjector.getUptimeMillis(),
                    mService.getTopApp(), false, false, false, OOM_ADJ_REASON_NONE,
                    CACHED_APP_MIN_ADJ, false, true /* dryRun */);
        }
        return false;
    }

    @GuardedBy("mService")
    boolean evaluateServiceConnectionRemoval(ProcessRecord client, ProcessRecord app,
@@ -4100,17 +4121,26 @@ public class OomAdjuster {
            return true;
        }

        if (app.getSetAdj() < client.getSetAdj()
                && app.getSetProcState() < client.getSetProcState()) {
            // The service host process has better states than the client.
            if (((app.getSetCapability() & client.getSetCapability()) == PROCESS_CAPABILITY_NONE)
                    || cr.notHasFlag(Context.BIND_INCLUDE_CAPABILITIES
                            | Context.BIND_BYPASS_USER_NETWORK_RESTRICTIONS)) {
                // The service host app doesn't get any capabilities from the client.
                return false;
            }
        }
        if (app.getSetAdj() >= client.getSetAdj()) {
            return true;
        } else if (app.getSetProcState() >= client.getSetProcState()) {
            return true;
        } else if (cr.hasFlag(Context.BIND_INCLUDE_CAPABILITIES
                            | Context.BIND_BYPASS_USER_NETWORK_RESTRICTIONS)
                && (app.getSetCapability() & client.getSetCapability())
                            != PROCESS_CAPABILITY_NONE) {
            return true;
        } else if (Flags.unfreezeBindPolicyFix()
                && cr.hasFlag(Context.BIND_WAIVE_PRIORITY
                            | Context.BIND_ALLOW_OOM_MANAGEMENT)) {
            return true;
        } else if (Flags.unfreezeBindPolicyFix()
                && app.mOptRecord.shouldNotFreeze()
                && client.mOptRecord.shouldNotFreeze()) {
            // Process has shouldNotFreeze and it could have gotten it from the client.
            return true;
        }
        return false;
    }

    @GuardedBy("mService")
@@ -4118,29 +4148,47 @@ public class OomAdjuster {
        if (evaluateConnectionPrelude(client, app)) {
            return true;
        }
        if (app.getSetAdj() <= client.getSetAdj()
                && app.getSetProcState() <= client.getSetProcState()) {
            // The provider host process has better states than the client, so no change.
            return false;

        boolean needDryRun = false;
        if (app.getSetAdj() > client.getSetAdj()) {
            needDryRun = true;
        } else if (app.getSetProcState() > client.getSetProcState()) {
            needDryRun = true;
        } else if (Flags.unfreezeBindPolicyFix()
                && client.mOptRecord.shouldNotFreeze()
                && !app.mOptRecord.shouldNotFreeze()) {
            needDryRun = true;
        }

        if (needDryRun) {
            return computeProviderHostOomAdjLSP(null, app, client, mInjector.getUptimeMillis(),
                mService.getTopApp(), false, false, false, OOM_ADJ_REASON_NONE, CACHED_APP_MIN_ADJ,
                    mService.getTopApp(), false, false, false, OOM_ADJ_REASON_NONE,
                    CACHED_APP_MIN_ADJ,
                    false, true /* dryRun */);
        }
        return false;
    }

    @GuardedBy("mService")
    boolean evaluateProviderConnectionRemoval(ProcessRecord client, ProcessRecord app) {
        if (evaluateConnectionPrelude(client, app)) {
            return true;
        }
        if (app.getSetAdj() < client.getSetAdj()
                && app.getSetProcState() < client.getSetProcState()) {
            // The provider host process has better states than the client, so no change.
            return false;
        }

        if (app.getSetAdj() >= client.getSetAdj()) {
            return true;
        } else if (app.getSetProcState() >= client.getSetProcState()) {
            return true;
        } else if (Flags.unfreezeBindPolicyFix()
                && app.mOptRecord.shouldNotFreeze()
                && client.mOptRecord.shouldNotFreeze()) {
            // Process has shouldNotFreeze and it could have gotten it from the client.
            return true;
        }

        return false;
    }

    private boolean evaluateConnectionPrelude(ProcessRecord client, ProcessRecord app) {
        if (client == null || app == null) {
            return true;
+6 −2
Original line number Diff line number Diff line
@@ -18,8 +18,8 @@ package com.android.server.am;

import android.annotation.IntDef;
import android.annotation.UptimeMillisLong;
import android.app.ActivityManagerInternal.OomAdjReason;
import android.app.ActivityManagerInternal.FrozenProcessListener;
import android.app.ActivityManagerInternal.OomAdjReason;
import android.util.Pair;
import android.util.TimeUtils;

@@ -338,8 +338,12 @@ final class ProcessCachedOptimizerRecord {
    boolean setShouldNotFreeze(boolean shouldNotFreeze, boolean dryRun,
            @ShouldNotFreezeReason int reason, int adjSeq) {
        if (dryRun) {
            if (Flags.unfreezeBindPolicyFix()) {
                return mShouldNotFreeze != shouldNotFreeze;
            } else {
                return mFrozen && !shouldNotFreeze;
            }
        }
        if (Flags.traceUpdateAppFreezeStateLsp()) {
            if (shouldNotFreeze) {
                reason &= ~SHOULD_NOT_FREEZE_REASON_NONE;
+10 −0
Original line number Diff line number Diff line
@@ -241,3 +241,13 @@ flag {
    is_fixed_read_only: true
    bug: "369487976"
}

flag {
    name: "unfreeze_bind_policy_fix"
    namespace: "backstage_power"
    description: "Make sure shouldNotFreeze state change correctly triggers updates."
    bug: "375691778"
    metadata {
        purpose: PURPOSE_BUGFIX
    }
}
 No newline at end of file
+269 −0
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import static android.app.ActivityManager.PROCESS_STATE_CACHED_EMPTY;
import static android.app.ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
import static android.app.ActivityManager.PROCESS_STATE_HOME;
import static android.app.ActivityManager.PROCESS_STATE_SERVICE;
import static android.content.Context.BIND_ALLOW_OOM_MANAGEMENT;
import static android.content.Context.BIND_AUTO_CREATE;
import static android.content.Context.BIND_INCLUDE_CAPABILITIES;
import static android.content.Context.BIND_WAIVE_PRIORITY;
@@ -29,6 +30,7 @@ import static android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_SYSTEM_EXEM
import static android.os.UserHandle.USER_SYSTEM;
import static android.platform.test.flag.junit.SetFlagsRule.DefaultInitValueType.DEVICE_DEFAULT;

import static com.android.server.am.ProcessCachedOptimizerRecord.SHOULD_NOT_FREEZE_REASON_NONE;
import static com.android.server.am.ProcessList.CACHED_APP_MIN_ADJ;
import static com.android.server.am.ProcessList.HOME_APP_ADJ;
import static com.android.server.am.ProcessList.PERCEPTIBLE_APP_ADJ;
@@ -63,6 +65,10 @@ import android.os.Handler;
import android.os.HandlerThread;
import android.os.IBinder;
import android.platform.test.annotations.Presubmit;
import android.platform.test.annotations.RequiresFlagsDisabled;
import android.platform.test.annotations.RequiresFlagsEnabled;
import android.platform.test.flag.junit.CheckFlagsRule;
import android.platform.test.flag.junit.DeviceFlagsValueProvider;
import android.platform.test.flag.junit.SetFlagsRule;

import androidx.test.platform.app.InstrumentationRegistry;
@@ -114,6 +120,8 @@ public final class ServiceBindingOomAdjPolicyTest {
    public final ServiceThreadRule mServiceThreadRule = new ServiceThreadRule();
    @Rule
    public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(DEVICE_DEFAULT);
    @Rule
    public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule();

    private Context mContext;
    private HandlerThread mHandlerThread;
@@ -317,6 +325,256 @@ public final class ServiceBindingOomAdjPolicyTest {
    }

    @Test
    @RequiresFlagsEnabled(com.android.server.am.Flags.FLAG_UNFREEZE_BIND_POLICY_FIX)
    public void testServiceDistinctBindingOomAdjShouldNotFreeze() throws Exception {
        // Enable the flags.
        mSetFlagsRule.enableFlags(Flags.FLAG_SERVICE_BINDING_OOM_ADJ_POLICY);

        // Verify that there should be at least 1 oom adj update
        // because the shouldNotFreeze state needs to be propagated.
        performTestServiceDistinctBindingOomAdj(TEST_APP1_PID, TEST_APP1_UID,
                PROCESS_STATE_FOREGROUND_SERVICE, PERCEPTIBLE_APP_ADJ,
                PROCESS_CAPABILITY_NONE, TEST_APP1_NAME,
                (app) -> {
                    this.setHasForegroundServices(app);
                    this.setAllowListed(app);
                },
                TEST_APP2_PID, TEST_APP2_UID, PROCESS_STATE_HOME,
                HOME_APP_ADJ, PROCESS_CAPABILITY_NONE, TEST_APP2_NAME, TEST_SERVICE2_NAME,
                this::setHomeProcess,
                BIND_AUTO_CREATE,
                atLeastOnce(), atLeastOnce());

        // Verify that there should be at least 1 oom adj update
        // because the shouldNotFreeze state needs to be propagated.
        performTestServiceDistinctBindingOomAdj(TEST_APP1_PID, TEST_APP1_UID,
                PROCESS_STATE_HOME, HOME_APP_ADJ, PROCESS_CAPABILITY_NONE, TEST_APP1_NAME,
                (app) -> {
                    this.setHomeProcess(app);
                    this.setAllowListed(app);
                },
                TEST_APP2_PID, TEST_APP2_UID, PROCESS_STATE_FOREGROUND_SERVICE,
                PERCEPTIBLE_APP_ADJ, PROCESS_CAPABILITY_NONE, TEST_APP2_NAME, TEST_SERVICE2_NAME,
                this::setHasForegroundServices,
                BIND_AUTO_CREATE,
                atLeastOnce(), atLeastOnce());

        // Verify that there should be at least 1 oom adj update
        // because the client is more important (regardless of shouldNotFreeze state).
        performTestServiceDistinctBindingOomAdj(TEST_APP1_PID, TEST_APP1_UID,
                PROCESS_STATE_FOREGROUND_SERVICE, PERCEPTIBLE_APP_ADJ,
                PROCESS_CAPABILITY_NONE, TEST_APP1_NAME,
                (app) -> {
                    this.setHasForegroundServices(app);
                    this.setAllowListed(app);
                },
                TEST_APP2_PID, TEST_APP2_UID, PROCESS_STATE_HOME,
                HOME_APP_ADJ, PROCESS_CAPABILITY_NONE, TEST_APP2_NAME, TEST_SERVICE2_NAME,
                (app) -> {
                    this.setHomeProcess(app);
                    this.setAllowListed(app);
                },
                BIND_AUTO_CREATE,
                atLeastOnce(), atLeastOnce());

        // Verify that there should be 0 oom adj update for binding
        // because setShouldNotFreeze is already set
        // but for the unbinding must update in case the binding could be the source of the
        // shouldNotFreeze.
        performTestServiceDistinctBindingOomAdj(TEST_APP1_PID, TEST_APP1_UID,
                PROCESS_STATE_HOME, HOME_APP_ADJ, PROCESS_CAPABILITY_NONE, TEST_APP1_NAME,
                (app) -> {
                    this.setHomeProcess(app);
                    this.setAllowListed(app);
                },
                TEST_APP2_PID, TEST_APP2_UID, PROCESS_STATE_FOREGROUND_SERVICE,
                PERCEPTIBLE_APP_ADJ, PROCESS_CAPABILITY_NONE, TEST_APP2_NAME, TEST_SERVICE2_NAME,
                (app) -> {
                    this.setHasForegroundServices(app);
                    this.setAllowListed(app);
                },
                BIND_AUTO_CREATE,
                never(), atLeastOnce());


        // Disable the flags.
        mSetFlagsRule.disableFlags(Flags.FLAG_SERVICE_BINDING_OOM_ADJ_POLICY);

        // Verify that there should be at least 1 oom adj update
        // because the client is more important.
        performTestServiceDistinctBindingOomAdj(TEST_APP1_PID, TEST_APP1_UID,
                PROCESS_STATE_FOREGROUND_SERVICE, PERCEPTIBLE_APP_ADJ,
                PROCESS_CAPABILITY_NONE, TEST_APP1_NAME,
                (app) -> {
                    this.setHasForegroundServices(app);
                    this.setAllowListed(app);
                },
                TEST_APP2_PID, TEST_APP2_UID, PROCESS_STATE_HOME,
                HOME_APP_ADJ, PROCESS_CAPABILITY_NONE, TEST_APP2_NAME, TEST_SERVICE2_NAME,
                this::setHomeProcess,
                BIND_AUTO_CREATE,
                atLeastOnce(), atLeastOnce());
    }

    @Test
    @RequiresFlagsEnabled(com.android.server.am.Flags.FLAG_UNFREEZE_BIND_POLICY_FIX)
    public void testServiceDistinctBindingOomAdjAllowOomManagement() throws Exception {
        // Enable the flags.
        mSetFlagsRule.enableFlags(Flags.FLAG_SERVICE_BINDING_OOM_ADJ_POLICY);

        // Verify that there should be at least 1 oom adj update
        // because BIND_ALLOW_OOM_MANAGEMENT sets the shouldNotFreeze state which needs to be
        // propagated.
        performTestServiceDistinctBindingOomAdj(TEST_APP1_PID, TEST_APP1_UID,
                PROCESS_STATE_FOREGROUND_SERVICE, PERCEPTIBLE_APP_ADJ,
                PROCESS_CAPABILITY_NONE, TEST_APP1_NAME,
                this::setHasForegroundServices,
                TEST_APP2_PID, TEST_APP2_UID, PROCESS_STATE_HOME,
                HOME_APP_ADJ, PROCESS_CAPABILITY_NONE, TEST_APP2_NAME, TEST_SERVICE2_NAME,
                this::setHomeProcess,
                BIND_AUTO_CREATE | BIND_ALLOW_OOM_MANAGEMENT,
                atLeastOnce(), atLeastOnce());

        // Verify that there should be at least 1 oom adj update
        // because BIND_ALLOW_OOM_MANAGEMENT sets the shouldNotFreeze state which needs to be
        // propagated.
        performTestServiceDistinctBindingOomAdj(TEST_APP1_PID, TEST_APP1_UID,
                PROCESS_STATE_HOME, HOME_APP_ADJ, PROCESS_CAPABILITY_NONE, TEST_APP1_NAME,
                this::setHomeProcess,
                TEST_APP2_PID, TEST_APP2_UID, PROCESS_STATE_FOREGROUND_SERVICE,
                PERCEPTIBLE_APP_ADJ, PROCESS_CAPABILITY_NONE, TEST_APP2_NAME, TEST_SERVICE2_NAME,
                this::setHasForegroundServices,
                BIND_AUTO_CREATE | BIND_ALLOW_OOM_MANAGEMENT,
                atLeastOnce(), atLeastOnce());

        // Verify that there should be at least 1 oom adj update
        // because the client is more important (regardless of BIND_ALLOW_OOM_MANAGEMENT).
        performTestServiceDistinctBindingOomAdj(TEST_APP1_PID, TEST_APP1_UID,
                PROCESS_STATE_FOREGROUND_SERVICE, PERCEPTIBLE_APP_ADJ,
                PROCESS_CAPABILITY_NONE, TEST_APP1_NAME,
                this::setHasForegroundServices,
                TEST_APP2_PID, TEST_APP2_UID, PROCESS_STATE_HOME,
                HOME_APP_ADJ, PROCESS_CAPABILITY_NONE, TEST_APP2_NAME, TEST_SERVICE2_NAME,
                (app) -> {
                    this.setHomeProcess(app);
                    this.setAllowListed(app);
                },
                BIND_AUTO_CREATE | BIND_ALLOW_OOM_MANAGEMENT,
                atLeastOnce(), atLeastOnce());

        // Verify that there should be 0 oom adj update for binding
        // because setShouldNotFreeze is already set
        // but for the unbinding must update in case the BIND_ALLOW_OOM_MANAGEMENT maintaining the
        // shouldNotFreeze.
        performTestServiceDistinctBindingOomAdj(TEST_APP1_PID, TEST_APP1_UID,
                PROCESS_STATE_HOME, HOME_APP_ADJ, PROCESS_CAPABILITY_NONE, TEST_APP1_NAME,
                this::setHomeProcess,
                TEST_APP2_PID, TEST_APP2_UID, PROCESS_STATE_FOREGROUND_SERVICE,
                PERCEPTIBLE_APP_ADJ, PROCESS_CAPABILITY_NONE, TEST_APP2_NAME, TEST_SERVICE2_NAME,
                (app) -> {
                    this.setHasForegroundServices(app);
                    this.setAllowListed(app);
                },
                BIND_AUTO_CREATE | BIND_ALLOW_OOM_MANAGEMENT,
                never(), atLeastOnce());


        // Disable the flags.
        mSetFlagsRule.disableFlags(Flags.FLAG_SERVICE_BINDING_OOM_ADJ_POLICY);

        // Verify that there should be at least 1 oom adj update
        // because the client is more important.
        performTestServiceDistinctBindingOomAdj(TEST_APP1_PID, TEST_APP1_UID,
                PROCESS_STATE_FOREGROUND_SERVICE, PERCEPTIBLE_APP_ADJ,
                PROCESS_CAPABILITY_NONE, TEST_APP1_NAME,
                this::setHasForegroundServices,
                TEST_APP2_PID, TEST_APP2_UID, PROCESS_STATE_HOME,
                HOME_APP_ADJ, PROCESS_CAPABILITY_NONE, TEST_APP2_NAME, TEST_SERVICE2_NAME,
                this::setHomeProcess,
                BIND_AUTO_CREATE | BIND_ALLOW_OOM_MANAGEMENT,
                atLeastOnce(), atLeastOnce());
    }

    @Test
    @RequiresFlagsEnabled(com.android.server.am.Flags.FLAG_UNFREEZE_BIND_POLICY_FIX)
    public void testServiceDistinctBindingOomAdjWaivePriority_propagateUnfreeze() throws Exception {
        // Enable the flags.
        mSetFlagsRule.enableFlags(Flags.FLAG_SERVICE_BINDING_OOM_ADJ_POLICY);

        // Verify that there should be at least 1 oom adj update
        // because BIND_WAIVE_PRIORITY sets the shouldNotFreeze state which needs to be propagated.
        performTestServiceDistinctBindingOomAdj(TEST_APP1_PID, TEST_APP1_UID,
                PROCESS_STATE_FOREGROUND_SERVICE, PERCEPTIBLE_APP_ADJ,
                PROCESS_CAPABILITY_NONE, TEST_APP1_NAME,
                this::setHasForegroundServices,
                TEST_APP2_PID, TEST_APP2_UID, PROCESS_STATE_HOME,
                HOME_APP_ADJ, PROCESS_CAPABILITY_NONE, TEST_APP2_NAME, TEST_SERVICE2_NAME,
                this::setHomeProcess,
                BIND_AUTO_CREATE | BIND_WAIVE_PRIORITY,
                atLeastOnce(), atLeastOnce());

        // Verify that there should be at least 1 oom adj update
        // because BIND_WAIVE_PRIORITY sets the shouldNotFreeze state which needs to be propagated.
        performTestServiceDistinctBindingOomAdj(TEST_APP1_PID, TEST_APP1_UID,
                PROCESS_STATE_HOME, HOME_APP_ADJ, PROCESS_CAPABILITY_NONE, TEST_APP1_NAME,
                this::setHomeProcess,
                TEST_APP2_PID, TEST_APP2_UID, PROCESS_STATE_FOREGROUND_SERVICE,
                PERCEPTIBLE_APP_ADJ, PROCESS_CAPABILITY_NONE, TEST_APP2_NAME, TEST_SERVICE2_NAME,
                this::setHasForegroundServices,
                BIND_AUTO_CREATE | BIND_WAIVE_PRIORITY,
                atLeastOnce(), atLeastOnce());

        // Verify that there should be 0 oom adj update for binding
        // because setShouldNotFreeze is already set
        // but for the unbinding, because client is better than service, we can't skip it safely.
        performTestServiceDistinctBindingOomAdj(TEST_APP1_PID, TEST_APP1_UID,
                PROCESS_STATE_FOREGROUND_SERVICE, PERCEPTIBLE_APP_ADJ,
                PROCESS_CAPABILITY_NONE, TEST_APP1_NAME,
                this::setHasForegroundServices,
                TEST_APP2_PID, TEST_APP2_UID, PROCESS_STATE_HOME,
                HOME_APP_ADJ, PROCESS_CAPABILITY_NONE, TEST_APP2_NAME, TEST_SERVICE2_NAME,
                (app) -> {
                    this.setHomeProcess(app);
                    this.setAllowListed(app);
                },
                BIND_AUTO_CREATE | BIND_WAIVE_PRIORITY,
                never(), atLeastOnce());

        // Verify that there should be 0 oom adj update for binding
        // because setShouldNotFreeze is already set
        // but for the unbinding must update in case the BIND_WAIVE_PRIORITY maintaining the
        // shouldNotFreeze.
        performTestServiceDistinctBindingOomAdj(TEST_APP1_PID, TEST_APP1_UID,
                PROCESS_STATE_HOME, HOME_APP_ADJ, PROCESS_CAPABILITY_NONE, TEST_APP1_NAME,
                this::setHomeProcess,
                TEST_APP2_PID, TEST_APP2_UID, PROCESS_STATE_FOREGROUND_SERVICE,
                PERCEPTIBLE_APP_ADJ, PROCESS_CAPABILITY_NONE, TEST_APP2_NAME, TEST_SERVICE2_NAME,
                (app) -> {
                    this.setHasForegroundServices(app);
                    this.setAllowListed(app);
                },
                BIND_AUTO_CREATE | BIND_WAIVE_PRIORITY,
                never(), atLeastOnce());


        // Disable the flags.
        mSetFlagsRule.disableFlags(Flags.FLAG_SERVICE_BINDING_OOM_ADJ_POLICY);

        // Verify that there should be at least 1 oom adj update
        // because the client is more important.
        performTestServiceDistinctBindingOomAdj(TEST_APP1_PID, TEST_APP1_UID,
                PROCESS_STATE_FOREGROUND_SERVICE, PERCEPTIBLE_APP_ADJ,
                PROCESS_CAPABILITY_NONE, TEST_APP1_NAME,
                this::setHasForegroundServices,
                TEST_APP2_PID, TEST_APP2_UID, PROCESS_STATE_HOME,
                HOME_APP_ADJ, PROCESS_CAPABILITY_NONE, TEST_APP2_NAME, TEST_SERVICE2_NAME,
                this::setHomeProcess,
                BIND_AUTO_CREATE | BIND_WAIVE_PRIORITY,
                atLeastOnce(), atLeastOnce());
    }

    @Test
    @RequiresFlagsDisabled(com.android.server.am.Flags.FLAG_UNFREEZE_BIND_POLICY_FIX)
    public void testServiceDistinctBindingOomAdjWaivePriority() throws Exception {
        // Enable the flags.
        mSetFlagsRule.enableFlags(Flags.FLAG_SERVICE_BINDING_OOM_ADJ_POLICY);
@@ -526,6 +784,15 @@ public final class ServiceBindingOomAdjPolicyTest {
        doReturn(true).when(wpc).isHomeProcess();
    }

    @SuppressWarnings("GuardedBy")
    private void setAllowListed(ProcessRecord app) {
        final UidRecord uidRec = mock(UidRecord.class);
        app.setUidRecord(uidRec);
        doReturn(true).when(uidRec).isCurAllowListed();

        app.mOptRecord.setShouldNotFreeze(true, SHOULD_NOT_FREEZE_REASON_NONE, 1234);
    }

    @SuppressWarnings("GuardedBy")
    private ProcessRecord addProcessRecord(int pid, int uid, int procState, int adj, int cap,
                String packageName) {
@@ -574,8 +841,10 @@ public final class ServiceBindingOomAdjPolicyTest {
            String processName, String packageName, ActivityManagerService ams) {
        final ProcessRecord app = ApplicationExitInfoTest.makeProcessRecord(pid, uid, packageUid,
                definingUid, connectionGroup, procState, pss, rss, processName, packageName, ams);
        app.mState.setCurRawProcState(procState);
        app.mState.setCurProcState(procState);
        app.mState.setSetProcState(procState);
        app.mState.setCurRawAdj(adj);
        app.mState.setCurAdj(adj);
        app.mState.setSetAdj(adj);
        app.mState.setCurCapability(cap);