Fix "Show settings key" option on 7" device

Cherry-pic I993ac772 from Honeycomb-MR2.

Bug: 4586882
Change-Id: Ie74138523a3ae7958c7bec674c49aa0ab1a72d05
diff --git a/java/res/values/attrs.xml b/java/res/values/attrs.xml
index 5c00510..e9b6354 100644
--- a/java/res/values/attrs.xml
+++ b/java/res/values/attrs.xml
@@ -277,6 +277,14 @@
         <attr name="navigateAction" format="boolean" />
         <attr name="passwordInput" format="boolean" />
         <attr name="hasSettingsKey" format="boolean" />
+        <!-- This should be aligned with KeyboardID.F2KEY_MODE_* -->
+        <attr name="f2KeyMode" format="enum">
+            <enum name="none" value="0" />
+            <enum name="settings" value="1" />
+            <enum name="shortcutIme" value="2" />
+            <enum name="shortcutImeOrSettings" value="3" />
+        </attr>
+        <attr name="clobberSettingsKey" format="boolean" />
         <attr name="voiceKeyEnabled" format="boolean" />
         <attr name="hasVoiceKey" format="boolean" />
         <attr name="imeAction" format="enum">
diff --git a/java/res/xml-sw600dp/kbd_key_styles.xml b/java/res/xml-sw600dp/kbd_key_styles.xml
index dbff293..e8e80ac 100644
--- a/java/res/xml-sw600dp/kbd_key_styles.xml
+++ b/java/res/xml-sw600dp/kbd_key_styles.xml
@@ -25,6 +25,23 @@
     <key-style
         latin:styleName="functionalKeyStyle"
         latin:isFunctional="true" />
+    <!-- Base key style for the key which may have settings key as popup key -->
+    <switch>
+        <case
+            latin:clobberSettingsKey="true"
+        >
+            <key-style
+                latin:styleName="settingsPopupStyle"
+                latin:parentStyle="functionalKeyStyle" />
+        </case>
+        <default>
+            <key-style
+                latin:styleName="settingsPopupStyle"
+                latin:keyLabelOption="popupHint"
+                latin:popupCharacters="\@icon/5|\@integer/key_settings"
+                latin:parentStyle="functionalKeyStyle" />
+        </default>
+    </switch>
     <!-- Functional key styles -->
     <key-style
         latin:styleName="shiftKeyStyle"
@@ -59,28 +76,18 @@
         latin:keyLabelOption="popupHint"
         latin:popupCharacters="@string/alternates_for_smiley"
         latin:maxPopupKeyboardColumn="5" />
-    <switch>
-        <case
-            latin:voiceKeyEnabled="true"
-        >
-            <key-style
-                latin:styleName="shortcutOrSettingsKeyStyle"
-                latin:code="@integer/key_shortcut"
-                latin:keyIcon="iconShortcutKey"
-                latin:keyIconPreview="iconPreviewShortcutKey"
-                latin:keyLabelOption="popupHint"
-                latin:popupCharacters="\@icon/5|\@integer/key_settings"
-                latin:parentStyle="functionalKeyStyle" />
-        </case>
-        <default>
-            <key-style
-                latin:styleName="shortcutOrSettingsKeyStyle"
-                latin:code="@integer/key_settings"
-                latin:keyIcon="iconSettingsKey"
-                latin:keyIconPreview="iconPreviewSettingsKey"
-                latin:parentStyle="functionalKeyStyle" />
-        </default>
-    </switch>
+    <key-style
+        latin:styleName="shortcutKeyStyle"
+        latin:code="@integer/key_shortcut"
+        latin:keyIcon="iconShortcutKey"
+        latin:keyIconPreview="iconPreviewShortcutKey"
+        latin:parentStyle="settingsPopupStyle" />
+    <key-style
+        latin:styleName="settingsKeyStyle"
+        latin:code="@integer/key_settings"
+        latin:keyIcon="iconSettingsKey"
+        latin:keyIconPreview="iconPreviewSettingsKey"
+        latin:parentStyle="functionalKeyStyle" />
     <key-style
         latin:styleName="tabKeyStyle"
         latin:code="@integer/key_tab"
