Merge "Add parameter descriptions"
diff --git a/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java b/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java
index 0fe2455..f7c54c7 100644
--- a/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java
@@ -31,8 +31,6 @@
 import android.graphics.Paint.Align;
 import android.graphics.Typeface;
 import android.graphics.drawable.Drawable;
-import android.os.Message;
-import android.os.SystemClock;
 import android.preference.PreferenceManager;
 import android.util.AttributeSet;
 import android.util.DisplayMetrics;
@@ -41,7 +39,6 @@
 import android.view.LayoutInflater;
 import android.view.MotionEvent;
 import android.view.View;
-import android.view.ViewConfiguration;
 import android.view.ViewGroup;
 import android.view.animation.AccelerateInterpolator;
 import android.view.animation.DecelerateInterpolator;
@@ -57,6 +54,8 @@
 import com.android.inputmethod.keyboard.internal.GestureTrailsPreview;
 import com.android.inputmethod.keyboard.internal.KeyDrawParams;
 import com.android.inputmethod.keyboard.internal.KeyPreviewDrawParams;
+import com.android.inputmethod.keyboard.internal.MainKeyboardViewDrawingHandler;
+import com.android.inputmethod.keyboard.internal.MainKeyboardViewTimerHandler;
 import com.android.inputmethod.keyboard.internal.NonDistinctMultitouchHelper;
 import com.android.inputmethod.keyboard.internal.PreviewPlacerView;
 import com.android.inputmethod.keyboard.internal.SlidingKeyInputPreview;
@@ -68,7 +67,6 @@
 import com.android.inputmethod.latin.settings.DebugSettings;
 import com.android.inputmethod.latin.utils.CollectionUtils;
 import com.android.inputmethod.latin.utils.CoordinateUtils;
-import com.android.inputmethod.latin.utils.StaticInnerHandlerWrapper;
 import com.android.inputmethod.latin.utils.SubtypeLocaleUtils;
 import com.android.inputmethod.latin.utils.TypefaceUtils;
 import com.android.inputmethod.latin.utils.UsabilityStudyLogUtils;
@@ -150,8 +148,8 @@
     private static final int SPACE_LED_LENGTH_PERCENT = 80;
 
     // Stuff to draw altCodeWhileTyping keys.
-    private ObjectAnimator mAltCodeKeyWhileTypingFadeoutAnimator;
-    private ObjectAnimator mAltCodeKeyWhileTypingFadeinAnimator;
+    private final ObjectAnimator mAltCodeKeyWhileTypingFadeoutAnimator;
+    private final ObjectAnimator mAltCodeKeyWhileTypingFadeinAnimator;
     private int mAltCodeKeyWhileTypingAnimAlpha = Constants.Color.ALPHA_OPAQUE;
 
     // Preview placer view
@@ -201,235 +199,11 @@
     private KeyDetector mKeyDetector;
     private final NonDistinctMultitouchHelper mNonDistinctMultitouchHelper;
 
-    private final KeyTimerHandler mKeyTimerHandler;
+    private final MainKeyboardViewTimerHandler mKeyTimerHandler;
     private final int mLanguageOnSpacebarHorizontalMargin;
 
