summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt23
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/ReturnToDragStartAnimator.kt20
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java4
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt41
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.kt49
5 files changed, 111 insertions, 26 deletions
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt
index 90f8276240a7..4b30ed0dfa7c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt
@@ -734,17 +734,33 @@ class DesktopTasksController(
* Quick-resize to the right or left half of the stable bounds.
*
* @param taskInfo current task that is being snap-resized via dragging or maximize menu button
+ * @param taskSurface the leash of the task being dragged
* @param currentDragBounds current position of the task leash being dragged (or current task
* bounds if being snapped resize via maximize menu button)
* @param position the portion of the screen (RIGHT or LEFT) we want to snap the task to.
*/
fun snapToHalfScreen(
taskInfo: RunningTaskInfo,
+ taskSurface: SurfaceControl,
currentDragBounds: Rect,
position: SnapPosition
) {
val destinationBounds = getSnapBounds(taskInfo, position)
- if (destinationBounds == taskInfo.configuration.windowConfiguration.bounds) return
+ if (destinationBounds == taskInfo.configuration.windowConfiguration.bounds) {
+ // Handle the case where we attempt to snap resize when already snap resized: the task
+ // position won't need to change but we want to animate the surface going back to the
+ // snapped position from the "dragged-to-the-edge" position.
+ if (destinationBounds != currentDragBounds) {
+ returnToDragStartAnimator.start(
+ taskInfo.taskId,
+ taskSurface,
+ startBounds = currentDragBounds,
+ endBounds = destinationBounds,
+ isResizable = taskInfo.isResizeable
+ )
+ }
+ return
+ }
taskbarDesktopTaskListener?.onTaskbarCornerRoundingUpdate(true)
val wct = WindowContainerTransaction().setBounds(taskInfo.token, destinationBounds)
@@ -774,13 +790,14 @@ class DesktopTasksController(
taskInfo.taskId,
taskSurface,
startBounds = currentDragBounds,
- endBounds = dragStartBounds
+ endBounds = dragStartBounds,
+ isResizable = taskInfo.isResizeable,
)
} else {
interactionJankMonitor.begin(
taskSurface, context, CUJ_DESKTOP_MODE_SNAP_RESIZE, "drag_resizable"
)
- snapToHalfScreen(taskInfo, currentDragBounds, position)
+ snapToHalfScreen(taskInfo, taskSurface, currentDragBounds, position)
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/ReturnToDragStartAnimator.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/ReturnToDragStartAnimator.kt
index 4c5258f2bfcd..f4df42cde10f 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/ReturnToDragStartAnimator.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/ReturnToDragStartAnimator.kt
@@ -48,7 +48,13 @@ class ReturnToDragStartAnimator(
}
/** Builds new animator and starts animation of task leash reposition. */
- fun start(taskId: Int, taskSurface: SurfaceControl, startBounds: Rect, endBounds: Rect) {
+ fun start(
+ taskId: Int,
+ taskSurface: SurfaceControl,
+ startBounds: Rect,
+ endBounds: Rect,
+ isResizable: Boolean
+ ) {
val tx = transactionSupplier.get()
boundsAnimator?.cancel()
@@ -81,11 +87,13 @@ class ReturnToDragStartAnimator(
.apply()
taskRepositionAnimationListener.onAnimationEnd(taskId)
boundsAnimator = null
- Toast.makeText(
- context,
- R.string.desktop_mode_non_resizable_snap_text,
- Toast.LENGTH_SHORT
- ).show()
+ if (!isResizable) {
+ Toast.makeText(
+ context,
+ R.string.desktop_mode_non_resizable_snap_text,
+ Toast.LENGTH_SHORT
+ ).show()
+ }
interactionJankMonitor.end(Cuj.CUJ_DESKTOP_MODE_SNAP_RESIZE)
}
)
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java
index ac35459347c6..c88c1e28b011 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java
@@ -491,7 +491,9 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
} else {
mInteractionJankMonitor.begin(decoration.mTaskSurface, mContext,
Cuj.CUJ_DESKTOP_MODE_SNAP_RESIZE, "maximize_menu_resizable");
- mDesktopTasksController.snapToHalfScreen(decoration.mTaskInfo,
+ mDesktopTasksController.snapToHalfScreen(
+ decoration.mTaskInfo,
+ decoration.mTaskSurface,
decoration.mTaskInfo.configuration.windowConfiguration.getBounds(),
left ? SnapPosition.LEFT : SnapPosition.RIGHT);
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt
index 5474e539f286..10557dd9b439 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt
@@ -123,12 +123,12 @@ import org.mockito.ArgumentMatchers.isA
import org.mockito.ArgumentMatchers.isNull
import org.mockito.Mock
import org.mockito.Mockito
-import org.mockito.Mockito.any
import org.mockito.Mockito.anyInt
import org.mockito.Mockito.clearInvocations
import org.mockito.Mockito.mock
import org.mockito.Mockito.spy
import org.mockito.Mockito.verify
+import org.mockito.kotlin.any
import org.mockito.kotlin.anyOrNull
import org.mockito.kotlin.atLeastOnce
import org.mockito.kotlin.eq
@@ -2859,7 +2859,7 @@ class DesktopTasksControllerTest : ShellTestCase() {
}
@Test
- fun getSnapBounds_calculatesBoundsForResizable() {
+ fun snapToHalfScreen_getSnapBounds_calculatesBoundsForResizable() {
val bounds = Rect(100, 100, 300, 300)
val task = setUpFreeformTask(DEFAULT_DISPLAY, bounds).apply {
topActivityInfo = ActivityInfo().apply {
@@ -2874,13 +2874,45 @@ class DesktopTasksControllerTest : ShellTestCase() {
STABLE_BOUNDS.left, STABLE_BOUNDS.top, STABLE_BOUNDS.right / 2, STABLE_BOUNDS.bottom
)
- controller.snapToHalfScreen(task, currentDragBounds, SnapPosition.LEFT)
+ controller.snapToHalfScreen(task, mockSurface, currentDragBounds, SnapPosition.LEFT)
// Assert bounds set to stable bounds
val wct = getLatestToggleResizeDesktopTaskWct(currentDragBounds)
assertThat(findBoundsChange(wct, task)).isEqualTo(expectedBounds)
}
@Test
+ fun snapToHalfScreen_snapBoundsWhenAlreadySnapped_animatesSurfaceWithoutWCT() {
+ assumeTrue(ENABLE_SHELL_TRANSITIONS)
+ // Set up task to already be in snapped-left bounds
+ val bounds = Rect(
+ STABLE_BOUNDS.left, STABLE_BOUNDS.top, STABLE_BOUNDS.right / 2, STABLE_BOUNDS.bottom
+ )
+ val task = setUpFreeformTask(DEFAULT_DISPLAY, bounds).apply {
+ topActivityInfo = ActivityInfo().apply {
+ screenOrientation = SCREEN_ORIENTATION_LANDSCAPE
+ configuration.windowConfiguration.appBounds = bounds
+ }
+ isResizeable = true
+ }
+
+ // Attempt to snap left again
+ val currentDragBounds = Rect(bounds).apply { offset(-100, 0) }
+ controller.snapToHalfScreen(task, mockSurface, currentDragBounds, SnapPosition.LEFT)
+
+ // Assert that task is NOT updated via WCT
+ verify(toggleResizeDesktopTaskTransitionHandler, never()).startTransition(any(), any())
+
+ // Assert that task leash is updated via Surface Animations
+ verify(mReturnToDragStartAnimator).start(
+ eq(task.taskId),
+ eq(mockSurface),
+ eq(currentDragBounds),
+ eq(bounds),
+ eq(true)
+ )
+ }
+
+ @Test
@DisableFlags(Flags.FLAG_DISABLE_NON_RESIZABLE_APP_SNAP_RESIZING)
fun handleSnapResizingTask_nonResizable_snapsToHalfScreen() {
val task = setUpFreeformTask(DEFAULT_DISPLAY, Rect(0, 0, 200, 100)).apply {
@@ -2911,7 +2943,8 @@ class DesktopTasksControllerTest : ShellTestCase() {
eq(task.taskId),
eq(mockSurface),
eq(currentDragBounds),
- eq(preDragBounds)
+ eq(preDragBounds),
+ eq(false)
)
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.kt
index 0b5c6784b73d..be0549b6655d 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.kt
@@ -113,7 +113,7 @@ import org.mockito.Mockito.anyInt
import org.mockito.Mockito.mock
import org.mockito.Mockito.never
import org.mockito.Mockito.times
-import org.mockito.Mockito.verify
+import org.mockito.kotlin.verify
import org.mockito.kotlin.any
import org.mockito.kotlin.anyOrNull
import org.mockito.kotlin.argThat
@@ -600,6 +600,7 @@ class DesktopModeWindowDecorViewModelTests : ShellTestCase() {
@Test
fun testOnDecorSnappedLeft_snapResizes() {
+ val taskSurfaceCaptor = argumentCaptor<SurfaceControl>()
val onLeftSnapClickListenerCaptor = forClass(Function0::class.java)
as ArgumentCaptor<Function0<Unit>>
val decor = createOpenTaskDecoration(
@@ -610,8 +611,13 @@ class DesktopModeWindowDecorViewModelTests : ShellTestCase() {
val currentBounds = decor.mTaskInfo.configuration.windowConfiguration.bounds
onLeftSnapClickListenerCaptor.value.invoke()
- verify(mockDesktopTasksController)
- .snapToHalfScreen(decor.mTaskInfo, currentBounds, SnapPosition.LEFT)
+ verify(mockDesktopTasksController).snapToHalfScreen(
+ eq(decor.mTaskInfo),
+ taskSurfaceCaptor.capture(),
+ eq(currentBounds),
+ eq(SnapPosition.LEFT)
+ )
+ assertEquals(taskSurfaceCaptor.firstValue, decor.mTaskSurface)
}
@Test
@@ -632,6 +638,7 @@ class DesktopModeWindowDecorViewModelTests : ShellTestCase() {
@Test
@DisableFlags(Flags.FLAG_DISABLE_NON_RESIZABLE_APP_SNAP_RESIZING)
fun testOnSnapResizeLeft_nonResizable_decorSnappedLeft() {
+ val taskSurfaceCaptor = argumentCaptor<SurfaceControl>()
val onLeftSnapClickListenerCaptor = forClass(Function0::class.java)
as ArgumentCaptor<Function0<Unit>>
val decor = createOpenTaskDecoration(
@@ -642,8 +649,13 @@ class DesktopModeWindowDecorViewModelTests : ShellTestCase() {
val currentBounds = decor.mTaskInfo.configuration.windowConfiguration.bounds
onLeftSnapClickListenerCaptor.value.invoke()
- verify(mockDesktopTasksController)
- .snapToHalfScreen(decor.mTaskInfo, currentBounds, SnapPosition.LEFT)
+ verify(mockDesktopTasksController).snapToHalfScreen(
+ eq(decor.mTaskInfo),
+ taskSurfaceCaptor.capture(),
+ eq(currentBounds),
+ eq(SnapPosition.LEFT)
+ )
+ assertEquals(decor.mTaskSurface, taskSurfaceCaptor.firstValue)
}
@Test
@@ -660,12 +672,13 @@ class DesktopModeWindowDecorViewModelTests : ShellTestCase() {
onLeftSnapClickListenerCaptor.value.invoke()
verify(mockDesktopTasksController, never())
- .snapToHalfScreen(decor.mTaskInfo, currentBounds, SnapPosition.LEFT)
+ .snapToHalfScreen(eq(decor.mTaskInfo), any(), eq(currentBounds), eq(SnapPosition.LEFT))
verify(mockToast).show()
}
@Test
fun testOnDecorSnappedRight_snapResizes() {
+ val taskSurfaceCaptor = argumentCaptor<SurfaceControl>()
val onRightSnapClickListenerCaptor = forClass(Function0::class.java)
as ArgumentCaptor<Function0<Unit>>
val decor = createOpenTaskDecoration(
@@ -676,8 +689,13 @@ class DesktopModeWindowDecorViewModelTests : ShellTestCase() {
val currentBounds = decor.mTaskInfo.configuration.windowConfiguration.bounds
onRightSnapClickListenerCaptor.value.invoke()
- verify(mockDesktopTasksController)
- .snapToHalfScreen(decor.mTaskInfo, currentBounds, SnapPosition.RIGHT)
+ verify(mockDesktopTasksController).snapToHalfScreen(
+ eq(decor.mTaskInfo),
+ taskSurfaceCaptor.capture(),
+ eq(currentBounds),
+ eq(SnapPosition.RIGHT)
+ )
+ assertEquals(decor.mTaskSurface, taskSurfaceCaptor.firstValue)
}
@Test
@@ -698,6 +716,7 @@ class DesktopModeWindowDecorViewModelTests : ShellTestCase() {
@Test
@DisableFlags(Flags.FLAG_DISABLE_NON_RESIZABLE_APP_SNAP_RESIZING)
fun testOnSnapResizeRight_nonResizable_decorSnappedRight() {
+ val taskSurfaceCaptor = argumentCaptor<SurfaceControl>()
val onRightSnapClickListenerCaptor = forClass(Function0::class.java)
as ArgumentCaptor<Function0<Unit>>
val decor = createOpenTaskDecoration(
@@ -708,8 +727,13 @@ class DesktopModeWindowDecorViewModelTests : ShellTestCase() {
val currentBounds = decor.mTaskInfo.configuration.windowConfiguration.bounds
onRightSnapClickListenerCaptor.value.invoke()
- verify(mockDesktopTasksController)
- .snapToHalfScreen(decor.mTaskInfo, currentBounds, SnapPosition.RIGHT)
+ verify(mockDesktopTasksController).snapToHalfScreen(
+ eq(decor.mTaskInfo),
+ taskSurfaceCaptor.capture(),
+ eq(currentBounds),
+ eq(SnapPosition.RIGHT)
+ )
+ assertEquals(decor.mTaskSurface, taskSurfaceCaptor.firstValue)
}
@Test
@@ -726,7 +750,7 @@ class DesktopModeWindowDecorViewModelTests : ShellTestCase() {
onRightSnapClickListenerCaptor.value.invoke()
verify(mockDesktopTasksController, never())
- .snapToHalfScreen(decor.mTaskInfo, currentBounds, SnapPosition.RIGHT)
+ .snapToHalfScreen(eq(decor.mTaskInfo), any(), eq(currentBounds), eq(SnapPosition.RIGHT))
verify(mockToast).show()
}
@@ -1033,6 +1057,7 @@ class DesktopModeWindowDecorViewModelTests : ShellTestCase() {
private fun createOpenTaskDecoration(
@WindowingMode windowingMode: Int,
+ taskSurface: SurfaceControl = SurfaceControl(),
onMaxOrRestoreListenerCaptor: ArgumentCaptor<Function0<Unit>> =
forClass(Function0::class.java) as ArgumentCaptor<Function0<Unit>>,
onLeftSnapClickListenerCaptor: ArgumentCaptor<Function0<Unit>> =
@@ -1051,7 +1076,7 @@ class DesktopModeWindowDecorViewModelTests : ShellTestCase() {
forClass(View.OnClickListener::class.java) as ArgumentCaptor<View.OnClickListener>
): DesktopModeWindowDecoration {
val decor = setUpMockDecorationForTask(createTask(windowingMode = windowingMode))
- onTaskOpening(decor.mTaskInfo)
+ onTaskOpening(decor.mTaskInfo, taskSurface)
verify(decor).setOnMaximizeOrRestoreClickListener(onMaxOrRestoreListenerCaptor.capture())
verify(decor).setOnLeftSnapClickListener(onLeftSnapClickListenerCaptor.capture())
verify(decor).setOnRightSnapClickListener(onRightSnapClickListenerCaptor.capture())