Merge "Hide voice input key from URI, Email, Number, and Phone layout"
diff --git a/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java b/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java
index 9a859bf..f513ac1 100644
--- a/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java
@@ -35,7 +35,6 @@
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.inputmethod.InputMethodSubtype;
-import android.widget.TextView;
 
 import com.android.inputmethod.accessibility.AccessibilityUtils;
 import com.android.inputmethod.accessibility.MainKeyboardAccessibilityDelegate;
@@ -48,6 +47,7 @@
 import com.android.inputmethod.keyboard.internal.KeyPreviewChoreographer;
 import com.android.inputmethod.keyboard.internal.KeyPreviewDrawParams;
 import com.android.inputmethod.keyboard.internal.LanguageOnSpacebarHelper;
+import com.android.inputmethod.keyboard.internal.MoreKeySpec;
 import com.android.inputmethod.keyboard.internal.NonDistinctMultitouchHelper;
 import com.android.inputmethod.keyboard.internal.SlidingKeyInputDrawingPreview;
 import com.android.inputmethod.keyboard.internal.TimerHandler;
@@ -428,15 +428,6 @@
         windowContentView.addView(mDrawingPreviewPlacerView);
     }
 
-    /**
-     * Returns the enabled state of the key feedback preview
-     * @return whether or not the key feedback preview is enabled
-     * @see #setKeyPreviewPopupEnabled(boolean, int)
-     */
-    public boolean isKeyPreviewPopupEnabled() {
-        return mKeyPreviewDrawParams.isPopupEnabled();
-    }
-
     // Implements {@link DrawingHandler.Callbacks} method.
     @Override
     public void dismissAllKeyPreviews() {
@@ -461,12 +452,9 @@
         }
 
         locatePreviewPlacerView();
-        final TextView previewTextView = mKeyPreviewChoreographer.getKeyPreviewTextView(
-                key, mDrawingPreviewPlacerView);
         getLocationInWindow(mOriginCoords);
-        mKeyPreviewChoreographer.placeKeyPreview(key, previewTextView, keyboard.mIconsSet,
-                mKeyDrawParams, getWidth(), mOriginCoords);
-        mKeyPreviewChoreographer.showKeyPreview(key, previewTextView, isHardwareAccelerated());
+        mKeyPreviewChoreographer.placeKeyPreviewAndShow(key, keyboard.mIconsSet, mKeyDrawParams,
+                getWidth(), mOriginCoords, mDrawingPreviewPlacerView, isHardwareAccelerated());
     }
 
     // Implements {@link TimerHandler.Callbacks} method.
