Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6a97e964 authored by Kevin Chyn's avatar Kevin Chyn
Browse files

Update Biometric TestApis

Fixes: 169459906
Test: make -j update-api && make -j
Change-Id: I128b55cac9ba76652c7c6228790278ac89d9122c
parent fc26e8a0
Loading
Loading
Loading
Loading
+11 −11
Original line number Diff line number Diff line
@@ -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();
  }

}
+14 −1
Original line number Diff line number Diff line
@@ -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)
    }

+40 −61
Original line number Diff line number Diff line
@@ -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);
    }
}
+9 −12
Original line number Diff line number Diff line
@@ -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);
}
+21 −17
Original line number Diff line number Diff line
@@ -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
Loading