Merge "[Rlog27] Add replay capability"
diff --git a/java/res/values/attrs.xml b/java/res/values/attrs.xml
index 5b38987..3a7b39e 100644
--- a/java/res/values/attrs.xml
+++ b/java/res/values/attrs.xml
@@ -173,18 +173,18 @@
         <attr name="themeId" format="integer" />
         <!-- Touch position correction -->
         <attr name="touchPositionCorrectionData" format="reference" />
-        <!-- Keyboard top, bottom, both horizontal edges paddings. -->
-        <attr name="keyboardTopPadding" format="dimension|fraction" />
-        <attr name="keyboardBottomPadding" format="dimension|fraction" />
-        <attr name="keyboardHorizontalEdgesPadding" format="dimension|fraction" />
-        <!-- Default height of a row (key height + vertical gap), in pixels or percentage of
+        <!-- Keyboard top, bottom, left, right edges paddings, in propotion of keyboard height. -->
+        <attr name="keyboardTopPadding" format="fraction" />
+        <attr name="keyboardBottomPadding" format="fraction" />
+        <attr name="keyboardLeftPadding" format="fraction" />
+        <attr name="keyboardRightPadding" format="fraction" />
+        <!-- Default height of a row (key height + vertical gap), in pixels or in the proportion of
              keyboard height. -->
         <attr name="rowHeight" format="dimension|fraction" />
-        <!-- Default horizontal gap between keys, in pixels or percentage of keyboard width. -->
-        <attr name="horizontalGap" format="dimension|fraction" />
-        <!-- Default vertical gap between rows of keys, in pixels or percentage of keyboard
-             height. -->
-        <attr name="verticalGap" format="dimension|fraction" />
+        <!-- Default horizontal gap between keys, in the proportion of keyboard width. -->
+        <attr name="horizontalGap" format="fraction" />
+        <!-- Default vertical gap between rows of keys, in the proportion of keyboard height. -->
+        <attr name="verticalGap" format="fraction" />
         <!-- More keys keyboard layout template -->
         <attr name="moreKeysTemplate" format="reference" />
         <!-- Icon set for key top and key preview.
@@ -288,19 +288,20 @@
         <attr name="keyIconPreview" format="string" />
         <!-- The key style to specify a set of key attributes defined by <key_style/> -->
         <attr name="keyStyle" format="string" />
-        <!-- Visual insets -->
-        <attr name="visualInsetsLeft" format="dimension|fraction" />
-        <attr name="visualInsetsRight" format="dimension|fraction" />
-        <!-- Width of the key, in pixels or percentage of display width.
-             If the value is fillRight, the actual key width will be determined to fill out the area
-             up to the right edge of the keyboard. -->
+        <!-- Visual insets, in the proportion of keyboard width. -->
+        <attr name="visualInsetsLeft" format="fraction" />
+        <attr name="visualInsetsRight" format="fraction" />
+        <!-- Width of the key, in the proportion of keyboard width.
+             If the value is fillRight, the actual key width will be determined to fill out the
+             area up to the right edge of the keyboard. -->
         <!-- This should be aligned with KeyboardBuilder.Row.KEYWIDTH_* -->
-        <attr name="keyWidth" format="dimension|fraction|enum">
+        <attr name="keyWidth" format="fraction|enum">
             <enum name="fillRight" value="-1" />
         </attr>
-        <!-- The X-coordinate of upper right corner of this key including horizontal gap.
+        <!-- The X-coordinate of upper right corner of this key including horizontal gap, in the
+             proportion of keyboard width.
              If the value is negative, the origin is the right edge of the keyboard. -->
-        <attr name="keyXPos" format="dimension|fraction" />
+        <attr name="keyXPos" format="fraction" />
 
         <!-- Key top visual attributes -->
         <attr name="keyTypeface" format="enum">
diff --git a/java/res/values/dimens.xml b/java/res/values/dimens.xml
index eb0934c..dd42acf 100644
--- a/java/res/values/dimens.xml
+++ b/java/res/values/dimens.xml
@@ -31,7 +31,8 @@
 
     <fraction name="keyboard_top_padding">1.556%p</fraction>
     <fraction name="keyboard_bottom_padding">4.669%p</fraction>
-    <fraction name="keyboard_horizontal_edges_padding">0%p</fraction>
+    <fraction name="keyboard_left_padding">0%p</fraction>
+    <fraction name="keyboard_right_padding">0%p</fraction>
     <fraction name="key_bottom_gap">6.250%p</fraction>
     <fraction name="key_horizontal_gap">1.352%p</fraction>
 
diff --git a/java/res/values/styles.xml b/java/res/values/styles.xml
index 19d6da8..fb59c74 100644
--- a/java/res/values/styles.xml
+++ b/java/res/values/styles.xml
@@ -24,7 +24,8 @@
         <item name="moreKeysTemplate">@xml/kbd_more_keys_keyboard_template</item>
         <item name="keyboardTopPadding">@fraction/keyboard_top_padding</item>
         <item name="keyboardBottomPadding">@fraction/keyboard_bottom_padding</item>
-        <item name="keyboardHorizontalEdgesPadding">@fraction/keyboard_horizontal_edges_padding</item>
+        <item name="keyboardLeftPadding">@fraction/keyboard_left_padding</item>
+        <item name="keyboardRightPadding">@fraction/keyboard_right_padding</item>
         <item name="horizontalGap">@fraction/key_horizontal_gap</item>
         <item name="verticalGap">@fraction/key_bottom_gap</item>
         <item name="maxMoreKeysColumn">@integer/config_max_more_keys_column</item>
@@ -119,9 +120,9 @@
         name="MoreKeysKeyboard"
         parent="Keyboard"
     >
