Move Surface operations out of WindowState.

Migrated the bulk of Surface operations from WindowState to
WindowStateAnimator. There remain a multitude of cross-referencing
between the two classes and most of the other classes in the wm
package.

Change-Id: I4bfdfb84be31341371f3ef311aca8fc6a4966692
diff --git a/services/java/com/android/server/wm/AppWindowToken.java b/services/java/com/android/server/wm/AppWindowToken.java
index 6269420..c24c2d9 100644
--- a/services/java/com/android/server/wm/AppWindowToken.java
+++ b/services/java/com/android/server/wm/AppWindowToken.java
@@ -184,13 +184,14 @@
         final int adj = animLayerAdjustment;
         thumbnailLayer = -1;
         for (int i=0; i<N; i++) {
-            WindowState w = allAppWindows.get(i);
-            w.mAnimLayer = w.mLayer + adj;
-            if (w.mAnimLayer > thumbnailLayer) {
-                thumbnailLayer = w.mAnimLayer;
+            final WindowState w = allAppWindows.get(i);
+            final WindowStateAnimator winAnimator = w.mWinAnimator;
+            winAnimator.mAnimLayer = w.mLayer + adj;
+            if (winAnimator.mAnimLayer > thumbnailLayer) {
+                thumbnailLayer = winAnimator.mAnimLayer;
             }
             if (WindowManagerService.DEBUG_LAYERS) Slog.v(WindowManagerService.TAG, "Updating layer " + w + ": "
-                    + w.mAnimLayer);
+                    + winAnimator.mAnimLayer);
             if (w == service.mInputMethodTarget && !service.mInputMethodTargetWaitingAnim) {
                 service.setInputMethodAnimLayerAdjustment(adj);
             }
@@ -221,11 +222,11 @@
         boolean isAnimating = false;
         final int NW = allAppWindows.size();
         for (int i=0; i<NW; i++) {
-            WindowState w = allAppWindows.get(i);
+            WindowStateAnimator winAnimator = allAppWindows.get(i).mWinAnimator;
             if (WindowManagerService.DEBUG_VISIBILITY) Slog.v(WindowManagerService.TAG,
-                    "performing show on: " + w);
-            w.performShowLocked();
-            isAnimating |= w.mWinAnimator.isAnimating();
+                    "performing show on: " + winAnimator);
+            winAnimator.performShowLocked();
+            isAnimating |= winAnimator.isAnimating();
         }
         return isAnimating;
     }
