From e6b6ee4b2c6729022f845a1d991ba75a3615ad65 Mon Sep 17 00:00:00 2001 From: Pieter De Baets Date: Tue, 7 Jan 2025 02:44:09 -0800 Subject: [PATCH 1/2] Remove getInspectorDataForInstance (#48335) Summary: This API was never adopted or implemented on iOS, and is not compatible with bridgeless. Changelog: [Internal] Reviewed By: rshest Differential Revision: D67342500 --- .../ReactAndroid/api/ReactAndroid.api | 1 - .../react/fabric/FabricUIManager.java | 23 -------------- .../react/fabric/FabricUIManagerBinding.kt | 6 ---- .../react/fabric/FabricUIManagerBinding.cpp | 30 ------------------ .../jni/react/fabric/FabricUIManagerBinding.h | 3 -- .../react/renderer/scheduler/Scheduler.cpp | 31 ------------------- .../react/renderer/scheduler/Scheduler.h | 3 -- .../renderer/uimanager/UIManagerBinding.cpp | 27 ---------------- .../renderer/uimanager/UIManagerBinding.h | 4 --- 9 files changed, 128 deletions(-) diff --git a/packages/react-native/ReactAndroid/api/ReactAndroid.api b/packages/react-native/ReactAndroid/api/ReactAndroid.api index 9b6071876fc8f3..50e7afc678c468 100644 --- a/packages/react-native/ReactAndroid/api/ReactAndroid.api +++ b/packages/react-native/ReactAndroid/api/ReactAndroid.api @@ -2595,7 +2595,6 @@ public class com/facebook/react/fabric/FabricUIManager : com/facebook/react/brid public fun dispatchCommand (ILjava/lang/String;Lcom/facebook/react/bridge/ReadableArray;)V public fun getColor (I[Ljava/lang/String;)I public fun getEventDispatcher ()Lcom/facebook/react/uimanager/events/EventDispatcher; - public fun getInspectorDataForInstance (ILandroid/view/View;)Lcom/facebook/react/bridge/ReadableMap; public fun getPerformanceCounters ()Ljava/util/Map; public fun getThemeData (I[F)Z public fun initialize ()V diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java index 4085705499cae7..803b9441e347e1 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java @@ -257,29 +257,6 @@ public int addRootView(final T rootView, final WritableMap init return rootTag; } - /** - * This API returns metadata associated to the React Component that rendered the Android View - * received as a parameter. - * - * @param surfaceId {@link int} that represents the surfaceId for the View received as a - * parameter. In practice surfaceId can be retrieved calling the {@link View#getId()} method - * on the {@link ReactRoot} that holds the View received as a second parameter. - * @param view {@link View} view that will be used to retrieve the React view hierarchy metadata. - * @return a {@link ReadableMap} that contains metadata associated to the React Component that - * rendered the Android View received as a parameter. For more details about the keys stored - * in the {@link ReadableMap} refer to the "getInspectorDataForInstance" method from - * jni/react/fabric/Binding.cpp file. - */ - @UiThread - @ThreadConfined(UI) - public ReadableMap getInspectorDataForInstance(final int surfaceId, final View view) { - UiThreadUtil.assertOnUiThread(); - int reactTag = view.getId(); - - EventEmitterWrapper eventEmitter = mMountingManager.getEventEmitter(surfaceId, reactTag); - return mBinding.getInspectorDataForInstance(eventEmitter); - } - @Override @AnyThread @ThreadConfined(ANY) diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManagerBinding.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManagerBinding.kt index 1607d1bda33a66..38ce98527e3995 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManagerBinding.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManagerBinding.kt @@ -11,12 +11,10 @@ import android.annotation.SuppressLint import com.facebook.jni.HybridClassBase import com.facebook.proguard.annotations.DoNotStrip import com.facebook.react.bridge.NativeMap -import com.facebook.react.bridge.ReadableNativeMap import com.facebook.react.bridge.RuntimeExecutor import com.facebook.react.bridge.RuntimeScheduler import com.facebook.react.common.mapbuffer.MapBufferSoLoader import com.facebook.react.fabric.events.EventBeatManager -import com.facebook.react.fabric.events.EventEmitterWrapper import com.facebook.react.uimanager.PixelUtil.getDisplayMetricDensity @DoNotStrip @@ -82,10 +80,6 @@ internal class FabricUIManagerBinding : HybridClassBase() { public external fun reportMount(surfaceId: Int) - public external fun getInspectorDataForInstance( - eventEmitterWrapper: EventEmitterWrapper? - ): ReadableNativeMap? - public fun register( runtimeExecutor: RuntimeExecutor, runtimeScheduler: RuntimeScheduler, diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/fabric/FabricUIManagerBinding.cpp b/packages/react-native/ReactAndroid/src/main/jni/react/fabric/FabricUIManagerBinding.cpp index abb0da0e9cc07e..6d781dcff33acf 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/fabric/FabricUIManagerBinding.cpp +++ b/packages/react-native/ReactAndroid/src/main/jni/react/fabric/FabricUIManagerBinding.cpp @@ -44,33 +44,6 @@ std::shared_ptr FabricUIManagerBinding::getScheduler() { return scheduler_; } -jni::local_ref -FabricUIManagerBinding::getInspectorDataForInstance( - jni::alias_ref eventEmitterWrapper) { - auto scheduler = getScheduler(); - if (!scheduler) { - LOG(ERROR) << "FabricUIManagerBinding::startSurface: scheduler disappeared"; - return ReadableNativeMap::newObjectCxxArgs(folly::dynamic::object()); - } - - EventEmitterWrapper* cEventEmitter = cthis(eventEmitterWrapper); - InspectorData data = - scheduler->getInspectorDataForInstance(*cEventEmitter->eventEmitter); - - folly::dynamic result = folly::dynamic::object; - result["fileName"] = data.fileName; - result["lineNumber"] = data.lineNumber; - result["columnNumber"] = data.columnNumber; - result["selectedIndex"] = data.selectedIndex; - result["props"] = data.props; - auto hierarchy = folly::dynamic::array(); - for (const auto& hierarchyItem : data.hierarchy) { - hierarchy.push_back(hierarchyItem); - } - result["hierarchy"] = hierarchy; - return ReadableNativeMap::newObjectCxxArgs(result); -} - void FabricUIManagerBinding::setPixelDensity(float pointScaleFactor) { pointScaleFactor_ = pointScaleFactor; } @@ -661,9 +634,6 @@ void FabricUIManagerBinding::registerNatives() { "installFabricUIManager", FabricUIManagerBinding::installFabricUIManager), makeNativeMethod("startSurface", FabricUIManagerBinding::startSurface), - makeNativeMethod( - "getInspectorDataForInstance", - FabricUIManagerBinding::getInspectorDataForInstance), makeNativeMethod( "startSurfaceWithConstraints", FabricUIManagerBinding::startSurfaceWithConstraints), diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/fabric/FabricUIManagerBinding.h b/packages/react-native/ReactAndroid/src/main/jni/react/fabric/FabricUIManagerBinding.h index 2976dc721923bc..50c234eca5f539 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/fabric/FabricUIManagerBinding.h +++ b/packages/react-native/ReactAndroid/src/main/jni/react/fabric/FabricUIManagerBinding.h @@ -57,9 +57,6 @@ class FabricUIManagerBinding : public jni::HybridClass, jboolean isRTL, jboolean doLeftAndRightSwapInRTL); - jni::local_ref getInspectorDataForInstance( - jni::alias_ref eventEmitterWrapper); - static void initHybrid(jni::alias_ref jobj); void installFabricUIManager( diff --git a/packages/react-native/ReactCommon/react/renderer/scheduler/Scheduler.cpp b/packages/react-native/ReactCommon/react/renderer/scheduler/Scheduler.cpp index 6a2c4c9a9a4342..74d5d258026473 100644 --- a/packages/react-native/ReactCommon/react/renderer/scheduler/Scheduler.cpp +++ b/packages/react-native/ReactCommon/react/renderer/scheduler/Scheduler.cpp @@ -216,37 +216,6 @@ void Scheduler::registerSurface( surfaceHandler.setUIManager(uiManager_.get()); } -InspectorData Scheduler::getInspectorDataForInstance( - const EventEmitter& eventEmitter) const noexcept { - return executeSynchronouslyOnSameThread_CAN_DEADLOCK( - runtimeExecutor_, [=](jsi::Runtime& runtime) -> InspectorData { - auto uiManagerBinding = UIManagerBinding::getBinding(runtime); - auto value = uiManagerBinding->getInspectorDataForInstance( - runtime, eventEmitter); - - // TODO T97216348: avoid transforming jsi into folly::dynamic - auto dynamic = jsi::dynamicFromValue(runtime, value); - auto source = dynamic["source"]; - - InspectorData result = {}; - result.fileName = - source["fileName"].isNull() ? "" : source["fileName"].c_str(); - result.lineNumber = (int)source["lineNumber"].getDouble(); - result.columnNumber = (int)source["columnNumber"].getDouble(); - result.selectedIndex = (int)dynamic["selectedIndex"].getDouble(); - // TODO T97216348: remove folly::dynamic from InspectorData struct - result.props = dynamic["props"]; - auto hierarchy = dynamic["hierarchy"]; - for (auto& i : hierarchy) { - auto viewHierarchyValue = i["name"]; - if (!viewHierarchyValue.isNull()) { - result.hierarchy.emplace_back(viewHierarchyValue.c_str()); - } - } - return result; - }); -} - void Scheduler::unregisterSurface( const SurfaceHandler& surfaceHandler) const noexcept { surfaceHandler.setUIManager(nullptr); diff --git a/packages/react-native/ReactCommon/react/renderer/scheduler/Scheduler.h b/packages/react-native/ReactCommon/react/renderer/scheduler/Scheduler.h index 30ab071b92f53b..4e364dbe6fcecb 100644 --- a/packages/react-native/ReactCommon/react/renderer/scheduler/Scheduler.h +++ b/packages/react-native/ReactCommon/react/renderer/scheduler/Scheduler.h @@ -52,9 +52,6 @@ class Scheduler final : public UIManagerDelegate { void registerSurface(const SurfaceHandler& surfaceHandler) const noexcept; void unregisterSurface(const SurfaceHandler& surfaceHandler) const noexcept; - InspectorData getInspectorDataForInstance( - const EventEmitter& eventEmitter) const noexcept; - /* * This is broken. Please do not use. * `ComponentDescriptor`s are not designed to be used outside of `UIManager`, diff --git a/packages/react-native/ReactCommon/react/renderer/uimanager/UIManagerBinding.cpp b/packages/react-native/ReactCommon/react/renderer/uimanager/UIManagerBinding.cpp index b63be2f6b2245c..ed3215bb65bdc6 100644 --- a/packages/react-native/ReactCommon/react/renderer/uimanager/UIManagerBinding.cpp +++ b/packages/react-native/ReactCommon/react/renderer/uimanager/UIManagerBinding.cpp @@ -62,33 +62,6 @@ UIManagerBinding::~UIManagerBinding() { << this << ")."; } -jsi::Value UIManagerBinding::getInspectorDataForInstance( - jsi::Runtime& runtime, - const EventEmitter& eventEmitter) const { - auto eventTarget = eventEmitter.eventTarget_; - EventEmitter::DispatchMutex().lock(); - - if (!runtime.global().hasProperty(runtime, "__fbBatchedBridge") || - !eventTarget) { - return jsi::Value::undefined(); - } - - eventTarget->retain(runtime); - auto instanceHandle = eventTarget->getInstanceHandle(runtime); - eventTarget->release(runtime); - EventEmitter::DispatchMutex().unlock(); - - if (instanceHandle.isUndefined()) { - return jsi::Value::undefined(); - } - - return callMethodOfModule( - runtime, - "ReactFabric", - "getInspectorDataForInstance", - {std::move(instanceHandle)}); -} - void UIManagerBinding::dispatchEvent( jsi::Runtime& runtime, const EventTarget* eventTarget, diff --git a/packages/react-native/ReactCommon/react/renderer/uimanager/UIManagerBinding.h b/packages/react-native/ReactCommon/react/renderer/uimanager/UIManagerBinding.h index 8f8e6a387898ee..ef6c682df00292 100644 --- a/packages/react-native/ReactCommon/react/renderer/uimanager/UIManagerBinding.h +++ b/packages/react-native/ReactCommon/react/renderer/uimanager/UIManagerBinding.h @@ -40,10 +40,6 @@ class UIManagerBinding : public jsi::HostObject { ~UIManagerBinding() override; - jsi::Value getInspectorDataForInstance( - jsi::Runtime& runtime, - const EventEmitter& eventEmitter) const; - /* * Delivers raw event data to JavaScript. * Thread synchronization must be enforced externally. From 7233b6697acc2ff9be9ddeb7c8d2d989ee5477a1 Mon Sep 17 00:00:00 2001 From: Pieter De Baets Date: Tue, 7 Jan 2025 02:44:09 -0800 Subject: [PATCH 2/2] Always use AppRegistry globals in SurfaceRegistryBinding (#48336) Summary: `RN$AppRegistry` and `RN$stopSurface` are always set on the init path, regardless of bridgeless or not, so we can remove the fallback path and cleanup this code. Changelog: [Internal] Reviewed By: rshest Differential Revision: D67342498 --- .../uimanager/SurfaceRegistryBinding.cpp | 95 ++++++------------- .../renderer/uimanager/UIManagerBinding.cpp | 2 - .../react/renderer/uimanager/bindingUtils.cpp | 79 --------------- .../react/renderer/uimanager/bindingUtils.h | 20 ---- 4 files changed, 30 insertions(+), 166 deletions(-) delete mode 100644 packages/react-native/ReactCommon/react/renderer/uimanager/bindingUtils.cpp delete mode 100644 packages/react-native/ReactCommon/react/renderer/uimanager/bindingUtils.h diff --git a/packages/react-native/ReactCommon/react/renderer/uimanager/SurfaceRegistryBinding.cpp b/packages/react-native/ReactCommon/react/renderer/uimanager/SurfaceRegistryBinding.cpp index 5b9d62bea6c17b..eeed20b043b22c 100644 --- a/packages/react-native/ReactCommon/react/renderer/uimanager/SurfaceRegistryBinding.cpp +++ b/packages/react-native/ReactCommon/react/renderer/uimanager/SurfaceRegistryBinding.cpp @@ -7,28 +7,10 @@ #include "SurfaceRegistryBinding.h" #include -#include #include -#include "bindingUtils.h" namespace facebook::react { -namespace { - -void throwIfBridgeless( - jsi::Runtime& runtime, - jsi::Object& global, - const char* methodName) { - auto isBridgeless = global.getProperty(runtime, "RN$Bridgeless"); - if (isBridgeless.isBool() && isBridgeless.asBool()) { - throw std::runtime_error( - "SurfaceRegistryBinding::" + std::string(methodName) + - " failed. Global was not installed."); - } -} - -} // namespace - void SurfaceRegistryBinding::startSurface( jsi::Runtime& runtime, SurfaceId surfaceId, @@ -44,24 +26,17 @@ void SurfaceRegistryBinding::startSurface( auto global = runtime.global(); auto registry = global.getProperty(runtime, "RN$AppRegistry"); - if (registry.isObject()) { - auto method = std::move(registry).asObject(runtime).getPropertyAsFunction( - runtime, "runApplication"); - method.call( - runtime, - {jsi::String::createFromUtf8(runtime, moduleName), - std::move(parameters), - jsi::Value(runtime, displayModeToInt(displayMode))}); - } else { - throwIfBridgeless(runtime, global, "startSurface"); - callMethodOfModule( - runtime, - "AppRegistry", - "runApplication", - {jsi::String::createFromUtf8(runtime, moduleName), - std::move(parameters), - jsi::Value(runtime, displayModeToInt(displayMode))}); + if (!registry.isObject()) { + throw std::runtime_error( + "SurfaceRegistryBinding::startSurface failed. Global was not installed."); } + auto method = std::move(registry).asObject(runtime).getPropertyAsFunction( + runtime, "runApplication"); + method.call( + runtime, + {jsi::String::createFromUtf8(runtime, moduleName), + std::move(parameters), + jsi::Value(runtime, displayModeToInt(displayMode))}); } void SurfaceRegistryBinding::setSurfaceProps( @@ -79,24 +54,18 @@ void SurfaceRegistryBinding::setSurfaceProps( auto global = runtime.global(); auto registry = global.getProperty(runtime, "RN$AppRegistry"); - if (registry.isObject()) { - auto method = std::move(registry).asObject(runtime).getPropertyAsFunction( - runtime, "setSurfaceProps"); - method.call( - runtime, - {jsi::String::createFromUtf8(runtime, moduleName), - std::move(parameters), - jsi::Value(runtime, displayModeToInt(displayMode))}); - } else { - throwIfBridgeless(runtime, global, "setSurfaceProps"); - callMethodOfModule( - runtime, - "AppRegistry", - "setSurfaceProps", - {jsi::String::createFromUtf8(runtime, moduleName), - std::move(parameters), - jsi::Value(runtime, displayModeToInt(displayMode))}); + if (!registry.isObject()) { + throw std::runtime_error( + "SurfaceRegistryBinding::setSurfaceProps failed. Global was not installed."); } + + auto method = std::move(registry).asObject(runtime).getPropertyAsFunction( + runtime, "setSurfaceProps"); + method.call( + runtime, + {jsi::String::createFromUtf8(runtime, moduleName), + std::move(parameters), + jsi::Value(runtime, displayModeToInt(displayMode))}); } void SurfaceRegistryBinding::stopSurface( @@ -104,20 +73,16 @@ void SurfaceRegistryBinding::stopSurface( SurfaceId surfaceId) { auto global = runtime.global(); auto stopFunction = global.getProperty(runtime, "RN$stopSurface"); - if (stopFunction.isObject() && - stopFunction.asObject(runtime).isFunction(runtime)) { - std::move(stopFunction) - .asObject(runtime) - .asFunction(runtime) - .call(runtime, {jsi::Value{surfaceId}}); - } else { - throwIfBridgeless(runtime, global, "stopSurface"); - callMethodOfModule( - runtime, - "ReactFabric", - "unmountComponentAtNode", - {jsi::Value{surfaceId}}); + if (!stopFunction.isObject() || + !stopFunction.asObject(runtime).isFunction(runtime)) { + throw std::runtime_error( + "SurfaceRegistryBinding::stopSurface failed. Global was not installed."); } + + std::move(stopFunction) + .asObject(runtime) + .asFunction(runtime) + .call(runtime, {jsi::Value{surfaceId}}); } } // namespace facebook::react diff --git a/packages/react-native/ReactCommon/react/renderer/uimanager/UIManagerBinding.cpp b/packages/react-native/ReactCommon/react/renderer/uimanager/UIManagerBinding.cpp index ed3215bb65bdc6..e43f94b645ed8a 100644 --- a/packages/react-native/ReactCommon/react/renderer/uimanager/UIManagerBinding.cpp +++ b/packages/react-native/ReactCommon/react/renderer/uimanager/UIManagerBinding.cpp @@ -19,8 +19,6 @@ #include -#include "bindingUtils.h" - namespace facebook::react { void UIManagerBinding::createAndInstallIfNeeded( diff --git a/packages/react-native/ReactCommon/react/renderer/uimanager/bindingUtils.cpp b/packages/react-native/ReactCommon/react/renderer/uimanager/bindingUtils.cpp deleted file mode 100644 index 3aa554762948c2..00000000000000 --- a/packages/react-native/ReactCommon/react/renderer/uimanager/bindingUtils.cpp +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -#include "bindingUtils.h" - -#include -#include - -namespace facebook::react { - -static jsi::Value getModule( - jsi::Runtime& runtime, - const std::string& moduleName) { - auto batchedBridge = - runtime.global().getPropertyAsObject(runtime, "__fbBatchedBridge"); - auto getCallableModule = - batchedBridge.getPropertyAsFunction(runtime, "getCallableModule"); - auto moduleAsValue = getCallableModule.callWithThis( - runtime, - batchedBridge, - {jsi::String::createFromUtf8(runtime, moduleName)}); - if (!moduleAsValue.isObject()) { - LOG(ERROR) << "getModule of " << moduleName << " is not an object"; - } - react_native_assert(moduleAsValue.isObject()); - return moduleAsValue; -} - -static bool checkBatchedBridgeIsActive(jsi::Runtime& runtime) { - if (!runtime.global().hasProperty(runtime, "__fbBatchedBridge")) { - LOG(ERROR) - << "getPropertyAsObject: property '__fbBatchedBridge' is undefined, expected an Object"; - return false; - } - return true; -} - -static bool checkGetCallableModuleIsActive(jsi::Runtime& runtime) { - if (!checkBatchedBridgeIsActive(runtime)) { - return false; - } - auto batchedBridge = - runtime.global().getPropertyAsObject(runtime, "__fbBatchedBridge"); - if (!batchedBridge.hasProperty(runtime, "getCallableModule")) { - LOG(ERROR) - << "getPropertyAsFunction: function 'getCallableModule' is undefined, expected a Function"; - return false; - } - return true; -} - -jsi::Value callMethodOfModule( - jsi::Runtime& runtime, - const std::string& moduleName, - const std::string& methodName, - std::initializer_list args) { - if (checkGetCallableModuleIsActive(runtime)) { - auto module = getModule(runtime, moduleName); - if (module.isObject()) { - jsi::Object object = module.asObject(runtime); - react_native_assert(object.hasProperty(runtime, methodName.c_str())); - if (object.hasProperty(runtime, methodName.c_str())) { - auto method = object.getPropertyAsFunction(runtime, methodName.c_str()); - return method.callWithThis(runtime, object, args); - } else { - LOG(ERROR) << "getPropertyAsFunction: property '" << methodName - << "' is undefined, expected a Function"; - } - } - } - - return jsi::Value::undefined(); -} - -} // namespace facebook::react diff --git a/packages/react-native/ReactCommon/react/renderer/uimanager/bindingUtils.h b/packages/react-native/ReactCommon/react/renderer/uimanager/bindingUtils.h deleted file mode 100644 index 60afbfff9b09d9..00000000000000 --- a/packages/react-native/ReactCommon/react/renderer/uimanager/bindingUtils.h +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -#pragma once - -#include - -namespace facebook::react { - -jsi::Value callMethodOfModule( - jsi::Runtime& runtime, - const std::string& moduleName, - const std::string& methodName, - std::initializer_list args); - -} // namespace facebook::react