Support label with icon key

Bug: 5108339
Change-Id: I7cd4258a95a7e25b8b1114b43ffcca5b77c5c1e3
diff --git a/java/res/drawable-hdpi/sym_bkeyboard_123_mic.png b/java/res/drawable-hdpi/sym_bkeyboard_123_mic.png
deleted file mode 100644
index 3e4eff6..0000000
--- a/java/res/drawable-hdpi/sym_bkeyboard_123_mic.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_bkeyboard_label_mic.png b/java/res/drawable-hdpi/sym_bkeyboard_label_mic.png
new file mode 100644
index 0000000..25702cf
--- /dev/null
+++ b/java/res/drawable-hdpi/sym_bkeyboard_label_mic.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_123_mic.png b/java/res/drawable-hdpi/sym_keyboard_123_mic.png
deleted file mode 100644
index 6f0aec2..0000000
--- a/java/res/drawable-hdpi/sym_keyboard_123_mic.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_123_mic_holo.png b/java/res/drawable-hdpi/sym_keyboard_123_mic_holo.png
deleted file mode 100644
index ed66f75..0000000
--- a/java/res/drawable-hdpi/sym_keyboard_123_mic_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_label_mic.png b/java/res/drawable-hdpi/sym_keyboard_label_mic.png
new file mode 100644
index 0000000..4e0a8ed
--- /dev/null
+++ b/java/res/drawable-hdpi/sym_keyboard_label_mic.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_label_mic_holo.png b/java/res/drawable-hdpi/sym_keyboard_label_mic_holo.png
new file mode 100644
index 0000000..2280243
--- /dev/null
+++ b/java/res/drawable-hdpi/sym_keyboard_label_mic_holo.png
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_bkeyboard_123_mic.png b/java/res/drawable-mdpi/sym_bkeyboard_123_mic.png
deleted file mode 100644
index 0749b5f..0000000
--- a/java/res/drawable-mdpi/sym_bkeyboard_123_mic.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_bkeyboard_label_mic.png b/java/res/drawable-mdpi/sym_bkeyboard_label_mic.png
new file mode 100644
index 0000000..7f0b135
--- /dev/null
+++ b/java/res/drawable-mdpi/sym_bkeyboard_label_mic.png
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_123_mic.png b/java/res/drawable-mdpi/sym_keyboard_123_mic.png
deleted file mode 100644
index 35afe08..0000000
--- a/java/res/drawable-mdpi/sym_keyboard_123_mic.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_123_mic_holo.png b/java/res/drawable-mdpi/sym_keyboard_123_mic_holo.png
deleted file mode 100644
index 4814e51..0000000
--- a/java/res/drawable-mdpi/sym_keyboard_123_mic_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_label_mic.png b/java/res/drawable-mdpi/sym_keyboard_label_mic.png
new file mode 100644
index 0000000..a354d53
--- /dev/null
+++ b/java/res/drawable-mdpi/sym_keyboard_label_mic.png
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_label_mic_holo.png b/java/res/drawable-mdpi/sym_keyboard_label_mic_holo.png
new file mode 100644
index 0000000..d51adbe
--- /dev/null
+++ b/java/res/drawable-mdpi/sym_keyboard_label_mic_holo.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_bkeyboard_123_mic.png b/java/res/drawable-xhdpi/sym_bkeyboard_123_mic.png
deleted file mode 100644
index 0aefaa1..0000000
--- a/java/res/drawable-xhdpi/sym_bkeyboard_123_mic.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_bkeyboard_label_mic.png b/java/res/drawable-xhdpi/sym_bkeyboard_label_mic.png
new file mode 100644
index 0000000..9bd1d65
--- /dev/null
+++ b/java/res/drawable-xhdpi/sym_bkeyboard_label_mic.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_123_mic.png b/java/res/drawable-xhdpi/sym_keyboard_123_mic.png
deleted file mode 100644
index bcb0979..0000000
--- a/java/res/drawable-xhdpi/sym_keyboard_123_mic.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_123_mic_holo.png b/java/res/drawable-xhdpi/sym_keyboard_123_mic_holo.png
deleted file mode 100644
index 0c75058..0000000
--- a/java/res/drawable-xhdpi/sym_keyboard_123_mic_holo.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_label_mic.png b/java/res/drawable-xhdpi/sym_keyboard_label_mic.png
new file mode 100644
index 0000000..49810a0
--- /dev/null
+++ b/java/res/drawable-xhdpi/sym_keyboard_label_mic.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_label_mic_holo.png b/java/res/drawable-xhdpi/sym_keyboard_label_mic_holo.png
new file mode 100644
index 0000000..a7d3eaa
--- /dev/null
+++ b/java/res/drawable-xhdpi/sym_keyboard_label_mic_holo.png
Binary files differ
diff --git a/java/res/values-ar/donottranslate-altchars.xml b/java/res/values-ar/donottranslate-altchars.xml
index 9706665..0e4f265 100644
--- a/java/res/values-ar/donottranslate-altchars.xml
+++ b/java/res/values-ar/donottranslate-altchars.xml
@@ -61,10 +61,10 @@
     <string name="keylabel_for_symbols_percent">\u066a</string>
     <string name="alternates_for_comma">,</string>
     <string name="alternates_for_f1">,</string>
