Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2a272d42 authored by Dianne Hackborn's avatar Dianne Hackborn
Browse files

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
parent db148b65
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -13143,8 +13143,8 @@ public final class ActivityManagerService extends ActivityManagerNative
                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
                                    intent.getAction());
                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
                                forceStopPackageLocked(ssp,
                                        intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true,
                                forceStopPackageLocked(ssp, UserHandle.getAppId(
                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
                                        false, userId, removed ? "pkg removed" : "pkg changed");
                            }
                            if (removed) {
+18 −9
Original line number Diff line number Diff line
@@ -478,37 +478,45 @@ final class ActivityStack {
        }
        final int userId = UserHandle.getUserId(info.applicationInfo.uid);

        if (DEBUG_TASKS) Slog.d(TAG, "Looking for task of " + target + " in " + this);
        for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
            final TaskRecord task = mTaskHistory.get(taskNdx);
            if (task.userId != userId) {
                // Looking for a different task.
                if (DEBUG_TASKS) Slog.d(TAG, "Skipping " + task + ": different user");
                continue;
            }
            final ActivityRecord r = task.getTopActivity();
            if (r == null || r.finishing || r.userId != userId ||
                    r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
                if (DEBUG_TASKS) Slog.d(TAG, "Skipping " + task + ": mismatch root " + r);
                continue;
            }

            //Slog.i(TAG, "Comparing existing cls=" + r.task.intent.getComponent().flattenToShortString()
            //        + "/aff=" + r.task.affinity + " to new cls="
            //        + intent.getComponent().flattenToShortString() + "/aff=" + taskAffinity);
            if (DEBUG_TASKS) Slog.d(TAG, "Comparing existing cls="
                    + r.task.intent.getComponent().flattenToShortString()
                    + "/aff=" + r.task.affinity + " to new cls="
                    + intent.getComponent().flattenToShortString() + "/aff=" + info.taskAffinity);
            if (task.affinity != null) {
                if (task.affinity.equals(info.taskAffinity)) {
                    //Slog.i(TAG, "Found matching affinity!");
                    if (DEBUG_TASKS) Slog.d(TAG, "Found matching affinity!");
                    return r;
                }
            } else if (task.intent != null && task.intent.getComponent().equals(cls)) {
                //Slog.i(TAG, "Found matching class!");
                if (DEBUG_TASKS) Slog.d(TAG, "Found matching class!");
                //dump();
                //Slog.i(TAG, "For Intent " + intent + " bringing to top: " + r.intent);
                if (DEBUG_TASKS) Slog.d(TAG, "For Intent " + intent + " bringing to top: "
                        + r.intent);
                return r;
            } else if (task.affinityIntent != null
                    && task.affinityIntent.getComponent().equals(cls)) {
                //Slog.i(TAG, "Found matching class!");
                if (DEBUG_TASKS) Slog.d(TAG, "Found matching class!");
                //dump();
                //Slog.i(TAG, "For Intent " + intent + " bringing to top: " + r.intent);
                if (DEBUG_TASKS) Slog.d(TAG, "For Intent " + intent + " bringing to top: "
                        + r.intent);
                return r;
            } else if (DEBUG_TASKS) {
                Slog.d(TAG, "Not a match: " + task);
            }
        }

@@ -3575,6 +3583,7 @@ final class ActivityStack {

    @Override
    public String toString() {
        return "stackId=" + mStackId + " tasks=" + mTaskHistory;
        return "ActivityStack{" + Integer.toHexString(System.identityHashCode(this))
                + " stackId=" + mStackId + ", " + mTaskHistory.size() + " tasks}";
    }
}
+23 −7
Original line number Diff line number Diff line
@@ -1377,12 +1377,23 @@ public final class ActivityStackSupervisor {
        }

        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 @@ public final class ActivityStackSupervisor {
                    }
                    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 @@ public final class ActivityStackSupervisor {
                }
            }
        } else if (sourceRecord != null) {
            sourceTask = sourceRecord.task;
            TaskRecord sourceTask = sourceRecord.task;
            targetStack = sourceTask.stack;
            moveHomeStack(targetStack.isHomeStack());
            if (!addingToTask &&
@@ -1683,7 +1696,7 @@ public final class ActivityStackSupervisor {
                        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 @@ public final class ActivityStackSupervisor {
            // 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 @@ public final class ActivityStackSupervisor {
    }

    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 @@ public final class ActivityStackSupervisor {
                return ar;
            }
        }
        if (DEBUG_TASKS) Slog.d(TAG, "No task found");
        return null;
    }