Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cd47f740 authored by Eghosa Ewansiha-Vlachavas's avatar Eghosa Ewansiha-Vlachavas
Browse files

[2/n] Introduce dynamic bounds calculation to prevent letterboxing

When entering desktop windowing, applications should no longer be
letterboxed. This means scaling down apps in SCM for all unresizable
apps so intial bounds match scale of the fullscreen bounds. This removes
letterboxing while ensuring the apps layout is not disrupted.

For portrait resizable apps when the device is in landscape, the height
of the initial bounds will match the desired app height for desktopmode
while the width will remain from the apps fullscreen width.

For landscape resizable apps when the device is portrait, the fullscreen
height of the app will be preserved while the width will be set to a
custom value.

Flag: com.android.window.flags.enable_windowing_dynamic_initial_bounds
Bug: 319820230
Bug: 324378380
Fixes: 335401172
Fixes: 346821376
Test: atest WmTests:DesktopModeLaunchParamsModifierTests
Test: atest WmTests:DesktopModeUtilsTests
Test: atest WmTests:DisplayContentTests
Test: atest WMShellUnitTests:DesktopTasksControllerTest

Change-Id: Ie111c025256de9afdd9d2568a28a5078413fcbfe
parent b564eb41
Loading
Loading
Loading
Loading
+4 −4
Original line number Diff line number Diff line
@@ -66,7 +66,7 @@ fun calculateInitialBounds(
                        idealSize
                    }
                } else {
                    maximumSizeMaintainingAspectRatio(taskInfo, idealSize, appAspectRatio)
                    maximizeSizeGivenAspectRatio(taskInfo, idealSize, appAspectRatio)
                }
            }
            ORIENTATION_PORTRAIT -> {
@@ -85,13 +85,13 @@ fun calculateInitialBounds(
                } else {
                    if (isFixedOrientationLandscape(topActivityInfo.screenOrientation)) {
                        // Apply custom app width and calculate maximum size
                        maximumSizeMaintainingAspectRatio(
                        maximizeSizeGivenAspectRatio(
                            taskInfo,
                            Size(customPortraitWidthForLandscapeApp, idealSize.height),
                            appAspectRatio
                        )
                    } else {
                        maximumSizeMaintainingAspectRatio(taskInfo, idealSize, appAspectRatio)
                        maximizeSizeGivenAspectRatio(taskInfo, idealSize, appAspectRatio)
                    }
                }
            }
@@ -107,7 +107,7 @@ fun calculateInitialBounds(
 * Calculates the largest size that can fit in a given area while maintaining a specific aspect
 * ratio.
 */
fun maximumSizeMaintainingAspectRatio(
fun maximizeSizeGivenAspectRatio(
    taskInfo: RunningTaskInfo,
    targetArea: Size,
    aspectRatio: Float
+1 −5
Original line number Diff line number Diff line
@@ -671,7 +671,7 @@ class DesktopTasksController(
            } else {
                // if non-resizable then calculate max bounds according to aspect ratio
                val activityAspectRatio = calculateAspectRatio(taskInfo)
                val newSize = maximumSizeMaintainingAspectRatio(taskInfo,
                val newSize = maximizeSizeGivenAspectRatio(taskInfo,
                    Size(stableBounds.width(), stableBounds.height()), activityAspectRatio)
                val newBounds = centerInArea(
                    newSize, stableBounds, stableBounds.left, stableBounds.top)
@@ -1074,7 +1074,6 @@ class DesktopTasksController(
        wct: WindowContainerTransaction,
        taskInfo: RunningTaskInfo
    ) {
        val displayLayout = displayController.getDisplayLayout(taskInfo.displayId) ?: return
        val tdaInfo = rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(taskInfo.displayId)!!
        val tdaWindowingMode = tdaInfo.configuration.windowConfiguration.windowingMode
        val targetWindowingMode =
@@ -1084,9 +1083,6 @@ class DesktopTasksController(
            } else {
                WINDOWING_MODE_FREEFORM
            }
        if (Flags.enableWindowingDynamicInitialBounds()) {
            wct.setBounds(taskInfo.token, calculateInitialBounds(displayLayout, taskInfo))
        }
        wct.setWindowingMode(taskInfo.token, targetWindowingMode)
        wct.reorder(taskInfo.token, true /* onTop */)
        if (useDesktopOverrideDensity()) {
+0 −132
Original line number Diff line number Diff line
@@ -579,138 +579,6 @@ class DesktopTasksControllerTest : ShellTestCase() {
    assertThat(controller.visibleTaskCount(SECOND_DISPLAY)).isEqualTo(1)
  }

  @Test
  @EnableFlags(Flags.FLAG_ENABLE_WINDOWING_DYNAMIC_INITIAL_BOUNDS)
  fun moveToDesktop_landscapeDevice_resizable_undefinedOrientation_defaultLandscapeBounds() {
    val task = setUpFullscreenTask()
    setUpLandscapeDisplay()

    controller.moveToDesktop(task, transitionSource = UNKNOWN)
    val wct = getLatestEnterDesktopWct()
    assertThat(findBoundsChange(wct, task)).isEqualTo(DEFAULT_LANDSCAPE_BOUNDS)
  }

  @Test
  @EnableFlags(Flags.FLAG_ENABLE_WINDOWING_DYNAMIC_INITIAL_BOUNDS)
  fun moveToDesktop_landscapeDevice_resizable_landscapeOrientation_defaultLandscapeBounds() {
    val task = setUpFullscreenTask(screenOrientation = SCREEN_ORIENTATION_LANDSCAPE)
    setUpLandscapeDisplay()

    controller.moveToDesktop(task, transitionSource = UNKNOWN)
    val wct = getLatestEnterDesktopWct()
    assertThat(findBoundsChange(wct, task)).isEqualTo(DEFAULT_LANDSCAPE_BOUNDS)
  }

  @Test
  @EnableFlags(Flags.FLAG_ENABLE_WINDOWING_DYNAMIC_INITIAL_BOUNDS)
  fun moveToDesktop_landscapeDevice_resizable_portraitOrientation_resizablePortraitBounds() {
    val task =
        setUpFullscreenTask(screenOrientation = SCREEN_ORIENTATION_PORTRAIT, shouldLetterbox = true)
    setUpLandscapeDisplay()

    controller.moveToDesktop(task, transitionSource = UNKNOWN)
    val wct = getLatestEnterDesktopWct()
    assertThat(findBoundsChange(wct, task)).isEqualTo(RESIZABLE_PORTRAIT_BOUNDS)
  }

  @Test
  @EnableFlags(Flags.FLAG_ENABLE_WINDOWING_DYNAMIC_INITIAL_BOUNDS)
  fun moveToDesktop_landscapeDevice_unResizable_landscapeOrientation_defaultLandscapeBounds() {
    val task =
        setUpFullscreenTask(isResizable = false, screenOrientation = SCREEN_ORIENTATION_LANDSCAPE)
    setUpLandscapeDisplay()

    controller.moveToDesktop(task, transitionSource = UNKNOWN)
    val wct = getLatestEnterDesktopWct()
    assertThat(findBoundsChange(wct, task)).isEqualTo(DEFAULT_LANDSCAPE_BOUNDS)
  }

  @Test
  @EnableFlags(Flags.FLAG_ENABLE_WINDOWING_DYNAMIC_INITIAL_BOUNDS)
  fun moveToDesktop_landscapeDevice_unResizable_portraitOrientation_unResizablePortraitBounds() {
    val task =
        setUpFullscreenTask(
            isResizable = false,
            screenOrientation = SCREEN_ORIENTATION_PORTRAIT,
            shouldLetterbox = true)
    setUpLandscapeDisplay()

    controller.moveToDesktop(task, transitionSource = UNKNOWN)
    val wct = getLatestEnterDesktopWct()
    assertThat(findBoundsChange(wct, task)).isEqualTo(UNRESIZABLE_PORTRAIT_BOUNDS)
  }

  @Test
  @EnableFlags(Flags.FLAG_ENABLE_WINDOWING_DYNAMIC_INITIAL_BOUNDS)
  fun moveToDesktop_portraitDevice_resizable_undefinedOrientation_defaultPortraitBounds() {
    val task = setUpFullscreenTask(deviceOrientation = ORIENTATION_PORTRAIT)
    setUpPortraitDisplay()

    controller.moveToDesktop(task, transitionSource = UNKNOWN)
    val wct = getLatestEnterDesktopWct()
    assertThat(findBoundsChange(wct, task)).isEqualTo(DEFAULT_PORTRAIT_BOUNDS)
  }

  @Test
  @EnableFlags(Flags.FLAG_ENABLE_WINDOWING_DYNAMIC_INITIAL_BOUNDS)
  fun moveToDesktop_portraitDevice_resizable_portraitOrientation_defaultPortraitBounds() {
    val task =
        setUpFullscreenTask(
            deviceOrientation = ORIENTATION_PORTRAIT,
            screenOrientation = SCREEN_ORIENTATION_PORTRAIT)
    setUpPortraitDisplay()

    controller.moveToDesktop(task, transitionSource = UNKNOWN)
    val wct = getLatestEnterDesktopWct()
    assertThat(findBoundsChange(wct, task)).isEqualTo(DEFAULT_PORTRAIT_BOUNDS)
  }

  @Test
  @EnableFlags(Flags.FLAG_ENABLE_WINDOWING_DYNAMIC_INITIAL_BOUNDS)
  fun moveToDesktop_portraitDevice_resizable_landscapeOrientation_resizableLandscapeBounds() {
    val task =
        setUpFullscreenTask(
            deviceOrientation = ORIENTATION_PORTRAIT,
            screenOrientation = SCREEN_ORIENTATION_LANDSCAPE,
            shouldLetterbox = true)
    setUpPortraitDisplay()

    controller.moveToDesktop(task, transitionSource = UNKNOWN)
    val wct = getLatestEnterDesktopWct()
    assertThat(findBoundsChange(wct, task)).isEqualTo(RESIZABLE_LANDSCAPE_BOUNDS)
  }

  @Test
  @EnableFlags(Flags.FLAG_ENABLE_WINDOWING_DYNAMIC_INITIAL_BOUNDS)
  fun moveToDesktop_portraitDevice_unResizable_portraitOrientation_defaultPortraitBounds() {
    val task =
        setUpFullscreenTask(
            isResizable = false,
            deviceOrientation = ORIENTATION_PORTRAIT,
            screenOrientation = SCREEN_ORIENTATION_PORTRAIT)
    setUpPortraitDisplay()

    controller.moveToDesktop(task, transitionSource = UNKNOWN)
    val wct = getLatestEnterDesktopWct()
    assertThat(findBoundsChange(wct, task)).isEqualTo(DEFAULT_PORTRAIT_BOUNDS)
  }

  @Test
  @EnableFlags(Flags.FLAG_ENABLE_WINDOWING_DYNAMIC_INITIAL_BOUNDS)
  fun moveToDesktop_portraitDevice_unResizable_landscapeOrientation_unResizableLandscapeBounds() {
    val task =
        setUpFullscreenTask(
            isResizable = false,
            deviceOrientation = ORIENTATION_PORTRAIT,
            screenOrientation = SCREEN_ORIENTATION_LANDSCAPE,
            shouldLetterbox = true)
    setUpPortraitDisplay()

    controller.moveToDesktop(task, transitionSource = UNKNOWN)
    val wct = getLatestEnterDesktopWct()
    assertThat(findBoundsChange(wct, task)).isEqualTo(UNRESIZABLE_LANDSCAPE_BOUNDS)
  }

  @Test
  fun moveToDesktop_tdaFullscreen_windowingModeSetToFreeform() {
    val task = setUpFullscreenTask()
+9 −1
Original line number Diff line number Diff line
@@ -226,6 +226,14 @@ class AppCompatAspectRatioOverrides {
                        : getDefaultMinAspectRatio();
    }

    float getDefaultMinAspectRatioForUnresizableAppsFromConfig() {
        return mAppCompatConfiguration.getDefaultMinAspectRatioForUnresizableApps();
    }

    boolean isSplitScreenAspectRatioForUnresizableAppsEnabled() {
        return mAppCompatConfiguration.getIsSplitScreenAspectRatioForUnresizableAppsEnabled();
    }

    private float getDisplaySizeMinAspectRatio() {
        final DisplayArea displayArea = mActivityRecord.getDisplayArea();
        if (displayArea == null) {
@@ -278,7 +286,7 @@ class AppCompatAspectRatioOverrides {
        return getSplitScreenAspectRatio();
    }

    private float getDefaultMinAspectRatio() {
    float getDefaultMinAspectRatio() {
        if (mActivityRecord.getDisplayArea() == null
                || !mAppCompatConfiguration
                .getIsDisplayAspectRatioEnabledForFixedOrientationLetterbox()) {
+279 −21

File changed.

Preview size limit exceeded, changes collapsed.

Loading