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

Commit ba160eb4 authored by Chandru S's avatar Chandru S
Browse files

[flexiglass] Add device entry restriction reason to DeviceEntryInteractor

Whenever certain device entry authentication methods are restricted, this field will specify the reason so the view layer can display a specific message to the user.

Bug: 299343534
Flag: ACONFIG com.android.systemui.compose_bouncer DEVELOPMENT
Test: atest DeviceEntryInteractorTest
Change-Id: If71980e682bc151f147117bd1abad8ef50bf27fb
parent 7e73502a
Loading
Loading
Loading
Loading
+214 −1
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package com.android.systemui.deviceentry.domain.interactor
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.compose.animation.scene.SceneKey
import com.android.internal.widget.LockPatternUtils
import com.android.systemui.SysuiTestCase
import com.android.systemui.authentication.data.repository.FakeAuthenticationRepository
import com.android.systemui.authentication.data.repository.fakeAuthenticationRepository
@@ -27,8 +28,21 @@ import com.android.systemui.authentication.shared.model.AuthenticationMethodMode
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.coroutines.collectValues
import com.android.systemui.deviceentry.data.repository.fakeDeviceEntryRepository
import com.android.systemui.deviceentry.shared.model.DeviceEntryRestrictionReason
import com.android.systemui.deviceentry.shared.model.DeviceEntryRestrictionReason.AdaptiveAuthRequest
import com.android.systemui.deviceentry.shared.model.DeviceEntryRestrictionReason.BouncerLockedOut
import com.android.systemui.deviceentry.shared.model.DeviceEntryRestrictionReason.DeviceNotUnlockedSinceReboot
import com.android.systemui.deviceentry.shared.model.DeviceEntryRestrictionReason.NonStrongBiometricsSecurityTimeout
import com.android.systemui.deviceentry.shared.model.DeviceEntryRestrictionReason.PolicyLockdown
import com.android.systemui.deviceentry.shared.model.DeviceEntryRestrictionReason.SecurityTimeout
import com.android.systemui.deviceentry.shared.model.DeviceEntryRestrictionReason.TrustAgentDisabled
import com.android.systemui.deviceentry.shared.model.DeviceEntryRestrictionReason.UnattendedUpdate
import com.android.systemui.deviceentry.shared.model.DeviceEntryRestrictionReason.UserLockdown
import com.android.systemui.flags.fakeSystemPropertiesHelper
import com.android.systemui.keyguard.data.repository.fakeBiometricSettingsRepository
import com.android.systemui.keyguard.data.repository.fakeDeviceEntryFaceAuthRepository
import com.android.systemui.keyguard.data.repository.fakeTrustRepository
import com.android.systemui.keyguard.shared.model.AuthenticationFlags
import com.android.systemui.kosmos.testScope
import com.android.systemui.scene.domain.interactor.sceneInteractor
import com.android.systemui.scene.shared.flag.fakeSceneContainerFlags
@@ -36,6 +50,7 @@ import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.testKosmos
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.runCurrent
import kotlinx.coroutines.test.runTest
import org.junit.Before
@@ -230,8 +245,8 @@ class DeviceEntryInteractorTest : SysuiTestCase() {
            assertThat(canSwipeToEnter).isFalse()

            trustRepository.setCurrentUserTrusted(true)
            runCurrent()
            faceAuthRepository.isAuthenticated.value = false
            runCurrent()

            assertThat(canSwipeToEnter).isTrue()
        }
