diff --git a/java/src/com/android/inputmethod/accessibility/AccessibilityEntityProvider.java b/java/src/com/android/inputmethod/accessibility/AccessibilityEntityProvider.java
index 77f3234406d48f74a29687dc52162c28eb647c69..8ce12633088709f15e770ad994059f3307e27174 100644
--- a/java/src/com/android/inputmethod/accessibility/AccessibilityEntityProvider.java
+++ b/java/src/com/android/inputmethod/accessibility/AccessibilityEntityProvider.java
@@ -172,7 +172,7 @@ public final class AccessibilityEntityProvider extends AccessibilityNodeProvider
             return null;
         }
         final String keyDescription = getKeyDescription(key);
-        final Rect boundsInParent = key.mHitBox;
+        final Rect boundsInParent = key.getHitBox();
 
         // Calculate the key's in-screen bounds.
         mTempBoundsInScreen.set(boundsInParent);
@@ -208,8 +208,8 @@ public final class AccessibilityEntityProvider extends AccessibilityNodeProvider
      * @param key The key to press.
      */
     void simulateKeyPress(final Key key) {
-        final int x = key.mHitBox.centerX();
-        final int y = key.mHitBox.centerY();
+        final int x = key.getHitBox().centerX();
+        final int y = key.getHitBox().centerY();
         final long downTime = SystemClock.uptimeMillis();
         final MotionEvent downEvent = MotionEvent.obtain(
                 downTime, downTime, MotionEvent.ACTION_DOWN, x, y, 0);
@@ -325,6 +325,6 @@ public final class AccessibilityEntityProvider extends AccessibilityNodeProvider
         // The key x- and y-coordinates are stable between layout changes.
         // Generate an identifier by bit-shifting the x-coordinate to the
         // left-half of the integer and OR'ing with the y-coordinate.
-        return ((0xFFFF & key.mX) << (Integer.SIZE / 2)) | (0xFFFF & key.mY);
+        return ((0xFFFF & key.getX()) << (Integer.SIZE / 2)) | (0xFFFF & key.getY());
     }
 }
