Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 696c471c authored by Taran Singh's avatar Taran Singh Committed by Android (Google) Code Review
Browse files

Merge "Additional cases for stylus handwriting without IC" into main

parents 91f4171f 90ac3910
Loading
Loading
Loading
Loading
+50 −14
Original line number Original line Diff line number Diff line
@@ -225,6 +225,7 @@ public class HandwritingInitiator {
                    View candidateView = findBestCandidateView(mState.mStylusDownX,
                    View candidateView = findBestCandidateView(mState.mStylusDownX,
                            mState.mStylusDownY, /* isHover */ false);
                            mState.mStylusDownY, /* isHover */ false);
                    if (candidateView != null && candidateView.isEnabled()) {
                    if (candidateView != null && candidateView.isEnabled()) {
                        boolean candidateHasFocus = candidateView.hasFocus();
                        if (shouldShowHandwritingUnavailableMessageForView(candidateView)) {
                        if (shouldShowHandwritingUnavailableMessageForView(candidateView)) {
                            int messagesResId = (candidateView instanceof TextView tv
                            int messagesResId = (candidateView instanceof TextView tv
                                    && tv.isAnyPasswordInputType())
                                    && tv.isAnyPasswordInputType())
@@ -243,23 +244,24 @@ public class HandwritingInitiator {
                                    | MotionEvent.ACTION_CANCEL);
                                    | MotionEvent.ACTION_CANCEL);
                            candidateView.getRootView().dispatchTouchEvent(motionEvent);
                            candidateView.getRootView().dispatchTouchEvent(motionEvent);
                        } else if (candidateView == getConnectedOrFocusedView()) {
                        } else if (candidateView == getConnectedOrFocusedView()) {
                            if (!mInitiateWithoutConnection && !candidateView.hasFocus()) {
                            if (!candidateHasFocus) {
                                requestFocusWithoutReveal(candidateView);
                                requestFocusWithoutReveal(candidateView);
                            }
                            }
                            startHandwriting(candidateView);
                            startHandwriting(candidateView);
                        } else if (candidateView.getHandwritingDelegatorCallback() != null) {
                        } else if (candidateView.getHandwritingDelegatorCallback() != null) {
                            prepareDelegation(candidateView);
                            prepareDelegation(candidateView);
                        } else {
                        } else {
                            if (!mInitiateWithoutConnection) {
                            if (mInitiateWithoutConnection) {
                                mState.mPendingConnectedView = new WeakReference<>(candidateView);
                                if (!candidateHasFocus) {
                                    // schedule for view focus.
                                    mState.mPendingFocusedView = new WeakReference<>(candidateView);
                                    requestFocusWithoutReveal(candidateView);
                                }
                                }
                            if (!candidateView.hasFocus()) {
                            } else {
                                mState.mPendingConnectedView = new WeakReference<>(candidateView);
                                if (!candidateHasFocus) {
                                    requestFocusWithoutReveal(candidateView);
                                    requestFocusWithoutReveal(candidateView);
                                }
                                }
                            if (mInitiateWithoutConnection
                                    && updateFocusedView(candidateView,
                                            /* fromTouchEvent */ true)) {
                                startHandwriting(candidateView);
                            }
                            }
                        }
                        }
                    }
                    }
