Fix home activity and user switch interactions.
- Make sure Home activity goes in the correct task and on the correct
stack.
- Do not allow different users to be in the same task.
- Do not set stacks aside for each user.
Fixes bug 9775492.
Change-Id: I0e7954e917aac8482a1015a36923e02914e2b692
diff --git a/services/java/com/android/server/am/ActivityStack.java b/services/java/com/android/server/am/ActivityStack.java
index a154b9c..4c7767c 100644
--- a/services/java/com/android/server/am/ActivityStack.java
+++ b/services/java/com/android/server/am/ActivityStack.java
@@ -465,7 +465,9 @@
* Returns the top activity in any existing task matching the given
* Intent. Returns null if no such task is found.
*/
- ActivityRecord findTaskLocked(Intent intent, ActivityInfo info) {
+ ActivityRecord findTaskLocked(ActivityRecord target) {
+ Intent intent = target.intent;
+ ActivityInfo info = target.info;
ComponentName cls = intent.getComponent();
if (info.targetActivity != null) {
cls = new ComponentName(info.packageName, info.targetActivity);
@@ -474,6 +476,10 @@
for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
final TaskRecord task = mTaskHistory.get(taskNdx);
+ if (task.userId != userId) {
+ // Looking for a different task.
+ continue;
+ }
final ActivityRecord r = task.getTopActivity();
if (r == null || r.finishing || r.userId != userId ||
r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
@@ -518,7 +524,11 @@
final int userId = UserHandle.getUserId(info.applicationInfo.uid);
for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
- final ArrayList<ActivityRecord> activities = mTaskHistory.get(taskNdx).mActivities;
+ TaskRecord task = mTaskHistory.get(taskNdx);
+ if (task.userId != mCurrentUser) {
+ return null;
+ }
+ final ArrayList<ActivityRecord> activities = task.mActivities;
for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
ActivityRecord r = activities.get(activityNdx);
if (!r.finishing && r.intent.getComponent().equals(cls) && r.userId == userId) {
@@ -534,8 +544,7 @@
}
/*
- * Move the activities around in the stack to bring a user to the foreground. This only
- * matters on the home stack. All other stacks are single user.
+ * Move the activities around in the stack to bring a user to the foreground.
* @return whether there are any activities for the specified user.
*/
final boolean switchUserLocked(int userId) {
@@ -1172,6 +1181,7 @@
// There are no more activities! Let's just start up the
// Launcher...
ActivityOptions.abort(options);
+ if (DEBUG_STATES) Slog.d(TAG, "resumeTopActivityLocked: No more activities go home");
if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
return mStackSupervisor.resumeHomeActivity(prev);
}
@@ -1186,6 +1196,7 @@
mWindowManager.executeAppTransition();
mNoAnimActivities.clear();
ActivityOptions.abort(options);
+ if (DEBUG_STATES) Slog.d(TAG, "resumeTopActivityLocked: Top activity resumed " + next);
if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
return false;
}
@@ -1213,6 +1224,7 @@
final int taskNdx = mTaskHistory.indexOf(prevTask) + 1;
mTaskHistory.get(taskNdx).mActivities.get(0).mLaunchHomeTaskNext = true;
} else {
+ if (DEBUG_STATES) Slog.d(TAG, "resumeTopActivityLocked: Launching home next");
return mStackSupervisor.resumeHomeActivity(prev);
}
}
@@ -1227,6 +1239,7 @@
mWindowManager.executeAppTransition();
mNoAnimActivities.clear();
ActivityOptions.abort(options);
+ if (DEBUG_STATES) Slog.d(TAG, "resumeTopActivityLocked: Going to sleep and all paused");
if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
return false;
}
@@ -1255,7 +1268,8 @@
// If we are currently pausing an activity, then don't do anything
// until that is done.
if (!mStackSupervisor.allPausedActivitiesComplete()) {
- if (DEBUG_SWITCH || DEBUG_PAUSE) Slog.v(TAG, "Skip resume: some activity pausing");
+ if (DEBUG_SWITCH || DEBUG_PAUSE || DEBUG_STATES) Slog.v(TAG,
+ "resumeTopActivityLocked: Skip resume: some activity pausing.");
if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
return false;
}
@@ -1295,9 +1309,11 @@
if (mResumedActivity != null) {
pausing = true;
startPausingLocked(userLeaving, false);
+ if (DEBUG_STATES) Slog.d(TAG, "resumeTopActivityLocked: Pausing " + mResumedActivity);
}
if (pausing) {
- if (DEBUG_SWITCH) Slog.v(TAG, "Skip resume: need to start pausing");
+ if (DEBUG_SWITCH || DEBUG_STATES) Slog.v(TAG,
+ "resumeTopActivityLocked: Skip resume: need to start pausing");
// At this point we want to put the upcoming activity's process
// at the top of the LRU list, since we know we will be needing it
// very soon and it would be a waste to let it get killed if it
@@ -1459,7 +1475,7 @@
// is still at the top and schedule another run if something
// weird happened.
ActivityRecord nextNext = topRunningActivityLocked(null);
- if (DEBUG_SWITCH) Slog.i(TAG,
+ if (DEBUG_SWITCH || DEBUG_STATES) Slog.i(TAG,
"Activity config changed during resume: " + next
+ ", new next: " + nextNext);
if (nextNext != next) {
@@ -1505,6 +1521,7 @@
mStackSupervisor.checkReadyForSleepLocked();
+ if (DEBUG_STATES) Slog.d(TAG, "resumeTopActivityLocked: Resumed " + next);
} catch (Exception e) {
// Whoops, need to restart this activity!
if (DEBUG_STATES) Slog.v(TAG, "Resume failed; resetting state to "
@@ -1561,6 +1578,7 @@
}
if (DEBUG_SWITCH) Slog.v(TAG, "Restarting: " + next);
}
+ if (DEBUG_STATES) Slog.d(TAG, "resumeTopActivityLocked: Restarting " + next);
mStackSupervisor.startSpecificActivityLocked(next, true, true);
}
@@ -1568,6 +1586,21 @@
return true;
}
+ private void insertTaskAtTop(TaskRecord task) {
+ mTaskHistory.remove(task);
+ // Now put task at top.
+ int stackNdx = mTaskHistory.size();
+ if (task.userId != mCurrentUser) {
+ // Put non-current user tasks below current user tasks.
+ while (--stackNdx >= 0) {
+ if (mTaskHistory.get(stackNdx).userId != mCurrentUser) {
+ break;
+ }
+ }
+ ++stackNdx;
+ }
+ mTaskHistory.add(stackNdx, task);
+ }
final void startActivityLocked(ActivityRecord r, boolean newTask,
boolean doResume, boolean keepCurTransition, Bundle options) {
@@ -1577,9 +1610,7 @@
// Last activity in task had been removed or ActivityManagerService is reusing task.
// Insert or replace.
// Might not even be in.
- mTaskHistory.remove(rTask);
- // Now put task at top.
- mTaskHistory.add(rTask);
+ insertTaskAtTop(rTask);
mWindowManager.moveTaskToTop(taskId);
}
TaskRecord task = null;
@@ -1599,7 +1630,8 @@
r.putInHistory();
mWindowManager.addAppToken(task.mActivities.indexOf(r), r.appToken,
r.task.taskId, mStackId, r.info.screenOrientation, r.fullscreen,
- (r.info.flags & ActivityInfo.FLAG_SHOW_ON_LOCK_SCREEN) != 0);
+ (r.info.flags & ActivityInfo.FLAG_SHOW_ON_LOCK_SCREEN) != 0,
+ r.userId);
if (VALIDATE_TOKENS) {
validateAppTokensLocked();
}
@@ -1660,7 +1692,7 @@
r.updateOptionsLocked(options);
mWindowManager.addAppToken(task.mActivities.indexOf(r),
r.appToken, r.task.taskId, mStackId, r.info.screenOrientation, r.fullscreen,
- (r.info.flags & ActivityInfo.FLAG_SHOW_ON_LOCK_SCREEN) != 0);
+ (r.info.flags & ActivityInfo.FLAG_SHOW_ON_LOCK_SCREEN) != 0, r.userId);
boolean doShow = true;
if (newTask) {
// Even though this activity is starting fresh, we still need
@@ -1703,7 +1735,7 @@
// because there is nothing for it to animate on top of.
mWindowManager.addAppToken(task.mActivities.indexOf(r), r.appToken,
r.task.taskId, mStackId, r.info.screenOrientation, r.fullscreen,
- (r.info.flags & ActivityInfo.FLAG_SHOW_ON_LOCK_SCREEN) != 0);
+ (r.info.flags & ActivityInfo.FLAG_SHOW_ON_LOCK_SCREEN) != 0, r.userId);
ActivityOptions.abort(options);
}
if (VALIDATE_TOKENS) {
@@ -2897,8 +2929,7 @@
// Shift all activities with this task up to the top
// of the stack, keeping them in the same internal order.
- mTaskHistory.remove(tr);
- mTaskHistory.add(tr);
+ insertTaskAtTop(tr);
if (DEBUG_TRANSITION) Slog.v(TAG, "Prepare to front transition: task=" + tr);
if (reason != null &&
@@ -3380,7 +3411,7 @@
printed |= ActivityStackSupervisor.dumpHistoryList(fd, pw,
mTaskHistory.get(taskNdx).mActivities, " ", "Hist", true, !dumpAll,
dumpClient, dumpPackage, needSep, header,
- " Task " + taskNdx + ": id #" + task.taskId);
+ " Task id #" + task.taskId);
if (printed) {
header = null;
}
@@ -3448,12 +3479,8 @@
}
TaskRecord createTaskRecord(int taskId, ActivityInfo info, Intent intent, boolean toTop) {
- TaskRecord task = new TaskRecord(taskId, info, intent, this);
- if (toTop) {
- mTaskHistory.add(task);
- } else {
- mTaskHistory.add(0, task);
- }
+ TaskRecord task = new TaskRecord(taskId, info, intent);
+ addTask(task, toTop);
return task;
}
@@ -3464,7 +3491,7 @@
void addTask(final TaskRecord task, final boolean toTop) {
task.stack = this;
if (toTop) {
- mTaskHistory.add(task);
+ insertTaskAtTop(task);
} else {
mTaskHistory.add(0, task);
}