diff --git a/services/core/java/com/android/server/am/OomAdjuster.java b/services/core/java/com/android/server/am/OomAdjuster.java index e02dda642b40f..3643db065be2c 100644 --- a/services/core/java/com/android/server/am/OomAdjuster.java +++ b/services/core/java/com/android/server/am/OomAdjuster.java @@ -1898,7 +1898,7 @@ public class OomAdjuster { // For short FGS. adjType = "fg-service-short"; // We use MEDIUM_APP_ADJ + 1 so we can tell apart EJ - // (which uses MEDIUM_APP_ADJ + 1) + // (which uses MEDIUM_APP_ADJ + 2) // from short-FGS. // (We use +1 and +2, not +0 and +1, to be consistent with the following // RECENT_FOREGROUND_APP_ADJ tweak) @@ -2319,6 +2319,14 @@ public class OomAdjuster { && adj >= (lbAdj = PERCEPTIBLE_LOW_APP_ADJ)) { newAdj = PERCEPTIBLE_LOW_APP_ADJ; } else if ((cr.flags & Context.BIND_ALMOST_PERCEPTIBLE) != 0 + && (cr.flags & Context.BIND_NOT_FOREGROUND) == 0 + && clientAdj < PERCEPTIBLE_APP_ADJ + && adj >= (lbAdj = PERCEPTIBLE_APP_ADJ)) { + // This is for user-initiated jobs. + // We use APP_ADJ + 1 here, so we can tell them apart from FGS. + newAdj = PERCEPTIBLE_APP_ADJ + 1; + } else if ((cr.flags & Context.BIND_ALMOST_PERCEPTIBLE) != 0 + && (cr.flags & Context.BIND_NOT_FOREGROUND) != 0 && clientAdj < PERCEPTIBLE_APP_ADJ && adj >= (lbAdj = (PERCEPTIBLE_MEDIUM_APP_ADJ + 2))) { // This is for expedited jobs. diff --git a/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java b/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java index 2fb6c2324be12..9f7b72cb09af1 100644 --- a/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java +++ b/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java @@ -630,6 +630,26 @@ public class MockingOomAdjusterTests { assertNotEquals(PERCEPTIBLE_RECENT_FOREGROUND_APP_ADJ + 2, app.mState.getSetAdj()); } } + + @SuppressWarnings("GuardedBy") + @Test + public void testUpdateOomAdj_DoOne_ImpFg_AlmostPerceptibleService() { + ProcessRecord system = spy(makeDefaultProcessRecord(MOCKAPP_PID, MOCKAPP_UID, + MOCKAPP_PROCESSNAME, MOCKAPP_PACKAGENAME, true)); + ProcessRecord app = spy(makeDefaultProcessRecord(MOCKAPP2_PID, MOCKAPP2_UID, + MOCKAPP2_PROCESSNAME, MOCKAPP2_PACKAGENAME, true)); + system.mState.setMaxAdj(PERSISTENT_PROC_ADJ); + system.mState.setHasTopUi(true); + // Simulate the system starting and binding to a service in the app. + ServiceRecord s = bindService(app, system, + null, Context.BIND_ALMOST_PERCEPTIBLE, mock(IBinder.class)); + sService.mWakefulness.set(PowerManagerInternal.WAKEFULNESS_AWAKE); + sService.mOomAdjuster.updateOomAdjLocked(app, OomAdjuster.OOM_ADJ_REASON_NONE); + + assertProcStates(app, PROCESS_STATE_IMPORTANT_FOREGROUND, + PERCEPTIBLE_APP_ADJ + 1, SCHED_GROUP_DEFAULT); + } + @SuppressWarnings("GuardedBy") @Test public void testUpdateOomAdj_DoOne_Toast() { @@ -1056,13 +1076,15 @@ public class MockingOomAdjusterTests { @SuppressWarnings("GuardedBy") @Test - public void testUpdateOomAdj_DoOne_Service_MediumPerceptible() { + public void testUpdateOomAdj_DoOne_Service_AlmostPerceptible() { { ProcessRecord app = spy(makeDefaultProcessRecord(MOCKAPP_PID, MOCKAPP_UID, MOCKAPP_PROCESSNAME, MOCKAPP_PACKAGENAME, false)); ProcessRecord client = spy(makeDefaultProcessRecord(MOCKAPP2_PID, MOCKAPP2_UID, MOCKAPP2_PROCESSNAME, MOCKAPP2_PACKAGENAME, false)); - bindService(app, client, null, Context.BIND_ALMOST_PERCEPTIBLE, mock(IBinder.class)); + bindService(app, client, null, + Context.BIND_ALMOST_PERCEPTIBLE | Context.BIND_NOT_FOREGROUND, + mock(IBinder.class)); client.mState.setMaxAdj(PERSISTENT_PROC_ADJ); sService.mWakefulness.set(PowerManagerInternal.WAKEFULNESS_AWAKE); updateOomAdj(client, app); @@ -1077,7 +1099,9 @@ public class MockingOomAdjusterTests { MOCKAPP2_PROCESSNAME, MOCKAPP2_PACKAGENAME, false)); WindowProcessController wpc = client.getWindowProcessController(); doReturn(true).when(wpc).isHeavyWeightProcess(); - bindService(app, client, null, Context.BIND_ALMOST_PERCEPTIBLE, mock(IBinder.class)); + bindService(app, client, null, + Context.BIND_ALMOST_PERCEPTIBLE | Context.BIND_NOT_FOREGROUND, + mock(IBinder.class)); client.mState.setMaxAdj(PERSISTENT_PROC_ADJ); sService.mWakefulness.set(PowerManagerInternal.WAKEFULNESS_AWAKE); updateOomAdj(client, app); @@ -1085,6 +1109,39 @@ public class MockingOomAdjusterTests { assertEquals(PERCEPTIBLE_MEDIUM_APP_ADJ + 2, app.mState.getSetAdj()); } + + { + ProcessRecord app = spy(makeDefaultProcessRecord(MOCKAPP_PID, MOCKAPP_UID, + MOCKAPP_PROCESSNAME, MOCKAPP_PACKAGENAME, false)); + ProcessRecord client = spy(makeDefaultProcessRecord(MOCKAPP2_PID, MOCKAPP2_UID, + MOCKAPP2_PROCESSNAME, MOCKAPP2_PACKAGENAME, false)); + bindService(app, client, null, + Context.BIND_ALMOST_PERCEPTIBLE, + mock(IBinder.class)); + client.mState.setMaxAdj(PERSISTENT_PROC_ADJ); + sService.mWakefulness.set(PowerManagerInternal.WAKEFULNESS_AWAKE); + sService.mOomAdjuster.updateOomAdjLocked(app, OomAdjuster.OOM_ADJ_REASON_NONE); + + assertEquals(PERCEPTIBLE_APP_ADJ + 1, app.mState.getSetAdj()); + } + + { + ProcessRecord app = spy(makeDefaultProcessRecord(MOCKAPP_PID, MOCKAPP_UID, + MOCKAPP_PROCESSNAME, MOCKAPP_PACKAGENAME, false)); + ProcessRecord client = spy(makeDefaultProcessRecord(MOCKAPP2_PID, MOCKAPP2_UID, + MOCKAPP2_PROCESSNAME, MOCKAPP2_PACKAGENAME, false)); + WindowProcessController wpc = client.getWindowProcessController(); + doReturn(true).when(wpc).isHeavyWeightProcess(); + bindService(app, client, null, + Context.BIND_ALMOST_PERCEPTIBLE, + mock(IBinder.class)); + client.mState.setMaxAdj(PERSISTENT_PROC_ADJ); + sService.mWakefulness.set(PowerManagerInternal.WAKEFULNESS_AWAKE); + sService.mOomAdjuster.updateOomAdjLocked(app, OomAdjuster.OOM_ADJ_REASON_NONE); + doReturn(false).when(wpc).isHeavyWeightProcess(); + + assertEquals(PERCEPTIBLE_APP_ADJ + 1, app.mState.getSetAdj()); + } } @SuppressWarnings("GuardedBy")