Loading core/java/android/hardware/face/FaceEnrollFrame.java +1 −0 Original line number Original line Diff line number Diff line Loading @@ -18,6 +18,7 @@ package android.hardware.face; import android.annotation.NonNull; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.Nullable; import android.hardware.face.FaceEnrollStages.FaceEnrollStage; import android.os.Parcel; import android.os.Parcel; import android.os.Parcelable; import android.os.Parcelable; Loading core/java/android/hardware/face/FaceEnrollStage.java→core/java/android/hardware/face/FaceEnrollStages.java +29 −19 Original line number Original line Diff line number Diff line Loading @@ -21,54 +21,64 @@ import android.annotation.IntDef; import java.lang.annotation.Retention; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy; /** * A collection of constants representing different stages of face enrollment. * * @hide */ public final class FaceEnrollStages { // Prevent instantiation. private FaceEnrollStages() {} /** /** * A stage that may occur during face enrollment. * A stage that may occur during face enrollment. * * * @hide * @hide */ */ @Retention(RetentionPolicy.SOURCE) @IntDef({ @IntDef({ FaceEnrollStage.UNKNOWN, UNKNOWN, FaceEnrollStage.FIRST_FRAME_RECEIVED, FIRST_FRAME_RECEIVED, FaceEnrollStage.WAITING_FOR_CENTERING, WAITING_FOR_CENTERING, FaceEnrollStage.HOLD_STILL_IN_CENTER, HOLD_STILL_IN_CENTER, FaceEnrollStage.ENROLLING_MOVEMENT_1, ENROLLING_MOVEMENT_1, FaceEnrollStage.ENROLLING_MOVEMENT_2, ENROLLING_MOVEMENT_2, FaceEnrollStage.ENROLLMENT_FINISHED ENROLLMENT_FINISHED }) }) public @interface FaceEnrollStage { @Retention(RetentionPolicy.SOURCE) public @interface FaceEnrollStage {} /** /** * The current enrollment stage is not known. * The current enrollment stage is not known. */ */ int UNKNOWN = -1; public static final int UNKNOWN = 0; /** /** * Enrollment has just begun. No action is needed from the user yet. * Enrollment has just begun. No action is needed from the user yet. */ */ int FIRST_FRAME_RECEIVED = 0; public static final int FIRST_FRAME_RECEIVED = 1; /** /** * The user must center their face in the frame. * The user must center their face in the frame. */ */ int WAITING_FOR_CENTERING = 1; public static final int WAITING_FOR_CENTERING = 2; /** /** * The user must keep their face centered in the frame. * The user must keep their face centered in the frame. */ */ int HOLD_STILL_IN_CENTER = 2; public static final int HOLD_STILL_IN_CENTER = 3; /** /** * The user must follow a first set of movement instructions. * The user must follow a first set of movement instructions. */ */ int ENROLLING_MOVEMENT_1 = 3; public static final int ENROLLING_MOVEMENT_1 = 4; /** /** * The user must follow a second set of movement instructions. * The user must follow a second set of movement instructions. */ */ int ENROLLING_MOVEMENT_2 = 4; public static final int ENROLLING_MOVEMENT_2 = 5; /** /** * Enrollment has completed. No more action is needed from the user. * Enrollment has completed. No more action is needed from the user. */ */ int ENROLLMENT_FINISHED = 5; public static final int ENROLLMENT_FINISHED = 6; } } core/java/android/hardware/face/FaceManager.java +40 −5 Original line number Original line Diff line number Diff line Loading @@ -1022,6 +1022,34 @@ public class FaceManager implements BiometricAuthenticator, BiometricFaceConstan public void onEnrollmentHelp(int helpMsgId, CharSequence helpString) { public void onEnrollmentHelp(int helpMsgId, CharSequence helpString) { } } /** * Called each time a single frame is captured during enrollment. * * <p>For older, non-AIDL implementations, only {@code helpCode} and {@code helpMessage} are * supported. Sensible default values will be provided for all other arguments. * * @param helpCode An integer identifying the capture status for this frame. * @param helpMessage A human-readable help string that can be shown in UI. * @param cell The cell captured during this frame of enrollment, if any. * @param stage An integer representing the current stage of enrollment. * @param pan The horizontal pan of the detected face. Values in the range [-1, 1] * indicate a good capture. * @param tilt The vertical tilt of the detected face. Values in the range [-1, 1] * indicate a good capture. * @param distance The distance of the detected face from the device. Values in * the range [-1, 1] indicate a good capture. */ public void onEnrollmentFrame( int helpCode, @Nullable CharSequence helpMessage, @Nullable FaceEnrollCell cell, @FaceEnrollStages.FaceEnrollStage int stage, float pan, float tilt, float distance) { onEnrollmentHelp(helpCode, helpMessage); } /** /** * Called as each enrollment step progresses. Enrollment is considered complete when * Called as each enrollment step progresses. Enrollment is considered complete when * remaining reaches 0. This function will not be called if enrollment fails. See * remaining reaches 0. This function will not be called if enrollment fails. See Loading Loading @@ -1305,7 +1333,7 @@ public class FaceManager implements BiometricAuthenticator, BiometricFaceConstan } else if (mEnrollmentCallback != null) { } else if (mEnrollmentCallback != null) { final FaceEnrollFrame frame = new FaceEnrollFrame( final FaceEnrollFrame frame = new FaceEnrollFrame( null /* cell */, null /* cell */, FaceEnrollStage.UNKNOWN, FaceEnrollStages.UNKNOWN, new FaceDataFrame(acquireInfo, vendorCode)); new FaceDataFrame(acquireInfo, vendorCode)); sendEnrollmentFrame(frame); sendEnrollmentFrame(frame); } } Loading Loading @@ -1333,12 +1361,19 @@ public class FaceManager implements BiometricAuthenticator, BiometricFaceConstan if (frame == null) { if (frame == null) { Slog.w(TAG, "Received null enrollment frame"); Slog.w(TAG, "Received null enrollment frame"); } else if (mEnrollmentCallback != null) { } else if (mEnrollmentCallback != null) { // TODO(b/178414967): Send additional frame data to callback final FaceDataFrame data = frame.getData(); final int acquireInfo = frame.getData().getAcquiredInfo(); final int acquireInfo = data.getAcquiredInfo(); final int vendorCode = frame.getData().getVendorCode(); final int vendorCode = data.getVendorCode(); final int helpCode = getHelpCode(acquireInfo, vendorCode); final int helpCode = getHelpCode(acquireInfo, vendorCode); final String helpMessage = getEnrollHelpMessage(mContext, acquireInfo, vendorCode); final String helpMessage = getEnrollHelpMessage(mContext, acquireInfo, vendorCode); mEnrollmentCallback.onEnrollmentHelp(helpCode, helpMessage); mEnrollmentCallback.onEnrollmentFrame( helpCode, helpMessage, frame.getCell(), frame.getStage(), data.getPan(), data.getTilt(), data.getDistance()); } } } } Loading services/core/java/com/android/server/biometrics/sensors/face/aidl/AidlConversionUtils.java +104 −84 Original line number Original line Diff line number Diff line Loading @@ -24,11 +24,14 @@ import android.hardware.biometrics.face.AuthenticationFrame; import android.hardware.biometrics.face.BaseFrame; import android.hardware.biometrics.face.BaseFrame; import android.hardware.biometrics.face.Cell; import android.hardware.biometrics.face.Cell; import android.hardware.biometrics.face.EnrollmentFrame; import android.hardware.biometrics.face.EnrollmentFrame; import android.hardware.biometrics.face.EnrollmentStage; import android.hardware.biometrics.face.Error; import android.hardware.biometrics.face.Error; import android.hardware.face.FaceAuthenticationFrame; import android.hardware.face.FaceAuthenticationFrame; import android.hardware.face.FaceDataFrame; import android.hardware.face.FaceDataFrame; import android.hardware.face.FaceEnrollCell; import android.hardware.face.FaceEnrollCell; import android.hardware.face.FaceEnrollFrame; import android.hardware.face.FaceEnrollFrame; import android.hardware.face.FaceEnrollStages; import android.hardware.face.FaceEnrollStages.FaceEnrollStage; /** /** * Utilities for converting from hardware to framework-defined AIDL models. * Utilities for converting from hardware to framework-defined AIDL models. Loading @@ -38,95 +41,110 @@ final class AidlConversionUtils { private AidlConversionUtils() { private AidlConversionUtils() { } } public static @BiometricFaceConstants.FaceError int toFrameworkError(byte aidlError) { @BiometricFaceConstants.FaceError if (aidlError == Error.UNKNOWN) { public static int toFrameworkError(byte aidlError) { // No framework constant available switch (aidlError) { return BiometricFaceConstants.FACE_ERROR_UNKNOWN; case Error.HW_UNAVAILABLE: } else if (aidlError == Error.HW_UNAVAILABLE) { return BiometricFaceConstants.FACE_ERROR_HW_UNAVAILABLE; return BiometricFaceConstants.FACE_ERROR_HW_UNAVAILABLE; } else if (aidlError == Error.UNABLE_TO_PROCESS) { case Error.UNABLE_TO_PROCESS: return BiometricFaceConstants.FACE_ERROR_UNABLE_TO_PROCESS; return BiometricFaceConstants.FACE_ERROR_UNABLE_TO_PROCESS; } else if (aidlError == Error.TIMEOUT) { case Error.TIMEOUT: return BiometricFaceConstants.FACE_ERROR_TIMEOUT; return BiometricFaceConstants.FACE_ERROR_TIMEOUT; } else if (aidlError == Error.NO_SPACE) { case Error.NO_SPACE: return BiometricFaceConstants.FACE_ERROR_NO_SPACE; return BiometricFaceConstants.FACE_ERROR_NO_SPACE; } else if (aidlError == Error.CANCELED) { case Error.CANCELED: return BiometricFaceConstants.FACE_ERROR_CANCELED; return BiometricFaceConstants.FACE_ERROR_CANCELED; } else if (aidlError == Error.UNABLE_TO_REMOVE) { case Error.UNABLE_TO_REMOVE: return BiometricFaceConstants.FACE_ERROR_UNABLE_TO_REMOVE; return BiometricFaceConstants.FACE_ERROR_UNABLE_TO_REMOVE; } else if (aidlError == Error.VENDOR) { case Error.VENDOR: return BiometricFaceConstants.FACE_ERROR_VENDOR; return BiometricFaceConstants.FACE_ERROR_VENDOR; } else if (aidlError == Error.REENROLL_REQUIRED) { case Error.REENROLL_REQUIRED: return BiometricFaceConstants.BIOMETRIC_ERROR_RE_ENROLL; return BiometricFaceConstants.BIOMETRIC_ERROR_RE_ENROLL; } else { case Error.UNKNOWN: default: return BiometricFaceConstants.FACE_ERROR_UNKNOWN; return BiometricFaceConstants.FACE_ERROR_UNKNOWN; } } } } public static @BiometricFaceConstants.FaceAcquired int toFrameworkAcquiredInfo( @BiometricFaceConstants.FaceAcquired byte aidlAcquired) { public static int toFrameworkAcquiredInfo(byte aidlAcquiredInfo) { if (aidlAcquired == AcquiredInfo.UNKNOWN) { switch (aidlAcquiredInfo) { return BiometricFaceConstants.FACE_ACQUIRED_UNKNOWN; case AcquiredInfo.GOOD: } else if (aidlAcquired == AcquiredInfo.GOOD) { return BiometricFaceConstants.FACE_ACQUIRED_GOOD; return BiometricFaceConstants.FACE_ACQUIRED_GOOD; } else if (aidlAcquired == AcquiredInfo.INSUFFICIENT) { case AcquiredInfo.INSUFFICIENT: return BiometricFaceConstants.FACE_ACQUIRED_INSUFFICIENT; return BiometricFaceConstants.FACE_ACQUIRED_INSUFFICIENT; } else if (aidlAcquired == AcquiredInfo.TOO_BRIGHT) { case AcquiredInfo.TOO_BRIGHT: return BiometricFaceConstants.FACE_ACQUIRED_TOO_BRIGHT; return BiometricFaceConstants.FACE_ACQUIRED_TOO_BRIGHT; } else if (aidlAcquired == AcquiredInfo.TOO_DARK) { case AcquiredInfo.TOO_DARK: return BiometricFaceConstants.FACE_ACQUIRED_TOO_DARK; return BiometricFaceConstants.FACE_ACQUIRED_TOO_DARK; } else if (aidlAcquired == AcquiredInfo.TOO_CLOSE) { case AcquiredInfo.TOO_CLOSE: return BiometricFaceConstants.FACE_ACQUIRED_TOO_CLOSE; return BiometricFaceConstants.FACE_ACQUIRED_TOO_CLOSE; } else if (aidlAcquired == AcquiredInfo.TOO_FAR) { case AcquiredInfo.TOO_FAR: return BiometricFaceConstants.FACE_ACQUIRED_TOO_FAR; return BiometricFaceConstants.FACE_ACQUIRED_TOO_FAR; } else if (aidlAcquired == AcquiredInfo.FACE_TOO_HIGH) { case AcquiredInfo.FACE_TOO_HIGH: return BiometricFaceConstants.FACE_ACQUIRED_TOO_HIGH; return BiometricFaceConstants.FACE_ACQUIRED_TOO_HIGH; } else if (aidlAcquired == AcquiredInfo.FACE_TOO_LOW) { case AcquiredInfo.FACE_TOO_LOW: return BiometricFaceConstants.FACE_ACQUIRED_TOO_LOW; return BiometricFaceConstants.FACE_ACQUIRED_TOO_LOW; } else if (aidlAcquired == AcquiredInfo.FACE_TOO_RIGHT) { case AcquiredInfo.FACE_TOO_RIGHT: return BiometricFaceConstants.FACE_ACQUIRED_TOO_RIGHT; return BiometricFaceConstants.FACE_ACQUIRED_TOO_RIGHT; } else if (aidlAcquired == AcquiredInfo.FACE_TOO_LEFT) { case AcquiredInfo.FACE_TOO_LEFT: return BiometricFaceConstants.FACE_ACQUIRED_TOO_LEFT; return BiometricFaceConstants.FACE_ACQUIRED_TOO_LEFT; } else if (aidlAcquired == AcquiredInfo.POOR_GAZE) { case AcquiredInfo.POOR_GAZE: return BiometricFaceConstants.FACE_ACQUIRED_POOR_GAZE; return BiometricFaceConstants.FACE_ACQUIRED_POOR_GAZE; } else if (aidlAcquired == AcquiredInfo.NOT_DETECTED) { case AcquiredInfo.NOT_DETECTED: return BiometricFaceConstants.FACE_ACQUIRED_NOT_DETECTED; return BiometricFaceConstants.FACE_ACQUIRED_NOT_DETECTED; } else if (aidlAcquired == AcquiredInfo.TOO_MUCH_MOTION) { case AcquiredInfo.TOO_MUCH_MOTION: return BiometricFaceConstants.FACE_ACQUIRED_TOO_MUCH_MOTION; return BiometricFaceConstants.FACE_ACQUIRED_TOO_MUCH_MOTION; } else if (aidlAcquired == AcquiredInfo.RECALIBRATE) { case AcquiredInfo.RECALIBRATE: return BiometricFaceConstants.FACE_ACQUIRED_RECALIBRATE; return BiometricFaceConstants.FACE_ACQUIRED_RECALIBRATE; } else if (aidlAcquired == AcquiredInfo.TOO_DIFFERENT) { case AcquiredInfo.TOO_DIFFERENT: return BiometricFaceConstants.FACE_ACQUIRED_TOO_DIFFERENT; return BiometricFaceConstants.FACE_ACQUIRED_TOO_DIFFERENT; } else if (aidlAcquired == AcquiredInfo.TOO_SIMILAR) { case AcquiredInfo.TOO_SIMILAR: return BiometricFaceConstants.FACE_ACQUIRED_TOO_SIMILAR; return BiometricFaceConstants.FACE_ACQUIRED_TOO_SIMILAR; } else if (aidlAcquired == AcquiredInfo.PAN_TOO_EXTREME) { case AcquiredInfo.PAN_TOO_EXTREME: return BiometricFaceConstants.FACE_ACQUIRED_PAN_TOO_EXTREME; return BiometricFaceConstants.FACE_ACQUIRED_PAN_TOO_EXTREME; } else if (aidlAcquired == AcquiredInfo.TILT_TOO_EXTREME) { case AcquiredInfo.TILT_TOO_EXTREME: return BiometricFaceConstants.FACE_ACQUIRED_TILT_TOO_EXTREME; return BiometricFaceConstants.FACE_ACQUIRED_TILT_TOO_EXTREME; } else if (aidlAcquired == AcquiredInfo.ROLL_TOO_EXTREME) { case AcquiredInfo.ROLL_TOO_EXTREME: return BiometricFaceConstants.FACE_ACQUIRED_ROLL_TOO_EXTREME; return BiometricFaceConstants.FACE_ACQUIRED_ROLL_TOO_EXTREME; } else if (aidlAcquired == AcquiredInfo.FACE_OBSCURED) { case AcquiredInfo.FACE_OBSCURED: return BiometricFaceConstants.FACE_ACQUIRED_FACE_OBSCURED; return BiometricFaceConstants.FACE_ACQUIRED_FACE_OBSCURED; } else if (aidlAcquired == AcquiredInfo.START) { case AcquiredInfo.START: return BiometricFaceConstants.FACE_ACQUIRED_START; return BiometricFaceConstants.FACE_ACQUIRED_START; } else if (aidlAcquired == AcquiredInfo.SENSOR_DIRTY) { case AcquiredInfo.SENSOR_DIRTY: return BiometricFaceConstants.FACE_ACQUIRED_SENSOR_DIRTY; return BiometricFaceConstants.FACE_ACQUIRED_SENSOR_DIRTY; } else if (aidlAcquired == AcquiredInfo.VENDOR) { case AcquiredInfo.VENDOR: return BiometricFaceConstants.FACE_ACQUIRED_VENDOR; return BiometricFaceConstants.FACE_ACQUIRED_VENDOR; } else if (aidlAcquired == AcquiredInfo.FIRST_FRAME_RECEIVED) { case AcquiredInfo.UNKNOWN: // No framework constant available case AcquiredInfo.FIRST_FRAME_RECEIVED: return BiometricFaceConstants.FACE_ACQUIRED_UNKNOWN; case AcquiredInfo.DARK_GLASSES_DETECTED: } else if (aidlAcquired == AcquiredInfo.DARK_GLASSES_DETECTED) { case AcquiredInfo.MOUTH_COVERING_DETECTED: // No framework constant available default: return BiometricFaceConstants.FACE_ACQUIRED_UNKNOWN; } else if (aidlAcquired == AcquiredInfo.MOUTH_COVERING_DETECTED) { // No framework constant available return BiometricFaceConstants.FACE_ACQUIRED_UNKNOWN; } else { return BiometricFaceConstants.FACE_ACQUIRED_UNKNOWN; return BiometricFaceConstants.FACE_ACQUIRED_UNKNOWN; } } } } @FaceEnrollStage public static int toFrameworkEnrollmentStage(int aidlEnrollmentStage) { switch (aidlEnrollmentStage) { case EnrollmentStage.FIRST_FRAME_RECEIVED: return FaceEnrollStages.FIRST_FRAME_RECEIVED; case EnrollmentStage.WAITING_FOR_CENTERING: return FaceEnrollStages.WAITING_FOR_CENTERING; case EnrollmentStage.HOLD_STILL_IN_CENTER: return FaceEnrollStages.HOLD_STILL_IN_CENTER; case EnrollmentStage.ENROLLING_MOVEMENT_1: return FaceEnrollStages.ENROLLING_MOVEMENT_1; case EnrollmentStage.ENROLLING_MOVEMENT_2: return FaceEnrollStages.ENROLLING_MOVEMENT_2; case EnrollmentStage.ENROLLMENT_FINISHED: return FaceEnrollStages.ENROLLMENT_FINISHED; case EnrollmentStage.UNKNOWN: default: return FaceEnrollStages.UNKNOWN; } } @NonNull @NonNull public static FaceAuthenticationFrame toFrameworkAuthenticationFrame( public static FaceAuthenticationFrame toFrameworkAuthenticationFrame( @NonNull AuthenticationFrame frame) { @NonNull AuthenticationFrame frame) { Loading @@ -135,7 +153,9 @@ final class AidlConversionUtils { @NonNull @NonNull public static FaceEnrollFrame toFrameworkEnrollmentFrame(@NonNull EnrollmentFrame frame) { public static FaceEnrollFrame toFrameworkEnrollmentFrame(@NonNull EnrollmentFrame frame) { return new FaceEnrollFrame(toFrameworkCell(frame.cell), frame.stage, return new FaceEnrollFrame( toFrameworkCell(frame.cell), toFrameworkEnrollmentStage(frame.stage), toFrameworkBaseFrame(frame.data)); toFrameworkBaseFrame(frame.data)); } } Loading Loading
core/java/android/hardware/face/FaceEnrollFrame.java +1 −0 Original line number Original line Diff line number Diff line Loading @@ -18,6 +18,7 @@ package android.hardware.face; import android.annotation.NonNull; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.Nullable; import android.hardware.face.FaceEnrollStages.FaceEnrollStage; import android.os.Parcel; import android.os.Parcel; import android.os.Parcelable; import android.os.Parcelable; Loading
core/java/android/hardware/face/FaceEnrollStage.java→core/java/android/hardware/face/FaceEnrollStages.java +29 −19 Original line number Original line Diff line number Diff line Loading @@ -21,54 +21,64 @@ import android.annotation.IntDef; import java.lang.annotation.Retention; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy; /** * A collection of constants representing different stages of face enrollment. * * @hide */ public final class FaceEnrollStages { // Prevent instantiation. private FaceEnrollStages() {} /** /** * A stage that may occur during face enrollment. * A stage that may occur during face enrollment. * * * @hide * @hide */ */ @Retention(RetentionPolicy.SOURCE) @IntDef({ @IntDef({ FaceEnrollStage.UNKNOWN, UNKNOWN, FaceEnrollStage.FIRST_FRAME_RECEIVED, FIRST_FRAME_RECEIVED, FaceEnrollStage.WAITING_FOR_CENTERING, WAITING_FOR_CENTERING, FaceEnrollStage.HOLD_STILL_IN_CENTER, HOLD_STILL_IN_CENTER, FaceEnrollStage.ENROLLING_MOVEMENT_1, ENROLLING_MOVEMENT_1, FaceEnrollStage.ENROLLING_MOVEMENT_2, ENROLLING_MOVEMENT_2, FaceEnrollStage.ENROLLMENT_FINISHED ENROLLMENT_FINISHED }) }) public @interface FaceEnrollStage { @Retention(RetentionPolicy.SOURCE) public @interface FaceEnrollStage {} /** /** * The current enrollment stage is not known. * The current enrollment stage is not known. */ */ int UNKNOWN = -1; public static final int UNKNOWN = 0; /** /** * Enrollment has just begun. No action is needed from the user yet. * Enrollment has just begun. No action is needed from the user yet. */ */ int FIRST_FRAME_RECEIVED = 0; public static final int FIRST_FRAME_RECEIVED = 1; /** /** * The user must center their face in the frame. * The user must center their face in the frame. */ */ int WAITING_FOR_CENTERING = 1; public static final int WAITING_FOR_CENTERING = 2; /** /** * The user must keep their face centered in the frame. * The user must keep their face centered in the frame. */ */ int HOLD_STILL_IN_CENTER = 2; public static final int HOLD_STILL_IN_CENTER = 3; /** /** * The user must follow a first set of movement instructions. * The user must follow a first set of movement instructions. */ */ int ENROLLING_MOVEMENT_1 = 3; public static final int ENROLLING_MOVEMENT_1 = 4; /** /** * The user must follow a second set of movement instructions. * The user must follow a second set of movement instructions. */ */ int ENROLLING_MOVEMENT_2 = 4; public static final int ENROLLING_MOVEMENT_2 = 5; /** /** * Enrollment has completed. No more action is needed from the user. * Enrollment has completed. No more action is needed from the user. */ */ int ENROLLMENT_FINISHED = 5; public static final int ENROLLMENT_FINISHED = 6; } }
core/java/android/hardware/face/FaceManager.java +40 −5 Original line number Original line Diff line number Diff line Loading @@ -1022,6 +1022,34 @@ public class FaceManager implements BiometricAuthenticator, BiometricFaceConstan public void onEnrollmentHelp(int helpMsgId, CharSequence helpString) { public void onEnrollmentHelp(int helpMsgId, CharSequence helpString) { } } /** * Called each time a single frame is captured during enrollment. * * <p>For older, non-AIDL implementations, only {@code helpCode} and {@code helpMessage} are * supported. Sensible default values will be provided for all other arguments. * * @param helpCode An integer identifying the capture status for this frame. * @param helpMessage A human-readable help string that can be shown in UI. * @param cell The cell captured during this frame of enrollment, if any. * @param stage An integer representing the current stage of enrollment. * @param pan The horizontal pan of the detected face. Values in the range [-1, 1] * indicate a good capture. * @param tilt The vertical tilt of the detected face. Values in the range [-1, 1] * indicate a good capture. * @param distance The distance of the detected face from the device. Values in * the range [-1, 1] indicate a good capture. */ public void onEnrollmentFrame( int helpCode, @Nullable CharSequence helpMessage, @Nullable FaceEnrollCell cell, @FaceEnrollStages.FaceEnrollStage int stage, float pan, float tilt, float distance) { onEnrollmentHelp(helpCode, helpMessage); } /** /** * Called as each enrollment step progresses. Enrollment is considered complete when * Called as each enrollment step progresses. Enrollment is considered complete when * remaining reaches 0. This function will not be called if enrollment fails. See * remaining reaches 0. This function will not be called if enrollment fails. See Loading Loading @@ -1305,7 +1333,7 @@ public class FaceManager implements BiometricAuthenticator, BiometricFaceConstan } else if (mEnrollmentCallback != null) { } else if (mEnrollmentCallback != null) { final FaceEnrollFrame frame = new FaceEnrollFrame( final FaceEnrollFrame frame = new FaceEnrollFrame( null /* cell */, null /* cell */, FaceEnrollStage.UNKNOWN, FaceEnrollStages.UNKNOWN, new FaceDataFrame(acquireInfo, vendorCode)); new FaceDataFrame(acquireInfo, vendorCode)); sendEnrollmentFrame(frame); sendEnrollmentFrame(frame); } } Loading Loading @@ -1333,12 +1361,19 @@ public class FaceManager implements BiometricAuthenticator, BiometricFaceConstan if (frame == null) { if (frame == null) { Slog.w(TAG, "Received null enrollment frame"); Slog.w(TAG, "Received null enrollment frame"); } else if (mEnrollmentCallback != null) { } else if (mEnrollmentCallback != null) { // TODO(b/178414967): Send additional frame data to callback final FaceDataFrame data = frame.getData(); final int acquireInfo = frame.getData().getAcquiredInfo(); final int acquireInfo = data.getAcquiredInfo(); final int vendorCode = frame.getData().getVendorCode(); final int vendorCode = data.getVendorCode(); final int helpCode = getHelpCode(acquireInfo, vendorCode); final int helpCode = getHelpCode(acquireInfo, vendorCode); final String helpMessage = getEnrollHelpMessage(mContext, acquireInfo, vendorCode); final String helpMessage = getEnrollHelpMessage(mContext, acquireInfo, vendorCode); mEnrollmentCallback.onEnrollmentHelp(helpCode, helpMessage); mEnrollmentCallback.onEnrollmentFrame( helpCode, helpMessage, frame.getCell(), frame.getStage(), data.getPan(), data.getTilt(), data.getDistance()); } } } } Loading
services/core/java/com/android/server/biometrics/sensors/face/aidl/AidlConversionUtils.java +104 −84 Original line number Original line Diff line number Diff line Loading @@ -24,11 +24,14 @@ import android.hardware.biometrics.face.AuthenticationFrame; import android.hardware.biometrics.face.BaseFrame; import android.hardware.biometrics.face.BaseFrame; import android.hardware.biometrics.face.Cell; import android.hardware.biometrics.face.Cell; import android.hardware.biometrics.face.EnrollmentFrame; import android.hardware.biometrics.face.EnrollmentFrame; import android.hardware.biometrics.face.EnrollmentStage; import android.hardware.biometrics.face.Error; import android.hardware.biometrics.face.Error; import android.hardware.face.FaceAuthenticationFrame; import android.hardware.face.FaceAuthenticationFrame; import android.hardware.face.FaceDataFrame; import android.hardware.face.FaceDataFrame; import android.hardware.face.FaceEnrollCell; import android.hardware.face.FaceEnrollCell; import android.hardware.face.FaceEnrollFrame; import android.hardware.face.FaceEnrollFrame; import android.hardware.face.FaceEnrollStages; import android.hardware.face.FaceEnrollStages.FaceEnrollStage; /** /** * Utilities for converting from hardware to framework-defined AIDL models. * Utilities for converting from hardware to framework-defined AIDL models. Loading @@ -38,95 +41,110 @@ final class AidlConversionUtils { private AidlConversionUtils() { private AidlConversionUtils() { } } public static @BiometricFaceConstants.FaceError int toFrameworkError(byte aidlError) { @BiometricFaceConstants.FaceError if (aidlError == Error.UNKNOWN) { public static int toFrameworkError(byte aidlError) { // No framework constant available switch (aidlError) { return BiometricFaceConstants.FACE_ERROR_UNKNOWN; case Error.HW_UNAVAILABLE: } else if (aidlError == Error.HW_UNAVAILABLE) { return BiometricFaceConstants.FACE_ERROR_HW_UNAVAILABLE; return BiometricFaceConstants.FACE_ERROR_HW_UNAVAILABLE; } else if (aidlError == Error.UNABLE_TO_PROCESS) { case Error.UNABLE_TO_PROCESS: return BiometricFaceConstants.FACE_ERROR_UNABLE_TO_PROCESS; return BiometricFaceConstants.FACE_ERROR_UNABLE_TO_PROCESS; } else if (aidlError == Error.TIMEOUT) { case Error.TIMEOUT: return BiometricFaceConstants.FACE_ERROR_TIMEOUT; return BiometricFaceConstants.FACE_ERROR_TIMEOUT; } else if (aidlError == Error.NO_SPACE) { case Error.NO_SPACE: return BiometricFaceConstants.FACE_ERROR_NO_SPACE; return BiometricFaceConstants.FACE_ERROR_NO_SPACE; } else if (aidlError == Error.CANCELED) { case Error.CANCELED: return BiometricFaceConstants.FACE_ERROR_CANCELED; return BiometricFaceConstants.FACE_ERROR_CANCELED; } else if (aidlError == Error.UNABLE_TO_REMOVE) { case Error.UNABLE_TO_REMOVE: return BiometricFaceConstants.FACE_ERROR_UNABLE_TO_REMOVE; return BiometricFaceConstants.FACE_ERROR_UNABLE_TO_REMOVE; } else if (aidlError == Error.VENDOR) { case Error.VENDOR: return BiometricFaceConstants.FACE_ERROR_VENDOR; return BiometricFaceConstants.FACE_ERROR_VENDOR; } else if (aidlError == Error.REENROLL_REQUIRED) { case Error.REENROLL_REQUIRED: return BiometricFaceConstants.BIOMETRIC_ERROR_RE_ENROLL; return BiometricFaceConstants.BIOMETRIC_ERROR_RE_ENROLL; } else { case Error.UNKNOWN: default: return BiometricFaceConstants.FACE_ERROR_UNKNOWN; return BiometricFaceConstants.FACE_ERROR_UNKNOWN; } } } } public static @BiometricFaceConstants.FaceAcquired int toFrameworkAcquiredInfo( @BiometricFaceConstants.FaceAcquired byte aidlAcquired) { public static int toFrameworkAcquiredInfo(byte aidlAcquiredInfo) { if (aidlAcquired == AcquiredInfo.UNKNOWN) { switch (aidlAcquiredInfo) { return BiometricFaceConstants.FACE_ACQUIRED_UNKNOWN; case AcquiredInfo.GOOD: } else if (aidlAcquired == AcquiredInfo.GOOD) { return BiometricFaceConstants.FACE_ACQUIRED_GOOD; return BiometricFaceConstants.FACE_ACQUIRED_GOOD; } else if (aidlAcquired == AcquiredInfo.INSUFFICIENT) { case AcquiredInfo.INSUFFICIENT: return BiometricFaceConstants.FACE_ACQUIRED_INSUFFICIENT; return BiometricFaceConstants.FACE_ACQUIRED_INSUFFICIENT; } else if (aidlAcquired == AcquiredInfo.TOO_BRIGHT) { case AcquiredInfo.TOO_BRIGHT: return BiometricFaceConstants.FACE_ACQUIRED_TOO_BRIGHT; return BiometricFaceConstants.FACE_ACQUIRED_TOO_BRIGHT; } else if (aidlAcquired == AcquiredInfo.TOO_DARK) { case AcquiredInfo.TOO_DARK: return BiometricFaceConstants.FACE_ACQUIRED_TOO_DARK; return BiometricFaceConstants.FACE_ACQUIRED_TOO_DARK; } else if (aidlAcquired == AcquiredInfo.TOO_CLOSE) { case AcquiredInfo.TOO_CLOSE: return BiometricFaceConstants.FACE_ACQUIRED_TOO_CLOSE; return BiometricFaceConstants.FACE_ACQUIRED_TOO_CLOSE; } else if (aidlAcquired == AcquiredInfo.TOO_FAR) { case AcquiredInfo.TOO_FAR: return BiometricFaceConstants.FACE_ACQUIRED_TOO_FAR; return BiometricFaceConstants.FACE_ACQUIRED_TOO_FAR; } else if (aidlAcquired == AcquiredInfo.FACE_TOO_HIGH) { case AcquiredInfo.FACE_TOO_HIGH: return BiometricFaceConstants.FACE_ACQUIRED_TOO_HIGH; return BiometricFaceConstants.FACE_ACQUIRED_TOO_HIGH; } else if (aidlAcquired == AcquiredInfo.FACE_TOO_LOW) { case AcquiredInfo.FACE_TOO_LOW: return BiometricFaceConstants.FACE_ACQUIRED_TOO_LOW; return BiometricFaceConstants.FACE_ACQUIRED_TOO_LOW; } else if (aidlAcquired == AcquiredInfo.FACE_TOO_RIGHT) { case AcquiredInfo.FACE_TOO_RIGHT: return BiometricFaceConstants.FACE_ACQUIRED_TOO_RIGHT; return BiometricFaceConstants.FACE_ACQUIRED_TOO_RIGHT; } else if (aidlAcquired == AcquiredInfo.FACE_TOO_LEFT) { case AcquiredInfo.FACE_TOO_LEFT: return BiometricFaceConstants.FACE_ACQUIRED_TOO_LEFT; return BiometricFaceConstants.FACE_ACQUIRED_TOO_LEFT; } else if (aidlAcquired == AcquiredInfo.POOR_GAZE) { case AcquiredInfo.POOR_GAZE: return BiometricFaceConstants.FACE_ACQUIRED_POOR_GAZE; return BiometricFaceConstants.FACE_ACQUIRED_POOR_GAZE; } else if (aidlAcquired == AcquiredInfo.NOT_DETECTED) { case AcquiredInfo.NOT_DETECTED: return BiometricFaceConstants.FACE_ACQUIRED_NOT_DETECTED; return BiometricFaceConstants.FACE_ACQUIRED_NOT_DETECTED; } else if (aidlAcquired == AcquiredInfo.TOO_MUCH_MOTION) { case AcquiredInfo.TOO_MUCH_MOTION: return BiometricFaceConstants.FACE_ACQUIRED_TOO_MUCH_MOTION; return BiometricFaceConstants.FACE_ACQUIRED_TOO_MUCH_MOTION; } else if (aidlAcquired == AcquiredInfo.RECALIBRATE) { case AcquiredInfo.RECALIBRATE: return BiometricFaceConstants.FACE_ACQUIRED_RECALIBRATE; return BiometricFaceConstants.FACE_ACQUIRED_RECALIBRATE; } else if (aidlAcquired == AcquiredInfo.TOO_DIFFERENT) { case AcquiredInfo.TOO_DIFFERENT: return BiometricFaceConstants.FACE_ACQUIRED_TOO_DIFFERENT; return BiometricFaceConstants.FACE_ACQUIRED_TOO_DIFFERENT; } else if (aidlAcquired == AcquiredInfo.TOO_SIMILAR) { case AcquiredInfo.TOO_SIMILAR: return BiometricFaceConstants.FACE_ACQUIRED_TOO_SIMILAR; return BiometricFaceConstants.FACE_ACQUIRED_TOO_SIMILAR; } else if (aidlAcquired == AcquiredInfo.PAN_TOO_EXTREME) { case AcquiredInfo.PAN_TOO_EXTREME: return BiometricFaceConstants.FACE_ACQUIRED_PAN_TOO_EXTREME; return BiometricFaceConstants.FACE_ACQUIRED_PAN_TOO_EXTREME; } else if (aidlAcquired == AcquiredInfo.TILT_TOO_EXTREME) { case AcquiredInfo.TILT_TOO_EXTREME: return BiometricFaceConstants.FACE_ACQUIRED_TILT_TOO_EXTREME; return BiometricFaceConstants.FACE_ACQUIRED_TILT_TOO_EXTREME; } else if (aidlAcquired == AcquiredInfo.ROLL_TOO_EXTREME) { case AcquiredInfo.ROLL_TOO_EXTREME: return BiometricFaceConstants.FACE_ACQUIRED_ROLL_TOO_EXTREME; return BiometricFaceConstants.FACE_ACQUIRED_ROLL_TOO_EXTREME; } else if (aidlAcquired == AcquiredInfo.FACE_OBSCURED) { case AcquiredInfo.FACE_OBSCURED: return BiometricFaceConstants.FACE_ACQUIRED_FACE_OBSCURED; return BiometricFaceConstants.FACE_ACQUIRED_FACE_OBSCURED; } else if (aidlAcquired == AcquiredInfo.START) { case AcquiredInfo.START: return BiometricFaceConstants.FACE_ACQUIRED_START; return BiometricFaceConstants.FACE_ACQUIRED_START; } else if (aidlAcquired == AcquiredInfo.SENSOR_DIRTY) { case AcquiredInfo.SENSOR_DIRTY: return BiometricFaceConstants.FACE_ACQUIRED_SENSOR_DIRTY; return BiometricFaceConstants.FACE_ACQUIRED_SENSOR_DIRTY; } else if (aidlAcquired == AcquiredInfo.VENDOR) { case AcquiredInfo.VENDOR: return BiometricFaceConstants.FACE_ACQUIRED_VENDOR; return BiometricFaceConstants.FACE_ACQUIRED_VENDOR; } else if (aidlAcquired == AcquiredInfo.FIRST_FRAME_RECEIVED) { case AcquiredInfo.UNKNOWN: // No framework constant available case AcquiredInfo.FIRST_FRAME_RECEIVED: return BiometricFaceConstants.FACE_ACQUIRED_UNKNOWN; case AcquiredInfo.DARK_GLASSES_DETECTED: } else if (aidlAcquired == AcquiredInfo.DARK_GLASSES_DETECTED) { case AcquiredInfo.MOUTH_COVERING_DETECTED: // No framework constant available default: return BiometricFaceConstants.FACE_ACQUIRED_UNKNOWN; } else if (aidlAcquired == AcquiredInfo.MOUTH_COVERING_DETECTED) { // No framework constant available return BiometricFaceConstants.FACE_ACQUIRED_UNKNOWN; } else { return BiometricFaceConstants.FACE_ACQUIRED_UNKNOWN; return BiometricFaceConstants.FACE_ACQUIRED_UNKNOWN; } } } } @FaceEnrollStage public static int toFrameworkEnrollmentStage(int aidlEnrollmentStage) { switch (aidlEnrollmentStage) { case EnrollmentStage.FIRST_FRAME_RECEIVED: return FaceEnrollStages.FIRST_FRAME_RECEIVED; case EnrollmentStage.WAITING_FOR_CENTERING: return FaceEnrollStages.WAITING_FOR_CENTERING; case EnrollmentStage.HOLD_STILL_IN_CENTER: return FaceEnrollStages.HOLD_STILL_IN_CENTER; case EnrollmentStage.ENROLLING_MOVEMENT_1: return FaceEnrollStages.ENROLLING_MOVEMENT_1; case EnrollmentStage.ENROLLING_MOVEMENT_2: return FaceEnrollStages.ENROLLING_MOVEMENT_2; case EnrollmentStage.ENROLLMENT_FINISHED: return FaceEnrollStages.ENROLLMENT_FINISHED; case EnrollmentStage.UNKNOWN: default: return FaceEnrollStages.UNKNOWN; } } @NonNull @NonNull public static FaceAuthenticationFrame toFrameworkAuthenticationFrame( public static FaceAuthenticationFrame toFrameworkAuthenticationFrame( @NonNull AuthenticationFrame frame) { @NonNull AuthenticationFrame frame) { Loading @@ -135,7 +153,9 @@ final class AidlConversionUtils { @NonNull @NonNull public static FaceEnrollFrame toFrameworkEnrollmentFrame(@NonNull EnrollmentFrame frame) { public static FaceEnrollFrame toFrameworkEnrollmentFrame(@NonNull EnrollmentFrame frame) { return new FaceEnrollFrame(toFrameworkCell(frame.cell), frame.stage, return new FaceEnrollFrame( toFrameworkCell(frame.cell), toFrameworkEnrollmentStage(frame.stage), toFrameworkBaseFrame(frame.data)); toFrameworkBaseFrame(frame.data)); } } Loading