Merge "Make UserLogRingCharBuffer an external class"
diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionary.java b/java/src/com/android/inputmethod/latin/BinaryDictionary.java
index 4425d7d..f36c9e8 100644
--- a/java/src/com/android/inputmethod/latin/BinaryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/BinaryDictionary.java
@@ -78,13 +78,15 @@
      * @param length the length of the binary data.
      * @param useFullEditDistance whether to use the full edit distance in suggestions
      * @param dictType the dictionary type, as a human-readable string
+     * @param isUpdatable whether to open the dictionary file in writable mode.
      */
     public BinaryDictionary(final String filename, final long offset, final long length,
-            final boolean useFullEditDistance, final Locale locale, final String dictType) {
+            final boolean useFullEditDistance, final Locale locale, final String dictType,
+            final boolean isUpdatable) {
         super(dictType);
         mLocale = locale;
         mNativeSuggestOptions.setUseFullEditDistance(useFullEditDistance);
-        loadDictionary(filename, offset, length);
+        loadDictionary(filename, offset, length, isUpdatable);
     }
 
     static {
@@ -106,8 +108,8 @@
 
     // TODO: Move native dict into session
     private final void loadDictionary(final String path, final long startOffset,
-            final long length) {
-        mNativeDict = openNative(path, startOffset, length, false /* isUpdatable */);
+            final long length, final boolean isUpdatable) {
+        mNativeDict = openNative(path, startOffset, length, isUpdatable);
     }
 
     @Override
diff --git a/java/src/com/android/inputmethod/latin/DictionaryFactory.java b/java/src/com/android/inputmethod/latin/DictionaryFactory.java
index 5b98613..3721132 100644
--- a/java/src/com/android/inputmethod/latin/DictionaryFactory.java
+++ b/java/src/com/android/inputmethod/latin/DictionaryFactory.java
@@ -60,7 +60,8 @@
         if (null != assetFileList) {
             for (final AssetFileAddress f : assetFileList) {
                 final BinaryDictionary binaryDictionary = new BinaryDictionary(f.mFilename,
-                        f.mOffset, f.mLength, useFullEditDistance, locale, Dictionary.TYPE_MAIN);
+                        f.mOffset, f.mLength, useFullEditDistance, locale, Dictionary.TYPE_MAIN,
+                        false /* isUpdatable */);
                 if (binaryDictionary.isValidDictionary()) {
                     dictList.add(binaryDictionary);
                 }
@@ -113,7 +114,8 @@
                 return null;
             }
             return new BinaryDictionary(sourceDir, afd.getStartOffset(), afd.getLength(),
-                    false /* useFullEditDistance */, locale, Dictionary.TYPE_MAIN);
+                    false /* useFullEditDistance */, locale, Dictionary.TYPE_MAIN,
+                    false /* isUpdatable */);
         } catch (android.content.res.Resources.NotFoundException e) {
             Log.e(TAG, "Could not find the resource");
             return null;
@@ -142,7 +144,7 @@
         for (final AssetFileAddress address : dictionaryList) {
             final BinaryDictionary binaryDictionary = new BinaryDictionary(address.mFilename,
                     address.mOffset, address.mLength, useFullEditDistance, locale,
-                    Dictionary.TYPE_MAIN);
+                    Dictionary.TYPE_MAIN, false /* isUpdatable */);
             dictionaryCollection.addDictionary(binaryDictionary);
         }
         return dictionaryCollection;
diff --git a/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java b/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java
index f357e2a..9cdb86c 100644
--- a/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java
@@ -286,7 +286,7 @@
 
         // Build the new binary dictionary
         final BinaryDictionary newBinaryDictionary = new BinaryDictionary(filename, 0, length,
-                true /* useFullEditDistance */, null, mDictType);
+                true /* useFullEditDistance */, null, mDictType, false /* isUpdatable */);
 
         if (mBinaryDictionary != null) {
             // Ensure all threads accessing the current dictionary have finished before swapping in
diff --git a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripLayoutHelper.java b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripLayoutHelper.java
index b6caf9b..9565f63 100644
--- a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripLayoutHelper.java
+++ b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripLayoutHelper.java
@@ -86,6 +86,7 @@
     private final float mAlphaObsoleted;
     private final float mCenterSuggestionWeight;
     private final int mCenterPositionInStrip;
+    private final int mTypedWordPositionWhenAutocorrect;
     private final Drawable mMoreSuggestionsHint;
     private static final String MORE_SUGGESTIONS_HINT = "\u2026";
     private static final String LEFTWARDS_ARROW = "\u2190";
@@ -159,6 +160,10 @@
         mMoreSuggestionsHint = getMoreSuggestionsHint(res,
                 res.getDimension(R.dimen.more_suggestions_hint_text_size), mColorAutoCorrect);
         mCenterPositionInStrip = mSuggestionsCountInStrip / 2;
+        // Assuming there are at least three suggestions. Also, note that the suggestions are
+        // laid out according to script direction, so this is left of the center for LTR scripts
+        // and right of the center for RTL scripts.
+        mTypedWordPositionWhenAutocorrect = mCenterPositionInStrip - 1;
         mMoreSuggestionsBottomGap = res.getDimensionPixelOffset(
                 R.dimen.more_suggestions_bottom_gap);
         mMoreSuggestionsRowHeight = res.getDimensionPixelSize(R.dimen.more_suggestions_row_height);
@@ -233,24 +238,31 @@
         return spannedWord;
     }
 
