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
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index 2e9272c..a449baf 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -1499,13 +1499,6 @@
             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 @@
         // 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 @@
                             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 @@
                         } 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 @@
                         } else {
                             ActivityOptions.abort(options);
                         }
+                        updateUserStackLocked(r.userId, targetStack);
                         return ActivityManager.START_TASK_TO_FRONT;
                     }
                 }
@@ -2322,7 +2318,9 @@
                 && (launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
             newTask = true;
             targetStack = computeStackFocus(r, newTask);
-            targetStack.moveToFront("startingNewTask");
+            if (doResume) {
+                targetStack.moveToFront("startingNewTask");
+            }
 
             if (reuseTask == null) {
                 r.setTask(targetStack.createTaskRecord(getNextTaskId(),
@@ -2355,7 +2353,9 @@
                 return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION;
             }
             targetStack = sourceTask.stack;
-            targetStack.moveToFront("sourceStackToFront");
+            if (doResume) {
+                targetStack.moveToFront("sourceStackToFront");
+            }
             final TaskRecord topTask = targetStack.topTask();
             if (topTask != sourceTask) {
                 targetStack.moveTaskToFrontLocked(sourceTask, noAnimation, options,
@@ -2450,7 +2450,9 @@
             // of a new task...  just put it in the top task, though these days
             // this case should never happen.
             targetStack = computeStackFocus(r, newTask);
-            targetStack.moveToFront("addingToTopTask");
+            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 @@
         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;
     }
 
@@ -2676,6 +2678,16 @@
     }
 
     /**
+     * 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).
      */
     boolean finishDisabledPackageActivitiesLocked(String packageName, Set<String> filterByClasses,
@@ -3511,6 +3523,12 @@
         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;