From 8732f9c5f992faf58ef17520de198443e0d210af Mon Sep 17 00:00:00 2001 From: Keisuke Kuroyanagi Date: Tue, 17 Dec 2013 19:36:19 +0900 Subject: [PATCH] Enable Personalized dictionaries based on the setting. Bug: 11757851 Change-Id: I83e484195f036e35cbae21fe63148bc9c22bfad7 --- .../android/inputmethod/latin/LatinIME.java | 69 ++------- .../android/inputmethod/latin/Suggest.java | 131 +++++++++++++++++- ...ecayingExpandableBinaryDictionaryBase.java | 4 +- 3 files changed, 135 insertions(+), 69 deletions(-) diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java index 8b466559c..770ea49e6 100644 --- a/java/src/com/android/inputmethod/latin/LatinIME.java +++ b/java/src/com/android/inputmethod/latin/LatinIME.java @@ -77,9 +77,7 @@ import com.android.inputmethod.latin.Suggest.OnGetSuggestedWordsCallback; import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo; import com.android.inputmethod.latin.define.ProductionFlag; 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.PersonalizationHelper; import com.android.inputmethod.latin.personalization.UserHistoryDictionary; import com.android.inputmethod.latin.settings.Settings; import com.android.inputmethod.latin.settings.SettingsActivity; @@ -179,8 +177,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen private boolean mIsMainDictionaryAvailable; private UserBinaryDictionary mUserDictionary; - private UserHistoryDictionary mUserHistoryDictionary; - private PersonalizationDictionary mPersonalizationDictionary; private boolean mIsUserDictionaryAvailable; 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 // be done later inside {@see #initSuggest()} when the reopenDictionaries message is // processed. - if (!mHandler.hasPendingReopenDictionaries()) { - // May need to reset the contacts dictionary depending on the user settings. - resetContactsDictionary(null == mSuggest ? null : mSuggest.getContactsDictionary()); + if (!mHandler.hasPendingReopenDictionaries() && mSuggest != null) { + // May need to reset dictionaries depending on the user settings. + mSuggest.setAdditionalDictionaries(mSuggest /* oldSuggest */, mSettings.getCurrent()); } } @@ -640,63 +636,12 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen mUserDictionary = new UserBinaryDictionary(this, subtypeLocale); mIsUserDictionaryAvailable = mUserDictionary.isEnabled(); newSuggest.setUserDictionary(mUserDictionary); - - mUserHistoryDictionary = PersonalizationHelper.getUserHistoryDictionary( - this, subtypeLocale); - newSuggest.setUserHistoryDictionary(mUserHistoryDictionary); - mPersonalizationDictionary = - PersonalizationHelper.getPersonalizationDictionary(this, subtypeLocale); - newSuggest.setPersonalizationDictionary(mPersonalizationDictionary); - + newSuggest.setAdditionalDictionaries(mSuggest /* oldSuggest */, mSettings.getCurrent()); final Suggest oldSuggest = mSuggest; - resetContactsDictionary(null != oldSuggest ? oldSuggest.getContactsDictionary() : null); mSuggest = newSuggest; 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() { final Locale subtypeLocale = mSubtypeSwitcher.getCurrentSubtypeLocale(); mSuggest.resetMainDict(this, subtypeLocale, this /* SuggestInitializationListener */); @@ -2854,7 +2799,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen final SettingsValues currentSettings = mSettings.getCurrent(); if (!currentSettings.mCorrectionEnabled) return null; - final UserHistoryDictionary userHistoryDictionary = mUserHistoryDictionary; + final UserHistoryDictionary userHistoryDictionary = suggest.getUserHistoryDictionary(); if (userHistoryDictionary == null) return null; final String prevWord = mConnection.getNthPreviousWord(currentSettings, 2); @@ -3069,7 +3014,9 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen } mConnection.deleteSurroundingText(deleteLength, 0); if (!TextUtils.isEmpty(previousWord) && !TextUtils.isEmpty(committedWord)) { - mUserHistoryDictionary.cancelAddingUserHistory(previousWord, committedWord); + if (mSuggest != null) { + mSuggest.cancelAddingUserHistory(previousWord, committedWord); + } } final String stringToCommit = originallyTypedWord + mLastComposedWord.mSeparatorString; if (mSettings.getCurrent().mCurrentLanguageHasSpaces) { diff --git a/java/src/com/android/inputmethod/latin/Suggest.java b/java/src/com/android/inputmethod/latin/Suggest.java index 0ecb41100..32ab1f3df 100644 --- a/java/src/com/android/inputmethod/latin/Suggest.java +++ b/java/src/com/android/inputmethod/latin/Suggest.java @@ -25,8 +25,10 @@ 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.PersonalizationDictionary; +import com.android.inputmethod.latin.personalization.PersonalizationHelper; import com.android.inputmethod.latin.personalization.UserHistoryDictionary; 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.BoundedTreeSet; import com.android.inputmethod.latin.utils.CollectionUtils; @@ -71,7 +73,9 @@ public final class Suggest { CollectionUtils.newConcurrentHashMap(); private HashSet mOnlyDictionarySetForDebug = null; private Dictionary mMainDictionary; - private ContactsBinaryDictionary mContactsDict; + private ContactsBinaryDictionary mContactsDictionary; + private UserHistoryDictionary mUserHistoryDictionary; + private PersonalizationDictionary mPersonalizationDictionary; @UsedForTesting private boolean mIsCurrentlyWaitingForMainDictionary = false; @@ -80,10 +84,14 @@ public final class Suggest { // Locale used for upper- and title-casing words public final Locale mLocale; + private final Context mContext; + public Suggest(final Context context, final Locale locale, final SuggestInitializationListener listener) { initAsynchronously(context, locale, listener); mLocale = locale; + mContext = context; + // TODO: Use SettingsValues instead of Settings. // initialize a debug flag for the personalization if (Settings.readUseOnlyPersonalizationDictionaryForDebug( PreferenceManager.getDefaultSharedPreferences(context))) { @@ -93,10 +101,11 @@ public final class Suggest { } @UsedForTesting - Suggest(final AssetFileAddress[] dictionaryList, final Locale locale) { + Suggest(final Context context, final AssetFileAddress[] dictionaryList, final Locale locale) { final Dictionary mainDict = DictionaryFactory.createDictionaryForTest(dictionaryList, false /* useFullEditDistance */, locale); mLocale = locale; + mContext = context; mMainDictionary = mainDict; addOrReplaceDictionaryInternal(Dictionary.TYPE_MAIN, mainDict); } @@ -163,7 +172,15 @@ public final class Suggest { } public ContactsBinaryDictionary getContactsDictionary() { - return mContactsDict; + return mContactsDictionary; + } + + public UserHistoryDictionary getUserHistoryDictionary() { + return mUserHistoryDictionary; + } + + public PersonalizationDictionary getPersonalizationDictionary() { + return mPersonalizationDictionary; } public ConcurrentHashMap getUnigramDictionaries() { @@ -184,18 +201,120 @@ public final class Suggest { * won't be used. */ public void setContactsDictionary(final ContactsBinaryDictionary contactsDictionary) { - mContactsDict = contactsDictionary; + mContactsDictionary = contactsDictionary; addOrReplaceDictionaryInternal(Dictionary.TYPE_CONTACTS, contactsDictionary); } public void setUserHistoryDictionary(final UserHistoryDictionary userHistoryDictionary) { + mUserHistoryDictionary = userHistoryDictionary; addOrReplaceDictionaryInternal(Dictionary.TYPE_USER_HISTORY, userHistoryDictionary); } public void setPersonalizationDictionary( final PersonalizationDictionary personalizationDictionary) { - addOrReplaceDictionaryInternal(Dictionary.TYPE_PERSONALIZATION, - personalizationDictionary); + mPersonalizationDictionary = 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) { diff --git a/java/src/com/android/inputmethod/latin/personalization/DecayingExpandableBinaryDictionaryBase.java b/java/src/com/android/inputmethod/latin/personalization/DecayingExpandableBinaryDictionaryBase.java index 3a5c11554..701c29023 100644 --- a/java/src/com/android/inputmethod/latin/personalization/DecayingExpandableBinaryDictionaryBase.java +++ b/java/src/com/android/inputmethod/latin/personalization/DecayingExpandableBinaryDictionaryBase.java @@ -55,8 +55,8 @@ public abstract class DecayingExpandableBinaryDictionaryBase extends ExpandableB public static final int REQUIRED_BINARY_DICTIONARY_VERSION = FormatSpec.VERSION4; - /** Locale for which this user history dictionary is storing words */ - private final Locale mLocale; + /** The locale for this dictionary. */ + public final Locale mLocale; private final String mDictName;