Skip to content

Commit 0b002fb

Browse files
hoxyqfacebook-github-bot
authored andcommitted
Implement onStateChange in TracingStateListener jni interface (react#54824)
Summary: # Changelog: [Internal] The previous approach was causing a crash if we would attempt to register multiple listeners on Android side, because we would static-initialize different methods from different instances. When the native code tried to invoke onStateChanged on a different listener class, JNI threw an error. Instead, we will cache the interface method. Reviewed By: javache Differential Revision: D88734482
1 parent 602a2d2 commit 0b002fb

2 files changed

Lines changed: 43 additions & 50 deletions

File tree

packages/react-native/ReactAndroid/src/main/jni/react/runtime/jni/JReactHostInspectorTarget.cpp

Lines changed: 2 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -17,35 +17,6 @@ using namespace facebook::react::jsinspector_modern;
1717

1818
namespace facebook::react {
1919

20-
namespace {
21-
jni::local_ref<JTracingState::javaobject> convertCPPTracingStateToJava(
22-
TracingState tracingState) {
23-
auto tracingStateClass = jni::findClassLocal(
24-
"com/facebook/react/devsupport/inspector/TracingState");
25-
auto valueOfMethod =
26-
tracingStateClass->getStaticMethod<JTracingState(jstring)>("valueOf");
27-
28-
switch (tracingState) {
29-
case TracingState::Disabled:
30-
return valueOfMethod(
31-
tracingStateClass, jni::make_jstring("DISABLED").get());
32-
33-
case TracingState::EnabledInBackgroundMode:
34-
return valueOfMethod(
35-
tracingStateClass,
36-
jni::make_jstring("ENABLED_IN_BACKGROUND_MODE").get());
37-
38-
case TracingState::EnabledInCDPMode:
39-
return valueOfMethod(
40-
tracingStateClass, jni::make_jstring("ENABLED_IN_CDP_MODE").get());
41-
42-
default:
43-
jni::throwNewJavaException(
44-
"java/lang/IllegalStateException", "Unexpected new TracingState.");
45-
}
46-
}
47-
} // namespace
48-
4920
JReactHostInspectorTarget::JReactHostInspectorTarget(
5021
alias_ref<JReactHostInspectorTarget::javaobject> jobj,
5122
alias_ref<JReactHostImpl> reactHostImpl,
@@ -266,17 +237,8 @@ JReactHostInspectorTarget::getTracingState() {
266237
jlong JReactHostInspectorTarget::registerTracingStateListener(
267238
jni::alias_ref<JTracingStateListener::javaobject> listener) {
268239
auto cppListener = [globalRef = make_global(listener)](
269-
TracingState state, bool screenshotsEnabled) {
270-
static auto method =
271-
globalRef->getClass()
272-
->getMethod<void(
273-
jni::local_ref<JTracingState::javaobject>, jboolean)>(
274-
"onStateChanged");
275-
276-
method(
277-
globalRef,
278-
convertCPPTracingStateToJava(state),
279-
static_cast<jboolean>(screenshotsEnabled));
240+
TracingState tracingState, bool screenshotsEnabled) {
241+
globalRef->onStateChanged(tracingState, screenshotsEnabled);
280242
};
281243

282244
return static_cast<jlong>(

packages/react-native/ReactAndroid/src/main/jni/react/runtime/jni/JReactHostInspectorTarget.h

Lines changed: 41 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,53 @@
2020

2121
namespace facebook::react {
2222

23-
struct JTaskInterface : public jni::JavaClass<JTaskInterface> {
24-
static constexpr auto kJavaDescriptor = "Lcom/facebook/react/interfaces/TaskInterface;";
25-
};
26-
2723
struct JTracingState : public jni::JavaClass<JTracingState> {
2824
static constexpr auto kJavaDescriptor = "Lcom/facebook/react/devsupport/inspector/TracingState;";
2925
};
3026

27+
namespace {
28+
29+
enum class TracingState {
30+
Disabled,
31+
EnabledInBackgroundMode,
32+
EnabledInCDPMode,
33+
};
34+
35+
jni::local_ref<JTracingState::javaobject> convertCPPTracingStateToJava(TracingState tracingState)
36+
{
37+
auto tracingStateClass = jni::findClassLocal("com/facebook/react/devsupport/inspector/TracingState");
38+
auto valueOfMethod = tracingStateClass->getStaticMethod<JTracingState(jstring)>("valueOf");
39+
40+
switch (tracingState) {
41+
case TracingState::Disabled:
42+
return valueOfMethod(tracingStateClass, jni::make_jstring("DISABLED").get());
43+
44+
case TracingState::EnabledInBackgroundMode:
45+
return valueOfMethod(tracingStateClass, jni::make_jstring("ENABLED_IN_BACKGROUND_MODE").get());
46+
47+
case TracingState::EnabledInCDPMode:
48+
return valueOfMethod(tracingStateClass, jni::make_jstring("ENABLED_IN_CDP_MODE").get());
49+
50+
default:
51+
jni::throwNewJavaException("java/lang/IllegalStateException", "Unexpected new TracingState.");
52+
}
53+
}
54+
55+
} // namespace
56+
57+
struct JTaskInterface : public jni::JavaClass<JTaskInterface> {
58+
static constexpr auto kJavaDescriptor = "Lcom/facebook/react/interfaces/TaskInterface;";
59+
};
60+
3161
struct JTracingStateListener : public jni::JavaClass<JTracingStateListener> {
3262
static constexpr auto kJavaDescriptor = "Lcom/facebook/react/devsupport/inspector/TracingStateListener;";
63+
64+
void onStateChanged(TracingState tracingState, bool screenshotsEnabled) const
65+
{
66+
static auto method =
67+
javaClassStatic()->getMethod<void(jni::local_ref<JTracingState::javaobject>, jboolean)>("onStateChanged");
68+
return method(self(), convertCPPTracingStateToJava(tracingState), static_cast<jboolean>(screenshotsEnabled));
69+
}
3370
};
3471

3572
struct JFrameTimingSequence : public jni::JavaClass<JFrameTimingSequence> {
@@ -112,12 +149,6 @@ struct JReactHostImpl : public jni::JavaClass<JReactHostImpl> {
112149
}
113150
};
114151

115-
enum class TracingState {
116-
Disabled,
117-
EnabledInBackgroundMode,
118-
EnabledInCDPMode,
119-
};
120-
121152
/**
122153
* A callback that will be invoked when tracing state has changed.
123154
*/

0 commit comments

Comments
 (0)