diff options
4 files changed, 116 insertions, 31 deletions
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/UserAspectRatioSettingsWindowManager.java b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/UserAspectRatioSettingsWindowManager.java index 81d13999e73c..7c280994042b 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/UserAspectRatioSettingsWindowManager.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/UserAspectRatioSettingsWindowManager.java @@ -20,6 +20,7 @@ import static android.window.TaskConstants.TASK_CHILD_LAYER_COMPAT_UI; import android.annotation.NonNull; import android.annotation.Nullable; +import android.app.AppCompatTaskInfo; import android.app.TaskInfo; import android.content.Context; import android.content.Intent; @@ -88,7 +89,8 @@ class UserAspectRatioSettingsWindowManager extends CompatUIWindowManagerAbstract mShellExecutor = shellExecutor; mUserAspectRatioButtonShownChecker = userAspectRatioButtonStateChecker; mUserAspectRatioButtonStateConsumer = userAspectRatioButtonShownConsumer; - mHasUserAspectRatioSettingsButton = getHasUserAspectRatioSettingsButton(taskInfo); + mHasUserAspectRatioSettingsButton = shouldShowUserAspectRatioSettingsButton( + taskInfo.appCompatTaskInfo, taskInfo.baseIntent); mCompatUIHintsState = compatUIHintsState; mOnButtonClicked = onButtonClicked; mDisappearTimeSupplier = disappearTimeSupplier; @@ -134,7 +136,8 @@ class UserAspectRatioSettingsWindowManager extends CompatUIWindowManagerAbstract public boolean updateCompatInfo(@NonNull TaskInfo taskInfo, @NonNull ShellTaskOrganizer.TaskListener taskListener, boolean canShow) { final boolean prevHasUserAspectRatioSettingsButton = mHasUserAspectRatioSettingsButton; - mHasUserAspectRatioSettingsButton = getHasUserAspectRatioSettingsButton(taskInfo); + mHasUserAspectRatioSettingsButton = shouldShowUserAspectRatioSettingsButton( + taskInfo.appCompatTaskInfo, taskInfo.baseIntent); if (!super.updateCompatInfo(taskInfo, taskListener, canShow)) { return false; @@ -227,12 +230,21 @@ class UserAspectRatioSettingsWindowManager extends CompatUIWindowManagerAbstract return SystemClock.uptimeMillis() + hideDelay; } - private boolean getHasUserAspectRatioSettingsButton(@NonNull TaskInfo taskInfo) { - final Intent intent = taskInfo.baseIntent; - return taskInfo.appCompatTaskInfo.topActivityEligibleForUserAspectRatioButton - && (taskInfo.appCompatTaskInfo.topActivityBoundsLetterboxed - || taskInfo.appCompatTaskInfo.isUserFullscreenOverrideEnabled) - && !taskInfo.appCompatTaskInfo.isSystemFullscreenOverrideEnabled + private boolean shouldShowUserAspectRatioSettingsButton(@NonNull AppCompatTaskInfo taskInfo, + @NonNull Intent intent) { + final Rect stableBounds = getTaskStableBounds(); + final int letterboxHeight = taskInfo.topActivityLetterboxHeight; + final int letterboxWidth = taskInfo.topActivityLetterboxWidth; + // App is not visibly letterboxed if it covers status bar/bottom insets or matches the + // stable bounds, so don't show the button + if (stableBounds.height() <= letterboxHeight && stableBounds.width() <= letterboxWidth) { + return false; + } + + return taskInfo.topActivityEligibleForUserAspectRatioButton + && (taskInfo.topActivityBoundsLetterboxed + || taskInfo.isUserFullscreenOverrideEnabled) + && !taskInfo.isSystemFullscreenOverrideEnabled && Intent.ACTION_MAIN.equals(intent.getAction()) && intent.hasCategory(Intent.CATEGORY_LAUNCHER) && (!mUserAspectRatioButtonShownChecker.get() || isShowingButton()); diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/UserAspectRatioSettingsWindowManagerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/UserAspectRatioSettingsWindowManagerTest.java index 9fe2cb11e804..81ba4b37d13b 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/UserAspectRatioSettingsWindowManagerTest.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/UserAspectRatioSettingsWindowManagerTest.java @@ -113,8 +113,22 @@ public class UserAspectRatioSettingsWindowManagerTest extends ShellTestCase { mExecutor = new TestShellExecutor(); mTaskInfo = createTaskInfo(/* eligibleForUserAspectRatioButton= */ false, /* topActivityBoundsLetterboxed */ true, ACTION_MAIN, CATEGORY_LAUNCHER); + final DisplayInfo displayInfo = new DisplayInfo(); + final int displayWidth = 1000; + final int displayHeight = 1200; + displayInfo.logicalWidth = displayWidth; + displayInfo.logicalHeight = displayHeight; + final DisplayLayout displayLayout = new DisplayLayout(displayInfo, + mContext.getResources(), /* hasNavigationBar= */ true, /* hasStatusBar= */ false); + InsetsState insetsState = new InsetsState(); + insetsState.setDisplayFrame(new Rect(0, 0, displayWidth, displayHeight)); + InsetsSource insetsSource = new InsetsSource( + InsetsSource.createId(null, 0, navigationBars()), navigationBars()); + insetsSource.setFrame(0, displayHeight - 200, displayWidth, displayHeight); + insetsState.addSource(insetsSource); + displayLayout.setInsets(mContext.getResources(), insetsState); mWindowManager = new UserAspectRatioSettingsWindowManager(mContext, mTaskInfo, - mSyncTransactionQueue, mTaskListener, new DisplayLayout(), new CompatUIHintsState(), + mSyncTransactionQueue, mTaskListener, displayLayout, new CompatUIHintsState(), mOnUserAspectRatioSettingsButtonClicked, mExecutor, flags -> 0, mUserAspectRatioButtonShownChecker, s -> {}); spyOn(mWindowManager); @@ -253,6 +267,31 @@ public class UserAspectRatioSettingsWindowManagerTest extends ShellTestCase { } @Test + public void testEligibleButtonHiddenIfLetterboxBoundsEqualToStableBounds() { + TaskInfo taskInfo = createTaskInfo(/* eligibleForUserAspectRatioButton= */ + true, /* topActivityBoundsLetterboxed */ true, ACTION_MAIN, CATEGORY_LAUNCHER); + + final Rect stableBounds = mWindowManager.getTaskStableBounds(); + final int stableHeight = stableBounds.height(); + + // Letterboxed activity bounds equal to stable bounds, layout shouldn't be inflated + taskInfo.appCompatTaskInfo.topActivityLetterboxHeight = stableHeight; + taskInfo.appCompatTaskInfo.topActivityLetterboxWidth = stableBounds.width(); + + mWindowManager.updateCompatInfo(taskInfo, mTaskListener, /* canShow= */ true); + + verify(mWindowManager, never()).inflateLayout(); + + // Letterboxed activity bounds smaller than stable bounds, layout should be inflated + taskInfo.appCompatTaskInfo.topActivityLetterboxHeight = stableHeight - 100; + + clearInvocations(mWindowManager); + mWindowManager.updateCompatInfo(taskInfo, mTaskListener, /* canShow= */ true); + + verify(mWindowManager).inflateLayout(); + } + + @Test public void testUpdateDisplayLayout() { final DisplayInfo displayInfo = new DisplayInfo(); displayInfo.logicalWidth = 1000; diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java index f15003966d32..2696fb6cba26 100644 --- a/services/core/java/com/android/server/wm/ActivityRecord.java +++ b/services/core/java/com/android/server/wm/ActivityRecord.java @@ -8943,6 +8943,15 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A } } + // Fixed orientation bounds are the same as its parent container, so clear the fixed + // orientation bounds. This can happen in close to square displays where the orientation + // is not respected with insets, but the display still matches or is less than the + // activity aspect ratio. + if (resolvedBounds.equals(parentBounds)) { + resolvedBounds.set(prevResolvedBounds); + return; + } + // Calculate app bounds using fixed orientation bounds because they will be needed later // for comparison with size compat app bounds in {@link resolveSizeCompatModeConfiguration}. getTaskFragment().computeConfigResourceOverrides(getResolvedOverrideConfiguration(), 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..d3f69b586cf5 100644 --- a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java @@ -46,6 +46,7 @@ import static android.view.WindowInsets.Type.statusBars; import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER; import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING; import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION; +import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR; import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing; @@ -100,6 +101,7 @@ import android.content.pm.ActivityInfo.ScreenOrientation; import android.content.pm.IPackageManager; import android.content.pm.PackageManager; import android.content.res.Configuration; +import android.graphics.Insets; import android.graphics.Rect; import android.os.Binder; import android.os.RemoteException; @@ -153,6 +155,8 @@ public class SizeCompatTests extends WindowTestsBase { private static final String CONFIG_NEVER_CONSTRAIN_DISPLAY_APIS_ALL_PACKAGES = "never_constrain_display_apis_all_packages"; + private static final float DELTA_ASPECT_RATIO_TOLERANCE = 0.005f; + @Rule public TestRule compatChangeRule = new PlatformCompatChangeRule(); @@ -2143,7 +2147,7 @@ public class SizeCompatTests extends WindowTestsBase { final Rect afterBounds = mActivity.getBounds(); final float actualAspectRatio = 1f * afterBounds.height() / afterBounds.width(); assertEquals(LetterboxConfiguration.DEFAULT_LETTERBOX_ASPECT_RATIO_FOR_MULTI_WINDOW, - actualAspectRatio, 0.001f); + actualAspectRatio, DELTA_ASPECT_RATIO_TOLERANCE); assertTrue(mActivity.areBoundsLetterboxed()); } @@ -2179,7 +2183,7 @@ public class SizeCompatTests extends WindowTestsBase { // default letterbox aspect ratio for multi-window. final Rect afterBounds = mActivity.getBounds(); final float actualAspectRatio = 1f * afterBounds.height() / afterBounds.width(); - assertEquals(minAspectRatio, actualAspectRatio, 0.001f); + assertEquals(minAspectRatio, actualAspectRatio, DELTA_ASPECT_RATIO_TOLERANCE); assertTrue(mActivity.areBoundsLetterboxed()); } @@ -2487,7 +2491,7 @@ public class SizeCompatTests extends WindowTestsBase { final float afterAspectRatio = (float) Math.max(width, height) / (float) Math.min(width, height); - assertEquals(expectedAspectRatio, afterAspectRatio, 0.001f); + assertEquals(expectedAspectRatio, afterAspectRatio, DELTA_ASPECT_RATIO_TOLERANCE); } @Test @@ -2512,7 +2516,7 @@ public class SizeCompatTests extends WindowTestsBase { float expectedAspectRatio = 1f * displayWidth / getExpectedSplitSize(displayHeight); final Rect afterBounds = activity.getBounds(); final float afterAspectRatio = (float) (afterBounds.height()) / afterBounds.width(); - assertEquals(expectedAspectRatio, afterAspectRatio, 0.001f); + assertEquals(expectedAspectRatio, afterAspectRatio, DELTA_ASPECT_RATIO_TOLERANCE); } @Test @@ -2537,7 +2541,7 @@ public class SizeCompatTests extends WindowTestsBase { float expectedAspectRatio = 1f * displayHeight / getExpectedSplitSize(displayWidth); final Rect afterBounds = activity.getBounds(); final float afterAspectRatio = (float) (afterBounds.height()) / afterBounds.width(); - assertEquals(expectedAspectRatio, afterAspectRatio, 0.001f); + assertEquals(expectedAspectRatio, afterAspectRatio, DELTA_ASPECT_RATIO_TOLERANCE); } @Test @@ -2563,7 +2567,7 @@ public class SizeCompatTests extends WindowTestsBase { float expectedAspectRatio = 1f * displayWidth / getExpectedSplitSize(displayHeight); final Rect afterBounds = activity.getBounds(); final float afterAspectRatio = (float) (afterBounds.width()) / afterBounds.height(); - assertEquals(expectedAspectRatio, afterAspectRatio, 0.001f); + assertEquals(expectedAspectRatio, afterAspectRatio, DELTA_ASPECT_RATIO_TOLERANCE); } @Test @@ -2589,7 +2593,7 @@ public class SizeCompatTests extends WindowTestsBase { float expectedAspectRatio = 1f * displayHeight / getExpectedSplitSize(displayWidth); final Rect afterBounds = activity.getBounds(); final float afterAspectRatio = (float) (afterBounds.width()) / afterBounds.height(); - assertEquals(expectedAspectRatio, afterAspectRatio, 0.001f); + assertEquals(expectedAspectRatio, afterAspectRatio, DELTA_ASPECT_RATIO_TOLERANCE); } @Test @@ -2629,7 +2633,7 @@ public class SizeCompatTests extends WindowTestsBase { float expectedAspectRatio = 1f * screenHeight / getExpectedSplitSize(screenWidth); final Rect afterBounds = activity.getBounds(); final float afterAspectRatio = (float) (afterBounds.height()) / afterBounds.width(); - assertEquals(expectedAspectRatio, afterAspectRatio, 0.001f); + assertEquals(expectedAspectRatio, afterAspectRatio, DELTA_ASPECT_RATIO_TOLERANCE); assertFalse(activity.areBoundsLetterboxed()); } @@ -2670,7 +2674,7 @@ public class SizeCompatTests extends WindowTestsBase { float expectedAspectRatio = 1f * screenWidth / getExpectedSplitSize(screenHeight); final Rect afterBounds = activity.getBounds(); final float afterAspectRatio = (float) (afterBounds.width()) / afterBounds.height(); - assertEquals(expectedAspectRatio, afterAspectRatio, 0.001f); + assertEquals(expectedAspectRatio, afterAspectRatio, DELTA_ASPECT_RATIO_TOLERANCE); assertFalse(activity.areBoundsLetterboxed()); } @@ -2847,9 +2851,8 @@ public class SizeCompatTests extends WindowTestsBase { assertFitted(); // Check that the display aspect ratio is used by the app. final float targetMinAspectRatio = 1f * displayHeight / displayWidth; - final float delta = 0.01f; assertEquals(targetMinAspectRatio, ActivityRecord - .computeAspectRatio(mActivity.getBounds()), delta); + .computeAspectRatio(mActivity.getBounds()), DELTA_ASPECT_RATIO_TOLERANCE); } @Test @@ -2883,9 +2886,8 @@ public class SizeCompatTests extends WindowTestsBase { assertFitted(); // Check that the display aspect ratio is used by the app. final float targetMinAspectRatio = 1f * displayWidth / displayHeight; - final float delta = 0.01f; assertEquals(targetMinAspectRatio, ActivityRecord - .computeAspectRatio(mActivity.getBounds()), delta); + .computeAspectRatio(mActivity.getBounds()), DELTA_ASPECT_RATIO_TOLERANCE); } @Test @@ -2910,9 +2912,8 @@ public class SizeCompatTests extends WindowTestsBase { assertFitted(); // Check that the display aspect ratio is used by the app. final float targetMinAspectRatio = 1f * displayHeight / displayWidth; - final float delta = 0.01f; assertEquals(targetMinAspectRatio, ActivityRecord - .computeAspectRatio(mActivity.getBounds()), delta); + .computeAspectRatio(mActivity.getBounds()), DELTA_ASPECT_RATIO_TOLERANCE); } @Test @@ -2937,9 +2938,8 @@ public class SizeCompatTests extends WindowTestsBase { assertFitted(); // Check that the display aspect ratio is used by the app. final float targetMinAspectRatio = 1f * displayWidth / displayHeight; - final float delta = 0.01f; assertEquals(targetMinAspectRatio, ActivityRecord - .computeAspectRatio(mActivity.getBounds()), delta); + .computeAspectRatio(mActivity.getBounds()), DELTA_ASPECT_RATIO_TOLERANCE); } @Test @@ -4053,6 +4053,32 @@ public class SizeCompatTests extends WindowTestsBase { } @Test + public void testPortraitCloseToSquareDisplayWithTaskbar_notLetterboxed() { + // Set up portrait close to square display + setUpDisplaySizeWithApp(2200, 2280); + final DisplayContent display = mActivity.mDisplayContent; + // Simulate taskbar, final app bounds are (0, 0, 2200, 2130) - landscape + final WindowState navbar = createWindow(null, TYPE_NAVIGATION_BAR, mDisplayContent, + "navbar"); + final Binder owner = new Binder(); + navbar.mAttrs.providedInsets = new InsetsFrameProvider[] { + new InsetsFrameProvider(owner, 0, WindowInsets.Type.navigationBars()) + .setInsetsSize(Insets.of(0, 0, 0, 150)) + }; + display.getDisplayPolicy().addWindowLw(navbar, navbar.mAttrs); + assertTrue(navbar.providesDisplayDecorInsets() + && display.getDisplayPolicy().updateDecorInsetsInfo()); + display.sendNewConfiguration(); + + prepareUnresizable(mActivity, SCREEN_ORIENTATION_PORTRAIT); + + // Activity is fullscreen even though orientation is not respected with insets, because + // the display still matches or is less than the activity aspect ratio + assertEquals(display.getBounds(), mActivity.getBounds()); + assertFalse(mActivity.isLetterboxedForFixedOrientationAndAspectRatio()); + } + + @Test public void testApplyAspectRatio_activityAlignWithParentAppVertical() { // The display's app bounds will be (0, 100, 1000, 2350) final DisplayContent display = new TestDisplayContent.Builder(mAtm, 1000, 2500) @@ -4275,7 +4301,7 @@ public class SizeCompatTests extends WindowTestsBase { .getFixedOrientationLetterboxAspectRatio(parentConfig); float expected = mActivity.mLetterboxUiController.getSplitScreenAspectRatio(); - assertEquals(expected, actual, 0.01); + assertEquals(expected, actual, DELTA_ASPECT_RATIO_TOLERANCE); } @Test @@ -4671,13 +4697,12 @@ public class SizeCompatTests extends WindowTestsBase { .windowConfiguration.getAppBounds()); // Check that aspect ratio of app bounds is equal to the min aspect ratio. - final float delta = 0.01f; assertEquals(targetMinAspectRatio, ActivityRecord - .computeAspectRatio(fixedOrientationAppBounds), delta); + .computeAspectRatio(fixedOrientationAppBounds), DELTA_ASPECT_RATIO_TOLERANCE); assertEquals(targetMinAspectRatio, ActivityRecord - .computeAspectRatio(minAspectRatioAppBounds), delta); + .computeAspectRatio(minAspectRatioAppBounds), DELTA_ASPECT_RATIO_TOLERANCE); assertEquals(targetMinAspectRatio, ActivityRecord - .computeAspectRatio(sizeCompatAppBounds), delta); + .computeAspectRatio(sizeCompatAppBounds), DELTA_ASPECT_RATIO_TOLERANCE); } @Test |