diff options
6 files changed, 94 insertions, 99 deletions
diff --git a/core/java/android/window/flags/windowing_frontend.aconfig b/core/java/android/window/flags/windowing_frontend.aconfig index 985dc102b31b..53e75f4be32a 100644 --- a/core/java/android/window/flags/windowing_frontend.aconfig +++ b/core/java/android/window/flags/windowing_frontend.aconfig @@ -146,6 +146,13 @@ flag { } flag { + name: "process_priority_policy_for_multi_window_mode" + namespace: "windowing_frontend" + description: "Use higher priority for top-like processes" + bug: "200769420" +} + +flag { name: "insets_decoupled_configuration" namespace: "windowing_frontend" description: "Configuration decoupled from insets" diff --git a/services/core/java/com/android/server/am/OomAdjuster.java b/services/core/java/com/android/server/am/OomAdjuster.java index 27c194b6b556..b058bd8eb3d6 100644 --- a/services/core/java/com/android/server/am/OomAdjuster.java +++ b/services/core/java/com/android/server/am/OomAdjuster.java @@ -1653,8 +1653,7 @@ public class OomAdjuster { new ComputeOomAdjWindowCallback(); /** These methods are called inline during computeOomAdjLSP(), on the same thread */ - final class ComputeOomAdjWindowCallback - implements WindowProcessController.ComputeOomAdjCallback { + final class ComputeOomAdjWindowCallback { ProcessRecord app; int adj; @@ -1684,8 +1683,7 @@ public class OomAdjuster { this.mState = app.mState; } - @Override - public void onVisibleActivity() { + void onVisibleActivity(int flags) { // App has a visible activity; only upgrade adjustment. if (adj > VISIBLE_APP_ADJ) { adj = VISIBLE_APP_ADJ; @@ -1705,12 +1703,17 @@ public class OomAdjuster { if (schedGroup < SCHED_GROUP_DEFAULT) { schedGroup = SCHED_GROUP_DEFAULT; } + if ((flags & WindowProcessController.ACTIVITY_STATE_FLAG_RESUMED_SPLIT_SCREEN) != 0) { + // Another side of split should be the current global top. Use the same top + // priority for this non-top split. + schedGroup = SCHED_GROUP_TOP_APP; + mAdjType = "resumed-split-screen-activity"; + } foregroundActivities = true; mHasVisibleActivities = true; } - @Override - public void onPausedActivity() { + void onPausedActivity() { if (adj > PERCEPTIBLE_APP_ADJ) { adj = PERCEPTIBLE_APP_ADJ; mAdjType = "pause-activity"; @@ -1733,8 +1736,7 @@ public class OomAdjuster { mHasVisibleActivities = false; } - @Override - public void onStoppingActivity(boolean finishing) { + void onStoppingActivity(boolean finishing) { if (adj > PERCEPTIBLE_APP_ADJ) { adj = PERCEPTIBLE_APP_ADJ; mAdjType = "stop-activity"; @@ -1764,8 +1766,7 @@ public class OomAdjuster { mHasVisibleActivities = false; } - @Override - public void onOtherActivity() { + void onOtherActivity() { if (procState > PROCESS_STATE_CACHED_ACTIVITY) { procState = PROCESS_STATE_CACHED_ACTIVITY; mAdjType = "cch-act"; diff --git a/services/core/java/com/android/server/am/ProcessStateRecord.java b/services/core/java/com/android/server/am/ProcessStateRecord.java index 7c64298a6053..bc990d9c5ef9 100644 --- a/services/core/java/com/android/server/am/ProcessStateRecord.java +++ b/services/core/java/com/android/server/am/ProcessStateRecord.java @@ -27,6 +27,11 @@ import static android.app.ProcessMemoryState.HOSTING_COMPONENT_TYPE_STARTED_SERV import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ; import static com.android.server.am.ProcessList.CACHED_APP_MIN_ADJ; import static com.android.server.am.ProcessRecord.TAG; +import static com.android.server.wm.WindowProcessController.ACTIVITY_STATE_FLAG_IS_PAUSING_OR_PAUSED; +import static com.android.server.wm.WindowProcessController.ACTIVITY_STATE_FLAG_IS_STOPPING; +import static com.android.server.wm.WindowProcessController.ACTIVITY_STATE_FLAG_IS_STOPPING_FINISHING; +import static com.android.server.wm.WindowProcessController.ACTIVITY_STATE_FLAG_IS_VISIBLE; +import static com.android.server.wm.WindowProcessController.ACTIVITY_STATE_FLAG_MASK_MIN_TASK_LAYER; import android.annotation.ElapsedRealtimeLong; import android.app.ActivityManager; @@ -1108,6 +1113,7 @@ final class ProcessStateRecord { return mCachedCompatChanges[cachedCompatChangeId] == VALUE_TRUE; } + /** This is only called if the process contains activities and is not the global top. */ @GuardedBy("mService") void computeOomAdjFromActivitiesIfNecessary(OomAdjuster.ComputeOomAdjWindowCallback callback, int adj, boolean foregroundActivities, boolean hasVisibleActivities, int procState, @@ -1117,8 +1123,17 @@ final class ProcessStateRecord { } callback.initialize(mApp, adj, foregroundActivities, hasVisibleActivities, procState, schedGroup, appUid, logUid, processCurTop); - final int minLayer = Math.min(ProcessList.VISIBLE_APP_LAYER_MAX, - mApp.getWindowProcessController().computeOomAdjFromActivities(callback)); + final int flags = mApp.getWindowProcessController().getActivityStateFlags(); + + if ((flags & ACTIVITY_STATE_FLAG_IS_VISIBLE) != 0) { + callback.onVisibleActivity(flags); + } else if ((flags & ACTIVITY_STATE_FLAG_IS_PAUSING_OR_PAUSED) != 0) { + callback.onPausedActivity(); + } else if ((flags & ACTIVITY_STATE_FLAG_IS_STOPPING) != 0) { + callback.onStoppingActivity((flags & ACTIVITY_STATE_FLAG_IS_STOPPING_FINISHING) != 0); + } else { + callback.onOtherActivity(); + } mCachedAdj = callback.adj; mCachedForegroundActivities = callback.foregroundActivities; @@ -1128,6 +1143,8 @@ final class ProcessStateRecord { mCachedAdjType = callback.mAdjType; if (mCachedAdj == ProcessList.VISIBLE_APP_ADJ) { + final int taskLayer = flags & ACTIVITY_STATE_FLAG_MASK_MIN_TASK_LAYER; + final int minLayer = Math.min(ProcessList.VISIBLE_APP_LAYER_MAX, taskLayer); mCachedAdj += minLayer; } } diff --git a/services/core/java/com/android/server/wm/WindowProcessController.java b/services/core/java/com/android/server/wm/WindowProcessController.java index 1c00fbbf5c92..b8780726f992 100644 --- a/services/core/java/com/android/server/wm/WindowProcessController.java +++ b/services/core/java/com/android/server/wm/WindowProcessController.java @@ -19,6 +19,7 @@ package com.android.server.wm; import static android.app.ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; import static android.app.ActivityManager.PROCESS_STATE_NONEXISTENT; import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED; +import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW; import static android.content.res.Configuration.ASSETS_SEQ_UNDEFINED; import static android.os.Build.VERSION_CODES.Q; import static android.os.InputConstants.DEFAULT_DISPATCHING_TIMEOUT_MILLIS; @@ -309,14 +310,15 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio private volatile boolean mWasStoppedLogged; // The bits used for mActivityStateFlags. - private static final int ACTIVITY_STATE_FLAG_IS_VISIBLE = 1 << 16; - private static final int ACTIVITY_STATE_FLAG_IS_PAUSING_OR_PAUSED = 1 << 17; - private static final int ACTIVITY_STATE_FLAG_IS_STOPPING = 1 << 18; - private static final int ACTIVITY_STATE_FLAG_IS_STOPPING_FINISHING = 1 << 19; - private static final int ACTIVITY_STATE_FLAG_IS_WINDOW_VISIBLE = 1 << 20; - private static final int ACTIVITY_STATE_FLAG_HAS_RESUMED = 1 << 21; - private static final int ACTIVITY_STATE_FLAG_HAS_ACTIVITY_IN_VISIBLE_TASK = 1 << 22; - private static final int ACTIVITY_STATE_FLAG_MASK_MIN_TASK_LAYER = 0x0000ffff; + public static final int ACTIVITY_STATE_FLAG_IS_VISIBLE = 1 << 16; + public static final int ACTIVITY_STATE_FLAG_IS_PAUSING_OR_PAUSED = 1 << 17; + public static final int ACTIVITY_STATE_FLAG_IS_STOPPING = 1 << 18; + public static final int ACTIVITY_STATE_FLAG_IS_STOPPING_FINISHING = 1 << 19; + public static final int ACTIVITY_STATE_FLAG_IS_WINDOW_VISIBLE = 1 << 20; + public static final int ACTIVITY_STATE_FLAG_HAS_RESUMED = 1 << 21; + public static final int ACTIVITY_STATE_FLAG_HAS_ACTIVITY_IN_VISIBLE_TASK = 1 << 22; + public static final int ACTIVITY_STATE_FLAG_RESUMED_SPLIT_SCREEN = 1 << 23; + public static final int ACTIVITY_STATE_FLAG_MASK_MIN_TASK_LAYER = 0x0000ffff; /** * The state for oom-adjustment calculation. The higher 16 bits are the activity states, and the @@ -1211,31 +1213,13 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio } } - public interface ComputeOomAdjCallback { - void onVisibleActivity(); - void onPausedActivity(); - void onStoppingActivity(boolean finishing); - void onOtherActivity(); - } - /** - * Returns the minimum task layer rank. It should only be called if {@link #hasActivities} - * returns {@code true}. + * Returns the current ACTIVITY_STATE_FLAG_* of this process. It should only be called if + * {@link #hasActivities} returns {@code true}. */ @HotPath(caller = HotPath.OOM_ADJUSTMENT) - public int computeOomAdjFromActivities(ComputeOomAdjCallback callback) { - final int flags = mActivityStateFlags; - if ((flags & ACTIVITY_STATE_FLAG_IS_VISIBLE) != 0) { - callback.onVisibleActivity(); - } else if ((flags & ACTIVITY_STATE_FLAG_IS_PAUSING_OR_PAUSED) != 0) { - callback.onPausedActivity(); - } else if ((flags & ACTIVITY_STATE_FLAG_IS_STOPPING) != 0) { - callback.onStoppingActivity( - (flags & ACTIVITY_STATE_FLAG_IS_STOPPING_FINISHING) != 0); - } else { - callback.onOtherActivity(); - } - return flags & ACTIVITY_STATE_FLAG_MASK_MIN_TASK_LAYER; + public int getActivityStateFlags() { + return mActivityStateFlags; } void computeProcessActivityState() { @@ -1256,14 +1240,25 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio stateFlags |= ACTIVITY_STATE_FLAG_IS_WINDOW_VISIBLE; } final Task task = r.getTask(); - if (task != null && task.mLayerRank != Task.LAYER_RANK_INVISIBLE) { + if (task == null) { + Slog.e(TAG, "Unexpected detached " + r + " in " + this); + continue; + } + if (task.mLayerRank != Task.LAYER_RANK_INVISIBLE) { stateFlags |= ACTIVITY_STATE_FLAG_HAS_ACTIVITY_IN_VISIBLE_TASK; } if (r.isVisibleRequested()) { if (r.isState(RESUMED)) { stateFlags |= ACTIVITY_STATE_FLAG_HAS_RESUMED; + final int windowingMode = r.getWindowingMode(); + if (windowingMode == WINDOWING_MODE_MULTI_WINDOW + && com.android.window.flags.Flags + .processPriorityPolicyForMultiWindowMode() + && task.getAdjacentTask() != null) { + stateFlags |= ACTIVITY_STATE_FLAG_RESUMED_SPLIT_SCREEN; + } } - if (task != null && minTaskLayer > 0) { + if (minTaskLayer > 0) { final int layer = task.mLayerRank; if (layer >= 0 && minTaskLayer > layer) { minTaskLayer = layer; @@ -2107,6 +2102,9 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio pw.print("V|"); if ((stateFlags & ACTIVITY_STATE_FLAG_HAS_RESUMED) != 0) { pw.print("R|"); + if ((stateFlags & ACTIVITY_STATE_FLAG_RESUMED_SPLIT_SCREEN) != 0) { + pw.print("RS|"); + } } } else if ((stateFlags & ACTIVITY_STATE_FLAG_IS_PAUSING_OR_PAUSED) != 0) { pw.print("P|"); 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 488ce66ca99b..6366f24a27e1 100644 --- a/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java +++ b/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java @@ -72,14 +72,12 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertTrue; -import static org.mockito.AdditionalAnswers.answer; import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.any; import static org.mockito.Mockito.anyBoolean; import static org.mockito.Mockito.anyInt; import static org.mockito.Mockito.atLeastOnce; -import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.doCallRealMethod; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doReturn; @@ -486,27 +484,22 @@ public class MockingOomAdjusterTests { MOCKAPP_PROCESSNAME, MOCKAPP_PACKAGENAME, true)); WindowProcessController wpc = app.getWindowProcessController(); doReturn(true).when(wpc).hasActivities(); - doAnswer(answer(callback -> { - Field field = callback.getClass().getDeclaredField("adj"); - field.set(callback, VISIBLE_APP_ADJ); - field = callback.getClass().getDeclaredField("foregroundActivities"); - field.set(callback, true); - field = callback.getClass().getDeclaredField("procState"); - field.set(callback, PROCESS_STATE_TOP); - field = callback.getClass().getDeclaredField("schedGroup"); - field.set(callback, SCHED_GROUP_TOP_APP); - field = callback.getClass().getDeclaredField("mAdjType"); - field.set(callback, "vis-activity"); - return 0; - })).when(wpc).computeOomAdjFromActivities( - any(WindowProcessController.ComputeOomAdjCallback.class)); + doReturn(WindowProcessController.ACTIVITY_STATE_FLAG_IS_VISIBLE) + .when(wpc).getActivityStateFlags(); mService.mWakefulness.set(PowerManagerInternal.WAKEFULNESS_AWAKE); updateOomAdj(app); - assertProcStates(app, PROCESS_STATE_TOP, VISIBLE_APP_ADJ, SCHED_GROUP_TOP_APP); + assertProcStates(app, PROCESS_STATE_TOP, VISIBLE_APP_ADJ, SCHED_GROUP_DEFAULT); assertFalse(app.mState.isCached()); assertFalse(app.mState.isEmpty()); assertEquals("vis-activity", app.mState.getAdjType()); + + doReturn(WindowProcessController.ACTIVITY_STATE_FLAG_IS_VISIBLE + | WindowProcessController.ACTIVITY_STATE_FLAG_RESUMED_SPLIT_SCREEN) + .when(wpc).getActivityStateFlags(); + updateOomAdj(app); + assertProcStates(app, PROCESS_STATE_TOP, VISIBLE_APP_ADJ, SCHED_GROUP_TOP_APP); + assertEquals("resumed-split-screen-activity", app.mState.getAdjType()); } @SuppressWarnings("GuardedBy") diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerTests.java index 059fed20c38d..e6648dad4bbe 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerTests.java @@ -340,54 +340,33 @@ public class WindowProcessControllerTests extends WindowTestsBase { public void testComputeOomAdjFromActivities() { final ActivityRecord activity = createActivityRecord(mWpc); activity.setVisibleRequested(true); - final int[] callbackResult = { 0 }; - final int visible = 1; - final int paused = 2; - final int stopping = 4; - final int other = 8; - final WindowProcessController.ComputeOomAdjCallback callback = - new WindowProcessController.ComputeOomAdjCallback() { - @Override - public void onVisibleActivity() { - callbackResult[0] |= visible; - } - - @Override - public void onPausedActivity() { - callbackResult[0] |= paused; - } - - @Override - public void onStoppingActivity(boolean finishing) { - callbackResult[0] |= stopping; - } - - @Override - public void onOtherActivity() { - callbackResult[0] |= other; - } - }; // onStartActivity should refresh the state immediately. mWpc.onStartActivity(0 /* topProcessState */, activity.info); - assertEquals(1 /* minTaskLayer */, mWpc.computeOomAdjFromActivities(callback)); - assertEquals(visible, callbackResult[0]); + int flags = mWpc.getActivityStateFlags(); + assertEquals(1 /* minTaskLayer */, + flags & WindowProcessController.ACTIVITY_STATE_FLAG_MASK_MIN_TASK_LAYER); + final int visibleFlags = WindowProcessController.ACTIVITY_STATE_FLAG_IS_VISIBLE + | WindowProcessController.ACTIVITY_STATE_FLAG_IS_WINDOW_VISIBLE + | WindowProcessController.ACTIVITY_STATE_FLAG_HAS_ACTIVITY_IN_VISIBLE_TASK; + assertEquals(visibleFlags, + flags & ~WindowProcessController.ACTIVITY_STATE_FLAG_MASK_MIN_TASK_LAYER); - callbackResult[0] = 0; activity.setVisibleRequested(false); activity.setState(PAUSED, "test"); - mWpc.computeOomAdjFromActivities(callback); - assertEquals(paused, callbackResult[0]); + final int exclusiveFlags = WindowProcessController.ACTIVITY_STATE_FLAG_IS_VISIBLE + | WindowProcessController.ACTIVITY_STATE_FLAG_IS_PAUSING_OR_PAUSED + | WindowProcessController.ACTIVITY_STATE_FLAG_IS_STOPPING; + flags = mWpc.getActivityStateFlags() & exclusiveFlags; + assertEquals(WindowProcessController.ACTIVITY_STATE_FLAG_IS_PAUSING_OR_PAUSED, flags); - callbackResult[0] = 0; activity.setState(STOPPING, "test"); - mWpc.computeOomAdjFromActivities(callback); - assertEquals(stopping, callbackResult[0]); + flags = mWpc.getActivityStateFlags() & exclusiveFlags; + assertEquals(WindowProcessController.ACTIVITY_STATE_FLAG_IS_STOPPING, flags); - callbackResult[0] = 0; activity.setState(STOPPED, "test"); - mWpc.computeOomAdjFromActivities(callback); - assertEquals(other, callbackResult[0]); + flags = mWpc.getActivityStateFlags() & exclusiveFlags; + assertEquals(0, flags); } @Test |