-    <!-- @icon/5 is iconSettingsKey -->
-    <string name="alternates_for_f1_settings">\\,,\@icon/5|\@integer/key_settings</string>
-    <!-- @icon/10 is iconTabKey -->
-    <string name="alternates_for_f1_navigate">\\,,\@icon/10|\@integer/key_tab</string>
+    <!-- @icon/3 is iconSettingsKey -->
+    <string name="alternates_for_f1_settings">\\,,\@icon/3|\@integer/key_settings</string>
+    <!-- @icon/7 is iconTabKey -->
+    <string name="alternates_for_f1_navigate">\\,,\@icon/7|\@integer/key_tab</string>
     <string name="alternates_for_symbols_question">\?,¿</string>
     <string name="alternates_for_symbols_semicolon">;</string>
     <string name="alternates_for_symbols_percent">%,‰</string>
diff --git a/java/res/values/attrs.xml b/java/res/values/attrs.xml
index af7484f..ab52271 100644
--- a/java/res/values/attrs.xml
+++ b/java/res/values/attrs.xml
@@ -154,15 +154,14 @@
         <attr name="isRtlKeyboard" format="boolean" />
         <!-- Icon set for key top and key preview. -->
         <attr name="iconShiftKey" format="reference" />
-        <attr name="iconToSymbolKey" format="reference" />
-        <attr name="iconToSymbolKeyWithShortcut" format="reference" />
         <attr name="iconDeleteKey" format="reference" />
         <attr name="iconSettingsKey" format="reference" />
-        <attr name="iconShortcutKey" format="reference" />
         <attr name="iconSpaceKey" format="reference" />
         <attr name="iconReturnKey" format="reference" />
         <attr name="iconSearchKey" format="reference" />
         <attr name="iconTabKey" format="reference" />
+        <attr name="iconShortcutKey" format="reference" />
+        <attr name="iconShortcutForLabel" format="reference" />
         <attr name="iconShiftedShiftKey" format="reference" />
         <attr name="iconPreviewTabKey" format="reference" />
         <attr name="iconPreviewSettingsKey" format="reference" />
@@ -202,32 +201,33 @@
             <flag name="hasPopupHint" value="0x200" />
             <flag name="hasUppercaseLetter" value="0x400" />
             <flag name="hasHintLabel" value="0x800" />
+            <flag name="withIconLeft" value="0x1000" />
+            <flag name="withIconRight" value="0x2000" />
         </attr>
         <!-- The icon to display on the key instead of the label. -->
         <attr name="keyIcon" format="enum">
             <!-- This should be aligned with KeyboardIcons.ICON_* -->
             <enum name="iconShiftKey" value="1" />
-            <enum name="iconToSymbolKey" value="2" />
-            <enum name="iconToSymbolKeyWithShortcut" value="3" />
-            <enum name="iconDeleteKey" value="4" />
-            <enum name="iconSettingsKey" value="5" />
-            <enum name="iconShortcutKey" value="6" />
-            <enum name="iconSpaceKey" value="7" />
-            <enum name="iconReturnKey" value="8" />
-            <enum name="iconSearchKey" value="9" />
-            <enum name="iconTabKey" value="10" />
+            <enum name="iconDeleteKey" value="2" />
+            <enum name="iconSettingsKey" value="3" />
+            <enum name="iconSpaceKey" value="4" />
+            <enum name="iconReturnKey" value="5" />
+            <enum name="iconSearchKey" value="6" />
+            <enum name="iconTabKey" value="7" />
+            <enum name="iconShortcutKey" value="8" />
+            <enum name="iconShortcutForLabel" value="9" />
         </attr>
         <!-- Shift key icon for shifted state -->
         <attr name="keyIconShifted" format="enum">
             <!-- This should be aligned with KeyboardIcons.ICON_SHIFTED_* -->
