From ed3e83b3d3aacf6a11607517dfd745c3a4cc6a51 Mon Sep 17 00:00:00 2001 From: Robert Carr Date: Fri, 21 Apr 2017 13:26:55 -0700 Subject: [PATCH] Prevent leak of AppWindowTokens. We need to check to remove ourselves from our previous parents exiting app list not the list of our new parents. If we check AOSP master AppWindowToken L333 we can see it used to work this way. This is causing the abandoned starting window buffer queue bugs in 36703921 by also triggering a leak of the startingdata and the assosciated viewrootimpl, though the surface ends up destroyed. Bug: 36703921 Test: Open app, hit back, verify dumpsys window displays "Exiting App Tokens" doesn't grow by one each time. Change-Id: I07a4df82b2694e9d0eaa1b9299d233c3aa496c3e --- .../core/java/com/android/server/wm/AppWindowToken.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java index 763464422e563..3ed0f14075b0c 100644 --- a/services/core/java/com/android/server/wm/AppWindowToken.java +++ b/services/core/java/com/android/server/wm/AppWindowToken.java @@ -175,6 +175,8 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree private boolean mDisbalePreviewScreenshots; + Task mLastParent; + AppWindowToken(WindowManagerService service, IApplicationToken token, boolean voiceInteraction, DisplayContent dc, long inputDispatchingTimeoutNanos, boolean fullscreen, boolean showForAllUsers, int targetSdk, int orientation, int rotationAnimationHint, @@ -725,19 +727,21 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree void onParentSet() { super.onParentSet(); + final Task task = getTask(); + // When the associated task is {@code null}, the {@link AppWindowToken} can no longer // access visual elements like the {@link DisplayContent}. We must remove any associations // such as animations. if (!mReparenting) { - final Task task = getTask(); if (task == null) { // It is possible we have been marked as a closing app earlier. We must remove ourselves // from this list so we do not participate in any future animations. mService.mClosingApps.remove(this); - } else if (task.mStack != null) { + } else if (mLastParent != null && mLastParent.mStack != null) { task.mStack.mExitingAppTokens.remove(this); } } + mLastParent = task; } void postWindowRemoveStartingWindowCleanup(WindowState win) {