diff --git a/java/src/com/android/inputmethod/latin/AssetFileAddress.java b/java/src/com/android/inputmethod/latin/AssetFileAddress.java index 855a8d8c7..fd6c24dfe 100644 --- a/java/src/com/android/inputmethod/latin/AssetFileAddress.java +++ b/java/src/com/android/inputmethod/latin/AssetFileAddress.java @@ -16,6 +16,8 @@ package com.android.inputmethod.latin; +import com.android.inputmethod.latin.utils.FileUtils; + import java.io.File; /** @@ -58,6 +60,6 @@ public final class AssetFileAddress { } public void deleteUnderlyingFile() { - new File(mFilename).delete(); + FileUtils.deleteRecursively(new File(mFilename)); } } diff --git a/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java b/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java index 41661573d..f53dc3748 100644 --- a/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java +++ b/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java @@ -27,6 +27,7 @@ import com.android.inputmethod.latin.makedict.FormatSpec; import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo; import com.android.inputmethod.latin.utils.AsyncResultHolder; import com.android.inputmethod.latin.utils.CollectionUtils; +import com.android.inputmethod.latin.utils.FileUtils; import com.android.inputmethod.latin.utils.PrioritizedSerialExecutor; import java.io.File; @@ -568,7 +569,9 @@ abstract public class ExpandableBinaryDictionary extends Dictionary { || !matchesExpectedBinaryDictFormatVersionForThisType( mBinaryDictionary.getFormatVersion())) { final File file = new File(mContext.getFilesDir(), mFilename); - file.delete(); + if (!FileUtils.deleteRecursively(file)) { + Log.e(TAG, "Can't remove a file: " + file.getName()); + } BinaryDictionary.createEmptyDictFile(file.getAbsolutePath(), DICTIONARY_FORMAT_VERSION, getHeaderAttributeMap()); } else { @@ -664,17 +667,26 @@ abstract public class ExpandableBinaryDictionary extends Dictionary { // load the shared dictionary. loadBinaryDictionary(); } - if (mBinaryDictionary != null && !(isValidDictionary() - // TODO: remove the check below - && matchesExpectedBinaryDictFormatVersionForThisType( - mBinaryDictionary.getFormatVersion()))) { - // Binary dictionary or its format version is not valid. Regenerate the - // dictionary file. - mFilenameDictionaryUpdateController.mLastUpdateTime = time; - writeBinaryDictionary(); - loadBinaryDictionary(); - } - mPerInstanceDictionaryUpdateController.mLastUpdateTime = time; + // If we just loaded the binary dictionary, then mBinaryDictionary is not + // up-to-date yet so it's useless to test it right away. Schedule the check + // for right after it's loaded instead. + getExecutor(mFilename).executePrioritized(new Runnable() { + @Override + public void run() { + if (mBinaryDictionary != null && !(isValidDictionary() + // TODO: remove the check below + && matchesExpectedBinaryDictFormatVersionForThisType( + mBinaryDictionary.getFormatVersion()))) { + // Binary dictionary or its format version is not valid. Regenerate + // the dictionary file. writeBinaryDictionary will remove the + // existing files if appropriate. + mFilenameDictionaryUpdateController.mLastUpdateTime = time; + writeBinaryDictionary(); + loadBinaryDictionary(); + } + mPerInstanceDictionaryUpdateController.mLastUpdateTime = time; + } + }); } finally { mFilenameDictionaryUpdateController.mProcessingLargeTask.set(false); } diff --git a/java/src/com/android/inputmethod/latin/utils/FileUtils.java b/java/src/com/android/inputmethod/latin/utils/FileUtils.java new file mode 100644 index 000000000..83c1e7c4d --- /dev/null +++ b/java/src/com/android/inputmethod/latin/utils/FileUtils.java @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package com.android.inputmethod.latin.utils; + +import java.io.File; + +/** + * A simple class to help with removing directories recursively. + */ +public class FileUtils { + public static boolean deleteRecursively(final File path) { + if (path.isDirectory()) { + for (final File child : path.listFiles()) { + deleteRecursively(child); + } + } + return path.delete(); + } +} diff --git a/native/jni/src/suggest/policyimpl/dictionary/header/header_read_write_utils.cpp b/native/jni/src/suggest/policyimpl/dictionary/header/header_read_write_utils.cpp index 5ef8e50b4..f5eee99c3 100644 --- a/native/jni/src/suggest/policyimpl/dictionary/header/header_read_write_utils.cpp +++ b/native/jni/src/suggest/policyimpl/dictionary/header/header_read_write_utils.cpp @@ -116,10 +116,10 @@ const char *const HeaderReadWriteUtils::REQUIRES_FRENCH_LIGATURE_PROCESSING_KEY // Version 2 dictionary writing is not supported. return false; case FormatUtils::VERSION_3: - return buffer->writeUintAndAdvancePosition(3 /* data */, + return buffer->writeUintAndAdvancePosition(FormatUtils::VERSION_3 /* data */, HEADER_DICTIONARY_VERSION_SIZE, writingPos); case FormatUtils::VERSION_4: - return buffer->writeUintAndAdvancePosition(4 /* data */, + return buffer->writeUintAndAdvancePosition(FormatUtils::VERSION_4 /* data */, HEADER_DICTIONARY_VERSION_SIZE, writingPos); default: return false;