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.
This commit is contained in:
Dianne Hackborn
2009-08-19 12:39:43 -07:00
parent 7773e87178
commit f8fbdb6b92
10 changed files with 408 additions and 31 deletions

View File

@@ -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"

View File

@@ -344,6 +344,12 @@ public interface WindowManagerPolicy {
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;

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>
<!-- ============================= -->

View File

@@ -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" />

View File

@@ -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>

View File

@@ -405,6 +405,7 @@ public class WindowManagerService extends IWindowManager.Stub
// 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 @@ public class WindowManagerService extends IWindowManager.Stub
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 @@ public class WindowManagerService extends IWindowManager.Stub
// 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 @@ public class WindowManagerService extends IWindowManager.Stub
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 @@ public class WindowManagerService extends IWindowManager.Stub
? 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 @@ public class WindowManagerService extends IWindowManager.Stub
// 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 @@ public class WindowManagerService extends IWindowManager.Stub
if (w == mInputMethodTarget) {
setInputMethodAnimLayerAdjustment(adj);
}
if (w == mWallpaperTarget) {
if (w == mWallpaperTarget && mUpcomingWallpaperTarget == null) {
setWallpaperAnimLayerAdjustmentLocked(adj);
}
}
@@ -8636,6 +8725,60 @@ public class WindowManagerService extends IWindowManager.Stub
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 @@ public class WindowManagerService extends IWindowManager.Stub
// 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();
}