-            <enum name="iconShiftedShiftKey" value="11" />
+            <enum name="iconShiftedShiftKey" value="10" />
         </attr>
         <!-- The icon to show in the popup preview. -->
         <attr name="keyIconPreview" format="enum">
             <!-- This should be aligned with KeyboardIcons.ICON_PREVIEW_* -->
-            <enum name="iconPreviewTabKey" value="12" />
-            <enum name="iconPreviewSettingsKey" value="13" />
-            <enum name="iconPreviewShortcutKey" value="14" />
+            <enum name="iconPreviewTabKey" value="11" />
+            <enum name="iconPreviewSettingsKey" value="12" />
+            <enum name="iconPreviewShortcutKey" value="13" />
         </attr>
         <!-- The key style to specify a set of key attributes defined by <key_style/> -->
         <attr name="keyStyle" format="string" />
diff --git a/java/res/values/donottranslate-altchars.xml b/java/res/values/donottranslate-altchars.xml
index 0502650..fbde4b9 100644
--- a/java/res/values/donottranslate-altchars.xml
+++ b/java/res/values/donottranslate-altchars.xml
@@ -82,10 +82,10 @@
     <string name="keylabel_for_symbols_percent">%</string>
     <string name="alternates_for_comma"></string>
     <string name="alternates_for_f1"></string>
-    <!-- @icon/5 is iconSettingsKey -->
-    <string name="alternates_for_f1_settings">\@icon/5|\@integer/key_settings</string>
-    <!-- @icon/10 is iconTabKey -->
-    <string name="alternates_for_f1_navigate">\@icon/10|\@integer/key_tab</string>
+    <!-- @icon/3 is iconSettingsKey -->
+    <string name="alternates_for_f1_settings">\@icon/3|\@integer/key_settings</string>
+    <!-- @icon/7 is iconTabKey -->
+    <string name="alternates_for_f1_navigate">\@icon/7|\@integer/key_tab</string>
     <string name="alternates_for_symbols_question">¿</string>
     <string name="alternates_for_symbols_semicolon"></string>
     <string name="alternates_for_symbols_percent">‰</string>
diff --git a/java/res/values/keyboard-icons-black.xml b/java/res/values/keyboard-icons-black.xml
index ff758dc..23d163c 100644
--- a/java/res/values/keyboard-icons-black.xml
+++ b/java/res/values/keyboard-icons-black.xml
@@ -22,14 +22,14 @@
              sym_bkeyboard_voice_off
           -->
         <item name="iconShiftKey">@drawable/sym_bkeyboard_shift</item>
-        <item name="iconToSymbolKeyWithShortcut">@drawable/sym_bkeyboard_123_mic</item>
         <item name="iconDeleteKey">@drawable/sym_bkeyboard_delete</item>
         <item name="iconSettingsKey">@drawable/sym_bkeyboard_settings</item>
-        <item name="iconShortcutKey">@drawable/sym_bkeyboard_mic</item>
         <item name="iconSpaceKey">@drawable/sym_bkeyboard_space</item>
         <item name="iconReturnKey">@drawable/sym_bkeyboard_return</item>
         <item name="iconSearchKey">@drawable/sym_bkeyboard_search</item>
         <item name="iconTabKey">@drawable/sym_bkeyboard_tab</item>
+        <item name="iconShortcutKey">@drawable/sym_bkeyboard_mic</item>
+        <item name="iconShortcutForLabel">@drawable/sym_bkeyboard_label_mic</item>
         <item name="iconShiftedShiftKey">@drawable/sym_bkeyboard_shift_locked</item>
         <item name="iconPreviewTabKey">@drawable/sym_keyboard_feedback_tab</item>
         <item name="iconPreviewSettingsKey">@drawable/sym_keyboard_feedback_settings</item>
