Merge "Improve the double letter word promotion logic."
diff --git a/java/res/layout/hint_add_to_dictionary.xml b/java/res/layout/hint_add_to_dictionary.xml
deleted file mode 100644
index d429082..0000000
--- a/java/res/layout/hint_add_to_dictionary.xml
+++ /dev/null
@@ -1,36 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 2012, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-
-<!-- This is derived from suggestion_word.xml without minWidth attribute and padding -->
-<TextView
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:textSize="@dimen/config_suggestion_text_size"
-    android:gravity="center"
-    android:paddingLeft="0dp"
-    android:paddingTop="0dp"
-    android:paddingRight="0dp"
-    android:paddingBottom="0dp"
-    android:focusable="false"
-    android:clickable="false"
-    android:singleLine="true"
-    android:ellipsize="none"
-    style="?attr/suggestionWordStyle" />
diff --git a/java/res/layout/suggestions_strip.xml b/java/res/layout/suggestions_strip.xml
index 2ffac17..85d60e6 100644
--- a/java/res/layout/suggestions_strip.xml
+++ b/java/res/layout/suggestions_strip.xml
@@ -37,7 +37,7 @@
         <include
             layout="@layout/suggestion_divider" />
         <include
-            layout="@layout/hint_add_to_dictionary"
+            layout="@layout/suggestion_word"
             android:id="@+id/hint_add_to_dictionary" />
     </LinearLayout>
 </merge>
diff --git a/java/src/com/android/inputmethod/keyboard/EmojiPalettesView.java b/java/src/com/android/inputmethod/keyboard/EmojiPalettesView.java
index 5bde668..36ebbb5 100644
--- a/java/src/com/android/inputmethod/keyboard/EmojiPalettesView.java
+++ b/java/src/com/android/inputmethod/keyboard/EmojiPalettesView.java
@@ -73,7 +73,7 @@
  * Because of the above reasons, this class doesn't extend {@link KeyboardView}.
  */
 public final class EmojiPalettesView extends LinearLayout implements OnTabChangeListener,
-        ViewPager.OnPageChangeListener, View.OnTouchListener,
+        ViewPager.OnPageChangeListener, View.OnClickListener, View.OnTouchListener,
         EmojiPageKeyboardView.OnKeyEventListener {
     static final String TAG = EmojiPalettesView.class.getSimpleName();
     private static final boolean DEBUG_PAGER = false;
@@ -482,22 +482,35 @@
         final LinearLayout actionBar = (LinearLayout)findViewById(R.id.emoji_action_bar);
         mEmojiLayoutParams.setActionBarProperties(actionBar);
 
+        // deleteKey depends only on OnTouchListener.
         final ImageView deleteKey = (ImageView)findViewById(R.id.emoji_keyboard_delete);
         deleteKey.setTag(Constants.CODE_DELETE);
         deleteKey.setOnTouchListener(mDeleteKeyOnTouchListener);
+
+        // alphabetKey depends only on OnTouchListener as it does everything in key-press in
+        // ACTION_DOWN.
         final ImageView alphabetKey = (ImageView)findViewById(R.id.emoji_keyboard_alphabet);
         alphabetKey.setBackgroundResource(mEmojiFunctionalKeyBackgroundId);
         alphabetKey.setTag(Constants.CODE_SWITCH_ALPHA_SYMBOL);
         alphabetKey.setOnTouchListener(this);
-        final ImageView spaceKey = (ImageView)findViewById(R.id.emoji_keyboard_space);
-        spaceKey.setBackgroundResource(mKeyBackgroundId);
-        spaceKey.setTag(Constants.CODE_SPACE);
-        spaceKey.setOnTouchListener(this);
-        mEmojiLayoutParams.setKeyProperties(spaceKey);
+
+        // alphabetKey2 depends only on OnTouchListener as it does everything in key-press in
+        // ACTION_DOWN.
         final ImageView alphabetKey2 = (ImageView)findViewById(R.id.emoji_keyboard_alphabet2);
         alphabetKey2.setBackgroundResource(mEmojiFunctionalKeyBackgroundId);
         alphabetKey2.setTag(Constants.CODE_SWITCH_ALPHA_SYMBOL);
         alphabetKey2.setOnTouchListener(this);
+
+        // spaceKey depends on {@link View.OnClickListener} as well as {@link View.OnTouchListener}.
+        // {@link View.OnTouchListener} is used as the trigger of key-press while
+        // {@link View.OnClickListener} is used as the trigger of key-release which may not occur
+        // if the event is canceled by moving off the finger from the view.
+        final ImageView spaceKey = (ImageView)findViewById(R.id.emoji_keyboard_space);
+        spaceKey.setBackgroundResource(mKeyBackgroundId);
+        spaceKey.setTag(Constants.CODE_SPACE);
+        spaceKey.setOnTouchListener(this);
+        spaceKey.setOnClickListener(this);
+        mEmojiLayoutParams.setKeyProperties(spaceKey);
     }
 
     @Override
