diff options
10 files changed, 84 insertions, 49 deletions
diff --git a/core/res/res/values/bools.xml b/core/res/res/values/bools.xml index 988303ea7bc5..4b27bf2849fb 100644 --- a/core/res/res/values/bools.xml +++ b/core/res/res/values/bools.xml @@ -31,5 +31,4 @@ lockscreen, setting this to true should come with customized drawables. --> <bool name="use_lock_pattern_drawable">false</bool> <bool name="resolver_landscape_phone">true</bool> - <bool name="system_server_plays_face_haptics">true</bool> </resources> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index f46752002478..44d84683abf9 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -4862,6 +4862,4 @@ <java-symbol type="id" name="language_picker_header" /> <java-symbol type="dimen" name="status_bar_height_default" /> - - <java-symbol type="bool" name="system_server_plays_face_haptics" /> </resources> diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java index e006befe6fac..ff18eeea45a5 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java @@ -78,6 +78,7 @@ import com.android.systemui.doze.DozeReceiver; import com.android.systemui.keyguard.WakefulnessLifecycle; import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.statusbar.CommandQueue; +import com.android.systemui.statusbar.VibratorHelper; import com.android.systemui.util.concurrency.DelayableExecutor; import com.android.systemui.util.concurrency.Execution; @@ -160,6 +161,19 @@ public class AuthController implements CoreStartable, CommandQueue.Callbacks, private final @Background DelayableExecutor mBackgroundExecutor; private final DisplayInfo mCachedDisplayInfo = new DisplayInfo(); + + private final VibratorHelper mVibratorHelper; + + private void vibrateSuccess(int modality) { + mVibratorHelper.vibrateAuthSuccess( + getClass().getSimpleName() + ", modality = " + modality + "BP::success"); + } + + private void vibrateError(int modality) { + mVibratorHelper.vibrateAuthError( + getClass().getSimpleName() + ", modality = " + modality + "BP::error"); + } + @VisibleForTesting final TaskStackListener mTaskStackListener = new TaskStackListener() { @Override @@ -671,7 +685,8 @@ public class AuthController implements CoreStartable, CommandQueue.Callbacks, @NonNull StatusBarStateController statusBarStateController, @NonNull InteractionJankMonitor jankMonitor, @Main Handler handler, - @Background DelayableExecutor bgExecutor) { + @Background DelayableExecutor bgExecutor, + @NonNull VibratorHelper vibrator) { mContext = context; mExecution = execution; mUserManager = userManager; @@ -689,6 +704,7 @@ public class AuthController implements CoreStartable, CommandQueue.Callbacks, mInteractionJankMonitor = jankMonitor; mUdfpsEnrolledForUser = new SparseBooleanArray(); mSfpsEnrolledForUser = new SparseBooleanArray(); + mVibratorHelper = vibrator; mOrientationListener = new BiometricDisplayListener( context, @@ -878,6 +894,8 @@ public class AuthController implements CoreStartable, CommandQueue.Callbacks, public void onBiometricAuthenticated(@Modality int modality) { if (DEBUG) Log.d(TAG, "onBiometricAuthenticated: "); + vibrateSuccess(modality); + if (mCurrentDialog != null) { mCurrentDialog.onAuthenticationSucceeded(modality); } else { @@ -930,6 +948,8 @@ public class AuthController implements CoreStartable, CommandQueue.Callbacks, Log.d(TAG, String.format("onBiometricError(%d, %d, %d)", modality, error, vendorCode)); } + vibrateError(modality); + final boolean isLockout = (error == BiometricConstants.BIOMETRIC_ERROR_LOCKOUT) || (error == BiometricConstants.BIOMETRIC_ERROR_LOCKOUT_PERMANENT); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/VibratorHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/VibratorHelper.java index 258f9fc5449f..c070fccf9808 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/VibratorHelper.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/VibratorHelper.java @@ -19,6 +19,7 @@ package com.android.systemui.statusbar; import android.annotation.NonNull; import android.annotation.Nullable; import android.media.AudioAttributes; +import android.os.Process; import android.os.VibrationAttributes; import android.os.VibrationEffect; import android.os.Vibrator; @@ -33,6 +34,7 @@ import java.util.concurrent.Executor; import javax.inject.Inject; /** + * */ @SysUISingleton public class VibratorHelper { @@ -40,9 +42,18 @@ public class VibratorHelper { private final Vibrator mVibrator; public static final VibrationAttributes TOUCH_VIBRATION_ATTRIBUTES = VibrationAttributes.createForUsage(VibrationAttributes.USAGE_TOUCH); + + private static final VibrationEffect BIOMETRIC_SUCCESS_VIBRATION_EFFECT = + VibrationEffect.get(VibrationEffect.EFFECT_CLICK); + private static final VibrationEffect BIOMETRIC_ERROR_VIBRATION_EFFECT = + VibrationEffect.get(VibrationEffect.EFFECT_DOUBLE_CLICK); + private static final VibrationAttributes HARDWARE_FEEDBACK_VIBRATION_ATTRIBUTES = + VibrationAttributes.createForUsage(VibrationAttributes.USAGE_HARDWARE_FEEDBACK); + private final Executor mExecutor; /** + * */ @Inject public VibratorHelper(@Nullable Vibrator vibrator, @Background Executor executor) { @@ -109,4 +120,23 @@ public class VibratorHelper { } mExecutor.execute(mVibrator::cancel); } + + /** + * Perform vibration when biometric authentication success + */ + public void vibrateAuthSuccess(String reason) { + vibrate(Process.myUid(), + "com.android.systemui", + BIOMETRIC_SUCCESS_VIBRATION_EFFECT, reason, + HARDWARE_FEEDBACK_VIBRATION_ATTRIBUTES); + } + + /** + * Perform vibration when biometric authentication error + */ + public void vibrateAuthError(String reason) { + vibrate(Process.myUid(), "com.android.systemui", + BIOMETRIC_ERROR_VIBRATION_EFFECT, reason, + HARDWARE_FEEDBACK_VIBRATION_ATTRIBUTES); + } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java index a2798f47be65..87b0423f1b74 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java @@ -27,11 +27,8 @@ import android.hardware.fingerprint.FingerprintManager; import android.metrics.LogMaker; import android.os.Handler; import android.os.PowerManager; -import android.os.Process; import android.os.SystemClock; import android.os.Trace; -import android.os.VibrationAttributes; -import android.os.VibrationEffect; import android.util.Log; import androidx.annotation.Nullable; @@ -87,12 +84,6 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback imp private static final String BIOMETRIC_WAKE_LOCK_NAME = "wake-and-unlock:wakelock"; private static final UiEventLogger UI_EVENT_LOGGER = new UiEventLoggerImpl(); private static final int UDFPS_ATTEMPTS_BEFORE_SHOW_BOUNCER = 3; - private static final VibrationEffect SUCCESS_VIBRATION_EFFECT = - VibrationEffect.get(VibrationEffect.EFFECT_CLICK); - private static final VibrationEffect ERROR_VIBRATION_EFFECT = - VibrationEffect.get(VibrationEffect.EFFECT_DOUBLE_CLICK); - private static final VibrationAttributes HARDWARE_FEEDBACK_VIBRATION_ATTRIBUTES = - VibrationAttributes.createForUsage(VibrationAttributes.USAGE_HARDWARE_FEEDBACK); @IntDef(prefix = { "MODE_" }, value = { MODE_NONE, @@ -167,7 +158,6 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback imp private final NotificationShadeWindowController mNotificationShadeWindowController; private final SessionTracker mSessionTracker; private final int mConsecutiveFpFailureThreshold; - private final boolean mShouldVibrate; private int mMode; private BiometricSourceType mBiometricType; private KeyguardViewController mKeyguardViewController; @@ -307,8 +297,6 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback imp mHandler = handler; mConsecutiveFpFailureThreshold = resources.getInteger( R.integer.fp_consecutive_failure_time_ms); - mShouldVibrate = !(resources.getBoolean( - com.android.internal.R.bool.system_server_plays_face_haptics)); mKeyguardBypassController = keyguardBypassController; mKeyguardBypassController.setUnlockController(this); mMetricsLogger = metricsLogger; @@ -423,10 +411,10 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback imp public void startWakeAndUnlock(BiometricSourceType biometricSourceType, boolean isStrongBiometric) { int mode = calculateMode(biometricSourceType, isStrongBiometric); - if (BiometricSourceType.FACE == biometricSourceType && (mode == MODE_WAKE_AND_UNLOCK + if (mode == MODE_WAKE_AND_UNLOCK || mode == MODE_WAKE_AND_UNLOCK_PULSING || mode == MODE_UNLOCK_COLLAPSING - || mode == MODE_WAKE_AND_UNLOCK_FROM_DREAM || mode == MODE_DISMISS_BOUNCER)) { - vibrateSuccess(); + || mode == MODE_WAKE_AND_UNLOCK_FROM_DREAM || mode == MODE_DISMISS_BOUNCER) { + vibrateSuccess(biometricSourceType); } startWakeAndUnlock(mode); } @@ -659,10 +647,11 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback imp } // Suppress all face auth errors if fingerprint can be used to authenticate - if (biometricSourceType == BiometricSourceType.FACE + if ((biometricSourceType == BiometricSourceType.FACE && !mUpdateMonitor.getCachedIsUnlockWithFingerprintPossible( - KeyguardUpdateMonitor.getCurrentUser())) { - vibrateError(); + KeyguardUpdateMonitor.getCurrentUser())) + || (biometricSourceType == BiometricSourceType.FINGERPRINT)) { + vibrateError(biometricSourceType); } cleanup(); @@ -688,24 +677,15 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback imp cleanup(); } - private void vibrateSuccess() { - if (mShouldVibrate) { - mVibratorHelper.vibrate(Process.myUid(), - "com.android.systemui", - SUCCESS_VIBRATION_EFFECT, - getClass().getSimpleName() + "::success", - HARDWARE_FEEDBACK_VIBRATION_ATTRIBUTES); - } + //these haptics are for device-entry only + private void vibrateSuccess(BiometricSourceType type) { + mVibratorHelper.vibrateAuthSuccess( + getClass().getSimpleName() + ", type =" + type + "device-entry::success"); } - private void vibrateError() { - if (mShouldVibrate) { - mVibratorHelper.vibrate(Process.myUid(), - "com.android.systemui", - ERROR_VIBRATION_EFFECT, - getClass().getSimpleName() + "::error", - HARDWARE_FEEDBACK_VIBRATION_ATTRIBUTES); - } + private void vibrateError(BiometricSourceType type) { + mVibratorHelper.vibrateAuthError( + getClass().getSimpleName() + ", type =" + type + "device-entry::error"); } private void cleanup() { diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java index a02dfa3935d7..a275c8d33751 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java @@ -87,6 +87,7 @@ import com.android.systemui.SysuiTestCase; import com.android.systemui.keyguard.WakefulnessLifecycle; import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.statusbar.CommandQueue; +import com.android.systemui.statusbar.VibratorHelper; import com.android.systemui.util.concurrency.DelayableExecutor; import com.android.systemui.util.concurrency.Execution; import com.android.systemui.util.concurrency.FakeExecution; @@ -173,6 +174,9 @@ public class AuthControllerTest extends SysuiTestCase { private DelayableExecutor mBackgroundExecutor; private TestableAuthController mAuthController; + @Mock + private VibratorHelper mVibratorHelper; + @Before public void setup() throws RemoteException { mContextSpy = spy(mContext); @@ -221,7 +225,8 @@ public class AuthControllerTest extends SysuiTestCase { mAuthController = new TestableAuthController(mContextSpy, mExecution, mCommandQueue, mActivityTaskManager, mWindowManager, mFingerprintManager, mFaceManager, - () -> mUdfpsController, () -> mSidefpsController, mStatusBarStateController); + () -> mUdfpsController, () -> mSidefpsController, mStatusBarStateController, + mVibratorHelper); mAuthController.start(); verify(mFingerprintManager).addAuthenticatorsRegisteredCallback( @@ -246,11 +251,13 @@ public class AuthControllerTest extends SysuiTestCase { // This test is sensitive to prior FingerprintManager interactions. reset(mFingerprintManager); + when(mVibratorHelper.hasVibrator()).thenReturn(true); + // This test requires an uninitialized AuthController. AuthController authController = new TestableAuthController(mContextSpy, mExecution, mCommandQueue, mActivityTaskManager, mWindowManager, mFingerprintManager, mFaceManager, () -> mUdfpsController, () -> mSidefpsController, - mStatusBarStateController); + mStatusBarStateController, mVibratorHelper); authController.start(); verify(mFingerprintManager).addAuthenticatorsRegisteredCallback( @@ -270,11 +277,13 @@ public class AuthControllerTest extends SysuiTestCase { // This test is sensitive to prior FingerprintManager interactions. reset(mFingerprintManager); + when(mVibratorHelper.hasVibrator()).thenReturn(true); + // This test requires an uninitialized AuthController. AuthController authController = new TestableAuthController(mContextSpy, mExecution, mCommandQueue, mActivityTaskManager, mWindowManager, mFingerprintManager, mFaceManager, () -> mUdfpsController, () -> mSidefpsController, - mStatusBarStateController); + mStatusBarStateController, mVibratorHelper); authController.start(); verify(mFingerprintManager).addAuthenticatorsRegisteredCallback( @@ -928,12 +937,13 @@ public class AuthControllerTest extends SysuiTestCase { FaceManager faceManager, Provider<UdfpsController> udfpsControllerFactory, Provider<SidefpsController> sidefpsControllerFactory, - StatusBarStateController statusBarStateController) { + StatusBarStateController statusBarStateController, + VibratorHelper vibratorHelper) { super(context, execution, commandQueue, activityTaskManager, windowManager, fingerprintManager, faceManager, udfpsControllerFactory, sidefpsControllerFactory, mDisplayManager, mWakefulnessLifecycle, mUserManager, mLockPatternUtils, statusBarStateController, - mInteractionJankMonitor, mHandler, mBackgroundExecutor); + mInteractionJankMonitor, mHandler, mBackgroundExecutor, vibratorHelper); } @Override 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 ca4b7475f7dc..dbe971f32dc1 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 @@ -100,9 +100,7 @@ class FaceAuthenticationClient extends AuthenticationClient<AidlSession> owner, cookie, requireConfirmation, sensorId, logger, biometricContext, isStrongBiometric, null /* taskStackListener */, lockoutCache, allowBackgroundAuthentication, - context.getResources().getBoolean( - com.android.internal.R.bool.system_server_plays_face_haptics) - /* shouldVibrate */, + false /* shouldVibrate */, isKeyguardBypassEnabled); setRequestId(requestId); mUsageStats = usageStats; 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 9baca98e4d2b..91eec7d19b3a 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 @@ -74,7 +74,7 @@ class FaceAuthenticationClient extends AuthenticationClient<IBiometricsFace> { super(context, lazyDaemon, token, listener, targetUserId, operationId, restricted, owner, cookie, requireConfirmation, sensorId, logger, biometricContext, isStrongBiometric, null /* taskStackListener */, - lockoutTracker, allowBackgroundAuthentication, true /* shouldVibrate */, + lockoutTracker, allowBackgroundAuthentication, false /* shouldVibrate */, isKeyguardBypassEnabled); setRequestId(requestId); mUsageStats = usageStats; 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 b8bac8dab1ff..9aecf783a881 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 @@ -135,7 +135,7 @@ class FingerprintAuthenticationClient extends AuthenticationClient<AidlSession> taskStackListener, lockoutCache, allowBackgroundAuthentication, - true /* shouldVibrate */, + false /* shouldVibrate */, false /* isKeyguardBypassEnabled */); setRequestId(requestId); mLockoutCache = lockoutCache; 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 7ed1a514f9bc..0d620fd3a9e4 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 @@ -81,7 +81,7 @@ class FingerprintAuthenticationClient extends AuthenticationClient<IBiometricsFi super(context, lazyDaemon, token, listener, targetUserId, operationId, restricted, owner, cookie, requireConfirmation, sensorId, logger, biometricContext, isStrongBiometric, taskStackListener, lockoutTracker, allowBackgroundAuthentication, - true /* shouldVibrate */, false /* isKeyguardBypassEnabled */); + false /* shouldVibrate */, false /* isKeyguardBypassEnabled */); setRequestId(requestId); mLockoutFrameworkImpl = lockoutTracker; mSensorOverlays = new SensorOverlays(udfpsOverlayController, sidefpsController); |