From 9888e15f2a4570b2376ec23a66809254b365d222 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Mart=C3=ADn?= Date: Tue, 9 Aug 2022 14:02:26 +0200 Subject: [PATCH] Improve logic to trigger LockScreenViewEvents --- .../pin/lockscreen/ui/LockScreenAction.kt | 1 + .../pin/lockscreen/ui/LockScreenFragment.kt | 13 ++----------- .../pin/lockscreen/ui/LockScreenViewEvent.kt | 1 + .../pin/lockscreen/ui/LockScreenViewModel.kt | 19 +++++++++++++++---- 4 files changed, 19 insertions(+), 15 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/pin/lockscreen/ui/LockScreenAction.kt b/vector/src/main/java/im/vector/app/features/pin/lockscreen/ui/LockScreenAction.kt index 7f8d08dddd..729cf24aa5 100644 --- a/vector/src/main/java/im/vector/app/features/pin/lockscreen/ui/LockScreenAction.kt +++ b/vector/src/main/java/im/vector/app/features/pin/lockscreen/ui/LockScreenAction.kt @@ -22,4 +22,5 @@ import im.vector.app.core.platform.VectorViewModelAction sealed class LockScreenAction : VectorViewModelAction { data class PinCodeEntered(val value: String) : LockScreenAction() data class ShowBiometricPrompt(val callingActivity: FragmentActivity) : LockScreenAction() + object OnUIReady : LockScreenAction() } diff --git a/vector/src/main/java/im/vector/app/features/pin/lockscreen/ui/LockScreenFragment.kt b/vector/src/main/java/im/vector/app/features/pin/lockscreen/ui/LockScreenFragment.kt index 9a618ce939..a7a228a105 100644 --- a/vector/src/main/java/im/vector/app/features/pin/lockscreen/ui/LockScreenFragment.kt +++ b/vector/src/main/java/im/vector/app/features/pin/lockscreen/ui/LockScreenFragment.kt @@ -23,7 +23,6 @@ import android.view.ViewGroup import android.view.animation.AnimationUtils import android.widget.TextView import androidx.core.view.isVisible -import androidx.lifecycle.lifecycleScope import com.airbnb.mvrx.fragmentViewModel import com.airbnb.mvrx.withState import dagger.hilt.android.AndroidEntryPoint @@ -34,10 +33,6 @@ import im.vector.app.databinding.FragmentLockScreenBinding import im.vector.app.features.pin.lockscreen.configuration.LockScreenConfiguration import im.vector.app.features.pin.lockscreen.configuration.LockScreenMode import im.vector.app.features.pin.lockscreen.views.LockScreenCodeView -import kotlinx.coroutines.flow.distinctUntilChangedBy -import kotlinx.coroutines.flow.filter -import kotlinx.coroutines.flow.launchIn -import kotlinx.coroutines.flow.onEach @AndroidEntryPoint class LockScreenFragment : VectorBaseFragment() { @@ -59,12 +54,7 @@ class LockScreenFragment : VectorBaseFragment() { handleEvent(it) } - viewModel.stateFlow.distinctUntilChangedBy { it.showBiometricPromptAutomatically } - .filter { it.showBiometricPromptAutomatically } - .onEach { - showBiometricPrompt() - } - .launchIn(viewLifecycleOwner.lifecycleScope) + viewModel.handle(LockScreenAction.OnUIReady) } override fun invalidate() = withState(viewModel) { state -> @@ -119,6 +109,7 @@ class LockScreenFragment : VectorBaseFragment() { is LockScreenViewEvent.AuthFailure -> onAuthFailure(viewEvent.method) is LockScreenViewEvent.AuthError -> onAuthError(viewEvent.method, viewEvent.throwable) is LockScreenViewEvent.ShowBiometricKeyInvalidatedMessage -> lockScreenListener?.onBiometricKeyInvalidated() + is LockScreenViewEvent.ShowBiometricPromptAutomatically -> showBiometricPrompt() } } diff --git a/vector/src/main/java/im/vector/app/features/pin/lockscreen/ui/LockScreenViewEvent.kt b/vector/src/main/java/im/vector/app/features/pin/lockscreen/ui/LockScreenViewEvent.kt index e340486bc0..543ed58ffa 100644 --- a/vector/src/main/java/im/vector/app/features/pin/lockscreen/ui/LockScreenViewEvent.kt +++ b/vector/src/main/java/im/vector/app/features/pin/lockscreen/ui/LockScreenViewEvent.kt @@ -25,4 +25,5 @@ sealed class LockScreenViewEvent : VectorViewEvents { data class AuthFailure(val method: AuthMethod) : LockScreenViewEvent() data class AuthError(val method: AuthMethod, val throwable: Throwable) : LockScreenViewEvent() object ShowBiometricKeyInvalidatedMessage : LockScreenViewEvent() + object ShowBiometricPromptAutomatically : LockScreenViewEvent() } diff --git a/vector/src/main/java/im/vector/app/features/pin/lockscreen/ui/LockScreenViewModel.kt b/vector/src/main/java/im/vector/app/features/pin/lockscreen/ui/LockScreenViewModel.kt index 2230215047..d40f67ea35 100644 --- a/vector/src/main/java/im/vector/app/features/pin/lockscreen/ui/LockScreenViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/pin/lockscreen/ui/LockScreenViewModel.kt @@ -20,7 +20,6 @@ import android.annotation.SuppressLint import android.app.KeyguardManager import android.os.Build import android.security.keystore.KeyPermanentlyInvalidatedException -import androidx.annotation.VisibleForTesting import androidx.fragment.app.FragmentActivity import com.airbnb.mvrx.MavericksViewModelFactory import dagger.assisted.Assisted @@ -37,6 +36,7 @@ import im.vector.app.features.pin.lockscreen.pincode.PinCodeHelper import kotlinx.coroutines.delay import kotlinx.coroutines.flow.catch import kotlinx.coroutines.flow.emitAll +import kotlinx.coroutines.flow.firstOrNull import kotlinx.coroutines.flow.flow import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach @@ -77,10 +77,20 @@ class LockScreenViewModel @AssistedInject constructor( lockScreenKeysMigrator.migrateIfNeeded() // Update initial state with biometric info updateStateWithBiometricInfo() + } + } - val state = awaitState() - // If when initialized we detect a key invalidation, we should show an error message. - if (state.isBiometricKeyInvalidated) { + private fun observeStateChanges() { + // The first time the state allows it, show the biometric prompt + viewModelScope.launch { + if (stateFlow.firstOrNull { it.showBiometricPromptAutomatically } != null) { + _viewEvents.post(LockScreenViewEvent.ShowBiometricPromptAutomatically) + } + } + + // The first time the state allows it, react to biometric key being invalidated + viewModelScope.launch { + if (stateFlow.firstOrNull { it.isBiometricKeyInvalidated } != null) { onBiometricKeyInvalidated() } } @@ -90,6 +100,7 @@ class LockScreenViewModel @AssistedInject constructor( when (action) { is LockScreenAction.PinCodeEntered -> onPinCodeEntered(action.value) is LockScreenAction.ShowBiometricPrompt -> showBiometricPrompt(action.callingActivity) + is LockScreenAction.OnUIReady -> observeStateChanges() } }