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
diff --git a/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java b/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java
index 4895b10..437a19b 100644
--- a/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java
+++ b/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java
@@ -31,6 +31,7 @@
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherState;
+import com.android.launcher3.tapl.AllApps;
import com.android.launcher3.tapl.Background;
import com.android.launcher3.tapl.LauncherInstrumentation.NavigationModel;
import com.android.launcher3.tapl.Overview;
@@ -49,6 +50,9 @@
@LargeTest
@RunWith(AndroidJUnit4.class)
public class TaplTestsQuickstep extends AbstractQuickStepTest {
+
+ private static final String APP_NAME = "LauncherTestApp";
+
@Before
public void setUp() throws Exception {
super.setUp();
@@ -286,6 +290,30 @@
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
@PortraitLandscape
public void testOverviewForTablet() throws Exception {
diff --git a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
index 0ffbeeb..82163cb 100644
--- a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
+++ b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
@@ -211,7 +211,8 @@
}
protected TestRule getRulesInsideActivityMonitor() {
- final RuleChain inner = RuleChain.outerRule(new PortraitLandscapeRunner(this))
+ final RuleChain inner = RuleChain
+ .outerRule(new PortraitLandscapeRunner(this))
.around(new FailureWatcher(mDevice, mLauncher));
return TestHelpers.isInLauncherProcess()
diff --git a/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java b/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java
index 2fa84b2..4007c26 100644
--- a/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java
+++ b/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java
@@ -413,6 +413,27 @@
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() {
return getInstrumentation().getContext().getPackageName();
}
diff --git a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
index 3ac5fa5..e2d0238 100644
--- a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
+++ b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
@@ -76,6 +76,7 @@
import java.io.IOException;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Deque;
@@ -110,6 +111,9 @@
static final Pattern EVENT_TOUCH_DOWN_TIS = getTouchEventPatternTIS("ACTION_DOWN");
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 Boolean mIsLauncher3;
private long mTestStartTime = -1;
@@ -125,7 +129,8 @@
// Where the gesture happens: outside of Launcher, inside or from inside to outside and
// whether the gesture recognition triggers pilfer.
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.
@@ -195,6 +200,10 @@
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.
*/
@@ -879,6 +888,38 @@
}
}
+ /**
+ * 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() {
return By.textStartsWith("");
}
@@ -888,6 +929,11 @@
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
* launcher is not in that state.
@@ -1414,6 +1460,7 @@
break;
case MotionEvent.ACTION_UP:
if (notLauncher3 && gestureScope != GestureScope.INSIDE
+ && gestureScope != GestureScope.INSIDE_TO_OUTSIDE_WITHOUT_PILFER
&& (gestureScope == GestureScope.OUTSIDE_WITH_PILFER
|| gestureScope == GestureScope.INSIDE_TO_OUTSIDE)) {
expectEvent(TestProtocol.SEQUENCE_PILFER, EVENT_PILFER_POINTERS);