Merge "Compile code used in logging conditionally so that gcc does not complain about unused-but-set variables."
diff --git a/java/res/values-sw600dp/config.xml b/java/res/values-sw600dp/config.xml
index 75c0edf..011054d 100644
--- a/java/res/values-sw600dp/config.xml
+++ b/java/res/values-sw600dp/config.xml
@@ -25,7 +25,6 @@
     <bool name="config_enable_show_recorrection_option">false</bool>
     <bool name="config_enable_quick_fixes_option">false</bool>
     <bool name="config_enable_bigram_suggestions_option">false</bool>
-    <bool name="config_swipe_down_dismiss_keyboard_enabled">false</bool>
     <bool name="config_sliding_key_input_enabled">false</bool>
     <bool name="config_digit_popup_characters_enabled">false</bool>
     <!-- Whether or not Popup on key press is enabled by default -->
diff --git a/java/res/values-sw768dp/config.xml b/java/res/values-sw768dp/config.xml
index 4025b0e..2828f9d 100644
--- a/java/res/values-sw768dp/config.xml
+++ b/java/res/values-sw768dp/config.xml
@@ -25,7 +25,6 @@
     <bool name="config_enable_show_recorrection_option">false</bool>
     <bool name="config_enable_quick_fixes_option">false</bool>
     <bool name="config_enable_bigram_suggestions_option">false</bool>
-    <bool name="config_swipe_down_dismiss_keyboard_enabled">false</bool>
     <bool name="config_sliding_key_input_enabled">false</bool>
     <bool name="config_digit_popup_characters_enabled">false</bool>
     <!-- Whether or not Popup on key press is enabled by default -->
diff --git a/java/res/values/config.xml b/java/res/values/config.xml
index 40cca95..86eeae7 100644
--- a/java/res/values/config.xml
+++ b/java/res/values/config.xml
@@ -19,7 +19,6 @@
 -->
 
 <resources>
-    <bool name="config_swipeDisambiguation">true</bool>
     <bool name="config_enable_show_settings_key_option">true</bool>
     <bool name="config_enable_show_voice_key_option">true</bool>
     <bool name="config_enable_show_popup_on_keypress_option">true</bool>
@@ -27,7 +26,6 @@
     <bool name="config_enable_quick_fixes_option">true</bool>
     <bool name="config_enable_bigram_suggestions_option">true</bool>
     <bool name="config_enable_usability_study_mode_option">false</bool>
-    <bool name="config_swipe_down_dismiss_keyboard_enabled">true</bool>
     <bool name="config_sliding_key_input_enabled">true</bool>
     <bool name="config_digit_popup_characters_enabled">true</bool>
     <!-- Whether or not Popup on key press is enabled by default -->
diff --git a/java/src/com/android/inputmethod/accessibility/AccessibleKeyboardViewProxy.java b/java/src/com/android/inputmethod/accessibility/AccessibleKeyboardViewProxy.java
index a87ff98..b18cbd3 100644
--- a/java/src/com/android/inputmethod/accessibility/AccessibleKeyboardViewProxy.java
+++ b/java/src/com/android/inputmethod/accessibility/AccessibleKeyboardViewProxy.java
@@ -200,8 +200,8 @@
     }
 
     private void fireKeyPressEvent(PointerTracker tracker, int x, int y, long eventTime) {
-        tracker.onDownEvent(x, y, eventTime, null);
-        tracker.onUpEvent(x, y, eventTime + DELAY_KEY_PRESS, null);
+        tracker.onDownEvent(x, y, eventTime);
+        tracker.onUpEvent(x, y, eventTime + DELAY_KEY_PRESS);
     }
 
     private class KeyboardFlickGestureDetector extends FlickGestureDetector {
diff --git a/java/src/com/android/inputmethod/keyboard/KeyDetector.java b/java/src/com/android/inputmethod/keyboard/KeyDetector.java
index 85418a6..6d25025 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyDetector.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyDetector.java
@@ -73,11 +73,10 @@
         return y + mCorrectionY;
     }
 
-    protected List<Key> getKeys() {
+    public Keyboard getKeyboard() {
         if (mKeyboard == null)
             throw new IllegalStateException("keyboard isn't set");
-        // mKeyboard is guaranteed not to be null at setKeybaord() method if mKeys is not null
-        return mKeyboard.getKeys();
+        return mKeyboard;
     }
 
     public void setProximityCorrectionEnabled(boolean enabled) {
@@ -154,7 +153,7 @@
     }
 
     private void getNearbyKeyCodes(final int[] allCodes) {
-        final List<Key> keys = getKeys();
+        final List<Key> keys = getKeyboard().getKeys();
         final int[] indices = mIndices;
 
         // allCodes[0] should always have the key code even if it is a non-letter key.
@@ -188,7 +187,7 @@
      * @return The nearest key index
      */
     public int getKeyIndexAndNearbyCodes(int x, int y, final int[] allCodes) {
-        final List<Key> keys = getKeys();
+        final List<Key> keys = getKeyboard().getKeys();
         final int touchX = getTouchX(x);
         final int touchY = getTouchY(y);
 
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardActionListener.java b/java/src/com/android/inputmethod/keyboard/KeyboardActionListener.java
index 7e67d6f..905f779 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardActionListener.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardActionListener.java
@@ -70,9 +70,4 @@
      * Called when user released a finger outside any key.
      */
     public void onCancelInput();
-
-    /**
-     * Called when the user quickly moves the finger from up to down.
-     */
-    public void onSwipeDown();
 }
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
index 275e9d1..7ad947c 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
@@ -763,7 +763,7 @@
         }
 
         mKeyboardView = (LatinKeyboardView) mCurrentInputView.findViewById(R.id.keyboard_view);
-        mKeyboardView.setOnKeyboardActionListener(mInputMethodService);
+        mKeyboardView.setKeyboardActionListener(mInputMethodService);
 
         // This always needs to be set since the accessibility state can
         // potentially change without the input view being re-created.
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardView.java b/java/src/com/android/inputmethod/keyboard/KeyboardView.java
index d1345db..e31aa84 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardView.java
@@ -331,7 +331,6 @@
             mPreviewText = null;
             mShowKeyPreviewPopup = false;
         }
