Merge "Don't use display orientation for reachability conditions" into main
diff --git a/services/core/java/com/android/server/wm/LetterboxUiController.java b/services/core/java/com/android/server/wm/LetterboxUiController.java
index 5243527..5d613cf 100644
--- a/services/core/java/com/android/server/wm/LetterboxUiController.java
+++ b/services/core/java/com/android/server/wm/LetterboxUiController.java
@@ -52,7 +52,6 @@
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;
@@ -1369,23 +1368,25 @@
*
* <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
@@ -1402,23 +1403,25 @@
*
* <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
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 d3f69b5..b96f39d 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
@@ -22,6 +22,7 @@
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;
@@ -215,90 +216,46 @@
@Test
public void testHorizontalReachabilityEnabledForTranslucentActivities() {
- setUpDisplaySizeWithApp(2500, 1000);
- mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
- final LetterboxConfiguration config = mWm.mLetterboxConfiguration;
- config.setTranslucentLetterboxingOverrideEnabled(true);
- config.setLetterboxHorizontalPositionMultiplier(0.5f);
- config.setIsHorizontalReachabilityEnabled(true);
+ testReachabilityEnabledForTranslucentActivity(/* dw */ 2500, /* dh */1000,
+ SCREEN_ORIENTATION_PORTRAIT, /* minAspectRatio */ 0f,
+ /* horizontalReachability */ true);
+ }
- // Opaque activity
- prepareUnresizable(mActivity, SCREEN_ORIENTATION_PORTRAIT);
- 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_PORTRAIT)
- .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 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).left > 0
- && innerBoundsOf.apply(translucentActivity).right < 2500).isTrue();
-
- final Consumer<Integer> doubleClick =
- (Integer x) -> {
- mActivity.mLetterboxUiController.handleHorizontalDoubleTap(x);
- mActivity.mRootWindowContainer.performSurfacePlacement();
- };
-
- // Initial state
- checkIsCentered.run();
-
- // Double-click left
- doubleClick.accept(/* x */ 10);
- checkLetterboxPositions.run();
- checkIsLeft.run();
-
- // Double-click right
- doubleClick.accept(/* x */ 1990);
- checkLetterboxPositions.run();
- checkIsCentered.run();
-
- // Double-click right
- doubleClick.accept(/* x */ 1990);
- checkLetterboxPositions.run();
- checkIsRight.run();
-
- // Double-click left
- doubleClick.accept(/* x */ 10);
- checkLetterboxPositions.run();
- checkIsCentered.run();
+ @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() {
- setUpDisplaySizeWithApp(1000, 2500);
+ 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_LANDSCAPE);
+ prepareMinAspectRatio(mActivity, minAspectRatio, screenOrientation);
addWindowToActivity(mActivity);
mActivity.mRootWindowContainer.performSurfacePlacement();
@@ -306,7 +263,7 @@
final ActivityRecord translucentActivity = new ActivityBuilder(mAtm)
.setActivityTheme(android.R.style.Theme_Translucent)
.setLaunchedFromUid(mActivity.getUid())
- .setScreenOrientation(SCREEN_ORIENTATION_LANDSCAPE)
+ .setScreenOrientation(screenOrientation)
.build();
mTask.addChild(translucentActivity);
@@ -328,39 +285,78 @@
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).bottom).isEqualTo(displayHeight);
+ final Runnable checkIsLeft = () -> assertThat(
+ innerBoundsOf.apply(translucentActivity).left).isEqualTo(0);
+ final Runnable checkIsRight = () -> assertThat(
+ innerBoundsOf.apply(translucentActivity).right).isEqualTo(displayWidth);
+ final Runnable checkIsHorizontallyCentered = () -> assertThat(
+ innerBoundsOf.apply(translucentActivity).left > 0
+ && innerBoundsOf.apply(translucentActivity).right < displayWidth).isTrue();
+ final Runnable checkIsVerticallyCentered = () -> assertThat(
innerBoundsOf.apply(translucentActivity).top > 0
- && innerBoundsOf.apply(translucentActivity).bottom < 2500).isTrue();
+ && innerBoundsOf.apply(translucentActivity).bottom < displayHeight)
+ .isTrue();
- final Consumer<Integer> doubleClick =
- (Integer y) -> {
- mActivity.mLetterboxUiController.handleVerticalDoubleTap(y);
- mActivity.mRootWindowContainer.performSurfacePlacement();
- };
+ if (horizontalReachability) {
+ final Consumer<Integer> doubleClick =
+ (Integer x) -> {
+ mActivity.mLetterboxUiController.handleHorizontalDoubleTap(x);
+ mActivity.mRootWindowContainer.performSurfacePlacement();
+ };
- // Initial state
- checkIsCentered.run();
+ // Initial state
+ checkIsHorizontallyCentered.run();
- // Double-click top
- doubleClick.accept(/* y */ 10);
- checkLetterboxPositions.run();
- checkIsTop.run();
+ // Double-click left
+ doubleClick.accept(/* x */ 10);
+ checkLetterboxPositions.run();
+ checkIsLeft.run();
- // Double-click bottom
- doubleClick.accept(/* y */ 1990);
- checkLetterboxPositions.run();
- checkIsCentered.run();
+ // Double-click right
+ doubleClick.accept(/* x */ displayWidth - 100);
+ checkLetterboxPositions.run();
+ checkIsHorizontallyCentered.run();
- // Double-click bottom
- doubleClick.accept(/* y */ 1990);
- checkLetterboxPositions.run();
- checkIsBottom.run();
+ // Double-click right
+ doubleClick.accept(/* x */ displayWidth - 100);
+ checkLetterboxPositions.run();
+ checkIsRight.run();
- // Double-click top
- doubleClick.accept(/* y */ 10);
- checkLetterboxPositions.run();
- checkIsCentered.run();
+ // Double-click left
+ doubleClick.accept(/* x */ 10);
+ checkLetterboxPositions.run();
+ checkIsHorizontallyCentered.run();
+ } else {
+ final Consumer<Integer> doubleClick =
+ (Integer y) -> {
+ mActivity.mLetterboxUiController.handleVerticalDoubleTap(y);
+ mActivity.mRootWindowContainer.performSurfacePlacement();
+ };
+
+ // Initial state
+ checkIsVerticallyCentered.run();
+
+ // Double-click top
+ doubleClick.accept(/* y */ 10);
+ checkLetterboxPositions.run();
+ checkIsTop.run();
+
+ // Double-click bottom
+ doubleClick.accept(/* y */ displayHeight - 100);
+ checkLetterboxPositions.run();
+ checkIsVerticallyCentered.run();
+
+ // Double-click bottom
+ doubleClick.accept(/* y */ displayHeight - 100);
+ checkLetterboxPositions.run();
+ checkIsBottom.run();
+
+ // Double-click top
+ doubleClick.accept(/* y */ 10);
+ checkLetterboxPositions.run();
+ checkIsVerticallyCentered.run();
+ }
}
@Test
@@ -3609,6 +3605,32 @@
}
@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);
mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
@@ -4884,6 +4906,12 @@
.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);
}
@@ -4898,12 +4926,18 @@
prepareLimitedBounds(activity, -1 /* maxAspect */, screenOrientation, isUnresizable);
}
- /**
- * Setups {@link #mActivity} with restriction on its bounds, such as maxAspect, fixed
- * orientation, and/or whether it is resizable.
- */
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, minAspect,
+ * fixed orientation, and/or whether it is resizable.
+ */
+ static void prepareLimitedBounds(ActivityRecord activity, float maxAspect, float minAspect,
+ int screenOrientation, boolean isUnresizable) {
activity.info.resizeMode = isUnresizable
? RESIZE_MODE_UNRESIZEABLE
: RESIZE_MODE_RESIZEABLE;
@@ -4917,6 +4951,9 @@
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);