Animate from Choreographer only.

Animation steps are now executed on a Thread launched from the
Choreographer rather than being called at the end of the WindowManager
layout process. Animations and layout are still tightly coupled in
that they share considerable state information and neither can be
executed without holding a lock on WindowServiceManager.mWindowMap.

Change-Id: Ie17d693706971507b50aa473da1b7258e9e67764
diff --git a/services/java/com/android/server/wm/ScreenRotationAnimation.java b/services/java/com/android/server/wm/ScreenRotationAnimation.java
index 3dcfd3c..11af6ea 100644
--- a/services/java/com/android/server/wm/ScreenRotationAnimation.java
+++ b/services/java/com/android/server/wm/ScreenRotationAnimation.java
@@ -18,6 +18,8 @@
 
 import java.io.PrintWriter;
 
+import static com.android.server.wm.WindowStateAnimator.SurfaceTrace;
+
 import android.content.Context;
 import android.graphics.Matrix;
 import android.graphics.PixelFormat;
@@ -205,17 +207,23 @@
                     ">>> OPEN TRANSACTION ScreenRotationAnimation");
             Surface.openTransaction();
         }
-        
+
         try {
             try {
-                mSurface = new Surface(session, 0, "FreezeSurface",
-                        -1, mWidth, mHeight, PixelFormat.OPAQUE, Surface.FX_SURFACE_SCREENSHOT | Surface.HIDDEN);
+                if (WindowManagerService.DEBUG_SURFACE_TRACE) {
+                    mSurface = new SurfaceTrace(session, 0, "FreezeSurface", -1, mWidth, mHeight,
+                        PixelFormat.OPAQUE, Surface.FX_SURFACE_SCREENSHOT | Surface.HIDDEN);
+                } else {
+                    mSurface = new Surface(session, 0, "FreezeSurface", -1, mWidth, mHeight,
+                        PixelFormat.OPAQUE, Surface.FX_SURFACE_SCREENSHOT | Surface.HIDDEN);
+                }
                 if (!mSurface.isValid()) {
                     // Screenshot failed, punt.
                     mSurface = null;
                     return;
                 }
                 mSurface.setLayer(FREEZE_LAYER + 1);
+                mSurface.setAlpha(0);
                 mSurface.show();
             } catch (Surface.OutOfResourcesException e) {
                 Slog.w(TAG, "Unable to allocate freeze surface", e);
@@ -308,10 +316,10 @@
         if (TWO_PHASE_ANIMATION) {
             return startAnimation(session, maxAnimationDuration, animationScale,
                     finalWidth, finalHeight, false);
-        } else {
-            // Don't start animation yet.
-            return false;
         }
+
+        // Don't start animation yet.
+        return false;
     }
 
     /**
@@ -590,29 +598,37 @@
             mEnteringBlackFrame.kill();
             mEnteringBlackFrame = null;
         }
-        if (mStartExitAnimation != null) {
-            mStartExitAnimation.cancel();
-            mStartExitAnimation = null;
+        if (TWO_PHASE_ANIMATION) {
+            if (mStartExitAnimation != null) {
+                mStartExitAnimation.cancel();
+                mStartExitAnimation = null;
+            }
+            if (mStartEnterAnimation != null) {
+                mStartEnterAnimation.cancel();
+                mStartEnterAnimation = null;
+            }
+            if (mFinishExitAnimation != null) {
+                mFinishExitAnimation.cancel();
+                mFinishExitAnimation = null;
+            }
+            if (mFinishEnterAnimation != null) {
+                mFinishEnterAnimation.cancel();
+                mFinishEnterAnimation = null;
+            }
         }
-        if (mStartEnterAnimation != null) {
-            mStartEnterAnimation.cancel();
-            mStartEnterAnimation = null;
-        }
-        if (mStartFrameAnimation != null) {
-            mStartFrameAnimation.cancel();
-            mStartFrameAnimation = null;
-        }
-        if (mFinishExitAnimation != null) {
-            mFinishExitAnimation.cancel();
-            mFinishExitAnimation = null;
-        }
-        if (mFinishEnterAnimation != null) {
-            mFinishEnterAnimation.cancel();
-            mFinishEnterAnimation = null;
-        }
-        if (mFinishFrameAnimation != null) {
-            mFinishFrameAnimation.cancel();
-            mFinishFrameAnimation = null;
+        if (USE_CUSTOM_BLACK_FRAME) {
+            if (mStartFrameAnimation != null) {
+                mStartFrameAnimation.cancel();
+                mStartFrameAnimation = null;
+            }
+            if (mRotateFrameAnimation != null) {
+                mRotateFrameAnimation.cancel();
+                mRotateFrameAnimation = null;
+            }
+            if (mFinishFrameAnimation != null) {
+                mFinishFrameAnimation.cancel();
+                mFinishFrameAnimation = null;
+            }
         }
         if (mRotateExitAnimation != null) {
             mRotateExitAnimation.cancel();
@@ -622,27 +638,20 @@
             mRotateEnterAnimation.cancel();
             mRotateEnterAnimation = null;
         }
-        if (mRotateFrameAnimation != null) {
-            mRotateFrameAnimation.cancel();
-            mRotateFrameAnimation = null;
-        }
     }
 
     public boolean isAnimating() {
-        if (TWO_PHASE_ANIMATION) {
-            return hasAnimations() || mFinishAnimReady;
-        } else {
-            return hasAnimations();
-        }
+        return hasAnimations() || (TWO_PHASE_ANIMATION && mFinishAnimReady);
     }
 
     private boolean hasAnimations() {
-        return mStartEnterAnimation != null || mStartExitAnimation != null
-                || mStartFrameAnimation != null
-                || mFinishEnterAnimation != null || mFinishExitAnimation != null
-                || mFinishFrameAnimation != null
-                || mRotateEnterAnimation != null || mRotateExitAnimation != null
-                || mRotateFrameAnimation != null;
+        return (TWO_PHASE_ANIMATION &&
+                    (mStartEnterAnimation != null || mStartExitAnimation != null
+                    || mFinishEnterAnimation != null || mFinishExitAnimation != null))
+                || (USE_CUSTOM_BLACK_FRAME &&
+                        (mStartFrameAnimation != null || mRotateFrameAnimation != null
+                        || mFinishFrameAnimation != null))
+                || mRotateEnterAnimation != null || mRotateExitAnimation != null;
     }
 
     private boolean stepAnimation(long now) {
@@ -651,43 +660,49 @@
             mFinishAnimStartTime = now;
         }
 
-        mMoreStartExit = false;
-        if (mStartExitAnimation != null) {
-            mMoreStartExit = mStartExitAnimation.getTransformation(now, mStartExitTransformation);
-            if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped start exit: " + mStartExitTransformation);
-        }
+        if (TWO_PHASE_ANIMATION) {
+            mMoreStartExit = false;
+            if (mStartExitAnimation != null) {
+                mMoreStartExit = mStartExitAnimation.getTransformation(now, mStartExitTransformation);
+                if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped start exit: " + mStartExitTransformation);
+            }
 
-        mMoreStartEnter = false;
-        if (mStartEnterAnimation != null) {
-            mMoreStartEnter = mStartEnterAnimation.getTransformation(now, mStartEnterTransformation);
-            if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped start enter: " + mStartEnterTransformation);
+            mMoreStartEnter = false;
+            if (mStartEnterAnimation != null) {
+                mMoreStartEnter = mStartEnterAnimation.getTransformation(now, mStartEnterTransformation);
+                if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped start enter: " + mStartEnterTransformation);
+            }
         }
-
-        mMoreStartFrame = false;
-        if (mStartFrameAnimation != null) {
-            mMoreStartFrame = mStartFrameAnimation.getTransformation(now, mStartFrameTransformation);
-            if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped start frame: " + mStartFrameTransformation);
+        if (USE_CUSTOM_BLACK_FRAME) {
+            mMoreStartFrame = false;
+            if (mStartFrameAnimation != null) {
+                mMoreStartFrame = mStartFrameAnimation.getTransformation(now, mStartFrameTransformation);
+                if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped start frame: " + mStartFrameTransformation);
+            }
         }
 
         long finishNow = mFinishAnimReady ? (now - mFinishAnimStartTime) : 0;
         if (DEBUG_STATE) Slog.v(TAG, "Step: finishNow=" + finishNow);
 
-        mMoreFinishExit = false;
-        if (mFinishExitAnimation != null) {
-            mMoreFinishExit = mFinishExitAnimation.getTransformation(finishNow, mFinishExitTransformation);
-            if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped finish exit: " + mFinishExitTransformation);
-        }
+        if (TWO_PHASE_ANIMATION) {
+            mMoreFinishExit = false;
+            if (mFinishExitAnimation != null) {
+                mMoreFinishExit = mFinishExitAnimation.getTransformation(finishNow, mFinishExitTransformation);
+                if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped finish exit: " + mFinishExitTransformation);
+            }
 
-        mMoreFinishEnter = false;
-        if (mFinishEnterAnimation != null) {
-            mMoreFinishEnter = mFinishEnterAnimation.getTransformation(finishNow, mFinishEnterTransformation);
-            if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped finish enter: " + mFinishEnterTransformation);
+            mMoreFinishEnter = false;
+            if (mFinishEnterAnimation != null) {
+                mMoreFinishEnter = mFinishEnterAnimation.getTransformation(finishNow, mFinishEnterTransformation);
+                if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped finish enter: " + mFinishEnterTransformation);
+            }
         }
-
-        mMoreFinishFrame = false;
-        if (mFinishFrameAnimation != null) {
-            mMoreFinishFrame = mFinishFrameAnimation.getTransformation(finishNow, mFinishFrameTransformation);
-            if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped finish frame: " + mFinishFrameTransformation);
+        if (USE_CUSTOM_BLACK_FRAME) {
+            mMoreFinishFrame = false;
+            if (mFinishFrameAnimation != null) {
+                mMoreFinishFrame = mFinishFrameAnimation.getTransformation(finishNow, mFinishFrameTransformation);
+                if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped finish frame: " + mFinishFrameTransformation);
+            }
         }
 
         mMoreRotateExit = false;
@@ -702,24 +717,28 @@
             if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped rotate enter: " + mRotateEnterTransformation);
         }
 
-        mMoreRotateFrame = false;
-        if (mRotateFrameAnimation != null) {
-            mMoreRotateFrame = mRotateFrameAnimation.getTransformation(now, mRotateFrameTransformation);
-            if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped rotate frame: " + mRotateFrameTransformation);
+        if (USE_CUSTOM_BLACK_FRAME) {
+            mMoreRotateFrame = false;
+            if (mRotateFrameAnimation != null) {
+                mMoreRotateFrame = mRotateFrameAnimation.getTransformation(now, mRotateFrameTransformation);
+                if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped rotate frame: " + mRotateFrameTransformation);
+            }
         }
 
-        if (!mMoreStartExit && !mMoreRotateExit && !mMoreFinishExit) {
-            if (mStartExitAnimation != null) {
-                if (DEBUG_STATE) Slog.v(TAG, "Exit animations done, clearing start exit anim!");
-                mStartExitAnimation.cancel();
-                mStartExitAnimation = null;
-                mStartExitTransformation.clear();
-            }
-            if (mFinishExitAnimation != null) {
-                if (DEBUG_STATE) Slog.v(TAG, "Exit animations done, clearing finish exit anim!");
-                mFinishExitAnimation.cancel();
-                mFinishExitAnimation = null;
-                mFinishExitTransformation.clear();
+        if (!mMoreRotateExit && (!TWO_PHASE_ANIMATION || (!mMoreStartExit && !mMoreFinishExit))) {
+            if (TWO_PHASE_ANIMATION) {
+                if (mStartExitAnimation != null) {
+                    if (DEBUG_STATE) Slog.v(TAG, "Exit animations done, clearing start exit anim!");
+                    mStartExitAnimation.cancel();
+                    mStartExitAnimation = null;
+                    mStartExitTransformation.clear();
+                }
+                if (mFinishExitAnimation != null) {
+                    if (DEBUG_STATE) Slog.v(TAG, "Exit animations done, clearing finish exit anim!");
+                    mFinishExitAnimation.cancel();
+                    mFinishExitAnimation = null;
+                    mFinishExitTransformation.clear();
+                }
             }
             if (mRotateExitAnimation != null) {
                 if (DEBUG_STATE) Slog.v(TAG, "Exit animations done, clearing rotate exit anim!");
@@ -729,18 +748,20 @@
             }
         }
 
-        if (!mMoreStartEnter && !mMoreRotateEnter && !mMoreFinishEnter) {
-            if (mStartEnterAnimation != null) {
-                if (DEBUG_STATE) Slog.v(TAG, "Enter animations done, clearing start enter anim!");
-                mStartEnterAnimation.cancel();
-                mStartEnterAnimation = null;
-                mStartEnterTransformation.clear();
-            }
-            if (mFinishEnterAnimation != null) {
-                if (DEBUG_STATE) Slog.v(TAG, "Enter animations done, clearing finish enter anim!");
-                mFinishEnterAnimation.cancel();
-                mFinishEnterAnimation = null;
-                mFinishEnterTransformation.clear();
+        if (!mMoreRotateEnter && (!TWO_PHASE_ANIMATION || (!mMoreStartEnter && !mMoreFinishEnter))) {
+            if (TWO_PHASE_ANIMATION) {
+                if (mStartEnterAnimation != null) {
+                    if (DEBUG_STATE) Slog.v(TAG, "Enter animations done, clearing start enter anim!");
+                    mStartEnterAnimation.cancel();
+                    mStartEnterAnimation = null;
+                    mStartEnterTransformation.clear();
+                }
+                if (mFinishEnterAnimation != null) {
+                    if (DEBUG_STATE) Slog.v(TAG, "Enter animations done, clearing finish enter anim!");
+                    mFinishEnterAnimation.cancel();
+                    mFinishEnterAnimation = null;
+                    mFinishEnterTransformation.clear();
+                }
             }
             if (mRotateEnterAnimation != null) {
                 if (DEBUG_STATE) Slog.v(TAG, "Enter animations done, clearing rotate enter anim!");
@@ -772,12 +793,14 @@
         }
 
         mExitTransformation.set(mRotateExitTransformation);
-        mExitTransformation.compose(mStartExitTransformation);
-        mExitTransformation.compose(mFinishExitTransformation);
-
         mEnterTransformation.set(mRotateEnterTransformation);
-        mEnterTransformation.compose(mStartEnterTransformation);
-        mEnterTransformation.compose(mFinishEnterTransformation);
+        if (TWO_PHASE_ANIMATION) {
+            mExitTransformation.compose(mStartExitTransformation);
+            mExitTransformation.compose(mFinishExitTransformation);
+
+            mEnterTransformation.compose(mStartEnterTransformation);
+            mEnterTransformation.compose(mFinishEnterTransformation);
+        }
 
         if (DEBUG_TRANSFORMS) Slog.v(TAG, "Final exit: " + mExitTransformation);
         if (DEBUG_TRANSFORMS) Slog.v(TAG, "Final enter: " + mEnterTransformation);
@@ -793,9 +816,11 @@
             if (DEBUG_TRANSFORMS) Slog.v(TAG, "Final frame: " + mFrameTransformation);
         }
 
-        final boolean more = mMoreStartEnter || mMoreStartExit || mMoreStartFrame
-                || mMoreFinishEnter || mMoreFinishExit || mMoreFinishFrame
-                || mMoreRotateEnter || mMoreRotateExit || mMoreRotateFrame
+        final boolean more = (TWO_PHASE_ANIMATION
+                    && (mMoreStartEnter || mMoreStartExit || mMoreFinishEnter || mMoreFinishExit))
+                || (USE_CUSTOM_BLACK_FRAME
+                        && (mMoreStartFrame || mMoreRotateFrame || mMoreFinishFrame))
+                || mMoreRotateEnter || mMoreRotateExit 
                 || !mFinishAnimReady;
 
         mSnapshotFinalMatrix.setConcat(mExitTransformation.getMatrix(), mSnapshotInitialMatrix);
@@ -848,7 +873,7 @@
 
         setSnapshotTransform(mSnapshotFinalMatrix, mExitTransformation.getAlpha());
     }
-    
+
     public boolean stepAnimationLocked(long now) {
         if (!hasAnimations()) {
             if (DEBUG_STATE) Slog.v(TAG, "Step: no animations running");
@@ -858,23 +883,30 @@
 
         if (!mAnimRunning) {
             if (DEBUG_STATE) Slog.v(TAG, "Step: starting start, finish, rotate");
-            if (mStartEnterAnimation != null) {
-                mStartEnterAnimation.setStartTime(now);
+            if (TWO_PHASE_ANIMATION) {
+                if (mStartEnterAnimation != null) {
+                    mStartEnterAnimation.setStartTime(now);
+                }
+                if (mStartExitAnimation != null) {
+                    mStartExitAnimation.setStartTime(now);
+                }
+                if (mFinishEnterAnimation != null) {
+                    mFinishEnterAnimation.setStartTime(0);
+                }
+                if (mFinishExitAnimation != null) {
+                    mFinishExitAnimation.setStartTime(0);
+                }
             }
-            if (mStartExitAnimation != null) {
-                mStartExitAnimation.setStartTime(now);
-            }
-            if (mStartFrameAnimation != null) {
-                mStartFrameAnimation.setStartTime(now);
-            }
-            if (mFinishEnterAnimation != null) {
-                mFinishEnterAnimation.setStartTime(0);
-            }
-            if (mFinishExitAnimation != null) {
-                mFinishExitAnimation.setStartTime(0);
-            }
-            if (mFinishFrameAnimation != null) {
-                mFinishFrameAnimation.setStartTime(0);
+            if (USE_CUSTOM_BLACK_FRAME) {
+                if (mStartFrameAnimation != null) {
+                    mStartFrameAnimation.setStartTime(now);
+                }
+                if (mFinishFrameAnimation != null) {
+                    mFinishFrameAnimation.setStartTime(0);
+                }
+                if (mRotateFrameAnimation != null) {
+                    mRotateFrameAnimation.setStartTime(now);
+                }
             }
             if (mRotateEnterAnimation != null) {
                 mRotateEnterAnimation.setStartTime(now);
@@ -882,9 +914,6 @@
             if (mRotateExitAnimation != null) {
                 mRotateExitAnimation.setStartTime(now);
             }
-            if (mRotateFrameAnimation != null) {
-                mRotateFrameAnimation.setStartTime(now);
-            }
             mAnimRunning = true;
         }
 
diff --git a/services/java/com/android/server/wm/WindowAnimator.java b/services/java/com/android/server/wm/WindowAnimator.java
index 00fd7d8..7611a0f 100644
--- a/services/java/com/android/server/wm/WindowAnimator.java
+++ b/services/java/com/android/server/wm/WindowAnimator.java
@@ -431,6 +431,10 @@
         mPendingLayoutChanges = 0;
         mCurrentTime = SystemClock.uptimeMillis();
         mBulkUpdateParams = 0;
+        mAnimating = false;
+        if (WindowManagerService.DEBUG_WINDOW_TRACE) {
+            Slog.i(TAG, "!!! animate: entry time=" + mCurrentTime);
+        }
 
         // Update animations of all applications, including those
         // associated with exiting/removed apps
@@ -478,7 +482,16 @@
             Surface.closeTransaction();
         }
 
-        mService.bulkSetParameters(mBulkUpdateParams);
+        mService.bulkSetParameters(mBulkUpdateParams, mPendingLayoutChanges);
+
+        if (mAnimating) {
+            mService.scheduleAnimationLocked();
+        }
+        if (WindowManagerService.DEBUG_WINDOW_TRACE) {
+            Slog.i(TAG, "!!! animate: exit mAnimating=" + mAnimating
+                + " mBulkUpdateParams=" + Integer.toHexString(mBulkUpdateParams)
+                + " mPendingLayoutChanges=" + Integer.toHexString(mPendingLayoutChanges));
+        }
     }
 
     WindowState mCurrentFocus;
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index 82018fe..0fe6921 100644
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -176,6 +176,7 @@
     static final boolean DEBUG_BOOT = false;
     static final boolean DEBUG_LAYOUT_REPEATS = true;
     static final boolean DEBUG_SURFACE_TRACE = false;
+    static final boolean DEBUG_WINDOW_TRACE = false;
     static final boolean SHOW_SURFACE_ALLOC = false;
     static final boolean SHOW_TRANSACTIONS = false;
     static final boolean SHOW_LIGHT_TRANSACTIONS = false || SHOW_TRANSACTIONS;
@@ -593,6 +594,7 @@
         static final int SET_WALLPAPER_MAY_CHANGE           = 1 << 1;
         static final int SET_FORCE_HIDING_CHANGED           = 1 << 2;
         static final int CLEAR_ORIENTATION_CHANGE_COMPLETE  = 1 << 3;
+        static final int SET_TURN_ON_SCREEN                 = 1 << 4;
 
         boolean mWallpaperForceHidingChanged = false;
         boolean mWallpaperMayChange = false;
@@ -616,7 +618,20 @@
         public void run() {
             synchronized(mWindowMap) {
                 mAnimationScheduled = false;
-                performLayoutAndPlaceSurfacesLocked();
+                // Update animations of all applications, including those
+                // associated with exiting/removed apps
+                synchronized (mAnimator) {
+                    final ArrayList<WindowStateAnimator> winAnimators = mAnimator.mWinAnimators;
+                    winAnimators.clear();
+                    final int N = mWindows.size();
+                    for (int i = 0; i < N; i++) {
+                        final WindowStateAnimator winAnimator = mWindows.get(i).mWinAnimator;
+                        if (winAnimator.mSurface != null) {
+                            winAnimators.add(winAnimator);
+                        }
+                    }
+                    mAnimator.animate();
+                }
             }
         }
     }
@@ -6487,6 +6502,9 @@
 
         @Override
         public void handleMessage(Message msg) {
+            if (DEBUG_WINDOW_TRACE) {
+                Slog.v(TAG, "handleMessage: entry what=" + msg.what);
+            }
             switch (msg.what) {
                 case REPORT_FOCUS_CHANGE: {
                     WindowState lastFocus;
@@ -6918,6 +6936,14 @@
                                 doRequest = true;
                             }
                         }
+                        if ((msg.arg1 & LayoutFields.SET_TURN_ON_SCREEN) != 0) {
+                            mTurnOnScreen = true;
+                        }
+
+                        mPendingLayoutChanges |= msg.arg2;
+                        if (mPendingLayoutChanges != 0) {
+                            doRequest = true;
+                        }
 
                         if (doRequest) {
                             requestTraversalLocked();
@@ -6962,6 +6988,9 @@
                     break;
                 }
             }
+            if (DEBUG_WINDOW_TRACE) {
+                Slog.v(TAG, "handleMessage: exit");
+            }
         }
     }
 
@@ -6969,6 +6998,7 @@
     // IWindowManager API
     // -------------------------------------------------------------
 
+    @Override
     public IWindowSession openSession(IInputMethodClient client,
             IInputContext inputContext) {
         if (client == null) throw new IllegalArgumentException("null client");
@@ -6977,6 +7007,7 @@
         return session;
     }
 
+    @Override
     public boolean inputMethodClientHasFocus(IInputMethodClient client) {
         synchronized (mWindowMap) {
             // The focus for the client is the window immediately below
@@ -7410,12 +7441,6 @@
             } else {
                 mLayoutRepeatCount = 0;
             }
-            
-            if (mAnimator.mAnimating) {
-                // Do this even if requestTraversalLocked was called above so we get a frame drawn
-                // at the proper time as well as the one drawn early.
-                scheduleAnimationLocked();
-            }
 
             if (mWindowsChanged && !mWindowChangeListeners.isEmpty()) {
                 mH.removeMessages(H.REPORT_WINDOWS_CHANGE);
@@ -8033,6 +8058,9 @@
     // "Something has changed!  Let's make it correct now."
     private final void performLayoutAndPlaceSurfacesLockedInner(
             boolean recoveringMemory) {
+        if (DEBUG_WINDOW_TRACE) {
+            Slog.v(TAG, "performLayoutAndPlaceSurfacesLockedInner: entry");
+        }
         if (mDisplay == null) {
             Slog.i(TAG, "skipping performLayoutAndPlaceSurfacesLockedInner with no mDisplay");
             return;
@@ -8065,7 +8093,6 @@
         mInnerFields.mHoldScreen = null;
         mInnerFields.mScreenBrightness = -1;
         mInnerFields.mButtonBrightness = -1;
-        mAnimator.mAnimating = false;
 
         if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
                 ">>> OPEN TRANSACTION performLayoutAndPlaceSurfaces");
@@ -8294,22 +8321,6 @@
             }
         }
 
-        // Update animations of all applications, including those
-        // associated with exiting/removed apps
-        synchronized (mAnimator) {
-            final ArrayList<WindowStateAnimator> winAnimators = mAnimator.mWinAnimators;
-            winAnimators.clear();
-            for (i = 0; i < N; i++) {
-                final WindowStateAnimator winAnimator = mWindows.get(i).mWinAnimator;
-                if (winAnimator.mSurface != null) {
-                    winAnimators.add(winAnimator);
-                }
-            }
-            mAnimator.animate();
-            mPendingLayoutChanges |= mAnimator.mPendingLayoutChanges;
-            if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("after animate()", mPendingLayoutChanges);
-        }
-
         if (DEBUG_ORIENTATION && mDisplayFrozen) Slog.v(TAG,
                 "With display frozen, orientationChangeComplete="
                 + mInnerFields.mOrientationChangeComplete);
@@ -8475,9 +8486,14 @@
         // Check to see if we are now in a state where the screen should
         // be enabled, because the window obscured flags have changed.
         enableScreenIfNeededLocked();
-//        Slog.e(TAG, "performLayoutAndPlaceSurfacesLockedInner exit: mPendingLayoutChanges="
-//                + Integer.toHexString(mPendingLayoutChanges) + " mLayoutNeeded=" + mLayoutNeeded
-//                + " animating=" + mAnimator.mAnimating);
+
+        scheduleAnimationLocked();
+
+        if (DEBUG_WINDOW_TRACE) {
+            Slog.e(TAG, "performLayoutAndPlaceSurfacesLockedInner exit: mPendingLayoutChanges="
+                + Integer.toHexString(mPendingLayoutChanges) + " mLayoutNeeded=" + mLayoutNeeded
+                + " animating=" + mAnimator.mAnimating);
+        }
     }
 
     void checkDrawnWindowsLocked() {
@@ -8789,9 +8805,9 @@
         mScreenFrozenLock.acquire();
 
         mDisplayFrozen = true;
-        
+
         mInputMonitor.freezeInputDispatchingLw();
-        
+
         if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
             mNextAppTransition = WindowManagerPolicy.TRANSIT_UNSET;
             mNextAppTransitionPackage = null;
@@ -8850,6 +8866,7 @@
                     mTransitionAnimationScale, mCurDisplayWidth, mCurDisplayHeight)) {
                 scheduleAnimationLocked();
             } else {
+                mAnimator.mScreenRotationAnimation.kill();
                 mAnimator.mScreenRotationAnimation = null;
                 updateRotation = true;
             }
@@ -9517,12 +9534,31 @@
         }
     }
 
-    void bulkSetParameters(final int bulkUpdateParams) {
-        mH.sendMessage(mH.obtainMessage(H.BULK_UPDATE_PARAMETERS, bulkUpdateParams, 0));
+    void bulkSetParameters(final int bulkUpdateParams, int pendingLayoutChanges) {
+        mH.sendMessage(mH.obtainMessage(H.BULK_UPDATE_PARAMETERS, bulkUpdateParams,
+                pendingLayoutChanges));
+    }
+
+    /**
+     * Never call directly. Only call through getCallers(int) or getCaller(). Otherwise
+     * the depth will be off.
+     * @param depth What level stack to return.
+     * @return A String indicating who the caller of the method that calls this is.
+     */
+    static String getCaller(int depth) {
+        StackTraceElement caller = Thread.currentThread().getStackTrace()[5 + depth];
+        return caller.getClassName() + "." + caller.getMethodName() + ":" + caller.getLineNumber();
+    }
+
+    static String getCallers(final int depth) {
+        StringBuffer sb = new StringBuffer();
+        for (int i = 0; i < depth; i++) {
+            sb.append(getCaller(i)).append(" ");
+        }
+        return sb.toString();
     }
 
     static String getCaller() {
-        StackTraceElement caller = Thread.currentThread().getStackTrace()[4];
-        return caller.getClassName() + "." + caller.getMethodName() + ":" + caller.getLineNumber();
+        return getCallers(1);
     }
 }
