Cancel predictive back when sliding off back button

Bug: 373544911
Test: Manual, i.e. verified that sliding away from the back button (within the taskbar window) cancels the predictive back animation
Flag: com.android.window.flags.predictive_back_three_button_nav
Change-Id: I9a1448c7005211c87a8979261b13fe37ab64a5b2
diff --git a/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java b/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java
index f9e7cf0..f346e19 100644
--- a/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java
@@ -66,6 +66,7 @@
 import android.graphics.Color;
 import android.graphics.Point;
 import android.graphics.Rect;
+import android.graphics.RectF;
 import android.graphics.Region;
 import android.graphics.Region.Op;
 import android.graphics.drawable.Drawable;
@@ -75,6 +76,7 @@
 import android.os.Handler;
 import android.util.Property;
 import android.view.Gravity;
+import android.view.HapticFeedbackConstants;
 import android.view.KeyEvent;
 import android.view.MotionEvent;
 import android.view.View;
@@ -862,15 +864,21 @@
 
     private void setBackButtonTouchListener(View buttonView,
             TaskbarNavButtonController navButtonController) {
+        final RectF rect = new RectF();
         buttonView.setOnTouchListener((v, event) -> {
-            if (event.getAction() == MotionEvent.ACTION_MOVE) return false;
+            if (event.getAction() == MotionEvent.ACTION_DOWN) {
+                rect.set(0, 0, v.getWidth(), v.getHeight());
+            }
+            boolean isCancelled = event.getAction() == MotionEvent.ACTION_CANCEL
+                    || !rect.contains(event.getX(), event.getY());
+            if (event.getAction() == MotionEvent.ACTION_MOVE && !isCancelled) return false;
             int motionEventAction = event.getAction();
             int keyEventAction = motionEventAction == MotionEvent.ACTION_DOWN
                     ? KeyEvent.ACTION_DOWN : ACTION_UP;
-            boolean isCancelled = event.getAction() == MotionEvent.ACTION_CANCEL;
             navButtonController.sendBackKeyEvent(keyEventAction, isCancelled);
-            if (motionEventAction == MotionEvent.ACTION_UP) {
+            if (motionEventAction == MotionEvent.ACTION_UP && !isCancelled) {
                 buttonView.performClick();
+                buttonView.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);
             }
             return false;
         });