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

Commit c2e4335f authored by Beverly's avatar Beverly
Browse files

Run face auth after sim pin success

Test: enroll face; add SIM with pin to device;
see SIM PIN bouncer; enter SIM pin; observe face
auth runs
Test: atest DeviceEntryFaceAuthInteractorTest
Fixes: 419405950
Flag: EXEMPT bugfix

Change-Id: I8c57eb56aba5d4fc5650a1a75975ae94f415d149
parent 2397c213
Loading
Loading
Loading
Loading
+22 −0
Original line number Diff line number Diff line
@@ -67,6 +67,8 @@ import com.android.systemui.scene.shared.model.Overlays
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.shade.domain.interactor.enableDualShade
import com.android.systemui.shade.domain.interactor.enableSingleShade
import com.android.systemui.statusbar.pipeline.mobile.data.repository.fakeMobileConnectionsRepository
import com.android.systemui.statusbar.pipeline.mobile.data.repository.mobileConnectionsRepository
import com.android.systemui.testKosmos
import com.android.systemui.user.data.model.SelectionStatus
import com.android.systemui.user.data.repository.fakeUserRepository
@@ -115,6 +117,7 @@ class DeviceEntryFaceAuthInteractorTest : SysuiTestCase() {
                    { sceneInteractor },
                    deviceEntryFaceAuthStatusInteractor,
                    cameraSensorPrivacyInteractor,
                    mobileConnectionsRepository,
                )
            }
    }
