OSDN Git Service

Cleanup mAnimatingExit flag before maybeUpdateTransitToWallpaper()
authorChong Zhang <chz@google.com>
Wed, 27 Jul 2016 00:47:29 +0000 (17:47 -0700)
committerChong Zhang <chz@google.com>
Wed, 27 Jul 2016 19:10:46 +0000 (12:10 -0700)
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

services/core/java/com/android/server/wm/AppWindowToken.java
services/core/java/com/android/server/wm/WindowSurfacePlacer.java

index eac72b0..a9624cf 100644 (file)
@@ -337,6 +337,30 @@ class AppWindowToken extends WindowToken {
         }
     }
 
+    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 @@ class AppWindowToken extends WindowToken {
 
             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;
             }
index 0bd5eaf..ee4a9a4 100644 (file)
@@ -1138,6 +1138,12 @@ class WindowSurfacePlacer {
                 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 @@ class WindowSurfacePlacer {
                 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;
                     }