Merge "Release visual indicator on snap to stable bounds" into main
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java
index f3f91e6e..615dad3 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java
@@ -842,8 +842,8 @@
     @WMSingleton
     @Provides
     static ReturnToDragStartAnimator provideReturnToDragStartAnimator(
-            Context context, InteractionJankMonitor interactionJankMonitor) {
-        return new ReturnToDragStartAnimator(context, interactionJankMonitor);
+            InteractionJankMonitor interactionJankMonitor) {
+        return new ReturnToDragStartAnimator(interactionJankMonitor);
     }
 
     @WMSingleton
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 577c18c..133f069 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
@@ -54,6 +54,7 @@
 import android.view.WindowManager.TRANSIT_NONE
 import android.view.WindowManager.TRANSIT_OPEN
 import android.view.WindowManager.TRANSIT_TO_FRONT
+import android.widget.Toast
 import android.window.DesktopModeFlags
 import android.window.DesktopModeFlags.DISABLE_NON_RESIZABLE_APP_SNAP_RESIZE
 import android.window.DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY
@@ -877,7 +878,6 @@
                     taskSurface,
                     startBounds = currentDragBounds,
                     endBounds = containerBounds,
-                    isResizable = taskInfo.isResizeable
                 )
             }
             return
@@ -1012,7 +1012,6 @@
                     taskSurface,
                     startBounds = currentDragBounds,
                     endBounds = destinationBounds,
-                    isResizable = taskInfo.isResizeable,
                 )
             }
             return
@@ -1046,7 +1045,13 @@
                 taskSurface,
                 startBounds = currentDragBounds,
                 endBounds = dragStartBounds,
-                isResizable = taskInfo.isResizeable,
+                doOnEnd = {
+                    Toast.makeText(
+                        context,
+                        com.android.wm.shell.R.string.desktop_mode_non_resizable_snap_text,
+                        Toast.LENGTH_SHORT
+                    ).show()
+                },
             )
         } else {
             val resizeTrigger = if (position == SnapPosition.LEFT) {
@@ -1984,17 +1989,32 @@
                 )
             }
             IndicatorType.NO_INDICATOR -> {
+                // Create a copy so that we can animate from the current bounds if we end up having
+                // to snap the surface back without a WCT change.
+                val destinationBounds = Rect(currentDragBounds)
                 // If task bounds are outside valid drag area, snap them inward
                 DragPositioningCallbackUtility.snapTaskBoundsIfNecessary(
-                    currentDragBounds,
+                    destinationBounds,
                     validDragArea
                 )
 
-                if (currentDragBounds == dragStartBounds) return
+                if (destinationBounds == dragStartBounds) {
+                    // There's no actual difference between the start and end bounds, so while a
+                    // WCT change isn't needed, the dragged surface still needs to be snapped back
+                    // to its original location.
+                    releaseVisualIndicator()
+                    returnToDragStartAnimator.start(
+                        taskInfo.taskId,
+                        taskSurface,
+                        startBounds = currentDragBounds,
+                        endBounds = dragStartBounds,
+                    )
+                    return
+                }
 
                 // Update task bounds so that the task position will match the position of its leash
                 val wct = WindowContainerTransaction()
-                wct.setBounds(taskInfo.token, currentDragBounds)
+                wct.setBounds(taskInfo.token, destinationBounds)
                 transitions.startTransition(TRANSIT_CHANGE, wct, null)
 
                 releaseVisualIndicator()
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 f4df42c..4e08d10 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
@@ -19,28 +19,24 @@
 import android.animation.Animator
 import android.animation.RectEvaluator
 import android.animation.ValueAnimator
-import android.content.Context
 import android.graphics.Rect
 import android.view.SurfaceControl
-import android.widget.Toast
 import androidx.core.animation.addListener
 import com.android.internal.jank.Cuj
 import com.android.internal.jank.InteractionJankMonitor
-import com.android.wm.shell.R
 import com.android.wm.shell.windowdecor.OnTaskRepositionAnimationListener
 import java.util.function.Supplier
 
 /** Animates the task surface moving from its current drag position to its pre-drag position. */
 class ReturnToDragStartAnimator(
-    private val context: Context,
     private val transactionSupplier: Supplier<SurfaceControl.Transaction>,
     private val interactionJankMonitor: InteractionJankMonitor
 ) {
     private var boundsAnimator: Animator? = null
     private lateinit var taskRepositionAnimationListener: OnTaskRepositionAnimationListener
 
-    constructor(context: Context, interactionJankMonitor: InteractionJankMonitor) :
-            this(context, Supplier { SurfaceControl.Transaction() }, interactionJankMonitor)
+    constructor(interactionJankMonitor: InteractionJankMonitor) :
+            this(Supplier { SurfaceControl.Transaction() }, interactionJankMonitor)
 
     /** Sets a listener for the start and end of the reposition animation. */
     fun setTaskRepositionAnimationListener(listener: OnTaskRepositionAnimationListener) {
@@ -53,7 +49,7 @@
         taskSurface: SurfaceControl,
         startBounds: Rect,
         endBounds: Rect,
-        isResizable: Boolean
+        doOnEnd: (() -> Unit)? = null,
     ) {
         val tx = transactionSupplier.get()
 
@@ -87,13 +83,7 @@
                                 .apply()
                             taskRepositionAnimationListener.onAnimationEnd(taskId)
                             boundsAnimator = null
-                            if (!isResizable) {
-                                Toast.makeText(
-                                    context,
-                                    R.string.desktop_mode_non_resizable_snap_text,
-                                    Toast.LENGTH_SHORT
-                                ).show()
-                            }
+                            doOnEnd?.invoke()
                             interactionJankMonitor.end(Cuj.CUJ_DESKTOP_MODE_SNAP_RESIZE)
                         }
                     )
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecoration.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecoration.kt
index 2303ec9..a7087ae 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecoration.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecoration.kt
@@ -127,7 +127,6 @@
                     resizeMetadata.getLeash(),
                     startBounds = currentBounds,
                     endBounds = destinationBounds,
-                    isResizable = taskInfo.isResizeable,
                 )
             }
         }
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 018f9c2..fc89b0e 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
@@ -3029,7 +3029,7 @@
       eq(mockSurface),
       eq(currentDragBounds),
       eq(STABLE_BOUNDS),
