Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1ceac5dd authored by Alex Chau's avatar Alex Chau
Browse files

Implement e2e test for desktop windowing

Code changes:
- TaskView, GroupedTaskView and DesktopTaskView now uses different resId, so it can be differentiated by TAPL
- Extracted result handling of icon loading, so we can override in DesktopTaskView
- DesktopTaskView now load icons, so titleDescription can be loaded. When icons are loaded, contentDescription are applied to respective snapshotViews; icon unloading is ignored
- Track launchDesktopFromRecents and composeRecentsLaunchAnimator in TAPL events so we can test if the TaskView launch path is correct

Test changes:
- Added TaplTestsOverviewDesktop that move 2 TestActivities into Desktop, and launch the DesktopTaskView as static and live tile
- TaplTestsOverviewDesktop is limited to Tangor/cf_tablet only, and added LimitDeviceRule to AbstractLauncherUiTest to enable @AllowedDevices and @IgnoreLimit

TAPL changes (2 APIs added/modified):
- Changed TaskView matcher to use id/task_view_* to match all TaskView types
- When Overview is launcehd from Background, mark the currentTask after the launch as liveTile. When an OverviewTask has the same accessibility node as the liveTile, it'll expect different event when launching.
- [API change] BaseOverview.getTestActivityTask can now matches mutiple test activiites, useful for matching GroupedTaskView and DesktopTaskView; Fix a bug that getTestActivityTask wrongly use `getParent()` which is RecentsView to match activityName.
- In OverviewTask.open, we'll expect different events based on TaskView types and whether it's a live tile. Launching DesktopTaskView will in additional verify Desktop header is present on screen.
- [API change] In OverviewTaskMenu, support tapping Desktop menu and verify Desktop header is present on screen.
- Removed unused OverviewTaskMenuItem

Fix: 320313527
Test: TaplTestsOverviewDesktop
Flag: com.android.window.flags.enable_desktop_windowing_mode
Change-Id: I89261c787364901320f3acb18f01ddad5f62d17c
parent 99a76f1f
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -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"
+1 −1
Original line number Diff line number Diff line
@@ -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"
+1 −1
Original line number Diff line number Diff line
@@ -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"
+16 −1
Original line number Diff line number Diff line
@@ -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" }
+22 −9
Original line number Diff line number Diff line
@@ -868,18 +868,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)
                }
            }
        }
@@ -898,6 +891,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) {
@@ -1119,6 +1127,11 @@ constructor(
            isClickableAsLiveTile = true
            return runnableList
        }
        TestLogging.recordEvent(
            TestProtocol.SEQUENCE_MAIN,
            "composeRecentsLaunchAnimator",
            taskIds.contentToString()
        )
        val runnableList = RunnableList()
        with(AnimatorSet()) {
            TaskViewUtils.composeRecentsLaunchAnimator(
Loading