update:2021.03.19

fix:重新提交
add:
This commit is contained in:
FHT
2021-03-19 18:19:49 +08:00
parent d4399ffa61
commit d23777e680
1191 changed files with 149106 additions and 0 deletions

1
quickstep/tests/OWNERS Normal file
View File

@@ -0,0 +1 @@
vadimt@google.com

View File

@@ -0,0 +1,34 @@
/*
* Copyright (C) 2018 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.quickstep;
import com.android.uiuios.ui.AbstractLauncherUiTest;
import org.junit.rules.RuleChain;
import org.junit.rules.TestRule;
/**
* Base class for all instrumentation tests that deal with Quickstep.
*/
public abstract class AbstractQuickStepTest extends AbstractLauncherUiTest {
@Override
protected TestRule getRulesInsideActivityMonitor() {
return RuleChain.
outerRule(new NavigationModeSwitchRule(mLauncher)).
around(super.getRulesInsideActivityMonitor());
}
}

View File

@@ -0,0 +1,163 @@
/**
* 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.quickstep;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import android.app.prediction.AppPredictor;
import android.app.prediction.AppTarget;
import android.app.prediction.AppTargetId;
import android.content.ComponentName;
import android.content.pm.LauncherActivityInfo;
import android.os.Process;
import android.view.View;
import androidx.test.filters.LargeTest;
import androidx.test.runner.AndroidJUnit4;
import com.android.uiuios.BubbleTextView;
import com.android.uiuios.Launcher;
import com.android.uiuios.appprediction.PredictionRowView;
import com.android.uiuios.appprediction.PredictionUiStateManager;
import com.android.uiuios.appprediction.PredictionUiStateManager.Client;
import com.android.uiuios.compat.LauncherAppsCompat;
import com.android.uiuios.model.AppLaunchTracker;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.util.ArrayList;
import java.util.List;
@LargeTest
@RunWith(AndroidJUnit4.class)
public class AppPredictionsUITests extends AbstractQuickStepTest {
private LauncherActivityInfo mSampleApp1;
private LauncherActivityInfo mSampleApp2;
private LauncherActivityInfo mSampleApp3;
private AppPredictor.Callback mCallback;
@Before
public void setUp() throws Exception {
super.setUp();
List<LauncherActivityInfo> activities = LauncherAppsCompat.getInstance(mTargetContext)
.getActivityList(null, Process.myUserHandle());
mSampleApp1 = activities.get(0);
mSampleApp2 = activities.get(1);
mSampleApp3 = activities.get(2);
// Disable app tracker
AppLaunchTracker.INSTANCE.initializeForTesting(new AppLaunchTracker());
PredictionUiStateManager.INSTANCE.initializeForTesting(null);
mCallback = PredictionUiStateManager.INSTANCE.get(mTargetContext).appPredictorCallback(
Client.HOME);
mDevice.setOrientationNatural();
}
@After
public void tearDown() throws Throwable {
AppLaunchTracker.INSTANCE.initializeForTesting(null);
PredictionUiStateManager.INSTANCE.initializeForTesting(null);
mDevice.unfreezeRotation();
}
/**
* Test that prediction UI is updated as soon as we get predictions from the system
*/
@Test
public void testPredictionExistsInAllApps() {
mActivityMonitor.startLauncher();
mLauncher.pressHome().switchToAllApps();
// Dispatch an update
sendPredictionUpdate(mSampleApp1, mSampleApp2);
// The first update should apply immediately.
waitForLauncherCondition("Predictions were not updated in loading state",
launcher -> getPredictedApp(launcher).size() == 2);
}
/**
* Test that prediction update is deferred if it is already visible
*/
@Test
public void testPredictionsDeferredUntilHome() {
mActivityMonitor.startLauncher();
sendPredictionUpdate(mSampleApp1, mSampleApp2);
mLauncher.pressHome().switchToAllApps();
waitForLauncherCondition("Predictions were not updated in loading state",
launcher -> getPredictedApp(launcher).size() == 2);
// Update predictions while all-apps is visible
sendPredictionUpdate(mSampleApp1, mSampleApp2, mSampleApp3);
assertEquals(2, getFromLauncher(this::getPredictedApp).size());
// Go home and go back to all-apps
mLauncher.pressHome().switchToAllApps();
assertEquals(3, getFromLauncher(this::getPredictedApp).size());
}
@Test
public void testPredictionsDisabled() {
mActivityMonitor.startLauncher();
sendPredictionUpdate();
mLauncher.pressHome().switchToAllApps();
waitForLauncherCondition("Predictions were not updated in loading state",
launcher -> launcher.getAppsView().getFloatingHeaderView()
.findFixedRowByType(PredictionRowView.class).getVisibility() == View.GONE);
assertFalse(PredictionUiStateManager.INSTANCE.get(mTargetContext)
.getCurrentState().isEnabled);
}
public ArrayList<BubbleTextView> getPredictedApp(Launcher launcher) {
PredictionRowView container = launcher.getAppsView().getFloatingHeaderView()
.findFixedRowByType(PredictionRowView.class);
ArrayList<BubbleTextView> predictedAppViews = new ArrayList<>();
for (int i = 0; i < container.getChildCount(); i++) {
View view = container.getChildAt(i);
if (view instanceof BubbleTextView && view.getVisibility() == View.VISIBLE) {
predictedAppViews.add((BubbleTextView) view);
}
}
return predictedAppViews;
}
private void sendPredictionUpdate(LauncherActivityInfo... activities) {
getOnUiThread(() -> {
List<AppTarget> targets = new ArrayList<>(activities.length);
for (LauncherActivityInfo info : activities) {
ComponentName cn = info.getComponentName();
AppTarget target =
new AppTarget.Builder(new AppTargetId("app:" + cn), cn.getPackageName(), info.getUser())
.setClassName(cn.getClassName())
.build();
targets.add(target);
}
mCallback.onTargetsAvailable(targets);
return null;
});
}
}

