Update Biometric TestApis

Fixes: 169459906
Test: make -j update-api && make -j
Change-Id: I128b55cac9ba76652c7c6228790278ac89d9122c
This commit is contained in:
Kevin Chyn
2020-10-09 15:33:47 -07:00
parent fc26e8a0e0
commit 6a97e964cb
7 changed files with 122 additions and 127 deletions

View File

@@ -1227,20 +1227,19 @@ package android.graphics.drawable {
package android.hardware.biometrics {
public class BiometricManager {
method @NonNull @RequiresPermission(android.Manifest.permission.TEST_BIOMETRIC) public android.hardware.biometrics.BiometricTestSession getTestSession();
method @NonNull @RequiresPermission(android.Manifest.permission.TEST_BIOMETRIC) public android.hardware.biometrics.BiometricTestSession createTestSession(int);
method @NonNull @RequiresPermission(android.Manifest.permission.TEST_BIOMETRIC) public java.util.List<android.hardware.biometrics.SensorProperties> getSensorProperties();
}
public class BiometricTestSession implements java.lang.AutoCloseable {
method @RequiresPermission(android.Manifest.permission.TEST_BIOMETRIC) public void authenticateReject(int, int);
method @RequiresPermission(android.Manifest.permission.TEST_BIOMETRIC) public void authenticateSuccess(int, int);
method @RequiresPermission(android.Manifest.permission.TEST_BIOMETRIC) public void acceptAuthentication(int);
method @RequiresPermission(android.Manifest.permission.TEST_BIOMETRIC) public void cleanupInternalState(int);
method @RequiresPermission(android.Manifest.permission.TEST_BIOMETRIC) public void close();
method @RequiresPermission(android.Manifest.permission.TEST_BIOMETRIC) public void enableTestHal(int, boolean);
method @RequiresPermission(android.Manifest.permission.TEST_BIOMETRIC) public void enrollFinish(int, int);
method @RequiresPermission(android.Manifest.permission.TEST_BIOMETRIC) public void enrollStart(int, int);
method @NonNull @RequiresPermission(android.Manifest.permission.TEST_BIOMETRIC) public java.util.List<android.hardware.biometrics.SensorProperties> getSensorProperties();
method @RequiresPermission(android.Manifest.permission.TEST_BIOMETRIC) public void internalCleanup(int, int);
method @RequiresPermission(android.Manifest.permission.TEST_BIOMETRIC) public void notifyAcquired(int, int);
method @RequiresPermission(android.Manifest.permission.TEST_BIOMETRIC) public void notifyError(int, int);
method @RequiresPermission(android.Manifest.permission.TEST_BIOMETRIC) public void finishEnroll(int);
method @RequiresPermission(android.Manifest.permission.TEST_BIOMETRIC) public void notifyAcquired(int);
method @RequiresPermission(android.Manifest.permission.TEST_BIOMETRIC) public void notifyError(int);
method @RequiresPermission(android.Manifest.permission.TEST_BIOMETRIC) public void rejectAuthentication(int);
method @RequiresPermission(android.Manifest.permission.TEST_BIOMETRIC) public void startEnroll(int);
}
public class SensorProperties {
@@ -1361,7 +1360,8 @@ package android.hardware.display {
package android.hardware.fingerprint {
@Deprecated public class FingerprintManager {
method @Deprecated @NonNull @RequiresPermission(android.Manifest.permission.TEST_BIOMETRIC) public android.hardware.biometrics.BiometricTestSession getTestSession();
method @Deprecated @NonNull @RequiresPermission(android.Manifest.permission.TEST_BIOMETRIC) public android.hardware.biometrics.BiometricTestSession createTestSession(int);
method @Deprecated @NonNull @RequiresPermission(android.Manifest.permission.TEST_BIOMETRIC) public java.util.List<android.hardware.biometrics.SensorProperties> getSensorProperties();
}
}

View File

@@ -35,6 +35,8 @@ import android.util.Slog;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.List;
/**
* A class that contains biometric utilities. For authentication, see {@link BiometricPrompt}.
@@ -198,6 +200,17 @@ public class BiometricManager {
mService = service;
}
/**
* @return A list of {@link SensorProperties}
* @hide
*/
@TestApi
@NonNull
@RequiresPermission(TEST_BIOMETRIC)
public List<SensorProperties> getSensorProperties() {
return new ArrayList<>(); // TODO(169459906)
}
/**
* Retrieves a test session for BiometricManager/BiometricPrompt.
* @hide
@@ -205,7 +218,7 @@ public class BiometricManager {
@TestApi
@NonNull
@RequiresPermission(TEST_BIOMETRIC)
public BiometricTestSession getTestSession() {
public BiometricTestSession createTestSession(int sensorId) {
return null; // TODO(169459906)
}

View File

@@ -23,10 +23,7 @@ import android.annotation.RequiresPermission;
import android.annotation.TestApi;
import android.content.Context;
import android.os.RemoteException;
import android.util.Log;
import java.util.ArrayList;
import java.util.List;
import android.util.ArraySet;
/**
* Common set of interfaces to test biometric-related APIs, including {@link BiometricPrompt} and
@@ -35,37 +32,20 @@ import java.util.List;
*/
@TestApi
public class BiometricTestSession implements AutoCloseable {
private static final String TAG = "TestManager";
private final Context mContext;
private final ITestService mTestService;
private final ITestSession mTestSession;
// Keep track of users that were tested, which need to be cleaned up when finishing.
private final ArraySet<Integer> mTestedUsers;
/**
* @hide
*/
public BiometricTestSession(@NonNull Context context, @NonNull ITestService testService) {
public BiometricTestSession(@NonNull Context context, @NonNull ITestSession testSession) {
mContext = context;
mTestService = testService;
}
/**
* @return A list of {@link SensorProperties}
*/
@NonNull
@RequiresPermission(TEST_BIOMETRIC)
public List<SensorProperties> getSensorProperties() {
try {
final List<SensorPropertiesInternal> internalProps =
mTestService.getSensorPropertiesInternal(mContext.getOpPackageName());
final List<SensorProperties> props = new ArrayList<>();
for (SensorPropertiesInternal internalProp : internalProps) {
props.add(new SensorProperties(internalProp.sensorId, internalProp.sensorStrength));
}
return props;
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
mTestSession = testSession;
mTestedUsers = new ArraySet<>();
enableTestHal(true);
}
/**
@@ -75,105 +55,101 @@ public class BiometricTestSession implements AutoCloseable {
* secure pathways such as HAT/Keystore are not testable, since they depend on the TEE or its
* equivalent for the secret key.
*
* @param sensorId Sensor that this command applies to.
* @param enableTestHal If true, enable testing with a fake HAL instead of the real HAL.
* @hide
*/
@RequiresPermission(TEST_BIOMETRIC)
public void enableTestHal(int sensorId, boolean enableTestHal) {
private void enableTestHal(boolean enableTestHal) {
try {
mTestService.enableTestHal(sensorId, enableTestHal);
mTestSession.enableTestHal(enableTestHal);
} catch (RemoteException e) {
Log.e(TAG, "Remote exception", e);
throw e.rethrowFromSystemServer();
}
}
/**
* Starts the enrollment process. This should generally be used when the test HAL is enabled.
*
* @param sensorId Sensor that this command applies to.
* @param userId User that this command applies to.
*/
@RequiresPermission(TEST_BIOMETRIC)
public void enrollStart(int sensorId, int userId) {
public void startEnroll(int userId) {
try {
mTestService.enrollStart(sensorId, userId);
mTestedUsers.add(userId);
mTestSession.startEnroll(userId);
} catch (RemoteException e) {
Log.e(TAG, "Remote exception", e);
throw e.rethrowFromSystemServer();
}
}
/**
* Finishes the enrollment process. Simulates the HAL's callback.
*
* @param sensorId Sensor that this command applies to.
* @param userId User that this command applies to.
*/
@RequiresPermission(TEST_BIOMETRIC)
public void enrollFinish(int sensorId, int userId) {
public void finishEnroll(int userId) {
try {
mTestService.enrollFinish(sensorId, userId);
mTestedUsers.add(userId);
mTestSession.finishEnroll(userId);
} catch (RemoteException e) {
Log.e(TAG, "Remote exception", e);
throw e.rethrowFromSystemServer();
}
}
/**
* Simulates a successful authentication, but does not provide a valid HAT.
*
* @param sensorId Sensor that this command applies to.
* @param userId User that this command applies to.
*/
@RequiresPermission(TEST_BIOMETRIC)
public void authenticateSuccess(int sensorId, int userId) {
public void acceptAuthentication(int userId) {
try {
mTestService.authenticateSuccess(sensorId, userId);
mTestSession.acceptAuthentication(userId);
} catch (RemoteException e) {
Log.e(TAG, "Remote exception", e);
throw e.rethrowFromSystemServer();
}
}
/**
* Simulates a rejected attempt.
*
* @param sensorId Sensor that this command applies to.
* @param userId User that this command applies to.
*/
@RequiresPermission(TEST_BIOMETRIC)
public void authenticateReject(int sensorId, int userId) {
public void rejectAuthentication(int userId) {
try {
mTestService.authenticateReject(sensorId, userId);
mTestSession.rejectAuthentication(userId);
} catch (RemoteException e) {
Log.e(TAG, "Remote exception", e);
throw e.rethrowFromSystemServer();
}
}
/**
* Simulates an acquired message from the HAL.
*
* @param sensorId Sensor that this command applies to.
* @param userId User that this command applies to.
*/
@RequiresPermission(TEST_BIOMETRIC)
public void notifyAcquired(int sensorId, int userId) {
public void notifyAcquired(int userId) {
try {
mTestService.notifyAcquired(sensorId, userId);
mTestSession.notifyAcquired(userId);
} catch (RemoteException e) {
Log.e(TAG, "Remote exception", e);
throw e.rethrowFromSystemServer();
}
}
/**
* Simulates an error message from the HAL.
*
* @param sensorId Sensor that this command applies to.
* @param userId User that this command applies to.
*/
@RequiresPermission(TEST_BIOMETRIC)
public void notifyError(int sensorId, int userId) {
public void notifyError(int userId) {
try {
mTestService.notifyError(sensorId, userId);
mTestSession.notifyError(userId);
} catch (RemoteException e) {
Log.e(TAG, "Remote exception", e);
throw e.rethrowFromSystemServer();
}
}
@@ -182,21 +158,24 @@ public class BiometricTestSession implements AutoCloseable {
* that isn't known by both sides are deleted. This should generally be used when the test
* HAL is disabled (e.g. to clean up after a test).
*
* @param sensorId Sensor that this command applies to.
* @param userId User that this command applies to.
*/
@RequiresPermission(TEST_BIOMETRIC)
public void internalCleanup(int sensorId, int userId) {
public void cleanupInternalState(int userId) {
try {
mTestService.internalCleanup(sensorId, userId);
mTestSession.cleanupInternalState(userId);
} catch (RemoteException e) {
Log.e(TAG, "Remote exception", e);
throw e.rethrowFromSystemServer();
}
}
@Override
@RequiresPermission(TEST_BIOMETRIC)
public void close() {
for (int user : mTestedUsers) {
cleanupInternalState(user);
}
enableTestHal(false);
}
}

View File

@@ -21,37 +21,34 @@ import android.hardware.biometrics.SensorPropertiesInternal;
* A test service for FingerprintManager and BiometricPrompt.
* @hide
*/
interface ITestService {
// Returns a list of sensor properties supported by the interface.
List<SensorPropertiesInternal> getSensorPropertiesInternal(String opPackageName);
interface ITestSession {
// Switches the specified sensor to use a test HAL. In this mode, the framework will not invoke
// any methods on the real HAL implementation. This allows the framework to test a substantial
// portion of the framework code that would otherwise require human interaction. Note that
// secure pathways such as HAT/Keystore are not testable, since they depend on the TEE or its
// equivalent for the secret key.
void enableTestHal(int sensorId, boolean enableTestHal);
void enableTestHal(boolean enableTestHal);
// Starts the enrollment process. This should generally be used when the test HAL is enabled.
void enrollStart(int sensorId, int userId);
void startEnroll(int userId);
// Finishes the enrollment process. Simulates the HAL's callback.
void enrollFinish(int sensorId, int userId);
void finishEnroll(int userId);
// Simulates a successful authentication, but does not provide a valid HAT.
void authenticateSuccess(int sensorId, int userId);
void acceptAuthentication(int userId);
// Simulates a rejected attempt.
void authenticateReject(int sensorId, int userId);
void rejectAuthentication(int userId);
// Simulates an acquired message from the HAL.
void notifyAcquired(int sensorId, int userId);
void notifyAcquired(int userId);
// Simulates an error message from the HAL.
void notifyError(int sensorId, int userId);
void notifyError(int userId);
// Matches the framework's cached enrollments against the HAL's enrollments. Any enrollment
// that isn't known by both sides are deleted. This should generally be used when the test
// HAL is disabled (e.g. to clean up after a test).
void internalCleanup(int sensorId, int userId);
void cleanupInternalState(int userId);
}

View File

@@ -39,6 +39,7 @@ import android.hardware.biometrics.BiometricFingerprintConstants;
import android.hardware.biometrics.BiometricPrompt;
import android.hardware.biometrics.BiometricTestSession;
import android.hardware.biometrics.IBiometricServiceLockoutResetCallback;
import android.hardware.biometrics.SensorProperties;
import android.os.Binder;
import android.os.CancellationSignal;
import android.os.CancellationSignal.OnCancelListener;
@@ -97,6 +98,24 @@ public class FingerprintManager implements BiometricAuthenticator, BiometricFing
private Fingerprint mRemovalFingerprint;
private Handler mHandler;
/**
* Retrieves a list of properties for all fingerprint sensors on the device.
* @hide
*/
@TestApi
@NonNull
@RequiresPermission(TEST_BIOMETRIC)
public List<SensorProperties> getSensorProperties() {
final List<SensorProperties> properties = new ArrayList<>();
final List<FingerprintSensorPropertiesInternal> internalProperties
= getSensorPropertiesInternal();
for (FingerprintSensorPropertiesInternal internalProp : internalProperties) {
properties.add(FingerprintSensorProperties.from(internalProp));
}
return properties;
}
/**
* Retrieves a test session for FingerprintManager.
* @hide
@@ -104,10 +123,10 @@ public class FingerprintManager implements BiometricAuthenticator, BiometricFing
@TestApi
@NonNull
@RequiresPermission(TEST_BIOMETRIC)
public BiometricTestSession getTestSession() {
public BiometricTestSession createTestSession(int sensorId) {
try {
return new BiometricTestSession(mContext,
mService.getTestService(mContext.getOpPackageName()));
mService.createTestSession(sensorId, mContext.getOpPackageName()));
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -866,21 +885,6 @@ public class FingerprintManager implements BiometricAuthenticator, BiometricFing
return false;
}
/**
* Retrieves a list of properties for all fingerprint sensors on the device.
* @hide
*/
@NonNull
public List<FingerprintSensorProperties> getSensorProperties() {
final List<FingerprintSensorProperties> properties = new ArrayList<>();
final List<FingerprintSensorPropertiesInternal> internalProperties
= getSensorPropertiesInternal();
for (FingerprintSensorPropertiesInternal internalProp : internalProperties) {
properties.add(FingerprintSensorProperties.from(internalProp));
}
return properties;
}
/**
* Get statically configured sensor properties.
* @hide

View File

@@ -17,7 +17,7 @@ package android.hardware.fingerprint;
import android.hardware.biometrics.IBiometricSensorReceiver;
import android.hardware.biometrics.IBiometricServiceLockoutResetCallback;
import android.hardware.biometrics.ITestService;
import android.hardware.biometrics.ITestSession;
import android.hardware.fingerprint.IFingerprintClientActiveCallback;
import android.hardware.fingerprint.IFingerprintServiceReceiver;
import android.hardware.fingerprint.IUdfpsOverlayController;
@@ -32,8 +32,8 @@ import java.util.List;
*/
interface IFingerprintService {
// Retrieves a test service
ITestService getTestService(String opPackageName);
// Creates a test session with the specified sensorId
ITestSession createTestSession(int sensorId, String opPackageName);
// Retrieve static sensor properties for all fingerprint sensors
List<FingerprintSensorPropertiesInternal> getSensorPropertiesInternal(String opPackageName);

View File

@@ -33,10 +33,9 @@ import android.content.pm.PackageManager;
import android.hardware.biometrics.BiometricsProtoEnums;
import android.hardware.biometrics.IBiometricSensorReceiver;
import android.hardware.biometrics.IBiometricServiceLockoutResetCallback;
import android.hardware.biometrics.ITestSession;
import android.hardware.biometrics.fingerprint.IFingerprint;
import android.hardware.biometrics.fingerprint.SensorProps;
import android.hardware.biometrics.ITestService;
import android.hardware.biometrics.SensorPropertiesInternal;
import android.hardware.fingerprint.Fingerprint;
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
import android.hardware.fingerprint.IFingerprintClientActiveCallback;
@@ -53,6 +52,8 @@ import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.UserHandle;
import android.provider.Settings;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.EventLog;
import android.util.Pair;
import android.util.Slog;
@@ -91,54 +92,52 @@ public class FingerprintService extends SystemService {
private final GestureAvailabilityDispatcher mGestureAvailabilityDispatcher;
private final LockPatternUtils mLockPatternUtils;
@NonNull private List<ServiceProvider> mServiceProviders;
@Nullable private TestService mTestService;
@NonNull private final ArrayMap<Integer, TestSession> mTestSessions;
private final class TestService extends ITestService.Stub {
private final class TestSession extends ITestSession.Stub {
private final int mSensorId;
@Override
public List<SensorPropertiesInternal> getSensorPropertiesInternal(
String opPackageName) {
Utils.checkPermission(getContext(), TEST_BIOMETRIC);
return null;
TestSession(int sensorId) {
mSensorId = sensorId;
}
@Override
public void enableTestHal(int sensorId, boolean enableTestHal) {
public void enableTestHal(boolean enableTestHal) {
Utils.checkPermission(getContext(), TEST_BIOMETRIC);
}
@Override
public void enrollStart(int sensorId, int userId) {
public void startEnroll(int userId) {
Utils.checkPermission(getContext(), TEST_BIOMETRIC);
}
@Override
public void enrollFinish(int sensorId, int userId) {
public void finishEnroll(int userId) {
Utils.checkPermission(getContext(), TEST_BIOMETRIC);
}
@Override
public void authenticateSuccess(int sensorId, int userId) {
public void acceptAuthentication(int userId) {
Utils.checkPermission(getContext(), TEST_BIOMETRIC);
}
@Override
public void authenticateReject(int sensorId, int userId) {
public void rejectAuthentication(int userId) {
Utils.checkPermission(getContext(), TEST_BIOMETRIC);
}
@Override
public void notifyAcquired(int sensorId, int userId) {
public void notifyAcquired(int userId) {
Utils.checkPermission(getContext(), TEST_BIOMETRIC);
}
@Override
public void notifyError(int sensorId, int userId) {
public void notifyError(int userId) {
Utils.checkPermission(getContext(), TEST_BIOMETRIC);
}
@Override
public void internalCleanup(int sensorId, int userId) {
public void cleanupInternalState(int userId) {
Utils.checkPermission(getContext(), TEST_BIOMETRIC);
}
}
@@ -148,15 +147,17 @@ public class FingerprintService extends SystemService {
*/
private final class FingerprintServiceWrapper extends IFingerprintService.Stub {
@Override
public ITestService getTestService(String opPackageName) {
public ITestSession createTestSession(int sensorId, String opPackageName) {
Utils.checkPermission(getContext(), TEST_BIOMETRIC);
synchronized (this) {
if (mTestService == null) {
mTestService = new TestService();
final TestSession session;
synchronized (mTestSessions) {
if (!mTestSessions.containsKey(sensorId)) {
mTestSessions.put(sensorId, new TestSession(sensorId));
}
session = mTestSessions.get(sensorId);
}
return mTestService;
return session;
}
@Override // Binder call
@@ -619,6 +620,7 @@ public class FingerprintService extends SystemService {
mLockoutResetDispatcher = new LockoutResetDispatcher(context);
mLockPatternUtils = new LockPatternUtils(context);
mServiceProviders = new ArrayList<>();
mTestSessions = new ArrayMap<>();
initializeAidlHals();
}