aboutsummaryrefslogtreecommitdiffstats
path: root/java/src/com/android/inputmethod/latin/DictionaryFactory.java
diff options
context:
space:
mode:
authorJean Chalard <jchalard@google.com>2013-12-04 12:47:05 +0900
committerJean Chalard <jchalard@google.com>2013-12-04 16:19:55 +0900
commit5e80e699c4369d3f4604728952ac3d4bc0bae23a (patch)
tree8a65896229e2dadf709b4ba8d03024d263c7de39 /java/src/com/android/inputmethod/latin/DictionaryFactory.java
parent294fe541c8689a1cb0783e16b83159a035464a5c (diff)
downloadlatinime-5e80e699c4369d3f4604728952ac3d4bc0bae23a.tar.gz
latinime-5e80e699c4369d3f4604728952ac3d4bc0bae23a.tar.xz
latinime-5e80e699c4369d3f4604728952ac3d4bc0bae23a.zip
[RF1] Remove files that don't match the expected format, step 1
This implements the skeleton implementation, and enables a fallback implementation in the case the file is coming from the dictionary provider. - A better scheme should be used for provider-supplied dicts. - This does not implement the solution for device-generated dicts yet. This will come in a future change. - This does not implement the checking process on the native side yet. This will come in a future change. Bug: 11281748 Change-Id: Ifa6e237d19dfbffe503e3674915480ea867b0ddf
Diffstat (limited to 'java/src/com/android/inputmethod/latin/DictionaryFactory.java')
-rw-r--r--java/src/com/android/inputmethod/latin/DictionaryFactory.java52
1 files changed, 51 insertions, 1 deletions
diff --git a/java/src/com/android/inputmethod/latin/DictionaryFactory.java b/java/src/com/android/inputmethod/latin/DictionaryFactory.java
index 828e54f14..bcb38da38 100644
--- a/java/src/com/android/inputmethod/latin/DictionaryFactory.java
+++ b/java/src/com/android/inputmethod/latin/DictionaryFactory.java
@@ -16,6 +16,7 @@
package com.android.inputmethod.latin;
+import android.content.ContentProviderClient;
import android.content.Context;
import android.content.res.AssetFileDescriptor;
import android.content.res.Resources;
@@ -62,8 +63,12 @@ public final class DictionaryFactory {
final ReadOnlyBinaryDictionary readOnlyBinaryDictionary =
new ReadOnlyBinaryDictionary(f.mFilename, f.mOffset, f.mLength,
useFullEditDistance, locale, Dictionary.TYPE_MAIN);
- if (readOnlyBinaryDictionary.isValidDictionary()) {
+ if (readOnlyBinaryDictionary.hasValidContents()) {
dictList.add(readOnlyBinaryDictionary);
+ } else {
+ readOnlyBinaryDictionary.close();
+ // Prevent this dictionary to do any further harm.
+ killDictionary(context, f);
}
}
}
@@ -75,6 +80,51 @@ public final class DictionaryFactory {
}
/**
+ * Kills a dictionary so that it is never used again, if possible.
+ * @param context The context to contact the dictionary provider, if possible.
+ * @param f A file address to the dictionary to kill.
+ */
+ private static void killDictionary(final Context context, final AssetFileAddress f) {
+ if (f.pointsToPhysicalFile()) {
+ f.deleteUnderlyingFile();
+ // Warn the dictionary provider if the dictionary came from there.
+ final ContentProviderClient providerClient;
+ try {
+ providerClient = context.getContentResolver().acquireContentProviderClient(
+ BinaryDictionaryFileDumper.getProviderUriBuilder("").build());
+ } catch (final SecurityException e) {
+ Log.e(TAG, "No permission to communicate with the dictionary provider", e);
+ return;
+ }
+ if (null == providerClient) {
+ Log.e(TAG, "Can't establish communication with the dictionary provider");
+ return;
+ }
+ final String wordlistId =
+ DictionaryInfoUtils.getWordListIdFromFileName(new File(f.mFilename).getName());
+ if (null != wordlistId) {
+ // TODO: this is a reasonable last resort, but it is suboptimal.
+ // The following will remove the entry for this dictionary with the dictionary
+ // provider. When the metadata is downloaded again, we will try downloading it
+ // again.
+ // However, in the practice that will mean the user will find themselves without
+ // the new dictionary. That's fine for languages where it's included in the APK,
+ // but for other languages it will leave the user without a dictionary at all until
+ // the next update, which may be a few days away.
+ // Ideally, we would trigger a new download right away, and use increasing retry
+ // delays for this particular id/version combination.
+ // Then again, this is expected to only ever happen in case of human mistake. If
+ // the wrong file is on the server, the following is still doing the right thing.
+ // If it's a file left over from the last version however, it's not great.
+ BinaryDictionaryFileDumper.reportBrokenFileToDictionaryProvider(
+ providerClient,
+ context.getString(R.string.dictionary_pack_client_id),
+ wordlistId);
+ }
+ }
+ }
+
+ /**
* Initializes a main dictionary collection from a dictionary pack, with default flags.
*
* This searches for a content provider providing a dictionary pack for the specified