diff options
Diffstat (limited to 'java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java')
-rw-r--r-- | java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java | 133 |
1 files changed, 84 insertions, 49 deletions
diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java b/java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java index 360cf21ca..5d2dab0a9 100644 --- a/java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java +++ b/java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java @@ -42,6 +42,11 @@ class BinaryDictionaryGetter { private static final String TAG = BinaryDictionaryGetter.class.getSimpleName(); /** + * Used to return empty lists + */ + private static final File[] EMPTY_FILE_ARRAY = new File[0]; + + /** * Name of the common preferences name to know which word list are on and which are off. */ private static final String COMMON_PREFERENCES_NAME = "LatinImeDictPrefs"; @@ -158,46 +163,61 @@ class BinaryDictionaryGetter { context.getApplicationInfo().sourceDir, afd.getStartOffset(), afd.getLength()); } + static private class DictPackSettings { + final SharedPreferences mDictPreferences; + public DictPackSettings(final Context context) { + Context dictPackContext = null; + try { + final String dictPackName = + context.getString(R.string.dictionary_pack_package_name); + dictPackContext = context.createPackageContext(dictPackName, 0); + } catch (NameNotFoundException e) { + // The dictionary pack is not installed... + // TODO: fallback on the built-in dict, see the TODO above + Log.e(TAG, "Could not find a dictionary pack"); + } + mDictPreferences = null == dictPackContext ? null + : dictPackContext.getSharedPreferences(COMMON_PREFERENCES_NAME, + Context.MODE_WORLD_READABLE | Context.MODE_MULTI_PROCESS); + } + public boolean isWordListActive(final String dictId) { + if (null == mDictPreferences) { + // If we don't have preferences it basically means we can't find the dictionary + // pack - either it's not installed, or it's disabled, or there is some strange + // bug. Either way, a word list with no settings should be on by default: default + // dictionaries in LatinIME are on if there is no settings at all, and if for some + // reason some dictionaries have been installed BUT the dictionary pack can't be + // found anymore it's safer to actually supply installed dictionaries. + return true; + } else { + // The default is true here for the same reasons as above. We got the dictionary + // pack but if we don't have any settings for it it means the user has never been + // to the settings yet. So by default, the main dictionaries should be on. + return mDictPreferences.getBoolean(dictId, true); + } + } + } + /** * Returns the list of cached files for a specific locale. * * @param locale the locale to find the dictionary files for. * @param context the context on which to open the files upon. - * @return a list of binary dictionary files, which may be null but may not be empty. + * @return an array of binary dictionary files, which may be empty but may not be null. */ - private static List<AssetFileAddress> getCachedDictionaryList(final Locale locale, + private static File[] getCachedDictionaryList(final Locale locale, final Context context) { final String directoryName = getCacheDirectoryForLocale(locale, context); final File[] cacheFiles = new File(directoryName).listFiles(); - // TODO: Never return null. Fallback on the built-in dictionary, and if that's - // not present or disabled, then return an empty list. - if (null == cacheFiles) return null; - - final SharedPreferences dictPackSettings; - try { - final String dictPackName = context.getString(R.string.dictionary_pack_package_name); - final Context dictPackContext = context.createPackageContext(dictPackName, 0); - dictPackSettings = dictPackContext.getSharedPreferences(COMMON_PREFERENCES_NAME, - Context.MODE_WORLD_READABLE | Context.MODE_MULTI_PROCESS); - } catch (NameNotFoundException e) { - // The dictionary pack is not installed... - // TODO: fallback on the built-in dict, see the TODO above - Log.e(TAG, "Could not find a dictionary pack"); - return null; - } + if (null == cacheFiles) return EMPTY_FILE_ARRAY; + return cacheFiles; + } - final ArrayList<AssetFileAddress> fileList = new ArrayList<AssetFileAddress>(); - for (File f : cacheFiles) { - final String wordListId = getWordListIdFromFileName(f.getName()); - final boolean isActive = dictPackSettings.getBoolean(wordListId, true); - if (!isActive) continue; - if (f.canRead()) { - fileList.add(AssetFileAddress.makeFromFileName(f.getPath())); - } else { - Log.e(TAG, "Found a cached dictionary file but cannot read it"); - } - } - return fileList.size() > 0 ? fileList : null; + /** + * Returns the id of the main dict for a specified locale. + */ + private static String getMainDictId(final Locale locale) { + return locale.toString(); } /** @@ -214,26 +234,41 @@ class BinaryDictionaryGetter { */ public static List<AssetFileAddress> getDictionaryFiles(final Locale locale, final Context context, final int fallbackResId) { - try { - // cacheDictionariesFromContentProvider returns the list of files it copied to local - // storage, but we don't really care about what was copied NOW: what we want is the - // list of everything we ever cached, so we ignore the return value. - BinaryDictionaryFileDumper.cacheDictionariesFromContentProvider(locale, context); - List<AssetFileAddress> cachedDictionaryList = getCachedDictionaryList(locale, context); - if (null != cachedDictionaryList) { - return cachedDictionaryList; + + // cacheDictionariesFromContentProvider returns the list of files it copied to local + // storage, but we don't really care about what was copied NOW: what we want is the + // list of everything we ever cached, so we ignore the return value. + BinaryDictionaryFileDumper.cacheDictionariesFromContentProvider(locale, context); + final File[] cachedDictionaryList = getCachedDictionaryList(locale, context); + + final String mainDictId = getMainDictId(locale); + + final DictPackSettings dictPackSettings = new DictPackSettings(context); + + boolean foundMainDict = false; + final ArrayList<AssetFileAddress> fileList = new ArrayList<AssetFileAddress>(); + // cachedDictionaryList may not be null, see doc for getCachedDictionaryList + for (final File f : cachedDictionaryList) { + final String wordListId = getWordListIdFromFileName(f.getName()); + if (wordListId.equals(mainDictId)) { + foundMainDict = true; + } + if (!dictPackSettings.isWordListActive(wordListId)) continue; + if (f.canRead()) { + fileList.add(AssetFileAddress.makeFromFileName(f.getPath())); + } else { + Log.e(TAG, "Found a cached dictionary file but cannot read it"); } - // If the list is null, fall through and return the fallback - } catch (FileNotFoundException e) { - Log.e(TAG, "Unable to create dictionary file from provider for locale " - + locale.toString() + ": falling back to internal dictionary"); - } catch (IOException e) { - Log.e(TAG, "Unable to read source data for locale " - + locale.toString() + ": falling back to internal dictionary"); } - final AssetFileAddress fallbackAsset = loadFallbackResource(context, fallbackResId, - locale); - if (null == fallbackAsset) return null; - return Arrays.asList(fallbackAsset); + + if (!foundMainDict && dictPackSettings.isWordListActive(mainDictId)) { + final AssetFileAddress fallbackAsset = loadFallbackResource(context, fallbackResId, + locale); + if (null != fallbackAsset) { + fileList.add(fallbackAsset); + } + } + + return fileList; } } |