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

Commit 1bea97c9 authored by Beverly's avatar Beverly Committed by Beverly Tai
Browse files

Show cameraPrivacyEnabled message on bouncer when needed

This was working for the keyguard indication area
but not for the bouncer message. This updates the biometricMessage
to surface the cameraPrivacyEnabled messsage correctly.

Test: atest BiometricMessageInteractorTest
Fixes: 382105436
Flag: EXEMPT bugfix
Change-Id: I4c6c5da1ce91a9437be5ada6f181af051195c557
parent f225fe41
Loading
Loading
Loading
Loading
+43 −15
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ import android.hardware.biometrics.BiometricFaceConstants.FACE_ACQUIRED_TOO_RIGH
import android.hardware.biometrics.BiometricFaceConstants.FACE_ERROR_HW_UNAVAILABLE
import android.hardware.biometrics.BiometricFaceConstants.FACE_ERROR_TIMEOUT
import android.hardware.fingerprint.FingerprintManager
import android.os.UserHandle
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
@@ -29,6 +30,7 @@ import com.android.systemui.biometrics.data.repository.fingerprintPropertyReposi
import com.android.systemui.biometrics.domain.faceHelpMessageDeferral
import com.android.systemui.biometrics.shared.model.FingerprintSensorType
import com.android.systemui.biometrics.shared.model.SensorStrength
import com.android.systemui.camera.data.repository.fakeCameraSensorPrivacyRepository
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.deviceentry.shared.model.ErrorFaceAuthenticationStatus
import com.android.systemui.deviceentry.shared.model.FaceTimeoutMessage
@@ -37,12 +39,14 @@ import com.android.systemui.deviceentry.shared.model.FingerprintLockoutMessage
import com.android.systemui.deviceentry.shared.model.HelpFaceAuthenticationStatus
import com.android.systemui.keyguard.data.repository.biometricSettingsRepository
import com.android.systemui.keyguard.data.repository.deviceEntryFingerprintAuthRepository
import com.android.systemui.keyguard.data.repository.fakeBiometricSettingsRepository
import com.android.systemui.keyguard.data.repository.fakeDeviceEntryFaceAuthRepository
import com.android.systemui.keyguard.shared.model.ErrorFingerprintAuthenticationStatus
import com.android.systemui.keyguard.shared.model.FailFingerprintAuthenticationStatus
import com.android.systemui.keyguard.shared.model.HelpFingerprintAuthenticationStatus
import com.android.systemui.kosmos.testScope
import com.android.systemui.testKosmos
import com.android.systemui.user.data.repository.FakeUserRepository.Companion.DEFAULT_SELECTED_USER
import com.android.systemui.util.mockito.whenever
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.test.runCurrent
@@ -76,7 +80,7 @@ class BiometricMessageInteractorTest : SysuiTestCase() {
            fingerprintAuthRepository.setAuthenticationStatus(
                ErrorFingerprintAuthenticationStatus(
                    msgId = FingerprintManager.FINGERPRINT_ERROR_HW_UNAVAILABLE,
                    msg = "test"
                    msg = "test",
                )
            )

@@ -96,7 +100,7 @@ class BiometricMessageInteractorTest : SysuiTestCase() {
            fingerprintAuthRepository.setAuthenticationStatus(
                ErrorFingerprintAuthenticationStatus(
                    msgId = FingerprintManager.FINGERPRINT_ERROR_LOCKOUT,
                    msg = "lockout"
                    msg = "lockout",
                )
            )

@@ -114,7 +118,7 @@ class BiometricMessageInteractorTest : SysuiTestCase() {
            fingerprintAuthRepository.setAuthenticationStatus(
                ErrorFingerprintAuthenticationStatus(
                    msgId = FingerprintManager.FINGERPRINT_ERROR_HW_UNAVAILABLE,
                    msg = "test"
                    msg = "test",
                )
            )

@@ -134,7 +138,7 @@ class BiometricMessageInteractorTest : SysuiTestCase() {
            fingerprintAuthRepository.setAuthenticationStatus(
                HelpFingerprintAuthenticationStatus(
                    msgId = FingerprintManager.FINGERPRINT_ACQUIRED_IMAGER_DIRTY,
                    msg = "test"
                    msg = "test",
                )
            )

@@ -154,7 +158,7 @@ class BiometricMessageInteractorTest : SysuiTestCase() {
            fingerprintAuthRepository.setAuthenticationStatus(
                HelpFingerprintAuthenticationStatus(
                    msgId = FingerprintManager.FINGERPRINT_ACQUIRED_IMAGER_DIRTY,
                    msg = "test"
                    msg = "test",
                )
            )

@@ -172,7 +176,7 @@ class BiometricMessageInteractorTest : SysuiTestCase() {
                0,
                SensorStrength.STRONG,
                FingerprintSensorType.REAR,
                mapOf()
                mapOf(),
            )

            // GIVEN fingerprint is allowed
@@ -200,7 +204,7 @@ class BiometricMessageInteractorTest : SysuiTestCase() {
                0,
                SensorStrength.STRONG,
                FingerprintSensorType.UDFPS_OPTICAL,
                mapOf()
                mapOf(),
            )

            // GIVEN fingerprint is allowed
@@ -302,10 +306,7 @@ class BiometricMessageInteractorTest : SysuiTestCase() {

            // WHEN authentication status help
            faceAuthRepository.setAuthenticationStatus(
                HelpFaceAuthenticationStatus(
                    msg = "Move left",
                    msgId = FACE_ACQUIRED_TOO_RIGHT,
                )
                HelpFaceAuthenticationStatus(msg = "Move left", msgId = FACE_ACQUIRED_TOO_RIGHT)
            )

            // THEN fingerprintHelpMessage is NOT updated
@@ -327,10 +328,7 @@ class BiometricMessageInteractorTest : SysuiTestCase() {

            // WHEN authentication status help
            faceAuthRepository.setAuthenticationStatus(
                HelpFaceAuthenticationStatus(
                    msg = "Move left",
                    msgId = FACE_ACQUIRED_TOO_RIGHT,
                )
                HelpFaceAuthenticationStatus(msg = "Move left", msgId = FACE_ACQUIRED_TOO_RIGHT)
            )

            // THEN fingerprintHelpMessage is NOT updated
@@ -368,6 +366,36 @@ class BiometricMessageInteractorTest : SysuiTestCase() {
            assertThat(faceErrorMessage?.message).isEqualTo("test")
        }

    @Test
    fun faceError_hwUnavailable_cameraSensorPrivacyEnabledMessage() =
        testScope.runTest {
            val isCameraPrivacyInterfering by
                collectLastValue(kosmos.deviceEntryFaceAuthInteractor.isCameraPrivacyInterfering)
            assertThat(isCameraPrivacyInterfering).isFalse()

            val faceErrorMessage by collectLastValue(underTest.faceMessage)

            // GIVEN camera sensor privacy is enabled (interfering with face auth)
            kosmos.fakeBiometricSettingsRepository.setIsFaceAuthEnrolledAndEnabled(true)
            runCurrent()
            kosmos.fakeCameraSensorPrivacyRepository.setEnabled(
                UserHandle(DEFAULT_SELECTED_USER),
                true,
            )
            runCurrent()
            assertThat(isCameraPrivacyInterfering).isTrue()

            // WHEN authentication status error is FACE_ERROR_HW_UNAVAILABLE
            faceAuthRepository.setAuthenticationStatus(
                ErrorFaceAuthenticationStatus(msgId = FACE_ERROR_HW_UNAVAILABLE, msg = "test")
            )
            biometricSettingsRepository.setIsFaceAuthCurrentlyAllowed(true)

            // THEN faceErrorMessage is updated to camera privacy message
            assertThat(faceErrorMessage?.message).isNotNull()
            assertThat(faceErrorMessage?.message).isNotEqualTo("test")
        }

    @Test
    fun faceTimeoutErrorMessage() =
        testScope.runTest {
+2 −0
Original line number Diff line number Diff line
@@ -36,6 +36,7 @@ import com.android.systemui.biometrics.shared.model.SensorStrength
import com.android.systemui.bouncer.data.repository.fakeKeyguardBouncerRepository
import com.android.systemui.bouncer.domain.interactor.alternateBouncerInteractor
import com.android.systemui.bouncer.domain.interactor.primaryBouncerInteractor
import com.android.systemui.camera.domain.interactor.cameraSensorPrivacyInteractor
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.deviceentry.data.repository.fakeFaceWakeUpTriggersConfig
import com.android.systemui.deviceentry.shared.FaceAuthUiEvent
@@ -132,6 +133,7 @@ class DeviceEntryFaceAuthInteractorTest : SysuiTestCase() {
                trustManager,
                { kosmos.sceneInteractor },
                deviceEntryFaceAuthStatusInteractor,
                kosmos.cameraSensorPrivacyInteractor,
            )
    }

+2 −1
Original line number Diff line number Diff line
@@ -40,6 +40,7 @@ import com.android.systemui.biometrics.udfps.EllipseOverlapDetector
import com.android.systemui.biometrics.udfps.OverlapDetector
import com.android.systemui.biometrics.ui.binder.DeviceEntryUnlockTrackerViewBinder
import com.android.systemui.biometrics.ui.binder.SideFpsOverlayViewBinder
import com.android.systemui.camera.CameraSensorPrivacyModule
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.display.data.repository.DisplayStateRepository
import com.android.systemui.display.data.repository.DisplayStateRepositoryImpl
@@ -57,7 +58,7 @@ import java.util.concurrent.Executor
import javax.inject.Qualifier

/** Dagger module for all things biometric. */
@Module
@Module(includes = [CameraSensorPrivacyModule::class])
interface BiometricsModule {
    /** Starts AuthController. */
    @Binds
+1 −5
Original line number Diff line number Diff line
@@ -18,16 +18,12 @@ package com.android.systemui.camera

import com.android.systemui.camera.data.repository.CameraAutoRotateRepository
import com.android.systemui.camera.data.repository.CameraAutoRotateRepositoryImpl
import com.android.systemui.camera.data.repository.CameraSensorPrivacyRepository
import com.android.systemui.camera.data.repository.CameraSensorPrivacyRepositoryImpl
import dagger.Binds
import dagger.Module

/** Module for repositories that provide data regarding camera rotation state. */
@Module
@Module(includes = [CameraSensorPrivacyModule::class])
interface CameraRotationModule {

    @Binds
    fun bindsPrivacyRepoImpl(impl: CameraSensorPrivacyRepositoryImpl): CameraSensorPrivacyRepository
    @Binds fun bindsRotateRepoImpl(impl: CameraAutoRotateRepositoryImpl): CameraAutoRotateRepository
}
+30 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2025 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.camera

import com.android.systemui.camera.data.repository.CameraSensorPrivacyRepository
import com.android.systemui.camera.data.repository.CameraSensorPrivacyRepositoryImpl
import dagger.Binds
import dagger.Module

/** Module for repositories that provide data regarding camera sensor privacy state. */
@Module
interface CameraSensorPrivacyModule {

    @Binds
    fun bindsPrivacyRepoImpl(impl: CameraSensorPrivacyRepositoryImpl): CameraSensorPrivacyRepository
}
Loading