A variety of work on animations.
- The lock screen now fades in and out.
- Fixed a bug where we would accidentally freeze the screen when switching
to an activity with a different orientation than the current (but
the screen itself is in the current orientation). This would mess up
the animations on the car dock.
- New API to force a particular animation for an activity transition
(untested).
- New wallpaper animations.
- Resources now uses the next API version when in a development build,
to help applications being developed against such builds.
Change-Id: I2d9998f8400967ff09a04d693dc4ce55f0dbef5b
diff --git a/api/current.xml b/api/current.xml
index 35bfab3..d5f3f46 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -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"
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 4561899..8755477 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -3015,6 +3015,23 @@
}
/**
+ * 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.
*
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index 82d49e3..2d7658a 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -1153,6 +1153,16 @@
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 @@
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;
}
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index 110b72d..7ad7561 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -285,6 +285,9 @@
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 @@
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;
}
diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java
index 8839f95..7a65af8 100644
--- a/core/java/android/content/pm/ApplicationInfo.java
+++ b/core/java/android/content/pm/ApplicationInfo.java
@@ -253,7 +253,7 @@
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
diff --git a/core/java/android/content/res/Resources.java b/core/java/android/content/res/Resources.java
index 3796201..00ab7de 100644
--- a/core/java/android/content/res/Resources.java
+++ b/core/java/android/content/res/Resources.java
@@ -25,6 +25,7 @@
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 @@
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;
diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl
index 7d1872a..23e7fb7 100644
--- a/core/java/android/view/IWindowManager.aidl
+++ b/core/java/android/view/IWindowManager.aidl
@@ -71,6 +71,7 @@
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,
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index 396e380..7a22301 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -522,6 +522,13 @@
* 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.
diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java
index 1923743..b3125b2 100644
--- a/core/java/android/view/WindowManagerPolicy.java
+++ b/core/java/android/view/WindowManagerPolicy.java
@@ -314,50 +314,60 @@
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;
@@ -444,6 +454,21 @@
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
* APPLICATION_STARTING_TYPE window with the given appToken to the window
@@ -524,6 +549,11 @@
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.
*
diff --git a/core/res/res/anim/lock_screen_behind_enter.xml b/core/res/res/anim/lock_screen_behind_enter.xml
new file mode 100644
index 0000000..9e03e15
--- /dev/null
+++ b/core/res/res/anim/lock_screen_behind_enter.xml
@@ -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>
diff --git a/core/res/res/anim/lock_screen_exit.xml b/core/res/res/anim/lock_screen_exit.xml
index 55c5ec9..0d32921 100644
--- a/core/res/res/anim/lock_screen_exit.xml
+++ b/core/res/res/anim/lock_screen_exit.xml
@@ -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");
diff --git a/core/res/res/anim/wallpaper_close_enter.xml b/core/res/res/anim/wallpaper_close_enter.xml
index 5bc299e..2329abb 100644
--- a/core/res/res/anim/wallpaper_close_enter.xml
+++ b/core/res/res/anim/wallpaper_close_enter.xml
@@ -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. -->
diff --git a/core/res/res/anim/wallpaper_close_exit.xml b/core/res/res/anim/wallpaper_close_exit.xml
index c3ae620..eccce81 100644
--- a/core/res/res/anim/wallpaper_close_exit.xml
+++ b/core/res/res/anim/wallpaper_close_exit.xml
@@ -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. -->
diff --git a/core/res/res/anim/wallpaper_open_enter.xml b/core/res/res/anim/wallpaper_open_enter.xml
index 7fe7e1e..3a6fb05 100644
--- a/core/res/res/anim/wallpaper_open_enter.xml
+++ b/core/res/res/anim/wallpaper_open_enter.xml
@@ -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. -->
diff --git a/core/res/res/anim/wallpaper_open_exit.xml b/core/res/res/anim/wallpaper_open_exit.xml
index 9489c6d..e5b7007 100644
--- a/core/res/res/anim/wallpaper_open_exit.xml
+++ b/core/res/res/anim/wallpaper_open_exit.xml
@@ -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. -->
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index b508372..cf0dfd7 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -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. -->
diff --git a/services/java/com/android/server/WindowManagerService.java b/services/java/com/android/server/WindowManagerService.java
index 2c39c2a..78a82dd 100644
--- a/services/java/com/android/server/WindowManagerService.java
+++ b/services/java/com/android/server/WindowManagerService.java
@@ -302,6 +302,18 @@
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.
*/
final ArrayList mWindows = new ArrayList();
@@ -374,6 +386,9 @@
// 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 @@
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 @@
"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 @@
// 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 @@
}
// 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 @@
foundI--;
}
} else {
- if (DEBUG_WALLPAPER) Log.v(TAG, "Wallpaper not visible");
+ if (DEBUG_WALLPAPER) Log.v(TAG, "No wallpaper target");
}
- // 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 (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 @@
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 @@
} 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 @@
}
}
}
- // 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.
- outSurface.release();
+
+ 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 @@
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 @@
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 @@
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 @@
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 @@
}
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 @@
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 @@
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 @@
Surface createSurfaceLocked() {
if (mSurface == null) {
+ mReportDestroySurface = false;
+ mSurfacePendingDestroy = false;
mDrawPending = true;
mCommitDrawPending = false;
mReadyToShow = false;
@@ -7033,6 +7142,28 @@
}
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 @@
+ " 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;
- }
}
}
@@ -7471,7 +7593,7 @@
*/
boolean isVisibleOrAdding() {
final AppWindowToken atoken = mAppToken;
- return (mSurface != null
+ return ((mSurface != null && !mReportDestroySurface)
|| (!mRelayoutCalled && mViewVisibility == View.VISIBLE))
&& mPolicyVisibility && !mAttachedHidden
&& (atoken == null || !atoken.hiddenRequested)
@@ -7642,38 +7764,50 @@
}
public boolean showLw(boolean doAnimation) {
- if (!mPolicyVisibility || !mPolicyVisibilityAfterAnim) {
- mPolicyVisibility = true;
- mPolicyVisibilityAfterAnim = true;
- if (doAnimation) {
- applyAnimationLocked(this, WindowManagerPolicy.TRANSIT_ENTER, true);
- }
- requestAnimationLocked(0);
- return true;
+ return showLw(doAnimation, true);
+ }
+
+ boolean showLw(boolean doAnimation, boolean requestAnim) {
+ if (mPolicyVisibility && mPolicyVisibilityAfterAnim) {
+ return false;
}
- return false;
+ mPolicyVisibility = true;
+ mPolicyVisibilityAfterAnim = true;
+ if (doAnimation) {
+ applyAnimationLocked(this, WindowManagerPolicy.TRANSIT_ENTER, true);
+ }
+ if (requestAnim) {
+ requestAnimationLocked(0);
+ }
+ 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 (doAnimation) {
- applyAnimationLocked(this, WindowManagerPolicy.TRANSIT_EXIT, false);
- if (mAnimation == null) {
- doAnimation = false;
- }
- }
- if (doAnimation) {
- mPolicyVisibilityAfterAnim = false;
- } else {
- mPolicyVisibilityAfterAnim = false;
- mPolicyVisibility = false;
- }
- requestAnimationLocked(0);
- return true;
+ if (!current) {
+ return false;
}
- return false;
+ if (doAnimation) {
+ applyAnimationLocked(this, WindowManagerPolicy.TRANSIT_EXIT, false);
+ if (mAnimation == null) {
+ doAnimation = false;
+ }
+ }
+ if (doAnimation) {
+ mPolicyVisibilityAfterAnim = false;
+ } else {
+ mPolicyVisibilityAfterAnim = false;
+ mPolicyVisibility = false;
+ }
+ if (requestAnim) {
+ requestAnimationLocked(0);
+ }
+ return true;
}
void dump(PrintWriter pw, String prefix) {
@@ -8703,28 +8837,37 @@
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 @@
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 @@
Surface.openTransaction();
try {
boolean restart;
+ boolean forceHiding = false;
do {
final int transactionSequence = ++mTransactionSequence;
@@ -8995,6 +9140,8 @@
boolean tokenMayBeDrawn = false;
boolean wallpaperMayChange = false;
+ boolean focusMayChange = false;
+ boolean wallpaperForceHidingChanged = false;
mPolicy.beginAnimationLw(dw, dh);
@@ -9015,6 +9162,7 @@
wallpaperMayChange = true;
}
}
+
boolean wasAnimating = w.mAnimating;
if (w.stepAnimationLocked(currentTime, dw, dh)) {
animating = true;
@@ -9023,6 +9171,38 @@
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 @@
transit = WindowManagerPolicy.TRANSIT_UNSET;
}
mNextAppTransition = WindowManagerPolicy.TRANSIT_UNSET;
+ mNextAppTransitionPackage = null;
mAppTransitionReady = false;
mAppTransitionRunning = true;
mAppTransitionTimeout = false;
@@ -9180,6 +9361,7 @@
// 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 @@
// 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 @@
"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 @@
}
performLayoutLockedInner();
updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES);
+ focusMayChange = false;
restart = true;
}
@@ -9325,26 +9519,71 @@
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();
- if ((adjResult&ADJUST_WALLPAPER_LAYERS_CHANGED) != 0) {
- if (DEBUG_WALLPAPER) Log.v(TAG,
- "Wallpaper layer changed: assigning layers + relayout");
+ adjResult = adjustWallpaperWindowsLocked();
+ }
+
+ if ((adjResult&ADJUST_WALLPAPER_LAYERS_CHANGED) != 0) {
+ if (DEBUG_WALLPAPER) Log.v(TAG,
+ "Wallpaper layer changed: assigning layers + relayout");
+ restart = true;
+ mLayoutNeeded = true;
+ assignLayersLocked();
+ } else if ((adjResult&ADJUST_WALLPAPER_VISIBILITY_CHANGED) != 0) {
+ if (DEBUG_WALLPAPER) Log.v(TAG,
+ "Wallpaper visibility changed: relayout");
+ restart = true;
+ mLayoutNeeded = true;
+ }
+
+ if (focusMayChange) {
+ if (updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES)) {
restart = true;
- mLayoutNeeded = true;
- assignLayersLocked();
- } else if ((adjResult&ADJUST_WALLPAPER_VISIBILITY_CHANGED) != 0) {
- if (DEBUG_WALLPAPER) Log.v(TAG,
- "Wallpaper visibility changed: relayout");
- restart = true;
- mLayoutNeeded = true;
+ adjResult = 0;
}
- if (mLayoutNeeded) {
- restart = true;
- performLayoutLockedInner();
- }
+ }
+
+ if (mLayoutNeeded) {
+ restart = true;
+ performLayoutLockedInner();
}
} while (restart);
@@ -9359,7 +9598,6 @@
boolean covered = false;
boolean syswin = false;
boolean backgroundFillerShown = false;
- boolean forceHiding = false;
final int N = mWindows.size();
@@ -9492,15 +9730,12 @@
}
}
- 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 @@
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 @@
}
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 @@
}
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 @@
token.animating = false;
mAppTokens.remove(token);
mExitingAppTokens.remove(i);
+ if (mLastEnterAnimToken == token) {
+ mLastEnterAnimToken = null;
+ mLastEnterAnimParams = null;
+ }
}
}
@@ -10169,6 +10379,7 @@
mDisplayFrozen = true;
if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
mNextAppTransition = WindowManagerPolicy.TRANSIT_UNSET;
+ mNextAppTransitionPackage = null;
mAppTransitionReady = true;
}
@@ -10403,8 +10614,20 @@
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);
}
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index e953b81..d917d17 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -2722,6 +2722,8 @@
// Do over!
mHandler.sendEmptyMessage(RESUME_TOP_ACTIVITY_MSG);
}
+ setFocusedActivityLocked(next);
+ ensureActivitiesVisibleLocked(null, 0);
mWindowManager.executeAppTransition();
mNoAnimActivities.clear();
return true;
@@ -4196,6 +4198,27 @@
}
}
+ 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.
*/