-      eq(true)
+      anyOrNull(),
     )
   }
 
@@ -3344,7 +3344,7 @@
       eq(mockSurface),
       eq(currentDragBounds),
       eq(bounds),
-      eq(true)
+      anyOrNull(),
     )
     verify(desktopModeEventLogger, times(1)).logTaskResizingEnded(
       ResizeTrigger.SNAP_LEFT_MENU,
@@ -3401,7 +3401,7 @@
       eq(mockSurface),
       eq(currentDragBounds),
       eq(preDragBounds),
-      eq(false)
+      any(),
     )
     verify(desktopModeEventLogger, never()).logTaskResizingStarted(
       any(),
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecorationTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecorationTest.kt
index 5b0cdc3..2ae2461 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecorationTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecorationTest.kt
@@ -49,6 +49,7 @@
 import org.mockito.ArgumentMatchers.eq
 import org.mockito.Captor
 import org.mockito.kotlin.any
+import org.mockito.kotlin.anyOrNull
 import org.mockito.kotlin.capture
 import org.mockito.kotlin.mock
 import org.mockito.kotlin.never
@@ -196,7 +197,7 @@
 
         verify(toggleResizeDesktopTaskTransitionHandler, times(1))
             .startTransition(capture(wctCaptor), any())
-        verify(returnToDragStartAnimator, times(1)).start(any(), any(), any(), any(), any())
+        verify(returnToDragStartAnimator, times(1)).start(any(), any(), any(), any(), anyOrNull())
         for (change in wctCaptor.value.changes) {
             val bounds = change.value.configuration.windowConfiguration.bounds
             val leftBounds = getLeftTaskBounds()