-        // TODO: Use Theme (android.R.styleable.Theme_backgroundDimAmount)
         mBackgroundDimAmount = a.getFloat(R.styleable.KeyboardView_backgroundDimAmount, 0.5f);
         a.recycle();
 
@@ -350,12 +349,6 @@
         return a.getFraction(index, 1000, 1000, 1) / 1000.0f;
     }
 
-    @Override
-    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
-        // TODO: Should notify InputMethodService instead?
-        KeyboardSwitcher.getInstance().onSizeChanged();
-    }
-
     /**
      * Attaches a keyboard to this view. The keyboard can be switched at any time and the
      * view will re-layout itself to accommodate the keyboard.
diff --git a/java/src/com/android/inputmethod/keyboard/LatinKeyboardBaseView.java b/java/src/com/android/inputmethod/keyboard/LatinKeyboardBaseView.java
index c8cfb43..60af1ec 100644
--- a/java/src/com/android/inputmethod/keyboard/LatinKeyboardBaseView.java
+++ b/java/src/com/android/inputmethod/keyboard/LatinKeyboardBaseView.java
@@ -35,7 +35,6 @@
 import com.android.inputmethod.accessibility.AccessibleKeyboardViewProxy;
 import com.android.inputmethod.keyboard.internal.MiniKeyboardBuilder;
 import com.android.inputmethod.keyboard.internal.PointerTrackerQueue;
-import com.android.inputmethod.keyboard.internal.SwipeTracker;
 import com.android.inputmethod.latin.R;
 import com.android.inputmethod.latin.StaticInnerHandlerWrapper;
 
@@ -74,7 +73,7 @@
     private final ArrayList<PointerTracker> mPointerTrackers = new ArrayList<PointerTracker>();
 
     // TODO: Let the PointerTracker class manage this pointer queue
-    private final PointerTrackerQueue mPointerQueue = new PointerTrackerQueue();
+    private final PointerTrackerQueue mPointerQueue;
 
     private final boolean mHasDistinctMultitouch;
     private int mOldPointerCount = 1;
@@ -82,11 +81,8 @@
 
     protected KeyDetector mKeyDetector;
 
-    // Swipe gesture detector
+    // To detect double tap.
     protected GestureDetector mGestureDetector;
-    private final SwipeTracker mSwipeTracker = new SwipeTracker();
-    private final int mSwipeThreshold;
-    private final boolean mDisambiguateSwipe;
 
     private final KeyTimerHandler mKeyTimerHandler = new KeyTimerHandler(this);
 
@@ -172,6 +168,52 @@
         }
     }
 
+    private class DoubleTapListener extends GestureDetector.SimpleOnGestureListener {
+        private boolean mProcessingShiftDoubleTapEvent = false;
+
+        @Override
+        public boolean onDoubleTap(MotionEvent firstDown) {
+            final Keyboard keyboard = getKeyboard();
+            if (ENABLE_CAPSLOCK_BY_DOUBLETAP && keyboard instanceof LatinKeyboard
+                    && ((LatinKeyboard) keyboard).isAlphaKeyboard()) {
+                final int pointerIndex = firstDown.getActionIndex();
+                final int id = firstDown.getPointerId(pointerIndex);
+                final PointerTracker tracker = getPointerTracker(id);
+                // If the first down event is on shift key.
+                if (tracker.isOnShiftKey((int) firstDown.getX(), (int) firstDown.getY())) {
+                    mProcessingShiftDoubleTapEvent = true;
+                    return true;
+                }
+            }
+            mProcessingShiftDoubleTapEvent = false;
+            return false;
+        }
+
+        @Override
+        public boolean onDoubleTapEvent(MotionEvent secondTap) {
+            if (mProcessingShiftDoubleTapEvent
+                    && secondTap.getAction() == MotionEvent.ACTION_DOWN) {
+                final MotionEvent secondDown = secondTap;
+                final int pointerIndex = secondDown.getActionIndex();
+                final int id = secondDown.getPointerId(pointerIndex);
+                final PointerTracker tracker = getPointerTracker(id);
+                // If the second down event is also on shift key.
+                if (tracker.isOnShiftKey((int) secondDown.getX(), (int) secondDown.getY())) {
+                    // Detected a double tap on shift key. If we are in the ignoring double tap
+                    // mode, it means we have already turned off caps lock in
+                    // {@link KeyboardSwitcher#onReleaseShift} .
+                    final boolean ignoringDoubleTap = mKeyTimerHandler.isIgnoringDoubleTap();
+                    if (!ignoringDoubleTap)
+                        onDoubleTapShiftKey(tracker);
+                    return true;
+                }
+                // Otherwise these events should not be handled as double tap.
+                mProcessingShiftDoubleTapEvent = false;
+            }
+            return mProcessingShiftDoubleTapEvent;
+        }
+    }
+
     public LatinKeyboardBaseView(Context context, AttributeSet attrs) {
         this(context, attrs, R.attr.keyboardViewStyle);
     }
@@ -183,91 +225,23 @@
                 attrs, R.styleable.KeyboardView, defStyle, R.style.KeyboardView);
         mVerticalCorrection = a.getDimensionPixelOffset(
                 R.styleable.KeyboardView_verticalCorrection, 0);
-
         mPopupLayout = a.getResourceId(R.styleable.KeyboardView_popupLayout, 0);
-        // TODO: Use Theme (android.R.styleable.Theme_backgroundDimAmount)
         a.recycle();
 
         final Resources res = getResources();
-
         final float keyHysteresisDistance = res.getDimension(R.dimen.key_hysteresis_distance);
         mKeyDetector = new KeyDetector(keyHysteresisDistance);
-        mSwipeThreshold = (int) (500 * res.getDisplayMetrics().density);
-        // TODO: Refer to frameworks/base/core/res/res/values/config.xml
-        mDisambiguateSwipe = res.getBoolean(R.bool.config_swipeDisambiguation);
-
-        GestureDetector.SimpleOnGestureListener listener =
-                new GestureDetector.SimpleOnGestureListener() {
-            private boolean mProcessingShiftDoubleTapEvent = false;
-
-            @Override
-            public boolean onFling(MotionEvent me1, MotionEvent me2, float velocityX,
-                    float velocityY) {
-                final float absX = Math.abs(velocityX);
-                final float absY = Math.abs(velocityY);
-                float deltaY = me2.getY() - me1.getY();
-                int travelY = getHeight() / 2; // Half the keyboard height
-                mSwipeTracker.computeCurrentVelocity(1000);
-                final float endingVelocityY = mSwipeTracker.getYVelocity();
-                if (velocityY > mSwipeThreshold && absX < absY / 2 && deltaY > travelY) {
-                    if (mDisambiguateSwipe && endingVelocityY >= velocityY / 4) {
-                        onSwipeDown();
-                        return true;
-                    }
-                }
-                return false;
-            }
-
-            @Override
-            public boolean onDoubleTap(MotionEvent firstDown) {
-                final Keyboard keyboard = getKeyboard();
-                if (ENABLE_CAPSLOCK_BY_DOUBLETAP && keyboard instanceof LatinKeyboard
-                        && ((LatinKeyboard) keyboard).isAlphaKeyboard()) {
-                    final int pointerIndex = firstDown.getActionIndex();
-                    final int id = firstDown.getPointerId(pointerIndex);
-                    final PointerTracker tracker = getPointerTracker(id);
-                    // If the first down event is on shift key.
-                    if (tracker.isOnShiftKey((int)firstDown.getX(), (int)firstDown.getY())) {
-                        mProcessingShiftDoubleTapEvent = true;
-                        return true;
-                    }
-                }
-                mProcessingShiftDoubleTapEvent = false;
-                return false;
-            }
-
-            @Override
-            public boolean onDoubleTapEvent(MotionEvent secondTap) {
-                if (mProcessingShiftDoubleTapEvent
-                        && secondTap.getAction() == MotionEvent.ACTION_DOWN) {
-                    final MotionEvent secondDown = secondTap;
-                    final int pointerIndex = secondDown.getActionIndex();
-                    final int id = secondDown.getPointerId(pointerIndex);
-                    final PointerTracker tracker = getPointerTracker(id);
-                    // If the second down event is also on shift key.
-                    if (tracker.isOnShiftKey((int)secondDown.getX(), (int)secondDown.getY())) {
-                        // Detected a double tap on shift key. If we are in the ignoring double tap
-                        // mode, it means we have already turned off caps lock in
-                        // {@link KeyboardSwitcher#onReleaseShift} .
-                        final boolean ignoringDoubleTap = mKeyTimerHandler.isIgnoringDoubleTap();
-                        if (!ignoringDoubleTap)
-                            onDoubleTapShiftKey(tracker);
-                        return true;
-                    }
-                    // Otherwise these events should not be handled as double tap.
-                    mProcessingShiftDoubleTapEvent = false;
-                }
-                return mProcessingShiftDoubleTapEvent;
-            }
-        };
 
         final boolean ignoreMultitouch = true;
-        mGestureDetector = new GestureDetector(getContext(), listener, null, ignoreMultitouch);
+        mGestureDetector = new GestureDetector(
+                getContext(), new DoubleTapListener(), null, ignoreMultitouch);
         mGestureDetector.setIsLongpressEnabled(false);
 
         mHasDistinctMultitouch = context.getPackageManager()
                 .hasSystemFeature(PackageManager.FEATURE_TOUCHSCREEN_MULTITOUCH_DISTINCT);
         mKeyRepeatInterval = res.getInteger(R.integer.config_key_repeat_interval);
+
+        mPointerQueue = mHasDistinctMultitouch ? new PointerTrackerQueue() : null;
     }
 
     public void startIgnoringDoubleTap() {
@@ -275,10 +249,10 @@
             mKeyTimerHandler.startIgnoringDoubleTap();
     }
 
-    public void setOnKeyboardActionListener(KeyboardActionListener listener) {
+    public void setKeyboardActionListener(KeyboardActionListener listener) {
         mKeyboardActionListener = listener;
         for (PointerTracker tracker : mPointerTrackers) {
-            tracker.setOnKeyboardActionListener(listener);
+            tracker.setKeyboardActionListener(listener);
         }
     }
 
@@ -286,10 +260,16 @@
      * Returns the {@link KeyboardActionListener} object.
      * @return the listener attached to this keyboard
      */
