summaryrefslogtreecommitdiffstats
path: root/services/core/java
diff options
context:
space:
mode:
authorAmith Yamasani <yamasani@google.com>2014-03-04 16:48:05 -0800
committerAmith Yamasani <yamasani@google.com>2014-03-07 17:41:24 -0800
commit734983fff35d9ed2b7a9848bdfbca401887d0dd8 (patch)
tree0f7514529fe469f5e1b1586cd9306b785fb3fcc6 /services/core/java
parent16340670aff0ec980fff4354d785a38b11c33d3b (diff)
downloadframeworks_base-734983fff35d9ed2b7a9848bdfbca401887d0dd8.zip
frameworks_base-734983fff35d9ed2b7a9848bdfbca401887d0dd8.tar.gz
frameworks_base-734983fff35d9ed2b7a9848bdfbca401887d0dd8.tar.bz2
Allow related users to show activities on primary user
Make ActivityManager and WindowManager understand related users. Task stack will now contain interleaved tasks for related users, but still group regular users separately from groups of related users. InputMethodManagerService permits related users to invoke IME and receive key events. Change-Id: I3bd87b32aec69c3f8d470c8b29b144f4e849c808
Diffstat (limited to 'services/core/java')
-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
6 files changed, 87 insertions, 16 deletions
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) {