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

Commit 6c00386c authored by Benno Lin's avatar Benno Lin
Browse files

Implement pressing back button and swiping back

This CL implements a pressBack function to press back button or swiping
back in gesture navigation mode.

Bug: 199120092
Test: atest -c Launcher3Tests:com.android.launcher3.ui.TaplTestsLauncher3#testPressBack &&
    atest -c NexusLauncherTests:com.android.quickstep.TaplTestsQuickstep#testPressBack
Change-Id: I001cea17d09ae1ab7952d04ee394a2afa5bf1e67
parent 8f083ccc
Loading
Loading
Loading
Loading
+28 −0
Original line number Original line Diff line number Diff line
@@ -31,6 +31,7 @@ import androidx.test.uiautomator.Until;


import com.android.launcher3.Launcher;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherState;
import com.android.launcher3.LauncherState;
import com.android.launcher3.tapl.AllApps;
import com.android.launcher3.tapl.Background;
import com.android.launcher3.tapl.Background;
import com.android.launcher3.tapl.LauncherInstrumentation.NavigationModel;
import com.android.launcher3.tapl.LauncherInstrumentation.NavigationModel;
import com.android.launcher3.tapl.Overview;
import com.android.launcher3.tapl.Overview;
@@ -49,6 +50,9 @@ import org.junit.runner.RunWith;
@LargeTest
@LargeTest
@RunWith(AndroidJUnit4.class)
@RunWith(AndroidJUnit4.class)
public class TaplTestsQuickstep extends AbstractQuickStepTest {
public class TaplTestsQuickstep extends AbstractQuickStepTest {

    private static final String APP_NAME = "LauncherTestApp";

