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"
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"
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;
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
<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>
<!-- ============================= -->
<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" />
<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. -->
<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>
<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>
// 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;
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;
+ }
+ }
+
+ if (mWallpaperTarget != foundW) {
+ mWallpaperTarget = foundW;
+ if (DEBUG_WALLPAPER) {
+ Log.v(TAG, "New wallpaper target: " + foundW);
+ }
}
- mWallpaperTarget = w;
+ 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();
// 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;
}
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;
}
}
? 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
// 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;
}
if (w == mInputMethodTarget) {
setInputMethodAnimLayerAdjustment(adj);
}
- if (w == mWallpaperTarget) {
+ if (w == mWallpaperTarget && mUpcomingWallpaperTarget == null) {
setWallpaperAnimLayerAdjustmentLocked(adj);
}
}
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);
// 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();
}