From 1d6024d2f8051271e3c9abc1285d989114f5f1d7 Mon Sep 17 00:00:00 2001
From: Keisuke Kuroyanagi <ksk@google.com>
Date: Mon, 14 Jul 2014 16:25:55 +0900
Subject: [PATCH] Track crashing during migration to avoid crash loop.

Bug: 16213554
Bug: 16235703
Change-Id: Ib29b1a84b4c6ebae06d3dc6448f3c274ec6a7aab
---
 .../inputmethod/latin/BinaryDictionary.java   | 40 ++++++++++++++-----
 1 file changed, 29 insertions(+), 11 deletions(-)

diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionary.java b/java/src/com/android/inputmethod/latin/BinaryDictionary.java
index c799ac7456..693e1cdccd 100644
--- a/java/src/com/android/inputmethod/latin/BinaryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/BinaryDictionary.java
@@ -80,6 +80,7 @@ public final class BinaryDictionary extends Dictionary {
     public static final int FORMAT_WORD_PROPERTY_COUNT_INDEX = 3;
 
     public static final String DICT_FILE_NAME_SUFFIX_FOR_MIGRATION = ".migrate";
+    public static final String DIR_NAME_SUFFIX_FOR_RECORD_MIGRATION = ".migrating";
 
     private long mNativeDict;
     private final Locale mLocale;
@@ -559,22 +560,39 @@ public final class BinaryDictionary extends Dictionary {
         if (!isValidDictionary()) {
             return false;
         }
-        final String tmpDictFilePath = mDictFilePath + DICT_FILE_NAME_SUFFIX_FOR_MIGRATION;
-        if (!migrateNative(mNativeDict, tmpDictFilePath, newFormatVersion)) {
+        final File isMigratingDir =
+                new File(mDictFilePath + DIR_NAME_SUFFIX_FOR_RECORD_MIGRATION);
+        if (isMigratingDir.exists()) {
+            isMigratingDir.delete();
+            Log.e(TAG, "Previous migration attempt failed probably due to a crash. "
+                        + "Giving up using the old dictionary (" + mDictFilePath + ").");
             return false;
         }
-        close();
-        final File dictFile = new File(mDictFilePath);
-        final File tmpDictFile = new File(tmpDictFilePath);
-        if (!FileUtils.deleteRecursively(dictFile)) {
+        if (!isMigratingDir.mkdir()) {
+            Log.e(TAG, "Cannot create a dir (" + isMigratingDir.getAbsolutePath()
+                    + ") to record migration.");
             return false;
         }
-        if (!BinaryDictionaryUtils.renameDict(tmpDictFile, dictFile)) {
-            return false;
+        try {
+            final String tmpDictFilePath = mDictFilePath + DICT_FILE_NAME_SUFFIX_FOR_MIGRATION;
+            if (!migrateNative(mNativeDict, tmpDictFilePath, newFormatVersion)) {
+                return false;
+            }
+            close();
+            final File dictFile = new File(mDictFilePath);
+            final File tmpDictFile = new File(tmpDictFilePath);
+            if (!FileUtils.deleteRecursively(dictFile)) {
+                return false;
+            }
+            if (!BinaryDictionaryUtils.renameDict(tmpDictFile, dictFile)) {
+                return false;
+            }
+            loadDictionary(dictFile.getAbsolutePath(), 0 /* startOffset */,
+                    dictFile.length(), mIsUpdatable);
+            return true;
+        } finally {
+            isMigratingDir.delete();
         }
-        loadDictionary(dictFile.getAbsolutePath(), 0 /* startOffset */,
-                dictFile.length(), mIsUpdatable);
-        return true;
     }
 
     @UsedForTesting
-- 
GitLab