Loading core/java/android/view/HandwritingInitiator.java +11 −36 Original line number Diff line number Diff line Loading @@ -208,6 +208,7 @@ public class HandwritingInitiator { candidateView.getHandwritingDelegatorCallback().run(); mState.mHasPreparedHandwritingDelegation = true; } else { mState.mPendingConnectedView = new WeakReference<>(candidateView); requestFocusWithoutReveal(candidateView); } } Loading Loading @@ -269,8 +270,9 @@ public class HandwritingInitiator { mShowHoverIconForConnectedView = false; return; } if (mState != null && mState.mShouldInitHandwriting) { tryStartHandwriting(); if (mState != null && mState.mPendingConnectedView != null && mState.mPendingConnectedView.get() == view) { startHandwriting(view); } } } Loading @@ -295,40 +297,6 @@ public class HandwritingInitiator { } } /** * Try to initiate handwriting. For this method to successfully send startHandwriting signal, * the following 3 conditions should meet: * a) The stylus movement exceeds the touchSlop. * b) A View has built InputConnection with IME. * c) The stylus event lands into the connected View's boundary. * This method will immediately fail without any side effect if condition a or b is not met. * However, if both condition a and b are met but the condition c is not met, it will reset the * internal states. And HandwritingInitiator won't attempt to call startHandwriting until the * next ACTION_DOWN. */ private void tryStartHandwriting() { if (!mState.mExceedHandwritingSlop) { return; } final View connectedView = getConnectedView(); if (connectedView == null) { return; } if (!connectedView.isAutoHandwritingEnabled()) { clearConnectedView(); return; } final Rect handwritingArea = getViewHandwritingArea(connectedView); if (isInHandwritingArea( handwritingArea, mState.mStylusDownX, mState.mStylusDownY, connectedView)) { startHandwriting(connectedView); } else { mState.mShouldInitHandwriting = false; } } /** Starts a stylus handwriting session for the view. */ @VisibleForTesting public void startHandwriting(@NonNull View view) { Loading Loading @@ -631,6 +599,7 @@ public class HandwritingInitiator { private boolean mHasInitiatedHandwriting; private boolean mHasPreparedHandwritingDelegation; /** * Whether the current ongoing stylus MotionEvent sequence already exceeds the * handwriting slop. Loading @@ -639,6 +608,12 @@ public class HandwritingInitiator { */ private boolean mExceedHandwritingSlop; /** * A view which has requested focus and is pending input connection creation. When an input * connection is created for the view, a handwriting session should be started for the view. */ private WeakReference<View> mPendingConnectedView = null; /** The pointer id of the stylus pointer that is being tracked. */ private final int mStylusPointerId; /** The time stamp when the stylus pointer goes down. */ Loading core/tests/coretests/src/android/view/stylus/HandwritingInitiatorTest.java +10 −4 Original line number Diff line number Diff line Loading @@ -221,8 +221,10 @@ public class HandwritingInitiatorTest { @Test public void onTouchEvent_startHandwriting_inputConnectionBuilt_stylusMoveInExtendedHWArea() { // The stylus down point is between mTestView1 and mTestView2, but it is within the // extended handwriting area of both views. It is closer to mTestView1. final int x1 = sHwArea1.right + HW_BOUNDS_OFFSETS_RIGHT_PX / 2; final int y1 = sHwArea1.bottom + HW_BOUNDS_OFFSETS_BOTTOM_PX / 2; final int y1 = sHwArea1.bottom + (sHwArea2.top - sHwArea1.bottom) / 3; MotionEvent stylusEvent1 = createStylusEvent(ACTION_DOWN, x1, y1, 0); mHandwritingInitiator.onTouchEvent(stylusEvent1); Loading @@ -231,10 +233,14 @@ public class HandwritingInitiatorTest { MotionEvent stylusEvent2 = createStylusEvent(ACTION_MOVE, x2, y2, 0); mHandwritingInitiator.onTouchEvent(stylusEvent2); // InputConnection is created after stylus movement. mHandwritingInitiator.onInputConnectionCreated(mTestView1); // First create InputConnection for mTestView2 and verify that handwriting is not started. mHandwritingInitiator.onInputConnectionCreated(mTestView2); verify(mHandwritingInitiator, never()).startHandwriting(mTestView2); verify(mHandwritingInitiator, times(1)).startHandwriting(mTestView1); // Next create InputConnection for mTextView1. Handwriting is started for this view since // the stylus down point is closest to this view. mHandwritingInitiator.onInputConnectionCreated(mTestView1); verify(mHandwritingInitiator).startHandwriting(mTestView1); } @Test Loading Loading
core/java/android/view/HandwritingInitiator.java +11 −36 Original line number Diff line number Diff line Loading @@ -208,6 +208,7 @@ public class HandwritingInitiator { candidateView.getHandwritingDelegatorCallback().run(); mState.mHasPreparedHandwritingDelegation = true; } else { mState.mPendingConnectedView = new WeakReference<>(candidateView); requestFocusWithoutReveal(candidateView); } } Loading Loading @@ -269,8 +270,9 @@ public class HandwritingInitiator { mShowHoverIconForConnectedView = false; return; } if (mState != null && mState.mShouldInitHandwriting) { tryStartHandwriting(); if (mState != null && mState.mPendingConnectedView != null && mState.mPendingConnectedView.get() == view) { startHandwriting(view); } } } Loading @@ -295,40 +297,6 @@ public class HandwritingInitiator { } } /** * Try to initiate handwriting. For this method to successfully send startHandwriting signal, * the following 3 conditions should meet: * a) The stylus movement exceeds the touchSlop. * b) A View has built InputConnection with IME. * c) The stylus event lands into the connected View's boundary. * This method will immediately fail without any side effect if condition a or b is not met. * However, if both condition a and b are met but the condition c is not met, it will reset the * internal states. And HandwritingInitiator won't attempt to call startHandwriting until the * next ACTION_DOWN. */ private void tryStartHandwriting() { if (!mState.mExceedHandwritingSlop) { return; } final View connectedView = getConnectedView(); if (connectedView == null) { return; } if (!connectedView.isAutoHandwritingEnabled()) { clearConnectedView(); return; } final Rect handwritingArea = getViewHandwritingArea(connectedView); if (isInHandwritingArea( handwritingArea, mState.mStylusDownX, mState.mStylusDownY, connectedView)) { startHandwriting(connectedView); } else { mState.mShouldInitHandwriting = false; } } /** Starts a stylus handwriting session for the view. */ @VisibleForTesting public void startHandwriting(@NonNull View view) { Loading Loading @@ -631,6 +599,7 @@ public class HandwritingInitiator { private boolean mHasInitiatedHandwriting; private boolean mHasPreparedHandwritingDelegation; /** * Whether the current ongoing stylus MotionEvent sequence already exceeds the * handwriting slop. Loading @@ -639,6 +608,12 @@ public class HandwritingInitiator { */ private boolean mExceedHandwritingSlop; /** * A view which has requested focus and is pending input connection creation. When an input * connection is created for the view, a handwriting session should be started for the view. */ private WeakReference<View> mPendingConnectedView = null; /** The pointer id of the stylus pointer that is being tracked. */ private final int mStylusPointerId; /** The time stamp when the stylus pointer goes down. */ Loading
core/tests/coretests/src/android/view/stylus/HandwritingInitiatorTest.java +10 −4 Original line number Diff line number Diff line Loading @@ -221,8 +221,10 @@ public class HandwritingInitiatorTest { @Test public void onTouchEvent_startHandwriting_inputConnectionBuilt_stylusMoveInExtendedHWArea() { // The stylus down point is between mTestView1 and mTestView2, but it is within the // extended handwriting area of both views. It is closer to mTestView1. final int x1 = sHwArea1.right + HW_BOUNDS_OFFSETS_RIGHT_PX / 2; final int y1 = sHwArea1.bottom + HW_BOUNDS_OFFSETS_BOTTOM_PX / 2; final int y1 = sHwArea1.bottom + (sHwArea2.top - sHwArea1.bottom) / 3; MotionEvent stylusEvent1 = createStylusEvent(ACTION_DOWN, x1, y1, 0); mHandwritingInitiator.onTouchEvent(stylusEvent1); Loading @@ -231,10 +233,14 @@ public class HandwritingInitiatorTest { MotionEvent stylusEvent2 = createStylusEvent(ACTION_MOVE, x2, y2, 0); mHandwritingInitiator.onTouchEvent(stylusEvent2); // InputConnection is created after stylus movement. mHandwritingInitiator.onInputConnectionCreated(mTestView1); // First create InputConnection for mTestView2 and verify that handwriting is not started. mHandwritingInitiator.onInputConnectionCreated(mTestView2); verify(mHandwritingInitiator, never()).startHandwriting(mTestView2); verify(mHandwritingInitiator, times(1)).startHandwriting(mTestView1); // Next create InputConnection for mTextView1. Handwriting is started for this view since // the stylus down point is closest to this view. mHandwritingInitiator.onInputConnectionCreated(mTestView1); verify(mHandwritingInitiator).startHandwriting(mTestView1); } @Test Loading