From 9f1fe87580adc9ca041fc044f88341fa262c82a2 Mon Sep 17 00:00:00 2001 From: Keisuke Kuroyanagi Date: Wed, 8 Jan 2014 18:59:43 +0900 Subject: [PATCH] Make reloadMainDict() private. Bug: 8187060 Change-Id: I852a751d748f39512e62c9cd69748dfbe87b2151 --- .../DictionaryFacilitatorForSuggest.java | 47 ++++++++++++---- .../android/inputmethod/latin/LatinIME.java | 53 +++++++++++++------ .../inputmethod/latin/InputTestsBase.java | 21 ++++---- 3 files changed, 84 insertions(+), 37 deletions(-) diff --git a/java/src/com/android/inputmethod/latin/DictionaryFacilitatorForSuggest.java b/java/src/com/android/inputmethod/latin/DictionaryFacilitatorForSuggest.java index c9bcfe369..aa8bb2ccb 100644 --- a/java/src/com/android/inputmethod/latin/DictionaryFacilitatorForSuggest.java +++ b/java/src/com/android/inputmethod/latin/DictionaryFacilitatorForSuggest.java @@ -36,6 +36,7 @@ import java.util.HashSet; import java.util.Locale; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; // TODO: Consolidate dictionaries in native code. @@ -55,8 +56,7 @@ public class DictionaryFacilitatorForSuggest { private UserHistoryDictionary mUserHistoryDictionary; private PersonalizationDictionary mPersonalizationDictionary; - @UsedForTesting - private boolean mIsCurrentlyWaitingForMainDictionary = false; + private final CountDownLatch mLatchForWaitingLoadingMainDictionary; public interface DictionaryInitializationListener { public void onUpdateMainDictionaryAvailability(boolean isMainDictionaryAvailable); @@ -77,12 +77,40 @@ public class DictionaryFacilitatorForSuggest { final DictionaryFacilitatorForSuggest oldDictionaryFacilitator) { mContext = context; mLocale = locale; + mLatchForWaitingLoadingMainDictionary = new CountDownLatch(1); initForDebug(settingsValues); - reloadMainDict(context, locale, listener); + loadMainDict(context, locale, listener); setUserDictionary(new UserBinaryDictionary(context, locale)); resetAdditionalDictionaries(oldDictionaryFacilitator, settingsValues); } + /** + * Creates instance for reloading the main dict. + * + * @param listener the listener + * @param oldDictionaryFacilitator the instance having old dictionaries. This must not be null. + */ + public DictionaryFacilitatorForSuggest(final DictionaryInitializationListener listener, + final DictionaryFacilitatorForSuggest oldDictionaryFacilitator) { + mContext = oldDictionaryFacilitator.mContext; + mLocale = oldDictionaryFacilitator.mLocale; + mDictionarySubsetForDebug = oldDictionaryFacilitator.mDictionarySubsetForDebug; + mLatchForWaitingLoadingMainDictionary = new CountDownLatch(1); + loadMainDict(mContext, mLocale, listener); + // Transfer user dictionary. + setUserDictionary(oldDictionaryFacilitator.mUserDictionary); + oldDictionaryFacilitator.removeDictionary(Dictionary.TYPE_USER); + // Transfer contacts dictionary. + setContactsDictionary(oldDictionaryFacilitator.mContactsDictionary); + oldDictionaryFacilitator.removeDictionary(Dictionary.TYPE_CONTACTS); + // Transfer user history dictionary. + setUserHistoryDictionary(oldDictionaryFacilitator.mUserHistoryDictionary); + oldDictionaryFacilitator.removeDictionary(Dictionary.TYPE_USER_HISTORY); + // Transfer personalization dictionary. + setPersonalizationDictionary(oldDictionaryFacilitator.mPersonalizationDictionary); + oldDictionaryFacilitator.removeDictionary(Dictionary.TYPE_PERSONALIZATION); + } + /** * Creates instance for when the settings values have been changed. * @@ -94,6 +122,7 @@ public class DictionaryFacilitatorForSuggest { final DictionaryFacilitatorForSuggest oldDictionaryFacilitator) { mContext = oldDictionaryFacilitator.mContext; mLocale = oldDictionaryFacilitator.mLocale; + mLatchForWaitingLoadingMainDictionary = new CountDownLatch(0); initForDebug(settingsValues); // Transfer main dictionary. setMainDictionary(oldDictionaryFacilitator.mMainDictionary); @@ -110,6 +139,7 @@ public class DictionaryFacilitatorForSuggest { final ArrayList dictionaryTypes, final HashMap dictionaryFiles) { mContext = context; mLocale = locale; + mLatchForWaitingLoadingMainDictionary = new CountDownLatch(0); for (final String dictType : dictionaryTypes) { if (dictType.equals(Dictionary.TYPE_MAIN)) { final DictionaryCollection mainDictionary = @@ -167,9 +197,8 @@ public class DictionaryFacilitatorForSuggest { } } - public void reloadMainDict(final Context context, final Locale locale, + private void loadMainDict(final Context context, final Locale locale, final DictionaryInitializationListener listener) { - mIsCurrentlyWaitingForMainDictionary = true; mMainDictionary = null; if (listener != null) { listener.onUpdateMainDictionaryAvailability(hasMainDictionary()); @@ -183,7 +212,7 @@ public class DictionaryFacilitatorForSuggest { if (listener != null) { listener.onUpdateMainDictionaryAvailability(hasMainDictionary()); } - mIsCurrentlyWaitingForMainDictionary = false; + mLatchForWaitingLoadingMainDictionary.countDown(); } }.start(); } @@ -194,9 +223,9 @@ public class DictionaryFacilitatorForSuggest { return null != mMainDictionary && mMainDictionary.isInitialized(); } - @UsedForTesting - public boolean isCurrentlyWaitingForMainDictionary() { - return mIsCurrentlyWaitingForMainDictionary; + public void waitForLoadingMainDictionary(final long timeout, final TimeUnit unit) + throws InterruptedException { + mLatchForWaitingLoadingMainDictionary.await(timeout, unit); } private void setMainDictionary(final Dictionary mainDictionary) { diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java index b7f035747..aadb65192 100644 --- a/java/src/com/android/inputmethod/latin/LatinIME.java +++ b/java/src/com/android/inputmethod/latin/LatinIME.java @@ -89,6 +89,7 @@ import java.io.FileDescriptor; import java.io.PrintWriter; import java.util.ArrayList; import java.util.Locale; +import java.util.concurrent.TimeUnit; /** * Input method implementation for Qwerty'ish keyboard. @@ -519,10 +520,14 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen new DictionaryFacilitatorForSuggest(currentSettingsValues, oldDictionaryFacilitator); // Create Suggest instance with the new dictionary facilitator. - mInputLogic.mSuggest = new Suggest(suggest /* oldSuggest */, dictionaryFacilitator); - suggest.close(); + resetSuggest(new Suggest(suggest /* oldSuggest */, dictionaryFacilitator)); + } else if (suggest == null) { + initSuggestForLocale(locale); } - if (currentSettingsValues.mUsePersonalizedDicts) { + } + + private void refreshPersonalizationDictionarySession() { + if (mSettings.getCurrent().mUsePersonalizedDicts) { if (mSubtypeSwitcher.isSystemLocaleSameAsLocaleOfAllEnabledSubtypes()) { final DictionaryFacilitatorForSuggest dictionaryFacilitator = (mInputLogic.mSuggest == null) ? @@ -562,33 +567,41 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen } else { subtypeLocale = switcherSubtypeLocale; } + initSuggestForLocale(subtypeLocale); + } + private void initSuggestForLocale(final Locale locale) { final SettingsValues settingsValues = mSettings.getCurrent(); final DictionaryFacilitatorForSuggest oldDictionaryFacilitator = (mInputLogic.mSuggest == null) ? null : mInputLogic.mSuggest.mDictionaryFacilitator; // Creates new dictionary facilitator for the new locale. final DictionaryFacilitatorForSuggest dictionaryFacilitator = - new DictionaryFacilitatorForSuggest(this /* context */, subtypeLocale, + new DictionaryFacilitatorForSuggest(this /* context */, locale, settingsValues, this /* DictionaryInitializationListener */, oldDictionaryFacilitator); - PersonalizationDictionarySessionRegistrar.onConfigurationChanged( - this, getResources().getConfiguration(), dictionaryFacilitator); - final Suggest newSuggest = new Suggest(subtypeLocale, dictionaryFacilitator); + final Suggest newSuggest = new Suggest(locale, dictionaryFacilitator); if (settingsValues.mCorrectionEnabled) { newSuggest.setAutoCorrectionThreshold(settingsValues.mAutoCorrectionThreshold); } + resetSuggest(newSuggest); + } + + /* package private */ void resetSuggestMainDict() { + final DictionaryFacilitatorForSuggest oldDictionaryFacilitator = + mInputLogic.mSuggest.mDictionaryFacilitator; + final DictionaryFacilitatorForSuggest dictionaryFacilitator = + new DictionaryFacilitatorForSuggest(this /* listener */, oldDictionaryFacilitator); + resetSuggest(new Suggest(mInputLogic.mSuggest /* oldSuggest */, dictionaryFacilitator)); + } + + private void resetSuggest(final Suggest newSuggest) { if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) { ResearchLogger.getInstance().initDictionary(newSuggest.mDictionaryFacilitator); } final Suggest oldSuggest = mInputLogic.mSuggest; mInputLogic.mSuggest = newSuggest; if (oldSuggest != null) oldSuggest.close(); - } - - /* package private */ void resetSuggestMainDict() { - final Locale subtypeLocale = mSubtypeSwitcher.getCurrentSubtypeLocale(); - mInputLogic.mSuggest.mDictionaryFacilitator.reloadMainDict(this, subtypeLocale, - this /* SuggestInitializationListener */); + refreshPersonalizationDictionarySession(); } @Override @@ -1789,14 +1802,20 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen // DO NOT USE THIS for any other purpose than testing. This is information private to LatinIME. @UsedForTesting - /* package for test */ boolean isCurrentlyWaitingForMainDictionary() { - return mInputLogic.mSuggest.mDictionaryFacilitator.isCurrentlyWaitingForMainDictionary(); + /* package for test */ void waitForMainDictionary(final long timeout, final TimeUnit unit) + throws InterruptedException { + mInputLogic.mSuggest.mDictionaryFacilitator.waitForLoadingMainDictionary(timeout, unit); } // DO NOT USE THIS for any other purpose than testing. This can break the keyboard badly. @UsedForTesting - /* package for test */ void replaceMainDictionaryForTest(final Locale locale) { - mInputLogic.mSuggest.mDictionaryFacilitator.reloadMainDict(this, locale, null); + /* package for test */ void replaceDictionariesForTest(final Locale locale) { + final DictionaryFacilitatorForSuggest oldDictionaryFacilitator = + mInputLogic.mSuggest.mDictionaryFacilitator; + final DictionaryFacilitatorForSuggest dictionaryFacilitator = + new DictionaryFacilitatorForSuggest(this, locale, mSettings.getCurrent(), + this /* listener */, oldDictionaryFacilitator); + resetSuggest(new Suggest(locale, dictionaryFacilitator)); } public void debugDumpStateAndCrashWithException(final String context) { diff --git a/tests/src/com/android/inputmethod/latin/InputTestsBase.java b/tests/src/com/android/inputmethod/latin/InputTestsBase.java index cee73c917..84e8a862c 100644 --- a/tests/src/com/android/inputmethod/latin/InputTestsBase.java +++ b/tests/src/com/android/inputmethod/latin/InputTestsBase.java @@ -25,6 +25,7 @@ import android.text.InputType; import android.text.SpannableStringBuilder; import android.text.style.CharacterStyle; import android.text.style.SuggestionSpan; +import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -41,8 +42,10 @@ import com.android.inputmethod.latin.utils.LocaleUtils; import com.android.inputmethod.latin.utils.SubtypeLocaleUtils; import java.util.Locale; +import java.util.concurrent.TimeUnit; public class InputTestsBase extends ServiceTestCase { + private static final String TAG = InputTestsBase.class.getSimpleName(); private static final String PREF_DEBUG_MODE = "debug_mode"; private static final String PREF_AUTO_CORRECTION_THRESHOLD = "auto_correction_threshold"; @@ -54,6 +57,7 @@ public class InputTestsBase extends ServiceTestCase { protected static final int DELAY_TO_WAIT_FOR_UNDERLINE = 500; // The message that sets predictions is posted with a 200 ms delay protected static final int DELAY_TO_WAIT_FOR_PREDICTIONS = 200; + private final int TIMEOUT_TO_WAIT_FOR_LOADING_MAIN_DICTIONARY_IN_SECONDS = 60; protected LatinIME mLatinIME; protected Keyboard mKeyboard; @@ -260,15 +264,11 @@ public class InputTestsBase extends ServiceTestCase { } protected void waitForDictionaryToBeLoaded() { - int remainingAttempts = 300; - while (remainingAttempts > 0 && mLatinIME.isCurrentlyWaitingForMainDictionary()) { - try { - Thread.sleep(200); - } catch (InterruptedException e) { - // Don't do much - } finally { - --remainingAttempts; - } + try { + mLatinIME.waitForMainDictionary( + TIMEOUT_TO_WAIT_FOR_LOADING_MAIN_DICTIONARY_IN_SECONDS, TimeUnit.SECONDS); + } catch (InterruptedException e) { + Log.e(TAG, "Interrupted during waiting for loading main dictionary.", e); } } @@ -300,8 +300,7 @@ public class InputTestsBase extends ServiceTestCase { final String dictLocale) { changeLanguage(keyboardLocale); if (!keyboardLocale.equals(dictLocale)) { - mLatinIME.replaceMainDictionaryForTest( - LocaleUtils.constructLocaleFromString(dictLocale)); + mLatinIME.replaceDictionariesForTest(LocaleUtils.constructLocaleFromString(dictLocale)); } waitForDictionaryToBeLoaded(); }