Recouple layout and animation a bit.

Share state between layout and animation and stop copying
redundant data between the two.

Change-Id: If07d3fc3ddfd33e3d46bf45d24d7aca58067ee66
diff --git a/services/java/com/android/server/wm/WindowAnimator.java b/services/java/com/android/server/wm/WindowAnimator.java
index 73293b0..f84c7f8 100644
--- a/services/java/com/android/server/wm/WindowAnimator.java
+++ b/services/java/com/android/server/wm/WindowAnimator.java
@@ -9,8 +9,7 @@
 import static com.android.server.wm.WindowManagerService.LayoutFields.SET_WALLPAPER_MAY_CHANGE;
 import static com.android.server.wm.WindowManagerService.LayoutFields.SET_FORCE_HIDING_CHANGED;
 import static com.android.server.wm.WindowManagerService.LayoutFields.SET_ORIENTATION_CHANGE_COMPLETE;
-
-import static com.android.server.wm.WindowManagerService.H.UPDATE_ANIM_PARAMETERS;
+import static com.android.server.wm.WindowManagerService.LayoutFields.SET_WALLPAPER_ACTION_PENDING;
 
 import android.content.Context;
 import android.os.Debug;
@@ -25,9 +24,7 @@
 import android.view.WindowManagerPolicy;
 import android.view.animation.Animation;
 
-import com.android.server.wm.WindowManagerService.AppWindowAnimParams;
 import com.android.server.wm.WindowManagerService.LayoutFields;
-import com.android.server.wm.WindowManagerService.LayoutToAnimatorParams;
 
 import java.io.PrintWriter;
 import java.util.ArrayList;
@@ -73,28 +70,6 @@
     SparseArray<DisplayContentsAnimator> mDisplayContentsAnimators =
             new SparseArray<WindowAnimator.DisplayContentsAnimator>();
 
-    static final int WALLPAPER_ACTION_PENDING = 1;
-    int mPendingActions;
-
-    WindowState mWallpaperTarget = null;
-    AppWindowAnimator mWpAppAnimator = null;
-    WindowState mLowerWallpaperTarget = null;
-    WindowState mUpperWallpaperTarget = null;
-
-    ArrayList<AppWindowAnimator> mAppAnimators = new ArrayList<AppWindowAnimator>();
-
-    ArrayList<WindowToken> mWallpaperTokens = new ArrayList<WindowToken>();
-
-    /** Parameters being passed from this into mService. */
-    static class AnimatorToLayoutParams {
-        boolean mUpdateQueued;
-        int mBulkUpdateParams;
-        SparseIntArray mPendingLayoutChanges;
-        WindowState mWindowDetachedWallpaper;
-    }
-    /** Do not modify unless holding mService.mWindowMap or this and mAnimToLayout in that order */
-    final AnimatorToLayoutParams mAnimToLayout = new AnimatorToLayoutParams();
-
     boolean mInitialized = false;
 
     // forceHiding states.
@@ -122,13 +97,9 @@
         mAnimationRunnable = new Runnable() {
             @Override
             public void run() {
-                // TODO(cmautner): When full isolation is achieved for animation, the first lock
-                // goes away and only the WindowAnimator.this remains.
-                synchronized(mService.mWindowMap) {
-                    synchronized(WindowAnimator.this) {
-                        copyLayoutToAnimParamsLocked();
-                        animateLocked();
-                    }
+                synchronized (mService.mWindowMap) {
+                    mService.mAnimationScheduled = false;
+                    animateLocked();
                 }
             }
         };
@@ -160,119 +131,20 @@
         }
 
         mDisplayContentsAnimators.delete(displayId);
+        mPendingLayoutChanges.delete(displayId);
     }
 
