Merge "[omni] Implement 2-stage for LPNH." into main
diff --git a/quickstep/src/com/android/quickstep/DeviceConfigWrapper.kt b/quickstep/src/com/android/quickstep/DeviceConfigWrapper.kt
index 678709c..1cc54d8 100644
--- a/quickstep/src/com/android/quickstep/DeviceConfigWrapper.kt
+++ b/quickstep/src/com/android/quickstep/DeviceConfigWrapper.kt
@@ -44,9 +44,26 @@
             "Enable AGSA override for LPNH and LPH timeout and touch slop"
         )
 
+    val lpnhTimeoutMs =
+        propReader.get("LPNH_TIMEOUT_MS", 450, "Controls lpnh timeout in milliseconds")
+
     val lpnhSlopPercentage =
         propReader.get("LPNH_SLOP_PERCENTAGE", 100, "Controls touch slop percentage for lpnh")
 
+    val enableLpnhTwoStages =
+        propReader.get(
+            "ENABLE_LPNH_TWO_STAGES",
+            false,
+            "Enable two stage for LPNH duration and touch slop"
+        )
+
+    val twoStageMultiplier =
+        propReader.get(
+            "TWO_STAGE_MULTIPLIER",
+            2,
+            "Extends the duration and touch slop if the initial slop is passed"
+        )
+
     val animateLpnh = propReader.get("ANIMATE_LPNH", false, "Animates navbar when long pressing")
 
     val shrinkNavHandleOnPress =
@@ -56,9 +73,6 @@
             "Shrinks navbar when long pressing if ANIMATE_LPNH is enabled"
         )
 
