From 7859e8401cb9ba645515c3fccd43293681547628 Mon Sep 17 00:00:00 2001 From: Garfield Tan Date: Thu, 11 Mar 2021 16:43:55 -0800 Subject: [PATCH] Use resolved windowing mode to match launch root WM core offers WindowContainerTransaction#setLaunchRoot() API to override launch root task for specific windowing modes and activity types. However before this CL we only pass windowing mode in ActivityOptions when selecting root task, which will make windowing mode most of the time unspecified, which diminishes the use of the API. This can help whoever needs to differentiate launch root for freeform tasks and fullscreen tasks. Bug: 182514695 Test: WCT#setLaunchRoot() takes effect with app launches with specific windowing mode that is initiated by launcher. Test: atest TaskDisplayAreaTests Change-Id: I8113d3c9a82c8202f3881b5c08347fcb765861c6 --- .../server/wm/RootWindowContainer.java | 7 +-- .../android/server/wm/TaskDisplayArea.java | 17 +++++-- .../server/wm/TaskDisplayAreaTests.java | 46 +++++++++++++++++++ 3 files changed, 62 insertions(+), 8 deletions(-) diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java index 1212302d40a5a..2a768e7c99b69 100644 --- a/services/core/java/com/android/server/wm/RootWindowContainer.java +++ b/services/core/java/com/android/server/wm/RootWindowContainer.java @@ -2818,7 +2818,7 @@ class RootWindowContainer extends WindowContainer * @param launchParams The resolved launch params to use. * @param realCallingPid The pid from {@link ActivityStarter#setRealCallingPid} * @param realCallingUid The uid from {@link ActivityStarter#setRealCallingUid} - * @return The roott task to use for the launch or INVALID_TASK_ID. + * @return The root task to use for the launch or INVALID_TASK_ID. */ Task getLaunchRootTask(@Nullable ActivityRecord r, @Nullable ActivityOptions options, @Nullable Task candidateTask, boolean onTop, @@ -2887,7 +2887,7 @@ class RootWindowContainer extends WindowContainer // Falling back to default task container taskDisplayArea = taskDisplayArea.mDisplayContent.getDefaultTaskDisplayArea(); rootTask = taskDisplayArea.getOrCreateRootTask(r, options, candidateTask, - activityType, onTop); + launchParams, activityType, onTop); if (rootTask != null) { return rootTask; } @@ -2942,7 +2942,8 @@ class RootWindowContainer extends WindowContainer } } - return container.getOrCreateRootTask(r, options, candidateTask, activityType, onTop); + return container.getOrCreateRootTask( + r, options, candidateTask, launchParams, activityType, onTop); } /** @return true if activity record is null or can be launched on provided display. */ diff --git a/services/core/java/com/android/server/wm/TaskDisplayArea.java b/services/core/java/com/android/server/wm/TaskDisplayArea.java index ed92fd08bef5e..f0f4dafe216ea 100644 --- a/services/core/java/com/android/server/wm/TaskDisplayArea.java +++ b/services/core/java/com/android/server/wm/TaskDisplayArea.java @@ -57,6 +57,7 @@ import com.android.internal.util.ArrayUtils; import com.android.internal.util.ToBooleanFunction; import com.android.internal.util.function.pooled.PooledLambda; import com.android.internal.util.function.pooled.PooledPredicate; +import com.android.server.wm.LaunchParamsController.LaunchParams; import java.io.PrintWriter; import java.util.ArrayList; @@ -1080,11 +1081,17 @@ final class TaskDisplayArea extends DisplayArea { * @see #getOrCreateRootTask(int, int, boolean) */ Task getOrCreateRootTask(@Nullable ActivityRecord r, - @Nullable ActivityOptions options, @Nullable Task candidateTask, int activityType, - boolean onTop) { - // First preference is the windowing mode in the activity options if set. - int windowingMode = (options != null) - ? options.getLaunchWindowingMode() : WINDOWING_MODE_UNDEFINED; + @Nullable ActivityOptions options, @Nullable Task candidateTask, + @Nullable LaunchParams launchParams, int activityType, boolean onTop) { + int windowingMode = WINDOWING_MODE_UNDEFINED; + if (launchParams != null) { + // If launchParams isn't null, windowing mode is already resolved. + windowingMode = launchParams.mWindowingMode; + } else if (options != null) { + // If launchParams is null and options isn't let's use the windowing mode in the + // options. + windowingMode = options.getLaunchWindowingMode(); + } // Validate that our desired windowingMode will work under the current conditions. // UNDEFINED windowing mode is a valid result and means that the new root task will inherit // it's display's windowing mode. diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskDisplayAreaTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskDisplayAreaTests.java index e22cda60d423c..eba5634e43559 100644 --- a/services/tests/wmtests/src/com/android/server/wm/TaskDisplayAreaTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/TaskDisplayAreaTests.java @@ -42,16 +42,20 @@ import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; +import android.app.ActivityOptions; import android.platform.test.annotations.Presubmit; import androidx.test.filters.SmallTest; +import com.android.server.wm.LaunchParamsController.LaunchParams; + import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -86,6 +90,48 @@ public class TaskDisplayAreaTests extends WindowTestsBase { mPinnedTask.removeImmediately(); } + @Test + public void getOrCreateLaunchRootRespectsResolvedWindowingMode() { + final Task rootTask = createTaskStackOnDisplay( + WINDOWING_MODE_MULTI_WINDOW, ACTIVITY_TYPE_STANDARD, mDisplayContent); + rootTask.mCreatedByOrganizer = true; + final TaskDisplayArea taskDisplayArea = rootTask.getDisplayArea(); + taskDisplayArea.setLaunchRootTask( + rootTask, new int[]{WINDOWING_MODE_FREEFORM}, new int[]{ACTIVITY_TYPE_STANDARD}); + + final Task candidateRootTask = createTaskStackOnDisplay( + WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, mDisplayContent); + final ActivityRecord activity = createNonAttachedActivityRecord(mDisplayContent); + final LaunchParams launchParams = new LaunchParams(); + launchParams.mWindowingMode = WINDOWING_MODE_FREEFORM; + + final Task actualRootTask = taskDisplayArea.getOrCreateRootTask( + activity, null /* options */, candidateRootTask, + launchParams, ACTIVITY_TYPE_STANDARD, true /* onTop */); + assertSame(rootTask, actualRootTask.getRootTask()); + } + + @Test + public void getOrCreateLaunchRootUsesActivityOptionsWindowingMode() { + final Task rootTask = createTaskStackOnDisplay( + WINDOWING_MODE_MULTI_WINDOW, ACTIVITY_TYPE_STANDARD, mDisplayContent); + rootTask.mCreatedByOrganizer = true; + final TaskDisplayArea taskDisplayArea = rootTask.getDisplayArea(); + taskDisplayArea.setLaunchRootTask( + rootTask, new int[]{WINDOWING_MODE_FREEFORM}, new int[]{ACTIVITY_TYPE_STANDARD}); + + final Task candidateRootTask = createTaskStackOnDisplay( + WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, mDisplayContent); + final ActivityRecord activity = createNonAttachedActivityRecord(mDisplayContent); + final ActivityOptions options = ActivityOptions.makeBasic(); + options.setLaunchWindowingMode(WINDOWING_MODE_FREEFORM); + + final Task actualRootTask = taskDisplayArea.getOrCreateRootTask( + activity, options, candidateRootTask, + null /* launchParams */, ACTIVITY_TYPE_STANDARD, true /* onTop */); + assertSame(rootTask, actualRootTask.getRootTask()); + } + @Test public void testActivityWithZBoost_taskDisplayAreaDoesNotMoveUp() { final Task stack = createTaskStackOnDisplay(