diff --git a/java/res/values/strings.xml b/java/res/values/strings.xml
index 25d982793d158e0891eb5539df4eeed08eedffd4..07b3f31c7b39acaab45e536a720dca99abdfbde0 100644
--- a/java/res/values/strings.xml
+++ b/java/res/values/strings.xml
@@ -111,10 +111,16 @@
     <!-- Description for "next word suggestion" option. This displays suggestions even when there is no input, based on the previous word. -->
     <string name="bigram_prediction_summary">Based on previous word</string>
 
-    <!-- Option to enable gesture input. The user can input a word by tracing the letters of a word without releasing the finger from the screen. [CHAR LIMIT=20]-->
+    <!-- Option to enable gesture input. The user can input a word by tracing the letters of a word without releasing the finger from the screen. [CHAR LIMIT=30]-->
     <string name="gesture_input">Gesture input</string>
     <!-- Description for "gesture_input" option. The user can input a word by tracing the letters of a word without releasing the finger from the screen. [CHAR LIMIT=65]-->
     <string name="gesture_input_summary">Input a word by tracing the letters of a word</string>
+    <!-- Option to enable gesture trail preview. The user can see a trail of the gesture during gesture input. [CHAR LIMIT=30]-->
+    <string name="gesture_preview_trail">Show gesture trail</string>
+    <!-- Option to enable gesture floating text preview. The user can see a suggested word floating under the moving finger during a gesture input. [CHAR LIMIT=30]-->
+    <string name="gesture_floating_preview_text">Show gesture word</string>
+    <!-- Description for "gesture_floating_preview_text" option. The user can see a suggested word floating under the moving finger during a gesture input. [CHAR LIMIT=65]-->
+    <string name="gesture_floating_preview_text_summary">Show floating preview word with gesture</string>
 
     <!-- Indicates that a word has been added to the dictionary -->
     <string name="added_word"><xliff:g id="word">%s</xliff:g> : Saved</string>
diff --git a/java/res/xml/prefs.xml b/java/res/xml/prefs.xml
index 4f11cb7e5f9f6bc34a4cc963c34edd9576cd5a96..ef6be3eedadb44be9c71d29a73910f3f5b81f8ce 100644
--- a/java/res/xml/prefs.xml
+++ b/java/res/xml/prefs.xml
@@ -101,6 +101,12 @@
             android:key="pref_advanced_settings"
             android:title="@string/advanced_settings"
             android:summary="@string/advanced_settings_summary">
+            <CheckBoxPreference
+                android:key="pref_key_use_contacts_dict"
+                android:title="@string/use_contacts_dict"
+                android:summary="@string/use_contacts_dict_summary"
+                android:persistent="true"
+                android:defaultValue="true" />
             <CheckBoxPreference
                 android:key="pref_suppress_language_switch_key"
                 android:title="@string/suppress_language_switch_key"
@@ -120,18 +126,23 @@
             <ListPreference
                 android:key="pref_key_preview_popup_dismiss_delay"
                 android:title="@string/key_preview_popup_dismiss_delay" />
-            <CheckBoxPreference
-                android:key="pref_key_use_contacts_dict"
-                android:title="@string/use_contacts_dict"
-                android:summary="@string/use_contacts_dict_summary"
-                android:persistent="true"
-                android:defaultValue="true" />
             <PreferenceScreen
                 android:key="pref_vibration_duration_settings"
                 android:title="@string/prefs_keypress_vibration_duration_settings"/>
             <PreferenceScreen
                 android:key="pref_keypress_sound_volume"
                 android:title="@string/prefs_keypress_sound_volume_settings" />
+            <CheckBoxPreference
+                android:key="pref_gesture_preview_trail"
+                android:title="@string/gesture_preview_trail"
+                android:persistent="true"
+                android:defaultValue="true" />
+            <CheckBoxPreference
+                android:key="pref_gesture_floating_preview_text"
+                android:title="@string/gesture_floating_preview_text"
+                android:summary="@string/gesture_floating_preview_text_summary"
+                android:persistent="true"
+                android:defaultValue="true" />
         </PreferenceScreen>
     </PreferenceCategory>
 </PreferenceScreen>
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardView.java b/java/src/com/android/inputmethod/keyboard/KeyboardView.java
index 9c6543b61ab3605ba602b53ac0603b0980dc3e6a..e70c7a19e95c7d99350d184b6c505f42dda693d1 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardView.java
@@ -432,8 +432,11 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
         return mShowKeyPreviewPopup;
     }
 
