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

Commit 259dadde authored by Ameer Armaly's avatar Ameer Armaly
Browse files

Add multi-finger double tap and hold gestures.

This CL includes two, three and four finger double-tap and hold.

Bug: 136131815
Test: atest GestureManifoldTest TouchExplorerTest AccessibilityGestureDetectorTest
Change-Id: I4c0a95a4ac2d13e0a7e2c7920df619063ec1cfc0
parent 9657bcfb
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -2876,6 +2876,7 @@ package android.accessibilityservice {
    method public final void setServiceInfo(android.accessibilityservice.AccessibilityServiceInfo);
    method public boolean takeScreenshot(int, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<android.accessibilityservice.AccessibilityService.ScreenshotResult>);
    field public static final int GESTURE_2_FINGER_DOUBLE_TAP = 20; // 0x14
    field public static final int GESTURE_2_FINGER_DOUBLE_TAP_AND_HOLD = 40; // 0x28
    field public static final int GESTURE_2_FINGER_SINGLE_TAP = 19; // 0x13
    field public static final int GESTURE_2_FINGER_SWIPE_DOWN = 26; // 0x1a
    field public static final int GESTURE_2_FINGER_SWIPE_LEFT = 27; // 0x1b
@@ -2883,6 +2884,7 @@ package android.accessibilityservice {
    field public static final int GESTURE_2_FINGER_SWIPE_UP = 25; // 0x19
    field public static final int GESTURE_2_FINGER_TRIPLE_TAP = 21; // 0x15
    field public static final int GESTURE_3_FINGER_DOUBLE_TAP = 23; // 0x17
    field public static final int GESTURE_3_FINGER_DOUBLE_TAP_AND_HOLD = 41; // 0x29
    field public static final int GESTURE_3_FINGER_SINGLE_TAP = 22; // 0x16
    field public static final int GESTURE_3_FINGER_SWIPE_DOWN = 30; // 0x1e
    field public static final int GESTURE_3_FINGER_SWIPE_LEFT = 31; // 0x1f
@@ -2890,6 +2892,7 @@ package android.accessibilityservice {
    field public static final int GESTURE_3_FINGER_SWIPE_UP = 29; // 0x1d
    field public static final int GESTURE_3_FINGER_TRIPLE_TAP = 24; // 0x18
    field public static final int GESTURE_4_FINGER_DOUBLE_TAP = 38; // 0x26
    field public static final int GESTURE_4_FINGER_DOUBLE_TAP_AND_HOLD = 42; // 0x2a
    field public static final int GESTURE_4_FINGER_SINGLE_TAP = 37; // 0x25
    field public static final int GESTURE_4_FINGER_SWIPE_DOWN = 34; // 0x22
    field public static final int GESTURE_4_FINGER_SWIPE_LEFT = 35; // 0x23
+12 −0
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package android.accessibilityservice;


import static android.accessibilityservice.AccessibilityService.GESTURE_2_FINGER_DOUBLE_TAP;
import static android.accessibilityservice.AccessibilityService.GESTURE_2_FINGER_DOUBLE_TAP_AND_HOLD;
import static android.accessibilityservice.AccessibilityService.GESTURE_2_FINGER_SINGLE_TAP;
import static android.accessibilityservice.AccessibilityService.GESTURE_2_FINGER_SWIPE_DOWN;
import static android.accessibilityservice.AccessibilityService.GESTURE_2_FINGER_SWIPE_LEFT;
@@ -25,6 +26,7 @@ import static android.accessibilityservice.AccessibilityService.GESTURE_2_FINGER
import static android.accessibilityservice.AccessibilityService.GESTURE_2_FINGER_SWIPE_UP;
import static android.accessibilityservice.AccessibilityService.GESTURE_2_FINGER_TRIPLE_TAP;
import static android.accessibilityservice.AccessibilityService.GESTURE_3_FINGER_DOUBLE_TAP;
import static android.accessibilityservice.AccessibilityService.GESTURE_3_FINGER_DOUBLE_TAP_AND_HOLD;
import static android.accessibilityservice.AccessibilityService.GESTURE_3_FINGER_SINGLE_TAP;
import static android.accessibilityservice.AccessibilityService.GESTURE_3_FINGER_SWIPE_DOWN;
import static android.accessibilityservice.AccessibilityService.GESTURE_3_FINGER_SWIPE_LEFT;
@@ -32,6 +34,7 @@ import static android.accessibilityservice.AccessibilityService.GESTURE_3_FINGER
import static android.accessibilityservice.AccessibilityService.GESTURE_3_FINGER_SWIPE_UP;
import static android.accessibilityservice.AccessibilityService.GESTURE_3_FINGER_TRIPLE_TAP;
import static android.accessibilityservice.AccessibilityService.GESTURE_4_FINGER_DOUBLE_TAP;
import static android.accessibilityservice.AccessibilityService.GESTURE_4_FINGER_DOUBLE_TAP_AND_HOLD;
import static android.accessibilityservice.AccessibilityService.GESTURE_4_FINGER_SINGLE_TAP;
import static android.accessibilityservice.AccessibilityService.GESTURE_4_FINGER_SWIPE_DOWN;
import static android.accessibilityservice.AccessibilityService.GESTURE_4_FINGER_SWIPE_LEFT;
@@ -83,9 +86,11 @@ public final class AccessibilityGestureEvent implements Parcelable {
    @IntDef(prefix = { "GESTURE_" }, value = {
            GESTURE_2_FINGER_SINGLE_TAP,
            GESTURE_2_FINGER_DOUBLE_TAP,
            GESTURE_2_FINGER_DOUBLE_TAP_AND_HOLD,
            GESTURE_2_FINGER_TRIPLE_TAP,
            GESTURE_3_FINGER_SINGLE_TAP,
            GESTURE_3_FINGER_DOUBLE_TAP,
            GESTURE_3_FINGER_DOUBLE_TAP_AND_HOLD,
            GESTURE_3_FINGER_TRIPLE_TAP,
            GESTURE_DOUBLE_TAP,
            GESTURE_DOUBLE_TAP_AND_HOLD,
@@ -114,6 +119,7 @@ public final class AccessibilityGestureEvent implements Parcelable {
            GESTURE_3_FINGER_SWIPE_RIGHT,
            GESTURE_3_FINGER_SWIPE_UP,
            GESTURE_4_FINGER_DOUBLE_TAP,
            GESTURE_4_FINGER_DOUBLE_TAP_AND_HOLD,
            GESTURE_4_FINGER_SINGLE_TAP,
            GESTURE_4_FINGER_SWIPE_DOWN,
            GESTURE_4_FINGER_SWIPE_LEFT,
@@ -175,12 +181,18 @@ public final class AccessibilityGestureEvent implements Parcelable {
        switch (eventType) {
            case GESTURE_2_FINGER_SINGLE_TAP: return "GESTURE_2_FINGER_SINGLE_TAP";
            case GESTURE_2_FINGER_DOUBLE_TAP: return "GESTURE_2_FINGER_DOUBLE_TAP";
            case GESTURE_2_FINGER_DOUBLE_TAP_AND_HOLD:
                return "GESTURE_2_FINGER_DOUBLE_TAP_AND_HOLD";
            case GESTURE_2_FINGER_TRIPLE_TAP: return "GESTURE_2_FINGER_TRIPLE_TAP";
            case GESTURE_3_FINGER_SINGLE_TAP: return "GESTURE_3_FINGER_SINGLE_TAP";
            case GESTURE_3_FINGER_DOUBLE_TAP: return "GESTURE_3_FINGER_DOUBLE_TAP";
            case GESTURE_3_FINGER_DOUBLE_TAP_AND_HOLD:
                return "GESTURE_3_FINGER_DOUBLE_TAP_AND_HOLD";
            case GESTURE_3_FINGER_TRIPLE_TAP: return "GESTURE_3_FINGER_TRIPLE_TAP";
            case GESTURE_4_FINGER_SINGLE_TAP: return "GESTURE_4_FINGER_SINGLE_TAP";
            case GESTURE_4_FINGER_DOUBLE_TAP: return "GESTURE_4_FINGER_DOUBLE_TAP";
            case GESTURE_4_FINGER_DOUBLE_TAP_AND_HOLD:
                return "GESTURE_4_FINGER_DOUBLE_TAP_AND_HOLD";
            case GESTURE_4_FINGER_TRIPLE_TAP: return "GESTURE_4_FINGER_TRIPLE_TAP";
            case GESTURE_DOUBLE_TAP: return "GESTURE_DOUBLE_TAP";
            case GESTURE_DOUBLE_TAP_AND_HOLD: return "GESTURE_DOUBLE_TAP_AND_HOLD";
+9 −0
Original line number Diff line number Diff line
@@ -411,6 +411,15 @@ public abstract class AccessibilityService extends Service {
    /** The user has performed a four-finger triple tap gesture on the touch screen. */
    public static final int GESTURE_4_FINGER_TRIPLE_TAP = 39;

    /** The user has performed a two-finger double tap and hold gesture on the touch screen. */
    public static final int GESTURE_2_FINGER_DOUBLE_TAP_AND_HOLD = 40;

    /** The user has performed a three-finger double tap and hold gesture on the touch screen. */
    public static final int GESTURE_3_FINGER_DOUBLE_TAP_AND_HOLD = 41;

    /** The user has performed a two-finger double tap and hold gesture on the touch screen. */
    public static final int GESTURE_4_FINGER_DOUBLE_TAP_AND_HOLD = 42;

    /**
     * The {@link Intent} that must be declared as handled by the service.
     */
+12 −0
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package com.android.server.accessibility.gestures;

import static android.accessibilityservice.AccessibilityService.GESTURE_2_FINGER_DOUBLE_TAP;
import static android.accessibilityservice.AccessibilityService.GESTURE_2_FINGER_DOUBLE_TAP_AND_HOLD;
import static android.accessibilityservice.AccessibilityService.GESTURE_2_FINGER_SINGLE_TAP;
import static android.accessibilityservice.AccessibilityService.GESTURE_2_FINGER_SWIPE_DOWN;
import static android.accessibilityservice.AccessibilityService.GESTURE_2_FINGER_SWIPE_LEFT;
@@ -24,6 +25,7 @@ import static android.accessibilityservice.AccessibilityService.GESTURE_2_FINGER
import static android.accessibilityservice.AccessibilityService.GESTURE_2_FINGER_SWIPE_UP;
import static android.accessibilityservice.AccessibilityService.GESTURE_2_FINGER_TRIPLE_TAP;
import static android.accessibilityservice.AccessibilityService.GESTURE_3_FINGER_DOUBLE_TAP;
import static android.accessibilityservice.AccessibilityService.GESTURE_3_FINGER_DOUBLE_TAP_AND_HOLD;
import static android.accessibilityservice.AccessibilityService.GESTURE_3_FINGER_SINGLE_TAP;
import static android.accessibilityservice.AccessibilityService.GESTURE_3_FINGER_SWIPE_DOWN;
import static android.accessibilityservice.AccessibilityService.GESTURE_3_FINGER_SWIPE_LEFT;
@@ -31,6 +33,7 @@ import static android.accessibilityservice.AccessibilityService.GESTURE_3_FINGER
import static android.accessibilityservice.AccessibilityService.GESTURE_3_FINGER_SWIPE_UP;
import static android.accessibilityservice.AccessibilityService.GESTURE_3_FINGER_TRIPLE_TAP;
import static android.accessibilityservice.AccessibilityService.GESTURE_4_FINGER_DOUBLE_TAP;
import static android.accessibilityservice.AccessibilityService.GESTURE_4_FINGER_DOUBLE_TAP_AND_HOLD;
import static android.accessibilityservice.AccessibilityService.GESTURE_4_FINGER_SINGLE_TAP;
import static android.accessibilityservice.AccessibilityService.GESTURE_4_FINGER_SWIPE_DOWN;
import static android.accessibilityservice.AccessibilityService.GESTURE_4_FINGER_SWIPE_LEFT;
@@ -131,6 +134,9 @@ class GestureManifold implements GestureMatcher.StateChangeListener {
                new MultiFingerMultiTap(mContext, 2, 1, GESTURE_2_FINGER_SINGLE_TAP, this));
        mMultiFingerGestures.add(
                new MultiFingerMultiTap(mContext, 2, 2, GESTURE_2_FINGER_DOUBLE_TAP, this));
        mMultiFingerGestures.add(
                new MultiFingerMultiTapAndHold(
                        mContext, 2, 2, GESTURE_2_FINGER_DOUBLE_TAP_AND_HOLD, this));
        mMultiFingerGestures.add(
                new MultiFingerMultiTap(mContext, 2, 3, GESTURE_2_FINGER_TRIPLE_TAP, this));
        // Three-finger taps.
@@ -138,6 +144,9 @@ class GestureManifold implements GestureMatcher.StateChangeListener {
                new MultiFingerMultiTap(mContext, 3, 1, GESTURE_3_FINGER_SINGLE_TAP, this));
        mMultiFingerGestures.add(
                new MultiFingerMultiTap(mContext, 3, 2, GESTURE_3_FINGER_DOUBLE_TAP, this));
        mMultiFingerGestures.add(
                new MultiFingerMultiTapAndHold(
                        mContext, 3, 2, GESTURE_3_FINGER_DOUBLE_TAP_AND_HOLD, this));
        mMultiFingerGestures.add(
                new MultiFingerMultiTap(mContext, 3, 3, GESTURE_3_FINGER_TRIPLE_TAP, this));
        // Four-finger taps.
@@ -145,6 +154,9 @@ class GestureManifold implements GestureMatcher.StateChangeListener {
                new MultiFingerMultiTap(mContext, 4, 1, GESTURE_4_FINGER_SINGLE_TAP, this));
        mMultiFingerGestures.add(
                new MultiFingerMultiTap(mContext, 4, 2, GESTURE_4_FINGER_DOUBLE_TAP, this));
        mMultiFingerGestures.add(
                new MultiFingerMultiTapAndHold(
                        mContext, 4, 2, GESTURE_4_FINGER_DOUBLE_TAP_AND_HOLD, this));
        mMultiFingerGestures.add(
                new MultiFingerMultiTap(mContext, 4, 3, GESTURE_4_FINGER_TRIPLE_TAP, this));
        // Two-finger swipes.
+14 −12
Original line number Diff line number Diff line
@@ -42,10 +42,10 @@ class MultiFingerMultiTap extends GestureMatcher {
    // The acceptable distance the pointer can move and still count as a tap.
    private int mTouchSlop;
    // A tap counts when target number of fingers are down and up once.
    private int mCompletedTapCount;
    protected int mCompletedTapCount;
    // A flag set to true when target number of fingers have touched down at once before.
    // Used to indicate what next finger action should be. Down when false and lift when true.
    private boolean mIsTargetFingerCountReached = false;
    protected boolean mIsTargetFingerCountReached = false;
    // Store initial down points for slop checking and update when next down if is inside slop.
    private PointF[] mBases;
    // The points in bases that already have slop checked when onDown or onPointerDown.
@@ -56,7 +56,11 @@ class MultiFingerMultiTap extends GestureMatcher {
     * @throws IllegalArgumentException if <code>fingers<code/> is less than 2
     *                                  or <code>taps<code/> is not positive.
     */
    MultiFingerMultiTap(Context context, int fingers, int taps, int gestureId,
    MultiFingerMultiTap(
            Context context,
            int fingers,
            int taps,
            int gestureId,
            GestureMatcher.StateChangeListener listener) {
        super(gestureId, new Handler(context.getMainLooper()), listener);
        Preconditions.checkArgument(fingers >= 2);
@@ -117,8 +121,7 @@ class MultiFingerMultiTap extends GestureMatcher {
        cancelAfterDoubleTapTimeout(event, rawEvent, policyFlags);

        final PointF nearest = findNearestPoint(rawEvent, mTouchSlop, false);
        if ((getState() == STATE_GESTURE_STARTED || getState() == STATE_CLEAR)
                && null != nearest) {
        if ((getState() == STATE_GESTURE_STARTED || getState() == STATE_CLEAR) && null != nearest) {
            // Increase current tap count when the user have all fingers lifted
            // within the tap timeout since the target number of fingers are down.
            if (mIsTargetFingerCountReached) {
@@ -169,8 +172,7 @@ class MultiFingerMultiTap extends GestureMatcher {
        } else {
            nearest = findNearestPoint(rawEvent, mDoubleTapSlop, true);
        }
        if ((getState() == STATE_GESTURE_STARTED || getState() == STATE_CLEAR)
                && nearest != null) {
        if ((getState() == STATE_GESTURE_STARTED || getState() == STATE_CLEAR) && nearest != null) {
            // The user have all fingers down within the tap timeout since first finger down,
            // setting the timeout for fingers to be lifted.
            if (currentFingerCount == mTargetFingerCount) {
@@ -227,11 +229,11 @@ class MultiFingerMultiTap extends GestureMatcher {
    }

    /**
     * Find the nearest location to the given event in the bases.
     * If no one found, it could be not inside {@code slop}, filtered or empty bases.
     * When {@code filterMatched} is true, if the location of given event matches one of the points
     * in {@link #mExcludedPointsForDownSlopChecked} it would be ignored. Otherwise, the location
     * will be added to {@link #mExcludedPointsForDownSlopChecked}.
     * Find the nearest location to the given event in the bases. If no one found, it could be not
     * inside {@code slop}, filtered or empty bases. When {@code filterMatched} is true, if the
     * location of given event matches one of the points in {@link
     * #mExcludedPointsForDownSlopChecked} it would be ignored. Otherwise, the location will be
     * added to {@link #mExcludedPointsForDownSlopChecked}.
     *
     * @param event to find nearest point in bases.
     * @param slop to check to the given location of the event.
Loading