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

Commit 794a68e9 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Fix SwipeDetector positive vs negative for HORIZONTAL direction" into ub-launcher3-master

parents 5d50fd85 101807d8
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -41,7 +41,7 @@ public class LandscapeEdgeSwipeController extends AbstractStateChangeTouchContro

    @Override
    protected LauncherState getTargetState(LauncherState fromState, boolean isDragTowardPositive) {
        boolean draggingFromNav = mLauncher.getDeviceProfile().isSeascape() != isDragTowardPositive;
        boolean draggingFromNav = mLauncher.getDeviceProfile().isSeascape() == isDragTowardPositive;
        return draggingFromNav ? OVERVIEW : NORMAL;
    }

+4 −1
Original line number Diff line number Diff line
@@ -69,6 +69,7 @@ public abstract class AbstractStateChangeTouchController

    protected final Launcher mLauncher;
    protected final SwipeDetector mDetector;
    protected final SwipeDetector.Direction mSwipeDirection;

    private boolean mNoIntercept;
    protected int mStartContainerType;
@@ -105,6 +106,7 @@ public abstract class AbstractStateChangeTouchController
    public AbstractStateChangeTouchController(Launcher l, SwipeDetector.Direction dir) {
        mLauncher = l;
        mDetector = new SwipeDetector(l, this, dir);
        mSwipeDirection = dir;
    }

    protected long getAtomicDuration() {
@@ -272,7 +274,8 @@ public abstract class AbstractStateChangeTouchController
                            displacement + "], progress = [" + progress + "]");
        }
        updateProgress(progress);
        boolean isDragTowardPositive = (displacement - mDisplacementShift) < 0;
        boolean isDragTowardPositive = mSwipeDirection.isPositive(
                displacement - mDisplacementShift);
        if (progress <= 0) {
            if (reinitCurrentAnimation(false, isDragTowardPositive)) {
                mDisplacementShift = displacement;
+56 −15
Original line number Diff line number Diff line
@@ -24,6 +24,8 @@ import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.ViewConfiguration;

import com.android.launcher3.Utilities;

import androidx.annotation.NonNull;
import androidx.annotation.VisibleForTesting;

@@ -64,20 +66,25 @@ public class SwipeDetector {

    public static abstract class Direction {

        abstract float getDisplacement(MotionEvent ev, int pointerIndex, PointF refPoint);
        abstract float getDisplacement(MotionEvent ev, int pointerIndex, PointF refPoint,
                boolean isRtl);

        /**
         * Distance in pixels a touch can wander before we think the user is scrolling.
         */
        abstract float getActiveTouchSlop(MotionEvent ev, int pointerIndex, PointF downPos);

        abstract float getVelocity(VelocityTracker tracker);
        abstract float getVelocity(VelocityTracker tracker, boolean isRtl);

        abstract boolean isPositive(float displacement);

        abstract boolean isNegative(float displacement);
    }

    public static final Direction VERTICAL = new Direction() {

        @Override
        float getDisplacement(MotionEvent ev, int pointerIndex, PointF refPoint) {
        float getDisplacement(MotionEvent ev, int pointerIndex, PointF refPoint, boolean isRtl) {
            return ev.getY(pointerIndex) - refPoint.y;
        }

@@ -87,16 +94,32 @@ public class SwipeDetector {
        }

        @Override
        float getVelocity(VelocityTracker tracker) {
        float getVelocity(VelocityTracker tracker, boolean isRtl) {
            return tracker.getYVelocity();
        }

        @Override
        boolean isPositive(float displacement) {
            // Up
            return displacement < 0;
        }

        @Override
        boolean isNegative(float displacement) {
            // Down
            return displacement > 0;
        }
    };

    public static final Direction HORIZONTAL = new Direction() {

        @Override
        float getDisplacement(MotionEvent ev, int pointerIndex, PointF refPoint) {
            return ev.getX(pointerIndex) - refPoint.x;
        float getDisplacement(MotionEvent ev, int pointerIndex, PointF refPoint, boolean isRtl) {
            float displacement = ev.getX(pointerIndex) - refPoint.x;
            if (isRtl) {
                displacement = -displacement;
            }
            return displacement;
        }

        @Override
@@ -105,8 +128,24 @@ public class SwipeDetector {
        }

        @Override
        float getVelocity(VelocityTracker tracker) {
            return tracker.getXVelocity();
        float getVelocity(VelocityTracker tracker, boolean isRtl) {
            float velocity = tracker.getXVelocity();
            if (isRtl) {
                velocity = -velocity;
            }
            return velocity;
        }

        @Override
        boolean isPositive(float displacement) {
            // Right
            return displacement > 0;
        }

        @Override
        boolean isNegative(float displacement) {
            // Left
            return displacement < 0;
        }
    };

@@ -159,6 +198,7 @@ public class SwipeDetector {
    private final PointF mDownPos = new PointF();
    private final PointF mLastPos = new PointF();
    private final Direction mDir;
    private final boolean mIsRtl;

    private final float mTouchSlop;
    private final float mMaxVelocity;
@@ -183,14 +223,15 @@ public class SwipeDetector {
    }

    public SwipeDetector(@NonNull Context context, @NonNull Listener l, @NonNull Direction dir) {
        this(ViewConfiguration.get(context), l, dir);
        this(ViewConfiguration.get(context), l, dir, Utilities.isRtl(context.getResources()));
    }

    @VisibleForTesting
    protected SwipeDetector(@NonNull ViewConfiguration config, @NonNull Listener l,
            @NonNull Direction dir) {
            @NonNull Direction dir, boolean isRtl) {
        mListener = l;
        mDir = dir;
        mIsRtl = isRtl;
        mTouchSlop = config.getScaledTouchSlop();
        mMaxVelocity = config.getScaledMaximumFlingVelocity();
    }
@@ -212,8 +253,8 @@ public class SwipeDetector {
        }

        // Check if the client is interested in scroll in current direction.
        if (((mScrollConditions & DIRECTION_NEGATIVE) > 0 && mDisplacement > 0) ||
                ((mScrollConditions & DIRECTION_POSITIVE) > 0 && mDisplacement < 0)) {
        if (((mScrollConditions & DIRECTION_NEGATIVE) > 0 && mDir.isNegative(mDisplacement)) ||
                ((mScrollConditions & DIRECTION_POSITIVE) > 0 && mDir.isPositive(mDisplacement))) {
            return true;
        }
        return false;
@@ -259,7 +300,7 @@ public class SwipeDetector {
                if (pointerIndex == INVALID_POINTER_ID) {
                    break;
                }
                mDisplacement = mDir.getDisplacement(ev, pointerIndex, mDownPos);
                mDisplacement = mDir.getDisplacement(ev, pointerIndex, mDownPos, mIsRtl);

                // handle state and listener calls.
                if (mState != ScrollState.DRAGGING && shouldScrollStart(ev, pointerIndex)) {
@@ -315,7 +356,7 @@ public class SwipeDetector {
     * @see #DIRECTION_BOTH
     */
    public boolean wasInitialTouchPositive() {
        return mSubtractDisplacement < 0;
        return mDir.isPositive(mSubtractDisplacement);
    }

    private boolean reportDragging() {
@@ -332,7 +373,7 @@ public class SwipeDetector {

    private void reportDragEnd() {
        mVelocityTracker.computeCurrentVelocity(1000, mMaxVelocity);
        float velocity = mDir.getVelocity(mVelocityTracker) / 1000;
        float velocity = mDir.getVelocity(mVelocityTracker, mIsRtl) / 1000;
        if (DBG) {
            Log.d(TAG, String.format("onScrollEnd disp=%.1f, velocity=%.1f",
                    mDisplacement, velocity));
+59 −13
Original line number Diff line number Diff line
@@ -15,9 +15,12 @@
 */
package com.android.launcher3.touch;

import androidx.test.InstrumentationRegistry;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
import static org.mockito.Matchers.anyBoolean;
import static org.mockito.Matchers.anyFloat;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;

import android.util.Log;
import android.view.ViewConfiguration;

@@ -29,11 +32,9 @@ import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;

import static org.mockito.Matchers.anyBoolean;
import static org.mockito.Matchers.anyFloat;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import androidx.test.InstrumentationRegistry;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;

@SmallTest
@RunWith(AndroidJUnit4.class)
@@ -63,7 +64,7 @@ public class SwipeDetectorTest {
        doReturn(orgConfig.getScaledMaximumFlingVelocity()).when(mMockConfig)
                .getScaledMaximumFlingVelocity();

        mDetector = new SwipeDetector(mMockConfig, mMockListener, SwipeDetector.VERTICAL);
        mDetector = new SwipeDetector(mMockConfig, mMockListener, SwipeDetector.VERTICAL, false);
        mDetector.setDetectableScrollConditions(SwipeDetector.DIRECTION_BOTH, false);
        mTouchSlop = orgConfig.getScaledTouchSlop();
        doReturn(mTouchSlop).when(mMockConfig).getScaledTouchSlop();
@@ -72,7 +73,19 @@ public class SwipeDetectorTest {
    }

    @Test
    public void testDragStart_vertical() {
    public void testDragStart_verticalPositive() {
        mDetector = new SwipeDetector(mMockConfig, mMockListener, SwipeDetector.VERTICAL, false);
        mDetector.setDetectableScrollConditions(SwipeDetector.DIRECTION_POSITIVE, false);
        mGenerator.put(0, 100, 100);
        mGenerator.move(0, 100, 100 - mTouchSlop);
        // TODO: actually calculate the following parameters and do exact value checks.
        verify(mMockListener).onDragStart(anyBoolean());
    }

    @Test
    public void testDragStart_verticalNegative() {
        mDetector = new SwipeDetector(mMockConfig, mMockListener, SwipeDetector.VERTICAL, false);
        mDetector.setDetectableScrollConditions(SwipeDetector.DIRECTION_NEGATIVE, false);
        mGenerator.put(0, 100, 100);
        mGenerator.move(0, 100, 100 + mTouchSlop);
        // TODO: actually calculate the following parameters and do exact value checks.
@@ -88,9 +101,42 @@ public class SwipeDetectorTest {
    }

    @Test
    public void testDragStart_horizontal() {
        mDetector = new SwipeDetector(mMockConfig, mMockListener, SwipeDetector.HORIZONTAL);
        mDetector.setDetectableScrollConditions(SwipeDetector.DIRECTION_BOTH, false);
    public void testDragStart_horizontalPositive() {
        mDetector = new SwipeDetector(mMockConfig, mMockListener, SwipeDetector.HORIZONTAL, false);
        mDetector.setDetectableScrollConditions(SwipeDetector.DIRECTION_POSITIVE, false);

        mGenerator.put(0, 100, 100);
        mGenerator.move(0, 100 + mTouchSlop, 100);
        // TODO: actually calculate the following parameters and do exact value checks.
        verify(mMockListener).onDragStart(anyBoolean());
    }

    @Test
    public void testDragStart_horizontalNegative() {
        mDetector = new SwipeDetector(mMockConfig, mMockListener, SwipeDetector.HORIZONTAL, false);
        mDetector.setDetectableScrollConditions(SwipeDetector.DIRECTION_NEGATIVE, false);

        mGenerator.put(0, 100, 100);
        mGenerator.move(0, 100 - mTouchSlop, 100);
        // TODO: actually calculate the following parameters and do exact value checks.
        verify(mMockListener).onDragStart(anyBoolean());
    }

    @Test
    public void testDragStart_horizontalRtlPositive() {
        mDetector = new SwipeDetector(mMockConfig, mMockListener, SwipeDetector.HORIZONTAL, true);
        mDetector.setDetectableScrollConditions(SwipeDetector.DIRECTION_POSITIVE, false);

        mGenerator.put(0, 100, 100);
        mGenerator.move(0, 100 - mTouchSlop, 100);
        // TODO: actually calculate the following parameters and do exact value checks.
        verify(mMockListener).onDragStart(anyBoolean());
    }

    @Test
    public void testDragStart_horizontalRtlNegative() {
        mDetector = new SwipeDetector(mMockConfig, mMockListener, SwipeDetector.HORIZONTAL, true);
        mDetector.setDetectableScrollConditions(SwipeDetector.DIRECTION_NEGATIVE, false);

        mGenerator.put(0, 100, 100);
        mGenerator.move(0, 100 + mTouchSlop, 100);