Merge "Adding recents test for 3P Launcher" into ub-launcher3-master

This commit is contained in:
TreeHugger Robot
2019-09-17 21:18:19 +00:00
committed by Android (Google) Code Review
8 changed files with 249 additions and 104 deletions
@@ -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.<RecentsView>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.<RecentsView>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();
}
}
}
@@ -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<RecentsActivity> 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<RecentsActivity> f) throws Exception {
getFromRecents(r -> {
f.accept(r);
return null;
});
}
protected <T> T getFromRecents(Function<RecentsActivity, T> 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.<RecentsView>getOverviewPanel().getCurrentPage();
}
private int getTaskCount(RecentsActivity recents) {
return recents.<RecentsView>getOverviewPanel().getTaskViewCount();
}
}
@@ -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) {
@@ -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<Launcher> {
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<Boolean> 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;
}
}
}
}
@@ -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<T extends Activity> implements TestRule {
private final Class<T> mClass;
private T mActivity;
public SimpleActivityRule(Class<T> 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;
}
}
}
}
@@ -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<UiObject2> 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
@@ -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);
}
@@ -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);
}
}
}