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

Commit 30248a19 authored by Chris Li's avatar Chris Li
Browse files

Determine whether to support activities in multi window (9/n)

When a Task is detached but is still stored as a recent Task, it should
be allowed to launched into split screen.

Bug: 176061101
Test: atest WMShellFlickerTests:EnterSplitScreenFromDetachedRecentTask
Test: atest WmTests:RecentTasksTest
Change-Id: Ic72901ca76f4acb6e68926062675ecc290b399be
parent 63a14538
Loading
Loading
Loading
Loading
+92 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2021 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.wm.shell.flicker.legacysplitscreen

import android.platform.test.annotations.Presubmit
import android.view.Surface
import androidx.test.filters.RequiresDevice
import com.android.server.wm.flicker.FlickerParametersRunnerFactory
import com.android.server.wm.flicker.FlickerTestParameter
import com.android.server.wm.flicker.FlickerTestParameterFactory
import com.android.server.wm.flicker.dsl.FlickerBuilder
import com.android.server.wm.flicker.helpers.launchSplitScreen
import com.android.server.wm.traces.parser.windowmanager.WindowManagerStateHelper
import com.android.wm.shell.flicker.dockedStackDividerIsVisible
import com.android.wm.shell.flicker.helpers.SplitScreenHelper
import org.junit.FixMethodOrder
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.MethodSorters
import org.junit.runners.Parameterized

/**
 * Test enter split screen from a detached recent task
 *
 * To run this test: `atest WMShellFlickerTests:EnterSplitScreenFromDetachedRecentTask`
 */
