From c0c9324fcb03c85ef7bed2d997c441119823d31c Mon Sep 17 00:00:00 2001 From: Jorim Jaggi Date: Fri, 4 Aug 2017 16:05:02 +0200 Subject: [PATCH] Fix light bar flickers There was a time in which no window was mTopFullscreenOpaqueWS when switching between two apps because the previous one was exiting already before the next one was shown. Fix this by only considering a window to be exiting after the animation actually has started. In that case the surface of the incoming window will be visible already. Test: go/wm-smoke Test: Open Cast settings, go home with light wallpaper set Change-Id: I89a85d5fbfe1618940b398cd26a8d5fe53be12fb Fixes: 64291272 --- .../com/android/server/wm/AppWindowAnimator.java | 8 ++++++++ .../java/com/android/server/wm/WindowState.java | 14 ++++++++++++-- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/services/core/java/com/android/server/wm/AppWindowAnimator.java b/services/core/java/com/android/server/wm/AppWindowAnimator.java index f3a09ed14936f..ddbbde1eb4218 100644 --- a/services/core/java/com/android/server/wm/AppWindowAnimator.java +++ b/services/core/java/com/android/server/wm/AppWindowAnimator.java @@ -198,6 +198,14 @@ public class AppWindowAnimator { return animation != null || mAppToken.inPendingTransaction; } + /** + * @return whether an animation is about to start, i.e. the animation is set already but we + * haven't processed the first frame yet. + */ + boolean isAnimationStarting() { + return animation != null && !animating; + } + public int getTransit() { return mTransit; } diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index 81c5164534a5c..58819144949e4 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -1457,8 +1457,18 @@ class WindowState extends WindowContainer implements WindowManagerP @Override public boolean canAffectSystemUiFlags() { final boolean shown = mWinAnimator.getShown(); - final boolean exiting = mAnimatingExit || mDestroying - || mAppToken != null && mAppToken.hidden; + + // We only consider the app to be exiting when the animation has started. After the app + // transition is executed the windows are marked exiting before the new windows have been + // shown. Thus, wait considering a window to be exiting after the animation has actually + // started. + final boolean appAnimationStarting = mAppToken != null + && mAppToken.mAppAnimator.isAnimationStarting(); + final boolean exitingSelf = mAnimatingExit && (!mWinAnimator.isAnimationStarting() + && !appAnimationStarting); + final boolean appExiting = mAppToken != null && mAppToken.hidden && !appAnimationStarting; + + final boolean exiting = exitingSelf || mDestroying || appExiting; final boolean translucent = mAttrs.alpha == 0.0f; return shown && !exiting && !translucent; }