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

Commit f104ba94 authored by Prabir Pradhan's avatar Prabir Pradhan Committed by Android (Google) Code Review
Browse files

Merge "[scribe] show hover icon on handwriting area"

parents c0ae23e7 7db1b9dc
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -19291,6 +19291,7 @@ package android.hardware.input {
    method @Nullable public android.view.InputDevice getInputDevice(int);
    method public int[] getInputDeviceIds();
    method @FloatRange(from=0, to=1) public float getMaximumObscuringOpacityForTouch();
    method public boolean isStylusPointerIconEnabled();
    method public void registerInputDeviceListener(android.hardware.input.InputManager.InputDeviceListener, android.os.Handler);
    method public void unregisterInputDeviceListener(android.hardware.input.InputManager.InputDeviceListener);
    method @Nullable public android.view.VerifiedInputEvent verifyInputEvent(@NonNull android.view.InputEvent);
@@ -50812,6 +50813,7 @@ package android.view {
    field public static final int TYPE_GRAB = 1020; // 0x3fc
    field public static final int TYPE_GRABBING = 1021; // 0x3fd
    field public static final int TYPE_HAND = 1002; // 0x3ea
    field public static final int TYPE_HANDWRITING = 1022; // 0x3fe
    field public static final int TYPE_HELP = 1003; // 0x3eb
    field public static final int TYPE_HORIZONTAL_DOUBLE_ARROW = 1014; // 0x3f6
    field public static final int TYPE_NO_DROP = 1012; // 0x3f4
+22 −1
Original line number Diff line number Diff line
@@ -102,6 +102,8 @@ public final class InputManager {
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
    private final IInputManager mIm;

    private final boolean mIsStylusPointerIconEnabled;

    // Guarded by mInputDevicesLock
    private final Object mInputDevicesLock = new Object();
    private SparseArray<InputDevice> mInputDevices;
@@ -324,6 +326,15 @@ public final class InputManager {
        } catch (RemoteException ex) {
            Log.w(TAG, "Could not get VelocityTracker strategy: " + ex);
        }

        // TODO(b/266013036): Pass a Context into InputManager constructor.
        final Context context = ActivityThread.currentApplication();
        if (context != null) {
            mIsStylusPointerIconEnabled = context.getResources()
                    .getBoolean(com.android.internal.R.bool.config_enableStylusPointerIcon);
        } else {
            mIsStylusPointerIconEnabled = false;
        }
    }

    /**
@@ -1382,7 +1393,7 @@ public final class InputManager {
     * Changes the mouse pointer's icon shape into the specified id.
     *
     * @param iconId The id of the pointer graphic, as a value between
     * {@link PointerIcon.TYPE_ARROW} and {@link PointerIcon.TYPE_GRABBING}.
     * {@link PointerIcon.TYPE_ARROW} and {@link PointerIcon.TYPE_HANDWRITING}.
     *
     * @hide
     */
@@ -1404,6 +1415,16 @@ public final class InputManager {
        }
    }

    /**
     * Check if showing a {@link android.view.PointerIcon} for styluses is enabled.
     *
     * @return true if a pointer icon will be shown over the location of a
     * stylus pointer, false if there is no pointer icon shown for styluses.
     */
    public boolean isStylusPointerIconEnabled() {
        return mIsStylusPointerIconEnabled;
    }

    /**
     * Request or release pointer capture.
     * <p>
+53 −1
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package android.view;
import android.annotation.IdRes;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.Context;
import android.graphics.Rect;
import android.view.inputmethod.InputMethodManager;

@@ -77,6 +78,15 @@ public class HandwritingInitiator {
    private int mConnectionCount = 0;
    private final InputMethodManager mImm;

    /**
     * The handwrite-able View that is currently the target of a hovering stylus pointer. This is
     * used to help determine whether the handwriting PointerIcon should be shown in
     * {@link #onResolvePointerIcon(Context, MotionEvent)} so that we can reduce the number of calls
     * to {@link #findBestCandidateView(float, float)}.
     */
    @Nullable
    private View mCachedHoverTarget = null;

    @VisibleForTesting
    public HandwritingInitiator(@NonNull ViewConfiguration viewConfiguration,
            @NonNull InputMethodManager inputMethodManager) {
@@ -307,6 +317,48 @@ public class HandwritingInitiator {
        return view.isStylusHandwritingAvailable();
    }

    /**
     * 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
     * handwrite-able area.
     */
    public PointerIcon onResolvePointerIcon(Context context, MotionEvent event) {
        if (shouldShowHandwritingPointerIcon(event)) {
            return PointerIcon.getSystemIcon(context, PointerIcon.TYPE_HANDWRITING);
        }
        return null;
    }

    private boolean shouldShowHandwritingPointerIcon(MotionEvent event) {
        if (!event.isStylusPointer() || !event.isHoverEvent()) {
            return false;
        }

        if (event.getActionMasked() == MotionEvent.ACTION_HOVER_ENTER
                || event.getActionMasked() == MotionEvent.ACTION_HOVER_MOVE) {
            final float hoverX = event.getX(event.getActionIndex());
            final float hoverY = event.getY(event.getActionIndex());

            if (mCachedHoverTarget != null) {
                final Rect handwritingArea = getViewHandwritingArea(mCachedHoverTarget);
                if (isInHandwritingArea(handwritingArea, hoverX, hoverY, mCachedHoverTarget)
                        && shouldTriggerStylusHandwritingForView(mCachedHoverTarget)) {
                    return true;
                }
            }

            final View candidateView = findBestCandidateView(hoverX, hoverY);

            if (candidateView != null) {
                mCachedHoverTarget = candidateView;
                return true;
            }
        }

        mCachedHoverTarget = null;
        return false;
    }

    /**
     * Given the location of the stylus event, return the best candidate view to initialize
     * handwriting mode.
@@ -437,7 +489,7 @@ public class HandwritingInitiator {
     * Return true if the (x, y) is inside by the given {@link Rect} with the View's
     * handwriting bounds with offsets applied.
     */
    private boolean isInHandwritingArea(@Nullable Rect handwritingArea,
    private static boolean isInHandwritingArea(@Nullable Rect handwritingArea,
            float x, float y, View view) {
        if (handwritingArea == null) return false;

+23 −0
Original line number Diff line number Diff line
@@ -2321,6 +2321,29 @@ public final class MotionEvent extends InputEvent implements Parcelable {
        return nativeIsTouchEvent(mNativePtr);
    }

    /**
     * Returns {@code true} if this motion event is from a stylus pointer.
     * @hide
     */
    public boolean isStylusPointer() {
        final int actionIndex = getActionIndex();
        return isFromSource(InputDevice.SOURCE_STYLUS)
                && (getToolType(actionIndex) == TOOL_TYPE_STYLUS
                || getToolType(actionIndex) == TOOL_TYPE_ERASER);
    }

    /**
     * Returns {@code true} if this motion event is a hover event, identified by it having an action
     * of either {@link #ACTION_HOVER_ENTER}, {@link #ACTION_HOVER_MOVE} or
     * {@link #ACTION_HOVER_EXIT}.
     * @hide
     */
    public boolean isHoverEvent() {
        return getActionMasked() == ACTION_HOVER_ENTER
                || getActionMasked() == ACTION_HOVER_EXIT
                || getActionMasked() == ACTION_HOVER_MOVE;
    }

    /**
     * Gets the motion event flags.
     *
+5 −0
Original line number Diff line number Diff line
@@ -138,6 +138,9 @@ public final class PointerIcon implements Parcelable {
    /** Type constant: grabbing. */
    public static final int TYPE_GRABBING = 1021;

    /** Type constant: handwriting. */
    public static final int TYPE_HANDWRITING = 1022;

    // OEM private types should be defined starting at this range to avoid
    // conflicts with any system types that may be defined in the future.
    private static final int TYPE_OEM_FIRST = 10000;
@@ -601,6 +604,8 @@ public final class PointerIcon implements Parcelable {
                return com.android.internal.R.styleable.Pointer_pointerIconGrab;
            case TYPE_GRABBING:
                return com.android.internal.R.styleable.Pointer_pointerIconGrabbing;
            case TYPE_HANDWRITING:
                return com.android.internal.R.styleable.Pointer_pointerIconHandwriting;
            default:
                return 0;
        }
Loading