-        <item name="keyboardTopPadding">0dp</item>
-        <item name="keyboardBottomPadding">0dp</item>
-        <item name="horizontalGap">0dp</item>
+        <item name="keyboardTopPadding">0%p</item>
+        <item name="keyboardBottomPadding">0%p</item>
+        <item name="horizontalGap">0%p</item>
         <item name="touchPositionCorrectionData">@null</item>
     </style>
     <style
@@ -224,9 +225,9 @@
         name="MoreKeysKeyboard.Stone"
         parent="Keyboard.Stone"
     >
-        <item name="keyboardTopPadding">0dp</item>
-        <item name="keyboardBottomPadding">0dp</item>
-        <item name="horizontalGap">0dp</item>
+        <item name="keyboardTopPadding">0%p</item>
+        <item name="keyboardBottomPadding">0%p</item>
+        <item name="horizontalGap">0%p</item>
         <item name="touchPositionCorrectionData">@null</item>
     </style>
     <style
@@ -294,9 +295,9 @@
         name="MoreKeysKeyboard.Gingerbread"
         parent="Keyboard.Gingerbread"
     >
-        <item name="keyboardTopPadding">0dp</item>
-        <item name="keyboardBottomPadding">0dp</item>
-        <item name="horizontalGap">0dp</item>
+        <item name="keyboardTopPadding">0%p</item>
+        <item name="keyboardBottomPadding">0%p</item>
+        <item name="horizontalGap">0%p</item>
         <item name="touchPositionCorrectionData">@null</item>
     </style>
     <style
@@ -353,9 +354,9 @@
         name="MoreKeysKeyboard.IceCreamSandwich"
         parent="Keyboard.IceCreamSandwich"
     >
-        <item name="keyboardTopPadding">0dp</item>
-        <item name="keyboardBottomPadding">0dp</item>
-        <item name="horizontalGap">0dp</item>
+        <item name="keyboardTopPadding">0%p</item>
+        <item name="keyboardBottomPadding">0%p</item>
+        <item name="horizontalGap">0%p</item>
         <item name="touchPositionCorrectionData">@null</item>
     </style>
     <style
diff --git a/java/res/xml-land/kbd_number.xml b/java/res/xml-land/kbd_number.xml
index 8d31df1..0dced28 100644
--- a/java/res/xml-land/kbd_number.xml
+++ b/java/res/xml-land/kbd_number.xml
@@ -20,7 +20,8 @@
 
 <Keyboard
     xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
-    latin:keyboardHorizontalEdgesPadding="10%p"
+    latin:keyboardLeftPadding="10%p"
+    latin:keyboardRightPadding="10%p"
     latin:keyWidth="26.67%p"
     latin:touchPositionCorrectionData="@array/touch_position_correction_data_default"
 >
diff --git a/java/res/xml-land/kbd_phone.xml b/java/res/xml-land/kbd_phone.xml
index 2f8fc35..e5d7b44 100644
--- a/java/res/xml-land/kbd_phone.xml
+++ b/java/res/xml-land/kbd_phone.xml
@@ -20,7 +20,8 @@
 
 <Keyboard
     xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
-    latin:keyboardHorizontalEdgesPadding="10%p"
+    latin:keyboardLeftPadding="10%p"
+    latin:keyboardRightPadding="10%p"
     latin:keyWidth="26.67%p"
     latin:touchPositionCorrectionData="@array/touch_position_correction_data_default"
 >
diff --git a/java/res/xml-land/kbd_phone_symbols.xml b/java/res/xml-land/kbd_phone_symbols.xml
index 0e6bcdd..b881e62 100644
--- a/java/res/xml-land/kbd_phone_symbols.xml
+++ b/java/res/xml-land/kbd_phone_symbols.xml
@@ -20,7 +20,8 @@
 
 <Keyboard
     xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
-    latin:keyboardHorizontalEdgesPadding="10%p"
+    latin:keyboardLeftPadding="10%p"
+    latin:keyboardRightPadding="10%p"
     latin:keyWidth="26.67%p"
     latin:touchPositionCorrectionData="@array/touch_position_correction_data_default"
 >
diff --git a/java/res/xml-sw600dp-land/kbd_number.xml b/java/res/xml-sw600dp-land/kbd_number.xml
index 63dfc90..a9e8121 100644
--- a/java/res/xml-sw600dp-land/kbd_number.xml
+++ b/java/res/xml-sw600dp-land/kbd_number.xml
@@ -20,7 +20,8 @@
 
 <Keyboard
     xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
-    latin:keyboardHorizontalEdgesPadding="10%p"
+    latin:keyboardLeftPadding="10%p"
+    latin:keyboardRightPadding="10%p"
     latin:keyWidth="18%p"
     latin:touchPositionCorrectionData="@array/touch_position_correction_data_default"
 >
diff --git a/java/res/xml-sw600dp-land/kbd_phone.xml b/java/res/xml-sw600dp-land/kbd_phone.xml
index b616111..4cabdeb 100644
--- a/java/res/xml-sw600dp-land/kbd_phone.xml
+++ b/java/res/xml-sw600dp-land/kbd_phone.xml
@@ -20,7 +20,8 @@
 
 <Keyboard
     xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
-    latin:keyboardHorizontalEdgesPadding="10%p"
+    latin:keyboardLeftPadding="10%p"
+    latin:keyboardRightPadding="10%p"
     latin:keyWidth="18%p"
     latin:touchPositionCorrectionData="@array/touch_position_correction_data_default"
 >
diff --git a/java/res/xml-sw600dp-land/kbd_phone_symbols.xml b/java/res/xml-sw600dp-land/kbd_phone_symbols.xml
index 9b0bee0..9c3e825 100644
--- a/java/res/xml-sw600dp-land/kbd_phone_symbols.xml
+++ b/java/res/xml-sw600dp-land/kbd_phone_symbols.xml
@@ -20,7 +20,8 @@
 
 <Keyboard
     xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