@@ -285,6 +287,9 @@ public class HandwritingInitiator {
     * gained focus.
     * gained focus.
     */
     */
    public void onDelegateViewFocused(@NonNull View view) {
    public void onDelegateViewFocused(@NonNull View view) {
        if (mInitiateWithoutConnection) {
            onEditorFocused(view);
        }
        if (view == getConnectedView()) {
        if (view == getConnectedView()) {
            tryAcceptStylusHandwritingDelegation(view);
            tryAcceptStylusHandwritingDelegation(view);
        }
        }
@@ -331,6 +336,33 @@ public class HandwritingInitiator {
        }
        }
    }
    }


    /**
     * Notify HandwritingInitiator that a new editor is focused.
     * @param view the view that received focus.
     */
    @VisibleForTesting
    public void onEditorFocused(@NonNull View view) {
        if (!mInitiateWithoutConnection) {
            return;
        }

        if (!view.isAutoHandwritingEnabled()) {
            clearFocusedView(view);
            return;
        }

        final View focusedView = getFocusedView();
        if (focusedView == view) {
            return;
        }
        updateFocusedView(view);

        if (mState != null && mState.mPendingFocusedView != null
                && mState.mPendingFocusedView.get() == view) {
            startHandwriting(view);
        }
    }

    /**
    /**
     * Notify HandwritingInitiator that the InputConnection has closed for the given view.
     * Notify HandwritingInitiator that the InputConnection has closed for the given view.
     * The caller of this method should guarantee that each onInputConnectionClosed call
     * The caller of this method should guarantee that each onInputConnectionClosed call
@@ -378,7 +410,7 @@ public class HandwritingInitiator {
     * @return {@code true} if handwriting can initiate for given view.
     * @return {@code true} if handwriting can initiate for given view.
     */
     */
    @VisibleForTesting
    @VisibleForTesting
    public boolean updateFocusedView(@NonNull View view, boolean fromTouchEvent) {
    public boolean updateFocusedView(@NonNull View view) {
        if (!view.shouldInitiateHandwriting()) {
        if (!view.shouldInitiateHandwriting()) {
            mFocusedView = null;
            mFocusedView = null;
            return false;
            return false;
@@ -390,9 +422,7 @@ public class HandwritingInitiator {
            // A new view just gain focus. By default, we should show hover icon for it.
            // A new view just gain focus. By default, we should show hover icon for it.
            mShowHoverIconForConnectedView = true;
            mShowHoverIconForConnectedView = true;
        }
        }
        if (!fromTouchEvent && view.isHandwritingDelegate()) {

            tryAcceptStylusHandwritingDelegation(view);
        }
        return true;
        return true;
    }
    }


@@ -861,6 +891,12 @@ public class HandwritingInitiator {
         */
         */
        private WeakReference<View> mPendingConnectedView = null;
        private WeakReference<View> mPendingConnectedView = null;


        /**
         * A view which has requested focus and is yet to receive it.
         * When view receives focus, a handwriting session should be started for the view.
         */
        private WeakReference<View> mPendingFocusedView = null;

        /** The pointer id of the stylus pointer that is being tracked. */
        /** The pointer id of the stylus pointer that is being tracked. */
        private final int mStylusPointerId;
        private final int mStylusPointerId;
        /** The time stamp when the stylus pointer goes down. */
        /** The time stamp when the stylus pointer goes down. */
+10 −4
Original line number Original line Diff line number Diff line
@@ -44,6 +44,7 @@ import static android.view.flags.Flags.toolkitMetricsForFrameRateDecision;
import static android.view.flags.Flags.toolkitSetFrameRateReadOnly;
import static android.view.flags.Flags.toolkitSetFrameRateReadOnly;
import static android.view.flags.Flags.viewVelocityApi;
import static android.view.flags.Flags.viewVelocityApi;
import static android.view.inputmethod.Flags.FLAG_HOME_SCREEN_HANDWRITING_DELEGATOR;
import static android.view.inputmethod.Flags.FLAG_HOME_SCREEN_HANDWRITING_DELEGATOR;
import static android.view.inputmethod.Flags.initiationWithoutInputConnection;
import static com.android.internal.util.FrameworkStatsLog.TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__DEEP_PRESS;
import static com.android.internal.util.FrameworkStatsLog.TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__DEEP_PRESS;
import static com.android.internal.util.FrameworkStatsLog.TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__LONG_PRESS;
import static com.android.internal.util.FrameworkStatsLog.TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__LONG_PRESS;
@@ -8669,11 +8670,12 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
            onFocusLost();
            onFocusLost();
        } else if (hasWindowFocus()) {
        } else if (hasWindowFocus()) {
            notifyFocusChangeToImeFocusController(true /* hasFocus */);
            notifyFocusChangeToImeFocusController(true /* hasFocus */);
            if (mIsHandwritingDelegate) {
            ViewRootImpl viewRoot = getViewRootImpl();
            ViewRootImpl viewRoot = getViewRootImpl();
            if (viewRoot != null) {
            if (viewRoot != null) {
                if (mIsHandwritingDelegate) {
                    viewRoot.getHandwritingInitiator().onDelegateViewFocused(this);
                    viewRoot.getHandwritingInitiator().onDelegateViewFocused(this);
                } else if (initiationWithoutInputConnection() && onCheckIsTextEditor()) {
                    viewRoot.getHandwritingInitiator().onEditorFocused(this);
                }
                }
            }
            }
        }
        }