diff --git a/services/java/com/android/server/wm/WindowStateAnimator.java b/services/java/com/android/server/wm/WindowStateAnimator.java
index 164325b..90b63a6 100644
--- a/services/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/java/com/android/server/wm/WindowStateAnimator.java
@@ -6,6 +6,7 @@
 import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
 
 import static com.android.server.wm.WindowManagerService.LayoutFields.CLEAR_ORIENTATION_CHANGE_COMPLETE;
+import static com.android.server.wm.WindowManagerService.LayoutFields.SET_TURN_ON_SCREEN;
 
 import android.content.Context;
 import android.graphics.Matrix;
@@ -84,9 +85,9 @@
      */
     boolean mSurfaceDestroyDeferred;
 
-    float mShownAlpha = 1;
-    float mAlpha = 1;
-    float mLastAlpha = 1;
+    float mShownAlpha = 0;
+    float mAlpha = 0;
+    float mLastAlpha = 0;
 
     // Used to save animation distances between the time they are calculated and when they are
     // used.
@@ -403,50 +404,55 @@
         return true;
     }
 
-    static class MySurface extends Surface {
-        final static ArrayList<MySurface> sSurfaces = new ArrayList<MySurface>();
+    static class SurfaceTrace extends Surface {
+        private final static String SURFACE_TAG = "SurfaceTrace";
+        final static ArrayList<SurfaceTrace> sSurfaces = new ArrayList<SurfaceTrace>();
 
-        private float mMySurfaceAlpha = 0xff;
+        private float mSurfaceTraceAlpha = 0;
         private int mLayer;
         private PointF mPosition = new PointF();
-        private Point mSize = new Point();
+        private Point mSize;
         private boolean mShown = false;
         private String mName = "Not named";
 
-        public MySurface(SurfaceSession s,
+        public SurfaceTrace(SurfaceSession s,
                        int pid, int display, int w, int h, int format, int flags) throws
                        OutOfResourcesException {
             super(s, pid, display, w, h, format, flags);
             mSize = new Point(w, h);
-            Slog.v("SurfaceTrace", "ctor: " + this);
+            Slog.v(SURFACE_TAG, "ctor: " + this + ". Called by "
+                    + WindowManagerService.getCallers(3));
         }
 
-        public MySurface(SurfaceSession s,
+        public SurfaceTrace(SurfaceSession s,
                        int pid, String name, int display, int w, int h, int format, int flags)
                    throws OutOfResourcesException {
             super(s, pid, name, display, w, h, format, flags);
             mName = name;
             mSize = new Point(w, h);
-            Slog.v("SurfaceTrace", "ctor: " + this);
+            Slog.v(SURFACE_TAG, "ctor: " + this + ". Called by "
+                    + WindowManagerService.getCallers(3));
         }
 
         @Override
         public void setAlpha(float alpha) {
             super.setAlpha(alpha);
-            mMySurfaceAlpha = alpha;
-            Slog.v("SurfaceTrace", "setAlpha: " + this);
+            mSurfaceTraceAlpha = alpha;
+            Slog.v(SURFACE_TAG, "setAlpha: " + this + ". Called by "
+                    + WindowManagerService.getCallers(3));
         }
 
         @Override
         public void setLayer(int zorder) {
             super.setLayer(zorder);
             mLayer = zorder;
-            Slog.v("SurfaceTrace", "setLayer: " + this);
+            Slog.v(SURFACE_TAG, "setLayer: " + this + ". Called by "
+                    + WindowManagerService.getCallers(3));
 
             sSurfaces.remove(this);
             int i;
             for (i = sSurfaces.size() - 1; i >= 0; i--) {
-                MySurface s = sSurfaces.get(i);
+                SurfaceTrace s = sSurfaces.get(i);
                 if (s.mLayer < zorder) {
                     break;
                 }
@@ -458,32 +464,38 @@
         public void setPosition(float x, float y) {
             super.setPosition(x, y);
             mPosition = new PointF(x, y);
+            Slog.v(SURFACE_TAG, "setPosition: " + this + ". Called by "
+                    + WindowManagerService.getCallers(3));
         }
 
         @Override
         public void setSize(int w, int h) {
             super.setSize(w, h);
             mSize = new Point(w, h);
+            Slog.v(SURFACE_TAG, "setSize: " + this + ". Called by "
+                    + WindowManagerService.getCallers(3));
         }
 
         @Override
         public void hide() {
             super.hide();
             mShown = false;
-            Slog.v("SurfaceTrace", "hide: " + this);
+            Slog.v(SURFACE_TAG, "hide: " + this + ". Called by "
+                    + WindowManagerService.getCallers(3));
         }
         @Override
         public void show() {
             super.show();
             mShown = true;
-            Slog.v("SurfaceTrace", "show: " + this);
+            Slog.v(SURFACE_TAG, "show: " + this + ". Called by "
+                    + WindowManagerService.getCallers(3));
         }
 
         @Override
         public void destroy() {
             super.destroy();
-            Slog.v("SurfaceTrace", "destroy: " + this + ". Called by "
-                    + WindowManagerService.getCaller());
+            Slog.v(SURFACE_TAG, "destroy: " + this + ". Called by "
+                    + WindowManagerService.getCallers(3));
             sSurfaces.remove(this);
         }
 
@@ -497,7 +509,7 @@
         @Override
         public String toString() {
             return "Surface " + mName + ": shown=" + mShown + " layer=" + mLayer
-                    + " alpha=" + mMySurfaceAlpha + " " + mPosition.x + "," + mPosition.y
+                    + " alpha=" + mSurfaceTraceAlpha + " " + mPosition.x + "," + mPosition.y
                     + " " + mSize.x + "x" + mSize.y;
         }
     }
@@ -544,7 +556,7 @@
 
             mSurfaceShown = false;
             mSurfaceLayer = 0;
-            mSurfaceAlpha = 1;
+            mSurfaceAlpha = 0;
             mSurfaceX = 0;
             mSurfaceY = 0;
             mSurfaceW = w;
@@ -557,7 +569,7 @@
                     flags |= Surface.OPAQUE;
                 }
                 if (DEBUG_SURFACE_TRACE) {
-                    mSurface = new MySurface(
+                    mSurface = new SurfaceTrace(
                             mSession.mSurfaceSession, mSession.mPid,
                             attrs.getTitle().toString(),
                             0, w, h, format, flags);
@@ -608,6 +620,7 @@
                     mSurface.setPosition(mSurfaceX, mSurfaceY);
                     mSurfaceLayer = mAnimLayer;
                     mSurface.setLayer(mAnimLayer);
+                    mSurface.setAlpha(0);
                     mSurfaceShown = false;
                     mSurface.hide();
                     if ((mWin.mAttrs.flags&WindowManager.LayoutParams.FLAG_DITHER) != 0) {
@@ -1185,7 +1198,7 @@
                     if (DEBUG_VISIBILITY) Slog.v(TAG,
                             "Show surface turning screen on: " + mWin);
                     mWin.mTurnOnScreen = false;
-                    mService.mTurnOnScreen = true;
+                    mAnimator.mBulkUpdateParams |= SET_TURN_ON_SCREEN;
                 }
             }
             return true;