@RequiresDevice
@RunWith(Parameterized::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
class EnterSplitScreenFromDetachedRecentTask(
    testSpec: FlickerTestParameter
) : LegacySplitScreenTransition(testSpec) {

    override val transition: FlickerBuilder.(Map<String, Any?>) -> Unit
        get() = { configuration ->
            cleanSetup(this, configuration)
            setup {
                eachRun {
                    splitScreenApp.launchViaIntent(wmHelper)
                    // Press back to remove the task, but it should still be shown in recent.
                    device.pressBack()
                }
            }
            transitions {
                device.launchSplitScreen(wmHelper)
            }
        }

    override val ignoredWindows: List<String>
        get() = listOf(LAUNCHER_PACKAGE_NAME,
                WindowManagerStateHelper.SPLASH_SCREEN_NAME,
                WindowManagerStateHelper.SNAPSHOT_WINDOW_NAME,
                splitScreenApp.defaultWindowName)

    @Presubmit
    @Test
    fun dockedStackDividerIsVisible() = testSpec.dockedStackDividerIsVisible()

    @Presubmit
    @Test
    fun appWindowIsVisible() {
        testSpec.assertWmEnd {
            isVisible(splitScreenApp.defaultWindowName)
        }
    }

    companion object {
        @Parameterized.Parameters(name = "{0}")
        @JvmStatic
        fun getParams(): Collection<FlickerTestParameter> {
            return FlickerTestParameterFactory.getInstance().getConfigNonRotationTests(
                    repetitions = SplitScreenHelper.TEST_REPETITIONS,
                    supportedRotations = listOf(Surface.ROTATION_0) // bugId = 179116910
            )
        }
    }
}
 No newline at end of file
+7 −2
Original line number Diff line number Diff line
@@ -1888,7 +1888,12 @@ class RecentTasks {
     */
    ActivityManager.RecentTaskInfo createRecentTaskInfo(Task tr, boolean stripExtras) {
        final ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
        tr.fillTaskInfo(rti, stripExtras);
        // If the recent Task is detached, we consider it will be re-attached to the default
        // TaskDisplayArea because we currently only support recent overview in the default TDA.
        final TaskDisplayArea tda = tr.isAttached()
                ? tr.getDisplayArea()
                : mService.mRootWindowContainer.getDefaultTaskDisplayArea();
        tr.fillTaskInfo(rti, stripExtras, tda);
        // Fill in some deprecated values.
        rti.id = rti.isRunning ? rti.taskId : INVALID_TASK_ID;
        rti.persistentId = rti.taskId;
@@ -1900,7 +1905,7 @@ class RecentTasks {
                final Task childTask = tr.getChildAt(i).asTask();
                if (childTask != null && childTask.isOrganized()) {
                    final ActivityManager.RecentTaskInfo cti = new ActivityManager.RecentTaskInfo();
                    childTask.fillTaskInfo(cti);
                    childTask.fillTaskInfo(cti, true /* stripExtras */, tda);
                    rti.childrenTaskInfos.add(cti);
                }
            }
+12 −3
Original line number Diff line number Diff line
@@ -2003,6 +2003,8 @@ class Task extends WindowContainer<WindowContainer> {
            return false;
        }
        if (tda == null) {
            Slog.w(TAG_TASKS, "Can't find TaskDisplayArea to determine support for multi"
                    + " window. Task id=" + mTaskId + " attached=" + isAttached());
            return false;
        }

@@ -4046,10 +4048,17 @@ class Task extends WindowContainer<WindowContainer> {
        fillTaskInfo(info, true /* stripExtras */);
    }

    void fillTaskInfo(TaskInfo info, boolean stripExtras) {
        fillTaskInfo(info, stripExtras, getDisplayArea());
    }

    /**
     * Fills in a {@link TaskInfo} with information from this task.
     *
     * @param tda consider whether this Task can be put in multi window as it will be attached to
     *            the give {@link TaskDisplayArea}.
     */
    void fillTaskInfo(TaskInfo info, boolean stripExtras) {
    void fillTaskInfo(TaskInfo info, boolean stripExtras, @Nullable TaskDisplayArea tda) {
        getNumRunningActivities(mReuseActivitiesReport);
        info.userId = isLeafTask() ? mUserId : mCurrentUser;
        info.taskId = mTaskId;
@@ -4074,8 +4083,8 @@ class Task extends WindowContainer<WindowContainer> {
        info.numActivities = mReuseActivitiesReport.numActivities;
        info.lastActiveTime = lastActiveTime;
        info.taskDescription = new ActivityManager.TaskDescription(getTaskDescription());
        info.supportsSplitScreenMultiWindow = supportsSplitScreenWindowingMode();
        info.supportsMultiWindow = supportsMultiWindow();
        info.supportsSplitScreenMultiWindow = supportsSplitScreenWindowingModeInDisplayArea(tda);
        info.supportsMultiWindow = supportsMultiWindowInDisplayArea(tda);
        info.configuration.setTo(getConfiguration());
        // Update to the task's current activity type and windowing mode which may differ from the
        // window configuration
+42 −0
Original line number Diff line number Diff line
@@ -1143,6 +1143,48 @@ public class RecentTasksTest extends WindowTestsBase {
        assertNull(lastSnapshotData.bufferSize);
    }

    @Test
    public void testCreateRecentTaskInfo_detachedTask() {
        final Task task = createTaskBuilder(".Task").setCreateActivity(true).build();
        final TaskDisplayArea tda = task.getDisplayArea();

        assertTrue(task.isAttached());
        assertTrue(task.supportsMultiWindow());

        RecentTaskInfo info = mRecentTasks.createRecentTaskInfo(task, true);

        assertTrue(info.supportsMultiWindow);
        assertTrue(info.supportsSplitScreenMultiWindow);

        // The task can be put in split screen even if it is not attached now.
        task.removeImmediately();

        info = mRecentTasks.createRecentTaskInfo(task, true);

        assertTrue(info.supportsMultiWindow);
        assertTrue(info.supportsSplitScreenMultiWindow);

        // Test non-resizable.
        // The non-resizable task cannot be put in split screen because of the config.
        doReturn(false).when(tda).supportsNonResizableMultiWindow();
        doReturn(false).when(task).isResizeable();

        info = mRecentTasks.createRecentTaskInfo(task, true);

        assertFalse(info.supportsMultiWindow);
        assertFalse(info.supportsSplitScreenMultiWindow);

        // Even if it is not attached, the non-resizable task can be put in split screen as long as
        // the device supports it.
        doReturn(true).when(tda).supportsNonResizableMultiWindow();

        info = mRecentTasks.createRecentTaskInfo(task, true);

        assertTrue(info.supportsMultiWindow);
        assertTrue(info.supportsSplitScreenMultiWindow);

    }

    private TaskSnapshot createSnapshot(Point taskSize, Point bufferSize) {
        HardwareBuffer buffer = null;
        if (bufferSize != null) {
+3 −0
Original line number Diff line number Diff line
@@ -289,6 +289,9 @@ public class TaskTests extends WindowTestsBase {

    @Test
    public void testResolveNonResizableTaskWindowingMode() {
        // Test with no support non-resizable in multi window regardless the screen size.
        mAtm.mSupportsNonResizableMultiWindow = -1;

        final Task task = createTask(mDisplayContent);
        Configuration parentConfig = task.getParent().getConfiguration();
        parentConfig.windowConfiguration.setWindowingMode(WINDOWING_MODE_FREEFORM);