com.android.inputmethod.latin.utils.DictionaryInfoUtils Java Examples

The following examples show how to use com.android.inputmethod.latin.utils.DictionaryInfoUtils. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: BinaryDictionaryGetter.java    From Android-Keyboard with Apache License 2.0 5 votes vote down vote up
/**
 * Generates a unique temporary file name in the app cache directory.
 */
public static String getTempFileName(final String id, final Context context)
        throws IOException {
    final String safeId = DictionaryInfoUtils.replaceFileNameDangerousCharacters(id);
    final File directory = new File(DictionaryInfoUtils.getWordListTempDirectory(context));
    if (!directory.exists()) {
        if (!directory.mkdirs()) {
            Log.e(TAG, "Could not create the temporary directory");
        }
    }
    // If the first argument is less than three chars, createTempFile throws a
    // RuntimeException. We don't really care about what name we get, so just
    // put a three-chars prefix makes us safe.
    return File.createTempFile("xxx" + safeId, null, directory).getAbsolutePath();
}
 
Example #2
Source File: BinaryDictionaryGetter.java    From Android-Keyboard with Apache License 2.0 5 votes vote down vote up
/**
 * Returns the list of cached files for a specific locale, one for each category.
 *
 * This will return exactly one file for each word list category that matches
 * the passed locale. If several files match the locale for any given category,
 * this returns the file with the closest match to the locale. For example, if
 * the passed word list is en_US, and for a category we have an en and an en_US
 * word list available, we'll return only the en_US one.
 * Thus, the list will contain as many files as there are categories.
 *
 * @param locale the locale to find the dictionary files for, as a string.
 * @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.
 */
public static File[] getCachedWordLists(final String locale, final Context context) {
    final File[] directoryList = DictionaryInfoUtils.getCachedDirectoryList(context);
    if (null == directoryList) return EMPTY_FILE_ARRAY;
    final HashMap<String, FileAndMatchLevel> cacheFiles = new HashMap<>();
    for (File directory : directoryList) {
        if (!directory.isDirectory()) continue;
        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 =
                            DictionaryInfoUtils.getCategoryFromFileName(wordList.getName());
                    final FileAndMatchLevel currentBestMatch = cacheFiles.get(category);
                    if (null == currentBestMatch || currentBestMatch.mMatchLevel < matchLevel) {
                        cacheFiles.put(category, new FileAndMatchLevel(wordList, matchLevel));
                    }
                }
            }
        }
    }
    if (cacheFiles.isEmpty()) return EMPTY_FILE_ARRAY;
    final File[] result = new File[cacheFiles.size()];
    int index = 0;
    for (final FileAndMatchLevel entry : cacheFiles.values()) {
        result[index++] = entry.mFile;
    }
    return result;
}
 
Example #3
Source File: DictionaryFactory.java    From AOSP-Kayboard-7.1.2 with Apache License 2.0 5 votes vote down vote up
/**
 * Kills a dictionary so that it is never used again, if possible.
 * @param context The context to contact the dictionary provider, if possible.
 * @param f A file address to the dictionary to kill.
 */
public static void killDictionary(final Context context, final AssetFileAddress f) {
    if (f.pointsToPhysicalFile()) {
        f.deleteUnderlyingFile();
        // Warn the dictionary provider if the dictionary came from there.
        final ContentProviderClient providerClient;
        try {
            providerClient = context.getContentResolver().acquireContentProviderClient(
                    BinaryDictionaryFileDumper.getProviderUriBuilder(context, "").build());
        } catch (final SecurityException e) {
            Log.e(TAG, "No permission to communicate with the dictionary provider", e);
            return;
        }
        if (null == providerClient) {
            Log.e(TAG, "Can't establish communication with the dictionary provider");
            return;
        }
        final String wordlistId =
                DictionaryInfoUtils.getWordListIdFromFileName(new File(f.mFilename).getName());
        // TODO: this is a reasonable last resort, but it is suboptimal.
        // The following will remove the entry for this dictionary with the dictionary
        // provider. When the metadata is downloaded again, we will try downloading it
        // again.
        // 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,
        // 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.
        // Ideally, we would trigger a new download right away, and use increasing retry
        // delays for this particular id/version combination.
        // 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.
        // If it's a file left over from the last version however, it's not great.
        BinaryDictionaryFileDumper.reportBrokenFileToDictionaryProvider(context,
                providerClient,
                context.getString(R.string.dictionary_pack_client_id),
                wordlistId);
    }
}
 
