diff --git a/quickstep/res/layout/task.xml b/quickstep/res/layout/task.xml index ac1a50a5d8..34193d34c6 100644 --- a/quickstep/res/layout/task.xml +++ b/quickstep/res/layout/task.xml @@ -19,7 +19,7 @@ xmlns:android="http://schemas.android.com/apk/res/android" xmlns:androidprv="http://schemas.android.com/apk/prv/res/android" xmlns:launcher="http://schemas.android.com/apk/res-auto" - android:id="@+id/task" + android:id="@+id/task_view_single" android:layout_width="match_parent" android:layout_height="match_parent" android:clipChildren="false" diff --git a/quickstep/res/layout/task_desktop.xml b/quickstep/res/layout/task_desktop.xml index 64aa7e14ed..8c7090e41a 100644 --- a/quickstep/res/layout/task_desktop.xml +++ b/quickstep/res/layout/task_desktop.xml @@ -19,7 +19,7 @@ xmlns:android="http://schemas.android.com/apk/res/android" xmlns:androidprv="http://schemas.android.com/apk/prv/res/android" xmlns:launcher="http://schemas.android.com/apk/res-auto" - android:id="@+id/task" + android:id="@+id/task_view_desktop" android:layout_width="match_parent" android:layout_height="match_parent" android:clipChildren="true" diff --git a/quickstep/res/layout/task_grouped.xml b/quickstep/res/layout/task_grouped.xml index da2b29f9c6..cb4b98fd4c 100644 --- a/quickstep/res/layout/task_grouped.xml +++ b/quickstep/res/layout/task_grouped.xml @@ -24,7 +24,7 @@ xmlns:android="http://schemas.android.com/apk/res/android" xmlns:androidprv="http://schemas.android.com/apk/prv/res/android" xmlns:launcher="http://schemas.android.com/apk/res-auto" - android:id="@+id/task" + android:id="@+id/task_view_grouped" android:layout_width="match_parent" android:layout_height="match_parent" android:clipChildren="false" diff --git a/quickstep/src/com/android/quickstep/views/DesktopTaskView.kt b/quickstep/src/com/android/quickstep/views/DesktopTaskView.kt index 9ce2277b14..384945b34c 100644 --- a/quickstep/src/com/android/quickstep/views/DesktopTaskView.kt +++ b/quickstep/src/com/android/quickstep/views/DesktopTaskView.kt @@ -30,6 +30,8 @@ import android.view.ViewGroup import androidx.core.view.updateLayoutParams import com.android.launcher3.Flags.enableRefactorTaskThumbnail import com.android.launcher3.R +import com.android.launcher3.testing.TestLogging +import com.android.launcher3.testing.shared.TestProtocol import com.android.launcher3.util.RunnableList import com.android.launcher3.util.SplitConfigurationOptions import com.android.launcher3.util.TransformingTouchDelegate @@ -213,7 +215,15 @@ class DesktopTaskView @JvmOverloads constructor(context: Context, attrs: Attribu } override fun needsUpdate(dataChange: Int, flag: Int) = - if (flag == FLAG_UPDATE_THUMBNAIL) super.needsUpdate(dataChange, flag) else false + if (flag == FLAG_UPDATE_CORNER_RADIUS) false else super.needsUpdate(dataChange, flag) + + override fun onIconLoaded(taskContainer: TaskContainer) { + // Update contentDescription of snapshotView only, individual task icon is unused. + taskContainer.snapshotView.contentDescription = taskContainer.task.titleDescription + } + + // Ignoring [onIconUnloaded] as all tasks shares the same Desktop icon + override fun onIconUnloaded(taskContainer: TaskContainer) {} // thumbnailView is laid out differently and is handled in onMeasure override fun updateThumbnailSize() {} @@ -228,6 +238,11 @@ class DesktopTaskView @JvmOverloads constructor(context: Context, attrs: Attribu override fun launchTaskAnimated(): RunnableList? { val recentsView = recentsView ?: return null + TestLogging.recordEvent( + TestProtocol.SEQUENCE_MAIN, + "launchDesktopFromRecents", + taskIds.contentToString() + ) val endCallback = RunnableList() val desktopController = recentsView.desktopRecentsController checkNotNull(desktopController) { "recentsController is null" } diff --git a/quickstep/src/com/android/quickstep/views/TaskView.kt b/quickstep/src/com/android/quickstep/views/TaskView.kt index d87e05ff50..176a538d48 100644 --- a/quickstep/src/com/android/quickstep/views/TaskView.kt +++ b/quickstep/src/com/android/quickstep/views/TaskView.kt @@ -901,18 +901,11 @@ constructor( it.task.icon = icon it.task.titleDescription = contentDescription it.task.title = title - setIcon(it.iconView, icon) - if (enableOverviewIconMenu()) { - setText(it.iconView, title) - } - it.digitalWellBeingToast?.initialize(it.task) + onIconLoaded(it) } ?.also { request -> pendingIconLoadRequests.add(request) } } else { - setIcon(it.iconView, null) - if (enableOverviewIconMenu()) { - setText(it.iconView, null) - } + onIconUnloaded(it) } } } @@ -931,6 +924,21 @@ constructor( pendingIconLoadRequests.clear() } + protected open fun onIconLoaded(taskContainer: TaskContainer) { + setIcon(taskContainer.iconView, taskContainer.task.icon) + if (enableOverviewIconMenu()) { + setText(taskContainer.iconView, taskContainer.task.title) + } + taskContainer.digitalWellBeingToast?.initialize(taskContainer.task) + } + + protected open fun onIconUnloaded(taskContainer: TaskContainer) { + setIcon(taskContainer.iconView, null) + if (enableOverviewIconMenu()) { + setText(taskContainer.iconView, null) + } + } + protected fun setIcon(iconView: TaskViewIcon, icon: Drawable?) { with(iconView) { if (icon != null) { @@ -1152,6 +1160,11 @@ constructor( isClickableAsLiveTile = true return runnableList } + TestLogging.recordEvent( + TestProtocol.SEQUENCE_MAIN, + "composeRecentsLaunchAnimator", + taskIds.contentToString() + ) val runnableList = RunnableList() with(AnimatorSet()) { TaskViewUtils.composeRecentsLaunchAnimator( diff --git a/quickstep/tests/src/com/android/quickstep/TaplTestsOverviewDesktop.kt b/quickstep/tests/src/com/android/quickstep/TaplTestsOverviewDesktop.kt new file mode 100644 index 0000000000..694a3822fe --- /dev/null +++ b/quickstep/tests/src/com/android/quickstep/TaplTestsOverviewDesktop.kt @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2024 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 android.platform.test.rule.AllowedDevices +import android.platform.test.rule.DeviceProduct +import android.platform.test.rule.IgnoreLimit +import androidx.test.uiautomator.By +import androidx.test.uiautomator.Until +import com.android.launcher3.BuildConfig +import com.android.launcher3.ui.AbstractLauncherUiTest +import com.android.launcher3.ui.PortraitLandscapeRunner.PortraitLandscape +import com.android.launcher3.uioverrides.QuickstepLauncher +import com.google.common.truth.Truth.assertWithMessage +import org.junit.Before +import org.junit.Test + +/** Test Desktop windowing in Overview. */ +@AllowedDevices(allowed = [DeviceProduct.CF_TABLET, DeviceProduct.TANGORPRO]) +@IgnoreLimit(ignoreLimit = BuildConfig.IS_STUDIO_BUILD) +class TaplTestsOverviewDesktop : AbstractLauncherUiTest() { + @Before + fun setup() { + val overview = mLauncher.goHome().switchToOverview() + if (overview.hasTasks()) { + overview.dismissAllTasks() + } + startTestAppsWithCheck() + mLauncher.goHome() + } + + @Test + @PortraitLandscape + fun enterDesktopViaOverviewMenu() { + // Move last launched TEST_ACTIVITY_2 into Desktop + mLauncher.workspace + .switchToOverview() + .getTestActivityTask(TEST_ACTIVITY_2) + .tapMenu() + .tapDesktopMenuItem() + assertTestAppLaunched(TEST_ACTIVITY_2) + + // Scroll back to TEST_ACTIVITY_1, then move it into Desktop + mLauncher + .goHome() + .switchToOverview() + .apply { flingForward() } + .getTestActivityTask(TEST_ACTIVITY_1) + .tapMenu() + .tapDesktopMenuItem() + TEST_ACTIVITIES.forEach { assertTestAppLaunched(it) } + + // Launch static DesktopTaskView + val desktop = + mLauncher.goHome().switchToOverview().getTestActivityTask(TEST_ACTIVITIES).open() + TEST_ACTIVITIES.forEach { assertTestAppLaunched(it) } + + // Launch live-tile DesktopTaskView + desktop.switchToOverview().getTestActivityTask(TEST_ACTIVITIES).open() + TEST_ACTIVITIES.forEach { assertTestAppLaunched(it) } + } + + private fun startTestAppsWithCheck() { + TEST_ACTIVITIES.forEach { + startTestActivity(it) + executeOnLauncher { launcher -> + assertWithMessage( + "Launcher activity is the top activity; expecting TestActivity$it" + ) + .that(isInLaunchedApp(launcher)) + .isTrue() + } + } + } + + private fun assertTestAppLaunched(index: Int) { + assertWithMessage("TestActivity$index not opened in Desktop") + .that( + mDevice.wait( + Until.hasObject(By.pkg(getAppPackageName()).text("TestActivity$index")), + DEFAULT_UI_TIMEOUT + ) + ) + .isTrue() + } + + companion object { + const val TEST_ACTIVITY_1 = 2 + const val TEST_ACTIVITY_2 = 3 + val TEST_ACTIVITIES = listOf(TEST_ACTIVITY_1, TEST_ACTIVITY_2) + } +} diff --git a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java index 1e2744c3aa..749a75aaa1 100644 --- a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java +++ b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java @@ -43,6 +43,7 @@ import android.os.RemoteException; import android.os.UserHandle; import android.os.UserManager; import android.platform.test.flag.junit.SetFlagsRule; +import android.platform.test.rule.LimitDevicesRule; import android.system.OsConstants; import android.util.Log; @@ -222,6 +223,9 @@ public abstract class AbstractLauncherUiTest { @Rule public ExtendedLongPressTimeoutRule mLongPressTimeoutRule = new ExtendedLongPressTimeoutRule(); + @Rule + public LimitDevicesRule mlimitDevicesRule = new LimitDevicesRule(); + public static void initialize(AbstractLauncherUiTest test) throws Exception { test.reinitializeLauncherData(); test.mDevice.pressHome(); diff --git a/tests/tapl/com/android/launcher3/tapl/Background.java b/tests/tapl/com/android/launcher3/tapl/Background.java index 988aa94c28..b7ebfcd0d6 100644 --- a/tests/tapl/com/android/launcher3/tapl/Background.java +++ b/tests/tapl/com/android/launcher3/tapl/Background.java @@ -16,7 +16,7 @@ package com.android.launcher3.tapl; -import static com.android.launcher3.tapl.BaseOverview.TASK_RES_ID; +import static com.android.launcher3.tapl.BaseOverview.TASK_SELECTOR; import static com.android.launcher3.tapl.OverviewTask.TASK_START_EVENT; import static com.android.launcher3.testing.shared.TestProtocol.OVERVIEW_STATE_ORDINAL; @@ -117,10 +117,10 @@ public abstract class Background extends LauncherInstrumentation.VisibleContaine // non-tablet overview, snapshots can be on either side of the swiped // task, but we still check that they become visible after swiping and // pausing. - mLauncher.waitForOverviewObject(TASK_RES_ID); + mLauncher.waitForObjectBySelector(TASK_SELECTOR); if (mLauncher.isTablet()) { List tasks = mLauncher.getDevice().findObjects( - mLauncher.getOverviewObjectSelector(TASK_RES_ID)); + TASK_SELECTOR); final int centerX = mLauncher.getDevice().getDisplayWidth() / 2; mLauncher.assertTrue( "All tasks not to the left of the swiped task", diff --git a/tests/tapl/com/android/launcher3/tapl/BaseOverview.java b/tests/tapl/com/android/launcher3/tapl/BaseOverview.java index 567a8bd1c0..e71b49fcad 100644 --- a/tests/tapl/com/android/launcher3/tapl/BaseOverview.java +++ b/tests/tapl/com/android/launcher3/tapl/BaseOverview.java @@ -19,7 +19,9 @@ package com.android.launcher3.tapl; import static android.view.KeyEvent.KEYCODE_ESCAPE; import static com.android.launcher3.tapl.LauncherInstrumentation.TASKBAR_RES_ID; +import static com.android.launcher3.tapl.LauncherInstrumentation.log; import static com.android.launcher3.tapl.OverviewTask.TASK_START_EVENT; +import static com.android.launcher3.tapl.TestHelpers.getOverviewPackageName; import static com.android.launcher3.testing.shared.TestProtocol.NORMAL_STATE_ORDINAL; import android.graphics.Rect; @@ -35,9 +37,11 @@ import androidx.test.uiautomator.UiObject2; import com.android.launcher3.testing.shared.TestProtocol; +import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.List; +import java.util.Optional; import java.util.regex.Pattern; import java.util.stream.Collectors; @@ -46,7 +50,9 @@ import java.util.stream.Collectors; */ public class BaseOverview extends LauncherInstrumentation.VisibleContainer { private static final String TAG = "BaseOverview"; - protected static final String TASK_RES_ID = "task"; + protected static final BySelector TASK_SELECTOR = By.res(Pattern.compile( + getOverviewPackageName() + + ":id/(task_view_single|task_view_grouped|task_view_desktop)")); private static final Pattern EVENT_ALT_ESC_UP = Pattern.compile( "Key event: KeyEvent.*?action=ACTION_UP.*?keyCode=KEYCODE_ESCAPE.*?metaState=0"); private static final Pattern EVENT_ENTER_DOWN = Pattern.compile( @@ -56,10 +62,22 @@ public class BaseOverview extends LauncherInstrumentation.VisibleContainer { private static final int FLINGS_FOR_DISMISS_LIMIT = 40; + private final @Nullable UiObject2 mLiveTileTask; + + BaseOverview(LauncherInstrumentation launcher) { + this(launcher, /*launchedFromApp=*/false); + } + + BaseOverview(LauncherInstrumentation launcher, boolean launchedFromApp) { super(launcher); verifyActiveContainer(); verifyActionsViewVisibility(); + if (launchedFromApp) { + mLiveTileTask = getCurrentTaskUnchecked(); + } else { + mLiveTileTask = null; + } } @Override @@ -79,7 +97,7 @@ public class BaseOverview extends LauncherInstrumentation.VisibleContainer { private void flingForwardImpl() { try (LauncherInstrumentation.Closable c = mLauncher.addContextLayer("want to fling forward in overview")) { - LauncherInstrumentation.log("Overview.flingForward before fling"); + log("Overview.flingForward before fling"); final UiObject2 overview = verifyActiveContainer(); final int leftMargin = mLauncher.getTargetInsets().left + mLauncher.getEdgeSensitivityWidth(); @@ -105,7 +123,7 @@ public class BaseOverview extends LauncherInstrumentation.VisibleContainer { private void flingBackwardImpl() { try (LauncherInstrumentation.Closable c = mLauncher.addContextLayer("want to fling backward in overview")) { - LauncherInstrumentation.log("Overview.flingBackward before fling"); + log("Overview.flingBackward before fling"); final UiObject2 overview = verifyActiveContainer(); final int rightMargin = mLauncher.getTargetInsets().right + mLauncher.getEdgeSensitivityWidth(); @@ -276,37 +294,56 @@ public class BaseOverview extends LauncherInstrumentation.VisibleContainer { */ @NonNull public OverviewTask getCurrentTask() { + UiObject2 currentTask = getCurrentTaskUnchecked(); + mLauncher.assertNotNull("Unable to find a task", currentTask); + return new OverviewTask(mLauncher, currentTask, this); + } + + @Nullable + private UiObject2 getCurrentTaskUnchecked() { final List taskViews = getTasks(); - mLauncher.assertNotEquals("Unable to find a task", 0, taskViews.size()); + if (taskViews.isEmpty()) { + return null; + } // The widest, and most top-right task should be the current task - UiObject2 currentTask = Collections.max(taskViews, + return Collections.max(taskViews, Comparator.comparingInt((UiObject2 t) -> t.getVisibleBounds().width()) .thenComparingInt((UiObject2 t) -> t.getVisibleCenter().x) .thenComparing(Comparator.comparing( (UiObject2 t) -> t.getVisibleCenter().y).reversed())); - return new OverviewTask(mLauncher, currentTask, this); } - /** Returns an overview task matching TestActivity {@param activityNumber}. */ + /** + * Returns an overview task that contains the specified test activity in its thumbnails. + * + * @param activityIndex index of TestActivity to match against + */ @NonNull - public OverviewTask getTestActivityTask(int activityNumber) { + public OverviewTask getTestActivityTask(int activityIndex) { + return getTestActivityTask(Collections.singleton(activityIndex)); + } + + /** + * Returns an overview task that contains all the specified test activities in its thumbnails. + * + * @param activityNumbers collection of indices of TestActivity to match against + */ + @NonNull + public OverviewTask getTestActivityTask(Collection activityNumbers) { final List taskViews = getTasks(); mLauncher.assertNotEquals("Unable to find a task", 0, taskViews.size()); - final String activityName = "TestActivity" + activityNumber; - UiObject2 task = null; - for (UiObject2 taskView : taskViews) { - // TODO(b/239452415): Use equals instead of descEndsWith - if (taskView.getParent().hasObject(By.descEndsWith(activityName))) { - task = taskView; - break; - } - } - mLauncher.assertNotNull( - "Unable to find a task with " + activityName + " from the task list", task); + Optional task = taskViews.stream().filter( + taskView -> activityNumbers.stream().allMatch(activityNumber -> + // TODO(b/239452415): Use equals instead of descEndsWith + taskView.hasObject(By.descEndsWith("TestActivity" + activityNumber)) + )).findFirst(); - return new OverviewTask(mLauncher, task, this); + mLauncher.assertTrue("Unable to find a task with test activities " + activityNumbers + + " from the task list", task.isPresent()); + + return new OverviewTask(mLauncher, task.get(), this); } /** @@ -328,8 +365,7 @@ public class BaseOverview extends LauncherInstrumentation.VisibleContainer { try (LauncherInstrumentation.Closable c = mLauncher.addContextLayer( "want to get overview tasks")) { verifyActiveContainer(); - return mLauncher.getDevice().findObjects( - mLauncher.getOverviewObjectSelector(TASK_RES_ID)); + return mLauncher.getDevice().findObjects(TASK_SELECTOR); } } @@ -506,4 +542,10 @@ public class BaseOverview extends LauncherInstrumentation.VisibleContainer { } return null; } + + protected boolean isLiveTile(UiObject2 task) { + // UiObject2.equals returns false even when mLiveTileTask and task have the same node, hence + // compare only hashCode as a workaround. + return mLiveTileTask != null && mLiveTileTask.hashCode() == task.hashCode(); + } } diff --git a/tests/tapl/com/android/launcher3/tapl/LaunchedAppState.java b/tests/tapl/com/android/launcher3/tapl/LaunchedAppState.java index 200f2fff17..b3ad930659 100644 --- a/tests/tapl/com/android/launcher3/tapl/LaunchedAppState.java +++ b/tests/tapl/com/android/launcher3/tapl/LaunchedAppState.java @@ -33,6 +33,7 @@ import android.view.InputDevice; import android.view.MotionEvent; import android.view.ViewConfiguration; +import androidx.annotation.NonNull; import androidx.test.uiautomator.Condition; import androidx.test.uiautomator.UiDevice; @@ -75,6 +76,20 @@ public final class LaunchedAppState extends Background { return false; } + @NonNull + @Override + public BaseOverview switchToOverview() { + try (LauncherInstrumentation.Closable ignored = mLauncher.eventsCheck(); + LauncherInstrumentation.Closable ignored1 = mLauncher.addContextLayer( + "want to switch from background to overview")) { + verifyActiveContainer(); + goToOverviewUnchecked(); + return mLauncher.is3PLauncher() + ? new BaseOverview(mLauncher, /*launchedFromApp=*/true) + : new Overview(mLauncher, /*launchedFromApp=*/true); + } + } + /** * Returns the taskbar. * diff --git a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java index 75c1b24e23..a87406286b 100644 --- a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java +++ b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java @@ -1585,7 +1585,7 @@ public final class LauncherInstrumentation { return objects; } - private UiObject2 waitForObjectBySelector(BySelector selector) { + UiObject2 waitForObjectBySelector(BySelector selector) { Log.d(TEST_DRAG_APP_ICON_TO_MULTIPLE_WORKSPACES_FAILURE, "LauncherInstrumentation.waitForObjectBySelector"); final UiObject2 object = mDevice.wait(Until.findObject(selector), WAIT_TIME_MS); diff --git a/tests/tapl/com/android/launcher3/tapl/Overview.java b/tests/tapl/com/android/launcher3/tapl/Overview.java index 50c21368e0..deb27e4f87 100644 --- a/tests/tapl/com/android/launcher3/tapl/Overview.java +++ b/tests/tapl/com/android/launcher3/tapl/Overview.java @@ -22,9 +22,12 @@ import com.android.launcher3.tapl.LauncherInstrumentation.ContainerType; * Overview pane. */ public class Overview extends BaseOverview { - Overview(LauncherInstrumentation launcher) { - super(launcher); + this(launcher, /*launchedFromApp=*/false); + } + + Overview(LauncherInstrumentation launcher, boolean launchedFromApp) { + super(launcher, launchedFromApp); } @Override diff --git a/tests/tapl/com/android/launcher3/tapl/OverviewTask.java b/tests/tapl/com/android/launcher3/tapl/OverviewTask.java index 6f420afe78..7a8ab492b5 100644 --- a/tests/tapl/com/android/launcher3/tapl/OverviewTask.java +++ b/tests/tapl/com/android/launcher3/tapl/OverviewTask.java @@ -40,16 +40,23 @@ import java.util.stream.Collectors; public final class OverviewTask { private static final String SYSTEMUI_PACKAGE = "com.android.systemui"; static final Pattern TASK_START_EVENT = Pattern.compile("startActivityFromRecentsAsync"); + static final Pattern TASK_START_EVENT_DESKTOP = Pattern.compile("launchDesktopFromRecents"); + static final Pattern TASK_START_EVENT_LIVE_TILE = Pattern.compile( + "composeRecentsLaunchAnimator"); static final Pattern SPLIT_SELECT_EVENT = Pattern.compile("enterSplitSelect"); static final Pattern SPLIT_START_EVENT = Pattern.compile("launchSplitTasks"); private final LauncherInstrumentation mLauncher; + @NonNull private final UiObject2 mTask; + private final TaskViewType mType; private final BaseOverview mOverview; - OverviewTask(LauncherInstrumentation launcher, UiObject2 task, BaseOverview overview) { + OverviewTask(LauncherInstrumentation launcher, @NonNull UiObject2 task, BaseOverview overview) { mLauncher = launcher; + mLauncher.assertNotNull("task must not be null", task); mTask = task; mOverview = overview; + mType = getType(); verifyActiveContainer(); } @@ -220,7 +227,22 @@ public final class OverviewTask { return new LaunchedAppState(mLauncher); } } else { - mLauncher.expectEvent(TestProtocol.SEQUENCE_MAIN, TASK_START_EVENT); + final Pattern event; + if (mOverview.isLiveTile(mTask)) { + event = TASK_START_EVENT_LIVE_TILE; + } else if (mType == TaskViewType.DESKTOP) { + event = TASK_START_EVENT_DESKTOP; + } else { + event = TASK_START_EVENT; + } + mLauncher.expectEvent(TestProtocol.SEQUENCE_MAIN, event); + + if (mType == TaskViewType.DESKTOP) { + try (LauncherInstrumentation.Closable ignored = mLauncher.addContextLayer( + "launched desktop")) { + mLauncher.waitForSystemUiObject("desktop_mode_caption"); + } + } return new LaunchedAppState(mLauncher); } } @@ -273,6 +295,17 @@ public final class OverviewTask { return actual.contains(expected); } + private TaskViewType getType() { + String resourceName = mTask.getResourceName(); + if (resourceName.endsWith("task_view_grouped")) { + return TaskViewType.GROUPED; + } else if (resourceName.endsWith("task_view_desktop")) { + return TaskViewType.DESKTOP; + } else { + return TaskViewType.SINGLE; + } + } + /** * Enum used to specify which task is retrieved when it is a split task. */ @@ -292,4 +325,10 @@ public final class OverviewTask { this.iconAppRes = iconAppRes; } } + + private enum TaskViewType { + SINGLE, + GROUPED, + DESKTOP + } } diff --git a/tests/tapl/com/android/launcher3/tapl/OverviewTaskMenu.java b/tests/tapl/com/android/launcher3/tapl/OverviewTaskMenu.java index 902ad5b568..90d32f3249 100644 --- a/tests/tapl/com/android/launcher3/tapl/OverviewTaskMenu.java +++ b/tests/tapl/com/android/launcher3/tapl/OverviewTaskMenu.java @@ -97,20 +97,35 @@ public class OverviewTaskMenu { } } + /** + * Taps the Desktop item from the overview task menu and returns the LaunchedAppState + * representing the Desktop. + */ + @NonNull + public LaunchedAppState tapDesktopMenuItem() { + try (LauncherInstrumentation.Closable ignored = mLauncher.eventsCheck(); + LauncherInstrumentation.Closable ignored1 = mLauncher.addContextLayer( + "before tapping the desktop menu item")) { + mLauncher.executeAndWaitForLauncherStop( + () -> mLauncher.clickLauncherObject( + mLauncher.findObjectInContainer(mMenu, By.text("Desktop"))), + "tapped desktop menu item"); + + try (LauncherInstrumentation.Closable ignored2 = mLauncher.addContextLayer( + "tapped desktop menu item")) { + mLauncher.waitUntilSystemLauncherObjectGone("overview_panel"); + mLauncher.waitForSystemUiObject("desktop_mode_caption"); + return new LaunchedAppState(mLauncher); + } + } + } + /** Returns true if an item matching the given string is present in the menu. */ public boolean hasMenuItem(String expectedMenuItemText) { UiObject2 menuItem = mLauncher.findObjectInContainer(mMenu, By.text(expectedMenuItemText)); return menuItem != null; } - /** - * Returns the menu item specified by name if present. - */ - public OverviewTaskMenuItem getMenuItemByName(String menuItemName) { - return new OverviewTaskMenuItem(mLauncher, - mLauncher.waitForObjectInContainer(mMenu, By.text(menuItemName))); - } - /** * Taps outside task menu to dismiss it. */ diff --git a/tests/tapl/com/android/launcher3/tapl/OverviewTaskMenuItem.java b/tests/tapl/com/android/launcher3/tapl/OverviewTaskMenuItem.java deleted file mode 100644 index e3035bf71b..0000000000 --- a/tests/tapl/com/android/launcher3/tapl/OverviewTaskMenuItem.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (C) 2023 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.tapl; - -import android.graphics.Rect; - -import androidx.test.uiautomator.UiObject2; - -/** Represents an item in the overview task menu. */ -public class OverviewTaskMenuItem { - - private final LauncherInstrumentation mLauncher; - private final UiObject2 mMenuItem; - - OverviewTaskMenuItem(LauncherInstrumentation launcher, UiObject2 menuItem) { - mLauncher = launcher; - mMenuItem = menuItem; - } - - /** - * Returns this menu item's visible bounds. - */ - public Rect getVisibleBounds() { - return mMenuItem.getVisibleBounds(); - } -}