From ed83cf6df020ce983b251751e765f69286164ea9 Mon Sep 17 00:00:00 2001 From: Sunny Goyal Date: Mon, 16 Sep 2019 16:31:19 -0700 Subject: [PATCH] Adding recents test for 3P Launcher Bug: 140749967 Change-Id: I3644822accfd229d1e46ca5e43ad827aef776787 --- .../QuickstepTestInformationHandler.java | 16 ++- .../quickstep/FallbackRecentsTest.java | 119 +++++++++++++++--- .../launcher3/ui/AbstractLauncherUiTest.java | 9 +- .../util/rule/LauncherActivityRule.java | 82 ++---------- .../util/rule/SimpleActivityRule.java | 104 +++++++++++++++ .../android/launcher3/tapl/BaseOverview.java | 10 +- .../tapl/LauncherInstrumentation.java | 4 +- .../com/android/launcher3/tapl/Overview.java | 9 ++ 8 files changed, 249 insertions(+), 104 deletions(-) create mode 100644 tests/src/com/android/launcher3/util/rule/SimpleActivityRule.java diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/QuickstepTestInformationHandler.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/QuickstepTestInformationHandler.java index 72a14b58ed..9a01c546af 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/QuickstepTestInformationHandler.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/QuickstepTestInformationHandler.java @@ -16,7 +16,9 @@ import java.util.concurrent.ExecutionException; public class QuickstepTestInformationHandler extends TestInformationHandler { + private final Context mContext; public QuickstepTestInformationHandler(Context context) { + mContext = context; } @Override @@ -54,7 +56,7 @@ public class QuickstepTestInformationHandler extends TestInformationHandler { case TestProtocol.REQUEST_OVERVIEW_LEFT_GESTURE_MARGIN: { try { final int leftMargin = MAIN_EXECUTOR.submit(() -> - mLauncher.getOverviewPanel().getLeftGestureMargin()).get(); + getRecentsView().getLeftGestureMargin()).get(); response.putInt(TestProtocol.TEST_INFO_RESPONSE_FIELD, leftMargin); } catch (ExecutionException e) { e.printStackTrace(); @@ -67,8 +69,7 @@ public class QuickstepTestInformationHandler extends TestInformationHandler { case TestProtocol.REQUEST_OVERVIEW_RIGHT_GESTURE_MARGIN: { try { final int rightMargin = MAIN_EXECUTOR.submit(() -> - mLauncher.getOverviewPanel().getRightGestureMargin()). - get(); + getRecentsView().getRightGestureMargin()).get(); response.putInt(TestProtocol.TEST_INFO_RESPONSE_FIELD, rightMargin); } catch (ExecutionException e) { e.printStackTrace(); @@ -81,4 +82,13 @@ public class QuickstepTestInformationHandler extends TestInformationHandler { return super.call(method); } + + private RecentsView getRecentsView() { + OverviewComponentObserver observer = new OverviewComponentObserver(mContext); + try { + return observer.getActivityControlHelper().getCreatedActivity().getOverviewPanel(); + } finally { + observer.onDestroy(); + } + } } diff --git a/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java b/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java index e5f949b880..a15fc3e287 100644 --- a/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java +++ b/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java @@ -22,11 +22,18 @@ 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.ui.AbstractLauncherUiTest.DEFAULT_UI_TIMEOUT; import static com.android.launcher3.ui.AbstractLauncherUiTest.resolveSystemApp; +import static com.android.launcher3.ui.AbstractLauncherUiTest.startAppFast; +import static com.android.launcher3.ui.AbstractLauncherUiTest.startTestActivity; +import static com.android.launcher3.ui.TaplTestsLauncher3.getAppPackageName; +import static com.android.launcher3.util.Executors.MAIN_EXECUTOR; import static com.android.launcher3.util.rule.ShellCommandRule.disableHeadsUpNotification; import static com.android.launcher3.util.rule.ShellCommandRule.getLauncherCommand; -import static com.android.quickstep.NavigationModeSwitchRule.Mode.THREE_BUTTON; +import static com.android.quickstep.NavigationModeSwitchRule.Mode.ZERO_BUTTON; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import android.app.Instrumentation; @@ -41,10 +48,16 @@ import androidx.test.uiautomator.By; import androidx.test.uiautomator.UiDevice; import androidx.test.uiautomator.Until; +import com.android.launcher3.Utilities; +import com.android.launcher3.tapl.BaseOverview; import com.android.launcher3.tapl.LauncherInstrumentation; +import com.android.launcher3.tapl.OverviewTask; +import com.android.launcher3.tapl.TestHelpers; import com.android.launcher3.testcomponent.TestCommandReceiver; import com.android.launcher3.util.rule.FailureWatcher; +import com.android.launcher3.util.rule.SimpleActivityRule; import com.android.quickstep.NavigationModeSwitchRule.NavigationModeSwitch; +import com.android.quickstep.views.RecentsView; import org.junit.Rule; import org.junit.Test; @@ -53,11 +66,11 @@ import org.junit.rules.TestRule; import org.junit.runner.RunWith; import org.junit.runners.model.Statement; +import java.util.function.Consumer; +import java.util.function.Function; + @LargeTest @RunWith(AndroidJUnit4.class) -/** - * TODO: Fix fallback when quickstep is enabled - */ public class FallbackRecentsTest { private final UiDevice mDevice; @@ -73,6 +86,11 @@ public class FallbackRecentsTest { @Rule public final TestRule mOrderSensitiveRules; + @Rule + public final SimpleActivityRule mActivityMonitor = + new SimpleActivityRule(RecentsActivity.class); + + public FallbackRecentsTest() throws RemoteException { Instrumentation instrumentation = getInstrumentation(); Context context = instrumentation.getContext(); @@ -80,9 +98,12 @@ public class FallbackRecentsTest { mDevice.setOrientationNatural(); mLauncher = new LauncherInstrumentation(instrumentation); - mOrderSensitiveRules = RuleChain. - outerRule(new NavigationModeSwitchRule(mLauncher)). - around(new FailureWatcher(mDevice)); + if (TestHelpers.isInLauncherProcess()) { + Utilities.enableRunningInTestHarnessForTests(); + } + + mOrderSensitiveRules = RuleChain.outerRule(new NavigationModeSwitchRule(mLauncher)) + .around(new FailureWatcher(mDevice)); mOtherLauncherActivity = context.getPackageManager().queryIntentActivities( getHomeIntentInPackage(context), @@ -105,7 +126,7 @@ public class FallbackRecentsTest { }; } - @NavigationModeSwitch(mode = THREE_BUTTON) + @NavigationModeSwitch @Test public void goToOverviewFromHome() { mDevice.pressHome(); @@ -115,7 +136,7 @@ public class FallbackRecentsTest { mLauncher.getBackground().switchToOverview(); } - @NavigationModeSwitch(mode = THREE_BUTTON) + @NavigationModeSwitch @Test public void goToOverviewFromApp() { startAppFast(resolveSystemApp(Intent.CATEGORY_APP_CALCULATOR)); @@ -123,15 +144,77 @@ public class FallbackRecentsTest { mLauncher.getBackground().switchToOverview(); } - private void startAppFast(String packageName) { - final Instrumentation instrumentation = getInstrumentation(); - final Intent intent = instrumentation.getContext().getPackageManager(). - getLaunchIntentForPackage(packageName); - intent.addCategory(Intent.CATEGORY_LAUNCHER); - intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - instrumentation.getTargetContext().startActivity(intent); - assertTrue(packageName + " didn't start", - mDevice.wait(Until.hasObject(By.pkg(packageName).depth(0)), WAIT_TIME_MS)); + protected void executeOnRecents(Consumer f) throws Exception { + getFromRecents(r -> { + f.accept(r); + return null; + }); } + protected T getFromRecents(Function f) throws Exception { + if (!TestHelpers.isInLauncherProcess()) return null; + return MAIN_EXECUTOR.submit(() -> f.apply(mActivityMonitor.getActivity())).get(); + } + + private BaseOverview pressHomeAndGoToOverview() { + mDevice.pressHome(); + return mLauncher.getBackground().switchToOverview(); + } + + // TODO: Enable all modes after b/141184247 is fixed + @NavigationModeSwitch(mode = ZERO_BUTTON) + @Test + public void testOverview() throws Exception { + startAppFast(getAppPackageName()); + startAppFast(resolveSystemApp(Intent.CATEGORY_APP_CALCULATOR)); + startTestActivity(2); + + BaseOverview overview = mLauncher.getBackground().switchToOverview(); + executeOnRecents( + recents -> assertTrue("Don't have at least 3 tasks", getTaskCount(recents) >= 3)); + + // Test flinging forward and backward. + overview.flingForward(); + final Integer currentTaskAfterFlingForward = getFromRecents(this::getCurrentOverviewPage); + executeOnRecents(recents -> assertTrue("Current task in Overview is still 0", + currentTaskAfterFlingForward > 0)); + + overview.flingBackward(); + executeOnRecents(recents -> assertTrue("Flinging back in Overview did nothing", + getCurrentOverviewPage(recents) < currentTaskAfterFlingForward)); + + // Test opening a task. + overview = pressHomeAndGoToOverview(); + + OverviewTask task = overview.getCurrentTask(); + assertNotNull("overview.getCurrentTask() returned null (1)", task); + assertNotNull("OverviewTask.open returned null", task.open()); + assertTrue("Test activity didn't open from Overview", mDevice.wait(Until.hasObject( + By.pkg(getAppPackageName()).text("TestActivity2")), + DEFAULT_UI_TIMEOUT)); + + + // Test dismissing a task. + overview = pressHomeAndGoToOverview(); + final Integer numTasks = getFromRecents(this::getTaskCount); + task = overview.getCurrentTask(); + assertNotNull("overview.getCurrentTask() returned null (2)", task); + task.dismiss(); + executeOnRecents( + recents -> assertEquals("Dismissing a task didn't remove 1 task from Overview", + numTasks - 1, getTaskCount(recents))); + + // Test dismissing all tasks. + pressHomeAndGoToOverview().dismissAllTasks(); + assertTrue("Fallback Launcher not visible", mDevice.wait(Until.hasObject(By.pkg( + mOtherLauncherActivity.packageName)), WAIT_TIME_MS)); + } + + private int getCurrentOverviewPage(RecentsActivity recents) { + return recents.getOverviewPanel().getCurrentPage(); + } + + private int getTaskCount(RecentsActivity recents) { + return recents.getOverviewPanel().getTaskViewCount(); + } } diff --git a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java index ed5f299837..6bc87c9044 100644 --- a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java +++ b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java @@ -345,14 +345,14 @@ public abstract class AbstractLauncherUiTest { } } - protected void startAppFast(String packageName) { + public static void startAppFast(String packageName) { startIntent( getInstrumentation().getContext().getPackageManager().getLaunchIntentForPackage( packageName), By.pkg(packageName).depth(0)); } - protected void startTestActivity(int activityNumber) { + public static void startTestActivity(int activityNumber) { final String packageName = getAppPackageName(); final Intent intent = getInstrumentation().getContext().getPackageManager(). getLaunchIntentForPackage(packageName); @@ -361,12 +361,13 @@ public abstract class AbstractLauncherUiTest { startIntent(intent, By.pkg(packageName).text("TestActivity" + activityNumber)); } - private void startIntent(Intent intent, BySelector selector) { + private static void startIntent(Intent intent, BySelector selector) { intent.addCategory(Intent.CATEGORY_LAUNCHER); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); getInstrumentation().getTargetContext().startActivity(intent); assertTrue("App didn't start: " + selector, - mDevice.wait(Until.hasObject(selector), DEFAULT_UI_TIMEOUT)); + UiDevice.getInstance(getInstrumentation()) + .wait(Until.hasObject(selector), DEFAULT_UI_TIMEOUT)); } public static ActivityInfo resolveSystemAppInfo(String category) { diff --git a/tests/src/com/android/launcher3/util/rule/LauncherActivityRule.java b/tests/src/com/android/launcher3/util/rule/LauncherActivityRule.java index 62fe26d13b..6a6ec3e41d 100644 --- a/tests/src/com/android/launcher3/util/rule/LauncherActivityRule.java +++ b/tests/src/com/android/launcher3/util/rule/LauncherActivityRule.java @@ -16,16 +16,10 @@ package com.android.launcher3.util.rule; import android.app.Activity; -import android.app.Application; -import android.app.Application.ActivityLifecycleCallbacks; -import android.os.Bundle; - -import androidx.test.InstrumentationRegistry; import com.android.launcher3.Launcher; import com.android.launcher3.Workspace.ItemOperator; -import org.junit.rules.TestRule; import org.junit.runner.Description; import org.junit.runners.model.Statement; @@ -34,17 +28,23 @@ import java.util.concurrent.Callable; /** * Test rule to get the current Launcher activity. */ -public class LauncherActivityRule implements TestRule { +public class LauncherActivityRule extends SimpleActivityRule { - private Launcher mActivity; + public LauncherActivityRule() { + super(Launcher.class); + } @Override public Statement apply(Statement base, Description description) { - return new MyStatement(base); - } - public Launcher getActivity() { - return mActivity; + return new MyStatement(base) { + @Override + public void onActivityStarted(Activity activity) { + if (activity instanceof Launcher) { + ((Launcher) activity).getRotationHelper().forceAllowRotationForTesting(true); + } + } + }; } public Callable itemExists(final ItemOperator op) { @@ -56,62 +56,4 @@ public class LauncherActivityRule implements TestRule { return launcher.getWorkspace().getFirstMatch(op) != null; }; } - - private class MyStatement extends Statement implements ActivityLifecycleCallbacks { - - private final Statement mBase; - - public MyStatement(Statement base) { - mBase = base; - } - - @Override - public void evaluate() throws Throwable { - Application app = (Application) - InstrumentationRegistry.getTargetContext().getApplicationContext(); - app.registerActivityLifecycleCallbacks(this); - try { - mBase.evaluate(); - } finally { - app.unregisterActivityLifecycleCallbacks(this); - } - } - - @Override - public void onActivityCreated(Activity activity, Bundle bundle) { - if (activity instanceof Launcher) { - mActivity = (Launcher) activity; - } - } - - @Override - public void onActivityStarted(Activity activity) { - if (activity instanceof Launcher) { - mActivity.getRotationHelper().forceAllowRotationForTesting(true); - } - } - - @Override - public void onActivityResumed(Activity activity) { - } - - @Override - public void onActivityPaused(Activity activity) { - } - - @Override - public void onActivityStopped(Activity activity) { - } - - @Override - public void onActivitySaveInstanceState(Activity activity, Bundle bundle) { - } - - @Override - public void onActivityDestroyed(Activity activity) { - if (activity == mActivity) { - mActivity = null; - } - } - } } diff --git a/tests/src/com/android/launcher3/util/rule/SimpleActivityRule.java b/tests/src/com/android/launcher3/util/rule/SimpleActivityRule.java new file mode 100644 index 0000000000..33a6cf9766 --- /dev/null +++ b/tests/src/com/android/launcher3/util/rule/SimpleActivityRule.java @@ -0,0 +1,104 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.android.launcher3.util.rule; + +import android.app.Activity; +import android.app.Application; +import android.app.Application.ActivityLifecycleCallbacks; +import android.os.Bundle; + +import androidx.test.InstrumentationRegistry; + +import org.junit.rules.TestRule; +import org.junit.runner.Description; +import org.junit.runners.model.Statement; + +/** + * Test rule to get the current activity. + */ +public class SimpleActivityRule implements TestRule { + + private final Class mClass; + private T mActivity; + + public SimpleActivityRule(Class clazz) { + mClass = clazz; + } + + @Override + public Statement apply(Statement base, Description description) { + return new MyStatement(base); + } + + public T getActivity() { + return mActivity; + } + + protected class MyStatement extends Statement implements ActivityLifecycleCallbacks { + + private final Statement mBase; + + public MyStatement(Statement base) { + mBase = base; + } + + @Override + public void evaluate() throws Throwable { + Application app = (Application) + InstrumentationRegistry.getTargetContext().getApplicationContext(); + app.registerActivityLifecycleCallbacks(this); + try { + mBase.evaluate(); + } finally { + app.unregisterActivityLifecycleCallbacks(this); + } + } + + @Override + public void onActivityCreated(Activity activity, Bundle bundle) { + if (activity != null && mClass.isInstance(activity)) { + mActivity = (T) activity; + } + } + + @Override + public void onActivityStarted(Activity activity) { + } + + @Override + public void onActivityResumed(Activity activity) { + } + + @Override + public void onActivityPaused(Activity activity) { + } + + @Override + public void onActivityStopped(Activity activity) { + } + + @Override + public void onActivitySaveInstanceState(Activity activity, Bundle bundle) { + } + + @Override + public void onActivityDestroyed(Activity activity) { + if (activity == mActivity) { + mActivity = null; + } + } + } +} diff --git a/tests/tapl/com/android/launcher3/tapl/BaseOverview.java b/tests/tapl/com/android/launcher3/tapl/BaseOverview.java index 25e6e8c8f7..eaa21aeebf 100644 --- a/tests/tapl/com/android/launcher3/tapl/BaseOverview.java +++ b/tests/tapl/com/android/launcher3/tapl/BaseOverview.java @@ -63,10 +63,10 @@ public class BaseOverview extends LauncherInstrumentation.VisibleContainer { /** * Dismissed all tasks by scrolling to Clear-all button and pressing it. */ - public Workspace dismissAllTasks() { + public void dismissAllTasks() { try (LauncherInstrumentation.Closable c = mLauncher.addContextLayer( "dismissing all tasks")) { - final BySelector clearAllSelector = mLauncher.getLauncherObjectSelector("clear_all"); + final BySelector clearAllSelector = mLauncher.getOverviewObjectSelector("clear_all"); for (int i = 0; i < FLINGS_FOR_DISMISS_LIMIT && !verifyActiveContainer().hasObject(clearAllSelector); @@ -75,10 +75,6 @@ public class BaseOverview extends LauncherInstrumentation.VisibleContainer { } mLauncher.waitForObjectInContainer(verifyActiveContainer(), clearAllSelector).click(); - try (LauncherInstrumentation.Closable c1 = mLauncher.addContextLayer( - "dismissed all tasks")) { - return new Workspace(mLauncher); - } } } @@ -109,7 +105,7 @@ public class BaseOverview extends LauncherInstrumentation.VisibleContainer { "want to get current task")) { verifyActiveContainer(); final List taskViews = mLauncher.getDevice().findObjects( - mLauncher.getLauncherObjectSelector("snapshot")); + mLauncher.getOverviewObjectSelector("snapshot")); mLauncher.assertNotEquals("Unable to find a task", 0, taskViews.size()); // taskViews contains up to 3 task views: the 'main' (having the widest visible diff --git a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java index 15615fc6b6..383c3cef31 100644 --- a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java +++ b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java @@ -725,7 +725,7 @@ public final class LauncherInstrumentation { @NonNull UiObject2 waitForFallbackLauncherObject(String resName) { - return waitForObjectBySelector(getFallbackLauncherObjectSelector(resName)); + return waitForObjectBySelector(getOverviewObjectSelector(resName)); } private UiObject2 waitForObjectBySelector(BySelector selector) { @@ -742,7 +742,7 @@ public final class LauncherInstrumentation { return By.res(getLauncherPackageName(), resName); } - BySelector getFallbackLauncherObjectSelector(String resName) { + BySelector getOverviewObjectSelector(String resName) { return By.res(getOverviewPackageName(), resName); } diff --git a/tests/tapl/com/android/launcher3/tapl/Overview.java b/tests/tapl/com/android/launcher3/tapl/Overview.java index da68da3ba6..4f8aeb1123 100644 --- a/tests/tapl/com/android/launcher3/tapl/Overview.java +++ b/tests/tapl/com/android/launcher3/tapl/Overview.java @@ -67,4 +67,13 @@ public final class Overview extends BaseOverview { } } } + + @Override + public void dismissAllTasks() { + super.dismissAllTasks(); + try (LauncherInstrumentation.Closable c1 = mLauncher.addContextLayer( + "dismissed all tasks")) { + new Workspace(mLauncher); + } + } }