Merge "Ensure injected gestures respect magnification" into nyc-dev

This commit is contained in:
Svetoslav Ganov
2016-04-13 22:09:17 +00:00
committed by Android (Google) Code Review
3 changed files with 64 additions and 32 deletions

View File

@@ -70,12 +70,22 @@ class AccessibilityInputFilter extends InputFilter implements EventStreamTransfo
static final int FLAG_FEATURE_AUTOCLICK = 0x00000008;
/**
* Flag for enabling motion event injectsion
* Flag for enabling motion event injection.
*
* @see #setUserAndEnabledFeatures(int, int)
*/
static final int FLAG_FEATURE_INJECT_MOTION_EVENTS = 0x00000010;
/**
* Flag for enabling the feature to control the screen magnifier. If
* {@link #FLAG_FEATURE_SCREEN_MAGNIFIER} is set this flag is ignored
* as the screen magnifier feature performs a super set of the work
* performed by this feature.
*
* @see #setUserAndEnabledFeatures(int, int)
*/
static final int FLAG_FEATURE_CONTROL_SCREEN_MAGNIFIER = 0x00000020;
private final Runnable mProcessBatchedEventsRunnable = new Runnable() {
@Override
public void run() {
@@ -373,8 +383,12 @@ class AccessibilityInputFilter extends InputFilter implements EventStreamTransfo
addFirstEventHandler(mTouchExplorer);
}
if ((mEnabledFeatures & FLAG_FEATURE_SCREEN_MAGNIFIER) != 0) {
mMagnificationGestureHandler = new MagnificationGestureHandler(mContext, mAms);
if ((mEnabledFeatures & FLAG_FEATURE_CONTROL_SCREEN_MAGNIFIER) != 0
|| (mEnabledFeatures & FLAG_FEATURE_SCREEN_MAGNIFIER) != 0) {
final boolean detectControlGestures = (mEnabledFeatures
& FLAG_FEATURE_SCREEN_MAGNIFIER) != 0;
mMagnificationGestureHandler = new MagnificationGestureHandler(
mContext, mAms, detectControlGestures);
addFirstEventHandler(mMagnificationGestureHandler);
}

View File

@@ -1311,6 +1311,9 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
if (userState.mIsDisplayMagnificationEnabled) {
flags |= AccessibilityInputFilter.FLAG_FEATURE_SCREEN_MAGNIFIER;
}
if (userHasMagnificationServicesLocked(userState)) {
flags |= AccessibilityInputFilter.FLAG_FEATURE_CONTROL_SCREEN_MAGNIFIER;
}
// Touch exploration without accessibility makes no sense.
if (userState.isHandlingAccessibilityEvents()
&& userState.mIsTouchExplorationEnabled) {

View File

@@ -80,7 +80,6 @@ class MagnificationGestureHandler implements EventStreamTransformation {
private static final boolean DEBUG_STATE_TRANSITIONS = false;
private static final boolean DEBUG_DETECTING = false;
private static final boolean DEBUG_PANNING = false;
private static final boolean DEBUG_SCALING = false;
private static final int STATE_DELEGATING = 1;
private static final int STATE_DETECTING = 2;
@@ -95,6 +94,9 @@ class MagnificationGestureHandler implements EventStreamTransformation {
private final MagnifiedContentInteractionStateHandler mMagnifiedContentInteractionStateHandler;
private final StateViewportDraggingHandler mStateViewportDraggingHandler;
private final boolean mDetectControlGestures;
private EventStreamTransformation mNext;
private int mCurrentState;
@@ -107,12 +109,14 @@ class MagnificationGestureHandler implements EventStreamTransformation {
private long mDelegatingStateDownTime;
public MagnificationGestureHandler(Context context, AccessibilityManagerService ams) {
public MagnificationGestureHandler(Context context, AccessibilityManagerService ams,
boolean detectControlGestures) {
mMagnificationController = ams.getMagnificationController();
mDetectingStateHandler = new DetectingStateHandler(context);
mStateViewportDraggingHandler = new StateViewportDraggingHandler();
mMagnifiedContentInteractionStateHandler =
new MagnifiedContentInteractionStateHandler(context);
mDetectControlGestures = detectControlGestures;
transitionToState(STATE_DETECTING);
}
@@ -125,6 +129,12 @@ class MagnificationGestureHandler implements EventStreamTransformation {
}
return;
}
if (!mDetectControlGestures) {
if (mNext != null) {
dispatchTransformedEvent(event, rawEvent, policyFlags);
}
return;
}
mMagnifiedContentInteractionStateHandler.onMotionEvent(event, rawEvent, policyFlags);
switch (mCurrentState) {
case STATE_DELEGATING: {
@@ -140,7 +150,7 @@ class MagnificationGestureHandler implements EventStreamTransformation {
}
break;
case STATE_MAGNIFIED_INTERACTION: {
// mMagnifiedContentInteractonStateHandler handles events only
// mMagnifiedContentInteractionStateHandler handles events only
// if this is the current state since it uses ScaleGestureDetecotr
// and a GestureDetector which need well formed event stream.
}
@@ -208,31 +218,6 @@ class MagnificationGestureHandler implements EventStreamTransformation {
break;
}
if (mNext != null) {
// If the event is within the magnified portion of the screen we have
// to change its location to be where the user thinks he is poking the
// UI which may have been magnified and panned.
final float eventX = event.getX();
final float eventY = event.getY();
if (mMagnificationController.isMagnifying()
&& mMagnificationController.magnifiedRegionContains(eventX, eventY)) {
final float scale = mMagnificationController.getScale();
final float scaledOffsetX = mMagnificationController.getOffsetX();
final float scaledOffsetY = mMagnificationController.getOffsetY();
final int pointerCount = event.getPointerCount();
PointerCoords[] coords = getTempPointerCoordsWithMinSize(pointerCount);
PointerProperties[] properties = getTempPointerPropertiesWithMinSize(
pointerCount);
for (int i = 0; i < pointerCount; i++) {
event.getPointerCoords(i, coords[i]);
coords[i].x = (coords[i].x - scaledOffsetX) / scale;
coords[i].y = (coords[i].y - scaledOffsetY) / scale;
event.getPointerProperties(i, properties[i]);
}
event = MotionEvent.obtain(event.getDownTime(),
event.getEventTime(), event.getAction(), pointerCount, properties,
coords, 0, 0, 1.0f, 1.0f, event.getDeviceId(), 0, event.getSource(),
event.getFlags());
}
// We cache some events to see if the user wants to trigger magnification.
// If no magnification is triggered we inject these events with adjusted
// time and down time to prevent subsequent transformations being confused
@@ -240,10 +225,40 @@ class MagnificationGestureHandler implements EventStreamTransformation {
// injected we need to also update the down time of all subsequent non cached
// events. All delegated events cached and non-cached are delivered here.
event.setDownTime(mDelegatingStateDownTime);
mNext.onMotionEvent(event, rawEvent, policyFlags);
dispatchTransformedEvent(event, rawEvent, policyFlags);
}
}
private void dispatchTransformedEvent(MotionEvent event, MotionEvent rawEvent,
int policyFlags) {
// If the event is within the magnified portion of the screen we have
// to change its location to be where the user thinks he is poking the
// UI which may have been magnified and panned.
final float eventX = event.getX();
final float eventY = event.getY();
if (mMagnificationController.isMagnifying()
&& mMagnificationController.magnifiedRegionContains(eventX, eventY)) {
final float scale = mMagnificationController.getScale();
final float scaledOffsetX = mMagnificationController.getOffsetX();
final float scaledOffsetY = mMagnificationController.getOffsetY();
final int pointerCount = event.getPointerCount();
PointerCoords[] coords = getTempPointerCoordsWithMinSize(pointerCount);
PointerProperties[] properties = getTempPointerPropertiesWithMinSize(
pointerCount);
for (int i = 0; i < pointerCount; i++) {
event.getPointerCoords(i, coords[i]);
coords[i].x = (coords[i].x - scaledOffsetX) / scale;
coords[i].y = (coords[i].y - scaledOffsetY) / scale;
event.getPointerProperties(i, properties[i]);
}
event = MotionEvent.obtain(event.getDownTime(),
event.getEventTime(), event.getAction(), pointerCount, properties,
coords, 0, 0, 1.0f, 1.0f, event.getDeviceId(), 0, event.getSource(),
event.getFlags());
}
mNext.onMotionEvent(event, rawEvent, policyFlags);
}
private PointerCoords[] getTempPointerCoordsWithMinSize(int size) {
final int oldSize = (mTempPointerCoords != null) ? mTempPointerCoords.length : 0;
if (oldSize < size) {