summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Eghosa Ewansiha-Vlachavas <eevlachavas@google.com> 2024-09-13 14:10:51 +0000
committer Eghosa Ewansiha-Vlachavas <eevlachavas@google.com> 2024-09-13 17:06:32 +0000
commitb8cc0a3c11727d002488a9c15a9b4dfd2f4316bc (patch)
tree8ab272e9f77a35f4ac4b131fdbeebe2a3bc5b161
parentbad2c984ada4b86bdf9d8ba738f79f6abf0ec811 (diff)
Maintain aspect ratio in DragPositioningCallbackUtility.changeBounds()
Adjusting one side of an unresizeable app without also adjusted a adjacent edge in proportion will cause the aspect ratio of the bounds to change. To prevent the aspect ratio of unresizeable apps being modified, opt to reset all coordinates to their previous valid state if at least one of the coordinates needs adjusting due to constraints. Flag: com.android.window.flags.enable_windowing_scaled_resizing Fix: 366424454 Test: atest WMShellUnitTests:DragPositioningCallbackUtilityTest Test: atest WMShellUnitTests:VeiledResizeTaskPositionerTest Test: atest WMShellUnitTests:FluidResizeTaskPositionerTest Change-Id: I4959f3a9a725e619bb620f00cc383e939a173e79
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragPositioningCallbackUtility.java38
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DragPositioningCallbackUtilityTest.kt84
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/FluidResizeTaskPositionerTest.kt1
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/VeiledResizeTaskPositionerTest.kt1
4 files changed, 124 insertions, 0 deletions
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragPositioningCallbackUtility.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragPositioningCallbackUtility.java
index cb9781e86c87..cad34621c82a 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragPositioningCallbackUtility.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragPositioningCallbackUtility.java
@@ -84,22 +84,47 @@ public class DragPositioningCallbackUtility {
repositionTaskBounds.set(taskBoundsAtDragStart);
+ boolean isAspectRatioMaintained = true;
// Make sure the new resizing destination in any direction falls within the stable bounds.
if ((ctrlType & CTRL_TYPE_LEFT) != 0) {
repositionTaskBounds.left = Math.max(repositionTaskBounds.left + (int) delta.x,
stableBounds.left);
+ if (repositionTaskBounds.left == stableBounds.left
+ && repositionTaskBounds.left + (int) delta.x != stableBounds.left) {
+ // If the task edge have been set to the stable bounds and not due to the users
+ // drag, the aspect ratio of the task will not be maintained.
+ isAspectRatioMaintained = false;
+ }
}
if ((ctrlType & CTRL_TYPE_RIGHT) != 0) {
repositionTaskBounds.right = Math.min(repositionTaskBounds.right + (int) delta.x,
stableBounds.right);
+ if (repositionTaskBounds.right == stableBounds.right
+ && repositionTaskBounds.right + (int) delta.x != stableBounds.right) {
+ // If the task edge have been set to the stable bounds and not due to the users
+ // drag, the aspect ratio of the task will not be maintained.
+ isAspectRatioMaintained = false;
+ }
}
if ((ctrlType & CTRL_TYPE_TOP) != 0) {
repositionTaskBounds.top = Math.max(repositionTaskBounds.top + (int) delta.y,
stableBounds.top);
+ if (repositionTaskBounds.top == stableBounds.top
+ && repositionTaskBounds.top + (int) delta.y != stableBounds.top) {
+ // If the task edge have been set to the stable bounds and not due to the users
+ // drag, the aspect ratio of the task will not be maintained.
+ isAspectRatioMaintained = false;
+ }
}
if ((ctrlType & CTRL_TYPE_BOTTOM) != 0) {
repositionTaskBounds.bottom = Math.min(repositionTaskBounds.bottom + (int) delta.y,
stableBounds.bottom);
+ if (repositionTaskBounds.bottom == stableBounds.bottom
+ && repositionTaskBounds.bottom + (int) delta.y != stableBounds.bottom) {
+ // If the task edge have been set to the stable bounds and not due to the users
+ // drag, the aspect ratio of the task will not be maintained.
+ isAspectRatioMaintained = false;
+ }
}
// If width or height are negative or exceeding the width or height constraints, revert the
@@ -108,11 +133,24 @@ public class DragPositioningCallbackUtility {
windowDecoration)) {
repositionTaskBounds.right = oldRight;
repositionTaskBounds.left = oldLeft;
+ isAspectRatioMaintained = false;
}
if (isExceedingHeightConstraint(repositionTaskBounds, stableBounds, displayController,
windowDecoration)) {
repositionTaskBounds.top = oldTop;
repositionTaskBounds.bottom = oldBottom;
+ isAspectRatioMaintained = false;
+ }
+
+ // If the application is unresizeable and any bounds have been set back to their old
+ // location or to a stable bound edge, reset all the bounds to maintain the applications
+ // aspect ratio.
+ if (DesktopModeFlags.SCALED_RESIZING.isEnabled(windowDecoration.mDecorWindowContext)
+ && !isAspectRatioMaintained && !windowDecoration.mTaskInfo.isResizeable) {
+ repositionTaskBounds.top = oldTop;
+ repositionTaskBounds.bottom = oldBottom;
+ repositionTaskBounds.right = oldRight;
+ repositionTaskBounds.left = oldLeft;
}
// If there are no changes to the bounds after checking new bounds against minimum and
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DragPositioningCallbackUtilityTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DragPositioningCallbackUtilityTest.kt
index 1f33ae69b724..24f6becc3536 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DragPositioningCallbackUtilityTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DragPositioningCallbackUtilityTest.kt
@@ -39,6 +39,7 @@ import com.android.wm.shell.windowdecor.DragPositioningCallback.CTRL_TYPE_BOTTOM
import com.android.wm.shell.windowdecor.DragPositioningCallback.CTRL_TYPE_RIGHT
import com.android.wm.shell.windowdecor.DragPositioningCallback.CTRL_TYPE_TOP
import com.google.common.truth.Truth.assertThat
+import junit.framework.Assert.assertFalse
import junit.framework.Assert.assertTrue
import org.junit.After
import org.junit.Before
@@ -105,6 +106,7 @@ class DragPositioningCallbackUtilityTest {
initializeTaskInfo()
mockWindowDecoration.mDisplay = mockDisplay
mockWindowDecoration.mDecorWindowContext = mockContext
+ mockWindowDecoration.mTaskInfo.isResizeable = true
whenever(mockContext.getResources()).thenReturn(mockResources)
whenever(mockWindowDecoration.mDecorWindowContext.resources).thenReturn(mockResources)
whenever(mockResources.getDimensionPixelSize(R.dimen.desktop_mode_minimum_window_width))
@@ -164,6 +166,60 @@ class DragPositioningCallbackUtilityTest {
}
@Test
+ @EnableFlags(Flags.FLAG_ENABLE_WINDOWING_SCALED_RESIZING)
+ fun testChangeBounds_unresizeableApp_heightLessThanMin_resetToStartingBounds() {
+ mockWindowDecoration.mTaskInfo.isResizeable = false
+ val startingPoint = PointF(STARTING_BOUNDS.right.toFloat(), STARTING_BOUNDS.top.toFloat())
+ val repositionTaskBounds = Rect(STARTING_BOUNDS)
+
+ // Resize to width of 95px and height of 5px with min width of 10px
+ val newX = STARTING_BOUNDS.right.toFloat() - 5
+ val newY = STARTING_BOUNDS.top.toFloat() + 95
+ val delta = DragPositioningCallbackUtility.calculateDelta(newX, newY, startingPoint)
+
+ assertFalse(
+ DragPositioningCallbackUtility.changeBounds(
+ CTRL_TYPE_RIGHT or CTRL_TYPE_TOP,
+ repositionTaskBounds, STARTING_BOUNDS, STABLE_BOUNDS, delta, mockDisplayController,
+ mockWindowDecoration
+ )
+ )
+
+ assertThat(repositionTaskBounds.left).isEqualTo(STARTING_BOUNDS.left)
+ assertThat(repositionTaskBounds.top).isEqualTo(STARTING_BOUNDS.top)
+ assertThat(repositionTaskBounds.right).isEqualTo(STARTING_BOUNDS.right)
+ assertThat(repositionTaskBounds.bottom).isEqualTo(STARTING_BOUNDS.bottom)
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_ENABLE_WINDOWING_SCALED_RESIZING)
+ fun testChangeBounds_unresizeableApp_widthLessThanMin_resetToStartingBounds() {
+ mockWindowDecoration.mTaskInfo.isResizeable = false
+ val startingPoint = PointF(STARTING_BOUNDS.right.toFloat(), STARTING_BOUNDS.top.toFloat())
+ val repositionTaskBounds = Rect(STARTING_BOUNDS)
+
+ // Resize to height of 95px and width of 5px with min width of 10px
+ val newX = STARTING_BOUNDS.right.toFloat() - 95
+ val newY = STARTING_BOUNDS.top.toFloat() + 5
+ val delta = DragPositioningCallbackUtility.calculateDelta(newX, newY, startingPoint)
+
+ assertFalse(
+ DragPositioningCallbackUtility.changeBounds(
+ CTRL_TYPE_RIGHT or CTRL_TYPE_TOP,
+ repositionTaskBounds, STARTING_BOUNDS, STABLE_BOUNDS, delta, mockDisplayController,
+ mockWindowDecoration
+ )
+ )
+
+
+ assertThat(repositionTaskBounds.left).isEqualTo(STARTING_BOUNDS.left)
+ assertThat(repositionTaskBounds.top).isEqualTo(STARTING_BOUNDS.top)
+ assertThat(repositionTaskBounds.right).isEqualTo(STARTING_BOUNDS.right)
+ assertThat(repositionTaskBounds.bottom).isEqualTo(STARTING_BOUNDS.bottom)
+ }
+
+
+ @Test
fun testChangeBoundsDoesNotChangeHeightWhenNegative() {
val startingPoint = PointF(STARTING_BOUNDS.right.toFloat(), STARTING_BOUNDS.top.toFloat())
val repositionTaskBounds = Rect(STARTING_BOUNDS)
@@ -317,6 +373,34 @@ class DragPositioningCallbackUtilityTest {
}
@Test
+ @EnableFlags(Flags.FLAG_ENABLE_WINDOWING_SCALED_RESIZING)
+ fun testChangeBounds_unresizeableApp_beyondStableBounds_resetToStartingBounds() {
+ mockWindowDecoration.mTaskInfo.isResizeable = false
+ val startingPoint = PointF(
+ STARTING_BOUNDS.right.toFloat(),
+ STARTING_BOUNDS.bottom.toFloat()
+ )
+ val repositionTaskBounds = Rect(STARTING_BOUNDS)
+
+ // Resize to beyond stable bounds.
+ val newX = STARTING_BOUNDS.right.toFloat() + STABLE_BOUNDS.width()
+ val newY = STARTING_BOUNDS.bottom.toFloat() + STABLE_BOUNDS.height()
+
+ val delta = DragPositioningCallbackUtility.calculateDelta(newX, newY, startingPoint)
+ assertFalse(
+ DragPositioningCallbackUtility.changeBounds(
+ CTRL_TYPE_RIGHT or CTRL_TYPE_BOTTOM,
+ repositionTaskBounds, STARTING_BOUNDS, STABLE_BOUNDS, delta, mockDisplayController,
+ mockWindowDecoration
+ )
+ )
+ assertThat(repositionTaskBounds.left).isEqualTo(STARTING_BOUNDS.left)
+ assertThat(repositionTaskBounds.top).isEqualTo(STARTING_BOUNDS.top)
+ assertThat(repositionTaskBounds.right).isEqualTo(STARTING_BOUNDS.right)
+ assertThat(repositionTaskBounds.bottom).isEqualTo(STARTING_BOUNDS.bottom)
+ }
+
+ @Test
@EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_SIZE_CONSTRAINTS)
fun taskMinWidthHeightUndefined_changeBoundsInDesktopModeLessThanMin_shouldNotChangeBounds() {
doReturn(true).`when` { DesktopModeStatus.canEnterDesktopMode(mockContext) }
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/FluidResizeTaskPositionerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/FluidResizeTaskPositionerTest.kt
index 3a3e965b625e..7543fed4b085 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/FluidResizeTaskPositionerTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/FluidResizeTaskPositionerTest.kt
@@ -121,6 +121,7 @@ class FluidResizeTaskPositionerTest : ShellTestCase() {
displayId = DISPLAY_ID
configuration.windowConfiguration.setBounds(STARTING_BOUNDS)
configuration.windowConfiguration.displayRotation = ROTATION_90
+ isResizeable = true
}
`when`(mockWindowDecoration.calculateValidDragArea()).thenReturn(VALID_DRAG_AREA)
mockWindowDecoration.mDisplay = mockDisplay
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/VeiledResizeTaskPositionerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/VeiledResizeTaskPositionerTest.kt
index 6ae16edaf3df..7784af6b1111 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/VeiledResizeTaskPositionerTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/VeiledResizeTaskPositionerTest.kt
@@ -141,6 +141,7 @@ class VeiledResizeTaskPositionerTest : ShellTestCase() {
displayId = DISPLAY_ID
configuration.windowConfiguration.setBounds(STARTING_BOUNDS)
configuration.windowConfiguration.displayRotation = ROTATION_90
+ isResizeable = true
}
`when`(mockDesktopWindowDecoration.calculateValidDragArea()).thenReturn(VALID_DRAG_AREA)
mockDesktopWindowDecoration.mDisplay = mockDisplay