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

Commit a9cec4c2 authored by Yohei Yukawa's avatar Yohei Yukawa Committed by Android (Google) Code Review
Browse files

Merge "Prepare to make InputMethodSubtypeSwitchingController per-user" into main

parents 2adf72c4 46e75da5
Loading
Loading
Loading
Loading
+28 −16
Original line number Diff line number Diff line
@@ -321,7 +321,9 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
    @GuardedBy("ImfLock.class")
    private final SparseArray<String> mVirtualDeviceMethodMap = new SparseArray<>();

    private final InputMethodSubtypeSwitchingController mSwitchingController;
    // TODO: Instantiate mSwitchingController for each user.
    @NonNull
    private InputMethodSubtypeSwitchingController mSwitchingController;
    final HardwareKeyboardShortcutController mHardwareKeyboardShortcutController =
            new HardwareKeyboardShortcutController();

@@ -1705,7 +1707,8 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub

        AdditionalSubtypeUtils.load(mAdditionalSubtypeMap, userId);
        mSwitchingController =
                InputMethodSubtypeSwitchingController.createInstanceLocked(mSettings, context);
                InputMethodSubtypeSwitchingController.createInstanceLocked(context, mMethodMap,
                        userId);
        mHardwareKeyboardShortcutController.reset(mSettings);
        mMenuController = new InputMethodMenuController(this);
        mBindingController =
@@ -3294,13 +3297,16 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
            // There is no longer an input method set, so stop any current one.
            resetCurrentMethodAndClientLocked(UnbindReason.NO_IME);
        }
        // Here is not the perfect place to reset the switching controller. Ideally
        // mSwitchingController and mSettings should be able to share the same state.
        // TODO: Make sure that mSwitchingController and mSettings are sharing the
        // the same enabled IMEs list.
        mSwitchingController.resetCircularListLocked(mContext);
        mHardwareKeyboardShortcutController.reset(mSettings);

        // TODO: Instantiate mSwitchingController for each user.
        if (mSettings.getCurrentUserId() == mSwitchingController.getUserId()) {
            mSwitchingController.resetCircularListLocked(mMethodMap);
        } else {
            mSwitchingController = InputMethodSubtypeSwitchingController.createInstanceLocked(
                    mContext, mMethodMap, mSettings.getCurrentUserId());
        }

        mHardwareKeyboardShortcutController.reset(mSettings);
        sendOnNavButtonFlagsChangedLocked();
    }

@@ -4687,6 +4693,9 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
                }
                return;
            }
            if (mSettings.getCurrentUserId() != mSwitchingController.getUserId()) {
                return;
            }
            final InputMethodInfo imi = mMethodMap.get(getSelectedMethodIdLocked());
            if (imi != null) {
                mSwitchingController.onUserActionLocked(imi, mCurrentSubtype);
@@ -4924,9 +4933,10 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
                    int lastInputMethodSubtypeId =
                            mSettings.getSelectedInputMethodSubtypeId(lastInputMethodId);

                    final List<ImeSubtypeListItem> imList = mSwitchingController
                            .getSortedInputMethodAndSubtypeListForImeMenuLocked(
                                    showAuxSubtypes, isScreenLocked);
                    final List<ImeSubtypeListItem> imList = InputMethodSubtypeSwitchingController
                            .getSortedInputMethodAndSubtypeList(
                                    showAuxSubtypes, isScreenLocked, false, mContext,
                                    mMethodMap, mSettings.getCurrentUserId());
                    mMenuController.showInputMethodMenuLocked(showAuxSubtypes, displayId,
                            lastInputMethodId, lastInputMethodSubtypeId, imList);
                }