@@ -16702,6 +16704,10 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
            onFocusLost();
            onFocusLost();
        } else if ((mPrivateFlags & PFLAG_FOCUSED) != 0) {
        } else if ((mPrivateFlags & PFLAG_FOCUSED) != 0) {
            notifyFocusChangeToImeFocusController(true /* hasFocus */);
            notifyFocusChangeToImeFocusController(true /* hasFocus */);
            ViewRootImpl viewRoot = getViewRootImpl();
            if (viewRoot != null && initiationWithoutInputConnection() && onCheckIsTextEditor()) {
                viewRoot.getHandwritingInitiator().onEditorFocused(this);
            }
        }
        }
        refreshDrawableState();
        refreshDrawableState();
+0 −4
Original line number Original line Diff line number Diff line
@@ -3499,10 +3499,6 @@ public final class InputMethodManager {
            return false;
            return false;
        }
        }
        mServedView = mNextServedView;
        mServedView = mNextServedView;
        if (initiationWithoutInputConnection() && mServedView.isHandwritingDelegate()) {
            mServedView.getViewRootImpl().getHandwritingInitiator().onDelegateViewFocused(
                    mServedView);
        }
        if (mServedInputConnection != null) {
        if (mServedInputConnection != null) {
            mServedInputConnection.finishComposingTextFromImm();
            mServedInputConnection.finishComposingTextFromImm();
        }
        }
+45 −76
Original line number Original line Diff line number Diff line
@@ -52,6 +52,7 @@ import android.view.PointerIcon;
import android.view.View;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.view.ViewGroup;
import android.view.inputmethod.Flags;
import android.view.inputmethod.InputMethodManager;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.EditText;


