aboutsummaryrefslogtreecommitdiffstats
path: root/java/src
diff options
context:
space:
mode:
Diffstat (limited to 'java/src')
-rw-r--r--java/src/com/android/inputmethod/keyboard/Key.java22
-rw-r--r--java/src/com/android/inputmethod/keyboard/Keyboard.java22
-rw-r--r--java/src/com/android/inputmethod/keyboard/KeyboardSet.java2
-rw-r--r--java/src/com/android/inputmethod/latin/AudioAndHapticFeedbackManager.java14
-rw-r--r--java/src/com/android/inputmethod/latin/AutoCorrection.java67
-rw-r--r--java/src/com/android/inputmethod/latin/LatinIME.java101
-rw-r--r--java/src/com/android/inputmethod/latin/Suggest.java175
-rw-r--r--java/src/com/android/inputmethod/latin/SuggestedWords.java90
-rw-r--r--java/src/com/android/inputmethod/latin/suggestions/SuggestionsView.java8
9 files changed, 271 insertions, 230 deletions
diff --git a/java/src/com/android/inputmethod/keyboard/Key.java b/java/src/com/android/inputmethod/keyboard/Key.java
index 6b4de184f..b09a27540 100644
--- a/java/src/com/android/inputmethod/keyboard/Key.java
+++ b/java/src/com/android/inputmethod/keyboard/Key.java
@@ -73,6 +73,8 @@ public class Key {
private static final int LABEL_FLAGS_PRESERVE_CASE = 0x8000;
private static final int LABEL_FLAGS_SHIFTED_LETTER_ACTIVATED = 0x10000;
private static final int LABEL_FLAGS_FROM_CUSTOM_ACTION_LABEL = 0x20000;
+ private static final int LABEL_FLAGS_DISABLE_HINT_LABEL = 0x40000000;
+ private static final int LABEL_FLAGS_DISABLE_ADDITIONAL_MORE_KEYS = 0x80000000;
/** Icon to display instead of a label. Icon takes precedence over a label */
private final int mIconId;
@@ -240,7 +242,8 @@ public class Key {
mDisabledIconId = style.getInt(keyAttr,
R.styleable.Keyboard_Key_keyIconDisabled, KeyboardIconsSet.ICON_UNDEFINED);
- mLabelFlags = style.getFlag(keyAttr, R.styleable.Keyboard_Key_keyLabelFlags);
+ mLabelFlags = style.getFlag(keyAttr, R.styleable.Keyboard_Key_keyLabelFlags)
+ | row.getDefaultKeyLabelFlags();
final boolean preserveCase = (mLabelFlags & LABEL_FLAGS_PRESERVE_CASE) != 0;
int actionFlags = style.getFlag(keyAttr, R.styleable.Keyboard_Key_keyActionFlags);
String[] moreKeys = style.getStringArray(keyAttr, R.styleable.Keyboard_Key_moreKeys);
@@ -265,8 +268,13 @@ public class Key {
}
mMoreKeysColumnAndFlags = moreKeysColumn;
- final String[] additionalMoreKeys = style.getStringArray(
- keyAttr, R.styleable.Keyboard_Key_additionalMoreKeys);
+ final String[] additionalMoreKeys;
+ if ((mLabelFlags & LABEL_FLAGS_DISABLE_ADDITIONAL_MORE_KEYS) != 0) {
+ additionalMoreKeys = null;
+ } else {
+ additionalMoreKeys = style.getStringArray(
+ keyAttr, R.styleable.Keyboard_Key_additionalMoreKeys);
+ }
moreKeys = KeySpecParser.insertAddtionalMoreKeys(moreKeys, additionalMoreKeys);
if (moreKeys != null) {
actionFlags |= ACTION_FLAGS_ENABLE_LONG_PRESS;
@@ -284,8 +292,12 @@ public class Key {
mLabel = adjustCaseOfStringForKeyboardId(style.getString(
keyAttr, R.styleable.Keyboard_Key_keyLabel), preserveCase, params.mId);
}
- mHintLabel = adjustCaseOfStringForKeyboardId(style.getString(
- keyAttr, R.styleable.Keyboard_Key_keyHintLabel), preserveCase, params.mId);
+ if ((mLabelFlags & LABEL_FLAGS_DISABLE_HINT_LABEL) != 0) {
+ mHintLabel = null;
+ } else {
+ mHintLabel = adjustCaseOfStringForKeyboardId(style.getString(
+ keyAttr, R.styleable.Keyboard_Key_keyHintLabel), preserveCase, params.mId);
+ }
String outputText = adjustCaseOfStringForKeyboardId(style.getString(
keyAttr, R.styleable.Keyboard_Key_keyOutputText), preserveCase, params.mId);
final int code = style.getInt(
diff --git a/java/src/com/android/inputmethod/keyboard/Keyboard.java b/java/src/com/android/inputmethod/keyboard/Keyboard.java
index 689e322ce..53467122a 100644
--- a/java/src/com/android/inputmethod/keyboard/Keyboard.java
+++ b/java/src/com/android/inputmethod/keyboard/Keyboard.java
@@ -505,6 +505,8 @@ public class Keyboard {
private float mDefaultKeyWidth;
/** Default height of a key in this row. */
public final int mRowHeight;
+ /** Default keyLabelFlags in this row. */
+ private int mDefaultKeyLabelFlags;
private final int mCurrentY;
// Will be updated by {@link Key}'s constructor.
@@ -525,6 +527,7 @@ public class Keyboard {
params.mBaseWidth, params.mDefaultKeyWidth);
keyAttr.recycle();
+ mDefaultKeyLabelFlags = 0;
mCurrentY = y;
mCurrentX = 0.0f;
}
@@ -537,6 +540,14 @@ public class Keyboard {
mDefaultKeyWidth = defaultKeyWidth;
}
+ public int getDefaultKeyLabelFlags() {
+ return mDefaultKeyLabelFlags;
+ }
+
+ public void setDefaultKeyLabelFlags(int keyLabelFlags) {
+ mDefaultKeyLabelFlags = keyLabelFlags;
+ }
+
public void setXPos(float keyXPos) {
mCurrentX = keyXPos;
}
@@ -927,6 +938,7 @@ public class Keyboard {
R.styleable.Keyboard_Key);
int keyboardLayout = 0;
float savedDefaultKeyWidth = 0;
+ int savedDefaultKeyLabelFlags = 0;
try {
XmlParseUtils.checkAttributeExists(keyboardAttr,
R.styleable.Keyboard_Include_keyboardLayout, "keyboardLayout",
@@ -935,6 +947,7 @@ public class Keyboard {
R.styleable.Keyboard_Include_keyboardLayout, 0);
if (row != null) {
savedDefaultKeyWidth = row.getDefaultKeyWidth();
+ savedDefaultKeyLabelFlags = row.getDefaultKeyLabelFlags();
if (keyAttr.hasValue(R.styleable.Keyboard_Key_keyXPos)) {
// Override current x coordinate.
row.setXPos(row.getKeyX(keyAttr));
@@ -943,6 +956,12 @@ public class Keyboard {
// Override default key width.
row.setDefaultKeyWidth(row.getKeyWidth(keyAttr));
}
+ if (keyAttr.hasValue(R.styleable.Keyboard_Key_keyLabelFlags)) {
+ // Override default key label flags.
+ row.setDefaultKeyLabelFlags(
+ keyAttr.getInt(R.styleable.Keyboard_Key_keyLabelFlags, 0)
+ | savedDefaultKeyLabelFlags);
+ }
}
} finally {
keyboardAttr.recycle();
@@ -959,8 +978,9 @@ public class Keyboard {
parseMerge(parserForInclude, row, skip);
} finally {
if (row != null) {
- // Restore default key width.
+ // Restore default key width and key label flags.
row.setDefaultKeyWidth(savedDefaultKeyWidth);
+ row.setDefaultKeyLabelFlags(savedDefaultKeyLabelFlags);
}
parserForInclude.close();
}
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardSet.java b/java/src/com/android/inputmethod/keyboard/KeyboardSet.java
index 5ac6d03a8..680ff0d25 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardSet.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardSet.java
@@ -379,6 +379,8 @@ public class KeyboardSet {
}
}
+ // TODO: Should be removed. This is no longer required if {@link InputMethodSubtype} is
+ // supported.
public static String parseKeyboardLocale(Resources res, int resId)
throws XmlPullParserException, IOException {
final XmlPullParser parser = res.getXml(resId);
diff --git a/java/src/com/android/inputmethod/latin/AudioAndHapticFeedbackManager.java b/java/src/com/android/inputmethod/latin/AudioAndHapticFeedbackManager.java
index 1cbdbd650..9c5ccc76b 100644
--- a/java/src/com/android/inputmethod/latin/AudioAndHapticFeedbackManager.java
+++ b/java/src/com/android/inputmethod/latin/AudioAndHapticFeedbackManager.java
@@ -16,9 +16,7 @@
package com.android.inputmethod.latin;
-import android.content.BroadcastReceiver;
import android.content.Context;
-import android.content.Intent;
import android.media.AudioManager;
import android.view.HapticFeedbackConstants;
import android.view.View;
@@ -32,7 +30,7 @@ import com.android.inputmethod.keyboard.Keyboard;
* It offers a consistent and simple interface that allows LatinIME to forget about the
* complexity of settings and the like.
*/
-public class AudioAndHapticFeedbackManager extends BroadcastReceiver {
+public class AudioAndHapticFeedbackManager {
final private SettingsValues mSettingsValues;
final private AudioManager mAudioManager;
final private VibratorCompatWrapper mVibrator;
@@ -100,13 +98,7 @@ public class AudioAndHapticFeedbackManager extends BroadcastReceiver {
}
}
- @Override
- public void onReceive(Context context, Intent intent) {
- final String action = intent.getAction();
- // The following test is supposedly useless since we only listen for the ringer event.
- // Still, it's a good safety measure.
- if (action.equals(AudioManager.RINGER_MODE_CHANGED_ACTION)) {
- mSoundOn = reevaluateIfSoundIsOn();
- }
+ public void onRingerModeChanged() {
+ mSoundOn = reevaluateIfSoundIsOn();
}
}
diff --git a/java/src/com/android/inputmethod/latin/AutoCorrection.java b/java/src/com/android/inputmethod/latin/AutoCorrection.java
index 425b5c3f3..9c35f8f6f 100644
--- a/java/src/com/android/inputmethod/latin/AutoCorrection.java
+++ b/java/src/com/android/inputmethod/latin/AutoCorrection.java
@@ -25,36 +25,25 @@ import java.util.Map;
public class AutoCorrection {
private static final boolean DBG = LatinImeLogger.sDBG;
private static final String TAG = AutoCorrection.class.getSimpleName();
- private CharSequence mAutoCorrectionWord;
- private double mNormalizedScore;
- public void init() {
- mAutoCorrectionWord = null;
- mNormalizedScore = Integer.MIN_VALUE;
+ private AutoCorrection() {
+ // Purely static class: can't instantiate.
}
- public boolean hasAutoCorrection() {
- return null != mAutoCorrectionWord;
- }
-
- public double getNormalizedScore() {
- return mNormalizedScore;
- }
-
- public CharSequence updateAutoCorrectionStatus(Map<String, Dictionary> dictionaries,
+ public static CharSequence computeAutoCorrectionWord(Map<String, Dictionary> dictionaries,
WordComposer wordComposer, ArrayList<CharSequence> suggestions, int[] sortedScores,
- CharSequence typedWord, double autoCorrectionThreshold, int correctionMode,
+ CharSequence consideredWord, double autoCorrectionThreshold,
CharSequence whitelistedWord) {
if (hasAutoCorrectionForWhitelistedWord(whitelistedWord)) {
- mAutoCorrectionWord = whitelistedWord;
- } else if (hasAutoCorrectionForTypedWord(
- dictionaries, wordComposer, suggestions, typedWord, correctionMode)) {
- mAutoCorrectionWord = typedWord;
- } else if (hasAutoCorrectionForBinaryDictionary(wordComposer, suggestions, correctionMode,
- sortedScores, typedWord, autoCorrectionThreshold)) {
- mAutoCorrectionWord = suggestions.get(0);
+ return whitelistedWord;
+ } else if (hasAutoCorrectionForConsideredWord(
+ dictionaries, wordComposer, suggestions, consideredWord)) {
+ return consideredWord;
+ } else if (hasAutoCorrectionForBinaryDictionary(wordComposer, suggestions,
+ sortedScores, consideredWord, autoCorrectionThreshold)) {
+ return suggestions.get(0);
}
- return mAutoCorrectionWord;
+ return null;
}
public static boolean isValidWord(
@@ -98,35 +87,31 @@ public class AutoCorrection {
return whiteListedWord != null;
}
- private static boolean hasAutoCorrectionForTypedWord(Map<String, Dictionary> dictionaries,
- WordComposer wordComposer, ArrayList<CharSequence> suggestions, CharSequence typedWord,
- int correctionMode) {
- if (TextUtils.isEmpty(typedWord)) return false;
+ private static boolean hasAutoCorrectionForConsideredWord(Map<String, Dictionary> dictionaries,
+ WordComposer wordComposer, ArrayList<CharSequence> suggestions,
+ CharSequence consideredWord) {
+ if (TextUtils.isEmpty(consideredWord)) return false;
return wordComposer.size() > 1 && suggestions.size() > 0
- && !allowsToBeAutoCorrected(dictionaries, typedWord, false)
- && (correctionMode == Suggest.CORRECTION_FULL
- || correctionMode == Suggest.CORRECTION_FULL_BIGRAM);
+ && !allowsToBeAutoCorrected(dictionaries, consideredWord, false);
}
- private boolean hasAutoCorrectionForBinaryDictionary(WordComposer wordComposer,
- ArrayList<CharSequence> suggestions, int correctionMode, int[] sortedScores,
- CharSequence typedWord, double autoCorrectionThreshold) {
- if (wordComposer.size() > 1 && (correctionMode == Suggest.CORRECTION_FULL
- || correctionMode == Suggest.CORRECTION_FULL_BIGRAM)
- && typedWord != null && suggestions.size() > 0 && sortedScores.length > 0) {
+ private static boolean hasAutoCorrectionForBinaryDictionary(WordComposer wordComposer,
+ ArrayList<CharSequence> suggestions, int[] sortedScores,
+ CharSequence consideredWord, double autoCorrectionThreshold) {
+ if (wordComposer.size() > 1 && suggestions.size() > 0 && sortedScores.length > 0) {
final CharSequence autoCorrectionSuggestion = suggestions.get(0);
final int autoCorrectionSuggestionScore = sortedScores[0];
// TODO: when the normalized score of the first suggestion is nearly equals to
// the normalized score of the second suggestion, behave less aggressive.
- mNormalizedScore = BinaryDictionary.calcNormalizedScore(
- typedWord.toString(), autoCorrectionSuggestion.toString(),
+ final double normalizedScore = BinaryDictionary.calcNormalizedScore(
+ consideredWord.toString(), autoCorrectionSuggestion.toString(),
autoCorrectionSuggestionScore);
if (DBG) {
- Log.d(TAG, "Normalized " + typedWord + "," + autoCorrectionSuggestion + ","
- + autoCorrectionSuggestionScore + ", " + mNormalizedScore
+ Log.d(TAG, "Normalized " + consideredWord + "," + autoCorrectionSuggestion + ","
+ + autoCorrectionSuggestionScore + ", " + normalizedScore
+ "(" + autoCorrectionThreshold + ")");
}
- if (mNormalizedScore >= autoCorrectionThreshold) {
+ if (normalizedScore >= autoCorrectionThreshold) {
if (DBG) {
Log.d(TAG, "Auto corrected by S-threshold.");
}
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index ca38cdeec..d96b858eb 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -72,6 +72,7 @@ import com.android.inputmethod.latin.suggestions.SuggestionsView;
import java.io.FileDescriptor;
import java.io.PrintWriter;
+import java.util.List;
import java.util.Locale;
/**
@@ -532,6 +533,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
// Also receive installation and removal of a dictionary pack.
final IntentFilter filter = new IntentFilter();
filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
+ filter.addAction(AudioManager.RINGER_MODE_CHANGED_ACTION);
registerReceiver(mReceiver, filter);
mVoiceProxy = VoiceProxy.init(this, prefs, mHandler);
@@ -547,19 +549,11 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
registerReceiver(mDictionaryPackInstallReceiver, newDictFilter);
}
- private void renewFeedbackReceiver() {
- if (null != mFeedbackManager) unregisterReceiver(mFeedbackManager);
- mFeedbackManager = new AudioAndHapticFeedbackManager(this, mSettingsValues);
- final IntentFilter ringerModeFilter = new IntentFilter();
- ringerModeFilter.addAction(AudioManager.RINGER_MODE_CHANGED_ACTION);
- registerReceiver(mFeedbackManager, ringerModeFilter);
- }
-
// Has to be package-visible for unit tests
/* package */ void loadSettings() {
if (null == mPrefs) mPrefs = PreferenceManager.getDefaultSharedPreferences(this);
mSettingsValues = new SettingsValues(mPrefs, this, mSubtypeSwitcher.getInputLocaleStr());
- renewFeedbackReceiver();
+ mFeedbackManager = new AudioAndHapticFeedbackManager(this, mSettingsValues);
resetContactsDictionary(null == mSuggest ? null : mSuggest.getContactsDictionary());
}
@@ -648,7 +642,6 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
mSuggest = null;
}
unregisterReceiver(mReceiver);
- unregisterReceiver(mFeedbackManager);
unregisterReceiver(mDictionaryPackInstallReceiver);
mVoiceProxy.destroy();
LatinImeLogger.commit();
@@ -987,8 +980,11 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
return;
}
+ final List<CharSequence> applicationSuggestedWords =
+ SuggestedWords.Builder.getFromApplicationSpecifiedCompletions(
+ applicationSpecifiedCompletions);
SuggestedWords.Builder builder = new SuggestedWords.Builder()
- .setApplicationSpecifiedCompletions(applicationSpecifiedCompletions)
+ .addWords(applicationSuggestedWords, null)
.setTypedWordValid(false)
.setHasMinimalSuggestion(false);
// When in fullscreen mode, show completions generated by the application
@@ -1292,7 +1288,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
}
private void handleLanguageSwitchKey() {
- final boolean includesOtherImes = !mSettingsValues.mIncludesOtherImesInLanguageSwitchList;
+ final boolean includesOtherImes = mSettingsValues.mIncludesOtherImesInLanguageSwitchList;
final IBinder token = getWindow().getWindow().getAttributes().token;
if (mShouldSwitchToLastSubtype) {
final InputMethodSubtypeCompatWrapper lastSubtype = mImm.getLastInputMethodSubtype();
@@ -1824,70 +1820,36 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
} else {
prevWord = EditingUtils.getPreviousWord(ic, mSettingsValues.mWordSeparators);
}
+
+ final CharSequence typedWord = mWordComposer.getTypedWord();
// getSuggestedWordBuilder handles gracefully a null value of prevWord
final SuggestedWords.Builder builder = mSuggest.getSuggestedWordBuilder(mWordComposer,
prevWord, mKeyboardSwitcher.getKeyboard().getProximityInfo(), mCorrectionMode);
- boolean autoCorrectionAvailable = !mInputAttributes.mInputTypeNoAutoCorrect
- && mSuggest.hasAutoCorrection();
- final CharSequence typedWord = mWordComposer.getTypedWord();
- // Here, we want to promote a whitelisted word if exists.
- // TODO: Change this scheme - a boolean is not enough. A whitelisted word may be "valid"
- // but still autocorrected from - in the case the whitelist only capitalizes the word.
- // The whitelist should be case-insensitive, so it's not possible to be consistent with
- // a boolean flag. Right now this is handled with a slight hack in
- // WhitelistDictionary#shouldForciblyAutoCorrectFrom.
- final int quotesCount = mWordComposer.trailingSingleQuotesCount();
- final boolean allowsToBeAutoCorrected = AutoCorrection.allowsToBeAutoCorrected(
- mSuggest.getUnigramDictionaries(),
- // If the typed string ends with a single quote, for dictionary lookup purposes
- // we behave as if the single quote was not here. Here, we are looking up the
- // typed string in the dictionary (to avoid autocorrecting from an existing
- // word, so for consistency this lookup should be made WITHOUT the trailing
- // single quote.
- quotesCount > 0
- ? typedWord.subSequence(0, typedWord.length() - quotesCount) : typedWord,
- preferCapitalization());
- if (mCorrectionMode == Suggest.CORRECTION_FULL
- || mCorrectionMode == Suggest.CORRECTION_FULL_BIGRAM) {
- autoCorrectionAvailable |= (!allowsToBeAutoCorrected);
- }
- // Don't auto-correct words with multiple capital letter
- autoCorrectionAvailable &= !mWordComposer.isMostlyCaps();
-
// Basically, we update the suggestion strip only when suggestion count > 1. However,
// there is an exception: We update the suggestion strip whenever typed word's length
// is 1 or typed word is found in dictionary, regardless of suggestion count. Actually,
// in most cases, suggestion count is 1 when typed word's length is 1, but we do always
// need to clear the previous state when the user starts typing a word (i.e. typed word's
// length == 1).
- if (typedWord != null) {
- if (builder.size() > 1 || typedWord.length() == 1 || (!allowsToBeAutoCorrected)
- || mSuggestionsView.isShowingAddToDictionaryHint()) {
- builder.setTypedWordValid(!allowsToBeAutoCorrected).setHasMinimalSuggestion(
- autoCorrectionAvailable);
- } else {
- SuggestedWords previousSuggestions = mSuggestionsView.getSuggestions();
- if (previousSuggestions == mSettingsValues.mSuggestPuncList) {
- if (builder.size() == 0) {
- return;
- }
- previousSuggestions = SuggestedWords.EMPTY;
- }
- builder.addTypedWordAndPreviousSuggestions(typedWord, previousSuggestions);
+ if (builder.size() > 1 || typedWord.length() == 1 || !builder.allowsToBeAutoCorrected()
+ || mSuggestionsView.isShowingAddToDictionaryHint()) {
+ showSuggestions(builder.build(), typedWord);
+ } else {
+ SuggestedWords previousSuggestions = mSuggestionsView.getSuggestions();
+ if (previousSuggestions == mSettingsValues.mSuggestPuncList) {
+ previousSuggestions = SuggestedWords.EMPTY;
}
+ final SuggestedWords.Builder obsoleteSuggestionsBuilder = new SuggestedWords.Builder()
+ .addTypedWordAndPreviousSuggestions(typedWord, previousSuggestions);
+ showSuggestions(obsoleteSuggestionsBuilder.build(), typedWord);
}
- if (Suggest.shouldBlockAutoCorrectionBySafetyNet(builder, mSuggest)) {
- builder.setShouldBlockAutoCorrectionBySafetyNet();
- }
- showSuggestions(builder.build(), typedWord);
}
public void showSuggestions(final SuggestedWords suggestedWords, final CharSequence typedWord) {
final CharSequence autoCorrection;
if (suggestedWords.size() > 0) {
- if (!suggestedWords.mShouldBlockAutoCorrectionBySafetyNet
- && suggestedWords.hasAutoCorrectionWord()) {
+ if (suggestedWords.hasAutoCorrectionWord()) {
autoCorrection = suggestedWords.getWord(1);
} else {
autoCorrection = typedWord;
@@ -2051,7 +2013,6 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
separatorCode);
}
- private static final WordComposer sEmptyWordComposer = new WordComposer();
public void updateBigramPredictions() {
if (mSuggest == null || !isSuggestionsRequested())
return;
@@ -2061,12 +2022,20 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
return;
}
- final CharSequence prevWord = EditingUtils.getThisWord(getCurrentInputConnection(),
- mSettingsValues.mWordSeparators);
- SuggestedWords.Builder builder = mSuggest.getSuggestedWordBuilder(sEmptyWordComposer,
- prevWord, mKeyboardSwitcher.getKeyboard().getProximityInfo(), mCorrectionMode);
+ final SuggestedWords.Builder builder;
+ if (mCorrectionMode == Suggest.CORRECTION_FULL_BIGRAM) {
+ final CharSequence prevWord = EditingUtils.getThisWord(getCurrentInputConnection(),
+ mSettingsValues.mWordSeparators);
+ if (!TextUtils.isEmpty(prevWord)) {
+ builder = mSuggest.getBigramPredictionWordBuilder(prevWord);
+ } else {
+ builder = null;
+ }
+ } else {
+ builder = null;
+ }
- if (builder.size() > 0) {
+ if (null != builder && builder.size() > 0) {
// Explicitly supply an empty typed word (the no-second-arg version of
// showSuggestions will retrieve the word near the cursor, we don't want that here)
showSuggestions(builder.build(), "");
@@ -2356,6 +2325,8 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
final String action = intent.getAction();
if (action.equals(ConnectivityManager.CONNECTIVITY_ACTION)) {
mSubtypeSwitcher.onNetworkStateChanged(intent);
+ } else if (action.equals(AudioManager.RINGER_MODE_CHANGED_ACTION)) {
+ mFeedbackManager.onRingerModeChanged();
}
}
};
diff --git a/java/src/com/android/inputmethod/latin/Suggest.java b/java/src/com/android/inputmethod/latin/Suggest.java
index 671fb905d..f17c1d95a 100644
--- a/java/src/com/android/inputmethod/latin/Suggest.java
+++ b/java/src/com/android/inputmethod/latin/Suggest.java
@@ -83,8 +83,6 @@ public class Suggest implements Dictionary.WordCallback {
private static final boolean DBG = LatinImeLogger.sDBG;
- private AutoCorrection mAutoCorrection;
-
private Dictionary mMainDict;
private ContactsDictionary mContactsDict;
private WhitelistDictionary mWhiteListDictionary;
@@ -124,7 +122,6 @@ public class Suggest implements Dictionary.WordCallback {
private void initWhitelistAndAutocorrectAndPool(final Context context, final Locale locale) {
mWhiteListDictionary = new WhitelistDictionary(context, locale);
addOrReplaceDictionary(mUnigramDictionaries, DICT_KEY_WHITELIST, mWhiteListDictionary);
- mAutoCorrection = new AutoCorrection();
StringBuilderPool.ensureCapacity(mPrefMaxSuggestions, getApproxMaxWordLength());
}
@@ -219,10 +216,6 @@ public class Suggest implements Dictionary.WordCallback {
mAutoCorrectionThreshold = threshold;
}
- public boolean isAggressiveAutoCorrectionMode() {
- return (mAutoCorrectionThreshold == 0);
- }
-
/**
* Number of suggestions to generate from the input key sequence. This has
* to be a number between 1 and 100 (inclusive).
@@ -240,20 +233,6 @@ public class Suggest implements Dictionary.WordCallback {
StringBuilderPool.ensureCapacity(mPrefMaxSuggestions, getApproxMaxWordLength());
}
- /**
- * Returns a object which represents suggested words that match the list of character codes
- * passed in. This object contents will be overwritten the next time this function is called.
- * @param wordComposer contains what is currently being typed
- * @param prevWordForBigram previous word (used only for bigram)
- * @return suggested words object.
- */
- public SuggestedWords getSuggestions(final WordComposer wordComposer,
- final CharSequence prevWordForBigram, final ProximityInfo proximityInfo,
- final int correctionMode) {
- return getSuggestedWordBuilder(wordComposer, prevWordForBigram,
- proximityInfo, correctionMode).build();
- }
-
private CharSequence capitalizeWord(boolean all, boolean first, CharSequence word) {
if (TextUtils.isEmpty(word) || !(all || first)) return word;
final int wordLength = word.length();
@@ -281,12 +260,47 @@ public class Suggest implements Dictionary.WordCallback {
mSuggestions.add(sb);
}
+ private static final WordComposer sEmptyWordComposer = new WordComposer();
+ public SuggestedWords.Builder getBigramPredictionWordBuilder(CharSequence prevWordForBigram) {
+ LatinImeLogger.onStartSuggestion(prevWordForBigram);
+ mIsFirstCharCapitalized = false;
+ mIsAllUpperCase = false;
+ mTrailingSingleQuotesCount = 0;
+ collectGarbage(mSuggestions, mPrefMaxSuggestions);
+ Arrays.fill(mScores, 0);
+
+ // Treating USER_TYPED as UNIGRAM suggestion for logging now.
+ LatinImeLogger.onAddSuggestedWord("", Suggest.DIC_USER_TYPED, Dictionary.UNIGRAM);
+ mConsideredWord = "";
+
+ Arrays.fill(mBigramScores, 0);
+ collectGarbage(mBigramSuggestions, PREF_MAX_BIGRAMS);
+
+ CharSequence lowerPrevWord = prevWordForBigram.toString().toLowerCase();
+ if (mMainDict != null && mMainDict.isValidWord(lowerPrevWord)) {
+ prevWordForBigram = lowerPrevWord;
+ }
+ for (final Dictionary dictionary : mBigramDictionaries.values()) {
+ dictionary.getBigrams(sEmptyWordComposer, prevWordForBigram, this);
+ }
+ // Nothing entered: return all bigrams for the previous word
+ int insertCount = Math.min(mBigramSuggestions.size(), mPrefMaxSuggestions);
+ for (int i = 0; i < insertCount; ++i) {
+ addBigramToSuggestions(mBigramSuggestions.get(i));
+ }
+
+ StringUtils.removeDupes(mSuggestions);
+
+ return new SuggestedWords.Builder().addWords(mSuggestions, null)
+ .setAllowsToBeAutoCorrected(false)
+ .setHasAutoCorrection(false);
+ }
+
// TODO: cleanup dictionaries looking up and suggestions building with SuggestedWords.Builder
public SuggestedWords.Builder getSuggestedWordBuilder(
final WordComposer wordComposer, CharSequence prevWordForBigram,
final ProximityInfo proximityInfo, final int correctionMode) {
LatinImeLogger.onStartSuggestion(prevWordForBigram);
- mAutoCorrection.init();
mIsFirstCharCapitalized = wordComposer.isFirstCharCapitalized();
mIsAllUpperCase = wordComposer.isAllUpperCase();
mTrailingSingleQuotesCount = wordComposer.trailingSingleQuotesCount();
@@ -297,13 +311,19 @@ public class Suggest implements Dictionary.WordCallback {
final String consideredWord = mTrailingSingleQuotesCount > 0
? typedWord.substring(0, typedWord.length() - mTrailingSingleQuotesCount)
: typedWord;
- if (typedWord != null) {
- // Treating USER_TYPED as UNIGRAM suggestion for logging now.
- LatinImeLogger.onAddSuggestedWord(typedWord, Suggest.DIC_USER_TYPED,
- Dictionary.UNIGRAM);
- }
+ // Treating USER_TYPED as UNIGRAM suggestion for logging now.
+ LatinImeLogger.onAddSuggestedWord(typedWord, Suggest.DIC_USER_TYPED,
+ Dictionary.UNIGRAM);
mConsideredWord = consideredWord;
+ // TODO: Change this scheme - a boolean is not enough. A whitelisted word may be "valid"
+ // but still autocorrected from - in the case the whitelist only capitalizes the word.
+ // The whitelist should be case-insensitive, so it's not possible to be consistent with
+ // a boolean flag. Right now this is handled with a slight hack in
+ // WhitelistDictionary#shouldForciblyAutoCorrectFrom.
+ final boolean allowsToBeAutoCorrected = AutoCorrection.allowsToBeAutoCorrected(
+ getUnigramDictionaries(), consideredWord, wordComposer.isFirstCharCapitalized());
+
if (wordComposer.size() <= 1 && (correctionMode == CORRECTION_FULL_BIGRAM)) {
// At first character typed, search only the bigrams
Arrays.fill(mBigramScores, 0);
@@ -360,15 +380,21 @@ public class Suggest implements Dictionary.WordCallback {
}
}
}
- final String consideredWordString =
- consideredWord == null ? null : consideredWord.toString();
CharSequence whitelistedWord = capitalizeWord(mIsAllUpperCase, mIsFirstCharCapitalized,
- mWhiteListDictionary.getWhitelistedWord(consideredWordString));
-
- mAutoCorrection.updateAutoCorrectionStatus(mUnigramDictionaries, wordComposer,
- mSuggestions, mScores, consideredWord, mAutoCorrectionThreshold, correctionMode,
- whitelistedWord);
+ mWhiteListDictionary.getWhitelistedWord(consideredWord));
+
+ final boolean hasAutoCorrection;
+ if (CORRECTION_FULL == correctionMode
+ || CORRECTION_FULL_BIGRAM == correctionMode) {
+ final CharSequence autoCorrection =
+ AutoCorrection.computeAutoCorrectionWord(mUnigramDictionaries, wordComposer,
+ mSuggestions, mScores, consideredWord, mAutoCorrectionThreshold,
+ whitelistedWord);
+ hasAutoCorrection = (null != autoCorrection);
+ } else {
+ hasAutoCorrection = false;
+ }
if (whitelistedWord != null) {
if (mTrailingSingleQuotesCount > 0) {
@@ -382,38 +408,66 @@ public class Suggest implements Dictionary.WordCallback {
}
}
- if (typedWord != null) {
- mSuggestions.add(0, typedWord.toString());
- }
+ mSuggestions.add(0, typedWord);
StringUtils.removeDupes(mSuggestions);
+ final SuggestedWords.Builder builder;
if (DBG) {
- double normalizedScore = mAutoCorrection.getNormalizedScore();
+ // TODO: this doesn't take into account the fact that removing dupes from mSuggestions
+ // may have made mScores[] and mSuggestions out of sync.
+ final CharSequence autoCorrectionSuggestion = mSuggestions.get(0);
+ final int autoCorrectionSuggestionScore = mScores[0];
+ double normalizedScore = BinaryDictionary.calcNormalizedScore(
+ typedWord, autoCorrectionSuggestion.toString(),
+ autoCorrectionSuggestionScore);
ArrayList<SuggestedWords.SuggestedWordInfo> scoreInfoList =
new ArrayList<SuggestedWords.SuggestedWordInfo>();
- scoreInfoList.add(new SuggestedWords.SuggestedWordInfo("+", false));
- for (int i = 0; i < mScores.length; ++i) {
+ scoreInfoList.add(new SuggestedWords.SuggestedWordInfo(autoCorrectionSuggestion, "+",
+ false));
+ final int suggestionsSize = mSuggestions.size();
+ // Note: i here is the index in mScores[], but the index in mSuggestions is one more
+ // than i because we added the typed word to mSuggestions without touching mScores.
+ for (int i = 0; i < mScores.length && i < suggestionsSize - 1; ++i) {
if (normalizedScore > 0) {
final String scoreThreshold = String.format("%d (%4.2f)", mScores[i],
normalizedScore);
scoreInfoList.add(
- new SuggestedWords.SuggestedWordInfo(scoreThreshold, false));
+ new SuggestedWords.SuggestedWordInfo(mSuggestions.get(i + 1),
+ scoreThreshold, false));
normalizedScore = 0.0;
} else {
final String score = Integer.toString(mScores[i]);
- scoreInfoList.add(new SuggestedWords.SuggestedWordInfo(score, false));
+ scoreInfoList.add(new SuggestedWords.SuggestedWordInfo(mSuggestions.get(i + 1),
+ score, false));
}
}
- for (int i = mScores.length; i < mSuggestions.size(); ++i) {
- scoreInfoList.add(new SuggestedWords.SuggestedWordInfo("--", false));
+ for (int i = mScores.length; i < suggestionsSize; ++i) {
+ scoreInfoList.add(new SuggestedWords.SuggestedWordInfo(mSuggestions.get(i),
+ "--", false));
}
- return new SuggestedWords.Builder().addWords(mSuggestions, scoreInfoList);
+ builder = new SuggestedWords.Builder().addWords(mSuggestions, scoreInfoList)
+ .setAllowsToBeAutoCorrected(allowsToBeAutoCorrected)
+ .setHasAutoCorrection(hasAutoCorrection);
+ } else {
+ builder = new SuggestedWords.Builder().addWords(mSuggestions, null)
+ .setAllowsToBeAutoCorrected(allowsToBeAutoCorrected)
+ .setHasAutoCorrection(hasAutoCorrection);
}
- return new SuggestedWords.Builder().addWords(mSuggestions, null);
- }
- public boolean hasAutoCorrection() {
- return mAutoCorrection.hasAutoCorrection();
+ boolean autoCorrectionAvailable = hasAutoCorrection;
+ if (correctionMode == Suggest.CORRECTION_FULL
+ || correctionMode == Suggest.CORRECTION_FULL_BIGRAM) {
+ autoCorrectionAvailable |= !allowsToBeAutoCorrected;
+ }
+ // Don't auto-correct words with multiple capital letter
+ autoCorrectionAvailable &= !wordComposer.isMostlyCaps();
+ builder.setTypedWordValid(!allowsToBeAutoCorrected).setHasMinimalSuggestion(
+ autoCorrectionAvailable);
+ if (allowsToBeAutoCorrected && builder.size() > 1 && mAutoCorrectionThreshold > 0
+ && Suggest.shouldBlockAutoCorrectionBySafetyNet(typedWord, builder.getWord(1))) {
+ builder.setShouldBlockAutoCorrectionBySafetyNet();
+ }
+ return builder;
}
@Override
@@ -563,37 +617,28 @@ public class Suggest implements Dictionary.WordCallback {
// TODO: Resolve the inconsistencies between the native auto correction algorithms and
// this safety net
- public static boolean shouldBlockAutoCorrectionBySafetyNet(
- SuggestedWords.Builder suggestedWordsBuilder, Suggest suggest) {
+ public static boolean shouldBlockAutoCorrectionBySafetyNet(final String typedWord,
+ final CharSequence suggestion) {
// Safety net for auto correction.
- // Actually if we hit this safety net, it's actually a bug.
- if (suggestedWordsBuilder.size() <= 1 || suggestedWordsBuilder.isTypedWordValid()) {
- return false;
- }
+ // Actually if we hit this safety net, it's a bug.
// If user selected aggressive auto correction mode, there is no need to use the safety
// net.
- if (suggest.isAggressiveAutoCorrectionMode()) {
- return false;
- }
- final CharSequence typedWord = suggestedWordsBuilder.getWord(0);
// If the length of typed word is less than MINIMUM_SAFETY_NET_CHAR_LENGTH,
// we should not use net because relatively edit distance can be big.
- if (typedWord.length() < Suggest.MINIMUM_SAFETY_NET_CHAR_LENGTH) {
+ final int typedWordLength = typedWord.length();
+ if (typedWordLength < Suggest.MINIMUM_SAFETY_NET_CHAR_LENGTH) {
return false;
}
- final CharSequence suggestionWord = suggestedWordsBuilder.getWord(1);
- final int typedWordLength = typedWord.length();
final int maxEditDistanceOfNativeDictionary =
(typedWordLength < 5 ? 2 : typedWordLength / 2) + 1;
- final int distance = BinaryDictionary.editDistance(
- typedWord.toString(), suggestionWord.toString());
+ final int distance = BinaryDictionary.editDistance(typedWord, suggestion.toString());
if (DBG) {
Log.d(TAG, "Autocorrected edit distance = " + distance
+ ", " + maxEditDistanceOfNativeDictionary);
}
if (distance > maxEditDistanceOfNativeDictionary) {
if (DBG) {
- Log.e(TAG, "Safety net: before = " + typedWord + ", after = " + suggestionWord);
+ Log.e(TAG, "Safety net: before = " + typedWord + ", after = " + suggestion);
Log.e(TAG, "(Error) The edit distance of this correction exceeds limit. "
+ "Turning off auto-correction.");
}
diff --git a/java/src/com/android/inputmethod/latin/SuggestedWords.java b/java/src/com/android/inputmethod/latin/SuggestedWords.java
index aad975e46..4a51e796d 100644
--- a/java/src/com/android/inputmethod/latin/SuggestedWords.java
+++ b/java/src/com/android/inputmethod/latin/SuggestedWords.java
@@ -20,44 +20,36 @@ import android.text.TextUtils;
import android.view.inputmethod.CompletionInfo;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
public class SuggestedWords {
- public static final SuggestedWords EMPTY = new SuggestedWords(null, false, false, false, false,
- null);
+ public static final SuggestedWords EMPTY = new SuggestedWords(false, false, false, false,
+ Collections.<SuggestedWordInfo>emptyList());
- private final List<CharSequence> mWords;
public final boolean mTypedWordValid;
public final boolean mHasAutoCorrectionCandidate;
public final boolean mIsPunctuationSuggestions;
- public final boolean mShouldBlockAutoCorrectionBySafetyNet;
private final List<SuggestedWordInfo> mSuggestedWordInfoList;
- SuggestedWords(List<CharSequence> words, boolean typedWordValid,
+ SuggestedWords(boolean typedWordValid,
boolean hasAutoCorrectionCandidate, boolean isPunctuationSuggestions,
boolean shouldBlockAutoCorrectionBySafetyNet,
List<SuggestedWordInfo> suggestedWordInfoList) {
- if (words != null) {
- mWords = words;
- } else {
- mWords = Collections.emptyList();
- }
mTypedWordValid = typedWordValid;
- mHasAutoCorrectionCandidate = hasAutoCorrectionCandidate;
+ mHasAutoCorrectionCandidate = hasAutoCorrectionCandidate
+ && !shouldBlockAutoCorrectionBySafetyNet;
mIsPunctuationSuggestions = isPunctuationSuggestions;
- mShouldBlockAutoCorrectionBySafetyNet = shouldBlockAutoCorrectionBySafetyNet;
mSuggestedWordInfoList = suggestedWordInfoList;
}
public int size() {
- return mWords.size();
+ return mSuggestedWordInfoList.size();
}
public CharSequence getWord(int pos) {
- return mWords.get(pos);
+ return mSuggestedWordInfoList.get(pos).mWord;
}
public SuggestedWordInfo getInfo(int pos) {
@@ -69,8 +61,7 @@ public class SuggestedWords {
}
public boolean willAutoCorrect() {
- return !mTypedWordValid && mHasAutoCorrectionCandidate
- && !mShouldBlockAutoCorrectionBySafetyNet;
+ return !mTypedWordValid && mHasAutoCorrectionCandidate;
}
@Override
@@ -79,17 +70,16 @@ public class SuggestedWords {
return "SuggestedWords:"
+ " mTypedWordValid=" + mTypedWordValid
+ " mHasAutoCorrectionCandidate=" + mHasAutoCorrectionCandidate
- + " mIsPunctuationSuggestions=" + mIsPunctuationSuggestions
- + " mShouldBlockAutoCorrectionBySafetyNet=" + mShouldBlockAutoCorrectionBySafetyNet
- + " mWords=" + Arrays.toString(mWords.toArray());
+ + " mIsPunctuationSuggestions=" + mIsPunctuationSuggestions;
}
public static class Builder {
- private List<CharSequence> mWords = new ArrayList<CharSequence>();
private boolean mTypedWordValid;
private boolean mHasMinimalSuggestion;
private boolean mIsPunctuationSuggestions;
private boolean mShouldBlockAutoCorrectionBySafetyNet;
+ private boolean mAllowsToBeAutoCorrected;
+ private boolean mHasAutoCorrection;
private List<SuggestedWordInfo> mSuggestedWordInfoList =
new ArrayList<SuggestedWordInfo>();
@@ -101,14 +91,15 @@ public class SuggestedWords {
List<SuggestedWordInfo> suggestedWordInfoList) {
final int N = words.size();
for (int i = 0; i < N; ++i) {
+ final CharSequence word = words.get(i);
SuggestedWordInfo suggestedWordInfo = null;
if (suggestedWordInfoList != null) {
suggestedWordInfo = suggestedWordInfoList.get(i);
}
if (suggestedWordInfo == null) {
- suggestedWordInfo = new SuggestedWordInfo();
+ suggestedWordInfo = new SuggestedWordInfo(word);
}
- addWord(words.get(i), suggestedWordInfo);
+ addWord(word, suggestedWordInfo);
}
return this;
}
@@ -119,24 +110,27 @@ public class SuggestedWords {
public Builder addWord(CharSequence word, CharSequence debugString,
boolean isPreviousSuggestedWord) {
- SuggestedWordInfo info = new SuggestedWordInfo(debugString, isPreviousSuggestedWord);
+ SuggestedWordInfo info = new SuggestedWordInfo(word, debugString,
+ isPreviousSuggestedWord);
return addWord(word, info);
}
- private Builder addWord(CharSequence word, SuggestedWordInfo suggestedWordInfo) {
- if (!TextUtils.isEmpty(word)) {
- mWords.add(word);
+ /* package for tests */
+ Builder addWord(CharSequence word, SuggestedWordInfo suggestedWordInfo) {
+ if (!TextUtils.isEmpty(suggestedWordInfo.mWord)) {
// It's okay if suggestedWordInfo is null since it's checked where it's used.
mSuggestedWordInfoList.add(suggestedWordInfo);
}
return this;
}
- public Builder setApplicationSpecifiedCompletions(CompletionInfo[] infos) {
+ public static List<CharSequence> getFromApplicationSpecifiedCompletions(
+ final CompletionInfo[] infos) {
+ final ArrayList<CharSequence> result = new ArrayList<CharSequence>();
for (CompletionInfo info : infos) {
- if (null != info) addWord(info.getText());
+ if (null != info) result.add(info.getText());
}
- return this;
+ return result;
}
public Builder setTypedWordValid(boolean typedWordValid) {
@@ -159,11 +153,20 @@ public class SuggestedWords {
return this;
}
+ public Builder setAllowsToBeAutoCorrected(final boolean allowsToBeAutoCorrected) {
+ mAllowsToBeAutoCorrected = allowsToBeAutoCorrected;
+ return this;
+ }
+
+ public Builder setHasAutoCorrection(final boolean hasAutoCorrection) {
+ mHasAutoCorrection = hasAutoCorrection;
+ return this;
+ }
+
// Should get rid of the first one (what the user typed previously) from suggestions
// and replace it with what the user currently typed.
public Builder addTypedWordAndPreviousSuggestions(CharSequence typedWord,
SuggestedWords previousSuggestions) {
- mWords.clear();
mSuggestedWordInfoList.clear();
final HashSet<String> alreadySeen = new HashSet<String>();
addWord(typedWord, null, false);
@@ -183,21 +186,25 @@ public class SuggestedWords {
}
public SuggestedWords build() {
- return new SuggestedWords(mWords, mTypedWordValid, mHasMinimalSuggestion,
+ return new SuggestedWords(mTypedWordValid, mHasMinimalSuggestion,
mIsPunctuationSuggestions, mShouldBlockAutoCorrectionBySafetyNet,
mSuggestedWordInfoList);
}
public int size() {
- return mWords.size();
+ return mSuggestedWordInfoList.size();
}
public CharSequence getWord(int pos) {
- return mWords.get(pos);
+ return mSuggestedWordInfoList.get(pos).mWord;
+ }
+
+ public boolean allowsToBeAutoCorrected() {
+ return mAllowsToBeAutoCorrected;
}
- public boolean isTypedWordValid() {
- return mTypedWordValid;
+ public boolean hasAutoCorrection() {
+ return mHasAutoCorrection;
}
@Override
@@ -208,21 +215,24 @@ public class SuggestedWords {
+ " mHasMinimalSuggestion=" + mHasMinimalSuggestion
+ " mIsPunctuationSuggestions=" + mIsPunctuationSuggestions
+ " mShouldBlockAutoCorrectionBySafetyNet="
- + mShouldBlockAutoCorrectionBySafetyNet
- + " mWords=" + Arrays.toString(mWords.toArray());
+ + mShouldBlockAutoCorrectionBySafetyNet;
}
}
public static class SuggestedWordInfo {
+ private final CharSequence mWord;
private final CharSequence mDebugString;
private final boolean mPreviousSuggestedWord;
- public SuggestedWordInfo() {
+ public SuggestedWordInfo(final CharSequence word) {
+ mWord = word;
mDebugString = "";
mPreviousSuggestedWord = false;
}
- public SuggestedWordInfo(CharSequence debugString, boolean previousSuggestedWord) {
+ public SuggestedWordInfo(final CharSequence word, final CharSequence debugString,
+ final boolean previousSuggestedWord) {
+ mWord = word;
mDebugString = debugString;
mPreviousSuggestedWord = previousSuggestedWord;
}
diff --git a/java/src/com/android/inputmethod/latin/suggestions/SuggestionsView.java b/java/src/com/android/inputmethod/latin/suggestions/SuggestionsView.java
index 075fb68ee..812376de0 100644
--- a/java/src/com/android/inputmethod/latin/suggestions/SuggestionsView.java
+++ b/java/src/com/android/inputmethod/latin/suggestions/SuggestionsView.java
@@ -60,6 +60,7 @@ import com.android.inputmethod.keyboard.PointerTracker;
import com.android.inputmethod.latin.LatinImeLogger;
import com.android.inputmethod.latin.R;
import com.android.inputmethod.latin.StaticInnerHandlerWrapper;
+import com.android.inputmethod.latin.Suggest;
import com.android.inputmethod.latin.SuggestedWords;
import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
@@ -328,9 +329,12 @@ public class SuggestionsView extends RelativeLayout implements OnClickListener,
} else {
color = mColorTypedWord;
}
- if (LatinImeLogger.sDBG) {
+ if (LatinImeLogger.sDBG && suggestedWords.size() > 1) {
+ // If we auto-correct, then the autocorrection is in slot 0 and the typed word
+ // is in slot 1.
if (index == mCenterSuggestionIndex && suggestedWords.mHasAutoCorrectionCandidate
- && suggestedWords.mShouldBlockAutoCorrectionBySafetyNet) {
+ && Suggest.shouldBlockAutoCorrectionBySafetyNet(
+ suggestedWords.getWord(1).toString(), suggestedWords.getWord(0))) {
return 0xFFFF0000;
}
}