From deb6fbd92911282e9b2a1313ccfce5e2a3e921be Mon Sep 17 00:00:00 2001 From: Andrei Shikov Date: Wed, 3 Nov 2021 12:07:16 -0700 Subject: [PATCH] Check for double dispose when sending touch event Summary: Makes new touch processing path check for double dispose on touch events. Old event dispatcher has a race condition which makes it double-dispose some events, so we need to make sure it also processes touches correctly. Changelog: [Internal] Check for double dispose when sending touch event Reviewed By: cortinico Differential Revision: D32110250 fbshipit-source-id: d6a12cbac60f9ff5e836cfaca5a47c467bea06c7 --- .../react/uimanager/events/TouchEvent.java | 29 +++++++++++-------- 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/TouchEvent.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/TouchEvent.java index eb8b7a78a7e..f9d6661684d 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/TouchEvent.java +++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/TouchEvent.java @@ -182,21 +182,17 @@ public class TouchEvent extends Event { @Override public void dispatch(RCTEventEmitter rctEventEmitter) { - if (!hasMotionEvent()) { - ReactSoftExceptionLogger.logSoftException( - TAG, - new IllegalStateException( - "Cannot dispatch a TouchEvent that has no MotionEvent; the TouchEvent has been recycled")); - return; + if (verifyMotionEvent()) { + TouchesHelper.sendTouchEvent(rctEventEmitter, this); } - - TouchesHelper.sendTouchEvent(rctEventEmitter, this); } @Override public void dispatchModern(RCTModernEventEmitter rctEventEmitter) { if (ReactFeatureFlags.useUpdatedTouchPreprocessing) { - TouchesHelper.sendTouchEventModern(rctEventEmitter, this, /* useDispatchV2 */ false); + if (verifyMotionEvent()) { + TouchesHelper.sendTouchEventModern(rctEventEmitter, this, /* useDispatchV2 */ false); + } } else { dispatch(rctEventEmitter); } @@ -205,7 +201,9 @@ public class TouchEvent extends Event { @Override public void dispatchModernV2(RCTModernEventEmitter rctEventEmitter) { if (ReactFeatureFlags.useUpdatedTouchPreprocessing) { - TouchesHelper.sendTouchEventModern(rctEventEmitter, this, /* useDispatchV2 */ true); + if (verifyMotionEvent()) { + TouchesHelper.sendTouchEventModern(rctEventEmitter, this, /* useDispatchV2 */ true); + } } else { dispatch(rctEventEmitter); } @@ -237,8 +235,15 @@ public class TouchEvent extends Event { return mMotionEvent; } - private boolean hasMotionEvent() { - return mMotionEvent != null; + private boolean verifyMotionEvent() { + if (mMotionEvent == null) { + ReactSoftExceptionLogger.logSoftException( + TAG, + new IllegalStateException( + "Cannot dispatch a TouchEvent that has no MotionEvent; the TouchEvent has been recycled")); + return false; + } + return true; } public TouchEventType getTouchEventType() {