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
This commit is contained in:
parent
bf732e7001
commit
3a5de64110
3 changed files with 91 additions and 23 deletions
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
return new DictionaryInfo(id, locale, description, fileAddress, version);
|
||||
// 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());
|
||||
|
||||
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();
|
||||
|
|
Loading…
Reference in a new issue