diff --git a/java/res/values-land/dimens.xml b/java/res/values-land/dimens.xml
index c46a517119c52e25b64d0ea065ac4d98b1925446..496da3de11d0f0dadcef12e500ac876af90e2f4f 100644
--- a/java/res/values-land/dimens.xml
+++ b/java/res/values-land/dimens.xml
@@ -21,6 +21,7 @@
 <resources>
     <!-- keyboardHeight = key_height*4 + key_bottom_gap*3, key_height=0.260in -->
     <dimen name="keyboardHeight">1.100in</dimen>
+    <fraction name="minKeyboardHeight">45%p</fraction>
     <!-- key_height + key_bottom_gap = popup_key_height -->
 <!--    <dimen name="key_height">0.260in</dimen>-->
     <dimen name="key_bottom_gap">0.020in</dimen>
diff --git a/java/res/values/attrs.xml b/java/res/values/attrs.xml
index e88b007a96f6e65d04be2aa710523d7b70b84f32..7f2a400dff58f853299408675ce5720a3911cabf 100644
--- a/java/res/values/attrs.xml
+++ b/java/res/values/attrs.xml
@@ -80,6 +80,9 @@
         <attr name="keyboardHeight" format="dimension" />
         <!-- Maximum keyboard height, in pixels or percentage of display height -->
         <attr name="maxKeyboardHeight" format="dimension|fraction" />
+        <!-- Minimum keyboard height represented in pixels, percentage of display height if fraction
+             is positive, or percentage of display width if fraction is negative. -->
+        <attr name="minKeyboardHeight" format="dimension|fraction" />
         <!-- Default width of a key, in pixels or percentage of display width. -->
         <attr name="keyWidth" format="dimension|fraction" />
         <!-- Default height of a row (key height + vertical gap), in pixels or percentage of
diff --git a/java/res/values/dimens.xml b/java/res/values/dimens.xml
index 69f962f0093bcdbc282d1a983c8138a11277a58e..82abf3b05b2ca0624f12ed1931141e0b2fb38db0 100644
--- a/java/res/values/dimens.xml
+++ b/java/res/values/dimens.xml
@@ -21,6 +21,8 @@
 <resources>
     <!-- keyboardHeight = key_height*4 + key_bottom_gap*3, key_height=0.295in -->
     <dimen name="keyboardHeight">1.285in</dimen>
+    <fraction name="maxKeyboardHeight">50%p</fraction>
+    <fraction name="minKeyboardHeight">-61.8%p</fraction>
     <!-- key_height + key_bottom_gap = popup_key_height -->
     <!-- <dimen name="key_height">0.295in</dimen> -->
     <dimen name="key_bottom_gap">0.035in</dimen>
@@ -41,10 +43,11 @@
          to user's finger. -->
     <dimen name="keyboard_vertical_correction">-0.05in</dimen>
 
-    <dimen name="key_letter_size">0.13in</dimen>
-    <dimen name="key_label_text_size">0.083in</dimen>
+    <!-- TODO: use fraction for key letter size and etc. -->
+    <dimen name="key_letter_size">21dip</dimen>
+    <dimen name="key_label_text_size">13dip</dimen>
     <!-- left or right padding of label alignment -->
-    <dimen name="key_label_horizontal_alignment_padding">0.13in</dimen>
+    <dimen name="key_label_horizontal_alignment_padding">21dip</dimen>
     <dimen name="key_preview_height">80sp</dimen>
     <dimen name="key_preview_offset">0.000in</dimen>
     <dimen name="key_preview_text_size_large">36sp</dimen>
diff --git a/java/res/xml-ar/kbd_qwerty.xml b/java/res/xml-ar/kbd_qwerty.xml
index 5faf603369e5192f2f82fa7b0cd863048f191e2e..93310bf9c069281442cd2543536df42feb8f88a0 100644
--- a/java/res/xml-ar/kbd_qwerty.xml
+++ b/java/res/xml-ar/kbd_qwerty.xml
@@ -21,7 +21,8 @@
 <Keyboard
     xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
     latin:keyboardHeight="@dimen/keyboardHeight"