-    private static final class KeyTimerHandler extends StaticInnerHandlerWrapper<MainKeyboardView>
-            implements TimerProxy {
-        private static final int MSG_TYPING_STATE_EXPIRED = 0;
-        private static final int MSG_REPEAT_KEY = 1;
-        private static final int MSG_LONGPRESS_KEY = 2;
-        private static final int MSG_DOUBLE_TAP_SHIFT_KEY = 3;
-        private static final int MSG_UPDATE_BATCH_INPUT = 4;
-
-        private final int mIgnoreAltCodeKeyTimeout;
-        private final int mGestureRecognitionUpdateTime;
-
-        public KeyTimerHandler(final MainKeyboardView outerInstance,
-                final TypedArray mainKeyboardViewAttr) {
-            super(outerInstance);
-
-            mIgnoreAltCodeKeyTimeout = mainKeyboardViewAttr.getInt(
-                    R.styleable.MainKeyboardView_ignoreAltCodeKeyTimeout, 0);
-            mGestureRecognitionUpdateTime = mainKeyboardViewAttr.getInt(
-                    R.styleable.MainKeyboardView_gestureRecognitionUpdateTime, 0);
-        }
-
-        @Override
-        public void handleMessage(final Message msg) {
-            final MainKeyboardView keyboardView = getOuterInstance();
-            if (keyboardView == null) {
-                return;
-            }
-            final PointerTracker tracker = (PointerTracker) msg.obj;
-            switch (msg.what) {
-            case MSG_TYPING_STATE_EXPIRED:
-                startWhileTypingFadeinAnimation(keyboardView);
-                break;
-            case MSG_REPEAT_KEY:
-                tracker.onKeyRepeat(msg.arg1 /* code */, msg.arg2 /* repeatCount */);
-                break;
-            case MSG_LONGPRESS_KEY:
-                keyboardView.onLongPress(tracker);
-                break;
-            case MSG_UPDATE_BATCH_INPUT:
-                tracker.updateBatchInputByTimer(SystemClock.uptimeMillis());
-                startUpdateBatchInputTimer(tracker);
-                break;
-            }
-        }
-
-        @Override
-        public void startKeyRepeatTimer(final PointerTracker tracker, final int repeatCount,
-                final int delay) {
-            final Key key = tracker.getKey();
-            if (key == null || delay == 0) {
-                return;
-            }
-            sendMessageDelayed(
-                    obtainMessage(MSG_REPEAT_KEY, key.getCode(), repeatCount, tracker), delay);
-        }
-
-        public void cancelKeyRepeatTimer() {
-            removeMessages(MSG_REPEAT_KEY);
-        }
-
-        // TODO: Suppress layout changes in key repeat mode
-        public boolean isInKeyRepeat() {
-            return hasMessages(MSG_REPEAT_KEY);
-        }
-
-        @Override
-        public void startLongPressTimer(final PointerTracker tracker, final int delay) {
-            cancelLongPressTimer();
-            if (delay <= 0) return;
-            sendMessageDelayed(obtainMessage(MSG_LONGPRESS_KEY, tracker), delay);
-        }
-
-        @Override
-        public void cancelLongPressTimer() {
-            removeMessages(MSG_LONGPRESS_KEY);
-        }
-
-        private static void cancelAndStartAnimators(final ObjectAnimator animatorToCancel,
-                final ObjectAnimator animatorToStart) {
-            if (animatorToCancel == null || animatorToStart == null) {
-                // TODO: Stop using null as a no-operation animator.
-                return;
-            }
-            float startFraction = 0.0f;
-            if (animatorToCancel.isStarted()) {
-                animatorToCancel.cancel();
-                startFraction = 1.0f - animatorToCancel.getAnimatedFraction();
-            }
-            final long startTime = (long)(animatorToStart.getDuration() * startFraction);
-            animatorToStart.start();
-            animatorToStart.setCurrentPlayTime(startTime);
-        }
-
-        private static void startWhileTypingFadeinAnimation(final MainKeyboardView keyboardView) {
-            cancelAndStartAnimators(keyboardView.mAltCodeKeyWhileTypingFadeoutAnimator,
-                    keyboardView.mAltCodeKeyWhileTypingFadeinAnimator);
-        }
-
-        private static void startWhileTypingFadeoutAnimation(final MainKeyboardView keyboardView) {
-            cancelAndStartAnimators(keyboardView.mAltCodeKeyWhileTypingFadeinAnimator,
-                    keyboardView.mAltCodeKeyWhileTypingFadeoutAnimator);
-        }
-
-        @Override
-        public void startTypingStateTimer(final Key typedKey) {
-            if (typedKey.isModifier() || typedKey.altCodeWhileTyping()) {
-                return;
-            }
-
-            final boolean isTyping = isTypingState();
-            removeMessages(MSG_TYPING_STATE_EXPIRED);
-            final MainKeyboardView keyboardView = getOuterInstance();
-
-            // When user hits the space or the enter key, just cancel the while-typing timer.
-            final int typedCode = typedKey.getCode();
-            if (typedCode == Constants.CODE_SPACE || typedCode == Constants.CODE_ENTER) {
-                if (isTyping) {
-                    startWhileTypingFadeinAnimation(keyboardView);
-                }
-                return;
-            }
-
-            sendMessageDelayed(
-                    obtainMessage(MSG_TYPING_STATE_EXPIRED), mIgnoreAltCodeKeyTimeout);
-            if (isTyping) {
-                return;
-            }
-            startWhileTypingFadeoutAnimation(keyboardView);
-        }
-
-        @Override
-        public boolean isTypingState() {
-            return hasMessages(MSG_TYPING_STATE_EXPIRED);
-        }
-
-        @Override
-        public void startDoubleTapShiftKeyTimer() {
-            sendMessageDelayed(obtainMessage(MSG_DOUBLE_TAP_SHIFT_KEY),
-                    ViewConfiguration.getDoubleTapTimeout());
-        }
-
-        @Override
-        public void cancelDoubleTapShiftKeyTimer() {
-            removeMessages(MSG_DOUBLE_TAP_SHIFT_KEY);
-        }
-
-        @Override
-        public boolean isInDoubleTapShiftKeyTimeout() {
-            return hasMessages(MSG_DOUBLE_TAP_SHIFT_KEY);
-        }
-
-        @Override
-        public void cancelKeyTimers() {
-            cancelKeyRepeatTimer();
-            cancelLongPressTimer();
-        }
-
-        @Override
-        public void startUpdateBatchInputTimer(final PointerTracker tracker) {
-            if (mGestureRecognitionUpdateTime <= 0) {
-                return;
-            }
-            removeMessages(MSG_UPDATE_BATCH_INPUT, tracker);
-            sendMessageDelayed(obtainMessage(MSG_UPDATE_BATCH_INPUT, tracker),
-                    mGestureRecognitionUpdateTime);
-        }
-
-        @Override
-        public void cancelUpdateBatchInputTimer(final PointerTracker tracker) {
-            removeMessages(MSG_UPDATE_BATCH_INPUT, tracker);
-        }
-
-        @Override
-        public void cancelAllUpdateBatchInputTimers() {
-            removeMessages(MSG_UPDATE_BATCH_INPUT);
-        }
-
-        public void cancelAllMessages() {
-            cancelKeyTimers();
-            cancelAllUpdateBatchInputTimers();
-        }
-    }
-
-    private final DrawingHandler mDrawingHandler = new DrawingHandler(this);
-
-    public static class DrawingHandler extends StaticInnerHandlerWrapper<MainKeyboardView> {
-        private static final int MSG_DISMISS_KEY_PREVIEW = 0;
-        private static final int MSG_DISMISS_GESTURE_FLOATING_PREVIEW_TEXT = 1;
-
-        public DrawingHandler(final MainKeyboardView outerInstance) {
-            super(outerInstance);
-        }
-
-        @Override
-        public void handleMessage(final Message msg) {
-            final MainKeyboardView mainKeyboardView = getOuterInstance();
-            if (mainKeyboardView == null) return;
-            switch (msg.what) {
-            case MSG_DISMISS_KEY_PREVIEW:
-                mainKeyboardView.dismissKeyPreviewWithoutDelay((Key)msg.obj);
-                break;
-            case MSG_DISMISS_GESTURE_FLOATING_PREVIEW_TEXT:
-                mainKeyboardView.showGestureFloatingPreviewText(SuggestedWords.EMPTY);
-                break;
-            }
-        }
-
-        public void dismissKeyPreview(final long delay, final Key key) {
-            sendMessageDelayed(obtainMessage(MSG_DISMISS_KEY_PREVIEW, key), delay);
-        }
-
-        private void cancelAllDismissKeyPreviews() {
-            removeMessages(MSG_DISMISS_KEY_PREVIEW);
-            final MainKeyboardView mainKeyboardView = getOuterInstance();
-            if (mainKeyboardView == null) return;
-            mainKeyboardView.dismissAllKeyPreviews();
-        }
-
-        public void dismissGestureFloatingPreviewText(final long delay) {
-            sendMessageDelayed(obtainMessage(MSG_DISMISS_GESTURE_FLOATING_PREVIEW_TEXT), delay);
-        }
-
-        public void cancelAllMessages() {
-            cancelAllDismissKeyPreviews();
-        }
-    }
+    private final MainKeyboardViewDrawingHandler mDrawingHandler =
+            new MainKeyboardViewDrawingHandler(this);
 
     public MainKeyboardView(final Context context, final AttributeSet attrs) {
         this(context, attrs, R.attr.mainKeyboardViewStyle);
@@ -482,7 +256,7 @@
                 R.styleable.MainKeyboardView_keyHysteresisDistanceForSlidingModifier, 0.0f);
         mKeyDetector = new KeyDetector(
                 keyHysteresisDistance, keyHysteresisDistanceForSlidingModifier);
