diff --git a/java/src/com/android/inputmethod/compat/InputMethodManagerCompatWrapper.java b/java/src/com/android/inputmethod/compat/InputMethodManagerCompatWrapper.java index 80586b753807fda0a41e2827cd0d79fa8a283ecd..e7eaba2d8450c6275250ab6cec72c25a3ed940d0 100644 --- a/java/src/com/android/inputmethod/compat/InputMethodManagerCompatWrapper.java +++ b/java/src/com/android/inputmethod/compat/InputMethodManagerCompatWrapper.java @@ -16,6 +16,7 @@ package com.android.inputmethod.compat; +import com.android.inputmethod.deprecated.LanguageSwitcherProxy; import com.android.inputmethod.latin.LatinIME; import com.android.inputmethod.latin.SubtypeSwitcher; import com.android.inputmethod.latin.Utils; @@ -56,6 +57,14 @@ public class InputMethodManagerCompatWrapper { private static final InputMethodManagerCompatWrapper sInstance = new InputMethodManagerCompatWrapper(); + public static final boolean SUBTYPE_SUPPORTED; + + static { + // This static initializer guarantees that METHOD_getShortcutInputMethodsAndSubtypes is + // already instantiated. + SUBTYPE_SUPPORTED = METHOD_getShortcutInputMethodsAndSubtypes != null; + } + // For the compatibility, IMM will create dummy subtypes if subtypes are not found. // This is required to be false if the current behavior is broken. For now, it's ok to be true. private static final boolean ALLOW_DUMMY_SUBTYPE = true; @@ -64,7 +73,9 @@ public class InputMethodManagerCompatWrapper { private static final String KEYBOARD_MODE = "keyboard"; private InputMethodManager mImm; + private LanguageSwitcherProxy mLanguageSwitcherProxy; private String mLatinImePackageName; + private InputMethodManagerCompatWrapper() { } @@ -81,15 +92,29 @@ public class InputMethodManagerCompatWrapper { if (context instanceof LatinIME) { mLatinImePackageName = context.getPackageName(); } + mLanguageSwitcherProxy = LanguageSwitcherProxy.getInstance(); } public InputMethodSubtypeCompatWrapper getCurrentInputMethodSubtype() { + if (!SUBTYPE_SUPPORTED) { + return new InputMethodSubtypeCompatWrapper( + 0, 0, mLanguageSwitcherProxy.getInputLocale().toString(), KEYBOARD_MODE, ""); + } Object o = CompatUtils.invoke(mImm, null, METHOD_getCurrentInputMethodSubtype); return new InputMethodSubtypeCompatWrapper(o); } public List<InputMethodSubtypeCompatWrapper> getEnabledInputMethodSubtypeList( InputMethodInfoCompatWrapper imi, boolean allowsImplicitlySelectedSubtypes) { + if (!SUBTYPE_SUPPORTED) { + String[] languages = mLanguageSwitcherProxy.getEnabledLanguages(); + List<InputMethodSubtypeCompatWrapper> subtypeList = + new ArrayList<InputMethodSubtypeCompatWrapper>(); + for (String lang: languages) { + subtypeList.add(new InputMethodSubtypeCompatWrapper(0, 0, lang, KEYBOARD_MODE, "")); + } + return subtypeList; + } Object retval = CompatUtils.invoke(mImm, null, METHOD_getEnabledInputMethodSubtypeList, (imi != null ? imi.getInputMethodInfo() : null), allowsImplicitlySelectedSubtypes); if (retval == null || !(retval instanceof List) || ((List<?>)retval).isEmpty()) { @@ -170,6 +195,10 @@ public class InputMethodManagerCompatWrapper { public void setInputMethodAndSubtype( IBinder token, String id, InputMethodSubtypeCompatWrapper subtype) { + if (!SUBTYPE_SUPPORTED) { + mLanguageSwitcherProxy.setLocale(subtype.getLocale()); + return; + } CompatUtils.invoke(mImm, null, METHOD_setInputMethodAndSubtype, token, id, subtype.getOriginalObject()); } diff --git a/java/src/com/android/inputmethod/compat/InputMethodSubtypeCompatWrapper.java b/java/src/com/android/inputmethod/compat/InputMethodSubtypeCompatWrapper.java index 317b02216a0e9793dfc12555ec6092cb5c23616f..86c8af37f8b574c090734f3c027b37f22100b3f1 100644 --- a/java/src/com/android/inputmethod/compat/InputMethodSubtypeCompatWrapper.java +++ b/java/src/com/android/inputmethod/compat/InputMethodSubtypeCompatWrapper.java @@ -58,9 +58,6 @@ public final class InputMethodSubtypeCompatWrapper extends AbstractCompatWrapper public InputMethodSubtypeCompatWrapper(Object subtype) { super((CLASS_InputMethodSubtype != null && CLASS_InputMethodSubtype.isInstance(subtype)) ? subtype : null); - if (DBG) { - Log.d(TAG, "CreateInputMethodSubtypeCompatWrapper"); - } mDummyNameResId = 0; mDummyIconResId = 0; mDummyLocale = DEFAULT_LOCALE; diff --git a/java/src/com/android/inputmethod/deprecated/LanguageSwitcherProxy.java b/java/src/com/android/inputmethod/deprecated/LanguageSwitcherProxy.java new file mode 100644 index 0000000000000000000000000000000000000000..5d165cda91eafb6bd55fb6d9b599f45e73bbfa60 --- /dev/null +++ b/java/src/com/android/inputmethod/deprecated/LanguageSwitcherProxy.java @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2011 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package com.android.inputmethod.deprecated; + +import com.android.inputmethod.compat.InputMethodManagerCompatWrapper; +import com.android.inputmethod.deprecated.languageswitcher.LanguageSwitcher; +import com.android.inputmethod.latin.LatinIME; + +import android.content.SharedPreferences; +import android.content.res.Configuration; + +import java.util.Locale; + +// This class is used only when the IME doesn't use method.xml for language switching. +public class LanguageSwitcherProxy { + private static final LanguageSwitcherProxy sInstance = new LanguageSwitcherProxy(); + private LanguageSwitcher mLanguageSwitcher; + private SharedPreferences mPrefs; + + public static LanguageSwitcherProxy getInstance() { + if (InputMethodManagerCompatWrapper.SUBTYPE_SUPPORTED) return null; + return sInstance; + } + + public static void init(LatinIME service, SharedPreferences prefs) { + if (InputMethodManagerCompatWrapper.SUBTYPE_SUPPORTED) return; + final Configuration conf = service.getResources().getConfiguration(); + sInstance.mLanguageSwitcher = new LanguageSwitcher(service); + sInstance.mLanguageSwitcher.loadLocales(prefs, conf.locale); + sInstance.mPrefs = prefs; + } + + public static void onConfigurationChanged(Configuration conf) { + if (InputMethodManagerCompatWrapper.SUBTYPE_SUPPORTED) return; + sInstance.mLanguageSwitcher.onConfigurationChanged(conf, sInstance.mPrefs); + } + + public static void loadSettings() { + if (InputMethodManagerCompatWrapper.SUBTYPE_SUPPORTED) return; + sInstance.mLanguageSwitcher.loadLocales(sInstance.mPrefs, null); + } + + public int getLocaleCount() { + return mLanguageSwitcher.getLocaleCount(); + } + + public String[] getEnabledLanguages() { + return mLanguageSwitcher.getEnabledLanguages(); + } + + public Locale getInputLocale() { + return mLanguageSwitcher.getInputLocale(); + } + + public void setLocale(String localeStr) { + mLanguageSwitcher.setLocale(localeStr); + mLanguageSwitcher.persist(mPrefs); + } +} diff --git a/java/src/com/android/inputmethod/latin/LanguageSwitcher.java b/java/src/com/android/inputmethod/deprecated/languageswitcher/LanguageSwitcher.java similarity index 77% rename from java/src/com/android/inputmethod/latin/LanguageSwitcher.java rename to java/src/com/android/inputmethod/deprecated/languageswitcher/LanguageSwitcher.java index 6faf7f95e32e62428a52fd12c4a3fe9bd007f2b4..639b7cdd073eb180ed9a48ba461bfa7292ac4374 100644 --- a/java/src/com/android/inputmethod/latin/LanguageSwitcher.java +++ b/java/src/com/android/inputmethod/deprecated/languageswitcher/LanguageSwitcher.java @@ -14,10 +14,16 @@ * the License. */ -package com.android.inputmethod.latin; +package com.android.inputmethod.deprecated.languageswitcher; + +import com.android.inputmethod.compat.InputMethodSubtypeCompatWrapper; +import com.android.inputmethod.latin.LatinIME; +import com.android.inputmethod.latin.Settings; +import com.android.inputmethod.latin.SharedPreferencesCompat; import android.content.SharedPreferences; import android.content.SharedPreferences.Editor; +import android.content.res.Configuration; import android.text.TextUtils; import java.util.ArrayList; @@ -29,6 +35,8 @@ import java.util.Locale; */ public class LanguageSwitcher { + private static final String KEYBOARD_MODE = "keyboard"; + private final ArrayList<Locale> mLocales = new ArrayList<Locale>(); private final LatinIME mIme; private String[] mSelectedLanguageArray; @@ -46,12 +54,24 @@ public class LanguageSwitcher { return mLocales.size(); } + public void onConfigurationChanged(Configuration conf, SharedPreferences prefs) { + final Locale newLocale = conf.locale; + if (!getSystemLocale().toString().equals(newLocale.toString())) { + loadLocales(prefs, newLocale); + } + } + /** * Loads the currently selected input languages from shared preferences. - * @param sp + * @param sp shared preference for getting the current input language and enabled languages + * @param systemLocale the current system locale, stored for changing the current input language + * based on the system current system locale. * @return whether there was any change */ - public boolean loadLocales(SharedPreferences sp) { + public boolean loadLocales(SharedPreferences sp, Locale systemLocale) { + if (systemLocale != null) { + setSystemLocale(systemLocale); + } String selectedLanguages = sp.getString(Settings.PREF_SELECTED_LANGUAGES, null); String currentLanguage = sp.getString(Settings.PREF_INPUT_LANGUAGE, null); if (selectedLanguages == null || selectedLanguages.length() < 1) { @@ -151,7 +171,7 @@ public class LanguageSwitcher { * Sets the system locale (display UI) used for comparing with the input language. * @param locale the locale of the system */ - public void setSystemLocale(Locale locale) { + private void setSystemLocale(Locale locale) { mSystemLocale = locale; } @@ -159,7 +179,7 @@ public class LanguageSwitcher { * Returns the system locale. * @return the system locale */ - public Locale getSystemLocale() { + private Locale getSystemLocale() { return mSystemLocale; } @@ -185,9 +205,22 @@ public class LanguageSwitcher { mCurrentIndex = prevLocaleIndex(); } + public void setLocale(String localeStr) { + final int N = mLocales.size(); + for (int i = 0; i < N; ++i) { + if (mLocales.get(i).toString().equals(localeStr)) { + mCurrentIndex = i; + } + } + } + public void persist(SharedPreferences prefs) { Editor editor = prefs.edit(); editor.putString(Settings.PREF_INPUT_LANGUAGE, getInputLanguage()); SharedPreferencesCompat.apply(editor); + // When the current language is changed, the event for this change should be handled + // internally as a subtype switching. + mIme.notifyOnCurrentInputMethodSubtypeChanged(new InputMethodSubtypeCompatWrapper( + 0, 0, getInputLocale().toString(), KEYBOARD_MODE, "")); } } diff --git a/java/src/com/android/inputmethod/keyboard/LatinKeyboard.java b/java/src/com/android/inputmethod/keyboard/LatinKeyboard.java index 9b87df3feefad7409314c6db6c418fcf1de85a5c..9d9793e1ef9daafb21b795ec82629b54153f51d5 100644 --- a/java/src/com/android/inputmethod/keyboard/LatinKeyboard.java +++ b/java/src/com/android/inputmethod/keyboard/LatinKeyboard.java @@ -271,7 +271,7 @@ public class LatinKeyboard extends Keyboard { canvas.drawText(language, width / 2, baseline - descent, paint); // Put arrows that are already layed out on either side of the text - if (SubtypeSwitcher.getInstance().useSpacebarLanguageSwitcher() + if (subtypeSwitcher.useSpacebarLanguageSwitcher() && subtypeSwitcher.getEnabledKeyboardLocaleCount() > 1) { mButtonArrowLeftIcon.draw(canvas); mButtonArrowRightIcon.draw(canvas); diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java index 6a858fe9905182d680b0461f638d3787e1f67646..3905a4c7aecb07f8298451bd1b273c78d955036a 100644 --- a/java/src/com/android/inputmethod/latin/LatinIME.java +++ b/java/src/com/android/inputmethod/latin/LatinIME.java @@ -23,6 +23,7 @@ import com.android.inputmethod.compat.InputMethodManagerCompatWrapper; import com.android.inputmethod.compat.InputMethodServiceCompatWrapper; import com.android.inputmethod.compat.InputTypeCompatUtils; import com.android.inputmethod.compat.VibratorCompatWrapper; +import com.android.inputmethod.deprecated.LanguageSwitcherProxy; import com.android.inputmethod.deprecated.VoiceProxy; import com.android.inputmethod.keyboard.Keyboard; import com.android.inputmethod.keyboard.KeyboardActionListener; @@ -379,6 +380,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar SubtypeSwitcher.init(this, prefs); KeyboardSwitcher.init(this, prefs); AccessibilityUtils.init(this, prefs); + LanguageSwitcherProxy.init(this, prefs); super.onCreate(); @@ -516,6 +518,9 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar super.onConfigurationChanged(conf); mVoiceProxy.onConfigurationChanged(conf); mConfigurationChanging = false; + + // This will work only when the subtype is not supported. + LanguageSwitcherProxy.onConfigurationChanged(conf); } @Override @@ -1155,10 +1160,10 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar onSettingsKeyLongPressed(); break; case Keyboard.CODE_NEXT_LANGUAGE: - toggleLanguage(false, true); + toggleLanguage(true); break; case Keyboard.CODE_PREV_LANGUAGE: - toggleLanguage(false, false); + toggleLanguage(false); break; case Keyboard.CODE_CAPSLOCK: switcher.toggleCapsLock(); @@ -1930,17 +1935,9 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar return mWord.isFirstCharCapitalized(); } - // Notify that language or mode have been changed and toggleLanguage will update KeyboaredID + // Notify that language or mode have been changed and toggleLanguage will update KeyboardID // according to new language or mode. public void onRefreshKeyboard() { - toggleLanguage(true, true); - } - - // "reset" and "next" are used only for USE_SPACEBAR_LANGUAGE_SWITCHER. - private void toggleLanguage(boolean reset, boolean next) { - if (mSubtypeSwitcher.useSpacebarLanguageSwitcher()) { - mSubtypeSwitcher.toggleLanguage(reset, next); - } // Reload keyboard because the current language has been changed. mKeyboardSwitcher.loadKeyboard(getCurrentInputEditorInfo(), mSubtypeSwitcher.isShortcutImeEnabled() && mVoiceProxy.isVoiceButtonEnabled(), @@ -1949,6 +1946,14 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar mKeyboardSwitcher.updateShiftState(); } + // "reset" and "next" are used only for USE_SPACEBAR_LANGUAGE_SWITCHER. + private void toggleLanguage(boolean next) { + if (mSubtypeSwitcher.useSpacebarLanguageSwitcher()) { + mSubtypeSwitcher.toggleLanguage(next); + } + onRefreshKeyboard();// no need?? + } + @Override public void onSwipeDown() { if (mConfigSwipeDownDismissKeyboardEnabled) @@ -2134,7 +2139,9 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar updateCorrectionMode(); updateAutoTextEnabled(); updateSuggestionVisibility(prefs); - SubtypeSwitcher.getInstance().loadSettings(); + + // This will work only when the subtype is not supported. + LanguageSwitcherProxy.loadSettings(); } /** diff --git a/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java b/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java index 053e2abe401a966e27d26be9bef50cda23d99850..2cdc4d2cda5cc947684ae1edf40434abca67e785 100644 --- a/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java +++ b/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java @@ -57,7 +57,6 @@ public class SubtypeSwitcher { private static final SubtypeSwitcher sInstance = new SubtypeSwitcher(); private /* final */ LatinIME mService; - private /* final */ SharedPreferences mPrefs; private /* final */ InputMethodManagerCompatWrapper mImm; private /* final */ Resources mResources; private /* final */ ConnectivityManager mConnectivityManager; @@ -66,6 +65,7 @@ public class SubtypeSwitcher { mEnabledKeyboardSubtypesOfCurrentInputMethod = new ArrayList<InputMethodSubtypeCompatWrapper>(); private final ArrayList<String> mEnabledLanguagesOfCurrentInputMethod = new ArrayList<String>(); + private final LanguageBarInfo mLanguageBarInfo = new LanguageBarInfo(); /*-----------------------------------------------------------*/ // Variants which should be changed only by reload functions. @@ -78,6 +78,7 @@ public class SubtypeSwitcher { private Locale mSystemLocale; private Locale mInputLocale; private String mInputLocaleStr; + private String mInputMethodId; private VoiceProxy.VoiceInputWrapper mVoiceInputWrapper; /*-----------------------------------------------------------*/ @@ -100,7 +101,6 @@ public class SubtypeSwitcher { private void initialize(LatinIME service, SharedPreferences prefs) { mService = service; - mPrefs = prefs; mResources = service.getResources(); mImm = InputMethodManagerCompatWrapper.getInstance(service); mConnectivityManager = (ConnectivityManager) service.getSystemService( @@ -114,13 +114,12 @@ public class SubtypeSwitcher { mAllEnabledSubtypesOfCurrentInputMethod = null; // TODO: Voice input should be created here mVoiceInputWrapper = null; - mConfigUseSpacebarLanguageSwitcher = mResources.getBoolean( + mConfigUseSpacebarLanguageSwitcher = service.getResources().getBoolean( R.bool.config_use_spacebar_language_switcher); - if (mConfigUseSpacebarLanguageSwitcher) - initLanguageSwitcher(service); final NetworkInfo info = mConnectivityManager.getActiveNetworkInfo(); mIsNetworkConnected = (info != null && info.isConnected()); + mInputMethodId = Utils.getInputMethodId(mImm, service.getPackageName()); } // Update all parameters stored in SubtypeSwitcher. @@ -134,11 +133,7 @@ public class SubtypeSwitcher { // Update parameters which are changed outside LatinIME. This parameters affect UI so they // should be updated every time onStartInputview. public void updateParametersOnStartInputView() { - if (mConfigUseSpacebarLanguageSwitcher) { - updateForSpacebarLanguageSwitch(); - } else { - updateEnabledSubtypes(); - } + updateEnabledSubtypes(); updateShortcutIME(); } @@ -150,7 +145,7 @@ public class SubtypeSwitcher { null, true); mEnabledLanguagesOfCurrentInputMethod.clear(); mEnabledKeyboardSubtypesOfCurrentInputMethod.clear(); - for (InputMethodSubtypeCompatWrapper ims: mAllEnabledSubtypesOfCurrentInputMethod) { + for (InputMethodSubtypeCompatWrapper ims : mAllEnabledSubtypesOfCurrentInputMethod) { final String locale = ims.getLocale(); final String mode = ims.getMode(); mLocaleSplitter.setString(locale); @@ -172,6 +167,10 @@ public class SubtypeSwitcher { Log.w(TAG, "Last subtype was disabled. Update to the current one."); } updateSubtype(mImm.getCurrentInputMethodSubtype()); + } else { + // mLanguageBarInfo.update() will be called in updateSubtype so there is no need + // to call this in the if-clause above. + mLanguageBarInfo.update(); } } @@ -269,6 +268,7 @@ public class SubtypeSwitcher { mVoiceInputWrapper.reset(); } } + mLanguageBarInfo.update(); } // Update the current input locale from Locale string. @@ -303,12 +303,21 @@ public class SubtypeSwitcher { //////////////////////////// public void switchToShortcutIME() { - final IBinder token = mService.getWindow().getWindow().getAttributes().token; - if (token == null || mShortcutInputMethodInfo == null) { + if (mShortcutInputMethodInfo == null) { return; } + final String imiId = mShortcutInputMethodInfo.getId(); final InputMethodSubtypeCompatWrapper subtype = mShortcutSubtype; + switchToTargetIME(imiId, subtype); + } + + private void switchToTargetIME( + final String imiId, final InputMethodSubtypeCompatWrapper subtype) { + final IBinder token = mService.getWindow().getWindow().getAttributes().token; + if (token == null) { + return; + } new AsyncTask<Void, Void, Void>() { @Override protected Void doInBackground(Void... params) { @@ -412,11 +421,7 @@ public class SubtypeSwitcher { ////////////////////////////////// public int getEnabledKeyboardLocaleCount() { - if (mConfigUseSpacebarLanguageSwitcher) { - return mLanguageSwitcher.getLocaleCount(); - } else { - return mEnabledKeyboardSubtypesOfCurrentInputMethod.size(); - } + return mEnabledKeyboardSubtypesOfCurrentInputMethod.size(); } public boolean useSpacebarLanguageSwitcher() { @@ -428,74 +433,37 @@ public class SubtypeSwitcher { } public Locale getInputLocale() { - if (mConfigUseSpacebarLanguageSwitcher) { - return mLanguageSwitcher.getInputLocale(); - } else { - return mInputLocale; - } + return mInputLocale; } public String getInputLocaleStr() { - if (mConfigUseSpacebarLanguageSwitcher) { - String inputLanguage = null; - inputLanguage = mLanguageSwitcher.getInputLanguage(); - // Should return system locale if there is no Language available. - if (inputLanguage == null) { - inputLanguage = getSystemLocale().getLanguage(); - } - return inputLanguage; - } else { - return mInputLocaleStr; - } + return mInputLocaleStr; } public String[] getEnabledLanguages() { - if (mConfigUseSpacebarLanguageSwitcher) { - return mLanguageSwitcher.getEnabledLanguages(); - } else { - int enabledLanguageCount = mEnabledLanguagesOfCurrentInputMethod.size(); - // Workaround for explicitly specifying the voice language - if (enabledLanguageCount == 1) { - mEnabledLanguagesOfCurrentInputMethod.add( - mEnabledLanguagesOfCurrentInputMethod.get(0)); - ++enabledLanguageCount; - } - return mEnabledLanguagesOfCurrentInputMethod.toArray( - new String[enabledLanguageCount]); + int enabledLanguageCount = mEnabledLanguagesOfCurrentInputMethod.size(); + // Workaround for explicitly specifying the voice language + if (enabledLanguageCount == 1) { + mEnabledLanguagesOfCurrentInputMethod.add(mEnabledLanguagesOfCurrentInputMethod + .get(0)); + ++enabledLanguageCount; } + return mEnabledLanguagesOfCurrentInputMethod.toArray(new String[enabledLanguageCount]); } public Locale getSystemLocale() { - if (mConfigUseSpacebarLanguageSwitcher) { - return mLanguageSwitcher.getSystemLocale(); - } else { - return mSystemLocale; - } + return mSystemLocale; } public boolean isSystemLanguageSameAsInputLanguage() { - if (mConfigUseSpacebarLanguageSwitcher) { - return getSystemLocale().getLanguage().equalsIgnoreCase( - getInputLocaleStr().substring(0, 2)); - } else { - return mIsSystemLanguageSameAsInputLanguage; - } + return mIsSystemLanguageSameAsInputLanguage; } public void onConfigurationChanged(Configuration conf) { final Locale systemLocale = conf.locale; // If system configuration was changed, update all parameters. if (!TextUtils.equals(systemLocale.toString(), mSystemLocale.toString())) { - if (mConfigUseSpacebarLanguageSwitcher) { - // If the system locale changes and is different from the saved - // locale (mSystemLocale), then reload the input locale list from the - // latin ime settings (shared prefs) and reset the input locale - // to the first one. - mLanguageSwitcher.loadLocales(mPrefs); - mLanguageSwitcher.setSystemLocale(systemLocale); - } else { - updateAllParameters(); - } + updateAllParameters(); } } @@ -554,7 +522,70 @@ public class SubtypeSwitcher { // Spacebar Language Switch support // ////////////////////////////////////// - private LanguageSwitcher mLanguageSwitcher; + private class LanguageBarInfo { + private int mCurrentKeyboardSubtypeIndex; + private InputMethodSubtypeCompatWrapper mNextKeyboardSubtype; + private InputMethodSubtypeCompatWrapper mPreviousKeyboardSubtype; + private String mNextLanguage; + private String mPreviousLanguage; + public LanguageBarInfo() { + update(); + } + + private String getNextLanguage() { + return mNextLanguage; + } + + private String getPreviousLanguage() { + return mPreviousLanguage; + } + + public InputMethodSubtypeCompatWrapper getNextKeyboardSubtype() { + return mNextKeyboardSubtype; + } + + public InputMethodSubtypeCompatWrapper getPreviousKeyboardSubtype() { + return mPreviousKeyboardSubtype; + } + + public void update() { + if (!mConfigUseSpacebarLanguageSwitcher + || mEnabledKeyboardSubtypesOfCurrentInputMethod == null + || mEnabledKeyboardSubtypesOfCurrentInputMethod.size() == 0) return; + mCurrentKeyboardSubtypeIndex = getCurrentIndex(); + mNextKeyboardSubtype = getNextKeyboardSubtypeInternal(mCurrentKeyboardSubtypeIndex); + Locale locale = new Locale(mNextKeyboardSubtype.getLocale()); + mNextLanguage = getDisplayLanguage(locale); + mPreviousKeyboardSubtype = getPreviousKeyboardSubtypeInternal( + mCurrentKeyboardSubtypeIndex); + locale = new Locale(mPreviousKeyboardSubtype.getLocale()); + mPreviousLanguage = getDisplayLanguage(locale); + } + + private int normalize(int index) { + final int N = mEnabledKeyboardSubtypesOfCurrentInputMethod.size(); + final int ret = index % N; + return ret < 0 ? ret + N : ret; + } + + private int getCurrentIndex() { + final int N = mEnabledKeyboardSubtypesOfCurrentInputMethod.size(); + for (int i = 0; i < N; ++i) { + if (mEnabledKeyboardSubtypesOfCurrentInputMethod.get(i).equals(mCurrentSubtype)) { + return i; + } + } + return 0; + } + + private InputMethodSubtypeCompatWrapper getNextKeyboardSubtypeInternal(int index) { + return mEnabledKeyboardSubtypesOfCurrentInputMethod.get(normalize(index + 1)); + } + + private InputMethodSubtypeCompatWrapper getPreviousKeyboardSubtypeInternal(int index) { + return mEnabledKeyboardSubtypesOfCurrentInputMethod.get(normalize(index - 1)); + } + } public static String getFullDisplayName(Locale locale, boolean returnsNameInThisLocale) { if (returnsNameInThisLocale) { @@ -579,32 +610,16 @@ public class SubtypeSwitcher { return Character.toUpperCase(s.charAt(0)) + s.substring(1); } - private void updateForSpacebarLanguageSwitch() { - // We need to update mNeedsToDisplayLanguage in onStartInputView because - // getEnabledKeyboardLocaleCount could have been changed. - mNeedsToDisplayLanguage = !(getEnabledKeyboardLocaleCount() <= 1 - && getSystemLocale().getLanguage().equalsIgnoreCase( - getInputLocale().getLanguage())); - } - public String getInputLanguageName() { return getDisplayLanguage(getInputLocale()); } public String getNextInputLanguageName() { - if (mConfigUseSpacebarLanguageSwitcher) { - return getDisplayLanguage(mLanguageSwitcher.getNextInputLocale()); - } else { - return ""; - } + return mLanguageBarInfo.getNextLanguage(); } public String getPreviousInputLanguageName() { - if (mConfigUseSpacebarLanguageSwitcher) { - return getDisplayLanguage(mLanguageSwitcher.getPrevInputLocale()); - } else { - return ""; - } + return mLanguageBarInfo.getPreviousLanguage(); } ///////////////////////////// @@ -644,31 +659,23 @@ public class SubtypeSwitcher { return voiceInputSupportedLocales.contains(locale); } - public void loadSettings() { - if (mConfigUseSpacebarLanguageSwitcher) { - mLanguageSwitcher.loadLocales(mPrefs); - } + private void changeToNextSubtype() { + final InputMethodSubtypeCompatWrapper subtype = + mLanguageBarInfo.getNextKeyboardSubtype(); + switchToTargetIME(mInputMethodId, subtype); } - public void toggleLanguage(boolean reset, boolean next) { - if (mConfigUseSpacebarLanguageSwitcher) { - if (reset) { - mLanguageSwitcher.reset(); - } else { - if (next) { - mLanguageSwitcher.next(); - } else { - mLanguageSwitcher.prev(); - } - } - mLanguageSwitcher.persist(mPrefs); - } + private void changeToPreviousSubtype() { + final InputMethodSubtypeCompatWrapper subtype = + mLanguageBarInfo.getPreviousKeyboardSubtype(); + switchToTargetIME(mInputMethodId, subtype); } - private void initLanguageSwitcher(LatinIME service) { - final Configuration conf = service.getResources().getConfiguration(); - mLanguageSwitcher = new LanguageSwitcher(service); - mLanguageSwitcher.loadLocales(mPrefs); - mLanguageSwitcher.setSystemLocale(conf.locale); + public void toggleLanguage(boolean next) { + if (next) { + changeToNextSubtype(); + } else { + changeToPreviousSubtype(); + } } }