-    latin:maxKeyboardHeight="50%p"
+    latin:maxKeyboardHeight="@fraction/maxKeyboardHeight"
+    latin:minKeyboardHeight="@fraction/minKeyboardHeight"
     latin:rowHeight="25%p"
     latin:keyWidth="10%p"
     latin:horizontalGap="@dimen/key_horizontal_gap"
diff --git a/java/res/xml-cs/kbd_qwerty.xml b/java/res/xml-cs/kbd_qwerty.xml
index 0e6e40d7c9f0f97b7ad9de6122d885ed340789d3..a74f7fa845f5c10a529810bb3a0308a2476ea7be 100644
--- a/java/res/xml-cs/kbd_qwerty.xml
+++ b/java/res/xml-cs/kbd_qwerty.xml
@@ -21,7 +21,8 @@
 <Keyboard
     xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
     latin:keyboardHeight="@dimen/keyboardHeight"
-    latin:maxKeyboardHeight="50%p"
+    latin:maxKeyboardHeight="@fraction/maxKeyboardHeight"
+    latin:minKeyboardHeight="@fraction/minKeyboardHeight"
     latin:rowHeight="25%p"
     latin:keyWidth="10%p"
     latin:horizontalGap="@dimen/key_horizontal_gap"
diff --git a/java/res/xml-da/kbd_qwerty.xml b/java/res/xml-da/kbd_qwerty.xml
index d9847ae834f1a60cbd2cbbdb9749db8e813da274..12ea33c13c8a0634e49403ce0c57bfbc5ae26f7a 100644
--- a/java/res/xml-da/kbd_qwerty.xml
+++ b/java/res/xml-da/kbd_qwerty.xml
@@ -21,7 +21,8 @@
 <Keyboard
     xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
     latin:keyboardHeight="@dimen/keyboardHeight"
-    latin:maxKeyboardHeight="50%p"
+    latin:maxKeyboardHeight="@fraction/maxKeyboardHeight"
+    latin:minKeyboardHeight="@fraction/minKeyboardHeight"
     latin:rowHeight="25%p"
     latin:horizontalGap="@dimen/key_horizontal_gap"
     latin:verticalGap="@dimen/key_bottom_gap"
diff --git a/java/res/xml-de/kbd_qwerty.xml b/java/res/xml-de/kbd_qwerty.xml
index e6569667d87c21d74de3f11ff078fe76bc29c207..6ad25b75c78bf2459db8625c7a12c7bd605c1013 100644
--- a/java/res/xml-de/kbd_qwerty.xml
+++ b/java/res/xml-de/kbd_qwerty.xml
@@ -21,7 +21,8 @@
 <Keyboard
     xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
     latin:keyboardHeight="@dimen/keyboardHeight"
-    latin:maxKeyboardHeight="50%p"
+    latin:maxKeyboardHeight="@fraction/maxKeyboardHeight"
+    latin:minKeyboardHeight="@fraction/minKeyboardHeight"
     latin:rowHeight="25%p"
     latin:keyWidth="10%p"
     latin:horizontalGap="@dimen/key_horizontal_gap"
diff --git a/java/res/xml-fi/kbd_qwerty.xml b/java/res/xml-fi/kbd_qwerty.xml
index ea08d670be1c9871f7998598e1e7de70e1a87948..e35ab2b41860ecc175c40e2e2e1e866e83a36ad4 100644
--- a/java/res/xml-fi/kbd_qwerty.xml
+++ b/java/res/xml-fi/kbd_qwerty.xml
@@ -21,7 +21,8 @@
 <Keyboard
     xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
     latin:keyboardHeight="@dimen/keyboardHeight"
-    latin:maxKeyboardHeight="50%p"
+    latin:maxKeyboardHeight="@fraction/maxKeyboardHeight"
+    latin:minKeyboardHeight="@fraction/minKeyboardHeight"
     latin:rowHeight="25%p"
     latin:horizontalGap="@dimen/key_horizontal_gap"
     latin:verticalGap="@dimen/key_bottom_gap"