View File

@@ -0,0 +1,95 @@
package com.android.quickstep;
import static androidx.test.InstrumentationRegistry.getInstrumentation;
import static com.android.uiuios.LauncherState.OVERVIEW;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import android.app.PendingIntent;
import android.app.usage.UsageStatsManager;
import android.content.Intent;
import androidx.test.filters.LargeTest;
import androidx.test.runner.AndroidJUnit4;
import com.android.uiuios.Launcher;
import com.android.quickstep.views.DigitalWellBeingToast;
import com.android.quickstep.views.RecentsView;
import com.android.quickstep.views.TaskView;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.time.Duration;
@LargeTest
@RunWith(AndroidJUnit4.class)
public class DigitalWellBeingToastTest extends AbstractQuickStepTest {
private static final String CALCULATOR_PACKAGE =
resolveSystemApp(Intent.CATEGORY_APP_CALCULATOR);
@Test
public void testToast() throws Exception {
startAppFast(CALCULATOR_PACKAGE);
final UsageStatsManager usageStatsManager =
mTargetContext.getSystemService(UsageStatsManager.class);
final int observerId = 0;
try {
final String[] packages = new String[]{CALCULATOR_PACKAGE};
// Set time limit for app.
runWithShellPermission(() ->
usageStatsManager.registerAppUsageLimitObserver(observerId, packages,
Duration.ofSeconds(600), Duration.ofSeconds(300),
PendingIntent.getActivity(mTargetContext, -1, new Intent(), 0)));
mLauncher.pressHome();
final DigitalWellBeingToast toast = getToast();
assertTrue("Toast is not visible", toast.hasLimit());
assertEquals("Toast text: ", "5 minutes left today", toast.getText());
// Unset time limit for app.
runWithShellPermission(
() -> usageStatsManager.unregisterAppUsageLimitObserver(observerId));
mLauncher.pressHome();
assertFalse("Toast is visible", getToast().hasLimit());
} finally {
runWithShellPermission(
() -> usageStatsManager.unregisterAppUsageLimitObserver(observerId));
}
}
private DigitalWellBeingToast getToast() {
executeOnLauncher(launcher -> launcher.getStateManager().goToState(OVERVIEW));
waitForState("Launcher internal state didn't switch to Overview", OVERVIEW);
waitForLauncherCondition("No latest task", launcher -> getLatestTask(launcher) != null);
return getFromLauncher(launcher -> {
final TaskView task = getLatestTask(launcher);
assertTrue("Latest task is not Calculator",
CALCULATOR_PACKAGE.equals(task.getTask().getTopComponent().getPackageName()));
return task.getDigitalWellBeingToast();
});
}
private TaskView getLatestTask(Launcher launcher) {
return launcher.<RecentsView>getOverviewPanel().getTaskViewAt(0);
}
private void runWithShellPermission(Runnable action) {
getInstrumentation().getUiAutomation().adoptShellPermissionIdentity();
try {
action.run();
} finally {
getInstrumentation().getUiAutomation().dropShellPermissionIdentity();
}
}
}

