diff options
3 files changed, 95 insertions, 23 deletions
diff --git a/data/etc/services.core.protolog.json b/data/etc/services.core.protolog.json index c70d6b0e946b..d9c0db999a3b 100644 --- a/data/etc/services.core.protolog.json +++ b/data/etc/services.core.protolog.json @@ -1219,12 +1219,6 @@ "group": "WM_DEBUG_ORIENTATION", "at": "com\/android\/server\/wm\/DragState.java" }, - "-681380736": { - "message": "Sandbox max bounds for uid %s to bounds %s due to letterboxing from mismatch with parent bounds? %s size compat mode %s", - "level": "DEBUG", - "group": "WM_DEBUG_CONFIGURATION", - "at": "com\/android\/server\/wm\/ActivityRecord.java" - }, "-677449371": { "message": "moveTaskToRootTask: moving task=%d to rootTaskId=%d toTop=%b", "level": "DEBUG", @@ -2875,6 +2869,12 @@ "group": "WM_DEBUG_BOOT", "at": "com\/android\/server\/wm\/WindowManagerService.java" }, + "1237719089": { + "message": "Sandbox max bounds for uid %s to bounds %s. letterboxing from mismatch with parent bounds = %s, has mCompatDisplayInsets = %s, should create compatDisplayInsets = %s", + "level": "DEBUG", + "group": "WM_DEBUG_CONFIGURATION", + "at": "com\/android\/server\/wm\/ActivityRecord.java" + }, "1246035185": { "message": "stopFreezingDisplayLocked: Returning waitingForConfig=%b, waitingForRemoteRotation=%b, mAppsFreezingScreen=%d, mWindowsFreezingScreen=%d, mClientFreezingScreen=%b, mOpeningApps.size()=%d", "level": "DEBUG", diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java index 4517ef5404c6..7c236617d14f 100644 --- a/services/core/java/com/android/server/wm/ActivityRecord.java +++ b/services/core/java/com/android/server/wm/ActivityRecord.java @@ -6954,18 +6954,27 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A mConfigurationSeq = Math.max(++mConfigurationSeq, 1); getResolvedOverrideConfiguration().seq = mConfigurationSeq; - // Sandbox max bounds by setting it to the app bounds, if activity is letterboxed or in - // size compat mode. + // Sandbox max bounds by setting it to the activity bounds, if activity is letterboxed, or + // has or will have mCompatDisplayInsets for size compat. if (providesMaxBounds()) { + mTmpBounds.set(resolvedConfig.windowConfiguration.getBounds()); + if (mTmpBounds.isEmpty()) { + // When there is no override bounds, the activity will inherit the bounds from + // parent. + mTmpBounds.set(newParentConfiguration.windowConfiguration.getBounds()); + } if (DEBUG_CONFIGURATION) { - ProtoLog.d(WM_DEBUG_CONFIGURATION, "Sandbox max bounds for uid %s to bounds %s " - + "due to letterboxing from mismatch with parent bounds? %s size compat " - + "mode %s", getUid(), - resolvedConfig.windowConfiguration.getBounds(), !matchParentBounds(), - inSizeCompatMode()); + ProtoLog.d(WM_DEBUG_CONFIGURATION, "Sandbox max bounds for uid %s to bounds %s. " + + "letterboxing from mismatch with parent bounds = %s, " + + "has mCompatDisplayInsets = %s, " + + "should create compatDisplayInsets = %s", + getUid(), + mTmpBounds, + !matchParentBounds(), + mCompatDisplayInsets != null, + shouldCreateCompatDisplayInsets()); } - resolvedConfig.windowConfiguration - .setMaxBounds(resolvedConfig.windowConfiguration.getBounds()); + resolvedConfig.windowConfiguration.setMaxBounds(mTmpBounds); } } @@ -7318,8 +7327,21 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A return false; } // Max bounds should be sandboxed where an activity is letterboxed (activity bounds will be - // smaller than task bounds) or put in size compat mode. - return !matchParentBounds() || inSizeCompatMode(); + // smaller than task bounds). + if (!matchParentBounds()) { + return true; + } + + // Max bounds should be sandboxed when an activity should have compatDisplayInsets, and it + // will keep the same bounds and screen configuration when it was first launched regardless + // how its parent window changes, so that the sandbox API will provide a consistent result. + if (mCompatDisplayInsets != null || shouldCreateCompatDisplayInsets()) { + return true; + } + + // No need to sandbox for resizable apps in multi-window because resizableActivity=true + // indicates that they support multi-window. + return false; } @VisibleForTesting diff --git a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java index 70c2971eea85..97cead1583e1 100644 --- a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java @@ -132,8 +132,8 @@ public class SizeCompatTests extends WindowTestsBase { mTask.setBounds(bounds); prepareUnresizable(mActivity, -1.f /* maxAspect */, SCREEN_ORIENTATION_PORTRAIT); assertEquals(bounds, mActivity.getBounds()); - // Activity is not yet in size compat mode; it is filling the freeform window. - assertMaxBoundsInheritDisplayAreaBounds(); + // Activity is not yet in size compat mode; it is filling the freeform task window. + assertActivityMaxBoundsSandboxed(); // The activity should be able to accept negative x position [-150, 100 - 150, 600]. final int dx = bounds.left + bounds.width() / 2; @@ -1388,7 +1388,7 @@ public class SizeCompatTests extends WindowTestsBase { } @Test - public void testSupportsNonResizableInSplitScreen() { + public void testSupportsNonResizableInSplitScreen_letterboxForDifferentOrientation() { // Support non resizable in multi window mAtm.mSupportsNonResizableMultiWindow = true; setUpDisplaySizeWithApp(1000, 2800); @@ -1399,16 +1399,18 @@ public class SizeCompatTests extends WindowTestsBase { prepareUnresizable(mActivity, SCREEN_ORIENTATION_LANDSCAPE); final Rect originalBounds = new Rect(mActivity.getBounds()); - // Move activity to split screen + // Move activity to split screen which takes half of the screen. mTask.reparent(organizer.mPrimary, POSITION_TOP, false /*moveParents*/, "test"); + organizer.mPrimary.setBounds(0, 0, 1000, 1400); assertEquals(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, mTask.getWindowingMode()); assertEquals(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, mActivity.getWindowingMode()); // Non-resizable activity in size compat mode assertScaled(); - assertEquals(originalBounds, - mActivity.getConfiguration().windowConfiguration.getBounds()); + final Rect newBounds = new Rect(mActivity.getWindowConfiguration().getBounds()); + assertEquals(originalBounds.width(), newBounds.width()); + assertEquals(originalBounds.height(), newBounds.height()); assertActivityMaxBoundsSandboxed(); // Recompute the natural configuration of the non-resizable activity and the split screen. @@ -1440,6 +1442,54 @@ public class SizeCompatTests extends WindowTestsBase { mActivity.getLetterboxInsets()); } + @Test + public void testSupportsNonResizableInSplitScreen_fillTaskForSameOrientation() { + // Support non resizable in multi window + mAtm.mSupportsNonResizableMultiWindow = true; + setUpDisplaySizeWithApp(1000, 2800); + final TestSplitOrganizer organizer = + new TestSplitOrganizer(mAtm, mActivity.getDisplayContent()); + + // Non-resizable portrait activity + prepareUnresizable(mActivity, SCREEN_ORIENTATION_PORTRAIT); + final Rect originalBounds = new Rect(mActivity.getBounds()); + + // Move activity to split screen which takes half of the screen. + mTask.reparent(organizer.mPrimary, POSITION_TOP, + false /*moveParents*/, "test"); + organizer.mPrimary.setBounds(0, 0, 1000, 1400); + assertEquals(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, mTask.getWindowingMode()); + assertEquals(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, mActivity.getWindowingMode()); + + // Non-resizable activity in size compat mode + assertScaled(); + final Rect newBounds = new Rect(mActivity.getWindowConfiguration().getBounds()); + assertEquals(originalBounds.width(), newBounds.width()); + assertEquals(originalBounds.height(), newBounds.height()); + assertActivityMaxBoundsSandboxed(); + + // Recompute the natural configuration of the non-resizable activity and the split screen. + mActivity.clearSizeCompatMode(); + mActivity.setVisible(false); + mActivity.mDisplayContent.prepareAppTransition(WindowManager.TRANSIT_OPEN); + mActivity.mDisplayContent.mOpeningApps.add(mActivity); + addWindowToActivity(mActivity); + mActivity.mRootWindowContainer.performSurfacePlacement(); + + // Split screen is also in portrait [1000,1400], which meets the activity request. It should + // sandbox to the activity bounds for non-resizable. + assertEquals(ORIENTATION_PORTRAIT, mTask.getConfiguration().orientation); + assertEquals(ORIENTATION_PORTRAIT, mActivity.getConfiguration().orientation); + assertFitted(); + assertFalse(mActivity.isLetterboxedForFixedOrientationAndAspectRatio()); + assertActivityMaxBoundsSandboxed(); + + // Activity bounds fill split screen. + final Rect primarySplitBounds = new Rect(organizer.mPrimary.getBounds()); + final Rect letterboxedBounds = new Rect(mActivity.getBounds()); + assertEquals(primarySplitBounds, letterboxedBounds); + } + private static WindowState addWindowToActivity(ActivityRecord activity) { final WindowManager.LayoutParams params = new WindowManager.LayoutParams(); params.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION; |