mirror of
https://github.com/status-im/react-native.git
synced 2025-02-26 16:10:58 +00:00
Fix touch handling crash that can when Modal is displayed as a result of touch handling code
Reviewed By: dmmiller Differential Revision: D3399325 fbshipit-source-id: 0a0bb179ef524bf35cc137d94ea3d5680a68aab2
This commit is contained in:
parent
f3fab5184e
commit
837aafde72
@ -32,6 +32,8 @@ public class JSTouchDispatcher {
|
|||||||
private final float[] mTargetCoordinates = new float[2];
|
private final float[] mTargetCoordinates = new float[2];
|
||||||
private boolean mChildIsHandlingNativeGesture = false;
|
private boolean mChildIsHandlingNativeGesture = false;
|
||||||
private final ViewGroup mRootViewGroup;
|
private final ViewGroup mRootViewGroup;
|
||||||
|
private final TouchEventCoalescingKeyHelper mTouchEventCoalescingKeyHelper =
|
||||||
|
new TouchEventCoalescingKeyHelper();
|
||||||
|
|
||||||
public JSTouchDispatcher(ViewGroup viewGroup) {
|
public JSTouchDispatcher(ViewGroup viewGroup) {
|
||||||
mRootViewGroup = viewGroup;
|
mRootViewGroup = viewGroup;
|
||||||
@ -83,7 +85,8 @@ public class JSTouchDispatcher {
|
|||||||
TouchEventType.START,
|
TouchEventType.START,
|
||||||
ev,
|
ev,
|
||||||
mTargetCoordinates[0],
|
mTargetCoordinates[0],
|
||||||
mTargetCoordinates[1]));
|
mTargetCoordinates[1],
|
||||||
|
mTouchEventCoalescingKeyHelper));
|
||||||
} else if (mChildIsHandlingNativeGesture) {
|
} else if (mChildIsHandlingNativeGesture) {
|
||||||
// If the touch was intercepted by a child, we've already sent a cancel event to JS for this
|
// If the touch was intercepted by a child, we've already sent a cancel event to JS for this
|
||||||
// gesture, so we shouldn't send any more touches related to it.
|
// gesture, so we shouldn't send any more touches related to it.
|
||||||
@ -105,7 +108,8 @@ public class JSTouchDispatcher {
|
|||||||
TouchEventType.END,
|
TouchEventType.END,
|
||||||
ev,
|
ev,
|
||||||
mTargetCoordinates[0],
|
mTargetCoordinates[0],
|
||||||
mTargetCoordinates[1]));
|
mTargetCoordinates[1],
|
||||||
|
mTouchEventCoalescingKeyHelper));
|
||||||
mTargetTag = -1;
|
mTargetTag = -1;
|
||||||
} else if (action == MotionEvent.ACTION_MOVE) {
|
} else if (action == MotionEvent.ACTION_MOVE) {
|
||||||
// Update pointer position for current gesture
|
// Update pointer position for current gesture
|
||||||
@ -116,7 +120,8 @@ public class JSTouchDispatcher {
|
|||||||
TouchEventType.MOVE,
|
TouchEventType.MOVE,
|
||||||
ev,
|
ev,
|
||||||
mTargetCoordinates[0],
|
mTargetCoordinates[0],
|
||||||
mTargetCoordinates[1]));
|
mTargetCoordinates[1],
|
||||||
|
mTouchEventCoalescingKeyHelper));
|
||||||
} else if (action == MotionEvent.ACTION_POINTER_DOWN) {
|
} else if (action == MotionEvent.ACTION_POINTER_DOWN) {
|
||||||
// New pointer goes down, this can only happen after ACTION_DOWN is sent for the first pointer
|
// New pointer goes down, this can only happen after ACTION_DOWN is sent for the first pointer
|
||||||
eventDispatcher.dispatchEvent(
|
eventDispatcher.dispatchEvent(
|
||||||
@ -126,7 +131,8 @@ public class JSTouchDispatcher {
|
|||||||
TouchEventType.START,
|
TouchEventType.START,
|
||||||
ev,
|
ev,
|
||||||
mTargetCoordinates[0],
|
mTargetCoordinates[0],
|
||||||
mTargetCoordinates[1]));
|
mTargetCoordinates[1],
|
||||||
|
mTouchEventCoalescingKeyHelper));
|
||||||
} else if (action == MotionEvent.ACTION_POINTER_UP) {
|
} else if (action == MotionEvent.ACTION_POINTER_UP) {
|
||||||
// Exactly onw of the pointers goes up
|
// Exactly onw of the pointers goes up
|
||||||
eventDispatcher.dispatchEvent(
|
eventDispatcher.dispatchEvent(
|
||||||
@ -136,9 +142,10 @@ public class JSTouchDispatcher {
|
|||||||
TouchEventType.END,
|
TouchEventType.END,
|
||||||
ev,
|
ev,
|
||||||
mTargetCoordinates[0],
|
mTargetCoordinates[0],
|
||||||
mTargetCoordinates[1]));
|
mTargetCoordinates[1],
|
||||||
|
mTouchEventCoalescingKeyHelper));
|
||||||
} else if (action == MotionEvent.ACTION_CANCEL) {
|
} else if (action == MotionEvent.ACTION_CANCEL) {
|
||||||
if (TouchEventCoalescingKeyHelper.hasCoalescingKey(ev.getDownTime())) {
|
if (mTouchEventCoalescingKeyHelper.hasCoalescingKey(ev.getDownTime())) {
|
||||||
dispatchCancelEvent(ev, eventDispatcher);
|
dispatchCancelEvent(ev, eventDispatcher);
|
||||||
} else {
|
} else {
|
||||||
FLog.e(
|
FLog.e(
|
||||||
@ -176,6 +183,7 @@ public class JSTouchDispatcher {
|
|||||||
TouchEventType.CANCEL,
|
TouchEventType.CANCEL,
|
||||||
androidEvent,
|
androidEvent,
|
||||||
mTargetCoordinates[0],
|
mTargetCoordinates[0],
|
||||||
mTargetCoordinates[1]));
|
mTargetCoordinates[1],
|
||||||
|
mTouchEventCoalescingKeyHelper));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -37,12 +37,20 @@ public class TouchEvent extends Event<TouchEvent> {
|
|||||||
TouchEventType touchEventType,
|
TouchEventType touchEventType,
|
||||||
MotionEvent motionEventToCopy,
|
MotionEvent motionEventToCopy,
|
||||||
float viewX,
|
float viewX,
|
||||||
float viewY) {
|
float viewY,
|
||||||
|
TouchEventCoalescingKeyHelper touchEventCoalescingKeyHelper) {
|
||||||
TouchEvent event = EVENTS_POOL.acquire();
|
TouchEvent event = EVENTS_POOL.acquire();
|
||||||
if (event == null) {
|
if (event == null) {
|
||||||
event = new TouchEvent();
|
event = new TouchEvent();
|
||||||
}
|
}
|
||||||
event.init(viewTag, timestampMs, touchEventType, motionEventToCopy, viewX, viewY);
|
event.init(
|
||||||
|
viewTag,
|
||||||
|
timestampMs,
|
||||||
|
touchEventType,
|
||||||
|
motionEventToCopy,
|
||||||
|
viewX,
|
||||||
|
viewY,
|
||||||
|
touchEventCoalescingKeyHelper);
|
||||||
return event;
|
return event;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -63,28 +71,29 @@ public class TouchEvent extends Event<TouchEvent> {
|
|||||||
TouchEventType touchEventType,
|
TouchEventType touchEventType,
|
||||||
MotionEvent motionEventToCopy,
|
MotionEvent motionEventToCopy,
|
||||||
float viewX,
|
float viewX,
|
||||||
float viewY) {
|
float viewY,
|
||||||
|
TouchEventCoalescingKeyHelper touchEventCoalescingKeyHelper) {
|
||||||
super.init(viewTag, timestampMs);
|
super.init(viewTag, timestampMs);
|
||||||
|
|
||||||
short coalescingKey = 0;
|
short coalescingKey = 0;
|
||||||
int action = (motionEventToCopy.getAction() & MotionEvent.ACTION_MASK);
|
int action = (motionEventToCopy.getAction() & MotionEvent.ACTION_MASK);
|
||||||
switch (action) {
|
switch (action) {
|
||||||
case MotionEvent.ACTION_DOWN:
|
case MotionEvent.ACTION_DOWN:
|
||||||
TouchEventCoalescingKeyHelper.addCoalescingKey(motionEventToCopy.getDownTime());
|
touchEventCoalescingKeyHelper.addCoalescingKey(motionEventToCopy.getDownTime());
|
||||||
break;
|
break;
|
||||||
case MotionEvent.ACTION_UP:
|
case MotionEvent.ACTION_UP:
|
||||||
TouchEventCoalescingKeyHelper.removeCoalescingKey(motionEventToCopy.getDownTime());
|
touchEventCoalescingKeyHelper.removeCoalescingKey(motionEventToCopy.getDownTime());
|
||||||
break;
|
break;
|
||||||
case MotionEvent.ACTION_POINTER_DOWN:
|
case MotionEvent.ACTION_POINTER_DOWN:
|
||||||
case MotionEvent.ACTION_POINTER_UP:
|
case MotionEvent.ACTION_POINTER_UP:
|
||||||
TouchEventCoalescingKeyHelper.incrementCoalescingKey(motionEventToCopy.getDownTime());
|
touchEventCoalescingKeyHelper.incrementCoalescingKey(motionEventToCopy.getDownTime());
|
||||||
break;
|
break;
|
||||||
case MotionEvent.ACTION_MOVE:
|
case MotionEvent.ACTION_MOVE:
|
||||||
coalescingKey =
|
coalescingKey =
|
||||||
TouchEventCoalescingKeyHelper.getCoalescingKey(motionEventToCopy.getDownTime());
|
touchEventCoalescingKeyHelper.getCoalescingKey(motionEventToCopy.getDownTime());
|
||||||
break;
|
break;
|
||||||
case MotionEvent.ACTION_CANCEL:
|
case MotionEvent.ACTION_CANCEL:
|
||||||
TouchEventCoalescingKeyHelper.removeCoalescingKey(motionEventToCopy.getDownTime());
|
touchEventCoalescingKeyHelper.removeCoalescingKey(motionEventToCopy.getDownTime());
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new RuntimeException("Unhandled MotionEvent action: " + action);
|
throw new RuntimeException("Unhandled MotionEvent action: " + action);
|
||||||
|
@ -46,31 +46,31 @@ import android.util.SparseIntArray;
|
|||||||
*/
|
*/
|
||||||
public class TouchEventCoalescingKeyHelper {
|
public class TouchEventCoalescingKeyHelper {
|
||||||
|
|
||||||
private static final SparseIntArray sDownTimeToCoalescingKey = new SparseIntArray();
|
private final SparseIntArray mDownTimeToCoalescingKey = new SparseIntArray();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Starts tracking a new coalescing key corresponding to the gesture with this down time.
|
* Starts tracking a new coalescing key corresponding to the gesture with this down time.
|
||||||
*/
|
*/
|
||||||
public static void addCoalescingKey(long downTime) {
|
public void addCoalescingKey(long downTime) {
|
||||||
sDownTimeToCoalescingKey.put((int) downTime, 0);
|
mDownTimeToCoalescingKey.put((int) downTime, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Increments the coalescing key corresponding to the gesture with this down time.
|
* Increments the coalescing key corresponding to the gesture with this down time.
|
||||||
*/
|
*/
|
||||||
public static void incrementCoalescingKey(long downTime) {
|
public void incrementCoalescingKey(long downTime) {
|
||||||
int currentValue = sDownTimeToCoalescingKey.get((int) downTime, -1);
|
int currentValue = mDownTimeToCoalescingKey.get((int) downTime, -1);
|
||||||
if (currentValue == -1) {
|
if (currentValue == -1) {
|
||||||
throw new RuntimeException("Tried to increment non-existent cookie");
|
throw new RuntimeException("Tried to increment non-existent cookie");
|
||||||
}
|
}
|
||||||
sDownTimeToCoalescingKey.put((int) downTime, currentValue + 1);
|
mDownTimeToCoalescingKey.put((int) downTime, currentValue + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the coalescing key corresponding to the gesture with this down time.
|
* Gets the coalescing key corresponding to the gesture with this down time.
|
||||||
*/
|
*/
|
||||||
public static short getCoalescingKey(long downTime) {
|
public short getCoalescingKey(long downTime) {
|
||||||
int currentValue = sDownTimeToCoalescingKey.get((int) downTime, -1);
|
int currentValue = mDownTimeToCoalescingKey.get((int) downTime, -1);
|
||||||
if (currentValue == -1) {
|
if (currentValue == -1) {
|
||||||
throw new RuntimeException("Tried to get non-existent cookie");
|
throw new RuntimeException("Tried to get non-existent cookie");
|
||||||
}
|
}
|
||||||
@ -80,12 +80,12 @@ public class TouchEventCoalescingKeyHelper {
|
|||||||
/**
|
/**
|
||||||
* Stops tracking a new coalescing key corresponding to the gesture with this down time.
|
* Stops tracking a new coalescing key corresponding to the gesture with this down time.
|
||||||
*/
|
*/
|
||||||
public static void removeCoalescingKey(long downTime) {
|
public void removeCoalescingKey(long downTime) {
|
||||||
sDownTimeToCoalescingKey.delete((int) downTime);
|
mDownTimeToCoalescingKey.delete((int) downTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean hasCoalescingKey(long downTime) {
|
public boolean hasCoalescingKey(long downTime) {
|
||||||
int currentValue = sDownTimeToCoalescingKey.get((int) downTime, -1);
|
int currentValue = mDownTimeToCoalescingKey.get((int) downTime, -1);
|
||||||
if (currentValue == -1) {
|
if (currentValue == -1) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user