From d20eef826c879c3be3be1d22322e51ee92880561 Mon Sep 17 00:00:00 2001 From: Yohei Yukawa Date: Tue, 5 Feb 2019 10:45:32 -0800 Subject: [PATCH] Query right user's system IMEs in AppRestrictionsHelper It turns out that AppRestrictionsHelper#addSystemImes() has always queried for the owner user's system IMEs despite the fact that it's trying to query system IMEs for a restricted profile user. This behavior has not changed since its beginning [1]. Most likely people would not have noticed this though, because: * Settings app does not show a menu item to create a restricted user on phone devices. * Even if it's available, most people do not use restricted users. * Even if someone created a restrected user, most likely the owner user and the restrected user share the same set of system IMEs, which are defined as "pre-installed" IMEs. Anyway, AppRestrictionsHelper#addSystemImes() will start using a newly introduced @hide API IMM#getEnabledInputMethodListAsUser() so that it can query for the right user's system IMEs, instead of querying owner user's ones. [1]: Ifced841ad3bfbde33d2403356216dd1749b7fa9a a7a93784d1f9798d37cb618def1a558f8d626f0f Bug: 122164939 Test: atest SettingsLibTests:AppRestrictionsHelperTest Test: manually done as follows. 1. Build aosp_taimen-userdebug and flash it. 2. adb shell pm create-user --restricted test_profile 3. adb shell am start -a android.settings.USER_SETTINGS 4. Click the gear icon next to the "test_profile" user. 5. By adding a log, make sure that IMMS#getInputMethodList() gets called with userId = 10. Change-Id: I5b50b5fe143c74c87b331bda3e5bcc4d6248436e --- .../view/inputmethod/InputMethodManager.java | 21 ++++++++++++++++++- .../internal/view/IInputMethodManager.aidl | 2 +- .../users/AppRestrictionsHelper.java | 2 +- .../InputMethodManagerService.java | 8 ++++--- .../MultiClientInputMethodManagerService.java | 7 +++++-- 5 files changed, 32 insertions(+), 8 deletions(-) diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java index 18f757c073696..aee4b1f638129 100644 --- a/core/java/android/view/inputmethod/InputMethodManager.java +++ b/core/java/android/view/inputmethod/InputMethodManager.java @@ -966,7 +966,26 @@ public final class InputMethodManager { */ public List getInputMethodList() { try { - return mService.getInputMethodList(); + // We intentionally do not use UserHandle.getCallingUserId() here because for system + // services InputMethodManagerInternal.getInputMethodListAsUser() should be used + // instead. + return mService.getInputMethodList(UserHandle.myUserId()); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** + * Returns the list of installed input methods for the specified user. + * + * @param userId user ID to query + * @return {@link List} of {@link InputMethodInfo}. + * @hide + */ + @RequiresPermission(INTERACT_ACROSS_USERS_FULL) + public List getInputMethodListAsUser(@UserIdInt int userId) { + try { + return mService.getInputMethodList(userId); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } diff --git a/core/java/com/android/internal/view/IInputMethodManager.aidl b/core/java/com/android/internal/view/IInputMethodManager.aidl index 98e854cc40a27..cb18ca1fb7fe3 100644 --- a/core/java/com/android/internal/view/IInputMethodManager.aidl +++ b/core/java/com/android/internal/view/IInputMethodManager.aidl @@ -34,7 +34,7 @@ interface IInputMethodManager { int untrustedDisplayId); // TODO: Use ParceledListSlice instead - List getInputMethodList(); + List getInputMethodList(int userId); // TODO: Use ParceledListSlice instead List getEnabledInputMethodList(int userId); List getEnabledInputMethodSubtypeList(in String imiId, diff --git a/packages/SettingsLib/src/com/android/settingslib/users/AppRestrictionsHelper.java b/packages/SettingsLib/src/com/android/settingslib/users/AppRestrictionsHelper.java index 9451b36204180..ec8bb80bee131 100644 --- a/packages/SettingsLib/src/com/android/settingslib/users/AppRestrictionsHelper.java +++ b/packages/SettingsLib/src/com/android/settingslib/users/AppRestrictionsHelper.java @@ -420,7 +420,7 @@ public class AppRestrictionsHelper { List getInputMethodList() { InputMethodManager imm = (InputMethodManager) getContext().getSystemService( Context.INPUT_METHOD_SERVICE); - return imm.getInputMethodList(); + return imm.getInputMethodListAsUser(mUser.getIdentifier()); } } } diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java index f0dce78722a2b..144f2b6b143fa 100644 --- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java +++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java @@ -1627,10 +1627,12 @@ public class InputMethodManagerService extends IInputMethodManager.Stub } @Override - public List getInputMethodList() { - final int callingUserId = UserHandle.getCallingUserId(); + public List getInputMethodList(@UserIdInt int userId) { + if (UserHandle.getCallingUserId() != userId) { + mContext.enforceCallingPermission(Manifest.permission.INTERACT_ACROSS_USERS_FULL, null); + } synchronized (mMethodMap) { - final int[] resolvedUserIds = InputMethodUtils.resolveUserId(callingUserId, + final int[] resolvedUserIds = InputMethodUtils.resolveUserId(userId, mSettings.getCurrentUserId(), null); if (resolvedUserIds.length != 1) { return Collections.emptyList(); diff --git a/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java index 109024d0d2f74..500c388ec99eb 100644 --- a/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java +++ b/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java @@ -1236,8 +1236,11 @@ public final class MultiClientInputMethodManagerService { @BinderThread @Override - public List getInputMethodList() { - return mInputMethodInfoMap.getAsList(UserHandle.getUserId(Binder.getCallingUid())); + public List getInputMethodList(@UserIdInt int userId) { + if (UserHandle.getCallingUserId() != userId) { + mContext.enforceCallingPermission(INTERACT_ACROSS_USERS_FULL, null); + } + return mInputMethodInfoMap.getAsList(userId); } @BinderThread