@@ -383,6 +398,204 @@ class DeviceEntryInteractorTest : SysuiTestCase() {
            assertThat(isUnlocked).isTrue()
        }

    @Test
    fun deviceEntryRestrictionReason_whenFaceOrFingerprintOrTrust_alwaysNull() =
        testScope.runTest {
            kosmos.fakeBiometricSettingsRepository.setIsFaceAuthEnrolledAndEnabled(false)
            kosmos.fakeBiometricSettingsRepository.setIsFingerprintAuthEnrolledAndEnabled(false)
            kosmos.fakeTrustRepository.setTrustUsuallyManaged(false)
            runCurrent()

            verifyRestrictionReasonsForAuthFlags(
                LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_BOOT to null,
                LockPatternUtils.StrongAuthTracker.SOME_AUTH_REQUIRED_AFTER_USER_REQUEST to null,
                LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_LOCKOUT to null,
                LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_TIMEOUT to null,
                LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN to null,
                LockPatternUtils.StrongAuthTracker
                    .STRONG_AUTH_REQUIRED_AFTER_NON_STRONG_BIOMETRICS_TIMEOUT to null,
                LockPatternUtils.StrongAuthTracker.SOME_AUTH_REQUIRED_AFTER_TRUSTAGENT_EXPIRED to
                    null,
                LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_FOR_UNATTENDED_UPDATE to
                    null,
                LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW to null
            )
        }

    @Test
    fun deviceEntryRestrictionReason_whenFaceIsEnrolledAndEnabled_mapsToAuthFlagsState() =
        testScope.runTest {
            kosmos.fakeBiometricSettingsRepository.setIsFaceAuthEnrolledAndEnabled(true)
            kosmos.fakeBiometricSettingsRepository.setIsFingerprintAuthEnrolledAndEnabled(false)
            kosmos.fakeTrustRepository.setTrustUsuallyManaged(false)
            kosmos.fakeSystemPropertiesHelper.set(
                DeviceEntryInteractor.SYS_BOOT_REASON_PROP,
                "not mainline reboot"
            )
            runCurrent()

            verifyRestrictionReasonsForAuthFlags(
                LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_BOOT to
                    DeviceNotUnlockedSinceReboot,
                LockPatternUtils.StrongAuthTracker.SOME_AUTH_REQUIRED_AFTER_ADAPTIVE_AUTH_REQUEST to
                    AdaptiveAuthRequest,
                LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_LOCKOUT to
                    BouncerLockedOut,
                LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_TIMEOUT to
                    SecurityTimeout,
                LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN to
                    UserLockdown,
                LockPatternUtils.StrongAuthTracker
                    .STRONG_AUTH_REQUIRED_AFTER_NON_STRONG_BIOMETRICS_TIMEOUT to
                    NonStrongBiometricsSecurityTimeout,
                LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_FOR_UNATTENDED_UPDATE to
                    UnattendedUpdate,
                LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW to
                    PolicyLockdown,
                LockPatternUtils.StrongAuthTracker.SOME_AUTH_REQUIRED_AFTER_USER_REQUEST to null,
                LockPatternUtils.StrongAuthTracker.SOME_AUTH_REQUIRED_AFTER_TRUSTAGENT_EXPIRED to
                    null,
            )
        }

    @Test
    fun deviceEntryRestrictionReason_whenFingerprintIsEnrolledAndEnabled_mapsToAuthFlagsState() =
        testScope.runTest {
            kosmos.fakeBiometricSettingsRepository.setIsFaceAuthEnrolledAndEnabled(false)
            kosmos.fakeBiometricSettingsRepository.setIsFingerprintAuthEnrolledAndEnabled(true)
            kosmos.fakeTrustRepository.setTrustUsuallyManaged(false)
            kosmos.fakeSystemPropertiesHelper.set(
                DeviceEntryInteractor.SYS_BOOT_REASON_PROP,
                "not mainline reboot"
            )
            runCurrent()

            verifyRestrictionReasonsForAuthFlags(
                LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_BOOT to
                    DeviceNotUnlockedSinceReboot,
                LockPatternUtils.StrongAuthTracker.SOME_AUTH_REQUIRED_AFTER_ADAPTIVE_AUTH_REQUEST to
                    AdaptiveAuthRequest,
                LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_LOCKOUT to
                    BouncerLockedOut,
                LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_TIMEOUT to
                    SecurityTimeout,
                LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN to
                    UserLockdown,
                LockPatternUtils.StrongAuthTracker
                    .STRONG_AUTH_REQUIRED_AFTER_NON_STRONG_BIOMETRICS_TIMEOUT to
                    NonStrongBiometricsSecurityTimeout,
                LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_FOR_UNATTENDED_UPDATE to
                    UnattendedUpdate,
                LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW to
                    PolicyLockdown,
                LockPatternUtils.StrongAuthTracker.SOME_AUTH_REQUIRED_AFTER_USER_REQUEST to null,
                LockPatternUtils.StrongAuthTracker.SOME_AUTH_REQUIRED_AFTER_TRUSTAGENT_EXPIRED to
                    null,
            )
        }

    @Test
    fun deviceEntryRestrictionReason_whenTrustAgentIsEnabled_mapsToAuthFlagsState() =
        testScope.runTest {
            kosmos.fakeBiometricSettingsRepository.setIsFaceAuthEnrolledAndEnabled(false)
            kosmos.fakeBiometricSettingsRepository.setIsFingerprintAuthEnrolledAndEnabled(false)
            kosmos.fakeTrustRepository.setTrustUsuallyManaged(true)
            kosmos.fakeTrustRepository.setCurrentUserTrustManaged(false)
            kosmos.fakeSystemPropertiesHelper.set(
                DeviceEntryInteractor.SYS_BOOT_REASON_PROP,
                "not mainline reboot"
            )
            runCurrent()

            verifyRestrictionReasonsForAuthFlags(
                LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_BOOT to
                    DeviceNotUnlockedSinceReboot,
                LockPatternUtils.StrongAuthTracker.SOME_AUTH_REQUIRED_AFTER_ADAPTIVE_AUTH_REQUEST to
                    AdaptiveAuthRequest,
                LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_LOCKOUT to
                    BouncerLockedOut,
                LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_TIMEOUT to
                    SecurityTimeout,
                LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN to
                    UserLockdown,
                LockPatternUtils.StrongAuthTracker
                    .STRONG_AUTH_REQUIRED_AFTER_NON_STRONG_BIOMETRICS_TIMEOUT to
                    NonStrongBiometricsSecurityTimeout,
                LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_FOR_UNATTENDED_UPDATE to
                    UnattendedUpdate,
                LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW to
                    PolicyLockdown,
                LockPatternUtils.StrongAuthTracker.SOME_AUTH_REQUIRED_AFTER_USER_REQUEST to
                    TrustAgentDisabled,
                LockPatternUtils.StrongAuthTracker.SOME_AUTH_REQUIRED_AFTER_TRUSTAGENT_EXPIRED to
                    TrustAgentDisabled,
            )
        }

    @Test
    fun deviceEntryRestrictionReason_whenDeviceRebootedForMainlineUpdate_mapsToTheCorrectReason() =
        testScope.runTest {
            val deviceEntryRestrictionReason by
                collectLastValue(underTest.deviceEntryRestrictionReason)
            kosmos.fakeSystemPropertiesHelper.set(
                DeviceEntryInteractor.SYS_BOOT_REASON_PROP,
                DeviceEntryInteractor.REBOOT_MAINLINE_UPDATE
            )
            kosmos.fakeBiometricSettingsRepository.setAuthenticationFlags(
                AuthenticationFlags(
                    userId = 1,
                    flag = LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_BOOT
                )
            )
            runCurrent()

            kosmos.fakeBiometricSettingsRepository.setIsFaceAuthEnrolledAndEnabled(false)
            kosmos.fakeBiometricSettingsRepository.setIsFingerprintAuthEnrolledAndEnabled(false)
            kosmos.fakeTrustRepository.setTrustUsuallyManaged(false)
            runCurrent()

            assertThat(deviceEntryRestrictionReason).isNull()

            kosmos.fakeBiometricSettingsRepository.setIsFaceAuthEnrolledAndEnabled(true)
            runCurrent()

            assertThat(deviceEntryRestrictionReason)
                .isEqualTo(DeviceEntryRestrictionReason.DeviceNotUnlockedSinceMainlineUpdate)

            kosmos.fakeBiometricSettingsRepository.setIsFaceAuthEnrolledAndEnabled(false)
            kosmos.fakeBiometricSettingsRepository.setIsFingerprintAuthEnrolledAndEnabled(true)
            runCurrent()

            assertThat(deviceEntryRestrictionReason)
                .isEqualTo(DeviceEntryRestrictionReason.DeviceNotUnlockedSinceMainlineUpdate)

            kosmos.fakeBiometricSettingsRepository.setIsFingerprintAuthEnrolledAndEnabled(false)
            kosmos.fakeTrustRepository.setTrustUsuallyManaged(true)
            runCurrent()

            assertThat(deviceEntryRestrictionReason)
                .isEqualTo(DeviceEntryRestrictionReason.DeviceNotUnlockedSinceMainlineUpdate)
        }

    private fun TestScope.verifyRestrictionReasonsForAuthFlags(
        vararg authFlagToDeviceEntryRestriction: Pair<Int, DeviceEntryRestrictionReason?>
    ) {
        val deviceEntryRestrictionReason by collectLastValue(underTest.deviceEntryRestrictionReason)

        authFlagToDeviceEntryRestriction.forEach { (flag, expectedReason) ->
            kosmos.fakeBiometricSettingsRepository.setAuthenticationFlags(
                AuthenticationFlags(userId = 1, flag = flag)
            )
            runCurrent()

            if (expectedReason == null) {
                assertThat(deviceEntryRestrictionReason).isNull()
            } else {
                assertThat(deviceEntryRestrictionReason).isEqualTo(expectedReason)
            }
        }
    }

    private fun switchToScene(sceneKey: SceneKey) {
        sceneInteractor.changeScene(sceneKey, "reason")
    }