View File

@@ -0,0 +1,137 @@
/*
* Copyright (C) 2018 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.quickstep;
import static android.content.pm.PackageManager.MATCH_DISABLED_COMPONENTS;
import static androidx.test.InstrumentationRegistry.getInstrumentation;
import static com.android.uiuios.tapl.LauncherInstrumentation.WAIT_TIME_MS;
import static com.android.uiuios.tapl.TestHelpers.getHomeIntentInPackage;
import static com.android.uiuios.tapl.TestHelpers.getLauncherInMyProcess;
import static com.android.uiuios.ui.AbstractLauncherUiTest.resolveSystemApp;
import static com.android.uiuios.util.rule.ShellCommandRule.disableHeadsUpNotification;
import static com.android.uiuios.util.rule.ShellCommandRule.getLauncherCommand;
import static com.android.quickstep.NavigationModeSwitchRule.Mode.THREE_BUTTON;
import static org.junit.Assert.assertTrue;
import android.app.Instrumentation;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.os.RemoteException;
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.uiuios.tapl.LauncherInstrumentation;
import com.android.uiuios.testcomponent.TestCommandReceiver;
import com.android.uiuios.util.rule.FailureWatcher;
import com.android.quickstep.NavigationModeSwitchRule.NavigationModeSwitch;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.RuleChain;
import org.junit.rules.TestRule;
import org.junit.runner.RunWith;
import org.junit.runners.model.Statement;
@LargeTest
@RunWith(AndroidJUnit4.class)
/**
* TODO: Fix fallback when quickstep is enabled
*/
public class FallbackRecentsTest {
private final UiDevice mDevice;
private final LauncherInstrumentation mLauncher;
private final ActivityInfo mOtherLauncherActivity;
@Rule
public final TestRule mDisableHeadsUpNotification = disableHeadsUpNotification();
@Rule
public final TestRule mSetLauncherCommand;
@Rule
public final TestRule mOrderSensitiveRules;
public FallbackRecentsTest() throws RemoteException {
Instrumentation instrumentation = getInstrumentation();
Context context = instrumentation.getContext();
mDevice = UiDevice.getInstance(instrumentation);
mDevice.setOrientationNatural();
mLauncher = new LauncherInstrumentation(instrumentation);
mOrderSensitiveRules = RuleChain.
outerRule(new NavigationModeSwitchRule(mLauncher)).
around(new FailureWatcher(mDevice));
mOtherLauncherActivity = context.getPackageManager().queryIntentActivities(
getHomeIntentInPackage(context),
MATCH_DISABLED_COMPONENTS).get(0).activityInfo;
mSetLauncherCommand = (base, desc) -> new Statement() {
@Override
public void evaluate() throws Throwable {
TestCommandReceiver.callCommand(TestCommandReceiver.ENABLE_TEST_LAUNCHER);
UiDevice.getInstance(getInstrumentation()).executeShellCommand(
getLauncherCommand(mOtherLauncherActivity));
try {
base.evaluate();
} finally {
TestCommandReceiver.callCommand(TestCommandReceiver.DISABLE_TEST_LAUNCHER);
UiDevice.getInstance(getInstrumentation()).executeShellCommand(
getLauncherCommand(getLauncherInMyProcess()));
}
}
};
}
@NavigationModeSwitch(mode = THREE_BUTTON)
@Test
public void goToOverviewFromHome() {
mDevice.pressHome();
assertTrue("Fallback Launcher not visible", mDevice.wait(Until.hasObject(By.pkg(
mOtherLauncherActivity.packageName)), WAIT_TIME_MS));
mLauncher.getBackground().switchToOverview();
}
@NavigationModeSwitch(mode = THREE_BUTTON)
@Test
public void goToOverviewFromApp() {
startAppFast(resolveSystemApp(Intent.CATEGORY_APP_CALCULATOR));
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));
}
}

