Skip to content

Commit

Permalink
Improve logic to trigger LockScreenViewEvents
Browse files Browse the repository at this point in the history
  • Loading branch information
jmartinesp committed Aug 9, 2022
1 parent cc59b9e commit 9888e15
Show file tree
Hide file tree
Showing 4 changed files with 19 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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()
}
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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<FragmentLockScreenBinding>() {
Expand All @@ -59,12 +54,7 @@ class LockScreenFragment : VectorBaseFragment<FragmentLockScreenBinding>() {
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 ->
Expand Down Expand Up @@ -119,6 +109,7 @@ class LockScreenFragment : VectorBaseFragment<FragmentLockScreenBinding>() {
is LockScreenViewEvent.AuthFailure -> onAuthFailure(viewEvent.method)
is LockScreenViewEvent.AuthError -> onAuthError(viewEvent.method, viewEvent.throwable)
is LockScreenViewEvent.ShowBiometricKeyInvalidatedMessage -> lockScreenListener?.onBiometricKeyInvalidated()
is LockScreenViewEvent.ShowBiometricPromptAutomatically -> showBiometricPrompt()
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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()
}
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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()
}
}
Expand All @@ -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()
}
}

Expand Down

0 comments on commit 9888e15

Please sign in to comment.