@@ -864,6 +867,25 @@ class DeviceEntryFaceAuthInteractorTest : SysuiTestCase() {
                .isSameInstanceAs(faceAuthRepository.isAuthenticated)
        }

    @Test
    fun faceAuthIsRequestedOnSimPinSuccess() =
        kosmos.runTest {
            underTest.start()
            runCurrent()

            // no auth request when the SIM is secure (requires pin)
            fakeMobileConnectionsRepository.isAnySimSecure.value = true
            runCurrent()
            assertThat(faceAuthRepository.runningAuthRequest.value).isNull()

            // auth request when the SIM is no longer secure (successful pin!)
            fakeMobileConnectionsRepository.isAnySimSecure.value = false
            runCurrent()

            assertThat(faceAuthRepository.runningAuthRequest.value)
                .isEqualTo(Pair(FaceAuthUiEvent.FACE_AUTH_SIM_PIN_SUCCESS, true))
        }

    companion object {
        private const val primaryUserId = 1
        private val primaryUser = UserInfo(primaryUserId, "test user", UserInfo.FLAG_PRIMARY)
+17 −0
Original line number Diff line number Diff line
@@ -55,6 +55,7 @@ import com.android.systemui.scene.domain.interactor.SceneInteractor
import com.android.systemui.scene.shared.flag.SceneContainerFlag
import com.android.systemui.scene.shared.model.Overlays
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionsRepository
import com.android.systemui.user.data.model.SelectionStatus
import com.android.systemui.user.data.repository.UserRepository
import com.android.systemui.util.kotlin.pairwise
@@ -110,6 +111,7 @@ constructor(
    private val sceneInteractor: Lazy<SceneInteractor>,
    deviceEntryFaceAuthStatusInteractor: DeviceEntryFaceAuthStatusInteractor,
    cameraSensorPrivacyInteractor: CameraSensorPrivacyInteractor,
    private val mobileConnectionsRepository: MobileConnectionsRepository,
) : DeviceEntryFaceAuthInteractor {

    private val listeners: MutableList<FaceAuthenticationListener> = mutableListOf()
@@ -198,6 +200,13 @@ constructor(
            }
            .launchIn(applicationScope)

        mobileConnectionsRepository.isAnySimSecure
            .whenItFlipsToFalse()
            .onEach {
                runFaceAuth(FaceAuthUiEvent.FACE_AUTH_SIM_PIN_SUCCESS, fallbackToDetect = true)
            }
            .launchIn(applicationScope)

        deviceEntryFingerprintAuthInteractor.isLockedOut
            .sample(biometricSettingsRepository.isFaceAuthEnrolledAndEnabled, ::Pair)
            .filter { (_, faceEnabledAndEnrolled) ->
@@ -484,3 +493,11 @@ private fun Flow<Boolean>.whenItFlipsToTrue(): Flow<Boolean> {
        .filter { pair -> !pair.previousValue && pair.newValue }
        .map { it.newValue }
}

// Extension method that filters a generic Boolean flow to one that emits
// whenever there is flip from true -> false
private fun Flow<Boolean>.whenItFlipsToFalse(): Flow<Boolean> {
    return this.pairwise()
        .filter { pair -> pair.previousValue && !pair.newValue }
        .map { it.newValue }
}
+4 −1
Original line number Diff line number Diff line
@@ -57,6 +57,7 @@ import com.android.systemui.deviceentry.shared.InternalFaceAuthReasons.POSTURE_C
import com.android.systemui.deviceentry.shared.InternalFaceAuthReasons.PRIMARY_BOUNCER_SHOWN
import com.android.systemui.deviceentry.shared.InternalFaceAuthReasons.PRIMARY_BOUNCER_SHOWN_OR_WILL_BE_SHOWN
import com.android.systemui.deviceentry.shared.InternalFaceAuthReasons.RETRY_AFTER_HW_UNAVAILABLE
import com.android.systemui.deviceentry.shared.InternalFaceAuthReasons.SIM_PIN_SUCCESS
import com.android.systemui.deviceentry.shared.InternalFaceAuthReasons.STARTED_WAKING_UP
import com.android.systemui.deviceentry.shared.InternalFaceAuthReasons.STRONG_AUTH_ALLOWED_CHANGED
import com.android.systemui.deviceentry.shared.InternalFaceAuthReasons.TRUST_DISABLED
@@ -133,6 +134,7 @@ private object InternalFaceAuthReasons {
    const val POSTURE_CHANGED = "Face auth started/stopped due to device posture changed."
    const val DISPLAY_OFF = "Face auth stopped due to display state OFF."
    const val CAMERA_AVAILABLE_CHANGED = "Face auth started due to the available camera changed"
    const val SIM_PIN_SUCCESS = "Face auth started due to SIM pin success"
}

/**
@@ -226,7 +228,8 @@ constructor(private val id: Int, val reason: String, var extraInfo: Int = 0) :
    @UiEvent(doc = ACCESSIBILITY_ACTION) FACE_AUTH_ACCESSIBILITY_ACTION(1454, ACCESSIBILITY_ACTION),
    @UiEvent(doc = DISPLAY_OFF) FACE_AUTH_DISPLAY_OFF(1461, DISPLAY_OFF),
    @UiEvent(doc = CAMERA_AVAILABLE_CHANGED)
    FACE_AUTH_CAMERA_AVAILABLE_CHANGED(1623, CAMERA_AVAILABLE_CHANGED);
    FACE_AUTH_CAMERA_AVAILABLE_CHANGED(1623, CAMERA_AVAILABLE_CHANGED),
    @UiEvent(doc = SIM_PIN_SUCCESS) FACE_AUTH_SIM_PIN_SUCCESS(2403, SIM_PIN_SUCCESS);

    override fun getId(): Int = this.id

+2 −0
Original line number Diff line number Diff line
@@ -33,6 +33,7 @@ import com.android.systemui.kosmos.testDispatcher
import com.android.systemui.log.FaceAuthenticationLogger
import com.android.systemui.power.domain.interactor.powerInteractor
import com.android.systemui.scene.domain.interactor.sceneInteractor
import com.android.systemui.statusbar.pipeline.mobile.data.repository.mobileConnectionsRepository
import com.android.systemui.user.data.repository.userRepository
import com.android.systemui.util.mockito.mock

@@ -59,5 +60,6 @@ val Kosmos.deviceEntryFaceAuthInteractor by
            sceneInteractor = { sceneInteractor },
            deviceEntryFaceAuthStatusInteractor = deviceEntryFaceAuthStatusInteractor,
            cameraSensorPrivacyInteractor = cameraSensorPrivacyInteractor,
            mobileConnectionsRepository = mobileConnectionsRepository,
        )
    }