diff --git a/java/res/xml-fr-rCA/kbd_qwerty.xml b/java/res/xml-fr-rCA/kbd_qwerty.xml
index f9c29698bd1aa9444efc9c2b6abf2d1e96fcb511..e649a1e9cd61909e8555deace7d38eec9bb76916 100644
--- a/java/res/xml-fr-rCA/kbd_qwerty.xml
+++ b/java/res/xml-fr-rCA/kbd_qwerty.xml
@@ -21,7 +21,8 @@
 <Keyboard
     xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
     latin:keyboardHeight="@dimen/keyboardHeight"
-    latin:maxKeyboardHeight="50%p"
+    latin:maxKeyboardHeight="@fraction/maxKeyboardHeight"
+    latin:minKeyboardHeight="@fraction/minKeyboardHeight"
     latin:rowHeight="25%p"
     latin:keyWidth="10%p"
     latin:horizontalGap="@dimen/key_horizontal_gap"
diff --git a/java/res/xml-fr-rCH/kbd_qwerty.xml b/java/res/xml-fr-rCH/kbd_qwerty.xml
index e47cfd9b4af3709fad7d28e3cbfbc5109100fedf..f82becb488507d42a33a9d6ff3680255683b63b0 100644
--- a/java/res/xml-fr-rCH/kbd_qwerty.xml
+++ b/java/res/xml-fr-rCH/kbd_qwerty.xml
@@ -21,7 +21,8 @@
 <Keyboard
     xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
     latin:keyboardHeight="@dimen/keyboardHeight"
-    latin:maxKeyboardHeight="50%p"
+    latin:maxKeyboardHeight="@fraction/maxKeyboardHeight"
+    latin:minKeyboardHeight="@fraction/minKeyboardHeight"
     latin:rowHeight="25%p"
     latin:keyWidth="10%p"
     latin:horizontalGap="@dimen/key_horizontal_gap"
diff --git a/java/res/xml-fr/kbd_qwerty.xml b/java/res/xml-fr/kbd_qwerty.xml
index 2f8e67bb187550631f1f7a029bdf6b1e7d1d518c..bda69e8074abd8b06949c5c7ecd079cd3ad369ca 100644
--- a/java/res/xml-fr/kbd_qwerty.xml
+++ b/java/res/xml-fr/kbd_qwerty.xml
@@ -21,7 +21,8 @@
 <Keyboard
     xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
     latin:keyboardHeight="@dimen/keyboardHeight"
-    latin:maxKeyboardHeight="50%p"
+    latin:maxKeyboardHeight="@fraction/maxKeyboardHeight"
+    latin:minKeyboardHeight="@fraction/minKeyboardHeight"
     latin:rowHeight="25%p"
     latin:keyWidth="10%p"
     latin:horizontalGap="@dimen/key_horizontal_gap"
diff --git a/java/res/xml-hu/kbd_qwerty.xml b/java/res/xml-hu/kbd_qwerty.xml
index db729cf0202d1075a0122909ff3b3e81088cd55a..952ad9a0f489706af7f1b29b774b05e18899f4a7 100644
--- a/java/res/xml-hu/kbd_qwerty.xml
+++ b/java/res/xml-hu/kbd_qwerty.xml
@@ -21,7 +21,8 @@
 <Keyboard
     xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
     latin:keyboardHeight="@dimen/keyboardHeight"
-    latin:maxKeyboardHeight="50%p"
+    latin:maxKeyboardHeight="@fraction/maxKeyboardHeight"
+    latin:minKeyboardHeight="@fraction/minKeyboardHeight"
     latin:rowHeight="25%p"
     latin:keyWidth="10%p"
     latin:horizontalGap="@dimen/key_horizontal_gap"
diff --git a/java/res/xml-iw/kbd_qwerty.xml b/java/res/xml-iw/kbd_qwerty.xml
index 4cd565b88362be9e191365a5ebdc9cc79d461226..cfe404c9d7fe6171447087750f4b4562295ff82a 100644
--- a/java/res/xml-iw/kbd_qwerty.xml
+++ b/java/res/xml-iw/kbd_qwerty.xml
@@ -21,7 +21,8 @@
 <Keyboard
     xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
     latin:keyboardHeight="@dimen/keyboardHeight"