diff --git a/java/res/xml-sw600dp/kbd_number.xml b/java/res/xml-sw600dp/kbd_number.xml
index 42d7d07..2c7af0a 100644
--- a/java/res/xml-sw600dp/kbd_number.xml
+++ b/java/res/xml-sw600dp/kbd_number.xml
@@ -78,12 +78,11 @@
                     latin:keyXPos="24.875%p" />
                 <Key
                     latin:keyStyle="num0KeyStyle" />
-                <Spacer />
-                <Key
-                    latin:keyStyle="shortcutOrSettingsKeyStyle"
+                <Spacer
                     latin:keyXPos="-11.00%p"
-                    latin:keyWidth="fillRight"
-                    latin:keyEdgeFlags="right" />
+                    latin:keyWidth="0%p" />
+                <include
+                    latin:keyboardLayout="@xml/kbd_qwerty_f2" />
             </Row>
         </case>
         <!-- latin:passwordInput="false" -->
@@ -185,11 +184,11 @@
                 <Key
                     latin:keyLabel="#"
                     latin:keyStyle="numLabelStyle" />
-                <Key
-                    latin:keyStyle="shortcutOrSettingsKeyStyle"
+                <Spacer
                     latin:keyXPos="-11.00%p"
-                    latin:keyWidth="fillBoth"
-                    latin:keyEdgeFlags="right" />
+                    latin:keyWidth="0%p" />
+                <include
+                    latin:keyboardLayout="@xml/kbd_qwerty_f2" />
             </Row>
         </default>
     </switch>
diff --git a/java/res/xml-sw600dp/kbd_phone.xml b/java/res/xml-sw600dp/kbd_phone.xml
index 017d003..4dee882 100644
--- a/java/res/xml-sw600dp/kbd_phone.xml
+++ b/java/res/xml-sw600dp/kbd_phone.xml
@@ -115,10 +115,10 @@
         <Key
             latin:keyLabel="#"
             latin:keyStyle="numLabelStyle" />
-        <Key
-            latin:keyStyle="shortcutOrSettingsKeyStyle"
+        <Spacer
             latin:keyXPos="-11.00%p"
-            latin:keyWidth="fillBoth"
-            latin:keyEdgeFlags="right" />
+            latin:keyWidth="0%p" />
+        <include
+            latin:keyboardLayout="@xml/kbd_qwerty_f2" />
     </Row>
 </Keyboard>
diff --git a/java/res/xml-sw600dp/kbd_phone_symbols.xml b/java/res/xml-sw600dp/kbd_phone_symbols.xml
index 168e6b1..87de880 100644
--- a/java/res/xml-sw600dp/kbd_phone_symbols.xml
+++ b/java/res/xml-sw600dp/kbd_phone_symbols.xml
@@ -125,10 +125,10 @@
         <Key
             latin:keyLabel="#"
             latin:keyStyle="numLabelStyle" />
-        <Key
-            latin:keyStyle="shortcutOrSettingsKeyStyle"
+        <Spacer
             latin:keyXPos="-11.00%p"
-            latin:keyWidth="fillBoth"
-            latin:keyEdgeFlags="right" />
+            latin:keyWidth="0%p" />
+        <include
+            latin:keyboardLayout="@xml/kbd_qwerty_f2" />
     </Row>
 </Keyboard>
