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

Commit 8f42ef56 authored by Riddle Hsu's avatar Riddle Hsu
Browse files

Update visibility when visible activity crashed

Previously, if a top fullscreen app is crashed when a display
transition is collecting, the transition will be ready and sent
directly from finishTopCrashedActivityLocked -> finishIfPossible
 -> continueWindowLayout -> BLASTSyncEngine.SyncGroup#tryFinish.
That causes the transition to contain a change to hide display
area because nothing is visible in it.

Now finishTopCrashedActivities has similar steps as handleAppDied.
If there is perceptible activity in the crashed process, the
next top activity will be requested to visible at the same time.
Then the transition can recognize that the display area is visible.

Note that finishTopCrashedActivityLocked calls finishIfPossible,
so it may already adjust focusable task. But because the crashing
activity is pausing (pause->resume from switch display and then
resume -> pausing when finishing for crash), the next activity
won't resume until the pausing is gone. Then it requires
ensureActivitiesVisible to make the current top activity (its
task was moved to front when adjusting focusable task) visible.

Bug: 300790517
Test: RootWindowContainerTests#testRemovingRootTaskOnAppCrash
Change-Id: I935121ed53638720ec3c8ef872f7c78e90edd714
parent 6c29a6fb
Loading
Loading
Loading
Loading
+14 −14
Original line number Diff line number Diff line
@@ -6420,19 +6420,8 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
                if (!restarting && hasVisibleActivities) {
                    deferWindowLayout();
                    try {
                        final Task topTask = mRootWindowContainer.getTopDisplayFocusedRootTask();
                        if (topTask != null
                                && topTask.topRunningActivity(true /* focusableOnly */) == null) {
                            topTask.adjustFocusToNextFocusableTask("handleAppDied");
                        }
                        if (!mRootWindowContainer.resumeFocusedTasksTopActivities()) {
                            // If there was nothing to resume, and we are not already restarting
                            // this process, but there is a visible activity that is hosted by the
                            // process...then make sure all visible activities are running, taking
                            // care of restarting this process.
                            mRootWindowContainer.ensureActivitiesVisible(null, 0,
                                    !PRESERVE_WINDOWS);
                        }
                        mRootWindowContainer.ensureVisibilityOnVisibleActivityDiedOrCrashed(
                                "handleAppDied");
                    } finally {
                        continueWindowLayout();
                    }
@@ -6873,7 +6862,18 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
        @Override
        public int finishTopCrashedActivities(WindowProcessController crashedApp, String reason) {
            synchronized (mGlobalLock) {
                return mRootWindowContainer.finishTopCrashedActivities(crashedApp, reason);
                deferWindowLayout();
                try {
                    final Task finishedTask = mRootWindowContainer.finishTopCrashedActivities(
                            crashedApp, reason);
                    if (finishedTask != null) {
                        mRootWindowContainer.ensureVisibilityOnVisibleActivityDiedOrCrashed(reason);
                        return finishedTask.mTaskId;
                    }
                    return INVALID_TASK_ID;
                } finally {
                    continueWindowLayout();
                }
            }
        }

+22 −5
Original line number Diff line number Diff line
@@ -2297,19 +2297,36 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
     *
     * @param app    The app that crashed.
     * @param reason Reason to perform this action.
     * @return The task id that was finished in this root task, or INVALID_TASK_ID if none was
     * finished.
     * @return The finished task which was on top or visible, otherwise {@code null} if the crashed
     *         app doesn't have activity in visible task.
     */
    int finishTopCrashedActivities(WindowProcessController app, String reason) {
    @Nullable
    Task finishTopCrashedActivities(WindowProcessController app, String reason) {
        Task focusedRootTask = getTopDisplayFocusedRootTask();
        final Task[] finishedTask = new Task[1];
        forAllRootTasks(rootTask -> {
            final boolean recordTopOrVisible = finishedTask[0] == null
                    && (focusedRootTask == rootTask || rootTask.isVisibleRequested());
            final Task t = rootTask.finishTopCrashedActivityLocked(app, reason);
            if (rootTask == focusedRootTask || finishedTask[0] == null) {
            if (recordTopOrVisible) {
                finishedTask[0] = t;
            }
        });
        return finishedTask[0] != null ? finishedTask[0].mTaskId : INVALID_TASK_ID;
        return finishedTask[0];
    }

    void ensureVisibilityOnVisibleActivityDiedOrCrashed(String reason) {
        final Task topTask = getTopDisplayFocusedRootTask();
        if (topTask != null && topTask.topRunningActivity(true /* focusableOnly */) == null) {
            // Move the next focusable task to front.
            topTask.adjustFocusToNextFocusableTask(reason);
        }
        if (!resumeFocusedTasksTopActivities()) {
            // It may be nothing to resume because there are pausing activities or all the top
            // activities are resumed. Then it still needs to make sure all visible activities are
            // running in case the tasks were reordered or there are non-top visible activities.
            ensureActivitiesVisible(null /* starting */, 0 /* configChanges */, !PRESERVE_WINDOWS);
        }
    }

    boolean resumeFocusedTasksTopActivities() {
+3 −1
Original line number Diff line number Diff line
@@ -549,10 +549,12 @@ public class RootWindowContainerTests extends WindowTestsBase {

        // Let's pretend that the app has crashed.
        firstActivity.app.setThread(null);
        mRootWindowContainer.finishTopCrashedActivities(firstActivity.app, "test");
        final Task finishedTask = mRootWindowContainer.finishTopCrashedActivities(
                firstActivity.app, "test");

        // Verify that the root task was removed.
        assertEquals(originalRootTaskCount, defaultTaskDisplayArea.getRootTaskCount());
        assertEquals(rootTask, finishedTask);
    }

    /**