Add wallpaper transition animations.

The window manager now detects when a transition between two
wallpaper activities is happening, and switches to a new set
of animations for that.  The animations I defined here are just
an arbitrary something that can work in this case.
diff --git a/api/current.xml b/api/current.xml
index ec76edb..d905f24 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -8567,6 +8567,50 @@
  visibility="public"
 >
 </field>
+<field name="wallpaperActivityCloseEnterAnimation"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843412"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="wallpaperActivityCloseExitAnimation"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843413"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="wallpaperActivityOpenEnterAnimation"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843410"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="wallpaperActivityOpenExitAnimation"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843411"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="webViewStyle"
  type="int"
  transient="false"
@@ -12087,6 +12131,17 @@
  visibility="public"
 >
 </field>
+<field name="Animation_InputMethod"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16973910"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="Animation_Toast"
  type="int"
  transient="false"
diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java
index f4e9900..ea08f33 100644
--- a/core/java/android/view/WindowManagerPolicy.java
+++ b/core/java/android/view/WindowManagerPolicy.java
@@ -344,6 +344,12 @@
     public final int TRANSIT_TASK_TO_FRONT = 10;
     /** A window in an existing task is being put below all other tasks. */
     public final int TRANSIT_TASK_TO_BACK = 11;
+    /** A window in a new activity is being opened on top of an existing one,
+     * and both are on top of the wallpaper. */
+    public final int TRANSIT_WALLPAPER_ACTIVITY_OPEN = 12;
+    /** The window in the top-most activity is being closed to reveal the
+     * previous activity, and both are on top of he wallpaper. */
+    public final int TRANSIT_WALLPAPER_ACTIVITY_CLOSE = 13;
     
     /** Screen turned off because of power button */
     public final int OFF_BECAUSE_OF_USER = 1;
