From dba623ae5648923e06157d53fcc0ab8a09a79870 Mon Sep 17 00:00:00 2001 From: Filip Gruszczynski Date: Fri, 4 Dec 2015 15:45:35 -0800 Subject: Don't lose stopping state when getting paused confirmation. 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 | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java index 36a7ceea5853..d62f4df8cde9 100644 --- a/services/core/java/com/android/server/am/ActivityStack.java +++ b/services/core/java/com/android/server/am/ActivityStack.java @@ -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) { -- cgit v1.2.3-59-g8ed1b