Using performHapticFeedback on ControlActionCoordinatorImpl

Replacing the calls to vibrate() with performHapticFeedback when a drag()
action is performed. The vibrations for when the drag event corresponds to
an edge or not where replaced by the SEGMENT_TICK and
SEGMENT_FREQUENT_TICK, respectively. The changes are controlled by a feature
flag

Test: Unit tests were added to ControlActionCoordinatorImplTest to verify
  that vibrate() or performHapticFeedback are used depending on the flag.
Bug: 245528624
Change-Id: Ifdb9e45c97071838a92d998912b5d8529b789320
diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlActionCoordinator.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlActionCoordinator.kt
index 8029ba8..534832c 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlActionCoordinator.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlActionCoordinator.kt
@@ -54,9 +54,10 @@
     /**
      * When a ToggleRange control is interacting with, a drag event is sent.
      *
+     * @param cvh [ControlViewHolder] for the control
      * @param isEdge did the drag event reach a control edge
      */
-    fun drag(isEdge: Boolean)
+    fun drag(cvh: ControlViewHolder, isEdge: Boolean)
 
     /**
      * Send a request to update the value of a device using the [FloatAction].
diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlActionCoordinatorImpl.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlActionCoordinatorImpl.kt
index a7e9efd8..00d95c0 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlActionCoordinatorImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlActionCoordinatorImpl.kt
@@ -37,6 +37,8 @@
 import com.android.systemui.controls.settings.ControlsSettingsRepository
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Main
+import com.android.systemui.flags.FeatureFlags
+import com.android.systemui.flags.Flags.ONE_WAY_HAPTICS_API_MIGRATION
 import com.android.systemui.plugins.ActivityStarter
 import com.android.systemui.statusbar.VibratorHelper
 import com.android.systemui.statusbar.policy.KeyguardStateController
@@ -57,6 +59,7 @@
         private val controlsMetricsLogger: ControlsMetricsLogger,
         private val vibrator: VibratorHelper,
         private val controlsSettingsRepository: ControlsSettingsRepository,
+        private val featureFlags: FeatureFlags,
 ) : ControlActionCoordinator {
     private var dialog: Dialog? = null
     private var pendingAction: Action? = null
@@ -119,11 +122,17 @@
         )
     }
 
-    override fun drag(isEdge: Boolean) {
-        if (isEdge) {
-            vibrate(Vibrations.rangeEdgeEffect)
+    override fun drag(cvh: ControlViewHolder, isEdge: Boolean) {
+        if (featureFlags.isEnabled(ONE_WAY_HAPTICS_API_MIGRATION)) {
+            val constant =
+                if (isEdge)
+                    HapticFeedbackConstants.SEGMENT_TICK
+                else
+                    HapticFeedbackConstants.SEGMENT_FREQUENT_TICK
+            vibrator.performHapticFeedback(cvh.layout, constant)
         } else {
-            vibrate(Vibrations.rangeMiddleEffect)
+            val effect = if (isEdge) Vibrations.rangeEdgeEffect else Vibrations.rangeMiddleEffect
+            vibrate(effect)
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/ToggleRangeBehavior.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/ToggleRangeBehavior.kt
index 1461135..c97825f 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/ui/ToggleRangeBehavior.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ToggleRangeBehavior.kt
@@ -235,7 +235,7 @@
         if (isDragging) {
             val isEdge = newLevel == MIN_LEVEL || newLevel == MAX_LEVEL
             if (clipLayer.level != newLevel) {
-                cvh.controlActionCoordinator.drag(isEdge)
+                cvh.controlActionCoordinator.drag(cvh, isEdge)
                 clipLayer.level = newLevel
             }
         } else if (newLevel != clipLayer.level) {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlActionCoordinatorImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlActionCoordinatorImplTest.kt
index 692d794..8416c46 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlActionCoordinatorImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlActionCoordinatorImplTest.kt
@@ -18,12 +18,14 @@
 
 import android.test.suitebuilder.annotation.SmallTest
 import android.testing.AndroidTestingRunner
+import android.view.HapticFeedbackConstants
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.broadcast.BroadcastSender
 import com.android.systemui.controls.ControlsMetricsLogger
 import com.android.systemui.controls.settings.ControlsSettingsDialogManager
 import com.android.systemui.controls.settings.FakeControlsSettingsRepository
-import com.android.systemui.flags.FeatureFlags
+import com.android.systemui.flags.FakeFeatureFlags
+import com.android.systemui.flags.Flags.ONE_WAY_HAPTICS_API_MIGRATION
 import com.android.systemui.plugins.ActivityStarter
 import com.android.systemui.statusbar.VibratorHelper
 import com.android.systemui.statusbar.policy.KeyguardStateController
@@ -33,6 +35,7 @@
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.mockito.Answers
+import org.mockito.ArgumentMatchers.eq
 import org.mockito.Mock
 import org.mockito.Mockito
 import org.mockito.Mockito.anyBoolean
@@ -68,8 +71,6 @@
     @Mock
     private lateinit var metricsLogger: ControlsMetricsLogger
     @Mock
-    private lateinit var featureFlags: FeatureFlags
-    @Mock
     private lateinit var controlsSettingsDialogManager: ControlsSettingsDialogManager
 
     companion object {
@@ -82,6 +83,8 @@
     private lateinit var action: ControlActionCoordinatorImpl.Action
     private lateinit var controlsSettingsRepository: FakeControlsSettingsRepository
 
+    private val featureFlags = FakeFeatureFlags()
+
     @Before
     fun setUp() {
         MockitoAnnotations.initMocks(this)
@@ -101,6 +104,7 @@
                 metricsLogger,
                 vibratorHelper,
                 controlsSettingsRepository,
+                featureFlags
         ))
         coordinator.activityContext = mContext
 
@@ -194,4 +198,50 @@
         verify(coordinator).bouncerOrRun(action)
         verify(action, never()).invoke()
     }
+
+    @Test
+    fun drag_isEdge_oneWayHapticsDisabled_usesVibrate() {
+        featureFlags.set(ONE_WAY_HAPTICS_API_MIGRATION, false)
+
+        coordinator.drag(cvh, true)
+
+        verify(vibratorHelper).vibrate(
+            Vibrations.rangeEdgeEffect
+        )
+    }
+
+    @Test
+    fun drag_isNotEdge_oneWayHapticsDisabled_usesVibrate() {
+        featureFlags.set(ONE_WAY_HAPTICS_API_MIGRATION, false)
+
+        coordinator.drag(cvh, false)
+
+        verify(vibratorHelper).vibrate(
+            Vibrations.rangeMiddleEffect
+        )
+    }
+
+    @Test
+    fun drag_isEdge_oneWayHapticsEnabled_usesPerformHapticFeedback() {
+        featureFlags.set(ONE_WAY_HAPTICS_API_MIGRATION, true)
+
+        coordinator.drag(cvh, true)
+
+        verify(vibratorHelper).performHapticFeedback(
+            any(),
+            eq(HapticFeedbackConstants.SEGMENT_TICK)
+        )
+    }
+
+    @Test
+    fun drag_isNotEdge_oneWayHapticsEnabled_usesPerformHapticFeedback() {
+        featureFlags.set(ONE_WAY_HAPTICS_API_MIGRATION, true)
+
+        coordinator.drag(cvh, false)
+
+        verify(vibratorHelper).performHapticFeedback(
+            any(),
+            eq(HapticFeedbackConstants.SEGMENT_FREQUENT_TICK)
+        )
+    }
 }