diff --git a/java/res/values/keyboard-icons-ics.xml b/java/res/values/keyboard-icons-ics.xml
index 62859e3..f619691 100644
--- a/java/res/values/keyboard-icons-ics.xml
+++ b/java/res/values/keyboard-icons-ics.xml
@@ -21,14 +21,14 @@
              sym_keyboard_123_mic_holo
              -->
         <item name="iconShiftKey">@drawable/sym_keyboard_shift_holo</item>
-        <item name="iconToSymbolKeyWithShortcut">@drawable/sym_keyboard_123_mic_holo</item>
         <item name="iconDeleteKey">@drawable/sym_keyboard_delete_holo</item>
         <item name="iconSettingsKey">@drawable/sym_keyboard_settings_holo</item>
-        <item name="iconShortcutKey">@drawable/sym_keyboard_voice_holo</item>
         <item name="iconSpaceKey">@drawable/sym_keyboard_space_holo</item>
         <item name="iconReturnKey">@drawable/sym_keyboard_return_holo</item>
         <item name="iconSearchKey">@drawable/sym_keyboard_search</item>
         <item name="iconTabKey">@drawable/sym_keyboard_tab_holo</item>
+        <item name="iconShortcutKey">@drawable/sym_keyboard_voice_holo</item>
+        <item name="iconShortcutForLabel">@drawable/sym_keyboard_label_mic_holo</item>
         <item name="iconShiftedShiftKey">@drawable/sym_keyboard_shift_locked_holo</item>
         <item name="iconPreviewTabKey">@drawable/sym_keyboard_feedback_tab</item>
         <item name="iconPreviewSettingsKey">@drawable/sym_keyboard_settings_holo</item>
diff --git a/java/res/values/keyboard-icons-white.xml b/java/res/values/keyboard-icons-white.xml
index 3c28cb7..a1765a4 100644
--- a/java/res/values/keyboard-icons-white.xml
+++ b/java/res/values/keyboard-icons-white.xml
@@ -18,14 +18,14 @@
     <style name="KeyboardIcons">
         <!-- Keyboard icons -->
         <item name="iconShiftKey">@drawable/sym_keyboard_shift</item>
-        <item name="iconToSymbolKeyWithShortcut">@drawable/sym_keyboard_123_mic</item>
         <item name="iconDeleteKey">@drawable/sym_keyboard_delete</item>
         <item name="iconSettingsKey">@drawable/sym_keyboard_settings</item>
-        <item name="iconShortcutKey">@drawable/sym_keyboard_mic</item>
         <item name="iconSpaceKey">@drawable/sym_keyboard_space</item>
         <item name="iconReturnKey">@drawable/sym_keyboard_return</item>
         <item name="iconSearchKey">@drawable/sym_keyboard_search</item>
         <item name="iconTabKey">@drawable/sym_keyboard_tab</item>
+        <item name="iconShortcutKey">@drawable/sym_keyboard_mic</item>
+        <item name="iconShortcutForLabel">@drawable/sym_keyboard_label_mic</item>
         <item name="iconShiftedShiftKey">@drawable/sym_keyboard_shift_locked</item>
         <item name="iconPreviewTabKey">@drawable/sym_keyboard_feedback_tab</item>
         <item name="iconPreviewSettingsKey">@drawable/sym_keyboard_feedback_settings</item>
diff --git a/java/res/values/strings.xml b/java/res/values/strings.xml
index aaea9ad..ed69fc9 100644
--- a/java/res/values/strings.xml
+++ b/java/res/values/strings.xml
@@ -121,6 +121,9 @@
     <string name="label_to_alpha_key">ABC</string>
     <!-- Label for "switch to symbols" key.  Must be short to fit on key! [CHAR LIMIT=4] -->
     <string name="label_to_symbol_key">\?123</string>
+    <!-- Label for "switch to symbols with microphone" key. This string shouldn't include the "mic"
+         part because it'll be appended by the code. Must be short to fit on key! [CHAR LIMIT=3] -->
+    <string name="label_to_symbol_with_microphone_key">123</string>
     <!-- Label for Shift modifier key of symbol keyboard.  Must be short to fit on key! [CHAR LIMIT=5] -->
     <string name="label_more_key">More</string>
     <!-- Label for "Pause" key of phone number keyboard.  Must be short to fit on key! [CHAR LIMIT=5] -->