@@ -390,7 +391,7 @@
                         + win.isDrawnLw()
                         + ", isAnimating=" + win.mWinAnimator.isAnimating());
                 if (!win.isDrawnLw()) {
-                    Slog.v(WindowManagerService.TAG, "Not displayed: s=" + win.mSurface
+                    Slog.v(WindowManagerService.TAG, "Not displayed: s=" + win.mWinAnimator.mSurface
                             + " pv=" + win.mPolicyVisibility
                             + " dp=" + win.mDrawPending
                             + " cdp=" + win.mCommitDrawPending
diff --git a/services/java/com/android/server/wm/DimAnimator.java b/services/java/com/android/server/wm/DimAnimator.java
index d8f2254..0051d98 100644
--- a/services/java/com/android/server/wm/DimAnimator.java
+++ b/services/java/com/android/server/wm/DimAnimator.java
@@ -85,17 +85,18 @@
      * {@link #updateSurface} after all windows are examined.
      */
     void updateParameters(Resources res, WindowState w, long currentTime) {
-        mDimSurface.setLayer(w.mAnimLayer - WindowManagerService.LAYER_OFFSET_DIM);
+        final WindowStateAnimator winAnimator = w.mWinAnimator;
+        mDimSurface.setLayer(winAnimator.mAnimLayer - WindowManagerService.LAYER_OFFSET_DIM);
 
         final float target = w.mExiting ? 0 : w.mAttrs.dimAmount;
-        if (WindowManagerService.SHOW_TRANSACTIONS) Slog.i(WindowManagerService.TAG, "  DIM " + mDimSurface
-                + ": layer=" + (w.mAnimLayer-1) + " target=" + target);
+        if (WindowManagerService.SHOW_TRANSACTIONS) Slog.i(WindowManagerService.TAG, "  DIM "
+                + mDimSurface + ": layer=" + (winAnimator.mAnimLayer-1) + " target=" + target);
         if (mDimTargetAlpha != target) {
             // If the desired dim level has changed, then
             // start an animation to it.
             mLastDimAnimTime = currentTime;
-            long duration = (w.mWinAnimator.mAnimating && w.mWinAnimator.mAnimation != null)
-                    ? w.mWinAnimator.mAnimation.computeDurationHint()
+            long duration = (winAnimator.mAnimating && winAnimator.mAnimation != null)
+                    ? winAnimator.mAnimation.computeDurationHint()
                     : WindowManagerService.DEFAULT_DIM_DURATION;
             if (target > mDimTargetAlpha) {
                 TypedValue tv = new TypedValue();
diff --git a/services/java/com/android/server/wm/WindowAnimator.java b/services/java/com/android/server/wm/WindowAnimator.java
index 7b52ac0..eddfe92 100644
--- a/services/java/com/android/server/wm/WindowAnimator.java
+++ b/services/java/com/android/server/wm/WindowAnimator.java
@@ -10,7 +10,6 @@
 import android.util.Slog;
 import android.view.Surface;
 import android.view.WindowManager;
-import android.view.WindowManager.LayoutParams;
 import android.view.WindowManagerPolicy;
 import android.view.animation.Animation;
 
@@ -103,7 +102,7 @@
             final int dw = mDw;
             final int dh = mDh;
             mWindowAnimationBackgroundSurface.show(dw, dh,
-                    target.mAnimLayer - WindowManagerService.LAYER_OFFSET_DIM,
+                    target.mWinAnimator.mAnimLayer - WindowManagerService.LAYER_OFFSET_DIM,
                     mWindowAnimationBackgroundColor);
         } else if (mWindowAnimationBackgroundSurface != null) {
             mWindowAnimationBackgroundSurface.hide();
@@ -164,10 +163,9 @@
         for (int i = mService.mWindows.size() - 1; i >= 0; i--) {
             WindowState w = mService.mWindows.get(i);
             WindowStateAnimator winAnimator = w.mWinAnimator;
-
             final WindowManager.LayoutParams attrs = w.mAttrs;
 
-            if (w.mSurface != null) {
+            if (winAnimator.mSurface != null) {
                 final boolean wasAnimating = winAnimator.mWasAnimating;
                 final boolean nowAnimating = winAnimator.stepAnimationLocked(mCurrentTime);
 
@@ -181,13 +179,14 @@
                 // a detached wallpaper animation.
                 if (nowAnimating) {
                     if (winAnimator.mAnimation != null) {
-                        if ((w.mAttrs.flags&FLAG_SHOW_WALLPAPER) != 0
+                        if ((attrs.flags&FLAG_SHOW_WALLPAPER) != 0
                                 && winAnimator.mAnimation.getDetachWallpaper()) {
-                            mService.mInnerFields.mDetachedWallpaper = w;
+                            mDetachedWallpaper = w;
                         }
                         if (winAnimator.mAnimation.getBackgroundColor() != 0) {
                             if (mWindowAnimationBackground == null
-                                    || (w.mAnimLayer < mWindowAnimationBackground.mAnimLayer)) {
+                                    || (winAnimator.mAnimLayer <
+                                            mWindowAnimationBackground.mWinAnimator.mAnimLayer)) {
                                 mWindowAnimationBackground = w;
                                 mWindowAnimationBackgroundColor =
                                         winAnimator.mAnimation.getBackgroundColor();
@@ -202,14 +201,14 @@
                 // displayed behind it.
                 if (w.mAppToken != null && w.mAppToken.animation != null
                         && w.mAppToken.animating) {
-                    if ((w.mAttrs.flags&FLAG_SHOW_WALLPAPER) != 0
+                    if ((attrs.flags&FLAG_SHOW_WALLPAPER) != 0
                             && w.mAppToken.animation.getDetachWallpaper()) {
-                        mService.mInnerFields.mDetachedWallpaper = w;
+                        mDetachedWallpaper = w;
                     }
                     if (w.mAppToken.animation.getBackgroundColor() != 0) {
                         if (mWindowAnimationBackground == null
-                                || (w.mAnimLayer <
-                                        mWindowAnimationBackground.mAnimLayer)) {
+                                || (winAnimator.mAnimLayer <
+                                        mWindowAnimationBackground.mWinAnimator.mAnimLayer)) {
                             mWindowAnimationBackground = w;
                             mWindowAnimationBackgroundColor =
                                     w.mAppToken.animation.getBackgroundColor();
@@ -296,7 +295,7 @@
                                 + w.isDrawnLw()
                                 + ", isAnimating=" + winAnimator.isAnimating());
                         if (!w.isDrawnLw()) {
-                            Slog.v(TAG, "Not displayed: s=" + w.mSurface
+                            Slog.v(TAG, "Not displayed: s=" + winAnimator.mSurface
                                     + " pv=" + w.mPolicyVisibility
                                     + " dp=" + w.mDrawPending
                                     + " cdp=" + w.mCommitDrawPending
@@ -323,7 +322,7 @@
                     }
                 }
             } else if (w.mReadyToShow) {
-                if (w.performShowLocked()) {
+                if (winAnimator.performShowLocked()) {
                     mPendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM;
                     if (WindowManagerService.DEBUG_LAYOUT_REPEATS) {
                         mService.debugLayoutRepeats("updateWindowsAndWallpaperLocked 5");
@@ -335,8 +334,8 @@
                     atoken.thumbnailTransactionSeq = mTransactionSequence;
                     atoken.thumbnailLayer = 0;
                 }
-                if (atoken.thumbnailLayer < w.mAnimLayer) {
-                    atoken.thumbnailLayer = w.mAnimLayer;
+                if (atoken.thumbnailLayer < winAnimator.mAnimLayer) {
+                    atoken.thumbnailLayer = winAnimator.mAnimLayer;
                 }
             }
         } // end forall windows
@@ -386,14 +385,10 @@
     }
 
     private void performAnimationsLocked() {
-        if (WindowManagerService.DEBUG_APP_TRANSITIONS) Slog.v(TAG, "*** ANIM STEP: seq="
-                + mTransactionSequence + " mAnimating="
-                + mAnimating);
-
         mTokenMayBeDrawn = false;
         mService.mInnerFields.mWallpaperMayChange = false;
         mForceHiding = false;
-        mService.mInnerFields.mDetachedWallpaper = null;
+        mDetachedWallpaper = null;
         mWindowAnimationBackground = null;
         mWindowAnimationBackgroundColor = 0;
 
@@ -402,188 +397,8 @@
         if (mTokenMayBeDrawn) {
             testTokenMayBeDrawnLocked();
         }
-
-        if (WindowManagerService.DEBUG_APP_TRANSITIONS) Slog.v(TAG, "*** ANIM STEP: changes=0x"
-                + Integer.toHexString(mPendingLayoutChanges));
     }
 
-    public void prepareSurfaceLocked(final WindowState w, final boolean recoveringMemory) {
-        if (w.mSurface == null) {
-            if (w.mOrientationChanging) {
-                if (WindowManagerService.DEBUG_ORIENTATION) {
-                    Slog.v(TAG, "Orientation change skips hidden " + w);
-                }
-                w.mOrientationChanging = false;
-            }
-            return;
-        }
-
-        boolean displayed = false;
-
-        w.computeShownFrameLocked();
-
-        int width, height;
-        if ((w.mAttrs.flags & LayoutParams.FLAG_SCALED) != 0) {
-            // for a scaled surface, we just want to use
-            // the requested size.
-            width  = w.mRequestedWidth;
-            height = w.mRequestedHeight;
-        } else {
-            width = w.mCompatFrame.width();
-            height = w.mCompatFrame.height();
-        }
-
-        if (width < 1) {
-            width = 1;
-        }
-        if (height < 1) {
-            height = 1;
-        }
-        final boolean surfaceResized = w.mSurfaceW != width || w.mSurfaceH != height;
-        if (surfaceResized) {
-            w.mSurfaceW = width;
-            w.mSurfaceH = height;
-        }
-
-        if (w.mSurfaceX != w.mShownFrame.left
-                || w.mSurfaceY != w.mShownFrame.top) {
-            try {
-                if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(w,
-                        "POS " + w.mShownFrame.left
-                        + ", " + w.mShownFrame.top, null);
-                w.mSurfaceX = w.mShownFrame.left;
-                w.mSurfaceY = w.mShownFrame.top;
-                w.mSurface.setPosition(w.mShownFrame.left, w.mShownFrame.top);
-            } catch (RuntimeException e) {
-                Slog.w(TAG, "Error positioning surface of " + w
-                        + " pos=(" + w.mShownFrame.left
-                        + "," + w.mShownFrame.top + ")", e);
-                if (!recoveringMemory) {
-                    mService.reclaimSomeSurfaceMemoryLocked(w, "position", true);
-                }
-            }
-        }
-
-        if (surfaceResized) {
-            try {
-                if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(w,
-                        "SIZE " + width + "x" + height, null);
-                w.mSurfaceResized = true;
-                w.mSurface.setSize(width, height);
-            } catch (RuntimeException e) {
-                // If something goes wrong with the surface (such
-                // as running out of memory), don't take down the
-                // entire system.
-                Slog.e(TAG, "Error resizing surface of " + w
-                        + " size=(" + width + "x" + height + ")", e);
-                if (!recoveringMemory) {
-                    mService.reclaimSomeSurfaceMemoryLocked(w, "size", true);
-                }
-            }
-        }
-
-        if (w.mAttachedHidden || !w.isReadyForDisplay()) {
-            if (!w.mLastHidden) {
-                //dump();
-                w.mLastHidden = true;
-                if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(w,
-                        "HIDE (performLayout)", null);
-                if (w.mSurface != null) {
-                    w.mSurfaceShown = false;
-                    try {
-                        w.mSurface.hide();
-                    } catch (RuntimeException e) {
-                        Slog.w(TAG, "Exception hiding surface in " + w);
-                    }
-                }
-            }
-            // If we are waiting for this window to handle an
-            // orientation change, well, it is hidden, so
-            // doesn't really matter.  Note that this does
-            // introduce a potential glitch if the window
-            // becomes unhidden before it has drawn for the
-            // new orientation.
-            if (w.mOrientationChanging) {
-                w.mOrientationChanging = false;
-                if (WindowManagerService.DEBUG_ORIENTATION) Slog.v(TAG,
-                        "Orientation change skips hidden " + w);
-            }
-        } else if (w.mLastLayer != w.mAnimLayer
-                || w.mLastAlpha != w.mShownAlpha
-                || w.mLastDsDx != w.mDsDx
-                || w.mLastDtDx != w.mDtDx
-                || w.mLastDsDy != w.mDsDy
-                || w.mLastDtDy != w.mDtDy
-                || w.mLastHScale != w.mHScale
-                || w.mLastVScale != w.mVScale
-                || w.mLastHidden) {
-            displayed = true;
-            w.mLastAlpha = w.mShownAlpha;
-            w.mLastLayer = w.mAnimLayer;
-            w.mLastDsDx = w.mDsDx;
-            w.mLastDtDx = w.mDtDx;
-            w.mLastDsDy = w.mDsDy;
-            w.mLastDtDy = w.mDtDy;
-            w.mLastHScale = w.mHScale;
-            w.mLastVScale = w.mVScale;
-            if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(w,
-                    "alpha=" + w.mShownAlpha + " layer=" + w.mAnimLayer
-                    + " matrix=[" + (w.mDsDx*w.mHScale)
-                    + "," + (w.mDtDx*w.mVScale)
-                    + "][" + (w.mDsDy*w.mHScale)
-                    + "," + (w.mDtDy*w.mVScale) + "]", null);
-            if (w.mSurface != null) {
-                try {
-                    w.mSurfaceAlpha = w.mShownAlpha;
-                    w.mSurface.setAlpha(w.mShownAlpha);
-                    w.mSurfaceLayer = w.mAnimLayer;
-                    w.mSurface.setLayer(w.mAnimLayer);
-                    w.mSurface.setMatrix(
-                            w.mDsDx*w.mHScale, w.mDtDx*w.mVScale,
-                            w.mDsDy*w.mHScale, w.mDtDy*w.mVScale);
-                } catch (RuntimeException e) {
-                    Slog.w(TAG, "Error updating surface in " + w, e);
-                    if (!recoveringMemory) {
-                        mService.reclaimSomeSurfaceMemoryLocked(w, "update", true);
-                    }
-                }
-            }
-
-            if (w.mLastHidden && w.isDrawnLw()
-                    && !w.mReadyToShow) {
-                if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(w,
-                        "SHOW (performLayout)", null);
-                if (WindowManagerService.DEBUG_VISIBILITY) Slog.v(TAG, "Showing " + w
-                        + " during relayout");
-                if (mService.showSurfaceRobustlyLocked(w)) {
-                    w.mHasDrawn = true;
-                    w.mLastHidden = false;
-                } else {
-                    w.mOrientationChanging = false;
-                }
-            }
-            if (w.mSurface != null) {
-                w.mToken.hasVisible = true;
-            }
-        } else {
-            displayed = true;
-        }
-
-        if (displayed) {
-            if (w.mOrientationChanging) {
-                if (!w.isDrawnLw()) {
-                    mService.mInnerFields.mOrientationChangeComplete = false;
-                    if (WindowManagerService.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);
-                }
-            }
-            w.mToken.hasVisible = true;
-        }
-    }
 
     void animate() {
         mPendingLayoutChanges = 0;
@@ -608,7 +423,7 @@
             final int N = mService.mWindows.size();
             for (int i=N-1; i>=0; i--) {
                 WindowState w = mService.mWindows.get(i);
-                prepareSurfaceLocked(w, true);
+                w.mWinAnimator.prepareSurfaceLocked(true);
             }
 
             if (mService.mDimAnimator != null && mService.mDimAnimator.mDimShown) {
@@ -629,7 +444,7 @@
         } finally {
             Surface.closeTransaction();
         }
-        
+
         if (mWallpaperMayChange) {
             mService.notifyWallpaperMayChange();
         }
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index fb1adaa..a1b7967 100644
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -592,7 +592,6 @@
     class LayoutAndSurfaceFields {
         boolean mWallpaperForceHidingChanged = false;
         boolean mWallpaperMayChange = false;
-        WindowState mDetachedWallpaper = null;
         boolean mOrientationChangeComplete = true;
         int mAdjResult = 0;
         private Session mHoldScreen = null;
@@ -1126,7 +1125,8 @@
             if (DEBUG_INPUT_METHOD) {
                 Slog.i(TAG, "isVisibleOrAdding " + w + ": " + w.isVisibleOrAdding());
                 if (!w.isVisibleOrAdding()) {
-                    Slog.i(TAG, "  mSurface=" + w.mSurface + " reportDestroy=" + w.mReportDestroySurface
+                    Slog.i(TAG, "  mSurface=" + w.mWinAnimator.mSurface + " reportDestroy="
+                            + w.mWinAnimator.mReportDestroySurface
                             + " relayoutCalled=" + w.mRelayoutCalled + " viewVis=" + w.mViewVisibility
                             + " policyVis=" + w.mPolicyVisibility + " attachHid=" + w.mAttachedHidden
                             + " exiting=" + w.mExiting + " destroying=" + w.mDestroying);
@@ -1190,7 +1190,7 @@
         if (mInputMethodTarget != null && w != null
                 && mInputMethodTarget.isDisplayedLw()
                 && mInputMethodTarget.mExiting) {
-            if (mInputMethodTarget.mAnimLayer > w.mAnimLayer) {
+            if (mInputMethodTarget.mWinAnimator.mAnimLayer > w.mWinAnimator.mAnimLayer) {
                 w = mInputMethodTarget;
                 i = localmWindows.indexOf(w);
                 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Current target higher, switching to: " + w);
@@ -1219,8 +1219,8 @@
                             break;
                         }
                         if (!win.mRemoved) {
-                            if (highestTarget == null || win.mAnimLayer >
-                                    highestTarget.mAnimLayer) {
+                            if (highestTarget == null || win.mWinAnimator.mAnimLayer >
+                                    highestTarget.mWinAnimator.mAnimLayer) {
                                 highestTarget = win;
                                 highestPos = pos;
                             }
@@ -1233,8 +1233,8 @@
                     if (DEBUG_INPUT_METHOD) Slog.v(TAG, "mNextAppTransition="
                             + mNextAppTransition + " " + highestTarget
                             + " animating=" + highestTarget.mWinAnimator.isAnimating()
-                            + " layer=" + highestTarget.mAnimLayer
-                            + " new layer=" + w.mAnimLayer);
+                            + " layer=" + highestTarget.mWinAnimator.mAnimLayer
+                            + " new layer=" + w.mWinAnimator.mAnimLayer);
 
                     if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
                         // If we are currently setting up for an animation,
@@ -1243,7 +1243,7 @@
                         mInputMethodTarget = highestTarget;
                         return highestPos + 1;
                     } else if (highestTarget.mWinAnimator.isAnimating() &&
-                            highestTarget.mAnimLayer > w.mAnimLayer) {
+                            highestTarget.mWinAnimator.mAnimLayer > w.mWinAnimator.mAnimLayer) {
                         // If the window we are currently targeting is involved
                         // with an animation, and it is on top of the next target
                         // we will be over, then hold off on moving until
@@ -1315,25 +1315,25 @@
         mInputMethodAnimLayerAdjustment = adj;
         WindowState imw = mInputMethodWindow;
         if (imw != null) {
-            imw.mAnimLayer = imw.mLayer + adj;
+            imw.mWinAnimator.mAnimLayer = imw.mLayer + adj;
             if (DEBUG_LAYERS) Slog.v(TAG, "IM win " + imw
-                    + " anim layer: " + imw.mAnimLayer);
+                    + " anim layer: " + imw.mWinAnimator.mAnimLayer);
             int wi = imw.mChildWindows.size();
             while (wi > 0) {
                 wi--;
                 WindowState cw = imw.mChildWindows.get(wi);
-                cw.mAnimLayer = cw.mLayer + adj;
+                cw.mWinAnimator.mAnimLayer = cw.mLayer + adj;
                 if (DEBUG_LAYERS) Slog.v(TAG, "IM win " + cw
-                        + " anim layer: " + cw.mAnimLayer);
+                        + " anim layer: " + cw.mWinAnimator.mAnimLayer);
             }
         }
         int di = mInputMethodDialogs.size();
         while (di > 0) {
             di --;
             imw = mInputMethodDialogs.get(di);
-            imw.mAnimLayer = imw.mLayer + adj;
+            imw.mWinAnimator.mAnimLayer = imw.mLayer + adj;
             if (DEBUG_LAYERS) Slog.v(TAG, "IM win " + imw
-                    + " anim layer: " + imw.mAnimLayer);
+                    + " anim layer: " + imw.mWinAnimator.mAnimLayer);
         }
     }
 
@@ -1820,9 +1820,9 @@
                     }
                 }
 
-                wallpaper.mAnimLayer = wallpaper.mLayer + mWallpaperAnimLayerAdjustment;
+                wallpaper.mWinAnimator.mAnimLayer = wallpaper.mLayer + mWallpaperAnimLayerAdjustment;
                 if (DEBUG_LAYERS || DEBUG_WALLPAPER) Slog.v(TAG, "Wallpaper win "
-                        + wallpaper + " anim layer: " + wallpaper.mAnimLayer);
+                        + wallpaper + " anim layer: " + wallpaper.mWinAnimator.mAnimLayer);
 
                 // First, if this window is at the current index, then all
                 // is well.
@@ -1874,9 +1874,9 @@
             while (curWallpaperIndex > 0) {
                 curWallpaperIndex--;
                 WindowState wallpaper = token.windows.get(curWallpaperIndex);
-                wallpaper.mAnimLayer = wallpaper.mLayer + adj;
+                wallpaper.mWinAnimator.mAnimLayer = wallpaper.mLayer + adj;
                 if (DEBUG_LAYERS || DEBUG_WALLPAPER) Slog.v(TAG, "Wallpaper win "
-                        + wallpaper + " anim layer: " + wallpaper.mAnimLayer);
+                        + wallpaper + " anim layer: " + wallpaper.mWinAnimator.mAnimLayer);
             }
         }
     }
@@ -1995,19 +1995,20 @@
                 curWallpaperIndex--;
                 WindowState wallpaper = token.windows.get(curWallpaperIndex);
                 if (updateWallpaperOffsetLocked(wallpaper, dw, dh, sync)) {
-                    wallpaper.computeShownFrameLocked();
+                    WindowStateAnimator winAnimator = wallpaper.mWinAnimator;
+                    winAnimator.computeShownFrameLocked();
                     // No need to lay out the windows - we can just set the wallpaper position
                     // directly.
-                    if (wallpaper.mSurfaceX != wallpaper.mShownFrame.left
-                            || wallpaper.mSurfaceY != wallpaper.mShownFrame.top) {
+                    if (winAnimator.mSurfaceX != wallpaper.mShownFrame.left
+                            || winAnimator.mSurfaceY != wallpaper.mShownFrame.top) {
                         Surface.openTransaction();
                         try {
                             if (SHOW_TRANSACTIONS) logSurface(wallpaper,
                                     "POS " + wallpaper.mShownFrame.left
                                     + ", " + wallpaper.mShownFrame.top, null);
-                            wallpaper.mSurfaceX = wallpaper.mShownFrame.left;
-                            wallpaper.mSurfaceY = wallpaper.mShownFrame.top;
-                            wallpaper.mSurface.setPosition(wallpaper.mShownFrame.left,
+                            winAnimator.mSurfaceX = wallpaper.mShownFrame.left;
+                            winAnimator.mSurfaceY = wallpaper.mShownFrame.top;
+                            winAnimator.mSurface.setPosition(wallpaper.mShownFrame.left,
                                     wallpaper.mShownFrame.top);
                         } catch (RuntimeException e) {
                             Slog.w(TAG, "Error positioning surface of " + wallpaper
@@ -2217,7 +2218,7 @@
                 }
             }
 
-            win.mEnterAnimationPending = true;
+            win.mWinAnimator.mEnterAnimationPending = true;
 
             mPolicy.getContentInsetHintLw(attrs, outContentInsets);
 
@@ -2288,14 +2289,14 @@
             TAG, "Remove " + win + " client="
             + Integer.toHexString(System.identityHashCode(
                 win.mClient.asBinder()))
-            + ", surface=" + win.mSurface);
+            + ", surface=" + win.mWinAnimator.mSurface);
 
         final long origId = Binder.clearCallingIdentity();
 
         win.disposeInputChannel();
 
         if (DEBUG_APP_TRANSITIONS) Slog.v(
-                TAG, "Remove " + win + ": mSurface=" + win.mSurface
+                TAG, "Remove " + win + ": mSurface=" + win.mWinAnimator.mSurface
                 + " mExiting=" + win.mExiting
                 + " isAnimating=" + win.mWinAnimator.isAnimating()
                 + " app-animation="
@@ -2309,7 +2310,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.mSurface != null && okToDisplay()) {
+        if (win.mWinAnimator.mSurface != null && okToDisplay()) {
             // If we are not currently running the exit animation, we
             // need to see about starting one.
             wasVisible = win.isWinVisibleLw();
@@ -2320,7 +2321,7 @@
                     transit = WindowManagerPolicy.TRANSIT_PREVIEW_DONE;
                 }
                 // Try starting an animation.
-                if (win.applyAnimationLocked(transit, false)) {
+                if (win.mWinAnimator.applyAnimationLocked(transit, false)) {
                     win.mExiting = true;
                 }
             }
@@ -2476,14 +2477,15 @@
         try {
             synchronized (mWindowMap) {
                 WindowState w = windowForClientLocked(session, client, false);
-                if ((w != null) && (w.mSurface != null)) {
+                WindowStateAnimator winAnimator = w.mWinAnimator;
+                if ((w != null) && (winAnimator.mSurface != null)) {
                     if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
                             ">>> OPEN TRANSACTION setTransparentRegion");
                     Surface.openTransaction();
                     try {
                         if (SHOW_TRANSACTIONS) logSurface(w,
                                 "transparentRegionHint=" + region, null);
-                        w.mSurface.setTransparentRegionHint(region);
+                        winAnimator.mSurface.setTransparentRegionHint(region);
                     } finally {
                         Surface.closeTransaction();
                         if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
@@ -2612,6 +2614,7 @@
 
         synchronized(mWindowMap) {
             WindowState win = windowForClientLocked(session, client, false);
+            WindowStateAnimator winAnimator = win.mWinAnimator;
             if (win == null) {
                 return 0;
             }
@@ -2629,7 +2632,7 @@
                 mPolicy.adjustWindowParamsLw(attrs);
             }
 
-            win.mSurfaceDestroyDeferred =
+            winAnimator.mSurfaceDestroyDeferred =
                     (flags&WindowManagerImpl.RELAYOUT_DEFER_SURFACE_DESTROY) != 0;
 
             int attrChanges = 0;
@@ -2651,7 +2654,7 @@
             win.mEnforceSizeCompat = (win.mAttrs.flags & FLAG_COMPATIBLE_WINDOW) != 0;
 
             if ((attrChanges & WindowManager.LayoutParams.ALPHA_CHANGED) != 0) {
-                win.mAlpha = attrs.alpha;
+                winAnimator.mAlpha = attrs.alpha;
             }
 
             final boolean scaledWindow =
@@ -2693,18 +2696,18 @@
                     (win.mAppToken == null || !win.mAppToken.clientHidden)) {
                 displayed = !win.isVisibleLw();
                 if (win.mExiting) {
-                    win.mWinAnimator.cancelExitAnimationForNextAnimationLocked();
+                    winAnimator.cancelExitAnimationForNextAnimationLocked();
                 }
                 if (win.mDestroying) {
                     win.mDestroying = false;
                     mDestroySurface.remove(win);
                 }
                 if (oldVisibility == View.GONE) {
-                    win.mEnterAnimationPending = true;
+                    winAnimator.mEnterAnimationPending = true;
                 }
                 if (displayed) {
                     if (win.isDrawnLw() && okToDisplay()) {
-                        win.applyEnterAnimationLocked();
+                        winAnimator.applyEnterAnimationLocked();
                     }
                     if ((win.mAttrs.flags
                             & WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON) != 0) {
@@ -2727,19 +2730,19 @@
                 }
                 if ((attrChanges&WindowManager.LayoutParams.FORMAT_CHANGED) != 0) {
                     // To change the format, we need to re-build the surface.
-                    win.destroySurfaceLocked();
+                    winAnimator.destroySurfaceLocked();
                     displayed = true;
                     surfaceChanged = true;
                 }
                 try {
-                    if (win.mSurface == null) {
+                    if (winAnimator.mSurface == null) {
                         surfaceChanged = true;
                     }
-                    Surface surface = win.createSurfaceLocked();
+                    Surface surface = winAnimator.createSurfaceLocked();
                     if (surface != null) {
                         outSurface.copyFrom(surface);
-                        win.mReportDestroySurface = false;
-                        win.mSurfacePendingDestroy = false;
+                        winAnimator.mReportDestroySurface = false;
+                        winAnimator.mSurfacePendingDestroy = false;
                         if (SHOW_TRANSACTIONS) Slog.i(TAG,
                                 "  OUT SURFACE " + outSurface + ": copied");
                     } else {
@@ -2778,14 +2781,14 @@
                     sa.flags = (sa.flags&~mask) | (win.mAttrs.flags&mask);
                 }
             } else {
-                win.mEnterAnimationPending = false;
-                if (win.mSurface != null) {
+                winAnimator.mEnterAnimationPending = false;
+                if (winAnimator.mSurface != null) {
                     if (DEBUG_VISIBILITY) Slog.i(TAG, "Relayout invis " + win
                             + ": mExiting=" + win.mExiting
-                            + " mSurfacePendingDestroy=" + win.mSurfacePendingDestroy);
+                            + " mSurfacePendingDestroy=" + winAnimator.mSurfacePendingDestroy);
                     // If we are not currently running the exit animation, we
                     // need to see about starting one.
-                    if (!win.mExiting || win.mSurfacePendingDestroy) {
+                    if (!win.mExiting || winAnimator.mSurfacePendingDestroy) {
                         surfaceChanged = true;
                         // Try starting an animation; if there isn't one, we
                         // can destroy the surface right away.
@@ -2793,8 +2796,8 @@
                         if (win.mAttrs.type == TYPE_APPLICATION_STARTING) {
                             transit = WindowManagerPolicy.TRANSIT_PREVIEW_DONE;
                         }
-                        if (!win.mSurfacePendingDestroy && win.isWinVisibleLw() &&
-                              win.applyAnimationLocked(transit, false)) {
+                        if (!winAnimator.mSurfacePendingDestroy && win.isWinVisibleLw() &&
+                                winAnimator.applyAnimationLocked(transit, false)) {
                             focusMayChange = true;
                             win.mExiting = true;
                         } else if (win.mWinAnimator.isAnimating()) {
@@ -2811,26 +2814,26 @@
                             if (mInputMethodWindow == win) {
                                 mInputMethodWindow = null;
                             }
-                            win.destroySurfaceLocked();
+                            winAnimator.destroySurfaceLocked();
                         }
                     }
                 }
 
-                if (win.mSurface == null || (win.getAttrs().flags
+                if (winAnimator.mSurface == null || (win.getAttrs().flags
                         & WindowManager.LayoutParams.FLAG_KEEP_SURFACE_WHILE_ANIMATING) == 0
-                        || win.mSurfacePendingDestroy) {
+                        || winAnimator.mSurfacePendingDestroy) {
                     // We could be called from a local process, which
                     // means outSurface holds its current surface.  Ensure the
                     // surface object is cleared, but we don't necessarily want
                     // it actually destroyed at this point.
-                    win.mSurfacePendingDestroy = false;
+                    winAnimator.mSurfacePendingDestroy = false;
                     outSurface.release();
                     if (DEBUG_VISIBILITY) Slog.i(TAG, "Releasing surface in: " + win);
-                } else if (win.mSurface != null) {
+                } else if (winAnimator.mSurface != null) {
                     if (DEBUG_VISIBILITY) Slog.i(TAG,
                             "Keeping surface, will report destroy: " + win);
-                    win.mReportDestroySurface = true;
-                    outSurface.copyFrom(win.mSurface);
+                    winAnimator.mReportDestroySurface = true;
+                    outSurface.copyFrom(winAnimator.mSurface);
                 }
             }
 
@@ -2915,7 +2918,7 @@
                 if (win == null) {
                     return;
                 }
-                win.destroyDeferredSurfaceLocked();
+                win.mWinAnimator.destroyDeferredSurfaceLocked();
             }
         } finally {
             Binder.restoreCallingIdentity(origId);
@@ -2931,7 +2934,7 @@
                 if (win == null) {
                     return false;
                 }
-                return reclaimSomeSurfaceMemoryLocked(win, "from-client", false);
+                return reclaimSomeSurfaceMemoryLocked(win.mWinAnimator, "from-client", false);
             }
         } finally {
             Binder.restoreCallingIdentity(origId);
@@ -3287,7 +3290,7 @@
                         }
 
                         if (win.isVisibleNow()) {
-                            win.applyAnimationLocked(WindowManagerPolicy.TRANSIT_EXIT, false);
+                            win.mWinAnimator.applyAnimationLocked(WindowManagerPolicy.TRANSIT_EXIT, false);
                             changed = true;
                         }
                     }
@@ -3546,7 +3549,6 @@
      * android.os.IBinder)
      */
     boolean updateOrientationFromAppTokensLocked(boolean inTransaction) {
-        boolean changed = false;
         long ident = Binder.clearCallingIdentity();
         try {
             int req = computeForcedAppOrientationLocked();
@@ -3557,11 +3559,12 @@
                 //action like disabling/enabling sensors etc.,
                 mPolicy.setCurrentOrientationLw(req);
                 if (updateRotationUncheckedLocked(inTransaction)) {
-                    changed = true;
+                    // changed
+                    return true;
                 }
             }
 
-            return changed;
+            return false;
         } finally {
             Binder.restoreCallingIdentity(ident);
         }
@@ -3983,13 +3986,15 @@
                 if (visible) {
                     if (!win.isVisibleNow()) {
                         if (!runningAppAnimation) {
-                            win.applyAnimationLocked(WindowManagerPolicy.TRANSIT_ENTER, true);
+                            win.mWinAnimator.applyAnimationLocked(
+                                    WindowManagerPolicy.TRANSIT_ENTER, true);
                         }
                         changed = true;
                     }
                 } else if (win.isVisibleNow()) {
                     if (!runningAppAnimation) {
-                        win.applyAnimationLocked(WindowManagerPolicy.TRANSIT_EXIT, false);
+                        win.mWinAnimator.applyAnimationLocked(
+                                WindowManagerPolicy.TRANSIT_EXIT, false);
                     }
                     changed = true;
                 }
@@ -4128,7 +4133,7 @@
                 WindowState w = wtoken.allAppWindows.get(i);
                 if (w.mAppFreezing) {
                     w.mAppFreezing = false;
-                    if (w.mSurface != null && !w.mOrientationChanging) {
+                    if (w.mWinAnimator.mSurface != null && !w.mOrientationChanging) {
                         if (DEBUG_ORIENTATION) Slog.v(TAG, "set mOrientationChanging of " + w);
                         w.mOrientationChanging = true;
                     }
@@ -4716,7 +4721,7 @@
         synchronized(mWindowMap) {
             for (int i=mWindows.size()-1; i>=0; i--) {
                 WindowState w = mWindows.get(i);
-                if (w.mSurface != null) {
+                if (w.mWinAnimator.mSurface != null) {
                     try {
                         w.mClient.closeSystemDialogs(reason);
                     } catch (RemoteException e) {
@@ -5188,7 +5193,7 @@
             boolean including = false;
             for (int i=mWindows.size()-1; i>=0; i--) {
                 WindowState ws = mWindows.get(i);
-                if (ws.mSurface == null) {
+                if (ws.mWinAnimator.mSurface == null) {
                     continue;
                 }
                 if (ws.mLayer >= aboveAppLayer) {
@@ -5214,8 +5219,8 @@
                 // window.
                 including = !ws.mIsImWindow && !ws.isFullscreen(dw, dh);
 
-                if (maxLayer < ws.mAnimLayer) {
-                    maxLayer = ws.mAnimLayer;
+                if (maxLayer < ws.mWinAnimator.mAnimLayer) {
+                    maxLayer = ws.mWinAnimator.mAnimLayer;
                 }
                 
                 // Don't include wallpaper in bounds calculation
@@ -5276,8 +5281,8 @@
                 Slog.i(TAG, "Screenshot: " + dw + "x" + dh + " from 0 to " + maxLayer);
                 for (int i=0; i<mWindows.size(); i++) {
                     Slog.i(TAG, mWindows.get(i) + ": " + mWindows.get(i).mLayer
-                            + " animLayer=" + mWindows.get(i).mAnimLayer
-                            + " surfaceLayer=" + mWindows.get(i).mSurfaceLayer);
+                            + " animLayer=" + mWindows.get(i).mWinAnimator.mAnimLayer
+                            + " surfaceLayer=" + mWindows.get(i).mWinAnimator.mSurfaceLayer);
                 }
             }
             rawss = Surface.screenshot(dw, dh, 0, maxLayer);
@@ -5502,7 +5507,7 @@
 
         for (int i=mWindows.size()-1; i>=0; i--) {
             WindowState w = mWindows.get(i);
-            if (w.mSurface != null) {
+            if (w.mWinAnimator.mSurface != null) {
                 if (DEBUG_ORIENTATION) Slog.v(TAG, "Set mOrientationChanging of " + w);
                 w.mOrientationChanging = true;
             }
@@ -7403,19 +7408,19 @@
                 w.mLayer = curLayer;
             }
             if (w.mTargetAppToken != null) {
-                w.mAnimLayer = w.mLayer + w.mTargetAppToken.animLayerAdjustment;
+                w.mWinAnimator.mAnimLayer = w.mLayer + w.mTargetAppToken.animLayerAdjustment;
             } else if (w.mAppToken != null) {
-                w.mAnimLayer = w.mLayer + w.mAppToken.animLayerAdjustment;
+                w.mWinAnimator.mAnimLayer = w.mLayer + w.mAppToken.animLayerAdjustment;
             } else {
-                w.mAnimLayer = w.mLayer;
+                w.mWinAnimator.mAnimLayer = w.mLayer;
             }
             if (w.mIsImWindow) {
-                w.mAnimLayer += mInputMethodAnimLayerAdjustment;
+                w.mWinAnimator.mAnimLayer += mInputMethodAnimLayerAdjustment;
             } else if (w.mIsWallpaper) {
-                w.mAnimLayer += mWallpaperAnimLayerAdjustment;
+                w.mWinAnimator.mAnimLayer += mWallpaperAnimLayerAdjustment;
             }
             if (DEBUG_LAYERS) Slog.v(TAG, "Assign layer " + w + ": "
-                    + w.mAnimLayer);
+                    + w.mWinAnimator.mAnimLayer);
             //System.out.println(
             //    "Assigned layer " + curLayer + " to " + w.mClient.asBinder());
         }
@@ -7852,8 +7857,8 @@
                     int layer = -1;
                     for (int j=0; j<wtoken.windows.size(); j++) {
                         WindowState win = wtoken.windows.get(j);
-                        if (win.mAnimLayer > layer) {
-                            layer = win.mAnimLayer;
+                        if (win.mWinAnimator.mAnimLayer > layer) {
+                            layer = win.mWinAnimator.mAnimLayer;
                         }
                     }
                     if (topOpeningApp == null || layer > topOpeningLayer) {
@@ -8002,7 +8007,7 @@
             mAnimator.mForceHiding = false;
             for (int i=mWindows.size()-1; i>=0; i--) {
                 WindowState w = mWindows.get(i);
-                if (w.mSurface != null) {
+                if (w.mWinAnimator.mSurface != null) {
                     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");
@@ -8041,13 +8046,13 @@
             w.mLastFrame.set(w.mFrame);
             if (w.mContentInsetsChanged
                     || w.mVisibleInsetsChanged
-                    || w.mSurfaceResized
+                    || w.mWinAnimator.mSurfaceResized
                     || configChanged) {
                 if (DEBUG_RESIZE || DEBUG_ORIENTATION) {
                     Slog.v(TAG, "Resize reasons: "
                             + " contentInsetsChanged=" + w.mContentInsetsChanged
                             + " visibleInsetsChanged=" + w.mVisibleInsetsChanged
-                            + " surfaceResized=" + w.mSurfaceResized
+                            + " surfaceResized=" + w.mWinAnimator.mSurfaceResized
                             + " configChanged=" + configChanged);
                 }
 
@@ -8062,7 +8067,7 @@
                 if (w.mOrientationChanging) {
                     if (DEBUG_ORIENTATION) Slog.v(TAG,
                             "Orientation start waiting for draw in "
-                            + w + ", surface " + w.mSurface);
+                            + w + ", surface " + w.mWinAnimator.mSurface);
                     w.mDrawPending = true;
                     w.mCommitDrawPending = false;
                     w.mReadyToShow = false;
@@ -8072,15 +8077,15 @@
                 }
                 if (!mResizingWindows.contains(w)) {
                     if (DEBUG_RESIZE || DEBUG_ORIENTATION) Slog.v(TAG,
-                            "Resizing window " + w + " to " + w.mSurfaceW
-                            + "x" + w.mSurfaceH);
+                            "Resizing window " + w + " to " + w.mWinAnimator.mSurfaceW
+                            + "x" + w.mWinAnimator.mSurfaceH);
                     mResizingWindows.add(w);
                 }
             } else if (w.mOrientationChanging) {
                 if (w.isDrawnLw()) {
                     if (DEBUG_ORIENTATION) Slog.v(TAG,
                             "Orientation not waiting for draw in "
-                            + w + ", surface " + w.mSurface);
+                            + w + ", surface " + w.mWinAnimator.mSurface);
                     w.mOrientationChanging = false;
                 }
             }
@@ -8101,7 +8106,7 @@
         final int attrFlags = attrs.flags;
         final boolean canBeSeen = w.isDisplayedLw();
 
-        if (w.mSurface != null) {
+        if (w.mWinAnimator.mSurface != null) {
             if ((attrFlags&FLAG_KEEP_SCREEN_ON) != 0) {
                 mInnerFields.mHoldScreen = w.mSession;
             }
@@ -8253,7 +8258,7 @@
                 mPolicy.beginAnimationLw(dw, dh);
                 for (i = mWindows.size() - 1; i >= 0; i--) {
                     WindowState w = mWindows.get(i);
-                    if (w.mSurface != null) {
+                    if (w.mWinAnimator.mSurface != null) {
                         mPolicy.animatingWindowLw(w, w.mAttrs);
                     }
                 }
@@ -8365,12 +8370,13 @@
 
         final int N = mWindows.size();
         for (i=N-1; i>=0; i--) {
-            WindowState w = mWindows.get(i);
+            final WindowState w = mWindows.get(i);
+            final WindowStateAnimator winAnimator = w.mWinAnimator; 
             // TODO(cmautner): Can this move up to the loop at the end of try/catch above?
             updateResizingWindows(w);
 
             // Moved from updateWindowsAndWallpaperLocked().
-            if (w.mSurface != null) {
+            if (winAnimator.mSurface != null) {
                 // Take care of the window being ready to display.
                 if (w.commitFinishDrawingLocked(currentTime)) {
                     if ((w.mAttrs.flags
@@ -8395,12 +8401,12 @@
                     // let's do something.
                     Animation a = AnimationUtils.loadAnimation(mContext,
                             com.android.internal.R.anim.window_move_from_decor);
-                    w.mWinAnimator.setAnimation(a);
-                    w.mAnimDw = w.mLastFrame.left - w.mFrame.left;
-                    w.mAnimDh = w.mLastFrame.top - w.mFrame.top;
+                    winAnimator.setAnimation(a);
+                    winAnimator.mAnimDw = w.mLastFrame.left - w.mFrame.left;
+                    winAnimator.mAnimDh = w.mLastFrame.top - w.mFrame.top;
                 } else {
-                    w.mAnimDw = innerDw;
-                    w.mAnimDh = innerDh;
+                    winAnimator.mAnimDw = innerDw;
+                    winAnimator.mAnimDh = innerDh;
                 }
             }
         }
@@ -8445,19 +8451,20 @@
                     if ((DEBUG_RESIZE || DEBUG_ORIENTATION || DEBUG_CONFIGURATION)
                             && configChanged) {
                         Slog.i(TAG, "Sending new config to window " + win + ": "
-                                + win.mSurfaceW + "x" + win.mSurfaceH
+                                + win.mWinAnimator.mSurfaceW + "x" + win.mWinAnimator.mSurfaceH
                                 + " / " + mCurConfiguration + " / 0x"
                                 + Integer.toHexString(diff));
                     }
                     win.mConfiguration = mCurConfiguration;
                     if (DEBUG_ORIENTATION && win.mDrawPending) Slog.i(
                             TAG, "Resizing " + win + " WITH DRAW PENDING"); 
-                    win.mClient.resized((int)win.mSurfaceW, (int)win.mSurfaceH,
+                    win.mClient.resized((int)win.mWinAnimator.mSurfaceW,
+                            (int)win.mWinAnimator.mSurfaceH,
                             win.mLastContentInsets, win.mLastVisibleInsets, win.mDrawPending,
                             configChanged ? win.mConfiguration : null);
                     win.mContentInsetsChanged = false;
                     win.mVisibleInsetsChanged = false;
-                    win.mSurfaceResized = false;
+                    win.mWinAnimator.mSurfaceResized = false;
                 } catch (RemoteException e) {
                     win.mOrientationChanging = false;
                 }
@@ -8479,7 +8486,7 @@
                 if (win == mWallpaperTarget) {
                     wallpaperDestroyed = true;
                 }
-                win.destroySurfaceLocked();
+                win.mWinAnimator.destroySurfaceLocked();
             } while (i > 0);
             mDestroySurface.clear();
         }
@@ -8605,7 +8612,7 @@
                     }
                     mWaitingForDrawn.remove(pair);
                     mH.removeMessages(H.WAITING_FOR_DRAWN_TIMEOUT, pair);
-                } else if (win.mSurfaceShown) {
+                } else if (win.mWinAnimator.mSurfaceShown) {
                     // Window is now drawn (and shown).
                     try {
                         pair.second.sendResult(null);
@@ -8662,43 +8669,14 @@
         }
     }
 
-    /**
-     * Have the surface flinger show a surface, robustly dealing with
-     * error conditions.  In particular, if there is not enough memory
-     * to show the surface, then we will try to get rid of other surfaces
-     * in order to succeed.
-     *
-     * @return Returns true if the surface was successfully shown.
-     */
-    boolean showSurfaceRobustlyLocked(WindowState win) {
-        try {
-            if (win.mSurface != null) {
-                win.mSurfaceShown = true;
-                win.mSurface.show();
-                if (win.mTurnOnScreen) {
-                    if (DEBUG_VISIBILITY) Slog.v(TAG,
-                            "Show surface turning screen on: " + win);
-                    win.mTurnOnScreen = false;
-                    mTurnOnScreen = true;
-                }
-            }
-            return true;
-        } catch (RuntimeException e) {
-            Slog.w(TAG, "Failure showing surface " + win.mSurface + " in " + win, e);
-        }
-
-        reclaimSomeSurfaceMemoryLocked(win, "show", true);
-
-        return false;
-    }
-
-    boolean reclaimSomeSurfaceMemoryLocked(WindowState win, String operation, boolean secure) {
-        final Surface surface = win.mSurface;
+    boolean reclaimSomeSurfaceMemoryLocked(WindowStateAnimator winAnimator, String operation,
+                                           boolean secure) {
+        final Surface surface = winAnimator.mSurface;
         boolean leakedSurface = false;
         boolean killedApps = false;
 
-        EventLog.writeEvent(EventLogTags.WM_NO_SURFACE_MEMORY, win.toString(),
-                win.mSession.mPid, operation);
+        EventLog.writeEvent(EventLogTags.WM_NO_SURFACE_MEMORY, winAnimator.mWin.toString(),
+                winAnimator.mSession.mPid, operation);
 
         if (mForceRemoves == null) {
             mForceRemoves = new ArrayList<WindowState>();
@@ -8713,29 +8691,30 @@
             Slog.i(TAG, "Out of memory for surface!  Looking for leaks...");
             for (int i=0; i<N; i++) {
                 WindowState ws = mWindows.get(i);
-                if (ws.mSurface != null) {
-                    if (!mSessions.contains(ws.mSession)) {
+                WindowStateAnimator wsa = ws.mWinAnimator;
+                if (wsa.mSurface != null) {
+                    if (!mSessions.contains(wsa.mSession)) {
                         Slog.w(TAG, "LEAKED SURFACE (session doesn't exist): "
-                                + ws + " surface=" + ws.mSurface
-                                + " token=" + win.mToken
+                                + ws + " surface=" + wsa.mSurface
+                                + " token=" + ws.mToken
                                 + " pid=" + ws.mSession.mPid
                                 + " uid=" + ws.mSession.mUid);
                         if (SHOW_TRANSACTIONS) logSurface(ws, "LEAK DESTROY", null);
-                        ws.mSurface.destroy();
-                        ws.mSurfaceShown = false;
-                        ws.mSurface = null;
+                        wsa.mSurface.destroy();
+                        wsa.mSurfaceShown = false;
+                        wsa.mSurface = null;
                         mForceRemoves.add(ws);
                         i--;
                         N--;
                         leakedSurface = true;
                     } else if (ws.mAppToken != null && ws.mAppToken.clientHidden) {
                         Slog.w(TAG, "LEAKED SURFACE (app token hidden): "
-                                + ws + " surface=" + ws.mSurface
-                                + " token=" + win.mAppToken);
+                                + ws + " surface=" + wsa.mSurface
+                                + " token=" + ws.mAppToken);
                         if (SHOW_TRANSACTIONS) logSurface(ws, "LEAK DESTROY", null);
-                        ws.mSurface.destroy();
-                        ws.mSurfaceShown = false;
-                        ws.mSurface = null;
+                        wsa.mSurface.destroy();
+                        wsa.mSurfaceShown = false;
+                        wsa.mSurface = null;
                         leakedSurface = true;
                     }
                 }
@@ -8745,9 +8724,9 @@
                 Slog.w(TAG, "No leaked surfaces; killing applicatons!");
                 SparseIntArray pidCandidates = new SparseIntArray();
                 for (int i=0; i<N; i++) {
-                    WindowState ws = mWindows.get(i);
-                    if (ws.mSurface != null) {
-                        pidCandidates.append(ws.mSession.mPid, ws.mSession.mPid);
+                    WindowStateAnimator wsa = mWindows.get(i).mWinAnimator;
+                    if (wsa.mSurface != null) {
+                        pidCandidates.append(wsa.mSession.mPid, wsa.mSession.mPid);
                     }
                 }
                 if (pidCandidates.size() > 0) {
@@ -8769,15 +8748,15 @@
                 // surface and ask the app to request another one.
                 Slog.w(TAG, "Looks like we have reclaimed some memory, clearing surface for retry.");
                 if (surface != null) {
-                    if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) logSurface(win,
+                    if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) logSurface(winAnimator.mWin,
                             "RECOVER DESTROY", null);
                     surface.destroy();
-                    win.mSurfaceShown = false;
-                    win.mSurface = null;
+                    winAnimator.mSurfaceShown = false;
+                    winAnimator.mSurface = null;
                 }
 
                 try {
-                    win.mClient.dispatchGetNewSurface();
+                    winAnimator.mWin.mClient.dispatchGetNewSurface();
                 } catch (RemoteException e) {
                 }
             }
@@ -9503,7 +9482,7 @@
             synchronized(mWindowMap) {
                 for (int i=mWindows.size()-1; i>=0; i--) {
                     WindowState w = mWindows.get(i);
-                    if (w.mSurfaceShown) {
+                    if (w.mWinAnimator.mSurfaceShown) {
                         windows.add(w);
                     }
                 }
diff --git a/services/java/com/android/server/wm/WindowState.java b/services/java/com/android/server/wm/WindowState.java
index c0e01cb..789bfaa 100644
--- a/services/java/com/android/server/wm/WindowState.java
+++ b/services/java/com/android/server/wm/WindowState.java
@@ -88,10 +88,6 @@
     boolean mPolicyVisibility = true;
     boolean mPolicyVisibilityAfterAnim = true;
     boolean mAppFreezing;
-    Surface mSurface;
-    Surface mPendingDestroySurface;
-    boolean mReportDestroySurface;
-    boolean mSurfacePendingDestroy;
     boolean mAttachedHidden;    // is our parent window hidden?
     boolean mLastHidden;        // was this window last hidden?
     boolean mWallpaperVisible;  // for wallpaper, what was last vis report?
@@ -106,8 +102,6 @@
     int mLastRequestedHeight;
 
     int mLayer;
-    int mAnimLayer;
-    int mLastLayer;
     boolean mHaveFrame;
     boolean mObscured;
     boolean mTurnOnScreen;
@@ -124,18 +118,6 @@
     final RectF mShownFrame = new RectF();
 
     /**
-     * Set when we have changed the size of the surface, to know that
-     * we must tell them application to resize (and thus redraw itself).
-     */
-    boolean mSurfaceResized;
-
-    /**
-     * Set if the client has asked that the destroy of its surface be delayed
-     * until it explicitly says it is okay.
-     */
-    boolean mSurfaceDestroyDeferred;
-
-    /**
      * Insets that determine the actually visible area.  These are in the application's
      * coordinate space (without compatibility scale applied).
      */
@@ -183,11 +165,8 @@
     int mTouchableInsets = ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME;
 
     // Current transformation being applied.
-    boolean mHaveMatrix;
     float mGlobalScale=1;
     float mInvGlobalScale=1;
-    float mDsDx=1, mDtDx=0, mDsDy=0, mDtDy=1;
-    float mLastDsDx=1, mLastDtDx=0, mLastDsDy=0, mLastDtDy=1;
     float mHScale=1, mVScale=1;
     float mLastHScale=1, mLastVScale=1;
     final Matrix mTmpMatrix = new Matrix();
@@ -207,14 +186,6 @@
 
     boolean mContentChanged;
 
-    float mShownAlpha = 1;
-    float mAlpha = 1;
-    float mLastAlpha = 1;
-
-    // Set to true if, when the window gets displayed, it should perform
-    // an enter animation.
-    boolean mEnterAnimationPending;
-
     // If a window showing a wallpaper: the requested offset for the
     // wallpaper; if a wallpaper window: the currently applied offset.
     float mWallpaperX = -1;
@@ -279,12 +250,6 @@
     // rebuilding window list.
     boolean mRebuilding;
 
-    // For debugging, this is the last information given to the surface flinger.
-    boolean mSurfaceShown;
-    float mSurfaceX, mSurfaceY, mSurfaceW, mSurfaceH;
-    int mSurfaceLayer;
-    float mSurfaceAlpha;
-
     // Input channel and input window handle used by the input dispatcher.
     final InputWindowHandle mInputWindowHandle;
     InputChannel mInputChannel;
@@ -294,11 +259,6 @@
     CharSequence mLastTitle;
     boolean mWasPaused;
 
-    // Used to save animation distances between the time they are calculated and when they are 
-    // used.
-    int mAnimDw;
-    int mAnimDh;
-
     final WindowStateAnimator mWinAnimator;
 
     WindowState(WindowManagerService service, Session s, IWindow c, WindowToken token,
@@ -313,7 +273,6 @@
         mPolicy = mService.mPolicy;
         mContext = mService.mContext;
         DeathRecipient deathRecipient = new DeathRecipient();
-        mAlpha = a.alpha;
         mSeq = seq;
         mEnforceSizeCompat = (mAttrs.flags & FLAG_COMPATIBLE_WINDOW) != 0;
         if (WindowManagerService.localLOGV) Slog.v(
@@ -369,6 +328,7 @@
         }
 
         mWinAnimator = new WindowStateAnimator(service, this, mAttachedWindow);
+        mWinAnimator.mAlpha = a.alpha;
 
         WindowState appWin = this;
         while (appWin.mAttachedWindow != null) {
@@ -385,7 +345,6 @@
         mRootToken = appToken;
         mAppToken = appToken.appWindowToken;
 
-        mSurface = null;
         mRequestedWidth = 0;
         mRequestedHeight = 0;
         mLastRequestedWidth = 0;
@@ -393,8 +352,6 @@
         mXOffset = 0;
         mYOffset = 0;
         mLayer = 0;
-        mAnimLayer = 0;
-        mLastLayer = 0;
         mInputWindowHandle = new InputWindowHandle(
                 mAppToken != null ? mAppToken.mInputApplicationHandle : null, this);
     }
@@ -643,225 +600,11 @@
         return mAppToken != null ? mAppToken.firstWindowDrawn : false;
     }
 
-    Surface createSurfaceLocked() {
-        if (mSurface == null) {
-            mReportDestroySurface = false;
-            mSurfacePendingDestroy = false;
-            if (WindowManagerService.DEBUG_ORIENTATION) Slog.i(WindowManagerService.TAG,
-                    "createSurface " + this + ": DRAW NOW PENDING");
-            mDrawPending = true;
-            mCommitDrawPending = false;
-            mReadyToShow = false;
-            if (mAppToken != null) {
-                mAppToken.allDrawn = false;
-            }
-
-            mService.makeWindowFreezingScreenIfNeededLocked(this);
-
-            int flags = 0;
-
-            if ((mAttrs.flags&WindowManager.LayoutParams.FLAG_SECURE) != 0) {
-                flags |= Surface.SECURE;
-            }
-            if (DEBUG_VISIBILITY) Slog.v(
-                WindowManagerService.TAG, "Creating surface in session "
-                + mSession.mSurfaceSession + " window " + this
-                + " w=" + mCompatFrame.width()
-                + " h=" + mCompatFrame.height() + " format="
-                + mAttrs.format + " flags=" + flags);
-
-            int w = mCompatFrame.width();
-            int h = mCompatFrame.height();
-            if ((mAttrs.flags & LayoutParams.FLAG_SCALED) != 0) {
-                // for a scaled surface, we always want the requested
-                // size.
-                w = mRequestedWidth;
-                h = mRequestedHeight;
-            }
-
-            // Something is wrong and SurfaceFlinger will not like this,
-            // try to revert to sane values
-            if (w <= 0) w = 1;
-            if (h <= 0) h = 1;
-
-            mSurfaceShown = false;
-            mSurfaceLayer = 0;
-            mSurfaceAlpha = 1;
-            mSurfaceX = 0;
-            mSurfaceY = 0;
-            mSurfaceW = w;
-            mSurfaceH = h;
-            try {
-                final boolean isHwAccelerated = (mAttrs.flags &
-                        WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED) != 0;
-                final int format = isHwAccelerated ? PixelFormat.TRANSLUCENT : mAttrs.format;
-                if (!PixelFormat.formatHasAlpha(mAttrs.format)) {
-                    flags |= Surface.OPAQUE;
-                }
-                mSurface = new Surface(
-                        mSession.mSurfaceSession, mSession.mPid,
-                        mAttrs.getTitle().toString(),
-                        0, w, h, format, flags);
-                if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) Slog.i(WindowManagerService.TAG,
-                        "  CREATE SURFACE "
-                        + mSurface + " IN SESSION "
-                        + mSession.mSurfaceSession
-                        + ": pid=" + mSession.mPid + " format="
-                        + mAttrs.format + " flags=0x"
-                        + Integer.toHexString(flags)
-                        + " / " + this);
-            } catch (Surface.OutOfResourcesException e) {
-                Slog.w(WindowManagerService.TAG, "OutOfResourcesException creating surface");
-                mService.reclaimSomeSurfaceMemoryLocked(this, "create", true);
-                return null;
-            } catch (Exception e) {
-                Slog.e(WindowManagerService.TAG, "Exception creating surface", e);
-                return null;
-            }
-
-            if (WindowManagerService.localLOGV) Slog.v(
-                WindowManagerService.TAG, "Got surface: " + mSurface
-                + ", set left=" + mFrame.left + " top=" + mFrame.top
-                + ", animLayer=" + mAnimLayer);
-            if (SHOW_LIGHT_TRANSACTIONS) {
-                Slog.i(WindowManagerService.TAG, ">>> OPEN TRANSACTION createSurfaceLocked");
-                WindowManagerService.logSurface(this, "CREATE pos=(" + mFrame.left
-                        + "," + mFrame.top + ") (" +
-                        mCompatFrame.width() + "x" + mCompatFrame.height() + "), layer=" +
-                        mAnimLayer + " HIDE", null);
-            }
-            Surface.openTransaction();
-            try {
-                try {
-                    mSurfaceX = mFrame.left + mXOffset;
-                    mSurfaceY = mFrame.top + mYOffset;
-                    mSurface.setPosition(mSurfaceX, mSurfaceY);
-                    mSurfaceLayer = mAnimLayer;
-                    mSurface.setLayer(mAnimLayer);
-                    mSurfaceShown = false;
-                    mSurface.hide();
-                    if ((mAttrs.flags&WindowManager.LayoutParams.FLAG_DITHER) != 0) {
-                        if (SHOW_TRANSACTIONS) WindowManagerService.logSurface(this, "DITHER", null);
-                        mSurface.setFlags(Surface.SURFACE_DITHER,
-                                Surface.SURFACE_DITHER);
-                    }
-                } catch (RuntimeException e) {
-                    Slog.w(WindowManagerService.TAG, "Error creating surface in " + w, e);
-                    mService.reclaimSomeSurfaceMemoryLocked(this, "create-init", true);
-                }
-                mLastHidden = true;
-            } finally {
-                Surface.closeTransaction();
-                if (SHOW_LIGHT_TRANSACTIONS) Slog.i(WindowManagerService.TAG,
-                        "<<< CLOSE TRANSACTION createSurfaceLocked");
-            }
-            if (WindowManagerService.localLOGV) Slog.v(
-                    WindowManagerService.TAG, "Created surface " + this);
-        }
-        return mSurface;
-    }
-
-    void destroySurfaceLocked() {
-        if (mAppToken != null && this == mAppToken.startingWindow) {
-            mAppToken.startingDisplayed = false;
-        }
-
-        if (mSurface != null) {
-            mDrawPending = false;
-            mCommitDrawPending = false;
-            mReadyToShow = false;
-
-            int i = mChildWindows.size();
-            while (i > 0) {
-                i--;
-                WindowState c = mChildWindows.get(i);
-                c.mAttachedHidden = true;
-            }
-
-            if (mReportDestroySurface) {
-                mReportDestroySurface = false;
-                mSurfacePendingDestroy = true;
-                try {
-                    mClient.dispatchGetNewSurface();
-                    // We'll really destroy on the next time around.
-                    return;
-                } catch (RemoteException e) {
-                }
-            }
-
-            try {
-                if (DEBUG_VISIBILITY) {
-                    RuntimeException e = null;
-                    if (!WindowManagerService.HIDE_STACK_CRAWLS) {
-                        e = new RuntimeException();
-                        e.fillInStackTrace();
-                    }
-                    Slog.w(WindowManagerService.TAG, "Window " + this + " destroying surface "
-                            + mSurface + ", session " + mSession, e);
-                }
-                if (mSurfaceDestroyDeferred) {
-                    if (mSurface != null && mPendingDestroySurface != mSurface) {
-                        if (mPendingDestroySurface != null) {
-                            if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) {
-                                RuntimeException e = null;
-                                if (!WindowManagerService.HIDE_STACK_CRAWLS) {
-                                    e = new RuntimeException();
-                                    e.fillInStackTrace();
-                                }
-                                WindowManagerService.logSurface(this, "DESTROY PENDING", e);
-                            }
-                            mPendingDestroySurface.destroy();
-                        }
-                        mPendingDestroySurface = mSurface;
-                    }
-                } else {
-                    if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) {
-                        RuntimeException e = null;
-                        if (!WindowManagerService.HIDE_STACK_CRAWLS) {
-                            e = new RuntimeException();
-                            e.fillInStackTrace();
-                        }
-                        WindowManagerService.logSurface(this, "DESTROY", e);
-                    }
-                    mSurface.destroy();
-                }
-            } catch (RuntimeException e) {
-                Slog.w(WindowManagerService.TAG, "Exception thrown when destroying Window " + this
-                    + " surface " + mSurface + " session " + mSession
-                    + ": " + e.toString());
-            }
-
-            mSurfaceShown = false;
-            mSurface = null;
-        }
-    }
-
-    void destroyDeferredSurfaceLocked() {
-        try {
-            if (mPendingDestroySurface != null) {
-                if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) {
-                    RuntimeException e = null;
-                    if (!WindowManagerService.HIDE_STACK_CRAWLS) {
-                        e = new RuntimeException();
-                        e.fillInStackTrace();
-                    }
-                    mService.logSurface(this, "DESTROY PENDING", e);
-                }
-                mPendingDestroySurface.destroy();
-            }
-        } catch (RuntimeException e) {
-            Slog.w(WindowManagerService.TAG, "Exception thrown when destroying Window "
-                    + this + " surface " + mPendingDestroySurface
-                    + " session " + mSession + ": " + e.toString());
-        }
-        mSurfaceDestroyDeferred = false;
-        mPendingDestroySurface = null;
-    }
-
     boolean finishDrawingLocked() {
         if (mDrawPending) {
             if (SHOW_TRANSACTIONS || WindowManagerService.DEBUG_ORIENTATION) Slog.v(
-                WindowManagerService.TAG, "finishDrawingLocked: " + this + " in " + mSurface);
+                WindowManagerService.TAG, "finishDrawingLocked: " + this + " in "
+                        + mWinAnimator.mSurface);
             mCommitDrawPending = true;
             mDrawPending = false;
             return true;
@@ -880,93 +623,7 @@
         final boolean starting = mAttrs.type == TYPE_APPLICATION_STARTING;
         final AppWindowToken atoken = mAppToken;
         if (atoken == null || atoken.allDrawn || starting) {
-            performShowLocked();
-        }
-        return true;
-    }
-
-    // This must be called while inside a transaction.
-    boolean performShowLocked() {
-        if (DEBUG_VISIBILITY) {
-            RuntimeException e = null;
-            if (!WindowManagerService.HIDE_STACK_CRAWLS) {
-                e = new RuntimeException();
-                e.fillInStackTrace();
-            }
-            Slog.v(WindowManagerService.TAG, "performShow on " + this
-                    + ": readyToShow=" + mReadyToShow + " readyForDisplay=" + isReadyForDisplay()
-                    + " starting=" + (mAttrs.type == TYPE_APPLICATION_STARTING), e);
-        }
-        if (mReadyToShow && isReadyForDisplay()) {
-            if (SHOW_TRANSACTIONS || WindowManagerService.DEBUG_ORIENTATION) WindowManagerService.logSurface(this,
-                    "SHOW (performShowLocked)", null);
-            if (DEBUG_VISIBILITY) Slog.v(WindowManagerService.TAG, "Showing " + this
-                    + " during animation: policyVis=" + mPolicyVisibility
-                    + " attHidden=" + mAttachedHidden
-                    + " tok.hiddenRequested="
-                    + (mAppToken != null ? mAppToken.hiddenRequested : false)
-                    + " tok.hidden="
-                    + (mAppToken != null ? mAppToken.hidden : false)
-                    + " animating=" + mWinAnimator.mAnimating
-                    + " tok animating="
-                    + (mAppToken != null ? mAppToken.animating : false));
-            if (!mService.showSurfaceRobustlyLocked(this)) {
-                return false;
-            }
-            
-            mService.enableScreenIfNeededLocked();
-
-            applyEnterAnimationLocked();
-
-            mLastAlpha = -1;
-            mHasDrawn = true;
-            mLastHidden = false;
-            mReadyToShow = false;
-
-            int i = mChildWindows.size();
-            while (i > 0) {
-                i--;
-                WindowState c = mChildWindows.get(i);
-                if (c.mAttachedHidden) {
-                    c.mAttachedHidden = false;
-                    if (c.mSurface != null) {
-                        c.performShowLocked();
-                        // It hadn't been shown, which means layout not
-                        // performed on it, so now we want to make sure to
-                        // do a layout.  If called from within the transaction
-                        // loop, this will cause it to restart with a new
-                        // layout.
-                        mService.mLayoutNeeded = true;
-                    }
-                }
-            }
-
-            if (mAttrs.type != TYPE_APPLICATION_STARTING
-                    && mAppToken != null) {
-                mAppToken.firstWindowDrawn = true;
-
-                if (mAppToken.startingData != null) {
-                    if (WindowManagerService.DEBUG_STARTING_WINDOW ||
-                            WindowManagerService.DEBUG_ANIM) Slog.v(WindowManagerService.TAG,
-                            "Finish starting " + mToken
-                            + ": first real window is shown, no animation");
-                    // If this initial window is animating, stop it -- we
-                    // will do an animation to reveal it from behind the
-                    // starting window, so there is no need for it to also
-                    // be doing its own stuff.
-                    if (mWinAnimator.mAnimation != null) {
-                        mWinAnimator.mAnimation.cancel();
-                        mWinAnimator.mAnimation = null;
-                        // Make sure we clean up the animation.
-                        mWinAnimator.mAnimating = true;
-                    }
-                    mService.mFinishedStarting.add(mAppToken);
-                    mService.mH.sendEmptyMessage(H.FINISHED_STARTING);
-                }
-                mAppToken.updateReportedVisibilityLocked();
-            }
-        } else {
-            return false;
+            mWinAnimator.performShowLocked();
         }
         return true;
     }
@@ -988,150 +645,6 @@
         }
     }
 
-    void computeShownFrameLocked() {
-        final boolean selfTransformation = mWinAnimator.mHasLocalTransformation;
-        Transformation attachedTransformation =
-                (mAttachedWindow != null && mAttachedWindow.mWinAnimator.mHasLocalTransformation)
-                ? mAttachedWindow.mWinAnimator.mTransformation : null;
-        Transformation appTransformation =
-                (mAppToken != null && mAppToken.hasTransformation)
-                ? mAppToken.transformation : null;
-
-        // Wallpapers are animated based on the "real" window they
-        // are currently targeting.
-        if (mAttrs.type == TYPE_WALLPAPER && mService.mLowerWallpaperTarget == null
-                && mService.mWallpaperTarget != null) {
-            if (mService.mWallpaperTarget.mWinAnimator.mHasLocalTransformation &&
-                    mService.mWallpaperTarget.mWinAnimator.mAnimation != null &&
-                    !mService.mWallpaperTarget.mWinAnimator.mAnimation.getDetachWallpaper()) {
-                attachedTransformation = mService.mWallpaperTarget.mWinAnimator.mTransformation;
-                if (WindowManagerService.DEBUG_WALLPAPER && attachedTransformation != null) {
-                    Slog.v(WindowManagerService.TAG, "WP target attached xform: " + attachedTransformation);
-                }
-            }
-            if (mService.mWallpaperTarget.mAppToken != null &&
-                    mService.mWallpaperTarget.mAppToken.hasTransformation &&
-                    mService.mWallpaperTarget.mAppToken.animation != null &&
-                    !mService.mWallpaperTarget.mAppToken.animation.getDetachWallpaper()) {
-                appTransformation = mService.mWallpaperTarget.mAppToken.transformation;
-                if (WindowManagerService.DEBUG_WALLPAPER && appTransformation != null) {
-                    Slog.v(WindowManagerService.TAG, "WP target app xform: " + appTransformation);
-                }
-            }
-        }
-
-        final boolean screenAnimation = mService.mAnimator.mScreenRotationAnimation != null
-                && mService.mAnimator.mScreenRotationAnimation.isAnimating();
-        if (selfTransformation || attachedTransformation != null
-                || appTransformation != null || screenAnimation) {
-            // cache often used attributes locally
-            final Rect frame = mFrame;
-            final float tmpFloats[] = mService.mTmpFloats;
-            final Matrix tmpMatrix = mTmpMatrix;
-
-            // Compute the desired transformation.
-            if (screenAnimation) {
-                // If we are doing a screen animation, the global rotation
-                // applied to windows can result in windows that are carefully
-                // aligned with each other to slightly separate, allowing you
-                // to see what is behind them.  An unsightly mess.  This...
-                // thing...  magically makes it call good: scale each window
-                // slightly (two pixels larger in each dimension, from the
-                // window's center).
-                final float w = frame.width();
-                final float h = frame.height();
-                if (w>=1 && h>=1) {
-                    tmpMatrix.setScale(1 + 2/w, 1 + 2/h, w/2, h/2);
-                } else {
-                    tmpMatrix.reset();
-                }
-            } else {
-                tmpMatrix.reset();
-            }
-            tmpMatrix.postScale(mGlobalScale, mGlobalScale);
-            if (selfTransformation) {
-                tmpMatrix.postConcat(mWinAnimator.mTransformation.getMatrix());
-            }
-            tmpMatrix.postTranslate(frame.left + mXOffset, frame.top + mYOffset);
-            if (attachedTransformation != null) {
-                tmpMatrix.postConcat(attachedTransformation.getMatrix());
-            }
-            if (appTransformation != null) {
-                tmpMatrix.postConcat(appTransformation.getMatrix());
-            }
-            if (screenAnimation) {
-                tmpMatrix.postConcat(
-                        mService.mAnimator.mScreenRotationAnimation.getEnterTransformation().getMatrix());
-            }
-
-            // "convert" it into SurfaceFlinger's format
-            // (a 2x2 matrix + an offset)
-            // Here we must not transform the position of the surface
-            // since it is already included in the transformation.
-            //Slog.i(TAG, "Transform: " + matrix);
-
-            mHaveMatrix = true;
-            tmpMatrix.getValues(tmpFloats);
-            mDsDx = tmpFloats[Matrix.MSCALE_X];
-            mDtDx = tmpFloats[Matrix.MSKEW_Y];
-            mDsDy = tmpFloats[Matrix.MSKEW_X];
-            mDtDy = tmpFloats[Matrix.MSCALE_Y];
-            float x = tmpFloats[Matrix.MTRANS_X];
-            float y = tmpFloats[Matrix.MTRANS_Y];
-            int w = frame.width();
-            int h = frame.height();
-            mShownFrame.set(x, y, x+w, y+h);
-
-            // Now set the alpha...  but because our current hardware
-            // can't do alpha transformation on a non-opaque surface,
-            // turn it off if we are running an animation that is also
-            // transforming since it is more important to have that
-            // animation be smooth.
-            mShownAlpha = mAlpha;
-            if (!mService.mLimitedAlphaCompositing
-                    || (!PixelFormat.formatHasAlpha(mAttrs.format)
-                    || (isIdentityMatrix(mDsDx, mDtDx, mDsDy, mDtDy)
-                            && x == frame.left && y == frame.top))) {
-                //Slog.i(TAG, "Applying alpha transform");
-                if (selfTransformation) {
-                    mShownAlpha *= mWinAnimator.mTransformation.getAlpha();
-                }
-                if (attachedTransformation != null) {
-                    mShownAlpha *= attachedTransformation.getAlpha();
-                }
-                if (appTransformation != null) {
-                    mShownAlpha *= appTransformation.getAlpha();
-                }
-                if (screenAnimation) {
-                    mShownAlpha *=
-                        mService.mAnimator.mScreenRotationAnimation.getEnterTransformation().getAlpha();
-                }
-            } else {
-                //Slog.i(TAG, "Not applying alpha transform");
-            }
-
-            if (WindowManagerService.localLOGV) Slog.v(
-                WindowManagerService.TAG, "computeShownFrameLocked: Animating " + this +
-                ": " + mShownFrame +
-                ", alpha=" + mWinAnimator.mTransformation.getAlpha() + ", mShownAlpha=" + mShownAlpha);
-            return;
-        }
-
-        if (WindowManagerService.localLOGV) Slog.v(
-            WindowManagerService.TAG, "computeShownFrameLocked: " + this +
-            " not attached, mAlpha=" + mAlpha);
-        mShownFrame.set(mFrame);
-        if (mXOffset != 0 || mYOffset != 0) {
-            mShownFrame.offset(mXOffset, mYOffset);
-        }
-        mShownAlpha = mAlpha;
-        mHaveMatrix = false;
-        mDsDx = mGlobalScale;
-        mDtDx = 0;
-        mDsDy = 0;
-        mDtDy = mGlobalScale;
-    }
-
     /**
      * Is this window visible?  It is not visible if there is no
      * surface, or we are in the process of running an exit animation
@@ -1139,7 +652,7 @@
      */
     public boolean isVisibleLw() {
         final AppWindowToken atoken = mAppToken;
-        return mSurface != null && mPolicyVisibility && !mAttachedHidden
+        return mWinAnimator.mSurface != null && mPolicyVisibility && !mAttachedHidden
                 && (atoken == null || !atoken.hiddenRequested)
                 && !mExiting && !mDestroying;
     }
@@ -1160,7 +673,7 @@
         final AppWindowToken atoken = mAppToken;
         final boolean animating = atoken != null
                 ? (atoken.animation != null) : false;
-        return mSurface != null && !mDestroying && !mExiting
+        return mWinAnimator.mSurface != null && !mDestroying && !mExiting
                 && (atoken == null ? mPolicyVisibility : !atoken.hiddenRequested)
                 && ((!mAttachedHidden && mViewVisibility == View.VISIBLE
                                 && !mRootToken.hidden)
@@ -1174,7 +687,7 @@
      */
     public boolean isWinVisibleLw() {
         final AppWindowToken atoken = mAppToken;
-        return mSurface != null && mPolicyVisibility && !mAttachedHidden
+        return mWinAnimator.mSurface != null && mPolicyVisibility && !mAttachedHidden
                 && (atoken == null || !atoken.hiddenRequested || atoken.animating)
                 && !mExiting && !mDestroying;
     }
@@ -1184,7 +697,7 @@
      * the associated app token, not the pending requested hidden state.
      */
     boolean isVisibleNow() {
-        return mSurface != null && mPolicyVisibility && !mAttachedHidden
+        return mWinAnimator.mSurface != null && mPolicyVisibility && !mAttachedHidden
                 && !mRootToken.hidden && !mExiting && !mDestroying;
     }
 
@@ -1204,7 +717,7 @@
      */
     boolean isVisibleOrAdding() {
         final AppWindowToken atoken = mAppToken;
-        return ((mSurface != null && !mReportDestroySurface)
+        return ((mWinAnimator.mSurface != null && !mWinAnimator.mReportDestroySurface)
                         || (!mRelayoutCalled && mViewVisibility == View.VISIBLE))
                 && mPolicyVisibility && !mAttachedHidden
                 && (atoken == null || !atoken.hiddenRequested)
@@ -1219,11 +732,11 @@
     boolean isOnScreen() {
         final AppWindowToken atoken = mAppToken;
         if (atoken != null) {
-            return mSurface != null && mPolicyVisibility && !mDestroying
+            return mWinAnimator.mSurface != null && mPolicyVisibility && !mDestroying
                     && ((!mAttachedHidden && !atoken.hiddenRequested)
                             || mWinAnimator.mAnimation != null || atoken.animation != null);
         } else {
-            return mSurface != null && mPolicyVisibility && !mDestroying
+            return mWinAnimator.mSurface != null && mPolicyVisibility && !mDestroying
                     && (!mAttachedHidden || mWinAnimator.mAnimation != null);
         }
     }
@@ -1237,7 +750,7 @@
                 mService.mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
             return false;
         }
-        return mSurface != null && mPolicyVisibility && !mDestroying
+        return mWinAnimator.mSurface != null && mPolicyVisibility && !mDestroying
                 && ((!mAttachedHidden && mViewVisibility == View.VISIBLE
                                 && !mRootToken.hidden)
                         || mWinAnimator.mAnimation != null
@@ -1271,7 +784,7 @@
      * complete UI in to.
      */
     public boolean isDrawnLw() {
-        return mSurface != null && !mDestroying
+        return mWinAnimator.mSurface != null && !mDestroying
             && !mDrawPending && !mCommitDrawPending;
     }
 
@@ -1298,89 +811,6 @@
                 && (mAttachedWindow == null || !mAttachedWindow.shouldAnimateMove());
     }
 
-    void applyEnterAnimationLocked() {
-        final int transit;
-        if (mEnterAnimationPending) {
-            mEnterAnimationPending = false;
-            transit = WindowManagerPolicy.TRANSIT_ENTER;
-        } else {
-            transit = WindowManagerPolicy.TRANSIT_SHOW;
-        }
-
-        applyAnimationLocked(transit, true);
-    }
-
-    /**
-     * Choose the correct animation and set it to the passed WindowState.
-     * @param win The window to add the animation to.
-     * @param transit If WindowManagerPolicy.TRANSIT_PREVIEW_DONE and the app window has been drawn
-     *      then the animation will be app_starting_exit. Any other value loads the animation from
-     *      the switch statement below.
-     * @param isEntrance The animation type the last time this was called. Used to keep from
-     *      loading the same animation twice.
-     * @return true if an animation has been loaded.
-     */
-    boolean applyAnimationLocked(int transit, boolean isEntrance) {
-        if (mWinAnimator.mLocalAnimating &&
-                mWinAnimator.mAnimationIsEntrance == isEntrance) {
-            // If we are trying to apply an animation, but already running
-            // an animation of the same type, then just leave that one alone.
-            return true;
-        }
-
-        // Only apply an animation if the display isn't frozen.  If it is
-        // frozen, there is no reason to animate and it can cause strange
-        // artifacts when we unfreeze the display if some different animation
-        // is running.
-        if (mService.okToDisplay()) {
-            int anim = mPolicy.selectAnimationLw(this, transit);
-            int attr = -1;
-            Animation a = null;
-            if (anim != 0) {
-                a = AnimationUtils.loadAnimation(mContext, anim);
-            } else {
-                switch (transit) {
-                    case WindowManagerPolicy.TRANSIT_ENTER:
-                        attr = com.android.internal.R.styleable.WindowAnimation_windowEnterAnimation;
-                        break;
-                    case WindowManagerPolicy.TRANSIT_EXIT:
-                        attr = com.android.internal.R.styleable.WindowAnimation_windowExitAnimation;
-                        break;
-                    case WindowManagerPolicy.TRANSIT_SHOW:
-                        attr = com.android.internal.R.styleable.WindowAnimation_windowShowAnimation;
-                        break;
-                    case WindowManagerPolicy.TRANSIT_HIDE:
-                        attr = com.android.internal.R.styleable.WindowAnimation_windowHideAnimation;
-                        break;
-                }
-                if (attr >= 0) {
-                    a = mService.loadAnimation(mAttrs, attr);
-                }
-            }
-            if (WindowManagerService.DEBUG_ANIM) Slog.v(WindowManagerService.TAG,
-                    "applyAnimation: win=" + this
-                    + " anim=" + anim + " attr=0x" + Integer.toHexString(attr)
-                    + " mAnimation=" + mWinAnimator.mAnimation
-                    + " isEntrance=" + isEntrance);
-            if (a != null) {
-                if (WindowManagerService.DEBUG_ANIM) {
-                    RuntimeException e = null;
-                    if (!WindowManagerService.HIDE_STACK_CRAWLS) {
-                        e = new RuntimeException();
-                        e.fillInStackTrace();
-                    }
-                    Slog.v(WindowManagerService.TAG, "Loaded animation " + a + " for " + this, e);
-                }
-                mWinAnimator.setAnimation(a);
-                mWinAnimator.mAnimationIsEntrance = isEntrance;
-            }
-        } else {
-            mWinAnimator.clearAnimation();
-        }
-
-        return mWinAnimator.mAnimation != null;
-    }
-
     boolean isFullscreen(int screenWidth, int screenHeight) {
         return mFrame.left <= 0 && mFrame.top <= 0 &&
                 mFrame.right >= screenWidth && mFrame.bottom >= screenHeight;
@@ -1393,8 +823,8 @@
             if (WindowManagerService.DEBUG_ADD_REMOVE) Slog.v(WindowManagerService.TAG, "Removing " + this + " from " + mAttachedWindow);
             mAttachedWindow.mChildWindows.remove(this);
         }
-        destroyDeferredSurfaceLocked();
-        destroySurfaceLocked();
+        mWinAnimator.destroyDeferredSurfaceLocked();
+        mWinAnimator.destroySurfaceLocked();
         mSession.windowRemovedLocked();
         try {
             mClient.asBinder().unlinkToDeath(mDeathRecipient, 0);
@@ -1477,7 +907,7 @@
         mPolicyVisibility = true;
         mPolicyVisibilityAfterAnim = true;
         if (doAnimation) {
-            applyAnimationLocked(WindowManagerPolicy.TRANSIT_ENTER, true);
+            mWinAnimator.applyAnimationLocked(WindowManagerPolicy.TRANSIT_ENTER, true);
         }
         if (requestAnim) {
             mService.scheduleAnimationLocked();
@@ -1502,7 +932,7 @@
             return false;
         }
         if (doAnimation) {
-            applyAnimationLocked(WindowManagerPolicy.TRANSIT_EXIT, false);
+            mWinAnimator.applyAnimationLocked(WindowManagerPolicy.TRANSIT_EXIT, false);
             if (mWinAnimator.mAnimation == null) {
                 doAnimation = false;
             }
@@ -1582,24 +1012,8 @@
                     pw.print(" mAnimLayer="); pw.print(mLayer); pw.print("+");
                     pw.print((mTargetAppToken != null ? mTargetAppToken.animLayerAdjustment
                           : (mAppToken != null ? mAppToken.animLayerAdjustment : 0)));
-                    pw.print("="); pw.print(mAnimLayer);
-                    pw.print(" mLastLayer="); pw.println(mLastLayer);
-        }
-        if (mSurface != null) {
-            if (dumpAll) {
-                pw.print(prefix); pw.print("mSurface="); pw.println(mSurface);
-            }
-            pw.print(prefix); pw.print("Surface: shown="); pw.print(mSurfaceShown);
-                    pw.print(" layer="); pw.print(mSurfaceLayer);
-                    pw.print(" alpha="); pw.print(mSurfaceAlpha);
-                    pw.print(" rect=("); pw.print(mSurfaceX);
-                    pw.print(","); pw.print(mSurfaceY);
-                    pw.print(") "); pw.print(mSurfaceW);
-                    pw.print(" x "); pw.println(mSurfaceH);
-        }
-        if (mPendingDestroySurface != null) {
-            pw.print(prefix); pw.print("mPendingDestroySurface=");
-                    pw.println(mPendingDestroySurface);
+                    pw.print("="); pw.print(mWinAnimator.mAnimLayer);
+                    pw.print(" mLastLayer="); pw.println(mWinAnimator.mLastLayer);
         }
         if (dumpAll) {
             pw.print(prefix); pw.print("mToken="); pw.println(mToken);
@@ -1630,10 +1044,6 @@
             pw.print(prefix); pw.print("mRelayoutCalled="); pw.print(mRelayoutCalled);
                     pw.print(" mLayoutNeeded="); pw.println(mLayoutNeeded);
         }
-        if (mSurfaceResized || mSurfaceDestroyDeferred) {
-            pw.print(prefix); pw.print("mSurfaceResized="); pw.print(mSurfaceResized);
-                    pw.print(" mSurfaceDestroyDeferred="); pw.println(mSurfaceDestroyDeferred);
-        }
         if (mXOffset != 0 || mYOffset != 0) {
             pw.print(prefix); pw.print("Offsets x="); pw.print(mXOffset);
                     pw.print(" y="); pw.println(mYOffset);
@@ -1679,18 +1089,6 @@
                     pw.println();
         }
         mWinAnimator.dump(pw, prefix, dumpAll);
-        if (mShownAlpha != 1 || mAlpha != 1 || mLastAlpha != 1) {
-            pw.print(prefix); pw.print("mShownAlpha="); pw.print(mShownAlpha);
-                    pw.print(" mAlpha="); pw.print(mAlpha);
-                    pw.print(" mLastAlpha="); pw.println(mLastAlpha);
-        }
-        if (mHaveMatrix || mGlobalScale != 1) {
-            pw.print(prefix); pw.print("mGlobalScale="); pw.print(mGlobalScale);
-                    pw.print(" mDsDx="); pw.print(mDsDx);
-                    pw.print(" mDtDx="); pw.print(mDtDx);
-                    pw.print(" mDsDy="); pw.print(mDsDy);
-                    pw.print(" mDtDy="); pw.println(mDtDy);
-        }
         if (dumpAll) {
             pw.print(prefix); pw.print("mDrawPending="); pw.print(mDrawPending);
                     pw.print(" mCommitDrawPending="); pw.print(mCommitDrawPending);
diff --git a/services/java/com/android/server/wm/WindowStateAnimator.java b/services/java/com/android/server/wm/WindowStateAnimator.java
index 73573d7..789e74b 100644
--- a/services/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/java/com/android/server/wm/WindowStateAnimator.java
@@ -2,10 +2,21 @@
 
 package com.android.server.wm;
 
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
+import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
+
+import android.content.Context;
+import android.graphics.Matrix;
+import android.graphics.PixelFormat;
+import android.graphics.Rect;
+import android.os.RemoteException;
 import android.util.Slog;
+import android.view.Surface;
 import android.view.WindowManager;
 import android.view.WindowManagerPolicy;
+import android.view.WindowManager.LayoutParams;
 import android.view.animation.Animation;
+import android.view.animation.AnimationUtils;
 import android.view.animation.Transformation;
 
 import com.android.server.wm.WindowManagerService.H;
@@ -13,15 +24,27 @@
 import java.io.PrintWriter;
 
 /**
- * @author cmautner@google.com (Craig Mautner)
- *
- */
+ * Keep track of animations and surface operations for a single WindowState.
+ **/
 class WindowStateAnimator {
+    static final boolean DEBUG_VISIBILITY = WindowManagerService.DEBUG_VISIBILITY;
+    static final boolean DEBUG_ANIM = WindowManagerService.DEBUG_ANIM;
+    static final boolean DEBUG_LAYERS = WindowManagerService.DEBUG_LAYERS;
+    static final boolean DEBUG_STARTING_WINDOW = WindowManagerService.DEBUG_STARTING_WINDOW;
+    static final boolean SHOW_TRANSACTIONS = WindowManagerService.SHOW_TRANSACTIONS;
+    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 String TAG = "WindowStateAnimator";
 
     final WindowManagerService mService;
     final WindowState mWin;
     final WindowState mAttachedWindow;
     final WindowAnimator mAnimator;
+    final Session mSession;
+    final WindowManagerPolicy mPolicy;
+    final Context mContext;
 
     // Currently running animation.
     boolean mAnimating;
@@ -32,6 +55,48 @@
     boolean mHasLocalTransformation;
     final Transformation mTransformation = new Transformation();
     boolean mWasAnimating;      // Were we animating going into the most recent animation step?
+    int mAnimLayer;
+    int mLastLayer;
+
+    Surface mSurface;
+    Surface mPendingDestroySurface;
+    boolean mReportDestroySurface;
+    boolean mSurfacePendingDestroy;
+
+    /**
+     * Set when we have changed the size of the surface, to know that
+     * we must tell them application to resize (and thus redraw itself).
+     */
+    boolean mSurfaceResized;
+
+    /**
+     * Set if the client has asked that the destroy of its surface be delayed
+     * until it explicitly says it is okay.
+     */
+    boolean mSurfaceDestroyDeferred;
+
+    float mShownAlpha = 1;
+    float mAlpha = 1;
+    float mLastAlpha = 1;
+
+    // Used to save animation distances between the time they are calculated and when they are
+    // used.
+    int mAnimDw;
+    int mAnimDh;
+    float mDsDx=1, mDtDx=0, mDsDy=0, mDtDy=1;
+    float mLastDsDx=1, mLastDtDx=0, mLastDsDy=0, mLastDtDy=1;
+
+    boolean mHaveMatrix;
+
+    // For debugging, this is the last information given to the surface flinger.
+    boolean mSurfaceShown;
+    float mSurfaceX, mSurfaceY, mSurfaceW, mSurfaceH;
+    int mSurfaceLayer;
+    float mSurfaceAlpha;
+
+    // Set to true if, when the window gets displayed, it should perform
+    // an enter animation.
+    boolean mEnterAnimationPending;
 
     public WindowStateAnimator(final WindowManagerService service, final WindowState win,
                                final WindowState attachedWindow) {
@@ -39,11 +104,14 @@
         mWin = win;
         mAttachedWindow = attachedWindow;
         mAnimator = mService.mAnimator;
+        mSession = win.mSession;
+        mPolicy = mService.mPolicy;
+        mContext = mService.mContext;
     }
 
     public void setAnimation(Animation anim) {
-        if (WindowManagerService.localLOGV) Slog.v(
-            WindowManagerService.TAG, "Setting animation in " + this + ": " + anim);
+        if (localLOGV) Slog.v(
+            TAG, "Setting animation in " + this + ": " + anim);
         mAnimating = false;
         mLocalAnimating = false;
         mAnimation = anim;
@@ -80,14 +148,12 @@
         return mAnimation != null;
     }
 
-    // TODO: Fix and call finishExit() instead of cancelExitAnimationForNextAnimationLocked()
-    // for avoiding the code duplication.
     void cancelExitAnimationForNextAnimationLocked() {
         if (!mWin.mExiting) return;
         if (mAnimation != null) {
             mAnimation.cancel();
             mAnimation = null;
-            mWin.destroySurfaceLocked();
+            destroySurfaceLocked();
         }
         mWin.mExiting = false;
     }
@@ -98,8 +164,8 @@
         }
         mTransformation.clear();
         final boolean more = mAnimation.getTransformation(currentTime, mTransformation);
-        if (WindowManagerService.DEBUG_ANIM) Slog.v(
-            WindowManagerService.TAG, "Stepped animation in " + this +
+        if (DEBUG_ANIM) Slog.v(
+            TAG, "Stepped animation in " + this +
             ": more=" + more + ", xform=" + mTransformation);
         return more;
     }
@@ -117,14 +183,14 @@
                 mHasTransformation = true;
                 mHasLocalTransformation = true;
                 if (!mLocalAnimating) {
-                    if (WindowManagerService.DEBUG_ANIM) Slog.v(
-                        WindowManagerService.TAG, "Starting animation in " + this +
+                    if (DEBUG_ANIM) Slog.v(
+                        TAG, "Starting animation in " + this +
                         " @ " + currentTime + ": ww=" + mWin.mFrame.width() +
                         " wh=" + mWin.mFrame.height() +
-                        " dw=" + mWin.mAnimDw + " dh=" + mWin.mAnimDh +
+                        " dw=" + mAnimDw + " dh=" + mAnimDh +
                         " scale=" + mService.mWindowAnimationScale);
-                    mAnimation.initialize(mWin.mFrame.width(), mWin.mFrame.height(), mWin.mAnimDw,
-                        mWin.mAnimDh);
+                    mAnimation.initialize(mWin.mFrame.width(), mWin.mFrame.height(),
+                            mAnimDw, mAnimDh);
                     mAnimation.setStartTime(currentTime);
                     mLocalAnimating = true;
                     mAnimating = true;
@@ -134,8 +200,8 @@
                         return true;
                     }
                 }
-                if (WindowManagerService.DEBUG_ANIM) Slog.v(
-                    WindowManagerService.TAG, "Finished animation in " + this +
+                if (DEBUG_ANIM) Slog.v(
+                    TAG, "Finished animation in " + this +
                     " @ " + currentTime);
                 //WindowManagerService.this.dump();
             }
@@ -173,8 +239,9 @@
             return false;
         }
 
-        if (WindowManagerService.DEBUG_ANIM) Slog.v(
-            WindowManagerService.TAG, "Animation done in " + this + ": exiting=" + mWin.mExiting
+        // Done animating, clean up.
+        if (DEBUG_ANIM) Slog.v(
+            TAG, "Animation done in " + this + ": exiting=" + mWin.mExiting
             + ", reportedVisible="
             + (mWin.mAppToken != null ? mWin.mAppToken.reportedVisible : false));
 
@@ -187,19 +254,19 @@
         if (mAnimator.mWindowDetachedWallpaper == mWin) {
             mAnimator.mWindowDetachedWallpaper = null;
         }
-        mWin.mAnimLayer = mWin.mLayer;
+        mAnimLayer = mWin.mLayer;
         if (mWin.mIsImWindow) {
-            mWin.mAnimLayer += mService.mInputMethodAnimLayerAdjustment;
+            mAnimLayer += mService.mInputMethodAnimLayerAdjustment;
         } else if (mWin.mIsWallpaper) {
-            mWin.mAnimLayer += mService.mWallpaperAnimLayerAdjustment;
+            mAnimLayer += mService.mWallpaperAnimLayerAdjustment;
         }
-        if (WindowManagerService.DEBUG_LAYERS) Slog.v(WindowManagerService.TAG, "Stepping win " + this
-                + " anim layer: " + mWin.mAnimLayer);
+        if (DEBUG_LAYERS) Slog.v(TAG, "Stepping win " + this
+                + " anim layer: " + mAnimLayer);
         mHasTransformation = false;
         mHasLocalTransformation = false;
         if (mWin.mPolicyVisibility != mWin.mPolicyVisibilityAfterAnim) {
             if (WindowState.DEBUG_VISIBILITY) {
-                Slog.v(WindowManagerService.TAG, "Policy visibility changing after anim in " + this + ": "
+                Slog.v(TAG, "Policy visibility changing after anim in " + this + ": "
                         + mWin.mPolicyVisibilityAfterAnim);
             }
             mWin.mPolicyVisibility = mWin.mPolicyVisibilityAfterAnim;
@@ -220,7 +287,7 @@
                 && mWin.mAppToken != null
                 && mWin.mAppToken.firstWindowDrawn
                 && mWin.mAppToken.startingData != null) {
-            if (WindowManagerService.DEBUG_STARTING_WINDOW) Slog.v(WindowManagerService.TAG, "Finish starting "
+            if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Finish starting "
                     + mWin.mToken + ": first real window done animating");
             mService.mFinishedStarting.add(mWin.mAppToken);
             mService.mH.sendEmptyMessage(H.FINISHED_STARTING);
@@ -239,7 +306,7 @@
 
     void finishExit() {
         if (WindowManagerService.DEBUG_ANIM) Slog.v(
-                WindowManagerService.TAG, "finishExit in " + this
+                TAG, "finishExit in " + this
                 + ": exiting=" + mWin.mExiting
                 + " remove=" + mWin.mRemoveOnExit
                 + " windowAnimating=" + isWindowAnimating());
@@ -258,18 +325,18 @@
         }
 
         if (WindowManagerService.localLOGV) Slog.v(
-                WindowManagerService.TAG, "Exit animation finished in " + this
+                TAG, "Exit animation finished in " + this
                 + ": remove=" + mWin.mRemoveOnExit);
-        if (mWin.mSurface != null) {
+        if (mSurface != null) {
             mService.mDestroySurface.add(mWin);
             mWin.mDestroying = true;
             if (WindowState.SHOW_TRANSACTIONS) WindowManagerService.logSurface(
                 mWin, "HIDE (finishExit)", null);
-            mWin.mSurfaceShown = false;
+            mSurfaceShown = false;
             try {
-                mWin.mSurface.hide();
+                mSurface.hide();
             } catch (RuntimeException e) {
-                Slog.w(WindowManagerService.TAG, "Error hiding surface in " + this, e);
+                Slog.w(TAG, "Error hiding surface in " + this, e);
             }
             mWin.mLastHidden = true;
         }
@@ -280,6 +347,742 @@
         }
     }
 
+    Surface createSurfaceLocked() {
+        if (mSurface == null) {
+            mReportDestroySurface = false;
+            mSurfacePendingDestroy = false;
+            if (WindowManagerService.DEBUG_ORIENTATION) Slog.i(TAG,
+                    "createSurface " + this + ": DRAW NOW PENDING");
+            mWin.mDrawPending = true;
+            mWin.mCommitDrawPending = false;
+            mWin.mReadyToShow = false;
+            if (mWin.mAppToken != null) {
+                mWin.mAppToken.allDrawn = false;
+            }
+
+            mService.makeWindowFreezingScreenIfNeededLocked(mWin);
+
+            int flags = 0;
+            final WindowManager.LayoutParams attrs = mWin.mAttrs;
+
+            if ((attrs.flags&WindowManager.LayoutParams.FLAG_SECURE) != 0) {
+                flags |= Surface.SECURE;
+            }
+            if (WindowState.DEBUG_VISIBILITY) Slog.v(
+                TAG, "Creating surface in session "
+                + mSession.mSurfaceSession + " window " + this
+                + " w=" + mWin.mCompatFrame.width()
+                + " h=" + mWin.mCompatFrame.height() + " format="
+                + attrs.format + " flags=" + flags);
+
+            int w = mWin.mCompatFrame.width();
+            int h = mWin.mCompatFrame.height();
+            if ((attrs.flags & LayoutParams.FLAG_SCALED) != 0) {
+                // for a scaled surface, we always want the requested
+                // size.
+                w = mWin.mRequestedWidth;
+                h = mWin.mRequestedHeight;
+            }
+
+            // Something is wrong and SurfaceFlinger will not like this,
+            // try to revert to sane values
+            if (w <= 0) w = 1;
+            if (h <= 0) h = 1;
+
+            mSurfaceShown = false;
+            mSurfaceLayer = 0;
+            mSurfaceAlpha = 1;
+            mSurfaceX = 0;
+            mSurfaceY = 0;
+            mSurfaceW = w;
+            mSurfaceH = h;
+            try {
+                final boolean isHwAccelerated = (attrs.flags &
+                        WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED) != 0;
+                final int format = isHwAccelerated ? PixelFormat.TRANSLUCENT : attrs.format;
+                if (!PixelFormat.formatHasAlpha(attrs.format)) {
+                    flags |= Surface.OPAQUE;
+                }
+                mSurface = new Surface(
+                        mSession.mSurfaceSession, mSession.mPid,
+                        attrs.getTitle().toString(),
+                        0, w, h, format, flags);
+                if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) Slog.i(TAG,
+                        "  CREATE SURFACE "
+                        + mSurface + " IN SESSION "
+                        + mSession.mSurfaceSession
+                        + ": pid=" + mSession.mPid + " format="
+                        + attrs.format + " flags=0x"
+                        + Integer.toHexString(flags)
+                        + " / " + this);
+            } catch (Surface.OutOfResourcesException e) {
+                Slog.w(TAG, "OutOfResourcesException creating surface");
+                mService.reclaimSomeSurfaceMemoryLocked(this, "create", true);
+                return null;
+            } catch (Exception e) {
+                Slog.e(TAG, "Exception creating surface", e);
+                return null;
+            }
+
+            if (WindowManagerService.localLOGV) Slog.v(
+                TAG, "Got surface: " + mSurface
+                + ", set left=" + mWin.mFrame.left + " top=" + mWin.mFrame.top
+                + ", animLayer=" + mAnimLayer);
+            if (SHOW_LIGHT_TRANSACTIONS) {
+                Slog.i(TAG, ">>> OPEN TRANSACTION createSurfaceLocked");
+                WindowManagerService.logSurface(mWin, "CREATE pos=("
+                        + mWin.mFrame.left + "," + mWin.mFrame.top + ") ("
+                        + mWin.mCompatFrame.width() + "x" + mWin.mCompatFrame.height()
+                        + "), layer=" + mAnimLayer + " HIDE", null);
+            }
+            Surface.openTransaction();
+            try {
+                try {
+                    mSurfaceX = mWin.mFrame.left + mWin.mXOffset;
+                    mSurfaceY = mWin.mFrame.top + mWin.mYOffset;
+                    mSurface.setPosition(mSurfaceX, mSurfaceY);
+                    mSurfaceLayer = mAnimLayer;
+                    mSurface.setLayer(mAnimLayer);
+                    mSurfaceShown = false;
+                    mSurface.hide();
+                    if ((mWin.mAttrs.flags&WindowManager.LayoutParams.FLAG_DITHER) != 0) {
+                        if (SHOW_TRANSACTIONS) WindowManagerService.logSurface(mWin, "DITHER", null);
+                        mSurface.setFlags(Surface.SURFACE_DITHER, Surface.SURFACE_DITHER);
+                    }
+                } catch (RuntimeException e) {
+                    Slog.w(TAG, "Error creating surface in " + w, e);
+                    mService.reclaimSomeSurfaceMemoryLocked(this, "create-init", true);
+                }
+                mWin.mLastHidden = true;
+            } finally {
+                Surface.closeTransaction();
+                if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
+                        "<<< CLOSE TRANSACTION createSurfaceLocked");
+            }
+            if (WindowManagerService.localLOGV) Slog.v(
+                    TAG, "Created surface " + this);
+        }
+        return mSurface;
+    }
+
+    void destroySurfaceLocked() {
+        if (mWin.mAppToken != null && mWin == mWin.mAppToken.startingWindow) {
+            mWin.mAppToken.startingDisplayed = false;
+        }
+
+        if (mSurface != null) {
+            mWin.mDrawPending = false;
+            mWin.mCommitDrawPending = false;
+            mWin.mReadyToShow = false;
+
+            int i = mWin.mChildWindows.size();
+            while (i > 0) {
+                i--;
+                WindowState c = mWin.mChildWindows.get(i);
+                c.mAttachedHidden = true;
+            }
+
+            if (mReportDestroySurface) {
+                mReportDestroySurface = false;
+                mSurfacePendingDestroy = true;
+                try {
+                    mWin.mClient.dispatchGetNewSurface();
+                    // We'll really destroy on the next time around.
+                    return;
+                } catch (RemoteException e) {
+                }
+            }
+
+            try {
+                if (DEBUG_VISIBILITY) {
+                    RuntimeException e = null;
+                    if (!WindowManagerService.HIDE_STACK_CRAWLS) {
+                        e = new RuntimeException();
+                        e.fillInStackTrace();
+                    }
+                    Slog.w(TAG, "Window " + this + " destroying surface "
+                            + mSurface + ", session " + mSession, e);
+                }
+                if (mSurfaceDestroyDeferred) {
+                    if (mSurface != null && mPendingDestroySurface != mSurface) {
+                        if (mPendingDestroySurface != null) {
+                            if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) {
+                                RuntimeException e = null;
+                                if (!WindowManagerService.HIDE_STACK_CRAWLS) {
+                                    e = new RuntimeException();
+                                    e.fillInStackTrace();
+                                }
+                                WindowManagerService.logSurface(mWin, "DESTROY PENDING", e);
+                            }
+                            mPendingDestroySurface.destroy();
+                        }
+                        mPendingDestroySurface = mSurface;
+                    }
+                } else {
+                    if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) {
+                        RuntimeException e = null;
+                        if (!WindowManagerService.HIDE_STACK_CRAWLS) {
+                            e = new RuntimeException();
+                            e.fillInStackTrace();
+                        }
+                        WindowManagerService.logSurface(mWin, "DESTROY", e);
+                    }
+                    mSurface.destroy();
+                }
+            } catch (RuntimeException e) {
+                Slog.w(TAG, "Exception thrown when destroying Window " + this
+                    + " surface " + mSurface + " session " + mSession
+                    + ": " + e.toString());
+            }
+
+            mSurfaceShown = false;
+            mSurface = null;
+        }
+    }
+
+    void destroyDeferredSurfaceLocked() {
+        try {
+            if (mPendingDestroySurface != null) {
+                if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) {
+                    RuntimeException e = null;
+                    if (!WindowManagerService.HIDE_STACK_CRAWLS) {
+                        e = new RuntimeException();
+                        e.fillInStackTrace();
+                    }
+                    WindowManagerService.logSurface(mWin, "DESTROY PENDING", e);
+                }
+                mPendingDestroySurface.destroy();
+            }
+        } catch (RuntimeException e) {
+            Slog.w(WindowManagerService.TAG, "Exception thrown when destroying Window "
+                    + this + " surface " + mPendingDestroySurface
+                    + " session " + mSession + ": " + e.toString());
+        }
+        mSurfaceDestroyDeferred = false;
+        mPendingDestroySurface = null;
+    }
+
+    void computeShownFrameLocked() {
+        final boolean selfTransformation = mHasLocalTransformation;
+        Transformation attachedTransformation =
+                (mAttachedWindow != null && mAttachedWindow.mWinAnimator.mHasLocalTransformation)
+                ? mAttachedWindow.mWinAnimator.mTransformation : null;
+        Transformation appTransformation =
+                (mWin.mAppToken != null && mWin.mAppToken.hasTransformation)
+                ? mWin.mAppToken.transformation : null;
+
+        // Wallpapers are animated based on the "real" window they
+        // are currently targeting.
+        if (mWin.mAttrs.type == TYPE_WALLPAPER && mService.mLowerWallpaperTarget == null
+                && mService.mWallpaperTarget != null) {
+            if (mService.mWallpaperTarget.mWinAnimator.mHasLocalTransformation &&
+                    mService.mWallpaperTarget.mWinAnimator.mAnimation != null &&
+                    !mService.mWallpaperTarget.mWinAnimator.mAnimation.getDetachWallpaper()) {
+                attachedTransformation = mService.mWallpaperTarget.mWinAnimator.mTransformation;
+                if (WindowManagerService.DEBUG_WALLPAPER && attachedTransformation != null) {
+                    Slog.v(TAG, "WP target attached xform: " + attachedTransformation);
+                }
+            }
+            if (mService.mWallpaperTarget.mAppToken != null &&
+                    mService.mWallpaperTarget.mAppToken.hasTransformation &&
+                    mService.mWallpaperTarget.mAppToken.animation != null &&
+                    !mService.mWallpaperTarget.mAppToken.animation.getDetachWallpaper()) {
+                appTransformation = mService.mWallpaperTarget.mAppToken.transformation;
+                if (WindowManagerService.DEBUG_WALLPAPER && appTransformation != null) {
+                    Slog.v(TAG, "WP target app xform: " + appTransformation);
+                }
+            }
+        }
+
+        final boolean screenAnimation = mService.mAnimator.mScreenRotationAnimation != null
+                && mService.mAnimator.mScreenRotationAnimation.isAnimating();
+        if (selfTransformation || attachedTransformation != null
+                || appTransformation != null || screenAnimation) {
+            // cache often used attributes locally
+            final Rect frame = mWin.mFrame;
+            final float tmpFloats[] = mService.mTmpFloats;
+            final Matrix tmpMatrix = mWin.mTmpMatrix;
+
+            // Compute the desired transformation.
+            if (screenAnimation) {
+                // If we are doing a screen animation, the global rotation
+                // applied to windows can result in windows that are carefully
+                // aligned with each other to slightly separate, allowing you
+                // to see what is behind them.  An unsightly mess.  This...
+                // thing...  magically makes it call good: scale each window
+                // slightly (two pixels larger in each dimension, from the
+                // window's center).
+                final float w = frame.width();
+                final float h = frame.height();
+                if (w>=1 && h>=1) {
+                    tmpMatrix.setScale(1 + 2/w, 1 + 2/h, w/2, h/2);
+                } else {
+                    tmpMatrix.reset();
+                }
+            } else {
+                tmpMatrix.reset();
+            }
+            tmpMatrix.postScale(mWin.mGlobalScale, mWin.mGlobalScale);
+            if (selfTransformation) {
+                tmpMatrix.postConcat(mTransformation.getMatrix());
+            }
+            tmpMatrix.postTranslate(frame.left + mWin.mXOffset, frame.top + mWin.mYOffset);
+            if (attachedTransformation != null) {
+                tmpMatrix.postConcat(attachedTransformation.getMatrix());
+            }
+            if (appTransformation != null) {
+                tmpMatrix.postConcat(appTransformation.getMatrix());
+            }
+            if (screenAnimation) {
+                tmpMatrix.postConcat(
+                        mService.mAnimator.mScreenRotationAnimation.getEnterTransformation().getMatrix());
+            }
+
+            // "convert" it into SurfaceFlinger's format
+            // (a 2x2 matrix + an offset)
+            // Here we must not transform the position of the surface
+            // since it is already included in the transformation.
+            //Slog.i(TAG, "Transform: " + matrix);
+
+            mHaveMatrix = true;
+            tmpMatrix.getValues(tmpFloats);
+            mDsDx = tmpFloats[Matrix.MSCALE_X];
+            mDtDx = tmpFloats[Matrix.MSKEW_Y];
+            mDsDy = tmpFloats[Matrix.MSKEW_X];
+            mDtDy = tmpFloats[Matrix.MSCALE_Y];
+            float x = tmpFloats[Matrix.MTRANS_X];
+            float y = tmpFloats[Matrix.MTRANS_Y];
+            int w = frame.width();
+            int h = frame.height();
+            mWin.mShownFrame.set(x, y, x+w, y+h);
+
+            // Now set the alpha...  but because our current hardware
+            // can't do alpha transformation on a non-opaque surface,
+            // turn it off if we are running an animation that is also
+            // transforming since it is more important to have that
+            // animation be smooth.
+            mShownAlpha = mAlpha;
+            if (!mService.mLimitedAlphaCompositing
+                    || (!PixelFormat.formatHasAlpha(mWin.mAttrs.format)
+                    || (mWin.isIdentityMatrix(mDsDx, mDtDx, mDsDy, mDtDy)
+                            && x == frame.left && y == frame.top))) {
+                //Slog.i(TAG, "Applying alpha transform");
+                if (selfTransformation) {
+                    mShownAlpha *= mTransformation.getAlpha();
+                }
+                if (attachedTransformation != null) {
+                    mShownAlpha *= attachedTransformation.getAlpha();
+                }
+                if (appTransformation != null) {
+                    mShownAlpha *= appTransformation.getAlpha();
+                }
+                if (screenAnimation) {
+                    mShownAlpha *=
+                        mService.mAnimator.mScreenRotationAnimation.getEnterTransformation().getAlpha();
+                }
+            } else {
+                //Slog.i(TAG, "Not applying alpha transform");
+            }
+
+            if (WindowManagerService.localLOGV) Slog.v(
+                TAG, "computeShownFrameLocked: Animating " + this +
+                ": " + mWin.mShownFrame +
+                ", alpha=" + mTransformation.getAlpha() + ", mShownAlpha=" + mShownAlpha);
+            return;
+        }
+
+        if (WindowManagerService.localLOGV) Slog.v(
+            TAG, "computeShownFrameLocked: " + this +
+            " not attached, mAlpha=" + mAlpha);
+        mWin.mShownFrame.set(mWin.mFrame);
+        if (mWin.mXOffset != 0 || mWin.mYOffset != 0) {
+            mWin.mShownFrame.offset(mWin.mXOffset, mWin.mYOffset);
+        }
+        mShownAlpha = mAlpha;
+        mHaveMatrix = false;
+        mDsDx = mWin.mGlobalScale;
+        mDtDx = 0;
+        mDsDy = 0;
+        mDtDy = mWin.mGlobalScale;
+    }
+    public void prepareSurfaceLocked(final boolean recoveringMemory) {
+        final WindowState w = mWin;
+        if (mSurface == null) {
+            if (w.mOrientationChanging) {
+                if (WindowManagerService.DEBUG_ORIENTATION) {
+                    Slog.v(TAG, "Orientation change skips hidden " + w);
+                }
+                w.mOrientationChanging = false;
+            }
+            return;
+        }
+
+        boolean displayed = false;
+
+        computeShownFrameLocked();
+
+        int width, height;
+        if ((w.mAttrs.flags & LayoutParams.FLAG_SCALED) != 0) {
+            // for a scaled surface, we just want to use
+            // the requested size.
+            width  = w.mRequestedWidth;
+            height = w.mRequestedHeight;
+        } else {
+            width = w.mCompatFrame.width();
+            height = w.mCompatFrame.height();
+        }
+
+        if (width < 1) {
+            width = 1;
+        }
+        if (height < 1) {
+            height = 1;
+        }
+        final boolean surfaceResized = mSurfaceW != width || mSurfaceH != height;
+        if (surfaceResized) {
+            mSurfaceW = width;
+            mSurfaceH = height;
+        }
+
+        if (mSurfaceX != w.mShownFrame.left
+                || mSurfaceY != w.mShownFrame.top) {
+            try {
+                if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(w,
+                        "POS " + w.mShownFrame.left
+                        + ", " + w.mShownFrame.top, null);
+                mSurfaceX = w.mShownFrame.left;
+                mSurfaceY = w.mShownFrame.top;
+                mSurface.setPosition(w.mShownFrame.left, w.mShownFrame.top);
+            } catch (RuntimeException e) {
+                Slog.w(TAG, "Error positioning surface of " + w
+                        + " pos=(" + w.mShownFrame.left
+                        + "," + w.mShownFrame.top + ")", e);
+                if (!recoveringMemory) {
+                    mService.reclaimSomeSurfaceMemoryLocked(this, "position", true);
+                }
+            }
+        }
+
+        if (surfaceResized) {
+            try {
+                if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(w,
+                        "SIZE " + width + "x" + height, null);
+                mSurfaceResized = true;
+                mSurface.setSize(width, height);
+            } catch (RuntimeException e) {
+                // If something goes wrong with the surface (such
+                // as running out of memory), don't take down the
+                // entire system.
+                Slog.e(TAG, "Error resizing surface of " + w
+                        + " size=(" + width + "x" + height + ")", e);
+                if (!recoveringMemory) {
+                    mService.reclaimSomeSurfaceMemoryLocked(this, "size", true);
+                }
+            }
+        }
+
+        if (w.mAttachedHidden || !w.isReadyForDisplay()) {
+            if (!w.mLastHidden) {
+                //dump();
+                w.mLastHidden = true;
+                if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(w,
+                        "HIDE (performLayout)", null);
+                if (mSurface != null) {
+                    mSurfaceShown = false;
+                    try {
+                        mSurface.hide();
+                    } catch (RuntimeException e) {
+                        Slog.w(TAG, "Exception hiding surface in " + w);
+                    }
+                }
+            }
+            // If we are waiting for this window to handle an
+            // orientation change, well, it is hidden, so
+            // doesn't really matter.  Note that this does
+            // introduce a potential glitch if the window
+            // becomes unhidden before it has drawn for the
+            // new orientation.
+            if (w.mOrientationChanging) {
+                w.mOrientationChanging = false;
+                if (WindowManagerService.DEBUG_ORIENTATION) Slog.v(TAG,
+                        "Orientation change skips hidden " + w);
+            }
+        } else if (mLastLayer != mAnimLayer
+                || mLastAlpha != mShownAlpha
+                || mLastDsDx != mDsDx
+                || mLastDtDx != mDtDx
+                || mLastDsDy != mDsDy
+                || mLastDtDy != mDtDy
+                || w.mLastHScale != w.mHScale
+                || w.mLastVScale != w.mVScale
+                || w.mLastHidden) {
+            displayed = true;
+            mLastAlpha = mShownAlpha;
+            mLastLayer = mAnimLayer;
+            mLastDsDx = mDsDx;
+            mLastDtDx = mDtDx;
+            mLastDsDy = mDsDy;
+            mLastDtDy = mDtDy;
+            w.mLastHScale = w.mHScale;
+            w.mLastVScale = w.mVScale;
+            if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(w,
+                    "alpha=" + mShownAlpha + " layer=" + mAnimLayer
+                    + " matrix=[" + (mDsDx*w.mHScale)
+                    + "," + (mDtDx*w.mVScale)
+                    + "][" + (mDsDy*w.mHScale)
+                    + "," + (mDtDy*w.mVScale) + "]", null);
+            if (mSurface != null) {
+                try {
+                    mSurfaceAlpha = mShownAlpha;
+                    mSurface.setAlpha(mShownAlpha);
+                    mSurfaceLayer = w.mWinAnimator.mAnimLayer;
+                    mSurface.setLayer(w.mWinAnimator.mAnimLayer);
+                    mSurface.setMatrix(
+                        mDsDx*w.mHScale, mDtDx*w.mVScale,
+                        mDsDy*w.mHScale, mDtDy*w.mVScale);
+                } catch (RuntimeException e) {
+                    Slog.w(TAG, "Error updating surface in " + w, e);
+                    if (!recoveringMemory) {
+                        mService.reclaimSomeSurfaceMemoryLocked(this, "update", true);
+                    }
+                }
+            }
+
+            if (w.mLastHidden && w.isDrawnLw()
+                    && !w.mReadyToShow) {
+                if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(w,
+                        "SHOW (performLayout)", null);
+                if (WindowManagerService.DEBUG_VISIBILITY) Slog.v(TAG, "Showing " + w
+                        + " during relayout");
+                if (showSurfaceRobustlyLocked()) {
+                    w.mHasDrawn = true;
+                    w.mLastHidden = false;
+                } else {
+                    w.mOrientationChanging = false;
+                }
+            }
+            if (mSurface != null) {
+                w.mToken.hasVisible = true;
+            }
+        } else {
+            displayed = true;
+        }
+
+        if (displayed) {
+            if (w.mOrientationChanging) {
+                if (!w.isDrawnLw()) {
+                    mService.mInnerFields.mOrientationChangeComplete = false;
+                    if (WindowManagerService.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);
+                }
+            }
+            w.mToken.hasVisible = true;
+        }
+    }
+
+    // This must be called while inside a transaction.
+    boolean performShowLocked() {
+        if (DEBUG_VISIBILITY) {
+            RuntimeException e = null;
+            if (!WindowManagerService.HIDE_STACK_CRAWLS) {
+                e = new RuntimeException();
+                e.fillInStackTrace();
+            }
+            Slog.v(WindowManagerService.TAG, "performShow on " + this
+                    + ": readyToShow=" + mWin.mReadyToShow + " readyForDisplay="
+                    + mWin.isReadyForDisplay()
+                    + " starting=" + (mWin.mAttrs.type == TYPE_APPLICATION_STARTING), e);
+        }
+        if (mWin.mReadyToShow && mWin.isReadyForDisplay()) {
+            if (SHOW_TRANSACTIONS || WindowManagerService.DEBUG_ORIENTATION)
+                WindowManagerService.logSurface(mWin, "SHOW (performShowLocked)", null);
+            if (DEBUG_VISIBILITY) Slog.v(WindowManagerService.TAG, "Showing " + this
+                    + " during animation: policyVis=" + mWin.mPolicyVisibility
+                    + " attHidden=" + mWin.mAttachedHidden
+                    + " tok.hiddenRequested="
+                    + (mWin.mAppToken != null ? mWin.mAppToken.hiddenRequested : false)
+                    + " tok.hidden="
+                    + (mWin.mAppToken != null ? mWin.mAppToken.hidden : false)
+                    + " animating=" + mAnimating
+                    + " tok animating="
+                    + (mWin.mAppToken != null ? mWin.mAppToken.animating : false));
+            if (!showSurfaceRobustlyLocked()) {
+                return false;
+            }
+
+            mService.enableScreenIfNeededLocked();
+
+            applyEnterAnimationLocked();
+
+            mLastAlpha = -1;
+            mWin.mHasDrawn = true;
+            mWin.mLastHidden = false;
+            mWin.mReadyToShow = false;
+
+            int i = mWin.mChildWindows.size();
+            while (i > 0) {
+                i--;
+                WindowState c = mWin.mChildWindows.get(i);
+                if (c.mAttachedHidden) {
+                    c.mAttachedHidden = false;
+                    if (c.mWinAnimator.mSurface != null) {
+                        c.mWinAnimator.performShowLocked();
+                        // It hadn't been shown, which means layout not
+                        // performed on it, so now we want to make sure to
+                        // do a layout.  If called from within the transaction
+                        // loop, this will cause it to restart with a new
+                        // layout.
+                        mService.mLayoutNeeded = true;
+                    }
+                }
+            }
+
+            if (mWin.mAttrs.type != TYPE_APPLICATION_STARTING
+                    && mWin.mAppToken != null) {
+                mWin.mAppToken.firstWindowDrawn = true;
+
+                if (mWin.mAppToken.startingData != null) {
+                    if (WindowManagerService.DEBUG_STARTING_WINDOW ||
+                            WindowManagerService.DEBUG_ANIM) Slog.v(WindowManagerService.TAG,
+                            "Finish starting " + mWin.mToken
+                            + ": first real window is shown, no animation");
+                    // If this initial window is animating, stop it -- we
+                    // will do an animation to reveal it from behind the
+                    // starting window, so there is no need for it to also
+                    // be doing its own stuff.
+                    if (mAnimation != null) {
+                        mAnimation.cancel();
+                        mAnimation = null;
+                        // Make sure we clean up the animation.
+                        mAnimating = true;
+                    }
+                    mService.mFinishedStarting.add(mWin.mAppToken);
+                    mService.mH.sendEmptyMessage(H.FINISHED_STARTING);
+                }
+                mWin.mAppToken.updateReportedVisibilityLocked();
+            }
+
+            return true;
+        }
+
+        return false;
+    }
+
+    /**
+     * Have the surface flinger show a surface, robustly dealing with
+     * error conditions.  In particular, if there is not enough memory
+     * to show the surface, then we will try to get rid of other surfaces
+     * in order to succeed.
+     *
+     * @return Returns true if the surface was successfully shown.
+     */
+    boolean showSurfaceRobustlyLocked() {
+        try {
+            if (mSurface != null) {
+                mSurfaceShown = true;
+                mSurface.show();
+                if (mWin.mTurnOnScreen) {
+                    if (DEBUG_VISIBILITY) Slog.v(TAG,
+                            "Show surface turning screen on: " + mWin);
+                    mWin.mTurnOnScreen = false;
+                    mService.mTurnOnScreen = true;
+                }
+            }
+            return true;
+        } catch (RuntimeException e) {
+            Slog.w(TAG, "Failure showing surface " + mSurface + " in " + mWin, e);
+        }
+
+        mService.reclaimSomeSurfaceMemoryLocked(this, "show", true);
+
+        return false;
+    }
+
+    void applyEnterAnimationLocked() {
+        final int transit;
+        if (mEnterAnimationPending) {
+            mEnterAnimationPending = false;
+            transit = WindowManagerPolicy.TRANSIT_ENTER;
+        } else {
+            transit = WindowManagerPolicy.TRANSIT_SHOW;
+        }
+
+        applyAnimationLocked(transit, true);
+    }
+
+    /**
+     * Choose the correct animation and set it to the passed WindowState.
+     * @param transit If WindowManagerPolicy.TRANSIT_PREVIEW_DONE and the app window has been drawn
+     *      then the animation will be app_starting_exit. Any other value loads the animation from
+     *      the switch statement below.
+     * @param isEntrance The animation type the last time this was called. Used to keep from
+     *      loading the same animation twice.
+     * @return true if an animation has been loaded.
+     */
+    boolean applyAnimationLocked(int transit, boolean isEntrance) {
+        if (mLocalAnimating && mAnimationIsEntrance == isEntrance) {
+            // If we are trying to apply an animation, but already running
+            // an animation of the same type, then just leave that one alone.
+            return true;
+        }
+
+        // Only apply an animation if the display isn't frozen.  If it is
+        // frozen, there is no reason to animate and it can cause strange
+        // artifacts when we unfreeze the display if some different animation
+        // is running.
+        if (mService.okToDisplay()) {
+            int anim = mPolicy.selectAnimationLw(mWin, transit);
+            int attr = -1;
+            Animation a = null;
+            if (anim != 0) {
+                a = AnimationUtils.loadAnimation(mContext, anim);
+            } else {
+                switch (transit) {
+                    case WindowManagerPolicy.TRANSIT_ENTER:
+                        attr = com.android.internal.R.styleable.WindowAnimation_windowEnterAnimation;
+                        break;
+                    case WindowManagerPolicy.TRANSIT_EXIT:
+                        attr = com.android.internal.R.styleable.WindowAnimation_windowExitAnimation;
+                        break;
+                    case WindowManagerPolicy.TRANSIT_SHOW:
+                        attr = com.android.internal.R.styleable.WindowAnimation_windowShowAnimation;
+                        break;
+                    case WindowManagerPolicy.TRANSIT_HIDE:
+                        attr = com.android.internal.R.styleable.WindowAnimation_windowHideAnimation;
+                        break;
+                }
+                if (attr >= 0) {
+                    a = mService.loadAnimation(mWin.mAttrs, attr);
+                }
+            }
+            if (WindowManagerService.DEBUG_ANIM) Slog.v(WindowManagerService.TAG,
+                    "applyAnimation: win=" + this
+                    + " anim=" + anim + " attr=0x" + Integer.toHexString(attr)
+                    + " mAnimation=" + mAnimation
+                    + " isEntrance=" + isEntrance);
+            if (a != null) {
+                if (WindowManagerService.DEBUG_ANIM) {
+                    RuntimeException e = null;
+                    if (!WindowManagerService.HIDE_STACK_CRAWLS) {
+                        e = new RuntimeException();
+                        e.fillInStackTrace();
+                    }
+                    Slog.v(WindowManagerService.TAG, "Loaded animation " + a + " for " + this, e);
+                }
+                setAnimation(a);
+                mAnimationIsEntrance = isEntrance;
+            }
+        } else {
+            clearAnimation();
+        }
+
+        return mAnimation != null;
+    }
+
     public void dump(PrintWriter pw, String prefix, boolean dumpAll) {
         if (mAnimating || mLocalAnimating || mAnimationIsEntrance
                 || mAnimation != null) {
@@ -295,6 +1098,38 @@
                     pw.print(" "); mTransformation.printShortString(pw);
                     pw.println();
         }
+        if (mSurface != null) {
+            if (dumpAll) {
+                pw.print(prefix); pw.print("mSurface="); pw.println(mSurface);
+            }
+            pw.print(prefix); pw.print("Surface: shown="); pw.print(mSurfaceShown);
+                    pw.print(" layer="); pw.print(mSurfaceLayer);
+                    pw.print(" alpha="); pw.print(mSurfaceAlpha);
+                    pw.print(" rect=("); pw.print(mSurfaceX);
+                    pw.print(","); pw.print(mSurfaceY);
+                    pw.print(") "); pw.print(mSurfaceW);
+                    pw.print(" x "); pw.println(mSurfaceH);
+        }
+        if (mPendingDestroySurface != null) {
+            pw.print(prefix); pw.print("mPendingDestroySurface=");
+                    pw.println(mPendingDestroySurface);
+        }
+        if (mSurfaceResized || mSurfaceDestroyDeferred) {
+            pw.print(prefix); pw.print("mSurfaceResized="); pw.print(mSurfaceResized);
+                    pw.print(" mSurfaceDestroyDeferred="); pw.println(mSurfaceDestroyDeferred);
+        }
+        if (mShownAlpha != 1 || mAlpha != 1 || mLastAlpha != 1) {
+            pw.print(prefix); pw.print("mShownAlpha="); pw.print(mShownAlpha);
+                    pw.print(" mAlpha="); pw.print(mAlpha);
+                    pw.print(" mLastAlpha="); pw.println(mLastAlpha);
+        }
+        if (mHaveMatrix || mWin.mGlobalScale != 1) {
+            pw.print(prefix); pw.print("mGlobalScale="); pw.print(mWin.mGlobalScale);
+                    pw.print(" mDsDx="); pw.print(mDsDx);
+                    pw.print(" mDtDx="); pw.print(mDtDx);
+                    pw.print(" mDsDy="); pw.print(mDsDy);
+                    pw.print(" mDtDy="); pw.println(mDtDy);
+        }
     }
 
 }