diff --git a/java/res/xml-sw600dp/kbd_qwerty_f2.xml b/java/res/xml-sw600dp/kbd_qwerty_f2.xml
new file mode 100644
index 0000000..2724755
--- /dev/null
+++ b/java/res/xml-sw600dp/kbd_qwerty_f2.xml
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2011, 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.
+*/
+-->
+
+<merge
+    xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+>
+    <switch>
+        <case
+            latin:f2KeyMode="settings"
+        >
+            <Key
+                latin:keyStyle="settingsKeyStyle"
+                latin:keyWidth="fillBoth"
+                latin:keyEdgeFlags="right" />
+        </case>
+        <case
+            latin:f2KeyMode="shortcutIme"
+        >
+            <switch>
+                <case
+                    latin:voiceKeyEnabled="true"
+                >
+                    <Key
+                        latin:keyStyle="micKeyStyle"
+                        latin:keyWidth="fillBoth"
+                        latin:keyEdgeFlags="right" />
+                </case>
+                <!-- voiceKeyEnabled="false" -->
+                <default>
+                    <Spacer />
+                </default>
+            </switch>
+        </case>
+        <case
+            latin:f2KeyMode="shortcutImeOrSettings"
+        >
+            <switch>
+                <case
+                    latin:voiceKeyEnabled="true"
+                >
+                    <Key
+                        latin:keyStyle="micKeyStyle"
+                        latin:keyWidth="fillBoth"
+                        latin:keyEdgeFlags="right" />
+                </case>
+                <!-- voiceKeyEnabled="false" -->
+                <default>
+                    <Key
+                        latin:keyStyle="settingsKeyStyle"
+                        latin:keyWidth="fillBoth"
+                        latin:keyEdgeFlags="right" />
+                </default>
+            </switch>
+        </case>
+        <!-- f2KeyMode="none" -->
+        <default>
+            <Spacer />
+        </default>
+    </switch>
+</merge>
diff --git a/java/res/xml-sw600dp/kbd_qwerty_row4.xml b/java/res/xml-sw600dp/kbd_qwerty_row4.xml
index 958a7ed..8fd65fe 100644
--- a/java/res/xml-sw600dp/kbd_qwerty_row4.xml
+++ b/java/res/xml-sw600dp/kbd_qwerty_row4.xml
@@ -154,10 +154,10 @@
                 </switch>
             </default>
         </switch>
-        <Key
-            latin:keyStyle="shortcutOrSettingsKeyStyle"
-            latin:keyXPos="-10.0%p"
-            latin:keyWidth="fillBoth"
-            latin:keyEdgeFlags="right" />
+        <Spacer
+            latin:keyXPos="-10.00%p"
+            latin:keyWidth="0%p" />
+        <include
+            latin:keyboardLayout="@xml/kbd_qwerty_f2" />
     </Row>
 </merge>
diff --git a/java/res/xml-sw600dp/kbd_symbols.xml b/java/res/xml-sw600dp/kbd_symbols.xml
index fca97c7..77849f6 100644
--- a/java/res/xml-sw600dp/kbd_symbols.xml
+++ b/java/res/xml-sw600dp/kbd_symbols.xml
@@ -209,10 +209,10 @@
                     latin:keyWidth="9.750%p" />
             </default>
         </switch>
-        <Key
-            latin:keyStyle="shortcutOrSettingsKeyStyle"
-            latin:keyXPos="-10.0%p"
-            latin:keyWidth="fillBoth"
-            latin:keyEdgeFlags="right" />
+        <Spacer
+            latin:keyXPos="-10.00%p"
+            latin:keyWidth="0%p" />
+        <include
+            latin:keyboardLayout="@xml/kbd_qwerty_f2" />
     </Row>
 </Keyboard>
diff --git a/java/res/xml-sw600dp/kbd_symbols_shift.xml b/java/res/xml-sw600dp/kbd_symbols_shift.xml
index c23681d..b25292f 100644
--- a/java/res/xml-sw600dp/kbd_symbols_shift.xml
+++ b/java/res/xml-sw600dp/kbd_symbols_shift.xml
@@ -147,10 +147,10 @@
             latin:keyStyle="spaceKeyStyle"
             latin:keyXPos="30.750%p"
             latin:keyWidth="39.750%p" />
-        <Key
-            latin:keyStyle="shortcutOrSettingsKeyStyle"
-            latin:keyXPos="-10.0%p"
-            latin:keyWidth="fillRight"
-            latin:keyEdgeFlags="right" />
+        <Spacer
+            latin:keyXPos="-10.00%p"
+            latin:keyWidth="0%p" />
+        <include
+            latin:keyboardLayout="@xml/kbd_qwerty_f2" />
     </Row>
 </Keyboard>
