Loading packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewBinder.kt +17 −0 Original line number Diff line number Diff line Loading @@ -457,6 +457,23 @@ object BiometricViewBinder { } } } // Retry and confirmation when finger on sensor launch { combine( viewModel.canTryAgainNow, viewModel.hasFingerOnSensor, viewModel.isPendingConfirmation, ::Triple ) .collect { (canRetry, fingerAcquired, pendingConfirmation) -> if (canRetry && fingerAcquired) { legacyCallback.onButtonTryAgain() } else if (pendingConfirmation && fingerAcquired) { viewModel.confirmAuthenticated() } } } } } Loading packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModel.kt +22 −0 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ import android.content.pm.PackageManager import android.graphics.Rect import android.graphics.drawable.BitmapDrawable import android.graphics.drawable.Drawable import android.hardware.biometrics.BiometricFingerprintConstants import android.hardware.biometrics.BiometricPrompt import android.hardware.biometrics.Flags.customBiometricPrompt import android.hardware.biometrics.PromptContentView Loading @@ -31,6 +32,7 @@ import android.view.MotionEvent import com.android.systemui.Flags.bpTalkback import com.android.systemui.biometrics.UdfpsUtils import com.android.systemui.biometrics.Utils import com.android.systemui.biometrics.domain.interactor.BiometricStatusInteractor import com.android.systemui.biometrics.domain.interactor.DisplayStateInteractor import com.android.systemui.biometrics.domain.interactor.PromptSelectorInteractor import com.android.systemui.biometrics.domain.interactor.UdfpsOverlayInteractor Loading @@ -39,6 +41,7 @@ import com.android.systemui.biometrics.shared.model.BiometricModality import com.android.systemui.biometrics.shared.model.DisplayRotation import com.android.systemui.biometrics.shared.model.PromptKind import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.keyguard.shared.model.AcquiredFingerprintAuthenticationStatus import com.android.systemui.res.R import javax.inject.Inject import kotlinx.coroutines.Job Loading @@ -65,6 +68,7 @@ constructor( promptSelectorInteractor: PromptSelectorInteractor, @Application private val context: Context, private val udfpsOverlayInteractor: UdfpsOverlayInteractor, private val biometricStatusInteractor: BiometricStatusInteractor, private val udfpsUtils: UdfpsUtils ) { /** The set of modalities available for this prompt */ Loading Loading @@ -147,6 +151,24 @@ constructor( /** Fingerprint sensor state. */ val fingerprintStartMode: Flow<FingerprintStartMode> = _fingerprintStartMode.asStateFlow() /** Whether a finger has been acquired by the sensor */ // TODO(b/331948073): Add support for detecting SFPS finger without authentication running val hasFingerBeenAcquired: Flow<Boolean> = combine(biometricStatusInteractor.fingerprintAcquiredStatus, modalities) { status, modalities -> modalities.hasSfps && status is AcquiredFingerprintAuthenticationStatus && status.acquiredInfo == BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_START } .distinctUntilChanged() /** Whether there is currently a finger on the sensor */ val hasFingerOnSensor: Flow<Boolean> = combine(hasFingerBeenAcquired, _isOverlayTouched) { hasFingerBeenAcquired, overlayTouched -> hasFingerBeenAcquired || overlayTouched } private val _forceLargeSize = MutableStateFlow(false) private val _forceMediumSize = MutableStateFlow(false) Loading packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt +10 −0 Original line number Diff line number Diff line Loading @@ -15,6 +15,7 @@ */ package com.android.systemui.biometrics import android.app.ActivityTaskManager import android.app.admin.DevicePolicyManager import android.content.pm.PackageManager import android.hardware.biometrics.BiometricAuthenticator Loading @@ -41,9 +42,12 @@ import androidx.test.filters.SmallTest import com.android.internal.jank.InteractionJankMonitor import com.android.internal.widget.LockPatternUtils import com.android.systemui.SysuiTestCase import com.android.systemui.biometrics.data.repository.FakeBiometricStatusRepository import com.android.systemui.biometrics.data.repository.FakeDisplayStateRepository import com.android.systemui.biometrics.data.repository.FakeFingerprintPropertyRepository import com.android.systemui.biometrics.data.repository.FakePromptRepository import com.android.systemui.biometrics.domain.interactor.BiometricStatusInteractor import com.android.systemui.biometrics.domain.interactor.BiometricStatusInteractorImpl import com.android.systemui.biometrics.domain.interactor.DisplayStateInteractor import com.android.systemui.biometrics.domain.interactor.DisplayStateInteractorImpl import com.android.systemui.biometrics.domain.interactor.FakeCredentialInteractor Loading Loading @@ -116,10 +120,12 @@ open class AuthContainerViewTest : SysuiTestCase() { lateinit var selectedUserInteractor: SelectedUserInteractor @Mock private lateinit var packageManager: PackageManager @Mock private lateinit var activityTaskManager: ActivityTaskManager private val testScope = TestScope(StandardTestDispatcher()) private val fakeExecutor = FakeExecutor(FakeSystemClock()) private val biometricPromptRepository = FakePromptRepository() private val biometricStatusRepository = FakeBiometricStatusRepository() private val fingerprintRepository = FakeFingerprintPropertyRepository() private val displayStateRepository = FakeDisplayStateRepository() private val credentialInteractor = FakeCredentialInteractor() Loading @@ -139,6 +145,7 @@ open class AuthContainerViewTest : SysuiTestCase() { private lateinit var displayRepository: FakeDisplayRepository private lateinit var displayStateInteractor: DisplayStateInteractor private lateinit var udfpsOverlayInteractor: UdfpsOverlayInteractor private lateinit var biometricStatusInteractor: BiometricStatusInteractor private val credentialViewModel = CredentialViewModel(mContext, bpCredentialInteractor) private val defaultLogoIcon = context.getDrawable(R.drawable.ic_android) Loading @@ -164,6 +171,8 @@ open class AuthContainerViewTest : SysuiTestCase() { selectedUserInteractor, testScope.backgroundScope, ) biometricStatusInteractor = BiometricStatusInteractorImpl(activityTaskManager, biometricStatusRepository) // Set up default logo icon whenever(packageManager.getApplicationIcon(OP_PACKAGE_NAME)).thenReturn(defaultLogoIcon) context.setMockPackageManager(packageManager) Loading Loading @@ -577,6 +586,7 @@ open class AuthContainerViewTest : SysuiTestCase() { promptSelectorInteractor, context, udfpsOverlayInteractor, biometricStatusInteractor, udfpsUtils ), { credentialViewModel }, Loading packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModelTest.kt +33 −11 Original line number Diff line number Diff line Loading @@ -16,12 +16,14 @@ package com.android.systemui.biometrics.ui.viewmodel import android.app.ActivityTaskManager import android.content.pm.ApplicationInfo import android.content.pm.PackageManager import android.content.res.Configuration import android.graphics.Bitmap import android.graphics.Point import android.graphics.drawable.BitmapDrawable import android.hardware.biometrics.BiometricFingerprintConstants import android.hardware.biometrics.Flags.FLAG_CUSTOM_BIOMETRIC_PROMPT import android.hardware.biometrics.PromptContentItemBulletedText import android.hardware.biometrics.PromptContentView Loading @@ -38,9 +40,12 @@ import com.android.systemui.Flags.FLAG_BP_TALKBACK import com.android.systemui.SysuiTestCase import com.android.systemui.biometrics.AuthController import com.android.systemui.biometrics.UdfpsUtils import com.android.systemui.biometrics.data.repository.FakeBiometricStatusRepository import com.android.systemui.biometrics.data.repository.FakeDisplayStateRepository import com.android.systemui.biometrics.data.repository.FakeFingerprintPropertyRepository import com.android.systemui.biometrics.data.repository.FakePromptRepository import com.android.systemui.biometrics.domain.interactor.BiometricStatusInteractor import com.android.systemui.biometrics.domain.interactor.BiometricStatusInteractorImpl import com.android.systemui.biometrics.domain.interactor.DisplayStateInteractor import com.android.systemui.biometrics.domain.interactor.DisplayStateInteractorImpl import com.android.systemui.biometrics.domain.interactor.PromptSelectorInteractor Loading @@ -49,6 +54,7 @@ import com.android.systemui.biometrics.domain.interactor.UdfpsOverlayInteractor import com.android.systemui.biometrics.extractAuthenticatorTypes import com.android.systemui.biometrics.faceSensorPropertiesInternal import com.android.systemui.biometrics.fingerprintSensorPropertiesInternal import com.android.systemui.biometrics.shared.model.AuthenticationReason import com.android.systemui.biometrics.shared.model.BiometricModalities import com.android.systemui.biometrics.shared.model.BiometricModality import com.android.systemui.biometrics.shared.model.DisplayRotation Loading @@ -57,6 +63,7 @@ import com.android.systemui.biometrics.shared.model.toSensorType import com.android.systemui.coroutines.collectLastValue import com.android.systemui.coroutines.collectValues import com.android.systemui.display.data.repository.FakeDisplayRepository import com.android.systemui.keyguard.shared.model.AcquiredFingerprintAuthenticationStatus import com.android.systemui.res.R import com.android.systemui.user.domain.interactor.SelectedUserInteractor import com.android.systemui.util.concurrency.FakeExecutor Loading Loading @@ -100,6 +107,7 @@ internal class PromptViewModelTest(private val testCase: TestCase) : SysuiTestCa @Mock private lateinit var packageManager: PackageManager @Mock private lateinit var applicationInfoWithIcon: ApplicationInfo @Mock private lateinit var applicationInfoNoIcon: ApplicationInfo @Mock private lateinit var activityTaskManager: ActivityTaskManager private val fakeExecutor = FakeExecutor(FakeSystemClock()) private val testScope = TestScope() Loading @@ -113,9 +121,11 @@ internal class PromptViewModelTest(private val testCase: TestCase) : SysuiTestCa private lateinit var fingerprintRepository: FakeFingerprintPropertyRepository private lateinit var promptRepository: FakePromptRepository private lateinit var displayStateRepository: FakeDisplayStateRepository private lateinit var biometricStatusRepository: FakeBiometricStatusRepository private lateinit var displayRepository: FakeDisplayRepository private lateinit var displayStateInteractor: DisplayStateInteractor private lateinit var udfpsOverlayInteractor: UdfpsOverlayInteractor private lateinit var biometricStatusInteractor: BiometricStatusInteractor private lateinit var selector: PromptSelectorInteractor private lateinit var viewModel: PromptViewModel Loading Loading @@ -153,6 +163,9 @@ internal class PromptViewModelTest(private val testCase: TestCase) : SysuiTestCa selectedUserInteractor, testScope.backgroundScope ) biometricStatusRepository = FakeBiometricStatusRepository() biometricStatusInteractor = BiometricStatusInteractorImpl(activityTaskManager, biometricStatusRepository) selector = PromptSelectorInteractorImpl(fingerprintRepository, promptRepository, lockPatternUtils) selector.resetPrompt() Loading @@ -168,6 +181,7 @@ internal class PromptViewModelTest(private val testCase: TestCase) : SysuiTestCa selector, mContext, udfpsOverlayInteractor, biometricStatusInteractor, udfpsUtils ) iconViewModel = viewModel.iconViewModel Loading Loading @@ -1043,8 +1057,7 @@ internal class PromptViewModelTest(private val testCase: TestCase) : SysuiTestCa fun auto_confirm_authentication_when_finger_down() = runGenericTest { val expectConfirmation = testCase.expectConfirmation(atLeastOneFailure = false) // No icon button when face only, can't confirm before auth if (!testCase.isFaceOnly) { if (testCase.isCoex) { viewModel.onOverlayTouch(obtainMotionEvent(MotionEvent.ACTION_DOWN)) } viewModel.showAuthenticated(testCase.authenticatedModality, 0) Loading @@ -1059,7 +1072,8 @@ internal class PromptViewModelTest(private val testCase: TestCase) : SysuiTestCa assertThat(canTryAgain).isFalse() assertThat(authenticated?.isAuthenticated).isTrue() if (testCase.isFaceOnly && expectConfirmation) { if (expectConfirmation) { if (testCase.isFaceOnly) { assertThat(size).isEqualTo(PromptSize.MEDIUM) assertButtonsVisible( cancel = true, Loading @@ -1067,6 +1081,9 @@ internal class PromptViewModelTest(private val testCase: TestCase) : SysuiTestCa ) viewModel.confirmAuthenticated() } else if (testCase.isCoex) { assertThat(authenticated?.isAuthenticatedAndConfirmed).isTrue() } assertThat(message).isEqualTo(PromptMessage.Empty) assertButtonsVisible() } Loading @@ -1076,8 +1093,7 @@ internal class PromptViewModelTest(private val testCase: TestCase) : SysuiTestCa fun cannot_auto_confirm_authentication_when_finger_up() = runGenericTest { val expectConfirmation = testCase.expectConfirmation(atLeastOneFailure = false) // No icon button when face only, can't confirm before auth if (!testCase.isFaceOnly) { if (testCase.isCoex) { viewModel.onOverlayTouch(obtainMotionEvent(MotionEvent.ACTION_DOWN)) viewModel.onOverlayTouch(obtainMotionEvent(MotionEvent.ACTION_UP)) } Loading Loading @@ -1379,6 +1395,12 @@ internal class PromptViewModelTest(private val testCase: TestCase) : SysuiTestCa packageName = packageName, ) biometricStatusRepository.setFingerprintAcquiredStatus( AcquiredFingerprintAuthenticationStatus( AuthenticationReason.BiometricPromptAuthentication, BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_UNKNOWN ) ) // put the view model in the initial authenticating state, unless explicitly skipped val startMode = when { Loading packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModelKosmos.kt +2 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.systemui.biometrics.ui.viewmodel import android.content.applicationContext import com.android.systemui.biometrics.domain.interactor.biometricStatusInteractor import com.android.systemui.biometrics.domain.interactor.displayStateInteractor import com.android.systemui.biometrics.domain.interactor.promptSelectorInteractor import com.android.systemui.biometrics.domain.interactor.udfpsOverlayInteractor Loading @@ -30,6 +31,7 @@ val Kosmos.promptViewModel by Fixture { promptSelectorInteractor = promptSelectorInteractor, context = applicationContext, udfpsOverlayInteractor = udfpsOverlayInteractor, biometricStatusInteractor = biometricStatusInteractor, udfpsUtils = udfpsUtils ) } Loading
packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewBinder.kt +17 −0 Original line number Diff line number Diff line Loading @@ -457,6 +457,23 @@ object BiometricViewBinder { } } } // Retry and confirmation when finger on sensor launch { combine( viewModel.canTryAgainNow, viewModel.hasFingerOnSensor, viewModel.isPendingConfirmation, ::Triple ) .collect { (canRetry, fingerAcquired, pendingConfirmation) -> if (canRetry && fingerAcquired) { legacyCallback.onButtonTryAgain() } else if (pendingConfirmation && fingerAcquired) { viewModel.confirmAuthenticated() } } } } } Loading
packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModel.kt +22 −0 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ import android.content.pm.PackageManager import android.graphics.Rect import android.graphics.drawable.BitmapDrawable import android.graphics.drawable.Drawable import android.hardware.biometrics.BiometricFingerprintConstants import android.hardware.biometrics.BiometricPrompt import android.hardware.biometrics.Flags.customBiometricPrompt import android.hardware.biometrics.PromptContentView Loading @@ -31,6 +32,7 @@ import android.view.MotionEvent import com.android.systemui.Flags.bpTalkback import com.android.systemui.biometrics.UdfpsUtils import com.android.systemui.biometrics.Utils import com.android.systemui.biometrics.domain.interactor.BiometricStatusInteractor import com.android.systemui.biometrics.domain.interactor.DisplayStateInteractor import com.android.systemui.biometrics.domain.interactor.PromptSelectorInteractor import com.android.systemui.biometrics.domain.interactor.UdfpsOverlayInteractor Loading @@ -39,6 +41,7 @@ import com.android.systemui.biometrics.shared.model.BiometricModality import com.android.systemui.biometrics.shared.model.DisplayRotation import com.android.systemui.biometrics.shared.model.PromptKind import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.keyguard.shared.model.AcquiredFingerprintAuthenticationStatus import com.android.systemui.res.R import javax.inject.Inject import kotlinx.coroutines.Job Loading @@ -65,6 +68,7 @@ constructor( promptSelectorInteractor: PromptSelectorInteractor, @Application private val context: Context, private val udfpsOverlayInteractor: UdfpsOverlayInteractor, private val biometricStatusInteractor: BiometricStatusInteractor, private val udfpsUtils: UdfpsUtils ) { /** The set of modalities available for this prompt */ Loading Loading @@ -147,6 +151,24 @@ constructor( /** Fingerprint sensor state. */ val fingerprintStartMode: Flow<FingerprintStartMode> = _fingerprintStartMode.asStateFlow() /** Whether a finger has been acquired by the sensor */ // TODO(b/331948073): Add support for detecting SFPS finger without authentication running val hasFingerBeenAcquired: Flow<Boolean> = combine(biometricStatusInteractor.fingerprintAcquiredStatus, modalities) { status, modalities -> modalities.hasSfps && status is AcquiredFingerprintAuthenticationStatus && status.acquiredInfo == BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_START } .distinctUntilChanged() /** Whether there is currently a finger on the sensor */ val hasFingerOnSensor: Flow<Boolean> = combine(hasFingerBeenAcquired, _isOverlayTouched) { hasFingerBeenAcquired, overlayTouched -> hasFingerBeenAcquired || overlayTouched } private val _forceLargeSize = MutableStateFlow(false) private val _forceMediumSize = MutableStateFlow(false) Loading
packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt +10 −0 Original line number Diff line number Diff line Loading @@ -15,6 +15,7 @@ */ package com.android.systemui.biometrics import android.app.ActivityTaskManager import android.app.admin.DevicePolicyManager import android.content.pm.PackageManager import android.hardware.biometrics.BiometricAuthenticator Loading @@ -41,9 +42,12 @@ import androidx.test.filters.SmallTest import com.android.internal.jank.InteractionJankMonitor import com.android.internal.widget.LockPatternUtils import com.android.systemui.SysuiTestCase import com.android.systemui.biometrics.data.repository.FakeBiometricStatusRepository import com.android.systemui.biometrics.data.repository.FakeDisplayStateRepository import com.android.systemui.biometrics.data.repository.FakeFingerprintPropertyRepository import com.android.systemui.biometrics.data.repository.FakePromptRepository import com.android.systemui.biometrics.domain.interactor.BiometricStatusInteractor import com.android.systemui.biometrics.domain.interactor.BiometricStatusInteractorImpl import com.android.systemui.biometrics.domain.interactor.DisplayStateInteractor import com.android.systemui.biometrics.domain.interactor.DisplayStateInteractorImpl import com.android.systemui.biometrics.domain.interactor.FakeCredentialInteractor Loading Loading @@ -116,10 +120,12 @@ open class AuthContainerViewTest : SysuiTestCase() { lateinit var selectedUserInteractor: SelectedUserInteractor @Mock private lateinit var packageManager: PackageManager @Mock private lateinit var activityTaskManager: ActivityTaskManager private val testScope = TestScope(StandardTestDispatcher()) private val fakeExecutor = FakeExecutor(FakeSystemClock()) private val biometricPromptRepository = FakePromptRepository() private val biometricStatusRepository = FakeBiometricStatusRepository() private val fingerprintRepository = FakeFingerprintPropertyRepository() private val displayStateRepository = FakeDisplayStateRepository() private val credentialInteractor = FakeCredentialInteractor() Loading @@ -139,6 +145,7 @@ open class AuthContainerViewTest : SysuiTestCase() { private lateinit var displayRepository: FakeDisplayRepository private lateinit var displayStateInteractor: DisplayStateInteractor private lateinit var udfpsOverlayInteractor: UdfpsOverlayInteractor private lateinit var biometricStatusInteractor: BiometricStatusInteractor private val credentialViewModel = CredentialViewModel(mContext, bpCredentialInteractor) private val defaultLogoIcon = context.getDrawable(R.drawable.ic_android) Loading @@ -164,6 +171,8 @@ open class AuthContainerViewTest : SysuiTestCase() { selectedUserInteractor, testScope.backgroundScope, ) biometricStatusInteractor = BiometricStatusInteractorImpl(activityTaskManager, biometricStatusRepository) // Set up default logo icon whenever(packageManager.getApplicationIcon(OP_PACKAGE_NAME)).thenReturn(defaultLogoIcon) context.setMockPackageManager(packageManager) Loading Loading @@ -577,6 +586,7 @@ open class AuthContainerViewTest : SysuiTestCase() { promptSelectorInteractor, context, udfpsOverlayInteractor, biometricStatusInteractor, udfpsUtils ), { credentialViewModel }, Loading
packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModelTest.kt +33 −11 Original line number Diff line number Diff line Loading @@ -16,12 +16,14 @@ package com.android.systemui.biometrics.ui.viewmodel import android.app.ActivityTaskManager import android.content.pm.ApplicationInfo import android.content.pm.PackageManager import android.content.res.Configuration import android.graphics.Bitmap import android.graphics.Point import android.graphics.drawable.BitmapDrawable import android.hardware.biometrics.BiometricFingerprintConstants import android.hardware.biometrics.Flags.FLAG_CUSTOM_BIOMETRIC_PROMPT import android.hardware.biometrics.PromptContentItemBulletedText import android.hardware.biometrics.PromptContentView Loading @@ -38,9 +40,12 @@ import com.android.systemui.Flags.FLAG_BP_TALKBACK import com.android.systemui.SysuiTestCase import com.android.systemui.biometrics.AuthController import com.android.systemui.biometrics.UdfpsUtils import com.android.systemui.biometrics.data.repository.FakeBiometricStatusRepository import com.android.systemui.biometrics.data.repository.FakeDisplayStateRepository import com.android.systemui.biometrics.data.repository.FakeFingerprintPropertyRepository import com.android.systemui.biometrics.data.repository.FakePromptRepository import com.android.systemui.biometrics.domain.interactor.BiometricStatusInteractor import com.android.systemui.biometrics.domain.interactor.BiometricStatusInteractorImpl import com.android.systemui.biometrics.domain.interactor.DisplayStateInteractor import com.android.systemui.biometrics.domain.interactor.DisplayStateInteractorImpl import com.android.systemui.biometrics.domain.interactor.PromptSelectorInteractor Loading @@ -49,6 +54,7 @@ import com.android.systemui.biometrics.domain.interactor.UdfpsOverlayInteractor import com.android.systemui.biometrics.extractAuthenticatorTypes import com.android.systemui.biometrics.faceSensorPropertiesInternal import com.android.systemui.biometrics.fingerprintSensorPropertiesInternal import com.android.systemui.biometrics.shared.model.AuthenticationReason import com.android.systemui.biometrics.shared.model.BiometricModalities import com.android.systemui.biometrics.shared.model.BiometricModality import com.android.systemui.biometrics.shared.model.DisplayRotation Loading @@ -57,6 +63,7 @@ import com.android.systemui.biometrics.shared.model.toSensorType import com.android.systemui.coroutines.collectLastValue import com.android.systemui.coroutines.collectValues import com.android.systemui.display.data.repository.FakeDisplayRepository import com.android.systemui.keyguard.shared.model.AcquiredFingerprintAuthenticationStatus import com.android.systemui.res.R import com.android.systemui.user.domain.interactor.SelectedUserInteractor import com.android.systemui.util.concurrency.FakeExecutor Loading Loading @@ -100,6 +107,7 @@ internal class PromptViewModelTest(private val testCase: TestCase) : SysuiTestCa @Mock private lateinit var packageManager: PackageManager @Mock private lateinit var applicationInfoWithIcon: ApplicationInfo @Mock private lateinit var applicationInfoNoIcon: ApplicationInfo @Mock private lateinit var activityTaskManager: ActivityTaskManager private val fakeExecutor = FakeExecutor(FakeSystemClock()) private val testScope = TestScope() Loading @@ -113,9 +121,11 @@ internal class PromptViewModelTest(private val testCase: TestCase) : SysuiTestCa private lateinit var fingerprintRepository: FakeFingerprintPropertyRepository private lateinit var promptRepository: FakePromptRepository private lateinit var displayStateRepository: FakeDisplayStateRepository private lateinit var biometricStatusRepository: FakeBiometricStatusRepository private lateinit var displayRepository: FakeDisplayRepository private lateinit var displayStateInteractor: DisplayStateInteractor private lateinit var udfpsOverlayInteractor: UdfpsOverlayInteractor private lateinit var biometricStatusInteractor: BiometricStatusInteractor private lateinit var selector: PromptSelectorInteractor private lateinit var viewModel: PromptViewModel Loading Loading @@ -153,6 +163,9 @@ internal class PromptViewModelTest(private val testCase: TestCase) : SysuiTestCa selectedUserInteractor, testScope.backgroundScope ) biometricStatusRepository = FakeBiometricStatusRepository() biometricStatusInteractor = BiometricStatusInteractorImpl(activityTaskManager, biometricStatusRepository) selector = PromptSelectorInteractorImpl(fingerprintRepository, promptRepository, lockPatternUtils) selector.resetPrompt() Loading @@ -168,6 +181,7 @@ internal class PromptViewModelTest(private val testCase: TestCase) : SysuiTestCa selector, mContext, udfpsOverlayInteractor, biometricStatusInteractor, udfpsUtils ) iconViewModel = viewModel.iconViewModel Loading Loading @@ -1043,8 +1057,7 @@ internal class PromptViewModelTest(private val testCase: TestCase) : SysuiTestCa fun auto_confirm_authentication_when_finger_down() = runGenericTest { val expectConfirmation = testCase.expectConfirmation(atLeastOneFailure = false) // No icon button when face only, can't confirm before auth if (!testCase.isFaceOnly) { if (testCase.isCoex) { viewModel.onOverlayTouch(obtainMotionEvent(MotionEvent.ACTION_DOWN)) } viewModel.showAuthenticated(testCase.authenticatedModality, 0) Loading @@ -1059,7 +1072,8 @@ internal class PromptViewModelTest(private val testCase: TestCase) : SysuiTestCa assertThat(canTryAgain).isFalse() assertThat(authenticated?.isAuthenticated).isTrue() if (testCase.isFaceOnly && expectConfirmation) { if (expectConfirmation) { if (testCase.isFaceOnly) { assertThat(size).isEqualTo(PromptSize.MEDIUM) assertButtonsVisible( cancel = true, Loading @@ -1067,6 +1081,9 @@ internal class PromptViewModelTest(private val testCase: TestCase) : SysuiTestCa ) viewModel.confirmAuthenticated() } else if (testCase.isCoex) { assertThat(authenticated?.isAuthenticatedAndConfirmed).isTrue() } assertThat(message).isEqualTo(PromptMessage.Empty) assertButtonsVisible() } Loading @@ -1076,8 +1093,7 @@ internal class PromptViewModelTest(private val testCase: TestCase) : SysuiTestCa fun cannot_auto_confirm_authentication_when_finger_up() = runGenericTest { val expectConfirmation = testCase.expectConfirmation(atLeastOneFailure = false) // No icon button when face only, can't confirm before auth if (!testCase.isFaceOnly) { if (testCase.isCoex) { viewModel.onOverlayTouch(obtainMotionEvent(MotionEvent.ACTION_DOWN)) viewModel.onOverlayTouch(obtainMotionEvent(MotionEvent.ACTION_UP)) } Loading Loading @@ -1379,6 +1395,12 @@ internal class PromptViewModelTest(private val testCase: TestCase) : SysuiTestCa packageName = packageName, ) biometricStatusRepository.setFingerprintAcquiredStatus( AcquiredFingerprintAuthenticationStatus( AuthenticationReason.BiometricPromptAuthentication, BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_UNKNOWN ) ) // put the view model in the initial authenticating state, unless explicitly skipped val startMode = when { Loading
packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModelKosmos.kt +2 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.systemui.biometrics.ui.viewmodel import android.content.applicationContext import com.android.systemui.biometrics.domain.interactor.biometricStatusInteractor import com.android.systemui.biometrics.domain.interactor.displayStateInteractor import com.android.systemui.biometrics.domain.interactor.promptSelectorInteractor import com.android.systemui.biometrics.domain.interactor.udfpsOverlayInteractor Loading @@ -30,6 +31,7 @@ val Kosmos.promptViewModel by Fixture { promptSelectorInteractor = promptSelectorInteractor, context = applicationContext, udfpsOverlayInteractor = udfpsOverlayInteractor, biometricStatusInteractor = biometricStatusInteractor, udfpsUtils = udfpsUtils ) }