Merge "Further isolate the Surface from WindowState."
diff --git a/services/java/com/android/server/wm/AppWindowToken.java b/services/java/com/android/server/wm/AppWindowToken.java
index d1f1b44..09e99a5 100644
--- a/services/java/com/android/server/wm/AppWindowToken.java
+++ b/services/java/com/android/server/wm/AppWindowToken.java
@@ -376,7 +376,8 @@
         int numDrawn = 0;
         boolean nowGone = true;
 
-        if (WindowManagerService.DEBUG_VISIBILITY) Slog.v(WindowManagerService.TAG, "Update reported visibility: " + this);
+        if (WindowManagerService.DEBUG_VISIBILITY) Slog.v(WindowManagerService.TAG,
+                "Update reported visibility: " + this);
         final int N = allAppWindows.size();
         for (int i=0; i<N; i++) {
             WindowState win = allAppWindows.get(i);
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index f84838b..20fa290 100644
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -2314,7 +2314,7 @@
         // to hold off on removing the window until the animation is done.
         // If the display is frozen, just remove immediately, since the
         // animation wouldn't be seen.
-        if (win.mWinAnimator.mSurface != null && okToDisplay()) {
+        if (win.mHasSurface && okToDisplay()) {
             // If we are not currently running the exit animation, we
             // need to see about starting one.
             wasVisible = win.isWinVisibleLw();
@@ -2458,8 +2458,7 @@
     }
 
     static void logSurface(WindowState w, String msg, RuntimeException where) {
-        String str = "  SURFACE " + Integer.toHexString(w.hashCode())
-                + ": " + msg + " / " + w.mAttrs.getTitle();
+        String str = "  SURFACE " + msg + ": " + w;
         if (where != null) {
             Slog.i(TAG, str, where);
         } else {
@@ -2481,15 +2480,14 @@
         try {
             synchronized (mWindowMap) {
                 WindowState w = windowForClientLocked(session, client, false);
-                WindowStateAnimator winAnimator = w.mWinAnimator;
-                if ((w != null) && (winAnimator.mSurface != null)) {
+                if ((w != null) && w.mHasSurface) {
                     if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
                             ">>> OPEN TRANSACTION setTransparentRegion");
                     Surface.openTransaction();
                     try {
                         if (SHOW_TRANSACTIONS) logSurface(w,
                                 "transparentRegionHint=" + region, null);
-                        winAnimator.mSurface.setTransparentRegionHint(region);
+                        w.mWinAnimator.mSurface.setTransparentRegionHint(region);
                     } finally {
                         Surface.closeTransaction();
                         if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
@@ -2618,10 +2616,10 @@
 
         synchronized(mWindowMap) {
             WindowState win = windowForClientLocked(session, client, false);
-            WindowStateAnimator winAnimator = win.mWinAnimator;
             if (win == null) {
                 return 0;
             }
+            WindowStateAnimator winAnimator = win.mWinAnimator;
             if (win.mRequestedWidth != requestedWidth
                     || win.mRequestedHeight != requestedHeight) {
                 win.mLayoutNeeded = true;
@@ -2702,6 +2700,7 @@
                 displayed = !win.isVisibleLw();
                 if (win.mExiting) {
                     winAnimator.cancelExitAnimationForNextAnimationLocked();
+                    win.mExiting = false;
                 }
                 if (win.mDestroying) {
                     win.mDestroying = false;
@@ -2740,7 +2739,7 @@
                     surfaceChanged = true;
                 }
                 try {
-                    if (winAnimator.mSurface == null) {
+                    if (!win.mHasSurface) {
                         surfaceChanged = true;
                     }
                     Surface surface = winAnimator.createSurfaceLocked();
@@ -3416,15 +3415,13 @@
     }
 
     public int getOrientationFromAppTokensLocked() {
-        int pos = mAppTokens.size() - 1;
         int curGroup = 0;
         int lastOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
         boolean findingBehind = false;
         boolean haveGroup = false;
         boolean lastFullscreen = false;
-        while (pos >= 0) {
+        for (int pos = mAppTokens.size() - 1; pos >= 0; pos--) {
             AppWindowToken wtoken = mAppTokens.get(pos);
-            pos--;
 
             if (DEBUG_APP_ORIENTATION) Slog.v(TAG, "Checking app orientation: " + wtoken);
 
@@ -4138,7 +4135,7 @@
                 WindowState w = wtoken.allAppWindows.get(i);
                 if (w.mAppFreezing) {
                     w.mAppFreezing = false;
-                    if (w.mWinAnimator.mSurface != null && !w.mOrientationChanging) {
+                    if (w.mHasSurface && !w.mOrientationChanging) {
                         if (DEBUG_ORIENTATION) Slog.v(TAG, "set mOrientationChanging of " + w);
                         w.mOrientationChanging = true;
                     }
@@ -4726,7 +4723,7 @@
         synchronized(mWindowMap) {
             for (int i=mWindows.size()-1; i>=0; i--) {
                 WindowState w = mWindows.get(i);
-                if (w.mWinAnimator.mSurface != null) {
+                if (w.mHasSurface) {
                     try {
                         w.mClient.closeSystemDialogs(reason);
                     } catch (RemoteException e) {
@@ -5198,7 +5195,7 @@
             boolean including = false;
             for (int i=mWindows.size()-1; i>=0; i--) {
                 WindowState ws = mWindows.get(i);
-                if (ws.mWinAnimator.mSurface == null) {
+                if (!ws.mHasSurface) {
                     continue;
                 }
                 if (ws.mLayer >= aboveAppLayer) {
@@ -5512,7 +5509,7 @@
 
         for (int i=mWindows.size()-1; i>=0; i--) {
             WindowState w = mWindows.get(i);
-            if (w.mWinAnimator.mSurface != null) {
+            if (w.mHasSurface) {
                 if (DEBUG_ORIENTATION) Slog.v(TAG, "Set mOrientationChanging of " + w);
                 w.mOrientationChanging = true;
             }
@@ -8027,7 +8024,7 @@
             mAnimator.mForceHiding = false;
             for (int i=mWindows.size()-1; i>=0; i--) {
                 WindowState w = mWindows.get(i);
-                if (w.mWinAnimator.mSurface != null) {
+                if (w.mHasSurface) {
                     final WindowManager.LayoutParams attrs = w.mAttrs;
                     if (mPolicy.doesForceHide(w, attrs) && w.isVisibleLw()) {
                         if (DEBUG_FOCUS) Slog.i(TAG, "win=" + w + " force hides other windows");
@@ -8127,7 +8124,7 @@
         final int attrFlags = attrs.flags;
         final boolean canBeSeen = w.isDisplayedLw();
 
-        if (w.mWinAnimator.mSurface != null) {
+        if (w.mHasSurface) {
             if ((attrFlags&FLAG_KEEP_SCREEN_ON) != 0) {
                 mInnerFields.mHoldScreen = w.mSession;
             }
@@ -8279,7 +8276,7 @@
                 mPolicy.beginAnimationLw(dw, dh);
                 for (i = mWindows.size() - 1; i >= 0; i--) {
                     WindowState w = mWindows.get(i);
-                    if (w.mWinAnimator.mSurface != null) {
+                    if (w.mHasSurface) {
                         mPolicy.animatingWindowLw(w, w.mAttrs);
                     }
                 }
@@ -8397,7 +8394,7 @@
             updateResizingWindows(w);
 
             // Moved from updateWindowsAndWallpaperLocked().
-            if (winAnimator.mSurface != null) {
+            if (w.mHasSurface) {
                 // Take care of the window being ready to display.
                 if (winAnimator.commitFinishDrawingLocked(currentTime)) {
                     if ((w.mAttrs.flags
@@ -8456,10 +8453,8 @@
             stopFreezingDisplayLocked();
         }
 
-        i = mResizingWindows.size();
-        if (i > 0) {
-            do {
-                i--;
+        if (!mResizingWindows.isEmpty()) {
+            for (i = mResizingWindows.size() - 1; i >= 0; i--) {
                 WindowState win = mResizingWindows.get(i);
                 final WindowStateAnimator winAnimator = win.mWinAnimator; 
                 try {
@@ -8490,7 +8485,7 @@
                 } catch (RemoteException e) {
                     win.mOrientationChanging = false;
                 }
-            } while (i > 0);
+            }
             mResizingWindows.clear();
         }
 
@@ -8725,6 +8720,7 @@
                         wsa.mSurface.destroy();
                         wsa.mSurfaceShown = false;
                         wsa.mSurface = null;
+                        ws.mHasSurface = false;
                         mForceRemoves.add(ws);
                         i--;
                         N--;
@@ -8737,6 +8733,7 @@
                         wsa.mSurface.destroy();
                         wsa.mSurfaceShown = false;
                         wsa.mSurface = null;
+                        ws.mHasSurface = false;
                         leakedSurface = true;
                     }
                 }
@@ -8775,6 +8772,7 @@
                     surface.destroy();
                     winAnimator.mSurfaceShown = false;
                     winAnimator.mSurface = null;
+                    winAnimator.mWin.mHasSurface = false;
                 }
 
                 try {
diff --git a/services/java/com/android/server/wm/WindowState.java b/services/java/com/android/server/wm/WindowState.java
index 7f63429..f8795e3 100644
--- a/services/java/com/android/server/wm/WindowState.java
+++ b/services/java/com/android/server/wm/WindowState.java
@@ -246,6 +246,8 @@
 
     final WindowStateAnimator mWinAnimator;
 
+    boolean mHasSurface = false;
+
     WindowState(WindowManagerService service, Session s, IWindow c, WindowToken token,
            WindowState attachedWindow, int seq, WindowManager.LayoutParams a,
            int viewVisibility) {
@@ -609,7 +611,7 @@
      */
     public boolean isVisibleLw() {
         final AppWindowToken atoken = mAppToken;
-        return mWinAnimator.mSurface != null && mPolicyVisibility && !mAttachedHidden
+        return mHasSurface && mPolicyVisibility && !mAttachedHidden
                 && (atoken == null || !atoken.hiddenRequested)
                 && !mExiting && !mDestroying;
     }
@@ -630,7 +632,7 @@
         final AppWindowToken atoken = mAppToken;
         final boolean animating = atoken != null
                 ? (atoken.animation != null) : false;
-        return mWinAnimator.mSurface != null && !mDestroying && !mExiting
+        return mHasSurface && !mDestroying && !mExiting
                 && (atoken == null ? mPolicyVisibility : !atoken.hiddenRequested)
                 && ((!mAttachedHidden && mViewVisibility == View.VISIBLE
                                 && !mRootToken.hidden)
@@ -644,7 +646,7 @@
      */
     public boolean isWinVisibleLw() {
         final AppWindowToken atoken = mAppToken;
-        return mWinAnimator.mSurface != null && mPolicyVisibility && !mAttachedHidden
+        return mHasSurface && mPolicyVisibility && !mAttachedHidden
                 && (atoken == null || !atoken.hiddenRequested || atoken.animating)
                 && !mExiting && !mDestroying;
     }
@@ -654,7 +656,7 @@
      * the associated app token, not the pending requested hidden state.
      */
     boolean isVisibleNow() {
-        return mWinAnimator.mSurface != null && mPolicyVisibility && !mAttachedHidden
+        return mHasSurface && mPolicyVisibility && !mAttachedHidden
                 && !mRootToken.hidden && !mExiting && !mDestroying;
     }
 
@@ -674,7 +676,7 @@
      */
     boolean isVisibleOrAdding() {
         final AppWindowToken atoken = mAppToken;
-        return ((mWinAnimator.mSurface != null && !mWinAnimator.mReportDestroySurface)
+        return ((mHasSurface && !mWinAnimator.mReportDestroySurface)
                         || (!mRelayoutCalled && mViewVisibility == View.VISIBLE))
                 && mPolicyVisibility && !mAttachedHidden
                 && (atoken == null || !atoken.hiddenRequested)
@@ -687,15 +689,15 @@
      * being visible.
      */
     boolean isOnScreen() {
+        if (!mHasSurface || !mPolicyVisibility || mDestroying) {
+            return false;
+        }
         final AppWindowToken atoken = mAppToken;
         if (atoken != null) {
-            return mWinAnimator.mSurface != null && mPolicyVisibility && !mDestroying
-                    && ((!mAttachedHidden && !atoken.hiddenRequested)
+            return ((!mAttachedHidden && !atoken.hiddenRequested)
                             || mWinAnimator.mAnimation != null || atoken.animation != null);
-        } else {
-            return mWinAnimator.mSurface != null && mPolicyVisibility && !mDestroying
-                    && (!mAttachedHidden || mWinAnimator.mAnimation != null);
         }
+        return !mAttachedHidden || mWinAnimator.mAnimation != null;
     }
 
     /**
@@ -707,7 +709,7 @@
                 mService.mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
             return false;
         }
-        return mWinAnimator.mSurface != null && mPolicyVisibility && !mDestroying
+        return mHasSurface && mPolicyVisibility && !mDestroying
                 && ((!mAttachedHidden && mViewVisibility == View.VISIBLE
                                 && !mRootToken.hidden)
                         || mWinAnimator.mAnimation != null
@@ -741,8 +743,8 @@
      * complete UI in to.
      */
     public boolean isDrawnLw() {
-        return mWinAnimator.mSurface != null && !mDestroying
-            && !mWinAnimator.mDrawPending && !mWinAnimator.mCommitDrawPending;
+        return mHasSurface && !mDestroying &&
+            !mWinAnimator.mDrawPending && !mWinAnimator.mCommitDrawPending;
     }
 
     /**
@@ -1017,8 +1019,8 @@
             }
             pw.print(prefix); pw.print("mConfiguration="); pw.println(mConfiguration);
         }
-        pw.print(prefix); pw.print("mShownFrame=");
-                mShownFrame.printShortString(pw); pw.println();
+        pw.print(prefix); pw.print("mHasSurface="); pw.print(mHasSurface);
+                pw.print(" mShownFrame="); mShownFrame.printShortString(pw); pw.println();
         if (dumpAll) {
             pw.print(prefix); pw.print("mFrame="); mFrame.printShortString(pw);
                     pw.print(" last="); mLastFrame.printShortString(pw);
diff --git a/services/java/com/android/server/wm/WindowStateAnimator.java b/services/java/com/android/server/wm/WindowStateAnimator.java
index e99340c..e6a2481 100644
--- a/services/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/java/com/android/server/wm/WindowStateAnimator.java
@@ -35,6 +35,7 @@
     static final boolean SHOW_LIGHT_TRANSACTIONS = WindowManagerService.SHOW_LIGHT_TRANSACTIONS;
     static final boolean SHOW_SURFACE_ALLOC = WindowManagerService.SHOW_SURFACE_ALLOC;
     static final boolean localLOGV = WindowManagerService.localLOGV;
+    static final boolean DEBUG_ORIENTATION = WindowManagerService.DEBUG_ORIENTATION;
 
     static final String TAG = "WindowStateAnimator";
 
@@ -158,13 +159,11 @@
     }
 
     void cancelExitAnimationForNextAnimationLocked() {
-        if (!mWin.mExiting) return;
         if (mAnimation != null) {
             mAnimation.cancel();
             mAnimation = null;
             destroySurfaceLocked();
         }
-        mWin.mExiting = false;
     }
 
     private boolean stepAnimation(long currentTime) {
@@ -443,6 +442,7 @@
                         mSession.mSurfaceSession, mSession.mPid,
                         attrs.getTitle().toString(),
                         0, w, h, format, flags);
+                mWin.mHasSurface = true;
                 if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) Slog.i(TAG,
                         "  CREATE SURFACE "
                         + mSurface + " IN SESSION "
@@ -452,10 +452,12 @@
                         + Integer.toHexString(flags)
                         + " / " + this);
             } catch (Surface.OutOfResourcesException e) {
+                mWin.mHasSurface = false;
                 Slog.w(TAG, "OutOfResourcesException creating surface");
                 mService.reclaimSomeSurfaceMemoryLocked(this, "create", true);
                 return null;
             } catch (Exception e) {
+                mWin.mHasSurface = false;
                 Slog.e(TAG, "Exception creating surface", e);
                 return null;
             }
@@ -573,6 +575,7 @@
 
             mSurfaceShown = false;
             mSurface = null;
+            mWin.mHasSurface =false;
         }
     }
 
@@ -746,7 +749,7 @@
         final WindowState w = mWin;
         if (mSurface == null) {
             if (w.mOrientationChanging) {
-                if (WindowManagerService.DEBUG_ORIENTATION) {
+                if (DEBUG_ORIENTATION) {
                     Slog.v(TAG, "Orientation change skips hidden " + w);
                 }
                 w.mOrientationChanging = false;
@@ -841,7 +844,7 @@
             // new orientation.
             if (w.mOrientationChanging) {
                 w.mOrientationChanging = false;
-                if (WindowManagerService.DEBUG_ORIENTATION) Slog.v(TAG,
+                if (DEBUG_ORIENTATION) Slog.v(TAG,
                         "Orientation change skips hidden " + w);
             }
         } else if (mLastLayer != mAnimLayer
@@ -909,12 +912,11 @@
             if (w.mOrientationChanging) {
                 if (!w.isDrawnLw()) {
                     mService.mInnerFields.mOrientationChangeComplete = false;
-                    if (WindowManagerService.DEBUG_ORIENTATION) Slog.v(TAG,
+                    if (DEBUG_ORIENTATION) Slog.v(TAG,
                             "Orientation continue waiting for draw in " + w);
                 } else {
                     w.mOrientationChanging = false;
-                    if (WindowManagerService.DEBUG_ORIENTATION) Slog.v(TAG,
-                            "Orientation change complete in " + w);
+                    if (DEBUG_ORIENTATION) Slog.v(TAG, "Orientation change complete in " + w);
                 }
             }
             w.mToken.hasVisible = true;
@@ -935,7 +937,7 @@
                     + " starting=" + (mWin.mAttrs.type == TYPE_APPLICATION_STARTING), e);
         }
         if (mWin.mReadyToShow && mWin.isReadyForDisplay()) {
-            if (SHOW_TRANSACTIONS || WindowManagerService.DEBUG_ORIENTATION)
+            if (SHOW_TRANSACTIONS || DEBUG_ORIENTATION)
                 WindowManagerService.logSurface(mWin, "SHOW (performShowLocked)", null);
             if (DEBUG_VISIBILITY) Slog.v(TAG, "Showing " + this
                     + " during animation: policyVis=" + mWin.mPolicyVisibility
@@ -1169,4 +1171,12 @@
         }
     }
 
+    @Override
+    public String toString() {
+        StringBuffer sb = new StringBuffer("WindowStateAnimator (");
+        sb.append(mWin.mLastTitle + "): ");
+        sb.append("mSurface " + mSurface);
+        sb.append(", mAnimation " + mAnimation);
+        return sb.toString();
+    }
 }