Fix SubtypeSwitcher to honor subtype

Bug: 6364170
Change-Id: I31f9a7c9b6b4ca04a1c78a4210dcaae0db9825db
This commit is contained in:
Tadashi G. Takaoka 2012-04-19 21:47:28 +09:00
parent aae757b8a1
commit 65e93e352f
2 changed files with 47 additions and 137 deletions

View File

@ -455,8 +455,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
} }
private void initSuggest() { private void initSuggest() {
final String localeStr = mSubtypeSwitcher.getInputLocaleStr();
final Locale keyboardLocale = mSubtypeSwitcher.getInputLocale(); final Locale keyboardLocale = mSubtypeSwitcher.getInputLocale();
final String localeStr = keyboardLocale.toString();
final Dictionary oldContactsDictionary; final Dictionary oldContactsDictionary;
if (mSuggest != null) { if (mSuggest != null) {

View File

@ -16,19 +16,16 @@
package com.android.inputmethod.latin; package com.android.inputmethod.latin;
import static com.android.inputmethod.latin.Constants.Subtype.KEYBOARD_MODE;
import static com.android.inputmethod.latin.Constants.Subtype.ExtraValue.REQ_NETWORK_CONNECTIVITY; import static com.android.inputmethod.latin.Constants.Subtype.ExtraValue.REQ_NETWORK_CONNECTIVITY;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.Configuration; import android.content.res.Configuration;
import android.content.res.Resources; import android.content.res.Resources;
import android.net.ConnectivityManager; import android.net.ConnectivityManager;
import android.net.NetworkInfo; import android.net.NetworkInfo;
import android.os.AsyncTask; import android.os.AsyncTask;
import android.os.IBinder; import android.os.IBinder;
import android.text.TextUtils;
import android.util.Log; import android.util.Log;
import android.view.inputmethod.InputMethodInfo; import android.view.inputmethod.InputMethodInfo;
import android.view.inputmethod.InputMethodManager; import android.view.inputmethod.InputMethodManager;
@ -36,7 +33,6 @@ import android.view.inputmethod.InputMethodSubtype;
import com.android.inputmethod.keyboard.KeyboardSwitcher; import com.android.inputmethod.keyboard.KeyboardSwitcher;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
@ -45,37 +41,43 @@ public class SubtypeSwitcher {
private static boolean DBG = LatinImeLogger.sDBG; private static boolean DBG = LatinImeLogger.sDBG;
private static final String TAG = SubtypeSwitcher.class.getSimpleName(); private static final String TAG = SubtypeSwitcher.class.getSimpleName();
private static final char LOCALE_SEPARATOR = '_';
private final TextUtils.SimpleStringSplitter mLocaleSplitter =
new TextUtils.SimpleStringSplitter(LOCALE_SEPARATOR);
private static final SubtypeSwitcher sInstance = new SubtypeSwitcher(); private static final SubtypeSwitcher sInstance = new SubtypeSwitcher();
private /* final */ LatinIME mService; private /* final */ LatinIME mService;
private /* final */ InputMethodManager mImm; private /* final */ InputMethodManager mImm;
private /* final */ Resources mResources; private /* final */ Resources mResources;
private /* final */ ConnectivityManager mConnectivityManager; private /* final */ ConnectivityManager mConnectivityManager;
private final ArrayList<InputMethodSubtype> mEnabledKeyboardSubtypesOfCurrentInputMethod =
new ArrayList<InputMethodSubtype>();
private final ArrayList<String> mEnabledLanguagesOfCurrentInputMethod = new ArrayList<String>();
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
// Variants which should be changed only by reload functions. // Variants which should be changed only by reload functions.
private boolean mNeedsToDisplayLanguage; private NeedsToDisplayLanguage mNeedsToDisplayLanguage = new NeedsToDisplayLanguage();
private boolean mIsDictionaryAvailable; private boolean mIsDictionaryAvailable;
private boolean mIsSystemLanguageSameAsInputLanguage;
private InputMethodInfo mShortcutInputMethodInfo; private InputMethodInfo mShortcutInputMethodInfo;
private InputMethodSubtype mShortcutSubtype; private InputMethodSubtype mShortcutSubtype;
private List<InputMethodSubtype> mAllEnabledSubtypesOfCurrentInputMethod;
private InputMethodSubtype mNoLanguageSubtype; private InputMethodSubtype mNoLanguageSubtype;
// Note: This variable is always non-null after {@link #initialize(LatinIME)}. // Note: This variable is always non-null after {@link #initialize(LatinIME)}.
private InputMethodSubtype mCurrentSubtype; private InputMethodSubtype mCurrentSubtype;
private Locale mSystemLocale; private Locale mCurrentSystemLocale;
private Locale mInputLocale;
private String mInputLocaleStr;
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
private boolean mIsNetworkConnected; private boolean mIsNetworkConnected;
static class NeedsToDisplayLanguage {
private int mEnabledSubtypeCount;
private boolean mIsSystemLanguageSameAsInputLanguage;
public boolean getValue() {
return mEnabledSubtypeCount >= 2 || !mIsSystemLanguageSameAsInputLanguage;
}
public void updateEnabledSubtypeCount(int count) {
mEnabledSubtypeCount = count;
}
public void updateIsSystemLanguageSameAsInputLanguage(boolean isSame) {
mIsSystemLanguageSameAsInputLanguage = isSame;
}
}
public static SubtypeSwitcher getInstance() { public static SubtypeSwitcher getInstance() {
return sInstance; return sInstance;
} }
@ -96,13 +98,8 @@ public class SubtypeSwitcher {
mImm = ImfUtils.getInputMethodManager(service); mImm = ImfUtils.getInputMethodManager(service);
mConnectivityManager = (ConnectivityManager) service.getSystemService( mConnectivityManager = (ConnectivityManager) service.getSystemService(
Context.CONNECTIVITY_SERVICE); Context.CONNECTIVITY_SERVICE);
mEnabledKeyboardSubtypesOfCurrentInputMethod.clear(); mCurrentSystemLocale = mResources.getConfiguration().locale;
mEnabledLanguagesOfCurrentInputMethod.clear();
mSystemLocale = null;
mInputLocale = null;
mInputLocaleStr = null;
mCurrentSubtype = mImm.getCurrentInputMethodSubtype(); mCurrentSubtype = mImm.getCurrentInputMethodSubtype();
mAllEnabledSubtypesOfCurrentInputMethod = null;
mNoLanguageSubtype = ImfUtils.findSubtypeByLocaleAndKeyboardLayoutSet( mNoLanguageSubtype = ImfUtils.findSubtypeByLocaleAndKeyboardLayoutSet(
service, SubtypeLocale.NO_LANGUAGE, AdditionalSubtype.QWERTY); service, SubtypeLocale.NO_LANGUAGE, AdditionalSubtype.QWERTY);
@ -113,7 +110,7 @@ public class SubtypeSwitcher {
// Update all parameters stored in SubtypeSwitcher. // Update all parameters stored in SubtypeSwitcher.
// Only configuration changed event is allowed to call this because this is heavy. // Only configuration changed event is allowed to call this because this is heavy.
private void updateAllParameters() { private void updateAllParameters() {
mSystemLocale = mResources.getConfiguration().locale; mCurrentSystemLocale = mResources.getConfiguration().locale;
updateSubtype(mImm.getCurrentInputMethodSubtype()); updateSubtype(mImm.getCurrentInputMethodSubtype());
updateParametersOnStartInputView(); updateParametersOnStartInputView();
} }
@ -127,31 +124,20 @@ public class SubtypeSwitcher {
// Reload enabledSubtypes from the framework. // Reload enabledSubtypes from the framework.
private void updateEnabledSubtypes() { private void updateEnabledSubtypes() {
final String currentMode = mCurrentSubtype.getMode(); final InputMethodSubtype currentSubtype = mCurrentSubtype;
boolean foundCurrentSubtypeBecameDisabled = true; boolean foundCurrentSubtypeBecameDisabled = true;
mAllEnabledSubtypesOfCurrentInputMethod = mImm.getEnabledInputMethodSubtypeList( final List<InputMethodSubtype> enabledSubtypesOfThisIme =
null, true); mImm.getEnabledInputMethodSubtypeList(null, true);
mEnabledLanguagesOfCurrentInputMethod.clear(); for (InputMethodSubtype ims : enabledSubtypesOfThisIme) {
mEnabledKeyboardSubtypesOfCurrentInputMethod.clear(); if (ims.equals(currentSubtype)) {
for (InputMethodSubtype ims : mAllEnabledSubtypesOfCurrentInputMethod) {
final String locale = ims.getLocale();
final String mode = ims.getMode();
mLocaleSplitter.setString(locale);
if (mLocaleSplitter.hasNext()) {
mEnabledLanguagesOfCurrentInputMethod.add(mLocaleSplitter.next());
}
if (locale.equals(mInputLocaleStr) && mode.equals(currentMode)) {
foundCurrentSubtypeBecameDisabled = false; foundCurrentSubtypeBecameDisabled = false;
} }
if (KEYBOARD_MODE.equals(ims.getMode())) {
mEnabledKeyboardSubtypesOfCurrentInputMethod.add(ims);
}
} }
mNeedsToDisplayLanguage = !(getEnabledKeyboardLocaleCount() <= 1 mNeedsToDisplayLanguage.updateEnabledSubtypeCount(enabledSubtypesOfThisIme.size());
&& mIsSystemLanguageSameAsInputLanguage);
if (foundCurrentSubtypeBecameDisabled) { if (foundCurrentSubtypeBecameDisabled) {
if (DBG) { if (DBG) {
Log.w(TAG, "Current subtype: " + mInputLocaleStr + ", " + currentMode); Log.w(TAG, "Last subtype: "
+ currentSubtype.getLocale() + "/" + currentSubtype.getExtraValue());
Log.w(TAG, "Last subtype was disabled. Update to the current one."); Log.w(TAG, "Last subtype was disabled. Update to the current one.");
} }
updateSubtype(mImm.getCurrentInputMethodSubtype()); updateSubtype(mImm.getCurrentInputMethodSubtype());
@ -192,70 +178,21 @@ public class SubtypeSwitcher {
// Update the current subtype. LatinIME.onCurrentInputMethodSubtypeChanged calls this function. // Update the current subtype. LatinIME.onCurrentInputMethodSubtypeChanged calls this function.
public void updateSubtype(InputMethodSubtype newSubtype) { public void updateSubtype(InputMethodSubtype newSubtype) {
final String newLocale = newSubtype.getLocale();
final String newMode = newSubtype.getMode();
final String oldMode = mCurrentSubtype.getMode();
if (DBG) { if (DBG) {
Log.w(TAG, "Update subtype to:" + newLocale + "," + newMode Log.w(TAG, "onCurrentInputMethodSubtypeChanged: to: "
+ ", from: " + mInputLocaleStr + ", " + oldMode); + newSubtype.getLocale() + "/" + newSubtype.getExtraValue() + ", from: "
} + mCurrentSubtype.getLocale() + "/" + mCurrentSubtype.getExtraValue());
boolean languageChanged = false;
if (!newLocale.equals(mInputLocaleStr)) {
if (mInputLocaleStr != null) {
languageChanged = true;
}
updateInputLocale(newLocale);
}
boolean modeChanged = false;
if (!newMode.equals(oldMode)) {
if (oldMode != null) {
modeChanged = true;
}
} }
if (newSubtype.equals(mCurrentSubtype)) return;
final Locale newLocale = SubtypeLocale.getSubtypeLocale(newSubtype);
mNeedsToDisplayLanguage.updateIsSystemLanguageSameAsInputLanguage(
mCurrentSystemLocale.equals(newLocale));
mIsDictionaryAvailable = DictionaryFactory.isDictionaryAvailable(mService, newLocale);
mCurrentSubtype = newSubtype; mCurrentSubtype = newSubtype;
updateShortcutIME();
if (KEYBOARD_MODE.equals(mCurrentSubtype.getMode())) { mService.onRefreshKeyboard();
if (modeChanged || languageChanged) {
updateShortcutIME();
mService.onRefreshKeyboard();
}
} else {
final String packageName = mService.getPackageName();
int version = -1;
try {
version = mService.getPackageManager().getPackageInfo(
packageName, 0).versionCode;
} catch (NameNotFoundException e) {
}
Log.w(TAG, "Unknown subtype mode: " + newMode + "," + version + ", " + packageName
+ ". IME is already changed to other IME.");
Log.w(TAG, "Subtype mode:" + newSubtype.getMode());
Log.w(TAG, "Subtype locale:" + newSubtype.getLocale());
Log.w(TAG, "Subtype extra value:" + newSubtype.getExtraValue());
Log.w(TAG, "Subtype is auxiliary:" + newSubtype.isAuxiliary());
}
}
// Update the current input locale from Locale string.
private void updateInputLocale(String inputLocaleStr) {
// example: inputLocaleStr = "en_US" "en" ""
// "en_US" --> language: en & country: US
// "en" --> language: en
// "" --> the system locale
if (!TextUtils.isEmpty(inputLocaleStr)) {
mInputLocale = LocaleUtils.constructLocaleFromString(inputLocaleStr);
mInputLocaleStr = inputLocaleStr;
} else {
mInputLocale = mSystemLocale;
String country = mSystemLocale.getCountry();
mInputLocaleStr = mSystemLocale.getLanguage()
+ (TextUtils.isEmpty(country) ? "" : "_" + mSystemLocale.getLanguage());
}
mIsSystemLanguageSameAsInputLanguage = getSystemLocale().getLanguage().equalsIgnoreCase(
getInputLocale().getLanguage());
mNeedsToDisplayLanguage = !(getEnabledKeyboardLocaleCount() <= 1
&& mIsSystemLanguageSameAsInputLanguage);
mIsDictionaryAvailable = DictionaryFactory.isDictionaryAvailable(mService, mInputLocale);
} }
//////////////////////////// ////////////////////////////
@ -323,54 +260,27 @@ public class SubtypeSwitcher {
} }
////////////////////////////////// //////////////////////////////////
// Language Switching functions // // Subtype Switching functions //
////////////////////////////////// //////////////////////////////////
public int getEnabledKeyboardLocaleCount() {
return mEnabledKeyboardSubtypesOfCurrentInputMethod.size();
}
public boolean needsToDisplayLanguage(Locale keyboardLocale) { public boolean needsToDisplayLanguage(Locale keyboardLocale) {
if (keyboardLocale.toString().equals(SubtypeLocale.NO_LANGUAGE)) { if (keyboardLocale.toString().equals(SubtypeLocale.NO_LANGUAGE)) {
return true; return true;
} }
if (!keyboardLocale.equals(mInputLocale)) { if (!keyboardLocale.equals(getInputLocale())) {
return false; return false;
} }
return mNeedsToDisplayLanguage; return mNeedsToDisplayLanguage.getValue();
} }
public Locale getInputLocale() { public Locale getInputLocale() {
return mInputLocale; return SubtypeLocale.getSubtypeLocale(mCurrentSubtype);
}
public String getInputLocaleStr() {
return mInputLocaleStr;
}
public String[] getEnabledLanguages() {
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() {
return mSystemLocale;
}
public boolean isSystemLanguageSameAsInputLanguage() {
return mIsSystemLanguageSameAsInputLanguage;
} }
public void onConfigurationChanged(Configuration conf) { public void onConfigurationChanged(Configuration conf) {
final Locale systemLocale = conf.locale; final Locale systemLocale = conf.locale;
// If system configuration was changed, update all parameters. // If system configuration was changed, update all parameters.
if (!TextUtils.equals(systemLocale.toString(), mSystemLocale.toString())) { if (!systemLocale.equals(mCurrentSystemLocale)) {
updateAllParameters(); updateAllParameters();
} }
} }