Loading services/core/java/com/android/server/wm/AppWindowToken.java +6 −6 Original line number Diff line number Diff line Loading @@ -254,7 +254,7 @@ class AppWindowToken extends WindowToken { // In cases where there are multiple windows, we prefer the non-exiting window. This // happens for example when replacing windows during an activity relaunch. When // constructing the animation, we want the new window, not the exiting one. if (win.mExiting) { if (win.mAnimatingExit) { candidate = win; } else { return win; Loading Loading @@ -307,11 +307,11 @@ class AppWindowToken extends WindowToken { // If the app already requested to remove its window, we don't modify // its exiting state. Otherwise the stale window won't get removed on // exit and could cause focus to be given to the wrong window. if (!(win.mRemoveOnExit && win.mExiting)) { win.mExiting = exiting; if (!(win.mRemoveOnExit && win.mAnimatingExit)) { win.mAnimatingExit = exiting; } // If we're no longer exiting, remove the window from destroying list if (!win.mExiting && win.mDestroying) { if (!win.mAnimatingExit && win.mDestroying) { win.mDestroying = false; service.mDestroySurface.remove(win); } Loading @@ -330,13 +330,13 @@ class AppWindowToken extends WindowToken { continue; } if (!mAppStopped && !win.mClientRemoveRequested) { if (!(mAppStopped || win.mWindowRemovalAllowed)) { continue; } win.destroyOrSaveSurface(); if (win.mRemoveOnExit) { win.mExiting = false; win.mAnimatingExit = false; service.removeWindowInnerLocked(win); } final DisplayContent displayContent = win.getDisplayContent(); Loading services/core/java/com/android/server/wm/TaskStack.java +1 −1 Original line number Diff line number Diff line Loading @@ -383,7 +383,7 @@ public class TaskStack implements DimLayer.DimLayerUser, final ArrayList<WindowState> windows = activities.get(activityNdx).allAppWindows; for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) { final WindowStateAnimator winAnimator = windows.get(winNdx).mWinAnimator; if (winAnimator.isAnimating() || winAnimator.mWin.mExiting) { if (winAnimator.isAnimating() || winAnimator.mWin.mAnimatingExit) { return true; } } Loading services/core/java/com/android/server/wm/WindowManagerService.java +54 −49 Original line number Diff line number Diff line Loading @@ -192,6 +192,8 @@ import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER; import static android.view.WindowManagerGlobal.RELAYOUT_DEFER_SURFACE_DESTROY; import static android.view.WindowManagerGlobal.RELAYOUT_RES_SURFACE_CHANGED; import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER; import static android.view.WindowManagerPolicy.TRANSIT_EXIT; import static android.view.WindowManagerPolicy.TRANSIT_PREVIEW_DONE; import static com.android.server.wm.AppWindowAnimator.PROLONG_ANIMATION_AT_END; import static com.android.server.wm.AppWindowAnimator.PROLONG_ANIMATION_AT_START; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG; Loading Loading @@ -1354,7 +1356,7 @@ public class WindowManagerService extends IWindowManager.Stub + " policyVis=" + w.mPolicyVisibility + " policyVisAfterAnim=" + w.mPolicyVisibilityAfterAnim + " attachHid=" + w.mAttachedHidden + " exiting=" + w.mExiting + " destroying=" + w.mDestroying); + " exiting=" + w.mAnimatingExit + " destroying=" + w.mDestroying); if (w.mAppToken != null) { Slog.i(TAG_WM, " mAppToken.hiddenRequested=" + w.mAppToken.hiddenRequested); } Loading Loading @@ -2057,7 +2059,7 @@ public class WindowManagerService extends IWindowManager.Stub WindowState replacedWindow = null; for (int i = atoken.windows.size() - 1; i >= 0 && replacedWindow == null; i--) { WindowState candidate = atoken.windows.get(i); if (candidate.mExiting && candidate.mWillReplaceWindow if (candidate.mAnimatingExit && candidate.mWillReplaceWindow && candidate.mAnimateReplacingWindow) { replacedWindow = candidate; } Loading Loading @@ -2131,19 +2133,12 @@ public class WindowManagerService extends IWindowManager.Stub if (win == null) { return; } // We set this here instead of removeWindowLocked because we only want it to be // true when the client has requested we remove the window. In other remove // cases, we have to wait for activity stop to safely remove the window (as the // client may still be using the surface). In this case though, the client has // just dismissed a window (for example a Dialog) and activity stop isn't // necessarily imminent, so we need to know not to wait for it after our // hanimation (if applicable) finishes. win.mClientRemoveRequested = true; removeWindowLocked(win); } } void removeWindowLocked(WindowState win) { win.mWindowRemovalAllowed = true; final boolean startingWindow = win.mAttrs.type == TYPE_APPLICATION_STARTING; if (startingWindow) { if (DEBUG_STARTING_WINDOW) Slog.d(TAG_WM, "Starting window removed " + win); Loading @@ -2159,23 +2154,25 @@ public class WindowManagerService extends IWindowManager.Stub win.disposeInputChannel(); if (DEBUG_APP_TRANSITIONS) Slog.v( TAG_WM, "Remove " + win + ": mSurfaceController=" + win.mWinAnimator.mSurfaceController + " mExiting=" + win.mExiting if (DEBUG_APP_TRANSITIONS) Slog.v(TAG_WM, "Remove " + win + ": mSurfaceController=" + win.mWinAnimator.mSurfaceController + " mAnimatingExit=" + win.mAnimatingExit + " mRemoveOnExit=" + win.mRemoveOnExit + " mHasSurface=" + win.mHasSurface + " surfaceShowing=" + win.mWinAnimator.getShown() + " isAnimating=" + win.mWinAnimator.isAnimating() + " app-animation=" + (win.mAppToken != null ? win.mAppToken.mAppAnimator.animation : null) + " mWillReplaceWindow=" + win.mWillReplaceWindow + " mWillReplaceWindow=" + win.mWillReplaceWindow + " inPendingTransaction=" + (win.mAppToken != null ? win.mAppToken.inPendingTransaction : false) + " mDisplayFrozen=" + mDisplayFrozen); + " mDisplayFrozen=" + mDisplayFrozen + " callers=" + Debug.getCallers(6)); // Visibility of the removed window. Will be used later to update orientation later on. boolean wasVisible = false; // First, see if we need to run an animation. If we do, we have // 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. // First, see if we need to run an animation. If we do, we have 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.mHasSurface && okToDisplay()) { final AppWindowToken appToken = win.mAppToken; if (win.mWillReplaceWindow) { Loading @@ -2183,13 +2180,16 @@ public class WindowManagerService extends IWindowManager.Stub // gets added, then we will get rid of this one. if (DEBUG_ADD_REMOVE) Slog.v(TAG_WM, "Preserving " + win + " until the new one is " + "added"); win.mExiting = true; // TODO: We are overloading mAnimatingExit flag to prevent the window state from // been removed. We probably need another falg to indicate that window removal // should be deffered vs. overloading the flag that says we are playing an exit // animation. win.mAnimatingExit = true; win.mReplacingRemoveRequested = true; Binder.restoreCallingIdentity(origId); return; } // If we are not currently running the exit animation, we // need to see about starting one. // If we are not currently running the exit animation, we need to see about starting one wasVisible = win.isWinVisibleLw(); if (win.shouldKeepVisibleDeadAppWindow()) { Loading @@ -2209,14 +2209,13 @@ public class WindowManagerService extends IWindowManager.Stub return; } final WindowStateAnimator winAnimator = win.mWinAnimator; if (wasVisible) { final int transit = (!startingWindow) ? WindowManagerPolicy.TRANSIT_EXIT : WindowManagerPolicy.TRANSIT_PREVIEW_DONE; final int transit = (!startingWindow) ? TRANSIT_EXIT : TRANSIT_PREVIEW_DONE; // Try starting an animation. if (win.mWinAnimator.applyAnimationLocked(transit, false)) { win.mExiting = true; if (winAnimator.applyAnimationLocked(transit, false)) { win.mAnimatingExit = true; } //TODO (multidisplay): Magnification is supported only for the default display. if (mAccessibilityController != null Loading @@ -2224,15 +2223,20 @@ public class WindowManagerService extends IWindowManager.Stub mAccessibilityController.onWindowTransitionLocked(win, transit); } } final boolean isAnimating = win.mWinAnimator.isAnimating() && !win.mWinAnimator.isDummyAnimation(); // The starting window is the last window in this app token and it isn't animating. // Allow it to be removed now as there is no additional window or animation that will // trigger its removal. final boolean lastWinStartingNotAnimating = startingWindow && appToken!= null && appToken.allAppWindows.size() == 1 && !isAnimating; if (!lastWinStartingNotAnimating && win.mExiting) { // The exit animation is running... wait for it! final boolean isAnimating = winAnimator.isAnimating() && !winAnimator.isDummyAnimation(); final boolean lastWindowIsStartingWindow = startingWindow && appToken != null && appToken.allAppWindows.size() == 1; // We delay the removal of a window if it has a showing surface that can be used to run // exit animation and it is marked as exiting. // Also, If isn't the an animating starting window that is the last window in the app. // We allow the removal of the non-animating starting window now as there is no // additional window or animation that will trigger its removal. if (winAnimator.getShown() && win.mAnimatingExit && (!lastWindowIsStartingWindow || isAnimating)) { // The exit animation is running or should run... wait for it! if (DEBUG_ADD_REMOVE) Slog.v(TAG_WM, "Not removing " + win + " due to exit animation "); win.mRemoveOnExit = true; win.setDisplayLayoutNeeded(); final boolean focusChanged = updateFocusedWindowLocked( Loading Loading @@ -2262,13 +2266,14 @@ public class WindowManagerService extends IWindowManager.Stub void removeWindowInnerLocked(WindowState win) { if (win.mRemoved) { // Nothing to do. if (DEBUG_ADD_REMOVE) Slog.v(TAG_WM, "removeWindowInnerLocked: " + win + " Already removed..."); return; } for (int i = win.mChildWindows.size() - 1; i >= 0; i--) { WindowState cwin = win.mChildWindows.get(i); Slog.w(TAG_WM, "Force-removing child win " + cwin + " from container " + win); Slog.w(TAG_WM, "Force-removing child win " + cwin + " from container " + win); removeWindowInnerLocked(cwin); } Loading Loading @@ -2681,16 +2686,16 @@ public class WindowManagerService extends IWindowManager.Stub final boolean usingSavedSurfaceBeforeVisible = oldVisibility != View.VISIBLE && win.isAnimatingWithSavedSurface(); if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) { if (winAnimator.hasSurface() && !win.mExiting if (winAnimator.hasSurface() && !win.mAnimatingExit && usingSavedSurfaceBeforeVisible) { Slog.d(TAG, "Ignoring layout to invisible when using saved surface " + win); } } if (winAnimator.hasSurface() && !win.mExiting if (winAnimator.hasSurface() && !win.mAnimatingExit && !usingSavedSurfaceBeforeVisible) { if (DEBUG_VISIBILITY) Slog.i(TAG_WM, "Relayout invis " + win + ": mExiting=" + win.mExiting); + ": mAnimatingExit=" + win.mAnimatingExit); // If we are not currently running the exit animation, we // need to see about starting one. // We don't want to animate visibility of windows which are pending Loading Loading @@ -2797,16 +2802,16 @@ public class WindowManagerService extends IWindowManager.Stub } if (win.isWinVisibleLw() && winAnimator.applyAnimationLocked(transit, false)) { focusMayChange = isDefaultDisplay; win.mExiting = true; win.mAnimatingExit = true; } else if (win.mWinAnimator.isAnimating()) { // Currently in a hide animation... turn this into // an exit. win.mExiting = true; win.mAnimatingExit = true; } else if (mWallpaperControllerLocked.isWallpaperTarget(win)) { // If the wallpaper is currently behind this // window, we need to change both of them inside // of a transaction to avoid artifacts. win.mExiting = true; win.mAnimatingExit = true; win.mWinAnimator.mAnimating = true; } else { if (mInputMethodWindow == win) { Loading Loading @@ -2842,12 +2847,12 @@ public class WindowManagerService extends IWindowManager.Stub private int relayoutVisibleWindow(Configuration outConfig, int result, WindowState win, WindowStateAnimator winAnimator, int attrChanges, int oldVisibility) { result |= !win.isVisibleLw() ? WindowManagerGlobal.RELAYOUT_RES_FIRST_TIME : 0; if (win.mExiting) { Slog.d(TAG, "relayoutVisibleWindow: " + win + " mExiting=true, mRemoveOnExit=" if (win.mAnimatingExit) { Slog.d(TAG, "relayoutVisibleWindow: " + win + " mAnimatingExit=true, mRemoveOnExit=" + win.mRemoveOnExit + ", mDestroying=" + win.mDestroying); winAnimator.cancelExitAnimationForNextAnimationLocked(); win.mExiting = false; win.mAnimatingExit = false; } if (win.mDestroying) { win.mDestroying = false; Loading services/core/java/com/android/server/wm/WindowState.java +20 −20 Original line number Diff line number Diff line Loading @@ -358,7 +358,7 @@ final class WindowState implements WindowManagerPolicy.WindowState { boolean mLayoutNeeded; /** Currently running an exit animation? */ boolean mExiting; boolean mAnimatingExit; /** Currently on the mDestroySurface list? */ boolean mDestroying; Loading Loading @@ -387,11 +387,11 @@ final class WindowState implements WindowManagerPolicy.WindowState { boolean mRemoved; /** * Has the client requested we remove the window? In this case we know * that we can dispose of it when we wish without further synchronization * with the client * It is save to remove the window and destroy the surface because the client requested removal * or some other higher level component said so (e.g. activity manager). * TODO: We should either have different booleans for the removal reason or use a bit-field. */ boolean mClientRemoveRequested; boolean mWindowRemovalAllowed; /** * Temp for keeping track of windows that have been removed when Loading Loading @@ -614,7 +614,7 @@ final class WindowState implements WindowManagerPolicy.WindowState { @Override public void computeFrameLw(Rect pf, Rect df, Rect of, Rect cf, Rect vf, Rect dcf, Rect sf, Rect osf) { if (mWillReplaceWindow && (mExiting || !mReplacingRemoveRequested)) { if (mWillReplaceWindow && (mAnimatingExit || !mReplacingRemoveRequested)) { // This window is being replaced and either already got information that it's being // removed or we are still waiting for some information. Because of this we don't // want to apply any more changes to it, so it remains in this state until new window Loading Loading @@ -1075,7 +1075,7 @@ final class WindowState implements WindowManagerPolicy.WindowState { */ private boolean isVisibleUnchecked() { return mHasSurface && mPolicyVisibility && !mAttachedHidden && !mExiting && !mDestroying && (!mIsWallpaper || mWallpaperVisible); && !mAnimatingExit && !mDestroying && (!mIsWallpaper || mWallpaperVisible); } /** Loading @@ -1100,7 +1100,7 @@ final class WindowState implements WindowManagerPolicy.WindowState { } final AppWindowToken atoken = mAppToken; final boolean animating = atoken != null && atoken.mAppAnimator.animation != null; return mHasSurface && !mDestroying && !mExiting return mHasSurface && !mDestroying && !mAnimatingExit && (atoken == null ? mPolicyVisibility : !atoken.hiddenRequested) && ((!mAttachedHidden && mViewVisibility == View.VISIBLE && !mRootToken.hidden) || mWinAnimator.mAnimation != null || animating); Loading Loading @@ -1143,7 +1143,7 @@ final class WindowState implements WindowManagerPolicy.WindowState { return (mHasSurface || (!mRelayoutCalled && mViewVisibility == View.VISIBLE)) && mPolicyVisibility && !mAttachedHidden && (atoken == null || !atoken.hiddenRequested) && !mExiting && !mDestroying; && !mAnimatingExit && !mDestroying; } /** Loading Loading @@ -1237,7 +1237,7 @@ final class WindowState implements WindowManagerPolicy.WindowState { || (atoken == null && mRootToken.hidden) || (atoken != null && (atoken.hiddenRequested || atoken.hidden)) || mAttachedHidden || (mExiting && !isAnimatingLw()) || (mAnimatingExit && !isAnimatingLw()) || mDestroying; } Loading Loading @@ -1283,7 +1283,7 @@ final class WindowState implements WindowManagerPolicy.WindowState { */ boolean hasMoved() { return mHasSurface && (mContentChanged || mMovedByResize) && !mExiting && !mWinAnimator.mLastHidden && mService.okToDisplay() && !mAnimatingExit && !mWinAnimator.mLastHidden && mService.okToDisplay() && (mFrame.top != mLastFrame.top || mFrame.left != mLastFrame.left) && (mAttachedWindow == null || !mAttachedWindow.hasMoved()); } Loading Loading @@ -1438,11 +1438,11 @@ final class WindowState implements WindowManagerPolicy.WindowState { return; } if (!mExiting && mAppDied) { if (!mAnimatingExit && mAppDied) { // If app died visible, apply a dim over the window to indicate that it's inactive mDisplayContent.mDimLayerController.applyDimAbove(getDimLayerUser(), mWinAnimator); } else if ((mAttrs.flags & FLAG_DIM_BEHIND) != 0 && mDisplayContent != null && !mExiting && isDisplayedLw()) { && mDisplayContent != null && !mAnimatingExit && isDisplayedLw()) { mDisplayContent.mDimLayerController.applyDimBehind(getDimLayerUser(), mWinAnimator); } } Loading @@ -1467,7 +1467,7 @@ final class WindowState implements WindowManagerPolicy.WindowState { win.mAnimateReplacingWindow = false; win.mReplacingRemoveRequested = false; win.mReplacingWindow = null; if (win.mExiting) { if (win.mAnimatingExit) { mService.removeWindowInnerLocked(win); } } Loading Loading @@ -1810,7 +1810,7 @@ final class WindowState implements WindowManagerPolicy.WindowState { } boolean isClosing() { return mExiting || (mService.mClosingApps.contains(mAppToken)); return mAnimatingExit || (mService.mClosingApps.contains(mAppToken)); } boolean isAnimatingWithSavedSurface() { Loading Loading @@ -2341,8 +2341,8 @@ final class WindowState implements WindowManagerPolicy.WindowState { } pw.print(prefix); pw.print(mWinAnimator); pw.println(":"); mWinAnimator.dump(pw, prefix + " ", dumpAll); if (mExiting || mRemoveOnExit || mDestroying || mRemoved) { pw.print(prefix); pw.print("mExiting="); pw.print(mExiting); if (mAnimatingExit || mRemoveOnExit || mDestroying || mRemoved) { pw.print(prefix); pw.print("mAnimatingExit="); pw.print(mAnimatingExit); pw.print(" mRemoveOnExit="); pw.print(mRemoveOnExit); pw.print(" mDestroying="); pw.print(mDestroying); pw.print(" mRemoved="); pw.println(mRemoved); Loading Loading @@ -2403,12 +2403,12 @@ final class WindowState implements WindowManagerPolicy.WindowState { @Override public String toString() { final CharSequence title = getWindowTag(); if (mStringNameCache == null || mLastTitle != title || mWasExiting != mExiting) { if (mStringNameCache == null || mLastTitle != title || mWasExiting != mAnimatingExit) { mLastTitle = title; mWasExiting = mExiting; mWasExiting = mAnimatingExit; mStringNameCache = "Window{" + Integer.toHexString(System.identityHashCode(this)) + " u" + UserHandle.getUserId(mSession.mUid) + " " + mLastTitle + (mExiting ? " EXITING}" : "}"); + " " + mLastTitle + (mAnimatingExit ? " EXITING}" : "}"); } return mStringNameCache; } Loading services/core/java/com/android/server/wm/WindowStateAnimator.java +10 −11 Original line number Diff line number Diff line Loading @@ -29,7 +29,6 @@ import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_SURFACE_TRACE import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WALLPAPER; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_CROP; import static com.android.server.wm.WindowManagerDebugConfig.SHOW_STACK_CRAWLS; import static com.android.server.wm.WindowManagerDebugConfig.SHOW_LIGHT_TRANSACTIONS; import static com.android.server.wm.WindowManagerDebugConfig.SHOW_SURFACE_ALLOC; import static com.android.server.wm.WindowManagerDebugConfig.SHOW_TRANSACTIONS; Loading Loading @@ -375,7 +374,7 @@ class WindowStateAnimator { // Done animating, clean up. if (DEBUG_ANIM) Slog.v( TAG, "Animation done in " + this + ": exiting=" + mWin.mExiting TAG, "Animation done in " + this + ": exiting=" + mWin.mAnimatingExit + ", reportedVisible=" + (mWin.mAppToken != null ? mWin.mAppToken.reportedVisible : false)); Loading Loading @@ -430,7 +429,7 @@ class WindowStateAnimator { void finishExit() { if (DEBUG_ANIM) Slog.v( TAG, "finishExit in " + this + ": exiting=" + mWin.mExiting + ": exiting=" + mWin.mAnimatingExit + " remove=" + mWin.mRemoveOnExit + " windowAnimating=" + isWindowAnimating()); Loading Loading @@ -460,7 +459,7 @@ class WindowStateAnimator { } } if (!mWin.mExiting) { if (!mWin.mAnimatingExit) { return; } Loading @@ -475,27 +474,27 @@ class WindowStateAnimator { mWin.mDestroying = true; final boolean hasSurface = hasSurface(); if (hasSurface) { hide("finishExit"); } // If we have an app token, we ask it to destroy the surface for us, // so that it can take care to ensure the activity has actually stopped // and the surface is not still in use. Otherwise we add the service to // mDestroySurface and allow it to be processed in our next transaction. if (mWin.mAppToken != null) { if (hasSurface()) { hide("finishExit"); } mWin.mAppToken.destroySurfaces(); } else { if (hasSurface()) { if (hasSurface) { mService.mDestroySurface.add(mWin); hide("finishExit"); } mWin.mExiting = false; if (mWin.mRemoveOnExit) { mService.mPendingRemove.add(mWin); mWin.mRemoveOnExit = false; } } mWin.mAnimatingExit = false; mWallpaperControllerLocked.hideWallpapers(mWin); } Loading Loading
services/core/java/com/android/server/wm/AppWindowToken.java +6 −6 Original line number Diff line number Diff line Loading @@ -254,7 +254,7 @@ class AppWindowToken extends WindowToken { // In cases where there are multiple windows, we prefer the non-exiting window. This // happens for example when replacing windows during an activity relaunch. When // constructing the animation, we want the new window, not the exiting one. if (win.mExiting) { if (win.mAnimatingExit) { candidate = win; } else { return win; Loading Loading @@ -307,11 +307,11 @@ class AppWindowToken extends WindowToken { // If the app already requested to remove its window, we don't modify // its exiting state. Otherwise the stale window won't get removed on // exit and could cause focus to be given to the wrong window. if (!(win.mRemoveOnExit && win.mExiting)) { win.mExiting = exiting; if (!(win.mRemoveOnExit && win.mAnimatingExit)) { win.mAnimatingExit = exiting; } // If we're no longer exiting, remove the window from destroying list if (!win.mExiting && win.mDestroying) { if (!win.mAnimatingExit && win.mDestroying) { win.mDestroying = false; service.mDestroySurface.remove(win); } Loading @@ -330,13 +330,13 @@ class AppWindowToken extends WindowToken { continue; } if (!mAppStopped && !win.mClientRemoveRequested) { if (!(mAppStopped || win.mWindowRemovalAllowed)) { continue; } win.destroyOrSaveSurface(); if (win.mRemoveOnExit) { win.mExiting = false; win.mAnimatingExit = false; service.removeWindowInnerLocked(win); } final DisplayContent displayContent = win.getDisplayContent(); Loading
services/core/java/com/android/server/wm/TaskStack.java +1 −1 Original line number Diff line number Diff line Loading @@ -383,7 +383,7 @@ public class TaskStack implements DimLayer.DimLayerUser, final ArrayList<WindowState> windows = activities.get(activityNdx).allAppWindows; for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) { final WindowStateAnimator winAnimator = windows.get(winNdx).mWinAnimator; if (winAnimator.isAnimating() || winAnimator.mWin.mExiting) { if (winAnimator.isAnimating() || winAnimator.mWin.mAnimatingExit) { return true; } } Loading
services/core/java/com/android/server/wm/WindowManagerService.java +54 −49 Original line number Diff line number Diff line Loading @@ -192,6 +192,8 @@ import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER; import static android.view.WindowManagerGlobal.RELAYOUT_DEFER_SURFACE_DESTROY; import static android.view.WindowManagerGlobal.RELAYOUT_RES_SURFACE_CHANGED; import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER; import static android.view.WindowManagerPolicy.TRANSIT_EXIT; import static android.view.WindowManagerPolicy.TRANSIT_PREVIEW_DONE; import static com.android.server.wm.AppWindowAnimator.PROLONG_ANIMATION_AT_END; import static com.android.server.wm.AppWindowAnimator.PROLONG_ANIMATION_AT_START; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG; Loading Loading @@ -1354,7 +1356,7 @@ public class WindowManagerService extends IWindowManager.Stub + " policyVis=" + w.mPolicyVisibility + " policyVisAfterAnim=" + w.mPolicyVisibilityAfterAnim + " attachHid=" + w.mAttachedHidden + " exiting=" + w.mExiting + " destroying=" + w.mDestroying); + " exiting=" + w.mAnimatingExit + " destroying=" + w.mDestroying); if (w.mAppToken != null) { Slog.i(TAG_WM, " mAppToken.hiddenRequested=" + w.mAppToken.hiddenRequested); } Loading Loading @@ -2057,7 +2059,7 @@ public class WindowManagerService extends IWindowManager.Stub WindowState replacedWindow = null; for (int i = atoken.windows.size() - 1; i >= 0 && replacedWindow == null; i--) { WindowState candidate = atoken.windows.get(i); if (candidate.mExiting && candidate.mWillReplaceWindow if (candidate.mAnimatingExit && candidate.mWillReplaceWindow && candidate.mAnimateReplacingWindow) { replacedWindow = candidate; } Loading Loading @@ -2131,19 +2133,12 @@ public class WindowManagerService extends IWindowManager.Stub if (win == null) { return; } // We set this here instead of removeWindowLocked because we only want it to be // true when the client has requested we remove the window. In other remove // cases, we have to wait for activity stop to safely remove the window (as the // client may still be using the surface). In this case though, the client has // just dismissed a window (for example a Dialog) and activity stop isn't // necessarily imminent, so we need to know not to wait for it after our // hanimation (if applicable) finishes. win.mClientRemoveRequested = true; removeWindowLocked(win); } } void removeWindowLocked(WindowState win) { win.mWindowRemovalAllowed = true; final boolean startingWindow = win.mAttrs.type == TYPE_APPLICATION_STARTING; if (startingWindow) { if (DEBUG_STARTING_WINDOW) Slog.d(TAG_WM, "Starting window removed " + win); Loading @@ -2159,23 +2154,25 @@ public class WindowManagerService extends IWindowManager.Stub win.disposeInputChannel(); if (DEBUG_APP_TRANSITIONS) Slog.v( TAG_WM, "Remove " + win + ": mSurfaceController=" + win.mWinAnimator.mSurfaceController + " mExiting=" + win.mExiting if (DEBUG_APP_TRANSITIONS) Slog.v(TAG_WM, "Remove " + win + ": mSurfaceController=" + win.mWinAnimator.mSurfaceController + " mAnimatingExit=" + win.mAnimatingExit + " mRemoveOnExit=" + win.mRemoveOnExit + " mHasSurface=" + win.mHasSurface + " surfaceShowing=" + win.mWinAnimator.getShown() + " isAnimating=" + win.mWinAnimator.isAnimating() + " app-animation=" + (win.mAppToken != null ? win.mAppToken.mAppAnimator.animation : null) + " mWillReplaceWindow=" + win.mWillReplaceWindow + " mWillReplaceWindow=" + win.mWillReplaceWindow + " inPendingTransaction=" + (win.mAppToken != null ? win.mAppToken.inPendingTransaction : false) + " mDisplayFrozen=" + mDisplayFrozen); + " mDisplayFrozen=" + mDisplayFrozen + " callers=" + Debug.getCallers(6)); // Visibility of the removed window. Will be used later to update orientation later on. boolean wasVisible = false; // First, see if we need to run an animation. If we do, we have // 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. // First, see if we need to run an animation. If we do, we have 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.mHasSurface && okToDisplay()) { final AppWindowToken appToken = win.mAppToken; if (win.mWillReplaceWindow) { Loading @@ -2183,13 +2180,16 @@ public class WindowManagerService extends IWindowManager.Stub // gets added, then we will get rid of this one. if (DEBUG_ADD_REMOVE) Slog.v(TAG_WM, "Preserving " + win + " until the new one is " + "added"); win.mExiting = true; // TODO: We are overloading mAnimatingExit flag to prevent the window state from // been removed. We probably need another falg to indicate that window removal // should be deffered vs. overloading the flag that says we are playing an exit // animation. win.mAnimatingExit = true; win.mReplacingRemoveRequested = true; Binder.restoreCallingIdentity(origId); return; } // If we are not currently running the exit animation, we // need to see about starting one. // If we are not currently running the exit animation, we need to see about starting one wasVisible = win.isWinVisibleLw(); if (win.shouldKeepVisibleDeadAppWindow()) { Loading @@ -2209,14 +2209,13 @@ public class WindowManagerService extends IWindowManager.Stub return; } final WindowStateAnimator winAnimator = win.mWinAnimator; if (wasVisible) { final int transit = (!startingWindow) ? WindowManagerPolicy.TRANSIT_EXIT : WindowManagerPolicy.TRANSIT_PREVIEW_DONE; final int transit = (!startingWindow) ? TRANSIT_EXIT : TRANSIT_PREVIEW_DONE; // Try starting an animation. if (win.mWinAnimator.applyAnimationLocked(transit, false)) { win.mExiting = true; if (winAnimator.applyAnimationLocked(transit, false)) { win.mAnimatingExit = true; } //TODO (multidisplay): Magnification is supported only for the default display. if (mAccessibilityController != null Loading @@ -2224,15 +2223,20 @@ public class WindowManagerService extends IWindowManager.Stub mAccessibilityController.onWindowTransitionLocked(win, transit); } } final boolean isAnimating = win.mWinAnimator.isAnimating() && !win.mWinAnimator.isDummyAnimation(); // The starting window is the last window in this app token and it isn't animating. // Allow it to be removed now as there is no additional window or animation that will // trigger its removal. final boolean lastWinStartingNotAnimating = startingWindow && appToken!= null && appToken.allAppWindows.size() == 1 && !isAnimating; if (!lastWinStartingNotAnimating && win.mExiting) { // The exit animation is running... wait for it! final boolean isAnimating = winAnimator.isAnimating() && !winAnimator.isDummyAnimation(); final boolean lastWindowIsStartingWindow = startingWindow && appToken != null && appToken.allAppWindows.size() == 1; // We delay the removal of a window if it has a showing surface that can be used to run // exit animation and it is marked as exiting. // Also, If isn't the an animating starting window that is the last window in the app. // We allow the removal of the non-animating starting window now as there is no // additional window or animation that will trigger its removal. if (winAnimator.getShown() && win.mAnimatingExit && (!lastWindowIsStartingWindow || isAnimating)) { // The exit animation is running or should run... wait for it! if (DEBUG_ADD_REMOVE) Slog.v(TAG_WM, "Not removing " + win + " due to exit animation "); win.mRemoveOnExit = true; win.setDisplayLayoutNeeded(); final boolean focusChanged = updateFocusedWindowLocked( Loading Loading @@ -2262,13 +2266,14 @@ public class WindowManagerService extends IWindowManager.Stub void removeWindowInnerLocked(WindowState win) { if (win.mRemoved) { // Nothing to do. if (DEBUG_ADD_REMOVE) Slog.v(TAG_WM, "removeWindowInnerLocked: " + win + " Already removed..."); return; } for (int i = win.mChildWindows.size() - 1; i >= 0; i--) { WindowState cwin = win.mChildWindows.get(i); Slog.w(TAG_WM, "Force-removing child win " + cwin + " from container " + win); Slog.w(TAG_WM, "Force-removing child win " + cwin + " from container " + win); removeWindowInnerLocked(cwin); } Loading Loading @@ -2681,16 +2686,16 @@ public class WindowManagerService extends IWindowManager.Stub final boolean usingSavedSurfaceBeforeVisible = oldVisibility != View.VISIBLE && win.isAnimatingWithSavedSurface(); if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) { if (winAnimator.hasSurface() && !win.mExiting if (winAnimator.hasSurface() && !win.mAnimatingExit && usingSavedSurfaceBeforeVisible) { Slog.d(TAG, "Ignoring layout to invisible when using saved surface " + win); } } if (winAnimator.hasSurface() && !win.mExiting if (winAnimator.hasSurface() && !win.mAnimatingExit && !usingSavedSurfaceBeforeVisible) { if (DEBUG_VISIBILITY) Slog.i(TAG_WM, "Relayout invis " + win + ": mExiting=" + win.mExiting); + ": mAnimatingExit=" + win.mAnimatingExit); // If we are not currently running the exit animation, we // need to see about starting one. // We don't want to animate visibility of windows which are pending Loading Loading @@ -2797,16 +2802,16 @@ public class WindowManagerService extends IWindowManager.Stub } if (win.isWinVisibleLw() && winAnimator.applyAnimationLocked(transit, false)) { focusMayChange = isDefaultDisplay; win.mExiting = true; win.mAnimatingExit = true; } else if (win.mWinAnimator.isAnimating()) { // Currently in a hide animation... turn this into // an exit. win.mExiting = true; win.mAnimatingExit = true; } else if (mWallpaperControllerLocked.isWallpaperTarget(win)) { // If the wallpaper is currently behind this // window, we need to change both of them inside // of a transaction to avoid artifacts. win.mExiting = true; win.mAnimatingExit = true; win.mWinAnimator.mAnimating = true; } else { if (mInputMethodWindow == win) { Loading Loading @@ -2842,12 +2847,12 @@ public class WindowManagerService extends IWindowManager.Stub private int relayoutVisibleWindow(Configuration outConfig, int result, WindowState win, WindowStateAnimator winAnimator, int attrChanges, int oldVisibility) { result |= !win.isVisibleLw() ? WindowManagerGlobal.RELAYOUT_RES_FIRST_TIME : 0; if (win.mExiting) { Slog.d(TAG, "relayoutVisibleWindow: " + win + " mExiting=true, mRemoveOnExit=" if (win.mAnimatingExit) { Slog.d(TAG, "relayoutVisibleWindow: " + win + " mAnimatingExit=true, mRemoveOnExit=" + win.mRemoveOnExit + ", mDestroying=" + win.mDestroying); winAnimator.cancelExitAnimationForNextAnimationLocked(); win.mExiting = false; win.mAnimatingExit = false; } if (win.mDestroying) { win.mDestroying = false; Loading
services/core/java/com/android/server/wm/WindowState.java +20 −20 Original line number Diff line number Diff line Loading @@ -358,7 +358,7 @@ final class WindowState implements WindowManagerPolicy.WindowState { boolean mLayoutNeeded; /** Currently running an exit animation? */ boolean mExiting; boolean mAnimatingExit; /** Currently on the mDestroySurface list? */ boolean mDestroying; Loading Loading @@ -387,11 +387,11 @@ final class WindowState implements WindowManagerPolicy.WindowState { boolean mRemoved; /** * Has the client requested we remove the window? In this case we know * that we can dispose of it when we wish without further synchronization * with the client * It is save to remove the window and destroy the surface because the client requested removal * or some other higher level component said so (e.g. activity manager). * TODO: We should either have different booleans for the removal reason or use a bit-field. */ boolean mClientRemoveRequested; boolean mWindowRemovalAllowed; /** * Temp for keeping track of windows that have been removed when Loading Loading @@ -614,7 +614,7 @@ final class WindowState implements WindowManagerPolicy.WindowState { @Override public void computeFrameLw(Rect pf, Rect df, Rect of, Rect cf, Rect vf, Rect dcf, Rect sf, Rect osf) { if (mWillReplaceWindow && (mExiting || !mReplacingRemoveRequested)) { if (mWillReplaceWindow && (mAnimatingExit || !mReplacingRemoveRequested)) { // This window is being replaced and either already got information that it's being // removed or we are still waiting for some information. Because of this we don't // want to apply any more changes to it, so it remains in this state until new window Loading Loading @@ -1075,7 +1075,7 @@ final class WindowState implements WindowManagerPolicy.WindowState { */ private boolean isVisibleUnchecked() { return mHasSurface && mPolicyVisibility && !mAttachedHidden && !mExiting && !mDestroying && (!mIsWallpaper || mWallpaperVisible); && !mAnimatingExit && !mDestroying && (!mIsWallpaper || mWallpaperVisible); } /** Loading @@ -1100,7 +1100,7 @@ final class WindowState implements WindowManagerPolicy.WindowState { } final AppWindowToken atoken = mAppToken; final boolean animating = atoken != null && atoken.mAppAnimator.animation != null; return mHasSurface && !mDestroying && !mExiting return mHasSurface && !mDestroying && !mAnimatingExit && (atoken == null ? mPolicyVisibility : !atoken.hiddenRequested) && ((!mAttachedHidden && mViewVisibility == View.VISIBLE && !mRootToken.hidden) || mWinAnimator.mAnimation != null || animating); Loading Loading @@ -1143,7 +1143,7 @@ final class WindowState implements WindowManagerPolicy.WindowState { return (mHasSurface || (!mRelayoutCalled && mViewVisibility == View.VISIBLE)) && mPolicyVisibility && !mAttachedHidden && (atoken == null || !atoken.hiddenRequested) && !mExiting && !mDestroying; && !mAnimatingExit && !mDestroying; } /** Loading Loading @@ -1237,7 +1237,7 @@ final class WindowState implements WindowManagerPolicy.WindowState { || (atoken == null && mRootToken.hidden) || (atoken != null && (atoken.hiddenRequested || atoken.hidden)) || mAttachedHidden || (mExiting && !isAnimatingLw()) || (mAnimatingExit && !isAnimatingLw()) || mDestroying; } Loading Loading @@ -1283,7 +1283,7 @@ final class WindowState implements WindowManagerPolicy.WindowState { */ boolean hasMoved() { return mHasSurface && (mContentChanged || mMovedByResize) && !mExiting && !mWinAnimator.mLastHidden && mService.okToDisplay() && !mAnimatingExit && !mWinAnimator.mLastHidden && mService.okToDisplay() && (mFrame.top != mLastFrame.top || mFrame.left != mLastFrame.left) && (mAttachedWindow == null || !mAttachedWindow.hasMoved()); } Loading Loading @@ -1438,11 +1438,11 @@ final class WindowState implements WindowManagerPolicy.WindowState { return; } if (!mExiting && mAppDied) { if (!mAnimatingExit && mAppDied) { // If app died visible, apply a dim over the window to indicate that it's inactive mDisplayContent.mDimLayerController.applyDimAbove(getDimLayerUser(), mWinAnimator); } else if ((mAttrs.flags & FLAG_DIM_BEHIND) != 0 && mDisplayContent != null && !mExiting && isDisplayedLw()) { && mDisplayContent != null && !mAnimatingExit && isDisplayedLw()) { mDisplayContent.mDimLayerController.applyDimBehind(getDimLayerUser(), mWinAnimator); } } Loading @@ -1467,7 +1467,7 @@ final class WindowState implements WindowManagerPolicy.WindowState { win.mAnimateReplacingWindow = false; win.mReplacingRemoveRequested = false; win.mReplacingWindow = null; if (win.mExiting) { if (win.mAnimatingExit) { mService.removeWindowInnerLocked(win); } } Loading Loading @@ -1810,7 +1810,7 @@ final class WindowState implements WindowManagerPolicy.WindowState { } boolean isClosing() { return mExiting || (mService.mClosingApps.contains(mAppToken)); return mAnimatingExit || (mService.mClosingApps.contains(mAppToken)); } boolean isAnimatingWithSavedSurface() { Loading Loading @@ -2341,8 +2341,8 @@ final class WindowState implements WindowManagerPolicy.WindowState { } pw.print(prefix); pw.print(mWinAnimator); pw.println(":"); mWinAnimator.dump(pw, prefix + " ", dumpAll); if (mExiting || mRemoveOnExit || mDestroying || mRemoved) { pw.print(prefix); pw.print("mExiting="); pw.print(mExiting); if (mAnimatingExit || mRemoveOnExit || mDestroying || mRemoved) { pw.print(prefix); pw.print("mAnimatingExit="); pw.print(mAnimatingExit); pw.print(" mRemoveOnExit="); pw.print(mRemoveOnExit); pw.print(" mDestroying="); pw.print(mDestroying); pw.print(" mRemoved="); pw.println(mRemoved); Loading Loading @@ -2403,12 +2403,12 @@ final class WindowState implements WindowManagerPolicy.WindowState { @Override public String toString() { final CharSequence title = getWindowTag(); if (mStringNameCache == null || mLastTitle != title || mWasExiting != mExiting) { if (mStringNameCache == null || mLastTitle != title || mWasExiting != mAnimatingExit) { mLastTitle = title; mWasExiting = mExiting; mWasExiting = mAnimatingExit; mStringNameCache = "Window{" + Integer.toHexString(System.identityHashCode(this)) + " u" + UserHandle.getUserId(mSession.mUid) + " " + mLastTitle + (mExiting ? " EXITING}" : "}"); + " " + mLastTitle + (mAnimatingExit ? " EXITING}" : "}"); } return mStringNameCache; } Loading
services/core/java/com/android/server/wm/WindowStateAnimator.java +10 −11 Original line number Diff line number Diff line Loading @@ -29,7 +29,6 @@ import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_SURFACE_TRACE import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WALLPAPER; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_CROP; import static com.android.server.wm.WindowManagerDebugConfig.SHOW_STACK_CRAWLS; import static com.android.server.wm.WindowManagerDebugConfig.SHOW_LIGHT_TRANSACTIONS; import static com.android.server.wm.WindowManagerDebugConfig.SHOW_SURFACE_ALLOC; import static com.android.server.wm.WindowManagerDebugConfig.SHOW_TRANSACTIONS; Loading Loading @@ -375,7 +374,7 @@ class WindowStateAnimator { // Done animating, clean up. if (DEBUG_ANIM) Slog.v( TAG, "Animation done in " + this + ": exiting=" + mWin.mExiting TAG, "Animation done in " + this + ": exiting=" + mWin.mAnimatingExit + ", reportedVisible=" + (mWin.mAppToken != null ? mWin.mAppToken.reportedVisible : false)); Loading Loading @@ -430,7 +429,7 @@ class WindowStateAnimator { void finishExit() { if (DEBUG_ANIM) Slog.v( TAG, "finishExit in " + this + ": exiting=" + mWin.mExiting + ": exiting=" + mWin.mAnimatingExit + " remove=" + mWin.mRemoveOnExit + " windowAnimating=" + isWindowAnimating()); Loading Loading @@ -460,7 +459,7 @@ class WindowStateAnimator { } } if (!mWin.mExiting) { if (!mWin.mAnimatingExit) { return; } Loading @@ -475,27 +474,27 @@ class WindowStateAnimator { mWin.mDestroying = true; final boolean hasSurface = hasSurface(); if (hasSurface) { hide("finishExit"); } // If we have an app token, we ask it to destroy the surface for us, // so that it can take care to ensure the activity has actually stopped // and the surface is not still in use. Otherwise we add the service to // mDestroySurface and allow it to be processed in our next transaction. if (mWin.mAppToken != null) { if (hasSurface()) { hide("finishExit"); } mWin.mAppToken.destroySurfaces(); } else { if (hasSurface()) { if (hasSurface) { mService.mDestroySurface.add(mWin); hide("finishExit"); } mWin.mExiting = false; if (mWin.mRemoveOnExit) { mService.mPendingRemove.add(mWin); mWin.mRemoveOnExit = false; } } mWin.mAnimatingExit = false; mWallpaperControllerLocked.hideWallpapers(mWin); } Loading