Improve logic to trigger LockScreenViewEvents

This commit is contained in:
Jorge Martín 2022-08-09 14:02:26 +02:00
parent cc59b9e695
commit 9888e15f2a
4 changed files with 19 additions and 15 deletions

View file

@ -22,4 +22,5 @@ import im.vector.app.core.platform.VectorViewModelAction
sealed class LockScreenAction : VectorViewModelAction { sealed class LockScreenAction : VectorViewModelAction {
data class PinCodeEntered(val value: String) : LockScreenAction() data class PinCodeEntered(val value: String) : LockScreenAction()
data class ShowBiometricPrompt(val callingActivity: FragmentActivity) : LockScreenAction() data class ShowBiometricPrompt(val callingActivity: FragmentActivity) : LockScreenAction()
object OnUIReady : LockScreenAction()
} }

View file

@ -23,7 +23,6 @@ import android.view.ViewGroup
import android.view.animation.AnimationUtils import android.view.animation.AnimationUtils
import android.widget.TextView import android.widget.TextView
import androidx.core.view.isVisible import androidx.core.view.isVisible
import androidx.lifecycle.lifecycleScope
import com.airbnb.mvrx.fragmentViewModel import com.airbnb.mvrx.fragmentViewModel
import com.airbnb.mvrx.withState import com.airbnb.mvrx.withState
import dagger.hilt.android.AndroidEntryPoint 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.LockScreenConfiguration
import im.vector.app.features.pin.lockscreen.configuration.LockScreenMode import im.vector.app.features.pin.lockscreen.configuration.LockScreenMode
import im.vector.app.features.pin.lockscreen.views.LockScreenCodeView 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 @AndroidEntryPoint
class LockScreenFragment : VectorBaseFragment<FragmentLockScreenBinding>() { class LockScreenFragment : VectorBaseFragment<FragmentLockScreenBinding>() {
@ -59,12 +54,7 @@ class LockScreenFragment : VectorBaseFragment<FragmentLockScreenBinding>() {
handleEvent(it) handleEvent(it)
} }
viewModel.stateFlow.distinctUntilChangedBy { it.showBiometricPromptAutomatically } viewModel.handle(LockScreenAction.OnUIReady)
.filter { it.showBiometricPromptAutomatically }
.onEach {
showBiometricPrompt()
}
.launchIn(viewLifecycleOwner.lifecycleScope)
} }
override fun invalidate() = withState(viewModel) { state -> override fun invalidate() = withState(viewModel) { state ->
@ -119,6 +109,7 @@ class LockScreenFragment : VectorBaseFragment<FragmentLockScreenBinding>() {
is LockScreenViewEvent.AuthFailure -> onAuthFailure(viewEvent.method) is LockScreenViewEvent.AuthFailure -> onAuthFailure(viewEvent.method)
is LockScreenViewEvent.AuthError -> onAuthError(viewEvent.method, viewEvent.throwable) is LockScreenViewEvent.AuthError -> onAuthError(viewEvent.method, viewEvent.throwable)
is LockScreenViewEvent.ShowBiometricKeyInvalidatedMessage -> lockScreenListener?.onBiometricKeyInvalidated() is LockScreenViewEvent.ShowBiometricKeyInvalidatedMessage -> lockScreenListener?.onBiometricKeyInvalidated()
is LockScreenViewEvent.ShowBiometricPromptAutomatically -> showBiometricPrompt()
} }
} }

View file

@ -25,4 +25,5 @@ sealed class LockScreenViewEvent : VectorViewEvents {
data class AuthFailure(val method: AuthMethod) : LockScreenViewEvent() data class AuthFailure(val method: AuthMethod) : LockScreenViewEvent()
data class AuthError(val method: AuthMethod, val throwable: Throwable) : LockScreenViewEvent() data class AuthError(val method: AuthMethod, val throwable: Throwable) : LockScreenViewEvent()
object ShowBiometricKeyInvalidatedMessage : LockScreenViewEvent() object ShowBiometricKeyInvalidatedMessage : LockScreenViewEvent()
object ShowBiometricPromptAutomatically : LockScreenViewEvent()
} }

View file

@ -20,7 +20,6 @@ import android.annotation.SuppressLint
import android.app.KeyguardManager import android.app.KeyguardManager
import android.os.Build import android.os.Build
import android.security.keystore.KeyPermanentlyInvalidatedException import android.security.keystore.KeyPermanentlyInvalidatedException
import androidx.annotation.VisibleForTesting
import androidx.fragment.app.FragmentActivity import androidx.fragment.app.FragmentActivity
import com.airbnb.mvrx.MavericksViewModelFactory import com.airbnb.mvrx.MavericksViewModelFactory
import dagger.assisted.Assisted import dagger.assisted.Assisted
@ -37,6 +36,7 @@ import im.vector.app.features.pin.lockscreen.pincode.PinCodeHelper
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.catch import kotlinx.coroutines.flow.catch
import kotlinx.coroutines.flow.emitAll import kotlinx.coroutines.flow.emitAll
import kotlinx.coroutines.flow.firstOrNull
import kotlinx.coroutines.flow.flow import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.onEach
@ -77,10 +77,20 @@ class LockScreenViewModel @AssistedInject constructor(
lockScreenKeysMigrator.migrateIfNeeded() lockScreenKeysMigrator.migrateIfNeeded()
// Update initial state with biometric info // Update initial state with biometric info
updateStateWithBiometricInfo() updateStateWithBiometricInfo()
}
}
val state = awaitState() private fun observeStateChanges() {
// If when initialized we detect a key invalidation, we should show an error message. // The first time the state allows it, show the biometric prompt
if (state.isBiometricKeyInvalidated) { 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() onBiometricKeyInvalidated()
} }
} }
@ -90,6 +100,7 @@ class LockScreenViewModel @AssistedInject constructor(
when (action) { when (action) {
is LockScreenAction.PinCodeEntered -> onPinCodeEntered(action.value) is LockScreenAction.PinCodeEntered -> onPinCodeEntered(action.value)
is LockScreenAction.ShowBiometricPrompt -> showBiometricPrompt(action.callingActivity) is LockScreenAction.ShowBiometricPrompt -> showBiometricPrompt(action.callingActivity)
is LockScreenAction.OnUIReady -> observeStateChanges()
} }
} }