Merge "- Consolidate all animations in a single place outside of layout loop. - Move mPolicy.startAnimationLw and mPolicy.finishAnimationLw into same method as mPolicy.animatingWindowLw. - Fix first parameter of performLayoutLockedInner(initial, ...) to pass true on initial pass."
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index 80ef0e6..dafc613 100644
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -268,6 +268,7 @@
 
     final TokenWatcher mKeyguardTokenWatcher = new TokenWatcher(
             new Handler(), "WindowManagerService.mKeyguardTokenWatcher") {
+        @Override
         public void acquired() {
             if (shouldAllowDisableKeyguard()) {
                 mPolicy.enableKeyguard(false);
@@ -276,6 +277,7 @@
                 Log.v(TAG, "Not disabling keyguard since device policy is enforced");
             }
         }
+        @Override
         public void released() {
             mPolicy.enableKeyguard(true);
             synchronized (mKeyguardTokenWatcher) {
@@ -599,6 +601,7 @@
         private boolean mSyswin = false;
         private float mScreenBrightness = -1;
         private float mButtonBrightness = -1;
+        private boolean mUpdateRotation = false;
     }
     private LayoutAndSurfaceFields mInnerFields = new LayoutAndSurfaceFields();
 
@@ -7620,53 +7623,53 @@
      * @param innerDh Height of app window.
      * @return true if rotation has stopped, false otherwise
      */
-    private boolean updateAppsAndRotationAnimationsLocked(long currentTime,
+    private void updateWindowsAppsAndRotationAnimationsLocked(long currentTime,
                                                           int innerDw, int innerDh) {
         int i;
+        for (i = mWindows.size() - 1; i >= 0; i--) {
+            mInnerFields.mAnimating |= mWindows.get(i).stepAnimationLocked(currentTime);
+        }
+
         final int NAT = mAppTokens.size();
         for (i=0; i<NAT; i++) {
-            if (mAppTokens.get(i).stepAnimationLocked(currentTime,
-                    innerDw, innerDh)) {
-                mInnerFields.mAnimating = true;
-            }
+            mInnerFields.mAnimating |=
+                    mAppTokens.get(i).stepAnimationLocked(currentTime, innerDw, innerDh);
         }
         final int NEAT = mExitingAppTokens.size();
         for (i=0; i<NEAT; i++) {
-            if (mExitingAppTokens.get(i).stepAnimationLocked(currentTime,
-                    innerDw, innerDh)) {
-                mInnerFields.mAnimating = true;
-            }
+            mInnerFields.mAnimating |=
+                    mExitingAppTokens.get(i).stepAnimationLocked(currentTime, innerDw, innerDh);
         }
 
-        boolean updateRotation = false;
         if (mScreenRotationAnimation != null) {
             if (mScreenRotationAnimation.isAnimating()) {
                 if (mScreenRotationAnimation.stepAnimation(currentTime)) {
+                    mInnerFields.mUpdateRotation = false;
                     mInnerFields.mAnimating = true;
                 } else {
-                    updateRotation = true;
+                    mInnerFields.mUpdateRotation = true;
                     mScreenRotationAnimation.kill();
                     mScreenRotationAnimation = null;
                 }
             }
         }
-
-        return updateRotation;
     }
 
     /**
      * Extracted from {@link #performLayoutAndPlaceSurfacesLockedInner} to reduce size of method.
      *
      * @param currentTime The time which animations use for calculating transitions.
+     * @param dw Width of app window.
+     * @param dh Height of app window.
      * @param innerDw Width of app window.
      * @param innerDh Height of app window.
      */
-    private void updateWindowsAndWallpaperLocked(final long currentTime,
-                                                 final int innerDw, final int innerDh) {
-        int i;
-        final int N = mWindows.size();
+    private int updateWindowsAndWallpaperLocked(final long currentTime, final int dw, final int dh,
+                                                final int innerDw, final int innerDh) {
 
-        for (i=N-1; i>=0; i--) {
+        mPolicy.beginAnimationLw(dw, dh);
+
+        for (int i = mWindows.size() - 1; i >= 0; i--) {
             WindowState w = mWindows.get(i);
 
             final WindowManager.LayoutParams attrs = w.mAttrs;
@@ -7684,9 +7687,6 @@
 
                 final boolean wasAnimating = w.mAnimating;
 
-                int animDw = innerDw;
-                int animDh = innerDh;
-
                 // If the window has moved due to its containing
                 // content frame changing, then we'd like to animate
                 // it.  The checks here are ordered by what is least
@@ -7698,13 +7698,15 @@
                     Animation a = AnimationUtils.loadAnimation(mContext,
                             com.android.internal.R.anim.window_move_from_decor);
                     w.setAnimation(a);
-                    animDw = w.mLastFrame.left - w.mFrame.left;
-                    animDh = w.mLastFrame.top - w.mFrame.top;
+                    w.mAnimDw = w.mLastFrame.left - w.mFrame.left;
+                    w.mAnimDh = w.mLastFrame.top - w.mFrame.top;
+                } else {
+                    w.mAnimDw = innerDw;
+                    w.mAnimDh = innerDh;
                 }
 
                 // Execute animation.
-                final boolean nowAnimating = w.stepAnimationLocked(currentTime,
-                        animDw, animDh);
+                final boolean nowAnimating = w.isAnimating();
 
                 // If this window is animating, make a note that we have
                 // an animating window and take care of a request to run
@@ -7846,6 +7848,8 @@
                 w.performShowLocked();
             }
         } // end forall windows
+
+        return mPolicy.finishAnimationLw();
     }
 
     /**
@@ -8116,7 +8120,7 @@
      *
      * @return bitmap indicating if another pass through layout must be made.
      */
-    private int handleAnimatingAndTransitionLocked() {
+    private int handleAnimatingStoppedAndTransitionLocked() {
         int changes = 0;
 
         mAppTransitionRunning = false;
@@ -8652,7 +8656,6 @@
         boolean focusDisplayed = false;
         mInnerFields.mAnimating = false;
         boolean createWatermark = false;
-        boolean updateRotation = false;
 
         if (mFxSession == null) {
             mFxSession = new SurfaceSession();
@@ -8706,22 +8709,13 @@
 
                 // FIRST LOOP: Perform a layout, if needed.
                 if (repeats < 4) {
-                    performLayoutLockedInner(repeats == 0, false /*updateInputWindows*/);
+                    performLayoutLockedInner(repeats == 1, false /*updateInputWindows*/);
                 } else {
                     Slog.w(TAG, "Layout repeat skipped after too many iterations");
                 }
 
-                changes = 0;
                 ++mTransactionSequence;
 
-                // Update animations of all applications, including those
-                // associated with exiting/removed apps
-                mInnerFields.mAnimating = false;
-
-                // SECOND LOOP: Execute animations and update visibility of windows.
-                updateRotation |=
-                        updateAppsAndRotationAnimationsLocked(currentTime, innerDw, innerDh);
-
                 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "*** ANIM STEP: seq="
                         + mTransactionSequence + " mAnimating="
                         + mInnerFields.mAnimating);
@@ -8733,11 +8727,7 @@
                 mInnerFields.mWindowAnimationBackground = null;
                 mInnerFields.mWindowAnimationBackgroundColor = 0;
 
-                mPolicy.beginAnimationLw(dw, dh);
-
-                updateWindowsAndWallpaperLocked(currentTime, innerDw, innerDh);
-
-                changes |= mPolicy.finishAnimationLw();
+                changes = updateWindowsAndWallpaperLocked(currentTime, dw, dh, innerDw, innerDh);
 
                 if (mInnerFields.mTokenMayBeDrawn) {
                     changes |= testTokenMayBeDrawnLocked();
@@ -8759,7 +8749,7 @@
                     // reflects the correct Z-order, but the window list may now
                     // be out of sync with it.  So here we will just rebuild the
                     // entire app window list.  Fun!
-                    changes |= handleAnimatingAndTransitionLocked();
+                    changes |= handleAnimatingStoppedAndTransitionLocked();
                 }
 
                 if (mInnerFields.mWallpaperForceHidingChanged && changes == 0 && !mAppTransitionReady) {
@@ -8782,6 +8772,12 @@
                         + Integer.toHexString(changes));
             } while (changes != 0);
 
+            // Update animations of all applications, including those
+            // associated with exiting/removed apps
+            mInnerFields.mAnimating = false;
+
+            updateWindowsAppsAndRotationAnimationsLocked(currentTime, innerDw, innerDh);
+
             // THIRD LOOP: Update the surfaces of all windows.
 
             final boolean someoneLosingFocus = mLosingFocus.size() != 0;
@@ -9023,16 +9019,17 @@
             mTurnOnScreen = false;
         }
 
-        if (updateRotation) {
+        if (mInnerFields.mUpdateRotation) {
             if (DEBUG_ORIENTATION) Slog.d(TAG, "Performing post-rotate rotation");
             if (updateRotationUncheckedLocked(false)) {
                 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
             } else {
-                updateRotation = false;
+                mInnerFields.mUpdateRotation = false;
             }
         }
 
-        if (mInnerFields.mOrientationChangeComplete && !needRelayout && !updateRotation) {
+        if (mInnerFields.mOrientationChangeComplete && !needRelayout &&
+                !mInnerFields.mUpdateRotation) {
             checkDrawnWindowsLocked();
         }
 
diff --git a/services/java/com/android/server/wm/WindowState.java b/services/java/com/android/server/wm/WindowState.java
index b013d27..d7a7cb0 100644
--- a/services/java/com/android/server/wm/WindowState.java
+++ b/services/java/com/android/server/wm/WindowState.java
@@ -297,6 +297,11 @@
     CharSequence mLastTitle;
     boolean mWasPaused;
 
+    // Used to save animation distances between the time they are calculated and when they are 
+    // used.
+    int mAnimDw;
+    int mAnimDh;
+
     WindowState(WindowManagerService service, Session s, IWindow c, WindowToken token,
            WindowState attachedWindow, int seq, WindowManager.LayoutParams a,
            int viewVisibility) {
@@ -973,7 +978,7 @@
 
     // This must be called while inside a transaction.  Returns true if
     // there is more animation to run.
-    boolean stepAnimationLocked(long currentTime, int dw, int dh) {
+    boolean stepAnimationLocked(long currentTime) {
         if (!mService.mDisplayFrozen && mService.mPolicy.isScreenOnFully()) {
             // We will run animations as long as the display isn't frozen.
 
@@ -985,8 +990,9 @@
                         WindowManagerService.TAG, "Starting animation in " + this +
                         " @ " + currentTime + ": ww=" + mFrame.width() +
                         " wh=" + mFrame.height() +
-                        " dw=" + dw + " dh=" + dh + " scale=" + mService.mWindowAnimationScale);
-                    mAnimation.initialize(mFrame.width(), mFrame.height(), dw, dh);
+                        " dw=" + mAnimDw + " dh=" + mAnimDh +
+                        " scale=" + mService.mWindowAnimationScale);
+                    mAnimation.initialize(mFrame.width(), mFrame.height(), mAnimDw, mAnimDh);
                     mAnimation.setStartTime(currentTime);
                     mLocalAnimating = true;
                     mAnimating = true;