-    latin:maxKeyboardHeight="50%p"
+    latin:maxKeyboardHeight="@fraction/maxKeyboardHeight"
+    latin:minKeyboardHeight="@fraction/minKeyboardHeight"
     latin:rowHeight="25%p"
     latin:keyWidth="10%p"
     latin:horizontalGap="@dimen/key_horizontal_gap"
diff --git a/java/res/xml-nb/kbd_qwerty.xml b/java/res/xml-nb/kbd_qwerty.xml
index 7b20ca28d89cf74d693537eca83cd3dc107da2a1..e7a743ca9c1ee02bf3f9c6346a432fa5bb6ab218 100644
--- a/java/res/xml-nb/kbd_qwerty.xml
+++ b/java/res/xml-nb/kbd_qwerty.xml
@@ -21,7 +21,8 @@
 <Keyboard
     xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
     latin:keyboardHeight="@dimen/keyboardHeight"
-    latin:maxKeyboardHeight="50%p"
+    latin:maxKeyboardHeight="@fraction/maxKeyboardHeight"
+    latin:minKeyboardHeight="@fraction/minKeyboardHeight"
     latin:rowHeight="25%p"
     latin:horizontalGap="@dimen/key_horizontal_gap"
     latin:verticalGap="@dimen/key_bottom_gap"
diff --git a/java/res/xml-ru/kbd_qwerty.xml b/java/res/xml-ru/kbd_qwerty.xml
index e5aea581eb512f7751997bf01143f01bbb1bdf18..0f5fdcd0acdbd2cf776d33a4a65dc5b35939f4ae 100644
--- a/java/res/xml-ru/kbd_qwerty.xml
+++ b/java/res/xml-ru/kbd_qwerty.xml
@@ -21,7 +21,8 @@
 <Keyboard
     xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
     latin:keyboardHeight="@dimen/keyboardHeight"
-    latin:maxKeyboardHeight="50%p"
+    latin:maxKeyboardHeight="@fraction/maxKeyboardHeight"
+    latin:minKeyboardHeight="@fraction/minKeyboardHeight"
     latin:rowHeight="25%p"
     latin:horizontalGap="@dimen/key_horizontal_gap"
     latin:verticalGap="@dimen/key_bottom_gap"
diff --git a/java/res/xml-sr/kbd_qwerty.xml b/java/res/xml-sr/kbd_qwerty.xml
index 9782cd5eba41eaff6f9a7dc5c8b01b8f1892a593..6116c7536ec2ba955c6a4ba4b01bcf6442a0b5c5 100644
--- a/java/res/xml-sr/kbd_qwerty.xml
+++ b/java/res/xml-sr/kbd_qwerty.xml
@@ -21,7 +21,8 @@
 <Keyboard
     xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
     latin:keyboardHeight="@dimen/keyboardHeight"
-    latin:maxKeyboardHeight="50%p"
+    latin:maxKeyboardHeight="@fraction/maxKeyboardHeight"
+    latin:minKeyboardHeight="@fraction/minKeyboardHeight"
     latin:rowHeight="25%p"
     latin:horizontalGap="@dimen/key_horizontal_gap"
     latin:verticalGap="@dimen/key_bottom_gap"
diff --git a/java/res/xml-sv/kbd_qwerty.xml b/java/res/xml-sv/kbd_qwerty.xml
index 3ff1679a21eb2cd95fb220dcd98cc8bec001e1c9..69f0b3fa090c291fbc346413ef66832553f3321c 100644
--- a/java/res/xml-sv/kbd_qwerty.xml
+++ b/java/res/xml-sv/kbd_qwerty.xml
@@ -21,7 +21,8 @@
 <Keyboard
     xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
     latin:keyboardHeight="@dimen/keyboardHeight"
-    latin:maxKeyboardHeight="50%p"
+    latin:maxKeyboardHeight="@fraction/maxKeyboardHeight"
+    latin:minKeyboardHeight="@fraction/minKeyboardHeight"
     latin:rowHeight="25%p"
     latin:horizontalGap="@dimen/key_horizontal_gap"
     latin:verticalGap="@dimen/key_bottom_gap"