    @Before
    @Before
    public void setUp() throws Exception {
    public void setUp() throws Exception {
        super.setUp();
        super.setUp();
@@ -286,6 +290,30 @@ public class TaplTestsQuickstep extends AbstractQuickStepTest {
        getAndAssertBackground();
        getAndAssertBackground();
    }
    }


    // TODO(b/204830798): test with all navigation modes(add @NavigationModeSwitch annotation)
    //  after the bug resolved.
    @Test
    @PortraitLandscape
    @ScreenRecord
    public void testPressBack() throws Exception {
        mLauncher.getWorkspace().switchToAllApps();
        mLauncher.pressBack();
        mLauncher.getWorkspace();
        waitForState("Launcher internal state didn't switch to Home", () -> LauncherState.NORMAL);

        AllApps allApps = mLauncher.getWorkspace().switchToAllApps();
        allApps.freeze();
        try {
            allApps.getAppIcon(APP_NAME).dragToWorkspace(false, false);
        } finally {
            allApps.unfreeze();
        }
        mLauncher.getWorkspace().getWorkspaceAppIcon(APP_NAME).launch(getAppPackageName());
        mLauncher.pressBack();
        mLauncher.getWorkspace();
        waitForState("Launcher internal state didn't switch to Home", () -> LauncherState.NORMAL);
    }

    @Test
    @Test
    @PortraitLandscape
    @PortraitLandscape
    public void testOverviewForTablet() throws Exception {
    public void testOverviewForTablet() throws Exception {
+2 −1
Original line number Original line Diff line number Diff line
@@ -211,7 +211,8 @@ public abstract class AbstractLauncherUiTest {
    }
    }


    protected TestRule getRulesInsideActivityMonitor() {
    protected TestRule getRulesInsideActivityMonitor() {
        final RuleChain inner = RuleChain.outerRule(new PortraitLandscapeRunner(this))
        final RuleChain inner = RuleChain
                .outerRule(new PortraitLandscapeRunner(this))
                .around(new FailureWatcher(mDevice, mLauncher));
                .around(new FailureWatcher(mDevice, mLauncher));


        return TestHelpers.isInLauncherProcess()
        return TestHelpers.isInLauncherProcess()
+21 −0
Original line number Original line Diff line number Diff line
@@ -413,6 +413,27 @@ public class TaplTestsLauncher3 extends AbstractLauncherUiTest {
        folder.close();
        folder.close();
    }
    }


    @Test
    @PortraitLandscape
    public void testPressBack() throws Exception {
        mLauncher.getWorkspace().switchToAllApps();
        mLauncher.pressBack();
        mLauncher.getWorkspace();
        waitForState("Launcher internal state didn't switch to Home", () -> LauncherState.NORMAL);

        AllApps allApps = mLauncher.getWorkspace().switchToAllApps();
        allApps.freeze();
        try {
            allApps.getAppIcon(APP_NAME).dragToWorkspace(false, false);
        } finally {
            allApps.unfreeze();
        }
        mLauncher.getWorkspace().getWorkspaceAppIcon(APP_NAME).launch(getAppPackageName());
        mLauncher.pressBack();
        mLauncher.getWorkspace();
        waitForState("Launcher internal state didn't switch to Home", () -> LauncherState.NORMAL);
    }

    public static String getAppPackageName() {
    public static String getAppPackageName() {
        return getInstrumentation().getContext().getPackageName();
        return getInstrumentation().getContext().getPackageName();
    }
    }
+48 −1
Original line number Original line Diff line number Diff line
@@ -76,6 +76,7 @@ import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.IOException;
import java.lang.ref.WeakReference;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collection;
import java.util.Collections;
import java.util.Collections;
import java.util.Deque;
import java.util.Deque;
@@ -110,6 +111,9 @@ public final class LauncherInstrumentation {
    static final Pattern EVENT_TOUCH_DOWN_TIS = getTouchEventPatternTIS("ACTION_DOWN");
    static final Pattern EVENT_TOUCH_DOWN_TIS = getTouchEventPatternTIS("ACTION_DOWN");
    static final Pattern EVENT_TOUCH_UP_TIS = getTouchEventPatternTIS("ACTION_UP");
    static final Pattern EVENT_TOUCH_UP_TIS = getTouchEventPatternTIS("ACTION_UP");


    static final Pattern EVENT_KEY_BACK_DOWN = getKeyEventPattern("ACTION_DOWN", "KEYCODE_BACK");
    static final Pattern EVENT_KEY_BACK_UP = getKeyEventPattern("ACTION_UP", "KEYCODE_BACK");

    private final String mLauncherPackage;
    private final String mLauncherPackage;
    private Boolean mIsLauncher3;
    private Boolean mIsLauncher3;
    private long mTestStartTime = -1;
    private long mTestStartTime = -1;
@@ -125,7 +129,8 @@ public final class LauncherInstrumentation {
    // Where the gesture happens: outside of Launcher, inside or from inside to outside and
    // Where the gesture happens: outside of Launcher, inside or from inside to outside and
    // whether the gesture recognition triggers pilfer.
    // whether the gesture recognition triggers pilfer.
    public enum GestureScope {
    public enum GestureScope {
        OUTSIDE_WITHOUT_PILFER, OUTSIDE_WITH_PILFER, INSIDE, INSIDE_TO_OUTSIDE
        OUTSIDE_WITHOUT_PILFER, OUTSIDE_WITH_PILFER, INSIDE, INSIDE_TO_OUTSIDE,
        INSIDE_TO_OUTSIDE_WITHOUT_PILFER,
    }
    }


    // Base class for launcher containers.
    // Base class for launcher containers.
@@ -195,6 +200,10 @@ public final class LauncherInstrumentation {
        return getTouchEventPattern("TouchInteractionService.onInputEvent", action);
        return getTouchEventPattern("TouchInteractionService.onInputEvent", action);
    }
    }


    private static Pattern getKeyEventPattern(String action, String keyCode) {
        return Pattern.compile("Key event: KeyEvent.*action=" + action + ".*keyCode=" + keyCode);
    }

    /**
    /**
     * Constructs the root of TAPL hierarchy. You get all other objects from it.
     * Constructs the root of TAPL hierarchy. You get all other objects from it.
     */
     */
@@ -879,6 +888,38 @@ public final class LauncherInstrumentation {
        }
        }
    }
    }


    /**
     * Press navbar back button or swipe back if in gesture navigation mode.
     */
    public void pressBack() {
        try (Closable e = eventsCheck(); Closable c = addContextLayer("want to press back")) {
            waitForLauncherInitialized();
            final boolean launcherVisible =
                    isTablet() ? isLauncherContainerVisible() : isLauncherVisible();
            if (getNavigationModel() == NavigationModel.ZERO_BUTTON) {
                final Point displaySize = getRealDisplaySize();
                final GestureScope gestureScope =
                        launcherVisible ? GestureScope.INSIDE_TO_OUTSIDE_WITHOUT_PILFER
                                : GestureScope.OUTSIDE_WITHOUT_PILFER;
                linearGesture(0, displaySize.y / 2, displaySize.x / 2, displaySize.y / 2,
                        10, false, gestureScope);
            } else {
                waitForNavigationUiObject("back").click();
                if (isTablet()) {
                    expectEvent(TestProtocol.SEQUENCE_MAIN, EVENT_TOUCH_DOWN);
                    expectEvent(TestProtocol.SEQUENCE_MAIN, EVENT_TOUCH_UP);
                } else if (!isLauncher3() && getNavigationModel() == NavigationModel.TWO_BUTTON) {
                    expectEvent(TestProtocol.SEQUENCE_TIS, EVENT_TOUCH_DOWN_TIS);
                    expectEvent(TestProtocol.SEQUENCE_TIS, EVENT_TOUCH_UP_TIS);
                }
            }
            if (launcherVisible) {
                expectEvent(TestProtocol.SEQUENCE_MAIN, EVENT_KEY_BACK_DOWN);
                expectEvent(TestProtocol.SEQUENCE_MAIN, EVENT_KEY_BACK_UP);
            }
        }
    }

    private static BySelector getAnyObjectSelector() {
    private static BySelector getAnyObjectSelector() {
        return By.textStartsWith("");
        return By.textStartsWith("");
    }
    }
@@ -888,6 +929,11 @@ public final class LauncherInstrumentation {
        return hasLauncherObject(getAnyObjectSelector());
        return hasLauncherObject(getAnyObjectSelector());
    }
    }


