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

Commit 119fe0ec authored by Bryce Lee's avatar Bryce Lee Committed by android-build-merger
Browse files

Merge "Allow at most one pinned stack task." into oc-dev

am: 467deff7

Change-Id: If2e9badaeb31295468ce09ddbcdf45620121a7a6
parents 6d3b6476 467deff7
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -2878,6 +2878,10 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D

        mWindowManager.deferSurfaceLayout();

        // This will clear the pinned stack by moving an existing task to the full screen stack,
        // ensuring only one task is present.
        moveTasksToFullscreenStackLocked(PINNED_STACK_ID, !ON_TOP);

        // Need to make sure the pinned stack exist so we can resize it below...
        final PinnedActivityStack stack = getStack(PINNED_STACK_ID, CREATE_IF_NEEDED, ON_TOP);

+16 −2
Original line number Diff line number Diff line
@@ -48,6 +48,7 @@ import android.service.voice.IVoiceInteractionSession;
import android.util.DisplayMetrics;
import android.util.Slog;

import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.app.IVoiceInteractor;
import com.android.internal.util.XmlUtils;

@@ -445,10 +446,23 @@ final class TaskRecord extends ConfigurationContainer implements TaskWindowConta

        final Rect bounds = updateOverrideConfigurationFromLaunchBounds();
        final Configuration overrideConfig = getOverrideConfiguration();
        mWindowContainerController = new TaskWindowContainerController(taskId, this,
        setWindowContainerController(new TaskWindowContainerController(taskId, this,
                getStack().getWindowContainerController(), userId, bounds, overrideConfig,
                mResizeMode, mSupportsPictureInPicture, isHomeTask(), onTop, showForAllUsers,
                lastTaskDescription);
                lastTaskDescription));
    }

    /**
     * Should only be invoked from {@link #createWindowContainer(boolean, boolean)}.
     */
    @VisibleForTesting
    protected void setWindowContainerController(TaskWindowContainerController controller) {
        if (mWindowContainerController != null) {
            throw new IllegalArgumentException("Window container=" + mWindowContainerController
                    + " already created for task=" + this);
        }

        mWindowContainerController = controller;
    }

    void removeWindowContainer() {
+27 −15
Original line number Diff line number Diff line
@@ -16,7 +16,8 @@

package com.android.server.am;

import static org.junit.Assert.assertTrue;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;

import android.content.ComponentName;
import android.platform.test.annotations.Presubmit;
@@ -36,50 +37,61 @@ import org.junit.Test;
@Presubmit
@RunWith(AndroidJUnit4.class)
public class ActivityRecordTests extends ActivityTestsBase {
    private static final int TEST_STACK_ID = 100;

    private final ComponentName testActivityComponent =
            ComponentName.unflattenFromString("com.foo/.BarActivity");
    @Test
    public void testStackCleanupOnClearingTask() throws Exception {
        final ActivityManagerService service = createActivityManagerService();
        final TestActivityStack testStack = new ActivityStackBuilder(service).build();
        final TaskRecord task = createTask(service, testActivityComponent, testStack);
        final TaskRecord task = createTask(service, testActivityComponent, TEST_STACK_ID);
        final ActivityRecord record = createActivity(service, testActivityComponent, task);

        record.setTask(null);
        assertTrue(testStack.onActivityRemovedFromStackInvocationCount() == 1);
        assertEquals(getActivityRemovedFromStackCount(service, TEST_STACK_ID), 1);
    }

    @Test
    public void testStackCleanupOnActivityRemoval() throws Exception {
        final ActivityManagerService service = createActivityManagerService();
        final TestActivityStack testStack = new ActivityStackBuilder(service).build();
        final TaskRecord task = createTask(service, testActivityComponent, testStack);
        final TaskRecord task = createTask(service, testActivityComponent, TEST_STACK_ID);
        final ActivityRecord record = createActivity(service, testActivityComponent, task);

        task.removeActivity(record);
        assertTrue(testStack.onActivityRemovedFromStackInvocationCount() == 1);
        assertEquals(getActivityRemovedFromStackCount(service, TEST_STACK_ID),  1);
    }

    @Test
    public void testStackCleanupOnTaskRemoval() throws Exception {
        final ActivityManagerService service = createActivityManagerService();
        final TestActivityStack testStack = new ActivityStackBuilder(service).build();
        final TaskRecord task = createTask(service, testActivityComponent, testStack);
        final TaskRecord task = createTask(service, testActivityComponent, TEST_STACK_ID);
        final ActivityRecord record = createActivity(service, testActivityComponent, task);

        testStack.removeTask(task, null /*reason*/, ActivityStack.REMOVE_TASK_MODE_MOVING);
        assertTrue(testStack.onActivityRemovedFromStackInvocationCount() == 1);
        service.mStackSupervisor.getStack(TEST_STACK_ID)
                .removeTask(task, null /*reason*/, ActivityStack.REMOVE_TASK_MODE_MOVING);

        // Stack should be gone on task removal.
        assertNull(service.mStackSupervisor.getStack(TEST_STACK_ID));
    }

    @Test
    public void testNoCleanupMovingActivityInSameStack() throws Exception {
        final ActivityManagerService service = createActivityManagerService();
        final TestActivityStack testStack = new ActivityStackBuilder(service).build();
        final TaskRecord oldTask = createTask(service, testActivityComponent, testStack);
        final TaskRecord oldTask = createTask(service, testActivityComponent, TEST_STACK_ID);
        final ActivityRecord record = createActivity(service, testActivityComponent, oldTask);
        final TaskRecord newTask = createTask(service, testActivityComponent, testStack);
        final TaskRecord newTask = createTask(service, testActivityComponent, TEST_STACK_ID);

        record.reparent(newTask, 0, null /*reason*/);
        assertTrue(testStack.onActivityRemovedFromStackInvocationCount() == 0);
        assertEquals(getActivityRemovedFromStackCount(service, TEST_STACK_ID), 0);
    }

    private static int getActivityRemovedFromStackCount(ActivityManagerService service,
            int stackId) {
        final ActivityStack stack = service.mStackSupervisor.getStack(stackId);
        if (stack instanceof ActivityStackReporter) {
            return ((ActivityStackReporter) stack).onActivityRemovedFromStackInvocationCount();
        }

        return -1;
    }
}
+68 −0
Original line number Diff line number Diff line
@@ -16,8 +16,14 @@

package com.android.server.am;

import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;

import android.content.ComponentName;
import android.graphics.Rect;
import android.platform.test.annotations.Presubmit;
import android.support.test.filters.MediumTest;
import android.support.test.runner.AndroidJUnit4;
@@ -25,6 +31,10 @@ import android.support.test.runner.AndroidJUnit4;
import org.junit.runner.RunWith;
import org.junit.Test;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE;

/**
@@ -37,6 +47,9 @@ import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS
@Presubmit
@RunWith(AndroidJUnit4.class)
public class ActivityStackSupervisorTests extends ActivityTestsBase {
    private final ComponentName testActivityComponent =
            ComponentName.unflattenFromString("com.foo/.BarActivity");

    /**
     * This test ensures that we do not try to restore a task based off an invalid task id. The
     * stack supervisor is a test version so there will be no tasks present. We should expect
@@ -49,4 +62,59 @@ public class ActivityStackSupervisorTests extends ActivityTestsBase {
                MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE, 0 /*stackId*/);
        assertNull(task);
    }

    /**
     * This test ensures that an existing task in the pinned stack is moved to the fullscreen
     * activity stack when a new task is added.
     */
    @Test
    public void testReplacingTaskInPinnedStack() throws Exception {
        final ActivityManagerService service = createActivityManagerService();
        final TaskRecord firstTask = createTask(service, testActivityComponent,
                FULLSCREEN_WORKSPACE_STACK_ID);
        final ActivityRecord firstActivity = createActivity(service, testActivityComponent,
                firstTask);
        // Create a new task on the full screen stack
        final TaskRecord secondTask = createTask(service, testActivityComponent,
                FULLSCREEN_WORKSPACE_STACK_ID);
        final ActivityRecord secondActivity = createActivity(service, testActivityComponent,
                secondTask);
        service.mStackSupervisor.setFocusStackUnchecked("testReplacingTaskInPinnedStack",
                service.mStackSupervisor.getStack(FULLSCREEN_WORKSPACE_STACK_ID));

        // Ensure full screen stack has both tasks.
        ensureStackPlacement(service.mStackSupervisor, FULLSCREEN_WORKSPACE_STACK_ID, firstTask,
                secondTask);

        // Move first activity to pinned stack.
        service.mStackSupervisor.moveActivityToPinnedStackLocked(firstActivity,
                new Rect() /*sourceBounds*/, 0f /*aspectRatio*/, false, "initialMove");

        // Ensure a task has moved over.
        ensureStackPlacement(service.mStackSupervisor, PINNED_STACK_ID, firstTask);
        ensureStackPlacement(service.mStackSupervisor, FULLSCREEN_WORKSPACE_STACK_ID, secondTask);

        // Move second activity to pinned stack.
        service.mStackSupervisor.moveActivityToPinnedStackLocked(secondActivity,
                new Rect() /*sourceBounds*/, 0f /*aspectRatio*/ /*destBounds*/, false, "secondMove");

        // Ensure stacks have swapped tasks.
        ensureStackPlacement(service.mStackSupervisor, PINNED_STACK_ID, secondTask);
        ensureStackPlacement(service.mStackSupervisor, FULLSCREEN_WORKSPACE_STACK_ID, firstTask);
    }

    private static void ensureStackPlacement(ActivityStackSupervisor supervisor, int stackId,
            TaskRecord... tasks) {
        final ActivityStack stack = supervisor.getStack(stackId);
        final ArrayList<TaskRecord> stackTasks = stack.getAllTasks();
        assertEquals(stackTasks.size(), tasks != null ? tasks.length : 0);

        if (tasks == null) {
            return;
        }

        for (TaskRecord task : tasks) {
            assertTrue(stackTasks.contains(task));
        }
    }
}
+8 −9
Original line number Diff line number Diff line
@@ -37,28 +37,27 @@ import org.junit.Test;
@Presubmit
@RunWith(AndroidJUnit4.class)
public class ActivityStackTests extends ActivityTestsBase {
    private final ComponentName testActivityComponent =
    private static final int TEST_STACK_ID = 100;
    private static final ComponentName testActivityComponent =
            ComponentName.unflattenFromString("com.foo/.BarActivity");

