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

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

Merge "Swipe: use event times to check for expiration rather than handlers." into rvc-dev

parents a08db2de b16b4486
Loading
Loading
Loading
Loading
+4 −4
Original line number Diff line number Diff line
@@ -20,9 +20,9 @@ import static android.view.MotionEvent.INVALID_POINTER_ID;

import static com.android.server.accessibility.gestures.GestureUtils.MM_PER_CM;
import static com.android.server.accessibility.gestures.GestureUtils.getActionIndex;
import static com.android.server.accessibility.gestures.Swipe.CANCEL_ON_PAUSE_THRESHOLD_NOT_STARTED_MS;
import static com.android.server.accessibility.gestures.Swipe.CANCEL_ON_PAUSE_THRESHOLD_STARTED_MS;
import static com.android.server.accessibility.gestures.Swipe.GESTURE_CONFIRM_CM;
import static com.android.server.accessibility.gestures.Swipe.MAX_TIME_TO_CONTINUE_SWIPE_MS;
import static com.android.server.accessibility.gestures.Swipe.MAX_TIME_TO_START_SWIPE_MS;
import static com.android.server.accessibility.gestures.TouchExplorer.DEBUG;

import android.content.Context;
@@ -387,10 +387,10 @@ class MultiFingerSwipe extends GestureMatcher {
        cancelPendingTransitions();
        switch (getState()) {
            case STATE_CLEAR:
                cancelAfter(CANCEL_ON_PAUSE_THRESHOLD_NOT_STARTED_MS, event, rawEvent, policyFlags);
                cancelAfter(MAX_TIME_TO_START_SWIPE_MS, event, rawEvent, policyFlags);
                break;
            case STATE_GESTURE_STARTED:
                cancelAfter(CANCEL_ON_PAUSE_THRESHOLD_STARTED_MS, event, rawEvent, policyFlags);
                cancelAfter(MAX_TIME_TO_CONTINUE_SWIPE_MS, event, rawEvent, policyFlags);
                break;
            default:
                break;
+39 −53
Original line number Diff line number Diff line
@@ -49,11 +49,10 @@ class Swipe extends GestureMatcher {
    // Buffer for storing points for gesture detection.
    private final ArrayList<PointF> mStrokeBuffer = new ArrayList<>(100);

    // The minimal delta between moves to add a gesture point.
    private static final int TOUCH_TOLERANCE_PIX = 3;

    // The minimal score for accepting a predicted gesture.
    private static final float MIN_PREDICTION_SCORE = 2.0f;
    // Constants for sampling motion event points.
    // We sample based on a minimum distance between points, primarily to improve accuracy by
    // reducing noisy minor changes in direction.
    private static final float MIN_CM_BETWEEN_SAMPLES = 0.25f;

    // Distance a finger must travel before we decide if it is a gesture or not.
    public static final int GESTURE_CONFIRM_CM = 1;
@@ -67,22 +66,19 @@ class Swipe extends GestureMatcher {
    // all gestures started with the initial movement taking less than 100ms.
    // When touch exploring, the first movement almost always takes longer than
    // 200ms.
    public static final long CANCEL_ON_PAUSE_THRESHOLD_NOT_STARTED_MS = 150;
    public static final long MAX_TIME_TO_START_SWIPE_MS = 150 * GESTURE_CONFIRM_CM;

    // Time threshold used to determine if a gesture should be cancelled.  If
    // the finger takes more than this time to move 1cm, the ongoing gesture is
    // cancelled.
    public static final long CANCEL_ON_PAUSE_THRESHOLD_STARTED_MS = 300;
    // the finger takes more than this time to move  to the next sample point, the ongoing gesture
    // is cancelled.
    public static final long MAX_TIME_TO_CONTINUE_SWIPE_MS = 350 * GESTURE_CONFIRM_CM;

    private int[] mDirections;
    private float mBaseX;
    private float mBaseY;
    private long mBaseTime;
    private float mPreviousGestureX;
    private float mPreviousGestureY;
    // Constants for sampling motion event points.
    // We sample based on a minimum distance between points, primarily to improve accuracy by
    // reducing noisy minor changes in direction.
    private static final float MIN_CM_BETWEEN_SAMPLES = 0.25f;
    private final float mMinPixelsBetweenSamplesX;
    private final float mMinPixelsBetweenSamplesY;
    // The minmimum distance the finger must travel before we evaluate the initial direction of the
@@ -134,16 +130,19 @@ class Swipe extends GestureMatcher {
    protected void clear() {
        mBaseX = Float.NaN;
        mBaseY = Float.NaN;
        mBaseTime = 0;
        mPreviousGestureX = Float.NaN;
        mPreviousGestureY = Float.NaN;
        mStrokeBuffer.clear();
        super.clear();
    }

    @Override
    protected void onDown(MotionEvent event, MotionEvent rawEvent, int policyFlags) {
        cancelAfterPauseThreshold(event, rawEvent, policyFlags);
        if (Float.isNaN(mBaseX) && Float.isNaN(mBaseY)) {
            mBaseX = rawEvent.getX();
            mBaseY = rawEvent.getY();
            mBaseTime = rawEvent.getEventTime();
            mPreviousGestureX = mBaseX;
            mPreviousGestureY = mBaseY;
        }
@@ -154,9 +153,11 @@ class Swipe extends GestureMatcher {
    protected void onMove(MotionEvent event, MotionEvent rawEvent, int policyFlags) {
        final float x = rawEvent.getX();
        final float y = rawEvent.getY();
        final long time = rawEvent.getEventTime();
        final float dX = Math.abs(x - mPreviousGestureX);
        final float dY = Math.abs(y - mPreviousGestureY);
        final double moveDelta = Math.hypot(Math.abs(x - mBaseX), Math.abs(y - mBaseY));
        final long timeDelta = time - mBaseTime;
        if (DEBUG) {
            Slog.d(
                    getGestureName(),
@@ -171,34 +172,38 @@ class Swipe extends GestureMatcher {
                return;
            } else if (mStrokeBuffer.size() == 0) {
                // First, make sure the pointer is going in the right direction.
                cancelAfterPauseThreshold(event, rawEvent, policyFlags);
                int direction = toDirection(x - mBaseX, y - mBaseY);
                if (direction != mDirections[0]) {
                    cancelGesture(event, rawEvent, policyFlags);
                    return;
                } else {
                }
                // This is confirmed to be some kind of swipe so start tracking points.
                mStrokeBuffer.add(new PointF(mBaseX, mBaseY));
            }
        }
        if (moveDelta > mGestureDetectionThresholdPixels) {
                // If the pointer has moved more than the threshold,
                // update the stored values.
            // This is a gesture, not touch exploration.
            mBaseX = x;
            mBaseY = y;
                if (getState() == STATE_CLEAR) {
            mBaseTime = time;
            startGesture(event, rawEvent, policyFlags);
                    cancelAfterPauseThreshold(event, rawEvent, policyFlags);
        } else if (getState() == STATE_CLEAR) {
            if (timeDelta > MAX_TIME_TO_START_SWIPE_MS) {
                // The user isn't moving fast enough.
                cancelGesture(event, rawEvent, policyFlags);
                return;
            }
        } else if (getState() == STATE_GESTURE_STARTED) {
            if (timeDelta > MAX_TIME_TO_CONTINUE_SWIPE_MS) {
                cancelGesture(event, rawEvent, policyFlags);
                return;
            }
        }
        if (getState() == STATE_GESTURE_STARTED) {
        if (dX >= mMinPixelsBetweenSamplesX || dY >= mMinPixelsBetweenSamplesY) {
            // At this point gesture detection has started and we are sampling points.
            mPreviousGestureX = x;
            mPreviousGestureY = y;
            mStrokeBuffer.add(new PointF(x, y));
                cancelAfterPauseThreshold(event, rawEvent, policyFlags);
            }
        }
    }

@@ -229,25 +234,6 @@ class Swipe extends GestureMatcher {
        cancelGesture(event, rawEvent, policyFlags);
    }

    /**
     * queues a transition to STATE_GESTURE_CANCEL based on the current state. If we have
     * transitioned to STATE_GESTURE_STARTED the delay is longer.
     */
    private void cancelAfterPauseThreshold(
            MotionEvent event, MotionEvent rawEvent, int policyFlags) {
        cancelPendingTransitions();
        switch (getState()) {
            case STATE_CLEAR:
                cancelAfter(CANCEL_ON_PAUSE_THRESHOLD_NOT_STARTED_MS, event, rawEvent, policyFlags);
                break;
            case STATE_GESTURE_STARTED:
                cancelAfter(CANCEL_ON_PAUSE_THRESHOLD_STARTED_MS, event, rawEvent, policyFlags);
                break;
            default:
                break;
        }
    }

    /**
     * Looks at the sequence of motions in mStrokeBuffer, classifies the gesture, then calls
     * Listener callbacks for success or failure.