diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java index 785f1660bb067..27328216b45e1 100644 --- a/services/core/java/com/android/server/wm/AppWindowToken.java +++ b/services/core/java/com/android/server/wm/AppWindowToken.java @@ -302,6 +302,13 @@ class AppWindowToken extends WindowToken { } } + void markSurfacesExiting() { + for (int i = allAppWindows.size() - 1; i >= 0; i--) { + WindowState win = allAppWindows.get(i); + win.mExiting = true; + } + } + /** * Checks whether we should save surfaces for this app. * @@ -329,15 +336,14 @@ class AppWindowToken extends WindowToken { if (!hasSavedSurface()) { return; } - - if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG_WM, - "Restoring saved surfaces: " + this + ", allDrawn=" + allDrawn); - mAnimatingWithSavedSurface = true; for (int i = windows.size() - 1; i >= 0; i--) { WindowState ws = windows.get(i); ws.restoreSavedSurface(); } + // Mark the app allDrawn since it must be allDrawn at the time + // it was first saved. + allDrawn = true; } void destroySavedSurfaces() { diff --git a/services/core/java/com/android/server/wm/WindowAnimator.java b/services/core/java/com/android/server/wm/WindowAnimator.java index 62d4f3611a74b..722c3b4d35b67 100644 --- a/services/core/java/com/android/server/wm/WindowAnimator.java +++ b/services/core/java/com/android/server/wm/WindowAnimator.java @@ -281,8 +281,7 @@ public class WindowAnimator { final int flags = win.mAttrs.flags; boolean canBeForceHidden = mPolicy.canBeForceHidden(win, win.mAttrs); boolean shouldBeForceHidden = shouldForceHide(win); - if (winAnimator.mSurfaceController != null - && winAnimator.mSurfaceController.hasSurface()) { + if (winAnimator.hasSurface()) { final boolean wasAnimating = winAnimator.mWasAnimating; final boolean nowAnimating = winAnimator.stepAnimationLocked(mCurrentTime); winAnimator.mWasAnimating = nowAnimating; diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 4b0015e603751..d2e2639b04cc0 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -2679,20 +2679,11 @@ public class WindowManagerService extends IWindowManager.Stub } else { winAnimator.mEnterAnimationPending = false; winAnimator.mEnteringAnimation = false; - if (winAnimator.mSurfaceController != null && - winAnimator.mSurfaceController.hasSurface()) { + if (winAnimator.hasSurface() && !win.mExiting) { if (DEBUG_VISIBILITY) Slog.i(TAG_WM, "Relayout invis " + win + ": mExiting=" + win.mExiting); - // If we are using a saved surface to do enter animation, just let the - // animation run and don't destroy the surface. This could happen when - // the app sets visibility to invisible for the first time after resume, - // or when the user exits immediately after a resume. In both cases, we - // don't want to destroy the saved surface. // If we are not currently running the exit animation, we // need to see about starting one. - final boolean notExitingOrAnimating = - !win.mExiting && !win.isAnimatingWithSavedSurface(); - result |= notExitingOrAnimating ? RELAYOUT_RES_SURFACE_CHANGED : 0; // We don't want to animate visibility of windows which are pending // replacement. In the case of activity relaunch child windows // could request visibility changes as they are detached from the main @@ -2700,11 +2691,11 @@ public class WindowManagerService extends IWindowManager.Stub // these visibility changes though, we would cause a visual glitch // hiding the window before it's replacement was available. // So we just do nothing on our side. - if (notExitingOrAnimating && win.mWillReplaceWindow == false) { - focusMayChange = tryStartingAnimation(win, winAnimator, isDefaultDisplay, - focusMayChange); - + if (!win.mWillReplaceWindow) { + focusMayChange = tryStartExitingAnimation( + win, winAnimator, isDefaultDisplay, focusMayChange); } + result |= RELAYOUT_RES_SURFACE_CHANGED; } outSurface.release(); @@ -2787,7 +2778,7 @@ public class WindowManagerService extends IWindowManager.Stub return result; } - private boolean tryStartingAnimation(WindowState win, WindowStateAnimator winAnimator, + private boolean tryStartExitingAnimation(WindowState win, WindowStateAnimator winAnimator, boolean isDefaultDisplay, boolean focusMayChange) { // Try starting an animation; if there isn't one, we // can destroy the surface right away. @@ -4240,6 +4231,7 @@ public class WindowManagerService extends IWindowManager.Stub } } } else { + wtoken.markSurfacesExiting(); mClosingApps.add(wtoken); wtoken.mEnteringAnimation = false; } @@ -10278,10 +10270,6 @@ public class WindowManagerService extends IWindowManager.Stub return (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dip, displayMetrics); } - void scheduleSurfaceDestroy(WindowState win) { - mDestroySurface.add(win); - } - @Override public void registerDockedStackListener(IDockedStackListener listener) { if (!checkCallingPermission(android.Manifest.permission.REGISTER_WINDOW_MANAGER_LISTENERS, diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index e8a02b0c4e0d9..dca7735f02fc7 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -1768,45 +1768,69 @@ final class WindowState implements WindowManagerPolicy.WindowState { return mAppToken != null && mAppToken.mAnimatingWithSavedSurface; } - // Returns true if the surface is saved. - boolean destroyOrSaveSurface() { - Task task = getTask(); + private boolean shouldSaveSurface() { if (ActivityManager.isLowRamDeviceStatic()) { // Don't save surfaces on Svelte devices. - mSurfaceSaved = false; - } else if (task == null || task.inHomeStack() - || task.getTopVisibleAppToken() != mAppToken) { + return false; + } + + if (isChildWindow()) { + return false; + } + + Task task = getTask(); + if (task == null || task.inHomeStack()) { // Don't save surfaces for home stack apps. These usually resume and draw // first frame very fast. Saving surfaces are mostly a waste of memory. - // Don't save if the window is not the topmost window. - mSurfaceSaved = false; - } else if (isChildWindow()) { - mSurfaceSaved = false; - } else { - mSurfaceSaved = mAppToken.shouldSaveSurface(); + return false; } - if (mSurfaceSaved == false) { + + final AppWindowToken taskTop = task.getTopVisibleAppToken(); + if (taskTop != null && taskTop != mAppToken) { + // Don't save if the window is not the topmost window. + return false; + } + + return mAppToken.shouldSaveSurface(); + } + + void destroyOrSaveSurface() { + mSurfaceSaved = shouldSaveSurface(); + if (mSurfaceSaved) { + if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) { + Slog.v(TAG, "Saving surface: " + this); + } + + mWinAnimator.hide("saved surface"); + mWinAnimator.mDrawState = WindowStateAnimator.NO_SURFACE; + setHasSurface(false); + } else { mWinAnimator.destroySurfaceLocked(); } - return mSurfaceSaved; } public void destroySavedSurface() { - if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG, "Destroying saved surface: " + this); if (mSurfaceSaved) { + if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) { + Slog.v(TAG, "Destroying saved surface: " + this); + } mWinAnimator.destroySurfaceLocked(); } } + public void restoreSavedSurface() { + mSurfaceSaved = false; + setHasSurface(true); + mWinAnimator.mDrawState = WindowStateAnimator.READY_TO_SHOW; + if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) { + Slog.v(TAG, "Restoring saved surface: " + this); + } + } + public boolean hasSavedSurface() { return mSurfaceSaved; } - public void restoreSavedSurface() { - mSurfaceSaved = false; - mWinAnimator.mDrawState = WindowStateAnimator.READY_TO_SHOW; - } - @Override public boolean isDefaultDisplay() { final DisplayContent displayContent = getDisplayContent(); diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java index da4e1913f2628..cffcc5db36ffe 100644 --- a/services/core/java/com/android/server/wm/WindowStateAnimator.java +++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java @@ -468,7 +468,7 @@ class WindowStateAnimator { if (WindowManagerService.localLOGV) Slog.v( TAG, "Exit animation finished in " + this + ": remove=" + mWin.mRemoveOnExit); - if (mSurfaceController != null && mSurfaceController.hasSurface()) { + if (hasSurface()) { mService.mDestroySurface.add(mWin); mWin.mDestroying = true; hide("finishExit"); @@ -734,6 +734,11 @@ class WindowStateAnimator { mTmpSize.bottom += scale * (attrs.surfaceInsets.top + attrs.surfaceInsets.bottom); } + boolean hasSurface() { + return !mWin.mSurfaceSaved + && mSurfaceController != null && mSurfaceController.hasSurface(); + } + void destroySurfaceLocked() { final AppWindowToken wtoken = mWin.mAppToken; if (wtoken != null) { @@ -1229,7 +1234,7 @@ class WindowStateAnimator { void prepareSurfaceLocked(final boolean recoveringMemory) { final WindowState w = mWin; - if (mSurfaceController == null || !mSurfaceController.hasSurface()) { + if (!hasSurface()) { if (w.mOrientationChanging) { if (DEBUG_ORIENTATION) { Slog.v(TAG, "Orientation change skips hidden " + w); @@ -1311,7 +1316,7 @@ class WindowStateAnimator { w.mOrientationChanging = false; } } - if (mSurfaceController != null && mSurfaceController.hasSurface()) { + if (hasSurface()) { w.mToken.hasVisible = true; } } else { diff --git a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java index ab6667a2f3839..9012b981cd1a4 100644 --- a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java +++ b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java @@ -1161,6 +1161,9 @@ class WindowSurfacePlacer { appAnimator.animation = null; } wtoken.inPendingTransaction = false; + + wtoken.restoreSavedSurfaces(); + if (!mService.setTokenVisibilityLocked( wtoken, animLp, true, transit, false, voiceInteraction)){ // This token isn't going to be animating. Add it to the list of tokens to @@ -1217,8 +1220,6 @@ class WindowSurfacePlacer { if (mService.mAppTransition.isNextAppTransitionThumbnailUp()) { createThumbnailAppAnimator(transit, wtoken, topOpeningLayer, topClosingLayer); } - - wtoken.restoreSavedSurfaces(); } return topOpeningApp; }