From a5c96f376ad57e78a88942bb618e067054ed818a Mon Sep 17 00:00:00 2001
From: "Tadashi G. Takaoka" <takaoka@google.com>
Date: Wed, 1 Feb 2012 15:07:25 +0900
Subject: [PATCH] Move long press shift handling from PointerTracker to
 KeyboardState

This change also
  * Rename phone shift keyboard to phone symbols keyboard.
    Use CODE_SWITCH_ALPHA_SYMBOL code to switch between phone and phone symbols keyboard.
  * Remove phone symbols keyboard from tablet.
  * Introduces enableLongPress flag of Key.keyActionFlags attribute.
  * Remove clumsy long press code from PointerTracker.
  * Remove CODE_CAPSLOCK handling from LatinIME.
  * Make KeyboardSwitcher to invoke haptic and audio feedback.

Change-Id: I00e1f697a10ab5112aec75e36853b96246ff5054
---
 java/res/values/attrs.xml                     |   5 +-
 java/res/values/keycodes.xml                  |   1 -
 java/res/xml-ar/keyboard_set.xml              |   4 +-
 java/res/xml-be/keyboard_set.xml              |   4 +-
 java/res/xml-bg/keyboard_set.xml              |   4 +-
 java/res/xml-cs/keyboard_set.xml              |   4 +-
 java/res/xml-da/keyboard_set.xml              |   4 +-
 java/res/xml-de-rZZ/keyboard_set.xml          |   4 +-
 java/res/xml-de/keyboard_set.xml              |   4 +-
 java/res/xml-es/keyboard_set.xml              |   4 +-
 java/res/xml-et/keyboard_set.xml              |   4 +-
 java/res/xml-fi/keyboard_set.xml              |   4 +-
 java/res/xml-fr-rCA/keyboard_set.xml          |   4 +-
 java/res/xml-fr-rCH/keyboard_set.xml          |   4 +-
 java/res/xml-fr/keyboard_set.xml              |   4 +-
 java/res/xml-hr/keyboard_set.xml              |   4 +-
 java/res/xml-hu/keyboard_set.xml              |   4 +-
 java/res/xml-iw/keyboard_set.xml              |   4 +-
 java/res/xml-ky/keyboard_set.xml              |   4 +-
 ..._phone_shift.xml => kbd_phone_symbols.xml} |   2 +-
 java/res/xml-nb/keyboard_set.xml              |   4 +-
 java/res/xml-pl/keyboard_set.xml              |   4 +-
 java/res/xml-pt/keyboard_set.xml              |   4 +-
 java/res/xml-ro/keyboard_set.xml              |   4 +-
 java/res/xml-ru/keyboard_set.xml              |   4 +-
 java/res/xml-sk/keyboard_set.xml              |   4 +-
 java/res/xml-sl/keyboard_set.xml              |   4 +-
 java/res/xml-sr/keyboard_set.xml              |   4 +-
 java/res/xml-sv/keyboard_set.xml              |   4 +-
 ..._phone_shift.xml => kbd_phone_symbols.xml} |   3 +-
 ..._phone_shift.xml => kbd_phone_symbols.xml} |   3 +-
 java/res/xml-sw600dp/rows_phone.xml           |  30 ++--
 java/res/xml-sw600dp/rows_phone_shift.xml     | 132 ---------------
 ..._phone_shift.xml => kbd_phone_symbols.xml} |   3 +-
 ..._phone_shift.xml => kbd_phone_symbols.xml} |   3 +-
 java/res/xml-sw768dp/rows_phone.xml           |  28 ++--
 java/res/xml-sw768dp/rows_phone_shift.xml     | 153 ------------------
 java/res/xml-tr/keyboard_set.xml              |   4 +-
 java/res/xml-uk/keyboard_set.xml              |   4 +-
 java/res/xml-vi/keyboard_set.xml              |   4 +-
 ..._phone_shift.xml => kbd_phone_symbols.xml} |   2 +-
 java/res/xml/key_styles_common.xml            |   2 +-
 java/res/xml/key_styles_number.xml            |  11 +-
 java/res/xml/keyboard_set.xml                 |   4 +-
 java/res/xml/rows_phone.xml                   |   2 +-
 ...phone_shift.xml => rows_phone_symbols.xml} |   2 +-
 .../com/android/inputmethod/keyboard/Key.java |  14 +-
 .../inputmethod/keyboard/Keyboard.java        |   3 +-
 .../inputmethod/keyboard/KeyboardId.java      |   8 +-
 .../inputmethod/keyboard/KeyboardSet.java     |   8 +-
 .../keyboard/KeyboardSwitcher.java            |  25 ++-
 .../keyboard/LatinKeyboardView.java           | 125 +++++++++-----
 .../inputmethod/keyboard/PointerTracker.java  |  42 ++---
 .../keyboard/internal/KeyboardState.java      |  70 ++++----
 .../android/inputmethod/latin/LatinIME.java   |  13 +-
 .../KeyboardStateMultiTouchTests.java         |  10 +-
 .../KeyboardStateSingleTouchTests.java        |  63 +++++---
 .../internal/KeyboardStateTestsBase.java      |  12 +-
 .../internal/MockKeyboardSwitcher.java        |  23 ++-
 59 files changed, 385 insertions(+), 533 deletions(-)
 rename java/res/xml-land/{kbd_phone_shift.xml => kbd_phone_symbols.xml} (93%)
 rename java/res/xml-sw600dp-land/{kbd_phone_shift.xml => kbd_phone_symbols.xml} (89%)
 rename java/res/xml-sw600dp/{kbd_phone_shift.xml => kbd_phone_symbols.xml} (88%)
 delete mode 100644 java/res/xml-sw600dp/rows_phone_shift.xml
 rename java/res/xml-sw768dp-land/{kbd_phone_shift.xml => kbd_phone_symbols.xml} (89%)
 rename java/res/xml-sw768dp/{kbd_phone_shift.xml => kbd_phone_symbols.xml} (88%)
 delete mode 100644 java/res/xml-sw768dp/rows_phone_shift.xml
 rename java/res/xml/{kbd_phone_shift.xml => kbd_phone_symbols.xml} (93%)
 rename java/res/xml/{rows_phone_shift.xml => rows_phone_symbols.xml} (97%)

diff --git a/java/res/values/attrs.xml b/java/res/values/attrs.xml
index a5bf6f69a9..d859ae3ea6 100644
--- a/java/res/values/attrs.xml
+++ b/java/res/values/attrs.xml
@@ -249,6 +249,7 @@
             <flag name="isRepeatable" value="0x01" />
             <flag name="noKeyPreview" value="0x02" />
             <flag name="altCodeWhileTyping" value="0x04" />
+            <flag name="enableLongPress" value="0x08" />
         </attr>
         <!-- The string of characters to output when this key is pressed. -->
         <attr name="keyOutputText" format="string" />
@@ -341,7 +342,7 @@
             <enum name="symbols" value="5" />
             <enum name="symbolsShifted" value="6"  />
             <enum name="phone" value="7"  />
-            <enum name="phoneShifted" value="8"  />
+            <enum name="phoneSymbols" value="8"  />
             <enum name="number" value="9"  />
         </attr>
         <!-- This should be aligned with KeyboardId.MODE_* -->
@@ -403,7 +404,7 @@
             <enum name="symbols" value="5" />
             <enum name="symbolsShifted" value="6"  />
             <enum name="phone" value="7"  />
-            <enum name="phoneShifted" value="8"  />
+            <enum name="phoneSymbols" value="8"  />
             <enum name="number" value="9"  />
         </attr>
         <attr name="elementKeyboard" format="reference"/>
diff --git a/java/res/values/keycodes.xml b/java/res/values/keycodes.xml
index b3f71d2bb4..2a91a3d6d3 100644
--- a/java/res/values/keycodes.xml
+++ b/java/res/values/keycodes.xml
@@ -25,7 +25,6 @@
     <integer name="key_space">32</integer>
     <integer name="key_shift">-1</integer>
     <integer name="key_switch_alpha_symbol">-2</integer>
-    <integer name="key_capslock">-3</integer>
     <integer name="key_output_text">-4</integer>
     <integer name="key_delete">-5</integer>
     <integer name="key_settings">-6</integer>
diff --git a/java/res/xml-ar/keyboard_set.xml b/java/res/xml-ar/keyboard_set.xml
index a8aac169bb..7b70f633ca 100644
--- a/java/res/xml-ar/keyboard_set.xml
+++ b/java/res/xml-ar/keyboard_set.xml
@@ -34,8 +34,8 @@
         latin:elementName="phone"
         latin:elementKeyboard="@xml/kbd_phone" />
     <Element
-        latin:elementName="phoneShifted"
-        latin:elementKeyboard="@xml/kbd_phone_shift" />
+        latin:elementName="phoneSymbols"
+        latin:elementKeyboard="@xml/kbd_phone_symbols" />
     <Element
         latin:elementName="number"
         latin:elementKeyboard="@xml/kbd_number" />
diff --git a/java/res/xml-be/keyboard_set.xml b/java/res/xml-be/keyboard_set.xml
index c8ee9c1620..042264aaee 100644
--- a/java/res/xml-be/keyboard_set.xml
+++ b/java/res/xml-be/keyboard_set.xml
@@ -34,8 +34,8 @@
         latin:elementName="phone"
         latin:elementKeyboard="@xml/kbd_phone" />
     <Element
-        latin:elementName="phoneShifted"
-        latin:elementKeyboard="@xml/kbd_phone_shift" />
+        latin:elementName="phoneSymbols"
+        latin:elementKeyboard="@xml/kbd_phone_symbols" />
     <Element
         latin:elementName="number"
         latin:elementKeyboard="@xml/kbd_number" />
diff --git a/java/res/xml-bg/keyboard_set.xml b/java/res/xml-bg/keyboard_set.xml
index 5a759648d3..49914d54b6 100644
--- a/java/res/xml-bg/keyboard_set.xml
+++ b/java/res/xml-bg/keyboard_set.xml
@@ -34,8 +34,8 @@
         latin:elementName="phone"
         latin:elementKeyboard="@xml/kbd_phone" />
     <Element
-        latin:elementName="phoneShifted"
-        latin:elementKeyboard="@xml/kbd_phone_shift" />
+        latin:elementName="phoneSymbols"
+        latin:elementKeyboard="@xml/kbd_phone_symbols" />
     <Element
         latin:elementName="number"
         latin:elementKeyboard="@xml/kbd_number" />
diff --git a/java/res/xml-cs/keyboard_set.xml b/java/res/xml-cs/keyboard_set.xml
index 6b476df822..b4535164b0 100644
--- a/java/res/xml-cs/keyboard_set.xml
+++ b/java/res/xml-cs/keyboard_set.xml
@@ -34,8 +34,8 @@
         latin:elementName="phone"
         latin:elementKeyboard="@xml/kbd_phone" />
     <Element
-        latin:elementName="phoneShifted"
-        latin:elementKeyboard="@xml/kbd_phone_shift" />
+        latin:elementName="phoneSymbols"
+        latin:elementKeyboard="@xml/kbd_phone_symbols" />
     <Element
         latin:elementName="number"
         latin:elementKeyboard="@xml/kbd_number" />
diff --git a/java/res/xml-da/keyboard_set.xml b/java/res/xml-da/keyboard_set.xml
index cf930dd05f..cf01ae6f53 100644
--- a/java/res/xml-da/keyboard_set.xml
+++ b/java/res/xml-da/keyboard_set.xml
@@ -34,8 +34,8 @@
         latin:elementName="phone"
         latin:elementKeyboard="@xml/kbd_phone" />
     <Element
-        latin:elementName="phoneShifted"
-        latin:elementKeyboard="@xml/kbd_phone_shift" />
+        latin:elementName="phoneSymbols"
+        latin:elementKeyboard="@xml/kbd_phone_symbols" />
     <Element
         latin:elementName="number"
         latin:elementKeyboard="@xml/kbd_number" />
diff --git a/java/res/xml-de-rZZ/keyboard_set.xml b/java/res/xml-de-rZZ/keyboard_set.xml
index 585dc3d6a4..635884d1db 100644
--- a/java/res/xml-de-rZZ/keyboard_set.xml
+++ b/java/res/xml-de-rZZ/keyboard_set.xml
@@ -34,8 +34,8 @@
         latin:elementName="phone"
         latin:elementKeyboard="@xml/kbd_phone" />
     <Element
-        latin:elementName="phoneShifted"
-        latin:elementKeyboard="@xml/kbd_phone_shift" />
+        latin:elementName="phoneSymbols"
+        latin:elementKeyboard="@xml/kbd_phone_symbols" />
     <Element
         latin:elementName="number"
         latin:elementKeyboard="@xml/kbd_number" />
diff --git a/java/res/xml-de/keyboard_set.xml b/java/res/xml-de/keyboard_set.xml
index 059174ccd1..485e63f061 100644
--- a/java/res/xml-de/keyboard_set.xml
+++ b/java/res/xml-de/keyboard_set.xml
@@ -34,8 +34,8 @@
         latin:elementName="phone"
         latin:elementKeyboard="@xml/kbd_phone" />
     <Element
-        latin:elementName="phoneShifted"
-        latin:elementKeyboard="@xml/kbd_phone_shift" />
+        latin:elementName="phoneSymbols"
+        latin:elementKeyboard="@xml/kbd_phone_symbols" />
     <Element
         latin:elementName="number"
         latin:elementKeyboard="@xml/kbd_number" />
diff --git a/java/res/xml-es/keyboard_set.xml b/java/res/xml-es/keyboard_set.xml
index ec40a5a9b2..2944a83ad9 100644
--- a/java/res/xml-es/keyboard_set.xml
+++ b/java/res/xml-es/keyboard_set.xml
@@ -34,8 +34,8 @@
         latin:elementName="phone"
         latin:elementKeyboard="@xml/kbd_phone" />
     <Element
