[ActivityManager] Finish the failed-to-pause activity
Symptom:
In some scenario, the mPausingActivity may be replaced by other
activity. When previous activity paused, the completePausedLocked()
won't be invoked because it is no longer the mPausingActivity. If
the activity is also pending to finish, it would never be done
because the activity kept in PAUSING state. Since the activity's
window also remain visible and is above on Wallpaper, user would
see it when back to home.
Solution:
Finish the failed-to-pause activity if the activity is pending to
finish.
A Real Case:
(1) Screen turn off
(2) The top activity T1 crashed
(3) When finish activity T1, the next top activity T2 will be
scheduled to resume and pause (due to screen off).
(4) The activity T2 is also set to finishing due to T1 crashed.
(5) Before T2 paused and before paused timeout occurs, there has
a new process started which brings up the next top activity T3
to resume and pause. So the pausing activity is now replaced.
(6) When activity T2 paused, it cannot completed the pause operation
T2 will remain in PAUSING and finishing state with its window
visible. The process won't be killed because the oomadj stays
at 1 (Visible).
Change-Id: Ib10fded891b21c774b26a93071c717fa50516e22
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index 9f22aa9..6fb488a 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -899,6 +899,11 @@
r.userId, System.identityHashCode(r), r.shortComponentName,
mPausingActivity != null
? mPausingActivity.shortComponentName : "(none)");
+ if (r.finishing && r.state == ActivityState.PAUSING) {
+ if (DEBUG_PAUSE) Slog.v(TAG,
+ "Executing finish of failed to pause activity: " + r);
+ finishCurrentActivityLocked(r, FINISH_AFTER_VISIBLE, false);
+ }
}
}
}