From 1b5411e5a28e2b88295d7e7da406d5e55db75c3e Mon Sep 17 00:00:00 2001 From: Thomas Nardone Date: Wed, 8 May 2024 10:24:08 -0700 Subject: [PATCH] [skip ci] Add native synchronous event support (#44451) Summary: Changelog: [internal] Exposing the experimental API EventEmitter::experimental_flushSync to trigger synchronous events from Android. The API will be changed in the future, this is exposed only for experimentation. Reviewed By: NickGerleman Differential Revision: D56886402 --- .../fabric/events/EventEmitterWrapper.java | 2 ++ .../jni/react/fabric/EventEmitterWrapper.cpp | 19 +++++++++++++++++++ .../jni/react/fabric/EventEmitterWrapper.h | 1 + 3 files changed, 22 insertions(+) diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/events/EventEmitterWrapper.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/events/EventEmitterWrapper.java index 406e9fd51489ba..491b798118d9ca 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/events/EventEmitterWrapper.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/events/EventEmitterWrapper.java @@ -40,6 +40,8 @@ private EventEmitterWrapper(HybridData hybridData) { private native void dispatchEvent( String eventName, @Nullable NativeMap params, @EventCategoryDef int category); + private native void dispatchEventSynchronously(String eventName, @Nullable NativeMap params); + private native void dispatchUniqueEvent(String eventName, @Nullable NativeMap params); /** diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/fabric/EventEmitterWrapper.cpp b/packages/react-native/ReactAndroid/src/main/jni/react/fabric/EventEmitterWrapper.cpp index e3908c880dff71..3fc99cd80cb38f 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/fabric/EventEmitterWrapper.cpp +++ b/packages/react-native/ReactAndroid/src/main/jni/react/fabric/EventEmitterWrapper.cpp @@ -27,6 +27,22 @@ void EventEmitterWrapper::dispatchEvent( } } +void EventEmitterWrapper::dispatchEventSynchronously( + std::string eventName, + NativeMap* params) { + // It is marginal, but possible for this to be constructed without a valid + // EventEmitter. In those cases, make sure we noop/blackhole events instead of + // crashing. + if (eventEmitter != nullptr) { + eventEmitter->experimental_flushSync([&]() { + eventEmitter->dispatchEvent( + std::move(eventName), + (params != nullptr) ? params->consume() : folly::dynamic::object(), + RawEvent::Category::Discrete); + }); + } +} + void EventEmitterWrapper::dispatchUniqueEvent( std::string eventName, NativeMap* payload) { @@ -44,6 +60,9 @@ void EventEmitterWrapper::registerNatives() { makeNativeMethod("dispatchEvent", EventEmitterWrapper::dispatchEvent), makeNativeMethod( "dispatchUniqueEvent", EventEmitterWrapper::dispatchUniqueEvent), + makeNativeMethod( + "dispatchEventSynchronously", + EventEmitterWrapper::dispatchEventSynchronously), }); } diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/fabric/EventEmitterWrapper.h b/packages/react-native/ReactAndroid/src/main/jni/react/fabric/EventEmitterWrapper.h index 21a8230e524de2..2bc6cc4426d8fc 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/fabric/EventEmitterWrapper.h +++ b/packages/react-native/ReactAndroid/src/main/jni/react/fabric/EventEmitterWrapper.h @@ -28,6 +28,7 @@ class EventEmitterWrapper : public jni::HybridClass { SharedEventEmitter eventEmitter; void dispatchEvent(std::string eventName, NativeMap* params, int category); + void dispatchEventSynchronously(std::string eventName, NativeMap* params); void dispatchUniqueEvent(std::string eventName, NativeMap* params); };