diff options
4 files changed, 370 insertions, 39 deletions
diff --git a/services/core/java/com/android/server/am/OomAdjuster.java b/services/core/java/com/android/server/am/OomAdjuster.java index 42966a347aec..de3e2c90efe1 100644 --- a/services/core/java/com/android/server/am/OomAdjuster.java +++ b/services/core/java/com/android/server/am/OomAdjuster.java @@ -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,20 +4078,40 @@ 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 */); } - // 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") @@ -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 true; + return false; } @GuardedBy("mService") @@ -4118,14 +4148,25 @@ 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, + false, true /* dryRun */); } - return computeProviderHostOomAdjLSP(null, app, client, mInjector.getUptimeMillis(), - mService.getTopApp(), false, false, false, OOM_ADJ_REASON_NONE, CACHED_APP_MIN_ADJ, - false, true /* dryRun */); + return false; } @GuardedBy("mService") @@ -4133,12 +4174,19 @@ 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; + + 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 true; + + return false; } private boolean evaluateConnectionPrelude(ProcessRecord client, ProcessRecord app) { diff --git a/services/core/java/com/android/server/am/ProcessCachedOptimizerRecord.java b/services/core/java/com/android/server/am/ProcessCachedOptimizerRecord.java index 57a5e3f0c302..980c1f587677 100644 --- a/services/core/java/com/android/server/am/ProcessCachedOptimizerRecord.java +++ b/services/core/java/com/android/server/am/ProcessCachedOptimizerRecord.java @@ -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,7 +338,11 @@ final class ProcessCachedOptimizerRecord { boolean setShouldNotFreeze(boolean shouldNotFreeze, boolean dryRun, @ShouldNotFreezeReason int reason, int adjSeq) { if (dryRun) { - return mFrozen && !shouldNotFreeze; + if (Flags.unfreezeBindPolicyFix()) { + return mShouldNotFreeze != shouldNotFreeze; + } else { + return mFrozen && !shouldNotFreeze; + } } if (Flags.traceUpdateAppFreezeStateLsp()) { if (shouldNotFreeze) { diff --git a/services/core/java/com/android/server/am/flags.aconfig b/services/core/java/com/android/server/am/flags.aconfig index d680712676cd..883482053490 100644 --- a/services/core/java/com/android/server/am/flags.aconfig +++ b/services/core/java/com/android/server/am/flags.aconfig @@ -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 diff --git a/services/tests/mockingservicestests/src/com/android/server/am/ServiceBindingOomAdjPolicyTest.java b/services/tests/mockingservicestests/src/com/android/server/am/ServiceBindingOomAdjPolicyTest.java index 59302ee408eb..2988c77703b7 100644 --- a/services/tests/mockingservicestests/src/com/android/server/am/ServiceBindingOomAdjPolicyTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/am/ServiceBindingOomAdjPolicyTest.java @@ -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); @@ -527,6 +785,15 @@ public final class ServiceBindingOomAdjPolicyTest { } @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) { final ApplicationThreadDeferred appThread = mock(ApplicationThreadDeferred.class); @@ -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); |