-    latin:keyboardHorizontalEdgesPadding="10%p"
+    latin:keyboardLeftPadding="10%p"
+    latin:keyboardRightPadding="10%p"
     latin:keyWidth="18%p"
     latin:touchPositionCorrectionData="@array/touch_position_correction_data_default"
 >
diff --git a/java/res/xml-sw768dp-land/kbd_number.xml b/java/res/xml-sw768dp-land/kbd_number.xml
index de8d559..1cb775e 100644
--- a/java/res/xml-sw768dp-land/kbd_number.xml
+++ b/java/res/xml-sw768dp-land/kbd_number.xml
@@ -20,7 +20,8 @@
 
 <Keyboard
     xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
-    latin:keyboardHorizontalEdgesPadding="10%p"
+    latin:keyboardLeftPadding="10%p"
+    latin:keyboardRightPadding="10%p"
     latin:keyWidth="13.250%p"
     latin:touchPositionCorrectionData="@array/touch_position_correction_data_default"
 >
diff --git a/java/res/xml-sw768dp-land/kbd_phone.xml b/java/res/xml-sw768dp-land/kbd_phone.xml
index f88a076..8905182 100644
--- a/java/res/xml-sw768dp-land/kbd_phone.xml
+++ b/java/res/xml-sw768dp-land/kbd_phone.xml
@@ -20,7 +20,8 @@
 
 <Keyboard
     xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
-    latin:keyboardHorizontalEdgesPadding="10%p"
+    latin:keyboardLeftPadding="10%p"
+    latin:keyboardRightPadding="10%p"
     latin:keyWidth="13.250%p"
     latin:touchPositionCorrectionData="@array/touch_position_correction_data_default"
 >
diff --git a/java/res/xml-sw768dp-land/kbd_phone_symbols.xml b/java/res/xml-sw768dp-land/kbd_phone_symbols.xml
index eaa413e..6038b1f 100644
--- a/java/res/xml-sw768dp-land/kbd_phone_symbols.xml
+++ b/java/res/xml-sw768dp-land/kbd_phone_symbols.xml
@@ -20,7 +20,8 @@
 
 <Keyboard
     xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
-    latin:keyboardHorizontalEdgesPadding="10%p"
+    latin:keyboardLeftPadding="10%p"
+    latin:keyboardRightPadding="10%p"
     latin:keyWidth="13.250%p"
     latin:touchPositionCorrectionData="@array/touch_position_correction_data_default"
 >
diff --git a/java/src/com/android/inputmethod/keyboard/Key.java b/java/src/com/android/inputmethod/keyboard/Key.java
index 9b97175..1e5af51 100644
--- a/java/src/com/android/inputmethod/keyboard/Key.java
+++ b/java/src/com/android/inputmethod/keyboard/Key.java
@@ -41,7 +41,6 @@
 import com.android.inputmethod.keyboard.internal.MoreKeySpec;
 import com.android.inputmethod.latin.Constants;
 import com.android.inputmethod.latin.R;
-import com.android.inputmethod.latin.ResourceUtils;
 import com.android.inputmethod.latin.StringUtils;
 
 import org.xmlpull.v1.XmlPullParser;
@@ -225,8 +224,8 @@
     public Key(final Resources res, final KeyboardParams params, final KeyboardRow row,
             final XmlPullParser parser) throws XmlPullParserException {
         final float horizontalGap = isSpacer() ? 0 : params.mHorizontalGap;
-        final int keyHeight = row.mRowHeight;
-        mHeight = keyHeight - params.mVerticalGap;
+        final int rowHeight = row.mRowHeight;
+        mHeight = rowHeight - params.mVerticalGap;
 
         final TypedArray keyAttr = res.obtainAttributes(Xml.asAttributeSet(parser),
                 R.styleable.Keyboard_Key);
@@ -241,17 +240,18 @@
         mY = keyYPos;
         mWidth = Math.round(keyWidth - horizontalGap);
         mHitBox.set(Math.round(keyXPos), keyYPos, Math.round(keyXPos + keyWidth) + 1,
-                keyYPos + keyHeight);
+                keyYPos + rowHeight);
         // Update row to have current x coordinate.
         row.setXPos(keyXPos + keyWidth);
 
         mBackgroundType = style.getInt(keyAttr,
                 R.styleable.Keyboard_Key_backgroundType, row.getDefaultBackgroundType());
 
