Skip to content

Commit 5f75b9e

Browse files
authored
fix: Fix HostObject destructors to make sure a JNI Environment is set up (#2462)
* fix: Fix HostObject destructors to make sure a JNI Environment is set up * Use `reset` instead of `= nullptr` * Format * Format
1 parent 9e12975 commit 5f75b9e

File tree

5 files changed

+21
-9
lines changed

5 files changed

+21
-9
lines changed

package/android/src/main/cpp/MutableJByteBuffer.cpp

+4-1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ MutableJByteBuffer::MutableJByteBuffer(jni::alias_ref<jni::JByteBuffer> byteBuff
1515
}
1616

1717
MutableJByteBuffer::~MutableJByteBuffer() noexcept {
18+
// Hermes GC might destroy HostObjects on an arbitrary Thread which might not be
19+
// connected to the JNI environment. To make sure fbjni can properly destroy
20+
// the Java method, we connect to a JNI environment first.
1821
jni::ThreadScope::WithClassLoader([&] { _byteBuffer.reset(); });
1922
}
2023

@@ -30,4 +33,4 @@ jni::global_ref<jni::JByteBuffer> MutableJByteBuffer::getByteBuffer() {
3033
return _byteBuffer;
3134
}
3235

33-
} // namespace vision
36+
} // namespace vision

package/android/src/main/cpp/frameprocessor/FrameHostObject.cpp

+3-4
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,9 @@ using namespace facebook;
2222
FrameHostObject::FrameHostObject(const jni::alias_ref<JFrame::javaobject>& frame) : frame(make_global(frame)) {}
2323

2424
FrameHostObject::~FrameHostObject() {
25-
// Hermes' Garbage Collector (Hades GC) calls destructors on a separate Thread
26-
// which might not be attached to JNI. Ensure that we use the JNI class loader when
27-
// deallocating the `frame` HybridClass, because otherwise JNI cannot call the Java
28-
// destroy() function.
25+
// Hermes GC might destroy HostObjects on an arbitrary Thread which might not be
26+
// connected to the JNI environment. To make sure fbjni can properly destroy
27+
// the Java method, we connect to a JNI environment first.
2928
jni::ThreadScope::WithClassLoader([&] { frame.reset(); });
3029
}
3130

package/android/src/main/cpp/frameprocessor/FrameProcessorPluginHostObject.cpp

+3
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ FrameProcessorPluginHostObject::FrameProcessorPluginHostObject(jni::alias_ref<JF
1616
: _plugin(make_global(plugin)) {}
1717

1818
FrameProcessorPluginHostObject::~FrameProcessorPluginHostObject() {
19+
// Hermes GC might destroy HostObjects on an arbitrary Thread which might not be
20+
// connected to the JNI environment. To make sure fbjni can properly destroy
21+
// the Java method, we connect to a JNI environment first.
1922
jni::ThreadScope::WithClassLoader([&] { _plugin.reset(); });
2023
}
2124

package/android/src/main/cpp/frameprocessor/VisionCameraProxy.cpp

+10-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,12 @@ VisionCameraProxy::VisionCameraProxy(const jni::alias_ref<JVisionCameraProxy::ja
3030
_javaProxy = make_global(javaProxy);
3131
}
3232

33-
VisionCameraProxy::~VisionCameraProxy() {}
33+
VisionCameraProxy::~VisionCameraProxy() {
34+
// Hermes GC might destroy HostObjects on an arbitrary Thread which might not be
35+
// connected to the JNI environment. To make sure fbjni can properly destroy
36+
// the Java method, we connect to a JNI environment first.
37+
jni::ThreadScope::WithClassLoader([&] { _javaProxy.reset(); });
38+
}
3439

3540
std::vector<jsi::PropNameID> VisionCameraProxy::getPropertyNames(jsi::Runtime& runtime) {
3641
std::vector<jsi::PropNameID> result;
@@ -96,6 +101,10 @@ jsi::Value VisionCameraProxy::get(jsi::Runtime& runtime, const jsi::PropNameID&
96101
return jsi::Value::undefined();
97102
}
98103

104+
void VisionCameraInstaller::registerNatives() {
105+
javaClassStatic()->registerNatives({makeNativeMethod("install", VisionCameraInstaller::install)});
106+
}
107+
99108
void VisionCameraInstaller::install(jni::alias_ref<jni::JClass>, jni::alias_ref<JVisionCameraProxy::javaobject> proxy) {
100109
// global.VisionCameraProxy
101110
auto visionCameraProxy = std::make_shared<VisionCameraProxy>(proxy);

package/android/src/main/cpp/frameprocessor/VisionCameraProxy.h

+1-3
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,7 @@ class VisionCameraProxy : public jsi::HostObject {
3838
class VisionCameraInstaller : public jni::JavaClass<VisionCameraInstaller> {
3939
public:
4040
static auto constexpr kJavaDescriptor = "Lcom/mrousavy/camera/frameprocessor/VisionCameraInstaller;";
41-
static void registerNatives() {
42-
javaClassStatic()->registerNatives({makeNativeMethod("install", VisionCameraInstaller::install)});
43-
}
41+
static void registerNatives();
4442
static void install(jni::alias_ref<jni::JClass> clazz, jni::alias_ref<JVisionCameraProxy::javaobject> proxy);
4543
};
4644

0 commit comments

Comments
 (0)