Adds a debug & server configurable delay to search haptic hint

Fix: 311370599
Test: Manual
Flag: LEGACY ENABLE_SEARCH_HAPTIC_HINT ENABLED

Change-Id: Ic050e8426ef91b28e6bf1dc4d86839eaa20b0dc0
diff --git a/quickstep/src/com/android/launcher3/uioverrides/flags/DeveloperOptionsUI.java b/quickstep/src/com/android/launcher3/uioverrides/flags/DeveloperOptionsUI.java
index 36d62c6..6671fc3 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/flags/DeveloperOptionsUI.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/flags/DeveloperOptionsUI.java
@@ -21,6 +21,7 @@
 import static android.view.View.VISIBLE;
 
 import static com.android.launcher3.LauncherPrefs.ALL_APPS_OVERVIEW_THRESHOLD;
+import static com.android.launcher3.LauncherPrefs.LONG_PRESS_NAV_HANDLE_HAPTIC_HINT_DELAY;
 import static com.android.launcher3.LauncherPrefs.LONG_PRESS_NAV_HANDLE_HAPTIC_HINT_END_SCALE_PERCENT;
 import static com.android.launcher3.LauncherPrefs.LONG_PRESS_NAV_HANDLE_HAPTIC_HINT_ITERATIONS;
 import static com.android.launcher3.LauncherPrefs.LONG_PRESS_NAV_HANDLE_HAPTIC_HINT_SCALE_EXPONENT;
@@ -359,6 +360,8 @@
                     1, 5, 1, LONG_PRESS_NAV_HANDLE_HAPTIC_HINT_SCALE_EXPONENT));
             category.addPreference(createSeekBarPreference("Haptic hint iterations (12 ms each)",
                     0, 100, 1, LONG_PRESS_NAV_HANDLE_HAPTIC_HINT_ITERATIONS));
+            category.addPreference(createSeekBarPreference("Haptic hint delay (ms)",
+                    0, 400, 1, LONG_PRESS_NAV_HANDLE_HAPTIC_HINT_DELAY));
         }
     }
 
diff --git a/src/com/android/launcher3/LauncherPrefs.kt b/src/com/android/launcher3/LauncherPrefs.kt
index fb58cbe..a05b0f5 100644
--- a/src/com/android/launcher3/LauncherPrefs.kt
+++ b/src/com/android/launcher3/LauncherPrefs.kt
@@ -24,6 +24,7 @@
 import com.android.launcher3.BuildConfig.WIDGET_ON_FIRST_SCREEN
 import com.android.launcher3.LauncherFiles.DEVICE_PREFERENCES_KEY
 import com.android.launcher3.LauncherFiles.SHARED_PREFERENCES_KEY
+import com.android.launcher3.config.FeatureFlags.LPNH_HAPTIC_HINT_DELAY
 import com.android.launcher3.config.FeatureFlags.LPNH_HAPTIC_HINT_END_SCALE_PERCENT
 import com.android.launcher3.config.FeatureFlags.LPNH_HAPTIC_HINT_ITERATIONS
 import com.android.launcher3.config.FeatureFlags.LPNH_HAPTIC_HINT_SCALE_EXPONENT
@@ -356,6 +357,13 @@
                         EncryptionType.MOVE_TO_DEVICE_PROTECTED
                 )
         @JvmField
+        val LONG_PRESS_NAV_HANDLE_HAPTIC_HINT_DELAY =
+                nonRestorableItem(
+                        "pref_long_press_nav_handle_haptic_hint_delay",
+                        LPNH_HAPTIC_HINT_DELAY.get(),
+                        EncryptionType.MOVE_TO_DEVICE_PROTECTED
+                )
+        @JvmField
         val THEMED_ICONS =
             backedUpItem(Themes.KEY_THEMED_ICONS, false, EncryptionType.MOVE_TO_DEVICE_PROTECTED)
         @JvmField val PROMISE_ICON_IDS = backedUpItem(InstallSessionHelper.PROMISE_ICON_IDS, "")
diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java
index 26751ee..8e583c2 100644
--- a/src/com/android/launcher3/config/FeatureFlags.java
+++ b/src/com/android/launcher3/config/FeatureFlags.java
@@ -306,6 +306,10 @@
             getReleaseFlag(310952290, "ENABLE_LPNH_DEEP_PRESS", ENABLED,
                     "Long press of nav handle is instantly triggered if deep press is detected.");
 
+    public static final IntFlag LPNH_HAPTIC_HINT_DELAY =
+            getIntFlag(309972570, "LPNH_HAPTIC_HINT_ITERATIONS", 0,
+                    "Delay before haptic hint starts.");
+
     // TODO(Block 17): Clean up flags
     // Aconfig migration complete for ENABLE_TASKBAR_PINNING.
     private static final BooleanFlag ENABLE_TASKBAR_PINNING = getDebugFlag(270396583,
diff --git a/src/com/android/launcher3/util/VibratorWrapper.java b/src/com/android/launcher3/util/VibratorWrapper.java
index 80a9bae..8aaad93 100644
--- a/src/com/android/launcher3/util/VibratorWrapper.java
+++ b/src/com/android/launcher3/util/VibratorWrapper.java
@@ -18,6 +18,7 @@
 import static android.os.VibrationEffect.createPredefined;
 import static android.provider.Settings.System.HAPTIC_FEEDBACK_ENABLED;
 
+import static com.android.launcher3.LauncherPrefs.LONG_PRESS_NAV_HANDLE_HAPTIC_HINT_DELAY;
 import static com.android.launcher3.LauncherPrefs.LONG_PRESS_NAV_HANDLE_HAPTIC_HINT_END_SCALE_PERCENT;
 import static com.android.launcher3.LauncherPrefs.LONG_PRESS_NAV_HANDLE_HAPTIC_HINT_ITERATIONS;
 import static com.android.launcher3.LauncherPrefs.LONG_PRESS_NAV_HANDLE_HAPTIC_HINT_SCALE_EXPONENT;
@@ -247,21 +248,30 @@
         if (FeatureFlags.ENABLE_SEARCH_HAPTIC_HINT.get() && Utilities.ATLEAST_S
                 && mVibrator.areAllPrimitivesSupported(
                 VibrationEffect.Composition.PRIMITIVE_LOW_TICK)) {
-            float startScale = LauncherPrefs.get(mContext).get(
+            LauncherPrefs launcherPrefs = LauncherPrefs.get(mContext);
+            float startScale = launcherPrefs.get(
                     LONG_PRESS_NAV_HANDLE_HAPTIC_HINT_START_SCALE_PERCENT) / 100f;
-            float endScale = LauncherPrefs.get(mContext).get(
+            float endScale = launcherPrefs.get(
                     LONG_PRESS_NAV_HANDLE_HAPTIC_HINT_END_SCALE_PERCENT) / 100f;
-            int scaleExponent = LauncherPrefs.get(mContext).get(
+            int scaleExponent = launcherPrefs.get(
                     LONG_PRESS_NAV_HANDLE_HAPTIC_HINT_SCALE_EXPONENT);
-            int iterations = LauncherPrefs.get(mContext).get(
+            int iterations = launcherPrefs.get(
                     LONG_PRESS_NAV_HANDLE_HAPTIC_HINT_ITERATIONS);
+            int delayMs = launcherPrefs.get(
+                    LONG_PRESS_NAV_HANDLE_HAPTIC_HINT_DELAY);
 
             VibrationEffect.Composition composition = VibrationEffect.startComposition();
             for (int i = 0; i < iterations; i++) {
                 float t = i / (iterations - 1f);
                 float scale = (float) Math.pow((1 - t) * startScale + t * endScale,
                         scaleExponent);
-                composition.addPrimitive(VibrationEffect.Composition.PRIMITIVE_LOW_TICK, scale);
+                if (i == 0) {
+                    // Adds a delay before the ramp starts
+                    composition.addPrimitive(VibrationEffect.Composition.PRIMITIVE_LOW_TICK, scale,
+                            delayMs);
+                } else {
+                    composition.addPrimitive(VibrationEffect.Composition.PRIMITIVE_LOW_TICK, scale);
+                }
             }
 
             vibrate(composition.compose());