Add keyboard margin options to place the keyboard dynamically.

Keyboard location and location can now be set in the debug options
section.

Change-Id: I87c5a1d679489e12dccf26632c399af28087629e
diff --git a/java/res/layout/input_view.xml b/java/res/layout/input_view.xml
index ae3c19d..98ef02b 100644
--- a/java/res/layout/input_view.xml
+++ b/java/res/layout/input_view.xml
@@ -23,10 +23,18 @@
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     style="?attr/inputViewStyle">
-    <include
-        android:id="@+id/main_keyboard_frame"
-        layout="@layout/main_keyboard_frame" />
-    <include
-        android:id="@+id/emoji_palettes_view"
-        layout="@layout/emoji_palettes_view" />
+    <LinearLayout
+        android:id="@+id/horizontal_keyboard_frame"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="bottom"
+        android:gravity="bottom"
+        android:orientation="horizontal">
+        <include
+            android:id="@+id/main_keyboard_frame"
+            layout="@layout/main_keyboard_frame" />
+        <include
+            android:id="@+id/emoji_palettes_view"
+            layout="@layout/emoji_palettes_view" />
+    </LinearLayout>
 </com.android.inputmethod.latin.InputView>
diff --git a/java/res/values/donottranslate-debug-settings.xml b/java/res/values/donottranslate-debug-settings.xml
index 491043f..55ab933 100644
--- a/java/res/values/donottranslate-debug-settings.xml
+++ b/java/res/values/donottranslate-debug-settings.xml
@@ -47,6 +47,12 @@
     <string name="prefs_resize_keyboard">Enable keyboard resizing</string>
     <!-- Title of the settings for setting keyboard height -->
     <string name="prefs_keyboard_height_scale">Keyboard height scale</string>
+    <!-- Title of the settings for setting keyboard width -->
+    <string name="prefs_keyboard_bottom_margin">Keyboard bottom margin</string>
+    <!-- Title of the settings for setting keyboard width -->
+    <string name="prefs_keyboard_left_margin">Keyboard left margin</string>
+    <!-- Title of the settings for setting keyboard width -->
+    <string name="prefs_keyboard_right_margin">Keyboard right margin</string>
     <!-- Message to show when there are no files to install as an external dictionary [CHAR LIMIT=100] -->
     <string name="read_external_dictionary_no_files_message">No dictionary files in the Downloads folder</string>
     <!-- Title of the dialog that selects a file to install as an external dictionary [CHAR LIMIT=50] -->
diff --git a/java/res/xml/prefs_screen_debug.xml b/java/res/xml/prefs_screen_debug.xml
index 905bc04..3134727 100644
--- a/java/res/xml/prefs_screen_debug.xml
+++ b/java/res/xml/prefs_screen_debug.xml
@@ -87,6 +87,24 @@
         android:title="@string/prefs_keyboard_height_scale"
         latin:minValue="50"
         latin:maxValue="120" /> <!-- percentage -->
+    <com.android.inputmethod.latin.settings.SeekBarDialogPreference
+        android:dependency="pref_resize_keyboard"
+        android:key="pref_keyboard_bottom_margin"
+        android:title="@string/prefs_keyboard_bottom_margin"
+        latin:minValue="0"
+        latin:maxValue="50" /> <!-- percentage -->
+    <com.android.inputmethod.latin.settings.SeekBarDialogPreference
+        android:dependency="pref_resize_keyboard"
+        android:key="pref_keyboard_left_margin"
+        android:title="@string/prefs_keyboard_left_margin"
+        latin:minValue="0"
+        latin:maxValue="50" /> <!-- percentage -->
+    <com.android.inputmethod.latin.settings.SeekBarDialogPreference
+        android:dependency="pref_resize_keyboard"
+        android:key="pref_keyboard_right_margin"
+        android:title="@string/prefs_keyboard_right_margin"
+        latin:minValue="0"
+        latin:maxValue="50" /> <!-- percentage -->
     <PreferenceScreen
         android:key="read_external_dictionary"
         android:title="@string/prefs_read_external_dictionary" />
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
index 5e3a5f1..d19f506 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
@@ -22,7 +22,9 @@
 import android.view.ContextThemeWrapper;
 import android.view.LayoutInflater;
 import android.view.View;