@@ -507,7 +520,6 @@
         updateEmojiCategoryPageIdView();
     }
 
-
     @Override
     public void onPageSelected(final int position) {
         final Pair<Integer, Integer> newPos =
@@ -545,40 +557,62 @@
         }
     }
 
-    // Called from {@link EmojiPageKeyboardView} through {@link View.OnTouchListener} interface to
-    // handle touch events from View-based elements such as the space bar.
+    /**
+     * Called from {@link EmojiPageKeyboardView} through {@link android.view.View.OnTouchListener}
+     * interface to handle touch events from View-based elements such as the space bar.
+     * Note that this method is used only for observing {@link MotionEvent#ACTION_DOWN} to trigger
+     * {@link KeyboardActionListener#onPressKey}. {@link KeyboardActionListener#onReleaseKey} will
+     * be covered by {@link #onClick} as long as the event is not canceled.
+     */
     @Override
     public boolean onTouch(final View v, final MotionEvent event) {
+        if (event.getActionMasked() != MotionEvent.ACTION_DOWN) {
+            return false;
+        }
         final Object tag = v.getTag();
         if (!(tag instanceof Integer)) {
             return false;
         }
         final int code = (Integer) tag;
-        switch (event.getAction()) {
-            case MotionEvent.ACTION_DOWN:
-                mKeyboardActionListener.onPressKey(
-                        code, 0 /* repeatCount */, true /* isSinglePointer */);
-                break;
-            case MotionEvent.ACTION_UP:
-                mKeyboardActionListener.onCodeInput(code, NOT_A_COORDINATE, NOT_A_COORDINATE);
-                mKeyboardActionListener.onReleaseKey(code, false /* withSliding */);
-                break;
-        }
+        mKeyboardActionListener.onPressKey(
+                code, 0 /* repeatCount */, true /* isSinglePointer */);
+        // It's important to return false here. Otherwise, {@link #onClick} and touch-down visual
+        // feedback stop working.
         return false;
     }
 
-    // Called from {@link EmojiPageKeyboardView} through
-    // {@link EmojiPageKeyboardView.OnKeyEventListener} interface to handle touch events from
-    // non-View-based elements like typical Emoji characters.
+    /**
+     * Called from {@link EmojiPageKeyboardView} through {@link android.view.View.OnClickListener}
+     * interface to handle non-canceled touch-up events from View-based elements such as the space
+     * bar.
+     */
+    @Override
+    public void onClick(View v) {
+        final Object tag = v.getTag();
+        if (!(tag instanceof Integer)) {
+            return;
+        }
+        final int code = (Integer) tag;
+        mKeyboardActionListener.onCodeInput(code, NOT_A_COORDINATE, NOT_A_COORDINATE);
+        mKeyboardActionListener.onReleaseKey(code, false /* withSliding */);
+    }
+
+    /**
+     * Called from {@link EmojiPageKeyboardView} through
+     * {@link com.android.inputmethod.keyboard.internal.EmojiPageKeyboardView.OnKeyEventListener}
+     * interface to handle touch events from non-View-based elements such as Emoji buttons.
+     */
     @Override
     public void onPressKey(final Key key) {
         final int code = key.getCode();
         mKeyboardActionListener.onPressKey(code, 0 /* repeatCount */, true /* isSinglePointer */);
     }
 
