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

Commit 3a5de641 authored by Mohammadinamul Sheik's avatar Mohammadinamul Sheik
Browse files

Do not re-download the unused dictionaries.

Does the following
1. Uses dictionaries from the files/ directory while populating the
   entries into the pendingUpdates table. So that a download happens only
   if the metadata.json says so.
2. Delete an unusable dictionaries from the files/ directory.

Bug: 20142708
Change-Id: Ibd738793585c39735868e324b8ad682dff0eba34
parent bf732e70
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -377,7 +377,8 @@ public final class ActionBatch {
            final ContentValues values = MetadataDbHelper.makeContentValues(0,
                    MetadataDbHelper.TYPE_BULK, MetadataDbHelper.STATUS_INSTALLED,
                    mWordList.mId, mWordList.mLocale, mWordList.mDescription,
                    "", mWordList.mRemoteFilename, mWordList.mLastUpdate,
                    TextUtils.isEmpty(mWordList.mLocalFilename) ? "" : mWordList.mLocalFilename,
                    mWordList.mRemoteFilename, mWordList.mLastUpdate,
                    mWordList.mRawChecksum, mWordList.mChecksum, mWordList.mRetryCount,
                    mWordList.mFileSize, mWordList.mVersion, mWordList.mFormatVersion);
            PrivateLog.log("Insert 'preinstalled' record for " + mWordList.mDescription
+3 −1
Original line number Diff line number Diff line
@@ -95,6 +95,8 @@ public final class UpdateHandler {
    // Name of the category for the main dictionary
    public static final String MAIN_DICTIONARY_CATEGORY = "main";

    public static final String TEMP_DICT_FILE_SUB = "___";

    // The id for the "dictionary available" notification.
    static final int DICT_AVAILABLE_NOTIFICATION_ID = 1;

@@ -743,7 +745,7 @@ public final class UpdateHandler {
            throws IOException {
        DebugLogUtils.l("Entering openTempFileOutput");
        final File dir = context.getFilesDir();
        final File f = File.createTempFile(locale + "___", DICT_FILE_SUFFIX, dir);
        final File f = File.createTempFile(locale + TEMP_DICT_FILE_SUB, DICT_FILE_SUFFIX, dir);
        DebugLogUtils.l("File name is", f.getName());
        return f.getName();
    }
+86 −21
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@ import android.util.Log;
import android.view.inputmethod.InputMethodSubtype;

import com.android.inputmethod.annotations.UsedForTesting;
import com.android.inputmethod.dictionarypack.UpdateHandler;
import com.android.inputmethod.latin.AssetFileAddress;
import com.android.inputmethod.latin.BinaryDictionaryGetter;
import com.android.inputmethod.latin.R;
@@ -36,6 +37,7 @@ import com.android.inputmethod.latin.makedict.UnsupportedFormatException;
import com.android.inputmethod.latin.settings.SpacingAndPunctuations;

import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
@@ -58,6 +60,8 @@ public class DictionaryInfoUtils {
    // 6 digits - unicode is limited to 21 bits
    private static final int MAX_HEX_DIGITS_FOR_CODEPOINT = 6;

    private static final String TEMP_DICT_FILE_SUB = UpdateHandler.TEMP_DICT_FILE_SUB;

    public static class DictionaryInfo {
        private static final String LOCALE_COLUMN = "locale";
        private static final String WORDLISTID_COLUMN = "id";
@@ -66,22 +70,24 @@ public class DictionaryInfoUtils {
        private static final String DATE_COLUMN = "date";
        private static final String FILESIZE_COLUMN = "filesize";
        private static final String VERSION_COLUMN = "version";
        @Nonnull
        public final String mId;
        @Nonnull
        public final Locale mLocale;
        @Nullable
        public final String mDescription;
        public final AssetFileAddress mFileAddress;

        @Nonnull public final String mId;
        @Nonnull public final Locale mLocale;
        @Nullable public final String mDescription;
        @Nullable public final String mFilename;
        public final long mFilesize;
        public final long mModifiedTimeMillis;
        public final int mVersion;

        public DictionaryInfo(@Nonnull final String id, @Nonnull final Locale locale,
                @Nullable final String description, @Nullable final AssetFileAddress fileAddress,
                final int version) {
        public DictionaryInfo(@Nonnull String id, @Nonnull Locale locale,
                @Nullable String description, @Nullable String filename,
                long filesize, long modifiedTimeMillis, int version) {
            mId = id;
            mLocale = locale;
            mDescription = description;
            mFileAddress = fileAddress;
            mFilename = filename;
            mFilesize = filesize;
            mModifiedTimeMillis = modifiedTimeMillis;
            mVersion = version;
        }

@@ -90,12 +96,9 @@ public class DictionaryInfoUtils {
            values.put(WORDLISTID_COLUMN, mId);
            values.put(LOCALE_COLUMN, mLocale.toString());
            values.put(DESCRIPTION_COLUMN, mDescription);
            values.put(LOCAL_FILENAME_COLUMN,
                    mFileAddress != null ? mFileAddress.mFilename : "");
            values.put(DATE_COLUMN, TimeUnit.MILLISECONDS.toSeconds(
                    mFileAddress != null ? new File(mFileAddress.mFilename).lastModified() : 0));
            values.put(FILESIZE_COLUMN,
                    mFileAddress != null ? mFileAddress.mLength : 0);
            values.put(LOCAL_FILENAME_COLUMN, mFilename != null ? mFilename : "");
            values.put(DATE_COLUMN, TimeUnit.MILLISECONDS.toSeconds(mModifiedTimeMillis));
            values.put(FILESIZE_COLUMN, mFilesize);
            values.put(VERSION_COLUMN, mVersion);
            return values;
        }
@@ -185,6 +188,17 @@ public class DictionaryInfoUtils {
        return new File(DictionaryInfoUtils.getWordListCacheDirectory(context)).listFiles();
    }

    @Nullable
    public static File[] getUnusedDictionaryList(final Context context) {
        return context.getFilesDir().listFiles(new FilenameFilter() {
            @Override
            public boolean accept(File dir, String filename) {
                return !TextUtils.isEmpty(filename) && filename.endsWith(".dict")
                        && filename.contains(TEMP_DICT_FILE_SUB);
            }
        });
    }

    /**
     * Returns the category for a given file name.
     *
@@ -342,12 +356,44 @@ public class DictionaryInfoUtils {
     * @return information of the specified dictionary.
     */
    private static DictionaryInfo createDictionaryInfoFromFileAddress(
            final AssetFileAddress fileAddress, Locale locale) {
            @Nonnull final AssetFileAddress fileAddress, final Locale locale) {
        final String id = getMainDictId(locale);
        final int version = DictionaryHeaderUtils.getContentVersion(fileAddress);
        final String description = SubtypeLocaleUtils
                .getSubtypeLocaleDisplayName(locale.toString());
        // Do not store the filename on db as it will try to move the filename from db to the
        // cached directory. If the filename is already in cached directory, this is not
        // necessary.
        final String filenameToStoreOnDb = null;
        return new DictionaryInfo(id, locale, description, filenameToStoreOnDb,
                fileAddress.mLength, new File(fileAddress.mFilename).lastModified(), version);
    }

    /**
     * Returns the information of the dictionary for the given {@link AssetFileAddress}.
     * If the file is corrupted or a pre-fava file, then the file gets deleted and the null
     * value is returned.
     */
    @Nullable
    private static DictionaryInfo createDictionaryInfoForUnCachedFile(
            @Nonnull final AssetFileAddress fileAddress, final Locale locale) {
        final String id = getMainDictId(locale);
        final int version = DictionaryHeaderUtils.getContentVersion(fileAddress);

        if (version == -1) {
            // Purge the pre-fava/corrupted unused dictionaires.
            fileAddress.deleteUnderlyingFile();
            return null;
        }

        final String description = SubtypeLocaleUtils
                .getSubtypeLocaleDisplayName(locale.toString());
        return new DictionaryInfo(id, locale, description, fileAddress, version);

        final File unCachedFile = new File(fileAddress.mFilename);
        // Store just the filename and not the full path.
        final String filenameToStoreOnDb = unCachedFile.getName();
        return new DictionaryInfo(id, locale, description, filenameToStoreOnDb, fileAddress.mLength,
                unCachedFile.lastModified(), version);
    }

    /**
@@ -358,7 +404,7 @@ public class DictionaryInfoUtils {
        final int version = -1;
        final String description = SubtypeLocaleUtils
                .getSubtypeLocaleDisplayName(locale.toString());
        return new DictionaryInfo(id, locale, description, null, version);
        return new DictionaryInfo(id, locale, description, null, 0L, 0L, version);
    }

    private static void addOrUpdateDictInfo(final ArrayList<DictionaryInfo> dictList,
@@ -380,7 +426,7 @@ public class DictionaryInfoUtils {
            final Context context) {
        final ArrayList<DictionaryInfo> dictList = new ArrayList<>();

        // Retrieve downloaded dictionaries
        // Retrieve downloaded dictionaries from cached directories
        final File[] directoryList = getCachedDirectoryList(context);
        if (null != directoryList) {
            for (final File directory : directoryList) {
@@ -407,6 +453,25 @@ public class DictionaryInfoUtils {
            }
        }

        // Retrieve downloaded dictionaries from the unused dictionaries.
        File[] unusedDictionaryList = getUnusedDictionaryList(context);
        if (unusedDictionaryList != null) {
            for (File dictionaryFile : unusedDictionaryList) {
                String fileName = dictionaryFile.getName();
                int index = fileName.indexOf(TEMP_DICT_FILE_SUB);
                if (index == -1) {
                    continue;
                }
                String locale = fileName.substring(0, index);
                DictionaryInfo dictionaryInfo = createDictionaryInfoForUnCachedFile(
                        AssetFileAddress.makeFromFile(dictionaryFile),
                        LocaleUtils.constructLocaleFromString(locale));
                if (dictionaryInfo != null) {
                    addOrUpdateDictInfo(dictList, dictionaryInfo);
                }
            }
        }

        // Retrieve files from assets
        final Resources resources = context.getResources();
        final AssetManager assets = resources.getAssets();