summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Graciela Wissen Putri <gracielawputri@google.com> 2024-02-08 11:55:07 +0000
committer Graciela Wissen Putri <gracielawputri@google.com> 2024-02-19 11:32:22 +0000
commita2d4a20a0d18ed13009a15699dd65ffb250b1444 (patch)
tree2610688634edcd773fc6aa6eed04fca1e98f98bd
parent72dc708c55a89080e0a6ae529b818fbe6e034e55 (diff)
Don't use display orientation for reachability conditions
We should base whether to enable reachability on bounds filling parent vertically/horizontally. Old assumption is incorrect that mismatched orientation between parent and activity is the only way that activities can be letterboxed. Letterboxed activities can have the same orientation as parent but be letterboxed because of aspect ratio restrictions. Fix: 323526309 Test: atest SizeCompatTests Change-Id: Iadb220e5df7640d5fc6b515ed0c60b376e135919
-rw-r--r--services/core/java/com/android/server/wm/LetterboxUiController.java31
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java253
2 files changed, 162 insertions, 122 deletions
diff --git a/services/core/java/com/android/server/wm/LetterboxUiController.java b/services/core/java/com/android/server/wm/LetterboxUiController.java
index edf9da1e0bf5..98d2fe34ec11 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_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;
@@ -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
@@ -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
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 f42cdb88021e..0b54a5872fa8 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_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;
@@ -211,90 +212,46 @@ public class SizeCompatTests extends WindowTestsBase {
@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);
-
- // 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();
+ testReachabilityEnabledForTranslucentActivity(/* dw */ 2500, /* dh */1000,
+ SCREEN_ORIENTATION_PORTRAIT, /* minAspectRatio */ 0f,
+ /* horizontalReachability */ true);
+ }
- // 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();
@@ -302,7 +259,7 @@ public class SizeCompatTests extends WindowTestsBase {
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);
@@ -324,39 +281,78 @@ public class SizeCompatTests extends WindowTestsBase {
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();
-
- final Consumer<Integer> doubleClick =
- (Integer y) -> {
- mActivity.mLetterboxUiController.handleVerticalDoubleTap(y);
- mActivity.mRootWindowContainer.performSurfacePlacement();
- };
-
- // Initial state
- checkIsCentered.run();
-
- // Double-click top
- doubleClick.accept(/* y */ 10);
- checkLetterboxPositions.run();
- checkIsTop.run();
-
- // Double-click bottom
- doubleClick.accept(/* y */ 1990);
- checkLetterboxPositions.run();
- checkIsCentered.run();
-
- // Double-click bottom
- doubleClick.accept(/* y */ 1990);
- checkLetterboxPositions.run();
- checkIsBottom.run();
-
- // Double-click top
- doubleClick.accept(/* y */ 10);
- checkLetterboxPositions.run();
- checkIsCentered.run();
+ && innerBoundsOf.apply(translucentActivity).bottom < displayHeight)
+ .isTrue();
+
+ if (horizontalReachability) {
+ final Consumer<Integer> doubleClick =
+ (Integer x) -> {
+ mActivity.mLetterboxUiController.handleHorizontalDoubleTap(x);
+ mActivity.mRootWindowContainer.performSurfacePlacement();
+ };
+
+ // Initial state
+ checkIsHorizontallyCentered.run();
+
+ // Double-click left
+ doubleClick.accept(/* x */ 10);
+ checkLetterboxPositions.run();
+ checkIsLeft.run();
+
+ // Double-click right
+ doubleClick.accept(/* x */ displayWidth - 100);
+ checkLetterboxPositions.run();
+ checkIsHorizontallyCentered.run();
+
+ // Double-click right
+ doubleClick.accept(/* x */ displayWidth - 100);
+ checkLetterboxPositions.run();
+ checkIsRight.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 @@ public class SizeCompatTests extends WindowTestsBase {
}
@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 */);
@@ -4859,6 +4881,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);
}
@@ -4873,11 +4901,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
@@ -4892,6 +4926,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);