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;
     }