diff options
| author | 2024-05-07 08:14:38 +0000 | |
|---|---|---|
| committer | 2024-05-11 00:36:38 +0000 | |
| commit | 69f72faeb92b0583a1abe87669fe244ccc5ed016 (patch) | |
| tree | 7cf4387bebdf21abefc101242c4021ba21293e53 | |
| parent | 47a93786f4911b8efde9e76273d252c5f9dec7fc (diff) | |
Use PromptKind to decide which layout to show.
1. Update PromptKind and use it to decide which layout to show.
In this way, we could know what PromptKind is before rendering the
layout. This enables us to use PromptKind to decide show one-pane or
two-pane layout as a follow-up step.
2. Do some clean ups.
Test: atest PromptSelectorInteractorImplTest
Test: atest PromptViewModelTest
Bug: 330908557
Flag: ACONFIG android.hardware.biometrics.custom_biometric_prompt NEXTFOOD
Change-Id: I2facb1e722c9f58475de92d685deddb3df055270
15 files changed, 308 insertions, 279 deletions
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/AuthControllerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/AuthControllerTest.java index f4ad7649a18f..9b1d4eca8b2b 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/AuthControllerTest.java +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/AuthControllerTest.java @@ -84,7 +84,6 @@ import com.android.internal.jank.InteractionJankMonitor; import com.android.internal.widget.LockPatternUtils; import com.android.systemui.SysuiTestCase; import com.android.systemui.biometrics.domain.interactor.LogContextInteractor; -import com.android.systemui.biometrics.domain.interactor.PromptCredentialInteractor; import com.android.systemui.biometrics.domain.interactor.PromptSelectorInteractor; import com.android.systemui.biometrics.ui.viewmodel.CredentialViewModel; import com.android.systemui.biometrics.ui.viewmodel.PromptViewModel; @@ -161,8 +160,6 @@ public class AuthControllerTest extends SysuiTestCase { @Mock private InteractionJankMonitor mInteractionJankMonitor; @Mock - private PromptCredentialInteractor mBiometricPromptCredentialInteractor; - @Mock private PromptSelectorInteractor mPromptSelectionInteractor; @Mock private CredentialViewModel mCredentialViewModel; @@ -1057,7 +1054,6 @@ public class AuthControllerTest extends SysuiTestCase { private final class TestableAuthController extends AuthController { private int mBuildCount = 0; - private PromptInfo mLastBiometricPromptInfo; TestableAuthController(Context context) { super(context, null /* applicationCoroutineScope */, @@ -1065,8 +1061,8 @@ public class AuthControllerTest extends SysuiTestCase { mFingerprintManager, mFaceManager, () -> mUdfpsController, mDisplayManager, mWakefulnessLifecycle, mPanelInteractionDetector, mUserManager, mLockPatternUtils, () -> mUdfpsLogger, () -> mLogContextInteractor, - () -> mBiometricPromptCredentialInteractor, () -> mPromptSelectionInteractor, - () -> mCredentialViewModel, () -> mPromptViewModel, mInteractionJankMonitor, + () -> mPromptSelectionInteractor, () -> mCredentialViewModel, + () -> mPromptViewModel, mInteractionJankMonitor, mHandler, mBackgroundExecutor, mUdfpsUtils, mVibratorHelper); } @@ -1079,8 +1075,6 @@ public class AuthControllerTest extends SysuiTestCase { UserManager userManager, LockPatternUtils lockPatternUtils, PromptViewModel viewModel) { - mLastBiometricPromptInfo = promptInfo; - AuthDialog dialog; if (mBuildCount == 0) { dialog = mDialog1; diff --git a/packages/SystemUI/shared/biometrics/src/com/android/systemui/biometrics/shared/model/PromptKind.kt b/packages/SystemUI/shared/biometrics/src/com/android/systemui/biometrics/shared/model/PromptKind.kt index 87829621f57d..b99c51489521 100644 --- a/packages/SystemUI/shared/biometrics/src/com/android/systemui/biometrics/shared/model/PromptKind.kt +++ b/packages/SystemUI/shared/biometrics/src/com/android/systemui/biometrics/shared/model/PromptKind.kt @@ -20,10 +20,11 @@ sealed interface PromptKind { object None : PromptKind data class Biometric( + /** The available modalities for the authentication on the prompt. */ val activeModalities: BiometricModalities = BiometricModalities(), // TODO(b/330908557): Use this value to decide whether to show two pane layout, instead of // simply depending on rotations. - val showTwoPane: Boolean = false + val showTwoPane: Boolean = false, ) : PromptKind object Pin : PromptKind diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java index 9ba41ef9ff47..298c0f782b79 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java @@ -73,7 +73,6 @@ import com.android.internal.annotations.VisibleForTesting; import com.android.internal.jank.InteractionJankMonitor; import com.android.internal.widget.LockPatternUtils; import com.android.systemui.biometrics.AuthController.ScaleFactorProvider; -import com.android.systemui.biometrics.domain.interactor.PromptCredentialInteractor; import com.android.systemui.biometrics.domain.interactor.PromptSelectorInteractor; import com.android.systemui.biometrics.shared.model.BiometricModalities; import com.android.systemui.biometrics.shared.model.PromptKind; @@ -150,7 +149,6 @@ public class AuthContainerView extends LinearLayout private final CoroutineScope mApplicationCoroutineScope; // TODO(b/287311775): these should be migrated out once ready - private final Provider<PromptCredentialInteractor> mPromptCredentialInteractor; private final @NonNull Provider<PromptSelectorInteractor> mPromptSelectorInteractorProvider; // TODO(b/287311775): these should be migrated out of the view private final Provider<CredentialViewModel> mCredentialViewModelProvider; @@ -311,7 +309,6 @@ public class AuthContainerView extends LinearLayout @NonNull UserManager userManager, @NonNull LockPatternUtils lockPatternUtils, @NonNull InteractionJankMonitor jankMonitor, - @NonNull Provider<PromptCredentialInteractor> promptCredentialInteractor, @NonNull Provider<PromptSelectorInteractor> promptSelectorInteractor, @NonNull PromptViewModel promptViewModel, @NonNull Provider<CredentialViewModel> credentialViewModelProvider, @@ -319,7 +316,7 @@ public class AuthContainerView extends LinearLayout @NonNull VibratorHelper vibratorHelper) { this(config, applicationCoroutineScope, fpProps, faceProps, wakefulnessLifecycle, panelInteractionDetector, userManager, lockPatternUtils, - jankMonitor, promptSelectorInteractor, promptCredentialInteractor, promptViewModel, + jankMonitor, promptSelectorInteractor, promptViewModel, credentialViewModelProvider, new Handler(Looper.getMainLooper()), bgExecutor, vibratorHelper); } @@ -335,7 +332,6 @@ public class AuthContainerView extends LinearLayout @NonNull LockPatternUtils lockPatternUtils, @NonNull InteractionJankMonitor jankMonitor, @NonNull Provider<PromptSelectorInteractor> promptSelectorInteractorProvider, - @NonNull Provider<PromptCredentialInteractor> credentialInteractor, @NonNull PromptViewModel promptViewModel, @NonNull Provider<CredentialViewModel> credentialViewModelProvider, @NonNull Handler mainHandler, @@ -358,13 +354,19 @@ public class AuthContainerView extends LinearLayout mLinearOutSlowIn = Interpolators.LINEAR_OUT_SLOW_IN; mBiometricCallback = new BiometricCallback(); + mFpProps = fpProps; + mFaceProps = faceProps; + final BiometricModalities biometricModalities = new BiometricModalities( + Utils.findFirstSensorProperties(fpProps, mConfig.mSensorIds), + Utils.findFirstSensorProperties(faceProps, mConfig.mSensorIds)); + mPromptSelectorInteractorProvider = promptSelectorInteractorProvider; - mPromptSelectorInteractorProvider.get().setShouldShowBpWithoutIconForCredential( - config.mPromptInfo); + mPromptSelectorInteractorProvider.get().setPrompt(mConfig.mPromptInfo, mEffectiveUserId, + biometricModalities, mConfig.mOperationId, mConfig.mOpPackageName, + false /*onSwitchToCredential*/); final LayoutInflater layoutInflater = LayoutInflater.from(mContext); - if (constraintBp() && (Utils.isBiometricAllowed(config.mPromptInfo) - || mPromptViewModel.getShowBpWithoutIconForCredential().getValue())) { + if (constraintBp() && mPromptViewModel.getPromptKind().getValue().isBiometric()) { mLayout = (ConstraintLayout) layoutInflater.inflate( R.layout.biometric_prompt_constraint_layout, this, false /* attachToRoot */); } else { @@ -398,10 +400,7 @@ public class AuthContainerView extends LinearLayout mPanelController = new AuthPanelController(mContext, mPanelView); mBackgroundExecutor = bgExecutor; mInteractionJankMonitor = jankMonitor; - mPromptCredentialInteractor = credentialInteractor; mCredentialViewModelProvider = credentialViewModelProvider; - mFpProps = fpProps; - mFaceProps = faceProps; showPrompt(config, layoutInflater, promptViewModel, Utils.findFirstSensorProperties(fpProps, mConfig.mSensorIds), @@ -430,11 +429,12 @@ public class AuthContainerView extends LinearLayout @Nullable FaceSensorPropertiesInternal faceProps, @NonNull VibratorHelper vibratorHelper ) { - if (Utils.isBiometricAllowed(config.mPromptInfo) - || mPromptViewModel.getShowBpWithoutIconForCredential().getValue()) { + if (mPromptViewModel.getPromptKind().getValue().isBiometric()) { addBiometricView(config, layoutInflater, viewModel, fpProps, faceProps, vibratorHelper); - } else if (constraintBp() && Utils.isDeviceCredentialAllowed(mConfig.mPromptInfo)) { - addCredentialView(true, false); + } else if (mPromptViewModel.getPromptKind().getValue().isCredential()) { + if (constraintBp()) { + addCredentialView(true, false); + } } else { mPromptSelectorInteractorProvider.get().resetPrompt(); } @@ -445,12 +445,6 @@ public class AuthContainerView extends LinearLayout @Nullable FingerprintSensorPropertiesInternal fpProps, @Nullable FaceSensorPropertiesInternal faceProps, @NonNull VibratorHelper vibratorHelper) { - mPromptSelectorInteractorProvider.get().useBiometricsForAuthentication( - config.mPromptInfo, - config.mUserId, - config.mOperationId, - new BiometricModalities(fpProps, faceProps), - config.mOpPackageName); if (constraintBp()) { mBiometricView = BiometricViewBinder.bind(mLayout, viewModel, null, @@ -519,10 +513,6 @@ public class AuthContainerView extends LinearLayout // disable it. mBackgroundView.setOnClickListener(null); mBackgroundView.setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_NO); - - mPromptSelectorInteractorProvider.get().useCredentialsForAuthentication( - mConfig.mPromptInfo, credentialType, mConfig.mUserId, mConfig.mOperationId, - mConfig.mOpPackageName); final CredentialViewModel vm = mCredentialViewModelProvider.get(); vm.setAnimateContents(animateContents); ((CredentialView) mCredentialView).init(vm, this, mPanelController, animatePanel, @@ -557,10 +547,9 @@ public class AuthContainerView extends LinearLayout () -> animateAway(AuthDialogCallback.DISMISSED_USER_CANCELED)); if (constraintBp()) { // Do nothing on attachment with constraintLayout - } else if (Utils.isBiometricAllowed(mConfig.mPromptInfo) - || mPromptViewModel.getShowBpWithoutIconForCredential().getValue()) { + } else if (mPromptViewModel.getPromptKind().getValue().isBiometric()) { mBiometricScrollView.addView(mBiometricView.asView()); - } else if (Utils.isDeviceCredentialAllowed(mConfig.mPromptInfo)) { + } else if (mPromptViewModel.getPromptKind().getValue().isCredential()) { addCredentialView(true /* animatePanel */, false /* animateContents */); } else { throw new IllegalStateException("Unknown configuration: " diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java index ca88d40df6af..b69e19696d8b 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java @@ -69,7 +69,6 @@ import com.android.internal.os.SomeArgs; import com.android.internal.widget.LockPatternUtils; import com.android.systemui.CoreStartable; import com.android.systemui.biometrics.domain.interactor.LogContextInteractor; -import com.android.systemui.biometrics.domain.interactor.PromptCredentialInteractor; import com.android.systemui.biometrics.domain.interactor.PromptSelectorInteractor; import com.android.systemui.biometrics.shared.model.UdfpsOverlayParams; import com.android.systemui.biometrics.ui.viewmodel.CredentialViewModel; @@ -139,7 +138,6 @@ public class AuthController implements private Job mBiometricContextListenerJob = null; // TODO: these should be migrated out once ready - @NonNull private final Provider<PromptCredentialInteractor> mPromptCredentialInteractor; @NonNull private final Provider<PromptSelectorInteractor> mPromptSelectorInteractor; @NonNull private final Provider<CredentialViewModel> mCredentialViewModelProvider; @NonNull private final Provider<PromptViewModel> mPromptViewModelProvider; @@ -735,7 +733,6 @@ public class AuthController implements @NonNull LockPatternUtils lockPatternUtils, @NonNull Lazy<UdfpsLogger> udfpsLogger, @NonNull Lazy<LogContextInteractor> logContextInteractor, - @NonNull Provider<PromptCredentialInteractor> promptCredentialInteractorProvider, @NonNull Provider<PromptSelectorInteractor> promptSelectorInteractorProvider, @NonNull Provider<CredentialViewModel> credentialViewModelProvider, @NonNull Provider<PromptViewModel> promptViewModelProvider, @@ -768,7 +765,6 @@ public class AuthController implements mLogContextInteractor = logContextInteractor; mPromptSelectorInteractor = promptSelectorInteractorProvider; - mPromptCredentialInteractor = promptCredentialInteractorProvider; mPromptViewModelProvider = promptViewModelProvider; mCredentialViewModelProvider = credentialViewModelProvider; @@ -1316,8 +1312,8 @@ public class AuthController implements config.mScaleProvider = this::getScaleFactor; return new AuthContainerView(config, mApplicationCoroutineScope, mFpProps, mFaceProps, wakefulnessLifecycle, panelInteractionDetector, userManager, lockPatternUtils, - mInteractionJankMonitor, mPromptCredentialInteractor, mPromptSelectorInteractor, - viewModel, mCredentialViewModelProvider, bgExecutor, mVibratorHelper); + mInteractionJankMonitor, mPromptSelectorInteractor, viewModel, + mCredentialViewModelProvider, bgExecutor, mVibratorHelper); } @Override diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/data/repository/PromptRepository.kt b/packages/SystemUI/src/com/android/systemui/biometrics/data/repository/PromptRepository.kt index f659ff0a4749..58b238b820c3 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/data/repository/PromptRepository.kt +++ b/packages/SystemUI/src/com/android/systemui/biometrics/data/repository/PromptRepository.kt @@ -16,12 +16,8 @@ package com.android.systemui.biometrics.data.repository -import android.hardware.biometrics.Flags import android.hardware.biometrics.PromptInfo -import com.android.systemui.Flags.constraintBp import com.android.systemui.biometrics.AuthController -import com.android.systemui.biometrics.Utils -import com.android.systemui.biometrics.Utils.isDeviceCredentialAllowed import com.android.systemui.biometrics.shared.model.PromptKind import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLogging import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow @@ -56,8 +52,8 @@ interface PromptRepository { /** The gatekeeper challenge, if one is associated with this prompt. */ val challenge: StateFlow<Long?> - /** The kind of credential to use (biometric, pin, pattern, etc.). */ - val kind: StateFlow<PromptKind> + /** The kind of prompt to use (biometric, pin, pattern, etc.). */ + val promptKind: StateFlow<PromptKind> /** The package name that the prompt is called from. */ val opPackageName: StateFlow<String?> @@ -69,18 +65,6 @@ interface PromptRepository { */ val isConfirmationRequired: Flow<Boolean> - /** - * If biometric prompt without icon needs to show for displaying content prior to credential - * view. - */ - val showBpWithoutIconForCredential: StateFlow<Boolean> - - /** - * Update whether biometric prompt without icon needs to show for displaying content prior to - * credential view, which should be set before [setPrompt]. - */ - fun setShouldShowBpWithoutIconForCredential(promptInfo: PromptInfo) - /** Update the prompt configuration, which should be set before [isShowing]. */ fun setPrompt( promptInfo: PromptInfo, @@ -125,8 +109,8 @@ constructor( private val _userId: MutableStateFlow<Int?> = MutableStateFlow(null) override val userId = _userId.asStateFlow() - private val _kind: MutableStateFlow<PromptKind> = MutableStateFlow(PromptKind.None) - override val kind = _kind.asStateFlow() + private val _promptKind: MutableStateFlow<PromptKind> = MutableStateFlow(PromptKind.None) + override val promptKind = _promptKind.asStateFlow() private val _opPackageName: MutableStateFlow<String?> = MutableStateFlow(null) override val opPackageName = _opPackageName.asStateFlow() @@ -145,21 +129,6 @@ constructor( } .distinctUntilChanged() - private val _showBpWithoutIconForCredential: MutableStateFlow<Boolean> = MutableStateFlow(false) - override val showBpWithoutIconForCredential = _showBpWithoutIconForCredential.asStateFlow() - - override fun setShouldShowBpWithoutIconForCredential(promptInfo: PromptInfo) { - val hasCredentialViewShown = kind.value.isCredential() - val showBpForCredential = - Flags.customBiometricPrompt() && - constraintBp() && - !Utils.isBiometricAllowed(promptInfo) && - isDeviceCredentialAllowed(promptInfo) && - promptInfo.contentView != null && - !promptInfo.isContentViewMoreOptionsButtonUsed - _showBpWithoutIconForCredential.value = showBpForCredential && !hasCredentialViewShown - } - override fun setPrompt( promptInfo: PromptInfo, userId: Int, @@ -167,7 +136,7 @@ constructor( kind: PromptKind, opPackageName: String, ) { - _kind.value = kind + _promptKind.value = kind _userId.value = userId _challenge.value = gatekeeperChallenge _promptInfo.value = promptInfo @@ -178,7 +147,7 @@ constructor( _promptInfo.value = null _userId.value = null _challenge.value = null - _kind.value = PromptKind.None + _promptKind.value = PromptKind.None _opPackageName.value = null } diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/PromptCredentialInteractor.kt b/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/PromptCredentialInteractor.kt index f8fb7bb7dff7..14ba8a22a65e 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/PromptCredentialInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/PromptCredentialInteractor.kt @@ -66,13 +66,13 @@ constructor( biometricPromptRepository.promptInfo, biometricPromptRepository.challenge, biometricPromptRepository.userId, - biometricPromptRepository.kind - ) { promptInfo, challenge, userId, kind -> + biometricPromptRepository.promptKind + ) { promptInfo, challenge, userId, promptKind -> if (promptInfo == null || userId == null || challenge == null) { return@combine null } - when (kind) { + when (promptKind) { PromptKind.Pin -> BiometricPromptRequest.Credential.Pin( info = promptInfo, diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/PromptSelectorInteractor.kt b/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/PromptSelectorInteractor.kt index deb47d309ea5..4ba780fcec69 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/PromptSelectorInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/PromptSelectorInteractor.kt @@ -16,8 +16,10 @@ package com.android.systemui.biometrics.domain.interactor +import android.hardware.biometrics.Flags import android.hardware.biometrics.PromptInfo import com.android.internal.widget.LockPatternUtils +import com.android.systemui.biometrics.Utils import com.android.systemui.biometrics.Utils.getCredentialType import com.android.systemui.biometrics.Utils.isDeviceCredentialAllowed import com.android.systemui.biometrics.data.repository.FingerprintPropertyRepository @@ -52,12 +54,16 @@ interface PromptSelectorInteractor { /** Static metadata about the current prompt. */ val prompt: Flow<BiometricPromptRequest.Biometric?> + /** The kind of prompt to use (biometric, pin, pattern, etc.). */ + val promptKind: StateFlow<PromptKind> + /** If using a credential is allowed. */ val isCredentialAllowed: Flow<Boolean> /** - * The kind of credential the user may use as a fallback or [PromptKind.Biometric] if unknown or - * not [isCredentialAllowed]. + * The kind of credential the user may use as a fallback or [PromptKind.None] if unknown or not + * [isCredentialAllowed]. This is separate from [promptKind], even if [promptKind] is + * [PromptKind.Biometric], [credentialKind] should still be one of pin/pattern/password. */ val credentialKind: Flow<PromptKind> @@ -70,34 +76,20 @@ interface PromptSelectorInteractor { /** Fingerprint sensor type */ val sensorType: Flow<FingerprintSensorType> - /** - * If biometric prompt without icon needs to show for displaying content prior to credential - * view. - */ - val showBpWithoutIconForCredential: StateFlow<Boolean> + /** Switch to the credential view. */ + fun onSwitchToCredential() /** - * Update whether biometric prompt without icon needs to show for displaying content prior to - * credential view, which should be set before [PromptRepository.setPrompt]. + * Update the kind of prompt (biometric prompt w/ or w/o sensor icon, pin view, pattern view, + * etc). */ - fun setShouldShowBpWithoutIconForCredential(promptInfo: PromptInfo) - - /** Use biometrics for authentication. */ - fun useBiometricsForAuthentication( + fun setPrompt( promptInfo: PromptInfo, - userId: Int, - challenge: Long, + effectiveUserId: Int, modalities: BiometricModalities, - opPackageName: String, - ) - - /** Use credential-based authentication instead of biometrics. */ - fun useCredentialsForAuthentication( - promptInfo: PromptInfo, - kind: PromptKind, - userId: Int, challenge: Long, opPackageName: String, + onSwitchToCredential: Boolean, ) /** Unset the current authentication request. */ @@ -110,7 +102,7 @@ class PromptSelectorInteractorImpl constructor( fingerprintPropertyRepository: FingerprintPropertyRepository, private val promptRepository: PromptRepository, - lockPatternUtils: LockPatternUtils, + private val lockPatternUtils: LockPatternUtils, ) : PromptSelectorInteractor { override val prompt: Flow<BiometricPromptRequest.Biometric?> = @@ -118,7 +110,7 @@ constructor( promptRepository.promptInfo, promptRepository.challenge, promptRepository.userId, - promptRepository.kind, + promptRepository.promptKind, promptRepository.opPackageName, ) { promptInfo, challenge, userId, kind, opPackageName -> if ( @@ -140,6 +132,8 @@ constructor( } } + override val promptKind: StateFlow<PromptKind> = promptRepository.promptKind + override val isConfirmationRequired: Flow<Boolean> = promptRepository.isConfirmationRequired.distinctUntilChanged() @@ -153,44 +147,57 @@ constructor( if (prompt != null && isAllowed) { getCredentialType(lockPatternUtils, prompt.userInfo.deviceCredentialOwnerId) } else { - PromptKind.Biometric() + PromptKind.None } } override val sensorType: Flow<FingerprintSensorType> = fingerprintPropertyRepository.sensorType - override val showBpWithoutIconForCredential = promptRepository.showBpWithoutIconForCredential - - override fun setShouldShowBpWithoutIconForCredential(promptInfo: PromptInfo) { - promptRepository.setShouldShowBpWithoutIconForCredential(promptInfo) - } - - override fun useBiometricsForAuthentication( - promptInfo: PromptInfo, - userId: Int, - challenge: Long, - modalities: BiometricModalities, - opPackageName: String, - ) { - promptRepository.setPrompt( - promptInfo = promptInfo, - userId = userId, - gatekeeperChallenge = challenge, - kind = PromptKind.Biometric(modalities), - opPackageName = opPackageName, + override fun onSwitchToCredential() { + val modalities: BiometricModalities = + if (promptRepository.promptKind.value.isBiometric()) + (promptRepository.promptKind.value as PromptKind.Biometric).activeModalities + else BiometricModalities() + setPrompt( + promptRepository.promptInfo.value!!, + promptRepository.userId.value!!, + modalities, + promptRepository.challenge.value!!, + promptRepository.opPackageName.value!!, + true /*onSwitchToCredential*/ ) } - override fun useCredentialsForAuthentication( + override fun setPrompt( promptInfo: PromptInfo, - kind: PromptKind, - userId: Int, + effectiveUserId: Int, + modalities: BiometricModalities, challenge: Long, opPackageName: String, + onSwitchToCredential: Boolean, ) { + val hasCredentialViewShown = promptKind.value.isCredential() + val showBpForCredential = + Flags.customBiometricPrompt() && + com.android.systemui.Flags.constraintBp() && + !Utils.isBiometricAllowed(promptInfo) && + isDeviceCredentialAllowed(promptInfo) && + promptInfo.contentView != null && + !promptInfo.isContentViewMoreOptionsButtonUsed + val showBpWithoutIconForCredential = showBpForCredential && !hasCredentialViewShown + var kind: PromptKind = PromptKind.None + if (onSwitchToCredential) { + kind = getCredentialType(lockPatternUtils, effectiveUserId) + } else if (Utils.isBiometricAllowed(promptInfo) || showBpWithoutIconForCredential) { + // TODO(b/330908557): check to show one pane or two pane + kind = PromptKind.Biometric(modalities) + } else if (isDeviceCredentialAllowed(promptInfo)) { + kind = getCredentialType(lockPatternUtils, effectiveUserId) + } + promptRepository.setPrompt( promptInfo = promptInfo, - userId = userId, + userId = effectiveUserId, gatekeeperChallenge = challenge, kind = kind, opPackageName = opPackageName, diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewBinder.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewBinder.kt index da5695163cb4..65c5b6b3859c 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewBinder.kt +++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewBinder.kt @@ -230,7 +230,7 @@ object BiometricViewBinder { } lifecycleScope.launch { - viewModel.showBpWithoutIconForCredential.collect { showWithoutIcon -> + viewModel.hideSensorIcon.collect { showWithoutIcon -> if (!showWithoutIcon) { PromptIconViewBinder.bind( iconView, diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewSizeBinder.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewSizeBinder.kt index d1ad783c7cc8..f0969eda4029 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewSizeBinder.kt +++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewSizeBinder.kt @@ -55,6 +55,7 @@ import com.android.systemui.lifecycle.repeatWhenAttached import com.android.systemui.res.R import kotlin.math.abs import kotlinx.coroutines.flow.combine +import kotlinx.coroutines.flow.first import kotlinx.coroutines.launch /** Helper for [BiometricViewBinder] to handle resize transitions. */ @@ -169,14 +170,14 @@ object BiometricViewSizeBinder { val flipConstraintSet = ConstraintSet() view.doOnLayout { - fun setVisibilities(size: PromptSize) { + fun setVisibilities(hideSensorIcon: Boolean, size: PromptSize) { viewsToHideWhenSmall.forEach { it.showContentOrHide(forceHide = size.isSmall) } largeConstraintSet.setVisibility(iconHolderView.id, View.GONE) largeConstraintSet.setVisibility(R.id.biometric_icon_overlay, View.GONE) largeConstraintSet.setVisibility(R.id.indicator, View.GONE) largeConstraintSet.setVisibility(R.id.scrollView, View.GONE) - if (viewModel.showBpWithoutIconForCredential.value) { + if (hideSensorIcon) { smallConstraintSet.setVisibility(iconHolderView.id, View.GONE) smallConstraintSet.setVisibility(R.id.biometric_icon_overlay, View.GONE) smallConstraintSet.setVisibility(R.id.indicator, View.GONE) @@ -362,12 +363,16 @@ object BiometricViewSizeBinder { } } } + lifecycleScope.launch { + combine(viewModel.hideSensorIcon, viewModel.size, ::Pair).collect { + (hideSensorIcon, size) -> + setVisibilities(hideSensorIcon, size) + } + } lifecycleScope.launch { combine(viewModel.position, viewModel.size, ::Pair).collect { (position, size) -> - setVisibilities(size) - if (position.isLeft) { if (size.isSmall) { flipConstraintSet.clone(smallConstraintSet) @@ -481,7 +486,7 @@ object BiometricViewSizeBinder { v.showContentOrHide(forceHide = size.isSmall) } - if (viewModel.showBpWithoutIconForCredential.value) { + if (viewModel.hideSensorIcon.first()) { iconHolderView.visibility = View.GONE } @@ -492,10 +497,6 @@ object BiometricViewSizeBinder { viewsToFadeInOnSizeChange.forEach { it.alpha = 0f } } - // TODO(b/302735104): Fix wrong height due to the delay of - // PromptContentView. addOnLayoutChangeListener() will cause crash - // when showing credential view, since |PromptIconViewModel| won't - // release the flow. // propagate size changes to legacy panel controller and animate // transitions view.doOnLayout { diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModel.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModel.kt index 2104f3e1fba6..a8c5976ed9d4 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModel.kt @@ -67,7 +67,7 @@ class PromptViewModel @Inject constructor( displayStateInteractor: DisplayStateInteractor, - promptSelectorInteractor: PromptSelectorInteractor, + private val promptSelectorInteractor: PromptSelectorInteractor, @Application private val context: Context, private val udfpsOverlayInteractor: UdfpsOverlayInteractor, private val biometricStatusInteractor: BiometricStatusInteractor, @@ -195,8 +195,11 @@ constructor( /** The kind of credential the user has. */ val credentialKind: Flow<PromptKind> = promptSelectorInteractor.credentialKind - val showBpWithoutIconForCredential: StateFlow<Boolean> = - promptSelectorInteractor.showBpWithoutIconForCredential + /** The kind of prompt to use (biometric, pin, pattern, etc.). */ + val promptKind: StateFlow<PromptKind> = promptSelectorInteractor.promptKind + + /** Whether the sensor icon on biometric prompt ui should be hidden. */ + val hideSensorIcon: Flow<Boolean> = modalities.map { it.isEmpty }.distinctUntilChanged() /** The label to use for the cancel button. */ val negativeButtonText: Flow<String> = @@ -896,6 +899,7 @@ constructor( */ fun onSwitchToCredential() { _forceLargeSize.value = true + promptSelectorInteractor.onSwitchToCredential() } private fun vibrateOnSuccess() { diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt index de3b741b762c..7597e62a8e81 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt @@ -649,7 +649,6 @@ open class AuthContainerViewTest : SysuiTestCase() { lockPatternUtils, interactionJankMonitor, { promptSelectorInteractor }, - { bpCredentialInteractor }, PromptViewModel( displayStateInteractor, promptSelectorInteractor, diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/data/repository/PromptRepositoryImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/data/repository/PromptRepositoryImplTest.kt index df0e5a718ed9..5e4272f125d7 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/data/repository/PromptRepositoryImplTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/data/repository/PromptRepositoryImplTest.kt @@ -16,13 +16,8 @@ package com.android.systemui.biometrics.data.repository -import android.hardware.biometrics.BiometricManager -import android.hardware.biometrics.Flags.FLAG_CUSTOM_BIOMETRIC_PROMPT -import android.hardware.biometrics.PromptContentViewWithMoreOptionsButton import android.hardware.biometrics.PromptInfo -import android.hardware.biometrics.PromptVerticalListContentView import androidx.test.filters.SmallTest -import com.android.systemui.Flags import com.android.systemui.SysuiTestCase import com.android.systemui.biometrics.AuthController import com.android.systemui.biometrics.shared.model.PromptKind @@ -139,83 +134,6 @@ class PromptRepositoryImplTest : SysuiTestCase() { } @Test - fun showBpWithoutIconForCredential_withVerticalListContentView() = - testScope.runTest { - mSetFlagsRule.enableFlags(Flags.FLAG_CONSTRAINT_BP) - mSetFlagsRule.enableFlags(FLAG_CUSTOM_BIOMETRIC_PROMPT) - for (case in - listOf( - PromptKind.Biometric(), - PromptKind.Pin, - PromptKind.Password, - PromptKind.Pattern - )) { - val hasCredentialViewShown = case !is PromptKind.Biometric - val promptInfo = - PromptInfo().apply { - authenticators = BiometricManager.Authenticators.DEVICE_CREDENTIAL - contentView = PromptVerticalListContentView.Builder().build() - } - repository.setPrompt(promptInfo, USER_ID, CHALLENGE, case, OP_PACKAGE_NAME) - repository.setShouldShowBpWithoutIconForCredential(promptInfo) - - assertThat(repository.showBpWithoutIconForCredential.value) - .isEqualTo(!hasCredentialViewShown) - } - } - - @Test - fun showBpWithoutIconForCredential_withContentViewWithMoreOptionsButton() = - testScope.runTest { - mSetFlagsRule.enableFlags(Flags.FLAG_CONSTRAINT_BP) - mSetFlagsRule.enableFlags(FLAG_CUSTOM_BIOMETRIC_PROMPT) - val promptInfo = - PromptInfo().apply { - authenticators = BiometricManager.Authenticators.DEVICE_CREDENTIAL - contentView = - PromptContentViewWithMoreOptionsButton.Builder() - .setMoreOptionsButtonListener(fakeExecutor) { _, _ -> } - .build() - } - for (case in - listOf( - PromptKind.Biometric(), - PromptKind.Pin, - PromptKind.Password, - PromptKind.Pattern - )) { - repository.setPrompt(promptInfo, USER_ID, CHALLENGE, case, OP_PACKAGE_NAME) - repository.setShouldShowBpWithoutIconForCredential(promptInfo) - - assertThat(repository.showBpWithoutIconForCredential.value).isFalse() - } - } - - @Test - fun showBpWithoutIconForCredential_withDescription() = - testScope.runTest { - mSetFlagsRule.enableFlags(Flags.FLAG_CONSTRAINT_BP) - mSetFlagsRule.enableFlags(FLAG_CUSTOM_BIOMETRIC_PROMPT) - for (case in - listOf( - PromptKind.Biometric(), - PromptKind.Pin, - PromptKind.Password, - PromptKind.Pattern - )) { - val promptInfo = - PromptInfo().apply { - authenticators = BiometricManager.Authenticators.DEVICE_CREDENTIAL - description = "description" - } - repository.setPrompt(promptInfo, USER_ID, CHALLENGE, case, OP_PACKAGE_NAME) - repository.setShouldShowBpWithoutIconForCredential(promptInfo) - - assertThat(repository.showBpWithoutIconForCredential.value).isFalse() - } - } - - @Test fun setsAndUnsetsPrompt() = testScope.runTest { val kind = PromptKind.Pin @@ -223,7 +141,7 @@ class PromptRepositoryImplTest : SysuiTestCase() { repository.setPrompt(promptInfo, USER_ID, CHALLENGE, kind, OP_PACKAGE_NAME) - assertThat(repository.kind.value).isEqualTo(kind) + assertThat(repository.promptKind.value).isEqualTo(kind) assertThat(repository.userId.value).isEqualTo(USER_ID) assertThat(repository.challenge.value).isEqualTo(CHALLENGE) assertThat(repository.promptInfo.value).isSameInstanceAs(promptInfo) diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/interactor/PromptSelectorInteractorImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/interactor/PromptSelectorInteractorImplTest.kt index c308507fdd90..e0324df8048a 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/interactor/PromptSelectorInteractorImplTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/interactor/PromptSelectorInteractorImplTest.kt @@ -18,7 +18,9 @@ package com.android.systemui.biometrics.domain.interactor import android.app.admin.DevicePolicyManager import android.hardware.biometrics.BiometricManager.Authenticators +import android.hardware.biometrics.PromptContentViewWithMoreOptionsButton import android.hardware.biometrics.PromptInfo +import android.hardware.biometrics.PromptVerticalListContentView import androidx.test.filters.SmallTest import com.android.internal.widget.LockPatternUtils import com.android.systemui.SysuiTestCase @@ -29,8 +31,10 @@ import com.android.systemui.biometrics.fingerprintSensorPropertiesInternal import com.android.systemui.biometrics.shared.model.BiometricModalities import com.android.systemui.biometrics.shared.model.PromptKind import com.android.systemui.coroutines.collectLastValue +import com.android.systemui.util.concurrency.FakeExecutor import com.android.systemui.util.mockito.any import com.android.systemui.util.mockito.whenever +import com.android.systemui.util.time.FakeSystemClock import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.TestScope @@ -64,6 +68,7 @@ class PromptSelectorInteractorImplTest : SysuiTestCase() { private val testScope = TestScope() private val fingerprintRepository = FakeFingerprintPropertyRepository() private val promptRepository = FakePromptRepository() + private val fakeExecutor = FakeExecutor(FakeSystemClock()) private lateinit var interactor: PromptSelectorInteractor @@ -73,6 +78,23 @@ class PromptSelectorInteractorImplTest : SysuiTestCase() { PromptSelectorInteractorImpl(fingerprintRepository, promptRepository, lockPatternUtils) } + private fun basicPromptInfo() = + PromptInfo().apply { + title = TITLE + subtitle = SUBTITLE + description = DESCRIPTION + negativeButtonText = NEGATIVE_TEXT + isConfirmationRequested = true + isDeviceCredentialAllowed = true + authenticators = Authenticators.BIOMETRIC_STRONG or Authenticators.DEVICE_CREDENTIAL + } + + private val modalities = + BiometricModalities( + fingerprintProperties = fingerprintSensorPropertiesInternal().first(), + faceProperties = faceSensorPropertiesInternal().first(), + ) + @Test fun useBiometricsAndReset() = testScope.runTest { useBiometricsAndReset(allowCredentialFallback = true) } @@ -86,11 +108,7 @@ class PromptSelectorInteractorImplTest : SysuiTestCase() { val confirmationRequired = true val info = - PromptInfo().apply { - title = TITLE - subtitle = SUBTITLE - description = DESCRIPTION - negativeButtonText = NEGATIVE_TEXT + basicPromptInfo().apply { isConfirmationRequested = confirmationRequired authenticators = if (allowCredentialFallback) { @@ -100,25 +118,22 @@ class PromptSelectorInteractorImplTest : SysuiTestCase() { } isDeviceCredentialAllowed = allowCredentialFallback } - val modalities = - BiometricModalities( - fingerprintProperties = fingerprintSensorPropertiesInternal().first(), - faceProperties = faceSensorPropertiesInternal().first(), - ) val currentPrompt by collectLastValue(interactor.prompt) - val credentialKind by collectLastValue(interactor.credentialKind) + val promptKind by collectLastValue(interactor.promptKind) val isCredentialAllowed by collectLastValue(interactor.isCredentialAllowed) - val isExplicitConfirmationRequired by collectLastValue(interactor.isConfirmationRequired) + val credentialKind by collectLastValue(interactor.credentialKind) + val isConfirmationRequired by collectLastValue(interactor.isConfirmationRequired) assertThat(currentPrompt).isNull() - interactor.useBiometricsForAuthentication( + interactor.setPrompt( info, USER_ID, - CHALLENGE, modalities, - OP_PACKAGE_NAME + CHALLENGE, + OP_PACKAGE_NAME, + false /*onSwitchToCredential*/ ) assertThat(currentPrompt).isNotNull() @@ -127,15 +142,16 @@ class PromptSelectorInteractorImplTest : SysuiTestCase() { assertThat(currentPrompt?.subtitle).isEqualTo(SUBTITLE) assertThat(currentPrompt?.negativeButtonText).isEqualTo(NEGATIVE_TEXT) assertThat(currentPrompt?.opPackageName).isEqualTo(OP_PACKAGE_NAME) + assertThat(promptKind!!.isBiometric()).isTrue() if (allowCredentialFallback) { assertThat(credentialKind).isSameInstanceAs(PromptKind.Password) assertThat(isCredentialAllowed).isTrue() } else { - assertThat(credentialKind).isEqualTo(PromptKind.Biometric()) + assertThat(credentialKind).isEqualTo(PromptKind.None) assertThat(isCredentialAllowed).isFalse() } - assertThat(isExplicitConfirmationRequired).isEqualTo(confirmationRequired) + assertThat(isConfirmationRequired).isEqualTo(confirmationRequired) interactor.resetPrompt() verifyUnset() @@ -152,6 +168,143 @@ class PromptSelectorInteractorImplTest : SysuiTestCase() { fun usePasswordCredentialAndReset() = testScope.runTest { useCredentialAndReset(PromptKind.Password) } + @Test + fun promptKind_isBiometric_whenBiometricAllowed() = + testScope.runTest { + setUserCredentialType(isPassword = true) + val info = basicPromptInfo() + + val promptKind by collectLastValue(interactor.promptKind) + assertThat(promptKind).isEqualTo(PromptKind.None) + + interactor.setPrompt( + info, + USER_ID, + modalities, + CHALLENGE, + OP_PACKAGE_NAME, + false /*onSwitchToCredential*/ + ) + + assertThat(promptKind?.isBiometric()).isTrue() + + interactor.resetPrompt() + verifyUnset() + } + + @Test + fun promptKind_isCredential_onSwitchToCredential() = + testScope.runTest { + setUserCredentialType(isPassword = true) + val info = basicPromptInfo() + + val promptKind by collectLastValue(interactor.promptKind) + assertThat(promptKind).isEqualTo(PromptKind.None) + + interactor.setPrompt( + info, + USER_ID, + modalities, + CHALLENGE, + OP_PACKAGE_NAME, + true /*onSwitchToCredential*/ + ) + + assertThat(promptKind).isEqualTo(PromptKind.Password) + + interactor.resetPrompt() + verifyUnset() + } + + @Test + fun promptKind_isCredential_whenBiometricIsNotAllowed() = + testScope.runTest { + setUserCredentialType(isPassword = true) + val info = + basicPromptInfo().apply { + isDeviceCredentialAllowed = true + authenticators = Authenticators.DEVICE_CREDENTIAL + } + + val promptKind by collectLastValue(interactor.promptKind) + assertThat(promptKind).isEqualTo(PromptKind.None) + + interactor.setPrompt( + info, + USER_ID, + modalities, + CHALLENGE, + OP_PACKAGE_NAME, + false /*onSwitchToCredential*/ + ) + + assertThat(promptKind).isEqualTo(PromptKind.Password) + + interactor.resetPrompt() + verifyUnset() + } + + @Test + fun promptKind_isCredential_whenBiometricIsNotAllowed_withMoreOptionsButton() = + testScope.runTest { + setUserCredentialType(isPassword = true) + val info = + basicPromptInfo().apply { + isDeviceCredentialAllowed = true + authenticators = Authenticators.DEVICE_CREDENTIAL + contentView = + PromptContentViewWithMoreOptionsButton.Builder() + .setMoreOptionsButtonListener(fakeExecutor) { _, _ -> } + .build() + } + + val promptKind by collectLastValue(interactor.promptKind) + assertThat(promptKind).isEqualTo(PromptKind.None) + + interactor.setPrompt( + info, + USER_ID, + modalities, + CHALLENGE, + OP_PACKAGE_NAME, + false /*onSwitchToCredential*/ + ) + + assertThat(promptKind).isEqualTo(PromptKind.Password) + + interactor.resetPrompt() + verifyUnset() + } + + @Test + fun promptKind_isBiometric_whenBiometricIsNotAllowed_withVerticalList() = + testScope.runTest { + setUserCredentialType(isPassword = true) + val info = + basicPromptInfo().apply { + isDeviceCredentialAllowed = true + authenticators = Authenticators.DEVICE_CREDENTIAL + contentView = PromptVerticalListContentView.Builder().build() + } + + val promptKind by collectLastValue(interactor.promptKind) + assertThat(promptKind).isEqualTo(PromptKind.None) + + interactor.setPrompt( + info, + USER_ID, + modalities, + CHALLENGE, + OP_PACKAGE_NAME, + false /*onSwitchToCredential*/ + ) + + assertThat(promptKind?.isBiometric()).isTrue() + + interactor.resetPrompt() + verifyUnset() + } + private fun TestScope.useCredentialAndReset(kind: PromptKind) { setUserCredentialType( isPin = kind == PromptKind.Pin, @@ -173,11 +326,18 @@ class PromptSelectorInteractorImplTest : SysuiTestCase() { assertThat(currentPrompt).isNull() - interactor.useCredentialsForAuthentication(info, kind, USER_ID, CHALLENGE, OP_PACKAGE_NAME) + interactor.setPrompt( + info, + USER_ID, + BiometricModalities(), + CHALLENGE, + OP_PACKAGE_NAME, + false /*onSwitchToCredential*/ + ) // not using biometrics, should be null with no fallback option assertThat(currentPrompt).isNull() - assertThat(credentialKind).isEqualTo(PromptKind.Biometric()) + assertThat(credentialKind).isEqualTo(PromptKind.None) interactor.resetPrompt() verifyUnset() @@ -185,13 +345,16 @@ class PromptSelectorInteractorImplTest : SysuiTestCase() { private fun TestScope.verifyUnset() { val currentPrompt by collectLastValue(interactor.prompt) + val promptKind by collectLastValue(interactor.promptKind) + val isCredentialAllowed by collectLastValue(interactor.isCredentialAllowed) val credentialKind by collectLastValue(interactor.credentialKind) + val isConfirmationRequired by collectLastValue(interactor.isConfirmationRequired) assertThat(currentPrompt).isNull() - - val kind = credentialKind as? PromptKind.Biometric - assertThat(kind).isNotNull() - assertThat(kind?.activeModalities?.isEmpty).isTrue() + assertThat(promptKind).isEqualTo(PromptKind.None) + assertThat(isCredentialAllowed).isFalse() + assertThat(credentialKind).isEqualTo(PromptKind.None) + assertThat(isConfirmationRequired).isFalse() } private fun setUserCredentialType(isPin: Boolean = false, isPassword: Boolean = false) { diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModelTest.kt index a7324182a91a..aae7ff6a71a2 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModelTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModelTest.kt @@ -169,8 +169,11 @@ internal class PromptViewModelTest(private val testCase: TestCase) : SysuiTestCa ) biometricStatusRepository = FakeBiometricStatusRepository() biometricStatusInteractor = - BiometricStatusInteractorImpl(activityTaskManager, biometricStatusRepository, - fingerprintRepository) + BiometricStatusInteractorImpl( + activityTaskManager, + biometricStatusRepository, + fingerprintRepository + ) selector = PromptSelectorInteractorImpl(fingerprintRepository, promptRepository, lockPatternUtils) selector.resetPrompt() @@ -183,7 +186,7 @@ internal class PromptViewModelTest(private val testCase: TestCase) : SysuiTestCa promptContentViewWithMoreOptionsButton = PromptContentViewWithMoreOptionsButton.Builder() .setDescription("test") - .setMoreOptionsButtonListener(fakeExecutor, { _, _ -> }) + .setMoreOptionsButtonListener(fakeExecutor) { _, _ -> } .build() viewModel = @@ -1630,12 +1633,13 @@ private fun PromptSelectorInteractor.initializePrompt( isConfirmationRequested = requireConfirmation } - useBiometricsForAuthentication( + setPrompt( info, USER_ID, - CHALLENGE, BiometricModalities(fingerprintProperties = fingerprint, faceProperties = face), + CHALLENGE, packageName, + false /*onUseDeviceCredential*/ ) } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/data/repository/FakePromptRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/data/repository/FakePromptRepository.kt index 0975687b4744..e37bdc15c0ac 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/data/repository/FakePromptRepository.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/data/repository/FakePromptRepository.kt @@ -1,8 +1,6 @@ package com.android.systemui.biometrics.data.repository -import android.hardware.biometrics.Flags import android.hardware.biometrics.PromptInfo -import com.android.systemui.biometrics.Utils import com.android.systemui.biometrics.shared.model.PromptKind import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asStateFlow @@ -22,15 +20,12 @@ class FakePromptRepository : PromptRepository { private var _challenge = MutableStateFlow<Long?>(null) override val challenge = _challenge.asStateFlow() - private val _kind = MutableStateFlow<PromptKind>(PromptKind.Biometric()) - override val kind = _kind.asStateFlow() + private val _promptKind = MutableStateFlow<PromptKind>(PromptKind.None) + override val promptKind = _promptKind.asStateFlow() private val _isConfirmationRequired = MutableStateFlow(false) override val isConfirmationRequired = _isConfirmationRequired.asStateFlow() - private val _showBpWithoutIconForCredential = MutableStateFlow(false) - override val showBpWithoutIconForCredential = _showBpWithoutIconForCredential.asStateFlow() - private val _opPackageName: MutableStateFlow<String?> = MutableStateFlow(null) override val opPackageName = _opPackageName.asStateFlow() @@ -61,7 +56,7 @@ class FakePromptRepository : PromptRepository { _promptInfo.value = promptInfo _userId.value = userId _challenge.value = gatekeeperChallenge - _kind.value = kind + _promptKind.value = kind _isConfirmationRequired.value = promptInfo.isConfirmationRequested || forceConfirmation _opPackageName.value = opPackageName } @@ -70,22 +65,11 @@ class FakePromptRepository : PromptRepository { _promptInfo.value = null _userId.value = null _challenge.value = null - _kind.value = PromptKind.Biometric() + _promptKind.value = PromptKind.None + _opPackageName.value = null _isConfirmationRequired.value = false } - override fun setShouldShowBpWithoutIconForCredential(promptInfo: PromptInfo) { - val hasCredentialViewShown = kind.value !is PromptKind.Biometric - val showBpForCredential = - Flags.customBiometricPrompt() && - com.android.systemui.Flags.constraintBp() && - !Utils.isBiometricAllowed(promptInfo) && - Utils.isDeviceCredentialAllowed(promptInfo) && - promptInfo.contentView != null && - !promptInfo.isContentViewMoreOptionsButtonUsed - _showBpWithoutIconForCredential.value = showBpForCredential && !hasCredentialViewShown - } - fun setIsShowing(showing: Boolean) { _isShowing.value = showing } |