diff --git a/java/res/xml-xlarge/kbd_number.xml b/java/res/xml-xlarge/kbd_number.xml
index 012b751159d09542677bcf6c120b81dd3d844263..7cb77ea001b80571bdc572690d3c0bd648ef4e88 100644
--- a/java/res/xml-xlarge/kbd_number.xml
+++ b/java/res/xml-xlarge/kbd_number.xml
@@ -21,7 +21,8 @@
 <Keyboard
     xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
     latin:keyboardHeight="@dimen/keyboardHeight"
-    latin:maxKeyboardHeight="50%p"
+    latin:maxKeyboardHeight="@fraction/maxKeyboardHeight"
+    latin:minKeyboardHeight="@fraction/minKeyboardHeight"
     latin:rowHeight="25%p"
     latin:keyWidth="11.949%p"
     latin:horizontalGap="@dimen/key_horizontal_gap"
diff --git a/java/res/xml-xlarge/kbd_phone.xml b/java/res/xml-xlarge/kbd_phone.xml
index 9122176a96343a0bae8cc263aa6fee9de6ef9e96..60edcf2bdf82d00dd18f78c7ad6694106b49a5ad 100644
--- a/java/res/xml-xlarge/kbd_phone.xml
+++ b/java/res/xml-xlarge/kbd_phone.xml
@@ -21,7 +21,8 @@
 <Keyboard
     xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
     latin:keyboardHeight="@dimen/keyboardHeight"
-    latin:maxKeyboardHeight="50%p"
+    latin:maxKeyboardHeight="@fraction/maxKeyboardHeight"
+    latin:minKeyboardHeight="@fraction/minKeyboardHeight"
     latin:rowHeight="25%p"
     latin:keyWidth="11.949%p"
     latin:horizontalGap="@dimen/key_horizontal_gap"
diff --git a/java/res/xml-xlarge/kbd_phone_symbols.xml b/java/res/xml-xlarge/kbd_phone_symbols.xml
index 055c148674631a239d94f34e734213fcd7e3b2bd..c388a466722477a4d30c8e6435f1760801c5ece3 100644
--- a/java/res/xml-xlarge/kbd_phone_symbols.xml
+++ b/java/res/xml-xlarge/kbd_phone_symbols.xml
@@ -21,7 +21,8 @@
 <Keyboard
     xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
     latin:keyboardHeight="@dimen/keyboardHeight"
-    latin:maxKeyboardHeight="50%p"
+    latin:maxKeyboardHeight="@fraction/maxKeyboardHeight"
+    latin:minKeyboardHeight="@fraction/minKeyboardHeight"
     latin:rowHeight="25%p"
     latin:keyWidth="11.949%p"
     latin:horizontalGap="@dimen/key_horizontal_gap"
diff --git a/java/res/xml-xlarge/kbd_symbols.xml b/java/res/xml-xlarge/kbd_symbols.xml
index f1deae0f9731000eb2b77672ee7b174a229ea5a0..3b9a6b280ad10d6b3c3822179c350b014a316779 100644
--- a/java/res/xml-xlarge/kbd_symbols.xml
+++ b/java/res/xml-xlarge/kbd_symbols.xml
@@ -21,7 +21,8 @@
 <Keyboard
     xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
     latin:keyboardHeight="@dimen/keyboardHeight"
-    latin:maxKeyboardHeight="50%p"
+    latin:maxKeyboardHeight="@fraction/maxKeyboardHeight"
+    latin:minKeyboardHeight="@fraction/minKeyboardHeight"
     latin:rowHeight="25%p"
     latin:horizontalGap="@dimen/key_horizontal_gap"
     latin:verticalGap="@dimen/key_bottom_gap"
