Loading java/src/com/android/inputmethod/dictionarypack/ActionBatch.java +2 −1 Original line number Diff line number Diff line Loading @@ -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 Loading java/src/com/android/inputmethod/dictionarypack/UpdateHandler.java +3 −1 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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(); } Loading java/src/com/android/inputmethod/latin/utils/DictionaryInfoUtils.java +86 −21 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading @@ -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"; Loading @@ -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; } Loading @@ -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; } Loading Loading @@ -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. * Loading Loading @@ -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); } /** Loading @@ -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, Loading @@ -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) { Loading @@ -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 Loading
java/src/com/android/inputmethod/dictionarypack/ActionBatch.java +2 −1 Original line number Diff line number Diff line Loading @@ -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 Loading
java/src/com/android/inputmethod/dictionarypack/UpdateHandler.java +3 −1 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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(); } Loading
java/src/com/android/inputmethod/latin/utils/DictionaryInfoUtils.java +86 −21 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading @@ -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"; Loading @@ -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; } Loading @@ -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; } Loading Loading @@ -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. * Loading Loading @@ -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); } /** Loading @@ -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, Loading @@ -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) { Loading @@ -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