Merge "Enable Personalized dictionaries based on the setting."

main
Keisuke Kuroyanagi 2013-12-17 10:40:29 +00:00 committed by Android (Google) Code Review
commit 1f5a3faf76
3 changed files with 135 additions and 69 deletions

View File

@ -77,9 +77,7 @@ import com.android.inputmethod.latin.Suggest.OnGetSuggestedWordsCallback;
import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo; import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
import com.android.inputmethod.latin.define.ProductionFlag; import com.android.inputmethod.latin.define.ProductionFlag;
import com.android.inputmethod.latin.personalization.DictionaryDecayBroadcastReciever; import com.android.inputmethod.latin.personalization.DictionaryDecayBroadcastReciever;
import com.android.inputmethod.latin.personalization.PersonalizationDictionary;
import com.android.inputmethod.latin.personalization.PersonalizationDictionarySessionRegister; import com.android.inputmethod.latin.personalization.PersonalizationDictionarySessionRegister;
import com.android.inputmethod.latin.personalization.PersonalizationHelper;
import com.android.inputmethod.latin.personalization.UserHistoryDictionary; import com.android.inputmethod.latin.personalization.UserHistoryDictionary;
import com.android.inputmethod.latin.settings.Settings; import com.android.inputmethod.latin.settings.Settings;
import com.android.inputmethod.latin.settings.SettingsActivity; import com.android.inputmethod.latin.settings.SettingsActivity;
@ -179,8 +177,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
private boolean mIsMainDictionaryAvailable; private boolean mIsMainDictionaryAvailable;
private UserBinaryDictionary mUserDictionary; private UserBinaryDictionary mUserDictionary;
private UserHistoryDictionary mUserHistoryDictionary;
private PersonalizationDictionary mPersonalizationDictionary;
private boolean mIsUserDictionaryAvailable; private boolean mIsUserDictionaryAvailable;
private LastComposedWord mLastComposedWord = LastComposedWord.NOT_A_COMPOSED_WORD; private LastComposedWord mLastComposedWord = LastComposedWord.NOT_A_COMPOSED_WORD;
@ -592,9 +588,9 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
// the layout; at this time, we need to skip resetting the contacts dictionary. It will // the layout; at this time, we need to skip resetting the contacts dictionary. It will
// be done later inside {@see #initSuggest()} when the reopenDictionaries message is // be done later inside {@see #initSuggest()} when the reopenDictionaries message is
// processed. // processed.
if (!mHandler.hasPendingReopenDictionaries()) { if (!mHandler.hasPendingReopenDictionaries() && mSuggest != null) {
// May need to reset the contacts dictionary depending on the user settings. // May need to reset dictionaries depending on the user settings.
resetContactsDictionary(null == mSuggest ? null : mSuggest.getContactsDictionary()); mSuggest.setAdditionalDictionaries(mSuggest /* oldSuggest */, mSettings.getCurrent());
} }
} }
@ -640,63 +636,12 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
mUserDictionary = new UserBinaryDictionary(this, subtypeLocale); mUserDictionary = new UserBinaryDictionary(this, subtypeLocale);
mIsUserDictionaryAvailable = mUserDictionary.isEnabled(); mIsUserDictionaryAvailable = mUserDictionary.isEnabled();
newSuggest.setUserDictionary(mUserDictionary); newSuggest.setUserDictionary(mUserDictionary);
newSuggest.setAdditionalDictionaries(mSuggest /* oldSuggest */, mSettings.getCurrent());
mUserHistoryDictionary = PersonalizationHelper.getUserHistoryDictionary(
this, subtypeLocale);
newSuggest.setUserHistoryDictionary(mUserHistoryDictionary);
mPersonalizationDictionary =
PersonalizationHelper.getPersonalizationDictionary(this, subtypeLocale);
newSuggest.setPersonalizationDictionary(mPersonalizationDictionary);
final Suggest oldSuggest = mSuggest; final Suggest oldSuggest = mSuggest;
resetContactsDictionary(null != oldSuggest ? oldSuggest.getContactsDictionary() : null);
mSuggest = newSuggest; mSuggest = newSuggest;
if (oldSuggest != null) oldSuggest.close(); if (oldSuggest != null) oldSuggest.close();
} }
/**
* Resets the contacts dictionary in mSuggest according to the user settings.
*
* This method takes an optional contacts dictionary to use when the locale hasn't changed
* since the contacts dictionary can be opened or closed as necessary depending on the settings.
*
* @param oldContactsDictionary an optional dictionary to use, or null
*/
private void resetContactsDictionary(final ContactsBinaryDictionary oldContactsDictionary) {
final Suggest suggest = mSuggest;
final boolean shouldSetDictionary =
(null != suggest && mSettings.getCurrent().mUseContactsDict);
final ContactsBinaryDictionary dictionaryToUse;
if (!shouldSetDictionary) {
// Make sure the dictionary is closed. If it is already closed, this is a no-op,
// so it's safe to call it anyways.
if (null != oldContactsDictionary) oldContactsDictionary.close();
dictionaryToUse = null;
} else {
final Locale locale = mSubtypeSwitcher.getCurrentSubtypeLocale();
if (null != oldContactsDictionary) {
if (!oldContactsDictionary.mLocale.equals(locale)) {
// If the locale has changed then recreate the contacts dictionary. This
// allows locale dependent rules for handling bigram name predictions.
oldContactsDictionary.close();
dictionaryToUse = new ContactsBinaryDictionary(this, locale);
} else {
// Make sure the old contacts dictionary is opened. If it is already open,
// this is a no-op, so it's safe to call it anyways.
oldContactsDictionary.reopen(this);
dictionaryToUse = oldContactsDictionary;
}
} else {
dictionaryToUse = new ContactsBinaryDictionary(this, locale);
}
}
if (null != suggest) {
suggest.setContactsDictionary(dictionaryToUse);
}
}
/* package private */ void resetSuggestMainDict() { /* package private */ void resetSuggestMainDict() {
final Locale subtypeLocale = mSubtypeSwitcher.getCurrentSubtypeLocale(); final Locale subtypeLocale = mSubtypeSwitcher.getCurrentSubtypeLocale();
mSuggest.resetMainDict(this, subtypeLocale, this /* SuggestInitializationListener */); mSuggest.resetMainDict(this, subtypeLocale, this /* SuggestInitializationListener */);
@ -2861,7 +2806,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
final SettingsValues currentSettings = mSettings.getCurrent(); final SettingsValues currentSettings = mSettings.getCurrent();
if (!currentSettings.mCorrectionEnabled) return null; if (!currentSettings.mCorrectionEnabled) return null;
final UserHistoryDictionary userHistoryDictionary = mUserHistoryDictionary; final UserHistoryDictionary userHistoryDictionary = suggest.getUserHistoryDictionary();
if (userHistoryDictionary == null) return null; if (userHistoryDictionary == null) return null;
final String prevWord = mConnection.getNthPreviousWord(currentSettings, 2); final String prevWord = mConnection.getNthPreviousWord(currentSettings, 2);
@ -3076,7 +3021,9 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
} }
mConnection.deleteSurroundingText(deleteLength, 0); mConnection.deleteSurroundingText(deleteLength, 0);
if (!TextUtils.isEmpty(previousWord) && !TextUtils.isEmpty(committedWord)) { if (!TextUtils.isEmpty(previousWord) && !TextUtils.isEmpty(committedWord)) {
mUserHistoryDictionary.cancelAddingUserHistory(previousWord, committedWord); if (mSuggest != null) {
mSuggest.cancelAddingUserHistory(previousWord, committedWord);
}
} }
final String stringToCommit = originallyTypedWord + mLastComposedWord.mSeparatorString; final String stringToCommit = originallyTypedWord + mLastComposedWord.mSeparatorString;
if (mSettings.getCurrent().mCurrentLanguageHasSpaces) { if (mSettings.getCurrent().mCurrentLanguageHasSpaces) {

View File

@ -25,8 +25,10 @@ import com.android.inputmethod.annotations.UsedForTesting;
import com.android.inputmethod.keyboard.ProximityInfo; import com.android.inputmethod.keyboard.ProximityInfo;
import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo; import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
import com.android.inputmethod.latin.personalization.PersonalizationDictionary; import com.android.inputmethod.latin.personalization.PersonalizationDictionary;
import com.android.inputmethod.latin.personalization.PersonalizationHelper;
import com.android.inputmethod.latin.personalization.UserHistoryDictionary; import com.android.inputmethod.latin.personalization.UserHistoryDictionary;
import com.android.inputmethod.latin.settings.Settings; import com.android.inputmethod.latin.settings.Settings;
import com.android.inputmethod.latin.settings.SettingsValues;
import com.android.inputmethod.latin.utils.AutoCorrectionUtils; import com.android.inputmethod.latin.utils.AutoCorrectionUtils;
import com.android.inputmethod.latin.utils.BoundedTreeSet; import com.android.inputmethod.latin.utils.BoundedTreeSet;
import com.android.inputmethod.latin.utils.CollectionUtils; import com.android.inputmethod.latin.utils.CollectionUtils;
@ -71,7 +73,9 @@ public final class Suggest {
CollectionUtils.newConcurrentHashMap(); CollectionUtils.newConcurrentHashMap();
private HashSet<String> mOnlyDictionarySetForDebug = null; private HashSet<String> mOnlyDictionarySetForDebug = null;
private Dictionary mMainDictionary; private Dictionary mMainDictionary;
private ContactsBinaryDictionary mContactsDict; private ContactsBinaryDictionary mContactsDictionary;
private UserHistoryDictionary mUserHistoryDictionary;
private PersonalizationDictionary mPersonalizationDictionary;
@UsedForTesting @UsedForTesting
private boolean mIsCurrentlyWaitingForMainDictionary = false; private boolean mIsCurrentlyWaitingForMainDictionary = false;
@ -80,10 +84,14 @@ public final class Suggest {
// Locale used for upper- and title-casing words // Locale used for upper- and title-casing words
public final Locale mLocale; public final Locale mLocale;
private final Context mContext;
public Suggest(final Context context, final Locale locale, public Suggest(final Context context, final Locale locale,
final SuggestInitializationListener listener) { final SuggestInitializationListener listener) {
initAsynchronously(context, locale, listener); initAsynchronously(context, locale, listener);
mLocale = locale; mLocale = locale;
mContext = context;
// TODO: Use SettingsValues instead of Settings.
// initialize a debug flag for the personalization // initialize a debug flag for the personalization
if (Settings.readUseOnlyPersonalizationDictionaryForDebug( if (Settings.readUseOnlyPersonalizationDictionaryForDebug(
PreferenceManager.getDefaultSharedPreferences(context))) { PreferenceManager.getDefaultSharedPreferences(context))) {
@ -93,10 +101,11 @@ public final class Suggest {
} }
@UsedForTesting @UsedForTesting
Suggest(final AssetFileAddress[] dictionaryList, final Locale locale) { Suggest(final Context context, final AssetFileAddress[] dictionaryList, final Locale locale) {
final Dictionary mainDict = DictionaryFactory.createDictionaryForTest(dictionaryList, final Dictionary mainDict = DictionaryFactory.createDictionaryForTest(dictionaryList,
false /* useFullEditDistance */, locale); false /* useFullEditDistance */, locale);
mLocale = locale; mLocale = locale;
mContext = context;
mMainDictionary = mainDict; mMainDictionary = mainDict;
addOrReplaceDictionaryInternal(Dictionary.TYPE_MAIN, mainDict); addOrReplaceDictionaryInternal(Dictionary.TYPE_MAIN, mainDict);
} }
@ -163,7 +172,15 @@ public final class Suggest {
} }
public ContactsBinaryDictionary getContactsDictionary() { public ContactsBinaryDictionary getContactsDictionary() {
return mContactsDict; return mContactsDictionary;
}
public UserHistoryDictionary getUserHistoryDictionary() {
return mUserHistoryDictionary;
}
public PersonalizationDictionary getPersonalizationDictionary() {
return mPersonalizationDictionary;
} }
public ConcurrentHashMap<String, Dictionary> getUnigramDictionaries() { public ConcurrentHashMap<String, Dictionary> getUnigramDictionaries() {
@ -184,18 +201,120 @@ public final class Suggest {
* won't be used. * won't be used.
*/ */
public void setContactsDictionary(final ContactsBinaryDictionary contactsDictionary) { public void setContactsDictionary(final ContactsBinaryDictionary contactsDictionary) {
mContactsDict = contactsDictionary; mContactsDictionary = contactsDictionary;
addOrReplaceDictionaryInternal(Dictionary.TYPE_CONTACTS, contactsDictionary); addOrReplaceDictionaryInternal(Dictionary.TYPE_CONTACTS, contactsDictionary);
} }
public void setUserHistoryDictionary(final UserHistoryDictionary userHistoryDictionary) { public void setUserHistoryDictionary(final UserHistoryDictionary userHistoryDictionary) {
mUserHistoryDictionary = userHistoryDictionary;
addOrReplaceDictionaryInternal(Dictionary.TYPE_USER_HISTORY, userHistoryDictionary); addOrReplaceDictionaryInternal(Dictionary.TYPE_USER_HISTORY, userHistoryDictionary);
} }
public void setPersonalizationDictionary( public void setPersonalizationDictionary(
final PersonalizationDictionary personalizationDictionary) { final PersonalizationDictionary personalizationDictionary) {
addOrReplaceDictionaryInternal(Dictionary.TYPE_PERSONALIZATION, mPersonalizationDictionary = personalizationDictionary;
personalizationDictionary); addOrReplaceDictionaryInternal(Dictionary.TYPE_PERSONALIZATION, personalizationDictionary);
}
/**
* Set dictionaries that can be turned off according to the user settings.
*
* @param oldSuggest the instance having old dictionaries
* @param settingsValues current SettingsValues
*/
public void setAdditionalDictionaries(final Suggest oldSuggest,
final SettingsValues settingsValues) {
// Contacts dictionary
resetContactsDictionary(null != oldSuggest ? oldSuggest.getContactsDictionary() : null,
settingsValues);
// User history dictionary & Personalization dictionary
resetPersonalizedDictionaries(oldSuggest, settingsValues);
}
/**
* Set the user history dictionary and personalization dictionary according to the user
* settings.
*
* @param oldSuggest the instance that has been used
* @param settingsValues current settingsValues
*/
// TODO: Consolidate resetPersonalizedDictionaries() and resetContactsDictionary(). Call up the
// new method for each dictionary.
private void resetPersonalizedDictionaries(final Suggest oldSuggest,
final SettingsValues settingsValues) {
final boolean shouldSetDictionaries = settingsValues.mUsePersonalizedDicts;
final UserHistoryDictionary oldUserHistoryDictionary = (null == oldSuggest) ? null :
oldSuggest.getUserHistoryDictionary();
final PersonalizationDictionary oldPersonalizationDictionary = (null == oldSuggest) ? null :
oldSuggest.getPersonalizationDictionary();
final UserHistoryDictionary userHistoryDictionaryToUse;
final PersonalizationDictionary personalizationDictionaryToUse;
if (!shouldSetDictionaries) {
userHistoryDictionaryToUse = null;
personalizationDictionaryToUse = null;
} else {
if (null != oldUserHistoryDictionary
&& oldUserHistoryDictionary.mLocale.equals(mLocale)) {
userHistoryDictionaryToUse = oldUserHistoryDictionary;
} else {
userHistoryDictionaryToUse =
PersonalizationHelper.getUserHistoryDictionary(mContext, mLocale);
}
if (null != oldPersonalizationDictionary
&& oldPersonalizationDictionary.mLocale.equals(mLocale)) {
personalizationDictionaryToUse = oldPersonalizationDictionary;
} else {
personalizationDictionaryToUse =
PersonalizationHelper.getPersonalizationDictionary(mContext, mLocale);
}
}
setUserHistoryDictionary(userHistoryDictionaryToUse);
setPersonalizationDictionary(personalizationDictionaryToUse);
}
/**
* Set the contacts dictionary according to the user settings.
*
* This method takes an optional contacts dictionary to use when the locale hasn't changed
* since the contacts dictionary can be opened or closed as necessary depending on the settings.
*
* @param oldContactsDictionary an optional dictionary to use, or null
* @param settingsValues current settingsValues
*/
private void resetContactsDictionary(final ContactsBinaryDictionary oldContactsDictionary,
final SettingsValues settingsValues) {
final boolean shouldSetDictionary = settingsValues.mUseContactsDict;
final ContactsBinaryDictionary dictionaryToUse;
if (!shouldSetDictionary) {
// Make sure the dictionary is closed. If it is already closed, this is a no-op,
// so it's safe to call it anyways.
if (null != oldContactsDictionary) oldContactsDictionary.close();
dictionaryToUse = null;
} else {
if (null != oldContactsDictionary) {
if (!oldContactsDictionary.mLocale.equals(mLocale)) {
// If the locale has changed then recreate the contacts dictionary. This
// allows locale dependent rules for handling bigram name predictions.
oldContactsDictionary.close();
dictionaryToUse = new ContactsBinaryDictionary(mContext, mLocale);
} else {
// Make sure the old contacts dictionary is opened. If it is already open,
// this is a no-op, so it's safe to call it anyways.
oldContactsDictionary.reopen(mContext);
dictionaryToUse = oldContactsDictionary;
}
} else {
dictionaryToUse = new ContactsBinaryDictionary(mContext, mLocale);
}
}
setContactsDictionary(dictionaryToUse);
}
public void cancelAddingUserHistory(final String previousWord, final String committedWord) {
if (mUserHistoryDictionary != null) {
mUserHistoryDictionary.cancelAddingUserHistory(previousWord, committedWord);
}
} }
public void setAutoCorrectionThreshold(float threshold) { public void setAutoCorrectionThreshold(float threshold) {

View File

@ -55,8 +55,8 @@ public abstract class DecayingExpandableBinaryDictionaryBase extends ExpandableB
public static final int REQUIRED_BINARY_DICTIONARY_VERSION = FormatSpec.VERSION4; public static final int REQUIRED_BINARY_DICTIONARY_VERSION = FormatSpec.VERSION4;
/** Locale for which this user history dictionary is storing words */ /** The locale for this dictionary. */
private final Locale mLocale; public final Locale mLocale;
private final String mDictName; private final String mDictName;