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

Commit e1516701 authored by wilsonshih's avatar wilsonshih
Browse files

Attempt to remove the starting window when an activity becomes invisible.

The starting data can be associated with the task and shared between
activities. If a trampoline activity, which never draws and gets
destroyed right after being launched/does not own the starting
data, the starting window cannot being removed from it. Turns out may be
miss opportunity to remove the starting window after trampoline gone.
Therefore, to be more generic, an attempt can be made to remove the
starting window whenever an activity becomes invisible.

Flag: com.android.window.flags.ensure_starting_window_remove_from_task
Bug: 405253899
Test: atest ActivityRecordTests
Change-Id: Iba7118b793ed55b0e85e0d21f2419dfead84759d
parent 4a767ed1
Loading
Loading
Loading
Loading
+11 −0
Original line number Diff line number Diff line
@@ -479,3 +479,14 @@ flag {
    description: "Removes restriction that only one back callback with PRIORITY_SYSTEM_NAVIGATION_OBSERVER can be registered"
    bug: "424146227"
}

flag {
    name: "ensure_starting_window_remove_from_task"
    namespace: "windowing_frontend"
    description: "Trigger the removal of the starting window from the task in case the shared starting data is not attached to itself."
    bug: "405253899"
    is_fixed_read_only: true
    metadata {
        purpose: PURPOSE_BUGFIX
    }
}
 No newline at end of file
+30 −6
Original line number Diff line number Diff line
@@ -5317,6 +5317,15 @@ final class ActivityRecord extends WindowToken {
        }
    }

    @Nullable
    private ActivityRecord getSharedStartingWindowOwnerIfTaskDrawn() {
        if (task.getActivity(r -> r.isVisibleRequested() && !r.firstWindowDrawn) == null) {
            // The last drawn activity may not be the one that owns the starting window.
            return task.getActivity(ar -> ar.mStartingData != null);
        }
        return null;
    }

    /**
     * This is the only place that writes {@link #mVisibleRequested} (except unit test). The caller
     * outside of this class should use {@link #setVisibility}.
@@ -5337,6 +5346,13 @@ final class ActivityRecord extends WindowToken {
                    && mDisplayContent.mInputMethodWindow != null
                    && mDisplayContent.mInputMethodWindow.isVisible();
            finishOrAbortReplacingWindow();
            if (Flags.ensureStartingWindowRemoveFromTask() && !firstWindowDrawn && task != null
                    && task.mSharedStartingData != null) {
                final ActivityRecord r = getSharedStartingWindowOwnerIfTaskDrawn();
                if (r != null) {
                    r.removeStartingWindow();
                }
            }
        }
        return true;
    }
@@ -6443,14 +6459,22 @@ final class ActivityRecord extends WindowToken {
        final Task associatedTask = task.mSharedStartingData != null ? task : null;
        if (associatedTask == null) {
            removeStartingWindow();
        } else {
            if (Flags.ensureStartingWindowRemoveFromTask()) {
                final ActivityRecord r = getSharedStartingWindowOwnerIfTaskDrawn();
                if (r != null) {
                    r.removeStartingWindow();
                }
            } else if (associatedTask.getActivity(
                    r -> r.isVisibleRequested() && !r.firstWindowDrawn) == null) {
                // The last drawn activity may not be the one that owns the starting window.
            final ActivityRecord r = associatedTask.getActivity(ar -> ar.mStartingData != null);
                final ActivityRecord r = associatedTask.getActivity(
                        ar -> ar.mStartingData != null);
                if (r != null) {
                    r.removeStartingWindow();
                }
            }
        }
        updateReportedVisibilityLocked();
    }

+18 −2
Original line number Diff line number Diff line
@@ -3095,7 +3095,18 @@ public class ActivityRecordTests extends WindowTestsBase {
    }

    @Test
    public void testStartingWindowInTaskFragment() {
    @EnableFlags(Flags.FLAG_ENSURE_STARTING_WINDOW_REMOVE_FROM_TASK)
    public void testStartingWindowInTaskFragment_RemoveAfterTrampolineInvisible() {
        testStartingWindowInTaskFragment_RemoveFrom(false, true);
    }

    @Test
    public void testStartingWindowInTaskFragment_RemoveAfterWindowDrawn() {
        testStartingWindowInTaskFragment_RemoveFrom(true, false);
    }

    private void testStartingWindowInTaskFragment_RemoveFrom(boolean firstWindowDrawn,
            boolean requestedInvisible) {
        final ActivityRecord activity1 = new ActivityBuilder(mAtm).setCreateTask(true)
                .setVisible(false).build();
        final WindowState startingWindow = createWindowState(
@@ -3147,7 +3158,12 @@ public class ActivityRecordTests extends WindowTestsBase {
        // The starting window is only removed when all embedded activities are drawn.
        final WindowState activityWindow = mock(WindowState.class);
        activity1.onFirstWindowDrawn(activityWindow);
        if (firstWindowDrawn) {
            activity2.onFirstWindowDrawn(activityWindow);
        }
        if (requestedInvisible) {
            activity2.setVisibleRequested(false);
        }
        assertNull(activity1.mStartingWindow);
        assertNull(task.mSharedStartingData);
    }