+import android.view.ViewGroup;
 import android.view.inputmethod.EditorInfo;
+import android.widget.LinearLayout;
 
 import com.android.inputmethod.compat.InputMethodServiceCompatUtils;
 import com.android.inputmethod.event.Event;
@@ -64,7 +66,7 @@
 
     private KeyboardTheme mKeyboardTheme;
     private Context mThemeContext;
-
+    private View mHorizontalKeyboardFrame;
     private static final KeyboardSwitcher sInstance = new KeyboardSwitcher();
 
     public static KeyboardSwitcher getInstance() {
@@ -111,8 +113,16 @@
         final KeyboardLayoutSet.Builder builder = new KeyboardLayoutSet.Builder(
                 mThemeContext, editorInfo);
         final Resources res = mThemeContext.getResources();
-        final int keyboardWidth = ResourceUtils.getDefaultKeyboardWidth(res);
+        final ViewGroup.MarginLayoutParams p =
+                (ViewGroup.MarginLayoutParams) mHorizontalKeyboardFrame.getLayoutParams();
+
+        final int keyboardLeftMargin = ResourceUtils.getKeyboardLeftMargin(res, settingsValues);
+        final int keyboardRightMargin = ResourceUtils.getKeyboardRightMargin(res, settingsValues);
+        final int keyboardBottomMargin = ResourceUtils.getKeyboardBottomMargin(res, settingsValues);
+        p.setMargins(keyboardLeftMargin, 0, keyboardRightMargin, keyboardBottomMargin);
+
         final int keyboardHeight = ResourceUtils.getKeyboardHeight(res, settingsValues);
+        final int keyboardWidth = ResourceUtils.getKeyboardWidth(res, settingsValues);
         builder.setKeyboardGeometry(keyboardWidth, keyboardHeight);
         builder.setSubtype(RichInputMethodManager.getInstance().getCurrentSubtype());
         builder.setVoiceInputKeyEnabled(settingsValues.mShowsVoiceInputKey);
@@ -411,6 +421,8 @@
         mEmojiPalettesView.setHardwareAcceleratedDrawingEnabled(
                 isHardwareAcceleratedDrawingEnabled);
         mEmojiPalettesView.setKeyboardActionListener(mLatinIME);
+        mHorizontalKeyboardFrame = (LinearLayout)mCurrentInputView.findViewById(
+                R.id.horizontal_keyboard_frame);
         return mCurrentInputView;
     }
 
