From 4f54f79586184e67ca98de3fc48e27cb64426605 Mon Sep 17 00:00:00 2001 From: Curtis Belmonte Date: Tue, 9 Feb 2021 15:29:35 -0800 Subject: [PATCH] Split acquire messages for face auth and enrollment Updates FaceManager to distinguish between face enrollment and authentication when producing help messages, returning more detailed messages for the former and less noisy ones for the latter. Test: Manually tested face enrollment and authentication. Bug: 179044580 Change-Id: I406b371804de94383e65a077380b26bfb9ecf5e7 --- .../android/hardware/face/FaceManager.java | 185 ++++++++++++------ .../server/biometrics/AuthSession.java | 2 +- 2 files changed, 123 insertions(+), 64 deletions(-) diff --git a/core/java/android/hardware/face/FaceManager.java b/core/java/android/hardware/face/FaceManager.java index f3da6a9d4a030..886a8c1fdae57 100644 --- a/core/java/android/hardware/face/FaceManager.java +++ b/core/java/android/hardware/face/FaceManager.java @@ -832,67 +832,6 @@ public class FaceManager implements BiometricAuthenticator, BiometricFaceConstan return ""; } - /** - * @hide - */ - public static String getAcquiredString(Context context, int acquireInfo, int vendorCode) { - switch (acquireInfo) { - case FACE_ACQUIRED_GOOD: - return null; - case FACE_ACQUIRED_INSUFFICIENT: - return context.getString(R.string.face_acquired_insufficient); - case FACE_ACQUIRED_TOO_BRIGHT: - return context.getString(R.string.face_acquired_too_bright); - case FACE_ACQUIRED_TOO_DARK: - return context.getString(R.string.face_acquired_too_dark); - case FACE_ACQUIRED_TOO_CLOSE: - return context.getString(R.string.face_acquired_too_close); - case FACE_ACQUIRED_TOO_FAR: - return context.getString(R.string.face_acquired_too_far); - case FACE_ACQUIRED_TOO_HIGH: - return context.getString(R.string.face_acquired_too_high); - case FACE_ACQUIRED_TOO_LOW: - return context.getString(R.string.face_acquired_too_low); - case FACE_ACQUIRED_TOO_RIGHT: - return context.getString(R.string.face_acquired_too_right); - case FACE_ACQUIRED_TOO_LEFT: - return context.getString(R.string.face_acquired_too_left); - case FACE_ACQUIRED_POOR_GAZE: - return context.getString(R.string.face_acquired_poor_gaze); - case FACE_ACQUIRED_NOT_DETECTED: - return context.getString(R.string.face_acquired_not_detected); - case FACE_ACQUIRED_TOO_MUCH_MOTION: - return context.getString(R.string.face_acquired_too_much_motion); - case FACE_ACQUIRED_RECALIBRATE: - return context.getString(R.string.face_acquired_recalibrate); - case FACE_ACQUIRED_TOO_DIFFERENT: - return context.getString(R.string.face_acquired_too_different); - case FACE_ACQUIRED_TOO_SIMILAR: - return context.getString(R.string.face_acquired_too_similar); - case FACE_ACQUIRED_PAN_TOO_EXTREME: - return context.getString(R.string.face_acquired_pan_too_extreme); - case FACE_ACQUIRED_TILT_TOO_EXTREME: - return context.getString(R.string.face_acquired_tilt_too_extreme); - case FACE_ACQUIRED_ROLL_TOO_EXTREME: - return context.getString(R.string.face_acquired_roll_too_extreme); - case FACE_ACQUIRED_FACE_OBSCURED: - return context.getString(R.string.face_acquired_obscured); - case FACE_ACQUIRED_START: - return null; - case FACE_ACQUIRED_SENSOR_DIRTY: - return context.getString(R.string.face_acquired_sensor_dirty); - case FACE_ACQUIRED_VENDOR: { - String[] msgArray = context.getResources().getStringArray( - R.array.face_acquired_vendor); - if (vendorCode < msgArray.length) { - return msgArray[vendorCode]; - } - } - } - Slog.w(TAG, "Invalid acquired message: " + acquireInfo + ", " + vendorCode); - return null; - } - /** * Used so BiometricPrompt can map the face ones onto existing public constants. * @hide @@ -1387,7 +1326,7 @@ public class FaceManager implements BiometricAuthenticator, BiometricFaceConstan final int acquireInfo = frame.getData().getAcquiredInfo(); final int vendorCode = frame.getData().getVendorCode(); final int helpCode = getHelpCode(acquireInfo, vendorCode); - final String helpMessage = getAcquiredString(mContext, acquireInfo, vendorCode); + final String helpMessage = getAuthHelpMessage(mContext, acquireInfo, vendorCode); mAuthenticationCallback.onAuthenticationAcquired(acquireInfo); // Ensure that only non-null help messages are sent. @@ -1405,7 +1344,7 @@ public class FaceManager implements BiometricAuthenticator, BiometricFaceConstan final int acquireInfo = frame.getData().getAcquiredInfo(); final int vendorCode = frame.getData().getVendorCode(); final int helpCode = getHelpCode(acquireInfo, vendorCode); - final String helpMessage = getAcquiredString(mContext, acquireInfo, vendorCode); + final String helpMessage = getEnrollHelpMessage(mContext, acquireInfo, vendorCode); mEnrollmentCallback.onEnrollmentHelp(helpCode, helpMessage); } } @@ -1415,4 +1354,124 @@ public class FaceManager implements BiometricAuthenticator, BiometricFaceConstan ? vendorCode + FACE_ACQUIRED_VENDOR_BASE : acquireInfo; } + + /** + * @hide + */ + @Nullable + public static String getAuthHelpMessage(Context context, int acquireInfo, int vendorCode) { + switch (acquireInfo) { + // No help message is needed for a good capture. + case FACE_ACQUIRED_GOOD: + case FACE_ACQUIRED_START: + return null; + + // Consolidate positional feedback to reduce noise during authentication. + case FACE_ACQUIRED_NOT_DETECTED: + case FACE_ACQUIRED_TOO_CLOSE: + case FACE_ACQUIRED_TOO_FAR: + case FACE_ACQUIRED_TOO_HIGH: + case FACE_ACQUIRED_TOO_LOW: + case FACE_ACQUIRED_TOO_RIGHT: + case FACE_ACQUIRED_TOO_LEFT: + case FACE_ACQUIRED_POOR_GAZE: + case FACE_ACQUIRED_PAN_TOO_EXTREME: + case FACE_ACQUIRED_TILT_TOO_EXTREME: + case FACE_ACQUIRED_ROLL_TOO_EXTREME: + return context.getString(R.string.face_acquired_not_detected); + + // Provide more detailed feedback for other soft errors. + case FACE_ACQUIRED_INSUFFICIENT: + return context.getString(R.string.face_acquired_insufficient); + case FACE_ACQUIRED_TOO_BRIGHT: + return context.getString(R.string.face_acquired_too_bright); + case FACE_ACQUIRED_TOO_DARK: + return context.getString(R.string.face_acquired_too_dark); + case FACE_ACQUIRED_TOO_MUCH_MOTION: + return context.getString(R.string.face_acquired_too_much_motion); + case FACE_ACQUIRED_RECALIBRATE: + return context.getString(R.string.face_acquired_recalibrate); + case FACE_ACQUIRED_TOO_DIFFERENT: + return context.getString(R.string.face_acquired_too_different); + case FACE_ACQUIRED_TOO_SIMILAR: + return context.getString(R.string.face_acquired_too_similar); + case FACE_ACQUIRED_FACE_OBSCURED: + return context.getString(R.string.face_acquired_obscured); + case FACE_ACQUIRED_SENSOR_DIRTY: + return context.getString(R.string.face_acquired_sensor_dirty); + + // Find and return the appropriate vendor-specific message. + case FACE_ACQUIRED_VENDOR: { + String[] msgArray = context.getResources().getStringArray( + R.array.face_acquired_vendor); + if (vendorCode < msgArray.length) { + return msgArray[vendorCode]; + } + } + } + + Slog.w(TAG, "Unknown authentication acquired message: " + acquireInfo + ", " + vendorCode); + return null; + } + + /** + * @hide + */ + @Nullable + public static String getEnrollHelpMessage(Context context, int acquireInfo, int vendorCode) { + switch (acquireInfo) { + case FACE_ACQUIRED_GOOD: + case FACE_ACQUIRED_START: + return null; + case FACE_ACQUIRED_INSUFFICIENT: + return context.getString(R.string.face_acquired_insufficient); + case FACE_ACQUIRED_TOO_BRIGHT: + return context.getString(R.string.face_acquired_too_bright); + case FACE_ACQUIRED_TOO_DARK: + return context.getString(R.string.face_acquired_too_dark); + case FACE_ACQUIRED_TOO_CLOSE: + return context.getString(R.string.face_acquired_too_close); + case FACE_ACQUIRED_TOO_FAR: + return context.getString(R.string.face_acquired_too_far); + case FACE_ACQUIRED_TOO_HIGH: + return context.getString(R.string.face_acquired_too_high); + case FACE_ACQUIRED_TOO_LOW: + return context.getString(R.string.face_acquired_too_low); + case FACE_ACQUIRED_TOO_RIGHT: + return context.getString(R.string.face_acquired_too_right); + case FACE_ACQUIRED_TOO_LEFT: + return context.getString(R.string.face_acquired_too_left); + case FACE_ACQUIRED_POOR_GAZE: + return context.getString(R.string.face_acquired_poor_gaze); + case FACE_ACQUIRED_NOT_DETECTED: + return context.getString(R.string.face_acquired_not_detected); + case FACE_ACQUIRED_TOO_MUCH_MOTION: + return context.getString(R.string.face_acquired_too_much_motion); + case FACE_ACQUIRED_RECALIBRATE: + return context.getString(R.string.face_acquired_recalibrate); + case FACE_ACQUIRED_TOO_DIFFERENT: + return context.getString(R.string.face_acquired_too_different); + case FACE_ACQUIRED_TOO_SIMILAR: + return context.getString(R.string.face_acquired_too_similar); + case FACE_ACQUIRED_PAN_TOO_EXTREME: + return context.getString(R.string.face_acquired_pan_too_extreme); + case FACE_ACQUIRED_TILT_TOO_EXTREME: + return context.getString(R.string.face_acquired_tilt_too_extreme); + case FACE_ACQUIRED_ROLL_TOO_EXTREME: + return context.getString(R.string.face_acquired_roll_too_extreme); + case FACE_ACQUIRED_FACE_OBSCURED: + return context.getString(R.string.face_acquired_obscured); + case FACE_ACQUIRED_SENSOR_DIRTY: + return context.getString(R.string.face_acquired_sensor_dirty); + case FACE_ACQUIRED_VENDOR: { + String[] msgArray = context.getResources().getStringArray( + R.array.face_acquired_vendor); + if (vendorCode < msgArray.length) { + return msgArray[vendorCode]; + } + } + } + Slog.w(TAG, "Unknown enrollment acquired message: " + acquireInfo + ", " + vendorCode); + return null; + } } diff --git a/services/core/java/com/android/server/biometrics/AuthSession.java b/services/core/java/com/android/server/biometrics/AuthSession.java index c9560437799e2..bb3d7a07ba366 100644 --- a/services/core/java/com/android/server/biometrics/AuthSession.java +++ b/services/core/java/com/android/server/biometrics/AuthSession.java @@ -794,7 +794,7 @@ public final class AuthSession implements IBinder.DeathRecipient { case BiometricAuthenticator.TYPE_FINGERPRINT: return FingerprintManager.getAcquiredString(mContext, acquiredInfo, vendorCode); case BiometricAuthenticator.TYPE_FACE: - return FaceManager.getAcquiredString(mContext, acquiredInfo, vendorCode); + return FaceManager.getAuthHelpMessage(mContext, acquiredInfo, vendorCode); default: return null; }