Isolate layout and animation wallpaper objects.

Provide separate copies of mWallpaperTarget, mWallpaperTokens, and
mLower/UpperWallpaperTarget in the layout and animation sides of
Window Manager.

Simplify constructors of WindowAnimator and WindowStateAnimator.

Change-Id: I7e35794a432c25c4194c046e9e27150d1c905403
diff --git a/services/java/com/android/server/wm/AppWindowAnimator.java b/services/java/com/android/server/wm/AppWindowAnimator.java
index 16461ab..4860f1e 100644
--- a/services/java/com/android/server/wm/AppWindowAnimator.java
+++ b/services/java/com/android/server/wm/AppWindowAnimator.java
@@ -123,7 +123,7 @@
             if (w == mService.mInputMethodTarget && !mService.mInputMethodTargetWaitingAnim) {
                 mService.setInputMethodAnimLayerAdjustment(adj);
             }
-            if (w == mService.mWallpaperTarget && mService.mLowerWallpaperTarget == null) {
+            if (w == mAnimator.mWallpaperTarget && mAnimator.mLowerWallpaperTarget == null) {
                 mService.setWallpaperAnimLayerAdjustmentLocked(adj);
             }
         }
diff --git a/services/java/com/android/server/wm/WindowAnimator.java b/services/java/com/android/server/wm/WindowAnimator.java
index af373e4..dda6b10 100644
--- a/services/java/com/android/server/wm/WindowAnimator.java
+++ b/services/java/com/android/server/wm/WindowAnimator.java
@@ -21,7 +21,6 @@
 import android.view.animation.Animation;
 
 import com.android.internal.policy.impl.PhoneWindowManager;
-import com.android.server.wm.WindowManagerService.AnimatorToLayoutParams;
 import com.android.server.wm.WindowManagerService.LayoutToAnimatorParams;
 
 import java.io.PrintWriter;
@@ -84,14 +83,26 @@
     int mPendingActions;
 
     WindowState mWallpaperTarget = null;
+    AppWindowAnimator mWpAppAnimator = null;
+    WindowState mLowerWallpaperTarget = null;
+    WindowState mUpperWallpaperTarget = null;
 
+    ArrayList<WindowToken> mWallpaperTokens = new ArrayList<WindowToken>();
+
+    /** Parameters being passed from this into mService. */
+    static class AnimatorToLayoutParams {
+        boolean mUpdateQueued;
+        int mBulkUpdateParams;
+        int mPendingLayoutChanges;
+        WindowState mWindowDetachedWallpaper;
+    }
+    /** Do not modify unless holding mService.mWindowMap or this and mAnimToLayout in that order */
     final AnimatorToLayoutParams mAnimToLayout = new AnimatorToLayoutParams();
 
