Loading services/core/java/com/android/server/wm/ActivityRecord.java +31 −17 Original line number Diff line number Diff line Loading @@ -813,6 +813,12 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A @Nullable private Rect mLetterboxBoundsForFixedOrientationAndAspectRatio; // Bounds populated in resolveAspectRatioRestriction when this activity is letterboxed for // aspect ratio. If not null, they are used as parent container in // resolveSizeCompatModeConfiguration and in a constructor of CompatDisplayInsets. @Nullable private Rect mLetterboxBoundsForAspectRatio; // Whether the activity is eligible to be letterboxed for fixed orientation with respect to its // requested orientation, even when it's letterbox for another reason (e.g., size compat mode) // and therefore #isLetterboxedForFixedOrientationAndAspectRatio returns false. Loading Loading @@ -8402,10 +8408,14 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A fullConfig.windowConfiguration.getRotation()); } final Rect letterboxedContainerBounds = mLetterboxBoundsForFixedOrientationAndAspectRatio != null ? mLetterboxBoundsForFixedOrientationAndAspectRatio : mLetterboxBoundsForAspectRatio; // The role of CompatDisplayInsets is like the override bounds. mCompatDisplayInsets = new CompatDisplayInsets( mDisplayContent, this, mLetterboxBoundsForFixedOrientationAndAspectRatio); new CompatDisplayInsets(mDisplayContent, this, letterboxedContainerBounds); } private void clearSizeCompatModeAttributes() { Loading Loading @@ -8477,6 +8487,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A mIsAspectRatioApplied = false; mIsEligibleForFixedOrientationLetterbox = false; mLetterboxBoundsForFixedOrientationAndAspectRatio = null; mLetterboxBoundsForAspectRatio = null; // Can't use resolvedConfig.windowConfiguration.getWindowingMode() because it can be // different from windowing mode of the task (PiP) during transition from fullscreen to PiP Loading Loading @@ -8511,9 +8522,11 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A getTaskFragment().computeConfigResourceOverrides(resolvedConfig, newParentConfiguration); } } // If activity in fullscreen mode is letterboxed because of fixed orientation then bounds // are already calculated in resolveFixedOrientationConfiguration. } else if (!isLetterboxedForFixedOrientationAndAspectRatio()) { // are already calculated in resolveFixedOrientationConfiguration, or if in size compat // mode, it should already be calculated in resolveSizeCompatModeConfiguration if (!isLetterboxedForFixedOrientationAndAspectRatio() && !mInSizeCompatModeForBounds) { resolveAspectRatioRestriction(newParentConfiguration); } Loading Loading @@ -8920,7 +8933,8 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A } final CompatDisplayInsets compatDisplayInsets = getCompatDisplayInsets(); if (compatDisplayInsets != null && !compatDisplayInsets.mIsInFixedOrientationLetterbox) { if (compatDisplayInsets != null && !compatDisplayInsets.mIsInFixedOrientationOrAspectRatioLetterbox) { // App prefers to keep its original size. // If the size compat is from previous fixed orientation letterboxing, we may want to // have fixed orientation letterbox again, otherwise it will show the size compat Loading Loading @@ -9052,6 +9066,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A // restrict, the bounds should be the requested override bounds. getTaskFragment().computeConfigResourceOverrides(resolvedConfig, newParentConfiguration, getFixedRotationTransformDisplayInfo()); mLetterboxBoundsForAspectRatio = new Rect(resolvedBounds); } } Loading Loading @@ -10620,10 +10635,10 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A /** Whether the {@link Task} windowingMode represents a floating window*/ final boolean mIsFloating; /** * Whether is letterboxed because of fixed orientation when the unresizable activity is * first shown. * Whether is letterboxed because of fixed orientation or aspect ratio when the * unresizable activity is first shown. */ final boolean mIsInFixedOrientationLetterbox; final boolean mIsInFixedOrientationOrAspectRatioLetterbox; /** * The nonDecorInsets for each rotation. Includes the navigation bar and cutout insets. It * is used to compute the appBounds. Loading @@ -10638,7 +10653,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A /** Constructs the environment to simulate the bounds behavior of the given container. */ CompatDisplayInsets(DisplayContent display, ActivityRecord container, @Nullable Rect fixedOrientationBounds) { @Nullable Rect letterboxedContainerBounds) { mOriginalRotation = display.getRotation(); mIsFloating = container.getWindowConfiguration().tasksAreFloating(); mOriginalRequestedOrientation = container.getRequestedConfigurationOrientation(); Loading @@ -10653,22 +10668,21 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A mNonDecorInsets[rotation] = emptyRect; mStableInsets[rotation] = emptyRect; } mIsInFixedOrientationLetterbox = false; mIsInFixedOrientationOrAspectRatioLetterbox = false; return; } final Task task = container.getTask(); mIsInFixedOrientationLetterbox = fixedOrientationBounds != null; mIsInFixedOrientationOrAspectRatioLetterbox = letterboxedContainerBounds != null; // Store the bounds of the Task for the non-resizable activity to use in size compat // mode so that the activity will not be resized regardless the windowing mode it is // currently in. // When an activity needs to be letterboxed because of fixed orientation, use fixed // orientation bounds instead of task bounds since the activity will be displayed // within these even if it is in size compat mode. final Rect filledContainerBounds = mIsInFixedOrientationLetterbox ? fixedOrientationBounds // When an activity needs to be letterboxed because of fixed orientation or aspect // ratio, use resolved bounds instead of task bounds since the activity will be // displayed within these even if it is in size compat mode. final Rect filledContainerBounds = mIsInFixedOrientationOrAspectRatioLetterbox ? letterboxedContainerBounds : task != null ? task.getBounds() : display.getBounds(); final int filledContainerRotation = task != null ? task.getConfiguration().windowConfiguration.getRotation() Loading services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java +33 −2 Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ 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; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; import static android.content.pm.PackageManager.USER_MIN_ASPECT_RATIO_16_9; import static android.content.pm.PackageManager.USER_MIN_ASPECT_RATIO_3_2; Loading Loading @@ -1910,7 +1911,6 @@ public class SizeCompatTests extends WindowTestsBase { assertThat(mActivity.inSizeCompatMode()).isTrue(); assertActivityMaxBoundsSandboxed(); final int scale = dh / dw; // App bounds should be dh / scale x dw / scale Loading Loading @@ -4100,6 +4100,37 @@ public class SizeCompatTests extends WindowTestsBase { assertFalse(mActivity.isLetterboxedForFixedOrientationAndAspectRatio()); } @Test public void testFixedAspectRatioAppInPortraitCloseToSquareDisplay_notInSizeCompat() { setUpDisplaySizeWithApp(2200, 2280); mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */); 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(); prepareMinAspectRatio(mActivity, OVERRIDE_MIN_ASPECT_RATIO_LARGE_VALUE, SCREEN_ORIENTATION_LANDSCAPE); // To force config to update again but with the same landscape orientation. mActivity.setRequestedOrientation(SCREEN_ORIENTATION_SENSOR_LANDSCAPE); assertTrue(mActivity.shouldCreateCompatDisplayInsets()); assertNotNull(mActivity.getCompatDisplayInsets()); // Activity is not letterboxed for fixed orientation because orientation is respected // with insets, and should not be in size compat mode assertFalse(mActivity.isLetterboxedForFixedOrientationAndAspectRatio()); assertFalse(mActivity.inSizeCompatMode()); } @Test public void testApplyAspectRatio_activityAlignWithParentAppVertical() { // The display's app bounds will be (0, 100, 1000, 2350) Loading services/tests/wmtests/src/com/android/server/wm/TaskTests.java +1 −1 Original line number Diff line number Diff line Loading @@ -799,7 +799,7 @@ public class TaskTests extends WindowTestsBase { final ActivityRecord activity = new ActivityBuilder(mAtm).setTask(task).build(); final ActivityRecord.CompatDisplayInsets compatInsets = new ActivityRecord.CompatDisplayInsets( display, activity, /* fixedOrientationBounds= */ null); display, activity, /* letterboxedContainerBounds */ null); task.computeConfigResourceOverrides(inOutConfig, parentConfig, compatInsets); assertEquals(largerLandscapeBounds, inOutConfig.windowConfiguration.getAppBounds()); Loading Loading
services/core/java/com/android/server/wm/ActivityRecord.java +31 −17 Original line number Diff line number Diff line Loading @@ -813,6 +813,12 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A @Nullable private Rect mLetterboxBoundsForFixedOrientationAndAspectRatio; // Bounds populated in resolveAspectRatioRestriction when this activity is letterboxed for // aspect ratio. If not null, they are used as parent container in // resolveSizeCompatModeConfiguration and in a constructor of CompatDisplayInsets. @Nullable private Rect mLetterboxBoundsForAspectRatio; // Whether the activity is eligible to be letterboxed for fixed orientation with respect to its // requested orientation, even when it's letterbox for another reason (e.g., size compat mode) // and therefore #isLetterboxedForFixedOrientationAndAspectRatio returns false. Loading Loading @@ -8402,10 +8408,14 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A fullConfig.windowConfiguration.getRotation()); } final Rect letterboxedContainerBounds = mLetterboxBoundsForFixedOrientationAndAspectRatio != null ? mLetterboxBoundsForFixedOrientationAndAspectRatio : mLetterboxBoundsForAspectRatio; // The role of CompatDisplayInsets is like the override bounds. mCompatDisplayInsets = new CompatDisplayInsets( mDisplayContent, this, mLetterboxBoundsForFixedOrientationAndAspectRatio); new CompatDisplayInsets(mDisplayContent, this, letterboxedContainerBounds); } private void clearSizeCompatModeAttributes() { Loading Loading @@ -8477,6 +8487,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A mIsAspectRatioApplied = false; mIsEligibleForFixedOrientationLetterbox = false; mLetterboxBoundsForFixedOrientationAndAspectRatio = null; mLetterboxBoundsForAspectRatio = null; // Can't use resolvedConfig.windowConfiguration.getWindowingMode() because it can be // different from windowing mode of the task (PiP) during transition from fullscreen to PiP Loading Loading @@ -8511,9 +8522,11 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A getTaskFragment().computeConfigResourceOverrides(resolvedConfig, newParentConfiguration); } } // If activity in fullscreen mode is letterboxed because of fixed orientation then bounds // are already calculated in resolveFixedOrientationConfiguration. } else if (!isLetterboxedForFixedOrientationAndAspectRatio()) { // are already calculated in resolveFixedOrientationConfiguration, or if in size compat // mode, it should already be calculated in resolveSizeCompatModeConfiguration if (!isLetterboxedForFixedOrientationAndAspectRatio() && !mInSizeCompatModeForBounds) { resolveAspectRatioRestriction(newParentConfiguration); } Loading Loading @@ -8920,7 +8933,8 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A } final CompatDisplayInsets compatDisplayInsets = getCompatDisplayInsets(); if (compatDisplayInsets != null && !compatDisplayInsets.mIsInFixedOrientationLetterbox) { if (compatDisplayInsets != null && !compatDisplayInsets.mIsInFixedOrientationOrAspectRatioLetterbox) { // App prefers to keep its original size. // If the size compat is from previous fixed orientation letterboxing, we may want to // have fixed orientation letterbox again, otherwise it will show the size compat Loading Loading @@ -9052,6 +9066,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A // restrict, the bounds should be the requested override bounds. getTaskFragment().computeConfigResourceOverrides(resolvedConfig, newParentConfiguration, getFixedRotationTransformDisplayInfo()); mLetterboxBoundsForAspectRatio = new Rect(resolvedBounds); } } Loading Loading @@ -10620,10 +10635,10 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A /** Whether the {@link Task} windowingMode represents a floating window*/ final boolean mIsFloating; /** * Whether is letterboxed because of fixed orientation when the unresizable activity is * first shown. * Whether is letterboxed because of fixed orientation or aspect ratio when the * unresizable activity is first shown. */ final boolean mIsInFixedOrientationLetterbox; final boolean mIsInFixedOrientationOrAspectRatioLetterbox; /** * The nonDecorInsets for each rotation. Includes the navigation bar and cutout insets. It * is used to compute the appBounds. Loading @@ -10638,7 +10653,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A /** Constructs the environment to simulate the bounds behavior of the given container. */ CompatDisplayInsets(DisplayContent display, ActivityRecord container, @Nullable Rect fixedOrientationBounds) { @Nullable Rect letterboxedContainerBounds) { mOriginalRotation = display.getRotation(); mIsFloating = container.getWindowConfiguration().tasksAreFloating(); mOriginalRequestedOrientation = container.getRequestedConfigurationOrientation(); Loading @@ -10653,22 +10668,21 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A mNonDecorInsets[rotation] = emptyRect; mStableInsets[rotation] = emptyRect; } mIsInFixedOrientationLetterbox = false; mIsInFixedOrientationOrAspectRatioLetterbox = false; return; } final Task task = container.getTask(); mIsInFixedOrientationLetterbox = fixedOrientationBounds != null; mIsInFixedOrientationOrAspectRatioLetterbox = letterboxedContainerBounds != null; // Store the bounds of the Task for the non-resizable activity to use in size compat // mode so that the activity will not be resized regardless the windowing mode it is // currently in. // When an activity needs to be letterboxed because of fixed orientation, use fixed // orientation bounds instead of task bounds since the activity will be displayed // within these even if it is in size compat mode. final Rect filledContainerBounds = mIsInFixedOrientationLetterbox ? fixedOrientationBounds // When an activity needs to be letterboxed because of fixed orientation or aspect // ratio, use resolved bounds instead of task bounds since the activity will be // displayed within these even if it is in size compat mode. final Rect filledContainerBounds = mIsInFixedOrientationOrAspectRatioLetterbox ? letterboxedContainerBounds : task != null ? task.getBounds() : display.getBounds(); final int filledContainerRotation = task != null ? task.getConfiguration().windowConfiguration.getRotation() Loading
services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java +33 −2 Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ 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; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; import static android.content.pm.PackageManager.USER_MIN_ASPECT_RATIO_16_9; import static android.content.pm.PackageManager.USER_MIN_ASPECT_RATIO_3_2; Loading Loading @@ -1910,7 +1911,6 @@ public class SizeCompatTests extends WindowTestsBase { assertThat(mActivity.inSizeCompatMode()).isTrue(); assertActivityMaxBoundsSandboxed(); final int scale = dh / dw; // App bounds should be dh / scale x dw / scale Loading Loading @@ -4100,6 +4100,37 @@ public class SizeCompatTests extends WindowTestsBase { assertFalse(mActivity.isLetterboxedForFixedOrientationAndAspectRatio()); } @Test public void testFixedAspectRatioAppInPortraitCloseToSquareDisplay_notInSizeCompat() { setUpDisplaySizeWithApp(2200, 2280); mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */); 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(); prepareMinAspectRatio(mActivity, OVERRIDE_MIN_ASPECT_RATIO_LARGE_VALUE, SCREEN_ORIENTATION_LANDSCAPE); // To force config to update again but with the same landscape orientation. mActivity.setRequestedOrientation(SCREEN_ORIENTATION_SENSOR_LANDSCAPE); assertTrue(mActivity.shouldCreateCompatDisplayInsets()); assertNotNull(mActivity.getCompatDisplayInsets()); // Activity is not letterboxed for fixed orientation because orientation is respected // with insets, and should not be in size compat mode assertFalse(mActivity.isLetterboxedForFixedOrientationAndAspectRatio()); assertFalse(mActivity.inSizeCompatMode()); } @Test public void testApplyAspectRatio_activityAlignWithParentAppVertical() { // The display's app bounds will be (0, 100, 1000, 2350) Loading
services/tests/wmtests/src/com/android/server/wm/TaskTests.java +1 −1 Original line number Diff line number Diff line Loading @@ -799,7 +799,7 @@ public class TaskTests extends WindowTestsBase { final ActivityRecord activity = new ActivityBuilder(mAtm).setTask(task).build(); final ActivityRecord.CompatDisplayInsets compatInsets = new ActivityRecord.CompatDisplayInsets( display, activity, /* fixedOrientationBounds= */ null); display, activity, /* letterboxedContainerBounds */ null); task.computeConfigResourceOverrides(inOutConfig, parentConfig, compatInsets); assertEquals(largerLandscapeBounds, inOutConfig.windowConfiguration.getAppBounds()); Loading