Example #4
Source File: BinaryDictionaryGetter.java    From AOSP-Kayboard-7.1.2 with Apache License 2.0 5 votes vote down vote up
/**
 * Generates a unique temporary file name in the app cache directory.
 */
public static String getTempFileName(final String id, final Context context)
        throws IOException {
    final String safeId = DictionaryInfoUtils.replaceFileNameDangerousCharacters(id);
    final File directory = new File(DictionaryInfoUtils.getWordListTempDirectory(context));
    if (!directory.exists()) {
        if (!directory.mkdirs()) {
            Log.e(TAG, "Could not create the temporary directory");
        }
    }
    // If the first argument is less than three chars, createTempFile throws a
    // RuntimeException. We don't really care about what name we get, so just
    // put a three-chars prefix makes us safe.
    return File.createTempFile("xxx" + safeId, null, directory).getAbsolutePath();
}
 
Example #5
Source File: BinaryDictionaryGetter.java    From AOSP-Kayboard-7.1.2 with Apache License 2.0 5 votes vote down vote up
/**
 * Returns the list of cached files for a specific locale, one for each category.
 *
 * This will return exactly one file for each word list category that matches
 * the passed locale. If several files match the locale for any given category,
 * this returns the file with the closest match to the locale. For example, if
 * the passed word list is en_US, and for a category we have an en and an en_US
 * word list available, we'll return only the en_US one.
 * Thus, the list will contain as many files as there are categories.
 *
 * @param locale the locale to find the dictionary files for, as a string.
 * @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.
 */
public static File[] getCachedWordLists(final String locale, final Context context) {
    final File[] directoryList = DictionaryInfoUtils.getCachedDirectoryList(context);
    if (null == directoryList) return EMPTY_FILE_ARRAY;
    final HashMap<String, FileAndMatchLevel> cacheFiles = new HashMap<>();
    for (File directory : directoryList) {
        if (!directory.isDirectory()) continue;
        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 =
                            DictionaryInfoUtils.getCategoryFromFileName(wordList.getName());
                    final FileAndMatchLevel currentBestMatch = cacheFiles.get(category);
                    if (null == currentBestMatch || currentBestMatch.mMatchLevel < matchLevel) {
                        cacheFiles.put(category, new FileAndMatchLevel(wordList, matchLevel));
                    }
                }
            }
        }
    }
    if (cacheFiles.isEmpty()) return EMPTY_FILE_ARRAY;
    final File[] result = new File[cacheFiles.size()];
    int index = 0;
    for (final FileAndMatchLevel entry : cacheFiles.values()) {
        result[index++] = entry.mFile;
    }
    return result;
}
 
Example #6
Source File: DictionaryFactory.java    From Indic-Keyboard with Apache License 2.0 5 votes vote down vote up
/**
 * Kills a dictionary so that it is never used again, if possible.
 * @param context The context to contact the dictionary provider, if possible.
 * @param f A file address to the dictionary to kill.
 */
public static void killDictionary(final Context context, final AssetFileAddress f) {
    if (f.pointsToPhysicalFile()) {
        f.deleteUnderlyingFile();
        // Warn the dictionary provider if the dictionary came from there.
        final ContentProviderClient providerClient;
        try {
            providerClient = context.getContentResolver().acquireContentProviderClient(
                    BinaryDictionaryFileDumper.getProviderUriBuilder("").build());
        } catch (final SecurityException e) {
            Log.e(TAG, "No permission to communicate with the dictionary provider", e);
            return;
        }
        if (null == providerClient) {
            Log.e(TAG, "Can't establish communication with the dictionary provider");
            return;
        }
        final String wordlistId =
                DictionaryInfoUtils.getWordListIdFromFileName(new File(f.mFilename).getName());
        // TODO: this is a reasonable last resort, but it is suboptimal.
        // The following will remove the entry for this dictionary with the dictionary
        // provider. When the metadata is downloaded again, we will try downloading it
        // again.
        // 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,
        // 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.
        // Ideally, we would trigger a new download right away, and use increasing retry
        // delays for this particular id/version combination.
        // 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.
        // If it's a file left over from the last version however, it's not great.
        BinaryDictionaryFileDumper.reportBrokenFileToDictionaryProvider(
                providerClient,
                context.getString(R.string.dictionary_pack_client_id),
                wordlistId);
    }
}
 