@@ -5311,11 +5321,13 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub

        updateDefaultVoiceImeIfNeededLocked();

        // Here is not the perfect place to reset the switching controller. Ideally
        // mSwitchingController and mSettings should be able to share the same state.
        // TODO: Make sure that mSwitchingController and mSettings are sharing the
        // the same enabled IMEs list.
        mSwitchingController.resetCircularListLocked(mContext);
        // TODO: Instantiate mSwitchingController for each user.
        if (mSettings.getCurrentUserId() == mSwitchingController.getUserId()) {
            mSwitchingController.resetCircularListLocked(mMethodMap);
        } else {
            mSwitchingController = InputMethodSubtypeSwitchingController.createInstanceLocked(
                    mContext, mMethodMap, mSettings.getCurrentUserId());
        }
        mHardwareKeyboardShortcutController.reset(mSettings);

        sendOnNavButtonFlagsChangedLocked();
+87 −84
Original line number Diff line number Diff line
@@ -16,10 +16,14 @@

package com.android.server.inputmethod;

import android.annotation.AnyThread;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UserIdInt;
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.UserHandle;
import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.Printer;
import android.util.Slog;
@@ -32,7 +36,6 @@ import com.android.server.inputmethod.InputMethodUtils.InputMethodSettings;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.Objects;