diff --git a/core/res/res/anim/wallpaper_activity_close_enter.xml b/core/res/res/anim/wallpaper_activity_close_enter.xml
new file mode 100644
index 0000000..fc6e332
--- /dev/null
+++ b/core/res/res/anim/wallpaper_activity_close_enter.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* //device/apps/common/res/anim/options_panel_exit.xml
+**
+** Copyright 2007, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License"); 
+** you may not use this file except in compliance with the License. 
+** You may obtain a copy of the License at 
+**
+**     http://www.apache.org/licenses/LICENSE-2.0 
+**
+** Unless required by applicable law or agreed to in writing, software 
+** distributed under the License is distributed on an "AS IS" BASIS, 
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+** See the License for the specific language governing permissions and 
+** limitations under the License.
+*/
+-->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+        android:interpolator="@anim/decelerate_interpolator"
+        android:zAdjustment="top">
+    <scale android:fromXScale="2.0" android:toXScale="1.0"
+           android:fromYScale="2.0" android:toYScale="1.0"
+           android:pivotX="50%" android:pivotY="50%"
+           android:duration="@android:integer/config_mediumAnimTime" />
+	<translate android:fromXDelta="-150%" android:toXDelta="0"
+        android:duration="@android:integer/config_mediumAnimTime"/>
+</set>
diff --git a/core/res/res/anim/wallpaper_activity_close_exit.xml b/core/res/res/anim/wallpaper_activity_close_exit.xml
new file mode 100644
index 0000000..edd00fd
--- /dev/null
+++ b/core/res/res/anim/wallpaper_activity_close_exit.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* //device/apps/common/res/anim/options_panel_exit.xml
+**
+** Copyright 2007, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License"); 
+** you may not use this file except in compliance with the License. 
+** You may obtain a copy of the License at 
+**
+**     http://www.apache.org/licenses/LICENSE-2.0 
+**
+** Unless required by applicable law or agreed to in writing, software 
+** distributed under the License is distributed on an "AS IS" BASIS, 
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+** See the License for the specific language governing permissions and 
+** limitations under the License.
+*/
+-->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+        android:interpolator="@anim/accelerate_interpolator">
+    <scale android:fromXScale="1.0" android:toXScale=".5"
+           android:fromYScale="1.0" android:toYScale=".5"
+           android:pivotX="50%" android:pivotY="50%"
+           android:duration="@android:integer/config_mediumAnimTime" />
+	<translate android:fromXDelta="0%" android:toXDelta="100%"
+        android:duration="@android:integer/config_mediumAnimTime"/>
+</set>
diff --git a/core/res/res/anim/wallpaper_activity_open_enter.xml b/core/res/res/anim/wallpaper_activity_open_enter.xml
new file mode 100644
index 0000000..5b44d97
--- /dev/null
+++ b/core/res/res/anim/wallpaper_activity_open_enter.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* //device/apps/common/res/anim/options_panel_exit.xml
+**
+** Copyright 2007, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License"); 
+** you may not use this file except in compliance with the License. 
+** You may obtain a copy of the License at 
+**
+**     http://www.apache.org/licenses/LICENSE-2.0 
+**
+** Unless required by applicable law or agreed to in writing, software 
+** distributed under the License is distributed on an "AS IS" BASIS, 
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+** See the License for the specific language governing permissions and 
+** limitations under the License.
+*/
+-->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+        android:interpolator="@anim/decelerate_interpolator">
+    <scale android:fromXScale=".5" android:toXScale="1.0"
+           android:fromYScale=".5" android:toYScale="1.0"
+           android:pivotX="50%" android:pivotY="50%"
+           android:duration="@android:integer/config_mediumAnimTime" />
+    <translate android:fromXDelta="100%" android:toXDelta="0"
+            android:duration="@android:integer/config_mediumAnimTime"/>
+</set>
diff --git a/core/res/res/anim/wallpaper_activity_open_exit.xml b/core/res/res/anim/wallpaper_activity_open_exit.xml
new file mode 100644
index 0000000..fa39bee
--- /dev/null
+++ b/core/res/res/anim/wallpaper_activity_open_exit.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* //device/apps/common/res/anim/options_panel_exit.xml
+**
+** Copyright 2007, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License"); 
+** you may not use this file except in compliance with the License. 
+** You may obtain a copy of the License at 
+**
+**     http://www.apache.org/licenses/LICENSE-2.0 
+**
+** Unless required by applicable law or agreed to in writing, software 
+** distributed under the License is distributed on an "AS IS" BASIS, 
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+** See the License for the specific language governing permissions and 
+** limitations under the License.
+*/
+-->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+        android:interpolator="@anim/accelerate_interpolator"
+        android:zAdjustment="top">
+    <scale android:fromXScale="1.0" android:toXScale="2.0"
+           android:fromYScale="1.0" android:toYScale="2.0"
+           android:pivotX="50%" android:pivotY="50%"
+           android:duration="@android:integer/config_mediumAnimTime" />
+    <translate android:fromXDelta="0" android:toXDelta="-150%"
+            android:duration="@android:integer/config_mediumAnimTime"/>
+</set>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index eee87e6..e03211d 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -937,18 +937,68 @@
         <attr name="windowShowAnimation" format="reference" />
         <!-- The animation used when a window is going from VISIBLE to INVISIBLE. -->
         <attr name="windowHideAnimation" format="reference" />
+        
+        <!--  When opening a new activity, this is the animation that is
+              run on the next activity (which is entering the screen). -->
         <attr name="activityOpenEnterAnimation" format="reference" />
+        <!--  When opening a new activity, this is the animation that is
+              run on the previous activity (which is exiting the screen). -->
         <attr name="activityOpenExitAnimation" format="reference" />
+        <!--  When closing the current activity, this is the animation that is
+              run on the next activity (which is entering the screen). -->
         <attr name="activityCloseEnterAnimation" format="reference" />
+        <!--  When closing the current activity, this is the animation that is
+              run on the current activity (which is exiting the screen). -->
         <attr name="activityCloseExitAnimation" format="reference" />
+        <!--  When opening an activity in a new task, this is the animation that is
+              run on the activity of the new task (which is entering the screen). -->
         <attr name="taskOpenEnterAnimation" format="reference" />
+        <!--  When opening an activity in a new task, this is the animation that is
+              run on the activity of the old task (which is exiting the screen). -->
         <attr name="taskOpenExitAnimation" format="reference" />
+        <!--  When closing the last activity of a task, this is the animation that is
+              run on the activity of the next task (which is entering the screen). -->
         <attr name="taskCloseEnterAnimation" format="reference" />
+        <!--  When opening an activity in a new task, this is the animation that is
+              run on the activity of the old task (which is exiting the screen). -->
         <attr name="taskCloseExitAnimation" format="reference" />
+        <!--  When bringing an existing task to the foreground, this is the
+              animation that is run on the top activity of the task being brought
+              to the foreground (which is entering the screen). -->
         <attr name="taskToFrontEnterAnimation" format="reference" />
