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  |