summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/hardware/biometrics/BiometricConstants.java6
-rw-r--r--core/java/android/hardware/biometrics/BiometricManager.java7
-rw-r--r--services/core/java/com/android/server/biometrics/PreAuthInfo.java8
-rw-r--r--services/core/java/com/android/server/biometrics/Utils.java8
-rw-r--r--services/tests/servicestests/src/com/android/server/biometrics/BiometricServiceTest.java27
-rw-r--r--services/tests/servicestests/src/com/android/server/biometrics/PreAuthInfoTest.java24
6 files changed, 77 insertions, 3 deletions
diff --git a/core/java/android/hardware/biometrics/BiometricConstants.java b/core/java/android/hardware/biometrics/BiometricConstants.java
index 8975191b54c1..9355937b0963 100644
--- a/core/java/android/hardware/biometrics/BiometricConstants.java
+++ b/core/java/android/hardware/biometrics/BiometricConstants.java
@@ -170,6 +170,12 @@ public interface BiometricConstants {
int BIOMETRIC_ERROR_MANDATORY_NOT_ACTIVE = 20;
/**
+ * Biometrics is not allowed to verify in apps.
+ * @hide
+ */
+ int BIOMETRIC_ERROR_NOT_ENABLED_FOR_APPS = 21;
+
+ /**
* This constant is only used by SystemUI. It notifies SystemUI that authentication was paused
* because the authentication attempt was unsuccessful.
* @hide
diff --git a/core/java/android/hardware/biometrics/BiometricManager.java b/core/java/android/hardware/biometrics/BiometricManager.java
index 9bc46b9f382a..a4f7485fcaa5 100644
--- a/core/java/android/hardware/biometrics/BiometricManager.java
+++ b/core/java/android/hardware/biometrics/BiometricManager.java
@@ -94,6 +94,13 @@ public class BiometricManager {
BiometricConstants.BIOMETRIC_ERROR_MANDATORY_NOT_ACTIVE;
/**
+ * Biometrics is not allowed to verify in apps.
+ * @hide
+ */
+ public static final int BIOMETRIC_ERROR_NOT_ENABLED_FOR_APPS =
+ BiometricConstants.BIOMETRIC_ERROR_NOT_ENABLED_FOR_APPS;
+
+ /**
* A security vulnerability has been discovered and the sensor is unavailable until a
* security update has addressed this issue. This error can be received if for example,
* authentication was requested with {@link Authenticators#BIOMETRIC_STRONG}, but the
diff --git a/services/core/java/com/android/server/biometrics/PreAuthInfo.java b/services/core/java/com/android/server/biometrics/PreAuthInfo.java
index ac3c02823d0a..b2c616ae5b3c 100644
--- a/services/core/java/com/android/server/biometrics/PreAuthInfo.java
+++ b/services/core/java/com/android/server/biometrics/PreAuthInfo.java
@@ -316,6 +316,7 @@ class PreAuthInfo {
Pair<BiometricSensor, Integer> sensorNotEnrolled = null;
Pair<BiometricSensor, Integer> sensorLockout = null;
Pair<BiometricSensor, Integer> hardwareNotDetected = null;
+ Pair<BiometricSensor, Integer> biometricAppNotAllowed = null;
for (Pair<BiometricSensor, Integer> pair : ineligibleSensors) {
final int status = pair.second;
if (status == BIOMETRIC_LOCKOUT_TIMED || status == BIOMETRIC_LOCKOUT_PERMANENT) {
@@ -327,6 +328,9 @@ class PreAuthInfo {
if (status == BIOMETRIC_HARDWARE_NOT_DETECTED) {
hardwareNotDetected = pair;
}
+ if (status == BIOMETRIC_NOT_ENABLED_FOR_APPS) {
+ biometricAppNotAllowed = pair;
+ }
}
// If there is a sensor locked out, prioritize lockout over other sensor's error.
@@ -339,6 +343,10 @@ class PreAuthInfo {
return hardwareNotDetected;
}
+ if (Flags.mandatoryBiometrics() && biometricAppNotAllowed != null) {
+ return biometricAppNotAllowed;
+ }
+
// If the caller requested STRONG, and the device contains both STRONG and non-STRONG
// sensors, prioritize BIOMETRIC_NOT_ENROLLED over the weak sensor's
// BIOMETRIC_INSUFFICIENT_STRENGTH error.
diff --git a/services/core/java/com/android/server/biometrics/Utils.java b/services/core/java/com/android/server/biometrics/Utils.java
index 871121472938..407ef1e41aa6 100644
--- a/services/core/java/com/android/server/biometrics/Utils.java
+++ b/services/core/java/com/android/server/biometrics/Utils.java
@@ -321,6 +321,9 @@ public class Utils {
case BiometricConstants.BIOMETRIC_ERROR_MANDATORY_NOT_ACTIVE:
biometricManagerCode = BiometricManager.BIOMETRIC_ERROR_MANDATORY_NOT_ACTIVE;
break;
+ case BiometricConstants.BIOMETRIC_ERROR_NOT_ENABLED_FOR_APPS:
+ biometricManagerCode = BiometricManager.BIOMETRIC_ERROR_NOT_ENABLED_FOR_APPS;
+ break;
default:
Slog.e(BiometricService.TAG, "Unhandled result code: " + biometricConstantsCode);
biometricManagerCode = BiometricManager.BIOMETRIC_ERROR_HW_UNAVAILABLE;
@@ -384,9 +387,12 @@ public class Utils {
return BiometricConstants.BIOMETRIC_ERROR_SENSOR_PRIVACY_ENABLED;
case MANDATORY_BIOMETRIC_UNAVAILABLE_ERROR:
return BiometricConstants.BIOMETRIC_ERROR_MANDATORY_NOT_ACTIVE;
+ case BIOMETRIC_NOT_ENABLED_FOR_APPS:
+ if (Flags.mandatoryBiometrics()) {
+ return BiometricConstants.BIOMETRIC_ERROR_NOT_ENABLED_FOR_APPS;
+ }
case BIOMETRIC_DISABLED_BY_DEVICE_POLICY:
case BIOMETRIC_HARDWARE_NOT_DETECTED:
- case BIOMETRIC_NOT_ENABLED_FOR_APPS:
default:
return BiometricConstants.BIOMETRIC_ERROR_HW_UNAVAILABLE;
}
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/BiometricServiceTest.java b/services/tests/servicestests/src/com/android/server/biometrics/BiometricServiceTest.java
index 6b8e414255cd..b4b36125f770 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/BiometricServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/BiometricServiceTest.java
@@ -558,7 +558,9 @@ public class BiometricServiceTest {
waitForIdle();
verify(mReceiver1).onError(
eq(BiometricAuthenticator.TYPE_NONE),
- eq(BiometricConstants.BIOMETRIC_ERROR_HW_UNAVAILABLE),
+ eq(Flags.mandatoryBiometrics()
+ ? BiometricConstants.BIOMETRIC_ERROR_NOT_ENABLED_FOR_APPS
+ : BiometricConstants.BIOMETRIC_ERROR_HW_UNAVAILABLE),
eq(0 /* vendorCode */));
// Enrolled, not disabled in settings, user requires confirmation in settings
@@ -1450,7 +1452,9 @@ public class BiometricServiceTest {
}
@Test
- public void testCanAuthenticate_whenBiometricsNotEnabledForApps() throws Exception {
+ @RequiresFlagsDisabled(Flags.FLAG_MANDATORY_BIOMETRICS)
+ public void testCanAuthenticate_whenBiometricsNotEnabledForApps_returnsHardwareUnavailable()
+ throws Exception {
setupAuthForOnly(TYPE_FACE, Authenticators.BIOMETRIC_STRONG);
when(mBiometricService.mSettingObserver.getEnabledForApps(anyInt())).thenReturn(false);
when(mTrustManager.isDeviceSecure(anyInt(), anyInt()))
@@ -1468,6 +1472,25 @@ public class BiometricServiceTest {
}
@Test
+ @RequiresFlagsEnabled(Flags.FLAG_MANDATORY_BIOMETRICS)
+ public void testCanAuthenticate_whenBiometricsNotEnabledForApps() throws Exception {
+ setupAuthForOnly(TYPE_FACE, Authenticators.BIOMETRIC_STRONG);
+ when(mBiometricService.mSettingObserver.getEnabledForApps(anyInt())).thenReturn(false);
+ when(mTrustManager.isDeviceSecure(anyInt(), anyInt()))
+ .thenReturn(true);
+
+ // When only biometric is requested
+ int authenticators = Authenticators.BIOMETRIC_STRONG;
+ assertEquals(BiometricManager.BIOMETRIC_ERROR_NOT_ENABLED_FOR_APPS,
+ invokeCanAuthenticate(mBiometricService, authenticators));
+
+ // When credential and biometric are requested
+ authenticators = Authenticators.BIOMETRIC_STRONG | Authenticators.DEVICE_CREDENTIAL;
+ assertEquals(BiometricManager.BIOMETRIC_SUCCESS,
+ invokeCanAuthenticate(mBiometricService, authenticators));
+ }
+
+ @Test
public void testCanAuthenticate_whenNoBiometricSensor() throws Exception {
mBiometricService = new BiometricService(mContext, mInjector, mBiometricHandlerProvider);
mBiometricService.onStart();
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/PreAuthInfoTest.java b/services/tests/servicestests/src/com/android/server/biometrics/PreAuthInfoTest.java
index 760d38e855a6..b758f57ff407 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/PreAuthInfoTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/PreAuthInfoTest.java
@@ -20,6 +20,7 @@ import static android.app.admin.DevicePolicyManager.KEYGUARD_DISABLE_FEATURES_NO
import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FACE;
import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FINGERPRINT;
import static android.hardware.biometrics.BiometricManager.BIOMETRIC_ERROR_HW_UNAVAILABLE;
+import static android.hardware.biometrics.BiometricManager.BIOMETRIC_ERROR_NOT_ENABLED_FOR_APPS;
import static com.android.server.biometrics.sensors.LockoutTracker.LOCKOUT_NONE;
@@ -266,6 +267,29 @@ public class PreAuthInfoTest {
@Test
@RequiresFlagsEnabled(Flags.FLAG_MANDATORY_BIOMETRICS)
+ public void testCalculateByPriority()
+ throws Exception {
+ when(mFaceAuthenticator.hasEnrolledTemplates(anyInt(), any())).thenReturn(false);
+ when(mSettingObserver.getEnabledForApps(anyInt())).thenReturn(false);
+
+ BiometricSensor faceSensor = getFaceSensor();
+ BiometricSensor fingerprintSensor = getFingerprintSensor();
+ PromptInfo promptInfo = new PromptInfo();
+ promptInfo.setConfirmationRequested(false /* requireConfirmation */);
+ promptInfo.setAuthenticators(BiometricManager.Authenticators.BIOMETRIC_STRONG);
+ promptInfo.setDisallowBiometricsIfPolicyExists(false /* checkDevicePolicy */);
+ PreAuthInfo preAuthInfo = PreAuthInfo.create(mTrustManager, mDevicePolicyManager,
+ mSettingObserver, List.of(faceSensor, fingerprintSensor),
+ 0 /* userId */, promptInfo, TEST_PACKAGE_NAME,
+ false /* checkDevicePolicyManager */, mContext, mBiometricCameraManager);
+
+ assertThat(preAuthInfo.eligibleSensors).hasSize(0);
+ assertThat(preAuthInfo.getCanAuthenticateResult()).isEqualTo(
+ BIOMETRIC_ERROR_NOT_ENABLED_FOR_APPS);
+ }
+
+ @Test
+ @RequiresFlagsEnabled(Flags.FLAG_MANDATORY_BIOMETRICS)
public void testMandatoryBiometricsNegativeButtonText_whenSet()
throws Exception {
when(mTrustManager.isInSignificantPlace()).thenReturn(false);