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

Commit 9a8f3712 authored by Louis Chang's avatar Louis Chang Committed by Android (Google) Code Review
Browse files

Merge "Ensure next invisible activity can be resumed while finishing top"

parents f398d998 c48a7ca8
Loading
Loading
Loading
Loading
+26 −12
Original line number Diff line number Diff line
@@ -2761,19 +2761,33 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
        // than destroy immediately.
        final boolean isNextNotYetVisible = next != null
                && (!next.nowVisible || !next.mVisibleRequested);
        if (isCurrentVisible && isNextNotYetVisible) {

        // Clear last paused activity to ensure top activity can be resumed during sleeping.
        if (isNextNotYetVisible && mDisplayContent.isSleeping()
                && next == next.getRootTask().mLastPausedActivity) {
            next.getRootTask().mLastPausedActivity = null;
        }

        if (isCurrentVisible) {
            if (isNextNotYetVisible) {
                // Add this activity to the list of stopping activities. It will be processed and
                // destroyed when the next activity reports idle.
                addToStopping(false /* scheduleIdle */, false /* idleDelayed */,
                        "completeFinishing");
                setState(STOPPING, "completeFinishing");
            } else if (addToFinishingAndWaitForIdle()) {
            // We added this activity to the finishing list and something else is becoming resumed.
            // The activity will complete finishing when the next activity reports idle. No need to
            // do anything else here.
                // We added this activity to the finishing list and something else is becoming
                // resumed. The activity will complete finishing when the next activity reports
                // idle. No need to do anything else here.
            } else {
            // Not waiting for the next one to become visible, and nothing else will be resumed in
            // place of this activity - requesting destruction right away.
                // Not waiting for the next one to become visible, and nothing else will be
                // resumed in place of this activity - requesting destruction right away.
                activityRemoved = destroyIfPossible(reason);
            }
        } else {
            // Just need to make sure the next activities can be resumed (if needed) and is free
            // to destroy this activity since it is currently not visible.
            addToFinishingAndWaitForIdle();
            activityRemoved = destroyIfPossible(reason);
        }

+1 −0
Original line number Diff line number Diff line
@@ -2379,6 +2379,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
                        }
                        return resumed;
                    }, false /* initValue */);
            result |= resumedOnDisplay;
            if (!resumedOnDisplay) {
                // In cases when there are no valid activities (e.g. device just booted or launcher
                // crashed) it's possible that nothing was resumed on a display. Requesting resume
+6 −0
Original line number Diff line number Diff line
@@ -1189,6 +1189,12 @@ final class TaskDisplayArea extends DisplayArea<Task> {
            return;
        }

        // Clear last paused activity if focused root task changed while sleeping, so that the
        // top activity of current focused task can be resumed.
        if (mDisplayContent.isSleeping()) {
            currentFocusedTask.mLastPausedActivity = null;
        }

        mLastFocusedStack = prevFocusedTask;
        EventLogTags.writeWmFocusedStack(mRootWindowContainer.mCurrentUser,
                mDisplayContent.mDisplayId,
+31 −4
Original line number Diff line number Diff line
@@ -1019,6 +1019,32 @@ public class ActivityRecordTests extends WindowTestsBase {
        verify(topActivity, never()).destroyIfPossible(anyString());
    }

    /**
     * Verify that complete finish request for top invisible activity must not be delayed while
     * sleeping, but next invisible activity must be resumed (and paused/stopped)
     */
    @Test
    public void testCompleteFinishing_noWaitForNextVisible_sleeping() {
        // Create a top activity on a new task
        final ActivityRecord topActivity = new ActivityBuilder(mAtm).setCreateTask(true).build();
        mDisplayContent.setIsSleeping(true);
        doReturn(true).when(mActivity).shouldBeVisible();
        topActivity.mVisibleRequested = false;
        topActivity.nowVisible = false;
        topActivity.finishing = true;
        topActivity.setState(STOPPED, "true");

        // Mark the activity behind (on a separate task) as not visible
        mActivity.mVisibleRequested = false;
        mActivity.nowVisible = false;
        mActivity.setState(STOPPED, "test");

        clearInvocations(mActivity);
        topActivity.completeFinishing("test");
        verify(mActivity).setState(eq(RESUMED), any());
        verify(topActivity).destroyIfPossible(anyString());
    }

    /**
     * Verify that complete finish request for invisible activity must not be delayed.
     */
@@ -1232,12 +1258,13 @@ public class ActivityRecordTests extends WindowTestsBase {
     */
    @Test
    public void testCompleteFinishing_lastActivityAboveEmptyHomeStack() {
        // Empty the home stack.
        final Task homeStack = mActivity.getDisplayArea().getRootHomeTask();
        homeStack.forAllLeafTasks((t) -> {
            homeStack.removeChild(t, "test");
        // Empty the home root task.
        final Task homeRootTask = mActivity.getDisplayArea().getRootHomeTask();
        homeRootTask.forAllLeafTasks((t) -> {
            homeRootTask.removeChild(t, "test");
        }, true /* traverseTopToBottom */);
        mActivity.finishing = true;
        mActivity.mVisibleRequested = true;
        spyOn(mStack);

        // Try to finish the last activity above the home stack.