diff options
| author | 2016-05-25 17:42:33 +0000 | |
|---|---|---|
| committer | 2016-05-25 17:42:33 +0000 | |
| commit | b56ea680fc3fa650370b539c229986f21d4ed512 (patch) | |
| tree | 8c86bb5a52b036a9a117a1228cb559c62b83a596 | |
| parent | 36cc78418011fa376a05ac44f25511e34ccf200c (diff) | |
| parent | 15818e1156101f1d3a01009e7bc223d8ae88546d (diff) | |
Merge "Destroy saved surfaces if one of the last visible windows gets removed" into nyc-dev
am: 15818e1156
* commit '15818e1156101f1d3a01009e7bc223d8ae88546d':
Destroy saved surfaces if one of the last visible windows gets removed
Change-Id: I143743940263578e7111ae41eb7b88c005be18a6
4 files changed, 36 insertions, 17 deletions
diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java index b773a4e016bd..f57e83aa1e0d 100644 --- a/services/core/java/com/android/server/wm/AppWindowToken.java +++ b/services/core/java/com/android/server/wm/AppWindowToken.java @@ -451,6 +451,16 @@ class AppWindowToken extends WindowToken { destroySurfaces(); } + void markSavedSurfaceExiting() { + for (int i = allAppWindows.size() - 1; i >= 0; i--) { + final WindowState w = allAppWindows.get(i); + if (w.isAnimatingInvisibleWithSavedSurface()) { + w.mAnimatingExit = true; + w.mWinAnimator.mAnimating = true; + } + } + } + void restoreSavedSurfaces() { if (!canRestoreSurfaces()) { clearVisibleBeforeClientHidden(); diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index aaed8ca9181d..d36371219ac0 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -2277,6 +2277,19 @@ public class WindowManagerService extends IWindowManager.Stub } } + private void setupWindowForRemoveOnExit(WindowState win) { + win.mRemoveOnExit = true; + win.setDisplayLayoutNeeded(); + // Request a focus update as this window's input channel is already gone. Otherwise + // we could have no focused window in input manager. + final boolean focusChanged = updateFocusedWindowLocked( + UPDATE_FOCUS_WILL_PLACE_SURFACES, false /*updateInputWindows*/); + mWindowPlacerLocked.performSurfacePlacement(); + if (focusChanged) { + mInputMonitor.updateInputWindowsLw(false /*force*/); + } + } + public void removeWindow(Session session, IWindow client) { synchronized(mWindowMap) { WindowState win = windowForClientLocked(session, client, false); @@ -2358,14 +2371,7 @@ public class WindowManagerService extends IWindowManager.Stub // Do not set mAnimatingExit to true here, it will cause the surface to be hidden // immediately after the enter animation is done. If the app is not yet drawn then // it will show up as a flicker. - win.mRemoveOnExit = true; - // Request a focus update as this window's input channel is already gone. Otherwise - // we could have no focused window in input manager. - final boolean focusChanged = updateFocusedWindowLocked( - UPDATE_FOCUS_WILL_PLACE_SURFACES, false /*updateInputWindows*/); - if (focusChanged) { - mInputMonitor.updateInputWindowsLw(false /*force*/); - } + setupWindowForRemoveOnExit(win); Binder.restoreCallingIdentity(origId); return; } @@ -2417,17 +2423,10 @@ public class WindowManagerService extends IWindowManager.Stub // 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( - UPDATE_FOCUS_WILL_PLACE_SURFACES, false /*updateInputWindows*/); - mWindowPlacerLocked.performSurfacePlacement(); + setupWindowForRemoveOnExit(win); if (appToken != null) { appToken.updateReportedVisibilityLocked(); } - if (focusChanged) { - mInputMonitor.updateInputWindowsLw(false /*force*/); - } Binder.restoreCallingIdentity(origId); return; } diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index c15afb339646..be27c82d61fc 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -2111,7 +2111,9 @@ final class WindowState implements WindowManagerPolicy.WindowState { void clearHasSavedSurface() { mSurfaceSaved = false; mAnimatingWithSavedSurface = false; - mWasVisibleBeforeClientHidden = false; + if (mWasVisibleBeforeClientHidden) { + mAppToken.destroySavedSurfaces(); + } } boolean clearAnimatingWithSavedSurface() { diff --git a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java index 308b24dd8dd6..4148cd07681f 100644 --- a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java +++ b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java @@ -1301,6 +1301,14 @@ class WindowSurfacePlacer { appsCount = mService.mClosingApps.size(); for (int i = 0; i < appsCount; i++) { AppWindowToken wtoken = mService.mClosingApps.valueAt(i); + + // If we still have some windows animating with saved surfaces that's + // either invisible or already removed, mark them exiting so that they + // are disposed of after the exit animation. These are not supposed to + // be shown, or are delayed removal until app is actually drawn (in which + // case the window will be removed after the animation). + wtoken.markSavedSurfaceExiting(); + final AppWindowAnimator appAnimator = wtoken.mAppAnimator; if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Now closing app " + wtoken); appAnimator.clearThumbnail(); |