From 3d7ca31c9e4a076cef5339ae58d5cafb2efbbc8f Mon Sep 17 00:00:00 2001 From: Craig Mautner Date: Thu, 8 Jan 2015 10:56:00 -0800 Subject: [PATCH] Remove AppWindowTokens from exiting apps with task When the task is removed from a task stack in window manager any exiting activities left in the stack were orphaned. This led to a memory leak. Removing all task activities from those that are exiting fixes this problem. Fixes bug 18943737. Change-Id: I0a5ea8d2d3be89af7ccaf01385a226a2eafdf507 --- .../java/com/android/server/wm/AppWindowToken.java | 5 +++-- services/core/java/com/android/server/wm/Task.java | 2 +- .../com/android/server/wm/WindowManagerService.java | 11 ++++++++++- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java index f859fd2e44bbd..da25c53323be9 100644 --- a/services/core/java/com/android/server/wm/AppWindowToken.java +++ b/services/core/java/com/android/server/wm/AppWindowToken.java @@ -304,10 +304,11 @@ class AppWindowToken extends WindowToken { pw.print(prefix); pw.print("inPendingTransaction="); pw.println(inPendingTransaction); } - if (startingData != null || removed || firstWindowDrawn) { + if (startingData != null || removed || firstWindowDrawn || mDeferRemoval) { pw.print(prefix); pw.print("startingData="); pw.print(startingData); pw.print(" removed="); pw.print(removed); - pw.print(" firstWindowDrawn="); pw.println(firstWindowDrawn); + pw.print(" firstWindowDrawn="); pw.print(firstWindowDrawn); + pw.print(" mDeferRemoval="); pw.println(mDeferRemoval); } if (startingWindow != null || startingView != null || startingDisplayed || startingMoved) { diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java index a60be3b95d6ab..b49b87c0d5b18 100644 --- a/services/core/java/com/android/server/wm/Task.java +++ b/services/core/java/com/android/server/wm/Task.java @@ -68,6 +68,6 @@ class Task { @Override public String toString() { - return "{taskId=" + taskId + " appTokens=" + mAppTokens + "}"; + return "{taskId=" + taskId + " appTokens=" + mAppTokens + " mdr=" + mDeferRemoval + "}"; } } diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 27509411d93d9..4d0169d559160 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -5200,8 +5200,17 @@ public class WindowManagerService extends IWindowManager.Stub if (DEBUG_STACK) Slog.i(TAG, "removeTask: removing taskId=" + taskId); EventLog.writeEvent(EventLogTags.WM_TASK_REMOVED, taskId, "removeTask"); task.mDeferRemoval = false; - task.mStack.removeTask(task); + stack.removeTask(task); mTaskIdToTask.delete(task.taskId); + + final ArrayList exitingApps = stack.mExitingAppTokens; + for (int appNdx = exitingApps.size() - 1; appNdx >= 0; --appNdx) { + final AppWindowToken wtoken = exitingApps.get(appNdx); + if (wtoken.groupId == taskId) { + wtoken.mDeferRemoval = false; + exitingApps.remove(appNdx); + } + } } public void removeTask(int taskId) {