-        latin:elementName="phoneShifted"
-        latin:elementKeyboard="@xml/kbd_phone_shift" />
+        latin:elementName="phoneSymbols"
+        latin:elementKeyboard="@xml/kbd_phone_symbols" />
     <Element
         latin:elementName="number"
         latin:elementKeyboard="@xml/kbd_number" />
diff --git a/java/res/xml-et/keyboard_set.xml b/java/res/xml-et/keyboard_set.xml
index 80a9d8fab9..1c23db3d80 100644
--- a/java/res/xml-et/keyboard_set.xml
+++ b/java/res/xml-et/keyboard_set.xml
@@ -34,8 +34,8 @@
         latin:elementName="phone"
         latin:elementKeyboard="@xml/kbd_phone" />
     <Element
-        latin:elementName="phoneShifted"
-        latin:elementKeyboard="@xml/kbd_phone_shift" />
+        latin:elementName="phoneSymbols"
+        latin:elementKeyboard="@xml/kbd_phone_symbols" />
     <Element
         latin:elementName="number"
         latin:elementKeyboard="@xml/kbd_number" />
diff --git a/java/res/xml-fi/keyboard_set.xml b/java/res/xml-fi/keyboard_set.xml
index cf95b5ec90..e8e4e7d9a3 100644
--- a/java/res/xml-fi/keyboard_set.xml
+++ b/java/res/xml-fi/keyboard_set.xml
@@ -34,8 +34,8 @@
         latin:elementName="phone"
         latin:elementKeyboard="@xml/kbd_phone" />
     <Element
-        latin:elementName="phoneShifted"
-        latin:elementKeyboard="@xml/kbd_phone_shift" />
+        latin:elementName="phoneSymbols"
+        latin:elementKeyboard="@xml/kbd_phone_symbols" />
     <Element
         latin:elementName="number"
         latin:elementKeyboard="@xml/kbd_number" />
diff --git a/java/res/xml-fr-rCA/keyboard_set.xml b/java/res/xml-fr-rCA/keyboard_set.xml
index 856363ea7d..ea6ac8f261 100644
--- a/java/res/xml-fr-rCA/keyboard_set.xml
+++ b/java/res/xml-fr-rCA/keyboard_set.xml
@@ -34,8 +34,8 @@
         latin:elementName="phone"
         latin:elementKeyboard="@xml/kbd_phone" />
     <Element
-        latin:elementName="phoneShifted"
-        latin:elementKeyboard="@xml/kbd_phone_shift" />
+        latin:elementName="phoneSymbols"
+        latin:elementKeyboard="@xml/kbd_phone_symbols" />
     <Element
         latin:elementName="number"
         latin:elementKeyboard="@xml/kbd_number" />
diff --git a/java/res/xml-fr-rCH/keyboard_set.xml b/java/res/xml-fr-rCH/keyboard_set.xml
index 778754c6ff..751900b88a 100644
--- a/java/res/xml-fr-rCH/keyboard_set.xml
+++ b/java/res/xml-fr-rCH/keyboard_set.xml
@@ -34,8 +34,8 @@
         latin:elementName="phone"
         latin:elementKeyboard="@xml/kbd_phone" />
     <Element
-        latin:elementName="phoneShifted"
-        latin:elementKeyboard="@xml/kbd_phone_shift" />
+        latin:elementName="phoneSymbols"
+        latin:elementKeyboard="@xml/kbd_phone_symbols" />
     <Element
         latin:elementName="number"
         latin:elementKeyboard="@xml/kbd_number" />
diff --git a/java/res/xml-fr/keyboard_set.xml b/java/res/xml-fr/keyboard_set.xml
index ae911afa00..42a20e5ea3 100644
--- a/java/res/xml-fr/keyboard_set.xml
+++ b/java/res/xml-fr/keyboard_set.xml
@@ -34,8 +34,8 @@
         latin:elementName="phone"
         latin:elementKeyboard="@xml/kbd_phone" />
     <Element
-        latin:elementName="phoneShifted"
-        latin:elementKeyboard="@xml/kbd_phone_shift" />
+        latin:elementName="phoneSymbols"
+        latin:elementKeyboard="@xml/kbd_phone_symbols" />
     <Element
         latin:elementName="number"
         latin:elementKeyboard="@xml/kbd_number" />
diff --git a/java/res/xml-hr/keyboard_set.xml b/java/res/xml-hr/keyboard_set.xml
index 4bd81d0e89..e17aefdf6a 100644
--- a/java/res/xml-hr/keyboard_set.xml
+++ b/java/res/xml-hr/keyboard_set.xml
@@ -34,8 +34,8 @@
         latin:elementName="phone"
         latin:elementKeyboard="@xml/kbd_phone" />
     <Element
-        latin:elementName="phoneShifted"
-        latin:elementKeyboard="@xml/kbd_phone_shift" />
+        latin:elementName="phoneSymbols"
+        latin:elementKeyboard="@xml/kbd_phone_symbols" />
     <Element
         latin:elementName="number"
         latin:elementKeyboard="@xml/kbd_number" />
diff --git a/java/res/xml-hu/keyboard_set.xml b/java/res/xml-hu/keyboard_set.xml
index 9ed1d949a0..0f6e5759e3 100644
--- a/java/res/xml-hu/keyboard_set.xml
+++ b/java/res/xml-hu/keyboard_set.xml
@@ -34,8 +34,8 @@
         latin:elementName="phone"
         latin:elementKeyboard="@xml/kbd_phone" />
     <Element
-        latin:elementName="phoneShifted"
-        latin:elementKeyboard="@xml/kbd_phone_shift" />
+        latin:elementName="phoneSymbols"
+        latin:elementKeyboard="@xml/kbd_phone_symbols" />
     <Element
         latin:elementName="number"
         latin:elementKeyboard="@xml/kbd_number" />
diff --git a/java/res/xml-iw/keyboard_set.xml b/java/res/xml-iw/keyboard_set.xml
index c16a6d79dc..501ba96ee2 100644
--- a/java/res/xml-iw/keyboard_set.xml
+++ b/java/res/xml-iw/keyboard_set.xml
@@ -34,8 +34,8 @@
         latin:elementName="phone"
         latin:elementKeyboard="@xml/kbd_phone" />
     <Element
-        latin:elementName="phoneShifted"
-        latin:elementKeyboard="@xml/kbd_phone_shift" />
+        latin:elementName="phoneSymbols"
+        latin:elementKeyboard="@xml/kbd_phone_symbols" />
     <Element
         latin:elementName="number"
         latin:elementKeyboard="@xml/kbd_number" />
diff --git a/java/res/xml-ky/keyboard_set.xml b/java/res/xml-ky/keyboard_set.xml
index 1bb8926dfb..abd5f16318 100644
--- a/java/res/xml-ky/keyboard_set.xml
+++ b/java/res/xml-ky/keyboard_set.xml
@@ -34,8 +34,8 @@
         latin:elementName="phone"
         latin:elementKeyboard="@xml/kbd_phone" />
     <Element
-        latin:elementName="phoneShifted"
-        latin:elementKeyboard="@xml/kbd_phone_shift" />
+        latin:elementName="phoneSymbols"
+        latin:elementKeyboard="@xml/kbd_phone_symbols" />
     <Element
         latin:elementName="number"
         latin:elementKeyboard="@xml/kbd_number" />
diff --git a/java/res/xml-land/kbd_phone_shift.xml b/java/res/xml-land/kbd_phone_symbols.xml
similarity index 93%
rename from java/res/xml-land/kbd_phone_shift.xml
rename to java/res/xml-land/kbd_phone_symbols.xml
index f456a17759..41ba6cf3b9 100644
--- a/java/res/xml-land/kbd_phone_shift.xml
+++ b/java/res/xml-land/kbd_phone_symbols.xml
@@ -24,5 +24,5 @@
     latin:keyWidth="26.67%p"
 >
     <include
-        latin:keyboardLayout="@xml/rows_phone_shift" />
+        latin:keyboardLayout="@xml/rows_phone_symbols" />
 </Keyboard>
diff --git a/java/res/xml-nb/keyboard_set.xml b/java/res/xml-nb/keyboard_set.xml
index 1a36de4356..d146beb711 100644
--- a/java/res/xml-nb/keyboard_set.xml
+++ b/java/res/xml-nb/keyboard_set.xml
@@ -34,8 +34,8 @@
         latin:elementName="phone"
         latin:elementKeyboard="@xml/kbd_phone" />
     <Element
-        latin:elementName="phoneShifted"
-        latin:elementKeyboard="@xml/kbd_phone_shift" />
+        latin:elementName="phoneSymbols"
+        latin:elementKeyboard="@xml/kbd_phone_symbols" />
     <Element
         latin:elementName="number"
         latin:elementKeyboard="@xml/kbd_number" />
diff --git a/java/res/xml-pl/keyboard_set.xml b/java/res/xml-pl/keyboard_set.xml
index 39ee777719..6d27379298 100644
--- a/java/res/xml-pl/keyboard_set.xml
+++ b/java/res/xml-pl/keyboard_set.xml
@@ -34,8 +34,8 @@
         latin:elementName="phone"
         latin:elementKeyboard="@xml/kbd_phone" />
     <Element
-        latin:elementName="phoneShifted"
-        latin:elementKeyboard="@xml/kbd_phone_shift" />
+        latin:elementName="phoneSymbols"
+        latin:elementKeyboard="@xml/kbd_phone_symbols" />
     <Element
         latin:elementName="number"
         latin:elementKeyboard="@xml/kbd_number" />
diff --git a/java/res/xml-pt/keyboard_set.xml b/java/res/xml-pt/keyboard_set.xml
index bd19761d38..65f9634ceb 100644
--- a/java/res/xml-pt/keyboard_set.xml
+++ b/java/res/xml-pt/keyboard_set.xml
@@ -34,8 +34,8 @@
         latin:elementName="phone"
         latin:elementKeyboard="@xml/kbd_phone" />
     <Element
-        latin:elementName="phoneShifted"
-        latin:elementKeyboard="@xml/kbd_phone_shift" />
+        latin:elementName="phoneSymbols"
+        latin:elementKeyboard="@xml/kbd_phone_symbols" />
     <Element
         latin:elementName="number"
         latin:elementKeyboard="@xml/kbd_number" />
diff --git a/java/res/xml-ro/keyboard_set.xml b/java/res/xml-ro/keyboard_set.xml
index 75ca682720..6c34966d0e 100644
--- a/java/res/xml-ro/keyboard_set.xml
+++ b/java/res/xml-ro/keyboard_set.xml
@@ -34,8 +34,8 @@
         latin:elementName="phone"
         latin:elementKeyboard="@xml/kbd_phone" />
     <Element
-        latin:elementName="phoneShifted"
-        latin:elementKeyboard="@xml/kbd_phone_shift" />
+        latin:elementName="phoneSymbols"
+        latin:elementKeyboard="@xml/kbd_phone_symbols" />
     <Element
         latin:elementName="number"
         latin:elementKeyboard="@xml/kbd_number" />
diff --git a/java/res/xml-ru/keyboard_set.xml b/java/res/xml-ru/keyboard_set.xml
index 8d4d277b22..b6a356891a 100644
--- a/java/res/xml-ru/keyboard_set.xml
+++ b/java/res/xml-ru/keyboard_set.xml
@@ -34,8 +34,8 @@
         latin:elementName="phone"
         latin:elementKeyboard="@xml/kbd_phone" />
     <Element
-        latin:elementName="phoneShifted"
-        latin:elementKeyboard="@xml/kbd_phone_shift" />
+        latin:elementName="phoneSymbols"
+        latin:elementKeyboard="@xml/kbd_phone_symbols" />
     <Element
         latin:elementName="number"
         latin:elementKeyboard="@xml/kbd_number" />
diff --git a/java/res/xml-sk/keyboard_set.xml b/java/res/xml-sk/keyboard_set.xml
index b73c446ef5..b283d968ab 100644
--- a/java/res/xml-sk/keyboard_set.xml
+++ b/java/res/xml-sk/keyboard_set.xml
@@ -34,8 +34,8 @@
         latin:elementName="phone"
         latin:elementKeyboard="@xml/kbd_phone" />
     <Element
-        latin:elementName="phoneShifted"
-        latin:elementKeyboard="@xml/kbd_phone_shift" />
+        latin:elementName="phoneSymbols"
+        latin:elementKeyboard="@xml/kbd_phone_symbols" />
     <Element
         latin:elementName="number"
         latin:elementKeyboard="@xml/kbd_number" />
diff --git a/java/res/xml-sl/keyboard_set.xml b/java/res/xml-sl/keyboard_set.xml
index b2378e2c2f..dbb2782f08 100644
--- a/java/res/xml-sl/keyboard_set.xml
+++ b/java/res/xml-sl/keyboard_set.xml
@@ -34,8 +34,8 @@
         latin:elementName="phone"
         latin:elementKeyboard="@xml/kbd_phone" />
     <Element
-        latin:elementName="phoneShifted"
-        latin:elementKeyboard="@xml/kbd_phone_shift" />
+        latin:elementName="phoneSymbols"
+        latin:elementKeyboard="@xml/kbd_phone_symbols" />
     <Element
         latin:elementName="number"
         latin:elementKeyboard="@xml/kbd_number" />
diff --git a/java/res/xml-sr/keyboard_set.xml b/java/res/xml-sr/keyboard_set.xml
index 729136f3a4..15471dbcd6 100644
--- a/java/res/xml-sr/keyboard_set.xml
+++ b/java/res/xml-sr/keyboard_set.xml
@@ -34,8 +34,8 @@
         latin:elementName="phone"
         latin:elementKeyboard="@xml/kbd_phone" />
     <Element
