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

Commit 45c25ceb authored by Chong Zhang's avatar Chong Zhang
Browse files

Handle activity launch for background users

- When launching activities in background, do not move the
  target stack to front or resume the top activity, it should
  have no observable effect to current user.

- Add the launched background task to recents so that they
  can be found when the background user becomes current.

- Keep track of the last accessed stack for background user,
  so that we know which stack to start with when that user goes
  current

bug: 22929608

Change-Id: I0421a6b490251503df7a7e71465b8aae5138eb2d
parent abdceed0
Loading
Loading
Loading
Loading
+1 −10
Original line number Diff line number Diff line
@@ -1809,15 +1809,6 @@ public class Instrumentation {
            case ActivityManager.START_NOT_VOICE_COMPATIBLE:
                throw new SecurityException(
                        "Starting under voice control not allowed for: " + intent);
            case ActivityManager.START_NOT_CURRENT_USER_ACTIVITY:
                // Fail silently for this case so we don't break current apps.
                // TODO(b/22929608): Instead of failing silently or throwing an exception,
                // we should properly position the activity in the stack (i.e. behind all current
                // user activity/task) and not change the positioning of stacks.
                Log.e(TAG,
                        "Not allowed to start background user activity that shouldn't be displayed"
                        + " for all users. Failing silently...");
                break;
            default:
                throw new AndroidRuntimeException("Unknown error code "
                        + res + " when starting " + intent);
+18 −2
Original line number Diff line number Diff line
@@ -363,8 +363,7 @@ final class ActivityStack {
    }

    boolean okToShowLocked(ActivityRecord r) {
        return mStackSupervisor.isCurrentProfileLocked(r.userId)
                || (r.info.flags & FLAG_SHOW_FOR_ALL_USERS) != 0;
        return mStackSupervisor.okToShowLocked(r);
    }

    final ActivityRecord topRunningActivityLocked(ActivityRecord notTop) {
@@ -690,6 +689,13 @@ final class ActivityStack {
                "Launch completed; removing icicle of " + r.icicle);
    }

    private void addRecentActivityLocked(ActivityRecord r) {
        if (r != null) {
            mRecentTasks.addLocked(r.task);
            r.task.touchActiveTime();
        }
    }

    private void startLaunchTraces(String packageName) {
        if (mFullyDrawnStartTime != 0)  {
            Trace.asyncTraceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER, "drawing", 0);
@@ -2285,6 +2291,8 @@ final class ActivityStack {

        if (doResume) {
            mStackSupervisor.resumeTopActivitiesLocked(this, r, options);
        } else {
            addRecentActivityLocked(r);
        }
    }

@@ -3730,6 +3738,14 @@ final class ActivityStack {
        // of the stack, keeping them in the same internal order.
        insertTaskAtTop(tr, null);

        // Don't refocus if invisible to current user
        ActivityRecord top = tr.getTopActivity();
        if (!okToShowLocked(top)) {
            addRecentActivityLocked(top);
            ActivityOptions.abort(options);
            return;
        }

        // Set focus to the top running activity of this stack.
        ActivityRecord r = topRunningActivityLocked(null);
        mService.setFocusedActivityLocked(r, reason);
+32 −14
Original line number Diff line number Diff line
@@ -1499,13 +1499,6 @@ public final class ActivityStackSupervisor implements DisplayListener {
            err = ActivityManager.START_CLASS_NOT_FOUND;
        }

        if (err == ActivityManager.START_SUCCESS
                && !isCurrentProfileLocked(userId)
                && (aInfo.flags & FLAG_SHOW_FOR_ALL_USERS) == 0) {
            // Trying to launch a background activity that doesn't show for all users.
            err = ActivityManager.START_NOT_CURRENT_USER_ACTIVITY;
        }

        if (err == ActivityManager.START_SUCCESS && sourceRecord != null
                && sourceRecord.task.voiceSession != null) {
            // If this activity is being launched as part of a voice session, we need
@@ -1922,8 +1915,9 @@ public final class ActivityStackSupervisor implements DisplayListener {
        // If the caller has asked not to resume at this point, we make note
        // of this in the record so that we can skip it when trying to find
        // the top running activity.
        if (!doResume) {
        if (!doResume || !okToShowLocked(r)) {
            r.delayedResume = true;
            doResume = false;
        }

        ActivityRecord notTop =
@@ -2128,7 +2122,7 @@ public final class ActivityStackSupervisor implements DisplayListener {
                            options = null;
                        }
                    }
                    if (!movedToFront) {
                    if (!movedToFront && doResume) {
                        if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Bring to front target: " + targetStack
                                + " from " + intentActivity);
                        targetStack.moveToFront("intentActivityFound");
@@ -2155,6 +2149,7 @@ public final class ActivityStackSupervisor implements DisplayListener {
                        } else {
                            ActivityOptions.abort(options);
                        }
                        updateUserStackLocked(r.userId, targetStack);
                        return ActivityManager.START_RETURN_INTENT_TO_CALLER;
                    }
                    if ((launchFlags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))
@@ -2257,6 +2252,7 @@ public final class ActivityStackSupervisor implements DisplayListener {
                        } else {
                            ActivityOptions.abort(options);
                        }
                        updateUserStackLocked(r.userId, targetStack);
                        return ActivityManager.START_TASK_TO_FRONT;
                    }
                }
@@ -2322,7 +2318,9 @@ public final class ActivityStackSupervisor implements DisplayListener {
                && (launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
            newTask = true;
            targetStack = computeStackFocus(r, newTask);
            if (doResume) {
                targetStack.moveToFront("startingNewTask");
            }

            if (reuseTask == null) {
                r.setTask(targetStack.createTaskRecord(getNextTaskId(),
@@ -2355,7 +2353,9 @@ public final class ActivityStackSupervisor implements DisplayListener {
                return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION;
            }
            targetStack = sourceTask.stack;
            if (doResume) {
                targetStack.moveToFront("sourceStackToFront");
            }
            final TaskRecord topTask = targetStack.topTask();
            if (topTask != sourceTask) {
                targetStack.moveTaskToFrontLocked(sourceTask, noAnimation, options,
@@ -2450,7 +2450,9 @@ public final class ActivityStackSupervisor implements DisplayListener {
            // of a new task...  just put it in the top task, though these days
            // this case should never happen.
            targetStack = computeStackFocus(r, newTask);
            if (doResume) {
                targetStack.moveToFront("addingToTopTask");
            }
            ActivityRecord prev = targetStack.topActivity();
            r.setTask(prev != null ? prev.task : targetStack.createTaskRecord(getNextTaskId(),
                            r.info, intent, null, null, true), null);
@@ -2471,10 +2473,10 @@ public final class ActivityStackSupervisor implements DisplayListener {
        ActivityStack.logStartActivity(EventLogTags.AM_CREATE_ACTIVITY, r, r.task);
        targetStack.mLastPausedActivity = null;
        targetStack.startActivityLocked(r, newTask, doResume, keepCurTransition, options);
        if (!launchTaskBehind) {
            // Don't set focus on an activity that's going to the back.
        if (!launchTaskBehind && doResume) {
            mService.setFocusedActivityLocked(r, "startedActivity");
        }
        updateUserStackLocked(r.userId, targetStack);
        return ActivityManager.START_SUCCESS;
    }

@@ -2675,6 +2677,16 @@ public final class ActivityStackSupervisor implements DisplayListener {
        mUserStackInFront.delete(userId);
    }

    /**
     * Update the last used stack id for non-current user (current user's last
     * used stack is the focused stack)
     */
    void updateUserStackLocked(int userId, ActivityStack stack) {
        if (userId != mCurrentUser) {
            mUserStackInFront.put(userId, stack != null ? stack.getStackId() : HOME_STACK_ID);
        }
    }

    /**
     * @return true if some activity was finished (or would have finished if doit were true).
     */
@@ -3511,6 +3523,12 @@ public final class ActivityStackSupervisor implements DisplayListener {
        return false;
    }

    /** Checks whether the activity should be shown for current user. */
    boolean okToShowLocked(ActivityRecord r) {
        return r != null && (isCurrentProfileLocked(r.userId)
                || (r.info.flags & FLAG_SHOW_FOR_ALL_USERS) != 0);
    }

    final ArrayList<ActivityRecord> processStoppingActivitiesLocked(boolean remove) {
        ArrayList<ActivityRecord> stops = null;