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

Commit 432a62b8 authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Show toast when handwriting in unsupported view" into main

parents 396b8718 bb225ec3
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -126,3 +126,10 @@ flag {
  description: "When handwriting is initiated in an unfocused TextView, cursor is placed at the end of the closest paragraph."
  bug: "323376217"
}

flag {
  name: "handwriting_unsupported_message"
  namespace: "text"
  description: "Feature flag for showing error message when user tries stylus handwriting on a text field which doesn't support it"
  bug: "297962571"
}
+35 −6
Original line number Diff line number Diff line
@@ -34,7 +34,9 @@ import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.Editor;
import android.widget.TextView;
import android.widget.Toast;

import com.android.internal.R;
import com.android.internal.annotations.VisibleForTesting;

import java.lang.ref.WeakReference;
@@ -223,7 +225,24 @@ public class HandwritingInitiator {
                    View candidateView = findBestCandidateView(mState.mStylusDownX,
                            mState.mStylusDownY, /* isHover */ false);
                    if (candidateView != null && candidateView.isEnabled()) {
                        if (candidateView == getConnectedOrFocusedView()) {
                        if (shouldShowHandwritingUnavailableMessageForView(candidateView)) {
                            int messagesResId = (candidateView instanceof TextView tv
                                    && tv.isAnyPasswordInputType())
                                    ? R.string.error_handwriting_unsupported_password
                                    : R.string.error_handwriting_unsupported;
                            Toast.makeText(candidateView.getContext(), messagesResId,
                                    Toast.LENGTH_SHORT).show();
                            if (!candidateView.hasFocus()) {
                                requestFocusWithoutReveal(candidateView);
                            }
                            mImm.showSoftInput(candidateView, 0);
                            mState.mHandled = true;
                            mState.mShouldInitHandwriting = false;
                            motionEvent.setAction((motionEvent.getAction()
                                    & MotionEvent.ACTION_POINTER_INDEX_MASK)
                                    | MotionEvent.ACTION_CANCEL);
                            candidateView.getRootView().dispatchTouchEvent(motionEvent);
                        } else if (candidateView == getConnectedOrFocusedView()) {
                            if (!mInitiateWithoutConnection && !candidateView.hasFocus()) {
                                requestFocusWithoutReveal(candidateView);
                            }
@@ -484,6 +503,15 @@ public class HandwritingInitiator {
        return view.isStylusHandwritingAvailable();
    }

    private static boolean shouldShowHandwritingUnavailableMessageForView(@NonNull View view) {
        return (view instanceof TextView) && !shouldTriggerStylusHandwritingForView(view);
    }

    private static boolean shouldTriggerHandwritingOrShowUnavailableMessageForView(
            @NonNull View view) {
        return (view instanceof TextView) || shouldTriggerStylusHandwritingForView(view);
    }

    /**
     * Returns the pointer icon for the motion event, or null if it doesn't specify the icon.
     * This gives HandwritingInitiator a chance to show the stylus handwriting icon over a
@@ -491,7 +519,7 @@ public class HandwritingInitiator {
     */
    public PointerIcon onResolvePointerIcon(Context context, MotionEvent event) {
        final View hoverView = findHoverView(event);
        if (hoverView == null) {
        if (hoverView == null || !shouldTriggerStylusHandwritingForView(hoverView)) {
            return null;
        }

@@ -594,7 +622,7 @@ public class HandwritingInitiator {

    /**
     * Given the location of the stylus event, return the best candidate view to initialize
     * handwriting mode.
     * handwriting mode or show the handwriting unavailable error message.
     *
     * @param x the x coordinates of the stylus event, in the coordinates of the window.
     * @param y the y coordinates of the stylus event, in the coordinates of the window.
@@ -610,7 +638,8 @@ public class HandwritingInitiator {
            Rect handwritingArea = mTempRect;
            if (getViewHandwritingArea(connectedOrFocusedView, handwritingArea)
                    && isInHandwritingArea(handwritingArea, x, y, connectedOrFocusedView, isHover)
                    && shouldTriggerStylusHandwritingForView(connectedOrFocusedView)) {
                    && shouldTriggerHandwritingOrShowUnavailableMessageForView(
                            connectedOrFocusedView)) {
                if (!isHover && mState != null) {
                    mState.mStylusDownWithinEditorBounds =
                            contains(handwritingArea, x, y, 0f, 0f, 0f, 0f);
@@ -628,7 +657,7 @@ public class HandwritingInitiator {
            final View view = viewInfo.getView();
            final Rect handwritingArea = viewInfo.getHandwritingArea();
            if (!isInHandwritingArea(handwritingArea, x, y, view, isHover)
                    || !shouldTriggerStylusHandwritingForView(view)) {
                    || !shouldTriggerHandwritingOrShowUnavailableMessageForView(view)) {
                continue;
            }

@@ -856,7 +885,7 @@ public class HandwritingInitiator {
    /** The helper method to check if the given view is still active for handwriting. */
    private static boolean isViewActive(@Nullable View view) {
        return view != null && view.isAttachedToWindow() && view.isAggregatedVisible()
                && view.shouldInitiateHandwriting();
                && view.shouldTrackHandwritingArea();
    }

    private CursorAnchorInfo getCursorAnchorInfoForConnectionless(View view) {
+12 −2
Original line number Diff line number Diff line
@@ -12695,7 +12695,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
        if (getSystemGestureExclusionRects().isEmpty()
                && collectPreferKeepClearRects().isEmpty()
                && collectUnrestrictedPreferKeepClearRects().isEmpty()
                && (info.mHandwritingArea == null || !shouldInitiateHandwriting())) {
                && (info.mHandwritingArea == null || !shouldTrackHandwritingArea())) {
            if (info.mPositionUpdateListener != null) {
                mRenderNode.removePositionUpdateListener(info.mPositionUpdateListener);
                info.mPositionUpdateListener = null;
@@ -13062,7 +13062,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
    void updateHandwritingArea() {
        // If autoHandwritingArea is not enabled, do nothing.
        if (!shouldInitiateHandwriting()) return;
        if (!shouldTrackHandwritingArea()) return;
        final AttachInfo ai = mAttachInfo;
        if (ai != null) {
            ai.mViewRootImpl.getHandwritingInitiator().updateHandwritingAreasForView(this);
@@ -13079,6 +13079,16 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
        return isAutoHandwritingEnabled() || getHandwritingDelegatorCallback() != null;
    }
    /**
     * Returns whether the handwriting initiator should track the handwriting area for this view,
     * either to initiate handwriting mode, or to prepare handwriting delegation, or to show the
     * handwriting unsupported message.
     * @hide
     */
    public boolean shouldTrackHandwritingArea() {
        return shouldInitiateHandwriting();
    }
    /**
     * Sets a callback which should be called when a stylus {@link MotionEvent} occurs within this
     * view's bounds. The callback will be called from the UI thread.
+9 −0
Original line number Diff line number Diff line
@@ -13563,6 +13563,15 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
        return super.isAutoHandwritingEnabled() && !isAnyPasswordInputType();
    }
    /** @hide */
    @Override
    public boolean shouldTrackHandwritingArea() {
        // The handwriting initiator tracks all editable TextViews regardless of whether handwriting
        // is supported, so that it can show an error message for unsupported editable TextViews.
        return super.shouldTrackHandwritingArea()
                || (Flags.handwritingUnsupportedMessage() && onCheckIsTextEditor());
    }
    /** @hide */
    @Override
    public boolean isStylusHandwritingAvailable() {
+6 −0
Original line number Diff line number Diff line
@@ -3249,6 +3249,12 @@
    <!-- Title for EditText context menu [CHAR LIMIT=20] -->
    <string name="editTextMenuTitle">Text actions</string>

    <!-- Error shown when a user uses a stylus to try handwriting on a text field which doesn't support stylus handwriting. [CHAR LIMIT=TOAST] -->
    <string name="error_handwriting_unsupported">Handwriting is not supported in this field</string>

    <!-- Error shown when a user uses a stylus to try handwriting on a password text field which doesn't support stylus handwriting. [CHAR LIMIT=TOAST] -->
    <string name="error_handwriting_unsupported_password">Handwriting is not supported in password fields</string>

    <!-- Content description of the back button for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
    <string name="input_method_nav_back_button_desc">Back</string>
    <!-- Content description of the switch input method button for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
Loading