From 420586af4dc1889fcd1866697d21c56996406946 Mon Sep 17 00:00:00 2001 From: Jing Ji Date: Thu, 1 Apr 2021 15:06:07 -0700 Subject: [PATCH] Pin sched group of service processes with binding flag SLTA at top ...even if the device is asleep, for better performance. Also limit the use of this flag to the bindings from system and persistent apps only, any uses in the bindings from other apps will be no op. Bug: 184173267 Test: atest MockingOomAdjusterTests Test: Manual - Check dumpsys output Change-Id: I930d42e8c53cff56efe85e1755c7c3145ea884af --- .../com/android/server/am/OomAdjuster.java | 10 +++- .../server/am/MockingOomAdjusterTests.java | 46 +++++++++++++++++++ 2 files changed, 54 insertions(+), 2 deletions(-) diff --git a/services/core/java/com/android/server/am/OomAdjuster.java b/services/core/java/com/android/server/am/OomAdjuster.java index 8ad11d161cdca..7c5936720feb4 100644 --- a/services/core/java/com/android/server/am/OomAdjuster.java +++ b/services/core/java/com/android/server/am/OomAdjuster.java @@ -1864,6 +1864,7 @@ public final class OomAdjuster { } int capabilityFromFGS = 0; // capability from foreground service. + boolean scheduleLikeTopApp = false; for (int is = psr.numberOfRunningServices() - 1; is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND @@ -1975,6 +1976,8 @@ public final class OomAdjuster { int clientAdj = cstate.getCurRawAdj(); int clientProcState = cstate.getCurRawProcState(); + final boolean clientIsSystem = clientProcState < PROCESS_STATE_TOP; + // pass client's mAllowStartFgs to the app if client is not persistent process. if (cstate.getAllowedStartFgs() != REASON_DENIED && cstate.getMaxAdj() >= ProcessList.FOREGROUND_APP_ADJ) { @@ -2170,8 +2173,10 @@ public final class OomAdjuster { } if (schedGroup < ProcessList.SCHED_GROUP_TOP_APP - && (cr.flags & Context.BIND_SCHEDULE_LIKE_TOP_APP) != 0) { + && (cr.flags & Context.BIND_SCHEDULE_LIKE_TOP_APP) != 0 + && clientIsSystem) { schedGroup = ProcessList.SCHED_GROUP_TOP_APP; + scheduleLikeTopApp = true; } if (!trackedProcState) { @@ -2438,7 +2443,8 @@ public final class OomAdjuster { // Put bound foreground services in a special sched group for additional // restrictions on screen off if (procState >= PROCESS_STATE_BOUND_FOREGROUND_SERVICE - && mService.mWakefulness.get() != PowerManagerInternal.WAKEFULNESS_AWAKE) { + && mService.mWakefulness.get() != PowerManagerInternal.WAKEFULNESS_AWAKE + && !scheduleLikeTopApp) { if (schedGroup > ProcessList.SCHED_GROUP_RESTRICTED) { schedGroup = ProcessList.SCHED_GROUP_RESTRICTED; } 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 1c45203bb3c98..3404aff976d0a 100644 --- a/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java +++ b/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java @@ -1359,6 +1359,52 @@ public class MockingOomAdjusterTests { SCHED_GROUP_DEFAULT); } + @SuppressWarnings("GuardedBy") + @Test + public void testUpdateOomAdj_DoOne_ScheduleLikeTop() { + final ProcessRecord app1 = spy(makeDefaultProcessRecord(MOCKAPP_PID, MOCKAPP_UID, + MOCKAPP_PROCESSNAME, MOCKAPP_PACKAGENAME, false)); + final ProcessRecord app2 = spy(makeDefaultProcessRecord(MOCKAPP2_PID, MOCKAPP2_UID, + MOCKAPP2_PROCESSNAME, MOCKAPP2_PACKAGENAME, false)); + final ProcessRecord client1 = spy(makeDefaultProcessRecord(MOCKAPP3_PID, MOCKAPP3_UID, + MOCKAPP3_PROCESSNAME, MOCKAPP3_PACKAGENAME, false)); + final ProcessRecord client2 = spy(makeDefaultProcessRecord(MOCKAPP4_PID, MOCKAPP4_UID, + MOCKAPP4_PROCESSNAME, MOCKAPP4_PACKAGENAME, false)); + bindService(app1, client1, null, Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE, + mock(IBinder.class)); + bindService(app2, client2, null, Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE, + mock(IBinder.class)); + client1.mState.setMaxAdj(PERSISTENT_PROC_ADJ); + client2.mServices.setHasForegroundServices(true, 0); + + sService.mWakefulness.set(PowerManagerInternal.WAKEFULNESS_AWAKE); + sService.mOomAdjuster.updateOomAdjLocked(app1, false, OomAdjuster.OOM_ADJ_REASON_NONE); + sService.mOomAdjuster.updateOomAdjLocked(app2, false, OomAdjuster.OOM_ADJ_REASON_NONE); + + assertProcStates(app1, PROCESS_STATE_BOUND_FOREGROUND_SERVICE, VISIBLE_APP_ADJ, + SCHED_GROUP_DEFAULT); + assertProcStates(app2, PROCESS_STATE_FOREGROUND_SERVICE, PERCEPTIBLE_APP_ADJ, + SCHED_GROUP_DEFAULT); + + bindService(app1, client1, null, Context.BIND_SCHEDULE_LIKE_TOP_APP, mock(IBinder.class)); + bindService(app2, client2, null, Context.BIND_SCHEDULE_LIKE_TOP_APP, mock(IBinder.class)); + sService.mOomAdjuster.updateOomAdjLocked(app1, false, OomAdjuster.OOM_ADJ_REASON_NONE); + sService.mOomAdjuster.updateOomAdjLocked(app2, false, OomAdjuster.OOM_ADJ_REASON_NONE); + + assertProcStates(app1, PROCESS_STATE_BOUND_FOREGROUND_SERVICE, VISIBLE_APP_ADJ, + SCHED_GROUP_TOP_APP); + assertProcStates(app2, PROCESS_STATE_FOREGROUND_SERVICE, PERCEPTIBLE_APP_ADJ, + SCHED_GROUP_DEFAULT); + + sService.mWakefulness.set(PowerManagerInternal.WAKEFULNESS_ASLEEP); + sService.mOomAdjuster.updateOomAdjLocked(app1, false, OomAdjuster.OOM_ADJ_REASON_NONE); + sService.mOomAdjuster.updateOomAdjLocked(app2, false, OomAdjuster.OOM_ADJ_REASON_NONE); + assertProcStates(app1, PROCESS_STATE_IMPORTANT_FOREGROUND, VISIBLE_APP_ADJ, + SCHED_GROUP_TOP_APP); + assertProcStates(app2, PROCESS_STATE_FOREGROUND_SERVICE, PERCEPTIBLE_APP_ADJ, + SCHED_GROUP_DEFAULT); + } + @SuppressWarnings("GuardedBy") @Test public void testUpdateOomAdj_UidIdle_StopService() {