diff --git a/java/src/com/android/inputmethod/keyboard/emoji/EmojiLayoutParams.java b/java/src/com/android/inputmethod/keyboard/emoji/EmojiLayoutParams.java
index 582e091..2ac7997 100644
--- a/java/src/com/android/inputmethod/keyboard/emoji/EmojiLayoutParams.java
+++ b/java/src/com/android/inputmethod/keyboard/emoji/EmojiLayoutParams.java
@@ -39,7 +39,7 @@
 
     public EmojiLayoutParams(final Resources res) {
         final int defaultKeyboardHeight = ResourceUtils.getDefaultKeyboardHeight(res);
-        final int defaultKeyboardWidth = ResourceUtils.getDefaultKeyboardWidth(res);
+        final int defaultKeyboardWidth = ResourceUtils.getKeyboardFrameWidth(res);
         mKeyVerticalGap = (int) res.getFraction(R.fraction.config_key_vertical_gap_holo,
                 defaultKeyboardHeight, defaultKeyboardHeight);
         mBottomPadding = (int) res.getFraction(R.fraction.config_keyboard_bottom_padding_holo,
diff --git a/java/src/com/android/inputmethod/keyboard/emoji/EmojiPalettesView.java b/java/src/com/android/inputmethod/keyboard/emoji/EmojiPalettesView.java
index cf4dd3d..223947e 100644
--- a/java/src/com/android/inputmethod/keyboard/emoji/EmojiPalettesView.java
+++ b/java/src/com/android/inputmethod/keyboard/emoji/EmojiPalettesView.java
@@ -50,6 +50,8 @@
 import com.android.inputmethod.latin.R;
 import com.android.inputmethod.latin.RichInputMethodSubtype;
 import com.android.inputmethod.latin.common.Constants;
+import com.android.inputmethod.latin.settings.Settings;
+import com.android.inputmethod.latin.settings.SettingsValues;
 import com.android.inputmethod.latin.utils.ResourceUtils;
 
 import java.util.concurrent.TimeUnit;
@@ -113,9 +115,10 @@
                 context, null /* editorInfo */);
         final Resources res = context.getResources();
         mEmojiLayoutParams = new EmojiLayoutParams(res);
+        final SettingsValues s = Settings.getInstance().getCurrent();
         builder.setSubtype(RichInputMethodSubtype.getEmojiSubtype());
-        builder.setKeyboardGeometry(ResourceUtils.getDefaultKeyboardWidth(res),
-                mEmojiLayoutParams.mEmojiKeyboardHeight);
+        builder.setKeyboardGeometry(ResourceUtils.getKeyboardWidth(res, s),
+                ResourceUtils.getKeyboardHeight(res, s));
         final KeyboardLayoutSet layoutSet = builder.build();
         final TypedArray emojiPalettesViewAttr = context.obtainStyledAttributes(attrs,
                 R.styleable.EmojiPalettesView, defStyle, R.style.EmojiPalettesView);
@@ -140,7 +143,7 @@
         super.onMeasure(widthMeasureSpec, heightMeasureSpec);
         final Resources res = getContext().getResources();
         // The main keyboard expands to the entire this {@link KeyboardView}.
-        final int width = ResourceUtils.getDefaultKeyboardWidth(res)
+        final int width = ResourceUtils.getKeyboardFrameWidth(res)
                 + getPaddingLeft() + getPaddingRight();
         final int height = ResourceUtils.getDefaultKeyboardHeight(res)
                 + res.getDimensionPixelSize(R.dimen.config_suggestions_strip_height)
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index 44dffa4..e20ec88 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -100,6 +100,7 @@
 import com.android.inputmethod.latin.utils.IntentUtils;
 import com.android.inputmethod.latin.utils.JniUtils;
 import com.android.inputmethod.latin.utils.LeakGuardHandlerWrapper;
+import com.android.inputmethod.latin.utils.ResourceUtils;
 import com.android.inputmethod.latin.utils.StatsUtils;
 import com.android.inputmethod.latin.utils.StatsUtilsManager;
 import com.android.inputmethod.latin.utils.SubtypeLocaleUtils;
@@ -1211,6 +1212,7 @@
             return;
         }
         final SettingsValues settingsValues = mSettings.getCurrent();
