diff options
21 files changed, 350 insertions, 756 deletions
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/ISession.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/ISession.aidl index 205429bd7a..9033989563 100644 --- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/ISession.aidl +++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/ISession.aidl @@ -34,17 +34,17 @@ package android.hardware.biometrics.face; @VintfStability interface ISession { - void generateChallenge(in int cookie); - void revokeChallenge(in int cookie, in long challenge); - android.hardware.biometrics.common.ICancellationSignal enroll(in int cookie, in android.hardware.keymaster.HardwareAuthToken hat, in android.hardware.biometrics.face.EnrollmentType type, in android.hardware.biometrics.face.Feature[] features, in android.hardware.common.NativeHandle previewSurface); - 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); - void getFeatures(in int cookie, in int enrollmentId); - void setFeature(in int cookie, in android.hardware.keymaster.HardwareAuthToken hat, in int enrollmentId, in android.hardware.biometrics.face.Feature feature, boolean enabled); - void getAuthenticatorId(in int cookie); - void invalidateAuthenticatorId(in int cookie); - void resetLockout(in int cookie, in android.hardware.keymaster.HardwareAuthToken hat); - void close(in int cookie); + void generateChallenge(); + void revokeChallenge(in long challenge); + android.hardware.biometrics.common.ICancellationSignal enroll(in android.hardware.keymaster.HardwareAuthToken hat, in android.hardware.biometrics.face.EnrollmentType type, in android.hardware.biometrics.face.Feature[] features, in android.hardware.common.NativeHandle previewSurface); + android.hardware.biometrics.common.ICancellationSignal authenticate(in long operationId); + android.hardware.biometrics.common.ICancellationSignal detectInteraction(); + void enumerateEnrollments(); + void removeEnrollments(in int[] enrollmentIds); + void getFeatures(in int enrollmentId); + void setFeature(in android.hardware.keymaster.HardwareAuthToken hat, in int enrollmentId, in android.hardware.biometrics.face.Feature feature, boolean enabled); + void getAuthenticatorId(); + void invalidateAuthenticatorId(); + void resetLockout(in android.hardware.keymaster.HardwareAuthToken hat); + void close(); } diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/ISessionCallback.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/ISessionCallback.aidl index b0bfa3084e..2bb053a31c 100644 --- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/ISessionCallback.aidl +++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/ISessionCallback.aidl @@ -34,7 +34,6 @@ package android.hardware.biometrics.face; @VintfStability interface ISessionCallback { - void onStateChanged(in int cookie, in android.hardware.biometrics.face.SessionState state); void onChallengeGenerated(in long challenge); void onChallengeRevoked(in long challenge); void onAuthenticationFrame(in android.hardware.biometrics.face.AuthenticationFrame frame); diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/SessionState.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/SessionState.aidl deleted file mode 100644 index 4db47c9c67..0000000000 --- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/SessionState.aidl +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (C) 2021 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. - */ -/////////////////////////////////////////////////////////////////////////////// -// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // -/////////////////////////////////////////////////////////////////////////////// - -// This file is a snapshot of an AIDL file. Do not edit it manually. There are -// two cases: -// 1). this is a frozen version file - do not edit this in any case. -// 2). this is a 'current' file. If you make a backwards compatible change to -// the interface (from the latest frozen version), the build system will -// prompt you to update this file with `m <name>-update-api`. -// -// You must not make a backward incompatible change to any AIDL file 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.face; -@Backing(type="byte") @VintfStability -enum SessionState { - IDLING = 0, - CLOSED = 1, - GENERATING_CHALLENGE = 2, - REVOKING_CHALLENGE = 3, - ENROLLING = 4, - AUTHENTICATING = 5, - DETECTING_INTERACTION = 6, - ENUMERATING_ENROLLMENTS = 7, - REMOVING_ENROLLMENTS = 8, - GETTING_FEATURES = 9, - SETTING_FEATURE = 10, - GETTING_AUTHENTICATOR_ID = 11, - INVALIDATING_AUTHENTICATOR_ID = 12, - RESETTING_LOCKOUT = 13, -} diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/ISession.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/ISession.aidl index 66c7c38710..75025157a7 100644 --- a/biometrics/face/aidl/android/hardware/biometrics/face/ISession.aidl +++ b/biometrics/face/aidl/android/hardware/biometrics/face/ISession.aidl @@ -23,11 +23,25 @@ import android.hardware.common.NativeHandle; import android.hardware.keymaster.HardwareAuthToken; /** - * A session is a collection of immutable state (sensorId, userId), mutable state (SessionState), - * methods available for the framework to call, and a callback (ISessionCallback) to notify the - * framework about the events and results. A session is used to establish communication between - * the framework and the HAL. + * Operations that can be performed for unique sessions retrieved via IFace#createSession. + * Operations defined within this interface can be divided into the following categories: + * 1) Cancellable operations. These are usually the operations that can execute for several + * minutes. To allow for cancellation, they return an instance of ICancellationSignal that + * lets the framework cancel them by calling ICancellationSignal#cancel. If such an operation + * is cancelled, it must notify the framework by calling ISessionCallback#onError with + * Error::CANCELED. + * 2) Non-cancellable operations. Such operations cannot be cancelled once started. + * + * The lifecycle of an operation ends when one of its terminal callbacks is called. For example, + * ISession#authenticate is considered completed when any of the following callbacks is called: + * ISessionCallback#onError, ISessionCallback#onAuthenticationSucceeded, + * ISessionCallback#onAuthenticationFailed. + * + * ISession only supports execution of one operation at a time, regardless of whether it's + * cancellable or not. The framework must wait for a corresponding callback indicating the end of + * the current operation before a new operation can be started. */ + @VintfStability interface ISession { /** @@ -68,9 +82,8 @@ interface ISession { * | 0 | 10 | <Time4> | <Random4> | * ---------------------------------------------- * - * @param cookie A unique number identifying this operation */ - void generateChallenge(in int cookie); + void generateChallenge(); /** * revokeChallenge: @@ -79,10 +92,9 @@ interface ISession { * parameters is requested, the implementation must still notify the framework using the * provided callback. * - * @param cookie A unique number identifying this operation * @param challenge Challenge that should be revoked. */ - void revokeChallenge(in int cookie, in long challenge); + void revokeChallenge(in long challenge); /** * getEnrollmentConfig: @@ -101,19 +113,13 @@ interface ISession { * * A request to add a face 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. + * framework via ISessionCallback#onError with the applicable enrollment-specific error. * * Before capturing face 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 ISession#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 + * the above checks fail, the framework must be notified using ISessionCallback#onError with * Error::UNABLE_TO_PROCESS. * * During enrollment, the implementation may notify the framework via @@ -121,15 +127,12 @@ interface ISession { * 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. + * ISessionCallback#onEnrollmentProgress for more info. * - * 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 + * When a face 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 * 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. * @param enrollmentType See the EnrollmentType enum. * @param features See the Feature enum. @@ -139,7 +142,7 @@ interface ISession { * @return ICancellationSignal An object that can be used by the framework to cancel this * operation. */ - ICancellationSignal enroll(in int cookie, in HardwareAuthToken hat, in EnrollmentType type, + ICancellationSignal enroll(in HardwareAuthToken hat, in EnrollmentType type, in Feature[] features, in NativeHandle previewSurface); /** @@ -147,13 +150,8 @@ interface ISession { * * A request to start looking for faces 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. + * the framework via ISessionCallback#onError with the applicable authentication-specific error. * * During authentication, the implementation may notify the framework via * ISessionCallback#onAcquired with messages that may be used to guide the user. This callback @@ -175,8 +173,6 @@ interface ISession { * 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 @@ -190,7 +186,7 @@ interface ISession { * @return ICancellationSignal An object that can be used by the framework to cancel this * operation. */ - ICancellationSignal authenticate(in int cookie, in long operationId); + ICancellationSignal authenticate(in long operationId); /** * detectInteraction: @@ -199,17 +195,12 @@ interface ISession { * SensorProps#supportsDetectInteraction is true. If invoked on implementations that do not * support this functionality, the HAL must respond with ISession#onError(UNABLE_TO_PROCESS, 0). * - * 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 framework via ISessionCallback#onError with the applicable error. * * The implementation must only check for a face-like image was detected (e.g. to * minimize interactions due to non-face objects), and the lockout counter must not @@ -222,17 +213,14 @@ interface ISession { * 1) Any face 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. * @return ICancellationSignal An object that can be used by the framework to cancel this * operation. */ - ICancellationSignal detectInteraction(in int cookie); + ICancellationSignal detectInteraction(); /* * enumerateEnrollments: @@ -240,32 +228,22 @@ interface ISession { * 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); + void enumerateEnrollments(); /** * 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); + void removeEnrollments(in int[] enrollmentIds); /** * getFeatures: @@ -273,20 +251,14 @@ interface ISession { * Returns a list of currently enabled features for the provided enrollmentId. * * If the enrollmentId is invalid, the HAL must invoke ISessionCallback#onError with - * Error::UNABLE_TO_PROCESS and return to SessionState::IDLING if no subsequent work is in the - * queue. - * - * Once the HAL is able to start processing this request, it must notify the framework by using - * ISessionCallback#onStateChanged with SessionState::GETTING_FEATURES. + * Error::UNABLE_TO_PROCESS. * * The HAL must notify the framework about the result by calling * ISessionCallback#onFeaturesRetrieved. * - * @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 enrollmentId the ID of the enrollment for which the features are requested. */ - void getFeatures(in int cookie, in int enrollmentId); + void getFeatures(in int enrollmentId); /** * setFeature: @@ -296,24 +268,18 @@ interface ISession { * (see @param hat). The HAL must verify the hat before changing any feature state. * * If either the hat or enrollmentId is invalid, the HAL must invoke ISessionCallback#onError - * with Error::UNABLE_TO_PROCESS and return to SessionState::IDLING if no subsequent work is in - * the queue. - * - * Once the HAL is able to start processing this request, it must notify the framework by using - * ISessionCallback#onStateChanged with SessionState::SETTING_FEATURE. + * with Error::UNABLE_TO_PROCESS. * * After the feature is successfully set, the HAL must notify the framework by calling * ISessionCallback#onFeatureSet. * - * @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 HardwareAuthToken See above documentation. * @param enrollmentId the ID of the enrollment for which the feature update is requested. * @param feature The feature to be enabled or disabled. * @param enabled Whether the provided features should be enabled or disabled. */ - void setFeature(in int cookie, in HardwareAuthToken hat, in int enrollmentId, - in Feature feature, boolean enabled); + void setFeature( + in HardwareAuthToken hat, in int enrollmentId, in Feature feature, boolean enabled); /** * getAuthenticatorId: @@ -341,10 +307,8 @@ interface ISession { * 3) MUST not change if a face is deleted. * 4) MUST be an entropy-encoded random number * - * @param cookie An identifier used to track subsystem operations related to this call path. The - * client must guarantee that it is unique per ISession. */ - void getAuthenticatorId(in int cookie); + void getAuthenticatorId(); /** * invalidateAuthenticatorId: @@ -368,10 +332,8 @@ interface ISession { * for more details). As such, the framework would coordinate invalidation across multiple * biometric HALs as necessary. * - * @param cookie An identifier used to track subsystem operations related to this call path. The - * client must guarantee that it is unique per ISession. */ - void invalidateAuthenticatorId(in int cookie); + void invalidateAuthenticatorId(); /** * resetLockout: @@ -382,8 +344,7 @@ interface ISession { * 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. + * Error::UNABLE_TO_PROCESS. * * Upon successful verification, the HAL must clear the lockout counter and notify the framework * via ISessionCallback#onLockoutCleared. @@ -414,27 +375,20 @@ interface ISession { * 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 - * client must guarantee that it is unique per ISession. * @param hat HardwareAuthToken See above documentation. */ - void resetLockout(in int cookie, in HardwareAuthToken hat); + void resetLockout(in HardwareAuthToken hat); /* * Close this session and allow the HAL to release the resources associated with this session. * - * A session can only be closed when it's in SessionState::IDLING. Closing a session will - * result in a ISessionCallback#onStateChanged call with SessionState::CLOSED. - * - * If a session is unresponsive or stuck in a state other than SessionState::CLOSED, - * IFace#reset could be used as a last resort to terminate the session and recover the HAL - * from a bad state. + * A session can only be closed when the HAL is idling, i.e. not performing any operations. + * If the HAL is busy performing a cancellable operation, the operation must be explicitly + * cancelled with a call to ICancellationSignal#cancel before the session can be closed. * * All sessions must be explicitly closed. Calling IFace#createSession while there is an active * session is considered an error. * - * @param cookie An identifier used to track subsystem operations related to this call path. The - * client must guarantee that it is unique per ISession. */ - void close(in int cookie); + void close(); } diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/ISessionCallback.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/ISessionCallback.aidl index c1aa3fcf80..a2601e7360 100644 --- a/biometrics/face/aidl/android/hardware/biometrics/face/ISessionCallback.aidl +++ b/biometrics/face/aidl/android/hardware/biometrics/face/ISessionCallback.aidl @@ -21,17 +21,11 @@ import android.hardware.biometrics.face.AuthenticationFrame; import android.hardware.biometrics.face.EnrollmentFrame; import android.hardware.biometrics.face.Error; import android.hardware.biometrics.face.Feature; -import android.hardware.biometrics.face.SessionState; import android.hardware.keymaster.HardwareAuthToken; @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); - - /** * Notifies the framework when a challenge is successfully generated. */ void onChallengeGenerated(in long challenge); @@ -42,9 +36,9 @@ interface ISessionCallback { void onChallengeRevoked(in long challenge); /** - * This method must only be used to notify the framework during the following states: - * 1) SessionState::AUTHENTICATING - * 2) SessionState::DETECTING_INTERACTION + * This method must only be used to notify the framework during the following operations: + * 1) ISession#authenticate + * 2) ISession#detectInteraction * * These messages may be used to provide user guidance multiple times if necessary per * operation. @@ -54,8 +48,8 @@ interface ISessionCallback { void onAuthenticationFrame(in AuthenticationFrame frame); /** - * This method must only be used to notify the framework during the SessionState::ENROLLING - * state. + * This method must only be used to notify the framework during the ISession#enroll + * operation. * * These messages may be used to provide user guidance multiple times if necessary per * operation. @@ -65,18 +59,18 @@ interface ISessionCallback { void onEnrollmentFrame(in EnrollmentFrame frame); /** - * 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 + * This method must only be used to notify the framework during the following operations: + * 1) ISession#enroll + * 2) ISession#authenticate + * 3) ISession#detectInteraction + * 4) ISession#invalidateAuthenticatorId + * 5) ISession#resetLockout * * 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. + * or return to the idling state. * - * Note that cancellation (see common::ICancellationSignal) and preemption most be followed with + * Note that cancellation (see common::ICancellationSignal) and preemption must be followed with * an Error::CANCELED message. * * @param error See the Error enum. @@ -88,8 +82,7 @@ interface ISessionCallback { void onError(in Error error, in int vendorCode); /** - * This method must only be used to notify the framework during the following state: - * 1) SessionState::ENROLLING + * This method must only be used to notify the framework during the ISession#enroll operation. * * @param enrollmentId Unique stable identifier for the enrollment that's being added by this * ISession#enroll invocation. @@ -98,7 +91,7 @@ interface ISessionCallback { void onEnrollmentProgress(in int enrollmentId, int remaining); /** - * This method must only be used to notify the framework during SessionState::AUTHENTICATING. + * This method must only be used to notify the framework during ISession#authenticate. * * Used to notify the framework about a successful authentication. This ends the authentication * lifecycle. @@ -112,7 +105,7 @@ interface ISessionCallback { void onAuthenticationSucceeded(in int enrollmentId, in HardwareAuthToken hat); /** - * This method must only be used to notify the framework during SessionState::AUTHENTICATING. + * This method must only be used to notify the framework during ISession#authenticate. * * Used to notify the framework about a failed authentication. This ends the authentication * lifecycle. @@ -120,7 +113,7 @@ interface ISessionCallback { void onAuthenticationFailed(); /** - * This method must only be used to notify the framework during SessionState::AUTHENTICATING. + * This method must only be used to notify the framework during ISession#authenticate. * * 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 @@ -133,7 +126,7 @@ interface ISessionCallback { void onLockoutTimed(in long durationMillis); /** - * This method must only be used to notify the framework during SessionState::AUTHENTICATING. + * This method must only be used to notify the framework during ISession#authenticate. * * Authentication is disabled until the user unlocks with their device credential * (PIN/Pattern/Password). See ISession#resetLockout. @@ -160,7 +153,7 @@ interface ISessionCallback { /** * This method must only be used to notify the framework during - * SessionState::DETECTING_INTERACTION + * ISession#detectInteraction * * Notifies the framework that user interaction occurred. See ISession#detectInteraction. */ @@ -168,7 +161,7 @@ interface ISessionCallback { /** * This method must only be used to notify the framework during - * SessionState::ENUMERATING_ENROLLMENTS. + * ISession#enumerateEnrollments. * * Notifies the framework of the current enrollments. See ISession#enumerateEnrollments. * @@ -177,7 +170,7 @@ interface ISessionCallback { void onEnrollmentsEnumerated(in int[] enrollmentIds); /** - * This method must only be used to notify the framework during SessionState::GETTING_FEATURES. + * This method must only be used to notify the framework during ISession#getFeatures. * * Provides a list of features that are currently enabled for the given enrollmentId. * @@ -187,7 +180,7 @@ interface ISessionCallback { void onFeaturesRetrieved(in Feature[] features, in int enrollmentId); /** - * This method must only be used to notify the framework during SessionState::SETTING_FEATURE. + * This method must only be used to notify the framework during ISession#setFeature. * * Notifies the framework that ISession#setFeature has completed. * @@ -198,7 +191,7 @@ interface ISessionCallback { /** * This method must only be used to notify the framework during - * SessionState::REMOVING_ENROLLMENTS. + * ISession#removeEnrollments. * * Notifies the framework that the specified enrollments are removed. * @@ -208,7 +201,7 @@ interface ISessionCallback { /** * This method must only be used to notify the framework during - * SessionState::GETTING_AUTHENTICATOR_ID. + * ISession#getAuthenticatorId. * * Notifies the framework with the authenticatorId corresponding to this session's * (userId, sensorId) pair. @@ -219,7 +212,7 @@ interface ISessionCallback { /** * This method must only be used to notify the framework during - * SessionState::INVALIDATING_AUTHENTICATOR_ID. + * ISession#invalidateAuthenticatorId. * * See ISession#invalidateAuthenticatorId for more information. * diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/SessionState.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/SessionState.aidl deleted file mode 100644 index afde4eb2d5..0000000000 --- a/biometrics/face/aidl/android/hardware/biometrics/face/SessionState.aidl +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright (C) 2021 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.face; - -@VintfStability -@Backing(type="byte") -enum SessionState { - /** - * The HAL is not processing any session requests. - */ - IDLING, - - /** - * The session has been closed by the client. - */ - CLOSED, - - /** - * The HAL is processing the ISession#generateChallenge request. - */ - GENERATING_CHALLENGE, - - /** - * The HAL is processing the ISession#revokeChallenge request. - */ - REVOKING_CHALLENGE, - - /** - * 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#getFeatures request. - */ - GETTING_FEATURES, - - /** - * The HAL is processing the ISession#setFeature request. - */ - SETTING_FEATURE, - - /** - * 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/face/aidl/default/Session.cpp b/biometrics/face/aidl/default/Session.cpp index ce6c5572e6..b5eb717351 100644 --- a/biometrics/face/aidl/default/Session.cpp +++ b/biometrics/face/aidl/default/Session.cpp @@ -30,119 +30,105 @@ class CancellationSignal : public common::BnCancellationSignal { ndk::ScopedAStatus cancel() override { cb_->onError(Error::CANCELED, 0 /* vendorCode */); - cb_->onStateChanged(0, SessionState::IDLING); return ndk::ScopedAStatus::ok(); } }; Session::Session(std::shared_ptr<ISessionCallback> cb) : cb_(std::move(cb)) {} -ndk::ScopedAStatus Session::generateChallenge(int32_t /*cookie*/) { +ndk::ScopedAStatus Session::generateChallenge() { LOG(INFO) << "generateChallenge"; if (cb_) { - cb_->onStateChanged(0, SessionState::GENERATING_CHALLENGE); cb_->onChallengeGenerated(0); - cb_->onStateChanged(0, SessionState::IDLING); } return ndk::ScopedAStatus::ok(); } -ndk::ScopedAStatus Session::revokeChallenge(int32_t /*cookie*/, int64_t challenge) { +ndk::ScopedAStatus Session::revokeChallenge(int64_t challenge) { LOG(INFO) << "revokeChallenge"; if (cb_) { - cb_->onStateChanged(0, SessionState::REVOKING_CHALLENGE); cb_->onChallengeRevoked(challenge); - cb_->onStateChanged(0, SessionState::IDLING); } return ndk::ScopedAStatus::ok(); } ndk::ScopedAStatus Session::enroll( - int32_t /*cookie*/, const keymaster::HardwareAuthToken& /*hat*/, - EnrollmentType /*enrollmentType*/, const std::vector<Feature>& /*features*/, - const NativeHandle& /*previewSurface*/, + const keymaster::HardwareAuthToken& /*hat*/, EnrollmentType /*enrollmentType*/, + const std::vector<Feature>& /*features*/, const NativeHandle& /*previewSurface*/, std::shared_ptr<biometrics::common::ICancellationSignal>* /*return_val*/) { LOG(INFO) << "enroll"; return ndk::ScopedAStatus::ok(); } -ndk::ScopedAStatus Session::authenticate(int32_t /*cookie*/, int64_t /*keystoreOperationId*/, +ndk::ScopedAStatus Session::authenticate(int64_t /*keystoreOperationId*/, std::shared_ptr<common::ICancellationSignal>* return_val) { LOG(INFO) << "authenticate"; if (cb_) { - cb_->onStateChanged(0, SessionState::AUTHENTICATING); + cb_->onError(Error::UNABLE_TO_PROCESS, 0 /* vendorCode */); } *return_val = SharedRefBase::make<CancellationSignal>(cb_); return ndk::ScopedAStatus::ok(); } ndk::ScopedAStatus Session::detectInteraction( - int32_t /*cookie*/, std::shared_ptr<common::ICancellationSignal>* /*return_val*/) { + std::shared_ptr<common::ICancellationSignal>* /*return_val*/) { LOG(INFO) << "detectInteraction"; return ndk::ScopedAStatus::ok(); } -ndk::ScopedAStatus Session::enumerateEnrollments(int32_t /*cookie*/) { +ndk::ScopedAStatus Session::enumerateEnrollments() { LOG(INFO) << "enumerateEnrollments"; if (cb_) { - cb_->onStateChanged(0, SessionState::ENUMERATING_ENROLLMENTS); cb_->onEnrollmentsEnumerated(std::vector<int32_t>()); - cb_->onStateChanged(0, SessionState::IDLING); } return ndk::ScopedAStatus::ok(); } -ndk::ScopedAStatus Session::removeEnrollments(int32_t /*cookie*/, - const std::vector<int32_t>& /*enrollmentIds*/) { +ndk::ScopedAStatus Session::removeEnrollments(const std::vector<int32_t>& /*enrollmentIds*/) { LOG(INFO) << "removeEnrollments"; if (cb_) { - cb_->onStateChanged(0, SessionState::REMOVING_ENROLLMENTS); cb_->onEnrollmentsRemoved(std::vector<int32_t>()); - cb_->onStateChanged(0, SessionState::IDLING); } return ndk::ScopedAStatus::ok(); } -ndk::ScopedAStatus Session::getFeatures(int32_t /*cookie*/, int32_t /*enrollmentId*/) { +ndk::ScopedAStatus Session::getFeatures(int32_t /*enrollmentId*/) { LOG(INFO) << "getFeatures"; return ndk::ScopedAStatus::ok(); } -ndk::ScopedAStatus Session::setFeature(int32_t /*cookie*/, - const keymaster::HardwareAuthToken& /*hat*/, +ndk::ScopedAStatus Session::setFeature(const keymaster::HardwareAuthToken& /*hat*/, int32_t /*enrollmentId*/, Feature /*feature*/, bool /*enabled*/) { LOG(INFO) << "setFeature"; return ndk::ScopedAStatus::ok(); } -ndk::ScopedAStatus Session::getAuthenticatorId(int32_t /*cookie*/) { +ndk::ScopedAStatus Session::getAuthenticatorId() { LOG(INFO) << "getAuthenticatorId"; if (cb_) { - cb_->onStateChanged(0, SessionState::GETTING_AUTHENTICATOR_ID); cb_->onAuthenticatorIdRetrieved(0 /* authenticatorId */); - cb_->onStateChanged(0, SessionState::IDLING); } return ndk::ScopedAStatus::ok(); } -ndk::ScopedAStatus Session::invalidateAuthenticatorId(int32_t /*cookie*/) { +ndk::ScopedAStatus Session::invalidateAuthenticatorId() { LOG(INFO) << "invalidateAuthenticatorId"; return ndk::ScopedAStatus::ok(); } -ndk::ScopedAStatus Session::resetLockout(int32_t /*cookie*/, - const keymaster::HardwareAuthToken& /*hat*/) { +ndk::ScopedAStatus Session::resetLockout(const keymaster::HardwareAuthToken& /*hat*/) { LOG(INFO) << "resetLockout"; if (cb_) { - cb_->onStateChanged(0, SessionState::RESETTING_LOCKOUT); cb_->onLockoutCleared(); - cb_->onStateChanged(0, SessionState::IDLING); } return ndk::ScopedAStatus::ok(); } -ndk::ScopedAStatus Session::close(int32_t /*cookie*/) { +ndk::ScopedAStatus Session::close() { + if (cb_) { + cb_->onSessionClosed(); + } return ndk::ScopedAStatus::ok(); } diff --git a/biometrics/face/aidl/default/Session.h b/biometrics/face/aidl/default/Session.h index eb9ae83342..73cdf08625 100644 --- a/biometrics/face/aidl/default/Session.h +++ b/biometrics/face/aidl/default/Session.h @@ -30,40 +30,38 @@ class Session : public BnSession { public: explicit Session(std::shared_ptr<ISessionCallback> cb); - ndk::ScopedAStatus generateChallenge(int32_t cookie) override; + ndk::ScopedAStatus generateChallenge() override; - ndk::ScopedAStatus revokeChallenge(int32_t cookie, int64_t challenge) override; + ndk::ScopedAStatus revokeChallenge(int64_t challenge) override; - ndk::ScopedAStatus enroll(int32_t cookie, const keymaster::HardwareAuthToken& hat, + ndk::ScopedAStatus enroll(const keymaster::HardwareAuthToken& hat, EnrollmentType enrollmentType, const std::vector<Feature>& features, const NativeHandle& previewSurface, std::shared_ptr<common::ICancellationSignal>* return_val) override; ndk::ScopedAStatus authenticate( - int32_t cookie, int64_t keystoreOperationId, + int64_t keystoreOperationId, std::shared_ptr<common::ICancellationSignal>* returnVal) override; ndk::ScopedAStatus detectInteraction( - int32_t cookie, std::shared_ptr<common::ICancellationSignal>* returnVal) override; + std::shared_ptr<common::ICancellationSignal>* returnVal) override; - ndk::ScopedAStatus enumerateEnrollments(int32_t cookie) override; + ndk::ScopedAStatus enumerateEnrollments() override; - ndk::ScopedAStatus removeEnrollments(int32_t cookie, - const std::vector<int32_t>& enrollmentIds) override; + ndk::ScopedAStatus removeEnrollments(const std::vector<int32_t>& enrollmentIds) override; - ndk::ScopedAStatus getFeatures(int32_t cookie, int32_t enrollmentId) override; + ndk::ScopedAStatus getFeatures(int32_t enrollmentId) override; - ndk::ScopedAStatus setFeature(int32_t cookie, const keymaster::HardwareAuthToken& hat, - int32_t enrollmentId, Feature feature, bool enabled) override; + ndk::ScopedAStatus setFeature(const keymaster::HardwareAuthToken& hat, int32_t enrollmentId, + Feature feature, bool enabled) override; - ndk::ScopedAStatus getAuthenticatorId(int32_t cookie) override; + ndk::ScopedAStatus getAuthenticatorId() override; - ndk::ScopedAStatus invalidateAuthenticatorId(int32_t cookie) override; + ndk::ScopedAStatus invalidateAuthenticatorId() override; - ndk::ScopedAStatus resetLockout(int32_t cookie, - const keymaster::HardwareAuthToken& hat) override; + ndk::ScopedAStatus resetLockout(const keymaster::HardwareAuthToken& hat) override; - ndk::ScopedAStatus close(int32_t cookie) override; + ndk::ScopedAStatus close() override; private: std::shared_ptr<ISessionCallback> cb_; diff --git a/biometrics/face/aidl/vts/VtsHalBiometricsFaceTargetTest.cpp b/biometrics/face/aidl/vts/VtsHalBiometricsFaceTargetTest.cpp index 936fcc69e5..60e0a2a41f 100644 --- a/biometrics/face/aidl/vts/VtsHalBiometricsFaceTargetTest.cpp +++ b/biometrics/face/aidl/vts/VtsHalBiometricsFaceTargetTest.cpp @@ -21,35 +21,31 @@ #include <android/binder_manager.h> #include <android/binder_process.h> +#include <chrono> #include <future> namespace aidl::android::hardware::biometrics::face { namespace { +using namespace std::literals::chrono_literals; + constexpr int kSensorId = 0; constexpr int kUserId = 0; -constexpr auto kCallbackTimeout = std::chrono::seconds(1); -enum class SessionCallbackMethodName { - kOnStateChanged, +enum class MethodName { + kOnError, + kOnSessionClosed, }; -struct SessionCallbackInvocation { - SessionCallbackMethodName method_name; - SessionState state; +struct Invocation { + MethodName methodName; + Error error; + int32_t vendorCode; }; class SessionCallback : public BnSessionCallback { public: - explicit SessionCallback(std::promise<SessionCallbackInvocation> invocation_promise) - : invocation_promise_(std::move(invocation_promise)) {} - ndk::ScopedAStatus onStateChanged(int32_t /*cookie*/, SessionState state) override { - SessionCallbackInvocation invocation = {}; - invocation.method_name = SessionCallbackMethodName::kOnStateChanged; - invocation.state = state; - invocation_promise_.set_value(invocation); - return ndk::ScopedAStatus::ok(); - } + explicit SessionCallback(Invocation* inv) : mInv(inv) {} ndk::ScopedAStatus onChallengeGenerated(int64_t /*challenge*/) override { return ndk::ScopedAStatus::ok(); @@ -67,7 +63,12 @@ class SessionCallback : public BnSessionCallback { return ndk::ScopedAStatus::ok(); } - ndk::ScopedAStatus onError(Error /*error*/, int32_t /*vendorCode*/) override { + ndk::ScopedAStatus onError(Error error, int32_t vendorCode) override { + *mInv = {}; + mInv->methodName = MethodName::kOnError; + mInv->error = error; + mInv->vendorCode = vendorCode; + return ndk::ScopedAStatus::ok(); } @@ -120,10 +121,15 @@ class SessionCallback : public BnSessionCallback { return ndk::ScopedAStatus::ok(); } - ndk::ScopedAStatus onSessionClosed() override { return ndk::ScopedAStatus::ok(); } + ndk::ScopedAStatus onSessionClosed() override { + *mInv = {}; + mInv->methodName = MethodName::kOnSessionClosed; + + return ndk::ScopedAStatus::ok(); + } private: - std::promise<SessionCallbackInvocation> invocation_promise_; + Invocation* mInv; }; class Face : public testing::TestWithParam<std::string> { @@ -131,28 +137,34 @@ class Face : public testing::TestWithParam<std::string> { void SetUp() override { AIBinder* binder = AServiceManager_waitForService(GetParam().c_str()); ASSERT_NE(binder, nullptr); - hal_ = IFace::fromBinder(ndk::SpAIBinder(binder)); + mHal = IFace::fromBinder(ndk::SpAIBinder(binder)); } - std::shared_ptr<IFace> hal_; + std::shared_ptr<IFace> mHal; + Invocation mInv; }; TEST_P(Face, AuthenticateTest) { - std::promise<SessionCallbackInvocation> invocation_promise; - std::future<SessionCallbackInvocation> invocation_future = invocation_promise.get_future(); - std::shared_ptr<SessionCallback> session_cb = - ndk::SharedRefBase::make<SessionCallback>(std::move(invocation_promise)); + // Prepare the callback. + auto cb = ndk::SharedRefBase::make<SessionCallback>(&mInv); + // Create a session std::shared_ptr<ISession> session; - ASSERT_TRUE(hal_->createSession(kSensorId, kUserId, session_cb, &session).isOk()); + ASSERT_TRUE(mHal->createSession(kSensorId, kUserId, cb, &session).isOk()); + + // Call authenticate + std::shared_ptr<common::ICancellationSignal> cancellationSignal; + ASSERT_TRUE(session->authenticate(0 /* operationId */, &cancellationSignal).isOk()); + + // Get the results + EXPECT_EQ(mInv.methodName, MethodName::kOnError); + EXPECT_EQ(mInv.error, Error::UNABLE_TO_PROCESS); + EXPECT_EQ(mInv.vendorCode, 0); - std::shared_ptr<common::ICancellationSignal> cancel_cb; - ASSERT_TRUE(session->authenticate(0, 0, &cancel_cb).isOk()); - ASSERT_EQ(invocation_future.wait_for(kCallbackTimeout), std::future_status::ready); + // Close the session + ASSERT_TRUE(session->close().isOk()); - SessionCallbackInvocation invocation = invocation_future.get(); - EXPECT_EQ(invocation.method_name, SessionCallbackMethodName::kOnStateChanged); - EXPECT_EQ(invocation.state, SessionState::AUTHENTICATING); + EXPECT_EQ(mInv.methodName, MethodName::kOnSessionClosed); } GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(Face); @@ -161,6 +173,7 @@ INSTANTIATE_TEST_SUITE_P(IFace, Face, ::android::PrintInstanceNameToString); } // namespace +} // namespace aidl::android::hardware::biometrics::face int main(int argc, char** argv) { ::testing::InitGoogleTest(&argc, argv); @@ -169,4 +182,3 @@ int main(int argc, char** argv) { return RUN_ALL_TESTS(); } -} // namespace aidl::android::hardware::biometrics::face 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 87eaf96a41..9934a763e7 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 @@ -34,17 +34,17 @@ package android.hardware.biometrics.fingerprint; @VintfStability interface ISession { - void generateChallenge(in int cookie); - void revokeChallenge(in int cookie, in long challenge); - 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 operationId); - android.hardware.biometrics.common.ICancellationSignal detectInteraction(in int cookie); - void enumerateEnrollments(in int cookie); - void removeEnrollments(in int cookie, in int[] enrollmentIds); - void getAuthenticatorId(in int cookie); - void invalidateAuthenticatorId(in int cookie); - void resetLockout(in int cookie, in android.hardware.keymaster.HardwareAuthToken hat); - void close(in int cookie); + void generateChallenge(); + void revokeChallenge(in long challenge); + android.hardware.biometrics.common.ICancellationSignal enroll(in android.hardware.keymaster.HardwareAuthToken hat); + android.hardware.biometrics.common.ICancellationSignal authenticate(in long operationId); + android.hardware.biometrics.common.ICancellationSignal detectInteraction(); + void enumerateEnrollments(); + void removeEnrollments(in int[] enrollmentIds); + void getAuthenticatorId(); + void invalidateAuthenticatorId(); + void resetLockout(in android.hardware.keymaster.HardwareAuthToken hat); + void close(); void onPointerDown(in int pointerId, in int x, in int y, in float minor, in float major); void onPointerUp(in int pointerId); void onUiReady(); 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 3a977178ff..3c40ad63bf 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 @@ -34,7 +34,6 @@ package android.hardware.biometrics.fingerprint; @VintfStability interface ISessionCallback { - void onStateChanged(in int cookie, in android.hardware.biometrics.fingerprint.SessionState state); void onChallengeGenerated(in long challenge); void onChallengeRevoked(in long challenge); void onAcquired(in android.hardware.biometrics.fingerprint.AcquiredInfo info, in int vendorCode); 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 deleted file mode 100644 index 9b0b6f6a77..0000000000 --- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SessionState.aidl +++ /dev/null @@ -1,49 +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. - */ -/////////////////////////////////////////////////////////////////////////////// -// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // -/////////////////////////////////////////////////////////////////////////////// - -// This file is a snapshot of an AIDL file. Do not edit it manually. There are -// two cases: -// 1). this is a frozen version file - do not edit this in any case. -// 2). this is a 'current' file. If you make a backwards compatible change to -// the interface (from the latest frozen version), the build system will -// prompt you to update this file with `m <name>-update-api`. -// -// You must not make a backward incompatible change to any AIDL file 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; -@Backing(type="byte") @VintfStability -enum SessionState { - IDLING = 0, - CLOSED = 1, - GENERATING_CHALLENGE = 2, - REVOKING_CHALLENGE = 3, - ENROLLING = 4, - AUTHENTICATING = 5, - DETECTING_INTERACTION = 6, - ENUMERATING_ENROLLMENTS = 7, - REMOVING_ENROLLMENTS = 8, - GETTING_AUTHENTICATOR_ID = 9, - INVALIDATING_AUTHENTICATOR_ID = 10, - RESETTING_LOCKOUT = 11, -} diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IFingerprint.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IFingerprint.aidl index 98a45307b9..271a9bf1cf 100644 --- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IFingerprint.aidl +++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IFingerprint.aidl @@ -32,27 +32,14 @@ interface IFingerprint { /** * createSession: * - * Creates a session which can then be used by the framework to perform operations such as - * enroll, authenticate, etc for the given sensorId and userId. + * Creates a instance of ISession which can be used by the framework to perform operations + * such as ISession#enroll, ISession#authenticate, etc. for the given sensorId and userId. * - * Calling this method while there is an active session is considered an error. If the - * framework is in a bad state and for some reason cannot close its session, it should use - * the reset method below. - * - * A physical sensor identified by sensorId typically supports only a single in-flight session - * at a time. As such, if a session is currently in a state other than SessionState::IDLING, the - * HAL MUST finish or cancel the current operation and return to SessionState::IDLING before the - * new session is created. For example: - * 1) If a session for sensorId=0, userId=0 is currently in a cancellable state (see - * ICancellationSignal) such as SessionState::AUTHENTICATING and the framework requests a - * new session for sensorId=0, userId=10, the HAL must end the current session with - * Error::CANCELED, invoke ISessionCallback#onStateChanged with SessionState::IDLING, and - * then return a new session for sensorId=0, userId=10. - * 2) If a session for sensorId=0, userId=0 is currently in a non-cancellable state such as - * SessionState::REMOVING_ENROLLMENTS, and the framework requests a new session for - * sensorId=0, userId=10, the HAL must finish the current operation before invoking - * ISessionCallback#onStateChanged with SessionState::IDLING, and return a new session for - * sensorId=0, userId=10. + * Calling this method while there is an active session is considered an error. If the framework + * wants to create a new session when it already has an active session, it must first cancel the + * current operation if it's cancellable, or wait until it completes. Then, the framework must + * explicitly close the session with ISession#close. Once the framework receives + * ISessionCallback#onSessionClosed, a new session can be created. * * Implementations must store user-specific state or metadata in /data/vendor_de/<user>/fpdata * as specified by the SeLinux policy. This directory is created/removed by vold (see diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl index ef2e6fc499..940548ba88 100644 --- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl +++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl @@ -22,23 +22,28 @@ 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. + * 1) Non-interrupting operations. These operations are handled by the HAL in FIFO order. + * 1a) Cancellable operations. These are usually the operations that can execute for several + * minutes. To allow for cancellation, they return an instance of ICancellationSignal that + * lets the framework cancel them by calling ICancellationSignal#cancel. If such an operation + * is cancelled, it must notify the framework by calling ISessionCallback#onError with + * Error::CANCELED. + * 1b) Non-cancellable operations. Such operations cannot be cancelled once started. + * 2) Interrupting operations. These operations may be invoked by the framework immediately, + * regardless of whether another operation is executing. For example, on devices with sensors + * of FingerprintSensorType::UNDER_DISPLAY_*, ISession#onFingerDown may be invoked while the + * HAL is executing ISession#enroll, ISession#authenticate or ISession#detectInteraction. * - * 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. + * The lifecycle of a non-interrupting operation ends when one of its terminal callbacks is called. + * For example, ISession#authenticate is considered completed when either of the following callbacks + * is called: ISessionCallback#onError or ISessionCallback#onAuthenticationSucceeded. + * + * The lifecycle of an interrupting operation ends when it returns. Interrupting operations do not + * have callbacks. + * + * ISession only supports execution of one non-interrupting operation at a time, regardless of + * whether it's cancellable. The framework must wait for a corresponding callback indicating the end of + * the current non-interrupting operation before a new non-interrupting operation can be started. */ @VintfStability interface ISession { @@ -84,9 +89,8 @@ interface ISession { * | 0 | 10 | <Time4> | <Random4> | * ---------------------------------------------- * - * @param cookie A unique number identifying this operation */ - void generateChallenge(in int cookie); + void generateChallenge(); /** * revokeChallenge: @@ -95,23 +99,17 @@ interface ISession { * parameters is requested, the implementation must still notify the framework using the * provided callback. * - * @param cookie A unique number identifying this operation * @param challenge Challenge that should be revoked. */ - void revokeChallenge(in int cookie, in long challenge); + void revokeChallenge(in long challenge); /** * 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. + * framework via ISessionCallback#onError with the applicable enrollment-specific error. * * 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 @@ -132,24 +130,17 @@ interface ISession { * 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 enroll(in HardwareAuthToken hat); /** * 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. + * the framework via ISessionCallback#onError with the applicable authentication-specific error. * * During authentication, the implementation may notify the framework via * ISessionCallback#onAcquired with messages that may be used to guide the user. This callback @@ -171,8 +162,6 @@ interface ISession { * 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 @@ -184,7 +173,7 @@ interface ISession { * setUserAuthenticationParameters in KeyGenParameterSpec.Builder and * KeyProtection.Builder. */ - ICancellationSignal authenticate(in int cookie, in long operationId); + ICancellationSignal authenticate(in long operationId); /** * detectInteraction: @@ -193,17 +182,12 @@ interface ISession { * if SensorProps#supportsDetectInteraction is true. If invoked on implementations that do not * support this functionality, the HAL must respond with ISession#onError(UNABLE_TO_PROCESS, 0). * - * 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 framework via ISessionCallback#onError with the applicable error. * * 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 @@ -221,10 +205,8 @@ interface ISession { * 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); + ICancellationSignal detectInteraction(); /* * enumerateEnrollments: @@ -232,32 +214,22 @@ interface ISession { * 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); + void enumerateEnrollments(); /** * 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); + void removeEnrollments(in int[] enrollmentIds); /** * getAuthenticatorId: @@ -285,10 +257,8 @@ interface ISession { * 3) MUST not change if a fingerprint is deleted. * 4) MUST be an entropy-encoded random number * - * @param cookie An identifier used to track subsystem operations related to this call path. The - * client must guarantee that it is unique per ISession. */ - void getAuthenticatorId(in int cookie); + void getAuthenticatorId(); /** * invalidateAuthenticatorId: @@ -312,10 +282,8 @@ interface ISession { * for more details). As such, the framework would coordinate invalidation across multiple * biometric HALs as necessary. * - * @param cookie An identifier used to track subsystem operations related to this call path. The - * client must guarantee that it is unique per ISession. */ - void invalidateAuthenticatorId(in int cookie); + void invalidateAuthenticatorId(); /** * resetLockout: @@ -326,8 +294,7 @@ interface ISession { * 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. + * Error::UNABLE_TO_PROCESS and return to the idling state. * * Upon successful verification, the HAL must clear the lockout counter and notify the framework * via ISessionCallback#onLockoutCleared. @@ -358,29 +325,26 @@ interface ISession { * 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 - * client must guarantee that it is unique per ISession. * @param hat HardwareAuthToken See above documentation. */ - void resetLockout(in int cookie, in HardwareAuthToken hat); + void resetLockout(in HardwareAuthToken hat); /* * Close this session and allow the HAL to release the resources associated with this session. * - * A session can only be closed when it's in SessionState::IDLING. Closing a session will - * result in a ISessionCallback#onStateChanged call with SessionState::CLOSED. + * A session can only be closed when the HAL is idling, i.e. not performing any of the + * non-interruptable operations. If the HAL is busy performing a cancellable operation, the + * operation must be explicitly cancelled with a call to ICancellationSignal#cancel before + * the session can be closed. * - * If a session is unresponsive or stuck in a state other than SessionState::CLOSED, - * IFingerprint#reset could be used as a last resort to terminate the session and recover the - * HAL from a bad state. + * After a session is closed, the HAL must notify the framework by calling + * ISessionCallback#onSessionClosed. * * All sessions must be explicitly closed. Calling IFingerprint#createSession while there is an * active session is considered an error. * - * @param cookie An identifier used to track subsystem operations related to this call path. The - * client must guarantee that it is unique per ISession. */ - void close(in int cookie); + void close(); /** * Methods for notifying the under-display fingerprint sensor about external events. @@ -394,9 +358,8 @@ interface ISession { * 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. + * HAL of display touches. This method can be invoked when the HAL is performing any one of: + * ISession#authenticate, ISession#enroll, ISession#detectInteraction. * * Note that the framework will only invoke this method if the event occurred on the display on * which this sensor is located. diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISessionCallback.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISessionCallback.aidl index cf3a271ef6..95657b3d7b 100644 --- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISessionCallback.aidl +++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISessionCallback.aidl @@ -18,17 +18,11 @@ package android.hardware.biometrics.fingerprint; import android.hardware.biometrics.fingerprint.AcquiredInfo; import android.hardware.biometrics.fingerprint.Error; -import android.hardware.biometrics.fingerprint.SessionState; import android.hardware.keymaster.HardwareAuthToken; @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); - - /** * Notifies the framework when a challenge is successfully generated. */ void onChallengeGenerated(in long challenge); @@ -39,10 +33,10 @@ interface ISessionCallback { void onChallengeRevoked(in long challenge); /** - * This method must only be used to notify the framework during the following states: - * 1) SessionState::ENROLLING - * 2) SessionState::AUTHENTICATING - * 3) SessionState::DETECTING_INTERACTION + * This method must only be used to notify the framework during the following operations: + * 1) ISession#enroll + * 2) ISession#authenticate + * 3) ISession#detectInteraction * * These messages may be used to provide user guidance multiple times if necessary per * operation. @@ -56,18 +50,18 @@ interface ISessionCallback { 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 + * This method must only be used to notify the framework during the following operations: + * 1) ISession#enroll + * 2) ISession#authenticate + * 3) ISession#detectInteraction + * 4) ISession#invalidateAuthenticatorId + * 5) ISession#resetLockout * * 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. + * has occurred. The operation is finished, and the HAL can proceed with the next operation + * or return to the idling state. * - * Note that cancellation (see common::ICancellationSignal) and preemption most be followed with + * Note that cancellation (see common::ICancellationSignal) and preemption must be followed with * an Error::CANCELED message. * * @param error See the Error enum. @@ -79,8 +73,7 @@ interface ISessionCallback { void onError(in Error error, in int vendorCode); /** - * This method must only be used to notify the framework during the following state: - * 1) SessionState::ENROLLING + * This method must only be used to notify the framework during the ISession#enroll operation. * * @param enrollmentId Unique stable identifier for the enrollment that's being added by this * ISession#enroll invocation. @@ -89,7 +82,7 @@ interface ISessionCallback { void onEnrollmentProgress(in int enrollmentId, int remaining); /** - * This method must only be used to notify the framework during SessionState::AUTHENTICATING. + * This method must only be used to notify the framework during ISession#authenticate. * * 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 @@ -104,7 +97,7 @@ interface ISessionCallback { void onAuthenticationSucceeded(in int enrollmentId, in HardwareAuthToken hat); /** - * This method must only be used to notify the framework during SessionState::AUTHENTICATING. + * This method must only be used to notify the framework during ISession#authenticate. * * 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 @@ -113,7 +106,7 @@ interface ISessionCallback { void onAuthenticationFailed(); /** - * This method must only be used to notify the framework during SessionState::AUTHENTICATING. + * This method must only be used to notify the framework during ISession#authenticate. * * 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 @@ -126,7 +119,7 @@ interface ISessionCallback { void onLockoutTimed(in long durationMillis); /** - * This method must only be used to notify the framework during SessionState::AUTHENTICATING. + * This method must only be used to notify the framework during ISession#authenticate. * * Authentication is disabled until the user unlocks with their device credential * (PIN/Pattern/Password). See ISession#resetLockout. @@ -153,7 +146,7 @@ interface ISessionCallback { /** * This method must only be used to notify the framework during - * SessionState::DETECTING_INTERACTION + * ISession#detectInteraction * * Notifies the framework that user interaction occurred. See ISession#detectInteraction. */ @@ -161,7 +154,7 @@ interface ISessionCallback { /** * This method must only be used to notify the framework during - * SessionState::ENUMERATING_ENROLLMENTS. + * ISession#enumerateEnrollments. * * Notifies the framework of the current enrollments. See ISession#enumerateEnrollments. * @@ -171,7 +164,7 @@ interface ISessionCallback { /** * This method must only be used to notify the framework during - * SessionState::REMOVING_ENROLLMENTS. + * ISession#removeEnrollments. * * Notifies the framework that the specified enrollments are removed. * @@ -181,7 +174,7 @@ interface ISessionCallback { /** * This method must only be used to notify the framework during - * SessionState::GETTING_AUTHENTICATOR_ID. + * ISession#getAuthenticatorId. * * Notifies the framework with the authenticatorId corresponding to this session's * (userId, sensorId) pair. @@ -192,7 +185,7 @@ interface ISessionCallback { /** * This method must only be used to notify the framework during - * SessionState::INVALIDATING_AUTHENTICATOR_ID. + * ISession#invalidateAuthenticatorId. * * See ISession#invalidateAuthenticatorId for more information. * diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/SessionState.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/SessionState.aidl deleted file mode 100644 index 19a6ce3682..0000000000 --- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/SessionState.aidl +++ /dev/null @@ -1,81 +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 -@Backing(type="byte") -enum SessionState { - /** - * The HAL is not processing any session requests. - */ - IDLING, - - /** - * The session has been closed by the client. - */ - CLOSED, - - /** - * The HAL is processing the ISession#generateChallenge request. - */ - GENERATING_CHALLENGE, - - /** - * The HAL is processing the ISession#revokeChallenge request. - */ - REVOKING_CHALLENGE, - - /** - * 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 fbfa52f0e7..734ff600b7 100644 --- a/biometrics/fingerprint/aidl/default/Fingerprint.cpp +++ b/biometrics/fingerprint/aidl/default/Fingerprint.cpp @@ -22,7 +22,7 @@ namespace aidl::android::hardware::biometrics::fingerprint { namespace { constexpr size_t MAX_WORKER_QUEUE_SIZE = 5; constexpr int SENSOR_ID = 1; -constexpr common::SensorStrength SENSOR_STRENGTH = common::SensorStrength::STRONG; +constexpr common::SensorStrength SENSOR_STRENGTH = common::SensorStrength::WEAK; constexpr int MAX_ENROLLMENTS_PER_USER = 5; constexpr FingerprintSensorType SENSOR_TYPE = FingerprintSensorType::REAR; constexpr bool SUPPORTS_NAVIGATION_GESTURES = true; diff --git a/biometrics/fingerprint/aidl/default/Session.cpp b/biometrics/fingerprint/aidl/default/Session.cpp index f030f138f5..ca481e7cf0 100644 --- a/biometrics/fingerprint/aidl/default/Session.cpp +++ b/biometrics/fingerprint/aidl/default/Session.cpp @@ -39,54 +39,56 @@ Session::Session(int sensorId, int userId, std::shared_ptr<ISessionCallback> cb, } void Session::scheduleStateOrCrash(SessionState state) { - CHECK(mScheduledState == SessionState::IDLING); - CHECK(mCurrentState == SessionState::IDLING); + // TODO(b/166800618): call enterIdling from the terminal callbacks and restore these checks. + // CHECK(mScheduledState == SessionState::IDLING); + // CHECK(mCurrentState == SessionState::IDLING); mScheduledState = state; } -void Session::enterStateOrCrash(int cookie, SessionState state) { +void Session::enterStateOrCrash(SessionState state) { CHECK(mScheduledState == state); mCurrentState = state; mScheduledState = SessionState::IDLING; - mCb->onStateChanged(cookie, mCurrentState); } -void Session::enterIdling(int cookie) { - mCurrentState = SessionState::IDLING; - mCb->onStateChanged(cookie, mCurrentState); +void Session::enterIdling() { + // TODO(b/166800618): call enterIdling from the terminal callbacks and rethink this conditional. + if (mCurrentState != SessionState::CLOSED) { + mCurrentState = SessionState::IDLING; + } } bool Session::isClosed() { return mCurrentState == SessionState::CLOSED; } -ndk::ScopedAStatus Session::generateChallenge(int32_t cookie) { +ndk::ScopedAStatus Session::generateChallenge() { LOG(INFO) << "generateChallenge"; scheduleStateOrCrash(SessionState::GENERATING_CHALLENGE); - mWorker->schedule(Callable::from([this, cookie] { - enterStateOrCrash(cookie, SessionState::GENERATING_CHALLENGE); + mWorker->schedule(Callable::from([this] { + enterStateOrCrash(SessionState::GENERATING_CHALLENGE); mEngine->generateChallengeImpl(mCb.get()); - enterIdling(cookie); + enterIdling(); })); return ndk::ScopedAStatus::ok(); } -ndk::ScopedAStatus Session::revokeChallenge(int32_t cookie, int64_t challenge) { +ndk::ScopedAStatus Session::revokeChallenge(int64_t challenge) { LOG(INFO) << "revokeChallenge"; scheduleStateOrCrash(SessionState::REVOKING_CHALLENGE); - mWorker->schedule(Callable::from([this, cookie, challenge] { - enterStateOrCrash(cookie, SessionState::REVOKING_CHALLENGE); + mWorker->schedule(Callable::from([this, challenge] { + enterStateOrCrash(SessionState::REVOKING_CHALLENGE); mEngine->revokeChallengeImpl(mCb.get(), challenge); - enterIdling(cookie); + enterIdling(); })); return ndk::ScopedAStatus::ok(); } -ndk::ScopedAStatus Session::enroll(int32_t cookie, const keymaster::HardwareAuthToken& hat, +ndk::ScopedAStatus Session::enroll(const keymaster::HardwareAuthToken& hat, std::shared_ptr<common::ICancellationSignal>* out) { LOG(INFO) << "enroll"; scheduleStateOrCrash(SessionState::ENROLLING); @@ -94,21 +96,21 @@ ndk::ScopedAStatus Session::enroll(int32_t cookie, const keymaster::HardwareAuth std::promise<void> cancellationPromise; auto cancFuture = cancellationPromise.get_future(); - mWorker->schedule(Callable::from([this, cookie, hat, cancFuture = std::move(cancFuture)] { - enterStateOrCrash(cookie, SessionState::ENROLLING); + mWorker->schedule(Callable::from([this, hat, cancFuture = std::move(cancFuture)] { + enterStateOrCrash(SessionState::ENROLLING); if (shouldCancel(cancFuture)) { mCb->onError(Error::CANCELED, 0 /* vendorCode */); } else { mEngine->enrollImpl(mCb.get(), hat); } - enterIdling(cookie); + enterIdling(); })); *out = SharedRefBase::make<CancellationSignal>(std::move(cancellationPromise)); return ndk::ScopedAStatus::ok(); } -ndk::ScopedAStatus Session::authenticate(int32_t cookie, int64_t operationId, +ndk::ScopedAStatus Session::authenticate(int64_t operationId, std::shared_ptr<common::ICancellationSignal>* out) { LOG(INFO) << "authenticate"; scheduleStateOrCrash(SessionState::AUTHENTICATING); @@ -116,112 +118,111 @@ ndk::ScopedAStatus Session::authenticate(int32_t cookie, int64_t operationId, std::promise<void> cancPromise; auto cancFuture = cancPromise.get_future(); - mWorker->schedule( - Callable::from([this, cookie, operationId, cancFuture = std::move(cancFuture)] { - enterStateOrCrash(cookie, SessionState::AUTHENTICATING); - if (shouldCancel(cancFuture)) { - mCb->onError(Error::CANCELED, 0 /* vendorCode */); - } else { - mEngine->authenticateImpl(mCb.get(), operationId); - } - enterIdling(cookie); - })); + mWorker->schedule(Callable::from([this, operationId, cancFuture = std::move(cancFuture)] { + enterStateOrCrash(SessionState::AUTHENTICATING); + if (shouldCancel(cancFuture)) { + mCb->onError(Error::CANCELED, 0 /* vendorCode */); + } else { + mEngine->authenticateImpl(mCb.get(), operationId); + } + enterIdling(); + })); *out = SharedRefBase::make<CancellationSignal>(std::move(cancPromise)); return ndk::ScopedAStatus::ok(); } -ndk::ScopedAStatus Session::detectInteraction(int32_t cookie, - std::shared_ptr<common::ICancellationSignal>* out) { +ndk::ScopedAStatus Session::detectInteraction(std::shared_ptr<common::ICancellationSignal>* out) { LOG(INFO) << "detectInteraction"; scheduleStateOrCrash(SessionState::DETECTING_INTERACTION); std::promise<void> cancellationPromise; auto cancFuture = cancellationPromise.get_future(); - mWorker->schedule(Callable::from([this, cookie, cancFuture = std::move(cancFuture)] { - enterStateOrCrash(cookie, SessionState::DETECTING_INTERACTION); + mWorker->schedule(Callable::from([this, cancFuture = std::move(cancFuture)] { + enterStateOrCrash(SessionState::DETECTING_INTERACTION); if (shouldCancel(cancFuture)) { mCb->onError(Error::CANCELED, 0 /* vendorCode */); } else { mEngine->detectInteractionImpl(mCb.get()); } - enterIdling(cookie); + enterIdling(); })); *out = SharedRefBase::make<CancellationSignal>(std::move(cancellationPromise)); return ndk::ScopedAStatus::ok(); } -ndk::ScopedAStatus Session::enumerateEnrollments(int32_t cookie) { +ndk::ScopedAStatus Session::enumerateEnrollments() { LOG(INFO) << "enumerateEnrollments"; scheduleStateOrCrash(SessionState::ENUMERATING_ENROLLMENTS); - mWorker->schedule(Callable::from([this, cookie] { - enterStateOrCrash(cookie, SessionState::ENUMERATING_ENROLLMENTS); + mWorker->schedule(Callable::from([this] { + enterStateOrCrash(SessionState::ENUMERATING_ENROLLMENTS); mEngine->enumerateEnrollmentsImpl(mCb.get()); - enterIdling(cookie); + enterIdling(); })); return ndk::ScopedAStatus::ok(); } -ndk::ScopedAStatus Session::removeEnrollments(int32_t cookie, - const std::vector<int32_t>& enrollmentIds) { +ndk::ScopedAStatus Session::removeEnrollments(const std::vector<int32_t>& enrollmentIds) { LOG(INFO) << "removeEnrollments"; scheduleStateOrCrash(SessionState::REMOVING_ENROLLMENTS); - mWorker->schedule(Callable::from([this, cookie, enrollmentIds] { - enterStateOrCrash(cookie, SessionState::REMOVING_ENROLLMENTS); + mWorker->schedule(Callable::from([this, enrollmentIds] { + enterStateOrCrash(SessionState::REMOVING_ENROLLMENTS); mEngine->removeEnrollmentsImpl(mCb.get(), enrollmentIds); - enterIdling(cookie); + enterIdling(); })); return ndk::ScopedAStatus::ok(); } -ndk::ScopedAStatus Session::getAuthenticatorId(int32_t cookie) { +ndk::ScopedAStatus Session::getAuthenticatorId() { LOG(INFO) << "getAuthenticatorId"; scheduleStateOrCrash(SessionState::GETTING_AUTHENTICATOR_ID); - mWorker->schedule(Callable::from([this, cookie] { - enterStateOrCrash(cookie, SessionState::GETTING_AUTHENTICATOR_ID); + mWorker->schedule(Callable::from([this] { + enterStateOrCrash(SessionState::GETTING_AUTHENTICATOR_ID); mEngine->getAuthenticatorIdImpl(mCb.get()); - enterIdling(cookie); + enterIdling(); })); return ndk::ScopedAStatus::ok(); } -ndk::ScopedAStatus Session::invalidateAuthenticatorId(int32_t cookie) { +ndk::ScopedAStatus Session::invalidateAuthenticatorId() { LOG(INFO) << "invalidateAuthenticatorId"; scheduleStateOrCrash(SessionState::INVALIDATING_AUTHENTICATOR_ID); - mWorker->schedule(Callable::from([this, cookie] { - enterStateOrCrash(cookie, SessionState::INVALIDATING_AUTHENTICATOR_ID); + mWorker->schedule(Callable::from([this] { + enterStateOrCrash(SessionState::INVALIDATING_AUTHENTICATOR_ID); mEngine->invalidateAuthenticatorIdImpl(mCb.get()); - enterIdling(cookie); + enterIdling(); })); return ndk::ScopedAStatus::ok(); } -ndk::ScopedAStatus Session::resetLockout(int32_t cookie, const keymaster::HardwareAuthToken& hat) { +ndk::ScopedAStatus Session::resetLockout(const keymaster::HardwareAuthToken& hat) { LOG(INFO) << "resetLockout"; scheduleStateOrCrash(SessionState::RESETTING_LOCKOUT); - mWorker->schedule(Callable::from([this, cookie, hat] { - enterStateOrCrash(cookie, SessionState::RESETTING_LOCKOUT); + mWorker->schedule(Callable::from([this, hat] { + enterStateOrCrash(SessionState::RESETTING_LOCKOUT); mEngine->resetLockoutImpl(mCb.get(), hat); - enterIdling(cookie); + enterIdling(); })); return ndk::ScopedAStatus::ok(); } -ndk::ScopedAStatus Session::close(int32_t /*cookie*/) { +ndk::ScopedAStatus Session::close() { LOG(INFO) << "close"; - CHECK(mCurrentState == SessionState::IDLING) << "Can't close a non-idling session. Crashing."; + // TODO(b/166800618): call enterIdling from the terminal callbacks and restore this check. + // CHECK(mCurrentState == SessionState::IDLING) << "Can't close a non-idling session. + // Crashing."; mCurrentState = SessionState::CLOSED; mCb->onSessionClosed(); return ndk::ScopedAStatus::ok(); diff --git a/biometrics/fingerprint/aidl/default/include/FakeFingerprintEngine.h b/biometrics/fingerprint/aidl/default/include/FakeFingerprintEngine.h index 42e1aa5357..6667f7a7f0 100644 --- a/biometrics/fingerprint/aidl/default/include/FakeFingerprintEngine.h +++ b/biometrics/fingerprint/aidl/default/include/FakeFingerprintEngine.h @@ -37,7 +37,7 @@ class FakeFingerprintEngine { cb->onEnrollmentProgress(0 /* enrollmentId */, 0 /* remaining */); } - void authenticateImpl(ISessionCallback* cb, int64_t /*operationId*/) { + void authenticateImpl(ISessionCallback* cb, int64_t /* operationId */) { LOG(INFO) << "authenticateImpl"; cb->onAuthenticationSucceeded(0 /* enrollmentId */, {} /* hat */); } diff --git a/biometrics/fingerprint/aidl/default/include/Session.h b/biometrics/fingerprint/aidl/default/include/Session.h index 97d5645c92..9e464229e1 100644 --- a/biometrics/fingerprint/aidl/default/include/Session.h +++ b/biometrics/fingerprint/aidl/default/include/Session.h @@ -27,37 +27,50 @@ namespace aidl::android::hardware::biometrics::fingerprint { namespace common = aidl::android::hardware::biometrics::common; namespace keymaster = aidl::android::hardware::keymaster; +enum class SessionState { + IDLING, + CLOSED, + GENERATING_CHALLENGE, + REVOKING_CHALLENGE, + ENROLLING, + AUTHENTICATING, + DETECTING_INTERACTION, + ENUMERATING_ENROLLMENTS, + REMOVING_ENROLLMENTS, + GETTING_AUTHENTICATOR_ID, + INVALIDATING_AUTHENTICATOR_ID, + RESETTING_LOCKOUT, +}; + class Session : public BnSession { public: Session(int sensorId, int userId, std::shared_ptr<ISessionCallback> cb, FakeFingerprintEngine* engine, WorkerThread* worker); - ndk::ScopedAStatus generateChallenge(int32_t cookie) override; + ndk::ScopedAStatus generateChallenge() override; - ndk::ScopedAStatus revokeChallenge(int32_t cookie, int64_t challenge) override; + ndk::ScopedAStatus revokeChallenge(int64_t challenge) override; - ndk::ScopedAStatus enroll(int32_t cookie, const keymaster::HardwareAuthToken& hat, + ndk::ScopedAStatus enroll(const keymaster::HardwareAuthToken& hat, std::shared_ptr<common::ICancellationSignal>* out) override; - ndk::ScopedAStatus authenticate(int32_t cookie, int64_t operationId, + ndk::ScopedAStatus authenticate(int64_t operationId, std::shared_ptr<common::ICancellationSignal>* out) override; ndk::ScopedAStatus detectInteraction( - int32_t cookie, std::shared_ptr<common::ICancellationSignal>* out) override; + std::shared_ptr<common::ICancellationSignal>* out) override; - ndk::ScopedAStatus enumerateEnrollments(int32_t cookie) override; + ndk::ScopedAStatus enumerateEnrollments() override; - ndk::ScopedAStatus removeEnrollments(int32_t cookie, - const std::vector<int32_t>& enrollmentIds) override; + ndk::ScopedAStatus removeEnrollments(const std::vector<int32_t>& enrollmentIds) override; - ndk::ScopedAStatus getAuthenticatorId(int32_t cookie) override; + ndk::ScopedAStatus getAuthenticatorId() override; - ndk::ScopedAStatus invalidateAuthenticatorId(int32_t cookie) override; + ndk::ScopedAStatus invalidateAuthenticatorId() override; - ndk::ScopedAStatus resetLockout(int32_t cookie, - const keymaster::HardwareAuthToken& hat) override; + ndk::ScopedAStatus resetLockout(const keymaster::HardwareAuthToken& hat) override; - ndk::ScopedAStatus close(int32_t cookie) override; + ndk::ScopedAStatus close() override; ndk::ScopedAStatus onPointerDown(int32_t pointerId, int32_t x, int32_t y, float minor, float major) override; @@ -76,11 +89,11 @@ class Session : public BnSession { // Crashes the HAL if the provided state doesn't match the previously scheduled state. // Otherwise, transitions into the provided state, clears the scheduled state, and notifies // the client about the transition by calling ISessionCallback#onStateChanged. - void enterStateOrCrash(int cookie, SessionState state); + void enterStateOrCrash(SessionState state); // Sets the current state to SessionState::IDLING and notifies the client about the transition // by calling ISessionCallback#onStateChanged. - void enterIdling(int cookie); + void enterIdling(); // The sensor and user IDs for which this session was created. int32_t mSensorId; diff --git a/biometrics/fingerprint/aidl/vts/VtsHalBiometricsFingerprintTargetTest.cpp b/biometrics/fingerprint/aidl/vts/VtsHalBiometricsFingerprintTargetTest.cpp index 885f703d5b..f1cfb17837 100644 --- a/biometrics/fingerprint/aidl/vts/VtsHalBiometricsFingerprintTargetTest.cpp +++ b/biometrics/fingerprint/aidl/vts/VtsHalBiometricsFingerprintTargetTest.cpp @@ -22,46 +22,20 @@ #include <android/binder_manager.h> #include <android/binder_process.h> +#include <chrono> #include <future> namespace aidl::android::hardware::biometrics::fingerprint { namespace { +using namespace std::literals::chrono_literals; + constexpr int kSensorId = 0; constexpr int kUserId = 0; -constexpr auto kCallbackTimeout = std::chrono::seconds(1); - -enum class MethodName { - kOnStateChanged, -}; - -struct Invocation { - MethodName methodName; - int32_t cookie; - SessionState state; -}; class SessionCallback : public BnSessionCallback { public: - explicit SessionCallback() : mIsPromiseValid(false) {} - - void setPromise(std::promise<std::vector<Invocation>>&& promise) { - mPromise = std::move(promise); - mIsPromiseValid = true; - } - - ndk::ScopedAStatus onStateChanged(int32_t cookie, SessionState state) override { - Invocation invocation = {}; - invocation.methodName = MethodName::kOnStateChanged; - invocation.cookie = cookie; - invocation.state = state; - mInvocations.push_back(invocation); - if (state == SessionState::IDLING) { - assert(mIsPromiseValid); - mPromise.set_value(mInvocations); - } - return ndk::ScopedAStatus::ok(); - } + explicit SessionCallback(std::promise<void>&& promise) : mPromise(std::move(promise)) {} ndk::ScopedAStatus onChallengeGenerated(int64_t /*challenge*/) override { return ndk::ScopedAStatus::ok(); @@ -119,12 +93,13 @@ class SessionCallback : public BnSessionCallback { return ndk::ScopedAStatus::ok(); } - ndk::ScopedAStatus onSessionClosed() override { return ndk::ScopedAStatus::ok(); } + ndk::ScopedAStatus onSessionClosed() override { + mPromise.set_value(); + return ndk::ScopedAStatus::ok(); + } private: - bool mIsPromiseValid; - std::vector<Invocation> mInvocations; - std::promise<std::vector<Invocation>> mPromise; + std::promise<void> mPromise; }; class Fingerprint : public testing::TestWithParam<std::string> { @@ -139,33 +114,26 @@ class Fingerprint : public testing::TestWithParam<std::string> { }; TEST_P(Fingerprint, AuthenticateTest) { - // Prepare the callback - std::promise<std::vector<Invocation>> promise; + auto promise = std::promise<void>{}; auto future = promise.get_future(); - std::shared_ptr<SessionCallback> cb = ndk::SharedRefBase::make<SessionCallback>(); - cb->setPromise(std::move(promise)); + // Prepare the callback. + auto cb = ndk::SharedRefBase::make<SessionCallback>(std::move(promise)); // Create a session std::shared_ptr<ISession> session; ASSERT_TRUE(mHal->createSession(kSensorId, kUserId, cb, &session).isOk()); // Call authenticate - int32_t cookie = 123; std::shared_ptr<common::ICancellationSignal> cancellationSignal; - ASSERT_TRUE(session->authenticate(cookie, 0, &cancellationSignal).isOk()); + ASSERT_TRUE(session->authenticate(-1 /* operationId */, &cancellationSignal).isOk()); // Get the results - ASSERT_TRUE(future.wait_for(kCallbackTimeout) == std::future_status::ready); - std::vector<Invocation> invocations = future.get(); + // TODO(b/166799066): test authenticate. // Close the session - ASSERT_TRUE(session->close(0).isOk()); - - ASSERT_FALSE(invocations.empty()); - EXPECT_EQ(invocations.front().methodName, MethodName::kOnStateChanged); - EXPECT_EQ(invocations.front().state, SessionState::AUTHENTICATING); - EXPECT_EQ(invocations.back().methodName, MethodName::kOnStateChanged); - EXPECT_EQ(invocations.back().state, SessionState::IDLING); + ASSERT_TRUE(session->close().isOk()); + auto status = future.wait_for(1s); + ASSERT_EQ(status, std::future_status::ready); } GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(Fingerprint); |