Cleanup mAnimatingExit flag before maybeUpdateTransitToWallpaper()
If we get onStopped before next resume, but previous exit animation
doesn't finish by the time the entering animation is started,
notifyAppResumed() won't do a surface cleanup (since it's already
stopped). Then maybeUpdateTransitToWallpaper() will think the wallpaper
target (launcher) is invisible because of the mAnimatingExit==true,
thus fails to pick WALLPAPER_OPEN animation.
We need to clear mAnimatingExit and relevant flags before
maybeUpdateTransitToWallpaper(). Currently we do it in handleOpeningApps
but that's too late.
bug: 30255354
Change-Id: Idb049c54978824709a190c413d82d42f40226aa7
diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java
index eac72b0..a9624cf 100644
--- a/services/core/java/com/android/server/wm/AppWindowToken.java
+++ b/services/core/java/com/android/server/wm/AppWindowToken.java
@@ -337,6 +337,30 @@
}
}
+ void clearAnimatingFlags() {
+ for (int i = allAppWindows.size() - 1; i >= 0; i--) {
+ final WindowState win = allAppWindows.get(i);
+ // We don't want to clear it out for windows that get replaced, because the
+ // animation depends on the flag to remove the replaced window.
+ //
+ // We also don't clear the mAnimatingExit flag for windows which have the
+ // mRemoveOnExit flag. This indicates an explicit remove request has been issued
+ // by the client. We should let animation proceed and not clear this flag or
+ // 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;
+ }
+ }
+ }
+
void destroySurfaces() {
destroySurfaces(false /*cleanupOnResume*/);
}
@@ -363,15 +387,6 @@
win.mWinAnimator.destroyPreservedSurfaceLocked();
- if (cleanupOnResume) {
- // If the window has an unfinished exit animation, consider that animation
- // done and mark the window destroying so that it goes through the cleanup.
- if (win.mAnimatingExit) {
- win.mDestroying = true;
- win.mAnimatingExit = false;
- }
- }
-
if (!win.mDestroying) {
continue;
}
diff --git a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
index 0bd5eaf..ee4a9a4 100644
--- a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
+++ b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
@@ -1138,6 +1138,12 @@
if (wtoken == lowerWallpaperAppToken || wtoken == upperWallpaperAppToken) {
openingAppHasWallpaper = true;
}
+ // Clearing the mAnimatingExit flag before entering animation. It's set to
+ // true if app window is removed, or window relayout to invisible.
+ // This also affects window visibility. We need to clear it *before*
+ // maybeUpdateTransitToWallpaper() as the transition selection depends on
+ // wallpaper target visibility.
+ wtoken.clearAnimatingFlags();
}
voiceInteraction |= wtoken.voiceInteraction;
@@ -1262,26 +1268,6 @@
int layer = -1;
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
- // the flag to remove the replaced window.
- //
- // We also don't clear the mAnimatingExit flag for windows which have the
- // mRemoveOnExit flag. This indicates an explicit remove request has been issued
- // by the client. We should let animation proceed and not clear this flag or
- // 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;
}