Merge "Make reloadMainDict() private."

main
Keisuke Kuroyanagi 2014-01-08 11:03:01 +00:00 committed by Android (Google) Code Review
commit 5742a415f3
3 changed files with 84 additions and 37 deletions

View File

@ -36,6 +36,7 @@ import java.util.HashSet;
import java.util.Locale; import java.util.Locale;
import java.util.Set; import java.util.Set;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
// TODO: Consolidate dictionaries in native code. // TODO: Consolidate dictionaries in native code.
@ -55,8 +56,7 @@ public class DictionaryFacilitatorForSuggest {
private UserHistoryDictionary mUserHistoryDictionary; private UserHistoryDictionary mUserHistoryDictionary;
private PersonalizationDictionary mPersonalizationDictionary; private PersonalizationDictionary mPersonalizationDictionary;
@UsedForTesting private final CountDownLatch mLatchForWaitingLoadingMainDictionary;
private boolean mIsCurrentlyWaitingForMainDictionary = false;
public interface DictionaryInitializationListener { public interface DictionaryInitializationListener {
public void onUpdateMainDictionaryAvailability(boolean isMainDictionaryAvailable); public void onUpdateMainDictionaryAvailability(boolean isMainDictionaryAvailable);
@ -77,12 +77,40 @@ public class DictionaryFacilitatorForSuggest {
final DictionaryFacilitatorForSuggest oldDictionaryFacilitator) { final DictionaryFacilitatorForSuggest oldDictionaryFacilitator) {
mContext = context; mContext = context;
mLocale = locale; mLocale = locale;
mLatchForWaitingLoadingMainDictionary = new CountDownLatch(1);
initForDebug(settingsValues); initForDebug(settingsValues);
reloadMainDict(context, locale, listener); loadMainDict(context, locale, listener);
setUserDictionary(new UserBinaryDictionary(context, locale)); setUserDictionary(new UserBinaryDictionary(context, locale));
resetAdditionalDictionaries(oldDictionaryFacilitator, settingsValues); 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. * Creates instance for when the settings values have been changed.
* *
@ -94,6 +122,7 @@ public class DictionaryFacilitatorForSuggest {
final DictionaryFacilitatorForSuggest oldDictionaryFacilitator) { final DictionaryFacilitatorForSuggest oldDictionaryFacilitator) {
mContext = oldDictionaryFacilitator.mContext; mContext = oldDictionaryFacilitator.mContext;
mLocale = oldDictionaryFacilitator.mLocale; mLocale = oldDictionaryFacilitator.mLocale;
mLatchForWaitingLoadingMainDictionary = new CountDownLatch(0);
initForDebug(settingsValues); initForDebug(settingsValues);
// Transfer main dictionary. // Transfer main dictionary.
setMainDictionary(oldDictionaryFacilitator.mMainDictionary); setMainDictionary(oldDictionaryFacilitator.mMainDictionary);
@ -110,6 +139,7 @@ public class DictionaryFacilitatorForSuggest {
final ArrayList<String> dictionaryTypes, final HashMap<String, File> dictionaryFiles) { final ArrayList<String> dictionaryTypes, final HashMap<String, File> dictionaryFiles) {
mContext = context; mContext = context;
mLocale = locale; mLocale = locale;
mLatchForWaitingLoadingMainDictionary = new CountDownLatch(0);
for (final String dictType : dictionaryTypes) { for (final String dictType : dictionaryTypes) {
if (dictType.equals(Dictionary.TYPE_MAIN)) { if (dictType.equals(Dictionary.TYPE_MAIN)) {
final DictionaryCollection mainDictionary = 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) { final DictionaryInitializationListener listener) {
mIsCurrentlyWaitingForMainDictionary = true;
mMainDictionary = null; mMainDictionary = null;
if (listener != null) { if (listener != null) {
listener.onUpdateMainDictionaryAvailability(hasMainDictionary()); listener.onUpdateMainDictionaryAvailability(hasMainDictionary());
@ -183,7 +212,7 @@ public class DictionaryFacilitatorForSuggest {
if (listener != null) { if (listener != null) {
listener.onUpdateMainDictionaryAvailability(hasMainDictionary()); listener.onUpdateMainDictionaryAvailability(hasMainDictionary());
} }
mIsCurrentlyWaitingForMainDictionary = false; mLatchForWaitingLoadingMainDictionary.countDown();
} }
}.start(); }.start();
} }
@ -194,9 +223,9 @@ public class DictionaryFacilitatorForSuggest {
return null != mMainDictionary && mMainDictionary.isInitialized(); return null != mMainDictionary && mMainDictionary.isInitialized();
} }
@UsedForTesting public void waitForLoadingMainDictionary(final long timeout, final TimeUnit unit)
public boolean isCurrentlyWaitingForMainDictionary() { throws InterruptedException {
return mIsCurrentlyWaitingForMainDictionary; mLatchForWaitingLoadingMainDictionary.await(timeout, unit);
} }
private void setMainDictionary(final Dictionary mainDictionary) { private void setMainDictionary(final Dictionary mainDictionary) {

View File

@ -89,6 +89,7 @@ import java.io.FileDescriptor;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Locale; import java.util.Locale;
import java.util.concurrent.TimeUnit;
/** /**
* Input method implementation for Qwerty'ish keyboard. * Input method implementation for Qwerty'ish keyboard.
@ -519,10 +520,14 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
new DictionaryFacilitatorForSuggest(currentSettingsValues, new DictionaryFacilitatorForSuggest(currentSettingsValues,
oldDictionaryFacilitator); oldDictionaryFacilitator);
// Create Suggest instance with the new dictionary facilitator. // Create Suggest instance with the new dictionary facilitator.
mInputLogic.mSuggest = new Suggest(suggest /* oldSuggest */, dictionaryFacilitator); resetSuggest(new Suggest(suggest /* oldSuggest */, dictionaryFacilitator));
suggest.close(); } else if (suggest == null) {
initSuggestForLocale(locale);
} }
if (currentSettingsValues.mUsePersonalizedDicts) { }
private void refreshPersonalizationDictionarySession() {
if (mSettings.getCurrent().mUsePersonalizedDicts) {
if (mSubtypeSwitcher.isSystemLocaleSameAsLocaleOfAllEnabledSubtypes()) { if (mSubtypeSwitcher.isSystemLocaleSameAsLocaleOfAllEnabledSubtypes()) {
final DictionaryFacilitatorForSuggest dictionaryFacilitator = final DictionaryFacilitatorForSuggest dictionaryFacilitator =
(mInputLogic.mSuggest == null) ? (mInputLogic.mSuggest == null) ?
@ -562,33 +567,41 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
} else { } else {
subtypeLocale = switcherSubtypeLocale; subtypeLocale = switcherSubtypeLocale;
} }
initSuggestForLocale(subtypeLocale);
}
private void initSuggestForLocale(final Locale locale) {
final SettingsValues settingsValues = mSettings.getCurrent(); final SettingsValues settingsValues = mSettings.getCurrent();
final DictionaryFacilitatorForSuggest oldDictionaryFacilitator = final DictionaryFacilitatorForSuggest oldDictionaryFacilitator =
(mInputLogic.mSuggest == null) ? null : mInputLogic.mSuggest.mDictionaryFacilitator; (mInputLogic.mSuggest == null) ? null : mInputLogic.mSuggest.mDictionaryFacilitator;
// Creates new dictionary facilitator for the new locale. // Creates new dictionary facilitator for the new locale.
final DictionaryFacilitatorForSuggest dictionaryFacilitator = final DictionaryFacilitatorForSuggest dictionaryFacilitator =
new DictionaryFacilitatorForSuggest(this /* context */, subtypeLocale, new DictionaryFacilitatorForSuggest(this /* context */, locale,
settingsValues, this /* DictionaryInitializationListener */, settingsValues, this /* DictionaryInitializationListener */,
oldDictionaryFacilitator); oldDictionaryFacilitator);
PersonalizationDictionarySessionRegistrar.onConfigurationChanged( final Suggest newSuggest = new Suggest(locale, dictionaryFacilitator);
this, getResources().getConfiguration(), dictionaryFacilitator);
final Suggest newSuggest = new Suggest(subtypeLocale, dictionaryFacilitator);
if (settingsValues.mCorrectionEnabled) { if (settingsValues.mCorrectionEnabled) {
newSuggest.setAutoCorrectionThreshold(settingsValues.mAutoCorrectionThreshold); 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) { if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
ResearchLogger.getInstance().initDictionary(newSuggest.mDictionaryFacilitator); ResearchLogger.getInstance().initDictionary(newSuggest.mDictionaryFacilitator);
} }
final Suggest oldSuggest = mInputLogic.mSuggest; final Suggest oldSuggest = mInputLogic.mSuggest;
mInputLogic.mSuggest = newSuggest; mInputLogic.mSuggest = newSuggest;
if (oldSuggest != null) oldSuggest.close(); if (oldSuggest != null) oldSuggest.close();
} refreshPersonalizationDictionarySession();
/* package private */ void resetSuggestMainDict() {
final Locale subtypeLocale = mSubtypeSwitcher.getCurrentSubtypeLocale();
mInputLogic.mSuggest.mDictionaryFacilitator.reloadMainDict(this, subtypeLocale,
this /* SuggestInitializationListener */);
} }
@Override @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. // DO NOT USE THIS for any other purpose than testing. This is information private to LatinIME.
@UsedForTesting @UsedForTesting
/* package for test */ boolean isCurrentlyWaitingForMainDictionary() { /* package for test */ void waitForMainDictionary(final long timeout, final TimeUnit unit)
return mInputLogic.mSuggest.mDictionaryFacilitator.isCurrentlyWaitingForMainDictionary(); throws InterruptedException {
mInputLogic.mSuggest.mDictionaryFacilitator.waitForLoadingMainDictionary(timeout, unit);
} }
// DO NOT USE THIS for any other purpose than testing. This can break the keyboard badly. // DO NOT USE THIS for any other purpose than testing. This can break the keyboard badly.
@UsedForTesting @UsedForTesting
/* package for test */ void replaceMainDictionaryForTest(final Locale locale) { /* package for test */ void replaceDictionariesForTest(final Locale locale) {
mInputLogic.mSuggest.mDictionaryFacilitator.reloadMainDict(this, locale, null); 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) { public void debugDumpStateAndCrashWithException(final String context) {

View File

@ -25,6 +25,7 @@ import android.text.InputType;
import android.text.SpannableStringBuilder; import android.text.SpannableStringBuilder;
import android.text.style.CharacterStyle; import android.text.style.CharacterStyle;
import android.text.style.SuggestionSpan; import android.text.style.SuggestionSpan;
import android.util.Log;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
@ -41,8 +42,10 @@ import com.android.inputmethod.latin.utils.LocaleUtils;
import com.android.inputmethod.latin.utils.SubtypeLocaleUtils; import com.android.inputmethod.latin.utils.SubtypeLocaleUtils;
import java.util.Locale; import java.util.Locale;
import java.util.concurrent.TimeUnit;
public class InputTestsBase extends ServiceTestCase<LatinIMEForTests> { public class InputTestsBase extends ServiceTestCase<LatinIMEForTests> {
private static final String TAG = InputTestsBase.class.getSimpleName();
private static final String PREF_DEBUG_MODE = "debug_mode"; private static final String PREF_DEBUG_MODE = "debug_mode";
private static final String PREF_AUTO_CORRECTION_THRESHOLD = "auto_correction_threshold"; private static final String PREF_AUTO_CORRECTION_THRESHOLD = "auto_correction_threshold";
@ -54,6 +57,7 @@ public class InputTestsBase extends ServiceTestCase<LatinIMEForTests> {
protected static final int DELAY_TO_WAIT_FOR_UNDERLINE = 500; protected static final int DELAY_TO_WAIT_FOR_UNDERLINE = 500;
// The message that sets predictions is posted with a 200 ms delay // The message that sets predictions is posted with a 200 ms delay
protected static final int DELAY_TO_WAIT_FOR_PREDICTIONS = 200; 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 LatinIME mLatinIME;
protected Keyboard mKeyboard; protected Keyboard mKeyboard;
@ -260,15 +264,11 @@ public class InputTestsBase extends ServiceTestCase<LatinIMEForTests> {
} }
protected void waitForDictionaryToBeLoaded() { protected void waitForDictionaryToBeLoaded() {
int remainingAttempts = 300; try {
while (remainingAttempts > 0 && mLatinIME.isCurrentlyWaitingForMainDictionary()) { mLatinIME.waitForMainDictionary(
try { TIMEOUT_TO_WAIT_FOR_LOADING_MAIN_DICTIONARY_IN_SECONDS, TimeUnit.SECONDS);
Thread.sleep(200); } catch (InterruptedException e) {
} catch (InterruptedException e) { Log.e(TAG, "Interrupted during waiting for loading main dictionary.", e);
// Don't do much
} finally {
--remainingAttempts;
}
} }
} }
@ -300,8 +300,7 @@ public class InputTestsBase extends ServiceTestCase<LatinIMEForTests> {
final String dictLocale) { final String dictLocale) {
changeLanguage(keyboardLocale); changeLanguage(keyboardLocale);
if (!keyboardLocale.equals(dictLocale)) { if (!keyboardLocale.equals(dictLocale)) {
mLatinIME.replaceMainDictionaryForTest( mLatinIME.replaceDictionariesForTest(LocaleUtils.constructLocaleFromString(dictLocale));
LocaleUtils.constructLocaleFromString(dictLocale));
} }
waitForDictionaryToBeLoaded(); waitForDictionaryToBeLoaded();
} }