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