Reconcile with jb-release

Change-Id: Ifd10621e6d78fd5df0e3e6b01b8e80a65e5503fe
diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionaryFileDumper.java b/java/src/com/android/inputmethod/latin/BinaryDictionaryFileDumper.java
index 37eced5..236c198 100644
--- a/java/src/com/android/inputmethod/latin/BinaryDictionaryFileDumper.java
+++ b/java/src/com/android/inputmethod/latin/BinaryDictionaryFileDumper.java
@@ -149,7 +149,8 @@
         final int MODE_MAX = NONE;
 
         final Uri.Builder wordListUriBuilder = getProviderUriBuilder(id);
-        final String outputFileName = BinaryDictionaryGetter.getCacheFileName(id, locale, context);
+        final String finalFileName = BinaryDictionaryGetter.getCacheFileName(id, locale, context);
+        final String tempFileName = finalFileName + ".tmp";
 
         for (int mode = MODE_MIN; mode <= MODE_MAX; ++mode) {
             InputStream originalSourceStream = null;
@@ -165,7 +166,10 @@
                 if (null == afd) return null;
                 originalSourceStream = afd.createInputStream();
                 // Open output.
-                outputFile = new File(outputFileName);
+                outputFile = new File(tempFileName);
+                // Just to be sure, delete the file. This may fail silently, and return false: this
+                // is the right thing to do, as we just want to continue anyway.
+                outputFile.delete();
                 outputStream = new FileOutputStream(outputFile);
                 // Get the appropriate decryption method for this try
                 switch (mode) {
@@ -194,14 +198,20 @@
                         break;
                     }
                 checkMagicAndCopyFileTo(new BufferedInputStream(inputStream), outputStream);
+                outputStream.flush();
+                outputStream.close();
+                final File finalFile = new File(finalFileName);
+                if (!outputFile.renameTo(finalFile)) {
+                    throw new IOException("Can't move the file to its final name");
+                }
                 wordListUriBuilder.appendQueryParameter(QUERY_PARAMETER_DELETE_RESULT,
                         QUERY_PARAMETER_SUCCESS);
                 if (0 >= resolver.delete(wordListUriBuilder.build(), null, null)) {
                     Log.e(TAG, "Could not have the dictionary pack delete a word list");
                 }
-                BinaryDictionaryGetter.removeFilesWithIdExcept(context, id, outputFile);
+                BinaryDictionaryGetter.removeFilesWithIdExcept(context, id, finalFile);
                 // Success! Close files (through the finally{} clause) and return.
-                return AssetFileAddress.makeFromFileName(outputFileName);
+                return AssetFileAddress.makeFromFileName(finalFileName);
             } catch (Exception e) {
                 if (DEBUG) {
                     Log.i(TAG, "Can't open word list in mode " + mode + " : " + e);
diff --git a/java/src/com/android/inputmethod/latin/Settings.java b/java/src/com/android/inputmethod/latin/Settings.java
index 152d668..4bb2172 100644
--- a/java/src/com/android/inputmethod/latin/Settings.java
+++ b/java/src/com/android/inputmethod/latin/Settings.java
@@ -116,6 +116,10 @@
         final Resources res = getResources();
         final Context context = getActivity();
 
+        // When we are called from the Settings application but we are not already running, the
+        // {@link SubtypeLocale} class may not have been initialized. It is safe to call
+        // {@link SubtypeLocale#init(Context)} multiple times.
+        SubtypeLocale.init(context);
         mVoicePreference = (ListPreference) findPreference(PREF_VOICE_MODE);
         mShowCorrectionSuggestionsPreference =
                 (ListPreference) findPreference(PREF_SHOW_SUGGESTIONS_SETTING);
diff --git a/java/src/com/android/inputmethod/latin/SubtypeLocale.java b/java/src/com/android/inputmethod/latin/SubtypeLocale.java
index acc17ef..21c9c0d 100644
--- a/java/src/com/android/inputmethod/latin/SubtypeLocale.java
+++ b/java/src/com/android/inputmethod/latin/SubtypeLocale.java
@@ -41,6 +41,7 @@
     public static final String QWERTY = "qwerty";
     public static final int UNKNOWN_KEYBOARD_LAYOUT = R.string.subtype_generic;
 
+    private static boolean sInitialized = false;
     private static String[] sPredefinedKeyboardLayoutSet;
     // Keyboard layout to its display name map.
     private static final HashMap<String, String> sKeyboardLayoutToDisplayNameMap =
@@ -69,7 +70,10 @@
         // Intentional empty constructor for utility class.
     }
 
-    public static void init(Context context) {
+    // Note that this initialization method can be called multiple times.
+    public static synchronized void init(Context context) {
+        if (sInitialized) return;
+
         final Resources res = context.getResources();
 
         final String[] predefinedLayoutSet = res.getStringArray(R.array.predefined_layouts);
@@ -109,6 +113,8 @@
             final String keyboardLayoutSet = keyboardLayoutSetMap[i + 1];
             sLocaleAndExtraValueToKeyboardLayoutSetMap.put(key, keyboardLayoutSet);
         }
+
+        sInitialized = true;
     }
 
     public static String[] getPredefinedKeyboardLayoutSet() {
diff --git a/native/jni/src/correction.cpp b/native/jni/src/correction.cpp
index d56938d..99f5b92 100644
--- a/native/jni/src/correction.cpp
+++ b/native/jni/src/correction.cpp
@@ -55,6 +55,7 @@
             }
             AKLOGI("[ %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d ]",
                     c[0], c[1], c[2], c[3], c[4], c[5], c[6], c[7], c[8], c[9], c[10]);
+            (void)c;
         }
     }
 }
diff --git a/native/jni/src/unigram_dictionary.cpp b/native/jni/src/unigram_dictionary.cpp
index e523b2f..ea9f11b 100644
--- a/native/jni/src/unigram_dictionary.cpp
+++ b/native/jni/src/unigram_dictionary.cpp
@@ -223,6 +223,7 @@
             short unsigned int* w = outWords + j * MAX_WORD_LENGTH;
             char s[MAX_WORD_LENGTH];
             for (int i = 0; i <= MAX_WORD_LENGTH; i++) s[i] = w[i];
+            (void)s;
             AKLOGI("%s %i", s, frequencies[j]);
         }
     }