-        final int visualInsetsLeft = Math.round(ResourceUtils.getDimensionOrFraction(keyAttr,
-                R.styleable.Keyboard_Key_visualInsetsLeft, params.mBaseWidth, 0));
-        final int visualInsetsRight = Math.round(ResourceUtils.getDimensionOrFraction(keyAttr,
-                R.styleable.Keyboard_Key_visualInsetsRight, params.mBaseWidth, 0));
+        final int baseWidth = params.mBaseWidth;
+        final int visualInsetsLeft = Math.round(keyAttr.getFraction(
+                R.styleable.Keyboard_Key_visualInsetsLeft, baseWidth, baseWidth, 0));
+        final int visualInsetsRight = Math.round(keyAttr.getFraction(
+                R.styleable.Keyboard_Key_visualInsetsRight, baseWidth, baseWidth, 0));
         mIconId = KeySpecParser.getIconId(style.getString(keyAttr,
                 R.styleable.Keyboard_Key_keyIcon));
         final int disabledIconId = KeySpecParser.getIconId(style.getString(keyAttr,
@@ -470,11 +470,11 @@
     }
 
     public void markAsLeftEdge(final KeyboardParams params) {
-        mHitBox.left = params.mHorizontalEdgesPadding;
+        mHitBox.left = params.mLeftPadding;
     }
 
     public void markAsRightEdge(final KeyboardParams params) {
-        mHitBox.right = params.mOccupiedWidth - params.mHorizontalEdgesPadding;
+        mHitBox.right = params.mOccupiedWidth - params.mRightPadding;
     }
 
     public void markAsTopEdge(final KeyboardParams params) {
diff --git a/java/src/com/android/inputmethod/keyboard/Keyboard.java b/java/src/com/android/inputmethod/keyboard/Keyboard.java
index c2036fc..e87ecbc 100644
--- a/java/src/com/android/inputmethod/keyboard/Keyboard.java
+++ b/java/src/com/android/inputmethod/keyboard/Keyboard.java
@@ -30,11 +30,11 @@
  * <p>The layout file for a keyboard contains XML that looks like the following snippet:</p>
  * <pre>
  * &lt;Keyboard
- *         latin:keyWidth="%10p"
- *         latin:keyHeight="50px"
- *         latin:horizontalGap="2px"
- *         latin:verticalGap="2px" &gt;
- *     &lt;Row latin:keyWidth="32px" &gt;
+ *         latin:keyWidth="10%p"
+ *         latin:rowHeight="50px"
+ *         latin:horizontalGap="2%p"
+ *         latin:verticalGap="2%p" &gt;
+ *     &lt;Row latin:keyWidth="10%p" &gt;
  *         &lt;Key latin:keyLabel="A" /&gt;
  *         ...
  *     &lt;/Row&gt;
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardBuilder.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardBuilder.java
index 802d926..e087a45 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardBuilder.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardBuilder.java
@@ -235,31 +235,36 @@
                 R.styleable.Keyboard_Key);
         try {
             final KeyboardParams params = mParams;
-            params.mOccupiedHeight = params.mId.mHeight;
-            params.mOccupiedWidth = params.mId.mWidth;
-            params.mTopPadding = (int)ResourceUtils.getDimensionOrFraction(keyboardAttr,
-                    R.styleable.Keyboard_keyboardTopPadding, params.mOccupiedHeight, 0);
-            params.mBottomPadding = (int)ResourceUtils.getDimensionOrFraction(keyboardAttr,
-                    R.styleable.Keyboard_keyboardBottomPadding, params.mOccupiedHeight, 0);
-            params.mHorizontalEdgesPadding = (int)ResourceUtils.getDimensionOrFraction(
-                    keyboardAttr,
-                    R.styleable.Keyboard_keyboardHorizontalEdgesPadding,
-                    mParams.mOccupiedWidth, 0);
+            final int height = params.mId.mHeight;
+            final int width = params.mId.mWidth;
+            params.mOccupiedHeight = height;
+            params.mOccupiedWidth = width;
+            params.mTopPadding = (int)keyboardAttr.getFraction(
+                    R.styleable.Keyboard_keyboardTopPadding, height, height, 0);
+            params.mBottomPadding = (int)keyboardAttr.getFraction(
+                    R.styleable.Keyboard_keyboardBottomPadding, height, height, 0);
+            params.mLeftPadding = (int)keyboardAttr.getFraction(
+                    R.styleable.Keyboard_keyboardLeftPadding, width, width, 0);
+            params.mRightPadding = (int)keyboardAttr.getFraction(
+                    R.styleable.Keyboard_keyboardRightPadding, width, width, 0);
 
-            params.mBaseWidth = params.mOccupiedWidth - params.mHorizontalEdgesPadding * 2
-                    - params.mHorizontalCenterPadding;
-            params.mDefaultKeyWidth = (int)ResourceUtils.getDimensionOrFraction(keyAttr,
-                    R.styleable.Keyboard_Key_keyWidth, params.mBaseWidth,
-                    params.mBaseWidth / DEFAULT_KEYBOARD_COLUMNS);
-            params.mHorizontalGap = (int)ResourceUtils.getDimensionOrFraction(keyboardAttr,
-                    R.styleable.Keyboard_horizontalGap, params.mBaseWidth, 0);
-            params.mVerticalGap = (int)ResourceUtils.getDimensionOrFraction(keyboardAttr,
-                    R.styleable.Keyboard_verticalGap, params.mOccupiedHeight, 0);
-            params.mBaseHeight = params.mOccupiedHeight - params.mTopPadding
+            final int baseWidth =
+                    params.mOccupiedWidth - params.mLeftPadding - params.mRightPadding;
+            params.mBaseWidth = baseWidth;
+            params.mDefaultKeyWidth = (int)keyAttr.getFraction(R.styleable.Keyboard_Key_keyWidth,
+                    baseWidth, baseWidth, baseWidth / DEFAULT_KEYBOARD_COLUMNS);
+            params.mHorizontalGap = (int)keyboardAttr.getFraction(
+                    R.styleable.Keyboard_horizontalGap, baseWidth, baseWidth, 0);
+            // TODO: Fix keyboard geometry calculation clearer. Historically vertical gap between
+            // rows are determined based on the entire keyboard height including top and bottom
+            // paddings.
+            params.mVerticalGap = (int)keyboardAttr.getFraction(
+                    R.styleable.Keyboard_verticalGap, height, height, 0);
+            final int baseHeight = params.mOccupiedHeight - params.mTopPadding
                     - params.mBottomPadding + params.mVerticalGap;
+            params.mBaseHeight = baseHeight;
             params.mDefaultRowHeight = (int)ResourceUtils.getDimensionOrFraction(keyboardAttr,
-                    R.styleable.Keyboard_rowHeight, params.mBaseHeight,
-                    params.mBaseHeight / DEFAULT_KEYBOARD_ROWS);
+                    R.styleable.Keyboard_rowHeight, baseHeight, baseHeight / DEFAULT_KEYBOARD_ROWS);
 
             params.mKeyVisualAttributes = KeyVisualAttributes.newInstance(keyAttr);
 
@@ -737,7 +742,7 @@
     }
 
     private void startRow(final KeyboardRow row) {
-        addEdgeSpace(mParams.mHorizontalEdgesPadding, row);
+        addEdgeSpace(mParams.mLeftPadding, row);
         mCurrentRow = row;
         mLeftEdge = true;
         mRightEdgeKey = null;
@@ -751,7 +756,7 @@
             mRightEdgeKey.markAsRightEdge(mParams);
             mRightEdgeKey = null;
         }
