[ML7] Have multiple DictionaryGroup instances in facilitator
This is the central change of multilingual input. Bug: 11230254 Change-Id: Id8b68fb101e837e8cf182ab4bc1e55e4da5cc49dmain
parent
97b465044f
commit
8cd5326622
|
@ -61,9 +61,9 @@ public class DictionaryFacilitator {
|
|||
// dictionary.
|
||||
private static final int CAPITALIZED_FORM_MAX_PROBABILITY_FOR_INSERT = 140;
|
||||
|
||||
private DictionaryGroup mDictionaryGroup = new DictionaryGroup();
|
||||
private DictionaryGroup[] mDictionaryGroups = new DictionaryGroup[] { new DictionaryGroup() };
|
||||
private boolean mIsUserDictEnabled = false;
|
||||
private volatile CountDownLatch mLatchForWaitingLoadingMainDictionary = new CountDownLatch(0);
|
||||
private volatile CountDownLatch mLatchForWaitingLoadingMainDictionaries = new CountDownLatch(0);
|
||||
// To synchronize assigning mDictionaryGroup to ensure closing dictionaries.
|
||||
private final Object mLock = new Object();
|
||||
private final DistracterFilter mDistracterFilter;
|
||||
|
@ -193,8 +193,9 @@ public class DictionaryFacilitator {
|
|||
mPersonalizationHelper.setIsMonolingualUser(isMonolingualUser);
|
||||
}
|
||||
|
||||
// TODO: remove this, replace with version returning multiple locales
|
||||
public Locale getLocale() {
|
||||
return mDictionaryGroup.mLocale;
|
||||
return mDictionaryGroups[0].mLocale;
|
||||
}
|
||||
|
||||
private static ExpandableBinaryDictionary getSubDict(final String dictType,
|
||||
|
@ -226,6 +227,21 @@ public class DictionaryFacilitator {
|
|||
usePersonalizedDicts, forceReloadMainDictionary, listener, "" /* dictNamePrefix */);
|
||||
}
|
||||
|
||||
private DictionaryGroup findDictionaryGroupWithLocale(final DictionaryGroup[] dictionaryGroups,
|
||||
final Locale locale) {
|
||||
for (int i = 0; i < dictionaryGroups.length; ++i) {
|
||||
if (locale.equals(dictionaryGroups[i].mLocale)) {
|
||||
return dictionaryGroups[i];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private DictionaryGroup getDictionaryGroupForActiveLanguage() {
|
||||
// TODO: implement this
|
||||
return mDictionaryGroups[0];
|
||||
}
|
||||
|
||||
public void resetDictionariesWithDictNamePrefix(final Context context,
|
||||
final Locale newLocaleToUse,
|
||||
final boolean useContactsDict, final boolean usePersonalizedDicts,
|
||||
|
@ -252,7 +268,7 @@ public class DictionaryFacilitator {
|
|||
final ArrayList<String> dictsForLocale = new ArrayList<>();
|
||||
existingDictsToCleanup.put(newLocale, dictsForLocale);
|
||||
final DictionaryGroup currentDictionaryGroupForLocale =
|
||||
newLocale.equals(mDictionaryGroup.mLocale) ? mDictionaryGroup : null;
|
||||
findDictionaryGroupWithLocale(mDictionaryGroups, newLocale);
|
||||
if (null == currentDictionaryGroupForLocale) {
|
||||
continue;
|
||||
}
|
||||
|
@ -266,10 +282,11 @@ public class DictionaryFacilitator {
|
|||
}
|
||||
}
|
||||
|
||||
final HashMap<Locale, DictionaryGroup> newDictionaryGroups = new HashMap<>();
|
||||
for (final Locale newLocale : newLocales) {
|
||||
final DictionaryGroup[] newDictionaryGroups = new DictionaryGroup[newLocales.length];
|
||||
for (int i = 0; i < newLocales.length; ++i) {
|
||||
final Locale newLocale = newLocales[i];
|
||||
final DictionaryGroup dictionaryGroupForLocale =
|
||||
newLocale.equals(mDictionaryGroup.mLocale) ? mDictionaryGroup : null;
|
||||
findDictionaryGroupWithLocale(mDictionaryGroups, newLocale);
|
||||
final ArrayList<String> dictsToCleanupForLocale = existingDictsToCleanup.get(newLocale);
|
||||
final boolean noExistingDictsForThisLocale = (null == dictionaryGroupForLocale);
|
||||
|
||||
|
@ -297,30 +314,29 @@ public class DictionaryFacilitator {
|
|||
}
|
||||
subDicts.put(subDictType, subDict);
|
||||
}
|
||||
newDictionaryGroups.put(newLocale, new DictionaryGroup(newLocale, mainDict, subDicts));
|
||||
newDictionaryGroups[i] = new DictionaryGroup(newLocale, mainDict, subDicts);
|
||||
}
|
||||
|
||||
// Replace Dictionaries.
|
||||
// TODO: use multiple locales.
|
||||
final DictionaryGroup newDictionaryGroup = newDictionaryGroups.get(newLocaleToUse);
|
||||
final DictionaryGroup oldDictionaryGroup;
|
||||
final DictionaryGroup[] oldDictionaryGroups;
|
||||
synchronized (mLock) {
|
||||
oldDictionaryGroup = mDictionaryGroup;
|
||||
mDictionaryGroup = newDictionaryGroup;
|
||||
oldDictionaryGroups = mDictionaryGroups;
|
||||
mDictionaryGroups = newDictionaryGroups;
|
||||
mIsUserDictEnabled = UserBinaryDictionary.isEnabled(context);
|
||||
if (null == newDictionaryGroup.getDict(Dictionary.TYPE_MAIN)) {
|
||||
if (hasAtLeastOneUninitializedMainDictionary()) {
|
||||
asyncReloadUninitializedMainDictionaries(context, newLocales, listener);
|
||||
}
|
||||
}
|
||||
if (listener != null) {
|
||||
listener.onUpdateMainDictionaryAvailability(hasInitializedMainDictionary());
|
||||
listener.onUpdateMainDictionaryAvailability(hasAtLeastOneInitializedMainDictionary());
|
||||
}
|
||||
|
||||
// Clean up old dictionaries.
|
||||
for (final Locale localeToCleanUp : existingDictsToCleanup.keySet()) {
|
||||
final ArrayList<String> dictTypesToCleanUp =
|
||||
existingDictsToCleanup.get(localeToCleanUp);
|
||||
final DictionaryGroup dictionarySetToCleanup = oldDictionaryGroup;
|
||||
final DictionaryGroup dictionarySetToCleanup =
|
||||
findDictionaryGroupWithLocale(oldDictionaryGroups, localeToCleanUp);
|
||||
for (final String dictType : dictTypesToCleanUp) {
|
||||
dictionarySetToCleanup.closeDict(dictType);
|
||||
}
|
||||
|
@ -330,12 +346,18 @@ public class DictionaryFacilitator {
|
|||
private void asyncReloadUninitializedMainDictionaries(final Context context,
|
||||
final Locale[] locales, final DictionaryInitializationListener listener) {
|
||||
final CountDownLatch latchForWaitingLoadingMainDictionary = new CountDownLatch(1);
|
||||
mLatchForWaitingLoadingMainDictionary = latchForWaitingLoadingMainDictionary;
|
||||
mLatchForWaitingLoadingMainDictionaries = latchForWaitingLoadingMainDictionary;
|
||||
ExecutorUtils.getExecutor("InitializeBinaryDictionary").execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
for (final Locale locale : locales) {
|
||||
final DictionaryGroup dictionaryGroup = mDictionaryGroup;
|
||||
final DictionaryGroup dictionaryGroup =
|
||||
findDictionaryGroupWithLocale(mDictionaryGroups, locale);
|
||||
if (null == dictionaryGroup) {
|
||||
// This should never happen, but better safe than crashy
|
||||
Log.w(TAG, "Expected a dictionary group for " + locale + " but none found");
|
||||
continue;
|
||||
}
|
||||
final Dictionary mainDict =
|
||||
DictionaryFactory.createMainDictionaryFromManager(context, locale);
|
||||
synchronized (mLock) {
|
||||
|
@ -348,7 +370,8 @@ public class DictionaryFacilitator {
|
|||
}
|
||||
}
|
||||
if (listener != null) {
|
||||
listener.onUpdateMainDictionaryAvailability(hasInitializedMainDictionary());
|
||||
listener.onUpdateMainDictionaryAvailability(
|
||||
hasAtLeastOneInitializedMainDictionary());
|
||||
}
|
||||
latchForWaitingLoadingMainDictionary.countDown();
|
||||
}
|
||||
|
@ -381,18 +404,21 @@ public class DictionaryFacilitator {
|
|||
subDicts.put(dictType, dict);
|
||||
}
|
||||
}
|
||||
mDictionaryGroup = new DictionaryGroup(locale, mainDictionary, subDicts);
|
||||
mDictionaryGroups = new DictionaryGroup[] {
|
||||
new DictionaryGroup(locale, mainDictionary, subDicts) };
|
||||
}
|
||||
|
||||
public void closeDictionaries() {
|
||||
final DictionaryGroup dictionaryGroup;
|
||||
final DictionaryGroup[] dictionaryGroups;
|
||||
synchronized (mLock) {
|
||||
dictionaryGroup = mDictionaryGroup;
|
||||
mDictionaryGroup = new DictionaryGroup();
|
||||
dictionaryGroups = mDictionaryGroups;
|
||||
mDictionaryGroups = new DictionaryGroup[] { new DictionaryGroup() };
|
||||
}
|
||||
for (final DictionaryGroup dictionaryGroup : dictionaryGroups) {
|
||||
for (final String dictType : DICT_TYPES_ORDERED_TO_GET_SUGGESTIONS) {
|
||||
dictionaryGroup.closeDict(dictType);
|
||||
}
|
||||
}
|
||||
mDistracterFilter.close();
|
||||
if (mPersonalizationHelper != null) {
|
||||
mPersonalizationHelper.close();
|
||||
|
@ -401,42 +427,73 @@ public class DictionaryFacilitator {
|
|||
|
||||
@UsedForTesting
|
||||
public ExpandableBinaryDictionary getSubDictForTesting(final String dictName) {
|
||||
return mDictionaryGroup.getSubDict(dictName);
|
||||
return mDictionaryGroups[0].getSubDict(dictName);
|
||||
}
|
||||
|
||||
// The main dictionary could have been loaded asynchronously. Don't cache the return value
|
||||
// of this method.
|
||||
public boolean hasInitializedMainDictionary() {
|
||||
final Dictionary mainDict = mDictionaryGroup.getDict(Dictionary.TYPE_MAIN);
|
||||
return mainDict != null && mainDict.isInitialized();
|
||||
// The main dictionaries are loaded asynchronously. Don't cache the return value
|
||||
// of these methods.
|
||||
public boolean hasAtLeastOneInitializedMainDictionary() {
|
||||
final DictionaryGroup[] dictionaryGroups = mDictionaryGroups;
|
||||
for (final DictionaryGroup dictionaryGroup : dictionaryGroups) {
|
||||
final Dictionary mainDict = dictionaryGroup.getDict(Dictionary.TYPE_MAIN);
|
||||
if (mainDict != null && mainDict.isInitialized()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean hasAtLeastOneUninitializedMainDictionary() {
|
||||
final DictionaryGroup[] dictionaryGroups = mDictionaryGroups;
|
||||
for (final DictionaryGroup dictionaryGroup : dictionaryGroups) {
|
||||
final Dictionary mainDict = dictionaryGroup.getDict(Dictionary.TYPE_MAIN);
|
||||
if (mainDict == null || !mainDict.isInitialized()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean hasPersonalizationDictionary() {
|
||||
return mDictionaryGroup.hasDict(Dictionary.TYPE_PERSONALIZATION);
|
||||
final DictionaryGroup[] dictionaryGroups = mDictionaryGroups;
|
||||
for (final DictionaryGroup dictionaryGroup : dictionaryGroups) {
|
||||
if (dictionaryGroup.hasDict(Dictionary.TYPE_PERSONALIZATION)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void flushPersonalizationDictionary() {
|
||||
final HashSet<ExpandableBinaryDictionary> personalizationDictsUsedForSuggestion =
|
||||
new HashSet<>();
|
||||
final DictionaryGroup[] dictionaryGroups = mDictionaryGroups;
|
||||
for (final DictionaryGroup dictionaryGroup : dictionaryGroups) {
|
||||
final ExpandableBinaryDictionary personalizationDictUsedForSuggestion =
|
||||
mDictionaryGroup.getSubDict(Dictionary.TYPE_PERSONALIZATION);
|
||||
dictionaryGroup.getSubDict(Dictionary.TYPE_PERSONALIZATION);
|
||||
personalizationDictsUsedForSuggestion.add(personalizationDictUsedForSuggestion);
|
||||
}
|
||||
mPersonalizationHelper.flushPersonalizationDictionariesToUpdate(
|
||||
personalizationDictUsedForSuggestion);
|
||||
personalizationDictsUsedForSuggestion);
|
||||
mDistracterFilter.close();
|
||||
}
|
||||
|
||||
public void waitForLoadingMainDictionary(final long timeout, final TimeUnit unit)
|
||||
public void waitForLoadingMainDictionaries(final long timeout, final TimeUnit unit)
|
||||
throws InterruptedException {
|
||||
mLatchForWaitingLoadingMainDictionary.await(timeout, unit);
|
||||
mLatchForWaitingLoadingMainDictionaries.await(timeout, unit);
|
||||
}
|
||||
|
||||
@UsedForTesting
|
||||
public void waitForLoadingDictionariesForTesting(final long timeout, final TimeUnit unit)
|
||||
throws InterruptedException {
|
||||
waitForLoadingMainDictionary(timeout, unit);
|
||||
final Map<String, ExpandableBinaryDictionary> dictMap = mDictionaryGroup.mSubDictMap;
|
||||
for (final ExpandableBinaryDictionary dict : dictMap.values()) {
|
||||
waitForLoadingMainDictionaries(timeout, unit);
|
||||
final DictionaryGroup[] dictionaryGroups = mDictionaryGroups;
|
||||
for (final DictionaryGroup dictionaryGroup : dictionaryGroups) {
|
||||
for (final ExpandableBinaryDictionary dict : dictionaryGroup.mSubDictMap.values()) {
|
||||
dict.waitAllTasksForTests();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isUserDictionaryEnabled() {
|
||||
return mIsUserDictEnabled;
|
||||
|
@ -453,7 +510,7 @@ public class DictionaryFacilitator {
|
|||
public void addToUserHistory(final String suggestion, final boolean wasAutoCapitalized,
|
||||
final PrevWordsInfo prevWordsInfo, final int timeStampInSeconds,
|
||||
final boolean blockPotentiallyOffensive) {
|
||||
final DictionaryGroup dictionaryGroup = mDictionaryGroup;
|
||||
final DictionaryGroup dictionaryGroup = getDictionaryGroupForActiveLanguage();
|
||||
final String[] words = suggestion.split(Constants.WORD_SEPARATOR);
|
||||
PrevWordsInfo prevWordsInfoForCurrentWord = prevWordsInfo;
|
||||
for (int i = 0; i < words.length; i++) {
|
||||
|
@ -520,7 +577,8 @@ public class DictionaryFacilitator {
|
|||
}
|
||||
|
||||
private void removeWord(final String dictName, final String word) {
|
||||
final ExpandableBinaryDictionary dictionary = mDictionaryGroup.getSubDict(dictName);
|
||||
final ExpandableBinaryDictionary dictionary =
|
||||
getDictionaryGroupForActiveLanguage().getSubDict(dictName);
|
||||
if (dictionary != null) {
|
||||
dictionary.removeUnigramEntryDynamically(word);
|
||||
}
|
||||
|
@ -536,10 +594,11 @@ public class DictionaryFacilitator {
|
|||
public SuggestionResults getSuggestionResults(final WordComposer composer,
|
||||
final PrevWordsInfo prevWordsInfo, final ProximityInfo proximityInfo,
|
||||
final SettingsValuesForSuggestion settingsValuesForSuggestion, final int sessionId) {
|
||||
final DictionaryGroup dictionaryGroup = mDictionaryGroup;
|
||||
final DictionaryGroup[] dictionaryGroups = mDictionaryGroups;
|
||||
final SuggestionResults suggestionResults =
|
||||
new SuggestionResults(SuggestedWords.MAX_SUGGESTIONS);
|
||||
final float[] languageWeight = new float[] { Dictionary.NOT_A_LANGUAGE_WEIGHT };
|
||||
for (final DictionaryGroup dictionaryGroup : dictionaryGroups) {
|
||||
for (final String dictType : DICT_TYPES_ORDERED_TO_GET_SUGGESTIONS) {
|
||||
final Dictionary dictionary = dictionaryGroup.getDict(dictType);
|
||||
if (null == dictionary) continue;
|
||||
|
@ -552,6 +611,7 @@ public class DictionaryFacilitator {
|
|||
suggestionResults.mRawSuggestions.addAll(dictionarySuggestions);
|
||||
}
|
||||
}
|
||||
}
|
||||
return suggestionResults;
|
||||
}
|
||||
|
||||
|
@ -559,9 +619,10 @@ public class DictionaryFacilitator {
|
|||
if (TextUtils.isEmpty(word)) {
|
||||
return false;
|
||||
}
|
||||
final DictionaryGroup dictionaryGroup = mDictionaryGroup;
|
||||
final DictionaryGroup[] dictionaryGroups = mDictionaryGroups;
|
||||
for (final DictionaryGroup dictionaryGroup : dictionaryGroups) {
|
||||
if (dictionaryGroup.mLocale == null) {
|
||||
return false;
|
||||
continue;
|
||||
}
|
||||
final String lowerCasedWord = word.toLowerCase(dictionaryGroup.mLocale);
|
||||
for (final String dictType : DICT_TYPES_ORDERED_TO_GET_SUGGESTIONS) {
|
||||
|
@ -575,6 +636,7 @@ public class DictionaryFacilitator {
|
|||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -584,7 +646,8 @@ public class DictionaryFacilitator {
|
|||
return Dictionary.NOT_A_PROBABILITY;
|
||||
}
|
||||
int maxFreq = Dictionary.NOT_A_PROBABILITY;
|
||||
final DictionaryGroup dictionaryGroup = mDictionaryGroup;
|
||||
final DictionaryGroup[] dictionaryGroups = mDictionaryGroups;
|
||||
for (final DictionaryGroup dictionaryGroup : dictionaryGroups) {
|
||||
for (final String dictType : DICT_TYPES_ORDERED_TO_GET_SUGGESTIONS) {
|
||||
final Dictionary dictionary = dictionaryGroup.getDict(dictType);
|
||||
if (dictionary == null) continue;
|
||||
|
@ -598,6 +661,7 @@ public class DictionaryFacilitator {
|
|||
maxFreq = tempFreq;
|
||||
}
|
||||
}
|
||||
}
|
||||
return maxFreq;
|
||||
}
|
||||
|
||||
|
@ -610,11 +674,14 @@ public class DictionaryFacilitator {
|
|||
}
|
||||
|
||||
private void clearSubDictionary(final String dictName) {
|
||||
final ExpandableBinaryDictionary dictionary = mDictionaryGroup.getSubDict(dictName);
|
||||
final DictionaryGroup[] dictionaryGroups = mDictionaryGroups;
|
||||
for (final DictionaryGroup dictionaryGroup : dictionaryGroups) {
|
||||
final ExpandableBinaryDictionary dictionary = dictionaryGroup.getSubDict(dictName);
|
||||
if (dictionary != null) {
|
||||
dictionary.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void clearUserHistoryDictionary() {
|
||||
clearSubDictionary(Dictionary.TYPE_USER_HISTORY);
|
||||
|
@ -641,8 +708,10 @@ public class DictionaryFacilitator {
|
|||
|
||||
public void addPhraseToContextualDictionary(final String[] phrase, final int probability,
|
||||
final int bigramProbabilityForWords, final int bigramProbabilityForPhrases) {
|
||||
// TODO: we're inserting the phrase into the dictionary for the active language. Rethink
|
||||
// this a bit from a theoretical point of view.
|
||||
final ExpandableBinaryDictionary contextualDict =
|
||||
mDictionaryGroup.getSubDict(Dictionary.TYPE_CONTEXTUAL);
|
||||
getDictionaryGroupForActiveLanguage().getSubDict(Dictionary.TYPE_CONTEXTUAL);
|
||||
if (contextualDict == null) {
|
||||
return;
|
||||
}
|
||||
|
@ -675,7 +744,9 @@ public class DictionaryFacilitator {
|
|||
}
|
||||
|
||||
public void dumpDictionaryForDebug(final String dictName) {
|
||||
final ExpandableBinaryDictionary dictToDump = mDictionaryGroup.getSubDict(dictName);
|
||||
final DictionaryGroup[] dictionaryGroups = mDictionaryGroups;
|
||||
for (final DictionaryGroup dictionaryGroup : dictionaryGroups) {
|
||||
final ExpandableBinaryDictionary dictToDump = dictionaryGroup.getSubDict(dictName);
|
||||
if (dictToDump == null) {
|
||||
Log.e(TAG, "Cannot dump " + dictName + ". "
|
||||
+ "The dictionary is not being used for suggestion or cannot be dumped.");
|
||||
|
@ -683,15 +754,18 @@ public class DictionaryFacilitator {
|
|||
}
|
||||
dictToDump.dumpAllWordsForDebug();
|
||||
}
|
||||
}
|
||||
|
||||
public ArrayList<Pair<String, DictionaryStats>> getStatsOfEnabledSubDicts() {
|
||||
final ArrayList<Pair<String, DictionaryStats>> statsOfEnabledSubDicts = new ArrayList<>();
|
||||
final DictionaryGroup dictionaryGroup = mDictionaryGroup;
|
||||
final DictionaryGroup[] dictionaryGroups = mDictionaryGroups;
|
||||
for (final DictionaryGroup dictionaryGroup : dictionaryGroups) {
|
||||
for (final String dictType : SUB_DICT_TYPES) {
|
||||
final ExpandableBinaryDictionary dictionary = dictionaryGroup.getSubDict(dictType);
|
||||
if (dictionary == null) continue;
|
||||
statsOfEnabledSubDicts.add(new Pair<>(dictType, dictionary.getDictionaryStats()));
|
||||
}
|
||||
}
|
||||
return statsOfEnabledSubDicts;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -84,7 +84,7 @@ public class DictionaryFacilitatorLruCache {
|
|||
private void waitForLoadingMainDictionary(final DictionaryFacilitator dictionaryFacilitator) {
|
||||
for (int i = 0; i < MAX_RETRY_COUNT_FOR_WAITING_FOR_LOADING_DICT; i++) {
|
||||
try {
|
||||
dictionaryFacilitator.waitForLoadingMainDictionary(
|
||||
dictionaryFacilitator.waitForLoadingMainDictionaries(
|
||||
WAIT_FOR_LOADING_MAIN_DICT_IN_MILLISECONDS, TimeUnit.MILLISECONDS);
|
||||
return;
|
||||
} catch (final InterruptedException e) {
|
||||
|
|
|
@ -156,23 +156,25 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
|
|||
}
|
||||
|
||||
private void asyncExecuteTaskWithWriteLock(final Runnable task) {
|
||||
asyncExecuteTaskWithLock(mLock.writeLock(), task);
|
||||
asyncExecuteTaskWithLock(mLock.writeLock(), mDictName /* executorName */, task);
|
||||
}
|
||||
|
||||
private void asyncExecuteTaskWithLock(final Lock lock, final Runnable task) {
|
||||
asyncPreCheckAndExecuteTaskWithLock(lock, null /* preCheckTask */, task);
|
||||
private void asyncExecuteTaskWithLock(final Lock lock, final String executorName,
|
||||
final Runnable task) {
|
||||
asyncPreCheckAndExecuteTaskWithLock(lock, null /* preCheckTask */, executorName, task);
|
||||
}
|
||||
|
||||
private void asyncPreCheckAndExecuteTaskWithWriteLock(
|
||||
final Callable<Boolean> preCheckTask, final Runnable task) {
|
||||
asyncPreCheckAndExecuteTaskWithLock(mLock.writeLock(), preCheckTask, task);
|
||||
asyncPreCheckAndExecuteTaskWithLock(mLock.writeLock(), preCheckTask,
|
||||
mDictName /* executorName */, task);
|
||||
|
||||
}
|
||||
|
||||
// Execute task with lock when the result of preCheckTask is true or preCheckTask is null.
|
||||
private void asyncPreCheckAndExecuteTaskWithLock(final Lock lock,
|
||||
final Callable<Boolean> preCheckTask, final Runnable task) {
|
||||
ExecutorUtils.getExecutor(mDictName).execute(new Runnable() {
|
||||
final Callable<Boolean> preCheckTask, final String executorName, final Runnable task) {
|
||||
ExecutorUtils.getExecutor(executorName).execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (preCheckTask != null) {
|
||||
|
@ -676,10 +678,10 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
|
|||
|
||||
public void dumpAllWordsForDebug() {
|
||||
reloadDictionaryIfRequired();
|
||||
asyncExecuteTaskWithLock(mLock.readLock(), new Runnable() {
|
||||
asyncExecuteTaskWithLock(mLock.readLock(), "dumpAllWordsForDebug", new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Log.d(TAG, "Dump dictionary: " + mDictName);
|
||||
Log.d(TAG, "Dump dictionary: " + mDictName + " for " + mLocale);
|
||||
try {
|
||||
final DictionaryHeader header = mBinaryDictionary.getHeader();
|
||||
Log.d(TAG, "Format version: " + mBinaryDictionary.getFormatVersion());
|
||||
|
|
|
@ -998,7 +998,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
|||
mHandler.cancelUpdateSuggestionStrip();
|
||||
|
||||
mainKeyboardView.setMainDictionaryAvailability(
|
||||
mDictionaryFacilitator.hasInitializedMainDictionary());
|
||||
mDictionaryFacilitator.hasAtLeastOneInitializedMainDictionary());
|
||||
mainKeyboardView.setKeyPreviewPopupEnabled(currentSettingsValues.mKeyPreviewPopupOn,
|
||||
currentSettingsValues.mKeyPreviewPopupDismissDelay);
|
||||
mainKeyboardView.setSlidingKeyInputPreviewEnabled(
|
||||
|
|
|
@ -88,17 +88,17 @@ public class PersonalizationHelperForDictionaryFacilitator {
|
|||
|
||||
/**
|
||||
* Flush personalization dictionaries to dictionary files. Close dictionaries after writing
|
||||
* files except the dictionary that is used for generating suggestions.
|
||||
* files except the dictionaries that is used for generating suggestions.
|
||||
*
|
||||
* @param personalizationDictUsedForSuggestion the personalization dictionary used for
|
||||
* @param personalizationDictsUsedForSuggestion the personalization dictionaries used for
|
||||
* generating suggestions that won't be closed.
|
||||
*/
|
||||
public void flushPersonalizationDictionariesToUpdate(
|
||||
final ExpandableBinaryDictionary personalizationDictUsedForSuggestion) {
|
||||
final HashSet<ExpandableBinaryDictionary> personalizationDictsUsedForSuggestion) {
|
||||
for (final ExpandableBinaryDictionary personalizationDict :
|
||||
mPersonalizationDictsToUpdate.values()) {
|
||||
personalizationDict.asyncFlushBinaryDictionary();
|
||||
if (personalizationDict != personalizationDictUsedForSuggestion) {
|
||||
if (!personalizationDictsUsedForSuggestion.contains(personalizationDict)) {
|
||||
// Close if the dictionary is not being used for suggestion.
|
||||
personalizationDict.close();
|
||||
}
|
||||
|
|
|
@ -157,7 +157,7 @@ public final class Suggest {
|
|||
if (!isCorrectionEnabled || !allowsToBeAutoCorrected || resultsArePredictions
|
||||
|| suggestionResults.isEmpty() || wordComposer.hasDigits()
|
||||
|| wordComposer.isMostlyCaps() || wordComposer.isResumed()
|
||||
|| !mDictionaryFacilitator.hasInitializedMainDictionary()
|
||||
|| !mDictionaryFacilitator.hasAtLeastOneInitializedMainDictionary()
|
||||
|| suggestionResults.first().isKindOf(SuggestedWordInfo.KIND_SHORTCUT)) {
|
||||
// If we don't have a main dictionary, we never want to auto-correct. The reason for
|
||||
// this is, the user may have a contact whose name happens to match a valid word in
|
||||
|
|
|
@ -185,7 +185,7 @@ public final class AndroidSpellCheckerService extends SpellCheckerService
|
|||
try {
|
||||
final DictionaryFacilitator dictionaryFacilitator =
|
||||
mDictionaryFacilitatorCache.get(locale);
|
||||
return dictionaryFacilitator.hasInitializedMainDictionary();
|
||||
return dictionaryFacilitator.hasAtLeastOneInitializedMainDictionary();
|
||||
} finally {
|
||||
mSemaphore.release();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue