diff --git a/java/src/com/android/inputmethod/latin/AssetFileAddress.java b/java/src/com/android/inputmethod/latin/AssetFileAddress.java index 16296f0e2..47c750f54 100644 --- a/java/src/com/android/inputmethod/latin/AssetFileAddress.java +++ b/java/src/com/android/inputmethod/latin/AssetFileAddress.java @@ -35,11 +35,14 @@ final class AssetFileAddress { mLength = length; } + public static AssetFileAddress makeFromFile(final File file) { + if (!file.isFile()) return null; + return new AssetFileAddress(file.getAbsolutePath(), 0L, file.length()); + } + public static AssetFileAddress makeFromFileName(final String filename) { if (null == filename) return null; - final File f = new File(filename); - if (!f.isFile()) return null; - return new AssetFileAddress(filename, 0l, f.length()); + return makeFromFile(new File(filename)); } public static AssetFileAddress makeFromFileNameAndOffset(final String filename, diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionaryFileDumper.java b/java/src/com/android/inputmethod/latin/BinaryDictionaryFileDumper.java index d0bd01f6b..443ffa2e9 100644 --- a/java/src/com/android/inputmethod/latin/BinaryDictionaryFileDumper.java +++ b/java/src/com/android/inputmethod/latin/BinaryDictionaryFileDumper.java @@ -149,7 +149,7 @@ public final class BinaryDictionaryFileDumper { final int MODE_MAX = NONE; final Uri.Builder wordListUriBuilder = getProviderUriBuilder(id); - final String finalFileName = BinaryDictionaryGetter.getCacheFileName(id, locale, context); + final String finalFileName = DictionaryInfoUtils.getCacheFileName(id, locale, context); String tempFileName; try { tempFileName = BinaryDictionaryGetter.getTempFileName(id, context); diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java b/java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java index 22b5cd55c..5da0f1be8 100644 --- a/java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java +++ b/java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java @@ -65,110 +65,12 @@ final class BinaryDictionaryGetter { // 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 - * alphanumeric or underscore. (true URL-encoding leaves alone characters like '*', which - * we cannot allow here) - */ - // TODO: create a unit test for this method - 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(); - final int nameLength = name.length(); - for (int i = 0; i < nameLength; i = name.offsetByCodePoints(i, 1)) { - final int codePoint = name.codePointAt(i); - 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(); - final int fnameLength = fname.length(); - for (int i = 0; i < fnameLength; i = fname.offsetByCodePoints(i, 1)) { - final int codePoint = fname.codePointAt(i); - if ('%' != codePoint) { - sb.appendCodePoint(codePoint); - } else { - final int encodedCodePoint = Integer.parseInt(fname.substring(i + 1, i + 7), 16); - i += 6; - sb.appendCodePoint(encodedCodePoint); - } - } - return sb.toString(); - } - - /** - * Helper method to get the top level cache directory. - */ - private static String getWordListCacheDirectory(final Context context) { - return context.getFilesDir() + File.separator + "dicts"; - } - - /** - * Find out the cache directory associated with a specific locale. - */ - private static String getCacheDirectoryForLocale(final String locale, final Context context) { - final String relativeDirectoryName = replaceFileNameDangerousCharacters(locale); - final String absoluteDirectoryName = getWordListCacheDirectory(context) + File.separator - + relativeDirectoryName; - final File directory = new File(absoluteDirectoryName); - if (!directory.exists()) { - if (!directory.mkdirs()) { - Log.e(TAG, "Could not create the directory for locale" + locale); - } - } - return absoluteDirectoryName; - } - - /** - * Generates a file name for the id and locale passed as an argument. - * - * In the current implementation the file name returned will always be unique for - * any id/locale pair, but please do not expect that the id can be the same for - * different dictionaries with different locales. An id should be unique for any - * dictionary. - * The file name is pretty much an URL-encoded version of the id inside a directory - * named like the locale, except it will also escape characters that look dangerous - * to some file systems. - * @param id the id of the dictionary for which to get a file name - * @param locale the locale for which to get the file name as a string - * @param context the context to use for getting the directory - * @return the name of the file to be created - */ - public static String getCacheFileName(String id, String locale, Context context) { - final String fileName = replaceFileNameDangerousCharacters(id); - return getCacheDirectoryForLocale(locale, context) + File.separator + fileName; - } - /** * Generates a unique temporary file name in the app cache directory. */ public static String getTempFileName(String id, Context context) throws IOException { - return File.createTempFile(replaceFileNameDangerousCharacters(id), null).getAbsolutePath(); + return File.createTempFile(DictionaryInfoUtils.replaceFileNameDangerousCharacters(id), + null).getAbsolutePath(); } /** @@ -221,27 +123,6 @@ final class BinaryDictionaryGetter { } } - /** - * Helper method to the list of cache directories, one for each distinct locale. - */ - private static File[] getCachedDirectoryList(final Context context) { - return new File(getWordListCacheDirectory(context)).listFiles(); - } - - /** - * Returns the category for a given file name. - * - * This parses the file name, extracts the category, and returns it. See - * {@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. - */ - private static String getCategoryFromFileName(final String fileName) { - final String id = getWordListIdFromFileName(fileName); - final String[] idArray = id.split(ID_CATEGORY_SEPARATOR); - if (2 != idArray.length) return null; - return idArray[0]; - } - /** * Utility class for the {@link #getCachedWordLists} method */ @@ -268,20 +149,21 @@ final class BinaryDictionaryGetter { * @param context the context on which to open the files upon. * @return an array of binary dictionary files, which may be empty but may not be null. */ - private static File[] getCachedWordLists(final String locale, - final Context context) { - final File[] directoryList = getCachedDirectoryList(context); + private static File[] getCachedWordLists(final String locale, final Context context) { + final File[] directoryList = DictionaryInfoUtils.getCachedDirectoryList(context); if (null == directoryList) return EMPTY_FILE_ARRAY; final HashMap cacheFiles = CollectionUtils.newHashMap(); for (File directory : directoryList) { if (!directory.isDirectory()) continue; - final String dirLocale = getWordListIdFromFileName(directory.getName()); + final String dirLocale = + DictionaryInfoUtils.getWordListIdFromFileName(directory.getName()); final int matchLevel = LocaleUtils.getMatchLevel(dirLocale, locale); if (LocaleUtils.isMatch(matchLevel)) { final File[] wordLists = directory.listFiles(); if (null != wordLists) { for (File wordList : wordLists) { - final String category = getCategoryFromFileName(wordList.getName()); + final String category = + DictionaryInfoUtils.getCategoryFromFileName(wordList.getName()); final FileAndMatchLevel currentBestMatch = cacheFiles.get(category); if (null == currentBestMatch || currentBestMatch.mMatchLevel < matchLevel) { cacheFiles.put(category, new FileAndMatchLevel(wordList, matchLevel)); @@ -310,7 +192,7 @@ final class BinaryDictionaryGetter { final File fileToKeep) { try { final File canonicalFileToKeep = fileToKeep.getCanonicalFile(); - final File[] directoryList = getCachedDirectoryList(context); + final File[] directoryList = DictionaryInfoUtils.getCachedDirectoryList(context); if (null == directoryList) return; for (File directory : directoryList) { // There is one directory per locale. See #getCachedDirectoryList @@ -318,7 +200,8 @@ final class BinaryDictionaryGetter { final File[] wordLists = directory.listFiles(); if (null == wordLists) continue; for (File wordList : wordLists) { - final String fileId = getWordListIdFromFileName(wordList.getName()); + final String fileId = + DictionaryInfoUtils.getWordListIdFromFileName(wordList.getName()); if (fileId.equals(id)) { if (!canonicalFileToKeep.equals(wordList.getCanonicalFile())) { wordList.delete(); @@ -331,28 +214,6 @@ final class BinaryDictionaryGetter { } } - - /** - * Returns the id associated with the main word list for a specified locale. - * - * Word lists stored in Android Keyboard's resources are referred to as the "main" - * word lists. Since they can be updated like any other list, we need to assign a - * unique ID to them. This ID is just the name of the language (locale-wise) they - * are for, and this method returns this ID. - */ - private static String getMainDictId(final Locale locale) { - // This works because we don't include by default different dictionaries for - // different countries. This actually needs to return the id that we would - // like to use for word lists included in resources, and the following is okay. - return MAIN_DICTIONARY_CATEGORY + ID_CATEGORY_SEPARATOR + locale.getLanguage().toString(); - } - - private static boolean isMainWordListId(final String id) { - final String[] idArray = id.split(ID_CATEGORY_SEPARATOR); - if (2 != idArray.length) return false; - return MAIN_DICTIONARY_CATEGORY.equals(idArray[0]); - } - // ## HACK ## we prevent usage of a dictionary before version 18 for English only. The reason // for this is, since those do not include whitelist entries, the new code with an old version // of the dictionary would lose whitelist functionality. @@ -429,16 +290,16 @@ final class BinaryDictionaryGetter { hasDefaultWordList); } final File[] cachedWordLists = getCachedWordLists(locale.toString(), context); - final String mainDictId = getMainDictId(locale); + final String mainDictId = DictionaryInfoUtils.getMainDictId(locale); final DictPackSettings dictPackSettings = new DictPackSettings(context); boolean foundMainDict = false; final ArrayList fileList = CollectionUtils.newArrayList(); // cachedWordLists may not be null, see doc for getCachedDictionaryList for (final File f : cachedWordLists) { - final String wordListId = getWordListIdFromFileName(f.getName()); + final String wordListId = DictionaryInfoUtils.getWordListIdFromFileName(f.getName()); final boolean canUse = f.canRead() && hackCanUseDictionaryFile(locale, f); - if (canUse && isMainWordListId(wordListId)) { + if (canUse && DictionaryInfoUtils.isMainWordListId(wordListId)) { foundMainDict = true; } if (!dictPackSettings.isWordListActive(wordListId)) continue; @@ -451,7 +312,7 @@ final class BinaryDictionaryGetter { if (!foundMainDict && dictPackSettings.isWordListActive(mainDictId)) { final int fallbackResId = - DictionaryFactory.getMainDictionaryResourceId(context.getResources(), locale); + DictionaryInfoUtils.getMainDictionaryResourceId(context.getResources(), locale); final AssetFileAddress fallbackAsset = loadFallbackResource(context, fallbackResId); if (null != fallbackAsset) { fileList.add(fallbackAsset); diff --git a/java/src/com/android/inputmethod/latin/DictionaryFactory.java b/java/src/com/android/inputmethod/latin/DictionaryFactory.java index 388ad6c59..40e51672a 100644 --- a/java/src/com/android/inputmethod/latin/DictionaryFactory.java +++ b/java/src/com/android/inputmethod/latin/DictionaryFactory.java @@ -31,9 +31,6 @@ import java.util.Locale; */ public final class DictionaryFactory { private static final String TAG = DictionaryFactory.class.getSimpleName(); - // This class must be located in the same package as LatinIME.java. - private static final String RESOURCE_PACKAGE_NAME = - DictionaryFactory.class.getPackage().getName(); /** * Initializes a main dictionary collection from a dictionary pack, with explicit flags. @@ -96,8 +93,8 @@ public final class DictionaryFactory { final Locale locale) { AssetFileDescriptor afd = null; try { - final int resId = - getMainDictionaryResourceIdIfAvailableForLocale(context.getResources(), locale); + final int resId = DictionaryInfoUtils.getMainDictionaryResourceIdIfAvailableForLocale( + context.getResources(), locale); if (0 == resId) return null; afd = context.getResources().openRawResourceFd(resId); if (afd == null) { @@ -154,47 +151,7 @@ public final class DictionaryFactory { */ public static boolean isDictionaryAvailable(Context context, Locale locale) { final Resources res = context.getResources(); - return 0 != getMainDictionaryResourceIdIfAvailableForLocale(res, locale); - } - - private static final String DEFAULT_MAIN_DICT = "main"; - private static final String MAIN_DICT_PREFIX = "main_"; - - /** - * Helper method to return a dictionary res id for a locale, or 0 if none. - * @param locale dictionary locale - * @return main dictionary resource id - */ - private static int getMainDictionaryResourceIdIfAvailableForLocale(final Resources res, - final Locale locale) { - int resId; - // Try to find main_language_country dictionary. - if (!locale.getCountry().isEmpty()) { - final String dictLanguageCountry = MAIN_DICT_PREFIX + locale.toString().toLowerCase(); - if ((resId = res.getIdentifier( - dictLanguageCountry, "raw", RESOURCE_PACKAGE_NAME)) != 0) { - return resId; - } - } - - // Try to find main_language dictionary. - final String dictLanguage = MAIN_DICT_PREFIX + locale.getLanguage(); - if ((resId = res.getIdentifier(dictLanguage, "raw", RESOURCE_PACKAGE_NAME)) != 0) { - return resId; - } - - // Not found, return 0 - return 0; - } - - /** - * Returns a main dictionary resource id - * @param locale dictionary locale - * @return main dictionary resource id - */ - public static int getMainDictionaryResourceId(final Resources res, final Locale locale) { - int resourceId = getMainDictionaryResourceIdIfAvailableForLocale(res, locale); - if (0 != resourceId) return resourceId; - return res.getIdentifier(DEFAULT_MAIN_DICT, "raw", RESOURCE_PACKAGE_NAME); + return 0 != DictionaryInfoUtils.getMainDictionaryResourceIdIfAvailableForLocale( + res, locale); } } diff --git a/java/src/com/android/inputmethod/latin/DictionaryInfoUtils.java b/java/src/com/android/inputmethod/latin/DictionaryInfoUtils.java new file mode 100644 index 000000000..c676bf1b9 --- /dev/null +++ b/java/src/com/android/inputmethod/latin/DictionaryInfoUtils.java @@ -0,0 +1,245 @@ +/* + * Copyright (C) 2013 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 android.content.res.Resources; +import android.util.Log; + +import com.android.inputmethod.latin.makedict.BinaryDictIOUtils; +import com.android.inputmethod.latin.makedict.FormatSpec.FileHeader; +import com.android.inputmethod.latin.makedict.UnsupportedFormatException; + +import java.io.File; +import java.io.IOException; +import java.util.Locale; + +/** + * This class encapsulates the logic for the Latin-IME side of dictionary information management. + */ +public class DictionaryInfoUtils { + private static final String TAG = DictionaryInfoUtils.class.getSimpleName(); + // This class must be located in the same package as LatinIME.java. + private static final String RESOURCE_PACKAGE_NAME = + DictionaryInfoUtils.class.getPackage().getName(); + private static final String DEFAULT_MAIN_DICT = "main"; + private static final String MAIN_DICT_PREFIX = "main_"; + // 6 digits - unicode is limited to 21 bits + private static final int MAX_HEX_DIGITS_FOR_CODEPOINT = 6; + + private DictionaryInfoUtils() { + // Private constructor to forbid instantation of this helper class. + } + + /** + * 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 + * alphanumeric or underscore. (true URL-encoding leaves alone characters like '*', which + * we cannot allow here) + */ + // TODO: create a unit test for this method + public 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(); + final int nameLength = name.length(); + for (int i = 0; i < nameLength; i = name.offsetByCodePoints(i, 1)) { + final int codePoint = name.codePointAt(i); + if (DictionaryInfoUtils.isFileNameCharacter(codePoint)) { + sb.appendCodePoint(codePoint); + } else { + sb.append(String.format((Locale)null, "%%%1$0" + MAX_HEX_DIGITS_FOR_CODEPOINT + "x", + codePoint)); + } + } + return sb.toString(); + } + + /** + * Helper method to get the top level cache directory. + */ + private static String getWordListCacheDirectory(final Context context) { + return context.getFilesDir() + File.separator + "dicts"; + } + + /** + * Reverse escaping done by replaceFileNameDangerousCharacters. + */ + public static String getWordListIdFromFileName(final String fname) { + final StringBuilder sb = new StringBuilder(); + final int fnameLength = fname.length(); + for (int i = 0; i < fnameLength; i = fname.offsetByCodePoints(i, 1)) { + final int codePoint = fname.codePointAt(i); + if ('%' != codePoint) { + sb.appendCodePoint(codePoint); + } else { + // + 1 to pass the % sign + final int encodedCodePoint = Integer.parseInt( + fname.substring(i + 1, i + 1 + MAX_HEX_DIGITS_FOR_CODEPOINT), 16); + i += MAX_HEX_DIGITS_FOR_CODEPOINT; + sb.appendCodePoint(encodedCodePoint); + } + } + return sb.toString(); + } + + /** + * Helper method to the list of cache directories, one for each distinct locale. + */ + public static File[] getCachedDirectoryList(final Context context) { + return new File(DictionaryInfoUtils.getWordListCacheDirectory(context)).listFiles(); + } + + /** + * Returns the category for a given file name. + * + * This parses the file name, extracts the category, and returns it. See + * {@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. + */ + public static String getCategoryFromFileName(final String fileName) { + final String id = getWordListIdFromFileName(fileName); + final String[] idArray = id.split(BinaryDictionaryGetter.ID_CATEGORY_SEPARATOR); + // An id is supposed to be in format category:locale, so splitting on the separator + // should yield a 2-elements array + if (2 != idArray.length) return null; + return idArray[0]; + } + + /** + * Find out the cache directory associated with a specific locale. + */ + private static String getCacheDirectoryForLocale(final String locale, final Context context) { + final String relativeDirectoryName = replaceFileNameDangerousCharacters(locale); + final String absoluteDirectoryName = getWordListCacheDirectory(context) + File.separator + + relativeDirectoryName; + final File directory = new File(absoluteDirectoryName); + if (!directory.exists()) { + if (!directory.mkdirs()) { + Log.e(TAG, "Could not create the directory for locale" + locale); + } + } + return absoluteDirectoryName; + } + + /** + * Generates a file name for the id and locale passed as an argument. + * + * In the current implementation the file name returned will always be unique for + * any id/locale pair, but please do not expect that the id can be the same for + * different dictionaries with different locales. An id should be unique for any + * dictionary. + * The file name is pretty much an URL-encoded version of the id inside a directory + * named like the locale, except it will also escape characters that look dangerous + * to some file systems. + * @param id the id of the dictionary for which to get a file name + * @param locale the locale for which to get the file name as a string + * @param context the context to use for getting the directory + * @return the name of the file to be created + */ + public static String getCacheFileName(String id, String locale, Context context) { + final String fileName = replaceFileNameDangerousCharacters(id); + return getCacheDirectoryForLocale(locale, context) + File.separator + fileName; + } + + public static boolean isMainWordListId(final String id) { + final String[] idArray = id.split(BinaryDictionaryGetter.ID_CATEGORY_SEPARATOR); + // An id is supposed to be in format category:locale, so splitting on the separator + // should yield a 2-elements array + if (2 != idArray.length) return false; + return BinaryDictionaryGetter.MAIN_DICTIONARY_CATEGORY.equals(idArray[0]); + } + + /** + * Helper method to return a dictionary res id for a locale, or 0 if none. + * @param locale dictionary locale + * @return main dictionary resource id + */ + public static int getMainDictionaryResourceIdIfAvailableForLocale(final Resources res, + final Locale locale) { + int resId; + // Try to find main_language_country dictionary. + if (!locale.getCountry().isEmpty()) { + final String dictLanguageCountry = + MAIN_DICT_PREFIX + locale.toString().toLowerCase(Locale.ROOT); + if ((resId = res.getIdentifier( + dictLanguageCountry, "raw", RESOURCE_PACKAGE_NAME)) != 0) { + return resId; + } + } + + // Try to find main_language dictionary. + final String dictLanguage = MAIN_DICT_PREFIX + locale.getLanguage(); + if ((resId = res.getIdentifier(dictLanguage, "raw", RESOURCE_PACKAGE_NAME)) != 0) { + return resId; + } + + // Not found, return 0 + return 0; + } + + /** + * Returns a main dictionary resource id + * @param locale dictionary locale + * @return main dictionary resource id + */ + public static int getMainDictionaryResourceId(final Resources res, final Locale locale) { + int resourceId = getMainDictionaryResourceIdIfAvailableForLocale(res, locale); + if (0 != resourceId) return resourceId; + return res.getIdentifier(DEFAULT_MAIN_DICT, "raw", RESOURCE_PACKAGE_NAME); + } + + /** + * Returns the id associated with the main word list for a specified locale. + * + * Word lists stored in Android Keyboard's resources are referred to as the "main" + * word lists. Since they can be updated like any other list, we need to assign a + * unique ID to them. This ID is just the name of the language (locale-wise) they + * are for, and this method returns this ID. + */ + public static String getMainDictId(final Locale locale) { + // This works because we don't include by default different dictionaries for + // different countries. This actually needs to return the id that we would + // like to use for word lists included in resources, and the following is okay. + return BinaryDictionaryGetter.MAIN_DICTIONARY_CATEGORY + + BinaryDictionaryGetter.ID_CATEGORY_SEPARATOR + locale.getLanguage().toString(); + } + + public static FileHeader getDictionaryFileHeaderOrNull(final File file) { + try { + final FileHeader header = BinaryDictIOUtils.getDictionaryFileHeader(file); + return header; + } catch (UnsupportedFormatException e) { + return null; + } catch (IOException e) { + return null; + } + } +} diff --git a/java/src/com/android/inputmethod/latin/ExternalDictionaryGetterForDebug.java b/java/src/com/android/inputmethod/latin/ExternalDictionaryGetterForDebug.java index 6e5a37c72..d9e4bb63d 100644 --- a/java/src/com/android/inputmethod/latin/ExternalDictionaryGetterForDebug.java +++ b/java/src/com/android/inputmethod/latin/ExternalDictionaryGetterForDebug.java @@ -21,11 +21,8 @@ import android.content.Context; import android.content.DialogInterface; import android.content.DialogInterface.OnClickListener; import android.os.Environment; -import android.util.Log; -import com.android.inputmethod.latin.makedict.BinaryDictIOUtils; import com.android.inputmethod.latin.makedict.FormatSpec.FileHeader; -import com.android.inputmethod.latin.makedict.UnsupportedFormatException; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; @@ -44,22 +41,11 @@ public class ExternalDictionaryGetterForDebug { + "/Download"; private static final String DICTIONARY_LOCALE_ATTRIBUTE = "locale"; - private static FileHeader getDictionaryFileHeaderOrNull(final File file) { - try { - final FileHeader header = BinaryDictIOUtils.getDictionaryFileHeader(file); - return header; - } catch (UnsupportedFormatException e) { - return null; - } catch (IOException e) { - return null; - } - } - private static String[] findDictionariesInTheDownloadedFolder() { final File[] files = new File(SOURCE_FOLDER).listFiles(); final ArrayList eligibleList = CollectionUtils.newArrayList(); for (File f : files) { - final FileHeader header = getDictionaryFileHeaderOrNull(f); + final FileHeader header = DictionaryInfoUtils.getDictionaryFileHeaderOrNull(f); if (null == header) continue; eligibleList.add(f.getName()); } @@ -102,7 +88,7 @@ public class ExternalDictionaryGetterForDebug { private static void askInstallFile(final Context context, final String fileName) { final File file = new File(SOURCE_FOLDER, fileName.toString()); - final FileHeader header = getDictionaryFileHeaderOrNull(file); + final FileHeader header = DictionaryInfoUtils.getDictionaryFileHeaderOrNull(file); final StringBuilder message = new StringBuilder(); final String locale = header.mDictionaryOptions.mAttributes.get(DICTIONARY_LOCALE_ATTRIBUTE); @@ -143,7 +129,7 @@ public class ExternalDictionaryGetterForDebug { final String id = BinaryDictionaryGetter.MAIN_DICTIONARY_CATEGORY + BinaryDictionaryGetter.ID_CATEGORY_SEPARATOR + locale; final String finalFileName = - BinaryDictionaryGetter.getCacheFileName(id, locale, context); + DictionaryInfoUtils.getCacheFileName(id, locale, context); final String tempFileName = BinaryDictionaryGetter.getTempFileName(id, context); tempFile = new File(tempFileName); tempFile.delete();