Preparing QuickstepOnOff for running in 3 navigation modes

Change-Id: I7855e756c9886a21bfc2584cf42e7921147fb256
diff --git a/quickstep/tests/src/com/android/quickstep/AbstractQuickStepTest.java b/quickstep/tests/src/com/android/quickstep/AbstractQuickStepTest.java
index 6854aa8..c77726e 100644
--- a/quickstep/tests/src/com/android/quickstep/AbstractQuickStepTest.java
+++ b/quickstep/tests/src/com/android/quickstep/AbstractQuickStepTest.java
@@ -27,5 +27,5 @@
 public abstract class AbstractQuickStepTest extends AbstractLauncherUiTest {
     @Rule
     public TestRule mQuickstepOnOffExecutor =
-            new QuickStepOnOffRule(mMainThreadExecutor, mLauncher);
+            new NavigationModeSwitchRule(mLauncher);
 }
diff --git a/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java b/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java
index 88b50d9..f436831 100644
--- a/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java
+++ b/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java
@@ -17,26 +17,31 @@
 
 import static android.content.pm.PackageManager.MATCH_DISABLED_COMPONENTS;
 
+import static androidx.test.InstrumentationRegistry.getInstrumentation;
+
 import static com.android.launcher3.tapl.LauncherInstrumentation.WAIT_TIME_MS;
 import static com.android.launcher3.tapl.TestHelpers.getHomeIntentInPackage;
 import static com.android.launcher3.tapl.TestHelpers.getLauncherInMyProcess;
 import static com.android.launcher3.util.rule.ShellCommandRule.disableHeadsUpNotification;
 import static com.android.launcher3.util.rule.ShellCommandRule.getLauncherCommand;
-import static com.android.quickstep.QuickStepOnOffRule.Mode.OFF;
+import static com.android.quickstep.NavigationModeSwitchRule.Mode.THREE_BUTTON;
 
 import static org.junit.Assert.assertTrue;
 
-import static androidx.test.InstrumentationRegistry.getInstrumentation;
-
 import android.app.Instrumentation;
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.ActivityInfo;
 
-import com.android.launcher3.MainThreadExecutor;
+import androidx.test.filters.LargeTest;
+import androidx.test.runner.AndroidJUnit4;
+import androidx.test.uiautomator.By;
+import androidx.test.uiautomator.UiDevice;
+import androidx.test.uiautomator.Until;
+
 import com.android.launcher3.tapl.LauncherInstrumentation;
 import com.android.launcher3.testcomponent.TestCommandReceiver;
-import com.android.quickstep.QuickStepOnOffRule.QuickstepOnOff;
+import com.android.quickstep.NavigationModeSwitchRule.NavigationModeSwitch;
 
 import org.junit.Rule;
 import org.junit.Test;
@@ -44,12 +49,6 @@
 import org.junit.runner.RunWith;
 import org.junit.runners.model.Statement;
 