diff --git a/java/res/xml-sw600dp/kbd_key_styles.xml b/java/res/xml-sw600dp/kbd_key_styles.xml
index b679368..5c693f4 100644
--- a/java/res/xml-sw600dp/kbd_key_styles.xml
+++ b/java/res/xml-sw600dp/kbd_key_styles.xml
@@ -38,7 +38,7 @@
             <key-style
                 latin:styleName="f2PopupStyle"
                 latin:keyLabelOption="hasPopupHint"
-                latin:popupCharacters="\@icon/5|\@integer/key_settings"
+                latin:popupCharacters="\@icon/3|\@integer/key_settings"
                 latin:parentStyle="functionalKeyStyle" />
         </default>
     </switch>
diff --git a/java/res/xml/kbd_key_styles.xml b/java/res/xml/kbd_key_styles.xml
index 5c4bf52..22b2a1d 100644
--- a/java/res/xml/kbd_key_styles.xml
+++ b/java/res/xml/kbd_key_styles.xml
@@ -187,7 +187,9 @@
             <key-style
                 latin:styleName="toSymbolKeyStyle"
                 latin:code="@integer/key_switch_alpha_symbol"
-                latin:keyIcon="iconToSymbolKeyWithShortcut"
+                latin:keyIcon="iconShortcutForLabel"
+                latin:keyLabel="@string/label_to_symbol_with_microphone_key"
+                latin:keyLabelOption="withIconRight"
                 latin:parentStyle="functionalKeyStyle" />
         </case>
         <default>
diff --git a/java/src/com/android/inputmethod/keyboard/Key.java b/java/src/com/android/inputmethod/keyboard/Key.java
index 57a354e..4cc0bba 100644
--- a/java/src/com/android/inputmethod/keyboard/Key.java
+++ b/java/src/com/android/inputmethod/keyboard/Key.java
@@ -51,10 +51,10 @@
     /** Hint label to display on the key in conjunction with the label */
     public final CharSequence mHintLabel;
     /** Option of the label */
-    public final int mLabelOption;
-    public static final int LABEL_OPTION_ALIGN_LEFT = 0x01;
-    public static final int LABEL_OPTION_ALIGN_RIGHT = 0x02;
-    public static final int LABEL_OPTION_ALIGN_LEFT_OF_CENTER = 0x08;
+    private final int mLabelOption;
+    private static final int LABEL_OPTION_ALIGN_LEFT = 0x01;
+    private static final int LABEL_OPTION_ALIGN_RIGHT = 0x02;
+    private static final int LABEL_OPTION_ALIGN_LEFT_OF_CENTER = 0x08;
     private static final int LABEL_OPTION_LARGE_LETTER = 0x10;
     private static final int LABEL_OPTION_FONT_NORMAL = 0x20;
     private static final int LABEL_OPTION_FONT_MONO_SPACE = 0x40;
@@ -63,6 +63,8 @@
     private static final int LABEL_OPTION_HAS_POPUP_HINT = 0x200;
     private static final int LABEL_OPTION_HAS_UPPERCASE_LETTER = 0x400;
     private static final int LABEL_OPTION_HAS_HINT_LABEL = 0x800;
+    private static final int LABEL_OPTION_WITH_ICON_LEFT = 0x1000;
+    private static final int LABEL_OPTION_WITH_ICON_RIGHT = 0x2000;
 
     /** Icon to display instead of a label. Icon takes precedence over a label */
     private Drawable mIcon;
@@ -384,6 +386,18 @@
         }
     }
 
+    public boolean isAlignLeft() {
+        return (mLabelOption & LABEL_OPTION_ALIGN_LEFT) != 0;
+    }
+
+    public boolean isAlignRight() {
+        return (mLabelOption & LABEL_OPTION_ALIGN_RIGHT) != 0;
+    }
+
+    public boolean isAlignLeftOfCenter() {
+        return (mLabelOption & LABEL_OPTION_ALIGN_LEFT_OF_CENTER) != 0;
+    }
+
     public boolean hasPopupHint() {
         return (mLabelOption & LABEL_OPTION_HAS_POPUP_HINT) != 0;
     }
@@ -396,6 +410,14 @@
         return (mLabelOption & LABEL_OPTION_HAS_HINT_LABEL) != 0;
     }
 
