summaryrefslogtreecommitdiffstats
path: root/services/java/com/android
diff options
context:
space:
mode:
authorSvetoslav Ganov <svetoslavganov@google.com>2012-10-01 16:25:08 -0700
committerSvetoslav Ganov <svetoslavganov@google.com>2012-10-02 12:02:05 -0700
commit45af84a483165f06c04d74baba67f90da29c6ad2 (patch)
treeb033e50c11473892a162251c0664b847c9a2ee18 /services/java/com/android
parentbfbf6e1232013a999f4776f7fdf7cf6fb577f89b (diff)
downloadframeworks_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')
-rw-r--r--services/java/com/android/server/accessibility/AccessibilityInputFilter.java11
-rw-r--r--services/java/com/android/server/accessibility/EventStreamTransformation.java9
-rw-r--r--services/java/com/android/server/accessibility/ScreenMagnifier.java37
-rw-r--r--services/java/com/android/server/accessibility/TouchExplorer.java49
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);