From 2c596d57535a1d8c327457931dfc835608b677a4 Mon Sep 17 00:00:00 2001 From: Wale Ogunwale Date: Thu, 6 Jul 2017 15:30:55 -0700 Subject: Don't remove starting window for visible app. Activity manager agressively removes starting windows to avoid leaks. See ag/696830 and ag/1213075 for some history. However, it is possible for window manager to process the request of removing the starting window coming from activity manager while the app token for the starting window is still visible from the window manager side because we are delaying hiding it due to an animation in progress. We now only process the request to remove starting window from the activity manager side if the app is hidden on the window manager side. Change-Id: Ia33076f0e7405f9430e9d4e9d4026ae6fd1b133e Fixes: 62443388 Test: go/wm-smoke Test: Swipe Gmail away in Recents, launch Chome, press home button, launch Gmail, and press the home button. --- .../java/com/android/server/am/ActivityRecord.java | 2 +- .../server/wm/AppWindowContainerController.java | 18 +++++++++++++++++- .../java/com/android/server/wm/AppWindowToken.java | 11 ++++++++--- 3 files changed, 26 insertions(+), 5 deletions(-) diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java index 68f4d0d99f93..6a8f6d35c7c0 100644 --- a/services/core/java/com/android/server/am/ActivityRecord.java +++ b/services/core/java/com/android/server/am/ActivityRecord.java @@ -2184,7 +2184,7 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo if (mStartingWindowState == STARTING_WINDOW_SHOWN && behindFullscreenActivity) { if (DEBUG_VISIBILITY) Slog.w(TAG_VISIBILITY, "Found orphaned starting window " + this); mStartingWindowState = STARTING_WINDOW_REMOVED; - mWindowContainerController.removeStartingWindow(); + mWindowContainerController.removeHiddenStartingWindow(); } } diff --git a/services/core/java/com/android/server/wm/AppWindowContainerController.java b/services/core/java/com/android/server/wm/AppWindowContainerController.java index cea8ee108201..86e130d723d8 100644 --- a/services/core/java/com/android/server/wm/AppWindowContainerController.java +++ b/services/core/java/com/android/server/wm/AppWindowContainerController.java @@ -647,7 +647,23 @@ public class AppWindowContainerController return mContainer.getTask().getConfiguration().orientation == snapshot.getOrientation(); } - public void removeStartingWindow() { + /** + * Remove starting window if the app is currently hidden. It is possible the starting window is + * part of its app exit transition animation in which case we delay hiding the app token. The + * method allows for removal when window manager has set the app token to hidden. + */ + public void removeHiddenStartingWindow() { + synchronized (mWindowMap) { + if (!mContainer.hidden) { + if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Starting window app still visible." + + " Ignoring remove request."); + return; + } + removeStartingWindow(); + } + } + + void removeStartingWindow() { synchronized (mWindowMap) { if (mHandler.hasCallbacks(mRemoveStartingWindow)) { // Already scheduled. diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java index ce44dab8fc09..839ee0ec7efd 100644 --- a/services/core/java/com/android/server/wm/AppWindowToken.java +++ b/services/core/java/com/android/server/wm/AppWindowToken.java @@ -441,6 +441,7 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree mChildren.get(i).mWinAnimator.hide("immediately hidden"); } SurfaceControl.closeTransaction(); + removeStartingWindow(); } if (!mService.mClosingApps.contains(this) && !mService.mOpeningApps.contains(this)) { @@ -518,6 +519,12 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree return super.checkCompleteDeferredRemoval(); } + private void removeStartingWindow() { + if (startingData != null && getController() != null) { + getController().removeStartingWindow(); + } + } + void onRemovedFromDisplay() { if (mRemovingFromDisplay) { return; @@ -545,9 +552,7 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG_WM, "removeAppToken: " + this + " delayed=" + delayed + " Callers=" + Debug.getCallers(4)); - if (startingData != null && getController() != null) { - getController().removeStartingWindow(); - } + removeStartingWindow(); // If this window was animating, then we need to ensure that the app transition notifies // that animations have completed in WMS.handleAnimatingStoppedAndTransitionLocked(), so -- cgit v1.2.3-59-g8ed1b