Retain stacks even if they are empty.
Previously stacks would be removed when the last ActivityRecord was
removed. This causes problems for ActivityContainers which persist and
permit activities to be launched into an empty stack.
Change-Id: Ia79ac65d17c42eff3a7b1321980c21b29996001b
diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java
index b78f24c..a27288a 100644
--- a/services/core/java/com/android/server/am/ActivityRecord.java
+++ b/services/core/java/com/android/server/am/ActivityRecord.java
@@ -486,7 +486,7 @@
void setTask(TaskRecord newTask, ThumbnailHolder newThumbHolder, boolean isRoot) {
if (task != null && task.removeActivity(this)) {
if (task != newTask) {
- mStackSupervisor.removeTask(task);
+ task.stack.removeTask(task);
} else {
Slog.d(TAG, "!!! REMOVE THIS LOG !!! setTask: nearly removed stack=" +
(newTask == null ? null : newTask.stack));
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index 5cb0b31..114fe34 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -2674,7 +2674,7 @@
r.finishLaunchTickingLocked();
}
- final void removeActivityFromHistoryLocked(ActivityRecord r) {
+ private void removeActivityFromHistoryLocked(ActivityRecord r) {
finishActivityResultsLocked(r, Activity.RESULT_CANCELED, null);
r.makeFinishing();
if (DEBUG_ADD_REMOVE) {
@@ -2689,7 +2689,7 @@
if (mStackSupervisor.isFrontStack(this) && task == topTask() && task.mOnTopOfHome) {
mStackSupervisor.moveHomeToTop();
}
- mStackSupervisor.removeTask(task);
+ removeTask(task);
}
r.takeFromHistory();
removeTimeoutsForActivityLocked(r);
@@ -3596,14 +3596,28 @@
return starting;
}
- boolean removeTask(TaskRecord task) {
+ void removeTask(TaskRecord task) {
+ mWindowManager.removeTask(task.taskId);
+ final ActivityRecord r = mResumedActivity;
+ if (r != null && r.task == task) {
+ mResumedActivity = null;
+ }
+
final int taskNdx = mTaskHistory.indexOf(task);
final int topTaskNdx = mTaskHistory.size() - 1;
if (task.mOnTopOfHome && taskNdx < topTaskNdx) {
mTaskHistory.get(taskNdx + 1).mOnTopOfHome = true;
}
mTaskHistory.remove(task);
- return mTaskHistory.isEmpty();
+
+ if (mTaskHistory.isEmpty()) {
+ if (DEBUG_STACK) Slog.i(TAG, "removeTask: moving to back stack=" + this);
+ if (isOnHomeDisplay()) {
+ mStackSupervisor.moveHomeStack(!isHomeStack());
+ }
+ mStacks.remove(this);
+ mStacks.add(0, this);
+ }
}
TaskRecord createTaskRecord(int taskId, ActivityInfo info, Intent intent, boolean toTop) {
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index ed11470f..bc12034 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -364,25 +364,6 @@
return mCurTaskId;
}
- void removeTask(TaskRecord task) {
- mWindowManager.removeTask(task.taskId);
- final ActivityStack stack = task.stack;
- final ActivityRecord r = stack.mResumedActivity;
- if (r != null && r.task == task) {
- stack.mResumedActivity = null;
- }
- if (stack.removeTask(task) && !stack.isHomeStack()) {
- if (DEBUG_STACK) Slog.i(TAG, "removeTask: removing stack " + stack);
- stack.mActivityContainer.detachLocked();
- final int stackId = stack.mStackId;
- final int nextStackId = mWindowManager.removeStack(stackId);
- // TODO: Perhaps we need to let the ActivityManager determine the next focus...
- if (stack.isOnHomeDisplay()) {
- mFocusedStack = getStack(nextStackId);
- }
- }
- }
-
ActivityRecord resumedAppLocked() {
ActivityStack stack = getFocusedStack();
if (stack == null) {
@@ -2192,7 +2173,7 @@
Slog.w(TAG, "moveTaskToStack: no stack for id=" + stackId);
return;
}
- removeTask(task);
+ task.stack.removeTask(task);
stack.addTask(task, toTop);
mWindowManager.addTask(taskId, stackId, toTop);
resumeTopActivitiesLocked();
diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java
index ef245f9..aa6b0c9 100644
--- a/services/core/java/com/android/server/wm/TaskStack.java
+++ b/services/core/java/com/android/server/wm/TaskStack.java
@@ -191,14 +191,18 @@
}
/**
- * Delete a Task from this stack. If it is the last Task in the stack, remove this stack from
- * its parent StackBox and merge the parent.
+ * Delete a Task from this stack. If it is the last Task in the stack, move this stack to the
+ * back.
* @param task The Task to delete.
*/
void removeTask(Task task) {
if (DEBUG_TASK_MOVEMENT) Slog.d(TAG, "removeTask: task=" + task);
mTasks.remove(task);
mDisplayContent.removeTask(task);
+ if (mTasks.isEmpty()) {
+ mDisplayContent.moveStack(this, false);
+ }
+ mDisplayContent.layoutNeeded = true;
}
int remove() {
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index f679846..b7b19ae 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -4845,23 +4845,6 @@
}
}
- public int removeStack(int stackId) {
- synchronized (mWindowMap) {
- final TaskStack stack = mStackIdToStack.get(stackId);
- if (stack != null) {
- mStackIdToStack.delete(stackId);
- int nextStackId = stack.remove();
- stack.getDisplayContent().layoutNeeded = true;
- requestTraversalLocked();
- if (nextStackId > HOME_STACK_ID) {
- return nextStackId;
- }
- }
- if (DEBUG_STACK) Slog.i(TAG, "removeStack: could not find stackId=" + stackId);
- }
- return HOME_STACK_ID;
- }
-
public void removeTask(int taskId) {
synchronized (mWindowMap) {
Task task = mTaskIdToTask.get(taskId);
@@ -4872,7 +4855,6 @@
final TaskStack stack = task.mStack;
EventLog.writeEvent(EventLogTags.WM_TASK_REMOVED, taskId, "removeTask");
stack.removeTask(task);
- stack.getDisplayContent().layoutNeeded = true;
}
}