Fix a bug with synchronicity of spell checking/user dict

This fixes a race condition that would end up with the spell
checker not finding some words in the user dictionary when it
just booted.

Bug: 5194627
Change-Id: I1ba911cc53e6ae3b111d54a6f91d1d5feef3f5de
This commit is contained in:
Jean Chalard 2011-08-29 18:09:00 +09:00
parent 940514989a
commit f019d505d7
3 changed files with 54 additions and 4 deletions

View file

@ -202,7 +202,11 @@ public class ExpandableDictionary extends Dictionary {
// Currently updating contacts, don't return any results. // Currently updating contacts, don't return any results.
if (mUpdatingDictionary) return; if (mUpdatingDictionary) return;
} }
getWordsInner(codes, callback, proximityInfo);
}
protected final void getWordsInner(final WordComposer codes, final WordCallback callback,
final ProximityInfo proximityInfo) {
mInputLength = codes.size(); mInputLength = codes.size();
if (mCodes.length < mInputLength) mCodes = new int[mInputLength][]; if (mCodes.length < mInputLength) mCodes = new int[mInputLength][];
// Cache the codes so that we don't have to lookup an array list // Cache the codes so that we don't have to lookup an array list
@ -223,8 +227,7 @@ public class ExpandableDictionary extends Dictionary {
if (mRequiresReload) startDictionaryLoadingTaskLocked(); if (mRequiresReload) startDictionaryLoadingTaskLocked();
if (mUpdatingDictionary) return false; if (mUpdatingDictionary) return false;
} }
final int freq = getWordFrequency(word); return getWordFrequency(word) > -1;
return freq > -1;
} }
/** /**
@ -464,7 +467,7 @@ public class ExpandableDictionary extends Dictionary {
} }
/** /**
* Used only for testing purposes * Used for testing purposes and in the spell checker
* This function will wait for loading from database to be done * This function will wait for loading from database to be done
*/ */
void waitForDictionaryLoading() { void waitForDictionaryLoading() {
@ -477,6 +480,11 @@ public class ExpandableDictionary extends Dictionary {
} }
} }
protected final void blockingReloadDictionaryIfRequired() {
reloadDictionaryIfRequired();
waitForDictionaryLoading();
}
// Local to reverseLookUp, but do not allocate each time. // Local to reverseLookUp, but do not allocate each time.
private final char[] mLookedUpString = new char[MAX_WORD_LENGTH]; private final char[] mLookedUpString = new char[MAX_WORD_LENGTH];

View file

@ -0,0 +1,41 @@
/*
* Copyright (C) 2011 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.inputmethod.latin;
import android.content.Context;
import com.android.inputmethod.keyboard.ProximityInfo;
public class SynchronouslyLoadedUserDictionary extends UserDictionary {
public SynchronouslyLoadedUserDictionary(final Context context, final String locale) {
super(context, locale);
}
@Override
public void getWords(final WordComposer codes, final WordCallback callback,
final ProximityInfo proximityInfo) {
blockingReloadDictionaryIfRequired();
getWordsInner(codes, callback, proximityInfo);
}
@Override
public synchronized boolean isValidWord(CharSequence word) {
blockingReloadDictionaryIfRequired();
return getWordFrequency(word) > -1;
}
}

View file

@ -34,6 +34,7 @@ import com.android.inputmethod.latin.Dictionary.WordCallback;
import com.android.inputmethod.latin.DictionaryCollection; import com.android.inputmethod.latin.DictionaryCollection;
import com.android.inputmethod.latin.DictionaryFactory; import com.android.inputmethod.latin.DictionaryFactory;
import com.android.inputmethod.latin.LocaleUtils; import com.android.inputmethod.latin.LocaleUtils;
import com.android.inputmethod.latin.SynchronouslyLoadedUserDictionary;
import com.android.inputmethod.latin.UserDictionary; import com.android.inputmethod.latin.UserDictionary;
import com.android.inputmethod.latin.Utils; import com.android.inputmethod.latin.Utils;
import com.android.inputmethod.latin.WordComposer; import com.android.inputmethod.latin.WordComposer;
@ -156,7 +157,7 @@ public class AndroidSpellCheckerService extends SpellCheckerService {
final String localeStr = locale.toString(); final String localeStr = locale.toString();
Dictionary userDict = mUserDictionaries.get(localeStr); Dictionary userDict = mUserDictionaries.get(localeStr);
if (null == userDict) { if (null == userDict) {
userDict = new UserDictionary(this, localeStr); userDict = new SynchronouslyLoadedUserDictionary(this, localeStr);
mUserDictionaries.put(localeStr, userDict); mUserDictionaries.put(localeStr, userDict);
} }
dictionaryCollection.addDictionary(userDict); dictionaryCollection.addDictionary(userDict);