Summary:
Ran `arc f` against some CPP files to be modified with the next diff
to reduce the churn on it.

## Changelog

[Android] [Changed] - Formatted cpp/h code with clang-format

Reviewed By: javache

Differential Revision: D19371785

fbshipit-source-id: b7f7b92c4cb9ec7f8da728bb577db29cf11fbb39
This commit is contained in:
Pascal Hartig 2020-01-14 01:02:22 -08:00 коммит произвёл Facebook Github Bot
Родитель 8d57691a60
Коммит d5ba113bb2
44 изменённых файлов: 914 добавлений и 648 удалений

Просмотреть файл

@ -16,9 +16,9 @@
#include <jsi/JSIDynamic.h> #include <jsi/JSIDynamic.h>
#include <jsi/jsi.h> #include <jsi/jsi.h>
#include <react/components/scrollview/ScrollViewProps.h> #include <react/components/scrollview/ScrollViewProps.h>
#include <react/core/conversions.h>
#include <react/core/EventBeat.h> #include <react/core/EventBeat.h>
#include <react/core/EventEmitter.h> #include <react/core/EventEmitter.h>
#include <react/core/conversions.h>
#include <react/debug/SystraceSection.h> #include <react/debug/SystraceSection.h>
#include <react/uimanager/ComponentDescriptorFactory.h> #include <react/uimanager/ComponentDescriptorFactory.h>
#include <react/uimanager/Scheduler.h> #include <react/uimanager/Scheduler.h>
@ -73,7 +73,6 @@ std::shared_ptr<Scheduler> Binding::getScheduler() {
return scheduler_; return scheduler_;
} }
void Binding::startSurface( void Binding::startSurface(
jint surfaceId, jint surfaceId,
jni::alias_ref<jstring> moduleName, jni::alias_ref<jstring> moduleName,
@ -89,7 +88,11 @@ void Binding::startSurface(
LayoutContext context; LayoutContext context;
context.pointScaleFactor = pointScaleFactor_; context.pointScaleFactor = pointScaleFactor_;
scheduler->startSurface( scheduler->startSurface(
surfaceId, moduleName->toStdString(), initialProps->consume(), {}, context); surfaceId,
moduleName->toStdString(),
initialProps->consume(),
{},
context);
} }
void Binding::startSurfaceWithConstraints( void Binding::startSurfaceWithConstraints(
@ -200,10 +203,12 @@ void Binding::installFabricUIManager(
LOG(WARNING) << "Binding::installFabricUIManager() was called (address: " LOG(WARNING) << "Binding::installFabricUIManager() was called (address: "
<< this << ")."; << this << ").";
// Use std::lock and std::adopt_lock to prevent deadlocks by locking mutexes at the same time // Use std::lock and std::adopt_lock to prevent deadlocks by locking mutexes
// at the same time
std::lock(schedulerMutex_, javaUIManagerMutex_); std::lock(schedulerMutex_, javaUIManagerMutex_);
std::lock_guard<std::mutex> schedulerLock(schedulerMutex_, std::adopt_lock); std::lock_guard<std::mutex> schedulerLock(schedulerMutex_, std::adopt_lock);
std::lock_guard<std::mutex> uiManagerLock(javaUIManagerMutex_, std::adopt_lock); std::lock_guard<std::mutex> uiManagerLock(
javaUIManagerMutex_, std::adopt_lock);
javaUIManager_ = make_global(javaUIManager); javaUIManager_ = make_global(javaUIManager);
@ -226,13 +231,15 @@ void Binding::installFabricUIManager(
// TODO: T31905686 Create synchronous Event Beat // TODO: T31905686 Create synchronous Event Beat
jni::global_ref<jobject> localJavaUIManager = javaUIManager_; jni::global_ref<jobject> localJavaUIManager = javaUIManager_;
EventBeat::Factory synchronousBeatFactory = EventBeat::Factory synchronousBeatFactory =
[eventBeatManager, runtimeExecutor, localJavaUIManager](EventBeat::SharedOwnerBox const &ownerBox) { [eventBeatManager, runtimeExecutor, localJavaUIManager](
EventBeat::SharedOwnerBox const &ownerBox) {
return std::make_unique<AsyncEventBeat>( return std::make_unique<AsyncEventBeat>(
ownerBox, eventBeatManager, runtimeExecutor, localJavaUIManager); ownerBox, eventBeatManager, runtimeExecutor, localJavaUIManager);
}; };
EventBeat::Factory asynchronousBeatFactory = EventBeat::Factory asynchronousBeatFactory =
[eventBeatManager, runtimeExecutor, localJavaUIManager](EventBeat::SharedOwnerBox const &ownerBox) { [eventBeatManager, runtimeExecutor, localJavaUIManager](
EventBeat::SharedOwnerBox const &ownerBox) {
return std::make_unique<AsyncEventBeat>( return std::make_unique<AsyncEventBeat>(
ownerBox, eventBeatManager, runtimeExecutor, localJavaUIManager); ownerBox, eventBeatManager, runtimeExecutor, localJavaUIManager);
}; };
@ -244,12 +251,14 @@ void Binding::installFabricUIManager(
// Keep reference to config object and cache some feature flags here // Keep reference to config object and cache some feature flags here
reactNativeConfig_ = config; reactNativeConfig_ = config;
shouldCollateRemovesAndDeletes_ = reactNativeConfig_->getBool("react_fabric:enable_removedelete_collation_android"); shouldCollateRemovesAndDeletes_ = reactNativeConfig_->getBool(
"react_fabric:enable_removedelete_collation_android");
collapseDeleteCreateMountingInstructions_ = reactNativeConfig_->getBool( collapseDeleteCreateMountingInstructions_ = reactNativeConfig_->getBool(
"react_fabric:enabled_collapse_delete_create_mounting_instructions"); "react_fabric:enabled_collapse_delete_create_mounting_instructions");
; ;
disablePreallocateViews_ = reactNativeConfig_->getBool("react_fabric:disabled_view_preallocation_android"); disablePreallocateViews_ = reactNativeConfig_->getBool(
"react_fabric:disabled_view_preallocation_android");
auto toolbox = SchedulerToolbox{}; auto toolbox = SchedulerToolbox{};
toolbox.contextContainer = contextContainer; toolbox.contextContainer = contextContainer;
@ -263,10 +272,12 @@ void Binding::installFabricUIManager(
void Binding::uninstallFabricUIManager() { void Binding::uninstallFabricUIManager() {
LOG(WARNING) << "Binding::uninstallFabricUIManager() was called (address: " LOG(WARNING) << "Binding::uninstallFabricUIManager() was called (address: "
<< this << ")."; << this << ").";
// Use std::lock and std::adopt_lock to prevent deadlocks by locking mutexes at the same time // Use std::lock and std::adopt_lock to prevent deadlocks by locking mutexes
// at the same time
std::lock(schedulerMutex_, javaUIManagerMutex_); std::lock(schedulerMutex_, javaUIManagerMutex_);
std::lock_guard<std::mutex> schedulerLock(schedulerMutex_, std::adopt_lock); std::lock_guard<std::mutex> schedulerLock(schedulerMutex_, std::adopt_lock);
std::lock_guard<std::mutex> uiManagerLock(javaUIManagerMutex_, std::adopt_lock); std::lock_guard<std::mutex> uiManagerLock(
javaUIManagerMutex_, std::adopt_lock);
scheduler_ = nullptr; scheduler_ = nullptr;
javaUIManager_ = nullptr; javaUIManager_ = nullptr;
@ -279,8 +290,9 @@ inline local_ref<ReadableMap::javaobject> castReadableMap(
} }
inline local_ref<ReadableArray::javaobject> castReadableArray( inline local_ref<ReadableArray::javaobject> castReadableArray(
local_ref<ReadableNativeArray::javaobject> nativeArray) { local_ref<ReadableNativeArray::javaobject> nativeArray) {
return make_local(reinterpret_cast<ReadableArray::javaobject>(nativeArray.get())); return make_local(
reinterpret_cast<ReadableArray::javaobject>(nativeArray.get()));
} }
// TODO: this method will be removed when binding for components are code-gen // TODO: this method will be removed when binding for components are code-gen
@ -351,8 +363,8 @@ local_ref<JMountItem::javaobject> createUpdateLayoutMountItem(
oldChildShadowView.layoutMetrics != newChildShadowView.layoutMetrics) { oldChildShadowView.layoutMetrics != newChildShadowView.layoutMetrics) {
static auto updateLayoutInstruction = static auto updateLayoutInstruction =
jni::findClassStatic(UIManagerJavaDescriptor) jni::findClassStatic(UIManagerJavaDescriptor)
->getMethod<alias_ref<JMountItem>(jint, jint, jint, jint, jint, jint)>( ->getMethod<alias_ref<JMountItem>(
"updateLayoutMountItem"); jint, jint, jint, jint, jint, jint)>("updateLayoutMountItem");
auto layoutMetrics = newChildShadowView.layoutMetrics; auto layoutMetrics = newChildShadowView.layoutMetrics;
auto pointScaleFactor = layoutMetrics.pointScaleFactor; auto pointScaleFactor = layoutMetrics.pointScaleFactor;
auto frame = layoutMetrics.frame; auto frame = layoutMetrics.frame;
@ -361,7 +373,8 @@ local_ref<JMountItem::javaobject> createUpdateLayoutMountItem(
int y = round(frame.origin.y * pointScaleFactor); int y = round(frame.origin.y * pointScaleFactor);
int w = round(frame.size.width * pointScaleFactor); int w = round(frame.size.width * pointScaleFactor);
int h = round(frame.size.height * pointScaleFactor); int h = round(frame.size.height * pointScaleFactor);
auto layoutDirection = toInt(newChildShadowView.layoutMetrics.layoutDirection); auto layoutDirection =
toInt(newChildShadowView.layoutMetrics.layoutDirection);
return updateLayoutInstruction( return updateLayoutInstruction(
javaUIManager, newChildShadowView.tag, x, y, w, h, layoutDirection); javaUIManager, newChildShadowView.tag, x, y, w, h, layoutDirection);
} }
@ -370,20 +383,20 @@ local_ref<JMountItem::javaobject> createUpdateLayoutMountItem(
} }
local_ref<JMountItem::javaobject> createUpdatePaddingMountItem( local_ref<JMountItem::javaobject> createUpdatePaddingMountItem(
const jni::global_ref<jobject> &javaUIManager, const jni::global_ref<jobject> &javaUIManager,
const ShadowViewMutation &mutation) { const ShadowViewMutation &mutation) {
auto oldChildShadowView = mutation.oldChildShadowView; auto oldChildShadowView = mutation.oldChildShadowView;
auto newChildShadowView = mutation.newChildShadowView; auto newChildShadowView = mutation.newChildShadowView;
if (oldChildShadowView.layoutMetrics.contentInsets == newChildShadowView.layoutMetrics.contentInsets) { if (oldChildShadowView.layoutMetrics.contentInsets ==
newChildShadowView.layoutMetrics.contentInsets) {
return nullptr; return nullptr;
} }
static auto updateLayoutInstruction = static auto updateLayoutInstruction =
jni::findClassStatic(UIManagerJavaDescriptor) jni::findClassStatic(UIManagerJavaDescriptor)
->getMethod<alias_ref<JMountItem>(jint, jint, jint, jint, jint)>( ->getMethod<alias_ref<JMountItem>(jint, jint, jint, jint, jint)>(
"updatePaddingMountItem"); "updatePaddingMountItem");
auto layoutMetrics = newChildShadowView.layoutMetrics; auto layoutMetrics = newChildShadowView.layoutMetrics;
auto pointScaleFactor = layoutMetrics.pointScaleFactor; auto pointScaleFactor = layoutMetrics.pointScaleFactor;
@ -394,7 +407,8 @@ local_ref<JMountItem::javaobject> createUpdatePaddingMountItem(
int right = round(contentInsets.right * pointScaleFactor); int right = round(contentInsets.right * pointScaleFactor);
int bottom = round(contentInsets.bottom * pointScaleFactor); int bottom = round(contentInsets.bottom * pointScaleFactor);
return updateLayoutInstruction(javaUIManager, newChildShadowView.tag, left, top, right, bottom); return updateLayoutInstruction(
javaUIManager, newChildShadowView.tag, left, top, right, bottom);
} }
local_ref<JMountItem::javaobject> createInsertMountItem( local_ref<JMountItem::javaobject> createInsertMountItem(
@ -439,9 +453,9 @@ local_ref<JMountItem::javaobject> createUpdateStateMountItem(
const jni::global_ref<jobject> &javaUIManager, const jni::global_ref<jobject> &javaUIManager,
const ShadowViewMutation &mutation) { const ShadowViewMutation &mutation) {
static auto updateStateInstruction = static auto updateStateInstruction =
jni::findClassStatic(UIManagerJavaDescriptor) jni::findClassStatic(UIManagerJavaDescriptor)
->getMethod<alias_ref<JMountItem>(jint, jobject)>( ->getMethod<alias_ref<JMountItem>(jint, jobject)>(
"updateStateMountItem"); "updateStateMountItem");
auto state = mutation.newChildShadowView.state; auto state = mutation.newChildShadowView.state;
@ -456,9 +470,9 @@ local_ref<JMountItem::javaobject> createUpdateStateMountItem(
} }
return updateStateInstruction( return updateStateInstruction(
javaUIManager, javaUIManager,
mutation.newChildShadowView.tag, mutation.newChildShadowView.tag,
(javaStateWrapper != nullptr ? javaStateWrapper.get() : nullptr)); (javaStateWrapper != nullptr ? javaStateWrapper.get() : nullptr));
} }
local_ref<JMountItem::javaobject> createRemoveMountItem( local_ref<JMountItem::javaobject> createRemoveMountItem(
@ -487,14 +501,13 @@ local_ref<JMountItem::javaobject> createDeleteMountItem(
} }
local_ref<JMountItem::javaobject> createRemoveAndDeleteMultiMountItem( local_ref<JMountItem::javaobject> createRemoveAndDeleteMultiMountItem(
const jni::global_ref<jobject> &javaUIManager, const jni::global_ref<jobject> &javaUIManager,
const std::vector<RemoveDeleteMetadata> &metadata) { const std::vector<RemoveDeleteMetadata> &metadata) {
auto env = Environment::current(); auto env = Environment::current();
auto removeAndDeleteArray = env->NewIntArray(metadata.size()*4); auto removeAndDeleteArray = env->NewIntArray(metadata.size() * 4);
int position = 0; int position = 0;
jint temp[4]; jint temp[4];
for (const auto& x : metadata) { for (const auto &x : metadata) {
temp[0] = x.tag; temp[0] = x.tag;
temp[1] = x.parentTag; temp[1] = x.parentTag;
temp[2] = x.index; temp[2] = x.index;
@ -504,30 +517,34 @@ local_ref<JMountItem::javaobject> createRemoveAndDeleteMultiMountItem(
} }
static auto removeDeleteMultiInstruction = static auto removeDeleteMultiInstruction =
jni::findClassStatic(UIManagerJavaDescriptor) jni::findClassStatic(UIManagerJavaDescriptor)
->getMethod<alias_ref<JMountItem>(jintArray)>("removeDeleteMultiMountItem"); ->getMethod<alias_ref<JMountItem>(jintArray)>(
"removeDeleteMultiMountItem");
auto ret = removeDeleteMultiInstruction(javaUIManager, removeAndDeleteArray); auto ret = removeDeleteMultiInstruction(javaUIManager, removeAndDeleteArray);
// It is not strictly necessary to manually delete the ref here, in this particular case. // It is not strictly necessary to manually delete the ref here, in this
// If JNI memory is being allocated in a loop, it's easy to overload the localref table // particular case. If JNI memory is being allocated in a loop, it's easy to
// and crash; this is not possible in this case since the JNI would automatically clear this // overload the localref table and crash; this is not possible in this case
// ref when it goes out of scope, anyway. However, this is being left here as a reminder of // since the JNI would automatically clear this ref when it goes out of scope,
// good hygiene and to be careful with JNI-allocated memory in general. // anyway. However, this is being left here as a reminder of good hygiene and
// to be careful with JNI-allocated memory in general.
env->DeleteLocalRef(removeAndDeleteArray); env->DeleteLocalRef(removeAndDeleteArray);
return ret; return ret;
} }
// TODO T48019320: because we pass initial props and state to the Create (and preallocate) mount instruction, // TODO T48019320: because we pass initial props and state to the Create (and
// we technically don't need to pass the first Update to any components. Dedupe? // preallocate) mount instruction, we technically don't need to pass the first
// Update to any components. Dedupe?
local_ref<JMountItem::javaobject> createCreateMountItem( local_ref<JMountItem::javaobject> createCreateMountItem(
const jni::global_ref<jobject> &javaUIManager, const jni::global_ref<jobject> &javaUIManager,
const ShadowViewMutation &mutation, const ShadowViewMutation &mutation,
const Tag surfaceId) { const Tag surfaceId) {
static auto createJavaInstruction = static auto createJavaInstruction =
jni::findClassStatic(UIManagerJavaDescriptor) jni::findClassStatic(UIManagerJavaDescriptor)
->getMethod<alias_ref<JMountItem>(jstring, ReadableMap::javaobject, jobject, jint, jint, jboolean)>( ->getMethod<alias_ref<JMountItem>(
jstring, ReadableMap::javaobject, jobject, jint, jint, jboolean)>(
"createMountItem"); "createMountItem");
auto newChildShadowView = mutation.newChildShadowView; auto newChildShadowView = mutation.newChildShadowView;
@ -539,7 +556,7 @@ local_ref<JMountItem::javaobject> createCreateMountItem(
newChildShadowView.layoutMetrics != EmptyLayoutMetrics; newChildShadowView.layoutMetrics != EmptyLayoutMetrics;
local_ref<ReadableMap::javaobject> props = castReadableMap( local_ref<ReadableMap::javaobject> props = castReadableMap(
ReadableNativeMap::newObjectCxxArgs(newChildShadowView.props->rawProps)); ReadableNativeMap::newObjectCxxArgs(newChildShadowView.props->rawProps));
// Do not hold onto Java object from C // Do not hold onto Java object from C
// We DO want to hold onto C object from Java, since we don't know the // We DO want to hold onto C object from Java, since we don't know the
@ -570,7 +587,8 @@ void Binding::schedulerDidFinishTransaction(
jni::global_ref<jobject> localJavaUIManager = getJavaUIManager(); jni::global_ref<jobject> localJavaUIManager = getJavaUIManager();
if (!localJavaUIManager) { if (!localJavaUIManager) {
LOG(ERROR) << "Binding::schedulerDidFinishTransaction: JavaUIManager disappeared"; LOG(ERROR)
<< "Binding::schedulerDidFinishTransaction: JavaUIManager disappeared";
return; return;
} }
@ -651,16 +669,20 @@ void Binding::schedulerDidFinishTransaction(
oldChildShadowView.layoutMetrics == EmptyLayoutMetrics; oldChildShadowView.layoutMetrics == EmptyLayoutMetrics;
// Handle accumulated removals/deletions // Handle accumulated removals/deletions
if (shouldCollateRemovesAndDeletes_ && mutation.type != ShadowViewMutation::Remove && mutation.type != ShadowViewMutation::Delete) { if (shouldCollateRemovesAndDeletes_ &&
mutation.type != ShadowViewMutation::Remove &&
mutation.type != ShadowViewMutation::Delete) {
if (toRemove.size() > 0) { if (toRemove.size() > 0) {
mountItems[position++] = createRemoveAndDeleteMultiMountItem(localJavaUIManager, toRemove); mountItems[position++] =
createRemoveAndDeleteMultiMountItem(localJavaUIManager, toRemove);
toRemove.clear(); toRemove.clear();
} }
} }
switch (mutation.type) { switch (mutation.type) {
case ShadowViewMutation::Create: { case ShadowViewMutation::Create: {
if (disablePreallocateViews_ || mutation.newChildShadowView.props->revision > 1 || if (disablePreallocateViews_ ||
mutation.newChildShadowView.props->revision > 1 ||
deletedViewTags.find(mutation.newChildShadowView.tag) != deletedViewTags.find(mutation.newChildShadowView.tag) !=
deletedViewTags.end()) { deletedViewTags.end()) {
mountItems[position++] = mountItems[position++] =
@ -671,9 +693,15 @@ void Binding::schedulerDidFinishTransaction(
case ShadowViewMutation::Remove: { case ShadowViewMutation::Remove: {
if (!isVirtual) { if (!isVirtual) {
if (shouldCollateRemovesAndDeletes_) { if (shouldCollateRemovesAndDeletes_) {
toRemove.push_back(RemoveDeleteMetadata{mutation.oldChildShadowView.tag, mutation.parentShadowView.tag, mutation.index, true, false}); toRemove.push_back(
RemoveDeleteMetadata{mutation.oldChildShadowView.tag,
mutation.parentShadowView.tag,
mutation.index,
true,
false});
} else { } else {
mountItems[position++] = createRemoveMountItem(localJavaUIManager, mutation); mountItems[position++] =
createRemoveMountItem(localJavaUIManager, mutation);
} }
} }
break; break;
@ -681,15 +709,22 @@ void Binding::schedulerDidFinishTransaction(
case ShadowViewMutation::Delete: { case ShadowViewMutation::Delete: {
if (shouldCollateRemovesAndDeletes_) { if (shouldCollateRemovesAndDeletes_) {
// It is impossible to delete without removing node first // It is impossible to delete without removing node first
const auto& it = std::find_if(std::begin(toRemove), std::end(toRemove), [&mutation](const auto& x) { return x.tag == mutation.oldChildShadowView.tag; }); const auto &it = std::find_if(
std::begin(toRemove),
std::end(toRemove),
[&mutation](const auto &x) {
return x.tag == mutation.oldChildShadowView.tag;
});
if (it != std::end(toRemove)) { if (it != std::end(toRemove)) {
it->shouldDelete = true; it->shouldDelete = true;
} else { } else {
toRemove.push_back(RemoveDeleteMetadata{mutation.oldChildShadowView.tag, -1, -1, false, true}); toRemove.push_back(RemoveDeleteMetadata{
mutation.oldChildShadowView.tag, -1, -1, false, true});
} }
} else { } else {
mountItems[position++] = createDeleteMountItem(localJavaUIManager, mutation); mountItems[position++] =
createDeleteMountItem(localJavaUIManager, mutation);
} }
deletedViewTags.insert(mutation.oldChildShadowView.tag); deletedViewTags.insert(mutation.oldChildShadowView.tag);
@ -719,7 +754,8 @@ void Binding::schedulerDidFinishTransaction(
mountItems[position++] = updateLayoutMountItem; mountItems[position++] = updateLayoutMountItem;
} }
auto updatePaddingMountItem = createUpdatePaddingMountItem(localJavaUIManager, mutation); auto updatePaddingMountItem =
createUpdatePaddingMountItem(localJavaUIManager, mutation);
if (updatePaddingMountItem) { if (updatePaddingMountItem) {
mountItems[position++] = updatePaddingMountItem; mountItems[position++] = updatePaddingMountItem;
} }
@ -741,7 +777,8 @@ void Binding::schedulerDidFinishTransaction(
mountItems[position++] = mountItems[position++] =
createInsertMountItem(localJavaUIManager, mutation); createInsertMountItem(localJavaUIManager, mutation);
if (disablePreallocateViews_ || mutation.newChildShadowView.props->revision > 1 || if (disablePreallocateViews_ ||
mutation.newChildShadowView.props->revision > 1 ||
deletedViewTags.find(mutation.newChildShadowView.tag) != deletedViewTags.find(mutation.newChildShadowView.tag) !=
deletedViewTags.end()) { deletedViewTags.end()) {
mountItems[position++] = mountItems[position++] =
@ -769,7 +806,7 @@ void Binding::schedulerDidFinishTransaction(
// Padding // Padding
auto updatePaddingMountItem = auto updatePaddingMountItem =
createUpdatePaddingMountItem(localJavaUIManager, mutation); createUpdatePaddingMountItem(localJavaUIManager, mutation);
if (updatePaddingMountItem) { if (updatePaddingMountItem) {
mountItems[position++] = updatePaddingMountItem; mountItems[position++] = updatePaddingMountItem;
} }
@ -792,12 +829,14 @@ void Binding::schedulerDidFinishTransaction(
// Handle remaining removals and deletions // Handle remaining removals and deletions
if (shouldCollateRemovesAndDeletes_ && toRemove.size() > 0) { if (shouldCollateRemovesAndDeletes_ && toRemove.size() > 0) {
mountItems[position++] = createRemoveAndDeleteMultiMountItem(localJavaUIManager, toRemove); mountItems[position++] =
createRemoveAndDeleteMultiMountItem(localJavaUIManager, toRemove);
toRemove.clear(); toRemove.clear();
} }
if (position <= 0) { if (position <= 0) {
// If there are no mountItems to be sent to the platform, then it is not necessary to even call. // If there are no mountItems to be sent to the platform, then it is not
// necessary to even call.
return; return;
} }
@ -810,10 +849,17 @@ void Binding::schedulerDidFinishTransaction(
auto batch = createMountItemsBatchContainer( auto batch = createMountItemsBatchContainer(
localJavaUIManager, mountItemsArray.get(), position, commitNumber); localJavaUIManager, mountItemsArray.get(), position, commitNumber);
static auto scheduleMountItem = static auto scheduleMountItem = jni::findClassStatic(UIManagerJavaDescriptor)
jni::findClassStatic(UIManagerJavaDescriptor) ->getMethod<void(
->getMethod<void(JMountItem::javaobject, jint, jlong, jlong, jlong, jlong, jlong, jlong, jlong)>( JMountItem::javaobject,
"scheduleMountItem"); jint,
jlong,
jlong,
jlong,
jlong,
jlong,
jlong,
jlong)>("scheduleMountItem");
long finishTransactionEndTime = monotonicTimeInMilliseconds(); long finishTransactionEndTime = monotonicTimeInMilliseconds();
@ -837,14 +883,14 @@ void Binding::setPixelDensity(float pointScaleFactor) {
void Binding::schedulerDidRequestPreliminaryViewAllocation( void Binding::schedulerDidRequestPreliminaryViewAllocation(
const SurfaceId surfaceId, const SurfaceId surfaceId,
const ShadowView &shadowView) { const ShadowView &shadowView) {
if (disablePreallocateViews_) { if (disablePreallocateViews_) {
return; return;
} }
jni::global_ref<jobject> localJavaUIManager = getJavaUIManager(); jni::global_ref<jobject> localJavaUIManager = getJavaUIManager();
if (!localJavaUIManager) { if (!localJavaUIManager) {
LOG(ERROR) << "Binding::schedulerDidRequestPreliminaryViewAllocation: JavaUIManager disappeared"; LOG(ERROR)
<< "Binding::schedulerDidRequestPreliminaryViewAllocation: JavaUIManager disappeared";
return; return;
} }
@ -881,28 +927,28 @@ void Binding::schedulerDidRequestPreliminaryViewAllocation(
} }
void Binding::schedulerDidDispatchCommand( void Binding::schedulerDidDispatchCommand(
const ShadowView &shadowView, const ShadowView &shadowView,
std::string const &commandName, std::string const &commandName,
folly::dynamic const args) { folly::dynamic const args) {
jni::global_ref<jobject> localJavaUIManager = getJavaUIManager(); jni::global_ref<jobject> localJavaUIManager = getJavaUIManager();
if (!localJavaUIManager) { if (!localJavaUIManager) {
LOG(ERROR) << "Binding::schedulerDidDispatchCommand: JavaUIManager disappeared"; LOG(ERROR)
<< "Binding::schedulerDidDispatchCommand: JavaUIManager disappeared";
return; return;
} }
static auto dispatchCommand = static auto dispatchCommand =
jni::findClassStatic(UIManagerJavaDescriptor) jni::findClassStatic(UIManagerJavaDescriptor)
->getMethod<void( ->getMethod<void(jint, jstring, ReadableArray::javaobject)>(
jint, jstring, ReadableArray::javaobject)>( "dispatchCommand");
"dispatchCommand");
local_ref<JString> command = make_jstring(commandName); local_ref<JString> command = make_jstring(commandName);
local_ref<ReadableArray::javaobject> argsArray = castReadableArray( local_ref<ReadableArray::javaobject> argsArray =
ReadableNativeArray::newObjectCxxArgs(args)); castReadableArray(ReadableNativeArray::newObjectCxxArgs(args));
dispatchCommand(localJavaUIManager, shadowView.tag, command.get(), argsArray.get()); dispatchCommand(
localJavaUIManager, shadowView.tag, command.get(), argsArray.get());
} }
void Binding::schedulerDidSetJSResponder( void Binding::schedulerDidSetJSResponder(
@ -910,7 +956,6 @@ void Binding::schedulerDidSetJSResponder(
const ShadowView &shadowView, const ShadowView &shadowView,
const ShadowView &initialShadowView, const ShadowView &initialShadowView,
bool blockNativeResponder) { bool blockNativeResponder) {
jni::global_ref<jobject> localJavaUIManager = getJavaUIManager(); jni::global_ref<jobject> localJavaUIManager = getJavaUIManager();
if (!localJavaUIManager) { if (!localJavaUIManager) {
LOG(ERROR) << "Binding::schedulerSetJSResponder: JavaUIManager disappeared"; LOG(ERROR) << "Binding::schedulerSetJSResponder: JavaUIManager disappeared";
@ -919,23 +964,25 @@ void Binding::schedulerDidSetJSResponder(
static auto setJSResponder = static auto setJSResponder =
jni::findClassStatic(UIManagerJavaDescriptor) jni::findClassStatic(UIManagerJavaDescriptor)
->getMethod<void( ->getMethod<void(jint, jint, jboolean)>("setJSResponder");
jint, jint, jboolean)>(
"setJSResponder");
setJSResponder(localJavaUIManager, shadowView.tag, initialShadowView.tag, (jboolean) blockNativeResponder); setJSResponder(
localJavaUIManager,
shadowView.tag,
initialShadowView.tag,
(jboolean)blockNativeResponder);
} }
void Binding::schedulerDidClearJSResponder() { void Binding::schedulerDidClearJSResponder() {
jni::global_ref<jobject> localJavaUIManager = getJavaUIManager(); jni::global_ref<jobject> localJavaUIManager = getJavaUIManager();
if (!localJavaUIManager) { if (!localJavaUIManager) {
LOG(ERROR) << "Binding::schedulerClearJSResponder: JavaUIManager disappeared"; LOG(ERROR)
<< "Binding::schedulerClearJSResponder: JavaUIManager disappeared";
return; return;
} }
static auto clearJSResponder = static auto clearJSResponder = jni::findClassStatic(UIManagerJavaDescriptor)
jni::findClassStatic(UIManagerJavaDescriptor) ->getMethod<void()>("clearJSResponder");
->getMethod<void()>("clearJSResponder");
clearJSResponder(localJavaUIManager); clearJSResponder(localJavaUIManager);
} }

Просмотреть файл

@ -76,17 +76,17 @@ class Binding : public jni::HybridClass<Binding>, public SchedulerDelegate {
const ShadowView &shadowView); const ShadowView &shadowView);
void schedulerDidDispatchCommand( void schedulerDidDispatchCommand(
const ShadowView &shadowView, const ShadowView &shadowView,
std::string const &commandName, std::string const &commandName,
folly::dynamic const args); folly::dynamic const args);
void setPixelDensity(float pointScaleFactor); void setPixelDensity(float pointScaleFactor);
void schedulerDidSetJSResponder( void schedulerDidSetJSResponder(
SurfaceId surfaceId, SurfaceId surfaceId,
const ShadowView &shadowView, const ShadowView &shadowView,
const ShadowView &initialShadowView, const ShadowView &initialShadowView,
bool blockNativeResponder); bool blockNativeResponder);
void schedulerDidClearJSResponder(); void schedulerDidClearJSResponder();

Просмотреть файл

@ -10,8 +10,8 @@
#include <fb/fbjni.h> #include <fb/fbjni.h>
#include <jsi/jsi.h> #include <jsi/jsi.h>
#include <react/uimanager/ComponentDescriptorRegistry.h> #include <react/uimanager/ComponentDescriptorRegistry.h>
#include <react/utils/ContextContainer.h>
#include <react/uimanager/Scheduler.h> #include <react/uimanager/Scheduler.h>
#include <react/utils/ContextContainer.h>
#include <mutex> #include <mutex>
#include <unordered_set> #include <unordered_set>
@ -25,7 +25,7 @@ class Instance;
class ComponentFactoryDelegate class ComponentFactoryDelegate
: public jni::HybridClass<ComponentFactoryDelegate> { : public jni::HybridClass<ComponentFactoryDelegate> {
public: public:
constexpr static const char* const kJavaDescriptor = constexpr static const char *const kJavaDescriptor =
"Lcom/facebook/react/fabric/ComponentFactoryDelegate;"; "Lcom/facebook/react/fabric/ComponentFactoryDelegate;";
static void registerNatives(); static void registerNatives();

Просмотреть файл

@ -13,8 +13,8 @@ namespace facebook {
namespace react { namespace react {
EventBeatManager::EventBeatManager( EventBeatManager::EventBeatManager(
jni::alias_ref<EventBeatManager::jhybriddata> jhybridobject) jni::alias_ref<EventBeatManager::jhybriddata> jhybridobject)
: jhybridobject_(jhybridobject) {} : jhybridobject_(jhybridobject) {}
jni::local_ref<EventBeatManager::jhybriddata> EventBeatManager::initHybrid( jni::local_ref<EventBeatManager::jhybriddata> EventBeatManager::initHybrid(
jni::alias_ref<EventBeatManager::jhybriddata> jhybridobject) { jni::alias_ref<EventBeatManager::jhybriddata> jhybridobject) {

Просмотреть файл

@ -20,7 +20,7 @@ EventEmitterWrapper::initHybrid(jni::alias_ref<jclass>) {
void EventEmitterWrapper::invokeEvent( void EventEmitterWrapper::invokeEvent(
std::string eventName, std::string eventName,
NativeMap* payload) { NativeMap *payload) {
eventEmitter->dispatchEvent( eventEmitter->dispatchEvent(
eventName, payload->consume(), EventPriority::AsynchronousBatched); eventName, payload->consume(), EventPriority::AsynchronousBatched);
} }

Просмотреть файл

@ -18,14 +18,14 @@ class Instance;
class EventEmitterWrapper : public jni::HybridClass<EventEmitterWrapper> { class EventEmitterWrapper : public jni::HybridClass<EventEmitterWrapper> {
public: public:
constexpr static const char* const kJavaDescriptor = constexpr static const char *const kJavaDescriptor =
"Lcom/facebook/react/fabric/events/EventEmitterWrapper;"; "Lcom/facebook/react/fabric/events/EventEmitterWrapper;";
static void registerNatives(); static void registerNatives();
SharedEventEmitter eventEmitter; SharedEventEmitter eventEmitter;
void invokeEvent(std::string eventName, NativeMap* params); void invokeEvent(std::string eventName, NativeMap *params);
private: private:
static jni::local_ref<jhybriddata> initHybrid(jni::alias_ref<jclass>); static jni::local_ref<jhybriddata> initHybrid(jni::alias_ref<jclass>);

Просмотреть файл

@ -14,8 +14,8 @@ using namespace facebook::jni;
namespace facebook { namespace facebook {
namespace react { namespace react {
jni::local_ref<NodeStateWrapper::jhybriddata> jni::local_ref<NodeStateWrapper::jhybriddata> NodeStateWrapper::initHybrid(
NodeStateWrapper::initHybrid(jni::alias_ref<jclass>) { jni::alias_ref<jclass>) {
return makeCxxInstance(); return makeCxxInstance();
} }
@ -26,7 +26,7 @@ jni::local_ref<ReadableNativeMap::jhybridobject> NodeStateWrapper::getState() {
return readableNativeMap; return readableNativeMap;
} }
void NodeStateWrapper::updateState(ReadableNativeMap* map) { void NodeStateWrapper::updateState(ReadableNativeMap *map) {
// Get folly::dynamic from map // Get folly::dynamic from map
auto dynamicMap = map->consume(); auto dynamicMap = map->consume();
// Set state // Set state

Просмотреть файл

@ -16,7 +16,7 @@ namespace react {
class NodeStateWrapper : public jni::HybridClass<NodeStateWrapper> { class NodeStateWrapper : public jni::HybridClass<NodeStateWrapper> {
public: public:
constexpr static const char* const kJavaDescriptor = constexpr static const char *const kJavaDescriptor =
"Lcom/facebook/react/fabric/NodeStateWrapper;"; "Lcom/facebook/react/fabric/NodeStateWrapper;";
NodeStateWrapper() {} NodeStateWrapper() {}
@ -24,9 +24,10 @@ class NodeStateWrapper : public jni::HybridClass<NodeStateWrapper> {
static void registerNatives(); static void registerNatives();
jni::local_ref<ReadableNativeMap::jhybridobject> getState(); jni::local_ref<ReadableNativeMap::jhybridobject> getState();
void updateState(ReadableNativeMap* map); void updateState(ReadableNativeMap *map);
const State *state_;
const State* state_;
private: private:
static jni::local_ref<jhybriddata> initHybrid(jni::alias_ref<jclass>); static jni::local_ref<jhybriddata> initHybrid(jni::alias_ref<jclass>);
}; };

Просмотреть файл

@ -13,7 +13,7 @@
#include "EventEmitterWrapper.h" #include "EventEmitterWrapper.h"
#include "StateWrapperImpl.h" #include "StateWrapperImpl.h"
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void*) { JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *) {
return facebook::xplat::initialize(vm, [] { return facebook::xplat::initialize(vm, [] {
facebook::react::Binding::registerNatives(); facebook::react::Binding::registerNatives();
facebook::react::EventBeatManager::registerNatives(); facebook::react::EventBeatManager::registerNatives();

Просмотреть файл

@ -11,14 +11,14 @@
using namespace facebook::react; using namespace facebook::react;
bool ReactNativeConfigHolder::getBool(const std::string& param) const { bool ReactNativeConfigHolder::getBool(const std::string &param) const {
static const auto method = facebook::jni::findClassStatic( static const auto method = facebook::jni::findClassStatic(
"com/facebook/react/fabric/ReactNativeConfig") "com/facebook/react/fabric/ReactNativeConfig")
->getMethod<jboolean(jstring)>("getBool"); ->getMethod<jboolean(jstring)>("getBool");
return method(reactNativeConfig_, facebook::jni::make_jstring(param).get()); return method(reactNativeConfig_, facebook::jni::make_jstring(param).get());
} }
std::string ReactNativeConfigHolder::getString(const std::string& param) const { std::string ReactNativeConfigHolder::getString(const std::string &param) const {
static const auto method = facebook::jni::findClassStatic( static const auto method = facebook::jni::findClassStatic(
"com/facebook/react/fabric/ReactNativeConfig") "com/facebook/react/fabric/ReactNativeConfig")
->getMethod<jstring(jstring)>("getString"); ->getMethod<jstring(jstring)>("getString");
@ -26,14 +26,14 @@ std::string ReactNativeConfigHolder::getString(const std::string& param) const {
->toString(); ->toString();
} }
int64_t ReactNativeConfigHolder::getInt64(const std::string& param) const { int64_t ReactNativeConfigHolder::getInt64(const std::string &param) const {
static const auto method = facebook::jni::findClassStatic( static const auto method = facebook::jni::findClassStatic(
"com/facebook/react/fabric/ReactNativeConfig") "com/facebook/react/fabric/ReactNativeConfig")
->getMethod<jint(jstring)>("getInt64"); ->getMethod<jint(jstring)>("getInt64");
return method(reactNativeConfig_, facebook::jni::make_jstring(param).get()); return method(reactNativeConfig_, facebook::jni::make_jstring(param).get());
} }
double ReactNativeConfigHolder::getDouble(const std::string& param) const { double ReactNativeConfigHolder::getDouble(const std::string &param) const {
static const auto method = facebook::jni::findClassStatic( static const auto method = facebook::jni::findClassStatic(
"com/facebook/react/fabric/ReactNativeConfig") "com/facebook/react/fabric/ReactNativeConfig")
->getMethod<jdouble(jstring)>("getDouble"); ->getMethod<jdouble(jstring)>("getDouble");

Просмотреть файл

@ -25,10 +25,10 @@ class ReactNativeConfigHolder : public ReactNativeConfig {
ReactNativeConfigHolder(jni::alias_ref<jobject> reactNativeConfig) ReactNativeConfigHolder(jni::alias_ref<jobject> reactNativeConfig)
: reactNativeConfig_(make_global(reactNativeConfig)){}; : reactNativeConfig_(make_global(reactNativeConfig)){};
bool getBool(const std::string& param) const override; bool getBool(const std::string &param) const override;
std::string getString(const std::string& param) const override; std::string getString(const std::string &param) const override;
int64_t getInt64(const std::string& param) const override; int64_t getInt64(const std::string &param) const override;
double getDouble(const std::string& param) const override; double getDouble(const std::string &param) const override;
private: private:
jni::global_ref<jobject> reactNativeConfig_; jni::global_ref<jobject> reactNativeConfig_;

Просмотреть файл

@ -17,8 +17,8 @@ namespace react {
/** /**
* Called from Java constructor through the JNI. * Called from Java constructor through the JNI.
*/ */
jni::local_ref<StateWrapperImpl::jhybriddata> jni::local_ref<StateWrapperImpl::jhybriddata> StateWrapperImpl::initHybrid(
StateWrapperImpl::initHybrid(jni::alias_ref<jclass>) { jni::alias_ref<jclass>) {
return makeCxxInstance(); return makeCxxInstance();
} }
@ -29,7 +29,7 @@ jni::local_ref<ReadableNativeMap::jhybridobject> StateWrapperImpl::getState() {
return readableNativeMap; return readableNativeMap;
} }
void StateWrapperImpl::updateStateImpl(NativeMap* map) { void StateWrapperImpl::updateStateImpl(NativeMap *map) {
// Get folly::dynamic from map // Get folly::dynamic from map
auto dynamicMap = map->consume(); auto dynamicMap = map->consume();
// Set state // Set state
@ -38,8 +38,8 @@ void StateWrapperImpl::updateStateImpl(NativeMap* map) {
void StateWrapperImpl::registerNatives() { void StateWrapperImpl::registerNatives() {
registerHybrid({ registerHybrid({
makeNativeMethod("initHybrid", StateWrapperImpl::initHybrid), makeNativeMethod("initHybrid", StateWrapperImpl::initHybrid),
makeNativeMethod("getState", StateWrapperImpl::getState), makeNativeMethod("getState", StateWrapperImpl::getState),
makeNativeMethod("updateStateImpl", StateWrapperImpl::updateStateImpl), makeNativeMethod("updateStateImpl", StateWrapperImpl::updateStateImpl),
}); });
} }

Просмотреть файл

@ -18,7 +18,7 @@ class Instance;
class StateWrapperImpl : public jni::HybridClass<StateWrapperImpl> { class StateWrapperImpl : public jni::HybridClass<StateWrapperImpl> {
public: public:
constexpr static const char* const kJavaDescriptor = constexpr static const char *const kJavaDescriptor =
"Lcom/facebook/react/fabric/StateWrapperImpl;"; "Lcom/facebook/react/fabric/StateWrapperImpl;";
static void registerNatives(); static void registerNatives();
@ -27,6 +27,7 @@ class StateWrapperImpl : public jni::HybridClass<StateWrapperImpl> {
void updateStateImpl(NativeMap *map); void updateStateImpl(NativeMap *map);
State::Shared state_; State::Shared state_;
private: private:
jni::alias_ref<StateWrapperImpl::jhybriddata> jhybridobject_; jni::alias_ref<StateWrapperImpl::jhybriddata> jhybridobject_;

Просмотреть файл

@ -27,7 +27,7 @@ BlobCollector::BlobCollector(
BlobCollector::~BlobCollector() { BlobCollector::~BlobCollector() {
jni::ThreadScope::WithClassLoader([&] { jni::ThreadScope::WithClassLoader([&] {
static auto removeMethod = jni::findClassStatic(kBlobModuleJavaDescriptor) static auto removeMethod = jni::findClassStatic(kBlobModuleJavaDescriptor)
->getMethod<void(jstring)>("remove"); ->getMethod<void(jstring)>("remove");
removeMethod(blobModule_, jni::make_jstring(blobId_).get()); removeMethod(blobModule_, jni::make_jstring(blobId_).get());
}); });
} }
@ -36,7 +36,7 @@ void BlobCollector::nativeInstall(
jni::alias_ref<jhybridobject> jThis, jni::alias_ref<jhybridobject> jThis,
jni::alias_ref<jobject> blobModule, jni::alias_ref<jobject> blobModule,
jlong jsContextNativePointer) { jlong jsContextNativePointer) {
auto &runtime = *((jsi::Runtime *) jsContextNativePointer); auto &runtime = *((jsi::Runtime *)jsContextNativePointer);
auto blobModuleRef = jni::make_global(blobModule); auto blobModuleRef = jni::make_global(blobModule);
runtime.global().setProperty( runtime.global().setProperty(
runtime, runtime,

Просмотреть файл

@ -7,15 +7,14 @@
#pragma once #pragma once
#include <fb/fbjni.h>
#include <ReactCommon/CallInvoker.h> #include <ReactCommon/CallInvoker.h>
#include <fb/fbjni.h>
#include <memory> #include <memory>
namespace facebook { namespace facebook {
namespace react { namespace react {
class CallInvokerHolder class CallInvokerHolder : public jni::HybridClass<CallInvokerHolder> {
: public jni::HybridClass<CallInvokerHolder> {
public: public:
static auto constexpr kJavaDescriptor = static auto constexpr kJavaDescriptor =
"Lcom/facebook/react/turbomodule/core/CallInvokerHolderImpl;"; "Lcom/facebook/react/turbomodule/core/CallInvokerHolderImpl;";

Просмотреть файл

@ -12,7 +12,8 @@
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *) { JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *) {
return facebook::xplat::initialize(vm, [] { return facebook::xplat::initialize(vm, [] {
// TODO: dvacca ramanpreet unify this with the way "ComponentDescriptorFactory" is defined in Fabric // TODO: dvacca ramanpreet unify this with the way
// "ComponentDescriptorFactory" is defined in Fabric
facebook::react::TurboModuleManager::registerNatives(); facebook::react::TurboModuleManager::registerNatives();
}); });
} }

Просмотреть файл

@ -11,8 +11,8 @@
#include <fb/fbjni.h> #include <fb/fbjni.h>
#include <jsi/jsi.h> #include <jsi/jsi.h>
#include <ReactCommon/TurboModuleBinding.h>
#include <ReactCommon/TurboCxxModule.h> #include <ReactCommon/TurboCxxModule.h>
#include <ReactCommon/TurboModuleBinding.h>
#include <react/jni/JMessageQueueThread.h> #include <react/jni/JMessageQueueThread.h>
#include "TurboModuleManager.h" #include "TurboModuleManager.h"
@ -21,37 +21,40 @@ namespace facebook {
namespace react { namespace react {
TurboModuleManager::TurboModuleManager( TurboModuleManager::TurboModuleManager(
jni::alias_ref<TurboModuleManager::javaobject> jThis, jni::alias_ref<TurboModuleManager::javaobject> jThis,
jsi::Runtime* rt, jsi::Runtime *rt,
std::shared_ptr<CallInvoker> jsCallInvoker, std::shared_ptr<CallInvoker> jsCallInvoker,
std::shared_ptr<CallInvoker> nativeCallInvoker, std::shared_ptr<CallInvoker> nativeCallInvoker,
jni::alias_ref<TurboModuleManagerDelegate::javaobject> delegate jni::alias_ref<TurboModuleManagerDelegate::javaobject> delegate)
): : javaPart_(jni::make_global(jThis)),
javaPart_(jni::make_global(jThis)), runtime_(rt),
runtime_(rt), jsCallInvoker_(jsCallInvoker),
jsCallInvoker_(jsCallInvoker), nativeCallInvoker_(nativeCallInvoker),
nativeCallInvoker_(nativeCallInvoker), delegate_(jni::make_global(delegate)),
delegate_(jni::make_global(delegate)), turboModuleCache_(std::make_shared<TurboModuleCache>()) {}
turboModuleCache_(std::make_shared<TurboModuleCache>())
{}
jni::local_ref<TurboModuleManager::jhybriddata> TurboModuleManager::initHybrid( jni::local_ref<TurboModuleManager::jhybriddata> TurboModuleManager::initHybrid(
jni::alias_ref<jhybridobject> jThis, jni::alias_ref<jhybridobject> jThis,
jlong jsContext, jlong jsContext,
jni::alias_ref<CallInvokerHolder::javaobject> jsCallInvokerHolder, jni::alias_ref<CallInvokerHolder::javaobject> jsCallInvokerHolder,
jni::alias_ref<CallInvokerHolder::javaobject> nativeCallInvokerHolder, jni::alias_ref<CallInvokerHolder::javaobject> nativeCallInvokerHolder,
jni::alias_ref<TurboModuleManagerDelegate::javaobject> delegate jni::alias_ref<TurboModuleManagerDelegate::javaobject> delegate) {
) {
auto jsCallInvoker = jsCallInvokerHolder->cthis()->getCallInvoker(); auto jsCallInvoker = jsCallInvokerHolder->cthis()->getCallInvoker();
auto nativeCallInvoker = nativeCallInvokerHolder->cthis()->getCallInvoker(); auto nativeCallInvoker = nativeCallInvokerHolder->cthis()->getCallInvoker();
return makeCxxInstance(jThis, (jsi::Runtime *) jsContext, jsCallInvoker, nativeCallInvoker, delegate); return makeCxxInstance(
jThis,
(jsi::Runtime *)jsContext,
jsCallInvoker,
nativeCallInvoker,
delegate);
} }
void TurboModuleManager::registerNatives() { void TurboModuleManager::registerNatives() {
registerHybrid({ registerHybrid({
makeNativeMethod("initHybrid", TurboModuleManager::initHybrid), makeNativeMethod("initHybrid", TurboModuleManager::initHybrid),
makeNativeMethod("installJSIBindings", TurboModuleManager::installJSIBindings), makeNativeMethod(
"installJSIBindings", TurboModuleManager::installJSIBindings),
}); });
} }
@ -60,57 +63,67 @@ void TurboModuleManager::installJSIBindings() {
return; // Runtime doesn't exist when attached to Chrome debugger. return; // Runtime doesn't exist when attached to Chrome debugger.
} }
TurboModuleBinding::install(*runtime_, std::make_shared<TurboModuleBinding>( TurboModuleBinding::install(
[ *runtime_,
turboModuleCache_ = std::weak_ptr<TurboModuleCache>(turboModuleCache_), std::make_shared<TurboModuleBinding>(
jsCallInvoker_ = std::weak_ptr<CallInvoker>(jsCallInvoker_), [turboModuleCache_ =
nativeCallInvoker_ = std::weak_ptr<CallInvoker>(nativeCallInvoker_), std::weak_ptr<TurboModuleCache>(turboModuleCache_),
delegate_ = jni::make_weak(delegate_), jsCallInvoker_ = std::weak_ptr<CallInvoker>(jsCallInvoker_),
javaPart_ = jni::make_weak(javaPart_) nativeCallInvoker_ = std::weak_ptr<CallInvoker>(nativeCallInvoker_),
] delegate_ = jni::make_weak(delegate_),
(const std::string &name) -> std::shared_ptr<TurboModule> { javaPart_ = jni::make_weak(javaPart_)](
auto turboModuleCache = turboModuleCache_.lock(); const std::string &name) -> std::shared_ptr<TurboModule> {
auto jsCallInvoker = jsCallInvoker_.lock(); auto turboModuleCache = turboModuleCache_.lock();
auto nativeCallInvoker = nativeCallInvoker_.lock(); auto jsCallInvoker = jsCallInvoker_.lock();
auto delegate = delegate_.lockLocal(); auto nativeCallInvoker = nativeCallInvoker_.lock();
auto javaPart = javaPart_.lockLocal(); auto delegate = delegate_.lockLocal();
auto javaPart = javaPart_.lockLocal();
if (!turboModuleCache || !jsCallInvoker || !nativeCallInvoker || !delegate || !javaPart) { if (!turboModuleCache || !jsCallInvoker || !nativeCallInvoker ||
return nullptr; !delegate || !javaPart) {
} return nullptr;
}
auto turboModuleLookup = turboModuleCache->find(name); auto turboModuleLookup = turboModuleCache->find(name);
if (turboModuleLookup != turboModuleCache->end()) { if (turboModuleLookup != turboModuleCache->end()) {
return turboModuleLookup->second; return turboModuleLookup->second;
} }
auto cxxModule = delegate->cthis()->getTurboModule(name, jsCallInvoker); auto cxxModule =
if (cxxModule) { delegate->cthis()->getTurboModule(name, jsCallInvoker);
turboModuleCache->insert({name, cxxModule}); if (cxxModule) {
return cxxModule; turboModuleCache->insert({name, cxxModule});
} return cxxModule;
}
static auto getLegacyCxxModule = delegate->getClass()->getMethod<jni::alias_ref<CxxModuleWrapper::javaobject>(const std::string&)>("getLegacyCxxModule"); static auto getLegacyCxxModule =
auto legacyCxxModule = getLegacyCxxModule(delegate.get(), name); delegate->getClass()
->getMethod<jni::alias_ref<CxxModuleWrapper::javaobject>(
const std::string &)>("getLegacyCxxModule");
auto legacyCxxModule = getLegacyCxxModule(delegate.get(), name);
if (legacyCxxModule) { if (legacyCxxModule) {
auto turboModule = std::make_shared<react::TurboCxxModule>(legacyCxxModule->cthis()->getModule(), jsCallInvoker); auto turboModule = std::make_shared<react::TurboCxxModule>(
turboModuleCache->insert({name, turboModule}); legacyCxxModule->cthis()->getModule(), jsCallInvoker);
return turboModule; turboModuleCache->insert({name, turboModule});
} return turboModule;
}
static auto getJavaModule = javaPart->getClass()->getMethod<jni::alias_ref<JTurboModule>(const std::string&)>("getJavaModule"); static auto getJavaModule =
auto moduleInstance = getJavaModule(javaPart.get(), name); javaPart->getClass()
->getMethod<jni::alias_ref<JTurboModule>(
const std::string &)>("getJavaModule");
auto moduleInstance = getJavaModule(javaPart.get(), name);
if (moduleInstance) { if (moduleInstance) {
auto turboModule = delegate->cthis()->getTurboModule(name, moduleInstance, jsCallInvoker, nativeCallInvoker); auto turboModule = delegate->cthis()->getTurboModule(
turboModuleCache->insert({name, turboModule}); name, moduleInstance, jsCallInvoker, nativeCallInvoker);
return turboModule; turboModuleCache->insert({name, turboModule});
} return turboModule;
}
return nullptr; return nullptr;
}) }));
);
} }
} // namespace react } // namespace react

Просмотреть файл

@ -7,40 +7,42 @@
#pragma once #pragma once
#include <memory> #include <ReactCommon/CallInvokerHolder.h>
#include <unordered_map> #include <ReactCommon/JavaTurboModule.h>
#include <ReactCommon/TurboModule.h>
#include <ReactCommon/TurboModuleManagerDelegate.h>
#include <fb/fbjni.h> #include <fb/fbjni.h>
#include <jsi/jsi.h> #include <jsi/jsi.h>
#include <ReactCommon/TurboModule.h>
#include <ReactCommon/JavaTurboModule.h>
#include <react/jni/CxxModuleWrapper.h> #include <react/jni/CxxModuleWrapper.h>
#include <react/jni/JMessageQueueThread.h> #include <react/jni/JMessageQueueThread.h>
#include <ReactCommon/CallInvokerHolder.h> #include <memory>
#include <ReactCommon/TurboModuleManagerDelegate.h> #include <unordered_map>
namespace facebook { namespace facebook {
namespace react { namespace react {
class TurboModuleManager : public jni::HybridClass<TurboModuleManager> { class TurboModuleManager : public jni::HybridClass<TurboModuleManager> {
public: public:
static auto constexpr kJavaDescriptor = "Lcom/facebook/react/turbomodule/core/TurboModuleManager;"; static auto constexpr kJavaDescriptor =
"Lcom/facebook/react/turbomodule/core/TurboModuleManager;";
static jni::local_ref<jhybriddata> initHybrid( static jni::local_ref<jhybriddata> initHybrid(
jni::alias_ref<jhybridobject> jThis, jni::alias_ref<jhybridobject> jThis,
jlong jsContext, jlong jsContext,
jni::alias_ref<CallInvokerHolder::javaobject> jsCallInvokerHolder, jni::alias_ref<CallInvokerHolder::javaobject> jsCallInvokerHolder,
jni::alias_ref<CallInvokerHolder::javaobject> nativeCallInvokerHolder, jni::alias_ref<CallInvokerHolder::javaobject> nativeCallInvokerHolder,
jni::alias_ref<TurboModuleManagerDelegate::javaobject> delegate jni::alias_ref<TurboModuleManagerDelegate::javaobject> delegate);
);
static void registerNatives(); static void registerNatives();
private:
private:
friend HybridBase; friend HybridBase;
jni::global_ref<TurboModuleManager::javaobject> javaPart_; jni::global_ref<TurboModuleManager::javaobject> javaPart_;
jsi::Runtime* runtime_; jsi::Runtime *runtime_;
std::shared_ptr<CallInvoker> jsCallInvoker_; std::shared_ptr<CallInvoker> jsCallInvoker_;
std::shared_ptr<CallInvoker> nativeCallInvoker_; std::shared_ptr<CallInvoker> nativeCallInvoker_;
jni::global_ref<TurboModuleManagerDelegate::javaobject> delegate_; jni::global_ref<TurboModuleManagerDelegate::javaobject> delegate_;
using TurboModuleCache = std::unordered_map<std::string, std::shared_ptr<react::TurboModule>>; using TurboModuleCache =
std::unordered_map<std::string, std::shared_ptr<react::TurboModule>>;
/** /**
* TODO(T48018690): * TODO(T48018690):
@ -52,12 +54,11 @@ private:
void installJSIBindings(); void installJSIBindings();
explicit TurboModuleManager( explicit TurboModuleManager(
jni::alias_ref<TurboModuleManager::jhybridobject> jThis, jni::alias_ref<TurboModuleManager::jhybridobject> jThis,
jsi::Runtime *rt, jsi::Runtime *rt,
std::shared_ptr<CallInvoker> jsCallInvoker, std::shared_ptr<CallInvoker> jsCallInvoker,
std::shared_ptr<CallInvoker> nativeCallInvoker, std::shared_ptr<CallInvoker> nativeCallInvoker,
jni::alias_ref<TurboModuleManagerDelegate::javaobject> delegate jni::alias_ref<TurboModuleManagerDelegate::javaobject> delegate);
);
}; };
} // namespace react } // namespace react

Просмотреть файл

@ -7,23 +7,31 @@
#pragma once #pragma once
#include <fb/fbjni.h>
#include <ReactCommon/JavaTurboModule.h>
#include <ReactCommon/CallInvoker.h> #include <ReactCommon/CallInvoker.h>
#include <string> #include <ReactCommon/JavaTurboModule.h>
#include <fb/fbjni.h>
#include <memory> #include <memory>
#include <string>
namespace facebook { namespace facebook {
namespace react { namespace react {
class TurboModuleManagerDelegate : public jni::HybridClass<TurboModuleManagerDelegate> { class TurboModuleManagerDelegate
public: : public jni::HybridClass<TurboModuleManagerDelegate> {
static auto constexpr kJavaDescriptor = "Lcom/facebook/react/turbomodule/core/TurboModuleManagerDelegate;"; public:
static auto constexpr kJavaDescriptor =
"Lcom/facebook/react/turbomodule/core/TurboModuleManagerDelegate;";
virtual std::shared_ptr<TurboModule> getTurboModule(std::string name, jni::alias_ref<JTurboModule> turboModule, std::shared_ptr<CallInvoker> jsInvoker, std::shared_ptr<CallInvoker> nativeInvoker) = 0; virtual std::shared_ptr<TurboModule> getTurboModule(
virtual std::shared_ptr<TurboModule> getTurboModule(std::string name, std::shared_ptr<CallInvoker> jsInvoker) = 0; std::string name,
jni::alias_ref<JTurboModule> turboModule,
std::shared_ptr<CallInvoker> jsInvoker,
std::shared_ptr<CallInvoker> nativeInvoker) = 0;
virtual std::shared_ptr<TurboModule> getTurboModule(
std::string name,
std::shared_ptr<CallInvoker> jsInvoker) = 0;
private: private:
friend HybridBase; friend HybridBase;
}; };

Просмотреть файл

@ -290,8 +290,8 @@ void CatalystInstanceImpl::handleMemoryPressure(int pressureLevel) {
jni::alias_ref<CallInvokerHolder::javaobject> jni::alias_ref<CallInvokerHolder::javaobject>
CatalystInstanceImpl::getJSCallInvokerHolder() { CatalystInstanceImpl::getJSCallInvokerHolder() {
if (!jsCallInvokerHolder_) { if (!jsCallInvokerHolder_) {
jsCallInvokerHolder_ = jsCallInvokerHolder_ = jni::make_global(CallInvokerHolder::newObjectCxxArgs(
jni::make_global(CallInvokerHolder::newObjectCxxArgs(std::make_shared<BridgeJSCallInvoker>(instance_))); std::make_shared<BridgeJSCallInvoker>(instance_)));
} }
return jsCallInvokerHolder_; return jsCallInvokerHolder_;
@ -301,7 +301,9 @@ jni::alias_ref<CallInvokerHolder::javaobject>
CatalystInstanceImpl::getNativeCallInvokerHolder() { CatalystInstanceImpl::getNativeCallInvokerHolder() {
if (!nativeCallInvokerHolder_) { if (!nativeCallInvokerHolder_) {
nativeCallInvokerHolder_ = nativeCallInvokerHolder_ =
jni::make_global(CallInvokerHolder::newObjectCxxArgs(std::make_shared<MessageQueueThreadCallInvoker>(moduleMessageQueue_))); jni::make_global(CallInvokerHolder::newObjectCxxArgs(
std::make_shared<MessageQueueThreadCallInvoker>(
moduleMessageQueue_)));
} }
return nativeCallInvokerHolder_; return nativeCallInvokerHolder_;

Просмотреть файл

@ -18,7 +18,7 @@ namespace react {
struct JNativeModule : jni::JavaClass<JNativeModule> { struct JNativeModule : jni::JavaClass<JNativeModule> {
constexpr static const char *const kJavaDescriptor = constexpr static const char *const kJavaDescriptor =
"Lcom/facebook/react/bridge/NativeModule;"; "Lcom/facebook/react/bridge/NativeModule;";
}; };
/** /**
@ -26,15 +26,14 @@ struct JNativeModule : jni::JavaClass<JNativeModule> {
* must extend this base class. * must extend this base class.
*/ */
class CxxModuleWrapperBase class CxxModuleWrapperBase
: public jni::HybridClass<CxxModuleWrapperBase, JNativeModule> { : public jni::HybridClass<CxxModuleWrapperBase, JNativeModule> {
public: public:
constexpr static const char *const kJavaDescriptor = constexpr static const char *const kJavaDescriptor =
"Lcom/facebook/react/bridge/CxxModuleWrapperBase;"; "Lcom/facebook/react/bridge/CxxModuleWrapperBase;";
static void registerNatives() { static void registerNatives() {
registerHybrid({ registerHybrid(
makeNativeMethod("getName", CxxModuleWrapperBase::getName) {makeNativeMethod("getName", CxxModuleWrapperBase::getName)});
});
} }
// JNI method // JNI method
@ -44,5 +43,5 @@ public:
virtual std::unique_ptr<xplat::module::CxxModule> getModule() = 0; virtual std::unique_ptr<xplat::module::CxxModule> getModule() = 0;
}; };
} } // namespace react
} } // namespace facebook

Просмотреть файл

@ -20,30 +20,33 @@ namespace react {
class Instance; class Instance;
struct JCallback : public jni::JavaClass<JCallback> { struct JCallback : public jni::JavaClass<JCallback> {
constexpr static auto kJavaDescriptor = "Lcom/facebook/react/bridge/Callback;"; constexpr static auto kJavaDescriptor =
"Lcom/facebook/react/bridge/Callback;";
}; };
class JCxxCallbackImpl : public jni::HybridClass<JCxxCallbackImpl, JCallback> { class JCxxCallbackImpl : public jni::HybridClass<JCxxCallbackImpl, JCallback> {
public: public:
constexpr static auto kJavaDescriptor = "Lcom/facebook/react/bridge/CxxCallbackImpl;"; constexpr static auto kJavaDescriptor =
"Lcom/facebook/react/bridge/CxxCallbackImpl;";
static void registerNatives() { static void registerNatives() {
javaClassStatic()->registerNatives({ javaClassStatic()->registerNatives({
makeNativeMethod("nativeInvoke", JCxxCallbackImpl::invoke), makeNativeMethod("nativeInvoke", JCxxCallbackImpl::invoke),
}); });
} }
private:
private:
friend HybridBase; friend HybridBase;
using Callback = std::function<void(folly::dynamic)>; using Callback = std::function<void(folly::dynamic)>;
JCxxCallbackImpl(Callback callback) : callback_(std::move(callback)) {} JCxxCallbackImpl(Callback callback) : callback_(std::move(callback)) {}
void invoke(NativeArray* arguments) { void invoke(NativeArray *arguments) {
callback_(arguments->consume()); callback_(arguments->consume());
} }
Callback callback_; Callback callback_;
}; };
} } // namespace react
} } // namespace facebook

Просмотреть файл

@ -19,23 +19,27 @@ namespace facebook {
namespace react { namespace react {
class JPage : public jni::JavaClass<JPage> { class JPage : public jni::JavaClass<JPage> {
public: public:
static constexpr auto kJavaDescriptor = "Lcom/facebook/react/bridge/Inspector$Page;"; static constexpr auto kJavaDescriptor =
"Lcom/facebook/react/bridge/Inspector$Page;";
static jni::local_ref<JPage::javaobject> create(int id, const std::string& title, const std::string& vm); static jni::local_ref<JPage::javaobject>
create(int id, const std::string &title, const std::string &vm);
}; };
class JRemoteConnection : public jni::JavaClass<JRemoteConnection> { class JRemoteConnection : public jni::JavaClass<JRemoteConnection> {
public: public:
static constexpr auto kJavaDescriptor = "Lcom/facebook/react/bridge/Inspector$RemoteConnection;"; static constexpr auto kJavaDescriptor =
"Lcom/facebook/react/bridge/Inspector$RemoteConnection;";
void onMessage(const std::string& message) const; void onMessage(const std::string &message) const;
void onDisconnect() const; void onDisconnect() const;
}; };
class JLocalConnection : public jni::HybridClass<JLocalConnection> { class JLocalConnection : public jni::HybridClass<JLocalConnection> {
public: public:
static constexpr auto kJavaDescriptor = "Lcom/facebook/react/bridge/Inspector$LocalConnection;"; static constexpr auto kJavaDescriptor =
"Lcom/facebook/react/bridge/Inspector$LocalConnection;";
JLocalConnection(std::unique_ptr<ILocalConnection> connection); JLocalConnection(std::unique_ptr<ILocalConnection> connection);
@ -43,29 +47,35 @@ public:
void disconnect(); void disconnect();
static void registerNatives(); static void registerNatives();
private:
private:
std::unique_ptr<ILocalConnection> connection_; std::unique_ptr<ILocalConnection> connection_;
}; };
class JInspector : public jni::HybridClass<JInspector> { class JInspector : public jni::HybridClass<JInspector> {
public: public:
static constexpr auto kJavaDescriptor = "Lcom/facebook/react/bridge/Inspector;"; static constexpr auto kJavaDescriptor =
"Lcom/facebook/react/bridge/Inspector;";
static jni::global_ref<JInspector::javaobject> instance(jni::alias_ref<jclass>); static jni::global_ref<JInspector::javaobject> instance(
jni::alias_ref<jclass>);
jni::local_ref<jni::JArrayClass<JPage::javaobject>> getPages(); jni::local_ref<jni::JArrayClass<JPage::javaobject>> getPages();
jni::local_ref<JLocalConnection::javaobject> connect(int pageId, jni::alias_ref<JRemoteConnection::javaobject> remote); jni::local_ref<JLocalConnection::javaobject> connect(
int pageId,
jni::alias_ref<JRemoteConnection::javaobject> remote);
static void registerNatives(); static void registerNatives();
private:
private:
friend HybridBase; friend HybridBase;
JInspector(IInspector* inspector) : inspector_(inspector) {} JInspector(IInspector *inspector) : inspector_(inspector) {}
IInspector* inspector_; IInspector *inspector_;
}; };
} } // namespace react
} } // namespace facebook
#endif #endif

Просмотреть файл

@ -22,16 +22,17 @@ namespace react {
namespace { namespace {
struct JavaJSException : jni::JavaClass<JavaJSException, JThrowable> { struct JavaJSException : jni::JavaClass<JavaJSException, JThrowable> {
static constexpr auto kJavaDescriptor = "Lcom/facebook/react/devsupport/JSException;"; static constexpr auto kJavaDescriptor =
"Lcom/facebook/react/devsupport/JSException;";
static local_ref<JavaJSException> create(const char* message, const char* stack, static local_ref<JavaJSException>
const std::exception& ex) { create(const char *message, const char *stack, const std::exception &ex) {
local_ref<jthrowable> cause = jni::JCppException::create(ex); local_ref<jthrowable> cause = jni::JCppException::create(ex);
return newInstance(make_jstring(message), make_jstring(stack), cause.get()); return newInstance(make_jstring(message), make_jstring(stack), cause.get());
} }
}; };
std::function<void()> wrapRunnable(std::function<void()>&& runnable) { std::function<void()> wrapRunnable(std::function<void()> &&runnable) {
return [runnable = std::move(runnable)]() mutable { return [runnable = std::move(runnable)]() mutable {
if (!runnable) { if (!runnable) {
// Runnable is empty, nothing to run. // Runnable is empty, nothing to run.
@ -46,33 +47,39 @@ std::function<void()> wrapRunnable(std::function<void()>&& runnable) {
try { try {
localRunnable(); localRunnable();
} catch (const jsi::JSError& ex) { } catch (const jsi::JSError &ex) {
throwNewJavaException( throwNewJavaException(
JavaJSException::create(ex.getMessage().c_str(), ex.getStack().c_str(), ex) JavaJSException::create(
.get()); ex.getMessage().c_str(), ex.getStack().c_str(), ex)
.get());
} }
}; };
} }
} } // namespace
JMessageQueueThread::JMessageQueueThread(alias_ref<JavaMessageQueueThread::javaobject> jobj) : JMessageQueueThread::JMessageQueueThread(
m_jobj(make_global(jobj)) { alias_ref<JavaMessageQueueThread::javaobject> jobj)
} : m_jobj(make_global(jobj)) {}
void JMessageQueueThread::runOnQueue(std::function<void()>&& runnable) { void JMessageQueueThread::runOnQueue(std::function<void()> &&runnable) {
// For C++ modules, this can be called from an arbitrary thread // For C++ modules, this can be called from an arbitrary thread
// managed by the module, via callJSCallback or callJSFunction. So, // managed by the module, via callJSCallback or callJSFunction. So,
// we ensure that it is registered with the JVM. // we ensure that it is registered with the JVM.
jni::ThreadScope guard; jni::ThreadScope guard;
static auto method = JavaMessageQueueThread::javaClassStatic()-> static auto method =
getMethod<void(Runnable::javaobject)>("runOnQueue"); JavaMessageQueueThread::javaClassStatic()
method(m_jobj, JNativeRunnable::newObjectCxxArgs(wrapRunnable(std::move(runnable))).get()); ->getMethod<void(Runnable::javaobject)>("runOnQueue");
method(
m_jobj,
JNativeRunnable::newObjectCxxArgs(wrapRunnable(std::move(runnable)))
.get());
} }
void JMessageQueueThread::runOnQueueSync(std::function<void()>&& runnable) { void JMessageQueueThread::runOnQueueSync(std::function<void()> &&runnable) {
static auto jIsOnThread = JavaMessageQueueThread::javaClassStatic()-> static auto jIsOnThread =
getMethod<jboolean()>("isOnThread"); JavaMessageQueueThread::javaClassStatic()->getMethod<jboolean()>(
"isOnThread");
if (jIsOnThread(m_jobj)) { if (jIsOnThread(m_jobj)) {
wrapRunnable(std::move(runnable))(); wrapRunnable(std::move(runnable))();
@ -81,7 +88,7 @@ void JMessageQueueThread::runOnQueueSync(std::function<void()>&& runnable) {
std::condition_variable signalCv; std::condition_variable signalCv;
bool runnableComplete = false; bool runnableComplete = false;
runOnQueue([&] () mutable { runOnQueue([&]() mutable {
std::lock_guard<std::mutex> lock(signalMutex); std::lock_guard<std::mutex> lock(signalMutex);
runnable(); runnable();
@ -96,9 +103,11 @@ void JMessageQueueThread::runOnQueueSync(std::function<void()>&& runnable) {
} }
void JMessageQueueThread::quitSynchronous() { void JMessageQueueThread::quitSynchronous() {
static auto method = JavaMessageQueueThread::javaClassStatic()-> static auto method =
getMethod<void()>("quitSynchronous"); JavaMessageQueueThread::javaClassStatic()->getMethod<void()>(
"quitSynchronous");
method(m_jobj); method(m_jobj);
} }
} } } // namespace react
} // namespace facebook

Просмотреть файл

@ -18,29 +18,30 @@ namespace facebook {
namespace react { namespace react {
class JavaMessageQueueThread : public jni::JavaClass<JavaMessageQueueThread> { class JavaMessageQueueThread : public jni::JavaClass<JavaMessageQueueThread> {
public: public:
static constexpr auto kJavaDescriptor = "Lcom/facebook/react/bridge/queue/MessageQueueThread;"; static constexpr auto kJavaDescriptor =
"Lcom/facebook/react/bridge/queue/MessageQueueThread;";
}; };
class JMessageQueueThread : public MessageQueueThread { class JMessageQueueThread : public MessageQueueThread {
public: public:
JMessageQueueThread(alias_ref<JavaMessageQueueThread::javaobject> jobj); JMessageQueueThread(alias_ref<JavaMessageQueueThread::javaobject> jobj);
/** /**
* Enqueues the given function to run on this MessageQueueThread. * Enqueues the given function to run on this MessageQueueThread.
*/ */
void runOnQueue(std::function<void()>&& runnable) override; void runOnQueue(std::function<void()> &&runnable) override;
/** /**
* Synchronously executes the given function to run on this * Synchronously executes the given function to run on this
* MessageQueueThread, waiting until it completes. Can be called from any * MessageQueueThread, waiting until it completes. Can be called from any
* thread, but will block if not called on this MessageQueueThread. * thread, but will block if not called on this MessageQueueThread.
*/ */
void runOnQueueSync(std::function<void()>&& runnable) override; void runOnQueueSync(std::function<void()> &&runnable) override;
/** /**
* Synchronously quits the current MessageQueueThread. Can be called from any thread, but will * Synchronously quits the current MessageQueueThread. Can be called from any
* block if not called on this MessageQueueThread. * thread, but will block if not called on this MessageQueueThread.
*/ */
void quitSynchronous() override; void quitSynchronous() override;
@ -48,8 +49,9 @@ public:
return m_jobj.get(); return m_jobj.get();
} }
private: private:
global_ref<JavaMessageQueueThread::javaobject> m_jobj; global_ref<JavaMessageQueueThread::javaobject> m_jobj;
}; };
} } } // namespace react
} // namespace facebook

Просмотреть файл

@ -6,33 +6,38 @@
*/ */
#include "JReactMarker.h" #include "JReactMarker.h"
#include <mutex>
#include <cxxreact/ReactMarker.h> #include <cxxreact/ReactMarker.h>
#include <fb/fbjni.h> #include <fb/fbjni.h>
#include <mutex>
namespace facebook { namespace facebook {
namespace react { namespace react {
void JReactMarker::setLogPerfMarkerIfNeeded() { void JReactMarker::setLogPerfMarkerIfNeeded() {
static std::once_flag flag {}; static std::once_flag flag{};
std::call_once(flag, [](){ std::call_once(flag, []() {
ReactMarker::logTaggedMarker = JReactMarker::logPerfMarker; ReactMarker::logTaggedMarker = JReactMarker::logPerfMarker;
}); });
} }
void JReactMarker::logMarker(const std::string& marker) { void JReactMarker::logMarker(const std::string &marker) {
static auto cls = javaClassStatic(); static auto cls = javaClassStatic();
static auto meth = cls->getStaticMethod<void(std::string)>("logMarker"); static auto meth = cls->getStaticMethod<void(std::string)>("logMarker");
meth(cls, marker); meth(cls, marker);
} }
void JReactMarker::logMarker(const std::string& marker, const std::string& tag) { void JReactMarker::logMarker(
const std::string &marker,
const std::string &tag) {
static auto cls = javaClassStatic(); static auto cls = javaClassStatic();
static auto meth = cls->getStaticMethod<void(std::string, std::string)>("logMarker"); static auto meth =
cls->getStaticMethod<void(std::string, std::string)>("logMarker");
meth(cls, marker, tag); meth(cls, marker, tag);
} }
void JReactMarker::logPerfMarker(const ReactMarker::ReactMarkerId markerId, const char* tag) { void JReactMarker::logPerfMarker(
const ReactMarker::ReactMarkerId markerId,
const char *tag) {
switch (markerId) { switch (markerId) {
case ReactMarker::RUN_JS_BUNDLE_START: case ReactMarker::RUN_JS_BUNDLE_START:
JReactMarker::logMarker("RUN_JS_BUNDLE_START", tag); JReactMarker::logMarker("RUN_JS_BUNDLE_START", tag);
@ -68,5 +73,5 @@ void JReactMarker::logPerfMarker(const ReactMarker::ReactMarkerId markerId, cons
} }
} }
} } // namespace react
} } // namespace facebook

Просмотреть файл

@ -7,8 +7,8 @@
#pragma once #pragma once
#include <string>
#include <fb/fbjni.h> #include <fb/fbjni.h>
#include <string>
#include <cxxreact/ReactMarker.h> #include <cxxreact/ReactMarker.h>
@ -16,15 +16,18 @@ namespace facebook {
namespace react { namespace react {
class JReactMarker : public facebook::jni::JavaClass<JReactMarker> { class JReactMarker : public facebook::jni::JavaClass<JReactMarker> {
public: public:
static constexpr auto kJavaDescriptor = "Lcom/facebook/react/bridge/ReactMarker;"; static constexpr auto kJavaDescriptor =
"Lcom/facebook/react/bridge/ReactMarker;";
static void setLogPerfMarkerIfNeeded(); static void setLogPerfMarkerIfNeeded();
private: private:
static void logMarker(const std::string& marker); static void logMarker(const std::string &marker);
static void logMarker(const std::string& marker, const std::string& tag); static void logMarker(const std::string &marker, const std::string &tag);
static void logPerfMarker(const ReactMarker::ReactMarkerId markerId, const char* tag); static void logPerfMarker(
const ReactMarker::ReactMarkerId markerId,
const char *tag);
}; };
} } // namespace react
} } // namespace facebook

Просмотреть файл

@ -28,30 +28,33 @@ using namespace facebook::jni;
namespace facebook { namespace facebook {
namespace react { namespace react {
__attribute__((visibility("default"))) __attribute__((visibility("default"))) AAssetManager *extractAssetManager(
AAssetManager *extractAssetManager(alias_ref<JAssetManager::javaobject> assetManager) { alias_ref<JAssetManager::javaobject> assetManager) {
auto env = Environment::current(); auto env = Environment::current();
return AAssetManager_fromJava(env, assetManager.get()); return AAssetManager_fromJava(env, assetManager.get());
} }
__attribute__((visibility("default"))) __attribute__((visibility("default"))) std::unique_ptr<const JSBigString>
std::unique_ptr<const JSBigString> loadScriptFromAssets( loadScriptFromAssets(AAssetManager *manager, const std::string &assetName) {
AAssetManager *manager, #ifdef WITH_FBSYSTRACE
const std::string& assetName) { FbSystraceSection s(
#ifdef WITH_FBSYSTRACE TRACE_TAG_REACT_CXX_BRIDGE,
FbSystraceSection s(TRACE_TAG_REACT_CXX_BRIDGE, "reactbridge_jni_loadScriptFromAssets", "reactbridge_jni_loadScriptFromAssets",
"assetName", assetName); "assetName",
#endif assetName);
#endif
if (manager) { if (manager) {
auto asset = AAssetManager_open( auto asset = AAssetManager_open(
manager, manager,
assetName.c_str(), assetName.c_str(),
AASSET_MODE_STREAMING); // Optimized for sequential read: see AssetManager.java for docs AASSET_MODE_STREAMING); // Optimized for sequential read: see
// AssetManager.java for docs
if (asset) { if (asset) {
auto buf = std::make_unique<JSBigBufferString>(AAsset_getLength(asset)); auto buf = std::make_unique<JSBigBufferString>(AAsset_getLength(asset));
size_t offset = 0; size_t offset = 0;
int readbytes; int readbytes;
while ((readbytes = AAsset_read(asset, buf->data() + offset, buf->size() - offset)) > 0) { while ((readbytes = AAsset_read(
asset, buf->data() + offset, buf->size() - offset)) > 0) {
offset += readbytes; offset += readbytes;
} }
AAsset_close(asset); AAsset_close(asset);
@ -61,9 +64,12 @@ std::unique_ptr<const JSBigString> loadScriptFromAssets(
} }
} }
throw std::runtime_error(folly::to<std::string>("Unable to load script. Make sure you're " throw std::runtime_error(folly::to<std::string>(
"either running a Metro server (run 'react-native start') or that your bundle '", assetName, "Unable to load script. Make sure you're "
"' is packaged correctly for release.")); "either running a Metro server (run 'react-native start') or that your bundle '",
assetName,
"' is packaged correctly for release."));
} }
}} } // namespace react
} // namespace facebook

Просмотреть файл

@ -23,8 +23,12 @@ struct JAssetManager : jni::JavaClass<JAssetManager> {
/** /**
* Helper method for loading JS script from android asset * Helper method for loading JS script from android asset
*/ */
AAssetManager *extractAssetManager(jni::alias_ref<JAssetManager::javaobject> assetManager); AAssetManager *extractAssetManager(
jni::alias_ref<JAssetManager::javaobject> assetManager);
std::unique_ptr<const JSBigString> loadScriptFromAssets(AAssetManager *assetManager, const std::string& assetName); std::unique_ptr<const JSBigString> loadScriptFromAssets(
AAssetManager *assetManager,
const std::string &assetName);
} } } // namespace react
} // namespace facebook

Просмотреть файл

@ -9,13 +9,13 @@
#include <glog/logging.h> #include <glog/logging.h>
#include <fb/fbjni.h>
#include <folly/json.h>
#include <cxxreact/CxxModule.h> #include <cxxreact/CxxModule.h>
#include <cxxreact/CxxNativeModule.h> #include <cxxreact/CxxNativeModule.h>
#include <cxxreact/Instance.h> #include <cxxreact/Instance.h>
#include <cxxreact/JsArgumentHelpers.h> #include <cxxreact/JsArgumentHelpers.h>
#include <cxxreact/NativeModule.h> #include <cxxreact/NativeModule.h>
#include <fb/fbjni.h>
#include <folly/json.h>
#ifdef WITH_FBSYSTRACE #ifdef WITH_FBSYSTRACE
#include <fbsystrace.h> #include <fbsystrace.h>
@ -45,7 +45,8 @@ std::string JMethodDescriptor::getType() const {
} }
std::string JavaNativeModule::getName() { std::string JavaNativeModule::getName() {
static auto getNameMethod = wrapper_->getClass()->getMethod<jstring()>("getName"); static auto getNameMethod =
wrapper_->getClass()->getMethod<jstring()>("getName");
return getNameMethod(wrapper_)->toStdString(); return getNameMethod(wrapper_)->toStdString();
} }
@ -53,35 +54,34 @@ std::vector<MethodDescriptor> JavaNativeModule::getMethods() {
std::vector<MethodDescriptor> ret; std::vector<MethodDescriptor> ret;
syncMethods_.clear(); syncMethods_.clear();
auto descs = wrapper_->getMethodDescriptors(); auto descs = wrapper_->getMethodDescriptors();
for (const auto& desc : *descs) { for (const auto &desc : *descs) {
auto methodName = desc->getName(); auto methodName = desc->getName();
auto methodType = desc->getType(); auto methodType = desc->getType();
if (methodType == "sync") { if (methodType == "sync") {
// allow for the sync methods vector to have empty values, resize on demand // allow for the sync methods vector to have empty values, resize on
// demand
size_t methodIndex = ret.size(); size_t methodIndex = ret.size();
if (methodIndex >= syncMethods_.size()) { if (methodIndex >= syncMethods_.size()) {
syncMethods_.resize(methodIndex + 1); syncMethods_.resize(methodIndex + 1);
} }
syncMethods_.insert(syncMethods_.begin() + methodIndex, MethodInvoker( syncMethods_.insert(
desc->getMethod(), syncMethods_.begin() + methodIndex,
desc->getSignature(), MethodInvoker(
getName() + "." + methodName, desc->getMethod(),
true desc->getSignature(),
)); getName() + "." + methodName,
true));
} }
ret.emplace_back( ret.emplace_back(std::move(methodName), std::move(methodType));
std::move(methodName),
std::move(methodType)
);
} }
return ret; return ret;
} }
folly::dynamic JavaNativeModule::getConstants() { folly::dynamic JavaNativeModule::getConstants() {
static auto constantsMethod = static auto constantsMethod =
wrapper_->getClass()->getMethod<NativeMap::javaobject()>("getConstants"); wrapper_->getClass()->getMethod<NativeMap::javaobject()>("getConstants");
auto constants = constantsMethod(wrapper_); auto constants = constantsMethod(wrapper_);
if (!constants) { if (!constants) {
return nullptr; return nullptr;
@ -90,46 +90,60 @@ folly::dynamic JavaNativeModule::getConstants() {
} }
} }
void JavaNativeModule::invoke(unsigned int reactMethodId, folly::dynamic&& params, int callId) { void JavaNativeModule::invoke(
messageQueueThread_->runOnQueue([this, reactMethodId, params=std::move(params), callId] { unsigned int reactMethodId,
static auto invokeMethod = wrapper_->getClass()->getMethod<void(jint, ReadableNativeArray::javaobject)>("invoke"); folly::dynamic &&params,
#ifdef WITH_FBSYSTRACE int callId) {
if (callId != -1) { messageQueueThread_->runOnQueue(
fbsystrace_end_async_flow(TRACE_TAG_REACT_APPS, "native", callId); [this, reactMethodId, params = std::move(params), callId] {
} static auto invokeMethod =
#endif wrapper_->getClass()
invokeMethod( ->getMethod<void(jint, ReadableNativeArray::javaobject)>(
wrapper_, "invoke");
static_cast<jint>(reactMethodId), #ifdef WITH_FBSYSTRACE
ReadableNativeArray::newObjectCxxArgs(std::move(params)).get()); if (callId != -1) {
}); fbsystrace_end_async_flow(TRACE_TAG_REACT_APPS, "native", callId);
}
#endif
invokeMethod(
wrapper_,
static_cast<jint>(reactMethodId),
ReadableNativeArray::newObjectCxxArgs(std::move(params)).get());
});
} }
MethodCallResult JavaNativeModule::callSerializableNativeHook(unsigned int reactMethodId, folly::dynamic&& params) { MethodCallResult JavaNativeModule::callSerializableNativeHook(
unsigned int reactMethodId,
folly::dynamic &&params) {
// TODO: evaluate whether calling through invoke is potentially faster // TODO: evaluate whether calling through invoke is potentially faster
if (reactMethodId >= syncMethods_.size()) { if (reactMethodId >= syncMethods_.size()) {
throw std::invalid_argument( throw std::invalid_argument(folly::to<std::string>(
folly::to<std::string>("methodId ", reactMethodId, " out of range [0..", syncMethods_.size(), "]")); "methodId ",
reactMethodId,
" out of range [0..",
syncMethods_.size(),
"]"));
} }
auto& method = syncMethods_[reactMethodId]; auto &method = syncMethods_[reactMethodId];
CHECK(method.hasValue() && method->isSyncHook()) << "Trying to invoke a asynchronous method as synchronous hook"; CHECK(method.hasValue() && method->isSyncHook())
<< "Trying to invoke a asynchronous method as synchronous hook";
return method->invoke(instance_, wrapper_->getModule(), params); return method->invoke(instance_, wrapper_->getModule(), params);
} }
NewJavaNativeModule::NewJavaNativeModule( NewJavaNativeModule::NewJavaNativeModule(
std::weak_ptr<Instance> instance, std::weak_ptr<Instance> instance,
jni::alias_ref<JavaModuleWrapper::javaobject> wrapper, jni::alias_ref<JavaModuleWrapper::javaobject> wrapper,
std::shared_ptr<MessageQueueThread> messageQueueThread) std::shared_ptr<MessageQueueThread> messageQueueThread)
: instance_(std::move(instance)) : instance_(std::move(instance)),
, wrapper_(make_global(wrapper)) wrapper_(make_global(wrapper)),
, module_(make_global(wrapper->getModule())) module_(make_global(wrapper->getModule())),
, messageQueueThread_(std::move(messageQueueThread)) { messageQueueThread_(std::move(messageQueueThread)) {
auto descs = wrapper_->getMethodDescriptors(); auto descs = wrapper_->getMethodDescriptors();
std::string moduleName = getName(); std::string moduleName = getName();
methods_.reserve(descs->size()); methods_.reserve(descs->size());
for (const auto& desc : *descs) { for (const auto &desc : *descs) {
auto type = desc->getType(); auto type = desc->getType();
auto name = desc->getName(); auto name = desc->getName();
methods_.emplace_back( methods_.emplace_back(
@ -143,7 +157,8 @@ NewJavaNativeModule::NewJavaNativeModule(
} }
std::string NewJavaNativeModule::getName() { std::string NewJavaNativeModule::getName() {
static auto getNameMethod = wrapper_->getClass()->getMethod<jstring()>("getName"); static auto getNameMethod =
wrapper_->getClass()->getMethod<jstring()>("getName");
return getNameMethod(wrapper_)->toStdString(); return getNameMethod(wrapper_)->toStdString();
} }
@ -153,7 +168,7 @@ std::vector<MethodDescriptor> NewJavaNativeModule::getMethods() {
folly::dynamic NewJavaNativeModule::getConstants() { folly::dynamic NewJavaNativeModule::getConstants() {
static auto constantsMethod = static auto constantsMethod =
wrapper_->getClass()->getMethod<NativeMap::javaobject()>("getConstants"); wrapper_->getClass()->getMethod<NativeMap::javaobject()>("getConstants");
auto constants = constantsMethod(wrapper_); auto constants = constantsMethod(wrapper_);
if (!constants) { if (!constants) {
return nullptr; return nullptr;
@ -162,39 +177,59 @@ folly::dynamic NewJavaNativeModule::getConstants() {
} }
} }
void NewJavaNativeModule::invoke(unsigned int reactMethodId, folly::dynamic&& params, int callId) { void NewJavaNativeModule::invoke(
unsigned int reactMethodId,
folly::dynamic &&params,
int callId) {
if (reactMethodId >= methods_.size()) { if (reactMethodId >= methods_.size()) {
throw std::invalid_argument( throw std::invalid_argument(folly::to<std::string>(
folly::to<std::string>("methodId ", reactMethodId, " out of range [0..", methods_.size(), "]")); "methodId ",
reactMethodId,
" out of range [0..",
methods_.size(),
"]"));
} }
CHECK(!methods_[reactMethodId].isSyncHook()) << "Trying to invoke a synchronous hook asynchronously"; CHECK(!methods_[reactMethodId].isSyncHook())
messageQueueThread_->runOnQueue([this, reactMethodId, params=std::move(params), callId] () mutable { << "Trying to invoke a synchronous hook asynchronously";
#ifdef WITH_FBSYSTRACE messageQueueThread_->runOnQueue(
if (callId != -1) { [this, reactMethodId, params = std::move(params), callId]() mutable {
fbsystrace_end_async_flow(TRACE_TAG_REACT_APPS, "native", callId); #ifdef WITH_FBSYSTRACE
} if (callId != -1) {
#endif fbsystrace_end_async_flow(TRACE_TAG_REACT_APPS, "native", callId);
invokeInner(reactMethodId, std::move(params)); }
}); #endif
invokeInner(reactMethodId, std::move(params));
});
} }
MethodCallResult NewJavaNativeModule::callSerializableNativeHook(unsigned int reactMethodId, folly::dynamic&& params) { MethodCallResult NewJavaNativeModule::callSerializableNativeHook(
unsigned int reactMethodId,
folly::dynamic &&params) {
if (reactMethodId >= methods_.size()) { if (reactMethodId >= methods_.size()) {
throw std::invalid_argument( throw std::invalid_argument(folly::to<std::string>(
folly::to<std::string>("methodId ", reactMethodId, " out of range [0..", methods_.size(), "]")); "methodId ",
reactMethodId,
" out of range [0..",
methods_.size(),
"]"));
} }
CHECK(methods_[reactMethodId].isSyncHook()) << "Trying to invoke a asynchronous method as synchronous hook"; CHECK(methods_[reactMethodId].isSyncHook())
<< "Trying to invoke a asynchronous method as synchronous hook";
return invokeInner(reactMethodId, std::move(params)); return invokeInner(reactMethodId, std::move(params));
} }
MethodCallResult NewJavaNativeModule::invokeInner(unsigned int reactMethodId, folly::dynamic&& params) { MethodCallResult NewJavaNativeModule::invokeInner(
unsigned int reactMethodId,
folly::dynamic &&params) {
return methods_[reactMethodId].invoke(instance_, module_.get(), params); return methods_[reactMethodId].invoke(instance_, module_.get(), params);
} }
jni::local_ref<JReflectMethod::javaobject> JMethodDescriptor::getMethod() const { jni::local_ref<JReflectMethod::javaobject> JMethodDescriptor::getMethod()
static auto method = javaClassStatic()->getField<JReflectMethod::javaobject>("method"); const {
static auto method =
javaClassStatic()->getField<JReflectMethod::javaobject>("method");
return getFieldValue(method); return getFieldValue(method);
} }
} } // namespace react
} } // namespace facebook

Просмотреть файл

@ -21,7 +21,7 @@ class MessageQueueThread;
struct JMethodDescriptor : public jni::JavaClass<JMethodDescriptor> { struct JMethodDescriptor : public jni::JavaClass<JMethodDescriptor> {
static constexpr auto kJavaDescriptor = static constexpr auto kJavaDescriptor =
"Lcom/facebook/react/bridge/JavaModuleWrapper$MethodDescriptor;"; "Lcom/facebook/react/bridge/JavaModuleWrapper$MethodDescriptor;";
jni::local_ref<JReflectMethod::javaobject> getMethod() const; jni::local_ref<JReflectMethod::javaobject> getMethod() const;
std::string getSignature() const; std::string getSignature() const;
@ -30,12 +30,15 @@ struct JMethodDescriptor : public jni::JavaClass<JMethodDescriptor> {
}; };
struct JavaModuleWrapper : jni::JavaClass<JavaModuleWrapper> { struct JavaModuleWrapper : jni::JavaClass<JavaModuleWrapper> {
static constexpr auto kJavaDescriptor = "Lcom/facebook/react/bridge/JavaModuleWrapper;"; static constexpr auto kJavaDescriptor =
"Lcom/facebook/react/bridge/JavaModuleWrapper;";
jni::local_ref<JBaseJavaModule::javaobject> getModule() { jni::local_ref<JBaseJavaModule::javaobject> getModule() {
// This is the call which causes a lazy Java module to actually be // This is the call which causes a lazy Java module to actually be
// created. // created.
static auto getModule = javaClassStatic()->getMethod<JBaseJavaModule::javaobject()>("getModule"); static auto getModule =
javaClassStatic()->getMethod<JBaseJavaModule::javaobject()>(
"getModule");
return getModule(self()); return getModule(self());
} }
@ -44,9 +47,13 @@ struct JavaModuleWrapper : jni::JavaClass<JavaModuleWrapper> {
return getName(self())->toStdString(); return getName(self())->toStdString();
} }
jni::local_ref<jni::JList<JMethodDescriptor::javaobject>::javaobject> getMethodDescriptors() { jni::local_ref<jni::JList<JMethodDescriptor::javaobject>::javaobject>
static auto getMethods = getClass() getMethodDescriptors() {
->getMethod<jni::JList<JMethodDescriptor::javaobject>::javaobject()>("getMethodDescriptors"); static auto getMethods =
getClass()
->getMethod<
jni::JList<JMethodDescriptor::javaobject>::javaobject()>(
"getMethodDescriptors");
return getMethods(self()); return getMethods(self());
} }
}; };
@ -54,18 +61,21 @@ struct JavaModuleWrapper : jni::JavaClass<JavaModuleWrapper> {
class JavaNativeModule : public NativeModule { class JavaNativeModule : public NativeModule {
public: public:
JavaNativeModule( JavaNativeModule(
std::weak_ptr<Instance> instance, std::weak_ptr<Instance> instance,
jni::alias_ref<JavaModuleWrapper::javaobject> wrapper, jni::alias_ref<JavaModuleWrapper::javaobject> wrapper,
std::shared_ptr<MessageQueueThread> messageQueueThread) std::shared_ptr<MessageQueueThread> messageQueueThread)
: instance_(std::move(instance)) : instance_(std::move(instance)),
, wrapper_(make_global(wrapper)) wrapper_(make_global(wrapper)),
, messageQueueThread_(std::move(messageQueueThread)) {} messageQueueThread_(std::move(messageQueueThread)) {}
std::string getName() override; std::string getName() override;
folly::dynamic getConstants() override; folly::dynamic getConstants() override;
std::vector<MethodDescriptor> getMethods() override; std::vector<MethodDescriptor> getMethods() override;
void invoke(unsigned int reactMethodId, folly::dynamic&& params, int callId) override; void invoke(unsigned int reactMethodId, folly::dynamic &&params, int callId)
MethodCallResult callSerializableNativeHook(unsigned int reactMethodId, folly::dynamic&& params) override; override;
MethodCallResult callSerializableNativeHook(
unsigned int reactMethodId,
folly::dynamic &&params) override;
private: private:
std::weak_ptr<Instance> instance_; std::weak_ptr<Instance> instance_;
@ -78,15 +88,18 @@ class JavaNativeModule : public NativeModule {
class NewJavaNativeModule : public NativeModule { class NewJavaNativeModule : public NativeModule {
public: public:
NewJavaNativeModule( NewJavaNativeModule(
std::weak_ptr<Instance> instance, std::weak_ptr<Instance> instance,
jni::alias_ref<JavaModuleWrapper::javaobject> wrapper, jni::alias_ref<JavaModuleWrapper::javaobject> wrapper,
std::shared_ptr<MessageQueueThread> messageQueueThread); std::shared_ptr<MessageQueueThread> messageQueueThread);
std::string getName() override; std::string getName() override;
std::vector<MethodDescriptor> getMethods() override; std::vector<MethodDescriptor> getMethods() override;
folly::dynamic getConstants() override; folly::dynamic getConstants() override;
void invoke(unsigned int reactMethodId, folly::dynamic&& params, int callId) override; void invoke(unsigned int reactMethodId, folly::dynamic &&params, int callId)
MethodCallResult callSerializableNativeHook(unsigned int reactMethodId, folly::dynamic&& params) override; override;
MethodCallResult callSerializableNativeHook(
unsigned int reactMethodId,
folly::dynamic &&params) override;
private: private:
std::weak_ptr<Instance> instance_; std::weak_ptr<Instance> instance_;
@ -96,7 +109,10 @@ class NewJavaNativeModule : public NativeModule {
std::vector<MethodInvoker> methods_; std::vector<MethodInvoker> methods_;
std::vector<MethodDescriptor> methodDescriptors_; std::vector<MethodDescriptor> methodDescriptors_;
MethodCallResult invokeInner(unsigned int reactMethodId, folly::dynamic&& params); MethodCallResult invokeInner(
unsigned int reactMethodId,
folly::dynamic &&params);
}; };
}} } // namespace react
} // namespace facebook

Просмотреть файл

@ -13,10 +13,11 @@
namespace facebook { namespace facebook {
namespace react { namespace react {
class JavaScriptExecutorHolder : public jni::HybridClass<JavaScriptExecutorHolder> { class JavaScriptExecutorHolder
: public jni::HybridClass<JavaScriptExecutorHolder> {
public: public:
static constexpr auto kJavaDescriptor = static constexpr auto kJavaDescriptor =
"Lcom/facebook/react/bridge/JavaScriptExecutor;"; "Lcom/facebook/react/bridge/JavaScriptExecutor;";
std::shared_ptr<JSExecutorFactory> getExecutorFactory() { std::shared_ptr<JSExecutorFactory> getExecutorFactory() {
return mExecutorFactory; return mExecutorFactory;
@ -30,4 +31,5 @@ class JavaScriptExecutorHolder : public jni::HybridClass<JavaScriptExecutorHolde
std::shared_ptr<JSExecutorFactory> mExecutorFactory; std::shared_ptr<JSExecutorFactory> mExecutorFactory;
}; };
}} } // namespace react
} // namespace facebook

Просмотреть файл

@ -32,9 +32,12 @@ namespace {
using dynamic_iterator = folly::dynamic::const_iterator; using dynamic_iterator = folly::dynamic::const_iterator;
struct JPromiseImpl : public JavaClass<JPromiseImpl> { struct JPromiseImpl : public JavaClass<JPromiseImpl> {
constexpr static auto kJavaDescriptor = "Lcom/facebook/react/bridge/PromiseImpl;"; constexpr static auto kJavaDescriptor =
"Lcom/facebook/react/bridge/PromiseImpl;";
static local_ref<javaobject> create(local_ref<JCallback::javaobject> resolve, local_ref<JCallback::javaobject> reject) { static local_ref<javaobject> create(
local_ref<JCallback::javaobject> resolve,
local_ref<JCallback::javaobject> reject) {
return newInstance(resolve, reject); return newInstance(resolve, reject);
} }
}; };
@ -42,10 +45,10 @@ struct JPromiseImpl : public JavaClass<JPromiseImpl> {
// HACK: Exposes constructor // HACK: Exposes constructor
struct ExposedReadableNativeArray : public ReadableNativeArray { struct ExposedReadableNativeArray : public ReadableNativeArray {
explicit ExposedReadableNativeArray(folly::dynamic array) explicit ExposedReadableNativeArray(folly::dynamic array)
: ReadableNativeArray(std::move(array)) {} : ReadableNativeArray(std::move(array)) {}
}; };
jdouble extractDouble(const folly::dynamic& value) { jdouble extractDouble(const folly::dynamic &value) {
if (value.isInt()) { if (value.isInt()) {
return static_cast<jdouble>(value.getInt()); return static_cast<jdouble>(value.getInt());
} else { } else {
@ -53,7 +56,7 @@ jdouble extractDouble(const folly::dynamic& value) {
} }
} }
jint extractInteger(const folly::dynamic& value) { jint extractInteger(const folly::dynamic &value) {
// The logic here is taken from convertDynamicIfIntegral, but the // The logic here is taken from convertDynamicIfIntegral, but the
// return type and exception are different. // return type and exception are different.
if (value.isInt()) { if (value.isInt()) {
@ -62,14 +65,16 @@ jint extractInteger(const folly::dynamic& value) {
double dbl = value.getDouble(); double dbl = value.getDouble();
jint result = static_cast<jint>(dbl); jint result = static_cast<jint>(dbl);
if (dbl != result) { if (dbl != result) {
throw std::invalid_argument( throw std::invalid_argument(folly::to<std::string>(
folly::to<std::string>( "Tried to convert jint argument, but got a non-integral double: ",
"Tried to convert jint argument, but got a non-integral double: ", dbl)); dbl));
} }
return result; return result;
} }
local_ref<JCxxCallbackImpl::jhybridobject> extractCallback(std::weak_ptr<Instance>& instance, const folly::dynamic& value) { local_ref<JCxxCallbackImpl::jhybridobject> extractCallback(
std::weak_ptr<Instance> &instance,
const folly::dynamic &value) {
if (value.isNull()) { if (value.isNull()) {
return local_ref<JCxxCallbackImpl::jhybridobject>(nullptr); return local_ref<JCxxCallbackImpl::jhybridobject>(nullptr);
} else { } else {
@ -77,7 +82,10 @@ local_ref<JCxxCallbackImpl::jhybridobject> extractCallback(std::weak_ptr<Instanc
} }
} }
local_ref<JPromiseImpl::javaobject> extractPromise(std::weak_ptr<Instance>& instance, dynamic_iterator& it, dynamic_iterator& end) { local_ref<JPromiseImpl::javaobject> extractPromise(
std::weak_ptr<Instance> &instance,
dynamic_iterator &it,
dynamic_iterator &end) {
auto resolve = extractCallback(instance, *it++); auto resolve = extractCallback(instance, *it++);
CHECK(it != end); CHECK(it != end);
auto reject = extractCallback(instance, *it++); auto reject = extractCallback(instance, *it++);
@ -95,11 +103,16 @@ bool isNullable(char type) {
case 'X': case 'X':
return true; return true;
default: default:
return false;; return false;
;
} }
} }
jvalue extract(std::weak_ptr<Instance>& instance, char type, dynamic_iterator& it, dynamic_iterator& end) { jvalue extract(
std::weak_ptr<Instance> &instance,
char type,
dynamic_iterator &it,
dynamic_iterator &end) {
CHECK(it != end); CHECK(it != end);
jvalue value; jvalue value;
if (type == 'P') { if (type == 'P') {
@ -107,7 +120,7 @@ jvalue extract(std::weak_ptr<Instance>& instance, char type, dynamic_iterator& i
return value; return value;
} }
const auto& arg = *it++; const auto &arg = *it++;
if (isNullable(type) && arg.isNull()) { if (isNullable(type) && arg.isNull()) {
value.l = nullptr; value.l = nullptr;
return value; return value;
@ -118,7 +131,8 @@ jvalue extract(std::weak_ptr<Instance>& instance, char type, dynamic_iterator& i
value.z = static_cast<jboolean>(arg.getBool()); value.z = static_cast<jboolean>(arg.getBool());
break; break;
case 'Z': case 'Z':
value.l = JBoolean::valueOf(static_cast<jboolean>(arg.getBool())).release(); value.l =
JBoolean::valueOf(static_cast<jboolean>(arg.getBool())).release();
break; break;
case 'i': case 'i':
value.i = extractInteger(arg); value.i = extractInteger(arg);
@ -130,7 +144,8 @@ jvalue extract(std::weak_ptr<Instance>& instance, char type, dynamic_iterator& i
value.f = static_cast<jfloat>(extractDouble(arg)); value.f = static_cast<jfloat>(extractDouble(arg));
break; break;
case 'F': case 'F':
value.l = JFloat::valueOf(static_cast<jfloat>(extractDouble(arg))).release(); value.l =
JFloat::valueOf(static_cast<jfloat>(extractDouble(arg))).release();
break; break;
case 'd': case 'd':
value.d = extractDouble(arg); value.d = extractDouble(arg);
@ -156,7 +171,7 @@ jvalue extract(std::weak_ptr<Instance>& instance, char type, dynamic_iterator& i
return value; return value;
} }
std::size_t countJsArgs(const std::string& signature) { std::size_t countJsArgs(const std::string &signature) {
std::size_t count = 0; std::size_t count = 0;
for (char c : signature) { for (char c : signature) {
switch (c) { switch (c) {
@ -171,29 +186,38 @@ std::size_t countJsArgs(const std::string& signature) {
return count; return count;
} }
} // namespace
MethodInvoker::MethodInvoker(
alias_ref<JReflectMethod::javaobject> method,
std::string signature,
std::string traceName,
bool isSync)
: method_(method->getMethodID()),
signature_(signature),
jsArgCount_(countJsArgs(signature) - 2),
traceName_(std::move(traceName)),
isSync_(isSync) {
CHECK(signature_.at(1) == '.') << "Improper module method signature";
CHECK(isSync_ || signature_.at(0) == 'v')
<< "Non-sync hooks cannot have a non-void return type";
} }
MethodInvoker::MethodInvoker(alias_ref<JReflectMethod::javaobject> method, std::string signature, std::string traceName, bool isSync) MethodCallResult MethodInvoker::invoke(
: method_(method->getMethodID()), std::weak_ptr<Instance> &instance,
signature_(signature), alias_ref<JBaseJavaModule::javaobject> module,
jsArgCount_(countJsArgs(signature) -2), const folly::dynamic &params) {
traceName_(std::move(traceName)), #ifdef WITH_FBSYSTRACE
isSync_(isSync) {
CHECK(signature_.at(1) == '.') << "Improper module method signature";
CHECK(isSync_ || signature_.at(0) == 'v') << "Non-sync hooks cannot have a non-void return type";
}
MethodCallResult MethodInvoker::invoke(std::weak_ptr<Instance>& instance, alias_ref<JBaseJavaModule::javaobject> module, const folly::dynamic& params) {
#ifdef WITH_FBSYSTRACE
fbsystrace::FbSystraceSection s( fbsystrace::FbSystraceSection s(
TRACE_TAG_REACT_CXX_BRIDGE, TRACE_TAG_REACT_CXX_BRIDGE,
isSync_ ? "callJavaSyncHook" : "callJavaModuleMethod", isSync_ ? "callJavaSyncHook" : "callJavaModuleMethod",
"method", "method",
traceName_); traceName_);
#endif #endif
if (params.size() != jsArgCount_) { if (params.size() != jsArgCount_) {
throw std::invalid_argument(folly::to<std::string>("expected ", jsArgCount_, " arguments, got ", params.size())); throw std::invalid_argument(folly::to<std::string>(
"expected ", jsArgCount_, " arguments, got ", params.size()));
} }
auto env = Environment::current(); auto env = Environment::current();
@ -201,44 +225,48 @@ MethodCallResult MethodInvoker::invoke(std::weak_ptr<Instance>& instance, alias_
JniLocalScope scope(env, argCount); JniLocalScope scope(env, argCount);
jvalue args[argCount]; jvalue args[argCount];
std::transform( std::transform(
signature_.begin() + 2, signature_.begin() + 2,
signature_.end(), signature_.end(),
args, args,
[&instance, it = params.begin(), end = params.end()] (char type) mutable { [&instance, it = params.begin(), end = params.end()](char type) mutable {
return extract(instance, type, it, end); return extract(instance, type, it, end);
}); });
#define PRIMITIVE_CASE(METHOD) { \ #define PRIMITIVE_CASE(METHOD) \
auto result = env->Call ## METHOD ## MethodA(module.get(), method_, args); \ { \
throwPendingJniExceptionAsCppException(); \ auto result = env->Call##METHOD##MethodA(module.get(), method_, args); \
return folly::dynamic(result); \ throwPendingJniExceptionAsCppException(); \
} return folly::dynamic(result); \
}
#define PRIMITIVE_CASE_CASTING(METHOD, RESULT_TYPE) { \ #define PRIMITIVE_CASE_CASTING(METHOD, RESULT_TYPE) \
auto result = env->Call ## METHOD ## MethodA(module.get(), method_, args); \ { \
throwPendingJniExceptionAsCppException(); \ auto result = env->Call##METHOD##MethodA(module.get(), method_, args); \
return folly::dynamic(static_cast<RESULT_TYPE>(result)); \ throwPendingJniExceptionAsCppException(); \
} return folly::dynamic(static_cast<RESULT_TYPE>(result)); \
}
#define OBJECT_CASE(JNI_CLASS, ACTIONS) { \ #define OBJECT_CASE(JNI_CLASS, ACTIONS) \
auto jobject = env->CallObjectMethodA(module.get(), method_, args); \ { \
throwPendingJniExceptionAsCppException(); \ auto jobject = env->CallObjectMethodA(module.get(), method_, args); \
if (!jobject) { \ throwPendingJniExceptionAsCppException(); \
return folly::dynamic(nullptr); \ if (!jobject) { \
} \ return folly::dynamic(nullptr); \
auto result = adopt_local(static_cast<JNI_CLASS::javaobject>(jobject)); \ } \
return folly::dynamic(result->ACTIONS()); \ auto result = adopt_local(static_cast<JNI_CLASS::javaobject>(jobject)); \
} return folly::dynamic(result->ACTIONS()); \
}
#define OBJECT_CASE_CASTING(JNI_CLASS, ACTIONS, RESULT_TYPE) { \ #define OBJECT_CASE_CASTING(JNI_CLASS, ACTIONS, RESULT_TYPE) \
auto jobject = env->CallObjectMethodA(module.get(), method_, args); \ { \
throwPendingJniExceptionAsCppException(); \ auto jobject = env->CallObjectMethodA(module.get(), method_, args); \
if (!jobject) { \ throwPendingJniExceptionAsCppException(); \
return folly::dynamic(nullptr); \ if (!jobject) { \
} \ return folly::dynamic(nullptr); \
auto result = adopt_local(static_cast<JNI_CLASS::javaobject>(jobject)); \ } \
return folly::dynamic(static_cast<RESULT_TYPE>(result->ACTIONS())); \ auto result = adopt_local(static_cast<JNI_CLASS::javaobject>(jobject)); \
} return folly::dynamic(static_cast<RESULT_TYPE>(result->ACTIONS())); \
}
char returnType = signature_.at(0); char returnType = signature_.at(0);
switch (returnType) { switch (returnType) {
@ -277,5 +305,5 @@ MethodCallResult MethodInvoker::invoke(std::weak_ptr<Instance>& instance, alias_
} }
} }
} } // namespace react
} } // namespace facebook

Просмотреть файл

@ -29,19 +29,28 @@ struct JReflectMethod : public jni::JavaClass<JReflectMethod> {
}; };
struct JBaseJavaModule : public jni::JavaClass<JBaseJavaModule> { struct JBaseJavaModule : public jni::JavaClass<JBaseJavaModule> {
static constexpr auto kJavaDescriptor = "Lcom/facebook/react/bridge/BaseJavaModule;"; static constexpr auto kJavaDescriptor =
"Lcom/facebook/react/bridge/BaseJavaModule;";
}; };
class MethodInvoker { class MethodInvoker {
public: public:
MethodInvoker(jni::alias_ref<JReflectMethod::javaobject> method, std::string signature, std::string traceName, bool isSync); MethodInvoker(
jni::alias_ref<JReflectMethod::javaobject> method,
std::string signature,
std::string traceName,
bool isSync);
MethodCallResult invoke(std::weak_ptr<Instance>& instance, jni::alias_ref<JBaseJavaModule::javaobject> module, const folly::dynamic& params); MethodCallResult invoke(
std::weak_ptr<Instance> &instance,
jni::alias_ref<JBaseJavaModule::javaobject> module,
const folly::dynamic &params);
bool isSyncHook() const { bool isSyncHook() const {
return isSync_; return isSync_;
} }
private:
private:
jmethodID method_; jmethodID method_;
std::string signature_; std::string signature_;
std::size_t jsArgCount_; std::size_t jsArgCount_;
@ -49,5 +58,5 @@ private:
bool isSync_; bool isSync_;
}; };
} } // namespace react
} } // namespace facebook

Просмотреть файл

@ -22,16 +22,19 @@ class MessageQueueThread;
class ModuleHolder : public jni::JavaClass<ModuleHolder> { class ModuleHolder : public jni::JavaClass<ModuleHolder> {
public: public:
static auto constexpr kJavaDescriptor = static auto constexpr kJavaDescriptor =
"Lcom/facebook/react/bridge/ModuleHolder;"; "Lcom/facebook/react/bridge/ModuleHolder;";
std::string getName() const; std::string getName() const;
xplat::module::CxxModule::Provider getProvider(const std::string& moduleName) const; xplat::module::CxxModule::Provider getProvider(
const std::string &moduleName) const;
}; };
std::vector<std::unique_ptr<NativeModule>> buildNativeModuleList( std::vector<std::unique_ptr<NativeModule>> buildNativeModuleList(
std::weak_ptr<Instance> winstance, std::weak_ptr<Instance> winstance,
jni::alias_ref<jni::JCollection<JavaModuleWrapper::javaobject>::javaobject> javaModules, jni::alias_ref<jni::JCollection<JavaModuleWrapper::javaobject>::javaobject>
jni::alias_ref<jni::JCollection<ModuleHolder::javaobject>::javaobject> cxxModules, javaModules,
std::shared_ptr<MessageQueueThread> moduleMessageQueue); jni::alias_ref<jni::JCollection<ModuleHolder::javaobject>::javaobject>
} cxxModules,
} std::shared_ptr<MessageQueueThread> moduleMessageQueue);
} // namespace react
} // namespace facebook

Просмотреть файл

@ -18,8 +18,10 @@ namespace react {
NativeArray::NativeArray(folly::dynamic array) NativeArray::NativeArray(folly::dynamic array)
: isConsumed(false), array_(std::move(array)) { : isConsumed(false), array_(std::move(array)) {
if (!array_.isArray()) { if (!array_.isArray()) {
throwNewJavaException(exceptions::gUnexpectedNativeTypeExceptionClass, throwNewJavaException(
"expected Array, got a %s", array_.typeName()); exceptions::gUnexpectedNativeTypeExceptionClass,
"expected Array, got a %s",
array_.typeName());
} }
} }
@ -30,7 +32,7 @@ local_ref<jstring> NativeArray::toString() {
void NativeArray::registerNatives() { void NativeArray::registerNatives() {
registerHybrid({ registerHybrid({
makeNativeMethod("toString", NativeArray::toString), makeNativeMethod("toString", NativeArray::toString),
}); });
} }
@ -44,5 +46,5 @@ void NativeArray::throwIfConsumed() {
exceptions::throwIfObjectAlreadyConsumed(this, "Array already consumed"); exceptions::throwIfObjectAlreadyConsumed(this, "Array already consumed");
} }
} } // namespace react
} } // namespace facebook

Просмотреть файл

@ -17,7 +17,8 @@ namespace react {
class NativeArray : public jni::HybridClass<NativeArray> { class NativeArray : public jni::HybridClass<NativeArray> {
public: public:
static constexpr const char* kJavaDescriptor = "Lcom/facebook/react/bridge/NativeArray;"; static constexpr const char *kJavaDescriptor =
"Lcom/facebook/react/bridge/NativeArray;";
jni::local_ref<jstring> toString(); jni::local_ref<jstring> toString();
@ -37,4 +38,5 @@ class NativeArray : public jni::HybridClass<NativeArray> {
explicit NativeArray(folly::dynamic array); explicit NativeArray(folly::dynamic array);
}; };
}} } // namespace react
} // namespace facebook

Просмотреть файл

@ -18,7 +18,8 @@ namespace facebook {
namespace react { namespace react {
struct ReadableType : public jni::JavaClass<ReadableType> { struct ReadableType : public jni::JavaClass<ReadableType> {
static auto constexpr kJavaDescriptor = "Lcom/facebook/react/bridge/ReadableType;"; static auto constexpr kJavaDescriptor =
"Lcom/facebook/react/bridge/ReadableType;";
static jni::local_ref<ReadableType> getType(folly::dynamic::Type type); static jni::local_ref<ReadableType> getType(folly::dynamic::Type type);
}; };
@ -28,9 +29,10 @@ namespace exceptions {
extern const char *gUnexpectedNativeTypeExceptionClass; extern const char *gUnexpectedNativeTypeExceptionClass;
template <typename T> template <typename T>
void throwIfObjectAlreadyConsumed(const T& t, const char* msg) { void throwIfObjectAlreadyConsumed(const T &t, const char *msg) {
if (t->isConsumed) { if (t->isConsumed) {
jni::throwNewJavaException("com/facebook/react/bridge/ObjectAlreadyConsumedException", msg); jni::throwNewJavaException(
"com/facebook/react/bridge/ObjectAlreadyConsumedException", msg);
} }
} }

Просмотреть файл

@ -17,7 +17,8 @@ namespace react {
class NativeMap : public jni::HybridClass<NativeMap> { class NativeMap : public jni::HybridClass<NativeMap> {
public: public:
static auto constexpr kJavaDescriptor = "Lcom/facebook/react/bridge/NativeMap;"; static auto constexpr kJavaDescriptor =
"Lcom/facebook/react/bridge/NativeMap;";
std::string toString(); std::string toString();
@ -38,5 +39,5 @@ class NativeMap : public jni::HybridClass<NativeMap> {
explicit NativeMap(folly::dynamic s) : isConsumed(false), map_(s) {} explicit NativeMap(folly::dynamic s) : isConsumed(false), map_(s) {}
}; };
} // namespace react } // namespace react
} // namespace facebook } // namespace facebook

Просмотреть файл

@ -10,8 +10,8 @@
#include <cxxreact/JSBigString.h> #include <cxxreact/JSBigString.h>
#include <cxxreact/ModuleRegistry.h> #include <cxxreact/ModuleRegistry.h>
#include <cxxreact/SystraceSection.h> #include <cxxreact/SystraceSection.h>
#include <fb/assert.h>
#include <fb/Environment.h> #include <fb/Environment.h>
#include <fb/assert.h>
#include <folly/json.h> #include <folly/json.h>
#include <jni/LocalReference.h> #include <jni/LocalReference.h>
#include <jni/LocalString.h> #include <jni/LocalString.h>
@ -25,28 +25,29 @@ const auto EXECUTOR_BASECLASS = "com/facebook/react/bridge/JavaJSExecutor";
static std::string executeJSCallWithProxy( static std::string executeJSCallWithProxy(
jobject executor, jobject executor,
const std::string& methodName, const std::string &methodName,
const folly::dynamic& arguments) { const folly::dynamic &arguments) {
static auto executeJSCall = static auto executeJSCall =
jni::findClassStatic(EXECUTOR_BASECLASS)->getMethod<jstring(jstring, jstring)>("executeJSCall"); jni::findClassStatic(EXECUTOR_BASECLASS)
->getMethod<jstring(jstring, jstring)>("executeJSCall");
auto result = executeJSCall( auto result = executeJSCall(
executor, executor,
jni::make_jstring(methodName).get(), jni::make_jstring(methodName).get(),
jni::make_jstring(folly::toJson(arguments).c_str()).get()); jni::make_jstring(folly::toJson(arguments).c_str()).get());
return result->toString(); return result->toString();
} }
std::unique_ptr<JSExecutor> ProxyExecutorOneTimeFactory::createJSExecutor( std::unique_ptr<JSExecutor> ProxyExecutorOneTimeFactory::createJSExecutor(
std::shared_ptr<ExecutorDelegate> delegate, std::shared_ptr<MessageQueueThread>) { std::shared_ptr<ExecutorDelegate> delegate,
std::shared_ptr<MessageQueueThread>) {
return std::make_unique<ProxyExecutor>(std::move(m_executor), delegate); return std::make_unique<ProxyExecutor>(std::move(m_executor), delegate);
} }
ProxyExecutor::ProxyExecutor(jni::global_ref<jobject>&& executorInstance, ProxyExecutor::ProxyExecutor(
std::shared_ptr<ExecutorDelegate> delegate) jni::global_ref<jobject> &&executorInstance,
: m_executor(std::move(executorInstance)) std::shared_ptr<ExecutorDelegate> delegate)
, m_delegate(delegate) : m_executor(std::move(executorInstance)), m_delegate(delegate) {}
{}
ProxyExecutor::~ProxyExecutor() { ProxyExecutor::~ProxyExecutor() {
m_executor.reset(); m_executor.reset();
@ -55,79 +56,88 @@ ProxyExecutor::~ProxyExecutor() {
void ProxyExecutor::loadApplicationScript( void ProxyExecutor::loadApplicationScript(
std::unique_ptr<const JSBigString>, std::unique_ptr<const JSBigString>,
std::string sourceURL) { std::string sourceURL) {
folly::dynamic nativeModuleConfig = folly::dynamic::array; folly::dynamic nativeModuleConfig = folly::dynamic::array;
{ {
SystraceSection s("collectNativeModuleDescriptions"); SystraceSection s("collectNativeModuleDescriptions");
auto moduleRegistry = m_delegate->getModuleRegistry(); auto moduleRegistry = m_delegate->getModuleRegistry();
for (const auto& name : moduleRegistry->moduleNames()) { for (const auto &name : moduleRegistry->moduleNames()) {
auto config = moduleRegistry->getConfig(name); auto config = moduleRegistry->getConfig(name);
nativeModuleConfig.push_back(config ? config->config : nullptr); nativeModuleConfig.push_back(config ? config->config : nullptr);
} }
} }
folly::dynamic config = folly::dynamic config = folly::dynamic::object(
folly::dynamic::object "remoteModuleConfig", std::move(nativeModuleConfig));
("remoteModuleConfig", std::move(nativeModuleConfig));
{ {
SystraceSection t("setGlobalVariable"); SystraceSection t("setGlobalVariable");
setGlobalVariable( setGlobalVariable(
"__fbBatchedBridgeConfig", "__fbBatchedBridgeConfig",
std::make_unique<JSBigStdString>(folly::toJson(config))); std::make_unique<JSBigStdString>(folly::toJson(config)));
} }
static auto loadApplicationScript = static auto loadApplicationScript =
jni::findClassStatic(EXECUTOR_BASECLASS)->getMethod<void(jstring)>("loadApplicationScript"); jni::findClassStatic(EXECUTOR_BASECLASS)
->getMethod<void(jstring)>("loadApplicationScript");
// The proxy ignores the script data passed in. // The proxy ignores the script data passed in.
loadApplicationScript( loadApplicationScript(m_executor.get(), jni::make_jstring(sourceURL).get());
m_executor.get(),
jni::make_jstring(sourceURL).get());
// We can get pending calls here to native but the queue will be drained when // We can get pending calls here to native but the queue will be drained when
// we launch the application. // we launch the application.
} }
void ProxyExecutor::setBundleRegistry(std::unique_ptr<RAMBundleRegistry>) { void ProxyExecutor::setBundleRegistry(std::unique_ptr<RAMBundleRegistry>) {
jni::throwNewJavaException( jni::throwNewJavaException(
"java/lang/UnsupportedOperationException", "java/lang/UnsupportedOperationException",
"Loading application RAM bundles is not supported for proxy executors"); "Loading application RAM bundles is not supported for proxy executors");
} }
void ProxyExecutor::registerBundle(uint32_t bundleId, const std::string& bundlePath) { void ProxyExecutor::registerBundle(
uint32_t bundleId,
const std::string &bundlePath) {
jni::throwNewJavaException( jni::throwNewJavaException(
"java/lang/UnsupportedOperationException", "java/lang/UnsupportedOperationException",
"Loading application RAM bundles is not supported for proxy executors"); "Loading application RAM bundles is not supported for proxy executors");
} }
void ProxyExecutor::callFunction(const std::string& moduleId, const std::string& methodId, const folly::dynamic& arguments) { void ProxyExecutor::callFunction(
const std::string &moduleId,
const std::string &methodId,
const folly::dynamic &arguments) {
auto call = folly::dynamic::array(moduleId, methodId, std::move(arguments)); auto call = folly::dynamic::array(moduleId, methodId, std::move(arguments));
std::string result = executeJSCallWithProxy(m_executor.get(), "callFunctionReturnFlushedQueue", std::move(call)); std::string result = executeJSCallWithProxy(
m_executor.get(), "callFunctionReturnFlushedQueue", std::move(call));
m_delegate->callNativeModules(*this, folly::parseJson(result), true); m_delegate->callNativeModules(*this, folly::parseJson(result), true);
} }
void ProxyExecutor::invokeCallback(const double callbackId, const folly::dynamic& arguments) { void ProxyExecutor::invokeCallback(
const double callbackId,
const folly::dynamic &arguments) {
auto call = folly::dynamic::array(callbackId, std::move(arguments)); auto call = folly::dynamic::array(callbackId, std::move(arguments));
std::string result = executeJSCallWithProxy(m_executor.get(), "invokeCallbackAndReturnFlushedQueue", std::move(call)); std::string result = executeJSCallWithProxy(
m_executor.get(), "invokeCallbackAndReturnFlushedQueue", std::move(call));
m_delegate->callNativeModules(*this, folly::parseJson(result), true); m_delegate->callNativeModules(*this, folly::parseJson(result), true);
} }
void ProxyExecutor::setGlobalVariable(std::string propName, void ProxyExecutor::setGlobalVariable(
std::unique_ptr<const JSBigString> jsonValue) { std::string propName,
std::unique_ptr<const JSBigString> jsonValue) {
static auto setGlobalVariable = static auto setGlobalVariable =
jni::findClassStatic(EXECUTOR_BASECLASS)->getMethod<void(jstring, jstring)>("setGlobalVariable"); jni::findClassStatic(EXECUTOR_BASECLASS)
->getMethod<void(jstring, jstring)>("setGlobalVariable");
setGlobalVariable( setGlobalVariable(
m_executor.get(), m_executor.get(),
jni::make_jstring(propName).get(), jni::make_jstring(propName).get(),
jni::make_jstring(jsonValue->c_str()).get()); jni::make_jstring(jsonValue->c_str()).get());
} }
std::string ProxyExecutor::getDescription() { std::string ProxyExecutor::getDescription() {
return "Chrome"; return "Chrome";
} }
} } } // namespace react
} // namespace facebook

Просмотреть файл

@ -17,48 +17,50 @@ namespace facebook {
namespace react { namespace react {
/** /**
* This executor factory can only create a single executor instance because it moves * This executor factory can only create a single executor instance because it
* executorInstance global reference to the executor instance it creates. * moves executorInstance global reference to the executor instance it creates.
*/ */
class ProxyExecutorOneTimeFactory : public JSExecutorFactory { class ProxyExecutorOneTimeFactory : public JSExecutorFactory {
public: public:
ProxyExecutorOneTimeFactory(jni::global_ref<jobject>&& executorInstance) : ProxyExecutorOneTimeFactory(jni::global_ref<jobject> &&executorInstance)
m_executor(std::move(executorInstance)) {} : m_executor(std::move(executorInstance)) {}
virtual std::unique_ptr<JSExecutor> createJSExecutor( virtual std::unique_ptr<JSExecutor> createJSExecutor(
std::shared_ptr<ExecutorDelegate> delegate, std::shared_ptr<ExecutorDelegate> delegate,
std::shared_ptr<MessageQueueThread> queue) override; std::shared_ptr<MessageQueueThread> queue) override;
private: private:
jni::global_ref<jobject> m_executor; jni::global_ref<jobject> m_executor;
}; };
class ProxyExecutor : public JSExecutor { class ProxyExecutor : public JSExecutor {
public: public:
ProxyExecutor(jni::global_ref<jobject>&& executorInstance, ProxyExecutor(
std::shared_ptr<ExecutorDelegate> delegate); jni::global_ref<jobject> &&executorInstance,
std::shared_ptr<ExecutorDelegate> delegate);
virtual ~ProxyExecutor() override; virtual ~ProxyExecutor() override;
virtual void loadApplicationScript( virtual void loadApplicationScript(
std::unique_ptr<const JSBigString> script, std::unique_ptr<const JSBigString> script,
std::string sourceURL) override; std::string sourceURL) override;
virtual void setBundleRegistry( virtual void setBundleRegistry(
std::unique_ptr<RAMBundleRegistry> bundle) override; std::unique_ptr<RAMBundleRegistry> bundle) override;
virtual void registerBundle( virtual void registerBundle(uint32_t bundleId, const std::string &bundlePath)
uint32_t bundleId, const std::string& bundlePath) override; override;
virtual void callFunction( virtual void callFunction(
const std::string& moduleId, const std::string &moduleId,
const std::string& methodId, const std::string &methodId,
const folly::dynamic& arguments) override; const folly::dynamic &arguments) override;
virtual void invokeCallback( virtual void invokeCallback(
const double callbackId, const double callbackId,
const folly::dynamic& arguments) override; const folly::dynamic &arguments) override;
virtual void setGlobalVariable( virtual void setGlobalVariable(
std::string propName, std::string propName,
std::unique_ptr<const JSBigString> jsonValue) override; std::unique_ptr<const JSBigString> jsonValue) override;
virtual std::string getDescription() override; virtual std::string getDescription() override;
private: private:
jni::global_ref<jobject> m_executor; jni::global_ref<jobject> m_executor;
std::shared_ptr<ExecutorDelegate> m_delegate; std::shared_ptr<ExecutorDelegate> m_delegate;
}; };
} } } // namespace react
} // namespace facebook

Просмотреть файл

@ -19,12 +19,14 @@ namespace react {
struct WritableNativeMap; struct WritableNativeMap;
struct WritableArray : jni::JavaClass<WritableArray> { struct WritableArray : jni::JavaClass<WritableArray> {
static auto constexpr kJavaDescriptor = "Lcom/facebook/react/bridge/WritableArray;"; static auto constexpr kJavaDescriptor =
"Lcom/facebook/react/bridge/WritableArray;";
}; };
struct WritableNativeArray struct WritableNativeArray
: public jni::HybridClass<WritableNativeArray, ReadableNativeArray> { : public jni::HybridClass<WritableNativeArray, ReadableNativeArray> {
static constexpr const char* kJavaDescriptor = "Lcom/facebook/react/bridge/WritableNativeArray;"; static constexpr const char *kJavaDescriptor =
"Lcom/facebook/react/bridge/WritableNativeArray;";
WritableNativeArray(); WritableNativeArray();
static jni::local_ref<jhybriddata> initHybrid(jni::alias_ref<jclass>); static jni::local_ref<jhybriddata> initHybrid(jni::alias_ref<jclass>);
@ -34,11 +36,11 @@ struct WritableNativeArray
void pushDouble(jdouble value); void pushDouble(jdouble value);
void pushInt(jint value); void pushInt(jint value);
void pushString(jstring value); void pushString(jstring value);
void pushNativeArray(WritableNativeArray* otherArray); void pushNativeArray(WritableNativeArray *otherArray);
void pushNativeMap(WritableNativeMap* map); void pushNativeMap(WritableNativeMap *map);
static void registerNatives(); static void registerNatives();
}; };
} } // namespace react
} } // namespace facebook

Просмотреть файл

@ -18,14 +18,17 @@ namespace facebook {
namespace react { namespace react {
struct WritableMap : jni::JavaClass<WritableMap> { struct WritableMap : jni::JavaClass<WritableMap> {
static auto constexpr kJavaDescriptor = "Lcom/facebook/react/bridge/WritableMap;"; static auto constexpr kJavaDescriptor =
"Lcom/facebook/react/bridge/WritableMap;";
}; };
struct WritableNativeMap : jni::HybridClass<WritableNativeMap, ReadableNativeMap> { struct WritableNativeMap
static auto constexpr kJavaDescriptor = "Lcom/facebook/react/bridge/WritableNativeMap;"; : jni::HybridClass<WritableNativeMap, ReadableNativeMap> {
static auto constexpr kJavaDescriptor =
"Lcom/facebook/react/bridge/WritableNativeMap;";
WritableNativeMap(); WritableNativeMap();
WritableNativeMap(folly::dynamic&& val); WritableNativeMap(folly::dynamic &&val);
static jni::local_ref<jhybriddata> initHybrid(jni::alias_ref<jclass>); static jni::local_ref<jhybriddata> initHybrid(jni::alias_ref<jclass>);
@ -34,9 +37,9 @@ struct WritableNativeMap : jni::HybridClass<WritableNativeMap, ReadableNativeMap
void putDouble(std::string key, double val); void putDouble(std::string key, double val);
void putInt(std::string key, int val); void putInt(std::string key, int val);
void putString(std::string key, jni::alias_ref<jstring> val); void putString(std::string key, jni::alias_ref<jstring> val);
void putNativeArray(std::string key, WritableNativeArray* val); void putNativeArray(std::string key, WritableNativeArray *val);
void putNativeMap(std::string key, WritableNativeMap* val); void putNativeMap(std::string key, WritableNativeMap *val);
void mergeNativeMap(ReadableNativeMap* other); void mergeNativeMap(ReadableNativeMap *other);
static void registerNatives(); static void registerNatives();

Просмотреть файл

@ -5,13 +5,13 @@
* LICENSE file in the root directory of this source tree. * LICENSE file in the root directory of this source tree.
*/ */
#include <fb/log.h>
#include <fb/fbjni.h>
#include <cxxreact/CxxModule.h> #include <cxxreact/CxxModule.h>
#include <cxxreact/JsArgumentHelpers.h> #include <cxxreact/JsArgumentHelpers.h>
#include <fb/fbjni.h>
#include <fb/log.h>
#include <mutex>
#include <condition_variable> #include <condition_variable>
#include <mutex>
namespace facebook { namespace facebook {
namespace react { namespace react {
@ -27,9 +27,9 @@ namespace {
// really desperate, you can fix this by using ToReflectedMethod on the // really desperate, you can fix this by using ToReflectedMethod on the
// underlying jmethodid and invoking that. // underlying jmethodid and invoking that.
class JavaJSModule : public jni::JavaClass<JavaJSModule> { class JavaJSModule : public jni::JavaClass<JavaJSModule> {
public: public:
static constexpr auto kJavaDescriptor = static constexpr auto kJavaDescriptor =
"Lcom/facebook/react/CatalystBridgeBenchmarks$BridgeBenchmarkModule;"; "Lcom/facebook/react/CatalystBridgeBenchmarks$BridgeBenchmarkModule;";
static void bounceCxx(alias_ref<javaobject> obj, int iters) { static void bounceCxx(alias_ref<javaobject> obj, int iters) {
static auto method = javaClassLocal()->getMethod<void(jint)>("bounceCxx"); static auto method = javaClassLocal()->getMethod<void(jint)>("bounceCxx");
@ -39,20 +39,35 @@ public:
static void bounceArgsCxx( static void bounceArgsCxx(
alias_ref<javaobject> obj, alias_ref<javaobject> obj,
int iters, int iters,
int a, int b, int a,
double x, double y, int b,
const std::string& s, const std::string& t) { double x,
double y,
const std::string &s,
const std::string &t) {
static auto method = static auto method =
javaClassLocal()->getMethod<void(jint, jint, jint, jdouble, jdouble, jstring, jstring)>("bounceArgsCxx"); javaClassLocal()
method(obj, iters, a, b, x, y, jni::make_jstring(s).get(), jni::make_jstring(t).get()); ->getMethod<void(
jint, jint, jint, jdouble, jdouble, jstring, jstring)>(
"bounceArgsCxx");
method(
obj,
iters,
a,
b,
x,
y,
jni::make_jstring(s).get(),
jni::make_jstring(t).get());
} }
}; };
// This is just the test instance itself. Used only to countdown the latch. // This is just the test instance itself. Used only to countdown the latch.
class CatalystBridgeBenchmarks : public jni::JavaClass<CatalystBridgeBenchmarks> { class CatalystBridgeBenchmarks
public: : public jni::JavaClass<CatalystBridgeBenchmarks> {
public:
static constexpr auto kJavaDescriptor = static constexpr auto kJavaDescriptor =
"Lcom/facebook/react/CatalystBridgeBenchmarks;"; "Lcom/facebook/react/CatalystBridgeBenchmarks;";
static void countDown(alias_ref<javaobject> obj) { static void countDown(alias_ref<javaobject> obj) {
static auto method = javaClassLocal()->getMethod<void()>("countDown"); static auto method = javaClassLocal()->getMethod<void()>("countDown");
@ -72,7 +87,7 @@ Data data;
void runBounce(jni::alias_ref<jclass>, bool isLeft, int iters) { void runBounce(jni::alias_ref<jclass>, bool isLeft, int iters) {
for (int i = 0; i < iters; i++) { for (int i = 0; i < iters; i++) {
std::unique_lock<std::mutex> lk(data.m); std::unique_lock<std::mutex> lk(data.m);
data.cv.wait(lk, [&]{ return data.leftActive == isLeft; }); data.cv.wait(lk, [&] { return data.leftActive == isLeft; });
data.leftActive = !isLeft; data.leftActive = !isLeft;
data.cv.notify_one(); data.cv.notify_one();
} }
@ -82,30 +97,35 @@ static jni::global_ref<JavaJSModule::javaobject> jsModule;
static jni::global_ref<CatalystBridgeBenchmarks::javaobject> javaTestInstance; static jni::global_ref<CatalystBridgeBenchmarks::javaobject> javaTestInstance;
class CxxBenchmarkModule : public xplat::module::CxxModule { class CxxBenchmarkModule : public xplat::module::CxxModule {
public: public:
virtual std::string getName() override { virtual std::string getName() override {
return "CxxBenchmarkModule"; return "CxxBenchmarkModule";
} }
virtual auto getConstants() -> std::map<std::string, folly::dynamic> override { virtual auto getConstants()
-> std::map<std::string, folly::dynamic> override {
return std::map<std::string, folly::dynamic>(); return std::map<std::string, folly::dynamic>();
} }
virtual auto getMethods() -> std::vector<Method> override { virtual auto getMethods() -> std::vector<Method> override {
return std::vector<Method>{ return std::vector<Method>{
Method("bounce", [this] (folly::dynamic args) { Method(
this->bounce(xplat::jsArgAsInt(args, 0)); "bounce",
}), [this](folly::dynamic args) {
Method("bounceArgs", [this] (folly::dynamic args) { this->bounce(xplat::jsArgAsInt(args, 0));
this->bounceArgs( }),
xplat::jsArgAsInt(args, 0), Method(
xplat::jsArgAsInt(args, 1), "bounceArgs",
xplat::jsArgAsInt(args, 2), [this](folly::dynamic args) {
xplat::jsArgAsDouble(args, 3), this->bounceArgs(
xplat::jsArgAsDouble(args, 4), xplat::jsArgAsInt(args, 0),
xplat::jsArgAsString(args, 5), xplat::jsArgAsInt(args, 1),
xplat::jsArgAsString(args, 6)); xplat::jsArgAsInt(args, 2),
}), xplat::jsArgAsDouble(args, 3),
xplat::jsArgAsDouble(args, 4),
xplat::jsArgAsString(args, 5),
xplat::jsArgAsString(args, 6));
}),
}; };
} }
@ -119,9 +139,12 @@ public:
void bounceArgs( void bounceArgs(
int iters, int iters,
int a, int b, int a,
double x, double y, int b,
const std::string& s, const std::string& t) { double x,
double y,
const std::string &s,
const std::string &t) {
if (iters == 0) { if (iters == 0) {
CatalystBridgeBenchmarks::countDown(javaTestInstance); CatalystBridgeBenchmarks::countDown(javaTestInstance);
} else { } else {
@ -130,7 +153,6 @@ public:
} }
}; };
void setUp( void setUp(
alias_ref<CatalystBridgeBenchmarks::javaobject> obj, alias_ref<CatalystBridgeBenchmarks::javaobject> obj,
alias_ref<JavaJSModule::javaobject> mod) { alias_ref<JavaJSModule::javaobject> mod) {
@ -138,8 +160,7 @@ void setUp(
jsModule = jni::make_global(mod); jsModule = jni::make_global(mod);
} }
void tearDown( void tearDown(alias_ref<CatalystBridgeBenchmarks::javaobject>) {
alias_ref<CatalystBridgeBenchmarks::javaobject>) {
javaTestInstance.reset(); javaTestInstance.reset();
jsModule.reset(); jsModule.reset();
} }
@ -163,17 +184,21 @@ static void stubLogHandler(int pri, const char *tag, const char *msg) {
gHasSeenMessage |= priorityMatches && substringFound; gHasSeenMessage |= priorityMatches && substringFound;
} }
static jboolean hasSeenExpectedLogMessage(JNIEnv*, jclass) { static jboolean hasSeenExpectedLogMessage(JNIEnv *, jclass) {
return gHasSeenMessage ? JNI_TRUE : JNI_FALSE; return gHasSeenMessage ? JNI_TRUE : JNI_FALSE;
} }
static void stopWatchingLogMessages(JNIEnv*, jclass) { static void stopWatchingLogMessages(JNIEnv *, jclass) {
gMessageToLookFor = ""; gMessageToLookFor = "";
gHasSeenMessage = false; gHasSeenMessage = false;
setLogHandler(NULL); setLogHandler(NULL);
} }
static void startWatchingForLogMessage(JNIEnv* env, jclass loggerClass, jstring jmsg, jint priority) { static void startWatchingForLogMessage(
JNIEnv *env,
jclass loggerClass,
jstring jmsg,
jint priority) {
stopWatchingLogMessages(env, loggerClass); stopWatchingLogMessages(env, loggerClass);
gMessageToLookFor = jni::wrap_alias(jmsg)->toStdString(); gMessageToLookFor = jni::wrap_alias(jmsg)->toStdString();
gMessagePriorityToLookFor = priority; gMessagePriorityToLookFor = priority;
@ -187,24 +212,34 @@ static void startWatchingForLogMessage(JNIEnv* env, jclass loggerClass, jstring
using namespace facebook::react; using namespace facebook::react;
extern "C" facebook::xplat::module::CxxModule* CxxBenchmarkModule() { extern "C" facebook::xplat::module::CxxModule *CxxBenchmarkModule() {
return new facebook::react::CxxBenchmarkModule(); return new facebook::react::CxxBenchmarkModule();
} }
extern "C" jint JNI_OnLoad(JavaVM* vm, void*) { extern "C" jint JNI_OnLoad(JavaVM *vm, void *) {
return facebook::jni::initialize(vm, [] { return facebook::jni::initialize(vm, [] {
facebook::jni::registerNatives( facebook::jni::registerNatives(
"com/facebook/catalyst/testing/LogWatcher", { "com/facebook/catalyst/testing/LogWatcher",
makeNativeMethod("startWatchingForLogMessage", "(Ljava/lang/String;I)V", logwatcher::startWatchingForLogMessage), {
makeNativeMethod("stopWatchingLogMessages", "()V", logwatcher::stopWatchingLogMessages), makeNativeMethod(
makeNativeMethod("hasSeenExpectedLogMessage", "()Z", logwatcher::hasSeenExpectedLogMessage), "startWatchingForLogMessage",
}); "(Ljava/lang/String;I)V",
facebook::jni::registerNatives( logwatcher::startWatchingForLogMessage),
"com/facebook/react/CatalystBridgeBenchmarks", { makeNativeMethod(
makeNativeMethod("runNativeBounce", runBounce), "stopWatchingLogMessages",
makeNativeMethod("nativeSetUp", setUp), "()V",
makeNativeMethod("nativeTearDown", tearDown), logwatcher::stopWatchingLogMessages),
makeNativeMethod(
"hasSeenExpectedLogMessage",
"()Z",
logwatcher::hasSeenExpectedLogMessage),
}); });
}); facebook::jni::registerNatives(
"com/facebook/react/CatalystBridgeBenchmarks",
{
makeNativeMethod("runNativeBounce", runBounce),
makeNativeMethod("nativeSetUp", setUp),
makeNativeMethod("nativeTearDown", tearDown),
});
});
} }