summaryrefslogtreecommitdiffstats
path: root/services/java/com/android/server/am/ActivityStackSupervisor.java
diff options
context:
space:
mode:
authorCraig Mautner <cmautner@google.com>2013-04-23 17:08:34 -0700
committerCraig Mautner <cmautner@google.com>2013-04-23 19:33:42 -0700
commit858d8a6583b0c91c66960167b84c67b6c4e2d3c6 (patch)
tree7aaf135ec6c0cd770f3d15372a7f662f09d6fa6f /services/java/com/android/server/am/ActivityStackSupervisor.java
parentcf910b0c714b2ca90ea0013e5695850506a1d36f (diff)
downloadframeworks_base-858d8a6583b0c91c66960167b84c67b6c4e2d3c6.zip
frameworks_base-858d8a6583b0c91c66960167b84c67b6c4e2d3c6.tar.gz
frameworks_base-858d8a6583b0c91c66960167b84c67b6c4e2d3c6.tar.bz2
Fix user switching.
- Save and restore WindowManager stack states. - Maintain ActivityManager activity states based on the stack the activity is in. Fixes bug 8646641. Change-Id: I16c76c7708ab49121c3884a7e5bf219898b92d3f
Diffstat (limited to 'services/java/com/android/server/am/ActivityStackSupervisor.java')
-rw-r--r--services/java/com/android/server/am/ActivityStackSupervisor.java84
1 files changed, 62 insertions, 22 deletions
diff --git a/services/java/com/android/server/am/ActivityStackSupervisor.java b/services/java/com/android/server/am/ActivityStackSupervisor.java
index 89b0ff2..528bf6f 100644
--- a/services/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/java/com/android/server/am/ActivityStackSupervisor.java
@@ -61,6 +61,7 @@ import android.os.SystemClock;
import android.os.UserHandle;
import android.util.EventLog;
import android.util.Slog;
+import android.util.SparseArray;
import com.android.internal.app.HeavyWeightSwitcherActivity;
import com.android.server.am.ActivityManagerService.PendingActivityLaunch;
@@ -160,6 +161,9 @@ public class ActivityStackSupervisor {
* is being brought in front of us. */
boolean mUserLeaving = false;
+ /** Stacks belonging to users other than mCurrentUser. Indexed by userId. */
+ final SparseArray<UserState> mUserStates = new SparseArray<UserState>();
+
public ActivityStackSupervisor(ActivityManagerService service, Context context,
Looper looper) {
mService = service;
@@ -213,6 +217,9 @@ public class ActivityStackSupervisor {
}
boolean isFrontStack(ActivityStack stack) {
+ if (stack.mCurrentUser != mCurrentUser) {
+ return false;
+ }
return !(stack.isHomeStack() ^ getFocusedStack().isHomeStack());
}
@@ -319,6 +326,9 @@ public class ActivityStackSupervisor {
final String processName = app.processName;
for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
final ActivityStack stack = mStacks.get(stackNdx);
+ if (!isFrontStack(stack)) {
+ continue;
+ }
ActivityRecord hr = stack.topRunningActivityLocked(null);
if (hr != null) {
if (hr.app == null && app.uid == hr.info.applicationInfo.uid
@@ -412,7 +422,7 @@ public class ActivityStackSupervisor {
}
void reportActivityVisibleLocked(ActivityRecord r) {
- for (int i=mWaitingActivityVisible.size()-1; i>=0; i--) {
+ for (int i = mWaitingActivityVisible.size()-1; i >= 0; i--) {
WaitResult w = mWaitingActivityVisible.get(i);
w.timeout = false;
if (r != null) {
@@ -449,6 +459,9 @@ public class ActivityStackSupervisor {
}
for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
final ActivityStack stack = mStacks.get(stackNdx);
+ if (stack.mCurrentUser != mCurrentUser) {
+ continue;
+ }
if (stack != mFocusedStack && isFrontStack(stack)) {
r = stack.topRunningActivityLocked(null);
if (r != null) {
@@ -1145,8 +1158,14 @@ public class ActivityStackSupervisor {
ActivityStack getCorrectStack(ActivityRecord r) {
if (!r.isHomeActivity) {
- if (mStacks.size() == 1) {
- // Time to create the first app stack.
+ int stackNdx;
+ for (stackNdx = mStacks.size() - 1; stackNdx > 0; --stackNdx) {
+ if (mStacks.get(stackNdx).mCurrentUser == mCurrentUser) {
+ break;
+ }
+ }
+ if (stackNdx == 0) {
+ // Time to create the first app stack for this user.
int stackId = mService.createStack(-1, HOME_STACK_ID,
StackBox.TASK_STACK_GOES_OVER, 1.0f);
mFocusedStack = getStack(stackId);
@@ -1776,7 +1795,7 @@ public class ActivityStackSupervisor {
return didSomething;
}
- void resumeTopActivityLocked() {
+ void resumeTopActivitiesLocked() {
for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
final ActivityStack stack = mStacks.get(stackNdx);
if (isFrontStack(stack)) {
@@ -1816,18 +1835,16 @@ public class ActivityStackSupervisor {
}
int createStack() {
- synchronized (this) {
- while (true) {
- if (++mLastStackId <= HOME_STACK_ID) {
- mLastStackId = HOME_STACK_ID + 1;
- }
- if (getStack(mLastStackId) == null) {
- break;
- }
+ while (true) {
+ if (++mLastStackId <= HOME_STACK_ID) {
+ mLastStackId = HOME_STACK_ID + 1;
+ }
+ if (getStack(mLastStackId) == null) {
+ break;
}
- mStacks.add(new ActivityStack(mService, mContext, mLooper, mLastStackId));
- return mLastStackId;
}
+ mStacks.add(new ActivityStack(mService, mContext, mLooper, mLastStackId));
+ return mLastStackId;
}
void moveTaskToStack(int taskId, int stackId, boolean toTop) {
@@ -1938,16 +1955,22 @@ public class ActivityStackSupervisor {
}
boolean switchUserLocked(int userId, UserStartedState uss) {
+ mUserStates.put(mCurrentUser, new UserState());
mCurrentUser = userId;
- mStartingUsers.add(uss);
- boolean haveActivities = false;
- final int numStacks = mStacks.size();
- for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
- final ActivityStack stack = mStacks.get(stackNdx);
- if (isFrontStack(stack)) {
- haveActivities |= stack.switchUserLocked(userId, uss);
- }
+ UserState userState = mUserStates.get(userId);
+ if (userState != null) {
+ userState.restore();
+ mUserStates.delete(userId);
+ } else {
+ mFocusedStack = null;
+ mStackState = STACK_STATE_HOME_IN_FRONT;
}
+
+ mStartingUsers.add(uss);
+ boolean haveActivities = mHomeStack.switchUserLocked(userId, uss);
+
+ resumeTopActivitiesLocked();
+
return haveActivities;
}
@@ -2203,4 +2226,21 @@ public class ActivityStackSupervisor {
}
}
}
+
+ private final class UserState {
+ final ActivityStack mSavedFocusedStack;
+ final int mSavedStackState;
+
+ public UserState() {
+ ActivityStackSupervisor supervisor = ActivityStackSupervisor.this;
+ mSavedFocusedStack = supervisor.mFocusedStack;
+ mSavedStackState = supervisor.mStackState;
+ }
+
+ void restore() {
+ ActivityStackSupervisor supervisor = ActivityStackSupervisor.this;
+ supervisor.mFocusedStack = mSavedFocusedStack;
+ supervisor.mStackState = mSavedStackState;
+ }
+ }
}