-    // Called from {@link EmojiPageKeyboardView} through
-    // {@link EmojiPageKeyboardView.OnKeyEventListener} interface to handle touch events from
-    // non-View-based elements like typical Emoji characters.
+    /**
+     * Called from {@link EmojiPageKeyboardView} through
+     * {@link com.android.inputmethod.keyboard.internal.EmojiPageKeyboardView.OnKeyEventListener}
+     * interface to handle touch events from non-View-based elements such as Emoji buttons.
+     */
     @Override
     public void onReleaseKey(final Key key) {
         mEmojiPalettesAdapter.addRecentKey(key);
diff --git a/java/src/com/android/inputmethod/latin/DictionaryFacilitatorForSuggest.java b/java/src/com/android/inputmethod/latin/DictionaryFacilitatorForSuggest.java
index fb95172..8a8a45f 100644
--- a/java/src/com/android/inputmethod/latin/DictionaryFacilitatorForSuggest.java
+++ b/java/src/com/android/inputmethod/latin/DictionaryFacilitatorForSuggest.java
@@ -44,6 +44,10 @@
 public class DictionaryFacilitatorForSuggest {
     public static final String TAG = DictionaryFacilitatorForSuggest.class.getSimpleName();
 
+    // HACK: This threshold is being used when adding a capitalized entry in the User History
+    // dictionary.
+    private static final int CAPITALIZED_FORM_MAX_PROBABILITY_FOR_INSERT = 140;
+
     private final Context mContext;
     public final Locale mLocale;
 
@@ -389,7 +393,26 @@
         if (maxFreq == 0) {
             return;
         }
-        final String secondWord = wasAutoCapitalized ? suggestion.toLowerCase(mLocale) : suggestion;
+        final String suggestionLowerCase = suggestion.toLowerCase(mLocale);
+        final String secondWord;
+        if (wasAutoCapitalized) {
+            secondWord = suggestionLowerCase;
+        } else {
+            // HACK: We'd like to avoid adding the capitalized form of common words to the User
+            // History dictionary in order to avoid suggesting them until the dictionary
+            // consolidation is done.
+            // TODO: Remove this hack when ready.
+            final int lowerCasefreqInMainDict = mMainDictionary != null ?
+                    mMainDictionary.getFrequency(suggestionLowerCase) :
+                            Dictionary.NOT_A_PROBABILITY;
+            if (maxFreq < lowerCasefreqInMainDict
+                    && lowerCasefreqInMainDict >= CAPITALIZED_FORM_MAX_PROBABILITY_FOR_INSERT) {
+                // Use lower cased word as the word can be a distracter of the popular word.
+                secondWord = suggestionLowerCase;
+            } else {
+                secondWord = suggestion;
+            }
+        }
         // We demote unrecognized words (frequency < 0, below) by specifying them as "invalid".
         // We don't add words with 0-frequency (assuming they would be profanity etc.).
         final boolean isValid = maxFreq > 0;
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index ba7503d..adebfc0 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -84,6 +84,7 @@
 import com.android.inputmethod.latin.utils.JniUtils;
 import com.android.inputmethod.latin.utils.LatinImeLoggerUtils;
 import com.android.inputmethod.latin.utils.LeakGuardHandlerWrapper;
+import com.android.inputmethod.latin.utils.SubtypeLocaleUtils;
 import com.android.inputmethod.research.ResearchLogger;
 
 import java.io.FileDescriptor;
@@ -1010,9 +1011,7 @@
                 false /* isObsoleteSuggestions */,
                 false /* isPrediction */);
         // When in fullscreen mode, show completions generated by the application
-        setSuggestedWords(suggestedWords);
-        setAutoCorrectionIndicator(false);
-        setSuggestionStripShown(true);
+        setSuggestedWords(suggestedWords, true /* shouldShow */);
         if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
             ResearchLogger.latinIME_onDisplayCompletions(applicationSpecifiedCompletions);
         }
