Merge change 27016 into eclair

* changes:
  A variety of work on animations.
This commit is contained in:
Android (Google) Code Review
2009-09-25 03:49:29 -04:00
18 changed files with 557 additions and 132 deletions

View File

@ -16877,6 +16877,21 @@
visibility="public"
>
</method>
<method name="overridePendingTransition"
return="void"
abstract="false"
native="false"
synchronized="false"
static="false"
final="false"
deprecated="not deprecated"
visibility="public"
>
<parameter name="enterAnim" type="int">
</parameter>
<parameter name="exitAnim" type="int">
</parameter>
</method>
<method name="registerForContextMenu"
return="void"
abstract="false"

View File

@ -3014,6 +3014,23 @@ public class Activity extends ContextThemeWrapper
flagsMask, flagsValues, child);
}
/**
* Call immediately after one of the flavors of {@link #startActivity(Intent)}
* or {@link #finish} to specify an explicit transition animation to
* perform next.
* @param enterAnim A resource ID of the animation resource to use for
* the incoming activity.
* @param exitAnim A resource ID of the animation resource to use for
* the outgoing activity.
*/
public void overridePendingTransition(int enterAnim, int exitAnim) {
try {
ActivityManagerNative.getDefault().overridePendingTransition(
mToken, getPackageName(), enterAnim, exitAnim);
} catch (RemoteException e) {
}
}
/**
* Call this to set the result that your activity will return to its
* caller.

View File

@ -1153,6 +1153,16 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
reply.writeNoException();
return true;
}
case OVERRIDE_PENDING_TRANSITION_TRANSACTION: {
data.enforceInterface(IActivityManager.descriptor);
IBinder token = data.readStrongBinder();
String packageName = data.readString();
int enterAnim = data.readInt();
int exitAnim = data.readInt();
overridePendingTransition(token, packageName, enterAnim, exitAnim);
return true;
}
}
return super.onTransact(code, data, reply, flags);
@ -2530,5 +2540,20 @@ class ActivityManagerProxy implements IActivityManager
reply.recycle();
}
public void overridePendingTransition(IBinder token, String packageName,
int enterAnim, int exitAnim) throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IActivityManager.descriptor);
data.writeStrongBinder(token);
data.writeString(packageName);
data.writeInt(enterAnim);
data.writeInt(exitAnim);
mRemote.transact(OVERRIDE_PENDING_TRANSITION_TRANSACTION, data, reply, 0);
reply.readException();
data.recycle();
reply.recycle();
}
private IBinder mRemote;
}

View File

@ -285,6 +285,9 @@ public interface IActivityManager extends IInterface {
public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids)
throws RemoteException;
public void overridePendingTransition(IBinder token, String packageName,
int enterAnim, int exitAnim) throws RemoteException;
/*
* Private non-Binder interfaces
*/
@ -444,4 +447,5 @@ public interface IActivityManager extends IInterface {
int GET_PROCESS_MEMORY_INFO_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+97;
int KILL_APPLICATION_PROCESS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+98;
int START_ACTIVITY_INTENT_SENDER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+99;
int OVERRIDE_PENDING_TRANSITION_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+100;
}

View File

