Merge "Revert "Revert "Add TaskbarModeSwitchRule to test both transient/persistent taskbar.""" into tm-qpr-dev

This commit is contained in:
TreeHugger Robot
2022-11-15 22:31:55 +00:00
committed by Android (Google) Code Review
12 changed files with 269 additions and 9 deletions

View File

@@ -38,6 +38,7 @@ filegroup {
name: "launcher3-quickstep-oop-tests-src",
path: "tests",
srcs: [
"tests/src/com/android/quickstep/TaskbarModeSwitchRule.java",
"tests/src/com/android/quickstep/NavigationModeSwitchRule.java",
"tests/src/com/android/quickstep/AbstractQuickStepTest.java",
"tests/src/com/android/quickstep/TaplTestsQuickstep.java",

View File

@@ -23,6 +23,7 @@ import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL;
import static com.android.launcher3.AbstractFloatingView.TYPE_ALL;
import static com.android.launcher3.AbstractFloatingView.TYPE_REBIND_SAFE;
import static com.android.launcher3.Utilities.IS_RUNNING_IN_TEST_HARNESS;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_FOLDER_OPEN;
import static com.android.launcher3.taskbar.TaskbarAutohideSuspendController.FLAG_AUTOHIDE_SUSPEND_DRAGGING;
import static com.android.launcher3.taskbar.TaskbarAutohideSuspendController.FLAG_AUTOHIDE_SUSPEND_FULLSCREEN;
@@ -308,7 +309,8 @@ public class TaskbarActivityContext extends BaseTaskbarContext {
int windowFlags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
| WindowManager.LayoutParams.FLAG_SLIPPERY
| WindowManager.LayoutParams.FLAG_SPLIT_TOUCH;
if (DisplayController.isTransientTaskbar(this)) {
if (DisplayController.isTransientTaskbar(this)
&& !IS_RUNNING_IN_TEST_HARNESS) {
windowFlags |= WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
| WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH;
}
@@ -896,13 +898,26 @@ public class TaskbarActivityContext extends BaseTaskbarContext {
mControllers.taskbarStashController.enableManualStashingDuringTests(enableManualStashing);
}
/**
* Enables the auto timeout for taskbar stashing. This method should only be used for taskbar
* testing.
*/
@VisibleForTesting
public void enableBlockingTimeoutDuringTests(boolean enableBlockingTimeout) {
mControllers.taskbarStashController.enableBlockingTimeoutDuringTests(enableBlockingTimeout);
}
/**
* Unstashes the Taskbar if it is stashed. This method should only be used to unstash the
* taskbar at the end of a test.
*/
@VisibleForTesting
public void unstashTaskbarIfStashed() {
mControllers.taskbarStashController.onLongPressToUnstashTaskbar();
if (DisplayController.isTransientTaskbar(this)) {
mControllers.taskbarStashController.updateAndAnimateTransientTaskbar(false);
} else {
mControllers.taskbarStashController.onLongPressToUnstashTaskbar();
}
}
protected boolean isUserSetupComplete() {

View File

@@ -37,6 +37,7 @@ import android.view.View;
import android.view.ViewConfiguration;
import androidx.annotation.NonNull;
import androidx.annotation.VisibleForTesting;
import com.android.internal.jank.InteractionJankMonitor;
import com.android.launcher3.Alarm;
@@ -169,6 +170,7 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba
private boolean mEnableManualStashingDuringTests = false;
private final Alarm mTimeoutAlarm = new Alarm();
private boolean mEnableBlockingTimeoutDuringTests = false;
// Evaluate whether the handle should be stashed
private final StatePropertyHolder mStatePropertyHolder = new StatePropertyHolder(
@@ -267,10 +269,20 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba
* Enables support for manual stashing. This should only be used to add this functionality
* to Launcher specific tests.
*/
@VisibleForTesting
public void enableManualStashingDuringTests(boolean enableManualStashing) {
mEnableManualStashingDuringTests = enableManualStashing;
}
/**
* Enables the auto timeout for taskbar stashing. This method should only be used for taskbar
* testing.
*/
@VisibleForTesting
public void enableBlockingTimeoutDuringTests(boolean enableBlockingTimeout) {
mEnableBlockingTimeoutDuringTests = enableBlockingTimeout;
}
/**
* Sets the flag indicating setup UI is visible
*/
@@ -846,12 +858,12 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba
* Attempts to start timer to auto hide the taskbar based on time.
*/
public void tryStartTaskbarTimeout() {
if (!DisplayController.isTransientTaskbar(mActivity)) {
return;
}
if (mIsStashed) {
if (!DisplayController.isTransientTaskbar(mActivity)
|| mIsStashed
|| mEnableBlockingTimeoutDuringTests) {
return;
}
cancelTimeoutIfExists();
mTimeoutAlarm.setOnAlarmListener(this::onTaskbarTimeout);

View File

@@ -11,9 +11,11 @@ import android.os.Bundle;
import androidx.annotation.Nullable;
import com.android.launcher3.R;
import com.android.launcher3.taskbar.TaskbarActivityContext;
import com.android.launcher3.testing.TestInformationHandler;
import com.android.launcher3.testing.shared.TestProtocol;
import com.android.launcher3.touch.PagedOrientationHandler;
import com.android.launcher3.util.DisplayController;
import com.android.quickstep.util.LayoutUtils;
import com.android.quickstep.util.TISBindHelper;
@@ -120,6 +122,30 @@ public class QuickstepTestInformationHandler extends TestInformationHandler {
.getCurrentActivityContext()
.getTaskbarAllAppsTopPadding());
}
case TestProtocol.REQUEST_ENABLE_BLOCK_TIMEOUT:
runOnTISBinder(tisBinder -> {
enableBlockingTimeout(tisBinder, true);
});
return response;
case TestProtocol.REQUEST_DISABLE_BLOCK_TIMEOUT:
runOnTISBinder(tisBinder -> {
enableBlockingTimeout(tisBinder, false);
});
return response;
case TestProtocol.REQUEST_ENABLE_TRANSIENT_TASKBAR:
runOnTISBinder(tisBinder -> {
enableTransientTaskbar(tisBinder, true);
});
return response;
case TestProtocol.REQUEST_DISABLE_TRANSIENT_TASKBAR:
runOnTISBinder(tisBinder -> {
enableTransientTaskbar(tisBinder, false);
});
return response;
}
return super.call(method, arg, extras);
@@ -149,6 +175,20 @@ public class QuickstepTestInformationHandler extends TestInformationHandler {
enable);
}
private void enableBlockingTimeout(
TouchInteractionService.TISBinder tisBinder, boolean enable) {
// Allow null-pointer to catch illegal states.
tisBinder.getTaskbarManager().getCurrentActivityContext().enableBlockingTimeoutDuringTests(
enable);
}
private void enableTransientTaskbar(
TouchInteractionService.TISBinder tisBinder, boolean enable) {
// Allow null-pointer to catch illegal states.
TaskbarActivityContext context = tisBinder.getTaskbarManager().getCurrentActivityContext();
DisplayController.INSTANCE.get(context).enableTransientTaskbarForTests(enable);
}
/**
* Runs the given command on the UI thread, after ensuring we are connected to
* TouchInteractionService.

View File

@@ -39,6 +39,7 @@ public abstract class AbstractQuickStepTest extends AbstractLauncherUiTest {
protected TestRule getRulesInsideActivityMonitor() {
return RuleChain.
outerRule(new NavigationModeSwitchRule(mLauncher)).
around(new TaskbarModeSwitchRule(mLauncher)).
around(super.getRulesInsideActivityMonitor());
}

View File

@@ -51,7 +51,7 @@ 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.
* The test should be annotated with @NavigationModeSwitch.
*/
public class NavigationModeSwitchRule implements TestRule {

View File

@@ -17,6 +17,8 @@ package com.android.quickstep;
import static androidx.test.InstrumentationRegistry.getInstrumentation;
import static com.android.quickstep.TaskbarModeSwitchRule.Mode.PERSISTENT;
import static junit.framework.TestCase.assertEquals;
import android.content.Intent;
@@ -27,6 +29,7 @@ import androidx.test.runner.AndroidJUnit4;
import com.android.launcher3.tapl.Taskbar;
import com.android.launcher3.ui.TaplTestsLauncher3;
import com.android.launcher3.util.rule.ScreenRecordRule.ScreenRecord;
import com.android.quickstep.TaskbarModeSwitchRule.TaskbarModeSwitch;
import org.junit.After;
import org.junit.Assume;
@@ -53,21 +56,25 @@ public class TaplTestsTaskbar extends AbstractQuickStepTest {
TaplTestsLauncher3.initialize(this);
startAppFast(CALCULATOR_APP_PACKAGE);
mLauncher.enableBlockTimeout(true);
mLauncher.showTaskbarIfHidden();
}
@After
public void tearDown() {
mLauncher.useDefaultWorkspaceLayoutOnReload();
mLauncher.enableBlockTimeout(false);
}
@Test
@TaskbarModeSwitch(mode = PERSISTENT)
public void testHideShowTaskbar() {
getTaskbar().hide();
mLauncher.getLaunchedAppState().showTaskbar();
}
@Test
@TaskbarModeSwitch(mode = PERSISTENT)
public void testHideTaskbarPersistsOnRecreate() {
getTaskbar().hide();
mLauncher.recreateTaskbar();
@@ -75,16 +82,19 @@ public class TaplTestsTaskbar extends AbstractQuickStepTest {
}
@Test
@TaskbarModeSwitch
public void testLaunchApp() throws Exception {
getTaskbar().getAppIcon(TEST_APP_NAME).launch(TEST_APP_PACKAGE);
}
@Test
@TaskbarModeSwitch
public void testOpenMenu() throws Exception {
getTaskbar().getAppIcon(TEST_APP_NAME).openMenu();
}
@Test
@TaskbarModeSwitch
public void testLaunchShortcut() throws Exception {
getTaskbar().getAppIcon(TEST_APP_NAME)
.openDeepShortcutMenu()
@@ -95,6 +105,7 @@ public class TaplTestsTaskbar extends AbstractQuickStepTest {
@Test
@ScreenRecord // b/231615831
@PortraitLandscape
@TaskbarModeSwitch
public void testLaunchAppInSplitscreen() throws Exception {
getTaskbar().getAppIcon(TEST_APP_NAME).dragToSplitscreen(
TEST_APP_PACKAGE, CALCULATOR_APP_PACKAGE);
@@ -103,6 +114,7 @@ public class TaplTestsTaskbar extends AbstractQuickStepTest {
@Test
@ScreenRecord // b/231615831
@PortraitLandscape
@TaskbarModeSwitch
public void testLaunchShortcutInSplitscreen() throws Exception {
getTaskbar().getAppIcon(TEST_APP_NAME)
.openDeepShortcutMenu()
@@ -111,16 +123,19 @@ public class TaplTestsTaskbar extends AbstractQuickStepTest {
}
@Test
@TaskbarModeSwitch
public void testLaunchApp_FromTaskbarAllApps() throws Exception {
getTaskbar().openAllApps().getAppIcon(TEST_APP_NAME).launch(TEST_APP_PACKAGE);
}
@Test
@TaskbarModeSwitch
public void testOpenMenu_FromTaskbarAllApps() throws Exception {
getTaskbar().openAllApps().getAppIcon(TEST_APP_NAME).openMenu();
}
@Test
@TaskbarModeSwitch
public void testLaunchShortcut_FromTaskbarAllApps() throws Exception {
getTaskbar().openAllApps()
.getAppIcon(TEST_APP_NAME)
@@ -132,6 +147,7 @@ public class TaplTestsTaskbar extends AbstractQuickStepTest {
@Test
@ScreenRecord // b/231615831
@PortraitLandscape
@TaskbarModeSwitch
public void testLaunchAppInSplitscreen_FromTaskbarAllApps() throws Exception {
getTaskbar().openAllApps()
.getAppIcon(TEST_APP_NAME)
@@ -141,6 +157,7 @@ public class TaplTestsTaskbar extends AbstractQuickStepTest {
@Test
@ScreenRecord // b/231615831
@PortraitLandscape
@TaskbarModeSwitch
public void testLaunchShortcutInSplitscreen_FromTaskbarAllApps() throws Exception {
getTaskbar().openAllApps()
.getAppIcon(TEST_APP_NAME)

View File

@@ -0,0 +1,140 @@
/*
* Copyright (C) 2022 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.TaskbarModeSwitchRule.Mode.ALL;
import static com.android.quickstep.TaskbarModeSwitchRule.Mode.PERSISTENT;
import static com.android.quickstep.TaskbarModeSwitchRule.Mode.TRANSIENT;
import android.content.Context;
import android.util.Log;
import com.android.launcher3.tapl.LauncherInstrumentation;
import com.android.launcher3.tapl.TestHelpers;
import com.android.launcher3.ui.AbstractLauncherUiTest;
import com.android.launcher3.util.DisplayController;
import com.android.launcher3.util.rule.FailureWatcher;
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;
/**
* Test rule that allows executing a test multiple times with different conditions
* ie. with transient taskbar enabled and disabled.
* The test should be annotated with @TaskbarModeSwitch.
*/
public class TaskbarModeSwitchRule implements TestRule {
static final String TAG = "TaskbarModeSwitchRule";
public static final int WAIT_TIME_MS = 10000;
public enum Mode {
TRANSIENT, PERSISTENT, ALL
}
// Annotation for tests that need to be run with quickstep enabled and disabled.
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface TaskbarModeSwitch {
Mode mode() default ALL;
}
private final LauncherInstrumentation mLauncher;
public TaskbarModeSwitchRule(LauncherInstrumentation launcher) {
mLauncher = launcher;
}
@Override
public Statement apply(Statement base, Description description) {
if (TestHelpers.isInLauncherProcess()
&& description.getAnnotation(TaskbarModeSwitch.class) != null) {
Mode mode = description.getAnnotation(TaskbarModeSwitch.class).mode();
return new Statement() {
@Override
public void evaluate() throws Throwable {
mLauncher.enableDebugTracing();
final boolean wasTransientTaskbarMode =
isTaskbarTransientMode(getInstrumentation().getTargetContext());
try {
if (mode == TRANSIENT || mode == ALL) {
evaluateWithTransientTaskbar();
}
if (mode == PERSISTENT || mode == ALL) {
evaluateWithPersistentTaskbar();
}
} catch (Throwable e) {
Log.e(TAG, "Error", e);
throw e;
} finally {
Log.d(TAG, "In Finally block");
setTaskbarMode(mLauncher, wasTransientTaskbarMode, description);
}
}
private void evaluateWithPersistentTaskbar() throws Throwable {
setTaskbarMode(mLauncher, false, description);
base.evaluate();
}
private void evaluateWithTransientTaskbar() throws Throwable {
setTaskbarMode(mLauncher, true, description);
base.evaluate();
}
};
} else {
return base;
}
}
private static boolean isTaskbarTransientMode(Context context) {
return DisplayController.isTransientTaskbar(context);
}
public static void setTaskbarMode(LauncherInstrumentation launcher,
boolean expectTransientTaskbar, Description description) throws Exception {
launcher.enableTransientTaskbar(expectTransientTaskbar);
launcher.recreateTaskbar();
Context context = getInstrumentation().getTargetContext();
assertTrue(launcher, "Couldn't set taskbar=" + expectTransientTaskbar,
isTaskbarTransientMode(context) == expectTransientTaskbar, description);
AbstractLauncherUiTest.checkDetectedLeaks(launcher);
}
private static void assertTrue(LauncherInstrumentation launcher, String message,
boolean condition, Description description) {
launcher.checkForAnomaly(true, true);
if (!condition) {
final AssertionError assertionError = new AssertionError(message);
if (description != null) {
FailureWatcher.onError(launcher, description, assertionError);
}
throw assertionError;
}
}
}

View File

@@ -84,6 +84,10 @@ public final class TestProtocol {
public static final String REQUEST_UNFREEZE_APP_LIST = "unfreeze-app-list";
public static final String REQUEST_ENABLE_MANUAL_TASKBAR_STASHING = "enable-taskbar-stashing";
public static final String REQUEST_DISABLE_MANUAL_TASKBAR_STASHING = "disable-taskbar-stashing";
public static final String REQUEST_ENABLE_BLOCK_TIMEOUT = "enable-block-timeout";
public static final String REQUEST_DISABLE_BLOCK_TIMEOUT = "disable-block-timeout";
public static final String REQUEST_ENABLE_TRANSIENT_TASKBAR = "enable-transient-taskbar";
public static final String REQUEST_DISABLE_TRANSIENT_TASKBAR = "disable-transient-taskbar";
public static final String REQUEST_UNSTASH_TASKBAR_IF_STASHED = "unstash-taskbar-if-stashed";
public static final String REQUEST_STASHED_TASKBAR_HEIGHT = "stashed-taskbar-height";
public static final String REQUEST_RECREATE_TASKBAR = "recreate-taskbar";

View File

@@ -42,6 +42,7 @@ import android.view.Display;
import androidx.annotation.AnyThread;
import androidx.annotation.UiThread;
import androidx.annotation.VisibleForTesting;
import com.android.launcher3.Utilities;
import com.android.launcher3.util.window.CachedDisplayInfo;
@@ -63,6 +64,7 @@ public class DisplayController implements ComponentCallbacks, SafeCloseable {
private static final String TAG = "DisplayController";
private static final boolean DEBUG = false;
private static boolean sTransientTaskbarStatusForTests;
public static final MainThreadInitializedObject<DisplayController> INSTANCE =
new MainThreadInitializedObject<>(DisplayController::new);
@@ -128,8 +130,18 @@ public class DisplayController implements ComponentCallbacks, SafeCloseable {
* Returns whether taskbar is transient.
*/
public static boolean isTransientTaskbar(Context context) {
return ENABLE_TRANSIENT_TASKBAR.get()
&& getNavigationMode(context) == NavigationMode.NO_BUTTON;
return getNavigationMode(context) == NavigationMode.NO_BUTTON
&& (Utilities.IS_RUNNING_IN_TEST_HARNESS
? sTransientTaskbarStatusForTests
: ENABLE_TRANSIENT_TASKBAR.get());
}
/**
* Enables transient taskbar status for tests.
*/
@VisibleForTesting
public static void enableTransientTaskbarForTests(boolean enable) {
sTransientTaskbarStatusForTests = enable;
}
@Override

View File

@@ -17,7 +17,9 @@
package com.android.launcher3.tapl;
import static com.android.launcher3.tapl.LauncherInstrumentation.TASKBAR_RES_ID;
import static com.android.launcher3.testing.shared.TestProtocol.REQUEST_DISABLE_BLOCK_TIMEOUT;
import static com.android.launcher3.testing.shared.TestProtocol.REQUEST_DISABLE_MANUAL_TASKBAR_STASHING;
import static com.android.launcher3.testing.shared.TestProtocol.REQUEST_ENABLE_BLOCK_TIMEOUT;
import static com.android.launcher3.testing.shared.TestProtocol.REQUEST_ENABLE_MANUAL_TASKBAR_STASHING;
import static com.android.launcher3.testing.shared.TestProtocol.REQUEST_STASHED_TASKBAR_HEIGHT;
@@ -88,6 +90,7 @@ public final class LaunchedAppState extends Background {
*/
public Taskbar showTaskbar() {
mLauncher.getTestInfo(REQUEST_ENABLE_MANUAL_TASKBAR_STASHING);
mLauncher.getTestInfo(REQUEST_ENABLE_BLOCK_TIMEOUT);
try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck();
LauncherInstrumentation.Closable c1 = mLauncher.addContextLayer(
@@ -114,6 +117,7 @@ public final class LaunchedAppState extends Background {
}
} finally {
mLauncher.getTestInfo(REQUEST_DISABLE_MANUAL_TASKBAR_STASHING);
mLauncher.getTestInfo(REQUEST_DISABLE_BLOCK_TIMEOUT);
}
}

View File

@@ -1850,6 +1850,20 @@ public final class LauncherInstrumentation {
getTestInfo(TestProtocol.REQUEST_UNSTASH_TASKBAR_IF_STASHED);
}
/** Blocks the taskbar from automatically stashing based on time. */
public void enableBlockTimeout(boolean enable) {
getTestInfo(enable
? TestProtocol.REQUEST_ENABLE_BLOCK_TIMEOUT
: TestProtocol.REQUEST_DISABLE_BLOCK_TIMEOUT);
}
/** Enables transient taskbar for testing purposes only. */
public void enableTransientTaskbar(boolean enable) {
getTestInfo(enable
? TestProtocol.REQUEST_ENABLE_TRANSIENT_TASKBAR
: TestProtocol.REQUEST_DISABLE_TRANSIENT_TASKBAR);
}
/**
* Recreates the taskbar (outside of tests this is done for certain configuration changes).
* The expected behavior is that the taskbar retains its current state after being recreated.