Example #7
Source File: BinaryDictionaryGetter.java    From Indic-Keyboard with Apache License 2.0 5 votes vote down vote up
/**
 * Generates a unique temporary file name in the app cache directory.
 */
public static String getTempFileName(final String id, final Context context)
        throws IOException {
    final String safeId = DictionaryInfoUtils.replaceFileNameDangerousCharacters(id);
    final File directory = new File(DictionaryInfoUtils.getWordListTempDirectory(context));
    if (!directory.exists()) {
        if (!directory.mkdirs()) {
            Log.e(TAG, "Could not create the temporary directory");
        }
    }
    // If the first argument is less than three chars, createTempFile throws a
    // RuntimeException. We don't really care about what name we get, so just
    // put a three-chars prefix makes us safe.
    return File.createTempFile("xxx" + safeId, null, directory).getAbsolutePath();
}
 
Example #8
Source File: BinaryDictionaryGetter.java    From Indic-Keyboard with Apache License 2.0 5 votes vote down vote up
/**
 * Returns the list of cached files for a specific locale, one for each category.
 *
 * This will return exactly one file for each word list category that matches
 * the passed locale. If several files match the locale for any given category,
 * this returns the file with the closest match to the locale. For example, if
 * the passed word list is en_US, and for a category we have an en and an en_US
 * word list available, we'll return only the en_US one.
 * Thus, the list will contain as many files as there are categories.
 *
 * @param locale the locale to find the dictionary files for, as a string.
 * @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.
 */
public static File[] getCachedWordLists(final String locale, final Context context) {
    final File[] directoryList = DictionaryInfoUtils.getCachedDirectoryList(context);
    if (null == directoryList) return EMPTY_FILE_ARRAY;
    final HashMap<String, FileAndMatchLevel> cacheFiles = new HashMap<>();
    for (File directory : directoryList) {
        if (!directory.isDirectory()) continue;
        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 =
                            DictionaryInfoUtils.getCategoryFromFileName(wordList.getName());
                    final FileAndMatchLevel currentBestMatch = cacheFiles.get(category);
                    if (null == currentBestMatch || currentBestMatch.mMatchLevel < matchLevel) {
                        cacheFiles.put(category, new FileAndMatchLevel(wordList, matchLevel));
                    }
                }
            }
        }
    }
    if (cacheFiles.isEmpty()) return EMPTY_FILE_ARRAY;
    final File[] result = new File[cacheFiles.size()];
    int index = 0;
    for (final FileAndMatchLevel entry : cacheFiles.values()) {
        result[index++] = entry.mFile;
    }
    return result;
}
 
Example #9
Source File: BinaryDictionaryGetter.java    From Android-Keyboard with Apache License 2.0 4 votes vote down vote up
/**
 * Returns a list of file addresses for a given locale, trying relevant methods in order.
 *
 * Tries to get binary dictionaries from various sources, in order:
 * - Uses a content provider to get a public dictionary set, as per the protocol described
 *   in BinaryDictionaryFileDumper.
 * If that fails:
 * - Gets a file name from the built-in dictionary for this locale, if any.
 * If that fails:
 * - Returns null.
 * @return The list of addresses of valid dictionary files, or null.
 */
