Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cec6037b authored by Danny Burakov's avatar Danny Burakov Committed by Android (Google) Code Review
Browse files

Merge "[flexiglass] Rename "throttling" to "lockout"." into main

parents a0b6693a d62e012f
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -203,7 +203,7 @@ private fun SceneScope.FoldSplittable(
    modifier: Modifier = Modifier,
) {
    val message: BouncerViewModel.MessageViewModel by viewModel.message.collectAsState()
    val dialogMessage: String? by viewModel.throttlingDialogMessage.collectAsState()
    val dialogMessage: String? by viewModel.dialogMessage.collectAsState()
    var dialog: Dialog? by remember { mutableStateOf(null) }
    val actionButton: BouncerActionButtonModel? by viewModel.actionButton.collectAsState()
    val splitRatio =
@@ -320,7 +320,7 @@ private fun SceneScope.FoldSplittable(
                            DialogInterface.BUTTON_NEUTRAL,
                            context.getString(R.string.ok),
                        ) { _, _ ->
                            viewModel.onThrottlingDialogDismissed()
                            viewModel.onDialogDismissed()
                        }
                        setCancelable(false)
                        setCanceledOnTouchOutside(false)
+46 −47
Original line number Diff line number Diff line
@@ -21,9 +21,9 @@ import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.authentication.data.repository.FakeAuthenticationRepository
import com.android.systemui.authentication.shared.model.AuthenticationLockoutModel
import com.android.systemui.authentication.shared.model.AuthenticationMethodModel
import com.android.systemui.authentication.shared.model.AuthenticationPatternCoordinate
import com.android.systemui.authentication.shared.model.AuthenticationThrottlingModel
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.scene.SceneTestUtils
import com.google.common.truth.Truth.assertThat
@@ -76,12 +76,12 @@ class AuthenticationInteractorTest : SysuiTestCase() {
    @Test
    fun authenticate_withCorrectPin_succeeds() =
        testScope.runTest {
            val throttling by collectLastValue(underTest.throttling)
            val lockout by collectLastValue(underTest.lockout)
            utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)

            assertThat(underTest.authenticate(FakeAuthenticationRepository.DEFAULT_PIN))
                .isEqualTo(AuthenticationResult.SUCCEEDED)
            assertThat(throttling).isNull()
            assertThat(lockout).isNull()
            assertThat(utils.authenticationRepository.lockoutStartedReportCount).isEqualTo(0)
        }

@@ -130,14 +130,14 @@ class AuthenticationInteractorTest : SysuiTestCase() {
    @Test
    fun authenticate_withCorrectPassword_succeeds() =
        testScope.runTest {
            val throttling by collectLastValue(underTest.throttling)
            val lockout by collectLastValue(underTest.lockout)
            utils.authenticationRepository.setAuthenticationMethod(
                AuthenticationMethodModel.Password
            )

            assertThat(underTest.authenticate("password".toList()))
                .isEqualTo(AuthenticationResult.SUCCEEDED)
            assertThat(throttling).isNull()
            assertThat(lockout).isNull()
            assertThat(utils.authenticationRepository.lockoutStartedReportCount).isEqualTo(0)
        }

@@ -187,7 +187,7 @@ class AuthenticationInteractorTest : SysuiTestCase() {
    fun tryAutoConfirm_withAutoConfirmPinAndShorterPin_returnsNull() =
        testScope.runTest {
            val isAutoConfirmEnabled by collectLastValue(underTest.isAutoConfirmEnabled)
            val throttling by collectLastValue(underTest.throttling)
            val lockout by collectLastValue(underTest.lockout)
            utils.authenticationRepository.apply {
                setAuthenticationMethod(AuthenticationMethodModel.Pin)
                setAutoConfirmFeatureEnabled(true)
@@ -203,7 +203,7 @@ class AuthenticationInteractorTest : SysuiTestCase() {
                    )
                )
                .isEqualTo(AuthenticationResult.SKIPPED)
            assertThat(throttling).isNull()
            assertThat(lockout).isNull()
            assertThat(utils.authenticationRepository.lockoutStartedReportCount).isEqualTo(0)
        }

@@ -265,7 +265,7 @@ class AuthenticationInteractorTest : SysuiTestCase() {
        }

    @Test
    fun tryAutoConfirm_withAutoConfirmCorrectPinButDuringThrottling_returnsNull() =
    fun tryAutoConfirm_withAutoConfirmCorrectPinButDuringLockout_returnsNull() =
        testScope.runTest {
            val isAutoConfirmEnabled by collectLastValue(underTest.isAutoConfirmEnabled)
            val isUnlocked by collectLastValue(utils.deviceEntryRepository.isUnlocked)
@@ -273,7 +273,7 @@ class AuthenticationInteractorTest : SysuiTestCase() {
            utils.authenticationRepository.apply {
                setAuthenticationMethod(AuthenticationMethodModel.Pin)
                setAutoConfirmFeatureEnabled(true)
                setThrottleDuration(42)
                setLockoutDuration(42)
            }

            val authResult =
@@ -334,30 +334,30 @@ class AuthenticationInteractorTest : SysuiTestCase() {
        }

    @Test
    fun isAutoConfirmEnabled_featureEnabledButDisabledByThrottling() =
    fun isAutoConfirmEnabled_featureEnabledButDisabledByLockout() =
        testScope.runTest {
            val isAutoConfirmEnabled by collectLastValue(underTest.isAutoConfirmEnabled)
            val throttling by collectLastValue(underTest.throttling)
            val lockout by collectLastValue(underTest.lockout)
            utils.authenticationRepository.setAutoConfirmFeatureEnabled(true)

            // The feature is enabled.
            assertThat(isAutoConfirmEnabled).isTrue()

            // Make many wrong attempts to trigger throttling.
            repeat(FakeAuthenticationRepository.MAX_FAILED_AUTH_TRIES_BEFORE_THROTTLING) {
            // Make many wrong attempts to trigger lockout.
            repeat(FakeAuthenticationRepository.MAX_FAILED_AUTH_TRIES_BEFORE_LOCKOUT) {
                underTest.authenticate(listOf(5, 6, 7)) // Wrong PIN
            }
            assertThat(throttling).isNotNull()
            assertThat(lockout).isNotNull()
            assertThat(utils.authenticationRepository.lockoutStartedReportCount).isEqualTo(1)

            // Throttling disabled auto-confirm.
            // Lockout disabled auto-confirm.
            assertThat(isAutoConfirmEnabled).isFalse()

            // Move the clock forward one more second, to completely finish the throttling period:
            advanceTimeBy(FakeAuthenticationRepository.THROTTLE_DURATION_MS + 1000L)
            assertThat(throttling).isNull()
            // Move the clock forward one more second, to completely finish the lockout period:
            advanceTimeBy(FakeAuthenticationRepository.LOCKOUT_DURATION_MS + 1000L)
            assertThat(lockout).isNull()

            // Auto-confirm is still disabled, because throttling occurred at least once in this
            // Auto-confirm is still disabled, because lockout occurred at least once in this
            // session.
            assertThat(isAutoConfirmEnabled).isFalse()

@@ -372,66 +372,65 @@ class AuthenticationInteractorTest : SysuiTestCase() {
        }

    @Test
    fun throttling() =
    fun lockout() =
        testScope.runTest {
            val throttling by collectLastValue(underTest.throttling)
            val lockout by collectLastValue(underTest.lockout)
            utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
            underTest.authenticate(FakeAuthenticationRepository.DEFAULT_PIN)
            assertThat(throttling).isNull()
            assertThat(lockout).isNull()

            // Make many wrong attempts, but just shy of what's needed to get throttled:
            repeat(FakeAuthenticationRepository.MAX_FAILED_AUTH_TRIES_BEFORE_THROTTLING - 1) {
            // Make many wrong attempts, but just shy of what's needed to get locked out:
            repeat(FakeAuthenticationRepository.MAX_FAILED_AUTH_TRIES_BEFORE_LOCKOUT - 1) {
                underTest.authenticate(listOf(5, 6, 7)) // Wrong PIN
                assertThat(throttling).isNull()
                assertThat(lockout).isNull()
            }

            // Make one more wrong attempt, leading to throttling:
            // Make one more wrong attempt, leading to lockout:
            underTest.authenticate(listOf(5, 6, 7)) // Wrong PIN
            assertThat(throttling)
            assertThat(lockout)
                .isEqualTo(
                    AuthenticationThrottlingModel(
                    AuthenticationLockoutModel(
                        failedAttemptCount =
                            FakeAuthenticationRepository.MAX_FAILED_AUTH_TRIES_BEFORE_THROTTLING,
                        remainingSeconds = FakeAuthenticationRepository.THROTTLE_DURATION_SECONDS,
                            FakeAuthenticationRepository.MAX_FAILED_AUTH_TRIES_BEFORE_LOCKOUT,
                        remainingSeconds = FakeAuthenticationRepository.LOCKOUT_DURATION_SECONDS,
                    )
                )
            assertThat(utils.authenticationRepository.lockoutStartedReportCount).isEqualTo(1)

            // Correct PIN, but throttled, so doesn't attempt it:
            // Correct PIN, but locked out, so doesn't attempt it:
            assertThat(underTest.authenticate(FakeAuthenticationRepository.DEFAULT_PIN))
                .isEqualTo(AuthenticationResult.SKIPPED)
            assertThat(throttling)
            assertThat(lockout)
                .isEqualTo(
                    AuthenticationThrottlingModel(
                    AuthenticationLockoutModel(
                        failedAttemptCount =
                            FakeAuthenticationRepository.MAX_FAILED_AUTH_TRIES_BEFORE_THROTTLING,
                        remainingSeconds = FakeAuthenticationRepository.THROTTLE_DURATION_SECONDS,
                            FakeAuthenticationRepository.MAX_FAILED_AUTH_TRIES_BEFORE_LOCKOUT,
                        remainingSeconds = FakeAuthenticationRepository.LOCKOUT_DURATION_SECONDS,
                    )
                )

            // Move the clock forward to ALMOST skip the throttling, leaving one second to go:
            val throttleTimeoutSec = FakeAuthenticationRepository.THROTTLE_DURATION_SECONDS
            repeat(FakeAuthenticationRepository.THROTTLE_DURATION_SECONDS - 1) { time ->
            // Move the clock forward to ALMOST skip the lockout, leaving one second to go:
            val lockoutTimeoutSec = FakeAuthenticationRepository.LOCKOUT_DURATION_SECONDS
            repeat(FakeAuthenticationRepository.LOCKOUT_DURATION_SECONDS - 1) { time ->
                advanceTimeBy(1000)
                assertThat(throttling)
                assertThat(lockout)
                    .isEqualTo(
                        AuthenticationThrottlingModel(
                        AuthenticationLockoutModel(
                            failedAttemptCount =
                                FakeAuthenticationRepository
                                    .MAX_FAILED_AUTH_TRIES_BEFORE_THROTTLING,
                            remainingSeconds = throttleTimeoutSec - (time + 1),
                                FakeAuthenticationRepository.MAX_FAILED_AUTH_TRIES_BEFORE_LOCKOUT,
                            remainingSeconds = lockoutTimeoutSec - (time + 1),
                        )
                    )
            }

            // Move the clock forward one more second, to completely finish the throttling period:
            // Move the clock forward one more second, to completely finish the lockout period:
            advanceTimeBy(1000)
            assertThat(throttling).isNull()
            assertThat(lockout).isNull()

            // Correct PIN and no longer throttled so unlocks successfully:
            // Correct PIN and no longer locked out so unlocks successfully:
            assertThat(underTest.authenticate(FakeAuthenticationRepository.DEFAULT_PIN))
                .isEqualTo(AuthenticationResult.SUCCEEDED)
            assertThat(throttling).isNull()
            assertThat(lockout).isNull()
        }

    @Test
+17 −21
Original line number Diff line number Diff line
@@ -21,9 +21,9 @@ import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.authentication.data.repository.FakeAuthenticationRepository
import com.android.systemui.authentication.domain.interactor.AuthenticationResult
import com.android.systemui.authentication.shared.model.AuthenticationLockoutModel
import com.android.systemui.authentication.shared.model.AuthenticationMethodModel
import com.android.systemui.authentication.shared.model.AuthenticationPatternCoordinate
import com.android.systemui.authentication.shared.model.AuthenticationThrottlingModel
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.keyguard.domain.interactor.KeyguardFaceAuthInteractor
import com.android.systemui.res.R
@@ -246,46 +246,42 @@ class BouncerInteractorTest : SysuiTestCase() {
        }

    @Test
    fun throttling() =
    fun lockout() =
        testScope.runTest {
            val throttling by collectLastValue(underTest.throttling)
            val lockout by collectLastValue(underTest.lockout)
            val message by collectLastValue(underTest.message)
            utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
            assertThat(throttling).isNull()
            repeat(FakeAuthenticationRepository.MAX_FAILED_AUTH_TRIES_BEFORE_THROTTLING) { times ->
            assertThat(lockout).isNull()
            repeat(FakeAuthenticationRepository.MAX_FAILED_AUTH_TRIES_BEFORE_LOCKOUT) { times ->
                // Wrong PIN.
                assertThat(underTest.authenticate(listOf(6, 7, 8, 9)))
                    .isEqualTo(AuthenticationResult.FAILED)
                if (
                    times < FakeAuthenticationRepository.MAX_FAILED_AUTH_TRIES_BEFORE_THROTTLING - 1
                ) {
                if (times < FakeAuthenticationRepository.MAX_FAILED_AUTH_TRIES_BEFORE_LOCKOUT - 1) {
                    assertThat(message).isEqualTo(MESSAGE_WRONG_PIN)
                }
            }
            assertThat(throttling)
            assertThat(lockout)
                .isEqualTo(
                    AuthenticationThrottlingModel(
                    AuthenticationLockoutModel(
                        failedAttemptCount =
                            FakeAuthenticationRepository.MAX_FAILED_AUTH_TRIES_BEFORE_THROTTLING,
                        remainingSeconds = FakeAuthenticationRepository.THROTTLE_DURATION_SECONDS,
                            FakeAuthenticationRepository.MAX_FAILED_AUTH_TRIES_BEFORE_LOCKOUT,
                        remainingSeconds = FakeAuthenticationRepository.LOCKOUT_DURATION_SECONDS,
                    )
                )
            assertTryAgainMessage(
                message,
                FakeAuthenticationRepository.THROTTLE_DURATION_MS.milliseconds.inWholeSeconds
                    .toInt()
                FakeAuthenticationRepository.LOCKOUT_DURATION_MS.milliseconds.inWholeSeconds.toInt()
            )

            // Correct PIN, but throttled, so doesn't change away from the bouncer scene:
            // Correct PIN, but locked out, so doesn't change away from the bouncer scene:
            assertThat(underTest.authenticate(FakeAuthenticationRepository.DEFAULT_PIN))
                .isEqualTo(AuthenticationResult.SKIPPED)
            assertTryAgainMessage(
                message,
                FakeAuthenticationRepository.THROTTLE_DURATION_MS.milliseconds.inWholeSeconds
                    .toInt()
                FakeAuthenticationRepository.LOCKOUT_DURATION_MS.milliseconds.inWholeSeconds.toInt()
            )

            throttling?.remainingSeconds?.let { seconds ->
            lockout?.remainingSeconds?.let { seconds ->
                repeat(seconds) { time ->
                    advanceTimeBy(1000)
                    val remainingTimeSec = seconds - time - 1
@@ -295,12 +291,12 @@ class BouncerInteractorTest : SysuiTestCase() {
                }
            }
            assertThat(message).isEqualTo("")
            assertThat(throttling).isNull()
            assertThat(lockout).isNull()

            // Correct PIN and no longer throttled so changes to the Gone scene:
            // Correct PIN and no longer locked out so changes to the Gone scene:
            assertThat(underTest.authenticate(FakeAuthenticationRepository.DEFAULT_PIN))
                .isEqualTo(AuthenticationResult.SUCCEEDED)
            assertThat(throttling).isNull()
            assertThat(lockout).isNull()
        }

    @Test
+0 −1
Original line number Diff line number Diff line
@@ -35,7 +35,6 @@ class AuthMethodBouncerViewModelTest : SysuiTestCase() {

    private val utils = SceneTestUtils(this)
    private val testScope = utils.testScope
    private val sceneInteractor = utils.sceneInteractor()
    private val bouncerInteractor =
        utils.bouncerInteractor(
            authenticationInteractor = utils.authenticationInteractor(),
+13 −13
Original line number Diff line number Diff line
@@ -135,17 +135,17 @@ class BouncerViewModelTest : SysuiTestCase() {
    fun message() =
        testScope.runTest {
            val message by collectLastValue(underTest.message)
            val throttling by collectLastValue(bouncerInteractor.throttling)
            val lockout by collectLastValue(bouncerInteractor.lockout)
            utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
            assertThat(message?.isUpdateAnimated).isTrue()

            repeat(FakeAuthenticationRepository.MAX_FAILED_AUTH_TRIES_BEFORE_THROTTLING) {
            repeat(FakeAuthenticationRepository.MAX_FAILED_AUTH_TRIES_BEFORE_LOCKOUT) {
                // Wrong PIN.
                bouncerInteractor.authenticate(listOf(3, 4, 5, 6))
            }
            assertThat(message?.isUpdateAnimated).isFalse()

            throttling?.remainingSeconds?.let { remainingSeconds ->
            lockout?.remainingSeconds?.let { remainingSeconds ->
                advanceTimeBy(remainingSeconds.seconds.inWholeMilliseconds)
            }
            assertThat(message?.isUpdateAnimated).isTrue()
@@ -160,37 +160,37 @@ class BouncerViewModelTest : SysuiTestCase() {
                        authViewModel?.isInputEnabled ?: emptyFlow()
                    }
                )
            val throttling by collectLastValue(bouncerInteractor.throttling)
            val lockout by collectLastValue(bouncerInteractor.lockout)
            utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
            assertThat(isInputEnabled).isTrue()

            repeat(FakeAuthenticationRepository.MAX_FAILED_AUTH_TRIES_BEFORE_THROTTLING) {
            repeat(FakeAuthenticationRepository.MAX_FAILED_AUTH_TRIES_BEFORE_LOCKOUT) {
                // Wrong PIN.
                bouncerInteractor.authenticate(listOf(3, 4, 5, 6))
            }
            assertThat(isInputEnabled).isFalse()

            throttling?.remainingSeconds?.let { remainingSeconds ->
            lockout?.remainingSeconds?.let { remainingSeconds ->
                advanceTimeBy(remainingSeconds.seconds.inWholeMilliseconds)
            }
            assertThat(isInputEnabled).isTrue()
        }

    @Test
    fun throttlingDialogMessage() =
    fun dialogMessage() =
        testScope.runTest {
            val throttlingDialogMessage by collectLastValue(underTest.throttlingDialogMessage)
            val dialogMessage by collectLastValue(underTest.dialogMessage)
            utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)

            repeat(FakeAuthenticationRepository.MAX_FAILED_AUTH_TRIES_BEFORE_THROTTLING) {
            repeat(FakeAuthenticationRepository.MAX_FAILED_AUTH_TRIES_BEFORE_LOCKOUT) {
                // Wrong PIN.
                assertThat(throttlingDialogMessage).isNull()
                assertThat(dialogMessage).isNull()
                bouncerInteractor.authenticate(listOf(3, 4, 5, 6))
            }
            assertThat(throttlingDialogMessage).isNotEmpty()
            assertThat(dialogMessage).isNotEmpty()

            underTest.onThrottlingDialogDismissed()
            assertThat(throttlingDialogMessage).isNull()
            underTest.onDialogDismissed()
            assertThat(dialogMessage).isNull()
        }

    @Test
Loading