aboutsummaryrefslogtreecommitdiffstats
path: root/java/src/com/android/inputmethod
diff options
context:
space:
mode:
Diffstat (limited to 'java/src/com/android/inputmethod')
-rw-r--r--java/src/com/android/inputmethod/accessibility/AccessibilityUtils.java10
-rw-r--r--java/src/com/android/inputmethod/keyboard/Key.java27
-rw-r--r--java/src/com/android/inputmethod/keyboard/MainKeyboardView.java4
-rw-r--r--java/src/com/android/inputmethod/keyboard/internal/MoreKeySpec.java14
-rw-r--r--java/src/com/android/inputmethod/latin/DictionaryFacilitator.java6
-rw-r--r--java/src/com/android/inputmethod/latin/LatinIME.java41
-rw-r--r--java/src/com/android/inputmethod/latin/PunctuationSuggestions.java4
-rw-r--r--java/src/com/android/inputmethod/latin/RichInputMethodManager.java9
-rw-r--r--java/src/com/android/inputmethod/latin/Suggest.java49
-rw-r--r--java/src/com/android/inputmethod/latin/SuggestedWords.java95
-rw-r--r--java/src/com/android/inputmethod/latin/SystemBroadcastReceiver.java2
-rw-r--r--java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java83
-rw-r--r--java/src/com/android/inputmethod/latin/utils/SubtypeLocaleUtils.java3
13 files changed, 208 insertions, 139 deletions
diff --git a/java/src/com/android/inputmethod/accessibility/AccessibilityUtils.java b/java/src/com/android/inputmethod/accessibility/AccessibilityUtils.java
index 2762a9f25..b0072eebe 100644
--- a/java/src/com/android/inputmethod/accessibility/AccessibilityUtils.java
+++ b/java/src/com/android/inputmethod/accessibility/AccessibilityUtils.java
@@ -152,12 +152,16 @@ public final class AccessibilityUtils {
* will occur when a key is typed.
*
* @param suggestedWords the list of suggested auto-correction words
- * @param typedWord the currently typed word
*/
- public void setAutoCorrection(final SuggestedWords suggestedWords, final String typedWord) {
+ public void setAutoCorrection(final SuggestedWords suggestedWords) {
if (suggestedWords.mWillAutoCorrect) {
mAutoCorrectionWord = suggestedWords.getWord(SuggestedWords.INDEX_OF_AUTO_CORRECTION);
- mTypedWord = typedWord;
+ final SuggestedWords.SuggestedWordInfo typedWordInfo = suggestedWords.mTypedWordInfo;
+ if (null == typedWordInfo) {
+ mTypedWord = null;
+ } else {
+ mTypedWord = typedWordInfo.mWord;
+ }
} else {
mAutoCorrectionWord = null;
mTypedWord = null;
diff --git a/java/src/com/android/inputmethod/keyboard/Key.java b/java/src/com/android/inputmethod/keyboard/Key.java
index 6b2094b9e..06e552e3d 100644
--- a/java/src/com/android/inputmethod/keyboard/Key.java
+++ b/java/src/com/android/inputmethod/keyboard/Key.java
@@ -341,17 +341,24 @@ public class Key implements Comparable<Key> {
// code point nor as a surrogate pair.
mLabel = new StringBuilder().appendCodePoint(code).toString();
} else {
- mLabel = StringUtils.toUpperCaseOfStringForLocale(
- KeySpecParser.getLabel(keySpec), needsToUpcase, localeForUpcasing);
+ final String label = KeySpecParser.getLabel(keySpec);
+ mLabel = needsToUpcase
+ ? StringUtils.toTitleCaseOfKeyLabel(label, localeForUpcasing)
+ : label;
}
if ((mLabelFlags & LABEL_FLAGS_DISABLE_HINT_LABEL) != 0) {
mHintLabel = null;
} else {
- mHintLabel = StringUtils.toUpperCaseOfStringForLocale(style.getString(keyAttr,
- R.styleable.Keyboard_Key_keyHintLabel), needsToUpcase, localeForUpcasing);
+ final String hintLabel = style.getString(
+ keyAttr, R.styleable.Keyboard_Key_keyHintLabel);
+ mHintLabel = needsToUpcase
+ ? StringUtils.toTitleCaseOfKeyLabel(hintLabel, localeForUpcasing)
+ : hintLabel;
+ }
+ String outputText = KeySpecParser.getOutputText(keySpec);
+ if (needsToUpcase) {
+ outputText = StringUtils.toTitleCaseOfKeyLabel(outputText, localeForUpcasing);
}
- String outputText = StringUtils.toUpperCaseOfStringForLocale(
- 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 +384,14 @@ public class Key implements Comparable<Key> {
mCode = CODE_OUTPUT_TEXT;
}
} else {
- mCode = StringUtils.toUpperCaseOfCodeForLocale(code, needsToUpcase, localeForUpcasing);
+ mCode = needsToUpcase ? StringUtils.toTitleCaseOfKeyCode(code, localeForUpcasing)
+ : code;
}
final int altCodeInAttr = KeySpecParser.parseCode(
style.getString(keyAttr, R.styleable.Keyboard_Key_altCode), CODE_UNSPECIFIED);
- final int altCode = StringUtils.toUpperCaseOfCodeForLocale(
- altCodeInAttr, needsToUpcase, localeForUpcasing);
+ final int altCode = needsToUpcase
+ ? StringUtils.toTitleCaseOfKeyCode(altCodeInAttr, localeForUpcasing)
+ : altCodeInAttr;
mOptionalAttributes = OptionalAttributes.newInstance(outputText, altCode,
disabledIconId, visualInsetsLeft, visualInsetsRight);
mKeyVisualAttributes = KeyVisualAttributes.newInstance(keyAttr);
diff --git a/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java b/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java
index cba7ff2a2..06b87bd9a 100644
--- a/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java
@@ -57,7 +57,6 @@ import com.android.inputmethod.latin.RichInputMethodSubtype;
import com.android.inputmethod.latin.SuggestedWords;
import com.android.inputmethod.latin.common.Constants;
import com.android.inputmethod.latin.common.CoordinateUtils;
-import com.android.inputmethod.latin.common.StringUtils;
import com.android.inputmethod.latin.settings.DebugSettings;
import com.android.inputmethod.latin.utils.TypefaceUtils;
@@ -874,8 +873,7 @@ public final class MainKeyboardView extends KeyboardView implements DrawingProxy
final Locale[] locales = subtype.getLocales();
final String[] languages = new String[locales.length];
for (int i = 0; i < locales.length; ++i) {
- languages[i] = StringUtils.toUpperCaseOfStringForLocale(
- locales[i].getLanguage(), true /* needsToUpperCase */, Locale.ROOT);
+ languages[i] = locales[i].getLanguage().toUpperCase(Locale.ROOT);
}
return TextUtils.join(" / ", languages);
}
diff --git a/java/src/com/android/inputmethod/keyboard/internal/MoreKeySpec.java b/java/src/com/android/inputmethod/keyboard/internal/MoreKeySpec.java
index b1a3887d8..87c96cc0d 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/MoreKeySpec.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/MoreKeySpec.java
@@ -55,10 +55,11 @@ public final class MoreKeySpec {
if (TextUtils.isEmpty(moreKeySpec)) {
throw new KeySpecParser.KeySpecParserError("Empty more key spec");
}
- mLabel = StringUtils.toUpperCaseOfStringForLocale(
- KeySpecParser.getLabel(moreKeySpec), needsToUpperCase, locale);
- final int code = StringUtils.toUpperCaseOfCodeForLocale(
- KeySpecParser.getCode(moreKeySpec), needsToUpperCase, locale);
+ final String label = KeySpecParser.getLabel(moreKeySpec);
+ mLabel = needsToUpperCase ? StringUtils.toTitleCaseOfKeyLabel(label, locale) : label;
+ final int codeInSpec = KeySpecParser.getCode(moreKeySpec);
+ final int code = needsToUpperCase ? StringUtils.toTitleCaseOfKeyCode(codeInSpec, locale)
+ : codeInSpec;
if (code == Constants.CODE_UNSPECIFIED) {
// Some letter, for example German Eszett (U+00DF: "ß"), has multiple characters
// upper case representation ("SS").
@@ -66,8 +67,9 @@ public final class MoreKeySpec {
mOutputText = mLabel;
} else {
mCode = code;
- mOutputText = StringUtils.toUpperCaseOfStringForLocale(
- KeySpecParser.getOutputText(moreKeySpec), needsToUpperCase, locale);
+ final String outputText = KeySpecParser.getOutputText(moreKeySpec);
+ mOutputText = needsToUpperCase
+ ? StringUtils.toTitleCaseOfKeyLabel(outputText, locale) : outputText;
}
mIconId = KeySpecParser.getIconId(moreKeySpec);
}
diff --git a/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java b/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java
index d23639a0d..b24fdea55 100644
--- a/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java
+++ b/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java
@@ -266,6 +266,12 @@ public class DictionaryFacilitator {
}
final DictionaryGroup newMostProbableDictionaryGroup =
findDictionaryGroupWithLocale(mDictionaryGroups, locale);
+ if (null == newMostProbableDictionaryGroup) {
+ // It seems this may happen as a race condition; pressing the globe key and space
+ // in quick succession could commit a word out of a dictionary that's not in the
+ // facilitator any more. In this case, just not changing things is fine.
+ return;
+ }
mMostProbableDictionaryGroup.mWeightForTypingInLocale =
DictionaryGroup.WEIGHT_FOR_TYPING_IN_NOT_MOST_PROBABLE_LANGUAGE;
mMostProbableDictionaryGroup.mWeightForGesturingInLocale =
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index 719656b07..7b7b6d35e 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -201,8 +201,9 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
private static final int MSG_RESET_CACHES = 7;
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;
// Update this when adding new messages
- private static final int MSG_LAST = MSG_DEALLOCATE_MEMORY;
+ private static final int MSG_LAST = MSG_RESUME_SUGGESTIONS_FOR_START_INPUT;
private static final int ARG1_NOT_GESTURE_INPUT = 0;
private static final int ARG1_DISMISS_GESTURE_FLOATING_PREVIEW_TEXT = 1;
@@ -257,7 +258,12 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
break;
case MSG_RESUME_SUGGESTIONS:
latinIme.mInputLogic.restartSuggestionsOnWordTouchedByCursor(
- latinIme.mSettings.getCurrent(),
+ latinIme.mSettings.getCurrent(), false /* forStartInput */,
+ latinIme.mKeyboardSwitcher.getCurrentKeyboardScriptId());
+ break;
+ case MSG_RESUME_SUGGESTIONS_FOR_START_INPUT:
+ latinIme.mInputLogic.restartSuggestionsOnWordTouchedByCursor(
+ latinIme.mSettings.getCurrent(), true /* forStartInput */,
latinIme.mKeyboardSwitcher.getCurrentKeyboardScriptId());
break;
case MSG_REOPEN_DICTIONARIES:
@@ -303,7 +309,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
sendMessage(obtainMessage(MSG_REOPEN_DICTIONARIES));
}
- public void postResumeSuggestions(final boolean shouldDelay) {
+ private void postResumeSuggestionsInternal(final boolean shouldDelay,
+ final boolean forStartInput) {
final LatinIME latinIme = getOwnerInstance();
if (latinIme == null) {
return;
@@ -312,14 +319,25 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
return;
}
removeMessages(MSG_RESUME_SUGGESTIONS);
+ removeMessages(MSG_RESUME_SUGGESTIONS_FOR_START_INPUT);
+ final int message = forStartInput ? MSG_RESUME_SUGGESTIONS_FOR_START_INPUT
+ : MSG_RESUME_SUGGESTIONS;
if (shouldDelay) {
- sendMessageDelayed(obtainMessage(MSG_RESUME_SUGGESTIONS),
+ sendMessageDelayed(obtainMessage(message),
mDelayInMillisecondsToUpdateSuggestions);
} else {
- sendMessage(obtainMessage(MSG_RESUME_SUGGESTIONS));
+ sendMessage(obtainMessage(message));
}
}
+ public void postResumeSuggestions(final boolean shouldDelay) {
+ postResumeSuggestionsInternal(shouldDelay, false /* forStartInput */);
+ }
+
+ public void postResumeSuggestionsForStartInput(final boolean shouldDelay) {
+ postResumeSuggestionsInternal(shouldDelay, true /* forStartInput */);
+ }
+
public void postResetCaches(final boolean tryResumeSuggestions, final int remainingTries) {
removeMessages(MSG_RESET_CACHES);
sendMessage(obtainMessage(MSG_RESET_CACHES, tryResumeSuggestions ? 1 : 0,
@@ -969,7 +987,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
// initialSelStart and initialSelEnd sometimes are lying. Make a best effort to
// work around this bug.
mInputLogic.mConnection.tryFixLyingCursorPosition();
- mHandler.postResumeSuggestions(true /* shouldDelay */);
+ mHandler.postResumeSuggestionsForStartInput(true /* shouldDelay */);
needToCallLoadKeyboardLater = false;
}
} else {
@@ -1171,9 +1189,13 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
SuggestedWords.getFromApplicationSpecifiedCompletions(
applicationSpecifiedCompletions);
final SuggestedWords suggestedWords = new SuggestedWords(applicationSuggestedWords,
- null /* rawSuggestions */, false /* typedWordValid */, false /* willAutoCorrect */,
+ null /* rawSuggestions */,
+ null /* typedWord */,
+ false /* typedWordValid */,
+ false /* willAutoCorrect */,
false /* isObsoleteSuggestions */,
- SuggestedWords.INPUT_STYLE_APPLICATION_SPECIFIED /* inputStyle */);
+ SuggestedWords.INPUT_STYLE_APPLICATION_SPECIFIED /* inputStyle */,
+ SuggestedWords.NOT_A_SEQUENCE_NUMBER);
// When in fullscreen mode, show completions generated by the application forcibly
setSuggestedWords(suggestedWords);
}
@@ -1615,8 +1637,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
}
// Cache the auto-correction in accessibility code so we can speak it if the user
// touches a key that will insert it.
- AccessibilityUtils.getInstance().setAutoCorrection(suggestedWords,
- suggestedWords.mTypedWord);
+ AccessibilityUtils.getInstance().setAutoCorrection(suggestedWords);
}
// Called from {@link SuggestionStripView} through the {@link SuggestionStripView#Listener}
diff --git a/java/src/com/android/inputmethod/latin/PunctuationSuggestions.java b/java/src/com/android/inputmethod/latin/PunctuationSuggestions.java
index a65304cd0..555bbc7d4 100644
--- a/java/src/com/android/inputmethod/latin/PunctuationSuggestions.java
+++ b/java/src/com/android/inputmethod/latin/PunctuationSuggestions.java
@@ -33,10 +33,12 @@ public final class PunctuationSuggestions extends SuggestedWords {
private PunctuationSuggestions(final ArrayList<SuggestedWordInfo> punctuationsList) {
super(punctuationsList,
null /* rawSuggestions */,
+ null /* typedWord */,
false /* typedWordValid */,
false /* hasAutoCorrectionCandidate */,
false /* isObsoleteSuggestions */,
- INPUT_STYLE_NONE /* inputStyle */);
+ INPUT_STYLE_NONE /* inputStyle */,
+ SuggestedWords.NOT_A_SEQUENCE_NUMBER);
}
/**
diff --git a/java/src/com/android/inputmethod/latin/RichInputMethodManager.java b/java/src/com/android/inputmethod/latin/RichInputMethodManager.java
index a1ac55a20..686c3a4b2 100644
--- a/java/src/com/android/inputmethod/latin/RichInputMethodManager.java
+++ b/java/src/com/android/inputmethod/latin/RichInputMethodManager.java
@@ -110,7 +110,7 @@ public class RichInputMethodManager {
// Initialize additional subtypes.
SubtypeLocaleUtils.init(context);
- final InputMethodSubtype[] additionalSubtypes = getAdditionalSubtypes(context);
+ final InputMethodSubtype[] additionalSubtypes = getAdditionalSubtypes();
setAdditionalInputMethodSubtypes(additionalSubtypes);
final ConnectivityManager connectivityManager =
@@ -119,11 +119,10 @@ public class RichInputMethodManager {
mIsNetworkConnected = (info != null && info.isConnected());
}
- public InputMethodSubtype[] getAdditionalSubtypes(final Context context) {
- SubtypeLocaleUtils.init(context);
- final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
+ public InputMethodSubtype[] getAdditionalSubtypes() {
+ final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(mContext);
final String prefAdditionalSubtypes = Settings.readPrefAdditionalSubtypes(
- prefs, context.getResources());
+ prefs, mContext.getResources());
return AdditionalSubtypeUtils.createAdditionalSubtypesArray(prefAdditionalSubtypes);
}
diff --git a/java/src/com/android/inputmethod/latin/Suggest.java b/java/src/com/android/inputmethod/latin/Suggest.java
index ee8d3f8cb..2d0ec42a6 100644
--- a/java/src/com/android/inputmethod/latin/Suggest.java
+++ b/java/src/com/android/inputmethod/latin/Suggest.java
@@ -32,6 +32,8 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.Locale;
+import javax.annotation.Nullable;
+
/**
* This class loads a dictionary and provides a list of suggestions for a given sequence of
* characters. This includes corrections and completions.
@@ -133,23 +135,26 @@ public final class Suggest {
final SettingsValuesForSuggestion settingsValuesForSuggestion,
final int inputStyleIfNotPrediction, final boolean isCorrectionEnabled,
final int sequenceNumber, final OnGetSuggestedWordsCallback callback) {
- final String typedWord = wordComposer.getTypedWord();
- final int trailingSingleQuotesCount = StringUtils.getTrailingSingleQuotesCount(typedWord);
+ final String typedWordString = wordComposer.getTypedWord();
+ final int trailingSingleQuotesCount =
+ StringUtils.getTrailingSingleQuotesCount(typedWordString);
final String consideredWord = trailingSingleQuotesCount > 0
- ? typedWord.substring(0, typedWord.length() - trailingSingleQuotesCount)
- : typedWord;
+ ? typedWordString.substring(0, typedWordString.length() - trailingSingleQuotesCount)
+ : typedWordString;
final SuggestionResults suggestionResults = mDictionaryFacilitator.getSuggestionResults(
wordComposer, ngramContext, proximityInfo.getNativeProximityInfo(),
settingsValuesForSuggestion, SESSION_ID_TYPING);
+ final Locale mostProbableLocale = mDictionaryFacilitator.getMostProbableLocale();
final ArrayList<SuggestedWordInfo> suggestionsContainer =
getTransformedSuggestedWordInfoList(wordComposer, suggestionResults,
trailingSingleQuotesCount,
// For transforming suggestions that don't come for any dictionary, we
// use the currently most probable locale as it's our best bet.
- mDictionaryFacilitator.getMostProbableLocale());
- final boolean didRemoveTypedWord =
- SuggestedWordInfo.removeDups(wordComposer.getTypedWord(), suggestionsContainer);
+ mostProbableLocale);
+ @Nullable final Dictionary sourceDictionaryOfRemovedWord =
+ SuggestedWordInfo.removeDupsAndReturnSourceOfTypedWord(wordComposer.getTypedWord(),
+ mostProbableLocale /* preferredLocale */, suggestionsContainer);
final String whitelistedWord = getWhitelistedWordOrNull(suggestionsContainer);
final boolean resultsArePredictions = !wordComposer.isComposingWord();
@@ -157,7 +162,7 @@ public final class Suggest {
// We allow auto-correction if we have a whitelisted word, or if the word had more than
// one char and was not suggested.
final boolean allowsToBeAutoCorrected = (null != whitelistedWord)
- || (consideredWord.length() > 1 && !didRemoveTypedWord);
+ || (consideredWord.length() > 1 && (null == sourceDictionaryOfRemovedWord));
final boolean hasAutoCorrection;
// If correction is not enabled, we never auto-correct. This is for example for when
@@ -206,17 +211,20 @@ public final class Suggest {
}
}
- if (!TextUtils.isEmpty(typedWord)) {
- suggestionsContainer.add(0, new SuggestedWordInfo(typedWord,
- SuggestedWordInfo.MAX_SCORE, SuggestedWordInfo.KIND_TYPED,
- Dictionary.DICTIONARY_USER_TYPED,
- SuggestedWordInfo.NOT_AN_INDEX /* indexOfTouchPointOfSecondWord */,
- SuggestedWordInfo.NOT_A_CONFIDENCE /* autoCommitFirstWordConfidence */));
+ final SuggestedWordInfo typedWordInfo = new SuggestedWordInfo(typedWordString,
+ SuggestedWordInfo.MAX_SCORE, SuggestedWordInfo.KIND_TYPED,
+ null == sourceDictionaryOfRemovedWord ? Dictionary.DICTIONARY_USER_TYPED
+ : sourceDictionaryOfRemovedWord,
+ SuggestedWordInfo.NOT_AN_INDEX /* indexOfTouchPointOfSecondWord */,
+ SuggestedWordInfo.NOT_A_CONFIDENCE /* autoCommitFirstWordConfidence */);
+ if (!TextUtils.isEmpty(typedWordString)) {
+ suggestionsContainer.add(0, typedWordInfo);
}
final ArrayList<SuggestedWordInfo> suggestionsList;
if (DBG && !suggestionsContainer.isEmpty()) {
- suggestionsList = getSuggestionsInfoListWithDebugInfo(typedWord, suggestionsContainer);
+ suggestionsList = getSuggestionsInfoListWithDebugInfo(typedWordString,
+ suggestionsContainer);
} else {
suggestionsList = suggestionsContainer;
}
@@ -230,7 +238,7 @@ public final class Suggest {
inputStyle = inputStyleIfNotPrediction;
}
callback.onGetSuggestedWords(new SuggestedWords(suggestionsList,
- suggestionResults.mRawSuggestions, typedWord,
+ suggestionResults.mRawSuggestions, typedWordInfo,
// TODO: this first argument is lying. If this is a whitelisted word which is an
// actual word, it says typedWordValid = false, which looks wrong. We should either
// rename the attribute or change the value.
@@ -272,7 +280,8 @@ public final class Suggest {
final SuggestedWordInfo rejected = suggestionsContainer.remove(0);
suggestionsContainer.add(1, rejected);
}
- SuggestedWordInfo.removeDups(null /* typedWord */, suggestionsContainer);
+ SuggestedWordInfo.removeDupsAndReturnSourceOfTypedWord(null /* typedWord */,
+ null /* preferredLocale */, suggestionsContainer);
// For some reason some suggestions with MIN_VALUE are making their way here.
// TODO: Find a more robust way to detect distracters.
@@ -286,12 +295,12 @@ public final class Suggest {
// (typedWordValid=true), not as an "auto correct word" (willAutoCorrect=false).
// Note that because this method is never used to get predictions, there is no need to
// modify inputType such in getSuggestedWordsForNonBatchInput.
- final String pseudoTypedWord = suggestionsContainer.isEmpty() ? null
- : suggestionsContainer.get(0).mWord;
+ final SuggestedWordInfo pseudoTypedWordInfo = suggestionsContainer.isEmpty() ? null
+ : suggestionsContainer.get(0);
callback.onGetSuggestedWords(new SuggestedWords(suggestionsContainer,
suggestionResults.mRawSuggestions,
- pseudoTypedWord,
+ pseudoTypedWordInfo,
true /* typedWordValid */,
false /* willAutoCorrect */,
false /* isObsoleteSuggestions */,
diff --git a/java/src/com/android/inputmethod/latin/SuggestedWords.java b/java/src/com/android/inputmethod/latin/SuggestedWords.java
index bddeac495..cbf48f0c0 100644
--- a/java/src/com/android/inputmethod/latin/SuggestedWords.java
+++ b/java/src/com/android/inputmethod/latin/SuggestedWords.java
@@ -27,8 +27,10 @@ import com.android.inputmethod.latin.define.DebugFlags;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
+import java.util.Locale;
import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
public class SuggestedWords {
public static final int INDEX_OF_TYPED_WORD = 0;
@@ -50,10 +52,12 @@ public class SuggestedWords {
private static final ArrayList<SuggestedWordInfo> EMPTY_WORD_INFO_LIST = new ArrayList<>(0);
@Nonnull
private static final SuggestedWords EMPTY = new SuggestedWords(
- EMPTY_WORD_INFO_LIST, null /* rawSuggestions */, false /* typedWordValid */,
- false /* willAutoCorrect */, false /* isObsoleteSuggestions */, INPUT_STYLE_NONE);
+ EMPTY_WORD_INFO_LIST, null /* rawSuggestions */, null /* typedWord */,
+ false /* typedWordValid */, false /* willAutoCorrect */,
+ false /* isObsoleteSuggestions */, INPUT_STYLE_NONE, NOT_A_SEQUENCE_NUMBER);
- public final String mTypedWord;
+ @Nullable
+ public final SuggestedWordInfo mTypedWordInfo;
public final boolean mTypedWordValid;
// Note: this INCLUDES cases where the word will auto-correct to itself. A good definition
// of what this flag means would be "the top suggestion is strong enough to auto-correct",
@@ -64,25 +68,14 @@ public class SuggestedWords {
// INPUT_STYLE_* constants above.
public final int mInputStyle;
public final int mSequenceNumber; // Sequence number for auto-commit.
+ @Nonnull
protected final ArrayList<SuggestedWordInfo> mSuggestedWordInfoList;
+ @Nullable
public final ArrayList<SuggestedWordInfo> mRawSuggestions;
- public SuggestedWords(final ArrayList<SuggestedWordInfo> suggestedWordInfoList,
- final ArrayList<SuggestedWordInfo> rawSuggestions,
- final boolean typedWordValid,
- final boolean willAutoCorrect,
- final boolean isObsoleteSuggestions,
- final int inputStyle) {
- this(suggestedWordInfoList, rawSuggestions,
- (suggestedWordInfoList.isEmpty() || isPrediction(inputStyle)) ? null
- : suggestedWordInfoList.get(INDEX_OF_TYPED_WORD).mWord,
- typedWordValid, willAutoCorrect,
- isObsoleteSuggestions, inputStyle, NOT_A_SEQUENCE_NUMBER);
- }
-
- public SuggestedWords(final ArrayList<SuggestedWordInfo> suggestedWordInfoList,
- final ArrayList<SuggestedWordInfo> rawSuggestions,
- final String typedWord,
+ public SuggestedWords(@Nonnull final ArrayList<SuggestedWordInfo> suggestedWordInfoList,
+ @Nullable final ArrayList<SuggestedWordInfo> rawSuggestions,
+ @Nullable final SuggestedWordInfo typedWordInfo,
final boolean typedWordValid,
final boolean willAutoCorrect,
final boolean isObsoleteSuggestions,
@@ -95,7 +88,7 @@ public class SuggestedWords {
mIsObsoleteSuggestions = isObsoleteSuggestions;
mInputStyle = inputStyle;
mSequenceNumber = sequenceNumber;
- mTypedWord = typedWord;
+ mTypedWordInfo = typedWordInfo;
}
public boolean isEmpty() {
@@ -211,14 +204,12 @@ public class SuggestedWords {
// Should get rid of the first one (what the user typed previously) from suggestions
// and replace it with what the user currently typed.
public static ArrayList<SuggestedWordInfo> getTypedWordAndPreviousSuggestions(
- final String typedWord, final SuggestedWords previousSuggestions) {
+ @Nonnull final SuggestedWordInfo typedWordInfo,
+ @Nonnull final SuggestedWords previousSuggestions) {
final ArrayList<SuggestedWordInfo> suggestionsList = new ArrayList<>();
final HashSet<String> alreadySeen = new HashSet<>();
- suggestionsList.add(new SuggestedWordInfo(typedWord, SuggestedWordInfo.MAX_SCORE,
- SuggestedWordInfo.KIND_TYPED, Dictionary.DICTIONARY_USER_TYPED,
- SuggestedWordInfo.NOT_AN_INDEX /* indexOfTouchPointOfSecondWord */,
- SuggestedWordInfo.NOT_A_CONFIDENCE /* autoCommitFirstWordConfidence */));
- alreadySeen.add(typedWord.toString());
+ suggestionsList.add(typedWordInfo);
+ alreadySeen.add(typedWordInfo.mWord);
final int previousSize = previousSuggestions.size();
for (int index = 1; index < previousSize; index++) {
final SuggestedWordInfo prevWordInfo = previousSuggestions.getInfo(index);
@@ -365,37 +356,53 @@ public class SuggestedWords {
}
// This will always remove the higher index if a duplicate is found.
- public static boolean removeDups(final String typedWord,
- ArrayList<SuggestedWordInfo> candidates) {
+ // Returns null if the typed word is not found. Always return the dictionary for the
+ // highest suggestion matching the locale if found, otherwise return the dictionary for
+ // the highest suggestion.
+ @Nullable
+ public static Dictionary removeDupsAndReturnSourceOfTypedWord(
+ @Nullable final String typedWord,
+ @Nullable final Locale preferredLocale,
+ @Nonnull ArrayList<SuggestedWordInfo> candidates) {
if (candidates.isEmpty()) {
- return false;
+ return null;
}
- final boolean didRemoveTypedWord;
+ final Dictionary sourceDictionaryOfTypedWord;
if (!TextUtils.isEmpty(typedWord)) {
- didRemoveTypedWord = removeSuggestedWordInfoFrom(typedWord, candidates,
- -1 /* startIndexExclusive */);
+ sourceDictionaryOfTypedWord =
+ removeSuggestedWordInfoFromListAndReturnSourceDictionary(typedWord,
+ preferredLocale, candidates, -1 /* startIndexExclusive */);
} else {
- didRemoveTypedWord = false;
+ sourceDictionaryOfTypedWord = null;
}
for (int i = 0; i < candidates.size(); ++i) {
- removeSuggestedWordInfoFrom(candidates.get(i).mWord, candidates,
- i /* startIndexExclusive */);
+ removeSuggestedWordInfoFromListAndReturnSourceDictionary(candidates.get(i).mWord,
+ null /* preferredLocale */, candidates, i /* startIndexExclusive */);
}
- return didRemoveTypedWord;
+ return sourceDictionaryOfTypedWord;
}
- private static boolean removeSuggestedWordInfoFrom(final String word,
- final ArrayList<SuggestedWordInfo> candidates, final int startIndexExclusive) {
- boolean didRemove = false;
+ @Nullable
+ private static Dictionary removeSuggestedWordInfoFromListAndReturnSourceDictionary(
+ @Nonnull final String word, @Nullable final Locale preferredLocale,
+ @Nonnull final ArrayList<SuggestedWordInfo> candidates,
+ final int startIndexExclusive) {
+ Dictionary sourceDictionaryOfTypedWord = null;
for (int i = startIndexExclusive + 1; i < candidates.size(); ++i) {
final SuggestedWordInfo previous = candidates.get(i);
if (word.equals(previous.mWord)) {
- didRemove = true;
+ if (null == sourceDictionaryOfTypedWord
+ || (null != preferredLocale
+ && preferredLocale.equals(previous.mSourceDict.mLocale))) {
+ if (Dictionary.TYPE_USER_HISTORY != previous.mSourceDict.mDictType) {
+ sourceDictionaryOfTypedWord = previous.mSourceDict;
+ }
+ }
candidates.remove(i);
--i;
}
}
- return didRemove;
+ return sourceDictionaryOfTypedWord;
}
}
@@ -423,8 +430,10 @@ public class SuggestedWords {
info.mSourceDict, SuggestedWordInfo.NOT_AN_INDEX,
SuggestedWordInfo.NOT_A_CONFIDENCE));
}
- return new SuggestedWords(newSuggestions, null /* rawSuggestions */, mTypedWordValid,
- mWillAutoCorrect, mIsObsoleteSuggestions, INPUT_STYLE_TAIL_BATCH);
+ return new SuggestedWords(newSuggestions, null /* rawSuggestions */,
+ newSuggestions.isEmpty() ? null : newSuggestions.get(0) /* typedWordInfo */,
+ mTypedWordValid, mWillAutoCorrect, mIsObsoleteSuggestions, INPUT_STYLE_TAIL_BATCH,
+ NOT_A_SEQUENCE_NUMBER);
}
/**
diff --git a/java/src/com/android/inputmethod/latin/SystemBroadcastReceiver.java b/java/src/com/android/inputmethod/latin/SystemBroadcastReceiver.java
index 123ab208c..982d4c690 100644
--- a/java/src/com/android/inputmethod/latin/SystemBroadcastReceiver.java
+++ b/java/src/com/android/inputmethod/latin/SystemBroadcastReceiver.java
@@ -69,7 +69,7 @@ public final class SystemBroadcastReceiver extends BroadcastReceiver {
// subtypes when the package is replaced.
RichInputMethodManager.init(context);
final RichInputMethodManager richImm = RichInputMethodManager.getInstance();
- final InputMethodSubtype[] additionalSubtypes = richImm.getAdditionalSubtypes(context);
+ final InputMethodSubtype[] additionalSubtypes = richImm.getAdditionalSubtypes();
richImm.setAdditionalInputMethodSubtypes(additionalSubtypes);
LauncherIconVisibilityManager.updateSetupWizardIconVisibility(context);
} else if (Intent.ACTION_BOOT_COMPLETED.equals(intentAction)) {
diff --git a/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java b/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java
index bafea178e..0185a04ef 100644
--- a/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java
+++ b/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java
@@ -255,7 +255,7 @@ public final class InputLogic {
handler.postUpdateSuggestionStrip(SuggestedWords.INPUT_STYLE_TYPING);
final String text = performSpecificTldProcessingOnTextInput(rawText);
if (SpaceState.PHANTOM == mSpaceState) {
- promotePhantomSpace(settingsValues);
+ insertAutomaticSpaceIfOptionsAndTextAllow(settingsValues);
}
mConnection.commitText(text, 1);
StatsUtils.onWordCommitUserTyped(mEnteredText, mWordComposer.isBatchMode());
@@ -322,7 +322,7 @@ public final class InputLogic {
final int firstChar = Character.codePointAt(suggestion, 0);
if (!settingsValues.isWordSeparator(firstChar)
|| settingsValues.isUsuallyPrecededBySpace(firstChar)) {
- promotePhantomSpace(settingsValues);
+ insertAutomaticSpaceIfOptionsAndTextAllow(settingsValues);
}
}
@@ -584,7 +584,9 @@ public final class InputLogic {
if (candidate.mSourceDict.shouldAutoCommit(candidate)) {
final String[] commitParts = candidate.mWord.split(Constants.WORD_SEPARATOR, 2);
batchPointers.shift(candidate.mIndexOfTouchPointOfSecondWord);
- promotePhantomSpace(settingsValues);
+ if (SpaceState.PHANTOM == mSpaceState) {
+ insertAutomaticSpaceIfOptionsAndTextAllow(settingsValues);
+ }
mConnection.commitText(commitParts[0], 0);
StatsUtils.onWordCommitUserTyped(commitParts[0], mWordComposer.isBatchMode());
mSpaceState = SpaceState.PHANTOM;
@@ -621,11 +623,7 @@ public final class InputLogic {
} else {
// We can't use suggestedWords.getWord(SuggestedWords.INDEX_OF_TYPED_WORD)
// because it may differ from mWordComposer.mTypedWord.
- suggestedWordInfo = new SuggestedWordInfo(suggestedWords.mTypedWord,
- SuggestedWordInfo.MAX_SCORE,
- SuggestedWordInfo.KIND_TYPED, Dictionary.DICTIONARY_USER_TYPED,
- SuggestedWordInfo.NOT_AN_INDEX /* indexOfTouchPointOfSecondWord */,
- SuggestedWordInfo.NOT_A_CONFIDENCE /* autoCommitFirstWordConfidence */);
+ suggestedWordInfo = suggestedWords.mTypedWordInfo;
}
mWordComposer.setAutoCorrection(suggestedWordInfo);
}
@@ -861,7 +859,7 @@ public final class InputLogic {
// Sanity check
throw new RuntimeException("Should not be composing here");
}
- promotePhantomSpace(settingsValues);
+ insertAutomaticSpaceIfOptionsAndTextAllow(settingsValues);
}
if (mWordComposer.isCursorFrontOrMiddleOfComposingWord()) {
@@ -972,7 +970,7 @@ public final class InputLogic {
}
if (needsPrecedingSpace) {
- promotePhantomSpace(settingsValues);
+ insertAutomaticSpaceIfOptionsAndTextAllow(settingsValues);
}
if (tryPerformDoubleSpacePeriod(event, inputTransaction)) {
@@ -1176,14 +1174,13 @@ public final class InputLogic {
StatsUtils.onBackspacePressed(totalDeletedLength);
}
}
- if (inputTransaction.mSettingsValues
- .isSuggestionsEnabledPerUserSettings()
+ if (inputTransaction.mSettingsValues.isSuggestionsEnabledPerUserSettings()
&& inputTransaction.mSettingsValues.mSpacingAndPunctuations
.mCurrentLanguageHasSpaces
&& !mConnection.isCursorFollowedByWordCharacter(
inputTransaction.mSettingsValues.mSpacingAndPunctuations)) {
restartSuggestionsOnWordTouchedByCursor(inputTransaction.mSettingsValues,
- currentKeyboardScriptId);
+ false /* forStartInput */, currentKeyboardScriptId);
}
}
}
@@ -1413,14 +1410,19 @@ public final class InputLogic {
new OnGetSuggestedWordsCallback() {
@Override
public void onGetSuggestedWords(final SuggestedWords suggestedWords) {
- final String typedWord = mWordComposer.getTypedWord();
+ final String typedWordString = mWordComposer.getTypedWord();
+ final SuggestedWordInfo typedWordInfo = new SuggestedWordInfo(
+ typedWordString, SuggestedWordInfo.MAX_SCORE,
+ SuggestedWordInfo.KIND_TYPED, Dictionary.DICTIONARY_USER_TYPED,
+ SuggestedWordInfo.NOT_AN_INDEX /* indexOfTouchPointOfSecondWord */,
+ SuggestedWordInfo.NOT_A_CONFIDENCE);
// Show new suggestions if we have at least one. Otherwise keep the old
// suggestions with the new typed word. Exception: if the length of the
// typed word is <= 1 (after a deletion typically) we clear old suggestions.
- if (suggestedWords.size() > 1 || typedWord.length() <= 1) {
+ if (suggestedWords.size() > 1 || typedWordString.length() <= 1) {
holder.set(suggestedWords);
} else {
- holder.set(retrieveOlderSuggestions(typedWord, mSuggestedWords));
+ holder.set(retrieveOlderSuggestions(typedWordInfo, mSuggestedWords));
}
}
}
@@ -1439,10 +1441,13 @@ public final class InputLogic {
* do nothing.
*
* @param settingsValues the current values of the settings.
- * suggestions in the suggestion list.
+ * @param forStartInput whether we're doing this in answer to starting the input (as opposed
+ * to a cursor move, for example). In ICS, there is a platform bug that we need to work
+ * around only when we come here at input start time.
*/
// TODO: make this private.
public void restartSuggestionsOnWordTouchedByCursor(final SettingsValues settingsValues,
+ final boolean forStartInput,
// TODO: remove this argument, put it into settingsValues
final int currentKeyboardScriptId) {
// HACK: We may want to special-case some apps that exhibit bad behavior in case of
@@ -1489,13 +1494,14 @@ public final class InputLogic {
final int numberOfCharsInWordBeforeCursor = range.getNumberOfCharsInWordBeforeCursor();
if (numberOfCharsInWordBeforeCursor > expectedCursorPosition) return;
final ArrayList<SuggestedWordInfo> suggestions = new ArrayList<>();
- final String typedWord = range.mWord.toString();
- suggestions.add(new SuggestedWordInfo(typedWord,
+ final String typedWordString = range.mWord.toString();
+ final SuggestedWordInfo typedWordInfo = new SuggestedWordInfo(typedWordString,
SuggestedWords.MAX_SUGGESTIONS + 1,
SuggestedWordInfo.KIND_TYPED, Dictionary.DICTIONARY_USER_TYPED,
SuggestedWordInfo.NOT_AN_INDEX /* indexOfTouchPointOfSecondWord */,
- SuggestedWordInfo.NOT_A_CONFIDENCE /* autoCommitFirstWordConfidence */));
- if (!isResumableWord(settingsValues, typedWord)) {
+ SuggestedWordInfo.NOT_A_CONFIDENCE /* autoCommitFirstWordConfidence */);
+ suggestions.add(typedWordInfo);
+ if (!isResumableWord(settingsValues, typedWordString)) {
mSuggestionStripViewAccessor.setNeutralSuggestionStrip();
return;
}
@@ -1503,7 +1509,7 @@ public final class InputLogic {
for (final SuggestionSpan span : range.getSuggestionSpansAtWord()) {
for (final String s : span.getSuggestions()) {
++i;
- if (!TextUtils.equals(s, typedWord)) {
+ if (!TextUtils.equals(s, typedWordString)) {
suggestions.add(new SuggestedWordInfo(s,
SuggestedWords.MAX_SUGGESTIONS - i,
SuggestedWordInfo.KIND_RESUMED, Dictionary.DICTIONARY_RESUMED,
@@ -1513,12 +1519,14 @@ public final class InputLogic {
}
}
}
- final int[] codePoints = StringUtils.toCodePointArray(typedWord);
+ final int[] codePoints = StringUtils.toCodePointArray(typedWordString);
mWordComposer.setComposingWord(codePoints,
mLatinIME.getCoordinatesForCurrentKeyboard(codePoints));
mWordComposer.setCursorPositionWithinWord(
- typedWord.codePointCount(0, numberOfCharsInWordBeforeCursor));
- mConnection.maybeMoveTheCursorAroundAndRestoreToWorkaroundABug();
+ typedWordString.codePointCount(0, numberOfCharsInWordBeforeCursor));
+ if (forStartInput) {
+ mConnection.maybeMoveTheCursorAroundAndRestoreToWorkaroundABug();
+ }
mConnection.setComposingRegion(expectedCursorPosition - numberOfCharsInWordBeforeCursor,
expectedCursorPosition + range.getNumberOfCharsInWordAfterCursor());
if (suggestions.size() <= 1) {
@@ -1537,7 +1545,7 @@ public final class InputLogic {
// color of the word in the suggestion strip changes according to this parameter,
// and false gives the correct color.
final SuggestedWords suggestedWords = new SuggestedWords(suggestions,
- null /* rawSuggestions */, typedWord, false /* typedWordValid */,
+ null /* rawSuggestions */, typedWordInfo, false /* typedWordValid */,
false /* willAutoCorrect */, false /* isObsoleteSuggestions */,
SuggestedWords.INPUT_STYLE_RECORRECTION, SuggestedWords.NOT_A_SEQUENCE_NUMBER);
doShowSuggestionsAndClearAutoCorrectionIndicator(suggestedWords);
@@ -1870,20 +1878,21 @@ public final class InputLogic {
* Make a {@link com.android.inputmethod.latin.SuggestedWords} object containing a typed word
* and obsolete suggestions.
* See {@link com.android.inputmethod.latin.SuggestedWords#getTypedWordAndPreviousSuggestions(
- * String, com.android.inputmethod.latin.SuggestedWords)}.
- * @param typedWord The typed word as a string.
+ * SuggestedWordInfo, com.android.inputmethod.latin.SuggestedWords)}.
+ * @param typedWordInfo The typed word as a SuggestedWordInfo.
* @param previousSuggestedWords The previously suggested words.
* @return Obsolete suggestions with the newly typed word.
*/
- static SuggestedWords retrieveOlderSuggestions(final String typedWord,
+ static SuggestedWords retrieveOlderSuggestions(final SuggestedWordInfo typedWordInfo,
final SuggestedWords previousSuggestedWords) {
final SuggestedWords oldSuggestedWords = previousSuggestedWords.isPunctuationSuggestions()
? SuggestedWords.getEmptyInstance() : previousSuggestedWords;
final ArrayList<SuggestedWords.SuggestedWordInfo> typedWordAndPreviousSuggestions =
- SuggestedWords.getTypedWordAndPreviousSuggestions(typedWord, oldSuggestedWords);
+ SuggestedWords.getTypedWordAndPreviousSuggestions(typedWordInfo, oldSuggestedWords);
return new SuggestedWords(typedWordAndPreviousSuggestions, null /* rawSuggestions */,
- false /* typedWordValid */, false /* hasAutoCorrectionCandidate */,
- true /* isObsoleteSuggestions */, oldSuggestedWords.mInputStyle);
+ typedWordInfo, false /* typedWordValid */, false /* hasAutoCorrectionCandidate */,
+ true /* isObsoleteSuggestions */, oldSuggestedWords.mInputStyle,
+ SuggestedWords.NOT_A_SEQUENCE_NUMBER);
}
/**
@@ -1960,14 +1969,14 @@ public final class InputLogic {
}
/**
- * Promote a phantom space to an actual space.
+ * Insert an automatic space, if the options allow it.
*
- * This essentially inserts a space, and that's it. It just checks the options and the text
- * before the cursor are appropriate before doing it.
+ * This checks the options and the text before the cursor are appropriate before inserting
+ * an automatic space.
*
* @param settingsValues the current values of the settings.
*/
- private void promotePhantomSpace(final SettingsValues settingsValues) {
+ private void insertAutomaticSpaceIfOptionsAndTextAllow(final SettingsValues settingsValues) {
if (settingsValues.shouldInsertSpacesAutomatically()
&& settingsValues.mSpacingAndPunctuations.mCurrentLanguageHasSpaces
&& !mConnection.textBeforeCursorLooksLikeURL()) {
@@ -1990,7 +1999,7 @@ public final class InputLogic {
}
mConnection.beginBatchEdit();
if (SpaceState.PHANTOM == mSpaceState) {
- promotePhantomSpace(settingsValues);
+ insertAutomaticSpaceIfOptionsAndTextAllow(settingsValues);
}
final SuggestedWordInfo autoCommitCandidate = mSuggestedWords.getAutoCommitCandidate();
// Commit except the last word for phrase gesture if the top suggestion is eligible for auto
diff --git a/java/src/com/android/inputmethod/latin/utils/SubtypeLocaleUtils.java b/java/src/com/android/inputmethod/latin/utils/SubtypeLocaleUtils.java
index 013f024c0..0e7f4717d 100644
--- a/java/src/com/android/inputmethod/latin/utils/SubtypeLocaleUtils.java
+++ b/java/src/com/android/inputmethod/latin/utils/SubtypeLocaleUtils.java
@@ -34,6 +34,7 @@ import java.util.HashMap;
import java.util.Locale;
import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
/**
* A helper class to deal with subtype locales.
@@ -273,7 +274,7 @@ public final class SubtypeLocaleUtils {
}
@Nonnull
- public static String getSubtypeNameForLogging(@Nonnull final InputMethodSubtype subtype) {
+ public static String getSubtypeNameForLogging(@Nullable final InputMethodSubtype subtype) {
if (subtype == null) {
return "<null subtype>";
}