From 23246ed18d9b26d8a7673140c00e060022be935b Mon Sep 17 00:00:00 2001 From: Keisuke Kuroyanagi Date: Fri, 16 May 2014 22:19:41 +0900 Subject: [PATCH] Use dedicated DictionaryFacilitator for DistracterFilter Bug: 15002249 Change-Id: Ic77eaa7d627d406daad7dcd15cb4884d9f647312 --- .../android/inputmethod/latin/LatinIME.java | 10 ++--- .../latin/utils/DistracterFilter.java | 41 ++++++++++++++++--- .../latin/utils/DistracterFilterUtils.java | 7 ++-- .../latin/utils/LanguageModelParam.java | 2 +- .../latin/DistracterFilterTest.java | 28 +++++++++---- 5 files changed, 65 insertions(+), 23 deletions(-) diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java index 74b83c1bb..d100d32bb 100644 --- a/java/src/com/android/inputmethod/latin/LatinIME.java +++ b/java/src/com/android/inputmethod/latin/LatinIME.java @@ -140,10 +140,10 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen private final SubtypeState mSubtypeState = new SubtypeState(); // Object for reacting to adding/removing a dictionary pack. - private BroadcastReceiver mDictionaryPackInstallReceiver = + private final BroadcastReceiver mDictionaryPackInstallReceiver = new DictionaryPackInstallBroadcastReceiver(this); - private BroadcastReceiver mDictionaryDumpBroadcastReceiver = + private final BroadcastReceiver mDictionaryDumpBroadcastReceiver = new DictionaryDumpBroadcastReceiver(this); private AlertDialog mOptionsDialog; @@ -1629,7 +1629,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen // boolean onKeyMultiple(final int keyCode, final int count, final KeyEvent event); // receive ringer mode change and network state change. - private BroadcastReceiver mConnectivityAndRingerModeChangeReceiver = new BroadcastReceiver() { + private final BroadcastReceiver mConnectivityAndRingerModeChangeReceiver = + new BroadcastReceiver() { @Override public void onReceive(final Context context, final Intent intent) { final String action = intent.getAction(); @@ -1746,8 +1747,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen @UsedForTesting /* package for test */ DistracterFilter createDistracterFilter() { - return DistracterFilterUtils.createDistracterFilter( - mInputLogic.mSuggest, mKeyboardSwitcher); + return DistracterFilterUtils.createDistracterFilter(this /* Context */, mKeyboardSwitcher); } public void dumpDictionaryForDebug(final String dictName) { diff --git a/java/src/com/android/inputmethod/latin/utils/DistracterFilter.java b/java/src/com/android/inputmethod/latin/utils/DistracterFilter.java index dc3e9bf71..05387d55b 100644 --- a/java/src/com/android/inputmethod/latin/utils/DistracterFilter.java +++ b/java/src/com/android/inputmethod/latin/utils/DistracterFilter.java @@ -16,6 +16,12 @@ package com.android.inputmethod.latin.utils; +import java.util.Locale; +import java.util.concurrent.TimeUnit; + +import android.content.Context; +import android.util.Log; + import com.android.inputmethod.keyboard.Keyboard; import com.android.inputmethod.latin.Constants; import com.android.inputmethod.latin.Suggest; @@ -29,6 +35,11 @@ import com.android.inputmethod.latin.WordComposer; * or user history dictionaries */ public class DistracterFilter { + private static final String TAG = DistracterFilter.class.getSimpleName(); + + private static final long TIMEOUT_TO_WAIT_LOADING_DICTIONARIES_IN_SECONDS = 120; + + private final Context mContext; private final Suggest mSuggest; private final Keyboard mKeyboard; @@ -42,13 +53,13 @@ public class DistracterFilter { /** * Create a DistracterFilter instance. * - * @param suggest an instance of Suggest which will be used to obtain a list of suggestions - * for a potential distracter + * @param context the context. * @param keyboard the keyboard that is currently being used. This information is needed * when calling mSuggest.getSuggestedWords(...) to obtain a list of suggestions. */ - public DistracterFilter(final Suggest suggest, final Keyboard keyboard) { - mSuggest = suggest; + public DistracterFilter(final Context context, final Keyboard keyboard) { + mContext = context; + mSuggest = new Suggest(); mKeyboard = keyboard; } @@ -66,19 +77,37 @@ public class DistracterFilter { return false; } + private void loadDictionariesForLocale(final Locale newlocale) throws InterruptedException { + mSuggest.mDictionaryFacilitator.resetDictionaries(mContext, newlocale, + false /* useContactsDict */, false /* usePersonalizedDicts */, + false /* forceReloadMainDictionary */, null /* listener */); + mSuggest.mDictionaryFacilitator.waitForLoadingMainDictionary( + TIMEOUT_TO_WAIT_LOADING_DICTIONARIES_IN_SECONDS, TimeUnit.SECONDS); + } + /** * 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. + * @param locale the locale of words. * @return true if testedWord is a distracter, otherwise false. */ public boolean isDistracterToWordsInDictionaries(final String prevWord, - final String testedWord) { - if (mSuggest == null || mKeyboard == null) { + final String testedWord, final Locale locale) { + if (mKeyboard == null || locale == null) { return false; } + if (!locale.equals(mSuggest.mDictionaryFacilitator.getLocale())) { + // Reset dictionaries for the locale. + try { + loadDictionariesForLocale(locale); + } catch (final InterruptedException e) { + Log.e(TAG, "Interrupted while waiting for loading dicts in DistracterFilter", e); + return false; + } + } final WordComposer composer = new WordComposer(); final int[] codePoints = StringUtils.toCodePointArray(testedWord); diff --git a/java/src/com/android/inputmethod/latin/utils/DistracterFilterUtils.java b/java/src/com/android/inputmethod/latin/utils/DistracterFilterUtils.java index df07f976c..8a711a24e 100644 --- a/java/src/com/android/inputmethod/latin/utils/DistracterFilterUtils.java +++ b/java/src/com/android/inputmethod/latin/utils/DistracterFilterUtils.java @@ -16,17 +16,18 @@ package com.android.inputmethod.latin.utils; +import android.content.Context; + import com.android.inputmethod.keyboard.Keyboard; import com.android.inputmethod.keyboard.KeyboardSwitcher; import com.android.inputmethod.keyboard.MainKeyboardView; -import com.android.inputmethod.latin.Suggest; public class DistracterFilterUtils { private DistracterFilterUtils() { // This utility class is not publicly instantiable. } - public static final DistracterFilter createDistracterFilter(final Suggest suggest, + public static final DistracterFilter createDistracterFilter(final Context context, final KeyboardSwitcher keyboardSwitcher) { final MainKeyboardView mainKeyboardView = keyboardSwitcher.getMainKeyboardView(); // TODO: Create Keyboard when mainKeyboardView is null. @@ -34,7 +35,7 @@ public class DistracterFilterUtils { // spellchecker's logic. final Keyboard keyboard = (mainKeyboardView != null) ? mainKeyboardView.getKeyboard() : null; - final DistracterFilter distracterFilter = new DistracterFilter(suggest, keyboard); + final DistracterFilter distracterFilter = new DistracterFilter(context, keyboard); return distracterFilter; } } diff --git a/java/src/com/android/inputmethod/latin/utils/LanguageModelParam.java b/java/src/com/android/inputmethod/latin/utils/LanguageModelParam.java index 74e7db901..2d6796e3e 100644 --- a/java/src/com/android/inputmethod/latin/utils/LanguageModelParam.java +++ b/java/src/com/android/inputmethod/latin/utils/LanguageModelParam.java @@ -150,7 +150,7 @@ public final class LanguageModelParam { // Adding such a word to dictonaries would interfere with entering in-dictionary words. For // example, adding "mot" to dictionaries might interfere with entering "not". // This kind of OOV should be filtered out. - if (distracterFilter.isDistracterToWordsInDictionaries(prevWord, targetWord)) { + if (distracterFilter.isDistracterToWordsInDictionaries(prevWord, targetWord, locale)) { return null; } return createAndGetLanguageModelParamOfWord(prevWord, targetWord, timestamp, diff --git a/tests/src/com/android/inputmethod/latin/DistracterFilterTest.java b/tests/src/com/android/inputmethod/latin/DistracterFilterTest.java index 186542ae5..d7b57aeea 100644 --- a/tests/src/com/android/inputmethod/latin/DistracterFilterTest.java +++ b/tests/src/com/android/inputmethod/latin/DistracterFilterTest.java @@ -16,6 +16,8 @@ package com.android.inputmethod.latin; +import java.util.Locale; + import android.test.suitebuilder.annotation.LargeTest; import com.android.inputmethod.latin.utils.DistracterFilter; @@ -35,39 +37,49 @@ public class DistracterFilterTest extends InputTestsBase { public void testIsDistractorToWordsInDictionaries() { final String EMPTY_PREV_WORD = null; + + final Locale localeEnUs = new Locale("en", "US"); String typedWord = "alot"; // For this test case, we consider "alot" is a distracter to "a lot". - assertTrue(mDistracterFilter.isDistracterToWordsInDictionaries(EMPTY_PREV_WORD, typedWord)); + assertTrue(mDistracterFilter.isDistracterToWordsInDictionaries( + EMPTY_PREV_WORD, typedWord, localeEnUs)); typedWord = "mot"; // For this test case, we consider "mot" is a distracter to "not". - assertTrue(mDistracterFilter.isDistracterToWordsInDictionaries(EMPTY_PREV_WORD, typedWord)); + assertTrue(mDistracterFilter.isDistracterToWordsInDictionaries( + EMPTY_PREV_WORD, typedWord, localeEnUs)); typedWord = "wierd"; // For this test case, we consider "wierd" is a distracter to "weird". - assertTrue(mDistracterFilter.isDistracterToWordsInDictionaries(EMPTY_PREV_WORD, typedWord)); + assertTrue(mDistracterFilter.isDistracterToWordsInDictionaries( + EMPTY_PREV_WORD, typedWord, localeEnUs)); typedWord = "hoe"; // For this test case, we consider "hoe" is a distracter to "how". - assertTrue(mDistracterFilter.isDistracterToWordsInDictionaries(EMPTY_PREV_WORD, typedWord)); + assertTrue(mDistracterFilter.isDistracterToWordsInDictionaries( + EMPTY_PREV_WORD, typedWord, localeEnUs)); typedWord = "nit"; // For this test case, we consider "nit" is a distracter to "not". - assertTrue(mDistracterFilter.isDistracterToWordsInDictionaries(EMPTY_PREV_WORD, typedWord)); + assertTrue(mDistracterFilter.isDistracterToWordsInDictionaries( + EMPTY_PREV_WORD, typedWord, localeEnUs)); typedWord = "ill"; // For this test case, we consider "ill" is a distracter to "I'll". - assertTrue(mDistracterFilter.isDistracterToWordsInDictionaries(EMPTY_PREV_WORD, typedWord)); + assertTrue(mDistracterFilter.isDistracterToWordsInDictionaries( + EMPTY_PREV_WORD, typedWord, localeEnUs)); typedWord = "asdfd"; // For this test case, we consider "asdfd" is not a distracter to any word in dictionaries. assertFalse( - mDistracterFilter.isDistracterToWordsInDictionaries(EMPTY_PREV_WORD, typedWord)); + mDistracterFilter.isDistracterToWordsInDictionaries( + EMPTY_PREV_WORD, typedWord, localeEnUs)); typedWord = "thank"; // For this test case, we consider "thank" is not a distracter to any other word // in dictionaries. assertFalse( - mDistracterFilter.isDistracterToWordsInDictionaries(EMPTY_PREV_WORD, typedWord)); + mDistracterFilter.isDistracterToWordsInDictionaries( + EMPTY_PREV_WORD, typedWord, localeEnUs)); } }