diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsEnrollHelper.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsEnrollHelper.java index 412b776981592..6a918a6c8d39d 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsEnrollHelper.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsEnrollHelper.java @@ -21,11 +21,8 @@ import android.annotation.Nullable; import android.content.Context; import android.graphics.PointF; import android.hardware.fingerprint.IUdfpsOverlayController; -import android.media.AudioAttributes; import android.os.Build; import android.os.UserHandle; -import android.os.VibrationEffect; -import android.os.Vibrator; import android.provider.Settings; import android.util.Log; import android.util.TypedValue; @@ -50,12 +47,6 @@ public class UdfpsEnrollHelper { // Enroll with two center touches before going to guided enrollment private static final int NUM_CENTER_TOUCHES = 2; - private static final AudioAttributes VIBRATION_SONFICATION_ATTRIBUTES = - new AudioAttributes.Builder() - .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION) - .setUsage(AudioAttributes.USAGE_ASSISTANCE_SONIFICATION) - .build(); - interface Listener { void onEnrollmentProgress(int remaining, int totalSteps); void onLastStepAcquired(); @@ -66,9 +57,6 @@ public class UdfpsEnrollHelper { private final int mEnrollReason; private final boolean mAccessibilityEnabled; @NonNull private final List mGuidedEnrollmentPoints; - @NonNull private final Vibrator mVibrator; - @NonNull private final VibrationEffect mEffectClick = - VibrationEffect.get(VibrationEffect.EFFECT_CLICK); private int mTotalSteps = -1; private int mRemainingSteps = -1; @@ -82,7 +70,6 @@ public class UdfpsEnrollHelper { public UdfpsEnrollHelper(@NonNull Context context, int reason) { mContext = context; mEnrollReason = reason; - mVibrator = context.getSystemService(Vibrator.class); final AccessibilityManager am = context.getSystemService(AccessibilityManager.class); mAccessibilityEnabled = am.isEnabled(); @@ -141,7 +128,6 @@ public class UdfpsEnrollHelper { if (remaining != mRemainingSteps) { mLocationsEnrolled++; - vibrateSuccess(); } mRemainingSteps = remaining; @@ -202,11 +188,6 @@ public class UdfpsEnrollHelper { if (mRemainingSteps <= 2 && mRemainingSteps >= 0) { mListener.onLastStepAcquired(); - vibrateSuccess(); } } - - private void vibrateSuccess() { - mVibrator.vibrate(mEffectClick, VIBRATION_SONFICATION_ATTRIBUTES); - } } diff --git a/services/core/java/com/android/server/biometrics/sensors/AcquisitionClient.java b/services/core/java/com/android/server/biometrics/sensors/AcquisitionClient.java index f11fe8aee64f3..c2eb06262edd5 100644 --- a/services/core/java/com/android/server/biometrics/sensors/AcquisitionClient.java +++ b/services/core/java/com/android/server/biometrics/sensors/AcquisitionClient.java @@ -22,6 +22,7 @@ import android.hardware.biometrics.BiometricConstants; import android.media.AudioAttributes; import android.os.IBinder; import android.os.PowerManager; +import android.os.Process; import android.os.RemoteException; import android.os.SystemClock; import android.os.VibrationEffect; @@ -49,6 +50,8 @@ public abstract class AcquisitionClient extends HalClientMonitor implement VibrationEffect.get(VibrationEffect.EFFECT_DOUBLE_CLICK); private final PowerManager mPowerManager; + // If haptics should occur when auth result (success/reject) is known + protected final boolean mShouldVibrate; private boolean mShouldSendErrorToClient = true; private boolean mAlreadyCancelled; @@ -59,11 +62,12 @@ public abstract class AcquisitionClient extends HalClientMonitor implement public AcquisitionClient(@NonNull Context context, @NonNull LazyDaemon lazyDaemon, @NonNull IBinder token, @NonNull ClientMonitorCallbackConverter listener, int userId, - @NonNull String owner, int cookie, int sensorId, int statsModality, - int statsAction, int statsClient) { + @NonNull String owner, int cookie, int sensorId, boolean shouldVibrate, + int statsModality, int statsAction, int statsClient) { super(context, lazyDaemon, token, listener, userId, owner, cookie, sensorId, statsModality, statsAction, statsClient); mPowerManager = context.getSystemService(PowerManager.class); + mShouldVibrate = shouldVibrate; } @Override @@ -191,14 +195,22 @@ public abstract class AcquisitionClient extends HalClientMonitor implement protected final void vibrateSuccess() { Vibrator vibrator = getContext().getSystemService(Vibrator.class); if (vibrator != null) { - vibrator.vibrate(SUCCESS_VIBRATION_EFFECT, VIBRATION_SONIFICATION_ATTRIBUTES); + vibrator.vibrate(Process.myUid(), + getContext().getOpPackageName(), + SUCCESS_VIBRATION_EFFECT, + getClass().getSimpleName() + "::success", + VIBRATION_SONIFICATION_ATTRIBUTES); } } protected final void vibrateError() { Vibrator vibrator = getContext().getSystemService(Vibrator.class); if (vibrator != null) { - vibrator.vibrate(ERROR_VIBRATION_EFFECT, VIBRATION_SONIFICATION_ATTRIBUTES); + vibrator.vibrate(Process.myUid(), + getContext().getOpPackageName(), + ERROR_VIBRATION_EFFECT, + getClass().getSimpleName() + "::error", + VIBRATION_SONIFICATION_ATTRIBUTES); } } } diff --git a/services/core/java/com/android/server/biometrics/sensors/AuthenticationClient.java b/services/core/java/com/android/server/biometrics/sensors/AuthenticationClient.java index 80e60e67f05a6..3e6602e3175ad 100644 --- a/services/core/java/com/android/server/biometrics/sensors/AuthenticationClient.java +++ b/services/core/java/com/android/server/biometrics/sensors/AuthenticationClient.java @@ -68,9 +68,11 @@ public abstract class AuthenticationClient extends AcquisitionClient int targetUserId, long operationId, boolean restricted, @NonNull String owner, int cookie, boolean requireConfirmation, int sensorId, boolean isStrongBiometric, int statsModality, int statsClient, @Nullable TaskStackListener taskStackListener, - @NonNull LockoutTracker lockoutTracker, boolean allowBackgroundAuthentication) { + @NonNull LockoutTracker lockoutTracker, boolean allowBackgroundAuthentication, + boolean shouldVibrate) { super(context, lazyDaemon, token, listener, targetUserId, owner, cookie, sensorId, - statsModality, BiometricsProtoEnums.ACTION_AUTHENTICATE, statsClient); + shouldVibrate, statsModality, BiometricsProtoEnums.ACTION_AUTHENTICATE, + statsClient); mIsStrongBiometric = isStrongBiometric; mOperationId = operationId; mRequireConfirmation = requireConfirmation; @@ -204,7 +206,7 @@ public abstract class AuthenticationClient extends AcquisitionClient mAlreadyDone = true; - if (listener != null) { + if (listener != null && mShouldVibrate) { vibrateSuccess(); } @@ -250,7 +252,7 @@ public abstract class AuthenticationClient extends AcquisitionClient Slog.w(TAG, "Client not listening"); } } else { - if (listener != null) { + if (listener != null && mShouldVibrate) { vibrateError(); } diff --git a/services/core/java/com/android/server/biometrics/sensors/EnrollClient.java b/services/core/java/com/android/server/biometrics/sensors/EnrollClient.java index e1320d8e1a4f1..a15e14b79e301 100644 --- a/services/core/java/com/android/server/biometrics/sensors/EnrollClient.java +++ b/services/core/java/com/android/server/biometrics/sensors/EnrollClient.java @@ -38,7 +38,6 @@ public abstract class EnrollClient extends AcquisitionClient { protected final byte[] mHardwareAuthToken; protected final int mTimeoutSec; protected final BiometricUtils mBiometricUtils; - private final boolean mShouldVibrate; private long mEnrollmentStartTimeMs; @@ -50,15 +49,13 @@ public abstract class EnrollClient extends AcquisitionClient { public EnrollClient(@NonNull Context context, @NonNull LazyDaemon lazyDaemon, @NonNull IBinder token, @NonNull ClientMonitorCallbackConverter listener, int userId, @NonNull byte[] hardwareAuthToken, @NonNull String owner, @NonNull BiometricUtils utils, - int timeoutSec, int statsModality, int sensorId, - boolean shouldVibrate) { + int timeoutSec, int statsModality, int sensorId, boolean shouldVibrate) { super(context, lazyDaemon, token, listener, userId, owner, 0 /* cookie */, sensorId, - statsModality, BiometricsProtoEnums.ACTION_ENROLL, + shouldVibrate, statsModality, BiometricsProtoEnums.ACTION_ENROLL, BiometricsProtoEnums.CLIENT_UNKNOWN); mBiometricUtils = utils; mHardwareAuthToken = Arrays.copyOf(hardwareAuthToken, hardwareAuthToken.length); mTimeoutSec = timeoutSec; - mShouldVibrate = shouldVibrate; } public void onEnrollResult(BiometricAuthenticator.Identifier identifier, int remaining) { diff --git a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceAuthenticationClient.java b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceAuthenticationClient.java index 3757404d226d9..0525d2da69880 100644 --- a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceAuthenticationClient.java +++ b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceAuthenticationClient.java @@ -73,7 +73,7 @@ class FaceAuthenticationClient extends AuthenticationClient implements super(context, lazyDaemon, token, listener, targetUserId, operationId, restricted, owner, cookie, requireConfirmation, sensorId, isStrongBiometric, BiometricsProtoEnums.MODALITY_FACE, statsClient, null /* taskStackListener */, - lockoutCache, allowBackgroundAuthentication); + lockoutCache, allowBackgroundAuthentication, true /* shouldVibrate */); mUsageStats = usageStats; mLockoutCache = lockoutCache; mNotificationManager = context.getSystemService(NotificationManager.class); diff --git a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceDetectClient.java b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceDetectClient.java index cb966e7b47a96..1e73ac528f088 100644 --- a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceDetectClient.java +++ b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceDetectClient.java @@ -46,8 +46,8 @@ public class FaceDetectClient extends AcquisitionClient implements Det @NonNull IBinder token, @NonNull ClientMonitorCallbackConverter listener, int userId, @NonNull String owner, int sensorId, boolean isStrongBiometric, int statsClient) { super(context, lazyDaemon, token, listener, userId, owner, 0 /* cookie */, sensorId, - BiometricsProtoEnums.MODALITY_FACE, BiometricsProtoEnums.ACTION_AUTHENTICATE, - statsClient); + true /* shouldVibrate */, BiometricsProtoEnums.MODALITY_FACE, + BiometricsProtoEnums.ACTION_AUTHENTICATE, statsClient); mIsStrongBiometric = isStrongBiometric; } diff --git a/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceAuthenticationClient.java b/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceAuthenticationClient.java index c3de7aa74d159..5731d73dfd492 100644 --- a/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceAuthenticationClient.java +++ b/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceAuthenticationClient.java @@ -65,7 +65,7 @@ class FaceAuthenticationClient extends AuthenticationClient { super(context, lazyDaemon, token, listener, targetUserId, operationId, restricted, owner, cookie, requireConfirmation, sensorId, isStrongBiometric, BiometricsProtoEnums.MODALITY_FACE, statsClient, null /* taskStackListener */, - lockoutTracker, allowBackgroundAuthentication); + lockoutTracker, allowBackgroundAuthentication, true /* shouldVibrate */); mUsageStats = usageStats; final Resources resources = getContext().getResources(); diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClient.java index 19134e46f08fd..8681ad75b7c65 100644 --- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClient.java +++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClient.java @@ -26,6 +26,7 @@ import android.hardware.biometrics.BiometricFingerprintConstants.FingerprintAcqu import android.hardware.biometrics.BiometricsProtoEnums; import android.hardware.biometrics.common.ICancellationSignal; import android.hardware.biometrics.fingerprint.ISession; +import android.hardware.fingerprint.FingerprintSensorPropertiesInternal; import android.hardware.fingerprint.IUdfpsOverlayController; import android.os.IBinder; import android.os.RemoteException; @@ -62,11 +63,12 @@ class FingerprintAuthenticationClient extends AuthenticationClient imp int sensorId, boolean isStrongBiometric, int statsClient, @Nullable TaskStackListener taskStackListener, @NonNull LockoutCache lockoutCache, @Nullable IUdfpsOverlayController udfpsOverlayController, - boolean allowBackgroundAuthentication) { + boolean allowBackgroundAuthentication, + @NonNull FingerprintSensorPropertiesInternal sensorProps) { super(context, lazyDaemon, token, listener, targetUserId, operationId, restricted, owner, cookie, requireConfirmation, sensorId, isStrongBiometric, BiometricsProtoEnums.MODALITY_FINGERPRINT, statsClient, taskStackListener, - lockoutCache, allowBackgroundAuthentication); + lockoutCache, allowBackgroundAuthentication, true /* shouldVibrate */); mLockoutCache = lockoutCache; mUdfpsOverlayController = udfpsOverlayController; } diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintDetectClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintDetectClient.java index 5e1a245554a65..c5dc44988612e 100644 --- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintDetectClient.java +++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintDetectClient.java @@ -52,8 +52,8 @@ class FingerprintDetectClient extends AcquisitionClient implements Det @Nullable IUdfpsOverlayController udfpsOverlayController, boolean isStrongBiometric, int statsClient) { super(context, lazyDaemon, token, listener, userId, owner, 0 /* cookie */, sensorId, - BiometricsProtoEnums.MODALITY_FINGERPRINT, BiometricsProtoEnums.ACTION_AUTHENTICATE, - statsClient); + true /* shouldVibrate */, BiometricsProtoEnums.MODALITY_FINGERPRINT, + BiometricsProtoEnums.ACTION_AUTHENTICATE, statsClient); mIsStrongBiometric = isStrongBiometric; mUdfpsOverlayController = udfpsOverlayController; } diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintEnrollClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintEnrollClient.java index 646b988545be4..a211bb5e14e38 100644 --- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintEnrollClient.java +++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintEnrollClient.java @@ -65,7 +65,7 @@ class FingerprintEnrollClient extends EnrollClient implements Udfps { @Nullable IUdfpsOverlayController udfpsOvelayController, @Nullable ISidefpsController sidefpsController, int maxTemplatesPerUser, @FingerprintManager.EnrollReason int enrollReason) { - // UDFPS enroll vibrations are handled in SystemUI + // UDFPS haptics occur when an image is acquired (instead of when the result is known) super(context, lazyDaemon, token, listener, userId, hardwareAuthToken, owner, utils, 0 /* timeoutSec */, BiometricsProtoEnums.MODALITY_FINGERPRINT, sensorId, !sensorProps.isAnyUdfpsType() /* shouldVibrate */); @@ -104,6 +104,7 @@ class FingerprintEnrollClient extends EnrollClient implements Udfps { // See AcquiredInfo#GOOD and AcquiredInfo#RETRYING_CAPTURE if (acquiredInfo == BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_GOOD && mSensorProps.isAnyUdfpsType()) { + vibrateSuccess(); UdfpsHelper.onAcquiredGood(getSensorId(), mUdfpsOverlayController); } diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java index 096c3111d35c9..cfc4674303490 100644 --- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java +++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java @@ -395,7 +395,8 @@ public class FingerprintProvider implements IBinder.DeathRecipient, ServiceProvi operationId, restricted, opPackageName, cookie, false /* requireConfirmation */, sensorId, isStrongBiometric, statsClient, mTaskStackListener, mSensors.get(sensorId).getLockoutCache(), - mUdfpsOverlayController, allowBackgroundAuthentication); + mUdfpsOverlayController, allowBackgroundAuthentication, + mSensors.get(sensorId).getSensorProperties()); scheduleForSensor(sensorId, client, fingerprintStateCallback); }); } diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintAuthenticationClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintAuthenticationClient.java index bf7775730a2cd..40e3bc3a46986 100644 --- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintAuthenticationClient.java +++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintAuthenticationClient.java @@ -65,7 +65,7 @@ class FingerprintAuthenticationClient extends AuthenticationClient int sensorId, @Nullable IUdfpsOverlayController udfpsOverlayController, boolean isStrongBiometric, int statsClient) { super(context, lazyDaemon, token, listener, userId, owner, 0 /* cookie */, sensorId, - BiometricsProtoEnums.MODALITY_FINGERPRINT, BiometricsProtoEnums.ACTION_AUTHENTICATE, - statsClient); + true /* shouldVibrate */, BiometricsProtoEnums.MODALITY_FINGERPRINT, + BiometricsProtoEnums.ACTION_AUTHENTICATE, statsClient); mUdfpsOverlayController = udfpsOverlayController; mIsStrongBiometric = isStrongBiometric; } diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/AcquisitionClientTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/AcquisitionClientTest.java index 46f96364ff9e4..a06a782885359 100644 --- a/services/tests/servicestests/src/com/android/server/biometrics/sensors/AcquisitionClientTest.java +++ b/services/tests/servicestests/src/com/android/server/biometrics/sensors/AcquisitionClientTest.java @@ -90,7 +90,8 @@ public class AcquisitionClientTest { @NonNull LazyDaemon lazyDaemon, @NonNull IBinder token, @NonNull ClientMonitorCallbackConverter callback) { super(context, lazyDaemon, token, callback, 0 /* userId */, "Test", 0 /* cookie */, - TEST_SENSOR_ID /* sensorId */, 0 /* statsModality */, 0 /* statsAction */, + TEST_SENSOR_ID /* sensorId */, true /* shouldVibrate */, 0 /* statsModality */, + 0 /* statsAction */, 0 /* statsClient */); } diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/BiometricSchedulerTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/BiometricSchedulerTest.java index 4d1f241787a75..109fb22520c8e 100644 --- a/services/tests/servicestests/src/com/android/server/biometrics/sensors/BiometricSchedulerTest.java +++ b/services/tests/servicestests/src/com/android/server/biometrics/sensors/BiometricSchedulerTest.java @@ -359,7 +359,7 @@ public class BiometricSchedulerTest { false /* restricted */, TAG, 1 /* cookie */, false /* requireConfirmation */, TEST_SENSOR_ID, true /* isStrongBiometric */, 0 /* statsModality */, 0 /* statsClient */, null /* taskStackListener */, mock(LockoutTracker.class), - false /* isKeyguard */); + false /* isKeyguard */, true /* shouldVibrate */); } @Override @@ -382,7 +382,7 @@ public class BiometricSchedulerTest { false /* restricted */, TAG, 1 /* cookie */, false /* requireConfirmation */, TEST_SENSOR_ID, true /* isStrongBiometric */, 0 /* statsModality */, 0 /* statsClient */, null /* taskStackListener */, mock(LockoutTracker.class), - false /* isKeyguard */); + false /* isKeyguard */, true /* shouldVibrate */); } @Override