diff options
| -rw-r--r-- | services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java | 43 | ||||
| -rw-r--r-- | services/tests/wmtests/src/com/android/server/wm/TaskLaunchParamsModifierTests.java | 31 |
2 files changed, 71 insertions, 3 deletions
diff --git a/services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java b/services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java index 19fbfedfc251..3ff1e7989619 100644 --- a/services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java +++ b/services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java @@ -159,11 +159,23 @@ class TaskLaunchParamsModifier implements LaunchParamsModifier { } // STEP 2: Resolve launch windowing mode. - // STEP 2.1: Determine if any parameter has specified initial bounds. That might be the - // launch bounds from activity options, or size/gravity passed in layout. It also treats the - // launch windowing mode in options as a suggestion for future resolution. + // STEP 2.1: Determine if any parameter can specify initial bounds/windowing mode. That + // might be the launch bounds from activity options, or size/gravity passed in layout. It + // also treats the launch windowing mode in options and source activity windowing mode in + // some cases as a suggestion for future resolution. int launchMode = options != null ? options.getLaunchWindowingMode() : WINDOWING_MODE_UNDEFINED; + // In some cases we want to use the source's windowing mode as the default value, e.g. when + // source is a freeform window in a fullscreen display launching an activity on the same + // display. + if (launchMode == WINDOWING_MODE_UNDEFINED + && canInheritWindowingModeFromSource(display, source)) { + launchMode = source.getWindowingMode(); + if (DEBUG) { + appendLog("inherit-from-source=" + + WindowConfiguration.windowingModeToString(launchMode)); + } + } // hasInitialBounds is set if either activity options or layout has specified bounds. If // that's set we'll skip some adjustments later to avoid overriding the initial bounds. boolean hasInitialBounds = false; @@ -334,6 +346,31 @@ class TaskLaunchParamsModifier implements LaunchParamsModifier { ? displayId : DEFAULT_DISPLAY; } + private boolean canInheritWindowingModeFromSource(@NonNull ActivityDisplay display, + @Nullable ActivityRecord source) { + if (source == null) { + return false; + } + + // There is not really any strong reason to tie the launching windowing mode and the source + // on freeform displays. The launching windowing mode is more tied to the content of the new + // activities. + if (display.inFreeformWindowingMode()) { + return false; + } + + final int sourceWindowingMode = source.getWindowingMode(); + if (sourceWindowingMode != WINDOWING_MODE_FULLSCREEN + && sourceWindowingMode != WINDOWING_MODE_FREEFORM) { + return false; + } + + // Only inherit windowing mode if both source and target activities are on the same display. + // Otherwise we may have unintended freeform windows showing up if an activity in freeform + // window launches an activity on a fullscreen display by specifying display ID. + return display.mDisplayId == source.getDisplayId(); + } + private boolean canApplyFreeformWindowPolicy(@NonNull ActivityDisplay display, int launchMode) { return mSupervisor.mService.mSupportsFreeformWindowManagement && (display.inFreeformWindowingMode() || launchMode == WINDOWING_MODE_FREEFORM); diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskLaunchParamsModifierTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskLaunchParamsModifierTests.java index 58614c650363..29eae3e79897 100644 --- a/services/tests/wmtests/src/com/android/server/wm/TaskLaunchParamsModifierTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/TaskLaunchParamsModifierTests.java @@ -249,6 +249,20 @@ public class TaskLaunchParamsModifierTests extends ActivityTestsBase { } @Test + public void testInheritsFreeformModeFromSourceOnFullscreenDisplay() { + final TestActivityDisplay fullscreenDisplay = createNewActivityDisplay( + WINDOWING_MODE_FULLSCREEN); + final ActivityRecord source = createSourceActivity(fullscreenDisplay); + source.setWindowingMode(WINDOWING_MODE_FREEFORM); + + assertEquals(RESULT_CONTINUE, mTarget.onCalculate(/* task */ null, /* layout */ null, + mActivity, source, /* options */ null, mCurrent, mResult)); + + assertEquivalentWindowingMode(WINDOWING_MODE_FREEFORM, mResult.mWindowingMode, + WINDOWING_MODE_FULLSCREEN); + } + + @Test public void testKeepsPictureInPictureLaunchModeInOptions() { final TestActivityDisplay freeformDisplay = createNewActivityDisplay( WINDOWING_MODE_FREEFORM); @@ -558,6 +572,23 @@ public class TaskLaunchParamsModifierTests extends ActivityTestsBase { } @Test + public void testRespectsLaunchBoundsWithFreeformSourceOnFullscreenDisplay() { + final TestActivityDisplay fullscreenDisplay = createNewActivityDisplay( + WINDOWING_MODE_FULLSCREEN); + final ActivityRecord source = createSourceActivity(fullscreenDisplay); + source.setWindowingMode(WINDOWING_MODE_FREEFORM); + + final ActivityOptions options = ActivityOptions.makeBasic(); + final Rect expected = new Rect(0, 0, 150, 150); + options.setLaunchBounds(expected); + + assertEquals(RESULT_CONTINUE, mTarget.onCalculate(/* task */ null, /* layout */ null, + mActivity, source, options, mCurrent, mResult)); + + assertEquals(expected, mResult.mBounds); + } + + @Test public void testNonEmptyLayoutBoundsRespectsGravityWithEmptySize_LeftGravity() { final TestActivityDisplay freeformDisplay = createNewActivityDisplay( WINDOWING_MODE_FREEFORM); |