am 1bf2b873: Defer detach until animations are complete.
* commit '1bf2b873470d2ba8a4ac218da73516cc2b20aa76':
Defer detach until animations are complete.
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index ee478a5..415a06b 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 @@
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 ce493d4..0941c76 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 @@
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 @@
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 15f8af0..a9947c0 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 @@
Object mLastWindowFreezeSource;
SparseArray<DisplayContentsAnimator> mDisplayContentsAnimators =
- new SparseArray<WindowAnimator.DisplayContentsAnimator>(2);
+ new SparseArray<DisplayContentsAnimator>(2);
boolean mInitialized = false;
@@ -451,11 +451,6 @@
}
}
- private void performAnimationsLocked(final int displayId) {
- updateWindowsLocked(displayId);
- updateWallpaperLocked(displayId);
- }
-
/** Locked on mService.mWindowMap. */
private void animateLocked() {
@@ -496,7 +491,8 @@
// 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 6f6b67e..0591175 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -4917,6 +4917,10 @@
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();
}
@@ -10848,6 +10852,10 @@
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 76e885f..5cff319 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 @@
mService.mPendingRemove.add(mWin);
mWin.mRemoveOnExit = false;
}
+ mWin.getStack().checkForDeferredDetach();
mAnimator.hideWallpapersLocked(mWin);
}