From 457e9d8530546ad0d74ce98412bb7b23a230cfeb Mon Sep 17 00:00:00 2001 From: Ilya Matyukhin Date: Thu, 8 Oct 2020 12:52:04 -0700 Subject: [PATCH 1/3] Define IFace Bug: 168730443 Test: m android.hardware.biometrics.face-update-api Change-Id: I6bd1d1240ef91680d8b96cb84849431c25265358 --- biometrics/face/aidl/Android.bp | 22 ++ .../biometrics/face/AcquiredInfo.aidl | 44 +++ .../hardware/biometrics/face/Error.aidl | 28 ++ .../biometrics/face/FaceSensorType.aidl | 23 ++ .../hardware/biometrics/face/IFace.aidl | 23 ++ .../hardware/biometrics/face/ISession.aidl | 31 ++ .../biometrics/face/ISessionCallback.aidl | 37 ++ .../hardware/biometrics/face/SensorProps.aidl | 24 ++ .../biometrics/face/SessionState.aidl | 33 ++ .../biometrics/face/AcquiredInfo.aidl | 219 +++++++++++ .../hardware/biometrics/face/Error.aidl | 92 +++++ .../biometrics/face/FaceSensorType.aidl | 24 ++ .../hardware/biometrics/face/IFace.aidl | 50 +++ .../hardware/biometrics/face/ISession.aidl | 369 ++++++++++++++++++ .../biometrics/face/ISessionCallback.aidl | 200 ++++++++++ .../hardware/biometrics/face/SensorProps.aidl | 43 ++ .../biometrics/face/SessionState.aidl | 82 ++++ .../compatibility_matrix.current.xml | 7 + 18 files changed, 1351 insertions(+) create mode 100644 biometrics/face/aidl/Android.bp create mode 100644 biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/AcquiredInfo.aidl create mode 100644 biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/Error.aidl create mode 100644 biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/FaceSensorType.aidl create mode 100644 biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/IFace.aidl create mode 100644 biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/ISession.aidl create mode 100644 biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/ISessionCallback.aidl create mode 100644 biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/SensorProps.aidl create mode 100644 biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/SessionState.aidl create mode 100644 biometrics/face/aidl/android/hardware/biometrics/face/AcquiredInfo.aidl create mode 100644 biometrics/face/aidl/android/hardware/biometrics/face/Error.aidl create mode 100644 biometrics/face/aidl/android/hardware/biometrics/face/FaceSensorType.aidl create mode 100644 biometrics/face/aidl/android/hardware/biometrics/face/IFace.aidl create mode 100644 biometrics/face/aidl/android/hardware/biometrics/face/ISession.aidl create mode 100644 biometrics/face/aidl/android/hardware/biometrics/face/ISessionCallback.aidl create mode 100644 biometrics/face/aidl/android/hardware/biometrics/face/SensorProps.aidl create mode 100644 biometrics/face/aidl/android/hardware/biometrics/face/SessionState.aidl diff --git a/biometrics/face/aidl/Android.bp b/biometrics/face/aidl/Android.bp new file mode 100644 index 0000000000..4f8b71ddbb --- /dev/null +++ b/biometrics/face/aidl/Android.bp @@ -0,0 +1,22 @@ +aidl_interface { + name: "android.hardware.biometrics.face", + vendor_available: true, + srcs: [ + "android/hardware/biometrics/face/**/*.aidl", + ], + imports: [ + "android.hardware.biometrics.common", + "android.hardware.common", + "android.hardware.keymaster", + ], + stability: "vintf", + backend: { + java: { + enabled: false, + platform_apis: false, + }, + cpp: { + enabled: false, + }, + }, +} diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/AcquiredInfo.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/AcquiredInfo.aidl new file mode 100644 index 0000000000..011b7112e5 --- /dev/null +++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/AcquiredInfo.aidl @@ -0,0 +1,44 @@ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL interface (or parcelable). Do not try to +// edit this file. It looks like you are doing that because you have modified +// an AIDL interface in a backward-incompatible way, e.g., deleting a function +// from an interface or a field from a parcelable and it broke the build. That +// breakage is intended. +// +// You must not make a backward incompatible changes to the AIDL files built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.biometrics.face; +@Backing(type="byte") @VintfStability +enum AcquiredInfo { + GOOD = 0, + INSUFFICIENT = 1, + TOO_BRIGHT = 2, + TOO_DARK = 3, + TOO_CLOSE = 4, + TOO_FAR = 5, + FACE_TOO_HIGH = 6, + FACE_TOO_LOW = 7, + FACE_TOO_RIGHT = 8, + FACE_TOO_LEFT = 9, + POOR_GAZE = 10, + NOT_DETECTED = 11, + TOO_MUCH_MOTION = 12, + RECALIBRATE = 13, + TOO_DIFFERENT = 14, + TOO_SIMILAR = 15, + PAN_TOO_EXTREME = 16, + TILT_TOO_EXTREME = 17, + ROLL_TOO_EXTREME = 18, + FACE_OBSCURED = 19, + START = 20, + SENSOR_DIRTY = 21, + VENDOR = 22, +} diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/Error.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/Error.aidl new file mode 100644 index 0000000000..15fcbf959a --- /dev/null +++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/Error.aidl @@ -0,0 +1,28 @@ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL interface (or parcelable). Do not try to +// edit this file. It looks like you are doing that because you have modified +// an AIDL interface in a backward-incompatible way, e.g., deleting a function +// from an interface or a field from a parcelable and it broke the build. That +// breakage is intended. +// +// You must not make a backward incompatible changes to the AIDL files built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.biometrics.face; +@Backing(type="byte") @VintfStability +enum Error { + HW_UNAVAILABLE = 1, + UNABLE_TO_PROCESS = 2, + TIMEOUT = 3, + NO_SPACE = 4, + CANCELED = 5, + UNABLE_TO_REMOVE = 6, + VENDOR = 8, +} diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/FaceSensorType.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/FaceSensorType.aidl new file mode 100644 index 0000000000..943129ed8a --- /dev/null +++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/FaceSensorType.aidl @@ -0,0 +1,23 @@ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL interface (or parcelable). Do not try to +// edit this file. It looks like you are doing that because you have modified +// an AIDL interface in a backward-incompatible way, e.g., deleting a function +// from an interface or a field from a parcelable and it broke the build. That +// breakage is intended. +// +// You must not make a backward incompatible changes to the AIDL files built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.biometrics.face; +@Backing(type="byte") @VintfStability +enum FaceSensorType { + RGB = 0, + IR = 1, +} diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/IFace.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/IFace.aidl new file mode 100644 index 0000000000..518fb147f4 --- /dev/null +++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/IFace.aidl @@ -0,0 +1,23 @@ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL interface (or parcelable). Do not try to +// edit this file. It looks like you are doing that because you have modified +// an AIDL interface in a backward-incompatible way, e.g., deleting a function +// from an interface or a field from a parcelable and it broke the build. That +// breakage is intended. +// +// You must not make a backward incompatible changes to the AIDL files built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.biometrics.face; +@VintfStability +interface IFace { + android.hardware.biometrics.face.SensorProps[] getSensorProps(); + android.hardware.biometrics.face.ISession createSession(in int sensorId, in int userId, in android.hardware.biometrics.face.ISessionCallback cb); +} 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 new file mode 100644 index 0000000000..c9b443d67c --- /dev/null +++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/ISession.aidl @@ -0,0 +1,31 @@ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL interface (or parcelable). Do not try to +// edit this file. It looks like you are doing that because you have modified +// an AIDL interface in a backward-incompatible way, e.g., deleting a function +// from an interface or a field from a parcelable and it broke the build. That +// breakage is intended. +// +// You must not make a backward incompatible changes to the AIDL files built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.biometrics.face; +@VintfStability +interface ISession { + void generateChallenge(in int cookie, in int sensorId, in int userId, in int timeoutSec); + void revokeChallenge(in int cookie, in int sensorId, in int userId, in long challenge); + android.hardware.biometrics.common.ICancellationSignal enroll(in int cookie, in android.hardware.keymaster.HardwareAuthToken hat, 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 getAuthenticatorId(in int cookie); + void invalidateAuthenticatorId(in int cookie); + void resetLockout(in int cookie, in android.hardware.keymaster.HardwareAuthToken hat); +} 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 new file mode 100644 index 0000000000..477ba5a27f --- /dev/null +++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/ISessionCallback.aidl @@ -0,0 +1,37 @@ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL interface (or parcelable). Do not try to +// edit this file. It looks like you are doing that because you have modified +// an AIDL interface in a backward-incompatible way, e.g., deleting a function +// from an interface or a field from a parcelable and it broke the build. That +// breakage is intended. +// +// You must not make a backward incompatible changes to the AIDL files built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.biometrics.face; +@VintfStability +interface ISessionCallback { + void onStateChanged(in int cookie, in android.hardware.biometrics.face.SessionState state); + void onChallengeGenerated(in int sensorId, in int userId, in long challenge); + void onChallengeRevoked(in int sensorId, in int userId, in long challenge); + void onAcquired(in android.hardware.biometrics.face.AcquiredInfo info, in int vendorCode); + void onError(in android.hardware.biometrics.face.Error error, in int vendorCode); + void onEnrollmentProgress(in int enrollmentId, int remaining); + void onAuthenticationSucceeded(in int enrollmentId, in android.hardware.keymaster.HardwareAuthToken hat); + void onAuthenticationFailed(); + void onLockoutTimed(in long durationMillis); + void onLockoutPermanent(); + void onLockoutCleared(); + void onInteractionDetected(); + void onEnrollmentsEnumerated(in int[] enrollmentIds); + void onEnrollmentsRemoved(in int[] enrollmentIds); + void onAuthenticatorIdRetrieved(in long authenticatorId); + void onAuthenticatorIdInvalidated(); +} diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/SensorProps.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/SensorProps.aidl new file mode 100644 index 0000000000..9f977f54af --- /dev/null +++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/SensorProps.aidl @@ -0,0 +1,24 @@ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL interface (or parcelable). Do not try to +// edit this file. It looks like you are doing that because you have modified +// an AIDL interface in a backward-incompatible way, e.g., deleting a function +// from an interface or a field from a parcelable and it broke the build. That +// breakage is intended. +// +// You must not make a backward incompatible changes to the AIDL files built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.biometrics.face; +@VintfStability +parcelable SensorProps { + android.hardware.biometrics.common.CommonProps commonProps; + android.hardware.biometrics.face.FaceSensorType sensorType; + boolean halControlsPreview; +} 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 new file mode 100644 index 0000000000..8e5139b38b --- /dev/null +++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/SessionState.aidl @@ -0,0 +1,33 @@ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL interface (or parcelable). Do not try to +// edit this file. It looks like you are doing that because you have modified +// an AIDL interface in a backward-incompatible way, e.g., deleting a function +// from an interface or a field from a parcelable and it broke the build. That +// breakage is intended. +// +// You must not make a backward incompatible changes to the AIDL files built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.biometrics.face; +@Backing(type="byte") @VintfStability +enum SessionState { + IDLING = 0, + TERMINATED = 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/face/aidl/android/hardware/biometrics/face/AcquiredInfo.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/AcquiredInfo.aidl new file mode 100644 index 0000000000..fffb418c03 --- /dev/null +++ b/biometrics/face/aidl/android/hardware/biometrics/face/AcquiredInfo.aidl @@ -0,0 +1,219 @@ +/* + * 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.face; + +@VintfStability +@Backing(type="byte") +enum AcquiredInfo { + + /** + * The acquired face data was good, no further user interaction is necessary. + */ + GOOD = 0, + + /** + * The acquired face data was too noisy or did not have sufficient detail. + * This is a catch-all for all acquisition errors not captured by the other + * constants. + */ + INSUFFICIENT = 1, + + /** + * Because there was too much ambient light, the captured face data was too + * bright. It's reasonable to return this after multiple + * AcquiredInfo.INSUFFICIENT. + * + * The user is expected to take action to retry the operation in better + * lighting conditions when this is returned. + */ + TOO_BRIGHT = 2, + + /** + * Because there was not enough illumination, the captured face data was too + * dark. It's reasonable to return this after multiple + * AcquiredInfo.INSUFFICIENT. + * + * The user is expected to take action to retry the operation in better + * lighting conditions when this is returned. + */ + TOO_DARK = 3, + + /** + * The detected face is too close to the sensor, and the image cannot be + * processed. + * + * The user is expected to be informed to move further from the sensor when + * this is returned. + */ + TOO_CLOSE = 4, + + /** + * The detected face is too small, as the user might be too far away from + * the sensor. + * + * The user is expected to be informed to move closer to the sensor when + * this is returned. + */ + TOO_FAR = 5, + + /** + * Only the upper part of the face was detected. The sensor's field of view + * is too high. + * + * The user should be informed to move up with respect to the sensor when + * this is returned. + */ + FACE_TOO_HIGH = 6, + + /** + * Only the lower part of the face was detected. The sensor's field of view + * is too low. + * + * The user should be informed to move down with respect to the sensor when + * this is returned. + */ + FACE_TOO_LOW = 7, + + /** + * Only the right part of the face was detected. The sensor's field of view + * is too far right. + * + * The user should be informed to move to the right with respect to the + * sensor when this is returned. + */ + FACE_TOO_RIGHT = 8, + + /** + * Only the left part of the face was detected. The sensor's field of view + * is too far left. + * + * The user should be informed to move to the left with respect to the + * sensor when this is returned. + */ + FACE_TOO_LEFT = 9, + + /** + * The user's eyes have strayed away from the sensor. If this message is + * sent, the user should be informed to look at the device. If the user + * can't be found in the frame, one of the other acquisition messages + * must be sent, e.g. NOT_DETECTED. + */ + POOR_GAZE = 10, + + /** + * No face was detected within the sensor's field of view. + * + * The user should be informed to point the sensor to a face when this is + * returned. + */ + NOT_DETECTED = 11, + + /** + * Too much motion was detected. + * + * The user should be informed to keep their face steady relative to the + * sensor. + */ + TOO_MUCH_MOTION = 12, + + /** + * The sensor needs to be re-calibrated. This is an unexpected condition, + * and must only be sent if a serious, uncorrectable, and unrecoverable + * calibration issue is detected which requires user intervention, e.g. + * re-enrolling. The expected response to this message is to direct the + * user to re-enroll. + */ + RECALIBRATE = 13, + + /** + * The face is too different from a previous acquisition. This condition + * only applies to enrollment. This can happen if the user passes the + * device to someone else in the middle of enrollment. + */ + TOO_DIFFERENT = 14, + + /** + * The face is too similar to a previous acquisition. This condition only + * applies to enrollment. The user should change their pose. + */ + TOO_SIMILAR = 15, + + /** + * The magnitude of the pan angle of the user’s face with respect to the sensor’s + * capture plane is too high. + * + * The pan angle is defined as the angle swept out by the user’s face turning + * their neck left and right. The pan angle would be zero if the user faced the + * camera directly. + * + * The user should be informed to look more directly at the camera. + */ + PAN_TOO_EXTREME = 16, + + /** + * The magnitude of the tilt angle of the user’s face with respect to the sensor’s + * capture plane is too high. + * + * The tilt angle is defined as the angle swept out by the user’s face looking up + * and down. The tilt angle would be zero if the user faced the camera directly. + * + * The user should be informed to look more directly at the camera. + */ + TILT_TOO_EXTREME = 17, + + /** + * The magnitude of the roll angle of the user’s face with respect to the sensor’s + * capture plane is too high. + * + * The roll angle is defined as the angle swept out by the user’s face tilting their head + * towards their shoulders to the left and right. The roll angle would be zero if the user's + * head is vertically aligned with the camera. + * + * The user should be informed to look more directly at the camera. + */ + ROLL_TOO_EXTREME = 18, + + /** + * The user’s face has been obscured by some object. + * + * The user should be informed to remove any objects from the line of sight from + * the sensor to the user’s face. + */ + FACE_OBSCURED = 19, + + /** + * This message represents the earliest message sent at the beginning of the authentication + * pipeline. It is expected to be used to measure latency. For example, in a camera-based + * authentication system it's expected to be sent prior to camera initialization. Note this + * should be sent whenever authentication is restarted (see IBiometricsFace#userActivity). + * The framework will measure latency based on the time between the last START message and the + * onAuthenticated callback. + */ + START = 20, + + /** + * The sensor is dirty. The user should be informed to clean the sensor. + */ + SENSOR_DIRTY = 21, + + /** + * Vendor-specific acquisition message. See ISessionCallback#onAcquired vendorCode + * documentation. + */ + VENDOR = 22 +} + diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/Error.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/Error.aidl new file mode 100644 index 0000000000..1d02456f6d --- /dev/null +++ b/biometrics/face/aidl/android/hardware/biometrics/face/Error.aidl @@ -0,0 +1,92 @@ +/* + * 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.face; + +@VintfStability +@Backing(type="byte") +enum Error { + /** + * Reserved for testing and to keep subsequent numbering consistent with + * older interfaces. + * + * NO_ERROR = 0, + */ + + /** + * A hardware error has occurred that cannot be resolved. Try again later. + */ + HW_UNAVAILABLE = 1, + + /** + * The current enroll or authenticate operation could not be completed, + * e.g. the sensor was unable to process the current image or the HAT was + * invalid. + */ + UNABLE_TO_PROCESS = 2, + + /** + * The current operation took too long to complete. This is intended to + * prevent programs from blocking the face HAL indefinitely. The timeout is + * framework and sensor-specific, but is generally on the order of 30 + * seconds. + * + * The timeout is a device-specific time meant to optimize power. For + * example after 30 seconds of searching for a face it can be use to + * indicate that the implementation is no longer looking and the framework + * should restart the operation on the next user interaction. + */ + TIMEOUT = 3, + + /** + * The current operation could not be completed because there is not enough + * storage space remaining to do so. + */ + NO_SPACE = 4, + + /** + * The current operation has been cancelled. This may happen if a new + * request (authenticate, remove, enumerate, enroll) is initiated while + * an on-going operation is in progress, or if cancel() was called. + */ + CANCELED = 5, + + /** + * The current remove operation could not be completed; the face template + * provided could not be removed. + */ + UNABLE_TO_REMOVE = 6, + + /** + * Reserved to maintain backwards compatibility. See + * ISessionCallback#onLockoutTimed instead. + * + * LOCKOUT = 7, + */ + + /** + * Used to enable a vendor-specific error message. + */ + VENDOR = 8, + + /** + * Reserved to maintain backwards compatibility. See + * ISessionCallback#onLockoutPermanent instead. + * + * LOCKOUT_PERMANENT = 9 + */ +} + diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/FaceSensorType.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/FaceSensorType.aidl new file mode 100644 index 0000000000..766f732a56 --- /dev/null +++ b/biometrics/face/aidl/android/hardware/biometrics/face/FaceSensorType.aidl @@ -0,0 +1,24 @@ +/* + * 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.face; + +@VintfStability +@Backing(type="byte") +enum FaceSensorType { + RGB, + IR +} diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/IFace.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/IFace.aidl new file mode 100644 index 0000000000..e9a66e2ea3 --- /dev/null +++ b/biometrics/face/aidl/android/hardware/biometrics/face/IFace.aidl @@ -0,0 +1,50 @@ +/* + * 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.face; + +import android.hardware.biometrics.face.ISession; +import android.hardware.biometrics.face.ISessionCallback; +import android.hardware.biometrics.face.SensorProps; + +@VintfStability +interface IFace { + /** + * getSensorProps: + * + * @return A list of properties for all face sensors available to the HAL. + */ + SensorProps[] getSensorProps(); + + /** + * createSession: + * + * Creates a session that can be used by the framework to perform operations such as + * enroll, authenticate, etc. for the given sensorId and userId. + * + * Implementations must store user-specific state or metadata in /data/vendor_de//facedata + * as specified by the SELinux policy. The directory /data/vendor_de is managed by vold (see + * vold_prepare_subdirs.cpp). Implementations may store additional user-specific data, such as + * embeddings or templates in StrongBox. + * + * @param sensorId The sensorId with which this session is being created. + * @param userId The userId with which this session is being created. + * @param cb A callback to notify the framework about the session's results and events. + * @return A new session. + */ + ISession createSession(in int sensorId, in int userId, in ISessionCallback cb); + +} diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/ISession.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/ISession.aidl new file mode 100644 index 0000000000..5145b1e94d --- /dev/null +++ b/biometrics/face/aidl/android/hardware/biometrics/face/ISession.aidl @@ -0,0 +1,369 @@ +/* + * 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.face; + +import android.hardware.biometrics.common.ICancellationSignal; +import android.hardware.keymaster.HardwareAuthToken; +import android.hardware.common.NativeHandle; + +/** + * 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. + */ +@VintfStability +interface ISession { + /** + * generateChallenge: + * + * Begins a secure transaction request. Note that the challenge by itself is not useful. It only + * becomes useful when wrapped in a verifiable message such as a HardwareAuthToken. + * + * Canonical example: + * 1) User requests an operation, such as face enrollment. + * 2) Face enrollment cannot happen until the user confirms their lockscreen credential + * (PIN/Pattern/Password). + * 3) However, the biometric subsystem does not want just "any" proof of credential + * confirmation. It needs proof that the user explicitly authenticated credential in order + * to allow addition of biometric enrollments. + * To secure this path, the following path is taken: + * 1) Upon user requesting face enroll, the framework requests + * IFace#generateChallenge + * 2) Framework sends the challenge to the credential subsystem, and upon credential + * confirmation, a HAT is created, containing the challenge in the "challenge" field. + * 3) Framework sends the HAT to the HAL, e.g. ISession#enroll. + * 4) Implementation verifies the authenticity and integrity of the HAT. + * 5) Implementation now has confidence that the user entered their credential to allow + * biometric enrollment. + * + * Note that the interface allows multiple in-flight challenges. For example, invoking + * generateChallenge(0, 0, timeoutSec) twice does not invalidate the first challenge. The + * challenge is invalidated only when: + * 1) The provided timeout expires, or + * 2) IFace#revokeChallenge is invoked + * + * For example, the following is a possible table of valid challenges: + * ---------------------------------------------- + * | SensorId | UserId | ValidUntil | Challenge | + * |----------|--------|------------|-----------| + * | 0 | 0 | | | + * | 0 | 0 | | | + * | 1 | 0 | | | + * | 0 | 10 | | | + * ---------------------------------------------- + * + * @param cookie A unique number identifying this operation + * @param sensorId Sensor to associate the challenge with + * @param userId User to associate the challenge with + * @param timeoutSec Duration for which the challenge is valid for + */ + void generateChallenge(in int cookie, in int sensorId, in int userId, in int timeoutSec); + + /** + * revokeChallenge: + * + * Revokes a challenge that was previously generated. Note that if an invalid combination of + * parameters is requested, the implementation must still notify the framework using the + * provided callback. + * + * @param cookie A unique number identifying this operation + * @param sensorId Sensor that the revocation should apply to. + * @param userId User that the revocation should apply to. + * @param challenge Challenge that should be revoked. + */ + void revokeChallenge(in int cookie, in int sensorId, in int userId, in long challenge); + + /** + * enroll: + * + * 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. + * + * 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 IFace#generateChallenge. If any of + * the above checks fail, the framework must be notified via ISessionCallback#onError and the + * HAL must notify the framework when it returns to the idle state. See + * Error::UNABLE_TO_PROCESS. + * + * During enrollment, the implementation may notify the framework via + * ISessionCallback#onAcquired with messages that may be used to guide the user. This callback + * can be invoked multiple times if necessary. Similarly, the framework may be notified of + * enrollment progress changes via ISessionCallback#onEnrollmentProgress. Once the framework is + * notified that there are 0 "remaining" steps, the framework may cache the "enrollmentId". See + * ISessionCallback#onEnrollmentProgress for more info. The HAL must notify the framework once + * it returns to the idle state. + * + * When a finger is successfully added and before the framework is notified of remaining=0, the + * implementation MUST update and associate this (sensorId, userId) pair with a new new + * entropy-encoded random identifier. See ISession#getAuthenticatorId for more information. + * + * @param cookie An identifier used to track subsystem operations related to this call path. The + * client must guarantee that it is unique per ISession. + * @param previewSurface A surface provided by the framework if SensorProps#halControlsPreview is + * set to true. The HAL must send the preview frames to previewSurface if + * it's not null. + * @param hat See above documentation. + * @return ICancellationSignal An object that can be used by the framework to cancel this + * operation. + */ + ICancellationSignal enroll(in int cookie, in HardwareAuthToken hat, in NativeHandle previewSurface); + + /** + * authenticate: + * + * 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. + * + * During authentication, the implementation may notify the framework via + * ISessionCallback#onAcquired with messages that may be used to guide the user. This callback + * can be invoked multiple times if necessary. + * + * The HAL must notify the framework of accepts/rejects via ISessionCallback#onAuthentication*. + * + * The authentication lifecycle ends when either + * 1) A face is accepted, and ISessionCallback#onAuthenticationSucceeded is invoked, or + * 2) Any non-recoverable error occurs (such as lockout). See the full list of + * authentication-specific errors in the Error enum. + * + * Note that upon successful authentication, the lockout counter for this (sensorId, userId) + * pair must be cleared. + * + * Note that upon successful authentication, ONLY sensors configured as SensorStrength::STRONG + * are allowed to create and send a HardwareAuthToken to the framework. See the Android CDD for + * more details. For SensorStrength::STRONG sensors, the HardwareAuthToken's "challenge" field + * must be set with the operationId passed in during #authenticate. If the sensor is NOT + * SensorStrength::STRONG, the HardwareAuthToken MUST be null. + * + * @param cookie An identifier used to track subsystem operations related to this call path. The + * client must guarantee that it is unique per ISession. + * @param operationId For sensors configured as SensorStrength::STRONG, this must be used ONLY + * upon successful authentication and wrapped in the HardwareAuthToken's + * "challenge" field and sent to the framework via + * ISessionCallback#onAuthenticated. The operationId is an opaque identifier + * created from a separate secure subsystem such as, but not limited to + * KeyStore/KeyMaster. The HardwareAuthToken can then be used as an + * attestation for the provided operation. For example, this is used + * to unlock biometric-bound auth-per-use keys (see + * setUserAuthenticationParameters in KeyGenParameterSpec.Builder and + * KeyProtection.Builder. + * @return ICancellationSignal An object that can be used by the framework to cancel this + * operation. + */ + ICancellationSignal authenticate(in int cookie, in long operationId); + + /** + * detectInteraction: + * + * A request to start looking for faces without performing matching. + * + * Once the HAL is able to start processing this request, it must notify the framework via + * ISessionCallback#onStateChanged with SessionState::DETECTING_INTERACTION. + * + * The framework will use this method in cases where determing user presence is required, but + * identifying/authentication is not. For example, when the device is encrypted (first boot) or + * in lockdown mode. + * + * At any point during detectInteraction, if a non-recoverable error occurs, the HAL must notify + * the framework via ISessionCallback#onError with the applicable error, and then send + * ISessionCallback#onStateChanged(cookie, SessionState::IDLING) if no subsequent operation is + * in the queue. + * + * The implementation must only check for a face-like image was detected (e.g. to + * minimize interactions due to non-face objects), and the lockout counter must not + * be modified. + * + * Upon detecting any face, the implementation must invoke + * ISessionCallback#onInteractionDetected. + * + * The lifecycle of this operation ends when either + * 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); + + /* + * enumerateEnrollments: + * + * A request to enumerate (list) the enrollments for this (sensorId, userId) pair. The + * framework typically uses this to ensure that its cache is in sync with the HAL. + * + * Once the HAL is able to start processing this request, it must notify the framework via + * ISessionCallback#onStateChanged with SessionState::ENUMERATING_ENROLLMENTS. + * + * The implementation must then notify the framework with a list of enrollments applicable + * for the current session via ISessionCallback#onEnrollmentsEnumerated. + * + * @param cookie An identifier used to track subsystem operations related to this call path. + * The framework will guarantee that it is unique per ISession. + */ + void enumerateEnrollments(in int cookie); + + /** + * removeEnrollments: + * + * A request to remove the enrollments for this (sensorId, userId) pair. + * + * Once the HAL is able to start processing this request, it must notify the framework via + * ISessionCallback#onStateChanged with SessionState::REMOVING_ENROLLMENTS. + * + * After removing the enrollmentIds from everywhere necessary (filesystem, secure subsystems, + * etc), the implementation must notify the framework via ISessionCallback#onEnrollmentsRemoved. + * + * @param cookie An identifier used to track subsystem operations related to this call path. + * The framework will guarantee that it is unique per ISession. + */ + void removeEnrollments(in int cookie, in int[] enrollmentIds); + + /** + * getAuthenticatorId: + * + * MUST return 0 via ISessionCallback#onAuthenticatorIdRetrieved for sensors that are configured + * as SensorStrength::WEAK or SensorStrength::CONVENIENCE. + * + * The following only applies to sensors that are configured as SensorStrength::STRONG. + * + * The authenticatorId is a (sensorId, user)-specific identifier which can be used during key + * generation and key import to to associate a key (in KeyStore / KeyMaster) with the current + * set of enrolled faces. For example, the following public Android APIs allow for keys + * to be invalidated when the user adds a new enrollment after the key was created: + * KeyGenParameterSpec.Builder.setInvalidatedByBiometricEnrollment and + * KeyProtection.Builder.setInvalidatedByBiometricEnrollment. + * + * In addition, upon successful face authentication, the signed HAT that is returned to + * the framework via ISessionCallback#onAuthenticated must contain this identifier in the + * authenticatorId field. + * + * Returns an entropy-encoded random identifier associated with the current set of enrollments + * via ISessionCallback#onAuthenticatorIdRetrieved. The authenticatorId + * 1) MUST change whenever a new face is enrolled + * 2) MUST return 0 if no faces are enrolled + * 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); + + /** + * invalidateAuthenticatorId: + * + * This method only applies to sensors that are configured as SensorStrength::STRONG. If invoked + * by the framework for sensor of other strengths, the HAL should immediately invoke + * ISessionCallback#onAuthenticatorIdInvalidated. + * + * The following only applies to sensors that are configured as SensorStrength::STRONG. + * + * When invoked by the framework, the implementation must perform the following sequence of + * events: + * 1) Verify the authenticity and integrity of the provided HAT. If this check fails, the HAL + * must invoke ISessionCallback#onError with Error::UNABLE_TO_PROCESS and return to + * SessionState::IDLING if no subsequent work is in the queue. + * 2) Verify that the timestamp provided within the HAT is relatively recent (e.g. on the + * order of minutes, not hours). If this check fails, the HAL must invoke + * ISessionCallback#onError with Error::UNABLE_TO_PROCESS and return to + * SessionState::IDLING if no subsequent work is in the queue. + * 3) Update the authenticatorId with a new entropy-encoded random number + * 4) Persist the new authenticatorId to non-ephemeral storage + * 5) Notify the framework that the above is completed, via + * ISessionCallback#onAuthenticatorInvalidated + * + * A practical use case of invalidation would be when the user adds a new enrollment to a sensor + * managed by a different HAL instance. The public android.security.keystore APIs bind keys to + * "all biometrics" rather than "face-only" or "face-only" (see #getAuthenticatorId + * 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); + + /** + * resetLockout: + * + * Requests the implementation to clear the lockout counter. Upon receiving this request, the + * implementation must perform the following: + * 1) Verify the authenticity and integrity of the provided HAT + * 2) Verify that the timestamp provided within the HAT is relatively recent (e.g. on the + * order of minutes, not hours). + * If either of the checks fail, the HAL must invoke ISessionCallback#onError with + * Error::UNABLE_TO_PROCESS and return to SessionState::IDLING if no subsequent work is in the + * queue. + * + * Upon successful verification, the HAL must clear the lockout counter and notify the framework + * via ISessionCallback#onLockoutCleared. + * + * Note that lockout is user AND sensor specific. In other words, there is a separate lockout + * state for each (user, sensor) pair. For example, the following is a valid state on a + * multi-sensor device: + * ------------------------------------------------------------------ + * | SensorId | UserId | FailedAttempts | LockedOut | LockedUntil | + * |----------|--------|----------------|-----------|---------------| + * | 0 | 0 | 1 | false | x | + * | 1 | 0 | 5 | true | | + * | 0 | 10 | 0 | false | x | + * | 1 | 10 | 0 | false | x | + * ------------------------------------------------------------------ + * + * Lockout may be cleared in the following ways: + * 1) ISession#resetLockout + * 2) After a period of time, according to a rate-limiter. + * + * Note that the "FailedAttempts" counter must be cleared upon successful face + * authentication. For example, if SensorId=0 UserId=0 FailedAttempts=1, and a successful + * face authentication occurs, the counter for that (SensorId, UserId) pair must be reset + * to 0. + * + * In addition, lockout states MUST persist after device reboots, HAL crashes, etc. + * + * See the Android CDD section 7.3.10 for the full set of lockout and rate-limiting + * requirements. + * + * @param cookie An identifier used to track subsystem operations related to this call path. The + * client must guarantee that it is unique per ISession. + * @param hat HardwareAuthToken See above documentation. + */ + void resetLockout(in int cookie, in HardwareAuthToken hat); +} + diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/ISessionCallback.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/ISessionCallback.aidl new file mode 100644 index 0000000000..2608d5fc7b --- /dev/null +++ b/biometrics/face/aidl/android/hardware/biometrics/face/ISessionCallback.aidl @@ -0,0 +1,200 @@ +/* + * 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.face; + +import android.hardware.biometrics.face.AcquiredInfo; +import android.hardware.biometrics.face.Error; +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 int sensorId, in int userId, in long challenge); + + /** + * Notifies the framework when a challenge has been revoked. + */ + void onChallengeRevoked(in int sensorId, in int userId, 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 + * + * These messages may be used to provide user guidance multiple times if necessary per + * operation. + * + * @param info See the AcquiredInfo enum. + * @param vendorCode Only valid if info == AcquiredInfo::VENDOR. The vendorCode must be used to + * index into the configuration + * com.android.internal.R.array.face_acquired_vendor that's installed + * on the vendor partition. + */ + void onAcquired(in AcquiredInfo info, in int vendorCode); + + /** + * This method must only be used to notify the framework during the following states: + * 1) SessionState::ENROLLING + * 2) SessionState::AUTHENTICATING + * 3) SessionState::DETECTING_INTERACTION + * 4) SessionState::INVALIDATING_AUTHENTICATOR_ID + * 5) SessionState::RESETTING_LOCKOUT + * + * These messages may be used to notify the framework or user that a non-recoverable error + * has occurred. The operation is finished, and the HAL must proceed with the next operation + * or return to SessionState::IDLING if the queue is empty. + * + * Note that cancellation (see common::ICancellationSignal) and preemption most be followed with + * an Error::CANCELED message. + * + * @param error See the Error enum. + * @param vendorCode Only valid if error == Error::VENDOR. The vendorCode must be used to index + * into the configuration + * com.android.internal.R.face_error_vendor that's installed on the + * vendor partition. + */ + 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 + * + * @param enrollmentId Unique stable identifier for the enrollment that's being added by this + * ISession#enroll invocation. + * @param remaining Remaining number of steps before enrollment is complete. + */ + void onEnrollmentProgress(in int enrollmentId, int remaining); + + /** + * This method must only be used to notify the framework during SessionState::AUTHENTICATING. + * + * Used to notify the framework upon successful authentication. Note that the authentication + * lifecycle ends when either 1) a face is accepted, or 2) an error occurred. The + * authentication lifecycle does NOT end when a face is rejected. + * + * @param enrollmentId Face that was accepted. + * @param hat If the sensor is configured as SensorStrength::STRONG, a non-null attestation that + * a face was accepted. The HardwareAuthToken's "challenge" field must be set + * with the operationId passed in during ISession#authenticate. If the sensor is NOT + * SensorStrength::STRONG, the HardwareAuthToken MUST be null. + */ + void onAuthenticationSucceeded(in int enrollmentId, in HardwareAuthToken hat); + + /** + * This method must only be used to notify the framework during SessionState::AUTHENTICATING. + * + * Used to notify the framework upon rejected attempts. Note that the authentication + * lifecycle ends when either 1) a face is accepted, or 2) an occurred. The + * authentication lifecycle does NOT end when a face is rejected. + */ + void onAuthenticationFailed(); + + /** + * This method must only be used to notify the framework during SessionState::AUTHENTICATING. + * + * Authentication is locked out due to too many unsuccessful attempts. This is a rate-limiting + * lockout, and authentication can be restarted after a period of time. See + * ISession#resetLockout. + * + * @param sensorId Sensor for which the user is locked out. + * @param userId User for which the sensor is locked out. + * @param durationMillis Remaining duration of the lockout. + */ + void onLockoutTimed(in long durationMillis); + + /** + * This method must only be used to notify the framework during SessionState::AUTHENTICATING. + * + * Authentication is disabled until the user unlocks with their device credential + * (PIN/Pattern/Password). See ISession#resetLockout. + * + * @param sensorId Sensor for which the user is locked out. + * @param userId User for which the sensor is locked out. + */ + void onLockoutPermanent(); + + /** + * Notifies the framework that lockout has been cleared for this (sensorId, userId) pair. + * + * Note that this method can be used to notify the framework during any state. + * + * Lockout can be cleared in the following scenarios: + * 1) A timed lockout has ended (e.g. durationMillis specified in previous #onLockoutTimed + * has expired. + * 2) See ISession#resetLockout. + * + * @param sensorId Sensor for which the user's lockout is cleared. + * @param userId User for the sensor's lockout is cleared. + */ + void onLockoutCleared(); + + /** + * This method must only be used to notify the framework during + * SessionState::DETECTING_INTERACTION + * + * Notifies the framework that user interaction occurred. See ISession#detectInteraction. + */ + void onInteractionDetected(); + + /** + * This method must only be used to notify the framework during + * SessionState::ENUMERATING_ENROLLMENTS. + * + * Notifies the framework of the current enrollments. See ISession#enumerateEnrollments. + * + * @param enrollmentIds A list of enrollments for the session's (userId, sensorId) pair. + */ + void onEnrollmentsEnumerated(in int[] enrollmentIds); + + /** + * This method must only be used to notify the framework during + * SessionState::REMOVING_ENROLLMENTS. + * + * Notifies the framework that the specified enrollments are removed. + * + * @param enrollmentIds The enrollments that were removed. + */ + void onEnrollmentsRemoved(in int[] enrollmentIds); + + /** + * This method must only be used to notify the framework during + * SessionState::GETTING_AUTHENTICATOR_ID. + * + * Notifies the framework with the authenticatorId corresponding to this session's + * (userId, sensorId) pair. + * + * @param authenticatorId See the above documentation. + */ + void onAuthenticatorIdRetrieved(in long authenticatorId); + + /** + * This method must only be used to notify the framework during + * SessionState::INVALIDATING_AUTHENTICATOR_ID. + * + * See ISession#invalidateAuthenticatorId for more information. + */ + void onAuthenticatorIdInvalidated(); +} diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/SensorProps.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/SensorProps.aidl new file mode 100644 index 0000000000..53cc44e7ec --- /dev/null +++ b/biometrics/face/aidl/android/hardware/biometrics/face/SensorProps.aidl @@ -0,0 +1,43 @@ +/* + * 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.face; + +import android.hardware.biometrics.common.CommonProps; +import android.hardware.biometrics.face.FaceSensorType; + +@VintfStability +parcelable SensorProps { + /** + * Statically configured properties that apply to this face sensor. + */ + CommonProps commonProps; + + /** + * A statically configured sensor type representing this face sensor. + */ + FaceSensorType sensorType; + + /** + * Whether or not the HAL is responsible for showing the face enrollment preview to the user. + * Devices with multiple front camera sensors can set this to false and rely on the framework to + * show the preview with one of the unused cameras. Devices with a single front sensor must set + * this to true and configure their send their camera stream to the preview surface provided by + * the framework. + */ + boolean halControlsPreview; +} + diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/SessionState.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/SessionState.aidl new file mode 100644 index 0000000000..1878f7c823 --- /dev/null +++ b/biometrics/face/aidl/android/hardware/biometrics/face/SessionState.aidl @@ -0,0 +1,82 @@ +/* + * 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.face; + +@VintfStability +@Backing(type="byte") +enum SessionState { + /** + * The HAL is not processing any session requests. + */ + IDLING, + + /** + * The session has been terminated by the HAL. + */ + TERMINATED, + + /** + * 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/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml index 4ac19731e2..a99f8feda4 100644 --- a/compatibility_matrices/compatibility_matrix.current.xml +++ b/compatibility_matrices/compatibility_matrix.current.xml @@ -96,6 +96,13 @@ default + + android.hardware.biometrics.face + + IFace + default + + android.hardware.biometrics.fingerprint 2.1-3 From 3b542cd396699e0c6d364be5a549fec30d60edb6 Mon Sep 17 00:00:00 2001 From: Ilya Matyukhin Date: Mon, 12 Oct 2020 18:23:46 -0700 Subject: [PATCH 2/3] Add VTS tests skeleton for IFace Bug: 168730443 Test: atest VtsHalBiometricsFaceTargetTest Change-Id: I90ec41b0b7cc461cce50f55f99e7ee2a836fb2e0 --- biometrics/face/aidl/vts/Android.bp | 16 ++ .../vts/VtsHalBiometricsFaceTargetTest.cpp | 157 ++++++++++++++++++ 2 files changed, 173 insertions(+) create mode 100644 biometrics/face/aidl/vts/Android.bp create mode 100644 biometrics/face/aidl/vts/VtsHalBiometricsFaceTargetTest.cpp diff --git a/biometrics/face/aidl/vts/Android.bp b/biometrics/face/aidl/vts/Android.bp new file mode 100644 index 0000000000..427b8785fb --- /dev/null +++ b/biometrics/face/aidl/vts/Android.bp @@ -0,0 +1,16 @@ +cc_test { + name: "VtsHalBiometricsFaceTargetTest", + defaults: [ + "VtsHalTargetTestDefaults", + "use_libaidlvintf_gtest_helper_static", + ], + srcs: ["VtsHalBiometricsFaceTargetTest.cpp"], + shared_libs: [ + "libbinder_ndk", + "android.hardware.biometrics.face-ndk_platform", + ], + test_suites: [ + "general-tests", + "vts", + ], +} diff --git a/biometrics/face/aidl/vts/VtsHalBiometricsFaceTargetTest.cpp b/biometrics/face/aidl/vts/VtsHalBiometricsFaceTargetTest.cpp new file mode 100644 index 0000000000..c1ba66b004 --- /dev/null +++ b/biometrics/face/aidl/vts/VtsHalBiometricsFaceTargetTest.cpp @@ -0,0 +1,157 @@ +/* + * 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. + */ +#include +#include +#include +#include + +#include +#include + +#include + +namespace aidl::android::hardware::biometrics::face { +namespace { + +constexpr int kSensorId = 0; +constexpr int kUserId = 0; +constexpr auto kCallbackTimeout = std::chrono::seconds(1); + +enum class SessionCallbackMethodName { + kOnStateChanged, +}; + +struct SessionCallbackInvocation { + SessionCallbackMethodName method_name; + SessionState state; +}; + +class SessionCallback : public BnSessionCallback { + public: + explicit SessionCallback(std::promise 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(); + } + + ndk::ScopedAStatus onChallengeGenerated(int32_t /*sensorId*/, int32_t /*userId*/, + int64_t /*challenge*/) override { + return ndk::ScopedAStatus::ok(); + } + + ndk::ScopedAStatus onChallengeRevoked(int32_t /*sensorId*/, int32_t /*userId*/, + int64_t /*challenge*/) override { + return ndk::ScopedAStatus::ok(); + } + + ndk::ScopedAStatus onAcquired(AcquiredInfo /*info*/, int32_t /*vendorCode*/) override { + return ndk::ScopedAStatus::ok(); + } + + ndk::ScopedAStatus onError(Error /*error*/, int32_t /*vendorCode*/) override { + return ndk::ScopedAStatus::ok(); + } + + ndk::ScopedAStatus onEnrollmentProgress(int32_t /*enrollmentId*/, + int32_t /*remaining*/) override { + return ndk::ScopedAStatus::ok(); + } + + ndk::ScopedAStatus onAuthenticationSucceeded( + int32_t /*enrollmentId*/, const keymaster::HardwareAuthToken& /*hat*/) override { + return ndk::ScopedAStatus::ok(); + } + + ndk::ScopedAStatus onAuthenticationFailed() override { return ndk::ScopedAStatus::ok(); } + + ndk::ScopedAStatus onLockoutTimed(int64_t /*durationMillis*/) override { + return ndk::ScopedAStatus::ok(); + } + + ndk::ScopedAStatus onLockoutPermanent() override { return ndk::ScopedAStatus::ok(); } + + ndk::ScopedAStatus onLockoutCleared() override { return ndk::ScopedAStatus::ok(); } + + ndk::ScopedAStatus onInteractionDetected() override { return ndk::ScopedAStatus::ok(); } + + ndk::ScopedAStatus onEnrollmentsEnumerated( + const std::vector& /*enrollmentIds*/) override { + return ndk::ScopedAStatus::ok(); + } + + ndk::ScopedAStatus onEnrollmentsRemoved( + const std::vector& /*enrollmentIds*/) override { + return ndk::ScopedAStatus::ok(); + } + + ndk::ScopedAStatus onAuthenticatorIdRetrieved(int64_t /*authenticatorId*/) override { + return ndk::ScopedAStatus::ok(); + } + + ndk::ScopedAStatus onAuthenticatorIdInvalidated() override { return ndk::ScopedAStatus::ok(); } + + private: + std::promise invocation_promise_; +}; + +class Face : public testing::TestWithParam { + protected: + void SetUp() override { + AIBinder* binder = AServiceManager_waitForService(GetParam().c_str()); + ASSERT_NE(binder, nullptr); + hal_ = IFace::fromBinder(ndk::SpAIBinder(binder)); + } + + std::shared_ptr hal_; +}; + +TEST_P(Face, AuthenticateTest) { + std::promise invocation_promise; + std::future invocation_future = invocation_promise.get_future(); + std::shared_ptr session_cb = + ndk::SharedRefBase::make(std::move(invocation_promise)); + + std::shared_ptr session; + ASSERT_TRUE(hal_->createSession(kSensorId, kUserId, session_cb, &session).isOk()); + + std::shared_ptr cancel_cb; + ASSERT_TRUE(session->authenticate(0, 0, &cancel_cb).isOk()); + ASSERT_EQ(invocation_future.wait_for(kCallbackTimeout), std::future_status::ready); + + SessionCallbackInvocation invocation = invocation_future.get(); + EXPECT_EQ(invocation.method_name, SessionCallbackMethodName::kOnStateChanged); + EXPECT_EQ(invocation.state, SessionState::AUTHENTICATING); +} + +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(Face); +INSTANTIATE_TEST_SUITE_P(IFace, Face, + testing::ValuesIn(::android::getAidlHalInstanceNames(IFace::descriptor)), + ::android::PrintInstanceNameToString); + +} // namespace + +int main(int argc, char** argv) { + ::testing::InitGoogleTest(&argc, argv); + ABinderProcess_setThreadPoolMaxThreadCount(1); + ABinderProcess_startThreadPool(); + return RUN_ALL_TESTS(); +} + +} // namespace aidl::android::hardware::biometrics::face From 0916698222165de89a111e88636582b5073f9252 Mon Sep 17 00:00:00 2001 From: Ilya Matyukhin Date: Mon, 12 Oct 2020 13:41:03 -0700 Subject: [PATCH 3/3] Default implementation skeleton for IFace Bug: 168730443 Test: atest VtsHalBiometricsFaceTargetTest Test: atest vts_treble_vintf_vendor_test Test: atest hal_implementation_test Change-Id: I97b2b00da928e7f9e175d9853424111d95f285fb --- biometrics/face/aidl/default/Android.bp | 18 ++++ biometrics/face/aidl/default/Face.cpp | 61 ++++++++++++++ biometrics/face/aidl/default/Face.h | 32 ++++++++ biometrics/face/aidl/default/Session.cpp | 82 +++++++++++++++++++ biometrics/face/aidl/default/Session.h | 67 +++++++++++++++ biometrics/face/aidl/default/face-default.rc | 5 ++ biometrics/face/aidl/default/face-default.xml | 6 ++ biometrics/face/aidl/default/main.cpp | 36 ++++++++ 8 files changed, 307 insertions(+) create mode 100644 biometrics/face/aidl/default/Android.bp create mode 100644 biometrics/face/aidl/default/Face.cpp create mode 100644 biometrics/face/aidl/default/Face.h create mode 100644 biometrics/face/aidl/default/Session.cpp create mode 100644 biometrics/face/aidl/default/Session.h create mode 100644 biometrics/face/aidl/default/face-default.rc create mode 100644 biometrics/face/aidl/default/face-default.xml create mode 100644 biometrics/face/aidl/default/main.cpp diff --git a/biometrics/face/aidl/default/Android.bp b/biometrics/face/aidl/default/Android.bp new file mode 100644 index 0000000000..51a8ef4488 --- /dev/null +++ b/biometrics/face/aidl/default/Android.bp @@ -0,0 +1,18 @@ +cc_binary { + name: "android.hardware.biometrics.face-service.example", + relative_install_path: "hw", + init_rc: ["face-default.rc"], + vintf_fragments: ["face-default.xml"], + vendor: true, + shared_libs: [ + "libbase", + "libbinder_ndk", + "android.hardware.biometrics.face-ndk_platform", + "android.hardware.biometrics.common-unstable-ndk_platform", + ], + srcs: [ + "main.cpp", + "Face.cpp", + "Session.cpp", + ], +} diff --git a/biometrics/face/aidl/default/Face.cpp b/biometrics/face/aidl/default/Face.cpp new file mode 100644 index 0000000000..1526245c70 --- /dev/null +++ b/biometrics/face/aidl/default/Face.cpp @@ -0,0 +1,61 @@ +/* + * 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. + */ + +#include "Face.h" +#include "Session.h" + +namespace aidl::android::hardware::biometrics::face { + +const int kSensorId = 0; +const common::SensorStrength kSensorStrength = common::SensorStrength::WEAK; +const int kMaxEnrollmentsPerUser = 5; +const FaceSensorType kSensorType = FaceSensorType::RGB; +const bool kHalControlsPreview = true; +const std::string kHwDeviceName = "faceSensor"; +const std::string kHardwareVersion = "vendor/model/revision"; +const std::string kFirmwareVersion = "1.01"; +const std::string kSerialNumber = "00000001"; + +ndk::ScopedAStatus Face::getSensorProps(std::vector* return_val) { + common::HardwareInfo hardware_info; + hardware_info.deviceName = kHwDeviceName; + hardware_info.hardwareVersion = kHardwareVersion; + hardware_info.firmwareVersion = kFirmwareVersion; + hardware_info.serialNumber = kSerialNumber; + + common::CommonProps commonProps; + commonProps.sensorId = kSensorId; + commonProps.sensorStrength = kSensorStrength; + commonProps.maxEnrollmentsPerUser = kMaxEnrollmentsPerUser; + commonProps.hardwareInfo = {std::move(hardware_info)}; + + SensorProps props; + props.commonProps = std::move(commonProps); + props.sensorType = kSensorType; + props.halControlsPreview = kHalControlsPreview; + + *return_val = {std::move(props)}; + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus Face::createSession(int32_t /*sensorId*/, int32_t /*userId*/, + const std::shared_ptr& cb, + std::shared_ptr* return_val) { + *return_val = SharedRefBase::make(cb); + return ndk::ScopedAStatus::ok(); +} + +} // namespace aidl::android::hardware::biometrics::face diff --git a/biometrics/face/aidl/default/Face.h b/biometrics/face/aidl/default/Face.h new file mode 100644 index 0000000000..786b4f89fe --- /dev/null +++ b/biometrics/face/aidl/default/Face.h @@ -0,0 +1,32 @@ +/* + * 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. + */ + +#pragma once + +#include + +namespace aidl::android::hardware::biometrics::face { + +class Face : public BnFace { + public: + ndk::ScopedAStatus getSensorProps(std::vector* _aidl_return) override; + + ndk::ScopedAStatus createSession(int32_t sensorId, int32_t userId, + const std::shared_ptr& cb, + std::shared_ptr* _aidl_return) override; +}; + +} // namespace aidl::android::hardware::biometrics::face diff --git a/biometrics/face/aidl/default/Session.cpp b/biometrics/face/aidl/default/Session.cpp new file mode 100644 index 0000000000..bb895b76ba --- /dev/null +++ b/biometrics/face/aidl/default/Session.cpp @@ -0,0 +1,82 @@ +/* + * 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. + */ + +#include + +#include "Session.h" + +namespace aidl::android::hardware::biometrics::face { + +class CancellationSignal : public common::BnCancellationSignal { + public: + ndk::ScopedAStatus cancel() override { return ndk::ScopedAStatus::ok(); } +}; + +Session::Session(std::shared_ptr cb) : cb_(std::move(cb)) {} + +ndk::ScopedAStatus Session::generateChallenge(int32_t /*cookie*/, int32_t /*sensorId*/, + int32_t /*userId*/, int32_t /*timeoutSec*/) { + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus Session::revokeChallenge(int32_t /*cookie*/, int32_t /*sensorId*/, + int32_t /*userId*/, int64_t /*challenge*/) { + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus Session::enroll(int32_t /*cookie*/, const keymaster::HardwareAuthToken& /*hat*/, + const NativeHandle& /*previewSurface*/, + std::shared_ptr* + /*returnVal*/) { + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus Session::authenticate(int32_t /*cookie*/, int64_t /*keystoreOperationId*/, + std::shared_ptr* return_val) { + if (cb_) { + cb_->onStateChanged(0, SessionState::AUTHENTICATING); + } + *return_val = SharedRefBase::make(); + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus Session::detectInteraction( + int32_t /*cookie*/, std::shared_ptr* /*return_val*/) { + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus Session::enumerateEnrollments(int32_t /*cookie*/) { + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus Session::removeEnrollments(int32_t /*cookie*/, + const std::vector& /*enrollmentIds*/) { + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus Session::getAuthenticatorId(int32_t /*cookie*/) { + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus Session::invalidateAuthenticatorId(int32_t /*cookie*/) { + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus Session::resetLockout(int32_t /*cookie*/, + const keymaster::HardwareAuthToken& /*hat*/) { + return ndk::ScopedAStatus::ok(); +} +} // namespace aidl::android::hardware::biometrics::face diff --git a/biometrics/face/aidl/default/Session.h b/biometrics/face/aidl/default/Session.h new file mode 100644 index 0000000000..a91ad8151b --- /dev/null +++ b/biometrics/face/aidl/default/Session.h @@ -0,0 +1,67 @@ +/* + * 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. + */ + +#pragma once + +#include +#include + +namespace aidl::android::hardware::biometrics::face { + +namespace common = aidl::android::hardware::biometrics::common; +namespace keymaster = aidl::android::hardware::keymaster; + +using aidl::android::hardware::common::NativeHandle; + +class Session : public BnSession { + public: + explicit Session(std::shared_ptr cb); + + ndk::ScopedAStatus generateChallenge(int32_t cookie, int32_t sensorId, int32_t userId, + int32_t timeoutSec) override; + + ndk::ScopedAStatus revokeChallenge(int32_t cookie, int32_t sensorId, int32_t userId, + int64_t challenge) override; + + ndk::ScopedAStatus enroll( + int32_t cookie, const keymaster::HardwareAuthToken& hat, + const NativeHandle& previewSurface, + std::shared_ptr* returnVal) override; + + ndk::ScopedAStatus authenticate( + int32_t cookie, int64_t keystoreOperationId, + std::shared_ptr* returnVal) override; + + ndk::ScopedAStatus detectInteraction( + int32_t cookie, std::shared_ptr* returnVal) override; + + ndk::ScopedAStatus enumerateEnrollments(int32_t cookie) override; + + ndk::ScopedAStatus removeEnrollments(int32_t cookie, + const std::vector& enrollmentIds) override; + + ndk::ScopedAStatus getAuthenticatorId(int32_t cookie) override; + + ndk::ScopedAStatus invalidateAuthenticatorId(int32_t cookie) override; + + ndk::ScopedAStatus resetLockout(int32_t cookie, + const keymaster::HardwareAuthToken& hat) override; + + private: + std::shared_ptr cb_; +}; + +} // namespace aidl::android::hardware::biometrics::face diff --git a/biometrics/face/aidl/default/face-default.rc b/biometrics/face/aidl/default/face-default.rc new file mode 100644 index 0000000000..f6499f0a09 --- /dev/null +++ b/biometrics/face/aidl/default/face-default.rc @@ -0,0 +1,5 @@ +service vendor.face-default /vendor/bin/hw/android.hardware.biometrics.face-service.example + class hal + user nobody + group nobody + diff --git a/biometrics/face/aidl/default/face-default.xml b/biometrics/face/aidl/default/face-default.xml new file mode 100644 index 0000000000..6915ad0a4d --- /dev/null +++ b/biometrics/face/aidl/default/face-default.xml @@ -0,0 +1,6 @@ + + + android.hardware.biometrics.face + IFace/default + + diff --git a/biometrics/face/aidl/default/main.cpp b/biometrics/face/aidl/default/main.cpp new file mode 100644 index 0000000000..80b153ea1f --- /dev/null +++ b/biometrics/face/aidl/default/main.cpp @@ -0,0 +1,36 @@ +/* + * 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. + */ + +#include "Face.h" + +#include +#include +#include + +using aidl::android::hardware::biometrics::face::Face; + +int main() { + LOG(INFO) << "Face HAL started"; + ABinderProcess_setThreadPoolMaxThreadCount(0); + std::shared_ptr hal = ndk::SharedRefBase::make(); + + const std::string instance = std::string(Face::descriptor) + "/default"; + binder_status_t status = AServiceManager_addService(hal->asBinder().get(), instance.c_str()); + CHECK(status == STATUS_OK); + + ABinderProcess_joinThreadPool(); + return EXIT_FAILURE; // should not reach +}