@@ -1021,22 +1020,17 @@
     private void setSuggestionStripShownInternal(final boolean shown,
             final boolean needsInputViewShown) {
         // TODO: Modify this if we support suggestions with hard keyboard
-        if (onEvaluateInputViewShown() && mSuggestionStripView != null) {
-            final boolean inputViewShown = mKeyboardSwitcher.isShowingMainKeyboardOrEmojiPalettes();
-            final boolean shouldShowSuggestions = shown
-                    && (needsInputViewShown ? inputViewShown : true);
-            if (isFullscreenMode()) {
-                mSuggestionStripView.setVisibility(
-                        shouldShowSuggestions ? View.VISIBLE : View.GONE);
-            } else {
-                mSuggestionStripView.setVisibility(
-                        shouldShowSuggestions ? View.VISIBLE : View.INVISIBLE);
-            }
+        if (!onEvaluateInputViewShown() || null == mSuggestionStripView) {
+            return;
         }
-    }
-
-    private void setSuggestionStripShown(final boolean shown) {
-        setSuggestionStripShownInternal(shown, /* needsInputViewShown */true);
+        final boolean inputViewShown = mKeyboardSwitcher.isShowingMainKeyboardOrEmojiPalettes();
+        final boolean shouldShowSuggestions = shown
+                && (needsInputViewShown ? inputViewShown : true);
+        if (shouldShowSuggestions) {
+            mSuggestionStripView.setVisibility(View.VISIBLE);
+        } else {
+            mSuggestionStripView.setVisibility(isFullscreenMode() ? View.GONE : View.INVISIBLE);
+        }
     }
 
     private int getAdjustedBackingViewHeight() {
@@ -1330,15 +1324,9 @@
     }
 
     // TODO[IL]: Define a clear interface for this
-    public void setSuggestedWords(final SuggestedWords words) {
+    public void setSuggestedWords(final SuggestedWords words, final boolean shouldShow) {
         mInputLogic.mSuggestedWords = words;
-        if (mSuggestionStripView != null) {
-            mSuggestionStripView.setSuggestions(words);
-            mKeyboardSwitcher.onAutoCorrectionStateChanged(words.mWillAutoCorrect);
-        }
-    }
-
-    private void setAutoCorrectionIndicator(final boolean newAutoCorrectionIndicator) {
+        final boolean newAutoCorrectionIndicator = words.mWillAutoCorrect;
         // Put a blue underline to a word in TextView which will be auto-corrected.
         if (mInputLogic.mIsAutoCorrectionIndicatorOn != newAutoCorrectionIndicator
                 && mInputLogic.mWordComposer.isComposingWord()) {
@@ -1351,6 +1339,12 @@
             // the practice.
             mInputLogic.mConnection.setComposingText(textWithUnderline, 1);
         }
+        if (mSuggestionStripView != null) {
+            mSuggestionStripView.setSuggestions(
+                    words, SubtypeLocaleUtils.isRtlLanguage(mSubtypeSwitcher.getCurrentSubtype()));
+            mKeyboardSwitcher.onAutoCorrectionStateChanged(words.mWillAutoCorrect);
+            setSuggestionStripShownInternal(shouldShow, true /* needsInputViewShown */);
+        }
     }
 
     // TODO[IL]: Move this out of LatinIME.
@@ -1426,16 +1420,8 @@
 
     private void showSuggestionStripWithTypedWord(final SuggestedWords sourceSuggestedWords,
             final String typedWord) {
-        // TODO: refactor this
         final SuggestedWords suggestedWords =
                 sourceSuggestedWords.isEmpty() ? SuggestedWords.EMPTY : sourceSuggestedWords;
-        if (suggestedWords.isEmpty()) {
-            // No auto-correction is available, clear the cached values.
-            AccessibilityUtils.getInstance().setAutoCorrection(suggestedWords, typedWord);
-            setSuggestedWords(suggestedWords);
-            setAutoCorrectionIndicator(false);
-            return;
-        }
         final String autoCorrection;
         if (suggestedWords.mWillAutoCorrect) {
             autoCorrection = suggestedWords.getWord(SuggestedWords.INDEX_OF_AUTO_CORRECTION);
@@ -1444,12 +1430,12 @@
             // because it may differ from mWordComposer.mTypedWord.
             autoCorrection = typedWord;
         }
-        mInputLogic.mWordComposer.setAutoCorrection(autoCorrection);
-        setSuggestedWords(suggestedWords);
-        setAutoCorrectionIndicator(suggestedWords.mWillAutoCorrect);
-        setSuggestionStripShown(isSuggestionsStripVisible());
-        // An auto-correction is available, cache it in accessibility code so
-        // we can be speak it if the user touches a key that will insert it.
+        if (SuggestedWords.EMPTY != suggestedWords) {
+            mInputLogic.mWordComposer.setAutoCorrection(autoCorrection);
+        }
+        setSuggestedWords(suggestedWords, isSuggestionsStripVisible());
+        // Cache the auto-correction in accessibility code so we can speak it if the user
+        // touches a key that will insert it.
         AccessibilityUtils.getInstance().setAutoCorrection(suggestedWords, typedWord);
     }
 
@@ -1560,12 +1546,11 @@
     public void setNeutralSuggestionStrip() {
         final SettingsValues currentSettings = mSettings.getCurrent();
         if (currentSettings.mBigramPredictionEnabled) {
-            setSuggestedWords(SuggestedWords.EMPTY);
+            setSuggestedWords(SuggestedWords.EMPTY, isSuggestionsStripVisible());
         } else {
-            setSuggestedWords(currentSettings.mSpacingAndPunctuations.mSuggestPuncList);
+            setSuggestedWords(currentSettings.mSpacingAndPunctuations.mSuggestPuncList,
+                    isSuggestionsStripVisible());
         }
-        setAutoCorrectionIndicator(false);
-        setSuggestionStripShown(isSuggestionsStripVisible());
     }
 
     public void unsetIsAutoCorrectionIndicatorOnAndCallShowSuggestionStrip(
diff --git a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripLayoutHelper.java b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripLayoutHelper.java
index af04de4..3cd9d95 100644
--- a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripLayoutHelper.java
+++ b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripLayoutHelper.java
@@ -28,6 +28,8 @@
 import android.graphics.Typeface;
 import android.graphics.drawable.BitmapDrawable;
 import android.graphics.drawable.Drawable;
+import android.support.v4.view.GravityCompat;
+import android.support.v4.view.ViewCompat;
 import android.text.Spannable;
 import android.text.SpannableString;
 import android.text.Spanned;
@@ -39,7 +41,6 @@
 import android.util.AttributeSet;
 import android.view.Gravity;
 import android.view.View;
-import android.view.View.OnClickListener;
 import android.view.ViewGroup;
 import android.widget.LinearLayout;
 import android.widget.TextView;
@@ -88,6 +89,7 @@
     private final Drawable mMoreSuggestionsHint;
     private static final String MORE_SUGGESTIONS_HINT = "\u2026";
     private static final String LEFTWARDS_ARROW = "\u2190";
+    private static final String RIGHTWARDS_ARROW = "\u2192";
 
     private static final CharacterStyle BOLD_SPAN = new StyleSpan(Typeface.BOLD);
     private static final CharacterStyle UNDERLINE_SPAN = new UnderlineSpan();
@@ -471,10 +473,13 @@
 
         final TextView hintView = (TextView)addToDictionaryStrip.findViewById(
                 R.id.hint_add_to_dictionary);
-        hintView.setGravity(Gravity.LEFT | Gravity.CENTER_VERTICAL);
+        hintView.setGravity(Gravity.LEFT | Gravity.CENTER_VERTICAL | GravityCompat.START);
         hintView.setTextColor(mColorAutoCorrect);
+        final boolean isRtlLanguage = (ViewCompat.getLayoutDirection(addToDictionaryStrip)
+                == ViewCompat.LAYOUT_DIRECTION_RTL);
+        final String hintWithArrow = (isRtlLanguage ? RIGHTWARDS_ARROW : LEFTWARDS_ARROW)
+                + hintText;
         final int hintWidth = width - wordWidth;
-        final String hintWithArrow = LEFTWARDS_ARROW + hintText;
         final float hintScaleX = getTextScaleX(hintWithArrow, hintWidth, hintView.getPaint());
         hintView.setText(hintWithArrow);
         hintView.setTextScaleX(hintScaleX);
diff --git a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java
index 32552eb..0ebf5cb 100644
--- a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java
+++ b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java
@@ -18,6 +18,7 @@
 
 import android.content.Context;
 import android.content.res.Resources;
+import android.support.v4.view.ViewCompat;
 import android.util.AttributeSet;
 import android.view.GestureDetector;
 import android.view.LayoutInflater;
@@ -26,6 +27,7 @@
 import android.view.View.OnClickListener;
 import android.view.View.OnLongClickListener;
 import android.view.ViewGroup;
+import android.view.ViewParent;
 import android.widget.RelativeLayout;
 import android.widget.TextView;
 
@@ -83,6 +85,13 @@
             showSuggestionsStrip();
         }
 
+        public void setLayoutDirection(final boolean isRtlLanguage) {
+            final int layoutDirection = isRtlLanguage ? ViewCompat.LAYOUT_DIRECTION_RTL
+                    : ViewCompat.LAYOUT_DIRECTION_LTR;
+            ViewCompat.setLayoutDirection(mSuggestionsStrip, layoutDirection);
+            ViewCompat.setLayoutDirection(mAddToDictionaryStrip, layoutDirection);
+        }
+
         public void showSuggestionsStrip() {
             mSuggestionsStrip.setVisibility(VISIBLE);
             mAddToDictionaryStrip.setVisibility(INVISIBLE);
@@ -153,8 +162,9 @@
         mMainKeyboardView = (MainKeyboardView)inputView.findViewById(R.id.keyboard_view);
     }
 
-    public void setSuggestions(final SuggestedWords suggestedWords) {
+    public void setSuggestions(final SuggestedWords suggestedWords, final boolean isRtlLanguage) {
         clear();
+        mStripVisibilityGroup.setLayoutDirection(isRtlLanguage);
         mSuggestedWords = suggestedWords;
         mLayoutHelper.layout(mSuggestedWords, mSuggestionsStrip, this);
         if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
@@ -189,10 +199,21 @@
 
     public void clear() {
         mSuggestionsStrip.removeAllViews();
+        removeAllDebugInfoViews();
         mStripVisibilityGroup.showSuggestionsStrip();
         dismissMoreSuggestionsPanel();
     }
 
+    private void removeAllDebugInfoViews() {
+        // The debug info views may be placed as children views of this {@link SuggestionStripView}.
+        for (final View debugInfoView : mDebugInfoViews) {
+            final ViewParent parent = debugInfoView.getParent();
+            if (parent instanceof ViewGroup) {
+                ((ViewGroup)parent).removeView(debugInfoView);
+            }
+        }
+    }
+
     private final MoreSuggestionsListener mMoreSuggestionsListener = new MoreSuggestionsListener() {
         @Override
         public void onSuggestionSelected(final int index, final SuggestedWordInfo wordInfo) {
diff --git a/java/src/com/android/inputmethod/latin/utils/SubtypeLocaleUtils.java b/java/src/com/android/inputmethod/latin/utils/SubtypeLocaleUtils.java
index fb1be30..0d02889 100644
--- a/java/src/com/android/inputmethod/latin/utils/SubtypeLocaleUtils.java
+++ b/java/src/com/android/inputmethod/latin/utils/SubtypeLocaleUtils.java
@@ -25,7 +25,6 @@
 import android.util.Log;
 import android.view.inputmethod.InputMethodSubtype;
 
-import com.android.inputmethod.annotations.UsedForTesting;
 import com.android.inputmethod.latin.DictionaryFactory;
 import com.android.inputmethod.latin.R;
 
@@ -348,8 +347,6 @@
         Arrays.sort(SORTED_RTL_LANGUAGES);
     }
 
-    // TODO: Remove @UsedForTesting annotation.
-    @UsedForTesting
     public static boolean isRtlLanguage(final InputMethodSubtype subtype) {
         final Locale locale = getSubtypeLocale(subtype);
         final String language = locale.getLanguage();