diff --git a/java/res/xml-xlarge/kbd_symbols_shift.xml b/java/res/xml-xlarge/kbd_symbols_shift.xml
index cc23358a52b670bf15587d2997e9cac92ab7d62b..d7f5958b7f0dacc6fd50e06dd7d23c9ba0895591 100644
--- a/java/res/xml-xlarge/kbd_symbols_shift.xml
+++ b/java/res/xml-xlarge/kbd_symbols_shift.xml
@@ -21,7 +21,8 @@
 <Keyboard
     xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
     latin:keyboardHeight="@dimen/keyboardHeight"
-    latin:maxKeyboardHeight="50%p"
+    latin:maxKeyboardHeight="@fraction/maxKeyboardHeight"
+    latin:minKeyboardHeight="@fraction/minKeyboardHeight"
     latin:rowHeight="25%p"
     latin:horizontalGap="@dimen/key_horizontal_gap"
     latin:verticalGap="@dimen/key_bottom_gap"
diff --git a/java/res/xml/kbd_number.xml b/java/res/xml/kbd_number.xml
index 7bd679bce529957d6b156c1fbcac71606cf05162..2556f6830068a20a713e9738db0fc044efa3b830 100644
--- a/java/res/xml/kbd_number.xml
+++ b/java/res/xml/kbd_number.xml
@@ -21,7 +21,8 @@
 <Keyboard
     xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
     latin:keyboardHeight="@dimen/keyboardHeight"
-    latin:maxKeyboardHeight="50%p"
+    latin:maxKeyboardHeight="@fraction/maxKeyboardHeight"
+    latin:minKeyboardHeight="@fraction/minKeyboardHeight"
     latin:rowHeight="25%p"
     latin:keyWidth="26.67%p"
     latin:horizontalGap="@dimen/key_horizontal_gap"
diff --git a/java/res/xml/kbd_phone.xml b/java/res/xml/kbd_phone.xml
index 62fbdeeec84235ff0eae3657bacad068559cacd6..ca591c72d37955c2f7af339edd532cf9b08d4fab 100644
--- a/java/res/xml/kbd_phone.xml
+++ b/java/res/xml/kbd_phone.xml
@@ -21,7 +21,8 @@
 <Keyboard
     xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
     latin:keyboardHeight="@dimen/keyboardHeight"
-    latin:maxKeyboardHeight="50%p"
+    latin:maxKeyboardHeight="@fraction/maxKeyboardHeight"
+    latin:minKeyboardHeight="@fraction/minKeyboardHeight"
     latin:rowHeight="25%p"
     latin:keyWidth="26.67%p"
     latin:horizontalGap="@dimen/key_horizontal_gap"
diff --git a/java/res/xml/kbd_phone_symbols.xml b/java/res/xml/kbd_phone_symbols.xml
index 67cd330e779b87e5cbc2ec9eada90e919376400b..99db23ef1bf2adec3258d11c032f3335eb7ff89d 100644
--- a/java/res/xml/kbd_phone_symbols.xml
+++ b/java/res/xml/kbd_phone_symbols.xml
@@ -21,7 +21,8 @@
 <Keyboard
     xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
     latin:keyboardHeight="@dimen/keyboardHeight"
-    latin:maxKeyboardHeight="50%p"
+    latin:maxKeyboardHeight="@fraction/maxKeyboardHeight"
+    latin:minKeyboardHeight="@fraction/minKeyboardHeight"
     latin:rowHeight="25%p"
     latin:keyWidth="26.67%p"
     latin:horizontalGap="@dimen/key_horizontal_gap"
diff --git a/java/res/xml/kbd_qwerty.xml b/java/res/xml/kbd_qwerty.xml
index a4251c0bdcc3328e60c96490044b94e743860689..fd43740a736c99725ac71cc96839d9465cad7979 100644
--- a/java/res/xml/kbd_qwerty.xml
+++ b/java/res/xml/kbd_qwerty.xml
@@ -21,7 +21,8 @@
 <Keyboard
     xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
     latin:keyboardHeight="@dimen/keyboardHeight"
-    latin:maxKeyboardHeight="50%p"
+    latin:maxKeyboardHeight="@fraction/maxKeyboardHeight"
+    latin:minKeyboardHeight="@fraction/minKeyboardHeight"
     latin:rowHeight="25%p"
     latin:keyWidth="10%p"
     latin:horizontalGap="@dimen/key_horizontal_gap"
