Fix crash when move on the edge of some phones like HUAWEI P9
Summary: The app crashes because of `TouchEventCoalescingKeyHelper.getCoalescingKey` throwing an exception when move on the edge of some phones like HUAWEI P9. It's caused by that the down time differs from `ACTION_DOWN` to `ACTION_MOVE` which belongs to the same gesture when I touched on the edge of my HUAWEI P9. It seems a native bug of manufacturer. Related issue #11302. ``` java.lang.RuntimeException: Tried to get non-existent cookie at com.facebook.react.uimanager.events.TouchEventCoalescingKeyHelper.getCoalescingKey(TouchEventCoalescingKeyHelper.java:75) at com.facebook.react.uimanager.events.TouchEvent.init(TouchEvent.java:93) at com.facebook.react.uimanager.events.TouchEvent.obtain(TouchEvent.java:46) at com.facebook.react.uimanager.JSTouchDispatcher.handleTouchEvent(JSTouchDispatcher.java:118) at com.facebook.react.ReactRootView.dispatchJSTouchEvent(ReactRootView.java:158) at com.facebook.react.ReactRootView.onInterceptTouchEvent(ReactRootView.java:130) at android.view.Vie Closes https://github.com/facebook/react-native/pull/12063 Differential Revision: D4779060 Pulled By: astreet fbshipit-source-id: 5cf20084ff9081f2535ff9cb3b99d1d52c443f03
This commit is contained in:
parent
3b2864404e
commit
d2939eafbf
|
@ -30,6 +30,7 @@ public class JSTouchDispatcher {
|
|||
private int mTargetTag = -1;
|
||||
private final float[] mTargetCoordinates = new float[2];
|
||||
private boolean mChildIsHandlingNativeGesture = false;
|
||||
private long mGestureStartTime = TouchEvent.UNSET;
|
||||
private final ViewGroup mRootViewGroup;
|
||||
private final TouchEventCoalescingKeyHelper mTouchEventCoalescingKeyHelper =
|
||||
new TouchEventCoalescingKeyHelper();
|
||||
|
@ -72,6 +73,7 @@ public class JSTouchDispatcher {
|
|||
// {@link #findTargetTagForTouch} to find react view ID that will be responsible for handling
|
||||
// this gesture
|
||||
mChildIsHandlingNativeGesture = false;
|
||||
mGestureStartTime = ev.getEventTime();
|
||||
mTargetTag = TouchTargetHelper.findTargetTagAndCoordinatesForTouch(
|
||||
ev.getX(),
|
||||
ev.getY(),
|
||||
|
@ -83,6 +85,7 @@ public class JSTouchDispatcher {
|
|||
mTargetTag,
|
||||
TouchEventType.START,
|
||||
ev,
|
||||
mGestureStartTime,
|
||||
mTargetCoordinates[0],
|
||||
mTargetCoordinates[1],
|
||||
mTouchEventCoalescingKeyHelper));
|
||||
|
@ -105,10 +108,12 @@ public class JSTouchDispatcher {
|
|||
mTargetTag,
|
||||
TouchEventType.END,
|
||||
ev,
|
||||
mGestureStartTime,
|
||||
mTargetCoordinates[0],
|
||||
mTargetCoordinates[1],
|
||||
mTouchEventCoalescingKeyHelper));
|
||||
mTargetTag = -1;
|
||||
mGestureStartTime = TouchEvent.UNSET;
|
||||
} else if (action == MotionEvent.ACTION_MOVE) {
|
||||
// Update pointer position for current gesture
|
||||
eventDispatcher.dispatchEvent(
|
||||
|
@ -116,6 +121,7 @@ public class JSTouchDispatcher {
|
|||
mTargetTag,
|
||||
TouchEventType.MOVE,
|
||||
ev,
|
||||
mGestureStartTime,
|
||||
mTargetCoordinates[0],
|
||||
mTargetCoordinates[1],
|
||||
mTouchEventCoalescingKeyHelper));
|
||||
|
@ -126,6 +132,7 @@ public class JSTouchDispatcher {
|
|||
mTargetTag,
|
||||
TouchEventType.START,
|
||||
ev,
|
||||
mGestureStartTime,
|
||||
mTargetCoordinates[0],
|
||||
mTargetCoordinates[1],
|
||||
mTouchEventCoalescingKeyHelper));
|
||||
|
@ -136,6 +143,7 @@ public class JSTouchDispatcher {
|
|||
mTargetTag,
|
||||
TouchEventType.END,
|
||||
ev,
|
||||
mGestureStartTime,
|
||||
mTargetCoordinates[0],
|
||||
mTargetCoordinates[1],
|
||||
mTouchEventCoalescingKeyHelper));
|
||||
|
@ -149,6 +157,7 @@ public class JSTouchDispatcher {
|
|||
);
|
||||
}
|
||||
mTargetTag = -1;
|
||||
mGestureStartTime = TouchEvent.UNSET;
|
||||
} else {
|
||||
FLog.w(
|
||||
ReactConstants.TAG,
|
||||
|
@ -176,6 +185,7 @@ public class JSTouchDispatcher {
|
|||
mTargetTag,
|
||||
TouchEventType.CANCEL,
|
||||
androidEvent,
|
||||
mGestureStartTime,
|
||||
mTargetCoordinates[0],
|
||||
mTargetCoordinates[1],
|
||||
mTouchEventCoalescingKeyHelper));
|
||||
|
|
|
@ -15,6 +15,7 @@ import android.support.v4.util.Pools;
|
|||
import android.view.MotionEvent;
|
||||
|
||||
import com.facebook.infer.annotation.Assertions;
|
||||
import com.facebook.react.bridge.SoftAssertions;
|
||||
|
||||
/**
|
||||
* An event representing the start, end or movement of a touch. Corresponds to a single
|
||||
|
@ -31,10 +32,13 @@ public class TouchEvent extends Event<TouchEvent> {
|
|||
private static final Pools.SynchronizedPool<TouchEvent> EVENTS_POOL =
|
||||
new Pools.SynchronizedPool<>(TOUCH_EVENTS_POOL_SIZE);
|
||||
|
||||
public static final long UNSET = Long.MIN_VALUE;
|
||||
|
||||
public static TouchEvent obtain(
|
||||
int viewTag,
|
||||
TouchEventType touchEventType,
|
||||
MotionEvent motionEventToCopy,
|
||||
long gestureStartTime,
|
||||
float viewX,
|
||||
float viewY,
|
||||
TouchEventCoalescingKeyHelper touchEventCoalescingKeyHelper) {
|
||||
|
@ -46,6 +50,7 @@ public class TouchEvent extends Event<TouchEvent> {
|
|||
viewTag,
|
||||
touchEventType,
|
||||
motionEventToCopy,
|
||||
gestureStartTime,
|
||||
viewX,
|
||||
viewY,
|
||||
touchEventCoalescingKeyHelper);
|
||||
|
@ -67,30 +72,33 @@ public class TouchEvent extends Event<TouchEvent> {
|
|||
int viewTag,
|
||||
TouchEventType touchEventType,
|
||||
MotionEvent motionEventToCopy,
|
||||
long gestureStartTime,
|
||||
float viewX,
|
||||
float viewY,
|
||||
TouchEventCoalescingKeyHelper touchEventCoalescingKeyHelper) {
|
||||
super.init(viewTag);
|
||||
|
||||
SoftAssertions.assertCondition(gestureStartTime != UNSET,
|
||||
"Gesture start time must be initialized");
|
||||
short coalescingKey = 0;
|
||||
int action = (motionEventToCopy.getAction() & MotionEvent.ACTION_MASK);
|
||||
switch (action) {
|
||||
case MotionEvent.ACTION_DOWN:
|
||||
touchEventCoalescingKeyHelper.addCoalescingKey(motionEventToCopy.getDownTime());
|
||||
touchEventCoalescingKeyHelper.addCoalescingKey(gestureStartTime);
|
||||
break;
|
||||
case MotionEvent.ACTION_UP:
|
||||
touchEventCoalescingKeyHelper.removeCoalescingKey(motionEventToCopy.getDownTime());
|
||||
touchEventCoalescingKeyHelper.removeCoalescingKey(gestureStartTime);
|
||||
break;
|
||||
case MotionEvent.ACTION_POINTER_DOWN:
|
||||
case MotionEvent.ACTION_POINTER_UP:
|
||||
touchEventCoalescingKeyHelper.incrementCoalescingKey(motionEventToCopy.getDownTime());
|
||||
touchEventCoalescingKeyHelper.incrementCoalescingKey(gestureStartTime);
|
||||
break;
|
||||
case MotionEvent.ACTION_MOVE:
|
||||
coalescingKey =
|
||||
touchEventCoalescingKeyHelper.getCoalescingKey(motionEventToCopy.getDownTime());
|
||||
touchEventCoalescingKeyHelper.getCoalescingKey(gestureStartTime);
|
||||
break;
|
||||
case MotionEvent.ACTION_CANCEL:
|
||||
touchEventCoalescingKeyHelper.removeCoalescingKey(motionEventToCopy.getDownTime());
|
||||
touchEventCoalescingKeyHelper.removeCoalescingKey(gestureStartTime);
|
||||
break;
|
||||
default:
|
||||
throw new RuntimeException("Unhandled MotionEvent action: " + action);
|
||||
|
|
Loading…
Reference in New Issue