-        mKeyTimerHandler = new KeyTimerHandler(this, mainKeyboardViewAttr);
+        mKeyTimerHandler = new MainKeyboardViewTimerHandler(this, mainKeyboardViewAttr);
         mKeyPreviewOffset = mainKeyboardViewAttr.getDimensionPixelOffset(
                 R.styleable.MainKeyboardView_keyPreviewOffset, 0);
         mKeyPreviewHeight = mainKeyboardViewAttr.getDimensionPixelSize(
@@ -554,6 +328,32 @@
         return animator;
     }
 
+    private static void cancelAndStartAnimators(final ObjectAnimator animatorToCancel,
+            final ObjectAnimator animatorToStart) {
+        if (animatorToCancel == null || animatorToStart == null) {
+            // TODO: Stop using null as a no-operation animator.
+            return;
+        }
+        float startFraction = 0.0f;
+        if (animatorToCancel.isStarted()) {
+            animatorToCancel.cancel();
+            startFraction = 1.0f - animatorToCancel.getAnimatedFraction();
+        }
+        final long startTime = (long)(animatorToStart.getDuration() * startFraction);
+        animatorToStart.start();
+        animatorToStart.setCurrentPlayTime(startTime);
+    }
+
+    public void startWhileTypingFadeinAnimation() {
+        cancelAndStartAnimators(
+                mAltCodeKeyWhileTypingFadeoutAnimator, mAltCodeKeyWhileTypingFadeinAnimator);
+    }
+
+    public void startWhileTypingFadeoutAnimation() {
+        cancelAndStartAnimators(
+                mAltCodeKeyWhileTypingFadeinAnimator, mAltCodeKeyWhileTypingFadeoutAnimator);
+    }
+
     @ExternallyReferenced
     public int getLanguageOnSpacebarAnimAlpha() {
         return mLanguageOnSpacebarAnimAlpha;
@@ -721,7 +521,7 @@
         return previewTextView;
     }
 
