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

Commit 2098a5ff authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Restrict maximum window size to the stable bounds of the display when...

Merge "Restrict maximum window size to the stable bounds of the display when resizing a window in desktop windowing mode." into main
parents 672d707f 9214f324
Loading
Loading
Loading
Loading
+32 −4
Original line number Diff line number Diff line
@@ -28,6 +28,8 @@ import android.graphics.Rect;
import android.util.DisplayMetrics;
import android.view.SurfaceControl;

import androidx.annotation.NonNull;

import com.android.window.flags.Flags;
import com.android.wm.shell.R;
import com.android.wm.shell.common.DisplayController;
@@ -106,13 +108,15 @@ public class DragPositioningCallbackUtility {
            repositionTaskBounds.bottom = (candidateBottom < stableBounds.bottom)
                    ? candidateBottom : oldBottom;
        }
        // If width or height are negative or less than the minimum width or height, revert the
        // If width or height are negative or exceeding the width or height constraints, revert the
        // respective bounds to use previous bound dimensions.
        if (repositionTaskBounds.width() < getMinWidth(displayController, windowDecoration)) {
        if (isExceedingWidthConstraint(repositionTaskBounds, stableBounds, displayController,
                windowDecoration)) {
            repositionTaskBounds.right = oldRight;
            repositionTaskBounds.left = oldLeft;
        }
        if (repositionTaskBounds.height() < getMinHeight(displayController, windowDecoration)) {
        if (isExceedingHeightConstraint(repositionTaskBounds, stableBounds, displayController,
                windowDecoration)) {
            repositionTaskBounds.top = oldTop;
            repositionTaskBounds.bottom = oldBottom;
        }
@@ -174,6 +178,30 @@ public class DragPositioningCallbackUtility {
        return result;
    }

    private static boolean isExceedingWidthConstraint(@NonNull Rect repositionTaskBounds,
            Rect maxResizeBounds, DisplayController displayController,
            WindowDecoration windowDecoration) {
        // Check if width is less than the minimum width constraint.
        if (repositionTaskBounds.width() < getMinWidth(displayController, windowDecoration)) {
            return true;
        }
        // Check if width is more than the maximum resize bounds on desktop windowing mode.
        return isSizeConstraintForDesktopModeEnabled(windowDecoration.mDecorWindowContext)
                && repositionTaskBounds.width() > maxResizeBounds.width();
    }

    private static boolean isExceedingHeightConstraint(@NonNull Rect repositionTaskBounds,
            Rect maxResizeBounds, DisplayController displayController,
            WindowDecoration windowDecoration) {
        // Check if height is less than the minimum height constraint.
        if (repositionTaskBounds.height() < getMinHeight(displayController, windowDecoration)) {
            return true;
        }
        // Check if height is more than the maximum resize bounds on desktop windowing mode.
        return isSizeConstraintForDesktopModeEnabled(windowDecoration.mDecorWindowContext)
                && repositionTaskBounds.height() > maxResizeBounds.height();
    }

    private static float getMinWidth(DisplayController displayController,
            WindowDecoration windowDecoration) {
        return windowDecoration.mTaskInfo.minWidth < 0 ? getDefaultMinWidth(displayController,
+58 −0
Original line number Diff line number Diff line
@@ -21,7 +21,9 @@ import android.content.res.Resources
import android.graphics.PointF
import android.graphics.Rect
import android.os.IBinder
import android.platform.test.annotations.DisableFlags
import android.platform.test.annotations.EnableFlags
import android.platform.test.flag.junit.SetFlagsRule
import android.testing.AndroidTestingRunner
import android.view.Display
import android.window.WindowContainerToken
@@ -36,6 +38,7 @@ import com.android.wm.shell.windowdecor.DragPositioningCallback.CTRL_TYPE_TOP
import com.google.common.truth.Truth.assertThat
import junit.framework.Assert.assertTrue
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mock
@@ -53,21 +56,32 @@ import org.mockito.MockitoAnnotations
class DragPositioningCallbackUtilityTest {
    @Mock
    private lateinit var mockWindowDecoration: WindowDecoration<*>

    @Mock
    private lateinit var taskToken: WindowContainerToken

    @Mock
    private lateinit var taskBinder: IBinder

    @Mock
    private lateinit var mockDisplayController: DisplayController

    @Mock
    private lateinit var mockDisplayLayout: DisplayLayout

    @Mock
    private lateinit var mockDisplay: Display

    @Mock
    private lateinit var mockContext: Context

    @Mock
    private lateinit var mockResources: Resources

    @JvmField
    @Rule
    val setFlagsRule = SetFlagsRule()

    @Before
    fun setup() {
        MockitoAnnotations.initMocks(this)
@@ -323,6 +337,49 @@ class DragPositioningCallbackUtilityTest {
        assertThat(repositionTaskBounds.bottom).isEqualTo(STARTING_BOUNDS.bottom - 50)
    }

    @Test
    @DisableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_SIZE_CONSTRAINTS)
    fun testChangeBounds_windowSizeExceedsStableBounds_shouldBeAllowedToChangeBounds() {
        val startingPoint =
            PointF(OFF_CENTER_STARTING_BOUNDS.right.toFloat(),
                OFF_CENTER_STARTING_BOUNDS.bottom.toFloat())
        val repositionTaskBounds = Rect(OFF_CENTER_STARTING_BOUNDS)
        // Increase height and width by STABLE_BOUNDS. Subtract by 5px so that it doesn't reach
        // the disallowed drag area.
        val offset = 5
        val newX = STABLE_BOUNDS.right.toFloat() - offset
        val newY = STABLE_BOUNDS.bottom.toFloat() - offset
        val delta = DragPositioningCallbackUtility.calculateDelta(newX, newY, startingPoint)

        DragPositioningCallbackUtility.changeBounds(CTRL_TYPE_RIGHT or CTRL_TYPE_BOTTOM,
            repositionTaskBounds, OFF_CENTER_STARTING_BOUNDS, STABLE_BOUNDS, delta,
            mockDisplayController, mockWindowDecoration)
        assertThat(repositionTaskBounds.width()).isGreaterThan(STABLE_BOUNDS.right)
        assertThat(repositionTaskBounds.height()).isGreaterThan(STABLE_BOUNDS.bottom)
    }

    @Test
    @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_SIZE_CONSTRAINTS)
    fun testChangeBoundsInDesktopMode_windowSizeExceedsStableBounds_shouldBeLimitedToDisplaySize() {
        whenever(DesktopModeStatus.canEnterDesktopMode(mockContext)).thenReturn(true)
        val startingPoint =
            PointF(OFF_CENTER_STARTING_BOUNDS.right.toFloat(),
                OFF_CENTER_STARTING_BOUNDS.bottom.toFloat())
        val repositionTaskBounds = Rect(OFF_CENTER_STARTING_BOUNDS)
        // Increase height and width by STABLE_BOUNDS. Subtract by 5px so that it doesn't reach
        // the disallowed drag area.
        val offset = 5
        val newX = STABLE_BOUNDS.right.toFloat() - offset
        val newY = STABLE_BOUNDS.bottom.toFloat() - offset
        val delta = DragPositioningCallbackUtility.calculateDelta(newX, newY, startingPoint)

        DragPositioningCallbackUtility.changeBounds(CTRL_TYPE_RIGHT or CTRL_TYPE_BOTTOM,
            repositionTaskBounds, OFF_CENTER_STARTING_BOUNDS, STABLE_BOUNDS, delta,
            mockDisplayController, mockWindowDecoration)
        assertThat(repositionTaskBounds.width()).isLessThan(STABLE_BOUNDS.right)
        assertThat(repositionTaskBounds.height()).isLessThan(STABLE_BOUNDS.bottom)
    }

    private fun initializeTaskInfo(taskMinWidth: Int = MIN_WIDTH, taskMinHeight: Int = MIN_HEIGHT) {
        mockWindowDecoration.mTaskInfo = ActivityManager.RunningTaskInfo().apply {
            taskId = TASK_ID
@@ -347,6 +404,7 @@ class DragPositioningCallbackUtilityTest {
        private const val NAVBAR_HEIGHT = 50
        private val DISPLAY_BOUNDS = Rect(0, 0, 2400, 1600)
        private val STARTING_BOUNDS = Rect(0, 0, 100, 100)
        private val OFF_CENTER_STARTING_BOUNDS = Rect(-100, -100, 10, 10)
        private val DISALLOWED_RESIZE_AREA = Rect(
            DISPLAY_BOUNDS.left,
            DISPLAY_BOUNDS.bottom - NAVBAR_HEIGHT,
+9 −0
Original line number Diff line number Diff line
@@ -17,6 +17,8 @@ package com.android.wm.shell.windowdecor

import android.app.ActivityManager
import android.app.WindowConfiguration
import android.content.Context
import android.content.res.Resources
import android.graphics.Point
import android.graphics.Rect
import android.os.IBinder
@@ -98,6 +100,10 @@ class VeiledResizeTaskPositionerTest : ShellTestCase() {
    private lateinit var mockFinishCallback: TransitionFinishCallback
    @Mock
    private lateinit var mockTransitions: Transitions
    @Mock
    private lateinit var mockContext: Context
    @Mock
    private lateinit var mockResources: Resources

    private lateinit var taskPositioner: VeiledResizeTaskPositioner

@@ -105,6 +111,9 @@ class VeiledResizeTaskPositionerTest : ShellTestCase() {
    fun setUp() {
        MockitoAnnotations.initMocks(this)

        mockDesktopWindowDecoration.mDisplay = mockDisplay
        mockDesktopWindowDecoration.mDecorWindowContext = mockContext
        whenever(mockContext.getResources()).thenReturn(mockResources)
        whenever(taskToken.asBinder()).thenReturn(taskBinder)
        whenever(mockDisplayController.getDisplayLayout(DISPLAY_ID)).thenReturn(mockDisplayLayout)
        whenever(mockDisplayLayout.densityDpi()).thenReturn(DENSITY_DPI)