Loading packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/AuthControllerTest.java +5 −1 Original line number Diff line number Diff line Loading @@ -97,6 +97,8 @@ import com.android.systemui.util.concurrency.FakeExecution; import com.android.systemui.util.concurrency.FakeExecutor; import com.android.systemui.util.time.FakeSystemClock; import com.google.android.msdl.domain.MSDLPlayer; import dagger.Lazy; import org.junit.Before; Loading Loading @@ -185,6 +187,8 @@ public class AuthControllerTest extends SysuiTestCase { private Resources mResources; @Mock private VibratorHelper mVibratorHelper; @Mock private MSDLPlayer mMSDLPlayer; private TestableContext mContextSpy; private Execution mExecution; Loading Loading @@ -1066,7 +1070,7 @@ public class AuthControllerTest extends SysuiTestCase { () -> mLogContextInteractor, () -> mPromptSelectionInteractor, () -> mCredentialViewModel, () -> mPromptViewModel, mInteractionJankMonitor, mHandler, mBackgroundExecutor, mUdfpsUtils, mVibratorHelper, mLazyViewCapture); mLazyViewCapture, mMSDLPlayer); } @Override Loading packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java +8 −2 Original line number Diff line number Diff line Loading @@ -78,6 +78,8 @@ import com.android.systemui.res.R; import com.android.systemui.statusbar.VibratorHelper; import com.android.systemui.util.concurrency.DelayableExecutor; import com.google.android.msdl.domain.MSDLPlayer; import kotlin.Lazy; import kotlinx.coroutines.CoroutineScope; Loading Loading @@ -157,6 +159,8 @@ public class AuthContainerView extends LinearLayout private final @Background DelayableExecutor mBackgroundExecutor; private final MSDLPlayer mMSDLPlayer; // Non-null only if the dialog is in the act of dismissing and has not sent the reason yet. @Nullable @AuthDialogCallback.DismissedReason private Integer mPendingCallbackReason; // HAT received from LockSettingsService when credential is verified. Loading Loading @@ -292,7 +296,8 @@ public class AuthContainerView extends LinearLayout @NonNull Provider<CredentialViewModel> credentialViewModelProvider, @NonNull @Background DelayableExecutor bgExecutor, @NonNull VibratorHelper vibratorHelper, Lazy<ViewCapture> lazyViewCapture) { Lazy<ViewCapture> lazyViewCapture, @NonNull MSDLPlayer msdlPlayer) { super(config.mContext); mConfig = config; Loading @@ -309,6 +314,7 @@ public class AuthContainerView extends LinearLayout .getDimension(R.dimen.biometric_dialog_animation_translation_offset); mLinearOutSlowIn = Interpolators.LINEAR_OUT_SLOW_IN; mBiometricCallback = new BiometricCallback(); mMSDLPlayer = msdlPlayer; final BiometricModalities biometricModalities = new BiometricModalities( Utils.findFirstSensorProperties(fpProps, mConfig.mSensorIds), Loading Loading @@ -379,7 +385,7 @@ public class AuthContainerView extends LinearLayout getJankListener(mLayout, TRANSIT, BiometricViewSizeBinder.ANIMATE_MEDIUM_TO_LARGE_DURATION_MS), mBackgroundView, mBiometricCallback, mApplicationCoroutineScope, vibratorHelper); vibratorHelper, mMSDLPlayer); } @VisibleForTesting Loading packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java +7 −2 Original line number Diff line number Diff line Loading @@ -89,6 +89,8 @@ import com.android.systemui.statusbar.policy.ConfigurationController; import com.android.systemui.util.concurrency.DelayableExecutor; import com.android.systemui.util.concurrency.Execution; import com.google.android.msdl.domain.MSDLPlayer; import dagger.Lazy; import kotlin.Unit; Loading Loading @@ -183,6 +185,7 @@ public class AuthController implements private final @Background DelayableExecutor mBackgroundExecutor; private final DisplayInfo mCachedDisplayInfo = new DisplayInfo(); @NonNull private final VibratorHelper mVibratorHelper; @NonNull private final MSDLPlayer mMSDLPlayer; private final kotlin.Lazy<ViewCapture> mLazyViewCapture; Loading Loading @@ -742,7 +745,8 @@ public class AuthController implements @Background DelayableExecutor bgExecutor, @NonNull UdfpsUtils udfpsUtils, @NonNull VibratorHelper vibratorHelper, Lazy<ViewCapture> daggerLazyViewCapture) { Lazy<ViewCapture> daggerLazyViewCapture, @NonNull MSDLPlayer msdlPlayer) { mContext = context; mExecution = execution; mUserManager = userManager; Loading @@ -764,6 +768,7 @@ public class AuthController implements mUdfpsUtils = udfpsUtils; mApplicationCoroutineScope = applicationCoroutineScope; mVibratorHelper = vibratorHelper; mMSDLPlayer = msdlPlayer; mLogContextInteractor = logContextInteractor; mPromptSelectorInteractor = promptSelectorInteractorProvider; Loading Loading @@ -1327,7 +1332,7 @@ public class AuthController implements wakefulnessLifecycle, userManager, lockPatternUtils, mInteractionJankMonitor, mPromptSelectorInteractor, viewModel, mCredentialViewModelProvider, bgExecutor, mVibratorHelper, mLazyViewCapture); mLazyViewCapture, mMSDLPlayer); } @Override Loading packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewBinder.kt +21 −14 Original line number Diff line number Diff line Loading @@ -25,7 +25,6 @@ import android.hardware.biometrics.BiometricPrompt import android.hardware.biometrics.Flags import android.hardware.face.FaceManager import android.util.Log import android.view.HapticFeedbackConstants import android.view.MotionEvent import android.view.View import android.view.View.IMPORTANT_FOR_ACCESSIBILITY_NO Loading Loading @@ -59,6 +58,7 @@ import com.android.systemui.common.ui.view.onTouchListener import com.android.systemui.lifecycle.repeatWhenAttached import com.android.systemui.res.R import com.android.systemui.statusbar.VibratorHelper import com.google.android.msdl.domain.MSDLPlayer import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.delay import kotlinx.coroutines.flow.combine Loading @@ -83,6 +83,7 @@ object BiometricViewBinder { legacyCallback: Spaghetti.Callback, applicationScope: CoroutineScope, vibratorHelper: VibratorHelper, msdlPlayer: MSDLPlayer, ): Spaghetti { val accessibilityManager = view.context.getSystemService(AccessibilityManager::class.java)!! Loading Loading @@ -434,21 +435,27 @@ object BiometricViewBinder { // Play haptics launch { viewModel.hapticsToPlay.collect { haptics -> if (haptics.hapticFeedbackConstant != HapticFeedbackConstants.NO_HAPTICS) { when (haptics) { is PromptViewModel.HapticsToPlay.HapticConstant -> { if (haptics.flag != null) { vibratorHelper.performHapticFeedback( view, haptics.hapticFeedbackConstant, haptics.constant, haptics.flag, ) } else { vibratorHelper.performHapticFeedback( view, haptics.hapticFeedbackConstant, haptics.constant, ) } viewModel.clearHaptics() } is PromptViewModel.HapticsToPlay.MSDL -> { msdlPlayer.playToken(haptics.token, haptics.properties) } is PromptViewModel.HapticsToPlay.None -> {} } viewModel.clearHaptics() } } Loading packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModel.kt +46 −21 Original line number Diff line number Diff line Loading @@ -35,7 +35,9 @@ import android.util.Log import android.util.RotationUtils import android.view.HapticFeedbackConstants import android.view.MotionEvent import com.android.keyguard.AuthInteractionProperties import com.android.launcher3.icons.IconProvider import com.android.systemui.Flags.msdlFeedback import com.android.systemui.biometrics.UdfpsUtils import com.android.systemui.biometrics.Utils import com.android.systemui.biometrics.Utils.isSystem Loading @@ -53,6 +55,8 @@ import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.keyguard.shared.model.AcquiredFingerprintAuthenticationStatus import com.android.systemui.res.R import com.android.systemui.util.kotlin.combine import com.google.android.msdl.data.model.MSDLToken import com.google.android.msdl.domain.InteractionProperties import javax.inject.Inject import kotlinx.coroutines.Job import kotlinx.coroutines.coroutineScope Loading Loading @@ -245,8 +249,9 @@ constructor( private val _forceLargeSize = MutableStateFlow(false) private val _forceMediumSize = MutableStateFlow(false) private val _hapticsToPlay = MutableStateFlow(HapticsToPlay(HapticFeedbackConstants.NO_HAPTICS, /* flag= */ null)) private val authInteractionProperties = AuthInteractionProperties() private val _hapticsToPlay: MutableStateFlow<HapticsToPlay> = MutableStateFlow(HapticsToPlay.None) /** Event fired to the view indicating a [HapticsToPlay] */ val hapticsToPlay = _hapticsToPlay.asStateFlow() Loading Loading @@ -939,26 +944,52 @@ constructor( } private fun vibrateOnSuccess() { _hapticsToPlay.value = HapticsToPlay( val haptics = if (msdlFeedback()) { HapticsToPlay.MSDL(MSDLToken.UNLOCK, authInteractionProperties) } else { HapticsToPlay.HapticConstant( HapticFeedbackConstants.BIOMETRIC_CONFIRM, null, flag = null, ) } _hapticsToPlay.value = haptics } private fun vibrateOnError() { _hapticsToPlay.value = HapticsToPlay( val haptics = if (msdlFeedback()) { HapticsToPlay.MSDL(MSDLToken.FAILURE, authInteractionProperties) } else { HapticsToPlay.HapticConstant( HapticFeedbackConstants.BIOMETRIC_REJECT, null, flag = null, ) } _hapticsToPlay.value = haptics } /** Clears the [hapticsToPlay] variable by setting its constant to the NO_HAPTICS default. */ fun clearHaptics() { _hapticsToPlay.update { previous -> HapticsToPlay(HapticFeedbackConstants.NO_HAPTICS, previous.flag) _hapticsToPlay.update { HapticsToPlay.None } } /** The state of haptic feedback to play. */ sealed interface HapticsToPlay { /** * Haptics using [HapticFeedbackConstants]. It is composed by a [HapticFeedbackConstants] * and a [HapticFeedbackConstants] flag. */ data class HapticConstant(val constant: Int, val flag: Int?) : HapticsToPlay /** * Haptics using MSDL feedback. It is composed by a [MSDLToken] and optional * [InteractionProperties] */ data class MSDL(val token: MSDLToken, val properties: InteractionProperties?) : HapticsToPlay data object None : HapticsToPlay } companion object { Loading Loading @@ -1095,9 +1126,3 @@ enum class FingerprintStartMode { val isStarted: Boolean get() = this == Normal || this == Delayed } /** * The state of haptic feedback to play. It is composed by a [HapticFeedbackConstants] and a * [HapticFeedbackConstants] flag. */ data class HapticsToPlay(val hapticFeedbackConstant: Int, val flag: Int?) Loading
packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/AuthControllerTest.java +5 −1 Original line number Diff line number Diff line Loading @@ -97,6 +97,8 @@ import com.android.systemui.util.concurrency.FakeExecution; import com.android.systemui.util.concurrency.FakeExecutor; import com.android.systemui.util.time.FakeSystemClock; import com.google.android.msdl.domain.MSDLPlayer; import dagger.Lazy; import org.junit.Before; Loading Loading @@ -185,6 +187,8 @@ public class AuthControllerTest extends SysuiTestCase { private Resources mResources; @Mock private VibratorHelper mVibratorHelper; @Mock private MSDLPlayer mMSDLPlayer; private TestableContext mContextSpy; private Execution mExecution; Loading Loading @@ -1066,7 +1070,7 @@ public class AuthControllerTest extends SysuiTestCase { () -> mLogContextInteractor, () -> mPromptSelectionInteractor, () -> mCredentialViewModel, () -> mPromptViewModel, mInteractionJankMonitor, mHandler, mBackgroundExecutor, mUdfpsUtils, mVibratorHelper, mLazyViewCapture); mLazyViewCapture, mMSDLPlayer); } @Override Loading
packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java +8 −2 Original line number Diff line number Diff line Loading @@ -78,6 +78,8 @@ import com.android.systemui.res.R; import com.android.systemui.statusbar.VibratorHelper; import com.android.systemui.util.concurrency.DelayableExecutor; import com.google.android.msdl.domain.MSDLPlayer; import kotlin.Lazy; import kotlinx.coroutines.CoroutineScope; Loading Loading @@ -157,6 +159,8 @@ public class AuthContainerView extends LinearLayout private final @Background DelayableExecutor mBackgroundExecutor; private final MSDLPlayer mMSDLPlayer; // Non-null only if the dialog is in the act of dismissing and has not sent the reason yet. @Nullable @AuthDialogCallback.DismissedReason private Integer mPendingCallbackReason; // HAT received from LockSettingsService when credential is verified. Loading Loading @@ -292,7 +296,8 @@ public class AuthContainerView extends LinearLayout @NonNull Provider<CredentialViewModel> credentialViewModelProvider, @NonNull @Background DelayableExecutor bgExecutor, @NonNull VibratorHelper vibratorHelper, Lazy<ViewCapture> lazyViewCapture) { Lazy<ViewCapture> lazyViewCapture, @NonNull MSDLPlayer msdlPlayer) { super(config.mContext); mConfig = config; Loading @@ -309,6 +314,7 @@ public class AuthContainerView extends LinearLayout .getDimension(R.dimen.biometric_dialog_animation_translation_offset); mLinearOutSlowIn = Interpolators.LINEAR_OUT_SLOW_IN; mBiometricCallback = new BiometricCallback(); mMSDLPlayer = msdlPlayer; final BiometricModalities biometricModalities = new BiometricModalities( Utils.findFirstSensorProperties(fpProps, mConfig.mSensorIds), Loading Loading @@ -379,7 +385,7 @@ public class AuthContainerView extends LinearLayout getJankListener(mLayout, TRANSIT, BiometricViewSizeBinder.ANIMATE_MEDIUM_TO_LARGE_DURATION_MS), mBackgroundView, mBiometricCallback, mApplicationCoroutineScope, vibratorHelper); vibratorHelper, mMSDLPlayer); } @VisibleForTesting Loading
packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java +7 −2 Original line number Diff line number Diff line Loading @@ -89,6 +89,8 @@ import com.android.systemui.statusbar.policy.ConfigurationController; import com.android.systemui.util.concurrency.DelayableExecutor; import com.android.systemui.util.concurrency.Execution; import com.google.android.msdl.domain.MSDLPlayer; import dagger.Lazy; import kotlin.Unit; Loading Loading @@ -183,6 +185,7 @@ public class AuthController implements private final @Background DelayableExecutor mBackgroundExecutor; private final DisplayInfo mCachedDisplayInfo = new DisplayInfo(); @NonNull private final VibratorHelper mVibratorHelper; @NonNull private final MSDLPlayer mMSDLPlayer; private final kotlin.Lazy<ViewCapture> mLazyViewCapture; Loading Loading @@ -742,7 +745,8 @@ public class AuthController implements @Background DelayableExecutor bgExecutor, @NonNull UdfpsUtils udfpsUtils, @NonNull VibratorHelper vibratorHelper, Lazy<ViewCapture> daggerLazyViewCapture) { Lazy<ViewCapture> daggerLazyViewCapture, @NonNull MSDLPlayer msdlPlayer) { mContext = context; mExecution = execution; mUserManager = userManager; Loading @@ -764,6 +768,7 @@ public class AuthController implements mUdfpsUtils = udfpsUtils; mApplicationCoroutineScope = applicationCoroutineScope; mVibratorHelper = vibratorHelper; mMSDLPlayer = msdlPlayer; mLogContextInteractor = logContextInteractor; mPromptSelectorInteractor = promptSelectorInteractorProvider; Loading Loading @@ -1327,7 +1332,7 @@ public class AuthController implements wakefulnessLifecycle, userManager, lockPatternUtils, mInteractionJankMonitor, mPromptSelectorInteractor, viewModel, mCredentialViewModelProvider, bgExecutor, mVibratorHelper, mLazyViewCapture); mLazyViewCapture, mMSDLPlayer); } @Override Loading
packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewBinder.kt +21 −14 Original line number Diff line number Diff line Loading @@ -25,7 +25,6 @@ import android.hardware.biometrics.BiometricPrompt import android.hardware.biometrics.Flags import android.hardware.face.FaceManager import android.util.Log import android.view.HapticFeedbackConstants import android.view.MotionEvent import android.view.View import android.view.View.IMPORTANT_FOR_ACCESSIBILITY_NO Loading Loading @@ -59,6 +58,7 @@ import com.android.systemui.common.ui.view.onTouchListener import com.android.systemui.lifecycle.repeatWhenAttached import com.android.systemui.res.R import com.android.systemui.statusbar.VibratorHelper import com.google.android.msdl.domain.MSDLPlayer import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.delay import kotlinx.coroutines.flow.combine Loading @@ -83,6 +83,7 @@ object BiometricViewBinder { legacyCallback: Spaghetti.Callback, applicationScope: CoroutineScope, vibratorHelper: VibratorHelper, msdlPlayer: MSDLPlayer, ): Spaghetti { val accessibilityManager = view.context.getSystemService(AccessibilityManager::class.java)!! Loading Loading @@ -434,21 +435,27 @@ object BiometricViewBinder { // Play haptics launch { viewModel.hapticsToPlay.collect { haptics -> if (haptics.hapticFeedbackConstant != HapticFeedbackConstants.NO_HAPTICS) { when (haptics) { is PromptViewModel.HapticsToPlay.HapticConstant -> { if (haptics.flag != null) { vibratorHelper.performHapticFeedback( view, haptics.hapticFeedbackConstant, haptics.constant, haptics.flag, ) } else { vibratorHelper.performHapticFeedback( view, haptics.hapticFeedbackConstant, haptics.constant, ) } viewModel.clearHaptics() } is PromptViewModel.HapticsToPlay.MSDL -> { msdlPlayer.playToken(haptics.token, haptics.properties) } is PromptViewModel.HapticsToPlay.None -> {} } viewModel.clearHaptics() } } Loading
packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModel.kt +46 −21 Original line number Diff line number Diff line Loading @@ -35,7 +35,9 @@ import android.util.Log import android.util.RotationUtils import android.view.HapticFeedbackConstants import android.view.MotionEvent import com.android.keyguard.AuthInteractionProperties import com.android.launcher3.icons.IconProvider import com.android.systemui.Flags.msdlFeedback import com.android.systemui.biometrics.UdfpsUtils import com.android.systemui.biometrics.Utils import com.android.systemui.biometrics.Utils.isSystem Loading @@ -53,6 +55,8 @@ import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.keyguard.shared.model.AcquiredFingerprintAuthenticationStatus import com.android.systemui.res.R import com.android.systemui.util.kotlin.combine import com.google.android.msdl.data.model.MSDLToken import com.google.android.msdl.domain.InteractionProperties import javax.inject.Inject import kotlinx.coroutines.Job import kotlinx.coroutines.coroutineScope Loading Loading @@ -245,8 +249,9 @@ constructor( private val _forceLargeSize = MutableStateFlow(false) private val _forceMediumSize = MutableStateFlow(false) private val _hapticsToPlay = MutableStateFlow(HapticsToPlay(HapticFeedbackConstants.NO_HAPTICS, /* flag= */ null)) private val authInteractionProperties = AuthInteractionProperties() private val _hapticsToPlay: MutableStateFlow<HapticsToPlay> = MutableStateFlow(HapticsToPlay.None) /** Event fired to the view indicating a [HapticsToPlay] */ val hapticsToPlay = _hapticsToPlay.asStateFlow() Loading Loading @@ -939,26 +944,52 @@ constructor( } private fun vibrateOnSuccess() { _hapticsToPlay.value = HapticsToPlay( val haptics = if (msdlFeedback()) { HapticsToPlay.MSDL(MSDLToken.UNLOCK, authInteractionProperties) } else { HapticsToPlay.HapticConstant( HapticFeedbackConstants.BIOMETRIC_CONFIRM, null, flag = null, ) } _hapticsToPlay.value = haptics } private fun vibrateOnError() { _hapticsToPlay.value = HapticsToPlay( val haptics = if (msdlFeedback()) { HapticsToPlay.MSDL(MSDLToken.FAILURE, authInteractionProperties) } else { HapticsToPlay.HapticConstant( HapticFeedbackConstants.BIOMETRIC_REJECT, null, flag = null, ) } _hapticsToPlay.value = haptics } /** Clears the [hapticsToPlay] variable by setting its constant to the NO_HAPTICS default. */ fun clearHaptics() { _hapticsToPlay.update { previous -> HapticsToPlay(HapticFeedbackConstants.NO_HAPTICS, previous.flag) _hapticsToPlay.update { HapticsToPlay.None } } /** The state of haptic feedback to play. */ sealed interface HapticsToPlay { /** * Haptics using [HapticFeedbackConstants]. It is composed by a [HapticFeedbackConstants] * and a [HapticFeedbackConstants] flag. */ data class HapticConstant(val constant: Int, val flag: Int?) : HapticsToPlay /** * Haptics using MSDL feedback. It is composed by a [MSDLToken] and optional * [InteractionProperties] */ data class MSDL(val token: MSDLToken, val properties: InteractionProperties?) : HapticsToPlay data object None : HapticsToPlay } companion object { Loading Loading @@ -1095,9 +1126,3 @@ enum class FingerprintStartMode { val isStarted: Boolean get() = this == Normal || this == Delayed } /** * The state of haptic feedback to play. It is composed by a [HapticFeedbackConstants] and a * [HapticFeedbackConstants] flag. */ data class HapticsToPlay(val hapticFeedbackConstant: Int, val flag: Int?)