-import androidx.test.filters.LargeTest;
-import androidx.test.runner.AndroidJUnit4;
-import androidx.test.uiautomator.By;
-import androidx.test.uiautomator.UiDevice;
-import androidx.test.uiautomator.Until;
-
 @LargeTest
 @RunWith(AndroidJUnit4.class)
 /**
@@ -72,7 +71,7 @@
         mDevice = UiDevice.getInstance(instrumentation);
         mLauncher = new LauncherInstrumentation(instrumentation);
 
-        mQuickstepOnOffExecutor = new QuickStepOnOffRule(new MainThreadExecutor(), mLauncher);
+        mQuickstepOnOffExecutor = new NavigationModeSwitchRule(mLauncher);
         mOtherLauncherActivity = context.getPackageManager().queryIntentActivities(
                 getHomeIntentInPackage(context),
                 MATCH_DISABLED_COMPONENTS).get(0).activityInfo;
@@ -94,7 +93,7 @@
         };
     }
 
-    @QuickstepOnOff(mode = OFF)
+    @NavigationModeSwitch(mode = THREE_BUTTON)
     @Test
     public void goToOverviewFromHome() {
         mDevice.pressHome();
@@ -104,7 +103,7 @@
         mLauncher.getBackground().switchToOverview();
     }
 
-    @QuickstepOnOff(mode = OFF)
+    @NavigationModeSwitch(mode = THREE_BUTTON)
     @Test
     public void goToOverviewFromApp() {
         startAppFast("com.android.settings");
diff --git a/quickstep/tests/src/com/android/quickstep/QuickStepOnOffRule.java b/quickstep/tests/src/com/android/quickstep/NavigationModeSwitchRule.java
similarity index 63%
rename from quickstep/tests/src/com/android/quickstep/QuickStepOnOffRule.java
rename to quickstep/tests/src/com/android/quickstep/NavigationModeSwitchRule.java
index 12bd0ca..8633b21 100644
--- a/quickstep/tests/src/com/android/quickstep/QuickStepOnOffRule.java
+++ b/quickstep/tests/src/com/android/quickstep/NavigationModeSwitchRule.java
@@ -18,9 +18,9 @@
 
 import static androidx.test.InstrumentationRegistry.getInstrumentation;
 
-import static com.android.quickstep.QuickStepOnOffRule.Mode.BOTH;
-import static com.android.quickstep.QuickStepOnOffRule.Mode.OFF;
-import static com.android.quickstep.QuickStepOnOffRule.Mode.ON;
+import static com.android.quickstep.NavigationModeSwitchRule.Mode.ALL;
+import static com.android.quickstep.NavigationModeSwitchRule.Mode.THREE_BUTTON;
+import static com.android.quickstep.NavigationModeSwitchRule.Mode.TWO_BUTTON;
 import static com.android.systemui.shared.system.QuickStepContract.NAV_BAR_MODE_2BUTTON_OVERLAY;
 import static com.android.systemui.shared.system.QuickStepContract.NAV_BAR_MODE_3BUTTON_OVERLAY;
 import static com.android.systemui.shared.system.QuickStepContract.NAV_BAR_MODE_GESTURAL_OVERLAY;
@@ -34,49 +34,46 @@
 import com.android.launcher3.tapl.TestHelpers;
 import com.android.systemui.shared.system.QuickStepContract;
 
+import org.junit.Assert;
 import org.junit.rules.TestRule;
 import org.junit.runner.Description;
 import org.junit.runners.model.Statement;
 
-import java.io.IOException;
 import java.lang.annotation.ElementType;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.lang.annotation.Target;
-import java.util.concurrent.Executor;
 
 /**
  * Test rule that allows executing a test with Quickstep on and then Quickstep off.
  * The test should be annotated with @QuickstepOnOff.
  */