@@ -135,7 +136,7 @@ public class HandwritingInitiatorTest {
        when(mTestView1.getOffsetForPosition(anyFloat(), anyFloat())).thenReturn(4);
        when(mTestView1.getOffsetForPosition(anyFloat(), anyFloat())).thenReturn(4);
        when(mTestView1.getLineAtCoordinate(anyFloat())).thenReturn(0);
        when(mTestView1.getLineAtCoordinate(anyFloat())).thenReturn(0);


        mHandwritingInitiator.onInputConnectionCreated(mTestView1);
        onEditorFocusedOrConnectionCreated(mTestView1);
        final int x1 = (sHwArea1.left + sHwArea1.right) / 2;
        final int x1 = (sHwArea1.left + sHwArea1.right) / 2;
        final int y1 = (sHwArea1.top + sHwArea1.bottom) / 2;
        final int y1 = (sHwArea1.top + sHwArea1.bottom) / 2;
        MotionEvent stylusEvent1 = createStylusEvent(ACTION_DOWN, x1, y1, 0);
        MotionEvent stylusEvent1 = createStylusEvent(ACTION_DOWN, x1, y1, 0);
@@ -172,7 +173,7 @@ public class HandwritingInitiatorTest {
        when(mTestView1.getOffsetForPosition(anyFloat(), anyFloat())).thenReturn(4);
        when(mTestView1.getOffsetForPosition(anyFloat(), anyFloat())).thenReturn(4);
        when(mTestView1.getLineAtCoordinate(anyFloat())).thenReturn(2);
        when(mTestView1.getLineAtCoordinate(anyFloat())).thenReturn(2);


        mHandwritingInitiator.onInputConnectionCreated(mTestView1);
        onEditorFocusedOrConnectionCreated(mTestView1);
        final int x1 = (sHwArea1.left + sHwArea1.right) / 2;
        final int x1 = (sHwArea1.left + sHwArea1.right) / 2;
        final int y1 = (sHwArea1.top + sHwArea1.bottom) / 2;
        final int y1 = (sHwArea1.top + sHwArea1.bottom) / 2;
        MotionEvent stylusEvent1 = createStylusEvent(ACTION_DOWN, x1, y1, 0);
        MotionEvent stylusEvent1 = createStylusEvent(ACTION_DOWN, x1, y1, 0);
@@ -202,7 +203,7 @@ public class HandwritingInitiatorTest {


    @Test
    @Test
    public void onTouchEvent_startHandwritingOnce_when_stylusMoveMultiTimes_withinHWArea() {
    public void onTouchEvent_startHandwritingOnce_when_stylusMoveMultiTimes_withinHWArea() {
        mHandwritingInitiator.onInputConnectionCreated(mTestView1);
        onEditorFocusedOrConnectionCreated(mTestView1);
        final int x1 = (sHwArea1.left + sHwArea1.right) / 2;
        final int x1 = (sHwArea1.left + sHwArea1.right) / 2;
        final int y1 = (sHwArea1.top + sHwArea1.bottom) / 2;
        final int y1 = (sHwArea1.top + sHwArea1.bottom) / 2;
        MotionEvent stylusEvent1 = createStylusEvent(ACTION_DOWN, x1, y1, 0);
        MotionEvent stylusEvent1 = createStylusEvent(ACTION_DOWN, x1, y1, 0);
@@ -246,9 +247,7 @@ public class HandwritingInitiatorTest {
        when(mTestView1.getOffsetForPosition(anyFloat(), anyFloat())).thenReturn(4);
        when(mTestView1.getOffsetForPosition(anyFloat(), anyFloat())).thenReturn(4);
        when(mTestView1.getLineAtCoordinate(anyFloat())).thenReturn(0);
        when(mTestView1.getLineAtCoordinate(anyFloat())).thenReturn(0);


        if (!mInitiateWithoutConnection) {
        onEditorFocusedOrConnectionCreated(mTestView1);
            mHandwritingInitiator.onInputConnectionCreated(mTestView1);
        }
        final int x1 = sHwArea1.left - HW_BOUNDS_OFFSETS_LEFT_PX / 2;
        final int x1 = sHwArea1.left - HW_BOUNDS_OFFSETS_LEFT_PX / 2;
        final int y1 = sHwArea1.top - HW_BOUNDS_OFFSETS_TOP_PX / 2;
        final int y1 = sHwArea1.top - HW_BOUNDS_OFFSETS_TOP_PX / 2;
        MotionEvent stylusEvent1 = createStylusEvent(ACTION_DOWN, x1, y1, 0);
        MotionEvent stylusEvent1 = createStylusEvent(ACTION_DOWN, x1, y1, 0);
@@ -284,13 +283,7 @@ public class HandwritingInitiatorTest {
        MotionEvent stylusEvent2 = createStylusEvent(ACTION_MOVE, x2, y2, 0);
        MotionEvent stylusEvent2 = createStylusEvent(ACTION_MOVE, x2, y2, 0);
        mHandwritingInitiator.onTouchEvent(stylusEvent2);
        mHandwritingInitiator.onTouchEvent(stylusEvent2);


        if (mInitiateWithoutConnection) {
        onEditorFocusedOrConnectionCreated(mTestView1);
            // Focus is changed after stylus movement.
            mHandwritingInitiator.updateFocusedView(mTestView1, /*fromTouchEvent*/ true);
        } else {
            // InputConnection is created after stylus movement.
            mHandwritingInitiator.onInputConnectionCreated(mTestView1);
        }


        verify(mHandwritingInitiator, times(1)).startHandwriting(mTestView1);
        verify(mHandwritingInitiator, times(1)).startHandwriting(mTestView1);
    }
    }
@@ -312,24 +305,11 @@ public class HandwritingInitiatorTest {
        final int y2 = y1;
        final int y2 = y1;
        MotionEvent stylusEvent2 = createStylusEvent(ACTION_MOVE, x2, y2, 0);
        MotionEvent stylusEvent2 = createStylusEvent(ACTION_MOVE, x2, y2, 0);
        mHandwritingInitiator.onTouchEvent(stylusEvent2);
        mHandwritingInitiator.onTouchEvent(stylusEvent2);

        onEditorFocusedOrConnectionCreated(mTestView2);
        if (!mInitiateWithoutConnection) {
            // First create InputConnection for mTestView2 and verify that handwriting is not
            // started.
            mHandwritingInitiator.onInputConnectionCreated(mTestView2);
        }

        // Note: mTestView2 receives focus when initiationWithoutInputConnection() is enabled.
        // Note: mTestView2 receives focus when initiationWithoutInputConnection() is enabled.
        //  verify that handwriting is not started.
        //  verify that handwriting is not started.
        verify(mHandwritingInitiator, never()).startHandwriting(mTestView2);
        verify(mHandwritingInitiator, never()).startHandwriting(mTestView2);
        if (mInitiateWithoutConnection) {
        onEditorFocusedOrConnectionCreated(mTestView1);
            // Focus is changed after stylus movement.
            mHandwritingInitiator.updateFocusedView(mTestView1, /*fromTouchEvent*/ true);
        } else {
            // Next create InputConnection for mTextView1. Handwriting is started for this view
            // since the stylus down point is closest to this view.
            mHandwritingInitiator.onInputConnectionCreated(mTestView1);
        }
        // Handwriting is started for this view since  the stylus down point is closest to this
        // Handwriting is started for this view since  the stylus down point is closest to this
        // view.
        // view.
        verify(mHandwritingInitiator).startHandwriting(mTestView1);
        verify(mHandwritingInitiator).startHandwriting(mTestView1);
@@ -351,7 +331,7 @@ public class HandwritingInitiatorTest {
        delegateView.setIsHandwritingDelegate(true);
        delegateView.setIsHandwritingDelegate(true);


        mTestView1.setHandwritingDelegatorCallback(
        mTestView1.setHandwritingDelegatorCallback(
                () -> mHandwritingInitiator.onInputConnectionCreated(delegateView));
                () -> onEditorFocusedOrConnectionCreated(delegateView));


        final int x1 = (sHwArea1.left + sHwArea1.right) / 2;
        final int x1 = (sHwArea1.left + sHwArea1.right) / 2;
        final int y1 = (sHwArea1.top + sHwArea1.bottom) / 2;
        final int y1 = (sHwArea1.top + sHwArea1.bottom) / 2;
@@ -371,17 +351,15 @@ public class HandwritingInitiatorTest {
    public void onTouchEvent_tryAcceptDelegation_delegatorCallbackFocusesDelegate() {
    public void onTouchEvent_tryAcceptDelegation_delegatorCallbackFocusesDelegate() {
        View delegateView = new EditText(mContext);
        View delegateView = new EditText(mContext);
        delegateView.setIsHandwritingDelegate(true);
        delegateView.setIsHandwritingDelegate(true);
        if (mInitiateWithoutConnection) {
            mHandwritingInitiator.onEditorFocused(delegateView);
        }
        mHandwritingInitiator.onInputConnectionCreated(delegateView);
        mHandwritingInitiator.onInputConnectionCreated(delegateView);
        reset(mHandwritingInitiator);
        reset(mHandwritingInitiator);


        if (mInitiateWithoutConnection) {

            mTestView1.setHandwritingDelegatorCallback(
                    () -> mHandwritingInitiator.updateFocusedView(
                            delegateView, /*fromTouchEvent*/ false));
        } else  {
        mTestView1.setHandwritingDelegatorCallback(
        mTestView1.setHandwritingDelegatorCallback(
                () -> mHandwritingInitiator.onDelegateViewFocused(delegateView));
                () -> mHandwritingInitiator.onDelegateViewFocused(delegateView));
        }


        final int x1 = (sHwArea1.left + sHwArea1.right) / 2;
        final int x1 = (sHwArea1.left + sHwArea1.right) / 2;
        final int y1 = (sHwArea1.top + sHwArea1.bottom) / 2;
        final int y1 = (sHwArea1.top + sHwArea1.bottom) / 2;
@@ -393,7 +371,7 @@ public class HandwritingInitiatorTest {
        MotionEvent stylusEvent2 = createStylusEvent(ACTION_MOVE, x2, y2, 0);
        MotionEvent stylusEvent2 = createStylusEvent(ACTION_MOVE, x2, y2, 0);
        mHandwritingInitiator.onTouchEvent(stylusEvent2);
        mHandwritingInitiator.onTouchEvent(stylusEvent2);


        verify(mHandwritingInitiator, times(1)).tryAcceptStylusHandwritingDelegation(delegateView);
        verify(mHandwritingInitiator, times(1)).tryAcceptStylusHandwritingDelegation(any());
    }
    }


    @Test
    @Test
@@ -431,14 +409,6 @@ public class HandwritingInitiatorTest {
        assertThat(onTouchEventResult4).isTrue();
        assertThat(onTouchEventResult4).isTrue();
    }
    }


    private void callOnInputConnectionOrUpdateViewFocus(View view) {
        if (mInitiateWithoutConnection) {
            mHandwritingInitiator.updateFocusedView(view, /*fromTouchEvent*/ true);
        } else {
            mHandwritingInitiator.onInputConnectionCreated(view);
        }
    }

    @Test
    @Test
    public void onTouchEvent_notStartHandwriting_whenHandwritingNotAvailable() {
    public void onTouchEvent_notStartHandwriting_whenHandwritingNotAvailable() {
        final Rect rect = new Rect(600, 600, 900, 900);
        final Rect rect = new Rect(600, 600, 900, 900);
@@ -446,7 +416,7 @@ public class HandwritingInitiatorTest {
                false /* isStylusHandwritingAvailable */);
                false /* isStylusHandwritingAvailable */);
        mHandwritingInitiator.updateHandwritingAreasForView(testView);
        mHandwritingInitiator.updateHandwritingAreasForView(testView);


        callOnInputConnectionOrUpdateViewFocus(testView);
        onEditorFocusedOrConnectionCreated(testView);
        final int x1 = (rect.left + rect.right) / 2;
        final int x1 = (rect.left + rect.right) / 2;
        final int y1 = (rect.top + rect.bottom) / 2;
        final int y1 = (rect.top + rect.bottom) / 2;
        MotionEvent stylusEvent1 = createStylusEvent(ACTION_DOWN, x1, y1, 0);
        MotionEvent stylusEvent1 = createStylusEvent(ACTION_DOWN, x1, y1, 0);
@@ -465,7 +435,7 @@ public class HandwritingInitiatorTest {


    @Test
    @Test
    public void onTouchEvent_notStartHandwriting_when_stylusTap_withinHWArea() {
    public void onTouchEvent_notStartHandwriting_when_stylusTap_withinHWArea() {
        callOnInputConnectionOrUpdateViewFocus(mTestView1);
        onEditorFocusedOrConnectionCreated(mTestView1);
        final int x1 = 200;
        final int x1 = 200;
        final int y1 = 200;
        final int y1 = 200;
        MotionEvent stylusEvent1 = createStylusEvent(ACTION_DOWN, x1, y1, 0);
        MotionEvent stylusEvent1 = createStylusEvent(ACTION_DOWN, x1, y1, 0);
@@ -481,7 +451,7 @@ public class HandwritingInitiatorTest {


    @Test
    @Test
    public void onTouchEvent_notStartHandwriting_when_stylusMove_outOfHWArea() {
    public void onTouchEvent_notStartHandwriting_when_stylusMove_outOfHWArea() {
        callOnInputConnectionOrUpdateViewFocus(mTestView1);
        onEditorFocusedOrConnectionCreated(mTestView1);
        final int x1 = 10;
        final int x1 = 10;
        final int y1 = 10;
        final int y1 = 10;
        MotionEvent stylusEvent1 = createStylusEvent(ACTION_DOWN, x1, y1, 0);
        MotionEvent stylusEvent1 = createStylusEvent(ACTION_DOWN, x1, y1, 0);
@@ -497,7 +467,7 @@ public class HandwritingInitiatorTest {


    @Test
    @Test
    public void onTouchEvent_notStartHandwriting_when_stylusMove_afterTimeOut() {
    public void onTouchEvent_notStartHandwriting_when_stylusMove_afterTimeOut() {
        callOnInputConnectionOrUpdateViewFocus(mTestView1);
        onEditorFocusedOrConnectionCreated(mTestView1);
        final int x1 = 10;
        final int x1 = 10;
        final int y1 = 10;
        final int y1 = 10;
        final long time1 = 10L;
        final long time1 = 10L;
@@ -553,9 +523,7 @@ public class HandwritingInitiatorTest {


    @Test
    @Test
    public void onTouchEvent_focusView_inputConnectionAlreadyBuilt_stylusMoveOnce_withinHWArea() {
    public void onTouchEvent_focusView_inputConnectionAlreadyBuilt_stylusMoveOnce_withinHWArea() {
        if (!mInitiateWithoutConnection) {
        onEditorFocusedOrConnectionCreated(mTestView1);
            mHandwritingInitiator.onInputConnectionCreated(mTestView1);
        }
        final int x1 = (sHwArea1.left + sHwArea1.right) / 2;
        final int x1 = (sHwArea1.left + sHwArea1.right) / 2;
        final int y1 = (sHwArea1.top + sHwArea1.bottom) / 2;
        final int y1 = (sHwArea1.top + sHwArea1.bottom) / 2;
        MotionEvent stylusEvent1 = createStylusEvent(ACTION_DOWN, x1, y1, 0);
        MotionEvent stylusEvent1 = createStylusEvent(ACTION_DOWN, x1, y1, 0);
@@ -608,14 +576,14 @@ public class HandwritingInitiatorTest {


        verify(mTestView2, times(1)).requestFocus();
        verify(mTestView2, times(1)).requestFocus();


        callOnInputConnectionOrUpdateViewFocus(mTestView2);
        onEditorFocusedOrConnectionCreated(mTestView2);
        verify(mHandwritingInitiator, times(1)).startHandwriting(mTestView2);
        verify(mHandwritingInitiator, times(1)).startHandwriting(mTestView2);
    }
    }


    @Test
    @Test
    public void onTouchEvent_handwritingAreaOverlapped_focusedViewHasPriority() {
    public void onTouchEvent_handwritingAreaOverlapped_focusedViewHasPriority() {
        // Simulate the case where mTestView1 is focused.
        // Simulate the case where mTestView1 is focused.
        callOnInputConnectionOrUpdateViewFocus(mTestView1);
        onEditorFocusedOrConnectionCreated(mTestView1);
        // The ACTION_DOWN location is within the handwriting bounds of both mTestView1 and
        // The ACTION_DOWN location is within the handwriting bounds of both mTestView1 and
        // mTestView2. Although it's closer to mTestView2's handwriting bounds, handwriting is
        // mTestView2. Although it's closer to mTestView2's handwriting bounds, handwriting is
        // initiated for mTestView1 because it's focused.
        // initiated for mTestView1 because it's focused.
@@ -653,7 +621,7 @@ public class HandwritingInitiatorTest {
    @Test
    @Test
    public void onResolvePointerIcon_afterHandwriting_hidePointerIconForConnectedView() {
    public void onResolvePointerIcon_afterHandwriting_hidePointerIconForConnectedView() {
        // simulate the case where sTestView1 is focused.
        // simulate the case where sTestView1 is focused.
        mHandwritingInitiator.onInputConnectionCreated(mTestView1);
        onEditorFocusedOrConnectionCreated(mTestView1);
        injectStylusEvent(mHandwritingInitiator, sHwArea1.centerX(), sHwArea1.centerY(),
        injectStylusEvent(mHandwritingInitiator, sHwArea1.centerX(), sHwArea1.centerY(),
                /* exceedsHWSlop */ true);
                /* exceedsHWSlop */ true);
        // Verify that handwriting started for sTestView1.
        // Verify that handwriting started for sTestView1.
@@ -679,15 +647,14 @@ public class HandwritingInitiatorTest {
    public void onResolvePointerIcon_afterHandwriting_hidePointerIconForDelegatorView() {
    public void onResolvePointerIcon_afterHandwriting_hidePointerIconForDelegatorView() {
        // Set mTextView2 to be the delegate of mTestView1.
        // Set mTextView2 to be the delegate of mTestView1.
        mTestView2.setIsHandwritingDelegate(true);
        mTestView2.setIsHandwritingDelegate(true);

        if (mInitiateWithoutConnection) {
        mTestView1.setHandwritingDelegatorCallback(
        mTestView1.setHandwritingDelegatorCallback(
                    () -> mHandwritingInitiator.updateFocusedView(
                () -> {
                            mTestView2, /*fromTouchEvent*/ false));
                    if (mInitiateWithoutConnection) {
        } else {
                        mHandwritingInitiator.updateFocusedView(mTestView2);
            mTestView1.setHandwritingDelegatorCallback(
                    () -> mHandwritingInitiator.onInputConnectionCreated(mTestView2));
                    }
                    }
                    mHandwritingInitiator.onInputConnectionCreated(mTestView2);
                });

        injectStylusEvent(mHandwritingInitiator, sHwArea1.centerX(), sHwArea1.centerY(),
        injectStylusEvent(mHandwritingInitiator, sHwArea1.centerX(), sHwArea1.centerY(),
                /* exceedsHWSlop */ true);
                /* exceedsHWSlop */ true);
        // Prerequisite check, verify that handwriting started for delegateView.
        // Prerequisite check, verify that handwriting started for delegateView.
@@ -702,7 +669,7 @@ public class HandwritingInitiatorTest {
    @Test
    @Test
    public void onResolvePointerIcon_showHoverIconAfterTap() {
    public void onResolvePointerIcon_showHoverIconAfterTap() {
        // Simulate the case where sTestView1 is focused.
        // Simulate the case where sTestView1 is focused.
        mHandwritingInitiator.onInputConnectionCreated(mTestView1);
        onEditorFocusedOrConnectionCreated(mTestView1);
        injectStylusEvent(mHandwritingInitiator, sHwArea1.centerX(), sHwArea1.centerY(),
        injectStylusEvent(mHandwritingInitiator, sHwArea1.centerX(), sHwArea1.centerY(),
                /* exceedsHWSlop */ true);
                /* exceedsHWSlop */ true);
        // Verify that handwriting started for sTestView1.
        // Verify that handwriting started for sTestView1.
@@ -724,7 +691,7 @@ public class HandwritingInitiatorTest {
    @Test
    @Test
    public void onResolvePointerIcon_showHoverIconAfterFocusChange() {
    public void onResolvePointerIcon_showHoverIconAfterFocusChange() {
        // Simulate the case where sTestView1 is focused.
        // Simulate the case where sTestView1 is focused.
        mHandwritingInitiator.onInputConnectionCreated(mTestView1);
        onEditorFocusedOrConnectionCreated(mTestView1);
        injectStylusEvent(mHandwritingInitiator, sHwArea1.centerX(), sHwArea1.centerY(),
        injectStylusEvent(mHandwritingInitiator, sHwArea1.centerX(), sHwArea1.centerY(),
                /* exceedsHWSlop */ true);
                /* exceedsHWSlop */ true);
        // Verify that handwriting started for sTestView1.
        // Verify that handwriting started for sTestView1.
@@ -735,14 +702,8 @@ public class HandwritingInitiatorTest {
        // After handwriting is initiated for the connected view, hide the hover icon.
        // After handwriting is initiated for the connected view, hide the hover icon.
        assertThat(icon1).isNull();
        assertThat(icon1).isNull();


        // Simulate that focus is switched to mTestView2 first and then switched back.
        onEditorFocusedOrConnectionCreated(mTestView2);
        if (mInitiateWithoutConnection) {
        onEditorFocusedOrConnectionCreated(mTestView1);
            mHandwritingInitiator.updateFocusedView(mTestView2, /*fromTouchEvent*/ true);
            mHandwritingInitiator.updateFocusedView(mTestView1, /*fromTouchEvent*/ true);
        } else {
            mHandwritingInitiator.onInputConnectionCreated(mTestView2);
            mHandwritingInitiator.onInputConnectionCreated(mTestView1);
        }


        PointerIcon icon2 = mHandwritingInitiator.onResolvePointerIcon(mContext, hoverEvent1);
        PointerIcon icon2 = mHandwritingInitiator.onResolvePointerIcon(mContext, hoverEvent1);
        // After the change of focus, hover icon shows again.
        // After the change of focus, hover icon shows again.
@@ -754,11 +715,11 @@ public class HandwritingInitiatorTest {
        if (mInitiateWithoutConnection) {
        if (mInitiateWithoutConnection) {
            mTestView1.setAutoHandwritingEnabled(false);
            mTestView1.setAutoHandwritingEnabled(false);
            mTestView1.setHandwritingDelegatorCallback(null);
            mTestView1.setHandwritingDelegatorCallback(null);
            mHandwritingInitiator.updateFocusedView(mTestView1, /*fromTouchEvent*/ true);
            onEditorFocusedOrConnectionCreated(mTestView1);
        } else {
        } else {
            View mockView = createView(sHwArea1, false /* autoHandwritingEnabled */,
            View mockView = createView(sHwArea1, false /* autoHandwritingEnabled */,
                    true /* isStylusHandwritingAvailable */);
                    true /* isStylusHandwritingAvailable */);
            mHandwritingInitiator.onInputConnectionCreated(mockView);
            onEditorFocusedOrConnectionCreated(mockView);
        }
        }
        final int x1 = (sHwArea1.left + sHwArea1.right) / 2;
        final int x1 = (sHwArea1.left + sHwArea1.right) / 2;
        final int y1 = (sHwArea1.top + sHwArea1.bottom) / 2;
        final int y1 = (sHwArea1.top + sHwArea1.bottom) / 2;
@@ -974,4 +935,12 @@ public class HandwritingInitiatorTest {
                1 /* yPrecision */, 0 /* deviceId */, 0 /* edgeFlags */,
                1 /* yPrecision */, 0 /* deviceId */, 0 /* edgeFlags */,
                InputDevice.SOURCE_STYLUS, 0 /* flags */);
                InputDevice.SOURCE_STYLUS, 0 /* flags */);
    }
    }

    private void onEditorFocusedOrConnectionCreated(View testView) {
        if (Flags.initiationWithoutInputConnection()) {
            mHandwritingInitiator.onEditorFocused(testView);
        } else {
            mHandwritingInitiator.onInputConnectionCreated(testView);
        }
    }
}
}