-    val lpnhTimeoutMs =
-        propReader.get("LPNH_TIMEOUT_MS", 450, "Controls lpnh timeout in milliseconds")
-
     val enableLongPressNavHandle =
         propReader.get(
             "ENABLE_LONG_PRESS_NAV_HANDLE",
diff --git a/quickstep/src/com/android/quickstep/inputconsumers/NavHandleLongPressInputConsumer.java b/quickstep/src/com/android/quickstep/inputconsumers/NavHandleLongPressInputConsumer.java
index 5ab2fcc..075e539 100644
--- a/quickstep/src/com/android/quickstep/inputconsumers/NavHandleLongPressInputConsumer.java
+++ b/quickstep/src/com/android/quickstep/inputconsumers/NavHandleLongPressInputConsumer.java
@@ -20,6 +20,7 @@
 import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_LONG_PRESS_NAVBAR;
 import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_LONG_PRESS_STASHED_TASKBAR;
 import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
+import static com.android.launcher3.util.LogConfig.NAV_HANDLE_LONG_PRESS;
 
 import android.content.Context;
 import android.util.Log;
@@ -43,14 +44,19 @@
 public class NavHandleLongPressInputConsumer extends DelegateInputConsumer {
 
     private static final String TAG = "NavHandleLongPressIC";
+    private static final boolean DEBUG_NAV_HANDLE = Utilities.isPropertyEnabled(
+            NAV_HANDLE_LONG_PRESS);
 
     private final NavHandleLongPressHandler mNavHandleLongPressHandler;
     private final float mNavHandleWidth;
     private final float mScreenWidth;
 
     private final Runnable mTriggerLongPress = this::triggerLongPress;
-    private final float mTouchSlopSquared;
+    private final float mTouchSlopSquaredOriginal;
+    private float mTouchSlopSquared;
+    private final float mOuterTouchSlopSquared;
     private final int mLongPressTimeout;
+    private final int mOuterLongPressTimeout;
     private final boolean mDeepPressEnabled;
     private final NavHandle mNavHandle;
     private final StatsLogManager mStatsLogManager;
@@ -65,13 +71,23 @@
         super(delegate, inputMonitor);
         mScreenWidth = DisplayController.INSTANCE.get(context).getInfo().currentSize.x;
         mDeepPressEnabled = DeviceConfigWrapper.get().getEnableLpnhDeepPress();
+        int twoStageMultiplier = DeviceConfigWrapper.get().getTwoStageMultiplier();
         AssistStateManager assistStateManager = AssistStateManager.INSTANCE.get(context);
         if (assistStateManager.getLPNHDurationMillis().isPresent()) {
             mLongPressTimeout = assistStateManager.getLPNHDurationMillis().get().intValue();
         } else {
             mLongPressTimeout = ViewConfiguration.getLongPressTimeout();
         }
-        mTouchSlopSquared = deviceState.getSquaredTouchSlop();
+        mOuterLongPressTimeout = mLongPressTimeout * twoStageMultiplier;
+        mTouchSlopSquaredOriginal = deviceState.getSquaredTouchSlop();
+        mTouchSlopSquared = mTouchSlopSquaredOriginal;
+        mOuterTouchSlopSquared = mTouchSlopSquared * (twoStageMultiplier * twoStageMultiplier);
+        if (DEBUG_NAV_HANDLE) {
+            Log.d(TAG, "mLongPressTimeout=" + mLongPressTimeout);
+            Log.d(TAG, "mOuterLongPressTimeout=" + mOuterLongPressTimeout);
+            Log.d(TAG, "mTouchSlopSquared=" + mTouchSlopSquared);
+            Log.d(TAG, "mOuterTouchSlopSquared=" + mOuterTouchSlopSquared);
+        }
         mNavHandle = navHandle;
         mNavHandleWidth = navHandle.getNavHandleWidth(context);
         mNavHandleLongPressHandler = NavHandleLongPressHandler.newInstance(context);
@@ -109,22 +125,44 @@
                     mCurrentDownEvent.recycle();
                 }
                 mCurrentDownEvent = MotionEvent.obtain(ev);
+                mTouchSlopSquared = mTouchSlopSquaredOriginal;
                 mDeepPressLogged = false;
                 if (isInNavBarHorizontalArea(ev.getRawX())) {
                     mNavHandleLongPressHandler.onTouchStarted(mNavHandle);
                     MAIN_EXECUTOR.getHandler().postDelayed(mTriggerLongPress, mLongPressTimeout);
                 }
+                if (DEBUG_NAV_HANDLE) {
+                    Log.d(TAG, "ACTION_DOWN");
+                }
             }
             case MotionEvent.ACTION_MOVE -> {
                 if (!MAIN_EXECUTOR.getHandler().hasCallbacks(mTriggerLongPress)) {
                     break;
                 }
 
-                float touchSlopSquared = mTouchSlopSquared;
                 float dx = ev.getX() - mCurrentDownEvent.getX();
                 float dy = ev.getY() - mCurrentDownEvent.getY();
                 double distanceSquared = (dx * dx) + (dy * dy);
-                if (distanceSquared > touchSlopSquared) {
+                if (DEBUG_NAV_HANDLE) {
+                    Log.d(TAG, "ACTION_MOVE distanceSquared=" + distanceSquared);
+                }
+                if (DeviceConfigWrapper.get().getEnableLpnhTwoStages()) {
+                    if (mTouchSlopSquared < distanceSquared
+                            && distanceSquared <= mOuterTouchSlopSquared) {
+                        MAIN_EXECUTOR.getHandler().removeCallbacks(mTriggerLongPress);
+                        int delay = mOuterLongPressTimeout
+                                - (int) (ev.getEventTime() - ev.getDownTime());
+                        MAIN_EXECUTOR.getHandler().postDelayed(mTriggerLongPress, delay);
+                        mTouchSlopSquared = mOuterTouchSlopSquared;
+                        if (DEBUG_NAV_HANDLE) {
+                            Log.d(TAG, "Touch in middle region!");
+                        }
+                    }
+                }
+                if (distanceSquared > mTouchSlopSquared) {
+                    if (DEBUG_NAV_HANDLE) {
+                        Log.d(TAG, "Touch slop out. mTouchSlopSquared=" + mTouchSlopSquared);
+                    }
                     cancelLongPress("touch slop passed");
                 }
             }
@@ -153,6 +191,9 @@
     }
 
     private void triggerLongPress() {
+        if (DEBUG_NAV_HANDLE) {
+            Log.d(TAG, "triggerLongPress");
+        }
         String runningPackage = mTopTaskTracker.getCachedTopTask(
                 /* filterOnlyVisibleRecents */ true).getPackageName();
         mStatsLogManager.logger().withPackageName(runningPackage).log(
@@ -175,6 +216,9 @@
     }
 
     private void cancelLongPress(String reason) {
+        if (DEBUG_NAV_HANDLE) {
+            Log.d(TAG, "cancelLongPress");
+        }
         MAIN_EXECUTOR.getHandler().removeCallbacks(mTriggerLongPress);
         mNavHandleLongPressHandler.onTouchFinished(mNavHandle, reason);
     }
diff --git a/src/com/android/launcher3/util/LogConfig.java b/src/com/android/launcher3/util/LogConfig.java
index e5bbcb1..d59c339 100644
--- a/src/com/android/launcher3/util/LogConfig.java
+++ b/src/com/android/launcher3/util/LogConfig.java
@@ -65,4 +65,9 @@
      * When turned on, we enable AGA related session summary logging.
      */
     public static final String AGA_SESSION_SUMMARY_LOG = "AGASessionSummaryLog";
+
+    /**
+     * When turned on, we enable long press nav handle related logging.
+     */
+    public static final String NAV_HANDLE_LONG_PRESS = "NavHandleLongPress";
 }