diff options
| author | 2021-11-03 20:27:50 -0600 | |
|---|---|---|
| committer | 2021-11-03 20:52:58 +0800 | |
| commit | 6a99e776867fa567a67416950fcd0b99e255e13f (patch) | |
| tree | c235d8f9769626e9afe0fdd380ce597c358dccff | |
| parent | cc110e6aeaef998b0a09b295eb247ad0a5b99896 (diff) | |
Set pending top and update process state for top resumed change
When switching focus between resumed activities, there is no activity
state change to trigger update process state. So if it is the case
that misses to update, add as pending top to ensure the current top
have higher oom-adj, and trigger a full oom-adj update to refresh
process states because layer rank of tasks are also changed.
Fixes: 204980211
Test: ActivityTaskSupervisorTests#testUpdatePendingTopForTopResumed
Test: Enter split with 2 apps, use command
adb shell dumpsys activity oom | grep -A2 A/TOP
to observe the value of oom-adj after switching focus.
Change-Id: I411a3980ea23d875dd8d9ce7af80de74957f1caa
3 files changed, 42 insertions, 1 deletions
diff --git a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java index 7c5f059fb89a..c8b7d982fa0e 100644 --- a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java +++ b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java @@ -2049,6 +2049,16 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks { // Update the current top activity. mTopResumedActivity = topRootTask.getTopResumedActivity(); + // Update process state if there is no activity state change (e.g. focus change between + // multi-window mode activities) to make sure that the current top has top oom-adj. + // If the previous top is null, there should be activity state change from it, Then the + // process state should also have been updated so no need to update again. + if (mTopResumedActivity != null && prevTopActivity != null) { + if (mTopResumedActivity.app != null) { + mTopResumedActivity.app.addToPendingTop(); + } + mService.updateOomAdj(); + } scheduleTopResumedActivityStateIfNeeded(); mService.updateTopApp(mTopResumedActivity); diff --git a/services/core/java/com/android/server/wm/WindowProcessController.java b/services/core/java/com/android/server/wm/WindowProcessController.java index 81878e3ef229..1cfbe07d3f16 100644 --- a/services/core/java/com/android/server/wm/WindowProcessController.java +++ b/services/core/java/com/android/server/wm/WindowProcessController.java @@ -1110,7 +1110,7 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio void updateProcessInfo(boolean updateServiceConnectionActivities, boolean activityChange, boolean updateOomAdj, boolean addPendingTopUid) { if (addPendingTopUid) { - mAtm.mAmInternal.addPendingTopUid(mUid, mPid); + addToPendingTop(); } if (updateOomAdj) { prepareOomAdjustment(); @@ -1121,6 +1121,11 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio mAtm.mH.sendMessage(m); } + /** Makes the process have top state before oom-adj is computed from a posted message. */ + void addToPendingTop() { + mAtm.mAmInternal.addPendingTopUid(mUid, mPid); + } + void updateServiceConnectionActivities() { // Posting on handler so WM lock isn't held when we call into AM. mAtm.mH.sendMessage(PooledLambda.obtainMessage( diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityTaskSupervisorTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityTaskSupervisorTests.java index a34586bb2e8a..66da2a631868 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityTaskSupervisorTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityTaskSupervisorTests.java @@ -19,6 +19,7 @@ package com.android.server.wm; import static android.app.ActivityManager.START_DELIVERED_TO_TOP; import static android.app.ActivityManager.START_TASK_TO_FRONT; import static android.app.ITaskStackListener.FORCED_RESIZEABLE_REASON_SECONDARY_DISPLAY; +import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn; import static com.android.dx.mockito.inline.extended.ExtendedMockito.never; @@ -36,6 +37,7 @@ import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.clearInvocations; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.timeout; @@ -266,6 +268,30 @@ public class ActivityTaskSupervisorTests extends WindowTestsBase { } /** + * Verifies that process state will be updated with pending top without activity state change. + * E.g. switch focus between resumed activities in multi-window mode. + */ + @Test + public void testUpdatePendingTopForTopResumed() { + final Task task1 = new TaskBuilder(mSupervisor) + .setWindowingMode(WINDOWING_MODE_MULTI_WINDOW).build(); + final ActivityRecord activity1 = new ActivityBuilder(mAtm) + .setTask(task1).setUid(ActivityBuilder.DEFAULT_FAKE_UID + 1).build(); + task1.setResumedActivity(activity1, "test"); + + final ActivityRecord activity2 = new TaskBuilder(mSupervisor) + .setWindowingMode(WINDOWING_MODE_MULTI_WINDOW) + .setCreateActivity(true).build().getTopMostActivity(); + activity2.getTask().setResumedActivity(activity2, "test"); + + mAtm.mAmInternal.deletePendingTopUid(activity1.getUid()); + clearInvocations(mAtm); + activity1.moveFocusableActivityToTop("test"); + assertTrue(mAtm.mAmInternal.isPendingTopUid(activity1.getUid())); + verify(mAtm).updateOomAdj(); + } + + /** * We need to launch home again after user unlocked for those displays that do not have * encryption aware home app. */ |