Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1fb13c59 authored by Yohei Yukawa's avatar Yohei Yukawa
Browse files

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
      7f8ee4b9

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
parent 629271aa
Loading
Loading
Loading
Loading
+23 −1
Original line number Diff line number Diff line
@@ -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();
        }
+1 −1
Original line number Diff line number Diff line
@@ -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();
+2 −1
Original line number Diff line number Diff line
@@ -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;
+5 −3
Original line number Diff line number Diff line
@@ -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();
+8 −2
Original line number Diff line number Diff line
@@ -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