Loading core/java/android/hardware/biometrics/flags.aconfig +7 −0 Original line number Diff line number Diff line Loading @@ -86,3 +86,10 @@ flag { description: "This flag is for test API changes related to Identity Check" bug: "347123256" } flag { name: "identity_check_all_surfaces" namespace: "biometrics_framework" description: "This flag applies Identity Check to all biometric prompt requests" bug: "402534668" } services/core/java/com/android/server/biometrics/PreAuthInfo.java +5 −15 Original line number Diff line number Diff line Loading @@ -36,7 +36,6 @@ import android.os.UserManager; import android.util.Pair; import android.util.Slog; import com.android.internal.R; import com.android.server.biometrics.sensors.LockoutTracker; import java.lang.annotation.Retention; Loading Loading @@ -128,7 +127,7 @@ class PreAuthInfo { promptInfo.setDeviceCredentialAllowed(Utils.isCredentialRequested(promptInfo)); final boolean isMandatoryBiometricsAuthentication = updateAuthenticatorsIfIdentityCheckIsActive(promptInfo, effectiveUserId, trustManager, settingObserver, context); trustManager, settingObserver); final boolean biometricRequested = Utils.isBiometricRequested(promptInfo); final int requestedStrength = Utils.getPublicBiometricStrength(promptInfo); Loading Loading @@ -184,24 +183,18 @@ class PreAuthInfo { private static boolean updateAuthenticatorsIfIdentityCheckIsActive(PromptInfo promptInfo, int effectiveUserId, ITrustManager trustManager, BiometricService.SettingObserver settingObserver, Context context) { BiometricService.SettingObserver settingObserver) { if (!Flags.identityCheckTestApi() && dropCredentialFallback(promptInfo.getAuthenticators(), settingObserver.getMandatoryBiometricsEnabledAndRequirementsSatisfiedForUser( effectiveUserId), trustManager)) { promptInfo.setAuthenticators(BiometricManager.Authenticators.BIOMETRIC_STRONG); promptInfo.setIdentityCheckActive(true); if (promptInfo.getNegativeButtonText() == null) { promptInfo.setNegativeButtonText(context.getString(R.string.cancel)); } return true; } else if (Flags.identityCheckTestApi() && (promptInfo.getAuthenticators() & BiometricManager.Authenticators.IDENTITY_CHECK) != 0 && settingObserver.isIdentityCheckActive(effectiveUserId)) { && Utils.shouldApplyIdentityCheck(promptInfo.getAuthenticators()) && settingObserver.isIdentityCheckActive(effectiveUserId)) { promptInfo.setAuthenticators(BiometricManager.Authenticators.BIOMETRIC_STRONG); promptInfo.setIdentityCheckActive(true); if (promptInfo.getNegativeButtonText() == null) { promptInfo.setNegativeButtonText(context.getString(R.string.cancel)); } return true; } Loading @@ -210,10 +203,7 @@ class PreAuthInfo { private static boolean dropCredentialFallback(int authenticators, boolean isMandatoryBiometricsEnabled, ITrustManager trustManager) { final boolean isMandatoryBiometricsRequested = (authenticators & BiometricManager.Authenticators.IDENTITY_CHECK) == BiometricManager.Authenticators.IDENTITY_CHECK; if (isMandatoryBiometricsEnabled && isMandatoryBiometricsRequested) { if (isMandatoryBiometricsEnabled && Utils.shouldApplyIdentityCheck(authenticators)) { try { final boolean isInSignificantPlace = trustManager.isInSignificantPlace(); return !isInSignificantPlace; Loading services/core/java/com/android/server/biometrics/Utils.java +28 −0 Original line number Diff line number Diff line Loading @@ -50,6 +50,7 @@ import android.hardware.biometrics.BiometricConstants; import android.hardware.biometrics.BiometricManager; import android.hardware.biometrics.BiometricPrompt; import android.hardware.biometrics.BiometricPrompt.AuthenticationResultType; import android.hardware.biometrics.Flags; import android.hardware.biometrics.IBiometricService; import android.hardware.biometrics.PromptInfo; import android.hardware.biometrics.SensorProperties; Loading Loading @@ -149,6 +150,33 @@ public class Utils { return (authenticators & Authenticators.IDENTITY_CHECK) != 0; } /** * * @param authenticators composed of one or more values from {@link Authenticators} * @return true if Identity Check requirements should be applied depending on the authenticators */ static boolean shouldApplyIdentityCheck(@Authenticators.Types int authenticators) { final boolean isIdentityCheckAllSurfacesEnabled = Flags.identityCheckAllSurfaces() && Flags.bpFallbackOptions(); final boolean isMandatoryOrBiometricRequested = isMandatoryBiometricsRequested(authenticators) || isBiometricRequested(authenticators); final boolean isOnlyStrongBiometricRequested = isOnlyStrongBiometricRequested(authenticators); if (isIdentityCheckAllSurfacesEnabled) { return isMandatoryOrBiometricRequested && !isOnlyStrongBiometricRequested; } return isMandatoryBiometricsRequested(authenticators); } private static boolean isOnlyStrongBiometricRequested( @Authenticators.Types int authenticators) { return getPublicBiometricStrength(authenticators) == Authenticators.BIOMETRIC_STRONG && !isCredentialRequested(authenticators); } /** * @param promptInfo should be first processed by * {@link #combineAuthenticatorBundles(PromptInfo)} Loading services/tests/servicestests/src/com/android/server/biometrics/PreAuthInfoTest.java +78 −14 Original line number Diff line number Diff line Loading @@ -208,7 +208,7 @@ public class PreAuthInfoTest { @Test @RequiresFlagsEnabled(Flags.FLAG_IDENTITY_CHECK_TEST_API) public void testMandatoryBiometricsStatus_whenAllRequirementsSatisfiedAndSensorAvailable() public void testMandatoryBiometricsStatus_whenAllRequirementsSatisfiedAndSensorAvailable_identityCheckAuthenticator() throws Exception { when(mSettingObserver.isIdentityCheckActive(anyInt())).thenReturn(true); Loading @@ -225,55 +225,102 @@ public class PreAuthInfoTest { @Test @RequiresFlagsEnabled(Flags.FLAG_IDENTITY_CHECK_TEST_API) public void testMandatoryBiometricsStatus_whenAllRequirementsSatisfiedAndSensorUnavailable() public void testMandatoryBiometricsAndStrongBiometricsStatus_whenRequirementsNotSatisfied_identityCheckAuthenticator() throws Exception { when(mSettingObserver.isIdentityCheckActive(anyInt())).thenReturn(true); when(mSettingObserver.isIdentityCheckActive(anyInt())).thenReturn(false); final BiometricSensor sensor = getFaceSensor(); final PromptInfo promptInfo = new PromptInfo(); promptInfo.setAuthenticators(BiometricManager.Authenticators.IDENTITY_CHECK | BiometricManager.Authenticators.BIOMETRIC_STRONG); final PreAuthInfo preAuthInfo = PreAuthInfo.create(mTrustManager, mDevicePolicyManager, mSettingObserver, List.of(sensor), USER_ID, promptInfo, TEST_PACKAGE_NAME, false /* checkDevicePolicyManager */, mContext, mBiometricCameraManager, mUserManager); assertThat(preAuthInfo.eligibleSensors).hasSize(1); } @Test @RequiresFlagsEnabled(Flags.FLAG_IDENTITY_CHECK_TEST_API) public void testMandatoryBiometricsStatus_whenRequirementsNotSatisfiedAndSensorAvailable_identityCheckAuthenticator() throws Exception { when(mSettingObserver.isIdentityCheckActive(anyInt())).thenReturn(false); final BiometricSensor sensor = getFaceSensor(); final PromptInfo promptInfo = new PromptInfo(); promptInfo.setAuthenticators(BiometricManager.Authenticators.IDENTITY_CHECK); final PreAuthInfo preAuthInfo = PreAuthInfo.create(mTrustManager, mDevicePolicyManager, mSettingObserver, List.of(), USER_ID, promptInfo, TEST_PACKAGE_NAME, mSettingObserver, List.of(sensor), USER_ID, promptInfo, TEST_PACKAGE_NAME, false /* checkDevicePolicyManager */, mContext, mBiometricCameraManager, mUserManager); assertThat(preAuthInfo.getCanAuthenticateResult()).isEqualTo( BiometricManager.BIOMETRIC_ERROR_IDENTITY_CHECK_NOT_ACTIVE); assertThat(preAuthInfo.eligibleSensors).hasSize(0); } @Test @RequiresFlagsEnabled(Flags.FLAG_IDENTITY_CHECK_TEST_API) public void testMandatoryBiometricsAndStrongBiometricsStatus_whenRequirementsNotSatisfied() @RequiresFlagsEnabled({Flags.FLAG_IDENTITY_CHECK_TEST_API, Flags.FLAG_IDENTITY_CHECK_ALL_SURFACES, Flags.FLAG_BP_FALLBACK_OPTIONS}) public void testIdentityCheckStatus_whenAllRequirementsSatisfiedAndSensorAvailable_biometricStrongAndDeviceCredential() throws Exception { when(mSettingObserver.isIdentityCheckActive(anyInt())).thenReturn(true); final BiometricSensor sensor = getFaceSensor(); final PromptInfo promptInfo = new PromptInfo(); promptInfo.setAuthenticators(BiometricManager.Authenticators.BIOMETRIC_STRONG | BiometricManager.Authenticators.DEVICE_CREDENTIAL); final PreAuthInfo preAuthInfo = PreAuthInfo.create(mTrustManager, mDevicePolicyManager, mSettingObserver, List.of(sensor), USER_ID, promptInfo, TEST_PACKAGE_NAME, false /* checkDevicePolicyManager */, mContext, mBiometricCameraManager, mUserManager); assertThat(promptInfo.isDeviceCredentialAllowed()).isTrue(); assertThat(preAuthInfo.getIsMandatoryBiometricsAuthentication()).isTrue(); assertThat(preAuthInfo.eligibleSensors).hasSize(1); } @Test @RequiresFlagsEnabled({Flags.FLAG_IDENTITY_CHECK_TEST_API, Flags.FLAG_IDENTITY_CHECK_ALL_SURFACES, Flags.FLAG_BP_FALLBACK_OPTIONS}) public void testIdentityCheckStatus_whenRequirementsNotSatisfied_biometricStrongAndDeviceCredential() throws Exception { when(mSettingObserver.isIdentityCheckActive(anyInt())).thenReturn(false); final BiometricSensor sensor = getFaceSensor(); final PromptInfo promptInfo = new PromptInfo(); promptInfo.setAuthenticators(BiometricManager.Authenticators.IDENTITY_CHECK | BiometricManager.Authenticators.BIOMETRIC_STRONG); promptInfo.setAuthenticators(BiometricManager.Authenticators.BIOMETRIC_STRONG | BiometricManager.Authenticators.DEVICE_CREDENTIAL); final PreAuthInfo preAuthInfo = PreAuthInfo.create(mTrustManager, mDevicePolicyManager, mSettingObserver, List.of(sensor), USER_ID, promptInfo, TEST_PACKAGE_NAME, false /* checkDevicePolicyManager */, mContext, mBiometricCameraManager, mUserManager); assertThat(promptInfo.isDeviceCredentialAllowed()).isTrue(); assertThat(preAuthInfo.getIsMandatoryBiometricsAuthentication()).isFalse(); assertThat(preAuthInfo.eligibleSensors).hasSize(1); } @Test @RequiresFlagsEnabled(Flags.FLAG_IDENTITY_CHECK_TEST_API) public void testMandatoryBiometricsStatus_whenRequirementsNotSatisfiedAndSensorAvailable() @RequiresFlagsEnabled({Flags.FLAG_IDENTITY_CHECK_TEST_API, Flags.FLAG_IDENTITY_CHECK_ALL_SURFACES, Flags.FLAG_BP_FALLBACK_OPTIONS}) public void testIdentityCheckStatus_whenRequirementsNotSatisfiedAndSensorAvailable_biometricStrongAndDeviceCredential() throws Exception { when(mSettingObserver.isIdentityCheckActive(anyInt())).thenReturn(false); final BiometricSensor sensor = getFaceSensor(); final PromptInfo promptInfo = new PromptInfo(); promptInfo.setAuthenticators(BiometricManager.Authenticators.IDENTITY_CHECK); promptInfo.setAuthenticators(BiometricManager.Authenticators.BIOMETRIC_STRONG | BiometricManager.Authenticators.DEVICE_CREDENTIAL); final PreAuthInfo preAuthInfo = PreAuthInfo.create(mTrustManager, mDevicePolicyManager, mSettingObserver, List.of(sensor), USER_ID, promptInfo, TEST_PACKAGE_NAME, false /* checkDevicePolicyManager */, mContext, mBiometricCameraManager, mUserManager); assertThat(preAuthInfo.getCanAuthenticateResult()).isEqualTo( BiometricManager.BIOMETRIC_ERROR_IDENTITY_CHECK_NOT_ACTIVE); assertThat(preAuthInfo.eligibleSensors).hasSize(0); assertThat(promptInfo.isDeviceCredentialAllowed()).isTrue(); assertThat(preAuthInfo.getIsMandatoryBiometricsAuthentication()).isFalse(); assertThat(preAuthInfo.eligibleSensors).hasSize(1); } @Test Loading Loading @@ -315,6 +362,23 @@ public class PreAuthInfoTest { assertThat(promptInfo.getNegativeButtonText()).isEqualTo(TEST_PACKAGE_NAME); } @Test @RequiresFlagsEnabled(Flags.FLAG_IDENTITY_CHECK_TEST_API) public void testMandatoryBiometricsNegativeButtonText_whenNotSet() throws Exception { when(mSettingObserver.isIdentityCheckActive(anyInt())).thenReturn(true); final BiometricSensor sensor = getFaceSensor(); final PromptInfo promptInfo = new PromptInfo(); promptInfo.setAuthenticators(BiometricManager.Authenticators.IDENTITY_CHECK); final PreAuthInfo preAuthInfo = PreAuthInfo.create(mTrustManager, mDevicePolicyManager, mSettingObserver, List.of(sensor), USER_ID, promptInfo, TEST_PACKAGE_NAME, false /* checkDevicePolicyManager */, mContext, mBiometricCameraManager, mUserManager); assertThat(preAuthInfo.getIsMandatoryBiometricsAuthentication()).isTrue(); assertThat(promptInfo.getNegativeButtonText()).isEqualTo(null); } @Test @RequiresFlagsEnabled(Flags.FLAG_EFFECTIVE_USER_BP) public void testCredentialOwnerIdAsUserId() throws Exception { Loading services/tests/servicestests/src/com/android/server/biometrics/UtilsTest.java +33 −0 Original line number Diff line number Diff line Loading @@ -19,6 +19,8 @@ package com.android.server.biometrics; import static android.Manifest.permission.SET_BIOMETRIC_DIALOG_ADVANCED; import static android.hardware.biometrics.BiometricManager.Authenticators; import static com.google.common.truth.Truth.assertThat; import static junit.framework.Assert.assertEquals; import static junit.framework.Assert.assertFalse; import static junit.framework.Assert.assertTrue; Loading @@ -34,8 +36,10 @@ import android.hardware.biometrics.BiometricAuthenticator; import android.hardware.biometrics.BiometricConstants; import android.hardware.biometrics.BiometricManager; import android.hardware.biometrics.BiometricPrompt; import android.hardware.biometrics.Flags; import android.hardware.biometrics.PromptInfo; import android.platform.test.annotations.Presubmit; import android.platform.test.annotations.RequiresFlagsEnabled; import android.platform.test.flag.junit.CheckFlagsRule; import android.platform.test.flag.junit.DeviceFlagsValueProvider; Loading Loading @@ -314,4 +318,33 @@ public class UtilsTest { // All biometric bits are removed assertEquals(0, authenticators & Authenticators.BIOMETRIC_MIN_STRENGTH); } @Test @RequiresFlagsEnabled({Flags.FLAG_IDENTITY_CHECK_ALL_SURFACES, Flags.FLAG_BP_FALLBACK_OPTIONS}) public void testShouldApplyIdentityCheck_singleAuthenticator_returnsTrue() { assertThat(Utils.shouldApplyIdentityCheck(Authenticators.IDENTITY_CHECK)).isTrue(); assertThat(Utils.shouldApplyIdentityCheck(Authenticators.BIOMETRIC_WEAK)).isTrue(); } @Test @RequiresFlagsEnabled({Flags.FLAG_IDENTITY_CHECK_ALL_SURFACES, Flags.FLAG_BP_FALLBACK_OPTIONS}) public void testShouldApplyIdentityCheck_combinationAuthenticators_returnsTrue() { assertThat(Utils.shouldApplyIdentityCheck(Authenticators.IDENTITY_CHECK | Authenticators.DEVICE_CREDENTIAL)).isTrue(); assertThat(Utils.shouldApplyIdentityCheck(Authenticators.DEVICE_CREDENTIAL | Authenticators.BIOMETRIC_STRONG)).isTrue(); assertThat(Utils.shouldApplyIdentityCheck(Authenticators.BIOMETRIC_WEAK | Authenticators.DEVICE_CREDENTIAL)).isTrue(); assertThat(Utils.shouldApplyIdentityCheck(Authenticators.BIOMETRIC_WEAK | Authenticators.IDENTITY_CHECK)).isTrue(); } @Test @RequiresFlagsEnabled({Flags.FLAG_IDENTITY_CHECK_ALL_SURFACES, Flags.FLAG_BP_FALLBACK_OPTIONS}) public void testShouldApplyIdentityCheck_returnsFalse() { assertThat(Utils.shouldApplyIdentityCheck(Authenticators.BIOMETRIC_STRONG | Authenticators.IDENTITY_CHECK)).isFalse(); assertThat(Utils.shouldApplyIdentityCheck(Authenticators.BIOMETRIC_STRONG)).isFalse(); assertThat(Utils.shouldApplyIdentityCheck(Authenticators.DEVICE_CREDENTIAL)).isFalse(); } } Loading
core/java/android/hardware/biometrics/flags.aconfig +7 −0 Original line number Diff line number Diff line Loading @@ -86,3 +86,10 @@ flag { description: "This flag is for test API changes related to Identity Check" bug: "347123256" } flag { name: "identity_check_all_surfaces" namespace: "biometrics_framework" description: "This flag applies Identity Check to all biometric prompt requests" bug: "402534668" }
services/core/java/com/android/server/biometrics/PreAuthInfo.java +5 −15 Original line number Diff line number Diff line Loading @@ -36,7 +36,6 @@ import android.os.UserManager; import android.util.Pair; import android.util.Slog; import com.android.internal.R; import com.android.server.biometrics.sensors.LockoutTracker; import java.lang.annotation.Retention; Loading Loading @@ -128,7 +127,7 @@ class PreAuthInfo { promptInfo.setDeviceCredentialAllowed(Utils.isCredentialRequested(promptInfo)); final boolean isMandatoryBiometricsAuthentication = updateAuthenticatorsIfIdentityCheckIsActive(promptInfo, effectiveUserId, trustManager, settingObserver, context); trustManager, settingObserver); final boolean biometricRequested = Utils.isBiometricRequested(promptInfo); final int requestedStrength = Utils.getPublicBiometricStrength(promptInfo); Loading Loading @@ -184,24 +183,18 @@ class PreAuthInfo { private static boolean updateAuthenticatorsIfIdentityCheckIsActive(PromptInfo promptInfo, int effectiveUserId, ITrustManager trustManager, BiometricService.SettingObserver settingObserver, Context context) { BiometricService.SettingObserver settingObserver) { if (!Flags.identityCheckTestApi() && dropCredentialFallback(promptInfo.getAuthenticators(), settingObserver.getMandatoryBiometricsEnabledAndRequirementsSatisfiedForUser( effectiveUserId), trustManager)) { promptInfo.setAuthenticators(BiometricManager.Authenticators.BIOMETRIC_STRONG); promptInfo.setIdentityCheckActive(true); if (promptInfo.getNegativeButtonText() == null) { promptInfo.setNegativeButtonText(context.getString(R.string.cancel)); } return true; } else if (Flags.identityCheckTestApi() && (promptInfo.getAuthenticators() & BiometricManager.Authenticators.IDENTITY_CHECK) != 0 && settingObserver.isIdentityCheckActive(effectiveUserId)) { && Utils.shouldApplyIdentityCheck(promptInfo.getAuthenticators()) && settingObserver.isIdentityCheckActive(effectiveUserId)) { promptInfo.setAuthenticators(BiometricManager.Authenticators.BIOMETRIC_STRONG); promptInfo.setIdentityCheckActive(true); if (promptInfo.getNegativeButtonText() == null) { promptInfo.setNegativeButtonText(context.getString(R.string.cancel)); } return true; } Loading @@ -210,10 +203,7 @@ class PreAuthInfo { private static boolean dropCredentialFallback(int authenticators, boolean isMandatoryBiometricsEnabled, ITrustManager trustManager) { final boolean isMandatoryBiometricsRequested = (authenticators & BiometricManager.Authenticators.IDENTITY_CHECK) == BiometricManager.Authenticators.IDENTITY_CHECK; if (isMandatoryBiometricsEnabled && isMandatoryBiometricsRequested) { if (isMandatoryBiometricsEnabled && Utils.shouldApplyIdentityCheck(authenticators)) { try { final boolean isInSignificantPlace = trustManager.isInSignificantPlace(); return !isInSignificantPlace; Loading
services/core/java/com/android/server/biometrics/Utils.java +28 −0 Original line number Diff line number Diff line Loading @@ -50,6 +50,7 @@ import android.hardware.biometrics.BiometricConstants; import android.hardware.biometrics.BiometricManager; import android.hardware.biometrics.BiometricPrompt; import android.hardware.biometrics.BiometricPrompt.AuthenticationResultType; import android.hardware.biometrics.Flags; import android.hardware.biometrics.IBiometricService; import android.hardware.biometrics.PromptInfo; import android.hardware.biometrics.SensorProperties; Loading Loading @@ -149,6 +150,33 @@ public class Utils { return (authenticators & Authenticators.IDENTITY_CHECK) != 0; } /** * * @param authenticators composed of one or more values from {@link Authenticators} * @return true if Identity Check requirements should be applied depending on the authenticators */ static boolean shouldApplyIdentityCheck(@Authenticators.Types int authenticators) { final boolean isIdentityCheckAllSurfacesEnabled = Flags.identityCheckAllSurfaces() && Flags.bpFallbackOptions(); final boolean isMandatoryOrBiometricRequested = isMandatoryBiometricsRequested(authenticators) || isBiometricRequested(authenticators); final boolean isOnlyStrongBiometricRequested = isOnlyStrongBiometricRequested(authenticators); if (isIdentityCheckAllSurfacesEnabled) { return isMandatoryOrBiometricRequested && !isOnlyStrongBiometricRequested; } return isMandatoryBiometricsRequested(authenticators); } private static boolean isOnlyStrongBiometricRequested( @Authenticators.Types int authenticators) { return getPublicBiometricStrength(authenticators) == Authenticators.BIOMETRIC_STRONG && !isCredentialRequested(authenticators); } /** * @param promptInfo should be first processed by * {@link #combineAuthenticatorBundles(PromptInfo)} Loading
services/tests/servicestests/src/com/android/server/biometrics/PreAuthInfoTest.java +78 −14 Original line number Diff line number Diff line Loading @@ -208,7 +208,7 @@ public class PreAuthInfoTest { @Test @RequiresFlagsEnabled(Flags.FLAG_IDENTITY_CHECK_TEST_API) public void testMandatoryBiometricsStatus_whenAllRequirementsSatisfiedAndSensorAvailable() public void testMandatoryBiometricsStatus_whenAllRequirementsSatisfiedAndSensorAvailable_identityCheckAuthenticator() throws Exception { when(mSettingObserver.isIdentityCheckActive(anyInt())).thenReturn(true); Loading @@ -225,55 +225,102 @@ public class PreAuthInfoTest { @Test @RequiresFlagsEnabled(Flags.FLAG_IDENTITY_CHECK_TEST_API) public void testMandatoryBiometricsStatus_whenAllRequirementsSatisfiedAndSensorUnavailable() public void testMandatoryBiometricsAndStrongBiometricsStatus_whenRequirementsNotSatisfied_identityCheckAuthenticator() throws Exception { when(mSettingObserver.isIdentityCheckActive(anyInt())).thenReturn(true); when(mSettingObserver.isIdentityCheckActive(anyInt())).thenReturn(false); final BiometricSensor sensor = getFaceSensor(); final PromptInfo promptInfo = new PromptInfo(); promptInfo.setAuthenticators(BiometricManager.Authenticators.IDENTITY_CHECK | BiometricManager.Authenticators.BIOMETRIC_STRONG); final PreAuthInfo preAuthInfo = PreAuthInfo.create(mTrustManager, mDevicePolicyManager, mSettingObserver, List.of(sensor), USER_ID, promptInfo, TEST_PACKAGE_NAME, false /* checkDevicePolicyManager */, mContext, mBiometricCameraManager, mUserManager); assertThat(preAuthInfo.eligibleSensors).hasSize(1); } @Test @RequiresFlagsEnabled(Flags.FLAG_IDENTITY_CHECK_TEST_API) public void testMandatoryBiometricsStatus_whenRequirementsNotSatisfiedAndSensorAvailable_identityCheckAuthenticator() throws Exception { when(mSettingObserver.isIdentityCheckActive(anyInt())).thenReturn(false); final BiometricSensor sensor = getFaceSensor(); final PromptInfo promptInfo = new PromptInfo(); promptInfo.setAuthenticators(BiometricManager.Authenticators.IDENTITY_CHECK); final PreAuthInfo preAuthInfo = PreAuthInfo.create(mTrustManager, mDevicePolicyManager, mSettingObserver, List.of(), USER_ID, promptInfo, TEST_PACKAGE_NAME, mSettingObserver, List.of(sensor), USER_ID, promptInfo, TEST_PACKAGE_NAME, false /* checkDevicePolicyManager */, mContext, mBiometricCameraManager, mUserManager); assertThat(preAuthInfo.getCanAuthenticateResult()).isEqualTo( BiometricManager.BIOMETRIC_ERROR_IDENTITY_CHECK_NOT_ACTIVE); assertThat(preAuthInfo.eligibleSensors).hasSize(0); } @Test @RequiresFlagsEnabled(Flags.FLAG_IDENTITY_CHECK_TEST_API) public void testMandatoryBiometricsAndStrongBiometricsStatus_whenRequirementsNotSatisfied() @RequiresFlagsEnabled({Flags.FLAG_IDENTITY_CHECK_TEST_API, Flags.FLAG_IDENTITY_CHECK_ALL_SURFACES, Flags.FLAG_BP_FALLBACK_OPTIONS}) public void testIdentityCheckStatus_whenAllRequirementsSatisfiedAndSensorAvailable_biometricStrongAndDeviceCredential() throws Exception { when(mSettingObserver.isIdentityCheckActive(anyInt())).thenReturn(true); final BiometricSensor sensor = getFaceSensor(); final PromptInfo promptInfo = new PromptInfo(); promptInfo.setAuthenticators(BiometricManager.Authenticators.BIOMETRIC_STRONG | BiometricManager.Authenticators.DEVICE_CREDENTIAL); final PreAuthInfo preAuthInfo = PreAuthInfo.create(mTrustManager, mDevicePolicyManager, mSettingObserver, List.of(sensor), USER_ID, promptInfo, TEST_PACKAGE_NAME, false /* checkDevicePolicyManager */, mContext, mBiometricCameraManager, mUserManager); assertThat(promptInfo.isDeviceCredentialAllowed()).isTrue(); assertThat(preAuthInfo.getIsMandatoryBiometricsAuthentication()).isTrue(); assertThat(preAuthInfo.eligibleSensors).hasSize(1); } @Test @RequiresFlagsEnabled({Flags.FLAG_IDENTITY_CHECK_TEST_API, Flags.FLAG_IDENTITY_CHECK_ALL_SURFACES, Flags.FLAG_BP_FALLBACK_OPTIONS}) public void testIdentityCheckStatus_whenRequirementsNotSatisfied_biometricStrongAndDeviceCredential() throws Exception { when(mSettingObserver.isIdentityCheckActive(anyInt())).thenReturn(false); final BiometricSensor sensor = getFaceSensor(); final PromptInfo promptInfo = new PromptInfo(); promptInfo.setAuthenticators(BiometricManager.Authenticators.IDENTITY_CHECK | BiometricManager.Authenticators.BIOMETRIC_STRONG); promptInfo.setAuthenticators(BiometricManager.Authenticators.BIOMETRIC_STRONG | BiometricManager.Authenticators.DEVICE_CREDENTIAL); final PreAuthInfo preAuthInfo = PreAuthInfo.create(mTrustManager, mDevicePolicyManager, mSettingObserver, List.of(sensor), USER_ID, promptInfo, TEST_PACKAGE_NAME, false /* checkDevicePolicyManager */, mContext, mBiometricCameraManager, mUserManager); assertThat(promptInfo.isDeviceCredentialAllowed()).isTrue(); assertThat(preAuthInfo.getIsMandatoryBiometricsAuthentication()).isFalse(); assertThat(preAuthInfo.eligibleSensors).hasSize(1); } @Test @RequiresFlagsEnabled(Flags.FLAG_IDENTITY_CHECK_TEST_API) public void testMandatoryBiometricsStatus_whenRequirementsNotSatisfiedAndSensorAvailable() @RequiresFlagsEnabled({Flags.FLAG_IDENTITY_CHECK_TEST_API, Flags.FLAG_IDENTITY_CHECK_ALL_SURFACES, Flags.FLAG_BP_FALLBACK_OPTIONS}) public void testIdentityCheckStatus_whenRequirementsNotSatisfiedAndSensorAvailable_biometricStrongAndDeviceCredential() throws Exception { when(mSettingObserver.isIdentityCheckActive(anyInt())).thenReturn(false); final BiometricSensor sensor = getFaceSensor(); final PromptInfo promptInfo = new PromptInfo(); promptInfo.setAuthenticators(BiometricManager.Authenticators.IDENTITY_CHECK); promptInfo.setAuthenticators(BiometricManager.Authenticators.BIOMETRIC_STRONG | BiometricManager.Authenticators.DEVICE_CREDENTIAL); final PreAuthInfo preAuthInfo = PreAuthInfo.create(mTrustManager, mDevicePolicyManager, mSettingObserver, List.of(sensor), USER_ID, promptInfo, TEST_PACKAGE_NAME, false /* checkDevicePolicyManager */, mContext, mBiometricCameraManager, mUserManager); assertThat(preAuthInfo.getCanAuthenticateResult()).isEqualTo( BiometricManager.BIOMETRIC_ERROR_IDENTITY_CHECK_NOT_ACTIVE); assertThat(preAuthInfo.eligibleSensors).hasSize(0); assertThat(promptInfo.isDeviceCredentialAllowed()).isTrue(); assertThat(preAuthInfo.getIsMandatoryBiometricsAuthentication()).isFalse(); assertThat(preAuthInfo.eligibleSensors).hasSize(1); } @Test Loading Loading @@ -315,6 +362,23 @@ public class PreAuthInfoTest { assertThat(promptInfo.getNegativeButtonText()).isEqualTo(TEST_PACKAGE_NAME); } @Test @RequiresFlagsEnabled(Flags.FLAG_IDENTITY_CHECK_TEST_API) public void testMandatoryBiometricsNegativeButtonText_whenNotSet() throws Exception { when(mSettingObserver.isIdentityCheckActive(anyInt())).thenReturn(true); final BiometricSensor sensor = getFaceSensor(); final PromptInfo promptInfo = new PromptInfo(); promptInfo.setAuthenticators(BiometricManager.Authenticators.IDENTITY_CHECK); final PreAuthInfo preAuthInfo = PreAuthInfo.create(mTrustManager, mDevicePolicyManager, mSettingObserver, List.of(sensor), USER_ID, promptInfo, TEST_PACKAGE_NAME, false /* checkDevicePolicyManager */, mContext, mBiometricCameraManager, mUserManager); assertThat(preAuthInfo.getIsMandatoryBiometricsAuthentication()).isTrue(); assertThat(promptInfo.getNegativeButtonText()).isEqualTo(null); } @Test @RequiresFlagsEnabled(Flags.FLAG_EFFECTIVE_USER_BP) public void testCredentialOwnerIdAsUserId() throws Exception { Loading
services/tests/servicestests/src/com/android/server/biometrics/UtilsTest.java +33 −0 Original line number Diff line number Diff line Loading @@ -19,6 +19,8 @@ package com.android.server.biometrics; import static android.Manifest.permission.SET_BIOMETRIC_DIALOG_ADVANCED; import static android.hardware.biometrics.BiometricManager.Authenticators; import static com.google.common.truth.Truth.assertThat; import static junit.framework.Assert.assertEquals; import static junit.framework.Assert.assertFalse; import static junit.framework.Assert.assertTrue; Loading @@ -34,8 +36,10 @@ import android.hardware.biometrics.BiometricAuthenticator; import android.hardware.biometrics.BiometricConstants; import android.hardware.biometrics.BiometricManager; import android.hardware.biometrics.BiometricPrompt; import android.hardware.biometrics.Flags; import android.hardware.biometrics.PromptInfo; import android.platform.test.annotations.Presubmit; import android.platform.test.annotations.RequiresFlagsEnabled; import android.platform.test.flag.junit.CheckFlagsRule; import android.platform.test.flag.junit.DeviceFlagsValueProvider; Loading Loading @@ -314,4 +318,33 @@ public class UtilsTest { // All biometric bits are removed assertEquals(0, authenticators & Authenticators.BIOMETRIC_MIN_STRENGTH); } @Test @RequiresFlagsEnabled({Flags.FLAG_IDENTITY_CHECK_ALL_SURFACES, Flags.FLAG_BP_FALLBACK_OPTIONS}) public void testShouldApplyIdentityCheck_singleAuthenticator_returnsTrue() { assertThat(Utils.shouldApplyIdentityCheck(Authenticators.IDENTITY_CHECK)).isTrue(); assertThat(Utils.shouldApplyIdentityCheck(Authenticators.BIOMETRIC_WEAK)).isTrue(); } @Test @RequiresFlagsEnabled({Flags.FLAG_IDENTITY_CHECK_ALL_SURFACES, Flags.FLAG_BP_FALLBACK_OPTIONS}) public void testShouldApplyIdentityCheck_combinationAuthenticators_returnsTrue() { assertThat(Utils.shouldApplyIdentityCheck(Authenticators.IDENTITY_CHECK | Authenticators.DEVICE_CREDENTIAL)).isTrue(); assertThat(Utils.shouldApplyIdentityCheck(Authenticators.DEVICE_CREDENTIAL | Authenticators.BIOMETRIC_STRONG)).isTrue(); assertThat(Utils.shouldApplyIdentityCheck(Authenticators.BIOMETRIC_WEAK | Authenticators.DEVICE_CREDENTIAL)).isTrue(); assertThat(Utils.shouldApplyIdentityCheck(Authenticators.BIOMETRIC_WEAK | Authenticators.IDENTITY_CHECK)).isTrue(); } @Test @RequiresFlagsEnabled({Flags.FLAG_IDENTITY_CHECK_ALL_SURFACES, Flags.FLAG_BP_FALLBACK_OPTIONS}) public void testShouldApplyIdentityCheck_returnsFalse() { assertThat(Utils.shouldApplyIdentityCheck(Authenticators.BIOMETRIC_STRONG | Authenticators.IDENTITY_CHECK)).isFalse(); assertThat(Utils.shouldApplyIdentityCheck(Authenticators.BIOMETRIC_STRONG)).isFalse(); assertThat(Utils.shouldApplyIdentityCheck(Authenticators.DEVICE_CREDENTIAL)).isFalse(); } }