1/ Provides feasibility to adjust touch slop in TouchController

There is a case when one handed mode triggered(Activated), all apps
drawer is very easy to trigger while user swipe up around NavBar
region to exit one handed mode. Since System Gesture monitor regsion
is small on screen bottom, swipe-up gesture usually cross over NavBar
monitor region and invoke launcher touch controller intercept touch
event and introduce unexpectedly trigger all apps drawer.

Adding onOneHandedModeStateChanged(boolean activated) for controller
be able to adjust the touch slop by multiplier, we can set a larger
multiplier when the visible window size translate become smaller
and make swipe gesture not too sensitive.

Test: manual swipe up to swich "home <-> all apps" and monitor
      minDisplacement of SingleAxisSwipeDetector
Test: Trigger one handed mode and swipe up to exit one handed mode
      check the minDisplacement of SingleAxisSwipeDetector
Bug: 186235522
Change-Id: I9729cd408d85b2b22582bf800e28d1471fc06980
diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonNavbarToOverviewTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonNavbarToOverviewTouchController.java
index eb62110..283743d 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonNavbarToOverviewTouchController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonNavbarToOverviewTouchController.java
@@ -51,7 +51,7 @@
  * first home screen instead of to Overview.
  */
 public class NoButtonNavbarToOverviewTouchController extends PortraitStatesTouchController {
-
+    private static final float ONE_HANDED_ACTIVATED_SLOP_MULTIPLIER = 2.5f;
 
     // How much of the movement to use for translating overview after swipe and hold.
     private static final float OVERVIEW_MOVEMENT_FACTOR = 0.25f;
@@ -260,4 +260,14 @@
     private float dpiFromPx(float pixels) {
         return Utilities.dpiFromPx(pixels, mLauncher.getResources().getDisplayMetrics().densityDpi);
     }
+
+    @Override
+    public void onOneHandedModeStateChanged(boolean activated) {
+        if (activated) {
+            mDetector.setTouchSlopMultiplier(ONE_HANDED_ACTIVATED_SLOP_MULTIPLIER);
+        } else {
+            // Reset touch slop multiplier to default 1.0f
+            mDetector.setTouchSlopMultiplier(1f /* default */);
+        }
+    }
 }
diff --git a/src/com/android/launcher3/dragndrop/DragLayer.java b/src/com/android/launcher3/dragndrop/DragLayer.java
index c2f609c..011325d 100644
--- a/src/com/android/launcher3/dragndrop/DragLayer.java
+++ b/src/com/android/launcher3/dragndrop/DragLayer.java
@@ -48,6 +48,7 @@
 import com.android.launcher3.graphics.Scrim;
 import com.android.launcher3.keyboard.ViewGroupFocusHelper;
 import com.android.launcher3.util.Thunk;
+import com.android.launcher3.util.TouchController;
 import com.android.launcher3.views.BaseDragLayer;
 
 import java.util.ArrayList;
@@ -519,4 +520,14 @@
     public Scrim getWorkspaceDragScrim() {
         return mWorkspaceDragScrim;
     }
+
+    /**
+     * Called when one handed mode state changed.
+     * @param activated true if one handed mode activated, false otherwise.
+     */
+    public void onOneHandedModeStateChanged(boolean activated) {
+        for (TouchController controller : mControllers) {
+            controller.onOneHandedModeStateChanged(activated);
+        }
+    }
 }
diff --git a/src/com/android/launcher3/touch/SingleAxisSwipeDetector.java b/src/com/android/launcher3/touch/SingleAxisSwipeDetector.java
index 8c3c115..f751b7d 100644
--- a/src/com/android/launcher3/touch/SingleAxisSwipeDetector.java
+++ b/src/com/android/launcher3/touch/SingleAxisSwipeDetector.java
@@ -102,6 +102,8 @@
 
     private int mScrollDirections;
 
+    private float mTouchSlopMultiplier = 1f;
+
     public SingleAxisSwipeDetector(@NonNull Context context, @NonNull Listener l,
             @NonNull Direction dir) {
         this(ViewConfiguration.get(context), l, dir, Utilities.isRtl(context.getResources()));
@@ -115,6 +117,19 @@
         mDir = dir;
     }
 
+    /**
+     * Provides feasibility to adjust touch slop when visible window size changed. When visible
+     * bounds translate become smaller, multiply a larger multiplier could ensure the UX
+     * more consistent.
+     *
+     * @see #shouldScrollStart(PointF)
+     *
+     * @param touchSlopMultiplier the value to multiply original touch slop.
+     */
+    public void setTouchSlopMultiplier(float touchSlopMultiplier) {
+        mTouchSlopMultiplier = touchSlopMultiplier;
+    }
+
     public void setDetectableScrollConditions(int scrollDirectionFlags, boolean ignoreSlop) {
         mScrollDirections = scrollDirectionFlags;
         mIgnoreSlopWhenSettling = ignoreSlop;
@@ -133,7 +148,7 @@
     @Override
     protected boolean shouldScrollStart(PointF displacement) {
         // Reject cases where the angle or slop condition is not met.
-        float minDisplacement = Math.max(mTouchSlop,
+        float minDisplacement = Math.max(mTouchSlop * mTouchSlopMultiplier,
                 Math.abs(mDir.extractOrthogonalDirection(displacement)));
         if (Math.abs(mDir.extractDirection(displacement)) < minDisplacement) {
             return false;
diff --git a/src/com/android/launcher3/util/TouchController.java b/src/com/android/launcher3/util/TouchController.java
index fc1d819..9c397c0 100644
--- a/src/com/android/launcher3/util/TouchController.java
+++ b/src/com/android/launcher3/util/TouchController.java
@@ -32,5 +32,10 @@
      */
     boolean onControllerInterceptTouchEvent(MotionEvent ev);
 
+    /**
+     * Called when one handed mode state changed
+     */
+    default void onOneHandedModeStateChanged(boolean activated) { }
+
     default void dump(String prefix, PrintWriter writer) { }
 }