Experimental automatic language switching support.
With this CL, LatinIME switches the current subtype from its enabled subtypes based on the first locale in EditorInfo#hintLocales. This functionality is still experimental, and will be triggered only when EditorInfo#hintLocales is specified by the application. Bug: 22859862 Change-Id: Ibd0559b370d8aa0d50d1bada8ecfdac0ed8db898
This commit is contained in:
parent
16645966a9
commit
809c93214b
2 changed files with 70 additions and 1 deletions
|
@ -54,7 +54,9 @@ import android.view.inputmethod.InputMethodSubtype;
|
|||
|
||||
import com.android.inputmethod.accessibility.AccessibilityUtils;
|
||||
import com.android.inputmethod.annotations.UsedForTesting;
|
||||
import com.android.inputmethod.compat.EditorInfoCompatUtils;
|
||||
import com.android.inputmethod.compat.InputMethodServiceCompatUtils;
|
||||
import com.android.inputmethod.compat.InputMethodSubtypeCompatUtils;
|
||||
import com.android.inputmethod.compat.ViewOutlineProviderCompatUtils;
|
||||
import com.android.inputmethod.compat.ViewOutlineProviderCompatUtils.InsetsUpdater;
|
||||
import com.android.inputmethod.dictionarypack.DictionaryPackConstants;
|
||||
|
@ -176,8 +178,9 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
|||
private static final int MSG_WAIT_FOR_DICTIONARY_LOAD = 8;
|
||||
private static final int MSG_DEALLOCATE_MEMORY = 9;
|
||||
private static final int MSG_RESUME_SUGGESTIONS_FOR_START_INPUT = 10;
|
||||
private static final int MSG_SWITCH_LANGUAGE_AUTOMATICALLY = 11;
|
||||
// Update this when adding new messages
|
||||
private static final int MSG_LAST = MSG_RESUME_SUGGESTIONS_FOR_START_INPUT;
|
||||
private static final int MSG_LAST = MSG_SWITCH_LANGUAGE_AUTOMATICALLY;
|
||||
|
||||
private static final int ARG1_NOT_GESTURE_INPUT = 0;
|
||||
private static final int ARG1_DISMISS_GESTURE_FLOATING_PREVIEW_TEXT = 1;
|
||||
|
@ -271,6 +274,9 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
|||
case MSG_DEALLOCATE_MEMORY:
|
||||
latinIme.deallocateMemory();
|
||||
break;
|
||||
case MSG_SWITCH_LANGUAGE_AUTOMATICALLY:
|
||||
latinIme.switchLanguage((InputMethodSubtype)msg.obj);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -389,6 +395,10 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
|||
obtainMessage(MSG_UPDATE_TAIL_BATCH_INPUT_COMPLETED, suggestedWords).sendToTarget();
|
||||
}
|
||||
|
||||
public void postSwitchLanguage(final InputMethodSubtype subtype) {
|
||||
obtainMessage(MSG_SWITCH_LANGUAGE_AUTOMATICALLY, subtype).sendToTarget();
|
||||
}
|
||||
|
||||
// Working variables for the following methods.
|
||||
private boolean mIsOrientationChanging;
|
||||
private boolean mPendingSuccessiveImsCallback;
|
||||
|
@ -795,6 +805,19 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
|||
|
||||
void onStartInputInternal(final EditorInfo editorInfo, final boolean restarting) {
|
||||
super.onStartInput(editorInfo, restarting);
|
||||
|
||||
// If the primary hint language does not match the current subtype language, then try
|
||||
// to switch to the primary hint language.
|
||||
// TODO: Support all the locales in EditorInfo#hintLocales.
|
||||
final Locale primaryHintLocale = EditorInfoCompatUtils.getPrimaryHintLocale(editorInfo);
|
||||
if (primaryHintLocale == null) {
|
||||
return;
|
||||
}
|
||||
final InputMethodSubtype newSubtype = mRichImm.findSubtypeByLocale(primaryHintLocale);
|
||||
if (newSubtype == null || newSubtype.equals(mRichImm.getCurrentSubtype().getRawSubtype())) {
|
||||
return;
|
||||
}
|
||||
mHandler.postSwitchLanguage(newSubtype);
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
|
@ -1301,6 +1324,11 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
|||
return mOptionsDialog != null && mOptionsDialog.isShowing();
|
||||
}
|
||||
|
||||
public void switchLanguage(final InputMethodSubtype subtype) {
|
||||
final IBinder token = getWindow().getWindow().getAttributes().token;
|
||||
mRichImm.setInputMethodAndSubtype(token, subtype);
|
||||
}
|
||||
|
||||
// TODO: Revise the language switch key behavior to make it much smarter and more reasonable.
|
||||
public void switchToNextSubtype() {
|
||||
final IBinder token = getWindow().getWindow().getAttributes().token;
|
||||
|
|
|
@ -32,6 +32,7 @@ import android.view.inputmethod.InputMethodSubtype;
|
|||
|
||||
import com.android.inputmethod.annotations.UsedForTesting;
|
||||
import com.android.inputmethod.compat.InputMethodManagerCompatWrapper;
|
||||
import com.android.inputmethod.compat.InputMethodSubtypeCompatUtils;
|
||||
import com.android.inputmethod.latin.settings.Settings;
|
||||
import com.android.inputmethod.latin.utils.AdditionalSubtypeUtils;
|
||||
import com.android.inputmethod.latin.utils.LanguageOnSpacebarUtils;
|
||||
|
@ -428,6 +429,46 @@ public class RichInputMethodManager {
|
|||
return null;
|
||||
}
|
||||
|
||||
public InputMethodSubtype findSubtypeByLocale(final Locale locale) {
|
||||
// Find the best subtype based on a straightforward matching algorithm.
|
||||
// TODO: Use LocaleList#getFirstMatch() instead.
|
||||
final List<InputMethodSubtype> subtypes =
|
||||
getMyEnabledInputMethodSubtypeList(true /* allowsImplicitlySelectedSubtypes */);
|
||||
final int count = subtypes.size();
|
||||
for (int i = 0; i < count; ++i) {
|
||||
final InputMethodSubtype subtype = subtypes.get(i);
|
||||
final Locale subtypeLocale = InputMethodSubtypeCompatUtils.getLocaleObject(subtype);
|
||||
if (subtypeLocale.equals(locale)) {
|
||||
return subtype;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < count; ++i) {
|
||||
final InputMethodSubtype subtype = subtypes.get(i);
|
||||
final Locale subtypeLocale = InputMethodSubtypeCompatUtils.getLocaleObject(subtype);
|
||||
if (subtypeLocale.getLanguage().equals(locale.getLanguage()) &&
|
||||
subtypeLocale.getCountry().equals(locale.getCountry()) &&
|
||||
subtypeLocale.getVariant().equals(locale.getVariant())) {
|
||||
return subtype;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < count; ++i) {
|
||||
final InputMethodSubtype subtype = subtypes.get(i);
|
||||
final Locale subtypeLocale = InputMethodSubtypeCompatUtils.getLocaleObject(subtype);
|
||||
if (subtypeLocale.getLanguage().equals(locale.getLanguage()) &&
|
||||
subtypeLocale.getCountry().equals(locale.getCountry())) {
|
||||
return subtype;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < count; ++i) {
|
||||
final InputMethodSubtype subtype = subtypes.get(i);
|
||||
final Locale subtypeLocale = InputMethodSubtypeCompatUtils.getLocaleObject(subtype);
|
||||
if (subtypeLocale.getLanguage().equals(locale.getLanguage())) {
|
||||
return subtype;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void setInputMethodAndSubtype(final IBinder token, final InputMethodSubtype subtype) {
|
||||
mImmWrapper.mImm.setInputMethodAndSubtype(
|
||||
token, getInputMethodIdOfThisIme(), subtype);
|
||||
|
|
Loading…
Reference in a new issue