diff options
author | 2011-08-11 22:10:16 +0900 | |
---|---|---|
committer | 2011-08-12 17:31:24 +0900 | |
commit | 86e517fe4a5981f6ab936a0f9f40a0e0aa196477 (patch) | |
tree | 4d297506326b20d9b361c7f71516eb0d7e453048 /java/src | |
parent | 7fca6a535779aff80a7d5d61c7aa4dcb7d940db9 (diff) | |
download | latinime-86e517fe4a5981f6ab936a0f9f40a0e0aa196477.tar.gz latinime-86e517fe4a5981f6ab936a0f9f40a0e0aa196477.tar.xz latinime-86e517fe4a5981f6ab936a0f9f40a0e0aa196477.zip |
Read shared prefs from the dictionary pack.
Bug: 5095140
Change-Id: I227fbd95d8a0330b6dede6de99fde3a5a715fe2d
Diffstat (limited to 'java/src')
-rw-r--r-- | java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java | 63 |
1 files changed, 59 insertions, 4 deletions
diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java b/java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java index 170edad99..360cf21ca 100644 --- a/java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java +++ b/java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java @@ -17,6 +17,8 @@ package com.android.inputmethod.latin; import android.content.Context; +import android.content.SharedPreferences; +import android.content.pm.PackageManager.NameNotFoundException; import android.content.res.AssetFileDescriptor; import android.content.res.Resources; import android.util.Log; @@ -39,10 +41,27 @@ class BinaryDictionaryGetter { */ private static final String TAG = BinaryDictionaryGetter.class.getSimpleName(); + /** + * 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"; + // Prevents this from being instantiated private BinaryDictionaryGetter() {} /** + * Returns whether we may want to use this character as part of a file name. + * + * This basically only accepts ascii letters and numbers, and rejects everything else. + */ + private static boolean isFileNameCharacter(int codePoint) { + if (codePoint >= 0x30 && codePoint <= 0x39) return true; // Digit + if (codePoint >= 0x41 && codePoint <= 0x5A) return true; // Uppercase + if (codePoint >= 0x61 && codePoint <= 0x7A) return true; // Lowercase + return codePoint == '_'; // Underscore + } + + /** * Escapes a string for any characters that may be suspicious for a file or directory name. * * Concretely this does a sort of URL-encoding except it will encode everything that's not @@ -50,17 +69,35 @@ class BinaryDictionaryGetter { * we cannot allow here) */ // TODO: create a unit test for this method - private static String replaceFileNameDangerousCharacters(String name) { + private static String replaceFileNameDangerousCharacters(final String name) { // This assumes '%' is fully available as a non-separator, normal // character in a file name. This is probably true for all file systems. final StringBuilder sb = new StringBuilder(); for (int i = 0; i < name.length(); ++i) { final int codePoint = name.codePointAt(i); - if (Character.isLetterOrDigit(codePoint) || '_' == codePoint) { + if (isFileNameCharacter(codePoint)) { + sb.appendCodePoint(codePoint); + } else { + // 6 digits - unicode is limited to 21 bits + sb.append(String.format((Locale)null, "%%%1$06x", codePoint)); + } + } + return sb.toString(); + } + + /** + * Reverse escaping done by replaceFileNameDangerousCharacters. + */ + private static String getWordListIdFromFileName(final String fname) { + final StringBuilder sb = new StringBuilder(); + for (int i = 0; i < fname.length(); ++i) { + final int codePoint = fname.codePointAt(i); + if ('%' != codePoint) { sb.appendCodePoint(codePoint); } else { - sb.append('%'); - sb.append(Integer.toHexString(codePoint)); + final int encodedCodePoint = Integer.parseInt(fname.substring(i + 1, i + 7), 16); + i += 6; + sb.appendCodePoint(encodedCodePoint); } } return sb.toString(); @@ -132,10 +169,28 @@ class BinaryDictionaryGetter { 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; + } + 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 { |