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

Commit 3a4eafdd authored by Wei Sheng Shih's avatar Wei Sheng Shih Committed by Android (Google) Code Review
Browse files

Merge "Transfer the starting window to next running activity when invisible" into main

parents d2e58a4b 883ab3ce
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -472,6 +472,15 @@ flag {
        purpose: PURPOSE_BUGFIX
    }
}
flag {
    name: "transfer_starting_window_to_next_when_invisible"
    namespace: "windowing_frontend"
    description: "Transfer the starting window to the next non-finishing activity when the top activity becomes invisible that contains the starting window."
    bug: "436461530"
    metadata {
        purpose: PURPOSE_BUGFIX
    }
}

flag {
    name: "predictive_back_callback_cancellation_fix"
+51 −1
Original line number Diff line number Diff line
@@ -4600,6 +4600,11 @@ final class ActivityRecord extends WindowToken {
                    firstWindowDrawn = true;
                }
                if (fromActivity.isVisible()) {
                    // Collect this activity in case it isn't yet visible from resume.
                    if (Flags.transferStartingWindowToNextWhenInvisible()
                            && !isVisibleRequested()) {
                        mTransitionController.collect(this);
                    }
                    setVisible(true);
                    setVisibleRequested(true);
                    mWmService.mAnimator.addSurfaceVisibilityUpdate(this);
@@ -4691,6 +4696,46 @@ final class ActivityRecord extends WindowToken {
        });
    }

    /**
     * Tries to transfer the starting window from this activity in the task but will not visible
     * anymore. This is a common scenario apps use: A trampoline activity is started on top of an
     * existing Task, the starting windowing should transfer to the activity below once the
     * trampoline activity finishes.
     */
    void transferStartingWindowToNextRunningIfNeeded() {
        if (mStartingData == null) {
            return;
        }
        final ActivityRecord next = task.topRunningActivity();
        if (next == null || next == this) {
            return;
        }
        final WindowState mainWin = next.findMainWindow(false);
        if (mainWin != null && mainWin.mWinAnimator.getShown()) {
            // Next activity already has a visible window, so doesn't need to transfer the starting
            // window from this activity to here. The starting window will be removed with this
            // activity.
            return;
        }
        final StartingData tmpStartingData = mStartingData;
        if (tmpStartingData != null && tmpStartingData.mAssociatedTask == null
                && mTransitionController.isCollecting(this)
                && tmpStartingData instanceof SnapshotStartingData) {
            final Rect myBounds = getBounds();
            final Rect nextBounds = next.getBounds();
            if (!myBounds.equals(nextBounds)) {
                // Mark as no animation, so these changes won't merge into playing transition.
                if (mTransitionController.inPlayingTransition(this)) {
                    mTransitionController.setNoAnimation(next);
                    mTransitionController.setNoAnimation(this);
                }
                removeStartingWindow();
                return;
            }
        }
        next.transferStartingWindow(this);
    }

    boolean isKeyguardLocked() {
        return (mDisplayContent != null) ? mDisplayContent.isKeyguardLocked() :
                mRootWindowContainer.getDefaultDisplay().isKeyguardLocked();
@@ -5446,6 +5491,9 @@ final class ActivityRecord extends WindowToken {
        setVisibleRequested(visible);

        if (!visible) {
            if (Flags.transferStartingWindowToNextWhenInvisible()) {
                transferStartingWindowToNextRunningIfNeeded();
            }
            // Because starting window was transferred, this activity may be a trampoline which has
            // been occluded by next activity. If it has added windows, set client visibility
            // immediately to avoid the client getting RELAYOUT_RES_FIRST_TIME from relayout and
@@ -5470,8 +5518,10 @@ final class ActivityRecord extends WindowToken {
            ProtoLog.v(WM_DEBUG_ADD_REMOVE, "No longer Stopped: %s", this);
            mAppStopped = false;

            if (!Flags.transferStartingWindowToNextWhenInvisible()) {
                transferStartingWindowFromHiddenAboveTokenIfNeeded();
            }
        }
        requestUpdateWallpaperIfNeeded();

        // Defer committing visibility until transition starts.
+31 −0
Original line number Diff line number Diff line
@@ -3123,6 +3123,7 @@ public class ActivityRecordTests extends WindowTestsBase {
    }

    @Test
    @DisableFlags(Flags.FLAG_TRANSFER_STARTING_WINDOW_TO_NEXT_WHEN_INVISIBLE)
    public void testTryTransferStartingWindowFromHiddenAboveToken() {
        registerTestStartingWindowOrganizer();
        // Add two tasks on top of each other.
@@ -3152,6 +3153,36 @@ public class ActivityRecordTests extends WindowTestsBase {
        assertHasStartingWindow(activityBottom);
    }

    @Test
    @EnableFlags(Flags.FLAG_TRANSFER_STARTING_WINDOW_TO_NEXT_WHEN_INVISIBLE)
    public void testTryTransferStartingWindowToNextRunningIfNeeded() {
        registerTestStartingWindowOrganizer();
        // Add two tasks on top of each other.
        final ActivityRecord activityTop = new ActivityBuilder(mAtm).setCreateTask(true).build();
        final ActivityRecord activityBottom = new ActivityBuilder(mAtm).build();
        activityTop.getTask().addChild(activityBottom, 0);

        // Add a starting window.
        activityTop.addStartingWindow(mPackageName, android.R.style.Theme, null, true, true, false,
                true, false, false, false);
        waitUntilHandlersIdle();

        final WindowState startingWindow = activityTop.mStartingWindow;
        assertNotNull(startingWindow);

        // Make the top one invisible, and try transferring the starting window from the top to the
        // bottom one.
        activityTop.finishIfPossible(0, new Intent(), null, "test", false /* oomAdj */);
        waitUntilHandlersIdle();

        // Expect getFrozenInsetsState will be null when transferring the starting window.
        assertNull(startingWindow.getFrozenInsetsState());

        // Assert that the bottom window now has the starting window.
        assertNoStartingWindow(activityTop);
        assertHasStartingWindow(activityBottom);
    }

    @Test
    @EnableFlags(Flags.FLAG_ENSURE_STARTING_WINDOW_REMOVE_FROM_TASK)
    public void testStartingWindowInTaskFragment_RemoveAfterTrampolineInvisible() {