-        latin:elementName="phoneShifted"
-        latin:elementKeyboard="@xml/kbd_phone_shift" />
+        latin:elementName="phoneSymbols"
+        latin:elementKeyboard="@xml/kbd_phone_symbols" />
     <Element
         latin:elementName="number"
         latin:elementKeyboard="@xml/kbd_number" />
diff --git a/java/res/xml-sv/keyboard_set.xml b/java/res/xml-sv/keyboard_set.xml
index 3d366a4439..e5184d33fd 100644
--- a/java/res/xml-sv/keyboard_set.xml
+++ b/java/res/xml-sv/keyboard_set.xml
@@ -34,8 +34,8 @@
         latin:elementName="phone"
         latin:elementKeyboard="@xml/kbd_phone" />
     <Element
-        latin:elementName="phoneShifted"
-        latin:elementKeyboard="@xml/kbd_phone_shift" />
+        latin:elementName="phoneSymbols"
+        latin:elementKeyboard="@xml/kbd_phone_symbols" />
     <Element
         latin:elementName="number"
         latin:elementKeyboard="@xml/kbd_number" />
diff --git a/java/res/xml-sw600dp-land/kbd_phone_shift.xml b/java/res/xml-sw600dp-land/kbd_phone_symbols.xml
similarity index 89%
rename from java/res/xml-sw600dp-land/kbd_phone_shift.xml
rename to java/res/xml-sw600dp-land/kbd_phone_symbols.xml
index ba837922f8..e3f56bce7d 100644
--- a/java/res/xml-sw600dp-land/kbd_phone_shift.xml
+++ b/java/res/xml-sw600dp-land/kbd_phone_symbols.xml
@@ -23,6 +23,7 @@
     latin:keyboardHorizontalEdgesPadding="10%p"
     latin:keyWidth="15.00%p"
 >
+    <!-- Tablet doesn't have phone symbols keyboard -->
     <include
-        latin:keyboardLayout="@xml/rows_phone_shift" />
+        latin:keyboardLayout="@xml/rows_phone" />
 </Keyboard>
diff --git a/java/res/xml-sw600dp/kbd_phone_shift.xml b/java/res/xml-sw600dp/kbd_phone_symbols.xml
similarity index 88%
rename from java/res/xml-sw600dp/kbd_phone_shift.xml
rename to java/res/xml-sw600dp/kbd_phone_symbols.xml
index e722545761..9faeaf4e03 100644
--- a/java/res/xml-sw600dp/kbd_phone_shift.xml
+++ b/java/res/xml-sw600dp/kbd_phone_symbols.xml
@@ -22,6 +22,7 @@
     xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
     latin:keyWidth="15.00%p"
 >
+    <!-- Tablet doesn't have phone symbols keyboard -->
     <include
-        latin:keyboardLayout="@xml/rows_phone_shift" />
+        latin:keyboardLayout="@xml/rows_phone" />
 </Keyboard>
diff --git a/java/res/xml-sw600dp/rows_phone.xml b/java/res/xml-sw600dp/rows_phone.xml
index 1bad7ca72c..fe8511988e 100644
--- a/java/res/xml-sw600dp/rows_phone.xml
+++ b/java/res/xml-sw600dp/rows_phone.xml
@@ -28,7 +28,7 @@
     <Row>
         <!-- Note: This Spacer prevents the below key from being marked as a left edge key. -->
         <Spacer
-            latin:keyWidth="17.375%p" />
+            latin:keyWidth="12.75%p" />
         <Key
             latin:keyLabel="-"
             latin:keyStyle="numKeyStyle"
@@ -37,6 +37,9 @@
             latin:keyLabel="+"
             latin:keyStyle="numKeyStyle"
             latin:keyWidth="9.25%p" />
+        <Key
+            latin:keyStyle="numPauseKeyStyle"
+            latin:keyWidth="9.25%p" />
         <Key
             latin:keyStyle="num1KeyStyle"
             latin:keyXPos="42.25%p" />
@@ -52,7 +55,7 @@
     <Row>
         <!-- Note: This Spacer prevents the below key from being marked as a left edge key. -->
         <Spacer
-            latin:keyWidth="17.375%p" />
+            latin:keyWidth="12.75%p" />
         <Key
             latin:keyLabel=","
             latin:keyStyle="numKeyStyle"
@@ -61,6 +64,9 @@
             latin:keyLabel="."
             latin:keyStyle="numKeyStyle"
             latin:keyWidth="9.25%p" />
+        <Key
+            latin:keyStyle="numWaitKeyStyle"
+            latin:keyWidth="9.25%p" />
         <Key
             latin:keyStyle="num4KeyStyle"
             latin:keyXPos="42.25%p" />
@@ -74,18 +80,22 @@
             latin:keyWidth="fillRight" />
     </Row>
     <Row>
-        <Key
-            latin:keyStyle="toMoreSymbolKeyStyle"
-            latin:keyWidth="11.0%p" />
+        <!-- Note: This Spacer prevents the below key from being marked as a left edge key. -->
+        <Spacer
+            latin:keyWidth="12.75%p" />
         <Key
             latin:keyLabel="("
             latin:keyStyle="numKeyStyle"
-            latin:keyXPos="17.375%p"
-            latin:keyWidth="9.25%p" />
+            latin:keyWidth="9.25%p"
+            latin:keyXPos="12.75%p" />
         <Key
             latin:keyLabel=")"
             latin:keyStyle="numKeyStyle"
             latin:keyWidth="9.25%p" />
+        <Key
+            latin:keyLabel="N"
+            latin:keyStyle="numKeyStyle"
+            latin:keyWidth="9.25%p" />
         <Key
             latin:keyStyle="num7KeyStyle"
             latin:keyXPos="42.25%p" />
@@ -96,15 +106,15 @@
         <!-- Note: This Spacer prevents the above key from being marked as a right edge key. -->
         <Spacer
             latin:keyWidth="0%p" />
-        </Row>
+    </Row>
     <Row>
         <Key
             latin:keyStyle="numTabKeyStyle"
             latin:keyWidth="11.00%p" />
         <Key
             latin:keyStyle="nonSpecialBackgroundSpaceKeyStyle"
-            latin:keyWidth="18.50%p"
-            latin:keyXPos="17.375%p" />
+            latin:keyWidth="27.75%p"
+            latin:keyXPos="12.75%p" />
         <Key
             latin:keyStyle="numStarKeyStyle"
             latin:keyXPos="42.25%p" />
diff --git a/java/res/xml-sw600dp/rows_phone_shift.xml b/java/res/xml-sw600dp/rows_phone_shift.xml
deleted file mode 100644
index c2f00fe8b8..0000000000
--- a/java/res/xml-sw600dp/rows_phone_shift.xml
+++ /dev/null
@@ -1,132 +0,0 @@
-<?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"
->
-    <include
-        latin:keyboardLayout="@xml/key_styles_common" />
-    <include
-        latin:keyboardLayout="@xml/key_styles_number" />
-    <Row>
-        <!-- Note: This Spacer prevents the below key from being marked as a left edge key. -->
-        <Spacer
-            latin:keyWidth="12.75%p" />
-        <Key
-            latin:keyLabel="-"
-            latin:keyStyle="numKeyStyle"
-            latin:keyWidth="9.25%p" />
-        <Key
-            latin:keyLabel="+"
-            latin:keyStyle="numKeyStyle"
-            latin:keyWidth="9.25%p" />
-        <Key
-            latin:keyStyle="numPauseKeyStyle"
-            latin:keyWidth="9.25%p" />
-        <Key
-            latin:keyStyle="num1KeyStyle"
-            latin:keyXPos="42.25%p" />
-        <Key
-            latin:keyStyle="num2KeyStyle" />
-        <Key
-            latin:keyStyle="num3KeyStyle" />
-        <Key
-            latin:keyStyle="deleteKeyStyle"
-            latin:keyXPos="-11.00%p"
-            latin:keyWidth="fillRight" />
-    </Row>
-    <Row>
-        <!-- Note: This Spacer prevents the below key from being marked as a left edge key. -->
-        <Spacer
-            latin:keyWidth="12.75%p" />
-        <Key
-            latin:keyLabel=","
-            latin:keyStyle="numKeyStyle"
-            latin:keyWidth="9.25%p" />
-        <Key
-            latin:keyLabel="."
-            latin:keyStyle="numKeyStyle"
-            latin:keyWidth="9.25%p" />
-        <Key
-            latin:keyStyle="numWaitKeyStyle"
-            latin:keyWidth="9.25%p" />
-        <Key
-            latin:keyStyle="num4KeyStyle"
-            latin:keyXPos="42.25%p" />
-        <Key
-            latin:keyStyle="num5KeyStyle" />
-        <Key
-            latin:keyStyle="num6KeyStyle" />
-        <Key
-            latin:keyStyle="returnKeyStyle"
-            latin:keyXPos="-11.00%p"
-            latin:keyWidth="fillRight" />
-    </Row>
-    <Row>
-        <Key
-            latin:keyStyle="backFromMoreSymbolKeyStyle"
-            latin:keyWidth="11.00%p" />
-        <Key
-            latin:keyLabel="("
-            latin:keyStyle="numKeyStyle"
-            latin:keyWidth="9.25%p"
-            latin:keyXPos="12.75%p" />
-        <Key
-            latin:keyLabel=")"
-            latin:keyStyle="numKeyStyle"
-            latin:keyWidth="9.25%p" />
-        <Key
-            latin:keyLabel="N"
-            latin:keyStyle="numKeyStyle"
-            latin:keyWidth="9.25%p" />
-        <Key
-            latin:keyStyle="num7KeyStyle"
-            latin:keyXPos="42.25%p" />
-        <Key
-            latin:keyStyle="num8KeyStyle" />
-        <Key
-            latin:keyStyle="num9KeyStyle" />
-        <!-- Note: This Spacer prevents the above key from being marked as a right edge key. -->
-        <Spacer
-            latin:keyWidth="0%p" />
-    </Row>
-    <Row>
-        <Key
-            latin:keyStyle="numTabKeyStyle"
-            latin:keyWidth="11.00%p" />
-        <Key
-            latin:keyStyle="nonSpecialBackgroundSpaceKeyStyle"
-            latin:keyWidth="27.75%p"
-            latin:keyXPos="12.75%p" />
-        <Key
-            latin:keyStyle="numStarKeyStyle"
-            latin:keyXPos="42.25%p" />
-        <Key
-            latin:keyStyle="num0KeyStyle" />
-        <Key
-            latin:keyLabel="#"
-            latin:keyStyle="numKeyStyle" />
-        <Spacer
-            latin:keyXPos="-11.00%p"
-            latin:keyWidth="0%p" />
-        <include
-            latin:keyboardLayout="@xml/key_f2" />
-    </Row>
-</merge>
diff --git a/java/res/xml-sw768dp-land/kbd_phone_shift.xml b/java/res/xml-sw768dp-land/kbd_phone_symbols.xml
similarity index 89%
rename from java/res/xml-sw768dp-land/kbd_phone_shift.xml
rename to java/res/xml-sw768dp-land/kbd_phone_symbols.xml
index 4ef8e96a12..641464dbe4 100644
--- a/java/res/xml-sw768dp-land/kbd_phone_shift.xml
+++ b/java/res/xml-sw768dp-land/kbd_phone_symbols.xml
@@ -23,6 +23,7 @@
     latin:keyboardHorizontalEdgesPadding="10%p"
     latin:keyWidth="13.250%p"
 >
+    <!-- Tablet doesn't have phone symbols keyboard -->
     <include
-        latin:keyboardLayout="@xml/rows_phone_shift" />
+        latin:keyboardLayout="@xml/rows_phone" />
 </Keyboard>
diff --git a/java/res/xml-sw768dp/kbd_phone_shift.xml b/java/res/xml-sw768dp/kbd_phone_symbols.xml
similarity index 88%
rename from java/res/xml-sw768dp/kbd_phone_shift.xml
rename to java/res/xml-sw768dp/kbd_phone_symbols.xml
index a56afcc0ca..e1a359e84d 100644
--- a/java/res/xml-sw768dp/kbd_phone_shift.xml
+++ b/java/res/xml-sw768dp/kbd_phone_symbols.xml
@@ -22,6 +22,7 @@
     xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
     latin:keyWidth="13.250%p"
 >
+    <!-- Tablet doesn't have phone symbols keyboard -->
     <include
-        latin:keyboardLayout="@xml/rows_phone_shift" />
+        latin:keyboardLayout="@xml/rows_phone" />
 </Keyboard>
diff --git a/java/res/xml-sw768dp/rows_phone.xml b/java/res/xml-sw768dp/rows_phone.xml
index da90895d03..789c02c425 100644
--- a/java/res/xml-sw768dp/rows_phone.xml
+++ b/java/res/xml-sw768dp/rows_phone.xml
@@ -33,12 +33,15 @@
         <Key
             latin:keyLabel="-"
             latin:keyStyle="numKeyStyle"
-            latin:keyXPos="20.400%p"
+            latin:keyXPos="13.829%p"
             latin:keyWidth="8.047%p" />
         <Key
             latin:keyLabel="+"
             latin:keyStyle="numKeyStyle"
             latin:keyWidth="8.047%p" />
+        <Key
+            latin:keyStyle="numPauseKeyStyle"
+            latin:keyWidth="8.047%p" />
         <Key
             latin:keyStyle="num1KeyStyle"
             latin:keyXPos="43.125%p" />
@@ -52,18 +55,21 @@
             latin:keyWidth="fillRight" />
     </Row>
     <Row>
-        <Key
-            latin:keyStyle="toMoreSymbolKeyStyle"
-            latin:keyWidth="11.172%p" />
+        <!-- Note: This Spacer prevents the below key from being marked as a left edge key. -->
+        <Spacer
+            latin:keyWidth="13.829%p" />
         <Key
             latin:keyLabel=","
             latin:keyStyle="numKeyStyle"