public static ArrayList<AssetFileAddress> getDictionaryFiles(final Locale locale,
        final Context context, boolean notifyDictionaryPackForUpdates) {
    if (notifyDictionaryPackForUpdates) {
        final boolean hasDefaultWordList = DictionaryInfoUtils.isDictionaryAvailable(
                context, locale);
        // It makes sure that the first time keyboard comes up and the dictionaries are reset,
        // the DB is populated with the appropriate values for each locale. Helps in downloading
        // the dictionaries when the user enables and switches new languages before the
        // DictionaryService runs.
        BinaryDictionaryFileDumper.downloadDictIfNeverRequested(
                locale, context, hasDefaultWordList);

        // Move a staging files to the cache ddirectories if any.
        DictionaryInfoUtils.moveStagingFilesIfExists(context);
    }
    final File[] cachedWordLists = getCachedWordLists(locale.toString(), context);
    final String mainDictId = DictionaryInfoUtils.getMainDictId(locale);
    final DictPackSettings dictPackSettings = new DictPackSettings(context);

    boolean foundMainDict = false;
    final ArrayList<AssetFileAddress> fileList = new ArrayList<>();
    // cachedWordLists may not be null, see doc for getCachedDictionaryList
    for (final File f : cachedWordLists) {
        final String wordListId = DictionaryInfoUtils.getWordListIdFromFileName(f.getName());
        final boolean canUse = f.canRead() && hackCanUseDictionaryFile(f);
        if (canUse && DictionaryInfoUtils.isMainWordListId(wordListId)) {
            foundMainDict = true;
        }
        if (!dictPackSettings.isWordListActive(wordListId)) continue;
        if (canUse) {
            final AssetFileAddress afa = AssetFileAddress.makeFromFileName(f.getPath());
            if (null != afa) fileList.add(afa);
        } else {
            Log.e(TAG, "Found a cached dictionary file for " + locale.toString()
                    + " but cannot read or use it");
        }
    }

    if (!foundMainDict && dictPackSettings.isWordListActive(mainDictId)) {
        final int fallbackResId =
                DictionaryInfoUtils.getMainDictionaryResourceId(context.getResources(), locale);
        final AssetFileAddress fallbackAsset = loadFallbackResource(context, fallbackResId);
        if (null != fallbackAsset) {
            fileList.add(fallbackAsset);
        }
    }

    return fileList;
}
 
Example #10
Source File: BinaryDictionaryGetter.java    From AOSP-Kayboard-7.1.2 with Apache License 2.0 4 votes vote down vote up
/**
 * Returns a list of file addresses for a given locale, trying relevant methods in order.
 *
 * Tries to get binary dictionaries from various sources, in order:
 * - Uses a content provider to get a public dictionary set, as per the protocol described
 *   in BinaryDictionaryFileDumper.
 * If that fails:
 * - Gets a file name from the built-in dictionary for this locale, if any.
 * If that fails:
 * - Returns null.
 * @return The list of addresses of valid dictionary files, or null.
 */
public static ArrayList<AssetFileAddress> getDictionaryFiles(final Locale locale,
        final Context context, boolean notifyDictionaryPackForUpdates) {
    if (notifyDictionaryPackForUpdates) {
        final boolean hasDefaultWordList = DictionaryInfoUtils.isDictionaryAvailable(
                context, locale);
        // It makes sure that the first time keyboard comes up and the dictionaries are reset,
        // the DB is populated with the appropriate values for each locale. Helps in downloading
        // the dictionaries when the user enables and switches new languages before the
        // DictionaryService runs.
        BinaryDictionaryFileDumper.downloadDictIfNeverRequested(
                locale, context, hasDefaultWordList);

        // Move a staging files to the cache ddirectories if any.
        DictionaryInfoUtils.moveStagingFilesIfExists(context);
    }
    final File[] cachedWordLists = getCachedWordLists(locale.toString(), context);
    final String mainDictId = DictionaryInfoUtils.getMainDictId(locale);
    final DictPackSettings dictPackSettings = new DictPackSettings(context);

    boolean foundMainDict = false;
    final ArrayList<AssetFileAddress> fileList = new ArrayList<>();
    // cachedWordLists may not be null, see doc for getCachedDictionaryList
    for (final File f : cachedWordLists) {
        final String wordListId = DictionaryInfoUtils.getWordListIdFromFileName(f.getName());
        final boolean canUse = f.canRead() && hackCanUseDictionaryFile(f);
        if (canUse && DictionaryInfoUtils.isMainWordListId(wordListId)) {
            foundMainDict = true;
        }
        if (!dictPackSettings.isWordListActive(wordListId)) continue;
        if (canUse) {
            final AssetFileAddress afa = AssetFileAddress.makeFromFileName(f.getPath());
            if (null != afa) fileList.add(afa);
        } else {
            Log.e(TAG, "Found a cached dictionary file for " + locale.toString()
                    + " but cannot read or use it");
        }
    }

    if (!foundMainDict && dictPackSettings.isWordListActive(mainDictId)) {
        final int fallbackResId =
                DictionaryInfoUtils.getMainDictionaryResourceId(context.getResources(), locale);
        final AssetFileAddress fallbackAsset = loadFallbackResource(context, fallbackResId);
        if (null != fallbackAsset) {
            fileList.add(fallbackAsset);
        }
    }

    return fileList;
}
 