    @Test
    public void testEmptyTaskCleanupOnRemove() throws Exception {
        final ActivityManagerService service = createActivityManagerService();
        final TestActivityStack testStack = new ActivityStackBuilder(service).build();
        final TaskRecord task = createTask(service, testActivityComponent, testStack);
        final TaskRecord task = createTask(service, testActivityComponent, TEST_STACK_ID);
        assertNotNull(task.getWindowContainerController());
        testStack.removeTask(task, "testEmptyTaskCleanupOnRemove",
                ActivityStack.REMOVE_TASK_MODE_DESTROYING);
        service.mStackSupervisor.getStack(TEST_STACK_ID).removeTask(task,
                "testEmptyTaskCleanupOnRemove", ActivityStack.REMOVE_TASK_MODE_DESTROYING);
        assertNull(task.getWindowContainerController());
    }
    @Test
    public void testOccupiedTaskCleanupOnRemove() throws Exception {
        final ActivityManagerService service = createActivityManagerService();
        final TestActivityStack testStack = new ActivityStackBuilder(service).build();
        final TaskRecord task = createTask(service, testActivityComponent, testStack);
        final TaskRecord task = createTask(service, testActivityComponent, TEST_STACK_ID);
        final ActivityRecord activityRecord = createActivity(service, testActivityComponent, task);
        assertNotNull(task.getWindowContainerController());
        testStack.removeTask(task, "testOccupiedTaskCleanupOnRemove",
                ActivityStack.REMOVE_TASK_MODE_DESTROYING);
        service.mStackSupervisor.getStack(TEST_STACK_ID).removeTask(task,
                "testOccupiedTaskCleanupOnRemove", ActivityStack.REMOVE_TASK_MODE_DESTROYING);
        assertNotNull(task.getWindowContainerController());
    }
}
Loading