-            latin:keyXPos="20.400%p"
+            latin:keyXPos="13.829%p"
             latin:keyWidth="8.047%p" />
         <Key
             latin:keyLabel="."
             latin:keyStyle="numKeyStyle"
             latin:keyWidth="8.047%p" />
+        <Key
+            latin:keyStyle="numWaitKeyStyle"
+            latin:keyWidth="8.047%p" />
         <Key
             latin:keyStyle="num4KeyStyle"
             latin:keyXPos="43.125%p" />
@@ -79,7 +85,7 @@
     <Row>
         <!-- Note: This Spacer prevents the below key from being marked as a left edge key. -->
         <Spacer
-            latin:keyWidth="20.400%p" />
+            latin:keyWidth="13.829%p" />
         <Key
             latin:keyLabel="("
             latin:keyStyle="numKeyStyle"
@@ -88,6 +94,10 @@
             latin:keyLabel=")"
             latin:keyStyle="numKeyStyle"
             latin:keyWidth="8.047%p" />
+        <Key
+            latin:keyLabel="N"
+            latin:keyStyle="numKeyStyle"
+            latin:keyWidth="8.047%p" />
         <Key
             latin:keyStyle="num7KeyStyle"
             latin:keyXPos="43.125%p" />
@@ -98,7 +108,7 @@
         <!-- Note: This Spacer prevents the above key from being marked as a right edge key. -->
         <Spacer
             latin:keyWidth="0%p" />
-        </Row>
+    </Row>
     <Row>
         <switch>
             <case latin:hasSettingsKey="true">
@@ -114,8 +124,8 @@
         </switch>
         <Key
             latin:keyStyle="nonSpecialBackgroundSpaceKeyStyle"
-            latin:keyXPos="20.400%p"
-            latin:keyWidth="16.084%p" />
+            latin:keyXPos="13.829%p"
+            latin:keyWidth="24.140%p" />
         <Key
             latin:keyStyle="numStarKeyStyle"
             latin:keyXPos="43.125%p" />
diff --git a/java/res/xml-sw768dp/rows_phone_shift.xml b/java/res/xml-sw768dp/rows_phone_shift.xml
deleted file mode 100644
index 5861998aef..0000000000
--- a/java/res/xml-sw768dp/rows_phone_shift.xml
+++ /dev/null
@@ -1,153 +0,0 @@
-<?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"
->
-    <include
-        latin:keyboardLayout="@xml/key_styles_common" />
-    <include
-        latin:keyboardLayout="@xml/key_styles_number" />
-    <Row>
-        <Key
-            latin:keyStyle="numTabKeyStyle"
-            latin:keyLabelFlags="alignLeft"
-            latin:keyWidth="11.172%p" />
-        <Key
-            latin:keyLabel="-"
-            latin:keyStyle="numKeyStyle"
-            latin:keyXPos="13.829%p"
-            latin:keyWidth="8.047%p" />
-        <Key
-            latin:keyLabel="+"
-            latin:keyStyle="numKeyStyle"
-            latin:keyWidth="8.047%p" />
-        <Key
-            latin:keyStyle="numPauseKeyStyle"
-            latin:keyWidth="8.047%p" />
-        <Key
-            latin:keyStyle="num1KeyStyle"
-            latin:keyXPos="43.125%p" />
-        <Key
-            latin:keyStyle="num2KeyStyle" />
-        <Key
-            latin:keyStyle="num3KeyStyle" />
-        <Key
-            latin:keyStyle="deleteKeyStyle"
-            latin:keyXPos="-11.172%p"
-            latin:keyWidth="fillRight" />
-    </Row>
-    <Row>
-        <Key
-            latin:keyStyle="backFromMoreSymbolKeyStyle"
-            latin:keyWidth="11.172%p" />
-        <Key
-            latin:keyLabel=","
-            latin:keyStyle="numKeyStyle"
-            latin:keyXPos="13.829%p"
-            latin:keyWidth="8.047%p" />
-        <Key
-            latin:keyLabel="."
-            latin:keyStyle="numKeyStyle"
-            latin:keyWidth="8.047%p" />
-        <Key
-            latin:keyStyle="numWaitKeyStyle"
-            latin:keyWidth="8.047%p" />
-        <Key
-            latin:keyStyle="num4KeyStyle"
-            latin:keyXPos="43.125%p" />
-        <Key
-            latin:keyStyle="num5KeyStyle" />
-        <Key
-            latin:keyStyle="num6KeyStyle" />
-        <Key
-            latin:keyStyle="returnKeyStyle"
-            latin:keyXPos="-11.172%p"
-            latin:keyWidth="fillRight" />
-    </Row>
-    <Row>
-        <!-- Note: This Spacer prevents the below key from being marked as a left edge key. -->
-        <Spacer
-            latin:keyWidth="13.829%p" />
-        <Key
-            latin:keyLabel="("
-            latin:keyStyle="numKeyStyle"
-            latin:keyWidth="8.047%p" />
-        <Key
-            latin:keyLabel=")"
-            latin:keyStyle="numKeyStyle"
-            latin:keyWidth="8.047%p" />
-        <Key
-            latin:keyLabel="N"
-            latin:keyStyle="numKeyStyle"
-            latin:keyWidth="8.047%p" />
-        <Key
-            latin:keyStyle="num7KeyStyle"
-            latin:keyXPos="43.125%p" />
-        <Key
-            latin:keyStyle="num8KeyStyle" />
-        <Key
-            latin:keyStyle="num9KeyStyle" />
-        <!-- Note: This Spacer prevents the above key from being marked as a right edge key. -->
-        <Spacer
-            latin:keyWidth="0%p" />
-    </Row>
-    <Row>
-        <switch>
-            <case latin:hasSettingsKey="true">
-                <Key
-                    latin:keyStyle="settingsKeyStyle"
-                    latin:keyWidth="8.047%p" />
-            </case>
-            <default>
-                <!-- Note: This Spacer prevents the below key from being marked as a left edge key. -->
-                <Spacer
-                    latin:keyWidth="8.047%p" />
-            </default>
-        </switch>
-        <Key
-            latin:keyStyle="nonSpecialBackgroundSpaceKeyStyle"
-            latin:keyXPos="13.829%p"
-            latin:keyWidth="24.140%p" />
-        <Key
-            latin:keyStyle="numStarKeyStyle"
-            latin:keyXPos="43.125%p" />
-        <Key
-            latin:keyStyle="num0KeyStyle" />
-        <Key
-            latin:keyLabel="#"
-            latin:keyStyle="numKeyStyle" />
-        <switch>
-            <case
-                latin:shortcutKeyEnabled="true"
-            >
-                <Key
-                    latin:keyStyle="shortcutKeyStyle"
-                    latin:keyXPos="-8.047%p"
-                    latin:keyWidth="fillRight" />
-            </case>
-            <default>
-                <!-- Note: This Spacer prevents the above key from being marked as a right edge key. -->
-                <Spacer
-                    latin:keyWidth="0%p" />
-            </default>
-        </switch>
-    </Row>
-</merge>
diff --git a/java/res/xml-tr/keyboard_set.xml b/java/res/xml-tr/keyboard_set.xml
index 3c429585f7..da79758ecf 100644
--- a/java/res/xml-tr/keyboard_set.xml
+++ b/java/res/xml-tr/keyboard_set.xml
@@ -34,8 +34,8 @@
         latin:elementName="phone"
         latin:elementKeyboard="@xml/kbd_phone" />
     <Element
-        latin:elementName="phoneShifted"
-        latin:elementKeyboard="@xml/kbd_phone_shift" />
+        latin:elementName="phoneSymbols"
+        latin:elementKeyboard="@xml/kbd_phone_symbols" />
     <Element
         latin:elementName="number"
         latin:elementKeyboard="@xml/kbd_number" />
diff --git a/java/res/xml-uk/keyboard_set.xml b/java/res/xml-uk/keyboard_set.xml
index 300eea2267..8eb9eccb78 100644
--- a/java/res/xml-uk/keyboard_set.xml
+++ b/java/res/xml-uk/keyboard_set.xml
@@ -34,8 +34,8 @@
         latin:elementName="phone"
         latin:elementKeyboard="@xml/kbd_phone" />
     <Element
-        latin:elementName="phoneShifted"
-        latin:elementKeyboard="@xml/kbd_phone_shift" />
+        latin:elementName="phoneSymbols"
+        latin:elementKeyboard="@xml/kbd_phone_symbols" />
     <Element
         latin:elementName="number"
         latin:elementKeyboard="@xml/kbd_number" />
diff --git a/java/res/xml-vi/keyboard_set.xml b/java/res/xml-vi/keyboard_set.xml
index 0b92c94c13..6d38eb1b4f 100644
--- a/java/res/xml-vi/keyboard_set.xml
+++ b/java/res/xml-vi/keyboard_set.xml
@@ -34,8 +34,8 @@
         latin:elementName="phone"
         latin:elementKeyboard="@xml/kbd_phone" />
     <Element
-        latin:elementName="phoneShifted"
-        latin:elementKeyboard="@xml/kbd_phone_shift" />
+        latin:elementName="phoneSymbols"
+        latin:elementKeyboard="@xml/kbd_phone_symbols" />
     <Element
         latin:elementName="number"
         latin:elementKeyboard="@xml/kbd_number" />
diff --git a/java/res/xml/kbd_phone_shift.xml b/java/res/xml/kbd_phone_symbols.xml
similarity index 93%
rename from java/res/xml/kbd_phone_shift.xml
rename to java/res/xml/kbd_phone_symbols.xml
index 104f33f5b3..7f59a855aa 100644
--- a/java/res/xml/kbd_phone_shift.xml
+++ b/java/res/xml/kbd_phone_symbols.xml
@@ -23,5 +23,5 @@
     latin:keyWidth="26.67%p"
 >
     <include
-        latin:keyboardLayout="@xml/rows_phone_shift" />
+        latin:keyboardLayout="@xml/rows_phone_symbols" />
 </Keyboard>
diff --git a/java/res/xml/key_styles_common.xml b/java/res/xml/key_styles_common.xml
index 8d01e0fb5b..14ee19ee95 100644
--- a/java/res/xml/key_styles_common.xml
+++ b/java/res/xml/key_styles_common.xml
@@ -180,7 +180,7 @@
     <key-style
         latin:styleName="spaceKeyStyle"
         latin:code="@integer/key_space"
-        latin:keyActionFlags="noKeyPreview"
+        latin:keyActionFlags="noKeyPreview|enableLongPress"
         latin:backgroundType="functional" />
     <key-style
         latin:styleName="shortcutKeyStyle"
diff --git a/java/res/xml/key_styles_number.xml b/java/res/xml/key_styles_number.xml
index 003165da84..7307a1a2bb 100644
--- a/java/res/xml/key_styles_number.xml
+++ b/java/res/xml/key_styles_number.xml
@@ -45,6 +45,7 @@
         latin:styleName="num0KeyStyle"
         latin:code="48"
         latin:keyLabel="0 +"
+        latin:keyActionFlags="enableLongPress"
         latin:parentStyle="numberKeyStyle" />
     <key-style
         latin:styleName="num1KeyStyle"
@@ -95,14 +96,15 @@
         latin:code="42"
         latin:keyLabel="\uff0a"
         latin:parentStyle="numKeyStyle" />
+    <!-- Only for non-tablet device -->
     <key-style
-        latin:styleName="numSwitchToAltKeyStyle"
-        latin:code="@integer/key_shift"
+        latin:styleName="numPhoneToSymbolKeyStyle"
+        latin:code="@integer/key_switch_alpha_symbol"
         latin:keyLabel="@string/label_to_phone_symbols_key"
         latin:parentStyle="numModeKeyStyle" />
     <key-style
-        latin:styleName="numSwitchToNumericKeyStyle"
-        latin:code="@integer/key_shift"
+        latin:styleName="numPhoneToNumericKeyStyle"
+        latin:code="@integer/key_switch_alpha_symbol"
         latin:keyLabel="@string/label_to_phone_numeric_key"
         latin:parentStyle="numModeKeyStyle" />
     <key-style
@@ -125,5 +127,6 @@
         latin:styleName="numSpaceKeyStyle"
         latin:code="@integer/key_space"
         latin:keyIcon="iconSpaceKeyForNumberLayout"
+        latin:keyActionFlags="enableLongPress"
         latin:parentStyle="numKeyBaseStyle" />
 </merge>
diff --git a/java/res/xml/keyboard_set.xml b/java/res/xml/keyboard_set.xml
index ebdd9902eb..1398b137c3 100644
--- a/java/res/xml/keyboard_set.xml
+++ b/java/res/xml/keyboard_set.xml
@@ -34,8 +34,8 @@
         latin:elementName="phone"
         latin:elementKeyboard="@xml/kbd_phone" />
     <Element
-        latin:elementName="phoneShifted"
-        latin:elementKeyboard="@xml/kbd_phone_shift" />
+        latin:elementName="phoneSymbols"
+        latin:elementKeyboard="@xml/kbd_phone_symbols" />
     <Element
         latin:elementName="number"
         latin:elementKeyboard="@xml/kbd_number" />
diff --git a/java/res/xml/rows_phone.xml b/java/res/xml/rows_phone.xml
index 94d0f7273f..18e4c9d3e9 100644
--- a/java/res/xml/rows_phone.xml
+++ b/java/res/xml/rows_phone.xml
@@ -62,7 +62,7 @@
     </Row>
     <Row>
         <Key
-            latin:keyStyle="numSwitchToAltKeyStyle" />
+            latin:keyStyle="numPhoneToSymbolKeyStyle" />
         <Key
             latin:keyStyle="num0KeyStyle" />
         <Key