diff --git a/java/res/xml/kbd_symbols.xml b/java/res/xml/kbd_symbols.xml
index 9748bce8b4346e75d829a45b38d3a03c8ae9f5a3..a1bd8c04b8ae325c942cdf1d0bb70825cc375e13 100644
--- a/java/res/xml/kbd_symbols.xml
+++ b/java/res/xml/kbd_symbols.xml
@@ -21,7 +21,8 @@
 <Keyboard
     xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
     latin:keyboardHeight="@dimen/keyboardHeight"
-    latin:maxKeyboardHeight="50%p"
+    latin:maxKeyboardHeight="@fraction/maxKeyboardHeight"
+    latin:minKeyboardHeight="@fraction/minKeyboardHeight"
     latin:rowHeight="25%p"
     latin:keyWidth="10%p"
     latin:horizontalGap="@dimen/key_horizontal_gap"
diff --git a/java/res/xml/kbd_symbols_shift.xml b/java/res/xml/kbd_symbols_shift.xml
index 3978f177673d7c3dd3e67b7cbf6f80dbb1928cfa..cde07333b54a434c8cf3f87963dfb90c60840ab9 100644
--- a/java/res/xml/kbd_symbols_shift.xml
+++ b/java/res/xml/kbd_symbols_shift.xml
@@ -21,7 +21,8 @@
 <Keyboard
     xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
     latin:keyboardHeight="@dimen/keyboardHeight"
-    latin:maxKeyboardHeight="50%p"
+    latin:maxKeyboardHeight="@fraction/maxKeyboardHeight"
+    latin:minKeyboardHeight="@fraction/minKeyboardHeight"
     latin:rowHeight="25%p"
     latin:keyWidth="10%p"
     latin:horizontalGap="@dimen/key_horizontal_gap"
diff --git a/java/src/com/android/inputmethod/keyboard/Key.java b/java/src/com/android/inputmethod/keyboard/Key.java
index 5c59d4441cde7aba3761829ee1ed094c3e8d5769..33b55b5d39573019dc19495f3b1d70cbc11eee55 100644
--- a/java/src/com/android/inputmethod/keyboard/Key.java
+++ b/java/src/com/android/inputmethod/keyboard/Key.java
@@ -143,9 +143,9 @@ public class Key {
      * This constructor is being used only for key in mini popup keyboard.
      */
     public Key(Resources res, Keyboard keyboard, CharSequence popupCharacter, int x, int y,
-            int width, int edgeFlags) {
+            int width, int height, int edgeFlags) {
         mKeyboard = keyboard;
-        mHeight = keyboard.getRowHeight() - keyboard.getVerticalGap();
+        mHeight = height - keyboard.getVerticalGap();
         mGap = keyboard.getHorizontalGap();
         mVisualInsetsLeft = mVisualInsetsRight = 0;
         mWidth = width - mGap;
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardParser.java b/java/src/com/android/inputmethod/keyboard/KeyboardParser.java
index 69ae7886a25814e5b0e3cb1ec65bb56cacca5c3f..31fd0bfa3296a4dd9921ef2937d068abe4b3e56d 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardParser.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardParser.java
@@ -196,9 +196,20 @@ public class KeyboardParser {
             final int keyboardHeight = (int)keyboardAttr.getDimension(
                     R.styleable.Keyboard_keyboardHeight, displayHeight / 2);
             final int maxKeyboardHeight = getDimensionOrFraction(keyboardAttr,
-                    R.styleable.Keyboard_maxKeyboardHeight, displayHeight,  displayHeight / 2);
-            // Keyboard height will not exceed maxKeyboardHeight.
-            final int height = Math.min(keyboardHeight, maxKeyboardHeight);
+                    R.styleable.Keyboard_maxKeyboardHeight, displayHeight, displayHeight / 2);
+            int minKeyboardHeight = getDimensionOrFraction(keyboardAttr,
+                    R.styleable.Keyboard_minKeyboardHeight, displayHeight, displayHeight / 2);
+            if (minKeyboardHeight < 0) {
+                // Specified fraction was negative, so it should be calculated against display
+                // width.
+                final int displayWidth = keyboard.getDisplayWidth();
+                minKeyboardHeight = -getDimensionOrFraction(keyboardAttr,
+                        R.styleable.Keyboard_minKeyboardHeight, displayWidth, displayWidth / 2);
+            }
+            // Keyboard height will not exceed maxKeyboardHeight and will not be less than
+            // minKeyboardHeight.
+            final int height = Math.max(
+                    Math.min(keyboardHeight, maxKeyboardHeight), minKeyboardHeight);
             final int width = keyboard.getDisplayWidth();
 
             keyboard.setKeyboardHeight(height);
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardView.java b/java/src/com/android/inputmethod/keyboard/KeyboardView.java
index c551ed49f7e9e35f50d2a9084b24ad24c3e8e4e0..bbda4009fa5f75c3fdddf8a52e660b1e1627b96c 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardView.java
@@ -1078,7 +1078,7 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
         });
 
         final Keyboard keyboard = new MiniKeyboardBuilder(this, mKeyboard.getPopupKeyboardResId(),
-                parentKey).build();
+                parentKey, mKeyboard).build();
         miniKeyboardView.setKeyboard(keyboard);
 
         container.measure(MeasureSpec.makeMeasureSpec(getWidth(), MeasureSpec.AT_MOST),
diff --git a/java/src/com/android/inputmethod/keyboard/MiniKeyboardBuilder.java b/java/src/com/android/inputmethod/keyboard/MiniKeyboardBuilder.java
index e540fa106e1545337b08823d733a66f3bea91028..2b83c3ff5c6628d7b8708cee8f6725643f0b5510 100644
--- a/java/src/com/android/inputmethod/keyboard/MiniKeyboardBuilder.java
+++ b/java/src/com/android/inputmethod/keyboard/MiniKeyboardBuilder.java
@@ -181,7 +181,8 @@ public class MiniKeyboardBuilder {
         }
     }
 
