diff options
| author | 2024-09-05 10:59:33 -0700 | |
|---|---|---|
| committer | 2024-09-05 15:14:35 -0700 | |
| commit | 196ee120bb52838f9eac9ee4d7941d400b453d2f (patch) | |
| tree | 71d06ab55a94381c68b3cc5b5e74cb807bce72db | |
| parent | 7eedb2d013a93c64860c57d2ee25613d1be4f9df (diff) | |
Adding MSDL haptic feedback to flexiglass lockscreen interactions.
As a followup of ag/29008354, this change adds haptic feedback
compliant with the Multi-sensory Design Language to authentication CUJs
in flexiglass and the lockscreen scene.
Test: atest SceneContainerStartableTest
Flag: com.android.systemui.msdl_feedback
Bug: 352770621
Bug: 352768515
Bug: 352767358
Bug: 352766822
Bug: 352765846
Bug: 352764953
Change-Id: I8fa80e0be9868128cf1c120cda5943b06c058179
6 files changed, 232 insertions, 11 deletions
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt index ec79cc6ef5da..d1804608d130 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt @@ -21,6 +21,8 @@ package com.android.systemui.scene.domain.startable  import android.app.StatusBarManager  import android.hardware.face.FaceManager  import android.os.PowerManager +import android.platform.test.annotations.DisableFlags +import android.platform.test.annotations.EnableFlags  import android.view.Display  import androidx.test.ext.junit.runners.AndroidJUnit4  import androidx.test.filters.SmallTest @@ -28,6 +30,8 @@ import com.android.compose.animation.scene.ObservableTransitionState  import com.android.compose.animation.scene.SceneKey  import com.android.internal.logging.uiEventLoggerFake  import com.android.internal.policy.IKeyguardDismissCallback +import com.android.keyguard.AuthInteractionProperties +import com.android.systemui.Flags  import com.android.systemui.SysuiTestCase  import com.android.systemui.authentication.data.repository.fakeAuthenticationRepository  import com.android.systemui.authentication.shared.model.AuthenticationMethodModel @@ -48,6 +52,7 @@ import com.android.systemui.deviceentry.domain.interactor.deviceEntryInteractor  import com.android.systemui.deviceentry.shared.model.FailedFaceAuthenticationStatus  import com.android.systemui.deviceentry.shared.model.SuccessFaceAuthenticationStatus  import com.android.systemui.flags.EnableSceneContainer +import com.android.systemui.haptics.msdl.fakeMSDLPlayer  import com.android.systemui.haptics.vibratorHelper  import com.android.systemui.keyevent.data.repository.fakeKeyEventRepository  import com.android.systemui.keyguard.data.repository.biometricSettingsRepository @@ -95,6 +100,7 @@ import com.android.systemui.statusbar.policy.data.repository.fakeDeviceProvision  import com.android.systemui.statusbar.sysuiStatusBarStateController  import com.android.systemui.testKosmos  import com.android.systemui.util.mockito.mock +import com.google.android.msdl.data.model.MSDLToken  import com.google.common.truth.Truth.assertThat  import kotlinx.coroutines.ExperimentalCoroutinesApi  import kotlinx.coroutines.flow.MutableStateFlow @@ -137,6 +143,8 @@ class SceneContainerStartableTest : SysuiTestCase() {      private val powerInteractor = kosmos.powerInteractor      private val fakeTrustRepository = kosmos.fakeTrustRepository      private val uiEventLoggerFake = kosmos.uiEventLoggerFake +    private val msdlPlayer = kosmos.fakeMSDLPlayer +    private val authInteractionProperties = AuthInteractionProperties()      private lateinit var underTest: SceneContainerStartable @@ -654,6 +662,7 @@ class SceneContainerStartableTest : SysuiTestCase() {          }      @Test +    @DisableFlags(Flags.FLAG_MSDL_FEEDBACK)      fun playSuccessHaptics_onSuccessfulLockscreenAuth_udfps() =          testScope.runTest {              val currentSceneKey by collectLastValue(sceneInteractor.currentScene) @@ -680,6 +689,31 @@ class SceneContainerStartableTest : SysuiTestCase() {          }      @Test +    @EnableFlags(Flags.FLAG_MSDL_FEEDBACK) +    fun playSuccessMSDLHaptics_onSuccessfulLockscreenAuth_udfps() = +        testScope.runTest { +            val currentSceneKey by collectLastValue(sceneInteractor.currentScene) +            val playSuccessHaptic by +                collectLastValue(deviceEntryHapticsInteractor.playSuccessHaptic) + +            setupBiometricAuth(hasUdfps = true) +            assertThat(currentSceneKey).isEqualTo(Scenes.Lockscreen) +            assertThat(kosmos.deviceEntryInteractor.isDeviceEntered.value).isFalse() + +            underTest.start() +            unlockWithFingerprintAuth() + +            assertThat(playSuccessHaptic).isNotNull() +            assertThat(currentSceneKey).isEqualTo(Scenes.Lockscreen) +            assertThat(msdlPlayer.latestTokenPlayed).isEqualTo(MSDLToken.UNLOCK) +            assertThat(msdlPlayer.latestPropertiesPlayed).isEqualTo(authInteractionProperties) + +            updateFingerprintAuthStatus(isSuccess = true) +            assertThat(currentSceneKey).isEqualTo(Scenes.Gone) +        } + +    @Test +    @DisableFlags(Flags.FLAG_MSDL_FEEDBACK)      fun playSuccessHaptics_onSuccessfulLockscreenAuth_sfps() =          testScope.runTest {              val currentSceneKey by collectLastValue(sceneInteractor.currentScene) @@ -707,6 +741,32 @@ class SceneContainerStartableTest : SysuiTestCase() {          }      @Test +    @EnableFlags(Flags.FLAG_MSDL_FEEDBACK) +    fun playSuccessMSDLHaptics_onSuccessfulLockscreenAuth_sfps() = +        testScope.runTest { +            val currentSceneKey by collectLastValue(sceneInteractor.currentScene) +            val playSuccessHaptic by +                collectLastValue(deviceEntryHapticsInteractor.playSuccessHaptic) + +            setupBiometricAuth(hasSfps = true) +            assertThat(currentSceneKey).isEqualTo(Scenes.Lockscreen) +            assertThat(kosmos.deviceEntryInteractor.isDeviceEntered.value).isFalse() + +            underTest.start() +            allowHapticsOnSfps() +            unlockWithFingerprintAuth() + +            assertThat(playSuccessHaptic).isNotNull() +            assertThat(currentSceneKey).isEqualTo(Scenes.Lockscreen) +            assertThat(msdlPlayer.latestTokenPlayed).isEqualTo(MSDLToken.UNLOCK) +            assertThat(msdlPlayer.latestPropertiesPlayed).isEqualTo(authInteractionProperties) + +            updateFingerprintAuthStatus(isSuccess = true) +            assertThat(currentSceneKey).isEqualTo(Scenes.Gone) +        } + +    @Test +    @DisableFlags(Flags.FLAG_MSDL_FEEDBACK)      fun playErrorHaptics_onFailedLockscreenAuth_udfps() =          testScope.runTest {              val currentSceneKey by collectLastValue(sceneInteractor.currentScene) @@ -727,6 +787,27 @@ class SceneContainerStartableTest : SysuiTestCase() {          }      @Test +    @EnableFlags(Flags.FLAG_MSDL_FEEDBACK) +    fun playMSDLErrorHaptics_onFailedLockscreenAuth_udfps() = +        testScope.runTest { +            val currentSceneKey by collectLastValue(sceneInteractor.currentScene) +            val playErrorHaptic by collectLastValue(deviceEntryHapticsInteractor.playErrorHaptic) + +            setupBiometricAuth(hasUdfps = true) +            assertThat(currentSceneKey).isEqualTo(Scenes.Lockscreen) +            assertThat(kosmos.deviceEntryInteractor.isDeviceEntered.value).isFalse() + +            underTest.start() +            updateFingerprintAuthStatus(isSuccess = false) + +            assertThat(playErrorHaptic).isNotNull() +            assertThat(currentSceneKey).isEqualTo(Scenes.Lockscreen) +            assertThat(msdlPlayer.latestTokenPlayed).isEqualTo(MSDLToken.FAILURE) +            assertThat(msdlPlayer.latestPropertiesPlayed).isEqualTo(authInteractionProperties) +        } + +    @Test +    @DisableFlags(Flags.FLAG_MSDL_FEEDBACK)      fun playErrorHaptics_onFailedLockscreenAuth_sfps() =          testScope.runTest {              val currentSceneKey by collectLastValue(sceneInteractor.currentScene) @@ -747,6 +828,27 @@ class SceneContainerStartableTest : SysuiTestCase() {          }      @Test +    @EnableFlags(Flags.FLAG_MSDL_FEEDBACK) +    fun playMSDLErrorHaptics_onFailedLockscreenAuth_sfps() = +        testScope.runTest { +            val currentSceneKey by collectLastValue(sceneInteractor.currentScene) +            val playErrorHaptic by collectLastValue(deviceEntryHapticsInteractor.playErrorHaptic) + +            setupBiometricAuth(hasSfps = true) +            assertThat(currentSceneKey).isEqualTo(Scenes.Lockscreen) +            assertThat(kosmos.deviceEntryInteractor.isDeviceEntered.value).isFalse() + +            underTest.start() +            updateFingerprintAuthStatus(isSuccess = false) + +            assertThat(playErrorHaptic).isNotNull() +            assertThat(currentSceneKey).isEqualTo(Scenes.Lockscreen) +            assertThat(msdlPlayer.latestTokenPlayed).isEqualTo(MSDLToken.FAILURE) +            assertThat(msdlPlayer.latestPropertiesPlayed).isEqualTo(authInteractionProperties) +        } + +    @Test +    @DisableFlags(Flags.FLAG_MSDL_FEEDBACK)      fun skipsSuccessHaptics_whenPowerButtonDown_sfps() =          testScope.runTest {              val currentSceneKey by collectLastValue(sceneInteractor.currentScene) @@ -774,6 +876,32 @@ class SceneContainerStartableTest : SysuiTestCase() {          }      @Test +    @EnableFlags(Flags.FLAG_MSDL_FEEDBACK) +    fun skipsMSDLSuccessHaptics_whenPowerButtonDown_sfps() = +        testScope.runTest { +            val currentSceneKey by collectLastValue(sceneInteractor.currentScene) +            val playSuccessHaptic by +                collectLastValue(deviceEntryHapticsInteractor.playSuccessHaptic) + +            setupBiometricAuth(hasSfps = true) +            assertThat(currentSceneKey).isEqualTo(Scenes.Lockscreen) +            assertThat(kosmos.deviceEntryInteractor.isDeviceEntered.value).isFalse() + +            underTest.start() +            allowHapticsOnSfps(isPowerButtonDown = true) +            unlockWithFingerprintAuth() + +            assertThat(playSuccessHaptic).isNull() +            assertThat(currentSceneKey).isEqualTo(Scenes.Lockscreen) +            assertThat(msdlPlayer.latestTokenPlayed).isNull() +            assertThat(msdlPlayer.latestPropertiesPlayed).isNull() + +            updateFingerprintAuthStatus(isSuccess = true) +            assertThat(currentSceneKey).isEqualTo(Scenes.Gone) +        } + +    @Test +    @DisableFlags(Flags.FLAG_MSDL_FEEDBACK)      fun skipsSuccessHaptics_whenPowerButtonRecentlyPressed_sfps() =          testScope.runTest {              val currentSceneKey by collectLastValue(sceneInteractor.currentScene) @@ -801,6 +929,32 @@ class SceneContainerStartableTest : SysuiTestCase() {          }      @Test +    @EnableFlags(Flags.FLAG_MSDL_FEEDBACK) +    fun skipsMSDLSuccessHaptics_whenPowerButtonRecentlyPressed_sfps() = +        testScope.runTest { +            val currentSceneKey by collectLastValue(sceneInteractor.currentScene) +            val playSuccessHaptic by +                collectLastValue(deviceEntryHapticsInteractor.playSuccessHaptic) + +            setupBiometricAuth(hasSfps = true) +            assertThat(currentSceneKey).isEqualTo(Scenes.Lockscreen) +            assertThat(kosmos.deviceEntryInteractor.isDeviceEntered.value).isFalse() + +            underTest.start() +            allowHapticsOnSfps(lastPowerPress = 50) +            unlockWithFingerprintAuth() + +            assertThat(playSuccessHaptic).isNull() +            assertThat(currentSceneKey).isEqualTo(Scenes.Lockscreen) +            assertThat(msdlPlayer.latestTokenPlayed).isNull() +            assertThat(msdlPlayer.latestPropertiesPlayed).isNull() + +            updateFingerprintAuthStatus(isSuccess = true) +            assertThat(currentSceneKey).isEqualTo(Scenes.Gone) +        } + +    @Test +    @DisableFlags(Flags.FLAG_MSDL_FEEDBACK)      fun skipsErrorHaptics_whenPowerButtonDown_sfps() =          testScope.runTest {              val currentSceneKey by collectLastValue(sceneInteractor.currentScene) @@ -822,6 +976,28 @@ class SceneContainerStartableTest : SysuiTestCase() {          }      @Test +    @EnableFlags(Flags.FLAG_MSDL_FEEDBACK) +    fun skipsMSDLErrorHaptics_whenPowerButtonDown_sfps() = +        testScope.runTest { +            val currentSceneKey by collectLastValue(sceneInteractor.currentScene) +            val playErrorHaptic by collectLastValue(deviceEntryHapticsInteractor.playErrorHaptic) + +            setupBiometricAuth(hasSfps = true) +            assertThat(currentSceneKey).isEqualTo(Scenes.Lockscreen) +            assertThat(kosmos.deviceEntryInteractor.isDeviceEntered.value).isFalse() + +            underTest.start() +            kosmos.fakeKeyEventRepository.setPowerButtonDown(true) +            updateFingerprintAuthStatus(isSuccess = false) + +            assertThat(playErrorHaptic).isNull() +            assertThat(currentSceneKey).isEqualTo(Scenes.Lockscreen) +            assertThat(msdlPlayer.latestTokenPlayed).isNull() +            assertThat(msdlPlayer.latestPropertiesPlayed).isNull() +        } + +    @Test +    @DisableFlags(Flags.FLAG_MSDL_FEEDBACK)      fun skipsFaceErrorHaptics_nonSfps_coEx() =          testScope.runTest {              val currentSceneKey by collectLastValue(sceneInteractor.currentScene) @@ -842,6 +1018,26 @@ class SceneContainerStartableTest : SysuiTestCase() {          }      @Test +    @EnableFlags(Flags.FLAG_MSDL_FEEDBACK) +    fun skipsMSDLFaceErrorHaptics_nonSfps_coEx() = +        testScope.runTest { +            val currentSceneKey by collectLastValue(sceneInteractor.currentScene) +            val playErrorHaptic by collectLastValue(deviceEntryHapticsInteractor.playErrorHaptic) + +            setupBiometricAuth(hasUdfps = true, hasFace = true) +            assertThat(currentSceneKey).isEqualTo(Scenes.Lockscreen) +            assertThat(kosmos.deviceEntryInteractor.isDeviceEntered.value).isFalse() + +            underTest.start() +            updateFaceAuthStatus(isSuccess = false) + +            assertThat(playErrorHaptic).isNull() +            assertThat(currentSceneKey).isEqualTo(Scenes.Lockscreen) +            assertThat(msdlPlayer.latestTokenPlayed).isNull() +            assertThat(msdlPlayer.latestPropertiesPlayed).isNull() +        } + +    @Test      fun hydrateSystemUiState() =          testScope.runTest {              val transitionStateFlow = prepareState() diff --git a/packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartable.kt b/packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartable.kt index e251c9edb57f..98907b037d85 100644 --- a/packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartable.kt +++ b/packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartable.kt @@ -22,7 +22,9 @@ import android.app.StatusBarManager  import com.android.compose.animation.scene.ObservableTransitionState  import com.android.compose.animation.scene.SceneKey  import com.android.internal.logging.UiEventLogger +import com.android.keyguard.AuthInteractionProperties  import com.android.systemui.CoreStartable +import com.android.systemui.Flags  import com.android.systemui.authentication.domain.interactor.AuthenticationInteractor  import com.android.systemui.authentication.shared.model.AuthenticationMethodModel  import com.android.systemui.bouncer.domain.interactor.AlternateBouncerInteractor @@ -73,6 +75,8 @@ import com.android.systemui.util.kotlin.pairwise  import com.android.systemui.util.kotlin.sample  import com.android.systemui.util.printSection  import com.android.systemui.util.println +import com.google.android.msdl.data.model.MSDLToken +import com.google.android.msdl.domain.MSDLPlayer  import dagger.Lazy  import java.io.PrintWriter  import java.util.Optional @@ -139,10 +143,13 @@ constructor(      private val statusBarStateController: SysuiStatusBarStateController,      private val alternateBouncerInteractor: AlternateBouncerInteractor,      private val vibratorHelper: VibratorHelper, +    private val msdlPlayer: MSDLPlayer,  ) : CoreStartable {      private val centralSurfaces: CentralSurfaces?          get() = centralSurfacesOptLazy.get().getOrNull() +    private val authInteractionProperties = AuthInteractionProperties() +      override fun start() {          if (SceneContainerFlag.isEnabled) {              sceneLogger.logFrameworkEnabled(isEnabled = true) @@ -541,9 +548,16 @@ constructor(                              deviceEntryHapticsInteractor.playSuccessHaptic                                  .sample(sceneInteractor.currentScene)                                  .collect { currentScene -> -                                    vibratorHelper.vibrateAuthSuccess( -                                        "$TAG, $currentScene device-entry::success" -                                    ) +                                    if (Flags.msdlFeedback()) { +                                        msdlPlayer.playToken( +                                            MSDLToken.UNLOCK, +                                            authInteractionProperties, +                                        ) +                                    } else { +                                        vibratorHelper.vibrateAuthSuccess( +                                            "$TAG, $currentScene device-entry::success" +                                        ) +                                    }                                  }                          } @@ -551,9 +565,16 @@ constructor(                              deviceEntryHapticsInteractor.playErrorHaptic                                  .sample(sceneInteractor.currentScene)                                  .collect { currentScene -> -                                    vibratorHelper.vibrateAuthError( -                                        "$TAG, $currentScene device-entry::error" -                                    ) +                                    if (Flags.msdlFeedback()) { +                                        msdlPlayer.playToken( +                                            MSDLToken.FAILURE, +                                            authInteractionProperties, +                                        ) +                                    } else { +                                        vibratorHelper.vibrateAuthError( +                                            "$TAG, $currentScene device-entry::error" +                                        ) +                                    }                                  }                          }                      } diff --git a/packages/SystemUI/tests/src/com/android/keyguard/EmergencyButtonControllerTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/EmergencyButtonControllerTest.kt index 43a780357027..c42e25b20e0d 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/EmergencyButtonControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/keyguard/EmergencyButtonControllerTest.kt @@ -29,7 +29,7 @@ import com.android.internal.logging.MetricsLogger  import com.android.internal.widget.LockPatternUtils  import com.android.systemui.Flags  import com.android.systemui.SysuiTestCase -import com.android.systemui.haptics.msdl.FakeMSDLPlayer +import com.android.systemui.haptics.msdl.fakeMSDLPlayer  import com.android.systemui.haptics.msdl.msdlPlayer  import com.android.systemui.shade.ShadeController  import com.android.systemui.statusbar.policy.ConfigurationController @@ -72,7 +72,7 @@ class EmergencyButtonControllerTest : SysuiTestCase() {      val mainExecutor = FakeExecutor(fakeSystemClock)      val backgroundExecutor = FakeExecutor(fakeSystemClock)      private val kosmos = testKosmos() -    private val msdlPlayer: FakeMSDLPlayer = kosmos.msdlPlayer +    private val msdlPlayer = kosmos.fakeMSDLPlayer      lateinit var underTest: EmergencyButtonController diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/haptics/msdl/MSDLPlayerKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/haptics/msdl/MSDLPlayerKosmos.kt index f5a05b44d2cf..4f5c32abd2f8 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/haptics/msdl/MSDLPlayerKosmos.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/haptics/msdl/MSDLPlayerKosmos.kt @@ -17,5 +17,7 @@  package com.android.systemui.haptics.msdl  import com.android.systemui.kosmos.Kosmos +import com.google.android.msdl.domain.MSDLPlayer -val Kosmos.msdlPlayer by Kosmos.Fixture { FakeMSDLPlayer() } +var Kosmos.msdlPlayer: MSDLPlayer by Kosmos.Fixture { fakeMSDLPlayer } +val Kosmos.fakeMSDLPlayer by Kosmos.Fixture { FakeMSDLPlayer() } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/kosmos/KosmosJavaAdapter.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/kosmos/KosmosJavaAdapter.kt index 851a378f3165..457bd284ea8d 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/kosmos/KosmosJavaAdapter.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/kosmos/KosmosJavaAdapter.kt @@ -36,7 +36,7 @@ import com.android.systemui.deviceentry.domain.interactor.deviceEntryInteractor  import com.android.systemui.deviceentry.domain.interactor.deviceEntryUdfpsInteractor  import com.android.systemui.deviceentry.domain.interactor.deviceUnlockedInteractor  import com.android.systemui.globalactions.domain.interactor.globalActionsInteractor -import com.android.systemui.haptics.msdl.msdlPlayer +import com.android.systemui.haptics.msdl.fakeMSDLPlayer  import com.android.systemui.haptics.qs.qsLongPressEffect  import com.android.systemui.jank.interactionJankMonitor  import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository @@ -155,5 +155,5 @@ class KosmosJavaAdapter() {      val scrimController by lazy { kosmos.scrimController }      val scrimStartable by lazy { kosmos.scrimStartable }      val sceneContainerOcclusionInteractor by lazy { kosmos.sceneContainerOcclusionInteractor } -    val msdlPlayer by lazy { kosmos.msdlPlayer } +    val msdlPlayer by lazy { kosmos.fakeMSDLPlayer }  } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/scene/domain/startable/SceneContainerStartableKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/scene/domain/startable/SceneContainerStartableKosmos.kt index b612a8b5893a..9a5698cfb8ca 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/scene/domain/startable/SceneContainerStartableKosmos.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/scene/domain/startable/SceneContainerStartableKosmos.kt @@ -27,6 +27,7 @@ import com.android.systemui.deviceentry.domain.interactor.deviceEntryFaceAuthInt  import com.android.systemui.deviceentry.domain.interactor.deviceEntryHapticsInteractor  import com.android.systemui.deviceentry.domain.interactor.deviceEntryInteractor  import com.android.systemui.deviceentry.domain.interactor.deviceUnlockedInteractor +import com.android.systemui.haptics.msdl.msdlPlayer  import com.android.systemui.haptics.vibratorHelper  import com.android.systemui.keyguard.dismissCallbackRegistry  import com.android.systemui.keyguard.domain.interactor.keyguardEnabledInteractor @@ -86,5 +87,6 @@ val Kosmos.sceneContainerStartable by Fixture {          statusBarStateController = sysuiStatusBarStateController,          alternateBouncerInteractor = alternateBouncerInteractor,          vibratorHelper = vibratorHelper, +        msdlPlayer = msdlPlayer,      )  }  |