Merge "Move surface save state tracking to WindowState."
diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java
index 3d00e02..23ad1a81b 100644
--- a/services/core/java/com/android/server/wm/AppWindowToken.java
+++ b/services/core/java/com/android/server/wm/AppWindowToken.java
@@ -54,10 +54,6 @@
 
     final boolean voiceInteraction;
 
-    // Whether the window has a saved surface from last pause, which can be
-    // used to start an entering animation earlier.
-    boolean mHasSavedSurface;
-
     // Whether we're performing an entering animation with a saved surface.
     boolean mAnimatingWithSavedSurface;
 
@@ -316,39 +312,38 @@
         // currently animating with save surfaces. (If the app didn't even finish
         // drawing when the user exits, but we have a saved surface from last time,
         // we still want to keep that surface.)
-        mHasSavedSurface = allDrawn || mAnimatingWithSavedSurface;
-        if (mHasSavedSurface) {
-            if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG,
-                    "Saving surface: " + this);
-            return true;
+        return allDrawn || mAnimatingWithSavedSurface;
+    }
+
+    boolean hasSavedSurface() {
+        for (int i = windows.size() -1; i >= 0; i--) {
+            final WindowState ws = windows.get(i);
+            if (ws.hasSavedSurface()) {
+                return true;
+            }
         }
         return false;
     }
 
     void restoreSavedSurfaces() {
-        if (!mHasSavedSurface) {
+        if (!hasSavedSurface()) {
             return;
         }
 
         if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG,
                 "Restoring saved surfaces: " + this + ", allDrawn=" + allDrawn);
 
-        mHasSavedSurface = false;
         mAnimatingWithSavedSurface = true;
         for (int i = windows.size() - 1; i >= 0; i--) {
             WindowState ws = windows.get(i);
-            ws.mWinAnimator.mDrawState = WindowStateAnimator.READY_TO_SHOW;
+            ws.restoreSavedSurface();
         }
     }
 
     void destroySavedSurfaces() {
-        if (mHasSavedSurface) {
-            if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG,
-                    "Destroying saved surface: " + this);
-            for (int i = windows.size() - 1; i >= 0; i--) {
-                final WindowState win = windows.get(i);
-                win.mWinAnimator.destroySurfaceLocked();
-            }
+        for (int i = windows.size() - 1; i >= 0; i--) {
+            WindowState win = windows.get(i);
+            win.destroySavedSurface();
         }
     }
 
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 0b851da..5237a13 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -2816,9 +2816,7 @@
             if (mInputMethodWindow == win) {
                 mInputMethodWindow = null;
             }
-            if (!win.shouldSaveSurface()) {
-                winAnimator.destroySurfaceLocked();
-            }
+            win.destroyOrSaveSurface();
         }
         //TODO (multidisplay): Magnification is supported only for the default
         if (mAccessibilityController != null
@@ -8985,11 +8983,10 @@
                             Slog.w(TAG, "LEAKED SURFACE (app token hidden): "
                                     + ws + " surface=" + wsa.mSurfaceController
                                     + " token=" + ws.mAppToken
-                                    + " saved=" + ws.mAppToken.mHasSavedSurface);
+                                    + " saved=" + ws.mAppToken.hasSavedSurface());
                             if (SHOW_TRANSACTIONS) logSurface(ws, "LEAK DESTROY", null);
                             wsa.destroySurface();
                             ws.setHasSurface(false);
-                            ws.mAppToken.mHasSavedSurface = false;
                             leakedSurface = true;
                         }
                     }
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 5e38492..c9ded3a 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -84,6 +84,8 @@
 import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG;
 import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
 import static com.android.server.wm.WindowManagerService.DEBUG_ADD_REMOVE;
+import static com.android.server.wm.WindowManagerService.DEBUG_ANIM;
+import static com.android.server.wm.WindowManagerService.DEBUG_APP_TRANSITIONS;
 import static com.android.server.wm.WindowManagerService.DEBUG_CONFIGURATION;
 import static com.android.server.wm.WindowManagerService.DEBUG_FOCUS_LIGHT;
 import static com.android.server.wm.WindowManagerService.DEBUG_LAYOUT;
