add vibration duration settings

Change-Id: I56a1a94df63160f367f866da759d7dd4fc428ed5
diff --git a/java/res/layout/vibration_settings_dialog.xml b/java/res/layout/vibration_settings_dialog.xml
new file mode 100644
index 0000000..981ba9b
--- /dev/null
+++ b/java/res/layout/vibration_settings_dialog.xml
@@ -0,0 +1,49 @@
+<?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.
+*/
+-->
+
+<LinearLayout
+        xmlns:android="http://schemas.android.com/apk/res/android"
+        android:orientation="vertical"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_margin="10dip">
+    <LinearLayout
+        android:orientation="horizontal"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:gravity="center_horizontal"
+        android:layout_margin="10dip">
+        <TextView android:id="@+id/vibration_value"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:textSize="20dip"/>
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/settings_ms"
+            android:textSize="20dip"/>
+    </LinearLayout>
+    <SeekBar
+        android:id="@+id/vibration_settings"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:max="250"
+        android:layout_margin="10dip"/>
+</LinearLayout>
diff --git a/java/res/values/donottranslate.xml b/java/res/values/donottranslate.xml
index 75e22dd..aefaec9 100644
--- a/java/res/values/donottranslate.xml
+++ b/java/res/values/donottranslate.xml
@@ -165,4 +165,5 @@
     <!-- dictionary pack package name /settings activity (for shared prefs and settings) -->
     <string name="dictionary_pack_package_name">com.google.android.inputmethod.latin.dictionarypack</string>
     <string name="dictionary_pack_settings_activity">com.google.android.inputmethod.latin.dictionarypack.DictionarySettingsActivity</string>
+    <string name="settings_ms">ms</string>
 </resources>
diff --git a/java/res/values/strings.xml b/java/res/values/strings.xml
index 2f591fd..a1c1a9f 100644
--- a/java/res/values/strings.xml
+++ b/java/res/values/strings.xml
@@ -343,4 +343,6 @@
 
     <!-- Title of an option for usability study mode -->
     <string name="prefs_usability_study_mode">Usability study mode</string>
+    <!-- Title of the settings for vibration duration -->
+    <string name="prefs_vibration_duration_settings">Vibration duration settings</string>
 </resources>
diff --git a/java/res/xml/prefs.xml b/java/res/xml/prefs.xml
index 24de95f..312af28 100644
--- a/java/res/xml/prefs.xml
+++ b/java/res/xml/prefs.xml
@@ -125,6 +125,9 @@
                 android:summary="@string/enable_span_insert_summary"
                 android:persistent="true"
                 android:defaultValue="true" />
+            <PreferenceScreen
+                android:key="pref_vibration_duration_settings"
+                android:title="@string/prefs_vibration_duration_settings"/>
             <!-- TODO: evaluate results and revive this option. The code
                 already supports it. -->
             <!-- <CheckBoxPreference -->
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index 32649d5..48a1f8b 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -2099,16 +2099,7 @@
     }
 
     private void updateKeypressVibrationDuration() {
-        final String[] durationPerHardwareList = mResources.getStringArray(
-                R.array.keypress_vibration_durations);
-        final String hardwarePrefix = Build.HARDWARE + ",";
-        for (final String element : durationPerHardwareList) {
-            if (element.startsWith(hardwarePrefix)) {
-                mKeypressVibrationDuration =
-                        Long.parseLong(element.substring(element.lastIndexOf(',') + 1));
-                break;
-            }
-        }
+        mKeypressVibrationDuration = Utils.getCurrentVibrationDuration(mPrefs, mResources);
     }
 
     private void playKeyClick(int primaryCode) {
diff --git a/java/src/com/android/inputmethod/latin/Settings.java b/java/src/com/android/inputmethod/latin/Settings.java
index d706cd0..a2e8966 100644
--- a/java/src/com/android/inputmethod/latin/Settings.java
+++ b/java/src/com/android/inputmethod/latin/Settings.java
@@ -36,7 +36,10 @@
 import android.text.TextUtils;
 import android.text.method.LinkMovementMethod;
 import android.util.Log;
+import android.view.View;
 import android.view.inputmethod.EditorInfo;
+import android.widget.SeekBar;
+import android.widget.SeekBar.OnSeekBarChangeListener;
 import android.widget.TextView;
 
 import com.android.inputmethod.compat.CompatUtils;
@@ -89,6 +92,9 @@
 
     public static final String PREF_USABILITY_STUDY_MODE = "usability_study_mode";
 
+    public static final String PREF_VIBRATION_DURATION_SETTINGS =
+            "pref_vibration_duration_settings";
+
     // Dialog ids
     private static final int VOICE_INPUT_CONFIRM_DIALOG = 0;
 
@@ -335,6 +341,7 @@
     private boolean mVoiceOn;
 
     private AlertDialog mDialog;
+    private TextView mVibrationSettingsTextView;
 
     private boolean mOkClicked = false;
     private String mVoiceModeOff;
@@ -475,6 +482,19 @@
                 miscSettings.removePreference(pref);
             }
         }