+        <!--  When bringing an existing task to the foreground, this is the
+              animation that is run on the current foreground activity
+              (which is exiting the screen). -->
         <attr name="taskToFrontExitAnimation" format="reference" />
+        <!--  When sending the current task to the background, this is the
+              animation that is run on the top activity of the task behind
+              it (which is entering the screen). -->
         <attr name="taskToBackEnterAnimation" format="reference" />
+        <!--  When sending the current task to the background, this is the
+              animation that is run on the top activity of the current task
+              (which is exiting the screen). -->
         <attr name="taskToBackExitAnimation" format="reference" />
+        
+        <!--  When opening a new activity that is on top of the wallpaper
+              when the current activity is also on top of the wallpaper,
+              this is the animation that is run on the new activity
+              (which is entering the screen). -->
+        <attr name="wallpaperActivityOpenEnterAnimation" format="reference" />
+        <!--  When opening a new activity that is on top of the wallpaper
+              when the current activity is also on top of the wallpaper,
+              this is the animation that is run on the current activity
+              (which is exiting the screen). -->
+        <attr name="wallpaperActivityOpenExitAnimation" format="reference" />
+        <!--  When closing a foreround activity that is on top of the wallpaper
+              when the previous activity is also on top of the wallpaper,
+              this is the animation that is run on the previous activity
+              (which is entering the screen). -->
+        <attr name="wallpaperActivityCloseEnterAnimation" format="reference" />
+        <!--  When closing a foreround activity that is on top of the wallpaper
+              when the previous activity is also on top of the wallpaper,
+              this is the animation that is run on the current activity
+              (which is exiting the screen). -->
+        <attr name="wallpaperActivityCloseExitAnimation" format="reference" />
     </declare-styleable>
 
     <!-- ============================= -->
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 60b492a..bbeb78d 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -1150,6 +1150,10 @@
   <public type="attr" name="contentAuthority" />
   <public type="attr" name="userVisible" />
   <public type="attr" name="windowShowWallpaper" />
+  <public type="attr" name="wallpaperActivityOpenEnterAnimation" />
+  <public type="attr" name="wallpaperActivityOpenExitAnimation" />
+  <public type="attr" name="wallpaperActivityCloseEnterAnimation" />
+  <public type="attr" name="wallpaperActivityCloseExitAnimation" />
 
   <public type="style" name="Theme.Wallpaper" />
   <public type="style" name="Theme.Wallpaper.NoTitleBar" />
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index 4aa4210..10d2093 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -66,6 +66,10 @@
         <item name="taskToFrontExitAnimation">@anim/task_open_exit</item>
         <item name="taskToBackEnterAnimation">@anim/task_close_enter</item>
         <item name="taskToBackExitAnimation">@anim/task_close_exit</item>
+        <item name="wallpaperActivityOpenEnterAnimation">@anim/wallpaper_activity_open_enter</item>
+        <item name="wallpaperActivityOpenExitAnimation">@anim/wallpaper_activity_open_exit</item>
+        <item name="wallpaperActivityCloseEnterAnimation">@anim/wallpaper_activity_close_enter</item>
+        <item name="wallpaperActivityCloseExitAnimation">@anim/wallpaper_activity_close_exit</item>
     </style>
 
     <!-- Standard animations for a non-full-screen window or activity. -->
@@ -130,8 +134,7 @@
         <item name="windowExitAnimation">@anim/slide_out_down</item>
     </style>
 
-    <!-- Window animations that are applied to input method overlay windows.
-         {@hide Pending API council approval} -->
+    <!-- Window animations that are applied to input method overlay windows. -->
     <style name="Animation.InputMethod">
         <item name="windowEnterAnimation">@anim/input_method_enter</item>
         <item name="windowExitAnimation">@anim/input_method_exit</item>
@@ -151,8 +154,7 @@
         <item name="windowExitAnimation">@anim/search_bar_exit</item>
     </style>
 
-    <!-- Window animations that are applied to the zoom buttons overlay window.
-         {@hide Pending API council approval} -->
+    <!-- Window animations that are applied to the zoom buttons overlay window. -->
     <style name="Animation.ZoomButtons">
         <item name="windowEnterAnimation">@anim/fade_in</item>
         <item name="windowExitAnimation">@anim/fade_out</item>
