diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java index e513713895e0f..e69cb292fb404 100644 --- a/services/core/java/com/android/server/wm/AppWindowToken.java +++ b/services/core/java/com/android/server/wm/AppWindowToken.java @@ -541,6 +541,7 @@ class AppWindowToken extends WindowToken { if (candidate.mWillReplaceWindow && candidate.mReplacingWindow == null && candidate.getWindowTag().equals(w.getWindowTag().toString())) { candidate.mReplacingWindow = w; + w.mSkipEnterAnimationForSeamlessReplacement = !candidate.mAnimateReplacingWindow; // if we got a replacement window, reset the timeout to give drawing more time service.mH.removeMessages(H.WINDOW_REPLACEMENT_TIMEOUT); @@ -575,6 +576,9 @@ class AppWindowToken extends WindowToken { continue; } candidate.mWillReplaceWindow = false; + if (candidate.mReplacingWindow != null) { + candidate.mReplacingWindow.mSkipEnterAnimationForSeamlessReplacement = false; + } // Since the window already timed out, remove it immediately now. // Use removeWindowInnerLocked() instead of removeWindowLocked(), as the latter // delays removal on certain conditions, which will leave the stale window in the diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index 1dc486c3182be..43cc8c75734b2 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -445,6 +445,11 @@ final class WindowState implements WindowManagerPolicy.WindowState { // If not null, the window that will be used to replace the old one. This is being set when // the window is added and unset when this window reports its first draw. WindowState mReplacingWindow = null; + // For the new window in the replacement transition, if we have + // requested to replace without animation, then we should + // make sure we also don't apply an enter animation for + // the new window. + boolean mSkipEnterAnimationForSeamlessReplacement = false; // Whether this window is being moved via the resize API boolean mMovedByResize; @@ -1574,6 +1579,7 @@ final class WindowState implements WindowManagerPolicy.WindowState { win.mAnimateReplacingWindow = false; win.mReplacingRemoveRequested = false; win.mReplacingWindow = null; + mSkipEnterAnimationForSeamlessReplacement = false; if (win.mAnimatingExit) { mService.removeWindowInnerLocked(win); } diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java index 9c25f63dfa2ab..3267f5c831486 100644 --- a/services/core/java/com/android/server/wm/WindowStateAnimator.java +++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java @@ -1661,6 +1661,12 @@ class WindowStateAnimator { } void applyEnterAnimationLocked() { + // If we are the new part of a window replacement transition and we have requested + // not to animate, we instead want to make it seamless, so we don't want to apply + // an enter transition. + if (mWin.mSkipEnterAnimationForSeamlessReplacement) { + return; + } final int transit; if (mEnterAnimationPending) { mEnterAnimationPending = false;