diff --git a/services/core/java/com/android/server/wm/LetterboxUiController.java b/services/core/java/com/android/server/wm/LetterboxUiController.java index ea82417a2389b..74a236bd862c7 100644 --- a/services/core/java/com/android/server/wm/LetterboxUiController.java +++ b/services/core/java/com/android/server/wm/LetterboxUiController.java @@ -501,12 +501,16 @@ final class LetterboxUiController { if (hasVisibleTaskbar(mainWindow)) { cropBounds = new Rect(mActivityRecord.getBounds()); + + // Rounded corners should be displayed above the taskbar. + // It is important to call adjustBoundsForTaskbarUnchecked before offsetTo + // because taskbar bounds are in screen coordinates + adjustBoundsForTaskbarUnchecked(mainWindow, cropBounds); + // Activity bounds are in screen coordinates while (0,0) for activity's surface // control is at the top left corner of an app window so offsetting bounds // accordingly. cropBounds.offsetTo(0, 0); - // Rounded corners should be displayed above the taskbar. - adjustBoundsForTaskbarUnchecked(mainWindow, cropBounds); } transaction 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 181e81d70dfa2..06eea298600c1 100644 --- a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java @@ -25,6 +25,7 @@ import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; import static android.content.res.Configuration.ORIENTATION_LANDSCAPE; import static android.content.res.Configuration.ORIENTATION_PORTRAIT; import static android.provider.DeviceConfig.NAMESPACE_CONSTRAIN_DISPLAY_APIS; +import static android.view.InsetsState.ITYPE_EXTRA_NAVIGATION_BAR; import static android.view.InsetsState.ITYPE_STATUS_BAR; import static android.view.Surface.ROTATION_0; import static android.view.Surface.ROTATION_180; @@ -69,6 +70,7 @@ import static org.mockito.ArgumentMatchers.same; import static org.mockito.Mockito.atLeastOnce; import static org.mockito.Mockito.clearInvocations; import static org.mockito.Mockito.doCallRealMethod; +import static org.mockito.Mockito.times; import android.annotation.Nullable; import android.app.ActivityManager; @@ -84,6 +86,7 @@ import android.os.UserHandle; import android.platform.test.annotations.Presubmit; import android.provider.DeviceConfig; import android.provider.DeviceConfig.Properties; +import android.view.InsetsSource; import android.view.InsetsVisibilities; import android.view.WindowManager; @@ -103,6 +106,9 @@ import org.junit.Rule; import org.junit.Test; import org.junit.rules.TestRule; import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; + +import java.util.List; /** * Tests for Size Compatibility mode. @@ -2368,6 +2374,48 @@ public class SizeCompatTests extends WindowTestsBase { any(InsetsVisibilities.class), isNull(), eq(expectedLetterboxDetails)); } + @Test + public void testLetterboxDetailsForTaskBar_letterboxNotOverlappingTaskBar() { + mAtm.mDevEnableNonResizableMultiWindow = true; + final int screenHeight = 2200; + final int screenWidth = 1400; + final int taskbarHeight = 200; + setUpDisplaySizeWithApp(screenWidth, screenHeight); + + final TestSplitOrganizer organizer = + new TestSplitOrganizer(mAtm, mActivity.getDisplayContent()); + + // Move first activity to split screen which takes half of the screen. + organizer.mPrimary.setBounds(0, screenHeight / 2, screenWidth, screenHeight); + organizer.putTaskToPrimary(mTask, true); + + final InsetsSource navSource = new InsetsSource(ITYPE_EXTRA_NAVIGATION_BAR); + 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 activity with max aspect ratio + prepareUnresizable(mActivity, /* maxAspect */ 1.1f, SCREEN_ORIENTATION_UNSPECIFIED); + + // Refresh the letterboxes + mActivity.mRootWindowContainer.performSurfacePlacement(); + + final ArgumentCaptor cropCapturer = ArgumentCaptor.forClass(Rect.class); + verify(mTransaction, times(2)).setWindowCrop( + eq(w1.getSurfaceControl()), + cropCapturer.capture() + ); + final List capturedCrops = cropCapturer.getAllValues(); + + final int expectedHeight = screenHeight / 2 - taskbarHeight; + assertEquals(2, capturedCrops.size()); + assertEquals(expectedHeight, capturedCrops.get(0).bottom); + assertEquals(expectedHeight, capturedCrops.get(1).bottom); + } + @Test public void testSplitScreenLetterboxDetailsForStatusBar_twoLetterboxedApps() { mAtm.mDevEnableNonResizableMultiWindow = true;