Check the md5 checksum of the copied file.

If it doesn't match, mark it broken. It means the dictionary pack
will try to install it again next time it updates. We may want to
rethink this.

Bug: 13125743
Change-Id: I0eb547aa7066bed8cb00c009debbafe9181c37ad
diff --git a/java/src/com/android/inputmethod/dictionarypack/MD5Calculator.java b/java/src/com/android/inputmethod/dictionarypack/MD5Calculator.java
index e47e86e..ccd054c 100644
--- a/java/src/com/android/inputmethod/dictionarypack/MD5Calculator.java
+++ b/java/src/com/android/inputmethod/dictionarypack/MD5Calculator.java
@@ -20,7 +20,7 @@
 import java.io.IOException;
 import java.security.MessageDigest;
 
-final class MD5Calculator {
+public final class MD5Calculator {
     private MD5Calculator() {} // This helper class is not instantiable
 
     public static String checksum(final InputStream in) throws IOException {
diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionaryFileDumper.java b/java/src/com/android/inputmethod/latin/BinaryDictionaryFileDumper.java
index 669ad09..72757e0 100644
--- a/java/src/com/android/inputmethod/latin/BinaryDictionaryFileDumper.java
+++ b/java/src/com/android/inputmethod/latin/BinaryDictionaryFileDumper.java
@@ -28,6 +28,7 @@
 import android.util.Log;
 
 import com.android.inputmethod.dictionarypack.DictionaryPackConstants;
+import com.android.inputmethod.dictionarypack.MD5Calculator;
 import com.android.inputmethod.latin.utils.CollectionUtils;
 import com.android.inputmethod.latin.utils.DictionaryInfoUtils;
 import com.android.inputmethod.latin.utils.DictionaryInfoUtils.DictionaryInfo;
@@ -38,6 +39,7 @@
 import java.io.BufferedOutputStream;
 import java.io.Closeable;
 import java.io.File;
+import java.io.FileInputStream;
 import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
 import java.io.IOException;
@@ -218,7 +220,8 @@
      * and creating it (and its containing directory) if necessary.
      */
     private static void cacheWordList(final String wordlistId, final String locale,
-            final ContentProviderClient providerClient, final Context context) {
+            final String rawChecksum, final ContentProviderClient providerClient,
+            final Context context) {
         final int COMPRESSED_CRYPTED_COMPRESSED = 0;
         final int CRYPTED_COMPRESSED = 1;
         final int COMPRESSED_CRYPTED = 2;
@@ -300,6 +303,13 @@
                 checkMagicAndCopyFileTo(bufferedInputStream, bufferedOutputStream);
                 bufferedOutputStream.flush();
                 bufferedOutputStream.close();
+                final String actualRawChecksum = MD5Calculator.checksum(
+                        new BufferedInputStream(new FileInputStream(outputFile)));
+                Log.i(TAG, "Computed checksum for downloaded dictionary. Expected = " + rawChecksum
+                        + " ; actual = " + actualRawChecksum);
+                if (!TextUtils.isEmpty(rawChecksum) && !rawChecksum.equals(actualRawChecksum)) {
+                    throw new IOException("Could not decode the file correctly : checksum differs");
+                }
                 final File finalFile = new File(finalFileName);
                 finalFile.delete();
                 if (!outputFile.renameTo(finalFile)) {
@@ -409,7 +419,7 @@
             final List<WordListInfo> idList = getWordListWordListInfos(locale, context,
                     hasDefaultWordList);
             for (WordListInfo id : idList) {
-                cacheWordList(id.mId, id.mLocale, providerClient, context);
+                cacheWordList(id.mId, id.mLocale, id.mRawChecksum, providerClient, context);
             }
         } finally {
             providerClient.release();