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

Commit c8b6411e authored by Louis Chang's avatar Louis Chang
Browse files

Do not move home task if Recent is not the previous top

We shouldn't move the home task to front if Recents was
not the previous top activity on the display where the
task lands.

Bug: 111363427
Test: atest ActivityStackSupervisorTests

Change-Id: I39b51d5eec897bf83b2380dd8b7947c13cc7dd57
parent 2d3972e2
Loading
Loading
Loading
Loading
+22 −13
Original line number Diff line number Diff line
@@ -2304,17 +2304,8 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
            mUserLeaving = true;
        }

        // TODO(b/111363427): The moving-to-top task may not be on the top display, so it could be
        // different from where the prev activity stays on.
        final ActivityRecord prev = topRunningActivityLocked();

        if ((flags & ActivityManager.MOVE_TASK_WITH_HOME) != 0
                || (prev != null && prev.isActivityTypeRecents())) {
            // Caller wants the home activity moved with it or the previous task is recents in which
            // case we always return home from the task we are moving to the front.
            currentStack.getDisplay().moveHomeStackToFront("findTaskToMoveToFront");
        }

        reason = reason + " findTaskToMoveToFront";
        boolean reparented = false;
        if (task.isResizeable() && canUseActivityOptionsLaunchBounds(options)) {
            final Rect bounds = options.getLaunchBounds();
            task.updateOverrideConfiguration(bounds);
@@ -2322,10 +2313,12 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
            ActivityStack stack = getLaunchStack(null, options, task, ON_TOP);

            if (stack != currentStack) {
                moveHomeStackToFrontIfNeeded(flags, stack.getDisplay(), reason);
                task.reparent(stack, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, !ANIMATE, DEFER_RESUME,
                        "findTaskToMoveToFront");
                        reason);
                currentStack = stack;
                // moveTaskToStackUncheckedLocked() should already placed the task on top,
                reparented = true;
                // task.reparent() should already placed the task on top,
                // still need moveTaskToFrontLocked() below for any transition settings.
            }
            if (stack.resizeStackWithLaunchBounds()) {
@@ -2340,6 +2333,10 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
            }
        }

        if (!reparented) {
            moveHomeStackToFrontIfNeeded(flags, currentStack.getDisplay(), reason);
        }

        final ActivityRecord r = task.getTopActivity();
        currentStack.moveTaskToFrontLocked(task, false /* noAnimation */, options,
                r == null ? null : r.appTimeTracker, reason);
@@ -2351,6 +2348,18 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
                currentStack, forceNonResizeable);
    }

    private void moveHomeStackToFrontIfNeeded(int flags, ActivityDisplay display, String reason) {
        final ActivityStack focusedStack = display.getFocusedStack();

        if ((display.getWindowingMode() == WINDOWING_MODE_FULLSCREEN
                && (flags & ActivityManager.MOVE_TASK_WITH_HOME) != 0)
                || (focusedStack != null && focusedStack.isActivityTypeRecents())) {
            // We move home stack to front when we are on a fullscreen display and caller has
            // requested the home activity to move with it. Or the previous stack is recents.
            display.moveHomeStackToFront(reason);
        }
    }

    boolean canUseActivityOptionsLaunchBounds(ActivityOptions options) {
        // We use the launch bounds in the activity options is the device supports freeform
        // window management or is launching into the pinned stack.
+54 −0
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package com.android.server.am;

import static android.app.ActivityManager.START_DELIVERED_TO_TOP;
import static android.app.ActivityManager.START_TASK_TO_FRONT;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY;
@@ -34,9 +35,11 @@ import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.contains;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
@@ -406,6 +409,57 @@ public class ActivityStackSupervisorTests extends ActivityTestsBase {
        assertEquals(task.getBounds(), TASK_SIZE);
    }

    /**
     * Verify that home stack would be moved to front when the top activity is Recents.
     */
    @Test
    public void testFindTaskToMoveToFrontWhenRecentsOnTop() throws Exception {
        // Create stack/task on default display.
        final ActivityDisplay display = mSupervisor.getDefaultDisplay();
        final ActivityStack targetStack = display.createStack(WINDOWING_MODE_FULLSCREEN,
                ACTIVITY_TYPE_STANDARD, false /* onTop */);
        final TaskRecord targetTask = new TaskBuilder(mSupervisor).setStack(targetStack).build();

        // Create Recents on top of the display.
        final ActivityStack stack = display.createStack(WINDOWING_MODE_FULLSCREEN,
                ACTIVITY_TYPE_RECENTS, true /* onTop */);
        final TaskRecord task = new TaskBuilder(mSupervisor).setStack(stack).build();
        new ActivityBuilder(mService).setTask(task).build();

        final String reason = "findTaskToMoveToFront";
        mSupervisor.findTaskToMoveToFront(targetTask, 0, ActivityOptions.makeBasic(), reason,
                false);

        verify(display).moveHomeStackToFront(contains(reason));
    }

    /**
     * Verify that home stack won't be moved to front if the top activity on other display is
     * Recents.
     */
    @Test
    public void testFindTaskToMoveToFrontWhenRecentsOnOtherDisplay() throws Exception {
        // Create stack/task on default display.
        final ActivityDisplay display = mSupervisor.getDefaultDisplay();
        final ActivityStack targetStack = display.createStack(WINDOWING_MODE_FULLSCREEN,
                ACTIVITY_TYPE_STANDARD, false /* onTop */);
        final TaskRecord targetTask = new TaskBuilder(mSupervisor).setStack(targetStack).build();

        // Create Recents on secondary display.
        final TestActivityDisplay secondDisplay = addNewActivityDisplayAt(
                ActivityDisplay.POSITION_TOP);
        final ActivityStack stack = secondDisplay.createStack(WINDOWING_MODE_FULLSCREEN,
                ACTIVITY_TYPE_RECENTS, true /* onTop */);
        final TaskRecord task = new TaskBuilder(mSupervisor).setStack(stack).build();
        new ActivityBuilder(mService).setTask(task).build();

        final String reason = "findTaskToMoveToFront";
        mSupervisor.findTaskToMoveToFront(targetTask, 0, ActivityOptions.makeBasic(), reason,
                false);

        verify(display, never()).moveHomeStackToFront(contains(reason));
    }

    /**
     * Verify if a stack is not at the topmost position, it should be able to resume its activity if
     * the stack is the top focused.