Loading java/src/com/android/inputmethod/compat/InputMethodManagerCompatWrapper.java +4 −36 Original line number Diff line number Diff line Loading @@ -19,53 +19,21 @@ package com.android.inputmethod.compat; import android.content.Context; import android.os.IBinder; import android.view.inputmethod.InputMethodManager; import android.view.inputmethod.InputMethodSubtype; import com.android.inputmethod.latin.ImfUtils; import java.lang.reflect.Method; // TODO: Override this class with the concrete implementation if we need to take care of the // performance. public final class InputMethodManagerCompatWrapper { private static final String TAG = InputMethodManagerCompatWrapper.class.getSimpleName(); private static final Method METHOD_switchToNextInputMethod = CompatUtils.getMethod( InputMethodManager.class, "switchToNextInputMethod", IBinder.class, Boolean.TYPE); private static final InputMethodManagerCompatWrapper sInstance = new InputMethodManagerCompatWrapper(); private InputMethodManager mImm; private InputMethodManagerCompatWrapper() { // This wrapper class is not publicly instantiable. } public static InputMethodManagerCompatWrapper getInstance() { if (sInstance.mImm == null) { throw new RuntimeException(TAG + ".getInstance() is called before initialization"); } return sInstance; } public final InputMethodManager mImm; public static void init(Context context) { sInstance.mImm = ImfUtils.getInputMethodManager(context); public InputMethodManagerCompatWrapper(final Context context) { mImm = (InputMethodManager)context.getSystemService(Context.INPUT_METHOD_SERVICE); } public InputMethodSubtype getLastInputMethodSubtype() { return mImm.getLastInputMethodSubtype(); } public boolean switchToLastInputMethod(IBinder token) { return mImm.switchToLastInputMethod(token); } public boolean switchToNextInputMethod(IBinder token, boolean onlyCurrentIme) { public boolean switchToNextInputMethod(final IBinder token, final boolean onlyCurrentIme) { return (Boolean)CompatUtils.invoke(mImm, false, METHOD_switchToNextInputMethod, token, onlyCurrentIme); } public void showInputMethodPicker() { mImm.showInputMethodPicker(); } } java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java +3 −3 Original line number Diff line number Diff line Loading @@ -30,11 +30,11 @@ import com.android.inputmethod.keyboard.KeyboardLayoutSet.KeyboardLayoutSetExcep import com.android.inputmethod.keyboard.PointerTracker.TimerProxy; import com.android.inputmethod.keyboard.internal.KeyboardState; import com.android.inputmethod.latin.AudioAndHapticFeedbackManager; import com.android.inputmethod.latin.ImfUtils; import com.android.inputmethod.latin.InputView; import com.android.inputmethod.latin.LatinIME; import com.android.inputmethod.latin.LatinImeLogger; import com.android.inputmethod.latin.R; import com.android.inputmethod.latin.RichInputMethodManager; import com.android.inputmethod.latin.SettingsValues; import com.android.inputmethod.latin.SubtypeSwitcher; import com.android.inputmethod.latin.WordComposer; Loading Loading @@ -142,7 +142,7 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions { builder.setOptions( settingsValues.isVoiceKeyEnabled(editorInfo), settingsValues.isVoiceKeyOnMain(), settingsValues.isLanguageSwitchKeyEnabled(mThemeContext)); settingsValues.isLanguageSwitchKeyEnabled()); mKeyboardLayoutSet = builder.build(); try { mState.onLoadKeyboard(mResources.getString(R.string.layout_switch_back_symbols)); Loading Loading @@ -187,7 +187,7 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions { final boolean needsToDisplayLanguage = mSubtypeSwitcher.needsToDisplayLanguage( keyboard.mId.mLocale); keyboardView.startDisplayLanguageOnSpacebar(subtypeChanged, needsToDisplayLanguage, ImfUtils.hasMultipleEnabledIMEsOrSubtypes(mLatinIME, true)); RichInputMethodManager.getInstance().hasMultipleEnabledIMEsOrSubtypes(true)); } public Keyboard getKeyboard() { Loading java/src/com/android/inputmethod/latin/AdditionalSubtypeSettings.java +13 −8 Original line number Diff line number Diff line Loading @@ -50,6 +50,7 @@ import java.util.ArrayList; import java.util.TreeSet; public final class AdditionalSubtypeSettings extends PreferenceFragment { private RichInputMethodManager mRichImm; private SharedPreferences mPrefs; private SubtypeLocaleAdapter mSubtypeLocaleAdapter; private KeyboardLayoutSetAdapter mKeyboardLayoutSetAdapter; Loading @@ -63,6 +64,7 @@ public final class AdditionalSubtypeSettings extends PreferenceFragment { private static final String KEY_IS_SUBTYPE_ENABLER_NOTIFICATION_DIALOG_OPEN = "is_subtype_enabler_notification_dialog_open"; private static final String KEY_SUBTYPE_FOR_SUBTYPE_ENABLER = "subtype_for_subtype_enabler"; static final class SubtypeLocaleItem extends Pair<String, String> implements Comparable<SubtypeLocaleItem> { public SubtypeLocaleItem(final String localeString, final String displayName) { Loading Loading @@ -90,7 +92,8 @@ public final class AdditionalSubtypeSettings extends PreferenceFragment { setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); final TreeSet<SubtypeLocaleItem> items = CollectionUtils.newTreeSet(); final InputMethodInfo imi = ImfUtils.getInputMethodInfoOfThisIme(context); final InputMethodInfo imi = RichInputMethodManager.getInstance() .getInputMethodInfoOfThisIme(); final int count = imi.getSubtypeCount(); for (int i = 0; i < count; i++) { final InputMethodSubtype subtype = imi.getSubtypeAt(i); Loading Loading @@ -375,6 +378,8 @@ public final class AdditionalSubtypeSettings extends PreferenceFragment { public void onCreate(final Bundle savedInstanceState) { super.onCreate(savedInstanceState); RichInputMethodManager.init(getActivity()); mRichImm = RichInputMethodManager.getInstance(); addPreferencesFromResource(R.xml.additional_subtype_settings); setHasOptionsMenu(true); Loading Loading @@ -431,7 +436,7 @@ public final class AdditionalSubtypeSettings extends PreferenceFragment { mIsAddingNewSubtype = false; final PreferenceGroup group = getPreferenceScreen(); group.removePreference(subtypePref); ImfUtils.setAdditionalInputMethodSubtypes(getActivity(), getSubtypes()); mRichImm.setAdditionalInputMethodSubtypes(getSubtypes()); } @Override Loading @@ -441,7 +446,7 @@ public final class AdditionalSubtypeSettings extends PreferenceFragment { return; } if (findDuplicatedSubtype(subtype) == null) { ImfUtils.setAdditionalInputMethodSubtypes(getActivity(), getSubtypes()); mRichImm.setAdditionalInputMethodSubtypes(getSubtypes()); return; } Loading @@ -458,7 +463,7 @@ public final class AdditionalSubtypeSettings extends PreferenceFragment { mIsAddingNewSubtype = false; final InputMethodSubtype subtype = subtypePref.getSubtype(); if (findDuplicatedSubtype(subtype) == null) { ImfUtils.setAdditionalInputMethodSubtypes(getActivity(), getSubtypes()); mRichImm.setAdditionalInputMethodSubtypes(getSubtypes()); mSubtypePreferenceKeyForSubtypeEnabler = subtypePref.getKey(); mSubtypeEnablerNotificationDialog = createDialog(subtypePref); mSubtypeEnablerNotificationDialog.show(); Loading Loading @@ -493,8 +498,8 @@ public final class AdditionalSubtypeSettings extends PreferenceFragment { private InputMethodSubtype findDuplicatedSubtype(final InputMethodSubtype subtype) { final String localeString = subtype.getLocale(); final String keyboardLayoutSetName = SubtypeLocale.getKeyboardLayoutSetName(subtype); return ImfUtils.findSubtypeByLocaleAndKeyboardLayoutSet( getActivity(), localeString, keyboardLayoutSetName); return mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet( localeString, keyboardLayoutSetName); } private AlertDialog createDialog( Loading @@ -507,7 +512,7 @@ public final class AdditionalSubtypeSettings extends PreferenceFragment { @Override public void onClick(DialogInterface dialog, int which) { final Intent intent = CompatUtils.getInputLanguageSelectionIntent( ImfUtils.getInputMethodIdOfThisIme(getActivity()), mRichImm.getInputMethodIdOfThisIme(), Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED | Intent.FLAG_ACTIVITY_CLEAR_TOP); Loading Loading @@ -565,7 +570,7 @@ public final class AdditionalSubtypeSettings extends PreferenceFragment { } finally { editor.apply(); } ImfUtils.setAdditionalInputMethodSubtypes(getActivity(), subtypes); mRichImm.setAdditionalInputMethodSubtypes(subtypes); } @Override Loading java/src/com/android/inputmethod/latin/LatinIME.java +18 −19 Original line number Diff line number Diff line Loading @@ -56,13 +56,13 @@ import android.view.WindowManager; import android.view.inputmethod.CompletionInfo; import android.view.inputmethod.CorrectionInfo; import android.view.inputmethod.EditorInfo; import android.view.inputmethod.InputMethodManager; import android.view.inputmethod.InputMethodSubtype; import com.android.inputmethod.accessibility.AccessibilityUtils; import com.android.inputmethod.accessibility.AccessibleKeyboardViewProxy; import com.android.inputmethod.annotations.UsedForTesting; import com.android.inputmethod.compat.CompatUtils; import com.android.inputmethod.compat.InputMethodManagerCompatWrapper; import com.android.inputmethod.compat.InputMethodServiceCompatUtils; import com.android.inputmethod.compat.SuggestionSpanUtils; import com.android.inputmethod.keyboard.KeyDetector; Loading Loading @@ -137,7 +137,7 @@ public final class LatinIME extends InputMethodService implements KeyboardAction private CompletionInfo[] mApplicationSpecifiedCompletions; private ApplicationInfo mTargetApplicationInfo; private InputMethodManagerCompatWrapper mImm; private RichInputMethodManager mRichImm; private Resources mResources; private SharedPreferences mPrefs; @UsedForTesting final KeyboardSwitcher mKeyboardSwitcher; Loading Loading @@ -383,14 +383,14 @@ public final class LatinIME extends InputMethodService implements KeyboardAction if (ProductionFlag.IS_EXPERIMENTAL) { ResearchLogger.getInstance().init(this, prefs); } InputMethodManagerCompatWrapper.init(this); RichInputMethodManager.init(this); SubtypeSwitcher.init(this); KeyboardSwitcher.init(this, prefs); AccessibilityUtils.init(this); super.onCreate(); mImm = InputMethodManagerCompatWrapper.getInstance(); mRichImm = RichInputMethodManager.getInstance(); mHandler.onCreate(); DEBUG = LatinImeLogger.sDBG; Loading @@ -399,7 +399,7 @@ public final class LatinIME extends InputMethodService implements KeyboardAction loadSettings(); ImfUtils.setAdditionalInputMethodSubtypes(this, mCurrentSettings.getAdditionalSubtypes()); mRichImm.setAdditionalInputMethodSubtypes(mCurrentSettings.getAdditionalSubtypes()); initSuggest(); Loading Loading @@ -556,7 +556,7 @@ public final class LatinIME extends InputMethodService implements KeyboardAction @Override public void onConfigurationChanged(final Configuration conf) { // System locale has been changed. Needs to reload keyboard. if (mSubtypeSwitcher.onConfigurationChanged(conf, this)) { if (mSubtypeSwitcher.onConfigurationChanged(conf)) { loadKeyboard(); } // If orientation changed while predicting, commit the change Loading Loading @@ -698,8 +698,8 @@ public final class LatinIME extends InputMethodService implements KeyboardAction .updateParametersOnStartInputViewAndReturnIfCurrentSubtypeEnabled(); if (!currentSubtypeEnabled) { // Current subtype is disabled. Needs to update subtype and keyboard. final InputMethodSubtype newSubtype = ImfUtils.getCurrentInputMethodSubtype( this, mSubtypeSwitcher.getNoLanguageSubtype()); final InputMethodSubtype newSubtype = mRichImm.getCurrentInputMethodSubtype( mSubtypeSwitcher.getNoLanguageSubtype()); mSubtypeSwitcher.updateSubtype(newSubtype); loadKeyboard(); } Loading Loading @@ -1216,9 +1216,8 @@ public final class LatinIME extends InputMethodService implements KeyboardAction if (isShowingOptionDialog()) return false; switch (requestCode) { case CODE_SHOW_INPUT_METHOD_PICKER: if (ImfUtils.hasMultipleEnabledIMEsOrSubtypes( this, true /* include aux subtypes */)) { mImm.showInputMethodPicker(); if (mRichImm.hasMultipleEnabledIMEsOrSubtypes(true /* include aux subtypes */)) { mRichImm.getInputMethodManager().showInputMethodPicker(); return true; } return false; Loading @@ -1242,21 +1241,22 @@ public final class LatinIME extends InputMethodService implements KeyboardAction private void handleLanguageSwitchKey() { final IBinder token = getWindow().getWindow().getAttributes().token; if (mCurrentSettings.mIncludesOtherImesInLanguageSwitchList) { mImm.switchToNextInputMethod(token, false /* onlyCurrentIme */); mRichImm.switchToNextInputMethod(token, false /* onlyCurrentIme */); return; } if (mShouldSwitchToLastSubtype) { final InputMethodSubtype lastSubtype = mImm.getLastInputMethodSubtype(); final InputMethodManager imm = mRichImm.getInputMethodManager(); final InputMethodSubtype lastSubtype = imm.getLastInputMethodSubtype(); final boolean lastSubtypeBelongsToThisIme = ImfUtils.checkIfSubtypeBelongsToThisImeAndEnabled(this, lastSubtype); if (lastSubtypeBelongsToThisIme && mImm.switchToLastInputMethod(token)) { mRichImm.checkIfSubtypeBelongsToThisImeAndEnabled(lastSubtype); if (lastSubtypeBelongsToThisIme && imm.switchToLastInputMethod(token)) { mShouldSwitchToLastSubtype = false; } else { mImm.switchToNextInputMethod(token, true /* onlyCurrentIme */); mRichImm.switchToNextInputMethod(token, true /* onlyCurrentIme */); mShouldSwitchToLastSubtype = true; } } else { mImm.switchToNextInputMethod(token, true /* onlyCurrentIme */); mRichImm.switchToNextInputMethod(token, true /* onlyCurrentIme */); } } Loading Loading @@ -2352,7 +2352,6 @@ public final class LatinIME extends InputMethodService implements KeyboardAction getString(R.string.language_selection_title), getString(R.string.english_ime_settings), }; final Context context = this; final DialogInterface.OnClickListener listener = new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface di, int position) { Loading @@ -2360,7 +2359,7 @@ public final class LatinIME extends InputMethodService implements KeyboardAction switch (position) { case 0: Intent intent = CompatUtils.getInputLanguageSelectionIntent( ImfUtils.getInputMethodIdOfThisIme(context), mRichImm.getInputMethodIdOfThisIme(), Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED | Intent.FLAG_ACTIVITY_CLEAR_TOP); Loading java/src/com/android/inputmethod/latin/ImfUtils.java→java/src/com/android/inputmethod/latin/RichInputMethodManager.java +213 −0 Original line number Diff line number Diff line Loading @@ -19,56 +19,91 @@ package com.android.inputmethod.latin; import static com.android.inputmethod.latin.Constants.Subtype.KEYBOARD_MODE; import android.content.Context; import android.os.IBinder; import android.view.inputmethod.InputMethodInfo; import android.view.inputmethod.InputMethodManager; import android.view.inputmethod.InputMethodSubtype; import com.android.inputmethod.compat.InputMethodManagerCompatWrapper; import java.util.Collections; import java.util.List; /** * Utility class for Input Method Framework * Enrichment class for InputMethodManager to simplify interaction and add functionality. */ public final class ImfUtils { private ImfUtils() { public final class RichInputMethodManager { private static final String TAG = RichInputMethodManager.class.getSimpleName(); private RichInputMethodManager() { // This utility class is not publicly instantiable. } private static InputMethodManager sInputMethodManager; private static final RichInputMethodManager sInstance = new RichInputMethodManager(); private InputMethodManagerCompatWrapper mImmWrapper; private InputMethodInfo mInputMethodInfoOfThisIme; public static RichInputMethodManager getInstance() { sInstance.checkInitialized(); return sInstance; } public static void init(final Context context) { sInstance.initInternal(context); } public static InputMethodManager getInputMethodManager(Context context) { if (sInputMethodManager == null) { sInputMethodManager = (InputMethodManager)context.getSystemService( Context.INPUT_METHOD_SERVICE); private void checkInitialized() { if (mImmWrapper == null) { throw new RuntimeException(TAG + " is used before initialization"); } } return sInputMethodManager; private void initInternal(final Context context) { mImmWrapper = new InputMethodManagerCompatWrapper(context); mInputMethodInfoOfThisIme = getInputMethodInfoOfThisIme(context); } private static InputMethodInfo sInputMethodInfoOfThisIme; public InputMethodManager getInputMethodManager() { checkInitialized(); return mImmWrapper.mImm; } public static InputMethodInfo getInputMethodInfoOfThisIme(Context context) { if (sInputMethodInfoOfThisIme == null) { final InputMethodManager imm = getInputMethodManager(context); private InputMethodInfo getInputMethodInfoOfThisIme(final Context context) { final String packageName = context.getPackageName(); for (final InputMethodInfo imi : imm.getInputMethodList()) { if (imi.getPackageName().equals(packageName)) for (final InputMethodInfo imi : mImmWrapper.mImm.getInputMethodList()) { if (imi.getPackageName().equals(packageName)) { return imi; } throw new RuntimeException("Can not find input method id for " + packageName); } return sInputMethodInfoOfThisIme; throw new RuntimeException("Input method id for " + packageName + " not found."); } public boolean switchToNextInputMethod(final IBinder token, final boolean onlyCurrentIme) { final boolean result = mImmWrapper.switchToNextInputMethod(token, onlyCurrentIme); if (!result) { mImmWrapper.mImm.switchToLastInputMethod(token); return false; } return true; } public InputMethodInfo getInputMethodInfoOfThisIme() { return mInputMethodInfoOfThisIme; } public String getInputMethodIdOfThisIme() { return mInputMethodInfoOfThisIme.getId(); } public static String getInputMethodIdOfThisIme(Context context) { return getInputMethodInfoOfThisIme(context).getId(); public boolean checkIfSubtypeBelongsToThisImeAndEnabled(final InputMethodSubtype ims) { return checkIfSubtypeBelongsToImeAndEnabled(mInputMethodInfoOfThisIme, ims); } public static boolean checkIfSubtypeBelongsToThisImeAndEnabled(Context context, InputMethodSubtype ims) { final InputMethodInfo myImi = getInputMethodInfoOfThisIme(context); final InputMethodManager imm = getInputMethodManager(context); // TODO: Cache all subtypes of this IME for optimization final List<InputMethodSubtype> subtypes = imm.getEnabledInputMethodSubtypeList(myImi, true); public boolean checkIfSubtypeBelongsToImeAndEnabled(final InputMethodInfo imi, final InputMethodSubtype ims) { final List<InputMethodSubtype> subtypes = mImmWrapper.mImm.getEnabledInputMethodSubtypeList( imi, true /* allowsImplicitlySelectedSubtypes */); for (final InputMethodSubtype subtype : subtypes) { if (subtype.equals(ims)) { return true; Loading @@ -77,9 +112,8 @@ public final class ImfUtils { return false; } public static boolean checkIfSubtypeBelongsToThisIme(Context context, InputMethodSubtype ims) { final InputMethodInfo myImi = getInputMethodInfoOfThisIme(context); public boolean checkIfSubtypeBelongsToThisIme(final InputMethodSubtype ims) { final InputMethodInfo myImi = mInputMethodInfoOfThisIme; final int count = myImi.getSubtypeCount(); for (int i = 0; i < count; i++) { final InputMethodSubtype subtype = myImi.getSubtypeAt(i); Loading @@ -90,31 +124,25 @@ public final class ImfUtils { return false; } public static InputMethodSubtype getCurrentInputMethodSubtype(Context context, InputMethodSubtype defaultSubtype) { final InputMethodManager imm = getInputMethodManager(context); final InputMethodSubtype currentSubtype = imm.getCurrentInputMethodSubtype(); public InputMethodSubtype getCurrentInputMethodSubtype( final InputMethodSubtype defaultSubtype) { final InputMethodSubtype currentSubtype = mImmWrapper.mImm.getCurrentInputMethodSubtype(); return (currentSubtype != null) ? currentSubtype : defaultSubtype; } public static boolean hasMultipleEnabledIMEsOrSubtypes(Context context, final boolean shouldIncludeAuxiliarySubtypes) { final InputMethodManager imm = getInputMethodManager(context); final List<InputMethodInfo> enabledImis = imm.getEnabledInputMethodList(); return hasMultipleEnabledSubtypes(context, shouldIncludeAuxiliarySubtypes, enabledImis); public boolean hasMultipleEnabledIMEsOrSubtypes(final boolean shouldIncludeAuxiliarySubtypes) { final List<InputMethodInfo> enabledImis = mImmWrapper.mImm.getEnabledInputMethodList(); return hasMultipleEnabledSubtypes(shouldIncludeAuxiliarySubtypes, enabledImis); } public static boolean hasMultipleEnabledSubtypesInThisIme(Context context, public boolean hasMultipleEnabledSubtypesInThisIme( final boolean shouldIncludeAuxiliarySubtypes) { final InputMethodInfo myImi = getInputMethodInfoOfThisIme(context); final List<InputMethodInfo> imiList = Collections.singletonList(myImi); return hasMultipleEnabledSubtypes(context, shouldIncludeAuxiliarySubtypes, imiList); final List<InputMethodInfo> imiList = Collections.singletonList(mInputMethodInfoOfThisIme); return hasMultipleEnabledSubtypes(shouldIncludeAuxiliarySubtypes, imiList); } private static boolean hasMultipleEnabledSubtypes(Context context, final boolean shouldIncludeAuxiliarySubtypes, List<InputMethodInfo> imiList) { final InputMethodManager imm = getInputMethodManager(context); private boolean hasMultipleEnabledSubtypes(final boolean shouldIncludeAuxiliarySubtypes, final List<InputMethodInfo> imiList) { // Number of the filtered IMEs int filteredImisCount = 0; Loading @@ -122,7 +150,7 @@ public final class ImfUtils { // We can return true immediately after we find two or more filtered IMEs. if (filteredImisCount > 1) return true; final List<InputMethodSubtype> subtypes = imm.getEnabledInputMethodSubtypeList(imi, true); mImmWrapper.mImm.getEnabledInputMethodSubtypeList(imi, true); // IMEs that have no subtypes should be counted. if (subtypes.isEmpty()) { ++filteredImisCount; Loading @@ -149,7 +177,8 @@ public final class ImfUtils { if (filteredImisCount > 1) { return true; } final List<InputMethodSubtype> subtypes = imm.getEnabledInputMethodSubtypeList(null, true); final List<InputMethodSubtype> subtypes = mImmWrapper.mImm.getEnabledInputMethodSubtypeList(null, true); int keyboardCount = 0; // imm.getEnabledInputMethodSubtypeList(null, true) will return the current IME's // both explicitly and implicitly enabled input method subtype. Loading @@ -162,12 +191,12 @@ public final class ImfUtils { return keyboardCount > 1; } public static InputMethodSubtype findSubtypeByLocaleAndKeyboardLayoutSet( Context context, String localeString, String keyboardLayoutSetName) { final InputMethodInfo imi = getInputMethodInfoOfThisIme(context); final int count = imi.getSubtypeCount(); public InputMethodSubtype findSubtypeByLocaleAndKeyboardLayoutSet(final String localeString, final String keyboardLayoutSetName) { final InputMethodInfo myImi = mInputMethodInfoOfThisIme; final int count = myImi.getSubtypeCount(); for (int i = 0; i < count; i++) { final InputMethodSubtype subtype = imi.getSubtypeAt(i); final InputMethodSubtype subtype = myImi.getSubtypeAt(i); final String layoutName = SubtypeLocale.getKeyboardLayoutSetName(subtype); if (localeString.equals(subtype.getLocale()) && keyboardLayoutSetName.equals(layoutName)) { Loading @@ -177,10 +206,8 @@ public final class ImfUtils { return null; } public static void setAdditionalInputMethodSubtypes(Context context, InputMethodSubtype[] subtypes) { final InputMethodManager imm = getInputMethodManager(context); final String imiId = getInputMethodIdOfThisIme(context); imm.setAdditionalInputMethodSubtypes(imiId, subtypes); public void setAdditionalInputMethodSubtypes(final InputMethodSubtype[] subtypes) { mImmWrapper.mImm.setAdditionalInputMethodSubtypes( mInputMethodInfoOfThisIme.getId(), subtypes); } } Loading
java/src/com/android/inputmethod/compat/InputMethodManagerCompatWrapper.java +4 −36 Original line number Diff line number Diff line Loading @@ -19,53 +19,21 @@ package com.android.inputmethod.compat; import android.content.Context; import android.os.IBinder; import android.view.inputmethod.InputMethodManager; import android.view.inputmethod.InputMethodSubtype; import com.android.inputmethod.latin.ImfUtils; import java.lang.reflect.Method; // TODO: Override this class with the concrete implementation if we need to take care of the // performance. public final class InputMethodManagerCompatWrapper { private static final String TAG = InputMethodManagerCompatWrapper.class.getSimpleName(); private static final Method METHOD_switchToNextInputMethod = CompatUtils.getMethod( InputMethodManager.class, "switchToNextInputMethod", IBinder.class, Boolean.TYPE); private static final InputMethodManagerCompatWrapper sInstance = new InputMethodManagerCompatWrapper(); private InputMethodManager mImm; private InputMethodManagerCompatWrapper() { // This wrapper class is not publicly instantiable. } public static InputMethodManagerCompatWrapper getInstance() { if (sInstance.mImm == null) { throw new RuntimeException(TAG + ".getInstance() is called before initialization"); } return sInstance; } public final InputMethodManager mImm; public static void init(Context context) { sInstance.mImm = ImfUtils.getInputMethodManager(context); public InputMethodManagerCompatWrapper(final Context context) { mImm = (InputMethodManager)context.getSystemService(Context.INPUT_METHOD_SERVICE); } public InputMethodSubtype getLastInputMethodSubtype() { return mImm.getLastInputMethodSubtype(); } public boolean switchToLastInputMethod(IBinder token) { return mImm.switchToLastInputMethod(token); } public boolean switchToNextInputMethod(IBinder token, boolean onlyCurrentIme) { public boolean switchToNextInputMethod(final IBinder token, final boolean onlyCurrentIme) { return (Boolean)CompatUtils.invoke(mImm, false, METHOD_switchToNextInputMethod, token, onlyCurrentIme); } public void showInputMethodPicker() { mImm.showInputMethodPicker(); } }
java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java +3 −3 Original line number Diff line number Diff line Loading @@ -30,11 +30,11 @@ import com.android.inputmethod.keyboard.KeyboardLayoutSet.KeyboardLayoutSetExcep import com.android.inputmethod.keyboard.PointerTracker.TimerProxy; import com.android.inputmethod.keyboard.internal.KeyboardState; import com.android.inputmethod.latin.AudioAndHapticFeedbackManager; import com.android.inputmethod.latin.ImfUtils; import com.android.inputmethod.latin.InputView; import com.android.inputmethod.latin.LatinIME; import com.android.inputmethod.latin.LatinImeLogger; import com.android.inputmethod.latin.R; import com.android.inputmethod.latin.RichInputMethodManager; import com.android.inputmethod.latin.SettingsValues; import com.android.inputmethod.latin.SubtypeSwitcher; import com.android.inputmethod.latin.WordComposer; Loading Loading @@ -142,7 +142,7 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions { builder.setOptions( settingsValues.isVoiceKeyEnabled(editorInfo), settingsValues.isVoiceKeyOnMain(), settingsValues.isLanguageSwitchKeyEnabled(mThemeContext)); settingsValues.isLanguageSwitchKeyEnabled()); mKeyboardLayoutSet = builder.build(); try { mState.onLoadKeyboard(mResources.getString(R.string.layout_switch_back_symbols)); Loading Loading @@ -187,7 +187,7 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions { final boolean needsToDisplayLanguage = mSubtypeSwitcher.needsToDisplayLanguage( keyboard.mId.mLocale); keyboardView.startDisplayLanguageOnSpacebar(subtypeChanged, needsToDisplayLanguage, ImfUtils.hasMultipleEnabledIMEsOrSubtypes(mLatinIME, true)); RichInputMethodManager.getInstance().hasMultipleEnabledIMEsOrSubtypes(true)); } public Keyboard getKeyboard() { Loading
java/src/com/android/inputmethod/latin/AdditionalSubtypeSettings.java +13 −8 Original line number Diff line number Diff line Loading @@ -50,6 +50,7 @@ import java.util.ArrayList; import java.util.TreeSet; public final class AdditionalSubtypeSettings extends PreferenceFragment { private RichInputMethodManager mRichImm; private SharedPreferences mPrefs; private SubtypeLocaleAdapter mSubtypeLocaleAdapter; private KeyboardLayoutSetAdapter mKeyboardLayoutSetAdapter; Loading @@ -63,6 +64,7 @@ public final class AdditionalSubtypeSettings extends PreferenceFragment { private static final String KEY_IS_SUBTYPE_ENABLER_NOTIFICATION_DIALOG_OPEN = "is_subtype_enabler_notification_dialog_open"; private static final String KEY_SUBTYPE_FOR_SUBTYPE_ENABLER = "subtype_for_subtype_enabler"; static final class SubtypeLocaleItem extends Pair<String, String> implements Comparable<SubtypeLocaleItem> { public SubtypeLocaleItem(final String localeString, final String displayName) { Loading Loading @@ -90,7 +92,8 @@ public final class AdditionalSubtypeSettings extends PreferenceFragment { setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); final TreeSet<SubtypeLocaleItem> items = CollectionUtils.newTreeSet(); final InputMethodInfo imi = ImfUtils.getInputMethodInfoOfThisIme(context); final InputMethodInfo imi = RichInputMethodManager.getInstance() .getInputMethodInfoOfThisIme(); final int count = imi.getSubtypeCount(); for (int i = 0; i < count; i++) { final InputMethodSubtype subtype = imi.getSubtypeAt(i); Loading Loading @@ -375,6 +378,8 @@ public final class AdditionalSubtypeSettings extends PreferenceFragment { public void onCreate(final Bundle savedInstanceState) { super.onCreate(savedInstanceState); RichInputMethodManager.init(getActivity()); mRichImm = RichInputMethodManager.getInstance(); addPreferencesFromResource(R.xml.additional_subtype_settings); setHasOptionsMenu(true); Loading Loading @@ -431,7 +436,7 @@ public final class AdditionalSubtypeSettings extends PreferenceFragment { mIsAddingNewSubtype = false; final PreferenceGroup group = getPreferenceScreen(); group.removePreference(subtypePref); ImfUtils.setAdditionalInputMethodSubtypes(getActivity(), getSubtypes()); mRichImm.setAdditionalInputMethodSubtypes(getSubtypes()); } @Override Loading @@ -441,7 +446,7 @@ public final class AdditionalSubtypeSettings extends PreferenceFragment { return; } if (findDuplicatedSubtype(subtype) == null) { ImfUtils.setAdditionalInputMethodSubtypes(getActivity(), getSubtypes()); mRichImm.setAdditionalInputMethodSubtypes(getSubtypes()); return; } Loading @@ -458,7 +463,7 @@ public final class AdditionalSubtypeSettings extends PreferenceFragment { mIsAddingNewSubtype = false; final InputMethodSubtype subtype = subtypePref.getSubtype(); if (findDuplicatedSubtype(subtype) == null) { ImfUtils.setAdditionalInputMethodSubtypes(getActivity(), getSubtypes()); mRichImm.setAdditionalInputMethodSubtypes(getSubtypes()); mSubtypePreferenceKeyForSubtypeEnabler = subtypePref.getKey(); mSubtypeEnablerNotificationDialog = createDialog(subtypePref); mSubtypeEnablerNotificationDialog.show(); Loading Loading @@ -493,8 +498,8 @@ public final class AdditionalSubtypeSettings extends PreferenceFragment { private InputMethodSubtype findDuplicatedSubtype(final InputMethodSubtype subtype) { final String localeString = subtype.getLocale(); final String keyboardLayoutSetName = SubtypeLocale.getKeyboardLayoutSetName(subtype); return ImfUtils.findSubtypeByLocaleAndKeyboardLayoutSet( getActivity(), localeString, keyboardLayoutSetName); return mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet( localeString, keyboardLayoutSetName); } private AlertDialog createDialog( Loading @@ -507,7 +512,7 @@ public final class AdditionalSubtypeSettings extends PreferenceFragment { @Override public void onClick(DialogInterface dialog, int which) { final Intent intent = CompatUtils.getInputLanguageSelectionIntent( ImfUtils.getInputMethodIdOfThisIme(getActivity()), mRichImm.getInputMethodIdOfThisIme(), Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED | Intent.FLAG_ACTIVITY_CLEAR_TOP); Loading Loading @@ -565,7 +570,7 @@ public final class AdditionalSubtypeSettings extends PreferenceFragment { } finally { editor.apply(); } ImfUtils.setAdditionalInputMethodSubtypes(getActivity(), subtypes); mRichImm.setAdditionalInputMethodSubtypes(subtypes); } @Override Loading
java/src/com/android/inputmethod/latin/LatinIME.java +18 −19 Original line number Diff line number Diff line Loading @@ -56,13 +56,13 @@ import android.view.WindowManager; import android.view.inputmethod.CompletionInfo; import android.view.inputmethod.CorrectionInfo; import android.view.inputmethod.EditorInfo; import android.view.inputmethod.InputMethodManager; import android.view.inputmethod.InputMethodSubtype; import com.android.inputmethod.accessibility.AccessibilityUtils; import com.android.inputmethod.accessibility.AccessibleKeyboardViewProxy; import com.android.inputmethod.annotations.UsedForTesting; import com.android.inputmethod.compat.CompatUtils; import com.android.inputmethod.compat.InputMethodManagerCompatWrapper; import com.android.inputmethod.compat.InputMethodServiceCompatUtils; import com.android.inputmethod.compat.SuggestionSpanUtils; import com.android.inputmethod.keyboard.KeyDetector; Loading Loading @@ -137,7 +137,7 @@ public final class LatinIME extends InputMethodService implements KeyboardAction private CompletionInfo[] mApplicationSpecifiedCompletions; private ApplicationInfo mTargetApplicationInfo; private InputMethodManagerCompatWrapper mImm; private RichInputMethodManager mRichImm; private Resources mResources; private SharedPreferences mPrefs; @UsedForTesting final KeyboardSwitcher mKeyboardSwitcher; Loading Loading @@ -383,14 +383,14 @@ public final class LatinIME extends InputMethodService implements KeyboardAction if (ProductionFlag.IS_EXPERIMENTAL) { ResearchLogger.getInstance().init(this, prefs); } InputMethodManagerCompatWrapper.init(this); RichInputMethodManager.init(this); SubtypeSwitcher.init(this); KeyboardSwitcher.init(this, prefs); AccessibilityUtils.init(this); super.onCreate(); mImm = InputMethodManagerCompatWrapper.getInstance(); mRichImm = RichInputMethodManager.getInstance(); mHandler.onCreate(); DEBUG = LatinImeLogger.sDBG; Loading @@ -399,7 +399,7 @@ public final class LatinIME extends InputMethodService implements KeyboardAction loadSettings(); ImfUtils.setAdditionalInputMethodSubtypes(this, mCurrentSettings.getAdditionalSubtypes()); mRichImm.setAdditionalInputMethodSubtypes(mCurrentSettings.getAdditionalSubtypes()); initSuggest(); Loading Loading @@ -556,7 +556,7 @@ public final class LatinIME extends InputMethodService implements KeyboardAction @Override public void onConfigurationChanged(final Configuration conf) { // System locale has been changed. Needs to reload keyboard. if (mSubtypeSwitcher.onConfigurationChanged(conf, this)) { if (mSubtypeSwitcher.onConfigurationChanged(conf)) { loadKeyboard(); } // If orientation changed while predicting, commit the change Loading Loading @@ -698,8 +698,8 @@ public final class LatinIME extends InputMethodService implements KeyboardAction .updateParametersOnStartInputViewAndReturnIfCurrentSubtypeEnabled(); if (!currentSubtypeEnabled) { // Current subtype is disabled. Needs to update subtype and keyboard. final InputMethodSubtype newSubtype = ImfUtils.getCurrentInputMethodSubtype( this, mSubtypeSwitcher.getNoLanguageSubtype()); final InputMethodSubtype newSubtype = mRichImm.getCurrentInputMethodSubtype( mSubtypeSwitcher.getNoLanguageSubtype()); mSubtypeSwitcher.updateSubtype(newSubtype); loadKeyboard(); } Loading Loading @@ -1216,9 +1216,8 @@ public final class LatinIME extends InputMethodService implements KeyboardAction if (isShowingOptionDialog()) return false; switch (requestCode) { case CODE_SHOW_INPUT_METHOD_PICKER: if (ImfUtils.hasMultipleEnabledIMEsOrSubtypes( this, true /* include aux subtypes */)) { mImm.showInputMethodPicker(); if (mRichImm.hasMultipleEnabledIMEsOrSubtypes(true /* include aux subtypes */)) { mRichImm.getInputMethodManager().showInputMethodPicker(); return true; } return false; Loading @@ -1242,21 +1241,22 @@ public final class LatinIME extends InputMethodService implements KeyboardAction private void handleLanguageSwitchKey() { final IBinder token = getWindow().getWindow().getAttributes().token; if (mCurrentSettings.mIncludesOtherImesInLanguageSwitchList) { mImm.switchToNextInputMethod(token, false /* onlyCurrentIme */); mRichImm.switchToNextInputMethod(token, false /* onlyCurrentIme */); return; } if (mShouldSwitchToLastSubtype) { final InputMethodSubtype lastSubtype = mImm.getLastInputMethodSubtype(); final InputMethodManager imm = mRichImm.getInputMethodManager(); final InputMethodSubtype lastSubtype = imm.getLastInputMethodSubtype(); final boolean lastSubtypeBelongsToThisIme = ImfUtils.checkIfSubtypeBelongsToThisImeAndEnabled(this, lastSubtype); if (lastSubtypeBelongsToThisIme && mImm.switchToLastInputMethod(token)) { mRichImm.checkIfSubtypeBelongsToThisImeAndEnabled(lastSubtype); if (lastSubtypeBelongsToThisIme && imm.switchToLastInputMethod(token)) { mShouldSwitchToLastSubtype = false; } else { mImm.switchToNextInputMethod(token, true /* onlyCurrentIme */); mRichImm.switchToNextInputMethod(token, true /* onlyCurrentIme */); mShouldSwitchToLastSubtype = true; } } else { mImm.switchToNextInputMethod(token, true /* onlyCurrentIme */); mRichImm.switchToNextInputMethod(token, true /* onlyCurrentIme */); } } Loading Loading @@ -2352,7 +2352,6 @@ public final class LatinIME extends InputMethodService implements KeyboardAction getString(R.string.language_selection_title), getString(R.string.english_ime_settings), }; final Context context = this; final DialogInterface.OnClickListener listener = new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface di, int position) { Loading @@ -2360,7 +2359,7 @@ public final class LatinIME extends InputMethodService implements KeyboardAction switch (position) { case 0: Intent intent = CompatUtils.getInputLanguageSelectionIntent( ImfUtils.getInputMethodIdOfThisIme(context), mRichImm.getInputMethodIdOfThisIme(), Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED | Intent.FLAG_ACTIVITY_CLEAR_TOP); Loading
java/src/com/android/inputmethod/latin/ImfUtils.java→java/src/com/android/inputmethod/latin/RichInputMethodManager.java +213 −0 Original line number Diff line number Diff line Loading @@ -19,56 +19,91 @@ package com.android.inputmethod.latin; import static com.android.inputmethod.latin.Constants.Subtype.KEYBOARD_MODE; import android.content.Context; import android.os.IBinder; import android.view.inputmethod.InputMethodInfo; import android.view.inputmethod.InputMethodManager; import android.view.inputmethod.InputMethodSubtype; import com.android.inputmethod.compat.InputMethodManagerCompatWrapper; import java.util.Collections; import java.util.List; /** * Utility class for Input Method Framework * Enrichment class for InputMethodManager to simplify interaction and add functionality. */ public final class ImfUtils { private ImfUtils() { public final class RichInputMethodManager { private static final String TAG = RichInputMethodManager.class.getSimpleName(); private RichInputMethodManager() { // This utility class is not publicly instantiable. } private static InputMethodManager sInputMethodManager; private static final RichInputMethodManager sInstance = new RichInputMethodManager(); private InputMethodManagerCompatWrapper mImmWrapper; private InputMethodInfo mInputMethodInfoOfThisIme; public static RichInputMethodManager getInstance() { sInstance.checkInitialized(); return sInstance; } public static void init(final Context context) { sInstance.initInternal(context); } public static InputMethodManager getInputMethodManager(Context context) { if (sInputMethodManager == null) { sInputMethodManager = (InputMethodManager)context.getSystemService( Context.INPUT_METHOD_SERVICE); private void checkInitialized() { if (mImmWrapper == null) { throw new RuntimeException(TAG + " is used before initialization"); } } return sInputMethodManager; private void initInternal(final Context context) { mImmWrapper = new InputMethodManagerCompatWrapper(context); mInputMethodInfoOfThisIme = getInputMethodInfoOfThisIme(context); } private static InputMethodInfo sInputMethodInfoOfThisIme; public InputMethodManager getInputMethodManager() { checkInitialized(); return mImmWrapper.mImm; } public static InputMethodInfo getInputMethodInfoOfThisIme(Context context) { if (sInputMethodInfoOfThisIme == null) { final InputMethodManager imm = getInputMethodManager(context); private InputMethodInfo getInputMethodInfoOfThisIme(final Context context) { final String packageName = context.getPackageName(); for (final InputMethodInfo imi : imm.getInputMethodList()) { if (imi.getPackageName().equals(packageName)) for (final InputMethodInfo imi : mImmWrapper.mImm.getInputMethodList()) { if (imi.getPackageName().equals(packageName)) { return imi; } throw new RuntimeException("Can not find input method id for " + packageName); } return sInputMethodInfoOfThisIme; throw new RuntimeException("Input method id for " + packageName + " not found."); } public boolean switchToNextInputMethod(final IBinder token, final boolean onlyCurrentIme) { final boolean result = mImmWrapper.switchToNextInputMethod(token, onlyCurrentIme); if (!result) { mImmWrapper.mImm.switchToLastInputMethod(token); return false; } return true; } public InputMethodInfo getInputMethodInfoOfThisIme() { return mInputMethodInfoOfThisIme; } public String getInputMethodIdOfThisIme() { return mInputMethodInfoOfThisIme.getId(); } public static String getInputMethodIdOfThisIme(Context context) { return getInputMethodInfoOfThisIme(context).getId(); public boolean checkIfSubtypeBelongsToThisImeAndEnabled(final InputMethodSubtype ims) { return checkIfSubtypeBelongsToImeAndEnabled(mInputMethodInfoOfThisIme, ims); } public static boolean checkIfSubtypeBelongsToThisImeAndEnabled(Context context, InputMethodSubtype ims) { final InputMethodInfo myImi = getInputMethodInfoOfThisIme(context); final InputMethodManager imm = getInputMethodManager(context); // TODO: Cache all subtypes of this IME for optimization final List<InputMethodSubtype> subtypes = imm.getEnabledInputMethodSubtypeList(myImi, true); public boolean checkIfSubtypeBelongsToImeAndEnabled(final InputMethodInfo imi, final InputMethodSubtype ims) { final List<InputMethodSubtype> subtypes = mImmWrapper.mImm.getEnabledInputMethodSubtypeList( imi, true /* allowsImplicitlySelectedSubtypes */); for (final InputMethodSubtype subtype : subtypes) { if (subtype.equals(ims)) { return true; Loading @@ -77,9 +112,8 @@ public final class ImfUtils { return false; } public static boolean checkIfSubtypeBelongsToThisIme(Context context, InputMethodSubtype ims) { final InputMethodInfo myImi = getInputMethodInfoOfThisIme(context); public boolean checkIfSubtypeBelongsToThisIme(final InputMethodSubtype ims) { final InputMethodInfo myImi = mInputMethodInfoOfThisIme; final int count = myImi.getSubtypeCount(); for (int i = 0; i < count; i++) { final InputMethodSubtype subtype = myImi.getSubtypeAt(i); Loading @@ -90,31 +124,25 @@ public final class ImfUtils { return false; } public static InputMethodSubtype getCurrentInputMethodSubtype(Context context, InputMethodSubtype defaultSubtype) { final InputMethodManager imm = getInputMethodManager(context); final InputMethodSubtype currentSubtype = imm.getCurrentInputMethodSubtype(); public InputMethodSubtype getCurrentInputMethodSubtype( final InputMethodSubtype defaultSubtype) { final InputMethodSubtype currentSubtype = mImmWrapper.mImm.getCurrentInputMethodSubtype(); return (currentSubtype != null) ? currentSubtype : defaultSubtype; } public static boolean hasMultipleEnabledIMEsOrSubtypes(Context context, final boolean shouldIncludeAuxiliarySubtypes) { final InputMethodManager imm = getInputMethodManager(context); final List<InputMethodInfo> enabledImis = imm.getEnabledInputMethodList(); return hasMultipleEnabledSubtypes(context, shouldIncludeAuxiliarySubtypes, enabledImis); public boolean hasMultipleEnabledIMEsOrSubtypes(final boolean shouldIncludeAuxiliarySubtypes) { final List<InputMethodInfo> enabledImis = mImmWrapper.mImm.getEnabledInputMethodList(); return hasMultipleEnabledSubtypes(shouldIncludeAuxiliarySubtypes, enabledImis); } public static boolean hasMultipleEnabledSubtypesInThisIme(Context context, public boolean hasMultipleEnabledSubtypesInThisIme( final boolean shouldIncludeAuxiliarySubtypes) { final InputMethodInfo myImi = getInputMethodInfoOfThisIme(context); final List<InputMethodInfo> imiList = Collections.singletonList(myImi); return hasMultipleEnabledSubtypes(context, shouldIncludeAuxiliarySubtypes, imiList); final List<InputMethodInfo> imiList = Collections.singletonList(mInputMethodInfoOfThisIme); return hasMultipleEnabledSubtypes(shouldIncludeAuxiliarySubtypes, imiList); } private static boolean hasMultipleEnabledSubtypes(Context context, final boolean shouldIncludeAuxiliarySubtypes, List<InputMethodInfo> imiList) { final InputMethodManager imm = getInputMethodManager(context); private boolean hasMultipleEnabledSubtypes(final boolean shouldIncludeAuxiliarySubtypes, final List<InputMethodInfo> imiList) { // Number of the filtered IMEs int filteredImisCount = 0; Loading @@ -122,7 +150,7 @@ public final class ImfUtils { // We can return true immediately after we find two or more filtered IMEs. if (filteredImisCount > 1) return true; final List<InputMethodSubtype> subtypes = imm.getEnabledInputMethodSubtypeList(imi, true); mImmWrapper.mImm.getEnabledInputMethodSubtypeList(imi, true); // IMEs that have no subtypes should be counted. if (subtypes.isEmpty()) { ++filteredImisCount; Loading @@ -149,7 +177,8 @@ public final class ImfUtils { if (filteredImisCount > 1) { return true; } final List<InputMethodSubtype> subtypes = imm.getEnabledInputMethodSubtypeList(null, true); final List<InputMethodSubtype> subtypes = mImmWrapper.mImm.getEnabledInputMethodSubtypeList(null, true); int keyboardCount = 0; // imm.getEnabledInputMethodSubtypeList(null, true) will return the current IME's // both explicitly and implicitly enabled input method subtype. Loading @@ -162,12 +191,12 @@ public final class ImfUtils { return keyboardCount > 1; } public static InputMethodSubtype findSubtypeByLocaleAndKeyboardLayoutSet( Context context, String localeString, String keyboardLayoutSetName) { final InputMethodInfo imi = getInputMethodInfoOfThisIme(context); final int count = imi.getSubtypeCount(); public InputMethodSubtype findSubtypeByLocaleAndKeyboardLayoutSet(final String localeString, final String keyboardLayoutSetName) { final InputMethodInfo myImi = mInputMethodInfoOfThisIme; final int count = myImi.getSubtypeCount(); for (int i = 0; i < count; i++) { final InputMethodSubtype subtype = imi.getSubtypeAt(i); final InputMethodSubtype subtype = myImi.getSubtypeAt(i); final String layoutName = SubtypeLocale.getKeyboardLayoutSetName(subtype); if (localeString.equals(subtype.getLocale()) && keyboardLayoutSetName.equals(layoutName)) { Loading @@ -177,10 +206,8 @@ public final class ImfUtils { return null; } public static void setAdditionalInputMethodSubtypes(Context context, InputMethodSubtype[] subtypes) { final InputMethodManager imm = getInputMethodManager(context); final String imiId = getInputMethodIdOfThisIme(context); imm.setAdditionalInputMethodSubtypes(imiId, subtypes); public void setAdditionalInputMethodSubtypes(final InputMethodSubtype[] subtypes) { mImmWrapper.mImm.setAdditionalInputMethodSubtypes( mInputMethodInfoOfThisIme.getId(), subtypes); } }