+    public boolean hasLabelWithIconLeft() {
+        return (mLabelOption & LABEL_OPTION_WITH_ICON_LEFT) != 0;
+    }
+
+    public boolean hasLabelWithIconRight() {
+        return (mLabelOption & LABEL_OPTION_WITH_ICON_RIGHT) != 0;
+    }
+
     public Drawable getIcon() {
         return mIcon;
     }
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardView.java b/java/src/com/android/inputmethod/keyboard/KeyboardView.java
index d1fd7e3..aab58b5 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardView.java
@@ -505,6 +505,7 @@
         }
 
         // Draw key label.
+        final Drawable icon = key.getIcon();
         float positionX = centerX;
         if (key.mLabel != null) {
             // Switch the character to uppercase if shift is pressed
@@ -521,16 +522,25 @@
             final float baseline = centerY + labelCharHeight / 2;
 
             // Horizontal label text alignment
-            if ((key.mLabelOption & Key.LABEL_OPTION_ALIGN_LEFT) != 0) {
+            float labelWidth = 0;
+            if (key.isAlignLeft()) {
                 positionX = (int)params.mKeyLabelHorizontalPadding;
                 paint.setTextAlign(Align.LEFT);
-            } else if ((key.mLabelOption & Key.LABEL_OPTION_ALIGN_RIGHT) != 0) {
+            } else if (key.isAlignRight()) {
                 positionX = keyWidth - (int)params.mKeyLabelHorizontalPadding;
                 paint.setTextAlign(Align.RIGHT);
-            } else if ((key.mLabelOption & Key.LABEL_OPTION_ALIGN_LEFT_OF_CENTER) != 0) {
+            } else if (key.isAlignLeftOfCenter()) {
                 // TODO: Parameterise this?
                 positionX = centerX - labelCharWidth * 7 / 4;
                 paint.setTextAlign(Align.LEFT);
+            } else if (key.hasLabelWithIconLeft() && icon != null) {
+                labelWidth = getLabelWidth(label, paint) + icon.getIntrinsicWidth();
+                positionX = centerX + labelWidth / 2;
+                paint.setTextAlign(Align.RIGHT);
+            } else if (key.hasLabelWithIconRight() && icon != null) {
+                labelWidth = getLabelWidth(label, paint) + icon.getIntrinsicWidth();
+                positionX = centerX - labelWidth / 2;
+                paint.setTextAlign(Align.LEFT);
             } else {
                 positionX = centerX;
                 paint.setTextAlign(Align.CENTER);
@@ -552,6 +562,19 @@
             // Turn off drop shadow
             paint.setShadowLayer(0, 0, 0, 0);
 
+            if (icon != null) {
+                final int iconWidth = icon.getIntrinsicWidth();
+                final int iconHeight = icon.getIntrinsicHeight();
+                final int iconY = (keyHeight - iconHeight) / 2;
+                if (key.hasLabelWithIconLeft()) {
+                    final int iconX = (int)(centerX - labelWidth / 2);
+                    drawIcon(canvas, icon, iconX, iconY, iconWidth, iconHeight);
+                } else if (key.hasLabelWithIconRight()) {
+                    final int iconX = (int)(centerX + labelWidth / 2 - iconWidth);
+                    drawIcon(canvas, icon, iconX, iconY, iconWidth, iconHeight);
+                }
+            }
+
             if (debugShowAlign) {
                 final Paint line = new Paint();
                 drawHorizontalLine(canvas, baseline, keyWidth, 0xc0008000, line);
@@ -605,16 +628,15 @@
         }
 
         // Draw key icon.
-        final Drawable icon = key.getIcon();
         if (key.mLabel == null && icon != null) {
             final int iconWidth = icon.getIntrinsicWidth();
             final int iconHeight = icon.getIntrinsicHeight();
             final int iconX, alignX;
             final int iconY = (keyHeight - iconHeight) / 2;
-            if ((key.mLabelOption & Key.LABEL_OPTION_ALIGN_LEFT) != 0) {
+            if (key.isAlignLeft()) {
                 iconX = (int)params.mKeyLabelHorizontalPadding;
                 alignX = iconX;
-            } else if ((key.mLabelOption & Key.LABEL_OPTION_ALIGN_RIGHT) != 0) {
+            } else if (key.isAlignRight()) {
                 iconX = keyWidth - (int)params.mKeyLabelHorizontalPadding - iconWidth;
                 alignX = iconX + iconWidth;
             } else { // Align center
@@ -694,6 +716,11 @@
         return width;
     }
 
+    private static float getLabelWidth(CharSequence label, Paint paint) {
+        paint.getTextBounds(label.toString(), 0, label.length(), sTextBounds);
+        return sTextBounds.width();
+    }
+
     private static void drawIcon(Canvas canvas, Drawable icon, int x, int y, int width,
             int height) {
         canvas.translate(x, y);
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardIconsSet.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardIconsSet.java
index ed4608b..2d8b7bf 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardIconsSet.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardIconsSet.java
@@ -30,23 +30,22 @@
 
     // This should be aligned with Keyboard.keyIcon enum.
     private static final int ICON_SHIFT_KEY = 1;
-    private static final int ICON_TO_SYMBOL_KEY = 2;
-    private static final int ICON_TO_SYMBOL_KEY_WITH_SHORTCUT = 3;
-    private static final int ICON_DELETE_KEY = 4;
-    private static final int ICON_SETTINGS_KEY = 5; // This is also represented as "@icon/5" in xml.
-    private static final int ICON_SHORTCUT_KEY = 6;
-    private static final int ICON_SPACE_KEY = 7;
-    private static final int ICON_RETURN_KEY = 8;
-    private static final int ICON_SEARCH_KEY = 9;
-    private static final int ICON_TAB_KEY = 10;
+    private static final int ICON_DELETE_KEY = 2;
+    private static final int ICON_SETTINGS_KEY = 3; // This is also represented as "@icon/3" in XML.
+    private static final int ICON_SPACE_KEY = 4;
+    private static final int ICON_RETURN_KEY = 5;
+    private static final int ICON_SEARCH_KEY = 6;
+    private static final int ICON_TAB_KEY = 7; // This is also represented as "@icon/7" in XML.
+    private static final int ICON_SHORTCUT_KEY = 8;
+    private static final int ICON_SHORTCUT_FOR_LABEL = 9;
     // This should be aligned with Keyboard.keyIconShifted enum.
-    private static final int ICON_SHIFTED_SHIFT_KEY = 11;
+    private static final int ICON_SHIFTED_SHIFT_KEY = 10;
     // This should be aligned with Keyboard.keyIconPreview enum.
-    private static final int ICON_PREVIEW_TAB_KEY = 12;
-    private static final int ICON_PREVIEW_SETTINGS_KEY = 13;
-    private static final int ICON_PREVIEW_SHORTCUT_KEY = 14;
+    private static final int ICON_PREVIEW_TAB_KEY = 11;
+    private static final int ICON_PREVIEW_SETTINGS_KEY = 12;
+    private static final int ICON_PREVIEW_SHORTCUT_KEY = 13;
 
-    private static final int ICON_LAST = 14;
+    private static final int ICON_LAST = 13;
 
     private final Drawable mIcons[] = new Drawable[ICON_LAST + 1];
 
@@ -54,16 +53,10 @@
         switch (attrIndex) {
         case R.styleable.Keyboard_iconShiftKey:
             return ICON_SHIFT_KEY;
-        case R.styleable.Keyboard_iconToSymbolKey:
-            return ICON_TO_SYMBOL_KEY;
-        case R.styleable.Keyboard_iconToSymbolKeyWithShortcut:
-            return ICON_TO_SYMBOL_KEY_WITH_SHORTCUT;
         case R.styleable.Keyboard_iconDeleteKey:
             return ICON_DELETE_KEY;
         case R.styleable.Keyboard_iconSettingsKey:
             return ICON_SETTINGS_KEY;
-        case R.styleable.Keyboard_iconShortcutKey:
-            return ICON_SHORTCUT_KEY;
         case R.styleable.Keyboard_iconSpaceKey:
             return ICON_SPACE_KEY;
         case R.styleable.Keyboard_iconReturnKey:
@@ -72,6 +65,10 @@
             return ICON_SEARCH_KEY;
         case R.styleable.Keyboard_iconTabKey:
             return ICON_TAB_KEY;
+        case R.styleable.Keyboard_iconShortcutKey:
+            return ICON_SHORTCUT_KEY;
+        case R.styleable.Keyboard_iconShortcutForLabel:
+            return ICON_SHORTCUT_FOR_LABEL;
         case R.styleable.Keyboard_iconShiftedShiftKey:
             return ICON_SHIFTED_SHIFT_KEY;
         case R.styleable.Keyboard_iconPreviewTabKey: