Merge "Support embedded more key"
diff --git a/java/res/xml/key_styles_enter.xml b/java/res/xml/key_styles_enter.xml
index 03bcb86..a4c9a33 100644
--- a/java/res/xml/key_styles_enter.xml
+++ b/java/res/xml/key_styles_enter.xml
@@ -33,6 +33,13 @@
                 latin:moreKeys="@string/action_previous_as_more_key" />
         </case>
         <case
+            latin:imeAction="actionNext"
+            latin:navigatePrevious="false"
+        >
+            <key-style
+                latin:styleName="navigateMoreKeysStyle" />
+        </case>
+        <case
             latin:imeAction="actionPrevious"
             latin:navigateNext="true"
         >
@@ -41,6 +48,13 @@
                 latin:keyLabelFlags="hasPopupHint|preserveCase"
                 latin:moreKeys="@string/action_next_as_more_key" />
         </case>
+        <case
+            latin:imeAction="actionPrevious"
+            latin:navigateNext="false"
+        >
+            <key-style
+                latin:styleName="navigateMoreKeysStyle" />
+        </case>
         <!-- imeAction!="actionNext" and imeAction!="actionPrevious" -->
         <case
             latin:navigateNext="true"
diff --git a/java/src/com/android/inputmethod/compat/InputMethodManagerCompatWrapper.java b/java/src/com/android/inputmethod/compat/InputMethodManagerCompatWrapper.java
index 0e5f8c8..7e216e5 100644
--- a/java/src/com/android/inputmethod/compat/InputMethodManagerCompatWrapper.java
+++ b/java/src/com/android/inputmethod/compat/InputMethodManagerCompatWrapper.java
@@ -150,7 +150,7 @@
     private InputMethodInfoCompatWrapper getLatinImeInputMethodInfo() {
         if (TextUtils.isEmpty(mLatinImePackageName))
             return null;
-        return Utils.getInputMethodInfo(this, mLatinImePackageName);
+        return Utils.getInputMethodInfo(mLatinImePackageName);
     }
 
     private static InputMethodSubtypeCompatWrapper getLastResortSubtype(String mode) {
@@ -239,8 +239,7 @@
 
         // The code below are based on {@link InputMethodManager#showInputMethodMenuInternal}.
 
-        final InputMethodInfoCompatWrapper myImi = Utils.getInputMethodInfo(
-                this, mLatinImePackageName);
+        final InputMethodInfoCompatWrapper myImi = Utils.getInputMethodInfo(mLatinImePackageName);
         final List<InputMethodSubtypeCompatWrapper> myImsList = getEnabledInputMethodSubtypeList(
                 myImi, true);
         final InputMethodSubtypeCompatWrapper currentIms = getCurrentInputMethodSubtype();
diff --git a/java/src/com/android/inputmethod/latin/ComposingStateManager.java b/java/src/com/android/inputmethod/latin/ComposingStateManager.java
index 27f509a..8811f20 100644
--- a/java/src/com/android/inputmethod/latin/ComposingStateManager.java
+++ b/java/src/com/android/inputmethod/latin/ComposingStateManager.java
@@ -53,13 +53,6 @@
         }
     }
 
-    public synchronized boolean isComposing() {
-        // TODO: use the composing flag in WordComposer instead of maintaining it
-        // here separately. Even better, do away with this class and manage the auto
-        // correction indicator in the same place as the suggestions.
-        return mIsComposing;
-    }
-
     public synchronized boolean isAutoCorrectionIndicatorOn() {
         return mAutoCorrectionIndicatorOn;
     }
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index 9045745..59fa66d 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -980,7 +980,7 @@
                     .setHasMinimalSuggestion(false);
             // When in fullscreen mode, show completions generated by the application
             final SuggestedWords words = builder.build();
-            final boolean isAutoCorrection = Utils.willAutoCorrect(words);
+            final boolean isAutoCorrection = false;
             setSuggestions(words, isAutoCorrection);
             setAutoCorrectionIndicator(isAutoCorrection);
             // TODO: is this the right thing to do? What should we auto-correct to in