+        final Resources res = getResources();
         final View visibleKeyboardView = mKeyboardSwitcher.getVisibleKeyboardView();
         if (visibleKeyboardView == null || !hasSuggestionStripView()) {
             return;
@@ -1228,13 +1230,15 @@
         final int suggestionsHeight = (!mKeyboardSwitcher.isShowingEmojiPalettes()
                 && mSuggestionStripView.getVisibility() == View.VISIBLE)
                 ? mSuggestionStripView.getHeight() : 0;
-        final int visibleTopY = inputHeight - visibleKeyboardView.getHeight() - suggestionsHeight;
+        final int visibleTopY = inputHeight
+                - ResourceUtils.getKeyboardFrameHeight(res, settingsValues)
+                - suggestionsHeight;
         mSuggestionStripView.setMoreSuggestionsHeight(visibleTopY);
         // Need to set expanded touchable region only if a keyboard view is being shown.
         if (visibleKeyboardView.isShown()) {
             final int touchLeft = 0;
             final int touchTop = mKeyboardSwitcher.isShowingMoreKeysPanel() ? 0 : visibleTopY;
-            final int touchRight = visibleKeyboardView.getWidth();
+            final int touchRight = ResourceUtils.getKeyboardFrameWidth(res);
             final int touchBottom = inputHeight
                     // Extend touchable region below the keyboard.
                     + EXTENDED_TOUCHABLE_REGION_HEIGHT;
diff --git a/java/src/com/android/inputmethod/latin/settings/DebugSettings.java b/java/src/com/android/inputmethod/latin/settings/DebugSettings.java
index 6fffb8e..eff7bde 100644
--- a/java/src/com/android/inputmethod/latin/settings/DebugSettings.java
+++ b/java/src/com/android/inputmethod/latin/settings/DebugSettings.java
@@ -31,6 +31,9 @@
             "pref_has_custom_key_preview_animation_params";
     public static final String PREF_RESIZE_KEYBOARD = "pref_resize_keyboard";
     public static final String PREF_KEYBOARD_HEIGHT_SCALE = "pref_keyboard_height_scale";
+    public static final String PREF_KEYBOARD_BOTTOM_MARGIN = "pref_keyboard_bottom_margin";
+    public static final String PREF_KEYBOARD_LEFT_MARGIN = "pref_keyboard_left_margin";
+    public static final String PREF_KEYBOARD_RIGHT_MARGIN = "pref_keyboard_right_margin";
     public static final String PREF_KEY_PREVIEW_DISMISS_DURATION =
             "pref_key_preview_dismiss_duration";
     public static final String PREF_KEY_PREVIEW_DISMISS_END_X_SCALE =
diff --git a/java/src/com/android/inputmethod/latin/settings/DebugSettingsFragment.java b/java/src/com/android/inputmethod/latin/settings/DebugSettingsFragment.java
index b788d7f..779bf47 100644
--- a/java/src/com/android/inputmethod/latin/settings/DebugSettingsFragment.java
+++ b/java/src/com/android/inputmethod/latin/settings/DebugSettingsFragment.java
@@ -89,8 +89,14 @@
                 defaultKeyPreviewDismissEndScale);
         setupKeyPreviewAnimationScale(DebugSettings.PREF_KEY_PREVIEW_DISMISS_END_Y_SCALE,
                 defaultKeyPreviewDismissEndScale);
-        setupKeyboardHeight(
+        setupKeyboardScale(
                 DebugSettings.PREF_KEYBOARD_HEIGHT_SCALE, SettingsValues.DEFAULT_SIZE_SCALE);
+        setupKeyboardScale(
+            DebugSettings.PREF_KEYBOARD_BOTTOM_MARGIN, SettingsValues.DEFAULT_MARGIN_SCALE);
+        setupKeyboardScale(
+            DebugSettings.PREF_KEYBOARD_LEFT_MARGIN, SettingsValues.DEFAULT_MARGIN_SCALE);
+        setupKeyboardScale(
+            DebugSettings.PREF_KEYBOARD_RIGHT_MARGIN, SettingsValues.DEFAULT_MARGIN_SCALE);
 
         mServiceNeedsRestart = false;
         mDebugMode = (TwoStatePreference) findPreference(DebugSettings.PREF_DEBUG_MODE);
@@ -253,7 +259,7 @@
         });
     }
 
