Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cec8552b authored by Jean Chalard's avatar Jean Chalard
Browse files

Pass a parameter to the dict pack if we don't have a default dict

Also, optimize quite a bit the code that decides whether we have
a default dict or not.

Bug: 5705834
Change-Id: Ied20fbcbbc42cbe8c01759d11b1804d1156c6960
parent fed44d08
Loading
Loading
Loading
Loading
+19 −8
Original line number Diff line number Diff line
@@ -53,17 +53,23 @@ public class BinaryDictionaryFileDumper {

    private static final String DICTIONARY_PROJECTION[] = { "id" };

    public static final String QUERY_PARAMETER_MAY_PROMPT_USER = "mayPrompt";
    public static final String QUERY_PARAMETER_TRUE = "true";

    // Prevents this class to be accidentally instantiated.
    private BinaryDictionaryFileDumper() {
    }

    /**
     * Return for a given locale or dictionary id the provider URI to get the dictionary.
     * Returns a URI builder pointing to the dictionary pack.
     *
     * This creates a URI builder able to build a URI pointing to the dictionary
     * pack content provider for a specific dictionary id.
     */
    private static Uri getProviderUri(String path) {
    private static Uri.Builder getProviderUriBuilder(final String path) {
        return new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT)
                .authority(BinaryDictionary.DICTIONARY_PACK_AUTHORITY).appendPath(
                        path).build();
                        path);
    }

    /**
@@ -71,9 +77,13 @@ public class BinaryDictionaryFileDumper {
     * available to copy into Latin IME.
     */
    private static List<WordListInfo> getWordListWordListInfos(final Locale locale,
            final Context context) {
            final Context context, final boolean hasDefaultWordList) {
        final ContentResolver resolver = context.getContentResolver();
        final Uri dictionaryPackUri = getProviderUri(locale.toString());
        final Uri.Builder builder = getProviderUriBuilder(locale.toString());
        if (!hasDefaultWordList) {
            builder.appendQueryParameter(QUERY_PARAMETER_MAY_PROMPT_USER, QUERY_PARAMETER_TRUE);
        }
        final Uri dictionaryPackUri = builder.build();

        final Cursor c = resolver.query(dictionaryPackUri, DICTIONARY_PROJECTION, null, null, null);
        if (null == c) return Collections.<WordListInfo>emptyList();
@@ -132,7 +142,7 @@ public class BinaryDictionaryFileDumper {
        final int MODE_MIN = COMPRESSED_CRYPTED_COMPRESSED;
        final int MODE_MAX = NONE;

        final Uri wordListUri = getProviderUri(id);
        final Uri wordListUri = getProviderUriBuilder(id).build();
        final String outputFileName = BinaryDictionaryGetter.getCacheFileName(id, locale, context);

        for (int mode = MODE_MIN; mode <= MODE_MAX; ++mode) {
@@ -231,9 +241,10 @@ public class BinaryDictionaryFileDumper {
     * @throw IOException if the provider-returned data could not be read.
     */
    public static List<AssetFileAddress> cacheWordListsFromContentProvider(final Locale locale,
            final Context context) {
            final Context context, final boolean hasDefaultWordList) {
        final ContentResolver resolver = context.getContentResolver();
        final List<WordListInfo> idList = getWordListWordListInfos(locale, context);
        final List<WordListInfo> idList = getWordListWordListInfos(locale, context,
                hasDefaultWordList);
        final List<AssetFileAddress> fileAddressList = new ArrayList<AssetFileAddress>();
        for (WordListInfo id : idList) {
            final AssetFileAddress afd = cacheWordList(id.mId, id.mLocale, resolver, context);
+3 −1
Original line number Diff line number Diff line
@@ -263,10 +263,12 @@ class BinaryDictionaryGetter {
    public static ArrayList<AssetFileAddress> getDictionaryFiles(final Locale locale,
            final Context context) {

        final boolean hasDefaultWordList = DictionaryFactory.isDictionaryAvailable(context, locale);
        // cacheWordListsFromContentProvider 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.cacheWordListsFromContentProvider(locale, context);
        BinaryDictionaryFileDumper.cacheWordListsFromContentProvider(locale, context,
                hasDefaultWordList);
        final File[] cachedWordLists = getCachedWordLists(locale.toString(), context);

        final String mainDictId = getMainDictId(locale);
+20 −42
Original line number Diff line number Diff line
@@ -94,13 +94,14 @@ public class DictionaryFactory {
            final Locale locale) {
        AssetFileDescriptor afd = null;
        try {
            final int resId = getMainDictionaryResourceId(context.getResources(), locale);
            final int resId =
                    getMainDictionaryResourceIdIfAvailableForLocale(context.getResources(), locale);
            if (0 == resId) return null;
            afd = context.getResources().openRawResourceFd(resId);
            if (afd == null) {
                Log.e(TAG, "Found the resource but it is compressed. resId=" + resId);
                return null;
            }
            if (!isFullDictionary(afd)) return null;
            final String sourceDir = context.getApplicationInfo().sourceDir;
            final File packagePath = new File(sourceDir);
            // TODO: Come up with a way to handle a directory.
@@ -152,55 +153,19 @@ public class DictionaryFactory {
     */
    public static boolean isDictionaryAvailable(Context context, Locale locale) {
        final Resources res = context.getResources();
        final int resourceId = getMainDictionaryResourceId(res, locale);
        final AssetFileDescriptor afd = res.openRawResourceFd(resourceId);
        final boolean hasDictionary = isFullDictionary(afd);
        try {
            if (null != afd) afd.close();
        } catch (java.io.IOException e) {
            /* Um, what can we do here exactly? */
        }
        return hasDictionary;
    }

    // TODO: Do not use the size of the dictionary as an unique dictionary ID.
    public static Long getDictionaryId(final Context context, final Locale locale) {
        final Resources res = context.getResources();
        final int resourceId = getMainDictionaryResourceId(res, locale);
        final AssetFileDescriptor afd = res.openRawResourceFd(resourceId);
        final Long size = (afd != null && afd.getLength() > PLACEHOLDER_LENGTH)
                ? afd.getLength()
                : null;
        try {
            if (null != afd) afd.close();
        } catch (java.io.IOException e) {
        }
        return size;
    }

    // TODO: Find the Right Way to find out whether the resource is a placeholder or not.
    // Suggestion : strip the locale, open the placeholder file and store its offset.
    // Upon opening the file, if it's the same offset, then it's the placeholder.
    private static final long PLACEHOLDER_LENGTH = 34;
    /**
     * Finds out whether the data pointed out by an AssetFileDescriptor is a full
     * dictionary (as opposed to null, or to a place holder).
     * @param afd the file descriptor to test, or null
     * @return true if the dictionary is a real full dictionary, false if it's null or a placeholder
     */
    protected static boolean isFullDictionary(final AssetFileDescriptor afd) {
        return (afd != null && afd.getLength() > PLACEHOLDER_LENGTH);
        return 0 != getMainDictionaryResourceIdIfAvailableForLocale(res, locale);
    }

    private static final String DEFAULT_MAIN_DICT = "main";
    private static final String MAIN_DICT_PREFIX = "main_";

    /**
     * Returns a main dictionary resource id
     * 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 getMainDictionaryResourceId(Resources res, Locale locale) {
    private static int getMainDictionaryResourceIdIfAvailableForLocale(final Resources res,
            final Locale locale) {
        final String packageName = LatinIME.class.getPackage().getName();
        int resId;

@@ -218,6 +183,19 @@ public class DictionaryFactory {
            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;
        final String packageName = LatinIME.class.getPackage().getName();
        return res.getIdentifier(DEFAULT_MAIN_DICT, "raw", packageName);
    }
}