Fix issue #11217255: Setup Wizard ANR when adding new user profile from settings.
Two problems addressed here:
- If a call to startActivity() comes in on an activity that is finishing, we can
end up putting the new activity in a stack that isn't actually in use any more
(if the finishing activity is the last one on that stack). This is a bad case,
anyway, so if this happen the treat it as not being called on an existing
activity and switch to NEW_TASK to find a task for it.
- There was a bug in handling PACKAGE_CHANGE broadcasts that would result in the
app's processes being killed, even though the cleanup through the activities
was done. This could leave the activity stack in a bad state. Fix this to
correctly provide an app id for the changing package so that its processes are
killed.
Change-Id: Iece04e0cf95025c3d30353d68bf3d14fd39d44c3
diff --git a/services/java/com/android/server/am/ActivityStackSupervisor.java b/services/java/com/android/server/am/ActivityStackSupervisor.java
index 2895552..523015d 100644
--- a/services/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/java/com/android/server/am/ActivityStackSupervisor.java
@@ -1377,12 +1377,23 @@
}
final ActivityStack sourceStack;
- TaskRecord sourceTask;
if (sourceRecord != null) {
- sourceTask = sourceRecord.task;
- sourceStack = sourceTask.stack;
+ if (sourceRecord.finishing) {
+ // If the source is finishing, we can't further count it as our source. This
+ // is because the task it is associated with may now be empty and on its way out,
+ // so we don't want to blindly throw it in to that task. Instead we will take
+ // the NEW_TASK flow and try to find a task for it.
+ if ((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
+ Slog.w(TAG, "startActivity called from finishing " + sourceRecord
+ + "; forcing " + "Intent.FLAG_ACTIVITY_NEW_TASK for: " + intent);
+ launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
+ }
+ sourceRecord = null;
+ sourceStack = null;
+ } else {
+ sourceStack = sourceRecord.task.stack;
+ }
} else {
- sourceTask = null;
sourceStack = null;
}
@@ -1424,6 +1435,8 @@
}
targetStack = intentActivity.task.stack;
targetStack.mLastPausedActivity = null;
+ if (DEBUG_TASKS) Slog.d(TAG, "Bring to front target: " + targetStack
+ + " from " + intentActivity);
moveHomeStack(targetStack.isHomeStack());
if (intentActivity.task.intent == null) {
// This task was started because of movement of
@@ -1663,7 +1676,7 @@
}
}
} else if (sourceRecord != null) {
- sourceTask = sourceRecord.task;
+ TaskRecord sourceTask = sourceRecord.task;
targetStack = sourceTask.stack;
moveHomeStack(targetStack.isHomeStack());
if (!addingToTask &&
@@ -1683,7 +1696,7 @@
targetStack.resumeTopActivityLocked(null);
}
ActivityOptions.abort(options);
- if (r.task == null) Slog.v(TAG,
+ if (r.task == null) Slog.w(TAG,
"startActivityUncheckedLocked: task left null",
new RuntimeException("here").fillInStackTrace());
return ActivityManager.START_DELIVERED_TO_TOP;
@@ -1712,7 +1725,7 @@
// it.
r.setTask(sourceTask, sourceRecord.thumbHolder, false);
if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r
- + " in existing task " + r.task);
+ + " in existing task " + r.task + " from source " + sourceRecord);
} else {
// This not being started from an existing activity, and not part
@@ -2060,9 +2073,11 @@
}
ActivityRecord findTaskLocked(ActivityRecord r) {
+ if (DEBUG_TASKS) Slog.d(TAG, "Looking for task of " + r);
for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
final ActivityStack stack = mStacks.get(stackNdx);
if (!r.isApplicationActivity() && !stack.isHomeStack()) {
+ if (DEBUG_TASKS) Slog.d(TAG, "Skipping stack: " + stack);
continue;
}
final ActivityRecord ar = stack.findTaskLocked(r);
@@ -2070,6 +2085,7 @@
return ar;
}
}
+ if (DEBUG_TASKS) Slog.d(TAG, "No task found");
return null;
}