-public class QuickStepOnOffRule implements TestRule {
+public class NavigationModeSwitchRule implements TestRule {
 
     static final String TAG = "QuickStepOnOffRule";
 
     public enum Mode {
-        ON, OFF, BOTH
+        THREE_BUTTON, TWO_BUTTON, ZERO_BUTTON, ALL
     }
 
     // Annotation for tests that need to be run with quickstep enabled and disabled.
     @Retention(RetentionPolicy.RUNTIME)
     @Target(ElementType.METHOD)
-    public @interface QuickstepOnOff {
-        Mode mode() default BOTH;
+    public @interface NavigationModeSwitch {
+        Mode mode() default ALL;
     }
 
-    private final Executor mMainThreadExecutor;
     private final LauncherInstrumentation mLauncher;
 
-    public QuickStepOnOffRule(Executor mainThreadExecutor, LauncherInstrumentation launcher) {
+    public NavigationModeSwitchRule(LauncherInstrumentation launcher) {
         mLauncher = launcher;
-        this.mMainThreadExecutor = mainThreadExecutor;
     }
 
     @Override
     public Statement apply(Statement base, Description description) {
         if (TestHelpers.isInLauncherProcess() &&
-                description.getAnnotation(QuickstepOnOff.class) != null) {
-            Mode mode = description.getAnnotation(QuickstepOnOff.class).mode();
+                description.getAnnotation(NavigationModeSwitch.class) != null) {
+            Mode mode = description.getAnnotation(NavigationModeSwitch.class).mode();
             return new Statement() {
                 @Override
                 public void evaluate() throws Throwable {
@@ -86,15 +83,20 @@
                             : QuickStepContract.isSwipeUpMode(context)
                                     ? NAV_BAR_MODE_2BUTTON_OVERLAY
                                     : NAV_BAR_MODE_3BUTTON_OVERLAY;
+                    final LauncherInstrumentation.NavigationModel originalMode =
+                            mLauncher.getNavigationModel();
                     try {
-                        if (mode == ON || mode == BOTH) {
-                            evaluateWithQuickstepOn();
+//                        if (mode == ZERO_BUTTON || mode == ALL) {
+//                            evaluateWithZeroButtons();
+//                        }
+                        if (mode == TWO_BUTTON || mode == ALL) {
+                            evaluateWithTwoButtons();
                         }
-                        if (mode == OFF || mode == BOTH) {
-                            evaluateWithQuickstepOff();
+                        if (mode == THREE_BUTTON || mode == ALL) {
+                            evaluateWithThreeButtons();
                         }
                     } finally {
-                        setActiveOverlay(prevOverlayPkg);
+                        setActiveOverlay(prevOverlayPkg, originalMode);
                     }
                 }
 
@@ -102,17 +104,26 @@
                     base.evaluate();
                 }
 
-                private void evaluateWithQuickstepOff() throws Throwable {
-                    setActiveOverlay(NAV_BAR_MODE_3BUTTON_OVERLAY);
+                private void evaluateWithThreeButtons() throws Throwable {
+                    setActiveOverlay(NAV_BAR_MODE_3BUTTON_OVERLAY,
+                            LauncherInstrumentation.NavigationModel.THREE_BUTTON);
                     evaluateWithoutChangingSetting(base);
                 }
 
-                private void evaluateWithQuickstepOn() throws Throwable {
-                    setActiveOverlay(NAV_BAR_MODE_2BUTTON_OVERLAY);
+                private void evaluateWithTwoButtons() throws Throwable {
+                    setActiveOverlay(NAV_BAR_MODE_2BUTTON_OVERLAY,
+                            LauncherInstrumentation.NavigationModel.TWO_BUTTON);
                     base.evaluate();
                 }
 
-                private void setActiveOverlay(String overlayPackage) {
+                private void evaluateWithZeroButtons() throws Throwable {
+                    setActiveOverlay(NAV_BAR_MODE_GESTURAL_OVERLAY,
+                            LauncherInstrumentation.NavigationModel.ZERO_BUTTON);
+                    base.evaluate();
+                }
+
+                private void setActiveOverlay(String overlayPackage,
+                        LauncherInstrumentation.NavigationModel expectedMode) throws Exception {
                     setOverlayPackageEnabled(NAV_BAR_MODE_3BUTTON_OVERLAY,
                             overlayPackage == NAV_BAR_MODE_3BUTTON_OVERLAY);
                     setOverlayPackageEnabled(NAV_BAR_MODE_2BUTTON_OVERLAY,
@@ -120,18 +131,19 @@
                     setOverlayPackageEnabled(NAV_BAR_MODE_GESTURAL_OVERLAY,
                             overlayPackage == NAV_BAR_MODE_GESTURAL_OVERLAY);
 
-                    // TODO: Wait until nav bar mode has applied
+                    for (int i = 0; i != 100; ++i) {
+                        if (mLauncher.getNavigationModel() == expectedMode) return;
+                        Thread.sleep(100);
+                    }
+                    Assert.fail("Couldn't switch to " + overlayPackage);
                 }
 
-                private void setOverlayPackageEnabled(String overlayPackage, boolean enable) {
+                private void setOverlayPackageEnabled(String overlayPackage, boolean enable)
+                        throws Exception {
                     Log.d(TAG, "setOverlayPackageEnabled: " + overlayPackage + " " + enable);
                     final String action = enable ? "enable" : "disable";
-                    try {
-                        UiDevice.getInstance(getInstrumentation()).executeShellCommand(
-                                "cmd overlay " + action + " " + overlayPackage);
-                    } catch (IOException e) {
-                        e.printStackTrace();
-                    }
+                    UiDevice.getInstance(getInstrumentation()).executeShellCommand(
+                            "cmd overlay " + action + " " + overlayPackage);
                 }
             };
         } else {
diff --git a/quickstep/tests/src/com/android/quickstep/StartLauncherViaGestureTests.java b/quickstep/tests/src/com/android/quickstep/StartLauncherViaGestureTests.java
index 6031dcd..554aef4 100644
--- a/quickstep/tests/src/com/android/quickstep/StartLauncherViaGestureTests.java
+++ b/quickstep/tests/src/com/android/quickstep/StartLauncherViaGestureTests.java
@@ -26,8 +26,8 @@
 
 import com.android.launcher3.Launcher;
 import com.android.launcher3.util.RaceConditionReproducer;
-import com.android.quickstep.QuickStepOnOffRule.Mode;
-import com.android.quickstep.QuickStepOnOffRule.QuickstepOnOff;
+import com.android.quickstep.NavigationModeSwitchRule.Mode;
+import com.android.quickstep.NavigationModeSwitchRule.NavigationModeSwitch;
 
 import org.junit.Before;
 import org.junit.Ignore;
@@ -62,7 +62,7 @@
 
     @Test
     @Ignore // Ignoring until gestural navigation event sequence settles
-    @QuickstepOnOff(mode = Mode.ON)
+    @NavigationModeSwitch(mode = Mode.TWO_BUTTON)
     public void testPressHome() {
         runTest(enterEvt(Launcher.ON_CREATE_EVT),
                 exitEvt(Launcher.ON_CREATE_EVT),
@@ -77,14 +77,14 @@
 
     @Test
     @Ignore // Ignoring until gestural navigation event sequence settles
-    @QuickstepOnOff(mode = Mode.ON)
+    @NavigationModeSwitch(mode = Mode.TWO_BUTTON)
     public void testSwipeToOverview() {
         closeLauncherActivity();
         mLauncher.getBackground().switchToOverview();
     }
 
     @Test
-    @QuickstepOnOff
+    @NavigationModeSwitch
     public void testStressPressHome() {
         for (int i = 0; i < STRESS_REPEAT_COUNT; ++i) {
             // Destroy Launcher activity.
@@ -96,7 +96,7 @@
     }
 
     @Test
-    @QuickstepOnOff
+    @NavigationModeSwitch
     public void testStressSwipeToOverview() {
         for (int i = 0; i < STRESS_REPEAT_COUNT; ++i) {
             // Destroy Launcher activity.
diff --git a/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java b/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java
index c60cf45..226e5ee 100644
--- a/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java
+++ b/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java
@@ -37,7 +37,7 @@
 import com.android.launcher3.tapl.OverviewTask;
 import com.android.launcher3.tapl.TestHelpers;
 import com.android.launcher3.ui.TaplTestsLauncher3;
-import com.android.quickstep.QuickStepOnOffRule.QuickstepOnOff;
+import com.android.quickstep.NavigationModeSwitchRule.NavigationModeSwitch;
 import com.android.quickstep.views.RecentsView;
 
 import org.junit.Before;
@@ -79,7 +79,7 @@
     }
 
     @Test
-    @QuickstepOnOff
+    @NavigationModeSwitch
     @PortraitLandscape
     public void testWorkspaceSwitchToAllApps() {
         assertNotNull("switchToAllApps() returned null",
@@ -198,7 +198,7 @@
     }
 
     @Test
-    @QuickstepOnOff
+    @NavigationModeSwitch
     @PortraitLandscape
     public void testSwitchToOverview() throws Exception {
         assertNotNull("Workspace.switchToOverview() returned null",
@@ -208,7 +208,7 @@
     }
 
     @Test
-    @QuickstepOnOff
+    @NavigationModeSwitch
     @PortraitLandscape
     public void testBackground() throws Exception {
         startAppFast(resolveSystemApp(Intent.CATEGORY_APP_CALCULATOR));
diff --git a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
index 125deaf..b71f790 100644
--- a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
+++ b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
@@ -166,23 +166,28 @@
     }
 
     public NavigationModel getNavigationModel() {
-        return isSwipeUpEnabled() ? NavigationModel.TWO_BUTTON : NavigationModel.THREE_BUTTON;
-    }
-
-    static boolean needSlowGestures() {
-        return Build.MODEL.contains("Cuttlefish");
-    }
-
-    private boolean isSwipeUpEnabled() {
         final Context baseContext = mInstrumentation.getTargetContext();
         try {
             // Workaround, use constructed context because both the instrumentation context and the
             // app context are not constructed with resources that take overlays into account
-            Context ctx = baseContext.createPackageContext(getLauncherPackageName(), 0);
-            return !QuickStepContract.isLegacyMode(ctx);
+            final Context ctx = baseContext.createPackageContext("android", 0);
+            if (QuickStepContract.isGesturalMode(ctx)) {
+                return NavigationModel.ZERO_BUTTON;
+            } else if (QuickStepContract.isSwipeUpMode(ctx)) {
+                return NavigationModel.TWO_BUTTON;
+            } else if (QuickStepContract.isLegacyMode(ctx)) {
+                return NavigationModel.THREE_BUTTON;
+            } else {
+                fail("Can't detect navigation mode");
+            }
         } catch (PackageManager.NameNotFoundException e) {
-            return false;
+            fail(e.toString());
         }
+        return NavigationModel.THREE_BUTTON;
+    }
+
+    static boolean needSlowGestures() {
+        return Build.MODEL.contains("Cuttlefish");
     }
 
     static void log(String message) {
@@ -233,9 +238,13 @@
     private UiObject2 verifyContainerType(ContainerType containerType) {
         assertEquals("Unexpected display rotation",
                 mExpectedRotation, mDevice.getDisplayRotation());
-        assertTrue("Presence of recents button doesn't match isSwipeUpEnabled()",
-                isSwipeUpEnabled() ==
-                        (mDevice.findObject(By.res(SYSTEMUI_PACKAGE, "recent_apps")) == null));
+        final NavigationModel navigationModel = getNavigationModel();
+        assertTrue("Presence of recents button doesn't match the interaction mode",
+                (navigationModel == NavigationModel.THREE_BUTTON) ==
+                        mDevice.hasObject(By.res(SYSTEMUI_PACKAGE, "recent_apps")));
+        assertTrue("Presence of home button doesn't match the interaction mode",
+                (navigationModel != NavigationModel.ZERO_BUTTON) ==
+                        mDevice.hasObject(By.res(SYSTEMUI_PACKAGE, "home")));
         log("verifyContainerType: " + containerType);
 
         try (Closable c = addContextLayer(