-    private void dismissAllKeyPreviews() {
+    public void dismissAllKeyPreviews() {
         for (final Key key : new HashSet<Key>(mShowingKeyPreviewTextViews.keySet())) {
             dismissKeyPreviewWithoutDelay(key);
         }
@@ -915,7 +715,7 @@
     }
 
     // TODO: Take this method out of this class.
-    private void dismissKeyPreviewWithoutDelay(final Key key) {
+    public void dismissKeyPreviewWithoutDelay(final Key key) {
         if (key == null) {
             return;
         }
@@ -1052,7 +852,7 @@
      * Called when a key is long pressed.
      * @param tracker the pointer tracker which pressed the parent key
      */
-    private void onLongPress(final PointerTracker tracker) {
+    public void onLongPress(final PointerTracker tracker) {
         if (isShowingMoreKeysPanel()) {
             return;
         }
diff --git a/java/src/com/android/inputmethod/keyboard/internal/MainKeyboardViewDrawingHandler.java b/java/src/com/android/inputmethod/keyboard/internal/MainKeyboardViewDrawingHandler.java
new file mode 100644
index 0000000..5384553
--- /dev/null
+++ b/java/src/com/android/inputmethod/keyboard/internal/MainKeyboardViewDrawingHandler.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2013 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.os.Message;
+
+import com.android.inputmethod.keyboard.Key;
+import com.android.inputmethod.keyboard.MainKeyboardView;
+import com.android.inputmethod.latin.SuggestedWords;
+import com.android.inputmethod.latin.utils.StaticInnerHandlerWrapper;
+
+public class MainKeyboardViewDrawingHandler extends StaticInnerHandlerWrapper<MainKeyboardView> {
+    private static final int MSG_DISMISS_KEY_PREVIEW = 0;
+    private static final int MSG_DISMISS_GESTURE_FLOATING_PREVIEW_TEXT = 1;
+
+    public MainKeyboardViewDrawingHandler(final MainKeyboardView outerInstance) {
+        super(outerInstance);
+    }
+
+    @Override
+    public void handleMessage(final Message msg) {
+        final MainKeyboardView mainKeyboardView = getOuterInstance();
+        if (mainKeyboardView == null) return;
+        switch (msg.what) {
+        case MSG_DISMISS_KEY_PREVIEW:
+            mainKeyboardView.dismissKeyPreviewWithoutDelay((Key)msg.obj);
+            break;
+        case MSG_DISMISS_GESTURE_FLOATING_PREVIEW_TEXT:
+            mainKeyboardView.showGestureFloatingPreviewText(SuggestedWords.EMPTY);
+            break;
+        }
+    }
+
+    public void dismissKeyPreview(final long delay, final Key key) {
+        sendMessageDelayed(obtainMessage(MSG_DISMISS_KEY_PREVIEW, key), delay);
+    }
+
+    private void cancelAllDismissKeyPreviews() {
+        removeMessages(MSG_DISMISS_KEY_PREVIEW);
+        final MainKeyboardView mainKeyboardView = getOuterInstance();
+        if (mainKeyboardView == null) return;
+        mainKeyboardView.dismissAllKeyPreviews();
+    }
+
+    public void dismissGestureFloatingPreviewText(final long delay) {
+        sendMessageDelayed(obtainMessage(MSG_DISMISS_GESTURE_FLOATING_PREVIEW_TEXT), delay);
+    }
+
+    public void cancelAllMessages() {
+        cancelAllDismissKeyPreviews();
+    }
+}
diff --git a/java/src/com/android/inputmethod/keyboard/internal/MainKeyboardViewTimerHandler.java b/java/src/com/android/inputmethod/keyboard/internal/MainKeyboardViewTimerHandler.java
new file mode 100644
index 0000000..3ffb2b6
--- /dev/null
+++ b/java/src/com/android/inputmethod/keyboard/internal/MainKeyboardViewTimerHandler.java
@@ -0,0 +1,187 @@
+/*
+ * Copyright (C) 2013 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.content.res.TypedArray;
+import android.os.Message;
+import android.os.SystemClock;
+import android.view.ViewConfiguration;
+
+import com.android.inputmethod.keyboard.Key;
+import com.android.inputmethod.keyboard.MainKeyboardView;
+import com.android.inputmethod.keyboard.PointerTracker;
+import com.android.inputmethod.keyboard.PointerTracker.TimerProxy;
+import com.android.inputmethod.latin.Constants;
+import com.android.inputmethod.latin.R;
+import com.android.inputmethod.latin.utils.StaticInnerHandlerWrapper;
+
+public final class MainKeyboardViewTimerHandler extends StaticInnerHandlerWrapper<MainKeyboardView>
+        implements TimerProxy {
+    private static final int MSG_TYPING_STATE_EXPIRED = 0;
+    private static final int MSG_REPEAT_KEY = 1;
+    private static final int MSG_LONGPRESS_KEY = 2;
+    private static final int MSG_DOUBLE_TAP_SHIFT_KEY = 3;
+    private static final int MSG_UPDATE_BATCH_INPUT = 4;
+
+    private final int mIgnoreAltCodeKeyTimeout;
+    private final int mGestureRecognitionUpdateTime;
+
+    public MainKeyboardViewTimerHandler(final MainKeyboardView outerInstance,
+            final TypedArray mainKeyboardViewAttr) {
+        super(outerInstance);
+
+        mIgnoreAltCodeKeyTimeout = mainKeyboardViewAttr.getInt(
+                R.styleable.MainKeyboardView_ignoreAltCodeKeyTimeout, 0);
+        mGestureRecognitionUpdateTime = mainKeyboardViewAttr.getInt(
+                R.styleable.MainKeyboardView_gestureRecognitionUpdateTime, 0);
+    }
+
+    @Override
+    public void handleMessage(final Message msg) {
+        final MainKeyboardView keyboardView = getOuterInstance();
+        if (keyboardView == null) {
+            return;
+        }
+        final PointerTracker tracker = (PointerTracker) msg.obj;
+        switch (msg.what) {
+        case MSG_TYPING_STATE_EXPIRED:
+            keyboardView.startWhileTypingFadeinAnimation();
+            break;
+        case MSG_REPEAT_KEY:
+            tracker.onKeyRepeat(msg.arg1 /* code */, msg.arg2 /* repeatCount */);
+            break;
+        case MSG_LONGPRESS_KEY:
+            keyboardView.onLongPress(tracker);
+            break;
+        case MSG_UPDATE_BATCH_INPUT:
+            tracker.updateBatchInputByTimer(SystemClock.uptimeMillis());
+            startUpdateBatchInputTimer(tracker);
+            break;
+        }
+    }
+
+    @Override
+    public void startKeyRepeatTimer(final PointerTracker tracker, final int repeatCount,
+            final int delay) {
+        final Key key = tracker.getKey();
+        if (key == null || delay == 0) {
+            return;
+        }
+        sendMessageDelayed(
+                obtainMessage(MSG_REPEAT_KEY, key.getCode(), repeatCount, tracker), delay);
+    }
+
+    public void cancelKeyRepeatTimer() {
+        removeMessages(MSG_REPEAT_KEY);
+    }
+
+    // TODO: Suppress layout changes in key repeat mode
+    public boolean isInKeyRepeat() {
+        return hasMessages(MSG_REPEAT_KEY);
+    }
+
+    @Override
+    public void startLongPressTimer(final PointerTracker tracker, final int delay) {
+        cancelLongPressTimer();
+        if (delay <= 0) return;
+        sendMessageDelayed(obtainMessage(MSG_LONGPRESS_KEY, tracker), delay);
+    }
+
+    @Override
+    public void cancelLongPressTimer() {
+        removeMessages(MSG_LONGPRESS_KEY);
+    }
+
+    @Override
+    public void startTypingStateTimer(final Key typedKey) {
+        if (typedKey.isModifier() || typedKey.altCodeWhileTyping()) {
+            return;
+        }
+
+        final boolean isTyping = isTypingState();
+        removeMessages(MSG_TYPING_STATE_EXPIRED);
+        final MainKeyboardView keyboardView = getOuterInstance();
+
+        // When user hits the space or the enter key, just cancel the while-typing timer.
+        final int typedCode = typedKey.getCode();
+        if (typedCode == Constants.CODE_SPACE || typedCode == Constants.CODE_ENTER) {
+            if (isTyping) {
+                keyboardView.startWhileTypingFadeinAnimation();
+            }
+            return;
+        }
+
+        sendMessageDelayed(
+                obtainMessage(MSG_TYPING_STATE_EXPIRED), mIgnoreAltCodeKeyTimeout);
+        if (isTyping) {
+            return;
+        }
+        keyboardView.startWhileTypingFadeoutAnimation();
+    }
+
+    @Override
+    public boolean isTypingState() {
+        return hasMessages(MSG_TYPING_STATE_EXPIRED);
+    }
+
+    @Override
+    public void startDoubleTapShiftKeyTimer() {
+        sendMessageDelayed(obtainMessage(MSG_DOUBLE_TAP_SHIFT_KEY),
+                ViewConfiguration.getDoubleTapTimeout());
+    }
+
+    @Override
+    public void cancelDoubleTapShiftKeyTimer() {
+        removeMessages(MSG_DOUBLE_TAP_SHIFT_KEY);
+    }
+
+    @Override
+    public boolean isInDoubleTapShiftKeyTimeout() {
+        return hasMessages(MSG_DOUBLE_TAP_SHIFT_KEY);
+    }
+
+    @Override
+    public void cancelKeyTimers() {
+        cancelKeyRepeatTimer();
+        cancelLongPressTimer();
+    }
+
+    @Override
+    public void startUpdateBatchInputTimer(final PointerTracker tracker) {
+        if (mGestureRecognitionUpdateTime <= 0) {
+            return;
+        }
+        removeMessages(MSG_UPDATE_BATCH_INPUT, tracker);
+        sendMessageDelayed(obtainMessage(MSG_UPDATE_BATCH_INPUT, tracker),
+                mGestureRecognitionUpdateTime);
+    }
+
+    @Override
+    public void cancelUpdateBatchInputTimer(final PointerTracker tracker) {
+        removeMessages(MSG_UPDATE_BATCH_INPUT, tracker);
+    }
+
+    @Override
+    public void cancelAllUpdateBatchInputTimers() {
+        removeMessages(MSG_UPDATE_BATCH_INPUT);
+    }
+
+    public void cancelAllMessages() {
+        cancelKeyTimers();
+        cancelAllUpdateBatchInputTimers();
+    }
+}