Defer detach until animations are complete.

Allowing the detach of ActivityStack from DisplayContent to happen
immediately was causing all sorts of problems associated with not
having a Display to complete the animations.

Waiting for animations to complete before either the detach or the
display removal fixes those problems.

Change-Id: I8a5663bfac5c3c1084ff4fcc451e0e38e8080265
This commit is contained in:
Craig Mautner
2014-02-05 15:37:40 -08:00
parent dc548483ae
commit 1bf2b87347
5 changed files with 44 additions and 7 deletions

View File

@@ -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.

View File

@@ -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) {

View File

@@ -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();

View File

@@ -4917,6 +4917,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();
}
@@ -10848,6 +10852,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) {

View File

@@ -416,6 +416,7 @@ class WindowStateAnimator {
mService.mPendingRemove.add(mWin);
mWin.mRemoveOnExit = false;
}
mWin.getStack().checkForDeferredDetach();
mAnimator.hideWallpapersLocked(mWin);
}