diff --git a/java/res/xml/kbd_key_styles.xml b/java/res/xml/kbd_key_styles.xml
index e7d8d31..63d519c 100644
--- a/java/res/xml/kbd_key_styles.xml
+++ b/java/res/xml/kbd_key_styles.xml
@@ -28,13 +28,21 @@
     <!-- Base key style for the key which may have settings key as popup key -->
     <switch>
         <case
+            latin:clobberSettingsKey="true"
+        >
+            <key-style
+                latin:styleName="settingsPopupStyle"
+                latin:parentStyle="functionalKeyStyle" />
+        </case>
+        <case
+            latin:clobberSettingsKey="false"
             latin:hasSettingsKey="true"
         >
             <key-style
                 latin:styleName="settingsPopupStyle"
                 latin:parentStyle="functionalKeyStyle" />
         </case>
-        <!-- latin:hasSettingsKey="false" -->
+        <!-- clobberSettingsKey="false" and hasSettingsKey="false" -->
         <default>
             <key-style
                 latin:styleName="settingsPopupStyle"
@@ -57,57 +65,6 @@
         latin:keyIcon="iconDeleteKey"
         latin:parentStyle="functionalKeyStyle"
         latin:isRepeatable="true" />
-    <switch>
-        <!-- When this qwerty keyboard has no voice key but voice key is enabled, then symbol
-             keyboard will have mic key. That means we should use "?123mic" key here. -->
-        <case
-            latin:voiceKeyEnabled="true"
-            latin:hasVoiceKey="false"
-        >
-            <key-style
-                latin:styleName="toSymbolKeyStyle"
-                latin:code="@integer/key_switch_alpha_symbol"
-                latin:keyIcon="iconToSymbolKeyWithShortcut"
-                latin:parentStyle="functionalKeyStyle" />
-        </case>
-        <default>
-            <key-style
-                latin:styleName="toSymbolKeyStyle"
-                latin:code="@integer/key_switch_alpha_symbol"
-                latin:keyLabel="@string/label_to_symbol_key"
-                latin:parentStyle="functionalKeyStyle" />
-        </default>
-    </switch>
-    <key-style
-        latin:styleName="settingsKeyStyle"
-        latin:code="@integer/key_settings"
-        latin:keyIcon="iconSettingsKey"
-        latin:keyIconPreview="iconPreviewSettingsKey"
-        latin:parentStyle="functionalKeyStyle" />
-    <key-style
-        latin:styleName="spaceKeyStyle"
-        latin:code="@integer/key_space"
-        latin:keyIconPreview="iconPreviewSpaceKey"
-        latin:parentStyle="functionalKeyStyle" />
-    <key-style
-        latin:styleName="tabKeyStyle"
-        latin:code="@integer/key_tab"
-        latin:keyIcon="iconTabKey"
-        latin:keyIconPreview="iconPreviewTabKey"
-        latin:parentStyle="functionalKeyStyle" />
-    <key-style
-        latin:styleName="shortcutKeyStyle"
-        latin:code="@integer/key_shortcut"
-        latin:keyIcon="iconShortcutKey"
-        latin:keyIconPreview="iconPreviewShortcutKey"
-        latin:parentStyle="settingsPopupStyle" />
-    <!-- Note: This key style is not for functional tab key. This is used for the tab key which is
-         laid out as normal letter key. -->
-    <key-style
-        latin:styleName="nonSpecialBackgroundTabKeyStyle"
-        latin:code="@integer/key_tab"
-        latin:keyIcon="iconTabKey"
-        latin:keyIconPreview="iconPreviewTabKey" />
     <!-- Return key style -->
     <switch>
         <case
@@ -164,6 +121,65 @@
         </default>
     </switch>
     <key-style
