Loading services/core/java/com/android/server/wm/LetterboxUiController.java +17 −14 Original line number Diff line number Diff line Loading @@ -52,7 +52,6 @@ import static android.content.pm.PackageManager.USER_MIN_ASPECT_RATIO_FULLSCREEN import static android.content.pm.PackageManager.USER_MIN_ASPECT_RATIO_SPLIT_SCREEN; import static android.content.pm.PackageManager.USER_MIN_ASPECT_RATIO_UNSET; import static android.content.res.Configuration.ORIENTATION_LANDSCAPE; import static android.content.res.Configuration.ORIENTATION_PORTRAIT; import static android.content.res.Configuration.ORIENTATION_UNDEFINED; import static android.content.res.Configuration.SCREEN_HEIGHT_DP_UNDEFINED; import static android.content.res.Configuration.SCREEN_WIDTH_DP_UNDEFINED; Loading Loading @@ -1369,23 +1368,25 @@ final class LetterboxUiController { * * <p>Conditions that needs to be met: * <ul> * <li>Activity is portrait-only. * <li>Fullscreen window in landscape device orientation. * <li>Windowing mode is fullscreen. * <li>Horizontal Reachability is enabled. * <li>Activity fills parent vertically. * <li>First top opaque activity fills parent vertically, but not horizontally. * </ul> */ private boolean isHorizontalReachabilityEnabled(Configuration parentConfiguration) { // Use screen resolved bounds which uses resolved bounds or size compat bounds // as activity bounds can sometimes be empty final Rect opaqueActivityBounds = hasInheritedLetterboxBehavior() ? mFirstOpaqueActivityBeneath.getScreenResolvedBounds() : mActivityRecord.getScreenResolvedBounds(); return mLetterboxConfiguration.getIsHorizontalReachabilityEnabled() && parentConfiguration.windowConfiguration.getWindowingMode() == WINDOWING_MODE_FULLSCREEN && (parentConfiguration.orientation == ORIENTATION_LANDSCAPE && mActivityRecord.getOrientationForReachability() == ORIENTATION_PORTRAIT) // Check whether the activity fills the parent vertically. && parentConfiguration.windowConfiguration.getAppBounds().height() <= mActivityRecord.getScreenResolvedBounds().height(); <= opaqueActivityBounds.height() && parentConfiguration.windowConfiguration.getAppBounds().width() > opaqueActivityBounds.width(); } @VisibleForTesting Loading @@ -1402,23 +1403,25 @@ final class LetterboxUiController { * * <p>Conditions that needs to be met: * <ul> * <li>Activity is landscape-only. * <li>Fullscreen window in portrait device orientation. * <li>Windowing mode is fullscreen. * <li>Vertical Reachability is enabled. * <li>Activity fills parent horizontally. * <li>First top opaque activity fills parent horizontally but not vertically. * </ul> */ private boolean isVerticalReachabilityEnabled(Configuration parentConfiguration) { // Use screen resolved bounds which uses resolved bounds or size compat bounds // as activity bounds can sometimes be empty final Rect opaqueActivityBounds = hasInheritedLetterboxBehavior() ? mFirstOpaqueActivityBeneath.getScreenResolvedBounds() : mActivityRecord.getScreenResolvedBounds(); return mLetterboxConfiguration.getIsVerticalReachabilityEnabled() && parentConfiguration.windowConfiguration.getWindowingMode() == WINDOWING_MODE_FULLSCREEN && (parentConfiguration.orientation == ORIENTATION_PORTRAIT && mActivityRecord.getOrientationForReachability() == ORIENTATION_LANDSCAPE) // Check whether the activity fills the parent horizontally. && parentConfiguration.windowConfiguration.getBounds().width() == mActivityRecord.getScreenResolvedBounds().width(); && parentConfiguration.windowConfiguration.getAppBounds().width() <= opaqueActivityBounds.width() && parentConfiguration.windowConfiguration.getAppBounds().height() > opaqueActivityBounds.height(); } @VisibleForTesting Loading services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java +145 −108 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW; import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; import static android.content.pm.ActivityInfo.OVERRIDE_MIN_ASPECT_RATIO_LARGE_VALUE; import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE; import static android.content.pm.ActivityInfo.RESIZE_MODE_UNRESIZEABLE; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE; Loading Loading @@ -215,15 +216,46 @@ public class SizeCompatTests extends WindowTestsBase { @Test public void testHorizontalReachabilityEnabledForTranslucentActivities() { setUpDisplaySizeWithApp(2500, 1000); testReachabilityEnabledForTranslucentActivity(/* dw */ 2500, /* dh */1000, SCREEN_ORIENTATION_PORTRAIT, /* minAspectRatio */ 0f, /* horizontalReachability */ true); } @Test public void testHorizontalReachabilityEnabled_TranslucentPortraitActivities_portraitDisplay() { testReachabilityEnabledForTranslucentActivity(/* dw */ 1400, /* dh */1600, SCREEN_ORIENTATION_PORTRAIT, OVERRIDE_MIN_ASPECT_RATIO_LARGE_VALUE, /* horizontalReachability */ true); } @Test public void testVerticalReachabilityEnabledForTranslucentActivities() { testReachabilityEnabledForTranslucentActivity(/* dw */ 1000, /* dh */2500, SCREEN_ORIENTATION_LANDSCAPE, /* minAspectRatio */ 0f, /* horizontalReachability */ false); } @Test public void testVerticalReachabilityEnabled_TranslucentLandscapeActivities_landscapeDisplay() { testReachabilityEnabledForTranslucentActivity(/* dw */ 1600, /* dh */1400, SCREEN_ORIENTATION_LANDSCAPE, OVERRIDE_MIN_ASPECT_RATIO_LARGE_VALUE, /* horizontalReachability */ false); } private void testReachabilityEnabledForTranslucentActivity(int displayWidth, int displayHeight, @ScreenOrientation int screenOrientation, float minAspectRatio, boolean horizontalReachability) { setUpDisplaySizeWithApp(displayWidth, displayHeight); mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */); final LetterboxConfiguration config = mWm.mLetterboxConfiguration; config.setTranslucentLetterboxingOverrideEnabled(true); config.setLetterboxVerticalPositionMultiplier(0.5f); config.setIsVerticalReachabilityEnabled(true); config.setLetterboxHorizontalPositionMultiplier(0.5f); config.setIsHorizontalReachabilityEnabled(true); // Opaque activity prepareUnresizable(mActivity, SCREEN_ORIENTATION_PORTRAIT); prepareMinAspectRatio(mActivity, minAspectRatio, screenOrientation); addWindowToActivity(mActivity); mActivity.mRootWindowContainer.performSurfacePlacement(); Loading @@ -231,7 +263,7 @@ public class SizeCompatTests extends WindowTestsBase { final ActivityRecord translucentActivity = new ActivityBuilder(mAtm) .setActivityTheme(android.R.style.Theme_Translucent) .setLaunchedFromUid(mActivity.getUid()) .setScreenOrientation(SCREEN_ORIENTATION_PORTRAIT) .setScreenOrientation(screenOrientation) .build(); mTask.addChild(translucentActivity); Loading @@ -250,14 +282,23 @@ public class SizeCompatTests extends WindowTestsBase { }; final Runnable checkLetterboxPositions = () -> assertEquals(innerBoundsOf.apply(mActivity), innerBoundsOf.apply(translucentActivity)); final Runnable checkIsTop = () -> assertThat( innerBoundsOf.apply(translucentActivity).top).isEqualTo(0); final Runnable checkIsBottom = () -> assertThat( innerBoundsOf.apply(translucentActivity).bottom).isEqualTo(displayHeight); final Runnable checkIsLeft = () -> assertThat( innerBoundsOf.apply(translucentActivity).left).isEqualTo(0); final Runnable checkIsRight = () -> assertThat( innerBoundsOf.apply(translucentActivity).right).isEqualTo(2500); final Runnable checkIsCentered = () -> assertThat( innerBoundsOf.apply(translucentActivity).right).isEqualTo(displayWidth); final Runnable checkIsHorizontallyCentered = () -> assertThat( innerBoundsOf.apply(translucentActivity).left > 0 && innerBoundsOf.apply(translucentActivity).right < 2500).isTrue(); && innerBoundsOf.apply(translucentActivity).right < displayWidth).isTrue(); final Runnable checkIsVerticallyCentered = () -> assertThat( innerBoundsOf.apply(translucentActivity).top > 0 && innerBoundsOf.apply(translucentActivity).bottom < displayHeight) .isTrue(); if (horizontalReachability) { final Consumer<Integer> doubleClick = (Integer x) -> { mActivity.mLetterboxUiController.handleHorizontalDoubleTap(x); Loading @@ -265,7 +306,7 @@ public class SizeCompatTests extends WindowTestsBase { }; // Initial state checkIsCentered.run(); checkIsHorizontallyCentered.run(); // Double-click left doubleClick.accept(/* x */ 10); Loading @@ -273,66 +314,20 @@ public class SizeCompatTests extends WindowTestsBase { checkIsLeft.run(); // Double-click right doubleClick.accept(/* x */ 1990); doubleClick.accept(/* x */ displayWidth - 100); checkLetterboxPositions.run(); checkIsCentered.run(); checkIsHorizontallyCentered.run(); // Double-click right doubleClick.accept(/* x */ 1990); doubleClick.accept(/* x */ displayWidth - 100); checkLetterboxPositions.run(); checkIsRight.run(); // Double-click left doubleClick.accept(/* x */ 10); checkLetterboxPositions.run(); checkIsCentered.run(); } @Test public void testVerticalReachabilityEnabledForTranslucentActivities() { setUpDisplaySizeWithApp(1000, 2500); mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */); final LetterboxConfiguration config = mWm.mLetterboxConfiguration; config.setTranslucentLetterboxingOverrideEnabled(true); config.setLetterboxVerticalPositionMultiplier(0.5f); config.setIsVerticalReachabilityEnabled(true); // Opaque activity prepareUnresizable(mActivity, SCREEN_ORIENTATION_LANDSCAPE); addWindowToActivity(mActivity); mActivity.mRootWindowContainer.performSurfacePlacement(); // Translucent Activity final ActivityRecord translucentActivity = new ActivityBuilder(mAtm) .setActivityTheme(android.R.style.Theme_Translucent) .setLaunchedFromUid(mActivity.getUid()) .setScreenOrientation(SCREEN_ORIENTATION_LANDSCAPE) .build(); mTask.addChild(translucentActivity); spyOn(translucentActivity.mLetterboxUiController); doReturn(true).when(translucentActivity.mLetterboxUiController) .shouldShowLetterboxUi(any()); addWindowToActivity(translucentActivity); translucentActivity.mRootWindowContainer.performSurfacePlacement(); final Function<ActivityRecord, Rect> innerBoundsOf = (ActivityRecord a) -> { final Rect bounds = new Rect(); a.mLetterboxUiController.getLetterboxInnerBounds(bounds); return bounds; }; final Runnable checkLetterboxPositions = () -> assertEquals(innerBoundsOf.apply(mActivity), innerBoundsOf.apply(translucentActivity)); final Runnable checkIsTop = () -> assertThat( innerBoundsOf.apply(translucentActivity).top).isEqualTo(0); final Runnable checkIsBottom = () -> assertThat( innerBoundsOf.apply(translucentActivity).bottom).isEqualTo(2500); final Runnable checkIsCentered = () -> assertThat( innerBoundsOf.apply(translucentActivity).top > 0 && innerBoundsOf.apply(translucentActivity).bottom < 2500).isTrue(); checkIsHorizontallyCentered.run(); } else { final Consumer<Integer> doubleClick = (Integer y) -> { mActivity.mLetterboxUiController.handleVerticalDoubleTap(y); Loading @@ -340,7 +335,7 @@ public class SizeCompatTests extends WindowTestsBase { }; // Initial state checkIsCentered.run(); checkIsVerticallyCentered.run(); // Double-click top doubleClick.accept(/* y */ 10); Loading @@ -348,19 +343,20 @@ public class SizeCompatTests extends WindowTestsBase { checkIsTop.run(); // Double-click bottom doubleClick.accept(/* y */ 1990); doubleClick.accept(/* y */ displayHeight - 100); checkLetterboxPositions.run(); checkIsCentered.run(); checkIsVerticallyCentered.run(); // Double-click bottom doubleClick.accept(/* y */ 1990); doubleClick.accept(/* y */ displayHeight - 100); checkLetterboxPositions.run(); checkIsBottom.run(); // Double-click top doubleClick.accept(/* y */ 10); checkLetterboxPositions.run(); checkIsCentered.run(); checkIsVerticallyCentered.run(); } } @Test Loading Loading @@ -3608,6 +3604,32 @@ public class SizeCompatTests extends WindowTestsBase { assertTrue(mActivity.mLetterboxUiController.isHorizontalReachabilityEnabled()); } @Test public void testIsHorizontalReachabilityEnabled_portraitDisplayAndApp_true() { // Portrait display setUpDisplaySizeWithApp(1400, 1600); mActivity.mWmService.mLetterboxConfiguration.setIsHorizontalReachabilityEnabled(true); // 16:9f unresizable portrait app prepareMinAspectRatio(mActivity, OVERRIDE_MIN_ASPECT_RATIO_LARGE_VALUE, SCREEN_ORIENTATION_PORTRAIT); assertTrue(mActivity.mLetterboxUiController.isHorizontalReachabilityEnabled()); } @Test public void testIsVerticalReachabilityEnabled_landscapeDisplayAndApp_true() { // Landscape display setUpDisplaySizeWithApp(1600, 1500); mActivity.mWmService.mLetterboxConfiguration.setIsVerticalReachabilityEnabled(true); // 16:9f unresizable landscape app prepareMinAspectRatio(mActivity, OVERRIDE_MIN_ASPECT_RATIO_LARGE_VALUE, SCREEN_ORIENTATION_LANDSCAPE); assertTrue(mActivity.mLetterboxUiController.isVerticalReachabilityEnabled()); } @Test public void testIsHorizontalReachabilityEnabled_doesNotMatchParentHeight_false() { setUpDisplaySizeWithApp(2800, 1000); Loading Loading @@ -4884,6 +4906,12 @@ public class SizeCompatTests extends WindowTestsBase { .build(); } static void prepareMinAspectRatio(ActivityRecord activity, float minAspect, int screenOrientation) { prepareLimitedBounds(activity, -1 /* maxAspect */, minAspect, screenOrientation, true /* isUnresizable */); } static void prepareUnresizable(ActivityRecord activity, int screenOrientation) { prepareUnresizable(activity, -1 /* maxAspect */, screenOrientation); } Loading @@ -4898,11 +4926,17 @@ public class SizeCompatTests extends WindowTestsBase { prepareLimitedBounds(activity, -1 /* maxAspect */, screenOrientation, isUnresizable); } static void prepareLimitedBounds(ActivityRecord activity, float maxAspect, int screenOrientation, boolean isUnresizable) { prepareLimitedBounds(activity, maxAspect, -1 /* minAspect */, screenOrientation, isUnresizable); } /** * Setups {@link #mActivity} with restriction on its bounds, such as maxAspect, fixed * orientation, and/or whether it is resizable. * Setups {@link #mActivity} with restriction on its bounds, such as maxAspect, minAspect, * fixed orientation, and/or whether it is resizable. */ static void prepareLimitedBounds(ActivityRecord activity, float maxAspect, static void prepareLimitedBounds(ActivityRecord activity, float maxAspect, float minAspect, int screenOrientation, boolean isUnresizable) { activity.info.resizeMode = isUnresizable ? RESIZE_MODE_UNRESIZEABLE Loading @@ -4917,6 +4951,9 @@ public class SizeCompatTests extends WindowTestsBase { if (maxAspect >= 0) { activity.info.setMaxAspectRatio(maxAspect); } if (minAspect >= 0) { activity.info.setMinAspectRatio(minAspect); } if (screenOrientation != SCREEN_ORIENTATION_UNSPECIFIED) { activity.info.screenOrientation = screenOrientation; activity.setRequestedOrientation(screenOrientation); Loading Loading
services/core/java/com/android/server/wm/LetterboxUiController.java +17 −14 Original line number Diff line number Diff line Loading @@ -52,7 +52,6 @@ import static android.content.pm.PackageManager.USER_MIN_ASPECT_RATIO_FULLSCREEN import static android.content.pm.PackageManager.USER_MIN_ASPECT_RATIO_SPLIT_SCREEN; import static android.content.pm.PackageManager.USER_MIN_ASPECT_RATIO_UNSET; import static android.content.res.Configuration.ORIENTATION_LANDSCAPE; import static android.content.res.Configuration.ORIENTATION_PORTRAIT; import static android.content.res.Configuration.ORIENTATION_UNDEFINED; import static android.content.res.Configuration.SCREEN_HEIGHT_DP_UNDEFINED; import static android.content.res.Configuration.SCREEN_WIDTH_DP_UNDEFINED; Loading Loading @@ -1369,23 +1368,25 @@ final class LetterboxUiController { * * <p>Conditions that needs to be met: * <ul> * <li>Activity is portrait-only. * <li>Fullscreen window in landscape device orientation. * <li>Windowing mode is fullscreen. * <li>Horizontal Reachability is enabled. * <li>Activity fills parent vertically. * <li>First top opaque activity fills parent vertically, but not horizontally. * </ul> */ private boolean isHorizontalReachabilityEnabled(Configuration parentConfiguration) { // Use screen resolved bounds which uses resolved bounds or size compat bounds // as activity bounds can sometimes be empty final Rect opaqueActivityBounds = hasInheritedLetterboxBehavior() ? mFirstOpaqueActivityBeneath.getScreenResolvedBounds() : mActivityRecord.getScreenResolvedBounds(); return mLetterboxConfiguration.getIsHorizontalReachabilityEnabled() && parentConfiguration.windowConfiguration.getWindowingMode() == WINDOWING_MODE_FULLSCREEN && (parentConfiguration.orientation == ORIENTATION_LANDSCAPE && mActivityRecord.getOrientationForReachability() == ORIENTATION_PORTRAIT) // Check whether the activity fills the parent vertically. && parentConfiguration.windowConfiguration.getAppBounds().height() <= mActivityRecord.getScreenResolvedBounds().height(); <= opaqueActivityBounds.height() && parentConfiguration.windowConfiguration.getAppBounds().width() > opaqueActivityBounds.width(); } @VisibleForTesting Loading @@ -1402,23 +1403,25 @@ final class LetterboxUiController { * * <p>Conditions that needs to be met: * <ul> * <li>Activity is landscape-only. * <li>Fullscreen window in portrait device orientation. * <li>Windowing mode is fullscreen. * <li>Vertical Reachability is enabled. * <li>Activity fills parent horizontally. * <li>First top opaque activity fills parent horizontally but not vertically. * </ul> */ private boolean isVerticalReachabilityEnabled(Configuration parentConfiguration) { // Use screen resolved bounds which uses resolved bounds or size compat bounds // as activity bounds can sometimes be empty final Rect opaqueActivityBounds = hasInheritedLetterboxBehavior() ? mFirstOpaqueActivityBeneath.getScreenResolvedBounds() : mActivityRecord.getScreenResolvedBounds(); return mLetterboxConfiguration.getIsVerticalReachabilityEnabled() && parentConfiguration.windowConfiguration.getWindowingMode() == WINDOWING_MODE_FULLSCREEN && (parentConfiguration.orientation == ORIENTATION_PORTRAIT && mActivityRecord.getOrientationForReachability() == ORIENTATION_LANDSCAPE) // Check whether the activity fills the parent horizontally. && parentConfiguration.windowConfiguration.getBounds().width() == mActivityRecord.getScreenResolvedBounds().width(); && parentConfiguration.windowConfiguration.getAppBounds().width() <= opaqueActivityBounds.width() && parentConfiguration.windowConfiguration.getAppBounds().height() > opaqueActivityBounds.height(); } @VisibleForTesting Loading
services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java +145 −108 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW; import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; import static android.content.pm.ActivityInfo.OVERRIDE_MIN_ASPECT_RATIO_LARGE_VALUE; import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE; import static android.content.pm.ActivityInfo.RESIZE_MODE_UNRESIZEABLE; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE; Loading Loading @@ -215,15 +216,46 @@ public class SizeCompatTests extends WindowTestsBase { @Test public void testHorizontalReachabilityEnabledForTranslucentActivities() { setUpDisplaySizeWithApp(2500, 1000); testReachabilityEnabledForTranslucentActivity(/* dw */ 2500, /* dh */1000, SCREEN_ORIENTATION_PORTRAIT, /* minAspectRatio */ 0f, /* horizontalReachability */ true); } @Test public void testHorizontalReachabilityEnabled_TranslucentPortraitActivities_portraitDisplay() { testReachabilityEnabledForTranslucentActivity(/* dw */ 1400, /* dh */1600, SCREEN_ORIENTATION_PORTRAIT, OVERRIDE_MIN_ASPECT_RATIO_LARGE_VALUE, /* horizontalReachability */ true); } @Test public void testVerticalReachabilityEnabledForTranslucentActivities() { testReachabilityEnabledForTranslucentActivity(/* dw */ 1000, /* dh */2500, SCREEN_ORIENTATION_LANDSCAPE, /* minAspectRatio */ 0f, /* horizontalReachability */ false); } @Test public void testVerticalReachabilityEnabled_TranslucentLandscapeActivities_landscapeDisplay() { testReachabilityEnabledForTranslucentActivity(/* dw */ 1600, /* dh */1400, SCREEN_ORIENTATION_LANDSCAPE, OVERRIDE_MIN_ASPECT_RATIO_LARGE_VALUE, /* horizontalReachability */ false); } private void testReachabilityEnabledForTranslucentActivity(int displayWidth, int displayHeight, @ScreenOrientation int screenOrientation, float minAspectRatio, boolean horizontalReachability) { setUpDisplaySizeWithApp(displayWidth, displayHeight); mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */); final LetterboxConfiguration config = mWm.mLetterboxConfiguration; config.setTranslucentLetterboxingOverrideEnabled(true); config.setLetterboxVerticalPositionMultiplier(0.5f); config.setIsVerticalReachabilityEnabled(true); config.setLetterboxHorizontalPositionMultiplier(0.5f); config.setIsHorizontalReachabilityEnabled(true); // Opaque activity prepareUnresizable(mActivity, SCREEN_ORIENTATION_PORTRAIT); prepareMinAspectRatio(mActivity, minAspectRatio, screenOrientation); addWindowToActivity(mActivity); mActivity.mRootWindowContainer.performSurfacePlacement(); Loading @@ -231,7 +263,7 @@ public class SizeCompatTests extends WindowTestsBase { final ActivityRecord translucentActivity = new ActivityBuilder(mAtm) .setActivityTheme(android.R.style.Theme_Translucent) .setLaunchedFromUid(mActivity.getUid()) .setScreenOrientation(SCREEN_ORIENTATION_PORTRAIT) .setScreenOrientation(screenOrientation) .build(); mTask.addChild(translucentActivity); Loading @@ -250,14 +282,23 @@ public class SizeCompatTests extends WindowTestsBase { }; final Runnable checkLetterboxPositions = () -> assertEquals(innerBoundsOf.apply(mActivity), innerBoundsOf.apply(translucentActivity)); final Runnable checkIsTop = () -> assertThat( innerBoundsOf.apply(translucentActivity).top).isEqualTo(0); final Runnable checkIsBottom = () -> assertThat( innerBoundsOf.apply(translucentActivity).bottom).isEqualTo(displayHeight); final Runnable checkIsLeft = () -> assertThat( innerBoundsOf.apply(translucentActivity).left).isEqualTo(0); final Runnable checkIsRight = () -> assertThat( innerBoundsOf.apply(translucentActivity).right).isEqualTo(2500); final Runnable checkIsCentered = () -> assertThat( innerBoundsOf.apply(translucentActivity).right).isEqualTo(displayWidth); final Runnable checkIsHorizontallyCentered = () -> assertThat( innerBoundsOf.apply(translucentActivity).left > 0 && innerBoundsOf.apply(translucentActivity).right < 2500).isTrue(); && innerBoundsOf.apply(translucentActivity).right < displayWidth).isTrue(); final Runnable checkIsVerticallyCentered = () -> assertThat( innerBoundsOf.apply(translucentActivity).top > 0 && innerBoundsOf.apply(translucentActivity).bottom < displayHeight) .isTrue(); if (horizontalReachability) { final Consumer<Integer> doubleClick = (Integer x) -> { mActivity.mLetterboxUiController.handleHorizontalDoubleTap(x); Loading @@ -265,7 +306,7 @@ public class SizeCompatTests extends WindowTestsBase { }; // Initial state checkIsCentered.run(); checkIsHorizontallyCentered.run(); // Double-click left doubleClick.accept(/* x */ 10); Loading @@ -273,66 +314,20 @@ public class SizeCompatTests extends WindowTestsBase { checkIsLeft.run(); // Double-click right doubleClick.accept(/* x */ 1990); doubleClick.accept(/* x */ displayWidth - 100); checkLetterboxPositions.run(); checkIsCentered.run(); checkIsHorizontallyCentered.run(); // Double-click right doubleClick.accept(/* x */ 1990); doubleClick.accept(/* x */ displayWidth - 100); checkLetterboxPositions.run(); checkIsRight.run(); // Double-click left doubleClick.accept(/* x */ 10); checkLetterboxPositions.run(); checkIsCentered.run(); } @Test public void testVerticalReachabilityEnabledForTranslucentActivities() { setUpDisplaySizeWithApp(1000, 2500); mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */); final LetterboxConfiguration config = mWm.mLetterboxConfiguration; config.setTranslucentLetterboxingOverrideEnabled(true); config.setLetterboxVerticalPositionMultiplier(0.5f); config.setIsVerticalReachabilityEnabled(true); // Opaque activity prepareUnresizable(mActivity, SCREEN_ORIENTATION_LANDSCAPE); addWindowToActivity(mActivity); mActivity.mRootWindowContainer.performSurfacePlacement(); // Translucent Activity final ActivityRecord translucentActivity = new ActivityBuilder(mAtm) .setActivityTheme(android.R.style.Theme_Translucent) .setLaunchedFromUid(mActivity.getUid()) .setScreenOrientation(SCREEN_ORIENTATION_LANDSCAPE) .build(); mTask.addChild(translucentActivity); spyOn(translucentActivity.mLetterboxUiController); doReturn(true).when(translucentActivity.mLetterboxUiController) .shouldShowLetterboxUi(any()); addWindowToActivity(translucentActivity); translucentActivity.mRootWindowContainer.performSurfacePlacement(); final Function<ActivityRecord, Rect> innerBoundsOf = (ActivityRecord a) -> { final Rect bounds = new Rect(); a.mLetterboxUiController.getLetterboxInnerBounds(bounds); return bounds; }; final Runnable checkLetterboxPositions = () -> assertEquals(innerBoundsOf.apply(mActivity), innerBoundsOf.apply(translucentActivity)); final Runnable checkIsTop = () -> assertThat( innerBoundsOf.apply(translucentActivity).top).isEqualTo(0); final Runnable checkIsBottom = () -> assertThat( innerBoundsOf.apply(translucentActivity).bottom).isEqualTo(2500); final Runnable checkIsCentered = () -> assertThat( innerBoundsOf.apply(translucentActivity).top > 0 && innerBoundsOf.apply(translucentActivity).bottom < 2500).isTrue(); checkIsHorizontallyCentered.run(); } else { final Consumer<Integer> doubleClick = (Integer y) -> { mActivity.mLetterboxUiController.handleVerticalDoubleTap(y); Loading @@ -340,7 +335,7 @@ public class SizeCompatTests extends WindowTestsBase { }; // Initial state checkIsCentered.run(); checkIsVerticallyCentered.run(); // Double-click top doubleClick.accept(/* y */ 10); Loading @@ -348,19 +343,20 @@ public class SizeCompatTests extends WindowTestsBase { checkIsTop.run(); // Double-click bottom doubleClick.accept(/* y */ 1990); doubleClick.accept(/* y */ displayHeight - 100); checkLetterboxPositions.run(); checkIsCentered.run(); checkIsVerticallyCentered.run(); // Double-click bottom doubleClick.accept(/* y */ 1990); doubleClick.accept(/* y */ displayHeight - 100); checkLetterboxPositions.run(); checkIsBottom.run(); // Double-click top doubleClick.accept(/* y */ 10); checkLetterboxPositions.run(); checkIsCentered.run(); checkIsVerticallyCentered.run(); } } @Test Loading Loading @@ -3608,6 +3604,32 @@ public class SizeCompatTests extends WindowTestsBase { assertTrue(mActivity.mLetterboxUiController.isHorizontalReachabilityEnabled()); } @Test public void testIsHorizontalReachabilityEnabled_portraitDisplayAndApp_true() { // Portrait display setUpDisplaySizeWithApp(1400, 1600); mActivity.mWmService.mLetterboxConfiguration.setIsHorizontalReachabilityEnabled(true); // 16:9f unresizable portrait app prepareMinAspectRatio(mActivity, OVERRIDE_MIN_ASPECT_RATIO_LARGE_VALUE, SCREEN_ORIENTATION_PORTRAIT); assertTrue(mActivity.mLetterboxUiController.isHorizontalReachabilityEnabled()); } @Test public void testIsVerticalReachabilityEnabled_landscapeDisplayAndApp_true() { // Landscape display setUpDisplaySizeWithApp(1600, 1500); mActivity.mWmService.mLetterboxConfiguration.setIsVerticalReachabilityEnabled(true); // 16:9f unresizable landscape app prepareMinAspectRatio(mActivity, OVERRIDE_MIN_ASPECT_RATIO_LARGE_VALUE, SCREEN_ORIENTATION_LANDSCAPE); assertTrue(mActivity.mLetterboxUiController.isVerticalReachabilityEnabled()); } @Test public void testIsHorizontalReachabilityEnabled_doesNotMatchParentHeight_false() { setUpDisplaySizeWithApp(2800, 1000); Loading Loading @@ -4884,6 +4906,12 @@ public class SizeCompatTests extends WindowTestsBase { .build(); } static void prepareMinAspectRatio(ActivityRecord activity, float minAspect, int screenOrientation) { prepareLimitedBounds(activity, -1 /* maxAspect */, minAspect, screenOrientation, true /* isUnresizable */); } static void prepareUnresizable(ActivityRecord activity, int screenOrientation) { prepareUnresizable(activity, -1 /* maxAspect */, screenOrientation); } Loading @@ -4898,11 +4926,17 @@ public class SizeCompatTests extends WindowTestsBase { prepareLimitedBounds(activity, -1 /* maxAspect */, screenOrientation, isUnresizable); } static void prepareLimitedBounds(ActivityRecord activity, float maxAspect, int screenOrientation, boolean isUnresizable) { prepareLimitedBounds(activity, maxAspect, -1 /* minAspect */, screenOrientation, isUnresizable); } /** * Setups {@link #mActivity} with restriction on its bounds, such as maxAspect, fixed * orientation, and/or whether it is resizable. * Setups {@link #mActivity} with restriction on its bounds, such as maxAspect, minAspect, * fixed orientation, and/or whether it is resizable. */ static void prepareLimitedBounds(ActivityRecord activity, float maxAspect, static void prepareLimitedBounds(ActivityRecord activity, float maxAspect, float minAspect, int screenOrientation, boolean isUnresizable) { activity.info.resizeMode = isUnresizable ? RESIZE_MODE_UNRESIZEABLE Loading @@ -4917,6 +4951,9 @@ public class SizeCompatTests extends WindowTestsBase { if (maxAspect >= 0) { activity.info.setMaxAspectRatio(maxAspect); } if (minAspect >= 0) { activity.info.setMinAspectRatio(minAspect); } if (screenOrientation != SCREEN_ORIENTATION_UNSPECIFIED) { activity.info.screenOrientation = screenOrientation; activity.setRequestedOrientation(screenOrientation); Loading