-    WindowAnimator(final WindowManagerService service, final Context context,
-            final WindowManagerPolicy policy) {
+    WindowAnimator(final WindowManagerService service) {
         mService = service;
-        mContext = context;
-        mPolicy = policy;
+        mContext = service.mContext;
+        mPolicy = service.mPolicy;
 
         mAnimationRunnable = new Runnable() {
             @Override
@@ -132,8 +143,18 @@
         synchronized(layoutToAnim) {
             layoutToAnim.mAnimationScheduled = false;
 
+            if ((layoutToAnim.mChanges & LayoutToAnimatorParams.WALLPAPER_TOKENS_CHANGED) != 0) {
+                layoutToAnim.mChanges &= ~LayoutToAnimatorParams.WALLPAPER_TOKENS_CHANGED;
+                mWallpaperTokens = new ArrayList<WindowToken>(layoutToAnim.mWallpaperTokens);
+            }
+
             mWinAnimators = new ArrayList<WindowStateAnimator>(layoutToAnim.mWinAnimators);
             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.
             DimAnimator.Parameters dimParams = layoutToAnim.mDimParams;
@@ -156,10 +177,13 @@
     }
 
     void hideWallpapersLocked(final WindowState w) {
-        if ((mService.mWallpaperTarget == w && mService.mLowerWallpaperTarget == null)
-                || mService.mWallpaperTarget == null) {
-            for (final WindowToken token : mService.mWallpaperTokens) {
-                for (final WindowState wallpaper : token.windows) {
+        if ((mWallpaperTarget == w && mLowerWallpaperTarget == null) || mWallpaperTarget == null) {
+            final int numTokens = mWallpaperTokens.size();
+            for (int i = numTokens - 1; i >= 0; i--) {
+                final WindowToken token = mWallpaperTokens.get(i);
+                final int numWindows = token.windows.size();
+                for (int j = numWindows - 1; j >= 0; j--) {
+                    final WindowState wallpaper = token.windows.get(j);
                     final WindowStateAnimator winAnimator = wallpaper.mWinAnimator;
                     if (!winAnimator.mLastHidden) {
                         winAnimator.hide();
@@ -245,7 +269,7 @@
                             ", nowAnimating=" + nowAnimating);
                 }
 
-                if (wasAnimating && !winAnimator.mAnimating && mService.mWallpaperTarget == win) {
+                if (wasAnimating && !winAnimator.mAnimating && mWallpaperTarget == win) {
                     mBulkUpdateParams |= SET_WALLPAPER_MAY_CHANGE;
                     mPendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
                     if (WindowManagerService.DEBUG_LAYOUT_REPEATS) {
@@ -431,13 +455,12 @@
             // don't cause the wallpaper to suddenly disappear.
             int animLayer = windowAnimationBackground.mAnimLayer;
             WindowState win = windowAnimationBackground.mWin;
-            if (windowAnimationBackground != null && mService.mWallpaperTarget == win
-                    || mService.mLowerWallpaperTarget == win
-                    || mService.mUpperWallpaperTarget == win) {
+            if (windowAnimationBackground != null && mWallpaperTarget == win
+                    || mLowerWallpaperTarget == win || mUpperWallpaperTarget == win) {
                 final int N = mWinAnimators.size();
                 for (int i = 0; i < N; i++) {
                     WindowStateAnimator winAnimator = mWinAnimators.get(i);
-                    if (winAnimator.mWin.mIsWallpaper) {
+                    if (winAnimator.mIsWallpaper) {
                         animLayer = winAnimator.mAnimLayer;
                         break;
                     }
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index 48bad9f..d29a8c2 100755
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -588,10 +588,10 @@
     WindowState mWallpaperTarget = null;
     // If non-null, we are in the middle of animating from one wallpaper target
     // to another, and this is the lower one in Z-order.
-    WindowState mLowerWallpaperTarget = null;
+    private WindowState mLowerWallpaperTarget = null;
     // If non-null, we are in the middle of animating from one wallpaper target
     // to another, and this is the higher one in Z-order.
-    WindowState mUpperWallpaperTarget = null;
+    private WindowState mUpperWallpaperTarget = null;
     int mWallpaperAnimLayerAdjustment;
     float mLastWallpaperX = -1;
     float mLastWallpaperY = -1;
@@ -648,25 +648,20 @@
     }
     final LayoutFields mInnerFields = new LayoutFields();
 
-    // TODO: Move this into WindowAnimator. For some reason it causes the H class to blow up.
-    /* Parameters being passed from mAnimator into this.
-     * Do not modify unless holding (mWindowMap or mAnimator) and mAnimToLayout in that order */
-    static class AnimatorToLayoutParams {
-        boolean mUpdateQueued;
-        int mBulkUpdateParams;
-        int mPendingLayoutChanges;
-        WindowState mWindowDetachedWallpaper;
-    }
-
     static class LayoutToAnimatorParams {
+        static final long WALLPAPER_TOKENS_CHANGED = 1 << 0;
+        long mChanges;
+
         boolean mAnimationScheduled;
         ArrayList<WindowStateAnimator> mWinAnimators = new ArrayList<WindowStateAnimator>();
         WindowState mWallpaperTarget;
+        WindowState mLowerWallpaperTarget;
+        WindowState mUpperWallpaperTarget;
         DimAnimator.Parameters mDimParams;
+        ArrayList<WindowToken> mWallpaperTokens = new ArrayList<WindowToken>();
     }
-    /** Params from WindowManagerService . Do not modify or read without first locking on
-     * either WindowManagerService.mWindowMap or WindowManagerService.mAnimator.and then on
-     * mLayoutToAnim */
+    /** Params from WindowManagerService to WindowAnimator. Do not modify or read without first
+     * locking on either mWindowMap or mAnimator and then on mLayoutToAnim */
     final LayoutToAnimatorParams mLayoutToAnim = new LayoutToAnimatorParams();
 
     /** The lowest wallpaper target with a detached wallpaper animation on it. */
@@ -916,7 +911,7 @@
 
         mInputManager = new InputManagerService(context, mInputMonitor);
         mFxSession = new SurfaceSession();
-        mAnimator = new WindowAnimator(this, context, mPolicy);
+        mAnimator = new WindowAnimator(this);
 
         PolicyThread thr = new PolicyThread(mPolicy, this, context, pm);
         thr.start();
@@ -2254,14 +2249,14 @@
             if (res != WindowManagerImpl.ADD_OKAY) {
                 return res;
             }
-            
+
             if (outInputChannel != null && (attrs.inputFeatures
                     & WindowManager.LayoutParams.INPUT_FEATURE_NO_INPUT_CHANNEL) == 0) {
                 String name = win.makeInputChannelName();
                 InputChannel[] inputChannels = InputChannel.openInputChannelPair(name);
                 win.setInputChannel(inputChannels[0]);
                 inputChannels[1].transferTo(outInputChannel);
-                
+
                 mInputManager.registerInputChannel(win.mInputChannel, win.mInputWindowHandle);
             }
 
@@ -3481,6 +3476,7 @@
             mTokenMap.put(token, wtoken);
             if (type == TYPE_WALLPAPER) {
                 mWallpaperTokens.add(wtoken);
+                updateLayoutToAnimWallpaperTokens();
             }
         }
     }
@@ -3527,6 +3523,7 @@
                         mExitingTokens.add(wtoken);
                     } else if (wtoken.windowType == TYPE_WALLPAPER) {
                         mWallpaperTokens.remove(wtoken);
+                        updateLayoutToAnimWallpaperTokens();
                     }
                 }
 
@@ -3698,7 +3695,7 @@
                 haveGroup = true;
                 curGroup = wtoken.groupId;
                 lastOrientation = wtoken.requestedOrientation;
-            } 
+            }
 
             int or = wtoken.requestedOrientation;
             // If this application is fullscreen, and didn't explicitly say
@@ -3824,6 +3821,7 @@
         return req;
     }
 
+    @Override
     public void setNewConfiguration(Configuration config) {
         if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
                 "setNewConfiguration()")) {
@@ -3836,7 +3834,8 @@
             performLayoutAndPlaceSurfacesLocked();
         }
     }
-    
+
+    @Override
     public void setAppOrientation(IApplicationToken token, int requestedOrientation) {
         if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
                 "setAppOrientation()")) {
@@ -7325,7 +7324,8 @@
                 case UPDATE_ANIM_PARAMETERS: {
                     // Used to send multiple changes from the animation side to the layout side.
                     synchronized (mWindowMap) {
-                        final AnimatorToLayoutParams animToLayout = mAnimator.mAnimToLayout;
+                        final WindowAnimator.AnimatorToLayoutParams animToLayout =
+                                mAnimator.mAnimToLayout;
                         synchronized (animToLayout) {
                             animToLayout.mUpdateQueued = false;
                             boolean doRequest = false;
@@ -8924,6 +8924,7 @@
                 mExitingTokens.remove(i);
                 if (token.windowType == TYPE_WALLPAPER) {
                     mWallpaperTokens.remove(token);
+                    updateLayoutToAnimWallpaperTokens();
                 }
             }
         }
@@ -9112,10 +9113,19 @@
                 }
             }
             layoutToAnim.mWallpaperTarget = mWallpaperTarget;
+            layoutToAnim.mLowerWallpaperTarget = mLowerWallpaperTarget;
+            layoutToAnim.mUpperWallpaperTarget = mUpperWallpaperTarget;
             scheduleAnimationLocked();
         }
     }
 
+    void updateLayoutToAnimWallpaperTokens() {
+        synchronized(mLayoutToAnim) {
+            mLayoutToAnim.mWallpaperTokens = new ArrayList<WindowToken>(mWallpaperTokens);
+            mLayoutToAnim.mChanges |= LayoutToAnimatorParams.WALLPAPER_TOKENS_CHANGED;
+        }
+    }
+
     void setAnimDimParams(DimAnimator.Parameters params) {
         synchronized (mLayoutToAnim) {
             mLayoutToAnim.mDimParams = params;
diff --git a/services/java/com/android/server/wm/WindowState.java b/services/java/com/android/server/wm/WindowState.java
index 248da74..e5ec5af 100644
--- a/services/java/com/android/server/wm/WindowState.java
+++ b/services/java/com/android/server/wm/WindowState.java
@@ -317,7 +317,7 @@
             mIsFloatingLayer = mIsImWindow || mIsWallpaper;
         }
 
-        mWinAnimator = new WindowStateAnimator(service, this, mAttachedWindow);
+        mWinAnimator = new WindowStateAnimator(this);
         mWinAnimator.mAlpha = a.alpha;
 
         WindowState appWin = this;
diff --git a/services/java/com/android/server/wm/WindowStateAnimator.java b/services/java/com/android/server/wm/WindowStateAnimator.java
index 794dade..464df6e 100644
--- a/services/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/java/com/android/server/wm/WindowStateAnimator.java
@@ -3,7 +3,6 @@
 package com.android.server.wm;
 
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
-import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
 
 import static com.android.server.wm.WindowManagerService.LayoutFields.SET_ORIENTATION_CHANGE_COMPLETE;
 import static com.android.server.wm.WindowManagerService.LayoutFields.SET_TURN_ON_SCREEN;
@@ -48,6 +47,7 @@
 
     static final String TAG = "WindowStateAnimator";
 
+    // Unchanging local convenience fields.
     final WindowManagerService mService;
     final WindowState mWin;
     final WindowState mAttachedWindow;
@@ -55,6 +55,7 @@
     final Session mSession;
     final WindowManagerPolicy mPolicy;
     final Context mContext;
+    final boolean mIsWallpaper;
 
     // If this is a universe background window, this is the transformation
     // it is applying to the rest of the universe.
@@ -142,19 +143,22 @@
     int mAttrFlags;
     int mAttrType;
 
-    public WindowStateAnimator(final WindowManagerService service, final WindowState win,
-                               final WindowState attachedWindow) {
+    public WindowStateAnimator(final WindowState win) {
+        final WindowManagerService service = win.mService;
+
         mService = service;
-        mWin = win;
-        mAttachedWindow = attachedWindow;
-        mAnimator = mService.mAnimator;
-        mSession = win.mSession;
-        mPolicy = mService.mPolicy;
-        mContext = mService.mContext;
-        mAttrFlags = win.mAttrs.flags;
-        mAttrType = win.mAttrs.type;
+        mAnimator = service.mAnimator;
+        mPolicy = service.mPolicy;
+        mContext = service.mContext;
         mAnimDw = service.mAppDisplayWidth;
         mAnimDh = service.mAppDisplayHeight;
+
+        mWin = win;
+        mAttachedWindow = win.mAttachedWindow;
+        mSession = win.mSession;
+        mAttrFlags = win.mAttrs.flags;
+        mAttrType = win.mAttrs.type;
+        mIsWallpaper = win.mIsWallpaper;
     }
 
     public void setAnimation(Animation anim) {
@@ -309,7 +313,7 @@
         mAnimLayer = mWin.mLayer;
         if (mWin.mIsImWindow) {
             mAnimLayer += mService.mInputMethodAnimLayerAdjustment;
-        } else if (mWin.mIsWallpaper) {
+        } else if (mIsWallpaper) {
             mAnimLayer += mService.mWallpaperAnimLayerAdjustment;
         }
         if (DEBUG_LAYERS) Slog.v(TAG, "Stepping win " + this
@@ -812,22 +816,21 @@
 
         // 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 (mIsWallpaper && mAnimator.mLowerWallpaperTarget == null
+                && mAnimator.mWallpaperTarget != null) {
+            final WindowStateAnimator wallpaperAnimator = mAnimator.mWallpaperTarget.mWinAnimator;
+            if (wallpaperAnimator.mHasLocalTransformation &&
+                    wallpaperAnimator.mAnimation != null &&
+                    !wallpaperAnimator.mAnimation.getDetachWallpaper()) {
+                attachedTransformation = wallpaperAnimator.mTransformation;
                 if (WindowManagerService.DEBUG_WALLPAPER && attachedTransformation != null) {
                     Slog.v(TAG, "WP target attached xform: " + attachedTransformation);
                 }
             }
-            final AppWindowAnimator wpAppAnimator = mService.mWallpaperTarget.mAppToken == null
-                    ? null : mService.mWallpaperTarget.mAppToken.mAppAnimator;
-            if (wpAppAnimator != null &&
-                    wpAppAnimator.hasTransformation &&
-                    wpAppAnimator.animation != null &&
-                    !wpAppAnimator.animation.getDetachWallpaper()) {
+            final AppWindowAnimator wpAppAnimator = mAnimator.mWpAppAnimator;
+            if (wpAppAnimator != null && wpAppAnimator.hasTransformation
+                    && wpAppAnimator.animation != null
+                    && !wpAppAnimator.animation.getDetachWallpaper()) {
                 appTransformation = wpAppAnimator.transformation;
                 if (WindowManagerService.DEBUG_WALLPAPER && appTransformation != null) {
                     Slog.v(TAG, "WP target app xform: " + appTransformation);
@@ -940,7 +943,7 @@
                 " screen=" + (screenAnimation ? mService.mAnimator.mScreenRotationAnimation.getEnterTransformation().getAlpha()
                         : "null"));
             return;
-        } else if (mWin.mIsWallpaper &&
+        } else if (mIsWallpaper &&
                     (mAnimator.mPendingActions & WindowAnimator.WALLPAPER_ACTION_PENDING) != 0) {
             return;
         }
@@ -1140,7 +1143,7 @@
 
         setSurfaceBoundaries(recoveringMemory);
 
-        if (mWin.mIsWallpaper && !mWin.mWallpaperVisible) {
+        if (mIsWallpaper && !mWin.mWallpaperVisible) {
             // Wallpaper is no longer visible and there is no wp target => hide it.
             hide();
         } else if (w.mAttachedHidden || !w.isReadyForDisplay()) {
@@ -1199,7 +1202,7 @@
                                 + " during relayout");
                         if (showSurfaceRobustlyLocked()) {
                             mLastHidden = false;
-                            if (w.mIsWallpaper) {
+                            if (mIsWallpaper) {
                                 mService.dispatchWallpaperVisibility(w, true);
                             }
                         } else {