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

Commit db476c39 authored by Tracy Zhou's avatar Tracy Zhou
Browse files

Introduce multi finger trackpad gestures to tapl tests

- Add tests to go to overview from home and all apps

Bug: 281732733
Test: presubmit
Change-Id: Ief6d72d7293ca7dff935e764362aa5ab271fd36b
parent 0b5cc64e
Loading
Loading
Loading
Loading
+26 −2
Original line number Diff line number Diff line
@@ -16,11 +16,13 @@

package com.android.quickstep;

import static org.junit.Assert.assertNotNull;
import static org.junit.Assume.assumeTrue;

import androidx.test.filters.LargeTest;
import androidx.test.runner.AndroidJUnit4;

import com.android.launcher3.tapl.LauncherInstrumentation.TrackpadGestureType;
import com.android.launcher3.ui.PortraitLandscapeRunner.PortraitLandscape;
import com.android.launcher3.ui.TaplTestsLauncher3;
import com.android.quickstep.NavigationModeSwitchRule.NavigationModeSwitch;
@@ -38,12 +40,11 @@ public class TaplTestsTrackpad extends AbstractQuickStepTest {
    public void setUp() throws Exception {
        super.setUp();
        TaplTestsLauncher3.initialize(this);
        mLauncher.setSwipeFromTrackpad(true);
    }

    @After
    public void tearDown() {
        mLauncher.setSwipeFromTrackpad(false);
        mLauncher.setTrackpadGestureType(TrackpadGestureType.NONE);
    }

    @Test
@@ -52,7 +53,30 @@ public class TaplTestsTrackpad extends AbstractQuickStepTest {
    public void goHome() throws Exception {
        assumeTrue(mLauncher.isTablet());

        mLauncher.setTrackpadGestureType(TrackpadGestureType.THREE_FINGER);
        startTestActivity(2);
        mLauncher.goHome();
    }

    @Test
    @PortraitLandscape
    @NavigationModeSwitch
    public void switchToOverview() throws Exception {
        assumeTrue(mLauncher.isTablet());

        mLauncher.setTrackpadGestureType(TrackpadGestureType.THREE_FINGER);
        startTestActivity(2);
        mLauncher.goHome().switchToOverview();
    }

    @Test
    @PortraitLandscape
    @NavigationModeSwitch
    public void testAllAppsFromHome() throws Exception {
        assumeTrue(mLauncher.isTablet());

        mLauncher.setTrackpadGestureType(TrackpadGestureType.TWO_FINGER);
        assertNotNull("switchToAllApps() returned null",
                mLauncher.getWorkspace().switchToAllApps());
    }
}
+72 −74
Original line number Diff line number Diff line
@@ -30,6 +30,8 @@ import android.view.MotionEvent;
import androidx.annotation.NonNull;
import androidx.test.uiautomator.UiObject2;

import com.android.launcher3.tapl.LauncherInstrumentation.NavigationModel;
import com.android.launcher3.tapl.LauncherInstrumentation.TrackpadGestureType;
import com.android.launcher3.testing.shared.TestProtocol;

import java.util.List;
@@ -75,8 +77,8 @@ public abstract class Background extends LauncherInstrumentation.VisibleContaine
    }

    protected void goToOverviewUnchecked() {
        switch (mLauncher.getNavigationModel()) {
            case ZERO_BUTTON: {
        if (mLauncher.getNavigationModel() == NavigationModel.ZERO_BUTTON
                || mLauncher.getTrackpadGestureType() == TrackpadGestureType.THREE_FINGER) {
            final long downTime = SystemClock.uptimeMillis();
            sendDownPointerToEnterOverviewToLauncher(downTime);
            String swipeAndHoldToEnterOverviewActionName =
@@ -130,10 +132,7 @@ public abstract class Background extends LauncherInstrumentation.VisibleContaine
                            OVERVIEW_STATE_ORDINAL, upPointerToEnterOverviewActionName);
                }
            }
                break;
            }

            case THREE_BUTTON:
        } else {
            if (mLauncher.isTablet()) {
                mLauncher.expectEvent(TestProtocol.SEQUENCE_MAIN,
                        LauncherInstrumentation.EVENT_TOUCH_DOWN);
@@ -148,7 +147,6 @@ public abstract class Background extends LauncherInstrumentation.VisibleContaine
            mLauncher.runToState(
                    () -> mLauncher.waitForNavigationUiObject("recent_apps").click(),
                    OVERVIEW_STATE_ORDINAL, "clicking Recents button");
                break;
        }
        expectSwitchToOverviewEvents();
    }
