Add BiometricPrompt.Builder#setAllowedSensorIds TestApi

Bug: 163058911
Test: atest CtsBiometricsTestCases
Change-Id: I7007e6f9803051b43d4d4909e210f3b6013b5538
This commit is contained in:
Kevin Chyn
2021-03-17 22:21:25 -07:00
parent 42968075d6
commit f8e775a357
7 changed files with 80 additions and 33 deletions

View File

@@ -1026,6 +1026,14 @@ package android.hardware.biometrics {
method @NonNull @RequiresPermission(android.Manifest.permission.TEST_BIOMETRIC) public String getUiPackage();
}
public class BiometricPrompt {
method @NonNull public java.util.List<java.lang.Integer> getAllowedSensorIds();
}
public static class BiometricPrompt.Builder {
method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.TEST_BIOMETRIC, "android.permission.USE_BIOMETRIC_INTERNAL"}) public android.hardware.biometrics.BiometricPrompt.Builder setAllowedSensorIds(@NonNull java.util.List<java.lang.Integer>);
}
public class BiometricTestSession implements java.lang.AutoCloseable {
method @RequiresPermission(android.Manifest.permission.TEST_BIOMETRIC) public void acceptAuthentication(int);
method @RequiresPermission(android.Manifest.permission.TEST_BIOMETRIC) public void cleanupInternalState(int);

View File

@@ -47,13 +47,6 @@ public class BiometricManager {
private static final String TAG = "BiometricManager";
/**
* An ID that should match any biometric sensor on the device.
*
* @hide
*/
public static final int SENSOR_ID_ANY = -1;
/**
* No error detected.
*/

View File

@@ -16,6 +16,7 @@
package android.hardware.biometrics;
import static android.Manifest.permission.TEST_BIOMETRIC;
import static android.Manifest.permission.USE_BIOMETRIC;
import static android.Manifest.permission.USE_BIOMETRIC_INTERNAL;
import static android.hardware.biometrics.BiometricManager.Authenticators;
@@ -25,6 +26,7 @@ import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.TestApi;
import android.content.Context;
import android.content.DialogInterface;
import android.hardware.face.FaceManager;
@@ -45,6 +47,7 @@ import com.android.internal.R;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.security.Signature;
import java.util.List;
import java.util.concurrent.Executor;
import javax.crypto.Cipher;
@@ -338,6 +341,32 @@ public class BiometricPrompt implements BiometricAuthenticator, BiometricConstan
return this;
}
/**
* If non-empty, requests authentication to be performed only if the sensor is contained
* within the list. Note that the actual sensor presented to the user/test will meet all
* constraints specified within this builder. For example, on a device with the below
* configuration:
*
* SensorId: 1, Strength: BIOMETRIC_STRONG
* SensorId: 2, Strength: BIOMETRIC_WEAK
*
* If authentication is invoked with setAllowedAuthenticators(BIOMETRIC_STRONG) and
* setAllowedSensorIds(2), then no sensor will be eligible for authentication.
*
* @see {@link BiometricManager#getSensorProperties()}
*
* @param sensorIds Sensor IDs to constrain this authentication to.
* @return This builder
* @hide
*/
@TestApi
@NonNull
@RequiresPermission(anyOf = {TEST_BIOMETRIC, USE_BIOMETRIC_INTERNAL})
public Builder setAllowedSensorIds(@NonNull List<Integer> sensorIds) {
mPromptInfo.setAllowedSensorIds(sensorIds);
return this;
}
/**
* If set check the Device Policy Manager for disabled biometrics.
*
@@ -363,21 +392,6 @@ public class BiometricPrompt implements BiometricAuthenticator, BiometricConstan
return this;
}
/**
* If set, authenticate using the biometric sensor with the given ID.
*
* @param sensorId The ID of a biometric sensor, or -1 to allow any sensor (default).
* @return This builder.
*
* @hide
*/
@RequiresPermission(USE_BIOMETRIC_INTERNAL)
@NonNull
public Builder setSensorId(int sensorId) {
mPromptInfo.setSensorId(sensorId);
return this;
}
/**
* Creates a {@link BiometricPrompt}.
*
@@ -595,6 +609,16 @@ public class BiometricPrompt implements BiometricAuthenticator, BiometricConstan
return mPromptInfo.getAuthenticators();
}
/**
* @return The values set by {@link Builder#setAllowedSensorIds(List)}
* @hide
*/
@TestApi
@NonNull
public List<Integer> getAllowedSensorIds() {
return mPromptInfo.getAllowedSensorIds();
}
/**
* A wrapper class for the cryptographic operations supported by BiometricPrompt.
*

View File

@@ -21,6 +21,9 @@ import android.annotation.Nullable;
import android.os.Parcel;
import android.os.Parcelable;
import java.util.ArrayList;
import java.util.List;
/**
* Contains the information set/requested by the caller of the {@link BiometricPrompt}
* @hide
@@ -40,7 +43,7 @@ public class PromptInfo implements Parcelable {
private @BiometricManager.Authenticators.Types int mAuthenticators;
private boolean mDisallowBiometricsIfPolicyExists;
private boolean mReceiveSystemEvents;
private int mSensorId = -1;
@NonNull private List<Integer> mAllowedSensorIds = new ArrayList<>();
public PromptInfo() {
@@ -60,7 +63,7 @@ public class PromptInfo implements Parcelable {
mAuthenticators = in.readInt();
mDisallowBiometricsIfPolicyExists = in.readBoolean();
mReceiveSystemEvents = in.readBoolean();
mSensorId = in.readInt();
mAllowedSensorIds = in.readArrayList(Integer.class.getClassLoader());
}
public static final Creator<PromptInfo> CREATOR = new Creator<PromptInfo>() {
@@ -95,7 +98,14 @@ public class PromptInfo implements Parcelable {
dest.writeInt(mAuthenticators);
dest.writeBoolean(mDisallowBiometricsIfPolicyExists);
dest.writeBoolean(mReceiveSystemEvents);
dest.writeInt(mSensorId);
dest.writeList(mAllowedSensorIds);
}
public boolean containsTestConfigurations() {
if (!mAllowedSensorIds.isEmpty()) {
return true;
}
return false;
}
public boolean containsPrivateApiConfigurations() {
@@ -169,8 +179,8 @@ public class PromptInfo implements Parcelable {
mReceiveSystemEvents = receiveSystemEvents;
}
public void setSensorId(int sensorId) {
mSensorId = sensorId;
public void setAllowedSensorIds(@NonNull List<Integer> sensorIds) {
mAllowedSensorIds = sensorIds;
}
// Getters
@@ -234,7 +244,8 @@ public class PromptInfo implements Parcelable {
return mReceiveSystemEvents;
}
public int getSensorId() {
return mSensorId;
@NonNull
public List<Integer> getAllowedSensorIds() {
return mAllowedSensorIds;
}
}

View File

@@ -214,6 +214,13 @@ public class AuthService extends SystemService {
return;
}
if (promptInfo.containsTestConfigurations()) {
if (getContext().checkCallingOrSelfPermission(TEST_BIOMETRIC)
!= PackageManager.PERMISSION_GRANTED) {
checkInternalPermission();
}
}
// Only allow internal clients to enable non-public options.
if (promptInfo.containsPrivateApiConfigurations()) {
checkInternalPermission();

View File

@@ -23,6 +23,7 @@ import static android.hardware.biometrics.BiometricAuthenticator.TYPE_IRIS;
import static android.hardware.biometrics.BiometricAuthenticator.TYPE_NONE;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.app.admin.DevicePolicyManager;
import android.app.trust.ITrustManager;
import android.hardware.biometrics.BiometricAuthenticator;
@@ -112,7 +113,8 @@ class PreAuthInfo {
@AuthenticatorStatus int status = getStatusForBiometricAuthenticator(
devicePolicyManager, settingObserver, sensor, userId, opPackageName,
checkDevicePolicyManager, requestedStrength, promptInfo.getSensorId());
checkDevicePolicyManager, requestedStrength,
promptInfo.getAllowedSensorIds());
Slog.d(TAG, "Package: " + opPackageName
+ " Sensor ID: " + sensor.id
@@ -142,9 +144,10 @@ class PreAuthInfo {
DevicePolicyManager devicePolicyManager,
BiometricService.SettingObserver settingObserver,
BiometricSensor sensor, int userId, String opPackageName,
boolean checkDevicePolicyManager, int requestedStrength, int requestedSensorId) {
boolean checkDevicePolicyManager, int requestedStrength,
@NonNull List<Integer> requestedSensorIds) {
if (requestedSensorId != BiometricManager.SENSOR_ID_ANY && sensor.id != requestedSensorId) {
if (!requestedSensorIds.isEmpty() && !requestedSensorIds.contains(sensor.id)) {
return BIOMETRIC_NO_HARDWARE;
}

View File

@@ -315,7 +315,8 @@ public class FingerprintService extends SystemService implements BiometricServic
Slog.e(TAG, "Remote exception in negative button onClick()", e);
}
})
.setSensorId(props.sensorId)
.setAllowedSensorIds(new ArrayList<>(
Collections.singletonList(props.sensorId)))
.build();
final BiometricPrompt.AuthenticationCallback promptCallback =