@@ -402,6 +404,10 @@
     /** When true this window can be displayed on screens owther than mOwnerUid's */
     private boolean mShowToOwnerOnly;
 
+    // Whether the window has a saved surface from last pause, which can be
+    // used to start an entering animation earlier.
+    public boolean mSurfaceSaved = false;
+
     /**
      * Wake lock for drawing.
      * Even though it's slightly more expensive to do so, we will use a separate wake lock
@@ -1670,22 +1676,45 @@
         return mAppToken != null && mAppToken.mAnimatingWithSavedSurface;
     }
 
-    boolean shouldSaveSurface() {
+    // Returns true if the surface is saved.
+    boolean destroyOrSaveSurface() {
+        Task task = getTask();
         if (ActivityManager.isLowRamDeviceStatic()) {
             // Don't save surfaces on Svelte devices.
-            return false;
-        }
-
-        Task task = getTask();
-        if (task == null || task.inHomeStack()
+            mSurfaceSaved = false;
+        } else if (task == null || task.inHomeStack()
                 || task.getTopVisibleAppToken() != mAppToken) {
             // Don't save surfaces for home stack apps. These usually resume and draw
             // first frame very fast. Saving surfaces are mostly a waste of memory.
             // Don't save if the window is not the topmost window.
-            return false;
+            mSurfaceSaved = false;
+        } else if (mAttachedWindow != null) {
+            mSurfaceSaved = false;
+        } else {
+            mSurfaceSaved = mAppToken.shouldSaveSurface();
         }
+        if (mSurfaceSaved == false) {
+            mWinAnimator.destroySurfaceLocked();
+        }
+        return mSurfaceSaved;
+    }
 
-        return mAppToken.shouldSaveSurface();
+    public void destroySavedSurface() {
+        if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG,
+                "Destroying saved surface: " + this);
+
+        if (mSurfaceSaved) {
+            mWinAnimator.destroySurfaceLocked();
+        }
+    }
+
+    public boolean hasSavedSurface() {
+        return mSurfaceSaved;
+    }
+
+    public void restoreSavedSurface() {
+        mSurfaceSaved = false;
+        mWinAnimator.mDrawState = WindowStateAnimator.READY_TO_SHOW;
     }
 
     @Override
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index 132b1b6..1790fb3 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -726,13 +726,14 @@
     void destroySurfaceLocked() {
         final AppWindowToken wtoken = mWin.mAppToken;
         if (wtoken != null) {
-            wtoken.mHasSavedSurface = false;
             wtoken.mAnimatingWithSavedSurface = false;
             if (mWin == wtoken.startingWindow) {
                 wtoken.startingDisplayed = false;
             }
         }
 
+        mWin.mSurfaceSaved = false;
+
         if (mSurfaceController != null) {
             int i = mWin.mChildWindows.size();
             // When destroying a surface we want to make sure child windows
diff --git a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
index 2149019..3ae3be5 100644
--- a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
+++ b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
@@ -394,9 +394,7 @@
                 if (mWallpaperControllerLocked.isWallpaperTarget(win)) {
                     wallpaperDestroyed = true;
                 }
-                if (!win.shouldSaveSurface()) {
-                    win.mWinAnimator.destroySurfaceLocked();
-                }
+                win.destroyOrSaveSurface();
             } while (i > 0);
             mService.mDestroySurface.clear();
         }
@@ -1252,7 +1250,7 @@
                         + wtoken.startingDisplayed + " startingMoved="
                         + wtoken.startingMoved);
 
-                if (wtoken.mHasSavedSurface || wtoken.mAnimatingWithSavedSurface) {
+                if (wtoken.hasSavedSurface() || wtoken.mAnimatingWithSavedSurface) {
                     continue;
                 }
                 if (!wtoken.allDrawn && !wtoken.startingDisplayed && !wtoken.startingMoved) {