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

Commit edc42940 authored by Riddle Hsu's avatar Riddle Hsu
Browse files

Handle stopping and finishing activities on drawn

If the non idle activity is started in a new task, there may have
a starting window. So the transition animation can be done with
the starting window but the main window of the activity may not
finish drawing if it is slow during startup. That causes the
allResumedActivitiesVisible to return false and the stopping
activities are still pending.

By scheduling to process stopping and finishing when the activity
windows are actually drawn (though its name is onWindowsVisible,
it is only called if the windows are drawn, see numVisible), the
pending stopping activities no longer need to wait until idle timeout
to be stopped or destroyed.

Also avoid sending duplicated idle message.

Bug: 169740664
Test: atest ActivityVisibilityTests# \
      testActivityStoppedWhileNextActivityNotIdle
Change-Id: I7317bf577a1b98601b6ec027a5d7bf66090aecde
parent 5683fda3
Loading
Loading
Loading
Loading
+9 −16
Original line number Diff line number Diff line
@@ -5862,6 +5862,12 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
            nowVisible = true;
            lastVisibleTime = SystemClock.uptimeMillis();
            mAtmService.scheduleAppGcsLocked();
            // The nowVisible may be false in onAnimationFinished because the transition animation
            // was started by starting window but the main window hasn't drawn so the procedure
            // didn't schedule. Hence also check when nowVisible becomes true (drawn) to avoid the
            // closing activity having to wait until idle timeout to be stopped or destroyed if the
            // next activity won't report idle (e.g. repeated view animation).
            mTaskSupervisor.scheduleProcessStoppingAndFinishingActivitiesIfNeeded();
        }
    }

@@ -6682,22 +6688,9 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
        getDisplayContent().mAppTransition.notifyAppTransitionFinishedLocked(token);
        scheduleAnimation();

        if (!mTaskSupervisor.mStoppingActivities.isEmpty()
                || !mTaskSupervisor.mFinishingActivities.isEmpty()) {
            if (mRootWindowContainer.allResumedActivitiesIdle()) {
                // If all activities are already idle then we now need to make sure we perform
                // the full stop of this activity. This is because we won't do that while they
                // are still waiting for the animation to finish.
                mTaskSupervisor.scheduleIdle();
            } else if (mRootWindowContainer.allResumedActivitiesVisible()) {
                // If all resumed activities are already visible (and should be drawn, see
                // updateReportedVisibility ~ nowVisible) but not idle, we still schedule to
                // process the stopping and finishing activities because the transition is done.
                // This also avoids if the next activity never reports idle (e.g. animating view),
                // the previous will need to wait until idle timeout to be stopped or destroyed.
                mTaskSupervisor.scheduleProcessStoppingAndFinishingActivities();
            }
        }
        // Schedule to handle the stopping and finishing activities which the animation is done
        // because the activities which were animating have not been stopped yet.
        mTaskSupervisor.scheduleProcessStoppingAndFinishingActivitiesIfNeeded();
        Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
    }

+7 −3
Original line number Diff line number Diff line
@@ -2027,8 +2027,10 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
    }

    final void scheduleIdle() {
        if (!mHandler.hasMessages(IDLE_NOW_MSG)) {
            mHandler.sendEmptyMessage(IDLE_NOW_MSG);
        }
    }

    /**
     * Updates the record of top resumed activity when it changes and handles reporting of the
@@ -2115,8 +2117,10 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
        }
    }

    void scheduleProcessStoppingAndFinishingActivities() {
        if (!mHandler.hasMessages(PROCESS_STOPPING_AND_FINISHING_MSG)) {
    void scheduleProcessStoppingAndFinishingActivitiesIfNeeded() {
        if ((!mStoppingActivities.isEmpty() || !mFinishingActivities.isEmpty())
                && !mHandler.hasMessages(PROCESS_STOPPING_AND_FINISHING_MSG)
                && mRootWindowContainer.allResumedActivitiesVisible()) {
            mHandler.sendEmptyMessage(PROCESS_STOPPING_AND_FINISHING_MSG);
        }
    }