-        addEdgeSpace(mParams.mHorizontalEdgesPadding, row);
+        addEdgeSpace(mParams.mRightPadding, row);
         mCurrentY += row.mRowHeight;
         mCurrentRow = null;
         mTopEdge = false;
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardParams.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardParams.java
index e13dbe5..15eb690 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardParams.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardParams.java
@@ -42,8 +42,8 @@
 
     public int mTopPadding;
     public int mBottomPadding;
-    public int mHorizontalEdgesPadding;
-    public int mHorizontalCenterPadding;
+    public int mLeftPadding;
+    public int mRightPadding;
 
     public KeyVisualAttributes mKeyVisualAttributes;
 
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardRow.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardRow.java
index 2278020..855f655 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardRow.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardRow.java
@@ -54,17 +54,16 @@
     public KeyboardRow(final Resources res, final KeyboardParams params, final XmlPullParser parser,
             final int y) {
         mParams = params;
-        TypedArray keyboardAttr = res.obtainAttributes(Xml.asAttributeSet(parser),
+        final TypedArray keyboardAttr = res.obtainAttributes(Xml.asAttributeSet(parser),
                 R.styleable.Keyboard);
         mRowHeight = (int)ResourceUtils.getDimensionOrFraction(keyboardAttr,
                 R.styleable.Keyboard_rowHeight,
                 params.mBaseHeight, params.mDefaultRowHeight);
         keyboardAttr.recycle();
-        TypedArray keyAttr = res.obtainAttributes(Xml.asAttributeSet(parser),
+        final TypedArray keyAttr = res.obtainAttributes(Xml.asAttributeSet(parser),
                 R.styleable.Keyboard_Key);
-        mDefaultKeyWidth = ResourceUtils.getDimensionOrFraction(keyAttr,
-                R.styleable.Keyboard_Key_keyWidth,
-                params.mBaseWidth, params.mDefaultKeyWidth);
+        mDefaultKeyWidth = keyAttr.getFraction(R.styleable.Keyboard_Key_keyWidth,
+                params.mBaseWidth, params.mBaseWidth, params.mDefaultKeyWidth);
         mDefaultBackgroundType = keyAttr.getInt(R.styleable.Keyboard_Key_backgroundType,
                 Key.BACKGROUND_TYPE_NORMAL);
         keyAttr.recycle();
@@ -112,20 +111,19 @@
     }
 
     public float getKeyX(final TypedArray keyAttr) {
-        final int keyboardRightEdge = mParams.mOccupiedWidth
-                - mParams.mHorizontalEdgesPadding;
         if (keyAttr.hasValue(R.styleable.Keyboard_Key_keyXPos)) {
-            final float keyXPos = ResourceUtils.getDimensionOrFraction(keyAttr,
-                    R.styleable.Keyboard_Key_keyXPos, mParams.mBaseWidth, 0);
+            final float keyXPos = keyAttr.getFraction(R.styleable.Keyboard_Key_keyXPos,
+                    mParams.mBaseWidth, mParams.mBaseWidth, 0);
             if (keyXPos < 0) {
                 // If keyXPos is negative, the actual x-coordinate will be
                 // keyboardWidth + keyXPos.
                 // keyXPos shouldn't be less than mCurrentX because drawable area for this
                 // key starts at mCurrentX. Or, this key will overlaps the adjacent key on
                 // its left hand side.
+                final int keyboardRightEdge = mParams.mOccupiedWidth - mParams.mRightPadding;
                 return Math.max(keyXPos + keyboardRightEdge, mCurrentX);
             } else {
-                return keyXPos + mParams.mHorizontalEdgesPadding;
+                return keyXPos + mParams.mLeftPadding;
             }
         }
         return mCurrentX;
@@ -140,15 +138,13 @@
                 R.styleable.Keyboard_Key_keyWidth, KEYWIDTH_NOT_ENUM);
         switch (widthType) {
         case KEYWIDTH_FILL_RIGHT:
-            final int keyboardRightEdge =
-                    mParams.mOccupiedWidth - mParams.mHorizontalEdgesPadding;
             // If keyWidth is fillRight, the actual key width will be determined to fill
             // out the area up to the right edge of the keyboard.
+            final int keyboardRightEdge = mParams.mOccupiedWidth - mParams.mRightPadding;
             return keyboardRightEdge - keyXPos;
         default: // KEYWIDTH_NOT_ENUM
-            return ResourceUtils.getDimensionOrFraction(keyAttr,
-                    R.styleable.Keyboard_Key_keyWidth,
-                    mParams.mBaseWidth, mDefaultKeyWidth);
+            return keyAttr.getFraction(R.styleable.Keyboard_Key_keyWidth,
+                    mParams.mBaseWidth, mParams.mBaseWidth, mDefaultKeyWidth);
         }
     }
 }
diff --git a/native/jni/com_android_inputmethod_latin_BinaryDictionary.cpp b/native/jni/com_android_inputmethod_latin_BinaryDictionary.cpp
index 5c8ef7e..ca38b0d 100644
--- a/native/jni/com_android_inputmethod_latin_BinaryDictionary.cpp
+++ b/native/jni/com_android_inputmethod_latin_BinaryDictionary.cpp
@@ -87,7 +87,7 @@
         AKLOGE("DICT: Can't allocate memory region for dictionary. errno=%d", errno);
         return 0;
     }
