Merge changes I0b7e7ab3,I92db9b22,I24615333,I7ca0365b
* changes:
Move lockout callbacks to ISessionCallback
Finish remainder of documentation.
Minor API changes and additional documentation for IFingerprint
Update fingerprint #authenticate interfaces & documentation
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl
index 329a35d..df30dca 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl
+++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl
@@ -24,6 +24,6 @@
SENSOR_DIRTY = 3,
TOO_SLOW = 4,
TOO_FAST = 5,
- START = 6,
- VENDOR = 7,
+ VENDOR = 6,
+ START = 7,
}
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/Error.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/Error.aidl
index 0298c12..6bd71b2 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/Error.aidl
+++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/Error.aidl
@@ -18,13 +18,11 @@
package android.hardware.biometrics.fingerprint;
@Backing(type="byte") @VintfStability
enum Error {
- HW_UNAVAILABLE = 0,
- UNABLE_TO_PROCESS = 1,
- TIMEOUT = 2,
- NO_SPACE = 3,
- CANCELED = 4,
- UNABLE_TO_REMOVE = 5,
- LOCKOUT = 6,
- LOCKOUT_PERMANENT = 7,
+ HW_UNAVAILABLE = 1,
+ UNABLE_TO_PROCESS = 2,
+ TIMEOUT = 3,
+ NO_SPACE = 4,
+ CANCELED = 5,
+ UNABLE_TO_REMOVE = 6,
VENDOR = 8,
}
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IFingerprint.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IFingerprint.aidl
index 9cbf343..6ca6d16 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IFingerprint.aidl
+++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IFingerprint.aidl
@@ -20,7 +20,6 @@
interface IFingerprint {
android.hardware.biometrics.fingerprint.SensorProps[] getSensorProps();
android.hardware.biometrics.fingerprint.ISession createSession(in int sensorId, in int userId, in android.hardware.biometrics.fingerprint.ISessionCallback cb);
- void setLockoutCallback(in android.hardware.biometrics.fingerprint.ILockoutCallback cb);
void generateChallenge(in int sensorId, in int userId, in int timeoutSec, in android.hardware.biometrics.fingerprint.IGenerateChallengeCallback cb);
void revokeChallenge(in int sensorId, in int userId, in long challenge, in android.hardware.biometrics.fingerprint.IRevokeChallengeCallback cb);
}
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ILockoutCallback.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ILockoutCallback.aidl
deleted file mode 100644
index 88aabbf..0000000
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ILockoutCallback.aidl
+++ /dev/null
@@ -1,24 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
-// edit this file. It looks like you are doing that because you have modified
-// an AIDL interface in a backward-incompatible way, e.g., deleting a function
-// from an interface or a field from a parcelable and it broke the build. That
-// breakage is intended.
-//
-// You must not make a backward incompatible changes to the AIDL files built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.hardware.biometrics.fingerprint;
-@VintfStability
-interface ILockoutCallback {
- oneway void onLockoutTimed(in int sensorId, in int userId, in long durationMillis);
- oneway void onLockoutPermanent(in int sensorId, in int userId);
- oneway void onLockoutCleared(in int sensorId, in int userId);
-}
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..74ec077 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
@@ -21,8 +21,12 @@
void onStateChanged(in int cookie, in android.hardware.biometrics.fingerprint.SessionState state);
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 onEnrollmentProgress(in int enrollmentId, int remaining);
+ void onAuthenticationSucceeded(in int enrollmentId, in android.hardware.keymaster.HardwareAuthToken hat);
+ void onAuthenticationFailed();
+ void onLockoutTimed(in long durationMillis);
+ void onLockoutPermanent();
+ void onLockoutCleared();
void onInteractionDetected();
void onEnrollmentsEnumerated(in int[] enrollmentIds);
void onEnrollmentsRemoved(in int[] enrollmentIds);
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SessionState.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SessionState.aidl
index 38ca1e0..97f1a1e 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SessionState.aidl
+++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SessionState.aidl
@@ -25,5 +25,6 @@
ENUMERATING_ENROLLMENTS = 4,
REMOVING_ENROLLMENTS = 5,
GETTING_AUTHENTICATOR_ID = 6,
- RESETTING_LOCKOUT = 7,
+ INVALIDATING_AUTHENTICATOR_ID = 7,
+ RESETTING_LOCKOUT = 8,
}
diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl
index 8cb7833..adb1c78 100644
--- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl
+++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl
@@ -19,13 +19,49 @@
@VintfStability
@Backing(type="byte")
enum AcquiredInfo {
+ /**
+ * A high quality fingerprint image was detected, no further user interaction is necessary.
+ */
GOOD,
+
+ /**
+ * Not enough of a fingerprint was detected. Reposition the finger, or a longer swipe needed.
+ */
PARTIAL,
+
+ /**
+ * Image doesn't contain enough detail for recognition.
+ */
INSUFFICIENT,
+
+ /**
+ * The sensor needs to be cleaned.
+ */
SENSOR_DIRTY,
+
+ /**
+ * For swipe-type sensors, the swipe was too slow and not enough data was collected.
+ */
TOO_SLOW,
+
+ /**
+ * For swipe-type sensors, the swipe was too fast and not enough data was collected.
+ */
TOO_FAST,
+
+ /**
+ * Vendor-specific acquisition message. See ISessionCallback#onAcquired vendorCode
+ * documentation.
+ */
+ VENDOR,
+
+ /**
+ * This message represents the earliest message sent at the beginning of the authentication
+ * pipeline. It is expected to be used to measure latency. For example, in a camera-based
+ * authentication system it's expected to be sent prior to camera initialization. Note this
+ * should be sent whenever authentication is started or restarted. The framework may measure
+ * latency based on the time between the last START message and the onAuthenticated callback.
+ */
START,
- VENDOR
}
diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/Error.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/Error.aidl
index cc79de7..014a4c0 100644
--- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/Error.aidl
+++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/Error.aidl
@@ -19,14 +19,58 @@
@VintfStability
@Backing(type="byte")
enum Error {
- HW_UNAVAILABLE,
+ /**
+ * Used for testing, and to keep subsequent numbering consistent with older HIDLs.
+ */
+ // NO_ERROR = 0,
+
+ /**
+ * A hardware error has occurred that cannot be resolved. For example, I2C failure or a broken
+ * sensor.
+ */
+ HW_UNAVAILABLE = 1,
+
+ /**
+ * The implementation is unable to process the request. For example, invalid arguments were
+ * supplied.
+ */
UNABLE_TO_PROCESS,
+
+ /**
+ * The current operation took too long to complete.
+ */
TIMEOUT,
+
+ /**
+ * No space available to store additional enrollments.
+ */
NO_SPACE,
+
+ /**
+ * The operation was canceled. See common::ICancellationSignal.
+ */
CANCELED,
+
+ /**
+ * The implementation was unable to remove an enrollment.
+ * See ISession#removeEnrollments.
+ */
UNABLE_TO_REMOVE,
- LOCKOUT,
- LOCKOUT_PERMANENT,
- VENDOR
+
+ /**
+ * Reserved to maintain backwards compatibility. See ISessionCallback#onLockoutTimed instead.
+ */
+ // LOCKOUT = 7,
+
+ /**
+ * Used to enable vendor-specific error messages.
+ */
+ VENDOR = 8,
+
+ /**
+ * Reserved to maintain backwards compatibility. See ISessionCallback#onLockoutPermanent
+ * instead.
+ */
+ // LOCKOUT_PERMANENT = 9,
}
diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IFingerprint.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IFingerprint.aidl
index 57319b2..0c8ebc5 100644
--- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IFingerprint.aidl
+++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IFingerprint.aidl
@@ -17,7 +17,6 @@
package android.hardware.biometrics.fingerprint;
import android.hardware.biometrics.fingerprint.IGenerateChallengeCallback;
-import android.hardware.biometrics.fingerprint.ILockoutCallback;
import android.hardware.biometrics.fingerprint.IRevokeChallengeCallback;
import android.hardware.biometrics.fingerprint.ISession;
import android.hardware.biometrics.fingerprint.ISessionCallback;
@@ -73,36 +72,6 @@
ISession createSession(in int sensorId, in int userId, in ISessionCallback cb);
/**
- * setLockoutCallback:
- *
- * Sets a callback to notify the framework lockout changes. Note
- * that lockout is user AND sensor specific. In other words, there is a
- * separate lockout state for each (user, sensor) pair. For example, the
- * following is a valid state on a multi-sensor device:
- * ------------------------------------------------------------------
- * | SensorId | UserId | FailedAttempts | LockedOut | LockedUntil |
- * |----------|--------|----------------|-----------|---------------|
- * | 0 | 0 | 1 | false | x |
- * | 1 | 0 | 5 | true | <future_time> |
- * | 0 | 10 | 0 | false | x |
- * | 1 | 10 | 0 | false | x |
- * ------------------------------------------------------------------
- *
- * Lockout may be cleared in the following ways:
- * 1) ISession#resetLockout
- * 2) After a period of time, according to a rate-limiter.
- *
- * In addition, lockout states MUST persist after device reboots, HAL
- * crashes, etc.
- *
- * See the Android CDD section 7.3.10 for the full set of lockout and
- * rate-limiting requirements.
- *
- * @param cb Used to notify the framework of lockout changes.
- */
- void setLockoutCallback(in ILockoutCallback cb);
-
- /**
* generateChallenge:
*
* Begins a secure transaction request. Note that the challenge by itself
diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ILockoutCallback.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ILockoutCallback.aidl
deleted file mode 100644
index 4b31a38..0000000
--- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ILockoutCallback.aidl
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.hardware.biometrics.fingerprint;
-
-@VintfStability
-oneway interface ILockoutCallback {
- /**
- * Notifies the framework that the user has just entered the Error::LOCKOUT state. This must be
- * sent in the following scenarios:
- * 1) The user just attempted authentication and was rejected, resulting in a timed lockout.
- * 2) The framework just created a session for a sensorId/userId pair that has not been
- * created since the HAL started (e.g. there is no active or idle session for this
- * sensorId/userId pair.
- *
- * @param sensorId Sensor for which the user is locked out.
- * @param userId User for which the sensor is locked out.
- * @param durationMillis Remaining duration of the lockout.
- */
- void onLockoutTimed(in int sensorId, in int userId, in long durationMillis);
-
- /**
- * Notifies the framework that the user has just entered the Error::LOCKOUT_PERMANENT state.
- * This must be sent in the following scenarios:
- * 1) The user just attempted authentication and was rejected, resulting in a permanent lockout.
- * 2) The framework just created a session for a sensorId/userId pair that has not been
- * created since the HAL started (e.g. there is no active or idle session for this
- * sensorId/userId pair.
- *
- * @param sensorId Sensor for which the user is locked out.
- * @param userId User for which the sensor is locked out.
- */
- void onLockoutPermanent(in int sensorId, in int userId);
-
- /**
- * Notifies the framework that lockout has been cleared for this sensorId/userId pair. This
- * can happen in the following scenarios:
- * 1) A timed lockout has ended (e.g. original durationMillis specified in #onLockoutTimed
- * has expired.
- * 2) See ISession#resetLockout.
- *
- * @param sensorId Sensor for which the user's lockout is cleared.
- * @param userId User for the sensor's lockout is cleared.
- */
- void onLockoutCleared(in int sensorId, in int userId);
-}
-
diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl
index e2d23a6..d0f546a 100644
--- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl
+++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl
@@ -19,20 +19,194 @@
import android.hardware.biometrics.common.ICancellationSignal;
import android.hardware.keymaster.HardwareAuthToken;
+/**
+ * Operations that can be performed for unique sessions retrieved via IFingerprint#createSession.
+ * Methods defined within this interface can be split into the following categories:
+ * 1) Methods associated with a state (see the SessionState enum). State-based operations are
+ * handled by the HAL in FIFO order.
+ * 1a) Cancellable state-based operations. If a cancellable operation is in-progress and the
+ * framework requests a subsequent state-based operation, the implementation should finish
+ * the operation via ISessionCallback#onError with Error::CANCELED.
+ * 1b) Non-cancellable state-based operations. These operations should fully complete before the
+ * next state-based operation can be started.
+ * 2) Methods without a state. These methods may be invoked by the framework depending on its
+ * use case. For example on devices with sensors of FingerprintSensorType::UNDER_DISPLAY_*,
+ * ISession#onFingerDown may be invoked while the HAL is in SessionState::ENROLLING,
+ * SessionState::AUTHENTICATING, or SessionState::DETECTING_INTERACTION.
+ *
+ * If the HAL has multiple operations in its queue, it is not required to notify the framework
+ * of SessionState::IDLING between each operation. However, it must notify the framework when all
+ * work is completed. See ISessionCallback#onStateChanged. For example, the following is a valid
+ * sequence of ISessionCallback#onStateChanged invocations: SessionState::IDLING -->
+ * SessionState::ENROLLING --> SessionState::ENUMERATING_ENROLLMENTS --> SessionState::IDLING.
+ */
@VintfStability
interface ISession {
/**
* Methods applicable to any fingerprint type.
*/
+ /**
+ * enroll:
+ *
+ * A request to add a fingerprint enrollment.
+ *
+ * Once the HAL is able to start processing the enrollment request, it must
+ * notify the framework via ISessionCallback#onStateChanged with
+ * SessionState::ENROLLING.
+ *
+ * At any point during enrollment, if a non-recoverable error occurs,
+ * the HAL must notify the framework via ISessionCallback#onError with
+ * the applicable enrollment-specific error, and then send
+ * ISessionCallback#onStateChanged(cookie, SessionState::IDLING) if no
+ * subsequent operation is in the queue.
+ *
+ * Before capturing fingerprint data, the implementation must first
+ * verify the authenticity and integrity of the provided HardwareAuthToken.
+ * In addition, it must check that the challenge within the provided
+ * HardwareAuthToken is valid. See IFingerprint#generateChallenge.
+ * If any of the above checks fail, the framework must be notified
+ * via ISessionCallback#onError and the HAL must notify the framework when
+ * it returns to the idle state. See Error::UNABLE_TO_PROCESS.
+ *
+ * During enrollment, 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.
+ * Similarly, the framework may be notified of enrollment progress changes
+ * via ISessionCallback#onEnrollmentProgress. Once the framework is notified
+ * that there are 0 "remaining" steps, the framework may cache the
+ * "enrollmentId". See ISessionCallback#onEnrollmentProgress for more info.
+ * The HAL must notify the framework once it returns to the idle state.
+ *
+ * When a finger is successfully added and before the framework is notified
+ * of remaining=0, the implementation MUST update and associate this
+ * (sensorId, userId) pair with a new new entropy-encoded random identifier.
+ * See ISession#getAuthenticatorId for more information.
+ *
+ * @param cookie An identifier used to track subsystem operations related
+ * to this call path. The client must guarantee that it is
+ * unique per ISession.
+ * @param hat See above documentation.
+ */
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) if no
+ * subsequent operation is in the queue.
+ *
+ * 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 upon successful authentication, the lockout counter for this (sensorId, userId)
+ * pair must be cleared.
+ *
+ * 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
+ * client must 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);
+ /**
+ * detectInteraction:
+ *
+ * A request to start looking for fingerprints without performing matching.
+ *
+ * Once the HAL is able to start processing this request, it must notify the framework via
+ * ISessionCallback#onStateChanged with SessionState::DETECTING_INTERACTION.
+ *
+ * The framework will use this method in cases where determing user presence is required, but
+ * identifying/authentication is not. For example, when the device is encrypted (first boot) or
+ * in lockdown mode.
+ *
+ * At any point during detectInteraction, if a non-recoverable error occurs, the HAL must notify
+ * the framework via ISessionCallback#onError with the applicable error, and then send
+ * ISessionCallback#onStateChanged(cookie, SessionState::IDLING) if no subsequent operation is
+ * in the queue.
+ *
+ * The implementation must only check for a fingerprint-like image was detected (e.g. to
+ * minimize interactions due to non-fingerprint objects), and the lockout counter must not
+ * be modified.
+ *
+ * Upon detecting any fingerprint, the implementation must invoke
+ * ISessionCallback#onInteractionDetected.
+ *
+ * The lifecycle of this operation ends when either
+ * 1) Any fingerprint is detected and the framework is notified via
+ * ISessionCallback#onInteractiondetected
+ * 2) The operation was cancelled by the framework (see ICancellationSignal)
+ * 3) The HAL ends the operation, for example when a subsequent operation pre-empts this one.
+ *
+ * Note that if the operation is canceled, the implementation must notify the framework via
+ * ISessionCallback#onError with Error::CANCELED.
+ *
+ * @param cookie An identifier used to track subsystem operations related to this call path.
+ * The framework will guarantee that it is unique per ISession.
+ */
ICancellationSignal detectInteraction(in int cookie);
+ /*
+ * enumerateEnrollments:
+ *
+ * A request to enumerate (list) the enrollments for this (sensorId, userId) pair. The
+ * framework typically uses this to ensure that its cache is in sync with the HAL.
+ *
+ * Once the HAL is able to start processing this request, it must notify the framework via
+ * ISessionCallback#onStateChanged with SessionState::ENUMERATING_ENROLLMENTS.
+ *
+ * The implementation must then notify the framework with a list of enrollments applicable
+ * for the current session via ISessionCallback#onEnrollmentsEnumerated.
+ *
+ * @param cookie An identifier used to track subsystem operations related to this call path.
+ * The framework will guarantee that it is unique per ISession.
+ */
void enumerateEnrollments(in int cookie);
+ /**
+ * removeEnrollments:
+ *
+ * A request to remove the enrollments for this (sensorId, userId) pair.
+ *
+ * Once the HAL is able to start processing this request, it must notify the framework via
+ * ISessionCallback#onStateChanged with SessionState::REMOVING_ENROLLMENTS.
+ *
+ * After removing the enrollmentIds from everywhere necessary (filesystem, secure subsystems,
+ * etc), the implementation must notify the framework via ISessionCallback#onEnrollmentsRemoved.
+ *
+ * @param cookie An identifier used to track subsystem operations related to this call path.
+ * The framework will guarantee that it is unique per ISession.
+ */
void removeEnrollments(in int cookie, in int[] enrollmentIds);
/**
@@ -45,9 +219,10 @@
* The following only applies to sensors that are configured as
* SensorStrength::STRONG.
*
- * The authenticatorId is used during key generation and key import to to
- * associate a key (in KeyStore / KeyMaster) with the current set of
- * enrolled fingerprints. For example, the following public Android APIs
+ * The authenticatorId is a (sensorId, user)-specific identifier which
+ * can be used during key generation and key import to to associate a
+ * key (in KeyStore / KeyMaster) with the current set of enrolled
+ * fingerprints. For example, the following public Android APIs
* allow for keys to be invalidated when the user adds a new enrollment
* after the key was created:
* KeyGenParameterSpec.Builder.setInvalidatedByBiometricEnrollment and
@@ -66,7 +241,7 @@
* 4) MUST be an entropy-encoded random number
*
* @param cookie An identifier used to track subsystem operations related
- * to this call path. The framework will guarantee that it is
+ * to this call path. The client must guarantee that it is
* unique per ISession.
*/
void getAuthenticatorId(in int cookie);
@@ -84,9 +259,15 @@
*
* When invoked by the framework, the implementation must perform the
* following sequence of events:
- * 1) Verify the authenticity and integrity of the provided HAT
+ * 1) Verify the authenticity and integrity of the provided HAT. If this
+ * check fails, the HAL must invoke ISessionCallback#onError with
+ * Error::UNABLE_TO_PROCESS and return to
+ * SessionState::IDLING if no subsequent work is in the queue.
* 2) Verify that the timestamp provided within the HAT is relatively
- * recent (e.g. on the order of minutes, not hours).
+ * recent (e.g. on the order of minutes, not hours). If this check fails,
+ * the HAL must invoke ISessionCallback#onError with
+ * Error::UNABLE_TO_PROCESS and return to SessionState::IDLING
+ * if no subsequent work is in the queue.
* 3) Update the authenticatorId with a new entropy-encoded random number
* 4) Persist the new authenticatorId to non-ephemeral storage
* 5) Notify the framework that the above is completed, via
@@ -100,7 +281,7 @@
* across multiple biometric HALs as necessary.
*
* @param cookie An identifier used to track subsystem operations related
- * to this call path. The framework will guarantee that it is
+ * to this call path. The client must guarantee that it is
* unique per ISession.
* @param hat HardwareAuthToken that must be validated before proceeding
* with this operation.
@@ -110,34 +291,103 @@
/**
* resetLockout:
*
- * Requests the implementation to clear the lockout counter. Upon receiving
- * this request, the implementation must perform the following:
+ * Requests the implementation to clear the lockout counter. Upon receiving this request, the
+ * implementation must perform the following:
* 1) Verify the authenticity and integrity of the provided HAT
- * 2) Verify that the timestamp provided within the HAT is relatively
- * recent (e.g. on the order of minutes, not hours).
+ * 2) Verify that the timestamp provided within the HAT is relatively recent (e.g. on the
+ * order of minutes, not hours).
+ * If either of the checks fail, the HAL must invoke ISessionCallback#onError with
+ * Error::UNABLE_TO_PROCESS and return to SessionState::IDLING if no subsequent work is in the
+ * queue.
*
- * Upon successful verification, the HAL must notify the framework via
- * ILockoutCallback#onLockoutChanged(sensorId, userId, 0).
+ * Upon successful verification, the HAL must clear the lockout counter and notify the framework
+ * via ISessionCallback#onLockoutCleared.
*
- * If verification was uncessful, the HAL must notify the framework via
- * ILockoutCallback#onLockoutChanged(sensorId, userId, remaining_time).
+ * Note that lockout is user AND sensor specific. In other words, there is a separate lockout
+ * state for each (user, sensor) pair. For example, the following is a valid state on a
+ * multi-sensor device:
+ * ------------------------------------------------------------------
+ * | SensorId | UserId | FailedAttempts | LockedOut | LockedUntil |
+ * |----------|--------|----------------|-----------|---------------|
+ * | 0 | 0 | 1 | false | x |
+ * | 1 | 0 | 5 | true | <future_time> |
+ * | 0 | 10 | 0 | false | x |
+ * | 1 | 10 | 0 | false | x |
+ * ------------------------------------------------------------------
+ *
+ * Lockout may be cleared in the following ways:
+ * 1) ISession#resetLockout
+ * 2) After a period of time, according to a rate-limiter.
+ *
+ * Note that the "FailedAttempts" counter must be cleared upon successful fingerprint
+ * authentication. For example, if SensorId=0 UserId=0 FailedAttempts=1, and a successful
+ * fingerprint authentication occurs, the counter for that (SensorId, UserId) pair must be reset
+ * to 0.
+ *
+ * In addition, lockout states MUST persist after device reboots, HAL crashes, etc.
+ *
+ * See the Android CDD section 7.3.10 for the full set of lockout and rate-limiting
+ * requirements.
*
* @param cookie An identifier used to track subsystem operations related
- * to this call path. The framework will guarantee that it is
+ * to this call path. The client must guarantee that it is
* unique per ISession.
* @param hat HardwareAuthToken See above documentation.
*/
void resetLockout(in int cookie, in HardwareAuthToken hat);
-
/**
* Methods for notifying the under-display fingerprint sensor about external events.
*/
+ /**
+ * onPointerDown:
+ *
+ * This method only applies to sensors that are configured as
+ * FingerprintSensorType::UNDER_DISPLAY_*. If invoked erroneously by the framework for sensors
+ * of other types, the HAL must treat this as a no-op and return immediately.
+ *
+ * For sensors of type FingerprintSensorType::UNDER_DISPLAY_*, this method is used to notify the
+ * HAL of display touches. This method can be invoked when the session is in one of the
+ * following states: SessionState::ENROLLING, SessionState::AUTHENTICATING, or
+ * SessionState::DETECTING_INTERACTION.
+ *
+ * Note that the framework will only invoke this method if the event occurred on the display
+ * on which this sensor is located.
+ *
+ * Note that for sensors which require illumination such as
+ * FingerprintSensorType::UNDER_DISPLAY_OPTICAL, and where illumination is handled below
+ * the framework, this is a good time to start illuminating.
+ *
+ * @param pointerId See android.view.MotionEvent#getPointerId
+ * @param x The distance in pixels from the left edge of the display.
+ * @param y The distance in pixels from the top edge of the display.
+ * @param minor See android.view.MotionEvent#getTouchMinor
+ * @param major See android.view.MotionEvent#getTouchMajor
+ */
void onPointerDown(in int pointerId, in int x, in int y, in float minor, in float major);
+ /**
+ * onPointerUp:
+ *
+ * This method only applies to sensors that are configured as
+ * FingerprintSensorType::UNDER_DISPLAY_*. If invoked for sensors of other types, the HAL must
+ * treat this as a no-op and return immediately.
+ *
+ * @param pointerId See android.view.MotionEvent#getPointerId
+ */
void onPointerUp(in int pointerId);
+ /*
+ * onUiReady:
+ *
+ * This method only applies to sensors that are configured as
+ * FingerprintSensorType::UNDER_DISPLAY_OPTICAL. If invoked for sensors of other types, the HAL
+ * must treat this as a no-op and return immediately.
+ *
+ * For FingerprintSensorType::UNDER_DISPLAY_OPTICAL where illumination is handled above the
+ * HAL, the framework will invoke this method to notify that the illumination has started.
+ */
void onUiReady();
}
diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISessionCallback.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISessionCallback.aidl
index c608d65..33a93e5 100644
--- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISessionCallback.aidl
+++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISessionCallback.aidl
@@ -23,29 +23,162 @@
@VintfStability
interface ISessionCallback {
+ /**
+ * Used to notify the framework of session state changes. See ISession for more information.
+ */
void onStateChanged(in int cookie, in SessionState state);
+ /**
+ * This method must only be used to notify the framework during the following states:
+ * 1) SessionState::ENROLLING
+ * 2) SessionState::AUTHENTICATING
+ * 3) SessionState::DETECTING_INTERACTION
+ *
+ * These messages may be used to provide user guidance multiple times if necessary per
+ * operation.
+ *
+ * @param info See the AcquiredInfo enum.
+ * @param vendorCode Only valid if info == AcquiredInfo::VENDOR.
+ */
void onAcquired(in AcquiredInfo info, in int vendorCode);
+ /**
+ * This method must only be used to notify the framework during the following states:
+ * 1) SessionState::ENROLLING
+ * 2) SessionState::AUTHENTICATING
+ * 3) SessionState::DETECTING_INTERACTION
+ * 4) SessionState::INVALIDATING_AUTHENTICATOR_ID
+ * 5) SessionState::RESETTING_LOCKOUT
+ *
+ * These messages may be used to notify the framework or user that a non-recoverable error
+ * has occurred. The operation is finished, and the HAL must proceed with the next operation
+ * or return to SessionState::IDLING if the queue is empty.
+ *
+ * Note that cancellation (see common::ICancellationSignal) and preemption most be followed with
+ * an Error::CANCELED message.
+ *
+ * @param error See the Error enum.
+ * @param vendorCode Only valid if error == Error::VENDOR.
+ */
void onError(in Error error, in int vendorCode);
- void onEnrollmentProgress(in int enrollmentId, int remaining, int vendorCode);
+ /**
+ * This method must only be used to notify the framework during the following state:
+ * 1) SessionState::ENROLLING
+ *
+ * @param enrollmentId Unique stable identifier for the enrollment that's being added by this
+ * ISession#enroll invocation.
+ * @param remaining Remaining number of steps before enrollment is complete.
+ */
+ void onEnrollmentProgress(in int enrollmentId, int remaining);
- void onAuthenticated(in int enrollmentId, in HardwareAuthToken hat);
+ /**
+ * This method must only be used to notify the framework during SessionState::AUTHENTICATING.
+ *
+ * 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 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);
+ /**
+ * This method must only be used to notify the framework during SessionState::AUTHENTICATING.
+ *
+ * Used to notify the framework upon rejected attempts. Note that the authentication
+ * lifecycle ends when either 1) a fingerprint is accepted, or 2) an occurred. The
+ * authentication lifecycle does NOT end when a fingerprint is rejected.
+ */
+ void onAuthenticationFailed();
+
+ /**
+ * This method must only be used to notify the framework during SessionState::AUTHENTICATING.
+ *
+ * Authentication is locked out due to too many unsuccessful attempts. This is a rate-limiting
+ * lockout, and authentication can be restarted after a period of time. See
+ * ISession#resetLockout.
+ *
+ * @param sensorId Sensor for which the user is locked out.
+ * @param userId User for which the sensor is locked out.
+ * @param durationMillis Remaining duration of the lockout.
+ */
+ void onLockoutTimed(in long durationMillis);
+
+ /**
+ * This method must only be used to notify the framework during SessionState::AUTHENTICATING.
+ *
+ * Authentication is disabled until the user unlocks with their device credential
+ * (PIN/Pattern/Password). See ISession#resetLockout.
+ *
+ * @param sensorId Sensor for which the user is locked out.
+ * @param userId User for which the sensor is locked out.
+ */
+ void onLockoutPermanent();
+
+ /**
+ * Notifies the framework that lockout has been cleared for this (sensorId, userId) pair.
+ *
+ * Note that this method can be used to notify the framework during any state.
+ *
+ * Lockout can be cleared in the following scenarios:
+ * 1) A timed lockout has ended (e.g. durationMillis specified in previous #onLockoutTimed
+ * has expired.
+ * 2) See ISession#resetLockout.
+ *
+ * @param sensorId Sensor for which the user's lockout is cleared.
+ * @param userId User for the sensor's lockout is cleared.
+ */
+ void onLockoutCleared();
+
+ /**
+ * This method must only be used to notify the framework during
+ * SessionState::DETECTING_INTERACTION
+ *
+ * Notifies the framework that user interaction occurred. See ISession#detectInteraction.
+ */
void onInteractionDetected();
+ /**
+ * This method must only be used to notify the framework during
+ * SessionState::ENUMERATING_ENROLLMENTS.
+ *
+ * Notifies the framework of the current enrollments. See ISession#enumerateEnrollments.
+ *
+ * @param enrollmentIds A list of enrollments for the session's (userId, sensorId) pair.
+ */
void onEnrollmentsEnumerated(in int[] enrollmentIds);
+ /**
+ * This method must only be used to notify the framework during
+ * SessionState::REMOVING_ENROLLMENTS.
+ *
+ * Notifies the framework that the specified enrollments are removed.
+ *
+ * @param enrollmentIds The enrollments that were removed.
+ */
void onEnrollmentsRemoved(in int[] enrollmentIds);
/**
- * A callback invoked when ISession#getAuthenticatorId is invoked.
+ * This method must only be used to notify the framework during
+ * SessionState::GETTING_AUTHENTICATOR_ID.
+ *
+ * Notifies the framework with the authenticatorId corresponding to this session's
+ * (userId, sensorId) pair.
+ *
+ * @param authenticatorId See the above documentation.
*/
void onAuthenticatorIdRetrieved(in long authenticatorId);
/**
- * A callback invoked when ISession#invalidateAuthenticatorId has completed.
+ * This method must only be used to notify the framework during
+ * SessionState::INVALIDATING_AUTHENTICATOR_ID.
+ *
+ * See ISession#invalidateAuthenticatorId for more information.
*/
void onAuthenticatorIdInvalidated();
}
diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/SessionState.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/SessionState.aidl
index 3b4ba18..405b011 100644
--- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/SessionState.aidl
+++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/SessionState.aidl
@@ -19,13 +19,49 @@
@VintfStability
@Backing(type="byte")
enum SessionState {
+ /**
+ * The HAL is not processing any session requests.
+ */
IDLING,
+
+ /**
+ * The HAL is processing the ISession#enroll request.
+ */
ENROLLING,
+
+ /**
+ * The HAL is processing the ISession#authenticate request.
+ */
AUTHENTICATING,
+
+ /**
+ * The HAL is processing the ISession#detectInteraction request.
+ */
DETECTING_INTERACTION,
+
+ /**
+ * The HAL is processing the ISession#enumerateEnrollments request.
+ */
ENUMERATING_ENROLLMENTS,
+
+ /**
+ * The HAL is processing the ISession#removeEnrollments request.
+ */
REMOVING_ENROLLMENTS,
+
+ /**
+ * The HAL is processing the ISession#getAuthenticatorId request.
+ */
GETTING_AUTHENTICATOR_ID,
+
+ /**
+ * The HAL is processing the ISession#invalidateAuthenticatorId request.
+ */
+ INVALIDATING_AUTHENTICATOR_ID,
+
+ /**
+ * The HAL is processing the ISession#resetLockout request.
+ */
RESETTING_LOCKOUT
}
diff --git a/biometrics/fingerprint/aidl/default/Fingerprint.cpp b/biometrics/fingerprint/aidl/default/Fingerprint.cpp
index b3bd4e7..b907bf1 100644
--- a/biometrics/fingerprint/aidl/default/Fingerprint.cpp
+++ b/biometrics/fingerprint/aidl/default/Fingerprint.cpp
@@ -61,11 +61,6 @@
return ndk::ScopedAStatus::ok();
}
-ndk::ScopedAStatus Fingerprint::setLockoutCallback(
- const std::shared_ptr<ILockoutCallback>& /*cb*/) {
- return ndk::ScopedAStatus::ok();
-}
-
ndk::ScopedAStatus Fingerprint::generateChallenge(
int32_t /*sensorId*/, int32_t /*userId*/, int32_t /*timeoutSec*/,
const std::shared_ptr<IGenerateChallengeCallback>& /*cb*/) {
diff --git a/biometrics/fingerprint/aidl/default/Fingerprint.h b/biometrics/fingerprint/aidl/default/Fingerprint.h
index 463d07d..59cdd44 100644
--- a/biometrics/fingerprint/aidl/default/Fingerprint.h
+++ b/biometrics/fingerprint/aidl/default/Fingerprint.h
@@ -28,9 +28,6 @@
const std::shared_ptr<ISessionCallback>& cb,
std::shared_ptr<ISession>* _aidl_return) override;
- ndk::ScopedAStatus setLockoutCallback(
- const std::shared_ptr<ILockoutCallback>& cb) override;
-
ndk::ScopedAStatus generateChallenge(
int32_t sensorId, int32_t userId, int32_t timeoutSec,
const std::shared_ptr<IGenerateChallengeCallback>& cb) override;
diff --git a/biometrics/fingerprint/aidl/vts/VtsHalBiometricsFingerprintTargetTest.cpp b/biometrics/fingerprint/aidl/vts/VtsHalBiometricsFingerprintTargetTest.cpp
index 9590d68..496badc 100644
--- a/biometrics/fingerprint/aidl/vts/VtsHalBiometricsFingerprintTargetTest.cpp
+++ b/biometrics/fingerprint/aidl/vts/VtsHalBiometricsFingerprintTargetTest.cpp
@@ -60,16 +60,32 @@
return ndk::ScopedAStatus::ok();
}
- ndk::ScopedAStatus onEnrollmentProgress(int32_t /*enrollmentId*/, int32_t /*remaining*/,
- int32_t /*vendorCode*/) override {
+ ndk::ScopedAStatus onEnrollmentProgress(int32_t /*enrollmentId*/,
+ int32_t /*remaining*/) override {
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 onLockoutTimed(int64_t /*durationMillis*/) override {
+ return ndk::ScopedAStatus::ok();
+ }
+
+ ndk::ScopedAStatus onLockoutPermanent() override {
+ return ndk::ScopedAStatus::ok();
+ }
+
+ ndk::ScopedAStatus onLockoutCleared() override {
+ return ndk::ScopedAStatus::ok();
+ }
+
ndk::ScopedAStatus onInteractionDetected() override { return ndk::ScopedAStatus::ok(); }
ndk::ScopedAStatus onEnrollmentsEnumerated(