Update fingerprint #authenticate interfaces & documentation
1) Split into onAuthenticationSucceeded and onAuthenticaitonFailed.
No longer need to use "weird behavior" below:
A) authenticated(id=0) == reject
B) onEnrolled(id=0) --> previously forbidden
C) remove(id=0) --> previously magic number to remove all
enrollments. The new interface has remove(int[] ids).
2) Renames keystoreOperationId to operationId, since keystore
is only one example of a valid use case. operationId and HATs
can be used as attestation for any opaque operation.
Bug: 168842956
Bug: 168843220
Test: make -j56 android.hardware.biometrics.fingerprint-update-api
Test: make -j56 VtsHalBiometricsFingerprintTargetTest
Change-Id: I7ca0365be9cf82539d6cabc6d9fcec916badc323
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISession.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISession.aidl
index 06c8623..c1f66e3 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISession.aidl
+++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISession.aidl
@@ -19,7 +19,7 @@
@VintfStability
interface ISession {
android.hardware.biometrics.common.ICancellationSignal enroll(in int cookie, in android.hardware.keymaster.HardwareAuthToken hat);
- android.hardware.biometrics.common.ICancellationSignal authenticate(in int cookie, in long keystoreOperationId);
+ android.hardware.biometrics.common.ICancellationSignal authenticate(in int cookie, in long operationId);
android.hardware.biometrics.common.ICancellationSignal detectInteraction(in int cookie);
void enumerateEnrollments(in int cookie);
void removeEnrollments(in int cookie, in int[] enrollmentIds);
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISessionCallback.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISessionCallback.aidl
index 6140447..114a2d1 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISessionCallback.aidl
+++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISessionCallback.aidl
@@ -22,7 +22,8 @@
void onAcquired(in android.hardware.biometrics.fingerprint.AcquiredInfo info, in int vendorCode);
void onError(in android.hardware.biometrics.fingerprint.Error error, in int vendorCode);
void onEnrollmentProgress(in int enrollmentId, int remaining, int vendorCode);
- void onAuthenticated(in int enrollmentId, in android.hardware.keymaster.HardwareAuthToken hat);
+ void onAuthenticationSucceeded(in int enrollmentId, in android.hardware.keymaster.HardwareAuthToken hat);
+ void onAuthenticationFailed();
void onInteractionDetected();
void onEnrollmentsEnumerated(in int[] enrollmentIds);
void onEnrollmentsRemoved(in int[] enrollmentIds);
diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl
index e2d23a6..2d2dcaf 100644
--- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl
+++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl
@@ -27,7 +27,61 @@
ICancellationSignal enroll(in int cookie, in HardwareAuthToken hat);
- ICancellationSignal authenticate(in int cookie, in long keystoreOperationId);
+ /**
+ * authenticate:
+ *
+ * A request to start looking for fingerprints to authenticate.
+ *
+ * Once the HAL is able to start processing the authentication request, it must
+ * notify framework via ISessionCallback#onStateChanged with
+ * SessionState::AUTHENTICATING.
+ *
+ * At any point during authentication, if a non-recoverable error occurs,
+ * the HAL must notify the framework via ISessionCallback#onError with
+ * the applicable authentication-specific error, and then send
+ * ISessionCallback#onStateChanged(cookie, SessionState::IDLING).
+ *
+ * During authentication, the implementation may notify the framework
+ * via ISessionCallback#onAcquired with messages that may be used to guide
+ * the user. This callback can be invoked multiple times if necessary.
+ *
+ * The HAL must notify the framework of accepts/rejects via
+ * ISessionCallback#onAuthentication*.
+ *
+ * The authentication lifecycle ends when either
+ * 1) A fingerprint is accepted, and ISessionCallback#onAuthenticationSucceeded
+ * is invoked, or
+ * 2) Any non-recoverable error occurs (such as lockout). See the full
+ * list of authentication-specific errors in the Error enum.
+ *
+ * Note that it is now the HAL's responsibility to keep track of lockout
+ * states. See IFingerprint#setLockoutCallback and ISession#resetLockout.
+ *
+ * Note that upon successful authentication, ONLY sensors configured as
+ * SensorStrength::STRONG are allowed to create and send a
+ * HardwareAuthToken to the framework. See the Android CDD for more
+ * details. For SensorStrength::STRONG sensors, the HardwareAuthToken's
+ * "challenge" field must be set with the operationId passed in during
+ * #authenticate. If the sensor is NOT SensorStrength::STRONG, the
+ * HardwareAuthToken MUST be null.
+ *
+ * @param cookie An identifier used to track subsystem operations related
+ * to this call path. The framework will guarantee that it is
+ * unique per ISession.
+ * @param operationId For sensors configured as SensorStrength::STRONG,
+ * this must be used ONLY upon successful authentication
+ * and wrapped in the HardwareAuthToken's "challenge"
+ * field and sent to the framework via
+ * ISessionCallback#onAuthenticated. The operationId is
+ * an opaque identifier created from a separate secure
+ * subsystem such as, but not limited to KeyStore/KeyMaster.
+ * The HardwareAuthToken can then be used as an attestation
+ * for the provided operation. For example, this is used
+ * to unlock biometric-bound auth-per-use keys (see
+ * setUserAuthenticationParameters in
+ * KeyGenParameterSpec.Builder and KeyProtection.Builder.
+ */
+ ICancellationSignal authenticate(in int cookie, in long operationId);
ICancellationSignal detectInteraction(in int cookie);
diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISessionCallback.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISessionCallback.aidl
index c608d65..d494965 100644
--- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISessionCallback.aidl
+++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISessionCallback.aidl
@@ -31,7 +31,27 @@
void onEnrollmentProgress(in int enrollmentId, int remaining, int vendorCode);
- void onAuthenticated(in int enrollmentId, in HardwareAuthToken hat);
+ /**
+ * Used to notify the framework upon successful authentication. Note that the authentication
+ * lifecycle ends when either 1) a fingerprint is accepted, or 2) an error such as
+ * Error::LOCKOUT occurred. The authentication lifecycle does NOT end when a fingerprint is
+ * rejected.
+ *
+ * @param enrollmentId Fingerprint that was accepted.
+ * @param hat If the sensor is configured as SensorStrength::STRONG, a non-null attestation that
+ * a fingerprint was accepted. The HardwareAuthToken's "challenge" field must be set
+ * with the operationId passed in during ISession#authenticate. If the sensor is NOT
+ * SensorStrength::STRONG, the HardwareAuthToken MUST be null.
+ */
+ void onAuthenticationSucceeded(in int enrollmentId, in HardwareAuthToken hat);
+
+ /**
+ * Used to notify the framework upon rejected attempts. Note that the authentication
+ * lifecycle ends when either 1) a fingerprint is accepted, or 2) an error such as
+ * Error::LOCKOUT occurred. The authentication lifecycle does NOT end when a fingerprint is
+ * rejected.
+ */
+ void onAuthenticationFailed();
void onInteractionDetected();
diff --git a/biometrics/fingerprint/aidl/vts/VtsHalBiometricsFingerprintTargetTest.cpp b/biometrics/fingerprint/aidl/vts/VtsHalBiometricsFingerprintTargetTest.cpp
index 9590d68..4651f25 100644
--- a/biometrics/fingerprint/aidl/vts/VtsHalBiometricsFingerprintTargetTest.cpp
+++ b/biometrics/fingerprint/aidl/vts/VtsHalBiometricsFingerprintTargetTest.cpp
@@ -65,11 +65,15 @@
return ndk::ScopedAStatus::ok();
}
- ndk::ScopedAStatus onAuthenticated(int32_t /*enrollmentId*/,
+ ndk::ScopedAStatus onAuthenticationSucceeded(int32_t /*enrollmentId*/,
const keymaster::HardwareAuthToken& /*hat*/) override {
return ndk::ScopedAStatus::ok();
}
+ ndk::ScopedAStatus onAuthenticationFailed() override {
+ return ndk::ScopedAStatus::ok();
+ }
+
ndk::ScopedAStatus onInteractionDetected() override { return ndk::ScopedAStatus::ok(); }
ndk::ScopedAStatus onEnrollmentsEnumerated(