From de2606dcd36e9dfa49c42dbc68c539505d5ff8d4 Mon Sep 17 00:00:00 2001 From: Dianne Hackborn Date: Fri, 18 Dec 2009 16:53:55 -0800 Subject: [PATCH] Don't perform app transition of the app is not currently visible. Yet more special casing for the window manager... try really hard, if we are performing an activity transition that is behind an opaque window (like say the lock screen or status bar) to just not do it. And, just as important, do a reasonable transition away from whatever is on top. Examples: - If the lock screen is up, and you get a call or press the emergency dialer button, we fade from the lock screen to the new UI, instead of fading to the animation going on between the old and new. - If you are in something hiding the lock screen, like the in-call screen, and that is hidden, then fade back to the lock screen. - If you select an item from the status bar, then have the new item displayed behind it as the status bar rolls up rather than seeing a second animation. (In fact this can't always be done because we may not start the transition to the new thing until the status bar is already going away. But for most cases we can do this with just one anim.) --- .../android/view/WindowManagerPolicy.java | 13 ++++ core/res/res/anim/lock_screen_enter.xml | 24 ++++++++ core/res/res/anim/lock_screen_exit.xml | 3 +- core/res/res/values/styles.xml | 1 + .../android/server/WindowManagerService.java | 59 +++++++++++++++---- 5 files changed, 87 insertions(+), 13 deletions(-) create mode 100644 core/res/res/anim/lock_screen_enter.xml diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java index 5d3840a244b1e..bbe9c1fdbfc0e 100644 --- a/core/java/android/view/WindowManagerPolicy.java +++ b/core/java/android/view/WindowManagerPolicy.java @@ -661,6 +661,14 @@ public interface WindowManagerPolicy { */ public boolean finishAnimationLw(); + /** + * Return true if it is okay to perform animations for an app transition + * that is about to occur. You may return false for this if, for example, + * the lock screen is currently displayed so the switch should happen + * immediately. + */ + public boolean allowAppAnimationsLw(); + /** * Called after the screen turns off. * @@ -674,6 +682,11 @@ public interface WindowManagerPolicy { */ public void screenTurnedOn(); + /** + * Return whether the screen is currently on. + */ + public boolean isScreenOn(); + /** * Perform any initial processing of a low-level input event before the * window manager handles special keys and generates a high-level event diff --git a/core/res/res/anim/lock_screen_enter.xml b/core/res/res/anim/lock_screen_enter.xml new file mode 100644 index 0000000000000..dd47ff866436f --- /dev/null +++ b/core/res/res/anim/lock_screen_enter.xml @@ -0,0 +1,24 @@ + + + + + + diff --git a/core/res/res/anim/lock_screen_exit.xml b/core/res/res/anim/lock_screen_exit.xml index 58bc6dbf0f7ee..077fc6baaa242 100644 --- a/core/res/res/anim/lock_screen_exit.xml +++ b/core/res/res/anim/lock_screen_exit.xml @@ -17,7 +17,8 @@ */ --> - + diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml index b155769e6140d..f2b52d9b5b771 100644 --- a/core/res/res/values/styles.xml +++ b/core/res/res/values/styles.xml @@ -101,6 +101,7 @@ diff --git a/services/java/com/android/server/WindowManagerService.java b/services/java/com/android/server/WindowManagerService.java index b2cf9ec9f4bd7..cdb8686735035 100644 --- a/services/java/com/android/server/WindowManagerService.java +++ b/services/java/com/android/server/WindowManagerService.java @@ -2020,7 +2020,7 @@ public class WindowManagerService extends IWindowManager.Stub // to hold off on removing the window until the animation is done. // If the display is frozen, just remove immediately, since the // animation wouldn't be seen. - if (win.mSurface != null && !mDisplayFrozen) { + if (win.mSurface != null && !mDisplayFrozen && mPolicy.isScreenOn()) { // If we are not currently running the exit animation, we // need to see about starting one. if (wasVisible=win.isWinVisibleLw()) { @@ -2336,7 +2336,8 @@ public class WindowManagerService extends IWindowManager.Stub win.mEnterAnimationPending = true; } if (displayed && win.mSurface != null && !win.mDrawPending - && !win.mCommitDrawPending && !mDisplayFrozen) { + && !win.mCommitDrawPending && !mDisplayFrozen + && mPolicy.isScreenOn()) { applyEnterAnimationLocked(win); } if (displayed && (win.mAttrs.flags @@ -2588,7 +2589,7 @@ public class WindowManagerService extends IWindowManager.Stub // frozen, there is no reason to animate and it can cause strange // artifacts when we unfreeze the display if some different animation // is running. - if (!mDisplayFrozen) { + if (!mDisplayFrozen && mPolicy.isScreenOn()) { int anim = mPolicy.selectAnimationLw(win, transit); int attr = -1; Animation a = null; @@ -2671,7 +2672,7 @@ public class WindowManagerService extends IWindowManager.Stub // frozen, there is no reason to animate and it can cause strange // artifacts when we unfreeze the display if some different animation // is running. - if (!mDisplayFrozen) { + if (!mDisplayFrozen && mPolicy.isScreenOn()) { Animation a; if (lp != null && (lp.flags & FLAG_COMPATIBLE_WINDOW) != 0) { a = new FadeInOutAnimation(enter); @@ -3262,7 +3263,7 @@ public class WindowManagerService extends IWindowManager.Stub // If the display is frozen, we won't do anything until the // actual window is displayed so there is no reason to put in // the starting window. - if (mDisplayFrozen) { + if (mDisplayFrozen || !mPolicy.isScreenOn()) { return; } @@ -7491,7 +7492,7 @@ public class WindowManagerService extends IWindowManager.Stub // This must be called while inside a transaction. Returns true if // there is more animation to run. boolean stepAnimationLocked(long currentTime, int dw, int dh) { - if (!mDisplayFrozen) { + if (!mDisplayFrozen && mPolicy.isScreenOn()) { // We will run animations as long as the display isn't frozen. if (!mDrawPending && !mCommitDrawPending && mAnimation != null) { @@ -8421,7 +8422,7 @@ public class WindowManagerService extends IWindowManager.Stub // This must be called while inside a transaction. boolean stepAnimationLocked(long currentTime, int dw, int dh) { - if (!mDisplayFrozen) { + if (!mDisplayFrozen && mPolicy.isScreenOn()) { // We will run animations as long as the display isn't frozen. if (animation == sDummyAnimation) { @@ -9391,6 +9392,7 @@ public class WindowManagerService extends IWindowManager.Stub try { boolean restart; boolean forceHiding = false; + boolean wallpaperForceHidingChanged = false; do { final int transactionSequence = ++mTransactionSequence; @@ -9411,13 +9413,16 @@ public class WindowManagerService extends IWindowManager.Stub } } + if (DEBUG_APP_TRANSITIONS) Log.v(TAG, "*** ANIM STEP: seq=" + + transactionSequence + " tokensAnimating=" + + tokensAnimating); + animating = tokensAnimating; restart = false; boolean tokenMayBeDrawn = false; boolean wallpaperMayChange = false; boolean focusMayChange = false; - boolean wallpaperForceHidingChanged = false; mPolicy.beginAnimationLw(dw, dh); @@ -9730,6 +9735,14 @@ public class WindowManagerService extends IWindowManager.Stub mLastEnterAnimParams = null; } + // If all closing windows are obscured, then there is + // no need to do an animation. This is the case, for + // example, when this transition is being done behind + // the lock screen. + if (!mPolicy.allowAppAnimationsLw()) { + animLp = null; + } + NN = mOpeningApps.size(); for (i=0; i