Lock : fix race condition on setup pin

This commit is contained in:
ganfra
2023-11-07 21:06:26 +01:00
parent 41517614c8
commit 8b4d3a4bc8
4 changed files with 15 additions and 10 deletions

View File

@@ -17,6 +17,6 @@
package io.element.android.features.lockscreen.impl.setup.pin
sealed interface SetupPinEvents {
data class OnPinEntryChanged(val entryAsText: String) : SetupPinEvents
data class OnPinEntryChanged(val entryAsText: String, val fromConfirmationStep: Boolean) : SetupPinEvents
data object ClearFailure : SetupPinEvents
}

View File

@@ -85,7 +85,8 @@ class SetupPinPresenter @Inject constructor(
fun handleEvents(event: SetupPinEvents) {
when (event) {
is SetupPinEvents.OnPinEntryChanged -> {
if (isConfirmationStep) {
// Use the fromConfirmationStep flag from ui to avoid race condition.
if (event.fromConfirmationStep) {
confirmPinEntry = confirmPinEntry.fillWith(event.entryAsText)
} else {
choosePinEntry = choosePinEntry.fillWith(event.entryAsText)

View File

@@ -116,8 +116,8 @@ private fun SetupPinContent(
PinEntryTextField(
pinEntry = state.activePinEntry,
isSecured = true,
onValueChange = {
state.eventSink(SetupPinEvents.OnPinEntryChanged(it))
onValueChange = { entry ->
state.eventSink(SetupPinEvents.OnPinEntryChanged(entry, state.isConfirmationStep))
},
modifier = modifier
.focusRequester(focusRequester)

View File

@@ -60,14 +60,14 @@ class SetupPinPresenterTest {
state.confirmPinEntry.assertEmpty()
assertThat(state.setupPinFailure).isNull()
assertThat(state.isConfirmationStep).isFalse()
state.eventSink(SetupPinEvents.OnPinEntryChanged(halfCompletePin))
state.onPinEntryChanged(halfCompletePin)
}
awaitItem().also { state ->
state.choosePinEntry.assertText(halfCompletePin)
state.confirmPinEntry.assertEmpty()
assertThat(state.setupPinFailure).isNull()
assertThat(state.isConfirmationStep).isFalse()
state.eventSink(SetupPinEvents.OnPinEntryChanged(blacklistedPin))
state.onPinEntryChanged(blacklistedPin)
}
awaitLastSequentialItem().also { state ->
state.choosePinEntry.assertText(blacklistedPin)
@@ -77,7 +77,7 @@ class SetupPinPresenterTest {
awaitLastSequentialItem().also { state ->
state.choosePinEntry.assertEmpty()
assertThat(state.setupPinFailure).isNull()
state.eventSink(SetupPinEvents.OnPinEntryChanged(completePin))
state.onPinEntryChanged(completePin)
}
consumeItemsUntilPredicate {
it.isConfirmationStep
@@ -85,7 +85,7 @@ class SetupPinPresenterTest {
state.choosePinEntry.assertText(completePin)
state.confirmPinEntry.assertEmpty()
assertThat(state.isConfirmationStep).isTrue()
state.eventSink(SetupPinEvents.OnPinEntryChanged(mismatchedPin))
state.onPinEntryChanged(mismatchedPin)
}
awaitLastSequentialItem().also { state ->
state.choosePinEntry.assertText(completePin)
@@ -98,7 +98,7 @@ class SetupPinPresenterTest {
state.confirmPinEntry.assertEmpty()
assertThat(state.isConfirmationStep).isFalse()
assertThat(state.setupPinFailure).isNull()
state.eventSink(SetupPinEvents.OnPinEntryChanged(completePin))
state.onPinEntryChanged(completePin)
}
consumeItemsUntilPredicate {
it.isConfirmationStep
@@ -106,7 +106,7 @@ class SetupPinPresenterTest {
state.choosePinEntry.assertText(completePin)
state.confirmPinEntry.assertEmpty()
assertThat(state.isConfirmationStep).isTrue()
state.eventSink(SetupPinEvents.OnPinEntryChanged(completePin))
state.onPinEntryChanged(completePin)
}
awaitItem().also { state ->
state.choosePinEntry.assertText(completePin)
@@ -116,6 +116,10 @@ class SetupPinPresenterTest {
}
}
private fun SetupPinState.onPinEntryChanged(pinEntry: String){
eventSink(SetupPinEvents.OnPinEntryChanged(pinEntry, isConfirmationStep))
}
private fun createSetupPinPresenter(
callback: PinCodeManager.Callback,
lockScreenConfig: LockScreenConfig = aLockScreenConfig(