Merge "Identity Check API" into main
diff --git a/core/api/current.txt b/core/api/current.txt
index 959e533..13e1210 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -19034,7 +19034,9 @@
method @FlaggedApi("android.hardware.biometrics.last_authentication_time") @RequiresPermission(android.Manifest.permission.USE_BIOMETRIC) public long getLastAuthenticationTime(int);
method @NonNull @RequiresPermission(android.Manifest.permission.USE_BIOMETRIC) public android.hardware.biometrics.BiometricManager.Strings getStrings(int);
field public static final int BIOMETRIC_ERROR_HW_UNAVAILABLE = 1; // 0x1
+ field @FlaggedApi("android.hardware.biometrics.identity_check_api") public static final int BIOMETRIC_ERROR_IDENTITY_CHECK_NOT_ACTIVE = 20; // 0x14
field public static final int BIOMETRIC_ERROR_NONE_ENROLLED = 11; // 0xb
+ field @FlaggedApi("android.hardware.biometrics.identity_check_api") public static final int BIOMETRIC_ERROR_NOT_ENABLED_FOR_APPS = 21; // 0x15
field public static final int BIOMETRIC_ERROR_NO_HARDWARE = 12; // 0xc
field public static final int BIOMETRIC_ERROR_SECURITY_UPDATE_REQUIRED = 15; // 0xf
field @FlaggedApi("android.hardware.biometrics.last_authentication_time") public static final long BIOMETRIC_NO_AUTHENTICATION = -1L; // 0xffffffffffffffffL
@@ -19045,6 +19047,7 @@
field public static final int BIOMETRIC_STRONG = 15; // 0xf
field public static final int BIOMETRIC_WEAK = 255; // 0xff
field public static final int DEVICE_CREDENTIAL = 32768; // 0x8000
+ field @FlaggedApi("android.hardware.biometrics.identity_check_api") public static final int IDENTITY_CHECK = 65536; // 0x10000
}
public static class BiometricManager.Strings {
@@ -19077,8 +19080,10 @@
field public static final int BIOMETRIC_ERROR_CANCELED = 5; // 0x5
field public static final int BIOMETRIC_ERROR_HW_NOT_PRESENT = 12; // 0xc
field public static final int BIOMETRIC_ERROR_HW_UNAVAILABLE = 1; // 0x1
+ field @FlaggedApi("android.hardware.biometrics.identity_check_api") public static final int BIOMETRIC_ERROR_IDENTITY_CHECK_NOT_ACTIVE = 20; // 0x14
field public static final int BIOMETRIC_ERROR_LOCKOUT = 7; // 0x7
field public static final int BIOMETRIC_ERROR_LOCKOUT_PERMANENT = 9; // 0x9
+ field @FlaggedApi("android.hardware.biometrics.identity_check_api") public static final int BIOMETRIC_ERROR_NOT_ENABLED_FOR_APPS = 21; // 0x15
field public static final int BIOMETRIC_ERROR_NO_BIOMETRICS = 11; // 0xb
field public static final int BIOMETRIC_ERROR_NO_DEVICE_CREDENTIAL = 14; // 0xe
field public static final int BIOMETRIC_ERROR_NO_SPACE = 4; // 0x4
diff --git a/core/java/android/hardware/biometrics/BiometricConstants.java b/core/java/android/hardware/biometrics/BiometricConstants.java
index 9355937..f649e47 100644
--- a/core/java/android/hardware/biometrics/BiometricConstants.java
+++ b/core/java/android/hardware/biometrics/BiometricConstants.java
@@ -164,15 +164,18 @@
int BIOMETRIC_ERROR_POWER_PRESSED = 19;
/**
- * Mandatory biometrics is not in effect.
- * @hide
+ * Identity Check is currently not active.
+ *
+ * This device either doesn't have this feature enabled, or it's not considered in a
+ * high-risk environment that requires extra security measures for accessing sensitive data.
*/
- int BIOMETRIC_ERROR_MANDATORY_NOT_ACTIVE = 20;
+ @FlaggedApi(Flags.FLAG_IDENTITY_CHECK_API)
+ int BIOMETRIC_ERROR_IDENTITY_CHECK_NOT_ACTIVE = 20;
/**
- * Biometrics is not allowed to verify in apps.
- * @hide
+ * Biometrics is not allowed to verify the user in apps.
*/
+ @FlaggedApi(Flags.FLAG_IDENTITY_CHECK_API)
int BIOMETRIC_ERROR_NOT_ENABLED_FOR_APPS = 21;
/**
@@ -204,6 +207,8 @@
BIOMETRIC_ERROR_NEGATIVE_BUTTON,
BIOMETRIC_ERROR_NO_DEVICE_CREDENTIAL,
BIOMETRIC_ERROR_SECURITY_UPDATE_REQUIRED,
+ BIOMETRIC_ERROR_IDENTITY_CHECK_NOT_ACTIVE,
+ BIOMETRIC_ERROR_NOT_ENABLED_FOR_APPS,
BIOMETRIC_PAUSED_REJECTED})
@Retention(RetentionPolicy.SOURCE)
@interface Errors {}
diff --git a/core/java/android/hardware/biometrics/BiometricManager.java b/core/java/android/hardware/biometrics/BiometricManager.java
index a4f7485f..c690c67 100644
--- a/core/java/android/hardware/biometrics/BiometricManager.java
+++ b/core/java/android/hardware/biometrics/BiometricManager.java
@@ -87,16 +87,19 @@
BiometricConstants.BIOMETRIC_ERROR_LOCKOUT;
/**
- * Mandatory biometrics is not effective.
- * @hide
+ * Identity Check is currently not active.
+ *
+ * This device either doesn't have this feature enabled, or it's not considered in a
+ * high-risk environment that requires extra security measures for accessing sensitive data.
*/
- public static final int BIOMETRIC_ERROR_MANDATORY_NOT_ACTIVE =
- BiometricConstants.BIOMETRIC_ERROR_MANDATORY_NOT_ACTIVE;
+ @FlaggedApi(Flags.FLAG_IDENTITY_CHECK_API)
+ public static final int BIOMETRIC_ERROR_IDENTITY_CHECK_NOT_ACTIVE =
+ BiometricConstants.BIOMETRIC_ERROR_IDENTITY_CHECK_NOT_ACTIVE;
/**
- * Biometrics is not allowed to verify in apps.
- * @hide
+ * Biometrics is not allowed to verify the user in apps.
*/
+ @FlaggedApi(Flags.FLAG_IDENTITY_CHECK_API)
public static final int BIOMETRIC_ERROR_NOT_ENABLED_FOR_APPS =
BiometricConstants.BIOMETRIC_ERROR_NOT_ENABLED_FOR_APPS;
@@ -136,7 +139,7 @@
BIOMETRIC_ERROR_NO_HARDWARE,
BIOMETRIC_ERROR_SECURITY_UPDATE_REQUIRED,
BIOMETRIC_ERROR_LOCKOUT,
- BIOMETRIC_ERROR_MANDATORY_NOT_ACTIVE})
+ BIOMETRIC_ERROR_IDENTITY_CHECK_NOT_ACTIVE})
@Retention(RetentionPolicy.SOURCE)
public @interface BiometricError {}
@@ -160,7 +163,7 @@
BIOMETRIC_WEAK,
BIOMETRIC_CONVENIENCE,
DEVICE_CREDENTIAL,
- MANDATORY_BIOMETRICS,
+ IDENTITY_CHECK,
})
@Retention(RetentionPolicy.SOURCE)
@interface Types {}
@@ -239,20 +242,24 @@
int DEVICE_CREDENTIAL = 1 << 15;
/**
- * The bit is used to request for mandatory biometrics.
+ * The bit is used to request for Identity Check.
*
- * <p> The requirements to trigger mandatory biometrics are as follows:
- * 1. User must have enabled the toggle for mandatory biometrics is settings
- * 2. User must have enrollments for all {@link #BIOMETRIC_STRONG} sensors available
- * 3. The device must not be in a trusted location
+ * Identity Check is a feature which requires class 3 biometric authentication to access
+ * sensitive surfaces when the device is outside trusted places.
+ *
+ * <p> The requirements to trigger Identity Check are as follows:
+ * 1. User must have enabled the toggle for Identity Check in settings
+ * 2. User must have enrollments for at least one {@link #BIOMETRIC_STRONG} sensor
+ * 3. The device is determined to be in a high risk environment, for example if it is
+ * outside of the user's trusted locations or fails to meet similar conditions.
+ * 4. The Identity Check requirements bit must be true
* </p>
*
* <p> If all the above conditions are satisfied, only {@link #BIOMETRIC_STRONG} sensors
* will be eligible for authentication, and device credential fallback will be dropped.
- * @hide
*/
- int MANDATORY_BIOMETRICS = 1 << 16;
-
+ @FlaggedApi(Flags.FLAG_IDENTITY_CHECK_API)
+ int IDENTITY_CHECK = 1 << 16;
}
/**
diff --git a/core/java/android/hardware/biometrics/PromptInfo.java b/core/java/android/hardware/biometrics/PromptInfo.java
index df5d864..e23ffeb 100644
--- a/core/java/android/hardware/biometrics/PromptInfo.java
+++ b/core/java/android/hardware/biometrics/PromptInfo.java
@@ -199,7 +199,7 @@
} else if (mContentView != null && isContentViewMoreOptionsButtonUsed()) {
return true;
} else if (Flags.mandatoryBiometrics()
- && (mAuthenticators & BiometricManager.Authenticators.MANDATORY_BIOMETRICS)
+ && (mAuthenticators & BiometricManager.Authenticators.IDENTITY_CHECK)
!= 0) {
return true;
}
diff --git a/core/java/android/hardware/biometrics/flags.aconfig b/core/java/android/hardware/biometrics/flags.aconfig
index 26ffa11..52a4898 100644
--- a/core/java/android/hardware/biometrics/flags.aconfig
+++ b/core/java/android/hardware/biometrics/flags.aconfig
@@ -47,3 +47,10 @@
description: "This flag controls Whether to enable fp unlock when screen turns off on udfps devices"
bug: "373792870"
}
+
+flag {
+ name: "identity_check_api"
+ namespace: "biometrics_framework"
+ description: "This flag is for API changes related to Identity Check"
+ bug: "373424727"
+}
diff --git a/services/core/java/com/android/server/biometrics/PreAuthInfo.java b/services/core/java/com/android/server/biometrics/PreAuthInfo.java
index b2c616a..96c178a 100644
--- a/services/core/java/com/android/server/biometrics/PreAuthInfo.java
+++ b/services/core/java/com/android/server/biometrics/PreAuthInfo.java
@@ -112,7 +112,7 @@
throws RemoteException {
final boolean isOnlyMandatoryBiometricsRequested = promptInfo.getAuthenticators()
- == BiometricManager.Authenticators.MANDATORY_BIOMETRICS;
+ == BiometricManager.Authenticators.IDENTITY_CHECK;
boolean isMandatoryBiometricsAuthentication = false;
if (dropCredentialFallback(promptInfo.getAuthenticators(),
@@ -180,8 +180,8 @@
private static boolean dropCredentialFallback(int authenticators,
boolean isMandatoryBiometricsEnabled, ITrustManager trustManager) {
final boolean isMandatoryBiometricsRequested =
- (authenticators & BiometricManager.Authenticators.MANDATORY_BIOMETRICS)
- == BiometricManager.Authenticators.MANDATORY_BIOMETRICS;
+ (authenticators & BiometricManager.Authenticators.IDENTITY_CHECK)
+ == BiometricManager.Authenticators.IDENTITY_CHECK;
if (Flags.mandatoryBiometrics() && isMandatoryBiometricsEnabled
&& isMandatoryBiometricsRequested) {
try {
diff --git a/services/core/java/com/android/server/biometrics/Utils.java b/services/core/java/com/android/server/biometrics/Utils.java
index 8734136..c1f8e2e 100644
--- a/services/core/java/com/android/server/biometrics/Utils.java
+++ b/services/core/java/com/android/server/biometrics/Utils.java
@@ -147,7 +147,7 @@
* @return true if mandatory biometrics is requested
*/
static boolean isMandatoryBiometricsRequested(@Authenticators.Types int authenticators) {
- return (authenticators & Authenticators.MANDATORY_BIOMETRICS) != 0;
+ return (authenticators & Authenticators.IDENTITY_CHECK) != 0;
}
/**
@@ -257,7 +257,7 @@
if (Flags.mandatoryBiometrics()) {
testBits = ~(Authenticators.DEVICE_CREDENTIAL
| Authenticators.BIOMETRIC_MIN_STRENGTH
- | Authenticators.MANDATORY_BIOMETRICS);
+ | Authenticators.IDENTITY_CHECK);
} else {
testBits = ~(Authenticators.DEVICE_CREDENTIAL
| Authenticators.BIOMETRIC_MIN_STRENGTH);
@@ -329,8 +329,8 @@
case BiometricConstants.BIOMETRIC_ERROR_SENSOR_PRIVACY_ENABLED:
biometricManagerCode = BiometricManager.BIOMETRIC_ERROR_HW_UNAVAILABLE;
break;
- case BiometricConstants.BIOMETRIC_ERROR_MANDATORY_NOT_ACTIVE:
- biometricManagerCode = BiometricManager.BIOMETRIC_ERROR_MANDATORY_NOT_ACTIVE;
+ case BiometricConstants.BIOMETRIC_ERROR_IDENTITY_CHECK_NOT_ACTIVE:
+ biometricManagerCode = BiometricManager.BIOMETRIC_ERROR_IDENTITY_CHECK_NOT_ACTIVE;
break;
case BiometricConstants.BIOMETRIC_ERROR_NOT_ENABLED_FOR_APPS:
biometricManagerCode = BiometricManager.BIOMETRIC_ERROR_NOT_ENABLED_FOR_APPS;
@@ -397,7 +397,7 @@
case BIOMETRIC_SENSOR_PRIVACY_ENABLED:
return BiometricConstants.BIOMETRIC_ERROR_SENSOR_PRIVACY_ENABLED;
case MANDATORY_BIOMETRIC_UNAVAILABLE_ERROR:
- return BiometricConstants.BIOMETRIC_ERROR_MANDATORY_NOT_ACTIVE;
+ return BiometricConstants.BIOMETRIC_ERROR_IDENTITY_CHECK_NOT_ACTIVE;
case BIOMETRIC_NOT_ENABLED_FOR_APPS:
if (Flags.mandatoryBiometrics()) {
return BiometricConstants.BIOMETRIC_ERROR_NOT_ENABLED_FOR_APPS;
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 b4b3612..bc410d9 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/BiometricServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/BiometricServiceTest.java
@@ -1580,12 +1580,12 @@
setupAuthForOnly(TYPE_FINGERPRINT, Authenticators.BIOMETRIC_STRONG);
assertEquals(BiometricManager.BIOMETRIC_SUCCESS,
- invokeCanAuthenticate(mBiometricService, Authenticators.MANDATORY_BIOMETRICS));
+ invokeCanAuthenticate(mBiometricService, Authenticators.IDENTITY_CHECK));
when(mTrustManager.isInSignificantPlace()).thenReturn(true);
- assertEquals(BiometricManager.BIOMETRIC_ERROR_MANDATORY_NOT_ACTIVE,
- invokeCanAuthenticate(mBiometricService, Authenticators.MANDATORY_BIOMETRICS));
+ assertEquals(BiometricManager.BIOMETRIC_ERROR_IDENTITY_CHECK_NOT_ACTIVE,
+ invokeCanAuthenticate(mBiometricService, Authenticators.IDENTITY_CHECK));
}
@Test
@@ -1603,13 +1603,13 @@
setupAuthForOnly(TYPE_FINGERPRINT, Authenticators.BIOMETRIC_STRONG);
assertEquals(BiometricManager.BIOMETRIC_SUCCESS,
- invokeCanAuthenticate(mBiometricService, Authenticators.MANDATORY_BIOMETRICS
+ invokeCanAuthenticate(mBiometricService, Authenticators.IDENTITY_CHECK
| Authenticators.BIOMETRIC_STRONG));
when(mTrustManager.isInSignificantPlace()).thenReturn(true);
assertEquals(BiometricManager.BIOMETRIC_SUCCESS,
- invokeCanAuthenticate(mBiometricService, Authenticators.MANDATORY_BIOMETRICS
+ invokeCanAuthenticate(mBiometricService, Authenticators.IDENTITY_CHECK
| Authenticators.BIOMETRIC_STRONG));
}
@@ -1628,12 +1628,12 @@
setupAuthForOnly(TYPE_CREDENTIAL, Authenticators.DEVICE_CREDENTIAL);
assertEquals(BiometricManager.BIOMETRIC_ERROR_NO_HARDWARE,
- invokeCanAuthenticate(mBiometricService, Authenticators.MANDATORY_BIOMETRICS));
+ invokeCanAuthenticate(mBiometricService, Authenticators.IDENTITY_CHECK));
when(mTrustManager.isInSignificantPlace()).thenReturn(true);
assertEquals(BiometricManager.BIOMETRIC_SUCCESS,
- invokeCanAuthenticate(mBiometricService, Authenticators.MANDATORY_BIOMETRICS
+ invokeCanAuthenticate(mBiometricService, Authenticators.IDENTITY_CHECK
| Authenticators.DEVICE_CREDENTIAL));
}
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 b758f57..85e45f4 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/PreAuthInfoTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/PreAuthInfoTest.java
@@ -207,7 +207,7 @@
final BiometricSensor sensor = getFaceSensor();
final PromptInfo promptInfo = new PromptInfo();
- promptInfo.setAuthenticators(BiometricManager.Authenticators.MANDATORY_BIOMETRICS);
+ promptInfo.setAuthenticators(BiometricManager.Authenticators.IDENTITY_CHECK);
final PreAuthInfo preAuthInfo = PreAuthInfo.create(mTrustManager, mDevicePolicyManager,
mSettingObserver, List.of(sensor), 0 /* userId */, promptInfo, TEST_PACKAGE_NAME,
false /* checkDevicePolicyManager */, mContext, mBiometricCameraManager);
@@ -222,7 +222,7 @@
when(mTrustManager.isInSignificantPlace()).thenReturn(false);
final PromptInfo promptInfo = new PromptInfo();
- promptInfo.setAuthenticators(BiometricManager.Authenticators.MANDATORY_BIOMETRICS);
+ promptInfo.setAuthenticators(BiometricManager.Authenticators.IDENTITY_CHECK);
final PreAuthInfo preAuthInfo = PreAuthInfo.create(mTrustManager, mDevicePolicyManager,
mSettingObserver, List.of(), 0 /* userId */, promptInfo, TEST_PACKAGE_NAME,
false /* checkDevicePolicyManager */, mContext, mBiometricCameraManager);
@@ -238,7 +238,7 @@
final BiometricSensor sensor = getFaceSensor();
final PromptInfo promptInfo = new PromptInfo();
- promptInfo.setAuthenticators(BiometricManager.Authenticators.MANDATORY_BIOMETRICS
+ promptInfo.setAuthenticators(BiometricManager.Authenticators.IDENTITY_CHECK
| BiometricManager.Authenticators.BIOMETRIC_STRONG);
final PreAuthInfo preAuthInfo = PreAuthInfo.create(mTrustManager, mDevicePolicyManager,
mSettingObserver, List.of(sensor), 0 /* userId */, promptInfo, TEST_PACKAGE_NAME,
@@ -255,13 +255,13 @@
final BiometricSensor sensor = getFaceSensor();
final PromptInfo promptInfo = new PromptInfo();
- promptInfo.setAuthenticators(BiometricManager.Authenticators.MANDATORY_BIOMETRICS);
+ promptInfo.setAuthenticators(BiometricManager.Authenticators.IDENTITY_CHECK);
final PreAuthInfo preAuthInfo = PreAuthInfo.create(mTrustManager, mDevicePolicyManager,
mSettingObserver, List.of(sensor), 0 /* userId */, promptInfo, TEST_PACKAGE_NAME,
false /* checkDevicePolicyManager */, mContext, mBiometricCameraManager);
assertThat(preAuthInfo.getCanAuthenticateResult()).isEqualTo(
- BiometricManager.BIOMETRIC_ERROR_MANDATORY_NOT_ACTIVE);
+ BiometricManager.BIOMETRIC_ERROR_IDENTITY_CHECK_NOT_ACTIVE);
assertThat(preAuthInfo.eligibleSensors).hasSize(0);
}
@@ -296,7 +296,7 @@
final BiometricSensor sensor = getFaceSensor();
final PromptInfo promptInfo = new PromptInfo();
- promptInfo.setAuthenticators(BiometricManager.Authenticators.MANDATORY_BIOMETRICS);
+ promptInfo.setAuthenticators(BiometricManager.Authenticators.IDENTITY_CHECK);
promptInfo.setNegativeButtonText(TEST_PACKAGE_NAME);
final PreAuthInfo preAuthInfo = PreAuthInfo.create(mTrustManager, mDevicePolicyManager,
mSettingObserver, List.of(sensor), 0 /* userId */, promptInfo, TEST_PACKAGE_NAME,
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/UtilsTest.java b/services/tests/servicestests/src/com/android/server/biometrics/UtilsTest.java
index 1bea371..c4167d2 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/UtilsTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/UtilsTest.java
@@ -212,24 +212,24 @@
mContext, Authenticators.BIOMETRIC_MIN_STRENGTH));
assertThrows(SecurityException.class, () -> Utils.isValidAuthenticatorConfig(
- mContext, Authenticators.MANDATORY_BIOMETRICS));
+ mContext, Authenticators.IDENTITY_CHECK));
doNothing().when(mContext).enforceCallingOrSelfPermission(
eq(SET_BIOMETRIC_DIALOG_ADVANCED), any());
if (Flags.mandatoryBiometrics()) {
assertTrue(Utils.isValidAuthenticatorConfig(mContext,
- Authenticators.MANDATORY_BIOMETRICS));
+ Authenticators.IDENTITY_CHECK));
} else {
assertFalse(Utils.isValidAuthenticatorConfig(mContext,
- Authenticators.MANDATORY_BIOMETRICS));
+ Authenticators.IDENTITY_CHECK));
}
// The rest of the bits are not allowed to integrate with the public APIs
for (int i = 8; i < 32; i++) {
final int authenticator = 1 << i;
if (authenticator == Authenticators.DEVICE_CREDENTIAL
- || authenticator == Authenticators.MANDATORY_BIOMETRICS) {
+ || authenticator == Authenticators.IDENTITY_CHECK) {
continue;
}
assertFalse(Utils.isValidAuthenticatorConfig(mContext, 1 << i));
@@ -307,8 +307,8 @@
BiometricManager.BIOMETRIC_ERROR_LOCKOUT},
{BiometricConstants.BIOMETRIC_ERROR_LOCKOUT_PERMANENT,
BiometricManager.BIOMETRIC_ERROR_LOCKOUT},
- {BiometricConstants.BIOMETRIC_ERROR_MANDATORY_NOT_ACTIVE,
- BiometricManager.BIOMETRIC_ERROR_MANDATORY_NOT_ACTIVE}
+ {BiometricConstants.BIOMETRIC_ERROR_IDENTITY_CHECK_NOT_ACTIVE,
+ BiometricManager.BIOMETRIC_ERROR_IDENTITY_CHECK_NOT_ACTIVE}
};
for (int i = 0; i < testCases.length; i++) {