diff options
Diffstat (limited to 'java/src')
19 files changed, 185 insertions, 111 deletions
diff --git a/java/src/com/android/inputmethod/compat/SuggestionSpanUtils.java b/java/src/com/android/inputmethod/compat/SuggestionSpanUtils.java index 27db9b8e8..d3e24e342 100644 --- a/java/src/com/android/inputmethod/compat/SuggestionSpanUtils.java +++ b/java/src/com/android/inputmethod/compat/SuggestionSpanUtils.java @@ -28,9 +28,13 @@ import com.android.inputmethod.latin.SuggestedWords; import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo; import com.android.inputmethod.latin.SuggestionSpanPickedNotificationReceiver; import com.android.inputmethod.latin.define.DebugFlags; +import com.android.inputmethod.latin.utils.LocaleUtils; import java.lang.reflect.Field; import java.util.ArrayList; +import java.util.Locale; + +import javax.annotation.Nullable; public final class SuggestionSpanUtils { // Note that SuggestionSpan.FLAG_AUTO_CORRECTION has been introduced @@ -98,4 +102,28 @@ public final class SuggestionSpanUtils { spannable.setSpan(suggestionSpan, 0, pickedWord.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); return spannable; } + + /** + * Returns first {@link Locale} found in the given array of {@link SuggestionSpan}. + * @param suggestionSpans the array of {@link SuggestionSpan} to be examined. + * @return the first {@link Locale} found in {@code suggestionSpans}. {@code null} when not + * found. + */ + @UsedForTesting + @Nullable + public static Locale findFirstLocaleFromSuggestionSpans( + final SuggestionSpan[] suggestionSpans) { + for (final SuggestionSpan suggestionSpan : suggestionSpans) { + final String localeString = suggestionSpan.getLocale(); + if (TextUtils.isEmpty(localeString)) { + continue; + } + final Locale locale = LocaleUtils.constructLocaleFromString(localeString); + if (locale == null) { + continue; + } + return locale; + } + return null; + } } diff --git a/java/src/com/android/inputmethod/keyboard/Key.java b/java/src/com/android/inputmethod/keyboard/Key.java index bf29b5ffe..45ce6a85f 100644 --- a/java/src/com/android/inputmethod/keyboard/Key.java +++ b/java/src/com/android/inputmethod/keyboard/Key.java @@ -278,8 +278,8 @@ public class Key implements Comparable<Key> { mLabelFlags = style.getFlags(keyAttr, R.styleable.Keyboard_Key_keyLabelFlags) | row.getDefaultKeyLabelFlags(); - final boolean needsToUpperCase = needsToUpperCase(mLabelFlags, params.mId.mElementId); - final Locale locale = params.mId.mLocale; + final boolean needsToUpcase = needsToUpcase(mLabelFlags, params.mId.mElementId); + final Locale localeForUpcasing = params.mId.getLocales()[0]; int actionFlags = style.getFlags(keyAttr, R.styleable.Keyboard_Key_keyActionFlags); String[] moreKeys = style.getStringArray(keyAttr, R.styleable.Keyboard_Key_moreKeys); @@ -321,7 +321,7 @@ public class Key implements Comparable<Key> { actionFlags |= ACTION_FLAGS_ENABLE_LONG_PRESS; mMoreKeys = new MoreKeySpec[moreKeys.length]; for (int i = 0; i < moreKeys.length; i++) { - mMoreKeys[i] = new MoreKeySpec(moreKeys[i], needsToUpperCase, locale); + mMoreKeys[i] = new MoreKeySpec(moreKeys[i], needsToUpcase, localeForUpcasing); } } else { mMoreKeys = null; @@ -342,16 +342,16 @@ public class Key implements Comparable<Key> { mLabel = new StringBuilder().appendCodePoint(code).toString(); } else { mLabel = StringUtils.toUpperCaseOfStringForLocale( - KeySpecParser.getLabel(keySpec), needsToUpperCase, locale); + KeySpecParser.getLabel(keySpec), needsToUpcase, localeForUpcasing); } if ((mLabelFlags & LABEL_FLAGS_DISABLE_HINT_LABEL) != 0) { mHintLabel = null; } else { mHintLabel = StringUtils.toUpperCaseOfStringForLocale(style.getString(keyAttr, - R.styleable.Keyboard_Key_keyHintLabel), needsToUpperCase, locale); + R.styleable.Keyboard_Key_keyHintLabel), needsToUpcase, localeForUpcasing); } String outputText = StringUtils.toUpperCaseOfStringForLocale( - KeySpecParser.getOutputText(keySpec), needsToUpperCase, locale); + KeySpecParser.getOutputText(keySpec), needsToUpcase, localeForUpcasing); // Choose the first letter of the label as primary code if not specified. if (code == CODE_UNSPECIFIED && TextUtils.isEmpty(outputText) && !TextUtils.isEmpty(mLabel)) { @@ -377,12 +377,12 @@ public class Key implements Comparable<Key> { mCode = CODE_OUTPUT_TEXT; } } else { - mCode = StringUtils.toUpperCaseOfCodeForLocale(code, needsToUpperCase, locale); + mCode = StringUtils.toUpperCaseOfCodeForLocale(code, needsToUpcase, localeForUpcasing); } final int altCodeInAttr = KeySpecParser.parseCode( style.getString(keyAttr, R.styleable.Keyboard_Key_altCode), CODE_UNSPECIFIED); final int altCode = StringUtils.toUpperCaseOfCodeForLocale( - altCodeInAttr, needsToUpperCase, locale); + altCodeInAttr, needsToUpcase, localeForUpcasing); mOptionalAttributes = OptionalAttributes.newInstance(outputText, altCode, disabledIconId, visualInsetsLeft, visualInsetsRight); mKeyVisualAttributes = KeyVisualAttributes.newInstance(keyAttr); @@ -432,7 +432,7 @@ public class Key implements Comparable<Key> { return (filteredMoreKeys == moreKeys) ? key : new Key(key, filteredMoreKeys); } - private static boolean needsToUpperCase(final int labelFlags, final int keyboardElementId) { + private static boolean needsToUpcase(final int labelFlags, final int keyboardElementId) { if ((labelFlags & LABEL_FLAGS_PRESERVE_CASE) != 0) return false; switch (keyboardElementId) { case KeyboardId.ELEMENT_ALPHABET_MANUAL_SHIFTED: diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardId.java b/java/src/com/android/inputmethod/keyboard/KeyboardId.java index f9cf3535e..ab0d63306 100644 --- a/java/src/com/android/inputmethod/keyboard/KeyboardId.java +++ b/java/src/com/android/inputmethod/keyboard/KeyboardId.java @@ -63,7 +63,6 @@ public final class KeyboardId { public static final int ELEMENT_EMOJI_CATEGORY6 = 16; public final RichInputMethodSubtype mSubtype; - public final Locale mLocale; public final int mWidth; public final int mHeight; public final int mMode; @@ -79,7 +78,6 @@ public final class KeyboardId { public KeyboardId(final int elementId, final KeyboardLayoutSet.Params params) { mSubtype = params.mSubtype; - mLocale = SubtypeLocaleUtils.getSubtypeLocale(mSubtype); mWidth = params.mKeyboardWidth; mHeight = params.mKeyboardHeight; mMode = params.mMode; @@ -167,6 +165,10 @@ public final class KeyboardId { return InputTypeUtils.getImeOptionsActionIdFromEditorInfo(mEditorInfo); } + public Locale[] getLocales() { + return mSubtype.getLocales(); + } + @Override public boolean equals(final Object other) { return other instanceof KeyboardId && equals((KeyboardId) other); @@ -181,7 +183,8 @@ public final class KeyboardId { public String toString() { return String.format(Locale.ROOT, "[%s %s:%s %dx%d %s %s%s%s%s%s%s%s%s%s]", elementIdToName(mElementId), - mLocale, mSubtype.getExtraValueOf(KEYBOARD_LAYOUT_SET), + Arrays.deepToString(mSubtype.getLocales()), + mSubtype.getExtraValueOf(KEYBOARD_LAYOUT_SET), mWidth, mHeight, modeName(mMode), actionName(imeAction()), diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java index 7f2957fff..93123d1ec 100644 --- a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java +++ b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java @@ -120,7 +120,9 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions { mKeyboardLayoutSet = builder.build(); try { mState.onLoadKeyboard(currentAutoCapsState, currentRecapitalizeState); - mKeyboardTextsSet.setLocale(mSubtypeSwitcher.getCurrentSubtypeLocale(), mThemeContext); + // TODO: revisit this for multi-lingual input + mKeyboardTextsSet.setLocale(mSubtypeSwitcher.getCurrentSubtypeLocales()[0], + mThemeContext); } catch (KeyboardLayoutSetException e) { Log.w(TAG, "loading keyboard failed: " + e.mKeyboardId, e.getCause()); return; @@ -161,7 +163,7 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions { currentSettingsValues.mKeyPreviewDismissDuration); keyboardView.updateShortcutKey(mSubtypeSwitcher.isShortcutImeReady()); final boolean subtypeChanged = (oldKeyboard == null) - || !keyboard.mId.mLocale.equals(oldKeyboard.mId.mLocale); + || !keyboard.mId.mSubtype.equals(oldKeyboard.mId.mSubtype); final int languageOnSpacebarFormatType = mSubtypeSwitcher.getLanguageOnSpacebarFormatType( keyboard.mId.mSubtype); final boolean hasMultipleEnabledIMEsOrSubtypes = RichInputMethodManager.getInstance() diff --git a/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java b/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java index cded2cb8c..ad30b746e 100644 --- a/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java +++ b/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java @@ -875,6 +875,11 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack // Layout language name on spacebar. private String layoutLanguageOnSpacebar(final Paint paint, final RichInputMethodSubtype subtype, final int width) { + if (mLanguageOnSpacebarFormatType == LanguageOnSpacebarHelper.FORMAT_TYPE_MULTIPLE) { + // TODO: return an appropriate string + return ""; + } + // Choose appropriate language name to fit into the width. if (mLanguageOnSpacebarFormatType == LanguageOnSpacebarHelper.FORMAT_TYPE_FULL_LOCALE) { final String fullText = subtype.getFullDisplayName(); diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardBuilder.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardBuilder.java index 50385555c..f4e010c4d 100644 --- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardBuilder.java +++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardBuilder.java @@ -45,6 +45,7 @@ import org.xmlpull.v1.XmlPullParserException; import java.io.IOException; import java.util.Arrays; +import java.util.Locale; /** * Keyboard Building helper. @@ -281,7 +282,8 @@ public class KeyboardBuilder<KP extends KeyboardParams> { params.mThemeId = keyboardAttr.getInt(R.styleable.Keyboard_themeId, 0); params.mIconsSet.loadIcons(keyboardAttr); - params.mTextsSet.setLocale(params.mId.mLocale, mContext); + // TODO: this needs to be revisited for multi-lingual input. + params.mTextsSet.setLocale(params.mId.getLocales()[0], mContext); final int resourceId = keyboardAttr.getResourceId( R.styleable.Keyboard_touchPositionCorrectionData, 0); @@ -672,12 +674,10 @@ public class KeyboardBuilder<KP extends KeyboardParams> { R.styleable.Keyboard_Case_imeAction, id.imeAction()); final boolean isIconDefinedMatched = isIconDefined(caseAttr, R.styleable.Keyboard_Case_isIconDefined, mParams.mIconsSet); - final boolean localeCodeMatched = matchString(caseAttr, - R.styleable.Keyboard_Case_localeCode, id.mLocale.toString()); - final boolean languageCodeMatched = matchString(caseAttr, - R.styleable.Keyboard_Case_languageCode, id.mLocale.getLanguage()); - final boolean countryCodeMatched = matchString(caseAttr, - R.styleable.Keyboard_Case_countryCode, id.mLocale.getCountry()); + final Locale[] locales = id.getLocales(); + final boolean localeCodeMatched = matchLocaleCodes(caseAttr, locales); + final boolean languageCodeMatched = matchLanguageCodes(caseAttr, locales); + final boolean countryCodeMatched = matchCountryCodes(caseAttr, locales); final boolean splitLayoutMatched = matchBoolean(caseAttr, R.styleable.Keyboard_Case_isSplitLayout, id.mIsSplitLayout); final boolean selected = keyboardLayoutSetMatched && keyboardLayoutSetElementMatched @@ -733,6 +733,23 @@ public class KeyboardBuilder<KP extends KeyboardParams> { } } + private boolean matchLocaleCodes(TypedArray caseAttr, final Locale[] locales) { + // TODO: adujst this for multilingual input + return matchString(caseAttr, R.styleable.Keyboard_Case_localeCode, locales[0].toString()); + } + + private boolean matchLanguageCodes(TypedArray caseAttr, Locale[] locales) { + // TODO: adujst this for multilingual input + return matchString(caseAttr, R.styleable.Keyboard_Case_languageCode, + locales[0].getLanguage()); + } + + private boolean matchCountryCodes(TypedArray caseAttr, Locale[] locales) { + // TODO: adujst this for multilingual input + return matchString(caseAttr, R.styleable.Keyboard_Case_countryCode, + locales[0].getCountry()); + } + private static boolean matchInteger(final TypedArray a, final int index, final int value) { // If <case> does not have "index" attribute, that means this <case> is wild-card for // the attribute. diff --git a/java/src/com/android/inputmethod/keyboard/internal/LanguageOnSpacebarHelper.java b/java/src/com/android/inputmethod/keyboard/internal/LanguageOnSpacebarHelper.java index 72ad2bd97..21eaed950 100644 --- a/java/src/com/android/inputmethod/keyboard/internal/LanguageOnSpacebarHelper.java +++ b/java/src/com/android/inputmethod/keyboard/internal/LanguageOnSpacebarHelper.java @@ -23,6 +23,7 @@ import com.android.inputmethod.latin.utils.SubtypeLocaleUtils; import java.util.Collections; import java.util.List; +import java.util.Locale; /** * This class determines that the language name on the spacebar should be displayed in what format. @@ -31,6 +32,7 @@ public final class LanguageOnSpacebarHelper { public static final int FORMAT_TYPE_NONE = 0; public static final int FORMAT_TYPE_LANGUAGE_ONLY = 1; public static final int FORMAT_TYPE_FULL_LOCALE = 2; + public static final int FORMAT_TYPE_MULTIPLE = 3; private List<InputMethodSubtype> mEnabledSubtypes = Collections.emptyList(); private boolean mIsSystemLanguageSameAsInputLanguage; @@ -43,7 +45,11 @@ public final class LanguageOnSpacebarHelper { if (mEnabledSubtypes.size() < 2 && mIsSystemLanguageSameAsInputLanguage) { return FORMAT_TYPE_NONE; } - final String keyboardLanguage = SubtypeLocaleUtils.getSubtypeLocale(subtype).getLanguage(); + final Locale[] locales = subtype.getLocales(); + if (1 < locales.length) { + return FORMAT_TYPE_MULTIPLE; + } + final String keyboardLanguage = locales[0].getLanguage(); final String keyboardLayout = SubtypeLocaleUtils.getKeyboardLayoutSetName(subtype); int sameLanguageAndLayoutCount = 0; for (final InputMethodSubtype ims : mEnabledSubtypes) { diff --git a/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java b/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java index 1f0317288..4a218d550 100644 --- a/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java +++ b/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java @@ -416,33 +416,38 @@ public class DictionaryFacilitator { } @UsedForTesting - public void resetDictionariesForTesting(final Context context, final Locale locale, + public void resetDictionariesForTesting(final Context context, final Locale[] locales, final ArrayList<String> dictionaryTypes, final HashMap<String, File> dictionaryFiles, final Map<String, Map<String, String>> additionalDictAttributes) { Dictionary mainDictionary = null; final Map<String, ExpandableBinaryDictionary> subDicts = new HashMap<>(); - for (final String dictType : dictionaryTypes) { - if (dictType.equals(Dictionary.TYPE_MAIN)) { - mainDictionary = DictionaryFactory.createMainDictionaryFromManager(context, locale); - } else { - final File dictFile = dictionaryFiles.get(dictType); - final ExpandableBinaryDictionary dict = getSubDict( - dictType, context, locale, dictFile, "" /* dictNamePrefix */); - if (additionalDictAttributes.containsKey(dictType)) { - dict.clearAndFlushDictionaryWithAdditionalAttributes( - additionalDictAttributes.get(dictType)); - } - if (dict == null) { - throw new RuntimeException("Unknown dictionary type: " + dictType); + final DictionaryGroup[] dictionaryGroups = new DictionaryGroup[locales.length]; + for (int i = 0; i < locales.length; ++i) { + final Locale locale = locales[i]; + for (final String dictType : dictionaryTypes) { + if (dictType.equals(Dictionary.TYPE_MAIN)) { + mainDictionary = DictionaryFactory.createMainDictionaryFromManager(context, + locale); + } else { + final File dictFile = dictionaryFiles.get(dictType); + final ExpandableBinaryDictionary dict = getSubDict( + dictType, context, locale, dictFile, "" /* dictNamePrefix */); + if (additionalDictAttributes.containsKey(dictType)) { + dict.clearAndFlushDictionaryWithAdditionalAttributes( + additionalDictAttributes.get(dictType)); + } + if (dict == null) { + throw new RuntimeException("Unknown dictionary type: " + dictType); + } + dict.reloadDictionaryIfRequired(); + dict.waitAllTasksForTests(); + subDicts.put(dictType, dict); } - dict.reloadDictionaryIfRequired(); - dict.waitAllTasksForTests(); - subDicts.put(dictType, dict); } + dictionaryGroups[i] = new DictionaryGroup(locale, mainDictionary, subDicts); } - mDictionaryGroups = new DictionaryGroup[] { - new DictionaryGroup(locale, mainDictionary, subDicts) }; + mDictionaryGroups = dictionaryGroups; } public void closeDictionaries() { diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java index bb7a36b4f..64e65effe 100644 --- a/java/src/com/android/inputmethod/latin/LatinIME.java +++ b/java/src/com/android/inputmethod/latin/LatinIME.java @@ -102,7 +102,7 @@ import com.android.inputmethod.latin.utils.ViewLayoutUtils; import java.io.FileDescriptor; import java.io.PrintWriter; import java.util.ArrayList; -import java.util.Collections; +import java.util.Arrays; import java.util.List; import java.util.Locale; import java.util.concurrent.TimeUnit; @@ -594,18 +594,19 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen // Has to be package-visible for unit tests @UsedForTesting void loadSettings() { - final Locale locale = mSubtypeSwitcher.getCurrentSubtypeLocale(); + final Locale[] locales = mSubtypeSwitcher.getCurrentSubtypeLocales(); final EditorInfo editorInfo = getCurrentInputEditorInfo(); final InputAttributes inputAttributes = new InputAttributes( editorInfo, isFullscreenMode(), getPackageName()); - mSettings.loadSettings(this, locale, inputAttributes); + // TODO: pass the array instead + mSettings.loadSettings(this, locales[0], inputAttributes); final SettingsValues currentSettingsValues = mSettings.getCurrent(); AudioAndHapticFeedbackManager.getInstance().onSettingsChanged(currentSettingsValues); // This method is called on startup and language switch, before the new layout has // been displayed. Opening dictionaries never affects responsivity as dictionaries are // asynchronously loaded. if (!mHandler.hasPendingReopenDictionaries()) { - resetDictionaryFacilitatorForLocale(locale); + resetDictionaryFacilitatorForLocale(locales); } mDictionaryFacilitator.updateEnabledSubtypes(mRichImm.getMyEnabledInputMethodSubtypeList( true /* allowsImplicitlySelectedSubtypes */)); @@ -647,35 +648,34 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen } private void resetDictionaryFacilitatorIfNecessary() { - final Locale switcherSubtypeLocale = mSubtypeSwitcher.getCurrentSubtypeLocale(); - if (mDictionaryFacilitator.isForLocales(new Locale[] { switcherSubtypeLocale })) { + final Locale[] subtypeSwitcherLocales = mSubtypeSwitcher.getCurrentSubtypeLocales(); + if (mDictionaryFacilitator.isForLocales(subtypeSwitcherLocales)) { return; } - final String switcherLocaleStr = switcherSubtypeLocale.toString(); - final Locale subtypeLocale; - if (TextUtils.isEmpty(switcherLocaleStr)) { + final Locale[] subtypeLocales; + if (0 == subtypeSwitcherLocales.length) { // This happens in very rare corner cases - for example, immediately after a switch // to LatinIME has been requested, about a frame later another switch happens. In this // case, we are about to go down but we still don't know it, however the system tells - // us there is no current subtype so the locale is the empty string. Take the best - // possible guess instead -- it's bound to have no consequences, and we have no way - // of knowing anyway. + // us there is no current subtype. Log.e(TAG, "System is reporting no current subtype."); - subtypeLocale = getResources().getConfiguration().locale; + subtypeLocales = new Locale[] { getResources().getConfiguration().locale }; } else { - subtypeLocale = switcherSubtypeLocale; + subtypeLocales = subtypeSwitcherLocales; } - resetDictionaryFacilitatorForLocale(subtypeLocale); + resetDictionaryFacilitatorForLocale(subtypeLocales); } /** - * Reset the facilitator by loading dictionaries for the locale and the current settings values. + * Reset the facilitator by loading dictionaries for the locales and the current settings values * - * @param locale the locale + * @param locales the locales */ - // TODO: make sure the current settings always have the right locale, and read from them - private void resetDictionaryFacilitatorForLocale(final Locale locale) { + // TODO: make sure the current settings always have the right locales, and read from them + private void resetDictionaryFacilitatorForLocale(final Locale[] locales) { final SettingsValues settingsValues = mSettings.getCurrent(); + // TODO: pass the array instead + final Locale locale = locales[0]; mDictionaryFacilitator.resetDictionaries(this /* context */, locale, settingsValues.mUseContactsDict, settingsValues.mUsePersonalizedDicts, false /* forceReloadMainDictionary */, this); @@ -899,7 +899,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen // Update to a gesture consumer with the current editor and IME state. mGestureConsumer = GestureConsumer.newInstance(editorInfo, mInputLogic.getPrivateCommandPerformer(), - Collections.singletonList(mSubtypeSwitcher.getCurrentSubtypeLocale()), + Arrays.asList(mSubtypeSwitcher.getCurrentSubtypeLocales()), switcher.getKeyboard()); // Forward this event to the accessibility utilities, if enabled. @@ -1455,7 +1455,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen public void onStartBatchInput() { mInputLogic.onStartBatchInput(mSettings.getCurrent(), mKeyboardSwitcher, mHandler); mGestureConsumer.onGestureStarted( - Collections.singletonList(mSubtypeSwitcher.getCurrentSubtypeLocale()), + Arrays.asList(mSubtypeSwitcher.getCurrentSubtypeLocales()), mKeyboardSwitcher.getKeyboard()); } @@ -1579,7 +1579,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen // We should clear the contextual strip if there is no suggestion from dictionaries. || noSuggestionsFromDictionaries) { mSuggestionStripView.setSuggestions(suggestedWords, - SubtypeLocaleUtils.isRtlLanguage(mSubtypeSwitcher.getCurrentSubtype())); + mSubtypeSwitcher.getCurrentSubtype().isRtlSubtype()); } } diff --git a/java/src/com/android/inputmethod/latin/RichInputMethodSubtype.java b/java/src/com/android/inputmethod/latin/RichInputMethodSubtype.java index 0b08c48e5..8d055531c 100644 --- a/java/src/com/android/inputmethod/latin/RichInputMethodSubtype.java +++ b/java/src/com/android/inputmethod/latin/RichInputMethodSubtype.java @@ -114,10 +114,13 @@ public final class RichInputMethodSubtype { return "Multi-lingual subtype: " + mSubtype.toString() + ", " + Arrays.toString(mLocales); } - // TODO: remove this method! We can always have several locales. Multi-lingual input will only - // be done when this method is gone. - public String getLocale() { - return mSubtype.getLocale(); + public Locale[] getLocales() { + return mLocales; + } + + public boolean isRtlSubtype() { + // The subtype is considered RTL if the language of the main subtype is RTL. + return SubtypeLocaleUtils.isRtlLanguage(mLocales[0]); } // TODO: remove this method diff --git a/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java b/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java index 45d67ff88..c339e96fb 100644 --- a/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java +++ b/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java @@ -170,15 +170,21 @@ public final class SubtypeSwitcher { Log.w(TAG, "onSubtypeChanged: " + newSubtype.getNameForLogging()); } - final Locale newLocale = SubtypeLocaleUtils.getSubtypeLocale(newSubtype); - final Locale systemLocale = mResources.getConfiguration().locale; - final boolean sameLocale = systemLocale.equals(newLocale); - final boolean sameLanguage = systemLocale.getLanguage().equals(newLocale.getLanguage()); - final boolean implicitlyEnabled = mRichImm - .checkIfSubtypeBelongsToThisImeAndImplicitlyEnabled(newSubtype.getRawSubtype()); - mLanguageOnSpacebarHelper.updateIsSystemLanguageSameAsInputLanguage( - sameLocale || (sameLanguage && implicitlyEnabled)); - + final Locale[] newLocales = newSubtype.getLocales(); + if (newLocales.length > 1) { + // In multi-locales mode, the system language is never the same as the input language + // because there is no single input language. + mLanguageOnSpacebarHelper.updateIsSystemLanguageSameAsInputLanguage(false); + } else { + final Locale newLocale = newLocales[0]; + final Locale systemLocale = mResources.getConfiguration().locale; + final boolean sameLocale = systemLocale.equals(newLocale); + final boolean sameLanguage = systemLocale.getLanguage().equals(newLocale.getLanguage()); + final boolean implicitlyEnabled = mRichImm + .checkIfSubtypeBelongsToThisImeAndImplicitlyEnabled(newSubtype.getRawSubtype()); + mLanguageOnSpacebarHelper.updateIsSystemLanguageSameAsInputLanguage( + sameLocale || (sameLanguage && implicitlyEnabled)); + } updateShortcutIME(); } @@ -284,11 +290,11 @@ public final class SubtypeSwitcher { sForcedSubtypeForTesting = new RichInputMethodSubtype(subtype); } - public Locale getCurrentSubtypeLocale() { + public Locale[] getCurrentSubtypeLocales() { if (null != sForcedSubtypeForTesting) { - return LocaleUtils.constructLocaleFromString(sForcedSubtypeForTesting.getLocale()); + return sForcedSubtypeForTesting.getLocales(); } - return SubtypeLocaleUtils.getSubtypeLocale(getCurrentSubtype()); + return getCurrentSubtype().getLocales(); } public RichInputMethodSubtype getCurrentSubtype() { diff --git a/java/src/com/android/inputmethod/latin/SuggestedWords.java b/java/src/com/android/inputmethod/latin/SuggestedWords.java index e6fd43a07..466576465 100644 --- a/java/src/com/android/inputmethod/latin/SuggestedWords.java +++ b/java/src/com/android/inputmethod/latin/SuggestedWords.java @@ -113,6 +113,19 @@ public class SuggestedWords { } /** + * Get suggested word to show as suggestions to UI. + * + * @param shouldShowLxxSuggestionUi true if showing suggestion UI introduced in LXX and later. + * @return the count of suggested word to show as suggestions to UI. + */ + public int getWordCountToShow(final boolean shouldShowLxxSuggestionUi) { + if (isPrediction() || !shouldShowLxxSuggestionUi) { + return size(); + } + return size() - /* typed word */ 1; + } + + /** * Get suggested word at <code>index</code>. * @param index The index of the suggested word. * @return The suggested word. diff --git a/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java b/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java index f67a9a6ef..07bfd0dee 100644 --- a/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java +++ b/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java @@ -53,7 +53,6 @@ import com.android.inputmethod.latin.SuggestedWords; import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo; import com.android.inputmethod.latin.WordComposer; import com.android.inputmethod.latin.define.DebugFlags; -import com.android.inputmethod.latin.define.ProductionFlags; import com.android.inputmethod.latin.settings.SettingsValues; import com.android.inputmethod.latin.settings.SettingsValuesForSuggestion; import com.android.inputmethod.latin.settings.SpacingAndPunctuations; @@ -169,7 +168,7 @@ public final class InputLogic { mInputLogicHandler.reset(); } - if (settingsValues.mShouldShowUiToAcceptTypedWord) { + if (settingsValues.mShouldShowLxxSuggestionUi) { mConnection.requestCursorUpdates(true /* enableMonitor */, true /* requestImmediateCallback */); } @@ -2352,7 +2351,7 @@ public final class InputLogic { // We cannot help in this case because we are heavily relying on this new API. return false; } - if (!settingsValues.mShouldShowUiToAcceptTypedWord) { + if (!settingsValues.mShouldShowLxxSuggestionUi) { return false; } if (TextUtils.isEmpty(lastComposedWord.mTypedWord)) { diff --git a/java/src/com/android/inputmethod/latin/settings/DebugSettings.java b/java/src/com/android/inputmethod/latin/settings/DebugSettings.java index 48f4c758c..091ca43c6 100644 --- a/java/src/com/android/inputmethod/latin/settings/DebugSettings.java +++ b/java/src/com/android/inputmethod/latin/settings/DebugSettings.java @@ -21,8 +21,8 @@ public final class DebugSettings { public static final String PREF_FORCE_NON_DISTINCT_MULTITOUCH = "force_non_distinct_multitouch"; public static final String PREF_FORCE_PHYSICAL_KEYBOARD_SPECIAL_KEY = "force_physical_keyboard_special_key"; - public static final String PREF_SHOW_UI_TO_ACCEPT_TYPED_WORD = - "pref_show_ui_to_accept_typed_word"; + public static final String PREF_SHOULD_SHOW_LXX_SUGGESTION_UI = + "pref_should_show_lxx_suggestion_ui"; public static final String PREF_HAS_CUSTOM_KEY_PREVIEW_ANIMATION_PARAMS = "pref_has_custom_key_preview_animation_params"; public static final String PREF_KEY_PREVIEW_SHOW_UP_START_X_SCALE = diff --git a/java/src/com/android/inputmethod/latin/settings/DebugSettingsFragment.java b/java/src/com/android/inputmethod/latin/settings/DebugSettingsFragment.java index 5640e2039..e9f8d45aa 100644 --- a/java/src/com/android/inputmethod/latin/settings/DebugSettingsFragment.java +++ b/java/src/com/android/inputmethod/latin/settings/DebugSettingsFragment.java @@ -56,8 +56,8 @@ public final class DebugSettingsFragment extends SubScreenFragment super.onCreate(icicle); addPreferencesFromResource(R.xml.prefs_screen_debug); - if (!Settings.HAS_UI_TO_ACCEPT_TYPED_WORD) { - removePreference(DebugSettings.PREF_SHOW_UI_TO_ACCEPT_TYPED_WORD); + if (!Settings.SHOULD_SHOW_LXX_SUGGESTION_UI) { + removePreference(DebugSettings.PREF_SHOULD_SHOW_LXX_SUGGESTION_UI); } mReadExternalDictionaryPref = findPreference(PREF_READ_EXTERNAL_DICTIONARY); diff --git a/java/src/com/android/inputmethod/latin/settings/Settings.java b/java/src/com/android/inputmethod/latin/settings/Settings.java index 83adb1c55..84596b4ad 100644 --- a/java/src/com/android/inputmethod/latin/settings/Settings.java +++ b/java/src/com/android/inputmethod/latin/settings/Settings.java @@ -77,7 +77,7 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang BuildCompatUtils.EFFECTIVE_SDK_INT <= Build.VERSION_CODES.KITKAT; public static final boolean ENABLE_SHOW_LANGUAGE_SWITCH_KEY_SETTINGS = BuildCompatUtils.EFFECTIVE_SDK_INT <= Build.VERSION_CODES.KITKAT; - public static final boolean HAS_UI_TO_ACCEPT_TYPED_WORD = + public static final boolean SHOULD_SHOW_LXX_SUGGESTION_UI = BuildCompatUtils.EFFECTIVE_SDK_INT >= BuildCompatUtils.VERSION_CODES_LXX; public static final String PREF_SHOW_LANGUAGE_SWITCH_KEY = "pref_show_language_switch_key"; diff --git a/java/src/com/android/inputmethod/latin/settings/SettingsValues.java b/java/src/com/android/inputmethod/latin/settings/SettingsValues.java index 99f761ca6..ce8a0ab9c 100644 --- a/java/src/com/android/inputmethod/latin/settings/SettingsValues.java +++ b/java/src/com/android/inputmethod/latin/settings/SettingsValues.java @@ -80,7 +80,7 @@ public class SettingsValues { public final boolean mPhraseGestureEnabled; public final int mKeyLongpressTimeout; public final boolean mEnableMetricsLogging; - public final boolean mShouldShowUiToAcceptTypedWord; + public final boolean mShouldShowLxxSuggestionUi; // Use split layout for keyboard. public final boolean mIsSplitKeyboardEnabled; public final int mScreenMetrics; @@ -163,8 +163,8 @@ public class SettingsValues { mIsSplitKeyboardEnabled = prefs.getBoolean(Settings.PREF_ENABLE_SPLIT_KEYBOARD, false); mScreenMetrics = res.getInteger(R.integer.config_screen_metrics); - mShouldShowUiToAcceptTypedWord = Settings.HAS_UI_TO_ACCEPT_TYPED_WORD - && prefs.getBoolean(DebugSettings.PREF_SHOW_UI_TO_ACCEPT_TYPED_WORD, true); + mShouldShowLxxSuggestionUi = Settings.SHOULD_SHOW_LXX_SUGGESTION_UI + && prefs.getBoolean(DebugSettings.PREF_SHOULD_SHOW_LXX_SUGGESTION_UI, true); // Compute other readable settings mKeyLongpressTimeout = Settings.readKeyLongpressTimeout(prefs, res); mKeypressVibrationDuration = Settings.readKeypressVibrationDuration(prefs, res); diff --git a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripLayoutHelper.java b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripLayoutHelper.java index a651774c6..d55939971 100644 --- a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripLayoutHelper.java +++ b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripLayoutHelper.java @@ -240,9 +240,9 @@ final class SuggestionStripLayoutHelper { final SettingsValues settingsValues = Settings.getInstance().getCurrent(); final boolean shouldOmitTypedWord = shouldOmitTypedWord(suggestedWords.mInputStyle, settingsValues.mGestureFloatingPreviewTextEnabled, - settingsValues.mShouldShowUiToAcceptTypedWord); + settingsValues.mShouldShowLxxSuggestionUi); return getPositionInSuggestionStrip(indexInSuggestedWords, suggestedWords.mWillAutoCorrect, - settingsValues.mShouldShowUiToAcceptTypedWord && shouldOmitTypedWord, + settingsValues.mShouldShowLxxSuggestionUi && shouldOmitTypedWord, mCenterPositionInStrip, mTypedWordPositionWhenAutocorrect); } @@ -367,21 +367,19 @@ final class SuggestionStripLayoutHelper { (PunctuationSuggestions)suggestedWords, stripView); } - final boolean shouldShowUiToAcceptTypedWord = Settings.getInstance().getCurrent() - .mShouldShowUiToAcceptTypedWord; - final int suggestionsCount = suggestedWords.size() - - (shouldShowUiToAcceptTypedWord ? /* typed word */ 1 : 0); + final int wordCountToShow = suggestedWords.getWordCountToShow( + Settings.getInstance().getCurrent().mShouldShowLxxSuggestionUi); final int startIndexOfMoreSuggestions = setupWordViewsAndReturnStartIndexOfMoreSuggestions( suggestedWords, mSuggestionsCountInStrip); final TextView centerWordView = mWordViews.get(mCenterPositionInStrip); final int stripWidth = stripView.getWidth(); final int centerWidth = getSuggestionWidth(mCenterPositionInStrip, stripWidth); - if (suggestionsCount == 1 || getTextScaleX(centerWordView.getText(), centerWidth, + if (wordCountToShow == 1 || getTextScaleX(centerWordView.getText(), centerWidth, centerWordView.getPaint()) < MIN_TEXT_XSCALE) { // Layout only the most relevant suggested word at the center of the suggestion strip // by consolidating all slots in the strip. final int countInStrip = 1; - mMoreSuggestionsAvailable = (suggestionsCount > countInStrip); + mMoreSuggestionsAvailable = (wordCountToShow > countInStrip); layoutWord(mCenterPositionInStrip, stripWidth - mPadding); stripView.addView(centerWordView); setLayoutWeight(centerWordView, 1.0f, ViewGroup.LayoutParams.MATCH_PARENT); @@ -393,7 +391,7 @@ final class SuggestionStripLayoutHelper { } final int countInStrip = mSuggestionsCountInStrip; - mMoreSuggestionsAvailable = (suggestionsCount > countInStrip); + mMoreSuggestionsAvailable = (wordCountToShow > countInStrip); int x = 0; for (int positionInStrip = 0; positionInStrip < countInStrip; positionInStrip++) { if (positionInStrip != 0) { @@ -557,7 +555,7 @@ final class SuggestionStripLayoutHelper { public void layoutAddToDictionaryHint(final String word, final ViewGroup addToDictionaryStrip) { final boolean shouldShowUiToAcceptTypedWord = Settings.getInstance().getCurrent() - .mShouldShowUiToAcceptTypedWord; + .mShouldShowLxxSuggestionUi; final int stripWidth = addToDictionaryStrip.getWidth(); final int width = shouldShowUiToAcceptTypedWord ? stripWidth : stripWidth - mDividerWidth - mPadding * 2; diff --git a/java/src/com/android/inputmethod/latin/utils/SubtypeLocaleUtils.java b/java/src/com/android/inputmethod/latin/utils/SubtypeLocaleUtils.java index 5a7f7662c..61661cd52 100644 --- a/java/src/com/android/inputmethod/latin/utils/SubtypeLocaleUtils.java +++ b/java/src/com/android/inputmethod/latin/utils/SubtypeLocaleUtils.java @@ -293,13 +293,6 @@ public final class SubtypeLocaleUtils { return LocaleUtils.constructLocaleFromString(localeString); } - // TODO: remove this. When RichInputMethodSubtype#getLocale is removed we can do away with this - // method at the same time. - public static Locale getSubtypeLocale(final RichInputMethodSubtype subtype) { - final String localeString = subtype.getLocale(); - return LocaleUtils.constructLocaleFromString(localeString); - } - public static String getKeyboardLayoutSetDisplayName(final InputMethodSubtype subtype) { final String layoutName = getKeyboardLayoutSetName(subtype); return getKeyboardLayoutSetDisplayName(layoutName); @@ -348,10 +341,6 @@ public final class SubtypeLocaleUtils { return Arrays.binarySearch(SORTED_RTL_LANGUAGES, language) >= 0; } - public static boolean isRtlLanguage(final RichInputMethodSubtype subtype) { - return isRtlLanguage(getSubtypeLocale(subtype)); - } - public static String getCombiningRulesExtraValue(final InputMethodSubtype subtype) { return subtype.getExtraValueOf(Constants.Subtype.ExtraValue.COMBINING_RULES); } |