-    public MiniKeyboardBuilder(KeyboardView view, int layoutTemplateResId, Key parentKey) {
+    public MiniKeyboardBuilder(KeyboardView view, int layoutTemplateResId, Key parentKey,
+            Keyboard parentKeyboard) {
         final Context context = view.getContext();
         mRes = context.getResources();
         final MiniKeyboard keyboard = new MiniKeyboard(context, layoutTemplateResId, null);
@@ -191,12 +192,13 @@ public class MiniKeyboardBuilder {
         final int keyWidth = getMaxKeyWidth(view, mPopupCharacters, keyboard.getKeyWidth());
         final MiniKeyboardLayoutParams params = new MiniKeyboardLayoutParams(
                 mPopupCharacters.length, parentKey.mMaxPopupColumn,
-                keyWidth, keyboard.getRowHeight(),
+                keyWidth, parentKeyboard.getRowHeight(),
                 parentKey.mX + (parentKey.mWidth + parentKey.mGap) / 2 - keyWidth / 2,
                 view.getMeasuredWidth());
         mParams = params;
 
-        keyboard.setHeight(params.mNumRows * params.mRowHeight - keyboard.getVerticalGap());
+        keyboard.setRowHeight(params.mRowHeight);
+        keyboard.setHeight(params.mNumRows * params.mRowHeight);
         keyboard.setMinWidth(params.mNumColumns * params.mKeyWidth);
         keyboard.setDefaultCoordX(params.getDefaultKeyCoordX() + params.mKeyWidth / 2);
     }
@@ -235,7 +237,7 @@ public class MiniKeyboardBuilder {
             final CharSequence label = mPopupCharacters[n];
             final int row = n / params.mNumColumns;
             final Key key = new Key(mRes, keyboard, label, params.getX(n, row), params.getY(row),
-                    params.mKeyWidth, params.getRowFlags(row));
+                    params.mKeyWidth, params.mRowHeight, params.getRowFlags(row));
             keys.add(key);
         }
         return keyboard;