+
+        final PreferenceScreen vibrationSettingsPref =
+                (PreferenceScreen) findPreference(PREF_VIBRATION_DURATION_SETTINGS);
+        if (vibrationSettingsPref != null) {
+            vibrationSettingsPref.setOnPreferenceClickListener(
+                    new OnPreferenceClickListener() {
+                        @Override
+                        public boolean onPreferenceClick(Preference arg0) {
+                            showVibrationSettingsDialog();
+                            return true;
+                        }
+                    });
+        }
     }
 
     @SuppressWarnings("unused")
@@ -621,4 +641,51 @@
             mVoicePreference.setValue(mVoiceModeOff);
         }
     }
-}
+
+    private void showVibrationSettingsDialog() {
+        final SharedPreferences sp = getPreferenceManager().getSharedPreferences();
+        final Activity context = getActivityInternal();
+        final AlertDialog.Builder builder = new AlertDialog.Builder(context);
+        builder.setTitle(R.string.prefs_vibration_duration_settings);
+        builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
+            @Override
+            public void onClick(DialogInterface dialog, int whichButton) {
+                final int ms = Integer.valueOf(mVibrationSettingsTextView.getText().toString());
+                sp.edit().putInt(Settings.PREF_VIBRATION_DURATION_SETTINGS, ms).apply();
+            }
+        });
+        builder.setNegativeButton(android.R.string.cancel,  new DialogInterface.OnClickListener() {
+            @Override
+            public void onClick(DialogInterface dialog, int whichButton) {
+                dialog.dismiss();
+            }
+        });
+        final View v = context.getLayoutInflater().inflate(
+                R.layout.vibration_settings_dialog, null);
+        final int currentMs = Utils.getCurrentVibrationDuration(
+                getPreferenceManager().getSharedPreferences(), getResources());
+        mVibrationSettingsTextView = (TextView)v.findViewById(R.id.vibration_value);
+        final SeekBar sb = (SeekBar)v.findViewById(R.id.vibration_settings);
+        sb.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
+            @Override
+            public void onProgressChanged(SeekBar arg0, int arg1, boolean arg2) {
+                final int tempMs = arg1;
+                mVibrationSettingsTextView.setText(String.valueOf(tempMs));
+            }
+
+            @Override
+            public void onStartTrackingTouch(SeekBar arg0) {
+            }
+
+            @Override
+            public void onStopTrackingTouch(SeekBar arg0) {
+                final int tempMs = arg0.getProgress();
+                VibratorCompatWrapper.getInstance(context).vibrate(tempMs);
+            }
+        });
+        sb.setProgress(currentMs);
+        mVibrationSettingsTextView.setText(String.valueOf(currentMs));
+        builder.setView(v);
+        builder.create().show();
+    }
+}
\ No newline at end of file
diff --git a/java/src/com/android/inputmethod/latin/Utils.java b/java/src/com/android/inputmethod/latin/Utils.java
index c35273e..7712765 100644
--- a/java/src/com/android/inputmethod/latin/Utils.java
+++ b/java/src/com/android/inputmethod/latin/Utils.java
@@ -17,9 +17,11 @@
 package com.android.inputmethod.latin;
 
 import android.content.Context;
+import android.content.SharedPreferences;
 import android.content.res.Resources;
 import android.inputmethodservice.InputMethodService;
 import android.os.AsyncTask;
+import android.os.Build;
 import android.os.Handler;
 import android.os.HandlerThread;
 import android.os.Process;
@@ -772,4 +774,20 @@
         // - It also does not work with unicode surrogate code points.
         return s.toUpperCase(locale).charAt(0) + s.substring(1);
     }
+
+    public static int getCurrentVibrationDuration(SharedPreferences sp, Resources res) {
+        final int ms = sp.getInt(Settings.PREF_VIBRATION_DURATION_SETTINGS, -1);
+        if (ms >= 0) {
+            return ms;
+        }
+        final String[] durationPerHardwareList = res.getStringArray(
+                R.array.keypress_vibration_durations);
+        final String hardwarePrefix = Build.HARDWARE + ",";
+        for (final String element : durationPerHardwareList) {
+            if (element.startsWith(hardwarePrefix)) {
+                return (int)Long.parseLong(element.substring(element.lastIndexOf(',') + 1));
+            }
+        }
+        return -1;
+    }
 }