Merge "Simplify DictionaryFacilitatorForSuggest to be flexible."

main
Keisuke Kuroyanagi 2014-04-25 04:29:50 +00:00 committed by Android (Google) Code Review
commit a933776bf1
1 changed files with 69 additions and 99 deletions

View File

@ -69,8 +69,9 @@ public class DictionaryFacilitatorForSuggest {
public final Locale mLocale; public final Locale mLocale;
public final ConcurrentHashMap<String, Dictionary> mDictMap = public final ConcurrentHashMap<String, Dictionary> mDictMap =
CollectionUtils.newConcurrentHashMap(); CollectionUtils.newConcurrentHashMap();
// Main dictionary will be asynchronously loaded. public final ConcurrentHashMap<String, ExpandableBinaryDictionary> mSubDictMap =
public Dictionary mMainDictionary; CollectionUtils.newConcurrentHashMap();
// TODO: Remove sub dictionary members and use mSubDictMap.
public final ContactsBinaryDictionary mContactsDictionary; public final ContactsBinaryDictionary mContactsDictionary;
public final UserBinaryDictionary mUserDictionary; public final UserBinaryDictionary mUserDictionary;
public final UserHistoryDictionary mUserHistoryDictionary; public final UserHistoryDictionary mUserHistoryDictionary;
@ -78,7 +79,6 @@ public class DictionaryFacilitatorForSuggest {
public Dictionaries() { public Dictionaries() {
mLocale = null; mLocale = null;
mMainDictionary = null;
mContactsDictionary = null; mContactsDictionary = null;
mUserDictionary = null; mUserDictionary = null;
mUserHistoryDictionary = null; mUserHistoryDictionary = null;
@ -90,57 +90,56 @@ public class DictionaryFacilitatorForSuggest {
final UserHistoryDictionary userHistoryDict, final UserHistoryDictionary userHistoryDict,
final PersonalizationDictionary personalizationDict) { final PersonalizationDictionary personalizationDict) {
mLocale = locale; mLocale = locale;
// Main dictionary can be asynchronously loaded.
setMainDict(mainDict); setMainDict(mainDict);
mContactsDictionary = contactsDict; mContactsDictionary = contactsDict;
if (mContactsDictionary != null) { setSubDict(Dictionary.TYPE_CONTACTS, mContactsDictionary);
mDictMap.put(Dictionary.TYPE_CONTACTS, mContactsDictionary);
}
mUserDictionary = userDict; mUserDictionary = userDict;
if (mUserDictionary != null) { setSubDict(Dictionary.TYPE_USER, mUserDictionary);
mDictMap.put(Dictionary.TYPE_USER, mUserDictionary);
}
mUserHistoryDictionary = userHistoryDict; mUserHistoryDictionary = userHistoryDict;
if (mUserHistoryDictionary != null) { setSubDict(Dictionary.TYPE_USER_HISTORY, mUserHistoryDictionary);
mDictMap.put(Dictionary.TYPE_USER_HISTORY, mUserHistoryDictionary);
}
mPersonalizationDictionary = personalizationDict; mPersonalizationDictionary = personalizationDict;
if (mPersonalizationDictionary != null) { setSubDict(Dictionary.TYPE_PERSONALIZATION, mPersonalizationDictionary);
mDictMap.put(Dictionary.TYPE_PERSONALIZATION, mPersonalizationDictionary); }
private void setSubDict(final String dictType, final ExpandableBinaryDictionary dict) {
if (dict != null) {
mDictMap.put(dictType, dict);
mSubDictMap.put(dictType, dict);
} }
} }
public void setMainDict(final Dictionary mainDict) { public void setMainDict(final Dictionary mainDict) {
mMainDictionary = mainDict;
// Close old dictionary if exists. Main dictionary can be assigned multiple times. // Close old dictionary if exists. Main dictionary can be assigned multiple times.
final Dictionary oldDict; final Dictionary oldDict;
if (mMainDictionary != null) { if (mainDict != null) {
oldDict = mDictMap.put(Dictionary.TYPE_MAIN, mMainDictionary); oldDict = mDictMap.put(Dictionary.TYPE_MAIN, mainDict);
} else { } else {
oldDict = mDictMap.remove(Dictionary.TYPE_MAIN); oldDict = mDictMap.remove(Dictionary.TYPE_MAIN);
} }
if (oldDict != null && mMainDictionary != oldDict) { if (oldDict != null && mainDict != oldDict) {
oldDict.close(); oldDict.close();
} }
} }
public boolean hasMainDict() { public Dictionary getMainDict() {
return mMainDictionary != null; return mDictMap.get(Dictionary.TYPE_MAIN);
} }
public boolean hasContactsDict() { public ExpandableBinaryDictionary getSubDict(final String dictType) {
return mContactsDictionary != null; return mSubDictMap.get(dictType);
} }
public boolean hasUserDict() { public boolean hasDict(final String dictType) {
return mUserDictionary != null; return mDictMap.contains(dictType);
} }
public boolean hasUserHistoryDict() { public void closeDict(final String dictType) {
return mUserHistoryDictionary != null; final Dictionary dict = mDictMap.remove(dictType);
} mSubDictMap.remove(dictType);
if (dict != null) {
public boolean hasPersonalizationDict() { dict.close();
return mPersonalizationDictionary != null; }
} }
} }
@ -172,12 +171,12 @@ public class DictionaryFacilitatorForSuggest {
// The main dictionary will be asynchronously loaded. // The main dictionary will be asynchronously loaded.
newMainDict = null; newMainDict = null;
} else { } else {
newMainDict = mDictionaries.mMainDictionary; newMainDict = mDictionaries.getMainDict();
} }
// Open or move contacts dictionary. // Open or move contacts dictionary.
final ContactsBinaryDictionary newContactsDict; final ContactsBinaryDictionary newContactsDict;
if (!closeContactsDictionary && mDictionaries.hasContactsDict()) { if (!closeContactsDictionary && mDictionaries.hasDict(Dictionary.TYPE_CONTACTS)) {
newContactsDict = mDictionaries.mContactsDictionary; newContactsDict = mDictionaries.mContactsDictionary;
} else if (useContactsDict) { } else if (useContactsDict) {
newContactsDict = new ContactsBinaryDictionary(context, newLocale); newContactsDict = new ContactsBinaryDictionary(context, newLocale);
@ -187,7 +186,7 @@ public class DictionaryFacilitatorForSuggest {
// Open or move user dictionary. // Open or move user dictionary.
final UserBinaryDictionary newUserDictionary; final UserBinaryDictionary newUserDictionary;
if (!closeUserDictionary && mDictionaries.hasUserDict()) { if (!closeUserDictionary && mDictionaries.hasDict(Dictionary.TYPE_USER)) {
newUserDictionary = mDictionaries.mUserDictionary; newUserDictionary = mDictionaries.mUserDictionary;
} else { } else {
newUserDictionary = new UserBinaryDictionary(context, newLocale); newUserDictionary = new UserBinaryDictionary(context, newLocale);
@ -195,7 +194,7 @@ public class DictionaryFacilitatorForSuggest {
// Open or move user history dictionary. // Open or move user history dictionary.
final UserHistoryDictionary newUserHistoryDict; final UserHistoryDictionary newUserHistoryDict;
if (!closeUserHistoryDictionary && mDictionaries.hasUserHistoryDict()) { if (!closeUserHistoryDictionary && mDictionaries.hasDict(Dictionary.TYPE_USER_HISTORY)) {
newUserHistoryDict = mDictionaries.mUserHistoryDictionary; newUserHistoryDict = mDictionaries.mUserHistoryDictionary;
} else if (usePersonalizedDicts) { } else if (usePersonalizedDicts) {
newUserHistoryDict = PersonalizationHelper.getUserHistoryDictionary(context, newLocale); newUserHistoryDict = PersonalizationHelper.getUserHistoryDictionary(context, newLocale);
@ -205,7 +204,8 @@ public class DictionaryFacilitatorForSuggest {
// Open or move personalization dictionary. // Open or move personalization dictionary.
final PersonalizationDictionary newPersonalizationDict; final PersonalizationDictionary newPersonalizationDict;
if (!closePersonalizationDictionary && mDictionaries.hasPersonalizationDict()) { if (!closePersonalizationDictionary
&& mDictionaries.hasDict(Dictionary.TYPE_PERSONALIZATION)) {
newPersonalizationDict = mDictionaries.mPersonalizationDictionary; newPersonalizationDict = mDictionaries.mPersonalizationDictionary;
} else if (usePersonalizedDicts) { } else if (usePersonalizedDicts) {
newPersonalizationDict = newPersonalizationDict =
@ -230,22 +230,23 @@ public class DictionaryFacilitatorForSuggest {
} }
// Clean up old dictionaries. // Clean up old dictionaries.
if (reloadMainDictionary) {
oldDictionaries.closeDict(Dictionary.TYPE_MAIN);
}
if (closeContactsDictionary) {
oldDictionaries.closeDict(Dictionary.TYPE_CONTACTS);
}
if (closeUserDictionary) {
oldDictionaries.closeDict(Dictionary.TYPE_USER);
}
if (closeUserHistoryDictionary) {
oldDictionaries.closeDict(Dictionary.TYPE_USER_HISTORY);
}
if (closePersonalizationDictionary) {
oldDictionaries.closeDict(Dictionary.TYPE_PERSONALIZATION);
}
oldDictionaries.mDictMap.clear(); oldDictionaries.mDictMap.clear();
if (reloadMainDictionary && oldDictionaries.hasMainDict()) { oldDictionaries.mSubDictMap.clear();
oldDictionaries.mMainDictionary.close();
}
if (closeContactsDictionary && oldDictionaries.hasContactsDict()) {
oldDictionaries.mContactsDictionary.close();
}
if (closeUserDictionary && oldDictionaries.hasUserDict()) {
oldDictionaries.mUserDictionary.close();
}
if (closeUserHistoryDictionary && oldDictionaries.hasUserHistoryDict()) {
oldDictionaries.mUserHistoryDictionary.close();
}
if (closePersonalizationDictionary && oldDictionaries.hasPersonalizationDict()) {
oldDictionaries.mPersonalizationDictionary.close();
}
} }
private void asyncReloadMainDictionary(final Context context, final Locale locale, private void asyncReloadMainDictionary(final Context context, final Locale locale,
@ -332,32 +333,20 @@ public class DictionaryFacilitatorForSuggest {
dictionaries = mDictionaries; dictionaries = mDictionaries;
mDictionaries = new Dictionaries(); mDictionaries = new Dictionaries();
} }
if (dictionaries.hasMainDict()) { for (final Dictionary dict : dictionaries.mDictMap.values()) {
dictionaries.mMainDictionary.close(); dict.close();
}
if (dictionaries.hasContactsDict()) {
dictionaries.mContactsDictionary.close();
}
if (dictionaries.hasUserDict()) {
dictionaries.mUserDictionary.close();
}
if (dictionaries.hasUserHistoryDict()) {
dictionaries.mUserHistoryDictionary.close();
}
if (dictionaries.hasPersonalizationDict()) {
dictionaries.mPersonalizationDictionary.close();
} }
} }
// The main dictionary could have been loaded asynchronously. Don't cache the return value // The main dictionary could have been loaded asynchronously. Don't cache the return value
// of this method. // of this method.
public boolean hasInitializedMainDictionary() { public boolean hasInitializedMainDictionary() {
final Dictionaries dictionaries = mDictionaries; final Dictionary mainDict = mDictionaries.getMainDict();
return dictionaries.hasMainDict() && dictionaries.mMainDictionary.isInitialized(); return mainDict != null && mainDict.isInitialized();
} }
public boolean hasPersonalizationDictionary() { public boolean hasPersonalizationDictionary() {
return mDictionaries.hasPersonalizationDict(); return mDictionaries.hasDict(Dictionary.TYPE_PERSONALIZATION);
} }
public void flushPersonalizationDictionary() { public void flushPersonalizationDictionary() {
@ -377,18 +366,9 @@ public class DictionaryFacilitatorForSuggest {
public void waitForLoadingDictionariesForTesting(final long timeout, final TimeUnit unit) public void waitForLoadingDictionariesForTesting(final long timeout, final TimeUnit unit)
throws InterruptedException { throws InterruptedException {
waitForLoadingMainDictionary(timeout, unit); waitForLoadingMainDictionary(timeout, unit);
final Dictionaries dictionaries = mDictionaries; final Map<String, ExpandableBinaryDictionary> dictMap = mDictionaries.mSubDictMap;
if (dictionaries.hasContactsDict()) { for (final ExpandableBinaryDictionary dict : dictMap.values()) {
dictionaries.mContactsDictionary.waitAllTasksForTests(); dict.waitAllTasksForTests();
}
if (dictionaries.hasUserDict()) {
dictionaries.mUserDictionary.waitAllTasksForTests();
}
if (dictionaries.hasUserHistoryDict()) {
dictionaries.mUserHistoryDictionary.waitAllTasksForTests();
}
if (dictionaries.hasPersonalizationDict()) {
dictionaries.mPersonalizationDictionary.waitAllTasksForTests();
} }
} }
@ -411,7 +391,7 @@ public class DictionaryFacilitatorForSuggest {
public void addToUserHistory(final String suggestion, final boolean wasAutoCapitalized, public void addToUserHistory(final String suggestion, final boolean wasAutoCapitalized,
final String previousWord, final int timeStampInSeconds) { final String previousWord, final int timeStampInSeconds) {
final Dictionaries dictionaries = mDictionaries; final Dictionaries dictionaries = mDictionaries;
if (!dictionaries.hasUserHistoryDict()) { if (!dictionaries.hasDict(Dictionary.TYPE_USER_HISTORY)) {
return; return;
} }
final int maxFreq = getMaxFrequency(suggestion); final int maxFreq = getMaxFrequency(suggestion);
@ -439,8 +419,8 @@ public class DictionaryFacilitatorForSuggest {
// History dictionary in order to avoid suggesting them until the dictionary // History dictionary in order to avoid suggesting them until the dictionary
// consolidation is done. // consolidation is done.
// TODO: Remove this hack when ready. // TODO: Remove this hack when ready.
final int lowerCaseFreqInMainDict = dictionaries.hasMainDict() ? final int lowerCaseFreqInMainDict = dictionaries.hasDict(Dictionary.TYPE_MAIN) ?
dictionaries.mMainDictionary.getFrequency(suggestionLowerCase) : dictionaries.getMainDict().getFrequency(suggestionLowerCase) :
Dictionary.NOT_A_PROBABILITY; Dictionary.NOT_A_PROBABILITY;
if (maxFreq < lowerCaseFreqInMainDict if (maxFreq < lowerCaseFreqInMainDict
&& lowerCaseFreqInMainDict >= CAPITALIZED_FORM_MAX_PROBABILITY_FOR_INSERT) { && lowerCaseFreqInMainDict >= CAPITALIZED_FORM_MAX_PROBABILITY_FOR_INSERT) {
@ -492,10 +472,10 @@ public class DictionaryFacilitatorForSuggest {
public boolean isValidMainDictWord(final String word) { public boolean isValidMainDictWord(final String word) {
final Dictionaries dictionaries = mDictionaries; final Dictionaries dictionaries = mDictionaries;
if (TextUtils.isEmpty(word) || !dictionaries.hasMainDict()) { if (TextUtils.isEmpty(word) || !dictionaries.hasDict(Dictionary.TYPE_MAIN)) {
return false; return false;
} }
return dictionaries.mMainDictionary.isValidWord(word); return dictionaries.getMainDict().isValidWord(word);
} }
public boolean isValidWord(final String word, final boolean ignoreCase) { public boolean isValidWord(final String word, final boolean ignoreCase) {
@ -538,7 +518,8 @@ public class DictionaryFacilitatorForSuggest {
public void clearUserHistoryDictionary() { public void clearUserHistoryDictionary() {
final UserHistoryDictionary userHistoryDict = mDictionaries.mUserHistoryDictionary; final ExpandableBinaryDictionary userHistoryDict =
mDictionaries.getSubDict(Dictionary.TYPE_USER_HISTORY);
if (userHistoryDict == null) { if (userHistoryDict == null) {
return; return;
} }
@ -548,8 +529,8 @@ public class DictionaryFacilitatorForSuggest {
// This method gets called only when the IME receives a notification to remove the // This method gets called only when the IME receives a notification to remove the
// personalization dictionary. // personalization dictionary.
public void clearPersonalizationDictionary() { public void clearPersonalizationDictionary() {
final PersonalizationDictionary personalizationDict = final ExpandableBinaryDictionary personalizationDict =
mDictionaries.mPersonalizationDictionary; mDictionaries.getSubDict(Dictionary.TYPE_PERSONALIZATION);
if (personalizationDict == null) { if (personalizationDict == null) {
return; return;
} }
@ -571,18 +552,7 @@ public class DictionaryFacilitatorForSuggest {
} }
public void dumpDictionaryForDebug(final String dictName) { public void dumpDictionaryForDebug(final String dictName) {
final ExpandableBinaryDictionary dictToDump; final ExpandableBinaryDictionary dictToDump = mDictionaries.getSubDict(dictName);
if (dictName.equals(Dictionary.TYPE_CONTACTS)) {
dictToDump = mDictionaries.mContactsDictionary;
} else if (dictName.equals(Dictionary.TYPE_USER)) {
dictToDump = mDictionaries.mUserDictionary;
} else if (dictName.equals(Dictionary.TYPE_USER_HISTORY)) {
dictToDump = mDictionaries.mUserHistoryDictionary;
} else if (dictName.equals(Dictionary.TYPE_PERSONALIZATION)) {
dictToDump = mDictionaries.mPersonalizationDictionary;
} else {
dictToDump = null;
}
if (dictToDump == null) { if (dictToDump == null) {
Log.e(TAG, "Cannot dump " + dictName + ". " Log.e(TAG, "Cannot dump " + dictName + ". "
+ "The dictionary is not being used for suggestion or cannot be dumped."); + "The dictionary is not being used for suggestion or cannot be dumped.");