Loading services/core/java/com/android/server/wm/ActivityRecord.java +20 −11 Original line number Diff line number Diff line Loading @@ -8445,21 +8445,23 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A private void updateResolvedBoundsPosition(Configuration newParentConfiguration) { final Configuration resolvedConfig = getResolvedOverrideConfiguration(); final Rect resolvedBounds = resolvedConfig.windowConfiguration.getBounds(); if (resolvedBounds.isEmpty()) { return; } final Rect screenResolvedBounds = mSizeCompatBounds != null ? mSizeCompatBounds : resolvedBounds; final Rect parentAppBounds = newParentConfiguration.windowConfiguration.getAppBounds(); final Rect parentBounds = newParentConfiguration.windowConfiguration.getBounds(); if (resolvedBounds.isEmpty()) { return; } final float screenResolvedBoundsWidth = screenResolvedBounds.width(); final float parentAppBoundsWidth = parentAppBounds.width(); // Horizontal position int offsetX = 0; if (parentBounds.width() != screenResolvedBounds.width()) { if (screenResolvedBounds.width() <= parentAppBounds.width()) { if (parentBounds.width() != screenResolvedBoundsWidth) { if (screenResolvedBoundsWidth <= parentAppBoundsWidth) { float positionMultiplier = mLetterboxUiController.getHorizontalPositionMultiplier( newParentConfiguration); offsetX = Math.max(0, (int) Math.ceil((parentAppBounds.width() - screenResolvedBounds.width()) * positionMultiplier) offsetX = Math.max(0, (int) Math.ceil((parentAppBoundsWidth - screenResolvedBoundsWidth) * positionMultiplier) // This is added to make sure that insets added inside // CompatDisplayInsets#getContainerBounds() do not break the alignment // provided by the positionMultiplier Loading @@ -8467,14 +8469,21 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A } } final float parentAppBoundsHeight = parentAppBounds.height(); final float parentBoundsHeight = parentBounds.height(); final float screenResolvedBoundsHeight = screenResolvedBounds.height(); // Vertical position int offsetY = 0; if (parentBounds.height() != screenResolvedBounds.height()) { if (screenResolvedBounds.height() <= parentAppBounds.height()) { if (parentBoundsHeight != screenResolvedBoundsHeight) { if (screenResolvedBoundsHeight <= parentAppBoundsHeight) { float positionMultiplier = mLetterboxUiController.getVerticalPositionMultiplier( newParentConfiguration); offsetY = Math.max(0, (int) Math.ceil((parentAppBounds.height() - screenResolvedBounds.height()) * positionMultiplier) // If in immersive mode, always align to bottom and overlap bottom insets (nav bar, // task bar) as they are transient and hidden. This removes awkward bottom spacing. final float newHeight = mDisplayContent.getDisplayPolicy().isImmersiveMode() ? parentBoundsHeight : parentAppBoundsHeight; offsetY = Math.max(0, (int) Math.ceil((newHeight - screenResolvedBoundsHeight) * positionMultiplier) // This is added to make sure that insets added inside // CompatDisplayInsets#getContainerBounds() do not break the alignment // provided by the positionMultiplier Loading services/core/java/com/android/server/wm/DisplayPolicy.java +4 −0 Original line number Diff line number Diff line Loading @@ -1254,6 +1254,10 @@ public class DisplayPolicy { return mNavigationBar; } boolean isImmersiveMode() { return mIsImmersiveMode; } /** * Control the animation to run when a window's state changes. Return a positive number to * force the animation to a specific resource ID, {@link #ANIMATION_STYLEABLE} to use the Loading services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java +46 −1 Original line number Diff line number Diff line Loading @@ -3510,6 +3510,51 @@ public class SizeCompatTests extends WindowTestsBase { assertEquals(expectedHeight, capturedCrops.get(1).bottom); } @Test public void testLetterboxAlignedToBottom_NotOverlappingNavbar() { assertLandscapeActivityAlignedToBottomWithNavbar(false /* immersive */); } @Test public void testImmersiveLetterboxAlignedToBottom_OverlappingNavbar() { assertLandscapeActivityAlignedToBottomWithNavbar(true /* immersive */); } private void assertLandscapeActivityAlignedToBottomWithNavbar(boolean immersive) { final int screenHeight = 2800; final int screenWidth = 1400; final int taskbarHeight = 200; setUpDisplaySizeWithApp(screenWidth, screenHeight); mActivity.mDisplayContent.setIgnoreOrientationRequest(true); mActivity.mWmService.mLetterboxConfiguration.setLetterboxVerticalPositionMultiplier(1.0f); final InsetsSource navSource = new InsetsSource( InsetsSource.createId(null, 0, navigationBars()), navigationBars()); navSource.setInsetsRoundedCornerFrame(true); // Immersive activity has transient navbar navSource.setVisible(!immersive); navSource.setFrame(new Rect(0, screenHeight - taskbarHeight, screenWidth, screenHeight)); mActivity.mWmService.mLetterboxConfiguration.setLetterboxActivityCornersRadius(15); final WindowState w1 = addWindowToActivity(mActivity); w1.mAboveInsetsState.addSource(navSource); // Prepare unresizable landscape activity prepareUnresizable(mActivity, SCREEN_ORIENTATION_LANDSCAPE); final DisplayPolicy displayPolicy = mActivity.mDisplayContent.getDisplayPolicy(); doReturn(immersive).when(displayPolicy).isImmersiveMode(); mActivity.mRootWindowContainer.performSurfacePlacement(); LetterboxDetails letterboxDetails = mActivity.mLetterboxUiController.getLetterboxDetails(); // Letterboxed activity at bottom assertEquals(new Rect(0, 2100, 1400, 2800), mActivity.getBounds()); final int expectedHeight = immersive ? screenHeight : screenHeight - taskbarHeight; assertEquals(expectedHeight, letterboxDetails.getLetterboxInnerBounds().bottom); } @Test public void testSplitScreenLetterboxDetailsForStatusBar_twoLetterboxedApps() { mAtm.mDevEnableNonResizableMultiWindow = true; Loading Loading @@ -3938,7 +3983,7 @@ public class SizeCompatTests extends WindowTestsBase { mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */); mWm.mLetterboxConfiguration.setIsAutomaticReachabilityInBookModeEnabled(true); mWm.mLetterboxConfiguration.setLetterboxHorizontalPositionMultiplier( 1.0f /*letterboxVerticalPositionMultiplier*/); 1.0f /*letterboxHorizontalPositionMultiplier*/); prepareUnresizable(mActivity, SCREEN_ORIENTATION_PORTRAIT); Rect letterboxNoFold = new Rect(2100, 0, 2800, 1400); Loading Loading
services/core/java/com/android/server/wm/ActivityRecord.java +20 −11 Original line number Diff line number Diff line Loading @@ -8445,21 +8445,23 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A private void updateResolvedBoundsPosition(Configuration newParentConfiguration) { final Configuration resolvedConfig = getResolvedOverrideConfiguration(); final Rect resolvedBounds = resolvedConfig.windowConfiguration.getBounds(); if (resolvedBounds.isEmpty()) { return; } final Rect screenResolvedBounds = mSizeCompatBounds != null ? mSizeCompatBounds : resolvedBounds; final Rect parentAppBounds = newParentConfiguration.windowConfiguration.getAppBounds(); final Rect parentBounds = newParentConfiguration.windowConfiguration.getBounds(); if (resolvedBounds.isEmpty()) { return; } final float screenResolvedBoundsWidth = screenResolvedBounds.width(); final float parentAppBoundsWidth = parentAppBounds.width(); // Horizontal position int offsetX = 0; if (parentBounds.width() != screenResolvedBounds.width()) { if (screenResolvedBounds.width() <= parentAppBounds.width()) { if (parentBounds.width() != screenResolvedBoundsWidth) { if (screenResolvedBoundsWidth <= parentAppBoundsWidth) { float positionMultiplier = mLetterboxUiController.getHorizontalPositionMultiplier( newParentConfiguration); offsetX = Math.max(0, (int) Math.ceil((parentAppBounds.width() - screenResolvedBounds.width()) * positionMultiplier) offsetX = Math.max(0, (int) Math.ceil((parentAppBoundsWidth - screenResolvedBoundsWidth) * positionMultiplier) // This is added to make sure that insets added inside // CompatDisplayInsets#getContainerBounds() do not break the alignment // provided by the positionMultiplier Loading @@ -8467,14 +8469,21 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A } } final float parentAppBoundsHeight = parentAppBounds.height(); final float parentBoundsHeight = parentBounds.height(); final float screenResolvedBoundsHeight = screenResolvedBounds.height(); // Vertical position int offsetY = 0; if (parentBounds.height() != screenResolvedBounds.height()) { if (screenResolvedBounds.height() <= parentAppBounds.height()) { if (parentBoundsHeight != screenResolvedBoundsHeight) { if (screenResolvedBoundsHeight <= parentAppBoundsHeight) { float positionMultiplier = mLetterboxUiController.getVerticalPositionMultiplier( newParentConfiguration); offsetY = Math.max(0, (int) Math.ceil((parentAppBounds.height() - screenResolvedBounds.height()) * positionMultiplier) // If in immersive mode, always align to bottom and overlap bottom insets (nav bar, // task bar) as they are transient and hidden. This removes awkward bottom spacing. final float newHeight = mDisplayContent.getDisplayPolicy().isImmersiveMode() ? parentBoundsHeight : parentAppBoundsHeight; offsetY = Math.max(0, (int) Math.ceil((newHeight - screenResolvedBoundsHeight) * positionMultiplier) // This is added to make sure that insets added inside // CompatDisplayInsets#getContainerBounds() do not break the alignment // provided by the positionMultiplier Loading
services/core/java/com/android/server/wm/DisplayPolicy.java +4 −0 Original line number Diff line number Diff line Loading @@ -1254,6 +1254,10 @@ public class DisplayPolicy { return mNavigationBar; } boolean isImmersiveMode() { return mIsImmersiveMode; } /** * Control the animation to run when a window's state changes. Return a positive number to * force the animation to a specific resource ID, {@link #ANIMATION_STYLEABLE} to use the Loading
services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java +46 −1 Original line number Diff line number Diff line Loading @@ -3510,6 +3510,51 @@ public class SizeCompatTests extends WindowTestsBase { assertEquals(expectedHeight, capturedCrops.get(1).bottom); } @Test public void testLetterboxAlignedToBottom_NotOverlappingNavbar() { assertLandscapeActivityAlignedToBottomWithNavbar(false /* immersive */); } @Test public void testImmersiveLetterboxAlignedToBottom_OverlappingNavbar() { assertLandscapeActivityAlignedToBottomWithNavbar(true /* immersive */); } private void assertLandscapeActivityAlignedToBottomWithNavbar(boolean immersive) { final int screenHeight = 2800; final int screenWidth = 1400; final int taskbarHeight = 200; setUpDisplaySizeWithApp(screenWidth, screenHeight); mActivity.mDisplayContent.setIgnoreOrientationRequest(true); mActivity.mWmService.mLetterboxConfiguration.setLetterboxVerticalPositionMultiplier(1.0f); final InsetsSource navSource = new InsetsSource( InsetsSource.createId(null, 0, navigationBars()), navigationBars()); navSource.setInsetsRoundedCornerFrame(true); // Immersive activity has transient navbar navSource.setVisible(!immersive); navSource.setFrame(new Rect(0, screenHeight - taskbarHeight, screenWidth, screenHeight)); mActivity.mWmService.mLetterboxConfiguration.setLetterboxActivityCornersRadius(15); final WindowState w1 = addWindowToActivity(mActivity); w1.mAboveInsetsState.addSource(navSource); // Prepare unresizable landscape activity prepareUnresizable(mActivity, SCREEN_ORIENTATION_LANDSCAPE); final DisplayPolicy displayPolicy = mActivity.mDisplayContent.getDisplayPolicy(); doReturn(immersive).when(displayPolicy).isImmersiveMode(); mActivity.mRootWindowContainer.performSurfacePlacement(); LetterboxDetails letterboxDetails = mActivity.mLetterboxUiController.getLetterboxDetails(); // Letterboxed activity at bottom assertEquals(new Rect(0, 2100, 1400, 2800), mActivity.getBounds()); final int expectedHeight = immersive ? screenHeight : screenHeight - taskbarHeight; assertEquals(expectedHeight, letterboxDetails.getLetterboxInnerBounds().bottom); } @Test public void testSplitScreenLetterboxDetailsForStatusBar_twoLetterboxedApps() { mAtm.mDevEnableNonResizableMultiWindow = true; Loading Loading @@ -3938,7 +3983,7 @@ public class SizeCompatTests extends WindowTestsBase { mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */); mWm.mLetterboxConfiguration.setIsAutomaticReachabilityInBookModeEnabled(true); mWm.mLetterboxConfiguration.setLetterboxHorizontalPositionMultiplier( 1.0f /*letterboxVerticalPositionMultiplier*/); 1.0f /*letterboxHorizontalPositionMultiplier*/); prepareUnresizable(mActivity, SCREEN_ORIENTATION_PORTRAIT); Rect letterboxNoFold = new Rect(2100, 0, 2800, 1400); Loading