diff options
| author | 2016-05-09 10:59:59 -0700 | |
|---|---|---|
| committer | 2016-05-09 11:25:45 -0700 | |
| commit | e22006d936e0928b4a335646f19a8ca18a7fb1e2 (patch) | |
| tree | 9ff67c717d06f23aa2c399d32d21faa65081ef8b | |
| parent | 3a3fb73c753efb2114693b1943246bc6c47f9470 (diff) | |
Fix a flicker when opening app again quickly while it's exiting
If the app is waiting for an opening animation with a dummy placeholder,
we need to skip the surface placement (in addition to the animateLocked).
Also, when animating is changing from exiting to entering, the mAnimating
flag needs to be cleared until the new animation starts. This prevents the
surface placement to place it wrong before the new animaition starts.
bug: 28599295
bug: 27742244
Change-Id: I26f0ead80ee9993a6c766ae8686ab11d1729519c
| -rw-r--r-- | services/core/java/com/android/server/wm/WindowStateAnimator.java | 11 | ||||
| -rw-r--r-- | services/core/java/com/android/server/wm/WindowSurfacePlacer.java | 14 |
2 files changed, 20 insertions, 5 deletions
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java index a0784b5008db..e5f603c7865b 100644 --- a/services/core/java/com/android/server/wm/WindowStateAnimator.java +++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java @@ -322,6 +322,14 @@ class WindowStateAnimator { return mAnimation != null; } + /** + * Is this window currently waiting to run an opening animation? + */ + boolean isWaitingForOpening() { + return mService.mAppTransition.isTransitionSet() && isDummyAnimation() + && mService.mOpeningApps.contains(mWin.mAppToken); + } + void cancelExitAnimationForNextAnimationLocked() { if (DEBUG_ANIM) Slog.d(TAG, "cancelExitAnimationForNextAnimationLocked: " + mWin); @@ -1448,8 +1456,7 @@ class WindowStateAnimator { // the same app again before the app's surface is destroyed or saved, the surface // is always ready in the whole process.) If we go ahead here, the opening app // will be shown with the full size before the correct animation spec arrives. - if (mService.mAppTransition.isTransitionSet() && isDummyAnimation() && - mService.mOpeningApps.contains(w.mAppToken)) { + if (isWaitingForOpening()) { return; } diff --git a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java index fb4be303ced3..e20e245aa574 100644 --- a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java +++ b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java @@ -772,7 +772,7 @@ class WindowSurfacePlacer { } } } - if (!winAnimator.isAnimationStarting()) { + if (!winAnimator.isAnimationStarting() && !winAnimator.isWaitingForOpening()) { // Updates the shown frame before we set up the surface. This is needed // because the resizing could change the top-left position (in addition to // size) of the window. setSurfaceBoundariesLocked uses mShownPosition to @@ -1236,8 +1236,8 @@ class WindowSurfacePlacer { int topOpeningLayer = 0; if (animLp != null) { int layer = -1; - for (int j = 0; j < wtoken.windows.size(); j++) { - final WindowState win = wtoken.windows.get(j); + for (int j = 0; j < wtoken.allAppWindows.size(); j++) { + final WindowState win = wtoken.allAppWindows.get(j); // Clearing the mAnimatingExit flag before entering animation. It will be set to true // if app window is removed, or window relayout to invisible. We don't want to // clear it out for windows that get replaced, because the animation depends on @@ -1249,6 +1249,14 @@ class WindowSurfacePlacer { // they won't eventually be removed by WindowStateAnimator#finishExit. if (!win.mWillReplaceWindow && !win.mRemoveOnExit) { win.mAnimatingExit = false; + // Clear mAnimating flag together with mAnimatingExit. When animation + // changes from exiting to entering, we need to clear this flag until the + // new animation gets applied, so that isAnimationStarting() becomes true + // until then. + // Otherwise applySurfaceChangesTransaction will faill to skip surface + // placement for this window during this period, one or more frame will + // show up with wrong position or scale. + win.mWinAnimator.mAnimating = false; } if (win.mWinAnimator.mAnimLayer > layer) { layer = win.mWinAnimator.mAnimLayer; |