diff --git a/java/src/com/android/inputmethod/keyboard/Keyboard.java b/java/src/com/android/inputmethod/keyboard/Keyboard.java
index 8d40e7aa5a31e8c354250de0c1bb5053cbdcaa4b..a57b9d17283377a112d172f76c96157c9f26cca0 100644
--- a/java/src/com/android/inputmethod/keyboard/Keyboard.java
+++ b/java/src/com/android/inputmethod/keyboard/Keyboard.java
@@ -75,6 +75,7 @@ public class Keyboard {
     public static final int CODE_DELETE = -5;
     public static final int CODE_SETTINGS = -6;
     public static final int CODE_SHORTCUT = -7;
+    public static final int CODE_HAPTIC_AND_AUDIO_FEEDBACK_ONLY = -98;
     // Code value representing the code is not specified.
     public static final int CODE_UNSPECIFIED = -99;
 
diff --git a/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java b/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java
index 4ec16bdcfd8d0affc0dd764da4b90cb08cb24ac1..a24195e87de3b86405ba12ff58b1d944e3cc9540 100644
--- a/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java
@@ -193,9 +193,7 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke
                     // Detected a double tap on shift key. If we are in the ignoring double tap
                     // mode, it means we have already turned off caps lock in
                     // {@link KeyboardSwitcher#onReleaseShift} .
-                    final boolean ignoringDoubleTap = mKeyTimerHandler.isIgnoringDoubleTap();
-                    if (!ignoringDoubleTap)
-                        onDoubleTapShiftKey(tracker);
+                    onDoubleTapShiftKey(tracker, mKeyTimerHandler.isIgnoringDoubleTap());
                     return true;
                 }
                 // Otherwise these events should not be handled as double tap.
@@ -346,11 +344,14 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke
         return onLongPress(parentKey, tracker);
     }
 
-    private void onDoubleTapShiftKey(@SuppressWarnings("unused") PointerTracker tracker) {
+    private void onDoubleTapShiftKey(@SuppressWarnings("unused") PointerTracker tracker,
+            final boolean ignore) {
         // When shift key is double tapped, the first tap is correctly processed as usual tap. And
         // the second tap is treated as this double tap event, so that we need not mark tracker
         // calling setAlreadyProcessed() nor remove the tracker from mPointerQueue.
-        mKeyboardActionListener.onCodeInput(Keyboard.CODE_CAPSLOCK, null, 0, 0);
+        final int primaryCode = ignore ? Keyboard.CODE_HAPTIC_AND_AUDIO_FEEDBACK_ONLY
+                : Keyboard.CODE_CAPSLOCK;
+        mKeyboardActionListener.onCodeInput(primaryCode, null, 0, 0);
     }
 
     // This default implementation returns a more keys panel.
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index 958092bc702ec67a3a87adddcaf79c6d8c1d0743..74fc18523fb18291b5505066b90c3bf0f6568f4e 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -1265,7 +1265,11 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
             break;
         case Keyboard.CODE_CAPSLOCK:
             switcher.toggleCapsLock();
+            //$FALL-THROUGH$
+        case Keyboard.CODE_HAPTIC_AND_AUDIO_FEEDBACK_ONLY:
+            // Dummy code for haptic and audio feedbacks.
             vibrate();
+            playKeyClick(primaryCode);
             break;
         case Keyboard.CODE_SHORTCUT:
             mSubtypeSwitcher.switchToShortcutIME();