Using MSDL feedback in Keyguard authentication results.
MSDL tokens are played for success and failed authentication haptics.
This is the first usage of the MSDL language in SysUI.
Test: manual. Authenticating in the lock screen and verifying that MSDL
feedback is played when the flag is on.
Flag: com.android.systemui.msdl_feedback
Bug: 361165906
Bug: 352600066
Change-Id: Ifd3f9d6fa0310a3e3bc55f033703e8e983bdb529
diff --git a/packages/SystemUI/shared/Android.bp b/packages/SystemUI/shared/Android.bp
index 02d39a4..e68da09 100644
--- a/packages/SystemUI/shared/Android.bp
+++ b/packages/SystemUI/shared/Android.bp
@@ -70,6 +70,7 @@
"dagger2",
"jsr330",
"//frameworks/libs/systemui:com_android_systemui_shared_flags_lib",
+ "//frameworks/libs/systemui:msdl",
],
resource_dirs: [
"res",
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
index 0363a68..411cbd5 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
@@ -66,6 +66,7 @@
import com.android.systemui.flags.FeatureFlags;
import com.android.systemui.flags.FlagDependenciesModule;
import com.android.systemui.flags.FlagsModule;
+import com.android.systemui.haptics.msdl.dagger.MSDLModule;
import com.android.systemui.inputmethod.InputMethodModule;
import com.android.systemui.keyboard.KeyboardModule;
import com.android.systemui.keyevent.data.repository.KeyEventRepositoryModule;
@@ -231,6 +232,7 @@
MediaProjectionTaskSwitcherModule.class,
MediaRouterModule.class,
MotionToolModule.class,
+ MSDLModule.class,
PeopleHubModule.class,
PeopleModule.class,
PluginModule.class,
diff --git a/packages/SystemUI/src/com/android/systemui/haptics/msdl/dagger/MSDLModule.kt b/packages/SystemUI/src/com/android/systemui/haptics/msdl/dagger/MSDLModule.kt
new file mode 100644
index 0000000..5ea96b8
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/haptics/msdl/dagger/MSDLModule.kt
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.haptics.msdl.dagger
+
+import android.content.Context
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Application
+import com.google.android.msdl.domain.MSDLPlayer
+import dagger.Module
+import dagger.Provides
+
+@Module
+object MSDLModule {
+ @Provides
+ @SysUISingleton
+ fun provideMSDLPlayer(@Application context: Context): MSDLPlayer =
+ MSDLPlayer.createPlayer(context)
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewConfigurator.kt b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewConfigurator.kt
index ba533ce..362e016c 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewConfigurator.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewConfigurator.kt
@@ -72,6 +72,7 @@
import com.android.systemui.statusbar.VibratorHelper
import com.android.systemui.statusbar.phone.ScreenOffAnimationController
import com.android.systemui.temporarydisplay.chipbar.ChipbarCoordinator
+import com.google.android.msdl.domain.MSDLPlayer
import dagger.Lazy
import java.util.Optional
import javax.inject.Inject
@@ -112,6 +113,7 @@
private val keyguardViewMediator: KeyguardViewMediator,
private val deviceEntryUnlockTrackerViewBinder: Optional<DeviceEntryUnlockTrackerViewBinder>,
@Main private val mainDispatcher: CoroutineDispatcher,
+ private val msdlPlayer: MSDLPlayer,
) : CoreStartable {
private var rootViewHandle: DisposableHandle? = null
@@ -219,6 +221,7 @@
falsingManager,
keyguardViewMediator,
mainDispatcher,
+ msdlPlayer,
)
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardRootViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardRootViewBinder.kt
index 89851db..a7a8321 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardRootViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardRootViewBinder.kt
@@ -22,6 +22,7 @@
import android.annotation.SuppressLint
import android.graphics.Point
import android.graphics.Rect
+import android.os.VibrationAttributes
import android.util.Log
import android.view.HapticFeedbackConstants
import android.view.View
@@ -40,6 +41,7 @@
import com.android.app.tracing.coroutines.launch
import com.android.internal.jank.InteractionJankMonitor
import com.android.internal.jank.InteractionJankMonitor.CUJ_SCREEN_OFF_SHOW_AOD
+import com.android.systemui.Flags.msdlFeedback
import com.android.systemui.Flags.newAodTransition
import com.android.systemui.common.shared.model.Icon
import com.android.systemui.common.shared.model.Text
@@ -79,6 +81,9 @@
import com.android.systemui.util.ui.isAnimating
import com.android.systemui.util.ui.stopAnimating
import com.android.systemui.util.ui.value
+import com.google.android.msdl.data.model.MSDLToken
+import com.google.android.msdl.domain.InteractionProperties
+import com.google.android.msdl.domain.MSDLPlayer
import kotlin.math.min
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.DisposableHandle
@@ -112,6 +117,7 @@
falsingManager: FalsingManager?,
keyguardViewMediator: KeyguardViewMediator?,
mainImmediateDispatcher: CoroutineDispatcher,
+ msdlPlayer: MSDLPlayer?,
): DisposableHandle {
val disposables = DisposableHandles()
val childViews = mutableMapOf<Int, View>()
@@ -351,21 +357,43 @@
if (deviceEntryHapticsInteractor != null && vibratorHelper != null) {
launch {
deviceEntryHapticsInteractor.playSuccessHaptic.collect {
- vibratorHelper.performHapticFeedback(
- view,
- HapticFeedbackConstants.CONFIRM,
- HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING,
- )
+ if (msdlFeedback()) {
+ val properties =
+ object : InteractionProperties {
+ override val vibrationAttributes: VibrationAttributes =
+ VibrationAttributes.createForUsage(
+ VibrationAttributes.USAGE_HARDWARE_FEEDBACK
+ )
+ }
+ msdlPlayer?.playToken(MSDLToken.UNLOCK, properties)
+ } else {
+ vibratorHelper.performHapticFeedback(
+ view,
+ HapticFeedbackConstants.CONFIRM,
+ HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING,
+ )
+ }
}
}
launch {
deviceEntryHapticsInteractor.playErrorHaptic.collect {
- vibratorHelper.performHapticFeedback(
- view,
- HapticFeedbackConstants.REJECT,
- HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING,
- )
+ if (msdlFeedback()) {
+ val properties =
+ object : InteractionProperties {
+ override val vibrationAttributes: VibrationAttributes =
+ VibrationAttributes.createForUsage(
+ VibrationAttributes.USAGE_HARDWARE_FEEDBACK
+ )
+ }
+ msdlPlayer?.playToken(MSDLToken.FAILURE, properties)
+ } else {
+ vibratorHelper.performHapticFeedback(
+ view,
+ HapticFeedbackConstants.REJECT,
+ HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING,
+ )
+ }
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt
index 9ccfb50..f581a2e 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt
@@ -418,6 +418,7 @@
null, // falsing manager not required for preview mode
null, // keyguard view mediator is not required for preview mode
mainDispatcher,
+ null,
)
}
rootView.addView(
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/haptics/msdl/FakeMSDLPlayer.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/haptics/msdl/FakeMSDLPlayer.kt
new file mode 100644
index 0000000..5ad973a
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/haptics/msdl/FakeMSDLPlayer.kt
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.haptics.msdl
+
+import com.google.android.msdl.data.model.FeedbackLevel
+import com.google.android.msdl.data.model.MSDLToken
+import com.google.android.msdl.domain.InteractionProperties
+import com.google.android.msdl.domain.MSDLPlayer
+
+class FakeMSDLPlayer : MSDLPlayer {
+ var currentFeedbackLevel = FeedbackLevel.DEFAULT
+ var latestTokenPlayed: MSDLToken? = null
+ private set
+
+ var latestPropertiesPlayed: InteractionProperties? = null
+ private set
+
+ override fun getSystemFeedbackLevel(): FeedbackLevel = currentFeedbackLevel
+
+ override fun playToken(token: MSDLToken, properties: InteractionProperties?) {
+ latestTokenPlayed = token
+ latestPropertiesPlayed = properties
+ }
+}
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
new file mode 100644
index 0000000..f5a05b4
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/haptics/msdl/MSDLPlayerKosmos.kt
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.haptics.msdl
+
+import com.android.systemui.kosmos.Kosmos
+
+val Kosmos.msdlPlayer by Kosmos.Fixture { FakeMSDLPlayer() }