Loading packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java +8 −2 Original line number Original line Diff line number Diff line Loading @@ -563,6 +563,7 @@ public class UdfpsController implements DozeReceiver, Dumpable { (TouchProcessorResult.ProcessedTouch) result; (TouchProcessorResult.ProcessedTouch) result; final NormalizedTouchData data = processedTouch.getTouchData(); final NormalizedTouchData data = processedTouch.getTouchData(); boolean shouldPilfer = false; mActivePointerId = processedTouch.getPointerOnSensorId(); mActivePointerId = processedTouch.getPointerOnSensorId(); switch (processedTouch.getEvent()) { switch (processedTouch.getEvent()) { case DOWN: case DOWN: Loading @@ -581,8 +582,7 @@ public class UdfpsController implements DozeReceiver, Dumpable { mStatusBarStateController.isDozing()); mStatusBarStateController.isDozing()); // Pilfer if valid overlap, don't allow following events to reach keyguard // Pilfer if valid overlap, don't allow following events to reach keyguard mInputManager.pilferPointers( shouldPilfer = true; mOverlay.getOverlayView().getViewRootImpl().getInputToken()); break; break; case UP: case UP: Loading Loading @@ -621,6 +621,12 @@ public class UdfpsController implements DozeReceiver, Dumpable { // Always pilfer pointers that are within sensor area or when alternate bouncer is showing // Always pilfer pointers that are within sensor area or when alternate bouncer is showing if (isWithinSensorArea(mOverlay.getOverlayView(), event.getRawX(), event.getRawY(), true) if (isWithinSensorArea(mOverlay.getOverlayView(), event.getRawX(), event.getRawY(), true) || mAlternateBouncerInteractor.isVisibleState()) { || mAlternateBouncerInteractor.isVisibleState()) { shouldPilfer = true; } // Execute the pilfer, never pilfer if a vertical swipe is in progress if (shouldPilfer && mLockscreenShadeTransitionController.getQSDragProgress() == 0f && !mPrimaryBouncerInteractor.isInTransit()) { mInputManager.pilferPointers( mInputManager.pilferPointers( mOverlay.getOverlayView().getViewRootImpl().getInputToken()); mOverlay.getOverlayView().getViewRootImpl().getInputToken()); } } Loading packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java +49 −5 Original line number Original line Diff line number Diff line Loading @@ -1017,7 +1017,7 @@ public class UdfpsControllerTest extends SysuiTestCase { // THEN the display should be unconfigured once. If the timeout action is not // THEN the display should be unconfigured once. If the timeout action is not // cancelled, the display would be unconfigured twice which would cause two // cancelled, the display would be unconfigured twice which would cause two // FP attempts. // FP attempts. verify(mUdfpsView, times(1)).unconfigureDisplay(); verify(mUdfpsView).unconfigureDisplay(); } else { } else { verify(mUdfpsView, never()).unconfigureDisplay(); verify(mUdfpsView, never()).unconfigureDisplay(); } } Loading Loading @@ -1301,8 +1301,8 @@ public class UdfpsControllerTest extends SysuiTestCase { mBiometricExecutor.runAllReady(); mBiometricExecutor.runAllReady(); downEvent.recycle(); downEvent.recycle(); // THEN the touch is pilfered, expected twice (valid overlap and touch on sensor) // THEN the touch is pilfered verify(mInputManager, times(2)).pilferPointers(any()); verify(mInputManager).pilferPointers(any()); } } @Test @Test Loading Loading @@ -1340,7 +1340,7 @@ public class UdfpsControllerTest extends SysuiTestCase { downEvent.recycle(); downEvent.recycle(); // THEN the touch is NOT pilfered // THEN the touch is NOT pilfered verify(mInputManager, times(0)).pilferPointers(any()); verify(mInputManager, never()).pilferPointers(any()); } } @Test @Test Loading Loading @@ -1380,7 +1380,51 @@ public class UdfpsControllerTest extends SysuiTestCase { downEvent.recycle(); downEvent.recycle(); // THEN the touch is pilfered // THEN the touch is pilfered verify(mInputManager, times(1)).pilferPointers(any()); verify(mInputManager).pilferPointers(any()); } @Test public void onTouch_withNewTouchDetection_doNotPilferWhenPullingUpBouncer() throws RemoteException { final NormalizedTouchData touchData = new NormalizedTouchData(0, 0f, 0f, 0f, 0f, 0f, 0L, 0L); final TouchProcessorResult processorResultMove = new TouchProcessorResult.ProcessedTouch(InteractionEvent.DOWN, 1 /* pointerId */, touchData); // Enable new touch detection. when(mFeatureFlags.isEnabled(Flags.UDFPS_NEW_TOUCH_DETECTION)).thenReturn(true); // Configure UdfpsController to use FingerprintManager as opposed to AlternateTouchProvider. initUdfpsController(mOpticalProps, false /* hasAlternateTouchProvider */); // Configure UdfpsView to accept the ACTION_MOVE event when(mUdfpsView.isDisplayConfigured()).thenReturn(false); when(mUdfpsView.isWithinSensorArea(anyFloat(), anyFloat())).thenReturn(true); // GIVEN that the alternate bouncer is not showing and a11y touch exploration NOT enabled when(mAccessibilityManager.isTouchExplorationEnabled()).thenReturn(false); when(mAlternateBouncerInteractor.isVisibleState()).thenReturn(false); mOverlayController.showUdfpsOverlay(TEST_REQUEST_ID, mOpticalProps.sensorId, BiometricOverlayConstants.REASON_AUTH_KEYGUARD, mUdfpsOverlayControllerCallback); mFgExecutor.runAllReady(); verify(mUdfpsView).setOnTouchListener(mTouchListenerCaptor.capture()); // GIVEN a swipe up to bring up primary bouncer is in progress or swipe down for QS when(mPrimaryBouncerInteractor.isInTransit()).thenReturn(true); when(mLockscreenShadeTransitionController.getFractionToShade()).thenReturn(1f); // WHEN ACTION_MOVE is received and touch is within sensor when(mSinglePointerTouchProcessor.processTouch(any(), anyInt(), any())).thenReturn( processorResultMove); MotionEvent moveEvent = MotionEvent.obtain(0, 0, ACTION_MOVE, 0, 0, 0); mTouchListenerCaptor.getValue().onTouch(mUdfpsView, moveEvent); mBiometricExecutor.runAllReady(); moveEvent.recycle(); // THEN the touch is NOT pilfered verify(mInputManager, never()).pilferPointers(any()); } } @Test @Test Loading Loading
packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java +8 −2 Original line number Original line Diff line number Diff line Loading @@ -563,6 +563,7 @@ public class UdfpsController implements DozeReceiver, Dumpable { (TouchProcessorResult.ProcessedTouch) result; (TouchProcessorResult.ProcessedTouch) result; final NormalizedTouchData data = processedTouch.getTouchData(); final NormalizedTouchData data = processedTouch.getTouchData(); boolean shouldPilfer = false; mActivePointerId = processedTouch.getPointerOnSensorId(); mActivePointerId = processedTouch.getPointerOnSensorId(); switch (processedTouch.getEvent()) { switch (processedTouch.getEvent()) { case DOWN: case DOWN: Loading @@ -581,8 +582,7 @@ public class UdfpsController implements DozeReceiver, Dumpable { mStatusBarStateController.isDozing()); mStatusBarStateController.isDozing()); // Pilfer if valid overlap, don't allow following events to reach keyguard // Pilfer if valid overlap, don't allow following events to reach keyguard mInputManager.pilferPointers( shouldPilfer = true; mOverlay.getOverlayView().getViewRootImpl().getInputToken()); break; break; case UP: case UP: Loading Loading @@ -621,6 +621,12 @@ public class UdfpsController implements DozeReceiver, Dumpable { // Always pilfer pointers that are within sensor area or when alternate bouncer is showing // Always pilfer pointers that are within sensor area or when alternate bouncer is showing if (isWithinSensorArea(mOverlay.getOverlayView(), event.getRawX(), event.getRawY(), true) if (isWithinSensorArea(mOverlay.getOverlayView(), event.getRawX(), event.getRawY(), true) || mAlternateBouncerInteractor.isVisibleState()) { || mAlternateBouncerInteractor.isVisibleState()) { shouldPilfer = true; } // Execute the pilfer, never pilfer if a vertical swipe is in progress if (shouldPilfer && mLockscreenShadeTransitionController.getQSDragProgress() == 0f && !mPrimaryBouncerInteractor.isInTransit()) { mInputManager.pilferPointers( mInputManager.pilferPointers( mOverlay.getOverlayView().getViewRootImpl().getInputToken()); mOverlay.getOverlayView().getViewRootImpl().getInputToken()); } } Loading
packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java +49 −5 Original line number Original line Diff line number Diff line Loading @@ -1017,7 +1017,7 @@ public class UdfpsControllerTest extends SysuiTestCase { // THEN the display should be unconfigured once. If the timeout action is not // THEN the display should be unconfigured once. If the timeout action is not // cancelled, the display would be unconfigured twice which would cause two // cancelled, the display would be unconfigured twice which would cause two // FP attempts. // FP attempts. verify(mUdfpsView, times(1)).unconfigureDisplay(); verify(mUdfpsView).unconfigureDisplay(); } else { } else { verify(mUdfpsView, never()).unconfigureDisplay(); verify(mUdfpsView, never()).unconfigureDisplay(); } } Loading Loading @@ -1301,8 +1301,8 @@ public class UdfpsControllerTest extends SysuiTestCase { mBiometricExecutor.runAllReady(); mBiometricExecutor.runAllReady(); downEvent.recycle(); downEvent.recycle(); // THEN the touch is pilfered, expected twice (valid overlap and touch on sensor) // THEN the touch is pilfered verify(mInputManager, times(2)).pilferPointers(any()); verify(mInputManager).pilferPointers(any()); } } @Test @Test Loading Loading @@ -1340,7 +1340,7 @@ public class UdfpsControllerTest extends SysuiTestCase { downEvent.recycle(); downEvent.recycle(); // THEN the touch is NOT pilfered // THEN the touch is NOT pilfered verify(mInputManager, times(0)).pilferPointers(any()); verify(mInputManager, never()).pilferPointers(any()); } } @Test @Test Loading Loading @@ -1380,7 +1380,51 @@ public class UdfpsControllerTest extends SysuiTestCase { downEvent.recycle(); downEvent.recycle(); // THEN the touch is pilfered // THEN the touch is pilfered verify(mInputManager, times(1)).pilferPointers(any()); verify(mInputManager).pilferPointers(any()); } @Test public void onTouch_withNewTouchDetection_doNotPilferWhenPullingUpBouncer() throws RemoteException { final NormalizedTouchData touchData = new NormalizedTouchData(0, 0f, 0f, 0f, 0f, 0f, 0L, 0L); final TouchProcessorResult processorResultMove = new TouchProcessorResult.ProcessedTouch(InteractionEvent.DOWN, 1 /* pointerId */, touchData); // Enable new touch detection. when(mFeatureFlags.isEnabled(Flags.UDFPS_NEW_TOUCH_DETECTION)).thenReturn(true); // Configure UdfpsController to use FingerprintManager as opposed to AlternateTouchProvider. initUdfpsController(mOpticalProps, false /* hasAlternateTouchProvider */); // Configure UdfpsView to accept the ACTION_MOVE event when(mUdfpsView.isDisplayConfigured()).thenReturn(false); when(mUdfpsView.isWithinSensorArea(anyFloat(), anyFloat())).thenReturn(true); // GIVEN that the alternate bouncer is not showing and a11y touch exploration NOT enabled when(mAccessibilityManager.isTouchExplorationEnabled()).thenReturn(false); when(mAlternateBouncerInteractor.isVisibleState()).thenReturn(false); mOverlayController.showUdfpsOverlay(TEST_REQUEST_ID, mOpticalProps.sensorId, BiometricOverlayConstants.REASON_AUTH_KEYGUARD, mUdfpsOverlayControllerCallback); mFgExecutor.runAllReady(); verify(mUdfpsView).setOnTouchListener(mTouchListenerCaptor.capture()); // GIVEN a swipe up to bring up primary bouncer is in progress or swipe down for QS when(mPrimaryBouncerInteractor.isInTransit()).thenReturn(true); when(mLockscreenShadeTransitionController.getFractionToShade()).thenReturn(1f); // WHEN ACTION_MOVE is received and touch is within sensor when(mSinglePointerTouchProcessor.processTouch(any(), anyInt(), any())).thenReturn( processorResultMove); MotionEvent moveEvent = MotionEvent.obtain(0, 0, ACTION_MOVE, 0, 0, 0); mTouchListenerCaptor.getValue().onTouch(mUdfpsView, moveEvent); mBiometricExecutor.runAllReady(); moveEvent.recycle(); // THEN the touch is NOT pilfered verify(mInputManager, never()).pilferPointers(any()); } } @Test @Test Loading