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:
@@ -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.
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -416,6 +416,7 @@ class WindowStateAnimator {
|
||||
mService.mPendingRemove.add(mWin);
|
||||
mWin.mRemoveOnExit = false;
|
||||
}
|
||||
mWin.getStack().checkForDeferredDetach();
|
||||
mAnimator.hideWallpapersLocked(mWin);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user