-    /** Locked on mAnimToLayout */
-    void updateAnimToLayoutLocked() {
-        final AnimatorToLayoutParams animToLayout = mAnimToLayout;
-        synchronized (animToLayout) {
-            animToLayout.mBulkUpdateParams = mBulkUpdateParams;
-            animToLayout.mPendingLayoutChanges = mPendingLayoutChanges.clone();
-            animToLayout.mWindowDetachedWallpaper = mWindowDetachedWallpaper;
-
-            if (!animToLayout.mUpdateQueued) {
-                animToLayout.mUpdateQueued = true;
-                mService.mH.sendMessage(mService.mH.obtainMessage(UPDATE_ANIM_PARAMETERS));
-            }
-        }
+    AppWindowAnimator getWallpaperAppAnimator() {
+        return mService.mWallpaperTarget == null
+                ? null : mService.mWallpaperTarget.mAppToken == null
+                        ? null : mService.mWallpaperTarget.mAppToken.mAppAnimator;
     }
 
-    /** Copy all WindowManagerService params into local params here. Locked on 'this'. */
-    private void copyLayoutToAnimParamsLocked() {
-        final LayoutToAnimatorParams layoutToAnim = mService.mLayoutToAnim;
-        synchronized(layoutToAnim) {
-            layoutToAnim.mAnimationScheduled = false;
-
-            if (!layoutToAnim.mParamsModified) {
-                return;
-            }
-            layoutToAnim.mParamsModified = false;
-
-            if ((layoutToAnim.mChanges & LayoutToAnimatorParams.WALLPAPER_TOKENS_CHANGED) != 0) {
-                layoutToAnim.mChanges &= ~LayoutToAnimatorParams.WALLPAPER_TOKENS_CHANGED;
-                mWallpaperTokens = new ArrayList<WindowToken>(layoutToAnim.mWallpaperTokens);
-            }
-
-            if (WindowManagerService.DEBUG_WALLPAPER_LIGHT) {
-                if (mWallpaperTarget != layoutToAnim.mWallpaperTarget
-                        || mLowerWallpaperTarget != layoutToAnim.mLowerWallpaperTarget
-                        || mUpperWallpaperTarget != layoutToAnim.mUpperWallpaperTarget) {
-                    Slog.d(TAG, "Pulling anim wallpaper: target=" + layoutToAnim.mWallpaperTarget
-                            + " lower=" + layoutToAnim.mLowerWallpaperTarget + " upper="
-                            + layoutToAnim.mUpperWallpaperTarget);
-                }
-            }
-            mWallpaperTarget = layoutToAnim.mWallpaperTarget;
-            mWpAppAnimator = mWallpaperTarget == null
-                    ? null : mWallpaperTarget.mAppToken == null
-                            ? null : mWallpaperTarget.mAppToken.mAppAnimator;
-            mLowerWallpaperTarget = layoutToAnim.mLowerWallpaperTarget;
-            mUpperWallpaperTarget = layoutToAnim.mUpperWallpaperTarget;
-
-            // Set the new DimAnimator params.
-            final int numDisplays = mDisplayContentsAnimators.size();
-            for (int i = 0; i < numDisplays; i++) {
-                final int displayId = mDisplayContentsAnimators.keyAt(i);
-                DisplayContentsAnimator displayAnimator = mDisplayContentsAnimators.valueAt(i);
-
-                displayAnimator.mWinAnimators.clear();
-                final WinAnimatorList winAnimators = layoutToAnim.mWinAnimatorLists.get(displayId);
-                if (winAnimators != null) {
-                    displayAnimator.mWinAnimators.addAll(winAnimators);
-                }
-
-                DimAnimator.Parameters dimParams = layoutToAnim.mDimParams.get(displayId);
-                if (dimParams == null) {
-                    displayAnimator.mDimParams = null;
-                } else {
-                    final WindowStateAnimator newWinAnimator = dimParams.mDimWinAnimator;
-
-                    // Only set dim params on the highest dimmed layer.
-                    final WindowStateAnimator existingDimWinAnimator =
-                            displayAnimator.mDimParams == null ?
-                                    null : displayAnimator.mDimParams.mDimWinAnimator;
-                    // Don't turn on for an unshown surface, or for any layer but the highest
-                    // dimmed layer.
-                    if (newWinAnimator.mSurfaceShown && (existingDimWinAnimator == null
-                            || !existingDimWinAnimator.mSurfaceShown
-                            || existingDimWinAnimator.mAnimLayer < newWinAnimator.mAnimLayer)) {
-                        displayAnimator.mDimParams = new DimAnimator.Parameters(dimParams);
-                    }
-                }
-            }
-
-            mAppAnimators.clear();
-            final int N = layoutToAnim.mAppWindowAnimParams.size();
-            for (int i = 0; i < N; i++) {
-                final AppWindowAnimParams params = layoutToAnim.mAppWindowAnimParams.get(i);
-                AppWindowAnimator appAnimator = params.mAppAnimator;
-                appAnimator.mAllAppWinAnimators.clear();
-                appAnimator.mAllAppWinAnimators.addAll(params.mWinAnimators);
-                mAppAnimators.add(appAnimator);
-            }
-        }
-    }
-
-    void hideWallpapersLocked(final WindowState w, boolean fromAnimator) {
-        // There is an issue where this function can be called either from
-        // the animation or the layout side of the window manager.  The problem
-        // is that if it is called from the layout side, we may not yet have
-        // propagated the current layout wallpaper state over into the animation
-        // state.  If that is the case, we can do bad things like hide the
-        // wallpaper when we had just made it shown because the animation side
-        // doesn't yet see that there is now a wallpaper target.  As a temporary
-        // work-around, we tell the function here which side of the window manager
-        // is calling so it can use the right state.
-        if (fromAnimator) {
-            hideWallpapersLocked(w, mWallpaperTarget, mLowerWallpaperTarget, mWallpaperTokens);
-        } else {
-            hideWallpapersLocked(w, mService.mWallpaperTarget,
-                    mService.mLowerWallpaperTarget, mService.mWallpaperTokens);
-        }
-    }
-
-    void hideWallpapersLocked(final WindowState w, final WindowState wallpaperTarget,
-            final WindowState lowerWallpaperTarget, final ArrayList<WindowToken> wallpaperTokens) {
+    void hideWallpapersLocked(final WindowState w) {
+        final WindowState wallpaperTarget = mService.mWallpaperTarget;
+        final WindowState lowerWallpaperTarget = mService.mLowerWallpaperTarget;
+        final ArrayList<WindowToken> wallpaperTokens = mService.mWallpaperTokens;
+        
         if ((wallpaperTarget == w && lowerWallpaperTarget == null) || wallpaperTarget == null) {
             final int numTokens = wallpaperTokens.size();
             for (int i = numTokens - 1; i >= 0; i--) {
@@ -299,9 +171,10 @@
 
     private void updateAppWindowsLocked() {
         int i;
-        final int NAT = mAppAnimators.size();
+        final ArrayList<AppWindowToken> appTokens = mService.mAnimatingAppTokens;
+        final int NAT = appTokens.size();
         for (i=0; i<NAT; i++) {
-            final AppWindowAnimator appAnimator = mAppAnimators.get(i);
+            final AppWindowAnimator appAnimator = appTokens.get(i).mAppAnimator;
             final boolean wasAnimating = appAnimator.animation != null
                     && appAnimator.animation != AppWindowAnimator.sDummyAnimation;
             if (appAnimator.stepAnimationLocked(mCurrentTime)) {
@@ -335,15 +208,14 @@
     private void updateWindowsLocked(final int displayId) {
         ++mAnimTransactionSequence;
 
-        final WinAnimatorList winAnimatorList =
-                getDisplayContentsAnimatorLocked(displayId).mWinAnimators;
+        final WindowList windows = mService.getWindowListLocked(displayId);
         ArrayList<WindowStateAnimator> unForceHiding = null;
         boolean wallpaperInUnForceHiding = false;
         mForceHiding = KEYGUARD_NOT_SHOWN;
 
-        for (int i = winAnimatorList.size() - 1; i >= 0; i--) {
-            WindowStateAnimator winAnimator = winAnimatorList.get(i);
-            WindowState win = winAnimator.mWin;
+        for (int i = windows.size() - 1; i >= 0; i--) {
+            WindowState win = windows.get(i);
+            WindowStateAnimator winAnimator = win.mWinAnimator;
             final int flags = winAnimator.mAttrFlags;
 
             if (winAnimator.mSurface != null) {
@@ -355,7 +227,7 @@
                             ", nowAnimating=" + nowAnimating);
                 }
 
-                if (wasAnimating && !winAnimator.mAnimating && mWallpaperTarget == win) {
+                if (wasAnimating && !winAnimator.mAnimating && mService.mWallpaperTarget == win) {
                     mBulkUpdateParams |= SET_WALLPAPER_MAY_CHANGE;
                     setPendingLayoutChanges(Display.DEFAULT_DISPLAY,
                             WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER);
@@ -486,21 +358,21 @@
     private void updateWallpaperLocked(int displayId) {
         final DisplayContentsAnimator displayAnimator =
                 getDisplayContentsAnimatorLocked(displayId);
-        final WinAnimatorList winAnimatorList = displayAnimator.mWinAnimators;
+        final WindowList windows = mService.getWindowListLocked(displayId);
         WindowStateAnimator windowAnimationBackground = null;
         int windowAnimationBackgroundColor = 0;
         WindowState detachedWallpaper = null;
         final DimSurface windowAnimationBackgroundSurface =
                 displayAnimator.mWindowAnimationBackgroundSurface;
 
-        for (int i = winAnimatorList.size() - 1; i >= 0; i--) {
-            WindowStateAnimator winAnimator = winAnimatorList.get(i);
+        for (int i = windows.size() - 1; i >= 0; i--) {
+            final WindowState win = windows.get(i);
+            WindowStateAnimator winAnimator = win.mWinAnimator;
             if (winAnimator.mSurface == null) {
                 continue;
             }
 
             final int flags = winAnimator.mAttrFlags;
-            final WindowState win = winAnimator.mWin;
 
             // If this window is animating, make a note that we have
             // an animating window and take care of a request to run
@@ -559,11 +431,11 @@
             // don't cause the wallpaper to suddenly disappear.
             int animLayer = windowAnimationBackground.mAnimLayer;
             WindowState win = windowAnimationBackground.mWin;
-            if (mWallpaperTarget == win
-                    || mLowerWallpaperTarget == win || mUpperWallpaperTarget == win) {
-                final int N = winAnimatorList.size();
+            if (mService.mWallpaperTarget == win || mService.mLowerWallpaperTarget == win
+                    || mService.mUpperWallpaperTarget == win) {
+                final int N = windows.size();
                 for (int i = 0; i < N; i++) {
-                    WindowStateAnimator winAnimator = winAnimatorList.get(i);
+                    WindowStateAnimator winAnimator = windows.get(i).mWinAnimator;
                     if (winAnimator.mIsWallpaper) {
                         animLayer = winAnimator.mAnimLayer;
                         break;
@@ -586,10 +458,13 @@
     /** See if any windows have been drawn, so they (and others associated with them) can now be
      *  shown. */
     private void testTokenMayBeDrawnLocked() {
-        final int NT = mAppAnimators.size();
+        // See if any windows have been drawn, so they (and others
+        // associated with them) can now be shown.
+        final ArrayList<AppWindowToken> appTokens = mService.mAnimatingAppTokens;
+        final int NT = appTokens.size();
         for (int i=0; i<NT; i++) {
-            AppWindowAnimator appAnimator = mAppAnimators.get(i);
-            AppWindowToken wtoken = appAnimator.mAppToken;
+            AppWindowToken wtoken = appTokens.get(i);
+            AppWindowAnimator appAnimator = wtoken.mAppAnimator;
             final boolean allDrawn = wtoken.allDrawn;
             if (allDrawn != appAnimator.allDrawn) {
                 appAnimator.allDrawn = allDrawn;
@@ -671,10 +546,10 @@
                 // associated with exiting/removed apps
                 performAnimationsLocked(displayId);
 
-                final WinAnimatorList winAnimatorList = displayAnimator.mWinAnimators;
-                final int N = winAnimatorList.size();
+                final WindowList windows = mService.getWindowListLocked(displayId);
+                final int N = windows.size();
                 for (int j = 0; j < N; j++) {
-                    winAnimatorList.get(j).prepareSurfaceLocked(true);
+                    windows.get(j).mWinAnimator.prepareSurfaceLocked(true);
                 }
             }
 
@@ -715,18 +590,18 @@
         for (int i = mPendingLayoutChanges.size() - 1; i >= 0; i--) {
             if ((mPendingLayoutChanges.valueAt(i)
                     & WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER) != 0) {
-                mPendingActions |= WALLPAPER_ACTION_PENDING;
+                mBulkUpdateParams |= SET_WALLPAPER_ACTION_PENDING;
             }
         }
 
         if (mBulkUpdateParams != 0 || mPendingLayoutChanges.size() > 0) {
-            updateAnimToLayoutLocked();
+            if (mService.copyAnimToLayoutParamsLocked()) {
+                mService.requestTraversalLocked();
+            }
         }
 
         if (mAnimating) {
-            synchronized (mService.mLayoutToAnim) {
-                mService.scheduleAnimationLocked();
-            }
+            mService.scheduleAnimationLocked();
         } else if (wasAnimating) {
             mService.requestTraversalLocked();
         }
@@ -777,51 +652,16 @@
         final String subPrefix = "  " + prefix;
         final String subSubPrefix = "  " + subPrefix;
 
-        boolean needSep = false;
-        if (mAppAnimators.size() > 0) {
-            needSep = true;
-            pw.println("  App Animators:");
-            for (int i=mAppAnimators.size()-1; i>=0; i--) {
-                AppWindowAnimator anim = mAppAnimators.get(i);
-                pw.print(prefix); pw.print("App Animator #"); pw.print(i);
-                        pw.print(' '); pw.print(anim);
-                if (dumpAll) {
-                    pw.println(':');
-                    anim.dump(pw, subPrefix, dumpAll);
-                } else {
-                    pw.println();
-                }
-            }
-        }
-        if (mWallpaperTokens.size() > 0) {
-            if (needSep) {
-                pw.println();
-            }
-            needSep = true;
-            pw.print(prefix); pw.println("Wallpaper tokens:");
-            for (int i=mWallpaperTokens.size()-1; i>=0; i--) {
-                WindowToken token = mWallpaperTokens.get(i);
-                pw.print(prefix); pw.print("Wallpaper #"); pw.print(i);
-                        pw.print(' '); pw.print(token);
-                if (dumpAll) {
-                    pw.println(':');
-                    token.dump(pw, subPrefix);
-                } else {
-                    pw.println();
-                }
-            }
-        }
-
-        if (needSep) {
-            pw.println();
-        }
         for (int i = 0; i < mDisplayContentsAnimators.size(); i++) {
             pw.print(prefix); pw.print("DisplayContentsAnimator #");
                     pw.print(mDisplayContentsAnimators.keyAt(i));
                     pw.println(":");
             DisplayContentsAnimator displayAnimator = mDisplayContentsAnimators.valueAt(i);
-            for (int j=0; j<displayAnimator.mWinAnimators.size(); j++) {
-                WindowStateAnimator wanim = displayAnimator.mWinAnimators.get(j);
+            final WindowList windows =
+                    mService.getWindowListLocked(mDisplayContentsAnimators.keyAt(i));
+            final int N = windows.size();
+            for (int j = 0; j < N; j++) {
+                WindowStateAnimator wanim = windows.get(j).mWinAnimator;
                 pw.print(subPrefix); pw.print("Window #"); pw.print(j);
                         pw.print(": "); pw.println(wanim);
             }
@@ -867,34 +707,16 @@
                     pw.print(Integer.toHexString(mBulkUpdateParams));
                     pw.println(bulkUpdateParamsToString(mBulkUpdateParams));
         }
-        if (mPendingActions != 0) {
-            pw.print(prefix); pw.print("mPendingActions=0x");
-                    pw.println(Integer.toHexString(mPendingActions));
-        }
         if (mWindowDetachedWallpaper != null) {
             pw.print(prefix); pw.print("mWindowDetachedWallpaper=");
                 pw.println(mWindowDetachedWallpaper);
         }
-        pw.print(prefix); pw.print("mWallpaperTarget="); pw.println(mWallpaperTarget);
-        pw.print(prefix); pw.print("mWpAppAnimator="); pw.println(mWpAppAnimator);
-        if (mLowerWallpaperTarget != null || mUpperWallpaperTarget != null) {
-            pw.print(prefix); pw.print("mLowerWallpaperTarget=");
-                    pw.println(mLowerWallpaperTarget);
-            pw.print(prefix); pw.print("mUpperWallpaperTarget=");
-                    pw.println(mUpperWallpaperTarget);
-        }
         if (mUniverseBackground != null) {
             pw.print(prefix); pw.print("mUniverseBackground="); pw.print(mUniverseBackground);
                     pw.print(" mAboveUniverseLayer="); pw.println(mAboveUniverseLayer);
         }
     }
 
-    void clearPendingActions() {
-        synchronized (this) {
-            mPendingActions = 0;
-        }
-    }
-
     void setPendingLayoutChanges(final int displayId, final int changes) {
         mPendingLayoutChanges.put(displayId, mPendingLayoutChanges.get(displayId) | changes);
     }
@@ -902,9 +724,9 @@
     void setAppLayoutChanges(final AppWindowAnimator appAnimator, final int changes, String s) {
         // Used to track which displays layout changes have been done.
         SparseIntArray displays = new SparseIntArray();
-        for (int i = appAnimator.mAllAppWinAnimators.size() - 1; i >= 0; i--) {
-            WindowStateAnimator winAnimator = appAnimator.mAllAppWinAnimators.get(i);
-            final int displayId = winAnimator.mWin.mDisplayContent.getDisplayId();
+        WindowList windows = appAnimator.mAppToken.allAppWindows;
+        for (int i = windows.size() - 1; i >= 0; i--) {
+            final int displayId = windows.get(i).getDisplayId();
             if (displays.indexOfKey(displayId) < 0) {
                 setPendingLayoutChanges(displayId, changes);
                 if (WindowManagerService.DEBUG_LAYOUT_REPEATS) {
@@ -916,6 +738,27 @@
         }
     }
 
+    void setDimParamsLocked(int displayId, DimAnimator.Parameters dimParams) {
+        DisplayContentsAnimator displayAnimator = mDisplayContentsAnimators.get(displayId);
+        if (dimParams == null) {
+            displayAnimator.mDimParams = null;
+        } else {
+            final WindowStateAnimator newWinAnimator = dimParams.mDimWinAnimator;
+
+            // Only set dim params on the highest dimmed layer.
+            final WindowStateAnimator existingDimWinAnimator =
+                    displayAnimator.mDimParams == null ?
+                            null : displayAnimator.mDimParams.mDimWinAnimator;
+            // Don't turn on for an unshown surface, or for any layer but the highest
+            // dimmed layer.
+            if (newWinAnimator.mSurfaceShown && (existingDimWinAnimator == null
+                    || !existingDimWinAnimator.mSurfaceShown
+                    || existingDimWinAnimator.mAnimLayer < newWinAnimator.mAnimLayer)) {
+                displayAnimator.mDimParams = new DimAnimator.Parameters(dimParams);
+            }
+        }
+    }
+
     private DisplayContentsAnimator getDisplayContentsAnimatorLocked(int displayId) {
         DisplayContentsAnimator displayAnimator = mDisplayContentsAnimators.get(displayId);
         if (displayAnimator == null) {
@@ -934,7 +777,6 @@
     }
 
     private class DisplayContentsAnimator {
-        WinAnimatorList mWinAnimators = new WinAnimatorList();
         DimAnimator mDimAnimator = null;
         DimAnimator.Parameters mDimParams = null;
         DimSurface mWindowAnimationBackgroundSurface = null;