diff --git a/core/java/android/view/HandwritingInitiator.java b/core/java/android/view/HandwritingInitiator.java index 6b604422ffbaa..77f3b1da92b41 100644 --- a/core/java/android/view/HandwritingInitiator.java +++ b/core/java/android/view/HandwritingInitiator.java @@ -151,14 +151,16 @@ public class HandwritingInitiator { // Either we've already tried to initiate handwriting, or the ongoing MotionEvent // sequence is considered to be tap, long-click or other gestures. if (!mState.mShouldInitHandwriting || mState.mExceedHandwritingSlop) { - return mState.mHasInitiatedHandwriting; + return mState.mHasInitiatedHandwriting + || mState.mHasPreparedHandwritingDelegation; } final long timeElapsed = motionEvent.getEventTime() - mState.mStylusDownTimeInMillis; if (timeElapsed > mHandwritingTimeoutInMillis) { mState.mShouldInitHandwriting = false; - return mState.mHasInitiatedHandwriting; + return mState.mHasInitiatedHandwriting + || mState.mHasPreparedHandwritingDelegation; } final int pointerIndex = motionEvent.findPointerIndex(mState.mStylusPointerId); @@ -183,12 +185,13 @@ public class HandwritingInitiator { mImm.prepareStylusHandwritingDelegation( candidateView, delegatePackageName); candidateView.getHandwritingDelegatorCallback().run(); + mState.mHasPreparedHandwritingDelegation = true; } else { requestFocusWithoutReveal(candidateView); } } } - return mState.mHasInitiatedHandwriting; + return mState.mHasInitiatedHandwriting || mState.mHasPreparedHandwritingDelegation; } return false; } @@ -568,6 +571,8 @@ public class HandwritingInitiator { * Whether handwriting mode has already been initiated for the current MotionEvent sequence. */ private boolean mHasInitiatedHandwriting; + + private boolean mHasPreparedHandwritingDelegation; /** * Whether the current ongoing stylus MotionEvent sequence already exceeds the * handwriting slop. @@ -593,6 +598,7 @@ public class HandwritingInitiator { mShouldInitHandwriting = true; mHasInitiatedHandwriting = false; + mHasPreparedHandwritingDelegation = false; mExceedHandwritingSlop = false; } } diff --git a/core/tests/coretests/src/android/view/stylus/HandwritingInitiatorTest.java b/core/tests/coretests/src/android/view/stylus/HandwritingInitiatorTest.java index fccb177dad4fd..8ae63816ba163 100644 --- a/core/tests/coretests/src/android/view/stylus/HandwritingInitiatorTest.java +++ b/core/tests/coretests/src/android/view/stylus/HandwritingInitiatorTest.java @@ -268,6 +268,41 @@ public class HandwritingInitiatorTest { verify(mHandwritingInitiator, times(1)).tryAcceptStylusHandwritingDelegation(delegateView); } + @Test + public void onTouchEvent_startHandwriting_delegate_touchEventsHandled() { + // There is no delegator view and the delegate callback does nothing so handwriting will not + // be started. This is so we can test how touch events are handled before handwriting is + // started. + mTestView1.setHandwritingDelegatorCallback(() -> {}); + + final int x1 = (sHwArea1.left + sHwArea1.right) / 2; + final int y = (sHwArea1.top + sHwArea1.bottom) / 2; + MotionEvent stylusEvent1 = createStylusEvent(ACTION_DOWN, x1, y, 0); + boolean onTouchEventResult1 = mHandwritingInitiator.onTouchEvent(stylusEvent1); + + final int x2 = x1 + mHandwritingSlop / 2; + MotionEvent stylusEvent2 = createStylusEvent(ACTION_MOVE, x2, y, 0); + boolean onTouchEventResult2 = mHandwritingInitiator.onTouchEvent(stylusEvent2); + + final int x3 = x2 + mHandwritingSlop * 2; + MotionEvent stylusEvent3 = createStylusEvent(ACTION_MOVE, x3, y, 0); + boolean onTouchEventResult3 = mHandwritingInitiator.onTouchEvent(stylusEvent3); + + final int x4 = x3 + mHandwritingSlop * 2; + MotionEvent stylusEvent4 = createStylusEvent(ACTION_MOVE, x4, y, 0); + boolean onTouchEventResult4 = mHandwritingInitiator.onTouchEvent(stylusEvent4); + + assertThat(onTouchEventResult1).isFalse(); + // stylusEvent2 does not trigger delegation since the touch slop distance has not been + // exceeded. onTouchEvent should return false so that the event is dispatched to the view + // tree. + assertThat(onTouchEventResult2).isFalse(); + // After delegation is triggered by stylusEvent3, onTouchEvent should return true for + // ACTION_MOVE events so that the events are not dispatched to the view tree. + assertThat(onTouchEventResult3).isTrue(); + assertThat(onTouchEventResult4).isTrue(); + } + @Test public void onTouchEvent_notStartHandwriting_whenHandwritingNotAvailable() { final Rect rect = new Rect(600, 600, 900, 900);