From abb433b30463c741c5b347acfd4dc6fcd430e08b Mon Sep 17 00:00:00 2001 From: Winson Chung Date: Fri, 24 Mar 2017 09:35:42 -0700 Subject: [PATCH] Remove task activities from LRU list when task is reparented. - When a task is reparented, the activities are not removed from the previous stack's LRU list. Afterwards, when the activity is destroyed, the previous stack's LRU list will contain an activity that has no task. Instead, we should remove all of the task's activities from the LRU list when it is removed, and update the LRU list of the new stack when the top activity is next resumed. - Also fixing issue with stack header in dumpsys not printing if there are no activities (but other states were still being printed for that stack) Bug: 36253246 Test: adb shell dumpsys activity activities Change-Id: Ia14f170dceff9eadc48d1ac4aac2f16c714adde2 --- .../java/com/android/server/am/ActivityStack.java | 8 ++++++++ .../android/server/am/ActivityStackSupervisor.java | 12 ++++++++++-- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java index 9a4f804cb1b3b..28a4e1ab298fa 100644 --- a/services/core/java/com/android/server/am/ActivityStack.java +++ b/services/core/java/com/android/server/am/ActivityStack.java @@ -759,6 +759,12 @@ class ActivityStack extends ConfigurationContai } } + final void removeActivitiesFromLRUListLocked(TaskRecord task) { + for (ActivityRecord r : task.mActivities) { + mLRUActivities.remove(r); + } + } + final boolean updateLRUListLocked(ActivityRecord r) { final boolean hadit = mLRUActivities.remove(r); mLRUActivities.add(r); @@ -4947,6 +4953,7 @@ class ActivityStack extends ConfigurationContai } } mTaskHistory.remove(task); + removeActivitiesFromLRUListLocked(task); updateTaskMovement(task, true); if (mode == REMOVE_TASK_MODE_DESTROYING && task.mActivities.isEmpty()) { @@ -5114,6 +5121,7 @@ class ActivityStack extends ConfigurationContai // Apps may depend on onResume()/onPause() being called in pairs. if (setResume) { mResumedActivity = r; + updateLRUListLocked(r); } // If the activity was previously pausing, then ensure we transfer that as well if (setPause) { diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java index 5c49dfd7052b1..fc62297b01425 100644 --- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java +++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java @@ -3569,8 +3569,16 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D stackHeader.append(" mFullscreen=" + stack.mFullscreen); stackHeader.append("\n"); stackHeader.append(" mBounds=" + stack.mBounds); - printed |= stack.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, dumpPackage, - needSep, stackHeader.toString()); + + final boolean printedStackHeader = stack.dumpActivitiesLocked(fd, pw, dumpAll, + dumpClient, dumpPackage, needSep, stackHeader.toString()); + printed |= printedStackHeader; + if (!printedStackHeader) { + // Ensure we always dump the stack header even if there are no activities + pw.println(); + pw.println(stackHeader); + } + printed |= dumpHistoryList(fd, pw, stack.mLRUActivities, " ", "Run", false, !dumpAll, false, dumpPackage, true, " Running activities (most recent first):", null);