diff --git a/services/java/com/android/server/WindowManagerService.java b/services/java/com/android/server/WindowManagerService.java
index a00a756..7ca8b52 100644
--- a/services/java/com/android/server/WindowManagerService.java
+++ b/services/java/com/android/server/WindowManagerService.java
@@ -405,6 +405,7 @@
     // If non-null, this is the currently visible window that is associated
     // with the wallpaper.
     WindowState mWallpaperTarget = null;
+    WindowState mUpcomingWallpaperTarget = null;
     int mWallpaperAnimLayerAdjustment;
     
     AppWindowToken mFocusedApp = null;
@@ -1178,60 +1179,136 @@
     boolean adjustWallpaperWindowsLocked() {
         boolean changed = false;
         
+        mUpcomingWallpaperTarget = null;
+        
         // First find top-most window that has asked to be on top of the
         // wallpaper; all wallpapers go behind it.
         final ArrayList localmWindows = mWindows;
         int N = localmWindows.size();
         WindowState w = null;
+        WindowState foundW = null;
+        int foundI = 0;
+        AppWindowToken topToken = null;
+        AppWindowToken behindToken = null;
         int i = N;
-        boolean visible = false;
         while (i > 0) {
             i--;
             w = (WindowState)localmWindows.get(i);
+            if (topToken != null) {
+                if (w.mAppToken == topToken) {
+                    continue;
+                }
+                if (w.mAppToken != null) {
+                    if (behindToken == null) {
+                        // We need to look through for what is behind the
+                        // potential new wallpaper target...  skip all tokens
+                        // that are hidden and not animating, since they can't
+                        // be involved with the transition.
+                        if (w.mAppToken.hidden && w.mAppToken.animation == null) {
+                            continue;
+                        }
+                        behindToken = w.mAppToken;
+                    }
+                    if (w.mAppToken != behindToken) {
+                        break;
+                    }
+                }
+            }
             if ((w.mAttrs.flags&FLAG_SHOW_WALLPAPER) != 0 && w.isReadyForDisplay()
                     && !w.mDrawPending && !w.mCommitDrawPending) {
-                visible = true;
+                if (behindToken != null && w.mAppToken == behindToken) {
+                    // We had previously found a wallpaper window that was
+                    // animating, and now we found one behind it.  We could
+                    // be doing an animation between two windows on top of
+                    // the wallpaper!
+                    if (mWallpaperTarget == w || mWallpaperTarget == foundW) {
+                        // Retain the current wallpaper target (don't move
+                        // the wallpaper yet), but note the window that is
+                        // going to become the wallpaper target so that
+                        // others know about this special state.
+                        if (DEBUG_WALLPAPER) Log.v(TAG,
+                                "Switching wallpaper activities: cur#" + i + "="
+                                + w + " upcoming#" + foundI + "=" + foundW);
+                        mUpcomingWallpaperTarget = foundW;
+                        foundW = w;
+                        foundI = i;
+                        break;
+                    }
+                }
+                foundW = w;
+                foundI = i;
+                if (w.mAppToken != null && w.mAppToken.animation != null) {
+                    // If this app token is animating, we want to keep the
+                    // wallpaper below it if it is animating on top of another
+                    // app with a wallpaper.
+                    topToken = w.mAppToken;
+                    continue;
+                }
                 break;
             }
         }
 
-        if (!visible) w = null;
-        if (DEBUG_WALLPAPER && mWallpaperTarget != w) {
-            Log.v(TAG, "New wallpaper target: " + w);
+        if (mNextAppTransition != WindowManagerPolicy.TRANSIT_NONE) {
+            // If we are currently waiting for an app transition, and either
+            // the current target or the next target are involved with it,
+            // then hold off on doing anything with the wallpaper.
+            // Note that we are checking here for just whether the target
+            // is part of an app token...  which is potentially overly aggressive
+            // (the app token may not be involved in the transition), but good
+            // enough (we'll just wait until whatever transition is pending
+            // executes).
+            if (mWallpaperTarget != null && mWallpaperTarget.mAppToken != null) {
+                return false;
+            }
+            if (foundW != null && foundW.mAppToken != null) {
+                return false;
+            }
+            if (mUpcomingWallpaperTarget != null && mUpcomingWallpaperTarget.mAppToken != null) {
+                return false;
+            }
         }
-        mWallpaperTarget = w;
         
+        if (mWallpaperTarget != foundW) {
+            mWallpaperTarget = foundW;
+            if (DEBUG_WALLPAPER) {
+                Log.v(TAG, "New wallpaper target: " + foundW);
+            }
+        }
+        
+        boolean visible = foundW != null;
         if (visible) {
             // The window is visible to the compositor...  but is it visible
             // to the user?  That is what the wallpaper cares about.
-            visible = !w.mObscured;
+            visible = !foundW.mObscured;
             if (DEBUG_WALLPAPER) Log.v(TAG, "Wallpaper visibility: " + visible);
             
             // If the wallpaper target is animating, we may need to copy
-            // its layer adjustment.
-            mWallpaperAnimLayerAdjustment = w.mAppToken != null
-                    ? w.mAppToken.animLayerAdjustment : 0;
+            // its layer adjustment.  Only do this if we are not transfering
+            // between two wallpaper targets.
+            mWallpaperAnimLayerAdjustment =
+                    (mUpcomingWallpaperTarget == null && foundW.mAppToken != null)
+                    ? foundW.mAppToken.animLayerAdjustment : 0;
             
             // Now w is the window we are supposed to be behind...  but we
             // need to be sure to also be behind any of its attached windows,
             // AND any starting window associated with it.
-            while (i > 0) {
-                WindowState wb = (WindowState)localmWindows.get(i-1);
-                if (wb.mAttachedWindow != w &&
+            while (foundI > 0) {
+                WindowState wb = (WindowState)localmWindows.get(foundI-1);
+                if (wb.mAttachedWindow != foundW &&
                         (wb.mAttrs.type != TYPE_APPLICATION_STARTING ||
-                                wb.mToken != w.mToken)) {
+                                wb.mToken != foundW.mToken)) {
                     // This window is not related to the previous one in any
                     // interesting way, so stop here.
                     break;
                 }
-                w = wb;
-                i--;
+                foundW = wb;
+                foundI--;
             }
         }
         
         // Okay i is the position immediately above the wallpaper.  Look at
         // what is below it for later.
-        w = i > 0 ? (WindowState)localmWindows.get(i-1) : null;
+        foundW = foundI > 0 ? (WindowState)localmWindows.get(foundI-1) : null;
         
         final int dw = mDisplay.getWidth();
         final int dh = mDisplay.getHeight();
@@ -1271,9 +1348,10 @@
                 
                 // First, if this window is at the current index, then all
                 // is well.
-                if (wallpaper == w) {
-                    i--;
-                    w = i > 0 ? (WindowState)localmWindows.get(i-1) : null;
+                if (wallpaper == foundW) {
+                    foundI--;
+                    foundW = foundI > 0
+                            ? (WindowState)localmWindows.get(foundI-1) : null;
                     continue;
                 }
                 
@@ -1283,16 +1361,16 @@
                 int oldIndex = localmWindows.indexOf(wallpaper);
                 if (oldIndex >= 0) {
                     localmWindows.remove(oldIndex);
-                    if (oldIndex < i) {
-                        i--;
+                    if (oldIndex < foundI) {
+                        foundI--;
                     }
                 }
                 
                 // Now stick it in.
                 if (DEBUG_WALLPAPER) Log.v(TAG, "Moving wallpaper " + wallpaper
-                        + " from " + oldIndex + " to " + i);
+                        + " from " + oldIndex + " to " + foundI);
                 
-                localmWindows.add(i, wallpaper);
+                localmWindows.add(foundI, wallpaper);
                 changed = true;
             }
         }
@@ -2246,6 +2324,16 @@
                                 ? com.android.internal.R.styleable.WindowAnimation_taskToBackEnterAnimation
                                 : com.android.internal.R.styleable.WindowAnimation_taskToBackExitAnimation;
                         break;
+                    case WindowManagerPolicy.TRANSIT_WALLPAPER_ACTIVITY_OPEN:
+                        animAttr = enter
+                                ? com.android.internal.R.styleable.WindowAnimation_wallpaperActivityOpenEnterAnimation
+                                : com.android.internal.R.styleable.WindowAnimation_wallpaperActivityOpenExitAnimation;
+                        break;
+                    case WindowManagerPolicy.TRANSIT_WALLPAPER_ACTIVITY_CLOSE:
+                        animAttr = enter
+                                ? com.android.internal.R.styleable.WindowAnimation_wallpaperActivityCloseEnterAnimation
+                                : com.android.internal.R.styleable.WindowAnimation_wallpaperActivityCloseExitAnimation;
+                        break;
                 }
                 a = loadAnimation(lp, animAttr);
                 if (DEBUG_ANIM) Log.v(TAG, "applyAnimation: wtoken=" + wtoken
@@ -6874,7 +6962,8 @@
             
             // Wallpapers are animated based on the "real" window they
             // are currently targeting.
-            if (mAttrs.type == TYPE_WALLPAPER && mWallpaperTarget != null) {
+            if (mAttrs.type == TYPE_WALLPAPER && mUpcomingWallpaperTarget == null
+                    && mWallpaperTarget != null) {
                 if (mWallpaperTarget.mHasLocalTransformation) {
                     attachedTransformation = mWallpaperTarget.mTransformation;
                 }
@@ -7511,7 +7600,7 @@
                 if (w == mInputMethodTarget) {
                     setInputMethodAnimLayerAdjustment(adj);
                 }
-                if (w == mWallpaperTarget) {
+                if (w == mWallpaperTarget && mUpcomingWallpaperTarget == null) {
                     setWallpaperAnimLayerAdjustmentLocked(adj);
                 }
             }
@@ -8636,6 +8725,60 @@
 
                         mH.removeMessages(H.APP_TRANSITION_TIMEOUT);
 
+                        boolean wallpaperMoved = adjustWallpaperWindowsLocked();
+                        if (DEBUG_APP_TRANSITIONS) Log.v(TAG,
+                                "Old wallpaper target=" + mWallpaperTarget
+                                + ", upcoming target=" + mUpcomingWallpaperTarget);
+                        if (mUpcomingWallpaperTarget != mWallpaperTarget &&
+                                mUpcomingWallpaperTarget != null &&
+                                mWallpaperTarget != null) {
+                            // Need to determine if both the closing and
+                            // opening app token sets are wallpaper targets,
+                            // in which case special animations are needed
+                            // (since the wallpaper needs to stay static
+                            // behind them).
+                            int found = 0;
+                            NN = mOpeningApps.size();
+                            for (i=0; i<NN; i++) {
+                                AppWindowToken wtoken = mOpeningApps.get(i);
+                                if (mUpcomingWallpaperTarget.mAppToken == wtoken) {
+                                    found |= 1;
+                                }
+                                if (mWallpaperTarget.mAppToken == wtoken) {
+                                    found |= 1;
+                                }
+                            }
+                            NN = mClosingApps.size();
+                            for (i=0; i<NN; i++) {
+                                AppWindowToken wtoken = mClosingApps.get(i);
+                                if (mUpcomingWallpaperTarget.mAppToken == wtoken) {
+                                    found |= 2;
+                                }
+                                if (mWallpaperTarget.mAppToken == wtoken) {
+                                    found |= 2;
+                                }
+                            }
+                            
+                            if (found == 3) {
+                                if (DEBUG_APP_TRANSITIONS) Log.v(TAG,
+                                        "Wallpaper animation!");
+                                switch (transit) {
+                                    case WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN:
+                                    case WindowManagerPolicy.TRANSIT_TASK_OPEN:
+                                    case WindowManagerPolicy.TRANSIT_TASK_TO_FRONT:
+                                        transit = WindowManagerPolicy.TRANSIT_WALLPAPER_ACTIVITY_OPEN;
+                                        break;
+                                    case WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE:
+                                    case WindowManagerPolicy.TRANSIT_TASK_CLOSE:
+                                    case WindowManagerPolicy.TRANSIT_TASK_TO_BACK:
+                                        transit = WindowManagerPolicy.TRANSIT_WALLPAPER_ACTIVITY_CLOSE;
+                                        break;
+                                }
+                                if (DEBUG_APP_TRANSITIONS) Log.v(TAG,
+                                        "New transit: " + transit);
+                            }
+                        }
+                        
                         // We need to figure out which animation to use...
                         WindowManager.LayoutParams lp = findAnimations(mAppTokens,
                                 mOpeningApps, mClosingApps);
@@ -8671,7 +8814,6 @@
                         // This has changed the visibility of windows, so perform
                         // a new layout to get them all up-to-date.
                         mLayoutNeeded = true;
-                        adjustWallpaperWindowsLocked();
                         if (!moveInputMethodWindowsIfNeededLocked(true)) {
                             assignLayersLocked();
                         }