From eb58fdaf602b01a8eaaa7a5c10fe3ad818faa8e3 Mon Sep 17 00:00:00 2001 From: Johannes Gallmann Date: Wed, 12 Mar 2025 07:43:02 +0000 Subject: [PATCH] Add 200 ms delay for predictive back animation in 3-button-nav Bug: 373544911 Test: Manual, i.e. verifying that regular clicks on the back button don't trigger predictive back animations but long presses do Flag: com.android.window.flags.predictive_back_three_button_nav Change-Id: I148bae8f09fa9b6d17fd929067b02175882115a3 --- .../taskbar/NavbarButtonsViewController.java | 28 ++++++++++++++----- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java b/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java index ee5b8d1285..b363e40417 100644 --- a/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java +++ b/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java @@ -15,7 +15,6 @@ */ package com.android.launcher3.taskbar; -import static android.view.KeyEvent.ACTION_UP; import static android.view.View.AccessibilityDelegate; import static android.view.ViewGroup.LayoutParams.MATCH_PARENT; import static android.view.ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION; @@ -121,6 +120,7 @@ import com.android.wm.shell.shared.bubbles.BubbleBarLocation; import java.io.PrintWriter; import java.util.ArrayList; import java.util.StringJoiner; +import java.util.concurrent.atomic.AtomicBoolean; import java.util.function.IntPredicate; /** @@ -174,6 +174,7 @@ public class NavbarButtonsViewController implements TaskbarControllers.LoggableT private static final int NUM_ALPHA_CHANNELS = 3; private static final long AUTODIM_TIMEOUT_MS = 2250; + private static final long PREDICTIVE_BACK_TIMEOUT_MS = 200; private final ArrayList mPropertyHolders = new ArrayList<>(); private final ArrayList mAllButtons = new ArrayList<>(); @@ -882,23 +883,36 @@ public class NavbarButtonsViewController implements TaskbarControllers.LoggableT private void setBackButtonTouchListener(View buttonView, TaskbarNavButtonController navButtonController) { final RectF rect = new RectF(); + final AtomicBoolean hasSentDownEvent = new AtomicBoolean(false); + final Runnable longPressTimeout = () -> { + navButtonController.sendBackKeyEvent(KeyEvent.ACTION_DOWN, /*cancelled*/ false); + hasSentDownEvent.set(true); + }; buttonView.setOnTouchListener((v, event) -> { int motionEventAction = event.getAction(); if (motionEventAction == MotionEvent.ACTION_DOWN) { + hasSentDownEvent.set(false); + mHandler.postDelayed(longPressTimeout, PREDICTIVE_BACK_TIMEOUT_MS); rect.set(0, 0, v.getWidth(), v.getHeight()); } boolean isCancelled = motionEventAction == MotionEvent.ACTION_CANCEL || (!rect.contains(event.getX(), event.getY()) && (motionEventAction == MotionEvent.ACTION_MOVE || motionEventAction == MotionEvent.ACTION_UP)); - if (motionEventAction != MotionEvent.ACTION_DOWN - && motionEventAction != MotionEvent.ACTION_UP && !isCancelled) { - // return early. we don't care about any other cases than DOWN, UP and CANCEL + if (motionEventAction != MotionEvent.ACTION_UP && !isCancelled) { + // return early. we don't care about any other cases than UP or CANCEL from here on return false; } - int keyEventAction = motionEventAction == MotionEvent.ACTION_DOWN - ? KeyEvent.ACTION_DOWN : ACTION_UP; - navButtonController.sendBackKeyEvent(keyEventAction, isCancelled); + mHandler.removeCallbacks(longPressTimeout); + if (!hasSentDownEvent.get()) { + if (isCancelled) { + // if it is cancelled and ACTION_DOWN has not been sent yet, return early and + // don't send anything to sysui. + return false; + } + navButtonController.sendBackKeyEvent(KeyEvent.ACTION_DOWN, isCancelled); + } + navButtonController.sendBackKeyEvent(KeyEvent.ACTION_UP, isCancelled); if (motionEventAction == MotionEvent.ACTION_UP && !isCancelled) { buttonView.performClick(); buttonView.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);