@@ -263,10 +261,8 @@ public abstract class Background extends LauncherInstrumentation.VisibleContaine
                        endY = startY;
                    }

                    final boolean isZeroButton = mLauncher.getNavigationModel()
                            == LauncherInstrumentation.NavigationModel.ZERO_BUTTON;
                    LauncherInstrumentation.GestureScope gestureScope =
                            launcherWasVisible && isZeroButton
                            launcherWasVisible
                                    ? LauncherInstrumentation.GestureScope.INSIDE_TO_OUTSIDE
                                    : LauncherInstrumentation.GestureScope.OUTSIDE_WITH_PILFER;
                    mLauncher.executeAndWaitForEvent(
@@ -326,6 +322,8 @@ public abstract class Background extends LauncherInstrumentation.VisibleContaine
    }

    protected int getSwipeStartY() {
        return mLauncher.getRealDisplaySize().y - 1;
        return mLauncher.getTrackpadGestureType() == TrackpadGestureType.THREE_FINGER
                ? mLauncher.getDevice().getDisplayHeight() * 3 / 4
                : mLauncher.getRealDisplaySize().y - 1;
    }
}
+70 −30
Original line number Diff line number Diff line
@@ -139,6 +139,13 @@ public final class LauncherInstrumentation {
        OUTSIDE_WITH_KEYCODE,
    }

    public enum TrackpadGestureType {
        NONE,
        TWO_FINGER,
        THREE_FINGER,
        FOUR_FINGER
    }

    // Base class for launcher containers.
    abstract static class VisibleContainer {
        protected final LauncherInstrumentation mLauncher;
@@ -198,7 +205,7 @@ public final class LauncherInstrumentation {
    private boolean mCheckEventsForSuccessfulGestures = false;
    private Runnable mOnLauncherCrashed;

    private boolean mSwipeFromTrackpad = false;
    private TrackpadGestureType mTrackpadGestureType = TrackpadGestureType.NONE;
    private int mPointerCount = 0;

    private static Pattern getTouchEventPattern(String prefix, String action) {
@@ -715,8 +722,17 @@ public final class LauncherInstrumentation {
        mIgnoreTaskbarVisibility = ignoreTaskbarVisibility;
    }

    public void setSwipeFromTrackpad(boolean swipeFromTrackpad) {
        mSwipeFromTrackpad = swipeFromTrackpad;
    /**
     * Set the trackpad gesture type of the interaction.
     * @param trackpadGestureType whether it's not from trackpad, two-finger, three-finger, or
     *                            four-finger gesture.
     */
    public void setTrackpadGestureType(TrackpadGestureType trackpadGestureType) {
        mTrackpadGestureType = trackpadGestureType;
    }

    TrackpadGestureType getTrackpadGestureType() {
        return mTrackpadGestureType;
    }

    /**
@@ -1008,8 +1024,11 @@ public final class LauncherInstrumentation {
            // We need waiting for any accessibility event generated after pressing Home because
            // otherwise waitForIdle may return immediately in case when there was a big enough
            // pause in accessibility events prior to pressing Home.
            boolean isThreeFingerTrackpadGesture =
                    mTrackpadGestureType == TrackpadGestureType.THREE_FINGER;
            final String action;
            if (getNavigationModel() == NavigationModel.ZERO_BUTTON || mSwipeFromTrackpad) {
            if (getNavigationModel() == NavigationModel.ZERO_BUTTON
                    || isThreeFingerTrackpadGesture) {
                checkForAnomaly(false, true);

                final Point displaySize = getRealDisplaySize();
@@ -1025,8 +1044,9 @@ public final class LauncherInstrumentation {
                } else {
                    action = "swiping up to home";

                    int startY = mSwipeFromTrackpad ? displaySize.y * 3 / 4 : displaySize.y - 1;
                    int endY = mSwipeFromTrackpad ? displaySize.y / 4 : displaySize.y / 2;
                    int startY = isThreeFingerTrackpadGesture ? displaySize.y * 3 / 4
                            : displaySize.y - 1;
                    int endY = isThreeFingerTrackpadGesture ? displaySize.y / 4 : displaySize.y / 2;
                    swipeToState(
                            displaySize.x / 2, startY,
                            displaySize.x / 2, endY,
@@ -1070,15 +1090,18 @@ public final class LauncherInstrumentation {
            waitForLauncherInitialized();
            final boolean launcherVisible =
                    isTablet() ? isLauncherContainerVisible() : isLauncherVisible();
            if (getNavigationModel() == NavigationModel.ZERO_BUTTON || mSwipeFromTrackpad) {
            boolean isThreeFingerTrackpadGesture =
                    mTrackpadGestureType == TrackpadGestureType.THREE_FINGER;
            if (getNavigationModel() == NavigationModel.ZERO_BUTTON
                    || isThreeFingerTrackpadGesture) {
                final Point displaySize = getRealDisplaySize();
                final GestureScope gestureScope =
                        launcherVisible ? GestureScope.INSIDE_TO_OUTSIDE_WITH_KEYCODE
                                : GestureScope.OUTSIDE_WITH_KEYCODE;
                // TODO(b/225505986): change startY and endY back to displaySize.y / 2 once the
                //  issue is solved.
                int startX = mSwipeFromTrackpad ? displaySize.x / 4 : 0;
                int endX = mSwipeFromTrackpad ? displaySize.x * 3 / 4 : displaySize.x / 2;
                int startX = isThreeFingerTrackpadGesture ? displaySize.x / 4 : 0;
                int endX = isThreeFingerTrackpadGesture ? displaySize.x * 3 / 4 : displaySize.x / 2;
                linearGesture(startX, displaySize.y / 4, endX, displaySize.y / 4,
                        10, false, gestureScope);
            } else {
@@ -1615,20 +1638,30 @@ public final class LauncherInstrumentation {
        final Point start = new Point(startX, startY);
        final Point end = new Point(endX, endY);
        sendPointer(downTime, downTime, MotionEvent.ACTION_DOWN, start, gestureScope);
        if (mSwipeFromTrackpad) {
        if (mTrackpadGestureType != TrackpadGestureType.NONE) {
            sendPointer(downTime, downTime, getPointerAction(MotionEvent.ACTION_POINTER_DOWN, 1),
                    start, gestureScope);
            sendPointer(downTime, downTime, getPointerAction(MotionEvent.ACTION_POINTER_DOWN, 2),
            if (mTrackpadGestureType == TrackpadGestureType.THREE_FINGER
                    || mTrackpadGestureType == TrackpadGestureType.FOUR_FINGER) {
                sendPointer(downTime, downTime,
                        getPointerAction(MotionEvent.ACTION_POINTER_DOWN, 2),
                        start, gestureScope);
                if (mTrackpadGestureType == TrackpadGestureType.FOUR_FINGER) {
                    sendPointer(downTime, downTime,
                            getPointerAction(MotionEvent.ACTION_POINTER_DOWN, 3),
                            start, gestureScope);
                }
            }
        }
        final long endTime = movePointer(
                start, end, steps, false, downTime, downTime, slowDown, gestureScope);
        if (mSwipeFromTrackpad) {
            sendPointer(downTime, downTime, getPointerAction(MotionEvent.ACTION_POINTER_UP, 2),
                    start, gestureScope);
            sendPointer(downTime, downTime, getPointerAction(MotionEvent.ACTION_POINTER_UP, 1),
        if (mTrackpadGestureType != TrackpadGestureType.NONE) {
            for (int i = mPointerCount; i >= 2; i--) {
                sendPointer(downTime, downTime,
                        getPointerAction(MotionEvent.ACTION_POINTER_UP, i - 1),
                        start, gestureScope);
            }
        }
        sendPointer(downTime, endTime, MotionEvent.ACTION_UP, end, gestureScope);
    }

@@ -1659,20 +1692,25 @@ public final class LauncherInstrumentation {
        return getContext().getResources();
    }

    private static MotionEvent getTrackpadThreeFingerMotionEvent(long downTime, long eventTime,
            int action, float x, float y, int pointerCount) {
    private static MotionEvent getTrackpadMotionEvent(long downTime, long eventTime,
            int action, float x, float y, int pointerCount, TrackpadGestureType gestureType) {
        MotionEvent.PointerProperties[] pointerProperties =
                new MotionEvent.PointerProperties[pointerCount];
        MotionEvent.PointerCoords[] pointerCoords = new MotionEvent.PointerCoords[pointerCount];
        boolean isMultiFingerGesture = gestureType != TrackpadGestureType.TWO_FINGER;
        for (int i = 0; i < pointerCount; i++) {
            pointerProperties[i] = getPointerProperties(i);
            pointerCoords[i] = getPointerCoords(x, y);
            pointerCoords[i].setAxisValue(AXIS_GESTURE_SWIPE_FINGER_COUNT, 3);
            if (isMultiFingerGesture) {
                pointerCoords[i].setAxisValue(AXIS_GESTURE_SWIPE_FINGER_COUNT,
                        gestureType == TrackpadGestureType.THREE_FINGER ? 3 : 4);
            }
        }
        return MotionEvent.obtain(downTime, eventTime, action, pointerCount, pointerProperties,
                pointerCoords, 0, 0, 1.0f, 1.0f, 0, 0,
                InputDevice.SOURCE_MOUSE | InputDevice.SOURCE_CLASS_POINTER, 0, 0,
                MotionEvent.CLASSIFICATION_MULTI_FINGER_SWIPE);
                isMultiFingerGesture ? MotionEvent.CLASSIFICATION_MULTI_FINGER_SWIPE
                        : MotionEvent.CLASSIFICATION_TWO_FINGER_SWIPE);
    }

    private static MotionEvent getMotionEvent(long downTime, long eventTime, int action,
@@ -1712,22 +1750,25 @@ public final class LauncherInstrumentation {
    public void sendPointer(long downTime, long currentTime, int action, Point point,
            GestureScope gestureScope) {
        final boolean hasTIS = hasTIS();
        int pointerCount = 1;
        int pointerCount = mPointerCount;

        boolean isTrackpadGesture = mTrackpadGestureType != TrackpadGestureType.NONE;
        boolean isTwoFingerTrackpadGesture = mTrackpadGestureType == TrackpadGestureType.TWO_FINGER;
        switch (action & MotionEvent.ACTION_MASK) {
            case MotionEvent.ACTION_DOWN:
                if (gestureScope != GestureScope.OUTSIDE_WITH_PILFER
                        && gestureScope != GestureScope.OUTSIDE_WITHOUT_PILFER
                        && gestureScope != GestureScope.OUTSIDE_WITH_KEYCODE
                        && !mSwipeFromTrackpad) {
                        && (!isTrackpadGesture || isTwoFingerTrackpadGesture)) {
                    expectEvent(TestProtocol.SEQUENCE_MAIN, EVENT_TOUCH_DOWN);
                }
                if (hasTIS && (isTrackpadGestureEnabled()
                        || getNavigationModel() != NavigationModel.THREE_BUTTON)) {
                    expectEvent(TestProtocol.SEQUENCE_TIS, EVENT_TOUCH_DOWN_TIS);
                }
                if (mSwipeFromTrackpad) {
                if (isTrackpadGesture) {
                    mPointerCount = 1;
                    pointerCount = mPointerCount;
                }
                break;
            case MotionEvent.ACTION_UP:
@@ -1740,7 +1781,7 @@ public final class LauncherInstrumentation {
                if (gestureScope != GestureScope.OUTSIDE_WITH_PILFER
                        && gestureScope != GestureScope.OUTSIDE_WITHOUT_PILFER
                        && gestureScope != GestureScope.OUTSIDE_WITH_KEYCODE
                        && !mSwipeFromTrackpad) {
                        && (!isTrackpadGesture || isTwoFingerTrackpadGesture)) {
                    expectEvent(TestProtocol.SEQUENCE_MAIN,
                            gestureScope == GestureScope.INSIDE
                                    || gestureScope == GestureScope.OUTSIDE_WITHOUT_PILFER
@@ -1767,8 +1808,6 @@ public final class LauncherInstrumentation {
                pointerCount = mPointerCount;
                break;
            case MotionEvent.ACTION_POINTER_UP:
                pointerCount = mPointerCount;

                // When the gesture is handled outside, it's cancelled within launcher.
                if (gestureScope != GestureScope.INSIDE_TO_OUTSIDE_WITH_KEYCODE
                        && gestureScope != GestureScope.OUTSIDE_WITH_KEYCODE) {
@@ -1779,9 +1818,10 @@ public final class LauncherInstrumentation {
                break;
        }

        final MotionEvent event = mSwipeFromTrackpad
                ? getTrackpadThreeFingerMotionEvent(
                        downTime, currentTime, action, point.x, point.y, pointerCount)
        final MotionEvent event = isTrackpadGesture
                ? getTrackpadMotionEvent(
                        downTime, currentTime, action, point.x, point.y, pointerCount,
                        mTrackpadGestureType)
                : getMotionEvent(downTime, currentTime, action, point.x, point.y);
        assertTrue("injectInputEvent failed",
                mInstrumentation.getUiAutomation().injectInputEvent(event, true, false));