-    int ret = fseek(file, (long)dictOffset, SEEK_SET);
+    int ret = fseek(file, static_cast<long>(dictOffset), SEEK_SET);
     if (ret != 0) {
         AKLOGE("DICT: Failure in fseek. ret=%d errno=%d", ret, errno);
         return 0;
@@ -121,7 +121,7 @@
     }
     PROF_END(66);
     PROF_CLOSE;
-    return (jlong)dictionary;
+    return reinterpret_cast<jlong>(dictionary);
 }
 
 static int latinime_BinaryDictionary_getSuggestions(JNIEnv *env, jclass clazz, jlong dict,
@@ -216,7 +216,7 @@
 static jboolean latinime_BinaryDictionary_isValidBigram(JNIEnv *env, jclass clazz, jlong dict,
         jintArray wordArray1, jintArray wordArray2) {
     Dictionary *dictionary = reinterpret_cast<Dictionary *>(dict);
-    if (!dictionary) return (jboolean) false;
+    if (!dictionary) return JNI_FALSE;
     const jsize codePointLength1 = env->GetArrayLength(wordArray1);
     const jsize codePointLength2 = env->GetArrayLength(wordArray2);
     int codePoints1[codePointLength1];
diff --git a/native/jni/src/binary_format.h b/native/jni/src/binary_format.h
index 61780de..f19d5e3 100644
--- a/native/jni/src/binary_format.h
+++ b/native/jni/src/binary_format.h
@@ -314,7 +314,7 @@
 }
 
 static AK_FORCE_INLINE int shortcutByteSize(const uint8_t *const dict, const int pos) {
-    return ((int)(dict[pos] << 8)) + (dict[pos + 1]);
+    return (static_cast<int>(dict[pos] << 8)) + (dict[pos + 1]);
 }
 
 inline int BinaryFormat::skipChildrenPosition(const uint8_t flags, const int pos) {
diff --git a/native/jni/src/correction.cpp b/native/jni/src/correction.cpp
index afedd29..d4bd4aa 100644
--- a/native/jni/src/correction.cpp
+++ b/native/jni/src/correction.cpp
@@ -677,7 +677,7 @@
             const float factor =
                     SuggestUtils::getDistanceScalingFactor(static_cast<float>(squaredDistance));
             if (factor > 0.0f) {
-                multiplyRate((int)(factor * 100.0f), &finalFreq);
+                multiplyRate(static_cast<int>(factor * 100.0f), &finalFreq);
             } else if (squaredDistance == PROXIMITY_CHAR_WITHOUT_DISTANCE_INFO) {
                 multiplyRate(WORDS_WITH_PROXIMITY_CHARACTER_DEMOTION_RATE, &finalFreq);
             }
diff --git a/native/jni/src/defines.h b/native/jni/src/defines.h
index 922a746..9883168 100644
--- a/native/jni/src/defines.h
+++ b/native/jni/src/defines.h
@@ -370,7 +370,7 @@
 
 // TODO: Remove
 #define MAX_POINTER_COUNT 1
-#define MAX_POINTER_COUNT_FOR_G 2
+#define MAX_POINTER_COUNT_G 2
 
 // Size, in bytes, of the bloom filter index for bigrams
 // 128 gives us 1024 buckets. The probability of false positive is (1 - e ** (-kn/m))**k,
diff --git a/native/jni/src/dic_traverse_wrapper.h b/native/jni/src/dic_traverse_wrapper.h
index 9a1db38..1108a45 100644
--- a/native/jni/src/dic_traverse_wrapper.h
+++ b/native/jni/src/dic_traverse_wrapper.h
@@ -31,8 +31,8 @@
         }
         return 0;
     }
-    static void initDicTraverseSession(void *traverseSession,
-            const Dictionary *const dictionary, const int *prevWord, const int prevWordLength) {
+    static void initDicTraverseSession(void *traverseSession, const Dictionary *const dictionary,
+            const int *prevWord, const int prevWordLength) {
         if (sDicTraverseSessionInitMethod) {
             sDicTraverseSessionInitMethod(traverseSession, dictionary, prevWord, prevWordLength);
         }
@@ -42,8 +42,7 @@
             sDicTraverseSessionReleaseMethod(traverseSession);
         }
     }
-    static void setTraverseSessionFactoryMethod(
-            void *(*factoryMethod)(JNIEnv *, jstring)) {
+    static void setTraverseSessionFactoryMethod(void *(*factoryMethod)(JNIEnv *, jstring)) {
         sDicTraverseSessionFactoryMethod = factoryMethod;
     }
     static void setTraverseSessionInitMethod(
@@ -53,6 +52,7 @@
     static void setTraverseSessionReleaseMethod(void (*releaseMethod)(void *)) {
         sDicTraverseSessionReleaseMethod = releaseMethod;
     }
+
  private:
     DISALLOW_IMPLICIT_CONSTRUCTORS(DicTraverseWrapper);
     static void *(*sDicTraverseSessionFactoryMethod)(JNIEnv *, jstring);
diff --git a/native/jni/src/proximity_info.cpp b/native/jni/src/proximity_info.cpp
index 8157fe2..a0bad1a 100644
--- a/native/jni/src/proximity_info.cpp
+++ b/native/jni/src/proximity_info.cpp
@@ -110,8 +110,8 @@
         return false;
     }
 
-    const int startIndex = ProximityInfoUtils::getStartIndexFromCoordinates(
-            MAX_PROXIMITY_CHARS_SIZE, x, y, CELL_HEIGHT, CELL_WIDTH, GRID_WIDTH);
+    const int startIndex = ProximityInfoUtils::getStartIndexFromCoordinates(x, y,
+            CELL_HEIGHT, CELL_WIDTH, GRID_WIDTH);
     if (DEBUG_PROXIMITY_INFO) {
         AKLOGI("hasSpaceProximity: index %d, %d, %d", startIndex, x, y);
     }
diff --git a/native/jni/src/proximity_info.h b/native/jni/src/proximity_info.h
index 6d571d7..f3a68e4 100644
--- a/native/jni/src/proximity_info.h
+++ b/native/jni/src/proximity_info.h
@@ -47,57 +47,21 @@
         // the radius of the key is assigned to zero.
         return mSweetSpotRadii[keyIndex] > 0.0f;
     }