-    public void setGestureHandlingMode(boolean shouldHandleGesture) {
+    public void setGestureHandlingMode(boolean shouldHandleGesture,
+            boolean drawsGesturePreviewTrail, boolean drawsGestureFloatingPreviewText) {
         mShouldHandleGesture = shouldHandleGesture;
+        mPreviewPlacerView.setGesturePreviewMode(
+                drawsGesturePreviewTrail, drawsGestureFloatingPreviewText);
     }
 
     @Override
@@ -896,15 +899,12 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
     }
 
     public void showGesturePreviewText(String gesturePreviewText) {
-        // TDOD: Add user settings option to control drawing gesture trail.
         locatePreviewPlacerView();
         mPreviewPlacerView.setGesturePreviewText(gesturePreviewText);
-        mPreviewPlacerView.invalidate();
     }
 
     @Override
     public void showGestureTrail(PointerTracker tracker) {
-        // TDOD: Add user settings option to control drawing gesture trail.
         locatePreviewPlacerView();
         mPreviewPlacerView.invalidatePointer(tracker);
     }
diff --git a/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java b/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java
index 9c28419cff669994cbe932b289c2aebc2fabc1ab..7ad552151fac09e88c538bd5cf2d911682c1f277 100644
--- a/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java
@@ -481,8 +481,10 @@ public class MainKeyboardView extends KeyboardView implements PointerTracker.Key
     }
 
     @Override
