diff options
| author | 2019-02-05 07:55:28 -0800 | |
|---|---|---|
| committer | 2019-02-05 07:55:28 -0800 | |
| commit | 1fb13c59dea3c29aaed5d3e2155ce4acba7b7f7c (patch) | |
| tree | 48c6e60880a1e239f4527b275691a2893b5b60b4 | |
| parent | 629271aa85327dca1bf800a55f48f606dbf504ba (diff) | |
Query right user's enabled IMEs in KeyguardPasswordView
This CL fixes a regression introduced by my previous CL [1], which
enabled InputMethodManager#getEnabledInputMethodList() to return the
result based on the caller's user ID, not based on the current IME
user, even when it gets called from background users.
Since Keyguard always runs as user 0 currently, it is now Keyguard's
responsibility for querying enabled IMEs with an explicit user ID.  To
do so this CL adds a @hide API IMM#getEnabledInputMethodListAsUser()
and lets KeyguardPasswordView use it.
 [1]: I192a0f5a1375170d17a4c08af94f23966dbaea8b
      7f8ee4b9ddd31ad36a12c5278b27990dc76011cc
Bug: 122164939
Fix: 123904896
Test: Manually verified as follows.
  1. Build aosp_taimen-userdebug and flash it.
  2. make -j SoftKeyboard
  3. adb install -r $OUT/system/app/SoftKeyboard/SoftKeyboard.apk
  4. adb shell ime enable com.example.android.softkeyboard/.SoftKeyboard
  5. adb shell pm create-user test_user
  6. adb shell am switch-user 10
  7. adb shell locksettings set-password aaaa
  8. adb shell wm dismiss-keyguard
  9. Make sure that the IME switcher icon is not shown at the right
     end of the password field.
Change-Id: I6e7d7353c2b5b1da5d460ae005fb2585f85fb1c4
5 files changed, 39 insertions, 8 deletions
| diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java index 8c770adcf2b5..18f757c07369 100644 --- a/core/java/android/view/inputmethod/InputMethodManager.java +++ b/core/java/android/view/inputmethod/InputMethodManager.java @@ -16,6 +16,7 @@  package android.view.inputmethod; +import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;  import static android.Manifest.permission.WRITE_SECURE_SETTINGS;  import android.annotation.DrawableRes; @@ -26,6 +27,7 @@ import android.annotation.RequiresPermission;  import android.annotation.SystemService;  import android.annotation.TestApi;  import android.annotation.UnsupportedAppUsage; +import android.annotation.UserIdInt;  import android.app.ActivityThread;  import android.content.ComponentName;  import android.content.ContentResolver; @@ -46,6 +48,7 @@ import android.os.ResultReceiver;  import android.os.ServiceManager;  import android.os.ServiceManager.ServiceNotFoundException;  import android.os.Trace; +import android.os.UserHandle;  import android.provider.Settings;  import android.text.style.SuggestionSpan;  import android.util.Log; @@ -978,7 +981,26 @@ public final class InputMethodManager {       */      public List<InputMethodInfo> getEnabledInputMethodList() {          try { -            return mService.getEnabledInputMethodList(); +            // We intentionally do not use UserHandle.getCallingUserId() here because for system +            // services InputMethodManagerInternal.getEnabledInputMethodListAsUser() should be used +            // instead. +            return mService.getEnabledInputMethodList(UserHandle.myUserId()); +        } catch (RemoteException e) { +            throw e.rethrowFromSystemServer(); +        } +    } + +    /** +     * Returns the list of enabled 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<InputMethodInfo> getEnabledInputMethodListAsUser(@UserIdInt int userId) { +        try { +            return mService.getEnabledInputMethodList(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 0752efe562a9..98e854cc40a2 100644 --- a/core/java/com/android/internal/view/IInputMethodManager.aidl +++ b/core/java/com/android/internal/view/IInputMethodManager.aidl @@ -36,7 +36,7 @@ interface IInputMethodManager {      // TODO: Use ParceledListSlice instead      List<InputMethodInfo> getInputMethodList();      // TODO: Use ParceledListSlice instead -    List<InputMethodInfo> getEnabledInputMethodList(); +    List<InputMethodInfo> getEnabledInputMethodList(int userId);      List<InputMethodSubtype> getEnabledInputMethodSubtypeList(in String imiId,              boolean allowsImplicitlySelectedSubtypes);      InputMethodSubtype getLastInputMethodSubtype(); diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordView.java index 64c5b1754fa8..261f391839b3 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordView.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordView.java @@ -264,7 +264,8 @@ public class KeyguardPasswordView extends KeyguardAbsKeyInputView       */      private boolean hasMultipleEnabledIMEsOrSubtypes(InputMethodManager imm,              final boolean shouldIncludeAuxiliarySubtypes) { -        final List<InputMethodInfo> enabledImis = imm.getEnabledInputMethodList(); +        final List<InputMethodInfo> enabledImis = +                imm.getEnabledInputMethodListAsUser(KeyguardUpdateMonitor.getCurrentUser());          // Number of the filtered IMEs          int filteredImisCount = 0; diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java index 9d9721d5d402..f0dce78722a2 100644 --- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java +++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java @@ -1645,10 +1645,12 @@ public class InputMethodManagerService extends IInputMethodManager.Stub      }      @Override -    public List<InputMethodInfo> getEnabledInputMethodList() { -        final int callingUserId = UserHandle.getCallingUserId(); +    public List<InputMethodInfo> getEnabledInputMethodList(@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 3222143fc89f..109024d0d2f7 100644 --- a/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java +++ b/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java @@ -16,6 +16,7 @@  package com.android.server.inputmethod; +import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;  import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;  import static java.lang.annotation.RetentionPolicy.SOURCE; @@ -1195,6 +1196,7 @@ public final class MultiClientInputMethodManagerService {       * Takes care of IPCs exposed to the IME client.       */      private static final class ApiCallbacks extends IInputMethodManager.Stub { +        private final Context mContext;          private final UserDataMap mUserDataMap;          private final UserToInputMethodInfoMap mInputMethodInfoMap;          private final AppOpsManager mAppOpsManager; @@ -1202,6 +1204,7 @@ public final class MultiClientInputMethodManagerService {          ApiCallbacks(Context context, UserDataMap userDataMap,                  UserToInputMethodInfoMap inputMethodInfoMap) { +            mContext = context;              mUserDataMap = userDataMap;              mInputMethodInfoMap = inputMethodInfoMap;              mAppOpsManager = context.getSystemService(AppOpsManager.class); @@ -1239,8 +1242,11 @@ public final class MultiClientInputMethodManagerService {          @BinderThread          @Override -        public List<InputMethodInfo> getEnabledInputMethodList() { -            return mInputMethodInfoMap.getAsList(UserHandle.getUserId(Binder.getCallingUid())); +        public List<InputMethodInfo> getEnabledInputMethodList(@UserIdInt int userId) { +            if (UserHandle.getCallingUserId() != userId) { +                mContext.enforceCallingPermission(INTERACT_ACROSS_USERS_FULL, null); +            } +            return mInputMethodInfoMap.getAsList(userId);          }          @BinderThread |