Add an option to user dict to match more precise locales

This should not be used lightly, as it violates the general
contract of locale, and does kill some legitimate (albeit
alledgedly rare) use patterns.
Currently, the spell checker uses this because it uses a
negative logic: it should match broadly, and when in doubt,
match even more broadly, which is almost never the case of
something that uses the locale.
In other words: don't use this option unless you are
very, VERY sure that's what you want. Hint: it isn't

Bug: 5280929
Change-Id: Ib3cae319c692161d653630038c5bcde1f4340c05
main
Jean Chalard 2011-09-15 14:31:24 +09:00
parent fa52a09f21
commit cfed273922
3 changed files with 41 additions and 6 deletions

View File

@ -23,7 +23,12 @@ import com.android.inputmethod.keyboard.ProximityInfo;
public class SynchronouslyLoadedUserDictionary extends UserDictionary { public class SynchronouslyLoadedUserDictionary extends UserDictionary {
public SynchronouslyLoadedUserDictionary(final Context context, final String locale) { public SynchronouslyLoadedUserDictionary(final Context context, final String locale) {
super(context, locale); this(context, locale, false);
}
public SynchronouslyLoadedUserDictionary(final Context context, final String locale,
final boolean alsoUseMoreRestrictiveLocales) {
super(context, locale, alsoUseMoreRestrictiveLocales);
} }
@Override @Override

View File

@ -29,6 +29,8 @@ import android.text.TextUtils;
import com.android.inputmethod.keyboard.ProximityInfo; import com.android.inputmethod.keyboard.ProximityInfo;
import java.util.Arrays;
public class UserDictionary extends ExpandableDictionary { public class UserDictionary extends ExpandableDictionary {
private static final String[] PROJECTION_QUERY = { private static final String[] PROJECTION_QUERY = {
@ -44,11 +46,18 @@ public class UserDictionary extends ExpandableDictionary {
private ContentObserver mObserver; private ContentObserver mObserver;
final private String mLocale; final private String mLocale;
final private boolean mAlsoUseMoreRestrictiveLocales;
public UserDictionary(Context context, String locale) { public UserDictionary(final Context context, final String locale) {
this(context, locale, false);
}
public UserDictionary(final Context context, final String locale,
final boolean alsoUseMoreRestrictiveLocales) {
super(context, Suggest.DIC_USER); super(context, Suggest.DIC_USER);
if (null == locale) throw new NullPointerException(); // Catch the error earlier if (null == locale) throw new NullPointerException(); // Catch the error earlier
mLocale = locale; mLocale = locale;
mAlsoUseMoreRestrictiveLocales = alsoUseMoreRestrictiveLocales;
// Perform a managed query. The Activity will handle closing and re-querying the cursor // Perform a managed query. The Activity will handle closing and re-querying the cursor
// when needed. // when needed.
ContentResolver cres = context.getContentResolver(); ContentResolver cres = context.getContentResolver();
@ -81,12 +90,13 @@ public class UserDictionary extends ExpandableDictionary {
// For this example, we'll look at the "en_US_POSIX" case. // For this example, we'll look at the "en_US_POSIX" case.
final String[] localeElements = final String[] localeElements =
TextUtils.isEmpty(mLocale) ? new String[] {} : mLocale.split("_", 3); TextUtils.isEmpty(mLocale) ? new String[] {} : mLocale.split("_", 3);
final int length = localeElements.length;
final StringBuilder request = new StringBuilder("(locale is NULL)"); final StringBuilder request = new StringBuilder("(locale is NULL)");
String localeSoFar = ""; String localeSoFar = "";
// At start, localeElements = ["en", "US", "POSIX"] ; localeSoFar = "" ; // At start, localeElements = ["en", "US", "POSIX"] ; localeSoFar = "" ;
// and request = "(locale is NULL)" // and request = "(locale is NULL)"
for (int i = 0; i < localeElements.length; ++i) { for (int i = 0; i < length; ++i) {
// i | localeSoFar | localeElements // i | localeSoFar | localeElements
// 0 | "" | ["en", "US", "POSIX"] // 0 | "" | ["en", "US", "POSIX"]
// 1 | "en_" | ["en", "US", "POSIX"] // 1 | "en_" | ["en", "US", "POSIX"]
@ -101,9 +111,29 @@ public class UserDictionary extends ExpandableDictionary {
} }
// At the end, localeElements = ["en", "en_US", "en_US_POSIX"]; localeSoFar = en_US_POSIX_" // At the end, localeElements = ["en", "en_US", "en_US_POSIX"]; localeSoFar = en_US_POSIX_"
// and request = "(locale is NULL) or (locale=?) or (locale=?) or (locale=?)" // and request = "(locale is NULL) or (locale=?) or (locale=?) or (locale=?)"
Cursor cursor = getContext().getContentResolver()
final String[] requestArguments;
// If length == 3, we already have all the arguments we need (common prefix is meaningless
// inside variants
if (mAlsoUseMoreRestrictiveLocales && length < 3) {
request.append(" or (locale like ?)");
// The following creates an array with one more (null) position
final String[] localeElementsWithMoreRestrictiveLocalesIncluded =
Arrays.copyOf(localeElements, length + 1);
localeElementsWithMoreRestrictiveLocalesIncluded[length] =
localeElements[length - 1] + "_%";
requestArguments = localeElementsWithMoreRestrictiveLocalesIncluded;
// If for example localeElements = ["en"]
// then requestArguments = ["en", "en_%"]
// and request = (locale is NULL) or (locale=?) or (locale like ?)
// If localeElements = ["en", "en_US"]
// then requestArguments = ["en", "en_US", "en_US_%"]
} else {
requestArguments = localeElements;
}
final Cursor cursor = getContext().getContentResolver()
.query(Words.CONTENT_URI, PROJECTION_QUERY, request.toString(), .query(Words.CONTENT_URI, PROJECTION_QUERY, request.toString(),
localeElements, null); requestArguments, null);
addWords(cursor); addWords(cursor);
} }

View File

@ -237,7 +237,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 SynchronouslyLoadedUserDictionary(this, localeStr); userDict = new SynchronouslyLoadedUserDictionary(this, localeStr, true);
mUserDictionaries.put(localeStr, userDict); mUserDictionaries.put(localeStr, userDict);
} }
dictionaryCollection.addDictionary(userDict); dictionaryCollection.addDictionary(userDict);