diff options
5 files changed, 44 insertions, 7 deletions
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index ee478a5fb7c6..415a06b2f250 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -102,6 +102,10 @@ class DisplayContent { final WindowManagerService mService; + static final int DEFER_DETACH = 1; + static final int DEFER_REMOVAL = 2; + int mDeferredActions; + /** * @param display May not be null. * @param service You know. diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java index ce493d433f48..0941c7685502 100644 --- a/services/core/java/com/android/server/wm/TaskStack.java +++ b/services/core/java/com/android/server/wm/TaskStack.java @@ -137,6 +137,21 @@ public class TaskStack { return mBounds.isEmpty(); } + boolean isAnimating() { + for (int taskNdx = mTasks.size() - 1; taskNdx >= 0; --taskNdx) { + final ArrayList<AppWindowToken> activities = mTasks.get(taskNdx).mAppTokens; + for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { + final ArrayList<WindowState> windows = activities.get(activityNdx).allAppWindows; + for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) { + if (windows.get(winNdx).mWinAnimator.isAnimating()) { + return true; + } + } + } + } + return false; + } + void resizeBounds(float oldWidth, float oldHeight, float newWidth, float newHeight) { if (oldWidth == newWidth && oldHeight == newHeight) { return; @@ -351,6 +366,19 @@ public class TaskStack { mAnimationBackgroundSurface.mDimSurface.destroy(); } + void checkForDeferredDetach() { + if (mDisplayContent != null && + (mDisplayContent.mDeferredActions & DisplayContent.DEFER_DETACH) != 0 && + !isAnimating()) { + mDisplayContent.mDeferredActions &= ~DisplayContent.DEFER_DETACH; + mService.detachStack(mStackId); + if ((mDisplayContent.mDeferredActions & DisplayContent.DEFER_REMOVAL) != 0) { + mDisplayContent.mDeferredActions &= ~DisplayContent.DEFER_REMOVAL; + mService.onDisplayRemoved(mDisplayContent.getDisplayId()); + } + } + } + public void dump(String prefix, PrintWriter pw) { pw.print(prefix); pw.print("mStackId="); pw.println(mStackId); for (int taskNdx = 0; taskNdx < mTasks.size(); ++taskNdx) { diff --git a/services/core/java/com/android/server/wm/WindowAnimator.java b/services/core/java/com/android/server/wm/WindowAnimator.java index 15f8af022929..a9947c05d2b9 100644 --- a/services/core/java/com/android/server/wm/WindowAnimator.java +++ b/services/core/java/com/android/server/wm/WindowAnimator.java @@ -64,7 +64,7 @@ public class WindowAnimator { Object mLastWindowFreezeSource; SparseArray<DisplayContentsAnimator> mDisplayContentsAnimators = - new SparseArray<WindowAnimator.DisplayContentsAnimator>(2); + new SparseArray<DisplayContentsAnimator>(2); boolean mInitialized = false; @@ -451,11 +451,6 @@ public class WindowAnimator { } } - private void performAnimationsLocked(final int displayId) { - updateWindowsLocked(displayId); - updateWallpaperLocked(displayId); - } - /** Locked on mService.mWindowMap. */ private void animateLocked() { @@ -496,7 +491,8 @@ public class WindowAnimator { // Update animations of all applications, including those // associated with exiting/removed apps - performAnimationsLocked(displayId); + updateWindowsLocked(displayId); + updateWallpaperLocked(displayId); final WindowList windows = mService.getWindowListLocked(displayId); final int N = windows.size(); diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 98bed5cb166c..d7f3fa0a9f27 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -4915,6 +4915,10 @@ public class WindowManagerService extends IWindowManager.Stub if (stack != null) { final DisplayContent displayContent = stack.getDisplayContent(); if (displayContent != null) { + if (stack.isAnimating()) { + displayContent.mDeferredActions |= DisplayContent.DEFER_DETACH; + return; + } displayContent.detachStack(stack); stack.detachDisplay(); } @@ -10852,6 +10856,10 @@ public class WindowManagerService extends IWindowManager.Stub private void handleDisplayRemovedLocked(int displayId) { final DisplayContent displayContent = getDisplayContentLocked(displayId); if (displayContent != null) { + if ((displayContent.mDeferredActions & DisplayContent.DEFER_DETACH) != 0) { + displayContent.mDeferredActions |= DisplayContent.DEFER_REMOVAL; + return; + } mDisplayContents.delete(displayId); displayContent.close(); if (displayId == Display.DEFAULT_DISPLAY) { diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java index 76e885f80bed..5cff3197a336 100644 --- a/services/core/java/com/android/server/wm/WindowStateAnimator.java +++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java @@ -416,6 +416,7 @@ class WindowStateAnimator { mService.mPendingRemove.add(mWin); mWin.mRemoveOnExit = false; } + mWin.getStack().checkForDeferredDetach(); mAnimator.hideWallpapersLocked(mWin); } |