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

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

Reports top resumed activity state loss when no focused task

There was no other focusable task while the top resumed activity
finished. So, the system didn’t report top-resumed-loss at that
moment, but was reported to the client after home activity started
and resumed afterward. That resulted in an app crash since the
activity client record was already destroyed.

Bug: 284552716
Test: verified locally by keeping one focused app task and
      force stopped all others tasks
Change-Id: Ibe6d38e1c4db328b8bfc7bae70fd14ba6f131a25
parent fae45798
Loading
Loading
Loading
Loading
+22 −10
Original line number Diff line number Diff line
@@ -2367,6 +2367,10 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
        final ActivityRecord prevTopActivity = mTopResumedActivity;
        final Task topRootTask = mRootWindowContainer.getTopDisplayFocusedRootTask();
        if (topRootTask == null || topRootTask.getTopResumedActivity() == prevTopActivity) {
            if (topRootTask == null) {
                // There's no focused task and there won't have any resumed activity either.
                scheduleTopResumedActivityStateLossIfNeeded();
            }
            if (mService.isSleepingLocked()) {
                // There won't be a next resumed activity. The top process should still be updated
                // according to the current top focused activity.
@@ -2376,16 +2380,7 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
        }

        // Ask previous activity to release the top state.
        final boolean prevActivityReceivedTopState =
                prevTopActivity != null && !mTopResumedActivityWaitingForPrev;
        // mTopResumedActivityWaitingForPrev == true at this point would mean that an activity
        // before the prevTopActivity one hasn't reported back yet. So server never sent the top
        // resumed state change message to prevTopActivity.
        if (prevActivityReceivedTopState
                && prevTopActivity.scheduleTopResumedActivityChanged(false /* onTop */)) {
            scheduleTopResumedStateLossTimeout(prevTopActivity);
            mTopResumedActivityWaitingForPrev = true;
        }
        scheduleTopResumedActivityStateLossIfNeeded();

        // Update the current top activity.
        mTopResumedActivity = topRootTask.getTopResumedActivity();
@@ -2410,6 +2405,23 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
        mService.updateTopApp(mTopResumedActivity);
    }

    /** Schedule current top resumed activity state loss */
    private void scheduleTopResumedActivityStateLossIfNeeded() {
        if (mTopResumedActivity == null) {
            return;
        }

        // mTopResumedActivityWaitingForPrev == true at this point would mean that an activity
        // before the prevTopActivity one hasn't reported back yet. So server never sent the top
        // resumed state change message to prevTopActivity.
        if (!mTopResumedActivityWaitingForPrev
                && mTopResumedActivity.scheduleTopResumedActivityChanged(false /* onTop */)) {
            scheduleTopResumedStateLossTimeout(mTopResumedActivity);
            mTopResumedActivityWaitingForPrev = true;
            mTopResumedActivity = null;
        }
    }

    /** Schedule top resumed state change if previous top activity already reported back. */
    private void scheduleTopResumedActivityStateIfNeeded() {
        if (mTopResumedActivity != null && !mTopResumedActivityWaitingForPrev) {