-    protected KeyboardActionListener getOnKeyboardActionListener() {
+    protected KeyboardActionListener getKeyboardActionListener() {
         return mKeyboardActionListener;
     }
 
+    @Override
+    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
+        // TODO: Should notify InputMethodService instead?
+        KeyboardSwitcher.getInstance().onSizeChanged();
+    }
+
     /**
      * Attaches a keyboard to this view. The keyboard can be switched at any time and the
      * view will re-layout itself to accommodate the keyboard.
@@ -305,10 +285,10 @@
         // Remove any pending messages, except dismissing preview
         mKeyTimerHandler.cancelKeyTimers();
         super.setKeyboard(keyboard);
-        mKeyDetector.setKeyboard(keyboard, -getPaddingLeft(),
-                -getPaddingTop() + mVerticalCorrection);
+        mKeyDetector.setKeyboard(
+                keyboard, -getPaddingLeft(), -getPaddingTop() + mVerticalCorrection);
         for (PointerTracker tracker : mPointerTrackers) {
-            tracker.setKeyboard(keyboard, mKeyDetector);
+            tracker.setKeyDetector(mKeyDetector);
         }
         mKeyDetector.setProximityThreshold(keyboard.getMostCommonKeyWidth());
         mPopupPanelCache.clear();
@@ -365,20 +345,20 @@
         boolean result = onLongPress(parentKey, tracker);
         if (result) {
             dismissAllKeyPreviews();
-            tracker.onLongPressed(mPointerQueue);
+            tracker.onLongPressed();
         }
         return result;
     }
 
     private void onLongPressShiftKey(PointerTracker tracker) {
-        tracker.onLongPressed(mPointerQueue);
+        tracker.onLongPressed();
         mKeyboardActionListener.onCodeInput(Keyboard.CODE_CAPSLOCK, null, 0, 0);
     }
 
     private void onDoubleTapShiftKey(@SuppressWarnings("unused") PointerTracker tracker) {
         // When shift key is double tapped, the first tap is correctly processed as usual tap. And
         // the second tap is treated as this double tap event, so that we need not mark tracker
-        // calling setAlreadyProcessed() nor remove the tracker from mPointerQueueueue.
+        // calling setAlreadyProcessed() nor remove the tracker from mPointerQueue.
         mKeyboardActionListener.onCodeInput(Keyboard.CODE_CAPSLOCK, null, 0, 0);
     }
 
@@ -394,7 +374,7 @@
 
         final PopupMiniKeyboardView miniKeyboardView =
                 (PopupMiniKeyboardView)container.findViewById(R.id.mini_keyboard_view);
-        miniKeyboardView.setOnKeyboardActionListener(new KeyboardActionListener() {
+        miniKeyboardView.setKeyboardActionListener(new KeyboardActionListener() {
             @Override
             public void onCodeInput(int primaryCode, int[] keyCodes, int x, int y) {
                 mKeyboardActionListener.onCodeInput(primaryCode, keyCodes, x, y);
@@ -414,10 +394,6 @@
             }
 
             @Override
-            public void onSwipeDown() {
-                // Nothing to do.
-            }
-            @Override
             public void onPress(int primaryCode, boolean withSliding) {
                 mKeyboardActionListener.onPress(primaryCode, withSliding);
             }
@@ -482,11 +458,11 @@
         for (int i = pointers.size(); i <= id; i++) {
             final PointerTracker tracker =
                 new PointerTracker(i, getContext(), mKeyTimerHandler, mKeyDetector, this,
-                        mHasDistinctMultitouch);
+                        mPointerQueue);
             if (keyboard != null)
-                tracker.setKeyboard(keyboard, mKeyDetector);
+                tracker.setKeyDetector(mKeyDetector);
             if (listener != null)
-                tracker.setOnKeyboardActionListener(listener);
+                tracker.setKeyboardActionListener(listener);
             pointers.add(tracker);
         }
 
@@ -520,9 +496,6 @@
             return true;
         }
 
-        // Track the last few movements to look for spurious swipes.
-        mSwipeTracker.addMovement(me);
-
         // Gesture detector must be enabled only when mini-keyboard is not on the screen.
         if (mPopupMiniKeyboardPanel == null && mGestureDetector != null
                 && mGestureDetector.onTouchEvent(me)) {
@@ -565,9 +538,9 @@
                 // previous key.
                 final int newKeyIndex = tracker.getKeyIndexOn(x, y);
                 if (mOldKeyIndex != newKeyIndex) {
-                    tracker.onDownEvent(x, y, eventTime, null);
+                    tracker.onDownEvent(x, y, eventTime);
                     if (action == MotionEvent.ACTION_UP)
-                        tracker.onUpEvent(x, y, eventTime, null);
+                        tracker.onUpEvent(x, y, eventTime);
                 }
             } else if (pointerCount == 2 && oldPointerCount == 1) {
                 // Single-touch to multi-touch transition.
@@ -575,9 +548,9 @@
                 final int lastX = tracker.getLastX();
                 final int lastY = tracker.getLastY();
                 mOldKeyIndex = tracker.getKeyIndexOn(lastX, lastY);
-                tracker.onUpEvent(lastX, lastY, eventTime, null);
+                tracker.onUpEvent(lastX, lastY, eventTime);
             } else if (pointerCount == 1 && oldPointerCount == 1) {
-                tracker.onTouchEvent(action, x, y, eventTime, null);
+                tracker.onTouchEvent(action, x, y, eventTime);
             } else {
                 Log.w(TAG, "Unknown touch panel behavior: pointer count is " + pointerCount
                         + " (old " + oldPointerCount + ")");
@@ -585,25 +558,24 @@
             return true;
         }
 
-        final PointerTrackerQueue queue = mPointerQueue;
         if (action == MotionEvent.ACTION_MOVE) {
             for (int i = 0; i < pointerCount; i++) {
                 final PointerTracker tracker = getPointerTracker(me.getPointerId(i));
-                tracker.onMoveEvent((int)me.getX(i), (int)me.getY(i), eventTime, queue);
+                tracker.onMoveEvent((int)me.getX(i), (int)me.getY(i), eventTime);
             }
         } else {
             final PointerTracker tracker = getPointerTracker(id);
             switch (action) {
             case MotionEvent.ACTION_DOWN:
             case MotionEvent.ACTION_POINTER_DOWN:
-                tracker.onDownEvent(x, y, eventTime, queue);
+                tracker.onDownEvent(x, y, eventTime);
                 break;
             case MotionEvent.ACTION_UP:
             case MotionEvent.ACTION_POINTER_UP:
-                tracker.onUpEvent(x, y, eventTime, queue);
+                tracker.onUpEvent(x, y, eventTime);
                 break;
             case MotionEvent.ACTION_CANCEL:
-                tracker.onCancelEvent(x, y, eventTime, queue);
+                tracker.onCancelEvent(x, y, eventTime);
                 break;
             }
         }
@@ -611,10 +583,6 @@
         return true;
     }
 
-    protected void onSwipeDown() {
-        mKeyboardActionListener.onSwipeDown();
-    }
-
     @Override
     public void closing() {
         super.closing();
diff --git a/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java b/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java
index 510bc16..39d607d 100644
--- a/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java
@@ -106,7 +106,7 @@
     }
 
     private boolean invokeOnKey(int primaryCode) {
-        getOnKeyboardActionListener().onCodeInput(primaryCode, null,
+        getKeyboardActionListener().onCodeInput(primaryCode, null,
                 KeyboardActionListener.NOT_A_TOUCH_COORDINATE,
                 KeyboardActionListener.NOT_A_TOUCH_COORDINATE);
         return true;
diff --git a/java/src/com/android/inputmethod/keyboard/MiniKeyboardKeyDetector.java b/java/src/com/android/inputmethod/keyboard/MiniKeyboardKeyDetector.java
index 69005db..1ec0dda 100644
--- a/java/src/com/android/inputmethod/keyboard/MiniKeyboardKeyDetector.java
+++ b/java/src/com/android/inputmethod/keyboard/MiniKeyboardKeyDetector.java
@@ -37,7 +37,7 @@
 
     @Override
     public int getKeyIndexAndNearbyCodes(int x, int y, final int[] allCodes) {
-        final List<Key> keys = getKeys();
+        final List<Key> keys = getKeyboard().getKeys();
         final int touchX = getTouchX(x);
         final int touchY = getTouchY(y);
 
diff --git a/java/src/com/android/inputmethod/keyboard/PointerTracker.java b/java/src/com/android/inputmethod/keyboard/PointerTracker.java
index 4ceabff..19cedc4 100644
--- a/java/src/com/android/inputmethod/keyboard/PointerTracker.java
+++ b/java/src/com/android/inputmethod/keyboard/PointerTracker.java
@@ -34,7 +34,6 @@
 
 public class PointerTracker {
     private static final String TAG = PointerTracker.class.getSimpleName();
-    private static final boolean ENABLE_ASSERTION = false;
     private static final boolean DEBUG_EVENT = false;
     private static final boolean DEBUG_MOVE_EVENT = false;
     private static final boolean DEBUG_LISTENER = false;
@@ -56,10 +55,10 @@
 
     private final DrawingProxy mDrawingProxy;
     private final KeyTimerHandler mKeyTimerHandler;
+    private final PointerTrackerQueue mPointerTrackerQueue;
     private KeyDetector mKeyDetector;
     private KeyboardActionListener mListener = EMPTY_LISTENER;
     private final KeyboardSwitcher mKeyboardSwitcher;
-    private final boolean mHasDistinctMultitouch;
     private final boolean mConfigSlidingKeyInputEnabled;
 
     private final int mTouchNoiseThresholdMillis;
@@ -107,21 +106,19 @@
         public void onTextInput(CharSequence text) {}
         @Override
         public void onCancelInput() {}
-        @Override
-        public void onSwipeDown() {}
     };
 
     public PointerTracker(int id, Context context, KeyTimerHandler keyTimerHandler,
-            KeyDetector keyDetector, DrawingProxy drawingProxy, boolean hasDistinctMultitouch) {
+            KeyDetector keyDetector, DrawingProxy drawingProxy, PointerTrackerQueue queue) {
         if (drawingProxy == null || keyTimerHandler == null || keyDetector == null)
             throw new NullPointerException();
         mPointerId = id;
         mDrawingProxy = drawingProxy;
         mKeyTimerHandler = keyTimerHandler;
-        mKeyDetector = keyDetector;
-        mKeyboardSwitcher = KeyboardSwitcher.getInstance();
+        mPointerTrackerQueue = queue;  // This is null for non-distinct multi-touch device.
         mKeyState = new PointerTrackerKeyState(keyDetector);
-        mHasDistinctMultitouch = hasDistinctMultitouch;
+        setKeyDetectorInner(keyDetector);
+        mKeyboardSwitcher = KeyboardSwitcher.getInstance();
         final Resources res = context.getResources();
         mConfigSlidingKeyInputEnabled = res.getBoolean(R.bool.config_sliding_key_input_enabled);
         mDelayBeforeKeyRepeatStart = res.getInteger(R.integer.config_delay_before_key_repeat_start);
@@ -135,7 +132,7 @@
         mSubtypeSwitcher = SubtypeSwitcher.getInstance();
     }
 
-    public void setOnKeyboardActionListener(KeyboardActionListener listener) {
+    public void setKeyboardActionListener(KeyboardActionListener listener) {
         mListener = listener;
     }
 
@@ -196,15 +193,19 @@
         mListener.onCancelInput();
     }
 
-    public void setKeyboard(Keyboard keyboard, KeyDetector keyDetector) {
-        if (keyboard == null || keyDetector == null)
-            throw new NullPointerException();
-        mKeyboard = keyboard;
-        mKeys = keyboard.getKeys();
+    public void setKeyDetectorInner(KeyDetector keyDetector) {
         mKeyDetector = keyDetector;
+        mKeyboard = keyDetector.getKeyboard();
+        mKeys = mKeyboard.getKeys();
         mKeyState.setKeyDetector(keyDetector);
-        final int keyQuarterWidth = keyboard.getKeyWidth() / 4;
+        final int keyQuarterWidth = mKeyboard.getKeyWidth() / 4;
         mKeyQuarterWidthSquared = keyQuarterWidth * keyQuarterWidth;
+    }
+
+    public void setKeyDetector(KeyDetector keyDetector) {
+        if (keyDetector == null)
+            throw new NullPointerException();
+        setKeyDetectorInner(keyDetector);
         // Mark that keyboard layout has been changed.
         mKeyboardLayoutHasBeenChanged = true;
     }
@@ -273,36 +274,26 @@
         }
     }
 
-    private void checkAssertion(PointerTrackerQueue queue) {
-        if (mHasDistinctMultitouch && queue == null)
-            throw new RuntimeException(
-                    "PointerTrackerQueue must be passed on distinct multi touch device");
-        if (!mHasDistinctMultitouch && queue != null)
-            throw new RuntimeException(
-                    "PointerTrackerQueue must be null on non-distinct multi touch device");
-    }
-
-    public void onTouchEvent(int action, int x, int y, long eventTime, PointerTrackerQueue queue) {
+    public void onTouchEvent(int action, int x, int y, long eventTime) {
         switch (action) {
         case MotionEvent.ACTION_MOVE:
-            onMoveEvent(x, y, eventTime, queue);
+            onMoveEvent(x, y, eventTime);
             break;
         case MotionEvent.ACTION_DOWN:
         case MotionEvent.ACTION_POINTER_DOWN:
-            onDownEvent(x, y, eventTime, queue);
+            onDownEvent(x, y, eventTime);
             break;
         case MotionEvent.ACTION_UP:
         case MotionEvent.ACTION_POINTER_UP:
-            onUpEvent(x, y, eventTime, queue);
+            onUpEvent(x, y, eventTime);
             break;
         case MotionEvent.ACTION_CANCEL:
-            onCancelEvent(x, y, eventTime, queue);
+            onCancelEvent(x, y, eventTime);
             break;
         }
     }
 
-    public void onDownEvent(int x, int y, long eventTime, PointerTrackerQueue queue) {
-        if (ENABLE_ASSERTION) checkAssertion(queue);
+    public void onDownEvent(int x, int y, long eventTime) {
         if (DEBUG_EVENT)
             printTouchEvent("onDownEvent:", x, y, eventTime);
 
@@ -321,6 +312,7 @@
             }
         }
 
+        final PointerTrackerQueue queue = mPointerTrackerQueue;
         if (queue != null) {
             if (isOnModifierKey(x, y)) {
                 // Before processing a down event of modifier key, all pointers already being
@@ -364,8 +356,7 @@
         mIsInSlidingKeyInput = true;
     }
 
-    public void onMoveEvent(int x, int y, long eventTime, PointerTrackerQueue queue) {
-        if (ENABLE_ASSERTION) checkAssertion(queue);
+    public void onMoveEvent(int x, int y, long eventTime) {
         if (DEBUG_MOVE_EVENT)
             printTouchEvent("onMoveEvent:", x, y, eventTime);
         if (mKeyAlreadyProcessed)
@@ -449,6 +440,7 @@
                         keyboard.updateSpacebarPreviewIcon(diff);
                         // Display spacebar slide language switcher.
                         showKeyPreview(keyIndex);
+                        final PointerTrackerQueue queue = mPointerTrackerQueue;
                         if (queue != null)
                             queue.releaseAllPointersExcept(this, eventTime, true);
                     }
@@ -472,11 +464,11 @@
         }
     }
 
-    public void onUpEvent(int x, int y, long eventTime, PointerTrackerQueue queue) {
-        if (ENABLE_ASSERTION) checkAssertion(queue);
+    public void onUpEvent(int x, int y, long eventTime) {
         if (DEBUG_EVENT)
             printTouchEvent("onUpEvent  :", x, y, eventTime);
 
+        final PointerTrackerQueue queue = mPointerTrackerQueue;
         if (queue != null) {
             if (isModifier()) {
                 // Before processing an up event of modifier key, all pointers already being
@@ -540,8 +532,9 @@
         }
     }
 
-    public void onLongPressed(PointerTrackerQueue queue) {
+    public void onLongPressed() {
         mKeyAlreadyProcessed = true;
+        final PointerTrackerQueue queue = mPointerTrackerQueue;
         if (queue != null) {
             // TODO: Support chording + long-press input.
             queue.releaseAllPointersExcept(this, SystemClock.uptimeMillis(), true);
@@ -549,11 +542,11 @@
         }
     }
 
-    public void onCancelEvent(int x, int y, long eventTime, PointerTrackerQueue queue) {
-        if (ENABLE_ASSERTION) checkAssertion(queue);
+    public void onCancelEvent(int x, int y, long eventTime) {
         if (DEBUG_EVENT)
             printTouchEvent("onCancelEvt:", x, y, eventTime);
 
+        final PointerTrackerQueue queue = mPointerTrackerQueue;
         if (queue != null) {
             queue.releaseAllPointersExcept(this, eventTime, true);
             queue.remove(this);
diff --git a/java/src/com/android/inputmethod/keyboard/PopupMiniKeyboardView.java b/java/src/com/android/inputmethod/keyboard/PopupMiniKeyboardView.java
index 959427a..a3d9c04 100644
--- a/java/src/com/android/inputmethod/keyboard/PopupMiniKeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/PopupMiniKeyboardView.java
@@ -58,6 +58,11 @@
     }
 
     @Override
+    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
+        // Do nothing for the mini keyboard.
+    }
+
+    @Override
     public void setKeyPreviewPopupEnabled(boolean previewEnabled, int delay) {
         // Mini keyboard needs no pop-up key preview displayed, so we pass always false with a
         // delay of 0. The delay does not matter actually since the popup is not shown anyway.
diff --git a/java/src/com/android/inputmethod/keyboard/internal/PointerTrackerKeyState.java b/java/src/com/android/inputmethod/keyboard/internal/PointerTrackerKeyState.java
index 6e2b60c..5a12db2 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/PointerTrackerKeyState.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/PointerTrackerKeyState.java
@@ -39,8 +39,10 @@
     private int mLastX;
     private int mLastY;
 
-    public PointerTrackerKeyState(KeyDetector keyDetecor) {
-        mKeyDetector = keyDetecor;
+    public PointerTrackerKeyState(KeyDetector keyDetector) {
+        if (keyDetector == null)
+            throw new NullPointerException();
+        mKeyDetector = keyDetector;
     }
 
     public void setKeyDetector(KeyDetector keyDetector) {
diff --git a/java/src/com/android/inputmethod/keyboard/internal/SwipeTracker.java b/java/src/com/android/inputmethod/keyboard/internal/SwipeTracker.java
deleted file mode 100644
index 8d192c2..0000000
--- a/java/src/com/android/inputmethod/keyboard/internal/SwipeTracker.java
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-
-package com.android.inputmethod.keyboard.internal;
-
-import android.view.MotionEvent;
-
-public class SwipeTracker {
-    private static final int NUM_PAST = 4;
-    private static final int LONGEST_PAST_TIME = 200;
-
-    final EventRingBuffer mBuffer = new EventRingBuffer(NUM_PAST);
-
-    private float mYVelocity;
-    private float mXVelocity;
-
-    public void addMovement(MotionEvent ev) {
-        if (ev.getAction() == MotionEvent.ACTION_DOWN) {
-            mBuffer.clear();
-            return;
-        }
-        long time = ev.getEventTime();
-        final int count = ev.getHistorySize();
-        for (int i = 0; i < count; i++) {
-            addPoint(ev.getHistoricalX(i), ev.getHistoricalY(i), ev.getHistoricalEventTime(i));
-        }
-        addPoint(ev.getX(), ev.getY(), time);
-    }
-
-    private void addPoint(float x, float y, long time) {
-        final EventRingBuffer buffer = mBuffer;
-        while (buffer.size() > 0) {
-            long lastT = buffer.getTime(0);
-            if (lastT >= time - LONGEST_PAST_TIME)
-                break;
-            buffer.dropOldest();
-        }
-        buffer.add(x, y, time);
-    }
-
-    public void computeCurrentVelocity(int units) {
-        computeCurrentVelocity(units, Float.MAX_VALUE);
-    }
-
-    public void computeCurrentVelocity(int units, float maxVelocity) {
-        final EventRingBuffer buffer = mBuffer;
-        final float oldestX = buffer.getX(0);
-        final float oldestY = buffer.getY(0);
-        final long oldestTime = buffer.getTime(0);
-
-        float accumX = 0;
-        float accumY = 0;
-        final int count = buffer.size();
-        for (int pos = 1; pos < count; pos++) {
-            final int dur = (int)(buffer.getTime(pos) - oldestTime);
-            if (dur == 0) continue;
-            float dist = buffer.getX(pos) - oldestX;
-            float vel = (dist / dur) * units;   // pixels/frame.
-            if (accumX == 0) accumX = vel;
-            else accumX = (accumX + vel) * .5f;
-
-            dist = buffer.getY(pos) - oldestY;
-            vel = (dist / dur) * units;   // pixels/frame.
-            if (accumY == 0) accumY = vel;
-            else accumY = (accumY + vel) * .5f;
-        }
-        mXVelocity = accumX < 0.0f ? Math.max(accumX, -maxVelocity)
-                : Math.min(accumX, maxVelocity);
-        mYVelocity = accumY < 0.0f ? Math.max(accumY, -maxVelocity)
-                : Math.min(accumY, maxVelocity);
-    }
-
-    public float getXVelocity() {
-        return mXVelocity;
-    }
-
-    public float getYVelocity() {
-        return mYVelocity;
-    }
-
-    public static class EventRingBuffer {
-        private final int bufSize;
-        private final float xBuf[];
-        private final float yBuf[];
-        private final long timeBuf[];
-        private int top;  // points new event
-        private int end;  // points oldest event
-        private int count; // the number of valid data
-
-        public EventRingBuffer(int max) {
-            this.bufSize = max;
-            xBuf = new float[max];
-            yBuf = new float[max];
-            timeBuf = new long[max];
-            clear();
-        }
-
-        public void clear() {
-            top = end = count = 0;
-        }
-
-        public int size() {
-            return count;
-        }
-
-        // Position 0 points oldest event
-        private int index(int pos) {
-            return (end + pos) % bufSize;
-        }
-
-        private int advance(int index) {
-            return (index + 1) % bufSize;
-        }
-
-        public void add(float x, float y, long time) {
-            xBuf[top] = x;
-            yBuf[top] = y;
-            timeBuf[top] = time;
-            top = advance(top);
-            if (count < bufSize) {
-                count++;
-            } else {
-                end = advance(end);
-            }
-        }
-
-        public float getX(int pos) {
-            return xBuf[index(pos)];
-        }
-
-        public float getY(int pos) {
-            return yBuf[index(pos)];
-        }
-
-        public long getTime(int pos) {
-            return timeBuf[index(pos)];
-        }
-
-        public void dropOldest() {
-            count--;
-            end = advance(end);
-        }
-    }
-}
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index 12dad53..30eb83c 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -1892,12 +1892,6 @@
         // subtype changes.
         if (!CAN_HANDLE_ON_CURRENT_INPUT_METHOD_SUBTYPE_CHANGED)
             onRefreshKeyboard();
-     }
-
-    @Override
-    public void onSwipeDown() {
-        if (mSettingsValues.mSwipeDownDismissKeyboardEnabled)
-            handleClose();
     }
 
     @Override
diff --git a/java/src/com/android/inputmethod/latin/Settings.java b/java/src/com/android/inputmethod/latin/Settings.java
index d6b9890..aba72d3 100644
--- a/java/src/com/android/inputmethod/latin/Settings.java
+++ b/java/src/com/android/inputmethod/latin/Settings.java
@@ -90,7 +90,6 @@
 
     public static class Values {
         // From resources:
-        public final boolean mSwipeDownDismissKeyboardEnabled;
         public final int mDelayBeforeFadeoutLanguageOnSpacebar;
         public final int mDelayUpdateSuggestions;
         public final int mDelayUpdateOldSuggestions;
@@ -131,8 +130,6 @@
             }
 
             // Get the resources
-            mSwipeDownDismissKeyboardEnabled = res.getBoolean(
-                    R.bool.config_swipe_down_dismiss_keyboard_enabled);
             mDelayBeforeFadeoutLanguageOnSpacebar = res.getInteger(
                     R.integer.config_delay_before_fadeout_language_on_spacebar);
             mDelayUpdateSuggestions =
@@ -539,6 +536,7 @@
                 [mVoicePreference.findIndexOfValue(mVoicePreference.getValue())]);
     }
 
+    @Override
     protected Dialog onCreateDialog(int id) {
         switch (id) {
             case VOICE_INPUT_CONFIRM_DIALOG:
diff --git a/tests/src/com/android/inputmethod/latin/EventRingBufferTests.java b/tests/src/com/android/inputmethod/latin/EventRingBufferTests.java
deleted file mode 100644
index a3d2a2b..0000000
--- a/tests/src/com/android/inputmethod/latin/EventRingBufferTests.java
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * Copyright (C) 2010 Google Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-
-package com.android.inputmethod.latin;
-
-import com.android.inputmethod.keyboard.internal.SwipeTracker.EventRingBuffer;
-
-import android.test.AndroidTestCase;
-
-public class EventRingBufferTests extends AndroidTestCase {
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        super.tearDown();
-    }
-
-    private static float X_BASE = 1000f;
-
-    private static float Y_BASE = 2000f;
-
-    private static long TIME_BASE = 3000l;
-
-    private static float x(int id) {
-        return X_BASE + id;
-    }
-
-    private static float y(int id) {
-        return Y_BASE + id;
-    }
-
-    private static long time(int id) {
-        return TIME_BASE + id;
-    }
-
-    private static void addEvent(EventRingBuffer buf, int id) {
-        buf.add(x(id), y(id), time(id));
-    }
-
-    private static void assertEventSize(EventRingBuffer buf, int size) {
-        assertEquals(size, buf.size());
-    }
-
-    private static void assertEvent(EventRingBuffer buf, int pos, int id) {
-        assertEquals(x(id), buf.getX(pos), 0f);
-        assertEquals(y(id), buf.getY(pos), 0f);
-        assertEquals(time(id), buf.getTime(pos));
-    }
-
-    public void testClearBuffer() {
-        EventRingBuffer buf = new EventRingBuffer(4);
-        assertEventSize(buf, 0);
-
-        addEvent(buf, 0);
-        addEvent(buf, 1);
-        addEvent(buf, 2);
-        addEvent(buf, 3);
-        addEvent(buf, 4);
-        assertEventSize(buf, 4);
-
-        buf.clear();
-        assertEventSize(buf, 0);
-    }
-
-    public void testRingBuffer() {
-        EventRingBuffer buf = new EventRingBuffer(4);
-        assertEventSize(buf, 0); // [0]
-
-        addEvent(buf, 0);
-        assertEventSize(buf, 1); // [1] 0
-        assertEvent(buf, 0, 0);
-
-        addEvent(buf, 1);
-        addEvent(buf, 2);
-        assertEventSize(buf, 3); // [3] 2 1 0
-        assertEvent(buf, 0, 0);
-        assertEvent(buf, 1, 1);
-        assertEvent(buf, 2, 2);
-
-        addEvent(buf, 3);
-        assertEventSize(buf, 4); // [4] 3 2 1 0
-        assertEvent(buf, 0, 0);
-        assertEvent(buf, 1, 1);
-        assertEvent(buf, 2, 2);
-        assertEvent(buf, 3, 3);
-
-        addEvent(buf, 4);
-        addEvent(buf, 5);
-        assertEventSize(buf, 4); // [4] 5 4|3 2(1 0)
-        assertEvent(buf, 0, 2);
-        assertEvent(buf, 1, 3);
-        assertEvent(buf, 2, 4);
-        assertEvent(buf, 3, 5);
-
-        addEvent(buf, 6);
-        addEvent(buf, 7);
-        addEvent(buf, 8);
-        assertEventSize(buf, 4); // [4] 8 7 6 5|(4 3 2)1|0
-        assertEvent(buf, 0, 5);
-        assertEvent(buf, 1, 6);
-        assertEvent(buf, 2, 7);
-        assertEvent(buf, 3, 8);
-    }
-
-    public void testDropOldest() {
-        EventRingBuffer buf = new EventRingBuffer(4);
-
-        addEvent(buf, 0);
-        assertEventSize(buf, 1); // [1] 0
-        assertEvent(buf, 0, 0);
-
-        buf.dropOldest();
-        assertEventSize(buf, 0); // [0] (0)
-
-        addEvent(buf, 1);
-        addEvent(buf, 2);
-        addEvent(buf, 3);
-        addEvent(buf, 4);
-        assertEventSize(buf, 4); // [4] 4|3 2 1(0)
-        assertEvent(buf, 0, 1);
-
-        buf.dropOldest();
-        assertEventSize(buf, 3); // [3] 4|3 2(1)0
-        assertEvent(buf, 0, 2);
-
-        buf.dropOldest();
-        assertEventSize(buf, 2); // [2] 4|3(2)10
-        assertEvent(buf, 0, 3);
-
-        buf.dropOldest();
-        assertEventSize(buf, 1); // [1] 4|(3)210
-        assertEvent(buf, 0, 4);
-
-        buf.dropOldest();
-        assertEventSize(buf, 0); // [0] (4)|3210
-    }
-}