Example #11
Source File: BinaryDictionaryGetter.java    From Indic-Keyboard with Apache License 2.0 4 votes vote down vote up
/**
 * Returns a list of file addresses for a given locale, trying relevant methods in order.
 *
 * Tries to get binary dictionaries from various sources, in order:
 * - Uses a content provider to get a public dictionary set, as per the protocol described
 *   in BinaryDictionaryFileDumper.
 * If that fails:
 * - Gets a file name from the built-in dictionary for this locale, if any.
 * If that fails:
 * - Returns null.
 * @return The list of addresses of valid dictionary files, or null.
 */
public static ArrayList<AssetFileAddress> getDictionaryFiles(final Locale locale,
        final Context context, boolean notifyDictionaryPackForUpdates) {
    if (notifyDictionaryPackForUpdates) {
        final boolean hasDefaultWordList = DictionaryInfoUtils.isDictionaryAvailable(
                context, locale);
        // It makes sure that the first time keyboard comes up and the dictionaries are reset,
        // the DB is populated with the appropriate values for each locale. Helps in downloading
        // the dictionaries when the user enables and switches new languages before the
        // DictionaryService runs.
        BinaryDictionaryFileDumper.downloadDictIfNeverRequested(
                locale, context, hasDefaultWordList);

        // Move a staging files to the cache ddirectories if any.
        DictionaryInfoUtils.moveStagingFilesIfExists(context);
    }
    final File[] cachedWordLists = getCachedWordLists(locale.toString(), context);
    final String mainDictId = DictionaryInfoUtils.getMainDictId(locale);
    final DictPackSettings dictPackSettings = new DictPackSettings(context);

    boolean foundMainDict = false;
    final ArrayList<AssetFileAddress> fileList = new ArrayList<>();
    // cachedWordLists may not be null, see doc for getCachedDictionaryList
    for (final File f : cachedWordLists) {
        final String wordListId = DictionaryInfoUtils.getWordListIdFromFileName(f.getName());
        final boolean canUse = f.canRead() && hackCanUseDictionaryFile(f);
        if (canUse && DictionaryInfoUtils.isMainWordListId(wordListId)) {
            foundMainDict = true;
        }
        if (!dictPackSettings.isWordListActive(wordListId)) continue;
        if (canUse) {
            final AssetFileAddress afa = AssetFileAddress.makeFromFileName(f.getPath());
            if (null != afa) fileList.add(afa);
        } else {
            Log.e(TAG, "Found a cached dictionary file for " + locale.toString()
                    + " but cannot read or use it");
        }
    }

    if (!foundMainDict && dictPackSettings.isWordListActive(mainDictId)) {
        final int fallbackResId =
                DictionaryInfoUtils.getMainDictionaryResourceId(context.getResources(), locale);
        final AssetFileAddress fallbackAsset = loadFallbackResource(context, fallbackResId);
        if (null != fallbackAsset) {
            fileList.add(fallbackAsset);
        }
    }

    return fileList;
}