Delete ModuleRegistryHolder
Reviewed By: mhorowitz Differential Revision: D4411478 fbshipit-source-id: 03f48f92f0d97bd5e3318f60c8357242fe9792cf
This commit is contained in:
parent
bf930e473a
commit
0e7d0ebd9a
|
@ -128,7 +128,8 @@ public class CatalystInstanceImpl implements CatalystInstance {
|
|||
jsExecutor,
|
||||
mReactQueueConfiguration.getJSQueueThread(),
|
||||
mReactQueueConfiguration.getNativeModulesQueueThread(),
|
||||
mJavaRegistry.getModuleRegistryHolder(this));
|
||||
mJavaRegistry.getJavaModules(this),
|
||||
mJavaRegistry.getCxxModules());
|
||||
mMainExecutorToken = getMainExecutorToken();
|
||||
}
|
||||
|
||||
|
@ -179,7 +180,8 @@ public class CatalystInstanceImpl implements CatalystInstance {
|
|||
JavaScriptExecutor jsExecutor,
|
||||
MessageQueueThread jsQueue,
|
||||
MessageQueueThread moduleQueue,
|
||||
ModuleRegistryHolder registryHolder);
|
||||
Collection<JavaModuleWrapper> javaModules,
|
||||
Collection<CxxModuleWrapper> cxxModules);
|
||||
|
||||
/**
|
||||
* This API is used in situations where the JS bundle is being executed not on
|
||||
|
|
|
@ -1,28 +0,0 @@
|
|||
/**
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*/
|
||||
|
||||
package com.facebook.react.cxxbridge;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import com.facebook.jni.HybridData;
|
||||
|
||||
public class ModuleRegistryHolder {
|
||||
private final HybridData mHybridData;
|
||||
private static native HybridData initHybrid(
|
||||
CatalystInstanceImpl catalystInstanceImpl,
|
||||
Collection<JavaModuleWrapper> javaModules,
|
||||
Collection<CxxModuleWrapper> cxxModules);
|
||||
|
||||
public ModuleRegistryHolder(CatalystInstanceImpl catalystInstanceImpl,
|
||||
Collection<JavaModuleWrapper> javaModules,
|
||||
Collection<CxxModuleWrapper> cxxModules) {
|
||||
mHybridData = initHybrid(catalystInstanceImpl, javaModules, cxxModules);
|
||||
}
|
||||
}
|
|
@ -10,6 +10,7 @@
|
|||
package com.facebook.react.cxxbridge;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
|
@ -36,22 +37,27 @@ public class NativeModuleRegistry {
|
|||
mBatchCompleteListenerModules = batchCompleteListenerModules;
|
||||
}
|
||||
|
||||
/* package */ ModuleRegistryHolder getModuleRegistryHolder(
|
||||
/* package */ Collection<JavaModuleWrapper> getJavaModules(
|
||||
CatalystInstanceImpl catalystInstanceImpl) {
|
||||
ArrayList<JavaModuleWrapper> javaModules = new ArrayList<>();
|
||||
for (Map.Entry<Class<? extends NativeModule>, ModuleHolder> entry : mModules.entrySet()) {
|
||||
Class<?> type = entry.getKey();
|
||||
if (!CxxModuleWrapper.class.isAssignableFrom(type)) {
|
||||
javaModules.add(new JavaModuleWrapper(catalystInstanceImpl, entry.getValue()));
|
||||
}
|
||||
}
|
||||
return javaModules;
|
||||
}
|
||||
|
||||
/* package */ Collection<CxxModuleWrapper> getCxxModules() {
|
||||
ArrayList<CxxModuleWrapper> cxxModules = new ArrayList<>();
|
||||
for (Map.Entry<Class<? extends NativeModule>, ModuleHolder> entry : mModules.entrySet()) {
|
||||
Class<?> type = entry.getKey();
|
||||
ModuleHolder moduleHolder = entry.getValue();
|
||||
if (BaseJavaModule.class.isAssignableFrom(type)) {
|
||||
javaModules.add(new JavaModuleWrapper(catalystInstanceImpl, moduleHolder));
|
||||
} else if (CxxModuleWrapper.class.isAssignableFrom(type)) {
|
||||
cxxModules.add((CxxModuleWrapper) moduleHolder.getModule());
|
||||
} else {
|
||||
throw new IllegalArgumentException("Unknown module type " + type);
|
||||
if (CxxModuleWrapper.class.isAssignableFrom(type)) {
|
||||
cxxModules.add((CxxModuleWrapper) entry.getValue().getModule());
|
||||
}
|
||||
}
|
||||
return new ModuleRegistryHolder(catalystInstanceImpl, javaModules, cxxModules);
|
||||
return cxxModules;
|
||||
}
|
||||
|
||||
/* package */ void notifyCatalystInstanceDestroy() {
|
||||
|
|
|
@ -7,6 +7,7 @@ LOCAL_MODULE := reactnativejnifb
|
|||
LOCAL_SRC_FILES := \
|
||||
CatalystInstanceImpl.cpp \
|
||||
CxxModuleWrapper.cpp \
|
||||
JavaModuleWrapper.cpp \
|
||||
JExecutorToken.cpp \
|
||||
JMessageQueueThread.cpp \
|
||||
JniJSModulesUnbundle.cpp \
|
||||
|
@ -14,7 +15,6 @@ LOCAL_SRC_FILES := \
|
|||
JSLoader.cpp \
|
||||
JSLogging.cpp \
|
||||
MethodInvoker.cpp \
|
||||
ModuleRegistryHolder.cpp \
|
||||
OnLoad.cpp \
|
||||
ProxyExecutor.cpp \
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@ LOCAL_MODULE := libreactnativejnifb
|
|||
LOCAL_SRC_FILES := \
|
||||
CatalystInstanceImpl.cpp \
|
||||
CxxModuleWrapper.cpp \
|
||||
JavaModuleWrapper.cpp \
|
||||
JExecutorToken.cpp \
|
||||
JMessageQueueThread.cpp \
|
||||
JSCPerfLogging.cpp \
|
||||
|
@ -14,7 +15,6 @@ LOCAL_SRC_FILES := \
|
|||
JSLogging.cpp \
|
||||
JniJSModulesUnbundle.cpp \
|
||||
MethodInvoker.cpp \
|
||||
ModuleRegistryHolder.cpp \
|
||||
NativeArray.cpp \
|
||||
NativeCommon.cpp \
|
||||
NativeMap.cpp \
|
||||
|
|
|
@ -18,13 +18,13 @@
|
|||
#include <cxxreact/JSIndexedRAMBundle.h>
|
||||
#include <cxxreact/MethodCall.h>
|
||||
#include <cxxreact/ModuleRegistry.h>
|
||||
#include <cxxreact/CxxNativeModule.h>
|
||||
|
||||
#include "JSLoader.h"
|
||||
#include "JavaScriptExecutorHolder.h"
|
||||
#include "JniJSModulesUnbundle.h"
|
||||
#include "ModuleRegistryHolder.h"
|
||||
#include "NativeArray.h"
|
||||
#include "JNativeRunnable.h"
|
||||
#include "JSLoader.h"
|
||||
#include "NativeArray.h"
|
||||
|
||||
using namespace facebook::jni;
|
||||
|
||||
|
@ -33,7 +33,6 @@ namespace react {
|
|||
|
||||
namespace {
|
||||
|
||||
|
||||
class Exception : public jni::JavaClass<Exception> {
|
||||
public:
|
||||
static auto constexpr kJavaDescriptor = "Ljava/lang/Exception;";
|
||||
|
@ -130,10 +129,22 @@ void CatalystInstanceImpl::initializeBridge(
|
|||
JavaScriptExecutorHolder* jseh,
|
||||
jni::alias_ref<JavaMessageQueueThread::javaobject> jsQueue,
|
||||
jni::alias_ref<JavaMessageQueueThread::javaobject> moduleQueue,
|
||||
ModuleRegistryHolder* mrh) {
|
||||
jni::alias_ref<jni::JCollection<JavaModuleWrapper::javaobject>::javaobject> javaModules,
|
||||
jni::alias_ref<jni::JCollection<CxxModuleWrapper::javaobject>::javaobject> cxxModules) {
|
||||
// TODO mhorowitz: how to assert here?
|
||||
// Assertions.assertCondition(mBridge == null, "initializeBridge should be called once");
|
||||
|
||||
std::vector<std::unique_ptr<NativeModule>> modules;
|
||||
std::weak_ptr<Instance> winstance(instance_);
|
||||
for (const auto& jm : *javaModules) {
|
||||
modules.emplace_back(folly::make_unique<JavaNativeModule>(winstance, jm));
|
||||
}
|
||||
for (const auto& cm : *cxxModules) {
|
||||
modules.emplace_back(
|
||||
folly::make_unique<CxxNativeModule>(winstance, std::move(cthis(cm)->getModule())));
|
||||
}
|
||||
auto moduleRegistry = std::make_shared<ModuleRegistry>(std::move(modules));
|
||||
|
||||
// This used to be:
|
||||
//
|
||||
// Java CatalystInstanceImpl -> C++ CatalystInstanceImpl -> Bridge -> Bridge::Callback
|
||||
|
@ -154,7 +165,7 @@ void CatalystInstanceImpl::initializeBridge(
|
|||
jseh->getExecutorFactory(),
|
||||
folly::make_unique<JMessageQueueThread>(jsQueue),
|
||||
folly::make_unique<JMessageQueueThread>(moduleQueue),
|
||||
mrh->getModuleRegistry());
|
||||
moduleRegistry);
|
||||
}
|
||||
|
||||
void CatalystInstanceImpl::jniSetSourceURL(const std::string& sourceURL) {
|
||||
|
|
|
@ -5,16 +5,17 @@
|
|||
#include <fb/fbjni.h>
|
||||
#include <folly/Memory.h>
|
||||
|
||||
#include "CxxModuleWrapper.h"
|
||||
#include "JExecutorToken.h"
|
||||
#include "JMessageQueueThread.h"
|
||||
#include "JSLoader.h"
|
||||
#include "JavaModuleWrapper.h"
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
class Instance;
|
||||
class JavaScriptExecutorHolder;
|
||||
class ModuleRegistryHolder;
|
||||
class NativeArray;
|
||||
|
||||
struct ReactCallback : public jni::JavaClass<ReactCallback> {
|
||||
|
@ -46,7 +47,8 @@ class CatalystInstanceImpl : public jni::HybridClass<CatalystInstanceImpl> {
|
|||
JavaScriptExecutorHolder* jseh,
|
||||
jni::alias_ref<JavaMessageQueueThread::javaobject> jsQueue,
|
||||
jni::alias_ref<JavaMessageQueueThread::javaobject> moduleQueue,
|
||||
ModuleRegistryHolder* mrh);
|
||||
jni::alias_ref<jni::JCollection<JavaModuleWrapper::javaobject>::javaobject> javaModules,
|
||||
jni::alias_ref<jni::JCollection<CxxModuleWrapper::javaobject>::javaobject> cxxModules);
|
||||
|
||||
/**
|
||||
* Sets the source URL of the underlying bridge without loading any JS code.
|
||||
|
|
|
@ -0,0 +1,159 @@
|
|||
// Copyright 2004-present Facebook. All Rights Reserved.
|
||||
|
||||
#include "JavaModuleWrapper.h"
|
||||
|
||||
#include <folly/json.h>
|
||||
|
||||
#include <fb/fbjni.h>
|
||||
|
||||
#include <cxxreact/CxxModule.h>
|
||||
#include <cxxreact/CxxNativeModule.h>
|
||||
#include <cxxreact/Instance.h>
|
||||
#include <cxxreact/JsArgumentHelpers.h>
|
||||
#include <cxxreact/NativeModule.h>
|
||||
|
||||
#include "CatalystInstanceImpl.h"
|
||||
#include "ReadableNativeArray.h"
|
||||
|
||||
using facebook::xplat::module::CxxModule;
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
std::string JMethodDescriptor::getSignature() const {
|
||||
static auto signature = javaClassStatic()->getField<jstring>("signature");
|
||||
return getFieldValue(signature)->toStdString();
|
||||
}
|
||||
|
||||
std::string JMethodDescriptor::getName() const {
|
||||
static auto name = javaClassStatic()->getField<jstring>("name");
|
||||
return getFieldValue(name)->toStdString();
|
||||
}
|
||||
|
||||
std::string JMethodDescriptor::getType() const {
|
||||
static auto type = javaClassStatic()->getField<jstring>("type");
|
||||
return getFieldValue(type)->toStdString();
|
||||
}
|
||||
|
||||
std::string JavaNativeModule::getName() {
|
||||
static auto getNameMethod = wrapper_->getClass()->getMethod<jstring()>("getName");
|
||||
return getNameMethod(wrapper_)->toStdString();
|
||||
}
|
||||
|
||||
std::vector<MethodDescriptor> JavaNativeModule::getMethods() {
|
||||
std::vector<MethodDescriptor> ret;
|
||||
auto descs = wrapper_->getMethodDescriptors();
|
||||
for (const auto& desc : *descs) {
|
||||
ret.emplace_back(desc->getName(), desc->getType());
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
folly::dynamic JavaNativeModule::getConstants() {
|
||||
static auto constantsMethod =
|
||||
wrapper_->getClass()->getMethod<NativeArray::javaobject()>("getConstants");
|
||||
auto constants = constantsMethod(wrapper_);
|
||||
if (!constants) {
|
||||
return nullptr;
|
||||
} else {
|
||||
// See JavaModuleWrapper#getConstants for the other side of this hack.
|
||||
return cthis(constants)->array[0];
|
||||
}
|
||||
}
|
||||
|
||||
bool JavaNativeModule::supportsWebWorkers() {
|
||||
static auto supportsWebWorkersMethod =
|
||||
wrapper_->getClass()->getMethod<jboolean()>("supportsWebWorkers");
|
||||
return supportsWebWorkersMethod(wrapper_);
|
||||
}
|
||||
|
||||
void JavaNativeModule::invoke(ExecutorToken token, unsigned int reactMethodId, folly::dynamic&& params) {
|
||||
static auto invokeMethod =
|
||||
wrapper_->getClass()->getMethod<void(JExecutorToken::javaobject, jint, ReadableNativeArray::javaobject)>("invoke");
|
||||
invokeMethod(wrapper_, JExecutorToken::extractJavaPartFromToken(token).get(), static_cast<jint>(reactMethodId),
|
||||
ReadableNativeArray::newObjectCxxArgs(std::move(params)).get());
|
||||
}
|
||||
|
||||
MethodCallResult JavaNativeModule::callSerializableNativeHook(ExecutorToken token, unsigned int reactMethodId, folly::dynamic&& params) {
|
||||
throw std::runtime_error("Unsupported operation.");
|
||||
}
|
||||
|
||||
NewJavaNativeModule::NewJavaNativeModule(
|
||||
std::weak_ptr<Instance> instance,
|
||||
jni::alias_ref<JavaModuleWrapper::javaobject> wrapper)
|
||||
: instance_(std::move(instance)),
|
||||
wrapper_(make_global(wrapper)),
|
||||
module_(make_global(wrapper->getModule())) {
|
||||
auto descs = wrapper_->getMethodDescriptors();
|
||||
std::string moduleName = getName();
|
||||
methods_.reserve(descs->size());
|
||||
|
||||
for (const auto& desc : *descs) {
|
||||
auto type = desc->getType();
|
||||
auto name = desc->getName();
|
||||
methods_.emplace_back(
|
||||
desc->getMethod(),
|
||||
desc->getSignature(),
|
||||
moduleName + "." + name,
|
||||
type == "syncHook");
|
||||
|
||||
methodDescriptors_.emplace_back(name, type);
|
||||
}
|
||||
}
|
||||
|
||||
std::string NewJavaNativeModule::getName() {
|
||||
static auto getNameMethod = wrapper_->getClass()->getMethod<jstring()>("getName");
|
||||
return getNameMethod(wrapper_)->toStdString();
|
||||
}
|
||||
|
||||
std::vector<MethodDescriptor> NewJavaNativeModule::getMethods() {
|
||||
return methodDescriptors_;
|
||||
}
|
||||
|
||||
folly::dynamic NewJavaNativeModule::getConstants() {
|
||||
static auto constantsMethod =
|
||||
wrapper_->getClass()->getMethod<NativeArray::javaobject()>("getConstants");
|
||||
auto constants = constantsMethod(wrapper_);
|
||||
if (!constants) {
|
||||
return nullptr;
|
||||
} else {
|
||||
// See JavaModuleWrapper#getConstants for the other side of this hack.
|
||||
return cthis(constants)->array[0];
|
||||
}
|
||||
}
|
||||
|
||||
bool NewJavaNativeModule::supportsWebWorkers() {
|
||||
static auto supportsWebWorkersMethod =
|
||||
wrapper_->getClass()->getMethod<jboolean()>("supportsWebWorkers");
|
||||
return supportsWebWorkersMethod(wrapper_);
|
||||
}
|
||||
|
||||
void NewJavaNativeModule::invoke(ExecutorToken token, unsigned int reactMethodId, folly::dynamic&& params) {
|
||||
if (reactMethodId >= methods_.size()) {
|
||||
throw std::invalid_argument(
|
||||
folly::to<std::string>("methodId ", reactMethodId, " out of range [0..", methods_.size(), "]"));
|
||||
}
|
||||
CHECK(!methods_[reactMethodId].isSyncHook()) << "Trying to invoke a synchronous hook asynchronously";
|
||||
invokeInner(token, reactMethodId, std::move(params));
|
||||
}
|
||||
|
||||
MethodCallResult NewJavaNativeModule::callSerializableNativeHook(ExecutorToken token, unsigned int reactMethodId, folly::dynamic&& params) {
|
||||
if (reactMethodId >= methods_.size()) {
|
||||
throw std::invalid_argument(
|
||||
folly::to<std::string>("methodId ", reactMethodId, " out of range [0..", methods_.size(), "]"));
|
||||
}
|
||||
CHECK(methods_[reactMethodId].isSyncHook()) << "Trying to invoke a asynchronous method as synchronous hook";
|
||||
return invokeInner(token, reactMethodId, std::move(params));
|
||||
}
|
||||
|
||||
MethodCallResult NewJavaNativeModule::invokeInner(ExecutorToken token, unsigned int reactMethodId, folly::dynamic&& params) {
|
||||
return methods_[reactMethodId].invoke(instance_, module_.get(), token, params);
|
||||
}
|
||||
|
||||
jni::local_ref<JReflectMethod::javaobject> JMethodDescriptor::getMethod() const {
|
||||
static auto method = javaClassStatic()->getField<JReflectMethod::javaobject>("method");
|
||||
return getFieldValue(method);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,83 @@
|
|||
// Copyright 2004-present Facebook. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cxxreact/NativeModule.h>
|
||||
#include <fb/fbjni.h>
|
||||
|
||||
#include "MethodInvoker.h"
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
class Instance;
|
||||
|
||||
struct JMethodDescriptor : public jni::JavaClass<JMethodDescriptor> {
|
||||
static constexpr auto kJavaDescriptor =
|
||||
"Lcom/facebook/react/cxxbridge/JavaModuleWrapper$MethodDescriptor;";
|
||||
|
||||
jni::local_ref<JReflectMethod::javaobject> getMethod() const;
|
||||
std::string getSignature() const;
|
||||
std::string getName() const;
|
||||
std::string getType() const;
|
||||
};
|
||||
|
||||
struct JavaModuleWrapper : jni::JavaClass<JavaModuleWrapper> {
|
||||
static constexpr auto kJavaDescriptor = "Lcom/facebook/react/cxxbridge/JavaModuleWrapper;";
|
||||
|
||||
jni::local_ref<JBaseJavaModule::javaobject> getModule() {
|
||||
static auto getModule = javaClassStatic()->getMethod<JBaseJavaModule::javaobject()>("getModule");
|
||||
return getModule(self());
|
||||
}
|
||||
|
||||
jni::local_ref<jni::JList<JMethodDescriptor::javaobject>::javaobject> getMethodDescriptors() {
|
||||
static auto getMethods = getClass()
|
||||
->getMethod<jni::JList<JMethodDescriptor::javaobject>::javaobject()>("getMethodDescriptors");
|
||||
return getMethods(self());
|
||||
}
|
||||
};
|
||||
|
||||
class JavaNativeModule : public NativeModule {
|
||||
public:
|
||||
JavaNativeModule(
|
||||
std::weak_ptr<Instance> instance,
|
||||
jni::alias_ref<JavaModuleWrapper::javaobject> wrapper)
|
||||
: instance_(std::move(instance)), wrapper_(make_global(wrapper)) {}
|
||||
|
||||
std::string getName() override;
|
||||
folly::dynamic getConstants() override;
|
||||
std::vector<MethodDescriptor> getMethods() override;
|
||||
bool supportsWebWorkers() override;
|
||||
void invoke(ExecutorToken token, unsigned int reactMethodId, folly::dynamic&& params) override;
|
||||
MethodCallResult callSerializableNativeHook(ExecutorToken token, unsigned int reactMethodId, folly::dynamic&& params) override;
|
||||
|
||||
private:
|
||||
std::weak_ptr<Instance> instance_;
|
||||
jni::global_ref<JavaModuleWrapper::javaobject> wrapper_;
|
||||
};
|
||||
|
||||
// Experimental new implementation that uses direct method invocation
|
||||
class NewJavaNativeModule : public NativeModule {
|
||||
public:
|
||||
NewJavaNativeModule(
|
||||
std::weak_ptr<Instance> instance,
|
||||
jni::alias_ref<JavaModuleWrapper::javaobject> wrapper);
|
||||
|
||||
std::string getName() override;
|
||||
std::vector<MethodDescriptor> getMethods() override;
|
||||
folly::dynamic getConstants() override;
|
||||
bool supportsWebWorkers() override;
|
||||
void invoke(ExecutorToken token, unsigned int reactMethodId, folly::dynamic&& params) override;
|
||||
MethodCallResult callSerializableNativeHook(ExecutorToken token, unsigned int reactMethodId, folly::dynamic&& params) override;
|
||||
|
||||
private:
|
||||
std::weak_ptr<Instance> instance_;
|
||||
jni::global_ref<JavaModuleWrapper::javaobject> wrapper_;
|
||||
jni::global_ref<JBaseJavaModule::javaobject> module_;
|
||||
std::vector<MethodInvoker> methods_;
|
||||
std::vector<MethodDescriptor> methodDescriptors_;
|
||||
|
||||
MethodCallResult invokeInner(ExecutorToken token, unsigned int reactMethodId, folly::dynamic&& params);
|
||||
};
|
||||
|
||||
}}
|
|
@ -4,18 +4,29 @@
|
|||
|
||||
#include <vector>
|
||||
|
||||
#include <cxxreact/ExecutorToken.h>
|
||||
#include <fb/fbjni.h>
|
||||
#include <folly/dynamic.h>
|
||||
|
||||
#include <cxxreact/ExecutorToken.h>
|
||||
|
||||
#include "ModuleRegistryHolder.h"
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
class Instance;
|
||||
|
||||
struct JReflectMethod : public jni::JavaClass<JReflectMethod> {
|
||||
static constexpr auto kJavaDescriptor = "Ljava/lang/reflect/Method;";
|
||||
|
||||
jmethodID getMethodID() {
|
||||
auto id = jni::Environment::current()->FromReflectedMethod(self());
|
||||
jni::throwPendingJniExceptionAsCppException();
|
||||
return id;
|
||||
}
|
||||
};
|
||||
|
||||
struct JBaseJavaModule : public jni::JavaClass<JBaseJavaModule> {
|
||||
static constexpr auto kJavaDescriptor = "Lcom/facebook/react/bridge/BaseJavaModule;";
|
||||
};
|
||||
|
||||
class MethodInvoker {
|
||||
public:
|
||||
MethodInvoker(jni::alias_ref<JReflectMethod::javaobject> method, std::string signature, std::string traceName, bool isSync);
|
||||
|
|
|
@ -1,216 +0,0 @@
|
|||
// Copyright 2004-present Facebook. All Rights Reserved.
|
||||
|
||||
#include "ModuleRegistryHolder.h"
|
||||
|
||||
#include <folly/json.h>
|
||||
|
||||
#include <fb/fbjni.h>
|
||||
|
||||
#include <cxxreact/CxxModule.h>
|
||||
#include <cxxreact/CxxNativeModule.h>
|
||||
#include <cxxreact/Instance.h>
|
||||
#include <cxxreact/JsArgumentHelpers.h>
|
||||
#include <cxxreact/NativeModule.h>
|
||||
|
||||
#include "CatalystInstanceImpl.h"
|
||||
#include "MethodInvoker.h"
|
||||
#include "ReadableNativeArray.h"
|
||||
|
||||
using facebook::xplat::module::CxxModule;
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
namespace {
|
||||
|
||||
class JavaNativeModule : public NativeModule {
|
||||
public:
|
||||
JavaNativeModule(jni::alias_ref<JavaModuleWrapper::javaobject> wrapper)
|
||||
: wrapper_(make_global(wrapper)) {}
|
||||
|
||||
std::string getName() override {
|
||||
static auto getNameMethod = wrapper_->getClass()->getMethod<jstring()>("getName");
|
||||
return getNameMethod(wrapper_)->toStdString();
|
||||
}
|
||||
|
||||
std::vector<MethodDescriptor> getMethods() override {
|
||||
static auto getMDMethod =
|
||||
wrapper_->getClass()->getMethod<jni::JList<JMethodDescriptor::javaobject>::javaobject()>(
|
||||
"getMethodDescriptors");
|
||||
|
||||
std::vector<MethodDescriptor> ret;
|
||||
auto descs = getMDMethod(wrapper_);
|
||||
for (const auto& desc : *descs) {
|
||||
static auto nameField =
|
||||
JMethodDescriptor::javaClassStatic()->getField<jstring>("name");
|
||||
static auto typeField =
|
||||
JMethodDescriptor::javaClassStatic()->getField<jstring>("type");
|
||||
|
||||
ret.emplace_back(
|
||||
desc->getFieldValue(nameField)->toStdString(),
|
||||
desc->getFieldValue(typeField)->toStdString()
|
||||
);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
folly::dynamic getConstants() override {
|
||||
static auto constantsMethod =
|
||||
wrapper_->getClass()->getMethod<NativeArray::javaobject()>("getConstants");
|
||||
auto constants = constantsMethod(wrapper_);
|
||||
if (!constants) {
|
||||
return nullptr;
|
||||
} else {
|
||||
// See JavaModuleWrapper#getConstants for the other side of this hack.
|
||||
return cthis(constants)->array[0];
|
||||
}
|
||||
}
|
||||
|
||||
virtual bool supportsWebWorkers() override {
|
||||
static auto supportsWebWorkersMethod =
|
||||
wrapper_->getClass()->getMethod<jboolean()>("supportsWebWorkers");
|
||||
return supportsWebWorkersMethod(wrapper_);
|
||||
}
|
||||
|
||||
void invoke(ExecutorToken token, unsigned int reactMethodId, folly::dynamic&& params) override {
|
||||
static auto invokeMethod =
|
||||
wrapper_->getClass()->getMethod<void(JExecutorToken::javaobject, jint, ReadableNativeArray::javaobject)>("invoke");
|
||||
invokeMethod(wrapper_, JExecutorToken::extractJavaPartFromToken(token).get(), static_cast<jint>(reactMethodId),
|
||||
ReadableNativeArray::newObjectCxxArgs(std::move(params)).get());
|
||||
}
|
||||
|
||||
MethodCallResult callSerializableNativeHook(ExecutorToken token, unsigned int reactMethodId, folly::dynamic&& params) override {
|
||||
throw std::runtime_error("Unsupported operation.");
|
||||
}
|
||||
|
||||
private:
|
||||
jni::global_ref<JavaModuleWrapper::javaobject> wrapper_;
|
||||
};
|
||||
|
||||
class NewJavaNativeModule : public NativeModule {
|
||||
public:
|
||||
NewJavaNativeModule(std::weak_ptr<Instance> instance, jni::alias_ref<JavaModuleWrapper::javaobject> wrapper)
|
||||
: instance_(std::move(instance)),
|
||||
wrapper_(make_global(wrapper)),
|
||||
module_(make_global(wrapper->getModule())) {
|
||||
auto descs = wrapper_->getMethodDescriptors();
|
||||
std::string moduleName = getName();
|
||||
methods_.reserve(descs->size());
|
||||
|
||||
for (const auto& desc : *descs) {
|
||||
auto type = desc->getType();
|
||||
auto name = desc->getName();
|
||||
methods_.emplace_back(
|
||||
desc->getMethod(),
|
||||
desc->getSignature(),
|
||||
moduleName + "." + name,
|
||||
type == "syncHook");
|
||||
|
||||
methodDescriptors_.emplace_back(name, type);
|
||||
}
|
||||
}
|
||||
|
||||
std::string getName() override {
|
||||
static auto getNameMethod = wrapper_->getClass()->getMethod<jstring()>("getName");
|
||||
return getNameMethod(wrapper_)->toStdString();
|
||||
}
|
||||
|
||||
std::vector<MethodDescriptor> getMethods() override {
|
||||
return methodDescriptors_;
|
||||
}
|
||||
|
||||
folly::dynamic getConstants() override {
|
||||
static auto constantsMethod =
|
||||
wrapper_->getClass()->getMethod<NativeArray::javaobject()>("getConstants");
|
||||
auto constants = constantsMethod(wrapper_);
|
||||
if (!constants) {
|
||||
return nullptr;
|
||||
} else {
|
||||
// See JavaModuleWrapper#getConstants for the other side of this hack.
|
||||
return cthis(constants)->array[0];
|
||||
}
|
||||
}
|
||||
|
||||
virtual bool supportsWebWorkers() override {
|
||||
static auto supportsWebWorkersMethod =
|
||||
wrapper_->getClass()->getMethod<jboolean()>("supportsWebWorkers");
|
||||
return supportsWebWorkersMethod(wrapper_);
|
||||
}
|
||||
|
||||
void invoke(ExecutorToken token, unsigned int reactMethodId, folly::dynamic&& params) override {
|
||||
if (reactMethodId >= methods_.size()) {
|
||||
throw std::invalid_argument(
|
||||
folly::to<std::string>("methodId ", reactMethodId, " out of range [0..", methods_.size(), "]"));
|
||||
}
|
||||
CHECK(!methods_[reactMethodId].isSyncHook()) << "Trying to invoke a synchronous hook asynchronously";
|
||||
invokeInner(token, reactMethodId, std::move(params));
|
||||
}
|
||||
|
||||
MethodCallResult callSerializableNativeHook(ExecutorToken token, unsigned int reactMethodId, folly::dynamic&& params) override {
|
||||
if (reactMethodId >= methods_.size()) {
|
||||
throw std::invalid_argument(
|
||||
folly::to<std::string>("methodId ", reactMethodId, " out of range [0..", methods_.size(), "]"));
|
||||
}
|
||||
CHECK(methods_[reactMethodId].isSyncHook()) << "Trying to invoke a asynchronous method as synchronous hook";
|
||||
return invokeInner(token, reactMethodId, std::move(params));
|
||||
}
|
||||
|
||||
private:
|
||||
std::weak_ptr<Instance> instance_;
|
||||
jni::global_ref<JavaModuleWrapper::javaobject> wrapper_;
|
||||
jni::global_ref<JBaseJavaModule::javaobject> module_;
|
||||
std::vector<MethodInvoker> methods_;
|
||||
std::vector<MethodDescriptor> methodDescriptors_;
|
||||
|
||||
MethodCallResult invokeInner(ExecutorToken token, unsigned int reactMethodId, folly::dynamic&& params) {
|
||||
return methods_[reactMethodId].invoke(instance_, module_.get(), token, params);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
jni::local_ref<JReflectMethod::javaobject> JMethodDescriptor::getMethod() const {
|
||||
static auto method = javaClassStatic()->getField<JReflectMethod::javaobject>("method");
|
||||
return getFieldValue(method);
|
||||
}
|
||||
|
||||
std::string JMethodDescriptor::getSignature() const {
|
||||
static auto signature = javaClassStatic()->getField<jstring>("signature");
|
||||
return getFieldValue(signature)->toStdString();
|
||||
}
|
||||
|
||||
std::string JMethodDescriptor::getName() const {
|
||||
static auto name = javaClassStatic()->getField<jstring>("name");
|
||||
return getFieldValue(name)->toStdString();
|
||||
}
|
||||
|
||||
std::string JMethodDescriptor::getType() const {
|
||||
static auto type = javaClassStatic()->getField<jstring>("type");
|
||||
return getFieldValue(type)->toStdString();
|
||||
}
|
||||
|
||||
void ModuleRegistryHolder::registerNatives() {
|
||||
registerHybrid({
|
||||
makeNativeMethod("initHybrid", ModuleRegistryHolder::initHybrid),
|
||||
});
|
||||
}
|
||||
|
||||
ModuleRegistryHolder::ModuleRegistryHolder(
|
||||
CatalystInstanceImpl* catalystInstanceImpl,
|
||||
jni::alias_ref<jni::JCollection<JavaModuleWrapper::javaobject>::javaobject> javaModules,
|
||||
jni::alias_ref<jni::JCollection<CxxModuleWrapper::javaobject>::javaobject> cxxModules) {
|
||||
std::vector<std::unique_ptr<NativeModule>> modules;
|
||||
std::weak_ptr<Instance> winstance(catalystInstanceImpl->getInstance());
|
||||
for (const auto& jm : *javaModules) {
|
||||
modules.emplace_back(folly::make_unique<JavaNativeModule>(jm));
|
||||
}
|
||||
for (const auto& cm : *cxxModules) {
|
||||
modules.emplace_back(
|
||||
folly::make_unique<CxxNativeModule>(winstance, std::move(cthis(cm)->getModule())));
|
||||
}
|
||||
|
||||
registry_ = std::make_shared<ModuleRegistry>(std::move(modules));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -1,83 +0,0 @@
|
|||
// Copyright 2004-present Facebook. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cxxreact/ModuleRegistry.h>
|
||||
#include <fb/fbjni.h>
|
||||
|
||||
#include "CxxModuleWrapper.h"
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
class Instance;
|
||||
class CatalystInstanceImpl;
|
||||
|
||||
struct JReflectMethod : public jni::JavaClass<JReflectMethod> {
|
||||
static constexpr auto kJavaDescriptor = "Ljava/lang/reflect/Method;";
|
||||
|
||||
jmethodID getMethodID() {
|
||||
auto id = jni::Environment::current()->FromReflectedMethod(self());
|
||||
jni::throwPendingJniExceptionAsCppException();
|
||||
return id;
|
||||
}
|
||||
};
|
||||
|
||||
struct JMethodDescriptor : public jni::JavaClass<JMethodDescriptor> {
|
||||
static constexpr auto kJavaDescriptor =
|
||||
"Lcom/facebook/react/cxxbridge/JavaModuleWrapper$MethodDescriptor;";
|
||||
|
||||
jni::local_ref<JReflectMethod::javaobject> getMethod() const;
|
||||
std::string getSignature() const;
|
||||
std::string getName() const;
|
||||
std::string getType() const;
|
||||
};
|
||||
|
||||
struct JBaseJavaModule : public jni::JavaClass<JBaseJavaModule> {
|
||||
static constexpr auto kJavaDescriptor = "Lcom/facebook/react/bridge/BaseJavaModule;";
|
||||
};
|
||||
|
||||
struct JavaModuleWrapper : jni::JavaClass<JavaModuleWrapper> {
|
||||
static constexpr auto kJavaDescriptor = "Lcom/facebook/react/cxxbridge/JavaModuleWrapper;";
|
||||
|
||||
jni::local_ref<JBaseJavaModule::javaobject> getModule() {
|
||||
static auto getModule = javaClassStatic()->getMethod<JBaseJavaModule::javaobject()>("getModule");
|
||||
return getModule(self());
|
||||
}
|
||||
|
||||
jni::local_ref<jni::JList<JMethodDescriptor::javaobject>::javaobject> getMethodDescriptors() {
|
||||
static auto getMethods =
|
||||
getClass()->getMethod<jni::JList<JMethodDescriptor::javaobject>::javaobject()>("getMethodDescriptors");
|
||||
return getMethods(self());
|
||||
}
|
||||
};
|
||||
|
||||
class ModuleRegistryHolder : public jni::HybridClass<ModuleRegistryHolder> {
|
||||
public:
|
||||
static constexpr auto kJavaDescriptor = "Lcom/facebook/react/cxxbridge/ModuleRegistryHolder;";
|
||||
|
||||
std::shared_ptr<ModuleRegistry> getModuleRegistry() {
|
||||
return registry_;
|
||||
}
|
||||
|
||||
static jni::local_ref<jhybriddata> initHybrid(
|
||||
jni::alias_ref<jclass>,
|
||||
CatalystInstanceImpl* catalystInstanceImpl,
|
||||
jni::alias_ref<jni::JCollection<JavaModuleWrapper::javaobject>::javaobject> javaModules,
|
||||
jni::alias_ref<jni::JCollection<CxxModuleWrapper::javaobject>::javaobject> cxxModules) {
|
||||
return makeCxxInstance(catalystInstanceImpl, javaModules, cxxModules);
|
||||
}
|
||||
|
||||
static void registerNatives();
|
||||
|
||||
private:
|
||||
friend HybridBase;
|
||||
ModuleRegistryHolder(
|
||||
CatalystInstanceImpl* catalystInstanceImpl,
|
||||
jni::alias_ref<jni::JCollection<JavaModuleWrapper::javaobject>::javaobject> javaModules,
|
||||
jni::alias_ref<jni::JCollection<CxxModuleWrapper::javaobject>::javaobject> cxxModules);
|
||||
|
||||
std::shared_ptr<ModuleRegistry> registry_;
|
||||
};
|
||||
|
||||
}}
|
|
@ -11,7 +11,6 @@
|
|||
#include "JavaScriptExecutorHolder.h"
|
||||
#include "JSCPerfLogging.h"
|
||||
#include "JSLoader.h"
|
||||
#include "ModuleRegistryHolder.h"
|
||||
#include "ProxyExecutor.h"
|
||||
#include "WebWorkers.h"
|
||||
#include "JCallback.h"
|
||||
|
@ -160,7 +159,6 @@ extern "C" JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) {
|
|||
JSCJavaScriptExecutorHolder::registerNatives();
|
||||
ProxyJavaScriptExecutorHolder::registerNatives();
|
||||
CatalystInstanceImpl::registerNatives();
|
||||
ModuleRegistryHolder::registerNatives();
|
||||
CxxModuleWrapper::registerNatives();
|
||||
JCallbackImpl::registerNatives();
|
||||
#ifdef WITH_INSPECTOR
|
||||
|
|
Loading…
Reference in New Issue