diff --git a/java/src/com/android/inputmethod/accessibility/AccessibilityLongPressTimer.java b/java/src/com/android/inputmethod/accessibility/AccessibilityLongPressTimer.java
index 967cafad0c39f847b975cbded3ef1cdbc73480aa..37d910edbc28a67488f4c0b48e6551991931e554 100644
--- a/java/src/com/android/inputmethod/accessibility/AccessibilityLongPressTimer.java
+++ b/java/src/com/android/inputmethod/accessibility/AccessibilityLongPressTimer.java
@@ -26,7 +26,7 @@ import com.android.inputmethod.latin.R;
 // Handling long press timer to show a more keys keyboard.
 final class AccessibilityLongPressTimer extends Handler {
     public interface LongPressTimerCallback {
-        public void onLongPressed(Key key);
+        public void performLongClickOn(Key key);
     }
 
     private static final int MSG_LONG_PRESS = 1;
@@ -47,7 +47,7 @@ final class AccessibilityLongPressTimer extends Handler {
         switch (msg.what) {
         case MSG_LONG_PRESS:
             cancelLongPress();
-            mCallback.onLongPressed((Key)msg.obj);
+            mCallback.performLongClickOn((Key)msg.obj);
             return;
         default:
             super.handleMessage(msg);
diff --git a/java/src/com/android/inputmethod/accessibility/KeyboardAccessibilityDelegate.java b/java/src/com/android/inputmethod/accessibility/KeyboardAccessibilityDelegate.java
index eb5b663dc90a8ed2cf975da24966834e3e71ed80..237117d10a6e0a30cd3c3c97823e40efe4b01551 100644
--- a/java/src/com/android/inputmethod/accessibility/KeyboardAccessibilityDelegate.java
+++ b/java/src/com/android/inputmethod/accessibility/KeyboardAccessibilityDelegate.java
@@ -17,6 +17,7 @@
 package com.android.inputmethod.accessibility;
 
 import android.content.Context;
+import android.os.SystemClock;
 import android.support.v4.view.AccessibilityDelegateCompat;
 import android.support.v4.view.ViewCompat;
 import android.support.v4.view.accessibility.AccessibilityNodeInfoCompat;
@@ -49,7 +50,7 @@ public class KeyboardAccessibilityDelegate<KV extends KeyboardView>
     protected final KV mKeyboardView;
     protected final KeyDetector mKeyDetector;
     private Keyboard mKeyboard;
-    private KeyboardAccessibilityNodeProvider mAccessibilityNodeProvider;
+    private KeyboardAccessibilityNodeProvider<KV> mAccessibilityNodeProvider;
     private Key mLastHoverKey;
 
     public static final int HOVER_EVENT_POINTER_ID = 0;
@@ -132,19 +133,20 @@ public class KeyboardAccessibilityDelegate<KV extends KeyboardView>
      * @return The accessibility node provider for the current keyboard.
      */
     @Override
-    public KeyboardAccessibilityNodeProvider getAccessibilityNodeProvider(final View host) {
+    public KeyboardAccessibilityNodeProvider<KV> getAccessibilityNodeProvider(final View host) {
         return getAccessibilityNodeProvider();
     }
 
     /**
      * @return A lazily-instantiated node provider for this view delegate.
      */
-    protected KeyboardAccessibilityNodeProvider getAccessibilityNodeProvider() {
+    protected KeyboardAccessibilityNodeProvider<KV> getAccessibilityNodeProvider() {
         // Instantiate the provide only when requested. Since the system
         // will call this method multiple times it is a good practice to
         // cache the provider instance.
         if (mAccessibilityNodeProvider == null) {
-            mAccessibilityNodeProvider = new KeyboardAccessibilityNodeProvider(mKeyboardView);
+            mAccessibilityNodeProvider =
+                    new KeyboardAccessibilityNodeProvider<>(mKeyboardView, this);
         }
         return mAccessibilityNodeProvider;
     }
@@ -241,35 +243,37 @@ public class KeyboardAccessibilityDelegate<KV extends KeyboardView>
         // Make sure we're not getting an EXIT event because the user slid
         // off the keyboard area, then force a key press.
         if (key != null) {
-            onRegisterHoverKey(key, event);
+            performClickOn(key);
             onHoverExitFrom(key);
         }
         setLastHoverKey(null);
     }
 
     /**
-     * Register a key that is selected by a hover event
+     * Perform click on a key.
      *
      * @param key A key to be registered.
-     * @param event A hover exit event that triggers key registering.
      */
-    protected void onRegisterHoverKey(final Key key, final MotionEvent event) {
+    public void performClickOn(final Key key) {
         if (DEBUG_HOVER) {
-            Log.d(TAG, "onRegisterHoverKey: key=" + key);
+            Log.d(TAG, "performClickOn: key=" + key);
         }
-        simulateTouchEvent(MotionEvent.ACTION_DOWN, event);
-        simulateTouchEvent(MotionEvent.ACTION_UP, event);
+        simulateTouchEvent(MotionEvent.ACTION_DOWN, key);
+        simulateTouchEvent(MotionEvent.ACTION_UP, key);
     }
 
     /**
      * Simulating a touch event by injecting a synthesized touch event into {@link KeyboardView}.
      *
      * @param touchAction The action of the synthesizing touch event.
-     * @param hoverEvent The base hover event from that the touch event is synthesized.
+     * @param key The key that a synthesized touch event is on.
      */
-    private void simulateTouchEvent(final int touchAction, final MotionEvent hoverEvent) {
-        final MotionEvent touchEvent = MotionEvent.obtain(hoverEvent);
-        touchEvent.setAction(touchAction);
+    private void simulateTouchEvent(final int touchAction, final Key key) {
+        final int x = key.getHitBox().centerX();
+        final int y = key.getHitBox().centerY();
+        final long eventTime = SystemClock.uptimeMillis();
+        final MotionEvent touchEvent = MotionEvent.obtain(
+                eventTime, eventTime, touchAction, x, y, 0 /* metaState */);
         mKeyboardView.onTouchEvent(touchEvent);
         touchEvent.recycle();
     }
@@ -285,7 +289,7 @@ public class KeyboardAccessibilityDelegate<KV extends KeyboardView>
         }
         key.onPressed();
         mKeyboardView.invalidateKey(key);
-        final KeyboardAccessibilityNodeProvider provider = getAccessibilityNodeProvider();
+        final KeyboardAccessibilityNodeProvider<KV> provider = getAccessibilityNodeProvider();
         provider.onHoverEnterTo(key);
         provider.performActionForKey(key, AccessibilityNodeInfoCompat.ACTION_ACCESSIBILITY_FOCUS);
     }
@@ -308,7 +312,16 @@ public class KeyboardAccessibilityDelegate<KV extends KeyboardView>
         }
         key.onReleased();
         mKeyboardView.invalidateKey(key);
-        final KeyboardAccessibilityNodeProvider provider = getAccessibilityNodeProvider();
+        final KeyboardAccessibilityNodeProvider<KV> provider = getAccessibilityNodeProvider();
         provider.onHoverExitFrom(key);
     }
+
+    /**
+     * Perform long click on a key.
+     *
+     * @param key A key to be long pressed on.
+     */
+    public void performLongClickOn(final Key key) {
+        // A extended class should override this method to implement long press.
+    }
 }
diff --git a/java/src/com/android/inputmethod/accessibility/KeyboardAccessibilityNodeProvider.java b/java/src/com/android/inputmethod/accessibility/KeyboardAccessibilityNodeProvider.java
index 328d9ec0d49522934f1a1154a6bd506e1b9697c0..66b0acb2f2833631e536c242a1bd791c7278b937 100644
--- a/java/src/com/android/inputmethod/accessibility/KeyboardAccessibilityNodeProvider.java
+++ b/java/src/com/android/inputmethod/accessibility/KeyboardAccessibilityNodeProvider.java
@@ -47,7 +47,8 @@ import java.util.List;
  * virtual views, thus conveying their logical structure.
  * </p>
  */
-final class KeyboardAccessibilityNodeProvider extends AccessibilityNodeProviderCompat {
+final class KeyboardAccessibilityNodeProvider<KV extends KeyboardView>
+        extends AccessibilityNodeProviderCompat {
     private static final String TAG = KeyboardAccessibilityNodeProvider.class.getSimpleName();
 
     // From {@link android.view.accessibility.AccessibilityNodeInfo#UNDEFINED_ITEM_ID}.
@@ -69,16 +70,20 @@ final class KeyboardAccessibilityNodeProvider extends AccessibilityNodeProviderC
     private int mHoveringNodeId = UNDEFINED;
 
     /** The keyboard view to provide an accessibility node info. */
-    private final KeyboardView mKeyboardView;
+    private final KV mKeyboardView;
+    /** The accessibility delegate. */
+    private final KeyboardAccessibilityDelegate<KV> mDelegate;
 
     /** The current keyboard. */
     private Keyboard mKeyboard;
 
-    public KeyboardAccessibilityNodeProvider(final KeyboardView keyboardView) {
+    public KeyboardAccessibilityNodeProvider(final KV keyboardView,
+            final KeyboardAccessibilityDelegate<KV> delegate) {
         super();
         mKeyCodeDescriptionMapper = KeyCodeDescriptionMapper.getInstance();
         mAccessibilityUtils = AccessibilityUtils.getInstance();
         mKeyboardView = keyboardView;
+        mDelegate = delegate;
 
         // Since this class is constructed lazily, we might not get a subsequent
         // call to setKeyboard() and therefore need to call it now.
@@ -287,9 +292,11 @@ final class KeyboardAccessibilityNodeProvider extends AccessibilityNodeProviderC
             return true;
         case AccessibilityNodeInfoCompat.ACTION_CLICK:
             sendAccessibilityEventForKey(key, AccessibilityEvent.TYPE_VIEW_CLICKED);
+            mDelegate.performClickOn(key);
             return true;
         case AccessibilityNodeInfoCompat.ACTION_LONG_CLICK:
             sendAccessibilityEventForKey(key, AccessibilityEvent.TYPE_VIEW_LONG_CLICKED);
+            mDelegate.performLongClickOn(key);
             return true;
         default:
             return false;
diff --git a/java/src/com/android/inputmethod/accessibility/MainKeyboardAccessibilityDelegate.java b/java/src/com/android/inputmethod/accessibility/MainKeyboardAccessibilityDelegate.java
index 96f84dde936aad72d02229595e213c2f502c9849..b84d402fbcb97a6d793d783afa62354a207b41b2 100644
--- a/java/src/com/android/inputmethod/accessibility/MainKeyboardAccessibilityDelegate.java
+++ b/java/src/com/android/inputmethod/accessibility/MainKeyboardAccessibilityDelegate.java
@@ -207,11 +207,11 @@ public final class MainKeyboardAccessibilityDelegate
     }
 
     @Override
-    protected void onRegisterHoverKey(final Key key, final MotionEvent event) {
+    public void performClickOn(final Key key) {
         final int x = key.getHitBox().centerX();
         final int y = key.getHitBox().centerY();
         if (DEBUG_HOVER) {
-            Log.d(TAG, "onRegisterHoverKey: key=" + key
+            Log.d(TAG, "performClickOn: key=" + key
                     + " inIgnoreBounds=" + mBoundsToIgnoreHoverEvent.contains(x, y));
         }
         if (mBoundsToIgnoreHoverEvent.contains(x, y)) {
@@ -220,7 +220,7 @@ public final class MainKeyboardAccessibilityDelegate
             mBoundsToIgnoreHoverEvent.setEmpty();
             return;
         }
-        super.onRegisterHoverKey(key, event);
+        super.performClickOn(key);
     }
 
     @Override
@@ -257,9 +257,9 @@ public final class MainKeyboardAccessibilityDelegate
     }
 
     @Override
-    public void onLongPressed(final Key key) {
+    public void performLongClickOn(final Key key) {
         if (DEBUG_HOVER) {
-            Log.d(TAG, "onLongPressed: key=" + key);
+            Log.d(TAG, "performLongClickOn: key=" + key);
         }
         final PointerTracker tracker = PointerTracker.getPointerTracker(HOVER_EVENT_POINTER_ID);
         final long eventTime = SystemClock.uptimeMillis();