mirror of
https://github.com/Evolution-X/hardware_interfaces
synced 2026-02-01 05:49:27 +00:00
Merge changes from topic "IFace.aidl"
* changes: Default implementation skeleton for IFace Add VTS tests skeleton for IFace Define IFace
This commit is contained in:
committed by
Android (Google) Code Review
commit
8d40eb3a74
22
biometrics/face/aidl/Android.bp
Normal file
22
biometrics/face/aidl/Android.bp
Normal file
@@ -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,
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -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,
|
||||
}
|
||||
@@ -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,
|
||||
}
|
||||
@@ -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,
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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,
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
*/
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
@@ -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/<user>/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);
|
||||
|
||||
}
|
||||
@@ -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 | <Time1> | <Random1> |
|
||||
* | 0 | 0 | <Time2> | <Random2> |
|
||||
* | 1 | 0 | <Time3> | <Random3> |
|
||||
* | 0 | 10 | <Time4> | <Random4> |
|
||||
* ----------------------------------------------
|
||||
*
|
||||
* @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 | <future_time> |
|
||||
* | 0 | 10 | 0 | false | x |
|
||||
* | 1 | 10 | 0 | false | x |
|
||||
* ------------------------------------------------------------------
|
||||
*
|
||||
* Lockout may be cleared in the following ways:
|
||||
* 1) ISession#resetLockout
|
||||
* 2) After a period of time, according to a rate-limiter.
|
||||
*
|
||||
* Note that the "FailedAttempts" counter must be cleared upon successful 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);
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
18
biometrics/face/aidl/default/Android.bp
Normal file
18
biometrics/face/aidl/default/Android.bp
Normal file
@@ -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",
|
||||
],
|
||||
}
|
||||
61
biometrics/face/aidl/default/Face.cpp
Normal file
61
biometrics/face/aidl/default/Face.cpp
Normal file
@@ -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<SensorProps>* 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<ISessionCallback>& cb,
|
||||
std::shared_ptr<ISession>* return_val) {
|
||||
*return_val = SharedRefBase::make<Session>(cb);
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
} // namespace aidl::android::hardware::biometrics::face
|
||||
32
biometrics/face/aidl/default/Face.h
Normal file
32
biometrics/face/aidl/default/Face.h
Normal file
@@ -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 <aidl/android/hardware/biometrics/face/BnFace.h>
|
||||
|
||||
namespace aidl::android::hardware::biometrics::face {
|
||||
|
||||
class Face : public BnFace {
|
||||
public:
|
||||
ndk::ScopedAStatus getSensorProps(std::vector<SensorProps>* _aidl_return) override;
|
||||
|
||||
ndk::ScopedAStatus createSession(int32_t sensorId, int32_t userId,
|
||||
const std::shared_ptr<ISessionCallback>& cb,
|
||||
std::shared_ptr<ISession>* _aidl_return) override;
|
||||
};
|
||||
|
||||
} // namespace aidl::android::hardware::biometrics::face
|
||||
82
biometrics/face/aidl/default/Session.cpp
Normal file
82
biometrics/face/aidl/default/Session.cpp
Normal file
@@ -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 <aidl/android/hardware/biometrics/common/BnCancellationSignal.h>
|
||||
|
||||
#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<ISessionCallback> 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<biometrics::common::ICancellationSignal>*
|
||||
/*returnVal*/) {
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus Session::authenticate(int32_t /*cookie*/, int64_t /*keystoreOperationId*/,
|
||||
std::shared_ptr<common::ICancellationSignal>* return_val) {
|
||||
if (cb_) {
|
||||
cb_->onStateChanged(0, SessionState::AUTHENTICATING);
|
||||
}
|
||||
*return_val = SharedRefBase::make<CancellationSignal>();
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus Session::detectInteraction(
|
||||
int32_t /*cookie*/, std::shared_ptr<common::ICancellationSignal>* /*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<int32_t>& /*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
|
||||
67
biometrics/face/aidl/default/Session.h
Normal file
67
biometrics/face/aidl/default/Session.h
Normal file
@@ -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 <aidl/android/hardware/biometrics/face/BnSession.h>
|
||||
#include <aidl/android/hardware/biometrics/face/ISessionCallback.h>
|
||||
|
||||
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<ISessionCallback> 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<biometrics::common::ICancellationSignal>* returnVal) override;
|
||||
|
||||
ndk::ScopedAStatus authenticate(
|
||||
int32_t cookie, int64_t keystoreOperationId,
|
||||
std::shared_ptr<common::ICancellationSignal>* returnVal) override;
|
||||
|
||||
ndk::ScopedAStatus detectInteraction(
|
||||
int32_t cookie, std::shared_ptr<common::ICancellationSignal>* returnVal) override;
|
||||
|
||||
ndk::ScopedAStatus enumerateEnrollments(int32_t cookie) override;
|
||||
|
||||
ndk::ScopedAStatus removeEnrollments(int32_t cookie,
|
||||
const std::vector<int32_t>& 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<ISessionCallback> cb_;
|
||||
};
|
||||
|
||||
} // namespace aidl::android::hardware::biometrics::face
|
||||
5
biometrics/face/aidl/default/face-default.rc
Normal file
5
biometrics/face/aidl/default/face-default.rc
Normal file
@@ -0,0 +1,5 @@
|
||||
service vendor.face-default /vendor/bin/hw/android.hardware.biometrics.face-service.example
|
||||
class hal
|
||||
user nobody
|
||||
group nobody
|
||||
|
||||
6
biometrics/face/aidl/default/face-default.xml
Normal file
6
biometrics/face/aidl/default/face-default.xml
Normal file
@@ -0,0 +1,6 @@
|
||||
<manifest version="1.0" type="device">
|
||||
<hal format="aidl">
|
||||
<name>android.hardware.biometrics.face</name>
|
||||
<fqname>IFace/default</fqname>
|
||||
</hal>
|
||||
</manifest>
|
||||
36
biometrics/face/aidl/default/main.cpp
Normal file
36
biometrics/face/aidl/default/main.cpp
Normal file
@@ -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 <android-base/logging.h>
|
||||
#include <android/binder_manager.h>
|
||||
#include <android/binder_process.h>
|
||||
|
||||
using aidl::android::hardware::biometrics::face::Face;
|
||||
|
||||
int main() {
|
||||
LOG(INFO) << "Face HAL started";
|
||||
ABinderProcess_setThreadPoolMaxThreadCount(0);
|
||||
std::shared_ptr<Face> hal = ndk::SharedRefBase::make<Face>();
|
||||
|
||||
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
|
||||
}
|
||||
16
biometrics/face/aidl/vts/Android.bp
Normal file
16
biometrics/face/aidl/vts/Android.bp
Normal file
@@ -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",
|
||||
],
|
||||
}
|
||||
157
biometrics/face/aidl/vts/VtsHalBiometricsFaceTargetTest.cpp
Normal file
157
biometrics/face/aidl/vts/VtsHalBiometricsFaceTargetTest.cpp
Normal file
@@ -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 <aidl/Gtest.h>
|
||||
#include <aidl/Vintf.h>
|
||||
#include <aidl/android/hardware/biometrics/face/BnFace.h>
|
||||
#include <aidl/android/hardware/biometrics/face/BnSessionCallback.h>
|
||||
|
||||
#include <android/binder_manager.h>
|
||||
#include <android/binder_process.h>
|
||||
|
||||
#include <future>
|
||||
|
||||
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<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();
|
||||
}
|
||||
|
||||
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<int32_t>& /*enrollmentIds*/) override {
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus onEnrollmentsRemoved(
|
||||
const std::vector<int32_t>& /*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<SessionCallbackInvocation> invocation_promise_;
|
||||
};
|
||||
|
||||
class Face : public testing::TestWithParam<std::string> {
|
||||
protected:
|
||||
void SetUp() override {
|
||||
AIBinder* binder = AServiceManager_waitForService(GetParam().c_str());
|
||||
ASSERT_NE(binder, nullptr);
|
||||
hal_ = IFace::fromBinder(ndk::SpAIBinder(binder));
|
||||
}
|
||||
|
||||
std::shared_ptr<IFace> hal_;
|
||||
};
|
||||
|
||||
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));
|
||||
|
||||
std::shared_ptr<ISession> session;
|
||||
ASSERT_TRUE(hal_->createSession(kSensorId, kUserId, session_cb, &session).isOk());
|
||||
|
||||
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);
|
||||
|
||||
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
|
||||
@@ -96,6 +96,13 @@
|
||||
<instance>default</instance>
|
||||
</interface>
|
||||
</hal>
|
||||
<hal format="aidl" optional="true">
|
||||
<name>android.hardware.biometrics.face</name>
|
||||
<interface>
|
||||
<name>IFace</name>
|
||||
<instance>default</instance>
|
||||
</interface>
|
||||
</hal>
|
||||
<hal format="hidl" optional="true">
|
||||
<name>android.hardware.biometrics.fingerprint</name>
|
||||
<version>2.1-3</version>
|
||||
|
||||
Reference in New Issue
Block a user