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

Commit d37ca1e6 authored by Ryan Lin's avatar Ryan Lin Committed by Android (Google) Code Review
Browse files

Merge "Fix touchexploration multi-finger gesture conflict" into sc-dev

parents a3b84a9a 0c7aeef0
Loading
Loading
Loading
Loading
+5 −3
Original line number Original line Diff line number Diff line
@@ -98,8 +98,7 @@ public final class GesturesObserver implements GestureMatcher.StateChangeListene
        }
        }
        mProcessMotionEvent = true;
        mProcessMotionEvent = true;
        for (int i = 0; i < mGestureMatchers.size(); i++) {
        for (int i = 0; i < mGestureMatchers.size(); i++) {
            final GestureMatcher matcher =
            final GestureMatcher matcher = mGestureMatchers.get(i);
                    mGestureMatchers.get(i);
            matcher.onMotionEvent(event, rawEvent, policyFlags);
            matcher.onMotionEvent(event, rawEvent, policyFlags);
            if (matcher.getState() == GestureMatcher.STATE_GESTURE_COMPLETED) {
            if (matcher.getState() == GestureMatcher.STATE_GESTURE_COMPLETED) {
                clear();
                clear();
@@ -128,7 +127,10 @@ public final class GesturesObserver implements GestureMatcher.StateChangeListene
            MotionEvent rawEvent, int policyFlags) {
            MotionEvent rawEvent, int policyFlags) {
        if (state == GestureMatcher.STATE_GESTURE_COMPLETED) {
        if (state == GestureMatcher.STATE_GESTURE_COMPLETED) {
            mListener.onGestureCompleted(gestureId, event, rawEvent, policyFlags);
            mListener.onGestureCompleted(gestureId, event, rawEvent, policyFlags);
            //Clear the states in onMotionEvent().
            // Ideally we clear the states in onMotionEvent(), this case is for hold gestures.
            // If we clear before processing up event , then MultiTap matcher cancels the gesture
            // due to incorrect state. It ends up listener#onGestureCancelled is called even
            // the gesture is detected.
            if (!mProcessMotionEvent) {
            if (!mProcessMotionEvent) {
                clear();
                clear();
            }
            }
+10 −4
Original line number Original line Diff line number Diff line
@@ -33,7 +33,7 @@ import java.lang.annotation.RetentionPolicy;
class MagnificationGestureMatcher {
class MagnificationGestureMatcher {


    private static final int GESTURE_BASE = 100;
    private static final int GESTURE_BASE = 100;
    public static final int GESTURE_TWO_FINGER_DOWN = GESTURE_BASE + 1;
    public static final int GESTURE_TWO_FINGERS_DOWN_OR_SWIPE = GESTURE_BASE + 1;
    public static final int GESTURE_SWIPE = GESTURE_BASE + 2;
    public static final int GESTURE_SWIPE = GESTURE_BASE + 2;
    public static final int GESTURE_SINGLE_TAP = GESTURE_BASE + 3;
    public static final int GESTURE_SINGLE_TAP = GESTURE_BASE + 3;
    public static final int GESTURE_SINGLE_TAP_AND_HOLD = GESTURE_BASE + 4;
    public static final int GESTURE_SINGLE_TAP_AND_HOLD = GESTURE_BASE + 4;
@@ -41,7 +41,7 @@ class MagnificationGestureMatcher {
    public static final int GESTURE_TRIPLE_TAP_AND_HOLD = GESTURE_BASE + 6;
    public static final int GESTURE_TRIPLE_TAP_AND_HOLD = GESTURE_BASE + 6;


    @IntDef(prefix = {"GESTURE_MAGNIFICATION_"}, value = {
    @IntDef(prefix = {"GESTURE_MAGNIFICATION_"}, value = {
            GESTURE_TWO_FINGER_DOWN,
            GESTURE_TWO_FINGERS_DOWN_OR_SWIPE,
            GESTURE_SWIPE
            GESTURE_SWIPE
    })
    })
    @Retention(RetentionPolicy.SOURCE)
    @Retention(RetentionPolicy.SOURCE)
@@ -57,8 +57,8 @@ class MagnificationGestureMatcher {
        switch (gestureId) {
        switch (gestureId) {
            case GESTURE_SWIPE:
            case GESTURE_SWIPE:
                return "GESTURE_SWIPE";
                return "GESTURE_SWIPE";
            case GESTURE_TWO_FINGER_DOWN:
            case GESTURE_TWO_FINGERS_DOWN_OR_SWIPE:
                return "GESTURE_TWO_FINGER_DOWN";
                return "GESTURE_TWO_FINGERS_DOWN_OR_SWIPE";
            case GESTURE_SINGLE_TAP:
            case GESTURE_SINGLE_TAP:
                return "GESTURE_SINGLE_TAP";
                return "GESTURE_SINGLE_TAP";
            case GESTURE_SINGLE_TAP_AND_HOLD:
            case GESTURE_SINGLE_TAP_AND_HOLD:
@@ -71,6 +71,12 @@ class MagnificationGestureMatcher {
        return "none";
        return "none";
    }
    }


    /**
     * @param context
     * @return the duration in milliseconds between the first tap's down event and
     * the second tap's down event to be considered that the user is going to performing
     *  panning/scaling gesture.
     */
    static int getMagnificationMultiTapTimeout(Context context) {
    static int getMagnificationMultiTapTimeout(Context context) {
        return ViewConfiguration.getDoubleTapTimeout() + context.getResources().getInteger(
        return ViewConfiguration.getDoubleTapTimeout() + context.getResources().getInteger(
                R.integer.config_screen_magnification_multi_tap_adjustment);
                R.integer.config_screen_magnification_multi_tap_adjustment);
+1 −1
Original line number Original line Diff line number Diff line
@@ -65,7 +65,7 @@ class MagnificationGesturesObserver implements GesturesObserver.Listener {
         *                  the last event before timeout.
         *                  the last event before timeout.
         *
         *
         * @see MagnificationGestureMatcher#GESTURE_SWIPE
         * @see MagnificationGestureMatcher#GESTURE_SWIPE
         * @see MagnificationGestureMatcher#GESTURE_TWO_FINGER_DOWN
         * @see MagnificationGestureMatcher#GESTURE_TWO_FINGERS_DOWN_OR_SWIPE
         */
         */
        void onGestureCompleted(@GestureId int gestureId, long lastDownEventTime,
        void onGestureCompleted(@GestureId int gestureId, long lastDownEventTime,
                List<MotionEventInfo> delayedEventQueue, MotionEvent event);
                List<MotionEventInfo> delayedEventQueue, MotionEvent event);
+6 −1
Original line number Original line Diff line number Diff line
@@ -48,6 +48,11 @@ class SimpleSwipe extends GestureMatcher {
        cancelAfter(mDetectionDurationMillis, event, rawEvent, policyFlags);
        cancelAfter(mDetectionDurationMillis, event, rawEvent, policyFlags);
    }
    }


    @Override
    protected void onPointerDown(MotionEvent event, MotionEvent rawEvent, int policyFlags) {
        cancelGesture(event, rawEvent, policyFlags);
    }

    @Override
    @Override
    protected void onMove(MotionEvent event, MotionEvent rawEvent, int policyFlags) {
    protected void onMove(MotionEvent event, MotionEvent rawEvent, int policyFlags) {
        if (gestureMatched(event, rawEvent, policyFlags)) {
        if (gestureMatched(event, rawEvent, policyFlags)) {
@@ -65,7 +70,7 @@ class SimpleSwipe extends GestureMatcher {
    }
    }


    private boolean gestureMatched(MotionEvent event, MotionEvent rawEvent, int policyFlags) {
    private boolean gestureMatched(MotionEvent event, MotionEvent rawEvent, int policyFlags) {
        return mLastDown != null && (distance(mLastDown, event) >= mSwipeMinDistance);
        return mLastDown != null && (distance(mLastDown, event) > mSwipeMinDistance);
    }
    }


    @Override
    @Override
+123 −0
Original line number Original line Diff line number Diff line
/*
/*
 * Copyright (C) 2020 The Android Open Source Project
 * Copyright (C) 2021 The Android Open Source Project
 *
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * you may not use this file except in compliance with the License.
@@ -16,42 +16,76 @@


package com.android.server.accessibility.magnification;
package com.android.server.accessibility.magnification;


import android.annotation.NonNull;
import android.content.Context;
import android.content.Context;
import android.os.Handler;
import android.os.Handler;
import android.util.MathUtils;
import android.view.MotionEvent;
import android.view.MotionEvent;
import android.view.ViewConfiguration;


import com.android.server.accessibility.gestures.GestureMatcher;
import com.android.server.accessibility.gestures.GestureMatcher;


/**
/**
 *
 * This class is responsible for detecting that the user is using two fingers to perform
 * This class is responsible for matching two fingers down gestures. The gesture matching
 * swiping gestures or just stay pressed on the screen. The gesture matching result is determined
 * result is determined in a duration.
 * in a duration.
 */
 */
final class TwoFingersDown extends GestureMatcher {
final class TwoFingersDownOrSwipe extends GestureMatcher {


    private MotionEvent mLastDown;
    private final int mDoubleTapTimeout;
    private final int mDetectionDurationMillis;
    private final int mDetectionDurationMillis;
    private final int mSwipeMinDistance;
    private MotionEvent mFirstPointerDown;
    private MotionEvent mSecondPointerDown;


    TwoFingersDown(Context context) {
    TwoFingersDownOrSwipe(Context context) {
        super(MagnificationGestureMatcher.GESTURE_TWO_FINGER_DOWN,
        super(MagnificationGestureMatcher.GESTURE_TWO_FINGERS_DOWN_OR_SWIPE,
                new Handler(context.getMainLooper()), null);
                new Handler(context.getMainLooper()), null);
        mDetectionDurationMillis = MagnificationGestureMatcher.getMagnificationMultiTapTimeout(
        mDetectionDurationMillis = MagnificationGestureMatcher.getMagnificationMultiTapTimeout(
                context);
                context);
        mDoubleTapTimeout = ViewConfiguration.getDoubleTapTimeout();
        mSwipeMinDistance = ViewConfiguration.get(context).getScaledTouchSlop();

    }
    }


    @Override
    @Override
    protected void onDown(MotionEvent event, MotionEvent rawEvent, int policyFlags) {
    protected void onDown(MotionEvent event, MotionEvent rawEvent, int policyFlags) {
        mLastDown = MotionEvent.obtain(event);
        mFirstPointerDown = MotionEvent.obtain(event);
        cancelAfter(mDetectionDurationMillis, event, rawEvent, policyFlags);
        cancelAfter(mDetectionDurationMillis, event, rawEvent, policyFlags);
    }
    }


    @Override
    @Override
    protected void onPointerDown(MotionEvent event, MotionEvent rawEvent, int policyFlags) {
    protected void onPointerDown(MotionEvent event, MotionEvent rawEvent, int policyFlags) {
        if (mLastDown == null) {
        if (mFirstPointerDown == null) {
            cancelGesture(event, rawEvent, policyFlags);
            cancelGesture(event, rawEvent, policyFlags);
        }
        }
        if (event.getPointerCount() == 2) {
            mSecondPointerDown = MotionEvent.obtain(event);
            completeAfter(mDoubleTapTimeout, event, rawEvent, policyFlags);
        } else {
            cancelGesture(event, rawEvent, policyFlags);
        }
    }

    @Override
    protected void onMove(MotionEvent event, MotionEvent rawEvent, int policyFlags) {
        if (mFirstPointerDown == null || mSecondPointerDown == null) {
            return;
        }
        if (distance(mFirstPointerDown, /* move */ event) > mSwipeMinDistance) {
            completeGesture(event, rawEvent, policyFlags);
            return;
        }
        if (distance(mSecondPointerDown, /* move */ event) > mSwipeMinDistance) {
            // The second pointer is swiping.
            completeGesture(event, rawEvent, policyFlags);
            completeGesture(event, rawEvent, policyFlags);
        }
        }
    }

    @Override
    protected void onPointerUp(MotionEvent event, MotionEvent rawEvent, int policyFlags) {
        cancelGesture(event, rawEvent, policyFlags);
    }


    @Override
    @Override
    protected void onUp(MotionEvent event, MotionEvent rawEvent, int policyFlags) {
    protected void onUp(MotionEvent event, MotionEvent rawEvent, int policyFlags) {
@@ -60,9 +94,13 @@ final class TwoFingersDown extends GestureMatcher {


    @Override
    @Override
    public void clear() {
    public void clear() {
        if (mLastDown != null) {
        if (mFirstPointerDown != null) {
            mLastDown.recycle();
            mFirstPointerDown.recycle();
            mLastDown = null;
            mFirstPointerDown = null;
        }
        if (mSecondPointerDown != null) {
            mSecondPointerDown.recycle();
            mSecondPointerDown = null;
        }
        }
        super.clear();
        super.clear();
    }
    }
@@ -71,4 +109,15 @@ final class TwoFingersDown extends GestureMatcher {
    protected String getGestureName() {
    protected String getGestureName() {
        return this.getClass().getSimpleName();
        return this.getClass().getSimpleName();
    }
    }

    private static double distance(@NonNull MotionEvent downEvent, @NonNull MotionEvent moveEvent) {
        final int downActionIndex = downEvent.getActionIndex();
        final int downPointerId = downEvent.getPointerId(downActionIndex);
        final int moveActionIndex = moveEvent.findPointerIndex(downPointerId);
        if (moveActionIndex < 0) {
            return -1;
        }
        return MathUtils.dist(downEvent.getX(downActionIndex), downEvent.getY(downActionIndex),
                moveEvent.getX(moveActionIndex), moveEvent.getY(moveActionIndex));
    }
}
}
Loading