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 8029ba844850d..534832c0992d9 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 @@ interface ControlActionCoordinator { /** * 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 a7e9efd8ab038..00d95c02c172a 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.ControlsMetricsLogger 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 @@ class ControlActionCoordinatorImpl @Inject constructor( 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 @@ class ControlActionCoordinatorImpl @Inject constructor( ) } - 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 b2c95a63ad728..0d570d2dcc735 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 @@ class ToggleRangeBehavior : Behavior { 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 692d794f21f0a..8416c46a3f384 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 @@ package com.android.systemui.controls.ui 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.Before 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 @@ class ControlActionCoordinatorImplTest : SysuiTestCase() { @Mock private lateinit var metricsLogger: ControlsMetricsLogger @Mock - private lateinit var featureFlags: FeatureFlags - @Mock private lateinit var controlsSettingsDialogManager: ControlsSettingsDialogManager companion object { @@ -82,6 +83,8 @@ class ControlActionCoordinatorImplTest : SysuiTestCase() { 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 @@ class ControlActionCoordinatorImplTest : SysuiTestCase() { metricsLogger, vibratorHelper, controlsSettingsRepository, + featureFlags )) coordinator.activityContext = mContext @@ -194,4 +198,50 @@ class ControlActionCoordinatorImplTest : SysuiTestCase() { 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) + ) + } }