Move distracter filter to dictionary facilitator.
Bug: 13142176 Bug: 15094186 Change-Id: Ib9e42f8e25538009f3ba62cf1e034cae3f6823c7main
parent
a1035be6d8
commit
1fa3e9044f
|
@ -19,14 +19,18 @@ package com.android.inputmethod.latin;
|
|||
import android.content.Context;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import android.view.inputmethod.InputMethodSubtype;
|
||||
|
||||
import com.android.inputmethod.annotations.UsedForTesting;
|
||||
import com.android.inputmethod.keyboard.ProximityInfo;
|
||||
import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
|
||||
import com.android.inputmethod.latin.personalization.ContextualDictionary;
|
||||
import com.android.inputmethod.latin.personalization.PersonalizationDataChunk;
|
||||
import com.android.inputmethod.latin.personalization.PersonalizationDictionary;
|
||||
import com.android.inputmethod.latin.personalization.UserHistoryDictionary;
|
||||
import com.android.inputmethod.latin.settings.SpacingAndPunctuations;
|
||||
import com.android.inputmethod.latin.utils.CollectionUtils;
|
||||
import com.android.inputmethod.latin.utils.DistracterFilter;
|
||||
import com.android.inputmethod.latin.utils.ExecutorUtils;
|
||||
import com.android.inputmethod.latin.utils.LanguageModelParam;
|
||||
import com.android.inputmethod.latin.utils.SuggestionResults;
|
||||
|
@ -37,6 +41,7 @@ import java.lang.reflect.Method;
|
|||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
@ -57,6 +62,7 @@ public class DictionaryFacilitator {
|
|||
private volatile CountDownLatch mLatchForWaitingLoadingMainDictionary = new CountDownLatch(0);
|
||||
// To synchronize assigning mDictionaries to ensure closing dictionaries.
|
||||
private final Object mLock = new Object();
|
||||
private final DistracterFilter mDistracterFilter;
|
||||
|
||||
private static final String[] DICT_TYPES_ORDERED_TO_GET_SUGGESTION =
|
||||
new String[] {
|
||||
|
@ -162,7 +168,17 @@ public class DictionaryFacilitator {
|
|||
public void onUpdateMainDictionaryAvailability(boolean isMainDictionaryAvailable);
|
||||
}
|
||||
|
||||
public DictionaryFacilitator() {}
|
||||
public DictionaryFacilitator() {
|
||||
mDistracterFilter = new DistracterFilter();
|
||||
}
|
||||
|
||||
public DictionaryFacilitator(final DistracterFilter distracterFilter) {
|
||||
mDistracterFilter = distracterFilter;
|
||||
}
|
||||
|
||||
public void updateEnabledSubtypes(final List<InputMethodSubtype> enabledSubtypes) {
|
||||
mDistracterFilter.updateEnabledSubtypes(enabledSubtypes);
|
||||
}
|
||||
|
||||
public Locale getLocale() {
|
||||
return mDictionaries.mLocale;
|
||||
|
@ -321,6 +337,7 @@ public class DictionaryFacilitator {
|
|||
for (final String dictType : DICT_TYPES_ORDERED_TO_GET_SUGGESTION) {
|
||||
dictionaries.closeDict(dictType);
|
||||
}
|
||||
mDistracterFilter.close();
|
||||
}
|
||||
|
||||
// The main dictionary could have been loaded asynchronously. Don't cache the return value
|
||||
|
@ -537,9 +554,16 @@ public class DictionaryFacilitator {
|
|||
personalizationDict.clear();
|
||||
}
|
||||
|
||||
public void addMultipleDictionaryEntriesToPersonalizationDictionary(
|
||||
final ArrayList<LanguageModelParam> languageModelParams,
|
||||
public void addEntriesToPersonalizationDictionary(
|
||||
final PersonalizationDataChunk personalizationDataChunk,
|
||||
final SpacingAndPunctuations spacingAndPunctuations,
|
||||
final ExpandableBinaryDictionary.AddMultipleDictionaryEntriesCallback callback) {
|
||||
final ArrayList<LanguageModelParam> languageModelParams =
|
||||
LanguageModelParam.createLanguageModelParamsFrom(
|
||||
personalizationDataChunk.mTokens,
|
||||
personalizationDataChunk.mTimestampInSeconds,
|
||||
this /* dictionaryFacilitator */, spacingAndPunctuations,
|
||||
mDistracterFilter);
|
||||
final ExpandableBinaryDictionary personalizationDict =
|
||||
mDictionaries.getSubDict(Dictionary.TYPE_PERSONALIZATION);
|
||||
if (personalizationDict == null || languageModelParams == null
|
||||
|
|
|
@ -81,6 +81,7 @@ import com.android.inputmethod.latin.suggestions.SuggestionStripView;
|
|||
import com.android.inputmethod.latin.suggestions.SuggestionStripViewAccessor;
|
||||
import com.android.inputmethod.latin.utils.ApplicationUtils;
|
||||
import com.android.inputmethod.latin.utils.CapsModeUtils;
|
||||
import com.android.inputmethod.latin.utils.CollectionUtils;
|
||||
import com.android.inputmethod.latin.utils.CoordinateUtils;
|
||||
import com.android.inputmethod.latin.utils.DialogUtils;
|
||||
import com.android.inputmethod.latin.utils.DistracterFilter;
|
||||
|
@ -95,6 +96,7 @@ import com.android.inputmethod.research.ResearchLogger;
|
|||
import java.io.FileDescriptor;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
|
@ -122,7 +124,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
|||
private static final String SCHEME_PACKAGE = "package";
|
||||
|
||||
private final Settings mSettings;
|
||||
private final DictionaryFacilitator mDictionaryFacilitator = new DictionaryFacilitator();
|
||||
private final DictionaryFacilitator mDictionaryFacilitator =
|
||||
new DictionaryFacilitator(new DistracterFilter(this /* context */));
|
||||
private final InputLogic mInputLogic = new InputLogic(this /* LatinIME */,
|
||||
this /* SuggestionStripViewAccessor */, mDictionaryFacilitator);
|
||||
// We expect to have only one decoder in almost all cases, hence the default capacity of 1.
|
||||
|
@ -538,6 +541,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
|||
if (!mHandler.hasPendingReopenDictionaries()) {
|
||||
resetSuggestForLocale(locale);
|
||||
}
|
||||
mDictionaryFacilitator.updateEnabledSubtypes(mRichImm.getMyEnabledInputMethodSubtypeList(
|
||||
true /* allowsImplicitlySelectedSubtypes */));
|
||||
refreshPersonalizationDictionarySession();
|
||||
StatsUtils.onLoadSettings(currentSettingsValues);
|
||||
}
|
||||
|
@ -564,9 +569,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
|||
PersonalizationHelper.removeAllPersonalizationDictionaries(this);
|
||||
PersonalizationDictionarySessionRegistrar.resetAll(this);
|
||||
} else {
|
||||
final DistracterFilter distracterFilter = createDistracterFilter();
|
||||
PersonalizationDictionarySessionRegistrar.init(
|
||||
this, mDictionaryFacilitator, distracterFilter);
|
||||
PersonalizationDictionarySessionRegistrar.init(this, mDictionaryFacilitator);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -660,9 +663,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
|||
mInputLogic.mConnection.finishComposingText();
|
||||
mInputLogic.mConnection.endBatchEdit();
|
||||
}
|
||||
final DistracterFilter distracterFilter = createDistracterFilter();
|
||||
PersonalizationDictionarySessionRegistrar.onConfigurationChanged(this, conf,
|
||||
mDictionaryFacilitator, distracterFilter);
|
||||
mDictionaryFacilitator);
|
||||
super.onConfigurationChanged(conf);
|
||||
}
|
||||
|
||||
|
@ -1739,11 +1741,9 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
|||
}
|
||||
|
||||
@UsedForTesting
|
||||
/* package for test */ DistracterFilter createDistracterFilter() {
|
||||
// Return an empty distracter filter when this method is called before onCreate().
|
||||
return (mRichImm != null) ? new DistracterFilter(this /* Context */,
|
||||
mRichImm.getMyEnabledInputMethodSubtypeList(
|
||||
true /* allowsImplicitlySelectedSubtypes */)) : new DistracterFilter();
|
||||
/* package for test */ List<InputMethodSubtype> getEnabledSubtypesForTest() {
|
||||
return (mRichImm != null) ? mRichImm.getMyEnabledInputMethodSubtypeList(
|
||||
true /* allowsImplicitlySelectedSubtypes */) : new ArrayList<InputMethodSubtype>();
|
||||
}
|
||||
|
||||
public void dumpDictionaryForDebug(final String dictName) {
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Copyright (C) 2014 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.inputmethod.latin.personalization;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
public class PersonalizationDataChunk {
|
||||
public final boolean mInputByUser;
|
||||
public final List<String> mTokens;
|
||||
public final int mTimestampInSeconds;
|
||||
public final String mPackageName;
|
||||
public final Locale mlocale = null;
|
||||
|
||||
public PersonalizationDataChunk(boolean inputByUser, final List<String> tokens,
|
||||
final int timestampInSeconds, final String packageName) {
|
||||
mInputByUser = inputByUser;
|
||||
mTokens = Collections.unmodifiableList(tokens);
|
||||
mTimestampInSeconds = timestampInSeconds;
|
||||
mPackageName = packageName;
|
||||
}
|
||||
}
|
|
@ -20,17 +20,14 @@ import android.content.Context;
|
|||
import android.content.res.Configuration;
|
||||
|
||||
import com.android.inputmethod.latin.DictionaryFacilitator;
|
||||
import com.android.inputmethod.latin.utils.DistracterFilter;
|
||||
|
||||
public class PersonalizationDictionarySessionRegistrar {
|
||||
public static void init(final Context context,
|
||||
final DictionaryFacilitator dictionaryFacilitator,
|
||||
final DistracterFilter distracterFilter) {
|
||||
final DictionaryFacilitator dictionaryFacilitator) {
|
||||
}
|
||||
|
||||
public static void onConfigurationChanged(final Context context, final Configuration conf,
|
||||
final DictionaryFacilitator dictionaryFacilitator,
|
||||
final DistracterFilter distracterFilter) {
|
||||
final DictionaryFacilitator dictionaryFacilitator) {
|
||||
}
|
||||
|
||||
public static void onUpdateData(final Context context, final String type) {
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
|
||||
package com.android.inputmethod.latin.utils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
@ -57,6 +56,7 @@ public class DistracterFilter {
|
|||
private final DictionaryFacilitator mDictionaryFacilitator;
|
||||
private final Suggest mSuggest;
|
||||
private Keyboard mKeyboard;
|
||||
private final Object mLock = new Object();
|
||||
|
||||
// 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
|
||||
|
@ -67,35 +67,59 @@ public class DistracterFilter {
|
|||
|
||||
// Create empty distracter filter.
|
||||
public DistracterFilter() {
|
||||
this(null, new ArrayList<InputMethodSubtype>());
|
||||
mContext = null;
|
||||
mLocaleToSubtypeMap = new HashMap<>();
|
||||
mLocaleToKeyboardMap = new HashMap<>();
|
||||
// TODO: Quit assigning null.
|
||||
mDictionaryFacilitator = null;
|
||||
mSuggest = null;
|
||||
mKeyboard = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a DistracterFilter instance.
|
||||
*
|
||||
* @param context the context.
|
||||
* @param enabledSubtypes the enabled subtypes.
|
||||
*/
|
||||
public DistracterFilter(final Context context, final List<InputMethodSubtype> enabledSubtypes) {
|
||||
public DistracterFilter(final Context context) {
|
||||
mContext = context;
|
||||
mLocaleToSubtypeMap = new HashMap<>();
|
||||
if (enabledSubtypes != null) {
|
||||
for (final InputMethodSubtype subtype : enabledSubtypes) {
|
||||
final Locale locale = SubtypeLocaleUtils.getSubtypeLocale(subtype);
|
||||
if (mLocaleToSubtypeMap.containsKey(locale)) {
|
||||
// Multiple subtypes are enabled for one locale.
|
||||
// TODO: Investigate what we should do for this case.
|
||||
continue;
|
||||
}
|
||||
mLocaleToSubtypeMap.put(locale, subtype);
|
||||
}
|
||||
}
|
||||
mLocaleToKeyboardMap = new HashMap<>();
|
||||
mDictionaryFacilitator = new DictionaryFacilitator();
|
||||
mSuggest = new Suggest(mDictionaryFacilitator);
|
||||
mKeyboard = null;
|
||||
}
|
||||
|
||||
public void close() {
|
||||
if (mDictionaryFacilitator != null) {
|
||||
mDictionaryFacilitator.closeDictionaries();
|
||||
}
|
||||
}
|
||||
|
||||
public void updateEnabledSubtypes(final List<InputMethodSubtype> enabledSubtypes) {
|
||||
final Map<Locale, InputMethodSubtype> newLocaleToSubtypeMap = new HashMap<>();
|
||||
if (enabledSubtypes != null) {
|
||||
for (final InputMethodSubtype subtype : enabledSubtypes) {
|
||||
final Locale locale = SubtypeLocaleUtils.getSubtypeLocale(subtype);
|
||||
if (newLocaleToSubtypeMap.containsKey(locale)) {
|
||||
// Multiple subtypes are enabled for one locale.
|
||||
// TODO: Investigate what we should do for this case.
|
||||
continue;
|
||||
}
|
||||
newLocaleToSubtypeMap.put(locale, subtype);
|
||||
}
|
||||
}
|
||||
if (mLocaleToSubtypeMap.equals(newLocaleToSubtypeMap)) {
|
||||
// Enabled subtypes have not been changed.
|
||||
return;
|
||||
}
|
||||
synchronized (mLock) {
|
||||
mLocaleToSubtypeMap.clear();
|
||||
mLocaleToSubtypeMap.putAll(newLocaleToSubtypeMap);
|
||||
mLocaleToKeyboardMap.clear();
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean suggestionExceedsDistracterThreshold(
|
||||
final SuggestedWordInfo suggestion, final String consideredWord,
|
||||
final float distracterThreshold) {
|
||||
|
@ -116,7 +140,10 @@ public class DistracterFilter {
|
|||
mKeyboard = cachedKeyboard;
|
||||
return;
|
||||
}
|
||||
final InputMethodSubtype subtype = mLocaleToSubtypeMap.get(newLocale);
|
||||
final InputMethodSubtype subtype;
|
||||
synchronized (mLock) {
|
||||
subtype = mLocaleToSubtypeMap.get(newLocale);
|
||||
}
|
||||
if (subtype == null) {
|
||||
return;
|
||||
}
|
||||
|
@ -153,22 +180,25 @@ public class DistracterFilter {
|
|||
*/
|
||||
public boolean isDistracterToWordsInDictionaries(final PrevWordsInfo prevWordsInfo,
|
||||
final String testedWord, final Locale locale) {
|
||||
if (locale == null) {
|
||||
if (mSuggest == null || locale == null) {
|
||||
return false;
|
||||
}
|
||||
if (!locale.equals(mDictionaryFacilitator.getLocale())) {
|
||||
if (!mLocaleToSubtypeMap.containsKey(locale)) {
|
||||
Log.e(TAG, "Locale " + locale + " is not enabled.");
|
||||
// TODO: Investigate what we should do for disabled locales.
|
||||
return false;
|
||||
}
|
||||
loadKeyboardForLocale(locale);
|
||||
// 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;
|
||||
synchronized (mLock) {
|
||||
if (!mLocaleToSubtypeMap.containsKey(locale)) {
|
||||
Log.e(TAG, "Locale " + locale + " is not enabled.");
|
||||
// TODO: Investigate what we should do for disabled locales.
|
||||
return false;
|
||||
}
|
||||
loadKeyboardForLocale(locale);
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (mKeyboard == null) {
|
||||
|
|
|
@ -24,6 +24,7 @@ import com.android.inputmethod.latin.PrevWordsInfo;
|
|||
import com.android.inputmethod.latin.settings.SpacingAndPunctuations;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
// Note: this class is used as a parameter type of a native method. You should be careful when you
|
||||
|
@ -79,7 +80,7 @@ public final class LanguageModelParam {
|
|||
|
||||
// Process a list of words and return a list of {@link LanguageModelParam} objects.
|
||||
public static ArrayList<LanguageModelParam> createLanguageModelParamsFrom(
|
||||
final ArrayList<String> tokens, final int timestamp,
|
||||
final List<String> tokens, final int timestamp,
|
||||
final DictionaryFacilitator dictionaryFacilitator,
|
||||
final SpacingAndPunctuations spacingAndPunctuations,
|
||||
final DistracterFilter distracterFilter) {
|
||||
|
|
|
@ -32,7 +32,8 @@ public class DistracterFilterTest extends InputTestsBase {
|
|||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
mDistracterFilter = mLatinIME.createDistracterFilter();
|
||||
mDistracterFilter = new DistracterFilter(getContext());
|
||||
mDistracterFilter.updateEnabledSubtypes(mLatinIME.getEnabledSubtypesForTest());
|
||||
}
|
||||
|
||||
public void testIsDistractorToWordsInDictionaries() {
|
||||
|
|
Loading…
Reference in New Issue