Loading packages/SystemUI/src/com/android/keyguard/LockIconViewController.java +1 −1 Original line number Diff line number Diff line Loading @@ -558,7 +558,7 @@ public class LockIconViewController extends ViewController<LockIconView> impleme switch(event.getActionMasked()) { case MotionEvent.ACTION_DOWN: case MotionEvent.ACTION_HOVER_ENTER: if (!mDownDetected) { if (!mDownDetected && mAccessibilityManager.isTouchExplorationEnabled()) { mVibrator.vibrate( Process.myUid(), getContext().getOpPackageName(), Loading packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java +9 −7 Original line number Diff line number Diff line Loading @@ -584,10 +584,11 @@ public class UdfpsController implements DozeReceiver { } /** * Play haptic to signal udfps scanning started. * If a11y touchExplorationEnabled, play haptic to signal UDFPS scanning started. */ @VisibleForTesting public void playStartHaptic() { if (mAccessibilityManager.isTouchExplorationEnabled()) { mVibrator.vibrate( Process.myUid(), mContext.getOpPackageName(), Loading @@ -595,6 +596,7 @@ public class UdfpsController implements DozeReceiver { "udfps-onStart-click", VIBRATION_ATTRIBUTES); } } @Nullable private FingerprintSensorPropertiesInternal findFirstUdfps() { Loading packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java +43 −10 Original line number Diff line number Diff line Loading @@ -48,6 +48,7 @@ import android.testing.AndroidTestingRunner; import android.testing.TestableLooper.RunWithLooper; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; import android.view.WindowManager; import android.view.accessibility.AccessibilityManager; Loading @@ -64,8 +65,8 @@ import com.android.systemui.plugins.FalsingManager; import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.statusbar.LockscreenShadeTransitionController; import com.android.systemui.statusbar.VibratorHelper; import com.android.systemui.statusbar.phone.KeyguardBypassController; import com.android.systemui.statusbar.phone.CentralSurfaces; import com.android.systemui.statusbar.phone.KeyguardBypassController; import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager; import com.android.systemui.statusbar.phone.SystemUIDialogManager; import com.android.systemui.statusbar.phone.UnlockedScreenOffAnimationController; Loading Loading @@ -188,6 +189,7 @@ public class UdfpsControllerTest extends SysuiTestCase { @Captor private ArgumentCaptor<IUdfpsOverlayController> mOverlayCaptor; private IUdfpsOverlayController mOverlayController; @Captor private ArgumentCaptor<UdfpsView.OnTouchListener> mTouchListenerCaptor; @Captor private ArgumentCaptor<View.OnHoverListener> mHoverListenerCaptor; @Captor private ArgumentCaptor<Runnable> mOnIlluminatedRunnableCaptor; @Captor private ArgumentCaptor<ScreenLifecycle.Observer> mScreenObserverCaptor; private ScreenLifecycle.Observer mScreenObserver; Loading Loading @@ -568,23 +570,24 @@ public class UdfpsControllerTest extends SysuiTestCase { } @Test public void playHapticOnTouchUdfpsArea() throws RemoteException { public void playHapticOnTouchUdfpsArea_a11yTouchExplorationEnabled() throws RemoteException { // Configure UdfpsView to accept the ACTION_DOWN event when(mUdfpsView.isIlluminationRequested()).thenReturn(false); when(mUdfpsView.isWithinSensorArea(anyFloat(), anyFloat())).thenReturn(true); // GIVEN that the overlay is showing // GIVEN that the overlay is showing and a11y touch exploration enabled when(mAccessibilityManager.isTouchExplorationEnabled()).thenReturn(true); mOverlayController.showUdfpsOverlay(TEST_UDFPS_SENSOR_ID, BiometricOverlayConstants.REASON_AUTH_KEYGUARD, mUdfpsOverlayControllerCallback); mFgExecutor.runAllReady(); // WHEN ACTION_DOWN is received verify(mUdfpsView).setOnTouchListener(mTouchListenerCaptor.capture()); MotionEvent downEvent = MotionEvent.obtain(0, 0, MotionEvent.ACTION_DOWN, 0, 0, 0); mTouchListenerCaptor.getValue().onTouch(mUdfpsView, downEvent); downEvent.recycle(); MotionEvent moveEvent = MotionEvent.obtain(0, 0, MotionEvent.ACTION_MOVE, 0, 0, 0); mTouchListenerCaptor.getValue().onTouch(mUdfpsView, moveEvent); // 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 tick haptic is played Loading @@ -600,4 +603,34 @@ public class UdfpsControllerTest extends SysuiTestCase { assertEquals(VibrationAttributes.USAGE_COMMUNICATION_REQUEST, UdfpsController.VIBRATION_ATTRIBUTES.getUsage()); } @Test public void noHapticOnTouchUdfpsArea_a11yTouchExplorationDisabled() throws RemoteException { // Configure UdfpsView to accept the ACTION_DOWN event when(mUdfpsView.isIlluminationRequested()).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_UDFPS_SENSOR_ID, BiometricOverlayConstants.REASON_AUTH_KEYGUARD, mUdfpsOverlayControllerCallback); mFgExecutor.runAllReady(); // WHEN ACTION_DOWN is received verify(mUdfpsView).setOnTouchListener(mTouchListenerCaptor.capture()); MotionEvent downEvent = MotionEvent.obtain(0, 0, MotionEvent.ACTION_DOWN, 0, 0, 0); mTouchListenerCaptor.getValue().onTouch(mUdfpsView, downEvent); downEvent.recycle(); MotionEvent moveEvent = MotionEvent.obtain(0, 0, MotionEvent.ACTION_MOVE, 0, 0, 0); mTouchListenerCaptor.getValue().onTouch(mUdfpsView, moveEvent); moveEvent.recycle(); // THEN NO haptic played verify(mVibrator, never()).vibrate( anyInt(), anyString(), any(), anyString(), any()); } } Loading
packages/SystemUI/src/com/android/keyguard/LockIconViewController.java +1 −1 Original line number Diff line number Diff line Loading @@ -558,7 +558,7 @@ public class LockIconViewController extends ViewController<LockIconView> impleme switch(event.getActionMasked()) { case MotionEvent.ACTION_DOWN: case MotionEvent.ACTION_HOVER_ENTER: if (!mDownDetected) { if (!mDownDetected && mAccessibilityManager.isTouchExplorationEnabled()) { mVibrator.vibrate( Process.myUid(), getContext().getOpPackageName(), Loading
packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java +9 −7 Original line number Diff line number Diff line Loading @@ -584,10 +584,11 @@ public class UdfpsController implements DozeReceiver { } /** * Play haptic to signal udfps scanning started. * If a11y touchExplorationEnabled, play haptic to signal UDFPS scanning started. */ @VisibleForTesting public void playStartHaptic() { if (mAccessibilityManager.isTouchExplorationEnabled()) { mVibrator.vibrate( Process.myUid(), mContext.getOpPackageName(), Loading @@ -595,6 +596,7 @@ public class UdfpsController implements DozeReceiver { "udfps-onStart-click", VIBRATION_ATTRIBUTES); } } @Nullable private FingerprintSensorPropertiesInternal findFirstUdfps() { Loading
packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java +43 −10 Original line number Diff line number Diff line Loading @@ -48,6 +48,7 @@ import android.testing.AndroidTestingRunner; import android.testing.TestableLooper.RunWithLooper; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; import android.view.WindowManager; import android.view.accessibility.AccessibilityManager; Loading @@ -64,8 +65,8 @@ import com.android.systemui.plugins.FalsingManager; import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.statusbar.LockscreenShadeTransitionController; import com.android.systemui.statusbar.VibratorHelper; import com.android.systemui.statusbar.phone.KeyguardBypassController; import com.android.systemui.statusbar.phone.CentralSurfaces; import com.android.systemui.statusbar.phone.KeyguardBypassController; import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager; import com.android.systemui.statusbar.phone.SystemUIDialogManager; import com.android.systemui.statusbar.phone.UnlockedScreenOffAnimationController; Loading Loading @@ -188,6 +189,7 @@ public class UdfpsControllerTest extends SysuiTestCase { @Captor private ArgumentCaptor<IUdfpsOverlayController> mOverlayCaptor; private IUdfpsOverlayController mOverlayController; @Captor private ArgumentCaptor<UdfpsView.OnTouchListener> mTouchListenerCaptor; @Captor private ArgumentCaptor<View.OnHoverListener> mHoverListenerCaptor; @Captor private ArgumentCaptor<Runnable> mOnIlluminatedRunnableCaptor; @Captor private ArgumentCaptor<ScreenLifecycle.Observer> mScreenObserverCaptor; private ScreenLifecycle.Observer mScreenObserver; Loading Loading @@ -568,23 +570,24 @@ public class UdfpsControllerTest extends SysuiTestCase { } @Test public void playHapticOnTouchUdfpsArea() throws RemoteException { public void playHapticOnTouchUdfpsArea_a11yTouchExplorationEnabled() throws RemoteException { // Configure UdfpsView to accept the ACTION_DOWN event when(mUdfpsView.isIlluminationRequested()).thenReturn(false); when(mUdfpsView.isWithinSensorArea(anyFloat(), anyFloat())).thenReturn(true); // GIVEN that the overlay is showing // GIVEN that the overlay is showing and a11y touch exploration enabled when(mAccessibilityManager.isTouchExplorationEnabled()).thenReturn(true); mOverlayController.showUdfpsOverlay(TEST_UDFPS_SENSOR_ID, BiometricOverlayConstants.REASON_AUTH_KEYGUARD, mUdfpsOverlayControllerCallback); mFgExecutor.runAllReady(); // WHEN ACTION_DOWN is received verify(mUdfpsView).setOnTouchListener(mTouchListenerCaptor.capture()); MotionEvent downEvent = MotionEvent.obtain(0, 0, MotionEvent.ACTION_DOWN, 0, 0, 0); mTouchListenerCaptor.getValue().onTouch(mUdfpsView, downEvent); downEvent.recycle(); MotionEvent moveEvent = MotionEvent.obtain(0, 0, MotionEvent.ACTION_MOVE, 0, 0, 0); mTouchListenerCaptor.getValue().onTouch(mUdfpsView, moveEvent); // 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 tick haptic is played Loading @@ -600,4 +603,34 @@ public class UdfpsControllerTest extends SysuiTestCase { assertEquals(VibrationAttributes.USAGE_COMMUNICATION_REQUEST, UdfpsController.VIBRATION_ATTRIBUTES.getUsage()); } @Test public void noHapticOnTouchUdfpsArea_a11yTouchExplorationDisabled() throws RemoteException { // Configure UdfpsView to accept the ACTION_DOWN event when(mUdfpsView.isIlluminationRequested()).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_UDFPS_SENSOR_ID, BiometricOverlayConstants.REASON_AUTH_KEYGUARD, mUdfpsOverlayControllerCallback); mFgExecutor.runAllReady(); // WHEN ACTION_DOWN is received verify(mUdfpsView).setOnTouchListener(mTouchListenerCaptor.capture()); MotionEvent downEvent = MotionEvent.obtain(0, 0, MotionEvent.ACTION_DOWN, 0, 0, 0); mTouchListenerCaptor.getValue().onTouch(mUdfpsView, downEvent); downEvent.recycle(); MotionEvent moveEvent = MotionEvent.obtain(0, 0, MotionEvent.ACTION_MOVE, 0, 0, 0); mTouchListenerCaptor.getValue().onTouch(mUdfpsView, moveEvent); moveEvent.recycle(); // THEN NO haptic played verify(mVibrator, never()).vibrate( anyInt(), anyString(), any(), anyString(), any()); } }