+        latin:styleName="spaceKeyStyle"
+        latin:code="@integer/key_space"
+        latin:keyIconPreview="iconPreviewSpaceKey"
+        latin:parentStyle="functionalKeyStyle" />
+    <key-style
+        latin:styleName="smileyKeyStyle"
+        latin:keyLabel=":-)"
+        latin:keyOutputText=":-) "
+        latin:keyLabelOption="popupHint"
+        latin:popupCharacters="@string/alternates_for_smiley"
+        latin:maxPopupKeyboardColumn="5"
+        latin:parentStyle="functionalKeyStyle" />
+    <key-style
+        latin:styleName="shortcutKeyStyle"
+        latin:code="@integer/key_shortcut"
+        latin:keyIcon="iconShortcutKey"
+        latin:keyIconPreview="iconPreviewShortcutKey"
+        latin:parentStyle="settingsPopupStyle" />
+    <key-style
+        latin:styleName="settingsKeyStyle"
+        latin:code="@integer/key_settings"
+        latin:keyIcon="iconSettingsKey"
+        latin:keyIconPreview="iconPreviewSettingsKey"
+        latin:parentStyle="functionalKeyStyle" />
+    <key-style
+        latin:styleName="tabKeyStyle"
+        latin:code="@integer/key_tab"
+        latin:keyIcon="iconTabKey"
+        latin:keyIconPreview="iconPreviewTabKey"
+        latin:parentStyle="functionalKeyStyle" />
+    <!-- Note: This key style is not for functional tab key. This is used for the tab key which is
+         laid out as normal letter key. -->
+    <key-style
+        latin:styleName="nonSpecialBackgroundTabKeyStyle"
+        latin:code="@integer/key_tab"
+        latin:keyIcon="iconTabKey"
+        latin:keyIconPreview="iconPreviewTabKey" />
+    <switch>
+        <!-- When this qwerty keyboard has no voice key but voice key is enabled, then symbol
+             keyboard will have mic key. That means we should use "?123mic" key here. -->
+        <case
+            latin:voiceKeyEnabled="true"
+            latin:hasVoiceKey="false"
+        >
+            <key-style
+                latin:styleName="toSymbolKeyStyle"
+                latin:code="@integer/key_switch_alpha_symbol"
+                latin:keyIcon="iconToSymbolKeyWithShortcut"
+                latin:parentStyle="functionalKeyStyle" />
+        </case>
+        <default>
+            <key-style
+                latin:styleName="toSymbolKeyStyle"
+                latin:code="@integer/key_switch_alpha_symbol"
+                latin:keyLabel="@string/label_to_symbol_key"
+                latin:parentStyle="functionalKeyStyle" />
+        </default>
+    </switch>
+    <key-style
         latin:styleName="toAlphaKeyStyle"
         latin:code="@integer/key_switch_alpha_symbol"
         latin:keyLabel="@string/label_to_alpha_key"
@@ -174,14 +190,6 @@
         latin:keyLabel="@string/label_alt_key"
         latin:parentStyle="functionalKeyStyle"
         latin:isSticky="true" />
-    <key-style
-        latin:styleName="smileyKeyStyle"
-        latin:keyLabel=":-)"
-        latin:keyOutputText=":-) "
-        latin:keyLabelOption="popupHint"
-        latin:popupCharacters="@string/alternates_for_smiley"
-        latin:maxPopupKeyboardColumn="5"
-        latin:parentStyle="functionalKeyStyle" />
     <switch>
         <case
             latin:passwordInput="true"
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardId.java b/java/src/com/android/inputmethod/keyboard/KeyboardId.java
index b91134d..9c63c19 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardId.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardId.java
@@ -37,6 +37,11 @@
     public static final int MODE_PHONE = 4;
     public static final int MODE_NUMBER = 5;
 
+    public static final int F2KEY_MODE_NONE = 0;
+    public static final int F2KEY_MODE_SETTINGS = 1;
+    public static final int F2KEY_MODE_SHORTCUT_IME = 2;
+    public static final int F2KEY_MODE_SHORTCUT_IME_OR_SETTINGS = 3;
+
     public final Locale mLocale;
     public final int mOrientation;
     public final int mWidth;
@@ -44,7 +49,10 @@
     public final int mXmlId;
     public final boolean mNavigateAction;
     public final boolean mPasswordInput;
+    // TODO: Clean up these booleans and modes.
     public final boolean mHasSettingsKey;
+    public final int mF2KeyMode;
+    public final boolean mClobberSettingsKey;
     public final boolean mVoiceKeyEnabled;
     public final boolean mHasVoiceKey;
     public final int mImeAction;
@@ -56,8 +64,9 @@
     private final int mHashCode;
 
     public KeyboardId(String xmlName, int xmlId, Locale locale, int orientation, int width,
-            int mode, EditorInfo attribute, boolean hasSettingsKey, boolean voiceKeyEnabled,
-            boolean hasVoiceKey, boolean enableShiftLock) {
+            int mode, EditorInfo attribute, boolean hasSettingsKey, int f2KeyMode,
+            boolean clobberSettingsKey, boolean voiceKeyEnabled, boolean hasVoiceKey,
+            boolean enableShiftLock) {
         final int inputType = (attribute != null) ? attribute.inputType : 0;
         final int imeOptions = (attribute != null) ? attribute.imeOptions : 0;
         this.mLocale = locale;
@@ -72,6 +81,8 @@
         this.mPasswordInput = InputTypeCompatUtils.isPasswordInputType(inputType)
                 || InputTypeCompatUtils.isVisiblePasswordInputType(inputType);
         this.mHasSettingsKey = hasSettingsKey;
+        this.mF2KeyMode = f2KeyMode;
+        this.mClobberSettingsKey = clobberSettingsKey;
         this.mVoiceKeyEnabled = voiceKeyEnabled;
         this.mHasVoiceKey = hasVoiceKey;
         // We are interested only in {@link EditorInfo#IME_MASK_ACTION} enum value and
@@ -92,6 +103,8 @@
                 mNavigateAction,
                 mPasswordInput,
                 hasSettingsKey,
+                f2KeyMode,
+                clobberSettingsKey,
                 voiceKeyEnabled,
                 hasVoiceKey,
                 mImeAction,
@@ -101,14 +114,16 @@
 
     public KeyboardId cloneWithNewLayout(String xmlName, int xmlId) {
         return new KeyboardId(xmlName, xmlId, mLocale, mOrientation, mWidth, mMode, mAttribute,
-                mHasSettingsKey, mVoiceKeyEnabled, mHasVoiceKey, mEnableShiftLock);
+                mHasSettingsKey, mF2KeyMode, mClobberSettingsKey, mVoiceKeyEnabled, mHasVoiceKey,
+                mEnableShiftLock);
     }
 
     public KeyboardId cloneWithNewGeometry(int width) {
         if (mWidth == width)
             return this;
         return new KeyboardId(mXmlName, mXmlId, mLocale, mOrientation, width, mMode, mAttribute,
-                mHasSettingsKey, mVoiceKeyEnabled, mHasVoiceKey, mEnableShiftLock);
+                mHasSettingsKey, mF2KeyMode, mClobberSettingsKey, mVoiceKeyEnabled, mHasVoiceKey,
+                mEnableShiftLock);
     }
 
     public int getXmlId() {
@@ -149,6 +164,8 @@
             && other.mNavigateAction == this.mNavigateAction
             && other.mPasswordInput == this.mPasswordInput
             && other.mHasSettingsKey == this.mHasSettingsKey
+            && other.mF2KeyMode == this.mF2KeyMode
+            && other.mClobberSettingsKey == this.mClobberSettingsKey
             && other.mVoiceKeyEnabled == this.mVoiceKeyEnabled
             && other.mHasVoiceKey == this.mHasVoiceKey
             && other.mImeAction == this.mImeAction
@@ -162,12 +179,14 @@
 
     @Override
     public String toString() {
-        return String.format("[%s.xml %s %s%d %s %s %s%s%s%s%s%s]",
+        return String.format("[%s.xml %s %s%d %s %s %s%s%s%s%s%s%s%s]",
                 mXmlName,
                 mLocale,
                 (mOrientation == 1 ? "port" : "land"), mWidth,
                 modeName(mMode),
                 EditorInfoCompatUtils.imeOptionsName(mImeAction),
+                f2KeyModeName(mF2KeyMode),
+                (mClobberSettingsKey ? " clobberSettingsKey" : ""),
                 (mNavigateAction ? " navigateAction" : ""),
                 (mPasswordInput ? " passwordInput" : ""),
                 (mHasSettingsKey ? " hasSettingsKey" : ""),
@@ -185,7 +204,17 @@
         case MODE_IM: return "im";
         case MODE_PHONE: return "phone";
         case MODE_NUMBER: return "number";
+        default: return null;
         }
-        return null;
+    }
+
+    public static String f2KeyModeName(int f2KeyMode) {
+        switch (f2KeyMode) {
+        case F2KEY_MODE_NONE: return "none";
+        case F2KEY_MODE_SETTINGS: return "settings";
+        case F2KEY_MODE_SHORTCUT_IME: return "shortcutIme";
+        case F2KEY_MODE_SHORTCUT_IME_OR_SETTINGS: return "shortcutImeOrSettings";
+        default: return null;
+        }
     }
 }
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
index 1ad5b08..5176467 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
@@ -285,6 +285,10 @@
             }
         }
         final boolean hasSettingsKey = hasSettingsKey(attribute);
