diff options
| author | 2023-08-01 23:46:59 +0000 | |
|---|---|---|
| committer | 2023-08-01 23:46:59 +0000 | |
| commit | e1a4b9e06b4489ffcc1227c465ab897d1e5c0e8c (patch) | |
| tree | 1c8954ae8807ce193a12d394bb8279d302395566 | |
| parent | 68652cf3747698c36f89cca73cdb03f015e9c153 (diff) | |
| parent | 2588c8d5bed7e3947393fcc3ed6173b14a45b080 (diff) | |
Merge "Using performHapticFeedback on UdfpsController" into udc-qpr-dev am: 2588c8d5be
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/24285290
Change-Id: I5749c842d375da54151a3a02a0ddbae7e0553e61
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
| -rw-r--r-- | packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java | 52 | ||||
| -rw-r--r-- | packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java | 102 |
2 files changed, 142 insertions, 12 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java index ebff0b05a52d..39a45f7f60a2 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java @@ -26,6 +26,7 @@ import static android.hardware.biometrics.BiometricOverlayConstants.REASON_ENROL import static com.android.internal.util.Preconditions.checkNotNull; import static com.android.systemui.classifier.Classifier.UDFPS_AUTHENTICATION; +import static com.android.systemui.flags.Flags.ONE_WAY_HAPTICS_API_MIGRATION; import android.content.BroadcastReceiver; import android.content.Context; @@ -50,6 +51,7 @@ import android.os.Trace; import android.os.VibrationAttributes; import android.os.VibrationEffect; import android.util.Log; +import android.view.HapticFeedbackConstants; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.VelocityTracker; @@ -234,6 +236,8 @@ public class UdfpsController implements DozeReceiver, Dumpable { public static final VibrationEffect EFFECT_CLICK = VibrationEffect.get(VibrationEffect.EFFECT_CLICK); + public static final int LONG_PRESS = HapticFeedbackConstants.LONG_PRESS; + private final ScreenLifecycle.Observer mScreenObserver = new ScreenLifecycle.Observer() { @Override public void onScreenTurnedOn() { @@ -926,12 +930,24 @@ public class UdfpsController implements DozeReceiver, Dumpable { @VisibleForTesting public void playStartHaptic() { if (mAccessibilityManager.isTouchExplorationEnabled()) { - mVibrator.vibrate( - Process.myUid(), - mContext.getOpPackageName(), - EFFECT_CLICK, - "udfps-onStart-click", - UDFPS_VIBRATION_ATTRIBUTES); + if (mFeatureFlags.isEnabled(ONE_WAY_HAPTICS_API_MIGRATION)) { + if (mOverlay != null && mOverlay.getOverlayView() != null) { + mVibrator.performHapticFeedback( + mOverlay.getOverlayView(), + HapticFeedbackConstants.CONTEXT_CLICK + ); + } else { + Log.e(TAG, "No haptics played. Could not obtain overlay view to perform" + + "vibration. Either the controller overlay is null or has no view"); + } + } else { + mVibrator.vibrate( + Process.myUid(), + mContext.getOpPackageName(), + EFFECT_CLICK, + "udfps-onStart-click", + UDFPS_VIBRATION_ATTRIBUTES); + } } } @@ -1024,12 +1040,24 @@ public class UdfpsController implements DozeReceiver, Dumpable { mKeyguardViewManager.showPrimaryBouncer(true); // play the same haptic as the LockIconViewController longpress - mVibrator.vibrate( - Process.myUid(), - mContext.getOpPackageName(), - UdfpsController.EFFECT_CLICK, - "aod-lock-icon-longpress", - LOCK_ICON_VIBRATION_ATTRIBUTES); + if (mFeatureFlags.isEnabled(ONE_WAY_HAPTICS_API_MIGRATION)) { + if (mOverlay != null && mOverlay.getOverlayView() != null) { + mVibrator.performHapticFeedback( + mOverlay.getOverlayView(), + UdfpsController.LONG_PRESS + ); + } else { + Log.e(TAG, "No haptics played. Could not obtain overlay view to perform" + + "vibration. Either the controller overlay is null or has no view"); + } + } else { + mVibrator.vibrate( + Process.myUid(), + mContext.getOpPackageName(), + UdfpsController.EFFECT_CLICK, + "aod-lock-icon-longpress", + LOCK_ICON_VIBRATION_ATTRIBUTES); + } return; } diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java index 58982d13481d..7ab8e8b229a3 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java @@ -23,6 +23,7 @@ import static android.view.MotionEvent.ACTION_UP; import static com.android.internal.util.FunctionalUtils.ThrowingConsumer; import static com.android.systemui.classifier.Classifier.UDFPS_AUTHENTICATION; +import static com.android.systemui.flags.Flags.ONE_WAY_HAPTICS_API_MIGRATION; import static junit.framework.Assert.assertEquals; import static junit.framework.Assert.assertFalse; @@ -61,6 +62,7 @@ import android.os.RemoteException; import android.os.VibrationAttributes; import android.testing.TestableLooper.RunWithLooper; import android.util.Pair; +import android.view.HapticFeedbackConstants; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.Surface; @@ -1128,6 +1130,36 @@ public class UdfpsControllerTest extends SysuiTestCase { } @Test + public void playHapticOnTouchUdfpsArea_a11yTouchExplorationEnabled_oneWayHapticsEnabled() + throws RemoteException { + when(mFeatureFlags.isEnabled(ONE_WAY_HAPTICS_API_MIGRATION)).thenReturn(true); + // Configure UdfpsView to accept the ACTION_DOWN event + when(mUdfpsView.isDisplayConfigured()).thenReturn(false); + when(mUdfpsView.isWithinSensorArea(anyFloat(), anyFloat())).thenReturn(true); + + // GIVEN that the overlay is showing and a11y touch exploration enabled + when(mAccessibilityManager.isTouchExplorationEnabled()).thenReturn(true); + mOverlayController.showUdfpsOverlay(TEST_REQUEST_ID, mOpticalProps.sensorId, + BiometricOverlayConstants.REASON_AUTH_KEYGUARD, mUdfpsOverlayControllerCallback); + mFgExecutor.runAllReady(); + + // WHEN ACTION_HOVER is received + verify(mUdfpsView).setOnHoverListener(mHoverListenerCaptor.capture()); + MotionEvent enterEvent = MotionEvent.obtain(0, 0, MotionEvent.ACTION_HOVER_ENTER, 0, 0, 0); + mHoverListenerCaptor.getValue().onHover(mUdfpsView, enterEvent); + enterEvent.recycle(); + MotionEvent moveEvent = MotionEvent.obtain(0, 0, MotionEvent.ACTION_HOVER_MOVE, 0, 0, 0); + mHoverListenerCaptor.getValue().onHover(mUdfpsView, moveEvent); + moveEvent.recycle(); + + // THEN context click haptic is played + verify(mVibrator).performHapticFeedback( + any(), + eq(HapticFeedbackConstants.CONTEXT_CLICK) + ); + } + + @Test public void noHapticOnTouchUdfpsArea_a11yTouchExplorationDisabled() throws RemoteException { // Configure UdfpsView to accept the ACTION_DOWN event when(mUdfpsView.isDisplayConfigured()).thenReturn(false); @@ -1160,6 +1192,35 @@ public class UdfpsControllerTest extends SysuiTestCase { } @Test + public void noHapticOnTouchUdfpsArea_a11yTouchExplorationDisabled__oneWayHapticsEnabled() + throws RemoteException { + when(mFeatureFlags.isEnabled(ONE_WAY_HAPTICS_API_MIGRATION)).thenReturn(true); + // Configure UdfpsView to accept the ACTION_DOWN event + when(mUdfpsView.isDisplayConfigured()).thenReturn(false); + when(mUdfpsView.isWithinSensorArea(anyFloat(), anyFloat())).thenReturn(true); + + // GIVEN that the overlay is showing and a11y touch exploration NOT enabled + when(mAccessibilityManager.isTouchExplorationEnabled()).thenReturn(false); + mOverlayController.showUdfpsOverlay(TEST_REQUEST_ID, mOpticalProps.sensorId, + BiometricOverlayConstants.REASON_AUTH_KEYGUARD, mUdfpsOverlayControllerCallback); + mFgExecutor.runAllReady(); + + // WHEN ACTION_DOWN is received + verify(mUdfpsView).setOnTouchListener(mTouchListenerCaptor.capture()); + MotionEvent downEvent = MotionEvent.obtain(0, 0, ACTION_DOWN, 0, 0, 0); + mTouchListenerCaptor.getValue().onTouch(mUdfpsView, downEvent); + mBiometricExecutor.runAllReady(); + downEvent.recycle(); + MotionEvent moveEvent = MotionEvent.obtain(0, 0, MotionEvent.ACTION_MOVE, 0, 0, 0); + mTouchListenerCaptor.getValue().onTouch(mUdfpsView, moveEvent); + mBiometricExecutor.runAllReady(); + moveEvent.recycle(); + + // THEN NO haptic played + verify(mVibrator, never()).performHapticFeedback(any(), anyInt()); + } + + @Test public void onTouch_withoutNewTouchDetection_shouldCallOldFingerprintManagerPath() throws RemoteException { // Disable new touch detection. @@ -1514,4 +1575,45 @@ public class UdfpsControllerTest extends SysuiTestCase { // THEN is fingerDown should be FALSE assertFalse(mUdfpsController.isFingerDown()); } + + @Test + public void playHaptic_onAodInterrupt_oneWayHapticsDisabled_onAcquiredBad_usesVibrate() + throws RemoteException { + // GIVEN UDFPS overlay is showing + mOverlayController.showUdfpsOverlay(TEST_REQUEST_ID, mOpticalProps.sensorId, + BiometricOverlayConstants.REASON_AUTH_KEYGUARD, mUdfpsOverlayControllerCallback); + mFgExecutor.runAllReady(); + + // GIVEN there's been an AoD interrupt + when(mKeyguardUpdateMonitor.isFingerprintDetectionRunning()).thenReturn(false); + mScreenObserver.onScreenTurnedOn(); + mUdfpsController.onAodInterrupt(0, 0, 0, 0); + + // THEN vibrate is used + verify(mVibrator).vibrate( + anyInt(), + anyString(), + eq(UdfpsController.EFFECT_CLICK), + eq("aod-lock-icon-longpress"), + eq(UdfpsController.LOCK_ICON_VIBRATION_ATTRIBUTES) + ); + } + + @Test + public void playHaptic_onAodInterrupt_oneWayHapticsEnabled_onAcquiredBad_performHapticFeedback() + throws RemoteException { + when(mFeatureFlags.isEnabled(ONE_WAY_HAPTICS_API_MIGRATION)).thenReturn(true); + // GIVEN UDFPS overlay is showing + mOverlayController.showUdfpsOverlay(TEST_REQUEST_ID, mOpticalProps.sensorId, + BiometricOverlayConstants.REASON_AUTH_KEYGUARD, mUdfpsOverlayControllerCallback); + mFgExecutor.runAllReady(); + + // GIVEN there's been an AoD interrupt + when(mKeyguardUpdateMonitor.isFingerprintDetectionRunning()).thenReturn(false); + mScreenObserver.onScreenTurnedOn(); + mUdfpsController.onAodInterrupt(0, 0, 0, 0); + + // THEN vibrate is used + verify(mVibrator).performHapticFeedback(any(), eq(UdfpsController.LONG_PRESS)); + } } |