aboutsummaryrefslogtreecommitdiffstats
path: root/java/src/com/android/inputmethod/latin
diff options
context:
space:
mode:
Diffstat (limited to 'java/src/com/android/inputmethod/latin')
-rw-r--r--java/src/com/android/inputmethod/latin/BinaryDictionary.java4
-rw-r--r--java/src/com/android/inputmethod/latin/DictionaryFacilitatorForSuggest.java10
-rw-r--r--java/src/com/android/inputmethod/latin/LatinIME.java17
-rw-r--r--java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java2
-rw-r--r--java/src/com/android/inputmethod/latin/settings/SettingsValues.java3
-rw-r--r--java/src/com/android/inputmethod/latin/suggestions/SuggestionStripLayoutHelper.java5
-rw-r--r--java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java6
-rw-r--r--java/src/com/android/inputmethod/latin/utils/DistracterFilter.java94
-rw-r--r--java/src/com/android/inputmethod/latin/utils/LanguageModelParam.java3
9 files changed, 115 insertions, 29 deletions
diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionary.java b/java/src/com/android/inputmethod/latin/BinaryDictionary.java
index 94a1e3658..999508e92 100644
--- a/java/src/com/android/inputmethod/latin/BinaryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/BinaryDictionary.java
@@ -414,8 +414,8 @@ public final class BinaryDictionary extends Dictionary {
public WordProperty mWordProperty;
public int mNextToken;
- public GetNextWordPropertyResult(final WordProperty wordPreperty, final int nextToken) {
- mWordProperty = wordPreperty;
+ public GetNextWordPropertyResult(final WordProperty wordProperty, final int nextToken) {
+ mWordProperty = wordProperty;
mNextToken = nextToken;
}
}
diff --git a/java/src/com/android/inputmethod/latin/DictionaryFacilitatorForSuggest.java b/java/src/com/android/inputmethod/latin/DictionaryFacilitatorForSuggest.java
index 3babb4195..e0220e137 100644
--- a/java/src/com/android/inputmethod/latin/DictionaryFacilitatorForSuggest.java
+++ b/java/src/com/android/inputmethod/latin/DictionaryFacilitatorForSuggest.java
@@ -370,7 +370,8 @@ public class DictionaryFacilitatorForSuggest {
}
public void addToUserHistory(final String suggestion, final boolean wasAutoCapitalized,
- final String previousWord, final int timeStampInSeconds) {
+ final String previousWord, final int timeStampInSeconds,
+ final boolean blockPotentiallyOffensive) {
final Dictionaries dictionaries = mDictionaries;
final String[] words = suggestion.split(Constants.WORD_SEPARATOR);
for (int i = 0; i < words.length; i++) {
@@ -378,19 +379,20 @@ public class DictionaryFacilitatorForSuggest {
final String prevWord = (i == 0) ? previousWord : words[i - 1];
final boolean wasCurrentWordAutoCapitalized = (i == 0) ? wasAutoCapitalized : false;
addWordToUserHistory(dictionaries, prevWord, currentWord,
- wasCurrentWordAutoCapitalized, timeStampInSeconds);
+ wasCurrentWordAutoCapitalized, timeStampInSeconds, blockPotentiallyOffensive);
}
}
private void addWordToUserHistory(final Dictionaries dictionaries, final String prevWord,
- final String word, final boolean wasAutoCapitalized, final int timeStampInSeconds) {
+ final String word, final boolean wasAutoCapitalized, final int timeStampInSeconds,
+ final boolean blockPotentiallyOffensive) {
final ExpandableBinaryDictionary userHistoryDictionary =
dictionaries.getSubDict(Dictionary.TYPE_USER_HISTORY);
if (userHistoryDictionary == null) {
return;
}
final int maxFreq = getMaxFrequency(word);
- if (maxFreq == 0) {
+ if (maxFreq == 0 && blockPotentiallyOffensive) {
return;
}
final String lowerCasedWord = word.toLowerCase(dictionaries.mLocale);
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index 7dc566a14..8a2ed1088 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -540,18 +540,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
refreshPersonalizationDictionarySession();
}
- private DistracterFilter createDistracterFilter() {
- final MainKeyboardView mainKeyboardView = mKeyboardSwitcher.getMainKeyboardView();
- // TODO: Create Keyboard when mainKeyboardView is null.
- // TODO: Figure out the most reasonable keyboard for the filter. Refer to the
- // spellchecker's logic.
- final Keyboard keyboard = (mainKeyboardView != null) ?
- mainKeyboardView.getKeyboard() : null;
- final DistracterFilter distracterFilter = new DistracterFilter(mInputLogic.mSuggest,
- keyboard);
- return distracterFilter;
- }
-
private void refreshPersonalizationDictionarySession() {
final DictionaryFacilitatorForSuggest dictionaryFacilitator =
mInputLogic.mSuggest.mDictionaryFacilitator;
@@ -1755,6 +1743,11 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
mInputLogic.mSuggest.mDictionaryFacilitator.clearPersonalizationDictionary();
}
+ @UsedForTesting
+ /* package for test */ DistracterFilter createDistracterFilter() {
+ return DistracterFilter.createDistracterFilter(mInputLogic.mSuggest, mKeyboardSwitcher);
+ }
+
public void dumpDictionaryForDebug(final String dictName) {
final DictionaryFacilitatorForSuggest dictionaryFacilitator =
mInputLogic.mSuggest.mDictionaryFacilitator;
diff --git a/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java b/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java
index 6a420748c..8b795b82f 100644
--- a/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java
+++ b/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java
@@ -1241,7 +1241,7 @@ public final class InputLogic {
final int timeStampInSeconds = (int)TimeUnit.MILLISECONDS.toSeconds(
System.currentTimeMillis());
mSuggest.mDictionaryFacilitator.addToUserHistory(suggestion, wasAutoCapitalized, prevWord,
- timeStampInSeconds);
+ timeStampInSeconds, settingsValues.mBlockPotentiallyOffensive);
}
public void performUpdateSuggestionStripSync(final SettingsValues settingsValues) {
diff --git a/java/src/com/android/inputmethod/latin/settings/SettingsValues.java b/java/src/com/android/inputmethod/latin/settings/SettingsValues.java
index dde50ccaf..de2eb951e 100644
--- a/java/src/com/android/inputmethod/latin/settings/SettingsValues.java
+++ b/java/src/com/android/inputmethod/latin/settings/SettingsValues.java
@@ -205,7 +205,8 @@ public final class SettingsValues {
}
public boolean isWordCodePoint(final int code) {
- return Character.isLetter(code) || isWordConnector(code);
+ return Character.isLetter(code) || isWordConnector(code)
+ || Character.COMBINING_SPACING_MARK == Character.getType(code);
}
public boolean isUsuallyPrecededBySpace(final int code) {
diff --git a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripLayoutHelper.java b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripLayoutHelper.java
index 8bfa63c3c..810bda758 100644
--- a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripLayoutHelper.java
+++ b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripLayoutHelper.java
@@ -381,6 +381,7 @@ final class SuggestionStripLayoutHelper {
}
// Disable this suggestion if the suggestion is null or empty.
+ // TODO: Fix disabled {@link TextView}'s content description.
wordView.setEnabled(!TextUtils.isEmpty(word));
final CharSequence text = getEllipsizedText(word, width, wordView.getPaint());
final float scaleX = getTextScaleX(word, width, wordView.getPaint());
@@ -424,7 +425,9 @@ final class SuggestionStripLayoutHelper {
final int countInStrip) {
// Clear all suggestions first
for (int positionInStrip = 0; positionInStrip < countInStrip; ++positionInStrip) {
- mWordViews.get(positionInStrip).setText(null);
+ final TextView wordView = mWordViews.get(positionInStrip);
+ wordView.setText(null);
+ wordView.setTag(null);
// Make this inactive for touches in {@link #layoutWord(int,int)}.
if (SuggestionStripView.DBG) {
mDebugInfoViews.get(positionInStrip).setText(null);
diff --git a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java
index d4f7f36da..619804afa 100644
--- a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java
+++ b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java
@@ -124,9 +124,9 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick
mImportantNoticeStrip.setVisibility(INVISIBLE);
}
- public void showImportantNoticeStrip() {
+ public void showImportantNoticeStrip(final boolean enableVoiceKey) {
mSuggestionsStrip.setVisibility(INVISIBLE);
- mVoiceKey.setVisibility(INVISIBLE);
+ mVoiceKey.setVisibility(enableVoiceKey ? VISIBLE : INVISIBLE);
mAddToDictionaryStrip.setVisibility(INVISIBLE);
mImportantNoticeStrip.setVisibility(VISIBLE);
}
@@ -274,7 +274,7 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick
dismissMoreSuggestionsPanel();
}
mLayoutHelper.layoutImportantNotice(mImportantNoticeStrip, importantNoticeTitle);
- mStripVisibilityGroup.showImportantNoticeStrip();
+ mStripVisibilityGroup.showImportantNoticeStrip(isVoiceKeyEnabled());
mImportantNoticeStrip.setOnClickListener(this);
return true;
}
diff --git a/java/src/com/android/inputmethod/latin/utils/DistracterFilter.java b/java/src/com/android/inputmethod/latin/utils/DistracterFilter.java
index 48e43d6ef..55cbf79b3 100644
--- a/java/src/com/android/inputmethod/latin/utils/DistracterFilter.java
+++ b/java/src/com/android/inputmethod/latin/utils/DistracterFilter.java
@@ -17,21 +17,35 @@
package com.android.inputmethod.latin.utils;
import com.android.inputmethod.keyboard.Keyboard;
+import com.android.inputmethod.keyboard.KeyboardSwitcher;
+import com.android.inputmethod.keyboard.MainKeyboardView;
+import com.android.inputmethod.latin.Constants;
import com.android.inputmethod.latin.Suggest;
+import com.android.inputmethod.latin.Suggest.OnGetSuggestedWordsCallback;
+import com.android.inputmethod.latin.SuggestedWords;
+import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
+import com.android.inputmethod.latin.WordComposer;
/**
- * This class is used to prevent distracters/misspellings being added to personalization
+ * This class is used to prevent distracters being added to personalization
* or user history dictionaries
*/
public class DistracterFilter {
private final Suggest mSuggest;
private final Keyboard mKeyboard;
+ // If the score of the top suggestion exceeds this value, the tested word (e.g.,
+ // an OOV, a misspelling, or an in-vocabulary word) would be considered as a distracter to
+ // words in dictionary. The greater the threshold is, the less likely the tested word would
+ // become a distracter, which means the tested word will be more likely to be added to
+ // the dictionary.
+ private static final float DISTRACTER_WORD_SCORE_THRESHOLD = 2.0f;
+
/**
* Create a DistracterFilter instance.
*
* @param suggest an instance of Suggest which will be used to obtain a list of suggestions
- * for a potential distracter/misspelling
+ * for a potential distracter
* @param keyboard the keyboard that is currently being used. This information is needed
* when calling mSuggest.getSuggestedWords(...) to obtain a list of suggestions.
*/
@@ -40,9 +54,79 @@ public class DistracterFilter {
mKeyboard = keyboard;
}
- public boolean isDistracterToWordsInDictionaries(final String prevWord,
- final String targetWord) {
- // TODO: to be implemented
+ public static DistracterFilter createDistracterFilter(final Suggest suggest,
+ final KeyboardSwitcher keyboardSwitcher) {
+ final MainKeyboardView mainKeyboardView = keyboardSwitcher.getMainKeyboardView();
+ // TODO: Create Keyboard when mainKeyboardView is null.
+ // TODO: Figure out the most reasonable keyboard for the filter. Refer to the
+ // spellchecker's logic.
+ final Keyboard keyboard = (mainKeyboardView != null) ?
+ mainKeyboardView.getKeyboard() : null;
+ final DistracterFilter distracterFilter = new DistracterFilter(suggest, keyboard);
+ return distracterFilter;
+ }
+
+ private static boolean suggestionExceedsDistracterThreshold(
+ final SuggestedWordInfo suggestion, final String consideredWord,
+ final float distracterThreshold) {
+ if (null != suggestion) {
+ final int suggestionScore = suggestion.mScore;
+ final float normalizedScore = BinaryDictionaryUtils.calcNormalizedScore(
+ consideredWord, suggestion.mWord, suggestionScore);
+ if (normalizedScore > distracterThreshold) {
+ return true;
+ }
+ }
return false;
}
+
+ /**
+ * Determine whether a word is a distracter to words in dictionaries.
+ *
+ * @param prevWord the previous word, or null if none.
+ * @param testedWord the word that will be tested to see whether it is a distracter to words
+ * in dictionaries.
+ * @return true if testedWord is a distracter, otherwise false.
+ */
+ public boolean isDistracterToWordsInDictionaries(final String prevWord,
+ final String testedWord) {
+ if (mSuggest == null) {
+ return false;
+ }
+
+ final WordComposer composer = new WordComposer();
+ final int[] codePoints = StringUtils.toCodePointArray(testedWord);
+ final int[] coordinates;
+ if (null == mKeyboard) {
+ coordinates = CoordinateUtils.newCoordinateArray(codePoints.length,
+ Constants.NOT_A_COORDINATE, Constants.NOT_A_COORDINATE);
+ } else {
+ coordinates = mKeyboard.getCoordinates(codePoints);
+ }
+ composer.setComposingWord(codePoints, coordinates, prevWord);
+
+ final int trailingSingleQuotesCount = composer.trailingSingleQuotesCount();
+ final String consideredWord = trailingSingleQuotesCount > 0 ? testedWord.substring(0,
+ testedWord.length() - trailingSingleQuotesCount) : testedWord;
+ final AsyncResultHolder<Boolean> holder = new AsyncResultHolder<Boolean>();
+ final OnGetSuggestedWordsCallback callback = new OnGetSuggestedWordsCallback() {
+ @Override
+ public void onGetSuggestedWords(final SuggestedWords suggestedWords) {
+ if (suggestedWords != null && suggestedWords.size() > 1) {
+ // The suggestedWordInfo at 0 is the typed word. The 1st suggestion from
+ // the decoder is at index 1.
+ final SuggestedWordInfo firstSuggestion = suggestedWords.getInfo(1);
+ final boolean hasStrongDistractor = suggestionExceedsDistracterThreshold(
+ firstSuggestion, consideredWord, DISTRACTER_WORD_SCORE_THRESHOLD);
+ holder.set(hasStrongDistractor);
+ }
+ }
+ };
+ mSuggest.getSuggestedWords(composer, prevWord, mKeyboard.getProximityInfo(),
+ true /* blockOffensiveWords */, true /* isCorrectionEnbaled */,
+ null /* additionalFeaturesOptions */, 0 /* sessionId */,
+ SuggestedWords.NOT_A_SEQUENCE_NUMBER, callback);
+
+ return holder.get(false /* defaultValue */, Constants.GET_SUGGESTED_WORDS_TIMEOUT);
+ }
}
diff --git a/java/src/com/android/inputmethod/latin/utils/LanguageModelParam.java b/java/src/com/android/inputmethod/latin/utils/LanguageModelParam.java
index 55061f45f..74e7db901 100644
--- a/java/src/com/android/inputmethod/latin/utils/LanguageModelParam.java
+++ b/java/src/com/android/inputmethod/latin/utils/LanguageModelParam.java
@@ -129,6 +129,9 @@ public final class LanguageModelParam {
if (locale == null) {
return null;
}
+ // TODO: Though targetWord is an IV (in-vocabulary) word, we should still apply
+ // distracterFilter in the following code. If targetWord is a distracter,
+ // it should be filtered out.
if (dictionaryFacilitator.isValidWord(targetWord, false /* ignoreCase */)) {
return createAndGetLanguageModelParamOfWord(prevWord, targetWord, timestamp,
true /* isValidWord */, locale);