Merge "Clean up and bug fixes in the TouchExplorer."

This commit is contained in:
Svetoslav Ganov
2011-08-29 11:04:33 -07:00
committed by Android (Google) Code Review

View File

@@ -21,11 +21,8 @@ import static android.view.accessibility.AccessibilityEvent.TYPE_TOUCH_EXPLORATI
import android.content.Context; import android.content.Context;
import android.os.Handler; import android.os.Handler;
import android.os.SystemClock;
import android.util.Slog; import android.util.Slog;
import android.view.MotionEvent; import android.view.MotionEvent;
import android.view.MotionEvent.PointerCoords;
import android.view.MotionEvent.PointerProperties;
import android.view.ViewConfiguration; import android.view.ViewConfiguration;
import android.view.WindowManagerPolicy; import android.view.WindowManagerPolicy;
import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityEvent;
@@ -75,11 +72,6 @@ public class TouchExplorer implements Explorer {
// Invalid pointer ID. // Invalid pointer ID.
private static final int INVALID_POINTER_ID = -1; private static final int INVALID_POINTER_ID = -1;
// The coefficient by which to multiply
// ViewConfiguration.#getScaledTouchExplorationTapSlop()
// to compute #mDraggingDistance.
private static final int COEFFICIENT_DRAGGING_DISTANCE = 2;
// The time slop in milliseconds for activating an item after it has // The time slop in milliseconds for activating an item after it has
// been touch explored. Tapping on an item within this slop will perform // been touch explored. Tapping on an item within this slop will perform
// a click and tapping and holding down a long press. // a click and tapping and holding down a long press.
@@ -95,23 +87,14 @@ public class TouchExplorer implements Explorer {
private static final float MIN_ANGLE_COS = 0.866025404f; // cos(pi/6) private static final float MIN_ANGLE_COS = 0.866025404f; // cos(pi/6)
// The delay for sending a hover enter event. // The delay for sending a hover enter event.
private static final long DELAY_SEND_HOVER_MOVE = 200; private static final long DELAY_SEND_HOVER_ENTER = 200;
// Constant referring to the ids bits of all pointers.
private static final int ALL_POINTER_ID_BITS = 0xFFFFFFFF;
// Temporary array for storing pointer IDs. // Temporary array for storing pointer IDs.
private final int[] mTempPointerIds = new int[MAX_POINTER_COUNT]; private final int[] mTempPointerIds = new int[MAX_POINTER_COUNT];
// Temporary array for storing PointerProperties
private final PointerProperties[] mTempPointerProperties =
PointerProperties.createArray(MAX_POINTER_COUNT);
// Temporary array for storing PointerCoords
private final PointerCoords[] mTempPointerCoords =
PointerCoords.createArray(MAX_POINTER_COUNT);
// The maximal distance between two pointers so they are
// considered to be performing a drag operation.
private final float mDraggingDistance;
// The distance from the last touch explored location tapping within // The distance from the last touch explored location tapping within
// which would perform a click and tapping and holding a long press. // which would perform a click and tapping and holding a long press.
private final int mTouchExplorationTapSlop; private final int mTouchExplorationTapSlop;
@@ -159,7 +142,6 @@ public class TouchExplorer implements Explorer {
mInputFilter = inputFilter; mInputFilter = inputFilter;
mTouchExplorationTapSlop = mTouchExplorationTapSlop =
ViewConfiguration.get(context).getScaledTouchExplorationTapSlop(); ViewConfiguration.get(context).getScaledTouchExplorationTapSlop();
mDraggingDistance = mTouchExplorationTapSlop * COEFFICIENT_DRAGGING_DISTANCE;
mPointerTracker = new PointerTracker(context); mPointerTracker = new PointerTracker(context);
mHandler = new Handler(context.getMainLooper()); mHandler = new Handler(context.getMainLooper());
mSendHoverDelayed = new SendHoverDelayed(); mSendHoverDelayed = new SendHoverDelayed();
@@ -220,18 +202,21 @@ public class TouchExplorer implements Explorer {
+ "touch exploring state!"); + "touch exploring state!");
} }
case 1: { case 1: {
// Send hover if pending. mSendHoverDelayed.remove();
mSendHoverDelayed.forceSendAndRemove();
// Send a hover for every finger down so the user gets feedback. // Send a hover for every finger down so the user gets feedback.
final int pointerId = pointerTracker.getPrimaryActivePointerId(); final int pointerId = pointerTracker.getPrimaryActivePointerId();
final int pointerIdBits = (1 << pointerId); final int pointerIdBits = (1 << pointerId);
final int lastAction = pointerTracker.getLastInjectedHoverAction(); final int lastAction = pointerTracker.getLastInjectedHoverAction();
// If a hover enter for another pointer is delivered we send move.
final int action = (lastAction == MotionEvent.ACTION_HOVER_ENTER) // Deliver hover enter with a delay to have a change to detect
? MotionEvent.ACTION_HOVER_MOVE // whether the user actually starts a scrolling gesture.
: MotionEvent.ACTION_HOVER_ENTER; if (lastAction == MotionEvent.ACTION_HOVER_EXIT) {
mSendHoverDelayed.post(event, action, pointerIdBits, policyFlags, mSendHoverDelayed.post(event, MotionEvent.ACTION_HOVER_ENTER,
DELAY_SEND_HOVER_MOVE); pointerIdBits, policyFlags, DELAY_SEND_HOVER_ENTER);
} else {
sendMotionEvent(event, MotionEvent.ACTION_HOVER_MOVE, pointerIdBits,
policyFlags);
}
if (mLastTouchExploreEvent == null) { if (mLastTouchExploreEvent == null) {
break; break;
@@ -318,12 +303,11 @@ public class TouchExplorer implements Explorer {
} }
} break; } break;
case 2: { case 2: {
mSendHoverDelayed.forceSendAndRemove(); mSendHoverDelayed.remove();
mPerformLongPressDelayed.remove(); mPerformLongPressDelayed.remove();
// We want to no longer hover over the location so subsequent // We want to no longer hover over the location so subsequent
// touch at the same spot will generate a hover enter. // touch at the same spot will generate a hover enter.
sendMotionEvent(event, MotionEvent.ACTION_HOVER_EXIT, pointerIdBits, ensureHoverExitSent(event, pointerIdBits, policyFlags);
policyFlags);
if (isDraggingGesture(event)) { if (isDraggingGesture(event)) {
// Two pointers moving in the same direction within // Two pointers moving in the same direction within
@@ -340,6 +324,7 @@ public class TouchExplorer implements Explorer {
} else { } else {
// Two pointers moving arbitrary are delegated to the view hierarchy. // Two pointers moving arbitrary are delegated to the view hierarchy.
mCurrentState = STATE_DELEGATING; mCurrentState = STATE_DELEGATING;
mSendHoverDelayed.remove();
if (mTouchExploreGestureInProgress) { if (mTouchExploreGestureInProgress) {
sendAccessibilityEvent(TYPE_TOUCH_EXPLORATION_GESTURE_END); sendAccessibilityEvent(TYPE_TOUCH_EXPLORATION_GESTURE_END);
mTouchExploreGestureInProgress = false; mTouchExploreGestureInProgress = false;
@@ -349,12 +334,11 @@ public class TouchExplorer implements Explorer {
} }
} break; } break;
default: { default: {
mSendHoverDelayed.forceSendAndRemove(); mSendHoverDelayed.remove();
mPerformLongPressDelayed.remove(); mPerformLongPressDelayed.remove();
// We want to no longer hover over the location so subsequent // We want to no longer hover over the location so subsequent
// touch at the same spot will generate a hover enter. // touch at the same spot will generate a hover enter.
sendMotionEvent(event, MotionEvent.ACTION_HOVER_EXIT, pointerIdBits, ensureHoverExitSent(event, pointerIdBits, policyFlags);
policyFlags);
// More than two pointers are delegated to the view hierarchy. // More than two pointers are delegated to the view hierarchy.
mCurrentState = STATE_DELEGATING; mCurrentState = STATE_DELEGATING;
@@ -379,8 +363,9 @@ public class TouchExplorer implements Explorer {
break; break;
} }
mSendHoverDelayed.forceSendAndRemove();
mPerformLongPressDelayed.remove(); mPerformLongPressDelayed.remove();
mSendHoverDelayed.forceSendAndRemove();
ensureHoverExitSent(event, pointerIdBits, policyFlags);
// If touch exploring announce the end of the gesture. // If touch exploring announce the end of the gesture.
// Also do not click on the last explored location. // Also do not click on the last explored location.
@@ -388,11 +373,6 @@ public class TouchExplorer implements Explorer {
mTouchExploreGestureInProgress = false; mTouchExploreGestureInProgress = false;
mLastTouchExploreEvent = MotionEvent.obtain(event); mLastTouchExploreEvent = MotionEvent.obtain(event);
sendAccessibilityEvent(TYPE_TOUCH_EXPLORATION_GESTURE_END); sendAccessibilityEvent(TYPE_TOUCH_EXPLORATION_GESTURE_END);
final int lastAction = mPointerTracker.getLastInjectedHoverAction();
if (lastAction != MotionEvent.ACTION_HOVER_EXIT) {
sendMotionEvent(event, MotionEvent.ACTION_HOVER_EXIT,
pointerIdBits, policyFlags);
}
break; break;
} }
@@ -404,11 +384,6 @@ public class TouchExplorer implements Explorer {
final long exploreTime = mLastTouchExploreEvent.getEventTime(); final long exploreTime = mLastTouchExploreEvent.getEventTime();
final long deltaTime = eventTime - exploreTime; final long deltaTime = eventTime - exploreTime;
if (deltaTime > ACTIVATION_TIME_SLOP) { if (deltaTime > ACTIVATION_TIME_SLOP) {
final int lastAction = mPointerTracker.getLastInjectedHoverAction();
if (lastAction != MotionEvent.ACTION_HOVER_EXIT) {
sendMotionEvent(event, MotionEvent.ACTION_HOVER_EXIT,
pointerIdBits, policyFlags);
}
mLastTouchExploreEvent = MotionEvent.obtain(event); mLastTouchExploreEvent = MotionEvent.obtain(event);
break; break;
} }
@@ -421,11 +396,6 @@ public class TouchExplorer implements Explorer {
- event.getY(pointerIndex); - event.getY(pointerIndex);
final float deltaMove = (float) Math.hypot(deltaX, deltaY); final float deltaMove = (float) Math.hypot(deltaX, deltaY);
if (deltaMove > mTouchExplorationTapSlop) { if (deltaMove > mTouchExplorationTapSlop) {
final int lastAction = mPointerTracker.getLastInjectedHoverAction();
if (lastAction != MotionEvent.ACTION_HOVER_EXIT) {
sendMotionEvent(event, MotionEvent.ACTION_HOVER_EXIT,
pointerIdBits, policyFlags);
}
mLastTouchExploreEvent = MotionEvent.obtain(event); mLastTouchExploreEvent = MotionEvent.obtain(event);
break; break;
} }
@@ -434,12 +404,6 @@ public class TouchExplorer implements Explorer {
sendActionDownAndUp(mLastTouchExploreEvent, policyFlags); sendActionDownAndUp(mLastTouchExploreEvent, policyFlags);
mLastTouchExploreEvent = null; mLastTouchExploreEvent = null;
} else { } else {
mSendHoverDelayed.forceSendAndRemove();
final int lastAction = mPointerTracker.getLastInjectedHoverAction();
if (lastAction != MotionEvent.ACTION_HOVER_EXIT) {
sendMotionEvent(event, MotionEvent.ACTION_HOVER_EXIT,
pointerIdBits, policyFlags);
}
mLastTouchExploreEvent = MotionEvent.obtain(event); mLastTouchExploreEvent = MotionEvent.obtain(event);
} }
} break; } break;
@@ -448,13 +412,9 @@ public class TouchExplorer implements Explorer {
case MotionEvent.ACTION_CANCEL: { case MotionEvent.ACTION_CANCEL: {
mSendHoverDelayed.remove(); mSendHoverDelayed.remove();
mPerformLongPressDelayed.remove(); mPerformLongPressDelayed.remove();
final int lastAction = pointerTracker.getLastInjectedHoverAction(); final int pointerId = pointerTracker.getPrimaryActivePointerId();
if (lastAction != MotionEvent.ACTION_HOVER_EXIT) { final int pointerIdBits = (1 << pointerId);
final int pointerId = pointerTracker.getPrimaryActivePointerId(); ensureHoverExitSent(event, pointerIdBits, policyFlags);
final int pointerIdBits = (1 << pointerId);
sendMotionEvent(event, MotionEvent.ACTION_HOVER_EXIT, pointerIdBits,
policyFlags);
}
clear(); clear();
} break; } break;
} }
@@ -540,7 +500,8 @@ public class TouchExplorer implements Explorer {
// a given distance and if such exist send them to the view hierarchy // a given distance and if such exist send them to the view hierarchy
final int notInjectedCount = mPointerTracker.getNotInjectedActivePointerCount(); final int notInjectedCount = mPointerTracker.getNotInjectedActivePointerCount();
if (notInjectedCount > 0) { if (notInjectedCount > 0) {
sendDownForAllActiveNotInjectedPointers(event, policyFlags); MotionEvent prototype = MotionEvent.obtain(event);
sendDownForAllActiveNotInjectedPointers(prototype, policyFlags);
} }
} break; } break;
case MotionEvent.ACTION_POINTER_UP: { case MotionEvent.ACTION_POINTER_UP: {
@@ -565,42 +526,47 @@ public class TouchExplorer implements Explorer {
* @param policyFlags The policy flags associated with the event. * @param policyFlags The policy flags associated with the event.
*/ */
private void sendDownForAllActiveNotInjectedPointers(MotionEvent prototype, int policyFlags) { private void sendDownForAllActiveNotInjectedPointers(MotionEvent prototype, int policyFlags) {
final PointerProperties[] pointerProperties = mTempPointerProperties;
final PointerCoords[] pointerCoords = mTempPointerCoords;
final PointerTracker pointerTracker = mPointerTracker; final PointerTracker pointerTracker = mPointerTracker;
int pointerDataIndex = 0; int pointerIdBits = 0;
final int pointerCount = prototype.getPointerCount();
final int pinterCount = prototype.getPointerCount(); // Find which pointers are already injected.
for (int i = 0; i < pinterCount; i++) { for (int i = 0; i < pointerCount; i++) {
final int pointerId = prototype.getPointerId(i); final int pointerId = prototype.getPointerId(i);
if (pointerTracker.isInjectedPointerDown(pointerId)) {
pointerIdBits |= (1 << pointerId);
}
}
// Inject the active and not injected pointers.
for (int i = 0; i < pointerCount; i++) {
final int pointerId = prototype.getPointerId(i);
// Skip inactive pointers. // Skip inactive pointers.
if (!pointerTracker.isActivePointer(pointerId)) { if (!pointerTracker.isActivePointer(pointerId)) {
continue; continue;
} }
// Skip already delivered pointers. // Do not send event for already delivered pointers.
if (pointerTracker.isInjectedPointerDown(pointerId)) { if (pointerTracker.isInjectedPointerDown(pointerId)) {
continue; continue;
} }
pointerIdBits |= (1 << pointerId);
final int action = computeInjectionAction(MotionEvent.ACTION_DOWN, i);
sendMotionEvent(prototype, action, pointerIdBits, policyFlags);
}
}
// Populate and inject an event for the current pointer. /**
prototype.getPointerProperties(i, pointerProperties[pointerDataIndex]); * Ensures that hover exit has been sent.
prototype.getPointerCoords(i, pointerCoords[pointerDataIndex]); *
* @param prototype The prototype from which to create the injected events.
final long downTime = pointerTracker.getLastInjectedDownEventTime(); * @param pointerIdBits The bits of the pointers to send.
final int action = computeInjectionAction(MotionEvent.ACTION_DOWN, pointerDataIndex); * @param policyFlags The policy flags associated with the event.
final int pointerCount = pointerDataIndex + 1; */
final long eventTime = SystemClock.uptimeMillis(); private void ensureHoverExitSent(MotionEvent prototype, int pointerIdBits, int policyFlags) {
final int lastAction = mPointerTracker.getLastInjectedHoverAction();
MotionEvent event = MotionEvent.obtain(downTime, eventTime, if (lastAction != MotionEvent.ACTION_HOVER_EXIT) {
action, pointerCount, pointerProperties, pointerCoords, sendMotionEvent(prototype, MotionEvent.ACTION_HOVER_EXIT, pointerIdBits,
prototype.getMetaState(), prototype.getButtonState(), policyFlags);
prototype.getXPrecision(), prototype.getYPrecision(), prototype.getDeviceId(),
prototype.getEdgeFlags(), prototype.getSource(), prototype.getFlags());
sendMotionEvent(event, policyFlags);
event.recycle();
pointerDataIndex++;
} }
} }
@@ -613,38 +579,17 @@ public class TouchExplorer implements Explorer {
*/ */
private void sendUpForInjectedDownPointers(MotionEvent prototype, int policyFlags) { private void sendUpForInjectedDownPointers(MotionEvent prototype, int policyFlags) {
final PointerTracker pointerTracker = mPointerTracker; final PointerTracker pointerTracker = mPointerTracker;
final PointerProperties[] pointerProperties = mTempPointerProperties; int pointerIdBits = 0;
final PointerCoords[] pointerCoords = mTempPointerCoords; final int pointerCount = prototype.getPointerCount();
int pointerDataIndex = 0;
final int pointerCount = prototype.getPointerCount();
for (int i = 0; i < pointerCount; i++) { for (int i = 0; i < pointerCount; i++) {
final int pointerId = prototype.getPointerId(i); final int pointerId = prototype.getPointerId(i);
// Skip non injected down pointers. // Skip non injected down pointers.
if (!pointerTracker.isInjectedPointerDown(pointerId)) { if (!pointerTracker.isInjectedPointerDown(pointerId)) {
continue; continue;
} }
pointerIdBits |= (1 << pointerId);
// Populate and inject event. final int action = computeInjectionAction(MotionEvent.ACTION_UP, i);
prototype.getPointerProperties(i, pointerProperties[pointerDataIndex]); sendMotionEvent(prototype, action, pointerIdBits, policyFlags);
prototype.getPointerCoords(i, pointerCoords[pointerDataIndex]);
final long downTime = pointerTracker.getLastInjectedDownEventTime();
final int action = computeInjectionAction(MotionEvent.ACTION_UP, pointerDataIndex);
final int newPointerCount = pointerDataIndex + 1;
final long eventTime = SystemClock.uptimeMillis();
MotionEvent event = MotionEvent.obtain(downTime, eventTime, action,
newPointerCount, pointerProperties, pointerCoords,
prototype.getMetaState(), prototype.getButtonState(),
prototype.getXPrecision(), prototype.getYPrecision(), prototype.getDeviceId(),
prototype.getEdgeFlags(), prototype.getSource(), prototype.getFlags());
sendMotionEvent(event, policyFlags);
event.recycle();
pointerDataIndex++;
} }
} }
@@ -659,7 +604,7 @@ public class TouchExplorer implements Explorer {
// All pointers active therefore we just inject the event as is. // All pointers active therefore we just inject the event as is.
if (prototype.getPointerCount() == pointerTracker.getActivePointerCount()) { if (prototype.getPointerCount() == pointerTracker.getActivePointerCount()) {
sendMotionEvent(prototype, policyFlags); sendMotionEvent(prototype, prototype.getAction(), ALL_POINTER_ID_BITS, policyFlags);
return; return;
} }
@@ -670,20 +615,27 @@ public class TouchExplorer implements Explorer {
return; return;
} }
// If the action pointer going up/down is not active we have nothing to do.
// However, for moves we keep going to report moves of active pointers.
final int actionMasked = prototype.getActionMasked();
final int actionPointerId = prototype.getPointerId(prototype.getActionIndex());
if (actionMasked != MotionEvent.ACTION_MOVE) {
if (!pointerTracker.isActiveOrWasLastActiveUpPointer(actionPointerId)) {
return;
}
}
// If the pointer is active or the pointer that just went up
// was active we keep the pointer data in the event.
int pointerIdBits = 0; int pointerIdBits = 0;
final int pointerCount = prototype.getPointerCount(); final int pointerCount = prototype.getPointerCount();
for (int pointerIndex = 0; pointerIndex < pointerCount; pointerIndex++) { for (int pointerIndex = 0; pointerIndex < pointerCount; pointerIndex++) {
final int pointerId = prototype.getPointerId(pointerIndex); final int pointerId = prototype.getPointerId(pointerIndex);
// If the pointer is inactive or the pointer that just went up
// was inactive we strip the pointer data from the event.
if (pointerTracker.isActiveOrWasLastActiveUpPointer(pointerId)) { if (pointerTracker.isActiveOrWasLastActiveUpPointer(pointerId)) {
pointerIdBits |= (1 << pointerId); pointerIdBits |= (1 << pointerId);
} }
} }
sendMotionEvent(prototype, prototype.getAction(), pointerIdBits, policyFlags);
MotionEvent event = prototype.split(pointerIdBits);
sendMotionEvent(event, policyFlags);
event.recycle();
} }
/** /**
@@ -693,26 +645,11 @@ public class TouchExplorer implements Explorer {
* @param policyFlags The policy flags associated with the event. * @param policyFlags The policy flags associated with the event.
*/ */
private void sendActionDownAndUp(MotionEvent prototype, int policyFlags) { private void sendActionDownAndUp(MotionEvent prototype, int policyFlags) {
final PointerProperties[] pointerProperties = mTempPointerProperties; // Tap with the pointer that last went up - we may have inactive pointers.
final PointerCoords[] pointerCoords = mTempPointerCoords; final int pointerId = mPointerTracker.getLastReceivedUpPointerId();
final int pointerIndex = prototype.getActionIndex(); final int pointerIdBits = (1 << pointerId);
sendMotionEvent(prototype, MotionEvent.ACTION_DOWN, pointerIdBits, policyFlags);
// Send down. sendMotionEvent(prototype, MotionEvent.ACTION_UP, pointerIdBits, policyFlags);
prototype.getPointerProperties(pointerIndex, pointerProperties[0]);
prototype.getPointerCoords(pointerIndex, pointerCoords[0]);
final long downTime = SystemClock.uptimeMillis();
MotionEvent event = MotionEvent.obtain(downTime, downTime, MotionEvent.ACTION_DOWN,
1, pointerProperties, pointerCoords,
prototype.getMetaState(), prototype.getButtonState(),
prototype.getXPrecision(), prototype.getYPrecision(), prototype.getDeviceId(),
prototype.getEdgeFlags(), prototype.getSource(), prototype.getFlags());
sendMotionEvent(event, policyFlags);
// Send up.
event.setAction(MotionEvent.ACTION_UP);
sendMotionEvent(event, policyFlags);
event.recycle();
} }
/** /**
@@ -725,11 +662,33 @@ public class TouchExplorer implements Explorer {
*/ */
private void sendMotionEvent(MotionEvent prototype, int action, int pointerIdBits, private void sendMotionEvent(MotionEvent prototype, int action, int pointerIdBits,
int policyFlags) { int policyFlags) {
MotionEvent event = prototype.split(pointerIdBits); prototype.setAction(action);
event.setDownTime(mPointerTracker.getLastInjectedDownEventTime());
event.setAction(action); MotionEvent event = null;
sendMotionEvent(event, policyFlags); if (pointerIdBits == ALL_POINTER_ID_BITS) {
event.recycle(); event = prototype;
} else {
event = prototype.split(pointerIdBits);
}
if (action == MotionEvent.ACTION_DOWN) {
event.setDownTime(event.getEventTime());
} else {
event.setDownTime(mPointerTracker.getLastInjectedDownEventTime());
}
if (DEBUG) {
Slog.d(LOG_TAG_INJECTED, "Injecting event: " + event + ", policyFlags=0x"
+ Integer.toHexString(policyFlags));
}
// Make sure that the user will see the event.
policyFlags |= WindowManagerPolicy.FLAG_PASS_TO_USER;
mPointerTracker.onInjectedMotionEvent(event);
mInputFilter.sendInputEvent(event, policyFlags);
if (event != prototype) {
event.recycle();
}
} }
/** /**
@@ -787,19 +746,16 @@ public class TouchExplorer implements Explorer {
final float secondPtrX = event.getX(secondPtrIndex); final float secondPtrX = event.getX(secondPtrIndex);
final float secondPtrY = event.getY(secondPtrIndex); final float secondPtrY = event.getY(secondPtrIndex);
// Check if the pointers are close enough.
final float deltaX = firstPtrX - secondPtrX;
final float deltaY = firstPtrY - secondPtrY;
final float deltaMove = (float) Math.hypot(deltaX, deltaY);
if (deltaMove > mDraggingDistance) {
return false;
}
// Check if the pointers are moving in the same direction. // Check if the pointers are moving in the same direction.
final float firstDeltaX = final float firstDeltaX =
firstPtrX - pointerTracker.getReceivedPointerDownX(firstPtrIndex); firstPtrX - pointerTracker.getReceivedPointerDownX(firstPtrIndex);
final float firstDeltaY = final float firstDeltaY =
firstPtrY - pointerTracker.getReceivedPointerDownY(firstPtrIndex); firstPtrY - pointerTracker.getReceivedPointerDownY(firstPtrIndex);
if (firstDeltaX == 0 && firstDeltaY == 0) {
return true;
}
final float firstMagnitude = final float firstMagnitude =
(float) Math.sqrt(firstDeltaX * firstDeltaX + firstDeltaY * firstDeltaY); (float) Math.sqrt(firstDeltaX * firstDeltaX + firstDeltaY * firstDeltaY);
final float firstXNormalized = final float firstXNormalized =
@@ -811,6 +767,11 @@ public class TouchExplorer implements Explorer {
secondPtrX - pointerTracker.getReceivedPointerDownX(secondPtrIndex); secondPtrX - pointerTracker.getReceivedPointerDownX(secondPtrIndex);
final float secondDeltaY = final float secondDeltaY =
secondPtrY - pointerTracker.getReceivedPointerDownY(secondPtrIndex); secondPtrY - pointerTracker.getReceivedPointerDownY(secondPtrIndex);
if (secondDeltaX == 0 && secondDeltaY == 0) {
return true;
}
final float secondMagnitude = final float secondMagnitude =
(float) Math.sqrt(secondDeltaX * secondDeltaX + secondDeltaY * secondDeltaY); (float) Math.sqrt(secondDeltaX * secondDeltaX + secondDeltaY * secondDeltaY);
final float secondXNormalized = final float secondXNormalized =
@@ -838,23 +799,6 @@ public class TouchExplorer implements Explorer {
mAccessibilityManager.sendAccessibilityEvent(event); mAccessibilityManager.sendAccessibilityEvent(event);
} }
/**
* Sends a motion event to the input filter for injection.
*
* @param event The event to send.
* @param policyFlags The policy flags associated with the event.
*/
private void sendMotionEvent(MotionEvent event, int policyFlags) {
if (DEBUG) {
Slog.d(LOG_TAG_INJECTED, "Injecting event: " + event + ", policyFlags=0x"
+ Integer.toHexString(policyFlags));
}
// Make sure that the user will see the event.
policyFlags |= WindowManagerPolicy.FLAG_PASS_TO_USER;
mPointerTracker.onInjectedMotionEvent(event);
mInputFilter.sendInputEvent(event, policyFlags);
}
/** /**
* Clears the internal state of this explorer. * Clears the internal state of this explorer.
*/ */
@@ -1013,6 +957,7 @@ public class TouchExplorer implements Explorer {
switch (action) { switch (action) {
case MotionEvent.ACTION_DOWN: { case MotionEvent.ACTION_DOWN: {
handleInjectedPointerDown(event.getActionIndex(), event); handleInjectedPointerDown(event.getActionIndex(), event);
mLastInjectedDownEventTime = event.getDownTime();
} break; } break;
case MotionEvent.ACTION_POINTER_DOWN: { case MotionEvent.ACTION_POINTER_DOWN: {
handleInjectedPointerDown(event.getActionIndex(), event); handleInjectedPointerDown(event.getActionIndex(), event);
@@ -1270,7 +1215,6 @@ public class TouchExplorer implements Explorer {
final int pointerId = event.getPointerId(pointerIndex); final int pointerId = event.getPointerId(pointerIndex);
final int pointerFlag = (1 << pointerId); final int pointerFlag = (1 << pointerId);
mInjectedPointersDown |= pointerFlag; mInjectedPointersDown |= pointerFlag;
mLastInjectedDownEventTime = event.getEventTime();
} }
/** /**
@@ -1406,7 +1350,11 @@ public class TouchExplorer implements Explorer {
public void run() { public void run() {
mCurrentState = STATE_DELEGATING; mCurrentState = STATE_DELEGATING;
// Make sure the scheduled hover exit is delivered. // Make sure the scheduled hover exit is delivered.
mSendHoverDelayed.forceSendAndRemove(); mSendHoverDelayed.remove();
final int pointerId = mPointerTracker.getPrimaryActivePointerId();
final int pointerIdBits = (1 << pointerId);
ensureHoverExitSent(mEvent, pointerIdBits, mPolicyFlags);
sendDownForAllActiveNotInjectedPointers(mEvent, mPolicyFlags); sendDownForAllActiveNotInjectedPointers(mEvent, mPolicyFlags);
mTouchExploreGestureInProgress = false; mTouchExploreGestureInProgress = false;
mLastTouchExploreEvent = null; mLastTouchExploreEvent = null;