/**
@@ -154,24 +157,17 @@ final class InputMethodSubtypeSwitchingController {
        }
    }

    private static class InputMethodAndSubtypeList {
        private final Context mContext;
        // Used to load label
        private final PackageManager mPm;
        private final String mSystemLocaleStr;
        private final InputMethodSettings mSettings;

        InputMethodAndSubtypeList(Context context, InputMethodSettings settings) {
            mContext = context;
            mSettings = settings;
            mPm = context.getPackageManager();
            final Locale locale = context.getResources().getConfiguration().locale;
            mSystemLocaleStr = locale != null ? locale.toString() : "";
        }
    static List<ImeSubtypeListItem> getSortedInputMethodAndSubtypeList(
            boolean includeAuxiliarySubtypes, boolean isScreenLocked, boolean forImeMenu,
            @NonNull Context context, @NonNull ArrayMap<String, InputMethodInfo> methodMap,
            @UserIdInt int userId) {
        final Context userAwareContext = context.getUserId() == userId
                ? context
                : context.createContextAsUser(UserHandle.of(userId), 0 /* flags */);
        final String mSystemLocaleStr = SystemLocaleWrapper.get(userId).get(0).toLanguageTag();
        final InputMethodSettings settings = new InputMethodSettings(methodMap, userId);

        public List<ImeSubtypeListItem> getSortedInputMethodAndSubtypeList(
                boolean includeAuxiliarySubtypes, boolean isScreenLocked, boolean forImeMenu) {
            final ArrayList<InputMethodInfo> imis = mSettings.getEnabledInputMethodListLocked();
        final ArrayList<InputMethodInfo> imis = settings.getEnabledInputMethodListLocked();
        if (imis.isEmpty()) {
            return Collections.emptyList();
        }
@@ -189,12 +185,12 @@ final class InputMethodSubtypeSwitchingController {
                continue;
            }
            final List<InputMethodSubtype> explicitlyOrImplicitlyEnabledSubtypeList =
                        mSettings.getEnabledInputMethodSubtypeListLocked(imi, true);
                    settings.getEnabledInputMethodSubtypeListLocked(imi, true);
            final ArraySet<String> enabledSubtypeSet = new ArraySet<>();
            for (InputMethodSubtype subtype : explicitlyOrImplicitlyEnabledSubtypeList) {
                enabledSubtypeSet.add(String.valueOf(subtype.hashCode()));
            }
                final CharSequence imeLabel = imi.loadLabel(mPm);
            final CharSequence imeLabel = imi.loadLabel(userAwareContext.getPackageManager());
            if (enabledSubtypeSet.size() > 0) {
                final int subtypeCount = imi.getSubtypeCount();
                if (DEBUG) {
@@ -208,7 +204,7 @@ final class InputMethodSubtypeSwitchingController {
                            && (includeAuxiliarySubtypes || !subtype.isAuxiliary())) {
                        final CharSequence subtypeLabel =
                                subtype.overridesImplicitlyEnabledSubtype() ? null : subtype
                                            .getDisplayName(mContext, imi.getPackageName(),
                                        .getDisplayName(userAwareContext, imi.getPackageName(),
                                                imi.getServiceInfo().applicationInfo);
                        imList.add(new ImeSubtypeListItem(imeLabel,
                                subtypeLabel, imi, j, subtype.getLocale(), mSystemLocaleStr));
@@ -227,7 +223,6 @@ final class InputMethodSubtypeSwitchingController {
        Collections.sort(imList);
        return imList;
    }
    }

    private static int calculateSubtypeId(InputMethodInfo imi, InputMethodSubtype subtype) {
        return subtype != null ? SubtypeUtils.getSubtypeIdFromHashCode(imi, subtype.hashCode())
@@ -479,18 +474,32 @@ final class InputMethodSubtypeSwitchingController {
        }
    }

    private final InputMethodSettings mSettings;
    private InputMethodAndSubtypeList mSubtypeList;
    private final Context mContext;
    @UserIdInt
    private final int mUserId;
    private ControllerImpl mController;

    private InputMethodSubtypeSwitchingController(InputMethodSettings settings, Context context) {
        mSettings = settings;
        resetCircularListLocked(context);
    private InputMethodSubtypeSwitchingController(@NonNull Context context,
            @NonNull ArrayMap<String, InputMethodInfo> methodMap, @UserIdInt int userId) {
        mContext = context;
        mUserId = userId;
        mController = ControllerImpl.createFrom(null,
                getSortedInputMethodAndSubtypeList(
                        false /* includeAuxiliarySubtypes */, false /* isScreenLocked */,
                        false /* forImeMenu */, context, methodMap, userId));
    }

    @NonNull
    public static InputMethodSubtypeSwitchingController createInstanceLocked(
            InputMethodSettings settings, Context context) {
        return new InputMethodSubtypeSwitchingController(settings, context);
            @NonNull Context context,
            @NonNull ArrayMap<String, InputMethodInfo> methodMap, @UserIdInt int userId) {
        return new InputMethodSubtypeSwitchingController(context, methodMap, userId);
    }

    @AnyThread
    @UserIdInt
    int getUserId() {
        return mUserId;
    }

    public void onUserActionLocked(InputMethodInfo imi, InputMethodSubtype subtype) {
@@ -503,12 +512,12 @@ final class InputMethodSubtypeSwitchingController {
        mController.onUserActionLocked(imi, subtype);
    }

    public void resetCircularListLocked(Context context) {
        mSubtypeList = new InputMethodAndSubtypeList(context, mSettings);
    public void resetCircularListLocked(
            @NonNull ArrayMap<String, InputMethodInfo> methodMap) {
        mController = ControllerImpl.createFrom(mController,
                mSubtypeList.getSortedInputMethodAndSubtypeList(
                getSortedInputMethodAndSubtypeList(
                        false /* includeAuxiliarySubtypes */, false /* isScreenLocked */,
                        false /* forImeMenu */));
                        false /* forImeMenu */, mContext, methodMap, mUserId));
    }

    public ImeSubtypeListItem getNextInputMethodLocked(boolean onlyCurrentIme, InputMethodInfo imi,
@@ -522,12 +531,6 @@ final class InputMethodSubtypeSwitchingController {
        return mController.getNextInputMethod(onlyCurrentIme, imi, subtype);
    }

    public List<ImeSubtypeListItem> getSortedInputMethodAndSubtypeListForImeMenuLocked(
            boolean includingAuxiliarySubtypes, boolean isScreenLocked) {
        return mSubtypeList.getSortedInputMethodAndSubtypeList(
                includingAuxiliarySubtypes, isScreenLocked, true /* forImeMenu */);
    }

    public void dump(final Printer pw) {
        if (mController != null) {
            mController.dump(pw);