Loading services/java/com/android/server/am/ActivityManagerService.java +14 −9 Original line number Original line Diff line number Diff line Loading @@ -4133,7 +4133,7 @@ public final class ActivityManagerService extends ActivityManagerNative } } } } if (mBooted) { if (mBooted) { mStackSupervisor.resumeTopActivityLocked(); mStackSupervisor.resumeTopActivitiesLocked(); mStackSupervisor.scheduleIdleLocked(); mStackSupervisor.scheduleIdleLocked(); } } } } Loading Loading @@ -4984,6 +4984,7 @@ public final class ActivityManagerService extends ActivityManagerNative } } } } @Override public void setProcessForeground(IBinder token, int pid, boolean isForeground) { public void setProcessForeground(IBinder token, int pid, boolean isForeground) { enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, "setProcessForeground()"); "setProcessForeground()"); Loading @@ -5007,6 +5008,7 @@ public final class ActivityManagerService extends ActivityManagerNative } } if (isForeground && token != null) { if (isForeground && token != null) { ForegroundToken newToken = new ForegroundToken() { ForegroundToken newToken = new ForegroundToken() { @Override public void binderDied() { public void binderDied() { foregroundTokenDied(this); foregroundTokenDied(this); } } Loading Loading @@ -5041,6 +5043,7 @@ public final class ActivityManagerService extends ActivityManagerNative mActivityManagerService = activityManagerService; mActivityManagerService = activityManagerService; } } @Override public boolean checkPermission(String permission, int pid, int uid) { public boolean checkPermission(String permission, int pid, int uid) { return mActivityManagerService.checkPermission(permission, pid, return mActivityManagerService.checkPermission(permission, pid, uid) == PackageManager.PERMISSION_GRANTED; uid) == PackageManager.PERMISSION_GRANTED; Loading @@ -5048,12 +5051,14 @@ public final class ActivityManagerService extends ActivityManagerNative } } class IntentFirewallInterface implements IntentFirewall.AMSInterface { class IntentFirewallInterface implements IntentFirewall.AMSInterface { @Override public int checkComponentPermission(String permission, int pid, int uid, public int checkComponentPermission(String permission, int pid, int uid, int owningUid, boolean exported) { int owningUid, boolean exported) { return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, owningUid, exported); owningUid, exported); } } @Override public Object getAMSLock() { public Object getAMSLock() { return ActivityManagerService.this; return ActivityManagerService.this; } } Loading Loading @@ -8281,7 +8286,7 @@ public final class ActivityManagerService extends ActivityManagerNative } finally { } finally { Binder.restoreCallingIdentity(ident); Binder.restoreCallingIdentity(ident); } } mStackSupervisor.resumeTopActivityLocked(); mStackSupervisor.resumeTopActivitiesLocked(); sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); } } } } Loading Loading @@ -8396,10 +8401,10 @@ public final class ActivityManagerService extends ActivityManagerNative // annoy the user repeatedly. Unless it is persistent, since those // annoy the user repeatedly. Unless it is persistent, since those // processes run critical code. // processes run critical code. removeProcessLocked(app, false, false, "crash"); removeProcessLocked(app, false, false, "crash"); mStackSupervisor.resumeTopActivityLocked(); mStackSupervisor.resumeTopActivitiesLocked(); return false; return false; } } mStackSupervisor.resumeTopActivityLocked(); mStackSupervisor.resumeTopActivitiesLocked(); } else { } else { mStackSupervisor.finishTopRunningActivityLocked(app); mStackSupervisor.finishTopRunningActivityLocked(app); } } Loading services/java/com/android/server/am/ActivityStack.java +4 −6 Original line number Original line Diff line number Diff line Loading @@ -234,7 +234,7 @@ final class ActivityStack { int mThumbnailWidth = -1; int mThumbnailWidth = -1; int mThumbnailHeight = -1; int mThumbnailHeight = -1; private int mCurrentUser; int mCurrentUser; final int mStackId; final int mStackId; Loading Loading @@ -576,7 +576,8 @@ final class ActivityStack { } } /* /* * Move the activities around in the stack to bring a user to the foreground. * 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. * @return whether there are any activities for the specified user. * @return whether there are any activities for the specified user. */ */ final boolean switchUserLocked(int userId, UserStartedState uss) { final boolean switchUserLocked(int userId, UserStartedState uss) { Loading @@ -602,9 +603,6 @@ final class ActivityStack { } } } } // task is now the original topmost TaskRecord. Transition from the old top to the new top. ActivityRecord top = task != null ? task.getTopActivity() : null; resumeTopActivityLocked(top); return haveActivities; return haveActivities; } } Loading Loading @@ -1718,7 +1716,7 @@ final class ActivityStack { } } if (doResume) { if (doResume) { mStackSupervisor.resumeTopActivityLocked(); mStackSupervisor.resumeTopActivitiesLocked(); } } } } Loading services/java/com/android/server/am/ActivityStackSupervisor.java +62 −22 Original line number Original line Diff line number Diff line Loading @@ -61,6 +61,7 @@ import android.os.SystemClock; import android.os.UserHandle; import android.os.UserHandle; import android.util.EventLog; import android.util.EventLog; import android.util.Slog; import android.util.Slog; import android.util.SparseArray; import com.android.internal.app.HeavyWeightSwitcherActivity; import com.android.internal.app.HeavyWeightSwitcherActivity; import com.android.server.am.ActivityManagerService.PendingActivityLaunch; import com.android.server.am.ActivityManagerService.PendingActivityLaunch; Loading Loading @@ -160,6 +161,9 @@ public class ActivityStackSupervisor { * is being brought in front of us. */ * is being brought in front of us. */ boolean mUserLeaving = false; 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, public ActivityStackSupervisor(ActivityManagerService service, Context context, Looper looper) { Looper looper) { mService = service; mService = service; Loading Loading @@ -213,6 +217,9 @@ public class ActivityStackSupervisor { } } boolean isFrontStack(ActivityStack stack) { boolean isFrontStack(ActivityStack stack) { if (stack.mCurrentUser != mCurrentUser) { return false; } return !(stack.isHomeStack() ^ getFocusedStack().isHomeStack()); return !(stack.isHomeStack() ^ getFocusedStack().isHomeStack()); } } Loading Loading @@ -319,6 +326,9 @@ public class ActivityStackSupervisor { final String processName = app.processName; final String processName = app.processName; for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { final ActivityStack stack = mStacks.get(stackNdx); final ActivityStack stack = mStacks.get(stackNdx); if (!isFrontStack(stack)) { continue; } ActivityRecord hr = stack.topRunningActivityLocked(null); ActivityRecord hr = stack.topRunningActivityLocked(null); if (hr != null) { if (hr != null) { if (hr.app == null && app.uid == hr.info.applicationInfo.uid if (hr.app == null && app.uid == hr.info.applicationInfo.uid Loading Loading @@ -449,6 +459,9 @@ public class ActivityStackSupervisor { } } for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { final ActivityStack stack = mStacks.get(stackNdx); final ActivityStack stack = mStacks.get(stackNdx); if (stack.mCurrentUser != mCurrentUser) { continue; } if (stack != mFocusedStack && isFrontStack(stack)) { if (stack != mFocusedStack && isFrontStack(stack)) { r = stack.topRunningActivityLocked(null); r = stack.topRunningActivityLocked(null); if (r != null) { if (r != null) { Loading Loading @@ -1145,8 +1158,14 @@ public class ActivityStackSupervisor { ActivityStack getCorrectStack(ActivityRecord r) { ActivityStack getCorrectStack(ActivityRecord r) { if (!r.isHomeActivity) { if (!r.isHomeActivity) { if (mStacks.size() == 1) { int stackNdx; // Time to create the first app stack. 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, int stackId = mService.createStack(-1, HOME_STACK_ID, StackBox.TASK_STACK_GOES_OVER, 1.0f); StackBox.TASK_STACK_GOES_OVER, 1.0f); mFocusedStack = getStack(stackId); mFocusedStack = getStack(stackId); Loading Loading @@ -1776,7 +1795,7 @@ public class ActivityStackSupervisor { return didSomething; return didSomething; } } void resumeTopActivityLocked() { void resumeTopActivitiesLocked() { for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { final ActivityStack stack = mStacks.get(stackNdx); final ActivityStack stack = mStacks.get(stackNdx); if (isFrontStack(stack)) { if (isFrontStack(stack)) { Loading Loading @@ -1816,7 +1835,6 @@ public class ActivityStackSupervisor { } } int createStack() { int createStack() { synchronized (this) { while (true) { while (true) { if (++mLastStackId <= HOME_STACK_ID) { if (++mLastStackId <= HOME_STACK_ID) { mLastStackId = HOME_STACK_ID + 1; mLastStackId = HOME_STACK_ID + 1; Loading @@ -1828,7 +1846,6 @@ public class ActivityStackSupervisor { mStacks.add(new ActivityStack(mService, mContext, mLooper, mLastStackId)); mStacks.add(new ActivityStack(mService, mContext, mLooper, mLastStackId)); return mLastStackId; return mLastStackId; } } } void moveTaskToStack(int taskId, int stackId, boolean toTop) { void moveTaskToStack(int taskId, int stackId, boolean toTop) { final ActivityStack stack = getStack(stackId); final ActivityStack stack = getStack(stackId); Loading Loading @@ -1938,16 +1955,22 @@ public class ActivityStackSupervisor { } } boolean switchUserLocked(int userId, UserStartedState uss) { boolean switchUserLocked(int userId, UserStartedState uss) { mUserStates.put(mCurrentUser, new UserState()); mCurrentUser = userId; mCurrentUser = userId; mStartingUsers.add(uss); UserState userState = mUserStates.get(userId); boolean haveActivities = false; if (userState != null) { final int numStacks = mStacks.size(); userState.restore(); for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { mUserStates.delete(userId); final ActivityStack stack = mStacks.get(stackNdx); } else { if (isFrontStack(stack)) { mFocusedStack = null; haveActivities |= stack.switchUserLocked(userId, uss); mStackState = STACK_STATE_HOME_IN_FRONT; } } } mStartingUsers.add(uss); boolean haveActivities = mHomeStack.switchUserLocked(userId, uss); resumeTopActivitiesLocked(); return haveActivities; return haveActivities; } } Loading Loading @@ -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; } } } } services/java/com/android/server/wm/DisplayContent.java +91 −0 Original line number Original line Diff line number Diff line Loading @@ -18,10 +18,12 @@ package com.android.server.wm; import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID; import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID; import static com.android.server.wm.WindowManagerService.DEBUG_STACK; import static com.android.server.wm.WindowManagerService.DEBUG_STACK; import static com.android.server.wm.WindowManagerService.DEBUG_VISIBILITY; import static com.android.server.wm.WindowManagerService.TAG; import static com.android.server.wm.WindowManagerService.TAG; import android.graphics.Rect; import android.graphics.Rect; import android.util.Slog; import android.util.Slog; import android.util.SparseArray; import android.view.Display; import android.view.Display; import android.view.DisplayInfo; import android.view.DisplayInfo; import android.view.InputChannel; import android.view.InputChannel; Loading Loading @@ -104,6 +106,8 @@ class DisplayContent { /** Detect user tapping outside of current focused stack bounds .*/ /** Detect user tapping outside of current focused stack bounds .*/ StackTapDetector mTapDetector; StackTapDetector mTapDetector; SparseArray<UserStacks> mUserStacks = new SparseArray<UserStacks>(); /** /** * @param display May not be null. * @param display May not be null. */ */ Loading Loading @@ -145,6 +149,22 @@ class DisplayContent { */ */ ArrayList<Task> getTasks() { ArrayList<Task> getTasks() { mTmpTasks.clear(); mTmpTasks.clear(); // First do the tasks belonging to other users. final int numUserStacks = mUserStacks.size(); for (int i = 0; i < numUserStacks; ++i) { UserStacks userStacks = mUserStacks.valueAt(i); ArrayList<TaskStack> stacks = userStacks.mSavedStackHistory; final int numStacks = stacks.size(); for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { TaskStack stack = stacks.get(stackNdx); if (stack != mHomeStack) { if (WindowManagerService.DEBUG_LAYERS) Slog.i(TAG, "getTasks: mStackHistory=" + mStackHistory); mTmpTasks.addAll(stack.getTasks()); } } } // Now do the current user's tasks. final int numStacks = mStackHistory.size(); final int numStacks = mStackHistory.size(); for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { mTmpTasks.addAll(mStackHistory.get(stackNdx).getTasks()); mTmpTasks.addAll(mStackHistory.get(stackNdx).getTasks()); Loading Loading @@ -292,6 +312,14 @@ class DisplayContent { return bounds; return bounds; } } } } // Not in the visible stacks, try the saved ones. for (int userNdx = mUserStacks.size() - 1; userNdx >= 0; --userNdx) { UserStacks userStacks = mUserStacks.valueAt(userNdx); Rect bounds = userStacks.mSavedStackBox.getStackBounds(stackId); if (bounds != null) { return bounds; } } return null; return null; } } Loading @@ -300,6 +328,26 @@ class DisplayContent { return topBox.stackIdFromPoint(x, y); return topBox.stackIdFromPoint(x, y); } } void switchUserStacks(int oldUserId, int newUserId) { final WindowList windows = getWindowList(); for (int i = 0; i < windows.size(); i++) { final WindowState win = windows.get(i); if (win.isHiddenFromUserLocked()) { if (DEBUG_VISIBILITY) Slog.w(TAG, "user changing " + newUserId + " hiding " + win + ", attrs=" + win.mAttrs.type + ", belonging to " + win.mOwnerUid); win.hideLw(false); } } // Clear the old user's non-home StackBox mUserStacks.put(oldUserId, new UserStacks()); UserStacks userStacks = mUserStacks.get(newUserId); if (userStacks != null) { userStacks.restore(); mUserStacks.delete(newUserId); } } public void dump(String prefix, PrintWriter pw) { public void dump(String prefix, PrintWriter pw) { pw.print(prefix); pw.print("Display: mDisplayId="); pw.println(mDisplayId); pw.print(prefix); pw.print("Display: mDisplayId="); pw.println(mDisplayId); final String subPrefix = " " + prefix; final String subPrefix = " " + prefix; Loading Loading @@ -365,6 +413,49 @@ class DisplayContent { token.dump(pw, " "); token.dump(pw, " "); } } } } if (mUserStacks.size() > 0) { pw.println(); pw.println(); pw.println(" Saved user stacks:"); for (int i = 0; i < mUserStacks.size(); ++i) { UserStacks userStacks = mUserStacks.valueAt(i); pw.print(" UserId="); pw.println(Integer.toHexString(mUserStacks.keyAt(i))); pw.print(" StackHistory="); pw.println(userStacks.mSavedStackHistory); pw.print(" StackBox="); userStacks.mSavedStackBox.dump(" ", pw); } } pw.println(); } private final class UserStacks { final ArrayList<TaskStack> mSavedStackHistory; StackBox mSavedStackBox; int mBoxNdx; public UserStacks() { mSavedStackHistory = new ArrayList<TaskStack>(mStackHistory); for (int stackNdx = mStackHistory.size() - 1; stackNdx >=0; --stackNdx) { if (mStackHistory.get(stackNdx) != mHomeStack) { mStackHistory.remove(stackNdx); } } mSavedStackBox = null; mBoxNdx = -1; for (int boxNdx = mStackBoxes.size() - 1; boxNdx >= 0; --boxNdx) { StackBox box = mStackBoxes.get(boxNdx); if (box.mStack != mHomeStack) { mSavedStackBox = box; mBoxNdx = boxNdx; mStackBoxes.remove(boxNdx); break; } } } void restore() { mStackHistory = mSavedStackHistory; if (mBoxNdx >= 0) { mStackBoxes.add(mBoxNdx, mSavedStackBox); } } } } } } services/java/com/android/server/wm/WindowManagerService.java +4 −10 Original line number Original line Diff line number Diff line Loading @@ -5094,22 +5094,16 @@ public class WindowManagerService extends IWindowManager.Stub public void setCurrentUser(final int newUserId) { public void setCurrentUser(final int newUserId) { synchronized (mWindowMap) { synchronized (mWindowMap) { int oldUserId = mCurrentUserId; mCurrentUserId = newUserId; mCurrentUserId = newUserId; mPolicy.setCurrentUserLw(newUserId); mPolicy.setCurrentUserLw(newUserId); // Hide windows that should not be seen by the new user. // Hide windows that should not be seen by the new user. DisplayContentsIterator iterator = new DisplayContentsIterator(); DisplayContentsIterator iterator = new DisplayContentsIterator(); while (iterator.hasNext()) { while (iterator.hasNext()) { final WindowList windows = iterator.next().getWindowList(); DisplayContent displayContent = iterator.next(); for (int i = 0; i < windows.size(); i++) { displayContent.switchUserStacks(oldUserId, newUserId); final WindowState win = windows.get(i); rebuildAppWindowListLocked(displayContent); if (win.isHiddenFromUserLocked()) { Slog.w(TAG, "current user violation " + newUserId + " hiding " + win + ", attrs=" + win.mAttrs.type + ", belonging to " + win.mOwnerUid); win.hideLw(false); } } } } performLayoutAndPlaceSurfacesLocked(); performLayoutAndPlaceSurfacesLocked(); } } Loading Loading
services/java/com/android/server/am/ActivityManagerService.java +14 −9 Original line number Original line Diff line number Diff line Loading @@ -4133,7 +4133,7 @@ public final class ActivityManagerService extends ActivityManagerNative } } } } if (mBooted) { if (mBooted) { mStackSupervisor.resumeTopActivityLocked(); mStackSupervisor.resumeTopActivitiesLocked(); mStackSupervisor.scheduleIdleLocked(); mStackSupervisor.scheduleIdleLocked(); } } } } Loading Loading @@ -4984,6 +4984,7 @@ public final class ActivityManagerService extends ActivityManagerNative } } } } @Override public void setProcessForeground(IBinder token, int pid, boolean isForeground) { public void setProcessForeground(IBinder token, int pid, boolean isForeground) { enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, "setProcessForeground()"); "setProcessForeground()"); Loading @@ -5007,6 +5008,7 @@ public final class ActivityManagerService extends ActivityManagerNative } } if (isForeground && token != null) { if (isForeground && token != null) { ForegroundToken newToken = new ForegroundToken() { ForegroundToken newToken = new ForegroundToken() { @Override public void binderDied() { public void binderDied() { foregroundTokenDied(this); foregroundTokenDied(this); } } Loading Loading @@ -5041,6 +5043,7 @@ public final class ActivityManagerService extends ActivityManagerNative mActivityManagerService = activityManagerService; mActivityManagerService = activityManagerService; } } @Override public boolean checkPermission(String permission, int pid, int uid) { public boolean checkPermission(String permission, int pid, int uid) { return mActivityManagerService.checkPermission(permission, pid, return mActivityManagerService.checkPermission(permission, pid, uid) == PackageManager.PERMISSION_GRANTED; uid) == PackageManager.PERMISSION_GRANTED; Loading @@ -5048,12 +5051,14 @@ public final class ActivityManagerService extends ActivityManagerNative } } class IntentFirewallInterface implements IntentFirewall.AMSInterface { class IntentFirewallInterface implements IntentFirewall.AMSInterface { @Override public int checkComponentPermission(String permission, int pid, int uid, public int checkComponentPermission(String permission, int pid, int uid, int owningUid, boolean exported) { int owningUid, boolean exported) { return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, owningUid, exported); owningUid, exported); } } @Override public Object getAMSLock() { public Object getAMSLock() { return ActivityManagerService.this; return ActivityManagerService.this; } } Loading Loading @@ -8281,7 +8286,7 @@ public final class ActivityManagerService extends ActivityManagerNative } finally { } finally { Binder.restoreCallingIdentity(ident); Binder.restoreCallingIdentity(ident); } } mStackSupervisor.resumeTopActivityLocked(); mStackSupervisor.resumeTopActivitiesLocked(); sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); } } } } Loading Loading @@ -8396,10 +8401,10 @@ public final class ActivityManagerService extends ActivityManagerNative // annoy the user repeatedly. Unless it is persistent, since those // annoy the user repeatedly. Unless it is persistent, since those // processes run critical code. // processes run critical code. removeProcessLocked(app, false, false, "crash"); removeProcessLocked(app, false, false, "crash"); mStackSupervisor.resumeTopActivityLocked(); mStackSupervisor.resumeTopActivitiesLocked(); return false; return false; } } mStackSupervisor.resumeTopActivityLocked(); mStackSupervisor.resumeTopActivitiesLocked(); } else { } else { mStackSupervisor.finishTopRunningActivityLocked(app); mStackSupervisor.finishTopRunningActivityLocked(app); } } Loading
services/java/com/android/server/am/ActivityStack.java +4 −6 Original line number Original line Diff line number Diff line Loading @@ -234,7 +234,7 @@ final class ActivityStack { int mThumbnailWidth = -1; int mThumbnailWidth = -1; int mThumbnailHeight = -1; int mThumbnailHeight = -1; private int mCurrentUser; int mCurrentUser; final int mStackId; final int mStackId; Loading Loading @@ -576,7 +576,8 @@ final class ActivityStack { } } /* /* * Move the activities around in the stack to bring a user to the foreground. * 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. * @return whether there are any activities for the specified user. * @return whether there are any activities for the specified user. */ */ final boolean switchUserLocked(int userId, UserStartedState uss) { final boolean switchUserLocked(int userId, UserStartedState uss) { Loading @@ -602,9 +603,6 @@ final class ActivityStack { } } } } // task is now the original topmost TaskRecord. Transition from the old top to the new top. ActivityRecord top = task != null ? task.getTopActivity() : null; resumeTopActivityLocked(top); return haveActivities; return haveActivities; } } Loading Loading @@ -1718,7 +1716,7 @@ final class ActivityStack { } } if (doResume) { if (doResume) { mStackSupervisor.resumeTopActivityLocked(); mStackSupervisor.resumeTopActivitiesLocked(); } } } } Loading
services/java/com/android/server/am/ActivityStackSupervisor.java +62 −22 Original line number Original line Diff line number Diff line Loading @@ -61,6 +61,7 @@ import android.os.SystemClock; import android.os.UserHandle; import android.os.UserHandle; import android.util.EventLog; import android.util.EventLog; import android.util.Slog; import android.util.Slog; import android.util.SparseArray; import com.android.internal.app.HeavyWeightSwitcherActivity; import com.android.internal.app.HeavyWeightSwitcherActivity; import com.android.server.am.ActivityManagerService.PendingActivityLaunch; import com.android.server.am.ActivityManagerService.PendingActivityLaunch; Loading Loading @@ -160,6 +161,9 @@ public class ActivityStackSupervisor { * is being brought in front of us. */ * is being brought in front of us. */ boolean mUserLeaving = false; 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, public ActivityStackSupervisor(ActivityManagerService service, Context context, Looper looper) { Looper looper) { mService = service; mService = service; Loading Loading @@ -213,6 +217,9 @@ public class ActivityStackSupervisor { } } boolean isFrontStack(ActivityStack stack) { boolean isFrontStack(ActivityStack stack) { if (stack.mCurrentUser != mCurrentUser) { return false; } return !(stack.isHomeStack() ^ getFocusedStack().isHomeStack()); return !(stack.isHomeStack() ^ getFocusedStack().isHomeStack()); } } Loading Loading @@ -319,6 +326,9 @@ public class ActivityStackSupervisor { final String processName = app.processName; final String processName = app.processName; for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { final ActivityStack stack = mStacks.get(stackNdx); final ActivityStack stack = mStacks.get(stackNdx); if (!isFrontStack(stack)) { continue; } ActivityRecord hr = stack.topRunningActivityLocked(null); ActivityRecord hr = stack.topRunningActivityLocked(null); if (hr != null) { if (hr != null) { if (hr.app == null && app.uid == hr.info.applicationInfo.uid if (hr.app == null && app.uid == hr.info.applicationInfo.uid Loading Loading @@ -449,6 +459,9 @@ public class ActivityStackSupervisor { } } for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { final ActivityStack stack = mStacks.get(stackNdx); final ActivityStack stack = mStacks.get(stackNdx); if (stack.mCurrentUser != mCurrentUser) { continue; } if (stack != mFocusedStack && isFrontStack(stack)) { if (stack != mFocusedStack && isFrontStack(stack)) { r = stack.topRunningActivityLocked(null); r = stack.topRunningActivityLocked(null); if (r != null) { if (r != null) { Loading Loading @@ -1145,8 +1158,14 @@ public class ActivityStackSupervisor { ActivityStack getCorrectStack(ActivityRecord r) { ActivityStack getCorrectStack(ActivityRecord r) { if (!r.isHomeActivity) { if (!r.isHomeActivity) { if (mStacks.size() == 1) { int stackNdx; // Time to create the first app stack. 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, int stackId = mService.createStack(-1, HOME_STACK_ID, StackBox.TASK_STACK_GOES_OVER, 1.0f); StackBox.TASK_STACK_GOES_OVER, 1.0f); mFocusedStack = getStack(stackId); mFocusedStack = getStack(stackId); Loading Loading @@ -1776,7 +1795,7 @@ public class ActivityStackSupervisor { return didSomething; return didSomething; } } void resumeTopActivityLocked() { void resumeTopActivitiesLocked() { for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { final ActivityStack stack = mStacks.get(stackNdx); final ActivityStack stack = mStacks.get(stackNdx); if (isFrontStack(stack)) { if (isFrontStack(stack)) { Loading Loading @@ -1816,7 +1835,6 @@ public class ActivityStackSupervisor { } } int createStack() { int createStack() { synchronized (this) { while (true) { while (true) { if (++mLastStackId <= HOME_STACK_ID) { if (++mLastStackId <= HOME_STACK_ID) { mLastStackId = HOME_STACK_ID + 1; mLastStackId = HOME_STACK_ID + 1; Loading @@ -1828,7 +1846,6 @@ public class ActivityStackSupervisor { mStacks.add(new ActivityStack(mService, mContext, mLooper, mLastStackId)); mStacks.add(new ActivityStack(mService, mContext, mLooper, mLastStackId)); return mLastStackId; return mLastStackId; } } } void moveTaskToStack(int taskId, int stackId, boolean toTop) { void moveTaskToStack(int taskId, int stackId, boolean toTop) { final ActivityStack stack = getStack(stackId); final ActivityStack stack = getStack(stackId); Loading Loading @@ -1938,16 +1955,22 @@ public class ActivityStackSupervisor { } } boolean switchUserLocked(int userId, UserStartedState uss) { boolean switchUserLocked(int userId, UserStartedState uss) { mUserStates.put(mCurrentUser, new UserState()); mCurrentUser = userId; mCurrentUser = userId; mStartingUsers.add(uss); UserState userState = mUserStates.get(userId); boolean haveActivities = false; if (userState != null) { final int numStacks = mStacks.size(); userState.restore(); for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { mUserStates.delete(userId); final ActivityStack stack = mStacks.get(stackNdx); } else { if (isFrontStack(stack)) { mFocusedStack = null; haveActivities |= stack.switchUserLocked(userId, uss); mStackState = STACK_STATE_HOME_IN_FRONT; } } } mStartingUsers.add(uss); boolean haveActivities = mHomeStack.switchUserLocked(userId, uss); resumeTopActivitiesLocked(); return haveActivities; return haveActivities; } } Loading Loading @@ -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; } } } }
services/java/com/android/server/wm/DisplayContent.java +91 −0 Original line number Original line Diff line number Diff line Loading @@ -18,10 +18,12 @@ package com.android.server.wm; import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID; import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID; import static com.android.server.wm.WindowManagerService.DEBUG_STACK; import static com.android.server.wm.WindowManagerService.DEBUG_STACK; import static com.android.server.wm.WindowManagerService.DEBUG_VISIBILITY; import static com.android.server.wm.WindowManagerService.TAG; import static com.android.server.wm.WindowManagerService.TAG; import android.graphics.Rect; import android.graphics.Rect; import android.util.Slog; import android.util.Slog; import android.util.SparseArray; import android.view.Display; import android.view.Display; import android.view.DisplayInfo; import android.view.DisplayInfo; import android.view.InputChannel; import android.view.InputChannel; Loading Loading @@ -104,6 +106,8 @@ class DisplayContent { /** Detect user tapping outside of current focused stack bounds .*/ /** Detect user tapping outside of current focused stack bounds .*/ StackTapDetector mTapDetector; StackTapDetector mTapDetector; SparseArray<UserStacks> mUserStacks = new SparseArray<UserStacks>(); /** /** * @param display May not be null. * @param display May not be null. */ */ Loading Loading @@ -145,6 +149,22 @@ class DisplayContent { */ */ ArrayList<Task> getTasks() { ArrayList<Task> getTasks() { mTmpTasks.clear(); mTmpTasks.clear(); // First do the tasks belonging to other users. final int numUserStacks = mUserStacks.size(); for (int i = 0; i < numUserStacks; ++i) { UserStacks userStacks = mUserStacks.valueAt(i); ArrayList<TaskStack> stacks = userStacks.mSavedStackHistory; final int numStacks = stacks.size(); for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { TaskStack stack = stacks.get(stackNdx); if (stack != mHomeStack) { if (WindowManagerService.DEBUG_LAYERS) Slog.i(TAG, "getTasks: mStackHistory=" + mStackHistory); mTmpTasks.addAll(stack.getTasks()); } } } // Now do the current user's tasks. final int numStacks = mStackHistory.size(); final int numStacks = mStackHistory.size(); for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { mTmpTasks.addAll(mStackHistory.get(stackNdx).getTasks()); mTmpTasks.addAll(mStackHistory.get(stackNdx).getTasks()); Loading Loading @@ -292,6 +312,14 @@ class DisplayContent { return bounds; return bounds; } } } } // Not in the visible stacks, try the saved ones. for (int userNdx = mUserStacks.size() - 1; userNdx >= 0; --userNdx) { UserStacks userStacks = mUserStacks.valueAt(userNdx); Rect bounds = userStacks.mSavedStackBox.getStackBounds(stackId); if (bounds != null) { return bounds; } } return null; return null; } } Loading @@ -300,6 +328,26 @@ class DisplayContent { return topBox.stackIdFromPoint(x, y); return topBox.stackIdFromPoint(x, y); } } void switchUserStacks(int oldUserId, int newUserId) { final WindowList windows = getWindowList(); for (int i = 0; i < windows.size(); i++) { final WindowState win = windows.get(i); if (win.isHiddenFromUserLocked()) { if (DEBUG_VISIBILITY) Slog.w(TAG, "user changing " + newUserId + " hiding " + win + ", attrs=" + win.mAttrs.type + ", belonging to " + win.mOwnerUid); win.hideLw(false); } } // Clear the old user's non-home StackBox mUserStacks.put(oldUserId, new UserStacks()); UserStacks userStacks = mUserStacks.get(newUserId); if (userStacks != null) { userStacks.restore(); mUserStacks.delete(newUserId); } } public void dump(String prefix, PrintWriter pw) { public void dump(String prefix, PrintWriter pw) { pw.print(prefix); pw.print("Display: mDisplayId="); pw.println(mDisplayId); pw.print(prefix); pw.print("Display: mDisplayId="); pw.println(mDisplayId); final String subPrefix = " " + prefix; final String subPrefix = " " + prefix; Loading Loading @@ -365,6 +413,49 @@ class DisplayContent { token.dump(pw, " "); token.dump(pw, " "); } } } } if (mUserStacks.size() > 0) { pw.println(); pw.println(); pw.println(" Saved user stacks:"); for (int i = 0; i < mUserStacks.size(); ++i) { UserStacks userStacks = mUserStacks.valueAt(i); pw.print(" UserId="); pw.println(Integer.toHexString(mUserStacks.keyAt(i))); pw.print(" StackHistory="); pw.println(userStacks.mSavedStackHistory); pw.print(" StackBox="); userStacks.mSavedStackBox.dump(" ", pw); } } pw.println(); } private final class UserStacks { final ArrayList<TaskStack> mSavedStackHistory; StackBox mSavedStackBox; int mBoxNdx; public UserStacks() { mSavedStackHistory = new ArrayList<TaskStack>(mStackHistory); for (int stackNdx = mStackHistory.size() - 1; stackNdx >=0; --stackNdx) { if (mStackHistory.get(stackNdx) != mHomeStack) { mStackHistory.remove(stackNdx); } } mSavedStackBox = null; mBoxNdx = -1; for (int boxNdx = mStackBoxes.size() - 1; boxNdx >= 0; --boxNdx) { StackBox box = mStackBoxes.get(boxNdx); if (box.mStack != mHomeStack) { mSavedStackBox = box; mBoxNdx = boxNdx; mStackBoxes.remove(boxNdx); break; } } } void restore() { mStackHistory = mSavedStackHistory; if (mBoxNdx >= 0) { mStackBoxes.add(mBoxNdx, mSavedStackBox); } } } } } }
services/java/com/android/server/wm/WindowManagerService.java +4 −10 Original line number Original line Diff line number Diff line Loading @@ -5094,22 +5094,16 @@ public class WindowManagerService extends IWindowManager.Stub public void setCurrentUser(final int newUserId) { public void setCurrentUser(final int newUserId) { synchronized (mWindowMap) { synchronized (mWindowMap) { int oldUserId = mCurrentUserId; mCurrentUserId = newUserId; mCurrentUserId = newUserId; mPolicy.setCurrentUserLw(newUserId); mPolicy.setCurrentUserLw(newUserId); // Hide windows that should not be seen by the new user. // Hide windows that should not be seen by the new user. DisplayContentsIterator iterator = new DisplayContentsIterator(); DisplayContentsIterator iterator = new DisplayContentsIterator(); while (iterator.hasNext()) { while (iterator.hasNext()) { final WindowList windows = iterator.next().getWindowList(); DisplayContent displayContent = iterator.next(); for (int i = 0; i < windows.size(); i++) { displayContent.switchUserStacks(oldUserId, newUserId); final WindowState win = windows.get(i); rebuildAppWindowListLocked(displayContent); if (win.isHiddenFromUserLocked()) { Slog.w(TAG, "current user violation " + newUserId + " hiding " + win + ", attrs=" + win.mAttrs.type + ", belonging to " + win.mOwnerUid); win.hideLw(false); } } } } performLayoutAndPlaceSurfacesLocked(); performLayoutAndPlaceSurfacesLocked(); } } Loading