+1 −1
Original line number Diff line number Diff line
@@ -54,7 +54,7 @@ class ShadeControllerSceneImplTest : SysuiTestCase() {
    private val kosmos = Kosmos()
    private val testScope = kosmos.testScope
    private val sceneInteractor = kosmos.sceneInteractor
    private val deviceEntryInteractor = kosmos.deviceEntryInteractor
    private val deviceEntryInteractor by lazy { kosmos.deviceEntryInteractor }

    private lateinit var shadeInteractor: ShadeInteractor
    private lateinit var underTest: ShadeControllerSceneImpl
+1 −1
Original line number Diff line number Diff line
@@ -177,7 +177,7 @@ constructor(
                        )
                        .toMessage()
                } else if (
                    trustOrBiometricsAvailable && flags.primaryAuthRequiredForUnattendedUpdate
                    trustOrBiometricsAvailable && flags.isPrimaryAuthRequiredForUnattendedUpdate
                ) {
                    BouncerMessageStrings.authRequiredForUnattendedUpdate(
                            currentSecurityMode.toAuthModel()
+84 −6
Original line number Diff line number Diff line
@@ -16,24 +16,30 @@

package com.android.systemui.deviceentry.domain.interactor

import androidx.annotation.VisibleForTesting
import com.android.systemui.authentication.domain.interactor.AuthenticationInteractor
import com.android.systemui.authentication.shared.model.AuthenticationMethodModel
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.deviceentry.data.repository.DeviceEntryFaceAuthRepository
import com.android.systemui.deviceentry.data.repository.DeviceEntryRepository
import com.android.systemui.keyguard.data.repository.TrustRepository
import com.android.systemui.deviceentry.shared.model.DeviceEntryRestrictionReason
import com.android.systemui.flags.SystemPropertiesHelper
import com.android.systemui.keyguard.domain.interactor.TrustInteractor
import com.android.systemui.scene.domain.interactor.SceneInteractor
import com.android.systemui.scene.shared.flag.SceneContainerFlags
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.util.kotlin.Quad
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.merge
import kotlinx.coroutines.flow.onStart
@@ -55,10 +61,13 @@ constructor(
    private val repository: DeviceEntryRepository,
    private val authenticationInteractor: AuthenticationInteractor,
    private val sceneInteractor: SceneInteractor,
    deviceEntryFaceAuthRepository: DeviceEntryFaceAuthRepository,
    trustRepository: TrustRepository,
    faceAuthInteractor: DeviceEntryFaceAuthInteractor,
    private val fingerprintAuthInteractor: DeviceEntryFingerprintAuthInteractor,
    private val biometricSettingsInteractor: DeviceEntryBiometricSettingsInteractor,
    private val trustInteractor: TrustInteractor,
    flags: SceneContainerFlags,
    deviceUnlockedInteractor: DeviceUnlockedInteractor,
    private val systemPropertiesHelper: SystemPropertiesHelper,
) {
    /**
     * Whether the device is unlocked.
@@ -96,8 +105,8 @@ constructor(
     */
    private val isPassivelyAuthenticated =
        merge(
                trustRepository.isCurrentUserTrusted,
                deviceEntryFaceAuthRepository.isAuthenticated,
                trustInteractor.isTrusted,
                faceAuthInteractor.authenticated,
            )
            .onStart { emit(false) }

@@ -134,6 +143,67 @@ constructor(
                initialValue = null,
            )

    private val faceEnrolledAndEnabled = biometricSettingsInteractor.isFaceAuthEnrolledAndEnabled
    private val fingerprintEnrolledAndEnabled =
        biometricSettingsInteractor.isFingerprintAuthEnrolledAndEnabled
    private val trustAgentEnabled = trustInteractor.isEnrolledAndEnabled

    private val faceOrFingerprintOrTrustEnabled: Flow<Triple<Boolean, Boolean, Boolean>> =
        combine(faceEnrolledAndEnabled, fingerprintEnrolledAndEnabled, trustAgentEnabled, ::Triple)

    /**
     * Reason why device entry is restricted to certain authentication methods for the current user.
     *
     * Emits null when there are no device entry restrictions active.
     */
    val deviceEntryRestrictionReason: Flow<DeviceEntryRestrictionReason?> =
        faceOrFingerprintOrTrustEnabled.flatMapLatest {
            (faceEnabled, fingerprintEnabled, trustEnabled) ->
            if (faceEnabled || fingerprintEnabled || trustEnabled) {
                combine(
                        biometricSettingsInteractor.authenticationFlags,
                        faceAuthInteractor.lockedOut,
                        fingerprintAuthInteractor.isLockedOut,
                        trustInteractor.isTrustAgentCurrentlyAllowed,
                        ::Quad
                    )
                    .map { (authFlags, isFaceLockedOut, isFingerprintLockedOut, trustManaged) ->
                        when {
                            authFlags.isPrimaryAuthRequiredAfterReboot &&
                                wasRebootedForMainlineUpdate ->
                                DeviceEntryRestrictionReason.DeviceNotUnlockedSinceMainlineUpdate
                            authFlags.isPrimaryAuthRequiredAfterReboot ->
                                DeviceEntryRestrictionReason.DeviceNotUnlockedSinceReboot
                            authFlags.isPrimaryAuthRequiredAfterDpmLockdown ->
                                DeviceEntryRestrictionReason.PolicyLockdown
                            authFlags.isInUserLockdown -> DeviceEntryRestrictionReason.UserLockdown
                            authFlags.isPrimaryAuthRequiredForUnattendedUpdate ->
                                DeviceEntryRestrictionReason.UnattendedUpdate
                            authFlags.isPrimaryAuthRequiredAfterTimeout ->
                                DeviceEntryRestrictionReason.SecurityTimeout
                            authFlags.isPrimaryAuthRequiredAfterLockout ->
                                DeviceEntryRestrictionReason.BouncerLockedOut
                            isFingerprintLockedOut ->
                                DeviceEntryRestrictionReason.StrongBiometricsLockedOut
                            isFaceLockedOut && faceAuthInteractor.isFaceAuthStrong() ->
                                DeviceEntryRestrictionReason.StrongBiometricsLockedOut
                            isFaceLockedOut -> DeviceEntryRestrictionReason.NonStrongFaceLockedOut
                            authFlags.isSomeAuthRequiredAfterAdaptiveAuthRequest ->
                                DeviceEntryRestrictionReason.AdaptiveAuthRequest
                            (trustEnabled && !trustManaged) &&
                                (authFlags.someAuthRequiredAfterTrustAgentExpired ||
                                    authFlags.someAuthRequiredAfterUserRequest) ->
                                DeviceEntryRestrictionReason.TrustAgentDisabled
                            authFlags.strongerAuthRequiredAfterNonStrongBiometricsTimeout ->
                                DeviceEntryRestrictionReason.NonStrongBiometricsSecurityTimeout
                            else -> null
                        }
                    }
            } else {
                flowOf(null)
            }
        }

    /**
     * Attempt to enter the device and dismiss the lockscreen. If authentication is required to
     * unlock the device it will transition to bouncer.
@@ -187,4 +257,12 @@ constructor(
            }
        }
    }

    private val wasRebootedForMainlineUpdate
        get() = systemPropertiesHelper.get(SYS_BOOT_REASON_PROP) == REBOOT_MAINLINE_UPDATE

    companion object {
        @VisibleForTesting const val SYS_BOOT_REASON_PROP = "sys.boot.reason.last"
        @VisibleForTesting const val REBOOT_MAINLINE_UPDATE = "reboot,mainline_update"
    }
}
+119 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.systemui.deviceentry.shared.model

/** List of reasons why device entry can be restricted to certain authentication methods. */
enum class DeviceEntryRestrictionReason {
    /**
     * Reason: Lockdown initiated by the user.
     *
     * Restriction: Only bouncer based device entry is allowed.
     */
    UserLockdown,

    /**
     * Reason: Not unlocked since reboot.
     *
     * Restriction: Only bouncer based device entry is allowed.
     */
    DeviceNotUnlockedSinceReboot,

    /**
     * Reason: Not unlocked since reboot after a mainline update.
     *
     * Restriction: Only bouncer based device entry is allowed.
     */
    DeviceNotUnlockedSinceMainlineUpdate,

    /**
     * Reason: Lockdown initiated by admin through installed device policy
     *
     * Restriction: Only bouncer based device entry is allowed.
     */
    PolicyLockdown,

    /**
     * Reason: Device entry credentials need to be used for an unattended update at a later point in
     * time.
     *
     * Restriction: Only bouncer based device entry is allowed.
     */
    UnattendedUpdate,

    /**
     * Reason: Device was not unlocked using PIN/Pattern/Password for a prolonged period of time.
     *
     * Restriction: Only bouncer based device entry is allowed.
     */
    SecurityTimeout,

    /**
     * Reason: A "class 3"/strong biometrics device entry method was locked out after many incorrect
     * authentication attempts.
     *
     * Restriction: Only bouncer based device entry is allowed.
     *
     * @see
     *   [Biometric classes](https://source.android.com/docs/security/features/biometric/measure#biometric-classes)
     */
    StrongBiometricsLockedOut,

    /**
     * Reason: A weak (class 2)/convenience (class 3) strength face biometrics device entry method
     * was locked out after many incorrect authentication attempts.
     *
     * Restriction: Only stronger authentication methods (class 3 or bouncer) are allowed.
     *
     * @see
     *   [Biometric classes](https://source.android.com/docs/security/features/biometric/measure#biometric-classes)
     */
    NonStrongFaceLockedOut,

    /**
     * Reason: Device was last unlocked using a weak/convenience strength biometrics device entry
     * method and a stronger authentication method wasn't used to unlock the device for a prolonged
     * period of time.
     *
     * Restriction: Only stronger authentication methods (class 3 or bouncer) are allowed.
     *
     * @see
     *   [Biometric classes](https://source.android.com/docs/security/features/biometric/measure#biometric-classes)
     */
    NonStrongBiometricsSecurityTimeout,

    /**
     * Reason: A trust agent that was granting trust has either expired or disabled by the user by
     * opening the power menu.
     *
     * Restriction: Only non trust agent device entry methods are allowed.
     */
    TrustAgentDisabled,

    /**
     * Reason: Theft protection is enabled after too many unlock attempts.
     *
     * Restriction: Only stronger authentication methods (class 3 or bouncer) are allowed.
     */
    AdaptiveAuthRequest,

    /**
     * Reason: Bouncer was locked out after too many incorrect authentication attempts.
     *
     * Restriction: Only bouncer based device entry is allowed.
     */
    BouncerLockedOut,
}
Loading