summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--core/java/com/android/internal/inputmethod/InputMethodUtils.java17
-rw-r--r--services/core/java/com/android/server/InputMethodManagerService.java22
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java20
-rwxr-xr-xservices/core/java/com/android/server/am/ActivityStack.java27
-rw-r--r--services/core/java/com/android/server/am/TaskRecord.java2
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java30
-rw-r--r--services/core/java/com/android/server/wm/WindowState.java2
7 files changed, 104 insertions, 16 deletions
diff --git a/core/java/com/android/internal/inputmethod/InputMethodUtils.java b/core/java/com/android/internal/inputmethod/InputMethodUtils.java
index bc051ce..03a053c 100644
--- a/core/java/com/android/internal/inputmethod/InputMethodUtils.java
+++ b/core/java/com/android/internal/inputmethod/InputMethodUtils.java
@@ -504,6 +504,7 @@ public class InputMethodUtils {
private String mEnabledInputMethodsStrCache;
private int mCurrentUserId;
+ private int[] mRelatedUserIds = new int[0];
private static void buildEnabledInputMethodsSettingString(
StringBuilder builder, Pair<String, ArrayList<String>> pair) {
@@ -536,6 +537,22 @@ public class InputMethodUtils {
mCurrentUserId = userId;
}
+ public void setRelatedUserIds(int[] relatedUserIds) {
+ synchronized (this) {
+ mRelatedUserIds = relatedUserIds;
+ }
+ }
+
+ public boolean isRelatedToOrCurrentUser(int userId) {
+ synchronized (this) {
+ if (userId == mCurrentUserId) return true;
+ for (int i = 0; i < mRelatedUserIds.length; i++) {
+ if (userId == mRelatedUserIds[i]) return true;
+ }
+ return false;
+ }
+ }
+
public List<InputMethodInfo> getEnabledInputMethodListLocked() {
return createEnabledInputMethodListLocked(
getEnabledInputMethodsAndSubtypeListLocked());
diff --git a/services/core/java/com/android/server/InputMethodManagerService.java b/services/core/java/com/android/server/InputMethodManagerService.java
index 0b3eb12..6827b3f 100644
--- a/services/core/java/com/android/server/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/InputMethodManagerService.java
@@ -59,6 +59,7 @@ import android.content.pm.IPackageManager;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
+import android.content.pm.UserInfo;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.content.res.TypedArray;
@@ -78,6 +79,7 @@ import android.os.ResultReceiver;
import android.os.ServiceManager;
import android.os.SystemClock;
import android.os.UserHandle;
+import android.os.UserManager;
import android.provider.Settings;
import android.text.TextUtils;
import android.text.style.SuggestionSpan;
@@ -441,6 +443,10 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
hideInputMethodMenu();
// No need to updateActive
return;
+ } else if (Intent.ACTION_USER_ADDED.equals(action)
+ || Intent.ACTION_USER_REMOVED.equals(action)) {
+ updateRelatedUserIds();
+ return;
} else {
Slog.w(TAG, "Unexpected intent " + intent);
}
@@ -642,6 +648,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
broadcastFilter.addAction(Intent.ACTION_SCREEN_ON);
broadcastFilter.addAction(Intent.ACTION_SCREEN_OFF);
broadcastFilter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
+ broadcastFilter.addAction(Intent.ACTION_USER_ADDED);
+ broadcastFilter.addAction(Intent.ACTION_USER_REMOVED);
mContext.registerReceiver(new ImmsBroadcastReceiver(), broadcastFilter);
mNotificationShown = false;
@@ -675,6 +683,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
// mSettings should be created before buildInputMethodListLocked
mSettings = new InputMethodSettings(
mRes, context.getContentResolver(), mMethodMap, mMethodList, userId);
+ updateRelatedUserIds();
mFileManager = new InputMethodFileManager(mMethodMap, userId);
mSwitchingController = new InputMethodSubtypeSwitchingController(mSettings);
mSwitchingController.resetCircularListLocked(context);
@@ -790,6 +799,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
private void switchUserLocked(int newUserId) {
mSettings.setCurrentUserId(newUserId);
+ updateRelatedUserIds();
// InputMethodFileManager should be reset when the user is changed
mFileManager = new InputMethodFileManager(mMethodMap, newUserId);
final String defaultImiId = mSettings.getSelectedInputMethod();
@@ -810,6 +820,16 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
}
}
+ void updateRelatedUserIds() {
+ List<UserInfo> relatedUsers =
+ UserManager.get(mContext).getRelatedUsers(mSettings.getCurrentUserId());
+ int[] relatedUserIds = new int[relatedUsers.size()]; // relatedUsers will not be null
+ for (int i = 0; i < relatedUserIds.length; i++) {
+ relatedUserIds[i] = relatedUsers.get(i).id;
+ }
+ mSettings.setRelatedUserIds(relatedUserIds);
+ }
+
@Override
public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
throws RemoteException {
@@ -905,7 +925,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
+ mSettings.getCurrentUserId() + ", calling pid = " + Binder.getCallingPid()
+ InputMethodUtils.getApiCallStack());
}
- if (uid == Process.SYSTEM_UID || userId == mSettings.getCurrentUserId()) {
+ if (uid == Process.SYSTEM_UID || mSettings.isRelatedToOrCurrentUser(userId)) {
return true;
}
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 782868e..f39e634 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -1015,6 +1015,7 @@ public final class ActivityManagerService extends ActivityManagerNative
final ActivityThread mSystemThread;
int mCurrentUserId = 0;
+ int[] mRelatedUserIds = new int[0]; // Accessed by ActivityStack
private UserManagerService mUserManager;
private final class AppDeathRecipient implements IBinder.DeathRecipient {
@@ -16097,6 +16098,20 @@ public final class ActivityManagerService extends ActivityManagerNative
return startUser(userId, /* foreground */ false);
}
+ /**
+ * Refreshes the list of users related to the current user when either a
+ * user switch happens or when a new related user is started in the
+ * background.
+ */
+ private void updateRelatedUserIdsLocked() {
+ final List<UserInfo> relatedUsers = getUserManagerLocked().getRelatedUsers(mCurrentUserId);
+ int[] relatedUserIds = new int[relatedUsers.size()]; // relatedUsers will not be null
+ for (int i = 0; i < relatedUserIds.length; i++) {
+ relatedUserIds[i] = relatedUsers.get(i).id;
+ }
+ mRelatedUserIds = relatedUserIds;
+ }
+
@Override
public boolean switchUser(final int userId) {
return startUser(userId, /* foregound */ true);
@@ -16150,12 +16165,15 @@ public final class ActivityManagerService extends ActivityManagerNative
if (foreground) {
mCurrentUserId = userId;
- mWindowManager.setCurrentUser(userId);
+ updateRelatedUserIdsLocked();
+ mWindowManager.setCurrentUser(userId, mRelatedUserIds);
// Once the internal notion of the active user has switched, we lock the device
// with the option to show the user switcher on the keyguard.
mWindowManager.lockNow(null);
} else {
final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
+ updateRelatedUserIdsLocked();
+ mWindowManager.updateRelatedUserIds(mRelatedUserIds);
mUserLru.remove(currentUserIdInt);
mUserLru.add(currentUserIdInt);
}
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index 922cef4..f3ccdd6 100755
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -341,8 +341,19 @@ final class ActivityStack {
mCurrentUser = mService.mCurrentUserId;
}
- boolean okToShow(ActivityRecord r) {
- return r.userId == mCurrentUser
+ /**
+ * Checks whether the userid is either the current user or a related user.
+ */
+ private boolean isRelatedToOrCurrentUserLocked(int userId) {
+ if (mCurrentUser == userId) return true;
+ for (int i = 0; i < mService.mRelatedUserIds.length; i++) {
+ if (mService.mRelatedUserIds[i] == userId) return true;
+ }
+ return false;
+ }
+
+ boolean okToShowLocked(ActivityRecord r) {
+ return isRelatedToOrCurrentUserLocked(r.userId)
|| (r.info.flags & ActivityInfo.FLAG_SHOW_ON_LOCK_SCREEN) != 0;
}
@@ -362,7 +373,7 @@ final class ActivityStack {
final ArrayList<ActivityRecord> activities = task.mActivities;
for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
ActivityRecord r = activities.get(activityNdx);
- if (!r.finishing && !r.delayedResume && r != notTop && okToShow(r)) {
+ if (!r.finishing && !r.delayedResume && r != notTop && okToShowLocked(r)) {
return r;
}
}
@@ -389,7 +400,7 @@ final class ActivityStack {
for (int i = activities.size() - 1; i >= 0; --i) {
final ActivityRecord r = activities.get(i);
// Note: the taskId check depends on real taskId fields being non-zero
- if (!r.finishing && (token != r.appToken) && okToShow(r)) {
+ if (!r.finishing && (token != r.appToken) && okToShowLocked(r)) {
return r;
}
}
@@ -542,7 +553,7 @@ final class ActivityStack {
for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
TaskRecord task = mTaskHistory.get(taskNdx);
- if (task.userId != mCurrentUser) {
+ if (!isRelatedToOrCurrentUserLocked(task.userId)) {
return null;
}
final ArrayList<ActivityRecord> activities = task.mActivities;
@@ -573,7 +584,7 @@ final class ActivityStack {
int index = mTaskHistory.size();
for (int i = 0; i < index; ) {
TaskRecord task = mTaskHistory.get(i);
- if (task.userId == userId) {
+ if (isRelatedToOrCurrentUserLocked(task.userId)) {
if (DEBUG_TASKS) Slog.d(TAG, "switchUserLocked: stack=" + getStackId() +
" moving " + task + " to top");
mTaskHistory.remove(i);
@@ -1728,10 +1739,10 @@ final class ActivityStack {
mTaskHistory.remove(task);
// Now put task at top.
int stackNdx = mTaskHistory.size();
- if (task.userId != mCurrentUser) {
+ if (!isRelatedToOrCurrentUserLocked(task.userId)) {
// Put non-current user tasks below current user tasks.
while (--stackNdx >= 0) {
- if (mTaskHistory.get(stackNdx).userId != mCurrentUser) {
+ if (!isRelatedToOrCurrentUserLocked(mTaskHistory.get(stackNdx).userId)) {
break;
}
}
diff --git a/services/core/java/com/android/server/am/TaskRecord.java b/services/core/java/com/android/server/am/TaskRecord.java
index 9740812..3a43521 100644
--- a/services/core/java/com/android/server/am/TaskRecord.java
+++ b/services/core/java/com/android/server/am/TaskRecord.java
@@ -153,7 +153,7 @@ final class TaskRecord extends ThumbnailHolder {
ActivityRecord topRunningActivityLocked(ActivityRecord notTop) {
for (int activityNdx = mActivities.size() - 1; activityNdx >= 0; --activityNdx) {
ActivityRecord r = mActivities.get(activityNdx);
- if (!r.finishing && r != notTop && stack.okToShow(r)) {
+ if (!r.finishing && r != notTop && stack.okToShowLocked(r)) {
return r;
}
}
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index c006613..be94ca7 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -19,7 +19,6 @@ package com.android.server.wm;
import static android.view.WindowManager.LayoutParams.*;
import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
-
import android.app.AppOpsManager;
import android.util.ArraySet;
import android.util.TimeUtils;
@@ -302,8 +301,16 @@ public class WindowManagerService extends IWindowManager.Stub
}
};
- // Current user when multi-user is enabled. Don't show windows of non-current user.
+ /**
+ * Current user when multi-user is enabled. Don't show windows of
+ * non-current user. Also see mRelatedUserIds.
+ */
int mCurrentUserId;
+ /**
+ * Users related to the current user. These are also allowed to show windows
+ * on the current user.
+ */
+ int[] mRelatedUserIds = new int[0];
final Context mContext;
@@ -5284,10 +5291,16 @@ public class WindowManagerService extends IWindowManager.Stub
mPolicy.setTouchExplorationEnabled(enabled);
}
- public void setCurrentUser(final int newUserId) {
+ public void updateRelatedUserIds(final int[] relatedUserIds) {
+ synchronized (mWindowMap) {
+ mRelatedUserIds = relatedUserIds;
+ }
+ }
+
+ public void setCurrentUser(final int newUserId, final int[] relatedUserIds) {
synchronized (mWindowMap) {
- int oldUserId = mCurrentUserId;
mCurrentUserId = newUserId;
+ mRelatedUserIds = relatedUserIds;
mAppTransition.setCurrentUser(newUserId);
mPolicy.setCurrentUserLw(newUserId);
@@ -5302,6 +5315,15 @@ public class WindowManagerService extends IWindowManager.Stub
}
}
+ /* Called by WindowState */
+ boolean isRelatedToOrCurrentUserLocked(int userId) {
+ if (userId == mCurrentUserId) return true;
+ for (int i = 0; i < mRelatedUserIds.length; i++) {
+ if (mRelatedUserIds[i] == userId) return true;
+ }
+ return false;
+ }
+
public void enableScreenAfterBoot() {
synchronized(mWindowMap) {
if (DEBUG_BOOT) {
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index a8e45c4..2c0e99e 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -1249,7 +1249,7 @@ final class WindowState implements WindowManagerPolicy.WindowState {
}
return win.mShowToOwnerOnly
- && UserHandle.getUserId(win.mOwnerUid) != mService.mCurrentUserId;
+ && !mService.isRelatedToOrCurrentUserLocked(UserHandle.getUserId(win.mOwnerUid));
}
private static void applyInsets(Region outRegion, Rect frame, Rect inset) {