View File

@@ -0,0 +1,198 @@
/*
* Copyright (C) 2018 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.quickstep;
import static androidx.test.InstrumentationRegistry.getInstrumentation;
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.quickstep.NavigationModeSwitchRule.Mode.ZERO_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;
import android.content.Context;
import android.util.Log;
import androidx.test.uiautomator.UiDevice;
import com.android.uiuios.tapl.LauncherInstrumentation;
import com.android.uiuios.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.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
/**
* Test rule that allows executing a test with Quickstep on and then Quickstep off.
* The test should be annotated with @QuickstepOnOff.
*/
public class NavigationModeSwitchRule implements TestRule {
static final String TAG = "QuickStepOnOffRule";
public enum Mode {
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 NavigationModeSwitch {
Mode mode() default ALL;
}
private final LauncherInstrumentation mLauncher;
public NavigationModeSwitchRule(LauncherInstrumentation launcher) {
mLauncher = launcher;
}
@Override
public Statement apply(Statement base, Description description) {
if (TestHelpers.isInLauncherProcess() &&
description.getAnnotation(NavigationModeSwitch.class) != null) {
Mode mode = description.getAnnotation(NavigationModeSwitch.class).mode();
return new Statement() {
@Override
public void evaluate() throws Throwable {
final Context context = getInstrumentation().getContext();
final int currentInteractionMode =
LauncherInstrumentation.getCurrentInteractionMode(context);
final String prevOverlayPkg =
QuickStepContract.isGesturalMode(currentInteractionMode)
? NAV_BAR_MODE_GESTURAL_OVERLAY
: QuickStepContract.isSwipeUpMode(currentInteractionMode)
? NAV_BAR_MODE_2BUTTON_OVERLAY
: NAV_BAR_MODE_3BUTTON_OVERLAY;
final LauncherInstrumentation.NavigationModel originalMode =
mLauncher.getNavigationModel();
try {
if (mode == ZERO_BUTTON || mode == ALL) {
evaluateWithZeroButtons();
}
if (mode == TWO_BUTTON || mode == ALL) {
evaluateWithTwoButtons();
}
if (mode == THREE_BUTTON || mode == ALL) {
evaluateWithThreeButtons();
}
} finally {
setActiveOverlay(prevOverlayPkg, originalMode);
}
}
public void evaluateWithoutChangingSetting(Statement base) throws Throwable {
base.evaluate();
}
private void evaluateWithThreeButtons() throws Throwable {
setActiveOverlay(NAV_BAR_MODE_3BUTTON_OVERLAY,
LauncherInstrumentation.NavigationModel.THREE_BUTTON);
evaluateWithoutChangingSetting(base);
}
private void evaluateWithTwoButtons() throws Throwable {
setActiveOverlay(NAV_BAR_MODE_2BUTTON_OVERLAY,
LauncherInstrumentation.NavigationModel.TWO_BUTTON);
base.evaluate();
}
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,
overlayPackage == NAV_BAR_MODE_2BUTTON_OVERLAY);
setOverlayPackageEnabled(NAV_BAR_MODE_GESTURAL_OVERLAY,
overlayPackage == NAV_BAR_MODE_GESTURAL_OVERLAY);
if (currentSysUiNavigationMode() != expectedMode) {
final CountDownLatch latch = new CountDownLatch(1);
final Context targetContext = getInstrumentation().getTargetContext();
final SysUINavigationMode.NavigationModeChangeListener listener =
newMode -> {
if (LauncherInstrumentation.getNavigationModel(newMode.resValue)
== expectedMode) {
latch.countDown();
}
};
final SysUINavigationMode sysUINavigationMode =
SysUINavigationMode.INSTANCE.get(targetContext);
targetContext.getMainExecutor().execute(() ->
sysUINavigationMode.addModeChangeListener(listener));
latch.await(10, TimeUnit.SECONDS);
targetContext.getMainExecutor().execute(() ->
sysUINavigationMode.removeModeChangeListener(listener));
Assert.assertTrue("Navigation mode didn't change to " + expectedMode,
currentSysUiNavigationMode() == expectedMode);
}
for (int i = 0; i != 100; ++i) {
if (mLauncher.getNavigationModel() == expectedMode) break;
Thread.sleep(100);
}
Assert.assertTrue("Couldn't switch to " + overlayPackage,
mLauncher.getNavigationModel() == expectedMode);
for (int i = 0; i != 100; ++i) {
if (mLauncher.getNavigationModeMismatchError() == null) break;
Thread.sleep(100);
}
final String error = mLauncher.getNavigationModeMismatchError();
Assert.assertTrue("Switching nav mode: " + error, error == null);
Thread.sleep(5000);
}
private void setOverlayPackageEnabled(String overlayPackage, boolean enable)
throws Exception {
Log.d(TAG, "setOverlayPackageEnabled: " + overlayPackage + " " + enable);
final String action = enable ? "enable" : "disable";
UiDevice.getInstance(getInstrumentation()).executeShellCommand(
"cmd overlay " + action + " " + overlayPackage);
}
};
} else {
return base;
}
}
private static LauncherInstrumentation.NavigationModel currentSysUiNavigationMode() {
return LauncherInstrumentation.getNavigationModel(
SysUINavigationMode.getMode(
getInstrumentation().
getTargetContext()).
resValue);
}
}

