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;