From 713abc2879c21106eb806739cfd51c2a81a9b401 Mon Sep 17 00:00:00 2001 From: tiger_huang Date: Mon, 16 Feb 2015 16:14:47 +0800 Subject: Prevent leaking surfaces from exiting windows AM would set the exiting app to be invisible twice by calling setAppVisibility(). If the screen is turned off during these calls, the window surfaces of this exiting app won't be destroyed. The flow: 1. Screen is on 2. App A is finished 3. AM calls setAppVisibility() token=App A, visible=false 4. WM sets a dummy animation to App A 5. WM marks App A's wtoken.inPendingTransaction=true 6. Screen is turned off 7. AM calls setAppVisibility() token=App A, visible=false 8. WM calls setTokenVisibilityLocked() directly (screen is off) 9. WM sends app visibility to App A's client (ViewRootImpl) 10. WM clears the dummy animation from App A 11. App A's client calls WMS.relayoutWindow() to be not visible 12. WM sets App A's window mExiting=true but not destroy its surface 13. App A's window surface leaks... Note: a. The call in 3. is from ActivityStack.finishActivityLocked b. The call in 7. is from ActivityStack.resumeTopActivityInnerLocked c. In 10., App A won't get the real animation while screen is off d. In 12., App A's inPendingTransaction=true; WM takes it's animating e. mExiting won't be cleared because App A has no animation to trigger WindowStateAnimator.finishExit() After applying this patch, WM would destroy the surface in 12. of the above flow. Change-Id: I18b79ba96695ec80d57a85dc15cf92a9e7d3a6ef --- services/core/java/com/android/server/wm/WindowManagerService.java | 1 + 1 file changed, 1 insertion(+) diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index c80d0e1..6775dee 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -4600,6 +4600,7 @@ public class WindowManagerService extends IWindowManager.Stub } final long origId = Binder.clearCallingIdentity(); + wtoken.inPendingTransaction = false; setTokenVisibilityLocked(wtoken, null, visible, AppTransition.TRANSIT_UNSET, true, wtoken.voiceInteraction); wtoken.updateReportedVisibilityLocked(); -- cgit v1.1