mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Expose new API FabricUIManager.getInspectorDataForInstance
Summary: This diff exposes a new API in FabricUIManager called getInspectorDataForInstance. The goal of this method is to return React metadata for a Native view. This data will be used from partner teams to build tools that uses React metadata in RN Data returned from React: P429701924 changelog: [internal] internal allow-large-files Reviewed By: JoshuaGross Differential Revision: D29747864 fbshipit-source-id: 8cb55573be08cb530f7e3c83eed8b4fcf43e7781
This commit is contained in:
1 parent
ff494eece2
commit
43cdd84a22
8 files changed
+109
No files matched your search
@@ -12,9 +12,11 @@ import androidx.annotation.NonNull;
|
||||
import com.facebook.jni.HybridData;
|
||||
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.queue.MessageQueueThread;
|
||||
import com.facebook.react.fabric.events.EventBeatManager;
|
||||
import com.facebook.react.fabric.events.EventEmitterWrapper;
|
||||
import com.facebook.react.uimanager.PixelUtil;
|
||||
|
||||
@DoNotStrip
|
||||
@@ -76,6 +78,9 @@ public class Binding {
|
||||
|
||||
public native void driveCxxAnimations();
|
||||
|
||||
public native ReadableNativeMap getInspectorDataForInstance(
|
||||
EventEmitterWrapper eventEmitterWrapper);
|
||||
|
||||
public void register(
|
||||
@NonNull RuntimeExecutor runtimeExecutor,
|
||||
@NonNull FabricUIManager fabricUIManager,
|
||||
|
||||
@@ -223,6 +223,16 @@ public class FabricUIManager implements UIManager, LifecycleEventListener {
|
||||
return rootTag;
|
||||
}
|
||||
|
||||
@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
|
||||
public void preInitializeViewManagers(List<String> viewManagerNames) {
|
||||
for (String viewManagerName : viewManagerNames) {
|
||||
|
||||
@@ -233,6 +233,32 @@ std::shared_ptr<Scheduler> Binding::getScheduler() {
|
||||
return scheduler_;
|
||||
}
|
||||
|
||||
jni::local_ref<ReadableNativeMap::jhybridobject>
|
||||
Binding::getInspectorDataForInstance(
|
||||
jni::alias_ref<EventEmitterWrapper::javaobject> eventEmitterWrapper) {
|
||||
std::shared_ptr<Scheduler> scheduler = getScheduler();
|
||||
if (!scheduler) {
|
||||
LOG(ERROR) << "Binding::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;
|
||||
auto hierarchy = folly::dynamic::array();
|
||||
for (auto hierarchyItem : data.hierarchy) {
|
||||
hierarchy.push_back(hierarchyItem);
|
||||
}
|
||||
result["hierarchy"] = hierarchy;
|
||||
return ReadableNativeMap::newObjectCxxArgs(result);
|
||||
}
|
||||
|
||||
void Binding::startSurface(
|
||||
jint surfaceId,
|
||||
jni::alias_ref<jstring> moduleName,
|
||||
@@ -1314,6 +1340,8 @@ void Binding::registerNatives() {
|
||||
makeNativeMethod(
|
||||
"installFabricUIManager", Binding::installFabricUIManager),
|
||||
makeNativeMethod("startSurface", Binding::startSurface),
|
||||
makeNativeMethod(
|
||||
"getInspectorDataForInstance", Binding::getInspectorDataForInstance),
|
||||
makeNativeMethod(
|
||||
"startSurfaceWithConstraints", Binding::startSurfaceWithConstraints),
|
||||
makeNativeMethod(
|
||||
|
||||
@@ -15,10 +15,12 @@
|
||||
#include <react/renderer/scheduler/Scheduler.h>
|
||||
#include <react/renderer/scheduler/SchedulerDelegate.h>
|
||||
#include <react/renderer/uimanager/LayoutAnimationStatusDelegate.h>
|
||||
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include "ComponentFactory.h"
|
||||
#include "EventBeatManager.h"
|
||||
#include "EventEmitterWrapper.h"
|
||||
#include "JBackgroundExecutor.h"
|
||||
#include "SurfaceHandlerBinding.h"
|
||||
|
||||
@@ -96,6 +98,9 @@ class Binding : public jni::HybridClass<Binding>,
|
||||
jboolean isRTL,
|
||||
jboolean doLeftAndRightSwapInRTL);
|
||||
|
||||
jni::local_ref<ReadableNativeMap::jhybridobject> getInspectorDataForInstance(
|
||||
jni::alias_ref<EventEmitterWrapper::javaobject> eventEmitterWrapper);
|
||||
|
||||
static jni::local_ref<jhybriddata> initHybrid(jni::alias_ref<jclass>);
|
||||
|
||||
void installFabricUIManager(
|
||||
|
||||
@@ -206,6 +206,31 @@ void Scheduler::registerSurface(
|
||||
surfaceHandler.setUIManager(uiManager_.get());
|
||||
}
|
||||
|
||||
InspectorData Scheduler::getInspectorDataForInstance(
|
||||
SharedEventEmitter eventEmitter) const noexcept {
|
||||
return executeSynchronouslyOnSameThread_CAN_DEADLOCK<InspectorData>(
|
||||
runtimeExecutor_, [=](jsi::Runtime &runtime) -> InspectorData {
|
||||
auto uiManagerBinding = UIManagerBinding::getBinding(runtime);
|
||||
auto value = uiManagerBinding->getInspectorDataForInstance(
|
||||
runtime, eventEmitter);
|
||||
|
||||
// TODO: avoid transforming jsi
|
||||
auto dynamic = jsi::dynamicFromValue(runtime, value);
|
||||
auto source = dynamic["source"];
|
||||
|
||||
InspectorData result = {};
|
||||
result.fileName = source["fileName"].c_str();
|
||||
result.lineNumber = (int)source["lineNumber"].getDouble();
|
||||
result.columnNumber = (int)source["columnNumber"].getDouble();
|
||||
result.selectedIndex = (int)dynamic["selectedIndex"].getDouble();
|
||||
auto hierarchy = dynamic["hierarchy"];
|
||||
for (size_t i = 0; i < hierarchy.size(); i++) {
|
||||
result.hierarchy.push_back(hierarchy[i]["name"].c_str());
|
||||
}
|
||||
return result;
|
||||
});
|
||||
}
|
||||
|
||||
void Scheduler::unregisterSurface(
|
||||
SurfaceHandler const &surfaceHandler) const noexcept {
|
||||
surfaceHandler.setUIManager(nullptr);
|
||||
|
||||
@@ -15,8 +15,10 @@
|
||||
#include <react/renderer/componentregistry/ComponentDescriptorFactory.h>
|
||||
#include <react/renderer/components/root/RootComponentDescriptor.h>
|
||||
#include <react/renderer/core/ComponentDescriptor.h>
|
||||
#include <react/renderer/core/EventEmitter.h>
|
||||
#include <react/renderer/core/LayoutConstraints.h>
|
||||
#include <react/renderer/mounting/MountingOverrideDelegate.h>
|
||||
#include <react/renderer/scheduler/InspectorData.h>
|
||||
#include <react/renderer/scheduler/SchedulerDelegate.h>
|
||||
#include <react/renderer/scheduler/SchedulerToolbox.h>
|
||||
#include <react/renderer/scheduler/SurfaceHandler.h>
|
||||
@@ -49,6 +51,9 @@ class Scheduler final : public UIManagerDelegate {
|
||||
void registerSurface(SurfaceHandler const &surfaceHandler) const noexcept;
|
||||
void unregisterSurface(SurfaceHandler const &surfaceHandler) const noexcept;
|
||||
|
||||
InspectorData getInspectorDataForInstance(
|
||||
SharedEventEmitter eventEmitter) const noexcept;
|
||||
|
||||
void renderTemplateToSurface(
|
||||
SurfaceId surfaceId,
|
||||
const std::string &uiTemplate);
|
||||
|
||||
@@ -133,6 +133,33 @@ static jsi::Value callMethodOfModule(
|
||||
return jsi::Value::undefined();
|
||||
}
|
||||
|
||||
jsi::Value UIManagerBinding::getInspectorDataForInstance(
|
||||
jsi::Runtime &runtime,
|
||||
SharedEventEmitter 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::startSurface(
|
||||
jsi::Runtime &runtime,
|
||||
SurfaceId surfaceId,
|
||||
|
||||
@@ -74,6 +74,10 @@ class UIManagerBinding : public jsi::HostObject {
|
||||
folly::dynamic const &props,
|
||||
DisplayMode displayMode) const;
|
||||
|
||||
jsi::Value getInspectorDataForInstance(
|
||||
jsi::Runtime &runtime,
|
||||
SharedEventEmitter eventEmitter) const;
|
||||
|
||||
/*
|
||||
* Stops React Native Surface with given id.
|
||||
* Thread synchronization must be enforced externally.
|
||||
|
||||
Reference in new issue
Block a user