View File

@@ -0,0 +1,102 @@
/*
* Copyright (C) 2018 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.quickstep;
import static com.android.uiuios.util.RaceConditionTracker.enterEvt;
import static com.android.uiuios.util.RaceConditionTracker.exitEvt;
import android.content.Intent;
import androidx.test.filters.LargeTest;
import androidx.test.runner.AndroidJUnit4;
import com.android.uiuios.Launcher;
import com.android.uiuios.util.RaceConditionReproducer;
import com.android.quickstep.NavigationModeSwitchRule.Mode;
import com.android.quickstep.NavigationModeSwitchRule.NavigationModeSwitch;
import com.android.quickstep.inputconsumers.OtherActivityInputConsumer;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
@LargeTest
@RunWith(AndroidJUnit4.class)
public class StartLauncherViaGestureTests extends AbstractQuickStepTest {
static final int STRESS_REPEAT_COUNT = 10;
@Override
@Before
public void setUp() throws Exception {
super.setUp();
// Start an activity where the gestures start.
startAppFast(resolveSystemApp(Intent.CATEGORY_APP_CALCULATOR));
}
private void runTest(String... eventSequence) {
final RaceConditionReproducer eventProcessor = new RaceConditionReproducer(eventSequence);
// Destroy Launcher activity.
closeLauncherActivity();
// The test action.
eventProcessor.startIteration();
mLauncher.pressHome();
eventProcessor.finishIteration();
}
@Test
@Ignore // Ignoring until race condition repro framework is changes for multi-process case.
@NavigationModeSwitch(mode = Mode.TWO_BUTTON)
public void testPressHome() {
runTest(enterEvt(Launcher.ON_CREATE_EVT),
exitEvt(Launcher.ON_CREATE_EVT),
enterEvt(OtherActivityInputConsumer.DOWN_EVT),
exitEvt(OtherActivityInputConsumer.DOWN_EVT));
runTest(enterEvt(OtherActivityInputConsumer.DOWN_EVT),
exitEvt(OtherActivityInputConsumer.DOWN_EVT),
enterEvt(Launcher.ON_CREATE_EVT),
exitEvt(Launcher.ON_CREATE_EVT));
}
@Test
@NavigationModeSwitch
public void testStressPressHome() {
for (int i = 0; i < STRESS_REPEAT_COUNT; ++i) {
// Destroy Launcher activity.
closeLauncherActivity();
// The test action.
mLauncher.pressHome();
}
}
@Test
@NavigationModeSwitch
public void testStressSwipeToOverview() {
for (int i = 0; i < STRESS_REPEAT_COUNT; ++i) {
// Destroy Launcher activity.
closeLauncherActivity();
// The test action.
mLauncher.getBackground().switchToOverview();
}
}
}

View File

@@ -0,0 +1,241 @@
/*
* Copyright (C) 2018 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.quickstep;
import static com.android.uiuios.ui.TaplTestsLauncher3.getAppPackageName;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import android.content.Intent;
import android.os.RemoteException;
import androidx.test.filters.LargeTest;
import androidx.test.runner.AndroidJUnit4;
import androidx.test.uiautomator.By;
import androidx.test.uiautomator.Until;
import com.android.uiuios.Launcher;
import com.android.uiuios.LauncherState;
import com.android.uiuios.tapl.AllApps;
import com.android.uiuios.tapl.AllAppsFromOverview;
import com.android.uiuios.tapl.Background;
import com.android.uiuios.tapl.Overview;
import com.android.uiuios.tapl.OverviewTask;
import com.android.uiuios.tapl.TestHelpers;
import com.android.uiuios.ui.TaplTestsLauncher3;
import com.android.quickstep.NavigationModeSwitchRule.NavigationModeSwitch;
import com.android.quickstep.views.RecentsView;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
@LargeTest
@RunWith(AndroidJUnit4.class)
public class TaplTestsQuickstep extends AbstractQuickStepTest {
@Before
public void setUp() throws Exception {
super.setUp();
TaplTestsLauncher3.initialize(this);
}
private void startTestApps() throws Exception {
startAppFast(getAppPackageName());
startAppFast(resolveSystemApp(Intent.CATEGORY_APP_CALCULATOR));
startTestActivity(2);
executeOnLauncher(launcher -> assertTrue(
"Launcher activity is the top activity; expecting another activity to be the top "
+ "one",
isInBackground(launcher)));
}
@Test
@PortraitLandscape
@Ignore // Enable after b/131115533
public void testPressRecentAppsLauncherAndGetOverview() throws RemoteException {
mDevice.pressRecentApps();
waitForState("Launcher internal state didn't switch to Overview", LauncherState.OVERVIEW);
assertNotNull("getOverview() returned null", mLauncher.getOverview());
}
@Test
@NavigationModeSwitch
@PortraitLandscape
public void testWorkspaceSwitchToAllApps() {
assertNotNull("switchToAllApps() returned null",
mLauncher.getWorkspace().switchToAllApps());
assertTrue("Launcher internal state is not All Apps", isInState(LauncherState.ALL_APPS));
}
@Test
public void testAllAppsFromOverview() throws Exception {
// Test opening all apps from Overview.
assertNotNull("switchToAllApps() returned null",
mLauncher.getWorkspace().switchToOverview().switchToAllApps());
TaplTestsLauncher3.runAllAppsTest(this, mLauncher.getAllAppsFromOverview());
}
@Test
@PortraitLandscape
public void testOverview() throws Exception {
startTestApps();
Overview overview = mLauncher.pressHome().switchToOverview();
assertTrue("Launcher internal state didn't switch to Overview",
isInState(LauncherState.OVERVIEW));
executeOnLauncher(
launcher -> assertTrue("Don't have at least 3 tasks", getTaskCount(launcher) >= 3));
// Test flinging forward and backward.
executeOnLauncher(launcher -> assertEquals("Current task in Overview is not 0",
0, getCurrentOverviewPage(launcher)));
overview.flingForward();
assertTrue("Launcher internal state is not Overview", isInState(LauncherState.OVERVIEW));
final Integer currentTaskAfterFlingForward = getFromLauncher(
launcher -> getCurrentOverviewPage(launcher));
executeOnLauncher(launcher -> assertTrue("Current task in Overview is still 0",
currentTaskAfterFlingForward > 0));
overview.flingBackward();
assertTrue("Launcher internal state is not Overview", isInState(LauncherState.OVERVIEW));
executeOnLauncher(launcher -> assertTrue("Flinging back in Overview did nothing",
getCurrentOverviewPage(launcher) < currentTaskAfterFlingForward));
// Test opening a task.
OverviewTask task = mLauncher.pressHome().switchToOverview().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));
executeOnLauncher(launcher -> assertTrue(
"Launcher activity is the top activity; expecting another activity to be the top "
+ "one",
isInBackground(launcher)));
// Test dismissing a task.
overview = mLauncher.pressHome().switchToOverview();
assertTrue("Launcher internal state didn't switch to Overview",
isInState(LauncherState.OVERVIEW));
final Integer numTasks = getFromLauncher(launcher -> getTaskCount(launcher));
task = overview.getCurrentTask();
assertNotNull("overview.getCurrentTask() returned null (2)", task);
task.dismiss();
executeOnLauncher(
launcher -> assertEquals("Dismissing a task didn't remove 1 task from Overview",
numTasks - 1, getTaskCount(launcher)));
if (!TestHelpers.isInLauncherProcess() ||
getFromLauncher(launcher -> !launcher.getDeviceProfile().isLandscape)) {
// Test switching to all apps and back.
final AllAppsFromOverview allApps = overview.switchToAllApps();
assertNotNull("overview.switchToAllApps() returned null (1)", allApps);
assertTrue("Launcher internal state is not All Apps (1)",
isInState(LauncherState.ALL_APPS));
overview = allApps.switchBackToOverview();
assertNotNull("allApps.switchBackToOverview() returned null", overview);
assertTrue("Launcher internal state didn't switch to Overview",
isInState(LauncherState.OVERVIEW));
// Test UIDevice.pressBack()
overview.switchToAllApps();
assertNotNull("overview.switchToAllApps() returned null (2)", allApps);
assertTrue("Launcher internal state is not All Apps (2)",
isInState(LauncherState.ALL_APPS));
mDevice.pressBack();
mLauncher.getOverview();
}
// Test UIDevice.pressHome, once we are in AllApps.
mDevice.pressHome();
waitForState("Launcher internal state didn't switch to Home", LauncherState.NORMAL);
// Test dismissing all tasks.
mLauncher.getWorkspace().switchToOverview().dismissAllTasks();
waitForState("Launcher internal state didn't switch to Home", LauncherState.NORMAL);
executeOnLauncher(
launcher -> assertEquals("Still have tasks after dismissing all",
0, getTaskCount(launcher)));
}
private int getCurrentOverviewPage(Launcher launcher) {
return launcher.<RecentsView>getOverviewPanel().getCurrentPage();
}
private int getTaskCount(Launcher launcher) {
return launcher.<RecentsView>getOverviewPanel().getTaskViewCount();
}
@Test
public void testAppIconLaunchFromAllAppsFromOverview() throws Exception {
final AllApps allApps =
mLauncher.getWorkspace().switchToOverview().switchToAllApps();
assertTrue("Launcher internal state is not All Apps", isInState(LauncherState.ALL_APPS));
TaplTestsLauncher3.runIconLaunchFromAllAppsTest(this, allApps);
}
@Test
@NavigationModeSwitch
@PortraitLandscape
public void testSwitchToOverview() throws Exception {
assertNotNull("Workspace.switchToOverview() returned null",
mLauncher.pressHome().switchToOverview());
assertTrue("Launcher internal state didn't switch to Overview",
isInState(LauncherState.OVERVIEW));
}
@Test
@NavigationModeSwitch
// @PortraitLandscape
public void testBackground() throws Exception {
startAppFast(resolveSystemApp(Intent.CATEGORY_APP_CALCULATOR));
final Background background = mLauncher.getBackground();
assertNotNull("Launcher.getBackground() returned null", background);
executeOnLauncher(launcher -> assertTrue(
"Launcher activity is the top activity; expecting another activity to be the top "
+ "one",
isInBackground(launcher)));
assertNotNull("Background.switchToOverview() returned null", background.switchToOverview());
assertTrue("Launcher internal state didn't switch to Overview",
isInState(LauncherState.OVERVIEW));
}
@Test
@PortraitLandscape
public void testAllAppsFromHome() throws Exception {
// Test opening all apps
assertNotNull("switchToAllApps() returned null",
mLauncher.getWorkspace().switchToAllApps());
TaplTestsLauncher3.runAllAppsTest(this, mLauncher.getAllApps());
// Testing pressHome.
assertTrue("Launcher internal state is not All Apps", isInState(LauncherState.ALL_APPS));
assertNotNull("pressHome returned null", mLauncher.pressHome());
assertTrue("Launcher internal state is not Home", isInState(LauncherState.NORMAL));
assertNotNull("getHome returned null", mLauncher.getWorkspace());
}
}