-    private int getIndexInSuggestedWords(final int positionInStrip,
+    private int getPositionInSuggestionStrip(final int indexInSuggestedWords,
             final SuggestedWords suggestedWords) {
-        // TODO: This works for 3 suggestions. Revisit this algorithm when there are 5 or more
-        // suggestions.
-        final int mostImportantIndexInSuggestedWords = suggestedWords.willAutoCorrect()
-                ? SuggestedWords.INDEX_OF_AUTO_CORRECTION : SuggestedWords.INDEX_OF_TYPED_WORD;
-        if (positionInStrip == mCenterPositionInStrip) {
-            return mostImportantIndexInSuggestedWords;
+        final int indexToDisplayMostImportantSuggestion;
+        final int indexToDisplaySecondMostImportantSuggestion;
+        if (suggestedWords.willAutoCorrect()) {
+            indexToDisplayMostImportantSuggestion = SuggestedWords.INDEX_OF_AUTO_CORRECTION;
+            indexToDisplaySecondMostImportantSuggestion = SuggestedWords.INDEX_OF_TYPED_WORD;
+        } else {
+            indexToDisplayMostImportantSuggestion = SuggestedWords.INDEX_OF_TYPED_WORD;
+            indexToDisplaySecondMostImportantSuggestion = SuggestedWords.INDEX_OF_AUTO_CORRECTION;
         }
-        if (positionInStrip == mostImportantIndexInSuggestedWords) {
+        if (indexInSuggestedWords == indexToDisplayMostImportantSuggestion) {
             return mCenterPositionInStrip;
         }
-        return positionInStrip;
+        if (indexInSuggestedWords == indexToDisplaySecondMostImportantSuggestion) {
+            return mTypedWordPositionWhenAutocorrect;
+        }
+        // If neither of those, the order in the suggestion strip is the same as in SuggestedWords.
+        return indexInSuggestedWords;
     }
 
-    private int getSuggestionTextColor(final int positionInStrip,
+    private int getSuggestionTextColor(final int indexInSuggestedWords,
             final SuggestedWords suggestedWords) {
-        final int indexInSuggestedWords = getIndexInSuggestedWords(positionInStrip, suggestedWords);
+        final int positionInStrip =
+                getPositionInSuggestionStrip(indexInSuggestedWords, suggestedWords);
         // TODO: Need to revisit this logic with bigram suggestions
         final boolean isSuggested = (indexInSuggestedWords != SuggestedWords.INDEX_OF_TYPED_WORD);
 
@@ -352,7 +364,7 @@
      * increase towards the right for LTR scripts and the left for RTL scripts, starting with 0.
      * The position of the most important suggestion is in {@link #mCenterPositionInStrip}. This
      * usually doesn't match the index in <code>suggedtedWords</code> -- see
-     * {@link #getIndexInSuggestedWords(int,SuggestedWords)}.
+     * {@link #getPositionInSuggestionStrip(int,SuggestedWords)}.
      *
      * @param positionInStrip the position in the suggestion strip.
      * @param width the maximum width for layout in pixels.
@@ -413,10 +425,19 @@
 
     private void setupWordViewsTextAndColor(final SuggestedWords suggestedWords,
             final int countInStrip) {
+        // Clear all suggestions first
+        for (int positionInStrip = 0; positionInStrip < countInStrip; ++positionInStrip) {
+            mWordViews.get(positionInStrip).setText(null);
+            // Make this inactive for touches in {@link #layoutWord(int,int)}.
+            if (SuggestionStripView.DBG) {
+                mDebugInfoViews.get(positionInStrip).setText(null);
+            }
+        }
         final int count = Math.min(suggestedWords.size(), countInStrip);
-        for (int positionInStrip = 0; positionInStrip < count; positionInStrip++) {
-            final int indexInSuggestedWords =
-                    getIndexInSuggestedWords(positionInStrip, suggestedWords);
+        for (int indexInSuggestedWords = 0; indexInSuggestedWords < count;
+                indexInSuggestedWords++) {
+            final int positionInStrip =
+                    getPositionInSuggestionStrip(indexInSuggestedWords, suggestedWords);
             final TextView wordView = mWordViews.get(positionInStrip);
             // {@link TextView#getTag()} is used to get the index in suggestedWords at
             // {@link SuggestionStripView#onClick(View)}.
@@ -428,13 +449,6 @@
                         Utils.getDebugInfo(suggestedWords, indexInSuggestedWords));
             }
         }
-        for (int positionInStrip = count; positionInStrip < countInStrip; positionInStrip++) {
-            mWordViews.get(positionInStrip).setText(null);
-            // Make this inactive for touches in {@link #layoutWord(int,int)}.
-            if (SuggestionStripView.DBG) {
-                mDebugInfoViews.get(positionInStrip).setText(null);
-            }
-        }
     }
 
     private void layoutPunctuationSuggestions(final SuggestedWords suggestedWords,