Consolidate TimerHandler.Callbacks with PointerTracker.DrawingProxy

Change-Id: I654f7483d1c013ac2685a45af4eb2af15fa219ad
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardView.java b/java/src/com/android/inputmethod/keyboard/KeyboardView.java
index 6feb1e7..b07693c 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardView.java
@@ -41,6 +41,8 @@
 
 import java.util.HashSet;
 
+import javax.annotation.Nullable;
+
 /**
  * A view that renders a virtual {@link Keyboard}.
  *
@@ -557,9 +559,10 @@
      * @param key key in the attached {@link Keyboard}.
      * @see #invalidateAllKeys
      */
-    public void invalidateKey(final Key key) {
-        if (mInvalidateAllKeys) return;
-        if (key == null) return;
+    public void invalidateKey(@Nullable final Key key) {
+        if (key == null || mInvalidateAllKeys) {
+            return;
+        }
         mInvalidatedKeys.add(key);
         final int x = key.getX() + getPaddingLeft();
         final int y = key.getY() + getPaddingTop();
diff --git a/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java b/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java
index 4c73da9..f23db04 100644
--- a/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java
@@ -39,6 +39,7 @@
 import com.android.inputmethod.accessibility.AccessibilityUtils;
 import com.android.inputmethod.accessibility.MainKeyboardAccessibilityDelegate;
 import com.android.inputmethod.annotations.ExternallyReferenced;
+import com.android.inputmethod.keyboard.PointerTracker.DrawingProxy;
 import com.android.inputmethod.keyboard.internal.DrawingPreviewPlacerView;
 import com.android.inputmethod.keyboard.internal.GestureFloatingTextDrawingPreview;
 import com.android.inputmethod.keyboard.internal.GestureTrailsDrawingPreview;
@@ -110,7 +111,7 @@
  * @attr ref R.styleable#MainKeyboardView_suppressKeyPreviewAfterBatchInputDuration
  */
 public final class MainKeyboardView extends KeyboardView implements PointerTracker.DrawingProxy,
-        MoreKeysPanel.Controller, TimerHandler.Callbacks {
+        MoreKeysPanel.Controller {
     private static final String TAG = MainKeyboardView.class.getSimpleName();
 
     /** Listener for {@link KeyboardActionListener}. */
@@ -178,7 +179,8 @@
     public MainKeyboardView(final Context context, final AttributeSet attrs, final int defStyle) {
         super(context, attrs, defStyle);
 
-        mDrawingPreviewPlacerView = new DrawingPreviewPlacerView(context, attrs);
+        final DrawingPreviewPlacerView drawingPreviewPlacerView =
+                new DrawingPreviewPlacerView(context, attrs);
 
         final TypedArray mainKeyboardViewAttr = context.obtainStyledAttributes(
                 attrs, R.styleable.MainKeyboardView, defStyle, R.style.MainKeyboardView);
@@ -246,15 +248,17 @@
 
         mGestureFloatingTextDrawingPreview = new GestureFloatingTextDrawingPreview(
                 mainKeyboardViewAttr);
-        mGestureFloatingTextDrawingPreview.setDrawingView(mDrawingPreviewPlacerView);
+        mGestureFloatingTextDrawingPreview.setDrawingView(drawingPreviewPlacerView);
 
         mGestureTrailsDrawingPreview = new GestureTrailsDrawingPreview(mainKeyboardViewAttr);
-        mGestureTrailsDrawingPreview.setDrawingView(mDrawingPreviewPlacerView);
+        mGestureTrailsDrawingPreview.setDrawingView(drawingPreviewPlacerView);
 
         mSlidingKeyInputDrawingPreview = new SlidingKeyInputDrawingPreview(mainKeyboardViewAttr);
-        mSlidingKeyInputDrawingPreview.setDrawingView(mDrawingPreviewPlacerView);
+        mSlidingKeyInputDrawingPreview.setDrawingView(drawingPreviewPlacerView);
         mainKeyboardViewAttr.recycle();
 
+        mDrawingPreviewPlacerView = drawingPreviewPlacerView;
+
         final LayoutInflater inflater = LayoutInflater.from(getContext());
         mMoreKeysKeyboardContainer = inflater.inflate(moreKeysKeyboardLayoutId, null);
         mMoreKeysKeyboardForActionContainer = inflater.inflate(
@@ -307,20 +311,20 @@
         animatorToStart.setCurrentPlayTime(startTime);
     }
 
-    // Implements {@link TimerHander.Callbacks#startWhileTypingAnimation(int)}.
+    // Implements {@link DrawingProxy#startWhileTypingAnimation(int)}.
     /**
      * Called when a while-typing-animation should be started.
-     * @param fadeInOrOut {@link TimerHandler.Callbacks#FADE_IN} starts while-typing-fade-in
-     * animation. {@link TimerHandler.Callbacks#FADE_OUT} starts while-typing-fade-out animation.
+     * @param fadeInOrOut {@link DrawingProxy#FADE_IN} starts while-typing-fade-in animation.
+     * {@link DrawingProxy#FADE_OUT} starts while-typing-fade-out animation.
      */
     @Override
     public void startWhileTypingAnimation(final int fadeInOrOut) {
         switch (fadeInOrOut) {
-        case TimerHandler.Callbacks.FADE_IN:
+        case DrawingProxy.FADE_IN:
             cancelAndStartAnimators(
                     mAltCodeKeyWhileTypingFadeoutAnimator, mAltCodeKeyWhileTypingFadeinAnimator);
             break;
-        case TimerHandler.Callbacks.FADE_OUT:
+        case DrawingProxy.FADE_OUT:
             cancelAndStartAnimators(
                     mAltCodeKeyWhileTypingFadeinAnimator, mAltCodeKeyWhileTypingFadeoutAnimator);
             break;
@@ -459,9 +463,9 @@
     }
 
     @Override
-    public void showKeyPreview(final Key key) {
+    public void showKeyPreview(@Nonnull final Key key) {
         // If the key is invalid or has no key preview, we must not show key preview.
-        if (key == null || key.noKeyPreview()) {
+        if (key.noKeyPreview()) {
             return;
         }
         final Keyboard keyboard = getKeyboard();
@@ -480,7 +484,7 @@
                 getWidth(), mOriginCoords, mDrawingPreviewPlacerView, isHardwareAccelerated());
     }
 
-    // Implements {@link TimerHandler.Callbacks#dismissKeyPreviewWithoutDelay(Key)}.
+    // Implements {@link DrawingProxy#dismissKeyPreviewWithoutDelay(Key)}.
     @Override
     public void dismissKeyPreviewWithoutDelay(@Nonnull final Key key) {
         mKeyPreviewChoreographer.dismissKeyPreview(key, false /* withAnimation */);
@@ -488,7 +492,7 @@
     }
 
     @Override
-    public void dismissKeyPreview(final Key key) {
+    public void dismissKeyPreview(@Nonnull final Key key) {
         if (isHardwareAccelerated()) {
             mKeyPreviewChoreographer.dismissKeyPreview(key, true /* withAnimation */);
             return;
@@ -502,7 +506,7 @@
     }
 
     @Override
-    public void showSlidingKeyInputPreview(final PointerTracker tracker) {
+    public void showSlidingKeyInputPreview(@Nullable final PointerTracker tracker) {
         locatePreviewPlacerView();
         if (tracker != null) {
             mSlidingKeyInputDrawingPreview.setPreviewPosition(tracker);
@@ -529,14 +533,14 @@
         }
     }
 
-    // Implements {@link TimerHandler.Callbacks#dismissGestureFloatingPreviewTextWithoutDelay()}.
+    // Implements {@link DrawingProxy#dismissGestureFloatingPreviewTextWithoutDelay()}.
     @Override
     public void dismissGestureFloatingPreviewTextWithoutDelay() {
         mGestureFloatingTextDrawingPreview.dismissGestureFloatingPreviewText();
     }
 
     @Override
-    public void showGestureTrail(final PointerTracker tracker,
+    public void showGestureTrail(@Nonnull final PointerTracker tracker,
             final boolean showsFloatingPreviewText) {
         locatePreviewPlacerView();
         if (showsFloatingPreviewText) {
@@ -603,7 +607,7 @@
         return moreKeysKeyboardView;
     }
 
-    // Implements {@link TimerHandler.Callbacks#onLongPress(PointerTracker)}.
+    // Implements {@link DrawingProxy@onLongPress(PointerTracker)}.
     /**
      * Called when a key is long pressed.
      * @param tracker the pointer tracker which pressed the parent key
diff --git a/java/src/com/android/inputmethod/keyboard/PointerTracker.java b/java/src/com/android/inputmethod/keyboard/PointerTracker.java
index fcf0522..467f515 100644
--- a/java/src/com/android/inputmethod/keyboard/PointerTracker.java
+++ b/java/src/com/android/inputmethod/keyboard/PointerTracker.java
@@ -53,12 +53,18 @@
     private static boolean DEBUG_MODE = DebugFlags.DEBUG_ENABLED || DEBUG_EVENT;
 
     public interface DrawingProxy {
-        public void invalidateKey(Key key);
-        public void showKeyPreview(Key key);
-        public void dismissKeyPreview(Key key);
+        public void invalidateKey(@Nullable Key key);
+        public void showKeyPreview(@Nonnull Key key);
+        public void dismissKeyPreview(@Nonnull Key key);
+        public void dismissKeyPreviewWithoutDelay(@Nonnull Key key);
+        public void onLongPress(@Nonnull PointerTracker tracker);
+        public static final int FADE_IN = 0;
+        public static final int FADE_OUT = 1;
+        public void startWhileTypingAnimation(final int fadeInOrOut);
         public void showSlidingKeyInputPreview(@Nullable PointerTracker tracker);
         public void showGestureTrail(@Nonnull PointerTracker tracker,
                 boolean showsFloatingPreviewText);
+        public void dismissGestureFloatingPreviewTextWithoutDelay();
     }
 
     public interface TimerProxy {
@@ -166,6 +172,7 @@
 
     // The position and time at which first down event occurred.
     private long mDownTime;
+    @Nonnull
     private int[] mDownCoordinates = CoordinateUtils.newInstance();
     private long mUpTime;
 
@@ -433,12 +440,12 @@
         return mKeyDetector.detectHitKey(x, y);
     }
 
-    private void setReleasedKeyGraphics(final Key key) {
-        sDrawingProxy.dismissKeyPreview(key);
+    private void setReleasedKeyGraphics(@Nullable final Key key) {
         if (key == null) {
             return;
         }
 
+        sDrawingProxy.dismissKeyPreview(key);
         // Even if the key is disabled, update the key release graphics just in case.
         updateReleaseKeyGraphics(key);
 
@@ -522,7 +529,7 @@
         return mGestureStrokeDrawingPoints;
     }
 
-    public void getLastCoordinates(final int[] outCoords) {
+    public void getLastCoordinates(@Nonnull final int[] outCoords) {
         CoordinateUtils.set(outCoords, mLastX, mLastY);
     }
 
@@ -530,7 +537,7 @@
         return mDownTime;
     }
 
-    public void getDownCoordinates(final int[] outCoords) {
+    public void getDownCoordinates(@Nonnull final int[] outCoords) {
         CoordinateUtils.copy(outCoords, mDownCoordinates);
     }
 
diff --git a/java/src/com/android/inputmethod/keyboard/internal/TimerHandler.java b/java/src/com/android/inputmethod/keyboard/internal/TimerHandler.java
index ca5bb12..4565225 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/TimerHandler.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/TimerHandler.java
@@ -22,24 +22,15 @@
 
 import com.android.inputmethod.keyboard.Key;
 import com.android.inputmethod.keyboard.PointerTracker;
+import com.android.inputmethod.keyboard.PointerTracker.DrawingProxy;
 import com.android.inputmethod.keyboard.PointerTracker.TimerProxy;
-import com.android.inputmethod.keyboard.internal.TimerHandler.Callbacks;
 import com.android.inputmethod.latin.common.Constants;
 import com.android.inputmethod.latin.utils.LeakGuardHandlerWrapper;
 
 import javax.annotation.Nonnull;
 
-// TODO: Separate this class into KeyTimerHandler and BatchInputTimerHandler or so.
-public final class TimerHandler extends LeakGuardHandlerWrapper<Callbacks> implements TimerProxy {
-    public interface Callbacks {
-        public static final int FADE_IN = 0;
-        public static final int FADE_OUT = 1;
-        public void startWhileTypingAnimation(final int fadeInOrOut);
-        public void onLongPress(@Nonnull PointerTracker tracker);
-        public void dismissKeyPreviewWithoutDelay(@Nonnull Key key);
-        public void dismissGestureFloatingPreviewTextWithoutDelay();
-    }
-
+public final class TimerHandler extends LeakGuardHandlerWrapper<DrawingProxy>
+        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;
@@ -52,8 +43,8 @@
     private final int mIgnoreAltCodeKeyTimeout;
     private final int mGestureRecognitionUpdateTime;
 
-    public TimerHandler(@Nonnull final Callbacks ownerInstance, final int ignoreAltCodeKeyTimeout,
-            final int gestureRecognitionUpdateTime) {
+    public TimerHandler(@Nonnull final DrawingProxy ownerInstance,
+            final int ignoreAltCodeKeyTimeout, final int gestureRecognitionUpdateTime) {
         super(ownerInstance);
         mIgnoreAltCodeKeyTimeout = ignoreAltCodeKeyTimeout;
         mGestureRecognitionUpdateTime = gestureRecognitionUpdateTime;
@@ -61,13 +52,13 @@
 
     @Override
     public void handleMessage(final Message msg) {
-        final Callbacks callbacks = getOwnerInstance();
-        if (callbacks == null) {
+        final DrawingProxy drawingProxy = getOwnerInstance();
+        if (drawingProxy == null) {
             return;
         }
         switch (msg.what) {
         case MSG_TYPING_STATE_EXPIRED:
-            callbacks.startWhileTypingAnimation(Callbacks.FADE_IN);
+            drawingProxy.startWhileTypingAnimation(DrawingProxy.FADE_IN);
             break;
         case MSG_REPEAT_KEY:
             final PointerTracker tracker1 = (PointerTracker) msg.obj;
@@ -77,7 +68,7 @@
         case MSG_LONGPRESS_SHIFT_KEY:
             cancelLongPressTimers();
             final PointerTracker tracker2 = (PointerTracker) msg.obj;
-            callbacks.onLongPress(tracker2);
+            drawingProxy.onLongPress(tracker2);
             break;
         case MSG_UPDATE_BATCH_INPUT:
             final PointerTracker tracker3 = (PointerTracker) msg.obj;
@@ -86,10 +77,10 @@
             break;
         case MSG_DISMISS_KEY_PREVIEW:
             final Key key = (Key) msg.obj;
-            callbacks.dismissKeyPreviewWithoutDelay(key);
+            drawingProxy.dismissKeyPreviewWithoutDelay(key);
             break;
         case MSG_DISMISS_GESTURE_FLOATING_PREVIEW_TEXT:
-            callbacks.dismissGestureFloatingPreviewTextWithoutDelay();
+            drawingProxy.dismissGestureFloatingPreviewTextWithoutDelay();
             break;
         }
     }
@@ -155,8 +146,8 @@
 
         final boolean isTyping = isTypingState();
         removeMessages(MSG_TYPING_STATE_EXPIRED);
-        final Callbacks callbacks = getOwnerInstance();
-        if (callbacks == null) {
+        final DrawingProxy drawingProxy = getOwnerInstance();
+        if (drawingProxy == null) {
             return;
         }
 
@@ -164,7 +155,7 @@
         final int typedCode = typedKey.getCode();
         if (typedCode == Constants.CODE_SPACE || typedCode == Constants.CODE_ENTER) {
             if (isTyping) {
-                callbacks.startWhileTypingAnimation(Callbacks.FADE_IN);
+                drawingProxy.startWhileTypingAnimation(DrawingProxy.FADE_IN);
             }
             return;
         }
@@ -174,7 +165,7 @@
         if (isTyping) {
             return;
         }
-        callbacks.startWhileTypingAnimation(Callbacks.FADE_OUT);
+        drawingProxy.startWhileTypingAnimation(DrawingProxy.FADE_OUT);
     }
 
     @Override