OSDN Git Service

Don't lose stopping state when getting paused confirmation.
authorFilip Gruszczynski <gruszczy@google.com>
Fri, 4 Dec 2015 23:45:35 +0000 (15:45 -0800)
committerFilip Gruszczynski <gruszczy@google.com>
Sat, 5 Dec 2015 01:30:52 +0000 (17:30 -0800)
In some cases we request pause and soon after request stop of an
activity. An example of this is maximizing an activity in side by side
mode when recents are visible. First, we add recents to a list of
activities to be stopped (because it becomes invisible), then we request
a pause (because we resume full screen activity and pause all other
stacks) and finally request a stop (from the list to which we added the
request).

The activity now will be put into pausing state (requesting pause), then
stopping (requesting stop), then paused (confirmation comes from the
activity) and stopped (another confirmation comes from activity). If we
switch from stopping to paused, the stop confirmation will become
confused.

Bug: 25729693

Change-Id: I935acd71a28f3d0882f608bdd4d7216cd08ba2eb

services/core/java/com/android/server/am/ActivityStack.java

index 36a7cee..d62f4df 100644 (file)
@@ -1071,6 +1071,7 @@ final class ActivityStack {
         if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Complete pause: " + prev);
 
         if (prev != null) {
+            final boolean wasStopping = prev.state == ActivityState.STOPPING;
             prev.state = ActivityState.PAUSED;
             if (prev.finishing) {
                 if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Executing finish of activity: " + prev);
@@ -1089,9 +1090,15 @@ final class ActivityStack {
                     // the current instance before starting the new one.
                     if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Destroying after pause: " + prev);
                     destroyActivityLocked(prev, true, "pause-config");
+                } else if (wasStopping) {
+                    // We are also stopping, the stop request must have gone soon after the pause.
+                    // We can't clobber it, because the stop confirmation will not be handled.
+                    // We don't need to schedule another stop, we only need to let it happen.
+                    prev.state = ActivityState.STOPPING;
                 } else if (!hasVisibleBehindActivity() || mService.isSleepingOrShuttingDown()) {
                     // If we were visible then resumeTopActivities will release resources before
                     // stopping.
+
                     mStackSupervisor.mStoppingActivities.add(prev);
                     if (mStackSupervisor.mStoppingActivities.size() > 3 ||
                             prev.frontOfTask && mTaskHistory.size() <= 1) {