diff --git a/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java b/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java index cbe2634452..2cae41ca2a 100644 --- a/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java +++ b/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java @@ -425,6 +425,7 @@ public class NavbarButtonsViewController implements TaskbarControllers.LoggableT mSeparateWindowParent = new BaseDragLayer<>(mContext, null, 0) { @Override public void recreateControllers() { + super.recreateControllers(); mControllers = new TouchController[0]; } diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayer.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayer.java index 4dbad8c56f..be5c8741d0 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayer.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayer.java @@ -126,6 +126,7 @@ public class TaskbarDragLayer extends BaseDragLayer { @Override public void recreateControllers() { + super.recreateControllers(); mControllers = mControllerCallbacks.getTouchControllers(); } diff --git a/quickstep/src/com/android/launcher3/taskbar/VoiceInteractionWindowController.kt b/quickstep/src/com/android/launcher3/taskbar/VoiceInteractionWindowController.kt index c7d42b1b90..c065d35528 100644 --- a/quickstep/src/com/android/launcher3/taskbar/VoiceInteractionWindowController.kt +++ b/quickstep/src/com/android/launcher3/taskbar/VoiceInteractionWindowController.kt @@ -67,6 +67,7 @@ class VoiceInteractionWindowController(val context: TaskbarActivityContext) : separateWindowForTaskbarBackground = object : BaseDragLayer(context, null, 0) { override fun recreateControllers() { + super.recreateControllers() mControllers = emptyArray() } diff --git a/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayDragLayer.java b/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayDragLayer.java index 41694ecee5..9ecffdc6b3 100644 --- a/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayDragLayer.java +++ b/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayDragLayer.java @@ -71,6 +71,7 @@ public class TaskbarOverlayDragLayer extends @Override public void recreateControllers() { + super.recreateControllers(); List controllers = new ArrayList<>(); controllers.add(mContainer.getDragController()); controllers.addAll(mTouchControllers); diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/TaskViewDismissTouchController.kt b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/TaskViewDismissTouchController.kt index 5cd717ac30..f2507da24a 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/TaskViewDismissTouchController.kt +++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/TaskViewDismissTouchController.kt @@ -28,6 +28,9 @@ import com.android.launcher3.Utilities.boundToRange import com.android.launcher3.Utilities.debugLog import com.android.launcher3.Utilities.isRtl import com.android.launcher3.Utilities.mapToRange +import com.android.launcher3.statemanager.BaseState +import com.android.launcher3.statemanager.StateManager.StateListener +import com.android.launcher3.statemanager.StatefulContainer import com.android.launcher3.touch.SingleAxisSwipeDetector import com.android.launcher3.util.MSDLPlayerWrapper import com.android.launcher3.util.TouchController @@ -40,12 +43,13 @@ import kotlin.math.abs import kotlin.math.ceil /** Touch controller for handling task view card dismiss swipes */ -class TaskViewDismissTouchController( +class TaskViewDismissTouchController>( private val container: CONTAINER, private val taskViewRecentsTouchContext: TaskViewRecentsTouchContext, ) : TouchController, SingleAxisSwipeDetector.Listener where CONTAINER : Context, -CONTAINER : RecentsViewContainer { +CONTAINER : RecentsViewContainer, +CONTAINER : StatefulContainer { private val recentsView: RecentsView<*, *> = container.getOverviewPanel() private val detector: SingleAxisSwipeDetector = SingleAxisSwipeDetector( @@ -55,7 +59,13 @@ CONTAINER : RecentsViewContainer { ) private val isRtl = isRtl(container.resources) private val upDirection: Int = recentsView.pagedOrientationHandler.getUpDirection(isRtl) - + private val stateListener = + object : StateListener { + override fun onStateTransitionStart(toState: T) { + springAnimation?.cancel() + clearState() + } + } private val tempTaskThumbnailBounds = Rect() private var taskBeingDragged: TaskView? = null @@ -68,6 +78,14 @@ CONTAINER : RecentsViewContainer { private var isBlockedDuringDismissal = false private var canInterceptTouch = false + init { + container.getStateManager().addStateListener(stateListener) + } + + override fun onTouchControllerDestroyed() { + container.getStateManager().removeStateListener(stateListener) + } + private fun canInterceptTouch(ev: MotionEvent): Boolean = when { // Don't intercept swipes on the nav bar, as user might be trying to go home during a @@ -261,6 +279,7 @@ CONTAINER : RecentsViewContainer { taskBeingDragged, velocity, isDismissing, + dismissLength, dismissThreshold, finalPosition, /* shouldRemoveTaskView= */ isDismissing, diff --git a/quickstep/src/com/android/quickstep/fallback/RecentsDragLayer.java b/quickstep/src/com/android/quickstep/fallback/RecentsDragLayer.java index 5d4f1db1a9..a3b5b9e417 100644 --- a/quickstep/src/com/android/quickstep/fallback/RecentsDragLayer.java +++ b/quickstep/src/com/android/quickstep/fallback/RecentsDragLayer.java @@ -55,6 +55,7 @@ public class RecentsDragLayer(mContainer, diff --git a/quickstep/src/com/android/quickstep/views/RecentsDismissUtils.kt b/quickstep/src/com/android/quickstep/views/RecentsDismissUtils.kt index b0d3c0e011..1dd0ac9e9d 100644 --- a/quickstep/src/com/android/quickstep/views/RecentsDismissUtils.kt +++ b/quickstep/src/com/android/quickstep/views/RecentsDismissUtils.kt @@ -65,6 +65,7 @@ class RecentsDismissUtils(private val recentsView: RecentsView<*, *>) { draggedTaskView, velocity = 0f, isDismissing = true, + dismissLength = 0, dismissThreshold = 0, finalPosition = 0f, shouldRemoveTaskView, @@ -88,6 +89,7 @@ class RecentsDismissUtils(private val recentsView: RecentsView<*, *>) { draggedTaskView, velocity, isDismissing = true, + dismissLength, dismissThreshold, finalPosition, shouldRemoveTaskView, @@ -107,6 +109,7 @@ class RecentsDismissUtils(private val recentsView: RecentsView<*, *>) { draggedTaskView: TaskView?, velocity: Float, isDismissing: Boolean, + dismissLength: Int, dismissThreshold: Int, finalPosition: Float, shouldRemoveTaskView: Boolean, @@ -160,7 +163,7 @@ class RecentsDismissUtils(private val recentsView: RecentsView<*, *>) { SpringAnimation(draggedTaskView, taskDismissFloatProperty) .setSpring(createExpressiveDismissSpringForce()) .setStartVelocity(startVelocity) - .addUpdateListener { _, currentDisplacement, _ -> + .addUpdateListener { animation, currentDisplacement, _ -> // Play haptic as task crosses dismiss threshold from above or below. val previousBeyondThreshold = abs(previousDisplacement) >= abs(dismissThreshold) val currentBeyondThreshold = abs(currentDisplacement) >= abs(dismissThreshold) @@ -185,8 +188,16 @@ class RecentsDismissUtils(private val recentsView: RecentsView<*, *>) { ) { toRunOnEnd() } + // End dismissed task animation once beyond the screen so next animations play. + if (isDismissing && abs(currentDisplacement) >= abs(dismissLength)) { + (animation as SpringAnimation).skipToEnd() + } + } + .addEndListener { _, canceled, value, _ -> + // Do not run animations if dismissed task animation is canceled, unless it has + // already animated off screen. + if (!canceled || abs(value) >= abs(dismissLength)) toRunOnEnd() } - .addEndListener { _, _, _, _ -> toRunOnEnd() } if (!isDismissing) { addNeighborSettlingSpringAnimations( draggedTaskView, diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java index 028f1b281c..c30ba0ded2 100644 --- a/quickstep/src/com/android/quickstep/views/RecentsView.java +++ b/quickstep/src/com/android/quickstep/views/RecentsView.java @@ -7003,11 +7003,11 @@ public abstract class RecentsView< * spring in response to the perceived impact of the settling task. */ public SpringAnimation runTaskDismissSettlingSpringAnimation(TaskView draggedTaskView, - float velocity, boolean isDismissing, int dismissThreshold, float finalPosition, - boolean shouldRemoveTaskView, boolean isSplitSelection, + float velocity, boolean isDismissing, int dismissLength, int dismissThreshold, + float finalPosition, boolean shouldRemoveTaskView, boolean isSplitSelection, @NonNull Function0 onEndRunnable) { return mDismissUtils.createTaskDismissSettlingSpringAnimation(draggedTaskView, velocity, - isDismissing, dismissThreshold, finalPosition, shouldRemoveTaskView, + isDismissing, dismissLength, dismissThreshold, finalPosition, shouldRemoveTaskView, isSplitSelection, onEndRunnable); } diff --git a/src/com/android/launcher3/dragndrop/DragLayer.java b/src/com/android/launcher3/dragndrop/DragLayer.java index 41b42b659b..d32bbe3626 100644 --- a/src/com/android/launcher3/dragndrop/DragLayer.java +++ b/src/com/android/launcher3/dragndrop/DragLayer.java @@ -124,6 +124,7 @@ public class DragLayer extends BaseDragLayer implements LauncherOverla @Override public void recreateControllers() { + super.recreateControllers(); mControllers = mContainer.createTouchControllers(); } diff --git a/src/com/android/launcher3/dragndrop/SimpleDragLayer.java b/src/com/android/launcher3/dragndrop/SimpleDragLayer.java index e42ba7261b..1ed9c68482 100644 --- a/src/com/android/launcher3/dragndrop/SimpleDragLayer.java +++ b/src/com/android/launcher3/dragndrop/SimpleDragLayer.java @@ -39,6 +39,7 @@ public class SimpleDragLayer extends BaseDr @Override public void recreateControllers() { + super.recreateControllers(); mControllers = new TouchController[] {}; } } diff --git a/src/com/android/launcher3/secondarydisplay/SecondaryDragLayer.java b/src/com/android/launcher3/secondarydisplay/SecondaryDragLayer.java index d5c87f4874..7c1bffbc69 100644 --- a/src/com/android/launcher3/secondarydisplay/SecondaryDragLayer.java +++ b/src/com/android/launcher3/secondarydisplay/SecondaryDragLayer.java @@ -64,6 +64,7 @@ public class SecondaryDragLayer extends BaseDragLayer @Override public void recreateControllers() { + super.recreateControllers(); mControllers = new TouchController[]{new CloseAllAppsTouchController(), mContainer.getDragController()}; } diff --git a/src/com/android/launcher3/util/TouchController.java b/src/com/android/launcher3/util/TouchController.java index fc1d819f78..989d69da6c 100644 --- a/src/com/android/launcher3/util/TouchController.java +++ b/src/com/android/launcher3/util/TouchController.java @@ -33,4 +33,7 @@ public interface TouchController { boolean onControllerInterceptTouchEvent(MotionEvent ev); default void dump(String prefix, PrintWriter writer) { } + + /** Called when touch controllers are destroyed during recreation. */ + default void onTouchControllerDestroyed() { } } diff --git a/src/com/android/launcher3/views/BaseDragLayer.java b/src/com/android/launcher3/views/BaseDragLayer.java index ea3fb3fb42..d465b4071c 100644 --- a/src/com/android/launcher3/views/BaseDragLayer.java +++ b/src/com/android/launcher3/views/BaseDragLayer.java @@ -128,7 +128,13 @@ public abstract class BaseDragLayer /** * Called to reinitialize touch controllers. */ - public abstract void recreateControllers(); + public void recreateControllers() { + if (mControllers != null) { + for (TouchController controller : mControllers) { + controller.onTouchControllerDestroyed(); + } + } + } /** * Same as {@link #isEventOverView(View, MotionEvent, View)} where evView == this drag layer. diff --git a/tests/multivalentTests/src/com/android/launcher3/util/ActivityContextWrapper.java b/tests/multivalentTests/src/com/android/launcher3/util/ActivityContextWrapper.java index f4dc88d5de..880a88a43b 100644 --- a/tests/multivalentTests/src/com/android/launcher3/util/ActivityContextWrapper.java +++ b/tests/multivalentTests/src/com/android/launcher3/util/ActivityContextWrapper.java @@ -60,6 +60,7 @@ public class ActivityContextWrapper extends BaseContext { @Override public void recreateControllers() { + super.recreateControllers(); mControllers = new TouchController[0]; } }