From a48eadbeb6fa34f27d6db7de51d3c01972ea2ebf Mon Sep 17 00:00:00 2001 From: Wale Ogunwale Date: Thu, 14 May 2015 17:43:12 -0700 Subject: [PATCH] Send AppTransitionFinish notification when there was no animation Activity#onEnterAnimationComplete() is the hook that we advise app developers to use to know when they are allowed to start drawing (so they don't collide with the window transition animation). However, it's not invoked if the window transition has no animation (e.g. by calling Activity#overridePendingTransition(0,0). Bug: 20823935 Change-Id: I5b286968b0cd3351e9a9224294d0a1e7faf8c654 --- .../com/android/server/wm/AppTransition.java | 3 +- .../android/server/wm/AppWindowAnimator.java | 2 +- .../server/wm/WindowManagerService.java | 73 ++++++++----------- 3 files changed, 34 insertions(+), 44 deletions(-) diff --git a/services/core/java/com/android/server/wm/AppTransition.java b/services/core/java/com/android/server/wm/AppTransition.java index 0357de270d87c..60bbc48934466 100644 --- a/services/core/java/com/android/server/wm/AppTransition.java +++ b/services/core/java/com/android/server/wm/AppTransition.java @@ -325,8 +325,7 @@ public class AppTransition implements Dump { mListeners.add(listener); } - public void notifyAppTransitionFinishedLocked(AppWindowAnimator animator) { - IBinder token = animator != null ? animator.mAppToken.token : null; + public void notifyAppTransitionFinishedLocked(IBinder token) { for (int i = 0; i < mListeners.size(); i++) { mListeners.get(i).onAppTransitionFinishedLocked(token); } diff --git a/services/core/java/com/android/server/wm/AppWindowAnimator.java b/services/core/java/com/android/server/wm/AppWindowAnimator.java index 3feec8209ed08..2e8938597e33d 100644 --- a/services/core/java/com/android/server/wm/AppWindowAnimator.java +++ b/services/core/java/com/android/server/wm/AppWindowAnimator.java @@ -345,7 +345,7 @@ public class AppWindowAnimator { for (int i = 0; i < numAllAppWinAnimators; i++) { mAllAppWinAnimators.get(i).finishExit(); } - mService.mAppTransition.notifyAppTransitionFinishedLocked(this); + mService.mAppTransition.notifyAppTransitionFinishedLocked(mAppToken.token); return false; } diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 4972ce4d84cce..6d801a4680941 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -251,11 +251,6 @@ public class WindowManagerService extends IWindowManager.Stub */ static final int LAYER_OFFSET_DIM = 1; - /** - * Blur surface layer is immediately below dim layer. - */ - static final int LAYER_OFFSET_BLUR = 2; - /** * FocusedStackFrame layer is immediately above focused window. */ @@ -266,27 +261,12 @@ public class WindowManagerService extends IWindowManager.Stub * the thumbnail (or in other words as far as possible above the window * below it). */ - static final int LAYER_OFFSET_THUMBNAIL = WINDOW_LAYER_MULTIPLIER-1; - - /** - * Layer at which to put the rotation freeze snapshot. - */ - static final int FREEZE_LAYER = (TYPE_LAYER_MULTIPLIER * 200) + 1; - - /** - * Layer at which to put the mask for emulated screen sizes. - */ - static final int MASK_LAYER = TYPE_LAYER_MULTIPLIER * 200; + static final int LAYER_OFFSET_THUMBNAIL = WINDOW_LAYER_MULTIPLIER - 1; /** The maximum length we will accept for a loaded animation duration: * this is 10 seconds. */ - static final int MAX_ANIMATION_DURATION = 10*1000; - - /** Amount of time (in milliseconds) to animate the fade-in-out transition for - * compatible windows. - */ - static final int DEFAULT_FADE_IN_OUT_DURATION = 400; + static final int MAX_ANIMATION_DURATION = 10 * 1000; /** Amount of time (in milliseconds) to delay before declaring a window freeze timeout. */ static final int WINDOW_FREEZE_TIMEOUT_DURATION = 2000; @@ -381,48 +361,43 @@ public class WindowManagerService extends IWindowManager.Stub /** * All currently active sessions with clients. */ - final ArraySet mSessions = new ArraySet(); + final ArraySet mSessions = new ArraySet<>(); /** * Mapping from an IWindow IBinder to the server's Window object. * This is also used as the lock for all of our state. * NOTE: Never call into methods that lock ActivityManagerService while holding this object. */ - final HashMap mWindowMap = new HashMap(); + final HashMap mWindowMap = new HashMap<>(); /** * Mapping from a token IBinder to a WindowToken object. */ - final HashMap mTokenMap = new HashMap(); + final HashMap mTokenMap = new HashMap<>(); /** * List of window tokens that have finished starting their application, * and now need to have the policy remove their windows. */ - final ArrayList mFinishedStarting = new ArrayList(); + final ArrayList mFinishedStarting = new ArrayList<>(); /** * Fake windows added to the window manager. Note: ordered from top to * bottom, opposite of mWindows. */ - final ArrayList mFakeWindows = new ArrayList(); + final ArrayList mFakeWindows = new ArrayList<>(); /** * Windows that are being resized. Used so we can tell the client about * the resize after closing the transaction in which we resized the * underlying surface. */ - final ArrayList mResizingWindows = new ArrayList(); + final ArrayList mResizingWindows = new ArrayList<>(); /** * Windows whose animations have ended and now must be removed. */ - final ArrayList mPendingRemove = new ArrayList(); - - /** - * Stacks whose animations have ended and whose tasks, apps, selves may now be removed. - */ - final ArraySet mPendingStacksRemove = new ArraySet(); + final ArrayList mPendingRemove = new ArrayList<>(); /** * Used when processing mPendingRemove to avoid working on the original array. @@ -432,13 +407,13 @@ public class WindowManagerService extends IWindowManager.Stub /** * Windows whose surface should be destroyed. */ - final ArrayList mDestroySurface = new ArrayList(); + final ArrayList mDestroySurface = new ArrayList<>(); /** * Windows that have lost input focus and are waiting for the new * focus window to be displayed before they are told about this. */ - ArrayList mLosingFocus = new ArrayList(); + ArrayList mLosingFocus = new ArrayList<>(); /** * This is set when we have run out of memory, and will either be an empty @@ -449,7 +424,7 @@ public class WindowManagerService extends IWindowManager.Stub /** * Windows that clients are waiting to have drawn. */ - ArrayList mWaitingForDrawn = new ArrayList(); + ArrayList mWaitingForDrawn = new ArrayList<>(); /** * And the callback to make when they've all been drawn. */ @@ -466,7 +441,7 @@ public class WindowManagerService extends IWindowManager.Stub * This array is essentially a cache for all userId for * {@link android.app.admin.DevicePolicyManager#getScreenCaptureDisabled} */ - SparseArray mScreenCaptureDisabled = new SparseArray(); + SparseArray mScreenCaptureDisabled = new SparseArray<>(); IInputMethodManager mInputMethodManager; @@ -840,8 +815,7 @@ public class WindowManagerService extends IWindowManager.Stub boolean mInTouchMode; private ViewServer mViewServer; - private final ArrayList mWindowChangeListeners = - new ArrayList(); + private final ArrayList mWindowChangeListeners = new ArrayList<>(); private boolean mWindowsChanged = false; public interface WindowChangeListener { @@ -859,6 +833,10 @@ public class WindowManagerService extends IWindowManager.Stub // For example, when this flag is true, there will be no wallpaper service. final boolean mOnlyCore; + // List of clients without a transtiton animation that we notify once we are done transitioning + // since they won't be notified through the app window animator. + private final List mNoAnimationNotifyOnTransitionFinished = new ArrayList<>(); + /** Listener to notify activity manager about app transitions. */ private final WindowManagerInternal.AppTransitionListener mActivityManagerAppTransitionNotifier = new WindowManagerInternal.AppTransitionListener() { @@ -9222,6 +9200,7 @@ public class WindowManagerService extends IWindowManager.Stub transit = AppTransition.TRANSIT_UNSET; } mSkipAppTransitionAnimation = false; + mNoAnimationNotifyOnTransitionFinished.clear(); mH.removeMessages(H.APP_TRANSITION_TIMEOUT); @@ -9391,7 +9370,13 @@ public class WindowManagerService extends IWindowManager.Stub appAnimator.animation = null; } wtoken.inPendingTransaction = false; - setTokenVisibilityLocked(wtoken, animLp, true, transit, false, voiceInteraction); + if (!setTokenVisibilityLocked( + wtoken, animLp, true, transit, false, voiceInteraction)){ + // This token isn't going to be animating. Add it to the list of tokens to + // be notified of app transition complete since the notification will not be + // sent be the app window animator. + mNoAnimationNotifyOnTransitionFinished.add(wtoken.token); + } wtoken.updateReportedVisibilityLocked(); wtoken.waitingToShow = false; @@ -9558,6 +9543,12 @@ public class WindowManagerService extends IWindowManager.Stub mAppTransition.setIdle(); + for (int i = mNoAnimationNotifyOnTransitionFinished.size() - 1; i >= 0; i--) { + final IBinder token = mNoAnimationNotifyOnTransitionFinished.get(i); + mAppTransition.notifyAppTransitionFinishedLocked(token); + } + mNoAnimationNotifyOnTransitionFinished.clear(); + if (mDeferredHideWallpaper != null) { hideWallpapersLocked(mDeferredHideWallpaper); mDeferredHideWallpaper = null;