Prevent multiple competing dismissals.

This brings into line with existing UX prior to the feature.

Fix: 400727071
Test: Manual. Dismiss as quickly as possible.
Flag: com.android.launcher3.enable_expressive_dismiss_task_motion
Change-Id: Ie3f6f82c3ed4626829f3a61307e73cbdb8a31ceb
This commit is contained in:
Pat Manning
2025-03-14 16:06:46 +00:00
parent 02be70164c
commit cc973dfdce
3 changed files with 13 additions and 4 deletions
@@ -63,6 +63,7 @@ CONTAINER : RecentsViewContainer {
private var hasDismissThresholdHapticRun = false
private var initialDisplacement: Float = 0f
private var recentsScaleAnimation: SpringAnimation? = null
private var isBlockedDuringDismissal = false
private fun canInterceptTouch(ev: MotionEvent): Boolean =
when {
@@ -137,6 +138,7 @@ CONTAINER : RecentsViewContainer {
}
override fun onDragStart(start: Boolean, startDisplacement: Float) {
if (isBlockedDuringDismissal) return
val taskBeingDragged = taskBeingDragged ?: return
initialDisplacement =
@@ -149,6 +151,7 @@ CONTAINER : RecentsViewContainer {
}
override fun onDrag(displacement: Float): Boolean {
if (isBlockedDuringDismissal) return true
val taskBeingDragged = taskBeingDragged ?: return false
val currentDisplacement = displacement + initialDisplacement
val boundedDisplacement =
@@ -204,6 +207,7 @@ CONTAINER : RecentsViewContainer {
}
override fun onDragEnd(velocity: Float) {
if (isBlockedDuringDismissal) return
val taskBeingDragged = taskBeingDragged ?: return
val currentDisplacement =
@@ -234,6 +238,7 @@ CONTAINER : RecentsViewContainer {
if (isDismissing) (dismissLength * verticalFactor).toFloat() else 0f
)
}
isBlockedDuringDismissal = true
recentsScaleAnimation =
recentsView.animateRecentsScale(RECENTS_SCALE_DEFAULT).addEndListener { _, _, _, _ ->
recentsScaleAnimation = null
@@ -246,6 +251,7 @@ CONTAINER : RecentsViewContainer {
taskBeingDragged?.translationZ = 0f
taskBeingDragged = null
springAnimation = null
isBlockedDuringDismissal = false
}
private fun getRecentsScale(dismissFraction: Float): Float {
@@ -82,6 +82,7 @@ class RecentsDismissUtils(private val recentsView: RecentsView<*, *>) {
runTaskGridReflowSpringAnimation(
draggedTaskView,
getDismissedTaskGapForReflow(draggedTaskView),
onEndRunnable,
)
} else {
recentsView.dismissTaskView(
@@ -89,11 +90,12 @@ class RecentsDismissUtils(private val recentsView: RecentsView<*, *>) {
/* animateTaskView = */ false,
/* removeTask = */ true,
)
onEndRunnable()
}
} else {
recentsView.onDismissAnimationEnds()
onEndRunnable()
}
onEndRunnable()
}
if (!isDismissing) {
addNeighboringSpringAnimationsForDismissCancel(
@@ -312,6 +314,7 @@ class RecentsDismissUtils(private val recentsView: RecentsView<*, *>) {
private fun runTaskGridReflowSpringAnimation(
dismissedTaskView: TaskView,
dismissedTaskGap: Float,
onEndRunnable: () -> Unit,
) {
// Empty spring animation exists for conditional start, and to drive neighboring springs.
val springAnimationDriver =
@@ -384,7 +387,7 @@ class RecentsDismissUtils(private val recentsView: RecentsView<*, *>) {
// Start animations and remove the dismissed task at the end, dismiss immediately if no
// neighboring tasks exist.
val runGridEndAnimationAndRelayout = {
recentsView.expressiveDismissTaskView(dismissedTaskView)
recentsView.expressiveDismissTaskView(dismissedTaskView, onEndRunnable)
}
springAnimationDriver?.apply {
addEndListener { _, _, _, _ -> runGridEndAnimationAndRelayout() }
@@ -142,7 +142,6 @@ import androidx.annotation.UiThread;
import androidx.core.graphics.ColorUtils;
import androidx.dynamicanimation.animation.SpringAnimation;
import com.android.app.tracing.TraceUtilsKt;
import com.android.internal.jank.Cuj;
import com.android.launcher3.AbstractFloatingView;
import com.android.launcher3.BaseActivity.MultiWindowModeChangedListener;
@@ -4748,11 +4747,12 @@ public abstract class RecentsView<
runDismissAnimation(pa);
}
protected void expressiveDismissTaskView(TaskView taskView) {
protected void expressiveDismissTaskView(TaskView taskView, Function0<Unit> onEndRunnable) {
PendingAnimation pa = new PendingAnimation(DISMISS_TASK_DURATION);
createTaskDismissAnimation(pa, taskView, false /* animateTaskView */, true /* removeTask */,
DISMISS_TASK_DURATION, false /* dismissingForSplitSelection*/,
true /* isExpressiveDismiss */);
pa.addEndListener((success) -> onEndRunnable.invoke());
runDismissAnimation(pa);
}