Loading data/etc/services.core.protolog.json +6 −6 Original line number Diff line number Diff line Loading @@ -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", Loading Loading @@ -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", Loading services/core/java/com/android/server/wm/ActivityRecord.java +33 −11 Original line number Diff line number Diff line Loading @@ -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); } } Loading Loading @@ -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 Loading services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java +56 −6 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); Loading @@ -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. Loading Loading @@ -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; Loading Loading
data/etc/services.core.protolog.json +6 −6 Original line number Diff line number Diff line Loading @@ -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", Loading Loading @@ -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", Loading
services/core/java/com/android/server/wm/ActivityRecord.java +33 −11 Original line number Diff line number Diff line Loading @@ -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); } } Loading Loading @@ -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 Loading
services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java +56 −6 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); Loading @@ -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. Loading Loading @@ -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; Loading