Loading packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/BiometricMessageInteractorTest.kt +43 −15 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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 Loading @@ -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 Loading Loading @@ -76,7 +80,7 @@ class BiometricMessageInteractorTest : SysuiTestCase() { fingerprintAuthRepository.setAuthenticationStatus( ErrorFingerprintAuthenticationStatus( msgId = FingerprintManager.FINGERPRINT_ERROR_HW_UNAVAILABLE, msg = "test" msg = "test", ) ) Loading @@ -96,7 +100,7 @@ class BiometricMessageInteractorTest : SysuiTestCase() { fingerprintAuthRepository.setAuthenticationStatus( ErrorFingerprintAuthenticationStatus( msgId = FingerprintManager.FINGERPRINT_ERROR_LOCKOUT, msg = "lockout" msg = "lockout", ) ) Loading @@ -114,7 +118,7 @@ class BiometricMessageInteractorTest : SysuiTestCase() { fingerprintAuthRepository.setAuthenticationStatus( ErrorFingerprintAuthenticationStatus( msgId = FingerprintManager.FINGERPRINT_ERROR_HW_UNAVAILABLE, msg = "test" msg = "test", ) ) Loading @@ -134,7 +138,7 @@ class BiometricMessageInteractorTest : SysuiTestCase() { fingerprintAuthRepository.setAuthenticationStatus( HelpFingerprintAuthenticationStatus( msgId = FingerprintManager.FINGERPRINT_ACQUIRED_IMAGER_DIRTY, msg = "test" msg = "test", ) ) Loading @@ -154,7 +158,7 @@ class BiometricMessageInteractorTest : SysuiTestCase() { fingerprintAuthRepository.setAuthenticationStatus( HelpFingerprintAuthenticationStatus( msgId = FingerprintManager.FINGERPRINT_ACQUIRED_IMAGER_DIRTY, msg = "test" msg = "test", ) ) Loading @@ -172,7 +176,7 @@ class BiometricMessageInteractorTest : SysuiTestCase() { 0, SensorStrength.STRONG, FingerprintSensorType.REAR, mapOf() mapOf(), ) // GIVEN fingerprint is allowed Loading Loading @@ -200,7 +204,7 @@ class BiometricMessageInteractorTest : SysuiTestCase() { 0, SensorStrength.STRONG, FingerprintSensorType.UDFPS_OPTICAL, mapOf() mapOf(), ) // GIVEN fingerprint is allowed Loading Loading @@ -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 Loading @@ -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 Loading Loading @@ -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 { Loading packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryFaceAuthInteractorTest.kt +2 −0 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -132,6 +133,7 @@ class DeviceEntryFaceAuthInteractorTest : SysuiTestCase() { trustManager, { kosmos.sceneInteractor }, deviceEntryFaceAuthStatusInteractor, kosmos.cameraSensorPrivacyInteractor, ) } Loading packages/SystemUI/src/com/android/systemui/biometrics/dagger/BiometricsModule.kt +2 −1 Original line number Diff line number Diff line Loading @@ -42,6 +42,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.dagger.SystemUIDisplaySubcomponent import com.android.systemui.display.data.repository.DisplayStateRepository Loading @@ -59,7 +60,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 Loading packages/SystemUI/src/com/android/systemui/camera/CameraRotationModule.kt +1 −5 Original line number Diff line number Diff line Loading @@ -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 } packages/SystemUI/src/com/android/systemui/camera/CameraSensorPrivacyModule.kt 0 → 100644 +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
packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/BiometricMessageInteractorTest.kt +43 −15 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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 Loading @@ -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 Loading Loading @@ -76,7 +80,7 @@ class BiometricMessageInteractorTest : SysuiTestCase() { fingerprintAuthRepository.setAuthenticationStatus( ErrorFingerprintAuthenticationStatus( msgId = FingerprintManager.FINGERPRINT_ERROR_HW_UNAVAILABLE, msg = "test" msg = "test", ) ) Loading @@ -96,7 +100,7 @@ class BiometricMessageInteractorTest : SysuiTestCase() { fingerprintAuthRepository.setAuthenticationStatus( ErrorFingerprintAuthenticationStatus( msgId = FingerprintManager.FINGERPRINT_ERROR_LOCKOUT, msg = "lockout" msg = "lockout", ) ) Loading @@ -114,7 +118,7 @@ class BiometricMessageInteractorTest : SysuiTestCase() { fingerprintAuthRepository.setAuthenticationStatus( ErrorFingerprintAuthenticationStatus( msgId = FingerprintManager.FINGERPRINT_ERROR_HW_UNAVAILABLE, msg = "test" msg = "test", ) ) Loading @@ -134,7 +138,7 @@ class BiometricMessageInteractorTest : SysuiTestCase() { fingerprintAuthRepository.setAuthenticationStatus( HelpFingerprintAuthenticationStatus( msgId = FingerprintManager.FINGERPRINT_ACQUIRED_IMAGER_DIRTY, msg = "test" msg = "test", ) ) Loading @@ -154,7 +158,7 @@ class BiometricMessageInteractorTest : SysuiTestCase() { fingerprintAuthRepository.setAuthenticationStatus( HelpFingerprintAuthenticationStatus( msgId = FingerprintManager.FINGERPRINT_ACQUIRED_IMAGER_DIRTY, msg = "test" msg = "test", ) ) Loading @@ -172,7 +176,7 @@ class BiometricMessageInteractorTest : SysuiTestCase() { 0, SensorStrength.STRONG, FingerprintSensorType.REAR, mapOf() mapOf(), ) // GIVEN fingerprint is allowed Loading Loading @@ -200,7 +204,7 @@ class BiometricMessageInteractorTest : SysuiTestCase() { 0, SensorStrength.STRONG, FingerprintSensorType.UDFPS_OPTICAL, mapOf() mapOf(), ) // GIVEN fingerprint is allowed Loading Loading @@ -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 Loading @@ -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 Loading Loading @@ -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 { Loading
packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryFaceAuthInteractorTest.kt +2 −0 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -132,6 +133,7 @@ class DeviceEntryFaceAuthInteractorTest : SysuiTestCase() { trustManager, { kosmos.sceneInteractor }, deviceEntryFaceAuthStatusInteractor, kosmos.cameraSensorPrivacyInteractor, ) } Loading
packages/SystemUI/src/com/android/systemui/biometrics/dagger/BiometricsModule.kt +2 −1 Original line number Diff line number Diff line Loading @@ -42,6 +42,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.dagger.SystemUIDisplaySubcomponent import com.android.systemui.display.data.repository.DisplayStateRepository Loading @@ -59,7 +60,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 Loading
packages/SystemUI/src/com/android/systemui/camera/CameraRotationModule.kt +1 −5 Original line number Diff line number Diff line Loading @@ -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 }
packages/SystemUI/src/com/android/systemui/camera/CameraSensorPrivacyModule.kt 0 → 100644 +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 }