From 1e3167229519843b83ba8bea7d78a82ffba236bc Mon Sep 17 00:00:00 2001 From: "Tadashi G. Takaoka" Date: Tue, 24 Jun 2014 15:14:24 -0700 Subject: [PATCH] Support performAccessibilityAction for CLICK and LONG_CLICK Bug: 15727335 Change-Id: I83274c1a9d3cf2e8237d1674fe915b7b2d222a53 --- .../AccessibilityLongPressTimer.java | 4 +- .../KeyboardAccessibilityDelegate.java | 47 ++++++++++++------- .../KeyboardAccessibilityNodeProvider.java | 13 +++-- .../MainKeyboardAccessibilityDelegate.java | 10 ++-- 4 files changed, 47 insertions(+), 27 deletions(-) diff --git a/java/src/com/android/inputmethod/accessibility/AccessibilityLongPressTimer.java b/java/src/com/android/inputmethod/accessibility/AccessibilityLongPressTimer.java index 967cafad0..37d910edb 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 eb5b663dc..237117d10 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 protected final KV mKeyboardView; protected final KeyDetector mKeyDetector; private Keyboard mKeyboard; - private KeyboardAccessibilityNodeProvider mAccessibilityNodeProvider; + private KeyboardAccessibilityNodeProvider mAccessibilityNodeProvider; private Key mLastHoverKey; public static final int HOVER_EVENT_POINTER_ID = 0; @@ -132,19 +133,20 @@ public class KeyboardAccessibilityDelegate * @return The accessibility node provider for the current keyboard. */ @Override - public KeyboardAccessibilityNodeProvider getAccessibilityNodeProvider(final View host) { + public KeyboardAccessibilityNodeProvider getAccessibilityNodeProvider(final View host) { return getAccessibilityNodeProvider(); } /** * @return A lazily-instantiated node provider for this view delegate. */ - protected KeyboardAccessibilityNodeProvider getAccessibilityNodeProvider() { + protected KeyboardAccessibilityNodeProvider 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 // 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 } key.onPressed(); mKeyboardView.invalidateKey(key); - final KeyboardAccessibilityNodeProvider provider = getAccessibilityNodeProvider(); + final KeyboardAccessibilityNodeProvider provider = getAccessibilityNodeProvider(); provider.onHoverEnterTo(key); provider.performActionForKey(key, AccessibilityNodeInfoCompat.ACTION_ACCESSIBILITY_FOCUS); } @@ -308,7 +312,16 @@ public class KeyboardAccessibilityDelegate } key.onReleased(); mKeyboardView.invalidateKey(key); - final KeyboardAccessibilityNodeProvider provider = getAccessibilityNodeProvider(); + final KeyboardAccessibilityNodeProvider 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 328d9ec0d..66b0acb2f 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. *

*/ -final class KeyboardAccessibilityNodeProvider extends AccessibilityNodeProviderCompat { +final class KeyboardAccessibilityNodeProvider + 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 mDelegate; /** The current keyboard. */ private Keyboard mKeyboard; - public KeyboardAccessibilityNodeProvider(final KeyboardView keyboardView) { + public KeyboardAccessibilityNodeProvider(final KV keyboardView, + final KeyboardAccessibilityDelegate 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 96f84dde9..b84d402fb 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();