@ -253,7 +253,7 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
public int uid;
/**
* The minimum SDK version this application targets. It may run on earilier
* The minimum SDK version this application targets. It may run on earlier
* versions, but it knows how to work with any new behavior added at this
* version. Will be {@link android.os.Build.VERSION_CODES#CUR_DEVELOPMENT}
* if this is a development build and the app is targeting that. You should

View File

@ -25,6 +25,7 @@ import org.xmlpull.v1.XmlPullParserException;
import android.graphics.Movie;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.ColorDrawable;
import android.os.Build;
import android.os.Bundle;
import android.os.SystemProperties;
import android.util.AttributeSet;
@ -50,8 +51,10 @@ public class Resources {
private static final boolean DEBUG_CONFIG = false;
private static final boolean TRACE_FOR_PRELOAD = false;
private static final int sSdkVersion = SystemProperties.getInt(
"ro.build.version.sdk", 0);
// Use the current SDK version code. If we are a development build,
// also allow the previous SDK version + 1.
private static final int sSdkVersion = Build.VERSION.SDK_INT
+ ("REL".equals(Build.VERSION.CODENAME) ? 1 : 0);
private static final Object mSync = new Object();
private static Resources mSystem = null;

View File

@ -71,6 +71,7 @@ interface IWindowManager
void setFocusedApp(IBinder token, boolean moveFocusNow);
void prepareAppTransition(int transit);
int getPendingAppTransition();
void overridePendingAppTransition(String packageName, int enterAnim, int exitAnim);
void executeAppTransition();
void setAppStartingWindow(IBinder token, String pkg, int theme,
CharSequence nonLocalizedLabel, int labelRes,

View File

@ -522,6 +522,13 @@ public interface WindowManager extends ViewManager {
* also been set. */
public static final int FLAG_DISMISS_KEYGUARD = 0x00400000;
/** Window flag: *sigh* The lock screen wants to continue running its
* animation while it is fading. A kind-of hack to allow this. Maybe
* in the future we just make this the default behavior.
*
* {@hide} */
public static final int FLAG_KEEP_SURFACE_WHILE_ANIMATING = 0x10000000;
/** Window flag: special flag to limit the size of the window to be
* original size ([320x480] x density). Used to create window for applications
* running under compatibility mode.

View File

@ -314,50 +314,60 @@ public interface WindowManagerPolicy {
public boolean showLw(boolean doAnimation);
}
/**
* Bit mask that is set for all enter transition.
*/
public final int TRANSIT_ENTER_MASK = 0x1000;
/**
* Bit mask that is set for all exit transitions.
*/
public final int TRANSIT_EXIT_MASK = 0x2000;
/** Not set up for a transition. */
public final int TRANSIT_UNSET = 0;
public final int TRANSIT_UNSET = -1;
/** No animation for transition. */
public final int TRANSIT_NONE = 0;
/** Window has been added to the screen. */
public final int TRANSIT_ENTER = 1;
public final int TRANSIT_ENTER = 1 | TRANSIT_ENTER_MASK;
/** Window has been removed from the screen. */
public final int TRANSIT_EXIT = 2;
public final int TRANSIT_EXIT = 2 | TRANSIT_EXIT_MASK;
/** Window has been made visible. */
public final int TRANSIT_SHOW = 3;
public final int TRANSIT_SHOW = 3 | TRANSIT_ENTER_MASK;
/** Window has been made invisible. */
public final int TRANSIT_HIDE = 4;
public final int TRANSIT_HIDE = 4 | TRANSIT_EXIT_MASK;
/** The "application starting" preview window is no longer needed, and will
* animate away to show the real window. */
public final int TRANSIT_PREVIEW_DONE = 5;
/** A window in a new activity is being opened on top of an existing one
* in the same task. */
public final int TRANSIT_ACTIVITY_OPEN = 6;
public final int TRANSIT_ACTIVITY_OPEN = 6 | TRANSIT_ENTER_MASK;
/** The window in the top-most activity is being closed to reveal the
* previous activity in the same task. */
public final int TRANSIT_ACTIVITY_CLOSE = 7;
public final int TRANSIT_ACTIVITY_CLOSE = 7 | TRANSIT_EXIT_MASK;
/** A window in a new task is being opened on top of an existing one
* in another activity's task. */
public final int TRANSIT_TASK_OPEN = 8;
public final int TRANSIT_TASK_OPEN = 8 | TRANSIT_ENTER_MASK;
/** A window in the top-most activity is being closed to reveal the
* previous activity in a different task. */
public final int TRANSIT_TASK_CLOSE = 9;
public final int TRANSIT_TASK_CLOSE = 9 | TRANSIT_EXIT_MASK;
/** A window in an existing task is being displayed on top of an existing one
* in another activity's task. */
public final int TRANSIT_TASK_TO_FRONT = 10;
public final int TRANSIT_TASK_TO_FRONT = 10 | TRANSIT_ENTER_MASK;
/** A window in an existing task is being put below all other tasks. */
public final int TRANSIT_TASK_TO_BACK = 11;
public final int TRANSIT_TASK_TO_BACK = 11 | TRANSIT_EXIT_MASK;
/** A window in a new activity that doesn't have a wallpaper is being
* opened on top of one that does, effectively closing the wallpaper. */
public final int TRANSIT_WALLPAPER_CLOSE = 12;
public final int TRANSIT_WALLPAPER_CLOSE = 12 | TRANSIT_EXIT_MASK;
/** A window in a new activity that does have a wallpaper is being
* opened on one that didn't, effectively opening the wallpaper. */
public final int TRANSIT_WALLPAPER_OPEN = 13;
public final int TRANSIT_WALLPAPER_OPEN = 13 | TRANSIT_ENTER_MASK;
/** 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_INTRA_OPEN = 14;
public final int TRANSIT_WALLPAPER_INTRA_OPEN = 14 | TRANSIT_ENTER_MASK;
/** 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_INTRA_CLOSE = 15;
public final int TRANSIT_WALLPAPER_INTRA_CLOSE = 15 | TRANSIT_EXIT_MASK;
/** Screen turned off because of power button */
public final int OFF_BECAUSE_OF_USER = 1;
@ -443,6 +453,21 @@ public interface WindowManagerPolicy {
*/
public int getMaxWallpaperLayer();
/**
* Return whether the given window should forcibly hide everything
* behind it. Typically returns true for the keyguard.
*/
public boolean doesForceHide(WindowState win, WindowManager.LayoutParams attrs);
/**
* Determine if a window that is behind one that is force hiding
* (as determined by {@link #doesForceHide}) should actually be hidden.
* For example, typically returns false for the status bar. Be careful
* to return false for any window that you may hide yourself, since this
* will conflict with what you set.
*/
public boolean canBeForceHidden(WindowState win, WindowManager.LayoutParams attrs);
/**
* Called when the system would like to show a UI to indicate that an
* application is starting. You can use this to add a
@ -523,6 +548,11 @@ public interface WindowManagerPolicy {
*/
public int selectAnimationLw(WindowState win, int transit);
/**
* Create and return an animation to re-display a force hidden window.
*/
public Animation createForceHideEnterAnimation();
/**
* Called from the key queue thread before a key is dispatched to the
* input thread.

View File

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
/*
** 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">
<alpha android:fromAlpha="0.0" android:toAlpha="1.0"
android:duration="@android:integer/config_mediumAnimTime" />
</set>

View File

@ -1,7 +1,6 @@
<?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");

View File

@ -17,8 +17,22 @@
*/
-->
<!-- This version zooms the new non-wallpaper up out of the
wallpaper, without zooming the wallpaper itself. -->
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@anim/decelerate_interpolator"
android:zAdjustment="top">
<scale android:fromXScale=".5" android:toXScale="1.0"
android:fromYScale=".5" android:toYScale="1.0"
android:pivotX="50%p" android:pivotY="50%p"
android:duration="@android:integer/config_mediumAnimTime" />
<alpha android:fromAlpha="0" android:toAlpha="1.0"
android:duration="@android:integer/config_mediumAnimTime"/>
</set>
<!-- This version zooms the new non-wallpaper down on top of the
wallpaper, without zooming the wallpaper itself. -->
<!--
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@anim/decelerate_interpolator"
android:zAdjustment="top">
@ -29,6 +43,7 @@
<alpha android:fromAlpha="0" android:toAlpha="1.0"
android:duration="@android:integer/config_mediumAnimTime"/>
</set>
-->
<!-- This version zooms the new non-wallpaper down on top of the
wallpaper. -->

View File

@ -17,8 +17,20 @@
*/
-->
<!-- This version zooms the new non-wallpaper up out of the
wallpaper, without zooming the wallpaper itself. -->
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@anim/decelerate_interpolator"
android:detachWallpaper="true">
<scale android:fromXScale="1.0" android:toXScale="2.0"
android:fromYScale="1.0" android:toYScale="2.0"
android:pivotX="50%p" android:pivotY="50%p"
android:duration="@android:integer/config_mediumAnimTime" />
</set>
<!-- This version zooms the new non-wallpaper down on top of the
wallpaper, without zooming the wallpaper itself. -->
<!--
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@anim/decelerate_interpolator"
android:detachWallpaper="true">
@ -27,6 +39,7 @@
android:pivotX="50%p" android:pivotY="50%p"
android:duration="@android:integer/config_mediumAnimTime" />
</set>
-->
<!-- This version zooms the new non-wallpaper down on top of the
wallpaper. The wallpaper here just stays fixed behind. -->

View File

@ -17,8 +17,20 @@
*/
-->
<!-- This version zooms the new non-wallpaper up out of the
wallpaper, without zooming the wallpaper itself. -->
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@anim/decelerate_interpolator"
android:detachWallpaper="true">
<scale android:fromXScale="2.0" android:toXScale="1.0"
android:fromYScale="2.0" android:toYScale="1.0"
android:pivotX="50%p" android:pivotY="50%p"
android:duration="@android:integer/config_mediumAnimTime" />
</set>
<!-- This version zooms the new non-wallpaper down on top of the
wallpaper, without zooming the wallpaper itself. -->
<!--
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@anim/decelerate_interpolator"
android:detachWallpaper="true">
@ -27,6 +39,7 @@
android:pivotX="50%p" android:pivotY="50%p"
android:duration="@android:integer/config_mediumAnimTime" />
</set>
-->
<!-- This version zooms the new non-wallpaper up off the wallpaper the
wallpaper. The wallpaper here just stays fixed behind. -->

View File

@ -16,9 +16,22 @@
** limitations under the License.
*/
-->
<!-- This version zooms the new non-wallpaper up out of the
wallpaper, without zooming the wallpaper itself. -->
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@anim/decelerate_interpolator"
android:zAdjustment="top">
<scale android:fromXScale="1.0" android:toXScale=".5"
android:fromYScale="1.0" android:toYScale=".5"
android:pivotX="50%p" android:pivotY="50%p"
android:duration="@android:integer/config_mediumAnimTime" />
<alpha android:fromAlpha="1.0" android:toAlpha="0"
android:duration="@android:integer/config_mediumAnimTime"/>
</set>
<!-- This version zooms the new non-wallpaper down on top of the
wallpaper, without zooming the wallpaper itself. -->
<!--
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@anim/decelerate_interpolator"
android:zAdjustment="top">
@ -29,6 +42,7 @@
<alpha android:fromAlpha="1.0" android:toAlpha="0"
android:duration="@android:integer/config_mediumAnimTime"/>
</set>
-->
<!-- This version zooms the new non-wallpaper down on top of the
wallpaper. -->

View File

@ -33,7 +33,7 @@
<integer name="config_mediumAnimTime">200</integer>
<!-- The duration (in milliseconds) of a long animation. -->
<integer name="config_longAnimTime">400</integer>
<integer name="config_longAnimTime">350</integer>
<!-- XXXXX NOTE THE FOLLOWING RESOURCES USE THE WRONG NAMING CONVENTION.
Please don't copy them, copy anything else. -->

View File

@ -301,6 +301,18 @@ public class WindowManagerService extends IWindowManager.Stub
*/
final ArrayList<AppWindowToken> mFinishedStarting = new ArrayList<AppWindowToken>();
/**
* This was the app token that was used to retrieve the last enter
* animation. It will be used for the next exit animation.
*/
AppWindowToken mLastEnterAnimToken;
/**
* These were the layout params used to retrieve the last enter animation.
* They will be used for the next exit animation.
*/
LayoutParams mLastEnterAnimParams;
/**
* Z-ordered (bottom-most first) list of all Window objects.
*/
@ -374,6 +386,9 @@ public class WindowManagerService extends IWindowManager.Stub
// mOpeningApps and mClosingApps are the lists of tokens that will be
// made visible or hidden at the next transition.
int mNextAppTransition = WindowManagerPolicy.TRANSIT_UNSET;
String mNextAppTransitionPackage;
int mNextAppTransitionEnter;
int mNextAppTransitionExit;
boolean mAppTransitionReady = false;
boolean mAppTransitionRunning = false;
boolean mAppTransitionTimeout = false;
@ -1245,16 +1260,27 @@ public class WindowManagerService extends IWindowManager.Stub
WindowState w = null;
WindowState foundW = null;
int foundI = 0;
WindowState topCurW = null;
int topCurI = 0;
int i = N;
while (i > 0) {
i--;
w = (WindowState)localmWindows.get(i);
if ((w.mAttrs.type == WindowManager.LayoutParams.TYPE_WALLPAPER)) {
if (topCurW == null) {
topCurW = w;
topCurI = i;
}
continue;
}
topCurW = null;
if (w.mAppToken != null) {
// If this window's app token is hidden and not animating,
// it is of no interest to us.
if (w.mAppToken.hidden && w.mAppToken.animation == null) {
if (DEBUG_WALLPAPER) Log.v(TAG,
"Skipping hidden or animating token: " + w);
topCurW = null;
continue;
}
}
@ -1268,8 +1294,9 @@ public class WindowManagerService extends IWindowManager.Stub
"Found wallpaper activity: #" + i + "=" + w);
foundW = w;
foundI = i;
if (w == mWallpaperTarget && w.mAppToken != null
&& w.mAppToken.animation != null) {
if (w == mWallpaperTarget && ((w.mAppToken != null
&& w.mAppToken.animation != null)
|| w.mAnimation != null)) {
// The current wallpaper target is animating, so we'll
// look behind it for another possible target and figure
// out what is going on below.
@ -1316,14 +1343,16 @@ public class WindowManagerService extends IWindowManager.Stub
// Now what is happening... if the current and new targets are
// animating, then we are in our super special mode!
if (foundW != null && foundW.mAppToken != null && oldW != null
&& oldW.mAppToken != null) {
if (foundW != null && oldW != null) {
boolean oldAnim = oldW.mAnimation != null
|| (oldW.mAppToken != null && oldW.mAppToken.animation != null);
boolean foundAnim = foundW.mAnimation != null
|| (foundW.mAppToken != null && foundW.mAppToken.animation != null);
if (DEBUG_WALLPAPER) {
Log.v(TAG, "New animation: " + foundW.mAppToken.animation
+ " old animation: " + oldW.mAppToken.animation);
Log.v(TAG, "New animation: " + foundAnim
+ " old animation: " + oldAnim);
}
if (foundW.mAppToken.animation != null
&& oldW.mAppToken.animation != null) {
if (foundAnim && oldAnim) {
int oldI = localmWindows.indexOf(oldW);
if (DEBUG_WALLPAPER) {
Log.v(TAG, "New i: " + foundI + " old i: " + oldI);
@ -1336,7 +1365,7 @@ public class WindowManagerService extends IWindowManager.Stub
}
// Set the new target correctly.
if (foundW.mAppToken.hiddenRequested) {
if (foundW.mAppToken != null && foundW.mAppToken.hiddenRequested) {
if (DEBUG_WALLPAPER) {
Log.v(TAG, "Old wallpaper still the target.");
}
@ -1417,12 +1446,19 @@ public class WindowManagerService extends IWindowManager.Stub
foundI--;
}
} else {
if (DEBUG_WALLPAPER) Log.v(TAG, "Wallpaper not visible");
if (DEBUG_WALLPAPER) Log.v(TAG, "No wallpaper target");
}
if (foundW == null && topCurW != null) {
// There is no wallpaper target, so it goes at the bottom.
// We will assume it is the same place as last time, if known.
foundW = topCurW;
foundI = topCurI+1;
} else {
// Okay i is the position immediately above the wallpaper. Look at
// what is below it for later.
foundW = foundI > 0 ? (WindowState)localmWindows.get(foundI-1) : null;
}
if (visible) {
mLastWallpaperX = mWallpaperTarget.mWallpaperX;
@ -2244,6 +2280,8 @@ public class WindowManagerService extends IWindowManager.Stub
Surface surface = win.createSurfaceLocked();
if (surface != null) {
outSurface.copyFrom(surface);
win.mReportDestroySurface = false;
win.mSurfacePendingDestroy = false;
if (SHOW_TRANSACTIONS) Log.i(TAG,
" OUT SURFACE " + outSurface + ": copied");
} else {
@ -2269,17 +2307,21 @@ public class WindowManagerService extends IWindowManager.Stub
} else {
win.mEnterAnimationPending = false;
if (win.mSurface != null) {
if (DEBUG_VISIBILITY) Log.i(TAG, "Relayout invis " + win
+ ": mExiting=" + win.mExiting
+ " mSurfacePendingDestroy=" + win.mSurfacePendingDestroy);
// If we are not currently running the exit animation, we
// need to see about starting one.
if (!win.mExiting) {
if (!win.mExiting || win.mSurfacePendingDestroy) {
// Try starting an animation; if there isn't one, we
// can destroy the surface right away.
int transit = WindowManagerPolicy.TRANSIT_EXIT;
if (win.getAttrs().type == TYPE_APPLICATION_STARTING) {
transit = WindowManagerPolicy.TRANSIT_PREVIEW_DONE;
}
if (win.isWinVisibleLw() &&
if (!win.mSurfacePendingDestroy && win.isWinVisibleLw() &&
applyAnimationLocked(win, transit, false)) {
focusMayChange = true;
win.mExiting = true;
mKeyWaiter.finishedKey(session, client, true,
KeyWaiter.RETURN_NOTHING);
@ -2301,11 +2343,23 @@ public class WindowManagerService extends IWindowManager.Stub
}
}
}
if (win.mSurface == null || (win.getAttrs().flags
& WindowManager.LayoutParams.FLAG_KEEP_SURFACE_WHILE_ANIMATING) == 0
|| win.mSurfacePendingDestroy) {
// We are being called from a local process, which
// means outSurface holds its current surface. Ensure the
// surface object is cleared, but we don't want it actually
// destroyed at this point.
win.mSurfacePendingDestroy = false;
outSurface.release();
if (DEBUG_VISIBILITY) Log.i(TAG, "Releasing surface in: " + win);
} else if (win.mSurface != null) {
if (DEBUG_VISIBILITY) Log.i(TAG,
"Keeping surface, will report destroy: " + win);
win.mReportDestroySurface = true;
outSurface.copyFrom(win.mSurface);
}
}
if (focusMayChange) {
@ -2408,6 +2462,21 @@ public class WindowManagerService extends IWindowManager.Stub
return null;
}
private AttributeCache.Entry getCachedAnimations(String packageName, int resId) {
if (DEBUG_ANIM) Log.v(TAG, "Loading animations: params package="
+ packageName + " resId=0x" + Integer.toHexString(resId));
if (packageName != null) {
if ((resId&0xFF000000) == 0x01000000) {
packageName = "android";
}
if (DEBUG_ANIM) Log.v(TAG, "Loading animations: picked package="
+ packageName);
return AttributeCache.instance().get(packageName, resId,
com.android.internal.R.styleable.WindowAnimation);
}
return null;
}
private void applyEnterAnimationLocked(WindowState win) {
int transit = WindowManagerPolicy.TRANSIT_SHOW;
if (win.mEnterAnimationPending) {
@ -2491,6 +2560,22 @@ public class WindowManagerService extends IWindowManager.Stub
return null;
}
private Animation loadAnimation(String packageName, int resId) {
int anim = 0;
Context context = mContext;
if (resId >= 0) {
AttributeCache.Entry ent = getCachedAnimations(packageName, resId);
if (ent != null) {
context = ent.context;
anim = resId;
}
}
if (anim != 0) {
return AnimationUtils.loadAnimation(context, anim);
}
return null;
}
private boolean applyAnimationLocked(AppWindowToken wtoken,
WindowManager.LayoutParams lp, int transit, boolean enter) {
// Only apply an animation if the display isn't frozen. If it is
@ -2503,6 +2588,9 @@ public class WindowManagerService extends IWindowManager.Stub
a = new FadeInOutAnimation(enter);
if (DEBUG_ANIM) Log.v(TAG,
"applying FadeInOutAnimation for a window in compatibility mode");
} else if (mNextAppTransitionPackage != null) {
a = loadAnimation(mNextAppTransitionPackage, enter ?
mNextAppTransitionEnter : mNextAppTransitionExit);
} else {
int animAttr = 0;
switch (transit) {
@ -3032,6 +3120,15 @@ public class WindowManagerService extends IWindowManager.Stub
return mNextAppTransition;
}
public void overridePendingAppTransition(String packageName,
int enterAnim, int exitAnim) {
if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET){
mNextAppTransitionPackage = packageName;
mNextAppTransitionEnter = enterAnim;
mNextAppTransitionExit = exitAnim;
}
}
public void executeAppTransition() {
if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
"executeAppTransition()")) {
@ -3039,8 +3136,12 @@ public class WindowManagerService extends IWindowManager.Stub
}
synchronized(mWindowMap) {
if (DEBUG_APP_TRANSITIONS) Log.v(
TAG, "Execute app transition: mNextAppTransition=" + mNextAppTransition);
if (DEBUG_APP_TRANSITIONS) {
RuntimeException e = new RuntimeException("here");
e.fillInStackTrace();
Log.w(TAG, "Execute app transition: mNextAppTransition="
+ mNextAppTransition, e);
}
if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
mAppTransitionReady = true;
final long origId = Binder.clearCallingIdentity();
@ -3537,6 +3638,10 @@ public class WindowManagerService extends IWindowManager.Stub
wtoken.animating = false;
}
mAppTokens.remove(wtoken);
if (mLastEnterAnimToken == wtoken) {
mLastEnterAnimToken = null;
mLastEnterAnimParams = null;
}
wtoken.removed = true;
if (wtoken.startingData != null) {
startingToken = wtoken;
@ -6527,6 +6632,8 @@ public class WindowManagerService extends IWindowManager.Stub
boolean mPolicyVisibilityAfterAnim = true;
boolean mAppFreezing;
Surface mSurface;
boolean mReportDestroySurface;
boolean mSurfacePendingDestroy;
boolean mAttachedHidden; // is our parent window hidden?
boolean mLastHidden; // was this window last hidden?
boolean mWallpaperVisible; // for wallpaper, what was last vis report?
@ -6929,6 +7036,8 @@ public class WindowManagerService extends IWindowManager.Stub
Surface createSurfaceLocked() {
if (mSurface == null) {
mReportDestroySurface = false;
mSurfacePendingDestroy = false;
mDrawPending = true;
mCommitDrawPending = false;
mReadyToShow = false;
@ -7033,6 +7142,28 @@ public class WindowManagerService extends IWindowManager.Stub
}
if (mSurface != null) {
mDrawPending = false;
mCommitDrawPending = false;
mReadyToShow = false;
int i = mChildWindows.size();
while (i > 0) {
i--;
WindowState c = (WindowState)mChildWindows.get(i);
c.mAttachedHidden = true;
}
if (mReportDestroySurface) {
mReportDestroySurface = false;
mSurfacePendingDestroy = true;
try {
mClient.dispatchGetNewSurface();
// We'll really destroy on the next time around.
return;
} catch (RemoteException e) {
}
}
try {
if (DEBUG_VISIBILITY) {
RuntimeException e = new RuntimeException();
@ -7052,17 +7183,8 @@ public class WindowManagerService extends IWindowManager.Stub
+ " surface " + mSurface + " session " + mSession
+ ": " + e.toString());
}
mSurface = null;
mDrawPending = false;
mCommitDrawPending = false;
mReadyToShow = false;
int i = mChildWindows.size();
while (i > 0) {
i--;
WindowState c = (WindowState)mChildWindows.get(i);
c.mAttachedHidden = true;
}
mSurface = null;
}
}
@ -7471,7 +7593,7 @@ public class WindowManagerService extends IWindowManager.Stub
*/
boolean isVisibleOrAdding() {
final AppWindowToken atoken = mAppToken;
return (mSurface != null
return ((mSurface != null && !mReportDestroySurface)
|| (!mRelayoutCalled && mViewVisibility == View.VISIBLE))
&& mPolicyVisibility && !mAttachedHidden
&& (atoken == null || !atoken.hiddenRequested)
@ -7642,22 +7764,34 @@ public class WindowManagerService extends IWindowManager.Stub
}
public boolean showLw(boolean doAnimation) {
if (!mPolicyVisibility || !mPolicyVisibilityAfterAnim) {
return showLw(doAnimation, true);
}
boolean showLw(boolean doAnimation, boolean requestAnim) {
if (mPolicyVisibility && mPolicyVisibilityAfterAnim) {
return false;
}
mPolicyVisibility = true;
mPolicyVisibilityAfterAnim = true;
if (doAnimation) {
applyAnimationLocked(this, WindowManagerPolicy.TRANSIT_ENTER, true);
}
if (requestAnim) {
requestAnimationLocked(0);
return true;
}
return false;
return true;
}
public boolean hideLw(boolean doAnimation) {
return hideLw(doAnimation, true);
}
boolean hideLw(boolean doAnimation, boolean requestAnim) {
boolean current = doAnimation ? mPolicyVisibilityAfterAnim
: mPolicyVisibility;
if (current) {
if (!current) {
return false;
}
if (doAnimation) {
applyAnimationLocked(this, WindowManagerPolicy.TRANSIT_EXIT, false);
if (mAnimation == null) {
@ -7670,10 +7804,10 @@ public class WindowManagerService extends IWindowManager.Stub
mPolicyVisibilityAfterAnim = false;
mPolicyVisibility = false;
}
if (requestAnim) {
requestAnimationLocked(0);
return true;
}
return false;
return true;
}
void dump(PrintWriter pw, String prefix) {
@ -8703,28 +8837,37 @@ public class WindowManagerService extends IWindowManager.Stub
final void rebuildAppWindowListLocked() {
int NW = mWindows.size();
int i;
int lastWallpaper = -1;
int numRemoved = 0;
// First remove all existing app windows.
i=0;
while (i < NW) {
if (((WindowState)mWindows.get(i)).mAppToken != null) {
WindowState w = (WindowState)mWindows.get(i);
if (w.mAppToken != null) {
WindowState win = (WindowState)mWindows.remove(i);
if (DEBUG_WINDOW_MOVEMENT) Log.v(TAG,
"Rebuild removing window: " + win);
NW--;
numRemoved++;
continue;
} else if (w.mAttrs.type == WindowManager.LayoutParams.TYPE_WALLPAPER
&& lastWallpaper == i-1) {
lastWallpaper = i;
}
i++;
}
// The wallpaper window(s) typically live at the bottom of the stack,
// so skip them before adding app tokens.
lastWallpaper++;
i = lastWallpaper;
// First add all of the exiting app tokens... these are no longer
// in the main app list, but still have windows shown. We put them
// in the back because now that the animation is over we no longer
// will care about them.
int NT = mExitingAppTokens.size();
i = 0;
for (int j=0; j<NT; j++) {
i = reAddAppWindowsLocked(i, mExitingAppTokens.get(j));
}
@ -8735,6 +8878,7 @@ public class WindowManagerService extends IWindowManager.Stub
i = reAddAppWindowsLocked(i, mAppTokens.get(j));
}
i -= lastWallpaper;
if (i != numRemoved) {
Log.w(TAG, "Rebuild removed " + numRemoved
+ " windows but added " + i);
@ -8970,6 +9114,7 @@ public class WindowManagerService extends IWindowManager.Stub
Surface.openTransaction();
try {
boolean restart;
boolean forceHiding = false;
do {
final int transactionSequence = ++mTransactionSequence;
@ -8995,6 +9140,8 @@ public class WindowManagerService extends IWindowManager.Stub
boolean tokenMayBeDrawn = false;
boolean wallpaperMayChange = false;
boolean focusMayChange = false;
boolean wallpaperForceHidingChanged = false;
mPolicy.beginAnimationLw(dw, dh);
@ -9015,6 +9162,7 @@ public class WindowManagerService extends IWindowManager.Stub
wallpaperMayChange = true;
}
}
boolean wasAnimating = w.mAnimating;
if (w.stepAnimationLocked(currentTime, dw, dh)) {
animating = true;
@ -9023,6 +9171,38 @@ public class WindowManagerService extends IWindowManager.Stub
if (wasAnimating && !w.mAnimating && mWallpaperTarget == w) {
wallpaperMayChange = true;
}
if (mPolicy.doesForceHide(w, attrs)) {
if (!wasAnimating && animating) {
wallpaperForceHidingChanged = true;
focusMayChange = true;
} else if (w.isReadyForDisplay() && w.mAnimation == null) {
forceHiding = true;
}
} else if (mPolicy.canBeForceHidden(w, attrs)) {
boolean changed;
if (forceHiding) {
changed = w.hideLw(false, false);
} else {
changed = w.showLw(false, false);
if (changed && wallpaperForceHidingChanged
&& w.isReadyForDisplay()) {
// Assume we will need to animate. If
// we don't (because the wallpaper will
// stay with the lock screen), then we will
// clean up later.
Animation a = mPolicy.createForceHideEnterAnimation();
if (a != null) {
w.setAnimation(a);
}
}
}
if (changed && (attrs.flags
& WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER) != 0) {
wallpaperMayChange = true;
}
}
mPolicy.animatingWindowLw(w, attrs);
}
@ -9147,6 +9327,7 @@ public class WindowManagerService extends IWindowManager.Stub
transit = WindowManagerPolicy.TRANSIT_UNSET;
}
mNextAppTransition = WindowManagerPolicy.TRANSIT_UNSET;
mNextAppTransitionPackage = null;
mAppTransitionReady = false;
mAppTransitionRunning = true;
mAppTransitionTimeout = false;
@ -9180,6 +9361,7 @@ public class WindowManagerService extends IWindowManager.Stub
// The top-most window will supply the layout params,
// and we will determine it below.
LayoutParams animLp = null;
AppWindowToken animToken = null;
int bestAnimLayer = -1;
if (DEBUG_APP_TRANSITIONS) Log.v(TAG,
@ -9222,9 +9404,11 @@ public class WindowManagerService extends IWindowManager.Stub
// window, we will always use its anim.
if ((ws.mAttrs.flags&FLAG_COMPATIBLE_WINDOW) != 0) {
animLp = ws.mAttrs;
animToken = ws.mAppToken;
bestAnimLayer = Integer.MAX_VALUE;
} else if (ws.mLayer > bestAnimLayer) {
animLp = ws.mAttrs;
animToken = ws.mAppToken;
bestAnimLayer = ws.mLayer;
}
}
@ -9262,6 +9446,15 @@ public class WindowManagerService extends IWindowManager.Stub
"New transit into wallpaper: " + transit);
}
if ((transit&WindowManagerPolicy.TRANSIT_ENTER_MASK) != 0) {
mLastEnterAnimToken = animToken;
mLastEnterAnimParams = animLp;
} else if (mLastEnterAnimParams != null) {
animLp = mLastEnterAnimParams;
mLastEnterAnimToken = null;
mLastEnterAnimParams = null;
}
NN = mOpeningApps.size();
for (i=0; i<NN; i++) {
AppWindowToken wtoken = mOpeningApps.get(i);
@ -9302,6 +9495,7 @@ public class WindowManagerService extends IWindowManager.Stub
}
performLayoutLockedInner();
updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES);
focusMayChange = false;
restart = true;
}
@ -9325,10 +9519,48 @@ public class WindowManagerService extends IWindowManager.Stub
mLayoutNeeded = true;
}
int adjResult = 0;
if (wallpaperForceHidingChanged) {
// At this point, there was a window with a wallpaper that
// was force hiding other windows behind it, but now it
// is going away. This may be simple -- just animate
// away the wallpaper and its window -- or it may be
// hard -- the wallpaper now needs to be shown behind
// something that was hidden.
WindowState oldWallpaper = mWallpaperTarget;
adjResult = adjustWallpaperWindowsLocked();
wallpaperMayChange = false;
if (false) Log.v(TAG, "****** OLD: " + oldWallpaper
+ " NEW: " + mWallpaperTarget);
if (mLowerWallpaperTarget == null) {
// Whoops, we don't need a special wallpaper animation.
// Clear them out.
forceHiding = false;
for (i=N-1; i>=0; i--) {
WindowState w = (WindowState)mWindows.get(i);
if (w.mSurface != null) {
final WindowManager.LayoutParams attrs = w.mAttrs;
if (mPolicy.doesForceHide(w, attrs)) {
forceHiding = true;
} else if (mPolicy.canBeForceHidden(w, attrs)) {
if (!w.mAnimating) {
// We set the animation above so it
// is not yet running.
w.clearAnimation();
}
}
}
}
}
}
if (wallpaperMayChange) {
if (DEBUG_WALLPAPER) Log.v(TAG,
"Wallpaper may change! Adjusting");
int adjResult = adjustWallpaperWindowsLocked();
adjResult = adjustWallpaperWindowsLocked();
}
if ((adjResult&ADJUST_WALLPAPER_LAYERS_CHANGED) != 0) {
if (DEBUG_WALLPAPER) Log.v(TAG,
"Wallpaper layer changed: assigning layers + relayout");
@ -9341,11 +9573,18 @@ public class WindowManagerService extends IWindowManager.Stub
restart = true;
mLayoutNeeded = true;
}
if (focusMayChange) {
if (updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES)) {
restart = true;
adjResult = 0;
}
}
if (mLayoutNeeded) {
restart = true;
performLayoutLockedInner();
}
}
} while (restart);
@ -9359,7 +9598,6 @@ public class WindowManagerService extends IWindowManager.Stub
boolean covered = false;
boolean syswin = false;
boolean backgroundFillerShown = false;
boolean forceHiding = false;
final int N = mWindows.size();
@ -9492,15 +9730,12 @@ public class WindowManagerService extends IWindowManager.Stub
}
}
if ((forceHiding
&& attrs.type != WindowManager.LayoutParams.TYPE_STATUS_BAR
&& attrs.type != WindowManager.LayoutParams.TYPE_WALLPAPER)
|| w.mAttachedHidden) {
if (w.mAttachedHidden || !w.isReadyForDisplay()) {
if (!w.mLastHidden) {
//dump();
w.mLastHidden = true;
if (SHOW_TRANSACTIONS) Log.i(
TAG, " SURFACE " + w.mSurface + ": HIDE (performLayout-attached)");
TAG, " SURFACE " + w.mSurface + ": HIDE (performLayout)");
if (w.mSurface != null) {
try {
w.mSurface.hide();
@ -9521,32 +9756,6 @@ public class WindowManagerService extends IWindowManager.Stub
if (DEBUG_ORIENTATION) Log.v(TAG,
"Orientation change skips hidden " + w);
}
} else if (!w.isReadyForDisplay()) {
if (!w.mLastHidden) {
//dump();
w.mLastHidden = true;
if (SHOW_TRANSACTIONS) Log.i(
TAG, " SURFACE " + w.mSurface + ": HIDE (performLayout-ready)");
if (w.mSurface != null) {
try {
w.mSurface.hide();
} catch (RuntimeException e) {
Log.w(TAG, "Exception exception hiding surface in " + w);
}
}
mKeyWaiter.releasePendingPointerLocked(w.mSession);
}
// If we are waiting for this window to handle an
// orientation change, well, it is hidden, so
// doesn't really matter. Note that this does
// introduce a potential glitch if the window
// becomes unhidden before it has drawn for the
// new orientation.
if (w.mOrientationChanging) {
w.mOrientationChanging = false;
if (DEBUG_ORIENTATION) Log.v(TAG,
"Orientation change skips hidden " + w);
}
} else if (w.mLastLayer != w.mAnimLayer
|| w.mLastAlpha != w.mShownAlpha
|| w.mLastDsDx != w.mDsDx
@ -9609,9 +9818,6 @@ public class WindowManagerService extends IWindowManager.Stub
}
if (displayed) {
if (attrs.type == WindowManager.LayoutParams.TYPE_KEYGUARD) {
forceHiding = true;
}
if (!covered) {
if (attrs.width == LayoutParams.FILL_PARENT
&& attrs.height == LayoutParams.FILL_PARENT) {
@ -9694,7 +9900,7 @@ public class WindowManagerService extends IWindowManager.Stub
}
backgroundFillerShown = true;
mBackgroundFillerShown = true;
} else if (canBeSeen && !obscured && !forceHiding &&
} else if (canBeSeen && !obscured &&
(attrFlags&FLAG_BLUR_BEHIND|FLAG_DIM_BEHIND) != 0) {
if (localLOGV) Log.v(TAG, "Win " + w
+ ": blurring=" + blurring
@ -9860,6 +10066,10 @@ public class WindowManagerService extends IWindowManager.Stub
token.animating = false;
mAppTokens.remove(token);
mExitingAppTokens.remove(i);
if (mLastEnterAnimToken == token) {
mLastEnterAnimToken = null;
mLastEnterAnimParams = null;
}
}
}
@ -10169,6 +10379,7 @@ public class WindowManagerService extends IWindowManager.Stub
mDisplayFrozen = true;
if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
mNextAppTransition = WindowManagerPolicy.TRANSIT_UNSET;
mNextAppTransitionPackage = null;
mAppTransitionReady = true;
}
@ -10403,8 +10614,20 @@ public class WindowManagerService extends IWindowManager.Stub
pw.print(", mAppTransitionReady="); pw.print(mAppTransitionReady);
pw.print(", mAppTransitionRunning="); pw.print(mAppTransitionRunning);
pw.print(", mAppTransitionTimeout="); pw.println( mAppTransitionTimeout);
if (mNextAppTransitionPackage != null) {
pw.print(" mNextAppTransitionPackage=");
pw.print(mNextAppTransitionPackage);
pw.print(", mNextAppTransitionEnter=0x");
pw.print(Integer.toHexString(mNextAppTransitionEnter));
pw.print(", mNextAppTransitionExit=0x");
pw.print(Integer.toHexString(mNextAppTransitionExit));
}
pw.print(" mStartingIconInTransition="); pw.print(mStartingIconInTransition);
pw.print(", mSkipAppTransitionAnimation="); pw.println(mSkipAppTransitionAnimation);
if (mLastEnterAnimToken != null || mLastEnterAnimToken != null) {
pw.print(" mLastEnterAnimToken="); pw.print(mLastEnterAnimToken);
pw.print(", mLastEnterAnimParams="); pw.println(mLastEnterAnimParams);
}
if (mOpeningApps.size() > 0) {
pw.print(" mOpeningApps="); pw.println(mOpeningApps);
}

View File

@ -2722,6 +2722,8 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
// Do over!
mHandler.sendEmptyMessage(RESUME_TOP_ACTIVITY_MSG);
}
setFocusedActivityLocked(next);
ensureActivitiesVisibleLocked(null, 0);
mWindowManager.executeAppTransition();
mNoAnimActivities.clear();
return true;
@ -4196,6 +4198,27 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
}
}
public void overridePendingTransition(IBinder token, String packageName,
int enterAnim, int exitAnim) {
synchronized(this) {
int index = indexOfTokenLocked(token);
if (index < 0) {
return;
}
HistoryRecord self = (HistoryRecord)mHistory.get(index);
final long origId = Binder.clearCallingIdentity();
if (self.state == ActivityState.RESUMED
|| self.state == ActivityState.PAUSING) {
mWindowManager.overridePendingAppTransition(packageName,
enterAnim, exitAnim);
}
Binder.restoreCallingIdentity(origId);
}
}
/**
* Perform clean-up of service connections in an activity record.
*/