+        final int f2KeyMode = getF2KeyMode(mPrefs, mInputMethodService, attribute);
+        final boolean clobberSettingsKey = Utils.inPrivateImeOptions(
+                mInputMethodService.getPackageName(), LatinIME.IME_OPTION_NO_SETTINGS_KEY,
+                attribute);
         final Resources res = mInputMethodService.getResources();
         final int orientation = res.getConfiguration().orientation;
         if (mKeyboardWidth == 0)
@@ -292,7 +296,8 @@
         final Locale locale = mSubtypeSwitcher.getInputLocale();
         return new KeyboardId(
                 res.getResourceEntryName(xmlId), xmlId, locale, orientation, mKeyboardWidth,
-                mode, attribute, hasSettingsKey, mVoiceKeyEnabled, hasVoiceKey, enableShiftLock);
+                mode, attribute, hasSettingsKey, f2KeyMode, clobberSettingsKey, mVoiceKeyEnabled,
+                hasVoiceKey, enableShiftLock);
     }
 
     private KeyboardId makeSiblingKeyboardId(KeyboardId base, int alphabet, int phone) {
@@ -806,16 +811,16 @@
     }
 
     private static boolean getSettingsKeyMode(SharedPreferences prefs, Context context) {
-        Resources resources = context.getResources();
-        final boolean showSettingsKeyOption = resources.getBoolean(
+        final Resources res = context.getResources();
+        final boolean showSettingsKeyOption = res.getBoolean(
                 R.bool.config_enable_show_settings_key_option);
         if (showSettingsKeyOption) {
             final String settingsKeyMode = prefs.getString(Settings.PREF_SETTINGS_KEY,
-                    resources.getString(DEFAULT_SETTINGS_KEY_MODE));
+                    res.getString(DEFAULT_SETTINGS_KEY_MODE));
             // We show the settings key when 1) SETTINGS_KEY_MODE_ALWAYS_SHOW or
             // 2) SETTINGS_KEY_MODE_AUTO and there are two or more enabled IMEs on the system
-            if (settingsKeyMode.equals(resources.getString(SETTINGS_KEY_MODE_ALWAYS_SHOW))
-                    || (settingsKeyMode.equals(resources.getString(SETTINGS_KEY_MODE_AUTO))
+            if (settingsKeyMode.equals(res.getString(SETTINGS_KEY_MODE_ALWAYS_SHOW))
+                    || (settingsKeyMode.equals(res.getString(SETTINGS_KEY_MODE_AUTO))
                             && Utils.hasMultipleEnabledIMEsOrSubtypes(
                                     (InputMethodManagerCompatWrapper.getInstance(context))))) {
                 return true;
@@ -825,4 +830,21 @@
         // If the show settings key option is disabled, we always try showing the settings key.
         return true;
     }
+
+    private static int getF2KeyMode(SharedPreferences prefs, Context context,
+            EditorInfo attribute) {
+        final boolean clobberSettingsKey = Utils.inPrivateImeOptions(
+                context.getPackageName(), LatinIME.IME_OPTION_NO_SETTINGS_KEY, attribute);
+        final Resources res = context.getResources();
+        final String settingsKeyMode = prefs.getString(Settings.PREF_SETTINGS_KEY,
+                res.getString(DEFAULT_SETTINGS_KEY_MODE));
+        if (settingsKeyMode.equals(res.getString(SETTINGS_KEY_MODE_AUTO))) {
+            return clobberSettingsKey ? KeyboardId.F2KEY_MODE_SHORTCUT_IME
+                    : KeyboardId.F2KEY_MODE_SHORTCUT_IME_OR_SETTINGS;
+        } else if (settingsKeyMode.equals(res.getString(SETTINGS_KEY_MODE_ALWAYS_SHOW))) {
+            return clobberSettingsKey ? KeyboardId.F2KEY_MODE_NONE : KeyboardId.F2KEY_MODE_SETTINGS;
+        } else { // SETTINGS_KEY_MODE_ALWAYS_HIDE
+            return KeyboardId.F2KEY_MODE_SHORTCUT_IME;
+        }
+    }
 }
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardParser.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardParser.java
index d5b3648..76c8410 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardParser.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardParser.java
@@ -487,8 +487,12 @@
                     R.styleable.Keyboard_Case_navigateAction, id.mNavigateAction);
             final boolean passwordInputMatched = matchBoolean(a,
                     R.styleable.Keyboard_Case_passwordInput, id.mPasswordInput);
-            final boolean settingsKeyMatched = matchBoolean(a,
+            final boolean hasSettingsKeyMatched = matchBoolean(a,
                     R.styleable.Keyboard_Case_hasSettingsKey, id.mHasSettingsKey);
+            final boolean f2KeyModeMatched = matchInteger(a,
+                    R.styleable.Keyboard_Case_f2KeyMode, id.mF2KeyMode);
+            final boolean clobberSettingsKeyMatched = matchBoolean(a,
+                    R.styleable.Keyboard_Case_clobberSettingsKey, id.mClobberSettingsKey);
             final boolean voiceEnabledMatched = matchBoolean(a,
                     R.styleable.Keyboard_Case_voiceKeyEnabled, id.mVoiceKeyEnabled);
             final boolean voiceKeyMatched = matchBoolean(a,
@@ -506,15 +510,19 @@
             final boolean countryCodeMatched = matchString(a,
                     R.styleable.Keyboard_Case_countryCode, id.mLocale.getCountry());
             final boolean selected = modeMatched && navigateActionMatched && passwordInputMatched
-                    && settingsKeyMatched && voiceEnabledMatched && voiceKeyMatched
-                    && imeActionMatched && localeCodeMatched && languageCodeMatched
-                    && countryCodeMatched;
+                    && hasSettingsKeyMatched && f2KeyModeMatched && clobberSettingsKeyMatched
+                    && voiceEnabledMatched && voiceKeyMatched && imeActionMatched &&
+                    localeCodeMatched && languageCodeMatched && countryCodeMatched;
 
-            if (DEBUG) Log.d(TAG, String.format("<%s%s%s%s%s%s%s%s%s%s%s> %s", TAG_CASE,
+            if (DEBUG) Log.d(TAG, String.format("<%s%s%s%s%s%s%s%s%s%s%s%s%s> %s", TAG_CASE,
                     textAttr(a.getString(R.styleable.Keyboard_Case_mode), "mode"),
                     booleanAttr(a, R.styleable.Keyboard_Case_navigateAction, "navigateAction"),
                     booleanAttr(a, R.styleable.Keyboard_Case_passwordInput, "passwordInput"),
                     booleanAttr(a, R.styleable.Keyboard_Case_hasSettingsKey, "hasSettingsKey"),
+                    textAttr(KeyboardId.f2KeyModeName(
+                            a.getInt(R.styleable.Keyboard_Case_f2KeyMode, -1)), "f2KeyMode"),
+                    booleanAttr(a, R.styleable.Keyboard_Case_clobberSettingsKey,
+                            "clobberSettingsKey"),
                     booleanAttr(a, R.styleable.Keyboard_Case_voiceKeyEnabled, "voiceKeyEnabled"),
                     booleanAttr(a, R.styleable.Keyboard_Case_hasVoiceKey, "hasVoiceKey"),
                     textAttr(EditorInfoCompatUtils.imeOptionsName(