-    float getSweetSpotRadiiAt(int keyIndex) const {
-        return mSweetSpotRadii[keyIndex];
-    }
-    float getSweetSpotCenterXAt(int keyIndex) const {
-        return mSweetSpotCenterXs[keyIndex];
-    }
-    float getSweetSpotCenterYAt(int keyIndex) const {
-        return mSweetSpotCenterYs[keyIndex];
-    }
+    float getSweetSpotRadiiAt(int keyIndex) const { return mSweetSpotRadii[keyIndex]; }
+    float getSweetSpotCenterXAt(int keyIndex) const { return mSweetSpotCenterXs[keyIndex]; }
+    float getSweetSpotCenterYAt(int keyIndex) const { return mSweetSpotCenterYs[keyIndex]; }
     void calculateNearbyKeyCodes(
             const int x, const int y, const int primaryKey, int *inputCodes) const;
-
-    bool hasTouchPositionCorrectionData() const {
-        return HAS_TOUCH_POSITION_CORRECTION_DATA;
-    }
-
-    int getMostCommonKeyWidth() const {
-        return MOST_COMMON_KEY_WIDTH;
-    }
-
-    int getMostCommonKeyWidthSquare() const {
-        return MOST_COMMON_KEY_WIDTH_SQUARE;
-    }
-
-    int getKeyCount() const {
-        return KEY_COUNT;
-    }
-
-    int getCellHeight() const {
-        return CELL_HEIGHT;
-    }
-
-    int getCellWidth() const {
-        return CELL_WIDTH;
-    }
-
-    int getGridWidth() const {
-        return GRID_WIDTH;
-    }
-
-    int getGridHeight() const {
-        return GRID_HEIGHT;
-    }
-
-    int getKeyboardWidth() const {
-        return KEYBOARD_WIDTH;
-    }
-
-    int getKeyboardHeight() const {
-        return KEYBOARD_HEIGHT;
-    }
+    bool hasTouchPositionCorrectionData() const { return HAS_TOUCH_POSITION_CORRECTION_DATA; }
+    int getMostCommonKeyWidth() const { return MOST_COMMON_KEY_WIDTH; }
+    int getMostCommonKeyWidthSquare() const { return MOST_COMMON_KEY_WIDTH_SQUARE; }
+    int getKeyCount() const { return KEY_COUNT; }
+    int getCellHeight() const { return CELL_HEIGHT; }
+    int getCellWidth() const { return CELL_WIDTH; }
+    int getGridWidth() const { return GRID_WIDTH; }
+    int getGridHeight() const { return GRID_HEIGHT; }
+    int getKeyboardWidth() const { return KEYBOARD_WIDTH; }
+    int getKeyboardHeight() const { return KEYBOARD_HEIGHT; }
 
     int getKeyCenterXOfCodePointG(int charCode) const;
     int getKeyCenterYOfCodePointG(int charCode) const;
@@ -109,9 +73,8 @@
             const int *const inputYCoordinates, const int inputSize, int *allInputCodes) const {
         ProximityInfoUtils::initializeProximities(inputCodes, inputXCoordinates, inputYCoordinates,
                 inputSize, mKeyXCoordinates, mKeyYCoordinates, mKeyWidths, mKeyHeights,
-                mProximityCharsArray, MAX_PROXIMITY_CHARS_SIZE, CELL_HEIGHT, CELL_WIDTH,
-                GRID_WIDTH, MOST_COMMON_KEY_WIDTH, KEY_COUNT, mLocaleStr, &mCodeToKeyMap,
-                allInputCodes);
+                mProximityCharsArray, CELL_HEIGHT, CELL_WIDTH, GRID_WIDTH, MOST_COMMON_KEY_WIDTH,
+                KEY_COUNT, mLocaleStr, &mCodeToKeyMap, allInputCodes);
     }
 
     int getKeyIndexOf(const int c) const {
diff --git a/native/jni/src/proximity_info_state_utils.cpp b/native/jni/src/proximity_info_state_utils.cpp
index 9f85743..ac74a4e 100644
--- a/native/jni/src/proximity_info_state_utils.cpp
+++ b/native/jni/src/proximity_info_state_utils.cpp
@@ -211,7 +211,7 @@
                             ProximityInfoParams::NOT_A_DISTANCE_FLOAT;
             if (squaredDistance >= 0.0f) {
                 normalizedSquaredDistances[i * MAX_PROXIMITY_CHARS_SIZE + j] =
-                        (int) (squaredDistance
+                        static_cast<int>(squaredDistance
                                 * ProximityInfoParams::NORMALIZED_SQUARED_DISTANCE_SCALING_FACTOR);
             } else {
                 normalizedSquaredDistances[i * MAX_PROXIMITY_CHARS_SIZE + j] =
diff --git a/native/jni/src/proximity_info_utils.h b/native/jni/src/proximity_info_utils.h
index 24917d8..c50df57 100644
--- a/native/jni/src/proximity_info_utils.h
+++ b/native/jni/src/proximity_info_utils.h
@@ -49,9 +49,9 @@
             const int *const inputXCoordinates, const int *const inputYCoordinates,
             const int inputSize, const int *const keyXCoordinates,
             const int *const keyYCoordinates, const int *const keyWidths, const int *keyHeights,
-            const int *const proximityCharsArray, const int maxProximityCharsSize,
-            const int cellHeight, const int cellWidth, const int gridWidth,
-            const int mostCommonKeyWidth, const int keyCount, const char *const localeStr,
+            const int *const proximityCharsArray, const int cellHeight, const int cellWidth,
+            const int gridWidth, const int mostCommonKeyWidth, const int keyCount,
+            const char *const localeStr,
             const hash_map_compat<int, int> *const codeToKeyMap, int *inputProximities) {
         // Initialize
         // - mInputCodes
@@ -63,9 +63,8 @@
             const int y = inputYCoordinates[i];
             int *proximities = &inputProximities[i * MAX_PROXIMITY_CHARS_SIZE];
             calculateProximities(keyXCoordinates, keyYCoordinates, keyWidths, keyHeights,
-                    proximityCharsArray, maxProximityCharsSize, cellHeight, cellWidth, gridWidth,
-                    mostCommonKeyWidth, keyCount, x, y, primaryKey, localeStr, codeToKeyMap,
-                    proximities);
+                    proximityCharsArray, cellHeight, cellWidth, gridWidth, mostCommonKeyWidth,
+                    keyCount, x, y, primaryKey, localeStr, codeToKeyMap, proximities);
         }
 
         if (DEBUG_PROXIMITY_CHARS) {
@@ -81,10 +80,9 @@
         }
     }
 
