Use onHoverEvent instead of dispatchHoverEvent

This CL also refactors KeyboardAccessibilityDelegate a bit to be able
to override on hovering methods that handle enter, move, and exit on a
key.

Bug: 12491371
Change-Id: I3c7e81ccb8729ae6e466c654efde0c18ed734bdf
main
Tadashi G. Takaoka 2014-05-26 12:51:37 +09:00
parent f6d59f6a6b
commit 9647d7fbee
3 changed files with 53 additions and 65 deletions

View File

@ -37,7 +37,7 @@ public class KeyboardAccessibilityDelegate<KV extends KeyboardView>
protected final KeyDetector mKeyDetector; protected final KeyDetector mKeyDetector;
private Keyboard mKeyboard; private Keyboard mKeyboard;
private KeyboardAccessibilityNodeProvider mAccessibilityNodeProvider; private KeyboardAccessibilityNodeProvider mAccessibilityNodeProvider;
private Key mLastHoverKey; private Key mCurrentHoverKey;
public KeyboardAccessibilityDelegate(final KV keyboardView, final KeyDetector keyDetector) { public KeyboardAccessibilityDelegate(final KV keyboardView, final KeyDetector keyDetector) {
super(); super();
@ -117,14 +117,14 @@ public class KeyboardAccessibilityDelegate<KV extends KeyboardView>
* Receives hover events when touch exploration is turned on in SDK versions ICS and higher. * Receives hover events when touch exploration is turned on in SDK versions ICS and higher.
* *
* @param event The hover event. * @param event The hover event.
* @return {@code true} if the event is handled * @return {@code true} if the event is handled.
*/ */
public boolean dispatchHoverEvent(final MotionEvent event) { public boolean onHoverEvent(final MotionEvent event) {
final int x = (int) event.getX(); final int x = (int) event.getX();
final int y = (int) event.getY(); final int y = (int) event.getY();
final Key previousKey = mLastHoverKey; final Key previousKey = mCurrentHoverKey;
final Key key = mKeyDetector.detectHitKey(x, y); final Key key = mKeyDetector.detectHitKey(x, y);
mLastHoverKey = key; mCurrentHoverKey = key;
switch (event.getAction()) { switch (event.getAction()) {
case MotionEvent.ACTION_HOVER_EXIT: case MotionEvent.ACTION_HOVER_EXIT:
@ -133,17 +133,30 @@ public class KeyboardAccessibilityDelegate<KV extends KeyboardView>
if (key != null) { if (key != null) {
final long downTime = simulateKeyPress(key); final long downTime = simulateKeyPress(key);
simulateKeyRelease(key, downTime); simulateKeyRelease(key, downTime);
onHoverExitKey(key);
} }
//$FALL-THROUGH$ mCurrentHoverKey = null;
break;
case MotionEvent.ACTION_HOVER_ENTER: case MotionEvent.ACTION_HOVER_ENTER:
return onHoverKey(key, event); if (key != null) {
onHoverEnterKey(key);
}
break;
case MotionEvent.ACTION_HOVER_MOVE: case MotionEvent.ACTION_HOVER_MOVE:
if (key != previousKey) { if (key != previousKey) {
return onTransitionKey(key, previousKey, event); if (previousKey != null) {
onHoverExitKey(previousKey);
}
if (key != null) {
onHoverEnterKey(key);
}
} }
return onHoverKey(key, event); if (key != null) {
onHoverMoveKey(key);
}
break;
} }
return false; return true;
} }
/** /**
@ -151,6 +164,7 @@ public class KeyboardAccessibilityDelegate<KV extends KeyboardView>
* This avoids the complexity of trackers and listeners within the keyboard. * This avoids the complexity of trackers and listeners within the keyboard.
* *
* @param key The key to press. * @param key The key to press.
* @return the event time of the simulated key press.
*/ */
private long simulateKeyPress(final Key key) { private long simulateKeyPress(final Key key) {
final int x = key.getHitBox().centerX(); final int x = key.getHitBox().centerX();
@ -168,6 +182,7 @@ public class KeyboardAccessibilityDelegate<KV extends KeyboardView>
* This avoids the complexity of trackers and listeners within the keyboard. * This avoids the complexity of trackers and listeners within the keyboard.
* *
* @param key The key to release. * @param key The key to release.
* @param downTime the event time of the key press.
*/ */
private void simulateKeyRelease(final Key key, final long downTime) { private void simulateKeyRelease(final Key key, final long downTime) {
final int x = key.getHitBox().centerX(); final int x = key.getHitBox().centerX();
@ -179,54 +194,30 @@ public class KeyboardAccessibilityDelegate<KV extends KeyboardView>
} }
/** /**
* Simulates a transition between two {@link Key}s by sending a HOVER_EXIT on the previous key, * Handles a hover enter event on a key.
* a HOVER_ENTER on the current key, and a HOVER_MOVE on the current key.
* *
* @param currentKey The currently hovered key. * @param key The currently hovered key.
* @param previousKey The previously hovered key.
* @param event The event that triggered the transition.
* @return {@code true} if the event was handled.
*/ */
private boolean onTransitionKey(final Key currentKey, final Key previousKey, protected void onHoverEnterKey(final Key key) {
final MotionEvent event) { final KeyboardAccessibilityNodeProvider provider = getAccessibilityNodeProvider();
final int savedAction = event.getAction(); provider.sendAccessibilityEventForKey(key, AccessibilityEventCompat.TYPE_VIEW_HOVER_ENTER);
event.setAction(MotionEvent.ACTION_HOVER_EXIT); provider.performActionForKey(key, AccessibilityNodeInfoCompat.ACTION_ACCESSIBILITY_FOCUS);
onHoverKey(previousKey, event);
event.setAction(MotionEvent.ACTION_HOVER_ENTER);
onHoverKey(currentKey, event);
event.setAction(MotionEvent.ACTION_HOVER_MOVE);
final boolean handled = onHoverKey(currentKey, event);
event.setAction(savedAction);
return handled;
} }
/** /**
* Handles a hover event on a key. If {@link Key} extended View, this would be analogous to * Handles a hover move event on a key.
* calling View.onHoverEvent(MotionEvent).
* *
* @param key The currently hovered key. * @param key The currently hovered key.
* @param event The hover event.
* @return {@code true} if the event was handled.
*/ */
private boolean onHoverKey(final Key key, final MotionEvent event) { protected void onHoverMoveKey(final Key key) { }
// Null keys can't receive events.
if (key == null) {
return false;
}
final KeyboardAccessibilityNodeProvider provider = getAccessibilityNodeProvider();
switch (event.getAction()) { /**
case MotionEvent.ACTION_HOVER_ENTER: * Handles a hover exit event on a key.
provider.sendAccessibilityEventForKey( *
key, AccessibilityEventCompat.TYPE_VIEW_HOVER_ENTER); * @param key The currently hovered key.
provider.performActionForKey( */
key, AccessibilityNodeInfoCompat.ACTION_ACCESSIBILITY_FOCUS); protected void onHoverExitKey(final Key key) {
break; final KeyboardAccessibilityNodeProvider provider = getAccessibilityNodeProvider();
case MotionEvent.ACTION_HOVER_EXIT: provider.sendAccessibilityEventForKey(key, AccessibilityEventCompat.TYPE_VIEW_HOVER_EXIT);
provider.sendAccessibilityEventForKey(
key, AccessibilityEventCompat.TYPE_VIEW_HOVER_EXIT);
break;
}
return true;
} }
} }

View File

@ -763,19 +763,14 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
} }
/** /**
* Receives hover events from the input framework. * {@inheritDoc}
*
* @param event The motion event to be dispatched.
* @return {@code true} if the event was handled by the view, {@code false}
* otherwise
*/ */
@Override @Override
public boolean dispatchHoverEvent(final MotionEvent event) { public boolean onHoverEvent(final MotionEvent event) {
if (!AccessibilityUtils.getInstance().isTouchExplorationEnabled()) { if (AccessibilityUtils.getInstance().isTouchExplorationEnabled()) {
// Reflection doesn't support calling superclass methods. return mAccessibilityDelegate.onHoverEvent(event);
return false;
} }
return mAccessibilityDelegate.dispatchHoverEvent(event); return super.onHoverEvent(event);
} }
public void updateShortcutKey(final boolean available) { public void updateShortcutKey(final boolean available) {

View File

@ -83,13 +83,15 @@ final class EmojiPageKeyboardView extends KeyboardView implements
mKeyDetector.setKeyboard(keyboard, 0 /* correctionX */, 0 /* correctionY */); mKeyDetector.setKeyboard(keyboard, 0 /* correctionX */, 0 /* correctionY */);
} }
/**
* {@inheritDoc}
*/
@Override @Override
public boolean dispatchHoverEvent(final MotionEvent event) { public boolean onHoverEvent(final MotionEvent event) {
if (!AccessibilityUtils.getInstance().isTouchExplorationEnabled()) { if (AccessibilityUtils.getInstance().isTouchExplorationEnabled()) {
// Reflection doesn't support calling superclass methods. return mAccessibilityDelegate.onHoverEvent(event);
return false;
} }
return mAccessibilityDelegate.dispatchHoverEvent(event); return super.onHoverEvent(event);
} }
/** /**