@@ -557,13 +545,25 @@
     }
 
     private MoreKeysPanel onCreateMoreKeysPanel(final Key key, final Context context) {
-        if (key.getMoreKeys() == null) {
+        final MoreKeySpec[] moreKeys = key.getMoreKeys();
+        if (moreKeys == null) {
             return null;
         }
         Keyboard moreKeysKeyboard = mMoreKeysKeyboardCache.get(key);
         if (moreKeysKeyboard == null) {
-            moreKeysKeyboard = new MoreKeysKeyboard.Builder(
-                    context, key, this, mKeyPreviewDrawParams).build();
+            // {@link KeyPreviewDrawParams#mPreviewVisibleWidth} should have been set at
+            // {@link KeyPreviewChoreographer#placeKeyPreview(Key,TextView,KeyboardIconsSet,KeyDrawParams,int,int[]},
+            // though there may be some chances that the value is zero. <code>width == 0</code>
+            // will cause zero-division error at
+            // {@link MoreKeysKeyboardParams#setParameters(int,int,int,int,int,int,boolean,int)}.
+            final boolean singleMoreKeyWithPreview = mKeyPreviewDrawParams.isPopupEnabled()
+                    && !key.noKeyPreview() && moreKeys.length == 1
+                    && mKeyPreviewDrawParams.getVisibleWidth() > 0;
+            final MoreKeysKeyboard.Builder builder = new MoreKeysKeyboard.Builder(
+                    context, key, getKeyboard(), singleMoreKeyWithPreview,
+                    mKeyPreviewDrawParams.getVisibleWidth(),
+                    mKeyPreviewDrawParams.getVisibleHeight(), newLabelPaint(key));
+            moreKeysKeyboard = builder.build();
             mMoreKeysKeyboardCache.put(key, moreKeysKeyboard);
         }
 
@@ -619,7 +619,8 @@
 
         final int[] lastCoords = CoordinateUtils.newInstance();
         tracker.getLastCoordinates(lastCoords);
-        final boolean keyPreviewEnabled = isKeyPreviewPopupEnabled() && !key.noKeyPreview();
+        final boolean keyPreviewEnabled = mKeyPreviewDrawParams.isPopupEnabled()
+                && !key.noKeyPreview();
         // The more keys keyboard is usually horizontally aligned with the center of the parent key.
         // If showMoreKeysKeyboardAtTouchedPoint is true and the key preview is disabled, the more
         // keys keyboard is placed at the touch point of the parent key.
diff --git a/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboard.java b/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboard.java
index a72f791..353e07c 100644
--- a/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboard.java
+++ b/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboard.java
@@ -21,7 +21,6 @@
 import android.graphics.drawable.Drawable;
 
 import com.android.inputmethod.annotations.UsedForTesting;
-import com.android.inputmethod.keyboard.internal.KeyPreviewDrawParams;
 import com.android.inputmethod.keyboard.internal.KeyboardBuilder;
 import com.android.inputmethod.keyboard.internal.KeyboardIconsSet;
 import com.android.inputmethod.keyboard.internal.KeyboardParams;
@@ -260,32 +259,25 @@
         /**
          * The builder of MoreKeysKeyboard.
          * @param context the context of {@link MoreKeysKeyboardView}.
-         * @param parentKey the {@link Key} that invokes more keys keyboard.
-         * @param parentKeyboardView the {@link KeyboardView} that contains the parentKey.
+         * @param key the {@link Key} that invokes more keys keyboard.
+         * @param keyboard the {@link Keyboard} that contains the parentKey.
+         * @param singleMoreKeyWithPreview true if the <code>key</code> has only one more key
+         *        and key popup preview is enabled.
          * @param keyPreviewDrawParams the parameter to place key preview.
+         * @param paintToMeasure the {@link Paint} object to measure a more key width
          */
-        public Builder(final Context context, final Key parentKey,
-                final MainKeyboardView parentKeyboardView,
-                final KeyPreviewDrawParams keyPreviewDrawParams) {
+        public Builder(final Context context, final Key key, final Keyboard keyboard,
+                final boolean singleMoreKeyWithPreview, final int keyPreviewVisibleWidth,
+                final int keyPreviewVisibleHeight, final Paint paintToMeasure) {
             super(context, new MoreKeysKeyboardParams());
-            final Keyboard parentKeyboard = parentKeyboardView.getKeyboard();
-            load(parentKeyboard.mMoreKeysTemplate, parentKeyboard.mId);
+            load(keyboard.mMoreKeysTemplate, keyboard.mId);
 
             // TODO: More keys keyboard's vertical gap is currently calculated heuristically.
             // Should revise the algorithm.
-            mParams.mVerticalGap = parentKeyboard.mVerticalGap / 2;
-            mParentKey = parentKey;
+            mParams.mVerticalGap = keyboard.mVerticalGap / 2;
+            mParentKey = key;
 
-            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
-            // some chances that the value is zero. <code>width == 0</code> will cause
-            // zero-division error at
-            // {@link MoreKeysKeyboardParams#setParameters(int,int,int,int,int,int,boolean,int)}.
-            final boolean singleMoreKeyWithPreview = parentKeyboardView.isKeyPreviewPopupEnabled()
-                    && !parentKey.noKeyPreview() && moreKeys.length == 1
-                    && keyPreviewDrawParams.getVisibleWidth() > 0;
+            final int keyWidth, rowHeight;
             if (singleMoreKeyWithPreview) {
                 // Use pre-computed width and height if this more keys keyboard has only one key to
                 // mitigate visual flicker between key preview and more keys keyboard.
@@ -294,29 +286,28 @@
                 // left/right/top paddings. The bottom paddings of both backgrounds don't need to
                 // be considered because the vertical positions of both backgrounds were already
                 // adjusted with their bottom paddings deducted.
-                width = keyPreviewDrawParams.getVisibleWidth();
-                height = keyPreviewDrawParams.getVisibleHeight() + mParams.mVerticalGap;
+                keyWidth = keyPreviewVisibleWidth;
+                rowHeight = keyPreviewVisibleHeight + mParams.mVerticalGap;
             } else {
                 final float padding = context.getResources().getDimension(
                         R.dimen.config_more_keys_keyboard_key_horizontal_padding)
-                        + (parentKey.hasLabelsInMoreKeys()
+                        + (key.hasLabelsInMoreKeys()
                                 ? mParams.mDefaultKeyWidth * LABEL_PADDING_RATIO : 0.0f);
-                width = getMaxKeyWidth(parentKey, mParams.mDefaultKeyWidth, padding,
-                        parentKeyboardView.newLabelPaint(parentKey));
-                height = parentKeyboard.mMostCommonKeyHeight;
+                keyWidth = getMaxKeyWidth(key, mParams.mDefaultKeyWidth, padding, paintToMeasure);
+                rowHeight = keyboard.mMostCommonKeyHeight;
             }
             final int dividerWidth;
-            if (parentKey.needsDividersInMoreKeys()) {
+            if (key.needsDividersInMoreKeys()) {
                 mDivider = mResources.getDrawable(R.drawable.more_keys_divider);
-                dividerWidth = (int)(width * DIVIDER_RATIO);
+                dividerWidth = (int)(keyWidth * DIVIDER_RATIO);
             } else {
                 mDivider = null;
                 dividerWidth = 0;
             }
-            mParams.setParameters(moreKeys.length, parentKey.getMoreKeysColumn(),
-                    width, height, parentKey.getX() + parentKey.getWidth() / 2,
-                    parentKeyboard.mId.mWidth, parentKey.isFixedColumnOrderMoreKeys(),
-                    dividerWidth);
+            final MoreKeySpec[] moreKeys = key.getMoreKeys();
+            mParams.setParameters(moreKeys.length, key.getMoreKeysColumn(), keyWidth, rowHeight,
+                    key.getX() + key.getWidth() / 2, keyboard.mId.mWidth,
+                    key.isFixedColumnOrderMoreKeys(), dividerWidth);
         }
 
         private static int getMaxKeyWidth(final Key parentKey, final int minKeyWidth,
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyPreviewChoreographer.java b/java/src/com/android/inputmethod/keyboard/internal/KeyPreviewChoreographer.java
index 605519b..d4c6710 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyPreviewChoreographer.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyPreviewChoreographer.java
@@ -57,7 +57,7 @@
         mParams = params;
     }
 
-    public TextView getKeyPreviewTextView(final Key key, final ViewGroup placerView) {
+    private TextView getKeyPreviewTextView(final Key key, final ViewGroup placerView) {
         TextView previewTextView = mShowingKeyPreviewTextViews.remove(key);
         if (previewTextView != null) {
             return previewTextView;
@@ -134,7 +134,16 @@
     private static final int STATE_NORMAL = 0;
     private static final int STATE_HAS_MOREKEYS = 1;
 
-    public void placeKeyPreview(final Key key, final TextView previewTextView,
+    public void placeKeyPreviewAndShow(final Key key, final KeyboardIconsSet iconsSet,
+            final KeyDrawParams drawParams, final int keyboardViewWidth, final int[] keyboardOrigin,
+            final ViewGroup placerView, final boolean withAnimation) {
+        final TextView previewTextView = getKeyPreviewTextView(key, placerView);
+        placeKeyPreview(
+                key, previewTextView, iconsSet, drawParams, keyboardViewWidth, keyboardOrigin);
+        showKeyPreview(key, previewTextView, withAnimation);
+    }
+
+    private void placeKeyPreview(final Key key, final TextView previewTextView,
             final KeyboardIconsSet iconsSet, final KeyDrawParams drawParams,
             final int keyboardViewWidth, final int[] originCoords) {
         previewTextView.setTextColor(drawParams.mPreviewTextColor);
@@ -189,7 +198,7 @@
         previewTextView.setPivotY(previewHeight);
     }
 
-    public void showKeyPreview(final Key key, final TextView previewTextView,
+    private void showKeyPreview(final Key key, final TextView previewTextView,
             final boolean withAnimation) {
         if (!withAnimation) {
             previewTextView.setVisibility(View.VISIBLE);