    boolean isLauncherContainerVisible() {
        final String[] containerResources = {WORKSPACE_RES_ID, OVERVIEW_RES_ID, APPS_RES_ID};
        return Arrays.stream(containerResources).anyMatch(r -> hasLauncherObject(r));
    }

    /**
    /**
     * Gets the Workspace object if the current state is "active home", i.e. workspace. Fails if the
     * Gets the Workspace object if the current state is "active home", i.e. workspace. Fails if the
     * launcher is not in that state.
     * launcher is not in that state.
@@ -1414,6 +1460,7 @@ public final class LauncherInstrumentation {
                break;
                break;
            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_UP:
                if (notLauncher3 && gestureScope != GestureScope.INSIDE
                if (notLauncher3 && gestureScope != GestureScope.INSIDE
                        && gestureScope != GestureScope.INSIDE_TO_OUTSIDE_WITHOUT_PILFER
                        && (gestureScope == GestureScope.OUTSIDE_WITH_PILFER
                        && (gestureScope == GestureScope.OUTSIDE_WITH_PILFER
                        || gestureScope == GestureScope.INSIDE_TO_OUTSIDE)) {
                        || gestureScope == GestureScope.INSIDE_TO_OUTSIDE)) {
                    expectEvent(TestProtocol.SEQUENCE_PILFER, EVENT_PILFER_POINTERS);
                    expectEvent(TestProtocol.SEQUENCE_PILFER, EVENT_PILFER_POINTERS);