-    private void setupKeyboardHeight(final String prefKey, final float defaultValue) {
+    private void setupKeyboardScale(final String prefKey, final float defaultValue) {
         final SharedPreferences prefs = getSharedPreferences();
         final SeekBarDialogPreference pref = (SeekBarDialogPreference)findPreference(prefKey);
         if (pref == null) {
@@ -281,7 +287,8 @@
 
             @Override
             public int readValue(final String key) {
-                return getPercentageFromValue(Settings.readKeyboardHeight(prefs, defaultValue));
+                return getPercentageFromValue(
+                        Settings.readKeyboardScale(prefs, key, defaultValue));
             }
 
             @Override
diff --git a/java/src/com/android/inputmethod/latin/settings/Settings.java b/java/src/com/android/inputmethod/latin/settings/Settings.java
index 0d3dab5..196fef4 100644
--- a/java/src/com/android/inputmethod/latin/settings/Settings.java
+++ b/java/src/com/android/inputmethod/latin/settings/Settings.java
@@ -367,10 +367,9 @@
         return (milliseconds != UNDEFINED_PREFERENCE_VALUE_INT) ? milliseconds : defaultValue;
     }
 
-    public static float readKeyboardHeight(final SharedPreferences prefs,
-            final float defaultValue) {
-        final float percentage = prefs.getFloat(
-                DebugSettings.PREF_KEYBOARD_HEIGHT_SCALE, UNDEFINED_PREFERENCE_VALUE_FLOAT);
+    public static float readKeyboardScale(final SharedPreferences prefs,
+            final String prefKey, final float defaultValue) {
+        final float percentage = prefs.getFloat(prefKey, UNDEFINED_PREFERENCE_VALUE_FLOAT);
         return (percentage != UNDEFINED_PREFERENCE_VALUE_FLOAT) ? percentage : defaultValue;
     }
 
diff --git a/java/src/com/android/inputmethod/latin/settings/SettingsValues.java b/java/src/com/android/inputmethod/latin/settings/SettingsValues.java
index 5f1a7af..99e0565 100644
--- a/java/src/com/android/inputmethod/latin/settings/SettingsValues.java
+++ b/java/src/com/android/inputmethod/latin/settings/SettingsValues.java
@@ -50,6 +50,7 @@
     private static final String FLOAT_NEGATIVE_INFINITY_MARKER_STRING = "floatNegativeInfinity";
     private static final int TIMEOUT_TO_GET_TARGET_PACKAGE = 5; // seconds
     public static final float DEFAULT_SIZE_SCALE = 1.0f; // 100%
+    public static final float DEFAULT_MARGIN_SCALE = 0.0f; // 0%
 
     // From resources:
     public final SpacingAndPunctuations mSpacingAndPunctuations;
@@ -113,6 +114,9 @@
     public final boolean mHasCustomKeyPreviewAnimationParams;
     public final boolean mHasKeyboardResize;
     public final float mKeyboardHeightScale;
+    public final float mKeyboardBottomMarginScale;
+    public final float mKeyboardLeftMarginScale;
+    public final float mKeyboardRightMarginScale;
     public final int mKeyPreviewShowUpDuration;
     public final int mKeyPreviewDismissDuration;
     public final float mKeyPreviewShowUpStartXScale;
@@ -190,7 +194,14 @@
         mHasCustomKeyPreviewAnimationParams = prefs.getBoolean(
                 DebugSettings.PREF_HAS_CUSTOM_KEY_PREVIEW_ANIMATION_PARAMS, false);
         mHasKeyboardResize = prefs.getBoolean(DebugSettings.PREF_RESIZE_KEYBOARD, false);
-        mKeyboardHeightScale = Settings.readKeyboardHeight(prefs, DEFAULT_SIZE_SCALE);
+        mKeyboardHeightScale = Settings.readKeyboardScale(
+                prefs, DebugSettings.PREF_KEYBOARD_HEIGHT_SCALE, DEFAULT_SIZE_SCALE);
+        mKeyboardBottomMarginScale = Settings.readKeyboardScale(
+                prefs, DebugSettings.PREF_KEYBOARD_BOTTOM_MARGIN, DEFAULT_MARGIN_SCALE);
+        mKeyboardLeftMarginScale = Settings.readKeyboardScale(
+                prefs, DebugSettings.PREF_KEYBOARD_LEFT_MARGIN, DEFAULT_MARGIN_SCALE);
+        mKeyboardRightMarginScale = Settings.readKeyboardScale(
+                prefs, DebugSettings.PREF_KEYBOARD_RIGHT_MARGIN, DEFAULT_MARGIN_SCALE);
         mKeyPreviewShowUpDuration = Settings.readKeyPreviewAnimationDuration(
                 prefs, DebugSettings.PREF_KEY_PREVIEW_SHOW_UP_DURATION,
                 res.getInteger(R.integer.config_key_preview_show_up_duration));
diff --git a/java/src/com/android/inputmethod/latin/utils/DistracterFilterCheckingExactMatchesAndSuggestions.java b/java/src/com/android/inputmethod/latin/utils/DistracterFilterCheckingExactMatchesAndSuggestions.java
index 9c6a948..0c01a73 100644
--- a/java/src/com/android/inputmethod/latin/utils/DistracterFilterCheckingExactMatchesAndSuggestions.java
+++ b/java/src/com/android/inputmethod/latin/utils/DistracterFilterCheckingExactMatchesAndSuggestions.java
@@ -143,7 +143,7 @@
         final KeyboardLayoutSet.Builder builder = new KeyboardLayoutSet.Builder(
                 mContext, editorInfo);
         final Resources res = mContext.getResources();
-        final int keyboardWidth = ResourceUtils.getDefaultKeyboardWidth(res);
+        final int keyboardWidth = ResourceUtils.getKeyboardFrameWidth(res);
         final int keyboardHeight = ResourceUtils.getDefaultKeyboardHeight(res);
         builder.setKeyboardGeometry(keyboardWidth, keyboardHeight);
         builder.setSubtype(new RichInputMethodSubtype(subtype));
diff --git a/java/src/com/android/inputmethod/latin/utils/ResourceUtils.java b/java/src/com/android/inputmethod/latin/utils/ResourceUtils.java
index cc0d470..0a75787 100644
--- a/java/src/com/android/inputmethod/latin/utils/ResourceUtils.java
+++ b/java/src/com/android/inputmethod/latin/utils/ResourceUtils.java
@@ -182,18 +182,63 @@
         return matchedAll;
     }
 
-    public static int getDefaultKeyboardWidth(final Resources res) {
+    public static int getKeyboardFrameWidth(final Resources res) {
         final DisplayMetrics dm = res.getDisplayMetrics();
         return dm.widthPixels;
     }
 
-    public static int getKeyboardHeight(final Resources res, final SettingsValues settingsValues) {
-        final int defaultKeyboardHeight = getDefaultKeyboardHeight(res);
+    public static int getKeyboardWidth(final Resources res, final SettingsValues settingsValues) {
+        final int frameWidth = getKeyboardFrameWidth(res);
         if (settingsValues.mHasKeyboardResize) {
-            // mKeyboardHeightScale Ranges from [.5,1.2], from xml/prefs_screen_debug.xml
-            return (int)(defaultKeyboardHeight * settingsValues.mKeyboardHeightScale);
+            final float widthFraction = 1f - settingsValues.mKeyboardLeftMarginScale
+                    - settingsValues.mKeyboardRightMarginScale;
+            return (int)(frameWidth * widthFraction);
         }
-        return defaultKeyboardHeight;
+        return frameWidth;
+    }
+
+    public static int getKeyboardFrameHeight(final Resources res,
+            final SettingsValues settingsValues) {
+        if (settingsValues.mHasKeyboardResize) {
+            return getKeyboardHeight(res, settingsValues)
+                    + getKeyboardBottomMargin(res, settingsValues);
+        }
+        return getDefaultKeyboardHeight(res);
+    }
+
+    public static int getKeyboardHeight(final Resources res, final SettingsValues settingsValues) {
+        final int keyboardHeight = getDefaultKeyboardHeight(res);
+        if (settingsValues.mHasKeyboardResize) {
+            return (int)(keyboardHeight * settingsValues.mKeyboardHeightScale);
+        }
+        return keyboardHeight;
+    }
+
+    public static int getKeyboardLeftMargin(
+            final Resources res, final SettingsValues settingsValues) {
+        if (settingsValues.mHasKeyboardResize) {
+          final int frameWidth = getKeyboardFrameWidth(res);
+            return (int)(frameWidth * settingsValues.mKeyboardLeftMarginScale);
+        }
+        return 0;
+    }
+
+    public static int getKeyboardRightMargin(
+            final Resources res, final SettingsValues settingsValues) {
+        if (settingsValues.mHasKeyboardResize) {
+            final int frameWidth = getKeyboardFrameWidth(res);
+            return (int)(frameWidth * settingsValues.mKeyboardRightMarginScale);
+        }
+        return 0;
+    }
+
+    public static int getKeyboardBottomMargin(
+            final Resources res, final SettingsValues settingsValues) {
+        if (settingsValues.mHasKeyboardResize) {
+            final int defaultHeight = getDefaultKeyboardHeight(res);
+            return (int)(defaultHeight * settingsValues.mKeyboardBottomMarginScale);
+        }
+        return 0;
     }
 
     public static int getDefaultKeyboardHeight(final Resources res) {