-    public void setGestureHandlingMode(final boolean shouldHandleGesture) {
-        super.setGestureHandlingMode(shouldHandleGesture);
+    public void setGestureHandlingMode(final boolean shouldHandleGesture,
+            boolean drawsGesturePreviewTrail, boolean drawsGestureFloatingPreviewText) {
+        super.setGestureHandlingMode(shouldHandleGesture, drawsGesturePreviewTrail,
+                drawsGestureFloatingPreviewText);
         PointerTracker.setKeyDetector(mKeyDetector, shouldHandleGesture);
     }
 
diff --git a/java/src/com/android/inputmethod/keyboard/internal/PreviewPlacerView.java b/java/src/com/android/inputmethod/keyboard/internal/PreviewPlacerView.java
index 2a53c59bb1865e56a5a816dcf72dec1e262ad0f6..a400fda15cd26f6a95e733df7513dbd30f9f9b30 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/PreviewPlacerView.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/PreviewPlacerView.java
@@ -51,6 +51,8 @@ public class PreviewPlacerView extends RelativeLayout {
     private final SparseArray<PointerTracker> mPointers = new SparseArray<PointerTracker>();
 
     private String mGesturePreviewText;
+    private boolean mDrawsGesturePreviewTrail;
+    private boolean mDrawsGestureFloatingPreviewText;
 
     public PreviewPlacerView(Context context) {
         super(context);
@@ -89,6 +91,12 @@ public class PreviewPlacerView extends RelativeLayout {
         mYOrigin = y;
     }
 
+    public void setGesturePreviewMode(boolean drawsGesturePreviewTrail,
+            boolean drawsGestureFloatingPreviewText) {
+        mDrawsGesturePreviewTrail = drawsGesturePreviewTrail;
+        mDrawsGestureFloatingPreviewText = drawsGestureFloatingPreviewText;
+    }
+
     public void invalidatePointer(PointerTracker tracker) {
         synchronized (mPointers) {
             mPointers.put(tracker.mPointerId, tracker);
@@ -100,18 +108,19 @@ public class PreviewPlacerView extends RelativeLayout {
     @Override
     public void onDraw(Canvas canvas) {
         super.onDraw(canvas);
-        // TDOD: Add user settings option to control drawing gesture trail and gesture preview.
         synchronized (mPointers) {
             canvas.translate(mXOrigin, mYOrigin);
             final int trackerCount = mPointers.size();
-            boolean floatingPreviewHasDrawn = false;
+            boolean hasDrawnFloatingPreviewText = false;
             for (int index = 0; index < trackerCount; index++) {
                 final PointerTracker tracker = mPointers.valueAt(index);
-                tracker.drawGestureTrail(canvas, mGesturePaint);
+                if (mDrawsGesturePreviewTrail) {
+                    tracker.drawGestureTrail(canvas, mGesturePaint);
+                }
                 // TODO: Figure out more cleaner way to draw gesture preview text.
-                if (!floatingPreviewHasDrawn) {
+                if (mDrawsGestureFloatingPreviewText && !hasDrawnFloatingPreviewText) {
                     drawGesturePreviewText(canvas, tracker, mGesturePreviewText);
-                    floatingPreviewHasDrawn = true;
+                    hasDrawnFloatingPreviewText = true;
                 }
             }
             canvas.translate(-mXOrigin, -mYOrigin);
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index 1aac734baa002917248b8df4f33a457ab8a7fa56..22213be5e18f4c49c0a86028646193023a2128da 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -2095,7 +2095,9 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
         if (keyboardView != null) {
             final boolean shouldHandleGesture = mCurrentSettings.mGestureInputEnabled
                     && mIsMainDictionaryAvailable;
-            keyboardView.setGestureHandlingMode(shouldHandleGesture);
+            keyboardView.setGestureHandlingMode(shouldHandleGesture,
+                    mCurrentSettings.mGesturePreviewTrailEnabled,
+                    mCurrentSettings.mGestureFloatingPreviewTextEnabled);
         }
     }
 
diff --git a/java/src/com/android/inputmethod/latin/Settings.java b/java/src/com/android/inputmethod/latin/Settings.java
index 45608f4395f002e7190e3256d077fbb67997e9a5..6251c9acd26d9909ef0b8bc63382b0125d577cc3 100644
--- a/java/src/com/android/inputmethod/latin/Settings.java
+++ b/java/src/com/android/inputmethod/latin/Settings.java
@@ -62,6 +62,7 @@ public class Settings extends InputMethodSettingsFragment
     public static final String PREF_LAST_USER_DICTIONARY_WRITE_TIME =
             "last_user_dictionary_write_time";
     public static final String PREF_ADVANCED_SETTINGS = "pref_advanced_settings";
+    public static final String PREF_KEY_USE_CONTACTS_DICT = "pref_key_use_contacts_dict";
     public static final String PREF_SUPPRESS_LANGUAGE_SWITCH_KEY =
             "pref_suppress_language_switch_key";
     public static final String PREF_INCLUDE_OTHER_IMES_IN_LANGUAGE_SWITCH_LIST =
@@ -69,13 +70,15 @@ public class Settings extends InputMethodSettingsFragment
     public static final String PREF_CUSTOM_INPUT_STYLES = "custom_input_styles";
     public static final String PREF_KEY_PREVIEW_POPUP_DISMISS_DELAY =
             "pref_key_preview_popup_dismiss_delay";
-    public static final String PREF_KEY_USE_CONTACTS_DICT = "pref_key_use_contacts_dict";
     public static final String PREF_BIGRAM_PREDICTIONS = "next_word_prediction";
     public static final String PREF_GESTURE_INPUT = "gesture_input";
     public static final String PREF_VIBRATION_DURATION_SETTINGS =
             "pref_vibration_duration_settings";
     public static final String PREF_KEYPRESS_SOUND_VOLUME =
             "pref_keypress_sound_volume";
+    public static final String PREF_GESTURE_PREVIEW_TRAIL = "pref_gesture_preview_trail";
+    public static final String PREF_GESTURE_FLOATING_PREVIEW_TEXT =
+            "pref_gesture_floating_preview_text";
 
     public static final String PREF_INPUT_LANGUAGE = "input_language";
     public static final String PREF_SELECTED_LANGUAGES = "selected_languages";
@@ -94,13 +97,17 @@ public class Settings extends InputMethodSettingsFragment
     private TextView mKeypressVibrationDurationSettingsTextView;
     private TextView mKeypressSoundVolumeSettingsTextView;
 
+    private static void setPreferenceEnabled(Preference preference, boolean enabled) {
+        if (preference != null) {
+            preference.setEnabled(enabled);
+        }
+    }
+
     private void ensureConsistencyOfAutoCorrectionSettings() {
         final String autoCorrectionOff = getResources().getString(
                 R.string.auto_correction_threshold_mode_index_off);
         final String currentSetting = mAutoCorrectionThresholdPreference.getValue();
-        if (null != mBigramPrediction) {
-            mBigramPrediction.setEnabled(!currentSetting.equals(autoCorrectionOff));
-        }
+        setPreferenceEnabled(mBigramPrediction, !currentSetting.equals(autoCorrectionOff));
     }
 
     @Override
@@ -180,13 +187,11 @@ public class Settings extends InputMethodSettingsFragment
             if (null == mKeyPreviewPopupDismissDelay.getValue()) {
                 mKeyPreviewPopupDismissDelay.setValue(popupDismissDelayDefaultValue);
             }
-            mKeyPreviewPopupDismissDelay.setEnabled(
+            setPreferenceEnabled(mKeyPreviewPopupDismissDelay,
                     SettingsValues.isKeyPreviewPopupEnabled(prefs, res));
         }
 
-        final CheckBoxPreference includeOtherImesInLanguageSwitchList =
-                (CheckBoxPreference)findPreference(PREF_INCLUDE_OTHER_IMES_IN_LANGUAGE_SWITCH_LIST);
-        includeOtherImesInLanguageSwitchList.setEnabled(
+        setPreferenceEnabled(findPreference(PREF_INCLUDE_OTHER_IMES_IN_LANGUAGE_SWITCH_LIST),
                 !SettingsValues.isLanguageSwitchKeySupressed(prefs));
 
         final PreferenceScreen dictionaryLink =
@@ -200,10 +205,19 @@ public class Settings extends InputMethodSettingsFragment
 
         final boolean gestureInputEnabledByBuildConfig = res.getBoolean(
                 R.bool.config_gesture_input_enabled_by_build_config);
+        final Preference gesturePreviewTrail = findPreference(PREF_GESTURE_PREVIEW_TRAIL);
+        final Preference gestureFloatingPreviewText = findPreference(
+                PREF_GESTURE_FLOATING_PREVIEW_TEXT);
         if (!gestureInputEnabledByBuildConfig) {
-            final Preference gestureInputPref = findPreference(PREF_GESTURE_INPUT);
-            miscSettings.removePreference(gestureInputPref);
+            miscSettings.removePreference(findPreference(PREF_GESTURE_INPUT));
+            miscSettings.removePreference(gesturePreviewTrail);
+            miscSettings.removePreference(gestureFloatingPreviewText);
+        } else {
+            final boolean gestureInputEnabledByUser = prefs.getBoolean(PREF_GESTURE_INPUT, true);
+            setPreferenceEnabled(gesturePreviewTrail, gestureInputEnabledByUser);
+            setPreferenceEnabled(gestureFloatingPreviewText, gestureInputEnabledByUser);
         }
+
         final boolean showUsabilityStudyModeOption =
                 res.getBoolean(R.bool.config_enable_usability_study_mode_option)
                         || ProductionFlag.IS_EXPERIMENTAL || ENABLE_EXPERIMENTAL_SETTINGS;
@@ -277,17 +291,22 @@ public class Settings extends InputMethodSettingsFragment
     public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
         (new BackupManager(getActivity())).dataChanged();
         if (key.equals(PREF_POPUP_ON)) {
-            final ListPreference popupDismissDelay =
-                (ListPreference)findPreference(PREF_KEY_PREVIEW_POPUP_DISMISS_DELAY);
-            if (null != popupDismissDelay) {
-                popupDismissDelay.setEnabled(prefs.getBoolean(PREF_POPUP_ON, true));
-            }
+            setPreferenceEnabled(findPreference(PREF_KEY_PREVIEW_POPUP_DISMISS_DELAY),
+                    prefs.getBoolean(PREF_POPUP_ON, true));
         } else if (key.equals(PREF_SUPPRESS_LANGUAGE_SWITCH_KEY)) {
-            final CheckBoxPreference includeOtherImesInLanguageSwicthList =
-                    (CheckBoxPreference)findPreference(
-                            PREF_INCLUDE_OTHER_IMES_IN_LANGUAGE_SWITCH_LIST);
-            includeOtherImesInLanguageSwicthList.setEnabled(
+            setPreferenceEnabled(findPreference(PREF_INCLUDE_OTHER_IMES_IN_LANGUAGE_SWITCH_LIST),
                     !SettingsValues.isLanguageSwitchKeySupressed(prefs));
+        } else if (key.equals(PREF_GESTURE_INPUT)) {
+            final boolean gestureInputEnabledByConfig = getResources().getBoolean(
+                    R.bool.config_gesture_input_enabled_by_build_config);
+            if (gestureInputEnabledByConfig) {
+                final boolean gestureInputEnabledByUser = prefs.getBoolean(
+                        PREF_GESTURE_INPUT, true);
+                setPreferenceEnabled(findPreference(PREF_GESTURE_PREVIEW_TRAIL),
+                        gestureInputEnabledByUser);
+                setPreferenceEnabled(findPreference(PREF_GESTURE_FLOATING_PREVIEW_TEXT),
+                        gestureInputEnabledByUser);
+            }
         }
         ensureConsistencyOfAutoCorrectionSettings();
         updateVoiceModeSummary();
@@ -335,16 +354,18 @@ public class Settings extends InputMethodSettingsFragment
     private void refreshEnablingsOfKeypressSoundAndVibrationSettings(
             SharedPreferences sp, Resources res) {
         if (mKeypressVibrationDurationSettingsPref != null) {
-            final boolean hasVibrator = VibratorUtils.getInstance(getActivity()).hasVibrator();
-            final boolean vibrateOn = hasVibrator && sp.getBoolean(Settings.PREF_VIBRATE_ON,
+            final boolean hasVibratorHardware = VibratorUtils.getInstance(getActivity())
+                    .hasVibrator();
+            final boolean vibrateOnByUser = sp.getBoolean(Settings.PREF_VIBRATE_ON,
                     res.getBoolean(R.bool.config_default_vibration_enabled));
-            mKeypressVibrationDurationSettingsPref.setEnabled(vibrateOn);
+            setPreferenceEnabled(mKeypressVibrationDurationSettingsPref,
+                    hasVibratorHardware && vibrateOnByUser);
         }
 
         if (mKeypressSoundVolumeSettingsPref != null) {
             final boolean soundOn = sp.getBoolean(Settings.PREF_SOUND_ON,
                     res.getBoolean(R.bool.config_default_sound_enabled));
-            mKeypressSoundVolumeSettingsPref.setEnabled(soundOn);
+            setPreferenceEnabled(mKeypressSoundVolumeSettingsPref, soundOn);
         }
     }
 
diff --git a/java/src/com/android/inputmethod/latin/SettingsValues.java b/java/src/com/android/inputmethod/latin/SettingsValues.java
index 3ed981375023e9d6d5c02fd1dd3db8d413331c0a..0843bdbbcbfd2fc71475e9f6be751d37954a3884 100644
--- a/java/src/com/android/inputmethod/latin/SettingsValues.java
+++ b/java/src/com/android/inputmethod/latin/SettingsValues.java
@@ -84,6 +84,8 @@ public class SettingsValues {
     private final float mKeypressSoundVolumeRawValue;
     private final InputMethodSubtype[] mAdditionalSubtypes;
     public final boolean mGestureInputEnabled;
+    public final boolean mGesturePreviewTrailEnabled;
+    public final boolean mGestureFloatingPreviewTextEnabled;
 
     // From the input box
     private final InputAttributes mInputAttributes;
@@ -174,6 +176,9 @@ public class SettingsValues {
                 R.bool.config_gesture_input_enabled_by_build_config);
         mGestureInputEnabled = gestureInputEnabledByBuildConfig
                 && prefs.getBoolean(Settings.PREF_GESTURE_INPUT, true);
+        mGesturePreviewTrailEnabled = prefs.getBoolean(Settings.PREF_GESTURE_PREVIEW_TRAIL, true);
+        mGestureFloatingPreviewTextEnabled = prefs.getBoolean(
+                Settings.PREF_GESTURE_FLOATING_PREVIEW_TEXT, true);
         mCorrectionEnabled = mAutoCorrectEnabled && !mInputAttributes.mInputTypeNoAutoCorrect;
         mSuggestionVisibility = createSuggestionVisibility(res);
     }