diff --git a/java/res/xml/rows_phone_shift.xml b/java/res/xml/rows_phone_symbols.xml
similarity index 97%
rename from java/res/xml/rows_phone_shift.xml
rename to java/res/xml/rows_phone_symbols.xml
index 1005206290..dfa1349466 100644
--- a/java/res/xml/rows_phone_shift.xml
+++ b/java/res/xml/rows_phone_symbols.xml
@@ -71,7 +71,7 @@
     </Row>
     <Row>
         <Key
-            latin:keyStyle="numSwitchToNumericKeyStyle" />
+            latin:keyStyle="numPhoneToNumericKeyStyle" />
         <Key
             latin:keyLabel="+"
             latin:keyStyle="numKeyStyle" />
diff --git a/java/src/com/android/inputmethod/keyboard/Key.java b/java/src/com/android/inputmethod/keyboard/Key.java
index d4419aeaff..3cfecf5eff 100644
--- a/java/src/com/android/inputmethod/keyboard/Key.java
+++ b/java/src/com/android/inputmethod/keyboard/Key.java
@@ -120,6 +120,7 @@ public class Key {
     private static final int ACTION_FLAGS_IS_REPEATABLE = 0x01;
     private static final int ACTION_FLAGS_NO_KEY_PREVIEW = 0x02;
     private static final int ACTION_FLAGS_ALT_CODE_WHILE_TYPING = 0x04;
+    private static final int ACTION_FLAGS_ENABLE_LONG_PRESS = 0x08;
 
     private final int mHashCode;
 
@@ -265,7 +266,6 @@ public class Key {
 
         mBackgroundType = style.getInt(keyAttr,
                 R.styleable.Keyboard_Key_backgroundType, BACKGROUND_TYPE_NORMAL);
-        mActionFlags = style.getFlag(keyAttr, R.styleable.Keyboard_Key_keyActionFlags, 0);
 
         final KeyboardIconsSet iconsSet = params.mIconsSet;
         mVisualInsetsLeft = (int) Keyboard.Builder.getDimensionOrFraction(keyAttr,
@@ -282,17 +282,19 @@ public class Key {
 
         mLabelFlags = style.getFlag(keyAttr, R.styleable.Keyboard_Key_keyLabelFlags, 0);
         final boolean preserveCase = (mLabelFlags & LABEL_FLAGS_PRESERVE_CASE) != 0;
-
+        int actionFlags = style.getFlag(keyAttr, R.styleable.Keyboard_Key_keyActionFlags, 0);
         final String[] additionalMoreKeys = style.getStringArray(
                 keyAttr, R.styleable.Keyboard_Key_additionalMoreKeys);
         final String[] moreKeys = MoreKeySpecParser.insertAddtionalMoreKeys(style.getStringArray(
                 keyAttr, R.styleable.Keyboard_Key_moreKeys), additionalMoreKeys);
         if (moreKeys != null) {
+            actionFlags |= ACTION_FLAGS_ENABLE_LONG_PRESS;
             for (int i = 0; i < moreKeys.length; i++) {
                 moreKeys[i] = adjustCaseOfStringForKeyboardId(
                         moreKeys[i], preserveCase, params.mId);
             }
         }
+        mActionFlags = actionFlags;
         mMoreKeys = moreKeys;
         mMaxMoreKeysColumn = style.getInt(keyAttr,
                 R.styleable.Keyboard_Key_maxMoreKeysColumn, params.mMaxMiniKeyboardColumn);
@@ -420,7 +422,7 @@ public class Key {
     @Override
     public String toString() {
         String top = Keyboard.printableCode(mCode);
-        if (mLabel != null && mLabel.length() != 1) {
+        if (mLabel != null && mLabel.codePointCount(0, mLabel.length()) != 1) {
             top += "/\"" + mLabel + '"';
         }
         return String.format("%s %d,%d", top, mX, mY);
@@ -466,6 +468,12 @@ public class Key {
         return (mActionFlags & ACTION_FLAGS_ALT_CODE_WHILE_TYPING) != 0;
     }
 
+    public boolean isLongPressEnabled() {
+        // We need not start long press timer on the key which has activated shifted letter.
+        return (mActionFlags & ACTION_FLAGS_ENABLE_LONG_PRESS) != 0
+                && (mLabelFlags & LABEL_FLAGS_SHIFTED_LETTER_ACTIVATED) == 0;
+    }
+
     public Typeface selectTypeface(Typeface defaultTypeface) {
         // TODO: Handle "bold" here too?
         if ((mLabelFlags & LABEL_FLAGS_FONT_NORMAL) != 0) {
diff --git a/java/src/com/android/inputmethod/keyboard/Keyboard.java b/java/src/com/android/inputmethod/keyboard/Keyboard.java
index 8832d8fd1d..1e1f439d4d 100644
--- a/java/src/com/android/inputmethod/keyboard/Keyboard.java
+++ b/java/src/com/android/inputmethod/keyboard/Keyboard.java
@@ -92,7 +92,6 @@ public class Keyboard {
      */
     public static final int CODE_SHIFT = -1;
     public static final int CODE_SWITCH_ALPHA_SYMBOL = -2;
-    public static final int CODE_CAPSLOCK = -3;
     public static final int CODE_OUTPUT_TEXT = -4;
     public static final int CODE_DELETE = -5;
     public static final int CODE_SETTINGS = -6;
@@ -368,9 +367,9 @@ public class Keyboard {
         switch (code) {
         case CODE_SHIFT: return "shift";
         case CODE_SWITCH_ALPHA_SYMBOL: return "symbol";
-        case CODE_CAPSLOCK: return "capslock";
         case CODE_OUTPUT_TEXT: return "text";
         case CODE_DELETE: return "delete";
+        case CODE_SETTINGS: return "settings";
         case CODE_SHORTCUT: return "shortcut";
         case CODE_UNSPECIFIED: return "unspec";
         case CODE_TAB: return "tab";
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardId.java b/java/src/com/android/inputmethod/keyboard/KeyboardId.java
index 997b952de3..0837e17da2 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardId.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardId.java
@@ -46,7 +46,7 @@ public class KeyboardId {
     public static final int ELEMENT_SYMBOLS = 5;
     public static final int ELEMENT_SYMBOLS_SHIFTED = 6;
     public static final int ELEMENT_PHONE = 7;
-    public static final int ELEMENT_PHONE_SHIFTED = 8;
+    public static final int ELEMENT_PHONE_SYMBOLS = 8;
     public static final int ELEMENT_NUMBER = 9;
 
     private static final int F2KEY_MODE_NONE = 0;
@@ -145,11 +145,11 @@ public class KeyboardId {
     }
 
     public boolean isPhoneKeyboard() {
-        return mElementId == ELEMENT_PHONE || mElementId == ELEMENT_PHONE_SHIFTED;
+        return mElementId == ELEMENT_PHONE || mElementId == ELEMENT_PHONE_SYMBOLS;
     }
 
     public boolean isPhoneShiftKeyboard() {
-        return mElementId == ELEMENT_PHONE_SHIFTED;
+        return mElementId == ELEMENT_PHONE_SYMBOLS;
     }
 
     public boolean navigateAction() {
@@ -237,7 +237,7 @@ public class KeyboardId {
         case ELEMENT_SYMBOLS: return "symbols";
         case ELEMENT_SYMBOLS_SHIFTED: return "symbolsShifted";
         case ELEMENT_PHONE: return "phone";
-        case ELEMENT_PHONE_SHIFTED: return "phoneShifted";
+        case ELEMENT_PHONE_SYMBOLS: return "phoneSymbols";
         case ELEMENT_NUMBER: return "number";
         default: return null;
         }
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardSet.java b/java/src/com/android/inputmethod/keyboard/KeyboardSet.java
index d35948bad0..664e7656e9 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardSet.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardSet.java
@@ -119,9 +119,11 @@ public class KeyboardSet {
         final int keyboardSetElementId;
         switch (mParams.mMode) {
         case KeyboardId.MODE_PHONE:
-            keyboardSetElementId =
-                    (baseKeyboardSetElementId == KeyboardId.ELEMENT_ALPHABET_MANUAL_SHIFTED)
-                    ? KeyboardId.ELEMENT_PHONE_SHIFTED : KeyboardId.ELEMENT_PHONE;
+            if (baseKeyboardSetElementId == KeyboardId.ELEMENT_SYMBOLS) {
+                keyboardSetElementId = KeyboardId.ELEMENT_PHONE_SYMBOLS;
+            } else {
+                keyboardSetElementId = KeyboardId.ELEMENT_PHONE;
+            }
             break;
         case KeyboardId.MODE_NUMBER:
             keyboardSetElementId = KeyboardId.ELEMENT_NUMBER;
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
index 951bcdbfdd..5ba560d727 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
@@ -194,6 +194,9 @@ public class KeyboardSwitcher implements KeyboardState.SwitchActions,
     }
 
     public void onPressKey(int code) {
+        if (isVibrateAndSoundFeedbackRequired()) {
+            mInputMethodService.hapticAndAudioFeedback(code);
+        }
         mState.onPressKey(code);
     }
 
@@ -271,11 +274,31 @@ public class KeyboardSwitcher implements KeyboardState.SwitchActions,
                 ? keyboardView.getTimerProxy().isInDoubleTapTimeout() : false;
     }
 
+    // Implements {@link KeyboardState.SwitchActions}.
+    @Override
+    public void startLongPressTimer(int code) {
+        final LatinKeyboardView keyboardView = getKeyboardView();
+        if (keyboardView != null) {
+            final TimerProxy timer = keyboardView.getTimerProxy();
+            timer.startLongPressTimer(code);
+        }
+    }
+
+    // Implements {@link KeyboardState.SwitchActions}.
+    @Override
+    public void hapticAndAudioFeedback(int code) {
+        mInputMethodService.hapticAndAudioFeedback(code);
+    }
+
+    public void onLongPressTimeout(int code) {
+        mState.onLongPressTimeout(code);
+    }
+
     public boolean isInMomentarySwitchState() {
         return mState.isInMomentarySwitchState();
     }
 
-    public boolean isVibrateAndSoundFeedbackRequired() {
+    private boolean isVibrateAndSoundFeedbackRequired() {
         return mKeyboardView != null && !mKeyboardView.isInSlidingKeyInput();
     }
 
diff --git a/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java b/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java
index 5aad67d49c..551a50a830 100644
--- a/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java
@@ -117,12 +117,12 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke
         private static final int MSG_DOUBLE_TAP = 3;
         private static final int MSG_KEY_TYPED = 4;
 
-        private final int mKeyRepeatInterval;
+        private final KeyTimerParams mParams;
         private boolean mInKeyRepeat;
 
-        public KeyTimerHandler(LatinKeyboardView outerInstance, int keyRepeatInterval) {
+        public KeyTimerHandler(LatinKeyboardView outerInstance, KeyTimerParams params) {
             super(outerInstance);
-            mKeyRepeatInterval = keyRepeatInterval;
+            mParams = params;
         }
 
         @Override
@@ -132,18 +132,23 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke
             switch (msg.what) {
             case MSG_REPEAT_KEY:
                 tracker.onRepeatKey(tracker.getKey());
-                startKeyRepeatTimer(mKeyRepeatInterval, tracker);
+                startKeyRepeatTimer(tracker);
                 break;
             case MSG_LONGPRESS_KEY:
-                keyboardView.openMiniKeyboardIfRequired(tracker.getKey(), tracker);
+                if (tracker != null) {
+                    keyboardView.openMiniKeyboardIfRequired(tracker.getKey(), tracker);
+                } else {
+                    KeyboardSwitcher.getInstance().onLongPressTimeout(msg.arg1);
+                }
                 break;
             }
         }
 
         @Override
-        public void startKeyRepeatTimer(long delay, PointerTracker tracker) {
+        public void startKeyRepeatTimer(PointerTracker tracker) {
             mInKeyRepeat = true;
-            sendMessageDelayed(obtainMessage(MSG_REPEAT_KEY, tracker), delay);
+            sendMessageDelayed(obtainMessage(MSG_REPEAT_KEY, tracker),
+                    mParams.mKeyRepeatStartTimeout);
         }
 
         public void cancelKeyRepeatTimer() {
@@ -156,9 +161,49 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke
         }
 
         @Override
-        public void startLongPressTimer(long delay, PointerTracker tracker) {
+        public void startLongPressTimer(int code) {
+            cancelLongPressTimer();
+            final int delay;
+            switch (code) {
+            case Keyboard.CODE_SHIFT:
+                delay = mParams.mLongPressKeyTimeout;
+                break;
+            default:
+                delay = 0;
+                break;
+            }
+            if (delay > 0) {
+                sendMessageDelayed(obtainMessage(MSG_LONGPRESS_KEY, code, 0), delay);
+            }
+        }
+
+        @Override
+        public void startLongPressTimer(PointerTracker tracker) {
             cancelLongPressTimer();
-            sendMessageDelayed(obtainMessage(MSG_LONGPRESS_KEY, tracker), delay);
+            if (tracker != null) {
+                final Key key = tracker.getKey();
+                final int delay;
+                switch (key.mCode) {
+                case Keyboard.CODE_SHIFT:
+                    delay = mParams.mLongPressShiftKeyTimeout;
+                    break;
+                case Keyboard.CODE_SPACE:
+                    delay = mParams.mLongPressSpaceKeyTimeout;
+                    break;
+                default:
+                    if (KeyboardSwitcher.getInstance().isInMomentarySwitchState()) {
+                        // We use longer timeout for sliding finger input started from the symbols
+                        // mode key.
+                        delay = mParams.mLongPressKeyTimeout * 3;
+                    } else {
+                        delay = mParams.mLongPressKeyTimeout;
+                    }
+                    break;
+                }
+                if (delay > 0) {
+                    sendMessageDelayed(obtainMessage(MSG_LONGPRESS_KEY, tracker), delay);
+                }
+            }
         }
 
         @Override
@@ -167,9 +212,9 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke
         }
 
         @Override
-        public void startKeyTypedTimer(long delay) {
+        public void startKeyTypedTimer() {
             removeMessages(MSG_KEY_TYPED);
-            sendMessageDelayed(obtainMessage(MSG_KEY_TYPED), delay);
+            sendMessageDelayed(obtainMessage(MSG_KEY_TYPED), mParams.mIgnoreSpecialKeyTimeout);
         }
 
         @Override
@@ -201,11 +246,6 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke
 
     public static class PointerTrackerParams {
         public final boolean mSlidingKeyInputEnabled;
-        public final int mKeyRepeatStartTimeout;
-        public final int mLongPressKeyTimeout;
-        public final int mLongPressShiftKeyTimeout;
-        public final int mLongPressSpaceKeyTimeout;
-        public final int mIgnoreSpecialKeyTimeout;
         public final int mTouchNoiseThresholdTime;
         public final float mTouchNoiseThresholdDistance;
 
@@ -213,11 +253,6 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke
 
         private PointerTrackerParams() {
             mSlidingKeyInputEnabled = false;
-            mKeyRepeatStartTimeout = 0;
-            mLongPressKeyTimeout = 0;
-            mLongPressShiftKeyTimeout = 0;
-            mLongPressSpaceKeyTimeout = 0;
-            mIgnoreSpecialKeyTimeout = 0;
             mTouchNoiseThresholdTime =0;
             mTouchNoiseThresholdDistance = 0;
         }
@@ -225,8 +260,35 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke
         public PointerTrackerParams(TypedArray latinKeyboardViewAttr) {
             mSlidingKeyInputEnabled = latinKeyboardViewAttr.getBoolean(
                     R.styleable.LatinKeyboardView_slidingKeyInputEnable, false);
+            mTouchNoiseThresholdTime = latinKeyboardViewAttr.getInt(
+                    R.styleable.LatinKeyboardView_touchNoiseThresholdTime, 0);
+            mTouchNoiseThresholdDistance = latinKeyboardViewAttr.getDimension(
+                    R.styleable.LatinKeyboardView_touchNoiseThresholdDistance, 0);
+        }
+    }
+
+    static class KeyTimerParams {
+        public final int mKeyRepeatStartTimeout;
+        public final int mKeyRepeatInterval;
+        public final int mLongPressKeyTimeout;
+        public final int mLongPressShiftKeyTimeout;
+        public final int mLongPressSpaceKeyTimeout;
+        public final int mIgnoreSpecialKeyTimeout;
+
+        KeyTimerParams() {
+            mKeyRepeatStartTimeout = 0;
+            mKeyRepeatInterval = 0;
+            mLongPressKeyTimeout = 0;
+            mLongPressShiftKeyTimeout = 0;
+            mLongPressSpaceKeyTimeout = 0;
+            mIgnoreSpecialKeyTimeout = 0;
+        }
+
+        public KeyTimerParams(TypedArray latinKeyboardViewAttr) {
             mKeyRepeatStartTimeout = latinKeyboardViewAttr.getInt(
                     R.styleable.LatinKeyboardView_keyRepeatStartTimeout, 0);
+            mKeyRepeatInterval = latinKeyboardViewAttr.getInt(
+                    R.styleable.LatinKeyboardView_keyRepeatInterval, 0);
             mLongPressKeyTimeout = latinKeyboardViewAttr.getInt(
                     R.styleable.LatinKeyboardView_longPressKeyTimeout, 0);
             mLongPressShiftKeyTimeout = latinKeyboardViewAttr.getInt(
@@ -235,10 +297,6 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke
                     R.styleable.LatinKeyboardView_longPressSpaceKeyTimeout, 0);
             mIgnoreSpecialKeyTimeout = latinKeyboardViewAttr.getInt(
                     R.styleable.LatinKeyboardView_ignoreSpecialKeyTimeout, 0);
-            mTouchNoiseThresholdTime = latinKeyboardViewAttr.getInt(
-                    R.styleable.LatinKeyboardView_touchNoiseThresholdTime, 0);
-            mTouchNoiseThresholdDistance = latinKeyboardViewAttr.getDimension(
-                    R.styleable.LatinKeyboardView_touchNoiseThresholdDistance, 0);
         }
     }
 
@@ -254,7 +312,7 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke
         mHasDistinctMultitouch = context.getPackageManager()
                 .hasSystemFeature(PackageManager.FEATURE_TOUCHSCREEN_MULTITOUCH_DISTINCT);
 
-        PointerTracker.init(mHasDistinctMultitouch, getContext());
+        PointerTracker.init(mHasDistinctMultitouch);
 
         final TypedArray a = context.obtainStyledAttributes(
                 attrs, R.styleable.LatinKeyboardView, defStyle, R.style.LatinKeyboardView);
@@ -268,16 +326,14 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke
         mSpacebarTextShadowColor = a.getColor(
                 R.styleable.LatinKeyboardView_spacebarTextShadowColor, 0);
 
+        final KeyTimerParams keyTimerParams = new KeyTimerParams(a);
         mPointerTrackerParams = new PointerTrackerParams(a);
-        mIsSpacebarTriggeringPopupByLongPress = (
-                mPointerTrackerParams.mLongPressSpaceKeyTimeout > 0);
+        mIsSpacebarTriggeringPopupByLongPress = (keyTimerParams.mLongPressSpaceKeyTimeout > 0);
 
         final float keyHysteresisDistance = a.getDimension(
                 R.styleable.LatinKeyboardView_keyHysteresisDistance, 0);
         mKeyDetector = new KeyDetector(keyHysteresisDistance);
-        final int keyRepeatInterval = a.getInt(
-                R.styleable.LatinKeyboardView_keyRepeatInterval, 0);
-        mKeyTimerHandler = new KeyTimerHandler(this, keyRepeatInterval);
+        mKeyTimerHandler = new KeyTimerHandler(this, keyTimerParams);
         mConfigShowMiniKeyboardAtTouchedPoint = a.getBoolean(
                 R.styleable.LatinKeyboardView_showMiniKeyboardAtTouchedPoint, false);
         a.recycle();
@@ -425,12 +481,7 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke
             // Long pressing on 0 in phone number keypad gives you a '+'.
             invokeCodeInput(Keyboard.CODE_PLUS);
             invokeReleaseKey(primaryCode);
-            return true;
-        }
-        if (primaryCode == Keyboard.CODE_SHIFT && keyboard.mId.isAlphabetKeyboard()) {
-            tracker.onLongPressed();
-            invokeCodeInput(Keyboard.CODE_CAPSLOCK);
-            invokeReleaseKey(primaryCode);
+            KeyboardSwitcher.getInstance().hapticAndAudioFeedback(primaryCode);
             return true;
         }
         if (primaryCode == Keyboard.CODE_SPACE) {
diff --git a/java/src/com/android/inputmethod/keyboard/PointerTracker.java b/java/src/com/android/inputmethod/keyboard/PointerTracker.java
index fc92a24a60..110f7f6aed 100644
--- a/java/src/com/android/inputmethod/keyboard/PointerTracker.java
+++ b/java/src/com/android/inputmethod/keyboard/PointerTracker.java
@@ -16,7 +16,6 @@
 
 package com.android.inputmethod.keyboard;
 
-import android.content.Context;
 import android.os.SystemClock;
 import android.util.Log;
 import android.view.MotionEvent;
@@ -71,10 +70,11 @@ public class PointerTracker {
     }
 
     public interface TimerProxy {
-        public void startKeyTypedTimer(long delay);
+        public void startKeyTypedTimer();
         public boolean isTyping();
-        public void startKeyRepeatTimer(long delay, PointerTracker tracker);
-        public void startLongPressTimer(long delay, PointerTracker tracker);
+        public void startKeyRepeatTimer(PointerTracker tracker);
+        public void startLongPressTimer(PointerTracker tracker);
+        public void startLongPressTimer(int code);
         public void cancelLongPressTimer();
         public void startDoubleTapTimer();
         public boolean isInDoubleTapTimeout();
@@ -82,13 +82,15 @@ public class PointerTracker {
 
         public static class Adapter implements TimerProxy {
             @Override
-            public void startKeyTypedTimer(long delay) {}
+            public void startKeyTypedTimer() {}
             @Override
             public boolean isTyping() { return false; }
             @Override
-            public void startKeyRepeatTimer(long delay, PointerTracker tracker) {}
+            public void startKeyRepeatTimer(PointerTracker tracker) {}
             @Override
-            public void startLongPressTimer(long delay, PointerTracker tracker) {}
+            public void startLongPressTimer(PointerTracker tracker) {}
+            @Override
+            public void startLongPressTimer(int code) {}
             @Override
             public void cancelLongPressTimer() {}
             @Override
@@ -159,7 +161,7 @@ public class PointerTracker {
     private static final KeyboardActionListener EMPTY_LISTENER =
             new KeyboardActionListener.Adapter();
 
-    public static void init(boolean hasDistinctMultitouch, Context context) {
+    public static void init(boolean hasDistinctMultitouch) {
         if (hasDistinctMultitouch) {
             sPointerTrackerQueue = new PointerTrackerQueue();
         } else {
@@ -269,7 +271,7 @@ public class PointerTracker {
                 mListener.onCodeInput(code, keyCodes, x, y);
             }
             if (!key.altCodeWhileTyping() && !key.isModifier()) {
-                mTimerProxy.startKeyTypedTimer(sParams.mIgnoreSpecialKeyTimeout);
+                mTimerProxy.startKeyTypedTimer();
             }
         }
     }
@@ -674,7 +676,7 @@ public class PointerTracker {
     private void startRepeatKey(Key key) {
         if (key != null && key.isRepeatable()) {
             onRepeatKey(key);
-            mTimerProxy.startKeyRepeatTimer(sParams.mKeyRepeatStartTimeout, this);
+            mTimerProxy.startKeyRepeatTimer(this);
             mIsRepeatableKey = true;
         } else {
             mIsRepeatableKey = false;
@@ -702,24 +704,8 @@ public class PointerTracker {
     }
 
     private void startLongPressTimer(Key key) {
-        if (key == null) return;
-        if (key.mCode == Keyboard.CODE_SHIFT) {
-            if (sParams.mLongPressShiftKeyTimeout > 0) {
-                mTimerProxy.startLongPressTimer(sParams.mLongPressShiftKeyTimeout, this);
-            }
-        } else if (key.mCode == Keyboard.CODE_SPACE) {
-            if (sParams.mLongPressSpaceKeyTimeout > 0) {
-                mTimerProxy.startLongPressTimer(sParams.mLongPressSpaceKeyTimeout, this);
-            }
-        } else if (key.hasShiftedLetterHint() && mKeyboard.isManualShifted()) {
-            // We need not start long press timer on the key which has manual temporary upper case
-            // code defined and the keyboard is in manual temporary upper case mode.
-            return;
-        } else if (sKeyboardSwitcher.isInMomentarySwitchState()) {
-            // We use longer timeout for sliding finger input started from the symbols mode key.
-            mTimerProxy.startLongPressTimer(sParams.mLongPressKeyTimeout * 3, this);
-        } else {
-            mTimerProxy.startLongPressTimer(sParams.mLongPressKeyTimeout, this);
+        if (key != null && key.isLongPressEnabled()) {
+            mTimerProxy.startLongPressTimer(this);
         }
     }
 
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java
index 1de83866f3..cb8b4f05ce 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java
@@ -29,7 +29,7 @@ import com.android.inputmethod.keyboard.Keyboard;
  * The input events are {@link #onLoadKeyboard(String)}, {@link #onSaveKeyboardState()},
  * {@link #onPressKey(int)}, {@link #onReleaseKey(int, boolean)},
  * {@link #onCodeInput(int, boolean, boolean)}, {@link #onCancelInput(boolean)},
- * {@link #onUpdateShiftState(boolean)}.
+ * {@link #onUpdateShiftState(boolean)}, {@link #onLongPressTimeout(int)}.
  *
  * The actions are {@link SwitchActions}'s methods.
  */
@@ -54,6 +54,8 @@ public class KeyboardState {
 
         public void startDoubleTapTimer();
         public boolean isInDoubleTapTimeout();
+        public void startLongPressTimer(int code);
+        public void hapticAndAudioFeedback(int code);
     }
 
     private final SwitchActions mSwitchActions;
@@ -335,6 +337,24 @@ public class KeyboardState {
         mSymbolKeyState.onRelease();
     }
 
+    public void onLongPressTimeout(int code) {
+        if (DEBUG_EVENT) {
+            Log.d(TAG, "onLongPressTimeout: code=" + Keyboard.printableCode(code) + " " + this);
+        }
+        if (mIsAlphabetMode && code == Keyboard.CODE_SHIFT) {
+            if (mAlphabetShiftState.isShiftLocked()) {
+                setShiftLocked(false);
+                // Shift key is long pressed while shift locked state, we will toggle back to normal
+                // state. And mark as if shift key is released.
+                mShiftKeyState.onRelease();
+            } else {
+                // Shift key is long pressed while shift unloked state.
+                setShiftLocked(true);
+            }
+            mSwitchActions.hapticAndAudioFeedback(code);
+        }
+    }
+
     public void onUpdateShiftState(boolean autoCaps) {
         if (DEBUG_EVENT) {
             Log.d(TAG, "onUpdateShiftState: autoCaps=" + autoCaps + " " + this);
@@ -370,23 +390,27 @@ public class KeyboardState {
                     // Shift key has been double tapped while in normal state. This is the second
                     // tap to disable shift locked state, so just ignore this.
                 }
-            } else if (mAlphabetShiftState.isShiftLocked()) {
-                // Shift key is pressed while shift locked state, we will treat this state as
-                // shift lock shifted state and mark as if shift key pressed while normal state.
-                setShifted(SHIFT_LOCK_SHIFTED);
-                mShiftKeyState.onPress();
-            } else if (mAlphabetShiftState.isAutomaticShifted()) {
-                // Shift key is pressed while automatic shifted, we have to move to manual shifted.
-                setShifted(MANUAL_SHIFT);
-                mShiftKeyState.onPress();
-            } else if (mAlphabetShiftState.isShiftedOrShiftLocked()) {
-                // In manual shifted state, we just record shift key has been pressing while
-                // shifted state.
-                mShiftKeyState.onPressOnShifted();
             } else {
-                // In base layout, chording or manual shifted mode is started.
-                setShifted(MANUAL_SHIFT);
-                mShiftKeyState.onPress();
+                if (mAlphabetShiftState.isShiftLocked()) {
+                    // Shift key is pressed while shift locked state, we will treat this state as
+                    // shift lock shifted state and mark as if shift key pressed while normal state.
+                    setShifted(SHIFT_LOCK_SHIFTED);
+                    mShiftKeyState.onPress();
+                } else if (mAlphabetShiftState.isAutomaticShifted()) {
+                    // Shift key is pressed while automatic shifted, we have to move to manual
+                    // shifted.
+                    setShifted(MANUAL_SHIFT);
+                    mShiftKeyState.onPress();
+                } else if (mAlphabetShiftState.isShiftedOrShiftLocked()) {
+                    // In manual shifted state, we just record shift key has been pressing while
+                    // shifted state.
+                    mShiftKeyState.onPressOnShifted();
+                } else {
+                    // In base layout, chording or manual shifted mode is started.
+                    setShifted(MANUAL_SHIFT);
+                    mShiftKeyState.onPress();
+                }
+                mSwitchActions.startLongPressTimer(Keyboard.CODE_SHIFT);
             }
         } else {
             // In symbol mode, just toggle symbol and symbol more keyboard.
@@ -480,18 +504,6 @@ public class KeyboardState {
                     + " autoCaps=" + autoCaps + " " + this);
         }
 
-        if (mIsAlphabetMode && code == Keyboard.CODE_CAPSLOCK) {
-            if (mAlphabetShiftState.isShiftLocked()) {
-                setShiftLocked(false);
-                // Shift key is long pressed while shift locked state, we will toggle back to normal
-                // state. And mark as if shift key is released.
-                mShiftKeyState.onRelease();
-            } else {
-                // Shift key is long pressed while shift unloked state.
-                setShiftLocked(true);
-            }
-        }
-
         switch (mSwitchState) {
         case SWITCH_STATE_MOMENTARY_ALPHA_AND_SYMBOL:
             if (code == Keyboard.CODE_SWITCH_ALPHA_SYMBOL) {
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index 1e7171406e..ef8fd13790 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -1296,10 +1296,6 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
         case Keyboard.CODE_SETTINGS:
             onSettingsKeyPressed();
             break;
-        case Keyboard.CODE_CAPSLOCK:
-            // Caps lock code is handled in KeyboardSwitcher.onCodeInput() below.
-            hapticAndAudioFeedback(primaryCode);
-            break;
         case Keyboard.CODE_SHORTCUT:
             mSubtypeSwitcher.switchToShortcutIME();
             break;
@@ -2294,18 +2290,14 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
         loadSettings();
     }
 
-    private void hapticAndAudioFeedback(int primaryCode) {
+    public void hapticAndAudioFeedback(int primaryCode) {
         vibrate();
         playKeyClick(primaryCode);
     }
 
     @Override
     public void onPressKey(int primaryCode) {
-        final KeyboardSwitcher switcher = mKeyboardSwitcher;
-        if (switcher.isVibrateAndSoundFeedbackRequired()) {
-            hapticAndAudioFeedback(primaryCode);
-        }
-        switcher.onPressKey(primaryCode);
+        mKeyboardSwitcher.onPressKey(primaryCode);
     }
 
     @Override
@@ -2313,7 +2305,6 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
         mKeyboardSwitcher.onReleaseKey(primaryCode, withSliding);
     }
 
-
     // receive ringer mode change and network state change.
     private BroadcastReceiver mReceiver = new BroadcastReceiver() {
         @Override
diff --git a/tests/src/com/android/inputmethod/keyboard/internal/KeyboardStateMultiTouchTests.java b/tests/src/com/android/inputmethod/keyboard/internal/KeyboardStateMultiTouchTests.java
index c6893847f3..e9f37afee7 100644
--- a/tests/src/com/android/inputmethod/keyboard/internal/KeyboardStateMultiTouchTests.java
+++ b/tests/src/com/android/inputmethod/keyboard/internal/KeyboardStateMultiTouchTests.java
@@ -37,7 +37,7 @@ public class KeyboardStateMultiTouchTests extends KeyboardStateTestsBase {
     // Chording input in shift locked.
     public void testChordingShiftLocked() {
         // Long press shift key, enter alphabet shift locked.
-        longPressShiftKey(ALPHABET_MANUAL_SHIFTED, ALPHABET_SHIFT_LOCKED);
+        longPressAndReleaseKey(CODE_SHIFT, ALPHABET_MANUAL_SHIFTED, ALPHABET_SHIFT_LOCKED);
 
         // Press shift key and hold, enter into choring shift state.
         pressKey(CODE_SHIFT, ALPHABET_SHIFT_LOCK_SHIFTED);
@@ -95,7 +95,7 @@ public class KeyboardStateMultiTouchTests extends KeyboardStateTestsBase {
         // Load keyboard
         loadKeyboard(ALPHABET_UNSHIFTED);
         // Long press shift key, enter alphabet shift locked.
-        longPressShiftKey(ALPHABET_MANUAL_SHIFTED, ALPHABET_SHIFT_LOCKED);
+        longPressAndReleaseKey(CODE_SHIFT, ALPHABET_MANUAL_SHIFTED, ALPHABET_SHIFT_LOCKED);
         // Press/release "?123" key, enter into symbols.
         pressAndReleaseKey(CODE_SYMBOL, SYMBOLS_UNSHIFTED, SYMBOLS_UNSHIFTED);
         // Press "ABC" key, enter into chording alphabet shift locked.
@@ -112,7 +112,7 @@ public class KeyboardStateMultiTouchTests extends KeyboardStateTestsBase {
         // Load keyboard
         loadKeyboard(ALPHABET_UNSHIFTED);
         // Long press shift key, enter alphabet shift locked.
-        longPressShiftKey(ALPHABET_MANUAL_SHIFTED, ALPHABET_SHIFT_LOCKED);
+        longPressAndReleaseKey(CODE_SHIFT, ALPHABET_MANUAL_SHIFTED, ALPHABET_SHIFT_LOCKED);
         // Press/release "?123" key, enter into symbols.
         pressAndReleaseKey(CODE_SYMBOL, SYMBOLS_UNSHIFTED, SYMBOLS_UNSHIFTED);
         // Press "=\<" key, enter into symbols shifted chording state.
@@ -170,7 +170,7 @@ public class KeyboardStateMultiTouchTests extends KeyboardStateTestsBase {
         // Load keyboard
         loadKeyboard(ALPHABET_UNSHIFTED);
         // Long press shift key, enter alphabet shift locked.
-        longPressShiftKey(ALPHABET_MANUAL_SHIFTED, ALPHABET_SHIFT_LOCKED);
+        longPressAndReleaseKey(CODE_SHIFT, ALPHABET_MANUAL_SHIFTED, ALPHABET_SHIFT_LOCKED);
         // Press/release "?123" key, enter into symbols.
         pressAndReleaseKey(CODE_SYMBOL, SYMBOLS_UNSHIFTED, SYMBOLS_UNSHIFTED);
         // Press/release "=\<" key, enter symbols shifted.
@@ -189,7 +189,7 @@ public class KeyboardStateMultiTouchTests extends KeyboardStateTestsBase {
         // Load keyboard
         loadKeyboard(ALPHABET_UNSHIFTED);
         // Long press shift key, enter alphabet shift locked.
-        longPressShiftKey(ALPHABET_MANUAL_SHIFTED, ALPHABET_SHIFT_LOCKED);
+        longPressAndReleaseKey(CODE_SHIFT, ALPHABET_MANUAL_SHIFTED, ALPHABET_SHIFT_LOCKED);
         // Press/release "?123" key, enter into symbols.
         pressAndReleaseKey(CODE_SYMBOL, SYMBOLS_UNSHIFTED, SYMBOLS_UNSHIFTED);
         // Press/release "=\<" key, enter symbols shifted.
diff --git a/tests/src/com/android/inputmethod/keyboard/internal/KeyboardStateSingleTouchTests.java b/tests/src/com/android/inputmethod/keyboard/internal/KeyboardStateSingleTouchTests.java
index 55147f613c..8c53fb5c89 100644
--- a/tests/src/com/android/inputmethod/keyboard/internal/KeyboardStateSingleTouchTests.java
+++ b/tests/src/com/android/inputmethod/keyboard/internal/KeyboardStateSingleTouchTests.java
@@ -88,7 +88,7 @@ public class KeyboardStateSingleTouchTests extends KeyboardStateTestsBase {
     // Switching between alphabet shift locked and symbols.
     public void testAlphabetShiftLockedAndSymbols() {
         // Long press shift key, enter alphabet shift locked.
-        longPressShiftKey(ALPHABET_MANUAL_SHIFTED, ALPHABET_SHIFT_LOCKED);
+        longPressAndReleaseKey(CODE_SHIFT, ALPHABET_MANUAL_SHIFTED, ALPHABET_SHIFT_LOCKED);
 
         // Press/release "?123" key, enter into symbols.
         pressAndReleaseKey(CODE_SYMBOL, SYMBOLS_UNSHIFTED, SYMBOLS_UNSHIFTED);
@@ -127,7 +127,7 @@ public class KeyboardStateSingleTouchTests extends KeyboardStateTestsBase {
     // Automatic switch back to alphabet shift locked test by space key.
     public void testSwitchBackBySpaceShiftLocked() {
         // Long press shift key, enter alphabet shift locked.
-        longPressShiftKey(ALPHABET_MANUAL_SHIFTED, ALPHABET_SHIFT_LOCKED);
+        longPressAndReleaseKey(CODE_SHIFT, ALPHABET_MANUAL_SHIFTED, ALPHABET_SHIFT_LOCKED);
 
         // Press/release "?123" key, enter into symbols.
         pressAndReleaseKey(CODE_SYMBOL, SYMBOLS_UNSHIFTED, SYMBOLS_UNSHIFTED);
@@ -179,7 +179,7 @@ public class KeyboardStateSingleTouchTests extends KeyboardStateTestsBase {
         setLayoutSwitchBackSymbols(switchBackSymbols);
         loadKeyboard(ALPHABET_UNSHIFTED);
         // Long press shift key, enter alphabet shift locked.
-        longPressShiftKey(ALPHABET_MANUAL_SHIFTED, ALPHABET_SHIFT_LOCKED);
+        longPressAndReleaseKey(CODE_SHIFT, ALPHABET_MANUAL_SHIFTED, ALPHABET_SHIFT_LOCKED);
 
         // Press/release "?123" key, enter into symbols.
         pressAndReleaseKey(CODE_SYMBOL, SYMBOLS_UNSHIFTED, SYMBOLS_UNSHIFTED);
@@ -235,24 +235,45 @@ public class KeyboardStateSingleTouchTests extends KeyboardStateTestsBase {
     }
 
     // Long press shift key.
-    // TODO: Move long press recognizing timer/logic into KeyboardState.
     public void testLongPressShift() {
+        // Set auto caps mode off.
+        setAutoCapsMode(NO_AUTO_CAPS);
+        // Load keyboard, should be in alphabet.
+        loadKeyboard(ALPHABET_UNSHIFTED);
         // Long press shift key, enter alphabet shift locked.
-        longPressShiftKey(ALPHABET_MANUAL_SHIFTED, ALPHABET_SHIFT_LOCKED);
+        longPressAndReleaseKey(CODE_SHIFT, ALPHABET_MANUAL_SHIFTED, ALPHABET_SHIFT_LOCKED);
+        // Press/release shift key, back to alphabet.
+        pressAndReleaseKey(CODE_SHIFT, ALPHABET_SHIFT_LOCK_SHIFTED, ALPHABET_UNSHIFTED);
 
+        // Long press shift key, enter alphabet shift locked.
+        longPressAndReleaseKey(CODE_SHIFT, ALPHABET_MANUAL_SHIFTED, ALPHABET_SHIFT_LOCKED);
         // Press/release letter key, remain in shift locked.
         pressAndReleaseKey('A', ALPHABET_SHIFT_LOCKED, ALPHABET_SHIFT_LOCKED);
         // Press/release word separator, remain in shift locked.
         pressAndReleaseKey(CODE_SPACE, ALPHABET_SHIFT_LOCKED, ALPHABET_SHIFT_LOCKED);
-
         // Press/release shift key, back to alphabet.
         pressAndReleaseKey(CODE_SHIFT, ALPHABET_SHIFT_LOCK_SHIFTED, ALPHABET_UNSHIFTED);
 
         // Long press shift key, enter alphabet shift locked.
-        longPressShiftKey(ALPHABET_MANUAL_SHIFTED, ALPHABET_SHIFT_LOCKED);
-
+        longPressAndReleaseKey(CODE_SHIFT, ALPHABET_MANUAL_SHIFTED, ALPHABET_SHIFT_LOCKED);
         // Long press shift key, back to alphabet.
-        longPressShiftKey(ALPHABET_SHIFT_LOCK_SHIFTED, ALPHABET_UNSHIFTED);
+        longPressAndReleaseKey(CODE_SHIFT, ALPHABET_SHIFT_LOCK_SHIFTED, ALPHABET_UNSHIFTED);
+
+        // Press/release shift key, enter alphabet shifted.
+        pressAndReleaseKey(CODE_SHIFT, ALPHABET_MANUAL_SHIFTED, ALPHABET_MANUAL_SHIFTED);
+        // Long press shift key, enter alphabet shift locked.
+        longPressAndReleaseKey(CODE_SHIFT, ALPHABET_MANUAL_SHIFTED, ALPHABET_SHIFT_LOCKED);
+        // Press/release shift key, back to alphabet.
+        pressAndReleaseKey(CODE_SHIFT, ALPHABET_SHIFT_LOCK_SHIFTED, ALPHABET_UNSHIFTED);
+
+        // Set auto caps mode on.
+        setAutoCapsMode(AUTO_CAPS);
+        // Load keyboard, should be in automatic shifted.
+        loadKeyboard(ALPHABET_AUTOMATIC_SHIFTED);
+        // Long press shift key, enter alphabet shift locked.
+        longPressAndReleaseKey(CODE_SHIFT, ALPHABET_MANUAL_SHIFTED, ALPHABET_SHIFT_LOCKED);
+        // Press/release shift key, back to alphabet.
+        pressAndReleaseKey(CODE_SHIFT, ALPHABET_SHIFT_LOCK_SHIFTED, ALPHABET_UNSHIFTED);
     }
 
     // Double tap shift key.
@@ -311,11 +332,11 @@ public class KeyboardStateSingleTouchTests extends KeyboardStateTestsBase {
         updateShiftState(ALPHABET_UNSHIFTED);
 
         // Long press shift key, enter alphabet shift locked.
-        longPressShiftKey(ALPHABET_MANUAL_SHIFTED, ALPHABET_SHIFT_LOCKED);
+        longPressAndReleaseKey(CODE_SHIFT, ALPHABET_MANUAL_SHIFTED, ALPHABET_SHIFT_LOCKED);
         // Update shift state, remained in alphabet shift locked.
         updateShiftState(ALPHABET_SHIFT_LOCKED);
         // Long press shift key, back to alphabet.
-        longPressShiftKey(ALPHABET_SHIFT_LOCK_SHIFTED, ALPHABET_UNSHIFTED);
+        longPressAndReleaseKey(CODE_SHIFT, ALPHABET_SHIFT_LOCK_SHIFTED, ALPHABET_UNSHIFTED);
 
         // Press/release "?123" key, enter into symbols.
         pressAndReleaseKey(CODE_SYMBOL, SYMBOLS_UNSHIFTED, SYMBOLS_UNSHIFTED);
@@ -342,11 +363,11 @@ public class KeyboardStateSingleTouchTests extends KeyboardStateTestsBase {
         updateShiftState(ALPHABET_AUTOMATIC_SHIFTED);
 
         // Long press shift key, enter alphabet shift locked.
-        longPressShiftKey(ALPHABET_MANUAL_SHIFTED, ALPHABET_SHIFT_LOCKED);
+        longPressAndReleaseKey(CODE_SHIFT, ALPHABET_MANUAL_SHIFTED, ALPHABET_SHIFT_LOCKED);
         // Update shift state, remained in alphabet shift locked (not automatic shifted).
         updateShiftState(ALPHABET_SHIFT_LOCKED);
         // Long press shift key, back to alphabet.
-        longPressShiftKey(ALPHABET_SHIFT_LOCK_SHIFTED, ALPHABET_UNSHIFTED);
+        longPressAndReleaseKey(CODE_SHIFT, ALPHABET_SHIFT_LOCK_SHIFTED, ALPHABET_UNSHIFTED);
 
         // Load keyboard, should be in automatic shifted.
         loadKeyboard(ALPHABET_AUTOMATIC_SHIFTED);
@@ -393,7 +414,7 @@ public class KeyboardStateSingleTouchTests extends KeyboardStateTestsBase {
 
         // Alphabet shift locked -> shift key + letter -> alphabet shift locked.
         // Long press shift key, enter alphabet shift locked.
-        longPressShiftKey(ALPHABET_MANUAL_SHIFTED, ALPHABET_SHIFT_LOCKED);
+        longPressAndReleaseKey(CODE_SHIFT, ALPHABET_MANUAL_SHIFTED, ALPHABET_SHIFT_LOCKED);
         // Press and slide from "123?" key, enter symbols.
         pressAndSlideFromKey(CODE_SYMBOL, SYMBOLS_UNSHIFTED, SYMBOLS_UNSHIFTED);
         // Enter/release into symbol letter key, switch back to alphabet shift locked.
@@ -444,7 +465,7 @@ public class KeyboardStateSingleTouchTests extends KeyboardStateTestsBase {
         // Load keyboard
         loadKeyboard(ALPHABET_UNSHIFTED);
         // Long press shift key, enter alphabet shift locked.
-        longPressShiftKey(ALPHABET_MANUAL_SHIFTED, ALPHABET_SHIFT_LOCKED);
+        longPressAndReleaseKey(CODE_SHIFT, ALPHABET_MANUAL_SHIFTED, ALPHABET_SHIFT_LOCKED);
         // Press/release "?123" key, enter into symbols.
         pressAndReleaseKey(CODE_SYMBOL, SYMBOLS_UNSHIFTED, SYMBOLS_UNSHIFTED);
         // Press and slide from "ABC" key, enter alphabet shift locked.
@@ -459,7 +480,7 @@ public class KeyboardStateSingleTouchTests extends KeyboardStateTestsBase {
         // Load keyboard
         loadKeyboard(ALPHABET_UNSHIFTED);
         // Long press shift key, enter alphabet shift locked.
-        longPressShiftKey(ALPHABET_MANUAL_SHIFTED, ALPHABET_SHIFT_LOCKED);
+        longPressAndReleaseKey(CODE_SHIFT, ALPHABET_MANUAL_SHIFTED, ALPHABET_SHIFT_LOCKED);
         // Press/release "?123" key, enter into symbols.
         pressAndReleaseKey(CODE_SYMBOL, SYMBOLS_UNSHIFTED, SYMBOLS_UNSHIFTED);
         // Press and slide from "=\<" key, enter symbols shifted.
@@ -512,7 +533,7 @@ public class KeyboardStateSingleTouchTests extends KeyboardStateTestsBase {
         // Load keyboard
         loadKeyboard(ALPHABET_UNSHIFTED);
         // Long press shift key, enter alphabet shift locked.
-        longPressShiftKey(ALPHABET_MANUAL_SHIFTED, ALPHABET_SHIFT_LOCKED);
+        longPressAndReleaseKey(CODE_SHIFT, ALPHABET_MANUAL_SHIFTED, ALPHABET_SHIFT_LOCKED);
         // Press/release "?123" key, enter into symbols.
         pressAndReleaseKey(CODE_SYMBOL, SYMBOLS_UNSHIFTED, SYMBOLS_UNSHIFTED);
         // Press/release "=\<" key, enter into symbols shifted.
@@ -529,7 +550,7 @@ public class KeyboardStateSingleTouchTests extends KeyboardStateTestsBase {
         // Load keyboard
         loadKeyboard(ALPHABET_UNSHIFTED);
         // Long press shift key, enter alphabet shift locked.
-        longPressShiftKey(ALPHABET_MANUAL_SHIFTED, ALPHABET_SHIFT_LOCKED);
+        longPressAndReleaseKey(CODE_SHIFT, ALPHABET_MANUAL_SHIFTED, ALPHABET_SHIFT_LOCKED);
         // Press/release "?123" key, enter into symbols.
         pressAndReleaseKey(CODE_SYMBOL, SYMBOLS_UNSHIFTED, SYMBOLS_UNSHIFTED);
         // Press/release "=\<" key, enter into symbols shifted.
@@ -550,7 +571,7 @@ public class KeyboardStateSingleTouchTests extends KeyboardStateTestsBase {
         loadKeyboard(ALPHABET_UNSHIFTED);
 
         // Long press shift key, enter alphabet shift locked.
-        longPressShiftKey(ALPHABET_MANUAL_SHIFTED, ALPHABET_SHIFT_LOCKED);
+        longPressAndReleaseKey(CODE_SHIFT, ALPHABET_MANUAL_SHIFTED, ALPHABET_SHIFT_LOCKED);
         // Change focus to new text field.
         loadKeyboard(ALPHABET_UNSHIFTED);
 
@@ -583,7 +604,7 @@ public class KeyboardStateSingleTouchTests extends KeyboardStateTestsBase {
         loadKeyboard(ALPHABET_AUTOMATIC_SHIFTED);
 
         // Long press shift key, enter alphabet shift locked.
-        longPressShiftKey(ALPHABET_MANUAL_SHIFTED, ALPHABET_SHIFT_LOCKED);
+        longPressAndReleaseKey(CODE_SHIFT, ALPHABET_MANUAL_SHIFTED, ALPHABET_SHIFT_LOCKED);
         // Change focus to new text field.
         loadKeyboard(ALPHABET_AUTOMATIC_SHIFTED);
 
@@ -615,7 +636,7 @@ public class KeyboardStateSingleTouchTests extends KeyboardStateTestsBase {
 
         // Alphabet shift locked -> rotate -> alphabet shift locked.
         // Long press shift key, enter alphabet shift locked.
-        longPressShiftKey(ALPHABET_MANUAL_SHIFTED, ALPHABET_SHIFT_LOCKED);
+        longPressAndReleaseKey(CODE_SHIFT, ALPHABET_MANUAL_SHIFTED, ALPHABET_SHIFT_LOCKED);
         // Rotate device, remain in alphabet shift locked.
         rotateDevice(ALPHABET_SHIFT_LOCKED);
 
diff --git a/tests/src/com/android/inputmethod/keyboard/internal/KeyboardStateTestsBase.java b/tests/src/com/android/inputmethod/keyboard/internal/KeyboardStateTestsBase.java
index 76b84364c4..96a54668ca 100644
--- a/tests/src/com/android/inputmethod/keyboard/internal/KeyboardStateTestsBase.java
+++ b/tests/src/com/android/inputmethod/keyboard/internal/KeyboardStateTestsBase.java
@@ -106,15 +106,11 @@ public class KeyboardStateTestsBase extends AndroidTestCase
         assertLayout(afterSlide, mSwitcher.getLayoutId());
     }
 
-    public void longPressShiftKey(int afterPress, int afterLongPress) {
-        // Long press shift key
-        mSwitcher.onPressKey(CODE_SHIFT);
-        assertLayout(afterPress, mSwitcher.getLayoutId());
-        // Long press recognized in LatinKeyboardView.KeyTimerHandler.
-        mSwitcher.onCodeInput(CODE_CAPSLOCK, SINGLE);
-        assertLayout(afterLongPress, mSwitcher.getLayoutId());
-        mSwitcher.onReleaseKey(CODE_SHIFT, NOT_SLIDING);
+    public void longPressAndReleaseKey(int code, int afterPress, int afterLongPress) {
+        pressKey(code, afterPress);
+        mSwitcher.onLongPressTimeout(code);
         assertLayout(afterLongPress, mSwitcher.getLayoutId());
+        releaseKey(code, afterLongPress);
     }
 
     public void secondPressAndReleaseKey(int code, int afterPress, int afterRelease) {
diff --git a/tests/src/com/android/inputmethod/keyboard/internal/MockKeyboardSwitcher.java b/tests/src/com/android/inputmethod/keyboard/internal/MockKeyboardSwitcher.java
index 2f39340c9d..a01b69cc17 100644
--- a/tests/src/com/android/inputmethod/keyboard/internal/MockKeyboardSwitcher.java
+++ b/tests/src/com/android/inputmethod/keyboard/internal/MockKeyboardSwitcher.java
@@ -31,7 +31,6 @@ public class MockKeyboardSwitcher implements KeyboardState.SwitchActions {
 
         public static final int CODE_SHIFT = Keyboard.CODE_SHIFT;
         public static final int CODE_SYMBOL = Keyboard.CODE_SWITCH_ALPHA_SYMBOL;
-        public static final int CODE_CAPSLOCK = Keyboard.CODE_CAPSLOCK;
         public static final int CODE_SPACE = Keyboard.CODE_SPACE;
         public static final int CODE_AUTO_CAPS_TRIGGER = Keyboard.CODE_SPACE;
 
@@ -51,6 +50,7 @@ public class MockKeyboardSwitcher implements KeyboardState.SwitchActions {
     private boolean mAutoCapsState = true;
 
     private boolean mIsInDoubleTapTimeout;
+    private int mLongPressTimeoutCode;
 
     private final KeyboardState mState = new KeyboardState(this);
 
@@ -129,6 +129,24 @@ public class MockKeyboardSwitcher implements KeyboardState.SwitchActions {
         return mIsInDoubleTapTimeout;
     }
 
+    @Override
+    public void startLongPressTimer(int code) {
+        mLongPressTimeoutCode = code;
+    }
+
+    @Override
+    public void hapticAndAudioFeedback(int code) {
+        // Nothing to do.
+    }
+
+    public void onLongPressTimeout(int code) {
+        // TODO: Handle simultaneous long presses.
+        if (mLongPressTimeoutCode == code) {
+            mLongPressTimeoutCode = 0;
+            mState.onLongPressTimeout(code);
+        }
+    }
+
     public void updateShiftState() {
         mState.onUpdateShiftState(mAutoCapsMode && mAutoCapsState);
     }
@@ -147,6 +165,9 @@ public class MockKeyboardSwitcher implements KeyboardState.SwitchActions {
 
     public void onReleaseKey(int code, boolean withSliding) {
         mState.onReleaseKey(code, withSliding);
+        if (mLongPressTimeoutCode == code) {
+            mLongPressTimeoutCode = 0;
+        }
     }
 
     public void onCodeInput(int code, boolean isSinglePointer) {
-- 
GitLab