diff --git a/java/src/com/android/inputmethod/accessibility/KeyCodeDescriptionMapper.java b/java/src/com/android/inputmethod/accessibility/KeyCodeDescriptionMapper.java
index 41f5b9a249df601b8098867977dc154909443df6..58624a2e6a46884157740ca9a3f925442c0ba635 100644
--- a/java/src/com/android/inputmethod/accessibility/KeyCodeDescriptionMapper.java
+++ b/java/src/com/android/inputmethod/accessibility/KeyCodeDescriptionMapper.java
@@ -97,7 +97,7 @@ public final class KeyCodeDescriptionMapper {
      */
     public String getDescriptionForKey(final Context context, final Keyboard keyboard,
             final Key key, final boolean shouldObscure) {
-        final int code = key.mCode;
+        final int code = key.getCode();
 
         if (code == Constants.CODE_SWITCH_ALPHA_SYMBOL) {
             final String description = getDescriptionForSwitchAlphaSymbol(context, keyboard);
@@ -116,8 +116,8 @@ public final class KeyCodeDescriptionMapper {
             return getDescriptionForActionKey(context, keyboard, key);
         }
 
-        if (!TextUtils.isEmpty(key.mLabel)) {
-            final String label = key.mLabel.toString().trim();
+        if (!TextUtils.isEmpty(key.getLabel())) {
+            final String label = key.getLabel().trim();
 
             // First, attempt to map the label to a pre-defined description.
             if (mKeyLabelMap.containsKey(label)) {
@@ -126,7 +126,7 @@ public final class KeyCodeDescriptionMapper {
         }
 
         // Just attempt to speak the description.
-        if (key.mCode != Constants.CODE_UNSPECIFIED) {
+        if (key.getCode() != Constants.CODE_UNSPECIFIED) {
             return getDescriptionForKeyCode(context, keyboard, key, shouldObscure);
         }
         return null;
@@ -215,8 +215,8 @@ public final class KeyCodeDescriptionMapper {
         final int resId;
 
         // Always use the label, if available.
-        if (!TextUtils.isEmpty(key.mLabel)) {
-            return key.mLabel.toString().trim();
+        if (!TextUtils.isEmpty(key.getLabel())) {
+            return key.getLabel().trim();
         }
 
         // Otherwise, use the action ID.
@@ -267,7 +267,7 @@ public final class KeyCodeDescriptionMapper {
      */
     private String getDescriptionForKeyCode(final Context context, final Keyboard keyboard,
             final Key key, final boolean shouldObscure) {
-        final int code = key.mCode;
+        final int code = key.getCode();
 
         // If the key description should be obscured, now is the time to do it.
         final boolean isDefinedNonCtrl = Character.isDefined(code) && !Character.isISOControl(code);
@@ -280,8 +280,8 @@ public final class KeyCodeDescriptionMapper {
         if (isDefinedNonCtrl) {
             return Character.toString((char) code);
         }
-        if (!TextUtils.isEmpty(key.mLabel)) {
-            return key.mLabel;
+        if (!TextUtils.isEmpty(key.getLabel())) {
+            return key.getLabel();
         }
         return context.getString(R.string.spoken_description_unknown, code);
     }
diff --git a/java/src/com/android/inputmethod/keyboard/Key.java b/java/src/com/android/inputmethod/keyboard/Key.java
index 16c79eb8e417edfb7fee16a34605f142cc2b6912..8098dab37b2077b7914dbbb393daa24a0b7eb2c6 100644
--- a/java/src/com/android/inputmethod/keyboard/Key.java
+++ b/java/src/com/android/inputmethod/keyboard/Key.java
@@ -58,12 +58,12 @@ public class Key implements Comparable<Key> {
     /**
      * The key code (unicode or custom code) that this key generates.
      */
-    public final int mCode;
+    private final int mCode;
 
     /** Label to display */
-    public final String mLabel;
+    private final String mLabel;
     /** Hint label to display on the key in conjunction with the label */
-    public final String mHintLabel;
+    private final String mHintLabel;
     /** Flags of the label */
     private final int mLabelFlags;
     private static final int LABEL_FLAGS_ALIGN_LEFT = 0x01;
@@ -95,18 +95,18 @@ public class Key implements Comparable<Key> {
     private final int mIconId;
 
     /** Width of the key, not including the gap */
-    public final int mWidth;
+    private final int mWidth;
     /** Height of the key, not including the gap */
-    public final int mHeight;
+    private final int mHeight;
     /** X coordinate of the key in the keyboard layout */
-    public final int mX;
+    private final int mX;
     /** Y coordinate of the key in the keyboard layout */
-    public final int mY;
+    private final int mY;
     /** Hit bounding box of the key */
-    public final Rect mHitBox = new Rect();
+    private final Rect mHitBox = new Rect();
 
     /** More keys. It is guaranteed that this is null or an array of one or more elements */
-    public final MoreKeySpec[] mMoreKeys;
+    private final MoreKeySpec[] mMoreKeys;
     /** More keys column number and flags */
     private final int mMoreKeysColumnAndFlags;
     private static final int MORE_KEYS_COLUMN_MASK = 0x000000ff;
@@ -121,7 +121,7 @@ public class Key implements Comparable<Key> {
     private static final String MORE_KEYS_NO_PANEL_AUTO_MORE_KEY = "!noPanelAutoMoreKey!";
 
     /** Background type that represents different key background visual than normal one. */
-    public final int mBackgroundType;
+    private final int mBackgroundType;
     public static final int BACKGROUND_TYPE_EMPTY = 0;
     public static final int BACKGROUND_TYPE_NORMAL = 1;
     public static final int BACKGROUND_TYPE_FUNCTIONAL = 2;
@@ -135,7 +135,7 @@ public class Key implements Comparable<Key> {
     private static final int ACTION_FLAGS_ALT_CODE_WHILE_TYPING = 0x04;
     private static final int ACTION_FLAGS_ENABLE_LONG_PRESS = 0x08;
 
-    public final KeyVisualAttributes mKeyVisualAttributes;
+    private final KeyVisualAttributes mKeyVisualAttributes;
 
     private final OptionalAttributes mOptionalAttributes;
 
@@ -151,7 +151,7 @@ public class Key implements Comparable<Key> {
         public final int mVisualInsetsLeft;
         public final int mVisualInsetsRight;
 
-        public OptionalAttributes(final String outputText, final int altCode,
+        private OptionalAttributes(final String outputText, final int altCode,
                 final int disabledIconId, final int previewIconId,
                 final int visualInsetsLeft, final int visualInsetsRight) {
             mOutputText = outputText;
@@ -161,6 +161,18 @@ public class Key implements Comparable<Key> {
             mVisualInsetsLeft = visualInsetsLeft;
             mVisualInsetsRight = visualInsetsRight;
         }
+
+        public static OptionalAttributes newInstance(final String outputText, final int altCode,
+                final int disabledIconId, final int previewIconId,
+                final int visualInsetsLeft, final int visualInsetsRight) {
+            if (outputText == null && altCode == CODE_UNSPECIFIED
+                    && disabledIconId == ICON_UNDEFINED && previewIconId == ICON_UNDEFINED
+                    && visualInsetsLeft == 0 && visualInsetsRight == 0) {
+                return null;
+            }
+            return new OptionalAttributes(outputText, altCode, disabledIconId, previewIconId,
+                    visualInsetsLeft, visualInsetsRight);
+        }
     }
 
     private final int mHashCode;
@@ -194,12 +206,9 @@ public class Key implements Comparable<Key> {
         mMoreKeys = null;
         mMoreKeysColumnAndFlags = 0;
         mLabel = label;
-        if (outputText == null) {
-            mOptionalAttributes = null;
-        } else {
-            mOptionalAttributes = new OptionalAttributes(outputText, CODE_UNSPECIFIED,
-                    ICON_UNDEFINED, ICON_UNDEFINED, 0, 0);
-        }
+        mOptionalAttributes = OptionalAttributes.newInstance(outputText, CODE_UNSPECIFIED,
+                ICON_UNDEFINED, ICON_UNDEFINED,
+                0 /* visualInsetsLeft */, 0 /* visualInsetsRight */);
         mCode = code;
         mEnabled = (code != CODE_UNSPECIFIED);
         mIconId = iconId;
@@ -360,15 +369,8 @@ public class Key implements Comparable<Key> {
                 KeySpecParser.parseCode(style.getString(keyAttr,
                 R.styleable.Keyboard_Key_altCode), params.mCodesSet, CODE_UNSPECIFIED),
                 needsToUpperCase, locale);
-        if (outputText == null && altCode == CODE_UNSPECIFIED
-                && disabledIconId == ICON_UNDEFINED && previewIconId == ICON_UNDEFINED
-                && visualInsetsLeft == 0 && visualInsetsRight == 0) {
-            mOptionalAttributes = null;
-        } else {
-            mOptionalAttributes = new OptionalAttributes(outputText, altCode,
-                    disabledIconId, previewIconId,
-                    visualInsetsLeft, visualInsetsRight);
-        }
+        mOptionalAttributes = OptionalAttributes.newInstance(outputText, altCode,
+                disabledIconId, previewIconId, visualInsetsLeft, visualInsetsRight);
         mKeyVisualAttributes = KeyVisualAttributes.newInstance(keyAttr);
         keyAttr.recycle();
         mHashCode = computeHashCode(this);
@@ -377,6 +379,35 @@ public class Key implements Comparable<Key> {
         }
     }
 
+    /**
+     * Copy constructor.
+     *
+     * @param key the original key.
+     */
+    protected Key(final Key key) {
+        // Final attributes.
+        mCode = key.mCode;
+        mLabel = key.mLabel;
+        mHintLabel = key.mHintLabel;
+        mLabelFlags = key.mLabelFlags;
+        mIconId = key.mIconId;
+        mWidth = key.mWidth;
+        mHeight = key.mHeight;
+        mX = key.mX;
+        mY = key.mY;
+        mHitBox.set(key.mHitBox);
+        mMoreKeys = key.mMoreKeys;
+        mMoreKeysColumnAndFlags = key.mMoreKeysColumnAndFlags;
+        mBackgroundType = key.mBackgroundType;
+        mActionFlags = key.mActionFlags;
+        mKeyVisualAttributes = key.mKeyVisualAttributes;
+        mOptionalAttributes = key.mOptionalAttributes;
+        mHashCode = key.mHashCode;
+        // Key state.
+        mPressed = key.mPressed;
+        mEnabled = key.mEnabled;
+    }
+
     private static boolean needsToUpperCase(final int labelFlags, final int keyboardElementId) {
         if ((labelFlags & LABEL_FLAGS_PRESERVE_CASE) != 0) return false;
         switch (keyboardElementId) {
@@ -476,6 +507,22 @@ public class Key implements Comparable<Key> {
         }
     }
 
+    public int getCode() {
+        return mCode;
+    }
+
+    public String getLabel() {
+        return mLabel;
+    }
+
+    public String getHintLabel() {
+        return mHintLabel;
+    }
+
+    public MoreKeySpec[] getMoreKeys() {
+        return mMoreKeys;
+    }
+
     public void markAsLeftEdge(final KeyboardParams params) {
         mHitBox.left = params.mLeftPadding;
     }
@@ -522,6 +569,10 @@ public class Key implements Comparable<Key> {
                 && (mLabelFlags & LABEL_FLAGS_SHIFTED_LETTER_ACTIVATED) == 0;
     }
 
+    public KeyVisualAttributes getVisualAttributes() {
+        return mKeyVisualAttributes;
+    }
+
     public final Typeface selectTypeface(final KeyDrawParams params) {
         // TODO: Handle "bold" here too?
         if ((mLabelFlags & LABEL_FLAGS_FONT_NORMAL) != 0) {
@@ -696,6 +747,22 @@ public class Key implements Comparable<Key> {
                 ? iconSet.getIconDrawable(previewIconId) : iconSet.getIconDrawable(mIconId);
     }
 
+    public int getWidth() {
+        return mWidth;
+    }
+
+    public int getHeight() {
+        return mHeight;
+    }
+
+    public int getX() {
+        return mX;
+    }
+
+    public int getY() {
+        return mY;
+    }
+
     public final int getDrawX() {
         final OptionalAttributes attrs = mOptionalAttributes;
         return (attrs == null) ? mX : mX + attrs.mVisualInsetsLeft;
@@ -733,6 +800,10 @@ public class Key implements Comparable<Key> {
         mEnabled = enabled;
     }
 
+    public Rect getHitBox() {
+        return mHitBox;
+    }
+
     /**
      * Detects if a point falls on this key.
      * @param x the x-coordinate of the point
diff --git a/java/src/com/android/inputmethod/keyboard/KeyDetector.java b/java/src/com/android/inputmethod/keyboard/KeyDetector.java
index 17e707f953294602bb0ba237660bbd6ada49f96d..befb6fa92ffaab5ba4b86a1618d9ee4c8751b803 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyDetector.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyDetector.java
@@ -108,8 +108,9 @@ public class KeyDetector {
             if (distance > minDistance) {
                 continue;
             }
-            // To take care of hitbox overlaps, we compare mCode here too.
-            if (primaryKey == null || distance < minDistance || key.mCode > primaryKey.mCode) {
+            // To take care of hitbox overlaps, we compare key's code here too.
+            if (primaryKey == null || distance < minDistance
+                    || key.getCode() > primaryKey.getCode()) {
                 minDistance = distance;
                 primaryKey = key;
             }
@@ -118,7 +119,7 @@ public class KeyDetector {
     }
 
     public static String printableCode(Key key) {
-        return key != null ? Constants.printableCode(key.mCode) : "none";
+        return key != null ? Constants.printableCode(key.getCode()) : "none";
     }
 
     public static String printableCodes(int[] codes) {
diff --git a/java/src/com/android/inputmethod/keyboard/Keyboard.java b/java/src/com/android/inputmethod/keyboard/Keyboard.java
index fefac96fd70324d3e20df4f6a826edc54f28a3e1..c40ddeabe046002e6a991aa53e783c445a884535 100644
--- a/java/src/com/android/inputmethod/keyboard/Keyboard.java
+++ b/java/src/com/android/inputmethod/keyboard/Keyboard.java
@@ -131,7 +131,7 @@ public class Keyboard {
             }
 
             for (final Key key : mKeys) {
-                if (key.mCode == code) {
+                if (key.getCode() == code) {
                     mKeyCache.put(code, key);
                     return key;
                 }
@@ -148,7 +148,7 @@ public class Keyboard {
 
         for (final Key key : mKeys) {
             if (key == aKey) {
-                mKeyCache.put(key.mCode, key);
+                mKeyCache.put(key.getCode(), key);
                 return true;
             }
         }
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardView.java b/java/src/com/android/inputmethod/keyboard/KeyboardView.java
index 28eb585739ddaf4dce3ccdda1b7098f6d840a2e9..d049a861e3c476488d6d3b679c6cc576af747fb3 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardView.java
@@ -265,9 +265,9 @@ public class KeyboardView extends View {
             mClipRegion.setEmpty();
             for (final Key key : mInvalidatedKeys) {
                 if (mKeyboard.hasKey(key)) {
-                    final int x = key.mX + getPaddingLeft();
-                    final int y = key.mY + getPaddingTop();
-                    mWorkingRect.set(x, y, x + key.mWidth, y + key.mHeight);
+                    final int x = key.getX() + getPaddingLeft();
+                    final int y = key.getY() + getPaddingTop();
+                    mWorkingRect.set(x, y, x + key.getWidth(), y + key.getHeight());
                     mClipRegion.union(mWorkingRect);
                 }
             }
@@ -310,11 +310,11 @@ public class KeyboardView extends View {
 
     private void onDrawKey(final Key key, final Canvas canvas, final Paint paint) {
         final int keyDrawX = key.getDrawX() + getPaddingLeft();
-        final int keyDrawY = key.mY + getPaddingTop();
+        final int keyDrawY = key.getY() + getPaddingTop();
         canvas.translate(keyDrawX, keyDrawY);
 
         final int keyHeight = mKeyboard.mMostCommonKeyHeight - mKeyboard.mVerticalGap;
-        final KeyVisualAttributes attr = key.mKeyVisualAttributes;
+        final KeyVisualAttributes attr = key.getVisualAttributes();
         final KeyDrawParams params = mKeyDrawParams.mayCloneAndUpdateParams(keyHeight, attr);
         params.mAnimAlpha = Constants.Color.ALPHA_OPAQUE;
 
@@ -330,7 +330,7 @@ public class KeyboardView extends View {
     protected void onDrawKeyBackground(final Key key, final Canvas canvas) {
         final Rect padding = mKeyBackgroundPadding;
         final int bgWidth = key.getDrawWidth() + padding.left + padding.right;
-        final int bgHeight = key.mHeight + padding.top + padding.bottom;
+        final int bgHeight = key.getHeight() + padding.top + padding.bottom;
         final int bgX = -padding.left;
         final int bgY = -padding.top;
         final int[] drawableState = key.getCurrentDrawableState();
@@ -352,7 +352,7 @@ public class KeyboardView extends View {
     protected void onDrawKeyTopVisuals(final Key key, final Canvas canvas, final Paint paint,
             final KeyDrawParams params) {
         final int keyWidth = key.getDrawWidth();
-        final int keyHeight = key.mHeight;
+        final int keyHeight = key.getHeight();
         final float centerX = keyWidth * 0.5f;
         final float centerY = keyHeight * 0.5f;
 
@@ -363,8 +363,8 @@ public class KeyboardView extends View {
         // Draw key label.
         final Drawable icon = key.getIcon(mKeyboard.mIconsSet, params.mAnimAlpha);
         float positionX = centerX;
-        if (key.mLabel != null) {
-            final String label = key.mLabel;
+        final String label = key.getLabel();
+        if (label != null) {
             paint.setTypeface(key.selectTypeface(params));
             paint.setTextSize(key.selectTextSize(params));
             final float labelCharHeight = TypefaceUtils.getCharHeight(
@@ -441,8 +441,8 @@ public class KeyboardView extends View {
         }
 
         // Draw hint label.
-        if (key.mHintLabel != null) {
-            final String hintLabel = key.mHintLabel;
+        final String hintLabel = key.getHintLabel();
+        if (hintLabel != null) {
             paint.setTextSize(key.selectHintTextSize(params));
             paint.setColor(key.selectHintTextColor(params));
             blendAlpha(paint, params.mAnimAlpha);
@@ -481,7 +481,7 @@ public class KeyboardView extends View {
         }
 
         // Draw key icon.
-        if (key.mLabel == null && icon != null) {
+        if (label == null && icon != null) {
             final int iconWidth = Math.min(icon.getIntrinsicWidth(), keyWidth);
             final int iconHeight = icon.getIntrinsicHeight();
             final int iconX, alignX;
@@ -505,7 +505,7 @@ public class KeyboardView extends View {
             }
         }
 
-        if (key.hasPopupHint() && key.mMoreKeys != null) {
+        if (key.hasPopupHint() && key.getMoreKeys() != null) {
             drawKeyPopupHint(key, canvas, paint, params);
         }
     }
@@ -514,7 +514,7 @@ public class KeyboardView extends View {
     protected void drawKeyPopupHint(final Key key, final Canvas canvas, final Paint paint,
             final KeyDrawParams params) {
         final int keyWidth = key.getDrawWidth();
-        final int keyHeight = key.mHeight;
+        final int keyHeight = key.getHeight();
 
         paint.setTypeface(params.mTypeface);
         paint.setTextSize(params.mHintLetterSize);
@@ -602,9 +602,9 @@ public class KeyboardView extends View {
         if (mInvalidateAllKeys) return;
         if (key == null) return;
         mInvalidatedKeys.add(key);
-        final int x = key.mX + getPaddingLeft();
-        final int y = key.mY + getPaddingTop();
-        invalidate(x, y, x + key.mWidth, y + key.mHeight);
+        final int x = key.getX() + getPaddingLeft();
+        final int y = key.getY() + getPaddingTop();
+        invalidate(x, y, x + key.getWidth(), y + key.getHeight());
     }
 
     @Override
diff --git a/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java b/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java
index f3d0eadc80cadc9b9f819d71bfcbf2cc25043de8..e4e44b6c431e321dc493c42351e06a18a27ce1d5 100644
--- a/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java
@@ -237,7 +237,7 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
                 return;
             }
             sendMessageDelayed(
-                    obtainMessage(MSG_REPEAT_KEY, key.mCode, repeatCount, tracker), delay);
+                    obtainMessage(MSG_REPEAT_KEY, key.getCode(), repeatCount, tracker), delay);
         }
 
         public void cancelKeyRepeatTimer() {
@@ -298,7 +298,7 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
             final MainKeyboardView keyboardView = getOuterInstance();
 
             // When user hits the space or the enter key, just cancel the while-typing timer.
-            final int typedCode = typedKey.mCode;
+            final int typedCode = typedKey.getCode();
             if (typedCode == Constants.CODE_SPACE || typedCode == Constants.CODE_ENTER) {
                 if (isTyping) {
                     startWhileTypingFadeinAnimation(keyboardView);
@@ -807,11 +807,11 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
         }
         // The key preview is placed vertically above the top edge of the parent key with an
         // arbitrary offset.
-        final int previewY = key.mY - previewHeight + mKeyPreviewOffset
+        final int previewY = key.getY() - previewHeight + mKeyPreviewOffset
                 + CoordinateUtils.y(mOriginCoords);
 
         if (background != null) {
-            final int hasMoreKeys = (key.mMoreKeys != null) ? STATE_HAS_MOREKEYS : STATE_NORMAL;
+            final int hasMoreKeys = (key.getMoreKeys() != null) ? STATE_HAS_MOREKEYS : STATE_NORMAL;
             background.setState(KEY_PREVIEW_BACKGROUND_STATE_TABLE[statePosition][hasMoreKeys]);
             background.setAlpha(PREVIEW_ALPHA);
         }
@@ -903,7 +903,7 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
     }
 
     private MoreKeysPanel onCreateMoreKeysPanel(final Key key, final Context context) {
-        if (key.mMoreKeys == null) {
+        if (key.getMoreKeys() == null) {
             return null;
         }
         Keyboard moreKeysKeyboard = mMoreKeysKeyboardCache.get(key);
@@ -938,7 +938,7 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
         }
         final KeyboardActionListener listener = mKeyboardActionListener;
         if (key.hasNoPanelAutoMoreKey()) {
-            final int moreKeyCode = key.mMoreKeys[0].mCode;
+            final int moreKeyCode = key.getMoreKeys()[0].mCode;
             tracker.onLongPressed();
             listener.onPressKey(moreKeyCode, 0 /* repeatCount */, true /* isSinglePointer */);
             listener.onCodeInput(moreKeyCode,
@@ -946,7 +946,7 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
             listener.onReleaseKey(moreKeyCode, false /* withSliding */);
             return;
         }
-        final int code = key.mCode;
+        final int code = key.getCode();
         if (code == Constants.CODE_SPACE || code == Constants.CODE_LANGUAGE_SWITCH) {
             // Long pressing the space key invokes IME switcher dialog.
             if (listener.onCustomRequest(Constants.CUSTOM_CODE_SHOW_INPUT_METHOD_PICKER)) {
@@ -972,13 +972,13 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
         // keys keyboard is placed at the touch point of the parent key.
         final int pointX = (mConfigShowMoreKeysKeyboardAtTouchedPoint && !keyPreviewEnabled)
                 ? CoordinateUtils.x(lastCoords)
-                : key.mX + key.mWidth / 2;
+                : key.getX() + key.getWidth() / 2;
         // The more keys keyboard is usually vertically aligned with the top edge of the parent key
         // (plus vertical gap). If the key preview is enabled, the more keys keyboard is vertically
         // aligned with the bottom edge of the visible part of the key preview.
         // {@code mPreviewVisibleOffset} has been set appropriately in
         // {@link KeyboardView#showKeyPreview(PointerTracker)}.
-        final int pointY = key.mY + mKeyPreviewDrawParams.mPreviewVisibleOffset;
+        final int pointY = key.getY() + mKeyPreviewDrawParams.mPreviewVisibleOffset;
         moreKeysPanel.showMoreKeysPanel(this, this, pointX, pointY, mKeyboardActionListener);
         tracker.onShowMoreKeysPanel(moreKeysPanel);
     }
@@ -1174,13 +1174,14 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
         if (key.altCodeWhileTyping() && key.isEnabled()) {
             params.mAnimAlpha = mAltCodeKeyWhileTypingAnimAlpha;
         }
-        if (key.mCode == Constants.CODE_SPACE) {
+        final int code = key.getCode();
+        if (code == Constants.CODE_SPACE) {
             drawSpacebar(key, canvas, paint);
             // Whether space key needs to show the "..." popup hint for special purposes
             if (key.isLongPressEnabled() && mHasMultipleEnabledIMEsOrSubtypes) {
                 drawKeyPopupHint(key, canvas, paint, params);
             }
-        } else if (key.mCode == Constants.CODE_LANGUAGE_SWITCH) {
+        } else if (code == Constants.CODE_LANGUAGE_SWITCH) {
             super.onDrawKeyTopVisuals(key, canvas, paint, params);
             drawKeyPopupHint(key, canvas, paint, params);
         } else {
@@ -1228,8 +1229,8 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
     }
 
     private void drawSpacebar(final Key key, final Canvas canvas, final Paint paint) {
-        final int width = key.mWidth;
-        final int height = key.mHeight;
+        final int width = key.getWidth();
+        final int height = key.getHeight();
 
         // If input language are explicitly selected.
         if (mNeedsToDisplayLanguage) {
diff --git a/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboard.java b/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboard.java
index 3fd29dcfdba3b7b4dd4ee9ccf38913c543686051..8256d462360708b438ff8d6876f8c2c06229e0c9 100644
--- a/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboard.java
+++ b/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboard.java
@@ -276,6 +276,7 @@ public final class MoreKeysKeyboard extends Keyboard {
             mParams.mVerticalGap = parentKeyboard.mVerticalGap / 2;
             mParentKey = parentKey;
 
+            final MoreKeySpec[] moreKeys = parentKey.getMoreKeys();
             final int width, height;
             // {@link KeyPreviewDrawParams#mPreviewVisibleWidth} should have been set at
             // {@link MainKeyboardView#showKeyPreview(PointerTracker}, though there may be
@@ -283,7 +284,7 @@ public final class MoreKeysKeyboard extends Keyboard {
             // zero-division error at
             // {@link MoreKeysKeyboardParams#setParameters(int,int,int,int,int,int,boolean,int)}.
             final boolean singleMoreKeyWithPreview = parentKeyboardView.isKeyPreviewPopupEnabled()
-                    && !parentKey.noKeyPreview() && parentKey.mMoreKeys.length == 1
+                    && !parentKey.noKeyPreview() && moreKeys.length == 1
                     && keyPreviewDrawParams.mPreviewVisibleWidth > 0;
             if (singleMoreKeyWithPreview) {
                 // Use pre-computed width and height if this more keys keyboard has only one key to
@@ -312,8 +313,8 @@ public final class MoreKeysKeyboard extends Keyboard {
                 mDivider = null;
                 dividerWidth = 0;
             }
-            mParams.setParameters(parentKey.mMoreKeys.length, parentKey.getMoreKeysColumn(),
-                    width, height, parentKey.mX + parentKey.mWidth / 2,
+            mParams.setParameters(moreKeys.length, parentKey.getMoreKeysColumn(),
+                    width, height, parentKey.getX() + parentKey.getWidth() / 2,
                     parentKeyboard.mId.mWidth, parentKey.isFixedColumnOrderMoreKeys(),
                     dividerWidth);
         }
@@ -321,7 +322,7 @@ public final class MoreKeysKeyboard extends Keyboard {
         private static int getMaxKeyWidth(final Key parentKey, final int minKeyWidth,
                 final float padding, final Paint paint) {
             int maxWidth = minKeyWidth;
-            for (final MoreKeySpec spec : parentKey.mMoreKeys) {
+            for (final MoreKeySpec spec : parentKey.getMoreKeys()) {
                 final String label = spec.mLabel;
                 // If the label is single letter, minKeyWidth is enough to hold the label.
                 if (label != null && StringUtils.codePointCount(label) > 1) {
@@ -336,7 +337,7 @@ public final class MoreKeysKeyboard extends Keyboard {
         public MoreKeysKeyboard build() {
             final MoreKeysKeyboardParams params = mParams;
             final int moreKeyFlags = mParentKey.getMoreKeyLabelFlags();
-            final MoreKeySpec[] moreKeys = mParentKey.mMoreKeys;
+            final MoreKeySpec[] moreKeys = mParentKey.getMoreKeys();
             for (int n = 0; n < moreKeys.length; n++) {
                 final MoreKeySpec moreKeySpec = moreKeys[n];
                 final int row = n / params.mNumColumns;
diff --git a/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboardView.java b/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboardView.java
index f00f5a99eaed6f9f0484e01be584ce2c8e31d7b3..973128d3669e5b680ae14604800a70175ded933c 100644
--- a/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboardView.java
@@ -127,7 +127,7 @@ public class MoreKeysKeyboardView extends KeyboardView implements MoreKeysPanel
     public void onUpEvent(final int x, final int y, final int pointerId, final long eventTime) {
         if (mCurrentKey != null && mActivePointerId == pointerId) {
             updateReleaseKeyGraphics(mCurrentKey);
-            onCodeInput(mCurrentKey.mCode, x, y);
+            onCodeInput(mCurrentKey.getCode(), x, y);
             mCurrentKey = null;
         }
     }
diff --git a/java/src/com/android/inputmethod/keyboard/PointerTracker.java b/java/src/com/android/inputmethod/keyboard/PointerTracker.java
index 5387ddb6d2a822f4769a4dd594c7c560b93b57df..d4d0d8718ddbb9141ff8fbf6cdf7aec485c1a55e 100644
--- a/java/src/com/android/inputmethod/keyboard/PointerTracker.java
+++ b/java/src/com/android/inputmethod/keyboard/PointerTracker.java
@@ -510,7 +510,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
             return false;
         }
         if (key.isEnabled()) {
-            mListener.onPressKey(key.mCode, repeatCount, getActivePointerTrackerCount() == 1);
+            mListener.onPressKey(key.getCode(), repeatCount, getActivePointerTrackerCount() == 1);
             final boolean keyboardLayoutHasBeenChanged = mKeyboardLayoutHasBeenChanged;
             mKeyboardLayoutHasBeenChanged = false;
             mTimerProxy.startTypingStateTimer(key);
@@ -776,7 +776,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
         if (sInGesture || !mGestureStrokeWithPreviewPoints.isStartOfAGesture()) {
             return;
         }
-        if (key == null || !Character.isLetter(key.mCode)) {
+        if (key == null || !Character.isLetter(key.getCode())) {
             return;
         }
         if (DEBUG_LISTENER) {
@@ -1075,8 +1075,8 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
                     + " phantom sudden move event (distance=%d) is translated to "
                     + "up[%d,%d,%s]/down[%d,%d,%s] events", mPointerId,
                     getDistance(x, y, lastX, lastY),
-                    lastX, lastY, Constants.printableCode(oldKey.mCode),
-                    x, y, Constants.printableCode(key.mCode)));
+                    lastX, lastY, Constants.printableCode(oldKey.getCode()),
+                    x, y, Constants.printableCode(key.getCode())));
         }
         // TODO: This should be moved to outside of this nested if-clause?
         if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
@@ -1098,8 +1098,8 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
                     + " bogus down-move-up event (raidus=%.2f key diagonal) is "
                     + " translated to up[%d,%d,%s]/down[%d,%d,%s] events",
                     mPointerId, radiusRatio,
-                    lastX, lastY, Constants.printableCode(oldKey.mCode),
-                    x, y, Constants.printableCode(key.mCode)));
+                    lastX, lastY, Constants.printableCode(oldKey.getCode()),
+                    x, y, Constants.printableCode(key.getCode())));
         }
         onUpEventInternal(x, y, eventTime);
         onDownEventInternal(x, y, eventTime);
@@ -1107,7 +1107,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
 
     private void processSildeOutFromOldKey(final Key oldKey) {
         setReleasedKeyGraphics(oldKey);
-        callListenerOnRelease(oldKey, oldKey.mCode, true /* withSliding */);
+        callListenerOnRelease(oldKey, oldKey.getCode(), true /* withSliding */);
         startSlidingKeyInput(oldKey);
         mTimerProxy.cancelKeyTimers();
     }
@@ -1263,7 +1263,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
 
         if (sInGesture) {
             if (currentKey != null) {
-                callListenerOnRelease(currentKey, currentKey.mCode, true /* withSliding */);
+                callListenerOnRelease(currentKey, currentKey.getCode(), true /* withSliding */);
             }
             mayEndBatchInput(eventTime);
             return;
@@ -1376,9 +1376,9 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
         // doesn't have its more keys. (e.g. spacebar, globe key)
         // We always need to start the long press timer if the key has its more keys regardless of
         // whether or not we are in the sliding input mode.
-        if (mIsInSlidingKeyInput && key.mMoreKeys == null) return;
+        if (mIsInSlidingKeyInput && key.getMoreKeys() == null) return;
         final int delay;
-        switch (key.mCode) {
+        switch (key.getCode()) {
         case Constants.CODE_SHIFT:
             delay = sParams.mLongPressShiftLockTimeout;
             break;
@@ -1401,7 +1401,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
             return;
         }
 
-        final int code = key.mCode;
+        final int code = key.getCode();
         callListenerOnCodeInput(key, code, x, y, eventTime);
         callListenerOnRelease(key, code, false /* withSliding */);
     }
@@ -1412,14 +1412,14 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
         if (!key.isRepeatable()) return;
         // Don't start key repeat when we are in sliding input mode.
         if (mIsInSlidingKeyInput) return;
-        detectAndSendKey(key, key.mX, key.mY, SystemClock.uptimeMillis());
+        detectAndSendKey(key, key.getX(), key.getY(), SystemClock.uptimeMillis());
         final int startRepeatCount = 1;
         mTimerProxy.startKeyRepeatTimer(this, startRepeatCount, sParams.mKeyRepeatStartTimeout);
     }
 
     public void onKeyRepeat(final int code, final int repeatCount) {
         final Key key = getKey();
-        if (key == null || key.mCode != code) {
+        if (key == null || key.getCode() != code) {
             return;
         }
         final int nextRepeatCount = repeatCount + 1;
diff --git a/java/src/com/android/inputmethod/keyboard/ProximityInfo.java b/java/src/com/android/inputmethod/keyboard/ProximityInfo.java
index 9b0a33cec99a82f7232538f8d1d1dd6f6af5b5a3..c0c02f10a028dbe65cbc539f92f5b3c2ffd569b6 100644
--- a/java/src/com/android/inputmethod/keyboard/ProximityInfo.java
+++ b/java/src/com/android/inputmethod/keyboard/ProximityInfo.java
@@ -96,7 +96,7 @@ public class ProximityInfo {
 
     private static boolean needsProximityInfo(final Key key) {
         // Don't include special keys into ProximityInfo.
-        return key.mCode >= Constants.CODE_SPACE;
+        return key.getCode() >= Constants.CODE_SPACE;
     }
 
     private static int getProximityInfoKeysCount(final Key[] keys) {
@@ -122,7 +122,7 @@ public class ProximityInfo {
                 if (!needsProximityInfo(neighborKey)) {
                     continue;
                 }
-                proximityCharsArray[infoIndex] = neighborKey.mCode;
+                proximityCharsArray[infoIndex] = neighborKey.getCode();
                 infoIndex++;
             }
         }
@@ -159,11 +159,11 @@ public class ProximityInfo {
             if (!needsProximityInfo(key)) {
                 continue;
             }
-            keyXCoordinates[infoIndex] = key.mX;
-            keyYCoordinates[infoIndex] = key.mY;
-            keyWidths[infoIndex] = key.mWidth;
-            keyHeights[infoIndex] = key.mHeight;
-            keyCharCodes[infoIndex] = key.mCode;
+            keyXCoordinates[infoIndex] = key.getX();
+            keyYCoordinates[infoIndex] = key.getY();
+            keyWidths[infoIndex] = key.getWidth();
+            keyHeights[infoIndex] = key.getHeight();
+            keyCharCodes[infoIndex] = key.getCode();
             infoIndex++;
         }
 
@@ -183,7 +183,7 @@ public class ProximityInfo {
                 if (!needsProximityInfo(key)) {
                     continue;
                 }
-                final Rect hitBox = key.mHitBox;
+                final Rect hitBox = key.getHitBox();
                 sweetSpotCenterXs[infoIndex] = hitBox.exactCenterX();
                 sweetSpotCenterYs[infoIndex] = hitBox.exactCenterY();
                 sweetSpotRadii[infoIndex] = defaultRadius;
@@ -204,7 +204,7 @@ public class ProximityInfo {
                             "  [%2d] row=%d x/y/r=%7.2f/%7.2f/%5.2f %s code=%s", infoIndex, row,
                             sweetSpotCenterXs[infoIndex], sweetSpotCenterYs[infoIndex],
                             sweetSpotRadii[infoIndex], (row < rows ? "correct" : "default"),
-                            Constants.printableCode(key.mCode)));
+                            Constants.printableCode(key.getCode())));
                 }
                 infoIndex++;
             }
@@ -322,19 +322,21 @@ y |---+---+---+---+-v-+-|-+---+---+---+---+---|          | thresholdBase and get
   have to align this on the center of the key. Hence, we don't need a separate value for
   bottomPixelWithinThreshold and call this yEnd right away.
 */
-            final int topPixelWithinThreshold = key.mY - threshold;
+            final int keyX = key.getX();
+            final int keyY = key.getY();
+            final int topPixelWithinThreshold = keyY - threshold;
             final int yDeltaToGrid = topPixelWithinThreshold % mCellHeight;
             final int yMiddleOfTopCell = topPixelWithinThreshold - yDeltaToGrid + halfCellHeight;
             final int yStart = Math.max(halfCellHeight,
                     yMiddleOfTopCell + (yDeltaToGrid <= halfCellHeight ? 0 : mCellHeight));
-            final int yEnd = Math.min(fullGridHeight, key.mY + key.mHeight + threshold);
+            final int yEnd = Math.min(fullGridHeight, keyY + key.getHeight() + threshold);
 
-            final int leftPixelWithinThreshold = key.mX - threshold;
+            final int leftPixelWithinThreshold = keyX - threshold;
             final int xDeltaToGrid = leftPixelWithinThreshold % mCellWidth;
             final int xMiddleOfLeftCell = leftPixelWithinThreshold - xDeltaToGrid + halfCellWidth;
             final int xStart = Math.max(halfCellWidth,
                     xMiddleOfLeftCell + (xDeltaToGrid <= halfCellWidth ? 0 : mCellWidth));
-            final int xEnd = Math.min(fullGridWidth, key.mX + key.mWidth + threshold);
+            final int xEnd = Math.min(fullGridWidth, keyX + key.getWidth() + threshold);
 
             int baseIndexOfCurrentRow = (yStart / mCellHeight) * mGridWidth + (xStart / mCellWidth);
             for (int centerY = yStart; centerY <= yEnd; centerY += mCellHeight) {
@@ -372,7 +374,7 @@ y |---+---+---+---+-v-+-|-+---+---+---+---+---|          | thresholdBase and get
             if (index >= destLength) {
                 break;
             }
-            final int code = key.mCode;
+            final int code = key.getCode();
             if (code <= Constants.CODE_SPACE) {
                 break;
             }
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardBuilder.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardBuilder.java
index b34d7c45f1cec97887ab8499ea1c95eee98f84d3..8261016b493efbaf8dc1e5128ddfa4ea87b7bb43 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardBuilder.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardBuilder.java
@@ -405,7 +405,7 @@ public class KeyboardBuilder<KP extends KeyboardParams> {
             if (DEBUG) {
                 startEndTag("<%s%s %s moreKeys=%s />", TAG_KEY,
                         (key.isEnabled() ? "" : " disabled"), key,
-                        Arrays.toString(key.mMoreKeys));
+                        Arrays.toString(key.getMoreKeys()));
             }
             XmlParseUtils.checkEndTag(TAG_KEY, parser);
             endKey(key);
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardParams.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardParams.java
index a57b83ac05f21c7e18701a0904a57ef38651c2a7..d32bb75819292c2f63642ee239562e06de051e98 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardParams.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardParams.java
@@ -85,7 +85,7 @@ public class KeyboardParams {
     public void onAddKey(final Key newKey) {
         final Key key = (mKeysCache != null) ? mKeysCache.get(newKey) : newKey;
         final boolean isSpacer = key.isSpacer();
-        if (isSpacer && key.mWidth == 0) {
+        if (isSpacer && key.getWidth() == 0) {
             // Ignore zero width {@link Spacer}.
             return;
         }
@@ -94,7 +94,7 @@ public class KeyboardParams {
             return;
         }
         updateHistogram(key);
-        if (key.mCode == Constants.CODE_SHIFT) {
+        if (key.getCode() == Constants.CODE_SHIFT) {
             mShiftKeys.add(key);
         }
         if (key.altCodeWhileTyping()) {
@@ -125,14 +125,14 @@ public class KeyboardParams {
     }
 
     private void updateHistogram(final Key key) {
-        final int height = key.mHeight + mVerticalGap;
+        final int height = key.getHeight() + mVerticalGap;
         final int heightCount = updateHistogramCounter(mHeightHistogram, height);
         if (heightCount > mMaxHeightCount) {
             mMaxHeightCount = heightCount;
             mMostCommonKeyHeight = height;
         }
 
-        final int width = key.mWidth + mHorizontalGap;
+        final int width = key.getWidth() + mHorizontalGap;
         final int widthCount = updateHistogramCounter(mWidthHistogram, width);
         if (widthCount > mMaxWidthCount) {
             mMaxWidthCount = widthCount;
diff --git a/java/src/com/android/inputmethod/latin/WordComposer.java b/java/src/com/android/inputmethod/latin/WordComposer.java
index a09ca605c8f2e80596f84ec93f8e81c27824a4a0..039dadc66be43f16cd30749fdbab3fd139f998aa 100644
--- a/java/src/com/android/inputmethod/latin/WordComposer.java
+++ b/java/src/com/android/inputmethod/latin/WordComposer.java
@@ -272,8 +272,8 @@ public final class WordComposer {
         final int x, y;
         final Key key;
         if (keyboard != null && (key = keyboard.getKey(codePoint)) != null) {
-            x = key.mX + key.mWidth / 2;
-            y = key.mY + key.mHeight / 2;
+            x = key.getX() + key.getWidth() / 2;
+            y = key.getY() + key.getHeight() / 2;
         } else {
             x = Constants.NOT_A_COORDINATE;
             y = Constants.NOT_A_COORDINATE;
diff --git a/java/src/com/android/inputmethod/research/JsonUtils.java b/java/src/com/android/inputmethod/research/JsonUtils.java
index 63d524df761aec5e4e428b8380a3d50b2104fbf8..977f843e9ee5c7a9629f80fa93d4a234c6983bf1 100644
--- a/java/src/com/android/inputmethod/research/JsonUtils.java
+++ b/java/src/com/android/inputmethod/research/JsonUtils.java
@@ -75,12 +75,12 @@ import java.util.Map;
 
     private static void writeJson(final Key key, final JsonWriter jsonWriter) throws IOException {
         jsonWriter.beginObject();
-        jsonWriter.name("code").value(key.mCode);
+        jsonWriter.name("code").value(key.getCode());
         jsonWriter.name("altCode").value(key.getAltCode());
-        jsonWriter.name("x").value(key.mX);
-        jsonWriter.name("y").value(key.mY);
-        jsonWriter.name("w").value(key.mWidth);
-        jsonWriter.name("h").value(key.mHeight);
+        jsonWriter.name("x").value(key.getX());
+        jsonWriter.name("y").value(key.getY());
+        jsonWriter.name("w").value(key.getWidth());
+        jsonWriter.name("h").value(key.getHeight());
         jsonWriter.endObject();
     }
 
diff --git a/tests/src/com/android/inputmethod/latin/InputTestsBase.java b/tests/src/com/android/inputmethod/latin/InputTestsBase.java
index ead134b73e89d019f40e287d5d52da54c7519957..cc3e0d74d5b046ecd85128a0ddf5a32a5f97565f 100644
--- a/tests/src/com/android/inputmethod/latin/InputTestsBase.java
+++ b/tests/src/com/android/inputmethod/latin/InputTestsBase.java
@@ -207,8 +207,8 @@ public class InputTestsBase extends ServiceTestCase<LatinIMEForTests> {
         //mLatinIME.onPressKey(codePoint, 0 /* repeatCount */, true /* isSinglePointer */);
         final Key key = mKeyboard.getKey(codePoint);
         if (key != null) {
-            final int x = key.mX + key.mWidth / 2;
-            final int y = key.mY + key.mHeight / 2;
+            final int x = key.getX() + key.getWidth() / 2;
+            final int y = key.getY() + key.getHeight() / 2;
             mLatinIME.onCodeInput(codePoint, x, y);
             return;
         }