-    static AK_FORCE_INLINE int getStartIndexFromCoordinates(const int maxProximityCharsSize,
-            const int x, const int y, const int cellHeight, const int cellWidth,
-            const int gridWidth) {
-        return ((y / cellHeight) * gridWidth + (x / cellWidth)) * maxProximityCharsSize;
+    static AK_FORCE_INLINE int getStartIndexFromCoordinates(const int x, const int y,
+            const int cellHeight, const int cellWidth, const int gridWidth) {
+        return ((y / cellHeight) * gridWidth + (x / cellWidth)) * MAX_PROXIMITY_CHARS_SIZE;
     }
 
     static inline float getSquaredDistanceFloat(const float x1, const float y1, const float x2,
@@ -153,21 +151,18 @@
         return left < right && top < bottom && x >= left && x < right && y >= top && y < bottom;
     }
 
-    static void calculateProximities(
-            const int *const keyXCoordinates, const int *const keyYCoordinates,
-            const int *const keyWidths, const int *keyHeights,
-            const int *const proximityCharsArray,
-            const int maxProximityCharsSize, const int cellHeight, const int cellWidth,
+    static void calculateProximities(const int *const keyXCoordinates,
+            const int *const keyYCoordinates, const int *const keyWidths, const int *keyHeights,
+            const int *const proximityCharsArray, const int cellHeight, const int cellWidth,
             const int gridWidth, const int mostCommonKeyWidth, const int keyCount,
             const int x, const int y, const int primaryKey, const char *const localeStr,
             const hash_map_compat<int, int> *const codeToKeyMap, int *proximities) {
         const int mostCommonKeyWidthSquare = mostCommonKeyWidth * mostCommonKeyWidth;
         int insertPos = 0;
         proximities[insertPos++] = primaryKey;
-        const int startIndex = getStartIndexFromCoordinates(
-                maxProximityCharsSize, x, y, cellHeight, cellWidth, gridWidth);
+        const int startIndex = getStartIndexFromCoordinates(x, y, cellHeight, cellWidth, gridWidth);
         if (startIndex >= 0) {
-            for (int i = 0; i < maxProximityCharsSize; ++i) {
+            for (int i = 0; i < MAX_PROXIMITY_CHARS_SIZE; ++i) {
                 const int c = proximityCharsArray[startIndex + i];
                 if (c < KEYCODE_SPACE || c == primaryKey) {
                     continue;
@@ -179,7 +174,7 @@
                         keyWidths, keyHeights, keyIndex, x, y);
                 if (onKey || distance < mostCommonKeyWidthSquare) {
                     proximities[insertPos++] = c;
-                    if (insertPos >= maxProximityCharsSize) {
+                    if (insertPos >= MAX_PROXIMITY_CHARS_SIZE) {
                         if (DEBUG_DICT) {
                             ASSERT(false);
                         }
@@ -191,7 +186,7 @@
                     AdditionalProximityChars::getAdditionalCharsSize(localeStr, primaryKey);
             if (additionalProximitySize > 0) {
                 proximities[insertPos++] = ADDITIONAL_PROXIMITY_CHAR_DELIMITER_CODE;
-                if (insertPos >= maxProximityCharsSize) {
+                if (insertPos >= MAX_PROXIMITY_CHARS_SIZE) {
                     if (DEBUG_DICT) {
                         ASSERT(false);
                     }
@@ -212,7 +207,7 @@
                         continue;
                     }
                     proximities[insertPos++] = ac;
-                    if (insertPos >= maxProximityCharsSize) {
+                    if (insertPos >= MAX_PROXIMITY_CHARS_SIZE) {
                         if (DEBUG_DICT) {
                             ASSERT(false);
                         }
@@ -222,7 +217,7 @@
             }
         }
         // Add a delimiter for the proximity characters
-        for (int i = insertPos; i < maxProximityCharsSize; ++i) {
+        for (int i = insertPos; i < MAX_PROXIMITY_CHARS_SIZE; ++i) {
             proximities[i] = NOT_A_CODE_POINT;
         }
     }