@@ -1737,10 +1737,6 @@
                 if (DEBUG) {
                     Log.d(TAG, "Flip the indicator. " + oldAutoCorrectionIndicator
                             + " -> " + newAutoCorrectionIndicator);
-                    if (mComposingStateManager.isComposing() && newAutoCorrectionIndicator
-                            != mComposingStateManager.isAutoCorrectionIndicatorOn()) {
-                        throw new RuntimeException("Couldn't flip the indicator!");
-                    }
                 }
                 if (mWordComposer.isComposingWord()) {
                     final CharSequence textWithUnderline =
@@ -1831,18 +1827,18 @@
                 builder.addTypedWordAndPreviousSuggestions(typedWord, previousSuggestions);
             }
         }
+        final SuggestedWords suggestedWords = builder.build();
+        if (Utils.shouldBlockAutoCorrectionBySafetyNet(suggestedWords, mSuggest)) {
+            suggestedWords.setShouldBlockAutoCorrectionBySatefyNet();
+        }
         showSuggestions(builder.build(), typedWord);
     }
 
     public void showSuggestions(final SuggestedWords suggestedWords, final CharSequence typedWord) {
-        final boolean shouldBlockAutoCorrectionBySafetyNet =
-                Utils.shouldBlockAutoCorrectionBySafetyNet(suggestedWords, mSuggest);
-        if (shouldBlockAutoCorrectionBySafetyNet) {
-            suggestedWords.setShouldBlockAutoCorrectionBySatefyNet();
-        }
         final CharSequence autoCorrection;
         if (suggestedWords.size() > 0) {
-            if (!shouldBlockAutoCorrectionBySafetyNet && suggestedWords.hasAutoCorrectionWord()) {
+            if (!suggestedWords.shouldBlockAutoCorrectionBySafetyNet()
+                    && suggestedWords.hasAutoCorrectionWord()) {
                 autoCorrection = suggestedWords.getWord(1);
             } else {
                 autoCorrection = typedWord;
@@ -1851,7 +1847,7 @@
             autoCorrection = null;
         }
         mWordComposer.setAutoCorrection(autoCorrection);
-        final boolean isAutoCorrection = Utils.willAutoCorrect(suggestedWords);
+        final boolean isAutoCorrection = suggestedWords.willAutoCorrect();
         setSuggestions(suggestedWords, isAutoCorrection);
         setAutoCorrectionIndicator(isAutoCorrection);
         setSuggestionStripShown(isSuggestionsStripVisible());
@@ -2420,7 +2416,7 @@
                 switch (position) {
                 case 0:
                     Intent intent = CompatUtils.getInputLanguageSelectionIntent(
-                            Utils.getInputMethodId(mImm, getPackageName()),
+                            Utils.getInputMethodId(getPackageName()),
                             Intent.FLAG_ACTIVITY_NEW_TASK
                             | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
                             | Intent.FLAG_ACTIVITY_CLEAR_TOP);
diff --git a/java/src/com/android/inputmethod/latin/Settings.java b/java/src/com/android/inputmethod/latin/Settings.java
index dfcb645..3029057 100644
--- a/java/src/com/android/inputmethod/latin/Settings.java
+++ b/java/src/com/android/inputmethod/latin/Settings.java
@@ -329,10 +329,9 @@
     @Override
     public boolean onPreferenceClick(Preference pref) {
         if (pref == mInputLanguageSelection) {
-            startActivity(CompatUtils.getInputLanguageSelectionIntent(
-                    Utils.getInputMethodId(
-                            InputMethodManagerCompatWrapper.getInstance(),
-                            getActivityInternal().getApplicationInfo().packageName), 0));
+            final String imeId = Utils.getInputMethodId(
+                    getActivityInternal().getApplicationInfo().packageName);
+            startActivity(CompatUtils.getInputLanguageSelectionIntent(imeId, 0));
             return true;
         }
         return false;
diff --git a/java/src/com/android/inputmethod/latin/SuggestedWords.java b/java/src/com/android/inputmethod/latin/SuggestedWords.java
index 7892297..ff8945f 100644
--- a/java/src/com/android/inputmethod/latin/SuggestedWords.java
+++ b/java/src/com/android/inputmethod/latin/SuggestedWords.java
@@ -77,6 +77,11 @@
         return mShouldBlockAutoCorrectionBySafetyNet;
     }
 
+    public boolean willAutoCorrect() {
+        return !mTypedWordValid && mHasAutoCorrectionCandidate
+                && !shouldBlockAutoCorrectionBySafetyNet();
+    }
+
     public static class Builder {
         private List<CharSequence> mWords = new ArrayList<CharSequence>();
         private boolean mTypedWordValid;
diff --git a/java/src/com/android/inputmethod/latin/Utils.java b/java/src/com/android/inputmethod/latin/Utils.java
index 6e8017d..f6bc854 100644
--- a/java/src/com/android/inputmethod/latin/Utils.java
+++ b/java/src/com/android/inputmethod/latin/Utils.java
@@ -171,12 +171,16 @@
         return keyboardCount > 1;
     }
 
-    public static String getInputMethodId(InputMethodManagerCompatWrapper imm, String packageName) {
-        return getInputMethodInfo(imm, packageName).getId();
+    public static String getInputMethodId(String packageName) {
+        return getInputMethodInfo(packageName).getId();
     }
 
-    public static InputMethodInfoCompatWrapper getInputMethodInfo(
-            InputMethodManagerCompatWrapper imm, String packageName) {
+    public static InputMethodInfoCompatWrapper getInputMethodInfo(String packageName) {
+        final InputMethodManagerCompatWrapper imm = InputMethodManagerCompatWrapper.getInstance();
+        if (imm == null) {
+            throw new RuntimeException("Input method manager not found");
+        }
+
         for (final InputMethodInfoCompatWrapper imi : imm.getEnabledInputMethodList()) {
             if (imi.getPackageName().equals(packageName))
                 return imi;
@@ -774,11 +778,6 @@
         return s.toUpperCase(locale).charAt(0) + s.substring(1);
     }
 
-    public static boolean willAutoCorrect(SuggestedWords suggestions) {
-        return !suggestions.mTypedWordValid && suggestions.mHasAutoCorrectionCandidate
-                && !suggestions.shouldBlockAutoCorrectionBySafetyNet();
-    }
-
     public static class Stats {
         public static void onNonSeparator(final char code, final int x,
                 final int y) {
diff --git a/java/src/com/android/inputmethod/latin/suggestions/SuggestionsView.java b/java/src/com/android/inputmethod/latin/suggestions/SuggestionsView.java
index 9ab8c01..e5638ef 100644
--- a/java/src/com/android/inputmethod/latin/suggestions/SuggestionsView.java
+++ b/java/src/com/android/inputmethod/latin/suggestions/SuggestionsView.java
@@ -62,7 +62,6 @@
 import com.android.inputmethod.latin.StaticInnerHandlerWrapper;
 import com.android.inputmethod.latin.SuggestedWords;
 import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
-import com.android.inputmethod.latin.Utils;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -261,7 +260,7 @@
 
         private CharSequence getStyledSuggestionWord(SuggestedWords suggestions, int pos) {
             final CharSequence word = suggestions.getWord(pos);
-            final boolean isAutoCorrect = pos == 1 && Utils.willAutoCorrect(suggestions);
+            final boolean isAutoCorrect = pos == 1 && suggestions.willAutoCorrect();
             final boolean isTypedWordValid = pos == 0 && suggestions.mTypedWordValid;
             if (!isAutoCorrect && !isTypedWordValid)
                 return word;
@@ -282,7 +281,7 @@
         private int getWordPosition(int index, SuggestedWords suggestions) {
             // TODO: This works for 3 suggestions. Revisit this algorithm when there are 5 or more
             // suggestions.
-            final int centerPos = Utils.willAutoCorrect(suggestions) ? 1 : 0;
+            final int centerPos = suggestions.willAutoCorrect() ? 1 : 0;
             if (index == mCenterSuggestionIndex) {
                 return centerPos;
             } else if (index == centerPos) {
@@ -297,7 +296,7 @@
             final boolean isSuggested = (pos != 0);
 
             final int color;
-            if (index == mCenterSuggestionIndex && Utils.willAutoCorrect(suggestions)) {
+            if (index == mCenterSuggestionIndex && suggestions.willAutoCorrect()) {
                 color = mColorAutoCorrect;
             } else if (index == mCenterSuggestionIndex && suggestions.mTypedWordValid) {
                 color = mColorValidTypedWord;