mirror of
https://gitlab.futo.org/keyboard/latinime.git
synced 2024-09-28 14:54:30 +01:00
Remove accessibility gesture handlers from LatinIME.
Bug: 6457558 Change-Id: If33ca6f026d4846ba79a701ef42c0112f5b0b488
This commit is contained in:
parent
67b2c58404
commit
34b2b5e694
@ -58,7 +58,6 @@ public class AccessibilityUtils {
|
|||||||
// These only need to be initialized if the kill switch is off.
|
// These only need to be initialized if the kill switch is off.
|
||||||
sInstance.initInternal(inputMethod);
|
sInstance.initInternal(inputMethod);
|
||||||
KeyCodeDescriptionMapper.init();
|
KeyCodeDescriptionMapper.init();
|
||||||
AccessibleInputMethodServiceProxy.init(inputMethod);
|
|
||||||
AccessibleKeyboardViewProxy.init(inputMethod);
|
AccessibleKeyboardViewProxy.init(inputMethod);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,84 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2011 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.accessibility;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.inputmethodservice.InputMethodService;
|
|
||||||
import android.media.AudioManager;
|
|
||||||
import android.os.Vibrator;
|
|
||||||
import android.view.KeyEvent;
|
|
||||||
|
|
||||||
public class AccessibleInputMethodServiceProxy implements AccessibleKeyboardActionListener {
|
|
||||||
private static final AccessibleInputMethodServiceProxy sInstance =
|
|
||||||
new AccessibleInputMethodServiceProxy();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Duration of the key click vibration in milliseconds.
|
|
||||||
*/
|
|
||||||
private static final long VIBRATE_KEY_CLICK = 50;
|
|
||||||
|
|
||||||
private static final float FX_VOLUME = -1.0f;
|
|
||||||
|
|
||||||
private InputMethodService mInputMethod;
|
|
||||||
private Vibrator mVibrator;
|
|
||||||
private AudioManager mAudioManager;
|
|
||||||
|
|
||||||
public static void init(InputMethodService inputMethod) {
|
|
||||||
sInstance.initInternal(inputMethod);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static AccessibleInputMethodServiceProxy getInstance() {
|
|
||||||
return sInstance;
|
|
||||||
}
|
|
||||||
|
|
||||||
private AccessibleInputMethodServiceProxy() {
|
|
||||||
// Not publicly instantiable.
|
|
||||||
}
|
|
||||||
|
|
||||||
private void initInternal(InputMethodService inputMethod) {
|
|
||||||
mInputMethod = inputMethod;
|
|
||||||
mVibrator = (Vibrator) inputMethod.getSystemService(Context.VIBRATOR_SERVICE);
|
|
||||||
mAudioManager = (AudioManager) inputMethod.getSystemService(Context.AUDIO_SERVICE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handle flick gestures by mapping them to directional pad keys.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void onFlickGesture(int direction) {
|
|
||||||
switch (direction) {
|
|
||||||
case FlickGestureDetector.FLICK_LEFT:
|
|
||||||
sendDownUpKeyEvents(KeyEvent.KEYCODE_DPAD_LEFT);
|
|
||||||
break;
|
|
||||||
case FlickGestureDetector.FLICK_RIGHT:
|
|
||||||
sendDownUpKeyEvents(KeyEvent.KEYCODE_DPAD_RIGHT);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Provide haptic feedback and send the specified keyCode to the input
|
|
||||||
* connection as a pair of down/up events.
|
|
||||||
*
|
|
||||||
* @param keyCode
|
|
||||||
*/
|
|
||||||
private void sendDownUpKeyEvents(int keyCode) {
|
|
||||||
mVibrator.vibrate(VIBRATE_KEY_CLICK);
|
|
||||||
mAudioManager.playSoundEffect(AudioManager.FX_KEYPRESS_STANDARD, FX_VOLUME);
|
|
||||||
mInputMethod.sendDownUpKeyEvents(keyCode);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,30 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2011 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.accessibility;
|
|
||||||
|
|
||||||
public interface AccessibleKeyboardActionListener {
|
|
||||||
/**
|
|
||||||
* @param direction the direction of the flick gesture, one of
|
|
||||||
* <ul>
|
|
||||||
* <li>{@link FlickGestureDetector#FLICK_UP}
|
|
||||||
* <li>{@link FlickGestureDetector#FLICK_DOWN}
|
|
||||||
* <li>{@link FlickGestureDetector#FLICK_LEFT}
|
|
||||||
* <li>{@link FlickGestureDetector#FLICK_RIGHT}
|
|
||||||
* </ul>
|
|
||||||
*/
|
|
||||||
public void onFlickGesture(int direction);
|
|
||||||
}
|
|
@ -17,8 +17,6 @@
|
|||||||
package com.android.inputmethod.accessibility;
|
package com.android.inputmethod.accessibility;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.graphics.Color;
|
|
||||||
import android.graphics.Paint;
|
|
||||||
import android.inputmethodservice.InputMethodService;
|
import android.inputmethodservice.InputMethodService;
|
||||||
import android.support.v4.view.AccessibilityDelegateCompat;
|
import android.support.v4.view.AccessibilityDelegateCompat;
|
||||||
import android.support.v4.view.ViewCompat;
|
import android.support.v4.view.ViewCompat;
|
||||||
@ -38,16 +36,13 @@ public class AccessibleKeyboardViewProxy extends AccessibilityDelegateCompat {
|
|||||||
private static final AccessibleKeyboardViewProxy sInstance = new AccessibleKeyboardViewProxy();
|
private static final AccessibleKeyboardViewProxy sInstance = new AccessibleKeyboardViewProxy();
|
||||||
|
|
||||||
private InputMethodService mInputMethod;
|
private InputMethodService mInputMethod;
|
||||||
private FlickGestureDetector mGestureDetector;
|
|
||||||
private LatinKeyboardView mView;
|
private LatinKeyboardView mView;
|
||||||
private AccessibleKeyboardActionListener mListener;
|
|
||||||
private AccessibilityEntityProvider mAccessibilityNodeProvider;
|
private AccessibilityEntityProvider mAccessibilityNodeProvider;
|
||||||
|
|
||||||
private Key mLastHoverKey = null;
|
private Key mLastHoverKey = null;
|
||||||
|
|
||||||
public static void init(InputMethodService inputMethod) {
|
public static void init(InputMethodService inputMethod) {
|
||||||
sInstance.initInternal(inputMethod);
|
sInstance.initInternal(inputMethod);
|
||||||
sInstance.mListener = AccessibleInputMethodServiceProxy.getInstance();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static AccessibleKeyboardViewProxy getInstance() {
|
public static AccessibleKeyboardViewProxy getInstance() {
|
||||||
@ -59,14 +54,7 @@ public class AccessibleKeyboardViewProxy extends AccessibilityDelegateCompat {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void initInternal(InputMethodService inputMethod) {
|
private void initInternal(InputMethodService inputMethod) {
|
||||||
final Paint paint = new Paint();
|
|
||||||
paint.setTextAlign(Paint.Align.LEFT);
|
|
||||||
paint.setTextSize(14.0f);
|
|
||||||
paint.setAntiAlias(true);
|
|
||||||
paint.setColor(Color.YELLOW);
|
|
||||||
|
|
||||||
mInputMethod = inputMethod;
|
mInputMethod = inputMethod;
|
||||||
mGestureDetector = new KeyboardFlickGestureDetector(inputMethod);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -112,19 +100,6 @@ public class AccessibleKeyboardViewProxy extends AccessibilityDelegateCompat {
|
|||||||
* @return {@code true} if the event is handled
|
* @return {@code true} if the event is handled
|
||||||
*/
|
*/
|
||||||
public boolean dispatchHoverEvent(MotionEvent event, PointerTracker tracker) {
|
public boolean dispatchHoverEvent(MotionEvent event, PointerTracker tracker) {
|
||||||
if (mGestureDetector.onHoverEvent(event, this, tracker))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
return onHoverEventInternal(event, tracker);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handles touch exploration events when Accessibility is turned on.
|
|
||||||
*
|
|
||||||
* @param event The touch exploration hover event.
|
|
||||||
* @return {@code true} if the event was handled
|
|
||||||
*/
|
|
||||||
/* package */boolean onHoverEventInternal(MotionEvent event, PointerTracker tracker) {
|
|
||||||
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 key = tracker.getKeyOn(x, y);
|
final Key key = tracker.getKeyOn(x, y);
|
||||||
@ -214,20 +189,6 @@ public class AccessibleKeyboardViewProxy extends AccessibilityDelegateCompat {
|
|||||||
mView.getParent().requestSendAccessibilityEvent(mView, event);
|
mView.getParent().requestSendAccessibilityEvent(mView, event);
|
||||||
}
|
}
|
||||||
|
|
||||||
private class KeyboardFlickGestureDetector extends FlickGestureDetector {
|
|
||||||
public KeyboardFlickGestureDetector(Context context) {
|
|
||||||
super(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onFlick(MotionEvent e1, MotionEvent e2, int direction) {
|
|
||||||
if (mListener != null) {
|
|
||||||
mListener.onFlickGesture(direction);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Notifies the user of changes in the keyboard shift state.
|
* Notifies the user of changes in the keyboard shift state.
|
||||||
*/
|
*/
|
||||||
|
@ -1,223 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2011 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.accessibility;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.os.Message;
|
|
||||||
import android.view.MotionEvent;
|
|
||||||
import android.view.ViewConfiguration;
|
|
||||||
|
|
||||||
import com.android.inputmethod.keyboard.PointerTracker;
|
|
||||||
import com.android.inputmethod.latin.StaticInnerHandlerWrapper;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Detects flick gestures within a stream of hover events.
|
|
||||||
* <p>
|
|
||||||
* A flick gesture is defined as a stream of hover events with the following
|
|
||||||
* properties:
|
|
||||||
* <ul>
|
|
||||||
* <li>Begins with a {@link MotionEvent#ACTION_HOVER_ENTER} event
|
|
||||||
* <li>Contains any number of {@link MotionEvent#ACTION_HOVER_MOVE}
|
|
||||||
* events
|
|
||||||
* <li>Ends with a {@link MotionEvent#ACTION_HOVER_EXIT} event
|
|
||||||
* <li>Maximum duration of 250 milliseconds
|
|
||||||
* <li>Minimum distance between enter and exit points must be at least equal to
|
|
||||||
* scaled double tap slop (see
|
|
||||||
* {@link ViewConfiguration#getScaledDoubleTapSlop()})
|
|
||||||
* </ul>
|
|
||||||
* <p>
|
|
||||||
* Initial enter events are intercepted and cached until the stream fails to
|
|
||||||
* satisfy the constraints defined above, at which point the cached enter event
|
|
||||||
* is sent to its source {@link AccessibleKeyboardViewProxy} and subsequent move
|
|
||||||
* and exit events are ignored.
|
|
||||||
*/
|
|
||||||
public abstract class FlickGestureDetector {
|
|
||||||
public static final int FLICK_UP = 0;
|
|
||||||
public static final int FLICK_RIGHT = 1;
|
|
||||||
public static final int FLICK_LEFT = 2;
|
|
||||||
public static final int FLICK_DOWN = 3;
|
|
||||||
|
|
||||||
private final FlickHandler mFlickHandler;
|
|
||||||
private final int mFlickRadiusSquare;
|
|
||||||
|
|
||||||
private AccessibleKeyboardViewProxy mCachedView;
|
|
||||||
private PointerTracker mCachedTracker;
|
|
||||||
private MotionEvent mCachedHoverEnter;
|
|
||||||
|
|
||||||
private static class FlickHandler extends StaticInnerHandlerWrapper<FlickGestureDetector> {
|
|
||||||
private static final int MSG_FLICK_TIMEOUT = 1;
|
|
||||||
|
|
||||||
/** The maximum duration of a flick gesture in milliseconds. */
|
|
||||||
private static final int DELAY_FLICK_TIMEOUT = 250;
|
|
||||||
|
|
||||||
public FlickHandler(FlickGestureDetector outerInstance) {
|
|
||||||
super(outerInstance);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void handleMessage(Message msg) {
|
|
||||||
final FlickGestureDetector gestureDetector = getOuterInstance();
|
|
||||||
|
|
||||||
switch (msg.what) {
|
|
||||||
case MSG_FLICK_TIMEOUT:
|
|
||||||
gestureDetector.clearFlick(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void startFlickTimeout() {
|
|
||||||
cancelFlickTimeout();
|
|
||||||
sendEmptyMessageDelayed(MSG_FLICK_TIMEOUT, DELAY_FLICK_TIMEOUT);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void cancelFlickTimeout() {
|
|
||||||
removeMessages(MSG_FLICK_TIMEOUT);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a new flick gesture detector.
|
|
||||||
*
|
|
||||||
* @param context The parent context.
|
|
||||||
*/
|
|
||||||
public FlickGestureDetector(Context context) {
|
|
||||||
final int doubleTapSlop = ViewConfiguration.get(context).getScaledDoubleTapSlop();
|
|
||||||
|
|
||||||
mFlickHandler = new FlickHandler(this);
|
|
||||||
mFlickRadiusSquare = doubleTapSlop * doubleTapSlop;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Processes motion events to detect flick gestures.
|
|
||||||
*
|
|
||||||
* @param event The current event.
|
|
||||||
* @param view The source of the event.
|
|
||||||
* @param tracker A pointer tracker for the event.
|
|
||||||
* @return {@code true} if the event was handled.
|
|
||||||
*/
|
|
||||||
public boolean onHoverEvent(MotionEvent event, AccessibleKeyboardViewProxy view,
|
|
||||||
PointerTracker tracker) {
|
|
||||||
// Always cache and consume the first hover event.
|
|
||||||
if (event.getAction() == MotionEvent.ACTION_HOVER_ENTER) {
|
|
||||||
mCachedView = view;
|
|
||||||
mCachedTracker = tracker;
|
|
||||||
mCachedHoverEnter = MotionEvent.obtain(event);
|
|
||||||
mFlickHandler.startFlickTimeout();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Stop if the event has already been canceled.
|
|
||||||
if (mCachedHoverEnter == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
final float distanceSquare = calculateDistanceSquare(mCachedHoverEnter, event);
|
|
||||||
|
|
||||||
switch (event.getAction()) {
|
|
||||||
case MotionEvent.ACTION_HOVER_MOVE:
|
|
||||||
// Consume all valid move events before timeout.
|
|
||||||
return true;
|
|
||||||
case MotionEvent.ACTION_HOVER_EXIT:
|
|
||||||
// Ignore exit events outside the flick radius.
|
|
||||||
if (distanceSquare < mFlickRadiusSquare) {
|
|
||||||
clearFlick(true);
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
return dispatchFlick(mCachedHoverEnter, event);
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Clears the cached flick information and optionally forwards the event to
|
|
||||||
* the source view's internal hover event handler.
|
|
||||||
*
|
|
||||||
* @param sendCachedEvent Set to {@code true} to forward the hover event to
|
|
||||||
* the source view.
|
|
||||||
*/
|
|
||||||
private void clearFlick(boolean sendCachedEvent) {
|
|
||||||
mFlickHandler.cancelFlickTimeout();
|
|
||||||
|
|
||||||
if (mCachedHoverEnter != null) {
|
|
||||||
if (sendCachedEvent) {
|
|
||||||
mCachedView.onHoverEventInternal(mCachedHoverEnter, mCachedTracker);
|
|
||||||
}
|
|
||||||
mCachedHoverEnter.recycle();
|
|
||||||
mCachedHoverEnter = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
mCachedTracker = null;
|
|
||||||
mCachedView = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Computes the direction of a flick gesture and forwards it to
|
|
||||||
* {@link #onFlick(MotionEvent, MotionEvent, int)} for handling.
|
|
||||||
*
|
|
||||||
* @param e1 The {@link MotionEvent#ACTION_HOVER_ENTER} event where the flick started.
|
|
||||||
* @param e2 The {@link MotionEvent#ACTION_HOVER_EXIT} event where the flick ended.
|
|
||||||
* @return {@code true} if the flick event was handled.
|
|
||||||
*/
|
|
||||||
private boolean dispatchFlick(MotionEvent e1, MotionEvent e2) {
|
|
||||||
clearFlick(false);
|
|
||||||
|
|
||||||
final float dX = e2.getX() - e1.getX();
|
|
||||||
final float dY = e2.getY() - e1.getY();
|
|
||||||
final int direction;
|
|
||||||
|
|
||||||
if (dY > dX) {
|
|
||||||
if (dY > -dX) {
|
|
||||||
direction = FLICK_DOWN;
|
|
||||||
} else {
|
|
||||||
direction = FLICK_LEFT;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (dY > -dX) {
|
|
||||||
direction = FLICK_RIGHT;
|
|
||||||
} else {
|
|
||||||
direction = FLICK_UP;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return onFlick(e1, e2, direction);
|
|
||||||
}
|
|
||||||
|
|
||||||
private float calculateDistanceSquare(MotionEvent e1, MotionEvent e2) {
|
|
||||||
final float dX = e2.getX() - e1.getX();
|
|
||||||
final float dY = e2.getY() - e1.getY();
|
|
||||||
return (dX * dX) + (dY * dY);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handles a detected flick gesture.
|
|
||||||
*
|
|
||||||
* @param e1 The {@link MotionEventCompatUtils#ACTION_HOVER_ENTER} event
|
|
||||||
* where the flick started.
|
|
||||||
* @param e2 The {@link MotionEventCompatUtils#ACTION_HOVER_EXIT} event
|
|
||||||
* where the flick ended.
|
|
||||||
* @param direction The direction of the flick event, one of:
|
|
||||||
* <ul>
|
|
||||||
* <li>{@link #FLICK_UP}
|
|
||||||
* <li>{@link #FLICK_DOWN}
|
|
||||||
* <li>{@link #FLICK_LEFT}
|
|
||||||
* <li>{@link #FLICK_RIGHT}
|
|
||||||
* </ul>
|
|
||||||
* @return {@code true} if the flick event was handled.
|
|
||||||
*/
|
|
||||||
public abstract boolean onFlick(MotionEvent e1, MotionEvent e2, int direction);
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user