Make LocaleUtils.constructLocaleFromString as @Nonnull

Change-Id: I82d574c67b25239510f3ecc8882efe46e40677eb
main
Tadashi G. Takaoka 2014-11-17 18:07:35 +09:00
parent a94733cbca
commit ebe5b42f71
14 changed files with 144 additions and 100 deletions

View File

@ -104,7 +104,8 @@ public final class LocaleUtils {
* @param testedLocale the locale to test. * @param testedLocale the locale to test.
* @return a constant that measures how well the tested locale matches the reference locale. * @return a constant that measures how well the tested locale matches the reference locale.
*/ */
public static int getMatchLevel(final String referenceLocale, final String testedLocale) { public static int getMatchLevel(@Nullable final String referenceLocale,
@Nullable final String testedLocale) {
if (StringUtils.isEmpty(referenceLocale)) { if (StringUtils.isEmpty(referenceLocale)) {
return StringUtils.isEmpty(testedLocale) ? LOCALE_FULL_MATCH : LOCALE_ANY_MATCH; return StringUtils.isEmpty(testedLocale) ? LOCALE_FULL_MATCH : LOCALE_ANY_MATCH;
} }
@ -167,11 +168,8 @@ public final class LocaleUtils {
* @param localeString a string specification of a locale, in a format of "ll_cc_variant" where * @param localeString a string specification of a locale, in a format of "ll_cc_variant" where
* "ll" is a language code, "cc" is a country code. * "ll" is a language code, "cc" is a country code.
*/ */
@Nullable @Nonnull
public static Locale constructLocaleFromString(@Nullable final String localeString) { public static Locale constructLocaleFromString(@Nonnull final String localeString) {
if (localeString == null) {
return null;
}
synchronized (sLocaleCache) { synchronized (sLocaleCache) {
if (sLocaleCache.containsKey(localeString)) { if (sLocaleCache.containsKey(localeString)) {
return sLocaleCache.get(localeString); return sLocaleCache.get(localeString);

View File

@ -118,11 +118,7 @@ public final class SuggestionSpanUtils {
if (TextUtils.isEmpty(localeString)) { if (TextUtils.isEmpty(localeString)) {
continue; continue;
} }
final Locale locale = LocaleUtils.constructLocaleFromString(localeString); return LocaleUtils.constructLocaleFromString(localeString);
if (locale == null) {
continue;
}
return locale;
} }
return null; return null;
} }

View File

@ -22,6 +22,7 @@ import android.app.Service;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.os.IBinder; import android.os.IBinder;
import android.util.Log;
import android.widget.Toast; import android.widget.Toast;
import com.android.inputmethod.latin.R; import com.android.inputmethod.latin.R;
@ -33,6 +34,8 @@ import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import javax.annotation.Nonnull;
/** /**
* Service that handles background tasks for the dictionary provider. * Service that handles background tasks for the dictionary provider.
* *
@ -51,6 +54,8 @@ import java.util.concurrent.TimeUnit;
* to access, and mark the current state as such. * to access, and mark the current state as such.
*/ */
public final class DictionaryService extends Service { public final class DictionaryService extends Service {
private static final String TAG = DictionaryService.class.getSimpleName();
/** /**
* The package name, to use in the intent actions. * The package name, to use in the intent actions.
*/ */
@ -156,9 +161,14 @@ public final class DictionaryService extends Service {
final int startId) { final int startId) {
final DictionaryService self = this; final DictionaryService self = this;
if (SHOW_DOWNLOAD_TOAST_INTENT_ACTION.equals(intent.getAction())) { if (SHOW_DOWNLOAD_TOAST_INTENT_ACTION.equals(intent.getAction())) {
// This is a UI action, it can't be run in another thread final String localeString = intent.getStringExtra(LOCALE_INTENT_ARGUMENT);
showStartDownloadingToast(this, LocaleUtils.constructLocaleFromString( if (localeString == null) {
intent.getStringExtra(LOCALE_INTENT_ARGUMENT))); Log.e(TAG, "Received " + intent.getAction() + " without locale; skipped");
} else {
// This is a UI action, it can't be run in another thread
showStartDownloadingToast(
this, LocaleUtils.constructLocaleFromString(localeString));
}
} else { } else {
// If it's a command that does not require UI, arrange for the work to be done on a // If it's a command that does not require UI, arrange for the work to be done on a
// separate thread, so that we can return right away. The executor will spawn a thread // separate thread, so that we can return right away. The executor will spawn a thread
@ -245,7 +255,8 @@ public final class DictionaryService extends Service {
/** /**
* Shows a toast informing the user that an automatic dictionary download is starting. * Shows a toast informing the user that an automatic dictionary download is starting.
*/ */
private static void showStartDownloadingToast(final Context context, final Locale locale) { private static void showStartDownloadingToast(final Context context,
@Nonnull final Locale locale) {
final String toastText = String.format( final String toastText = String.format(
context.getString(R.string.toast_downloading_suggestions), context.getString(R.string.toast_downloading_suggestions),
locale.getDisplayName()); locale.getDisplayName());

View File

@ -28,7 +28,7 @@ import com.android.inputmethod.annotations.ExternallyReferenced;
import com.android.inputmethod.latin.R; import com.android.inputmethod.latin.R;
import com.android.inputmethod.latin.common.LocaleUtils; import com.android.inputmethod.latin.common.LocaleUtils;
import java.util.Locale; import javax.annotation.Nullable;
/** /**
* This implements the dialog for asking the user whether it's okay to download dictionaries over * This implements the dialog for asking the user whether it's okay to download dictionaries over
@ -54,11 +54,11 @@ public final class DownloadOverMeteredDialog extends Activity {
setTexts(localeString, size); setTexts(localeString, size);
} }
private void setTexts(final String localeString, final long size) { private void setTexts(@Nullable final String localeString, final long size) {
final String promptFormat = getString(R.string.should_download_over_metered_prompt); final String promptFormat = getString(R.string.should_download_over_metered_prompt);
final String allowButtonFormat = getString(R.string.download_over_metered); final String allowButtonFormat = getString(R.string.download_over_metered);
final Locale locale = LocaleUtils.constructLocaleFromString(localeString); final String language = (null == localeString) ? ""
final String language = (null == locale ? "" : locale.getDisplayLanguage()); : LocaleUtils.constructLocaleFromString(localeString).getDisplayLanguage();
final TextView prompt = (TextView)findViewById(R.id.download_over_metered_prompt); final TextView prompt = (TextView)findViewById(R.id.download_over_metered_prompt);
prompt.setText(Html.fromHtml(String.format(promptFormat, language))); prompt.setText(Html.fromHtml(String.format(promptFormat, language)));
final Button allowButton = (Button)findViewById(R.id.allow_button); final Button allowButton = (Button)findViewById(R.id.allow_button);

View File

@ -57,7 +57,6 @@ import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Locale;
import java.util.Set; import java.util.Set;
import java.util.TreeSet; import java.util.TreeSet;
@ -880,8 +879,8 @@ public final class UpdateHandler {
// None of those are expected to happen, but just in case... // None of those are expected to happen, but just in case...
if (null == notificationIntent || null == notificationManager) return; if (null == notificationIntent || null == notificationManager) return;
final Locale locale = LocaleUtils.constructLocaleFromString(localeString); final String language = (null == localeString) ? ""
final String language = (null == locale ? "" : locale.getDisplayLanguage()); : LocaleUtils.constructLocaleFromString(localeString).getDisplayLanguage();
final String titleFormat = context.getString(R.string.dict_available_notification_title); final String titleFormat = context.getString(R.string.dict_available_notification_title);
final String notificationTitle = String.format(titleFormat, language); final String notificationTitle = String.format(titleFormat, language);
final Notification.Builder builder = new Notification.Builder(context) final Notification.Builder builder = new Notification.Builder(context)

View File

@ -257,7 +257,7 @@ public class DictionaryFacilitator {
return mMostProbableDictionaryGroup; return mMostProbableDictionaryGroup;
} }
public void switchMostProbableLanguage(final Locale locale) { public void switchMostProbableLanguage(@Nullable final Locale locale) {
if (null == locale) { if (null == locale) {
// In many cases, there is no locale to a committed word. For example, a typed word // In many cases, there is no locale to a committed word. For example, a typed word
// that does not auto-correct has no locale. In this case we simply do not change // that does not auto-correct has no locale. In this case we simply do not change

View File

@ -101,25 +101,23 @@ public final class DictionaryFactory {
} }
final String wordlistId = final String wordlistId =
DictionaryInfoUtils.getWordListIdFromFileName(new File(f.mFilename).getName()); DictionaryInfoUtils.getWordListIdFromFileName(new File(f.mFilename).getName());
if (null != wordlistId) { // TODO: this is a reasonable last resort, but it is suboptimal.
// TODO: this is a reasonable last resort, but it is suboptimal. // The following will remove the entry for this dictionary with the dictionary
// The following will remove the entry for this dictionary with the dictionary // provider. When the metadata is downloaded again, we will try downloading it
// provider. When the metadata is downloaded again, we will try downloading it // again.
// again. // However, in the practice that will mean the user will find themselves without
// However, in the practice that will mean the user will find themselves without // the new dictionary. That's fine for languages where it's included in the APK,
// the new dictionary. That's fine for languages where it's included in the APK, // but for other languages it will leave the user without a dictionary at all until
// but for other languages it will leave the user without a dictionary at all until // the next update, which may be a few days away.
// the next update, which may be a few days away. // Ideally, we would trigger a new download right away, and use increasing retry
// Ideally, we would trigger a new download right away, and use increasing retry // delays for this particular id/version combination.
// delays for this particular id/version combination. // Then again, this is expected to only ever happen in case of human mistake. If
// Then again, this is expected to only ever happen in case of human mistake. If // the wrong file is on the server, the following is still doing the right thing.
// the wrong file is on the server, the following is still doing the right thing. // If it's a file left over from the last version however, it's not great.
// If it's a file left over from the last version however, it's not great. BinaryDictionaryFileDumper.reportBrokenFileToDictionaryProvider(
BinaryDictionaryFileDumper.reportBrokenFileToDictionaryProvider( providerClient,
providerClient, context.getString(R.string.dictionary_pack_client_id),
context.getString(R.string.dictionary_pack_client_id), wordlistId);
wordlistId);
}
} }
} }

View File

@ -101,12 +101,12 @@ public class ExternalDictionaryGetterForDebug {
final File file = new File(dirPath, fileName.toString()); final File file = new File(dirPath, fileName.toString());
final DictionaryHeader header = DictionaryInfoUtils.getDictionaryFileHeaderOrNull(file); final DictionaryHeader header = DictionaryInfoUtils.getDictionaryFileHeaderOrNull(file);
final StringBuilder message = new StringBuilder(); final StringBuilder message = new StringBuilder();
final String locale = header.getLocaleString(); final String localeString = header.mLocaleString;
for (String key : header.mDictionaryOptions.mAttributes.keySet()) { for (final String key : header.mDictionaryOptions.mAttributes.keySet()) {
message.append(key + " = " + header.mDictionaryOptions.mAttributes.get(key)); message.append(key + " = " + header.mDictionaryOptions.mAttributes.get(key));
message.append("\n"); message.append("\n");
} }
final String languageName = LocaleUtils.constructLocaleFromString(locale) final String languageName = LocaleUtils.constructLocaleFromString(localeString)
.getDisplayName(Locale.getDefault()); .getDisplayName(Locale.getDefault());
final String title = String.format( final String title = String.format(
context.getString(R.string.read_external_dictionary_confirm_install_message), context.getString(R.string.read_external_dictionary_confirm_install_message),
@ -146,11 +146,12 @@ public class ExternalDictionaryGetterForDebug {
BufferedOutputStream outputStream = null; BufferedOutputStream outputStream = null;
File tempFile = null; File tempFile = null;
try { try {
final String locale = header.getLocaleString(); final String localeString = header.mLocaleString;
// Create the id for a main dictionary for this locale // Create the id for a main dictionary for this locale
final String id = BinaryDictionaryGetter.MAIN_DICTIONARY_CATEGORY final String id = BinaryDictionaryGetter.MAIN_DICTIONARY_CATEGORY
+ BinaryDictionaryGetter.ID_CATEGORY_SEPARATOR + locale; + BinaryDictionaryGetter.ID_CATEGORY_SEPARATOR + localeString;
final String finalFileName = DictionaryInfoUtils.getCacheFileName(id, locale, context); final String finalFileName = DictionaryInfoUtils.getCacheFileName(
id, localeString, context);
final String tempFileName = BinaryDictionaryGetter.getTempFileName(id, context); final String tempFileName = BinaryDictionaryGetter.getTempFileName(id, context);
tempFile = new File(tempFileName); tempFile = new File(tempFileName);
tempFile.delete(); tempFile.delete();

View File

@ -19,13 +19,24 @@ package com.android.inputmethod.latin.makedict;
import com.android.inputmethod.latin.makedict.FormatSpec.DictionaryOptions; import com.android.inputmethod.latin.makedict.FormatSpec.DictionaryOptions;
import com.android.inputmethod.latin.makedict.FormatSpec.FormatOptions; import com.android.inputmethod.latin.makedict.FormatSpec.FormatOptions;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
/** /**
* Class representing dictionary header. * Class representing dictionary header.
*/ */
public final class DictionaryHeader { public final class DictionaryHeader {
public final int mBodyOffset; public final int mBodyOffset;
@Nonnull
public final DictionaryOptions mDictionaryOptions; public final DictionaryOptions mDictionaryOptions;
@Nonnull
public final FormatOptions mFormatOptions; public final FormatOptions mFormatOptions;
@Nonnull
public final String mLocaleString;
@Nonnull
public final String mVersionString;
@Nonnull
public final String mIdString;
// Note that these are corresponding definitions in native code in latinime::HeaderPolicy // Note that these are corresponding definitions in native code in latinime::HeaderPolicy
// and latinime::HeaderReadWriteUtils. // and latinime::HeaderReadWriteUtils.
@ -46,39 +57,32 @@ public final class DictionaryHeader {
public static final String ATTRIBUTE_VALUE_TRUE = "1"; public static final String ATTRIBUTE_VALUE_TRUE = "1";
public static final String CODE_POINT_TABLE_KEY = "codePointTable"; public static final String CODE_POINT_TABLE_KEY = "codePointTable";
public DictionaryHeader(final int headerSize, final DictionaryOptions dictionaryOptions, public DictionaryHeader(final int headerSize,
final FormatOptions formatOptions) throws UnsupportedFormatException { @Nonnull final DictionaryOptions dictionaryOptions,
@Nonnull final FormatOptions formatOptions) throws UnsupportedFormatException {
mDictionaryOptions = dictionaryOptions; mDictionaryOptions = dictionaryOptions;
mFormatOptions = formatOptions; mFormatOptions = formatOptions;
mBodyOffset = formatOptions.mVersion < FormatSpec.VERSION4 ? headerSize : 0; mBodyOffset = formatOptions.mVersion < FormatSpec.VERSION4 ? headerSize : 0;
if (null == getLocaleString()) { final String localeString = dictionaryOptions.mAttributes.get(DICTIONARY_LOCALE_KEY);
if (null == localeString) {
throw new UnsupportedFormatException("Cannot create a FileHeader without a locale"); throw new UnsupportedFormatException("Cannot create a FileHeader without a locale");
} }
if (null == getVersion()) { final String versionString = dictionaryOptions.mAttributes.get(DICTIONARY_VERSION_KEY);
if (null == versionString) {
throw new UnsupportedFormatException( throw new UnsupportedFormatException(
"Cannot create a FileHeader without a version"); "Cannot create a FileHeader without a version");
} }
if (null == getId()) { final String idString = dictionaryOptions.mAttributes.get(DICTIONARY_ID_KEY);
if (null == idString) {
throw new UnsupportedFormatException("Cannot create a FileHeader without an ID"); throw new UnsupportedFormatException("Cannot create a FileHeader without an ID");
} }
} mLocaleString = localeString;
mVersionString = versionString;
// Helper method to get the locale as a String mIdString = idString;
public String getLocaleString() {
return mDictionaryOptions.mAttributes.get(DICTIONARY_LOCALE_KEY);
}
// Helper method to get the version String
public String getVersion() {
return mDictionaryOptions.mAttributes.get(DICTIONARY_VERSION_KEY);
}
// Helper method to get the dictionary ID as a String
public String getId() {
return mDictionaryOptions.mAttributes.get(DICTIONARY_ID_KEY);
} }
// Helper method to get the description // Helper method to get the description
@Nullable
public String getDescription() { public String getDescription() {
// TODO: Right now each dictionary file comes with a description in its own language. // TODO: Right now each dictionary file comes with a description in its own language.
// It will display as is no matter the device's locale. It should be internationalized. // It will display as is no matter the device's locale. It should be internationalized.

View File

@ -115,7 +115,8 @@ public abstract class AndroidWordLevelSpellCheckerSession extends Session {
@Override @Override
public void onCreate() { public void onCreate() {
final String localeString = getLocale(); final String localeString = getLocale();
mLocale = LocaleUtils.constructLocaleFromString(localeString); mLocale = (null == localeString) ? null
: LocaleUtils.constructLocaleFromString(localeString);
mScript = ScriptUtils.getScriptFromSpellCheckerLocale(mLocale); mScript = ScriptUtils.getScriptFromSpellCheckerLocale(mLocale);
} }

View File

@ -34,6 +34,8 @@ import java.util.ArrayList;
import java.util.Locale; import java.util.Locale;
import java.util.TreeSet; import java.util.TreeSet;
import javax.annotation.Nullable;
// Caveat: This class is basically taken from // Caveat: This class is basically taken from
// packages/apps/Settings/src/com/android/settings/inputmethod/UserDictionaryAddWordContents.java // packages/apps/Settings/src/com/android/settings/inputmethod/UserDictionaryAddWordContents.java
// in order to deal with some devices that have issues with the user dictionary handling // in order to deal with some devices that have issues with the user dictionary handling
@ -218,8 +220,8 @@ public class UserDictionaryAddWordContents {
public static class LocaleRenderer { public static class LocaleRenderer {
private final String mLocaleString; private final String mLocaleString;
private final String mDescription; private final String mDescription;
// LocaleString may NOT be null.
public LocaleRenderer(final Context context, final String localeString) { public LocaleRenderer(final Context context, @Nullable final String localeString) {
mLocaleString = localeString; mLocaleString = localeString;
if (null == localeString) { if (null == localeString) {
mDescription = context.getString(R.string.user_dict_settings_more_languages); mDescription = context.getString(R.string.user_dict_settings_more_languages);

View File

@ -37,6 +37,8 @@ import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.TreeSet; import java.util.TreeSet;
import javax.annotation.Nullable;
// Caveat: This class is basically taken from // Caveat: This class is basically taken from
// packages/apps/Settings/src/com/android/settings/inputmethod/UserDictionaryList.java // packages/apps/Settings/src/com/android/settings/inputmethod/UserDictionaryList.java
// in order to deal with some devices that have issues with the user dictionary handling // in order to deal with some devices that have issues with the user dictionary handling
@ -131,21 +133,23 @@ public class UserDictionaryList extends PreferenceFragment {
/** /**
* Create a single User Dictionary Preference object, with its parameters set. * Create a single User Dictionary Preference object, with its parameters set.
* @param locale The locale for which this user dictionary is for. * @param localeString The locale for which this user dictionary is for.
* @return The corresponding preference. * @return The corresponding preference.
*/ */
protected Preference createUserDictionaryPreference(final String locale) { protected Preference createUserDictionaryPreference(@Nullable final String localeString) {
final Preference newPref = new Preference(getActivity()); final Preference newPref = new Preference(getActivity());
final Intent intent = new Intent(USER_DICTIONARY_SETTINGS_INTENT_ACTION); final Intent intent = new Intent(USER_DICTIONARY_SETTINGS_INTENT_ACTION);
if (null == locale) { if (null == localeString) {
newPref.setTitle(Locale.getDefault().getDisplayName()); newPref.setTitle(Locale.getDefault().getDisplayName());
} else { } else {
if ("".equals(locale)) if (localeString.isEmpty()) {
newPref.setTitle(getString(R.string.user_dict_settings_all_languages)); newPref.setTitle(getString(R.string.user_dict_settings_all_languages));
else } else {
newPref.setTitle(LocaleUtils.constructLocaleFromString(locale).getDisplayName()); newPref.setTitle(
intent.putExtra("locale", locale); LocaleUtils.constructLocaleFromString(localeString).getDisplayName());
newPref.getExtras().putString("locale", locale); }
intent.putExtra("locale", localeString);
newPref.getExtras().putString("locale", localeString);
} }
newPref.setIntent(intent); newPref.setIntent(intent);
newPref.setFragment(UserDictionarySettings.class.getName()); newPref.setFragment(UserDictionarySettings.class.getName());

View File

@ -40,6 +40,9 @@ import java.util.Iterator;
import java.util.Locale; import java.util.Locale;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
/** /**
* This class encapsulates the logic for the Latin-IME side of dictionary information management. * This class encapsulates the logic for the Latin-IME side of dictionary information management.
*/ */
@ -59,19 +62,26 @@ public class DictionaryInfoUtils {
private static final String DATE_COLUMN = "date"; private static final String DATE_COLUMN = "date";
private static final String FILESIZE_COLUMN = "filesize"; private static final String FILESIZE_COLUMN = "filesize";
private static final String VERSION_COLUMN = "version"; private static final String VERSION_COLUMN = "version";
@Nonnull
public final String mId; public final String mId;
@Nonnull
public final Locale mLocale; public final Locale mLocale;
@Nullable
public final String mDescription; public final String mDescription;
@Nonnull
public final AssetFileAddress mFileAddress; public final AssetFileAddress mFileAddress;
public final int mVersion; public final int mVersion;
public DictionaryInfo(final String id, final Locale locale, final String description,
final AssetFileAddress fileAddress, final int version) { public DictionaryInfo(@Nonnull final String id, @Nonnull final Locale locale,
@Nullable final String description, @Nonnull final AssetFileAddress fileAddress,
final int version) {
mId = id; mId = id;
mLocale = locale; mLocale = locale;
mDescription = description; mDescription = description;
mFileAddress = fileAddress; mFileAddress = fileAddress;
mVersion = version; mVersion = version;
} }
public ContentValues toContentValues() { public ContentValues toContentValues() {
final ContentValues values = new ContentValues(); final ContentValues values = new ContentValues();
values.put(WORDLISTID_COLUMN, mId); values.put(WORDLISTID_COLUMN, mId);
@ -144,7 +154,8 @@ public class DictionaryInfoUtils {
/** /**
* Reverse escaping done by replaceFileNameDangerousCharacters. * Reverse escaping done by replaceFileNameDangerousCharacters.
*/ */
public static String getWordListIdFromFileName(final String fname) { @Nonnull
public static String getWordListIdFromFileName(@Nonnull final String fname) {
final StringBuilder sb = new StringBuilder(); final StringBuilder sb = new StringBuilder();
final int fnameLength = fname.length(); final int fnameLength = fname.length();
for (int i = 0; i < fnameLength; i = fname.offsetByCodePoints(i, 1)) { for (int i = 0; i < fnameLength; i = fname.offsetByCodePoints(i, 1)) {
@ -176,12 +187,15 @@ public class DictionaryInfoUtils {
* {@link #getMainDictId(Locale)} and {@link #isMainWordListId(String)}. * {@link #getMainDictId(Locale)} and {@link #isMainWordListId(String)}.
* @return The category as a string or null if it can't be found in the file name. * @return The category as a string or null if it can't be found in the file name.
*/ */
public static String getCategoryFromFileName(final String fileName) { @Nullable
public static String getCategoryFromFileName(@Nonnull final String fileName) {
final String id = getWordListIdFromFileName(fileName); final String id = getWordListIdFromFileName(fileName);
final String[] idArray = id.split(BinaryDictionaryGetter.ID_CATEGORY_SEPARATOR); final String[] idArray = id.split(BinaryDictionaryGetter.ID_CATEGORY_SEPARATOR);
// An id is supposed to be in format category:locale, so splitting on the separator // An id is supposed to be in format category:locale, so splitting on the separator
// should yield a 2-elements array // should yield a 2-elements array
if (2 != idArray.length) return null; if (2 != idArray.length) {
return null;
}
return idArray[0]; return idArray[0];
} }
@ -225,7 +239,9 @@ public class DictionaryInfoUtils {
final String[] idArray = id.split(BinaryDictionaryGetter.ID_CATEGORY_SEPARATOR); final String[] idArray = id.split(BinaryDictionaryGetter.ID_CATEGORY_SEPARATOR);
// An id is supposed to be in format category:locale, so splitting on the separator // An id is supposed to be in format category:locale, so splitting on the separator
// should yield a 2-elements array // should yield a 2-elements array
if (2 != idArray.length) return false; if (2 != idArray.length) {
return false;
}
return BinaryDictionaryGetter.MAIN_DICTIONARY_CATEGORY.equals(idArray[0]); return BinaryDictionaryGetter.MAIN_DICTIONARY_CATEGORY.equals(idArray[0]);
} }
@ -266,7 +282,9 @@ public class DictionaryInfoUtils {
*/ */
public static int getMainDictionaryResourceId(final Resources res, final Locale locale) { public static int getMainDictionaryResourceId(final Resources res, final Locale locale) {
int resourceId = getMainDictionaryResourceIdIfAvailableForLocale(res, locale); int resourceId = getMainDictionaryResourceIdIfAvailableForLocale(res, locale);
if (0 != resourceId) return resourceId; if (0 != resourceId) {
return resourceId;
}
return res.getIdentifier(DEFAULT_MAIN_DICT, "raw", RESOURCE_PACKAGE_NAME); return res.getIdentifier(DEFAULT_MAIN_DICT, "raw", RESOURCE_PACKAGE_NAME);
} }
@ -335,10 +353,10 @@ public class DictionaryInfoUtils {
if (header == null) { if (header == null) {
return null; return null;
} }
final String id = header.getId(); final String id = header.mIdString;
final Locale locale = LocaleUtils.constructLocaleFromString(header.getLocaleString()); final Locale locale = LocaleUtils.constructLocaleFromString(header.mLocaleString);
final String description = header.getDescription(); final String description = header.getDescription();
final String version = header.getVersion(); final String version = header.mVersionString;
return new DictionaryInfo(id, locale, description, fileAddress, Integer.parseInt(version)); return new DictionaryInfo(id, locale, description, fileAddress, Integer.parseInt(version));
} }
@ -366,10 +384,13 @@ public class DictionaryInfoUtils {
if (null != directoryList) { if (null != directoryList) {
for (final File directory : directoryList) { for (final File directory : directoryList) {
final String localeString = getWordListIdFromFileName(directory.getName()); final String localeString = getWordListIdFromFileName(directory.getName());
File[] dicts = BinaryDictionaryGetter.getCachedWordLists(localeString, context); final File[] dicts = BinaryDictionaryGetter.getCachedWordLists(
localeString, context);
for (final File dict : dicts) { for (final File dict : dicts) {
final String wordListId = getWordListIdFromFileName(dict.getName()); final String wordListId = getWordListIdFromFileName(dict.getName());
if (!DictionaryInfoUtils.isMainWordListId(wordListId)) continue; if (!DictionaryInfoUtils.isMainWordListId(wordListId)) {
continue;
}
final Locale locale = LocaleUtils.constructLocaleFromString(localeString); final Locale locale = LocaleUtils.constructLocaleFromString(localeString);
final AssetFileAddress fileAddress = AssetFileAddress.makeFromFile(dict); final AssetFileAddress fileAddress = AssetFileAddress.makeFromFile(dict);
final DictionaryInfo dictionaryInfo = final DictionaryInfo dictionaryInfo =
@ -377,7 +398,9 @@ public class DictionaryInfoUtils {
// Protect against cases of a less-specific dictionary being found, like an // Protect against cases of a less-specific dictionary being found, like an
// en dictionary being used for an en_US locale. In this case, the en dictionary // en dictionary being used for an en_US locale. In this case, the en dictionary
// should be used for en_US but discounted for listing purposes. // should be used for en_US but discounted for listing purposes.
if (dictionaryInfo == null || !dictionaryInfo.mLocale.equals(locale)) continue; if (dictionaryInfo == null || !dictionaryInfo.mLocale.equals(locale)) {
continue;
}
addOrUpdateDictInfo(dictList, dictionaryInfo); addOrUpdateDictInfo(dictList, dictionaryInfo);
} }
} }
@ -391,14 +414,18 @@ public class DictionaryInfoUtils {
final int resourceId = final int resourceId =
DictionaryInfoUtils.getMainDictionaryResourceIdIfAvailableForLocale( DictionaryInfoUtils.getMainDictionaryResourceIdIfAvailableForLocale(
context.getResources(), locale); context.getResources(), locale);
if (0 == resourceId) continue; if (0 == resourceId) {
continue;
}
final AssetFileAddress fileAddress = final AssetFileAddress fileAddress =
BinaryDictionaryGetter.loadFallbackResource(context, resourceId); BinaryDictionaryGetter.loadFallbackResource(context, resourceId);
final DictionaryInfo dictionaryInfo = createDictionaryInfoFromFileAddress(fileAddress); final DictionaryInfo dictionaryInfo = createDictionaryInfoFromFileAddress(fileAddress);
// Protect against cases of a less-specific dictionary being found, like an // Protect against cases of a less-specific dictionary being found, like an
// en dictionary being used for an en_US locale. In this case, the en dictionary // en dictionary being used for an en_US locale. In this case, the en dictionary
// should be used for en_US but discounted for listing purposes. // should be used for en_US but discounted for listing purposes.
if (!dictionaryInfo.mLocale.equals(locale)) continue; if (!dictionaryInfo.mLocale.equals(locale)) {
continue;
}
addOrUpdateDictInfo(dictList, dictionaryInfo); addOrUpdateDictInfo(dictList, dictionaryInfo);
} }
@ -408,7 +435,9 @@ public class DictionaryInfoUtils {
@UsedForTesting @UsedForTesting
public static boolean looksValidForDictionaryInsertion(final CharSequence text, public static boolean looksValidForDictionaryInsertion(final CharSequence text,
final SpacingAndPunctuations spacingAndPunctuations) { final SpacingAndPunctuations spacingAndPunctuations) {
if (TextUtils.isEmpty(text)) return false; if (TextUtils.isEmpty(text)) {
return false;
}
final int length = text.length(); final int length = text.length();
if (length > Constants.DICTIONARY_MAX_WORD_LENGTH) { if (length > Constants.DICTIONARY_MAX_WORD_LENGTH) {
return false; return false;
@ -424,7 +453,9 @@ public class DictionaryInfoUtils {
digitCount += charCount; digitCount += charCount;
continue; continue;
} }
if (!spacingAndPunctuations.isWordCodePoint(codePoint)) return false; if (!spacingAndPunctuations.isWordCodePoint(codePoint)) {
return false;
}
} }
// We reject strings entirely comprised of digits to avoid using PIN codes or credit // We reject strings entirely comprised of digits to avoid using PIN codes or credit
// card numbers. It would come in handy for word prediction though; a good example is // card numbers. It would come in handy for word prediction though; a good example is

View File

@ -199,8 +199,7 @@ public final class SubtypeLocaleUtils {
if (sExceptionalLocaleDisplayedInRootLocale.containsKey(localeString)) { if (sExceptionalLocaleDisplayedInRootLocale.containsKey(localeString)) {
languageString = localeString; languageString = localeString;
} else { } else {
final Locale locale = LocaleUtils.constructLocaleFromString(localeString); languageString = LocaleUtils.constructLocaleFromString(localeString).getLanguage();
languageString = locale.getLanguage();
} }
return getSubtypeLocaleDisplayNameInternal(languageString, displayLocale); return getSubtypeLocaleDisplayNameInternal(languageString, displayLocale);
} }
@ -232,8 +231,8 @@ public final class SubtypeLocaleUtils {
}; };
displayName = getExceptionalName.runInLocale(sResources, displayLocale); displayName = getExceptionalName.runInLocale(sResources, displayLocale);
} else { } else {
final Locale locale = LocaleUtils.constructLocaleFromString(localeString); displayName = LocaleUtils.constructLocaleFromString(localeString)
displayName = locale.getDisplayName(displayLocale); .getDisplayName(displayLocale);
} }
return StringUtils.capitalizeFirstCodePoint(displayName, displayLocale); return StringUtils.capitalizeFirstCodePoint(displayName, displayLocale);
} }