diff options
author | Svetoslav Ganov <svetoslavganov@google.com> | 2012-10-01 16:25:08 -0700 |
---|---|---|
committer | Svetoslav Ganov <svetoslavganov@google.com> | 2012-10-02 12:02:05 -0700 |
commit | 45af84a483165f06c04d74baba67f90da29c6ad2 (patch) | |
tree | b033e50c11473892a162251c0664b847c9a2ee18 /services/java/com/android | |
parent | bfbf6e1232013a999f4776f7fdf7cf6fb577f89b (diff) | |
download | frameworks_base-45af84a483165f06c04d74baba67f90da29c6ad2.zip frameworks_base-45af84a483165f06c04d74baba67f90da29c6ad2.tar.gz frameworks_base-45af84a483165f06c04d74baba67f90da29c6ad2.tar.bz2 |
Touch explorer and magnifier do not work well together.
1. If tocuh exploration and screen magnification are enabled and the screen
is currently magnified, gesture detection does not work well. The reason
is because we are transforming the events if the screen is magnified before
passing them to the touch explorer to compensate for the magnification so
the user can poke what he thinks he pokes. However, when doing gesture
detection/velocity computing this compensating shrinks the gestured shape/
decreases velocity leading to poor gesture reco/incorrect velocity.
This change adds a onRawMotionEvent method in the event transformation chain
which will process the raw touch events. In this method of the touch explorer
we are passing events to the gesture recognized and the velocity tracker.
2. Velocity tracker was not cleared on transitions out of touch exploring state
which is the only one that uses velocity.
bug:7266617
Change-Id: I7887fe5f3c3bb6cfa203b7866a145c7341098a02
Diffstat (limited to 'services/java/com/android')
4 files changed, 64 insertions, 42 deletions
diff --git a/services/java/com/android/server/accessibility/AccessibilityInputFilter.java b/services/java/com/android/server/accessibility/AccessibilityInputFilter.java index f1a03de..eb414fa 100644 --- a/services/java/com/android/server/accessibility/AccessibilityInputFilter.java +++ b/services/java/com/android/server/accessibility/AccessibilityInputFilter.java @@ -119,13 +119,16 @@ class AccessibilityInputFilter extends InputFilter implements EventStreamTransfo mCurrentDeviceId = deviceId; } mPm.userActivity(event.getEventTime(), false); - MotionEvent motionEvent = (MotionEvent) event; - mEventHandler.onMotionEvent(motionEvent, policyFlags); + MotionEvent rawEvent = (MotionEvent) event; + MotionEvent transformedEvent = MotionEvent.obtain(rawEvent); + mEventHandler.onMotionEvent(transformedEvent, rawEvent, policyFlags); + transformedEvent.recycle(); } @Override - public void onMotionEvent(MotionEvent event, int policyFlags) { - sendInputEvent(event, policyFlags); + public void onMotionEvent(MotionEvent transformedEvent, MotionEvent rawEvent, + int policyFlags) { + sendInputEvent(transformedEvent, policyFlags); } @Override diff --git a/services/java/com/android/server/accessibility/EventStreamTransformation.java b/services/java/com/android/server/accessibility/EventStreamTransformation.java index b715570..3289a15 100644 --- a/services/java/com/android/server/accessibility/EventStreamTransformation.java +++ b/services/java/com/android/server/accessibility/EventStreamTransformation.java @@ -57,12 +57,15 @@ import android.view.accessibility.AccessibilityEvent; interface EventStreamTransformation { /** - * Receives a motion event. + * Receives motion event. Passed are the event transformed by previous + * transformations and the raw event to which no transformations have + * been applied. * - * @param event The motion event. + * @param event The transformed motion event. + * @param rawEvent The raw motion event. * @param policyFlags Policy flags for the event. */ - public void onMotionEvent(MotionEvent event, int policyFlags); + public void onMotionEvent(MotionEvent event, MotionEvent rawEvent, int policyFlags); /** * Receives an accessibility event. diff --git a/services/java/com/android/server/accessibility/ScreenMagnifier.java b/services/java/com/android/server/accessibility/ScreenMagnifier.java index b732708..f20eff1 100644 --- a/services/java/com/android/server/accessibility/ScreenMagnifier.java +++ b/services/java/com/android/server/accessibility/ScreenMagnifier.java @@ -203,14 +203,15 @@ public final class ScreenMagnifier implements EventStreamTransformation { } @Override - public void onMotionEvent(MotionEvent event, int policyFlags) { + public void onMotionEvent(MotionEvent event, MotionEvent rawEvent, + int policyFlags) { mMagnifiedContentInteractonStateHandler.onMotionEvent(event); switch (mCurrentState) { case STATE_DELEGATING: { - handleMotionEventStateDelegating(event, policyFlags); + handleMotionEventStateDelegating(event, rawEvent, policyFlags); } break; case STATE_DETECTING: { - mDetectingStateHandler.onMotionEvent(event, policyFlags); + mDetectingStateHandler.onMotionEvent(event, rawEvent, policyFlags); } break; case STATE_VIEWPORT_DRAGGING: { mStateViewportDraggingHandler.onMotionEvent(event, policyFlags); @@ -259,7 +260,8 @@ public final class ScreenMagnifier implements EventStreamTransformation { mScreenStateObserver.destroy(); } - private void handleMotionEventStateDelegating(MotionEvent event, int policyFlags) { + private void handleMotionEventStateDelegating(MotionEvent event, + MotionEvent rawEvent, int policyFlags) { if (event.getActionMasked() == MotionEvent.ACTION_UP) { if (mDetectingStateHandler.mDelayedEventQueue == null) { transitionToState(STATE_DETECTING); @@ -290,7 +292,7 @@ public final class ScreenMagnifier implements EventStreamTransformation { coords, 0, 0, 1.0f, 1.0f, event.getDeviceId(), 0, event.getSource(), event.getFlags()); } - mNext.onMotionEvent(event, policyFlags); + mNext.onMotionEvent(event, rawEvent, policyFlags); } } @@ -533,8 +535,8 @@ public final class ScreenMagnifier implements EventStreamTransformation { } }; - public void onMotionEvent(MotionEvent event, int policyFlags) { - cacheDelayedMotionEvent(event, policyFlags); + public void onMotionEvent(MotionEvent event, MotionEvent rawEvent, int policyFlags) { + cacheDelayedMotionEvent(event, rawEvent, policyFlags); final int action = event.getActionMasked(); switch (action) { case MotionEvent.ACTION_DOWN: { @@ -640,8 +642,10 @@ public final class ScreenMagnifier implements EventStreamTransformation { } } - private void cacheDelayedMotionEvent(MotionEvent event, int policyFlags) { - MotionEventInfo info = MotionEventInfo.obtain(event, policyFlags); + private void cacheDelayedMotionEvent(MotionEvent event, MotionEvent rawEvent, + int policyFlags) { + MotionEventInfo info = MotionEventInfo.obtain(event, rawEvent, + policyFlags); if (mDelayedEventQueue == null) { mDelayedEventQueue = info; } else { @@ -657,7 +661,8 @@ public final class ScreenMagnifier implements EventStreamTransformation { while (mDelayedEventQueue != null) { MotionEventInfo info = mDelayedEventQueue; mDelayedEventQueue = info.mNext; - ScreenMagnifier.this.onMotionEvent(info.mEvent, info.mPolicyFlags); + ScreenMagnifier.this.onMotionEvent(info.mEvent, info.mRawEvent, + info.mPolicyFlags); info.recycle(); } } @@ -738,9 +743,11 @@ public final class ScreenMagnifier implements EventStreamTransformation { private boolean mInPool; public MotionEvent mEvent; + public MotionEvent mRawEvent; public int mPolicyFlags; - public static MotionEventInfo obtain(MotionEvent event, int policyFlags) { + public static MotionEventInfo obtain(MotionEvent event, MotionEvent rawEvent, + int policyFlags) { synchronized (sLock) { MotionEventInfo info; if (sPoolSize > 0) { @@ -752,13 +759,15 @@ public final class ScreenMagnifier implements EventStreamTransformation { } else { info = new MotionEventInfo(); } - info.initialize(event, policyFlags); + info.initialize(event, rawEvent, policyFlags); return info; } } - private void initialize(MotionEvent event, int policyFlags) { + private void initialize(MotionEvent event, MotionEvent rawEvent, + int policyFlags) { mEvent = MotionEvent.obtain(event); + mRawEvent = MotionEvent.obtain(rawEvent); mPolicyFlags = policyFlags; } @@ -780,6 +789,8 @@ public final class ScreenMagnifier implements EventStreamTransformation { private void clear() { mEvent.recycle(); mEvent = null; + mRawEvent.recycle(); + mRawEvent = null; mPolicyFlags = 0; } } diff --git a/services/java/com/android/server/accessibility/TouchExplorer.java b/services/java/com/android/server/accessibility/TouchExplorer.java index 6e57d1f..616bc13 100644 --- a/services/java/com/android/server/accessibility/TouchExplorer.java +++ b/services/java/com/android/server/accessibility/TouchExplorer.java @@ -162,7 +162,7 @@ class TouchExplorer implements EventStreamTransformation { private EventStreamTransformation mNext; // Helper to track gesture velocity. - private VelocityTracker mVelocityTracker; + private final VelocityTracker mVelocityTracker = VelocityTracker.obtain(); // Helper class to track received pointers. private final ReceivedPointerTracker mReceivedPointerTracker; @@ -309,18 +309,18 @@ class TouchExplorer implements EventStreamTransformation { } @Override - public void onMotionEvent(MotionEvent event, int policyFlags) { + public void onMotionEvent(MotionEvent event, MotionEvent rawEvent, int policyFlags) { if (DEBUG) { Slog.d(LOG_TAG, "Received event: " + event + ", policyFlags=0x" + Integer.toHexString(policyFlags)); Slog.d(LOG_TAG, getStateSymbolicName(mCurrentState)); } - mReceivedPointerTracker.onMotionEvent(event); + mReceivedPointerTracker.onMotionEvent(rawEvent); switch(mCurrentState) { case STATE_TOUCH_EXPLORING: { - handleMotionEventStateTouchExploring(event, policyFlags); + handleMotionEventStateTouchExploring(event, rawEvent, policyFlags); } break; case STATE_DRAGGING: { handleMotionEventStateDragging(event, policyFlags); @@ -329,7 +329,7 @@ class TouchExplorer implements EventStreamTransformation { handleMotionEventStateDelegating(event, policyFlags); } break; case STATE_GESTURE_DETECTING: { - handleMotionEventGestureDetecting(event, policyFlags); + handleMotionEventGestureDetecting(rawEvent, policyFlags); } break; default: throw new IllegalStateException("Illegal state: " + mCurrentState); @@ -382,16 +382,15 @@ class TouchExplorer implements EventStreamTransformation { * Handles a motion event in touch exploring state. * * @param event The event to be handled. + * @param rawEvent The raw (unmodified) motion event. * @param policyFlags The policy flags associated with the event. */ - private void handleMotionEventStateTouchExploring(MotionEvent event, int policyFlags) { + private void handleMotionEventStateTouchExploring(MotionEvent event, MotionEvent rawEvent, + int policyFlags) { ReceivedPointerTracker receivedTracker = mReceivedPointerTracker; final int activePointerCount = receivedTracker.getActivePointerCount(); - if (mVelocityTracker == null) { - mVelocityTracker = VelocityTracker.obtain(); - } - mVelocityTracker.addMovement(event); + mVelocityTracker.addMovement(rawEvent); mDoubleTapDetector.onMotionEvent(event, policyFlags); @@ -410,7 +409,7 @@ class TouchExplorer implements EventStreamTransformation { // have a distance slop before getting into gesture detection // mode and not using the points within this slop significantly // decreases the quality of gesture recognition. - handleMotionEventGestureDetecting(event, policyFlags); + handleMotionEventGestureDetecting(rawEvent, policyFlags); //$FALL-THROUGH$ case MotionEvent.ACTION_POINTER_DOWN: { switch (activePointerCount) { @@ -471,12 +470,13 @@ class TouchExplorer implements EventStreamTransformation { // have a distance slop before getting into gesture detection // mode and not using the points within this slop significantly // decreases the quality of gesture recognition. - handleMotionEventGestureDetecting(event, policyFlags); - + handleMotionEventGestureDetecting(rawEvent, policyFlags); + // It is *important* to use the distance traveled by the pointers + // on the screen which may or may not be magnified. final float deltaX = receivedTracker.getReceivedPointerDownX(pointerId) - - event.getX(pointerIndex); + - rawEvent.getX(pointerIndex); final float deltaY = receivedTracker.getReceivedPointerDownY(pointerId) - - event.getY(pointerIndex); + - rawEvent.getY(pointerIndex); final double moveDelta = Math.hypot(deltaX, deltaY); // The user has moved enough for us to decide. if (moveDelta > mDoubleTapSlop) { @@ -491,6 +491,7 @@ class TouchExplorer implements EventStreamTransformation { // We have to perform gesture detection, so // clear the current state and try to detect. mCurrentState = STATE_GESTURE_DETECTING; + mVelocityTracker.clear(); mSendHoverEnterDelayed.remove(); mSendHoverExitDelayed.remove(); mPerformLongPressDelayed.remove(); @@ -535,10 +536,12 @@ class TouchExplorer implements EventStreamTransformation { // If the user is touch exploring the second pointer may be // performing a double tap to activate an item without need // for the user to lift his exploring finger. + // It is *important* to use the distance traveled by the pointers + // on the screen which may or may not be magnified. final float deltaX = receivedTracker.getReceivedPointerDownX(pointerId) - - event.getX(pointerIndex); + - rawEvent.getX(pointerIndex); final float deltaY = receivedTracker.getReceivedPointerDownY(pointerId) - - event.getY(pointerIndex); + - rawEvent.getY(pointerIndex); final double moveDelta = Math.hypot(deltaX, deltaY); if (moveDelta < mDoubleTapSlop) { break; @@ -565,6 +568,7 @@ class TouchExplorer implements EventStreamTransformation { mCurrentState = STATE_DELEGATING; sendDownForAllActiveNotInjectedPointers(event, policyFlags); } + mVelocityTracker.clear(); } break; default: { // More than one pointer so the user is not touch exploring @@ -585,6 +589,7 @@ class TouchExplorer implements EventStreamTransformation { // More than two pointers are delegated to the view hierarchy. mCurrentState = STATE_DELEGATING; sendDownForAllActiveNotInjectedPointers(event, policyFlags); + mVelocityTracker.clear(); } } } break; @@ -615,10 +620,7 @@ class TouchExplorer implements EventStreamTransformation { } } break; } - if (mVelocityTracker != null) { - mVelocityTracker.clear(); - mVelocityTracker = null; - } + mVelocityTracker.clear(); } break; case MotionEvent.ACTION_CANCEL: { clear(event, policyFlags); @@ -1046,7 +1048,10 @@ class TouchExplorer implements EventStreamTransformation { // Make sure that the user will see the event. policyFlags |= WindowManagerPolicy.FLAG_PASS_TO_USER; if (mNext != null) { - mNext.onMotionEvent(event, policyFlags); + // TODO: For now pass null for the raw event since the touch + // explorer is the last event transformation and it does + // not care about the raw event. + mNext.onMotionEvent(event, null, policyFlags); } mInjectedPointerTracker.onMotionEvent(event); |